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

Source Code for Module x2go.mimebox

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