From a0c34a17b8ca26220edb9f20065ae51d5c2232b9 Mon Sep 17 00:00:00 2001 From: yumoqing Date: Thu, 25 Aug 2022 13:32:54 +0800 Subject: [PATCH] bugfix --- kivyblocks/blocks.py | 12 +++--- kivyblocks/script.py | 97 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 104 insertions(+), 5 deletions(-) create mode 100644 kivyblocks/script.py diff --git a/kivyblocks/blocks.py b/kivyblocks/blocks.py index dcb5a90..9368833 100755 --- a/kivyblocks/blocks.py +++ b/kivyblocks/blocks.py @@ -32,6 +32,7 @@ from .newvideo import Video from .orientationlayout import OrientationLayout from .threadcall import HttpClient from .register import * +from .script import Script class WidgetNotFoundById(Exception): def __init__(self, id): @@ -108,6 +109,11 @@ class Blocks(EventDispatcher): self.register_event_type('on_built') self.register_event_type('on_failed') self.env = GlobalEnv() + config = getConfig() + if config.script_root: + self.script = Script(config.script_root) + else: + self.script = Script(config.workdir) def set(self, k:str, v): self.env[k] = v @@ -157,11 +163,7 @@ class Blocks(EventDispatcher): return None if url.startswith('file://'): - filename = url[7:] - with codecs.open(filename,'r','utf-8') as f: - b = f.read() - dic = json.loads(b) - return dic + return self.script.dispatch(url, **params) elif url.startswith('http://') or url.startswith('https://'): try: hc = HttpClient() diff --git a/kivyblocks/script.py b/kivyblocks/script.py new file mode 100644 index 0000000..08e6650 --- /dev/null +++ b/kivyblocks/script.py @@ -0,0 +1,97 @@ +try: + import ujson as json +except: + import json +from os.path import join, sep, dirname, basename +from appPublic.Singleton import GlobalEnv +from appPublic.jsonConfig import getConfig +from appPublic.myTE import MyTemplateEngine + +class Script: + def __init__(self, root): + print('root=', root) + self.root = root + self.env = {} + self.handlers = {} + self.register('.tmpl', TemplateHandler) + self.register('.dspy', DspyHandler) + + def url2filepath(self, url): + if url.startswith('file://'): + url = url[7:] + return join(self.root, *url.split('/')) + + def dispatch(self, url, **kw): + filepath = self.url2filepath(url) + for suffix, handler in self.handlers.items(): + if filepath.endswith(suffix): + env = self.env.copy() + env.update(kw) + env['root_path'] = self.root + env['url'] = url + env['filepath'] = filepath + h = handler(env, **kw) + d = h.render() + try: + return json.loads(d) + except: + return d + + def register(self, suffix, handler): + self.handlers[suffix] = handler + + def set_env(self, n, v): + self.env.update({n:v}) + +class BaseHandler: + def entire_url(self, url): + if url.startswith('file://') or \ + url.startswith('http://') or \ + url.startswith('hppts://'): + return url + p1 = self.env['url'].split('/')[:-1] + p2 = url.split('/') + return '/'.join(p1+p2) + def __init__(self, env): + self.env = env + self.env['entire_url'] = self.entire_url + +class TemplateHandler(BaseHandler): + def __init__(self, env): + super().__init__(env) + root = env['root_path'] + paths = [root] + fp = env['filepath'][len(root):] + plst = fp.split(sep)[:-1] + self.templ_file = basename(env['filepath']) + cpath = root + for p in plst: + cpath = join(cpath, p) + paths.append(cpath) + + self.engine = MyTemplateEngine(paths) + + def render(self): + return self.engine.render(self.templ_file, self.env) + +class DspyHandler(BaseHandler): + def __init__(self, env): + super().__init__(env) + + def loadScript(self, path): + data = '' + with codecs.open(path,'rb','utf-8') as f: + data = f.read() + b= ''.join(data.split('\r')) + lines = b.split('\n') + lines = ['\t' + l for l in lines ] + txt = "def myfunc(request,**ns):\n" + '\n'.join(lines) + return txt + + def render(self, params={}): + lenv = self.env.copy() + lenv.update(params) + txt = self.loadScript(self.env['filepath']) + exec(txt,lenv,lenv) + func = lenv['myfunc'] + return func(self.env, **lenv)