9c3458063de9bb2c77a3a8f755d65cc5ee321b7a
[Portfolio.git] / ImageManipulationTool.py
1 # -*- coding: utf-8 -*-
2 ############################################################
3 # Copyright © 2005-2008 Benoît PIN <benoit.pin@ensmp.fr> #
4 # Plinn - http://plinn.org #
5 # #
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 manipulation tool
12 $Id: ImageManipulationTool.py 1391 2009-09-16 23:36:05Z pin $
13 $URL: http://svn.luxia.fr/svn/labo/projects/zope/Portfolio/trunk/ImageManipulationTool.py $
14 """
15
16 from AccessControl import ClassSecurityInfo
17 from AccessControl.requestmethod import postonly
18 from Products.PageTemplates.PageTemplateFile import PageTemplateFile
19 from Products.CMFCore.permissions import ManagePortal
20 from AccessControl import getSecurityManager
21 from Globals import InitializeClass
22 from OFS.OrderedFolder import OrderedFolder
23 from Products.CMFCore.utils import UniqueObject
24 from Products.CMFCore.utils import getToolByName
25 from utils import Message as _
26 from manipulation import ImageQueueProcessorThread
27 from Products.MailHost.decorator import synchronized
28 import time
29 from logging import getLogger
30 from threading import Lock
31 import weakref
32 console = getLogger('[portal_image_manipulation]')
33 queue_threads = weakref.WeakValueDictionary()
34
35
36 class ImageManipulationTool( UniqueObject, OrderedFolder) :
37 """ Contains image manipulation plugins
38 """
39
40 id = 'portal_image_manipulation'
41 meta_type = 'Image Manipulation Tool'
42 manage_options = ({'label' : _('Processor'), 'action' : 'manage_processor'}, ) + \
43 OrderedFolder.manage_options
44
45 security = ClassSecurityInfo()
46 lock = Lock()
47
48 security.declareProtected( ManagePortal, 'manage_processor' )
49 manage_processor = PageTemplateFile('www/manageProcessor', globals(),
50 __name__='manage_processor')
51
52 security.declareProtected(ManagePortal, 'manage_startProcess')
53 @postonly
54 def manage_startProcess(self, REQUEST) :
55 ' start processor thread '
56 self._startQueueProcessorThread()
57 return self.manage_processor(self, REQUEST,
58 manage_tabs_message=_('Process started.'))
59
60 security.declareProtected(ManagePortal, 'manage_stopProcess')
61 @postonly
62 def manage_stopProcess(self, REQUEST) :
63 ' stop processor thread '
64 self._stopQueueProcessorThread()
65 return self.manage_processor(self, REQUEST,
66 manage_tabs_message=_('Process stopped.'))
67
68 security.declareProtected(ManagePortal, 'isRunning')
69 def isRunning(self):
70 """ returns boolean telling if the processor thread is running.
71 """
72 path = self.absolute_url(1)
73 if queue_threads.has_key(path):
74 thread = queue_threads[path]
75 return thread.isAlive()
76 else :
77 return False
78
79 security.declareProtected(ManagePortal, 'getQueueSize')
80 def getQueueSize(self):
81 """returns queue size
82 """
83 if self.isRunning() :
84 path = self.absolute_url(1)
85 if queue_threads.has_key(path):
86 thread = queue_threads[path]
87 return thread.queueSize
88
89 return 0
90
91 def _queueAdd(self, itemPath) :
92 if not self.isRunning() :
93 self._startQueueProcessorThread(itemPath)
94 else :
95 path = self.absolute_url(1)
96 thread = queue_threads[path]
97 thread.queueAdd(itemPath)
98
99 @synchronized(lock)
100 def _startQueueProcessorThread(self, itemPath=None):
101 """ Start thread for processing image manipulation """
102
103 if not self.isRunning() :
104 utool = getToolByName(self, 'portal_url')
105 portal = utool.getPortalObject()
106 thread = ImageQueueProcessorThread(portal.getPhysicalPath(), itemPath)
107 thread.start()
108 path = self.absolute_url(1)
109 queue_threads[path] = thread
110 console.info('Thread for %s started' % path)
111
112 @synchronized(lock)
113 def _stopQueueProcessorThread(self):
114 """ Stop thread for processing image manipulation """
115
116 path = self.absolute_url(1)
117 if queue_threads.has_key(path):
118 thread = queue_threads[path]
119 thread.stop()
120 while thread.isAlive():
121 # wait until thread is really dead
122 time.sleep(0.3)
123 del queue_threads[path]
124 console.info('Thread for %s stopped' % path)
125
126 InitializeClass( ImageManipulationTool )