shrink -> adjust.
[Portfolio.git] / _zctl / regenPhotos.py
1 # -*- coding: utf-8 -*-
2 from argparse import ArgumentParser
3 import os
4 from AccessControl import getSecurityManager
5 from Testing.makerequest import makerequest
6 from zope.globalrequest import setRequest
7 from zope.site.hooks import setSite
8 from ZODB.POSException import ConflictError
9 from Products.Photo.cache import aggregateIndex
10 import transaction
11
12 GET_RI_SIGNATURE = (('size', 1), ('keepAspectRatio', 2))
13
14
15 def main(app, portal_path, userid, skipfile) :
16 portal = app.unrestrictedTraverse(portal_path)
17 portal = makerequest(portal)
18 setRequest(portal.REQUEST)
19 setSite(portal)
20 user = portal.acl_users.getUser(userid)
21 sm = getSecurityManager()
22 sm._context.user = user
23
24 absSkipFilePath = os.path.abspath(os.path.expanduser(skipfile))
25 if os.path.exists(absSkipFilePath) :
26 skipFile = open(absSkipFilePath, 'r+')
27 skip = filter(None, skipFile.readlines())
28 _skipDict = dict([(path.strip(), True) for path in skip])
29 del skip
30 else :
31 skipFile = open(absSkipFilePath, 'w')
32 _skipDict = {}
33
34 toSkip = _skipDict.has_key
35
36
37 thumb_size = portal.thumb_size
38 ctool = portal.portal_catalog
39 brains = ctool.unrestrictedSearchResults(portal_type='Photo', tiles_available=1)
40 brains = [b for b in brains if not toSkip(b.getPath())]
41
42 while brains :
43 try :
44 for i, b in enumerate(brains) :
45 path = b.getPath()
46 p = b._unrestrictedGetObject()
47
48 print '%d/%d: %s' % (i+1, len(brains), p.absolute_url())
49
50 try :
51 if hasattr(p, 'thumbnail'):
52 print 'make thumbnail'
53 delattr(p, 'thumbnail')
54 p.thumb_width = thumb_size
55 p.thumb_height = thumb_size
56 p.makeThumbnail()
57 transaction.commit()
58
59 for size in ((500, 500), (600, 600), (800, 800)) :
60 index = aggregateIndex(GET_RI_SIGNATURE, (size, True))
61 if p._methodResultsCache['_getResizedImage'].has_key(index) :
62 del p._methodResultsCache['_getResizedImage'][index]
63 print 'resize at', size
64 p._getResizedImage(size, True)
65 transaction.commit()
66
67 zMin = p.tiles_min_zoom
68 zMax = p.tiles_max_zoom
69 zStep = p.tiles_step_zoom
70 levels = range(zMin, zMax + zStep, zStep)
71 zooms = [l/100. for l in levels]
72
73 if p.tileGenerationLock.locked() :
74 print 'skip %s: already tiling.' % p.absolute_url()
75 continue
76
77 p.tileGenerationLock.acquire()
78 try :
79 ppm = p._getPPM()
80 for zoom in zooms :
81
82 print 'tiling at', zoom
83 if zoom < 1 :
84 rppm = ppm.resize(ratio=zoom)
85 else :
86 rppm = ppm
87 p._makeTilesAt(zoom, rppm)
88 del rppm
89 transaction.commit()
90 finally :
91 try : del ppm
92 except UnboundLocalError : pass
93 p.tileGenerationLock.release()
94
95 try :
96 delattr(p, '_v__methodResultsCache')
97 except AttributeError:
98 pass
99
100 _skipDict[path] = True
101 skipFile.write('%s\n' % path)
102
103 except ConflictError :
104 print 'Resync after ZODB ConflicError'
105 transaction.abort()
106 portal._p_jar.sync()
107 brains = ctool.unrestrictedSearchResults(portal_type='Photo', tiles_available=1)
108 brains = [b for b in brains if not toSkip(b.getPath())]
109 break
110
111 except KeyboardInterrupt:
112 raise
113 else :
114 p.tiles_available = 1
115
116 p.reindexObject(idxs=['tiles_available'])
117 transaction.commit()
118 else :
119 print 'queue finished.'
120 break
121
122 except KeyError :
123 print 'Objects deleted during processing'
124 portal._p_jar.sync()
125 brains = ctool.unrestrictedSearchResults(portal_type='Photo', tiles_available=1)
126 brains = [b for b in brains if not toSkip(b.getPath())]
127
128 except ConflictError :
129 print 'Resync after ZODB ConflicError'
130 transaction.abort()
131 portal._p_jar.sync()
132 brains = ctool.unrestrictedSearchResults(portal_type='Photo', tiles_available=1)
133 brains = [b for b in brains if not toSkip(b.getPath())]
134
135 except KeyboardInterrupt:
136 break
137
138 skipFile.close()
139
140
141
142 if __name__ == '__main__':
143 parser = ArgumentParser(description="Thumbnails regeneration")
144 parser.add_argument('portal_path', help='portal object path')
145 parser.add_argument('userid', help='zope user id')
146 parser.add_argument('--skipfile',
147 type=str,
148 required=False,
149 default='skipfile.txt',
150 help="File that log work's progress.")
151 args = parser.parse_args()
152 main(app,
153 args.portal_path,
154 args.userid,
155 args.skipfile)