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

⌈⌋ ⎇ branch:  streamtuner2


Check-in [d08461a712]

Overview
Comment:Rewrite some comments.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: d08461a71271715a7d6e5f5179226b4285d15e1e
User & Date: mario on 2015-05-04 17:47:14
Other Links: manifest | tags
Context
2015-05-04
22:29
Stub placeholder version: as `0` check-in: 9f252677fa user: mario tags: trunk
17:47
Rewrite some comments. check-in: d08461a712 user: mario tags: trunk
17:45
Fix http reference, unneeded. check-in: 718fb64e78 user: mario tags: trunk
Changes

Modified pluginconf.py from [8af6dbea92] to [1109b86183].

1
2
3
4
5
6
7
8

9
10
11
12
13


14
15
16
17
18




19
20
21
22


23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44




45
46
47
48
49
50
51
1
2
3
4
5
6
7
8
9
10
11
12


13
14
15




16
17
18
19
20
21


22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41




42
43
44
45
46
47
48
49
50
51
52








+



-
-
+
+

-
-
-
-
+
+
+
+


-
-
+
+


















-
-
-
-
+
+
+
+







# encoding: UTF-8
# api: python
# type: handler
# category: io
# title: Plugin configuration
# description: Read meta data, pyz/package contents, module locating
# version: 0.5
# priority: core
# doc: http://fossil.include-once.org/streamtuner2/wiki/plugin+meta+data
# config: -
#
# Provides plugin lookup and meta data extraction utility functions.
# It's used to abstract module+option management in applications,
# which consolidates internal and external tool reuse.
# It's used to abstract module+option management in applications.
# For consolidating internal use and external/tool accessibility.
#
# The key:value format is language-agnostic, but in Python just uses
# hash comments. It's basically YAML in the top-most script comment,
# common field names, documentation, and a simple config: { .. } spec
# for options and defaults.
# The key:value format is language-agnostic. It's basically YAML in
# a topmost script comment. For Python only # hash comments though.
# Uses common field names, a documentation block, and an obvious
# `config: { .. }` spec for options and defaults.
#
# It neither imposes a specific module/plugin API, nor config storage,
# and doesn't provide much for module loading. It's really just meant
# to look up meta infos.
# and doesn't fixate module loading. It's really just meant to look
# up meta infos.
# This approach avoids in-code values/inspection, externalized meta
# descriptors, and any hodgepodge or premature module loading just to
# uncover module description fields.
#
# plugin_meta() 
# ‾‾‾‾‾‾‾‾‾‾‾‾‾
#  Is the primary function to extract a meta dictionary from files.
#  It either reads from a given module= name, a literal fn=, or just
#  src= code, and as fallback inspects the last stack frame= else.
#
# module_list()
# ‾‾‾‾‾‾‾‾‾‾‾‾‾
#  Returns basenames of available/installed plugins. It uses the
#  plugin_base=[] list for module relation. Which needs to be set up
#  beforehand, or injected.
#
# add_plugin_defaults()
# ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
#  Populates a configval{} and pluginstate{} list. Used for initial
#  setup, when adding new plugins, etc. Both dicts might also be
#  ConfigParser stores, or implement magic __set__ handling to act
#  on changed states.
#  Populates a config_options{} and plugin_states{} list. Used for
#  initial setup, or when adding new plugins, etc. Both dicts might
#  also be ConfigParser stores, or implement magic __set__ handling
#  to act on state changes.
#
# get_data()
# ‾‾‾‾‾‾‾‾‾‾
#  Is mostly an alias for pkgutil.get_data(). It abstracts the main
#  base path, allows PYZ usage, and adds some convenience flags.‾
#  It's somewhat off-scope for plugin management, but used internally.
#
79
80
81
82
83
84
85
86

87
88
89

90
91

92
93
94
95
96
97
98
99
100
101




102
103
104
105
106
107
108
80
81
82
83
84
85
86

87
88
89

90
91

92
93
94
95
96
97
98




99
100
101
102
103
104
105
106
107
108
109







-
+


-
+

-
+






-
-
-
-
+
+
+
+









# Injectables
# ‾‾‾‾‾‾‾‾‾‾‾
log_WARN = lambda *x:None
log_ERR = lambda *x:None

# File lookup relation for get_data(), should be a top-level package module
# File lookup relation for get_data(), should name a top-level module/package
module_base = "pluginconf"

# Module lookups via module_list(), may contain names or paths
# Package names or base paths for module_list() and plugin_meta() lookups
plugin_base = ["plugins"]
    #   [conf.share+"/channels", conf.dir+"/plugins"])
            # [conf.share+"/channels", conf.dir+"/plugins"])




# Resource retrieval
# ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
# Retrieve file content from install path or from within
# pyzip archive. This is just an alias and convenience
# wrapper for pkgutil.get_data().
# Uses module_base / file_base as top-level reference.
# Fetches file content from install path or from within PYZ
# archive. This is just an alias and convenience wrapper for
# pkgutil.get_data().
# Utilizes the module_base / file_base as top-level reference.
#
def get_data(fn, decode=False, gz=False, file_base=None):
    try:
        bin = pkgutil.get_data(file_base or module_base, fn)
        if gz:
            bin = gzip_decode(bin)
        if decode:
142
143
144
145
146
147
148
149

150
151
152
153
154
155
156
143
144
145
146
147
148
149

150
151
152
153
154
155
156
157







-
+








# Plugin meta data extraction
# ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
# Can fetch infos from different sources:
#
#   fn=      read literal files, or .pyz contents
#
#   src=     from pre-available script code
#   src=     from already uncovered script code
#
#   module=  lookup per pkgutil, from plugin bases
#            or top-level modules
#
#   frame=   extract comment header of caller
#            (default)
#
309
310
311
312
313
314
315
316

317
318
319
320
321
322
323
310
311
312
313
314
315
316

317
318
319
320
321
322
323
324







-
+







#  · Understands the types `str`, `int` and `bool`.
#
#  · Entries may carry a `hidden: 1` or `required: 1` attribute.
#
#  · And `help:` is an alias to `description:`
#    And `default:` an alias for `value:`
#
#  · While `type: select` utilizes the `select: a|b|c` format as uaual.
#  · While `type: select` utilizes the `select: a|b|c` format as usual.
#
# ArgParsers const=, metavar= flag, or type=file are not aliased here.
#
# Basically returns a dictionary that can be fed per **kwargs directly
# to an ArgumentParsers add_argument(). Iterate over each plugins
# meta['config'][] options to convert them.
#
362
363
364
365
366
367
368
369
370
371



372
373
374

375
376
377
378
379
380
381
363
364
365
366
367
368
369



370
371
372
373
374

375
376
377
378
379
380
381
382







-
-
-
+
+
+


-
+







#   depends: config, appcore >= 2.0, bin:wkhtmltoimage, python < 3.5
#
# Here only in-application modules are honored, system references
# ignored. Unknown plugin names are also skipped. A real install
# helper might want to auto-tick them on, etc. This example is just
# meant for probing downloadable plugins.
#
# The .valid() helper just asserts the api: string, or skips existing
# modules.
# While .depends() compares minimum versions of existing base plugins.
# The .valid() helper only asserts the api: string, or skips existing
# modules, and if they're more recent.
# While .depends() compares minimum versions against existing modules.
#
# In practice there's little need for full-blown dependency resolving
# for in-app modules.
# for application-level modules.
#
class dependency(object):

    # prepare list of known plugins and versions
    def __init__(self):
        self.have = all_plugin_meta()
        # dependencies on core modules are somewhat more interesting: