lib/shorturl.py
changeset 12 c2d8e9a754a1
child 14 4b5478da5850
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/shorturl.py	Fri Dec 21 20:36:03 2007 +0000
@@ -0,0 +1,78 @@
+import struct
+import base64
+import shelve
+import os.path
+
+from log import index
+
+def int2key (id) :
+    """
+        Turn an integer into a short-as-possible url-safe string
+    """
+    for type in ('B', 'H', 'I') :
+        try :
+            return base64.b64encode(struct.pack(type, id), '-_').rstrip('=')
+        except struct.error :
+            continue
+
+    raise Exception("ID overflow: %s" % id)
+
+def updateDB (root) :
+    """
+        DeGAL <= 0.2 used a simple key => path mapping, but now we use
+        something more structured, key => (type, dirpath, fname), where
+
+        type    - one of 'img', 'dir'
+        dirpath - the path to the directory, e.g. '.', './foobar', './foobar/quux'
+        fname   - the filename, one of '', 'DSC9839.JPG', 'this.png', etc.
+    """
+
+    db = shelve.open('shorturls2', 'c', writeback=True)
+    
+    id = db.get('_id', 1)
+
+    dirqueue = [root]
+
+    # dict of path -> obj
+    paths = {}
+
+    index.info("Processing ShortURLs...")
+
+    while dirqueue :
+        dir = dirqueue.pop(0)
+
+        dirqueue.extend(dir.subdirs.itervalues())
+
+        if dir.alive :
+            paths[dir.path] = dir
+
+        for img in dir.images.itervalues() :
+            paths[img.path] = img
+
+    for key in db.keys() :
+        if key.startswith('_') :
+            continue
+
+        type, dirpath, fname = db[key]
+        
+        path = os.path.join(dirpath, fname).rstrip(os.sep)
+
+        try :
+            paths.pop(path).shorturl_code = key
+            index.debug("Code for `%s' is %s", path, key)
+
+        except KeyError :
+            index.debug("Path `%s' in DB does not exist?", path)
+
+    for obj in paths.itervalues() :
+        key = int2key(id)
+        id += 1
+        
+        index.info("Alloc code `%s' for `%s'", key, obj.html_path)
+
+        obj.shorturl_code = key
+
+        db[key] = obj.getObjInfo()
+
+    db['_id'] = id
+    db.close()