changeset 14:667ebf2a5e8b

added filestorage; server.py now saves stuff persistently in the storage directory.
author Atul Varma <avarma@mozilla.com>
date Thu, 24 Jun 2010 21:50:40 -0700
parents 42093a5a19b4
children a631c77a3bf5
files .hgignore server.py summitidp/app.py summitidp/file_storage.py
diffstat 4 files changed, 129 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/.hgignore	Thu Jun 24 18:49:27 2010 -0700
+++ b/.hgignore	Thu Jun 24 21:50:40 2010 -0700
@@ -1,2 +1,3 @@
 syntax: glob
 *.pyc
+storage
--- a/server.py	Thu Jun 24 18:49:27 2010 -0700
+++ b/server.py	Thu Jun 24 21:50:40 2010 -0700
@@ -1,16 +1,46 @@
+import os
 import json
+import datetime
 
 from wsgiref.simple_server import make_server
 from summitidp.static_file_serving import StaticFileApp
-from summitidp.app import Server
+from summitidp.app import Server, TokenStore, ProfileStore
+from summitidp.file_storage import FileStorage
+
+CHALLENGE_TOKEN_LIFETIME = datetime.timedelta(days=1)
+AUTH_TOKEN_LIFETIME = None
+
+def ensure_dirs(*paths):
+    for path in paths:
+        if not os.path.exists(path):
+            os.mkdir(path)
+
+def send_email(email, token):
+    print "Please send %s an email with the token %s." % (email, token)
 
 if __name__ == '__main__':
-    def send_email(email, token):
-        print "Please send %s an email with the token %s." % (email, token)
+    mydir = os.getcwd()
+
+    storage_dir = os.path.join(mydir, 'storage')
+    emails_file = os.path.join(storage_dir, 'attendees.json')
+    static_files_dir = os.path.join(mydir, 'static-files')
+    challenge_dir = os.path.join(storage_dir, 'challenge-tokens')
+    auth_dir = os.path.join(storage_dir, 'auth-tokens')
+    profile_dir = os.path.join(storage_dir, 'profiles')
+
+    ensure_dirs(storage_dir, challenge_dir, auth_dir, profile_dir)
 
-    server = Server(json.loads(open('attendees.json').read()),
-                    send_email,
-                    delegate_404s=StaticFileApp('static-files'))
+    server = Server(
+        emails=json.loads(open(emails_file).read()),
+        send_email=send_email,
+        delegate_404s=StaticFileApp(static_files_dir),
+        challenge_tokens=TokenStore(lifetime=CHALLENGE_TOKEN_LIFETIME,
+                                    mapping=FileStorage(challenge_dir)),
+        auth_tokens=TokenStore(lifetime=AUTH_TOKEN_LIFETIME,
+                               mapping=FileStorage(auth_dir)),
+        profiles=ProfileStore(FileStorage(profile_dir))
+        )
+
     port = 8000
     httpd = make_server('', port, server.wsgi_app)
     print 'serving on port %d' % port
--- a/summitidp/app.py	Thu Jun 24 18:49:27 2010 -0700
+++ b/summitidp/app.py	Thu Jun 24 21:50:40 2010 -0700
@@ -57,11 +57,13 @@
 
 class TokenStore(object):
     def __init__(self, lifetime=None, utcnow=datetime.datetime.utcnow,
-                 gentoken=gentoken):
+                 gentoken=gentoken, mapping=None):
+        if mapping is None:
+            mapping = {}
         self.utcnow = utcnow
         self.gentoken = gentoken
         self.lifetime = lifetime
-        self.__tokens = {}
+        self.__tokens = mapping
 
     def create(self, **contents):
         token = self.gentoken()
@@ -89,14 +91,19 @@
         return self.__tokens[token]['contents']
 
 class ProfileStore(object):
-    def __init__(self):
-        self.__profiles = {}
+    def __init__(self, mapping=None):
+        if mapping is None:
+            mapping = {}
+        self.__profiles = mapping
 
     def set(self, user_id, contents):
-        self.__profiles[user_id] = contents
+        self.__profiles[str(user_id)] = contents
 
     def get(self):
-        return self.__profiles
+        everything = {}
+        for user_id in self.__profiles:
+            everything[user_id] = self.__profiles[user_id]
+        return everything
 
 class Server(object):
     request_challenge_path = '/challenge/request'
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/summitidp/file_storage.py	Thu Jun 24 21:50:40 2010 -0700
@@ -0,0 +1,79 @@
+import re
+import os
+import json
+
+class FileStorage(object):
+    """
+    >>> import tempfile
+    >>> dirname = tempfile.mkdtemp(prefix='test')
+    >>> olddir = os.getcwd()
+    >>> os.chdir(dirname)
+
+    >>> fs = FileStorage('.')
+    >>> 'blah' in fs
+    False
+    >>> os.path.exists('blah.json')
+    False
+    >>> fs['blah'] = {'foo': 1}
+    >>> 'blah' in fs
+    True
+    >>> os.path.exists('blah.json')
+    True
+    >>> open('blah.json').read()
+    '{"foo": 1}'
+    >>> fs['blah']
+    {u'foo': 1}
+    >>> for name in fs:
+    ...   print name
+    blah
+    >>> del fs['blah']
+    >>> 'blah' in fs
+    False
+    >>> '9-p' in fs
+    False
+    >>> '9_p' in fs
+    False
+    >>> os.path.exists('blah.json')
+    False
+
+    >>> os.chdir(olddir)
+    >>> os.rmdir(dirname)
+    """
+
+    keypattern = re.compile('^[A-Za-z0-9\-_]+$')
+
+    def __init__(self, dirname):
+        self.dirname = dirname
+
+    def __filename(self, name):
+        if not self.keypattern.match(name):
+            raise ValueError('invalid key name: %s' % name)
+        return os.path.join(self.dirname, "%s.json" % name)
+
+    def __iter__(self):
+        for name in os.listdir(self.dirname):
+            base, ext = os.path.splitext(name)
+            if ext == '.json' and self.keypattern.match(base):
+                yield base
+
+    def __contains__(self, name):
+        return os.path.exists(self.__filename(name))
+
+    def __delitem__(self, name):
+        if not name in self:
+            raise KeyError(name)
+        os.remove(self.__filename(name))
+
+    def __getitem__(self, name):
+        if not name in self:
+            raise KeyError(name)
+        return json.loads(open(self.__filename(name)).read())
+
+    def __setitem__(self, name, value):
+        open(self.__filename(name), 'w').write(json.dumps(value))
+
+if __name__ == '__main__':
+    import doctest
+
+    doctest.testmod()
+    print "done running tests"