Bug fixes
[fofum.git] / fofum.py
1 import requests
2 import os
3 import json
4 import tempfile
5 import time
6
7 """
8
9 The Fofum class encapsulates feefie events. It can be used to create events,
10 listen on events fire events.
11
12 """
13
14 PHANTOM_PATH = '/usr/bin/phantomjs'
15 #FEEFIE_SERVER_URL = "http://www.feefie.com/command"
16 FEEFIE_SERVER_URL = "http://feefie980522.appspot.com/command"
17
18 CHANNEL_JS="""
19         var page = require('webpage').create();
20         page.open('%s?action=subscribe&hash=%s&html=1',function() {
21         loopfn = function() {
22             var title = page.evaluate(function () {
23                 return eCount+'###'+payload.data;
24             });
25             console.log(title);
26             setTimeout(loopfn,1000);
27         };
28         setTimeout(loopfn,1000);
29         });
30         
31 """
32
33 class FofumException(Exception):
34     def __init__(self, value):
35         self.value = value
36
37     def __str__(self):
38         return str(self.value)
39         
40
41 class Fofum:
42     def run_action(self, action, hash='', message='',title=''):
43         event = json.dumps({'title':title})
44         params = {'action':action,'hash':hash,'payload':message,'u':self.user,'event':event}
45         return requests.get(FEEFIE_SERVER_URL, params=params)
46
47     def make(self, title):
48         ret_string = self.run_action('add',title=title)
49         try:
50             ret_dict = json.loads(ret_string.text)
51             if (ret_dict['status']!=0):
52                 raise FofumException('Error creating event. Server error.')
53             else:
54                 try:
55                     self.hash = ret_dict['hash']
56                 except KeyError:
57                     raise FofumException('Error creating event. Did not get event spec.')
58         except:
59             raise FofumException('Error creating event. Malformed response: %s'%ret_string.text)
60
61     def subscribe(self):
62         ret_string = self.run_action('subscribe', hash=self.hash)
63         try:
64             ret_dict = json.loads(ret_string.text)
65             if (ret_dict['status']!=0):
66                 raise FofumException('Error creating event. Server error.')
67             else:
68                 try:
69                     self.token = ret_dict['token']
70                 except KeyError:
71                     raise FofumException('Error fetching token. Did not get token spec')
72         except:
73             raise FofumException('Error subscribing to event. Malformed response.')
74
75     def fire(self, payload):
76         print 'Firing %s'%self.hash
77         self.run_action('fire',hash=self.hash,message=payload)
78
79     def listen(self):
80         channel_js = CHANNEL_JS%(FEEFIE_SERVER_URL, self.hash)
81         f = tempfile.NamedTemporaryFile('w')
82         f.write(channel_js)
83         f.flush()
84         print "Hash = %s"%self.hash
85         cmdline = '%s %s'%(PHANTOM_PATH, f.name)
86         conn = os.popen(cmdline)
87         self.series = 0
88         
89         while True:
90             msg = conn.readline()
91             if ('###' in msg):
92                 status,payload = msg.split('###')
93                 status = int(status)
94                 if (status>self.series):
95                     self.series = status
96                     if (self.callback):
97                         self.callback(payload)
98                 elif (status<0):
99                     break
100         # Returns when connection breaks. Caller needs to resubscribe, relisten
101         return    
102
103     # This method creates/looks up an event, subscribes to it, listens and reconnects if necessary.
104     def listen_on_event(self, event_name, callback):
105         self.callback = callback
106         hash = self.make(event_name)
107
108         stamp = time.time() 
109         while (True):
110             self.subscribe()
111             self.listen()
112             interval = time.time() - stamp
113             if (interval < 5.0):
114                 # Too fast, wait
115                 time.sleep(5.0 - interval)
116                 
117
118     def __init__(self,user=''):
119         # Check phantomjs dependency
120         if (not os.access(PHANTOM_PATH,0)):
121             raise FofumException('Phantomjs not installed.')
122         self.user = user
123
124