X-Git-Url: https://svn.cri.ensmp.fr/git/Portfolio.git/blobdiff_plain/011a53d5681ad1f5fa88a534ec041c93d3e7be95..06d12e5d89cad3da647c74de04ee8375a88ecc59:/manipulation.py?ds=sidebyside diff --git a/manipulation.py b/manipulation.py index e27ab1e..af010a5 100755 --- a/manipulation.py +++ b/manipulation.py @@ -1,137 +1,145 @@ # -*- coding: utf-8 -*- -#################################################### -# Copyright © 2009 Luxia SAS. All rights reserved. # -# # -# Contributors: # -# - Benoît Pin # -#################################################### +############################################################ +# Copyright © 2005-2010 Benoît PIN # +# Plinn - http://plinn.org # +# # +# This program is free software; you can redistribute it # +# and/or modify it under the terms of the Creative Commons # +# "Attribution-Noncommercial 2.0 Generic" # +# http://creativecommons.org/licenses/by-nc/2.0/ # +############################################################ """ Image threaded batch computation module - -$Id: manipulation.py 1391 2009-09-16 23:36:05Z pin $ -$URL: http://svn.luxia.fr/svn/labo/projects/zope/Portfolio/trunk/manipulation.py $ """ import threading import logging import atexit -import time -import Zope2 +from types import StringTypes from math import ceil import transaction from ZODB.POSException import ConflictError +from ZODB.POSException import ConnectionStateError +from zope.site.hooks import setSite from cStringIO import StringIO console = logging.getLogger('[manipulation thread]') class ImageQueueProcessorThread(threading.Thread) : - """This thread is started at zope startup - """ - - __stopped = False + """This thread is started at zope startup + """ - def __init__(self, portal_path, itemPath): - threading.Thread.__init__(self) - self.app = app = Zope2.app() - self.portal = portal = app.unrestrictedTraverse(portal_path) - self.imgTool = portal.portal_image_manipulation - self.queue = [] - if itemPath : - self.queueAdd(itemPath) - else : - ctool = portal.portal_catalog - brains = ctool.unrestrictedSearchResults(portal_type='Photo', tiles_available=0) - for b in brains : - self.queueAdd(b.getPath()) - - @property - def queueSize(self) : - return len(self.queue) - - def queueAdd(self, itemPath) : - self.queue.append(itemPath) + __stopped = False + + + def __init__(self, portal_path, itemsPath) : + threading.Thread.__init__(self) + self.portal_path = portal_path + self.queue = [] + if isinstance(itemsPath, StringTypes) : + itemsPath = [itemsPath] + for i in itemsPath : + self.queueAdd(i) + + @property + def queueSize(self) : + return len(self.queue) + + def queueAdd(self, itemPath) : + self.queue.append(itemPath) - def run(self) : - console.info('process started.') - atexit.register(self.stop) - while not self.__stopped and self.queueSize : - self._process() - console.info('process finished.') + def run(self) : + console.info('process started.') + #atexit.register(self.stop) + import Zope2 + app = Zope2.app() + portal = app.unrestrictedTraverse(self.portal_path) + setSite(portal) + while not self.__stopped and self.queueSize : + self._process(app) + + con = app._p_jar + try : + con.close() + except ConnectionStateError, e : + console.warn('ConnectionStateError raised before finished.') + console.info('process finished.') + - def stop(self): - console.info('process stopped.') - self.__stopped = True - - def _process(self) : - - path = self.queue.pop(0) - - try : - p = self.app.unrestrictedTraverse(path) - except KeyError : - console.warn('deleted during processing: %s' % path) - return - - console.info('%d : %s' % (self.queueSize, p.absolute_url())) + def stop(self): + console.info('process stopped.') + self.__stopped = True + + def _process(self, app) : + path = self.queue.pop(0) + try : + p = app.unrestrictedTraverse(path) + except KeyError : + console.warn('deleted during processing: %s' % path) + return + + console.info('%d : %s' % (self.queueSize, p.absolute_url())) - try : - if not hasattr(p, 'thumbnail'): - p.makeThumbnail() - # print 'make thumbnail' + try : + if not hasattr(p, 'thumbnail'): + p.makeThumbnail() + # print 'make thumbnail' - for size in ((500, 500), (600, 600), (800, 800)) : - # print 'resize at', size - p._getResizedImage(size, True) - transaction.commit() - - zMin = p.tiles_min_zoom - zMax = p.tiles_max_zoom - zStep = p.tiles_step_zoom - levels = range(zMin, zMax + zStep, zStep) - zooms = [l/100. for l in levels] - todo = set(zooms) - set(p._tiles.keys()) - if todo : - if p.tileGenerationLock.locked() : - console.info('skip %s: already tiling.' % p.absolute_url()) - return - - p.tileGenerationLock.acquire() - zooms = list(todo) - zooms.sort() - ppm = None - try : - ppm = p._getPPM() - for zoom in zooms : - - # print 'tiling at', zoom - if zoom < 1 : - rppm = ppm.resize(ratio=zoom) - else : - rppm = ppm - p._makeTilesAt(zoom, rppm) - del rppm - transaction.commit() - finally : - del ppm - p.tileGenerationLock.release() - - try : - delattr(p, '_v__methodResultsCache') - except AttributeError: - pass - - p.tiles_available = 1 - p.reindexObject(idxs=['tiles_available']) - transaction.commit() + for size in ((500, 500), (600, 600), (800, 800)) : + # print 'resize at', size + p._getResizedImage(size, True) + transaction.commit() + + zMin = p.tiles_min_zoom + zMax = p.tiles_max_zoom + zStep = p.tiles_step_zoom + levels = range(zMin, zMax + zStep, zStep) + zooms = [l/100. for l in levels] + todo = set(zooms) - set(p._tiles.keys()) + if todo : + if p.tileGenerationLock.locked() : + console.info('skip %s: already tiling.' % p.absolute_url()) + return + + p.tileGenerationLock.acquire() + zooms = list(todo) + zooms.sort() + ppm = None + try : + ppm = p._getPPM() + for zoom in zooms : + + # print 'tiling at', zoom + if zoom < 1 : + rppm = ppm.resize(ratio=zoom) + else : + rppm = ppm + p._makeTilesAt(zoom, rppm) + del rppm + transaction.commit() + finally : + del ppm + p.tileGenerationLock.release() + + try : + delattr(p, '_v__methodResultsCache') + except AttributeError: + pass + + p.tiles_available = 1 + assert p._getCatalogTool() + p.reindexObject(idxs=['tiles_available']) + transaction.commit() - except ConflictError : - console.warn('Resync after ZODB ConflicError') - transaction.abort() - self.portal._p_jar.sync() - self.queueAdd(path) - return - except : - p.tiles_available = -1 - import traceback - out = StringIO() - traceback.print_exc(None, out) - console.error(out.getvalue()) + except ConflictError : + console.warn('Resync after ZODB ConflicError') + transaction.abort() + portal = app.unrestrictedTraverse(self.portal_path) + portal._p_jar.sync() + self.queueAdd(path) + return + except : + p.tiles_available = -1 + import traceback + out = StringIO() + traceback.print_exc(None, out) + console.error(out.getvalue())