Package x2go :: Package backends :: Package info :: Module plain
[frames] | no frames]

Source Code for Module x2go.backends.info.plain

  1  # -*- coding: utf-8 -*- 
  2   
  3  # Copyright (C) 2010-2015 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  X2GoServerSessionList and X2GoServerSessionInfo classes - data handling for  
 22  X2Go server sessions. 
 23   
 24  This backend handles X2Go server implementations that respond with session infos  
 25  via server-side PLAIN text output. 
 26   
 27  """ 
 28  __NAME__ = 'x2goserversessioninfo-pylib' 
 29   
 30   
 31  # modules 
 32  import types 
 33  import re 
 34   
35 -class X2GoServerSessionInfo(object):
36 """\ 37 L{X2GoServerSessionInfo} is used to store all information 38 that is retrieved from the connected X2Go server on 39 C{X2GoTerminalSession.start()} resp. C{X2GoTerminalSession.resume()}. 40 41 """
42 - def __str__(self):
43 return self.name
44 - def __repr__(self):
45 result = 'X2GoServerSessionInfo(' 46 for p in dir(self): 47 if '__' in p or not p in self.__dict__ or type(p) is types.InstanceType: continue 48 result += p + '=' + str(self.__dict__[p]) +',' 49 return result.strip(',') + ')'
50
51 - def _parse_x2golistsessions_line(self, x2go_output):
52 """\ 53 Parse a single line of X2Go's listsessions output. 54 55 @param x2go_output: output from ,,x2golistsessions'' command (as list of strings/lines) 56 @type x2go_output: C{list} 57 58 """ 59 try: 60 l = x2go_output.split("|") 61 self.agent_pid = int(l[0]) 62 self.name = l[1] 63 self.display = int(l[2]) 64 self.hostname = l[3] 65 self.status = l[4] 66 # TODO: turn into datetime object 67 self.date_created = l[5] 68 self.cookie = l[6] 69 self.graphics_port = int(l[8]) 70 self.snd_port = int(l[9]) 71 # TODO: turn into datetime object 72 self.date_suspended = l[10] 73 self.username = l[11] 74 self.sshfs_port = int(l[13]) 75 self.local_container = '' 76 except IndexError, e: 77 # DEBUGGING CODE 78 raise e 79 except ValueError, e: 80 # DEBUGGING CODE 81 raise e 82 83 # retrieve Telekinesis ports from list of sessions... 84 try: 85 self.tekictrl_port = int(l[14]) 86 except (IndexError, ValueError), e: 87 self.tekictrl_port = -1 88 try: 89 self.tekidata_port = int(l[15]) 90 except (IndexError, ValueError), e: 91 self.tekidata_port = -1
92
94 """\ 95 Detect from session info if this session is a published applications provider. 96 97 @return: returns C{True} if this session is a published applications provider 98 @rtype: C{bool} 99 100 """ 101 return bool(re.match('.*_stRPUBLISHED_.*', self.name))
102
103 - def is_running(self):
104 """\ 105 Is this session running? 106 107 @return: C{True} if the session is running, C{False} otherwise 108 @rtype: C{bool} 109 110 """ 111 return self.status == 'R'
112
113 - def get_session_type(self):
114 """\ 115 Get the session type (i.e. 'D', 'R', 'S' or 'P'). 116 117 @return: session type 118 @rtype: C{str} 119 """ 120 cmd = self.name.split('_')[1] 121 session_type = cmd[2] 122 if session_type == 'R' and self.is_published_applications_provider(): 123 session_type = 'P' 124 return session_type
125
126 - def get_share_mode(self):
127 """\ 128 Get the share mode of a shadow session. 129 130 @return: share mode (0: view-only, 1: full access), C{None} when used for non-desktop-sharing sessions 131 @rtype: C{str} 132 133 """ 134 share_mode = None 135 cmd = self.name.split('_')[1] 136 session_type = cmd[2] 137 if session_type == 'S': 138 share_mode = cmd[3] 139 return share_mode
140
141 - def is_suspended(self):
142 """\ 143 Is this session suspended? 144 145 @return: C{True} if the session is suspended, C{False} otherwise 146 @rtype: C{bool} 147 148 """ 149 return self.status == 'S'
150
151 - def is_desktop_session(self):
152 """\ 153 Is this session a desktop session? 154 155 @return: C{True} if this session is a desktop session, C{False} otherwise 156 @rtype: C{bool} 157 158 """ 159 return self.get_session_type() == 'D'
160
161 - def _parse_x2gostartagent_output(self, x2go_output):
162 """\ 163 Parse x2gostartagent output. 164 165 @param x2go_output: output from ,,x2gostartagent'' command (as list of strings/lines) 166 @type x2go_output: C{list} 167 168 """ 169 try: 170 l = x2go_output.split("\n") 171 self.name = l[3] 172 self.cookie = l[1] 173 self.agent_pid = int(l[2]) 174 self.display = int(l[0]) 175 self.graphics_port = int(l[4]) 176 self.snd_port = int(l[5]) 177 self.sshfs_port = int(l[6]) 178 self.username = '' 179 self.hostname = '' 180 # TODO: we have to see how we fill these fields here... 181 self.date_created = '' 182 self.date_suspended = '' 183 # TODO: presume session is running after x2gostartagent, this could be better 184 self.status = 'R' 185 self.local_container = '' 186 self.remote_container = '' 187 except IndexError, e: 188 # DEBUGGING CODE 189 raise e 190 except ValueError, e: 191 # DEBUGGING CODE 192 raise e 193 194 # retrieve Telekinesis ports from x2gostartagent output 195 try: 196 self.tekictrl_port = int(l[7]) 197 except (IndexError, ValueError), e: 198 self.tekictrl_port = -1 199 try: 200 self.tekidata_port = int(l[8]) 201 except (IndexError, ValueError), e: 202 self.tekidata_port = -1
203
204 - def initialize(self, x2go_output, username='', hostname='', local_container='', remote_container=''):
205 """\ 206 Setup a a session info data block, includes parsing of X2Go server's C{x2gostartagent} stdout values. 207 208 @param x2go_output: X2Go server's C{x2gostartagent} command output, each value 209 separated by a newline character. 210 @type x2go_output: str 211 @param username: session user name 212 @type username: str 213 @param hostname: hostname of X2Go server 214 @type hostname: str 215 @param local_container: X2Go client session directory for config files, cache and session logs 216 @type local_container: str 217 @param remote_container: X2Go server session directory for config files, cache and session logs 218 @type remote_container: str 219 220 """ 221 self.protect() 222 self._parse_x2gostartagent_output(x2go_output) 223 self.username = username 224 self.hostname = hostname 225 self.local_container = local_container 226 self.remote_container = remote_container
227
228 - def protect(self):
229 """\ 230 Write-protect this session info data structure. 231 232 """ 233 self.protected = True
234
235 - def unprotect(self):
236 """\ 237 Remove write-protection from this session info data structure. 238 239 """ 240 self.protected = False
241
242 - def is_protected(self):
243 """\ 244 245 """ 246 return self.protected
247
248 - def get_status(self):
249 """\ 250 Retrieve the session's status from this session info data structure. 251 252 @return: session status 253 @rtype: C{str} 254 255 """ 256 return self.status
257
258 - def clear(self):
259 """\ 260 Clear all properties of a L{X2GoServerSessionInfo} object. 261 262 """ 263 self.name = '' 264 self.cookie = '' 265 self.agent_pid = '' 266 self.display = '' 267 self.graphics_port = '' 268 self.snd_port = '' 269 self.sshfs_port = '' 270 self.tekictrl_port = '' 271 self.tekidata_port = '' 272 self.username = '' 273 self.hostname = '' 274 self.date_created = '' 275 self.date_suspended = '' 276 self.status = '' 277 self.local_container = '' 278 self.remote_container = '' 279 self.protected = False
280
281 - def update(self, session_info):
282 """\ 283 Update all properties of a L{X2GoServerSessionInfo} object. 284 285 @param session_info: a provided session info data structure 286 @type session_info: C{X2GoServerSessionInfo*} 287 288 """ 289 if type(session_info) == type(self): 290 for prop in ('graphics_port', 'snd_port', 'sshfs_port', 'tekictrl_port', 'tekidata_port', 'date_suspended', 'status', ): 291 if hasattr(session_info, prop): 292 _new = getattr(session_info, prop) 293 _current = getattr(self, prop) 294 if _new != _current: 295 setattr(self, prop, _new)
296
297 - def __init__(self):
298 """\ 299 Class constructor, identical to L{clear()} method. 300 301 """ 302 self.clear()
303 304
305 -class X2GoServerSessionList(object):
306 """\ 307 L{X2GoServerSessionList} is used to store all information 308 that is retrieved from a connected X2Go server on a 309 C{X2GoControlSession.list_sessions()} call. 310 311 """
312 - def __init__(self, x2go_output=None, info_backend=X2GoServerSessionInfo):
313 """\ 314 @param x2go_output: X2Go server's C{x2golistsessions} command output, each 315 session separated by a newline character. Session values are separated 316 by Unix Pipe Symbols ('|') 317 @type x2go_output: str 318 @param info_backend: the session info backend to use 319 @type info_backend: C{X2GoServerSessionInfo*} 320 321 """ 322 self.sessions = {} 323 if x2go_output is not None: 324 lines = x2go_output.split("\n") 325 for line in lines: 326 if not line: 327 continue 328 s_info = info_backend() 329 s_info._parse_x2golistsessions_line(line) 330 self.sessions[s_info.name] = s_info
331
332 - def __call__(self):
333 return self.sessions
334
335 - def set_sessions(self, sessions):
336 """\ 337 Set the sessions property directly by parsing a complete data structure. 338 339 """ 340 self.sessions = sessions
341
342 - def get_session_info(self, session_name):
343 """\ 344 Retrieve the session information for C{<session_name>}. 345 346 @param session_name: the queried session name 347 @type session_name: C{str} 348 349 @return: the session info of C{<session_name>} 350 @rtype: C{X2GoServerSessionInfo*} or C{None} 351 352 """ 353 try: 354 return self.sessions[session_name] 355 except KeyError: 356 return None
357
358 - def get_session_with(self, property_name, value, hostname=None):
359 """\ 360 Find session with a given display number on a given host. 361 362 @param property_name: match a session based on this property name 363 @type property_name: C{str} 364 @param value: the resulting session has to match this value for C{<property_name>} 365 @type value: C{str} 366 @param hostname: the result has to match this hostname 367 @type hostname: C{str} 368 369 """ 370 if property_name == 'display': 371 value = value.lstrip(':') 372 if '.' in value: value = value.split('.')[0] 373 374 for session in self.sessions.values(): 375 try: 376 if str(getattr(session, property_name)) == str(value): 377 if hostname is None or session.hostname == hostname: 378 return session 379 except AttributeError: 380 pass
381