def add_twitter_to_politician(): # Politicians w/out FTV ps = Politician.objects(ftv__exists=False) p_counter = 0 print len(ps) for a in db.paid_twitter.find(): if 'assigned_to_bioguide_id' not in a.keys(): if p_counter < len(ps): # Don't go over array length p = ps[p_counter] print p_counter print p.last_name # Double check p.ftv doesn't exist if p.ftv: raise Exception # Assign new twitter account! p.ftv = FTV(twitter = a['twitter'], twitter_id = a['twitter_id'], access_key = a['access_key'], access_secret = a['access_secret'], name = a['name'], email = a['email'], email_password = a['email_password']) p.save() p_counter = p_counter + 1 a['assigned_to_bioguide_id'] = p.bioguide_id save(a) else: print "No more politicians! We have extra twitter accounts!"
def update_all_friends(): fail_list = [] for p in Politician.objects(): #__raw__={'ftv':{'$exists':True}}): print "Updating friends of %s..." % p.name() try: api = p.login_twitter() except: print "Could not authenticate with %s" % p.name() break list_friends = api.friends_ids() for p2 in Politician.objects(): #__raw__={'ftv':{'$exists':True}}): if not p.bioguide_id == p2.bioguide_id and p2.ftv.twitter_id not in list_friends and p2.ftv.twitter not in fail_list: try: api.create_friendship(p2.ftv.twitter_id) print "Following %s..." % p2.ftv.twitter except: print p2.ftv.twitter print p2.ftv.twitter_id fail_list.append(p2.ftv.twitter) print fail_list
def get(self): if self.current_user not in settings.get('staff'): self.redirect('/') else: # Database filtering title = self.get_argument('title', None) no_description = self.get_argument('no_description', None) if title: politicians = Politician.objects(title=title) elif no_description: politicians = Politician.objects(ftv__description="") else: politicians = Politician.objects() # Order politicians = politicians.order_by('-title', 'last_name') if self.get_argument('show_twitter', None): return self.render('admin/database_twitter.html', politicians=politicians) else: return self.render('admin/database.html', politicians=politicians)
def check_twitter_ftv(): fail_list = [] for p in Politician.objects(): print "Checking %s..." % p.name() try: api = p.login_twitter() except: print "Failed: %s" % p.name() fail_list.append(p.bioguide_id) me = api.verify_credentials() p.ftv.twitter = me.screen_name p.ftv.description = me.description p.ftv.name = me.name p.save() if fail_list: print fail_list
def update_all(): for p in Politician.objects(): print "Updating %s..." % p.name() try: api = p.login_twitter() except: print "Could not authenticate with %s" % p.name() break # Determine description, name, location, and url... if p.twitter: p.ftv.description = 'Tweeting the Congressional votes of @%s' % p.twitter # 160 char max else: p.ftv.description = 'Tweeting the Congressional votes of %s' % p.brief_name() p.ftv.name = 'FTV for %s' % p.brief_name() # 20 char max if len(p.ftv.name) > 20: p.ftv.name = p.ftv.name.replace('.', '') if len(p.ftv.name) > 20: p.ftv.name = "FTV @%s" % p.twitter if len(p.ftv.name) > 20: print p['ftv']['name'] print len(p['ftv']['name']) raise Exception # ...and write try: api.update_profile(name=p.ftv.name, location='Washington, D.C.', description=p.ftv.description, url='http://followthevote.org') profile_img_path = settings.get('project_root') + '/static/img/congress.jpeg' api.update_profile_image(profile_img_path) background_img_path = settings.get('project_root') + '/static/img/congress.jpeg' api.update_profile_background_image(background_img_path, tile='true') # Not working p.save except: print "Could not update %s" % p.name()
def post(self): if self.current_user not in settings.get('staff'): return self.redirect('/') tweet = self.get_argument('tweet_text', '') if not tweet: return self.redirect('') # Goes back to GET # 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({'tweet': tweet}) if existing_tweet: err = 'Already tweeted same text!' return self.render('admin/tweet_no_vote.html', err=err, tweet_text=tweet) if len(tweet) > 110: err = 'Tweet exceeds 110 characters' return self.render('admin/tweet_no_vote.html', err=err, tweet_text=tweet) # Get accounts to tweet for account = self.get_argument('account', '') chamber = self.get_argument('chamber', '') if account and chamber: err = 'Please choose EITHER a group of accounts or write in a single FTV account name' return self.render('admin/tweet_no_vote.html', err=err, tweet_text=tweet) # Single account takes precedence if account: try: politicians = Politician.objects(ftv__twitter=account) except: err = 'Could not find account' return self.render('admin/tweet_no_vote.html', err=err, tweet_text=tweet) else: if chamber == 'all': politicians = Politician.objects() elif chamber == 'house': politicians = Politician.objects(chamber='House') elif senate == 'senate': politicians = Politician.objects(chamber='Senate') else: raise Exception tweeted = [] # Track successfully tweeted accounts... failed = [] # and those that failed for p in politicians: success = p.tweet(tweet) # If successfully tweeted, save for entry to database if success: tweeted.append(p.bioguide_id) else: failed.append(p.bioguide_id) # Save to database save_tweet = { 'datetime': datetime.datetime.now(), 'tweeted': tweeted, # Who actually had FTV accounts, i.e. actually tweeted 'tweet': tweet, # A sample tweet (always from last rep in database to tweet) 'admin': self.current_user } tweetdb.save(save_tweet) logging.info('saved tweet') # Email admins subject = '%s tweeted!' % self.current_user text_body = tweet 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))
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))
def update_accounts(): fail_list = [] # Those accounts that failed to update for p in Politician.objects(title="Sen"): # Calc new username if p.title == 'Sen': if p.ftv.twitter == 'FTV_' + p.state + '_Senator1' or p.ftv.twitter == 'FTV_' + p.state + '_Senator2': new_username = p.ftv.twitter if p.ftv.email == p.state + "*****@*****.**" or p.ftv.email == p.state + "*****@*****.**": new_email = p.ftv.email else: if '1' in new_username: new_email = p.state + "*****@*****.**" else: new_email = p.state + "*****@*****.**" else: # then need a new username new_username = '******' + p.state + '_Senator1' if Politician.objects(ftv__twitter=new_username, bioguide_id__ne=p.bioguide_id): new_username = '******' + p.state + '_Senator2' if '1' in new_username: new_email = p.state + "*****@*****.**" else: new_email = p.state + "*****@*****.**" elif p.title == 'Rep': new_username = '******' + p.state + str(p.district) new_email = p.state + str(p.district) + "@followthevote.org" else: if len(p.full_state_name) <= 11: new_username = '******' + p.full_state_name else: new_username = '******' + p.state new_email = p.state + "@followthevote.org" # Run splinter log in only if username needs updating if new_username != p.ftv.twitter: # or new_email != p.ftv.email: print 'Changing %s...' % p.name() print "new: " + new_username print p.ftv.twitter print "" print "new: " + new_email print p.ftv.email print "" try: with splinter.Browser( 'chrome') as browser: # browser closes at end browser.visit('https://twitter.com') # Log in browser.fill('session[username_or_email]', p.ftv.twitter) browser.fill('session[password]', p.ftv.twitter_password) browser.find_by_css('button').first.click() # Click on settings gear icon browser.visit('https://twitter.com/settings/account') # Change username and/or email if new_username != p.ftv.twitter: browser.fill('user[screen_name]', new_username) #if new_email != p.ftv.email: browser.fill('user[email]', new_email) time.sleep(1) browser.find_by_id('settings_save').first.click() time.sleep(1) browser.fill('auth_password', p.ftv.twitter_password) browser.find_by_id('save_password').first.click() # Save to database p.ftv.twitter = new_username old_email = p.ftv.email p.ftv.email = new_email p.ftv.email_password = "" p.save() print 'Saved!' print "-------------" # Click on email confirmation if new_email != old_email: time.sleep(3) # Wait for confirmation email to arrive #gmail_confirm(browser) code below instead browser.visit('https://gmail.com') # Log in browser.fill('Email', '*****@*****.**') browser.fill('Passwd', 'statueofliberty') browser.find_by_id('signIn').first.click() # Click on first email browser.find_by_css('td')[7].click() # Click on link to verify email browser.find_link_by_partial_href( 'https://twitter.com' )[3].click( ) #says this link is invalid but still seems to work except: fail_list.append(p.name()) print fail_list