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 |