Differences From Artifact [a0794eef80]:

To Artifact [874773144e]:


158
159
160
161
162
163
164



165

166

167

168




169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188



189




190
191
192
193
194
195
196
def get_data(filename, decode=False, gzip=False, file_base=None):
    """
    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 / plugin_base as top-level reference.




    :arg  str   fn:         filename in pyz or bundle

    :arg  bool  decode:     text file decoding utf-8

    :arg  bool  gz:         automatic gzdecode

    :arg  str   file_base:  alternative base module reference




    """
    try:
        data = pkgutil.get_data(file_base or module_base, filename)
        if gzip:
            data = gzip_decode(data)
        if decode:
            return data.decode("utf-8", errors='ignore')
        return str(data)
    except:
        # log_ERR("get_data() didn't find:", fn, "in", file_base)
        pass


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




    :arg  list  extra_paths:  in addition to plugin_base list




    """

    # Convert plugin_base package names into paths for iter_modules
    paths = []
    for module_or_path in plugin_base:
        if sys.modules.get(module_or_path):
            paths += sys.modules[module_or_path].__path__






>
>
>
|
>
|
>
|
>
|
>
>
>
>




















>
>
>
|
>
>
>
>







158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
def get_data(filename, decode=False, gzip=False, file_base=None):
    """
    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 / plugin_base as top-level reference.

    Parameters
    ----------
    filename :  str
        filename in pyz or bundle
    decode : bool
        text file decoding utf-8
    gzip : bool
        automatic gzdecode
    file_base : list
        alternative base module reference

    Returns
    -------
    str : file contents
    """
    try:
        data = pkgutil.get_data(file_base or module_base, filename)
        if gzip:
            data = gzip_decode(data)
        if decode:
            return data.decode("utf-8", errors='ignore')
        return str(data)
    except:
        # log_ERR("get_data() didn't find:", fn, "in", file_base)
        pass


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

    Parameters
    ----------
    extra_paths : list
        in addition to plugin_base list

    Returns
    -------
    list : names of found plugins
    """

    # Convert plugin_base package names into paths for iter_modules
    paths = []
    for module_or_path in plugin_base:
        if sys.modules.get(module_or_path):
            paths += sys.modules[module_or_path].__path__
205
206
207
208
209
210
211




212
213
214
215
216
217
218
219
220
221
222
223
224



225

226

227

228

229

230




231
232
233
234
235
236
237
# Plugin => meta dict
# ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
def all_plugin_meta():
    """
    This is a trivial wrapper to assemble a complete dictionary
    of available/installed plugins. It associates each plugin name
    with a its meta{} fields.




    """
    return {
        name: plugin_meta(module=name) for name in module_list()
    }


# Plugin meta data extraction
# ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
@renamed_arguments({"fn": "filename"})
def plugin_meta(filename=None, src=None, module=None, frame=1, **kwargs):
    """
    Extract plugin meta data block from different sources:




    :arg  str   filename:          read literal files, or .pyz contents

    :arg  str   src:         from already uncovered script code

    :arg  str   module:      lookup per pkgutil, from plugin_base or top-level modules

    :arg  int   frame:       extract comment header of caller (default)

    :arg  list  extra_base:  additional search directories

    :arg  ist   max_length:  maximum size to read from files




    """

    # Try via pkgutil first,
    # find any plugins.* modules, or main packages
    if module:
        filename = module
        for base in plugin_base + kwargs.get("extra_base", []):






>
>
>
>













>
>
>
|
>
|
>
|
>
|
>
|
>
|
>
>
>
>







222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
# Plugin => meta dict
# ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
def all_plugin_meta():
    """
    This is a trivial wrapper to assemble a complete dictionary
    of available/installed plugins. It associates each plugin name
    with a its meta{} fields.

    Returns
    -------
    dict : names to meta data dict
    """
    return {
        name: plugin_meta(module=name) for name in module_list()
    }


# Plugin meta data extraction
# ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
@renamed_arguments({"fn": "filename"})
def plugin_meta(filename=None, src=None, module=None, frame=1, **kwargs):
    """
    Extract plugin meta data block from different sources:

    Parameters
    ----------
    filename : str
        read literal files, or .pyz contents
    src : str
        from already uncovered script code
    module : str
        lookup per pkgutil, from plugin_base or top-level modules
    frame : int
        extract comment header of caller (default)
    extra_base : list
        additional search directories
    max_length : list
        maximum size to read from files

    Returns
    -------
    dict : key-value pairs of comment fields, config: preparsed
    """

    # Try via pkgutil first,
    # find any plugins.* modules, or main packages
    if module:
        filename = module
        for base in plugin_base + kwargs.get("extra_base", []):
274
275
276
277
278
279
280



281

282

283
284
285
286
287
288
289
290
@renamed_arguments({"fn": "filename"})
def plugin_meta_extract(src="", filename=None, literal=False):
    """
    Finds the first comment block. Splits key:value header
    fields from comment. Turns everything into an dict, with
    some stub fields if absent.




    :arg  str   src:       from existing source code

    :arg  int   filename:  set filename attribute

    :arg  bool  literla:   just split comment from doc
    """

    # Defaults
    meta = {
        "id": os.path.splitext(os.path.basename(filename or ""))[0],
        "fn": filename,
        "api": "python",






>
>
>
|
>
|
>
|







307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
@renamed_arguments({"fn": "filename"})
def plugin_meta_extract(src="", filename=None, literal=False):
    """
    Finds the first comment block. Splits key:value header
    fields from comment. Turns everything into an dict, with
    some stub fields if absent.

    Parameters
    ----------
    src : str
        from existing source code
    filename : str
        set filename attribute
    literls : bool
        just split comment from doc
    """

    # Defaults
    meta = {
        "id": os.path.splitext(os.path.basename(filename or ""))[0],
        "fn": filename,
        "api": "python",
323
324
325
326
327
328
329
330
331
332
333
334
335









336
337
338
339
340
341
342
# Unpack config: structures
# ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
def plugin_meta_config(src):
    """
    Further breaks up the meta['config'] descriptor.
    Creates an array from JSON/YAML option lists.

    :arg  str  src:  unprocessed config: field

    Stubs out name, value, type, description if absent.
    # config:
       { name: 'var1', type: text, value: "default, ..." }
       { name=option2, type=boolean, $value=1, etc. }









    """

    config = []
    for entry in rx.config.findall(src):
        entry = entry[0] or entry[1]
        opt = {
            "type": None,






<
<




>
>
>
>
>
>
>
>
>







361
362
363
364
365
366
367


368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
# Unpack config: structures
# ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
def plugin_meta_config(src):
    """
    Further breaks up the meta['config'] descriptor.
    Creates an array from JSON/YAML option lists.



    Stubs out name, value, type, description if absent.
    # config:
       { name: 'var1', type: text, value: "default, ..." }
       { name=option2, type=boolean, $value=1, etc. }

    Parameters
    ----------
    src : str
        unprocessed config: field

    Returns
    -------
    list : of option dictionaries
    """

    config = []
    for entry in rx.config.findall(src):
        entry = entry[0] or entry[1]
        opt = {
            "type": None,
461
462
463
464
465
466
467



468

469

470

471
472
473
474
475
476
477
478
# ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
def add_plugin_defaults(conf_options, conf_plugins, meta, module=""):
    """
    Utility function which collect defaults from plugin meta data to
    a config store. Which in the case of streamtuner2 is really just a
    dictionary `conf{}` and a plugin list in `conf.plugins{}`.




    :arg  dict  conf_options:  storage for amassed options

    :arg  dict  conf_plugins:  enable status based on plugin state/priority:

    :arg  dict  meta:          input plugin meta data (invoke once per plugin)

    :arg  str   module:        module name of meta: block
    """

    # Option defaults, if not yet defined
    for opt in meta.get("config", []):
        if "name" not in opt or "value" not in opt:
            continue
        _value = opt.get("value", "")






>
>
>
|
>
|
>
|
>
|







506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
# ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
def add_plugin_defaults(conf_options, conf_plugins, meta, module=""):
    """
    Utility function which collect defaults from plugin meta data to
    a config store. Which in the case of streamtuner2 is really just a
    dictionary `conf{}` and a plugin list in `conf.plugins{}`.

    Parameters
    ----------
    conf_options : dict : input/output
        storage for amassed options
    conf_plugins : dict : input/output
        enable status based on plugin state/priority:
    meta : dict
        input plugin meta data (invoke once per plugin)
    module : str
        basename of meta: blocks plugin file
    """

    # Option defaults, if not yet defined
    for opt in meta.get("config", []):
        if "name" not in opt or "value" not in opt:
            continue
        _value = opt.get("value", "")