pass pk and model_dict to deleter, dynamic load of deleters
diff --git a/planetstack/core/models/plcorebase.py b/planetstack/core/models/plcorebase.py
index 94c3d5a..590e240 100644
--- a/planetstack/core/models/plcorebase.py
+++ b/planetstack/core/models/plcorebase.py
@@ -2,6 +2,7 @@
from django.db import models
from django.forms.models import model_to_dict
from django.core.urlresolvers import reverse
+from django.forms.models import model_to_dict
# This is a no-op if observer_disabled is set to 1 in the config file
from observer import *
@@ -38,10 +39,17 @@
return self.diff.get(field_name, None)
def delete(self, *args, **kwds):
+ # so we have something to give the observer
+ pk = self.pk
+ model_dict = model_to_dict(self)
+ for (k,v) in model_dict.items():
+ # things like datetime are not JSON serializable
+ model_dict[k] = str(v)
+
super(PlCoreBase, self).delete(*args, **kwds)
# This is a no-op if observer_disabled is set
- notify_observer(model=self, delete=True, pk=self.pk)
+ notify_observer(model=self, delete=True, pk=pk, model_dict=model_dict)
def save(self, *args, **kwargs):
super(PlCoreBase, self).save(*args, **kwargs)
diff --git a/planetstack/observer/__init__.py b/planetstack/observer/__init__.py
index e2a93de..0d6c550 100644
--- a/planetstack/observer/__init__.py
+++ b/planetstack/observer/__init__.py
@@ -10,14 +10,14 @@
if (not observer_disabled):
from .event_manager import EventSender
- def notify_observer(model=None, delete=False, pk=None):
+ def notify_observer(model=None, delete=False, pk=None, model_dict={}):
try:
if (model and delete):
if hasattr(model,"__name__"):
modelName = model.__name__
else:
modelName = model.__class__.__name__
- EventSender().fire(delete_flag = delete, model = modelName, pk = pk)
+ EventSender().fire(delete_flag = delete, model = modelName, pk = pk, model_dict=model_dict)
else:
EventSender().fire()
except Exception,e:
diff --git a/planetstack/observer/deleter.py b/planetstack/observer/deleter.py
index 9a62ccd..e088558 100644
--- a/planetstack/observer/deleter.py
+++ b/planetstack/observer/deleter.py
@@ -5,9 +5,12 @@
class Deleter:
model=None # Must be overridden
- def call(self,pk):
+ def __init__(self, *args, **kwargs):
+ pass
+
+ def call(self, pk, model_dict):
# Fetch object from PlanetStack db and delete it
pass
- def __call__(self):
- return self.call()
+ def __call__(self, *args, **kwargs):
+ return self.call(*args, **kwargs)
diff --git a/planetstack/observer/event_manager.py b/planetstack/observer/event_manager.py
index 8ec3fc2..112564a 100644
--- a/planetstack/observer/event_manager.py
+++ b/planetstack/observer/event_manager.py
@@ -2,13 +2,16 @@
import requests, json
from planetstack.config import Config
-from observer.deleters import deleters
+from observer.deleter import Deleter
import uuid
import os
+import imp
+import inspect
import base64
from fofum import Fofum
import json
+import traceback
# decorator that marks dispatachable event methods
def event(func):
@@ -52,29 +55,61 @@
def fire(self,**kwargs):
kwargs["uuid"] = str(uuid.uuid1())
- print "YYY fire", kwargs
self.fofum.fire(json.dumps(kwargs))
class EventListener:
def __init__(self,wake_up=None):
self.handler = EventHandler()
self.wake_up = wake_up
+ self.deleters = {}
+ self.load_deleter_modules()
+
+ def load_deleter_modules(self, deleter_dir=None):
+ if deleter_dir is None:
+ if hasattr(Config(), "observer_deleters_dir"):
+ deleter_dir = Config().observer_deleters_dir
+ else:
+ deleter_dir = "/opt/planetstack/observer/deleters"
+
+ for fn in os.listdir(deleter_dir):
+ pathname = os.path.join(deleter_dir,fn)
+ if os.path.isfile(pathname) and fn.endswith(".py") and (fn!="__init__.py"):
+ module = imp.load_source(fn[:-3],pathname)
+ for classname in dir(module):
+ c = getattr(module, classname, None)
+
+ # make sure 'c' is a descendent of Deleter and has a
+ # provides field (this eliminates the abstract base classes
+ # since they don't have a provides)
+
+ if inspect.isclass(c) and issubclass(c, Deleter) and hasattr(c,"model") and c.model!=None:
+ modelName = c.model
+ if not modelName in self.deleters:
+ self.deleters[modelName] = []
+ if not (c in self.deleters[modelName]):
+ self.deleters[modelName].append(c)
+ print 'loaded deleters: %s' % ",".join(self.deleters.keys())
+
def handle_event(self, payload):
payload_dict = json.loads(payload)
try:
deletion = payload_dict.get('delete_flag', False)
- print "XXX", payload_dict, deletion
if (deletion):
model = payload_dict['model']
pk = payload_dict['pk']
+ model_dict = payload_dict['model_dict']
- print "XXX", model, pk, deleters
+ for deleter in self.deleters[model]:
+ try:
+ deleter()(pk, model_dict)
+ except:
+ # something is silently eating these
+ # exceptions...
+ traceback.print_exc()
+ raise
- for deleter in deleters[model]:
- print "ZZZ executing deleter"
- deleter(pk)
except:
deletion = False