Package omeroweb :: Package webgateway :: Module views
[hide private]
[frames] | no frames]

Source Code for Module omeroweb.webgateway.views

   1  # 
   2  # webgateway/views.py - django application view handling functions 
   3  #  
   4  # Copyright (c) 2007, 2008, 2009 Glencoe Software, Inc. All rights reserved. 
   5  #  
   6  # This software is distributed under the terms described by the LICENCE file 
   7  # you can find at the root of the distribution bundle, which states you are 
   8  # free to use it only for non commercial purposes. 
   9  # If the file is missing please request a copy by contacting 
  10  # jason@glencoesoftware.com. 
  11  # 
  12  # Author: Carlos Neves <carlos(at)glencoesoftware.com> 
  13   
  14  import omero 
  15  import omero.clients 
  16  from django.http import HttpResponse, HttpResponseServerError, HttpResponseRedirect, Http404 
  17  from django.utils import simplejson 
  18  from django.utils.http import urlquote 
  19  from django.core import template_loader 
  20  from django.core.urlresolvers import reverse 
  21  from django.template import RequestContext as Context 
  22   
  23  try: 
  24      from hashlib import md5 
  25  except: 
  26      from md5 import md5 
  27       
  28  from cStringIO import StringIO 
  29   
  30  from omero import client_wrapper, ApiUsageException 
  31  from omero.gateway import timeit, TimeIt 
  32   
  33  import Ice 
  34   
  35  #from models import StoredConnection 
  36   
  37  from webgateway_cache import webgateway_cache, CacheBase, webgateway_tempfile 
  38   
  39  cache = CacheBase() 
  40   
  41  connectors = {} 
  42  CONNECTOR_POOL_SIZE = 70 
  43  CONNECTOR_POOL_KEEP = 0.75 # keep only SIZE-SIZE*KEEP of the connectors if POOL_SIZE is reached 
  44   
  45  import logging, os, traceback, time, zipfile, shutil 
  46   
  47  #omero.gateway.BlitzGateway.ICE_CONFIG = os.environ.get('ICE_CONFIG', 'etc/ice.config') 
  48   
  49  logger = logging.getLogger('webgateway') 
  50   
  51  logger.debug("INIT") 
52 53 -def _session_logout (request, server_id, force_key=None):
54 """ 55 Remove reference to old sUuid key and old blitz connection. 56 57 @param request: http request 58 @param server_id: used to generate session_key 59 @param force_key: If specified, use this as session_key 60 """ 61 62 if force_key: 63 session_key = force_key 64 else: 65 browsersession_connection_key = 'cuuid#%s'%server_id 66 session_key = 'S:' + request.session.get(browsersession_connection_key,'') + '#' + str(server_id) 67 if request.session.has_key(browsersession_connection_key): 68 logger.debug('logout: removing "%s"' % (request.session[browsersession_connection_key])) 69 del request.session[browsersession_connection_key] 70 for k in ('username', 'password', 'server', 'host', 'port', 'ssl'): 71 if request.session.has_key(k): 72 del request.session[k] 73 if connectors.has_key(session_key): 74 logger.debug('logout: killing connection "%s"' % (session_key)) 75 if connectors[session_key]: 76 logger.info('logout request for "%s"' % connectors[session_key].getUser().omeName) 77 connectors[session_key] and connectors[session_key].seppuku() 78 del connectors[session_key]
79
80 -class UserProxy (object):
81 """ 82 Represents the current user of the connection, with methods delegating to the connection itself. 83 """ 84
85 - def __init__ (self, blitzcon):
86 """ 87 Initialises the User proxy with the L{omero.gateway.BlitzGateway} connection 88 89 @param blitzcon: connection 90 @type blitzcon: L{omero.gateway.BlitzGateway} 91 """ 92 93 self._blitzcon = blitzcon 94 self.loggedIn = False
95
96 - def logIn (self):
97 """ Sets the loggedIn Flag to True """ 98 99 self.loggedIn = True
100
101 - def isAdmin (self):
102 """ 103 True if the current user is an admin 104 105 @return: True if the current user is an admin 106 @rtype: Boolean 107 """ 108 109 return self._blitzcon.isAdmin()
110
111 - def canBeAdmin (self):
112 """ 113 True if the current user can be admin 114 115 @return: True if the current user can be admin 116 @rtype: Boolean 117 """ 118 119 return self._blitzcon.canBeAdmin()
120
121 - def getId (self):
122 """ 123 Returns the ID of the current user 124 125 @return: User ID 126 @rtype: Long 127 """ 128 129 return self._blitzcon._user.id
130
131 - def getName (self):
132 """ 133 Returns the Name of the current user 134 135 @return: User Name 136 @rtype: String 137 """ 138 139 return self._blitzcon._user.omeName
140
141 - def getFirstName (self):
142 """ 143 Returns the first name of the current user 144 145 @return: First Name 146 @rtype: String 147 """ 148 149 return self._blitzcon._user.firstName or self.getName()
150
151 # def getPreferences (self): 152 # return self._blitzcon._user.getPreferences() 153 # 154 # def getUserObj (self): 155 # return self._blitzcon._user 156 157 #class SessionCB (object): 158 # def _log (self, what, c): 159 # logger.debug('CONN:%s %s:%d:%s' % (what, c._user, os.getpid(), c._sessionUuid)) 160 # 161 # def create (self, c): 162 # self._log('create',c) 163 # 164 # def join (self, c): 165 # self._log('join',c) 166 # 167 # def close (self, c): 168 # self._log('close',c) 169 #_session_cb = SessionCB() 170 171 -def _createConnection (server_id, sUuid=None, username=None, passwd=None, host=None, port=None, retry=True, group=None, try_super=False, secure=False, anonymous=False, useragent=None):
172 """ 173 Attempts to create a L{omero.gateway.BlitzGateway} connection. 174 Tries to join an existing session for the specified user, using sUuid. 175 176 @param server_id: Way of referencing the server, used in connection dict keys. Int or String 177 @param sUuid: Session ID - used for attempts to join sessions etc without password 178 @param username: User name to log on with 179 @param passwd: Password 180 @param host: Host name 181 @param port: Port number 182 @param retry: Boolean 183 @param group: String? TODO: parameter is ignored. 184 @param try_super: If True, try to log on as super user, 'system' group 185 @param secure: If True, use an encrypted connection 186 @param anonymous: Boolean 187 @param useragent: Log which python clients use this connection. E.g. 'OMERO.webadmin' 188 @return: The connection 189 @rtype: L{omero.gateway.BlitzGateway} 190 """ 191 try: 192 blitzcon = client_wrapper(username, passwd, host=host, port=port, group=None, try_super=try_super, secure=secure, anonymous=anonymous, useragent=useragent) 193 blitzcon.connect(sUuid=sUuid) 194 blitzcon.server_id = server_id 195 blitzcon.user = UserProxy(blitzcon) 196 if blitzcon._anonymous and hasattr(blitzcon.c, 'onEventLogs'): 197 logger.debug('Connecting weblitz_cache to eventslog') 198 def eventlistener (e): 199 return webgateway_cache.eventListener(server_id, e)
200 blitzcon.c.onEventLogs(eventlistener) 201 return blitzcon 202 except: 203 logger.debug(traceback.format_exc()) 204 if not retry: 205 return None 206 logger.error("Critical error during connect, retrying after _purge") 207 logger.debug(traceback.format_exc()) 208 _purge(force=True) 209 return _createConnection(server_id, sUuid, username, passwd, retry=False, host=host, port=port, group=None, try_super=try_super, anonymous=anonymous, useragent=useragent) 210
211 -def _purge (force=False):
212 if force or len(connectors) > CONNECTOR_POOL_SIZE: 213 keys = connectors.keys() 214 for i in range(int(len(connectors)*CONNECTOR_POOL_KEEP)): 215 try: 216 c = connectors.pop(keys[i]) 217 c.seppuku(softclose=True) 218 except: 219 logger.debug(traceback.format_exc()) 220 logger.info('reached connector_pool_size (%d), size after purge: (%d)' % 221 (CONNECTOR_POOL_SIZE, len(connectors)))
222
223 -def getBlitzConnection (request, server_id=None, with_session=False, retry=True, force_key=None, group=None, try_super=False, useragent=None):
224 """ 225 Grab a connection to the Ice server, trying hard to reuse connections as possible. 226 A per-process dictionary of StoredConnection based connections (key = "C:$base") is kept. 227 A per-process dictionary of session created connections (key = "S:$session_id") is kept. 228 Another set of connections (key = "C:$server_id") is also kept, for creating 'guest' connections 229 using with_session=False. 230 Server id, if not passed in as function argument, is retrieved from session['server']. 231 To allow multiple worker processes to access the session created connections (which will need to be 232 recreated on each process) the blitz session key will be kept in the django session data, and joining that 233 session is attempted, thus avoiding having to keep user/pass around. 234 235 @param request: http request. Used to get these values, either from request.session or 236 from request.REQUEST if not in session: 237 - username 238 - password 239 - host 240 - port 241 - secure (optional, False by default) 242 @param server_id: Way of referencing the server, used in connection dict keys. Int or String 243 @param with_session: If true, try to use existing session 244 @param retry: If true, make an extra attempt to connect 245 @param group: String? 246 @param try_super: If True, try to log on as super user, 'system' group 247 @param useragent: Log which python clients use this connection. E.g. 'OMERO.webadmin' 248 @return: The connection 249 @rtype: L{omero.gateway.BlitzGateway} 250 """ 251 252 r = request.REQUEST 253 if server_id is None: 254 # If no server id is passed, the db entry will not be used and instead we'll depend on the 255 # request.session and request.REQUEST values 256 with_session = True 257 server_id = request.session.get('server',None) 258 if server_id is None: 259 return None 260 261 browsersession_connection_key = 'cuuid#%s'%server_id 262 browsersession_key = request.session.session_key 263 blitz_session = None 264 265 username = request.session.get('username', r.get('username', None)) 266 passwd = request.session.get('password', r.get('password', None)) 267 host = request.session.get('host', r.get('host', None)) 268 port = request.session.get('port', r.get('port', None)) 269 secure = request.session.get('ssl', r.get('ssl', False)) 270 logger.debug(':: (session) %s %s %s' % (str(request.session.get('username', None)), 271 str(request.session.get('host', None)), 272 str(request.session.get('port', None)))) 273 logger.debug(':: (request) %s %s %s' % (str(r.get('username', None)), 274 str(r.get('host', None)), 275 str(r.get('port', None)))) 276 #logger.debug(':: %s %s :: %s' % (str(username), str(passwd), str(browsersession_connection_key))) 277 278 # if r.has_key('logout'): 279 # logger.debug('logout required by HTTP GET or POST') 280 if r.has_key('bsession'): 281 blitz_session = r['bsession'] 282 request.session[browsersession_connection_key] = blitz_session 283 284 if force_key: 285 ckey = force_key 286 else: 287 #### 288 # If we don't want to use sessions, just go with the client connection 289 if not with_session and not request.session.has_key(browsersession_connection_key) and \ 290 not username and not blitz_session: 291 ckey = 'C:' + str(server_id) 292 #logger.debug("a)connection key: %s" % ckey) 293 elif browsersession_key is None: 294 ckey = 'C:' + str(server_id) 295 else: 296 #### 297 # If there is a session key, find if there's a connection for it 298 if browsersession_key is not None and request.session.get(browsersession_connection_key, False): 299 ckey = 'S:' + request.session[browsersession_connection_key] + '#' + str(server_id) 300 #logger.debug("b)connection key: %s" % ckey) 301 else: 302 ckey = 'S:' # postpone key creation to when we have a session uuid 303 304 if r.get('username', None): 305 logger.info('getBlitzConnection(host=%s, port=%s, ssl=%s, username=%s)' % 306 (str(host), str(port), str(secure), str(username))) 307 logger.debug('k=%s' % str(browsersession_connection_key)) 308 blitzcon = None 309 else: 310 # During normal use of web (not login), this is where we lookup connections 311 logger.debug('trying stored connection with userAgent: %s ckey: %s' % (useragent, ckey)) 312 logger.debug(connectors.items()) 313 blitzcon = connectors.get(ckey, None) 314 if not force_key and blitzcon and request.session.get(browsersession_connection_key, blitzcon._sessionUuid) != blitzcon._sessionUuid: 315 logger.debug('stale connection found: %s != %s' % (str(request.session.get(browsersession_connection_key, None)), str(blitzcon._sessionUuid))) 316 blitzcon.seppuku() 317 blitzcon = None 318 319 if blitzcon is None: 320 #### 321 # No stored connection matching the request found, so create a new one 322 if ckey.startswith('S:') and not force_key: 323 ckey = 'S:' 324 if force_key or r.get('username', None): 325 sUuid = None 326 else: 327 sUuid = request.session.get(browsersession_connection_key, None) 328 logger.debug('creating new connection with ckey "%s", sUuid "%s" (%s)' % (ckey, sUuid, try_super)) 329 # create connection, by trying to join existing session... 330 blitzcon = _createConnection(server_id, sUuid=sUuid, 331 username=username, passwd=passwd, 332 host=host, port=port, group=group, try_super=try_super, secure=secure, 333 anonymous=ckey.startswith('C:'), useragent=useragent) 334 if blitzcon is None: 335 if not retry or username: 336 logger.debug('connection failed with provided login information, bail out') 337 return None 338 return getBlitzConnection(request, server_id, with_session, retry=False, group=group, try_super=try_super, useragent=useragent) 339 else: 340 logger.debug('created new connection %s' % str(blitzcon)) 341 342 if not blitzcon.isConnected(): 343 #### 344 # Have a blitzcon, but it doesn't connect. 345 if username: 346 logger.debug('connection failed with provided login information, bail out') 347 return None 348 logger.debug('Failed connection, logging out') 349 _session_logout(request, server_id) 350 #return blitzcon 351 return None 352 #return getBlitzConnection(request, server_id, with_session, force_anon=True, skip_stored=skip_stored) 353 else: 354 #### 355 # Success, new connection created 356 if ckey == 'S:': 357 ckey = 'S:' + blitzcon._sessionUuid + '#' + str(server_id) 358 _purge() 359 connectors[ckey] = blitzcon 360 logger.debug(str(connectors.items())) 361 if username or blitz_session: 362 #### 363 # Because it was a login, store some data 364 if not force_key: 365 request.session[browsersession_connection_key] = blitzcon._sessionUuid 366 logger.debug('blitz session key: ' + blitzcon._sessionUuid) 367 logger.debug('stored as session.' + ckey) 368 blitzcon.user.logIn() 369 elif request.session.get(browsersession_connection_key, None): 370 blitzcon.user.logIn() 371 372 if blitzcon and not blitzcon.keepAlive() and not ckey.startswith('C:'): 373 # session could expire or be closed by another client. webclient needs to recreate connection with new uuid 374 # otherwise it will forward user to login screen. 375 logger.info("Failed keepalive for connection %s" % ckey) 376 #del request.session[browsersession_connection_key] 377 del connectors[ckey] 378 #_session_logout(request, server_id) 379 #return blitzcon 380 return getBlitzConnection(request, server_id, with_session, retry=False, group=group, try_super=try_super, useragent=useragent) 381 if blitzcon and ckey.startswith('C:') and not blitzcon.isConnected(): 382 logger.info("Something killed the base connection, recreating") 383 del connectors[ckey] 384 return None 385 #return getBlitzConnection(request, server_id, with_session, force_anon=True, skip_stored=skip_stored, useragent=useragent) 386 if r.has_key('logout') and not ckey.startswith('C:'): 387 logger.debug('logout required by HTTP GET or POST : killing current connection') 388 _session_logout(request, server_id) 389 return None 390 #return getBlitzConnection(request, server_id, with_session, force_anon=True, skip_stored=skip_stored, useragent=useragent) 391 # # After keepalive the user session may have been replaced with an 'anonymous' one... 392 # if not force_key and blitzcon and request.session.get(browsersession_connection_key, None) != blitzcon._sessionUuid: 393 # logger.debug('Cleaning the user proxy %s!=%s' % (str(request.session.get(browsersession_connection_key, None)), str(blitzcon._sessionUuid))) 394 # blitzcon.user = UserProxy(blitzcon) 395 396 return blitzcon
397
398 -def _split_channel_info (rchannels):
399 """ 400 Splits the request query channel information for images into a sequence of channels, window ranges 401 and channel colors. 402 403 @param rchannels: The request string with channel info. E.g 1|100:505$0000FF,-2,3|620:3879$FF0000 404 @type rchannels: String 405 @return: E.g. [1, -2, 3] [[100.0, 505.0], (None, None), [620.0, 3879.0]] [u'0000FF', None, u'FF0000'] 406 @rtype: tuple of 3 lists 407 """ 408 409 channels = [] 410 windows = [] 411 colors = [] 412 for chan in rchannels.split(','): 413 chan = chan.split('|') 414 t = chan[0].strip() 415 color = None 416 if t.find('$')>=0: 417 t,color = t.split('$') 418 try: 419 channels.append(int(t)) 420 ch_window = (None, None) 421 if len(chan) > 1: 422 t = chan[1].strip() 423 if t.find('$')>=0: 424 t, color = t.split('$') 425 t = t.split(':') 426 if len(t) == 2: 427 try: 428 ch_window = [float(x) for x in t] 429 except ValueError: 430 pass 431 windows.append(ch_window) 432 colors.append(color) 433 except ValueError: 434 pass 435 logger.debug(str(channels)+","+str(windows)+","+str(colors)) 436 return channels, windows, colors
437
438 -def getImgDetailsFromReq (request, as_string=False):
439 """ Break the GET information from the request object into details on how to render the image. 440 The following keys are recognized: 441 z - Z axis position 442 t - T axis position 443 q - Quality set (0,0..1,0) 444 m - Model (g for greyscale, c for color) 445 p - Projection (see blitz_gateway.ImageWrapper.PROJECTIONS for keys) 446 x - X position (for now based on top/left offset on the browser window) 447 y - Y position (same as above) 448 c - a comma separated list of channels to be rendered (start index 1) 449 - format for each entry [-]ID[|wndst:wndend][#HEXCOLOR][,...] 450 zm - the zoom setting (as a percentual value) 451 452 @param request: http request with keys above 453 @param as_string: If True, return a string representation of the rendering details 454 @return: A dict or String representation of rendering details above. 455 @rtype: Dict or String 456 """ 457 458 r = request.REQUEST 459 rv = {} 460 for k in ('z', 't', 'q', 'm', 'zm', 'x', 'y', 'p'): 461 if r.has_key(k): 462 rv[k] = r[k] 463 if r.has_key('c'): 464 rv['c'] = [] 465 ci = _split_channel_info(r['c']) 466 logger.debug(ci) 467 for i in range(len(ci[0])): 468 # a = abs channel, i = channel, s = window start, e = window end, c = color 469 rv['c'].append({'a':abs(ci[0][i]), 'i':ci[0][i], 's':ci[1][i][0], 'e':ci[1][i][1], 'c':ci[2][i]}) 470 if as_string: 471 return "&".join(["%s=%s" % (x[0], x[1]) for x in rv.items()]) 472 return rv
473
474 -def serverid (func):
475 def handler (request, *args, **kwargs): 476 if not kwargs.has_key('server_id'): 477 kwargs['server_id'] = request.session.get('server', None) 478 return func(request, *args, **kwargs)
479 return handler 480
481 @serverid 482 -def render_birds_eye_view (request, iid, server_id=None, size=None, 483 _conn=None, **kwargs):
484 """ 485 Returns an HttpResponse wrapped jpeg with the rendered bird's eye view 486 for image 'iid'. Rendering settings can be specified in the request 487 parameters as in L{render_image} and L{render_image_region}; see 488 L{getImgDetailsFromReq} for a complete list. 489 490 @param request: http request 491 @param iid: Image ID 492 @param size: Maximum size of the longest side of the resulting bird's eye view. 493 @param server_id: Optional, used for getting connection if needed etc 494 @return: http response containing jpeg 495 """ 496 if _conn is None: 497 blitzcon = getBlitzConnection(request, server_id, useragent="OMERO.webgateway") 498 else: 499 blitzcon = _conn 500 if blitzcon is None or not blitzcon.isConnected(): 501 logger.debug("failed connect, HTTP404") 502 raise Http404 503 USE_SESSION = False 504 img = _get_prepared_image(request, iid, server_id=server_id, _conn=_conn, 505 with_session=USE_SESSION) 506 if img is None: 507 logger.debug("(b)Image %s not found..." % (str(iid))) 508 raise Http404 509 img, compress_quality = img 510 return HttpResponse(img.renderBirdsEyeView(size), mimetype='image/jpeg')
511
512 @serverid 513 -def render_thumbnail (request, iid, server_id=None, w=None, h=None, _conn=None, _defcb=None, **kwargs):
514 """ 515 Returns an HttpResponse wrapped jpeg with the rendered thumbnail for image 'iid' 516 517 @param request: http request 518 @param iid: Image ID 519 @param server_id: Optional, used for getting connection if needed etc 520 @param w: Thumbnail max width. 64 by default 521 @param h: Thumbnail max height 522 @return: http response containing jpeg 523 """ 524 if w is None: 525 size = (64,) 526 else: 527 if h is None: 528 size = (int(w),) 529 else: 530 size = (int(w), int(h)) 531 if _conn is None: 532 blitzcon = getBlitzConnection(request, server_id, useragent="OMERO.webgateway") 533 else: 534 blitzcon = _conn 535 if blitzcon is None or not blitzcon.isConnected(): 536 logger.debug("failed connect, HTTP404") 537 raise Http404 538 user_id = blitzcon.getEventContext().userId 539 jpeg_data = webgateway_cache.getThumb(request, server_id, user_id, iid, size) 540 if jpeg_data is None: 541 prevent_cache = False 542 img = blitzcon.getObject("Image", iid) 543 if img is None: 544 logger.debug("(b)Image %s not found..." % (str(iid))) 545 if _defcb: 546 jpeg_data = _defcb(size=size) 547 prevent_cache = True 548 else: 549 raise Http404 550 else: 551 jpeg_data = img.getThumbnail(size=size) 552 if jpeg_data is None: 553 logger.debug("(c)Image %s not found..." % (str(iid))) 554 if _defcb: 555 jpeg_data = _defcb(size=size) 556 prevent_cache = True 557 else: 558 return HttpResponseServerError('Failed to render thumbnail') 559 if not prevent_cache: 560 webgateway_cache.setThumb(request, server_id, user_id, iid, jpeg_data, size) 561 else: 562 pass 563 rsp = HttpResponse(jpeg_data, mimetype='image/jpeg') 564 return rsp
565
566 -def _get_signature_from_request (request):
567 """ 568 returns a string that identifies this image, along with the settings passed on the request. 569 Useful for using as img identifier key, for prepared image. 570 571 @param request: http request 572 @return: String 573 """ 574 575 r = request.REQUEST 576 rv = r.get('m','_') + r.get('p','_')+r.get('c','_')+r.get('q', '_') 577 return rv
578
579 @serverid 580 -def _get_prepared_image (request, iid, server_id=None, _conn=None, with_session=True, saveDefs=False, retry=True):
581 """ 582 Fetches the Image object for image 'iid' and prepares it according to the request query, setting the channels, 583 rendering model and projection arguments. The compression level is parsed and returned too. 584 For parameters in request, see L{getImgDetailsFromReq} 585 586 @param request: http request 587 @param iid: Image ID 588 @param server_id: 589 @param _conn: L{omero.gateway.BlitzGateway} connection 590 @param with_session: If true, attempt to use existing session 591 @param saveDefs: Try to save the rendering settings, default z and t. 592 @param retry: Try an extra attempt at this method 593 @return: Tuple (L{omero.gateway.ImageWrapper} image, quality) 594 """ 595 r = request.REQUEST 596 logger.debug('Preparing Image:%r with_session=%r saveDefs=%r ' \ 597 'retry=%r request=%r' % (iid, with_session, saveDefs, retry, 598 r)) 599 if _conn is None: 600 _conn = getBlitzConnection(request, server_id=server_id, with_session=with_session, useragent="OMERO.webgateway") 601 if _conn is None or not _conn.isConnected(): 602 return HttpResponseServerError('""', mimetype='application/javascript') 603 img = _conn.getObject("Image", iid) 604 if r.has_key('c'): 605 logger.debug("c="+r['c']) 606 channels, windows, colors = _split_channel_info(r['c']) 607 if not img.setActiveChannels(channels, windows, colors): 608 logger.debug("Something bad happened while setting the active channels...") 609 if r.get('m', None) == 'g': 610 img.setGreyscaleRenderingModel() 611 elif r.get('m', None) == 'c': 612 img.setColorRenderingModel() 613 img.setProjection(r.get('p', None)) 614 img.setInvertedAxis(bool(r.get('ia', "0") == "1")) 615 compress_quality = r.get('q', None) 616 if saveDefs: 617 r.has_key('z') and img._re.setDefaultZ(long(r['z'])-1) 618 r.has_key('t') and img._re.setDefaultT(long(r['t'])-1) 619 try: 620 img.saveDefaults() 621 except Ice.Exception, x: 622 if x.serverExceptionClass == 'ome.conditions.InternalException': 623 #if x.message.find('java.lang.NullPointerException') > 0: 624 # # This actually happens when saving rdefs owned by someone else, even 625 # # if we have permissions to write 626 # logger.debug("NullPointerException, ignoring") 627 if x.message.find('Session is dirty') >= 0: 628 if retry: 629 # retry once, to get around "Session is dirty" exceptions 630 return _get_prepared_image(request, iid=iid, server_id=server_id, _conn=_conn, with_session=with_session, saveDefs=saveDefs, retry=False) 631 logger.debug("Session is dirty, bailing out") 632 raise 633 else: 634 raise 635 return (img, compress_quality)
636
637 @serverid 638 -def render_image_region(request, iid, z, t, server_id=None, _conn=None, **kwargs):
639 """ 640 Returns a jpeg of the OMERO image, rendering only a region specified in query string as 641 region=x,y,width,height. E.g. region=0,512,256,256 642 Rendering settings can be specified in the request parameters. 643 644 @param request: http request 645 @param iid: image ID 646 @param z: Z index 647 @param t: T index 648 @param server_id: 649 @param _conn: L{omero.gateway.BlitzGateway} connection 650 @return: http response wrapping jpeg 651 """ 652 653 # if the region=x,y,w,h is not parsed correctly to give 4 ints then we simply provide whole image plane. 654 # alternatively, could return a 404? 655 #if h == None: 656 # return render_image (request, iid, z, t, server_id=None, _conn=None, **kwargs) 657 658 USE_SESSION = False 659 pi = _get_prepared_image(request, iid, server_id=server_id, _conn=_conn, with_session=USE_SESSION) 660 661 if pi is None: 662 raise Http404 663 img, compress_quality = pi 664 665 tile = request.REQUEST.get('tile', None) 666 region = request.REQUEST.get('region', None) 667 level = None 668 669 if tile: 670 try: 671 img._prepareRenderingEngine() 672 tiles = img._re.requiresPixelsPyramid() 673 w, h = img._re.getTileSize() 674 levels = img._re.getResolutionLevels()-1 675 676 zxyt = tile.split(",") 677 678 #w = int(zxyt[3]) 679 #h = int(zxyt[4]) 680 level = levels-int(zxyt[0]) 681 682 x = int(zxyt[1])*w 683 y = int(zxyt[2])*h 684 except: 685 logger.debug("render_image_region: tile=%s" % tile) 686 logger.debug(traceback.format_exc()) 687 688 elif region: 689 try: 690 xywh = region.split(",") 691 692 x = int(xywh[0]) 693 y = int(xywh[1]) 694 w = int(xywh[2]) 695 h = int(xywh[3]) 696 except: 697 logger.debug("render_image_region: region=%s" % region) 698 logger.debug(traceback.format_exc()) 699 700 # region details in request are used as key for caching. 701 jpeg_data = webgateway_cache.getImage(request, server_id, img, z, t) 702 if jpeg_data is None: 703 jpeg_data = img.renderJpegRegion(z,t,x,y,w,h,level=level, compression=compress_quality) 704 if jpeg_data is None: 705 raise Http404 706 webgateway_cache.setImage(request, server_id, img, z, t, jpeg_data) 707 rsp = HttpResponse(jpeg_data, mimetype='image/jpeg') 708 return rsp
709
710 @serverid 711 -def render_image (request, iid, z, t, server_id=None, _conn=None, **kwargs):
712 """ 713 Renders the image with id {{iid}} at {{z}} and {{t}} as jpeg. 714 Many options are available from the request dict. See L{getImgDetailsFromReq} for list. 715 I am assuming a single Pixels object on image with image-Id='iid'. May be wrong 716 717 @param request: http request 718 @param iid: image ID 719 @param z: Z index 720 @param t: T index 721 @param server_id: 722 @param _conn: L{omero.gateway.BlitzGateway} connection 723 @return: http response wrapping jpeg 724 """ 725 726 USE_SESSION = False 727 pi = _get_prepared_image(request, iid, server_id=server_id, _conn=_conn, with_session=USE_SESSION) 728 if pi is None: 729 raise Http404 730 img, compress_quality = pi 731 jpeg_data = webgateway_cache.getImage(request, server_id, img, z, t) 732 if jpeg_data is None: 733 jpeg_data = img.renderJpeg(z,t, compression=compress_quality) 734 if jpeg_data is None: 735 raise Http404 736 webgateway_cache.setImage(request, server_id, img, z, t, jpeg_data) 737 738 try: 739 from PIL import Image, ImageDraw # see ticket:2597 740 except ImportError: 741 try: 742 import Image, ImageDraw # see ticket:2597 743 except: 744 logger.error("You need to install the Python Imaging Library. Get it at http://www.pythonware.com/products/pil/") 745 logger.error(traceback.format_exc()) 746 747 rsp = HttpResponse(jpeg_data, mimetype='image/jpeg') 748 return rsp
749
750 @serverid 751 -def render_ome_tiff (request, ctx, cid, server_id=None, _conn=None, **kwargs):
752 """ 753 Renders the OME-TIFF representation of the image(s) with id cid in ctx (i)mage, 754 (d)ataset, or (p)roject. 755 756 @param request: http request 757 @param ctx: 'p' or 'd' or 'i' 758 @param cid: Project, Dataset or Image ID 759 @param server_id: 760 @param _conn: L{omero.gateway.BlitzGateway} connection 761 @return: http response wrapping the tiff (or zip for multiple files), or redirect to temp file/zip 762 """ 763 USE_SESSION = False 764 if _conn is None: 765 _conn = getBlitzConnection(request, server_id=server_id, with_session=USE_SESSION, useragent="OMERO.webgateway") 766 if _conn is None or not _conn.isConnected(): 767 return HttpResponseServerError('""', mimetype='application/javascript') 768 imgs = [] 769 if ctx == 'p': 770 obj = _conn.getObject("Project", cid) 771 if obj is None: 772 raise Http404 773 for d in obj.listChildren(): 774 imgs.extend(list(d.listChildren())) 775 name = obj.getName() 776 elif ctx == 'd': 777 obj = _conn.getObject("Dataset", cid) 778 if obj is None: 779 raise Http404 780 imgs.extend(list(obj.listChildren())) 781 selection = filter(None, request.REQUEST.get('selection', '').split(',')) 782 if len(selection): 783 logger.debug(selection) 784 logger.debug(imgs) 785 imgs = filter(lambda x: str(x.getId()) in selection, imgs) 786 logger.debug(imgs) 787 if len(imgs) == 0: 788 raise Http404 789 name = '%s-%s' % (obj.getParent().getName(), obj.getName()) 790 else: 791 obj = _conn.getObject("Image", cid) 792 if obj is None: 793 raise Http404 794 imgs.append(obj) 795 796 if len(imgs) == 1: 797 obj = imgs[0] 798 key = '_'.join((str(x.getId()) for x in obj.getAncestry())) + '_' + str(obj.getId()) + '_ome_tiff' 799 fpath, rpath, fobj = webgateway_tempfile.new(str(obj.getId()) + '-'+obj.getName() + '.ome.tiff', key=key) 800 if fobj is True: 801 # already exists 802 return HttpResponseRedirect('/appmedia/tfiles/' + rpath) 803 tiff_data = webgateway_cache.getOmeTiffImage(request, server_id, imgs[0]) 804 if tiff_data is None: 805 tiff_data = imgs[0].exportOmeTiff() 806 if tiff_data is None: 807 raise Http404 808 webgateway_cache.setOmeTiffImage(request, server_id, imgs[0], tiff_data) 809 if fobj is None: 810 rsp = HttpResponse(tiff_data, mimetype='application/x-ome-tiff') 811 rsp['Content-Disposition'] = 'attachment; filename="%s.ome.tiff"' % (str(obj.getId()) + '-'+obj.getName()) 812 rsp['Content-Length'] = len(tiff_data) 813 return rsp 814 else: 815 fobj.write(tiff_data) 816 fobj.close() 817 return HttpResponseRedirect('/appmedia/tfiles/' + rpath) 818 else: 819 try: 820 img_ids = '+'.join((str(x.getId()) for x in imgs)) 821 key = '_'.join((str(x.getId()) for x in imgs[0].getAncestry())) + '_' + md5(img_ids).hexdigest() + '_ome_tiff_zip' 822 fpath, rpath, fobj = webgateway_tempfile.new(name + '.zip', key=key) 823 if fobj is True: 824 return HttpResponseRedirect('/appmedia/tfiles/' + rpath) 825 logger.debug(fpath) 826 if fobj is None: 827 fobj = StringIO() 828 zobj = zipfile.ZipFile(fobj, 'w', zipfile.ZIP_STORED) 829 for obj in imgs: 830 tiff_data = webgateway_cache.getOmeTiffImage(request, server_id, obj) 831 if tiff_data is None: 832 tiff_data = obj.exportOmeTiff() 833 if tiff_data is None: 834 continue 835 webgateway_cache.setOmeTiffImage(request, server_id, obj, tiff_data) 836 zobj.writestr(str(obj.getId()) + '-'+obj.getName() + '.ome.tiff', tiff_data) 837 zobj.close() 838 if fpath is None: 839 zip_data = fobj.getvalue() 840 rsp = HttpResponse(zip_data, mimetype='application/zip') 841 rsp['Content-Disposition'] = 'attachment; filename="%s.zip"' % name 842 rsp['Content-Length'] = len(zip_data) 843 return rsp 844 except: 845 logger.debug(traceback.format_exc()) 846 raise 847 return HttpResponseRedirect('/appmedia/tfiles/' + rpath)
848
849 @serverid 850 -def render_movie (request, iid, axis, pos, server_id=None, _conn=None, **kwargs):
851 """ 852 Renders a movie from the image with id iid 853 854 @param request: http request 855 @param iid: Image ID 856 @param axis: Movie frames are along 'z' or 't' dimension. String 857 @param pos: The T index (for z axis) or Z index (for t axis) 858 @param server_id: 859 @param _conn: L{omero.gateway.BlitzGateway} connection 860 @return: http response wrapping the file, or redirect to temp file 861 """ 862 863 try: 864 # Prepare a filename we'll use for temp cache, and check if file is already there 865 opts = {} 866 opts['format'] = 'video/' + request.REQUEST.get('format', 'quicktime') 867 opts['fps'] = int(request.REQUEST.get('fps', 4)) 868 opts['minsize'] = (512,512, '#222222') 869 ext = opts['format']== 'video/quicktime' and '.mov' or '.avi' 870 key = "%s-%s-%s-%d-%s-%s" % (iid, axis, pos, opts['fps'], _get_signature_from_request(request), 871 request.REQUEST.get('format', 'quicktime')) 872 873 USE_SESSION = False 874 pos = int(pos) 875 pi = _get_prepared_image(request, iid, server_id=server_id, _conn=_conn, with_session=USE_SESSION) 876 if pi is None: 877 raise Http404 878 img, compress_quality = pi 879 880 fpath, rpath, fobj = webgateway_tempfile.new(img.getName() + ext, key=key) 881 logger.debug(fpath, rpath, fobj) 882 if fobj is True: 883 return HttpResponseRedirect('/appmedia/tfiles/' + rpath)#os.path.join(rpath, img.getName() + ext)) 884 885 if kwargs.has_key('optsCB'): 886 opts.update(kwargs['optsCB'](img)) 887 opts.update(kwargs.get('opts', {})) 888 logger.debug('rendering movie for img %s with axis %s, pos %i and opts %s' % (iid, axis, pos, opts)) 889 #fpath, rpath = webgateway_tempfile.newdir() 890 if fpath is None: 891 import tempfile 892 fo, fn = tempfile.mkstemp() 893 else: 894 fn = fpath #os.path.join(fpath, img.getName()) 895 if axis.lower() == 'z': 896 dext, mimetype = img.createMovie(fn, 0, img.getSizeZ()-1, pos-1, pos-1, opts) 897 else: 898 dext, mimetype = img.createMovie(fn, pos-1, pos-1, 0, img.getSizeT()-1, opts) 899 if dext is None and mimetype is None: 900 # createMovie is currently only available on 4.1_custom 901 # https://trac.openmicroscopy.org.uk/ome/ticket/3857 902 raise Http404 903 if fpath is None: 904 movie = open(fn).read() 905 os.close(fo) 906 rsp = HttpResponse(movie, mimetype=mimetype) 907 rsp['Content-Disposition'] = 'attachment; filename="%s"' % (img.getName()+ext) 908 rsp['Content-Length'] = len(movie) 909 return rsp 910 else: 911 fobj.close() 912 #shutil.move(fn, fn + ext) 913 return HttpResponseRedirect('/appmedia/tfiles/' + rpath)#os.path.join(rpath, img.getName() + ext)) 914 except: 915 logger.debug(traceback.format_exc()) 916 raise
917
918 @serverid 919 -def render_split_channel (request, iid, z, t, server_id=None, _conn=None, **kwargs):
920 """ 921 Renders a split channel view of the image with id {{iid}} at {{z}} and {{t}} as jpeg. 922 Many options are available from the request dict. 923 Requires PIL to be installed on the server. 924 925 @param request: http request 926 @param iid: Image ID 927 @param z: Z index 928 @param t: T index 929 @param server_id: 930 @param _conn: L{omero.gateway.BlitzGateway} connection 931 @return: http response wrapping a jpeg 932 """ 933 934 USE_SESSION = False 935 pi = _get_prepared_image(request, iid, server_id=server_id, _conn=_conn, with_session=USE_SESSION) 936 if pi is None: 937 raise Http404 938 img, compress_quality = pi 939 compress_quality = compress_quality and float(compress_quality) or 0.9 940 jpeg_data = webgateway_cache.getSplitChannelImage(request, server_id, img, z, t) 941 if jpeg_data is None: 942 jpeg_data = img.renderSplitChannel(z,t, compression=compress_quality) 943 if jpeg_data is None: 944 raise Http404 945 webgateway_cache.setSplitChannelImage(request, server_id, img, z, t, jpeg_data) 946 rsp = HttpResponse(jpeg_data, mimetype='image/jpeg') 947 return rsp
948
949 -def debug (f):
950 """ 951 Decorator for adding debugging functionality to methods. 952 953 @param f: The function to wrap 954 @return: The wrapped function 955 """ 956 957 def wrap (request, *args, **kwargs): 958 debug = request.REQUEST.getlist('debug') 959 if 'slow' in debug: 960 time.sleep(5) 961 if 'fail' in debug: 962 raise Http404 963 if 'error' in debug: 964 raise AttributeError('Debug requested error') 965 return f(request, *args, **kwargs)
966 wrap.func_name = f.func_name 967 return wrap 968
969 -def jsonp (f):
970 """ 971 Decorator for adding connection debugging and returning function result as json, depending on 972 values in kwargs 973 974 @param f: The function to wrap 975 @return: The wrapped function, which will return json 976 """ 977 978 def wrap (request, *args, **kwargs): 979 logger.debug('jsonp') 980 try: 981 server_id = kwargs.get('server_id', None) 982 if server_id is None: 983 server_id = request.session.get('server', None) 984 kwargs['server_id'] = server_id 985 _conn = kwargs.get('_conn', None) 986 if _conn is None: 987 blitzcon = getBlitzConnection(request, server_id, useragent="OMERO.webgateway") 988 kwargs['_conn'] = blitzcon 989 if kwargs['_conn'] is None or not kwargs['_conn'].isConnected(): 990 return HttpResponseServerError('"failed connection"', mimetype='application/javascript') 991 rv = f(request, *args, **kwargs) 992 if _conn is not None and kwargs.get('_internal', False): 993 return rv 994 if isinstance(rv, HttpResponseServerError): 995 return rv 996 rv = simplejson.dumps(rv) 997 c = request.REQUEST.get('callback', None) 998 if c is not None and not kwargs.get('_internal', False): 999 rv = '%s(%s)' % (c, rv) 1000 if _conn is not None or kwargs.get('_internal', False): 1001 return rv 1002 return HttpResponse(rv, mimetype='application/javascript') 1003 except omero.ServerError: 1004 if kwargs.get('_internal', False): 1005 raise 1006 return HttpResponseServerError('("error in call","%s")' % traceback.format_exc(), mimetype='application/javascript') 1007 except: 1008 logger.debug(traceback.format_exc()) 1009 if kwargs.get('_internal', False): 1010 raise 1011 return HttpResponseServerError('("error in call","%s")' % traceback.format_exc(), mimetype='application/javascript')
1012 wrap.func_name = f.func_name 1013 return wrap 1014
1015 #def json_error_catch (f): 1016 # def wrap (*args, **kwargs): 1017 # try: 1018 # return f(*args, **kwargs) 1019 # except omero.ServerError: 1020 # return HttpResponseServerError('"error in call"', mimetype='application/javascript') 1021 # return wrap 1022 1023 @debug 1024 @serverid 1025 -def render_row_plot (request, iid, z, t, y, server_id=None, _conn=None, w=1, **kwargs):
1026 """ 1027 Renders the line plot for the image with id {{iid}} at {{z}} and {{t}} as gif with transparent background. 1028 Many options are available from the request dict. 1029 I am assuming a single Pixels object on image with Image ID='iid'. May be wrong 1030 TODO: cache 1031 1032 @param request: http request 1033 @param iid: Image ID 1034 @param z: Z index 1035 @param t: T index 1036 @param y: Y position of row to measure 1037 @param server_id: 1038 @param _conn: L{omero.gateway.BlitzGateway} connection 1039 @param w: Line width 1040 @return: http response wrapping a gif 1041 """ 1042 1043 if not w: 1044 w = 1 1045 pi = _get_prepared_image(request, iid, server_id=server_id, _conn=_conn) 1046 if pi is None: 1047 raise Http404 1048 img, compress_quality = pi 1049 gif_data = img.renderRowLinePlotGif(int(z),int(t),int(y), int(w)) 1050 if gif_data is None: 1051 raise Http404 1052 rsp = HttpResponse(gif_data, mimetype='image/gif') 1053 return rsp
1054
1055 @debug 1056 @serverid 1057 -def render_col_plot (request, iid, z, t, x, w=1, server_id=None, _conn=None, **kwargs):
1058 """ 1059 Renders the line plot for the image with id {{iid}} at {{z}} and {{t}} as gif with transparent background. 1060 Many options are available from the request dict. 1061 I am assuming a single Pixels object on image with id='iid'. May be wrong 1062 TODO: cache 1063 1064 @param request: http request 1065 @param iid: Image ID 1066 @param z: Z index 1067 @param t: T index 1068 @param x: X position of column to measure 1069 @param server_id: 1070 @param _conn: L{omero.gateway.BlitzGateway} connection 1071 @param w: Line width 1072 @return: http response wrapping a gif 1073 """ 1074 1075 if not w: 1076 w = 1 1077 pi = _get_prepared_image(request, iid, server_id=server_id, _conn=_conn) 1078 if pi is None: 1079 raise Http404 1080 img, compress_quality = pi 1081 gif_data = img.renderColLinePlotGif(int(z),int(t),int(x), int(w)) 1082 if gif_data is None: 1083 raise Http404 1084 rsp = HttpResponse(gif_data, mimetype='image/gif') 1085 return rsp
1086
1087 -def channelMarshal (channel):
1088 """ 1089 return a dict with all there is to know about a channel 1090 1091 @param channel: L{omero.gateway.ChannelWrapper} 1092 @return: Dict 1093 """ 1094 1095 return {'emissionWave': channel.getEmissionWave(), 1096 'label': channel.getLabel(), 1097 'color': channel.getColor().getHtml(), 1098 'window': {'min': channel.getWindowMin(), 1099 'max': channel.getWindowMax(), 1100 'start': channel.getWindowStart(), 1101 'end': channel.getWindowEnd(),}, 1102 'active': channel.isActive()}
1103
1104 -def imageMarshal (image, key=None):
1105 """ 1106 return a dict with pretty much everything we know and care about an image, 1107 all wrapped in a pretty structure. 1108 1109 @param image: L{omero.gateway.ImageWrapper} 1110 @param key: key of specific attributes to select 1111 @return: Dict 1112 """ 1113 1114 image.loadRenderOptions() 1115 pr = image.getProject() 1116 ds = None 1117 try: 1118 # Replicating the functionality of the deprecated 1119 # ImageWrapper.getDataset() with shares in mind. 1120 # -- Tue Sep 6 10:48:47 BST 2011 (See #6660) 1121 parents = image.listParents() 1122 if parents is not None and len(parents) == 1 \ 1123 and parents[0].OMERO_CLASS == 'Dataset': 1124 ds = parents[0] 1125 except omero.SecurityViolation, e: 1126 # We're in a share so the Image's parent Dataset cannot be loaded 1127 # or some other permissions related issue has tripped us up. 1128 logger.warn('Security violation while retrieving Dataset when ' \ 1129 'marshaling image metadata: %s' % e.message) 1130 1131 try: 1132 reOK = image._prepareRenderingEngine() 1133 if not reOK: 1134 logger.debug("Failed to prepare Rendering Engine for imageMarshal") 1135 return None 1136 except omero.ConcurrencyException, ce: 1137 backOff = ce.backOff 1138 rv = { 1139 'ConcurrencyException': { 1140 'backOff': backOff 1141 } 1142 } 1143 return rv 1144 1145 #big images 1146 tiles = image._re.requiresPixelsPyramid() 1147 width, height = image._re.getTileSize() 1148 levels = image._re.getResolutionLevels()-1 1149 init_zoom = image._re.getResolutionLevel() 1150 1151 try: 1152 rv = { 1153 'tiles': tiles, 1154 'tile_size': {'width': width, 1155 'height': height}, 1156 'init_zoom': init_zoom, 1157 'levels': levels, 1158 'id': image.id, 1159 'size': {'width': image.getSizeX(), 1160 'height': image.getSizeY(), 1161 'z': image.getSizeZ(), 1162 't': image.getSizeT(), 1163 'c': image.getSizeC(),}, 1164 'pixel_size': {'x': image.getPixelSizeX(), 1165 'y': image.getPixelSizeY(), 1166 'z': image.getPixelSizeZ(),}, 1167 'meta': {'imageName': image.name or '', 1168 'imageDescription': image.description or '', 1169 'imageAuthor': image.getAuthor(), 1170 'projectName': pr and pr.name or 'Multiple', 1171 'projectId': pr and pr.id or None, 1172 'projectDescription':pr and pr.description or '', 1173 'datasetName': ds and ds.name or 'Multiple', 1174 'datasetId': ds and ds.id or '', 1175 'datasetDescription': ds and ds.description or '', 1176 'imageTimestamp': time.mktime(image.getDate().timetuple()), 1177 'imageId': image.id,}, 1178 } 1179 try: 1180 rv['pixel_range'] = image.getPixelRange() 1181 rv['channels'] = map(lambda x: channelMarshal(x), image.getChannels()) 1182 rv['split_channel'] = image.splitChannelDims() 1183 rv['rdefs'] = {'model': image.isGreyscaleRenderingModel() and 'greyscale' or 'color', 1184 'projection': image.getProjection(), 1185 'defaultZ': image._re.getDefaultZ(), 1186 'defaultT': image._re.getDefaultT(), 1187 'invertAxis': image.isInvertedAxis()} 1188 except TypeError: 1189 # Will happen if an image has bad or missing pixel data 1190 rv['pixel_range'] = (0, 0) 1191 rv['channels'] = () 1192 rv['split_channel'] = () 1193 rv['rdefs'] = {'model': 'color', 'projection': image.getProjection(), 'invertAxis': image.isInvertedAxis()} 1194 except AttributeError: 1195 rv = None 1196 raise 1197 if key is not None and rv is not None: 1198 for k in key.split('.'): 1199 rv = rv.get(k, {}) 1200 if rv == {}: 1201 rv = None 1202 return rv
1203
1204 @jsonp 1205 -def imageData_json (request, server_id=None, _conn=None, _internal=False, **kwargs):
1206 """ 1207 Get a dict with image information 1208 TODO: cache 1209 1210 @param request: http request 1211 @param server_id: 1212 @param _conn: L{omero.gateway.BlitzGateway} 1213 @param _internal: TODO: ? 1214 @return: Dict 1215 """ 1216 1217 iid = kwargs['iid'] 1218 key = kwargs.get('key', None) 1219 blitzcon = _conn 1220 image = blitzcon.getObject("Image", iid) 1221 if image is None: 1222 return HttpResponseServerError('""', mimetype='application/javascript') 1223 rv = imageMarshal(image, key) 1224 return rv
1225
1226 @jsonp 1227 -def wellData_json (request, server_id=None, _conn=None, _internal=False, **kwargs):
1228 """ 1229 Get a dict with image information 1230 TODO: cache 1231 1232 @param request: http request 1233 @param server_id: 1234 @param _conn: L{omero.gateway.BlitzGateway} 1235 @param _internal: TODO: ? 1236 @return: Dict 1237 """ 1238 1239 wid = kwargs['wid'] 1240 blitzcon = _conn 1241 well = blitzcon.getObject("Well", wid) 1242 if well is None: 1243 return HttpResponseServerError('""', mimetype='application/javascript') 1244 prefix = kwargs.get('thumbprefix', 'webgateway.views.render_thumbnail') 1245 def urlprefix(iid): 1246 return reverse(prefix, args=(iid,))
1247 xtra = {'thumbUrlPrefix': urlprefix} 1248 rv = well.simpleMarshal(xtra=xtra) 1249 return rv 1250
1251 @jsonp 1252 -def plateGrid_json (request, pid, field=0, server_id=None, _conn=None, **kwargs):
1253 """ 1254 """ 1255 plate = _conn.getObject('plate', long(pid)) 1256 try: 1257 field = long(field or 0) 1258 except ValueError: 1259 field = 0 1260 if plate is None: 1261 return HttpResponseServerError('""', mimetype='application/javascript') 1262 grid = [] 1263 prefix = kwargs.get('thumbprefix', 'webgateway.views.render_thumbnail') 1264 def urlprefix(iid): 1265 return reverse(prefix, args=(iid,64))
1266 xtra = {'thumbUrlPrefix': urlprefix} 1267 plate.setGridSizeConstraints(8,12) 1268 for row in plate.getWellGrid(field): 1269 tr = [] 1270 for e in row: 1271 if e: 1272 i = e.getImage() 1273 if i: 1274 t = i.simpleMarshal(xtra=xtra) 1275 t['wellId'] = e.getId() 1276 t['field'] = field 1277 tr.append(t) 1278 continue 1279 tr.append(None) 1280 grid.append(tr) 1281 #grid.append(map(lambda x: x is not None and x.simpleMarshal(xtra=xtra) or None, [( x and x.getImage() ) for x in row])) 1282 return {'grid': grid, 1283 'collabels': plate.getColumnLabels(), 1284 'rowlabels': plate.getRowLabels()} 1285
1286 @jsonp 1287 -def listImages_json (request, did, server_id=None, _conn=None, **kwargs):
1288 """ 1289 lists all Images in a Dataset, as json 1290 TODO: cache 1291 1292 @param request: http request 1293 @param did: Dataset ID 1294 @param server_id: 1295 @param _conn: L{omero.gateway.BlitzGateway} 1296 @return: list of image json. 1297 """ 1298 1299 blitzcon = _conn 1300 dataset = blitzcon.getObject("Dataset", did) 1301 if dataset is None: 1302 return HttpResponseServerError('""', mimetype='application/javascript') 1303 prefix = kwargs.get('thumbprefix', 'webgateway.views.render_thumbnail') 1304 def urlprefix(iid): 1305 return reverse(prefix, args=(iid,))
1306 xtra = {'thumbUrlPrefix': urlprefix} 1307 return map(lambda x: x.simpleMarshal(xtra=xtra), dataset.listChildren()) 1308
1309 @jsonp 1310 -def listWellImages_json (request, did, server_id=None, _conn=None, **kwargs):
1311 """ 1312 lists all Images in a Well, as json 1313 TODO: cache 1314 1315 @param request: http request 1316 @param did: Well ID 1317 @param server_id: 1318 @param _conn: L{omero.gateway.BlitzGateway} 1319 @return: list of image json. 1320 """ 1321 1322 blitzcon = _conn 1323 well = blitzcon.getObject("Well", did) 1324 if well is None: 1325 return HttpResponseServerError('""', mimetype='application/javascript') 1326 prefix = kwargs.get('thumbprefix', 'webgateway.views.render_thumbnail') 1327 def urlprefix(iid): 1328 return reverse(prefix, args=(iid,))
1329 xtra = {'thumbUrlPrefix': urlprefix} 1330 return map(lambda x: x.getImage() and x.getImage().simpleMarshal(xtra=xtra), well.listChildren()) 1331
1332 @jsonp 1333 -def listDatasets_json (request, pid, server_id=None, _conn=None, **kwargs):
1334 """ 1335 lists all Datasets in a Project, as json 1336 TODO: cache 1337 1338 @param request: http request 1339 @param pid: Project ID 1340 @param server_id: 1341 @param _conn: L{omero.gateway.BlitzGateway} 1342 @return: list of dataset json. 1343 """ 1344 1345 blitzcon = _conn 1346 project = blitzcon.getObject("Project", pid) 1347 rv = [] 1348 if project is None: 1349 return HttpResponse('[]', mimetype='application/javascript') 1350 return [x.simpleMarshal(xtra={'childCount':0}) for x in project.listChildren()]
1351
1352 @jsonp 1353 -def datasetDetail_json (request, did, server_id=None, _conn=None, **kwargs):
1354 """ 1355 return json encoded details for a dataset 1356 TODO: cache 1357 """ 1358 blitzcon = _conn 1359 ds = blitzcon.getObject("Dataset", did) 1360 return ds.simpleMarshal()
1361
1362 @jsonp 1363 -def listProjects_json (request, server_id=None, _conn=None, **kwargs):
1364 """ 1365 lists all Projects, as json 1366 TODO: cache 1367 1368 @param request: http request 1369 @param server_id: 1370 @param _conn: L{omero.gateway.BlitzGateway} 1371 @return: list of project json. 1372 """ 1373 1374 blitzcon = _conn 1375 rv = [] 1376 for pr in blitzcon.listProjects(): 1377 rv.append( {'id': pr.id, 'name': pr.name, 'description': pr.description or ''} ) 1378 return rv
1379
1380 @jsonp 1381 -def projectDetail_json (request, pid, server_id=None, _conn=None, **kwargs):
1382 """ 1383 grab details from one specific project 1384 TODO: cache 1385 1386 @param request: http request 1387 @param pid: Project ID 1388 @param server_id: 1389 @param _conn: L{omero.gateway.BlitzGateway} 1390 @return: project details as dict. 1391 """ 1392 1393 blitzcon = _conn 1394 pr = blitzcon.getObject("Project", pid) 1395 rv = pr.simpleMarshal() 1396 return rv
1397
1398 -def searchOptFromRequest (request):
1399 """ 1400 Returns a dict of options for searching, based on 1401 parameters in the http request 1402 Request keys include: 1403 - ctx: (http request) 'imgs' to search only images 1404 - text: (http request) the actual text phrase 1405 - start: starting index (0 based) for result 1406 - limit: nr of results to retuen (0 == unlimited) 1407 - author: 1408 - grabData: 1409 - parents: 1410 1411 @param request: http request 1412 @return: Dict of options 1413 """ 1414 1415 try: 1416 r = request.REQUEST 1417 opts = { 1418 'search': unicode(r.get('text', '')).encode('utf8'), 1419 'ctx': r.get('ctx', ''), 1420 'grabData': not not r.get('grabData', False), 1421 'parents': not not bool(r.get('parents', False)), 1422 'start': int(r.get('start', 0)), 1423 'limit': int(r.get('limit', 0)), 1424 'key': r.get('key', None) 1425 } 1426 author = r.get('author', '') 1427 if author: 1428 opts['search'] += ' author:'+author 1429 return opts 1430 except: 1431 logger.error(traceback.format_exc()) 1432 return {}
1433
1434 @TimeIt(logging.INFO) 1435 @jsonp 1436 -def search_json (request, server_id=None, _conn=None, **kwargs):
1437 """ 1438 Search for objects in blitz. 1439 Returns json encoded list of marshalled objects found by the search query 1440 Request keys include: 1441 - text: The text to search for 1442 - ctx: (http request) 'imgs' to search only images 1443 - text: (http request) the actual text phrase 1444 - start: starting index (0 based) for result 1445 - limit: nr of results to retuen (0 == unlimited) 1446 - author: 1447 - grabData: 1448 - parents: 1449 1450 @param request: http request 1451 @param server_id: 1452 @param _conn: L{omero.gateway.BlitzGateway} 1453 @return: json search results 1454 TODO: cache 1455 """ 1456 opts = searchOptFromRequest(request) 1457 rv = [] 1458 logger.debug("searchObjects(%s)" % (opts['search'])) 1459 # search returns blitz_connector wrapper objects 1460 def urlprefix(iid): 1461 return reverse('webgateway.views.render_thumbnail', args=(iid,))
1462 xtra = {'thumbUrlPrefix': urlprefix} 1463 pks = None 1464 try: 1465 if opts['ctx'] == 'imgs': 1466 sr = _conn.searchObjects(["image"], opts['search']) 1467 else: 1468 sr = _conn.searchObjects(None, opts['search']) # searches P/D/I 1469 except ApiUsageException: 1470 return HttpResponseServerError('"parse exception"', mimetype='application/javascript') 1471 def marshal (): 1472 rv = [] 1473 if (opts['grabData'] and opts['ctx'] == 'imgs'): 1474 bottom = min(opts['start'], len(sr)-1) 1475 if opts['limit'] == 0: 1476 top = len(sr) 1477 else: 1478 top = min(len(sr), bottom + opts['limit']) 1479 for i in range(bottom, top): 1480 e = sr[i] 1481 #for e in sr: 1482 try: 1483 rv.append(imageData_json(request, server_id, iid=e.id, key=opts['key'], _conn=_conn, _internal=True)) 1484 except AttributeError, x: 1485 logger.debug('(iid %i) ignoring Attribute Error: %s' % (e.id, str(x))) 1486 pass 1487 except omero.ServerError, x: 1488 logger.debug('(iid %i) ignoring Server Error: %s' % (e.id, str(x))) 1489 return rv 1490 else: 1491 return map(lambda x: x.simpleMarshal(xtra=xtra, parents=opts['parents']), sr) 1492 rv = timeit(marshal)() 1493 logger.debug(rv) 1494 return rv 1495
1496 @serverid 1497 -def save_image_rdef_json (request, iid, server_id=None, **kwargs):
1498 """ 1499 Requests that the rendering defs passed in the request be set as the default for this image. 1500 Rendering defs in request listed at L{getImgDetailsFromReq} 1501 TODO: jsonp 1502 1503 @param request: http request 1504 @param iid: Image ID 1505 @param server_id: 1506 @return: http response 'true' or 'false' 1507 """ 1508 1509 r = request.REQUEST 1510 pi = _get_prepared_image(request, iid, server_id=server_id, with_session=True, saveDefs=True) 1511 if pi is None: 1512 json_data = 'false' 1513 else: 1514 user_id = pi[0]._conn.getEventContext().userId 1515 webgateway_cache.invalidateObject(server_id, user_id, pi[0]) 1516 pi[0].getThumbnail() 1517 json_data = 'true' 1518 if r.get('callback', None): 1519 json_data = '%s(%s)' % (r['callback'], json_data) 1520 return HttpResponse(json_data, mimetype='application/javascript')
1521
1522 @serverid 1523 -def list_compatible_imgs_json (request, server_id, iid, _conn=None, **kwargs):
1524 """ 1525 Lists the images on the same project that would be viable targets for copying rendering settings. 1526 TODO: change method to: 1527 list_compatible_imgs_json (request, iid, server_id=None, _conn=None, **kwargs): 1528 1529 @param request: http request 1530 @param server_id: 1531 @param iid: Image ID 1532 @param _conn: L{omero.gateway.BlitzGateway} 1533 @return: json list of image IDs 1534 """ 1535 1536 json_data = 'false' 1537 r = request.REQUEST 1538 if _conn is None: 1539 blitzcon = getBlitzConnection(request, server_id, with_session=True, useragent="OMERO.webgateway") 1540 else: 1541 blitzcon = _conn 1542 if blitzcon is None or not blitzcon.isConnected(): 1543 img = None 1544 else: 1545 img = blitzcon.getObject("Image", iid) 1546 1547 if img is not None: 1548 # List all images in project 1549 imgs = [] 1550 for ds in img.getProject().listChildren(): 1551 imgs.extend(ds.listChildren()) 1552 # Filter the ones that would pass the applySettingsToImages call 1553 img_ptype = img.getPrimaryPixels().getPixelsType().getValue() 1554 img_ccount = img.getSizeC() 1555 img_ew = [x.getLabel() for x in img.getChannels()] 1556 img_ew.sort() 1557 def compat (i): 1558 if long(i.getId()) == long(iid): 1559 return False 1560 pp = i.getPrimaryPixels() 1561 if pp is None or \ 1562 i.getPrimaryPixels().getPixelsType().getValue() != img_ptype or \ 1563 i.getSizeC() != img_ccount: 1564 return False 1565 ew = [x.getLabel() for x in i.getChannels()] 1566 ew.sort() 1567 if ew != img_ew: 1568 return False 1569 return True
1570 imgs = filter(compat, imgs) 1571 json_data = simplejson.dumps([x.getId() for x in imgs]) 1572 1573 if r.get('callback', None): 1574 json_data = '%s(%s)' % (r['callback'], json_data) 1575 return HttpResponse(json_data, mimetype='application/javascript') 1576
1577 @jsonp 1578 @serverid 1579 -def copy_image_rdef_json (request, server_id=None, _conn=None, _internal=False, **kwargs):
1580 """ 1581 Copy the rendering settings from one image to a list of images. 1582 Images are specified in request by 'fromid' and list of 'toids' 1583 Returns json dict of Boolean:[Image-IDs] for images that have successfully 1584 had the rendering settings applied, or not. 1585 1586 @param request: http request 1587 @param server_id: 1588 @param _conn: L{omero.gateway.BlitzGateway} 1589 @return: json dict of Boolean:[Image-IDs] 1590 """ 1591 1592 json_data = False 1593 r = request.REQUEST 1594 try: 1595 fromid = long(r.get('fromid', None)) 1596 toids = map(lambda x: long(x), r.getlist('toids')) 1597 except TypeError: 1598 fromid = None 1599 except ValueError: 1600 fromid = None 1601 if fromid is not None and len(toids) > 0: 1602 # if _conn is None: 1603 # blitzcon = getBlitzConnection(request, server_id, with_session=True, useragent="OMERO.webgateway") 1604 # else: 1605 blitzcon = _conn 1606 1607 fromimg = blitzcon.getObject("Image", fromid) 1608 details = fromimg.getDetails() 1609 frompid = fromimg.getPixelsId() 1610 newConn = None 1611 if blitzcon.isAdmin(): 1612 p = omero.sys.Principal() 1613 p.name = details.getOwner().omeName 1614 p.group = details.getGroup().name 1615 p.eventType = "User" 1616 # This connection will have a 20 minute timeout 1617 newConnId = blitzcon.getSessionService().createSessionWithTimeout(p, 1200000) 1618 newConn = blitzcon.clone() 1619 newConn.connect(sUuid=newConnId.getUuid().val) 1620 elif fromimg.isEditable(): 1621 newConn = blitzcon 1622 newConn.setGroupForSession(details.getGroup().getId()) 1623 1624 if newConn is not None and newConn.isConnected(): 1625 frompid = newConn.getObject("Image", fromid).getPixelsId() 1626 rsettings = newConn.getRenderingSettingsService() 1627 json_data = rsettings.applySettingsToImages(frompid, list(toids)) 1628 if fromid in json_data[True]: 1629 del json_data[True][json_data[True].index(fromid)] 1630 for iid in json_data[True]: 1631 img = newConn.getObject("Image", iid) 1632 user_id = newConn.getEventContext().userId 1633 img is not None and webgateway_cache.invalidateObject(server_id, user_id, img) 1634 return json_data
1635 #
1636 # json_data = simplejson.dumps(json_data) 1637 # 1638 # if r.get('callback', None): 1639 # json_data = '%s(%s)' % (r['callback'], json_data) 1640 # return HttpResponse(json_data, mimetype='application/javascript') 1641 1642 @serverid 1643 @jsonp 1644 -def reset_image_rdef_json (request, iid, server_id=None, _conn=None, **kwargs):
1645 """ 1646 Try to remove all rendering defs the logged in user has for this image. 1647 1648 @param request: http request 1649 @param iid: Image ID 1650 @param server_id: 1651 @param _conn: L{omero.gateway.BlitzGateway} 1652 @return: json 'true', or 'false' if failed 1653 """ 1654 # if _conn is None: 1655 # blitzcon = getBlitzConnection(request, server_id, with_session=True, useragent="OMERO.webgateway") 1656 # else: 1657 # blitzcon = _conn 1658 # r = request.REQUEST 1659 # tr 1660 # if blitzcon is None or not blitzcon.isConnected(): 1661 # img = None 1662 # else: 1663 img = _conn.getObject("Image", iid) 1664 1665 if img is not None and img.resetRDefs(): 1666 user_id = _conn.getEventContext().userId 1667 webgateway_cache.invalidateObject(server_id, user_id, img) 1668 return True 1669 json_data = 'true' 1670 else: 1671 json_data = 'false' 1672 return False
1673 # if _conn is not None:
1674 # return json_data == 'true' # TODO: really return a boolean? (not json) 1675 # if r.get('callback', None): 1676 # json_data = '%s(%s)' % (r['callback'], json_data) 1677 # return HttpResponse(json_data, mimetype='application/javascript') 1678 1679 -def dbg_connectors (request):
1680 """ 1681 For debugging, return connectors dict as plain text 1682 """ 1683 rv = connectors.items() 1684 return HttpResponse(rv, mimetype='text/plain')
1685
1686 @serverid 1687 -def full_viewer (request, iid, server_id=None, _conn=None, **kwargs):
1688 """ 1689 This view is responsible for showing the omero_image template 1690 Image rendering options in request are used in the display page. See L{getImgDetailsFromReq}. 1691 1692 @param request: http request. 1693 @param iid: Image ID 1694 @param server_id: 1695 @param _conn: L{omero.gateway.BlitzGateway} 1696 @param **kwargs: Can be used to specify the html 'template' for rendering 1697 @return: html page of image and metadata 1698 """ 1699 1700 rid = getImgDetailsFromReq(request) 1701 try: 1702 if _conn is None: 1703 _conn = getBlitzConnection(request, server_id=server_id, useragent="OMERO.webgateway") 1704 if _conn is None or not _conn.isConnected(): 1705 raise Http404 1706 image = _conn.getObject("Image", iid) 1707 if image is None: 1708 logger.debug("(a)Image %s not found..." % (str(iid))) 1709 raise Http404 1710 d = {'blitzcon': _conn, 1711 'image': image, 1712 'opts': rid, 1713 'viewport_server': kwargs.get('viewport_server', '/webgateway'), 1714 'object': 'image:%i' % int(iid)} 1715 1716 template = kwargs.get('template', "webgateway/omero_image.html") 1717 t = template_loader.get_template(template) 1718 c = Context(request,d) 1719 rsp = t.render(c) 1720 except omero.SecurityViolation: 1721 raise Http404 1722 return HttpResponse(rsp)
1723
1724 @serverid 1725 -def get_rois_json(request, imageId, server_id=None):
1726 """ 1727 Returns json data of the ROIs in the specified image. 1728 """ 1729 _conn = getBlitzConnection(request, server_id=server_id, with_session=False, useragent="OMERO.webgateway") 1730 if _conn is None or not _conn.isConnected(): 1731 raise Http404 1732 1733 def stringToSvg(string): 1734 """ 1735 Method for converting the string returned from omero.model.ShapeI.getPoints() 1736 into an SVG for display on web. 1737 E.g: "points[309,427, 366,503, 190,491] points1[309,427, 366,503, 190,491] points2[309,427, 366,503, 190,491]" 1738 To: M 309 427 L 366 503 L 190 491 z 1739 """ 1740 pointLists = string.strip().split("points") 1741 if len(pointLists) < 2: 1742 logger.error("Unrecognised ROI shape 'points' string: %s" % string) 1743 return "" 1744 firstList = pointLists[1] 1745 nums = firstList.strip("[]").replace(", ", " L").replace(",", " ") 1746 return "M" + nums
1747 1748 def rgb_int2css(rgbint): 1749 """ 1750 converts a bin int number into css colour, E.g. -1006567680 to '#00ff00' 1751 """ 1752 r,g,b = (rgbint // 256 // 256 % 256, rgbint // 256 % 256, rgbint % 256) 1753 return "#%02x%02x%02x" % (r,g,b) # format hex 1754 1755 rois = [] 1756 roiService = _conn.getRoiService() 1757 #rois = webfigure_utils.getRoiShapes(roiService, long(imageId)) # gets a whole json list of ROIs 1758 result = roiService.findByImage(long(imageId), None) 1759 1760 for r in result.rois: 1761 roi = {} 1762 roi['id'] = r.getId().getValue() 1763 # go through all the shapes of the ROI 1764 shapes = [] 1765 for s in r.copyShapes(): 1766 shape = {} 1767 if s is None: # seems possible in some situations 1768 continue 1769 shape['id'] = s.getId().getValue() 1770 shape['theT'] = s.getTheT().getValue() 1771 shape['theZ'] = s.getTheZ().getValue() 1772 if type(s) == omero.model.RectI: 1773 shape['type'] = 'Rectangle' 1774 shape['x'] = s.getX().getValue() 1775 shape['y'] = s.getY().getValue() 1776 shape['width'] = s.getWidth().getValue() 1777 shape['height'] = s.getHeight().getValue() 1778 elif type(s) == omero.model.MaskI: 1779 shape['type'] = 'Mask' 1780 shape['x'] = s.getX().getValue() 1781 shape['y'] = s.getY().getValue() 1782 shape['width'] = s.getWidth().getValue() 1783 shape['height'] = s.getHeight().getValue() 1784 # TODO: support for mask 1785 elif type(s) == omero.model.EllipseI: 1786 shape['type'] = 'Ellipse' 1787 shape['cx'] = s.getCx().getValue() 1788 shape['cy'] = s.getCy().getValue() 1789 shape['rx'] = s.getRx().getValue() 1790 shape['ry'] = s.getRy().getValue() 1791 elif type(s) == omero.model.PolylineI: 1792 shape['type'] = 'PolyLine' 1793 shape['points'] = stringToSvg(s.getPoints().getValue()) 1794 elif type(s) == omero.model.LineI: 1795 shape['type'] = 'Line' 1796 shape['x1'] = s.getX1().getValue() 1797 shape['x2'] = s.getX2().getValue() 1798 shape['y1'] = s.getY1().getValue() 1799 shape['y2'] = s.getY2().getValue() 1800 elif type(s) == omero.model.PointI: 1801 shape['type'] = 'Point' 1802 shape['cx'] = s.getCx().getValue() 1803 shape['cy'] = s.getCy().getValue() 1804 elif type(s) == omero.model.PolygonI: 1805 shape['type'] = 'Polygon' 1806 shape['points'] = stringToSvg(s.getPoints().getValue()) + "z" # z = closed line 1807 elif type(s) == omero.model.LabelI: 1808 shape['type'] = 'Label' 1809 shape['x'] = s.getX().getValue() 1810 shape['y'] = s.getY().getValue() 1811 else: 1812 logger.debug("Shape type not supported: %s" % str(type(s))) 1813 try: 1814 if s.getTextValue() and s.getTextValue().getValue(): 1815 shape['textValue'] = s.getTextValue().getValue() 1816 # only populate json with font styles if we have some text 1817 if s.getFontSize() and s.getFontSize().getValue(): 1818 shape['fontSize'] = s.getFontSize().getValue() 1819 if s.getFontStyle() and s.getFontStyle().getValue(): 1820 shape['fontStyle'] = s.getFontStyle().getValue() 1821 if s.getFontFamily() and s.getFontFamily().getValue(): 1822 shape['fontFamily'] = s.getFontFamily().getValue() 1823 except AttributeError: pass 1824 if s.getTransform(): 1825 t = s.getTransform().getValue() 1826 if t and t != 'none': 1827 shape['transform'] = t 1828 if s.getFillColor() and s.getFillColor().getValue(): 1829 shape['fillColor'] = rgb_int2css(s.getFillColor().getValue()) 1830 if s.getStrokeColor() and s.getStrokeColor().getValue(): 1831 shape['strokeColor'] = rgb_int2css(s.getStrokeColor().getValue()) 1832 if s.getStrokeWidth() and s.getStrokeWidth().getValue(): 1833 shape['strokeWidth'] = s.getStrokeWidth().getValue() 1834 shapes.append(shape) 1835 # sort shapes by Z, then T. 1836 shapes.sort(key=lambda x: "%03d%03d"% (x['theZ'],x['theT']) ); 1837 roi['shapes'] = shapes 1838 rois.append(roi) 1839 1840 rois.sort(key=lambda x: x['id']) # sort by ID - same as in measurement tool. 1841 1842 return HttpResponse(simplejson.dumps(rois), mimetype='application/javascript') 1843
1844 1845 -def test (request):
1846 """ 1847 Tests the L{full_viewer} with no args passed to the template. 1848 1849 @param request: http request. 1850 @return: blank page template 1851 """ 1852 1853 context = {} 1854 1855 t = template_loader.get_template('webgateway/omero_image.html') 1856 c = Context(request,context) 1857 return HttpResponse(t.render(c))
1858
1859 @jsonp 1860 -def su (request, user, server_id=None, _conn=None, **kwargs):
1861 """ 1862 If current user is admin, switch the session to a new connection owned by 'user' 1863 (puts the new session ID in the request.session) 1864 Return False if not possible 1865 1866 @param request: http request. 1867 @param user: Username of new connection owner 1868 @param server_id: 1869 @param _conn: L{omero.gateway.BlitzGateway} 1870 @param **kwargs: Can be used to specify the html 'template' for rendering 1871 @return: Boolean 1872 """ 1873 if not _conn.canBeAdmin(): 1874 return False 1875 _conn.setGroupNameForSession('system') 1876 if server_id is None: 1877 # If no server id is passed, the db entry will not be used and instead we'll depend on the 1878 # request.session and request.REQUEST values 1879 try: 1880 server_id = request.session['server'] 1881 except KeyError: 1882 return None 1883 browsersession_connection_key = 'cuuid#%s'%server_id 1884 c = _conn.suConn(user, 1885 ttl=_conn.getSessionService().getSession(_conn._sessionUuid).getTimeToIdle().val) 1886 _conn.revertGroupForSession() 1887 _conn.seppuku() 1888 logger.debug(browsersession_connection_key) 1889 request.session[browsersession_connection_key] = c._sessionUuid 1890 return True
1891