1. Marc-Alexandre Chan
  2. DailyPromptBot

Commits

Marc-Alexandre Chan  committed 937cccf

Bugfixes for ListPromptsCommand, some handle_exception() and misc fixes

  • Participants
  • Parent commits 2ea8f08
  • Branches dev-minibot

Comments (0)

Files changed (3)

File minibot/commands.txt

View file
  • Ignore whitespace
 
 * **id**
     Optional. A specific id to search for, or a list of ids to search for
-    (space- or comma-delimited). Overrides all other parameters except
+    (space-delimited). Overrides all other parameters except
     short_entry, by_id and limit.
 * **past**
     Optional. If ``true``, include past prompts. If ``false``, show only

File minibot/events.py

View file
  • Ignore whitespace
         pass
 
     def handle_exception(self, e):
+        self.res['dbsession'].rollback()
         return self.owner.EXC_UNHANDLED
 
 
         self.run()
 
     def run(self):
+        self._run_db()
+        self._run_reddit()
+
+    def _run_db(self):
         # shorthand
         p = self.params
         db = self.res['dbsession']
             db.commit()
             self.added = True
 
-        self.log.info("%s: Added prompt '%s' (%d) to database queue.",
-            classname(self), p['title'], new_prompt.id)
-        self.log.debug("%s: %s", classname(self), repr(new_prompt))
+            self.log.info("%s: Added prompt '%s' (%d) to database queue.",
+                classname(self), p['title'], new_prompt.id)
+            self.log.debug("%s: %s", classname(self), repr(new_prompt))
+
+    def _run_reddit(self):
+        # shorthand
+        p = self.params
+        db = self.res['dbsession']
 
         self.msg.mark_as_read()
-        self.log.info("%s: Marked message %s as read.",
+        self.log.debug("%s: Marked message %s as read.",
             classname(self), self.msg.name)
 
         reply_topic = "Prompt added"
             SendReplyCommand(self.msg, reply_topic, reply_text))
 
 
-
 class RemovePromptCommand(CommandBase, DataFormatMixin):
     """ Command to remove a prompt from the queue.
 
         db.commit()
         self.msg.mark_as_read()
 
-        self.log.info("%s: Marked message %s as read.",
+        self.log.debug("%s: Marked message %s as read.",
                     classname(self), self.msg.name)
 
         reply_title = ''.join([target_reddit, ": Prompt deleted"])
 
         # take care of things reddit-side
         self.msg.mark_as_read()
-        self.log.info("%s: Marked message %s as read.",
+        self.log.debug("%s: Marked message %s as read.",
                     classname(self), self.msg.name)
 
         reply_title = "Prompt updated"
         return SendErrorMessageCommand(source_msg, subject, body)
 
 
-class ListPromptsCommand(CommandBase, MarkdownMixin, DateParseMixin):
+class ListPromptsCommand(CommandBase, DataFormatMixin):
+    # MarkdownMixin, DateParseMixing via DataFormatMixin
     """ Command to send a list of prompts to a user via PM.
 
     Defaults:
 
     """
 
-    SHORT_TEXT_LENGTH = 100
     MAX_ENTRIES = 30
     start_time = 0 # execute ASAP
     priority = 60
 
         self.msg = msg
 
-        s_ids = kwargs.get('id', None)
-        s_past = kwargs.get('past', None)
-        s_start_date = kwargs.get('start_date', None)
-        s_end_date = kwargs.get('end_date', None)
-        s_user = kwargs.get('user', None)
-        s_approver = kwargs.get('approver', None)
-        s_short_entry = kwargs.get('short_entry', None)
-        s_by_id = kwargs.get('by_id', None)
-        s_limit = kwargs.get('limit', None)
+        s_ids = kwargs.pop('id', None)
+        s_past = kwargs.pop('past', None)
+        s_start_date = kwargs.pop('start_date', None)
+        s_end_date = kwargs.pop('end_date', None)
+        s_user = kwargs.pop('user', None)
+        s_approver = kwargs.pop('approver', None)
+        s_short_entry = kwargs.pop('short_entry', None)
+        s_by_id = kwargs.pop('by_id', None)
+        s_limit = kwargs.pop('limit', None)
 
         # if parameters left over, they're not valid
         if len(kwargs):
             if len(kwargs) == 1:
                 raise CommandParameterError(
-                    "Unknown parameter: '" + kwargs.keys()[0])
+                    "Unknown parameter: " + kwargs.keys()[0])
             else:
                 raise CommandParameterError(
-                    "Unknown parameters: '" + ', '.join(kwargs.keys()))
+                    "Unknown parameters: " + ', '.join(kwargs.keys()))
 
         self.ids = None
 
             self.approver = s_approver
 
         self.short_entry = (s_short_entry.lower() == 'true') if\
-                s_short_entry is not None else True
-        self.by_id = (by_id.lower() == 'true') if\
-                by_id is not None else False
+                s_short_entry else True
+        self.by_id = (s_by_id.lower() == 'true') if\
+                s_by_id else False
 
         if s_limit is not None:
             try:
                 raise CommandParameterError("Invalid 'limit' value: " + s_limit)
         else:
             par_limit = self.MAX_ENTRIES
+        # bracket 'limit' to between 1 and self.MAX_ENTRIES
         self.limit = max(1, min(self.MAX_ENTRIES, par_limit))
 
     def start(self):
+        self.run()
+
+    def run(self):
         self.log = self.res['logger']
+        query = self._run_query()
+
+        self.msg.reply(self._build_prompt_list(query))
+        self.log.info("%s: Sent prompt listing by PM to %s.",
+            classname(self), self.msg.author)
+
+        self.msg.mark_as_read()
+        self.log.debug("%s: Marked message %s as read.",
+            classname(self), self.msg.name)
+
+    def _run_query(self):
+        """ Return a Query object for the query configured. """
         query = self.res['dbsession'].query(Prompt)
 
         if self.ids:
             if self.user is not None:
                 query = query.filter(Prompt.user == self.user)
             if self.approver is not None:
-                query = query.filter(Prompt.approver.uname == self.approver)
+                query = query.join(User).filter(User.uname == self.approver)
 
         if not self.by_id:
             query = query.order_by(Prompt.post_time)
         else:
             query = query.order_by(Prompt.id)
+        return query
 
-        prompt_list = [self._header_prompt(self.short_entry)]
+    def _build_prompt_list(self, query):
+        """ Return a string containing the prompt listing. """
+        prompt_listing = [self._header_prompt(self.short_entry)]
         prompt_ids = []
         has_prompt = False
 
         for prompt in query[0:self.limit]:
             has_prompt = True
-            prompt_list.append(self._format_prompt(prompt, self.short_entry))
+            prompt_listing.append(self._format_prompt(prompt, self.short_entry))
             prompt_ids.append(prompt.id)
 
-        if not has_prompt:
-            prompt_list = ["No results found."]
+        if has_prompt:
+            self.log.debug("%s: Found prompts: %s", classname(self),
+                ', '.join(['{:d}'.format(i) for i in prompt_ids]))
+        else:
+            self.log.debug("%s: No prompts found.", classname(self))
+            prompt_listing = ["No results found."]
 
         if self.short_entry: # no newlines between entries
-            self.msg.reply(u''.join(prompt_list))
+            return u''.join(prompt_listing)
         else: # long list = newlines between entries
-            self.msg.reply(u'\n'.join(prompt_list))
-
-        self.log.info("%s: Sent PM list to %s for prompts %s.",
-            classname(self), self.msg.author, ', '.join(prompt_ids))
-
-        self.msg.mark_as_read()
-        self.log.info("%s: Marked message %s as read.",
-            classname(self), self.msg.name)
-
-    def run(self):
-        pass
+            return u'\n'.join(prompt_listing)
 
     def end(self):
         pass
 
+    def handle_exception(self, e):
+        self.res['dbsession'].rollback()
+        return self.owner.EXC_UNHANDLED
+
     def _format_url(self, post_id):
         """ Overrides ``DataFormatMixin._format_url()``. """
         return get_reddit_url(post_id, self.res['reddit'])
 
+    def __repr__(self):
+        """ Return a string representing this object. """
+        display = [('short_entry', self.short_entry),
+                   ('by_id',       self.by_id),
+                   ('limit',       self.limit)]
+        if self.ids:
+            criteria = [('ids', self.ids)]
+        else:
+            criteria = [('past', self.past)]
+            if self.start_date is not None:
+                criteria.append(('start_date', self.start_date))
+            if self.end_date is not None:
+                criteria.append(('end_date', self.end_date))
+            if self.user is not None:
+                criteria.append(('user', self.user))
+            if self.approver is not None:
+                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,
+                disp_args=', '.join(['{}: {}'.format(x, repr(y))
+                            for x, y in display]),
+                criteria=', '.join(['{}: {}'.format(x, repr(y))
+                            for x, y in criteria]))
+
 
 class SendHelpMessageCommand(SendReplyCommand):
     """ Command to send a help message.

File minibot/util.py

View file
  • Ignore whitespace
             return u''.join(['|', '|'.join(header[0]), '|\n',
                             '|'.join(header[1]), '|\n'])
         else:
-            return u"# PROMPT LISTING\n___\n"
+            return u"# PROMPT LISTING\n"
 
     def _format_url(self, post_id):
         """ Return a Reddit link for a given post ID.  This defaults to
                             self._localtime(prompt.submit_time).\
                             strftime('%Y-%m-%d %H:%M:%S'))
             # submitter
-            if prompt.r_source_url:
+            if prompt.r_source_url and prompt.user is not None:
                 str_data.append(self.md_link(
                     prompt.user, prompt.r_source_url))
+            elif prompt.r_source_url:
+                str_data.append(self.md_link(
+                    prompt.r_source_url, prompt.r_source_url))
+            elif prompt.user:
+                str_data.append(prompt.user)
             else:
-                str_data.append(prompt.user)
+                str_data.append('')
             # approver
             str_data.append(prompt.approver.uname)
             # text
         if prompt is not None:
             str_data = []
             # ID
+            str_data.append('___\n\n')
             str_data.append(u' '.join(
-                [u'#', unicode(prompt.id), prompt.title]))
-            str_data.append('\n')
+                [u'##', unicode(prompt.id), prompt.title]))
+            str_data.append(u'\n\n')
             # status
-            str_data.append(u'Status: ')
+            str_data.append(u'|Status|')
             if prompt.status == prompt.STATUS_POSTED:
                 str_data.append(self.md_link(
                     prompt.get_status_string(),
                     self._format_url(prompt.r_post_id)))
             else:
                 str_data.append(prompt.get_status_string())
-            str_data.append(u'\n')
+            str_data.append(u'|\n')
+            str_data.append(u'|:-|:-|\n')
             # Post time
-            str_data.append(u''.join([u'Post time: ',
+            str_data.append(u''.join([u'|Post time|',
                             self._localtime(prompt.post_time).\
-                            strftime('%Y-%m-%d %H:%M:%S'), u'\n']))
+                            strftime('%Y-%m-%d %H:%M:%S'), u'|\n']))
             # submit time
-            str_data.append(u''.join([u'Submit time: ',
+            str_data.append(u''.join([u'|Submit time|',
                             self._localtime(prompt.submit_time).\
-                            strftime('%Y-%m-%d %H:%M:%S'), u'\n']))
+                            strftime('%Y-%m-%d %H:%M:%S'), u'|\n']))
             # submitter
-            str_data.append(u'Submitter: ')
-            if prompt.r_source_url:
+            str_data.append(u'|Submitter|')
+            if prompt.r_source_url and prompt.user is not None:
                 str_data.append(self.md_link(
                     prompt.user, prompt.r_source_url))
+            elif prompt.r_source_url:
+                str_data.append(self.md_link(
+                    prompt.r_source_url, prompt.r_source_url))
+            elif prompt.user:
+                str_data.append(prompt.user)
             else:
-                str_data.append(prompt.user)
-            str_data.append(u'\n')
+                str_data.append('')
+            str_data.append(u'|\n')
             # approver
             str_data.append(
-                ''.join(['Approver: ', prompt.approver.uname, u'\n']))
+                ''.join(['|Approver|', prompt.approver.uname, u'|\n']))
             # text
             str_data.append(u'\n')
             str_data.append(prompt.text)
+            str_data.append(u'\n')
             # final newline
             str_data.append(u'\n')