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 import simplejson |
13 try: |
|
14 import json |
|
15 except ImportError: |
|
16 import simplejson as json |
14 |
17 |
15 from logilab.common.decorators import cached |
18 from logilab.common.decorators import cached |
16 from logilab.common.date import strptime |
19 from logilab.common.date import strptime |
17 |
20 |
18 from cubicweb import (NoSelectableObject, ObjectNotFound, ValidationError, |
21 from cubicweb import (NoSelectableObject, ObjectNotFound, ValidationError, |
30 HAS_SEARCH_RESTRICTION = True |
33 HAS_SEARCH_RESTRICTION = True |
31 except ImportError: # gae |
34 except ImportError: # gae |
32 HAS_SEARCH_RESTRICTION = False |
35 HAS_SEARCH_RESTRICTION = False |
33 |
36 |
34 def jsonize(func): |
37 def jsonize(func): |
35 """decorator to sets correct content_type and calls `simplejson.dumps` on |
38 """decorator to sets correct content_type and calls `json.dumps` on |
36 results |
39 results |
37 """ |
40 """ |
38 def wrapper(self, *args, **kwargs): |
41 def wrapper(self, *args, **kwargs): |
39 self._cw.set_content_type('application/json') |
42 self._cw.set_content_type('application/json') |
40 return json_dumps(func(self, *args, **kwargs)) |
43 return json_dumps(func(self, *args, **kwargs)) |
235 def response(self, domid, status, args, entity): |
238 def response(self, domid, status, args, entity): |
236 callback = str(self._cw.form.get('__onsuccess', 'null')) |
239 callback = str(self._cw.form.get('__onsuccess', 'null')) |
237 errback = str(self._cw.form.get('__onfailure', 'null')) |
240 errback = str(self._cw.form.get('__onfailure', 'null')) |
238 cbargs = str(self._cw.form.get('__cbargs', 'null')) |
241 cbargs = str(self._cw.form.get('__cbargs', 'null')) |
239 self._cw.set_content_type('text/html') |
242 self._cw.set_content_type('text/html') |
240 jsargs = simplejson.dumps((status, args, entity), cls=CubicWebJsonEncoder) |
243 jsargs = json.dumps((status, args, entity), cls=CubicWebJsonEncoder) |
241 return """<script type="text/javascript"> |
244 return """<script type="text/javascript"> |
242 window.parent.handleFormValidationResponse('%s', %s, %s, %s, %s); |
245 window.parent.handleFormValidationResponse('%s', %s, %s, %s, %s); |
243 </script>""" % (domid, callback, errback, jsargs, cbargs) |
246 </script>""" % (domid, callback, errback, jsargs, cbargs) |
244 |
247 |
245 def publish(self, rset=None): |
248 def publish(self, rset=None): |
275 # no <arg> attribute means the callback takes no argument |
278 # no <arg> attribute means the callback takes no argument |
276 args = self._cw.form.get('arg', ()) |
279 args = self._cw.form.get('arg', ()) |
277 if not isinstance(args, (list, tuple)): |
280 if not isinstance(args, (list, tuple)): |
278 args = (args,) |
281 args = (args,) |
279 try: |
282 try: |
280 args = [simplejson.loads(arg) for arg in args] |
283 args = [json.loads(arg) for arg in args] |
281 except ValueError, exc: |
284 except ValueError, exc: |
282 self.exception('error while decoding json arguments for js_%s: %s', fname, args, exc) |
285 self.exception('error while decoding json arguments for js_%s: %s', fname, args, exc) |
283 raise RemoteCallFailed(repr(exc)) |
286 raise RemoteCallFailed(repr(exc)) |
284 try: |
287 try: |
285 result = func(*args) |
288 result = func(*args) |
439 args = dict((x, self._cw.form[x]) |
442 args = dict((x, self._cw.form[x]) |
440 for x in frozenset(('rtype', 'role', 'reload', 'landing_zone'))) |
443 for x in frozenset(('rtype', 'role', 'reload', 'landing_zone'))) |
441 entity = self._cw.entity_from_eid(int(self._cw.form['eid'])) |
444 entity = self._cw.entity_from_eid(int(self._cw.form['eid'])) |
442 # note: default is reserved in js land |
445 # note: default is reserved in js land |
443 args['default'] = self._cw.form['default_value'] |
446 args['default'] = self._cw.form['default_value'] |
444 args['reload'] = simplejson.loads(args['reload']) |
447 args['reload'] = json.loads(args['reload']) |
445 rset = req.eid_rset(int(self._cw.form['eid'])) |
448 rset = req.eid_rset(int(self._cw.form['eid'])) |
446 view = req.vreg['views'].select('doreledit', req, rset=rset, rtype=args['rtype']) |
449 view = req.vreg['views'].select('doreledit', req, rset=rset, rtype=args['rtype']) |
447 stream = view.set_stream() |
450 stream = view.set_stream() |
448 view.render(**args) |
451 view.render(**args) |
449 # XXX why not _call_view ? |
452 # XXX why not _call_view ? |
575 eid_from = self._cw.execute('INSERT %s T : T name "%s"' % ( etype_from, value_from ))[0][0] |
578 eid_from = self._cw.execute('INSERT %s T : T name "%s"' % ( etype_from, value_from ))[0][0] |
576 # link the new entity to the main entity |
579 # link the new entity to the main entity |
577 rql = 'SET F %(rel)s T WHERE F eid %(eid_to)s, T eid %(eid_from)s' % {'rel' : rel, 'eid_to' : eid_to, 'eid_from' : eid_from} |
580 rql = 'SET F %(rel)s T WHERE F eid %(eid_to)s, T eid %(eid_from)s' % {'rel' : rel, 'eid_to' : eid_to, 'eid_from' : eid_from} |
578 return eid_from |
581 return eid_from |
579 |
582 |
580 |
583 # XXX move to massmailing |
581 class SendMailController(Controller): |
584 class SendMailController(Controller): |
582 __regid__ = 'sendmail' |
585 __regid__ = 'sendmail' |
583 __select__ = authenticated_user() & match_form_params('recipient', 'mailbody', 'subject') |
586 __select__ = authenticated_user() & match_form_params('recipient', 'mailbody', 'subject') |
584 |
587 |
585 def recipients(self): |
588 def recipients(self): |
586 """returns an iterator on email's recipients as entities""" |
589 """returns an iterator on email's recipients as entities""" |
587 eids = self._cw.form['recipient'] |
590 eids = self._cw.form['recipient'] |
588 # make sure we have a list even though only one recipient was specified |
591 # eids may be a string if only one recipient was specified |
589 if isinstance(eids, basestring): |
592 if isinstance(eids, basestring): |
590 eids = (eids,) |
593 rset = self._cw.execute('Any X WHERE X eid %(x)s', {'x': eids}) |
591 rql = 'Any X WHERE X eid in (%s)' % (','.join(eids)) |
594 else: |
592 rset = self._cw.execute(rql) |
595 rset = self._cw.execute('Any X WHERE X eid in (%s)' % (','.join(eids))) |
593 for entity in rset.entities(): |
596 return rset.entities() |
594 yield entity |
|
595 |
597 |
596 def sendmail(self, recipient, subject, body): |
598 def sendmail(self, recipient, subject, body): |
597 msg = format_mail({'email' : self._cw.user.get_email(), |
599 msg = format_mail({'email' : self._cw.user.get_email(), |
598 'name' : self._cw.user.dc_title(),}, |
600 'name' : self._cw.user.dc_title(),}, |
599 [recipient], body, subject) |
601 [recipient], body, subject) |
608 body = self._cw.form['mailbody'] |
610 body = self._cw.form['mailbody'] |
609 subject = self._cw.form['subject'] |
611 subject = self._cw.form['subject'] |
610 for recipient in self.recipients(): |
612 for recipient in self.recipients(): |
611 text = body % recipient.as_email_context() |
613 text = body % recipient.as_email_context() |
612 self.sendmail(recipient.get_email(), subject, text) |
614 self.sendmail(recipient.get_email(), subject, text) |
613 #breadcrumbs = self._cw.session.data.get('breadcrumbs', None) |
|
614 url = self._cw.build_url(__message=self._cw._('emails successfully sent')) |
615 url = self._cw.build_url(__message=self._cw._('emails successfully sent')) |
615 raise Redirect(url) |
616 raise Redirect(url) |
616 |
617 |
617 |
618 |
618 class MailBugReportController(SendMailController): |
619 class MailBugReportController(SendMailController): |