comparison libervia/server/pages.py @ 1246:aaf28d45ae67

pages: browser code, first draft: - code for browser can now be specified if a page subdirectory named `_browser` exists - the default engine used is `Brython` (not yet implemented, so it will do nothing for now) - build_path now uses C.SITE_NAME_DEFAULT for default site instead of empty string, to avoid collision with other sites - ProtectedFile transtype path (first positional argument) to str, so a pathlib.Path can be used
author Goffi <goffi@goffi.org>
date Sun, 26 Apr 2020 22:01:13 +0200
parents f511f8fbbf8a
children 6d49fae517ba
comparison
equal deleted inserted replaced
1245:079e8eb6e327 1246:aaf28d45ae67
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU Affero General Public License for more details. 15 # GNU Affero General Public License for more details.
16 16
17 # You should have received a copy of the GNU Affero General Public License 17 # You should have received a copy of the GNU Affero General Public License
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. 18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
19 from twisted.web import server
20 from twisted.web import resource as web_resource
21 from twisted.web import util as web_util
22 from twisted.internet import defer
23 from twisted.words.protocols.jabber import jid
24 from twisted.python import failure
25
26 from sat.core.i18n import _
27 from sat.core import exceptions
28 from sat.tools.common import date_utils
29 from sat.core.log import getLogger
30 from sat_frontends.bridge.bridge_frontend import BridgeException
31
32 from libervia.server.constants import Const as C
33 from libervia.server import session_iface
34 from libervia.server.utils import quote, SubPage
35 from libervia.server.classes import WebsocketMeta
36 19
37 import uuid 20 import uuid
38 import os.path 21 import os.path
39 import urllib.request, urllib.parse, urllib.error 22 import urllib.request, urllib.parse, urllib.error
40 import time 23 import time
41 import hashlib 24 import hashlib
42 import copy 25 import copy
43 from functools import reduce 26 from functools import reduce
27 from pathlib import Path
28
29 from twisted.web import server
30 from twisted.web import resource as web_resource
31 from twisted.web import util as web_util
32 from twisted.internet import defer
33 from twisted.words.protocols.jabber import jid
34 from twisted.python import failure
35
36 from sat.core.i18n import _
37 from sat.core import exceptions
38 from sat.tools.common import date_utils
39 from sat.core.log import getLogger
40 from sat_frontends.bridge.bridge_frontend import BridgeException
41
42 from libervia.server.constants import Const as C
43 from libervia.server import session_iface
44 from libervia.server.utils import quote, SubPage
45 from libervia.server.classes import WebsocketMeta
44 46
45 log = getLogger(__name__) 47 log = getLogger(__name__)
46 48
47 49
48 class CacheBase(object): 50 class CacheBase(object):
171 self.host = host 173 self.host = host
172 self.vhost_root = vhost_root 174 self.vhost_root = vhost_root
173 self.root_dir = root_dir 175 self.root_dir = root_dir
174 self.url = url 176 self.url = url
175 self.name = name 177 self.name = name
178 self.dyn_data = {}
176 if name is not None: 179 if name is not None:
177 if (name in self.named_pages 180 if (name in self.named_pages
178 and not (replace_on_conflict and self.named_pages[name].url == url)): 181 and not (replace_on_conflict and self.named_pages[name].url == url)):
179 raise exceptions.ConflictError( 182 raise exceptions.ConflictError(
180 _('a Libervia page named "{}" already exists'.format(name))) 183 _('a Libervia page named "{}" already exists'.format(name)))
329 continue 332 continue
330 meta_path = os.path.join(dir_path, C.PAGES_META_FILE) 333 meta_path = os.path.join(dir_path, C.PAGES_META_FILE)
331 if os.path.isfile(meta_path): 334 if os.path.isfile(meta_path):
332 new_path = _path + [d] 335 new_path = _path + [d]
333 try: 336 try:
334 page_data, resource = cls.createPage(host, meta_path, vhost_root, new_path) 337 page_data, resource = cls.createPage(
338 host, meta_path, vhost_root, new_path)
335 except exceptions.ConflictError as e: 339 except exceptions.ConflictError as e:
336 if _extra_pages: 340 if _extra_pages:
337 # extra pages are discarded if there is already an existing page 341 # extra pages are discarded if there is already an existing page
338 continue 342 continue
339 else: 343 else:
367 resource.registerURI(uri_tuple, cb) 371 resource.registerURI(uri_tuple, cb)
368 372
369 LiberviaPage.importPages( 373 LiberviaPage.importPages(
370 host, vhost_root, _parent=resource, _path=new_path, 374 host, vhost_root, _parent=resource, _path=new_path,
371 _extra_pages=_extra_pages) 375 _extra_pages=_extra_pages)
376 # now we check if there is some code for browser
377 browser_path = Path(dir_path) / C.PAGES_BROWSER_DIR
378 if browser_path.is_dir():
379 # for now we only handle Brython
380 dyn_data = {
381 "path": browser_path,
382 "url_hash": hashlib.sha256(
383 '/'.join(new_path).encode()).hexdigest(),
384 }
385 vhost_root.browser_modules.setdefault(
386 "brython", []).append(dyn_data)
387 resource.dyn_data['brython'] = dyn_data
372 388
373 @classmethod 389 @classmethod
374 def onFileChange(cls, host, file_path, flags, site_root, site_path): 390 def onFileChange(cls, host, file_path, flags, site_root, site_path):
375 """Method triggered by file_watcher when something is changed in files 391 """Method triggered by file_watcher when something is changed in files
376 392
1255 template_data["notifications"] = notifs 1271 template_data["notifications"] = notifs
1256 if session_data.locale is not None: 1272 if session_data.locale is not None:
1257 template_data['locale'] = session_data.locale 1273 template_data['locale'] = session_data.locale
1258 if self.vhost_root.site_name: 1274 if self.vhost_root.site_name:
1259 template_data['site'] = self.vhost_root.site_name 1275 template_data['site'] = self.vhost_root.site_name
1276 if self.dyn_data:
1277 for data in self.dyn_data.values():
1278 template_data_dyn = data.get('template', {})
1279 try:
1280 scripts = template_data_dyn['scripts']
1281 except KeyError:
1282 pass
1283 else:
1284 template_data.setdefault('scripts', []).extend(scripts)
1285 template_data.update(template_data_dyn)
1260 1286
1261 return self.host.renderer.render( 1287 return self.host.renderer.render(
1262 self.template, 1288 self.template,
1263 page_url=self.getURL(), 1289 page_url=self.getURL(),
1264 media_path="/" + C.MEDIA_DIR, 1290 media_path="/" + C.MEDIA_DIR,