/
__init__.py
executable file
·133 lines (120 loc) · 4.52 KB
/
__init__.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
try:
# Python 2
import httplib
except ImportError:
# Python 3
import http.client as httplib
import socket
from django.conf import settings
try:
from django.utils import simplejson as json
except ImportError:
import json
__version__ = '0.1.6'
VERSION = map(int, __version__.split('.'))
class iShoutClient(object):
"""
A really basic HTTP client to the iShout.js internal interface.
It is intended for use with django, but could easily be adapted
for general use (or maybe for another python web framework)
"""
def __init__(self):
self.base_url = getattr(settings, 'ISHOUT_API_ADDR', 'localhost:6600')
def _do_request(self, method, path, *args, **kwargs):
# A generic wrapper around httplib.
# I initally wanted to use @kennethreitz's awesome Requests
# (python-requests.org) but didn't want to intoduce more dependencies.
try:
con = httplib.HTTPConnection(self.base_url)
con.request(method, path, *args, **kwargs)
return con.getresponse()
except (httplib.HTTPException, socket.error):
return None
def get_token(self, user_id):
"""
For a given user ID, return a token. Keep in mind that this ID
could be anything that uniquley describes a user in the system.
A primary key from the users table is a good fit, but so is
a session ID, as long as it is unique.
"""
path = '/auth/token/%s' % (user_id)
response = self._do_request('POST', path)
if not response or response.status > 399:
return None
try:
resp = json.loads(response.read())
except ValueError:
return None
if resp:
if 'token' in resp:
return '%s|%s' % (user_id, resp['token'])
return None
def register_group(self, user_id, group_name):
"""
Add a user ID (read about what a user ID is under get_token())
to a given group name. Groups are created on the fly when adding
the first user. This group could be anything you want it to be,
no rules here. Map a set of users to a logical name.
"""
path = '/auth/group/%s/%s' % (group_name, user_id)
response = self._do_request('POST', path)
response.read()
def unregister_group(self, user_id, group_name):
"""
Remove a user from group.
"""
path = '/auth/group/%s/%s' % (group_name, user_id)
response = self._do_request('DELETE', path)
response.read()
def emit(self, user_id, channel, data):
"""
send a message over the given channel to the specified user.
`data` should be a regular python dict, or any other object
that is json.dumps'able.
"""
path = '/emit/user/%s/%s' % (user_id, channel)
headers = {'Content-Type' : 'application/json'}
data = json.dumps(data)
response = self._do_request('POST', path, data, headers)
response.read()
def broadcast_group(self, group_name, channel, data):
"""
Emitts the message over the specified channel to all members
of the group.
"""
path = '/emit/group/%s/%s' % (group_name, channel)
headers = {'Content-Type' : 'application/json'}
data = json.dumps(data)
response = self._do_request('POST', path, data, headers)
response.read()
def broadcast_room(self, channel, data):
"""
Emitts the message over the specified channel to all members
of the group.
"""
path = '/emit/room/%s' % (channel)
headers = {'Content-Type' : 'application/json'}
data = json.dumps(data)
response = self._do_request('POST', path, data, headers)
response.read()
def broadcast(self, channel, data):
"""
Emit the given message to all connected users.
"""
path = '/emit/broadcast/%s' % (channel)
headers = {'Content-Type' : 'application/json'}
data = json.dumps(data)
response = self._do_request('POST', path, data, headers)
response.read()
def get_room_status(self, channel):
"""
Return information about the current status of a room.
(most importanly, members currently online in that room).
"""
path = '/status/room/%s' % (channel)
response = self._do_request('GET', path)
data = response.read()
try:
return json.loads(data)
except ValueError:
return None