def render_to_response(self, context): # Allow superusers to set ?dwft_bypass_teamwork=1 # while viewing a transcript. flag_is_active(self.request, 'bypass_teamwork') return super(TranscriptDetailView, self).render_to_response(context)
def payments_confirm(request, addon_id, addon): data = {} # TODO(solitude): remove all references to AddonPaymentData. if waffle.flag_is_active(request, 'solitude-payments'): data = client.get_seller_paypal_if_exists(addon) or {} adp, created = AddonPaymentData.objects.safer_get_or_create(addon=addon) if not data: data = model_to_dict(adp) form = PaypalPaymentData(request.POST or data) if request.method == 'POST' and form.is_valid(): if waffle.flag_is_active(request, 'solitude-payments'): # TODO(solitude): when the migration of data is completed, we # will be able to remove this. pk = client.create_seller_for_pay(addon) client.patch_seller_paypal(pk=pk, data=form.cleaned_data) # TODO(solitude): remove this. adp.update(**form.cleaned_data) AppSubmissionChecklist.objects.get(addon=addon).update(payments=True) addon.mark_done() return redirect('submit.app.done', addon.app_slug) return jingo.render(request, 'submit/payments-confirm.html', { 'step': 'payments', 'addon': addon, 'form': form })
def test(request): c = {} if waffle.flag_is_active(request, 'feature1'): c["feature11"] = "View Feature 1 is live!" else: c["feature11"] = "View Feature 1 is not available right now" # question feature users = User.objects.all() c['question_array'] = [] if waffle.flag_is_active(request, 'question'): for user in users: questions = Question.objects.filter(user=user.id) c['question_array'].append("") c['question_array'].append(user.username + ":") if questions: for question in questions: c['question_array'].append(question.text) else: c['question_array'].append("Hasn't asked any questions... sad.") if waffle.flag_is_active(request, 'answer'): c["answer_array"] = Answer.objects.all() c['cookie_answer'] = request.COOKIES.get('dwf_answer') c['cookie_question'] = request.COOKIES.get('dwf_question') c['cookie_feature1'] = request.COOKIES.get('dwf_feature1') return render_to_response('test.html',c, context_instance = RequestContext(request))
def _check_readonly(request, *args, **kwargs): if not flag_is_active(request, 'kumaediting'): raise ReadOnlyException("kumaediting") elif flag_is_active(request, 'kumabanned'): raise ReadOnlyException("kumabanned") return view(request, *args, **kwargs)
def payment(request, status=None): # Note this is not post required, because PayPal does not reply with a # POST but a GET, that's a sad face. pre, created = PreApprovalUser.objects.safer_get_or_create(user=request.amo_user) context = {"preapproval": pre, "currency": CurrencyForm(initial={"currency": pre.currency or "USD"})} if status: data = request.session.get("setup-preapproval", {}) context["status"] = status if status == "complete": # The user has completed the setup at PayPal and bounced back. if "setup-preapproval" in request.session: if waffle.flag_is_active(request, "solitude-payments"): client.put_preapproval(data={"uuid": request.amo_user}, pk=data["solitude-key"]) paypal_log.info(u"Preapproval key created: %s" % request.amo_user.pk) amo.log(amo.LOG.PREAPPROVAL_ADDED) # TODO(solitude): once this is turned off, we will want to # keep preapproval table populated with something, perhaps # a boolean inplace of pre-approval key. pre.update(paypal_key=data.get("key"), paypal_expiry=data.get("expiry")) # If there is a target, bounce to it and don't show a message # we'll let whatever set this up worry about that. if data.get("complete"): return http.HttpResponseRedirect(data["complete"]) messages.success(request, _("You're all set for instant app purchases with PayPal.")) del request.session["setup-preapproval"] elif status == "cancel": # The user has chosen to cancel out of PayPal. Nothing really # to do here, PayPal just bounce to the cancel page if defined. if data.get("cancel"): return http.HttpResponseRedirect(data["cancel"]) messages.success(request, _("Your payment pre-approval has been cancelled.")) elif status == "remove": # The user has an pre approval key set and chooses to remove it if waffle.flag_is_active(request, "solitude-payments"): other = client.lookup_buyer_paypal(request.amo_user) if other: client.patch_buyer_paypal(pk=other["resource_pk"], data={"key": ""}) if pre.paypal_key: # TODO(solitude): again, we'll want to maintain some local # state in zamboni, so this will probably change to a # boolean in the future. pre.update(paypal_key="") amo.log(amo.LOG.PREAPPROVAL_REMOVED) messages.success(request, _("Your payment pre-approval has been disabled.")) paypal_log.info(u"Preapproval key removed for user: %s" % request.amo_user) return jingo.render(request, "account/payment.html", context)
def test_flag_all_sites_override(self): name = 'sample' Flag.objects.create(name=name, everyone=True, site=self.site1) self.assertTrue(waffle.flag_is_active(get(), name)) with self.settings(SITE_ID=2): self.assertTrue(waffle.flag_is_active(get(), name))
def test_testing_disabled_flag(self): Flag.objects.create(name='foo') request = get(dwft_foo='1') assert not waffle.flag_is_active(request, 'foo') assert not hasattr(request, 'waffle_tests') request = get(dwft_foo='0') assert not waffle.flag_is_active(request, 'foo') assert not hasattr(request, 'waffle_tests')
def _wrapped_view(request, *args, **kwargs): if flag_name.startswith('!'): active = not flag_is_active(request, flag_name[1:]) else: active = flag_is_active(request, flag_name) if not active: raise Http404 return view(request, *args, **kwargs)
def test_testing_disabled_flag(self): Flag.objects.create(name="foo") request = get(dwft_foo="1") assert not waffle.flag_is_active(request, "foo") assert not hasattr(request, "waffle_tests") request = get(dwft_foo="0") assert not waffle.flag_is_active(request, "foo") assert not hasattr(request, "waffle_tests")
def dispatch(self, request, *args, **kwargs): if self.waffle_flag.startswith('!'): active = not flag_is_active(request, self.waffle_flag[1:]) else: active = flag_is_active(request, self.waffle_flag) if not active: raise Http404 return super(WaffleFlagMixin, self).dispatch(request, *args, **kwargs)
def test_flag_existed_and_was_active(self): Flag.objects.create(name='foo', everyone=True) with override_flag('foo', active=True): assert waffle.flag_is_active(req(), 'foo') with override_flag('foo', active=False): assert not waffle.flag_is_active(req(), 'foo') assert Flag.objects.get(name='foo').everyone
def test_flag_existed_and_was_null(self): Flag.objects.create(name="foo", everyone=None) with override_flag("foo", active=True): assert waffle.flag_is_active(req(), "foo") with override_flag("foo", active=False): assert not waffle.flag_is_active(req(), "foo") assert Flag.objects.get(name="foo").everyone is None
def test_flag_existed_and_was_null(self): waffle.get_waffle_flag_model().objects.create(name='foo', everyone=None) with override_flag('foo', active=True): assert waffle.flag_is_active(req(), 'foo') with override_flag('foo', active=False): assert not waffle.flag_is_active(req(), 'foo') assert waffle.get_waffle_flag_model().objects.get(name='foo').everyone is None
def test_flag_did_not_exist(self): assert not Flag.objects.filter(name='foo').exists() with override_flag('foo', active=True): assert waffle.flag_is_active(req(), 'foo') with override_flag('foo', active=False): assert not waffle.flag_is_active(req(), 'foo') assert not Flag.objects.filter(name='foo').exists()
def test_cache_is_flushed_by_testutils_even_in_transaction(self): waffle.get_waffle_flag_model().objects.create(name='foo', everyone=True) with transaction.atomic(): with override_flag('foo', active=True): assert waffle.flag_is_active(req(), 'foo') with override_flag('foo', active=False): assert not waffle.flag_is_active(req(), 'foo') assert waffle.flag_is_active(req(), 'foo')
def test_testing_flag(self): Flag.objects.create(name='foo', testing=True) request = get(dwft_foo='1') assert waffle.flag_is_active(request, 'foo') assert 'foo' in request.waffle_tests assert request.waffle_tests['foo'] request = get(dwft_foo='0') assert not waffle.flag_is_active(request, 'foo') assert 'foo' in request.waffle_tests assert not request.waffle_tests['foo']
def test_testing_flag(self): Flag.objects.create(name="foo", testing=True) request = get(dwft_foo="1") assert waffle.flag_is_active(request, "foo") assert "foo" in request.waffle_tests assert request.waffle_tests["foo"] request = get(dwft_foo="0") assert not waffle.flag_is_active(request, "foo") assert "foo" in request.waffle_tests assert not request.waffle_tests["foo"]
def test_custom_segment(self): Flag.objects.create(name='flag-1', custom_segment=( '{"even_numbers": 1}' )) Flag.objects.create(name='flag-2', custom_segment=( '{"even_numbers": 2}' )) request = get() self.assertFalse(waffle.flag_is_active(request, 'flag-1')) self.assertTrue(waffle.flag_is_active(request, 'flag-2'))
def akismet_parameter_overrides(self): """ Get parameter overrides based on user's waffle flags. """ parameters = {} if flag_is_active(self.request, constants.SPAM_ADMIN_FLAG): parameters['user_role'] = 'administrator' if flag_is_active(self.request, constants.SPAM_SPAMMER_FLAG): parameters['comment_author'] = 'viagra-test-123' if flag_is_active(self.request, constants.SPAM_TESTING_FLAG): parameters['is_test'] = True return parameters
def PAID_PLATFORMS(request=None, is_packaged=False): import waffle platforms = (("paid-firefoxos", _("Firefox OS")),) android_payments_enabled = request and waffle.flag_is_active(request, "android-payments") android_packaged_enabled = request and waffle.flag_is_active(request, "android-packaged") if android_payments_enabled: if not is_packaged or (is_packaged and android_packaged_enabled): platforms += (("paid-android-mobile", _("Firefox Mobile")), ("paid-android-tablet", _("Firefox Tablet"))) return platforms
def test_testing_flag(self): Flag.objects.create(name="foo", testing=True) request = get(dwft_foo="1") assert waffle.flag_is_active(request, "foo") assert "foo" in request.waffle_tests assert request.waffle_tests["foo"] # GET param should override cookie request = get(dwft_foo="0") request.COOKIES["dwft_foo"] = "True" assert not waffle.flag_is_active(request, "foo") assert "foo" in request.waffle_tests assert not request.waffle_tests["foo"]
def test_testing_flag(self): Flag.objects.create(name='foo', testing=True) request = get(dwft_foo='1') assert waffle.flag_is_active(request, 'foo') assert 'foo' in request.waffle_tests assert request.waffle_tests['foo'] # GET param should override cookie request = get(dwft_foo='0') request.COOKIES['dwft_foo'] = 'True' assert not waffle.flag_is_active(request, 'foo') assert 'foo' in request.waffle_tests assert not request.waffle_tests['foo']
def _set_packaged_errors(self): """Add packaged-app submission errors for incompatible platforms.""" devices = self._get_combined() bad_android = ( not waffle.flag_is_active(self.request, 'android-packaged') and ('android-mobile' in devices or 'android-tablet' in devices) ) bad_desktop = ( not waffle.flag_is_active(self.request, 'desktop-packaged') and 'desktop' in devices ) if bad_android or bad_desktop: self._errors['free_platforms'] = self._errors['paid_platforms'] = ( self.ERRORS['packaged'])
def _wrapped_view(request, *args, **kwargs): if flag_name.startswith('!'): active = not flag_is_active(request, flag_name[1:]) else: active = flag_is_active(request, flag_name) if not active: response_to_redirect_to = get_response_to_redirect(redirect_to) if response_to_redirect_to: return response_to_redirect_to else: raise Http404 return view(request, *args, **kwargs)
def FREE_PLATFORMS(request=None, is_packaged=False): import waffle platforms = (("free-firefoxos", _("Firefox OS")),) android_packaged_enabled = request and waffle.flag_is_active(request, "android-packaged") desktop_packaged_enabled = request and waffle.flag_is_active(request, "desktop-packaged") if not is_packaged or (is_packaged and desktop_packaged_enabled): platforms += (("free-desktop", _("Firefox for Desktop")),) if not is_packaged or (is_packaged and android_packaged_enabled): platforms += (("free-android-mobile", _("Firefox Mobile")), ("free-android-tablet", _("Firefox Tablet"))) return platforms
def test_reroll(self, uniform): """Even without a cookie, calling flag_is_active twice should return the same value.""" Flag.objects.create(name="myflag", percent="50.0") # Make sure we're not really random. request = get() # Create a clean request. assert not hasattr(request, "waffles") uniform.return_value = "10" # < 50. Flag is True. assert waffle.flag_is_active(request, "myflag") assert hasattr(request, "waffles") # We should record this flag. assert "myflag" in request.waffles assert request.waffles["myflag"][0] uniform.return_value = "70" # > 50. Normally, Flag would be False. assert waffle.flag_is_active(request, "myflag") assert request.waffles["myflag"][0]
def test_reroll(self, uniform): """Even without a cookie, calling flag_is_active twice should return the same value.""" Flag.objects.create(name='myflag', percent='50.0') # Make sure we're not really random. request = get() # Create a clean request. assert not hasattr(request, 'waffles') uniform.return_value = '10' # < 50. Flag is True. assert waffle.flag_is_active(request, 'myflag') assert hasattr(request, 'waffles') # We should record this flag. assert 'myflag' in request.waffles assert request.waffles['myflag'][0] uniform.return_value = '70' # > 50. Normally, Flag would be False. assert waffle.flag_is_active(request, 'myflag') assert request.waffles['myflag'][0]
def root(request, format=None, **kwargs): """ The documentation for the Open Science Framework API can be found at [developer.osf.io](https://developer.osf.io). The contents of this endpoint are variable and subject to change without notification. """ if request.user and not request.user.is_anonymous: user = request.user current_user = UserSerializer(user, context={'request': request}).data else: current_user = None flags = [name for name in Flag.objects.values_list('name', flat=True) if flag_is_active(request, name)] kwargs = request.parser_context['kwargs'] return_val = { 'meta': { 'message': 'Welcome to the OSF API.', 'version': request.version, 'current_user': current_user, 'active_flags': flags, }, 'links': { 'nodes': utils.absolute_reverse('nodes:node-list', kwargs=kwargs), 'users': utils.absolute_reverse('users:user-list', kwargs=kwargs), 'collections': utils.absolute_reverse('collections:collection-list', kwargs=kwargs), 'registrations': utils.absolute_reverse('registrations:registration-list', kwargs=kwargs), 'institutions': utils.absolute_reverse('institutions:institution-list', kwargs=kwargs), 'licenses': utils.absolute_reverse('licenses:license-list', kwargs=kwargs), 'schemas': utils.absolute_reverse('schemas:registration-schema-list', kwargs=kwargs), 'addons': utils.absolute_reverse('addons:addon-list', kwargs=kwargs), }, } if utils.has_admin_scope(request): return_val['meta']['admin'] = True return Response(return_val)
def get_context_data(self, **kwargs): context = super(CommitteeListView, self).get_context_data(**kwargs) context['tags_cloud'] = Tag.objects.cloud_for_model(CommitteeMeeting) if waffle.flag_is_active(self.request, 'show_committee_topics'): context = self._add_topics_to_context(context) return context
def test_all_flags_matched(self): """ The flag has been found in ALL_FLAGS. Must return True. """ setattr(waffle, 'ALL_FLAGS', ['foo', ]) request = get() assert waffle.flag_is_active(request, 'foo')
def overview_series(request, addon, group, start, end, format): """Combines downloads_series and updates_series into one payload.""" date_range = check_series_params_or_404(group, start, end, format) start_date, end_date = date_range check_stats_permission(request, addon) if waffle.flag_is_active(request, 'bigquery-download-stats'): downloads = get_download_series( addon=addon, start_date=start_date, end_date=end_date ) else: downloads = get_series( DownloadCount, addon=addon.id, date__range=date_range ) updates = get_updates_series( addon=addon, start_date=start_date, end_date=end_date ) series = zip_overview(downloads, updates) return render_json(request, addon, series)
def _add_to_context_data(self, context): formset = context.get('formset', []) lines = context.get('line_list', []) site_configuration = self.request.site.siteconfiguration context_updates, lines_data = self.process_basket_lines(lines) context.update(context_updates) context.update(self.process_totals(context)) context.update({ 'analytics_data': prepare_analytics_data( self.request.user, site_configuration.segment_key, ), 'enable_client_side_checkout': False, 'sdn_check': site_configuration.enable_sdn_check }) payment_processors = site_configuration.get_payment_processors() if (site_configuration.client_side_payment_processor and waffle.flag_is_active(self.request, CLIENT_SIDE_CHECKOUT_FLAG_NAME)): payment_processors_data = self._get_payment_processors_data( payment_processors) context.update(payment_processors_data) context.update({ 'formset_lines_data': list(zip(formset, lines_data)), 'homepage_url': get_lms_url(''), 'min_seat_quantity': 1, 'max_seat_quantity': 100, 'payment_processors': payment_processors, 'lms_url_root': site_configuration.lms_url_root, }) return context
def _get_basket(self, basket_id): if not basket_id: return None try: basket_id = int(basket_id) basket = Basket.objects.get(id=basket_id) basket.strategy = strategy.Default() # TODO: Remove as a part of REVMI-124 as this is a hacky solution # The problem is that orders are being created after payment processing, and the discount is not # saved in the database, so it needs to be calculated again in order to save the correct info to the # order. REVMI-124 will create the order before payment processing, when we have the discount context. if waffle.flag_is_active( self.request, DYNAMIC_DISCOUNT_FLAG) and basket.lines.count() == 1: discount_lms_url = get_lms_url('/api/discounts/') lms_discount_client = EdxRestApiClient( discount_lms_url, jwt=self.request.site.siteconfiguration.access_token) ck = basket.lines.first().product.course_id user_id = self.request.user.lms_user_id try: response = lms_discount_client.user(user_id).course( ck).get() self.request.POST = self.request.POST.copy() self.request.POST['discount_jwt'] = response.get('jwt') except (SlumberHttpBaseException, requests.exceptions.Timeout) as error: logger.warning( 'Failed to get discount jwt from LMS. [%s] returned [%s]', discount_lms_url, error.response) # End TODO Applicator().apply(basket, basket.owner, self.request) logger.info('Applicator applied, basket id: [%s]', basket.id) return basket except (ValueError, ObjectDoesNotExist) as error: logger.warning('Could not get basket--error: [%s]', str(error)) return None
def process_totals(self, context): """ Returns a Dictionary of data related to total price and discounts. """ # Total benefit displayed in price summary. # Currently only one voucher per basket is supported. try: applied_voucher = self.request.basket.vouchers.first() total_benefit_object = applied_voucher.best_offer.benefit if applied_voucher else None # TODO This ValueError handling no longer seems to be required and could probably be removed except ValueError: # pragma: no cover total_benefit_object = None num_of_items = self.request.basket.num_items discount_jwt = None discount_percent = None if waffle.flag_is_active(self.request, DYNAMIC_DISCOUNT_FLAG): applied_offers = self.request.basket.applied_offers().values() if len(applied_offers) == 1 and list(applied_offers)[ 0].condition.name == 'dynamic_discount_condition': discount_jwt = self.request.GET.get('discount_jwt') discount_percent = get_percentage_from_request() return { 'total_benefit_object': total_benefit_object, 'total_benefit': format_benefit_value(total_benefit_object) if total_benefit_object else None, 'free_basket': context['order_total'].incl_tax == 0, 'line_price': (self.request.basket.total_incl_tax_excl_discounts / num_of_items) if num_of_items > 0 else 0, 'discount_jwt': discount_jwt, 'discount_percent': discount_percent, }
def akismet_error(self, parameters, exception=None): """ Upon errors from the Akismet API records the user, document and date of the attempt for further analysis. Then call the parent class' error handler. """ try: document = self.instance.document except ObjectDoesNotExist: document = None if exception and isinstance(exception, AkismetError): # For Akismet errors, save the submission and exception details dsa_params = parameters.copy() dsa_params['akismet_status_code'] = exception.status_code dsa_params['akismet_debug_help'] = exception.debug_help dsa_params['akismet_response'] = exception.response.content review = DocumentSpamAttempt.AKISMET_ERROR else: # For detected spam, save the details for review dsa_params = parameters review = DocumentSpamAttempt.NEEDS_REVIEW # Wrapping this in a try/finally to make sure that even if # creating a spam attempt object fails we call the parent # method that raises a ValidationError try: DocumentSpamAttempt.objects.create( title=self.cleaned_data['title'], slug=self.cleaned_data['slug'], user=self.request.user, document=document, data=json.dumps(dsa_params, indent=2, sort_keys=True), review=review ) finally: if not waffle.flag_is_active(self.request, SPAM_TRAINING_FLAG): super(RevisionForm, self).akismet_error(parameters, exception)
def create_stripe_subscription(request): user = request.user if not flag_is_active(request, "subscription"): return HttpResponseForbidden("subscription flag not active for this user") has_stripe_error = False try: email = request.POST.get("stripe_email", "") stripe_token = request.POST.get("stripe_token", "") create_stripe_customer_and_subscription_for_user(user, email, stripe_token) except stripe.error.StripeError: raven_client.captureException() has_stripe_error = True return redirect( urlparams( reverse("users.user_edit", args=[user.username]), has_stripe_error=has_stripe_error, ) + "#subscription" )
def form_valid(self, form): if waffle.flag_is_active(self.request, "create_note"): form.instance.created_by = self.request.user leadid = self.request.POST.get("create_note_lead") urlparameters = self.request.POST.get("urlparameters") try: lead = Lead.objects.get(pk=leadid) except Exception as e: print(str(e)) logger.critical("Note Create error - Lead not found") messages.error(self.request, "There is an error on the form.") return redirect( reverse("leads:listnote", args=[leadid]) + "?" + urlparameters) else: form.instance.lead = lead return super().form_valid(form) else: messages.error( self.request, "Please update your subscription to continue using this feature.", ) return super(NoteCreateView, self).form_valid(form)
def subscriptions(request): if not request.user.is_authenticated or not flag_is_active( request, "subscription"): return Response(None, status=status.HTTP_403_FORBIDDEN) if request.method == "POST": create_stripe_customer_and_subscription_for_user( request.user, request.user.email, request.data["stripe_token"]) return Response(None, status=status.HTTP_201_CREATED) elif request.method == "DELETE": cancelled = cancel_stripe_customer_subscriptions(request.user) if cancelled: return Response(None, status=status.HTTP_204_NO_CONTENT) else: return Response("nothing to cancel", status=status.HTTP_410_GONE) all_subscriptions = [] subscription_info = retrieve_and_synchronize_subscription_info( request.user) if subscription_info: all_subscriptions.append(subscription_info) return Response({"subscriptions": all_subscriptions})
def wafflejs(request): flags = cache.get(FLAGS_ALL_CACHE_KEY) if not flags: flags = Flag.objects.values_list('name', flat=True) cache.add(FLAGS_ALL_CACHE_KEY, flags) flag_values = [(f, flag_is_active(request, f)) for f in flags] switches = cache.get(SWITCHES_ALL_CACHE_KEY) if not switches: switches = Switch.objects.values_list('name', 'active') cache.add(SWITCHES_ALL_CACHE_KEY, switches) samples = cache.get(SAMPLES_ALL_CACHE_KEY) if not samples: samples = Sample.objects.values_list('name', flat=True) cache.add(SAMPLES_ALL_CACHE_KEY, samples) sample_values = [(s, sample_is_active(s)) for s in samples] return render_to_response('waffle/waffle.js', { 'flags': flag_values, 'switches': switches, 'samples': sample_values }, mimetype='application/x-javascript')
def check_stats_permission(request, addon, beta): """ Check if user is allowed to view stats/beta stats for ``addon``. Raises PermissionDenied if user is not allowed. Raises Http404 if user cannot access the beta mode (only if enabled). """ user = request.user user_cannot_access_beta = not user.is_authenticated or ( user.is_authenticated and not (user.email.endswith('@mozilla.com') or waffle.flag_is_active(request, 'beta-stats'))) addon_has_no_beta = addon.type not in amo.ADDON_TYPES_WITH_STATS if beta and (user_cannot_access_beta or addon_has_no_beta): raise http.Http404 can_view = user.is_authenticated and ( addon.has_author(user) or acl.action_allowed(request, amo.permissions.STATS_VIEW)) if not can_view: raise PermissionDenied
def home(request): """Home page.""" if flag_is_active(request, 'redesign'): demos = Submission.objects.exclude( hidden=True).order_by('-modified').all()[:4] else: demos = Submission.objects.filter(id=constance.config.DEMOS_DEVDERBY_HOMEPAGE_FEATURED_DEMO)\ .exclude(hidden=True)\ .order_by('-modified').all()[:1] updates = [] for s in SECTION_USAGE: updates += Bundle.objects.recent_entries(s.updates)[:5] return render( request, 'landing/homepage.html', { 'demos': demos, 'updates': updates, 'current_challenge_tag_name': str(constance.config.DEMOS_DEVDERBY_CURRENT_CHALLENGE_TAG).strip() })
def get_course_tabs(user, course, active_page, request): """ Return the tabs to show a particular user, as a list of CourseTab items. """ if not hasattr(course, 'tabs') or not course.tabs: return get_default_tabs(user, course, active_page, request) # TODO (vshnayder): There needs to be a place to call this right after course # load, but not from inside xmodule, since that doesn't (and probably # shouldn't) know about the details of what tabs are supported, etc. validate_tabs(course) tabs = [] if waffle.flag_is_active(request, 'merge_course_tabs'): course_tabs = [ tab for tab in course.tabs if tab['type'] != "course_info" ] else: course_tabs = course.tabs for tab in course_tabs: # expect handlers to return lists--handles things that are turned off # via feature flags, and things like 'textbook' which might generate # multiple tabs. gen = VALID_TAB_TYPES[tab['type']].generator tabs.extend(gen(tab, user, course, active_page, request)) # Instructor tab is special--automatically added if user is staff for the course if has_access(user, course, 'staff'): tabs.append( CourseTab('Instructor', reverse('instructor_dashboard', args=[course.id]), active_page == 'instructor')) return tabs
def can_use_enterprise_catalog(enterprise_uuid): """ Function to check if enterprise-catalog endpoints should be hit given an enterprise uuid. Checks the USE_ENTERPRISE_CATALOG waffle sample and ensures the passed enterprise uuid is not in the ENTERPRISE_CUSTOMERS_EXCLUDED_FROM_CATALOG list. Args: enterprise_uuid: the unique identifier for an enterprise customer Returns: boolean: True if sample is active and enterprise is not excluded False if sample not active or enterprise is excluded """ customer_uuid = str(enterprise_uuid) is_flag_active = waffle.flag_is_active(crum.get_current_request(), USE_ENTERPRISE_CATALOG) can_use_catalog = customer_uuid not in getattr( settings, 'ENTERPRISE_CUSTOMERS_EXCLUDED_FROM_CATALOG', []) log.info( 'ENT-2885: USE_ENTEPRISE_CATALOG flag %s active. Enterprise %s %s use the enterprise-catalog service.', 'IS' if is_flag_active else 'IS NOT', customer_uuid, 'CAN' if can_use_catalog else 'CANNOT') return is_flag_active and can_use_catalog
def post(self, request): form = RunForm(request.POST) if form.is_valid(): parameters = dict() for f in ALL_FIELDS: parameters[f] = form.cleaned_data[f] r = Run(**parameters) rr = RunRecord() rr.user = request.user rr.from_run(r) out = r.run() ror = RunOutputRecord(run=rr) skew_params = dict(mass=0., intake=0., expenditure=0.) if waffle.flag_is_active(request, 'demo_mode'): skew_params = apply_skews(request, skew_params) ror.from_runoutput(out, skew_params) return HttpResponseRedirect(rr.get_absolute_url()) return render( request, self.template_name, dict(form=form, interventions=Intervention.objects.all(), parameters=Parameter.objects.all()))
def profile_view(request, username): profile = get_object_or_404(UserProfile, user__username=username) user = profile.user DEMOS_PAGE_SIZE = getattr(settings, 'DEMOS_PAGE_SIZE', 12) sort_order = request.GET.get('sort', 'created') try: page_number = int(request.GET.get('page', 1)) except ValueError: page_number = 1 show_hidden = (user == request.user) or user.is_superuser demos = Submission.objects.all_sorted(sort_order).filter( creator=profile.user) if not show_hidden: demos = demos.exclude(hidden=True) demos_paginator = Paginator(demos, DEMOS_PAGE_SIZE, True) demos_page = demos_paginator.page(page_number) wiki_activity, docs_feed_items = None, None if waffle.flag_is_active(request, 'kumawiki'): wiki_activity = profile.wiki_activity() else: docs_feed_items = UserDocsActivityFeed(user.username).items if docs_feed_items is not False: docs_feed_items = docs_feed_items[:DOCS_ACTIVITY_MAX_ITEMS] return jingo.render( request, 'devmo/profile.html', dict(profile=profile, demos=demos, demos_paginator=demos_paginator, demos_page=demos_page, docs_feed_items=docs_feed_items, wiki_activity=wiki_activity))
def test_override(self): request = get(foo='1') waffle.get_waffle_flag_model().objects.create( name='foo') # Off for everyone. assert waffle.flag_is_active(request, 'foo')
def test_undefined_default(self): """WAFFLE_FLAG_DEFAULT controls undefined flags.""" request = get() assert waffle.flag_is_active(request, 'foo')
def test_undefined(self): """Undefined flags are always false.""" request = get() assert not waffle.flag_is_active(request, 'foo')
def payments(request, addon_id, addon, webapp=False): premium_form = forms_payments.PremiumForm(request.POST or None, request=request, addon=addon, user=request.user) region_form = forms.RegionForm(request.POST or None, product=addon, request=request) upsell_form = forms_payments.UpsellForm(request.POST or None, addon=addon, user=request.user) providers = get_providers() if 'form-TOTAL_FORMS' in request.POST: formset_data = request.POST else: formset_data = None account_list_formset = forms_payments.AccountListFormSet( data=formset_data, provider_data=[{ 'addon': addon, 'user': request.user, 'provider': provider } for provider in providers]) if request.method == 'POST': active_forms = [premium_form, region_form, upsell_form] if formset_data is not None: active_forms.append(account_list_formset) success = all(form.is_valid() for form in active_forms) if success: region_form.save() try: premium_form.save() except client.Error as err: success = False log.error('Error setting payment information (%s)' % err) messages.error( request, _(u'We encountered a problem connecting to the ' u'payment server.')) raise # We want to see these exceptions! is_free_inapp = addon.premium_type == mkt.ADDON_FREE_INAPP is_now_paid = (addon.premium_type in mkt.ADDON_PREMIUMS or is_free_inapp) # If we haven't changed to a free app, check the upsell. if is_now_paid and success: try: if not is_free_inapp: upsell_form.save() if formset_data is not None: account_list_formset.save() except client.Error as err: log.error('Error saving payment information (%s)' % err) messages.error( request, _(u'We encountered a problem connecting to ' u'the payment server.')) success = False raise # We want to see all the solitude errors now. # If everything happened successfully, give the user a pat on the back. if success: messages.success(request, _('Changes successfully saved.')) return redirect(addon.get_dev_url('payments')) # TODO: refactor this (bug 945267) android_pay = waffle.flag_is_active(request, 'android-payments') desktop_pay = waffle.flag_is_active(request, 'desktop-payments') # If android payments is not allowed then firefox os must # be 'checked' and android-mobile and android-tablet should not be. invalid_paid_platform_state = [] if not android_pay: # When android-payments is off... invalid_paid_platform_state += [('android-mobile', True), ('android-tablet', True), ('firefoxos', False)] if not desktop_pay: # When desktop-payments is off... invalid_paid_platform_state += [('desktop', True)] cannot_be_paid = (addon.premium_type == mkt.ADDON_FREE and any(premium_form.device_data['free-%s' % x] == y for x, y in invalid_paid_platform_state)) try: tier_zero = Price.objects.get(price='0.00', active=True) tier_zero_id = tier_zero.pk except Price.DoesNotExist: tier_zero = None tier_zero_id = '' # Get the regions based on tier zero. This should be all the # regions with payments enabled. paid_region_ids_by_name = [] if tier_zero: paid_region_ids_by_name = tier_zero.region_ids_by_name() platforms = PAID_PLATFORMS(request) paid_platform_names = [unicode(platform[1]) for platform in platforms] provider_regions = {} if tier_zero: provider_regions = tier_zero.provider_regions() return render( request, 'developers/payments/premium.html', { 'addon': addon, 'webapp': webapp, 'premium': addon.premium, 'form': premium_form, 'upsell_form': upsell_form, 'tier_zero_id': tier_zero_id, 'region_form': region_form, 'PLATFORMS_NAMES': PLATFORMS_NAMES, 'is_paid': (addon.premium_type in mkt.ADDON_PREMIUMS or addon.premium_type == mkt.ADDON_FREE_INAPP), 'cannot_be_paid': cannot_be_paid, 'paid_platform_names': paid_platform_names, 'is_packaged': addon.is_packaged, # Bango values 'account_list_forms': account_list_formset.forms, 'account_list_formset': account_list_formset, # Waffles 'api_pricelist_url': reverse('price-list'), 'payment_methods': { PAYMENT_METHOD_ALL: _('All'), PAYMENT_METHOD_CARD: _('Credit card'), PAYMENT_METHOD_OPERATOR: _('Carrier'), }, 'provider_lookup': dict(PROVIDER_CHOICES), 'all_paid_region_ids_by_name': paid_region_ids_by_name, 'providers': providers, 'provider_regions': provider_regions, 'enabled_provider_ids': [ acct.payment_account.provider for acct in addon.all_payment_accounts() ] })
def toggle_is_active(self, flag): return waffle.flag_is_active(get(), flag.name)
def get(self, request): # pylint: disable=too-many-statements """ Calculate basket totals given a list of sku's Create a temporary basket add the sku's and apply an optional voucher code. Then calculate the total price less discounts. If a voucher code is not provided apply a voucher in the Enterprise entitlements available to the user. Query Params: sku (string): A list of sku(s) to calculate code (string): Optional voucher code to apply to the basket. username (string): Optional username of a user for which to calculate the basket. Returns: JSON: { 'total_incl_tax_excl_discounts': basket.total_incl_tax_excl_discounts, 'total_incl_tax': basket.total_incl_tax, 'currency': basket.currency } """ RequestCache.set(TEMPORARY_BASKET_CACHE_KEY, True) # TODO: LEARNER 5463 partner = get_partner_for_site(request) skus = request.GET.getlist('sku') if not skus: return HttpResponseBadRequest(_('No SKUs provided.')) skus.sort() code = request.GET.get('code', None) try: voucher = Voucher.objects.get(code=code) if code else None except Voucher.DoesNotExist: voucher = None products = Product.objects.filter(stockrecords__partner=partner, stockrecords__partner_sku__in=skus) if not products: return HttpResponseBadRequest( _('Products with SKU(s) [{skus}] do not exist.').format( skus=', '.join(skus))) # If there is only one product apply an Enterprise entitlement voucher if not voucher and len(products) == 1: voucher = get_entitlement_voucher(request, products[0]) basket_owner = request.user requested_username = request.GET.get('username', default='') is_anonymous = request.GET.get('is_anonymous', 'false').lower() == 'true' use_default_basket = is_anonymous # validate query parameters if requested_username and is_anonymous: return HttpResponseBadRequest( _('Provide username or is_anonymous query param, but not both') ) elif not requested_username and not is_anonymous: logger.warning( "Request to Basket Calculate must supply either username or is_anonymous query" " param. Requesting user=%s. Future versions of this API will treat this " "WARNING as an ERROR and raise an exception.", basket_owner.username) requested_username = request.user.username # If a username is passed in, validate that the user has staff access or is the same user. if requested_username: if basket_owner.username.lower() == requested_username.lower(): pass elif basket_owner.is_staff: try: basket_owner = User.objects.get( username=requested_username) except User.DoesNotExist: # This case represents a user who is logged in to marketing, but # doesn't yet have an account in ecommerce. These users have # never purchased before. use_default_basket = True else: return HttpResponseForbidden('Unauthorized user credentials') if basket_owner.username == self.MARKETING_USER and not use_default_basket: # For legacy requests that predate is_anonymous parameter, we will calculate # an anonymous basket if the calculated user is the marketing user. # TODO: LEARNER-5057: Remove this special case for the marketing user # once logs show no more requests with no parameters (see above). use_default_basket = True if use_default_basket: basket_owner = None cache_key = None if use_default_basket: # For an anonymous user we can directly get the cached price, because # there can't be any enrollments or entitlements. cache_key = get_cache_key(site_comain=request.site, resource_name='calculate', skus=skus) cached_response = TieredCache.get_cached_response(cache_key) if cached_response.is_hit: return Response(cached_response.value) if waffle.flag_is_active( request, "disable_calculate_temporary_basket_atomic_transaction"): response = self._calculate_temporary_basket( basket_owner, request, products, voucher, skus, code) else: response = self._calculate_temporary_basket_atomic( basket_owner, request, products, voucher, skus, code) if response and use_default_basket: TieredCache.set_all_tiers( cache_key, response, settings.ANONYMOUS_BASKET_CALCULATE_CACHE_TIMEOUT) return Response(response)
def test_no_logging_missing_flag_by_default(self, mock_logger): request = get() waffle.flag_is_active(request, 'foo') mock_logger.log.call_count == 0
def test_logging_missing_flag(self, mock_logger): request = get() waffle.flag_is_active(request, 'foo') mock_logger.log.assert_called_with(logging.WARNING, 'Flag %s not found', 'foo')
def get_context_data(self, **kwargs): context = super(BasketSummaryView, self).get_context_data(**kwargs) formset = context.get('formset', []) lines = context.get('line_list', []) site_configuration = self.request.site.siteconfiguration failed_enterprise_consent_code = self.request.GET.get( CONSENT_FAILED_PARAM) if failed_enterprise_consent_code: messages.error( self.request, _("Could not apply the code '{code}'; it requires data sharing consent." ).format(code=failed_enterprise_consent_code)) context_updates, lines_data = self._process_basket_lines(lines) context.update(context_updates) user = self.request.user context.update({ 'analytics_data': prepare_analytics_data( user, site_configuration.segment_key, ), 'enable_client_side_checkout': False, 'sdn_check': site_configuration.enable_sdn_check }) payment_processors = site_configuration.get_payment_processors() if site_configuration.client_side_payment_processor \ and waffle.flag_is_active(self.request, CLIENT_SIDE_CHECKOUT_FLAG_NAME): payment_processors_data = self._get_payment_processors_data( payment_processors) context.update(payment_processors_data) # Total benefit displayed in price summary. # Currently only one voucher per basket is supported. try: applied_voucher = self.request.basket.vouchers.first() total_benefit = (format_benefit_value( applied_voucher.best_offer.benefit) if applied_voucher else None) except ValueError: total_benefit = None num_of_items = self.request.basket.num_items context.update({ 'formset_lines_data': zip(formset, lines_data), 'free_basket': context['order_total'].incl_tax == 0, 'homepage_url': get_lms_url(''), 'min_seat_quantity': 1, 'max_seat_quantity': 100, 'payment_processors': payment_processors, 'total_benefit': total_benefit, 'line_price': (self.request.basket.total_incl_tax_excl_discounts / num_of_items) if num_of_items > 0 else 0 }) return context
def payments(request, addon_id, addon, webapp=False): premium_form = forms_payments.PremiumForm( request.POST or None, request=request, addon=addon, user=request.amo_user) region_form = forms.RegionForm( request.POST or None, product=addon, request=request) upsell_form = forms_payments.UpsellForm( request.POST or None, addon=addon, user=request.amo_user) account_list_form = forms_payments.AccountListForm( request.POST or None, addon=addon, user=request.amo_user) if request.method == 'POST': success = all(form.is_valid() for form in [premium_form, region_form, upsell_form, account_list_form]) if success: region_form.save() try: premium_form.save() except client.Error as err: success = False log.error('Error setting payment information (%s)' % err) messages.error( request, _(u'We encountered a problem connecting to the ' u'payment server.')) raise # We want to see these exceptions! is_free_inapp = addon.premium_type == amo.ADDON_FREE_INAPP is_now_paid = (addon.premium_type in amo.ADDON_PREMIUMS or is_free_inapp) # If we haven't changed to a free app, check the upsell. if is_now_paid and success: try: if not is_free_inapp: upsell_form.save() account_list_form.save() except client.Error as err: log.error('Error saving payment information (%s)' % err) messages.error( request, _(u'We encountered a problem connecting to ' u'the payment server.')) success = False raise # We want to see all the solitude errors now. # If everything happened successfully, give the user a pat on the back. if success: messages.success(request, _('Changes successfully saved.')) return redirect(addon.get_dev_url('payments')) # TODO: refactor this (bug 945267) is_packaged = addon.is_packaged android_payments_enabled = waffle.flag_is_active(request, 'android-payments') android_packaged_enabled = waffle.flag_is_active(request, 'android-packaged') desktop_packaged_enabled = waffle.flag_is_active(request, 'desktop-packaged') # If android payments is not allowed then firefox os must # be 'checked' and android-mobile and android-tablet should not be. invalid_paid_platform_state = [] # If isn't packaged or it is packaged and the android-packaged flag is on # then we should check that desktop isn't set to True. if not is_packaged or (is_packaged and desktop_packaged_enabled): invalid_paid_platform_state.append(('desktop', True)) if not android_payments_enabled: # When android-payments is off... # If isn't packaged or it is packaged and the android-packaged flag is on # then we should check for the state of android-mobile and android-tablet. if not is_packaged or (is_packaged and android_packaged_enabled): invalid_paid_platform_state += [('android-mobile', True), ('android-tablet', True)] invalid_paid_platform_state.append(('firefoxos', False)) cannot_be_paid = ( addon.premium_type == amo.ADDON_FREE and any(premium_form.device_data['free-%s' % x] == y for x, y in invalid_paid_platform_state)) try: tier_zero = Price.objects.get(price='0.00', active=True) tier_zero_id = tier_zero.pk except Price.DoesNotExist: tier_zero = None tier_zero_id = '' # Get the regions based on tier zero. This should be all the # regions with payments enabled. paid_region_ids_by_slug = [] if tier_zero: paid_region_ids_by_slug = tier_zero.region_ids_by_slug() provider = get_provider() paid_platform_names = [unicode(platform[1]) for platform in PAID_PLATFORMS(request, is_packaged)] return render(request, 'developers/payments/premium.html', {'addon': addon, 'webapp': webapp, 'premium': addon.premium, 'form': premium_form, 'upsell_form': upsell_form, 'tier_zero_id': tier_zero_id, 'region_form': region_form, 'DEVICE_LOOKUP': DEVICE_LOOKUP, 'is_paid': (addon.premium_type in amo.ADDON_PREMIUMS or addon.premium_type == amo.ADDON_FREE_INAPP), 'cannot_be_paid': cannot_be_paid, 'paid_platform_names': paid_platform_names, 'has_incomplete_status': addon.status == amo.STATUS_NULL, 'is_packaged': addon.is_packaged, # Bango values 'account_form': provider.forms['account'](), 'account_list_form': account_list_form, # Waffles 'api_pricelist_url': reverse('price-list'), 'payment_methods': { PAYMENT_METHOD_ALL: _('All'), PAYMENT_METHOD_CARD: _('Credit card'), PAYMENT_METHOD_OPERATOR: _('Carrier'), }, 'all_paid_region_ids_by_slug': paid_region_ids_by_slug, 'provider': provider})
uuid=str(uuid_), price_tier=tier, type=amo.CONTRIB_INAPP_PENDING, paykey=paykey, user=request.amo_user) log.debug('Storing in-app payment contrib for uuid: %s' % uuid_) # If this was a pre-approval, it's completed already, we'll # double check this with PayPal, just to be sure nothing went wrong. if status == 'COMPLETED': paypal.paypal_log_cef(request, product, uuid_, 'Purchase', 'PURCHASE', 'A user purchased using pre-approval') log.debug('Status is completed for uuid: %s' % uuid_) if waffle.flag_is_active(request, 'solitude-payments'): result = client.post_pay_check(data={'pay_key': paykey}) if result['status'] == 'COMPLETED': log.debug( 'Check in-app payment is completed for uuid: %s' % uuid_) contrib.type = amo.CONTRIB_INAPP else: # In this case PayPal disagreed, we should not be trusting # what get_paykey said. Which is a worry. log.error('Check in-app payment failed on uuid: %s' % uuid_) status = 'NOT-COMPLETED' else: # TODO(solitude): remove this when solitude goes live. if paypal.check_purchase(paykey) == 'COMPLETED':
def _create_courseware_context(self, request): """ Returns and creates the rendering context for the courseware. Also returns the table of contents for the courseware. """ course_url_name = default_course_url_name(request) course_url = reverse(course_url_name, kwargs={'course_id': unicode(self.course.id)}) courseware_context = { 'csrf': csrf(self.request)['csrf_token'], 'course': self.course, 'course_url': course_url, 'chapter': self.chapter, 'section': self.section, 'init': '', 'fragment': Fragment(), 'staff_access': self.is_staff, 'masquerade': self.masquerade, 'supports_preview_menu': True, 'studio_url': get_studio_url(self.course, 'course'), 'xqa_server': settings.FEATURES.get('XQA_SERVER', "http://your_xqa_server.com"), 'bookmarks_api_url': reverse('bookmarks'), 'language_preference': self._get_language_preference(), 'disable_optimizely': not WaffleSwitchNamespace('RET').is_enabled( 'enable_optimizely_in_courseware'), 'section_title': None, 'sequence_title': None, 'disable_accordion': waffle.flag_is_active(request, UNIFIED_COURSE_VIEW_FLAG), # TODO: (Experimental Code). See https://openedx.atlassian.net/wiki/display/RET/2.+In-course+Verification+Prompts 'upgrade_link': check_and_get_upgrade_link(request, self.effective_user, self.course.id), 'upgrade_price': get_cosmetic_verified_display_price(self.course), # ENDTODO } table_of_contents = toc_for_course( self.effective_user, self.request, self.course, self.chapter_url_name, self.section_url_name, self.field_data_cache, ) courseware_context['accordion'] = render_accordion( self.request, self.course, table_of_contents['chapters'], ) courseware_context['course_sock_fragment'] = CourseSockFragmentView( ).render_to_fragment(request, course=self.course) # entrance exam data self._add_entrance_exam_to_context(courseware_context) # staff masquerading data if not is_course_open_for_learner(self.effective_user, self.course): # Disable student view button if user is staff and # course is not yet visible to students. courseware_context['disable_student_access'] = True courseware_context['supports_preview_menu'] = False if self.section: # chromeless data if self.section.chrome: chrome = [ s.strip() for s in self.section.chrome.lower().split(",") ] if 'accordion' not in chrome: courseware_context['disable_accordion'] = True if 'tabs' not in chrome: courseware_context['disable_tabs'] = True # default tab if self.section.default_tab: courseware_context['default_tab'] = self.section.default_tab # section data courseware_context[ 'section_title'] = self.section.display_name_with_default section_context = self._create_section_context( table_of_contents['previous_of_active_section'], table_of_contents['next_of_active_section'], ) courseware_context['fragment'] = self.section.render( STUDENT_VIEW, section_context) if self.section.position and self.section.has_children: display_items = self.section.get_display_items() if display_items: try: courseware_context['sequence_title'] = display_items[self.section.position - 1] \ .display_name_with_default except IndexError: log.exception( "IndexError loading courseware for user %s, course %s, section %s, position %d. Total items: %d. URL: %s", self.real_user.username, self.course.id, self.section.display_name_with_default, self.section.position, len(display_items), self.url, ) raise return courseware_context
def get_table_items(self, request): items = [] enrollment_items = { 'name': _('Enrollment'), 'icon': 'fa-child', 'heading': _('Who are my learners?'), 'items': [ { 'title': ugettext_noop('How many learners are in my course?'), 'view': 'courses:enrollment:activity', 'breadcrumbs': [_('Activity')], 'fragment': '', 'scope': 'course', 'lens': 'enrollment', 'report': 'activity', 'depth': '' }, { 'title': ugettext_noop('How old are my learners?'), 'view': 'courses:enrollment:demographics_age', 'breadcrumbs': [_('Demographics'), _('Age')], 'fragment': '', 'scope': 'course', 'lens': 'enrollment', 'report': 'demographics', 'depth': 'age' }, { 'title': ugettext_noop( 'What level of education do my learners have?'), 'view': 'courses:enrollment:demographics_education', 'breadcrumbs': [_('Demographics'), _('Education')], 'fragment': '', 'scope': 'course', 'lens': 'enrollment', 'report': 'demographics', 'depth': 'education' }, { 'title': ugettext_noop('What is the learner gender breakdown?'), 'view': 'courses:enrollment:demographics_gender', 'breadcrumbs': [_('Demographics'), _('Gender')], 'fragment': '', 'scope': 'course', 'lens': 'enrollment', 'report': 'demographics', 'depth': 'gender' }, { 'title': ugettext_noop('Where are my learners?'), 'view': 'courses:enrollment:geography', 'breadcrumbs': [_('Geography')], 'fragment': '', 'scope': 'course', 'lens': 'enrollment', 'report': 'geography', 'depth': '' }, ], } items.append(enrollment_items) engagement_items = { 'name': _('Engagement'), 'icon': 'fa-bar-chart', 'heading': _('What are learners doing in my course?'), 'items': [{ 'title': ugettext_noop( 'How many learners are interacting with my course?'), 'view': 'courses:engagement:content', 'breadcrumbs': [_('Content')], 'fragment': '', 'scope': 'course', 'lens': 'engagement', 'report': 'content', 'depth': '' }] } if switch_is_active('enable_engagement_videos_pages'): engagement_items['items'].append({ 'title': ugettext_noop('How did learners interact with course videos?'), 'view': 'courses:engagement:videos', 'breadcrumbs': [_('Videos')], 'fragment': '', 'scope': 'course', 'lens': 'engagement', 'report': 'videos', 'depth': '' }) items.append(engagement_items) if self.course_api_enabled: subitems = [{ 'title': ugettext_noop( 'How are learners doing on graded course assignments?'), 'view': 'courses:performance:graded_content', 'breadcrumbs': [_('Graded Content')], 'fragment': '', 'scope': 'course', 'lens': 'performance', 'report': 'graded', 'depth': '' }, { 'title': ugettext_noop('How are learners doing on ungraded exercises?'), 'view': 'courses:performance:ungraded_content', 'breadcrumbs': [_('Ungraded Problems')], 'fragment': '', 'scope': 'course', 'lens': 'performance', 'report': 'ungraded', 'depth': '' }] if switch_is_active('enable_performance_learning_outcome'): subitems.append({ 'title': ugettext_noop( 'What is the breakdown for course learning outcomes?'), 'view': 'courses:performance:learning_outcomes', 'breadcrumbs': [_('Learning Outcomes')], 'fragment': '', 'scope': 'course', 'lens': 'performance', 'report': 'outcomes', 'depth': '' }) if switch_is_active('enable_problem_response_download'): try: info = CourseReportDownloadPresenter( self.course_id).get_report_info( report_name=CourseReportDownloadPresenter. PROBLEM_RESPONSES) except NotFoundError: info = {} if 'download_url' in info: # A problem response report CSV is available: subitems.append({ 'title': ugettext_noop( 'How are learners responding to questions?'), 'view': 'courses:csv:performance_problem_responses', 'breadcrumbs': [_('Problem Response Report')], 'format': 'csv', }) items.append({ 'name': _('Performance'), 'icon': 'fa-check-square-o', 'heading': _('How are learners doing on course assignments?'), 'items': subitems }) if flag_is_active(request, 'display_learner_analytics'): items.append({ 'name': _('Learners'), 'icon': 'fa-users', 'heading': _('What are individual learners doing?'), 'items': [ { 'title': ugettext_noop("Who is engaged? Who isn't?"), 'view': 'courses:learners:learners', 'breadcrumbs': [_('All Learners')], 'fragment': '#?ignore_segments=inactive', 'scope': 'course', 'lens': 'learners', 'report': 'roster', 'depth': '' }, # TODO: this is commented out until we complete the deep linking work, AN-6671 # { # 'title': _('Who has been active recently?'), # 'view': 'courses:learners:learners', # TODO: map this to the actual action in AN-6205 # # TODO: what would the breadcrumbs be? # 'breadcrumbs': [_('Learners')] # }, # { # 'title': _('Who is most engaged in the discussions?'), # 'view': 'courses:learners:learners', # TODO: map this to the actual action in AN-6205 # # TODO: what would the breadcrumbs be? # 'breadcrumbs': [_('Learners')] # }, # { # 'title': _("Who hasn't watched videos recently?"), # 'view': 'courses:learners:learners', # TODO: map this to the actual action in AN-6205 # # TODO: what would the breadcrumbs be? # 'breadcrumbs': [_('Learners')] # } ] }) translate_dict_values(items, ('name', )) for item in items: translate_dict_values(item['items'], ('title', )) return items
def pay(request, signed_req, pay_req): paykey, status = '', '' preapproval = None if request.amo_user: preapproval = request.amo_user.get_preapproval() tier, price, currency = _get_price(pay_req, preapproval=preapproval) source = request.POST.get('source', '') product = pay_req['_config'].addon # L10n: {0} is the product name. {1} is the application name. contrib_for = ( _(u'Firefox Marketplace in-app payment for {0} to {1}').format( pay_req['request']['name'], product.name)) # TODO(solitude): solitude lib will create these for us. uuid_ = hashlib.md5(str(uuid.uuid4())).hexdigest() if waffle.flag_is_active(request, 'solitude-payments'): # TODO(solitude): when the migration of data is completed, we # will be able to remove this. Seller data is populated in solitude # on submission or devhub changes. If those don't occur, you won't be # able to sell at all. client.create_seller_for_pay(product) complete = reverse('inapp_pay.pay_status', args=[pay_req['_config'].pk, 'complete']) cancel = reverse('inapp_pay.pay_status', args=[pay_req['_config'].pk, 'cancel']) # TODO(bug 748137): remove retry is False. try: result = client.pay( { 'amount': price, 'currency': currency, 'buyer': request.amo_user, 'seller': product, 'memo': contrib_for, 'complete': complete, 'cancel': cancel }, retry=False) except client.Error as exc: paypal.paypal_log_cef(request, product, uuid_, 'in-app PayKey Failure', 'PAYKEYFAIL', 'There was an error getting the paykey') log.error(u'Error getting paykey, in-app payment: %s' % pay_req['_config'].pk, exc_info=True) InappPayLog.log(request, 'PAY_ERROR', config=pay_req['_config']) return render_error(request, exc) #TODO(solitude): just use the dictionary when solitude is live. paykey = result.get('pay_key', '') status = result.get('status', '') uuid_ = result.get('uuid', '') else: try: paykey, status = paypal.get_paykey( dict( amount=price, chains=settings.PAYPAL_CHAINS, currency=currency, email=product.paypal_id, ip=request.META.get('REMOTE_ADDR'), memo=contrib_for, pattern='inapp_pay.pay_status', preapproval=preapproval, qs={'realurl': request.POST.get('realurl')}, slug=pay_req['_config'].pk, # passed to pay_done() # via reverse() uuid=uuid_)) except paypal.PaypalError, exc: paypal.paypal_log_cef(request, product, uuid_, 'in-app PayKey Failure', 'PAYKEYFAIL', 'There was an error getting the paykey') log.error(u'Error getting paykey, in-app payment: %s' % pay_req['_config'].pk, exc_info=True) InappPayLog.log(request, 'PAY_ERROR', config=pay_req['_config']) return render_error(request, exc)
def get_context_data(self, **kwargs): context = super(BasketSummaryView, self).get_context_data(**kwargs) formset = context.get('formset', []) lines = context.get('line_list', []) lines_data = [] is_verification_required = is_bulk_purchase = False switch_link_text = partner_sku = '' basket = self.request.basket site = self.request.site site_configuration = site.siteconfiguration for line in lines: course_key = CourseKey.from_string(line.product.attr.course_key) course_name = None image_url = None short_description = None try: course = get_course_info_from_catalog(self.request.site, course_key) try: image_url = course['image']['src'] except (KeyError, TypeError): image_url = '' short_description = course.get('short_description', '') course_name = course.get('title', '') except (ConnectionError, SlumberBaseException, Timeout): logger.exception('Failed to retrieve data from Catalog Service for course [%s].', course_key) if self.request.site.siteconfiguration.enable_enrollment_codes: # Get variables for the switch link that toggles from enrollment codes and seat. switch_link_text, partner_sku = get_basket_switch_data(line.product) if line.product.get_product_class().name == ENROLLMENT_CODE_PRODUCT_CLASS_NAME: is_bulk_purchase = True # Iterate on message storage so all messages are marked as read. # This will hide the success messages when a user updates the quantity # for an item in the basket. list(messages.get_messages(self.request)) if line.has_discount: benefit = basket.applied_offers().values()[0].benefit benefit_value = format_benefit_value(benefit) else: benefit_value = None lines_data.append({ 'seat_type': self._determine_seat_type(line.product), 'course_name': course_name, 'course_key': course_key, 'image_url': image_url, 'course_short_description': short_description, 'benefit_value': benefit_value, 'enrollment_code': line.product.get_product_class().name == ENROLLMENT_CODE_PRODUCT_CLASS_NAME, 'line': line, }) user = self.request.user context.update({ 'analytics_data': prepare_analytics_data( user, self.request.site.siteconfiguration.segment_key, unicode(course_key) ), 'enable_client_side_checkout': False, }) if site_configuration.client_side_payment_processor \ and waffle.flag_is_active(self.request, CLIENT_SIDE_CHECKOUT_FLAG_NAME): payment_processor_class = site_configuration.get_client_side_payment_processor_class() if payment_processor_class: payment_processor = payment_processor_class(site) context.update({ 'enable_client_side_checkout': True, 'payment_form': PaymentForm(user=user, initial={'basket': basket}, label_suffix=''), 'payment_url': payment_processor.client_side_payment_url, }) else: msg = 'Unable to load client-side payment processor [{processor}] for ' \ 'site configuration [{sc}]'.format(processor=site_configuration.client_side_payment_processor, sc=site_configuration.id) raise SiteConfigurationError(msg) # Check product attributes to determine if ID verification is required for this basket try: is_verification_required = line.product.attr.id_verification_required \ and line.product.attr.certificate_type != 'credit' except AttributeError: pass context.update({ 'free_basket': context['order_total'].incl_tax == 0, 'payment_processors': site_configuration.get_payment_processors(), 'homepage_url': get_lms_url(''), 'formset_lines_data': zip(formset, lines_data), 'is_verification_required': is_verification_required, 'min_seat_quantity': 1, 'is_bulk_purchase': is_bulk_purchase, 'switch_link_text': switch_link_text, 'partner_sku': partner_sku, }) return context