def _change_passwords(self, rows: List[dict]): """ Change the password of the accounts that are loaded in the `dict` param. Also save the accounts to the DB. :param [dict] rows: A list containing the information of the accounts. """ # Push an app context. app = create_app() app.app_context().push() # Create a rotating log for errors. logger = logging.getLogger() logger.setLevel(logging.ERROR) handler = RotatingFileHandler('logs/password_update.log', maxBytes=65536, backupCount=5) logger.addHandler(handler) # Also send errors to stderr. logger.addHandler(logging.lastResort) # Each row represents the information of one account. for row in rows: # Create the account model. account = Account(**row) # Generate the new password. chars = string.ascii_letters + string.digits new_password = ''.join((random.choice(chars)) for x in range(8)) try: # Update the account password. TwitterPasswordUpdate(TwitterLogin(account), new_password) # Save the new password. account.password = new_password except Exception as e: # There was an error during the password update. logger.error('"%s" password update failed with exception: %s', account.screen_name, e) # Save the account to the DB. db.session.add(account) db.session.commit()
from createapp import create_app app = create_app() if __name__ == "__main__": app.run()
def _vote(self, vote_pool_id: int): """ Make the vote requests. :param int vote_pool_id: Vote pool ID. """ # Push an app context. app = create_app() app.app_context().push() # We need to create the model again because the same db session cannot # be used from two different threads. vote_pool = VotePool.query.filter(VotePool.id == vote_pool_id).first() # Add this pool to the list of running vote pools. running_vote_pool_ids.append(vote_pool.id) # Get the id of the accounts that already voted on the poll. screen_names = [] duplicated_vote_pools = VotePool.query.\ filter(VotePool.id != vote_pool.id).\ filter(VotePool.tweet_id == vote_pool.tweet_id).all() if duplicated_vote_pools: vote_pool_ids = [vp.id for vp in duplicated_vote_pools] votes = Vote.query.\ filter(Vote.vote_pool_id.in_(vote_pool_ids)).\ filter(Vote.hit == True).all() screen_names = [v.screen_name for v in votes] # Get the accounts that are the most likely to make a successful vote. # Custom order for status column. whens = { Account.STATUS_LOGGED_IN: 1, None: 2, Account.STATUS_UNCONFIRMED_ACCESS: 3, Account.STATUS_UNDETERMINED: 4, Account.STATUS_WRONG_CREDENTIALS: 5, Account.STATUS_SUSPENDED: 6 } status_order = case(value=Account.status, whens=whens) accounts = Account.query.\ filter(Account.screen_name.notin_(screen_names)).\ order_by( status_order, Account.status_updated_at.desc(), Account.id.desc() ).\ limit(vote_pool.max_tries).all() # Try while there are available accounts and the intended hits was not # reached. while accounts and self._hits < vote_pool.intended_hits: # Sleep for a random amount of time if the previos try was a hit. # Error could be undeclared. if 'error' in locals() and not locals()['error']: sleep(random() * 60) # Sleep for a maximum of one minute. account = accounts.pop(0) error = None # Try to vote. try: twitter_login = TwitterLogin(account) twitter_poll = \ TwitterPoll(vote_pool.tweet_id, twitter_login) twitter_poll.vote(vote_pool.option_index) except Exception as e: error = str(e) # Save the result. vote = Vote(vote_pool_id=vote_pool.id, create_datetime=datetime.utcnow(), screen_name=account.screen_name, email=account.email, password=account.password, phone_number=account.phone_number, hit=not error, error=error) db.session.add(vote) db.session.commit() if not error: self._hits += 1 # The vote pool has finished. Update its status. vote_pool.update_status(VotePool.STATUS_FINISHED) # Remove it from the list of running vote pools. running_vote_pool_ids.remove(vote_pool.id)