1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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
32 import types
33 import re
34
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 """
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
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
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
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
78 raise e
79 except ValueError, e:
80
81 raise e
82
83
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
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
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
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
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
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
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
181 self.date_created = ''
182 self.date_suspended = ''
183
184 self.status = 'R'
185 self.local_container = ''
186 self.remote_container = ''
187 except IndexError, e:
188
189 raise e
190 except ValueError, e:
191
192 raise e
193
194
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
229 """\
230 Write-protect this session info data structure.
231
232 """
233 self.protected = True
234
236 """\
237 Remove write-protection from this session info data structure.
238
239 """
240 self.protected = False
241
243 """\
244
245 """
246 return self.protected
247
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
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
298 """\
299 Class constructor, identical to L{clear()} method.
300
301 """
302 self.clear()
303
304
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 """
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
334
336 """\
337 Set the sessions property directly by parsing a complete data structure.
338
339 """
340 self.sessions = sessions
341
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
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