def notify_developers_of_failure(app, error_message, has_link=False): if (app.status not in mkt.WEBAPPS_APPROVED_STATUSES or RereviewQueue.objects.filter(addon=app).exists()): # If the app isn't public, or has already been reviewed, we don't # want to send the mail. return # FIXME: how to integrate with commbadge? for author in app.authors.all(): context = { 'error_message': error_message, 'SITE_URL': settings.SITE_URL, 'SUPPORT_GROUP': settings.SUPPORT_GROUP, 'has_link': has_link } to = [author.email] with author.activate_lang(): # Re-fetch the app to get translations in the right language. context['app'] = Webapp.objects.get(pk=app.pk) subject = _(u'Issue with your app "{app}" on the Firefox ' u'Marketplace').format(**context) send_mail_jinja(subject, 'webapps/emails/update_manifest_failure.txt', context, recipient_list=to)
def email_daily_ratings(): """ Does email for yesterday's ratings (right after the day has passed). Sends an email containing all reviews for that day for certain app. """ dt = datetime.datetime.today() - datetime.timedelta(1) yesterday = datetime.datetime(dt.year, dt.month, dt.day, 0, 0, 0) today = yesterday + datetime.timedelta(1) pretty_date = '%04d-%02d-%02d' % (dt.year, dt.month, dt.day) yesterday_reviews = Review.objects.filter(created__gte=yesterday, created__lt=today) # For each app in yesterday's set of reviews, gather reviews and email out. apps = set(review.addon for review in yesterday_reviews) for app in apps: # Email all reviews in one email for current app in loop. author_emails = app.authors.values_list('email', flat=True) subject = 'Firefox Marketplace reviews for %s on %s' % (app.name, pretty_date) context = { 'reviews': (yesterday_reviews.filter(addon=app).order_by('-created')), 'base_url': settings.SITE_URL, 'pretty_date': pretty_date } send_mail_jinja(subject, 'ratings/emails/daily_digest.html', context, recipient_list=author_emails, perm_setting='app_new_review', async=True)
def email_daily_ratings(): """ Does email for yesterday's ratings (right after the day has passed). Sends an email containing all reviews for that day for certain app. """ dt = datetime.datetime.today() - datetime.timedelta(1) yesterday = datetime.datetime(dt.year, dt.month, dt.day, 0, 0, 0) today = yesterday + datetime.timedelta(1) pretty_date = "%04d-%02d-%02d" % (dt.year, dt.month, dt.day) yesterday_reviews = Review.objects.filter(created__gte=yesterday, created__lt=today, addon__type=amo.ADDON_WEBAPP) # For each app in yesterday's set of reviews, gather reviews and email out. apps = set(review.addon for review in yesterday_reviews) for app in apps: # Email all reviews in one email for current app in loop. author_emails = app.authors.values_list("email", flat=True) subject = "Firefox Marketplace reviews for %s on %s" % (app.name, pretty_date) context = { "reviews": (yesterday_reviews.filter(addon=app).order_by("-created")), "base_url": settings.SITE_URL, "pretty_date": pretty_date, } send_mail_jinja( subject, "ratings/emails/daily_digest.html", context, recipient_list=author_emails, perm_setting="app_new_review", async=True, )
def email_recipients(recipients, note, template=None, extra_context=None): """ Given a list of tuple of user_id/user_email, email bunch of people. note -- commbadge note, the note type determines which email to use. template -- override which template we use. """ subject = '%s: %s' % (unicode(comm.NOTE_TYPES[note.note_type]), note.thread.obj.name) for email, user_id, tok in tokenize_recipients(recipients, note.thread): headers = {} if tok: headers['Reply-To'] = '{0}{1}@{2}'.format( comm.REPLY_TO_PREFIX, tok, settings.POSTFIX_DOMAIN) # Get the appropriate mail template. mail_template = template or comm.COMM_MAIL_MAP.get(note.note_type, 'generic') # Send mail. context = get_mail_context(note, user_id) context.update(extra_context or {}) send_mail_jinja(subject, 'comm/emails/%s.html' % mail_template, context, recipient_list=[email], from_email=settings.MKT_REVIEWERS_EMAIL, perm_setting='app_reviewed', headers=headers)
def email_recipients(recipients, note, template=None): """ Given a list of tuple of user_id/user_email, email bunch of people. note -- commbadge note, the note type determines which email to use. template -- override which template we use. """ subject = '%s: %s' % (unicode( comm.NOTE_TYPES[note.note_type]), note.thread.addon.name) for email, tok in tokenize_recipients(recipients, note.thread): reply_to = '{0}{1}@{2}'.format(comm.REPLY_TO_PREFIX, tok, settings.POSTFIX_DOMAIN) # Get the appropriate mail template. mail_template = template or comm.COMM_MAIL_MAP.get( note.note_type, 'generic') # Send mail. send_mail_jinja(subject, 'comm/emails/%s.html' % mail_template, get_mail_context(note), recipient_list=[email], from_email=settings.MKT_REVIEWERS_EMAIL, perm_setting='app_reviewed', headers={'Reply-To': reply_to}) # Also send mail to the fallback emailing list. if note.note_type == comm.DEVELOPER_COMMENT: mail_template = comm.COMM_MAIL_MAP.get(note.note_type, 'generic') send_mail_jinja(subject, 'comm/emails/%s.html' % mail_template, get_mail_context(note), recipient_list=[settings.MKT_REVIEWS_EMAIL], from_email=settings.MKT_REVIEWERS_EMAIL, perm_setting='app_reviewed')
def send_mail_comm(note): """ Email utility used globally by the Communication Dashboard to send emails. Given a note (its actions and permissions), recipients are determined and emails are sent to appropriate people. """ log.info(u'Sending emails for %s' % note.thread.obj) if note.note_type in comm.EMAIL_SENIOR_REVIEWERS_AND_DEV: # Email senior reviewers (such as for escalations). rev_template = comm.EMAIL_SENIOR_REVIEWERS_AND_DEV[ note.note_type]['reviewer'] email_recipients(get_senior_reviewers(), note, template=rev_template) # Email developers (such as for escalations). dev_template = comm.EMAIL_SENIOR_REVIEWERS_AND_DEV[ note.note_type]['developer'] email_recipients(get_developers(note), note, template=dev_template) else: email_recipients(get_recipients(note), note) # Also send mail to the fallback emailing list. if note.note_type == comm.DEVELOPER_COMMENT: subject = '%s: %s' % (unicode( comm.NOTE_TYPES[note.note_type]), note.thread.obj.name) mail_template = comm.COMM_MAIL_MAP.get(note.note_type, 'generic') send_mail_jinja(subject, 'comm/emails/%s.html' % mail_template, get_mail_context(note, None), recipient_list=[settings.MKT_REVIEWS_EMAIL], from_email=settings.MKT_REVIEWERS_EMAIL, perm_setting='app_reviewed')
def email_recipients(recipients, note, template=None, extra_context=None): """ Given a list of tuple of user_id/user_email, email bunch of people. note -- commbadge note, the note type determines which email to use. template -- override which template we use. """ subject = '%s: %s' % (unicode( comm.NOTE_TYPES[note.note_type]), note.thread.obj.name) for email, user_id, tok in tokenize_recipients(recipients, note.thread): headers = {} if tok: headers['Reply-To'] = '{0}{1}@{2}'.format(comm.REPLY_TO_PREFIX, tok, settings.POSTFIX_DOMAIN) # Get the appropriate mail template. mail_template = template or comm.COMM_MAIL_MAP.get( note.note_type, 'generic') # Send mail. context = get_mail_context(note, user_id) context.update(extra_context or {}) send_mail_jinja(subject, 'comm/emails/%s.html' % mail_template, context, recipient_list=[email], from_email=settings.MKT_REVIEWERS_EMAIL, perm_setting='app_reviewed', headers=headers)
def email_daily_ratings(): """ Does email for yesterday's ratings (right after the day has passed). Sends an email containing all reviews for that day for certain app. """ dt = datetime.datetime.today() - datetime.timedelta(1) yesterday = datetime.datetime(dt.year, dt.month, dt.day, 0, 0, 0) today = yesterday + datetime.timedelta(1) pretty_date = '%04d-%02d-%02d' % (dt.year, dt.month, dt.day) yesterday_reviews = Review.objects.filter(created__gte=yesterday, created__lt=today) # For each app in yesterday's set of reviews, gather reviews and email out. apps = set(review.addon for review in yesterday_reviews) for app in apps: # Email all reviews in one email for current app in loop. author_emails = app.authors.values_list('email', flat=True) subject = 'Firefox Marketplace reviews for %s on %s' % (app.name, pretty_date) context = {'reviews': (yesterday_reviews.filter(addon=app). order_by('-created')), 'base_url': settings.SITE_URL, 'pretty_date': pretty_date} send_mail_jinja(subject, 'ratings/emails/daily_digest.html', context, recipient_list=author_emails, perm_setting='app_new_review', async=True)
def send_mail_comm(note): """ Email utility used globally by the Communication Dashboard to send emails. Given a note (its actions and permissions), recipients are determined and emails are sent to appropriate people. """ log.info(u'Sending emails for %s' % note.thread.obj) if note.note_type in comm.EMAIL_SENIOR_REVIEWERS_AND_DEV: # Email senior reviewers (such as for escalations). rev_template = comm.EMAIL_SENIOR_REVIEWERS_AND_DEV[note.note_type][ 'reviewer'] email_recipients(get_senior_reviewers(), note, template=rev_template) # Email developers (such as for escalations). dev_template = comm.EMAIL_SENIOR_REVIEWERS_AND_DEV[note.note_type][ 'developer'] email_recipients(get_developers(note), note, template=dev_template) else: email_recipients(get_recipients(note), note) # Also send mail to the fallback emailing list. if note.note_type == comm.DEVELOPER_COMMENT: subject = '%s: %s' % (unicode(comm.NOTE_TYPES[note.note_type]), note.thread.obj.name) mail_template = comm.COMM_MAIL_MAP.get(note.note_type, 'generic') send_mail_jinja(subject, 'comm/emails/%s.html' % mail_template, get_mail_context(note, None), recipient_list=[settings.MKT_REVIEWS_EMAIL], from_email=settings.MKT_REVIEWERS_EMAIL, perm_setting='app_reviewed')
def create_action(self, request, serializer): context_data = self.get_context_data(request, serializer) sender = getattr(request.user, 'email', settings.NOBODY_EMAIL) send_mail_jinja(u'Marketplace Feedback', 'account/email/feedback.txt', context_data, headers={'Reply-To': sender}, recipient_list=[settings.MKT_APPS_FEEDBACK_EMAIL])
def send_tarako_mail(review): if not waffle.switch_is_active('comm-dashboard'): send_mail_jinja( 'Low-memory devices review {passed}'.format( passed='passed' if review.passed else 'failed'), 'reviewers/emails/tarako_review_complete.txt', {'review': review}, recipient_list=[a.email for a in review.app.authors.all()], from_email=settings.MKT_REVIEWERS_EMAIL)
def send_reviewer_mail(subject, template, context, emails, perm_setting=None, cc=None, attachments=None, reply_to=None): if not reply_to: reply_to = settings.MKT_REVIEWERS_EMAIL # Link to our newfangled "Account Settings" page. manage_url = absolutify('/settings') + '#notifications' send_mail_jinja(subject, template, context, recipient_list=emails, from_email=settings.MKT_REVIEWERS_EMAIL, use_blacklist=False, perm_setting=perm_setting, manage_url=manage_url, headers={'Reply-To': reply_to}, cc=cc, attachments=attachments)
def record_failed_refund(self, e, user): self.enqueue_refund(amo.REFUND_FAILED, user, rejection_reason=str(e)) self._switch_locale() self._mail('users/support/emails/refund-failed.txt', # L10n: the addon name. _(u'%s refund failed' % self.addon.name), {'name': self.addon.name}) send_mail_jinja( 'Refund failed', 'purchase/email/refund-failed.txt', {'name': self.user.email, 'error': str(e)}, settings.MARKETPLACE_EMAIL, [str(self.addon.support_email)], fail_silently=True)
def patch(self, request, *args, **kwargs): form = FailureForm(request.DATA) if not form.is_valid(): return Response(form.errors, status=status.HTTP_400_BAD_REQUEST) obj = self.get_object() data = { 'transaction_id': obj, 'transaction_url': absolutify( urlparams(reverse('mkt.developers.transactions'), transaction_id=obj.uuid)), 'url': form.cleaned_data['url'], 'retries': form.cleaned_data['attempts']} owners = obj.addon.authors.values_list('email', flat=True) send_mail_jinja('Payment notification failure.', 'webpay/failure.txt', data, recipient_list=owners) return Response(status=status.HTTP_202_ACCEPTED)
def region_email(ids, region_ids, **kw): regions = [REGIONS_CHOICES_ID_DICT[id] for id in region_ids] region_names = regions = sorted([unicode(r.name) for r in regions]) # Format the region names with commas and fanciness. if len(regions) == 2: suffix = 'two' region_names = ' '.join([regions[0], _(u'and'), regions[1]]) else: if len(regions) == 1: suffix = 'one' elif len(regions) > 2: suffix = 'many' region_names[-1] = _(u'and') + ' ' + region_names[-1] region_names = ', '.join(region_names) log.info('[%s@%s] Emailing devs about new region(s): %s.' % (len(ids), region_email.rate_limit, region_names)) for id_ in ids: log.info('[Webapp:%s] Emailing devs about new region(s): %s.' % (id_, region_names)) product = Webapp.objects.get(id=id_) to = set(product.authors.values_list('email', flat=True)) if len(regions) == 1: subject = _(u'{region} region added to the Firefox Marketplace' ).format(region=regions[0]) else: subject = _(u'New regions added to the Firefox Marketplace') dev_url = absolutify(product.get_dev_url('edit'), settings.SITE_URL) + '#details' context = { 'app': product.name, 'regions': region_names, 'dev_url': dev_url } send_mail_jinja('%s: %s' % (product.name, subject), 'developers/emails/new_regions_%s.ltxt' % suffix, context, recipient_list=to, perm_setting='app_regions')
def region_email(ids, region_ids, **kw): regions = [REGIONS_CHOICES_ID_DICT[id] for id in region_ids] region_names = regions = sorted([unicode(r.name) for r in regions]) # Format the region names with commas and fanciness. if len(regions) == 2: suffix = 'two' region_names = ' '.join([regions[0], _(u'and'), regions[1]]) else: if len(regions) == 1: suffix = 'one' elif len(regions) > 2: suffix = 'many' region_names[-1] = _(u'and') + ' ' + region_names[-1] region_names = ', '.join(region_names) log.info('[%s@%s] Emailing devs about new region(s): %s.' % (len(ids), region_email.rate_limit, region_names)) for id_ in ids: log.info('[Webapp:%s] Emailing devs about new region(s): %s.' % (id_, region_names)) product = Webapp.objects.get(id=id_) to = set(product.authors.values_list('email', flat=True)) if len(regions) == 1: subject = _( u'{region} region added to the Firefox Marketplace').format( region=regions[0]) else: subject = _(u'New regions added to the Firefox Marketplace') dev_url = absolutify(product.get_dev_url('edit'), settings.SITE_URL) + '#details' context = {'app': product.name, 'regions': region_names, 'dev_url': dev_url} send_mail_jinja('%s: %s' % (product.name, subject), 'developers/emails/new_regions_%s.ltxt' % suffix, context, recipient_list=to, perm_setting='app_regions')
def region_email(ids, region_ids, **kw): regions = [REGIONS_CHOICES_ID_DICT[id] for id in region_ids] region_names = regions = sorted([unicode(r.name) for r in regions]) # Format the region names with commas and fanciness. if len(regions) == 2: suffix = "two" region_names = " ".join([regions[0], _(u"and"), regions[1]]) else: if len(regions) == 1: suffix = "one" elif len(regions) > 2: suffix = "many" region_names[-1] = _(u"and") + " " + region_names[-1] region_names = ", ".join(region_names) log.info("[%s@%s] Emailing devs about new region(s): %s." % (len(ids), region_email.rate_limit, region_names)) for id_ in ids: log.info("[Webapp:%s] Emailing devs about new region(s): %s." % (id_, region_names)) product = Webapp.objects.get(id=id_) to = set(product.authors.values_list("email", flat=True)) if len(regions) == 1: subject = _(u"{region} region added to the Firefox Marketplace").format(region=regions[0]) else: subject = _(u"New regions added to the Firefox Marketplace") dev_url = absolutify(product.get_dev_url("edit"), settings.SITE_URL) + "#details" context = {"app": product.name, "regions": region_names, "dev_url": dev_url} send_mail_jinja( "%s: %s" % (product.name, subject), "developers/emails/new_regions_%s.ltxt" % suffix, context, recipient_list=to, perm_setting="app_regions", )
def email_buyer_refund_approved(contrib): send_mail_jinja('Your refund request for %s has been approved!' % contrib.addon.name, 'lookup/emails/refund-approved.txt', {'name': contrib.addon.name}, recipient_list=[contrib.user.email]),
def email_buyer_refund_pending(contrib): send_mail_jinja('Your refund request for %s is now being processed' % contrib.addon.name, 'lookup/emails/refund-pending.txt', {'name': contrib.addon.name}, recipient_list=[contrib.user.email]),