Browse Source

fix #456: dedicated interrupts phrase

Rafał Pitoń 10 years ago
parent
commit
3135ab5342

+ 2 - 2
docs/developers/posting_process.rst

@@ -99,6 +99,6 @@ When different middlewares add custom fields to ``update_fields`` and set ``upda
 Interrupting posting process from middleware
 ============================================
 
-Middlewares can always interrupt (and rollback) posting process during ``pre_save`` phrase by raising :py:class:`misago.threads.posting.PostingInterrupt` exception with error message as its only argument.
+Middlewares can always interrupt (and rollback) posting process during ``interrupt_posting`` phrase by raising :py:class:`misago.threads.posting.PostingInterrupt` exception with error message as its only argument.
 
-All ``PostingInterrupt`` raised outside that phrase will be escalated to ``ValueError`` that will result in 500 error response from Misago. However as this will happen inside database transaction, there is chance that no data loss has occured during that.
+All ``PostingInterrupt`` raised outside that phrase will be escalated to ``ValueError`` that will result in 500 error response from Misago. However as this will happen inside database transaction, there is chance that this has caused no data loss in process.

+ 13 - 7
misago/threads/posting/__init__.py

@@ -129,8 +129,15 @@ class EditorFormset(object):
     def save(self):
         """change state"""
         forms_dict = self.get_forms_dict()
+        try:
+            for middleware, obj in self.middlewares:
+                obj.pre_save(forms_dict.get(middleware))
+        except PostingInterrupt as e:
+            raise ValueError("Posting process can only be interrupted "
+                             "from within interrupt_posting method")
+
         for middleware, obj in self.middlewares:
-            obj.pre_save(forms_dict.get(middleware))
+            obj.interrupt_posting(forms_dict.get(middleware))
 
         try:
             for middleware, obj in self.middlewares:
@@ -138,12 +145,8 @@ class EditorFormset(object):
             for middleware, obj in self.middlewares:
                 obj.post_save(forms_dict.get(middleware))
         except PostingInterrupt as e:
-            from misago.threads.posting import floodprotection
-            if isinstance(obj, floodprotection.FloodProtectionMiddleware):
-                raise e
-            else:
-                raise ValueError("Posting process can only be "
-                                 "interrupted during pre_save phase")
+            raise ValueError("Posting process can only be interrupted "
+                             "from within interrupt_posting method")
 
     def update(self):
         """handle POST that shouldn't result in state change"""
@@ -169,6 +172,9 @@ class PostingMiddleware(object):
     def pre_save(self, form):
         pass
 
+    def interrupt_posting(self, form):
+        pass
+
     def save(self, form):
         pass
 

+ 2 - 1
misago/threads/posting/floodprotection.py

@@ -8,12 +8,13 @@ MIN_POSTING_PAUSE = 3
 
 
 class FloodProtectionMiddleware(PostingMiddleware):
-    def save(self, form):
+    def interrupt_posting(self, form):
         message = _("You can't post message so quickly after previous one.")
         if self.user.last_post:
             previous_post = timezone.now() - self.user.last_post
             if previous_post.total_seconds() < MIN_POSTING_PAUSE:
                 raise PostingInterrupt(message)
 
+    def post_save(self, form):
         self.user.last_post = timezone.now()
         self.user.update_fields.append('last_post')