def execute(self, delay): user = self.tweet.user res = self.make_request(constants.FOLLOW_URL, error_delay=delay) if res.status_code != 200: logger.error(f'failed to follow {user.username}') else: logger.info(f'followed: {user.username}')
def execute(self, delay): time.sleep(delay) res = self.make_request(url=constants.LIKE_URL, error_delay=delay) if res.status_code != 200: logger.error(f'failed to like: {self.tweet}') else: logger.info(f'liked: {self.tweet}')
def clear(silent=False): cache = _get_cache_fs() dir = cache.getsyspath('/') for the_file in os.listdir(dir): file_path = os.path.join(dir, the_file) try: if os.path.isfile(file_path): os.unlink(file_path) except Exception as e: pass else: if not silent: logger.info('All stored data has been erased')
def login(username, password, tries=10, delay=2): with create_session(username) as session: res = session.get(constants.LOGIN_URL) soup = BeautifulSoup(res.text,"html.parser") token = soup.select_one("[name='authenticity_token']")['value'] payload = { 'session[username_or_email]':username, 'session[password]': password, 'authenticity_token':token, 'ui_metrics': constants.UI_METRICS, 'authenticity_token':token, 'remember_me':1 } session.headers['Origin'] = constants.BASE_URL session.headers['Referer'] = constants.LOGIN_URL session.headers['Upgrade-Insecure-Requests'] = '1' time.sleep(5) # pause a bit while tries > 0: try: session.headers['User-Agent'] = ua_provider.fetch() res = session.post(constants.SESSIONS_URL, data=payload, allow_redirects=False) res.raise_for_status() if 'location' in res.headers: url = res.headers['location'] if 'locked' in url: logger.error('Too many attempts. Your account has been locked (60 mins).') exit() elif 'error' in url: raise InvalidCredentials if 'auth_token' in res.cookies.get_dict(): typing.cast(FileCookieJar, session.cookies).save() logger.info(f'You have signed in as {username}') return except Exception as ex: if isinstance(ex, InvalidCredentials): raise logger.error(f'Error while signing in:\n{ex}') pass time.sleep(delay) tries -= 1 # Twitter won't provide auth_token in cookies or ban logger.error( '''Failed to sign in. Your IP address (or account) may have been banned (yikes). Try logging in through your browser. If you can't log in, then you've been banned.''' ) exit()
def _is_logged(username): session, expired = create_session(username), False if session is not None: for cookie in session.cookies: if cookie.is_expired(): expired = True break if cookie.name == 'auth_token': logger.info(f'You have signed in as {username}') return True if expired: # remove cookies for that user file = _get_cache_fs().getsyspath( f'{username}-{constants.COOKIES_FILE}' ) os.remove(file) logger.warning(f'{username}\'s session has expired. Please sign in.') else: logger.warning(f'No sessions found for {username}.') return False
def _finish(self, query, tweet_count): self._queue.put(_sentinel) time.sleep(3) # some executor may be still working logger.info(f'{query} --- Total tweets found:{tweet_count}')
def main(): if sys.version_info[0] < 3: logger.error('Python 3 or a more recent version is required.') exit() parser = argparse.ArgumentParser() parser.add_argument( '-a', '--agents', help='File containing user-agents', dest='agents_file', default=f'{default_config_path}/user-agents.txt' ) parser.add_argument( '-i', '--invalidate', help='Invalidate all saved sessions', dest='invalidate', action='store_true' ) parser.add_argument( '-v', '--version', help='Version of the bot', dest='version', action='store_true' ) parser.add_argument( '-c', '--config', help='Configuration file', dest='config', default=f'{default_config_path}/config.json' ) parser.add_argument( '-e', '--executor-count', help='How many executors should we have running', dest='executor_count', default=2 ) args = parser.parse_args() if args.version: logger.info(f'tweebot version: {__version__}') exit() if args.invalidate: _base.clear() if args.agents_file: ua_provider.load(args.agents_file) if not args.config: logger.error('You need to provide the path to the config.json file') exit() config = {} try: with open(args.config, encoding='UTF-8') as fp: config = json.loads(fp.read()) config['searchers']; config['handlers'] # quick check except Exception as ex: exit(f'Failed to read config.json .\n {ex}') if not 'executors' in config: if not args.executor_count: logger.error( '''You will need to provide configurations for the executor object. Check the docs for more info.''' ) exit() config['executors'] = [{ 'count': args.executor_count, 'request-delay': 2 }] while True: username = input('Twitter username: '******'Twitter password: '******'Invalid credentials.Try again') continue os.environ['username'] = username break tweet_queue = queue.Queue() action_queue = queue.Queue() for params in config['searchers']: searcher = _get_searchers(tweet_queue, params) _spin_searchers(searcher['query'], searcher['searchers']) for params in config['handlers']: handler = _get_handlers(tweet_queue, action_queue, params) _spin_handlers(handler) for params in config['executors']: executors = _get_executors(action_queue, **params) _spin_executors(executors) tweet_queue.join(); action_queue.join()