8 :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr |
8 :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr |
9 :license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses |
9 :license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses |
10 """ |
10 """ |
11 __docformat__ = "restructuredtext en" |
11 __docformat__ = "restructuredtext en" |
12 |
12 |
13 from smtplib import SMTP |
|
14 |
|
15 import simplejson |
13 import simplejson |
16 |
14 |
17 from logilab.common.decorators import cached |
15 from logilab.common.decorators import cached |
18 from logilab.common.date import strptime |
16 from logilab.common.date import strptime |
19 |
17 |
20 from cubicweb import (NoSelectableObject, ValidationError, ObjectNotFound, |
18 from cubicweb import (NoSelectableObject, ObjectNotFound, ValidationError, |
21 typed_eid) |
19 AuthenticationError, typed_eid) |
22 from cubicweb.utils import CubicWebJsonEncoder |
20 from cubicweb.utils import CubicWebJsonEncoder |
23 from cubicweb.selectors import authenticated_user, match_form_params |
21 from cubicweb.selectors import authenticated_user, match_form_params |
24 from cubicweb.mail import format_mail |
22 from cubicweb.mail import format_mail |
25 from cubicweb.web import ExplicitLogin, Redirect, RemoteCallFailed, DirectResponse, json_dumps |
23 from cubicweb.web import Redirect, RemoteCallFailed, DirectResponse, json_dumps |
26 from cubicweb.web.controller import Controller |
24 from cubicweb.web.controller import Controller |
27 from cubicweb.web.views import vid_from_rset |
25 from cubicweb.web.views import vid_from_rset, formrenderers |
28 from cubicweb.web.views.formrenderers import FormRenderer |
|
29 |
26 |
30 try: |
27 try: |
31 from cubicweb.web.facet import (FilterRQLBuilder, get_facet, |
28 from cubicweb.web.facet import (FilterRQLBuilder, get_facet, |
32 prepare_facets_rqlst) |
29 prepare_facets_rqlst) |
33 HAS_SEARCH_RESTRICTION = True |
30 HAS_SEARCH_RESTRICTION = True |
57 def check_pageid(func): |
54 def check_pageid(func): |
58 """decorator which checks the given pageid is found in the |
55 """decorator which checks the given pageid is found in the |
59 user's session data |
56 user's session data |
60 """ |
57 """ |
61 def wrapper(self, *args, **kwargs): |
58 def wrapper(self, *args, **kwargs): |
62 data = self._cw.get_session_data(self._cw.pageid) |
59 data = self._cw.session.data.get(self._cw.pageid) |
63 if data is None: |
60 if data is None: |
64 raise RemoteCallFailed(self._cw._('pageid-not-found')) |
61 raise RemoteCallFailed(self._cw._('pageid-not-found')) |
65 return func(self, *args, **kwargs) |
62 return func(self, *args, **kwargs) |
66 return wrapper |
63 return wrapper |
67 |
64 |
71 |
68 |
72 def publish(self, rset=None): |
69 def publish(self, rset=None): |
73 """log in the instance""" |
70 """log in the instance""" |
74 if self._cw.vreg.config['auth-mode'] == 'http': |
71 if self._cw.vreg.config['auth-mode'] == 'http': |
75 # HTTP authentication |
72 # HTTP authentication |
76 raise ExplicitLogin() |
73 raise AuthenticationError() |
77 else: |
74 else: |
78 # Cookie authentication |
75 # Cookie authentication |
79 return self.appli.need_login_content(self._cw) |
76 return self.appli.need_login_content(self._cw) |
80 |
77 |
81 |
78 |
117 |
114 |
118 def _select_view_and_rset(self, rset): |
115 def _select_view_and_rset(self, rset): |
119 req = self._cw |
116 req = self._cw |
120 if rset is None and not hasattr(req, '_rql_processed'): |
117 if rset is None and not hasattr(req, '_rql_processed'): |
121 req._rql_processed = True |
118 req._rql_processed = True |
122 rset = self.process_rql(req.form.get('rql')) |
119 if req.cnx is None: |
|
120 rset = None |
|
121 else: |
|
122 rset = self.process_rql(req.form.get('rql')) |
123 if rset and rset.rowcount == 1 and '__method' in req.form: |
123 if rset and rset.rowcount == 1 and '__method' in req.form: |
124 entity = rset.get_entity(0, 0) |
124 entity = rset.get_entity(0, 0) |
125 try: |
125 try: |
126 method = getattr(entity, req.form.pop('__method')) |
126 method = getattr(entity, req.form.pop('__method')) |
127 method() |
127 method() |
185 |
185 |
186 def _validation_error(req, ex): |
186 def _validation_error(req, ex): |
187 req.cnx.rollback() |
187 req.cnx.rollback() |
188 # XXX necessary to remove existant validation error? |
188 # XXX necessary to remove existant validation error? |
189 # imo (syt), it's not necessary |
189 # imo (syt), it's not necessary |
190 req.get_session_data(req.form.get('__errorurl'), pop=True) |
190 req.session.data.pop(req.form.get('__errorurl'), None) |
191 foreid = ex.entity |
191 foreid = ex.entity |
192 eidmap = req.data.get('eidmap', {}) |
192 eidmap = req.data.get('eidmap', {}) |
193 for var, eid in eidmap.items(): |
193 for var, eid in eidmap.items(): |
194 if foreid == eid: |
194 if foreid == eid: |
195 foreid = var |
195 foreid = var |
378 entity.eid = varname |
378 entity.eid = varname |
379 entity['pkey'] = propkey |
379 entity['pkey'] = propkey |
380 form = self._cw.vreg['forms'].select('edition', self._cw, entity=entity) |
380 form = self._cw.vreg['forms'].select('edition', self._cw, entity=entity) |
381 form.build_context() |
381 form.build_context() |
382 vfield = form.field_by_name('value') |
382 vfield = form.field_by_name('value') |
383 renderer = FormRenderer(self._cw) |
383 renderer = formrenderers.FormRenderer(self._cw) |
384 return vfield.render(form, renderer, tabindex=tabindex) \ |
384 return vfield.render(form, renderer, tabindex=tabindex) \ |
385 + renderer.render_help(form, vfield) |
385 + renderer.render_help(form, vfield) |
386 |
386 |
387 @xhtmlize |
387 @xhtmlize |
388 def js_component(self, compid, rql, registry='components', extraargs=None): |
388 def js_component(self, compid, rql, registry='components', extraargs=None): |
472 return self._cw.external_resource(resource) |
472 return self._cw.external_resource(resource) |
473 |
473 |
474 @check_pageid |
474 @check_pageid |
475 @jsonize |
475 @jsonize |
476 def js_user_callback(self, cbname): |
476 def js_user_callback(self, cbname): |
477 page_data = self._cw.get_session_data(self._cw.pageid, {}) |
477 page_data = self._cw.session.data.get(self._cw.pageid, {}) |
478 try: |
478 try: |
479 cb = page_data[cbname] |
479 cb = page_data[cbname] |
480 except KeyError: |
480 except KeyError: |
481 return None |
481 return None |
482 return cb(self._cw) |
482 return cb(self._cw) |
501 |
501 |
502 def js_unregister_user_callback(self, cbname): |
502 def js_unregister_user_callback(self, cbname): |
503 self._cw.unregister_callback(self._cw.pageid, cbname) |
503 self._cw.unregister_callback(self._cw.pageid, cbname) |
504 |
504 |
505 def js_unload_page_data(self): |
505 def js_unload_page_data(self): |
506 self._cw.del_session_data(self._cw.pageid) |
506 self._cw.session.data.pop(self._cw.pageid, None) |
507 |
507 |
508 def js_cancel_edition(self, errorurl): |
508 def js_cancel_edition(self, errorurl): |
509 """cancelling edition from javascript |
509 """cancelling edition from javascript |
510 |
510 |
511 We need to clear associated req's data : |
511 We need to clear associated req's data : |
546 |
546 |
547 # relations edition stuff ################################################## |
547 # relations edition stuff ################################################## |
548 |
548 |
549 def _add_pending(self, eidfrom, rel, eidto, kind): |
549 def _add_pending(self, eidfrom, rel, eidto, kind): |
550 key = 'pending_%s' % kind |
550 key = 'pending_%s' % kind |
551 pendings = self._cw.get_session_data(key, set()) |
551 pendings = self._cw.session.data.setdefault(key, set()) |
552 pendings.add( (typed_eid(eidfrom), rel, typed_eid(eidto)) ) |
552 pendings.add( (typed_eid(eidfrom), rel, typed_eid(eidto)) ) |
553 self._cw.set_session_data(key, pendings) |
|
554 |
553 |
555 def _remove_pending(self, eidfrom, rel, eidto, kind): |
554 def _remove_pending(self, eidfrom, rel, eidto, kind): |
556 key = 'pending_%s' % kind |
555 key = 'pending_%s' % kind |
557 pendings = self._cw.get_session_data(key) |
556 pendings = self._cw.session.data[key] |
558 pendings.remove( (typed_eid(eidfrom), rel, typed_eid(eidto)) ) |
557 pendings.remove( (typed_eid(eidfrom), rel, typed_eid(eidto)) ) |
559 self._cw.set_session_data(key, pendings) |
|
560 |
558 |
561 def js_remove_pending_insert(self, (eidfrom, rel, eidto)): |
559 def js_remove_pending_insert(self, (eidfrom, rel, eidto)): |
562 self._remove_pending(eidfrom, rel, eidto, 'insert') |
560 self._remove_pending(eidfrom, rel, eidto, 'insert') |
563 |
561 |
564 def js_add_pending_inserts(self, tripletlist): |
562 def js_add_pending_inserts(self, tripletlist): |
611 body = self._cw.form['mailbody'] |
609 body = self._cw.form['mailbody'] |
612 subject = self._cw.form['subject'] |
610 subject = self._cw.form['subject'] |
613 for recipient in self.recipients(): |
611 for recipient in self.recipients(): |
614 text = body % recipient.as_email_context() |
612 text = body % recipient.as_email_context() |
615 self.sendmail(recipient.get_email(), subject, text) |
613 self.sendmail(recipient.get_email(), subject, text) |
616 # breadcrumbs = self._cw.get_session_data('breadcrumbs', None) |
614 #breadcrumbs = self._cw.session.data.get('breadcrumbs', None) |
617 url = self._cw.build_url(__message=self._cw._('emails successfully sent')) |
615 url = self._cw.build_url(__message=self._cw._('emails successfully sent')) |
618 raise Redirect(url) |
616 raise Redirect(url) |
619 |
617 |
620 |
618 |
621 class MailBugReportController(SendMailController): |
619 class MailBugReportController(SendMailController): |
642 else: |
640 else: |
643 self.redirect() |
641 self.redirect() |
644 |
642 |
645 def redirect(self): |
643 def redirect(self): |
646 req = self._cw |
644 req = self._cw |
647 breadcrumbs = req.get_session_data('breadcrumbs', None) |
645 breadcrumbs = req.session.data.get('breadcrumbs', None) |
648 if breadcrumbs is not None and len(breadcrumbs) > 1: |
646 if breadcrumbs is not None and len(breadcrumbs) > 1: |
649 url = req.rebuild_url(breadcrumbs[-2], |
647 url = req.rebuild_url(breadcrumbs[-2], |
650 __message=req._('transaction undoed')) |
648 __message=req._('transaction undoed')) |
651 else: |
649 else: |
652 url = req.build_url(__message=req._('transaction undoed')) |
650 url = req.build_url(__message=req._('transaction undoed')) |