.
D 2017-02-20T15:12:11.301
L api-pluginconf
N text/html
U mario
W 16446
<html><head><title>Python: module pluginconf</title>
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
<tr bgcolor="#7799ee">
<td valign=bottom> <br>
<font color="#ffffff" face="helvetica, arial"> <br><big><big><strong>pluginconf</strong></big></big></font></td
><td align=right valign=bottom
><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="streamtuner2/pluginconf.py">/home/mario/projects/streamtuner2/pluginconf.py</a></font></td></tr></table>
<p><tt># encoding: UTF-8<br>
# api: python<br>
# type: handler<br>
# category: io<br>
# title: Plugin configuration<br>
# description: Read meta data, pyz/package contents, module locating<br>
# version: 0.6.8<br>
# priority: core<br>
# docs: <a href="http://fossil.include-once.org/streamtuner2/wiki/plugin+meta+data">http://fossil.include-once.org/streamtuner2/wiki/plugin+meta+data</a><br>
# config: -<br>
#<br>
# Provides plugin lookup and meta data extraction utility functions.<br>
# It's used to abstract module+option management in applications.<br>
# For consolidating internal use and external/tool accessibility.<br>
#<br>
# The key:value format is language-agnostic. It's basically YAML in<br>
# a topmost script comment. For Python only # hash comments though.<br>
# Uses common field names, a documentation block, and an obvious<br>
# `config: { .. }` spec for options and defaults.<br>
#<br>
# It neither imposes a specific module/plugin API, nor config storage,<br>
# and doesn't fixate module loading. It's really just meant to look<br>
# up meta infos.<br>
# This approach avoids in-code values/inspection, externalized meta<br>
# descriptors, and any hodgepodge or premature module loading just to<br>
# uncover module description fields.<br>
#<br>
# <a href="#-plugin_meta">plugin_meta</a>()<br>
# ‾‾‾‾‾‾‾‾‾‾‾‾‾<br>
# Is the primary function to extract a meta dictionary from files.<br>
# It either reads from a given module= name, a literal fn=, or just<br>
# src= code, and as fallback inspects the last stack frame= else.<br>
#<br>
# <a href="#-module_list">module_list</a>()<br>
# ‾‾‾‾‾‾‾‾‾‾‾‾‾<br>
# Returns basenames of available/installed plugins. It uses the<br>
# plugin_base=[] list for module relation. Which needs to be set up<br>
# beforehand, or injected.<br>
#<br>
# <a href="#-add_plugin_defaults">add_plugin_defaults</a>()<br>
# ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾<br>
# Populates a config_options{} and plugin_states{} list. Used for<br>
# initial setup, or when adding new plugins, etc. Both dicts might<br>
# also be ConfigParser stores, or implement magic __set__ handling<br>
# to act on state changes.<br>
#<br>
# <a href="#-get_data">get_data</a>()<br>
# ‾‾‾‾‾‾‾‾‾‾<br>
# Is mostly an alias for pkgutil.<a href="#-get_data">get_data</a>(). It abstracts the main<br>
# base path, allows PYZ usage, and adds some convenience flags.‾<br>
# It's somewhat off-scope for plugin management, but used internally.<br>
#<br>
# argparse_map()<br>
# ‾‾‾‾‾‾‾‾‾‾‾‾‾‾<br>
# Converts a list of config: options with arg: attribute for use as<br>
# argparser parameters.<br>
#<br>
# <a href="#dependency">dependency</a>().depends()/.valid()<br>
# ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾<br>
# Probes a new plugins` depends: list against installed base modules.<br>
# Utilizes each version: fields and allows for virtual modules, or<br>
# alternatives and honors alias: names.<br>
#<br>
#<br>
# Generally this scheme concerns itself more with plugin basenames.<br>
# That is: module scripts in a package like `ext.plg1` and `ext.plg2`.<br>
# It can be initialized by injecting the plugin-package basename into<br>
# plugin_base = []. The associated paths will be used for module<br>
# lookup via pkgutil.iter_modules().<br>
#<br>
# And a central module can be extended with new lookup locations best<br>
# by attaching new locations itself via module.__path__ + ["./local"]<br>
# for example.<br>
#<br>
# Plugin loading thus becomes as simple as __import__("ext.local").<br>
# The attached plugin_state config dictionary in most cases can just<br>
# list module basenames, if there's only one set to manage.</tt></p>
<p>
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
<tr bgcolor="#aa55cc">
<td colspan=3 valign=bottom> <br>
<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
<tr><td bgcolor="#aa55cc"><tt> </tt></td><td> </td>
<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a
href="https://docs.python.org/3/library/argparse.html">argparse</a><br>
<a href="https://docs.python.org/3/library/inspect.html">inspect</a><br>
</td><td width="25%" valign=top><a href="os.html">os</a><br>
<a href="https://docs.python.org/3/library/pkgutil.html">pkgutil</a><br>
</td><td width="25%" valign=top><a href="re.html">re</a><br>
<a href="https://docs.python.org/3/library/sys.html">sys</a><br>
</td><td width="25%" valign=top><a href="https://docs.python.org/3/library/zipfile.html">zipfile</a><br>
</td></tr></table></td></tr></table><p>
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
<tr bgcolor="#ee77aa">
<td colspan=3 valign=bottom> <br>
<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
<tr><td bgcolor="#ee77aa"><tt> </tt></td><td> </td>
<td width="100%"><dl>
<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
</font></dt><dd>
<dl>
<dt><font face="helvetica, arial"><a href="api-pluginconf#dependency">dependency</a>
</font></dt></dl>
</dd>
</dl>
<p>
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
<tr bgcolor="#ffc8d8">
<td colspan=3 valign=bottom> <br>
<font color="#000000" face="helvetica, arial"><a name="dependency">class <strong>dependency</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
<tr bgcolor="#ffc8d8"><td rowspan=2><tt> </tt></td>
<td colspan=2><tt># Minimal depends: probing<br>
# ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾<br>
# Now this definitely requires customization. Each plugin can carry<br>
# a list of (soft-) <a href="#dependency">dependency</a> names.<br>
#<br>
# depends: config, appcore >= 2.0, bin:wkhtmltoimage, python < 3.5<br>
#<br>
# Here only in-application modules are honored, system references<br>
# ignored. Unknown plugin names are also skipped. A real install<br>
# helper might want to auto-tick them on, etc. This example is just<br>
# meant for probing downloadable plugins.<br>
#<br>
# The .<a href="#dependency-valid">valid</a>() helper only asserts the api: string, or skips existing<br>
# modules, and if they're more recent.<br>
# While .<a href="#dependency-depends">depends</a>() compares minimum versions against existing modules.<br>
#<br>
# In practice there's little need for full-blown <a href="#dependency">dependency</a> resolving<br>
# for application-level modules.<br> </tt></td></tr>
<tr><td> </td>
<td width="100%">Methods defined here:<br>
<dl><dt><a name="dependency-__init__"><strong>__init__</strong></a>(self, add<font color="#909090">={}</font>, core<font color="#909090">=['st2', 'uikit', 'config', 'action']</font>)</dt><dd><tt># prepare list of known plugins and versions</tt></dd></dl>
<dl><dt><a name="dependency-and_or"><strong>and_or</strong></a>(self, deps, have, r<font color="#909090">=True</font>)</dt><dd><tt># Compare nested structure of [[dep],[alt,alt]]</tt></dd></dl>
<dl><dt><a name="dependency-cmp"><strong>cmp</strong></a>(self, d, have, absent<font color="#909090">=True</font>)</dt><dd><tt># Single comparison</tt></dd></dl>
<dl><dt><a name="dependency-depends"><strong>depends</strong></a>(self, plugin)</dt><dd><tt># Verify depends: and breaks: against existing plugins/modules</tt></dd></dl>
<dl><dt><a name="dependency-module_test"><strong>module_test</strong></a>(self, type, name)</dt><dd><tt># Resolves/injects complex "bin:name" or "python:name" <a href="#dependency">dependency</a> URNs</tt></dd></dl>
<dl><dt><a name="dependency-neither"><strong>neither</strong></a>(self, deps, have)</dt><dd><tt># Breaks/Conflicts: check [[or],[or]]</tt></dd></dl>
<dl><dt><a name="dependency-split"><strong>split</strong></a>(self, dep_str)</dt><dd><tt># Split trivial "pkg | alt, mod >= 1, uikit < 4.0" string into nested list [[dep],[alt,alt],[dep]]</tt></dd></dl>
<dl><dt><a name="dependency-valid"><strong>valid</strong></a>(self, newpl)</dt><dd><tt># basic plugin pre-screening (skip __init__, filter by api:,<br>
# exclude installed & same-version plugins)</tt></dd></dl>
<hr>
Data descriptors defined here:<br>
<dl><dt><strong>__dict__</strong></dt>
<dd><tt>dictionary for instance variables (if defined)</tt></dd>
</dl>
<dl><dt><strong>__weakref__</strong></dt>
<dd><tt>list of weak references to the object (if defined)</tt></dd>
</dl>
</td></tr></table></td></tr></table><p>
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
<tr bgcolor="#eeaa77">
<td colspan=3 valign=bottom> <br>
<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
<tr><td bgcolor="#eeaa77"><tt> </tt></td><td> </td>
<td width="100%"><dl><dt><a name="-add_plugin_defaults"><strong>add_plugin_defaults</strong></a>(conf_options, conf_plugins, meta<font color="#909090">={}</font>, module<font color="#909090">=''</font>)</dt><dd><tt># Add plugin defaults to conf.* store<br>
# ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾<br>
# Utility function which applies plugin meta data to a config<br>
# store. Which in the case of streamtuner2 is really just a<br>
# dictionary `conf{}` and a plugin list in `conf.plugins{}`.<br>
#<br>
# Adds each default option value: to conf_options{}. And sets<br>
# first plugin state (enabled/disabled) in conf_plugins{} list,<br>
# depending on priority: classifier.</tt></dd></dl>
<dl><dt><a name="-get_data"><strong>get_data</strong></a>(fn, decode<font color="#909090">=False</font>, gz<font color="#909090">=False</font>, file_base<font color="#909090">=None</font>)</dt><dd><tt># Resource retrieval<br>
# ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾<br>
# Fetches file content from install path or from within PYZ<br>
# archive. This is just an alias and convenience wrapper for<br>
# pkgutil.<a href="#-get_data">get_data</a>().<br>
# Utilizes the module_base / file_base as top-level reference.</tt></dd></dl>
<dl><dt><a name="-module_list"><strong>module_list</strong></a>(extra_paths<font color="#909090">=[]</font>)</dt><dd><tt># Plugin name lookup<br>
# ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾<br>
# Search through ./plugins/ (and other configured plugin_base<br>
# names → paths) and get module basenames.</tt></dd></dl>
<dl><dt><a name="-plugin_meta"><strong>plugin_meta</strong></a>(fn<font color="#909090">=None</font>, src<font color="#909090">=None</font>, module<font color="#909090">=None</font>, frame<font color="#909090">=1</font>, extra_base<font color="#909090">=[]</font>)</dt><dd><tt># Plugin meta data extraction<br>
# ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾<br>
# Can fetch infos from different sources:<br>
#<br>
# fn= read literal files, or .pyz contents<br>
#<br>
# src= from already uncovered script code<br>
#<br>
# module= lookup per pkgutil, from plugin bases<br>
# or top-level modules<br>
#<br>
# frame= extract comment header of caller<br>
# (default)</tt></dd></dl>
</td></tr></table><p>
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
<tr bgcolor="#55aa55">
<td colspan=3 valign=bottom> <br>
<font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>
<tr><td bgcolor="#55aa55"><tt> </tt></td><td> </td>
<td width="100%"><strong>__all__</strong> = ['get_data', 'module_list', 'plugin_meta', 'dependency', 'add_plugin_defaults']</td></tr></table>
Z 451fd7499f94e14efca2daf61c6485bc