annotate src/server/pages.py @ 998:0848b8b0188d

pages: dynamic set up is now done just before prepare_render call: dynamic set up is not done at the beginning of the page workflow anymore because dynamic method should not be used during parse_url and page workflow may switch in case of redirection.
author Goffi <goffi@goffi.org>
date Fri, 05 Jan 2018 16:29:29 +0100
parents f88325b56a6a
children 05cc33d8e328
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
331
06a48d805547 server side: make Libervia a Twisted plugin, and add it the --port argument + add a config file for the port.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 330
diff changeset
1 #!/usr/bin/python
06a48d805547 server side: make Libervia a Twisted plugin, and add it the --port argument + add a config file for the port.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 330
diff changeset
2 # -*- coding: utf-8 -*-
06a48d805547 server side: make Libervia a Twisted plugin, and add it the --port argument + add a config file for the port.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 330
diff changeset
3
339
2067d6241927 fixed docstrings wrong usage for licence informations
Goffi <goffi@goffi.org>
parents: 336
diff changeset
4 # Libervia: a Salut à Toi frontend
964
fd4eae654182 misc: date update (yes it's a bit late :p )
Goffi <goffi@goffi.org>
parents: 962
diff changeset
5 # Copyright (C) 2011-2017 Jérôme Poisson <goffi@goffi.org>
331
06a48d805547 server side: make Libervia a Twisted plugin, and add it the --port argument + add a config file for the port.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 330
diff changeset
6
339
2067d6241927 fixed docstrings wrong usage for licence informations
Goffi <goffi@goffi.org>
parents: 336
diff changeset
7 # This program is free software: you can redistribute it and/or modify
2067d6241927 fixed docstrings wrong usage for licence informations
Goffi <goffi@goffi.org>
parents: 336
diff changeset
8 # it under the terms of the GNU Affero General Public License as published by
2067d6241927 fixed docstrings wrong usage for licence informations
Goffi <goffi@goffi.org>
parents: 336
diff changeset
9 # the Free Software Foundation, either version 3 of the License, or
2067d6241927 fixed docstrings wrong usage for licence informations
Goffi <goffi@goffi.org>
parents: 336
diff changeset
10 # (at your option) any later version.
331
06a48d805547 server side: make Libervia a Twisted plugin, and add it the --port argument + add a config file for the port.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 330
diff changeset
11
339
2067d6241927 fixed docstrings wrong usage for licence informations
Goffi <goffi@goffi.org>
parents: 336
diff changeset
12 # This program is distributed in the hope that it will be useful,
2067d6241927 fixed docstrings wrong usage for licence informations
Goffi <goffi@goffi.org>
parents: 336
diff changeset
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
2067d6241927 fixed docstrings wrong usage for licence informations
Goffi <goffi@goffi.org>
parents: 336
diff changeset
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2067d6241927 fixed docstrings wrong usage for licence informations
Goffi <goffi@goffi.org>
parents: 336
diff changeset
15 # GNU Affero General Public License for more details.
331
06a48d805547 server side: make Libervia a Twisted plugin, and add it the --port argument + add a config file for the port.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 330
diff changeset
16
339
2067d6241927 fixed docstrings wrong usage for licence informations
Goffi <goffi@goffi.org>
parents: 336
diff changeset
17 # You should have received a copy of the GNU Affero General Public License
2067d6241927 fixed docstrings wrong usage for licence informations
Goffi <goffi@goffi.org>
parents: 336
diff changeset
18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
331
06a48d805547 server side: make Libervia a Twisted plugin, and add it the --port argument + add a config file for the port.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 330
diff changeset
19 from twisted.web import server
858
7dde76708892 server: URL redirections + misc:
Goffi <goffi@goffi.org>
parents: 856
diff changeset
20 from twisted.web import resource as web_resource
7dde76708892 server: URL redirections + misc:
Goffi <goffi@goffi.org>
parents: 856
diff changeset
21 from twisted.web import util as web_util
984
f0fc28b3bd1e server: moved LiberviaPage code in its own module
Goffi <goffi@goffi.org>
parents: 980
diff changeset
22 from twisted.internet import defer
985
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
23 from twisted.words.protocols.jabber import jid
917
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
24 from twisted.python import failure
449
981ed669d3b3 /!\ reorganize all the file hierarchy, move the code and launching script to src:
souliane <souliane@mailoo.org>
parents: 448
diff changeset
25
984
f0fc28b3bd1e server: moved LiberviaPage code in its own module
Goffi <goffi@goffi.org>
parents: 980
diff changeset
26 from sat.core.i18n import _
f0fc28b3bd1e server: moved LiberviaPage code in its own module
Goffi <goffi@goffi.org>
parents: 980
diff changeset
27 from sat.core import exceptions
f0fc28b3bd1e server: moved LiberviaPage code in its own module
Goffi <goffi@goffi.org>
parents: 980
diff changeset
28 from sat.tools.common import uri as common_uri
438
582c435dab6b server side: new log system is used
Goffi <goffi@goffi.org>
parents: 435
diff changeset
29 from sat.core.log import getLogger
582c435dab6b server side: new log system is used
Goffi <goffi@goffi.org>
parents: 435
diff changeset
30 log = getLogger(__name__)
984
f0fc28b3bd1e server: moved LiberviaPage code in its own module
Goffi <goffi@goffi.org>
parents: 980
diff changeset
31 from libervia.server.constants import Const as C
f0fc28b3bd1e server: moved LiberviaPage code in its own module
Goffi <goffi@goffi.org>
parents: 980
diff changeset
32 from libervia.server import session_iface
f0fc28b3bd1e server: moved LiberviaPage code in its own module
Goffi <goffi@goffi.org>
parents: 980
diff changeset
33 from libervia.server.utils import quote
682
e6bb64bd6b4d server side: implemented methods to get SàT and Libervia versions
Goffi <goffi@goffi.org>
parents: 679
diff changeset
34 import libervia
331
06a48d805547 server side: make Libervia a Twisted plugin, and add it the --port argument + add a config file for the port.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 330
diff changeset
35
995
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
36 from collections import namedtuple
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
37 import uuid
984
f0fc28b3bd1e server: moved LiberviaPage code in its own module
Goffi <goffi@goffi.org>
parents: 980
diff changeset
38 import os.path
f0fc28b3bd1e server: moved LiberviaPage code in its own module
Goffi <goffi@goffi.org>
parents: 980
diff changeset
39 import urllib
985
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
40 import time
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
41
995
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
42 WebsocketMeta = namedtuple("WebsocketMeta", ('url', 'token', 'debug'))
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
43
985
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
44
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
45 class Cache(object):
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
46
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
47 def __init__(self, rendered):
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
48 self._created = time.time()
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
49 self._last_access = self._created
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
50 self._rendered = rendered
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
51
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
52 @property
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
53 def created(self):
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
54 return self._created
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
55
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
56 @property
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
57 def last_access(self):
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
58 return self._last_access
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
59
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
60 @last_access.setter
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
61 def last_access(self, timestamp):
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
62 self._last_access = timestamp
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
63
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
64 @property
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
65 def rendered(self):
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
66 return self._rendered
331
06a48d805547 server side: make Libervia a Twisted plugin, and add it the --port argument + add a config file for the port.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 330
diff changeset
67
06a48d805547 server side: make Libervia a Twisted plugin, and add it the --port argument + add a config file for the port.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 330
diff changeset
68
917
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
69 class LiberviaPage(web_resource.Resource):
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
70 isLeaf = True # we handle subpages ourself
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
71 named_pages = {}
925
e00151140f77 server (pages): URIs handling:
Goffi <goffi@goffi.org>
parents: 924
diff changeset
72 uri_callbacks = {}
995
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
73 signals_handlers = {}
980
bcacf970f970 core (pages redirection): inverted redirection + getSubPageURL:
Goffi <goffi@goffi.org>
parents: 979
diff changeset
74 pages_redirects = {}
985
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
75 cache = {}
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
76 # Set of tuples (service/node/sub_id) of nodes subscribed for caching
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
77 # sub_id can be empty string if not handled by service
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
78 cache_pubsub_sub = set()
990
6daa59d44ee2 pages: menu implementation, first draft:
Goffi <goffi@goffi.org>
parents: 985
diff changeset
79 main_menu = None
917
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
80
995
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
81 def __init__(self, host, root_dir, url, name=None, redirect=None, access=None, dynamic=False, parse_url=None,
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
82 prepare_render=None, render=None, template=None,
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
83 on_data_post=None, on_data=None, on_signal=None):
917
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
84 """initiate LiberviaPages
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
85
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
86 LiberviaPages are the main resources of Libervia, using easy to set python files
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
87 The arguments are the variables found in page_meta.py
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
88 @param host(Libervia): the running instance of Libervia
962
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
89 @param root_dir(unicode): aboslute file path of the page
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
90 @param url(unicode): relative URL to the page
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
91 this URL may not be valid, as pages may require path arguments
917
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
92 @param name(unicode, None): if not None, a unique name to identify the page
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
93 can then be used for e.g. redirection
923
edb322c87ea4 server (pages): pages now handle redirection, check self.pageRedirect docstring for details
Goffi <goffi@goffi.org>
parents: 922
diff changeset
94 "/" is not allowed in names (as it can be used to construct URL paths)
962
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
95 @param redirect(unicode, None): if not None, this page will be redirected. A redirected
923
edb322c87ea4 server (pages): pages now handle redirection, check self.pageRedirect docstring for details
Goffi <goffi@goffi.org>
parents: 922
diff changeset
96 parameter is used as in self.pageRedirect. parse_url will not be skipped
edb322c87ea4 server (pages): pages now handle redirection, check self.pageRedirect docstring for details
Goffi <goffi@goffi.org>
parents: 922
diff changeset
97 using this redirect parameter is called "full redirection"
edb322c87ea4 server (pages): pages now handle redirection, check self.pageRedirect docstring for details
Goffi <goffi@goffi.org>
parents: 922
diff changeset
98 using self.pageRedirect is called "partial redirection" (because some rendering method
edb322c87ea4 server (pages): pages now handle redirection, check self.pageRedirect docstring for details
Goffi <goffi@goffi.org>
parents: 922
diff changeset
99 can still be used, e.g. parse_url)
917
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
100 @param access(unicode, None): permission needed to access the page
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
101 None means public access.
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
102 Pages inherit from parent pages: e.g. if a "settings" page is restricted to admins,
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
103 and if "settings/blog" is public, it still can only be accessed by admins.
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
104 see C.PAGES_ACCESS_* for details
995
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
105 @param dynamic(bool): if True, activate websocket for bidirectional communication
917
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
106 @param parse_url(callable, None): if set it will be called to handle the URL path
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
107 after this method, the page will be rendered if noting is left in path (request.postpath)
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
108 else a the request will be transmitted to a subpage
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
109 @param prepare_render(callable, None): if set, will be used to prepare the rendering
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
110 that often means gathering data using the bridge
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
111 @param render(callable, None): if not template is set, this method will be called and
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
112 what it returns will be rendered.
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
113 This method is mutually exclusive with template and must return a unicode string.
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
114 @param template(unicode, None): path to the template to render.
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
115 This method is mutually exclusive with render
931
8a393ae90f8c server (pages): post requests are now handled:
Goffi <goffi@goffi.org>
parents: 927
diff changeset
116 @param on_data_post(callable, None): method to call when data is posted
8a393ae90f8c server (pages): post requests are now handled:
Goffi <goffi@goffi.org>
parents: 927
diff changeset
117 None if not post is handled
962
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
118 on_data_post can return a string with following value:
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
119 - C.POST_NO_CONFIRM: confirm flag will not be set
995
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
120 @param on_data(callable, None): method to call when dynamic data is sent
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
121 this method is used with Libervia's websocket mechanism
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
122 @param on_signal(callable, None): method to call when a registered signal is received
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
123 this method is used with Libervia's websocket mechanism
917
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
124 """
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
125
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
126 web_resource.Resource.__init__(self)
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
127 self.host = host
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
128 self.root_dir = root_dir
962
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
129 self.url = url
980
bcacf970f970 core (pages redirection): inverted redirection + getSubPageURL:
Goffi <goffi@goffi.org>
parents: 979
diff changeset
130 self.name = name
917
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
131 if name is not None:
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
132 if name in self.named_pages:
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
133 raise exceptions.ConflictError(_(u'a Libervia page named "{}" already exists'.format(name)))
923
edb322c87ea4 server (pages): pages now handle redirection, check self.pageRedirect docstring for details
Goffi <goffi@goffi.org>
parents: 922
diff changeset
134 if u'/' in name:
edb322c87ea4 server (pages): pages now handle redirection, check self.pageRedirect docstring for details
Goffi <goffi@goffi.org>
parents: 922
diff changeset
135 raise ValueError(_(u'"/" is not allowed in page names'))
edb322c87ea4 server (pages): pages now handle redirection, check self.pageRedirect docstring for details
Goffi <goffi@goffi.org>
parents: 922
diff changeset
136 if not name:
edb322c87ea4 server (pages): pages now handle redirection, check self.pageRedirect docstring for details
Goffi <goffi@goffi.org>
parents: 922
diff changeset
137 raise ValueError(_(u"a page name can't be empty"))
917
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
138 self.named_pages[name] = self
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
139 if access is None:
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
140 access = C.PAGES_ACCESS_PUBLIC
922
16d1084d1371 server (pages): added "None" access (page is not rendered at all) and some HTTP code constants + helper methods to get session data
Goffi <goffi@goffi.org>
parents: 921
diff changeset
141 if access not in (C.PAGES_ACCESS_PUBLIC, C.PAGES_ACCESS_PROFILE, C.PAGES_ACCESS_NONE):
16d1084d1371 server (pages): added "None" access (page is not rendered at all) and some HTTP code constants + helper methods to get session data
Goffi <goffi@goffi.org>
parents: 921
diff changeset
142 raise NotImplementedError(_(u"{} access is not implemented yet").format(access))
16d1084d1371 server (pages): added "None" access (page is not rendered at all) and some HTTP code constants + helper methods to get session data
Goffi <goffi@goffi.org>
parents: 921
diff changeset
143 self.access = access
995
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
144 self.dynamic = dynamic
923
edb322c87ea4 server (pages): pages now handle redirection, check self.pageRedirect docstring for details
Goffi <goffi@goffi.org>
parents: 922
diff changeset
145 if redirect is not None:
edb322c87ea4 server (pages): pages now handle redirection, check self.pageRedirect docstring for details
Goffi <goffi@goffi.org>
parents: 922
diff changeset
146 # only page access and name make sense in case of full redirection
980
bcacf970f970 core (pages redirection): inverted redirection + getSubPageURL:
Goffi <goffi@goffi.org>
parents: 979
diff changeset
147 # so we check that rendering methods/values are not set
923
edb322c87ea4 server (pages): pages now handle redirection, check self.pageRedirect docstring for details
Goffi <goffi@goffi.org>
parents: 922
diff changeset
148 if not all(lambda x: x is not None
edb322c87ea4 server (pages): pages now handle redirection, check self.pageRedirect docstring for details
Goffi <goffi@goffi.org>
parents: 922
diff changeset
149 for x in (parse_url, prepare_render, render, template)):
980
bcacf970f970 core (pages redirection): inverted redirection + getSubPageURL:
Goffi <goffi@goffi.org>
parents: 979
diff changeset
150 raise ValueError(_(u"you can't use full page redirection with other rendering method,"
bcacf970f970 core (pages redirection): inverted redirection + getSubPageURL:
Goffi <goffi@goffi.org>
parents: 979
diff changeset
151 u"check self.pageRedirect if you need to use them"))
923
edb322c87ea4 server (pages): pages now handle redirection, check self.pageRedirect docstring for details
Goffi <goffi@goffi.org>
parents: 922
diff changeset
152 self.redirect = redirect
edb322c87ea4 server (pages): pages now handle redirection, check self.pageRedirect docstring for details
Goffi <goffi@goffi.org>
parents: 922
diff changeset
153 else:
edb322c87ea4 server (pages): pages now handle redirection, check self.pageRedirect docstring for details
Goffi <goffi@goffi.org>
parents: 922
diff changeset
154 self.redirect = None
917
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
155 self.parse_url = parse_url
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
156 self.prepare_render = prepare_render
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
157 self.template = template
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
158 self.render_method = render
931
8a393ae90f8c server (pages): post requests are now handled:
Goffi <goffi@goffi.org>
parents: 927
diff changeset
159 self.on_data_post = on_data_post
995
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
160 self.on_data = on_data
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
161 self.on_signal = on_signal
922
16d1084d1371 server (pages): added "None" access (page is not rendered at all) and some HTTP code constants + helper methods to get session data
Goffi <goffi@goffi.org>
parents: 921
diff changeset
162 if access == C.PAGES_ACCESS_NONE:
16d1084d1371 server (pages): added "None" access (page is not rendered at all) and some HTTP code constants + helper methods to get session data
Goffi <goffi@goffi.org>
parents: 921
diff changeset
163 # none pages just return a 404, no further check is needed
16d1084d1371 server (pages): added "None" access (page is not rendered at all) and some HTTP code constants + helper methods to get session data
Goffi <goffi@goffi.org>
parents: 921
diff changeset
164 return
917
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
165 if template is None:
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
166 if not callable(render):
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
167 log.error(_(u"render must be implemented and callable if template is not set"))
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
168 else:
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
169 if render is not None:
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
170 log.error(_(u"render can't be used at the same time as template"))
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
171 if parse_url is not None and not callable(parse_url):
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
172 log.error(_(u"parse_url must be a callable"))
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
173
985
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
174 # if not None, next rendering will be cached
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
175 # it must then contain a list of the the keys to use (without the page instance)
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
176 # e.g. [C.SERVICE_PROFILE, "pubsub", server@example.tld, pubsub_node] 
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
177 self._do_cache = None
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
178
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
179 def __unicode__(self):
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
180 return u'LiberviaPage {name} at {url}'.format(
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
181 name = self.name or u'<anonymous>',
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
182 url = self.url)
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
183
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
184 def __str__(self):
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
185 return self.__unicode__.encode('utf-8')
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
186
925
e00151140f77 server (pages): URIs handling:
Goffi <goffi@goffi.org>
parents: 924
diff changeset
187 @classmethod
e00151140f77 server (pages): URIs handling:
Goffi <goffi@goffi.org>
parents: 924
diff changeset
188 def importPages(cls, host, parent=None, path=None):
937
00236973e138 server (pages): an HTTP internal error is raised if an error is uncatched during page workflow
Goffi <goffi@goffi.org>
parents: 936
diff changeset
189 """Recursively import Libervia pages"""
917
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
190 if path is None:
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
191 path = []
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
192 if parent is None:
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
193 root_dir = os.path.join(os.path.dirname(libervia.__file__), C.PAGES_DIR)
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
194 parent = host
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
195 else:
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
196 root_dir = parent.root_dir
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
197 for d in os.listdir(root_dir):
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
198 dir_path = os.path.join(root_dir, d)
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
199 if not os.path.isdir(dir_path):
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
200 continue
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
201 meta_path = os.path.join(dir_path, C.PAGES_META_FILE)
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
202 if os.path.isfile(meta_path):
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
203 page_data = {}
962
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
204 new_path = path + [d]
917
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
205 # we don't want to force the presence of __init__.py
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
206 # so we use execfile instead of import.
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
207 # TODO: when moved to Python 3, __init__.py is not mandatory anymore
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
208 # so we can switch to import
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
209 execfile(meta_path, page_data)
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
210 resource = LiberviaPage(
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
211 host,
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
212 dir_path,
962
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
213 u'/' + u'/'.join(new_path),
917
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
214 name=page_data.get('name'),
923
edb322c87ea4 server (pages): pages now handle redirection, check self.pageRedirect docstring for details
Goffi <goffi@goffi.org>
parents: 922
diff changeset
215 redirect=page_data.get('redirect'),
917
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
216 access=page_data.get('access'),
995
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
217 dynamic=page_data.get('dynamic', False),
917
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
218 parse_url=page_data.get('parse_url'),
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
219 prepare_render=page_data.get('prepare_render'),
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
220 render=page_data.get('render'),
931
8a393ae90f8c server (pages): post requests are now handled:
Goffi <goffi@goffi.org>
parents: 927
diff changeset
221 template=page_data.get('template'),
995
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
222 on_data_post=page_data.get('on_data_post'),
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
223 on_data=page_data.get('on_data'),
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
224 on_signal=page_data.get('on_signal'),
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
225 )
917
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
226 parent.putChild(d, resource)
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
227 log.info(u"Added /{path} page".format(path=u'[...]/'.join(new_path)))
925
e00151140f77 server (pages): URIs handling:
Goffi <goffi@goffi.org>
parents: 924
diff changeset
228 if 'uri_handlers' in page_data:
e00151140f77 server (pages): URIs handling:
Goffi <goffi@goffi.org>
parents: 924
diff changeset
229 if not isinstance(page_data, dict):
e00151140f77 server (pages): URIs handling:
Goffi <goffi@goffi.org>
parents: 924
diff changeset
230 log.error(_(u'uri_handlers must be a dict'))
e00151140f77 server (pages): URIs handling:
Goffi <goffi@goffi.org>
parents: 924
diff changeset
231 else:
e00151140f77 server (pages): URIs handling:
Goffi <goffi@goffi.org>
parents: 924
diff changeset
232 for uri_tuple, cb_name in page_data['uri_handlers'].iteritems():
e00151140f77 server (pages): URIs handling:
Goffi <goffi@goffi.org>
parents: 924
diff changeset
233 if len(uri_tuple) != 2 or not isinstance(cb_name, basestring):
e00151140f77 server (pages): URIs handling:
Goffi <goffi@goffi.org>
parents: 924
diff changeset
234 log.error(_(u"invalid uri_tuple"))
e00151140f77 server (pages): URIs handling:
Goffi <goffi@goffi.org>
parents: 924
diff changeset
235 continue
e00151140f77 server (pages): URIs handling:
Goffi <goffi@goffi.org>
parents: 924
diff changeset
236 log.info(_(u'setting {}/{} URIs handler').format(*uri_tuple))
e00151140f77 server (pages): URIs handling:
Goffi <goffi@goffi.org>
parents: 924
diff changeset
237 try:
e00151140f77 server (pages): URIs handling:
Goffi <goffi@goffi.org>
parents: 924
diff changeset
238 cb = page_data[cb_name]
e00151140f77 server (pages): URIs handling:
Goffi <goffi@goffi.org>
parents: 924
diff changeset
239 except KeyError:
e00151140f77 server (pages): URIs handling:
Goffi <goffi@goffi.org>
parents: 924
diff changeset
240 log.error(_(u'missing {name} method to handle {1}/{2}').format(
e00151140f77 server (pages): URIs handling:
Goffi <goffi@goffi.org>
parents: 924
diff changeset
241 name = cb_name, *uri_tuple))
e00151140f77 server (pages): URIs handling:
Goffi <goffi@goffi.org>
parents: 924
diff changeset
242 continue
e00151140f77 server (pages): URIs handling:
Goffi <goffi@goffi.org>
parents: 924
diff changeset
243 else:
e00151140f77 server (pages): URIs handling:
Goffi <goffi@goffi.org>
parents: 924
diff changeset
244 cls.registerURI(uri_tuple, cb, new_path)
e00151140f77 server (pages): URIs handling:
Goffi <goffi@goffi.org>
parents: 924
diff changeset
245
917
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
246 LiberviaPage.importPages(host, resource, new_path)
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
247
925
e00151140f77 server (pages): URIs handling:
Goffi <goffi@goffi.org>
parents: 924
diff changeset
248 @classmethod
990
6daa59d44ee2 pages: menu implementation, first draft:
Goffi <goffi@goffi.org>
parents: 985
diff changeset
249 def setMenu(cls, menus):
6daa59d44ee2 pages: menu implementation, first draft:
Goffi <goffi@goffi.org>
parents: 985
diff changeset
250 main_menu = []
6daa59d44ee2 pages: menu implementation, first draft:
Goffi <goffi@goffi.org>
parents: 985
diff changeset
251 for menu in menus:
6daa59d44ee2 pages: menu implementation, first draft:
Goffi <goffi@goffi.org>
parents: 985
diff changeset
252 if not menu:
6daa59d44ee2 pages: menu implementation, first draft:
Goffi <goffi@goffi.org>
parents: 985
diff changeset
253 raise ValueError(_(u"menu item can't be empty"))
6daa59d44ee2 pages: menu implementation, first draft:
Goffi <goffi@goffi.org>
parents: 985
diff changeset
254 elif isinstance(menu, list):
6daa59d44ee2 pages: menu implementation, first draft:
Goffi <goffi@goffi.org>
parents: 985
diff changeset
255 if len(menu) != 2:
6daa59d44ee2 pages: menu implementation, first draft:
Goffi <goffi@goffi.org>
parents: 985
diff changeset
256 raise ValueError(_(u"menu item as list must be in the form [page_name, absolue URL]"))
6daa59d44ee2 pages: menu implementation, first draft:
Goffi <goffi@goffi.org>
parents: 985
diff changeset
257 page_name, url = menu
6daa59d44ee2 pages: menu implementation, first draft:
Goffi <goffi@goffi.org>
parents: 985
diff changeset
258 else:
6daa59d44ee2 pages: menu implementation, first draft:
Goffi <goffi@goffi.org>
parents: 985
diff changeset
259 page_name = menu
6daa59d44ee2 pages: menu implementation, first draft:
Goffi <goffi@goffi.org>
parents: 985
diff changeset
260 url = cls.getPageByName(page_name).url
6daa59d44ee2 pages: menu implementation, first draft:
Goffi <goffi@goffi.org>
parents: 985
diff changeset
261 main_menu.append((page_name, url))
6daa59d44ee2 pages: menu implementation, first draft:
Goffi <goffi@goffi.org>
parents: 985
diff changeset
262 cls.main_menu = main_menu
6daa59d44ee2 pages: menu implementation, first draft:
Goffi <goffi@goffi.org>
parents: 985
diff changeset
263
6daa59d44ee2 pages: menu implementation, first draft:
Goffi <goffi@goffi.org>
parents: 985
diff changeset
264 @classmethod
925
e00151140f77 server (pages): URIs handling:
Goffi <goffi@goffi.org>
parents: 924
diff changeset
265 def registerURI(cls, uri_tuple, get_uri_cb, pre_path):
e00151140f77 server (pages): URIs handling:
Goffi <goffi@goffi.org>
parents: 924
diff changeset
266 """register a URI handler
e00151140f77 server (pages): URIs handling:
Goffi <goffi@goffi.org>
parents: 924
diff changeset
267
e00151140f77 server (pages): URIs handling:
Goffi <goffi@goffi.org>
parents: 924
diff changeset
268 @param uri_tuple(tuple[unicode, unicode]): type or URIs handler
e00151140f77 server (pages): URIs handling:
Goffi <goffi@goffi.org>
parents: 924
diff changeset
269 type/subtype as returned by tools/common/parseXMPPUri
e00151140f77 server (pages): URIs handling:
Goffi <goffi@goffi.org>
parents: 924
diff changeset
270 @param get_uri_cb(callable): method which take uri_data dict as only argument
e00151140f77 server (pages): URIs handling:
Goffi <goffi@goffi.org>
parents: 924
diff changeset
271 and return path with correct arguments relative to page itself
e00151140f77 server (pages): URIs handling:
Goffi <goffi@goffi.org>
parents: 924
diff changeset
272 @param pre_path(list[unicode]): prefix path to reference the handler page
e00151140f77 server (pages): URIs handling:
Goffi <goffi@goffi.org>
parents: 924
diff changeset
273 """
e00151140f77 server (pages): URIs handling:
Goffi <goffi@goffi.org>
parents: 924
diff changeset
274 if uri_tuple in cls.uri_callbacks:
e00151140f77 server (pages): URIs handling:
Goffi <goffi@goffi.org>
parents: 924
diff changeset
275 log.info(_(u"{}/{} URIs are already handled, replacing by the new handler").format(*uri_tuple))
e00151140f77 server (pages): URIs handling:
Goffi <goffi@goffi.org>
parents: 924
diff changeset
276 cls.uri_callbacks[uri_tuple] = {u'callback': get_uri_cb,
e00151140f77 server (pages): URIs handling:
Goffi <goffi@goffi.org>
parents: 924
diff changeset
277 u'pre_path': pre_path}
e00151140f77 server (pages): URIs handling:
Goffi <goffi@goffi.org>
parents: 924
diff changeset
278
995
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
279 def registerSignal(self, request, signal, check_profile=True):
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
280 r"""register a signal handler
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
281
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
282 the page must be dynamic
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
283 when signal is received, self.on_signal will be called with:
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
284 - request
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
285 - signal name
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
286 - signal arguments
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
287 signal handler will be removed when connection with dynamic page will be lost
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
288 @param signal(unicode): name of the signal
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
289 last arg of signal must be profile, as it will be checked to filter signals
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
290 @param check_profile(bool): if True, signal profile (which MUST be last arg) will be
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
291 checked against session profile.
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
292 /!\ if False, profile will not be checked/filtered, be sure to know what you are doing
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
293 if you unset this option /!\
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
294 """
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
295 # FIXME: add a timeout, if socket is not opened before it, signal handler must be removed
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
296 if not self.dynamic:
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
297 log.error(_(u"You can't register signal if page is not dynamic"))
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
298 return
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
299 LiberviaPage.signals_handlers.setdefault(signal, {})[id(request)] = (self, request, check_profile)
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
300 request._signals_registered.append(signal)
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
301
927
bb4dfc2802c0 server (pages): added getPagePathFromURI method to retrieve page handling an URI
Goffi <goffi@goffi.org>
parents: 926
diff changeset
302 def getPagePathFromURI(self, uri):
bb4dfc2802c0 server (pages): added getPagePathFromURI method to retrieve page handling an URI
Goffi <goffi@goffi.org>
parents: 926
diff changeset
303 """Retrieve page URL from xmpp: URI
bb4dfc2802c0 server (pages): added getPagePathFromURI method to retrieve page handling an URI
Goffi <goffi@goffi.org>
parents: 926
diff changeset
304
bb4dfc2802c0 server (pages): added getPagePathFromURI method to retrieve page handling an URI
Goffi <goffi@goffi.org>
parents: 926
diff changeset
305 @param uri(unicode): URI with a xmpp: scheme
bb4dfc2802c0 server (pages): added getPagePathFromURI method to retrieve page handling an URI
Goffi <goffi@goffi.org>
parents: 926
diff changeset
306 @return (unicode,None): absolute path (starting from root "/") to page handling the URI
bb4dfc2802c0 server (pages): added getPagePathFromURI method to retrieve page handling an URI
Goffi <goffi@goffi.org>
parents: 926
diff changeset
307 None is returned if not page has been registered for this URI
bb4dfc2802c0 server (pages): added getPagePathFromURI method to retrieve page handling an URI
Goffi <goffi@goffi.org>
parents: 926
diff changeset
308 """
bb4dfc2802c0 server (pages): added getPagePathFromURI method to retrieve page handling an URI
Goffi <goffi@goffi.org>
parents: 926
diff changeset
309 uri_data = common_uri.parseXMPPUri(uri)
bb4dfc2802c0 server (pages): added getPagePathFromURI method to retrieve page handling an URI
Goffi <goffi@goffi.org>
parents: 926
diff changeset
310 try:
bb4dfc2802c0 server (pages): added getPagePathFromURI method to retrieve page handling an URI
Goffi <goffi@goffi.org>
parents: 926
diff changeset
311 callback_data = self.uri_callbacks[uri_data['type'], uri_data.get('sub_type')]
bb4dfc2802c0 server (pages): added getPagePathFromURI method to retrieve page handling an URI
Goffi <goffi@goffi.org>
parents: 926
diff changeset
312 except KeyError:
bb4dfc2802c0 server (pages): added getPagePathFromURI method to retrieve page handling an URI
Goffi <goffi@goffi.org>
parents: 926
diff changeset
313 return
bb4dfc2802c0 server (pages): added getPagePathFromURI method to retrieve page handling an URI
Goffi <goffi@goffi.org>
parents: 926
diff changeset
314 else:
bb4dfc2802c0 server (pages): added getPagePathFromURI method to retrieve page handling an URI
Goffi <goffi@goffi.org>
parents: 926
diff changeset
315 url = os.path.join(u'/', u'/'.join(callback_data['pre_path']), callback_data['callback'](self, uri_data))
bb4dfc2802c0 server (pages): added getPagePathFromURI method to retrieve page handling an URI
Goffi <goffi@goffi.org>
parents: 926
diff changeset
316 return url
bb4dfc2802c0 server (pages): added getPagePathFromURI method to retrieve page handling an URI
Goffi <goffi@goffi.org>
parents: 926
diff changeset
317
979
1d558dfb32ca server: pages redirection:
Goffi <goffi@goffi.org>
parents: 978
diff changeset
318 @classmethod
1d558dfb32ca server: pages redirection:
Goffi <goffi@goffi.org>
parents: 978
diff changeset
319 def getPageByName(cls, name):
936
78692d47340d server (pages): added getPageByName
Goffi <goffi@goffi.org>
parents: 935
diff changeset
320 """retrieve page instance from its name
78692d47340d server (pages): added getPageByName
Goffi <goffi@goffi.org>
parents: 935
diff changeset
321
78692d47340d server (pages): added getPageByName
Goffi <goffi@goffi.org>
parents: 935
diff changeset
322 @param name(unicode): name of the page
78692d47340d server (pages): added getPageByName
Goffi <goffi@goffi.org>
parents: 935
diff changeset
323 @return (LiberviaPage): page instance
78692d47340d server (pages): added getPageByName
Goffi <goffi@goffi.org>
parents: 935
diff changeset
324 @raise KeyError: the page doesn't exist
78692d47340d server (pages): added getPageByName
Goffi <goffi@goffi.org>
parents: 935
diff changeset
325 """
979
1d558dfb32ca server: pages redirection:
Goffi <goffi@goffi.org>
parents: 978
diff changeset
326 return cls.named_pages[name]
936
78692d47340d server (pages): added getPageByName
Goffi <goffi@goffi.org>
parents: 935
diff changeset
327
962
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
328 def getPageRedirectURL(self, request, page_name=u'login', url=None):
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
329 """generate URL for a page with redirect_url parameter set
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
330
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
331 mainly used for login page with redirection to current page
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
332 @param request(server.Request): current HTTP request
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
333 @param page_name(unicode): name of the page to go
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
334 @param url(None, unicode): url to redirect to
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
335 None to use request path (i.e. current page)
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
336 @return (unicode): URL to use
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
337 """
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
338 return u'{root_url}?redirect_url={redirect_url}'.format(
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
339 root_url = self.getPageByName(page_name).url,
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
340 redirect_url=urllib.quote_plus(request.uri) if url is None else url.encode('utf-8'))
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
341
972
c4e58c4dba75 server: getURL + minor improvments:
Goffi <goffi@goffi.org>
parents: 968
diff changeset
342 def getURL(self, *args):
c4e58c4dba75 server: getURL + minor improvments:
Goffi <goffi@goffi.org>
parents: 968
diff changeset
343 """retrieve URL of the page set arguments
c4e58c4dba75 server: getURL + minor improvments:
Goffi <goffi@goffi.org>
parents: 968
diff changeset
344
c4e58c4dba75 server: getURL + minor improvments:
Goffi <goffi@goffi.org>
parents: 968
diff changeset
345 *args(list[unicode]): argument to add to the URL as path elements
c4e58c4dba75 server: getURL + minor improvments:
Goffi <goffi@goffi.org>
parents: 968
diff changeset
346 """
c4e58c4dba75 server: getURL + minor improvments:
Goffi <goffi@goffi.org>
parents: 968
diff changeset
347 url_args = [quote(a) for a in args]
980
bcacf970f970 core (pages redirection): inverted redirection + getSubPageURL:
Goffi <goffi@goffi.org>
parents: 979
diff changeset
348
bcacf970f970 core (pages redirection): inverted redirection + getSubPageURL:
Goffi <goffi@goffi.org>
parents: 979
diff changeset
349 if self.name is not None and self.name in self.pages_redirects:
bcacf970f970 core (pages redirection): inverted redirection + getSubPageURL:
Goffi <goffi@goffi.org>
parents: 979
diff changeset
350 # we check for redirection
bcacf970f970 core (pages redirection): inverted redirection + getSubPageURL:
Goffi <goffi@goffi.org>
parents: 979
diff changeset
351 redirect_data = self.pages_redirects[self.name]
bcacf970f970 core (pages redirection): inverted redirection + getSubPageURL:
Goffi <goffi@goffi.org>
parents: 979
diff changeset
352 args_hash = tuple(args)
bcacf970f970 core (pages redirection): inverted redirection + getSubPageURL:
Goffi <goffi@goffi.org>
parents: 979
diff changeset
353 for limit in xrange(len(args)+1):
bcacf970f970 core (pages redirection): inverted redirection + getSubPageURL:
Goffi <goffi@goffi.org>
parents: 979
diff changeset
354 current_hash = args_hash[:limit]
bcacf970f970 core (pages redirection): inverted redirection + getSubPageURL:
Goffi <goffi@goffi.org>
parents: 979
diff changeset
355 if current_hash in redirect_data:
bcacf970f970 core (pages redirection): inverted redirection + getSubPageURL:
Goffi <goffi@goffi.org>
parents: 979
diff changeset
356 url_base = redirect_data[current_hash]
bcacf970f970 core (pages redirection): inverted redirection + getSubPageURL:
Goffi <goffi@goffi.org>
parents: 979
diff changeset
357 remaining = args[limit:]
bcacf970f970 core (pages redirection): inverted redirection + getSubPageURL:
Goffi <goffi@goffi.org>
parents: 979
diff changeset
358 remaining_url = '/'.join(remaining)
bcacf970f970 core (pages redirection): inverted redirection + getSubPageURL:
Goffi <goffi@goffi.org>
parents: 979
diff changeset
359 return os.path.join('/', url_base, remaining_url)
bcacf970f970 core (pages redirection): inverted redirection + getSubPageURL:
Goffi <goffi@goffi.org>
parents: 979
diff changeset
360
972
c4e58c4dba75 server: getURL + minor improvments:
Goffi <goffi@goffi.org>
parents: 968
diff changeset
361 return os.path.join(self.url, *url_args)
c4e58c4dba75 server: getURL + minor improvments:
Goffi <goffi@goffi.org>
parents: 968
diff changeset
362
980
bcacf970f970 core (pages redirection): inverted redirection + getSubPageURL:
Goffi <goffi@goffi.org>
parents: 979
diff changeset
363 def getSubPageURL(self, request, page_name, *args):
bcacf970f970 core (pages redirection): inverted redirection + getSubPageURL:
Goffi <goffi@goffi.org>
parents: 979
diff changeset
364 """retrieve a page in direct children and build its URL according to request
bcacf970f970 core (pages redirection): inverted redirection + getSubPageURL:
Goffi <goffi@goffi.org>
parents: 979
diff changeset
365
bcacf970f970 core (pages redirection): inverted redirection + getSubPageURL:
Goffi <goffi@goffi.org>
parents: 979
diff changeset
366 request's current path is used as base (at current parsing point,
bcacf970f970 core (pages redirection): inverted redirection + getSubPageURL:
Goffi <goffi@goffi.org>
parents: 979
diff changeset
367 i.e. it's more prepath than path).
bcacf970f970 core (pages redirection): inverted redirection + getSubPageURL:
Goffi <goffi@goffi.org>
parents: 979
diff changeset
368 Requested page is checked in children and an absolute URL is then built
bcacf970f970 core (pages redirection): inverted redirection + getSubPageURL:
Goffi <goffi@goffi.org>
parents: 979
diff changeset
369 by the resulting combination.
bcacf970f970 core (pages redirection): inverted redirection + getSubPageURL:
Goffi <goffi@goffi.org>
parents: 979
diff changeset
370 This method is useful to construct absolute URLs for children instead of
bcacf970f970 core (pages redirection): inverted redirection + getSubPageURL:
Goffi <goffi@goffi.org>
parents: 979
diff changeset
371 using relative path, which may not work in subpages, and are linked to the
bcacf970f970 core (pages redirection): inverted redirection + getSubPageURL:
Goffi <goffi@goffi.org>
parents: 979
diff changeset
372 names of directories (i.e. relative URL will break if subdirectory is renamed
bcacf970f970 core (pages redirection): inverted redirection + getSubPageURL:
Goffi <goffi@goffi.org>
parents: 979
diff changeset
373 while getSubPageURL won't as long as page_name is consistent).
bcacf970f970 core (pages redirection): inverted redirection + getSubPageURL:
Goffi <goffi@goffi.org>
parents: 979
diff changeset
374 Also, request.path is used, keeping real path used by user,
bcacf970f970 core (pages redirection): inverted redirection + getSubPageURL:
Goffi <goffi@goffi.org>
parents: 979
diff changeset
375 and potential redirections.
bcacf970f970 core (pages redirection): inverted redirection + getSubPageURL:
Goffi <goffi@goffi.org>
parents: 979
diff changeset
376 @param request(server.Request): current HTTP request
bcacf970f970 core (pages redirection): inverted redirection + getSubPageURL:
Goffi <goffi@goffi.org>
parents: 979
diff changeset
377 @param page_name(unicode): name of the page to retrieve
bcacf970f970 core (pages redirection): inverted redirection + getSubPageURL:
Goffi <goffi@goffi.org>
parents: 979
diff changeset
378 it must be a direct children of current page
bcacf970f970 core (pages redirection): inverted redirection + getSubPageURL:
Goffi <goffi@goffi.org>
parents: 979
diff changeset
379 @param *args(list[unicode]): arguments to add as path elements
bcacf970f970 core (pages redirection): inverted redirection + getSubPageURL:
Goffi <goffi@goffi.org>
parents: 979
diff changeset
380 @return unicode: absolute URL to the sub page
bcacf970f970 core (pages redirection): inverted redirection + getSubPageURL:
Goffi <goffi@goffi.org>
parents: 979
diff changeset
381 """
bcacf970f970 core (pages redirection): inverted redirection + getSubPageURL:
Goffi <goffi@goffi.org>
parents: 979
diff changeset
382 # we get url in the following way (splitting request.path instead of using
bcacf970f970 core (pages redirection): inverted redirection + getSubPageURL:
Goffi <goffi@goffi.org>
parents: 979
diff changeset
383 # request.prepath) because request.prepath may have been modified by
bcacf970f970 core (pages redirection): inverted redirection + getSubPageURL:
Goffi <goffi@goffi.org>
parents: 979
diff changeset
384 # redirection (if redirection args have been specified), while path reflect
bcacf970f970 core (pages redirection): inverted redirection + getSubPageURL:
Goffi <goffi@goffi.org>
parents: 979
diff changeset
385 # the real request
bcacf970f970 core (pages redirection): inverted redirection + getSubPageURL:
Goffi <goffi@goffi.org>
parents: 979
diff changeset
386
bcacf970f970 core (pages redirection): inverted redirection + getSubPageURL:
Goffi <goffi@goffi.org>
parents: 979
diff changeset
387 # we ignore empty path elements (i.e. double '/' or '/' at the end)
bcacf970f970 core (pages redirection): inverted redirection + getSubPageURL:
Goffi <goffi@goffi.org>
parents: 979
diff changeset
388 path_elts = [p for p in request.path.split('/') if p]
bcacf970f970 core (pages redirection): inverted redirection + getSubPageURL:
Goffi <goffi@goffi.org>
parents: 979
diff changeset
389
bcacf970f970 core (pages redirection): inverted redirection + getSubPageURL:
Goffi <goffi@goffi.org>
parents: 979
diff changeset
390 if request.postpath:
bcacf970f970 core (pages redirection): inverted redirection + getSubPageURL:
Goffi <goffi@goffi.org>
parents: 979
diff changeset
391 if not request.postpath[-1]:
bcacf970f970 core (pages redirection): inverted redirection + getSubPageURL:
Goffi <goffi@goffi.org>
parents: 979
diff changeset
392 # we remove trailing slash
bcacf970f970 core (pages redirection): inverted redirection + getSubPageURL:
Goffi <goffi@goffi.org>
parents: 979
diff changeset
393 request.postpath = request.postpath[:-1]
bcacf970f970 core (pages redirection): inverted redirection + getSubPageURL:
Goffi <goffi@goffi.org>
parents: 979
diff changeset
394 if request.postpath:
bcacf970f970 core (pages redirection): inverted redirection + getSubPageURL:
Goffi <goffi@goffi.org>
parents: 979
diff changeset
395 # getSubPageURL must return subpage from the point where
bcacf970f970 core (pages redirection): inverted redirection + getSubPageURL:
Goffi <goffi@goffi.org>
parents: 979
diff changeset
396 # the it is called, so we have to remove remanining
bcacf970f970 core (pages redirection): inverted redirection + getSubPageURL:
Goffi <goffi@goffi.org>
parents: 979
diff changeset
397 # path elements
bcacf970f970 core (pages redirection): inverted redirection + getSubPageURL:
Goffi <goffi@goffi.org>
parents: 979
diff changeset
398 path_elts = path_elts[:-len(request.postpath)]
bcacf970f970 core (pages redirection): inverted redirection + getSubPageURL:
Goffi <goffi@goffi.org>
parents: 979
diff changeset
399
bcacf970f970 core (pages redirection): inverted redirection + getSubPageURL:
Goffi <goffi@goffi.org>
parents: 979
diff changeset
400 current_url = '/' + '/'.join(path_elts).decode('utf-8')
bcacf970f970 core (pages redirection): inverted redirection + getSubPageURL:
Goffi <goffi@goffi.org>
parents: 979
diff changeset
401
bcacf970f970 core (pages redirection): inverted redirection + getSubPageURL:
Goffi <goffi@goffi.org>
parents: 979
diff changeset
402 for path, child in self.children.iteritems():
bcacf970f970 core (pages redirection): inverted redirection + getSubPageURL:
Goffi <goffi@goffi.org>
parents: 979
diff changeset
403 try:
bcacf970f970 core (pages redirection): inverted redirection + getSubPageURL:
Goffi <goffi@goffi.org>
parents: 979
diff changeset
404 child_name = child.name
bcacf970f970 core (pages redirection): inverted redirection + getSubPageURL:
Goffi <goffi@goffi.org>
parents: 979
diff changeset
405 except AttributeError:
bcacf970f970 core (pages redirection): inverted redirection + getSubPageURL:
Goffi <goffi@goffi.org>
parents: 979
diff changeset
406 # LiberviaPage have a name, but maybe this is an other Resource
bcacf970f970 core (pages redirection): inverted redirection + getSubPageURL:
Goffi <goffi@goffi.org>
parents: 979
diff changeset
407 continue
bcacf970f970 core (pages redirection): inverted redirection + getSubPageURL:
Goffi <goffi@goffi.org>
parents: 979
diff changeset
408 if child_name == page_name:
bcacf970f970 core (pages redirection): inverted redirection + getSubPageURL:
Goffi <goffi@goffi.org>
parents: 979
diff changeset
409 return os.path.join(u'/', current_url, path, *args)
bcacf970f970 core (pages redirection): inverted redirection + getSubPageURL:
Goffi <goffi@goffi.org>
parents: 979
diff changeset
410 raise exceptions.NotFound(_(u'requested sub page has not been found'))
bcacf970f970 core (pages redirection): inverted redirection + getSubPageURL:
Goffi <goffi@goffi.org>
parents: 979
diff changeset
411
917
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
412 def getChildWithDefault(self, path, request):
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
413 # we handle children ourselves
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
414 raise exceptions.InternalError(u"this method should not be used with LiberviaPage")
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
415
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
416 def nextPath(self, request):
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
417 """get next URL path segment, and update request accordingly
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
418
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
419 will move first segment of postpath in prepath
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
420 @param request(server.Request): current HTTP request
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
421 @return (unicode): unquoted segment
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
422 @raise IndexError: there is no segment left
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
423 """
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
424 pathElement = request.postpath.pop(0)
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
425 request.prepath.append(pathElement)
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
426 return urllib.unquote(pathElement).decode('utf-8')
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
427
985
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
428 def checkCacheSubscribeCb(self, sub_id, service, node):
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
429 self.cache_pubsub_sub.add((service, node, sub_id))
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
430
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
431 def checkCacheSubscribeEb(self, failure_, service, node):
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
432 log.warning(_(u"Can't subscribe to node: {msg}").format(msg=failure_))
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
433 # FIXME: cache must be marked as unusable here
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
434
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
435 def psNodeWatchAddEb(self, failure_, service, node):
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
436 log.warning(_(u"Can't add node watched: {msg}").format(msg=failure_))
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
437
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
438 def checkCache(self, request, cache_type, **kwargs):
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
439 """check if a page is in cache and return cached version if suitable
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
440
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
441 this method may perform extra operation to handle cache (e.g. subscribing to a
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
442 pubsub node)
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
443 @param request(server.Request): current HTTP request
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
444 @param cache_type(int): on of C.CACHE_* const.
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
445 @param **kwargs: args according to cache_type:
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
446 C.CACHE_PROFILE:
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
447 service: pubsub service
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
448 node: pubsub node
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
449 short: short name of feature (needed if node is empty)
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
450
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
451 """
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
452 if request.postpath:
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
453 # we are not on the final page, no need to go further
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
454 return
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
455 profile = self.getProfile(request) or C.SERVICE_PROFILE
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
456
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
457 if cache_type == C.CACHE_PUBSUB:
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
458 service, node = kwargs['service'], kwargs['node']
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
459 if not node:
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
460 try:
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
461 short = kwargs['short']
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
462 node = self.host.ns_map[short]
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
463 except KeyError:
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
464 log.warning(_(u"Can't use cache for empty node without namespace set, please ensure to set \"short\" and that it is registered"))
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
465 return
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
466 if profile != C.SERVICE_PROFILE:
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
467 # only service profile is cache for now
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
468 return
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
469 try:
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
470 cache = self.cache[profile][cache_type][service][node][self]
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
471 except KeyError:
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
472 # no cache yet, let's subscribe to the pubsub node
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
473 d1 = self.host.bridgeCall('psSubscribe', service.full(), node, {}, profile)
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
474 d1.addCallback(self.checkCacheSubscribeCb, service, node)
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
475 d1.addErrback(self.checkCacheSubscribeEb, service, node)
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
476 d2 = self.host.bridgeCall('psNodeWatchAdd', service.full(), node, profile)
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
477 d2.addErrback(self.psNodeWatchAddEb, service, node)
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
478 self._do_cache = [profile, cache_type, service, node]
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
479 # we don't return the Deferreds as it is not needed to wait for
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
480 # the subscription to continue with page rendering
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
481 return
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
482
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
483 else:
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
484 raise exceptions.InternalError(u'Unknown cache_type')
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
485 log.debug(u'using cache for {page}'.format(page=self))
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
486 cache.last_access = time.time()
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
487 request.write(cache.rendered)
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
488 request.finish()
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
489 raise failure.Failure(exceptions.CancelError(u'cache is used'))
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
490
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
491 @classmethod
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
492 def onNodeEvent(cls, host, service, node, event_type, items, profile):
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
493 """Invalidate cache for all pages linked to this node"""
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
494 try:
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
495 cache = cls.cache[profile][C.CACHE_PUBSUB][jid.JID(service)][node]
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
496 except KeyError:
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
497 log.info(_(u'Removing subscription for {service}/{node}: '
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
498 u'the page is not cached').format(service=service, node=node))
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
499 d1 = host.bridgeCall('psUnsubscribe', service, node, profile)
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
500 d1.addErrback(lambda failure_:
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
501 log.warning(_(u"Can't unsubscribe from {service}/{node}: {msg}").format(
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
502 service=service, node=node, msg=failure_)))
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
503 d2 = host.bridgeCall('psNodeWatchAdd', service, node, profile)
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
504 # TODO: check why the page is not in cache, remove subscription?
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
505 d2.addErrback(lambda failure_:
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
506 log.warning(_(u"Can't remove watch for {service}/{node}: {msg}").format(
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
507 service=service, node=node, msg=failure_)))
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
508 else:
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
509 cache.clear()
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
510
995
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
511 @classmethod
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
512 def onSignal(cls, host, signal, *args):
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
513 """Generic method which receive registered signals
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
514
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
515 if a callback is registered for this signal, call it
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
516 @param host: Libervia instance
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
517 @param signal(unicode): name of the signal
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
518 @param *args: args of the signals
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
519 """
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
520 for page, request, check_profile in cls.signals_handlers.get(signal, {}).itervalues():
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
521 if check_profile:
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
522 signal_profile = args[-1]
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
523 request_profile = page.getProfile(request)
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
524 if not request_profile:
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
525 # if you want to use signal without session, unset check_profile
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
526 # (be sure to know what you are doing)
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
527 log.error(_(u"no session started, signal can't be checked"))
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
528 continue
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
529 if signal_profile != request_profile:
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
530 # we ignore the signal, it's not for our profile
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
531 continue
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
532 if request._signals_cache is not None:
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
533 # socket is not yet opened, we cache the signal
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
534 request._signals_cache.append((request, signal, args))
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
535 log.debug(u"signal [{signal}] cached: {args}".format(
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
536 signal = signal,
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
537 args = args))
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
538 else:
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
539 page.on_signal(page, request, signal, *args)
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
540
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
541 def onSocketOpen(self, request):
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
542 """Called for dynamic pages when socket has just been opened
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
543
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
544 we send all cached signals
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
545 """
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
546 assert request._signals_cache is not None
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
547 cache = request._signals_cache
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
548 request._signals_cache = None
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
549 for request, signal, args in cache:
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
550 self.on_signal(self, request, signal, *args)
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
551
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
552 def onSocketClose(self, request):
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
553 """Called for dynamic pages when socket has just been closed
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
554
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
555 we remove signal handler
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
556 """
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
557 for signal in request._signals_registered:
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
558 try:
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
559 del LiberviaPage.signals_handlers[signal][id(request)]
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
560 except KeyError:
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
561 log.error(_(u"Can't find signal handler for [{signal}], this should not happen").format(
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
562 signal = signal))
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
563 else:
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
564 log.debug(_(u"Removed signal handler"))
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
565
962
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
566 def HTTPRedirect(self, request, url):
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
567 """redirect to an URL using HTTP redirection
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
568
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
569 @param request(server.Request): current HTTP request
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
570 @param url(unicode): url to redirect to
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
571 """
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
572
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
573 web_util.redirectTo(url.encode('utf-8'), request)
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
574 request.finish()
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
575 raise failure.Failure(exceptions.CancelError(u'HTTP redirection is used'))
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
576
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
577 def redirectOrContinue(self, request, redirect_arg=u'redirect_url'):
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
578 """helper method to redirect a page to an url given as arg
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
579
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
580 if the arg is not present, the page will continue normal workflow
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
581 @param request(server.Request): current HTTP request
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
582 @param redirect_arg(unicode): argument to use to get redirection URL
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
583 @interrupt: redirect the page to requested URL
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
584 @interrupt pageError(C.HTTP_BAD_REQUEST): empty or non local URL is used
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
585 """
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
586 try:
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
587 url = self.getPostedData(request, 'redirect_url')
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
588 except KeyError:
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
589 pass
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
590 else:
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
591 # a redirection is requested
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
592 if not url or url[0] != u'/':
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
593 # we only want local urls
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
594 self.pageError(request, C.HTTP_BAD_REQUEST)
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
595 else:
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
596 self.HTTPRedirect(request, url)
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
597
923
edb322c87ea4 server (pages): pages now handle redirection, check self.pageRedirect docstring for details
Goffi <goffi@goffi.org>
parents: 922
diff changeset
598 def pageRedirect(self, page_path, request, skip_parse_url=True):
edb322c87ea4 server (pages): pages now handle redirection, check self.pageRedirect docstring for details
Goffi <goffi@goffi.org>
parents: 922
diff changeset
599 """redirect a page to a named page
edb322c87ea4 server (pages): pages now handle redirection, check self.pageRedirect docstring for details
Goffi <goffi@goffi.org>
parents: 922
diff changeset
600
edb322c87ea4 server (pages): pages now handle redirection, check self.pageRedirect docstring for details
Goffi <goffi@goffi.org>
parents: 922
diff changeset
601 the workflow will continue with the workflow of the named page,
edb322c87ea4 server (pages): pages now handle redirection, check self.pageRedirect docstring for details
Goffi <goffi@goffi.org>
parents: 922
diff changeset
602 skipping named page's parse_url method if it exist.
962
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
603 If you want to do a HTTP redirection, use HTTPRedirect
923
edb322c87ea4 server (pages): pages now handle redirection, check self.pageRedirect docstring for details
Goffi <goffi@goffi.org>
parents: 922
diff changeset
604 @param page_path(unicode): path to page (elements are separated by "/"):
edb322c87ea4 server (pages): pages now handle redirection, check self.pageRedirect docstring for details
Goffi <goffi@goffi.org>
parents: 922
diff changeset
605 if path starts with a "/":
edb322c87ea4 server (pages): pages now handle redirection, check self.pageRedirect docstring for details
Goffi <goffi@goffi.org>
parents: 922
diff changeset
606 path is a full path starting from root
edb322c87ea4 server (pages): pages now handle redirection, check self.pageRedirect docstring for details
Goffi <goffi@goffi.org>
parents: 922
diff changeset
607 else:
edb322c87ea4 server (pages): pages now handle redirection, check self.pageRedirect docstring for details
Goffi <goffi@goffi.org>
parents: 922
diff changeset
608 - first element is name as registered in name variable
edb322c87ea4 server (pages): pages now handle redirection, check self.pageRedirect docstring for details
Goffi <goffi@goffi.org>
parents: 922
diff changeset
609 - following element are subpages path
edb322c87ea4 server (pages): pages now handle redirection, check self.pageRedirect docstring for details
Goffi <goffi@goffi.org>
parents: 922
diff changeset
610 e.g.: "blog" redirect to page named "blog"
edb322c87ea4 server (pages): pages now handle redirection, check self.pageRedirect docstring for details
Goffi <goffi@goffi.org>
parents: 922
diff changeset
611 "blog/atom.xml" redirect to atom.xml subpage of "blog"
edb322c87ea4 server (pages): pages now handle redirection, check self.pageRedirect docstring for details
Goffi <goffi@goffi.org>
parents: 922
diff changeset
612 "/common/blog/atom.xml" redirect to the page at the fiven full path
edb322c87ea4 server (pages): pages now handle redirection, check self.pageRedirect docstring for details
Goffi <goffi@goffi.org>
parents: 922
diff changeset
613 @param request(server.Request): current HTTP request
edb322c87ea4 server (pages): pages now handle redirection, check self.pageRedirect docstring for details
Goffi <goffi@goffi.org>
parents: 922
diff changeset
614 @param skip_parse_url(bool): if True, parse_url method on redirect page will be skipped
edb322c87ea4 server (pages): pages now handle redirection, check self.pageRedirect docstring for details
Goffi <goffi@goffi.org>
parents: 922
diff changeset
615 @raise KeyError: there is no known page with this name
edb322c87ea4 server (pages): pages now handle redirection, check self.pageRedirect docstring for details
Goffi <goffi@goffi.org>
parents: 922
diff changeset
616 """
edb322c87ea4 server (pages): pages now handle redirection, check self.pageRedirect docstring for details
Goffi <goffi@goffi.org>
parents: 922
diff changeset
617 # FIXME: render non LiberviaPage resources
edb322c87ea4 server (pages): pages now handle redirection, check self.pageRedirect docstring for details
Goffi <goffi@goffi.org>
parents: 922
diff changeset
618 path = page_path.rstrip(u'/').split(u'/')
edb322c87ea4 server (pages): pages now handle redirection, check self.pageRedirect docstring for details
Goffi <goffi@goffi.org>
parents: 922
diff changeset
619 if not path[0]:
edb322c87ea4 server (pages): pages now handle redirection, check self.pageRedirect docstring for details
Goffi <goffi@goffi.org>
parents: 922
diff changeset
620 redirect_page = self.host.root
edb322c87ea4 server (pages): pages now handle redirection, check self.pageRedirect docstring for details
Goffi <goffi@goffi.org>
parents: 922
diff changeset
621 else:
edb322c87ea4 server (pages): pages now handle redirection, check self.pageRedirect docstring for details
Goffi <goffi@goffi.org>
parents: 922
diff changeset
622 redirect_page = self.named_pages[path[0]]
edb322c87ea4 server (pages): pages now handle redirection, check self.pageRedirect docstring for details
Goffi <goffi@goffi.org>
parents: 922
diff changeset
623
edb322c87ea4 server (pages): pages now handle redirection, check self.pageRedirect docstring for details
Goffi <goffi@goffi.org>
parents: 922
diff changeset
624 for subpage in path[1:]:
962
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
625 if redirect_page is self.host.root:
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
626 redirect_page = redirect_page.children[subpage]
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
627 else:
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
628 redirect_page = redirect_page.original.children[subpage]
923
edb322c87ea4 server (pages): pages now handle redirection, check self.pageRedirect docstring for details
Goffi <goffi@goffi.org>
parents: 922
diff changeset
629
edb322c87ea4 server (pages): pages now handle redirection, check self.pageRedirect docstring for details
Goffi <goffi@goffi.org>
parents: 922
diff changeset
630 redirect_page.renderPage(request, skip_parse_url=True)
edb322c87ea4 server (pages): pages now handle redirection, check self.pageRedirect docstring for details
Goffi <goffi@goffi.org>
parents: 922
diff changeset
631 raise failure.Failure(exceptions.CancelError(u'page redirection is used'))
edb322c87ea4 server (pages): pages now handle redirection, check self.pageRedirect docstring for details
Goffi <goffi@goffi.org>
parents: 922
diff changeset
632
922
16d1084d1371 server (pages): added "None" access (page is not rendered at all) and some HTTP code constants + helper methods to get session data
Goffi <goffi@goffi.org>
parents: 921
diff changeset
633 def pageError(self, request, code=C.HTTP_NOT_FOUND):
917
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
634 """generate an error page and terminate the request
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
635
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
636 @param request(server.Request): HTTP request
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
637 @param core(int): error code to use
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
638 """
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
639 template = u'error/' + unicode(code) + '.html'
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
640
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
641 request.setResponseCode(code)
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
642
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
643 rendered = self.host.renderer.render(
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
644 template,
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
645 root_path = '/templates/',
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
646 error_code = code,
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
647 **request.template_data)
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
648
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
649 self.writeData(rendered, request)
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
650 raise failure.Failure(exceptions.CancelError(u'error page is used'))
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
651
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
652 def writeData(self, data, request):
937
00236973e138 server (pages): an HTTP internal error is raised if an error is uncatched during page workflow
Goffi <goffi@goffi.org>
parents: 936
diff changeset
653 """write data to transport and finish the request"""
917
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
654 if data is None:
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
655 self.pageError(request)
985
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
656 data_encoded = data.encode('utf-8')
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
657 request.write(data_encoded)
917
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
658 request.finish()
985
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
659 if self._do_cache is not None:
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
660 cache = reduce(lambda d, k: d.setdefault(k, {}), self._do_cache, self.cache)
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
661 cache[self] = Cache(data_encoded)
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
662 log.debug(_(u'{page} put in cache for [{profile}]').format(
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
663 page=self,
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
664 profile=self._do_cache[0]))
64826e69f365 pages: cache mechanism, first draft:
Goffi <goffi@goffi.org>
parents: 984
diff changeset
665 self._do_cache = None
917
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
666
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
667 def _subpagesHandler(self, dummy, request):
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
668 """render subpage if suitable
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
669
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
670 this method checks if there is still an unmanaged part of the path
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
671 and check if it corresponds to a subpage. If so, it render the subpage
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
672 else it render a NoResource.
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
673 If there is no unmanaged part of the segment, current page workflow is pursued
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
674 """
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
675 if request.postpath:
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
676 subpage = self.nextPath(request)
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
677 try:
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
678 child = self.children[subpage]
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
679 except KeyError:
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
680 self.pageError(request)
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
681 else:
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
682 child.render(request)
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
683 raise failure.Failure(exceptions.CancelError(u'subpage page is used'))
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
684
998
0848b8b0188d pages: dynamic set up is now done just before prepare_render call:
Goffi <goffi@goffi.org>
parents: 995
diff changeset
685 def _prepare_dynamic(self, dummy, request):
0848b8b0188d pages: dynamic set up is now done just before prepare_render call:
Goffi <goffi@goffi.org>
parents: 995
diff changeset
686 # we need to activate dynamic page
0848b8b0188d pages: dynamic set up is now done just before prepare_render call:
Goffi <goffi@goffi.org>
parents: 995
diff changeset
687 # we set data for template, and create/register token
0848b8b0188d pages: dynamic set up is now done just before prepare_render call:
Goffi <goffi@goffi.org>
parents: 995
diff changeset
688 socket_token = unicode(uuid.uuid4())
0848b8b0188d pages: dynamic set up is now done just before prepare_render call:
Goffi <goffi@goffi.org>
parents: 995
diff changeset
689 socket_url = self.host.getWebsocketURL(request)
0848b8b0188d pages: dynamic set up is now done just before prepare_render call:
Goffi <goffi@goffi.org>
parents: 995
diff changeset
690 socket_debug = C.boolConst(self.host.debug)
0848b8b0188d pages: dynamic set up is now done just before prepare_render call:
Goffi <goffi@goffi.org>
parents: 995
diff changeset
691 request.template_data['websocket'] = WebsocketMeta(socket_url, socket_token, socket_debug)
0848b8b0188d pages: dynamic set up is now done just before prepare_render call:
Goffi <goffi@goffi.org>
parents: 995
diff changeset
692 self.host.registerWSToken(socket_token, self, request)
0848b8b0188d pages: dynamic set up is now done just before prepare_render call:
Goffi <goffi@goffi.org>
parents: 995
diff changeset
693 # we will keep track of handlers to remove
0848b8b0188d pages: dynamic set up is now done just before prepare_render call:
Goffi <goffi@goffi.org>
parents: 995
diff changeset
694 request._signals_registered = []
0848b8b0188d pages: dynamic set up is now done just before prepare_render call:
Goffi <goffi@goffi.org>
parents: 995
diff changeset
695 # we will cache registered signals until socket is opened
0848b8b0188d pages: dynamic set up is now done just before prepare_render call:
Goffi <goffi@goffi.org>
parents: 995
diff changeset
696 request._signals_cache = []
0848b8b0188d pages: dynamic set up is now done just before prepare_render call:
Goffi <goffi@goffi.org>
parents: 995
diff changeset
697
917
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
698 def _prepare_render(self, dummy, request):
926
612e33fd32a8 server (pages): fixed _prepare_render handling
Goffi <goffi@goffi.org>
parents: 925
diff changeset
699 return defer.maybeDeferred(self.prepare_render, self, request)
917
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
700
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
701 def _render_method(self, dummy, request):
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
702 return defer.maybeDeferred(self.render_method, self, request)
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
703
962
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
704 def _render_template(self, dummy, request):
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
705 template_data = request.template_data
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
706
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
707 # if confirm variable is set in case of successfuly data post
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
708 session_data = self.host.getSessionData(request, session_iface.ISATSession)
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
709 if session_data.popPageFlag(self, C.FLAG_CONFIRM):
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
710 template_data[u'confirm'] = True
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
711
917
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
712 return self.host.renderer.render(
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
713 self.template,
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
714 root_path = '/templates/',
962
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
715 media_path = '/' + C.MEDIA_DIR,
995
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
716 cache_path = session_data.cache_dir,
990
6daa59d44ee2 pages: menu implementation, first draft:
Goffi <goffi@goffi.org>
parents: 985
diff changeset
717 main_menu = LiberviaPage.main_menu,
917
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
718 **template_data)
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
719
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
720 def _renderEb(self, failure_, request):
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
721 """don't raise error on CancelError"""
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
722 failure_.trap(exceptions.CancelError)
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
723
937
00236973e138 server (pages): an HTTP internal error is raised if an error is uncatched during page workflow
Goffi <goffi@goffi.org>
parents: 936
diff changeset
724 def _internalError(self, failure_, request):
00236973e138 server (pages): an HTTP internal error is raised if an error is uncatched during page workflow
Goffi <goffi@goffi.org>
parents: 936
diff changeset
725 """called if an error is not catched"""
00236973e138 server (pages): an HTTP internal error is raised if an error is uncatched during page workflow
Goffi <goffi@goffi.org>
parents: 936
diff changeset
726 log.error(_(u"Uncatched error for HTTP request on {url}: {msg}").format(
00236973e138 server (pages): an HTTP internal error is raised if an error is uncatched during page workflow
Goffi <goffi@goffi.org>
parents: 936
diff changeset
727 url = request.URLPath(),
00236973e138 server (pages): an HTTP internal error is raised if an error is uncatched during page workflow
Goffi <goffi@goffi.org>
parents: 936
diff changeset
728 msg = failure_))
00236973e138 server (pages): an HTTP internal error is raised if an error is uncatched during page workflow
Goffi <goffi@goffi.org>
parents: 936
diff changeset
729 self.pageError(request, C.HTTP_INTERNAL_ERROR)
00236973e138 server (pages): an HTTP internal error is raised if an error is uncatched during page workflow
Goffi <goffi@goffi.org>
parents: 936
diff changeset
730
956
dabecab10faa server (pages): impleted CSRF protection:
Goffi <goffi@goffi.org>
parents: 955
diff changeset
731 def _on_data_post_redirect(self, ret, request):
968
4d37b23777c3 pages (core, tickets/new): replaced post_redirect_uri mechanism by post_redirect_page:
Goffi <goffi@goffi.org>
parents: 966
diff changeset
732 """called when page's on_data_post has been done successfuly
956
dabecab10faa server (pages): impleted CSRF protection:
Goffi <goffi@goffi.org>
parents: 955
diff changeset
733
968
4d37b23777c3 pages (core, tickets/new): replaced post_redirect_uri mechanism by post_redirect_page:
Goffi <goffi@goffi.org>
parents: 966
diff changeset
734 This will do a Post/Redirect/Get pattern.
4d37b23777c3 pages (core, tickets/new): replaced post_redirect_uri mechanism by post_redirect_page:
Goffi <goffi@goffi.org>
parents: 966
diff changeset
735 this method redirect to the same page or to request.data['post_redirect_page']
4d37b23777c3 pages (core, tickets/new): replaced post_redirect_uri mechanism by post_redirect_page:
Goffi <goffi@goffi.org>
parents: 966
diff changeset
736 post_redirect_page can be either a page or a tuple with page as first item, then a list of unicode arguments to append to the url.
4d37b23777c3 pages (core, tickets/new): replaced post_redirect_uri mechanism by post_redirect_page:
Goffi <goffi@goffi.org>
parents: 966
diff changeset
737 if post_redirect_page is not used, initial request.uri (i.e. the same page as where the data have been posted) will be used for redirection.
4d37b23777c3 pages (core, tickets/new): replaced post_redirect_uri mechanism by post_redirect_page:
Goffi <goffi@goffi.org>
parents: 966
diff changeset
738 HTTP status code "See Other" (303) is used as it is the recommanded code in this case.
962
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
739 @param ret(None, unicode, iterable): on_data_post return value
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
740 see LiberviaPage.__init__ on_data_post docstring
956
dabecab10faa server (pages): impleted CSRF protection:
Goffi <goffi@goffi.org>
parents: 955
diff changeset
741 """
962
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
742 if ret is None:
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
743 ret = ()
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
744 elif isinstance(ret, basestring):
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
745 ret = (ret,)
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
746 else:
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
747 ret = tuple(ret)
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
748 raise NotImplementedError(_(u'iterable in on_data_post return value is not used yet'))
957
67bf14c91d5c server (pages): added a confirm flag on successful post:
Goffi <goffi@goffi.org>
parents: 956
diff changeset
749 session_data = self.host.getSessionData(request, session_iface.ISATSession)
974
4aa38c49bff7 pages: fixed use of request data in _on_data_post_redirect
Goffi <goffi@goffi.org>
parents: 972
diff changeset
750 request_data = self.getRData(request)
4aa38c49bff7 pages: fixed use of request data in _on_data_post_redirect
Goffi <goffi@goffi.org>
parents: 972
diff changeset
751 if 'post_redirect_page' in request_data:
4aa38c49bff7 pages: fixed use of request data in _on_data_post_redirect
Goffi <goffi@goffi.org>
parents: 972
diff changeset
752 redirect_page_data = request_data['post_redirect_page']
968
4d37b23777c3 pages (core, tickets/new): replaced post_redirect_uri mechanism by post_redirect_page:
Goffi <goffi@goffi.org>
parents: 966
diff changeset
753 if isinstance(redirect_page_data, tuple):
4d37b23777c3 pages (core, tickets/new): replaced post_redirect_uri mechanism by post_redirect_page:
Goffi <goffi@goffi.org>
parents: 966
diff changeset
754 redirect_page = redirect_page_data[0]
972
c4e58c4dba75 server: getURL + minor improvments:
Goffi <goffi@goffi.org>
parents: 968
diff changeset
755 redirect_page_args = redirect_page_data[1:]
c4e58c4dba75 server: getURL + minor improvments:
Goffi <goffi@goffi.org>
parents: 968
diff changeset
756 redirect_uri = redirect_page.getURL(*redirect_page_args)
968
4d37b23777c3 pages (core, tickets/new): replaced post_redirect_uri mechanism by post_redirect_page:
Goffi <goffi@goffi.org>
parents: 966
diff changeset
757 else:
4d37b23777c3 pages (core, tickets/new): replaced post_redirect_uri mechanism by post_redirect_page:
Goffi <goffi@goffi.org>
parents: 966
diff changeset
758 redirect_page = redirect_page_data
972
c4e58c4dba75 server: getURL + minor improvments:
Goffi <goffi@goffi.org>
parents: 968
diff changeset
759 redirect_uri = redirect_page.url
968
4d37b23777c3 pages (core, tickets/new): replaced post_redirect_uri mechanism by post_redirect_page:
Goffi <goffi@goffi.org>
parents: 966
diff changeset
760 else:
4d37b23777c3 pages (core, tickets/new): replaced post_redirect_uri mechanism by post_redirect_page:
Goffi <goffi@goffi.org>
parents: 966
diff changeset
761 redirect_page = self
4d37b23777c3 pages (core, tickets/new): replaced post_redirect_uri mechanism by post_redirect_page:
Goffi <goffi@goffi.org>
parents: 966
diff changeset
762 redirect_uri = request.uri
4d37b23777c3 pages (core, tickets/new): replaced post_redirect_uri mechanism by post_redirect_page:
Goffi <goffi@goffi.org>
parents: 966
diff changeset
763
962
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
764 if not C.POST_NO_CONFIRM in ret:
968
4d37b23777c3 pages (core, tickets/new): replaced post_redirect_uri mechanism by post_redirect_page:
Goffi <goffi@goffi.org>
parents: 966
diff changeset
765 session_data.setPageFlag(redirect_page, C.FLAG_CONFIRM)
956
dabecab10faa server (pages): impleted CSRF protection:
Goffi <goffi@goffi.org>
parents: 955
diff changeset
766 request.setResponseCode(C.HTTP_SEE_OTHER)
968
4d37b23777c3 pages (core, tickets/new): replaced post_redirect_uri mechanism by post_redirect_page:
Goffi <goffi@goffi.org>
parents: 966
diff changeset
767 request.setHeader("location", redirect_uri)
955
4f7cb6335a33 server(pages): do Post/Redirect/Get pattern when on_data_post is used (avoid double posting on refresh)
Goffi <goffi@goffi.org>
parents: 950
diff changeset
768 request.finish()
4f7cb6335a33 server(pages): do Post/Redirect/Get pattern when on_data_post is used (avoid double posting on refresh)
Goffi <goffi@goffi.org>
parents: 950
diff changeset
769 raise failure.Failure(exceptions.CancelError(u'Post/Redirect/Get is used'))
4f7cb6335a33 server(pages): do Post/Redirect/Get pattern when on_data_post is used (avoid double posting on refresh)
Goffi <goffi@goffi.org>
parents: 950
diff changeset
770
956
dabecab10faa server (pages): impleted CSRF protection:
Goffi <goffi@goffi.org>
parents: 955
diff changeset
771 def _on_data_post(self, dummy, request):
dabecab10faa server (pages): impleted CSRF protection:
Goffi <goffi@goffi.org>
parents: 955
diff changeset
772 csrf_token = self.host.getSessionData(request, session_iface.ISATSession).csrf_token
dabecab10faa server (pages): impleted CSRF protection:
Goffi <goffi@goffi.org>
parents: 955
diff changeset
773 try:
dabecab10faa server (pages): impleted CSRF protection:
Goffi <goffi@goffi.org>
parents: 955
diff changeset
774 given_csrf = self.getPostedData(request, u'csrf_token')
dabecab10faa server (pages): impleted CSRF protection:
Goffi <goffi@goffi.org>
parents: 955
diff changeset
775 except KeyError:
dabecab10faa server (pages): impleted CSRF protection:
Goffi <goffi@goffi.org>
parents: 955
diff changeset
776 given_csrf = None
dabecab10faa server (pages): impleted CSRF protection:
Goffi <goffi@goffi.org>
parents: 955
diff changeset
777 if given_csrf is None or given_csrf != csrf_token:
dabecab10faa server (pages): impleted CSRF protection:
Goffi <goffi@goffi.org>
parents: 955
diff changeset
778 log.warning(_(u"invalid CSRF token, hack attempt? URL: {url}, IP: {ip}").format(
dabecab10faa server (pages): impleted CSRF protection:
Goffi <goffi@goffi.org>
parents: 955
diff changeset
779 url=request.uri,
dabecab10faa server (pages): impleted CSRF protection:
Goffi <goffi@goffi.org>
parents: 955
diff changeset
780 ip=request.getClientIP()))
dabecab10faa server (pages): impleted CSRF protection:
Goffi <goffi@goffi.org>
parents: 955
diff changeset
781 self.pageError(request, C.HTTP_UNAUTHORIZED)
dabecab10faa server (pages): impleted CSRF protection:
Goffi <goffi@goffi.org>
parents: 955
diff changeset
782 d = defer.maybeDeferred(self.on_data_post, self, request)
dabecab10faa server (pages): impleted CSRF protection:
Goffi <goffi@goffi.org>
parents: 955
diff changeset
783 d.addCallback(self._on_data_post_redirect, request)
dabecab10faa server (pages): impleted CSRF protection:
Goffi <goffi@goffi.org>
parents: 955
diff changeset
784 return d
dabecab10faa server (pages): impleted CSRF protection:
Goffi <goffi@goffi.org>
parents: 955
diff changeset
785
931
8a393ae90f8c server (pages): post requests are now handled:
Goffi <goffi@goffi.org>
parents: 927
diff changeset
786 def getPostedData(self, request, keys, multiple=False):
8a393ae90f8c server (pages): post requests are now handled:
Goffi <goffi@goffi.org>
parents: 927
diff changeset
787 """get data from a POST request and decode it
8a393ae90f8c server (pages): post requests are now handled:
Goffi <goffi@goffi.org>
parents: 927
diff changeset
788
8a393ae90f8c server (pages): post requests are now handled:
Goffi <goffi@goffi.org>
parents: 927
diff changeset
789 @param request(server.Request): request linked to the session
8a393ae90f8c server (pages): post requests are now handled:
Goffi <goffi@goffi.org>
parents: 927
diff changeset
790 @param keys(unicode, iterable[unicode]): name of the value(s) to get
8a393ae90f8c server (pages): post requests are now handled:
Goffi <goffi@goffi.org>
parents: 927
diff changeset
791 unicode to get one value
8a393ae90f8c server (pages): post requests are now handled:
Goffi <goffi@goffi.org>
parents: 927
diff changeset
792 iterable to get more than one
8a393ae90f8c server (pages): post requests are now handled:
Goffi <goffi@goffi.org>
parents: 927
diff changeset
793 @param multiple(bool): True if multiple values are possible/expected
8a393ae90f8c server (pages): post requests are now handled:
Goffi <goffi@goffi.org>
parents: 927
diff changeset
794 if False, the first value is returned
8a393ae90f8c server (pages): post requests are now handled:
Goffi <goffi@goffi.org>
parents: 927
diff changeset
795 @return (iterator[unicode], list[iterator[unicode], unicode, list[unicode]): values received for this(these) key(s)
956
dabecab10faa server (pages): impleted CSRF protection:
Goffi <goffi@goffi.org>
parents: 955
diff changeset
796 @raise KeyError: one specific key has been requested, and it is missing
931
8a393ae90f8c server (pages): post requests are now handled:
Goffi <goffi@goffi.org>
parents: 927
diff changeset
797 """
8a393ae90f8c server (pages): post requests are now handled:
Goffi <goffi@goffi.org>
parents: 927
diff changeset
798 if isinstance(keys, basestring):
8a393ae90f8c server (pages): post requests are now handled:
Goffi <goffi@goffi.org>
parents: 927
diff changeset
799 keys = [keys]
8a393ae90f8c server (pages): post requests are now handled:
Goffi <goffi@goffi.org>
parents: 927
diff changeset
800 get_first = True
8a393ae90f8c server (pages): post requests are now handled:
Goffi <goffi@goffi.org>
parents: 927
diff changeset
801 else:
8a393ae90f8c server (pages): post requests are now handled:
Goffi <goffi@goffi.org>
parents: 927
diff changeset
802 get_first = False
8a393ae90f8c server (pages): post requests are now handled:
Goffi <goffi@goffi.org>
parents: 927
diff changeset
803
8a393ae90f8c server (pages): post requests are now handled:
Goffi <goffi@goffi.org>
parents: 927
diff changeset
804 ret = []
8a393ae90f8c server (pages): post requests are now handled:
Goffi <goffi@goffi.org>
parents: 927
diff changeset
805 for key in keys:
8a393ae90f8c server (pages): post requests are now handled:
Goffi <goffi@goffi.org>
parents: 927
diff changeset
806 gen = (urllib.unquote(v).decode('utf-8') for v in request.args.get(key,[]))
8a393ae90f8c server (pages): post requests are now handled:
Goffi <goffi@goffi.org>
parents: 927
diff changeset
807 if multiple:
8a393ae90f8c server (pages): post requests are now handled:
Goffi <goffi@goffi.org>
parents: 927
diff changeset
808 ret.append(gen)
8a393ae90f8c server (pages): post requests are now handled:
Goffi <goffi@goffi.org>
parents: 927
diff changeset
809 else:
956
dabecab10faa server (pages): impleted CSRF protection:
Goffi <goffi@goffi.org>
parents: 955
diff changeset
810 try:
dabecab10faa server (pages): impleted CSRF protection:
Goffi <goffi@goffi.org>
parents: 955
diff changeset
811 ret.append(next(gen))
dabecab10faa server (pages): impleted CSRF protection:
Goffi <goffi@goffi.org>
parents: 955
diff changeset
812 except StopIteration:
962
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
813 raise KeyError(key)
931
8a393ae90f8c server (pages): post requests are now handled:
Goffi <goffi@goffi.org>
parents: 927
diff changeset
814
8a393ae90f8c server (pages): post requests are now handled:
Goffi <goffi@goffi.org>
parents: 927
diff changeset
815 return ret[0] if get_first else ret
8a393ae90f8c server (pages): post requests are now handled:
Goffi <goffi@goffi.org>
parents: 927
diff changeset
816
959
968eda9e982a server: added getAllPostedData
Goffi <goffi@goffi.org>
parents: 957
diff changeset
817 def getAllPostedData(self, request, except_=()):
968eda9e982a server: added getAllPostedData
Goffi <goffi@goffi.org>
parents: 957
diff changeset
818 """get all posted data
968eda9e982a server: added getAllPostedData
Goffi <goffi@goffi.org>
parents: 957
diff changeset
819
968eda9e982a server: added getAllPostedData
Goffi <goffi@goffi.org>
parents: 957
diff changeset
820 @param request(server.Request): request linked to the session
968eda9e982a server: added getAllPostedData
Goffi <goffi@goffi.org>
parents: 957
diff changeset
821 @param except_(iterable[unicode]): key of values to ignore
968eda9e982a server: added getAllPostedData
Goffi <goffi@goffi.org>
parents: 957
diff changeset
822 csrf_token will always be ignored
968eda9e982a server: added getAllPostedData
Goffi <goffi@goffi.org>
parents: 957
diff changeset
823 @return (dict[unicode, list[unicode]]): post values
968eda9e982a server: added getAllPostedData
Goffi <goffi@goffi.org>
parents: 957
diff changeset
824 """
968eda9e982a server: added getAllPostedData
Goffi <goffi@goffi.org>
parents: 957
diff changeset
825 except_ = tuple(except_) + (u'csrf_token',)
968eda9e982a server: added getAllPostedData
Goffi <goffi@goffi.org>
parents: 957
diff changeset
826 ret = {}
968eda9e982a server: added getAllPostedData
Goffi <goffi@goffi.org>
parents: 957
diff changeset
827 for key, values in request.args.iteritems():
968eda9e982a server: added getAllPostedData
Goffi <goffi@goffi.org>
parents: 957
diff changeset
828 key = urllib.unquote(key).decode('utf-8')
968eda9e982a server: added getAllPostedData
Goffi <goffi@goffi.org>
parents: 957
diff changeset
829 if key in except_:
968eda9e982a server: added getAllPostedData
Goffi <goffi@goffi.org>
parents: 957
diff changeset
830 continue
968eda9e982a server: added getAllPostedData
Goffi <goffi@goffi.org>
parents: 957
diff changeset
831 ret[key] = [urllib.unquote(v).decode('utf-8') for v in values]
968eda9e982a server: added getAllPostedData
Goffi <goffi@goffi.org>
parents: 957
diff changeset
832 return ret
968eda9e982a server: added getAllPostedData
Goffi <goffi@goffi.org>
parents: 957
diff changeset
833
922
16d1084d1371 server (pages): added "None" access (page is not rendered at all) and some HTTP code constants + helper methods to get session data
Goffi <goffi@goffi.org>
parents: 921
diff changeset
834 def getProfile(self, request):
16d1084d1371 server (pages): added "None" access (page is not rendered at all) and some HTTP code constants + helper methods to get session data
Goffi <goffi@goffi.org>
parents: 921
diff changeset
835 """helper method to easily get current profile
16d1084d1371 server (pages): added "None" access (page is not rendered at all) and some HTTP code constants + helper methods to get session data
Goffi <goffi@goffi.org>
parents: 921
diff changeset
836
16d1084d1371 server (pages): added "None" access (page is not rendered at all) and some HTTP code constants + helper methods to get session data
Goffi <goffi@goffi.org>
parents: 921
diff changeset
837 @return (unicode, None): current profile
16d1084d1371 server (pages): added "None" access (page is not rendered at all) and some HTTP code constants + helper methods to get session data
Goffi <goffi@goffi.org>
parents: 921
diff changeset
838 None if no profile session is started
16d1084d1371 server (pages): added "None" access (page is not rendered at all) and some HTTP code constants + helper methods to get session data
Goffi <goffi@goffi.org>
parents: 921
diff changeset
839 """
16d1084d1371 server (pages): added "None" access (page is not rendered at all) and some HTTP code constants + helper methods to get session data
Goffi <goffi@goffi.org>
parents: 921
diff changeset
840 sat_session = self.host.getSessionData(request, session_iface.ISATSession)
16d1084d1371 server (pages): added "None" access (page is not rendered at all) and some HTTP code constants + helper methods to get session data
Goffi <goffi@goffi.org>
parents: 921
diff changeset
841 return sat_session.profile
16d1084d1371 server (pages): added "None" access (page is not rendered at all) and some HTTP code constants + helper methods to get session data
Goffi <goffi@goffi.org>
parents: 921
diff changeset
842
16d1084d1371 server (pages): added "None" access (page is not rendered at all) and some HTTP code constants + helper methods to get session data
Goffi <goffi@goffi.org>
parents: 921
diff changeset
843 def getRData(self, request):
16d1084d1371 server (pages): added "None" access (page is not rendered at all) and some HTTP code constants + helper methods to get session data
Goffi <goffi@goffi.org>
parents: 921
diff changeset
844 """helper method to get request data dict
16d1084d1371 server (pages): added "None" access (page is not rendered at all) and some HTTP code constants + helper methods to get session data
Goffi <goffi@goffi.org>
parents: 921
diff changeset
845
16d1084d1371 server (pages): added "None" access (page is not rendered at all) and some HTTP code constants + helper methods to get session data
Goffi <goffi@goffi.org>
parents: 921
diff changeset
846 this dictionnary if for the request only, it is not saved in session
16d1084d1371 server (pages): added "None" access (page is not rendered at all) and some HTTP code constants + helper methods to get session data
Goffi <goffi@goffi.org>
parents: 921
diff changeset
847 It is mainly used to pass data between pages/methods called during request workflow
16d1084d1371 server (pages): added "None" access (page is not rendered at all) and some HTTP code constants + helper methods to get session data
Goffi <goffi@goffi.org>
parents: 921
diff changeset
848 @return (dict): request data
16d1084d1371 server (pages): added "None" access (page is not rendered at all) and some HTTP code constants + helper methods to get session data
Goffi <goffi@goffi.org>
parents: 921
diff changeset
849 """
16d1084d1371 server (pages): added "None" access (page is not rendered at all) and some HTTP code constants + helper methods to get session data
Goffi <goffi@goffi.org>
parents: 921
diff changeset
850 try:
16d1084d1371 server (pages): added "None" access (page is not rendered at all) and some HTTP code constants + helper methods to get session data
Goffi <goffi@goffi.org>
parents: 921
diff changeset
851 return request.data
16d1084d1371 server (pages): added "None" access (page is not rendered at all) and some HTTP code constants + helper methods to get session data
Goffi <goffi@goffi.org>
parents: 921
diff changeset
852 except AttributeError:
16d1084d1371 server (pages): added "None" access (page is not rendered at all) and some HTTP code constants + helper methods to get session data
Goffi <goffi@goffi.org>
parents: 921
diff changeset
853 request.data = {}
16d1084d1371 server (pages): added "None" access (page is not rendered at all) and some HTTP code constants + helper methods to get session data
Goffi <goffi@goffi.org>
parents: 921
diff changeset
854 return request.data
16d1084d1371 server (pages): added "None" access (page is not rendered at all) and some HTTP code constants + helper methods to get session data
Goffi <goffi@goffi.org>
parents: 921
diff changeset
855
16d1084d1371 server (pages): added "None" access (page is not rendered at all) and some HTTP code constants + helper methods to get session data
Goffi <goffi@goffi.org>
parents: 921
diff changeset
856 def _checkAccess(self, data, request):
16d1084d1371 server (pages): added "None" access (page is not rendered at all) and some HTTP code constants + helper methods to get session data
Goffi <goffi@goffi.org>
parents: 921
diff changeset
857 """Check access according to self.access
16d1084d1371 server (pages): added "None" access (page is not rendered at all) and some HTTP code constants + helper methods to get session data
Goffi <goffi@goffi.org>
parents: 921
diff changeset
858
16d1084d1371 server (pages): added "None" access (page is not rendered at all) and some HTTP code constants + helper methods to get session data
Goffi <goffi@goffi.org>
parents: 921
diff changeset
859 if access is not granted, show a HTTP_UNAUTHORIZED pageError and stop request,
16d1084d1371 server (pages): added "None" access (page is not rendered at all) and some HTTP code constants + helper methods to get session data
Goffi <goffi@goffi.org>
parents: 921
diff changeset
860 else return data (so it can be inserted in deferred chain
16d1084d1371 server (pages): added "None" access (page is not rendered at all) and some HTTP code constants + helper methods to get session data
Goffi <goffi@goffi.org>
parents: 921
diff changeset
861 """
16d1084d1371 server (pages): added "None" access (page is not rendered at all) and some HTTP code constants + helper methods to get session data
Goffi <goffi@goffi.org>
parents: 921
diff changeset
862 if self.access == C.PAGES_ACCESS_PUBLIC:
16d1084d1371 server (pages): added "None" access (page is not rendered at all) and some HTTP code constants + helper methods to get session data
Goffi <goffi@goffi.org>
parents: 921
diff changeset
863 pass
16d1084d1371 server (pages): added "None" access (page is not rendered at all) and some HTTP code constants + helper methods to get session data
Goffi <goffi@goffi.org>
parents: 921
diff changeset
864 elif self.access == C.PAGES_ACCESS_PROFILE:
16d1084d1371 server (pages): added "None" access (page is not rendered at all) and some HTTP code constants + helper methods to get session data
Goffi <goffi@goffi.org>
parents: 921
diff changeset
865 profile = self.getProfile(request)
16d1084d1371 server (pages): added "None" access (page is not rendered at all) and some HTTP code constants + helper methods to get session data
Goffi <goffi@goffi.org>
parents: 921
diff changeset
866 if not profile:
962
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
867 # no session started
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
868 if not self.host.options["allow_registration"]:
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
869 # registration not allowed, access is not granted
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
870 self.pageError(request, C.HTTP_UNAUTHORIZED)
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
871 else:
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
872 # registration allowed, we redirect to login page
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
873 login_url = self.getPageRedirectURL(request)
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
874 self.HTTPRedirect(request, login_url)
922
16d1084d1371 server (pages): added "None" access (page is not rendered at all) and some HTTP code constants + helper methods to get session data
Goffi <goffi@goffi.org>
parents: 921
diff changeset
875
16d1084d1371 server (pages): added "None" access (page is not rendered at all) and some HTTP code constants + helper methods to get session data
Goffi <goffi@goffi.org>
parents: 921
diff changeset
876 return data
16d1084d1371 server (pages): added "None" access (page is not rendered at all) and some HTTP code constants + helper methods to get session data
Goffi <goffi@goffi.org>
parents: 921
diff changeset
877
995
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
878 def renderPartial(self, request, template, template_data):
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
879 """Render a template to be inserted in dynamic page
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
880
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
881 this is NOT the normal page rendering method, it is used only to update
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
882 dynamic pages
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
883 @param template(unicode): path of the template to render
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
884 @param template_data(dict): template_data to use
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
885 """
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
886 if not self.dynamic:
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
887 raise exceptions.InternalError(_(u"renderPartial must only be used with dynamic pages"))
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
888 session_data = self.host.getSessionData(request, session_iface.ISATSession)
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
889
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
890 return self.host.renderer.render(
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
891 template,
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
892 root_path = '/templates/',
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
893 media_path = '/' + C.MEDIA_DIR,
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
894 cache_path = session_data.cache_dir,
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
895 main_menu = LiberviaPage.main_menu,
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
896 **template_data)
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
897
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
898 def renderAndUpdate(self, request, template, selectors, template_data_update, update_type="append"):
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
899 """Helper method to render a partial page element and update the page
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
900
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
901 this is NOT the normal page rendering method, it is used only to update
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
902 dynamic pages
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
903 @param request(server.Request): current HTTP request
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
904 @param template: same as for [renderPartial]
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
905 @param selectors: CSS selectors to use
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
906 @param template_data_update: template data to use
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
907 template data cached in request will be copied then updated
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
908 with this data
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
909 @parap update_type(unicode): one of:
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
910 append: append rendered element to selected element
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
911 """
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
912 template_data = request.template_data.copy()
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
913 template_data.update(template_data_update)
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
914 html = self.renderPartial(request, template, template_data)
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
915 request.sendData(u'dom',
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
916 selectors=selectors,
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
917 update_type=update_type,
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
918 html=html)
f88325b56a6a server: dynamic pages first draft:
Goffi <goffi@goffi.org>
parents: 994
diff changeset
919
923
edb322c87ea4 server (pages): pages now handle redirection, check self.pageRedirect docstring for details
Goffi <goffi@goffi.org>
parents: 922
diff changeset
920 def renderPage(self, request, skip_parse_url=False):
937
00236973e138 server (pages): an HTTP internal error is raised if an error is uncatched during page workflow
Goffi <goffi@goffi.org>
parents: 936
diff changeset
921 """Main method to handle the workflow of a LiberviaPage"""
994
b92b06f023cb pages: profile is now always set in template_data, and None if there is no user logged
Goffi <goffi@goffi.org>
parents: 990
diff changeset
922
923
edb322c87ea4 server (pages): pages now handle redirection, check self.pageRedirect docstring for details
Goffi <goffi@goffi.org>
parents: 922
diff changeset
923 # template_data are the variables passed to template
917
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
924 if not hasattr(request, 'template_data'):
957
67bf14c91d5c server (pages): added a confirm flag on successful post:
Goffi <goffi@goffi.org>
parents: 956
diff changeset
925 session_data = self.host.getSessionData(request, session_iface.ISATSession)
67bf14c91d5c server (pages): added a confirm flag on successful post:
Goffi <goffi@goffi.org>
parents: 956
diff changeset
926 csrf_token = session_data.csrf_token
994
b92b06f023cb pages: profile is now always set in template_data, and None if there is no user logged
Goffi <goffi@goffi.org>
parents: 990
diff changeset
927 request.template_data = {u'profile': session_data.profile,
b92b06f023cb pages: profile is now always set in template_data, and None if there is no user logged
Goffi <goffi@goffi.org>
parents: 990
diff changeset
928 u'csrf_token': csrf_token}
922
16d1084d1371 server (pages): added "None" access (page is not rendered at all) and some HTTP code constants + helper methods to get session data
Goffi <goffi@goffi.org>
parents: 921
diff changeset
929
16d1084d1371 server (pages): added "None" access (page is not rendered at all) and some HTTP code constants + helper methods to get session data
Goffi <goffi@goffi.org>
parents: 921
diff changeset
930 # XXX: here is the code which need to be executed once
16d1084d1371 server (pages): added "None" access (page is not rendered at all) and some HTTP code constants + helper methods to get session data
Goffi <goffi@goffi.org>
parents: 921
diff changeset
931 # at the beginning of the request hanling
917
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
932 if request.postpath and not request.postpath[-1]:
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
933 # we don't differenciate URLs finishing with '/' or not
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
934 del request.postpath[-1]
922
16d1084d1371 server (pages): added "None" access (page is not rendered at all) and some HTTP code constants + helper methods to get session data
Goffi <goffi@goffi.org>
parents: 921
diff changeset
935
917
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
936 d = defer.Deferred()
922
16d1084d1371 server (pages): added "None" access (page is not rendered at all) and some HTTP code constants + helper methods to get session data
Goffi <goffi@goffi.org>
parents: 921
diff changeset
937 d.addCallback(self._checkAccess, request)
16d1084d1371 server (pages): added "None" access (page is not rendered at all) and some HTTP code constants + helper methods to get session data
Goffi <goffi@goffi.org>
parents: 921
diff changeset
938
923
edb322c87ea4 server (pages): pages now handle redirection, check self.pageRedirect docstring for details
Goffi <goffi@goffi.org>
parents: 922
diff changeset
939 if self.redirect is not None:
edb322c87ea4 server (pages): pages now handle redirection, check self.pageRedirect docstring for details
Goffi <goffi@goffi.org>
parents: 922
diff changeset
940 self.pageRedirect(self.redirect, request, skip_parse_url=False)
edb322c87ea4 server (pages): pages now handle redirection, check self.pageRedirect docstring for details
Goffi <goffi@goffi.org>
parents: 922
diff changeset
941
edb322c87ea4 server (pages): pages now handle redirection, check self.pageRedirect docstring for details
Goffi <goffi@goffi.org>
parents: 922
diff changeset
942 if self.parse_url is not None and not skip_parse_url:
917
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
943 d.addCallback(self.parse_url, request)
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
944
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
945 d.addCallback(self._subpagesHandler, request)
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
946
931
8a393ae90f8c server (pages): post requests are now handled:
Goffi <goffi@goffi.org>
parents: 927
diff changeset
947 if request.method not in (C.HTTP_METHOD_GET, C.HTTP_METHOD_POST):
8a393ae90f8c server (pages): post requests are now handled:
Goffi <goffi@goffi.org>
parents: 927
diff changeset
948 # only HTTP GET and POST are handled so far
8a393ae90f8c server (pages): post requests are now handled:
Goffi <goffi@goffi.org>
parents: 927
diff changeset
949 d.addCallback(lambda dummy: self.pageError(request, C.HTTP_BAD_REQUEST))
8a393ae90f8c server (pages): post requests are now handled:
Goffi <goffi@goffi.org>
parents: 927
diff changeset
950
8a393ae90f8c server (pages): post requests are now handled:
Goffi <goffi@goffi.org>
parents: 927
diff changeset
951 if request.method == C.HTTP_METHOD_POST:
8a393ae90f8c server (pages): post requests are now handled:
Goffi <goffi@goffi.org>
parents: 927
diff changeset
952 if self.on_data_post is None:
8a393ae90f8c server (pages): post requests are now handled:
Goffi <goffi@goffi.org>
parents: 927
diff changeset
953 # if we don't have on_data_post, the page was not expecting POST
8a393ae90f8c server (pages): post requests are now handled:
Goffi <goffi@goffi.org>
parents: 927
diff changeset
954 # so we return an error
8a393ae90f8c server (pages): post requests are now handled:
Goffi <goffi@goffi.org>
parents: 927
diff changeset
955 d.addCallback(lambda dummy: self.pageError(request, C.HTTP_BAD_REQUEST))
8a393ae90f8c server (pages): post requests are now handled:
Goffi <goffi@goffi.org>
parents: 927
diff changeset
956 else:
8a393ae90f8c server (pages): post requests are now handled:
Goffi <goffi@goffi.org>
parents: 927
diff changeset
957 d.addCallback(self._on_data_post, request)
8a393ae90f8c server (pages): post requests are now handled:
Goffi <goffi@goffi.org>
parents: 927
diff changeset
958 # by default, POST follow normal behaviour after on_data_post is called
8a393ae90f8c server (pages): post requests are now handled:
Goffi <goffi@goffi.org>
parents: 927
diff changeset
959 # this can be changed by a redirection or other method call in on_data_post
8a393ae90f8c server (pages): post requests are now handled:
Goffi <goffi@goffi.org>
parents: 927
diff changeset
960
998
0848b8b0188d pages: dynamic set up is now done just before prepare_render call:
Goffi <goffi@goffi.org>
parents: 995
diff changeset
961 if self.dynamic:
0848b8b0188d pages: dynamic set up is now done just before prepare_render call:
Goffi <goffi@goffi.org>
parents: 995
diff changeset
962 d.addCallback(self._prepare_dynamic, request)
0848b8b0188d pages: dynamic set up is now done just before prepare_render call:
Goffi <goffi@goffi.org>
parents: 995
diff changeset
963
917
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
964 if self.prepare_render:
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
965 d.addCallback(self._prepare_render, request)
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
966
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
967 if self.template:
962
c7fba7709d05 Pages: various improvments:
Goffi <goffi@goffi.org>
parents: 961
diff changeset
968 d.addCallback(self._render_template, request)
917
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
969 elif self.render_method:
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
970 d.addCallback(self._render_method, request)
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
971
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
972 d.addCallback(self.writeData, request)
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
973 d.addErrback(self._renderEb, request)
937
00236973e138 server (pages): an HTTP internal error is raised if an error is uncatched during page workflow
Goffi <goffi@goffi.org>
parents: 936
diff changeset
974 d.addErrback(self._internalError, request)
917
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
975 d.callback(self)
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
976 return server.NOT_DONE_YET
86563d6c83b0 server: Libervia pages:
Goffi <goffi@goffi.org>
parents: 915
diff changeset
977
923
edb322c87ea4 server (pages): pages now handle redirection, check self.pageRedirect docstring for details
Goffi <goffi@goffi.org>
parents: 922
diff changeset
978 def render_GET(self, request):
edb322c87ea4 server (pages): pages now handle redirection, check self.pageRedirect docstring for details
Goffi <goffi@goffi.org>
parents: 922
diff changeset
979 return self.renderPage(request)
edb322c87ea4 server (pages): pages now handle redirection, check self.pageRedirect docstring for details
Goffi <goffi@goffi.org>
parents: 922
diff changeset
980
931
8a393ae90f8c server (pages): post requests are now handled:
Goffi <goffi@goffi.org>
parents: 927
diff changeset
981 def render_POST(self, request):
8a393ae90f8c server (pages): post requests are now handled:
Goffi <goffi@goffi.org>
parents: 927
diff changeset
982 return self.renderPage(request)