diff -r 4b3cf12848c2 -r 81d6679d50d0 lib/shorturl.py --- 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()) + ) +