fc94a176eb777dc01452b4d1be933021a172a90e
[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 %s'%ret_string.text)
74
75     def fire(self, payload='""'):
76         self.run_action('fire',hash=self.hash,message=payload)
77
78     def listen(self):
79         channel_js = CHANNEL_JS%(FEEFIE_SERVER_URL, self.hash)
80         f = tempfile.NamedTemporaryFile('w')
81         f.write(channel_js)
82         f.flush()
83         cmdline = '%s %s'%(PHANTOM_PATH, f.name)
84         conn = os.popen(cmdline)
85         self.series = 0
86         
87         while True:
88             msg = conn.readline()
89             if ('###' in msg):
90                 status,payload = msg.split('###')
91                 status = int(status)
92                 if (status>self.series):
93                     self.series = status
94                     if (self.callback):
95                         self.callback(payload)
96                 elif (status<0):
97                     break
98         # Returns when connection breaks. Caller needs to resubscribe, relisten
99         return    
100
101     # This method creates/looks up an event, subscribes to it, listens and reconnects if necessary.
102     def listen_for_event(self, event_name, callback):
103         self.callback = callback
104         hash = self.make(event_name)
105
106         stamp = time.time() 
107         while (True):
108             self.subscribe()
109             self.listen()
110             interval = time.time() - stamp
111             if (interval < 5.0):
112                 # Too fast, wait
113                 time.sleep(5.0 - interval)
114                 
115
116     def __init__(self,user='',hash=None):
117         # Check phantomjs dependency
118         if (not os.access(PHANTOM_PATH,0)):
119             raise FofumException('Phantomjs not installed.')
120         self.user = user
121
122