Mercurial > libervia-web
comparison src/server/server.py @ 995:f88325b56a6a
server: dynamic pages first draft:
/!\ new dependency: autobahn
This patch introduce server part of dynamic pages.
Dynamic pages use websockets to establish constant connection with a Libervia page, allowing to receive real time data or update it.
The feature is activated by specifying "dynamic = true" in the page.
Once activated, page can implement "on_data" method which will be called when data are sent by the page.
To send data the other way, the page can use request.sendData.
The new "registerSignal" method allows to use an "on_signal" method to be called each time given signal is received, with automatic (and optional) filtering on profile.
New renderPartial and renderAndUpdate method allow to append new HTML elements to the dynamic page.
author | Goffi <goffi@goffi.org> |
---|---|
date | Wed, 03 Jan 2018 01:10:12 +0100 |
parents | 6daa59d44ee2 |
children | 05cc33d8e328 |
comparison
equal
deleted
inserted
replaced
994:b92b06f023cb | 995:f88325b56a6a |
---|---|
49 import uuid | 49 import uuid |
50 import urlparse | 50 import urlparse |
51 import urllib | 51 import urllib |
52 from httplib import HTTPS_PORT | 52 from httplib import HTTPS_PORT |
53 import libervia | 53 import libervia |
54 from libervia.server import websockets | |
54 from libervia.server.pages import LiberviaPage | 55 from libervia.server.pages import LiberviaPage |
55 from libervia.server.utils import quote | 56 from libervia.server.utils import quote |
56 from functools import partial | 57 from functools import partial |
57 | 58 |
58 try: | 59 try: |
828 avatar = yield self.asyncBridgeCall("avatarGet", entity, cache_only, hash_only, profile) | 829 avatar = yield self.asyncBridgeCall("avatarGet", entity, cache_only, hash_only, profile) |
829 if hash_only: | 830 if hash_only: |
830 defer.returnValue(avatar) | 831 defer.returnValue(avatar) |
831 else: | 832 else: |
832 filename = os.path.basename(avatar) | 833 filename = os.path.basename(avatar) |
833 avatar_url = os.path.join(C.CACHE_DIR, session_data.uuid, filename) | 834 avatar_url = os.path.join(session_data.cache_dir, filename) |
834 defer.returnValue(avatar_url) | 835 defer.returnValue(avatar_url) |
835 | 836 |
836 def jsonrpc_getAccountDialogUI(self): | 837 def jsonrpc_getAccountDialogUI(self): |
837 """Get the dialog for managing user account | 838 """Get the dialog for managing user account |
838 @return: XML string of the XMLUI""" | 839 @return: XML string of the XMLUI""" |
1362 profile = session_iface.ISATSession(request.getSession()).profile | 1363 profile = session_iface.ISATSession(request.getSession()).profile |
1363 return ("setAvatar", filepath, profile) | 1364 return ("setAvatar", filepath, profile) |
1364 | 1365 |
1365 | 1366 |
1366 class Libervia(service.Service): | 1367 class Libervia(service.Service): |
1368 debug = defer.Deferred.debug # True if twistd/Libervia is launched in debug mode | |
1367 | 1369 |
1368 def __init__(self, options): | 1370 def __init__(self, options): |
1369 self.options = options | 1371 self.options = options |
1370 self.initialised = defer.Deferred() | 1372 self.initialised = defer.Deferred() |
1371 self.waiting_profiles = WaitingRequests() # FIXME: should be removed | 1373 self.waiting_profiles = WaitingRequests() # FIXME: should be removed |
1450 | 1452 |
1451 # static pages | 1453 # static pages |
1452 self.putChild('blog', MicroBlog(self)) | 1454 self.putChild('blog', MicroBlog(self)) |
1453 self.putChild(C.THEMES_URL, ProtectedFile(self.themes_dir)) | 1455 self.putChild(C.THEMES_URL, ProtectedFile(self.themes_dir)) |
1454 | 1456 |
1457 # websocket | |
1458 if self.options['connection_type'] in ('https', 'both'): | |
1459 wss = websockets.LiberviaPageWSProtocol.getResource(self, secure=True) | |
1460 self.putChild('wss', wss) | |
1461 if self.options['connection_type'] in ('http', 'both'): | |
1462 ws = websockets.LiberviaPageWSProtocol.getResource(self, secure=False) | |
1463 self.putChild('ws', ws) | |
1464 | |
1465 # Libervia pages | |
1455 LiberviaPage.importPages(self) | 1466 LiberviaPage.importPages(self) |
1456 LiberviaPage.setMenu(self.options['menu_json']) | 1467 LiberviaPage.setMenu(self.options['menu_json']) |
1468 ## following signal is needed for cache handling in Libervia pages | |
1457 self.bridge.register_signal("psEventRaw", partial(LiberviaPage.onNodeEvent, self), "plugin") | 1469 self.bridge.register_signal("psEventRaw", partial(LiberviaPage.onNodeEvent, self), "plugin") |
1470 self.bridge.register_signal("messageNew", partial(LiberviaPage.onSignal, self, "messageNew")) | |
1458 | 1471 |
1459 # media dirs | 1472 # media dirs |
1460 # FIXME: get rid of dirname and "/" in C.XXX_DIR | 1473 # FIXME: get rid of dirname and "/" in C.XXX_DIR |
1461 self.putChild(os.path.dirname(C.MEDIA_DIR), ProtectedFile(self.media_dir)) | 1474 self.putChild(os.path.dirname(C.MEDIA_DIR), ProtectedFile(self.media_dir)) |
1462 self.cache_resource = web_resource.NoResource() | 1475 self.cache_resource = web_resource.NoResource() |
1792 if len(args) == 1: | 1805 if len(args) == 1: |
1793 return args[0](session) | 1806 return args[0](session) |
1794 else: | 1807 else: |
1795 return (iface(session) for iface in args) | 1808 return (iface(session) for iface in args) |
1796 | 1809 |
1810 ## Websocket (dynamic pages) ## | |
1811 | |
1812 def getWebsocketURL(self, request): | |
1813 if request.isSecure(): | |
1814 ws = 'wss' | |
1815 else: | |
1816 ws = 'ws' | |
1817 | |
1818 if self.base_url_ext: | |
1819 base_url = self.base_url_ext | |
1820 else: | |
1821 o = self.options | |
1822 if request.isSecure(): | |
1823 port = o['port_https_ext'] or o['port_https'] | |
1824 else: | |
1825 port = o['port'] | |
1826 base_url = request.getRequestHostname().decode('utf-8') + u':' + unicode(port)+ u'/' | |
1827 | |
1828 return u'{ws}://{base_url}{ws}'.format( | |
1829 ws = ws, | |
1830 base_url = base_url) | |
1831 | |
1832 def registerWSToken(self, token, page, request): | |
1833 websockets.LiberviaPageWSProtocol.registerToken(token, page, request) | |
1834 | |
1797 ## TLS related methods ## | 1835 ## TLS related methods ## |
1798 | 1836 |
1799 def _TLSOptionsCheck(self): | 1837 def _TLSOptionsCheck(self): |
1800 """Check options coherence if TLS is activated, and update missing values | 1838 """Check options coherence if TLS is activated, and update missing values |
1801 | 1839 |