def mail_project_complete(project): with TenantLanguage(project.owner.primary_language): subject = _(u"The project '{0}' has been realised").format( project.title) survey_link = Survey.url(project, user_type='initiator') send_mail(template_name="projects/mails/project_complete.mail", subject=subject, to=project.owner, title=project.title, receiver_name=project.owner.short_name, survey_link=mark_safe(survey_link) if survey_link else None, site=tenant_url(), link='/go/projects/{0}'.format(project.slug)) if project.organization: with TenantLanguage(project.owner.primary_language): subject = _(u"The project '{0}' has been realised").format( project.title) survey_link = Survey.url(project, user_type='organization') send_mail( template_name="projects/mails/organization_project_complete.mail", subject=subject, to=project.organization, title=project.title, receiver_name=project.organization.name, survey_link=mark_safe(survey_link) if survey_link else None, site=tenant_url(), link='/go/projects/{0}'.format(project.slug))
def put(self, request, *args, **kwargs): serializer = PasswordResetSerializer(data=request.data) serializer.is_valid(raise_exception=True) try: user = USER_MODEL.objects.get( email__iexact=serializer.validated_data['email']) context = { 'email': user.email, 'site': tenant_url(), 'site_name': tenant_url(), 'uid': int_to_base36(user.pk), 'user': user, 'token': default_token_generator.make_token(user), } with TenantLanguage(user.primary_language): subject = loader.render_to_string( 'bb_accounts/password_reset_subject.txt', context) # Email subject *must not* contain newlines subject = ''.join(subject.splitlines()) send_mail(template_name='bb_accounts/password_reset_email', to=user, subject=subject, **context) except USER_MODEL.DoesNotExist: pass return response.Response({}, status=status.HTTP_200_OK)
def send_suggestion_confirmation_email(sender, instance, created, **kwargs): """ Send a confirmation email when a new Suggestion is created """ if created: with TenantLanguage(instance.language): subject = _('Thank you for submitting your project request.') url = getattr(properties, 'OPEN_EXTERNAL_URL', None) if not url: return tokenurl = '{0}/confirm-suggestion/{1}/{2}'.format(url, instance.token, instance.language) user = User() user['email'] = instance.org_email user.email = instance.org_email send_mail( template_name="suggestions/mails/suggestion_confirm.mail", subject=subject, to=user, suggestion=instance, tokenurl=tokenurl, language=instance.language )
def mail_pledge_platform_admin(donation): # Only process "one-off" type donations if donation.order.order_type != "one-off": return project_url = '/projects/{0}'.format(donation.project.slug) try: admin_email = properties.TENANT_MAIL_PROPERTIES.get('address') except AttributeError: logger.critical('No mail properties found for {0}'.format( connection.tenant.client_name)) if admin_email: # Use the platform default language with TenantLanguage(properties.LANGUAGE_CODE): subject = _('A new pledge donation has been received') payment_method = get_payment_method(donation) # Create fake user object for mail receiver = bunchify({'email': admin_email}) # Send email to the project owner. send_mail(template_name='payments_pledge/mails/pledge_details.mail', subject=subject, to=receiver, link=project_url, donation=donation, pledged=True, payment_method=payment_method)
def send_welcome_mail(user=None): subject = _("Welcome to %(site_name)s") % {'site_name': tenant_name()} if user and user.primary_language: with TenantLanguage(user.primary_language): subject = _("Welcome to %(site_name)s") % { 'site_name': tenant_name() } data = { 'email': user.email, 'site': tenant_url(), 'site_name': tenant_name(), 'user': user, 'first_name': user.first_name, 'contact_email': properties.CONTACT_EMAIL, 'token': default_token_generator.make_token(user), 'uid': int_to_base36(user.pk), 'LANGUAGE_CODE': user.primary_language, } # If there is no password and no remote_id (SSO) then use the # welcome + password template, and then set a random password if not user.password and not user.remote_id: send_mail(template_name='bb_accounts/activation_email_no_password', subject=subject, to=user, **data) else: send_mail(template_name='bb_accounts/activation_email', subject=subject, to=user, **data)
def _merge_attrs(data, attrs): try: items = attrs.iteritems() except AttributeError: logger.exception('analytics_merge_attrs') return for label, attr in items: options = {} # If a dict is passed then the key is the dotted # property string and the value is options. try: new_attr = attr.keys()[0] options = attr[new_attr] attr = new_attr except AttributeError: # TODO: Logging pass value = _multi_getattr(instance, attr, default='') if options.get('translate', False): with LocalTenant(): # Translate using the default tenant language with TenantLanguage( getattr(properties, 'LANGUAGE_CODE', 'en')): # If attr is a string then try to translate # Note: tag values should always be strings. value = _(value) data[label] = value
def order_payment_refund_mail(instance): order_payment = instance order = order_payment.order receiver = order.user if not receiver: return try: # NOTE: only handling on order with a single donation donation = order.donations.first() except IndexError: return try: if donation.fundraiser: project = donation.fundraiser.project else: project = donation.project except AttributeError: return with TenantLanguage(receiver.primary_language): subject = _('Donation Refund') admin_email = properties.TENANT_MAIL_PROPERTIES.get('address') send_mail(template_name='payments/mails/order_payment_refund.mail', subject=subject, to=receiver, site=tenant_url(), project=project, admin_email=admin_email)
def mail_project_funded_monthly_donor_notification(receiver, project): with TenantLanguage(receiver.primary_language): subject = _("Congratulations: project completed!") send_mail(template_name= 'recurring_donations/mails/project_full_monthly_donor.mail', subject=subject, receiver_first_name=receiver.first_name.capitalize(), to=receiver, project=project, link='/go/projects/{0}'.format(project.slug))
def mail_project_incomplete(project): with TenantLanguage(project.owner.primary_language): subject = _(u"The project '{0}' has expired").format(project.title) send_mail(template_name="projects/mails/project_incomplete.mail", subject=subject, to=project.owner, title=project.title, receiver_name=project.owner.short_name, site=tenant_url(), link='/go/projects/{0}'.format(project.slug))
def deadline_reached(self): if self.people_accepted: self.status = self.TaskStatuses.realized else: self.status = self.TaskStatuses.closed with TenantLanguage(self.author.primary_language): subject = _( "The status of your task '{0}' is set to closed").format( self.title) send_mail(template_name="tasks/mails/task_status_closed.mail", subject=subject, title=self.title, to=self.author, site=tenant_url(), link='/tasks/{0}'.format(self.id)) self.save()
def create_message(template_name=None, to=None, subject=None, cc=None, bcc=None, from_email=None, reply_to=None, attachments=None, **kwargs): if hasattr(to, 'primary_language') and to.primary_language: language = to.primary_language else: language = properties.LANGUAGE_CODE # This is an exception to handle a Bookingcares.com language which # contains more languages than the rest of the platform if 'language' in kwargs: language = kwargs['language'] with TenantLanguage(language): ctx = ClientContext(kwargs) ctx['to'] = to # Add the recipient to the context text_content = get_template('{0}.txt'.format(template_name)).render( ctx.flatten()) html_content = get_template('{0}.html'.format(template_name)).render( ctx.flatten()) args = dict(subject=subject, body=text_content, to=[to.email]) if cc: args['cc'] = cc if bcc: args['bcc'] = bcc if reply_to: args['reply_to'] = [reply_to] # even if it's None args['from_email'] = from_email args['attachments'] = attachments # Calling force_unicode on the subject below in case the subject # is being translated using ugettext_lazy. msg = EmailMultiAlternatives(**args) msg.activated_language = translation.get_language() msg.attach_alternative(html_content, "text/html") return msg
def email_deadline_update(sender, instance, **kwargs): if instance.pk: previous_instance = Task.objects.get(pk=instance.pk) if (previous_instance.deadline.date() != instance.deadline.date() and instance.status not in (Task.TaskStatuses.realized, Task.TaskStatuses.closed)): for task_member in instance.members_applied: with TenantLanguage(task_member.member.primary_language): subject = _('The deadline of your task is changed') send_mail(template_name='tasks/mails/deadline_changed.mail', subject=subject, title=instance.title, original_date=previous_instance.deadline, date=instance.deadline, to=task_member.member, site=tenant_url(), link='/tasks/{0}'.format(instance.id))
def notify(self): task = self.parent task_owner = task.author if self.author != task_owner: with TenantLanguage(task_owner.primary_language): subject = _('%(author)s commented on your task') % { 'author': self.author.get_short_name() } site = self.site send_mail(template_name='task_wallpost_new.mail', subject=subject, to=task_owner, task=task, link='/go/tasks/{0}'.format(task.id), site=site, author=self.author, receiver=task_owner)
def deadline_to_apply_reached(self): with TenantLanguage(self.author.primary_language): subject = ugettext( "The deadline to apply for your task '{0}' has passed").format( self.title) send_deadline_to_apply_passed_mail(self, subject, connection.tenant) if self.status == self.TaskStatuses.open: if self.people_applied: if self.people_applied + self.externals_applied < self.people_needed: self.people_needed = self.people_applied if self.type == self.TaskTypes.ongoing: self.status = self.TaskStatuses.in_progress else: self.status = self.TaskStatuses.full else: self.status = self.TaskStatuses.closed self.save()
def mail_monthly_donation_processed_notification(monthly_order): cur_language = translation.get_language() receiver = monthly_order.user with TenantLanguage(receiver.primary_language): subject = _("Thank you for your monthly support") translation.activate(cur_language) send_mail(template_name='recurring_donations/mails/monthly_donation.mail', subject=subject, to=receiver, order=monthly_order, receiver_first_name=receiver.first_name.capitalize(), link='/go/projects', date=format_date(locale='nl_NL'), amount=format_currency(monthly_order.amount.amount, 'EUR', locale='nl_NL'))
def successful_donation_fundraiser_mail(instance): donation = instance # should be only when the status is success try: receiver = donation.fundraiser.owner except Exception: # donation it's not coming from a fundraiser return fundraiser_link = '/go/fundraisers/{0}'.format(instance.fundraiser.id) pledged = (donation.order.status == StatusDefinition.PLEDGED) with TenantLanguage(receiver.primary_language): subject = _('You received a new donation') if instance.fundraiser.owner.email: if instance.anonymous: donor_name = _('an anonymous person') elif instance.order.user: if instance.order.user.first_name: donor_name = instance.order.user.first_name else: donor_name = instance.order.user.email else: donor_name = _('a guest') with LogMail(donation.mail_logs, 'new_oneoff_donation_fundraiser') as sent: if not sent: send_mail(template_name= 'donations/mails/new_oneoff_donation_fundraiser.mail', subject=subject, site=tenant_url(), to=receiver, link=fundraiser_link, donation=donation, pledged=pledged, donor_name=donor_name)
def notify(self): project = self.parent for manager in set( [project.owner, project.task_manager, project.promoter]): # Implement 1a: send email to Object owner, if Wallpost author is not # the Object owner. if manager and self.author != manager: with TenantLanguage(manager.primary_language): subject = _('%(author)s commented on your project') % { 'author': self.author.get_short_name() } send_mail(template_name='project_wallpost_new.mail', subject=subject, to=manager, project=project, link='/go/projects/{0}'.format(project.slug), author=self.author, receiver=manager)
def post(self, request, *args, **kwargs): serializer = ShareSerializer(data=request.data) serializer.is_valid(raise_exception=True) args = self.project_args(serializer.validated_data.get('project')) if args is None: return HttpResponseNotFound() sender_name = self.request.user.get_full_name( ) or self.request.user.username sender_email = self.request.user.email share_name = serializer.validated_data.get('share_name', None) share_email = serializer.validated_data.get('share_email', None) share_motivation = serializer.validated_data.get( 'share_motivation', None) share_cc = serializer.validated_data.get('share_cc') with TenantLanguage(self.request.user.primary_language): subject = _('%(name)s wants to share a project with you!') % dict( name=sender_name) args.update( dict(template_name='utils/mails/share_flyer.mail', subject=subject, to=namedtuple("Receiver", "email")(email=share_email), share_name=share_name, share_email=share_email, share_motivation=share_motivation, sender_name=sender_name, sender_email=sender_email, reply_to=sender_email, cc=[sender_email] if share_cc else [])) if share_cc: args['cc'] = [sender_email] send_mail(**args) return response.Response({}, status=201)
def send_new_role_email(sender, instance, **kwargs): """ Send an email if a project role is assigned. """ if not instance.pk: return from bluebottle.projects.models import Project original = Project.objects.get(pk=instance.pk) for role in ['task_manager', 'reviewer', 'promoter']: user = getattr(instance, role) if user and getattr(original, role) != user: # The original is not the same as the current: sent email with TenantLanguage(user.primary_language): role_name = ROLE_NAMES[role] subject = _( _('You are assigned as %(role)s for project %(project)s') % { 'role': role_name, 'project': instance.title }) if role == 'reviewer': link = reverse('admin:projects_project_change', args=(instance.pk, )) else: link = '/projects/{}'.format(instance.slug) send_mail( template_name='projects/mails/project_role.mail', subject=subject, to=user, receiver_name=user.short_name, role=role, role_name=role_name, title=instance.title, admin_email=properties.TENANT_MAIL_PROPERTIES.get('address'), link=link)
def status_changed(self, oldstate, newstate): """ called by post_save signal handler, if status changed """ # confirm everything with task owner if oldstate in (self.TaskStatuses.in_progress, self.TaskStatuses.open, self.TaskStatuses.closed ) and newstate == self.TaskStatuses.realized: self.project.check_task_status() with TenantLanguage(self.author.primary_language): subject = ugettext( "The status of your task '{0}' is set to realized").format( self.title) second_subject = ugettext( "Don't forget to confirm the participants of your task!") third_subject = ugettext( "Last chance to confirm the participants of your task") # Immediately send email about realized task send_task_realized_mail(self, 'task_status_realized', subject, connection.tenant) if getattr(properties, 'CELERY_RESULT_BACKEND', None): # And schedule two more mails (in 3 and 6 days) send_task_realized_mail.apply_async( [ self, 'task_status_realized_reminder', second_subject, connection.tenant ], eta=timezone.now() + timedelta(minutes=settings.REMINDER_MAIL_DELAY)) send_task_realized_mail.apply_async( [ self, 'task_status_realized_second_reminder', third_subject, connection.tenant ], eta=timezone.now() + timedelta(minutes=2 * settings.REMINDER_MAIL_DELAY))
def subject(self): with TenantLanguage(self.receiver.primary_language): return _('The task you subscribed to is due')
def notify(self): task = self.post.content_object task_author = task.author # Make sure users only get mailed once! mailed_users = set() # It's commented out... check why # Implement 2c: send email to other Reaction authors that are not # the Object owner or the post author. # reactions = post.reactions.exclude( # Q(author=post_author) | # Q(author=project_owner) | # Q(author=reaction_author)) # for r in reactions: # if r.author not in mailed_users: # send_mail( # template_name='project_wallpost_reaction_same_wallpost.mail', # subject=_('%(author)s replied on your comment') # % {'author': reaction_author.first_name}, # to=r.author, # # project=project, # link='/go/projects/{0}'.format(project.slug), # author=reaction_author # ) # mailed_users.add(r.author) # Implement 2b: send email to post author, if Reaction author is not # the post author. if self.reaction_author != self.post_author: if self.reaction_author not in mailed_users and self.post_author: with TenantLanguage(self.post_author.primary_language): subject = _('%(author)s replied on your comment') % { 'author': self.reaction_author.get_short_name() } send_mail(template_name='task_wallpost_reaction_new.mail', subject=subject, to=self.post_author, site=self.site, task=task, link='/go/tasks/{0}'.format(task.id), author=self.reaction_author, receiver=self.post_author) mailed_users.add(self.post_author) # Implement 2a: send email to Object owner, if Reaction author is not # the Object owner. if self.reaction_author != task_author: if task_author not in mailed_users: with TenantLanguage(task_author.primary_language): subject = _('%(author)s commented on your task') % { 'author': self.reaction_author.get_short_name() } send_mail(template_name='task_wallpost_reaction_task.mail', subject=subject, to=task_author, site=self.site, task=task, link='/go/tasks/{0}'.format(task.id), author=self.reaction_author, receiver=task_author)
def notify(self): project = self.post.content_object # Make sure users only get mailed once! mailed_users = set() # Implement 2c: send email to other Reaction authors that are not the # Object owner or the post author. reactions = self.post.reactions.exclude( Q(author=self.post_author) | Q(author=project.owner) | Q(author=self.reaction_author)) for r in reactions: if r.author not in mailed_users: with TenantLanguage(r.author.primary_language): subject = _('%(author)s replied on your comment') % { 'author': self.reaction_author.get_short_name() } send_mail(template_name= 'project_wallpost_reaction_same_wallpost.mail', subject=subject, to=r.author, project=project, link='/go/projects/{0}'.format(project.slug), author=self.reaction_author, receiver=r.author) mailed_users.add(r.author) # Implement 2b: send email to post author, if Reaction author is not # the post author. if self.reaction_author != self.post_author: if self.reaction_author not in mailed_users and self.post_author: with TenantLanguage(self.post_author.primary_language): subject = _('%(author)s replied on your comment') % { 'author': self.reaction_author.get_short_name() } send_mail(template_name='project_wallpost_reaction_new.mail', subject=subject, to=self.post_author, project=project, link='/go/projects/{0}'.format(project.slug), site=self.site, author=self.reaction_author, receiver=self.post_author) mailed_users.add(self.post_author) # Implement 2a: send email to Object owner, if Reaction author is not # the Object owner. for manager in set( [project.owner, project.task_manager, project.promoter]): if manager and self.reaction_author != manager: if manager not in mailed_users: with TenantLanguage(manager.primary_language): subject = _('%(author)s commented on your project') % { 'author': self.reaction_author.get_short_name() } send_mail( template_name='project_wallpost_reaction_project.mail', subject=subject, to=manager, project=project, site=self.site, link='/go/projects/{0}'.format(project.slug), author=self.reaction_author, receiver=manager)
def subject(self): with TenantLanguage(self.receiver.primary_language): return _("A task you've joined is marked as realised")
def subject(self): with TenantLanguage(self.receiver.primary_language): return _('%(member)s withdrew from a task') % { 'member': self.task_member.member.get_short_name() }
def subject(self): with TenantLanguage(self.task_member.member.primary_language): return _('%(member)s applied for your task') % { 'member': self.task_member.member.get_short_name() }
def subject(self): with TenantLanguage(self.receiver.primary_language): return _('%(author)s didn\'t select you for a task') % { 'author': self.task.author.get_short_name() }
def subject(self): with TenantLanguage(self.receiver.primary_language): return _('%(author)s assigned you to a task') % { 'author': self.task.author.get_short_name() }
def new_oneoff_donation(instance): """ Send project owner a mail if a new "one off" donation is done. We consider a donation done if the status is pending. """ donation = instance # Only process "one-off" type donations if donation.order.order_type != "one-off": return project_url = '/projects/{0}'.format(donation.project.slug) pledged = (donation.order.status == StatusDefinition.PLEDGED) try: admin_email = properties.TENANT_MAIL_PROPERTIES.get('address') except AttributeError: logger.critical('No mail properties found for {0}'.format( connection.tenant.client_name)) if donation.project.owner.email: receiver = donation.project.owner with TenantLanguage(receiver.primary_language): subject = _('You received a new donation') if donation.anonymous: donor_name = _('an anonymous person') elif donation.order.user: donor_name = donation.order.user.first_name else: donor_name = _('a guest') payment_method = get_payment_method(donation) with LogMail(donation.mail_logs, 'new_oneoff_donation') as sent: if not sent: # Send email to the project owner. send_mail( template_name='donations/mails/new_oneoff_donation.mail', subject=subject, to=receiver, link=project_url, donor_name=donor_name, donation=donation, pledged=pledged, admin_email=admin_email, payment_method=payment_method) if donation.order.user and donation.order.user.email: # Send email to the project supporter donor = donation.order.user with TenantLanguage(donor.primary_language): subject = _('Thanks for your donation') payment_method = get_payment_method(donation) with LogMail(donation.mail_logs, 'confirmation') as sent: if not sent: send_mail(template_name="donations/mails/confirmation.mail", subject=subject, to=donor, link=project_url, donation=donation, pledged=pledged, payment_method=payment_method)
def email_followers(sender, instance, created, **kwargs): """ When a Wallpost is created, project owners, task owners and fundraiser owners can check a box wether to email their followers. This signal handler looksup the appropriate followers depending on the type of page (project, task, fundraiser). It then sends out an email to those followers if they have campaign notifications enabled. """ from bluebottle.wallposts.models import Wallpost, SystemWallpost if not created: return if isinstance(instance, Wallpost) and not isinstance(instance, SystemWallpost): if instance.email_followers: content_type = ContentType.objects.get_for_model( instance.content_object) # content_type references project # Determine if this wallpost is on a Project page, Task page, or # Fundraiser page. Required because of different Follow object # lookup mailers = set() # Contains unique user objects link = None if isinstance(instance.content_object, BaseProject): # Send update to all task owners, all fundraisers, all people # who donated and all people who are following (i.e. posted to # the wall) followers = Follow.objects.filter( content_type=content_type, object_id=instance.content_object.id).distinct().exclude( user=instance.author) [mailers.add(follower.user) for follower in followers] follow_object = _('project') link = '/go/projects/{0}'.format(instance.content_object.slug) if isinstance(instance.content_object, Task): # Send update to all task members and to people who posted to # the wall --> Follower followers = Follow.objects.filter( content_type=content_type, object_id=instance.content_object.id).distinct().exclude( user=instance.author) [mailers.add(follower.user) for follower in followers] follow_object = _('task') link = '/go/tasks/{0}'.format(instance.content_object.id) if isinstance(instance.content_object, BaseFundraiser): # Send update to all people who donated or posted to the wall # --> Followers followers = Follow.objects.filter( content_type=content_type, object_id=instance.content_object.id).distinct().exclude( user=instance.author) [mailers.add(follower.user) for follower in followers] follow_object = _('fundraiser') link = '/go/fundraisers/{0}'.format(instance.content_object.id) wallpost_text = instance.text site = tenant_url() full_link = site + link for mailee in mailers: if mailee.campaign_notifications: cur_language = translation.get_language() if mailee.primary_language: translation.activate(mailee.primary_language) else: translation.activate(properties.LANGUAGE_CODE) with TenantLanguage(mailee.primary_language): subject = _("New wallpost on %(name)s") % { 'name': instance.content_object.title } translation.activate(cur_language) send_mail( template_name='bb_follow/mails/wallpost_mail.mail', subject=subject, wallpost_text=wallpost_text[:250], to=mailee, link=full_link, follow_object=follow_object, first_name=mailee.first_name, author=instance.author.first_name)