fix _client_id not found error
[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 = '/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     # Use _client_id as a class variable. It will be shared by all Fofum
43     # objects in this python interpreter process.
44     _client_id=''
45
46     def run_action(self, action, hash='', message='',title=''):
47         event = json.dumps({'title':title})
48         params = {'action':action,'hash':hash,'payload':message,'u':self.user,'event':event,'client_id':Fofum._client_id}
49         return requests.get(FEEFIE_SERVER_URL, params=params)
50
51     def make(self, title):
52         ret_string = self.run_action('add',title=title)
53         try:
54             ret_dict = json.loads(ret_string.text)
55             if (ret_dict['status']!=0):
56                 raise FofumException('Error creating event. Server error.')
57             else:
58                 try:
59                     self.hash = ret_dict['hash']
60                 except KeyError:
61                     raise FofumException('Error creating event. Did not get event spec.')
62         except:
63             raise FofumException('Error creating event. Malformed response: %s'%ret_string.text)
64
65     def subscribe(self):
66         ret_string = self.run_action('subscribe', hash=self.hash)
67         try:
68             ret_dict = json.loads(ret_string.text)
69             if (ret_dict['status']!=0):
70                 raise FofumException('Error creating event. Server error.')
71             else:
72                 try:
73                     self.token = ret_dict['token']
74                     Fofum._client_id = ret_dict['client_id']
75                 except KeyError:
76                     raise FofumException('Error fetching token. Did not get token spec')
77         except:
78             raise FofumException('Error subscribing to event. Malformed response %s'%ret_string.text)
79
80     def fire(self, payload='""'):
81         self.run_action('fire',hash=self.hash,message=payload)
82
83     def listen(self):
84         channel_js = CHANNEL_JS%(FEEFIE_SERVER_URL, self.hash)
85         f = tempfile.NamedTemporaryFile('w')
86         f.write(channel_js)
87         f.flush()
88         cmdline = '%s %s'%(PHANTOM_PATH, f.name)
89         conn = os.popen(cmdline)
90         self.series = 0
91         
92         while True:
93             msg = conn.readline()
94             if ('###' in msg):
95                 status,payload = msg.split('###')
96                 status = int(status)
97                 if (status>self.series):
98                     self.series = status
99                     if (self.callback):
100                         self.callback(payload)
101                 elif (status<0):
102                     break
103         # Returns when connection breaks. Caller needs to resubscribe, relisten
104         try:
105             conn.close()
106         except Exception,e:
107             print "Could not terminate phantomjs. This may cause a memory leak."
108             print str(e)
109
110         return    
111
112     # This method creates/looks up an event, subscribes to it, listens and reconnects if necessary.
113     def listen_for_event(self, event_name, callback):
114         self.callback = callback
115         hash = self.make(event_name)
116
117         stamp = time.time() 
118         while (True):
119             self.subscribe()
120             self.listen()
121             interval = time.time() - stamp
122             if (interval < 5.0):
123                 # Too fast, wait
124                 time.sleep(5.0 - interval)
125                 
126
127     def __init__(self,user='',hash=None,client_id=''):
128         Fofum._client_id = client_id
129         # Check phantomjs dependency
130         if (not os.access(PHANTOM_PATH,0)):
131             raise FofumException('Phantomjs not installed.')
132         self.user = user
133
134