comparison libervia/server/tasks/implicit/task_brython.py @ 1503:2796e73ed50c

tasks (brython): fix brython scripts loading.
author Goffi <goffi@goffi.org>
date Wed, 01 Mar 2023 17:55:25 +0100
parents b61509c47cac
children 106bae41f5c8
comparison
equal deleted inserted replaced
1502:e1ccba0d2b71 1503:2796e73ed50c
1 #!/ur/bin/env python3 1 #!/ur/bin/env python3
2 2
3 import shutil 3 from ast import literal_eval
4 import json 4 import json
5 from pathlib import Path 5 from pathlib import Path
6 from ast import literal_eval 6 import shutil
7 from typing import Any, Dict
8
9 from sat.core import exceptions
7 from sat.core.i18n import _ 10 from sat.core.i18n import _
8 from sat.core.log import getLogger 11 from sat.core.log import getLogger
9 from sat.core import exceptions
10 from sat.tools.common import utils 12 from sat.tools.common import utils
13
14 from libervia.server.classes import Script
11 from libervia.server.constants import Const as C 15 from libervia.server.constants import Const as C
12 from libervia.server.classes import Script
13 from libervia.server.tasks import task 16 from libervia.server.tasks import task
14 17
15 18
16 log = getLogger(__name__) 19 log = getLogger(__name__)
17 20
41 ) 44 )
42 installed_ver = None 45 installed_ver = None
43 46
44 try: 47 try:
45 import brython 48 import brython
49 from brython import version as brython_version
46 except ModuleNotFoundError as e: 50 except ModuleNotFoundError as e:
47 log.error('"brython" module is missing, can\'t use browser code for Brython') 51 log.error('"brython" module is missing, can\'t use browser code for Brython')
48 raise e 52 raise e
49 ver = [int(v) for v in brython.implementation.split('.')[:3]] 53 ver = [int(v) for v in brython_version.implementation.split('.')[:3]]
50 if ver != installed_ver: 54 if ver != installed_ver:
51 log.info(_("Installing Brython v{version}").format( 55 log.info(_("Installing Brython v{version}").format(
52 version='.'.join(str(v) for v in ver))) 56 version='.'.join(str(v) for v in ver)))
53 data_path = Path(brython.__file__).parent / 'data' 57 data_path = Path(brython.__file__).parent / 'data'
54 # shutil has blocking method, but the task is run before we start 58 # shutil has blocking method, but the task is run before we start
57 shutil.copy(data_path / "brython_stdlib.js", self.build_path) 61 shutil.copy(data_path / "brython_stdlib.js", self.build_path)
58 else: 62 else:
59 log.debug("Brython is already installed") 63 log.debug("Brython is already installed")
60 64
61 self.WATCH_DIRS = [] 65 self.WATCH_DIRS = []
62 self.setCommonScripts() 66 self.set_common_scripts()
63 67
64 def setCommonScripts(self): 68 def set_common_scripts(self):
65 for dyn_data in self.resource.browser_modules["brython"]: 69 for dyn_data in self.resource.browser_modules["brython"]:
66 url_hash = dyn_data['url_hash'] 70 url_hash = dyn_data['url_hash']
67 import_url = f"/{C.BUILD_DIR}/{C.BUILD_DIR_DYN}/{url_hash}" 71 import_url = f"/{C.BUILD_DIR}/{C.BUILD_DIR_DYN}/{url_hash}"
68 dyn_data.setdefault('scripts', utils.OrderedSet()).update([ 72 dyn_data.setdefault('scripts', utils.OrderedSet()).update([
69 Script(src=f"/{C.BUILD_DIR}/brython.js"), 73 Script(src=f"/{C.BUILD_DIR}/brython.js"),
70 Script(src=f"/{C.BUILD_DIR}/brython_stdlib.js"), 74 Script(src=f"/{C.BUILD_DIR}/brython_stdlib.js"),
71 ]) 75 ])
72 dyn_data.setdefault('template', {})['body_onload'] = self.getBodyOnload( 76 dyn_data.setdefault('template', {})['body_onload'] = self.get_body_onload(
73 extra_path=[import_url]) 77 extra_path=[import_url])
74 self.WATCH_DIRS.append(dyn_data['path'].resolve()) 78 self.WATCH_DIRS.append(dyn_data['path'].resolve())
75 79
76 def getBodyOnload(self, debug=True, cache=True, extra_path=None): 80 def get_body_onload(self, debug=True, cache=True, extra_path=None):
77 on_load_opts = {"pythonpath": [f"/{C.BUILD_DIR}"]} 81 on_load_opts: Dict[str, Any] = {"pythonpath": [f"/{C.BUILD_DIR}"]}
78 if debug: 82 if debug:
79 on_load_opts[debug] = 1 83 on_load_opts["debug"] = 1
80 if cache: 84 if cache:
81 on_load_opts["cache"] = True 85 on_load_opts["cache"] = True
82 if extra_path is not None: 86 if extra_path is not None:
83 on_load_opts["pythonpath"].extend(extra_path) 87 on_load_opts["pythonpath"].extend(extra_path)
84 88
85 return f"brython({json.dumps(on_load_opts)})" 89 return f"brython({json.dumps(on_load_opts)})"
86 90
87 def copyFiles(self, files_paths, dest): 91 def copy_files(self, files_paths, dest):
88 for p in files_paths: 92 for p in files_paths:
89 log.debug(f"copying {p}") 93 log.debug(f"copying {p}")
90 if p.is_dir(): 94 if p.is_dir():
91 if p.name == '__pycache__': 95 if p.name == '__pycache__':
92 continue 96 continue
93 shutil.copytree(p, dest / p.name) 97 shutil.copytree(p, dest / p.name)
94 else: 98 else:
95 shutil.copy(p, dest) 99 shutil.copy(p, dest)
96 100
97 async def onDirEvent(self, host, filepath, flags): 101 async def onDirEvent(self, host, filepath, flags):
98 self.setCommonScripts() 102 self.set_common_scripts()
99 await self.manager.runTaskInstance(self) 103 await self.manager.runTaskInstance(self)
100 104
101 def start(self): 105 def start(self):
102 dyn_path = self.build_path / C.BUILD_DIR_DYN 106 dyn_path = self.build_path / C.BUILD_DIR_DYN
103 for dyn_data in self.resource.browser_modules["brython"]: 107 for dyn_data in self.resource.browser_modules["brython"]:
111 else: 115 else:
112 dest = self.build_path / url_prefix 116 dest = self.build_path / url_prefix
113 dest.mkdir(exist_ok = True) 117 dest.mkdir(exist_ok = True)
114 init_dest_url = f"/{C.BUILD_DIR}/{url_prefix}/__init__.py" 118 init_dest_url = f"/{C.BUILD_DIR}/{url_prefix}/__init__.py"
115 119
116 self.copyFiles(dyn_data['path'].glob('*py'), dest) 120 self.copy_files(dyn_data['path'].glob('*py'), dest)
117 121
118 init_file = dyn_data['path'] / '__init__.py' 122 init_file = dyn_data['path'] / '__init__.py'
119 if init_file.is_file(): 123 if init_file.is_file():
120 self.resource.dyn_data_common['scripts'].update([ 124 self.resource.dyn_data_common['scripts'].update([
121 Script(src=f"/{C.BUILD_DIR}/brython.js"), 125 Script(src=f"/{C.BUILD_DIR}/brython.js"),
126 Script(src=f"/{C.BUILD_DIR}/brython_stdlib.js"),
122 Script(type='text/python', src=init_dest_url) 127 Script(type='text/python', src=init_dest_url)
123 ]) 128 ])
124 self.resource.dyn_data_common.setdefault( 129 self.resource.dyn_data_common.setdefault(
125 "template", {})['body_onload'] = self.getBodyOnload() 130 "template", {})['body_onload'] = self.get_body_onload()
126 else: 131 else:
127 page_dyn_path = dyn_path / url_hash 132 page_dyn_path = dyn_path / url_hash
128 log.debug(f"using dynamic path at {page_dyn_path}") 133 log.debug(f"using dynamic path at {page_dyn_path}")
129 if page_dyn_path.exists(): 134 if page_dyn_path.exists():
130 log.debug("cleaning existing path") 135 log.debug("cleaning existing path")
131 shutil.rmtree(page_dyn_path) 136 shutil.rmtree(page_dyn_path)
132 137
133 page_dyn_path.mkdir(parents=True, exist_ok=True) 138 page_dyn_path.mkdir(parents=True, exist_ok=True)
134 log.debug("copying browser python files") 139 log.debug("copying browser python files")
135 self.copyFiles(dyn_data['path'].iterdir(), page_dyn_path) 140 self.copy_files(dyn_data['path'].iterdir(), page_dyn_path)
136 141
137 script = Script( 142 script = Script(
138 type='text/python', 143 type='text/python',
139 src=f"/{C.BUILD_DIR}/{C.BUILD_DIR_DYN}/{url_hash}/__init__.py" 144 src=f"/{C.BUILD_DIR}/{C.BUILD_DIR_DYN}/{url_hash}/__init__.py"
140 ) 145 )