Pull some code in from 2016 project; add tests
This commit is contained in:
99
blenderpack.py
Normal file → Executable file
99
blenderpack.py
Normal file → Executable file
@@ -3,10 +3,109 @@
|
||||
# HACK: seems 'requests' module bundled with blender isn't bundled with 'idna' module. So force system python for now
|
||||
import sys
|
||||
sys.path.insert(0, '/usr/lib/python3.6/site-packages')
|
||||
|
||||
import requests
|
||||
import json
|
||||
import os
|
||||
import ast
|
||||
import argparse
|
||||
import zipfile
|
||||
import logging
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
def report(msg):
|
||||
# if __name__ == '__main__':
|
||||
print("blenderpack:", msg)
|
||||
|
||||
def fatal_report(msg, code=1):
|
||||
report(msg)
|
||||
exit(code)
|
||||
|
||||
def fetch(url):
|
||||
# TODO: do conditional request
|
||||
re = requests.get(url)
|
||||
print(re.json())
|
||||
|
||||
def parse_blinfo(source, addon_name="unknown"):
|
||||
"""Parse a python file and return its bl_info dict, if there is one (else return None)"""
|
||||
|
||||
try:
|
||||
tree = ast.parse(source)
|
||||
except SyntaxError as ex:
|
||||
log.warning('Skipping addon: SyntaxError in %s: %s', addon_name, ex)
|
||||
return None
|
||||
|
||||
for body in tree.body:
|
||||
if body.__class__ != ast.Assign:
|
||||
continue
|
||||
if len(body.targets) != 1:
|
||||
continue
|
||||
if getattr(body.targets[0], 'id', '') != 'bl_info':
|
||||
continue
|
||||
|
||||
return ast.literal_eval(body.value)
|
||||
|
||||
log.warning('Unable to find bl_info dict in %s', addon_name)
|
||||
return None
|
||||
|
||||
|
||||
def extract_blinfo(path):
|
||||
"""Extract bl_info dict from addon at path (can be single file, module, or zip)"""
|
||||
|
||||
source = None
|
||||
# get last component of path, even with trailing slash
|
||||
addon_name = os.path.split(path.rstrip(os.path.sep))[1]
|
||||
|
||||
if os.path.isdir(path):
|
||||
with open(os.path.join(path, '__init__.py' 'r')) as f:
|
||||
source = f.read()
|
||||
else:
|
||||
|
||||
# HACK: perhaps not the best approach determining filetype..?
|
||||
try:
|
||||
with zipfile.ZipFile(path, 'r') as z:
|
||||
for fname in z.namelist():
|
||||
# HACK: this seems potentially fragile; depends on zipfile listing root contents first
|
||||
if fname.endswith('__init__.py'):
|
||||
source = z.read(fname)
|
||||
break
|
||||
except zipfile.BadZipFile:
|
||||
with open(path, 'r') as f:
|
||||
source = f.read()
|
||||
|
||||
if source == None:
|
||||
raise RuntimeError("Could not read addon '%s'" % addon_name)
|
||||
|
||||
return parse_blinfo(source, addon_name)
|
||||
|
||||
|
||||
|
||||
def make_repo(path):
|
||||
"""Make repo.json for files in directory 'path'"""
|
||||
# try:
|
||||
for addon in os.listdir(path):
|
||||
extract_blinfo(os.path.join(path, addon))
|
||||
# except FileNotFoundError:
|
||||
# fatal_report("No such file or directory: '%s'" % path)
|
||||
|
||||
|
||||
|
||||
def main():
|
||||
pass
|
||||
# print(args)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser(description='Search, install, and manage packages for Blender')
|
||||
subparsers = parser.add_subparsers()
|
||||
|
||||
make = subparsers.add_parser('make')
|
||||
make.add_argument('path')
|
||||
make.set_defaults(func=lambda args: make_repo(args.path))
|
||||
|
||||
args = parser.parse_args()
|
||||
args.func(args)
|
||||
|
||||
main()
|
||||
|
||||
|
Reference in New Issue
Block a user