Make client id a static property
[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     _client_id=''
43     def run_action(self, action, hash='', message='',title=''):
44         event = json.dumps({'title':title})
45         params = {'action':action,'hash':hash,'payload':message,'u':self.user,'event':event,'client_id'=_client_id}
46         return requests.get(FEEFIE_SERVER_URL, params=params)
47
48     def make(self, title):
49         ret_string = self.run_action('add',title=title)
50         try:
51             ret_dict = json.loads(ret_string.text)
52             if (ret_dict['status']!=0):
53                 raise FofumException('Error creating event. Server error.')
54             else:
55                 try:
56                     self.hash = ret_dict['hash']
57                 except KeyError:
58                     raise FofumException('Error creating event. Did not get event spec.')
59         except:
60             raise FofumException('Error creating event. Malformed response: %s'%ret_string.text)
61
62     def subscribe(self):
63         ret_string = self.run_action('subscribe', hash=self.hash)
64         try:
65             ret_dict = json.loads(ret_string.text)
66             if (ret_dict['status']!=0):
67                 raise FofumException('Error creating event. Server error.')
68             else:
69                 try:
70                     self.token = ret_dict['token']
71                     _client_id = ret_dict['client_id']
72                 except KeyError:
73                     raise FofumException('Error fetching token. Did not get token spec')
74         except:
75             raise FofumException('Error subscribing to event. Malformed response %s'%ret_string.text)
76
77     def fire(self, payload='""'):
78         self.run_action('fire',hash=self.hash,message=payload)
79
80     def listen(self):
81         channel_js = CHANNEL_JS%(FEEFIE_SERVER_URL, self.hash)
82         f = tempfile.NamedTemporaryFile('w')
83         f.write(channel_js)
84         f.flush()
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_for_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='',hash=None,client_id=''):
119         _client_id = client_id
120         # Check phantomjs dependency
121         if (not os.access(PHANTOM_PATH,0)):
122             raise FofumException('Phantomjs not installed.')
123         self.user = user
124
125