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