blob: 1d94f589e923582939033759b512c3a1e125ac0b [file] [log] [blame]
Tony Mack79a49c82013-06-15 23:51:57 -04001import threading
2import requests, json
Sapan Bhatia66f4e612013-07-02 12:12:38 -04003
Sapan Bhatia66f4e612013-07-02 12:12:38 -04004from planetstack.config import Config
Scott Baker6ecd4262014-01-21 23:15:21 -08005from observer.deleter import Deleter
Tony Mack79a49c82013-06-15 23:51:57 -04006
Scott Bakerc1c45f82014-01-21 16:23:51 -08007import uuid
Sapan Bhatia9182b322013-06-25 16:22:14 -04008import os
Scott Baker6ecd4262014-01-21 23:15:21 -08009import imp
10import inspect
Sapan Bhatia9182b322013-06-25 16:22:14 -040011import base64
Tony Mack5c0c4552013-07-03 09:36:51 -040012from fofum import Fofum
Sapan Bhatiadbaf1932013-09-03 11:28:52 -040013import json
Scott Baker6ecd4262014-01-21 23:15:21 -080014import traceback
Sapan Bhatia9182b322013-06-25 16:22:14 -040015
Sapan Bhatia9faf7b02013-10-09 10:27:14 -040016# decorator that marks dispatachable event methods
Tony Mack79a49c82013-06-15 23:51:57 -040017def event(func):
Sapan Bhatia9faf7b02013-10-09 10:27:14 -040018 setattr(func, 'event', func.__name__)
19 return func
Tony Mack79a49c82013-06-15 23:51:57 -040020
21class EventHandler:
Sapan Bhatia9faf7b02013-10-09 10:27:14 -040022 # This code is currently not in use.
23 def __init__(self):
24 pass
Tony Mack79a49c82013-06-15 23:51:57 -040025
Sapan Bhatia9faf7b02013-10-09 10:27:14 -040026 @staticmethod
27 def get_events():
28 events = []
29 for name in dir(EventHandler):
30 attribute = getattr(EventHandler, name)
31 if hasattr(attribute, 'event'):
32 events.append(getattr(attribute, 'event'))
33 return events
Tony Mack79a49c82013-06-15 23:51:57 -040034
Sapan Bhatia9faf7b02013-10-09 10:27:14 -040035 def dispatch(self, event, *args, **kwds):
36 if hasattr(self, event):
37 return getattr(self, event)(*args, **kwds)
38
39
Sapan Bhatia66f4e612013-07-02 12:12:38 -040040class EventSender:
Sapan Bhatia9faf7b02013-10-09 10:27:14 -040041 def __init__(self,user=None,clientid=None):
42 try:
43 user = Config().feefie_client_user
44 except:
45 user = 'pl'
Sapan Bhatia66f4e612013-07-02 12:12:38 -040046
Sapan Bhatia9faf7b02013-10-09 10:27:14 -040047 try:
48 clid = Config().feefie_client_id
49 except:
50 clid = self.random_client_id()
51
Sapan Bhatia66f4e612013-07-02 12:12:38 -040052
Sapan Bhatia9faf7b02013-10-09 10:27:14 -040053 self.fofum = Fofum(user=user)
54 self.fofum.make(clid)
55
Scott Bakerc1c45f82014-01-21 16:23:51 -080056 def fire(self,**kwargs):
57 kwargs["uuid"] = str(uuid.uuid1())
Scott Bakerc1c45f82014-01-21 16:23:51 -080058 self.fofum.fire(json.dumps(kwargs))
Tony Mack79a49c82013-06-15 23:51:57 -040059
Scott Bakeraacc5c62014-05-12 17:00:11 -070060 def random_client_id(self):
61 try:
62 return self.client_id
63 except AttributeError:
64 self.client_id = base64.urlsafe_b64encode(os.urandom(12))
65 return self.client_id
66
Tony Mack79a49c82013-06-15 23:51:57 -040067class EventListener:
Sapan Bhatia9faf7b02013-10-09 10:27:14 -040068 def __init__(self,wake_up=None):
69 self.handler = EventHandler()
70 self.wake_up = wake_up
Scott Baker6ecd4262014-01-21 23:15:21 -080071 self.deleters = {}
72 self.load_deleter_modules()
73
74 def load_deleter_modules(self, deleter_dir=None):
75 if deleter_dir is None:
76 if hasattr(Config(), "observer_deleters_dir"):
77 deleter_dir = Config().observer_deleters_dir
78 else:
79 deleter_dir = "/opt/planetstack/observer/deleters"
80
81 for fn in os.listdir(deleter_dir):
82 pathname = os.path.join(deleter_dir,fn)
83 if os.path.isfile(pathname) and fn.endswith(".py") and (fn!="__init__.py"):
84 module = imp.load_source(fn[:-3],pathname)
85 for classname in dir(module):
86 c = getattr(module, classname, None)
87
88 # make sure 'c' is a descendent of Deleter and has a
89 # provides field (this eliminates the abstract base classes
90 # since they don't have a provides)
91
92 if inspect.isclass(c) and issubclass(c, Deleter) and hasattr(c,"model") and c.model!=None:
93 modelName = c.model
94 if not modelName in self.deleters:
95 self.deleters[modelName] = []
96 if not (c in self.deleters[modelName]):
97 self.deleters[modelName].append(c)
98 print 'loaded deleters: %s' % ",".join(self.deleters.keys())
99
Tony Mack79a49c82013-06-15 23:51:57 -0400100
Sapan Bhatia9faf7b02013-10-09 10:27:14 -0400101 def handle_event(self, payload):
102 payload_dict = json.loads(payload)
Sapan Bhatia43c3a772013-07-03 11:19:07 -0400103
Sapan Bhatia9faf7b02013-10-09 10:27:14 -0400104 try:
Scott Bakerc1c45f82014-01-21 16:23:51 -0800105 deletion = payload_dict.get('delete_flag', False)
Sapan Bhatia9faf7b02013-10-09 10:27:14 -0400106 if (deletion):
107 model = payload_dict['model']
108 pk = payload_dict['pk']
Scott Baker6ecd4262014-01-21 23:15:21 -0800109 model_dict = payload_dict['model_dict']
Sapan Bhatiadbaf1932013-09-03 11:28:52 -0400110
Scott Baker6ecd4262014-01-21 23:15:21 -0800111 for deleter in self.deleters[model]:
112 try:
113 deleter()(pk, model_dict)
114 except:
115 # something is silently eating these
116 # exceptions...
117 traceback.print_exc()
118 raise
Scott Bakerc1c45f82014-01-21 16:23:51 -0800119
Sapan Bhatia9faf7b02013-10-09 10:27:14 -0400120 except:
121 deletion = False
Sapan Bhatia66f4e612013-07-02 12:12:38 -0400122
Sapan Bhatia9faf7b02013-10-09 10:27:14 -0400123 if (not deletion and self.wake_up):
124 self.wake_up()
Scott Bakerc1c45f82014-01-21 16:23:51 -0800125
Sapan Bhatia9faf7b02013-10-09 10:27:14 -0400126 def random_client_id(self):
Sapan Bhatia012ecff2013-10-09 10:56:06 -0400127 try:
Sapan Bhatia9faf7b02013-10-09 10:27:14 -0400128 return self.client_id
Sapan Bhatia012ecff2013-10-09 10:56:06 -0400129 except AttributeError:
Sapan Bhatia9faf7b02013-10-09 10:27:14 -0400130 self.client_id = base64.urlsafe_b64encode(os.urandom(12))
131 return self.client_id
Scott Bakerc1c45f82014-01-21 16:23:51 -0800132
Sapan Bhatia9faf7b02013-10-09 10:27:14 -0400133 def run(self):
134 # This is our unique client id, to be used when firing and receiving events
135 # It needs to be generated once and placed in the config file
Sapan Bhatia66f4e612013-07-02 12:12:38 -0400136
Sapan Bhatia9faf7b02013-10-09 10:27:14 -0400137 try:
138 user = Config().feefie_client_user
139 except:
140 user = 'pl'
Sapan Bhatiab9c59342013-09-03 10:21:13 -0400141
Sapan Bhatia9faf7b02013-10-09 10:27:14 -0400142 try:
143 clid = Config().feefie_client_id
144 except:
145 clid = self.random_client_id()
146
147 f = Fofum(user=user)
148
149 listener_thread = threading.Thread(target=f.listen_for_event,args=(clid,self.handle_event))
150 listener_thread.start()