Example #1
0
    def get_base_queryset(self, all_aids=False):
        """Return the list of aids based on the initial search querysting."""

        from aids.forms import AidSearchForm
        data = self.get_base_querystring_data()
        form = AidSearchForm(data)
        if all_aids:
            qs = form.filter_queryset(
                qs=Aid.objects.all(),
                apply_generic_aid_filter=False).distinct()
        else:
            qs = form.filter_queryset(
                apply_generic_aid_filter=False).distinct()

        # Annotate aids contained in the highlighted_aids field
        # This field will be helpful to order the queryset
        # source: https://stackoverflow.com/a/44048355
        highlighted_aids_id_list = self.highlighted_aids.values_list(
            'id', flat=True)  # noqa
        qs = qs.annotate(is_highlighted_aid=Count(
            Case(When(id__in=highlighted_aids_id_list, then=1),
                 output_field=IntegerField())))
        # Simpler approach, but error-prone (aid could be highlighted in another SearchPage)  # noqa
        # qs = qs.annotate(is_highlighted_aid=Count('highlighted_in_search_pages'))  # noqa

        # Also exlude aids contained in the excluded_aids field
        excluded_aids_id_list = self.excluded_aids.values_list('id', flat=True)
        qs = qs.exclude(id__in=excluded_aids_id_list)

        return qs
Example #2
0
    def get_queryset(self):
        """Filter data according to search query."""

        qs = self.get_base_queryset()
        filter_form = AidSearchForm(data=self.request.GET)
        results = filter_form.filter_queryset(qs)
        ordered_results = filter_form.order_queryset(results).distinct()
        return ordered_results
Example #3
0
    def get_queryset(self):
        """Filter data according to search query."""

        qs = self.get_base_queryset()
        filter_form = AidSearchForm(data=self.request.GET)
        apply_filter = 'prevent_generic_filter' not in self.request.GET
        results = filter_form.filter_queryset(qs, apply_generic_aid_filter=apply_filter)
        ordered_results = filter_form.order_queryset(results).distinct()
        return ordered_results
Example #4
0
def send_alert_confirmation_email(user_email, alert_token):
    """Send an alert confirmation link to the user.

    The email contains a token that can be used to validate the
    email ownership.
    """
    try:
        alert = Alert.objects.get(token=alert_token)
    except (Alert.DoesNotExist):
        # In case we could not find any valid user with the given email
        # we don't raise any exception, because we can't give any hints
        # about whether or not any particular email has an account
        # on our site.
        return

    # Use the search form to parse the search querydict and
    # extract the perimeter
    querydict = QueryDict(alert.querystring)
    search_form = AidSearchForm(querydict)
    if search_form.is_valid():
        perimeter = search_form.cleaned_data.get('perimeter', None)
    else:
        perimeter = None

    site = Site.objects.get_current()
    scheme = 'https'
    base_url = '{scheme}://{domain}'.format(scheme=scheme, domain=site.domain)
    alert_validation_link = reverse('alert_validate_view', args=[alert_token])
    alert_date = '{:%d/%m/%Y %H:%M:%S}'.format(alert.date_created)
    subject = _('Please confirm your Aides-territoires alert (%(date)s)') % {
        'date': alert_date
    }

    if alert.alert_frequency == Alert.FREQUENCIES.daily:
        frequency = _(
            'You will receive a daily email whenever new matching aids will be published.'
        )  # noqa
    else:
        frequency = _(
            'You will receive a weekly email whenever new matching aids will be published.'
        )  # noqa

    email_body = render_to_string(
        TEMPLATE, {
            'base_url': base_url,
            'alert': alert,
            'frequency': frequency,
            'perimeter': perimeter,
            'alert_validation_link': '{}{}'.format(base_url,
                                                   alert_validation_link)
        })
    send_mail(subject,
              email_body,
              settings.DEFAULT_FROM_EMAIL, [user_email],
              fail_silently=False)
Example #5
0
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)

        initial = self.get_initial()
        filter_form = AidSearchForm(initial)
        theme_aids = filter_form.filter_queryset()

        context['total_aids'] = theme_aids \
            .values('id') \
            .distinct() \
            .count()
        return context
Example #6
0
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)

        current_search = self.request.session.get(settings.SEARCH_COOKIE_NAME, '')
        context['current_search'] = current_search
        # Here we reconstruct the AidSearchForm from the current_search
        # querystring. This is needed to display some of the search filters.
        current_search_form = AidSearchForm(data=QueryDict(current_search))
        if current_search_form.is_valid():
            context['current_search_dict'] = clean_search_form(
                current_search_form.cleaned_data, remove_extra_fields=True)

        if self.request.GET.get('open-modal'):
            context['open_modal'] = True

        context['programs'] = self.object.programs \
            .exclude(logo__isnull=True) \
            .exclude(logo='') \
            .distinct()
        financers = self.object.financers.all()

        # We don't want to display instructors if they are the same as the
        # financers
        all_instructors = self.object.instructors.all()
        instructors = [i for i in all_instructors if i not in financers]
        context.update({
            'financers': financers,
            'instructors': instructors,
        })

        context['financers_with_logo'] = financers \
            .exclude(logo__isnull=True) \
            .exclude(logo='') \
            .distinct()

        context['idf_financer'] = financers \
            .filter(pk=40)

        context['eligibility_criteria'] = any((
            self.object.mobilization_steps,
            self.object.destinations,
            self.object.project_examples,
            self.object.eligibility))

        context['alert_form'] = AlertForm(label_suffix='')
        if self.request.user.is_authenticated:
            context['aid_match_project_form'] = AidMatchProjectForm(label_suffix='')
            if self.request.user.beneficiary_organization:
                context['projects'] = Project.objects \
                    .filter(organizations=self.request.user.beneficiary_organization.pk) \
                    .order_by('name')

        return context
Example #7
0
    def get_queryset(self):
        """Filter data according to search query."""

        qs = Aid.objects \
            .published() \
            .open() \
            .select_related('perimeter') \
            .prefetch_related('backers') \
            .order_by('perimeter__scale', 'submission_deadline')

        filter_form = AidSearchForm(data=self.request.GET)
        filtered_qs = filter_form.filter_queryset(qs)
        return filtered_qs
Example #8
0
    def get_new_aids(self):
        """Get the list of aids that match the stored search params."""

        querydict = QueryDict(self.querystring)
        search_form = AidSearchForm(querydict)
        base_qs = Aid.objects \
            .published() \
            .open() \
            .select_related('perimeter', 'author') \
            .prefetch_related('financers') \
            .filter(date_published__gte=self.latest_alert_date) \
            .order_by('date_published')
        qs = search_form.filter_queryset(base_qs)
        return qs
Example #9
0
def send_alert_confirmation_email(user_email, alert_token):
    """Send an alert confirmation link to the user.

    The email contains a token that can be used to validate the
    email ownership.
    """
    try:
        alert = Alert.objects.get(token=alert_token)
    except (Alert.DoesNotExist):
        # In case we could not find any valid user with the given email
        # we don't raise any exception, because we can't give any hints
        # about whether or not any particular email has an account
        # on our site.
        return

    # Use the search form to parse the search querydict and
    # extract the perimeter
    querydict = QueryDict(alert.querystring)
    search_form = AidSearchForm(querydict)
    perimeter = ''
    if search_form.is_valid():
        perimeter = search_form.cleaned_data.get('perimeter') or ''
        perimeter = str(perimeter)

    base_url = get_base_url()
    alert_validation_link = reverse('alert_validate_view', args=[alert_token])
    alert_date = '{:%d/%m/%Y %H:%M:%S}'.format(alert.date_created)

    if alert.alert_frequency == Alert.FREQUENCIES.daily:
        frequency = 'quotidien'
    else:
        frequency = 'hebdomadaire'

    data = {
        'URL_SITE': base_url,
        'FREQUENCE': frequency,
        'PERIMETRE': perimeter,
        'DATE_ALERTE': alert_date,
        'LIEN_VALIDATION': '{}{}'.format(base_url, alert_validation_link)
    }

    send_email_with_template(
        recipient_list=[user_email],
        template_id=settings.SIB_ALERT_CONFIRMATION_EMAIL_TEMPLATE_ID,
        data=data,
        tags=['alerte_confirmation', settings.ENV_NAME],
        fail_silently=False)
Example #10
0
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        # We have a problem here.
        # We want to return the list of existing themes, but we also want to
        # count the number of aids **matching the current search** for each
        # theme.
        #
        # Since the search query is already quite complex to generate, we
        # use it as a base and then we do a join on categories and themes,
        # then we group by theme and count.
        filter_form = AidSearchForm(self.initial)
        themes_with_aid_count = filter_form.filter_queryset() \
            .exclude(categories__isnull=True) \
            .values('categories__theme__slug', 'categories__theme__name') \
            .annotate(nb_aids=Count('id', distinct=True)) \
            .order_by('categories__theme__name')
        self.fields['themes'].queryset = themes_with_aid_count
Example #11
0
    def get_base_queryset(self, all_aids=False):
        """Return the list of aids based on the initial search querysting."""

        from aids.forms import AidSearchForm

        # Sometime, the admin person enters a prefix "?" character
        # and we don't want it here.
        querystring = self.search_querystring.strip('?')
        data = QueryDict(querystring)
        form = AidSearchForm(data)
        if all_aids:
            qs = form.filter_queryset(Aid.objects.all()).distinct()
        else:
            qs = form.filter_queryset().distinct()

        # Also exlude aids contained in the excluded_aids field
        qs = qs.exclude(id__in=self.excluded_aids.values_list('id', flat=True))

        return qs
Example #12
0
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        # See `ThemeSearchForm` for explanation about the following lines.
        filter_form = AidSearchForm(self.initial)
        filtered_qs = filter_form.filter_queryset() \
            .exclude(categories__isnull=True)

        # We list categories for selected themes
        # Special case: if no theme was selected, we return all of them
        themes = self.initial.get('themes', [])
        if themes:
            filtered_qs = filtered_qs \
                .filter(categories__theme__slug__in=themes)

        categories_with_aid_count = filtered_qs \
            .values(
                'categories__theme__name',
                'categories__name',
                'categories__slug') \
            .annotate(nb_aids=Count('id', distinct=True)) \
            .order_by('categories__theme__name', 'categories__name')
        self.fields['categories'].queryset = categories_with_aid_count
Example #13
0
def test_search_form_filter_by_types(aids):
    form = AidSearchForm({'aid_types': ['grant']})
    qs = form.filter_queryset(aids)
    assert qs.count() == 8
    for aid in qs:
        assert 'grant' in aid.aid_types

    form = AidSearchForm({'aid_types': ['grant', 'networking']})
    qs = form.filter_queryset(aids)
    for aid in qs:
        print(aid.aid_types)
    assert qs.count() == 9
    for aid in qs:
        assert 'grant' in aid.aid_types or 'networking' in aid.aid_types
Example #14
0
def test_search_form_filter_by_types(aids):
    form = AidSearchForm({'financial_aids': ['grant']})
    qs = form.filter_queryset(aids)
    assert qs.count() == 8
    for aid in qs:
        assert 'grant' in aid.aid_types

    form = AidSearchForm({
        'financial_aids': ['grant'],
        'technical_aids': ['technical']
    })
    qs = form.filter_queryset(aids)
    assert qs.count() == 9
    for aid in qs:
        assert 'grant' in aid.aid_types or 'technical' in aid.aid_types
Example #15
0
def test_search_from_filter_by_audiences(aids):
    form = AidSearchForm({'targeted_audiences': ['commune']})
    qs = form.filter_queryset(aids)
    assert qs.count() == 1
    for aid in qs:
        assert 'commune' in aid.targeted_audiences

    form = AidSearchForm({'targeted_audiences': ['commune', 'department']})
    qs = form.filter_queryset(aids)
    assert qs.count() == 2
    for aid in qs:
        assert any(('commune' in aid.targeted_audiences, 'department'
                    in aid.targeted_audiences))

    form = AidSearchForm(
        {'targeted_audiences': ['commune', 'department', 'region']})
    qs = form.filter_queryset(aids)
    assert qs.count() == 3
    for aid in qs:
        assert any(
            ('commune' in aid.targeted_audiences, 'department'
             in aid.targeted_audiences, 'region' in aid.targeted_audiences))

    form = AidSearchForm(
        {'targeted_audiences': ['commune', 'department', 'region', 'epci']})
    qs = form.filter_queryset(aids)
    assert qs.count() == 4
    for aid in qs:
        assert any(
            ('commune' in aid.targeted_audiences, 'department'
             in aid.targeted_audiences, 'region'
             in aid.targeted_audiences, 'epci' in aid.targeted_audiences))

    form = AidSearchForm({
        'targeted_audiences':
        ['commune', 'department', 'region', 'epci', 'public_cies']
    })
    qs = form.filter_queryset(aids)
    assert qs.count() == 5
    for aid in qs:
        assert any(('commune' in aid.targeted_audiences, 'department'
                    in aid.targeted_audiences, 'region'
                    in aid.targeted_audiences, 'epci'
                    in aid.targeted_audiences, 'public_cies'
                    in aid.targeted_audiences))

    form = AidSearchForm({
        'targeted_audiences': [
            'commune', 'department', 'region', 'epci', 'public_cies',
            'association'
        ]
    })
    qs = form.filter_queryset(aids)
    assert qs.count() == 6
    for aid in qs:
        assert any(
            ('commune' in aid.targeted_audiences, 'department'
             in aid.targeted_audiences, 'region' in aid.targeted_audiences,
             'epci' in aid.targeted_audiences, 'public_cies'
             in aid.targeted_audiences, 'association'
             in aid.targeted_audiences))

    form = AidSearchForm({
        'targeted_audiences': [
            'commune', 'department', 'region', 'epci', 'public_cies',
            'association', 'private_person'
        ]
    })
    qs = form.filter_queryset(aids)
    assert qs.count() == 7
    for aid in qs:
        assert any(
            ('commune' in aid.targeted_audiences, 'department'
             in aid.targeted_audiences, 'region' in aid.targeted_audiences,
             'epci' in aid.targeted_audiences, 'public_cies'
             in aid.targeted_audiences, 'association'
             in aid.targeted_audiences, 'private_person'
             in aid.targeted_audiences))

    form = AidSearchForm({
        'targeted_audiences': [
            'commune', 'department', 'region', 'epci', 'public_cies',
            'association', 'private_person', 'researcher'
        ]
    })
    qs = form.filter_queryset(aids)
    assert qs.count() == 8
    for aid in qs:
        assert any((
            'commune' in aid.targeted_audiences,
            'department' in aid.targeted_audiences,
            'region' in aid.targeted_audiences,
            'epci' in aid.targeted_audiences,
            'public_cies' in aid.targeted_audiences,
            'association' in aid.targeted_audiences,
            'private_person' in aid.targeted_audiences,
            'researcher' in aid.targeted_audiences,
        ))

    form = AidSearchForm({
        'targeted_audiences': [
            'commune', 'department', 'region', 'epci', 'public_cies',
            'association', 'private_person', 'researcher', 'private_sector'
        ]
    })
    qs = form.filter_queryset(aids)
    assert qs.count() == 9
    for aid in qs:
        assert any(
            ('commune' in aid.targeted_audiences, 'department'
             in aid.targeted_audiences, 'region' in aid.targeted_audiences,
             'epci' in aid.targeted_audiences, 'public_cies'
             in aid.targeted_audiences, 'association'
             in aid.targeted_audiences, 'private_person'
             in aid.targeted_audiences, 'researcher' in aid.targeted_audiences,
             'private_sector' in aid.targeted_audiences))
Example #16
0
def test_search_form_filter_by_deadline(aids):
    form = AidSearchForm({'apply_before': '2018-12-01'})
    qs = form.filter_queryset(aids)
    assert qs.count() == 12

    form = AidSearchForm({'apply_before': '2018-08-01'})
    qs = form.filter_queryset(aids)
    assert qs.count() == 8

    form = AidSearchForm({'apply_before': '2018-04-01'})
    qs = form.filter_queryset(aids)
    assert qs.count() == 4

    form = AidSearchForm({'apply_before': '2018-01-01'})
    qs = form.filter_queryset(aids)
    assert qs.count() == 4

    form = AidSearchForm({'apply_before': '2017-12-31'})
    qs = form.filter_queryset(aids)
    assert qs.count() == 0
Example #17
0
def test_search_form_filter_mobilization_step(aids):
    form = AidSearchForm({'mobilization_step': ['preop']})
    qs = form.filter_queryset(aids)
    assert qs.count() == 9
    for aid in qs:
        assert 'preop' in aid.mobilization_steps

    form = AidSearchForm({'mobilization_step': ['op']})
    qs = form.filter_queryset(aids)
    assert qs.count() == 6
    for aid in qs:
        assert 'op' in aid.mobilization_steps

    form = AidSearchForm({'mobilization_step': ['postop']})
    qs = form.filter_queryset(aids)
    assert qs.count() == 4
    for aid in qs:
        assert 'postop' in aid.mobilization_steps

    form = AidSearchForm({'mobilization_step': ['preop', 'postop']})
    qs = form.filter_queryset(aids)
    assert qs.count() == 12
    for aid in qs:
        assert any(('preop' in aid.mobilization_steps, 'postop'
                    in aid.mobilization_steps))