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

⌈⌋ branch:  streamtuner2


Diff

Differences From Artifact [8430e295e9]:

To Artifact [51ce82a04c]:


296
297
298
299
300
301
302



303


304
305
306
307






308
309
310
311

312
313
314
315

316
317
318
319

320
321
322
323
324
325
326
296
297
298
299
300
301
302
303
304
305

306
307
308



309
310
311
312
313
314


315

316
317
318
319

320
321
322
323

324
325
326
327
328
329
330
331







+
+
+
-
+
+

-
-
-
+
+
+
+
+
+
-
-

-
+



-
+



-
+







    # get source directly from caller
    elif not src and not fn:
        module = inspect.getmodule(sys._getframe(frame))
        fn = inspect.getsourcefile(module)
        src = inspect.getcomments(module)

    # real filename/path
    elif fn and os.path.exists(fn):
        src = open(fn).read(4096)
    # within zip archive or dir?

    # assume it's within a zip
    elif fn:
        zip = rx.zipfn.match(fn)
        if zip and zipfile.is_zipfile(zip.group(1)):
            src = zipfile.ZipFile(zip.group(1), "r").read(zip.group(2))
        intfn = ""
        while fn and len(fn) and not os.path.exists(fn):
            fn, add = os.path.split(fn)
            intfn = add + "/" + intfn
        if len(fn) >= 3 and intfn and zipfile.is_zipfile(fn):
            src = zipfile.ZipFile(fn, "r").read(intfn.strip("/"))
        else:
            src = open(fn).read(4096)

    return plugin_meta_extract(src, fn)
    return plugin_meta_extract(src or "", fn)


# Actual comment extraction logic
def plugin_meta_extract(src="", fn="", literal=False):
def plugin_meta_extract(src="", fn=None, literal=False):

    # defaults
    meta = {
        "id": os.path.basename(fn or "").split(".")[0],
        "id": os.path.splitext(os.path.basename(fn or "")),
        "fn": fn,
        "title": fn, "description": "no description", "config": [],
        "type": "module", "api": "python", "doc": ""
    }

    # extract coherent comment block, split doc section
    if not literal:
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
355
356
357
358
359
360
361




362
363
364
365
366
367
368







-
-
-
-






        for field in rx.options.findall(entry):
            opt[field[0]] = (field[1] or field[2] or field[3] or "").strip()
        config.append(opt)
    return config

# Comment extraction regexps
class rx:
    zipfn   = re.compile(r"""
        ^ (.+  \.(?:zip|pyz|pyzw|pyzip)        # zip-wrapping extensions
        (?:\.py)? ) /(\w.*) $
    """, re.X)
    comment = re.compile(r"""(^ {0,4}#.*\n)+""", re.M)
    hash    = re.compile(r"""(^ {0,4}# *)""", re.M)
    keyval  = re.compile(r"""
        ^([\w-]+):(.*$(?:\n(?![\w-]+:).+$)*)      # plain key:value lines
    """, re.M|re.X)
    config  = re.compile(r"""
        [\{\<] (.+?) [\}\>]                    # JSOL/YAML scheme {...} dicts