Marc-Alexandre Chan avatar Marc-Alexandre Chan committed bfd13fa

Bugfixes for message/reply-sending commands; fix misuse of msg.author to msg.author.name

Comments (0)

Files changed (1)

minibot/events.py

                     CommandParameterError, MissingParameterError) as e:
                 self.log.info("%s: %s", classname(self), e.args[0])
 
-                self.log.info("%s: Replying to invalid command PM %s (%d)",
-                    classname(self), msg.author, msg.id)
+                self.log.info("%s: Replying to invalid command PM from %s (%d)",
+                    classname(self), msg.author.name, msg.id)
                 err_cmd = SendErrorMessageCommand.command_parameter(e, msg)
                 self.owner.queue_event(err_cmd)
 
                 if msg.subreddit is None:
                     self.log.info(
                         "%s: Ignoring bad private message from %s (%d)",
-                        classname(self), msg.author, msg.id)
+                        classname(self), msg.author.name, msg.id)
                 msg.mark_as_read()
 
     def end(self):
 
         """
         self.log.debug('%s: Parsing message %d from %s.',
-            classname(self), msg.id, msg.author)
+            classname(self), msg.id, msg.author.name)
         msg_data = {}
         text_data = []
 
     def _exc_msg_data(self, msg):
         """ Return info string on a message for use in exceptions. """
         return 'message "{subject}" from {author} at {time}'.format(
-            txt=msg.subject, author=msg.author,
+            txt=msg.subject, author=msg.author.name,
             time=strftime('%Y-%m-%d %H:%M:%S',
                 localtime(msg.created_utc)))
 
     def __repr__(self):
         """ Return a string representing this object. """
         return '<{cls}: message {id_} ({author}), {args}>'.format(
-                cls=classname(self), id_=self.msg.id, author=self.msg.author,
-                args=self.raw_params)
+                cls=classname(self), id_=self.msg.id,
+                author=self.msg.author.name, args=self.raw_params)
 
     def _check_param_fields(self):
         """ Check that the parameter fields passed are valid and that all
 
     def __repr__(self):
         return "<{cls}: message={msg_id} ({author}), id={p_id}>".format(
-                cls=classname(self), msg_id=self.msg.id, author=self.msg.author,
-                p_id=self.id)
+                cls=classname(self), msg_id=self.msg.id,
+                author=self.msg.author.name, p_id=self.id)
 
 
 class UpdatePromptCommand(PromptCommandBase):
     def end(self):
         pass
 
+    def handle_exception(self, e):
+        return self.owner.EXC_UNHANDLED
+
+    def __repr__(self):
+        if len(self.text) > 127:
+            excerpt = self.text[0:125] + '...'
+        else:
+            excerpt = self.text
+        return "<{cls}: to={to}, title={title}, message={msg}>".format(
+            cls=classname(self), to=self.user, title=self.title, msg=excerpt)
+
 
 
 class SendReplyCommand(CommandBase):
     """ Command to send a private message reply to a user and then mark the
-    original message unread.
+    original message read.
 
     Defaults:
         * ``start_time`` = 0 (immediately)
     def start(self):
         self.log = self.res['logger']
         self.msg.reply(self.text)
+        self.msg.mark_as_read()
         self.log.info("%s: Sent Reddit reply to %s from %s.", classname(self),
-            self.msg.name, self.msg.user)
+            self.msg.author.name, self.res['reddit'].user.name)
 
     def run(self):
         pass
     def end(self):
         pass
 
+    def handle_exception(self, e):
+        return self.owner.EXC_UNHANDLED
+
+    def __repr__(self):
+        if len(self.text) > 127:
+            excerpt = self.text[0:125] + '...'
+        else:
+            excerpt = self.text
+        return "<{cls}: msgid={id_}, to={to}, title={title}, message={msg}>".\
+            format(cls=classname(self), msgid=self.msg.id,
+            to=self.msg.author.name, msg=excerpt)
+
 
 class SendErrorMessageCommand(SendReplyCommand):
     """ Command to send an error message to a user.
                    "sent me. I couldn't understand one of the parameters in "
                    "your command. The error that occurred is:\n\n{error}").\
                    format(error=exc_obj.args[0])
-        return SendErrorMessageCommand(source_msg, subject, body)
+        return SendReplyCommand(source_msg, subject, body)
 
 
 class ListPromptsCommand(CommandBase, DataFormatMixin):
 
         self.msg.reply(self._build_prompt_list(query))
         self.log.info("%s: Sent prompt listing by PM to %s.",
-            classname(self), self.msg.author)
+            classname(self), self.msg.author.name)
 
         self.msg.mark_as_read()
         self.log.debug("%s: Marked message %s as read.",
                 criteria.append(('approver', self.approver))
         return ('<{cls}: message {id_} ({author}), display: {{{disp_args}}}, '
                 'criteria: {{{criteria}}}>').format(
-                cls=classname(self), id_=self.msg.id, author=self.msg.author,
+                cls=classname(self), id_=self.msg.id, author=self.msg.author.name,
                 disp_args=', '.join(['{}: {}'.format(x, repr(y))
                             for x, y in display]),
                 criteria=', '.join(['{}: {}'.format(x, repr(y))
         * ``priority`` = 60
 
     """
+
+    MAX_RETRY = 5
+
     def __init__(self, msg, **kwargs):
         """ Constructor. Keyword arguments are strings defined as per the
         `CheckCommandSpec` class documentation; the text block is expected as
         a 'text' argument. Throws MissingParameterError or CommandParameterError
         on missing or invalid parameters (respectively). """
         self.msg = msg
+        self.tries = 0
 
     def start(self):
-        self.log = self.res['logger']
-        with open('minibot/commands.txt') as help_file:
-            self.msg.reply(help_file.read())
-        self.log.info("%s: Sent help message to",
-            classname(self), self.msg.author)
+        self.tries += 1 # retries related to exceptions being thrown
+        if self.tries <= self.MAX_RETRY:
+            self.log = self.res['logger']
+            with open('minibot/commands.txt') as help_file:
+                self.msg.reply(help_file.read())
+            self.log.info("%s: Sent help message to %s",
+                classname(self), self.msg.author.name)
+        else:
+            self.msg.reply("Can't open help file!")
+            self.log.info("%s: Can't open help file: %s: %s",
+                classname(self), classname(e), e.args[0])
 
     def run(self):
         pass
     def end(self):
         pass
 
+    def handle_exception(self, e):
+        if isinstance(e, IOError) or isinstance(e, OSError):
+            if self.tries <= self.MAX_RETRY:
+                self.delay = 5
+                return self.owner.EXC_HANDLED_RETRY
+            else:
+                return self.owner.EXC_HANDLED_FINAL
+        return self.owner.EXC_UNHANDLED
+
+    def __repr__(self):
+        return "<{cls}: to={to}>".format(
+                cls=classname(self), to=self.msg.author.name)
+
 
 class PostPromptCommand(CommandBase, DataFormatMixin):
     # indirectly inherits: DateParseMixin, MarkdownMixin
             return self.owner.EXC_HANDLED_RETRY
         return self.owner.EXC_UNHANDLED
 
+    def __repr__(self):
+        return "<{cls}: post_id={id_}, post_time={time}>".format(
+                cls=classname(self),
+                id_=self.post_id,
+                time=self.post_time.strftime('%Y-%m-%d %H:%M:%S'))
+
     def _get_title(self):
         """ Return the submission title for the prompt stored in
         ``self.prompt``. """
             return self.owner.EXC_HANDLED_RETRY
         return self.owner.EXC_UNHANDLED
 
+    def __repr__(self):
+        return "<{cls}: post_id={id_}, post_time={time}>".format(
+                cls=classname(self),
+                id_=self.post_id,
+                time=self.post_time.strftime('%Y-%m-%d %H:%M:%S'))
+
     def _get_title(self):
         """ Return the submission title for the thread stored in
         ``self.thread``. """
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.