<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -16,11 +16,15 @@ import logging
 class FooApp(object):
     name = 'foo'
 
-    def __init__(self):
+    def __init__(self, user):
         self.config = json.loads(file('/etc/foobox.conf', 'r').read())
+        self.data = HTTPStore(self.config['common']['data_url'])
+        try:
+            self.config.update(json.loads(self.data['%s/config' % user]))
+        except KeyError: pass
+        self.data = PrefixDict(self.data, '%s/%s/' % (user, self.name))
 
-        self.data = PrefixDict(HTTPStore(self.config['common']['data_url']), self.name + '/')
-        self.server = self.config['common']['foobox_url']
+        self.server = '%s/%s' % (self.config['common']['foobox_url'], user)
     
     def recv(self, text, dst=None):
         msg = {</diff>
      <filename>fooapp.py</filename>
    </modified>
    <modified>
      <diff>@@ -27,20 +27,20 @@ class FooInterface(object):
     max_index = 0
 
     def __init__(self, data):
-        self._data = data
-        self.data = PrefixDict(data, self.typename + '/')
+        self.data = data
     
-    def GET(self, id=None):
+    def GET(self, user, id=None):
+        data = PrefixDict(self.data, '%s/%s/' % (user, self.typename))
         if not id:
             self.app.status = '200 OK'
-            keys = self.data.keys()
+            keys = data.keys()
             if not keys:
                 self.app.status = '404 Not Found'
                 return
             keys.sort()
             if self.max_index &gt; 0 and len(keys) &gt; self.max_index:
                 keys = keys[self.max_index:]
-            objects = dict([(k, self.data[k]) for k in keys])
+            objects = dict([(k, data[k]) for k in keys])
             for key in objects:
                 try:
                     obj = json.loads(objects[key])
@@ -50,7 +50,7 @@ class FooInterface(object):
             return
         
         try:
-            obj = self.data[id]
+            obj = data[id]
             self.app.status = '200 OK'
             self.app.header('Content-type', 'application/json')
             yield obj
@@ -60,10 +60,11 @@ class FooInterface(object):
 
         f = getattr(self, 'after_GET', None)
         if f:
-            f(id)
+            f(user, id)
         return
     
-    def POST(self, id=None):
+    def POST(self, user, id=None):
+        data = PrefixDict(self.data, '%s/%s/' % (user, self.typename))
         if id:
             self.app.status = '400 Bad Request'
             yield &quot;Don't send an ID when creating an object, I'll give you one&quot;
@@ -90,22 +91,23 @@ class FooInterface(object):
                 logging.error(format_exc())
         else:
             key = str(obj[self.keyname])
-        self.data[key] = json.dumps(obj)
+        data[key] = json.dumps(obj)
 
         self.app.status = '200 OK'
         yield key
         f = getattr(self, 'after_POST', None)
         if f:
-            f(key)
+            f(user, key)
         return
     
-    def PUT(self, id=None):
+    def PUT(self, user, id=None):
+        data = PrefixDict(self.data, '%s/%s/' % (user, self.typename))
         if not id:
             self.app.status = '400 Bad Request'
             yield 'ID is required when updating an object'
             return
         
-        if id in self.data.keys():
+        if id in data.keys():
             postdata = self.app.get_content()
 
             try:
@@ -121,7 +123,7 @@ class FooInterface(object):
 
             ts = int(time())
             obj['ts'] = ts
-            self.data[id] = json.dumps(obj)
+            data[id] = json.dumps(obj)
             self.app.status = '200 OK'
             yield id
         else:
@@ -130,24 +132,25 @@ class FooInterface(object):
 
         f = getattr(self, 'after_PUT', None)
         if f:
-            f(id)
+            f(user, id)
         return
 
-    def DELETE(self, id=None):
+    def DELETE(self, user, id=None):
+        data = PrefixDict(self.data, '%s/%s/' % (user, self.typename))
         if not id:
             self.app.status = '400 Bad Request'
             yield 'ID is required when deleting an object'
             return
 
-        if id in self.data.keys():
-            del self.data[id]
+        if id in data.keys():
+            del data[id]
             self.app.status = '200 OK'
         else:
             self.app.status = '404 Not Found'
             yield self.app.status
         f = getattr(self, 'after_DELETE', None)
         if f:
-            f(id)
+            f(user, id)
         return
 
 class Message(FooInterface):
@@ -156,14 +159,15 @@ class Message(FooInterface):
     max_index = 50
     queue = Queue(1000)
 
-    def after_POST(self, id):
-        msg = self.data[id]
+    def after_POST(self, user, id):
+        data = PrefixDict(self.data, '%s/' % user)
+        msg = data['message/' + id]
         msg = json.loads(msg)
         msg['id'] = id
 
         if 'dst' in msg:
             try:
-                app = self._data['app/%s' % msg['dst']]
+                app = data['app/%s' % msg['dst']]
                 app = json.loads(app)
                 self.queue.put((app, msg, 0))
             except KeyError:
@@ -173,14 +177,14 @@ class Message(FooInterface):
             return
 
         try:
-            routes = self._data['route/%s' % msg['src']]
+            routes = data['route/%s' % msg['src']]
         except KeyError:
             logging.info('No route for source %s, using default route' % msg['src'])
-            routes = self._data['route/default']
+            routes = data['route/default']
         routes = [x for x in routes.split('\n') if x]
         for route in routes:
             try:
-                app = self._data['app/%s' % route]
+                app = data['app/%s' % route]
                 app = json.loads(app)
                 self.queue.put((app, msg, 0))
             except KeyError:
@@ -255,16 +259,16 @@ def main():
     logging.basicConfig(filename=config['common']['log_path'], level=logging.DEBUG, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
 
     urls = [
-        ('^/message/(?P&lt;id&gt;[a-z0-9\-]+)$',  Message),
-        ('^/message$',                      Message),
-        ('^/route/(?P&lt;id&gt;[a-z0-9\-]+)$',    Route),
-        ('^/route$',                        Route),
-        ('^/app/(?P&lt;id&gt;[a-z0-9\-]+)$',      App),
-        ('^/app$',                          App),
+        ('^/(?P&lt;user&gt;[_\w]+)/message/(?P&lt;id&gt;[a-z0-9\-]+)$',  Message),
+        ('^/(?P&lt;user&gt;[_\w]+)/message$',                      Message),
+        ('^/(?P&lt;user&gt;[_\w]+)/route/(?P&lt;id&gt;[a-z0-9\-]+)$',    Route),
+        ('^/(?P&lt;user&gt;[_\w]+)/route$',                        Route),
+        ('^/(?P&lt;user&gt;[_\w]+)/app/(?P&lt;id&gt;[a-z0-9\-]+)$',      App),
+        ('^/(?P&lt;user&gt;[_\w]+)/app$',                          App),
         ('^/$',                             StaticPage),
     ]
 
-    data = PrefixDict(HTTPStore(config['common']['data_url']), 'foobox/')
+    data = HTTPStore(config['common']['data_url'])
     app = WSGIApp(urls, data=data)
     #server = WSGIServer(app, bindAddress=(config['bind_address'], int(config['bind_port'])))
     server = make_server(config['foobox']['bind_address'], config['foobox']['bind_port'], app)</diff>
      <filename>foobox.py</filename>
    </modified>
    <modified>
      <diff>@@ -15,9 +15,8 @@ class GoogleSMS(FooApp):
     name = 'google'
     config_opts = {}
 
-    def __init__(self, server=None):
-        FooApp.__init__(self, server)
-        self.data = FileStore('/tmp/apps/google')
+    def __init__(self, user='synack'):
+        FooApp.__init__(self, user)
         self.searchurl = 'http://www.google.com/sms/demo?hl=en&amp;country=US&amp;q='
         try:
             self.queries = json.loads(self.data['queries'])</diff>
      <filename>google_sms.py</filename>
    </modified>
    <modified>
      <diff>@@ -14,8 +14,8 @@ class IRC(FooApp):
         'target': 'Nick to send messages to',
     }
 
-    def __init__(self):
-        FooApp.__init__(self)
+    def __init__(self, user='synack'):
+        FooApp.__init__(self, user)
 
         self.nick = self.config['irc']['nick']
         self.target = self.config['irc']['target']</diff>
      <filename>irc.py</filename>
    </modified>
    <modified>
      <diff>@@ -17,8 +17,8 @@ class Twitter(FooApp):
         'password': 'Your twitter password',
     }
 
-    def __init__(self):
-        FooApp.__init__(self)
+    def __init__(self, user='synack'):
+        FooApp.__init__(self, user)
         self.api = twitter.Api(username=self.config['twitter']['username'], password=self.config['twitter']['password'])
         try:
             self.cache = json.loads(self.data['cache'])</diff>
      <filename>tweet.py</filename>
    </modified>
    <modified>
      <diff>@@ -16,8 +16,8 @@ class UPS(FooApp):
     name = 'ups'
     config_opts = {}
 
-    def __init__(self):
-        FooApp.__init__(self)
+    def __init__(self, user='synack'):
+        FooApp.__init__(self, user)
 
         try:
             self.numbers = json.loads(self.data['numbers'])</diff>
      <filename>ups.py</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>289dc0422f093e7c9d9038dd7767b80516b6b377</id>
    </parent>
  </parents>
  <author>
    <name>Jeremy Grosser</name>
    <email>synack@neohippie.net</email>
  </author>
  <url>http://github.com/synack/foobox/commit/a663063b8f742b9d5465f80e08301812edcb19b2</url>
  <id>a663063b8f742b9d5465f80e08301812edcb19b2</id>
  <committed-date>2009-01-13T14:38:27-08:00</committed-date>
  <authored-date>2009-01-13T14:38:27-08:00</authored-date>
  <message>Basic implementation of users and user-specific configs</message>
  <tree>fd1b0ba9dca4bf44539ef92f30b69eb78cba8894</tree>
  <committer>
    <name>Jeremy Grosser</name>
    <email>synack@neohippie.net</email>
  </committer>
</commit>
