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 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)
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)
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)
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')
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
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' )
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 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')
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')
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')
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
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 ) )
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')
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" )
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)
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
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))