--- a/lib/shorturl.py Sun Jan 20 01:52:00 2008 +0000
+++ b/lib/shorturl.py Thu Jan 31 17:28:02 2008 +0000
@@ -25,7 +25,7 @@
from log import index
-import utils, db
+import utils, db, helpers, folder, image
def int2key (id) :
"""
@@ -41,7 +41,8 @@
def key2int (key) :
# base64 ignores extra padding, but if it doesn't, it's (4 - len%4), if len%4 != 0
- bytes = base64.b64decode(key + '='*6, '-_')
+ # and it breaks on unicode strings
+ bytes = base64.b64decode(str(key + '='*6), '-_')
type = {
1: 'B',
@@ -51,66 +52,6 @@
return struct.unpack(type, bytes)[0]
-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()
-
class DB (object) :
def __init__ (self, read_only=True) :
self.db = shelve.open('shorturls2', read_only and 'r' or 'c')
@@ -158,9 +99,21 @@
return ret
def html_path (key, index=None) :
- dir, fname = image_info(key)
+ dir, fname = node_info(key)
- return utils.url(dir, fname + '.html')
+ if fname :
+ return utils.url(dir, fname + '.html')
+ else :
+ return utils.url(dir, helpers.url_for_page(index or 0))
+
+def node_info (key) :
+ res = db.select("""SELECT dirpath, filename FROM nodes WHERE id=?""", key2int(key)).fetchone()
+
+ if res :
+ return res
+
+ else :
+ raise KeyError(key)
def image_info (key) :
res = db.select("""SELECT dirpath, filename FROM images WHERE id=?""", key2int(key)).fetchone()
@@ -181,3 +134,75 @@
else :
raise KeyError(keys)
+def _got_obj_key (obj, id) :
+ key = int2key(id)
+
+ obj.shorturl_code = key
+
+ if isinstance(obj, folder.Folder) :
+ dir, fname = utils.strip_path(obj.path), ''
+ elif isinstance(obj, image.Image) :
+ dir, fname = utils.strip_path(obj.dir.path), obj.name
+ else :
+ assert(False, "%r %r" % (obj, id))
+
+ index.info("img %50s %15s = %d %s", dir, fname, id, key)
+
+def updateDB (root) :
+ """
+ Update the SQL database
+
+ 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.
+ """
+
+ dirqueue = [root]
+
+ # dict of (dir, fname) -> obj
+ paths = {}
+
+ index.info("Processing ShortURLs...")
+
+ while dirqueue :
+ dir = dirqueue.pop(0)
+
+ dirqueue.extend(dir.subdirs.itervalues())
+
+ if dir.alive :
+ pathtuple = (utils.strip_path(dir.path), '')
+
+ index.debug("dir %50s", pathtuple[0])
+
+ paths[pathtuple] = dir
+
+ for img in dir.images.itervalues() :
+ pathtuple = (utils.strip_path(img.dir.path), img.name)
+
+ index.debug("img %50s %15s", *pathtuple)
+
+ paths[pathtuple] = img
+
+ print "%d nodes:" % (len(paths))
+
+ for (id, dir, fname) in db.select("SELECT id, dirpath, filename FROM nodes") :
+ try :
+ obj = paths.pop((dir, fname))
+ key = int2key(id)
+
+ obj.shorturl_code = key
+
+ index.debug("%s %50s %15s -> %d %s", dir and "img" or "dir", dir, fname, id, key)
+
+ except KeyError :
+ pass
+# index.warning("non-existant node (%d, %s, %s) in db", id, dir, fname)
+
+ print "%d NEW nodes:" % (len(paths))
+
+ db.insert_many(
+ _got_obj_key,
+ "INSERT INTO nodes (dirpath, filename) VALUES (?, ?)",
+ ((obj, (path, fname)) for ((path, fname), obj) in paths.iteritems())
+ )
+