def mail( user: User, subject: str, template: Union[str, LazyI18nString], context: Dict[str, Any] = None, event: Event = None, locale: str = None, headers: dict = None, ): from pretalx.mail.models import QueuedMail headers = headers or {} with override(locale): body = str(template) if context: body = body.format_map(TolerantDict(context)) QueuedMail( event=event, to=user.email, subject=str(subject), text=body, reply_to=headers.get('reply-to'), bcc=headers.get('bcc'), ).send()
def send_orga_mail(self, text, stats=False): from django.utils.translation import override from pretalx.mail.models import QueuedMail context = { "event_dashboard": self.orga_urls.base.full(), "event_review": self.orga_urls.reviews.full(), "event_schedule": self.orga_urls.schedule.full(), "event_submissions": self.orga_urls.submissions.full(), "event_team": self.orga_urls.team_settings.full(), "submission_count": self.submissions.all().count(), } if stats: context.update( { "talk_count": self.current_schedule.talks.filter( is_visible=True ).count(), "review_count": self.reviews.count(), "schedule_count": self.schedules.count() - 1, "mail_count": self.queued_mails.filter(sent__isnull=False).count(), } ) with override(self.locale): QueuedMail( subject=_("News from your content system"), text=str(text).format(**context), to=self.email, ).send()
def send_email(self, event): email_hashed = hash_email(self.cleaned_data["email"], event) email_signed = event_sign(email_hashed, event) # For the email link, sign the hashed email address, so that no one # can just randomly create new URLs and pretend to be a user that # was validated via email. Credits for the email signing code go # to Volker Mische / @vmx vote_url = build_absolute_uri( "plugins:pretalx_public_voting:talks", kwargs={ "event": event.slug, "signed_user": email_signed }, ) mail_text = _("""Hi, you have registered to vote for submissions for {event.name}. Please confirm that this email address is valid by following this link: {vote_url} If you did not register for voting, you can ignore this email. Thank you for participating in the vote! The {event.name} organisers """) QueuedMail( event=event, to=self.cleaned_data["email"], subject=_("Public voting registration"), text=str(mail_text).format(vote_url=vote_url, event=event), ).send()
def save(self): QueuedMail( event=self.submission.event, to=self.cleaned_data['speaker'], subject=self.cleaned_data['subject'], text=self.cleaned_data['text'], ).send()
def send_invite(self, to, _from=None, subject=None, text=None): if not _from and (not subject or not text): raise Exception("Please enter a sender for this invitation.") subject = subject or _("{speaker} invites you to join their talk!" ).format(speaker=_from.get_display_name()) subject = f"[{self.event.slug}] {subject}" text = (text or _("""Hi! I'd like to invite you to be a speaker in the talk “{title}” at {event}. Please follow this link to join: {url} I'm looking forward to it! {speaker}""").format( event=self.event.name, title=self.title, url=self.urls.accept_invitation.full(), speaker=_from.get_display_name(), )) to = to.split(",") if isinstance(to, str) else to for invite in to: QueuedMail( event=self.event, to=invite, subject=subject, text=text, ).send()
def send_orga_mail(self, text, stats=False): from django.utils.translation import override from pretalx.common.mail import mail_send_task from pretalx.mail.models import QueuedMail context = { 'event_dashboard': self.orga_urls.base.full(), 'event_review': self.orga_urls.reviews.full(), 'event_schedule': self.orga_urls.schedule.full(), 'event_submissions': self.orga_urls.submissions.full(), 'event_team': self.orga_urls.team_settings.full(), 'submission_count': self.submissions.all().count(), } if stats: context.update({ 'talk_count': self.current_schedule.talks.filter(is_visible=True).count(), 'reviewer_count': self.permissions.filter(is_reviewer=True).count(), 'review_count': self.reviews.count(), 'schedule_count': self.schedules.count() - 1, 'mail_count': self.queued_mails.filter(sent__isnull=False).count(), }) with override(self.locale): text = str(text).format(**context) + '-- ' text += _(''' This mail was sent to you by the content system of your event {name}.''').format(name=self.name) mail_send_task.apply_async(kwargs={ 'to': [self.email], 'subject': _('[{slug}] News from your content system').format(slug=self.slug), 'body': text, 'html': QueuedMail.text_to_html(text, event=self), })
def _handle_new_user(self, request, email, permission=None): event = request.event if not permission: invitation_token = get_random_string(allowed_chars=string.ascii_lowercase + string.digits, length=20) permission = EventPermission.objects.create( event=event, invitation_email=email, invitation_token=invitation_token, is_orga=False, is_reviewer=True, ) invitation_link = build_absolute_uri('orga:invitation.view', event=event, kwargs={'code': permission.invitation_token}) invitation_text = _('''Hi! You have been invited to the submission review team of {event} - Please click here to accept: {invitation_link} We look forward to have you on the team!, The {event} orga crew (minus you)''').format(event=event.name, invitation_link=invitation_link) invitation_subject = _('You have been invited to the reviewer team of {event}').format(event=request.event.name) QueuedMail( event=request.event, to=email, reply_to=request.event.email, subject=str(invitation_subject), text=str(invitation_text), ).send() request.event.log_action('pretalx.invite.reviewer.send', person=request.user, orga=True) messages.success( request, _('<{email}> has been invited to your reviewer team - more reviewers help gain perspective, so … yay!').format(email=email) ) return redirect(event.orga_urls.review_settings)
def _handle_existing_user(self, request, user): if user: permission = user.permissions.filter(event=request.event).first() if not permission: EventPermission.objects.create(event=request.event, is_orga=False, is_reviewer=True) else: permission.is_reviewer = True permission.save(update_fields=['is_reviewer']) if user != request.user: invitation_text = _('''Hi! You have been added to the submission reviewer team of {event}! We are happy to have you on the team, The {event} orga crew''').format(event=request.event.name) invitation_subject = _('You have been added to the review team of {event}').format(event=request.event.name) QueuedMail( event=request.event, to=user.email, reply_to=request.event.email, subject=str(invitation_subject), text=str(invitation_text), ).send() messages.success(request, _('The user already existed and is now a reviewer.')) else: messages.success(request, _('You successfully made yourself a reviewer!')) request.event.log_action('pretalx.invite.reviewer.send', person=request.user, orga=True) return redirect(request.event.orga_urls.review_settings)
def send_invite(self, to, _from=None, subject=None, text=None): if not _from and (not subject or not text): raise Exception('Please tell me how to sign this invitation.') subject = subject or _('{speaker} invites you to join their talk!' ).format(speaker=_from.get_display_name()) subject = f'[{self.event.slug}] {subject}' text = text or _('''Hi! I'd like to invite you to be a speaker in the talk »{title}« at {event}. Please follow this link to join: {url} I'm looking forward to it! {speaker}''').format( event=self.event.name, title=self.title, url=self.urls.accept_invitation.full(), speaker=_from.get_display_name(), ) to = to.split(',') if isinstance(to, str) else to for invite in to: QueuedMail( event=self.event, to=invite, subject=subject, text=text, ).send()
def send_invite_email(self): from pretalx.mail.models import QueuedMail role = _('organiser') if not self.is_orga and self.is_reviewer: role = _('reviewer') elif self.is_orga and self.is_reviewer: role = _('organiser and reviewer') if self.user: invitation_link = build_absolute_uri( 'orga:event.dashboard', event=self.event, kwargs={'event': self.event.slug}) invitation_text = _('''Hi! You have been added to the {event} team as a {role} - you can access the organiser area here: {invitation_link} See you there, The {event} crew''').format(role=role, event=self.event.name, invitation_link=invitation_link) invitation_subject = _( 'You have been granted additional privileges on {event}' ).format(event=self.event.name) to = self.user.email else: self.invitation_token = get_random_string( allowed_chars=string.ascii_lowercase + string.digits, length=20) self.save() invitation_link = build_absolute_uri( 'orga:invitation.view', event=self.event, kwargs={'code': self.invitation_token}) invitation_text = _('''Hi! You have been invited to the {event} team as a {role} - Please click here to accept: {invitation_link} See you there, The {event} crew (minus you)''').format(role=role, event=self.event.name, invitation_link=invitation_link) invitation_subject = _('You have been invited to the {event} crew' ).format(event=self.event.name) to = self.invitation_email return QueuedMail( to=to, reply_to=self.event.email, subject=str(invitation_subject), text=str(invitation_text), event=self.event, )
def post(self, request, event): email = request.POST.get('email') event = request.event kwargs = { 'event': event, 'invitation_email': email, 'is_orga': True, } permission = EventPermission.objects.filter(user__isnull=True, **kwargs).first() if not permission: invitation_token = get_random_string( allowed_chars=string.ascii_lowercase + string.digits, length=20) permission = EventPermission.objects.create( event=event, invitation_email=email, invitation_token=invitation_token, is_orga=True, ) messages.success( request, _('<{email}> has been invited to your team - more team members help distribute the workload, so … yay!' ).format(email=email)) else: invitation_token = permission.invitation_token messages.info( request, _('<{email}> had already been invited – we\'ve resent the invitation instead :)' ).format(email=email), ) invitation_link = build_absolute_uri('orga:invitation.view', kwargs={'code': invitation_token}) invitation_text = _('''Hi! You have been invited to the orga crew of {event} - Please click here to accept: {invitation_link} See you there, The {event} orga crew (minus you)''').format(event=event.name, invitation_link=invitation_link) invitation_subject = _( 'You have been invited to the orga crew of {event}').format( event=request.event.name) QueuedMail(event=event, to=email, reply_to=request.event.email, subject=str(invitation_subject), text=str(invitation_text)).send() request.event.log_action('pretalx.event.invite.orga.send', person=request.user, orga=True) return redirect(request.event.orga_urls.team_settings)
def send_invite(self, to, subject, text): from pretalx.mail.models import QueuedMail to = to.split(',') if isinstance(to, str) else to for invite in to: QueuedMail( event=self.event, to=invite, subject=subject, text=text, ).send()
def send(self, event): from pretalx.mail.models import QueuedMail invitation_link = build_absolute_uri('orga:invitation.view', kwargs={'code': self.token}) invitation_text = _('''Hi! You have been invited to the {name} event organiser team - Please click here to accept: {invitation_link} See you there, The {event} team''').format( name=str(self.team.name), invitation_link=invitation_link, event=str(event.name) if event else str(self.team.organiser.name)) invitation_subject = _('You have been invited to an organiser team') mail = QueuedMail( to=self.email, event=event, subject=str(invitation_subject), text=str(invitation_text), ) if event: mail.save() else: mail.send() return mail
def notifications(self): tz = pytz.timezone(self.event.timezone) mails = [] for speaker in self.speakers_concerned: with override(speaker.locale), tzoverride(tz): text = get_template('schedule/speaker_notification.txt').render( {'speaker': speaker, **self.speakers_concerned[speaker]} ) mails.append( QueuedMail( event=self.event, to=speaker.email, reply_to=self.event.email, subject=_('New schedule!').format(event=self.event.slug), text=text, ) ) return mails
def notifications(self): tz = pytz.timezone(self.event.timezone) speakers = defaultdict(lambda: {'create': [], 'update': []}) if self.changes['action'] == 'create': speakers = { speaker: { 'create': self.talks.filter(submission__speakers=speaker), 'update': [], } for speaker in User.objects.filter(submissions__slots__schedule=self) } else: if self.changes['count'] == len(self.changes['canceled_talks']): return [] for new_talk in self.changes['new_talks']: for speaker in new_talk.submission.speakers.all(): speakers[speaker]['create'].append(new_talk) for moved_talk in self.changes['moved_talks']: for speaker in moved_talk['submission'].speakers.all(): speakers[speaker]['update'].append(moved_talk) mails = [] for speaker in speakers: with override(speaker.locale), tzoverride(tz): text = get_template('schedule/speaker_notification.txt').render( {'speaker': speaker, **speakers[speaker]} ) mails.append( QueuedMail( event=self.event, to=speaker.email, reply_to=self.event.email, subject=_('New schedule!').format(event=self.event.slug), text=text, ) ) return mails
def test_mail_make_subject(event, text, prefix, expected): if prefix: event.settings.mail_subject_prefix = prefix assert QueuedMail.make_subject(text, event) == expected
def test_mail_make_text(event, text, signature, expected): if signature: event.settings.mail_signature = signature assert QueuedMail.make_text(text, event) == expected