Commits

Marc-Alexandre Chan committed d15d963

Completed prompt info output overhaul, SuggestionThread text navigation button

  • Participants
  • Parent commits 8874ee6

Comments (0)

Files changed (3)

 
     base
         A reference to the declarative base.
+
     """
     def __init__(self, dbfile='minibot.sqlite', **kwargs):
         """ Constructor. Set up parameters, engine, base, and logging.
             *Default: None*
 
             Table prefix. String to prepend to every table name in the database.
-            """
+
+        """
         # declaration  of instance attributes
         # objects/components
         self.engine      = None

minibot/events.py

 
 from sqlalchemy.sql import desc
 
-from datetime import datetime
+from datetime import datetime, timedelta, time as dt_time, date as dt_date
 from datetime import timedelta
 from calendar import timegm
 from urlparse import urlparse
 
 # TODO: logging
-# TODO: move format methods to the Prompt class, + get_url methods for submissions
-# TODO: fix prompt info output reply on Add/Update/???
 # TODO: error handling
 
 # this is in all superscript (renders equiv. small text) ^(syntax is like this)
         pass
 
 
-class AddPromptCommand(CommandBase, DateParseMixin):
+class AddPromptCommand(CommandBase, DateParseMixin, DataFormatMixin):
     """ Command to add a prompt to the queue.
 
     Defaults:
 
         self.msg.mark_as_read()
 
-        # TODO: Fix output of prompt info - move format entry methods to mixin?
-        self.owner.queue_command(SendReplyCommand(
-                self.msg, target_reddit + ": Prompt added",
-                u"Your prompt has been added.\n\n" + unicode(new_prompt)))
+        reply_topic = ''.join([target_reddit, ": Prompt added"])
+        reply_text  = ''.join([
+                        u"Your prompt has been added.\n\n___\n\n",
+                        self._format_prompt(new_prompt)])
+        self.owner.queue_command(
+            SendReplyCommand(self.msg, reply_topic, reply_text))
 
     def run(self):
         pass
         return current_date
 
 
-class RemovePromptCommand(CommandBase):
+class RemovePromptCommand(CommandBase, DataParseMixin):
     """ Command to remove a prompt from the queue.
 
     Defaults:
         db.commit()
         self.msg.mark_as_read()
 
-        # TODO: Fix output of prompt info - move format entry methods to mixin?
-        self.owner.queue_command(SendReplyCommand(
-                self.msg, target_reddit + ": Prompt deleted",
-                u"Prompt {:d} has been deleted.\n\n".format(upd_prompt.id) +
-                unicode(new_prompt)))
+        reply_title = ''.join([target_reddit, ": Prompt deleted"])
+        reply_text = u"Prompt {id_:d} has been deleted.\n\n___\n\n{prompt}".\
+            format(id_=upd_prompt.id, prompt=self._format_prompt(del_prompt))
+        self.owner.queue_command(
+            SendReplyCommand(self.msg, reply_title, reply_text))
 
     def run(self):
         pass
 
         self.msg.mark_as_read()
 
-        # TODO: Fix output of prompt info - move format entry methods to mixin?
-        self.owner.queue_command(SendReplyCommand(
-                self.msg, target_reddit + ": Prompt updated",
-                u"Prompt {:d} has been updated.\n\n".format(upd_prompt.id) +
-                unicode(new_prompt)))
+        reply_title = ''.join([target_reddit, ": Prompt updated"])
+        reply_text = u"Prompt {id_:d} has been updated.\n\n___\n\n{prompt}".\
+            format(id_=upd_prompt.id, prompt=self._format_prompt(upd_prompt))
+        self.owner.queue_command(
+            SendReplyCommand(self.msg, reply_title, reply_text))
 
     def run(self):
         pass
 
     def _format_url(self, post_id):
         """ Overrides ``DataFormatMixin._format_url()``. """
-        reddit = self.res['reddit']
-        return ''.join(['http://', reddit.config.domain, '/', post_id])
+        return _get_reddit_url(post_id, self.res['reddit'])
 
 
 class SendHelpMessageCommand(SendReplyCommand):
         return ' '.join(text_parts)
 
 
-class PostSuggestionThreadCommand(CommandBase):
+class PostSuggestionThreadCommand(CommandBase, MarkdownMixin):
     """ Command to post a suggestions thread.
 
     Defaults:
                 "and queue them up for next week or beyond.\n\n"
                 "{text}\n\n"
                 "Please try to avoid repeating suggestions that were already "
-                "posted in the last few weekswe probably already read it "
+                "posted in the last few weeks—we probably already read it "
                 "and either didn't find it interesting enough to post or liked "
                 "it enough to queue it up later on!")
-    NAV_MENU = ("| Previous | Current | Next |\n"
-                "|:--------:|:-------:|:----:|\n"
-                "| {prev_date} | {cur_date} | {next_date}|")
+    NAV_MENU = (u"| | | |\n"
+                u"| :-: | :-: | :-: |\n"
+                u"| {prev} | {cur} | {next} |\n"
+                u"| | | |\n")
 
     required_res = ['reddit', 'dbsession', 'config.reddit']
-    # self.post_time, self.post_id
     def __init__(self, post_id, post_time):
         """ Constructor. Throws MissingParameterError or CommandParameterError
         on missing or invalid parameters (respectively). """
         db = self.res['dbsession']
 
         thread = self.thread = db.query(SuggestionThread).get(self.post_id)
+        self.prev_thread = self._find_prev_thread()
         if thread is None:
             raise CommandParameterError(
                 ''.join(["Queued suggestion thread ", self.id, " not found."]))
 
     def end(self):
         self.res['dbsession'].close()
-        del se.fres['dbsession']
+        del self.res['dbsession']
 
     def _get_title(self):
         """ Return the submission title for the thread stored in
     def _get_text(self):
         """ Return the submission text for the thread stored in
         ``self.thread``. """
-        text = self.BODY_TEXT.format(
+        prev_date_str = (self.post_time.date() - timedelta(days=7)).\
+                        strftime('%d %B %Y')
+        curr_date_str = self.post_time.date().strftime('%d %B %Y')
+        next_date_str = (self.post_time.date() + timedelta(days=7)).\
+                        strftime('%d %B %Y')
+
+        if self.prev_thread is not None and\
+                self.prev_thread.r_post_id is not None:
+            prev_url = _get_reddit_url(self.prev_thread.r_post_id, reddit)
+            prev_text = self.md_link(prev_date_str, prev_url)
+
+        text = ''.join([
+                self.BODY_TEXT.format(
                     date_=self._str_date,
-                    text=self.thread.text if self.thread.text else '')
-        text += '\n___\n' + _BOT_MSG
+                    text=self.thread.text if self.thread.text else ''),
+                self.NAV_MENU.format(
+                    prev=prev_text,
+                    cur=self.md_bold(curr_date_str),
+                    next=next_date_str),
+                '\n___\n', _BOT_MSG])
         return text
-        # TODO: the previous/next week navigational menu
+
+    def _find_prev_thread(self):
+        """ Find the previous week's SuggestionThread. If none found, returns
+        None. This method queries the database; it should be called in start()
+        and its result stored in the ``prev_thread`` attribute. """
+        db = self.res['dbsession']
+        prev_date = self.post_time.date() - timedelta(days=7)
+        prev_start = datetime.combine(prev_date, dt_time())
+        prev_end = datetime.combine(prev_date + timedelta(days=1), dt_time())
+        thread = db.query(SuggestionThread).\
+                    filter(SuggestionThread.time >= prev_start).\
+                    filter(SuggestionThread.time < prev_end).\
+                    order_by(SuggestionThread.time).limit(1).first()
+        return thread
 
     def _archive_older_threads(self):
         """ Sets all older active threads to archived status in database. Does
     def _add_link_to_last_thread(self):
         """ Adds a 'next week's suggestion thread' link to the previous
         suggestion thread. """
-        return # TODO
+        if self.prev_thread is not None:
+            curr_date_str = self.post_time.date().strftime('%d %B %Y')
+            post_url = _get_reddit_url(
+                                        self.prev_thread.r_post_id,
+                                        self.res['reddit'])
+             self.prev_thread.text.replace(
+                ' '.join(['|', curr_date_str, '|']),
+                ' '.join(['|', self.md_link(curr_date_str, post_url), '|')])
+
+
+def _get_reddit_url(id, reddit):
+    """ Returns the URL to a reddit submission, given the submission id and a
+    Reddit API object. """
+    return ''.join(['http://', reddit.config.domain, '/', id])
 
 
 CheckMessageEvent.cmd_actions = {'add'    : AddPromptCommand,
 
 class DataFormatMixin(object, MarkdownMixin):
     """ Mixin for formatting database data in human-readable format. """
-    def _format_prompt(self, prompt, short=None):
+    def _format_prompt(self, prompt, short=False):
         """ Format a prompt for listing. If ``short`` is true, the tabular
         format is returned; if ``short`` is false, a full listing is returned.
         The returned string is ended by a single newline. If ``short`` is True