def add(request): "Displays/processes a form to create a collection." data = {} if request.method == 'POST': form = forms.CollectionForm( request.POST, request.FILES, initial=initial_data_from_request(request)) aform = forms.AddonsForm(request.POST) if form.is_valid(): collection = form.save(default_locale=request.LANG) collection.save() if aform.is_valid(): aform.save(collection) title = _("Collection created!") msg = _("""Your new collection is shown below. You can <a href="%(url)s">edit additional settings</a> if you'd like.""") % {'url': collection.edit_url()} messages.success(request, title, msg, extra_tags='collection', message_safe=True) log.info('Created collection %s' % collection.id) return http.HttpResponseRedirect(collection.get_url_path()) else: data['addons'] = Addon.objects.filter(pk__in=aform.clean_addon()) data['comments'] = aform.clean_addon_comment() else: form = forms.CollectionForm() data.update(form=form, filter=get_filter(request)) return render(request, 'bandwagon/add.html', data)
def in_app_config(request, addon_id, addon, webapp=True): inapp = addon.premium_type in amo.ADDON_INAPPS if not inapp: messages.error(request, _('Your app is not configured for in-app payments.')) return redirect(reverse('mkt.developers.apps.payments', args=[addon.app_slug])) try: account = addon.app_payment_account except ObjectDoesNotExist: messages.error(request, _('No payment account for this app.')) return redirect(reverse('mkt.developers.apps.payments', args=[addon.app_slug])) seller_config = get_seller_product(account) owner = acl.check_addon_ownership(request, addon) if request.method == 'POST': # Reset the in-app secret for the app. (client.api.generic .product(seller_config['resource_pk']) .patch(data={'secret': generate_key(48)})) messages.success(request, _('Changes successfully saved.')) return redirect(reverse('mkt.developers.apps.in_app_config', args=[addon.app_slug])) return jingo.render(request, 'developers/payments/in-app-config.html', {'addon': addon, 'owner': owner, 'seller_config': seller_config})
def monthly_pick(request): form = MonthlyPickFormSet(request.POST or None) if request.method == 'POST' and form.is_valid(): form.save() messages.success(request, 'Changes successfully saved.') return redirect('zadmin.monthly_pick') return jingo.render(request, 'zadmin/monthly_pick.html', dict(form=form))
def edit(request): webapp = settings.APP_PREVIEW # Don't use request.amo_user since it has too much caching. amouser = UserProfile.objects.get(pk=request.user.id) if request.method == 'POST': # ModelForm alters the instance you pass in. We need to keep a copy # around in case we need to use it below (to email the user) original_email = amouser.email form = forms.UserEditForm(request.POST, request.FILES, request=request, instance=amouser, webapp=webapp) if form.is_valid(): messages.success(request, _('Profile Updated')) if amouser.email != original_email: # Temporarily block email changes. if settings.APP_PREVIEW: messages.error(request, 'Error', 'You cannot change your email on the ' 'developer preview site.') return jingo.render(request, 'users/edit.html', {'form': form, 'amouser': amouser}) l = {'user': amouser, 'mail1': original_email, 'mail2': amouser.email} log.info(u"User (%(user)s) has requested email change from" "(%(mail1)s) to (%(mail2)s)" % l) messages.info(request, _('Email Confirmation Sent'), _(u'An email has been sent to {0} to confirm your new ' 'email address. For the change to take effect, you ' 'need to click on the link provided in this email. ' 'Until then, you can keep logging in with your ' 'current email address.').format(amouser.email)) domain = settings.DOMAIN token, hash = EmailResetCode.create(amouser.id, amouser.email) url = "%s%s" % (settings.SITE_URL, reverse('users.emailchange', args=[amouser.id, token, hash])) t = loader.get_template('users/email/emailchange.ltxt') c = {'domain': domain, 'url': url} send_mail(_('Please confirm your email address ' 'change at %s' % domain), t.render(Context(c)), None, [amouser.email], use_blacklist=False, real_email=True) # Reset the original email back. We aren't changing their # address until they confirm the new one amouser.email = original_email form.save() return redirect('users.edit') else: messages.error(request, _('Errors Found'), _('There were errors in the changes ' 'you made. Please correct them and ' 'resubmit.')) else: form = forms.UserEditForm(instance=amouser, webapp=webapp) return jingo.render(request, 'users/edit.html', {'form': form, 'amouser': amouser, 'webapp': webapp})
def refund_reason(request, contribution, wizard): addon = contribution.addon if not 'request' in wizard.get_progress(): return redirect('users.support', contribution.pk, 'request') if contribution.is_instant_refund(): paypal.refund(contribution.paykey) paypal_log.info('Refund issued for contribution %r' % contribution.pk) # Note: we have to wait for PayPal to issue an IPN before it's # completely refunded. messages.success(request, _('Refund is being processed.')) return redirect('users.purchases') form = forms.ContactForm(request.POST or None) if request.method == 'POST' and form.is_valid(): url = absolutify(urlparams(addon.get_dev_url('issue_refund'), transaction_id=contribution.transaction_id)) template = jingo.render_to_string(request, wizard.tpl('emails/refund-request.txt'), context={'addon': addon, 'form': form, 'user': request.amo_user, 'contribution': contribution, 'refund_url': url}) log.info('Refund request sent by user: %s for addon: %s' % (request.amo_user.pk, addon.pk)) # L10n: %s is the addon name. send_mail(_(u'New Refund Request for %s' % addon.name), template, settings.NOBODY_EMAIL, [smart_str(addon.support_email)]) return redirect(reverse('users.support', args=[contribution.pk, 'refund-sent'])) return wizard.render(request, wizard.tpl('refund.html'), {'form': form})
def paypal_setup(request, addon_id, addon, webapp): if addon.premium_type == amo.ADDON_FREE: messages.error(request, 'Your app does not use payments.') return redirect(addon.get_dev_url('payments')) paypal_form = PaypalSetupForm(request.POST or None) currency_form = CurrencyForm(request.POST or None, initial={'currencies': addon.premium.currencies if addon.premium else {}}) context = {'addon': addon, 'paypal_form': paypal_form, 'currency_form': currency_form} if request.POST.get('form') == 'paypal' and paypal_form.is_valid(): existing = paypal_form.cleaned_data['business_account'] if existing != 'yes': # Go create an account. # TODO: this will either become the API or something some better # URL for the future. return redirect(settings.PAYPAL_CGI_URL) else: # Go setup your details on paypal. addon.update(paypal_id=paypal_form.cleaned_data['email']) if addon.premium and addon.premium.paypal_permissions_token: addon.premium.update(paypal_permissions_token='') return redirect(addon.get_dev_url('paypal_setup_bounce')) if request.POST.get('form') == 'currency' and currency_form.is_valid(): currencies = currency_form.cleaned_data['currencies'] addon.premium.update(currencies=currencies) messages.success(request, _('Currencies updated.')) return redirect(addon.get_dev_url('paypal_setup')) return jingo.render(request, 'developers/payments/paypal-setup.html', context)
def issue_refund(request, addon_id, addon, webapp=False): txn_id = request.REQUEST.get('transaction_id') if not txn_id: raise http.Http404 form_enabled = True contribution = get_object_or_404(Contribution, transaction_id=txn_id, type__in=[amo.CONTRIB_PURCHASE, amo.CONTRIB_INAPP]) if (hasattr(contribution, 'refund') and contribution.refund.status not in (amo.REFUND_PENDING, amo.REFUND_FAILED)): # If it's not pending, we've already taken action. messages.error(request, _('Refund already processed.')) form_enabled = False elif request.method == 'POST': if 'issue' in request.POST: try: results = paypal.refund(contribution.paykey) except PaypalError, e: contribution.record_failed_refund(e) paypal_log.error('Refund failed for: %s' % txn_id, exc_info=True) messages.error(request, _('There was an error with ' 'the refund.')) return redirect(addon.get_dev_url('refunds')) for res in results: if res['refundStatus'] == 'ALREADY_REVERSED_OR_REFUNDED': paypal_log.debug( 'Refund attempt for already-refunded paykey: %s, %s' % (contribution.paykey, res['receiver.email'])) messages.error(request, _('Refund was previously issued; ' 'no action taken.')) return redirect(addon.get_dev_url('refunds')) elif res['refundStatus'] == 'NO_API_ACCESS_TO_RECEIVER': paypal_log.debug('Refund attempt for product %s with no ' 'refund token: %s, %s' % (contribution.addon.pk, contribution.paykey, res['receiver.email'])) messages.error(request, _("A refund can't be issued at this time. We've " "notified an admin; please try again later.")) return redirect(addon.get_dev_url('refunds')) contribution.mail_approved() refund = contribution.enqueue_refund(amo.REFUND_APPROVED) paypal_log.info('Refund %r issued for contribution %r' % (refund.pk, contribution.pk)) messages.success(request, _('Refund issued.')) else: contribution.mail_declined() # TODO: Consider requiring a rejection reason for declined refunds. refund = contribution.enqueue_refund(amo.REFUND_DECLINED) paypal_log.info('Refund %r declined for contribution %r' % (refund.pk, contribution.pk)) messages.success(request, _('Refund declined.')) return redirect(addon.get_dev_url('refunds'))
def preload_submit(request, addon_id, addon): if request.method == "POST": form = PreloadTestPlanForm(request.POST, request.FILES) if form.is_valid(): # Save test plan file. test_plan = request.FILES["test_plan"] # Figure the type to save it as (cleaned as pdf/xls from the form). filetype = mimetypes.guess_type(test_plan.name)[0] if "pdf" in filetype: filename = "test_plan_%s.pdf" else: filename = "test_plan_%s.xls" # Timestamp. filename = filename % str(time.time()).split(".")[0] save_test_plan(request.FILES["test_plan"], filename, addon) # Log test plan. PreloadTestPlan.objects.filter(addon=addon).update(status=amo.STATUS_DISABLED) PreloadTestPlan.objects.create(addon=addon, filename=filename) messages.success(request, _("Application for preload successfully submitted.")) return redirect(addon.get_dev_url("versions")) else: messages.error(request, _("There was an error with the form.")) else: form = PreloadTestPlanForm() return render(request, "developers/apps/preload/submit.html", {"addon": addon, "form": form})
def version_delete(request, addon_id, addon): version_id = request.POST.get('version_id') version = get_object_or_404(Version, pk=version_id, addon=addon) version.delete() messages.success(request, _('Version "{0}" deleted.').format(version.version)) return redirect(addon.get_dev_url('versions'))
def status(request, addon_id, addon, webapp=False): form = forms.AppAppealForm(request.POST, product=addon) upload_form = NewWebappForm(request.POST or None, is_packaged=True, addon=addon) if request.method == 'POST': if 'resubmit-app' in request.POST and form.is_valid(): form.save() messages.success(request, _('App successfully resubmitted.')) return redirect(addon.get_dev_url('versions')) elif 'upload-version' in request.POST and upload_form.is_valid(): ver = Version.from_upload(upload_form.cleaned_data['upload'], addon, [amo.PLATFORM_ALL]) log.info('[Webapp:%s] New version created id=%s from upload: %s' % (addon, ver.pk, upload_form.cleaned_data['upload'])) return redirect(addon.get_dev_url('versions.edit', args=[ver.pk])) ctx = {'addon': addon, 'webapp': webapp, 'form': form, 'upload_form': upload_form} if addon.status == amo.STATUS_REJECTED: try: entry = (AppLog.objects .filter(addon=addon, activity_log__action=amo.LOG.REJECT_VERSION.id) .order_by('-created'))[0] except IndexError: entry = None # This contains the rejection reason and timestamp. ctx['rejection'] = entry and entry.activity_log return jingo.render(request, 'developers/apps/status.html', ctx)
def _refresh_mdn(request): if settings.MDN_LAZY_REFRESH and 'refresh' in request.GET: # If you can delay this, please teach me. I give up. refresh_mdn_cache() messages.success(request, 'Pulling new content from MDN. Please check back in a few minutes.' ' Thanks for all your awesome work! Devs appreciate it!')
def hera(request): form = FlushForm(initial={'flushprefix': settings.SITE_URL}) boxes = [] configured = False # Default to not showing the form. for i in settings.HERA: hera = get_hera(i) r = {'location': urlparse(i['LOCATION'])[1], 'stats': False} if hera: r['stats'] = hera.getGlobalCacheInfo() configured = True boxes.append(r) if not configured: messages.error(request, "Hera is not (or mis-)configured.") form = None if request.method == 'POST' and hera: form = FlushForm(request.POST) if form.is_valid(): expressions = request.POST['flushlist'].splitlines() for url in expressions: num = flush_urls([url], request.POST['flushprefix'], True) msg = ("Flushed %d objects from front end cache for: %s" % (len(num), url)) log.info("[Hera] (user:%s) %s" % (request.user, msg)) messages.success(request, msg) return jingo.render(request, 'zadmin/hera.html', {'form': form, 'boxes': boxes})
def hera(request): form = FlushForm(initial={"flushprefix": site_settings.SITE_URL}) boxes = [] configured = False # Default to not showing the form. for i in site_settings.HERA: hera = get_hera(i) r = {"location": urlparse(i["LOCATION"])[1], "stats": False} if hera: r["stats"] = hera.getGlobalCacheInfo() configured = True boxes.append(r) if not configured: messages.error(request, "Hera is not (or mis-)configured.") form = None if request.method == "POST" and hera: form = FlushForm(request.POST) if form.is_valid(): expressions = request.POST["flushlist"].splitlines() for url in expressions: num = flush_urls([url], request.POST["flushprefix"], True) msg = "Flushed %d objects from front end cache for: %s" % (len(num), url) log.info("[Hera] (user:%s) %s" % (request.user, msg)) messages.success(request, msg) return jingo.render(request, "zadmin/hera.html", {"form": form, "boxes": boxes})
def ownership(request, addon_id, addon, webapp=False): # Authors. qs = AddonUser.objects.filter(addon=addon).order_by('position') user_form = forms.AuthorFormSet(request.POST or None, queryset=qs) if request.method == 'POST' and user_form.is_valid(): # Authors. authors = user_form.save(commit=False) for author in authors: action = None if not author.id or author.user_id != author._original_user_id: action = amo.LOG.ADD_USER_WITH_ROLE author.addon = addon elif author.role != author._original_role: action = amo.LOG.CHANGE_USER_WITH_ROLE author.save() if action: amo.log(action, author.user, author.get_role_display(), addon) if (author._original_user_id and author.user_id != author._original_user_id): amo.log(amo.LOG.REMOVE_USER_WITH_ROLE, (UserProfile, author._original_user_id), author.get_role_display(), addon) for author in user_form.deleted_objects: amo.log(amo.LOG.REMOVE_USER_WITH_ROLE, author.user, author.get_role_display(), addon) messages.success(request, _('Changes successfully saved.')) return redirect(addon.get_dev_url('owner')) ctx = dict(addon=addon, webapp=webapp, user_form=user_form) return jingo.render(request, 'developers/apps/owner.html', ctx)
def in_app_config(request, addon_id, addon, webapp=True): if addon.premium_type not in amo.ADDON_INAPPS: messages.error(request, 'Your app does not use payments.') return redirect(addon.get_dev_url('payments')) try: inapp_config = InappConfig.objects.get(addon=addon, status=amo.INAPP_STATUS_ACTIVE) except models.ObjectDoesNotExist: inapp_config = None inapp_form = InappConfigForm(request.POST or None, instance=inapp_config) if request.method == 'POST' and inapp_form.is_valid(): new_inapp = inapp_form.save(commit=False) new_inapp.addon = addon new_inapp.status = amo.INAPP_STATUS_ACTIVE if not new_inapp.public_key: new_inapp.public_key = InappConfig.generate_public_key() new_inapp.save() if not new_inapp.has_private_key(): new_inapp.set_private_key(InappConfig.generate_private_key()) messages.success(request, _('Changes successfully saved.')) return redirect(addon.get_dev_url('in_app_config')) return jingo.render(request, 'developers/payments/in-app-config.html', dict(addon=addon, inapp_form=inapp_form, inapp_config=inapp_config))
def paypal_setup_confirm(request, addon_id, addon, webapp, source='paypal'): # If you bounce through paypal as you do permissions changes set the # source to paypal. if source == 'paypal': msg = _('PayPal set up complete.') title = _('Confirm Details') button = _('Continue') # If you just hit this page from the Manage Paypal, show some less # wizardy stuff. else: msg = _('Changes saved.') title = _('Contact Details') button = _('Save') adp, created = AddonPaymentData.objects.safer_get_or_create(addon=addon) form = forms.PaypalPaymentData(request.POST or None, instance=adp) if request.method == 'POST' and form.is_valid(): adp.update(**form.cleaned_data) messages.success(request, msg) if source == 'paypal' and addon.is_incomplete() and addon.paypal_id: addon.mark_done() return redirect(addon.get_dev_url('paypal_setup')) return jingo.render(request, 'developers/payments/paypal-details-confirm.html', {'addon': addon, 'button': button, 'form': form, 'title': title})
def features(request): form = FeaturedCollectionFormSet(request.POST or None) if request.method == 'POST' and form.is_valid(): form.save(commit=False) messages.success(request, 'Changes successfully saved.') return redirect('zadmin.features') return jingo.render(request, 'zadmin/features.html', dict(form=form))
def issue_refund(request, addon_id, addon, webapp=False): txn_id = request.REQUEST.get("transaction_id") if not txn_id: raise http.Http404 form_enabled = True contribution = get_object_or_404( Contribution, transaction_id=txn_id, type__in=[amo.CONTRIB_PURCHASE, amo.CONTRIB_INAPP] ) if hasattr(contribution, "refund") and contribution.refund.status not in (amo.REFUND_PENDING, amo.REFUND_FAILED): # If it's not pending, we've already taken action. messages.error(request, _("Refund already processed.")) form_enabled = False elif request.method == "POST": if "issue" in request.POST: if waffle.flag_is_active(request, "solitude-payments"): try: response = client.post_refund(data={"uuid": contribution.transaction_id}) except client.Error, e: contribution.record_failed_refund(e) paypal_log.error("Refund failed for: %s" % txn_id, exc_info=True) messages.error(request, _("There was an error with " "the refund.")) return redirect(addon.get_dev_url("refunds")) results = response["response"] else: # TODO(solitude): remove this. try: results = paypal.refund(contribution.paykey) except PaypalError, e: contribution.record_failed_refund(e) paypal_log.error("Refund failed for: %s" % txn_id, exc_info=True) messages.error(request, _("There was an error with " "the refund.")) return redirect(addon.get_dev_url("refunds")) for res in results: if res["refundStatus"] == "ALREADY_REVERSED_OR_REFUNDED": paypal_log.debug( "Refund attempt for already-refunded paykey: %s, %s" % (contribution.paykey, res["receiver.email"]) ) messages.error(request, _("Refund was previously issued; " "no action taken.")) return redirect(addon.get_dev_url("refunds")) elif res["refundStatus"] == "NO_API_ACCESS_TO_RECEIVER": paypal_log.debug( "Refund attempt for product %s with no " "refund token: %s, %s" % (contribution.addon.pk, contribution.paykey, res["receiver.email"]) ) messages.error( request, _("A refund can't be issued at this time. We've " "notified an admin; please try again later."), ) return redirect(addon.get_dev_url("refunds")) contribution.mail_approved() amo.log(amo.LOG.REFUND_GRANTED, addon, contribution.user) refund = contribution.enqueue_refund(amo.REFUND_APPROVED) paypal_log.info("Refund %r issued for contribution %r" % (refund.pk, contribution.pk)) messages.success(request, _("Refund issued."))
def payments(request, addon_id, addon): charity = None if addon.charity_id == amo.FOUNDATION_ORG else addon.charity charity_form = forms.CharityForm(request.POST or None, instance=charity, prefix='charity') contrib_form = forms.ContribForm(request.POST or None, instance=addon, initial=forms.ContribForm.initial(addon)) profile_form = forms.ProfileForm(request.POST or None, instance=addon, required=True) if request.method == 'POST': if contrib_form.is_valid(): addon = contrib_form.save(commit=False) addon.wants_contributions = True valid = _save_charity(addon, contrib_form, charity_form) if not addon.has_full_profile(): valid &= profile_form.is_valid() if valid: profile_form.save() if valid: addon.save() messages.success(request, _('Changes successfully saved.')) amo.log(amo.LOG.EDIT_CONTRIBUTIONS, addon) return redirect('devhub.addons.payments', addon.slug) errors = charity_form.errors or contrib_form.errors or profile_form.errors if errors: messages.error(request, _('There were errors in your submission.')) return jingo.render(request, 'devhub/addons/payments.html', dict(addon=addon, charity_form=charity_form, errors=errors, contrib_form=contrib_form, profile_form=profile_form))
def payments(request, addon_id, addon): charity = None if addon.charity_id == amo.FOUNDATION_ORG else addon.charity charity_form = forms.CharityForm(request.POST or None, instance=charity, prefix='charity') contrib_form = forms.ContribForm(request.POST or None, instance=addon, initial=forms.ContribForm.initial(addon)) if request.method == 'POST': if contrib_form.is_valid(): addon, valid = contrib_form.save(commit=False), True addon.wants_contributions = True recipient = contrib_form.cleaned_data['recipient'] if recipient == 'dev': addon.charity = None elif recipient == 'moz': addon.charity_id = amo.FOUNDATION_ORG elif recipient == 'org': valid = charity_form.is_valid() if valid: addon.charity = charity_form.save() if valid: addon.save() messages.success(request, _('Changes successfully saved.')) return redirect('devhub.addons.payments', addon_id) if charity_form.errors or contrib_form.errors: messages.error(request, _('There were errors in your submission.')) return jingo.render(request, 'devhub/addons/payments.html', dict(addon=addon, charity_form=charity_form, contrib_form=contrib_form))
def spam(request): if not acl.action_allowed(request, 'Spam', 'Flag'): raise PermissionDenied spam = Spam() if request.method == 'POST': review = Review.objects.get(pk=request.POST['review']) if 'del_review' in request.POST: log.info('SPAM: %s' % review.id) delete(request, request.POST['addon'], review.id) messages.success(request, 'Deleted that review.') elif 'del_user' in request.POST: user = review.user log.info('SPAMMER: %s deleted %s' % (request.amo_user.username, user.username)) if not user.is_developer: Review.objects.filter(user=user).delete() user.anonymize() messages.success(request, 'Deleted that dirty spammer.') for reason in spam.reasons(): spam.redis.srem(reason, review.id) return http.HttpResponseRedirect(request.path) buckets = {} for reason in spam.reasons(): ids = spam.redis.smembers(reason) key = reason.split(':')[-1] buckets[key] = Review.objects.no_cache().filter(id__in=ids) reviews = dict((review.addon_id, review) for bucket in buckets.values() for review in bucket) for addon in Addon.objects.no_cache().filter(id__in=reviews): reviews[addon.id].addon = addon return render(request, 'reviews/spam.html', dict(buckets=buckets, review_perms=dict(is_admin=True)))
def content_ratings_edit(request, addon_id, addon): initial = {} try: app_info = addon.iarc_info initial['submission_id'] = app_info.submission_id initial['security_code'] = app_info.security_code except IARCInfo.DoesNotExist: pass form = IARCGetAppInfoForm(data=request.POST or None, initial=initial) if request.method == 'POST' and form.is_valid(): try: form.save(addon) messages.success(request, _('Content ratings successfully saved.')) return redirect(addon.get_dev_url('ratings')) except django_forms.ValidationError: pass # Fall through to show the form error. with amo.utils.no_translation(addon.default_locale): addon_delocalized = Addon.objects.get(pk=addon.pk) return jingo.render( request, 'developers/apps/ratings/ratings_edit.html', { 'addon': addon, 'app_name': addon_delocalized.name, 'form': form, 'now': datetime.now().strftime('%Y-%m-%d %H:%M:%S') })
def api(request): roles = request.amo_user.groups.filter(name='Admins').exists() f = APIConsumerForm() if roles: messages.error(request, _('Users with the admin role cannot use the API.')) elif request.method == 'POST': if 'delete' in request.POST: try: consumer = Access.objects.get(pk=request.POST.get('consumer')) consumer.delete() except Access.DoesNotExist: messages.error(request, _('No such API key.')) else: key = 'mkt:%s:%s:%s' % ( request.amo_user.pk, request.amo_user.email, Access.objects.filter(user=request.user).count()) access = Access.objects.create(key=key, user=request.user, secret=generate()) f = APIConsumerForm(request.POST, instance=access) if f.is_valid(): f.save() messages.success(request, _('New API key generated.')) else: access.delete() consumers = list(Access.objects.filter(user=request.user)) return jingo.render(request, 'developers/api.html', {'consumers': consumers, 'roles': roles, 'form': f})
def email_devs(request): form = DevMailerForm(request.POST or None) preview = EmailPreviewTopic(topic='email-devs') if preview.filter().count(): preview_csv = reverse('zadmin.email_preview_csv', args=[preview.topic]) else: preview_csv = None if request.method == 'POST' and form.is_valid(): data = form.cleaned_data qs = (AddonUser.objects.filter(role__in=(amo.AUTHOR_ROLE_DEV, amo.AUTHOR_ROLE_OWNER)) .exclude(user__email=None)) if data['recipients'] in ('payments', 'desktop_apps'): qs = qs.exclude(addon__status=amo.STATUS_DELETED) else: qs = qs.filter(addon__status__in=amo.LISTED_STATUSES) if data['recipients'] == 'eula': qs = qs.exclude(addon__eula=None) elif data['recipients'] in ('payments', 'payments_region_enabled', 'payments_region_disabled'): qs = qs.filter(addon__type=amo.ADDON_WEBAPP) qs = qs.exclude(addon__premium_type__in=(amo.ADDON_FREE, amo.ADDON_OTHER_INAPP)) if data['recipients'] == 'payments_region_enabled': qs = qs.filter(addon__enable_new_regions=True) elif data['recipients'] == 'payments_region_disabled': qs = qs.filter(addon__enable_new_regions=False) elif data['recipients'] == 'apps': qs = qs.filter(addon__type=amo.ADDON_WEBAPP) elif data['recipients'] == 'desktop_apps': qs = (qs.filter(addon__type=amo.ADDON_WEBAPP, addon__addondevicetype__device_type=amo.DEVICE_DESKTOP.id)) elif data['recipients'] == 'sdk': qs = qs.exclude(addon__versions__files__jetpack_version=None) elif data['recipients'] == 'all_extensions': qs = qs.filter(addon__type=amo.ADDON_EXTENSION) else: raise NotImplementedError('If you want to support emailing other ' 'types of developers, do it here!') if data['preview_only']: # Clear out the last batch of previewed emails. preview.filter().delete() total = 0 for emails in chunked(set(qs.values_list('user__email', flat=True)), 100): total += len(emails) tasks.admin_email.delay(emails, data['subject'], data['message'], preview_only=data['preview_only'], preview_topic=preview.topic) msg = 'Emails queued for delivery: %s' % total if data['preview_only']: msg = '%s (for preview only, emails not sent!)' % msg messages.success(request, msg) return redirect('zadmin.email_devs') return jingo.render(request, 'zadmin/email-devs.html', dict(form=form, preview_csv=preview_csv))
def emailchange(request, user_id, token, hash): user = get_object_or_404(UserProfile, id=user_id) try: _uid, newemail = EmailResetCode.parse(token, hash) except ValueError: return http.HttpResponse(status=400) if _uid != user.id: # I'm calling this a warning because invalid hashes up to this point # could be any number of things, but this is a targeted attack from # one user account to another log.warning((u"[Tampering] Valid email reset code for UID (%s) " "attempted to change email address for user (%s)") % (_uid, user)) return http.HttpResponse(status=400) user.email = newemail user.save() l = {'user': user, 'newemail': newemail} log.info(u"User (%(user)s) confirmed new email address (%(newemail)s)" % l) messages.success(request, _('Your email address was changed successfully'), _(u'From now on, please use {0} to log in.').format(newemail)) return http.HttpResponseRedirect(reverse('users.edit'))
def api(request): try: access = Access.objects.get(user=request.user) except Access.DoesNotExist: access = None roles = request.amo_user.groups.all() if roles: messages.error(request, _('Users with roles cannot use the API.')) elif not request.amo_user.read_dev_agreement: messages.error(request, _('You must accept the terms of service.')) elif request.method == 'POST': if 'delete' in request.POST: if access: access.delete() messages.success(request, _('API key deleted.')) else: if not access: key = 'mkt:%s:%s' % (request.amo_user.pk, request.amo_user.email) access = Access.objects.create(key=key, user=request.user, secret=generate()) else: access.update(secret=generate()) messages.success(request, _('New API key generated.')) return redirect(reverse('mkt.developers.apps.api')) return jingo.render(request, 'developers/api.html', {'consumer': access, 'profile': profile, 'roles': roles})
def featured_apps_admin(request): home_collection = Webapp.featured_collection('home') category_collection = Webapp.featured_collection('category') if request.POST: if 'home_submit' in request.POST: coll = home_collection rowid = 'home' elif 'category_submit' in request.POST: coll = category_collection rowid = 'category' existing = set(coll.addons.values_list('id', flat=True)) requested = set(int(request.POST[k]) for k in sorted(request.POST.keys()) if k.endswith(rowid + '-webapp')) CollectionAddon.objects.filter(collection=coll, addon__in=(existing - requested)).delete() for id in requested - existing: CollectionAddon.objects.create(collection=coll, addon_id=id) messages.success(request, 'Changes successfully saved.') return redirect(reverse('admin.featured_apps')) return jingo.render(request, 'zadmin/featuredapp.html', { 'home_featured': enumerate(home_collection.addons.all()), 'category_featured': enumerate(category_collection.addons.all()) })
def edit(request): webapp = settings.APP_PREVIEW # Don't use request.amo_user since it has too much caching. amouser = UserProfile.objects.get(pk=request.user.id) if request.method == "POST": # ModelForm alters the instance you pass in. We need to keep a copy # around in case we need to use it below (to email the user) original_email = amouser.email form = forms.UserEditForm(request.POST, request.FILES, request=request, instance=amouser, webapp=webapp) if form.is_valid(): messages.success(request, _("Profile Updated")) if amouser.email != original_email: # Temporarily block email changes. if settings.APP_PREVIEW: messages.error(request, "Error", "You cannot change your email on the " "developer preview site.") return jingo.render(request, "users/edit.html", {"form": form, "amouser": amouser}) l = {"user": amouser, "mail1": original_email, "mail2": amouser.email} log.info(u"User (%(user)s) has requested email change from" "(%(mail1)s) to (%(mail2)s)" % l) messages.info( request, _("Email Confirmation Sent"), _( u"An email has been sent to {0} to confirm your new " "email address. For the change to take effect, you " "need to click on the link provided in this email. " "Until then, you can keep logging in with your " "current email address." ).format(amouser.email), ) domain = settings.DOMAIN token, hash = EmailResetCode.create(amouser.id, amouser.email) url = "%s%s" % (settings.SITE_URL, reverse("users.emailchange", args=[amouser.id, token, hash])) t = loader.get_template("users/email/emailchange.ltxt") c = {"domain": domain, "url": url} send_mail( _("Please confirm your email address " "change at %s" % domain), t.render(Context(c)), None, [amouser.email], use_blacklist=False, real_email=True, ) # Reset the original email back. We aren't changing their # address until they confirm the new one amouser.email = original_email form.save() return redirect("users.edit") else: messages.error( request, _("Errors Found"), _("There were errors in the changes " "you made. Please correct them and " "resubmit."), ) else: form = forms.UserEditForm(instance=amouser, webapp=webapp) return jingo.render(request, "users/edit.html", {"form": form, "amouser": amouser, "webapp": webapp})
def version_edit(request, addon_id, addon, version_id): show_features = waffle.switch_is_active('buchets') and addon.is_packaged version = get_object_or_404(Version, pk=version_id, addon=addon) form = VersionForm(request.POST or None, instance=version) all_forms = [form] if show_features: appfeatures = version.features appfeatures_form = AppFeaturesForm(request.POST, instance=appfeatures) all_forms.append(appfeatures_form) if request.method == 'POST' and all(f.is_valid() for f in all_forms): [f.save() for f in all_forms] messages.success(request, _('Version successfully edited.')) return redirect(addon.get_dev_url('versions')) context = { 'addon': addon, 'version': version, 'form': form } if show_features: context.update({ 'appfeatures_form': appfeatures_form, 'appfeatures': appfeatures, 'feature_list': [unicode(f) for f in appfeatures.to_list()] }) return jingo.render(request, 'developers/apps/version_edit.html', context)
def preload_submit(request, addon_id, addon, webapp): if request.method == 'POST': form = PreloadTestPlanForm(request.POST, request.FILES) if form.is_valid(): # Save test plan file. test_plan = request.FILES['test_plan'] # Figure the type to save it as (cleaned as pdf/xls from the form). if test_plan.content_type == 'application/pdf': filename = 'test_plan_%s.pdf' else: filename = 'test_plan_%s.xls' # Timestamp. filename = filename % str(time.time()).split('.')[0] save_test_plan(request.FILES['test_plan'], filename, addon) # Log test plan. PreloadTestPlan.objects.filter(addon=addon).update( status=amo.STATUS_DISABLED ) PreloadTestPlan.objects.create(addon=addon, filename=filename) messages.success( request, _('Application for preload successfully submitted.')) return redirect(addon.get_dev_url('versions')) else: messages.error(request, _('There was an error with the form.')) else: form = PreloadTestPlanForm() return jingo.render(request, 'developers/apps/preload/submit.html', { 'addon': addon, 'form': form })
def recalc_hash(request, file_id): file = get_object_or_404(File, pk=file_id) file.size = storage.size(file.file_path) file.hash = file.generate_hash() file.save() log.info('Recalculated hash for file ID %d' % file.id) messages.success(request, 'File hash and size recalculated for file %d.' % file.id) return {'success': 1}
def submit_persona(request): if not waffle.flag_is_active(request, 'submit-personas'): return http.HttpResponseForbidden() form = NewPersonaForm(data=request.POST or None, files=request.FILES or None, request=request) if request.method == 'POST' and form.is_valid(): addon = form.save() messages.success(request, _('Persona successfully added.')) return redirect('personas.submit.done', addon.slug) return jingo.render(request, 'addons/impala/personas/submit.html', dict(form=form))
def blocklist(request, addon): """ Blocklists the app by creating a new version/file. """ if addon.status != amo.STATUS_BLOCKED: addon.create_blocklisted_version() messages.success(request, _('Created blocklisted version.')) else: messages.info(request, _('App already blocklisted.')) return redirect(addon.get_dev_url('versions'))
def profile(request, addon_id, addon): profile_form = forms.ProfileForm(request.POST or None, instance=addon) if request.method == 'POST' and profile_form.is_valid(): profile_form.save() amo.log(amo.LOG.EDIT_PROPERTIES, addon) messages.success(request, _('Changes successfully saved.')) return redirect('devhub.addons.profile', addon.slug) return jingo.render(request, 'devhub/addons/profile.html', dict(addon=addon, profile_form=profile_form))
def fix_disabled_file(request): file_ = None if request.method == 'POST' and 'file' in request.POST: file_ = get_object_or_404(File, id=request.POST['file']) if 'confirm' in request.POST: file_.unhide_disabled_file() messages.success(request, 'We have done a great thing.') return redirect('zadmin.fix-disabled') return jingo.render(request, 'zadmin/fix-disabled.html', {'file': file_, 'file_id': request.POST.get('file', '')})
def terms(request): form = forms.DevAgreementForm({'read_dev_agreement': True}, instance=request.amo_user) if request.POST and form.is_valid(): form.save() log.info('Dev agreement agreed for user: %s' % request.amo_user.pk) messages.success(request, _('Terms of service accepted.')) return jingo.render(request, 'developers/terms.html', { 'accepted': request.amo_user.read_dev_agreement, 'agreement_form': form })
def admin_edit(request, user): if request.method == 'POST': form = forms.AdminUserEditForm(request.POST, request.FILES, request=request, instance=user) if form.is_valid(): form.save() messages.success(request, _('Profile Updated')) return http.HttpResponseRedirect(reverse('zadmin.index')) else: form = forms.AdminUserEditForm(instance=user, request=request) return render(request, 'users/edit.html', {'form': form, 'amouser': user})
def report_abuse(request, user): form = AbuseForm(request.POST or None, request=request) if request.method == 'POST' and form.is_valid(): send_abuse_report(request, user, form.cleaned_data['text']) messages.success(request, _('User reported.')) else: return jingo.render(request, 'users/report_abuse_full.html', { 'profile': user, 'abuse_form': form, }) return redirect(user.get_url_path())
def edit(request): # Don't use request.user since it has too much caching. amouser = UserProfile.objects.get(pk=request.user.id) if request.method == 'POST': # ModelForm alters the instance you pass in. We need to keep a copy # around in case we need to use it below (to email the user) original_email = amouser.email form = forms.UserEditForm(request.POST, request.FILES, request=request, instance=amouser) if form.is_valid(): messages.success(request, _('Profile Updated')) if amouser.email != original_email: l = {'user': amouser, 'mail1': original_email, 'mail2': amouser.email} log.info(u"User (%(user)s) has requested email change from " u"(%(mail1)s) to (%(mail2)s)" % l) messages.info( request, _('Email Confirmation Sent'), _(u'An email has been sent to {0} to confirm your new ' u'email address. For the change to take effect, you ' u'need to click on the link provided in this email. ' u'Until then, you can keep logging in with your ' u'current email address.').format(amouser.email)) token, hash_ = EmailResetCode.create(amouser.id, amouser.email) url = '%s%s' % (settings.SITE_URL, reverse('users.emailchange', args=[amouser.id, token, hash_])) t = loader.get_template('users/email/emailchange.ltxt') c = {'domain': settings.DOMAIN, 'url': url} send_mail( _('Please confirm your email address ' 'change at %s' % settings.DOMAIN), t.render(Context(c)), None, [amouser.email], use_blacklist=False, real_email=True) # Reset the original email back. We aren't changing their # address until they confirm the new one amouser.email = original_email form.save() return redirect('users.edit') else: messages.error( request, _('Errors Found'), _('There were errors in the changes you made. Please correct ' 'them and resubmit.')) else: form = forms.UserEditForm(instance=amouser, request=request) return render(request, 'users/edit.html', {'form': form, 'amouser': amouser})
def report_abuse(request, addon): form = AbuseForm(request.POST or None, request=request) if request.method == "POST" and form.is_valid(): send_abuse_report(request, addon, form.cleaned_data['text']) messages.success(request, _('Abuse reported.')) return http.HttpResponseRedirect(addon.get_url_path()) else: return render(request, 'addons/report_abuse_full.html', { 'addon': addon, 'abuse_form': form })
def edit(request, collection, username, slug): is_admin = acl.action_allowed(request, 'Admin', '%') if request.method == 'POST': initial = initial_data_from_request(request) if collection.author_id: # Don't try to change the author. initial['author'] = collection.author form = forms.CollectionForm(request.POST, request.FILES, initial=initial, instance=collection) if form.is_valid(): collection = form.save() title = _("Collection updated!") msg = _(("""<a href="%(url)s">View your collection</a> to see the changes.""")) % { 'url': collection.get_url_path() } messages.success(request, title, msg, extra_tags='collection', message_safe=True) log.info(u'%s edited collection %s' % (request.amo_user, collection.id)) return http.HttpResponseRedirect(collection.edit_url()) else: form = forms.CollectionForm(instance=collection) qs = (CollectionAddon.uncached.using('default').filter( collection=collection)) meta = dict((c.addon_id, c) for c in qs) addons = collection.addons.no_cache().all() comments = get_notes(collection, raw=True).next() if is_admin: initial = dict(type=collection.type, application=collection.application_id) admin_form = forms.AdminForm(initial=initial) else: admin_form = None data = dict(collection=collection, form=form, user=request.amo_user, username=username, slug=slug, meta=meta, filter=get_filter(request), is_admin=is_admin, admin_form=admin_form, addons=addons, comments=comments) return render(request, 'bandwagon/edit.html', data)
def memcache(request): form = YesImSure(request.POST or None) if form.is_valid(): cache.clear() form = YesImSure() messages.success(request, 'Cache cleared') if cache._cache and hasattr(cache._cache, 'get_stats'): stats = cache._cache.get_stats() else: stats = [] return jingo.render(request, 'zadmin/memcache.html', {'form': form, 'stats': stats})
def report_abuse(request, user_id): user = get_object_or_404(UserProfile, pk=user_id) form = AbuseForm(request.POST or None, request=request) if request.method == "POST" and form.is_valid(): send_abuse_report(request, user, form.cleaned_data['text']) messages.success(request, _('User reported.')) else: return jingo.render(request, 'users/report_abuse_full.html', { 'profile': user, 'abuse_form': form, }) return redirect(reverse('users.profile', args=[user.pk]))
def profile(request, addon_id, addon, webapp=False): profile_form = forms.ProfileForm(request.POST or None, instance=addon) if request.method == 'POST' and profile_form.is_valid(): profile_form.save() amo.log(amo.LOG.EDIT_PROPERTIES, addon) messages.success(request, _('Changes successfully saved.')) return redirect(addon.get_dev_url('profile')) return jingo.render( request, 'developers/apps/profile.html', dict(addon=addon, webapp=webapp, profile_form=profile_form))
def delete_photo(request): u = request.amo_user if request.method == 'POST': u.picture_type = '' u.save() log.debug(u"User (%s) deleted photo" % u) tasks.delete_photo.delay(u.picture_path) messages.success(request, _('Photo Deleted')) return http.HttpResponseRedirect( reverse('users.edit') + '#user-profile') return render(request, 'users/delete_photo.html', dict(user=u))
def delete_icon(request, collection, username, slug): log.debug(u"User deleted collection (%s) icon " % slug) tasks.delete_icon( os.path.join(collection.get_img_dir(), '%d.png' % collection.id)) collection.icontype = '' collection.save() if request.is_ajax(): return {'icon': collection.icon_url} else: messages.success(request, _('Icon Deleted')) return redirect(collection.edit_url())
def confirm(request, user, token): if not user.confirmationcode: return redirect('users.login') if user.confirmationcode != token: log.info(u"Account confirmation failed for user (%s)", user) messages.error(request, _('Invalid confirmation code!')) return redirect('users.login') user.confirmationcode = '' user.save() messages.success(request, _('Successfully verified!')) log.info(u"Account confirmed for user (%s)", user) return redirect('users.login')
def refund_reason(request, contribution, wizard): addon = contribution.addon if not 'request' in wizard.get_progress(): return redirect('users.support', contribution.pk, 'request') if contribution.transaction_id is None: messages.error( request, _('A refund cannot be applied for yet. Please try again' ' later. If this error persists contact ' '[email protected].')) paypal_log.info('Refund requested for contribution with no ' 'transaction_id: %r' % (contribution.pk, )) return redirect('users.purchases') if contribution.is_instant_refund(): paypal.refund(contribution.paykey) # TODO: Consider requiring a refund reason for instant refunds. refund = contribution.enqueue_refund(amo.REFUND_APPROVED_INSTANT) paypal_log.info('Refund %r issued for contribution %r' % (refund.pk, contribution.pk)) # Note: we have to wait for PayPal to issue an IPN before it's # completely refunded. messages.success(request, _('Refund is being processed.')) return redirect('users.purchases') form = forms.ContactForm(request.POST or None) if request.method == 'POST' and form.is_valid(): reason = form.cleaned_data['text'] template = jingo.render_to_string( request, wizard.tpl('emails/refund-request.txt'), context={ 'addon': addon, 'form': form, 'user': request.amo_user, 'contribution': contribution, 'refund_url': contribution.get_absolute_refund_url(), 'refund_reason': reason }) log.info('Refund request sent by user: %s for addon: %s' % (request.amo_user.pk, addon.pk)) # L10n: %s is the addon name. send_mail(_(u'New Refund Request for %s' % addon.name), template, settings.NOBODY_EMAIL, [smart_str(addon.support_email)]) # Add this refund request to the queue. contribution.enqueue_refund(amo.REFUND_PENDING, reason) return redirect( reverse('users.support', args=[contribution.pk, 'refund-sent'])) return wizard.render(request, wizard.tpl('refund.html'), {'form': form})
def collection_message(request, collection, option): if option == 'add': title = _('Collection created!') msg = _("""Your new collection is shown below. You can <a href="%(url)s">edit additional settings</a> if you'd like.""") % {'url': collection.edit_url()} elif option == 'update': title = _('Collection updated!') msg = _("""<a href="%(url)s">View your collection</a> to see the changes.""") % {'url': collection.get_url_path()} else: raise ValueError('Incorrect option "%s", ' 'takes only "add" or "update".' % option) messages.success(request, title, msg, message_safe=True)
def version_edit(request, addon_id, addon, version_id): version = get_object_or_404(Version, pk=version_id, addon=addon) form = VersionForm(request.POST or None, instance=version) if request.method == 'POST' and form.is_valid(): form.save() messages.success(request, _('Version successfully edited.')) return redirect(addon.get_dev_url('versions')) return jingo.render(request, 'developers/apps/version_edit.html', { 'addon': addon, 'version': version, 'form': form })
def email_devs(request): form = DevMailerForm(request.POST or None) preview = EmailPreviewTopic(topic='email-devs') if preview.filter().count(): preview_csv = reverse('zadmin.email_preview_csv', args=[preview.topic]) else: preview_csv = None if request.method == 'POST' and form.is_valid(): data = form.cleaned_data listed = amo.LISTED_STATUSES qs = (AddonUser.objects.filter( role__in=(amo.AUTHOR_ROLE_DEV, amo.AUTHOR_ROLE_OWNER), addon__status__in=listed).exclude(user__email=None)) if data['recipients'] == 'eula': qs = qs.exclude(addon__eula=None) elif data['recipients'] == 'payments': qs = qs.filter(addon__type=amo.ADDON_WEBAPP) qs = qs.exclude(addon__paypal_id=None) qs = qs.exclude(addon__premium_type__in=(amo.ADDON_FREE, amo.ADDON_OTHER_INAPP)) elif data['recipients'] == 'apps': qs = qs.filter(addon__type=amo.ADDON_WEBAPP) elif data['recipients'] == 'desktop_apps': qs = (qs.filter( addon__type=amo.ADDON_WEBAPP, addon__addondevicetype__device_type=amo.DEVICE_DESKTOP.id)) elif data['recipients'] == 'sdk': qs = qs.exclude(addon__versions__files__jetpack_version=None) else: raise NotImplementedError('If you want to support emailing other ' 'types of developers, do it here!') if data['preview_only']: # Clear out the last batch of previewed emails. preview.filter().delete() total = 0 for emails in chunked(set(qs.values_list('user__email', flat=True)), 100): total += len(emails) tasks.admin_email.delay(emails, data['subject'], data['message'], preview_only=data['preview_only'], preview_topic=preview.topic) msg = 'Emails queued for delivery: %s' % total if data['preview_only']: msg = '%s (for preview only, emails not sent!)' % msg messages.success(request, msg) return redirect('zadmin.email_devs') return jingo.render(request, 'zadmin/email-devs.html', dict(form=form, preview_csv=preview_csv))
def notify_failure(request, job): job = get_object_or_404(ValidationJob, pk=job) notify_form = NotifyForm(request.POST, text='failure') if not notify_form.is_valid(): messages.error(request, notify_form) else: file_pks = job.result_failing().values_list('file_id', flat=True) for chunk in chunked(file_pks, 100): tasks.notify_failed.delay(chunk, job.pk, notify_form.cleaned_data) messages.success(request, _('Notifying authors task started.')) return redirect(reverse('zadmin.validation'))
def recalc_hash(request, file_id): file = get_object_or_404(File, pk=file_id) file.size = int(max(1, round(os.path.getsize(file.file_path) / 1024, 0))) file.hash = file.generate_hash() file.save() log.info('Recalculated hash for file ID %d' % file.id) messages.success(request, 'File hash and size recalculated for file %d.' % file.id) redirect_url = reverse('zadmin.addon_manage', args=[file.version.addon.slug]) page = request.GET.get('page', 1) return redirect(urlparams(redirect_url, page=page))
def notify_success(request, job): job = get_object_or_404(ValidationJob, pk=job) notify_form = NotifyForm(request.POST, text='success') if not notify_form.is_valid(): messages.error(request, notify_form.errors) else: versions = completed_versions_dirty(job) for chunk in chunked(versions, 100): tasks.notify_success.delay(chunk, job.pk, notify_form.cleaned_data) messages.success(request, _('Updating max version task and ' 'notifying authors started.')) return redirect(reverse('zadmin.validation'))
def delete(request): amouser = request.user if request.method == 'POST': form = forms.UserDeleteForm(request.POST, request=request) if form.is_valid(): messages.success(request, _('Profile Deleted')) amouser.anonymize() logout(request) form = None return http.HttpResponseRedirect(reverse('users.login')) else: form = forms.UserDeleteForm() return render(request, 'users/delete.html', {'form': form, 'amouser': amouser})
def report_abuse(request, addon): if not settings.REPORT_ABUSE: raise http.Http404() form = AbuseForm(request.POST or None, request=request) if request.method == "POST" and form.is_valid(): url = reverse('addons.detail', args=[addon.slug]) send_abuse_report(request, addon, url, form.cleaned_data['text']) messages.success(request, _('Abuse reported.')) return redirect('addons.detail', addon.slug) else: return jingo.render(request, 'addons/report_abuse_full.html', { 'addon': addon, 'abuse_form': form, })
def content_ratings(request, addon_id, addon): if not addon.is_rated(): return redirect(addon.get_dev_url('ratings_edit')) # Use _ratings_success_msg to display success message. session = request.session if 'ratings_edit' in session and addon.id in session['ratings_edit']: prev_state = session['ratings_edit'][addon.id] msg = _ratings_success_msg(addon, prev_state['app_status'], prev_state['rating_modified']) messages.success(request, msg) if msg else None del session['ratings_edit'][addon.id] # Clear msg so not shown again. request.session.modified = True return render(request, 'developers/apps/ratings/ratings_summary.html', {'addon': addon})
def confirm(request, user_id, token): user = get_object_or_404(UserProfile, id=user_id) if not user.confirmationcode: return http.HttpResponseRedirect(reverse('users.login')) if user.confirmationcode != token: log.info(u"Account confirmation failed for user (%s)", user) messages.error(request, _('Invalid confirmation code!')) return http.HttpResponseRedirect(reverse('users.login')) user.confirmationcode = '' user.save() messages.success(request, _('Successfully verified!')) log.info(u"Account confirmed for user (%s)", user) return http.HttpResponseRedirect(reverse('users.login'))
def status(request, addon_id, addon, webapp=False): form = forms.AppAppealForm(request.POST, product=addon) upload_form = NewWebappVersionForm(request.POST or None, is_packaged=True, addon=addon, request=request) if request.method == 'POST': if 'resubmit-app' in request.POST and form.is_valid(): form.save() messages.success(request, _('App successfully resubmitted.')) return redirect(addon.get_dev_url('versions')) elif 'upload-version' in request.POST and upload_form.is_valid(): ver = Version.from_upload(upload_form.cleaned_data['upload'], addon, [amo.PLATFORM_ALL]) messages.success(request, _('New version successfully added.')) log.info('[Webapp:%s] New version created id=%s from upload: %s' % (addon, ver.pk, upload_form.cleaned_data['upload'])) return redirect(addon.get_dev_url('versions.edit', args=[ver.pk])) ctx = { 'addon': addon, 'webapp': webapp, 'form': form, 'upload_form': upload_form } # Used in the delete version modal. if addon.is_packaged: versions = addon.versions.values('id', 'version') version_strings = dict((v['id'], v) for v in versions) version_strings['num'] = len(versions) ctx['version_strings'] = json.dumps(version_strings) if addon.status == amo.STATUS_REJECTED: try: entry = (AppLog.objects.filter( addon=addon, activity_log__action=amo.LOG.REJECT_VERSION.id).order_by( '-created'))[0] except IndexError: entry = None # This contains the rejection reason and timestamp. ctx['rejection'] = entry and entry.activity_log return jingo.render(request, 'developers/apps/status.html', ctx)
def edit_contributors(request, collection, username, slug): is_admin = acl.action_allowed(request, 'Admin', '%') if is_admin: admin_form = forms.AdminForm(request.POST) if admin_form.is_valid(): admin_form.save(collection) form = forms.ContributorsForm(request.POST) if form.is_valid(): form.save(collection) messages.success(request, _('Your collection has been updated.')) if form.cleaned_data['new_owner']: return http.HttpResponseRedirect(collection.get_url_path()) return http.HttpResponseRedirect(collection.edit_url() + '#users-edit')