Commits

Marc-Alexandre Chan  committed 8487ccf

Bugfixes RemovePromptCommand; refactor UpdatePromptCommand

  • Participants
  • Parent commits ca6e723

Comments (0)

Files changed (2)

File minibot/config/localtest/notes.txt

 ev = minibot.events.ListPromptsCommand(msg, **msg_params)
 ev.res = res
 ev.owner = owner
+
+# RemovePromptCommand
+msg_params={'id' : '5'}
+ev = minibot.events.RemovePromptCommand(msg, **msg_params)
+ev.res = res
+ev.owner = owner

File minibot/events.py

             self.msg.mark_as_read()
             self.res['dbsession'].rollback()
             return self.owner.EXC_HANDLED_FINAL
+        elif isinstance(e, SQLAlchemyError) or\
+             isinstance(e, DBAPIError):
+            self.res['dbsession'].rollback()
+            return self.owner.EXC_HANDLED_RETRY
         else:
             self.res['dbsession'].rollback()
             return self.owner.EXC_UNHANDLED
 
     def _check_param_fields(self):
         """ Overriden from PromptCommandBase. """
-        if self.raw_params.get('text', None) is None:
+        if not self.raw_params.get('text', None):
             raise MissingParameterError(
                 "The required text block parameter is missing.")
         return PromptCommandBase._check_param_fields(self)
         self.run()
 
     def run(self):
-        self._run_db()
+        if not self.added:
+            self._run_db()
         self._run_reddit()
 
     def _run_db(self):
+        """ Add the prompt to the DB. Sets self.prompt to the newly-created
+        prompt. """
         # shorthand
         p = self.params
         db = self.res['dbsession']
 
         # guard against re-adding prompt to DB if Reddit errors occur and the
         # event is requeued
-        if not self.added:
-            # first check User table for approver
-            self._make_approver_user(p['r_approver_id'], self.msg.author.name)
+        # first check User table for approver
+        self._make_approver_user(p['r_approver_id'], self.msg.author.name)
 
-            # now make new prompt entry in queue
-            new_prompt = Prompt(
-                                p['title'], p['text'], p['r_approver_id'],
-                                datetime.utcfromtimestamp(self.msg.created_utc),
-                                user=p['user'], user_id=p['r_user_id'],
-                                source_url=p['r_source_url'])
-            new_prompt.queue(p['post_time']) # already in UTC
-            db.add(new_prompt)
-            db.commit()
-            self.added = True
+        # now make new prompt entry in queue
+        self.prompt = new_prompt = Prompt(
+                            p['title'], p['text'], p['r_approver_id'],
+                            datetime.utcfromtimestamp(self.msg.created_utc),
+                            user=p['user'], user_id=p['r_user_id'],
+                            source_url=p['r_source_url'])
+        new_prompt.queue(p['post_time']) # already in UTC
+        db.add(new_prompt)
+        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.debug("%s: Marked message %s as read.",
             classname(self), self.msg.name)
 
         reply_topic = "Prompt added"
         reply_text  = ''.join([
-                        u"Your prompt has been added.\n\n___\n\n",
-                        self._format_prompt(new_prompt)])
+                        u"Your prompt has been added.\n\n",
+                        self._format_prompt(self.prompt)])
         self.owner.queue_event(
             SendReplyCommand(self.msg, reply_topic, reply_text))
 
         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()))
+
     def start(self):
-        # resources
-        reddit = self.res['reddit']
-        db     = self.res['dbsession']
-        self.log = self.res['logger']
+        self.run()
 
-        del_prompt = db.query(Prompt).filter(Prompt.id==self.id).first()
-        if del_prompt is None:
+    def run(self):
+        self._run_db()
+        self._run_reddit()
+
+    def _run_db(self):
+        """ Remove the prompt from the DB. Sets self.prompt to the deleted
+        prompt object. """
+        db = self.res['dbsession']
+        log = self.res['logger']
+
+        self.prompt = db.query(Prompt).filter(Prompt.id==self.id).first()
+        if self.prompt is None:
             raise CommandParameterError(
                 ''.join(["Prompt ", self.id, " not found."]))
-        del_prompt.reject()
+        self.prompt.reject()
+        db.commit()
 
-        self.log.info("%s: Removed prompt '%s' (%d) from database queue.",
-            classname(self), self.title, del_prompt.id)
+        log.info("%s: Removed prompt '%s' (%d) from database queue.",
+                 classname(self), self.prompt.title, self.prompt.id)
 
-        db.commit()
+    def _run_reddit(self):
+        log = self.res['logger']
+
         self.msg.mark_as_read()
+        log.debug("%s: Marked message %s as read.",
+                  classname(self), self.msg.name)
 
-        self.log.debug("%s: Marked message %s as read.",
-                    classname(self), self.msg.name)
-
-        reply_title = ''.join([target_reddit, ": Prompt deleted"])
-        reply_text = u"Prompt {id_:d} has been deleted.\n\n___\n\n{prompt}".\
-            format(id_=del_prompt.id, prompt=self._format_prompt(del_prompt))
-        self.owner.queue_command(
+        reply_title = "Prompt deleted"
+        reply_text = u"Prompt {id_:d} has been deleted.\n\n{prompt}".\
+            format(id_=self.prompt.id, prompt=self._format_prompt(self.prompt))
+        self.owner.queue_event(
             SendReplyCommand(self.msg, reply_title, reply_text))
 
-    def run(self):
-        pass
-
     def end(self):
         self.res['dbsession'].close()
         del self.res['dbsession']
 
+    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)
+
 
 class UpdatePromptCommand(PromptCommandBase):
     """ Command to remove a prompt from the queue.
         * ``start_time`` = 0 (immediately)
         * ``duration`` = 0
         * ``interval`` = 0
-        * ``priority`` = 100
+        * ``priority`` = 49
 
     """
     priority = 49
         `CheckCommandSpec` class documentation; the text block is expected as
         a 'text' argument. Throws MissingParameterError or CommandParameterError
         on missing or invalid parameters (respectively). """
-        PromptCommandBase.__init__(msg, **kwargs)
+        self.updated = False
+        PromptCommandBase.__init__(self, msg, **kwargs)
 
     def _check_param_fields(self):
         """ Overriden from PromptCommandBase. """
         except ValueError, TypeError:
             raise CommandParameterError(
                 "The 'id' parameter is not valid: '{}'.".format(str_id))
-        return PromptCommandBase._check_param_fields()
+        return PromptCommandBase._check_param_fields(self)
 
     def start(self):
         db = self.res['dbsession']
         self.run()
 
     def run(self):
+        if not self.updated:
+            # update in database
+            self._run_db()
+            # remove the prompt from the scheduler queue, if applicable
+            self._check_event_queue()
+        # send reddit confirmation
+        self._run_reddit()
+
+    def _run_db(self):
+        """ Update the prompt in the DB. Relies on the prompt object having been
+        retrieved and set to self.prompt."""
         # shorthand
         db = self.res['dbsession']
         p = self.params
 
         # finalise
         db.commit()
+        self.updated = True
         self.log.info(
             "%s: Updated prompt '%s' (%d) in database queue.",
-            classname(self), self.title, upd_prompt.id)
-        self.log.debug("%s: %s", classname(self), repr(upd_prompt))
+            classname(self), self.title, prompt.id)
+        self.log.debug("%s: %s", classname(self), repr(prompt))
 
-        # and remove the prompt from the scheduler queue, if applicable
-        self._check_event_queue()
+    def _run_reddit(self):
+        prompt = self.prompt
 
         # take care of things reddit-side
         self.msg.mark_as_read()
                     classname(self), self.msg.name)
 
         reply_title = "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(
+        reply_text = u"Prompt {id_:d} has been updated.\n\n{prompt}".\
+            format(id_=prompt.id, prompt=self._format_prompt(prompt))
+        self.owner.queue_event(
             SendReplyCommand(self.msg, reply_title, reply_text))
 
     def _check_event_queue(self):