Пример #1
0
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['staff'] = self.staff
        context['start_date'] = self.start_date
        context['end_date'] = self.end_date
        context['today'] = datetime.datetime.today()
        context['total_tasks'] = self.queryset.count()
        if self.search_phrase != '':
            context['search_count'] = self.queryset.count()
            context['search_phrase'] = self.search_phrase
            context['search_words'] = ' '.join(self.qb.words)
        # exclude CollegePlan and CollegeBoundary
        context['locations'] = Location.objects.exclude(
            name__startswith='College')
        context['selected_locations'] = self.locations
        context['selected_location_pks'] = self.locations.values_list(
            'pk', flat=True)

        context['tasktypes'] = TaskType.objects.all()
        context['selected_tasktypes'] = self.tasktypes
        context['selected_tasktype_pks'] = self.tasktypes.values_list(
            'pk', flat=True)

        # query string to be included in pagination links
        qd = QueryDict(self.request.GET.urlencode(), mutable=True)
        try:
            qd.pop('page')
        except KeyError:
            pass
        context['query_string'] = '?' + qd.urlencode() + '&' if qd else '?'
        return context
Пример #2
0
    def get_feedback_filter_params(self):
        # We need to be careful here because some of the filter_form params
        # are for FRs not the nested Feedback. If we include those and then
        # we edit the FR in a way where it no longer matches the params we'll
        # get a 404 as we'll exclude ourself. Given that we only want to pass
        # along params that are for Feedback.
        params_to_exclude = (
            "search",
            "state",
            "theme",
            "priority",
            "effort",
            "shipped_start_date",
            "shipped_end_date",
            "shipped_date_range",
        )
        filter_dict = self.get_filter_form().data
        qd = QueryDict(mutable=True)
        qd.update(filter_dict)
        for param_name in params_to_exclude:
            if param_name in qd:
                qd.pop(param_name)

        # HACK: there is surely a better way but the form returns empty values
        # here as None but when we urlencode that we get 'None'. DateField
        # doesn't like 'None' b/c it's not a valid date. So... here we just
        # turn None into '' which the form is happy with.
        if qd.get("feedback_date_range", None) is None:
            qd["feedback_date_range"] = ""
        if qd.get("feedback_start_date", None) is None:
            qd["feedback_start_date"] = ""
        if qd.get("feedback_end_date", None) is None:
            qd["feedback_end_date"] = ""

        return qd
Пример #3
0
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['staff'] = self.user.staff
        context['start_date'] = self.start_date
        context['end_date'] = self.end_date
        context['today'] = datetime.datetime.today()

        # get some useful summary data about the queryset
        context['days'] = self.queryset.count()
        context['days_worked'] = self.queryset.filter(hours__gt=0.0).count()
        context['total_hours'] = self.queryset.aggregate(
            total_hours=Sum('hours'))['total_hours']
        task_qs = Task.objects.filter(staff=self.user.staff).filter(
            completed__in=self.queryset.values_list('day', flat=True))
        context['total_tasks'] = task_qs.count()

        # filter for search term
        if self.search_phrase != '':
            qb = QueryBuilder(self.search_phrase, 'description')
            qb.parse_parts()
            context['search_count'] = task_qs.filter(qb.query).count()
            context['search_phrase'] = self.search_phrase
            context['search_words'] = ' '.join(qb.words)

        # create word cloud from task descriptions
        words = ' '.join(task_qs.values_list('description', flat=True)).lower()
        if words and False:  # TODO: get tkinter working on heroku to make matplotlib work
            stopwords = set(STOPWORDS)
            stopwords.add('block')

            cloud = WordCloud(background_color='white',
                              stopwords=stopwords,
                              width=960,
                              height=100,
                              max_font_size=50,
                              min_font_size=2,
                              font_path=FONT_PATH,
                              max_words=300,
                              prefer_horizontal=0.8)
            cloud.generate(words)
            cloud.recolor(color_func=color_func, random_state=3)
            img = cloud.to_image()

            in_mem_file = BytesIO()
            img.save(in_mem_file, format="PNG")
            img_bytes = in_mem_file.getvalue()
            result_bytes = base64.b64encode(img_bytes)
            result_str = result_bytes.decode('ascii')
            context['wordcloud'] = 'data:image/png;base64,' + result_str

        # query string to be included in pagination links
        qd = QueryDict(self.request.GET.urlencode(), mutable=True)
        try:
            qd.pop('page')
        except KeyError:
            pass
        context['query_string'] = '?' + qd.urlencode() + '&' if qd else '?'
        return context
Пример #4
0
    def update_params(param_str, **kwargs):
        query_dict = QueryDict(param_str, True)

        for key, val in kwargs.iteritems():
            if val:
                query_dict[key] = val
            else:
                query_dict.pop(key) if query_dict.has_key(key) else None

        return UrlHelper.format_params(query_dict)
Пример #5
0
    def update_params(param_str, **kwargs):
        query_dict = QueryDict(param_str, True)

        for key, val in kwargs.iteritems():
            if val:
                query_dict[key] = val
            else:
                query_dict.pop(key) if query_dict.has_key(key) else None

        return UrlHelper.format_params(query_dict)
Пример #6
0
def map_discover_query_args(url: str, args: Mapping[str, str]) -> Mapping[str, Any]:
    """
    Extracts discover arguments from the discover link's query string
    """
    parsed_url = urlparse(url)
    query = QueryDict(parsed_url.query).copy()

    # Remove some unused query keys
    query.pop("widths", None)

    return dict(**args, query=query)
Пример #7
0
 def url_param_replace(self, **kwargs):
     query = QueryDict(self.request.META['QUERY_STRING'], mutable=True)
     for key, value in kwargs.items():
         if not key:
             query.pop(key, None)
         else:
             query[key] = value
     if query:
         return self.request.path_info + '?' + query.urlencode('{}')
     else:
         return self.request.path_info
Пример #8
0
def map_discover_query_args(url: str, args: Mapping[str, str]) -> Mapping[str, Any]:
    """
    Extracts discover arguments from the discover link's query string
    """
    # Slack uses HTML escaped ampersands in its Event Links, when need
    # to be unescaped for QueryDict to split properly.
    url = html.unescape(url)
    parsed_url = urlparse(url)
    query = QueryDict(parsed_url.query).copy()

    # Remove some unused query keys
    query.pop("widths", None)

    return dict(**args, query=query)
Пример #9
0
    def get(self, request, *args, **kwargs):
        request_meta_qs = request.META["QUERY_STRING"]
        request_get = request.GET
        response_qs = None

        if request_meta_qs:
            response_qs = request_meta_qs
        elif "oauth_token" in request_get and "oauth_verifier" in request_get:
            response_qs = request_get.urlencode()

        try:
            response_qs_parsed = urllib.parse.parse_qs(response_qs)
            assert "oauth_token" in response_qs_parsed
            assert "oauth_verifier" in response_qs_parsed
        except (AssertionError, TypeError):
            logger.exception("Did not receive a valid oauth response.")
            messages.add_message(
                request,
                messages.WARNING,
                # Translators: This warning message is shown to users when the response received from Wikimedia OAuth servers is not a valid one.
                _("Did not receive a valid oauth response."),
            )
            raise PermissionDenied

        # Get the handshaker. It should have already been constructed by
        # OAuthInitializeView.
        domain = self.request.get_host()
        try:
            assert domain in settings.ALLOWED_HOSTS
        except (AssertionError, DisallowedHost):
            logger.exception("Domain is not an allowed host")
            messages.add_message(
                request,
                messages.WARNING,
                # Translators: This message is shown when the OAuth login process fails because the request came from the wrong website. Don't translate {domain}.
                _("{domain} is not an allowed host.").format(domain=domain),
            )
            raise PermissionDenied

        try:
            handshaker = _get_handshaker()
        except AssertionError:
            # get_handshaker will throw AssertionErrors for invalid data.
            logger.exception("Could not find handshaker")
            messages.add_message(
                request,
                messages.WARNING,
                # Translators: This message is shown when the OAuth login process fails.
                _("Could not find handshaker."),
            )
            raise PermissionDenied

        # Get the session token placed by OAuthInitializeView.
        session_token = request.session.pop("request_token", None)

        if not session_token:
            logger.info("No session token.")
            messages.add_message(
                request,
                messages.WARNING,
                # Translators: This message is shown when the OAuth login process fails.
                _("No session token."),
            )
            raise PermissionDenied

        # Rehydrate it into a request token.
        request_token = _rehydrate_token(session_token)

        if not request_token:
            logger.info("No request token.")
            messages.add_message(
                request,
                messages.WARNING,
                # Translators: This message is shown when the OAuth login process fails.
                _("No request token."),
            )
            raise PermissionDenied

        # See if we can complete the OAuth process.
        try:
            access_token = handshaker.complete(request_token, response_qs)
        except:
            logger.exception("Access token generation failed.")
            messages.add_message(
                request,
                messages.WARNING,
                # Translators: This message is shown when the OAuth login process fails.
                _("Access token generation failed."),
            )
            raise PermissionDenied

        user = authenticate(request=request,
                            access_token=access_token,
                            handshaker=handshaker)
        created = request.session.pop("user_created", False)

        if user and not user.is_active:
            # Do NOT log in the user.

            if created:
                messages.add_message(
                    request,
                    messages.WARNING,
                    # fmt: off
                    # Translators: If the user tries to log in, but their account does not meet certain requirements, they cannot login.
                    _("Your Wikipedia account does not meet the eligibility criteria in the terms of use, so your Wikipedia Library Card Platform account cannot be activated."
                      ),
                    # fmt: on
                )
            else:
                messages.add_message(
                    request,
                    messages.WARNING,
                    # fmt: off
                    # Translators: If the user tries to log in, but their account does not meet certain requirements, they cannot login.
                    _("Your Wikipedia account no longer meets the eligibility criteria in the terms of use, so you cannot be logged in. If you think you should be able to log in, please email [email protected]."
                      ),
                    # fmt: on
                )

            return_url = reverse_lazy("terms")

        elif user:
            login(request, user)

            if created:
                messages.add_message(
                    request,
                    messages.INFO,
                    # Translators: this message is displayed to users with brand new accounts.
                    _("Welcome! Please agree to the terms of use."),
                )
                return_url = reverse_lazy("terms")
            else:
                # We're using this twice. Not very DRY.
                # Send user either to the destination specified in the 'next'
                # parameter or to their own editor detail page.
                if user.userprofile.terms_of_use:
                    try:
                        # Create a QueryDict from the 'get' session dict.
                        query_dict = QueryDict(urlencode(
                            request.session["get"]),
                                               mutable=True)
                        # Pop the 'next' parameter out of the QueryDict.
                        next = query_dict.pop("next")
                        # Set the return url to the value of 'next'. Basic.
                        return_url = next[0]
                        # If there is anything left in the QueryDict after popping
                        # 'next', append it to the return url. This preserves state
                        # for filtered lists and redirected form submissions like
                        # the partner suggestion form.
                        if query_dict:
                            return_url += "?" + urlencode(query_dict)
                        logger.info(
                            "User authenticated. Sending them on for "
                            'post-login redirection per "next" parameter.')
                    except KeyError:
                        return_url = reverse_lazy("homepage")
                        logger.warning(
                            'User authenticated. No "next" parameter '
                            "for post-login redirection.")
                else:
                    messages.add_message(
                        request,
                        messages.INFO,
                        # Translators: This message is shown when a user logs back in to the site after their first time and hasn't agreed to the terms of use.
                        _("Welcome back! Please agree to the terms of use."),
                    )
                    return_url = reverse_lazy("terms")
        else:
            return_url = reverse_lazy("homepage")

        return HttpResponseRedirect(return_url)
Пример #10
0
    def get(self, request, *args, **kwargs):
        # The site might be running under multiple URLs, so find out the current
        # one (and make sure it's legit).
        # The Sites framework was designed for different URLs that correspond to
        # different databases or functionality - it's not a good fit here.
        domain = self.request.get_host()
        try:
            assert domain in settings.ALLOWED_HOSTS  # safety first!
        except (AssertionError, DisallowedHost):
            logger.exception()
            messages.add_message(
                request,
                messages.WARNING,
                # Translators: This message is shown when the OAuth login process fails because the request came from the wrong website. Don't translate {domain}.
                _("{domain} is not an allowed host.").format(domain=domain),
            )
            raise PermissionDenied

        # Try to capture the relevant page state, including desired destination
        try:
            request.session["get"] = request.GET
            logger.info("Found get parameters for post-login redirection.")
        except:
            logger.warning("No get parameters for post-login redirection.")
            pass

        # If the user has already logged in, let's not spam the OAuth provider.
        if self.request.user.is_authenticated:
            # We're using this twice. Not very DRY.
            # Send user either to the destination specified in the 'next'
            # parameter or to their own editor detail page.
            try:
                # Create a QueryDict from the 'get' session dict.
                query_dict = QueryDict(urlencode(request.session["get"]),
                                       mutable=True)
                # Pop the 'next' parameter out of the QueryDict.
                next = query_dict.pop("next")
                # Set the return url to the value of 'next'. Basic.
                return_url = next[0]
                # If there is anything left in the QueryDict after popping
                # 'next', append it to the return url. This preserves state
                # for filtered lists and redirected form submissions like
                # the partner suggestion form.
                if query_dict:
                    return_url += "?" + urlencode(query_dict)
                logger.info("User is already authenticated. Sending them on "
                            'for post-login redirection per "next" parameter.')
            except KeyError:
                return_url = reverse_lazy("homepage")
                logger.warning('User already authenticated. No "next" '
                               "parameter for post-login redirection.")

            return HttpResponseRedirect(return_url)
        else:
            # Get handshaker for the configured wiki oauth URL.
            handshaker = _get_handshaker()
            logger.info("handshaker gotten.")

            try:
                redirect, request_token = handshaker.initiate()
            except:
                logger.exception("Handshaker not initiated.")
                raise

            local_redirect = _localize_oauth_redirect(redirect)

            logger.info("handshaker initiated.")
            self.request.session["request_token"] = _dehydrate_token(
                request_token)
            return HttpResponseRedirect(local_redirect)
Пример #11
0
    def get(self, request, *args, **kwargs):
        request_meta_qs = request.META['QUERY_STRING']
        request_get = request.GET
        response_qs = None

        if request_meta_qs:
            response_qs = request_meta_qs
        elif 'oauth_token' in request_get and 'oauth_verifier' in request_get:
            response_qs = request_get.urlencode()

        try:
            response_qs_parsed = urlparse.parse_qs(response_qs)
            assert 'oauth_token' in response_qs_parsed
            assert 'oauth_verifier' in response_qs_parsed
        except (AssertionError, TypeError):
            logger.exception('Did not receive a valid oauth response.')
            messages.add_message(request, messages.WARNING,
                                 _('Did not receive a valid oauth response.'))
            raise PermissionDenied

        # Get the handshaker. It should have already been constructed by
        # OAuthInitializeView.
        try:
            domain = self.request.get_host()
            assert domain in settings.ALLOWED_HOSTS
        except (AssertionError, DisallowedHost):
            logger.exception('Domain is not an allowed host')
            messages.add_message(
                request, messages.WARNING,
                _('{domain} is not an allowed host.').format(domain=domain))
            raise PermissionDenied

        try:
            handshaker = _get_handshaker()
        except AssertionError:
            # get_handshaker will throw AssertionErrors for invalid data.
            logger.exception('Could not find handshaker')
            messages.add_message(
                request,
                messages.WARNING,
                # Translators: This message is shown when the OAuth login process fails.
                _('Could not find handshaker.'))
            raise PermissionDenied

        # Get the request token, placed in session by OAuthInitializeView.
        session_token = request.session.pop('request_token', None)
        request_token = _rehydrate_token(session_token)

        if not request_token:
            logger.info('No request token.')
            messages.add_message(
                request,
                messages.WARNING,
                # Translators: This message is shown when the OAuth login process fails.
                _('No request token.'))
            raise PermissionDenied

        # See if we can complete the OAuth process.
        try:
            access_token = handshaker.complete(request_token, response_qs)
        except:
            logger.exception('Access token generation failed.')
            messages.add_message(
                request,
                messages.WARNING,
                # Translators: This message is shown when the OAuth login process fails.
                _('Access token generation failed.'))
            raise PermissionDenied

        user = authenticate(request=request,
                            access_token=access_token,
                            handshaker=handshaker)
        created = request.session.pop('user_created', False)

        if not user.is_active:
            # Do NOT log in the user.

            if created:
                messages.add_message(
                    request,
                    messages.WARNING,
                    # Translators: If the user tries to log in, but their account does not meet certain requirements, they cannot login.
                    _('Your Wikipedia account does not meet the eligibility '
                      'criteria in the terms of use, so your Wikipedia Library '
                      'Card Platform account cannot be activated.'))
            else:
                # Translators: If the user tries to log in, but their account does not meet certain requirements, they cannot login. Translate Wikipedia Library in the same way as the global branch is named (click through from https://meta.wikimedia.org/wiki/The_Wikipedia_Library).
                messages.add_message(
                    request, messages.WARNING,
                    _('Your Wikipedia account no longer '
                      'meets the eligibility criteria in the terms of use, so '
                      'you cannot be logged in. If you think you should be '
                      'able to log in, please email '
                      '[email protected].'))

            return_url = reverse_lazy('terms')

        else:
            login(request, user)

            if created:
                # Translators: this message is displayed to users with brand new accounts.
                messages.add_message(
                    request, messages.INFO,
                    _('Welcome! '
                      'Please agree to the terms of use.'))
                return_url = reverse_lazy('terms')
            else:
                # Translators: This message is shown when a user logs back in to the site after their first time.
                messages.add_message(request, messages.INFO,
                                     _('Welcome back!'))
                # We're using this twice. Not very DRY.
                # Send user either to the destination specified in the 'next'
                # parameter or to their own editor detail page.
                try:
                    # Create a QueryDict from the 'get' session dict.
                    query_dict = QueryDict(urlencode(request.session['get']),
                                           mutable=True)
                    # Pop the 'next' parameter out of the QueryDict.
                    next = query_dict.pop('next')
                    # Set the return url to the value of 'next'. Basic.
                    return_url = next[0].encode('ascii', 'ignore')
                    # If there is anything left in the QueryDict after popping
                    # 'next', append it to the return url. This preserves state
                    # for filtered lists and redirected form submissions like
                    # the partner suggestion form.
                    if query_dict:
                        return_url += '?' + urlencode(query_dict)
                    logger.info('User authenticated. Sending them on for '
                                'post-login redirection per "next" parameter.')
                except KeyError:
                    return_url = reverse_lazy('users:editor_detail',
                                              kwargs={'pk': user.editor.pk})
                    logger.warning('User authenticated. No "next" parameter '
                                   'for post-login redirection.')

        return HttpResponseRedirect(return_url)