def test_photo_review_upload_undecided_privileged(
            self,
            mock_send_mail
    ):
        settings = get_current_usersettings()
        settings.DEFAULT_FROM_EMAIL = '*****@*****.**'
        settings.save()
        review_url = reverse(
            'photo-review',
            kwargs={'queued_image_id': self.q1.id}
        )
        review_page_response = self.app.get(
            review_url,
            user=self.test_reviewer
        )
        form = review_page_response.forms['photo-review-form']
        form['decision'] = 'undecided'
        form['rejection_reason'] = 'No clear source or copyright statement'
        response = form.submit(user=self.test_reviewer)
        self.assertEqual(response.status_code, 302)
        split_location = urlsplit(response.location)
        self.assertEqual('/moderation/photo/review', split_location.path)

        self.assertEqual(mock_send_mail.call_count, 0)

        self.assertEqual(QueuedImage.objects.get(pk=self.q1.id).decision, 'undecided')
Exemple #2
0
def parse_approximate_date(s):
    """Take any reasonable date string, and return an ApproximateDate for it

    >>> ad = parse_approximate_date('2014-02-17')
    >>> type(ad)
    <class 'django_date_extensions.fields.ApproximateDate'>
    >>> ad
    2014-02-17
    >>> parse_approximate_date('2014-02')
    2014-02-00
    >>> parse_approximate_date('2014')
    2014-00-00
    >>> parse_approximate_date('future')
    future
    """

    user_settings = get_current_usersettings()

    for regexp in [
            r'^(\d{4})-(\d{2})-(\d{2})$', r'^(\d{4})-(\d{2})$', r'^(\d{4})$'
    ]:
        m = re.search(regexp, s)
        if m:
            return ApproximateDate(*(int(g, 10) for g in m.groups()))
    if s == 'future':
        return ApproximateDate(future=True)
    if s:
        dt = parser.parse(s,
                          parserinfo=localparserinfo(),
                          dayfirst=user_settings.DD_MM_DATE_FORMAT_PREFERRED)
        return ApproximateDate(dt.year, dt.month, dt.day)
    raise ValueError("Couldn't parse '{0}' as an ApproximateDate".format(s))
    def test_photo_review_upload_ignore_privileged(
            self,
            mock_send_mail
    ):
        settings = get_current_usersettings()
        settings.DEFAULT_FROM_EMAIL = '*****@*****.**'
        settings.save()
        review_url = reverse(
            'photo-review',
            kwargs={'queued_image_id': self.q1.id}
        )
        review_page_response = self.app.get(
            review_url,
            user=self.test_reviewer
        )
        form = review_page_response.forms['photo-review-form']
        form['decision'] = 'ignore'
        response = form.submit(user=self.test_reviewer)
        self.assertEqual(response.status_code, 302)
        split_location = urlsplit(response.location)
        self.assertEqual('/moderation/photo/review', split_location.path)

        self.assertEqual(mock_send_mail.call_count, 0)

        self.assertEqual(QueuedImage.objects.get(pk=self.q1.id).decision, 'ignore')

        las = LoggedAction.objects.all()
        self.assertEqual(1, len(las))
        la = las[0]
        self.assertEqual(la.user.username, 'jane')
        self.assertEqual(la.action_type, 'photo-ignore')
        self.assertEqual(la.person.id, 2009)
Exemple #4
0
 def test_mm_dd_yyyy_with_slashes(self):
     settings = get_current_usersettings()
     settings.DD_MM_DATE_FORMAT_PREFERRED=False
     settings.save()
     parsed = parse_approximate_date('4/1/1977')
     self.assertEqual(type(parsed), ApproximateDate)
     self.assertEqual(repr(parsed), '1977-04-01')
 def process_exception(self, request, exc):
     if isinstance(exc, NameChangeDisallowedException):
         usersettings = get_current_usersettings()
         intro = _('As a precaution, an update was blocked:')
         outro = _('If this update is appropriate, someone should apply it manually.')
         # Then email the support address about the name change...
         message = '{intro}\n\n  {message}\n\n{outro}'.format(
             intro=intro,
             message=exc,
             outro=outro,
         )
         send_mail(
             _('Disallowed {site_name} update for checking').format(
                 site_name=Site.objects.get_current().name
             ),
             message,
             usersettings.DEFAULT_FROM_EMAIL,
             [usersettings.SUPPORT_EMAIL],
             fail_silently=False
         )
         # And redirect to a page explaining to the user what has happened
         disallowed_explanation_url = reverse('update-disallowed')
         return HttpResponseRedirect(disallowed_explanation_url)
     elif isinstance(exc, ChangeToLockedConstituencyDisallowedException):
         msg = 'Attempted a change candidates in a locked constituency'
         return HttpResponseForbidden(msg)
 def process_exception(self, request, exc):
     if isinstance(exc, NameChangeDisallowedException):
         usersettings = get_current_usersettings()
         intro = _('As a precaution, an update was blocked:')
         outro = _(
             'If this update is appropriate, someone should apply it manually.'
         )
         # Then email the support address about the name change...
         message = '{intro}\n\n  {message}\n\n{outro}'.format(
             intro=intro,
             message=exc,
             outro=outro,
         )
         send_mail(_('Disallowed {site_name} update for checking').format(
             site_name=Site.objects.get_current().name),
                   message,
                   usersettings.DEFAULT_FROM_EMAIL,
                   [usersettings.SUPPORT_EMAIL],
                   fail_silently=False)
         # And redirect to a page explaining to the user what has happened
         disallowed_explanation_url = reverse('update-disallowed')
         return HttpResponseRedirect(disallowed_explanation_url)
     elif isinstance(exc, ChangeToLockedConstituencyDisallowedException):
         msg = 'Attempted a change candidates in a locked constituency'
         return HttpResponseForbidden(msg)
Exemple #7
0
    def test_photo_review_upload_ignore_privileged(self, mock_send_mail):
        settings = get_current_usersettings()
        settings.DEFAULT_FROM_EMAIL = '*****@*****.**'
        settings.save()
        review_url = reverse('photo-review',
                             kwargs={'queued_image_id': self.q1.id})
        review_page_response = self.app.get(review_url,
                                            user=self.test_reviewer)
        form = review_page_response.forms['photo-review-form']
        form['decision'] = 'ignore'
        response = form.submit(user=self.test_reviewer)
        self.assertEqual(response.status_code, 302)
        split_location = urlsplit(response.location)
        self.assertEqual('/moderation/photo/review', split_location.path)

        self.assertEqual(mock_send_mail.call_count, 0)

        self.assertEqual(
            QueuedImage.objects.get(pk=self.q1.id).decision, 'ignore')

        las = LoggedAction.objects.all()
        self.assertEqual(1, len(las))
        la = las[0]
        self.assertEqual(la.user.username, 'jane')
        self.assertEqual(la.action_type, 'photo-ignore')
        self.assertEqual(la.person.id, 2009)
Exemple #8
0
 def test_signup_disabled(self):
     user_settings = get_current_usersettings()
     user_settings.NEW_ACCOUNTS_ALLOWED = False
     user_settings.save()
     settings_url = reverse('account_signup', )
     response = self.app.get(settings_url, expect_errors=True)
     self.assertEqual(response.status_code, 200)
     self.assertContains(response, 'Sign Up Closed')
     self.assertNotContains(response, 'Password (again)')
    def test_photo_review_upload_approved_privileged(
            self,
            mock_send_mail
    ):
        settings = get_current_usersettings()
        settings.DEFAULT_FROM_EMAIL = '*****@*****.**'
        settings.site_id = self.site.id
        settings.save()
        with self.settings(SITE_ID=self.site.id):
            review_url = reverse(
                'photo-review',
                kwargs={'queued_image_id': self.q1.id}
            )
            review_page_response = self.app.get(
                review_url,
                user=self.test_reviewer
            )
            form = review_page_response.forms['photo-review-form']
            form['decision'] = 'approved'
            form['moderator_why_allowed'] = 'profile-photo'
            response = form.submit(user=self.test_reviewer)
            # FIXME: check that mocked_person_put got the right calls
            self.assertEqual(response.status_code, 302)
            split_location = urlsplit(response.location)
            self.assertEqual('/moderation/photo/review', split_location.path)

            mock_send_mail.assert_called_once_with(
                'YNR image upload approved',
                "Thank-you for submitting a photo to YNR; that's been uploaded\nnow for the candidate page here:\n\n  http://localhost:80/person/2009/tessa-jowell\n\nMany thanks from the YNR volunteers\n",
                '*****@*****.**',
                ['*****@*****.**'],
                fail_silently=False
            )

            person = Person.objects.get(id=2009)
            image = person.extra.images.last()

            self.assertTrue(image.is_primary)
            self.assertEqual(
                'Uploaded by john: Approved from photo moderation queue',
                image.source
            )
            self.assertEqual(427, image.image.width)
            self.assertEqual(639, image.image.height)

            self.q1.refresh_from_db()
            self.assertEqual('public-domain', self.q1.why_allowed)
            self.assertEqual('approved', self.q1.decision)
            las = LoggedAction.objects.all()
            self.assertEqual(1, len(las))
            la = las[0]
            self.assertEqual(la.user.username, 'jane')
            self.assertEqual(la.action_type, 'photo-approve')
            self.assertEqual(la.person.id, 2009)

            self.assertEqual(QueuedImage.objects.get(pk=self.q1.id).decision, 'approved')
Exemple #10
0
def get_site_setting(param):
    try:
        sitesettings = get_current_usersettings()
        return getattr(sitesettings, param)
    except AttributeError:
        field, _, _, _ = SiteSettings._meta.get_field_by_name(param)
        if field.default == fields.NOT_PROVIDED:
            return None
        else:
            return field.default
Exemple #11
0
def add_settings(request):
    """Add some selected settings values to the context"""

    all_settings = {k: getattr(settings, k) for k in SETTINGS_TO_ADD}

    current = get_current_usersettings()
    usersettings = {k: getattr(current, k) for k in USERSETTINGS_TO_ADD}

    all_settings.update(usersettings)

    return {'settings': all_settings}
    def test_edit_restricted_unprivileged(self):
        settings = get_current_usersettings()
        settings.EDITS_ALLOWED = False
        settings.save()
        response = self.app.get(
            '/person/4322/update',
            user=self.user
        )

        self.assertContains(
            response,
            'Editing of data in  is now disabled'
        )
Exemple #13
0
def split_by_elected(election_data, memberships):
    elected_candidates = set()
    unelected_candidates = set()
    for membership in memberships:
        if membership.extra.elected:
            elected_candidates.add(membership)
            user_settings = get_current_usersettings()
            if not user_settings.HOIST_ELECTED_CANDIDATES:
                unelected_candidates.add(membership)
        else:
            unelected_candidates.add(membership)

    return elected_candidates, unelected_candidates
def split_by_elected(election_data, memberships):
    elected_candidates = set()
    unelected_candidates = set()
    for membership in memberships:
        if membership.extra.elected:
            elected_candidates.add(membership)
            user_settings = get_current_usersettings()
            if not user_settings.HOIST_ELECTED_CANDIDATES:
                unelected_candidates.add(membership)
        else:
            unelected_candidates.add(membership)

    return elected_candidates, unelected_candidates
Exemple #15
0
    def test_settings_saved(self):
        settings_url = reverse(
            'settings',
        )
        response = self.app.get(settings_url, user=self.user_who_can_edit_settings)
        form = response.forms['settings']

        form['SITE_OWNER'].value = 'The New Owners'
        response = form.submit()

        self.assertEqual(form['SITE_OWNER'].value, 'The New Owners')

        settings = get_current_usersettings()
        self.assertEqual(settings.SITE_OWNER, 'The New Owners')
Exemple #16
0
 def test_renames_restricted_unprivileged(self):
     settings = get_current_usersettings()
     settings.RESTRICT_RENAMES = True
     settings.save()
     response = self.app.get('/person/4322/update', user=self.user)
     form = response.forms['person-details']
     form['name'] = 'Ms Helen Hayes'
     form['source'] = 'Testing renaming'
     submission_response = form.submit(expect_errors=True)
     self.assertEqual(submission_response.status_code, 302)
     self.assertEqual(
         submission_response.location,
         'http://localhost:80/update-disallowed',
     )
    def is_open_for_signup(self, request):
        """
        Checks whether or not the site is open for signups.

        Next to simply returning True/False you can also intervene the
        regular flow by raising an ImmediateHttpResponse

        (Comment reproduced from the overridden method.)
        """

        userconf = get_current_usersettings()
        if userconf.NEW_ACCOUNTS_ALLOWED:
            return True

        return False
    def test_constituency_with_winner(self):
        response = self.app.get('/election/2015/post/14419/edinburgh-east')
        response.mustcontain('<div class="candidates__elected">')
        response.mustcontain('<div class="candidates__known">')

        response.mustcontain(no='Unset the current winners')

        response.mustcontain('Unelected candidates for')
        response.mustcontain(no='Known candidates for')

        settings = get_current_usersettings()
        settings.HOIST_ELECTED_CANDIDATES = False
        settings.save()
        response = self.app.get('/election/2015/post/14419/edinburgh-east')
        response.mustcontain(no='Unelected candidates for')
        response.mustcontain('Known candidates for')
Exemple #19
0
    def test_constituency_with_winner(self):
        response = self.app.get('/election/2015/post/14419/edinburgh-east')
        response.mustcontain('<div class="candidates__elected">')
        response.mustcontain('<div class="candidates__known">')

        response.mustcontain(no='Unset the current winners')

        response.mustcontain('Unelected candidates for')
        response.mustcontain(no='Known candidates for')

        settings = get_current_usersettings()
        settings.HOIST_ELECTED_CANDIDATES = False
        settings.save()
        response = self.app.get('/election/2015/post/14419/edinburgh-east')
        response.mustcontain(no='Unelected candidates for')
        response.mustcontain('Known candidates for')
Exemple #20
0
    def test_photo_review_upload_approved_privileged(self, mock_send_mail):
        settings = get_current_usersettings()
        settings.DEFAULT_FROM_EMAIL = '*****@*****.**'
        settings.site_id = self.site.id
        settings.save()
        with self.settings(SITE_ID=self.site.id):
            review_url = reverse('photo-review',
                                 kwargs={'queued_image_id': self.q1.id})
            review_page_response = self.app.get(review_url,
                                                user=self.test_reviewer)
            form = review_page_response.forms['photo-review-form']
            form['decision'] = 'approved'
            form['moderator_why_allowed'] = 'profile-photo'
            response = form.submit(user=self.test_reviewer)
            # FIXME: check that mocked_person_put got the right calls
            self.assertEqual(response.status_code, 302)
            split_location = urlsplit(response.location)
            self.assertEqual('/moderation/photo/review', split_location.path)

            mock_send_mail.assert_called_once_with(
                'YNR image upload approved',
                "Thank-you for submitting a photo to YNR; that's been uploaded\nnow for the candidate page here:\n\n  http://localhost:80/person/2009/tessa-jowell\n\nMany thanks from the YNR volunteers\n",
                '*****@*****.**', ['*****@*****.**'],
                fail_silently=False)

            person = Person.objects.get(id=2009)
            image = person.extra.images.last()

            self.assertTrue(image.is_primary)
            self.assertEqual(
                'Uploaded by john: Approved from photo moderation queue',
                image.source)
            self.assertEqual(427, image.image.width)
            self.assertEqual(639, image.image.height)

            self.q1.refresh_from_db()
            self.assertEqual('public-domain', self.q1.why_allowed)
            self.assertEqual('approved', self.q1.decision)
            las = LoggedAction.objects.all()
            self.assertEqual(1, len(las))
            la = las[0]
            self.assertEqual(la.user.username, 'jane')
            self.assertEqual(la.action_type, 'photo-approve')
            self.assertEqual(la.person.id, 2009)

            self.assertEqual(
                QueuedImage.objects.get(pk=self.q1.id).decision, 'approved')
 def test_edit_restricted_privileged(self):
     settings = get_current_usersettings()
     settings.EDITS_ALLOWED = False
     settings.save()
     response = self.app.get(
         '/person/4322/update',
         user=self.user_is_staff,
     )
     form = response.forms['person-details']
     form['email'] = '*****@*****.**'
     form['source'] = 'Testing renaming'
     submission_response = form.submit(expect_errors=True)
     self.assertEqual(submission_response.status_code, 302)
     self.assertEqual(
         submission_response.location,
         'http://localhost:80/person/4322',
     )
    def test_photo_review_upload_rejected_privileged(
            self,
            mock_send_mail
    ):
        settings = get_current_usersettings()
        settings.DEFAULT_FROM_EMAIL = '*****@*****.**'
        settings.SUPPORT_EMAIL = '*****@*****.**'
        settings.site_id = self.site.id
        settings.save()
        with self.settings(SITE_ID=self.site.id):
            review_url = reverse(
                'photo-review',
                kwargs={'queued_image_id': self.q1.id}
            )
            review_page_response = self.app.get(
                review_url,
                user=self.test_reviewer
            )
            form = review_page_response.forms['photo-review-form']
            form['decision'] = 'rejected'
            form['rejection_reason'] = 'There\'s no clear source or copyright statement'
            response = form.submit(user=self.test_reviewer)
            self.assertEqual(response.status_code, 302)
            split_location = urlsplit(response.location)
            self.assertEqual('/moderation/photo/review', split_location.path)

            las = LoggedAction.objects.all()
            self.assertEqual(1, len(las))
            la = las[0]
            self.assertEqual(la.user.username, 'jane')
            self.assertEqual(la.action_type, 'photo-reject')
            self.assertEqual(la.person.id, 2009)
            self.assertEqual(la.source, 'Rejected a photo upload from john')
            self.assertEqual(la.note, 'There\'s no clear source or copyright statement')

            mock_send_mail.assert_called_once_with(
                'YNR image moderation results',
                "Thank-you for uploading a photo of Tessa Jowell to YNR, but\nunfortunately we can't use that image because:\n\n  There\'s no clear source or copyright statement\n\nYou can just reply to this email if you want to discuss that\nfurther, or you can try uploading a photo with a different\nreason or justification for its use using this link:\n\n  http://localhost:80/moderation/photo/upload/2009\n\nMany thanks from the YNR volunteers\n\n-- \nFor administrators' use: http://localhost:80/moderation/photo/review/{0}\n".format(self.q1.id),
                '*****@*****.**',
                ['*****@*****.**', '*****@*****.**'],
                fail_silently=False
            )

            self.assertEqual(QueuedImage.objects.get(pk=self.q1.id).decision, 'rejected')
Exemple #23
0
 def party_choices(self):
     # For various reasons, we've found it's best to order the
     # parties by those that have the most candidates - this means
     # that the commonest parties to select are at the top of the
     # drop down.  The logic here tries to build such an ordered
     # list of candidates if there are enough that such an ordering
     # makes sense.  Otherwise the fallback is to rank
     # alphabetically.
     candidacies_current_qs = Membership.objects.filter(
         extra__election__current=True,
         role=models.F('extra__election__candidate_membership_role'),
         on_behalf_of__party_sets=self,
     )
     candidacies_ever_qs = Membership.objects.filter(
         role=models.F('extra__election__candidate_membership_role'),
         on_behalf_of__party_sets=self,
     )
     user_settings = get_current_usersettings()
     minimum_count = user_settings.CANDIDATES_REQUIRED_FOR_WEIGHTED_PARTY_LIST
     qs = None
     if candidacies_current_qs.count() > minimum_count:
         qs = candidacies_current_qs
     elif candidacies_ever_qs.count() > minimum_count:
         qs = candidacies_ever_qs
     else:
         return self.party_choices_basic()
     result = [('party:none', '')]
     parties_with_candidates = []
     for party_tuple in qs \
             .values('on_behalf_of', 'on_behalf_of__name') \
             .order_by() \
             .annotate(party_count=models.Count('pk')) \
             .order_by('-party_count', 'on_behalf_of__name'):
         parties_with_candidates.append(party_tuple['on_behalf_of'])
         name_with_count = \
             _('{party_name} ({number_of_candidates} candidates)').format(
                 party_name=party_tuple['on_behalf_of__name'],
                 number_of_candidates=party_tuple['party_count']
             )
         result.append((party_tuple['on_behalf_of'], name_with_count))
     result += self.parties.exclude(id__in=parties_with_candidates) \
         .order_by('name').values_list('id', 'name')
     return result
Exemple #24
0
    def test_photo_review_upload_undecided_privileged(self, mock_send_mail):
        settings = get_current_usersettings()
        settings.DEFAULT_FROM_EMAIL = '*****@*****.**'
        settings.save()
        review_url = reverse('photo-review',
                             kwargs={'queued_image_id': self.q1.id})
        review_page_response = self.app.get(review_url,
                                            user=self.test_reviewer)
        form = review_page_response.forms['photo-review-form']
        form['decision'] = 'undecided'
        form['rejection_reason'] = 'No clear source or copyright statement'
        response = form.submit(user=self.test_reviewer)
        self.assertEqual(response.status_code, 302)
        split_location = urlsplit(response.location)
        self.assertEqual('/moderation/photo/review', split_location.path)

        self.assertEqual(mock_send_mail.call_count, 0)

        self.assertEqual(
            QueuedImage.objects.get(pk=self.q1.id).decision, 'undecided')
def check_update_allowed(user, old_name, old_candidacies, new_name, new_candidacies):
    # Check whether an unauthorized user has tried to rename someone
    # while RESTRICT_RENAMES is set:
    usersettings = get_current_usersettings()
    if usersettings.RESTRICT_RENAMES:
        allowed_by_group = user_in_group(user, TRUSTED_TO_RENAME_GROUP_NAME)
        name_the_same = old_name == new_name
        if not (allowed_by_group or name_the_same):
            message = _("Name change from '{0}' to '{1}' by user {2} disallowed")
            raise NameChangeDisallowedException(message.format(
                old_name, new_name, user.username
            ))
    # Check that none of the posts that the person's leaving or
    # joining were locked:
    old_posts = set(c.post for c in old_candidacies)
    new_posts = set(c.post for c in new_candidacies)
    for post in old_posts ^ new_posts:
        dummy, edits_allowed = get_constituency_lock(user, post)
        if not edits_allowed:
            raise ChangeToLockedConstituencyDisallowedException(
                _("That update isn't allowed because candidates for a locked "
                  "post ({post_label}) would be changed").format(
                      post_label=post.label
                  )
            )
    # Now check that they're not changing party in a locked
    # constituency:
    for post in old_posts & new_posts:
        old_party = next(c.on_behalf_of for c in old_candidacies if c.post == post)
        new_party = next(c.on_behalf_of for c in new_candidacies if c.post == post)
        dummy, edits_allowed = get_constituency_lock(user, post)
        if not edits_allowed and (old_party != new_party):
            raise ChangeToLockedConstituencyDisallowedException(
                _("That update isn't allowed because you can't change the party "
                  "(in this case from {old_party} to {new_party}) for a candidate "
                  "in a locked post ({post_label})").format(
                      old_party=old_party.name, new_party=new_party.name,
                      post_label=post.label
                  )
            )
Exemple #26
0
    def test_photo_review_upload_rejected_privileged(self, mock_send_mail):
        settings = get_current_usersettings()
        settings.DEFAULT_FROM_EMAIL = '*****@*****.**'
        settings.SUPPORT_EMAIL = '*****@*****.**'
        settings.site_id = self.site.id
        settings.save()
        with self.settings(SITE_ID=self.site.id):
            review_url = reverse('photo-review',
                                 kwargs={'queued_image_id': self.q1.id})
            review_page_response = self.app.get(review_url,
                                                user=self.test_reviewer)
            form = review_page_response.forms['photo-review-form']
            form['decision'] = 'rejected'
            form[
                'rejection_reason'] = 'There\'s no clear source or copyright statement'
            response = form.submit(user=self.test_reviewer)
            self.assertEqual(response.status_code, 302)
            split_location = urlsplit(response.location)
            self.assertEqual('/moderation/photo/review', split_location.path)

            las = LoggedAction.objects.all()
            self.assertEqual(1, len(las))
            la = las[0]
            self.assertEqual(la.user.username, 'jane')
            self.assertEqual(la.action_type, 'photo-reject')
            self.assertEqual(la.person.id, 2009)
            self.assertEqual(la.source, 'Rejected a photo upload from john')
            self.assertEqual(
                la.note, 'There\'s no clear source or copyright statement')

            mock_send_mail.assert_called_once_with(
                'YNR image moderation results',
                "Thank-you for uploading a photo of Tessa Jowell to YNR, but\nunfortunately we can't use that image because:\n\n  There\'s no clear source or copyright statement\n\nYou can just reply to this email if you want to discuss that\nfurther, or you can try uploading a photo with a different\nreason or justification for its use using this link:\n\n  http://localhost:80/moderation/photo/upload/2009\n\nMany thanks from the YNR volunteers\n\n-- \nFor administrators' use: http://localhost:80/moderation/photo/review/{0}\n"
                .format(self.q1.id),
                '*****@*****.**',
                ['*****@*****.**', '*****@*****.**'],
                fail_silently=False)

            self.assertEqual(
                QueuedImage.objects.get(pk=self.q1.id).decision, 'rejected')
Exemple #27
0
    def test_logged_action_created(self):
        settings_url = reverse(
            'settings',
        )
        response = self.app.get(settings_url, user=self.user_who_can_edit_settings)
        form = response.forms['settings']

        form['SITE_OWNER'].value = 'The New Owners'
        response = form.submit()

        settings = get_current_usersettings()
        self.assertEqual(settings.SITE_OWNER, 'The New Owners')

        actions = LoggedAction.objects.filter(
            action_type='settings-edited'
        ).order_by('-created')

        action = actions[0]

        self.assertEqual(
            action.note,
            "Changed SITE_OWNER from \"The Site Owners\" to \"The New Owners\"\n"
        )
Exemple #28
0
def get_twitter_user_id(twitter_screen_name):
    cache_key = 'twitter-screen-name:{0}'.format(twitter_screen_name)
    cached_result = cache.get(cache_key)
    if cached_result:
        return cached_result
    user_settings = get_current_usersettings()
    token = user_settings.TWITTER_APP_ONLY_BEARER_TOKEN
    if not token:
        raise TwitterAPITokenMissing()
    headers = {'Authorization': 'Bearer {token}'.format(token=token)}
    r = requests.post(
        'https://api.twitter.com/1.1/users/lookup.json',
        data={'screen_name': twitter_screen_name},
        headers=headers,
    )
    data = r.json()
    if data:
        if 'errors' in data:
            all_errors = data['errors']
            if any(d['code'] == 17 for d in all_errors):
                # (That's the error code for not being able to find the
                # user.)
                result = ''
            else:
                raise Exception("The Twitter API says: {error_messages}".format(
                    error_messages=data['errors']
                ))
        else:
            result = text_type(data[0]['id'])
    else:
        result = ''
    # Cache Twitter screen name -> user ID results for 5 minutes -
    # this is largely so we usually only make one API call for both
    # validating a screen name in a form and acting on submission of
    # that form.
    cache.set(cache_key, result, 60 * 5)
    return result
def parse_approximate_date(s):
    """Take any reasonable date string, and return an ApproximateDate for it

    >>> ad = parse_approximate_date('2014-02-17')
    >>> type(ad)
    <class 'django_date_extensions.fields.ApproximateDate'>
    >>> ad
    2014-02-17
    >>> parse_approximate_date('2014-02')
    2014-02-00
    >>> parse_approximate_date('2014')
    2014-00-00
    >>> parse_approximate_date('future')
    future
    """

    user_settings = get_current_usersettings()

    for regexp in [
        r'^(\d{4})-(\d{2})-(\d{2})$',
        r'^(\d{4})-(\d{2})$',
        r'^(\d{4})$'
    ]:
        m = re.search(regexp, s)
        if m:
            return ApproximateDate(*(int(g, 10) for g in m.groups()))
    if s == 'future':
        return ApproximateDate(future=True)
    if s:
        dt = parser.parse(
            s,
            parserinfo=localparserinfo(),
            dayfirst=user_settings.DD_MM_DATE_FORMAT_PREFERRED
        )
        return ApproximateDate(dt.year, dt.month, dt.day)
    raise ValueError("Couldn't parse '{0}' as an ApproximateDate".format(s))
 def test_get_current_usersettings(self):
     # Test that the correct UserSettings object is returned
     current_usersettings = get_current_usersettings()
     self.assertIsInstance(current_usersettings, self.usersettings_model)
Exemple #31
0
    def handle(self, *args, **options):
        global VERBOSE
        VERBOSE = int(options['verbosity']) > 1
        user_settings = get_current_usersettings()
        token = user_settings.TWITTER_APP_ONLY_BEARER_TOKEN
        if not token:
            raise CommandError(_("TWITTER_APP_ONLY_BEARER_TOKEN was not set"))
        headers = {'Authorization': 'Bearer {token}'.format(token=token)}

        # Find all unique Twitter screen names in the database:
        all_screen_names = list(
            ContactDetail.objects.filter(contact_type='twitter'). \
                values_list('value', flat=True).distinct()
        )

        # Find all unique Twitter identifiers in the database:
        all_user_ids = list(
            Identifier.objects.filter(scheme='twitter'). \
                values_list('identifier', flat=True).distinct()
        )

        self.screen_name_to_user_id = {}
        self.user_id_to_screen_name = {}
        for i in range(0, len(all_screen_names), MAX_IN_A_REQUEST):
            screen_names = all_screen_names[i:(i + MAX_IN_A_REQUEST)]
            r = requests.post(
                'https://api.twitter.com/1.1/users/lookup.json',
                data={'screen_name': ','.join(screen_names)},
                headers=headers,
            )
            response_data = r.json()
            if no_users_found(response_data):
                continue
            for d in response_data:
                self.screen_name_to_user_id[
                    d['screen_name'].lower()] = text_type(d['id'])
                self.user_id_to_screen_name[text_type(
                    d['id'])] = d['screen_name']

        # Now look for any user IDs in the database that weren't found
        # from the above query:
        remaining_user_ids = list(
            set(all_user_ids) - set(self.user_id_to_screen_name.keys()))
        for i in range(0, len(remaining_user_ids), MAX_IN_A_REQUEST):
            user_ids = remaining_user_ids[i:(i + MAX_IN_A_REQUEST)]
            r = requests.post(
                'https://api.twitter.com/1.1/users/lookup.json',
                data={'user_id': ','.join(user_ids)},
                headers=headers,
            )
            response_data = r.json()
            if no_users_found(response_data):
                continue
            for d in response_data:
                self.screen_name_to_user_id[
                    d['screen_name'].lower()] = text_type(d['id'])
                self.user_id_to_screen_name[d['id']] = text_type(d['id'])

        # Now go through every person in the database and check their
        # Twitter details:
        for person in Person.objects.select_related('extra'):
            with transaction.atomic():
                self.handle_person(person)
    def as_list_of_dicts(self, election, base_url=None):
        result = []
        user_settings = get_current_usersettings()
        if not base_url:
            base_url = ''
        # Find the list of relevant candidacies. So as not to cause
        # extra queries, we don't use filter but instead iterate over
        # all objects:
        candidacies = []
        for m in self.base.memberships.all():
            try:
                m_extra = m.extra
            except ObjectDoesNotExist:
                continue
            if not m_extra.election:
                continue
            expected_role = m.extra.election.candidate_membership_role
            if election is None:
                if expected_role == m.role:
                    candidacies.append(m)
            else:
                if m_extra.election == election and expected_role == m.role:
                    candidacies.append(m)
        for candidacy in candidacies:
            candidacy_extra = candidacy.extra
            party = candidacy.on_behalf_of
            post = candidacy.post
            elected = candidacy_extra.elected
            elected_for_csv = ''
            image_copyright = ''
            image_uploading_user = ''
            image_uploading_user_notes = ''
            proxy_image_url_template = ''
            if elected is not None:
                elected_for_csv = str(elected)
            mapit_identifier = None
            for identifier in post.area.other_identifiers.all():
                if identifier.scheme == 'mapit-area-url':
                    mapit_identifier = identifier
            if mapit_identifier:
                mapit_url = mapit_identifier.identifier
            else:
                mapit_url = ''
            primary_image = None
            for image in self.images.all():
                if image.is_primary:
                    primary_image = image
            primary_image_url = None
            if primary_image:
                primary_image_url = urljoin(base_url, primary_image.image.url)
                if user_settings.IMAGE_PROXY_URL and base_url:
                    encoded_url = quote_plus(primary_image_url)
                    proxy_image_url_template = user_settings.IMAGE_PROXY_URL + \
                        encoded_url + '/{height}/{width}.{extension}'

                try:
                    image_copyright = primary_image.extra.copyright
                    user = primary_image.extra.uploading_user
                    if user is not None:
                        image_uploading_user = primary_image.extra.uploading_user.username
                    image_uploading_user_notes = primary_image.extra.user_notes
                except ObjectDoesNotExist:
                    pass
            twitter_user_id = ''
            for identifier in self.base.identifiers.all():
                if identifier.scheme == 'twitter':
                    twitter_user_id = identifier.identifier

            row = {
                'id': self.base.id,
                'name': self.base.name,
                'honorific_prefix': self.base.honorific_prefix,
                'honorific_suffix': self.base.honorific_suffix,
                'gender': self.base.gender,
                'birth_date': self.base.birth_date,
                'election': candidacy_extra.election.slug,
                'election_date': candidacy_extra.election.election_date,
                'election_current': candidacy_extra.election.current,
                'party_id': party.extra.slug,
                'party_lists_in_use': candidacy_extra.election.party_lists_in_use,
                'party_list_position': candidacy_extra.party_list_position,
                'party_name': party.name,
                'post_id': post.extra.slug,
                'post_label': post.extra.short_label,
                'mapit_url': mapit_url,
                'elected': elected_for_csv,
                'email': self.base.email,
                'twitter_username': self.twitter_username,
                'twitter_user_id': twitter_user_id,
                'facebook_page_url': self.facebook_page_url,
                'linkedin_url': self.linkedin_url,
                'party_ppc_page_url': self.party_ppc_page_url,
                'facebook_personal_url': self.facebook_personal_url,
                'homepage_url': self.homepage_url,
                'wikipedia_url': self.wikipedia_url,
                'image_url': primary_image_url,
                'proxy_image_url_template': proxy_image_url_template,
                'image_copyright': image_copyright,
                'image_uploading_user': image_uploading_user,
                'image_uploading_user_notes': image_uploading_user_notes,
            }
            from ..election_specific import get_extra_csv_values
            extra_csv_data = get_extra_csv_values(self.base, election, post)
            row.update(extra_csv_data)
            result.append(row)

        return result
Exemple #33
0
    def as_list_of_dicts(self, election, base_url=None):
        result = []
        user_settings = get_current_usersettings()
        if not base_url:
            base_url = ''
        # Find the list of relevant candidacies. So as not to cause
        # extra queries, we don't use filter but instead iterate over
        # all objects:
        candidacies = []
        for m in self.base.memberships.all():
            try:
                m_extra = m.extra
            except ObjectDoesNotExist:
                continue
            if not m_extra.election:
                continue
            expected_role = m.extra.election.candidate_membership_role
            if election is None:
                if expected_role == m.role:
                    candidacies.append(m)
            else:
                if m_extra.election == election and expected_role == m.role:
                    candidacies.append(m)
        for candidacy in candidacies:
            candidacy_extra = candidacy.extra
            party = candidacy.on_behalf_of
            post = candidacy.post
            elected = candidacy_extra.elected
            elected_for_csv = ''
            image_copyright = ''
            image_uploading_user = ''
            image_uploading_user_notes = ''
            proxy_image_url_template = ''
            if elected is not None:
                elected_for_csv = str(elected)
            mapit_identifier = None
            for identifier in post.area.other_identifiers.all():
                if identifier.scheme == 'mapit-area-url':
                    mapit_identifier = identifier
            if mapit_identifier:
                mapit_url = mapit_identifier.identifier
            else:
                mapit_url = ''
            primary_image = None
            for image in self.images.all():
                if image.is_primary:
                    primary_image = image
            primary_image_url = None
            if primary_image:
                primary_image_url = urljoin(base_url, primary_image.image.url)
                if user_settings.IMAGE_PROXY_URL and base_url:
                    encoded_url = quote_plus(primary_image_url)
                    proxy_image_url_template = user_settings.IMAGE_PROXY_URL + \
                        encoded_url + '/{height}/{width}.{extension}'

                try:
                    image_copyright = primary_image.extra.copyright
                    user = primary_image.extra.uploading_user
                    if user is not None:
                        image_uploading_user = primary_image.extra.uploading_user.username
                    image_uploading_user_notes = primary_image.extra.user_notes
                except ObjectDoesNotExist:
                    pass
            twitter_user_id = ''
            for identifier in self.base.identifiers.all():
                if identifier.scheme == 'twitter':
                    twitter_user_id = identifier.identifier

            row = {
                'id': self.base.id,
                'name': self.base.name,
                'honorific_prefix': self.base.honorific_prefix,
                'honorific_suffix': self.base.honorific_suffix,
                'gender': self.base.gender,
                'birth_date': self.base.birth_date,
                'election': candidacy_extra.election.slug,
                'election_date': candidacy_extra.election.election_date,
                'election_current': candidacy_extra.election.current,
                'party_id': party.extra.slug,
                'party_lists_in_use':
                candidacy_extra.election.party_lists_in_use,
                'party_list_position': candidacy_extra.party_list_position,
                'party_name': party.name,
                'post_id': post.extra.slug,
                'post_label': post.extra.short_label,
                'mapit_url': mapit_url,
                'elected': elected_for_csv,
                'email': self.base.email,
                'twitter_username': self.twitter_username,
                'twitter_user_id': twitter_user_id,
                'facebook_page_url': self.facebook_page_url,
                'linkedin_url': self.linkedin_url,
                'party_ppc_page_url': self.party_ppc_page_url,
                'facebook_personal_url': self.facebook_personal_url,
                'homepage_url': self.homepage_url,
                'wikipedia_url': self.wikipedia_url,
                'image_url': primary_image_url,
                'proxy_image_url_template': proxy_image_url_template,
                'image_copyright': image_copyright,
                'image_uploading_user': image_uploading_user,
                'image_uploading_user_notes': image_uploading_user_notes,
            }
            from ..election_specific import get_extra_csv_values
            extra_csv_data = get_extra_csv_values(self.base, election, post)
            row.update(extra_csv_data)
            result.append(row)

        return result
def get_site_setting(key):
    user_settings = get_current_usersettings()
    return getattr(user_settings, key, get_sitesettings_default(key))
def get_site_setting(key):
    user_settings = get_current_usersettings()
    return getattr(
        user_settings,
        key,
        get_sitesettings_default(key))
 def test_get_current_usersettings(self):
     # Test that the correct UserSettings object is returned
     current_usersettings = get_current_usersettings()
     self.assertIsInstance(current_usersettings, self.usersettings_model)