1
2 """
3 Library for managing user sessions.
4
5 Copyright 2010 Glencoe Software, Inc. All rights reserved.
6 Use is subject to license terms supplied in LICENSE.txt
7
8 """
9
10 """
11 * Track last used
12 * provide single library (with lock) which does all of this
13 - save session
14 - clear session
15 - check session # detachOnDestroy
16 - list previous sessions
17 * Use an environment variable for changing directories
18
19 import subprocess, optparse, os, sys
20 import getpass, pickle
21 import omero.java
22 from omero.cli import Arguments, BaseControl, VERSION
23 from path import path
24
25 """
26
27 from omero.util import get_user_dir, make_logname
28 from path import path
29
30 import logging
31 import exceptions
32
33
35 """
36 The store is a file-based repository of user sessions.
37 By default, stores use $HOME/omero/sessions as their
38 repository path.
39
40 Use add() to add items to the repository
41 """
42
44 """
45 """
46 self.logger = logging.getLogger(make_logname(self))
47 if dir == None:
48 dir = get_user_dir()
49 self.dir = path(dir) / "omero" / "sessions"
50 if not self.dir.exists():
51 self.dir.makedirs()
52 try:
53 self.dir.chmod(0700)
54 except:
55 print "WARN: failed to chmod %s" % self.dir
56
57
58
59
60
62 """
63 Simple dump utility
64 """
65 for host in self.dir.dirs():
66 print "[%s]" % host
67 for name in host.dirs():
68 print " -> %s : " % name
69 for sess in name.files():
70 print " %s" % sess
71
72 - def add(self, host, name, id, props):
73 """
74 Stores a file containing the properties at
75 REPO/host/name/id
76 """
77
78 props["omero.host"] = host
79 props["omero.user"] = name
80 props["omero.sess"] = id
81
82 lines = []
83 for k,v in props.items():
84 lines.append("%s=%s" % (k, v))
85
86 dhn = self.dir / host / name
87 if not dhn.exists():
88 dhn.makedirs()
89
90 (dhn / id).write_lines(lines)
91 self.set_current(host, name, id)
92
93 - def conflicts(self, host, name, id, new_props, ignore_nulls = False):
94 """
95 Compares if the passed properties are compatible with
96 with those for the host, name, id tuple
97
98 If ignore_nulls is True, then a null in new_props means matches
99 anything.
100 """
101 conflicts = ""
102 old_props = self.get(host, name, id)
103 for key in ("omero.group", "omero.port"):
104 old = old_props.get(key, None)
105 new = new_props.get(key, None)
106 if ignore_nulls and new is None:
107 continue
108 elif old != new:
109 conflicts += (key + (":%s!=%s;" % (old, new)))
110 return conflicts
111
112 - def remove(self, host, name, uuid):
113 """
114 Removes the given session file from the store
115 """
116 (self.dir / host / name / uuid).remove()
117
118 - def get(self, host, name, uuid):
119 """
120 Returns the properties stored in the given session file
121 """
122 return self.props(self.dir / host / name / uuid)
123
125 """
126 Returns the path to property files which are stored.
127 Internal accounting files are not returned.
128 """
129 d = self.dir / host / name
130 if not d.exists():
131 return []
132 return [x.basename() for x in self.non_dot(d)]
133
134 - def set_current(self, host, name = None, uuid = None):
135 """
136 Sets the current session, user, and host files
137 These are used as defaults by other methods.
138 """
139 if host is not None: self.host_file().write_text(host)
140 if name is not None: self.user_file(host).write_text(name)
141 if uuid is not None: self.sess_file(host, name).write_text(uuid)
142
160
162 """
163 Prints either the last saved host (see get_current())
164 or "localhost"
165 """
166 f = self.host_file()
167 if not f.exists():
168 return "localhost"
169 text = f.text().strip()
170 if not text:
171 return "localhost"
172 return text
173
174 - def contents(self):
175 """
176 Returns a map of maps with all the contents
177 of the store. Internal accounting files are
178 skipped.
179 """
180 rv = {}
181 Dhosts = self.dir.dirs()
182 for Dhost in Dhosts:
183 host = str(Dhost.basename())
184 if host not in rv:
185 rv[host] = {}
186 Dnames = Dhost.dirs()
187 for Dname in Dnames:
188 name = str(Dname.basename())
189 if name not in rv[host]:
190 rv[host][name] = {}
191 Dids = self.non_dot(Dname)
192 for Did in Dids:
193 id = str(Did.basename())
194 props = self.props(Did)
195 props["active"] = "unknown"
196 rv[host][name][id] = props
197 return rv
198
199 - def count(self, host=None, name=None):
200 """
201 Returns the sum of all files visited by walk()
202 """
203 def f(h, n, s):
204 f.i += 1
205 f.i = 0
206 self.walk(f, host, name)
207 return f.i
208
209 - def walk(self, func, host=None, name=None, sess=None):
210 """
211 Applies func to all host, name, and session path-objects.
212 """
213 for h in self.dir.dirs():
214 if host is None or str(h.basename()) == host:
215 for n in h.dirs():
216 if name is None or str(n.basename()) == name:
217 for s in self.non_dot(n):
218 if sess is None or str(s.basename()) == sess:
219 func(h, n, s)
220
221
222
223
224
225
226 - def attach(self, server, name, sess):
227 """
228 Simple helper. Delegates to create() using the session
229 as both the username and the password. This reproduces
230 the logic of client.joinSession()
231 """
232 props = self.get(server, name, sess)
233 return self.create(sess, sess, props, new=False)
234
235 - def create(self, name, pasw, props, new=True):
236 """
237 Creates a new omero.client object, and returns:
238 (cilent, session_id, timeToIdle, timeToLive)
239 """
240 import omero.clients
241 props = dict(props)
242 client = omero.client(props)
243 client.setAgent("OMERO.sessions")
244 sf = client.createSession(name, pasw)
245 uuid = sf.ice_getIdentity().name
246 sf.detachOnDestroy()
247 sess = sf.getSessionService().getSession(uuid)
248 timeToIdle = sess.getTimeToIdle().getValue()
249 timeToLive = sess.getTimeToLive().getValue()
250 if new:
251 self.add(props["omero.host"], name, uuid, props)
252 return client, uuid, timeToIdle, timeToLive
253
254 - def clear(self, host = None, name = None, sess = None):
255 """
256 Walks through all sessions and calls killSession.
257 Regardless of exceptions, it will remove the session files
258 from the store.
259 """
260 removed = []
261 def f(h, n, s):
262 hS = str(h.basename())
263 nS = str(n.basename())
264 sS = str(s.basename())
265 try:
266 client = self.attach(hS, nS, sS)
267 client.killSession()
268 except exceptions.Exception, e:
269 self.logger.debug("Exception on killSession: %s" % e)
270 s.remove()
271 removed.append(s)
272 self.walk(f, host, name, sess)
273 return removed
274
275
276
277
278
280 """ Returns the path-object which stores the last active host """
281 return self.dir / "._LASTHOST_"
282
284 """ Returns the path-object which stores the last active user """
285 d = self.dir / host
286 if not d.exists():
287 d.makedirs()
288 return d / "._LASTUSER_"
289
291 """ Returns the path-object which stores the last active session """
292 d = self.dir / host / user
293 if not d.exists():
294 d.makedirs()
295 return d / "._LASTSESS_"
296
298 """ Only returns the files (not directories) contained in d that don't start with a dot """
299 return [f for f in d.files("*") if not str(f.basename()).startswith(".")]
300
302 """
303 Parses the path-object into properties
304 """
305 txt = f.text()
306 lines = txt.split("\n")
307 props = {}
308 for line in lines:
309 if not line:
310 continue
311 parts = line.split("=",1)
312 if len(parts) == 1:
313 parts.append("")
314 props[parts[0]] = parts[1]
315 return props
316
317 if __name__ == "__main__":
318 SessionsStore().report()
319