From d72537739848839e48e9fd72127f8ad8cd9be449 Mon Sep 17 00:00:00 2001 From: Albert Sanchez Date: Sat, 20 Nov 2021 01:22:20 -0600 Subject: [PATCH] fix Command attrs, wrapping fixes, new actions Updated CLI to enforce -i requirement for run_cmd_tweet, get_tweet_parents, and test_parser. Twitter bot actions: - Added new run_cmd_tweet action - Fixed behavior of pasta_tweet action - Updated docstring on test_parser --- pseudbot/cli.py | 8 +++- pseudbot/command.py | 30 ++++++++----- pseudbot/tweet_bot.py | 100 +++++++++++++++++++++++++++++++----------- 3 files changed, 101 insertions(+), 37 deletions(-) diff --git a/pseudbot/cli.py b/pseudbot/cli.py index a782ceb..4fadb8c 100644 --- a/pseudbot/cli.py +++ b/pseudbot/cli.py @@ -80,7 +80,13 @@ def main(args: [str], name: str) -> int: ) elif opts.action == "list_actions": pb = PseudBot(tcfg=tcfg, quiet=True, debug=opts.debug) - elif opts.action in ("pasta_tweet", "dump_tweet"): + elif opts.action in ( + "pasta_tweet", + "dump_tweet", + "run_cmd_tweet", + "get_tweet_parents", + "test_parser", + ): if opts.reply_to_id is not None: pb = PseudBot( tcfg=tcfg, diff --git a/pseudbot/command.py b/pseudbot/command.py index 25e9f36..39434b2 100644 --- a/pseudbot/command.py +++ b/pseudbot/command.py @@ -6,25 +6,25 @@ from .pastas import PASTAS class Command: - pasta = "" - media = [] - target = None - - error = None - reason = None - def __init__(self, text: str, debug: bool = False): self.text = re.sub(r"[\ufe0f]", "", text, re.UNICODE) self.debug = debug + + self.pasta = "" + self.media = [] + self.target = None + self.error = False + self.reasons = [] + self.parse() def parse(self): - words = re.split(r'[\s.;():"]+', self.text) + words = re.split(r'[\s.;():"]+', self.text, re.UNICODE) if len(words[-1]) < 1: words.pop() if self.debug is True: - print('[DEBUG]: words: "{}"'.format(words)) + print('[DEBUG]: [WORDS]: "{}"'.format(words)) lexed = { "all": [], @@ -51,7 +51,7 @@ class Command: self.media.append(random.choice(MEDIA[media_category])) else: self.error = True - self.reason = 'Could not find media category: "{}"'.format( + self.reasons = 'Could not find media category: "{}"'.format( media_category ) if words[i] == "😲🤳": @@ -75,7 +75,15 @@ class Command: def mk_commands(text: str, debug: bool = False) -> [Command]: commands = [] - for command_string in text.split("|"): + split_input = text.split("|") + + if debug is True: + print("[DEBUG]: split command input: {}".format(split_input)) + + for command_string in split_input: commands.append(Command(text=command_string, debug=debug)) + if debug is True: + print('[DEBUG]: self.pasta = "{}"'.format(commands[-1].pasta)) + print("[DEBUG]: self.media = {}".format(commands[-1].media)) return commands diff --git a/pseudbot/tweet_bot.py b/pseudbot/tweet_bot.py index 22e19c2..673badf 100644 --- a/pseudbot/tweet_bot.py +++ b/pseudbot/tweet_bot.py @@ -131,12 +131,14 @@ class PseudBot: jdump(jsons, extra_tag=self.screen_name) def _tweet_media( - self, id_reply_to: int, parent_screen_name: str, media: [str] = [] + self, id_reply_to: int, parent_screen_names: str, media: [str] = [] ): _stat = self.last_stat + if self.debug is True: + print("[DEBUG]: _tweet_media's media: {}".format(media)) try: self.last_stat = self.tapi.update_status_with_media( - "@" + parent_screen_name, + parent_screen_names, in_reply_to_status_id=id_reply_to, filename=media.pop(0), ) @@ -145,8 +147,18 @@ class PseudBot: if len(media) > 0: sleep(2) + parent_screen_names = ( + parent_screen_names + if parent_screen_names.startswith( + "@" + self.last_stat.user.screen_name + ) + else "@" + + self.last_stat.user.screen_name + + " " + + parent_screen_names + ) return self._tweet_media( - self.last_stat.id, self.last_stat.user.screen_name, media + self.last_stat.id, parent_screen_names, media ) else: return self.last_stat @@ -230,14 +242,15 @@ class PseudBot: jdump(tweets_j) - def dump_tweet(self): + def dump_tweet(self, status_id: int = None): """ Dump the JSON data dictionary of a specific tweet. If called from the CLI, requires ``-i`` to be set. """ - tweets = self.tapi.lookup_statuses( - [self.last_id], tweet_mode="extended" - ) + if status_id is None: + status_id = self.last_id + + tweets = self.tapi.lookup_statuses([status_id], tweet_mode="extended") jtweets = [] for tweet in tweets: log_t_by_sname(tweet) @@ -247,13 +260,30 @@ class PseudBot: def pasta_tweet(self): """ - Insert a copy pasta in a Tweet chain manually starting from a specific + Insert a copy pasta in a Tweet chain manually under a specific tweet ID. Requires ``-i`` to be set if calling from the CLI. """ - pasta = [] + tweet = self.tapi.lookup_statuses( + [self.last_id], tweet_mode="extended" + )[0] + parents = self._get_reply_parents(tweet) + parent_screen_names = " ".join(list(map(lambda p: "@" + p[1], parents))) + + pasta = "" while len(pasta) < 1: pasta = random.choice(PASTAS) + noodles = self._make_pasta_chain(parent_screen_names, pasta) + self._tweet_pasta(self.last_id, noodles) + + print("[INFO]: Inserting pasta under {}...".format(self.last_id)) + + def run_cmd_tweet(self): + """ + Parse a specific tweet for a command and post specified pasta(s). + Requires ``-i`` to be set if calling from the CLI. + """ + print("[INFO]: Replying to {}...".format(self.last_id)) tweets = self.tapi.lookup_statuses( [self.last_id], tweet_mode="extended" @@ -265,7 +295,7 @@ class PseudBot: """ Print the parent tuple list (parent_id, reply_to_screen_name). - Works best when invoked with -i on a tweet status ID. + Requires ``-i`` to be set if calling from the CLI. """ print( self._get_reply_parents( @@ -299,9 +329,9 @@ class PseudBot: parent_id = tweet.in_reply_to_status_id parents = parents + self._get_reply_parents( tweet=self.tapi.lookup_statuses( - [tweet.in_reply_to_status_id], tweet_mode="extended" - )[0] - ) + [tweet.in_reply_to_status_id], tweet_mode="extended" + )[0] + ) else: reply_to_screen_name = tweet.user.screen_name parent_id = tweet.id @@ -315,7 +345,7 @@ class PseudBot: Run the command parser in a dry run (e.g. without sending any tweets) on a specific tweet. - Works best when invoked with -i on a tweet status ID. + Requires ``-i`` to be set if calling from the CLI. """ self._parse_mention( self.tapi.lookup_statuses([self.last_id], tweet_mode="extended")[0], @@ -328,12 +358,21 @@ class PseudBot: """ # Each parent in the list is a (parent_id, parent_screen_name) tuple. parents = self._get_reply_parents(tweet) + parent_screen_names = " ".join(list(map(lambda p: "@" + p[1], parents))) drybug = False if wet_run is True else True - - for command in mk_commands(get_tweet_text(tweet), debug=drybug): + if self.debug is True: + jdump(tweet._json, extra_tag="{}.debug".format(tweet.id)) + drybug = True + + commands = mk_commands(get_tweet_text(tweet), debug=drybug) + for ci in range(len(commands)): + command = commands[ci] + pasta = [] if len(command.pasta) > 0: - pasta = self._make_pasta_chain(parents, command) + pasta = self._make_pasta_chain( + parent_screen_names, command.pasta + ) if wet_run is True: self._tweet_pasta(parents[0][0], pasta, command.media) else: @@ -341,9 +380,8 @@ class PseudBot: print("[DRY]: Such wow, very tweet!") elif len(command.media) > 0: if wet_run is True: - self._tweet_media( - parents[0][0], parent_screen_name, command.media - ) + media = command.media + self._tweet_media(parents[0][0], parent_screen_names, media) else: # TODO: show media in dry mode? print("[DRY]: Such wow, very media!") @@ -354,20 +392,32 @@ class PseudBot: ), file=stderr, ) + if self.debug is True: + print( + "[DEBUG]: error parsing text from " + + "commands[{}]. ".format(ci) + + "text: {}".format( + list(map(lambda c: c.text, commands)) + ) + ) + self.dump_tweet(status_id=tweet.id) - def _make_pasta_chain(self, parents: [(int, str)], cmd: Command) -> [str]: + def _make_pasta_chain(self, parent_screen_names: str, in_txt: str) -> [str]: """ Make a text reply chain. """ - - parent_screen_names = " ".join(list(map(lambda p: "@" + p[1], parents))) pasta = [] - in_pasta = wrap(parent_screen_names + " " + cmd.pasta, width=280) + in_pasta = wrap(parent_screen_names + " " + in_txt, width=280) pasta.append(in_pasta.pop(0)) while len(in_pasta) > 0: tmp_pasta = wrap( - "@" + self.screen_name + " " + parent_screen_names + " " + in_pasta.pop(0), + "@" + + self.screen_name + + " " + + parent_screen_names + + " " + + in_pasta.pop(0), width=280, ) pasta.append(tmp_pasta.pop(0))