Exemplo n.º 1
0
    def buildVotesForBill(self, billId):
        rawVotes = congress.votes(bill_id=billId, roll_type="On Passage", fields="voter_ids")

        if rawVotes is None:
            return

        ids = rawVotes[0]["voter_ids"]

        for key, value in ids.iteritems():
            self.lastVoteId += 1
            legislator = None

            # Create vote obj for each individual
            vote = {"vote": value, "bill": self.bills[billId]}

            # if we have a legislator for that id
            if self.legislators.get(key) != None:
                legislator = self.legislators[key]

                # Add it to the vote
                vote["legislator"] = legislator
                vote["chamber"] = legislator["chamber"]

                legislator.keys()

                # Add vote to the legislator
                legislator["votes"].append(vote)

            self.bills[billId]["votes"].append(vote)
            self.votes[self.lastVoteId] = vote
Exemplo n.º 2
0
    def load_data(self, since=None):

        if not since:
            res = self.db.votes.aggregate(
                {'$group': {
                    '_id': '',
                    'last': {
                        '$max': '$voted_at'
                    }
                }})
            since = res['result'][0]['last'] if res['result'] else day_before(
                yesterday())

        votes = congress.votes(voted_at__gte=since.isoformat() + 'Z',
                               fields='roll_id,vote_type,bill,voted_at,result',
                               per_page=200)

        for vote in votes:
            if self.db.votes.find_one({'roll_id': vote['roll_id']}) is None:
                obj = self.db.Vote()
                obj.roll_id = vote['roll_id']
                obj.type = vote['vote_type']
                obj.voted_at = parse_date(vote['voted_at'])
                obj.result = vote['result']
                if 'bill' in vote:
                    obj.bill_id = vote['bill']['bill_id']
                    obj.sponsor_id = vote['bill']['sponsor_id']
                obj.save()
Exemplo n.º 3
0
    def buildVotesForBill(self, billId):
        rawVotes = congress.votes(bill_id=billId,
                                  roll_type='On Passage',
                                  fields='voter_ids')

        if rawVotes is None:
            return

        ids = rawVotes[0]['voter_ids']

        for key, value in ids.iteritems():
            self.lastVoteId += 1
            legislator = None

            # Create vote obj for each individual
            vote = {'vote': value, 'bill': self.bills[billId]}

            # if we have a legislator for that id
            if self.legislators.get(key) != None:
                legislator = self.legislators[key]

                # Add it to the vote
                vote['legislator'] = legislator
                vote['chamber'] = legislator['chamber']

                legislator.keys()

                # Add vote to the legislator
                legislator['votes'].append(vote)

            self.bills[billId]['votes'].append(vote)
            self.votes[self.lastVoteId] = vote
Exemplo n.º 4
0
    def get(self):
        if self.current_user not in settings.get('staff'):
            self.redirect('/')

        # Sunlight API pukes on null args, so sanitize
        kwargs = {'per_page': 50}  # Max 50 results
        form = self.get_votes_form()
        for k, v in form.iteritems():
            if v:
                kwargs[k] = v

        # Query Sunlight API
        print kwargs
        #congress2 = PagingService(congress)
        #votes = list(congress2.votes(**kwargs))
        votes = congress.votes(**kwargs)

        # Post-query logic
        if not votes:
            err = 'No search results, try again'
            return self.render('admin/votes.html', form=form, err=err)
        if len(votes) > 1:
            msg = 'Showing %s results:' % len(votes)
            # TODO: returns max 50 results on first page. Give option to search further pages
        else:
            msg = 'Please confirm that this is the correct vote'
        return self.render('admin/votes.html', msg=msg, votes=votes, form=form)
Exemplo n.º 5
0
def tweet(request):
    vote = request.GET # assumes request comes from votes(request)
    reps_account_placeholder = "@[representative's account]"
    choice_placeholder = '[yes/no]'
    tweet_beginning = "%s voted %s on " % (reps_account_placeholder, choice_placeholder)

    if request.method == 'POST': # If the form has been submitted...
        form = TweetForm(request.POST)
        if not form.is_valid():
            error = 'Submitted invalid tweet!'
            return render_to_response('tweet.html', {'error': error, 'tweet_beginning': tweet_beginning, 'vote': vote, 'form':form}, 
                context_instance=RequestContext(request))
        else: 
            # Create base tweet
            tweet_text = form.cleaned_data['text']
            tweet_template = tweet_beginning + tweet_text

            # Get votes for each politician from Sunlight
            kwargs = {'fields': 'voter_ids'}
            for k, v in request.GET.iteritems():
                if v:
                    kwargs[k] = v
            individual_votes = congress.votes(**kwargs)
            if len(individual_votes) != 1:
                print 'Error finding votes'
                return
                #TODO figure out error handling or better transfer method
            individual_votes = individual_votes[0]['voter_ids'] # returns a dict with bioguide_ids for keys

            # Tweet for every applicable politician
            for twitter_ftv in Twitter_FTV.objects.all().exclude(handle="FollowTheVote"):
                p = twitter_ftv.politician
                # Hierarchy of name choosing
                if len(p.brief_name()) <= 16:
                    name = p.brief_name()
                elif p.twitter:
                    name = twitter
                elif len(p.last_name) <= 16:
                    name = p.last_name
                elif p.title == 'sen':
                    name = "Senator"
                else:
                    name = "Representative"

                # Find corresponding vote
                if p.portrait_id in individual_votes:
                    choice = individual_votes[p.portrait_id]
                    if choice == 'Yea':
                        choice = 'YES'
                    elif choice == 'Nay':
                        choice == 'NO'
                    tweet = tweet_template.replace(reps_account_placeholder, name).replace(choice_placeholder, choice)
                    twitter_ftv.tweet(tweet)

            return render_to_response('admin.html', {'msg': 'All accounts tweeted successfully!'}, 
        context_instance=RequestContext(request))
    else:
        form = TweetForm()
        return render_to_response('tweet.html', {'tweet_beginning': tweet_beginning, 'vote': vote, 'form':form}, 
            context_instance=RequestContext(request))
Exemplo n.º 6
0
def votes(request):
    if request.method == 'POST': # If the form has been submitted...
        form = VotesForm(request.POST) # A form bound to the POST data
        if form.is_valid():
            # Sunlight API pukes on null args, so sanitize
            kwargs = {'per_page': 50}
            for k, v in form.cleaned_data.items():
                if v:
                    kwargs[k] = v

            # Query Sunlight API
            votes = congress.votes(**kwargs)

            # Post-query logic
            if not votes:
                error = 'No search results, try again'
                return render_to_response('votes.html', {'error': error, 'form': form}, 
                    context_instance=RequestContext(request))
            if len(votes) > 1:
                message = 'Found %s results, please choose the correct one:' % len(votes)
                # TODO: returns max 50 results on first page. Give option to search further pages
            else:
                message = 'Please confirm that this is the correct vote'
            return render_to_response('votes.html', {'message': message, 'votes': votes}, 
                context_instance=RequestContext(request))
    else:
        form = VotesForm() # An unbound form
        message = 'What shall we tweet about? Search the Congressional Archives'
        return render_to_response('votes.html', {'form': form, 'message': message}, 
            context_instance=RequestContext(request))
Exemplo n.º 7
0
  def buildVotesForBill(self, billId):
    rawVotes = congress.votes(bill_id=billId,
      roll_type='On Passage',
      fields='voter_ids')

    if rawVotes is None:
      return

    ids = rawVotes[0]['voter_ids']

    for key, value in ids.iteritems():
      self.lastVoteId += 1
      legislator = None

      # Create vote obj for each individual
      vote = {
        'vote': value,
        'bill': self.bills[billId]
      }

      # if we have a legislator for that id
      if self.legislators.get(key) != None:
        legislator = self.legislators[key]

        # Add it to the vote
        vote['legislator'] = legislator
        vote['chamber'] = legislator['chamber']

        legislator.keys()

        # Add vote to the legislator
        legislator['votes'].append(vote)

      self.bills[billId]['votes'].append(vote)
      self.votes[self.lastVoteId] = vote
	def voted_for(self, score_adjustment, roll_ids):
		""" Checks for aye votes on one or more roll call votes """
		(adjustment_desc, adjustment) = self._get_adjustment_desc(score_adjustment)
		
		for roll_id in roll_ids:
			votes = congress.votes(roll_id=roll_id, fields='voters')	
			
			for legislator in self.scores:
				score = 0							
				if votes[0]['voters'].get(legislator, {'vote': 'not present in data'})['vote'].lower().strip() == 'yea':
					score = adjustment
				self.scores[legislator]['%s (%s%s)' % (adjustment_desc, (adjustment > 0) and '+' or '', adjustment)] = score		
    def voted_for(self, score_adjustment, roll_ids):
        """ Checks for aye votes on one or more roll call votes """
        (adjustment_desc, adjustment) = self._get_adjustment_desc(score_adjustment)

        for roll_id in roll_ids:
            votes = congress.votes(roll_id=roll_id, fields="voters")

            for legislator in self.scores:
                score = 0
                if votes[0]["voters"].get(legislator, {"vote": "not present in data"})["vote"].lower().strip() == "yea":
                    score = adjustment
                self.scores[legislator][
                    "%s (%s%s)" % (adjustment_desc, (adjustment > 0) and "+" or "", adjustment)
                ] = score
Exemplo n.º 10
0
    def load_data(self, since=None):

        if not since:
            res = self.db.votes.aggregate({'$group': {'_id': '', 'last': {'$max': '$voted_at'}}})
            since = res['result'][0]['last'] if res['result'] else day_before(yesterday())

        votes = congress.votes(voted_at__gte=since.isoformat() + 'Z', fields='roll_id,vote_type,bill,voted_at,result', per_page=200)

        for vote in votes:
            if self.db.votes.find_one({'roll_id': vote['roll_id']}) is None:
                obj = self.db.Vote()
                obj.roll_id = vote['roll_id']
                obj.type = vote['vote_type']
                obj.voted_at = parse_date(vote['voted_at'])
                obj.result = vote['result']
                if 'bill' in vote:
                    obj.bill_id = vote['bill']['bill_id']
                    obj.sponsor_id = vote['bill']['sponsor_id']
                obj.save()
Exemplo n.º 11
0
    def post(self):
        if self.current_user not in settings.get('staff'):
            return self.redirect('/')

        vote = self.get_vote()
        tweet_beginning = self.get_tweet_beginning()
        tweet_text = self.get_argument('tweet_text', '')

        # Check if rePOSTing. I did this once and it doesn't break anything
        # but fails when trying to tweet, so sets tweet document to 0 accounts tweeted
        existing_tweet = tweetdb.find_one({'vote': vote})
        if existing_tweet:
            return self.redirect('admin/?err=tweet_exists')

        if len(
                tweet_text
        ) > 110:  # poorly hardcoded. calculated from get_tweet_beginning()
            err = 'Some tweets will exceed 140 characters in length!'
            return self.render('admin/tweet.html',
                               err=err,
                               tweet_beginning=tweet_beginning,
                               vote=vote,
                               form=self.get_tweet_form())

        else:
            vote['fields'] = 'voter_ids'
            individual_votes = congress.votes(**vote)

            if len(individual_votes) != 1:
                print 'Error finding votes'
                raise Exception

            individual_votes = individual_votes[0][
                'voter_ids']  # returns a dict with bioguide_ids for keys

            # Tweet for every applicable politician. Yes, this is suboptimal
            tweeted = {}  # Track successfully tweeted accounts...
            failed = {}  # and those that failed
            for p in Politician.objects():
                # Hierarchy of name choosing
                if p.twitter:
                    name = "@" + p.twitter
                elif len(p.brief_name()) <= 16:
                    name = p.brief_name()
                elif len(p.last_name) <= 16:
                    name = p.last_name
                elif p.title == 'Sen':
                    name = "Senator"
                else:
                    name = "Representative"

                # Find corresponding vote
                if p.bioguide_id in individual_votes:
                    choice = individual_votes[p.bioguide_id]
                    if choice == 'Yea':
                        choice = 'YES'
                    elif choice == 'Nay':
                        choice = 'NO'
                    elif choice == 'Not Voting':
                        choice = 'abstained'

                    # Turn template into actual tweet and tweet!
                    tweet_template = tweet_beginning + tweet_text  # Further down replace
                    tweet = tweet_template.replace(REPS_ACCOUNT_PLACEHOLDER,
                                                   name).replace(
                                                       CHOICE_PLACEHOLDER,
                                                       choice)
                    if choice == 'abstained':
                        tweet = tweet.replace(
                            'voted ',
                            '')  # get rid of voting verb if abstained

                    success = p.tweet(tweet)
                    # If successfull tweeted, save for entry to database
                    if success:
                        tweeted[p.bioguide_id] = choice
                    else:
                        failed[p.bioguide_id] = choice

                    logging.info(len(tweeted))
                    logging.info(len(failed))
                # endfor p in Politician.objects():

            # Save to database
            save_tweet = {
                'datetime': datetime.datetime.now(),
                'vote': vote,
                'tweeted':
                tweeted,  # Who actually had FTV accounts, i.e. actually tweeted 
                'tweet_template': tweet_template,
                'placeholders': {
                    'reps_account_placeholder': REPS_ACCOUNT_PLACEHOLDER,
                    'choice_placeholder': CHOICE_PLACEHOLDER
                },
                'tweet':
                tweet,  # A sample tweet (always from last rep in database to tweet)
                'individual_votes': individual_votes,
                'admin': self.current_user
            }
            tweetdb.save(save_tweet)
            logging.info('saved tweet')

            # Email admins
            subject = '%s tweeted!' % self.current_user
            text_body = tweet_template
            for sn in settings.get('staff'):
                admin = userdb.get_user_by_screen_name(sn)
                try:
                    self.send_email(admin['email_address'], subject, text_body)
                except:
                    print 'Failed to send email to admin %s' % admin['user'][
                        'username']
                    pass

            if len(failed) is 0:
                return self.redirect('/admin?msg=tweet_success')
            else:
                return self.redirect(
                    '/admin?msg=tweet_success&num_accounts_failed=%s' %
                    len(failed))