use sqlite3 instead of bdb, series and shorturl should still work with this (adding new images won't yet)
--- a/de-cgi-bin/series.py Wed Jan 16 16:28:03 2008 +0000
+++ b/de-cgi-bin/series.py Wed Jan 16 18:44:03 2008 +0000
@@ -101,9 +101,6 @@
except ValueError :
fname = arg2
- # load DB
- db = shorturl.DB()
-
# our custom Series/Image classes, because they do act slightly differently
class Series (object) :
@@ -113,9 +110,9 @@
self.image_dict = dict()
- for index, key in enumerate(keys) :
- dir, fname = db.image_info(key)
+ images = shorturl.get_images(keys)
+ for index, (key, (dir, fname)) in enumerate(zip(keys, images)) :
img = Image(self, key, dir, fname, index)
self.images.append(img)
self.image_dict[fname] = img
--- a/de-cgi-bin/shorturl.py Wed Jan 16 16:28:03 2008 +0000
+++ b/de-cgi-bin/shorturl.py Wed Jan 16 18:44:03 2008 +0000
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2.4
+#!/usr/bin/env python2.5
#
# DeGAL - A pretty simple web image gallery
# Copyright (C) 2007 Tero Marttila
@@ -20,26 +20,22 @@
# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
-import cgi
-
import inc
-from lib import shorturl
-
-vars = cgi.FieldStorage()
-
-key = vars['key'].value
+from lib import shorturl, req
-if 'index' in vars :
- index = int(vars['index'].value.lstrip('/'))
-else :
- index = None
-
-db = shorturl.DB()
+key = req.get_str('key')
+index = req.get_int('index', None)
-path = db.html_path(key, index)
+path = shorturl.html_path(key)
-print "Status: 302"
-print "Location: ../%s" % path
-print
-print "../%s" % path
+if path :
+ print "Status: 302"
+ print "Location: ../%s" % path
+ print
+ print "../%s" % path
+else :
+ print "Status: 404"
+ print
+ print "404"
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/db.py Wed Jan 16 18:44:03 2008 +0000
@@ -0,0 +1,37 @@
+# DeGAL - A pretty simple web image gallery
+# Copyright (C) 2007 Tero Marttila
+# http://marttila.de/~terom/degal/
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the
+# Free Software Foundation, Inc.,
+# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+
+import sqlite3
+
+conn = sqlite3.connect("degal.db")
+
+def execute (expr, *args) :
+ c = conn.cursor()
+ c.execute(expr, args)
+
+ return c
+
+def insert (expr, *args) :
+ return execute(expr, *args).rowcount
+
+select = execute
+
+cursor = conn.cursor
+
--- a/lib/shorturl.py Wed Jan 16 16:28:03 2008 +0000
+++ b/lib/shorturl.py Wed Jan 16 18:44:03 2008 +0000
@@ -25,6 +25,8 @@
from log import index
+import utils, db
+
def int2key (id) :
"""
Turn an integer into a short-as-possible url-safe string
@@ -37,6 +39,18 @@
raise Exception("ID overflow: %s" % id)
+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, '-_')
+
+ type = {
+ 1: 'B',
+ 2: 'H',
+ 4: 'I',
+ }[len(bytes)]
+
+ return struct.unpack(type, bytes)[0]
+
def updateDB (root) :
"""
DeGAL <= 0.2 used a simple key => path mapping, but now we use
@@ -143,3 +157,27 @@
return ret
+def html_path (key, index=None) :
+ dir, fname = image_info(key)
+
+ return utils.url(dir, fname + '.html')
+
+def image_info (key) :
+ res = db.select("""SELECT dirpath, filename FROM images WHERE id=?""", key2int(key)).fetchone()
+
+ if res :
+ return res
+
+ else :
+ raise KeyError(key)
+
+def get_images (keys) :
+ res = [db.select("""SELECT dirpath, filename FROM images WHERE id=?""", key2int(key)).fetchone() for key in keys]
+
+ # don't mind if we don't get as many as we asked for?
+ if res :
+ return res
+
+ else :
+ raise KeyError(keys)
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/fix_duplicate_shorturls.py Wed Jan 16 18:44:03 2008 +0000
@@ -0,0 +1,33 @@
+from lib import shorturl
+
+db = shorturl.DB(read_only=False)
+
+ids = dict()
+
+newid = db.db['_id']
+
+for key in db.db.keys() :
+ if key.startswith('_') :
+ continue
+
+ if len(key) == 1 :
+ print "key %s is too short!?" % key
+ del db.db[key]
+
+ continue
+
+ print "%s:" % key,
+ id = shorturl.key2int(key)
+
+ if id in ids :
+ newkey = shorturl.int2key(newid)
+ newid += 1
+
+ print "%d -> %s, -> %s" % (id, ids[id], newkey)
+
+ db.db[newkey] = db.db[key]
+ del db.db[key]
+ else :
+ print "ok"
+ ids[id] = key
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/lib Wed Jan 16 18:44:03 2008 +0000
@@ -0,0 +1,1 @@
+../lib/
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/migrate_shorturls.py Wed Jan 16 18:44:03 2008 +0000
@@ -0,0 +1,51 @@
+from lib import shorturl, db
+
+sdb = shorturl.DB()
+
+def gen () :
+ count = 0
+
+ for key in sdb.db.keys() :
+ if key.startswith("_") :
+ continue
+
+ print "%6s" % key,
+
+ value = sdb.db[key]
+
+ if not isinstance(value, tuple) or len(value) != 3 :
+ print "CORRUPT VALUE!!!"
+ continue
+
+ type, dirpath, fname = value
+
+ if type == "img" :
+ id = shorturl.key2int(key)
+
+ dirpath = dirpath.lstrip('.').lstrip('/')
+
+ print "%6d %50s %10s" % (id, dirpath, fname)
+
+ yield id, dirpath, fname
+
+ count += 1
+
+ if count % 500 == 0 :
+ print count
+ else :
+ print "dir"
+
+print "Starting import..."
+
+c = db.cursor()
+
+c.executemany("""
+ INSERT INTO images VALUES (?, ?, ?)
+""", gen())
+
+print "Done!"
+
+print "%d rows affected" % c.rowcount
+
+c.execute("SELECT id FROM images").fetchall()
+