def on_status(self, tweet: tweepy.Status) -> None: """Retweet and like matching tweets containing keywords and/or by accounts to watch. """ try: # Return if tweet belongs to bot or is already checked. if self.is_own_tweet(tweet): return utils.log_stream_warning( 'This is your own tweet, ignore!') if tweet.id <= self.since_id: return logger.warning( "You've already checked this tweet, ignore!") time.sleep(10) self.since_id = tweet.id logger.info(f'Current tweet:\n{tweet.text}') # Reply to mention. if tweet.in_reply_to_status_id is None and self.is_mention(tweet): self.reply_to_mention(tweet) logger.info(f'Replied to {tweet.user.screen_name}') print() time.sleep(10) return None # Like and retweet tracked tweets. self.like(tweet) time.sleep(0.1) self.retweet(tweet) time.sleep(0.1) except tweepy.TweepError as e: utils.log_tweepy_error(e) finally: print()
def on_error(status_code): """Handle stream errors based on error status code.""" if status_code == 420: print('Disconnected the stream') return False # Disconnect stream if status_code == 429: logger.info('Waiting 120 seconds...') time.sleep(120) else: utils.log_tweepy_error(tweepy.TweepError)
def main(): """Create API instance and handle followers. Follow back any followers and unfollow ex followers. """ api = create_api() while True: try: follow_followers(api) unfollow_non_followers(api) time.sleep(RATE_LIMIT_BREAK) except KeyboardInterrupt: print() logger.info('Exiting polling on user request, bye!') sys.exit()
def filter( stream: tweepy.Stream, keywords, accounts, is_async: bool = config.STREAM_USES_MULTIPLE_THREADS, ) -> None: """Fetch and process tweets matching keywords and watched accounts. """ try: stream.filter( track=keywords, follow=accounts, is_async=is_async, ) except KeyboardInterrupt: stream.disconnect() print() logger.info('Exiting stream on user request, bye!') sys.exit()
def follow_followers(api: tweepy.API) -> None: """Follow all followers.""" logger.info('Retrieving followers...') for follower in api_cursor(api.followers): logger.info(f'Follower: {follower.name} ({follower.screen_name})...') if not follower.following: try: follow_user(api, user_id=follower.id_str) logger.info(f'Following {follower.name} (' f'{follower.screen_name})') time.sleep(ACTION_BRAKE) except tweepy.TweepError as e: log_tweepy_error(e) logger.info(f'Waiting {RATE_LIMIT_BREAK} seconds...') time.sleep(RATE_LIMIT_BREAK)
def unfollow_non_followers(api: tweepy.API) -> None: """Unfollow all non-followers.""" logger.info('Retrieving followed users and checking relationships...') for friend in api_cursor(api.friends): logger.info(f'Currently following {friend.name} (' f'{friend.screen_name})...') if not is_follower(api, user_id=friend.id_str): try: print('We are no longer friends. :(') unfollow_user(api, user_id=friend.id_str) logger.info(f'Unfollowing {friend.name} (' f'{friend.screen_name})') time.sleep(ACTION_BRAKE) except tweepy.TweepError as e: log_tweepy_error(e) logger.info(f'Waiting {RATE_LIMIT_BREAK} seconds...') time.sleep(RATE_LIMIT_BREAK)
def on_friends(friends): # Todo: Implement method. logger.info(f'on_friends method triggered: {friends=}')
if config.TRACK_HASHTAGS: keywords.update(config.HASHTAGS) if config.TRACK_MENTIONS: keywords.add('@' + api.me().screen_name) return {'keywords': keywords, 'accounts': accounts} def filter( stream: tweepy.Stream, keywords, accounts, is_async: bool = config.STREAM_USES_MULTIPLE_THREADS, ) -> None: """Fetch and process tweets matching keywords and watched accounts. """ try: stream.filter( track=keywords, follow=accounts, is_async=is_async, ) except KeyboardInterrupt: stream.disconnect() print() logger.info('Exiting stream on user request, bye!') sys.exit() if __name__ == '__main__': logger.info('Create and open a stream via the stream.py module.')