1 # -*- coding: utf-8 -*-
2 ############################################################
3 # Copyright © 2005-2010 Benoît PIN <benoit.pin@ensmp.fr> #
4 # Plinn - http://plinn.org #
6 # This program is free software; you can redistribute it #
7 # and/or modify it under the terms of the Creative Commons #
8 # "Attribution-Noncommercial 2.0 Generic" #
9 # http://creativecommons.org/licenses/by-nc/2.0/ #
10 ############################################################
11 """ Image threaded batch computation module
17 from types
import StringTypes
20 from ZODB
.POSException
import ConflictError
21 from ZODB
.POSException
import ConnectionStateError
22 from zope
.site
.hooks
import setSite
23 from cStringIO
import StringIO
25 console
= logging
.getLogger('[manipulation thread]')
27 class ImageQueueProcessorThread(threading
.Thread
) :
28 """This thread is started at zope startup
34 def __init__(self
, portal_path
, itemsPath
) :
35 threading
.Thread
.__init
__(self
)
36 self
.portal_path
= portal_path
38 if isinstance(itemsPath
, StringTypes
) :
39 itemsPath
= [itemsPath
]
45 return len(self
.queue
)
47 def queueAdd(self
, itemPath
) :
48 self
.queue
.append(itemPath
)
51 console
.info('process started.')
52 #atexit.register(self.stop)
55 portal
= app
.unrestrictedTraverse(self
.portal_path
)
57 while not self
.__stopped
and self
.queueSize
:
63 except ConnectionStateError
, e
:
64 console
.warn('ConnectionStateError raised before finished.')
65 console
.info('process finished.')
69 console
.info('process stopped.')
72 def _process(self
, app
) :
73 path
= self
.queue
.pop(0)
75 p
= app
.unrestrictedTraverse(path
)
77 console
.warn('deleted during processing: %s' % path
)
80 console
.info('%d : %s' % (self
.queueSize
, p
.absolute_url()))
83 if not hasattr(p
, 'thumbnail'):
85 # print 'make thumbnail'
87 for size
in ((500, 500), (600, 600), (800, 800)) :
88 # print 'resize at', size
89 p
._getResizedImage
(size
, True)
92 zMin
= p
.tiles_min_zoom
93 zMax
= p
.tiles_max_zoom
94 zStep
= p
.tiles_step_zoom
95 levels
= range(zMin
, zMax
+ zStep
, zStep
)
96 zooms
= [l
/100. for l
in levels
]
97 todo
= set(zooms
) - set(p
._tiles
.keys())
99 if p
.tileGenerationLock
.locked() :
100 console
.info('skip %s: already tiling.' % p
.absolute_url())
103 p
.tileGenerationLock
.acquire()
111 # print 'tiling at', zoom
113 rppm
= ppm
.resize(ratio
=zoom
)
116 p
._makeTilesAt
(zoom
, rppm
)
121 p
.tileGenerationLock
.release()
124 delattr(p
, '_v__methodResultsCache')
125 except AttributeError:
128 p
.tiles_available
= 1
129 assert p
._getCatalogTool
()
130 p
.reindexObject(idxs
=['tiles_available'])
133 except ConflictError
:
134 console
.warn('Resync after ZODB ConflicError')
136 portal
= app
.unrestrictedTraverse(self
.portal_path
)
141 p
.tiles_available
= -1
144 traceback
.print_exc(None, out
)
145 console
.error(out
.getvalue())