blob: bd04cedfe9269d72e244a8092e615e041665ad38 [file] [log] [blame]
import threading
import requests, json
from planetstack.config import Config
from observer.deleter import Deleter
import uuid
import os
import imp
import inspect
import base64
from fofum import Fofum
import json
import traceback
random_client_id=None
def get_random_client_id():
global random_client_id
if (random_client_id is None) and os.path.exists("/opt/planetstack/random_client_id"):
# try to use the last one we used, if we saved it
try:
random_client_id = open("/opt/planetstack/random_client_id","r").readline().strip()
print "get_random_client_id: loaded %s" % random_client_id
except:
print "get_random_client_id: failed to read /opt/planetstack/random_client_id"
if random_client_id is None:
random_client_id = base64.urlsafe_b64encode(os.urandom(12))
print "get_random_client_id: generated new id %s" % random_client_id
# try to save it for later (XXX: could race with another client here)
try:
open("/opt/planetstack/random_client_id","w").write("%s\n" % random_client_id)
except:
print "get_random_client_id: failed to write /opt/planetstack/random_client_id"
return random_client_id
# decorator that marks dispatachable event methods
def event(func):
setattr(func, 'event', func.__name__)
return func
class EventHandler:
# This code is currently not in use.
def __init__(self):
pass
@staticmethod
def get_events():
events = []
for name in dir(EventHandler):
attribute = getattr(EventHandler, name)
if hasattr(attribute, 'event'):
events.append(getattr(attribute, 'event'))
return events
def dispatch(self, event, *args, **kwds):
if hasattr(self, event):
return getattr(self, event)(*args, **kwds)
class EventSender:
def __init__(self,user=None,clientid=None):
try:
user = Config().feefie_client_user
except:
user = 'pl'
try:
clid = Config().feefie_client_id
except:
clid = get_random_client_id()
print "EventSender: no feefie_client_id configured. Using random id %s" % clid
self.fofum = Fofum(user=user)
self.fofum.make(clid)
def fire(self,**kwargs):
kwargs["uuid"] = str(uuid.uuid1())
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)
if (deletion):
model = payload_dict['model']
pk = payload_dict['pk']
model_dict = payload_dict['model_dict']
for deleter in self.deleters[model]:
try:
deleter()(pk, model_dict)
except:
# something is silently eating these
# exceptions...
traceback.print_exc()
raise
except:
deletion = False
if (not deletion and self.wake_up):
self.wake_up()
def run(self):
# This is our unique client id, to be used when firing and receiving events
# It needs to be generated once and placed in the config file
try:
user = Config().feefie_client_user
except:
user = 'pl'
try:
clid = Config().feefie_client_id
except:
clid = get_random_client_id()
print "EventListener: no feefie_client_id configured. Using random id %s" % clid
f = Fofum(user=user)
listener_thread = threading.Thread(target=f.listen_for_event,args=(clid,self.handle_event))
listener_thread.start()