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

⌈⌋ ⎇ branch:  streamtuner2


Diff

Differences From Artifact [a5813116de]:

To Artifact [33b1fa968d]:


1
2
3
4
5
6
7

8
9
10
11
12
13
14
1
2
3
4
5
6

7
8
9
10
11
12
13
14






-
+







# encoding: UTF-8
# api: python
# type: handler
# category: io
# title: Plugin configuration
# description: Read meta data, pyz/package contents, module locating
# version: 0.5
# version: 0.6
# 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.
# For consolidating internal use and external/tool accessibility.
57
58
59
60
61
62
63





64








65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85

86
87
88


89
90
91
92
93
94
95
96
97
98
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
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
109
110







+
+
+
+
+

+
+
+
+
+
+
+
+




















-
+


-
+
+

-
-







#
# dependency().valid/depends()
# ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
#  Probes a new plugins` depends: list against installed base modules.
#  Very crude and tied to streamtuner2 base names.
#
#
# Generally this scheme concerns itself more with plugin basenames.
# That is: module scripts in a package like `ext.plg1` and `ext.plg2`.
# It can be initialized by injecting the plugin-package basename into
# plugin_base = []. The associated paths will be used for module
# lookup via pkgutil.iter_modules().
#
# And a central module can be extended with new lookup locations best
# by attaching new locations itself via module.__path__ + ["./local"]
# for example.
#
# Plugin loading thus becomes as simple as __import__("ext.local").
# The attachaed plugin_state config dictionary in most cases can just
# list module basenames, if there's only one set to manage.



import sys
import os
import re
import pkgutil
import inspect
try: from compat2and3 import gzip_decode
except: from gzip import decompress as gzip_decode # Py3 only
import zipfile
import argparse

__all__ = ["get_data", "module_list", "plugin_meta", "dependency", "add_plugin_defaults"]



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

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

# Package names or base paths for module_list() and plugin_meta() lookups
# Package/module names for module_list() and plugin_meta() lookups.
# All associated paths will be scanned for module/plugin basenames.
plugin_base = ["channels"]
            # [conf.share+"/channels", conf.dir+"/plugins"])




# Resource retrieval
# ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
# Fetches file content from install path or from within PYZ
# archive. This is just an alias and convenience wrapper for
112
113
114
115
116
117
118
119

120
121

122








123
124

125
126
127
128
129
130
131
124
125
126
127
128
129
130

131
132

133
134
135
136
137
138
139
140
141
142
143

144
145
146
147
148
149
150
151







-
+

-
+

+
+
+
+
+
+
+
+

-
+







        pass#log_ERR("get_data() didn't find:", fn, "in", file_base)



# Plugin name lookup
# ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
# Search through ./plugins/ (and other configured plugin_base
# names or paths) and get module basenames.
# names → paths) and get module basenames.
#
def module_list(extra_base=[]):
def module_list(extra_paths=[]):

    # Convert plugin_base package names into paths for iter_modules
    paths = []
    for mp in plugin_base:
        if sys.modules.get(mp):
            paths += sys.modules[mp].__path__
        elif os.path.exists(mp):
            paths.append(mp)

    # Should list plugins within zips as well as local paths
    ls = pkgutil.iter_modules(plugin_base + extra_base)
    ls = pkgutil.iter_modules(paths + extra_paths)
    return [name for loader,name,ispkg in ls]



# Plugin => meta dict
# ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
# This is a trivial wrapper to assemble a complete dictionary