Package x2go :: Module mimebox
[frames] | no frames]

Source Code for Module x2go.mimebox

  1  # -*- coding: utf-8 -*- 
  2   
  3  # Copyright (C) 2010-2014 by Mike Gabriel <mike.gabriel@das-netzwerkteam.de> 
  4  # 
  5  # Python X2Go is free software; you can redistribute it and/or modify 
  6  # it under the terms of the GNU Affero General Public License as published by 
  7  # the Free Software Foundation; either version 3 of the License, or 
  8  # (at your option) any later version. 
  9  # 
 10  # Python X2Go is distributed in the hope that it will be useful, 
 11  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
 12  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 13  # GNU Affero General Public License for more details. 
 14  # 
 15  # You should have received a copy of the GNU Affero General Public License 
 16  # along with this program; if not, write to the 
 17  # Free Software Foundation, Inc., 
 18  # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. 
 19   
 20  """\ 
 21  L{X2GoMIMEboxQueue} sets up a thread that listens for incoming files that 
 22  shall be opened locally on the client. 
 23   
 24  For each file that gets dropped in the MIME box an individual  
 25  thread is started (L{X2GoMIMEboxJob}) that handles the processing  
 26  of the incoming file. 
 27   
 28  """ 
 29  __NAME__ = 'x2gomimeboxqueue-pylib' 
 30   
 31  # modules 
 32  import os 
 33  import copy 
 34  import types 
 35  import threading 
 36  import gevent 
 37   
 38  # Python X2Go modules 
 39  import defaults 
 40  import utils 
 41  import log 
 42  import mimeboxactions 
43 44 45 -class X2GoMIMEboxQueue(threading.Thread):
46 """\ 47 If the X2Go MIME box is supported in a particaluar L{X2GoSession} instance 48 this class provides a sub-thread for handling incoming files in the MIME box 49 directory. The actual handling of a dropped file is handled by the classes 50 L{X2GoMIMEboxActionOPEN}, L{X2GoMIMEboxActionOPENWITH} and L{X2GoMIMEboxActionSAVEAS}. 51 52 """ 53 mimebox_action = None 54 55 mimebox = None 56 active_jobs = {} 57 mimebox_history = [] 58
59 - def __init__(self, profile_name='UNKNOWN', session_name='UNKNOWN', 60 mimebox_dir=None, mimebox_action=None, mimebox_extensions=[], 61 client_instance=None, logger=None, loglevel=log.loglevel_DEFAULT):
62 """\ 63 @param profile_name: name of the session profile this print queue belongs to 64 @type profile_name: C{str} 65 @param mimebox_dir: local directory for incoming MIME box files 66 @type mimebox_dir: C{str} 67 @param mimebox_action: name or instance of either of the possible X2Go print action classes 68 @type mimebox_action: C{str} or instance 69 @param client_instance: the underlying L{X2GoClient} instance 70 @type client_instance: C{obj} 71 @param logger: you can pass an L{X2GoLogger} object to the 72 L{X2GoPrintQueue} constructor 73 @type logger: C{obj} 74 @param loglevel: if no L{X2GoLogger} object has been supplied a new one will be 75 constructed with the given loglevel 76 @type loglevel: C{int} 77 78 """ 79 if logger is None: 80 self.logger = log.X2GoLogger(loglevel=loglevel) 81 else: 82 self.logger = copy.deepcopy(logger) 83 self.logger.tag = __NAME__ 84 85 self.profile_name = profile_name 86 self.session_name = session_name 87 self.mimebox_dir = mimebox_dir 88 if self.mimebox_dir: self.mimebox_dir = os.path.normpath(self.mimebox_dir) 89 self.mimebox_extensions = mimebox_extensions 90 self.client_instance = client_instance 91 self.client_rootdir = client_instance.get_client_rootdir() 92 93 # this has to be set before we set the MIME box action... 94 self._accept_jobs = False 95 96 if mimebox_action is None: 97 mimebox_action = mimeboxactions.X2GoMIMEboxActionOPEN(client_instance=self.client_instance, logger=self.logger) 98 elif type(mimebox_action) in (types.StringType, types.UnicodeType): 99 mimebox_action = self.set_mimebox_action(mimebox_action, client_instance=self.client_instance, logger=self.logger) 100 else: 101 # hope it's already an instance... 102 self.mimebox_action = mimebox_action 103 104 threading.Thread.__init__(self) 105 self.daemon = True 106 self._accept_jobs = True
107 108
109 - def __del__(self):
110 """\ 111 Class destructor. 112 113 """ 114 self.stop_thread()
115
116 - def pause(self):
117 """\ 118 Prevent acceptance of new incoming files. The processing of MIME box jobs that 119 are currently still active will be completed, though. 120 121 """ 122 if self._accept_jobs == True: 123 self._accept_jobs = False 124 self.logger('paused thread: %s' % repr(self), loglevel=log.loglevel_DEBUG)
125
126 - def resume(self):
127 """\ 128 Resume operation of the X2Go MIME box queue and continue accepting new incoming 129 files. 130 131 """ 132 if self._accept_jobs == False: 133 self._accept_jobs = True 134 self.logger('resumed thread: %s' % repr(self), loglevel=log.loglevel_DEBUG)
135
136 - def stop_thread(self):
137 """\ 138 Stops this L{X2GoMIMEboxQueue} thread completely. 139 140 """ 141 self.pause() 142 self._keepalive = False 143 self.logger('stopping thread: %s' % repr(self), loglevel=log.loglevel_DEBUG)
144 145 @property
146 - def _incoming_mimebox_jobs(self):
147 if os.path.exists(self.mimebox_dir): 148 l = os.listdir(self.mimebox_dir) 149 mimebox_jobs = [] 150 for _ext in self.mimebox_extensions: 151 mimebox_jobs.extend([ dj for dj in l if dj.upper().endswith(_ext.upper()) ]) 152 else: 153 mimebox_jobs = l 154 return [ dj for dj in mimebox_jobs if dj not in self.active_jobs.keys() ] 155 else: 156 return []
157
158 - def set_mimebox_action(self, mimebox_action, **kwargs):
159 """\ 160 Modify the MIME box action of this L{X2GoMIMEboxQueue} thread during runtime. The 161 change of the MIME box action will be valid for the next incoming file in the MIME box 162 directory. 163 164 @param mimebox_action: the MIME box action to execute for incoming files 165 @type mimebox_action: C{str} or C{obj} 166 @param kwargs: extra options for the specified MIME box action 167 @type kwargs: C{dict} 168 169 """ 170 if mimebox_action in defaults.X2GO_MIMEBOX_ACTIONS.keys(): 171 mimebox_action = defaults.X2GO_MIMEBOX_ACTIONS[mimebox_action] 172 173 if mimebox_action in defaults.X2GO_MIMEBOX_ACTIONS.values(): 174 self.mimebox_action = eval ('mimeboxactions.%s(**kwargs)' % mimebox_action)
175
176 - def run(self):
177 """\ 178 This method gets called once the L{X2GoMIMEboxQueue} thread is started by the C{X2GoMIMEboxQueue.start()} method. 179 180 """ 181 self.logger('starting MIME box queue thread: %s' % repr(self), loglevel=log.loglevel_DEBUG) 182 183 self._keepalive = True 184 while self._keepalive: 185 186 while self._accept_jobs: 187 188 if self._incoming_mimebox_jobs: 189 190 for _job in self._incoming_mimebox_jobs: 191 self.logger('processing incoming X2Go MIME box job: %s' % _job, loglevel=log.loglevel_NOTICE) 192 _new_mimeboxjob_thread = X2GoMIMEboxJob(target=x2go_mimeboxjob_handler, 193 kwargs={ 194 'mimebox_file': _job, 195 'mimebox_extensions': self.mimebox_extensions, 196 'mimebox_action': self.mimebox_action, 197 'parent_thread': self, 198 'logger': self.logger, 199 } 200 ) 201 self.active_jobs['%s' % _job] = _new_mimeboxjob_thread 202 _new_mimeboxjob_thread.start() 203 204 gevent.sleep(3) 205 206 gevent.sleep(1)
207
208 209 -def x2go_mimeboxjob_handler(mimebox_file=None, 210 mimebox_extensions=[], 211 mimebox_action=None, 212 parent_thread=None, logger=None, ):
213 """\ 214 This function is called as a handler function for each incoming X2Go MIME box file 215 represented by the class L{X2GoMIMEboxJob}. 216 217 @param mimebox_file: MIME box file name as placed in to the X2Go MIME box spool directory 218 @type mimebox_file: C{str} 219 @param mimebox_action: an instance of either of the possible C{X2GoMIMEboxActionXXX} classes 220 @type mimebox_action: C{X2GoMIMEboxActionXXX} nstance 221 @param parent_thread: the L{X2GoMIMEboxQueue} thread that actually created this handler's L{X2GoMIMEboxJob} instance 222 @type parent_thread: C{obj} 223 @param logger: the L{X2GoMIMEboxQueue}'s logging instance 224 @type logger: C{obj} 225 226 """ 227 mimebox_action.profile_name = parent_thread.profile_name 228 mimebox_action.session_name = parent_thread.session_name 229 230 logger('action for printing is: %s' % mimebox_action, loglevel=log.loglevel_DEBUG) 231 232 _dotfile = mimebox_file.startswith('.') 233 _blacklisted = mimebox_file.upper().split('.')[-1] in defaults.X2GO_MIMEBOX_EXTENSIONS_BLACKLIST 234 _really_process = bool(not _blacklisted and ((not mimebox_extensions) or [ ext for ext in mimebox_extensions if mimebox_file.upper().endswith('%s' % ext.upper()) ])) 235 if _really_process and not _blacklisted and not _dotfile: 236 mimebox_action.do_process(mimebox_file=mimebox_file, 237 mimebox_dir=parent_thread.mimebox_dir, 238 ) 239 elif not _blacklisted and not _dotfile: 240 logger('file extension of MIME box file %s is prohibited by session profile configuration' % mimebox_file, loglevel=log.loglevel_NOTICE) 241 elif _dotfile: 242 logger('placing files starting with a dot (.<file>) into the X2Go MIME box is prohibited, ignoring the file ,,%s\'\'' % mimebox_file, loglevel=log.loglevel_WARN) 243 else: 244 logger('file extension of MIME box file %s has been found in Python X2Go\' hardcoded MIME box extenstions blacklist' % mimebox_file, loglevel=log.loglevel_WARN) 245 246 logger('removing MIME box file %s' % mimebox_file, loglevel=log.loglevel_DEBUG) 247 248 utils.patiently_remove_file(parent_thread.mimebox_dir, mimebox_file) 249 logger('removed print job file %s' % mimebox_file, loglevel=log.loglevel_DEBUG) 250 251 del parent_thread.active_jobs['%s' % mimebox_file] 252 parent_thread.mimebox_history.append(mimebox_file) 253 # in case we do a lot of mimebox file exports we do not want to risk an 254 # endlessly growing mimebox job history 255 if len(parent_thread.mimebox_history) > 100: 256 parent_thread.mimebox_history = parent_thread.mimebox_history[-100:]
257
258 259 -class X2GoMIMEboxJob(threading.Thread):
260 """\ 261 For each X2Go MIME box job we create a sub-thread that let's 262 the MIME box job be processed in the background. 263 264 As a handler for this class the function L{x2go_mimeboxjob_handler()} 265 is used. 266 267 """
268 - def __init__(self, **kwargs):
269 """\ 270 Construct the X2Go MIME box job thread... 271 272 All parameters (**kwargs) are passed through to the constructor 273 of C{threading.Thread()}. 274 275 """ 276 threading.Thread.__init__(self, **kwargs) 277 self.daemon = True
278