author | Julien Jehannet <julien.jehannet@logilab.fr> |
Thu, 23 Jun 2011 10:24:40 +0200 | |
branch | stable |
changeset 7557 | a397305f3976 |
parent 7528 | 11659cbe5eea |
child 7562 | cdef82ca9eab |
permissions | -rw-r--r-- |
7374
3c9850d929e5
[web request] don't define pageid js variable when one is found in form parameters (eg, page ajax call)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
7076
diff
changeset
|
1 |
# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved. |
5421
8167de96c523
proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5389
diff
changeset
|
2 |
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr |
8167de96c523
proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5389
diff
changeset
|
3 |
# |
8167de96c523
proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5389
diff
changeset
|
4 |
# This file is part of CubicWeb. |
8167de96c523
proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5389
diff
changeset
|
5 |
# |
8167de96c523
proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5389
diff
changeset
|
6 |
# CubicWeb is free software: you can redistribute it and/or modify it under the |
8167de96c523
proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5389
diff
changeset
|
7 |
# terms of the GNU Lesser General Public License as published by the Free |
8167de96c523
proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5389
diff
changeset
|
8 |
# Software Foundation, either version 2.1 of the License, or (at your option) |
8167de96c523
proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5389
diff
changeset
|
9 |
# any later version. |
8167de96c523
proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5389
diff
changeset
|
10 |
# |
5424
8ecbcbff9777
replace logilab-common by CubicWeb in disclaimer
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5421
diff
changeset
|
11 |
# CubicWeb is distributed in the hope that it will be useful, but WITHOUT |
5421
8167de96c523
proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5389
diff
changeset
|
12 |
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
8167de96c523
proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5389
diff
changeset
|
13 |
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more |
8167de96c523
proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5389
diff
changeset
|
14 |
# details. |
8167de96c523
proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5389
diff
changeset
|
15 |
# |
8167de96c523
proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5389
diff
changeset
|
16 |
# You should have received a copy of the GNU Lesser General Public License along |
8167de96c523
proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5389
diff
changeset
|
17 |
# with CubicWeb. If not, see <http://www.gnu.org/licenses/>. |
0 | 18 |
"""Set of base controllers, which are directly plugged into the application |
19 |
object to handle publication. |
|
5626 | 20 |
""" |
0 | 21 |
|
22 |
__docformat__ = "restructuredtext en" |
|
6582
8eb7883b4223
[pylint] fix a bug of pylint detected errors and i18n pb (calling builtins._ instead of req._)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6545
diff
changeset
|
23 |
_ = unicode |
0 | 24 |
|
4466
8b0ca7904820
moved generic datetime manipulation function to lgc
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4436
diff
changeset
|
25 |
from logilab.common.date import strptime |
0 | 26 |
|
5223
6abd6e3599f4
#773448: refactor session and 'no connection' handling, by introducing proper web session. We should now be able to see page even when no anon is configured, and be redirected to the login form as soon as one tries to do a query.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5201
diff
changeset
|
27 |
from cubicweb import (NoSelectableObject, ObjectNotFound, ValidationError, |
6abd6e3599f4
#773448: refactor session and 'no connection' handling, by introducing proper web session. We should now be able to see page even when no anon is configured, and be redirected to the login form as soon as one tries to do a query.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5201
diff
changeset
|
28 |
AuthenticationError, typed_eid) |
6140
65a619eb31c4
[boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6109
diff
changeset
|
29 |
from cubicweb.utils import UStringIO, json, json_dumps |
6683
68cfebd3b9f3
fix #724689: exception's display during ajax call
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6619
diff
changeset
|
30 |
from cubicweb.uilib import exc_message |
5584
c1823448f81d
[web] disallow authenticated users to access to the login form (closes #914873)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5546
diff
changeset
|
31 |
from cubicweb.selectors import authenticated_user, anonymous_user, match_form_params |
4023
eae23c40627a
drop common subpackage
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4003
diff
changeset
|
32 |
from cubicweb.mail import format_mail |
5940
0e3ae19b181a
[uilib] refactor json_dumps code organization
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5869
diff
changeset
|
33 |
from cubicweb.web import Redirect, RemoteCallFailed, DirectResponse |
0 | 34 |
from cubicweb.web.controller import Controller |
5223
6abd6e3599f4
#773448: refactor session and 'no connection' handling, by introducing proper web session. We should now be able to see page even when no anon is configured, and be redirected to the login form as soon as one tries to do a query.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5201
diff
changeset
|
35 |
from cubicweb.web.views import vid_from_rset, formrenderers |
5155
1dea6e0fdfc1
Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents:
5113
diff
changeset
|
36 |
|
0 | 37 |
try: |
38 |
from cubicweb.web.facet import (FilterRQLBuilder, get_facet, |
|
408
a8814ff6824e
reactivate tests and fix bug triggering removal of undesired relation (eg type restriction) in some cases
sylvain.thenault@logilab.fr
parents:
353
diff
changeset
|
39 |
prepare_facets_rqlst) |
0 | 40 |
HAS_SEARCH_RESTRICTION = True |
41 |
except ImportError: # gae |
|
42 |
HAS_SEARCH_RESTRICTION = False |
|
1419 | 43 |
|
44 |
def jsonize(func): |
|
5940
0e3ae19b181a
[uilib] refactor json_dumps code organization
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5869
diff
changeset
|
45 |
"""decorator to sets correct content_type and calls `json_dumps` on |
1419 | 46 |
results |
47 |
""" |
|
48 |
def wrapper(self, *args, **kwargs): |
|
3451
6b46d73823f5
[api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3377
diff
changeset
|
49 |
self._cw.set_content_type('application/json') |
1635
866563e2d0fc
don't depends on simplejson outside web/
sylvain.thenault@logilab.fr
parents:
1560
diff
changeset
|
50 |
return json_dumps(func(self, *args, **kwargs)) |
1527
c8ca1782e252
controller fixes
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
1467
diff
changeset
|
51 |
wrapper.__name__ = func.__name__ |
1419 | 52 |
return wrapper |
53 |
||
54 |
def xhtmlize(func): |
|
55 |
"""decorator to sets correct content_type and calls `xmlize` on results""" |
|
56 |
def wrapper(self, *args, **kwargs): |
|
3451
6b46d73823f5
[api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3377
diff
changeset
|
57 |
self._cw.set_content_type(self._cw.html_content_type()) |
1419 | 58 |
result = func(self, *args, **kwargs) |
3451
6b46d73823f5
[api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3377
diff
changeset
|
59 |
return ''.join((self._cw.document_surrounding_div(), result.strip(), |
2559
46859078c866
[R xhtml] remove xhtml_wrap* function, use instead a single req.document_surrounding_div method
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2557
diff
changeset
|
60 |
u'</div>')) |
1527
c8ca1782e252
controller fixes
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
1467
diff
changeset
|
61 |
wrapper.__name__ = func.__name__ |
1419 | 62 |
return wrapper |
63 |
||
64 |
def check_pageid(func): |
|
65 |
"""decorator which checks the given pageid is found in the |
|
66 |
user's session data |
|
67 |
""" |
|
68 |
def wrapper(self, *args, **kwargs): |
|
5223
6abd6e3599f4
#773448: refactor session and 'no connection' handling, by introducing proper web session. We should now be able to see page even when no anon is configured, and be redirected to the login form as soon as one tries to do a query.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5201
diff
changeset
|
69 |
data = self._cw.session.data.get(self._cw.pageid) |
1419 | 70 |
if data is None: |
3451
6b46d73823f5
[api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3377
diff
changeset
|
71 |
raise RemoteCallFailed(self._cw._('pageid-not-found')) |
1419 | 72 |
return func(self, *args, **kwargs) |
73 |
return wrapper |
|
74 |
||
75 |
||
0 | 76 |
class LoginController(Controller): |
3377
dd9d292b6a6d
use __regid__ instead of id on appobject classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3369
diff
changeset
|
77 |
__regid__ = 'login' |
5584
c1823448f81d
[web] disallow authenticated users to access to the login form (closes #914873)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5546
diff
changeset
|
78 |
__select__ = anonymous_user() |
0 | 79 |
|
80 |
def publish(self, rset=None): |
|
2476
1294a6bdf3bf
application -> instance where it makes sense
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2458
diff
changeset
|
81 |
"""log in the instance""" |
4072
ead446e70c28
some api update
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4023
diff
changeset
|
82 |
if self._cw.vreg.config['auth-mode'] == 'http': |
0 | 83 |
# HTTP authentication |
5223
6abd6e3599f4
#773448: refactor session and 'no connection' handling, by introducing proper web session. We should now be able to see page even when no anon is configured, and be redirected to the login form as soon as one tries to do a query.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5201
diff
changeset
|
84 |
raise AuthenticationError() |
0 | 85 |
else: |
86 |
# Cookie authentication |
|
3451
6b46d73823f5
[api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3377
diff
changeset
|
87 |
return self.appli.need_login_content(self._cw) |
0 | 88 |
|
1419 | 89 |
|
0 | 90 |
class LogoutController(Controller): |
3377
dd9d292b6a6d
use __regid__ instead of id on appobject classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3369
diff
changeset
|
91 |
__regid__ = 'logout' |
1419 | 92 |
|
0 | 93 |
def publish(self, rset=None): |
2476
1294a6bdf3bf
application -> instance where it makes sense
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2458
diff
changeset
|
94 |
"""logout from the instance""" |
4911
898c35be5873
#750055: make it easier to change post logout url
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4741
diff
changeset
|
95 |
return self.appli.session_handler.logout(self._cw, self.goto_url()) |
0 | 96 |
|
4911
898c35be5873
#750055: make it easier to change post logout url
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4741
diff
changeset
|
97 |
def goto_url(self): |
898c35be5873
#750055: make it easier to change post logout url
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4741
diff
changeset
|
98 |
# * in http auth mode, url will be ignored |
898c35be5873
#750055: make it easier to change post logout url
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4741
diff
changeset
|
99 |
# * in cookie mode redirecting to the index view is enough : either |
898c35be5873
#750055: make it easier to change post logout url
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4741
diff
changeset
|
100 |
# anonymous connection is allowed and the page will be displayed or |
898c35be5873
#750055: make it easier to change post logout url
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4741
diff
changeset
|
101 |
# we'll be redirected to the login form |
898c35be5873
#750055: make it easier to change post logout url
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4741
diff
changeset
|
102 |
msg = self._cw._('you have been logged out') |
5200
2b454c6ab7ef
[web] on logout, use the base_url argument of build_url instead of hacking the request to get proper url. This fix a bug on site with http/https versions: the session cookie is badly removed on logout
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5198
diff
changeset
|
103 |
# force base_url so on dual http/https configuration, we generate an url |
2b454c6ab7ef
[web] on logout, use the base_url argument of build_url instead of hacking the request to get proper url. This fix a bug on site with http/https versions: the session cookie is badly removed on logout
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5198
diff
changeset
|
104 |
# on the http version of the site |
2b454c6ab7ef
[web] on logout, use the base_url argument of build_url instead of hacking the request to get proper url. This fix a bug on site with http/https versions: the session cookie is badly removed on logout
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5198
diff
changeset
|
105 |
return self._cw.build_url('view', vid='index', __message=msg, |
2b454c6ab7ef
[web] on logout, use the base_url argument of build_url instead of hacking the request to get proper url. This fix a bug on site with http/https versions: the session cookie is badly removed on logout
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5198
diff
changeset
|
106 |
base_url=self._cw.vreg.config['base-url']) |
2b454c6ab7ef
[web] on logout, use the base_url argument of build_url instead of hacking the request to get proper url. This fix a bug on site with http/https versions: the session cookie is badly removed on logout
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5198
diff
changeset
|
107 |
|
0 | 108 |
|
109 |
class ViewController(Controller): |
|
823
cb8ccbef8fa5
main template refactoring
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
808
diff
changeset
|
110 |
"""standard entry point : |
cb8ccbef8fa5
main template refactoring
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
808
diff
changeset
|
111 |
- build result set |
cb8ccbef8fa5
main template refactoring
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
808
diff
changeset
|
112 |
- select and call main template |
cb8ccbef8fa5
main template refactoring
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
808
diff
changeset
|
113 |
""" |
3377
dd9d292b6a6d
use __regid__ instead of id on appobject classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3369
diff
changeset
|
114 |
__regid__ = 'view' |
823
cb8ccbef8fa5
main template refactoring
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
808
diff
changeset
|
115 |
template = 'main-template' |
1419 | 116 |
|
0 | 117 |
def publish(self, rset=None): |
118 |
"""publish a request, returning an encoded string""" |
|
823
cb8ccbef8fa5
main template refactoring
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
808
diff
changeset
|
119 |
view, rset = self._select_view_and_rset(rset) |
cb8ccbef8fa5
main template refactoring
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
808
diff
changeset
|
120 |
self.add_to_breadcrumbs(view) |
cb8ccbef8fa5
main template refactoring
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
808
diff
changeset
|
121 |
self.validate_cache(view) |
3451
6b46d73823f5
[api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3377
diff
changeset
|
122 |
template = self.appli.main_template_id(self._cw) |
6b46d73823f5
[api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3377
diff
changeset
|
123 |
return self._cw.vreg['views'].main_template(self._cw, template, |
6582
8eb7883b4223
[pylint] fix a bug of pylint detected errors and i18n pb (calling builtins._ instead of req._)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6545
diff
changeset
|
124 |
rset=rset, view=view) |
823
cb8ccbef8fa5
main template refactoring
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
808
diff
changeset
|
125 |
|
cb8ccbef8fa5
main template refactoring
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
808
diff
changeset
|
126 |
def _select_view_and_rset(self, rset): |
3451
6b46d73823f5
[api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3377
diff
changeset
|
127 |
req = self._cw |
823
cb8ccbef8fa5
main template refactoring
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
808
diff
changeset
|
128 |
if rset is None and not hasattr(req, '_rql_processed'): |
cb8ccbef8fa5
main template refactoring
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
808
diff
changeset
|
129 |
req._rql_processed = True |
5244
5467674ad101
[web] put a fake object that raise Unauthorized on any attribute access as req.cnx and req._user, so we are properly asked to authenticated on any view that tries to do something with one of those attributes (instead of doing defensive programming everywhere we're doing that)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5223
diff
changeset
|
130 |
if req.cnx: |
5715
2c3e83817a8e
[view] add a new entity_call method to entity view protocol, allowing some to work with not yet created entities. Also, start considering 'eid' form parameters where we only consider 'rql', so we can move on bloquing arbitrary rql inputs (more to do on this...)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5658
diff
changeset
|
131 |
rset = self.process_rql() |
5244
5467674ad101
[web] put a fake object that raise Unauthorized on any attribute access as req.cnx and req._user, so we are properly asked to authenticated on any view that tries to do something with one of those attributes (instead of doing defensive programming everywhere we're doing that)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5223
diff
changeset
|
132 |
else: |
5223
6abd6e3599f4
#773448: refactor session and 'no connection' handling, by introducing proper web session. We should now be able to see page even when no anon is configured, and be redirected to the login form as soon as one tries to do a query.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5201
diff
changeset
|
133 |
rset = None |
3659 | 134 |
vid = req.form.get('vid') or vid_from_rset(req, rset, self._cw.vreg.schema) |
823
cb8ccbef8fa5
main template refactoring
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
808
diff
changeset
|
135 |
try: |
3451
6b46d73823f5
[api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3377
diff
changeset
|
136 |
view = self._cw.vreg['views'].select(vid, req, rset=rset) |
823
cb8ccbef8fa5
main template refactoring
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
808
diff
changeset
|
137 |
except ObjectNotFound: |
cb8ccbef8fa5
main template refactoring
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
808
diff
changeset
|
138 |
self.warning("the view %s could not be found", vid) |
cb8ccbef8fa5
main template refactoring
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
808
diff
changeset
|
139 |
req.set_message(req._("The view %s could not be found") % vid) |
3659 | 140 |
vid = vid_from_rset(req, rset, self._cw.vreg.schema) |
3451
6b46d73823f5
[api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3377
diff
changeset
|
141 |
view = self._cw.vreg['views'].select(vid, req, rset=rset) |
823
cb8ccbef8fa5
main template refactoring
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
808
diff
changeset
|
142 |
except NoSelectableObject: |
cb8ccbef8fa5
main template refactoring
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
808
diff
changeset
|
143 |
if rset: |
cb8ccbef8fa5
main template refactoring
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
808
diff
changeset
|
144 |
req.set_message(req._("The view %s can not be applied to this query") % vid) |
cb8ccbef8fa5
main template refactoring
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
808
diff
changeset
|
145 |
else: |
3144
a5deac822a13
Bugfix: message was not written in english
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
2870
diff
changeset
|
146 |
req.set_message(req._("You have no access to this view or it can not " |
a5deac822a13
Bugfix: message was not written in english
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents:
2870
diff
changeset
|
147 |
"be used to display the current data.")) |
3890
d7a270f50f54
backport stable branch (one more time painfully)
Sylvain Thénault <sylvain.thenault@logilab.fr>
diff
changeset
|
148 |
vid = req.form.get('fallbackvid') or vid_from_rset(req, rset, req.vreg.schema) |
d7a270f50f54
backport stable branch (one more time painfully)
Sylvain Thénault <sylvain.thenault@logilab.fr>
diff
changeset
|
149 |
view = req.vreg['views'].select(vid, req, rset=rset) |
823
cb8ccbef8fa5
main template refactoring
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
808
diff
changeset
|
150 |
return view, rset |
cb8ccbef8fa5
main template refactoring
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
808
diff
changeset
|
151 |
|
cb8ccbef8fa5
main template refactoring
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
808
diff
changeset
|
152 |
def add_to_breadcrumbs(self, view): |
6302
ca5d09ff0379
[book - #1251259] reorganize plan for basetemplate, talk about class attributes
Stephanie Marcu <stephanie.marcu@logilab.fr>
parents:
6283
diff
changeset
|
153 |
# update breadcrumbs **before** validating cache, unless the view |
823
cb8ccbef8fa5
main template refactoring
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
808
diff
changeset
|
154 |
# specifies explicitly it should not be added to breadcrumb or the |
cb8ccbef8fa5
main template refactoring
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
808
diff
changeset
|
155 |
# view is a binary view |
cb8ccbef8fa5
main template refactoring
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
808
diff
changeset
|
156 |
if view.add_to_breadcrumbs and not view.binary: |
3451
6b46d73823f5
[api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3377
diff
changeset
|
157 |
self._cw.update_breadcrumbs() |
823
cb8ccbef8fa5
main template refactoring
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
808
diff
changeset
|
158 |
|
0 | 159 |
def execute_linkto(self, eid=None): |
160 |
"""XXX __linkto parameter may cause security issue |
|
161 |
||
162 |
defined here since custom application controller inheriting from this |
|
163 |
one use this method? |
|
164 |
""" |
|
3451
6b46d73823f5
[api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3377
diff
changeset
|
165 |
req = self._cw |
0 | 166 |
if not '__linkto' in req.form: |
167 |
return |
|
168 |
if eid is None: |
|
169 |
eid = typed_eid(req.form['eid']) |
|
170 |
for linkto in req.list_form_param('__linkto', pop=True): |
|
171 |
rtype, eids, target = linkto.split(':') |
|
172 |
assert target in ('subject', 'object') |
|
173 |
eids = eids.split('_') |
|
174 |
if target == 'subject': |
|
175 |
rql = 'SET X %s Y WHERE X eid %%(x)s, Y eid %%(y)s' % rtype |
|
176 |
else: |
|
177 |
rql = 'SET Y %s X WHERE X eid %%(x)s, Y eid %%(y)s' % rtype |
|
178 |
for teid in eids: |
|
5174
78438ad513ca
#759035: Automate addition of eid cachekey in RQL analysis
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5159
diff
changeset
|
179 |
req.execute(rql, {'x': eid, 'y': typed_eid(teid)}) |
0 | 180 |
|
181 |
||
2240
ff84892900ac
factorize form validation code, fix pb with validation error in inlined forms during creation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2079
diff
changeset
|
182 |
def _validation_error(req, ex): |
2293 | 183 |
req.cnx.rollback() |
4719
aaed3f813ef8
kill dead/useless code as suggested by pylint
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4638
diff
changeset
|
184 |
# XXX necessary to remove existant validation error? |
aaed3f813ef8
kill dead/useless code as suggested by pylint
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4638
diff
changeset
|
185 |
# imo (syt), it's not necessary |
5223
6abd6e3599f4
#773448: refactor session and 'no connection' handling, by introducing proper web session. We should now be able to see page even when no anon is configured, and be redirected to the login form as soon as one tries to do a query.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5201
diff
changeset
|
186 |
req.session.data.pop(req.form.get('__errorurl'), None) |
2240
ff84892900ac
factorize form validation code, fix pb with validation error in inlined forms during creation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2079
diff
changeset
|
187 |
foreid = ex.entity |
ff84892900ac
factorize form validation code, fix pb with validation error in inlined forms during creation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2079
diff
changeset
|
188 |
eidmap = req.data.get('eidmap', {}) |
ff84892900ac
factorize form validation code, fix pb with validation error in inlined forms during creation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2079
diff
changeset
|
189 |
for var, eid in eidmap.items(): |
ff84892900ac
factorize form validation code, fix pb with validation error in inlined forms during creation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2079
diff
changeset
|
190 |
if foreid == eid: |
ff84892900ac
factorize form validation code, fix pb with validation error in inlined forms during creation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2079
diff
changeset
|
191 |
foreid = var |
ff84892900ac
factorize form validation code, fix pb with validation error in inlined forms during creation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2079
diff
changeset
|
192 |
break |
ff84892900ac
factorize form validation code, fix pb with validation error in inlined forms during creation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2079
diff
changeset
|
193 |
return (foreid, ex.errors) |
ff84892900ac
factorize form validation code, fix pb with validation error in inlined forms during creation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2079
diff
changeset
|
194 |
|
3232
eccb7380dc3b
[controllers] allow onsuccess / onfailure callback to be passed to validateform
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3144
diff
changeset
|
195 |
|
2240
ff84892900ac
factorize form validation code, fix pb with validation error in inlined forms during creation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2079
diff
changeset
|
196 |
def _validate_form(req, vreg): |
ff84892900ac
factorize form validation code, fix pb with validation error in inlined forms during creation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2079
diff
changeset
|
197 |
# XXX should use the `RemoteCallFailed` mechanism |
ff84892900ac
factorize form validation code, fix pb with validation error in inlined forms during creation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2079
diff
changeset
|
198 |
try: |
2650
18aec79ec3a3
R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2559
diff
changeset
|
199 |
ctrl = vreg['controllers'].select('edit', req=req) |
2240
ff84892900ac
factorize form validation code, fix pb with validation error in inlined forms during creation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2079
diff
changeset
|
200 |
except NoSelectableObject: |
3232
eccb7380dc3b
[controllers] allow onsuccess / onfailure callback to be passed to validateform
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3144
diff
changeset
|
201 |
return (False, {None: req._('not authorized')}, None) |
2240
ff84892900ac
factorize form validation code, fix pb with validation error in inlined forms during creation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2079
diff
changeset
|
202 |
try: |
2255
c346af0727ca
more generic way to detect json requests (not yet perfect though)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2240
diff
changeset
|
203 |
ctrl.publish(None) |
2240
ff84892900ac
factorize form validation code, fix pb with validation error in inlined forms during creation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2079
diff
changeset
|
204 |
except ValidationError, ex: |
3232
eccb7380dc3b
[controllers] allow onsuccess / onfailure callback to be passed to validateform
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3144
diff
changeset
|
205 |
return (False, _validation_error(req, ex), ctrl._edited_entity) |
2240
ff84892900ac
factorize form validation code, fix pb with validation error in inlined forms during creation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2079
diff
changeset
|
206 |
except Redirect, ex: |
ff84892900ac
factorize form validation code, fix pb with validation error in inlined forms during creation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2079
diff
changeset
|
207 |
try: |
ff84892900ac
factorize form validation code, fix pb with validation error in inlined forms during creation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2079
diff
changeset
|
208 |
req.cnx.commit() # ValidationError may be raise on commit |
ff84892900ac
factorize form validation code, fix pb with validation error in inlined forms during creation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2079
diff
changeset
|
209 |
except ValidationError, ex: |
3232
eccb7380dc3b
[controllers] allow onsuccess / onfailure callback to be passed to validateform
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3144
diff
changeset
|
210 |
return (False, _validation_error(req, ex), ctrl._edited_entity) |
3571
54743fc6172c
[json validation] catch everything here
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3518
diff
changeset
|
211 |
except Exception, ex: |
54743fc6172c
[json validation] catch everything here
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3518
diff
changeset
|
212 |
req.cnx.rollback() |
54743fc6172c
[json validation] catch everything here
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3518
diff
changeset
|
213 |
req.exception('unexpected error while validating form') |
6107
05061eda1fa7
[web controller]Â don't try to translate arbitrary exception message
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5940
diff
changeset
|
214 |
return (False, str(ex).decode('utf-8'), ctrl._edited_entity) |
2240
ff84892900ac
factorize form validation code, fix pb with validation error in inlined forms during creation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2079
diff
changeset
|
215 |
else: |
3608
5a46e68c3d3c
[editcontroller] backout (sort of) removal of entity.complete() in validate_form
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3599
diff
changeset
|
216 |
# complete entity: it can be used in js callbacks where we might |
5a46e68c3d3c
[editcontroller] backout (sort of) removal of entity.complete() in validate_form
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3599
diff
changeset
|
217 |
# want every possible information |
5a46e68c3d3c
[editcontroller] backout (sort of) removal of entity.complete() in validate_form
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3599
diff
changeset
|
218 |
if ctrl._edited_entity: |
5a46e68c3d3c
[editcontroller] backout (sort of) removal of entity.complete() in validate_form
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3599
diff
changeset
|
219 |
ctrl._edited_entity.complete() |
3232
eccb7380dc3b
[controllers] allow onsuccess / onfailure callback to be passed to validateform
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3144
diff
changeset
|
220 |
return (True, ex.location, ctrl._edited_entity) |
2240
ff84892900ac
factorize form validation code, fix pb with validation error in inlined forms during creation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2079
diff
changeset
|
221 |
except Exception, ex: |
ff84892900ac
factorize form validation code, fix pb with validation error in inlined forms during creation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2079
diff
changeset
|
222 |
req.cnx.rollback() |
ff84892900ac
factorize form validation code, fix pb with validation error in inlined forms during creation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2079
diff
changeset
|
223 |
req.exception('unexpected error while validating form') |
6107
05061eda1fa7
[web controller]Â don't try to translate arbitrary exception message
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5940
diff
changeset
|
224 |
return (False, str(ex).decode('utf-8'), ctrl._edited_entity) |
3232
eccb7380dc3b
[controllers] allow onsuccess / onfailure callback to be passed to validateform
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3144
diff
changeset
|
225 |
return (False, '???', None) |
2240
ff84892900ac
factorize form validation code, fix pb with validation error in inlined forms during creation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2079
diff
changeset
|
226 |
|
ff84892900ac
factorize form validation code, fix pb with validation error in inlined forms during creation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2079
diff
changeset
|
227 |
|
0 | 228 |
class FormValidatorController(Controller): |
3377
dd9d292b6a6d
use __regid__ instead of id on appobject classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3369
diff
changeset
|
229 |
__regid__ = 'validateform' |
0 | 230 |
|
3232
eccb7380dc3b
[controllers] allow onsuccess / onfailure callback to be passed to validateform
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3144
diff
changeset
|
231 |
def response(self, domid, status, args, entity): |
3451
6b46d73823f5
[api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3377
diff
changeset
|
232 |
callback = str(self._cw.form.get('__onsuccess', 'null')) |
6b46d73823f5
[api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3377
diff
changeset
|
233 |
errback = str(self._cw.form.get('__onfailure', 'null')) |
6b46d73823f5
[api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3377
diff
changeset
|
234 |
cbargs = str(self._cw.form.get('__cbargs', 'null')) |
6b46d73823f5
[api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3377
diff
changeset
|
235 |
self._cw.set_content_type('text/html') |
5556
9ab2b4c74baf
[entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5555
diff
changeset
|
236 |
jsargs = json_dumps((status, args, entity)) |
2557
200985d3258d
make it easy to change response of FormValidatorController
Florent <florent@secondweb.fr>
parents:
2555
diff
changeset
|
237 |
return """<script type="text/javascript"> |
3343
383b42263bb1
[validatecontroller] allow additional args to be passed to the js callback
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3327
diff
changeset
|
238 |
window.parent.handleFormValidationResponse('%s', %s, %s, %s, %s); |
383b42263bb1
[validatecontroller] allow additional args to be passed to the js callback
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3327
diff
changeset
|
239 |
</script>""" % (domid, callback, errback, jsargs, cbargs) |
2557
200985d3258d
make it easy to change response of FormValidatorController
Florent <florent@secondweb.fr>
parents:
2555
diff
changeset
|
240 |
|
0 | 241 |
def publish(self, rset=None): |
3451
6b46d73823f5
[api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3377
diff
changeset
|
242 |
self._cw.json_request = True |
2240
ff84892900ac
factorize form validation code, fix pb with validation error in inlined forms during creation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2079
diff
changeset
|
243 |
# XXX unclear why we have a separated controller here vs |
ff84892900ac
factorize form validation code, fix pb with validation error in inlined forms during creation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2079
diff
changeset
|
244 |
# js_validate_form on the json controller |
3451
6b46d73823f5
[api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3377
diff
changeset
|
245 |
status, args, entity = _validate_form(self._cw, self._cw.vreg) |
6b46d73823f5
[api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3377
diff
changeset
|
246 |
domid = self._cw.form.get('__domid', 'entityForm').encode( |
6b46d73823f5
[api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3377
diff
changeset
|
247 |
self._cw.encoding) |
3232
eccb7380dc3b
[controllers] allow onsuccess / onfailure callback to be passed to validateform
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3144
diff
changeset
|
248 |
return self.response(domid, status, args, entity) |
0 | 249 |
|
5658
7b9553a9db65
[ajax] refactor/cleanup low-level ajax functions
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
5627
diff
changeset
|
250 |
def optional_kwargs(extraargs): |
7b9553a9db65
[ajax] refactor/cleanup low-level ajax functions
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
5627
diff
changeset
|
251 |
if extraargs is None: |
7b9553a9db65
[ajax] refactor/cleanup low-level ajax functions
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
5627
diff
changeset
|
252 |
return {} |
6240 | 253 |
# we receive unicode keys which is not supported by the **syntax |
254 |
return dict((str(key), value) for key, value in extraargs.iteritems()) |
|
0 | 255 |
|
6684
b8bd0ecced2e
minor cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6683
diff
changeset
|
256 |
|
0 | 257 |
class JSonController(Controller): |
3377
dd9d292b6a6d
use __regid__ instead of id on appobject classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3369
diff
changeset
|
258 |
__regid__ = 'json' |
0 | 259 |
|
260 |
def publish(self, rset=None): |
|
1419 | 261 |
"""call js_* methods. Expected form keys: |
262 |
||
263 |
:fname: the method name without the js_ prefix |
|
264 |
:args: arguments list (json) |
|
265 |
||
266 |
note: it's the responsability of js_* methods to set the correct |
|
267 |
response content type |
|
268 |
""" |
|
3451
6b46d73823f5
[api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3377
diff
changeset
|
269 |
self._cw.json_request = True |
1419 | 270 |
try: |
3451
6b46d73823f5
[api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3377
diff
changeset
|
271 |
fname = self._cw.form['fname'] |
1419 | 272 |
func = getattr(self, 'js_%s' % fname) |
2079
aff0950c54c4
proper error when fname isn't specified
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2045
diff
changeset
|
273 |
except KeyError: |
aff0950c54c4
proper error when fname isn't specified
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2045
diff
changeset
|
274 |
raise RemoteCallFailed('no method specified') |
1419 | 275 |
except AttributeError: |
276 |
raise RemoteCallFailed('no %s method' % fname) |
|
277 |
# no <arg> attribute means the callback takes no argument |
|
3451
6b46d73823f5
[api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3377
diff
changeset
|
278 |
args = self._cw.form.get('arg', ()) |
1419 | 279 |
if not isinstance(args, (list, tuple)): |
280 |
args = (args,) |
|
5139
61b607c8571b
catch and log errors caused by bad json data
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
5113
diff
changeset
|
281 |
try: |
5377
84d14ddfae13
[python2.6] prefer python2.6's builtin json module over simplejson
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
5366
diff
changeset
|
282 |
args = [json.loads(arg) for arg in args] |
5139
61b607c8571b
catch and log errors caused by bad json data
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents:
5113
diff
changeset
|
283 |
except ValueError, exc: |
7435
a2c83140794e
[json controller] fix .exception call msg format string (missing one slot)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
7393
diff
changeset
|
284 |
self.exception('error while decoding json arguments for js_%s: %s (err: %s)', |
6207 | 285 |
fname, args, exc) |
6683
68cfebd3b9f3
fix #724689: exception's display during ajax call
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6619
diff
changeset
|
286 |
raise RemoteCallFailed(exc_message(exc, self._cw.encoding)) |
0 | 287 |
try: |
1419 | 288 |
result = func(*args) |
5155
1dea6e0fdfc1
Switched from TwistedWeb2 to TwistedWeb
Adrien Chauve <adrien.chauve@logilab.fr>
parents:
5113
diff
changeset
|
289 |
except (RemoteCallFailed, DirectResponse): |
1419 | 290 |
raise |
6683
68cfebd3b9f3
fix #724689: exception's display during ajax call
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6619
diff
changeset
|
291 |
except Exception, exc: |
6109
47d9c0e0f7b7
integrate Celso's work on translation file: proper/complete spanish translation, fixed some typos in french translation, occured -> occurred fix in various places
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6107
diff
changeset
|
292 |
self.exception('an exception occurred while calling js_%s(%s): %s', |
6683
68cfebd3b9f3
fix #724689: exception's display during ajax call
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6619
diff
changeset
|
293 |
fname, args, exc) |
68cfebd3b9f3
fix #724689: exception's display during ajax call
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6619
diff
changeset
|
294 |
raise RemoteCallFailed(exc_message(exc, self._cw.encoding)) |
1419 | 295 |
if result is None: |
296 |
return '' |
|
297 |
# get unicode on @htmlize methods, encoded string on @jsonize methods |
|
298 |
elif isinstance(result, unicode): |
|
3451
6b46d73823f5
[api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3377
diff
changeset
|
299 |
return result.encode(self._cw.encoding) |
1419 | 300 |
return result |
301 |
||
302 |
def _rebuild_posted_form(self, names, values, action=None): |
|
303 |
form = {} |
|
304 |
for name, value in zip(names, values): |
|
305 |
# remove possible __action_xxx inputs |
|
306 |
if name.startswith('__action'): |
|
5546
1bdaa9e1cd57
[forms] consider __action_xxx field if passed to JSonController.validate_form
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
5426
diff
changeset
|
307 |
if action is None: |
1bdaa9e1cd57
[forms] consider __action_xxx field if passed to JSonController.validate_form
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
5426
diff
changeset
|
308 |
# strip '__action_' to get the actual action name |
1bdaa9e1cd57
[forms] consider __action_xxx field if passed to JSonController.validate_form
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
5426
diff
changeset
|
309 |
action = name[9:] |
1419 | 310 |
continue |
311 |
# form.setdefault(name, []).append(value) |
|
312 |
if name in form: |
|
313 |
curvalue = form[name] |
|
314 |
if isinstance(curvalue, list): |
|
315 |
curvalue.append(value) |
|
316 |
else: |
|
317 |
form[name] = [curvalue, value] |
|
318 |
else: |
|
319 |
form[name] = value |
|
320 |
# simulate click on __action_%s button to help the controller |
|
321 |
if action: |
|
322 |
form['__action_%s' % action] = u'whatever' |
|
323 |
return form |
|
0 | 324 |
|
5174
78438ad513ca
#759035: Automate addition of eid cachekey in RQL analysis
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5159
diff
changeset
|
325 |
def _exec(self, rql, args=None, rocheck=True): |
0 | 326 |
"""json mode: execute RQL and return resultset as json""" |
6237
0c886f667b1f
[basecontroller] handle case where the query is prefixed by 'rql:' as allowed by the search input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6207
diff
changeset
|
327 |
rql = rql.strip() |
0c886f667b1f
[basecontroller] handle case where the query is prefixed by 'rql:' as allowed by the search input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6207
diff
changeset
|
328 |
if rql.startswith('rql:'): |
0c886f667b1f
[basecontroller] handle case where the query is prefixed by 'rql:' as allowed by the search input
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6207
diff
changeset
|
329 |
rql = rql[4:] |
0 | 330 |
if rocheck: |
3451
6b46d73823f5
[api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3377
diff
changeset
|
331 |
self._cw.ensure_ro_rql(rql) |
0 | 332 |
try: |
5174
78438ad513ca
#759035: Automate addition of eid cachekey in RQL analysis
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5159
diff
changeset
|
333 |
return self._cw.execute(rql, args) |
0 | 334 |
except Exception, ex: |
335 |
self.exception("error in _exec(rql=%s): %s", rql, ex) |
|
336 |
return None |
|
337 |
return None |
|
338 |
||
5454
76b828dc3b9f
[json-controller] - refactoring of js_component and js_view, it now uses _call_view
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents:
5453
diff
changeset
|
339 |
def _call_view(self, view, paginate=False, **kwargs): |
6249
1729f53b3e42
fix regretion introduced by changeset "pagination/ ajaxes fixes" (2f5ebeb7665d)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6240
diff
changeset
|
340 |
divid = self._cw.form.get('divid') |
2852
858b33162e9d
[ajax] allow inlineCreationForms to add their own JS / CSS
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
2681
diff
changeset
|
341 |
# we need to call pagination before with the stream set |
6140
65a619eb31c4
[boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6109
diff
changeset
|
342 |
try: |
65a619eb31c4
[boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6109
diff
changeset
|
343 |
stream = view.set_stream() |
65a619eb31c4
[boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6109
diff
changeset
|
344 |
except AttributeError: |
65a619eb31c4
[boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6109
diff
changeset
|
345 |
stream = UStringIO() |
65a619eb31c4
[boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6109
diff
changeset
|
346 |
kwargs['w'] = stream.write |
65a619eb31c4
[boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6109
diff
changeset
|
347 |
assert not paginate |
6249
1729f53b3e42
fix regretion introduced by changeset "pagination/ ajaxes fixes" (2f5ebeb7665d)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6240
diff
changeset
|
348 |
if divid == 'pageContent': |
1729f53b3e42
fix regretion introduced by changeset "pagination/ ajaxes fixes" (2f5ebeb7665d)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6240
diff
changeset
|
349 |
# ensure divid isn't reused by the view (e.g. table view) |
1729f53b3e42
fix regretion introduced by changeset "pagination/ ajaxes fixes" (2f5ebeb7665d)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6240
diff
changeset
|
350 |
del self._cw.form['divid'] |
1729f53b3e42
fix regretion introduced by changeset "pagination/ ajaxes fixes" (2f5ebeb7665d)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6240
diff
changeset
|
351 |
# mimick main template behaviour |
1729f53b3e42
fix regretion introduced by changeset "pagination/ ajaxes fixes" (2f5ebeb7665d)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6240
diff
changeset
|
352 |
stream.write(u'<div id="pageContent">') |
1729f53b3e42
fix regretion introduced by changeset "pagination/ ajaxes fixes" (2f5ebeb7665d)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6240
diff
changeset
|
353 |
vtitle = self._cw.form.get('vtitle') |
1729f53b3e42
fix regretion introduced by changeset "pagination/ ajaxes fixes" (2f5ebeb7665d)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6240
diff
changeset
|
354 |
if vtitle: |
1729f53b3e42
fix regretion introduced by changeset "pagination/ ajaxes fixes" (2f5ebeb7665d)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6240
diff
changeset
|
355 |
stream.write(u'<h1 class="vtitle">%s</h1>\n' % vtitle) |
1729f53b3e42
fix regretion introduced by changeset "pagination/ ajaxes fixes" (2f5ebeb7665d)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6240
diff
changeset
|
356 |
paginate = True |
5454
76b828dc3b9f
[json-controller] - refactoring of js_component and js_view, it now uses _call_view
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents:
5453
diff
changeset
|
357 |
if paginate: |
2870
e3a5b7c3f767
use view.paginate
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
2862
diff
changeset
|
358 |
view.paginate() |
6249
1729f53b3e42
fix regretion introduced by changeset "pagination/ ajaxes fixes" (2f5ebeb7665d)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6240
diff
changeset
|
359 |
if divid == 'pageContent': |
1729f53b3e42
fix regretion introduced by changeset "pagination/ ajaxes fixes" (2f5ebeb7665d)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6240
diff
changeset
|
360 |
stream.write(u'<div id="contentmain">') |
2852
858b33162e9d
[ajax] allow inlineCreationForms to add their own JS / CSS
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
2681
diff
changeset
|
361 |
view.render(**kwargs) |
5454
76b828dc3b9f
[json-controller] - refactoring of js_component and js_view, it now uses _call_view
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents:
5453
diff
changeset
|
362 |
extresources = self._cw.html_headers.getvalue(skiphead=True) |
2852
858b33162e9d
[ajax] allow inlineCreationForms to add their own JS / CSS
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
2681
diff
changeset
|
363 |
if extresources: |
858b33162e9d
[ajax] allow inlineCreationForms to add their own JS / CSS
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
2681
diff
changeset
|
364 |
stream.write(u'<div class="ajaxHtmlHead">\n') # XXX use a widget ? |
858b33162e9d
[ajax] allow inlineCreationForms to add their own JS / CSS
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
2681
diff
changeset
|
365 |
stream.write(extresources) |
858b33162e9d
[ajax] allow inlineCreationForms to add their own JS / CSS
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
2681
diff
changeset
|
366 |
stream.write(u'</div>\n') |
6249
1729f53b3e42
fix regretion introduced by changeset "pagination/ ajaxes fixes" (2f5ebeb7665d)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6240
diff
changeset
|
367 |
if divid == 'pageContent': |
2852
858b33162e9d
[ajax] allow inlineCreationForms to add their own JS / CSS
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
2681
diff
changeset
|
368 |
stream.write(u'</div></div>') |
858b33162e9d
[ajax] allow inlineCreationForms to add their own JS / CSS
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
2681
diff
changeset
|
369 |
return stream.getvalue() |
858b33162e9d
[ajax] allow inlineCreationForms to add their own JS / CSS
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
2681
diff
changeset
|
370 |
|
1419 | 371 |
@xhtmlize |
372 |
def js_view(self): |
|
643
616191014b8b
[jsoncontroller] reorganize _html_exec (used by replacePageChunk) to output required css and js scripts
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
603
diff
changeset
|
373 |
# XXX try to use the page-content template |
3451
6b46d73823f5
[api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3377
diff
changeset
|
374 |
req = self._cw |
0 | 375 |
rql = req.form.get('rql') |
1419 | 376 |
if rql: |
0 | 377 |
rset = self._exec(rql) |
5715
2c3e83817a8e
[view] add a new entity_call method to entity view protocol, allowing some to work with not yet created entities. Also, start considering 'eid' form parameters where we only consider 'rql', so we can move on bloquing arbitrary rql inputs (more to do on this...)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5658
diff
changeset
|
378 |
elif 'eid' in req.form: |
2c3e83817a8e
[view] add a new entity_call method to entity view protocol, allowing some to work with not yet created entities. Also, start considering 'eid' form parameters where we only consider 'rql', so we can move on bloquing arbitrary rql inputs (more to do on this...)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5658
diff
changeset
|
379 |
rset = self._cw.eid_rset(req.form['eid']) |
1419 | 380 |
else: |
381 |
rset = None |
|
3659 | 382 |
vid = req.form.get('vid') or vid_from_rset(req, rset, self._cw.vreg.schema) |
0 | 383 |
try: |
3451
6b46d73823f5
[api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3377
diff
changeset
|
384 |
view = self._cw.vreg['views'].select(vid, req, rset=rset) |
0 | 385 |
except NoSelectableObject: |
386 |
vid = req.form.get('fallbackvid', 'noresult') |
|
3451
6b46d73823f5
[api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3377
diff
changeset
|
387 |
view = self._cw.vreg['views'].select(vid, req, rset=rset) |
4638
c7d2145abf61
grmmbl, bad resolve
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4637
diff
changeset
|
388 |
self.validate_cache(view) |
6249
1729f53b3e42
fix regretion introduced by changeset "pagination/ ajaxes fixes" (2f5ebeb7665d)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6240
diff
changeset
|
389 |
return self._call_view(view, paginate=req.form.pop('paginate', False)) |
0 | 390 |
|
1419 | 391 |
@xhtmlize |
392 |
def js_prop_widget(self, propkey, varname, tabindex=None): |
|
393 |
"""specific method for CWProperty handling""" |
|
3451
6b46d73823f5
[api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3377
diff
changeset
|
394 |
entity = self._cw.vreg['etypes'].etype_class('CWProperty')(self._cw) |
1419 | 395 |
entity.eid = varname |
396 |
entity['pkey'] = propkey |
|
3451
6b46d73823f5
[api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3377
diff
changeset
|
397 |
form = self._cw.vreg['forms'].select('edition', self._cw, entity=entity) |
3514
1531edc6c021
forgotten that one
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3343
diff
changeset
|
398 |
form.build_context() |
1419 | 399 |
vfield = form.field_by_name('value') |
5223
6abd6e3599f4
#773448: refactor session and 'no connection' handling, by introducing proper web session. We should now be able to see page even when no anon is configured, and be redirected to the login form as soon as one tries to do a query.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5201
diff
changeset
|
400 |
renderer = formrenderers.FormRenderer(self._cw) |
1419 | 401 |
return vfield.render(form, renderer, tabindex=tabindex) \ |
402 |
+ renderer.render_help(form, vfield) |
|
0 | 403 |
|
1419 | 404 |
@xhtmlize |
405 |
def js_component(self, compid, rql, registry='components', extraargs=None): |
|
406 |
if rql: |
|
407 |
rset = self._exec(rql) |
|
408 |
else: |
|
409 |
rset = None |
|
5113
f8cbdb51e6d4
[cleanup] tb already printed by self.exception; add note
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4984
diff
changeset
|
410 |
# XXX while it sounds good, addition of the try/except below cause pb: |
f8cbdb51e6d4
[cleanup] tb already printed by self.exception; add note
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4984
diff
changeset
|
411 |
# when filtering using facets return an empty rset, the edition box |
f8cbdb51e6d4
[cleanup] tb already printed by self.exception; add note
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4984
diff
changeset
|
412 |
# isn't anymore selectable, as expected. The pb is that with the |
6109
47d9c0e0f7b7
integrate Celso's work on translation file: proper/complete spanish translation, fixed some typos in french translation, occured -> occurred fix in various places
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6107
diff
changeset
|
413 |
# try/except below, we see a "an error occurred" message in the ui, while |
5113
f8cbdb51e6d4
[cleanup] tb already printed by self.exception; add note
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4984
diff
changeset
|
414 |
# we don't see it without it. Proper fix would probably be to deal with |
f8cbdb51e6d4
[cleanup] tb already printed by self.exception; add note
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4984
diff
changeset
|
415 |
# this by allowing facet handling code to tell to js_component that such |
f8cbdb51e6d4
[cleanup] tb already printed by self.exception; add note
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4984
diff
changeset
|
416 |
# error is expected and should'nt be reported. |
f8cbdb51e6d4
[cleanup] tb already printed by self.exception; add note
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4984
diff
changeset
|
417 |
#try: |
f8cbdb51e6d4
[cleanup] tb already printed by self.exception; add note
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4984
diff
changeset
|
418 |
comp = self._cw.vreg[registry].select(compid, self._cw, rset=rset, |
6250 | 419 |
**optional_kwargs(extraargs)) |
5113
f8cbdb51e6d4
[cleanup] tb already printed by self.exception; add note
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4984
diff
changeset
|
420 |
#except NoSelectableObject: |
f8cbdb51e6d4
[cleanup] tb already printed by self.exception; add note
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4984
diff
changeset
|
421 |
# raise RemoteCallFailed('unselectable') |
6787
aede8c85207f
[json controler] extraargs in js_component contains unicode keys which may not be given as argument names
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6684
diff
changeset
|
422 |
return self._call_view(comp, **optional_kwargs(extraargs)) |
1419 | 423 |
|
5658
7b9553a9db65
[ajax] refactor/cleanup low-level ajax functions
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
5627
diff
changeset
|
424 |
@xhtmlize |
6240 | 425 |
def js_render(self, registry, oid, eid=None, |
426 |
selectargs=None, renderargs=None): |
|
5658
7b9553a9db65
[ajax] refactor/cleanup low-level ajax functions
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
5627
diff
changeset
|
427 |
if eid is not None: |
7b9553a9db65
[ajax] refactor/cleanup low-level ajax functions
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
5627
diff
changeset
|
428 |
rset = self._cw.eid_rset(eid) |
6926 | 429 |
# XXX set row=0 |
6204
fd6d8f4d1904
[json controller] check rql is really specified
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6109
diff
changeset
|
430 |
elif self._cw.form.get('rql'): |
5658
7b9553a9db65
[ajax] refactor/cleanup low-level ajax functions
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
5627
diff
changeset
|
431 |
rset = self._cw.execute(self._cw.form['rql']) |
7b9553a9db65
[ajax] refactor/cleanup low-level ajax functions
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
5627
diff
changeset
|
432 |
else: |
7b9553a9db65
[ajax] refactor/cleanup low-level ajax functions
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
5627
diff
changeset
|
433 |
rset = None |
6240 | 434 |
view = self._cw.vreg[registry].select(oid, self._cw, rset=rset, |
435 |
**optional_kwargs(selectargs)) |
|
5658
7b9553a9db65
[ajax] refactor/cleanup low-level ajax functions
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
5627
diff
changeset
|
436 |
return self._call_view(view, **optional_kwargs(renderargs)) |
1419 | 437 |
|
438 |
@check_pageid |
|
439 |
@xhtmlize |
|
4629
1eeef3cbf528
fix 4626:c26b4df9fc90 (#703911): use can't rely on peid since it's not an actual eid when we're creating the parent entity
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4466
diff
changeset
|
440 |
def js_inline_creation_form(self, peid, petype, ttype, rtype, role, i18nctx): |
3451
6b46d73823f5
[api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3377
diff
changeset
|
441 |
view = self._cw.vreg['views'].select('inline-creation', self._cw, |
4629
1eeef3cbf528
fix 4626:c26b4df9fc90 (#703911): use can't rely on peid since it's not an actual eid when we're creating the parent entity
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4466
diff
changeset
|
442 |
etype=ttype, rtype=rtype, role=role, |
1eeef3cbf528
fix 4626:c26b4df9fc90 (#703911): use can't rely on peid since it's not an actual eid when we're creating the parent entity
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4466
diff
changeset
|
443 |
peid=peid, petype=petype) |
3518
11ce4682187d
[form] important refactoring of inlined forms to get proper separation of form object creation / rendering
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3514
diff
changeset
|
444 |
return self._call_view(view, i18nctx=i18nctx) |
1419 | 445 |
|
446 |
@jsonize |
|
0 | 447 |
def js_validate_form(self, action, names, values): |
1527
c8ca1782e252
controller fixes
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
1467
diff
changeset
|
448 |
return self.validate_form(action, names, values) |
c8ca1782e252
controller fixes
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
1467
diff
changeset
|
449 |
|
c8ca1782e252
controller fixes
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
1467
diff
changeset
|
450 |
def validate_form(self, action, names, values): |
3451
6b46d73823f5
[api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3377
diff
changeset
|
451 |
self._cw.form = self._rebuild_posted_form(names, values, action) |
6b46d73823f5
[api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3377
diff
changeset
|
452 |
return _validate_form(self._cw, self._cw.vreg) |
0 | 453 |
|
3742
20f429eb5f46
kill separate attribute client-side handling #473636
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
3608
diff
changeset
|
454 |
@xhtmlize |
20f429eb5f46
kill separate attribute client-side handling #473636
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
3608
diff
changeset
|
455 |
def js_reledit_form(self): |
4739
64806b0f7431
[reledit] add ajax html head div, which allows to get additional css/js up to the browser #620569
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
4721
diff
changeset
|
456 |
req = self._cw |
5658
7b9553a9db65
[ajax] refactor/cleanup low-level ajax functions
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
5627
diff
changeset
|
457 |
args = dict((x, req.form[x]) |
7076
0eed6045d785
[reledit] kill the reledit/doreledit duality
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
6926
diff
changeset
|
458 |
for x in ('formid', 'rtype', 'role', 'reload', 'action')) |
5869
8a129b3a5aff
reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5868
diff
changeset
|
459 |
rset = req.eid_rset(typed_eid(self._cw.form['eid'])) |
8a129b3a5aff
reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5868
diff
changeset
|
460 |
try: |
8a129b3a5aff
reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5868
diff
changeset
|
461 |
args['reload'] = json.loads(args['reload']) |
8a129b3a5aff
reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5868
diff
changeset
|
462 |
except ValueError: # not true/false, an absolute url |
8a129b3a5aff
reledit refactoring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
5868
diff
changeset
|
463 |
assert args['reload'].startswith('http') |
7076
0eed6045d785
[reledit] kill the reledit/doreledit duality
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
6926
diff
changeset
|
464 |
view = req.vreg['views'].select('reledit', req, rset=rset, rtype=args['rtype']) |
5454
76b828dc3b9f
[json-controller] - refactoring of js_component and js_view, it now uses _call_view
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents:
5453
diff
changeset
|
465 |
return self._call_view(view, **args) |
1759
61d026ced19f
preliminary support for inline edition of relations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
1736
diff
changeset
|
466 |
|
61d026ced19f
preliminary support for inline edition of relations
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
1736
diff
changeset
|
467 |
@jsonize |
0 | 468 |
def js_i18n(self, msgids): |
469 |
"""returns the translation of `msgid`""" |
|
3451
6b46d73823f5
[api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3377
diff
changeset
|
470 |
return [self._cw._(msgid) for msgid in msgids] |
0 | 471 |
|
1419 | 472 |
@jsonize |
0 | 473 |
def js_format_date(self, strdate): |
474 |
"""returns the formatted date for `msgid`""" |
|
1380 | 475 |
date = strptime(strdate, '%Y-%m-%d %H:%M:%S') |
3460
e4843535db25
[api] some more _cw / __regid__, automatic tests now pass again
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3451
diff
changeset
|
476 |
return self._cw.format_date(date) |
0 | 477 |
|
1419 | 478 |
@jsonize |
0 | 479 |
def js_external_resource(self, resource): |
480 |
"""returns the URL of the external resource named `resource`""" |
|
5467
57372dbfd114
[https] fix resource urls in https version of a site: should use the https version as well to avoid warnings from the nrowser
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5454
diff
changeset
|
481 |
return self._cw.uiprops[resource] |
0 | 482 |
|
483 |
@check_pageid |
|
1419 | 484 |
@jsonize |
0 | 485 |
def js_user_callback(self, cbname): |
5223
6abd6e3599f4
#773448: refactor session and 'no connection' handling, by introducing proper web session. We should now be able to see page even when no anon is configured, and be redirected to the login form as soon as one tries to do a query.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5201
diff
changeset
|
486 |
page_data = self._cw.session.data.get(self._cw.pageid, {}) |
0 | 487 |
try: |
488 |
cb = page_data[cbname] |
|
489 |
except KeyError: |
|
490 |
return None |
|
3451
6b46d73823f5
[api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3377
diff
changeset
|
491 |
return cb(self._cw) |
0 | 492 |
|
493 |
if HAS_SEARCH_RESTRICTION: |
|
1419 | 494 |
@jsonize |
0 | 495 |
def js_filter_build_rql(self, names, values): |
496 |
form = self._rebuild_posted_form(names, values) |
|
3451
6b46d73823f5
[api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3377
diff
changeset
|
497 |
self._cw.form = form |
6b46d73823f5
[api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3377
diff
changeset
|
498 |
builder = FilterRQLBuilder(self._cw) |
0 | 499 |
return builder.build_rql() |
500 |
||
1419 | 501 |
@jsonize |
0 | 502 |
def js_filter_select_content(self, facetids, rql): |
3451
6b46d73823f5
[api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3377
diff
changeset
|
503 |
rqlst = self._cw.vreg.parse(self._cw, rql) # XXX Union unsupported yet |
0 | 504 |
mainvar = prepare_facets_rqlst(rqlst)[0] |
505 |
update_map = {} |
|
506 |
for facetid in facetids: |
|
3451
6b46d73823f5
[api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3377
diff
changeset
|
507 |
facet = get_facet(self._cw, facetid, rqlst.children[0], mainvar) |
0 | 508 |
update_map[facetid] = facet.possible_values() |
509 |
return update_map |
|
510 |
||
1419 | 511 |
def js_unregister_user_callback(self, cbname): |
3451
6b46d73823f5
[api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3377
diff
changeset
|
512 |
self._cw.unregister_callback(self._cw.pageid, cbname) |
1419 | 513 |
|
514 |
def js_unload_page_data(self): |
|
5223
6abd6e3599f4
#773448: refactor session and 'no connection' handling, by introducing proper web session. We should now be able to see page even when no anon is configured, and be redirected to the login form as soon as one tries to do a query.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5201
diff
changeset
|
515 |
self._cw.session.data.pop(self._cw.pageid, None) |
1419 | 516 |
|
517 |
def js_cancel_edition(self, errorurl): |
|
518 |
"""cancelling edition from javascript |
|
519 |
||
520 |
We need to clear associated req's data : |
|
521 |
- errorurl |
|
522 |
- pending insertions / deletions |
|
523 |
""" |
|
3451
6b46d73823f5
[api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3377
diff
changeset
|
524 |
self._cw.cancel_edition(errorurl) |
1419 | 525 |
|
0 | 526 |
def js_delete_bookmark(self, beid): |
1419 | 527 |
rql = 'DELETE B bookmarked_by U WHERE B eid %(b)s, U eid %(u)s' |
3451
6b46d73823f5
[api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3377
diff
changeset
|
528 |
self._cw.execute(rql, {'b': typed_eid(beid), 'u' : self._cw.user.eid}) |
1419 | 529 |
|
1844
ec51bf1b8be3
avoid monkeypatching JsonController in cw, to avoid _potential_ load order problems
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
1839
diff
changeset
|
530 |
def js_node_clicked(self, treeid, nodeeid): |
ec51bf1b8be3
avoid monkeypatching JsonController in cw, to avoid _potential_ load order problems
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
1839
diff
changeset
|
531 |
"""add/remove eid in treestate cookie""" |
ec51bf1b8be3
avoid monkeypatching JsonController in cw, to avoid _potential_ load order problems
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
1839
diff
changeset
|
532 |
from cubicweb.web.views.treeview import treecookiename |
3451
6b46d73823f5
[api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3377
diff
changeset
|
533 |
cookies = self._cw.get_cookie() |
1844
ec51bf1b8be3
avoid monkeypatching JsonController in cw, to avoid _potential_ load order problems
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
1839
diff
changeset
|
534 |
statename = treecookiename(treeid) |
ec51bf1b8be3
avoid monkeypatching JsonController in cw, to avoid _potential_ load order problems
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
1839
diff
changeset
|
535 |
treestate = cookies.get(statename) |
ec51bf1b8be3
avoid monkeypatching JsonController in cw, to avoid _potential_ load order problems
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
1839
diff
changeset
|
536 |
if treestate is None: |
ec51bf1b8be3
avoid monkeypatching JsonController in cw, to avoid _potential_ load order problems
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
1839
diff
changeset
|
537 |
cookies[statename] = nodeeid |
3451
6b46d73823f5
[api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3377
diff
changeset
|
538 |
self._cw.set_cookie(cookies, statename) |
1844
ec51bf1b8be3
avoid monkeypatching JsonController in cw, to avoid _potential_ load order problems
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
1839
diff
changeset
|
539 |
else: |
5758
37968502da70
imported patch cookie handling: do not use semicolon as it has some tech meaning (web2 -> web)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5626
diff
changeset
|
540 |
marked = set(filter(None, treestate.value.split(':'))) |
1844
ec51bf1b8be3
avoid monkeypatching JsonController in cw, to avoid _potential_ load order problems
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
1839
diff
changeset
|
541 |
if nodeeid in marked: |
ec51bf1b8be3
avoid monkeypatching JsonController in cw, to avoid _potential_ load order problems
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
1839
diff
changeset
|
542 |
marked.remove(nodeeid) |
ec51bf1b8be3
avoid monkeypatching JsonController in cw, to avoid _potential_ load order problems
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
1839
diff
changeset
|
543 |
else: |
ec51bf1b8be3
avoid monkeypatching JsonController in cw, to avoid _potential_ load order problems
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
1839
diff
changeset
|
544 |
marked.add(nodeeid) |
5758
37968502da70
imported patch cookie handling: do not use semicolon as it has some tech meaning (web2 -> web)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5626
diff
changeset
|
545 |
cookies[statename] = ':'.join(marked) |
3451
6b46d73823f5
[api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3377
diff
changeset
|
546 |
self._cw.set_cookie(cookies, statename) |
1844
ec51bf1b8be3
avoid monkeypatching JsonController in cw, to avoid _potential_ load order problems
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
1839
diff
changeset
|
547 |
|
4420
a9a8628a1a87
missing jsonize, avoid spurious error w/ ff
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4212
diff
changeset
|
548 |
@jsonize |
1419 | 549 |
def js_set_cookie(self, cookiename, cookievalue): |
550 |
# XXX we should consider jQuery.Cookie |
|
551 |
cookiename, cookievalue = str(cookiename), str(cookievalue) |
|
3451
6b46d73823f5
[api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3377
diff
changeset
|
552 |
cookies = self._cw.get_cookie() |
1419 | 553 |
cookies[cookiename] = cookievalue |
3451
6b46d73823f5
[api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3377
diff
changeset
|
554 |
self._cw.set_cookie(cookies, cookiename) |
1419 | 555 |
|
556 |
# relations edition stuff ################################################## |
|
0 | 557 |
|
558 |
def _add_pending(self, eidfrom, rel, eidto, kind): |
|
559 |
key = 'pending_%s' % kind |
|
5223
6abd6e3599f4
#773448: refactor session and 'no connection' handling, by introducing proper web session. We should now be able to see page even when no anon is configured, and be redirected to the login form as soon as one tries to do a query.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5201
diff
changeset
|
560 |
pendings = self._cw.session.data.setdefault(key, set()) |
0 | 561 |
pendings.add( (typed_eid(eidfrom), rel, typed_eid(eidto)) ) |
562 |
||
563 |
def _remove_pending(self, eidfrom, rel, eidto, kind): |
|
1419 | 564 |
key = 'pending_%s' % kind |
5223
6abd6e3599f4
#773448: refactor session and 'no connection' handling, by introducing proper web session. We should now be able to see page even when no anon is configured, and be redirected to the login form as soon as one tries to do a query.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5201
diff
changeset
|
565 |
pendings = self._cw.session.data[key] |
1713
d817f23439ba
bix a bug: correct the sended parameter 'no need for id in the string parameter name'
Graziella Toutoungis <graziella.toutoungis@logilab.fr>
parents:
1635
diff
changeset
|
566 |
pendings.remove( (typed_eid(eidfrom), rel, typed_eid(eidto)) ) |
0 | 567 |
|
1419 | 568 |
def js_remove_pending_insert(self, (eidfrom, rel, eidto)): |
569 |
self._remove_pending(eidfrom, rel, eidto, 'insert') |
|
570 |
||
571 |
def js_add_pending_inserts(self, tripletlist): |
|
572 |
for eidfrom, rel, eidto in tripletlist: |
|
573 |
self._add_pending(eidfrom, rel, eidto, 'insert') |
|
574 |
||
575 |
def js_remove_pending_delete(self, (eidfrom, rel, eidto)): |
|
576 |
self._remove_pending(eidfrom, rel, eidto, 'delete') |
|
577 |
||
578 |
def js_add_pending_delete(self, (eidfrom, rel, eidto)): |
|
579 |
self._add_pending(eidfrom, rel, eidto, 'delete') |
|
580 |
||
603
18c6c31bbaf4
[controllers] a set_cookie method
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
581
diff
changeset
|
581 |
|
5366
5f116a4d8a54
[masmailing] cleanup: use authenticated_user selectors, define stuff on form instead of on selection when possible, other cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5200
diff
changeset
|
582 |
# XXX move to massmailing |
0 | 583 |
|
5556
9ab2b4c74baf
[entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5555
diff
changeset
|
584 |
class MailBugReportController(Controller): |
3377
dd9d292b6a6d
use __regid__ instead of id on appobject classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
3369
diff
changeset
|
585 |
__regid__ = 'reportbug' |
4894
41c28ddca055
[cleanup selectors] use authenticated_user, check for form params instead of handling potential key error on missing params
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
4741
diff
changeset
|
586 |
__select__ = match_form_params('description') |
0 | 587 |
|
588 |
def publish(self, rset=None): |
|
3451
6b46d73823f5
[api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3377
diff
changeset
|
589 |
body = self._cw.form['description'] |
6582
8eb7883b4223
[pylint] fix a bug of pylint detected errors and i18n pb (calling builtins._ instead of req._)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6545
diff
changeset
|
590 |
self.sendmail(self._cw.config['submit-mail'], |
8eb7883b4223
[pylint] fix a bug of pylint detected errors and i18n pb (calling builtins._ instead of req._)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6545
diff
changeset
|
591 |
self._cw._('%s error report') % self._cw.config.appid, |
8eb7883b4223
[pylint] fix a bug of pylint detected errors and i18n pb (calling builtins._ instead of req._)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6545
diff
changeset
|
592 |
body) |
3460
e4843535db25
[api] some more _cw / __regid__, automatic tests now pass again
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
3451
diff
changeset
|
593 |
url = self._cw.build_url(__message=self._cw._('bug report sent')) |
0 | 594 |
raise Redirect(url) |
1419 | 595 |
|
4913
083b4d454192
server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents:
4894
diff
changeset
|
596 |
|
5556
9ab2b4c74baf
[entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5555
diff
changeset
|
597 |
class UndoController(Controller): |
4913
083b4d454192
server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents:
4894
diff
changeset
|
598 |
__regid__ = 'undo' |
083b4d454192
server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents:
4894
diff
changeset
|
599 |
__select__ = authenticated_user() & match_form_params('txuuid') |
083b4d454192
server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents:
4894
diff
changeset
|
600 |
|
083b4d454192
server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents:
4894
diff
changeset
|
601 |
def publish(self, rset=None): |
083b4d454192
server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents:
4894
diff
changeset
|
602 |
txuuid = self._cw.form['txuuid'] |
083b4d454192
server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents:
4894
diff
changeset
|
603 |
errors = self._cw.cnx.undo_transaction(txuuid) |
6582
8eb7883b4223
[pylint] fix a bug of pylint detected errors and i18n pb (calling builtins._ instead of req._)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
6545
diff
changeset
|
604 |
if not errors: |
4913
083b4d454192
server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents:
4894
diff
changeset
|
605 |
self.redirect() |
7557
a397305f3976
[controller] UndoController: fix output method (closes: #1776091)
Julien Jehannet <julien.jehannet@logilab.fr>
parents:
7528
diff
changeset
|
606 |
raise ValidationError(None, {None: '\n'.join(errors)}) |
4913
083b4d454192
server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents:
4894
diff
changeset
|
607 |
|
7557
a397305f3976
[controller] UndoController: fix output method (closes: #1776091)
Julien Jehannet <julien.jehannet@logilab.fr>
parents:
7528
diff
changeset
|
608 |
def redirect(self, msg=None): |
4913
083b4d454192
server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents:
4894
diff
changeset
|
609 |
req = self._cw |
7557
a397305f3976
[controller] UndoController: fix output method (closes: #1776091)
Julien Jehannet <julien.jehannet@logilab.fr>
parents:
7528
diff
changeset
|
610 |
msg = msg or req._("transaction undone") |
5223
6abd6e3599f4
#773448: refactor session and 'no connection' handling, by introducing proper web session. We should now be able to see page even when no anon is configured, and be redirected to the login form as soon as one tries to do a query.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
5201
diff
changeset
|
611 |
breadcrumbs = req.session.data.get('breadcrumbs', None) |
4913
083b4d454192
server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents:
4894
diff
changeset
|
612 |
if breadcrumbs is not None and len(breadcrumbs) > 1: |
7557
a397305f3976
[controller] UndoController: fix output method (closes: #1776091)
Julien Jehannet <julien.jehannet@logilab.fr>
parents:
7528
diff
changeset
|
613 |
url = req.rebuild_url(breadcrumbs[-2], __message=msg) |
4913
083b4d454192
server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents:
4894
diff
changeset
|
614 |
else: |
7557
a397305f3976
[controller] UndoController: fix output method (closes: #1776091)
Julien Jehannet <julien.jehannet@logilab.fr>
parents:
7528
diff
changeset
|
615 |
url = req.build_url(__message=msg) |
4913
083b4d454192
server/web api for accessing to deleted_entites
Katia Saurfelt <katia.saurfelt@logilab.fr>
parents:
4894
diff
changeset
|
616 |
raise Redirect(url) |