# HG changeset patch # User Peter Sanchez # Date 1308928455 25200 # Fri Jun 24 08:14:15 2011 -0700 # Node ID 1288e06c26e7138261501d81a410106eef9d4f9a # Parent 0fb7fc65d81c7bc9f8d1546d65f6ded77c5ef94c Adding more to the callback manager, model, and some management commands diff --git a/callback/__init__.py b/callback/__init__.py --- a/callback/__init__.py +++ b/callback/__init__.py @@ -1,5 +1,7 @@ from callback import callback_manager from base import CallbackException, CallbackBase +from callback import callback_manager __version__ = '0.1' +__all__ = ['CallbackException', 'CallbackBase', 'callback_manager'] diff --git a/callback/callback.py b/callback/callback.py --- a/callback/callback.py +++ b/callback/callback.py @@ -2,11 +2,21 @@ from models import CallbackMap from base import CallbackException, CallbackBase +REQUIRED_METHODS = ('process',) + class CallbackManager(object): def __init__(self): self._callbacks = {} + def self.validate_methods(self, cls): + for method in REQUIRED_METHODS: + if not hasattr(cls, method): + raise CallbackException( + 'Cannot register class - does not contain ' + '%s method' % method + ) + def register_callback(self, dest_model, dest_cls): if not issubclass(dest_model, models.Model): raise CallbackException( @@ -15,9 +25,11 @@ ) if not issubclass(dest_cls, CallbackBase): raise CallbackException( - 'Cannot register class - not a subclass of CallbackBase' + 'Cannot register class - not a subclass of ' + 'callback.CallbackBase' ) + self.validate_methods(dest_cls) self._callbacks[dest_model] = dest_cls def unregister_callback(self, dest_model): @@ -41,11 +53,9 @@ cls = self.get_callback_class(model) try: cls.process(model) - except: - # Do something here - raise CallbackException( - 'Error!!!' - ) + except Exception, e: + callback_instance.mark_error(str(e)) + raise CallbackException(str(e)) callback_manager = CallbackManager() diff --git a/callback/management/__init__.py b/callback/management/__init__.py new file mode 100644 diff --git a/callback/management/commands/__init__.py b/callback/management/commands/__init__.py new file mode 100644 diff --git a/callback/management/commands/run_callbacks.py b/callback/management/commands/run_callbacks.py new file mode 100644 --- /dev/null +++ b/callback/management/commands/run_callbacks.py @@ -0,0 +1,12 @@ +from django.conf import settings +from django.core.management.base import BaseCommand +from callback import callback_manager +from callback.models import CallbackMap + + +class Command(BaseCommand): + help = 'Process all pending callbacks' + + def handle(self, *args, **kwargs): + for callback in CallbackMap.objects.all_live_callbacks(): + callback_manager.process_callback(callback) diff --git a/callback/managers.py b/callback/managers.py --- a/callback/managers.py +++ b/callback/managers.py @@ -3,6 +3,8 @@ from django.db import models from django.contrib.auth.models import User +Q = models.Q + class CallbackMapManager(models.Manager): def generate_hash(self): @@ -15,3 +17,7 @@ while self.get_query_set().filter(hash_id=hash_id).exists(): hash_id = self.generate_hash() return self.create(hash_id=hash_id, content_object=model_instance) + + def all_live_callbacks(self): + query = Q(is_active=True) & Q(is_error=False) + return self.get_query_set().filter(query) diff --git a/callback/models.py b/callback/models.py --- a/callback/models.py +++ b/callback/models.py @@ -11,12 +11,28 @@ object_id = models.PositiveIntegerField() content_object = generic.GenericForeignKey('content_type', 'object_id') + is_active = models.BooleanField(default=True) + + is_error = models.BooleanField(default=False) + error_msg = models.TextField(blank=True) + created_on = models.DateTimeField(default=datetime.datetime.now) updated_on = models.DateTimeField(default=datetime.datetime.now) objects = CallbackMapManager() # Methods + def mark_error(self, msg): + self.is_active = False + self.is_error = True + self.error_msg = msg + self.save() + + def mark_active(self): + self.is_active = True + self.is_error = False + self.save() + def save(self, *args, **kwargs): if self.id: self.updated_on = datetime.datetime.now()