D 2017-01-01T21:11:23.551 L plugin\smeta\sdata N text/x-markdown P 5539fd6f978205f9bbb332816255a5e263bb6cf1 U Oliver W 5119 # Plugin meta spec Streamtuner2 now uses a proper plugin description scheme. Note that this is completely unrelated to the streamtuner2 or channels API, or how plugins are actually initialized (pkgutil, imp, implib, pluginbase/plugnplay). Basically the top-level comment block is scanned on initialization. It simply lists a few key: values for documentation and technical descriptors. It's basically a subset of YAML embedded in a script comment. # api: streamtuner2 # type: feature # title: My Plugin # description: Lists all the things # version: 1.0 # category: music # config: { name: myconf, value: 1, type: boolean, description: enable foo } # # And here goes a longer doc/comment. The key names are case-insensitive of course. A few fields like title:, description: are required. Theoretically also the api: and type:. Though in ST2 they're currently just used for decorative purposes like the category: or version: field. More interestingly the config: field can be used to describe plugin options. Default values will automatically end up in streamtuners `conf.*` dict, and are presented to users in the config dialog. * A value: represents the default. * The type: select can be used for dropdown boxes, with a `select:` key=VAl|key2=VAL2.. attribute for options. * Other type: values are interpreted as strings, except type: boolean which becomes a checkbox. * The new type: dict creates an association table (like player/recording treeviews). And optionally array/table is available for Excel-style inputs. * A per-option category: attribute is ignored at the moment. * Params can be optionally quoted as in value: "Desc, desc, desc." in case they contain commas (which otherwise separate option attrs.) And of course, the config: field can list multiple options. Simply make it multi-line (every plugin meta field can be) by indenting wrapped lines. ### Why? This scheme is designed to be language-agnostic. It originated in PHP way back (see [libconfig](http://milki.include-once.org/genericplugins/)), precisely to avoid a few common misdesigns. * Meta data does **not** belong *in code*. Because that incurs always importing them, even when they may go uninitialized/unused. * And it certainly should not reside in externalized ini/json data blobs. *(Or do you want ants? Because that's how you get ants.)* * Furthermore it encourages a *useful* documentation block atop. (Instead of license blobs everywhere in lieu of proper comments.) The meta description block incidentally can also serve as packaging control scheme. The pack: descriptor is used by [fpm/xpm -s src](http://fossil.include-once.org/xpm/wiki/src). Which avoids manually doubling descriptions into separated setup.py/.cfg as the current Python packaging eco system does. Note though that the plugin description scheme is primarily intended for *in-application* feature/plugin management. Reducing packaging effort is just a by-effect. ### Plugin list The purpose of this scheme is feeding the plugin management in the settings window of course: This is meanwhile a sortof Python package of its own, [http://pypi.python.org/pypi/pluginconf/](http://pypi.python.org/pypi/pluginconf/). Doesn't include the current GUI code though. ### argparse config: struct Similarly to internal plugin configuration settings, the config: list is now used for ArgumentParser definitions. Fields are slightly remapped to remain in line with regular options. # config: # { arg: -D, name: debug, type: bool, description: enable debugging } # { arg: -e, name: enable[], type: str*, description: add plugin } It's basically just the extra arg: field which discerns such entries from standard options. And the type: may carry an optional quantifier (mapped to argparses' nargs= flag). Or the name: can indicate a list property with `[]` attached (maps to argparses' append instead of store). Not every argparse peculiarity is provided for though. And using a docopt section would probably be a better option anyway. ### common.json Just a few implemntation notes: * [pluginconf.py](artifact/9a5f974003eec12409de6b690ecc9210d541b153) handles initialization and parsing of channel/*.py files * Whereas [channel/pluginmanager2.py](artifact/1f88837392bbe4e1dc6cf89b13775dd41ca54b0d) is the GUI and ST2 hook for managing them * Plugins that are downloaded from the fossil repository are scanned using a server-side setup of [dev/fossil-json-plugin-repo.php](finfo?name=dev/fossil-json-plugin-repo.php) * See also [technote 489b041520](technote/489b041520c3365146538c6e5f92fef4835fabcc) Z 3e96ba2c840ec304c6e63208b5dcafe6