annotate libervia/server/tasks/implicit/task_brython.py @ 1321:eb85ef26cb4a

server: use `bulma` theme as default for default site: `default` theme is not used for now as real default, because dev work is focusing on bulma theme, and the default one may be broken. This should (or may not) change in the future.
author Goffi <goffi@goffi.org>
date Sat, 01 Aug 2020 16:56:04 +0200
parents 0e4e413eb8db
children 089742e065e3
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1247
a6c7f07f1e4d tasks: implicit tasks + Brython task:
Goffi <goffi@goffi.org>
parents:
diff changeset
1 #!/ur/bin/env python3
a6c7f07f1e4d tasks: implicit tasks + Brython task:
Goffi <goffi@goffi.org>
parents:
diff changeset
2
a6c7f07f1e4d tasks: implicit tasks + Brython task:
Goffi <goffi@goffi.org>
parents:
diff changeset
3 import shutil
a6c7f07f1e4d tasks: implicit tasks + Brython task:
Goffi <goffi@goffi.org>
parents:
diff changeset
4 import json
a6c7f07f1e4d tasks: implicit tasks + Brython task:
Goffi <goffi@goffi.org>
parents:
diff changeset
5 from pathlib import Path
a6c7f07f1e4d tasks: implicit tasks + Brython task:
Goffi <goffi@goffi.org>
parents:
diff changeset
6 from ast import literal_eval
a6c7f07f1e4d tasks: implicit tasks + Brython task:
Goffi <goffi@goffi.org>
parents:
diff changeset
7 from sat.core.i18n import _
a6c7f07f1e4d tasks: implicit tasks + Brython task:
Goffi <goffi@goffi.org>
parents:
diff changeset
8 from sat.core.log import getLogger
a6c7f07f1e4d tasks: implicit tasks + Brython task:
Goffi <goffi@goffi.org>
parents:
diff changeset
9 from sat.core import exceptions
1282
0e4e413eb8db server: user new OrderedSet to handle scripts:
Goffi <goffi@goffi.org>
parents: 1279
diff changeset
10 from sat.tools.common import utils
1247
a6c7f07f1e4d tasks: implicit tasks + Brython task:
Goffi <goffi@goffi.org>
parents:
diff changeset
11 from libervia.server.constants import Const as C
1268
e628724530ec pages, tasks (brython): use set for scripts + common template data:
Goffi <goffi@goffi.org>
parents: 1262
diff changeset
12 from libervia.server.classes import Script
1247
a6c7f07f1e4d tasks: implicit tasks + Brython task:
Goffi <goffi@goffi.org>
parents:
diff changeset
13 from libervia.server.tasks import task
a6c7f07f1e4d tasks: implicit tasks + Brython task:
Goffi <goffi@goffi.org>
parents:
diff changeset
14
a6c7f07f1e4d tasks: implicit tasks + Brython task:
Goffi <goffi@goffi.org>
parents:
diff changeset
15
a6c7f07f1e4d tasks: implicit tasks + Brython task:
Goffi <goffi@goffi.org>
parents:
diff changeset
16 log = getLogger(__name__)
a6c7f07f1e4d tasks: implicit tasks + Brython task:
Goffi <goffi@goffi.org>
parents:
diff changeset
17
a6c7f07f1e4d tasks: implicit tasks + Brython task:
Goffi <goffi@goffi.org>
parents:
diff changeset
18
a6c7f07f1e4d tasks: implicit tasks + Brython task:
Goffi <goffi@goffi.org>
parents:
diff changeset
19 class Task(task.Task):
a6c7f07f1e4d tasks: implicit tasks + Brython task:
Goffi <goffi@goffi.org>
parents:
diff changeset
20
a6c7f07f1e4d tasks: implicit tasks + Brython task:
Goffi <goffi@goffi.org>
parents:
diff changeset
21 def prepare(self):
a6c7f07f1e4d tasks: implicit tasks + Brython task:
Goffi <goffi@goffi.org>
parents:
diff changeset
22 if "brython" not in self.resource.browser_modules:
a6c7f07f1e4d tasks: implicit tasks + Brython task:
Goffi <goffi@goffi.org>
parents:
diff changeset
23 raise exceptions.CancelError(f"No brython module found")
a6c7f07f1e4d tasks: implicit tasks + Brython task:
Goffi <goffi@goffi.org>
parents:
diff changeset
24
a6c7f07f1e4d tasks: implicit tasks + Brython task:
Goffi <goffi@goffi.org>
parents:
diff changeset
25 brython_js = self.build_path / "brython.js"
a6c7f07f1e4d tasks: implicit tasks + Brython task:
Goffi <goffi@goffi.org>
parents:
diff changeset
26 if not brython_js.is_file():
a6c7f07f1e4d tasks: implicit tasks + Brython task:
Goffi <goffi@goffi.org>
parents:
diff changeset
27 installed_ver = None
a6c7f07f1e4d tasks: implicit tasks + Brython task:
Goffi <goffi@goffi.org>
parents:
diff changeset
28 else:
a6c7f07f1e4d tasks: implicit tasks + Brython task:
Goffi <goffi@goffi.org>
parents:
diff changeset
29 with brython_js.open() as f:
a6c7f07f1e4d tasks: implicit tasks + Brython task:
Goffi <goffi@goffi.org>
parents:
diff changeset
30 for line in f:
a6c7f07f1e4d tasks: implicit tasks + Brython task:
Goffi <goffi@goffi.org>
parents:
diff changeset
31 if line.startswith('// implementation ['):
a6c7f07f1e4d tasks: implicit tasks + Brython task:
Goffi <goffi@goffi.org>
parents:
diff changeset
32 installed_ver = literal_eval(line[18:])[:3]
a6c7f07f1e4d tasks: implicit tasks + Brython task:
Goffi <goffi@goffi.org>
parents:
diff changeset
33 log.debug(
a6c7f07f1e4d tasks: implicit tasks + Brython task:
Goffi <goffi@goffi.org>
parents:
diff changeset
34 f"brython v{'.'.join(str(v) for v in installed_ver)} already "
a6c7f07f1e4d tasks: implicit tasks + Brython task:
Goffi <goffi@goffi.org>
parents:
diff changeset
35 f"installed")
a6c7f07f1e4d tasks: implicit tasks + Brython task:
Goffi <goffi@goffi.org>
parents:
diff changeset
36 break
a6c7f07f1e4d tasks: implicit tasks + Brython task:
Goffi <goffi@goffi.org>
parents:
diff changeset
37 else:
a6c7f07f1e4d tasks: implicit tasks + Brython task:
Goffi <goffi@goffi.org>
parents:
diff changeset
38 log.warning(
a6c7f07f1e4d tasks: implicit tasks + Brython task:
Goffi <goffi@goffi.org>
parents:
diff changeset
39 f"brython file at {brython_js} doesn't has implementation "
a6c7f07f1e4d tasks: implicit tasks + Brython task:
Goffi <goffi@goffi.org>
parents:
diff changeset
40 f"version"
a6c7f07f1e4d tasks: implicit tasks + Brython task:
Goffi <goffi@goffi.org>
parents:
diff changeset
41 )
a6c7f07f1e4d tasks: implicit tasks + Brython task:
Goffi <goffi@goffi.org>
parents:
diff changeset
42 installed_ver = None
a6c7f07f1e4d tasks: implicit tasks + Brython task:
Goffi <goffi@goffi.org>
parents:
diff changeset
43
1250
821b6ce57f99 server (tasks/brython): log an error if brython is missing and needed
Goffi <goffi@goffi.org>
parents: 1247
diff changeset
44 try:
821b6ce57f99 server (tasks/brython): log an error if brython is missing and needed
Goffi <goffi@goffi.org>
parents: 1247
diff changeset
45 import brython
821b6ce57f99 server (tasks/brython): log an error if brython is missing and needed
Goffi <goffi@goffi.org>
parents: 1247
diff changeset
46 except ModuleNotFoundError as e:
821b6ce57f99 server (tasks/brython): log an error if brython is missing and needed
Goffi <goffi@goffi.org>
parents: 1247
diff changeset
47 log.error('"brython" module is missing, can\'t use browser code for Brython')
821b6ce57f99 server (tasks/brython): log an error if brython is missing and needed
Goffi <goffi@goffi.org>
parents: 1247
diff changeset
48 raise e
1247
a6c7f07f1e4d tasks: implicit tasks + Brython task:
Goffi <goffi@goffi.org>
parents:
diff changeset
49 ver = [int(v) for v in brython.implementation.split('.')[:3]]
a6c7f07f1e4d tasks: implicit tasks + Brython task:
Goffi <goffi@goffi.org>
parents:
diff changeset
50 if ver != installed_ver:
a6c7f07f1e4d tasks: implicit tasks + Brython task:
Goffi <goffi@goffi.org>
parents:
diff changeset
51 log.info(_("Installing Brython v{version}").format(
a6c7f07f1e4d tasks: implicit tasks + Brython task:
Goffi <goffi@goffi.org>
parents:
diff changeset
52 version='.'.join(str(v) for v in ver)))
a6c7f07f1e4d tasks: implicit tasks + Brython task:
Goffi <goffi@goffi.org>
parents:
diff changeset
53 data_path = Path(brython.__file__).parent / 'data'
a6c7f07f1e4d tasks: implicit tasks + Brython task:
Goffi <goffi@goffi.org>
parents:
diff changeset
54 # shutil has blocking method, but the task is run before we start
a6c7f07f1e4d tasks: implicit tasks + Brython task:
Goffi <goffi@goffi.org>
parents:
diff changeset
55 # the web server, so it's not a big deal
a6c7f07f1e4d tasks: implicit tasks + Brython task:
Goffi <goffi@goffi.org>
parents:
diff changeset
56 shutil.copyfile(data_path / "brython.js", brython_js)
1279
2d1ceb026d0e tasks (brython): copy and load `brython_stdlib.js`
Goffi <goffi@goffi.org>
parents: 1268
diff changeset
57 shutil.copy(data_path / "brython_stdlib.js", self.build_path)
1247
a6c7f07f1e4d tasks: implicit tasks + Brython task:
Goffi <goffi@goffi.org>
parents:
diff changeset
58 else:
a6c7f07f1e4d tasks: implicit tasks + Brython task:
Goffi <goffi@goffi.org>
parents:
diff changeset
59 log.debug("Brython is already installed")
a6c7f07f1e4d tasks: implicit tasks + Brython task:
Goffi <goffi@goffi.org>
parents:
diff changeset
60
a6c7f07f1e4d tasks: implicit tasks + Brython task:
Goffi <goffi@goffi.org>
parents:
diff changeset
61 self.WATCH_DIRS = []
a6c7f07f1e4d tasks: implicit tasks + Brython task:
Goffi <goffi@goffi.org>
parents:
diff changeset
62
a6c7f07f1e4d tasks: implicit tasks + Brython task:
Goffi <goffi@goffi.org>
parents:
diff changeset
63 for dyn_data in self.resource.browser_modules["brython"]:
a6c7f07f1e4d tasks: implicit tasks + Brython task:
Goffi <goffi@goffi.org>
parents:
diff changeset
64 url_hash = dyn_data['url_hash']
a6c7f07f1e4d tasks: implicit tasks + Brython task:
Goffi <goffi@goffi.org>
parents:
diff changeset
65 import_url = f"/{C.BUILD_DIR}/{C.BUILD_DIR_DYN}/{url_hash}"
1282
0e4e413eb8db server: user new OrderedSet to handle scripts:
Goffi <goffi@goffi.org>
parents: 1279
diff changeset
66 dyn_data.setdefault('scripts', utils.OrderedSet()).update([
1268
e628724530ec pages, tasks (brython): use set for scripts + common template data:
Goffi <goffi@goffi.org>
parents: 1262
diff changeset
67 Script(src=f"/{C.BUILD_DIR}/brython.js"),
1279
2d1ceb026d0e tasks (brython): copy and load `brython_stdlib.js`
Goffi <goffi@goffi.org>
parents: 1268
diff changeset
68 Script(src=f"/{C.BUILD_DIR}/brython_stdlib.js"),
1282
0e4e413eb8db server: user new OrderedSet to handle scripts:
Goffi <goffi@goffi.org>
parents: 1279
diff changeset
69 ])
1268
e628724530ec pages, tasks (brython): use set for scripts + common template data:
Goffi <goffi@goffi.org>
parents: 1262
diff changeset
70 dyn_data.setdefault('template', {})['body_onload'] = self.getBodyOnload(
e628724530ec pages, tasks (brython): use set for scripts + common template data:
Goffi <goffi@goffi.org>
parents: 1262
diff changeset
71 extra_path=[import_url])
1247
a6c7f07f1e4d tasks: implicit tasks + Brython task:
Goffi <goffi@goffi.org>
parents:
diff changeset
72 self.WATCH_DIRS.append(dyn_data['path'].resolve())
a6c7f07f1e4d tasks: implicit tasks + Brython task:
Goffi <goffi@goffi.org>
parents:
diff changeset
73
1268
e628724530ec pages, tasks (brython): use set for scripts + common template data:
Goffi <goffi@goffi.org>
parents: 1262
diff changeset
74 def getBodyOnload(self, debug=True, cache=True, extra_path=None):
e628724530ec pages, tasks (brython): use set for scripts + common template data:
Goffi <goffi@goffi.org>
parents: 1262
diff changeset
75 on_load_opts = {"pythonpath": [f"/{C.BUILD_DIR}"]}
e628724530ec pages, tasks (brython): use set for scripts + common template data:
Goffi <goffi@goffi.org>
parents: 1262
diff changeset
76 if debug:
e628724530ec pages, tasks (brython): use set for scripts + common template data:
Goffi <goffi@goffi.org>
parents: 1262
diff changeset
77 on_load_opts[debug] = 1
e628724530ec pages, tasks (brython): use set for scripts + common template data:
Goffi <goffi@goffi.org>
parents: 1262
diff changeset
78 if cache:
e628724530ec pages, tasks (brython): use set for scripts + common template data:
Goffi <goffi@goffi.org>
parents: 1262
diff changeset
79 on_load_opts["cache"] = True
e628724530ec pages, tasks (brython): use set for scripts + common template data:
Goffi <goffi@goffi.org>
parents: 1262
diff changeset
80 if extra_path is not None:
e628724530ec pages, tasks (brython): use set for scripts + common template data:
Goffi <goffi@goffi.org>
parents: 1262
diff changeset
81 on_load_opts["pythonpath"].extend(extra_path)
e628724530ec pages, tasks (brython): use set for scripts + common template data:
Goffi <goffi@goffi.org>
parents: 1262
diff changeset
82
e628724530ec pages, tasks (brython): use set for scripts + common template data:
Goffi <goffi@goffi.org>
parents: 1262
diff changeset
83 return f"brython({json.dumps(on_load_opts)})"
e628724530ec pages, tasks (brython): use set for scripts + common template data:
Goffi <goffi@goffi.org>
parents: 1262
diff changeset
84
1253
6d49fae517ba pages: browser metadata + root `_browser`:
Goffi <goffi@goffi.org>
parents: 1250
diff changeset
85 def copyFiles(self, files_paths, dest):
6d49fae517ba pages: browser metadata + root `_browser`:
Goffi <goffi@goffi.org>
parents: 1250
diff changeset
86 for p in files_paths:
6d49fae517ba pages: browser metadata + root `_browser`:
Goffi <goffi@goffi.org>
parents: 1250
diff changeset
87 log.debug(f"copying {p}")
6d49fae517ba pages: browser metadata + root `_browser`:
Goffi <goffi@goffi.org>
parents: 1250
diff changeset
88 if p.is_dir():
6d49fae517ba pages: browser metadata + root `_browser`:
Goffi <goffi@goffi.org>
parents: 1250
diff changeset
89 shutil.copytree(p, dest)
6d49fae517ba pages: browser metadata + root `_browser`:
Goffi <goffi@goffi.org>
parents: 1250
diff changeset
90 else:
6d49fae517ba pages: browser metadata + root `_browser`:
Goffi <goffi@goffi.org>
parents: 1250
diff changeset
91 shutil.copy(p, dest)
6d49fae517ba pages: browser metadata + root `_browser`:
Goffi <goffi@goffi.org>
parents: 1250
diff changeset
92
1247
a6c7f07f1e4d tasks: implicit tasks + Brython task:
Goffi <goffi@goffi.org>
parents:
diff changeset
93 def start(self):
a6c7f07f1e4d tasks: implicit tasks + Brython task:
Goffi <goffi@goffi.org>
parents:
diff changeset
94 dyn_path = self.build_path / C.BUILD_DIR_DYN
a6c7f07f1e4d tasks: implicit tasks + Brython task:
Goffi <goffi@goffi.org>
parents:
diff changeset
95 for dyn_data in self.resource.browser_modules["brython"]:
a6c7f07f1e4d tasks: implicit tasks + Brython task:
Goffi <goffi@goffi.org>
parents:
diff changeset
96 url_hash = dyn_data['url_hash']
1253
6d49fae517ba pages: browser metadata + root `_browser`:
Goffi <goffi@goffi.org>
parents: 1250
diff changeset
97 if url_hash is None:
6d49fae517ba pages: browser metadata + root `_browser`:
Goffi <goffi@goffi.org>
parents: 1250
diff changeset
98 # root modules
1256
08cd652dea14 server, pages, tasks (brython): common_scripts:
Goffi <goffi@goffi.org>
parents: 1253
diff changeset
99 url_prefix = dyn_data.get('url_prefix')
08cd652dea14 server, pages, tasks (brython): common_scripts:
Goffi <goffi@goffi.org>
parents: 1253
diff changeset
100 if url_prefix is None:
08cd652dea14 server, pages, tasks (brython): common_scripts:
Goffi <goffi@goffi.org>
parents: 1253
diff changeset
101 dest = self.build_path
08cd652dea14 server, pages, tasks (brython): common_scripts:
Goffi <goffi@goffi.org>
parents: 1253
diff changeset
102 init_dest_url = f"/{C.BUILD_DIR}/__init__.py"
08cd652dea14 server, pages, tasks (brython): common_scripts:
Goffi <goffi@goffi.org>
parents: 1253
diff changeset
103 else:
08cd652dea14 server, pages, tasks (brython): common_scripts:
Goffi <goffi@goffi.org>
parents: 1253
diff changeset
104 dest = self.build_path / url_prefix
08cd652dea14 server, pages, tasks (brython): common_scripts:
Goffi <goffi@goffi.org>
parents: 1253
diff changeset
105 dest.mkdir(exist_ok = True)
08cd652dea14 server, pages, tasks (brython): common_scripts:
Goffi <goffi@goffi.org>
parents: 1253
diff changeset
106 init_dest_url = f"/{C.BUILD_DIR}/{url_prefix}/__init__.py"
08cd652dea14 server, pages, tasks (brython): common_scripts:
Goffi <goffi@goffi.org>
parents: 1253
diff changeset
107
08cd652dea14 server, pages, tasks (brython): common_scripts:
Goffi <goffi@goffi.org>
parents: 1253
diff changeset
108 self.copyFiles(dyn_data['path'].glob('*py'), dest)
08cd652dea14 server, pages, tasks (brython): common_scripts:
Goffi <goffi@goffi.org>
parents: 1253
diff changeset
109
08cd652dea14 server, pages, tasks (brython): common_scripts:
Goffi <goffi@goffi.org>
parents: 1253
diff changeset
110 init_file = dyn_data['path'] / '__init__.py'
08cd652dea14 server, pages, tasks (brython): common_scripts:
Goffi <goffi@goffi.org>
parents: 1253
diff changeset
111 if init_file.is_file():
1282
0e4e413eb8db server: user new OrderedSet to handle scripts:
Goffi <goffi@goffi.org>
parents: 1279
diff changeset
112 self.resource.dyn_data_common['scripts'].update([
1268
e628724530ec pages, tasks (brython): use set for scripts + common template data:
Goffi <goffi@goffi.org>
parents: 1262
diff changeset
113 Script(src=f"/{C.BUILD_DIR}/brython.js"),
e628724530ec pages, tasks (brython): use set for scripts + common template data:
Goffi <goffi@goffi.org>
parents: 1262
diff changeset
114 Script(type='text/python', src=init_dest_url)
1282
0e4e413eb8db server: user new OrderedSet to handle scripts:
Goffi <goffi@goffi.org>
parents: 1279
diff changeset
115 ])
1268
e628724530ec pages, tasks (brython): use set for scripts + common template data:
Goffi <goffi@goffi.org>
parents: 1262
diff changeset
116 self.resource.dyn_data_common.setdefault(
e628724530ec pages, tasks (brython): use set for scripts + common template data:
Goffi <goffi@goffi.org>
parents: 1262
diff changeset
117 "template", {})['body_onload'] = self.getBodyOnload()
1253
6d49fae517ba pages: browser metadata + root `_browser`:
Goffi <goffi@goffi.org>
parents: 1250
diff changeset
118 else:
6d49fae517ba pages: browser metadata + root `_browser`:
Goffi <goffi@goffi.org>
parents: 1250
diff changeset
119 page_dyn_path = dyn_path / url_hash
6d49fae517ba pages: browser metadata + root `_browser`:
Goffi <goffi@goffi.org>
parents: 1250
diff changeset
120 if page_dyn_path.exists():
6d49fae517ba pages: browser metadata + root `_browser`:
Goffi <goffi@goffi.org>
parents: 1250
diff changeset
121 log.debug("cleaning existing path")
6d49fae517ba pages: browser metadata + root `_browser`:
Goffi <goffi@goffi.org>
parents: 1250
diff changeset
122 shutil.rmtree(page_dyn_path)
1247
a6c7f07f1e4d tasks: implicit tasks + Brython task:
Goffi <goffi@goffi.org>
parents:
diff changeset
123
1253
6d49fae517ba pages: browser metadata + root `_browser`:
Goffi <goffi@goffi.org>
parents: 1250
diff changeset
124 page_dyn_path.mkdir(parents=True, exist_ok=True)
6d49fae517ba pages: browser metadata + root `_browser`:
Goffi <goffi@goffi.org>
parents: 1250
diff changeset
125 log.debug("copying browser python files")
6d49fae517ba pages: browser metadata + root `_browser`:
Goffi <goffi@goffi.org>
parents: 1250
diff changeset
126 self.copyFiles(dyn_data['path'].iterdir(), page_dyn_path)
1247
a6c7f07f1e4d tasks: implicit tasks + Brython task:
Goffi <goffi@goffi.org>
parents:
diff changeset
127
1268
e628724530ec pages, tasks (brython): use set for scripts + common template data:
Goffi <goffi@goffi.org>
parents: 1262
diff changeset
128 script = Script(
e628724530ec pages, tasks (brython): use set for scripts + common template data:
Goffi <goffi@goffi.org>
parents: 1262
diff changeset
129 type='text/python',
e628724530ec pages, tasks (brython): use set for scripts + common template data:
Goffi <goffi@goffi.org>
parents: 1262
diff changeset
130 src=f"/{C.BUILD_DIR}/{C.BUILD_DIR_DYN}/{url_hash}/__init__.py"
e628724530ec pages, tasks (brython): use set for scripts + common template data:
Goffi <goffi@goffi.org>
parents: 1262
diff changeset
131 )
e628724530ec pages, tasks (brython): use set for scripts + common template data:
Goffi <goffi@goffi.org>
parents: 1262
diff changeset
132 dyn_data['scripts'].add(script)