changeset 55:5e08a9f4730e

We now support multiple conversations based on the URL.
author Atul Varma <varmaa@toolness.com>
date Tue, 28 Apr 2009 15:04:29 -0700
parents d1331955845f
children 0bb64cafd063
files openwebchat.py
diffstat 1 files changed, 57 insertions(+), 40 deletions(-) [+]
line wrap: on
line diff
--- a/openwebchat.py	Tue Apr 28 14:39:40 2009 -0700
+++ b/openwebchat.py	Tue Apr 28 15:04:29 2009 -0700
@@ -14,6 +14,19 @@
 except ImportError:
     import simplejson as json
 
+class Conversations(object):
+    def __init__(self):
+        self._convs = {}
+
+    def get(self, name):
+        if name not in self._convs:
+            filename = '%s.conversation' % name
+            if not os.path.exists(filename):
+                open(filename, 'w').close()
+
+            self._convs[name] = Conversation(open(filename, 'r+w'))
+        return self._convs[name]
+
 class Conversation(list):
     def __init__(self, fileobj):
         list.__init__(self)
@@ -29,7 +42,7 @@
         self.__file.flush()
 
 class OpenWebChatServer(object):
-    CONVERSATION_URL = re.compile('\/conversations\/([A-Za-z0-9_]+)')
+    URL_TEMPLATE = re.compile('\/([A-Za-z0-9_]+)/(.*)')
 
     BOUNDARY = "'''"
 
@@ -39,8 +52,8 @@
                   'js' : 'text/javascript',
                   'css' : 'text/css'}
 
-    def __init__(self, addr, conversation):
-        self._conv = conversation
+    def __init__(self, addr, conversations):
+        self._convs = conversations
         self._server = CoroutineSocketServer(addr,
                                              self._server_coroutine)
 
@@ -111,6 +124,37 @@
                  self.__multipart_boundary(boundary))
                 ))
 
+    def _until_conv_request_processed(self, addr, headers, method,
+                                      conv_name, page):
+        if page == 'listen/multipart':
+            yield self._until_multipart_header_sent(self.BOUNDARY)
+            i = 0
+            conv = self._convs.get(conv_name)
+            while 1:
+                while i < len(conv):
+                    msg = json.dumps(conv[i])
+                    i += 1
+                    yield self._until_multipart_part_sent(self.BOUNDARY, msg)
+                yield channels.until_message_received('new-message')
+        elif page == 'send':
+            length = int(headers.getheader('Content-Length', 0))
+            msg = yield until_received(bytes = length)
+            conv = self._convs.get(conv_name)
+            conv.append(json.loads(msg))
+            yield channels.until_message_sent('new-message', None)
+            yield self._until_http_response_sent('sent.')
+        elif page in ['', 'jquery.js', 'openwebchat.js',
+                      'json2.js', 'openwebchat.css']:
+            if page == '':
+                filename = 'openwebchat.html'
+            else:
+                filename = page
+
+            yield self._until_file_sent(filename)
+        else:
+            yield self._until_http_response_sent('not found',
+                                                 code = 404)
+
     def _until_one_request_processed(self, addr):
         request = yield until_received(terminator = '\r\n\r\n')
         request = request.splitlines()
@@ -118,37 +162,16 @@
         stringfile = cStringIO.StringIO('\n'.join(request[1:]))
         headers = mimetools.Message(stringfile)
         req_parts = request_line.split()
-        if req_parts[1] == '/listen/multipart':
-            yield self._until_multipart_header_sent(self.BOUNDARY)
-            i = 0
-            while 1:
-                while i < len(self._conv):
-                    msg = json.dumps(self._conv[i])
-                    i += 1
-                    yield self._until_multipart_part_sent(self.BOUNDARY, msg)
-                yield channels.until_message_received('new-message')
-        elif req_parts[1] == '/send':
-            length = int(headers.getheader('Content-Length', 0))
-            msg = yield until_received(bytes = length)
-            self._conv.append(json.loads(msg))
-            yield channels.until_message_sent('new-message', None)
-            yield self._until_http_response_sent('sent.')
-        elif req_parts[1] in ['/', '/jquery.js', '/openwebchat.js',
-                              '/json2.js', '/openwebchat.css']:
-            if req_parts[1] == '/':
-                filename = 'openwebchat.html'
-            else:
-                filename = req_parts[1][1:]
-
-            yield self._until_file_sent(filename)
+        method = req_parts[0]
+        match = self.URL_TEMPLATE.match(req_parts[1])
+        if not match:
+            yield self._until_http_response_sent('not found',
+                                                 code = 404)
         else:
-            match = self.CONVERSATION_URL.match(req_parts[1])
-            if match:
-                yield self._until_http_response_sent('not implemented',
-                                                     code = 501)
-            else:
-                yield self._until_http_response_sent('not found',
-                                                     code = 404)
+            conv_name = match.group(1)
+            page = match.group(2)
+            yield self._until_conv_request_processed(addr, headers, method,
+                                                     conv_name, page)
 
 if __name__ == '__main__':
     if len(sys.argv) > 1:
@@ -156,11 +179,5 @@
     else:
         port = 8071
 
-    CONVERSATION_FILE = 'conversation.dat'
-
-    if not os.path.exists(CONVERSATION_FILE):
-        open(CONVERSATION_FILE, 'w').close()
-
-    server = OpenWebChatServer(('', port),
-                               Conversation(open(CONVERSATION_FILE, 'r+w')))
+    server = OpenWebChatServer(('', port), Conversations())
     server.run()