def send_html_mail(request, template, content, **kwargs): """" Sends an email rendered from the given template. Example:: send_html_mail(request, 'mail_template.pt', {'model': self}, subject=_("Test subject") receivers=('*****@*****.**', ) ) """ assert 'model' in content assert 'subject' in kwargs assert 'receivers' in kwargs kwargs['subject'] = request.translate(kwargs['subject']) if 'layout' not in content: content['layout'] = DefaultMailLayout(content['model'], request) if 'title' not in content: content['title'] = kwargs['subject'] kwargs['content'] = render_template(template, request, content) # the email is queued here, not actually sent! request.app.send_email(**kwargs)
def handle_password_reset_request(self, request, form): """ Handles the password reset requests. """ show_form = True callout = None if form.submitted(request): users = UserCollection(request.session) user = users.by_username(form.email.data) if user: url = password_reset_url( user, request, request.link(self, name='reset-password') ) request.app.send_transactional_email( subject=request.translate(_("Password reset")), receivers=(user.username, ), reply_to=request.app.mail['transactional']['sender'], content=render_template( 'mail_password_reset.pt', request, { 'title': request.translate(_("Password reset")), 'model': None, 'url': url, 'layout': MailLayout(self, request) } ) ) else: log.info( "Failed password reset attempt by {}".format( request.client_addr ) ) show_form = False callout = _( ( 'A password reset link has been sent to ${email}, provided an ' 'account exists for this email address.' ), mapping={'email': form.email.data} ) return { 'layout': DefaultLayout(self, request), 'title': _('Reset password'), 'form': form, 'show_form': show_form, 'callout': callout }
def handle_password_reset_request(self, request, form): """ Handles the password reset requests. """ show_form = True callout = None if form.submitted(request): users = UserCollection(request.session) user = users.by_username(form.email.data) if user: url = password_reset_url( user, request, request.link(self, name='reset-password') ) request.app.send_transactional_email( subject=request.translate(_("Password reset")), receivers=(user.username, ), reply_to=request.app.mail['transactional']['sender'], content=render_template( 'mail_password_reset.pt', request, { 'title': request.translate(_("Password reset")), 'model': None, 'url': url, 'layout': MailLayout(self, request) } ) ) else: log.info( "Failed password reset attempt by {}".format( request.client_addr ) ) show_form = False callout = _( ( 'A password reset link has been sent to ${email}, provided an ' 'account exists for this email address.' ), mapping={'email': form.email.data} ) return { 'layout': Layout(self, request), 'title': _('Reset password'), 'form': form, 'show_form': show_form, 'callout': callout }
def handle_send_notification(self, request, form): period = PeriodCollection(request.session).active() variables = TemplateVariables(request, period) layout = NotificationTemplateLayout(self, request) if form.submitted(request): recipients = form.recipients if not recipients: request.alert(_("There are no recipients matching the selection")) else: current = request.current_username if current not in recipients: recipients.add(current) subject = variables.render(self.subject) content = render_template('mail_notification.pt', request, { 'layout': DefaultMailLayout(self, request), 'title': subject, 'notification': variables.render(self.text) }) plaintext = html_to_text(content) for recipient in recipients: request.app.send_marketing_email( receivers=(recipient, ), subject=subject, content=content, plaintext=plaintext, ) self.last_sent = utcnow() request.success(_( "Successfully sent the e-mail to ${count} recipients", mapping={ 'count': len(recipients) } )) return request.redirect( request.class_link(NotificationTemplateCollection)) return { 'title': _("Mailing"), 'layout': layout, 'form': form, 'preview_subject': variables.render(self.subject), 'preview_body': variables.render(self.text), 'edit_link': request.return_here(request.link(self, 'edit')), 'button_text': _("Send E-Mail Now") }
def add_town(self, name, user, color, request): current_schema = self.app.session_manager.current_schema password = random_password(16) try: schema = self.get_schema(name) custom_config = self.config['configuration'] self.app.session_manager.set_current_schema(schema) session = self.app.session_manager.session() if session.query(Organisation).first(): raise AlreadyExistsError with self.app.temporary_depot(schema, **custom_config): create_new_organisation(self.app, name=name, reply_to=user) org = session.query(Organisation).first() org.theme_options['primary-color'] = color users = UserCollection(self.app.session_manager.session()) assert not users.query().first() users.add(user, password, 'admin') title = request.translate(_("Welcome to OneGov Cloud")) welcome_mail = render_template( 'mail_welcome.pt', request, { 'url': 'https://{}'.format(self.get_domain(name)), 'mail': user, 'layout': MailLayout(self, request), 'title': title, 'org': name }) self.app.es_perform_reindex() self.app.send_transactional_email(subject=title, receivers=(user, ), content=welcome_mail, reply_to='*****@*****.**') finally: self.app.session_manager.set_current_schema(current_schema) return { 'info': [ (_("Username"), user), (_("Password"), password), ], 'url': 'https://{}'.format(self.get_domain(name)) }
def send_accepted_mail(request, notice): """ Sends a mail to the publisher with the contents of the notice. We use named temporary files because the files stored by depot does not have a nice filename (which is automatically used by mailton) and to allow temporary files from the memory without a real file on the disk. """ def construct_subject(notice, request): issues = notice.issue_objects number = issues[0].number if issues else '' organization = notice.organization_object parent = organization.parent if organization else None parent_id = (parent.external_name or '') if parent else '' prefixes = [] if notice.at_cost: prefixes.append(request.translate(_("With costs"))) if notice.print_only: prefixes.append(request.translate(_("Print only"))) prefix = '' if not prefixes else "{} - ".format(" / ".join(prefixes)) return "{}{} {} {} {}".format(prefix, number, parent_id, notice.title, notice.id) reply_to = (request.app.principal.on_accept.get('mail_from') or request.app.mail['transactional']['sender']) subject = construct_subject(notice, request) content = render_template('mail_on_accept.pt', request, { 'title': subject, 'model': notice, 'layout': MailLayout(notice, request) }) attachments = [] for file in notice.files: attachment = Attachment(file.reference.file._file_path) content_disposition = 'attachment; filename="{}"'.format(file.name) attachment.headers['Content-Disposition'] = content_disposition attachments.append(attachment) request.app.send_transactional_email( subject=subject, receivers=(request.app.principal.on_accept['mail_to'], ), reply_to=reply_to, content=content, attachments=attachments)
def add_town(self, name, user, color, request): current_schema = self.app.session_manager.current_schema password = random_password(16) try: self.app.session_manager.set_current_schema(self.get_schema(name)) session = self.app.session_manager.session() if session.query(Organisation).first(): raise AlreadyExistsError create_new_organisation(self.app, name=name, reply_to=user) org = session.query(Organisation).first() org.theme_options['primary-color'] = color users = UserCollection(self.app.session_manager.session()) assert not users.query().first() users.add(user, password, 'admin') title = request.translate(_("Welcome to OneGov Cloud")) welcome_mail = render_template('mail_welcome.pt', request, { 'url': 'https://{}'.format(self.get_domain(name)), 'mail': user, 'layout': MailLayout(self, request), 'title': title, 'org': name }) self.app.send_email( subject=title, receivers=(user, ), content=welcome_mail, reply_to='*****@*****.**' ) finally: self.app.session_manager.set_current_schema(current_schema) return { 'info': [ (_("Username"), user), (_("Password"), password), ], 'url': 'https://{}'.format(self.get_domain(name)) }
def add_scan_job(self, request, form): """ Create a new scan job. """ if request.has_permission(self, AddModelUnrestricted): return redirect(request.link(self, name='add-unrestricted')) layout = AddScanJobLayout(self, request) if form.submitted(request): scan_job = ScanJob() form.update_model(scan_job) scan_job.delivery_number = self.next_delivery_number( scan_job.municipality_id ) request.session.add(scan_job) request.message(_("Scan job added."), 'success') subject = request.translate( _("Order confirmation for scanning your tax returns") ) request.app.send_transactional_email( subject=subject, receivers=(request.identity.userid, ), reply_to=request.app.mail['transactional']['sender'], content=render_template( 'mail_confirm.pt', request, { 'title': subject, 'model': scan_job, 'layout': MailLayout(scan_job, request) } ), ) return redirect(layout.success_url) return { 'layout': layout, 'form': form, 'button_text': _("Save"), 'cancel': layout.cancel_url }
def create_user(self, request, form): """ Create a new publisher or editor. This view is visible for admins and publishers. """ layout = Layout(self, request) if form.submitted(request): user = self.add(form.username.data, random_password(16), form.role.data, realname=form.name.data) form.update_model(user) user.modified = user.timestamp() url = password_reset_url( user, request, request.link(request.app.principal, name='reset-password')) request.app.send_transactional_email( subject=request.translate(_("User account created")), receivers=(user.username, ), reply_to=request.app.mail['transactional']['sender'], content=render_template( 'mail_user_created.pt', request, { 'title': request.translate(_("User account created")), 'model': None, 'url': url, 'layout': MailLayout(self, request) })) request.message(_("User added."), 'success') return redirect(layout.manage_users_link) return { 'layout': layout, 'form': form, 'title': _("New User"), 'cancel': layout.manage_users_link }
def send_daily_ticket_statistics(request): today = replace_timezone(datetime.utcnow(), 'UTC') today = to_timezone(today, 'Europe/Zurich') if today.weekday() in (SAT, SUN): return args = {} # get the current ticket count collection = TicketCollection(request.app.session()) count = collection.get_count() args['currently_open'] = count.open args['currently_pending'] = count.pending args['currently_closed'] = count.closed # get tickets created yesterday or on the weekend end = datetime(today.year, today.month, today.day, tzinfo=today.tzinfo) if today.weekday() == MON: start = end - timedelta(days=2) else: start = end - timedelta(days=1) query = collection.query() query = query.filter(Ticket.created >= start) query = query.filter(Ticket.created <= end) args['opened'] = query.count() query = collection.query() query = query.filter(Ticket.modified >= start) query = query.filter(Ticket.modified <= end) query = query.filter(Ticket.state == 'pending') args['pending'] = query.count() query = collection.query() query = query.filter(Ticket.modified >= start) query = query.filter(Ticket.modified <= end) query = query.filter(Ticket.state == 'closed') args['closed'] = query.count() # render the email args['title'] = request.translate( _("${town} OneGov Cloud Status", mapping={ 'town': request.app.town.name }) ) args['layout'] = DefaultMailLayout(object(), request) args['is_monday'] = today.weekday() == MON args['town'] = request.app.town.name content = render_template('mail_daily_ticket_statistics.pt', request, args) # send one e-mail per user users = UserCollection(request.app.session()).query() users = users.options(undefer('data')) users = users.all() for user in users: if user.data and not user.data.get('daily_ticket_statistics'): continue request.app.send_email( subject=args['title'], receivers=(user.username, ), content=content )
def reject_notice(self, request, form): """ Reject a notice. This view is used by the publishers to reject a submitted notice. Only submitted notices may be rejected. """ layout = Layout(self, request) if self.state != 'submitted': return { 'layout': layout, 'title': self.title, 'subtitle': _("Reject Official Note"), 'callout': _("Only submitted official notices may be rejected."), 'show_form': False } if form.submitted(request): self.reject(request, form.comment.data) request.message(_("Official notice rejected."), 'success') if self.user: request.app.send_transactional_email( subject=request.translate( _("Official Notice Rejected ${id}", mapping={'id': self.id})), receivers=(self.user.username, ), reply_to=request.app.mail['transactional']['sender'], content=render_template( 'mail_notice_rejected.pt', request, { 'title': request.translate( _("Official Notice Rejected ${id}", mapping={'id': self.id})), 'model': self, 'comment': form.comment.data, 'layout': MailLayout(self, request), 'url': request.link(self) })) return redirect(layout.dashboard_or_notices_link) return { 'message': _('Do you really want to reject "${item}"?', mapping={'item': self.title}), 'layout': layout, 'form': form, 'title': self.title, 'subtitle': _("Reject Official Note"), 'button_text': _("Reject Official Note"), 'button_class': 'alert', 'cancel': request.link(self) }