tmp
This commit is contained in:
parent
f6fed08e26
commit
e801f15066
69
README.md
69
README.md
|
@ -0,0 +1,69 @@
|
|||
Providers are modules that export:
|
||||
CONFIG = {
|
||||
"config key": "optional | required",
|
||||
...
|
||||
}
|
||||
|
||||
update(config, state) -> list[items]
|
||||
|
||||
And optionally:
|
||||
action_NAME(config, state, item) -> None
|
||||
|
||||
on_create(config, state, item) -> None
|
||||
|
||||
on_delete(config, state, item) -> None
|
||||
|
||||
Sources are folders in the data directory with:
|
||||
config: user-modified configuration values, drawn from the provider
|
||||
state: provider-modified data
|
||||
*.item: feed items
|
||||
|
||||
config reserved keys:
|
||||
"provider": the provider the source uses
|
||||
"name": given to sources by default, individuates sources from same provider
|
||||
|
||||
GET /config
|
||||
Edit subfeed configs
|
||||
|
||||
GET /config/[feedname]
|
||||
Edit config values for feedname
|
||||
|
||||
GET /feed/[feedname]
|
||||
Feed view for feedname
|
||||
|
||||
<!-- GET /items
|
||||
Get item JSON
|
||||
?include=[tags]
|
||||
?exclude=[tags]
|
||||
?limit=100 -->
|
||||
|
||||
CLI:
|
||||
intake create [provider] [--config KEY VALUE] [-c KEY VALUE] ...
|
||||
load the provider
|
||||
verify that the provider's config is satisfied
|
||||
create the source and set the config values
|
||||
|
||||
intake update [source] [--reset]
|
||||
load the source's config and state
|
||||
use config.provider to load the provider
|
||||
verify the source config against the provider config
|
||||
call provider.update(config, state) to get current items
|
||||
merge new items into current items
|
||||
if --reset, new items overwrite everything, including active
|
||||
|
||||
intake deactivate [source] [--tag TAG] [--title TITLE]
|
||||
load each item in the source and deactivate it
|
||||
|
||||
intake add [--id ID] [--title TITLE] [--link LINK] [--time TIME] [--author AUTHOR] [--body BODY] [--tags TAGS] [--ttl TTL] [--ttd TTD] [--tts TTS]
|
||||
create the item and add it to the default source
|
||||
|
||||
intake feed [--json]
|
||||
Dump active item feed to stdout
|
||||
|
||||
intake action [source] [item] [action]
|
||||
load config, state, item
|
||||
verify item supports this action
|
||||
load config.provider
|
||||
verify config
|
||||
verify provider supports this action
|
||||
action_[action](config, state, item)
|
|
@ -0,0 +1,21 @@
|
|||
from intake import BaseSettings, Setting
|
||||
|
||||
|
||||
class Settings(BaseSettings):
|
||||
message = Setting(default="Hello, world!")
|
||||
|
||||
|
||||
def update(config, state):
|
||||
pass
|
||||
|
||||
|
||||
def on_create(config, state, item):
|
||||
pass
|
||||
|
||||
|
||||
def on_delete(config, state, item):
|
||||
pass
|
||||
|
||||
|
||||
def action_tick(config, state, item):
|
||||
pass
|
|
@ -15,6 +15,40 @@ from intake.provider import (
|
|||
verify_settings,
|
||||
verify_update,
|
||||
)
|
||||
from intake.source import initialize_source
|
||||
|
||||
|
||||
def command_create(args):
|
||||
"""Create a source."""
|
||||
parser = argparse.ArgumentParser(
|
||||
prog="intake create",
|
||||
description=command_create.__doc__)
|
||||
parser.add_argument("provider",
|
||||
help="Provider to create the source from",
|
||||
metavar="provider")
|
||||
parser.add_argument("--setting", "-s",
|
||||
help="Define a provider setting",
|
||||
nargs=2,
|
||||
action="append",
|
||||
metavar="key value",
|
||||
dest="settings",
|
||||
default=[])
|
||||
parser.add_argument("--data",
|
||||
help="Data folder path",
|
||||
metavar="path",
|
||||
type=os.path.abspath)
|
||||
parser.add_argument("--path",
|
||||
nargs="+",
|
||||
help="Additional paths to add to INTAKEPATH",
|
||||
metavar="path",
|
||||
type=os.path.abspath,
|
||||
default=[])
|
||||
args = parser.parse_args()
|
||||
|
||||
ret = 0
|
||||
|
||||
settings = {key: value for key, value in args.settings}
|
||||
initialize_source(args.data, args.path, **settings)
|
||||
|
||||
|
||||
def command_test(args):
|
||||
|
|
|
@ -45,6 +45,10 @@ class BaseSettings:
|
|||
raise SettingMissingError(missing)
|
||||
|
||||
|
||||
def issetting(obj):
|
||||
return isinstance(obj, Setting)
|
||||
|
||||
|
||||
class chdir:
|
||||
"""
|
||||
A context manager that changes the working directory inside the context.
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
import inspect
|
||||
import json
|
||||
import os
|
||||
|
||||
from intake.provider import (
|
||||
load_provider,
|
||||
issetting,
|
||||
SettingMissingError,
|
||||
verify_settings,
|
||||
)
|
||||
|
||||
|
||||
def initialize_source(data_path, search_paths, **setting_kvs):
|
||||
"""
|
||||
Create a source's data folder and store its settings.
|
||||
"""
|
||||
# Verify the base required settings
|
||||
if "name" not in setting_kvs:
|
||||
raise KeyError("Missing name in settings")
|
||||
if "provider" not in setting_kvs:
|
||||
raise KeyError("Missing provider in settings")
|
||||
# Check if the directory exists already
|
||||
source_name = setting_kvs.get("name")
|
||||
source_path = os.path.join(data_path, source_name)
|
||||
if os.path.exists(source_path):
|
||||
raise FileExistsError(source_path)
|
||||
# Load the provider
|
||||
provider_name = setting_kvs.get("provider")
|
||||
provider = load_provider(search_paths, provider_name)
|
||||
if not provider:
|
||||
raise FileNotFoundError(provider_name)
|
||||
# Verify that the provider has settings
|
||||
verify_settings(provider)
|
||||
# Check that all the required settings are populated
|
||||
settings = inspect.getmembers(provider.Settings, issetting)
|
||||
for name, setting in settings:
|
||||
if setting.required and name not in setting_kvs:
|
||||
raise SettingMissingError()
|
||||
|
||||
# Create the directory
|
||||
os.mkdir(source_path)
|
||||
# Create the settings file
|
||||
setting_json = {}
|
||||
for name, setting in settings:
|
||||
setting_json[name] = setting_kvs.get(name, setting.default)
|
||||
with open(os.path.join(source_path, ".settings"), 'w') as f:
|
||||
json.dump(setting_json, f, indent=2)
|
||||
# Create the state file
|
||||
with open(os.path.join(source_path, ".state"), 'w') as f:
|
||||
json.dump({}, f, indent=2)
|
Loading…
Reference in New Issue