Internet radio browser GUI for music/video streams from various directory services.

⌈⌋ branch:  streamtuner2


Artifact [bcc909d039]

Artifact bcc909d0398e9687a7989faf52c309096eecbc25:

Wiki page [plugin meta data] by mario on 2018-07-07 14:55:32.
D 2018-07-07T14:55:32.339
L plugin\smeta\sdata
N text/x-markdown
P 10f6f183d215c448caa4da87e29dfed77d7725ff
U mario
W 5378
# Plugin meta spec

Streamtuner2 now uses a proper ➜ <a href="http://fossil.include-once.org/pluginspec/" style="background:#ec9"><img src="/static/img/pluginspec.png" width=16 height=16> plugin description scheme</a>. 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 <kbd>key: values</kbd> 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 <kbd>title:</kbd>, <kbd>description:</kbd> are required. Theoretically also the <kbd>api:</kbd> and <kbd>type:</kbd>. Though in ST2 they're currently just used for decorative purposes like the <kbd>category:</kbd> or <kbd>version:</kbd> field.

More interestingly the <kbd>config:</kbd> 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 <kbd>value:</kbd> represents the default.
   * The <kbd>type: select</kbd> can be used for dropdown boxes, with a `select:` <kbd>key=VAl|key2=VAL2..</kbd> attribute for options.
   * Other <kbd>type:</kbd> values are interpreted as strings, except <kbd>type: boolean</kbd> which becomes a checkbox.
   * The new <kbd>type: dict</kbd> creates an association table (like player/recording treeviews). And optionally <kbd>array/table</kbd> is available for Excel-style inputs.
   * A per-option <kbd>category:</kbd> attribute is ignored at the moment.
   * Params can be optionally quoted as in <kbd>value: "Desc, desc, desc."</kbd> in case they contain commas (which otherwise separate option attrs.)

And of course, the <kbd>config:</kbd> field can list multiple options. Simply make it multi-line (every plugin meta field can be) by indenting wrapped lines.


### Why?

This [scheme](http://fossil.include-once.org/pluginspec/) 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 <kbd>pack:</kbd> 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:

<img src="raw/st2-plugins.png?name=946c0e32c868a22facd7498250451723a50ab00a" style="margin:10pt" width=260 height=375>

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.

See also: [pluginspec](http://fossil.include-once.org/pluginspec/)


### argparse config: struct

Similarly to internal plugin configuration settings, the <kbd>config:</kbd> 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 <kbd>arg:</kbd> field which discerns such entries from standard options. And the <kbd>type:</kbd> may carry an optional quantifier (mapped to argparses' nargs= flag). Or the <kbd>name:</kbd> 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 ef0621858329069d0a2335d30d766cf0