def email_buyer_refund_pending(contrib): # Email buyer. send_mail_jinja('Your refund request for %s is now being processed' % contrib.addon.name, 'support/emails/refund-pending.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], ),
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. """ if not waffle.switch_is_active('ratings'): return 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')
def mail_pending_refunds(): # First find all the pending refunds and the addons for them. pending = dict((Refund.objects.filter(status=amo.REFUND_PENDING) .values_list('contribution__addon_id') .annotate(Count('id')))) if not pending: log.info('No refunds to email') return log.info('Mailing pending refunds: %s refunds found' % len(pending)) # Find all owners of those addons. users = (AddonUser.objects.filter(role=amo.AUTHOR_ROLE_OWNER, addon__in=pending.keys()) .values_list('addon_id', 'user__email')) # Group up the owners. An owner could have more than one addon and each # addon can have more than one owner. owners = {} for addon_id, email in users: owners.setdefault(email, []) owners[email].append(addon_id) # Send the emails out. for owner, addon_ids in owners.items(): log.info('Sending refund emails to: %s about %s' % (email, ', '.join([str(i) for i in addon_ids]))) addons = Addon.objects.filter(pk__in=addon_ids) ctx = {'addons': addons, 'refunds': pending, 'site_url': settings.SITE_URL} send_mail_jinja('Pending refund requests at the Firefox Marketplace', 'market/emails/refund-nag.txt', ctx, from_email=settings.NOBODY_EMAIL, recipient_list=[owner])
def account_feedback(request): form = forms.FeedbackForm(request.POST or None) if request.method == 'POST' and form.is_valid(): feedback = form.cleaned_data['feedback'] platform = form.cleaned_data['platform'] chromeless = form.cleaned_data['chromeless'] context = { 'user': request.amo_user, 'user_agent': request.META['HTTP_USER_AGENT'], 'ip_address': request.META['REMOTE_ADDR'], 'feedback': feedback, 'platform': platform, 'chromeless': chromeless } send_mail_jinja(u'Marketplace Feedback', 'account/email/feedback.txt', context, request.amo_user.email, [settings.MKT_FEEDBACK_EMAIL]) if request.is_ajax(): return http.HttpResponse(json.dumps({'status': 'win'}), content_type='application/json') amo.messages.success(request, _('Feedback sent.')) return redirect(reverse('account.feedback')) return jingo.render(request, 'account/feedback.html', {'form': form})
def send_mail(subject, template, context, emails, perm_setting=None, cc=None): # Link to our newfangled "Account Settings" page. manage_url = absolutify(reverse('account.settings')) + '#notifications' send_mail_jinja(subject, template, context, recipient_list=emails, from_email=settings.NOBODY_EMAIL, use_blacklist=False, perm_setting=perm_setting, manage_url=manage_url, headers={'Reply-To': settings.MKT_REVIEWERS_EMAIL}, cc=cc)
def notify_developers_of_failure(app, error_message, has_link=False): if (app.status not in amo.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, 'MKT_SUPPORT_EMAIL': settings.MKT_SUPPORT_EMAIL, '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 feedback(request): form = forms.FeedbackForm(request.POST or None, request=request) if request.method == 'POST' and form.is_valid(): feedback = form.cleaned_data['feedback'] platform = form.cleaned_data['platform'] chromeless = form.cleaned_data['chromeless'] from_url = form.cleaned_data['from_url'] context = {'user': request.amo_user, 'user_agent': request.META.get('HTTP_USER_AGENT', ''), 'ip_address': request.META.get('REMOTE_ADDR', ''), 'feedback': feedback, 'platform': platform, 'from_url': from_url, 'chromeless': chromeless} send_mail_jinja( u'Marketplace Feedback', 'account/email/feedback.txt', context, request.amo_user.email if request.amo_user else '*****@*****.**', [settings.MKT_FEEDBACK_EMAIL]) if from_url == '': from_url = reverse('site.feedback') amo.messages.success(request, _('Feedback sent. Thanks!')) return redirect(from_url) return jingo.render(request, 'account/feedback.html', {'form': form})
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 feedback(request): form = forms.FeedbackForm(request.POST or None, request=request) if request.method == "POST" and form.is_valid(): feedback = form.cleaned_data["feedback"] platform = form.cleaned_data["platform"] chromeless = form.cleaned_data["chromeless"] from_url = form.cleaned_data["from_url"] context = { "user": request.amo_user, "user_agent": request.META.get("HTTP_USER_AGENT", ""), "ip_address": request.META.get("REMOTE_ADDR", ""), "feedback": feedback, "platform": platform, "from_url": from_url, "chromeless": chromeless, } send_mail_jinja( u"Marketplace Feedback", "account/email/feedback.txt", context, request.amo_user.email if request.amo_user else "*****@*****.**", [settings.MKT_FEEDBACK_EMAIL], ) if from_url == "": from_url = reverse("site.feedback") amo.messages.success(request, _("Feedback sent. Thanks!")) return redirect(from_url) return jingo.render(request, "account/feedback.html", {"form": form})
def mail_pending_refunds(): # First find all the pending refunds and the addons for them. pending = dict( (Refund.objects.filter(status=amo.REFUND_PENDING).values_list("contribution__addon_id").annotate(Count("id"))) ) if not pending: log.info("No refunds to email") return log.info("Mailing pending refunds: %s refunds found" % len(pending)) # Find all owners of those addons. users = AddonUser.objects.filter(role=amo.AUTHOR_ROLE_OWNER, addon__in=pending.keys()).values_list( "addon_id", "user__email" ) # Group up the owners. An owner could have more than one addon and each # addon can have more than one owner. owners = {} for addon_id, email in users: owners.setdefault(email, []) owners[email].append(addon_id) # Send the emails out. for owner, addon_ids in owners.items(): log.info("Sending refund emails to: %s about %s" % (email, ", ".join([str(i) for i in addon_ids]))) addons = Addon.objects.filter(pk__in=addon_ids) ctx = {"addons": addons, "refunds": pending, "site_url": settings.SITE_URL} send_mail_jinja( "Pending refund requests at the Mozilla Marketplace", "market/emails/refund-nag.txt", ctx, from_email=settings.NOBODY_EMAIL, recipient_list=[owner], )
def send_purchase_receipt(contrib_id, **kw): """ Sends an email to the purchaser of the app. """ contrib = Contribution.objects.get(pk=contrib_id) with contrib.user.activate_lang(): # L10n: {0} is the app name. subject = _('Receipt for {0}') % contrib.addon.name data = { 'app_name': contrib.addon.name, 'authors': ', '.join([ author.display_name for author in contrib.addon.authors.all() ]), 'date': datetime(contrib.created.date()), 'purchases': absolutify(reverse('account.purchases')), 'support_url': contrib.addon.support_url, 'terms_of_service_url': absolutify(reverse('site.terms')), 'transaction_id': contrib.uuid } log.info('Sending email about purchase: %s' % contrib_id) send_mail_jinja(subject, 'purchase/receipt.txt', data, recipient_list=[contrib.user.email])
def new_payments_region_email(ids, region_slug, **kw): region_name = dict(REGIONS_CHOICES_SLUG)[region_slug].name log.info( '[%s@%s] Emailing paid-app devs about new region: %s.' % (len(ids), new_payments_region_email.rate_limit, unicode(region_name))) for id_ in ids: log.info('[Webapp:%s] Emailing paid-app devs about new region: %s.' % (id_, unicode(region_name))) app = Webapp.objects.get(id=id_) for author in app.authors.all(): to = [author.email] with author.activate_lang(): if author.lang is not None: lang = to_language(author.lang) with translation.override(lang): app = Webapp.objects.get(id=id_) context = { 'app': app.name, 'region': region_name, 'payments_url': app.get_dev_url('payments') } subject = _(u'{app}: {region} region added to the Firefox ' u'Marketplace').format(**context) send_mail_jinja(subject, 'developers/emails/new_payments_region.html', context, recipient_list=to, perm_setting='app_regions')
def account_feedback(request): form = forms.FeedbackForm(request.POST or None) if request.method == 'POST' and form.is_valid(): feedback = form.cleaned_data['feedback'] platform = form.cleaned_data['platform'] chromeless = form.cleaned_data['chromeless'] context = {'user': request.amo_user, 'user_agent': request.META.get('HTTP_USER_AGENT', ''), 'ip_address': request.META.get('REMOTE_ADDR', ''), 'feedback': feedback, 'platform': platform, 'chromeless': chromeless} send_mail_jinja( u'Marketplace Feedback', 'account/email/feedback.txt', context, request.amo_user.email if request.amo_user else '*****@*****.**', [settings.MKT_FEEDBACK_EMAIL]) if request.is_ajax(): return http.HttpResponse( json.dumps({'status': 'win'}), content_type='application/json') amo.messages.success(request, _('Feedback sent.')) return redirect(reverse('account.feedback')) return jingo.render(request, 'account/feedback.html', {'form': form})
def email_buyer_refund_approved(contrib): # Email buyer. send_mail_jinja('Your refund request for %s has been approved!' % contrib.addon.name, 'support/emails/refund-approved.txt', {'name': contrib.addon.name}, recipient_list=[contrib.user.email]),
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 new_payments_region_email(ids, region_slug, **kw): region_name = dict(REGIONS_CHOICES_SLUG)[region_slug].name log.info('[%s@%s] Emailing paid-app devs about new region: %s.' % (len(ids), new_payments_region_email.rate_limit, unicode(region_name))) for id_ in ids: log.info('[Webapp:%s] Emailing paid-app devs about new region: %s.' % (id_, unicode(region_name))) app = Webapp.objects.get(id=id_) for author in app.authors.all(): to = [author.email] with author.activate_lang(): if author.lang is not None: lang = to_language(author.lang) with translation.override(lang): app = Webapp.objects.get(id=id_) context = {'app': app.name, 'region': region_name, 'payments_url': app.get_dev_url('payments')} subject = _(u'{app}: {region} region added to the Firefox ' u'Marketplace').format(**context) send_mail_jinja(subject, 'developers/emails/new_payments_region.html', context, recipient_list=to, perm_setting='app_regions')
def send_mail(subject, template, context, emails, perm_setting=None): # Link to our newfangled "Account Settings" page. manage_url = absolutify(reverse('account.settings')) + '#notifications' send_mail_jinja(subject, template, context, recipient_list=emails, from_email=settings.NOBODY_EMAIL, use_blacklist=False, perm_setting=perm_setting, manage_url=manage_url, headers={'Reply-To': settings.MKT_REVIEWERS_EMAIL})
def send_email(self, request, context_data): sender = getattr(request.amo_user, 'email', settings.NOBODY_EMAIL) send_mail_jinja(u'Marketplace Feedback', 'account/email/feedback.txt', context_data, from_email=sender, recipient_list=[settings.MKT_FEEDBACK_EMAIL])
def mail_thankyou(self, request=None): """ Mail a thankyou note for a completed contribution. Raises a ``ContributionError`` exception when the contribution is not complete or email addresses are not found. """ locale = self._switch_locale() # Thankyous must be enabled. if not self.addon.enable_thankyou: # Not an error condition, just return. return # Contribution must be complete. if not self.transaction_id: raise ContributionError("Transaction not complete") # Send from support_email, developer's email, or default. from_email = settings.DEFAULT_FROM_EMAIL if self.addon.support_email: from_email = str(self.addon.support_email) else: try: author = self.addon.listed_authors[0] if author.email and not author.emailhidden: from_email = author.email except (IndexError, TypeError): # This shouldn't happen, but the default set above is still ok. pass # We need the contributor's email. to_email = self.post_data["payer_email"] if not to_email: raise ContributionError("Empty payer email") # Make sure the url uses the right language. # Setting a prefixer would be nicer, but that requires a request. url_parts = self.addon.meet_the_dev_url().split("/") url_parts[1] = locale.language subject = _("Thanks for contributing to {addon_name}").format(addon_name=self.addon.name) # Send the email. send_mail_jinja( subject, "stats/contribution-thankyou-email.ltxt", { "thankyou_note": bleach.clean(unicode(self.addon.thankyou_note), strip=True), "addon_name": self.addon.name, "learn_url": "%s%s?src=emailinfo" % (settings.SITE_URL, "/".join(url_parts)), "domain": settings.DOMAIN, }, from_email, [to_email], fail_silently=True, perm_setting="dev_thanks", )
def _send_email(self, bundle): """ Send feedback email from the valid bundle. """ user = bundle.data.get('user') sender = getattr(user, 'email', settings.NOBODY_EMAIL) send_mail_jinja(u'Marketplace Feedback', 'account/email/feedback.txt', bundle.data, from_email=sender, recipient_list=[settings.MKT_FEEDBACK_EMAIL])
def send_email(self, request, context_data): sender = getattr(request.amo_user, "email", settings.NOBODY_EMAIL) send_mail_jinja( u"Marketplace Feedback", "account/email/feedback.txt", context_data, from_email=sender, recipient_list=[settings.MKT_FEEDBACK_EMAIL], )
def mail_thankyou(self, request=None): """ Mail a thankyou note for a completed contribution. Raises a ``ContributionError`` exception when the contribution is not complete or email addresses are not found. """ locale = self._switch_locale() # Thankyous must be enabled. if not self.addon.enable_thankyou: # Not an error condition, just return. return # Contribution must be complete. if not self.transaction_id: raise ContributionError('Transaction not complete') # Send from support_email, developer's email, or default. from_email = settings.DEFAULT_FROM_EMAIL if self.addon.support_email: from_email = str(self.addon.support_email) else: try: author = self.addon.listed_authors[0] if author.email and not author.emailhidden: from_email = author.email except (IndexError, TypeError): # This shouldn't happen, but the default set above is still ok. pass # We need the contributor's email. to_email = self.post_data['payer_email'] if not to_email: raise ContributionError('Empty payer email') # Make sure the url uses the right language. # Setting a prefixer would be nicer, but that requires a request. url_parts = self.addon.meet_the_dev_url().split('/') url_parts[1] = locale.language subject = _('Thanks for contributing to {addon_name}').format( addon_name=self.addon.name) # Send the email. send_mail_jinja( subject, 'stats/contribution-thankyou-email.ltxt', {'thankyou_note': bleach.clean(unicode(self.addon.thankyou_note), strip=True), 'addon_name': self.addon.name, 'learn_url': '%s%s?src=emailinfo' % (settings.SITE_URL, '/'.join(url_parts)), 'domain': settings.DOMAIN}, from_email, [to_email], fail_silently=True, perm_setting='dev_thanks')
def send_mail(cleaned_data, theme_lock): """ Send emails out for respective review actions taken on themes. """ theme = cleaned_data['theme'] action = cleaned_data['action'] comment = cleaned_data['comment'] reject_reason = cleaned_data['reject_reason'] reason = None if reject_reason: reason = rvw.THEME_REJECT_REASONS[reject_reason] elif action == rvw.ACTION_DUPLICATE: reason = _('Duplicate Submission') emails = set(theme.addon.authors.values_list('email', flat=True)) context = { 'theme': theme, 'base_url': settings.SITE_URL, 'reason': reason, 'comment': comment } subject = None if action == rvw.ACTION_APPROVE: subject = _('Thanks for submitting your Theme') template = 'reviewers/themes/emails/approve.html' theme.addon.update(status=amo.STATUS_PUBLIC) elif action == rvw.ACTION_REJECT: subject = _('A problem with your Theme submission') template = 'reviewers/themes/emails/reject.html' elif action == rvw.ACTION_DUPLICATE: subject = _('A problem with your Theme submission') template = 'reviewers/themes/emails/reject.html' elif action == rvw.ACTION_FLAG: subject = _('Theme submission flagged for review') template = 'reviewers/themes/emails/flag_reviewer.html' # Send the flagged email to themes email. emails = [settings.THEMES_EMAIL] elif action == rvw.ACTION_MOREINFO: subject = _('A question about your Theme submission') template = 'reviewers/themes/emails/moreinfo.html' context['reviewer_email'] = theme_lock.reviewer.email send_mail_jinja(subject, template, context, recipient_list=emails, from_email=settings.ADDONS_EMAIL, headers={'Reply-To': settings.THEMES_EMAIL})
def send_mail(cleaned_data, theme_lock): """ Send emails out for respective review actions taken on themes. """ theme = cleaned_data['theme'] action = cleaned_data['action'] comment = cleaned_data['comment'] reject_reason = cleaned_data['reject_reason'] reason = None if reject_reason: reason = rvw.THEME_REJECT_REASONS[reject_reason] elif action == rvw.ACTION_DUPLICATE: reason = _('Duplicate Submission') emails = set(theme.addon.authors.values_list('email', flat=True)) cc = settings.THEMES_EMAIL context = { 'theme': theme, 'base_url': settings.SITE_URL, 'reason': reason, 'comment': comment } subject = None if action == rvw.ACTION_APPROVE: subject = _('Thanks for submitting your Theme') template = 'reviewers/themes/emails/approve.html' theme.addon.update(status=amo.STATUS_PUBLIC) elif action == rvw.ACTION_REJECT: subject = _('A problem with your Theme submission') template = 'reviewers/themes/emails/reject.html' elif action == rvw.ACTION_DUPLICATE: subject = _('A problem with your Theme submission') template = 'reviewers/themes/emails/reject.html' elif action == rvw.ACTION_FLAG: subject = _('Theme submission flagged for review') template = 'reviewers/themes/emails/flag_reviewer.html' # Send the flagged email to themes email. emails = [settings.THEMES_EMAIL] cc = None elif action == rvw.ACTION_MOREINFO: subject = _('A question about your Theme submission') template = 'reviewers/themes/emails/moreinfo.html' context['reviewer_email'] = theme_lock.reviewer.email send_mail_jinja(subject, template, context, recipient_list=emails, cc=cc, from_email=settings.ADDONS_EMAIL, headers={'Reply-To': settings.THEMES_EMAIL})
def send_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 _send_email(self, bundle): """ Send feedback email from the valid bundle. """ user = bundle.data.get("user") sender = getattr(user, "email", settings.NOBODY_EMAIL) send_mail_jinja( u"Marketplace Feedback", "account/email/feedback.txt", bundle.data, from_email=sender, recipient_list=[settings.MKT_FEEDBACK_EMAIL], )
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', 'devhub/email/refund-failed.txt', {'name': self.user.email, 'error': str(e)}, settings.MARKETPLACE_EMAIL, [str(self.addon.support_email)], fail_silently=True)
def record_failed_refund(self, e): self.enqueue_refund(amo.REFUND_FAILED, 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', 'devhub/email/refund-failed.txt', {'name': self.user.email, 'error': str(e)}, settings.MARKETPLACE_EMAIL, [str(self.addon.support_email)], fail_silently=True)
def support_mail(subject, template, context, sender, recipients): try: return send_mail_jinja(subject, template, context, from_email=sender, recipient_list=recipients) except SMTPRecipientsRefused, e: log.error('Tried to send mail from %s to %s: %s' % (sender, ', '.join(recipients), e), exc_info=True)
def obj_update(self, bundle, **kw): form = FailureForm(bundle.data) if not form.is_valid(): raise self.form_errors(form) data = {'transaction_id': bundle.obj, 'transaction_url': absolutify( urlparams(reverse('mkt.developers.transactions'), transaction_id=bundle.obj.uuid)), 'url': form.cleaned_data['url'], 'retries': form.cleaned_data['attempts']} owners = bundle.obj.addon.authors.values_list('email', flat=True) send_mail_jinja('Payment notification failure.', 'webpay/failure.txt', data, recipient_list=owners) return bundle
def mail_thankyou(self, request=None): """ Mail a thankyou note for a completed contribution. Raises a ``ContributionError`` exception when the contribution is not complete or email addresses are not found. """ locale = self._switch_locale() # Thankyous must be enabled. if not self.addon.enable_thankyou: # Not an error condition, just return. return # Contribution must be complete. if not self.transaction_id: raise ContributionError('Transaction not complete') # Send from support_email, developer's email, or default. from_email = settings.DEFAULT_FROM_EMAIL if self.addon.support_email: from_email = str(self.addon.support_email) # We need the contributor's email. to_email = self.post_data['payer_email'] if not to_email: raise ContributionError('Empty payer email') # Make sure the url uses the right language. # Setting a prefixer would be nicer, but that requires a request. url_parts = self.addon.meet_the_dev_url().split('/') url_parts[1] = locale.language subject = _('Thanks for contributing to {addon_name}').format( addon_name=self.addon.name) # Send the email. send_mail_jinja( subject, 'stats/contribution-thankyou-email.ltxt', {'thankyou_note': bleach.clean(unicode(self.addon.thankyou_note), strip=True), 'addon_name': self.addon.name, 'learn_url': '%s%s?src=emailinfo' % (settings.SITE_URL, '/'.join(url_parts)), 'domain': settings.DOMAIN}, from_email, [to_email], fail_silently=True, perm_setting='dev_thanks')
def record_failed_refund(self, e): refund = self.enqueue_refund(amo.REFUND_FAILED, 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", "devhub/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 send_purchase_receipt(contrib_id, **kw): """ Sends an email to the purchaser of the app. """ contrib = Contribution.objects.get(pk=contrib_id) # TODO: localize when 833049 is done. subject = u'Receipt for %s' % contrib.addon.name data = {'app_name': contrib.addon.name, 'date': contrib.created.date(), # TODO: localize this properly. 'authors': contrib.addon.authors, 'purchases': absolutify(reverse('account.purchases')), 'support_url': contrib.addon.support_url, 'terms_of_service_url': absolutify(reverse('site.terms')), 'transaction_id': contrib.uuid} log.info('Sending email about purchase: %s' % contrib_id) send_mail_jinja(subject, 'purchase/receipt.txt', data, recipient_list=[contrib.user.email])
def region_email(ids, regions, **kw): 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, regions, **kw): 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 send_purchase_receipt(contrib_id, **kw): """ Sends an email to the purchaser of the app. """ contrib = Contribution.objects.get(pk=contrib_id) with contrib.user.activate_lang(): # L10n: {0} is the app name. subject = _('Receipt for {0}') % contrib.addon.name data = { 'app_name': contrib.addon.name, 'authors': ', '.join([author.display_name for author in contrib.addon.authors.all()]), 'date': datetime(contrib.created.date()), 'purchases': absolutify('/purchases'), 'support_url': contrib.addon.support_url, 'terms_of_service_url': absolutify(reverse('site.terms')), 'transaction_id': contrib.uuid } log.info('Sending email about purchase: %s' % contrib_id) send_mail_jinja(subject, 'purchase/receipt.txt', data, recipient_list=[contrib.user.email])
def obj_update(self, bundle, **kw): form = FailureForm(bundle.data) if not form.is_valid(): raise self.form_errors(form) data = { 'transaction_id': bundle.obj, 'transaction_url': absolutify( urlparams(reverse('mkt.developers.transactions'), transaction_id=bundle.obj.uuid)), 'url': form.cleaned_data['url'], 'retries': form.cleaned_data['attempts'] } owners = bundle.obj.addon.authors.values_list('email', flat=True) send_mail_jinja('Payment notification failure.', 'webpay/failure.txt', data, recipient_list=owners) return bundle
def mail_pending_refunds(): # First find all the pending refunds and the addons for them. pending = dict( (Refund.objects.filter(status=amo.REFUND_PENDING).values_list( 'contribution__addon_id').annotate(Count('id')))) if not pending: log.info('No refunds to email') return log.info('Mailing pending refunds: %s refunds found' % len(pending)) # Find all owners of those addons. users = (AddonUser.objects.filter(role=amo.AUTHOR_ROLE_OWNER, addon__in=pending.keys()).values_list( 'addon_id', 'user__email')) # Group up the owners. An owner could have more than one addon and each # addon can have more than one owner. owners = {} for addon_id, email in users: owners.setdefault(email, []) owners[email].append(addon_id) # Send the emails out. for owner, addon_ids in owners.items(): log.info('Sending refund emails to: %s about %s' % (email, ', '.join([str(i) for i in addon_ids]))) addons = Addon.objects.filter(pk__in=addon_ids) ctx = { 'addons': addons, 'refunds': pending, 'site_url': settings.SITE_URL } send_mail_jinja('Pending refund requests at the Mozilla Marketplace', 'market/emails/refund-nag.txt', ctx, from_email=settings.NOBODY_EMAIL, recipient_list=[owner])
def email_buyer_refund_approved(contrib): # Email buyer. send_mail_jinja( 'Your refund request for %s has been approved!' % contrib.addon.name, 'support/emails/refund-approved.txt', {'name': contrib.addon.name}, recipient_list=[contrib.user.email]),
def send_mail(cleaned_data, theme_lock): """ Send emails out for respective review actions taken on themes. """ theme = cleaned_data["theme"] action = cleaned_data["action"] reject_reason = cleaned_data["reject_reason"] reason = None if reject_reason: reason = rvw.THEME_REJECT_REASONS[reject_reason] comment = cleaned_data["comment"] emails = set(theme.addon.authors.values_list("email", flat=True)) context = {"theme": theme, "base_url": settings.SITE_URL, "reason": reason, "comment": comment} subject = None if action == rvw.ACTION_APPROVE: subject = _("Thanks for submitting your Theme") template = "reviewers/themes/emails/approve.html" theme.addon.update(status=amo.STATUS_PUBLIC) elif action == rvw.ACTION_REJECT: subject = _("A problem with your Theme submission") template = "reviewers/themes/emails/reject.html" theme.addon.update(status=amo.STATUS_REJECTED) reason = rvw.THEME_REJECT_REASONS[reject_reason] elif action == rvw.ACTION_DUPLICATE: subject = _("A problem with your Theme submission") template = "reviewers/themes/emails/reject.html" theme.addon.update(status=amo.STATUS_REJECTED) reason = "Duplicate" elif action == rvw.ACTION_FLAG: subject = _("Theme submission flagged for review") template = "reviewers/themes/emails/flag_reviewer.html" emails = [settings.SENIOR_EDITORS_EMAIL] theme.addon.update(status=amo.STATUS_REVIEW_PENDING) # Send another email to the user notifying them that their Theme has # been flagged. send_mail_jinja( _("A problem with your Theme submission"), "reviewers/themes/emails/flag_user.html", context, recipient_list=emails, headers={"Reply-To": theme_lock.reviewer.email}, ) elif action == rvw.ACTION_MOREINFO: subject = _("A question about your Theme submission") template = "reviewers/themes/emails/moreinfo.html" context["reviewer_email"] = theme_lock.reviewer.email theme.addon.update(status=amo.STATUS_REVIEW_PENDING) amo.log( amo.LOG.THEME_REVIEW, theme.addon, details={"action": action, "reject_reason": reject_reason, "comment": comment}, user=theme_lock.reviewer, ) log.info("Theme %s (%s) - %s" % (theme.addon.name, theme.id, action)) theme.approve = datetime.datetime.now() theme.save() send_mail_jinja(subject, template, context, recipient_list=emails, headers={"Reply-To": theme_lock.reviewer.email})
def send_mail(cleaned_data, theme_lock): """ Send emails out for respective review actions taken on themes. """ theme = cleaned_data['theme'] action = cleaned_data['action'] reject_reason = cleaned_data['reject_reason'] reason = None if reject_reason: reason = rvw.THEME_REJECT_REASONS[reject_reason] elif action == rvw.ACTION_DUPLICATE: reason = _('Duplicate Submission') comment = cleaned_data['comment'] emails = set(theme.addon.authors.values_list('email', flat=True)) cc = settings.THEMES_EMAIL context = { 'theme': theme, 'base_url': settings.SITE_URL, 'reason': reason, 'comment': comment } subject = None if action == rvw.ACTION_APPROVE: subject = _('Thanks for submitting your Theme') template = 'reviewers/themes/emails/approve.html' theme.addon.update(status=amo.STATUS_PUBLIC) elif action == rvw.ACTION_REJECT: subject = _('A problem with your Theme submission') template = 'reviewers/themes/emails/reject.html' theme.addon.update(status=amo.STATUS_REJECTED) elif action == rvw.ACTION_DUPLICATE: subject = _('A problem with your Theme submission') template = 'reviewers/themes/emails/reject.html' theme.addon.update(status=amo.STATUS_REJECTED) elif action == rvw.ACTION_FLAG: subject = _('Theme submission flagged for review') template = 'reviewers/themes/emails/flag_reviewer.html' theme.addon.update(status=amo.STATUS_REVIEW_PENDING) # Send another email to the user notifying them that their Theme has # been flagged. send_mail_jinja(_('A problem with your Theme submission'), 'reviewers/themes/emails/flag_user.html', context, recipient_list=emails, headers={'Reply-To': settings.THEMES_EMAIL}) # Send the other email below to themes email. emails = [settings.THEMES_EMAIL] cc = None elif action == rvw.ACTION_MOREINFO: subject = _('A question about your Theme submission') template = 'reviewers/themes/emails/moreinfo.html' context['reviewer_email'] = theme_lock.reviewer.email theme.addon.update(status=amo.STATUS_REVIEW_PENDING) amo.log(amo.LOG.THEME_REVIEW, theme.addon, details={ 'action': action, 'reject_reason': reject_reason, 'comment': comment }, user=theme_lock.reviewer) log.info('Theme %s (%s) - %s' % (theme.addon.name, theme.id, action)) theme.approve = datetime.datetime.now() theme.save() send_mail_jinja(subject, template, context, recipient_list=emails, cc=cc, headers={'Reply-To': settings.THEMES_EMAIL})
def send_mail(cleaned_data, theme_lock): """ Send emails out for respective review actions taken on themes. """ theme = cleaned_data['theme'] action = cleaned_data['action'] reject_reason = cleaned_data['reject_reason'] reason = None if reject_reason: reason = rvw.THEME_REJECT_REASONS[reject_reason] comment = cleaned_data['comment'] emails = set(theme.addon.authors.values_list('email', flat=True)) context = { 'theme': theme, 'base_url': settings.SITE_URL, 'reason': reason, 'comment': comment } subject = None if action == rvw.ACTION_APPROVE: subject = _('Thanks for submitting your Theme') template = 'reviewers/themes/emails/approve.html' theme.addon.update(status=amo.STATUS_PUBLIC) elif action == rvw.ACTION_REJECT: subject = _('A problem with your Theme submission') template = 'reviewers/themes/emails/reject.html' theme.addon.update(status=amo.STATUS_REJECTED) reason = (rvw.THEME_REJECT_REASONS[reject_reason]) elif action == rvw.ACTION_DUPLICATE: subject = _('A problem with your Theme submission') template = 'reviewers/themes/emails/reject.html' theme.addon.update(status=amo.STATUS_REJECTED) reason = 'Duplicate' elif action == rvw.ACTION_FLAG: subject = _('Theme submission flagged for review') template = 'reviewers/themes/emails/flag_reviewer.html' emails = [settings.THEMES_EMAIL] theme.addon.update(status=amo.STATUS_REVIEW_PENDING) # Send another email to the user notifying them that their Theme has # been flagged. send_mail_jinja(_('A problem with your Theme submission'), 'reviewers/themes/emails/flag_user.html', context, recipient_list=emails, headers={'Reply-To': settings.THEMES_EMAIL}) elif action == rvw.ACTION_MOREINFO: subject = _('A question about your Theme submission') template = 'reviewers/themes/emails/moreinfo.html' context['reviewer_email'] = theme_lock.reviewer.email theme.addon.update(status=amo.STATUS_REVIEW_PENDING) amo.log(amo.LOG.THEME_REVIEW, theme.addon, details={ 'action': action, 'reject_reason': reject_reason, 'comment': comment}, user=theme_lock.reviewer) log.info('Theme %s (%s) - %s' % (theme.addon.name, theme.id, action)) theme.approve = datetime.datetime.now() theme.save() send_mail_jinja(subject, template, context, recipient_list=emails, headers={'Reply-To': settings.THEMES_EMAIL})