|
1 import struct |
|
2 import base64 |
|
3 import shelve |
|
4 import os.path |
|
5 |
|
6 from log import index |
|
7 |
|
8 def int2key (id) : |
|
9 """ |
|
10 Turn an integer into a short-as-possible url-safe string |
|
11 """ |
|
12 for type in ('B', 'H', 'I') : |
|
13 try : |
|
14 return base64.b64encode(struct.pack(type, id), '-_').rstrip('=') |
|
15 except struct.error : |
|
16 continue |
|
17 |
|
18 raise Exception("ID overflow: %s" % id) |
|
19 |
|
20 def updateDB (root) : |
|
21 """ |
|
22 DeGAL <= 0.2 used a simple key => path mapping, but now we use |
|
23 something more structured, key => (type, dirpath, fname), where |
|
24 |
|
25 type - one of 'img', 'dir' |
|
26 dirpath - the path to the directory, e.g. '.', './foobar', './foobar/quux' |
|
27 fname - the filename, one of '', 'DSC9839.JPG', 'this.png', etc. |
|
28 """ |
|
29 |
|
30 db = shelve.open('shorturls2', 'c', writeback=True) |
|
31 |
|
32 id = db.get('_id', 1) |
|
33 |
|
34 dirqueue = [root] |
|
35 |
|
36 # dict of path -> obj |
|
37 paths = {} |
|
38 |
|
39 index.info("Processing ShortURLs...") |
|
40 |
|
41 while dirqueue : |
|
42 dir = dirqueue.pop(0) |
|
43 |
|
44 dirqueue.extend(dir.subdirs.itervalues()) |
|
45 |
|
46 if dir.alive : |
|
47 paths[dir.path] = dir |
|
48 |
|
49 for img in dir.images.itervalues() : |
|
50 paths[img.path] = img |
|
51 |
|
52 for key in db.keys() : |
|
53 if key.startswith('_') : |
|
54 continue |
|
55 |
|
56 type, dirpath, fname = db[key] |
|
57 |
|
58 path = os.path.join(dirpath, fname).rstrip(os.sep) |
|
59 |
|
60 try : |
|
61 paths.pop(path).shorturl_code = key |
|
62 index.debug("Code for `%s' is %s", path, key) |
|
63 |
|
64 except KeyError : |
|
65 index.debug("Path `%s' in DB does not exist?", path) |
|
66 |
|
67 for obj in paths.itervalues() : |
|
68 key = int2key(id) |
|
69 id += 1 |
|
70 |
|
71 index.info("Alloc code `%s' for `%s'", key, obj.html_path) |
|
72 |
|
73 obj.shorturl_code = key |
|
74 |
|
75 db[key] = obj.getObjInfo() |
|
76 |
|
77 db['_id'] = id |
|
78 db.close() |