comparison src/plugins/plugin_misc_invitations.py @ 2291:c05000d00dbb

plugin events, invitations + jp (event/create, invitation/invitee/invite): several emails addresses can now be specified for a single invitation: if several addresses are specified, the same invitation (same ID and data) is sent to all the addresses
author Goffi <goffi@goffi.org>
date Fri, 30 Jun 2017 00:04:47 +0200
parents 61e836cc9512
children 310a454c8657
comparison
equal deleted inserted replaced
2290:d5c75be1c8c0 2291:c05000d00dbb
22 from sat.core import exceptions 22 from sat.core import exceptions
23 from sat.core.log import getLogger 23 from sat.core.log import getLogger
24 log = getLogger(__name__) 24 log = getLogger(__name__)
25 import shortuuid 25 import shortuuid
26 from sat.tools import utils 26 from sat.tools import utils
27 from sat.tools.common import data_format
27 from twisted.internet import defer 28 from twisted.internet import defer
28 from twisted.words.protocols.jabber import jid 29 from twisted.words.protocols.jabber import jid
29 from twisted.words.protocols.jabber import error 30 from twisted.words.protocols.jabber import error
30 from sat.memory import persistent 31 from sat.memory import persistent
31 from sat.tools import email as sat_email 32 from sat.tools import email as sat_email
49 KEY_JID = u'jid' 50 KEY_JID = u'jid'
50 KEY_CREATED = u'created' 51 KEY_CREATED = u'created'
51 KEY_LAST_CONNECTION = u'last_connection' 52 KEY_LAST_CONNECTION = u'last_connection'
52 KEY_GUEST_PROFILE = u'guest_profile' 53 KEY_GUEST_PROFILE = u'guest_profile'
53 KEY_PASSWORD = u'password' 54 KEY_PASSWORD = u'password'
54 EXTRA_RESERVED = {KEY_ID, KEY_JID, KEY_CREATED, u'jid_', u'jid', KEY_LAST_CONNECTION, KEY_GUEST_PROFILE, KEY_PASSWORD} 55 KEY_EMAILS_EXTRA = u'emails_extra'
56 EXTRA_RESERVED = {KEY_ID, KEY_JID, KEY_CREATED, u'jid_', u'jid', KEY_LAST_CONNECTION, KEY_GUEST_PROFILE, KEY_PASSWORD, KEY_EMAILS_EXTRA}
55 DEFAULT_SUBJECT = D_(u"You have been invited by {host_name} to {app_name}") 57 DEFAULT_SUBJECT = D_(u"You have been invited by {host_name} to {app_name}")
56 DEFAULT_BODY = D_(u"""Hello {name}! 58 DEFAULT_BODY = D_(u"""Hello {name}!
57 59
58 You have received an invitation from {host_name} to participate to "{app_name}". 60 You have received an invitation from {host_name} to participate to "{app_name}".
59 To join, you just have to click on the following URL: 61 To join, you just have to click on the following URL:
70 72
71 def __init__(self, host): 73 def __init__(self, host):
72 log.info(_(u"plugin Invitations initialization")) 74 log.info(_(u"plugin Invitations initialization"))
73 self.host = host 75 self.host = host
74 self.invitations = persistent.LazyPersistentBinaryDict(u'invitations') 76 self.invitations = persistent.LazyPersistentBinaryDict(u'invitations')
75 host.bridge.addMethod("invitationCreate", ".plugin", in_sign='sssssssssa{ss}s', out_sign='a{ss}', 77 host.bridge.addMethod("invitationCreate", ".plugin", in_sign='sasssssssssa{ss}s', out_sign='a{ss}',
76 method=self._create, 78 method=self._create,
77 async=True) 79 async=True)
78 host.bridge.addMethod("invitationGet", ".plugin", in_sign='s', out_sign='a{ss}', 80 host.bridge.addMethod("invitationGet", ".plugin", in_sign='s', out_sign='a{ss}',
79 method=self.get, 81 method=self.get,
80 async=True) 82 async=True)
88 def checkExtra(self, extra): 90 def checkExtra(self, extra):
89 if EXTRA_RESERVED.intersection(extra): 91 if EXTRA_RESERVED.intersection(extra):
90 raise ValueError(_(u"You can't use following key(s) in extra, they are reserved: {}").format( 92 raise ValueError(_(u"You can't use following key(s) in extra, they are reserved: {}").format(
91 u', '.join(EXTRA_RESERVED.intersection(extra)))) 93 u', '.join(EXTRA_RESERVED.intersection(extra))))
92 94
93 def _create(self, jid_=u'', password=u'', name=u'', host_name=u'', email=u'', language=u'', url_template=u'', message_subject=u'', message_body=u'', extra=None, profile=u''): 95 def _create(self, email=u'', emails_extra=None, jid_=u'', password=u'', name=u'', host_name=u'', language=u'', url_template=u'', message_subject=u'', message_body=u'', extra=None, profile=u''):
94 # XXX: we don't use **kwargs here to keep arguments name for introspection with D-Bus bridge 96 # XXX: we don't use **kwargs here to keep arguments name for introspection with D-Bus bridge
97 if emails_extra is None:
98 emails_extra = []
95 99
96 if extra is None: 100 if extra is None:
97 extra = {} 101 extra = {}
98 else: 102 else:
99 extra = {unicode(k): unicode(v) for k,v in extra.iteritems()} 103 extra = {unicode(k): unicode(v) for k,v in extra.iteritems()}
100 104
105 kwargs = {"extra": extra,
106 KEY_EMAILS_EXTRA: [unicode(e) for e in emails_extra]
107 }
108
101 # we need to be sure that values are unicode, else they won't be pickled correctly with D-Bus 109 # we need to be sure that values are unicode, else they won't be pickled correctly with D-Bus
102 kwargs = {"extra": extra}
103 for key in ("jid_", "password", "name", "host_name", "email", "language", "url_template", "message_subject", "message_body", "profile"): 110 for key in ("jid_", "password", "name", "host_name", "email", "language", "url_template", "message_subject", "message_body", "profile"):
104 value = locals()[key] 111 value = locals()[key]
105 if value: 112 if value:
106 kwargs[key] = unicode(value) 113 kwargs[key] = unicode(value)
107 d = self.create(**kwargs) 114 d = self.create(**kwargs)
166 u', '.join(set(kwargs).intersection(extra)))) 173 u', '.join(set(kwargs).intersection(extra))))
167 174
168 self.checkExtra(extra) 175 self.checkExtra(extra)
169 176
170 email = kwargs.pop(u'email', None) 177 email = kwargs.pop(u'email', None)
178 emails_extra = kwargs.pop(u'emails_extra', [])
179 if not email and emails_extra:
180 raise ValueError(_(u'You need to provide a main email address before using emails_extra'))
171 181
172 if email is not None and not 'url_template' in kwargs and not 'message_body' in kwargs: 182 if email is not None and not 'url_template' in kwargs and not 'message_body' in kwargs:
173 raise ValueError(_(u"You need to provide url_template if you use default message body")) 183 raise ValueError(_(u"You need to provide url_template if you use default message body"))
174 184
175 ## uuid 185 ## uuid
246 if language is not None: 256 if language is not None:
247 extra[u'language'] = language 257 extra[u'language'] = language
248 258
249 if email is not None: 259 if email is not None:
250 extra[u'email'] = email 260 extra[u'email'] = email
261 data_format.iter2dict(KEY_EMAILS_EXTRA, extra)
251 url_template = kwargs.pop(u'url_template', '') 262 url_template = kwargs.pop(u'url_template', '')
252 format_args = { 263 format_args = {
253 u'uuid': id_, 264 u'uuid': id_,
254 u'app_name': C.APP_NAME, 265 u'app_name': C.APP_NAME,
255 u'app_url': C.APP_URL} 266 u'app_url': C.APP_URL}
274 invite_url = url_template.format(**format_args) 285 invite_url = url_template.format(**format_args)
275 format_args[u'url'] = invite_url 286 format_args[u'url'] = invite_url
276 287
277 yield sat_email.sendEmail( 288 yield sat_email.sendEmail(
278 self.host, 289 self.host,
279 [email], 290 [email] + emails_extra,
280 (kwargs.pop(u'message_subject', None) or DEFAULT_SUBJECT).format(**format_args), 291 (kwargs.pop(u'message_subject', None) or DEFAULT_SUBJECT).format(**format_args),
281 (kwargs.pop(u'message_body', None) or DEFAULT_BODY).format(**format_args), 292 (kwargs.pop(u'message_body', None) or DEFAULT_BODY).format(**format_args),
282 ) 293 )
283 294
284 ## extra data saving 295 ## extra data saving