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

Source Code for Module omeroweb.webclient.views

   1  #!/usr/bin/env python 
   2  #  
   3  #  
   4  #  
   5  # Copyright (c) 2008-2011 University of Dundee. 
   6  #  
   7  # This program is free software: you can redistribute it and/or modify 
   8  # it under the terms of the GNU Affero General Public License as 
   9  # published by the Free Software Foundation, either version 3 of the 
  10  # License, or (at your option) any later version. 
  11  #  
  12  # This program is distributed in the hope that it will be useful, 
  13  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
  14  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
  15  # GNU Affero General Public License for more details. 
  16  #  
  17  # You should have received a copy of the GNU Affero General Public License 
  18  # along with this program.  If not, see <http://www.gnu.org/licenses/>. 
  19  #  
  20  # Author: Aleksandra Tarkowska <A(dot)Tarkowska(at)dundee(dot)ac(dot)uk>, 2008. 
  21  #  
  22  # Version: 1.0 
  23  # 
  24   
  25  ''' A view functions is simply a Python function that takes a Web request and  
  26  returns a Web response. This response can be the HTML contents of a Web page,  
  27  or a redirect, or the 404 and 500 error, or an XML document, or an image...  
  28  or anything.''' 
  29   
  30  import sys 
  31  import copy 
  32  import re 
  33  import os 
  34  import calendar 
  35  import cStringIO 
  36  import datetime 
  37  import httplib 
  38  import Ice 
  39  import locale 
  40  import logging 
  41  import traceback 
  42   
  43  import shutil 
  44  import zipfile 
  45  import glob 
  46   
  47  from time import time 
  48  from thread import start_new_thread 
  49   
  50  from omero_version import omero_version 
  51  import omero, omero.scripts  
  52  from omero.rtypes import * 
  53   
  54  from django.conf import settings 
  55  from django.contrib.sessions.backends.cache import SessionStore 
  56  from django.core import template_loader 
  57  from django.core.cache import cache 
  58  from django.http import HttpResponse, HttpResponseRedirect, HttpResponseServerError 
  59  from django.shortcuts import render_to_response 
  60  from django.template import RequestContext as Context 
  61  from django.utils import simplejson 
  62  from django.views.defaults import page_not_found, server_error 
  63  from django.views import debug 
  64  from django.core.urlresolvers import reverse 
  65  from django.utils.translation import ugettext_lazy as _ 
  66  from django.utils.encoding import smart_str 
  67  from django.core.servers.basehttp import FileWrapper 
  68   
  69  from webclient.webclient_gateway import OmeroWebGateway 
  70  from omeroweb.webclient.webclient_utils import string_to_dict 
  71   
  72  from webclient_http import HttpJavascriptRedirect, HttpJavascriptResponse, HttpLoginRedirect 
  73   
  74  from webclient_utils import _formatReport, _purgeCallback 
  75  from forms import ShareForm, BasketShareForm, ShareCommentForm, \ 
  76                      ContainerForm, ContainerNameForm, ContainerDescriptionForm, \ 
  77                      CommentAnnotationForm, TagAnnotationForm, \ 
  78                      UploadFileForm, UsersForm, ActiveGroupForm, HistoryTypeForm, \ 
  79                      MetadataFilterForm, MetadataDetectorForm, MetadataChannelForm, \ 
  80                      MetadataEnvironmentForm, MetadataObjectiveForm, MetadataObjectiveSettingsForm, MetadataStageLabelForm, \ 
  81                      MetadataLightSourceForm, MetadataDichroicForm, MetadataMicroscopeForm, \ 
  82                      TagListForm, FileListForm, TagFilterForm, \ 
  83                      MultiAnnotationForm, \ 
  84                      WellIndexForm 
  85   
  86  from controller import BaseController 
  87  from controller.index import BaseIndex 
  88  from controller.basket import BaseBasket 
  89  from controller.container import BaseContainer 
  90  from controller.help import BaseHelp 
  91  from controller.history import BaseCalendar 
  92  from controller.impexp import BaseImpexp 
  93  from controller.search import BaseSearch 
  94  from controller.share import BaseShare 
  95   
  96  from omeroweb.webadmin.forms import MyAccountForm, UploadPhotoForm, LoginForm, ChangePassword 
  97  from omeroweb.webadmin.controller.experimenter import BaseExperimenter  
  98  from omeroweb.webadmin.controller.uploadfile import BaseUploadFile 
  99  from omeroweb.webadmin.webadmin_utils import _checkVersion, _isServerOn, toBoolean, upgradeCheck 
 100   
 101  from omeroweb.webgateway.views import getBlitzConnection 
 102  from omeroweb.webgateway import views as webgateway_views 
 103   
 104  from omeroweb.feedback.views import handlerInternalError 
 105   
 106  logger = logging.getLogger('views-web') 
 107   
 108  connectors = {} 
 109  share_connectors = {} 
 110   
 111  logger.info("INIT '%s'" % os.getpid()) 
112 113 114 ################################################################################ 115 # Blitz Gateway Connection 116 117 -def getShareConnection (request, share_id):
118 browsersession_key = request.session.session_key 119 share_conn_key = "S:%s#%s#%s" % (browsersession_key, request.session.get('server'), share_id) 120 share = getBlitzConnection(request, force_key=share_conn_key, useragent="OMERO.web") 121 share.attachToShare(share_id) 122 request.session['shares'][share_id] = share._sessionUuid 123 request.session.modified = True 124 logger.debug('shared connection: %s : %s' % (share_id, share._sessionUuid)) 125 return share
126
127 ################################################################################ 128 # decorators 129 130 -def isUserConnected (f):
131 def wrapped (request, *args, **kwargs): 132 #this check the connection exist, if not it will redirect to login page 133 server = string_to_dict(request.REQUEST.get('path')).get('server',request.REQUEST.get('server', None)) 134 url = request.REQUEST.get('url') 135 if url is None or len(url) == 0: 136 if request.META.get('QUERY_STRING'): 137 url = '%s?%s' % (request.META.get('PATH_INFO'), request.META.get('QUERY_STRING')) 138 else: 139 url = '%s' % (request.META.get('PATH_INFO')) 140 141 conn = None 142 try: 143 conn = getBlitzConnection(request, useragent="OMERO.web") 144 except Exception, x: 145 logger.error(traceback.format_exc()) 146 147 if conn is None: 148 # TODO: Should be changed to use HttpRequest.is_ajax() 149 # http://docs.djangoproject.com/en/dev/ref/request-response/ 150 # Thu 6 Jan 2011 09:57:27 GMT -- callan at blackcat dot ca 151 if request.is_ajax(): 152 return HttpResponseServerError(reverse("weblogin")) 153 _session_logout(request, request.REQUEST.get('server', None)) 154 if server is not None: 155 return HttpLoginRedirect(reverse("weblogin")+(("?url=%s&server=%s") % (url,server))) 156 return HttpLoginRedirect(reverse("weblogin")+(("?url=%s") % url)) 157 158 conn_share = None 159 share_id = kwargs.get('share_id', None) 160 if share_id is not None: 161 sh = conn.getShare(share_id) 162 if sh is not None: 163 try: 164 if sh.getOwner().id != conn.getEventContext().userId: 165 conn_share = getShareConnection(request, share_id) 166 except Exception, x: 167 logger.error(traceback.format_exc()) 168 169 sessionHelper(request) 170 kwargs["error"] = request.REQUEST.get('error') 171 kwargs["conn"] = conn 172 kwargs["conn_share"] = conn_share 173 kwargs["url"] = url 174 return f(request, *args, **kwargs)
175 return wrapped 176
177 -def sessionHelper(request):
178 changes = False 179 if request.session.get('callback') is None: 180 request.session['callback'] = dict() 181 changes = True 182 if request.session.get('shares') is None: 183 request.session['shares'] = dict() 184 changes = True 185 if request.session.get('imageInBasket') is None: 186 request.session['imageInBasket'] = set() 187 changes = True 188 #if request.session.get('datasetInBasket') is None: 189 # request.session['datasetInBasket'] = set() 190 if request.session.get('nav') is None: 191 if request.session.get('server') is not None: 192 blitz = settings.SERVER_LIST.get(pk=request.session.get('server')) 193 elif request.session.get('host') is not None: 194 blitz = settings.SERVER_LIST.get(host=request.session.get('host')) 195 blitz = "%s:%s" % (blitz.host, blitz.port) 196 request.session['nav']={"blitz": blitz, "menu": "mydata", "view": "tree", "basket": 0, "experimenter":None} 197 changes = True 198 if changes: 199 request.session.modified = True
200
201 ################################################################################ 202 # views controll 203 204 -def login(request):
205 request.session.modified = True 206 if request.REQUEST.get('server'): 207 blitz = settings.SERVER_LIST.get(pk=request.REQUEST.get('server')) 208 request.session['server'] = blitz.id 209 request.session['host'] = blitz.host 210 request.session['port'] = blitz.port 211 request.session['username'] = smart_str(request.REQUEST.get('username',None)) 212 request.session['password'] = smart_str(request.REQUEST.get('password',None)) 213 request.session['ssl'] = (True, False)[request.REQUEST.get('ssl') is None] 214 request.session['shares'] = dict() 215 request.session['imageInBasket'] = set() 216 blitz_host = "%s:%s" % (blitz.host, blitz.port) 217 request.session['nav']={"error": None, "blitz": blitz_host, "menu": "start", "view": "icon", "basket": 0, "experimenter":None, 'callback':dict()} 218 219 error = request.REQUEST.get('error') 220 221 conn = None 222 # TODO: version check should be done on the low level, see #5983 223 if _checkVersion(request.session.get('host'), request.session.get('port')): 224 try: 225 conn = getBlitzConnection(request, useragent="OMERO.web") 226 except Exception, x: 227 error = x.__class__.__name__ 228 229 if conn is not None: 230 upgradeCheck() 231 request.session['version'] = conn.getServerVersion() 232 if request.REQUEST.get('noredirect'): 233 return HttpResponse('OK') 234 url = request.REQUEST.get("url") 235 if url is not None and len(url) != 0: 236 return HttpResponseRedirect(url) 237 else: 238 return HttpResponseRedirect(reverse("webindex")) 239 else: 240 if request.method == 'POST' and request.REQUEST.get('server'): 241 if not _isServerOn(request.session.get('host'), request.session.get('port')): 242 error = "Server is not responding, please contact administrator." 243 elif not _checkVersion(request.session.get('host'), request.session.get('port')): 244 error = "Client version does not match server, please contact administrator." 245 else: 246 error = "Connection not available, please check your user name and password." 247 url = request.REQUEST.get("url") 248 request.session['server'] = request.REQUEST.get('server') 249 250 template = "webclient/login.html" 251 if request.method == 'POST': 252 form = LoginForm(data=request.REQUEST.copy()) 253 else: 254 blitz = settings.SERVER_LIST.get(pk=request.session.get('server')) 255 if blitz is not None: 256 initial = {'server': unicode(blitz.id)} 257 form = LoginForm(initial=initial) 258 else: 259 form = LoginForm() 260 261 context = {"version": omero_version, 'error':error, 'form':form, 'url': url} 262 if url is not None and len(url) != 0: 263 context['url'] = url 264 265 t = template_loader.get_template(template) 266 c = Context(request, context) 267 rsp = t.render(c) 268 return HttpResponse(rsp)
269
270 @isUserConnected 271 -def index(request, **kwargs):
272 template = "webclient/index/index.html" 273 274 request.session['nav']['error'] = request.REQUEST.get('error') 275 276 conn = None 277 try: 278 conn = kwargs["conn"] 279 except: 280 logger.error(traceback.format_exc()) 281 return handlerInternalError("Connection is not available. Please contact your administrator.") 282 283 url = None 284 try: 285 url = kwargs["url"] 286 except: 287 logger.error(traceback.format_exc()) 288 289 try: 290 if request.session['nav']['menu'] != 'start': 291 request.session['nav']['menu'] = 'home' 292 except: 293 request.session['nav']['menu'] = 'start' 294 295 controller = BaseIndex(conn) 296 #controller.loadData() 297 form_active_group = ActiveGroupForm(initial={'activeGroup':controller.eContext['context'].groupId, 'mygroups': controller.eContext['allGroups'], 'url':url}) 298 299 context = {'nav':request.session['nav'], 'controller':controller, 'eContext': controller.eContext, 'form_active_group':form_active_group} 300 301 t = template_loader.get_template(template) 302 c = Context(request, context) 303 rsp = t.render(c) 304 return HttpResponse(rsp)
305
306 @isUserConnected 307 -def index_context(request, **kwargs):
308 template = "webclient/index/index_context.html" 309 conn = None 310 try: 311 conn = kwargs["conn"] 312 except: 313 logger.error(traceback.format_exc()) 314 return handlerInternalError("Connection is not available. Please contact your administrator.") 315 316 controller = BaseIndex(conn) 317 #controller.loadData() 318 319 context = {'nav':request.session['nav'], 'controller':controller} 320 t = template_loader.get_template(template) 321 c = Context(request, context) 322 rsp = t.render(c) 323 return HttpResponse(rsp)
324
325 @isUserConnected 326 -def index_last_imports(request, **kwargs):
327 template = "webclient/index/index_last_imports.html" 328 conn = None 329 try: 330 conn = kwargs["conn"] 331 except: 332 logger.error(traceback.format_exc()) 333 return handlerInternalError("Connection is not available. Please contact your administrator.") 334 335 controller = BaseIndex(conn) 336 controller.loadLastAcquisitions() 337 338 context = {'controller':controller, 'eContext': controller.eContext } 339 t = template_loader.get_template(template) 340 c = Context(request, context) 341 rsp = t.render(c) 342 return HttpResponse(rsp)
343
344 @isUserConnected 345 -def index_most_recent(request, **kwargs):
346 template = "webclient/index/index_most_recent.html" 347 conn = None 348 try: 349 conn = kwargs["conn"] 350 except: 351 logger.error(traceback.format_exc()) 352 return handlerInternalError("Connection is not available. Please contact your administrator.") 353 354 controller = BaseIndex(conn) 355 controller.loadMostRecent() 356 357 context = {'controller':controller, 'eContext': controller.eContext } 358 t = template_loader.get_template(template) 359 c = Context(request, context) 360 rsp = t.render(c) 361 return HttpResponse(rsp)
362
363 @isUserConnected 364 -def index_tag_cloud(request, **kwargs):
365 template = "webclient/index/index_tag_cloud.html" 366 conn = None 367 try: 368 conn = kwargs["conn"] 369 except: 370 logger.error(traceback.format_exc()) 371 return handlerInternalError("Connection is not available. Please contact your administrator.") 372 373 controller = BaseIndex(conn) 374 controller.loadTagCloud() 375 376 context = {'controller':controller, 'eContext': controller.eContext } 377 t = template_loader.get_template(template) 378 c = Context(request, context) 379 rsp = t.render(c) 380 return HttpResponse(rsp)
381
382 @isUserConnected 383 -def change_active_group(request, **kwargs):
384 try: 385 conn = kwargs["conn"] 386 except: 387 logger.error(traceback.format_exc()) 388 return handlerInternalError("Connection is not available. Please contact your administrator.") 389 390 url = None 391 try: 392 url = kwargs["url"] 393 except: 394 logger.error(traceback.format_exc()) 395 396 server = request.session.get('server') 397 username = request.session.get('username') 398 password = request.session.get('password') 399 ssl = request.session.get('ssl') 400 version = request.session.get('version') 401 402 webgateway_views._session_logout(request, request.session.get('server')) 403 404 blitz = settings.SERVER_LIST.get(pk=server) 405 request.session['server'] = blitz.id 406 request.session['host'] = blitz.host 407 request.session['port'] = blitz.port 408 request.session['username'] = username 409 request.session['password'] = password 410 request.session['ssl'] = (True, False)[request.REQUEST.get('ssl') is None] 411 request.session['shares'] = dict() 412 request.session['imageInBasket'] = set() 413 blitz_host = "%s:%s" % (blitz.host, blitz.port) 414 request.session['nav']={"error": None, "blitz": blitz_host, "menu": "start", "view": "icon", "basket": 0, "experimenter":None, 'callback':dict()} 415 416 conn = getBlitzConnection(request, useragent="OMERO.web") 417 418 active_group = request.REQUEST.get('active_group') 419 if conn.changeActiveGroup(active_group): 420 request.session.modified = True 421 else: 422 error = 'You cannot change your group becuase the data is currently processing. You can force it by logging out and logging in again.' 423 url = reverse("webindex")+ ("?error=%s" % error) 424 if request.session.get('nav')['experimenter'] is not None: 425 url += "&experimenter=%s" % request.session.get('nav')['experimenter'] 426 427 request.session['version'] = conn.getServerVersion() 428 429 return HttpResponseRedirect(url)
430
431 -def _session_logout (request, server_id):
432 webgateway_views._session_logout(request, server_id) 433 434 try: 435 if request.session.get('shares') is not None: 436 for key in request.session.get('shares').iterkeys(): 437 session_key = "S:%s#%s#%s" % (request.session.session_key,server_id, key) 438 webgateway_views._session_logout(request,server_id, force_key=session_key) 439 for k in request.session.keys(): 440 if request.session.has_key(k): 441 del request.session[k] 442 except: 443 logger.error(traceback.format_exc())
444
445 @isUserConnected 446 -def logout(request, **kwargs):
447 _session_logout(request, request.session.get('server')) 448 #request.session.set_expiry(1) 449 return HttpResponseRedirect(reverse("webindex"))
450
451 452 ########################################################################### 453 @isUserConnected 454 -def load_template(request, menu, **kwargs):
455 request.session.modified = True 456 457 if menu == 'userdata': 458 template = "webclient/data/containers.html" 459 elif menu == 'usertags': 460 template = "webclient/data/container_tags.html" 461 else: 462 template = "webclient/%s/%s.html" % (menu,menu) 463 request.session['nav']['menu'] = menu 464 465 request.session['nav']['error'] = request.REQUEST.get('error') 466 467 conn = None 468 try: 469 conn = kwargs["conn"] 470 except: 471 logger.error(traceback.format_exc()) 472 return handlerInternalError("Connection is not available. Please contact your administrator.") 473 474 url = None 475 try: 476 url = kwargs["url"] 477 except: 478 logger.error(traceback.format_exc()) 479 if url is None: 480 url = reverse(viewname="load_template", args=[menu]) 481 482 #tree support 483 init = {'initially_open':[], 'initially_select': None} 484 for k,v in string_to_dict(request.REQUEST.get('path')).items(): 485 if k.lower() in ('project', 'dataset', 'image', 'screen', 'plate'): 486 for i in v.split(","): 487 if ":selected" in str(i) and init['initially_select'] is None: 488 init['initially_select'] = k+"-"+i.replace(":selected", "") 489 else: 490 init['initially_open'].append(k+"-"+i) 491 492 try: 493 manager = BaseContainer(conn) 494 except AttributeError, x: 495 logger.error(traceback.format_exc()) 496 return handlerInternalError(x) 497 498 form_users = None 499 filter_user_id = None 500 501 users = list(conn.listColleagues()) 502 users.sort(key=lambda x: x.getOmeName().lower()) 503 empty_label = "*%s (%s)" % (conn.getUser().getFullName(), conn.getUser().omeName) 504 if len(users) > 0: 505 if request.REQUEST.get('experimenter') is not None and len(request.REQUEST.get('experimenter'))>0: 506 form_users = UsersForm(initial={'users': users, 'empty_label':empty_label, 'menu':menu}, data=request.REQUEST.copy()) 507 if form_users.is_valid(): 508 filter_user_id = request.REQUEST.get('experimenter', None) 509 request.session.get('nav')['experimenter'] = filter_user_id 510 form_users = UsersForm(initial={'user':filter_user_id, 'users': users, 'empty_label':empty_label, 'menu':menu}) 511 else: 512 if request.REQUEST.get('experimenter') == "": 513 request.session.get('nav')['experimenter'] = None 514 filter_user_id = request.session.get('nav')['experimenter'] is not None and request.session.get('nav')['experimenter'] or None 515 if filter_user_id is not None: 516 form_users = UsersForm(initial={'user':filter_user_id, 'users': users, 'empty_label':empty_label, 'menu':menu}) 517 else: 518 form_users = UsersForm(initial={'users': users, 'empty_label':empty_label, 'menu':menu}) 519 520 else: 521 form_users = UsersForm(initial={'users': users, 'empty_label':empty_label, 'menu':menu}) 522 523 form_active_group = ActiveGroupForm(initial={'activeGroup':manager.eContext['context'].groupId, 'mygroups': manager.eContext['allGroups'], 'url':url}) 524 525 context = {'nav':request.session['nav'], 'url':url, 'init':init, 'eContext':manager.eContext, 'form_active_group':form_active_group, 'form_users':form_users} 526 527 t = template_loader.get_template(template) 528 c = Context(request,context) 529 logger.debug('TEMPLATE: '+template) 530 return HttpResponse(t.render(c))
531
532 @isUserConnected 533 -def load_data(request, o1_type=None, o1_id=None, o2_type=None, o2_id=None, o3_type=None, o3_id=None, **kwargs):
534 request.session.modified = True 535 536 # check menu 537 menu = request.REQUEST.get("menu") 538 if menu is not None: 539 request.session['nav']['menu'] = menu 540 else: 541 menu = request.session['nav']['menu'] 542 543 # check view 544 view = request.REQUEST.get("view") 545 if view is not None: 546 request.session['nav']['view'] = view 547 else: 548 view = request.session['nav']['view'] 549 550 # get connection 551 conn = None 552 try: 553 conn = kwargs["conn"] 554 except: 555 logger.error(traceback.format_exc()) 556 return handlerInternalError("Connection is not available. Please contact your administrator.") 557 558 # get url to redirect 559 url = None 560 if o1_type is None and o1_id is None: 561 args = [line for line in [o1_type, o1_id, o2_type, o2_id, o3_type, o3_id] if line is not None] 562 url = reverse(viewname="load_data", args=args) 563 else: 564 try: 565 url = kwargs["url"] 566 except: 567 logger.error(traceback.format_exc()) 568 if url is None: 569 url = reverse(viewname="load_template", args=[menu]) 570 571 # get page 572 try: 573 page = int(request.REQUEST['page']) 574 except: 575 #page = (1, None)[view=="tree"] 576 page = 1 577 578 # get index of the plate 579 try: 580 index = int(request.REQUEST['index']) 581 except: 582 index = 0 583 584 # prepare data 585 kw = dict() 586 if o1_type is not None: 587 if o1_id is not None and o1_id > 0: 588 kw[str(o1_type)] = long(o1_id) 589 else: 590 kw[str(o1_type)] = bool(o1_id) 591 592 if o2_type is not None and o2_id > 0: 593 kw[str(o2_type)] = long(o2_id) 594 if o3_type is not None and o3_id > 0: 595 kw[str(o3_type)] = long(o3_id) 596 try: 597 manager= BaseContainer(conn, **kw) 598 except AttributeError, x: 599 logger.error(traceback.format_exc()) 600 return HttpJavascriptResponse("Object does not exist. Refresh the page.") 601 #return handlerInternalError(x) 602 603 # prepare forms 604 filter_user_id = request.session.get('nav')['experimenter'] 605 form_well_index = None 606 607 # load data & template 608 template = None 609 if kw.has_key('orphaned'): 610 manager.listOrphanedImages(filter_user_id, page) 611 if view =='icon': 612 template = "webclient/data/containers_icon.html" 613 elif view =='table': 614 template = "webclient/data/containers_table.html" 615 else: 616 template = "webclient/data/container_subtree.html" 617 elif len(kw.keys()) > 0 : 618 if kw.has_key('dataset'): 619 manager.listImagesInDataset(kw.get('dataset'), filter_user_id, page) 620 if view =='icon': 621 template = "webclient/data/containers_icon.html" 622 elif view =='table': 623 template = "webclient/data/containers_table.html" 624 else: 625 template = "webclient/data/container_subtree.html" 626 elif kw.has_key('plate'): 627 fields = manager.plate.getFields(kw.get('acquisition', None)) 628 if fields is not None: 629 form_well_index = WellIndexForm(initial={'index':index, 'range':fields}) 630 if index == 0: 631 index = fields[0] 632 template = "webclient/data/plate.html" 633 else: 634 manager.listContainerHierarchy(filter_user_id) 635 if view =='tree': 636 template = "webclient/data/containers_tree.html" 637 elif view =='icon': 638 template = "webclient/data/containers_icon.html" 639 elif view =='table': 640 template = "webclient/data/containers_table.html" 641 else: 642 template = "webclient/data/containers.html" 643 644 context = {'nav':request.session['nav'], 'url':url, 'eContext':manager.eContext, 'manager':manager, 'form_well_index':form_well_index, 'index':index} 645 646 t = template_loader.get_template(template) 647 c = Context(request,context) 648 logger.debug('TEMPLATE: '+template) 649 return HttpResponse(t.render(c))
650
651 @isUserConnected 652 -def load_searching(request, form=None, **kwargs):
653 request.session.modified = True 654 655 # check menu 656 menu = request.REQUEST.get("menu") 657 if menu is not None: 658 request.session['nav']['menu'] = menu 659 else: 660 menu = request.session['nav']['menu'] 661 # check view 662 view = request.REQUEST.get("view") 663 if view is not None: 664 request.session['nav']['view'] = view 665 else: 666 view = request.session['nav']['view'] 667 668 # get connection 669 conn = None 670 try: 671 conn = kwargs["conn"] 672 except: 673 logger.error(traceback.format_exc()) 674 return handlerInternalError("Connection is not available. Please contact your administrator.") 675 676 # get url to redirect 677 url = None 678 try: 679 url = kwargs["url"] 680 except: 681 logger.error(traceback.format_exc()) 682 if url is None: 683 url = reverse(viewname="load_template", args=[menu]) 684 685 # get page 686 try: 687 page = int(request.REQUEST['page']) 688 except: 689 page = 1 690 691 manager = BaseSearch(conn) 692 if form is not None: 693 query_search = request.REQUEST.get('query').replace("+", " ") 694 print "".replace("+", " ") 695 template = "webclient/search/search_details.html" 696 697 onlyTypes = list() 698 if request.REQUEST.get('projects') is not None and request.REQUEST.get('projects') == 'on': 699 onlyTypes.append('projects') 700 if request.REQUEST.get('datasets') is not None and request.REQUEST.get('datasets') == 'on': 701 onlyTypes.append('datasets') 702 if request.REQUEST.get('images') is not None and request.REQUEST.get('images') == 'on': 703 onlyTypes.append('images') 704 if request.REQUEST.get('plates') is not None and request.REQUEST.get('plates') == 'on': 705 onlyTypes.append('plates') 706 if request.REQUEST.get('screens') is not None and request.REQUEST.get('screens') == 'on': 707 onlyTypes.append('screens') 708 709 date = request.REQUEST.get('dateperiodinput', None) 710 if date is not None: 711 date = smart_str(date) 712 713 manager.search(query_search, onlyTypes, date) 714 else: 715 template = "webclient/search/search.html" 716 717 batch_query = request.REQUEST.get('batch_query') 718 if batch_query is not None: 719 delimiter = request.REQUEST.get('delimiter') 720 delimiter = delimiter.decode("string_escape") 721 batch_query = batch_query.split("\n") 722 batch_query = [query.split(delimiter) for query in batch_query] 723 template = "webclient/search/search_details.html" 724 manager.batch_search(batch_query) 725 726 context = {'nav':request.session['nav'], 'url':url, 'eContext':manager.eContext, 'manager':manager} 727 728 t = template_loader.get_template(template) 729 c = Context(request,context) 730 logger.debug('TEMPLATE: '+template) 731 return HttpResponse(t.render(c))
732
733 @isUserConnected 734 -def load_data_by_tag(request, o_type=None, o_id=None, **kwargs):
735 request.session.modified = True 736 737 if request.REQUEST.get("o_type") is not None and len(request.REQUEST.get("o_type")) > 0: 738 o_type = request.REQUEST.get("o_type") 739 try: 740 o_id = long(request.REQUEST.get("o_id")) 741 except: 742 pass 743 744 # check menu 745 menu = request.REQUEST.get("menu") 746 if menu is not None: 747 request.session['nav']['menu'] = menu 748 else: 749 menu = request.session['nav']['menu'] 750 751 # check view 752 view = request.REQUEST.get("view") 753 if view is not None: 754 request.session['nav']['view'] = view 755 else: 756 view = request.session['nav']['view'] 757 758 # get connection 759 conn = None 760 try: 761 conn = kwargs["conn"] 762 except: 763 logger.error(traceback.format_exc()) 764 return handlerInternalError("Connection is not available. Please contact your administrator.") 765 766 # get url to redirect 767 url = None 768 try: 769 url = kwargs["url"] 770 except: 771 logger.error(traceback.format_exc()) 772 if url is None: 773 url = reverse(viewname="load_data_by_tag") 774 775 # get page 776 try: 777 page = int(request.REQUEST['page']) 778 except: 779 page = None 780 781 # get index of the plate 782 try: 783 index = int(request.REQUEST['index']) 784 except: 785 index = 0 786 787 # prepare forms 788 filter_user_id = request.session.get('nav')['experimenter'] 789 790 # prepare data 791 kw = dict() 792 if o_type is not None and o_id > 0: 793 kw[str(o_type)] = long(o_id) 794 try: 795 manager= BaseContainer(conn, **kw) 796 except AttributeError, x: 797 logger.error(traceback.format_exc()) 798 return handlerInternalError(x) 799 800 if o_id is not None: 801 if o_type == "tag": 802 manager.loadDataByTag() 803 if view == "tree": 804 template = "webclient/data/container_tags_containers.html" 805 elif view == "icon": 806 template = "webclient/data/containers_icon.html" 807 elif view == "table": 808 template = "webclient/data/containers_table.html" 809 810 elif o_type == "dataset": 811 manager.listImagesInDataset(o_id, filter_user_id) 812 template = "webclient/data/container_tags_subtree.html" 813 else: 814 manager.loadTags(filter_user_id) 815 template = "webclient/data/container_tags_tree.html" 816 # load data 817 form_well_index = None 818 819 820 context = {'nav':request.session['nav'], 'url':url, 'eContext':manager.eContext, 'manager':manager, 'form_well_index':form_well_index} 821 822 t = template_loader.get_template(template) 823 c = Context(request,context) 824 logger.debug('TEMPLATE: '+template) 825 return HttpResponse(t.render(c))
826
827 @isUserConnected 828 -def autocomplete_tags(request, **kwargs):
829 conn = None 830 try: 831 conn = kwargs["conn"] 832 except: 833 logger.error(traceback.format_exc()) 834 return handlerInternalError("Connection is not available. Please contact your administrator.") 835 836 eid = conn.getGroupFromContext().isReadOnly() and conn.getEventContext().userId or None 837 838 tags = [{'tag': t.textValue,'id':t.id, 'desc':t.description} for t in conn.listTags(eid)] 839 json_data = simplejson.dumps(tags) 840 return HttpResponse(json_data, mimetype='application/javascript')
841
842 @isUserConnected 843 -def open_astex_viewer(request, obj_type, obj_id, **kwargs):
844 conn = None 845 try: 846 conn = kwargs["conn"] 847 except: 848 logger.error(traceback.format_exc()) 849 return handlerInternalError("Connection is not available. Please contact your administrator.") 850 851 # can only populate these for 'image' 852 image = None 853 data_storage_mode = None 854 pixelRange = None # (min, max) values of the raw data 855 # If we convert to 8bit map, subtract dataOffset, multiply by mapPixelFactor add mapOffset. (used for js contour controls) 856 if obj_type == 'file': 857 ann = conn.getObject("Annotation", obj_id) 858 if ann is None: 859 return handlerInternalError("Can't find file Annotation ID %s as data source for Open Astex Viewer." % obj_id) 860 # determine mapType by name 861 imageName = ann.getFileName() 862 if imageName.endswith(".bit"): 863 data_url = reverse("open_astex_bit", args=[obj_id]) 864 else: 865 data_url = reverse("open_astex_map", args=[obj_id]) 866 867 elif obj_type in ('image', 'image_8bit'): 868 image = conn.getObject("Image", obj_id) # just check the image exists 869 if image is None: 870 return handlerInternalError("Can't find image ID %s as data source for Open Astex Viewer." % obj_id) 871 imageName = image.getName() 872 c = image.getChannels()[0] 873 # By default, scale to 120 ^3. Also give option to load 'bigger' map or full sized 874 DEFAULTMAPSIZE = 120 875 BIGGERMAPSIZE = 160 876 targetSize = DEFAULTMAPSIZE * DEFAULTMAPSIZE * DEFAULTMAPSIZE 877 biggerSize = BIGGERMAPSIZE * BIGGERMAPSIZE * BIGGERMAPSIZE 878 imgSize = image.getSizeX() * image.getSizeY() * image.getSizeZ() 879 sizeOptions = None # only give user choice if we need to scale down (and we CAN scale with scipy) 880 if imgSize > targetSize: 881 try: 882 import scipy.ndimage 883 sizeOptions = {} 884 factor = float(targetSize)/ imgSize 885 f = pow(factor,1.0/3) 886 sizeOptions["small"] = {'x':image.getSizeX() * f, 'y':image.getSizeY() * f, 'z':image.getSizeZ() * f, 'size':DEFAULTMAPSIZE} 887 if imgSize > biggerSize: 888 factor2 = float(biggerSize)/ imgSize 889 f2 = pow(factor2,1.0/3) 890 sizeOptions["medium"] = {'x':image.getSizeX() * f2, 'y':image.getSizeY() * f2, 'z':image.getSizeZ() * f2, 'size':BIGGERMAPSIZE} 891 else: 892 sizeOptions["full"] = {'x':image.getSizeX(), 'y':image.getSizeY(), 'z':image.getSizeZ()} 893 except ImportError: 894 DEFAULTMAPSIZE = 0 # don't try to resize the map (see image_as_map) 895 pass 896 pixelRange = (c.getWindowMin(), c.getWindowMax()) 897 contourSliderInit = (pixelRange[0] + pixelRange[1])/2 # best guess as starting position for contour slider 898 899 def calcPrecision(range): 900 dec=0 901 if (range == 0): dec = 0 902 elif (range < 0.0000001): dec = 10 903 elif (range < 0.000001): dec = 9 904 elif (range < 0.00001): dec = 8 905 elif (range < 0.0001): dec = 7 906 elif (range < 0.001): dec = 6 907 elif (range < 0.01): dec = 5 908 elif (range < 0.1): dec = 4 909 elif (range < 1.0): dec = 3 910 elif (range < 10.0): dec = 2 911 elif (range < 100.0): dec = 1 912 return dec
913 dec = calcPrecision(pixelRange[1]-pixelRange[0]) 914 contourSliderIncr = "%.*f" % (dec,abs((pixelRange[1]-pixelRange[0])/128.0)) 915 916 if obj_type == 'image_8bit': 917 data_storage_mode = 1 918 data_url = reverse("webclient_image_as_map_8bit", args=[obj_id, DEFAULTMAPSIZE]) 919 else: 920 if image.getPrimaryPixels().getPixelsType.value == 'float': 921 data_storage_mode = 2 922 else: 923 data_storage_mode = 1 # E.g. uint16 image will get served as 8bit map 924 data_url = reverse("webclient_image_as_map", args=[obj_id, DEFAULTMAPSIZE]) 925 926 return render_to_response('webclient/annotations/open_astex_viewer.html', {'data_url': data_url, "image": image, 927 "sizeOptions":sizeOptions, "contourSliderInit":contourSliderInit, "contourSliderIncr":contourSliderIncr, 928 "data_storage_mode": data_storage_mode,'pixelRange':pixelRange}) 929
930 931 @isUserConnected 932 -def load_metadata_details(request, c_type, c_id, share_id=None, **kwargs):
933 conn = None 934 try: 935 conn = kwargs["conn"] 936 except: 937 logger.error(traceback.format_exc()) 938 return handlerInternalError("Connection is not available. Please contact your administrator.") 939 940 conn_share = None 941 try: 942 conn_share = kwargs["conn_share"] 943 except: 944 logger.error(traceback.format_exc()) 945 return handlerInternalError("Connection is not available. Please contact your administrator.") 946 947 url = None 948 try: 949 url = kwargs["url"] 950 except: 951 logger.error(traceback.format_exc()) 952 953 try: 954 index = int(request.REQUEST['index']) 955 except: 956 index = 0 957 958 form_comment = None 959 try: 960 if c_type in ("share", "discussion"): 961 template = "webclient/annotations/annotations_share.html" 962 manager = BaseShare(conn, conn_share, c_id) 963 manager.getAllUsers(c_id) 964 manager.getComments(c_id) 965 form_comment = ShareCommentForm() 966 else: 967 if conn_share is not None: 968 template = "webclient/annotations/annotations_share.html" 969 manager = BaseContainer(conn_share, index=index, **{str(c_type): long(c_id)}) 970 else: 971 #template = "webclient/annotations/annotations.html" 972 template = "webclient/annotations/metadata_general.html" 973 manager = BaseContainer(conn, index=index, **{str(c_type): long(c_id)}) 974 manager.annotationList() 975 form_comment = CommentAnnotationForm() 976 except AttributeError, x: 977 logger.error(traceback.format_exc()) 978 return handlerInternalError(x) 979 980 if c_type in ("tag"): 981 context = {'nav':request.session['nav'], 'url':url, 'eContext': manager.eContext, 'manager':manager} 982 else: 983 context = {'nav':request.session['nav'], 'url':url, 'eContext':manager.eContext, 'manager':manager, 'form_comment':form_comment, 'index':index} 984 985 t = template_loader.get_template(template) 986 c = Context(request,context) 987 logger.debug('TEMPLATE: '+template) 988 return HttpResponse(t.render(c))
989
990 @isUserConnected 991 -def load_metadata_preview(request, imageId, share_id=None, **kwargs):
992 993 conn = None 994 try: 995 conn = kwargs["conn"] 996 except: 997 logger.error(traceback.format_exc()) 998 return handlerInternalError("Connection is not available. Please contact your administrator.") 999 1000 conn_share = None 1001 try: 1002 conn_share = kwargs["conn_share"] 1003 except: 1004 logger.error(traceback.format_exc()) 1005 return handlerInternalError("Connection is not available. Please contact your administrator.") 1006 1007 url = None 1008 try: 1009 url = kwargs["url"] 1010 except: 1011 logger.error(traceback.format_exc()) 1012 1013 try: 1014 template = "webclient/annotations/metadata_preview.html" 1015 if conn_share is not None: 1016 manager = BaseContainer(conn_share, index=index, image=long(imageId)) 1017 else: 1018 manager = BaseContainer(conn, index=index, image=long(imageId)) 1019 except AttributeError, x: 1020 logger.error(traceback.format_exc()) 1021 return handlerInternalError(x) 1022 1023 context = {'imageId':imageId, 'manager':manager} 1024 1025 t = template_loader.get_template(template) 1026 c = Context(request,context) 1027 logger.debug('TEMPLATE: '+template) 1028 return HttpResponse(t.render(c))
1029
1030 @isUserConnected 1031 -def load_metadata_hierarchy(request, c_type, c_id, **kwargs):
1032 conn = None 1033 try: 1034 conn = kwargs["conn"] 1035 except: 1036 logger.error(traceback.format_exc()) 1037 return handlerInternalError("Connection is not available. Please contact your administrator.") 1038 1039 conn_share = None 1040 try: 1041 conn_share = kwargs["conn_share"] 1042 except: 1043 logger.error(traceback.format_exc()) 1044 return handlerInternalError("Connection is not available. Please contact your administrator.") 1045 1046 url = None 1047 try: 1048 url = kwargs["url"] 1049 except: 1050 logger.error(traceback.format_exc()) 1051 1052 try: 1053 index = int(request.REQUEST['index']) 1054 except: 1055 index = 0 1056 1057 try: 1058 template = "webclient/annotations/metadata_hierarchy.html" 1059 if conn_share is not None: 1060 manager = BaseContainer(conn_share, index=index, **{str(c_type): long(c_id)}) 1061 else: 1062 manager = BaseContainer(conn, index=index, **{str(c_type): long(c_id)}) 1063 except AttributeError, x: 1064 logger.error(traceback.format_exc()) 1065 return handlerInternalError(x) 1066 1067 context = {'manager':manager} 1068 1069 t = template_loader.get_template(template) 1070 c = Context(request,context) 1071 logger.debug('TEMPLATE: '+template) 1072 return HttpResponse(t.render(c))
1073
1074 @isUserConnected 1075 -def load_metadata_acquisition(request, c_type, c_id, share_id=None, **kwargs):
1076 conn = None 1077 try: 1078 conn = kwargs["conn"] 1079 except: 1080 logger.error(traceback.format_exc()) 1081 return handlerInternalError("Connection is not available. Please contact your administrator.") 1082 1083 conn_share = None 1084 try: 1085 conn_share = kwargs["conn_share"] 1086 except: 1087 logger.error(traceback.format_exc()) 1088 return handlerInternalError("Connection is not available. Please contact your administrator.") 1089 1090 url = None 1091 try: 1092 url = kwargs["url"] 1093 except: 1094 logger.error(traceback.format_exc()) 1095 1096 try: 1097 index = int(request.REQUEST['index']) 1098 except: 1099 index = 0 1100 1101 try: 1102 if c_type in ("share", "discussion"): 1103 template = "webclient/annotations/annotations_share.html" 1104 manager = BaseShare(conn, conn_share, c_id) 1105 manager.getAllUsers(c_id) 1106 manager.getComments(c_id) 1107 else: 1108 if conn_share is not None: 1109 template = "webclient/annotations/metadata_acquisition.html" 1110 manager = BaseContainer(conn_share, index=index, **{str(c_type): long(c_id)}) 1111 else: 1112 template = "webclient/annotations/metadata_acquisition.html" 1113 manager = BaseContainer(conn, index=index, **{str(c_type): long(c_id)}) 1114 except AttributeError, x: 1115 logger.error(traceback.format_exc()) 1116 return handlerInternalError(x) 1117 1118 form_environment = None 1119 form_objective = None 1120 form_microscope = None 1121 form_instrument_objectives = list() 1122 form_stageLabel = None 1123 form_filters = list() 1124 form_dichroics = list() 1125 form_detectors = list() 1126 form_channels = list() 1127 form_lasers = list() 1128 1129 # various enums we need for the forms (don't load unless needed) 1130 mediums = None 1131 immersions = None 1132 corrections = None 1133 1134 if c_type == 'well' or c_type == 'image': 1135 if conn_share is None: 1136 manager.originalMetadata() 1137 manager.channelMetadata() 1138 for theC, ch in enumerate(manager.channel_metadata): 1139 logicalChannel = ch.getLogicalChannel() 1140 if logicalChannel is not None: 1141 channel = dict() 1142 channel['form'] = MetadataChannelForm(initial={'logicalChannel': logicalChannel, 1143 'illuminations': list(conn.getEnumerationEntries("IlluminationI")), 1144 'contrastMethods': list(conn.getEnumerationEntries("ContrastMethodI")), 1145 'modes': list(conn.getEnumerationEntries("AcquisitionModeI"))}) 1146 lightPath = logicalChannel.getLightPath() 1147 if lightPath is not None: 1148 channel['form_dichroic'] = None 1149 channel['form_excitation_filters'] = list() 1150 channel['form_emission_filters'] = list() 1151 lightPathDichroic = lightPath.getDichroic() 1152 if lightPathDichroic is not None: 1153 channel['form_dichroic'] = MetadataDichroicForm(initial={'dichroic': lightPathDichroic}) 1154 filterTypes = list(conn.getEnumerationEntries("FilterTypeI")) 1155 for f in lightPath.copyEmissionFilters(): 1156 channel['form_emission_filters'].append(MetadataFilterForm(initial={'filter': f,'types':filterTypes})) 1157 for f in lightPath.copyExcitationFilters(): 1158 channel['form_excitation_filters'].append(MetadataFilterForm(initial={'filter': f,'types':filterTypes})) 1159 if logicalChannel.getDetectorSettings()._obj is not None and logicalChannel.getDetectorSettings().getDetector(): 1160 channel['form_detector_settings'] = MetadataDetectorForm(initial={'detectorSettings':logicalChannel.getDetectorSettings(), 1161 'detector': logicalChannel.getDetectorSettings().getDetector(), 1162 'types':list(conn.getEnumerationEntries("DetectorTypeI")), 1163 'binnings':list(conn.getEnumerationEntries("Binning"))}) 1164 1165 lightSourceSettings = logicalChannel.getLightSourceSettings() 1166 if lightSourceSettings is not None and lightSourceSettings._obj is not None: 1167 if lightSourceSettings.getLightSource() is not None: 1168 channel['form_light_source'] = MetadataLightSourceForm(initial={'lightSource': lightSourceSettings.getLightSource(), 1169 'lstypes': list(conn.getEnumerationEntries("LaserType")), 1170 'mediums': list(conn.getEnumerationEntries("LaserMediumI")), 1171 'pulses': list(conn.getEnumerationEntries("PulseI"))}) 1172 # TODO: We don't display filter sets here yet since they are not populated on Import by BioFormats. 1173 channel['label'] = ch.getLabel() 1174 color = ch.getColor() 1175 channel['color'] = color is not None and color.getHtml() or None 1176 planeInfo = manager.image and manager.image.getPrimaryPixels().copyPlaneInfo(theC=theC, theZ=0) 1177 channel['plane_info'] = list(planeInfo) 1178 form_channels.append(channel) 1179 1180 try: 1181 image = manager.well.getWellSample().image() 1182 except: 1183 image = manager.image 1184 1185 if image.getObjectiveSettings() is not None: 1186 # load the enums if needed and create our Objective Form 1187 if mediums is None: mediums = list(conn.getEnumerationEntries("MediumI")) 1188 if immersions is None: immersions = list(conn.getEnumerationEntries("ImmersionI")) 1189 if corrections is None: corrections = list(conn.getEnumerationEntries("CorrectionI")) 1190 form_objective = MetadataObjectiveSettingsForm(initial={'objectiveSettings': image.getObjectiveSettings(), 1191 'objective': image.getObjectiveSettings().getObjective(), 1192 'mediums': mediums, 'immersions': immersions, 'corrections': corrections }) 1193 if image.getImagingEnvironment() is not None: 1194 form_environment = MetadataEnvironmentForm(initial={'image': image}) 1195 if image.getStageLabel() is not None: 1196 form_stageLabel = MetadataStageLabelForm(initial={'image': image }) 1197 1198 instrument = image.getInstrument() 1199 if instrument is not None: 1200 if instrument.getMicroscope() is not None: 1201 form_microscope = MetadataMicroscopeForm(initial={'microscopeTypes':list(conn.getEnumerationEntries("MicroscopeTypeI")), 'microscope': instrument.getMicroscope()}) 1202 1203 objectives = instrument.getObjectives() 1204 for o in objectives: 1205 # load the enums if needed and create our Objective Form 1206 if mediums is None: mediums = list(conn.getEnumerationEntries("MediumI")) 1207 if immersions is None: immersions = list(conn.getEnumerationEntries("ImmersionI")) 1208 if corrections is None: corrections = list(conn.getEnumerationEntries("CorrectionI")) 1209 obj_form = MetadataObjectiveForm(initial={'objective': o, 1210 'mediums': mediums, 'immersions': immersions, 'corrections': corrections }) 1211 form_instrument_objectives.append(obj_form) 1212 filters = list(instrument.getFilters()) 1213 if len(filters) > 0: 1214 for f in filters: 1215 form_filter = MetadataFilterForm(initial={'filter': f, 'types':list(conn.getEnumerationEntries("FilterTypeI"))}) 1216 form_filters.append(form_filter) 1217 1218 dichroics = list(instrument.getDichroics()) 1219 for d in dichroics: 1220 form_dichroic = MetadataDichroicForm(initial={'dichroic': d}) 1221 form_dichroics.append(form_dichroic) 1222 1223 detectors = list(instrument.getDetectors()) 1224 if len(detectors) > 0: 1225 for d in detectors: 1226 form_detector = MetadataDetectorForm(initial={'detectorSettings':None, 'detector': d, 'types':list(conn.getEnumerationEntries("DetectorTypeI"))}) 1227 form_detectors.append(form_detector) 1228 1229 lasers = list(instrument.getLightSources()) 1230 if len(lasers) > 0: 1231 for l in lasers: 1232 form_laser = MetadataLightSourceForm(initial={'lightSource': l, 1233 'lstypes':list(conn.getEnumerationEntries("LaserType")), 1234 'mediums': list(conn.getEnumerationEntries("LaserMediumI")), 1235 'pulses': list(conn.getEnumerationEntries("PulseI"))}) 1236 form_lasers.append(form_laser) 1237 1238 if c_type in ("share", "discussion", "tag"): 1239 context = {'nav':request.session['nav'], 'url':url, 'eContext': manager.eContext, 'manager':manager} 1240 else: 1241 context = {'nav':request.session['nav'], 'url':url, 'eContext':manager.eContext, 'manager':manager, 1242 'form_channels':form_channels, 'form_environment':form_environment, 'form_objective':form_objective, 1243 'form_microscope':form_microscope, 'form_instrument_objectives': form_instrument_objectives, 'form_filters':form_filters, 1244 'form_dichroics':form_dichroics, 'form_detectors':form_detectors, 'form_lasers':form_lasers, 'form_stageLabel':form_stageLabel} 1245 1246 t = template_loader.get_template(template) 1247 c = Context(request,context) 1248 logger.debug('TEMPLATE: '+template) 1249 return HttpResponse(t.render(c)) 1250
1251 1252 ########################################################################### 1253 # ACTIONS 1254 1255 @isUserConnected 1256 -def manage_annotation_multi(request, action=None, **kwargs):
1257 template = "webclient/annotations/annotation_new_form_multi.html" 1258 1259 conn = None 1260 try: 1261 conn = kwargs["conn"] 1262 1263 except: 1264 logger.error(traceback.format_exc()) 1265 return handlerInternalError("Connection is not available. Please contact your administrator.") 1266 1267 # check menu 1268 menu = request.REQUEST.get("menu") 1269 if menu is not None: 1270 request.session['nav']['menu'] = menu 1271 else: 1272 menu = request.session['nav']['menu'] 1273 1274 url = None 1275 try: 1276 url = kwargs["url"] 1277 except: 1278 logger.error(traceback.format_exc()) 1279 1280 try: 1281 index = int(request.REQUEST['index']) 1282 except: 1283 index = None 1284 1285 try: 1286 manager = BaseContainer(conn, index=index) 1287 except AttributeError, x: 1288 logger.error(traceback.format_exc()) 1289 return handlerInternalError(x) 1290 1291 oids = {'image':request.REQUEST.getlist('image'), 'dataset':request.REQUEST.getlist('dataset'), 'project':request.REQUEST.getlist('project'), 'screen':request.REQUEST.getlist('screen'), 'plate':request.REQUEST.getlist('plate'), 'well':request.REQUEST.getlist('well')} 1292 1293 images = len(request.REQUEST.getlist('image')) > 0 and list(conn.getObjects("Image", request.REQUEST.getlist('image'))) or list() 1294 datasets = len(request.REQUEST.getlist('dataset')) > 0 and list(conn.getObjects("Dataset", request.REQUEST.getlist('dataset'))) or list() 1295 projects = len(request.REQUEST.getlist('project')) > 0 and list(conn.getObjects("Project", request.REQUEST.getlist('project'))) or list() 1296 screens = len(request.REQUEST.getlist('screen')) > 0 and list(conn.getObjects("Screen", request.REQUEST.getlist('screen'))) or list() 1297 plates = len(request.REQUEST.getlist('plate')) > 0 and list(conn.getObjects("Plate", request.REQUEST.getlist('plate'))) or list() 1298 acquisitions = len(request.REQUEST.getlist('acquisition')) > 0 and list(conn.getObjects("PlateAcquisition", request.REQUEST.getlist('acquisition'))) or list() 1299 wells = list() 1300 if len(request.REQUEST.getlist('well')) > 0: 1301 for w in conn.getObjects("Well", request.REQUEST.getlist('well')): 1302 w.index=index 1303 wells.append(w) 1304 1305 oids = {'image':images, 'dataset':datasets, 'project':projects, 'screen':screens, 'plate':plates, 'acquisitions':acquisitions, 'well':wells} 1306 1307 count = {'images':len(images), 'datasets':len(datasets), 'projects':len(projects), 'screens':len(screens), 'plates':len(plates), 'wells':len(wells)} 1308 1309 form_multi = None 1310 if action == "annotatemany": 1311 selected = {'images':request.REQUEST.getlist('image'), 'datasets':request.REQUEST.getlist('dataset'), 'projects':request.REQUEST.getlist('project'), 'screens':request.REQUEST.getlist('screen'), 'plates':request.REQUEST.getlist('plate'), 'acquisitions':request.REQUEST.getlist('acquisition'), 'wells':request.REQUEST.getlist('well')} 1312 form_multi = MultiAnnotationForm(initial={'tags':manager.getTagsByObject(), 'files':manager.getFilesByObject(), 'selected':selected, 'images':images, 'datasets':datasets, 'projects':projects, 'screens':screens, 'plates':plates, 'acquisitions':acquisitions, 'wells':wells}) 1313 else: 1314 if request.method == 'POST': 1315 form_multi = MultiAnnotationForm(initial={'tags':manager.getTagsByObject(), 'files':manager.getFilesByObject(), 'images':images, 'datasets':datasets, 'projects':projects, 'screens':screens, 'plates':plates, 'acquisitions':acquisitions, 'wells':wells}, data=request.REQUEST.copy(), files=request.FILES) 1316 if form_multi.is_valid(): 1317 1318 content = form_multi.cleaned_data['content'] 1319 if content is not None and content != "": 1320 manager.createCommentAnnotations(content, oids) 1321 1322 tag = form_multi.cleaned_data['tag'] 1323 description = form_multi.cleaned_data['description'] 1324 if tag is not None and tag != "": 1325 manager.createTagAnnotations(tag, description, oids) 1326 1327 tags = request.REQUEST.getlist('tags') 1328 if tags is not None and len(tags) > 0: 1329 manager.createAnnotationsLinks('tag', tags, oids) 1330 1331 files = request.REQUEST.getlist('files') 1332 if files is not None and len(files) > 0: 1333 manager.createAnnotationsLinks('file', files, oids) 1334 1335 f = request.FILES.get('annotation_file') 1336 if f is not None: 1337 manager.createFileAnnotations(f, oids) 1338 1339 return HttpJavascriptRedirect(reverse(viewname="load_template", args=[menu])) 1340 1341 context = {'url':url, 'nav':request.session['nav'], 'eContext':manager.eContext, 'manager':manager, 'form_multi':form_multi, 'count':count, 'oids':oids, 'index':index} 1342 1343 t = template_loader.get_template(template) 1344 c = Context(request,context) 1345 logger.debug('TEMPLATE: '+template) 1346 return HttpResponse(t.render(c)) 1347
1348 @isUserConnected 1349 -def manage_action_containers(request, action, o_type=None, o_id=None, **kwargs):
1350 template = None 1351 1352 conn = None 1353 try: 1354 conn = kwargs["conn"] 1355 except: 1356 logger.error(traceback.format_exc()) 1357 return handlerInternalError("Connection is not available. Please contact your administrator.") 1358 1359 # check menu 1360 menu = request.REQUEST.get("menu") 1361 if menu is not None: 1362 request.session['nav']['menu'] = menu 1363 else: 1364 menu = request.session['nav']['menu'] 1365 1366 url = None 1367 try: 1368 url = kwargs["url"] 1369 except: 1370 logger.error(traceback.format_exc()) 1371 1372 try: 1373 index = int(request.REQUEST['index']) 1374 except: 1375 index = None 1376 1377 manager = None 1378 if o_type in ("dataset", "project", "image", "screen", "plate", "acquisition", "well","comment", "file", "tag", "tagset"): 1379 if o_type == 'tagset': o_type = 'tag' # TODO: this should be handled by the BaseContainer 1380 kw = {'index':index} 1381 if o_type is not None and o_id > 0: 1382 kw[str(o_type)] = long(o_id) 1383 try: 1384 manager = BaseContainer(conn, **kw) 1385 except AttributeError, x: 1386 logger.error(traceback.format_exc()) 1387 return handlerInternalError(x) 1388 elif o_type in ("share", "sharecomment"): 1389 manager = BaseShare(conn, None, o_id) 1390 else: 1391 manager = BaseContainer(conn) 1392 1393 form = None 1394 if action == 'new': 1395 template = "webclient/data/container_new.html" 1396 form = ContainerForm() 1397 context = {'nav':request.session['nav'], 'url':url, 'eContext':manager.eContext, 'manager':manager, 'form':form} 1398 elif action == 'newcomment': 1399 template = "webclient/annotations/annotation_new_form.html" 1400 form_comment = CommentAnnotationForm() 1401 context = {'nav':request.session['nav'], 'url':url, 'manager':manager, 'eContext':manager.eContext, 'form_comment':form_comment, 'index':index} 1402 elif action == 'newtagonly': 1403 template = "webclient/annotations/annotation_new_form.html" 1404 form_tag = TagAnnotationForm() 1405 context = {'nav':request.session['nav'], 'url':url, 'manager':manager, 'eContext':manager.eContext, 'form_tag':form_tag} 1406 elif action == 'newtag': 1407 template = "webclient/annotations/annotation_new_form.html" 1408 form_tag = TagAnnotationForm() 1409 form_tags = TagListForm(initial={'tags':manager.getTagsByObject()}) 1410 context = {'nav':request.session['nav'], 'url':url, 'manager':manager, 'eContext':manager.eContext, 'form_tag':form_tag, 'form_tags':form_tags, 'index':index} 1411 elif action == 'newfile': 1412 template = "webclient/annotations/annotation_new_form.html" 1413 form_file = UploadFileForm() 1414 form_files = FileListForm(initial={'files':manager.getFilesByObject()}) 1415 context = {'nav':request.session['nav'], 'url':url, 'manager':manager, 'eContext':manager.eContext, 'form_file':form_file, 'form_files':form_files, 'index':index} 1416 elif action == 'newsharecomment': 1417 template = "webclient/annotations/annotation_new_form.html" 1418 if manager.share.isExpired(): 1419 form_sharecomments = None 1420 else: 1421 form_sharecomments = ShareCommentForm() 1422 context = {'nav':request.session['nav'], 'url':url, 'eContext': manager.eContext, 'manager':manager, 'form_sharecomments':form_sharecomments} 1423 elif action == 'addnewcontainer': 1424 if not request.method == 'POST': 1425 return HttpResponseRedirect(reverse("manage_action_containers", args=["edit", o_type, o_id])) 1426 if o_type is not None and hasattr(manager, o_type) and o_id > 0: 1427 form = ContainerForm(data=request.REQUEST.copy()) 1428 if form.is_valid(): 1429 logger.debug("Create new in %s: %s" % (o_type, str(form.cleaned_data))) 1430 name = form.cleaned_data['name'] 1431 description = form.cleaned_data['description'] 1432 oid = manager.createDataset(name, description) 1433 rdict = {'bad':'false', 'id': oid} 1434 json = simplejson.dumps(rdict, ensure_ascii=False) 1435 return HttpResponse( json, mimetype='application/javascript') 1436 else: 1437 d = dict() 1438 for e in form.errors.iteritems(): 1439 d.update({e[0]:unicode(e[1])}) 1440 rdict = {'bad':'true','errs': d } 1441 json = simplejson.dumps(rdict, ensure_ascii=False) 1442 return HttpResponse( json, mimetype='application/javascript') 1443 elif request.REQUEST.get('folder_type') in ("project", "screen", "dataset"): 1444 form = ContainerForm(data=request.REQUEST.copy()) 1445 if form.is_valid(): 1446 logger.debug("Create new: %s" % (str(form.cleaned_data))) 1447 name = form.cleaned_data['name'] 1448 description = form.cleaned_data['description'] 1449 oid = getattr(manager, "create"+request.REQUEST.get('folder_type').capitalize())(name, description) 1450 rdict = {'bad':'false', 'id': oid} 1451 json = simplejson.dumps(rdict, ensure_ascii=False) 1452 return HttpResponse( json, mimetype='application/javascript') 1453 else: 1454 d = dict() 1455 for e in form.errors.iteritems(): 1456 d.update({e[0]:unicode(e[1])}) 1457 rdict = {'bad':'true','errs': d } 1458 json = simplejson.dumps(rdict, ensure_ascii=False) 1459 return HttpResponse( json, mimetype='application/javascript') 1460 else: 1461 return HttpResponseServerError("Object does not exist") 1462 elif action == 'addnew': 1463 if not request.method == 'POST': 1464 return HttpResponseRedirect(reverse("manage_action_containers", args=["action", "new"])) 1465 if o_type == "project" and o_id > 0: 1466 form = ContainerForm(data=request.REQUEST.copy()) 1467 if form.is_valid(): 1468 logger.debug("Create new dataset: %s" % (str(form.cleaned_data))) 1469 name = form.cleaned_data['name'] 1470 description = form.cleaned_data['description'] 1471 manager.createDataset(name, description) 1472 return HttpJavascriptRedirect(reverse(viewname="load_template", args=[menu])) 1473 else: 1474 template = "webclient/data/container_new.html" 1475 context = {'nav':request.session['nav'], 'url':url, 'manager':manager, 'form':form} 1476 else: 1477 if request.REQUEST.get('folder_type') in ("project", "screen", "dataset"): 1478 form = ContainerForm(data=request.REQUEST.copy()) 1479 if form.is_valid(): 1480 logger.debug("Create new folder: %s" % (str(form.cleaned_data))) 1481 name = form.cleaned_data['name'] 1482 description = form.cleaned_data['description'] 1483 getattr(manager, "create"+request.REQUEST.get('folder_type').capitalize())(name, description) 1484 return HttpJavascriptRedirect(reverse(viewname="load_template", args=[menu])) 1485 else: 1486 template = "webclient/data/container_new.html" 1487 context = {'nav':request.session['nav'], 'url':url, 'manager':manager, 'form':form} 1488 elif action == 'edit': 1489 if o_type == "share" and o_id > 0: 1490 template = "webclient/public/share_form.html" 1491 manager.getMembers(o_id) 1492 manager.getComments(o_id) 1493 experimenters = list(conn.getExperimenters()) 1494 experimenters.sort(key=lambda x: x.getOmeName().lower()) 1495 if manager.share.getExpirationDate() is not None: 1496 form = ShareForm(initial={'message': manager.share.message, 'expiration': manager.share.getExpirationDate().strftime("%Y-%m-%d"), \ 1497 'shareMembers': manager.membersInShare, 'enable': manager.share.active, \ 1498 'experimenters': experimenters}) #'guests': share.guestsInShare, 1499 else: 1500 form = ShareForm(initial={'message': manager.share.message, 'expiration': "", \ 1501 'shareMembers': manager.membersInShare, 'enable': manager.share.active, \ 1502 'experimenters': experimenters}) #'guests': share.guestsInShare, 1503 context = {'url':url, 'nav':request.session['nav'], 'eContext': manager.eContext, 'share':manager, 'form':form} 1504 elif hasattr(manager, o_type) and o_id > 0: 1505 obj = getattr(manager, o_type) 1506 template = "webclient/data/container_form.html" 1507 form = ContainerForm(initial={'name': obj.name, 'description':obj.description}) 1508 context = {'nav':request.session['nav'], 'url':url, 'eContext':manager.eContext, 'manager':manager, 'form':form} 1509 elif action == 'save': 1510 if not request.method == 'POST': 1511 return HttpResponseRedirect(reverse("manage_action_containers", args=["edit", o_type, o_id])) 1512 if o_type in ("project", "dataset", "image", "screen", "plate", "well"): 1513 if hasattr(manager, o_type) and o_id > 0: 1514 form = ContainerForm(data=request.REQUEST.copy()) 1515 if form.is_valid(): 1516 logger.debug("Update: %s" % (str(form.cleaned_data))) 1517 name = form.cleaned_data['name'] 1518 description = form.cleaned_data['description'] 1519 getattr(manager, "update"+o_type.capitalize())(name, description) 1520 return HttpResponseRedirect(url) 1521 else: 1522 template = "webclient/data/container_form.html" 1523 context = {'nav':request.session['nav'], 'url':url, 'manager':manager, 'eContext':manager.eContext, 'form':form} 1524 elif o_type == 'comment': 1525 form = CommentAnnotationForm(data=request.REQUEST.copy()) 1526 if form.is_valid(): 1527 logger.debug("Save Comment: %s" % (str(form.cleaned_data))) 1528 content = form.cleaned_data['content'] 1529 manager.saveCommentAnnotation(content) 1530 return HttpResponseRedirect(url) 1531 else: 1532 template = "webclient/data/container_form.html" 1533 context = {'nav':request.session['nav'], 'url':url, 'manager':manager, 'eContext':manager.eContext, 'form':form, 'index':index} 1534 elif o_type == 'tag': 1535 form = TagAnnotationForm(data=request.REQUEST.copy()) 1536 if form.is_valid(): 1537 logger.debug("Save Tag: %s" % (str(form.cleaned_data))) 1538 tag = form.cleaned_data['tag'] 1539 description = form.cleaned_data['description'] 1540 manager.saveTagAnnotation(tag, description) 1541 return HttpResponseRedirect(url) 1542 else: 1543 template = "webclient/data/container_form.html" 1544 context = {'nav':request.session['nav'], 'url':url, 'manager':manager, 'eContext':manager.eContext, 'form':form, 'index':index} 1545 elif o_type == "share": 1546 experimenters = list(conn.getExperimenters()) 1547 experimenters.sort(key=lambda x: x.getOmeName().lower()) 1548 form = ShareForm(initial={'experimenters':experimenters}, data=request.REQUEST.copy()) 1549 if form.is_valid(): 1550 logger.debug("Update share: %s" % (str(form.cleaned_data))) 1551 message = form.cleaned_data['message'] 1552 expiration = form.cleaned_data['expiration'] 1553 members = form.cleaned_data['members'] 1554 #guests = request.REQUEST['guests'] 1555 enable = toBoolean(form.cleaned_data['enable']) 1556 try: 1557 host = '%s%s' % (settings.APPLICATION_HOST, reverse("webindex")) 1558 except: 1559 host = '%s://%s:%s%s' % (request.META['wsgi.url_scheme'], request.META['SERVER_NAME'], request.META['SERVER_PORT'], reverse("webindex")) 1560 manager.updateShareOrDiscussion(host, request.session.get('server'), message, members, enable, expiration) 1561 return HttpResponseRedirect(url) 1562 else: 1563 template = "webclient/public/share_form.html" 1564 context = {'nav':request.session['nav'], 'url':url, 'eContext': manager.eContext, 'share':manager, 'form':form} 1565 elif o_type == "sharecomment": 1566 form_sharecomments = ShareCommentForm(data=request.REQUEST.copy()) 1567 if form_sharecomments.is_valid(): 1568 logger.debug("Create share comment: %s" % (str(form_sharecomments.cleaned_data))) 1569 comment = form_sharecomments.cleaned_data['comment'] 1570 try: 1571 host = '%s%s' % (settings.APPLICATION_HOST, reverse("webindex")) 1572 except: 1573 host = '%s://%s:%s%s' % (request.META['wsgi.url_scheme'], request.META['SERVER_NAME'], request.META['SERVER_PORT'], reverse("webindex")) 1574 manager.addComment(host, request.session['server'], comment) 1575 return HttpResponseRedirect(url) 1576 else: 1577 template = "webclient/annotations/annotation_new_form.html" 1578 context = {'nav':request.session['nav'], 'url':url, 'eContext': manager.eContext, 'manager':manager, 'form_sharecomments':form_sharecomments} 1579 elif action == 'editname': 1580 if hasattr(manager, o_type) and o_id > 0: 1581 obj = getattr(manager, o_type) 1582 template = "webclient/ajax_form/container_form_ajax.html" 1583 form = ContainerNameForm(initial={'name': ((o_type != ("tag")) and obj.getName() or obj.textValue)}) 1584 context = {'nav':request.session['nav'], 'manager':manager, 'eContext':manager.eContext, 'form':form} 1585 else: 1586 return HttpResponseServerError("Object does not exist") 1587 elif action == 'savename': 1588 if not request.method == 'POST': 1589 return HttpResponseRedirect(reverse("manage_action_containers", args=["edit", o_type, o_id])) 1590 if hasattr(manager, o_type) and o_id > 0: 1591 form = ContainerNameForm(data=request.REQUEST.copy()) 1592 if form.is_valid(): 1593 logger.debug("Update name form:" + str(form.cleaned_data)) 1594 name = form.cleaned_data['name'] 1595 manager.updateName(o_type, o_id, name) 1596 rdict = {'bad':'false' } 1597 json = simplejson.dumps(rdict, ensure_ascii=False) 1598 return HttpResponse( json, mimetype='application/javascript') 1599 else: 1600 d = dict() 1601 for e in form.errors.iteritems(): 1602 d.update({e[0]:unicode(e[1])}) 1603 rdict = {'bad':'true','errs': d } 1604 json = simplejson.dumps(rdict, ensure_ascii=False) 1605 return HttpResponse( json, mimetype='application/javascript') 1606 else: 1607 return HttpResponseServerError("Object does not exist") 1608 elif action == 'editdescription': 1609 if hasattr(manager, o_type) and o_id > 0: 1610 obj = getattr(manager, o_type) 1611 template = "webclient/ajax_form/container_form_ajax.html" 1612 form = ContainerDescriptionForm(initial={'description': obj.description}) 1613 context = {'nav':request.session['nav'], 'manager':manager, 'eContext':manager.eContext, 'form':form} 1614 else: 1615 return HttpResponseServerError("Object does not exist") 1616 elif action == 'savedescription': 1617 if not request.method == 'POST': 1618 return HttpResponseServerError("Action '%s' on the '%s' id:%s cannot be complited" % (action, o_type, o_id)) 1619 if hasattr(manager, o_type) and o_id > 0: 1620 form = ContainerDescriptionForm(data=request.REQUEST.copy()) 1621 if form.is_valid(): 1622 logger.debug("Update name form:" + str(form.cleaned_data)) 1623 description = form.cleaned_data['description'] 1624 manager.updateDescription(o_type, o_id, description) 1625 rdict = {'bad':'false' } 1626 json = simplejson.dumps(rdict, ensure_ascii=False) 1627 return HttpResponse( json, mimetype='application/javascript') 1628 else: 1629 d = dict() 1630 for e in form.errors.iteritems(): 1631 d.update({e[0]:unicode(e[1])}) 1632 rdict = {'bad':'true','errs': d } 1633 json = simplejson.dumps(rdict, ensure_ascii=False) 1634 return HttpResponse( json, mimetype='application/javascript') 1635 else: 1636 return HttpResponseServerError("Object does not exist") 1637 elif action == 'paste': 1638 destination = request.REQUEST['destination'].split('-') 1639 rv = manager.paste(destination) 1640 if rv: 1641 rdict = {'bad':'true','errs': rv } 1642 json = simplejson.dumps(rdict, ensure_ascii=False) 1643 return HttpResponse( json, mimetype='application/javascript') 1644 else: 1645 rdict = {'bad':'false' } 1646 json = simplejson.dumps(rdict, ensure_ascii=False) 1647 return HttpResponse( json, mimetype='application/javascript') 1648 elif action == 'move': 1649 parent = request.REQUEST['parent'].split('-') 1650 #source = request.REQUEST['source'].split('-') 1651 destination = request.REQUEST['destination'].split('-') 1652 rv = None 1653 try: 1654 if parent[1] == destination[1]: 1655 rv = "Error: Cannot move to the same place." 1656 except Exception, x: 1657 rdict = {'bad':'true','errs': str(x) } 1658 else: 1659 if rv is None: 1660 rv = manager.move(parent,destination) 1661 if rv: 1662 rdict = {'bad':'true','errs': rv } 1663 else: 1664 rdict = {'bad':'false' } 1665 json = simplejson.dumps(rdict, ensure_ascii=False) 1666 return HttpResponse( json, mimetype='application/javascript') 1667 elif action == 'remove': 1668 parent = request.REQUEST['parent'].split('-') 1669 #source = request.REQUEST['source'].split('-') 1670 try: 1671 manager.remove(parent) 1672 except Exception, x: 1673 logger.error(traceback.format_exc()) 1674 rdict = {'bad':'true','errs': str(x) } 1675 json = simplejson.dumps(rdict, ensure_ascii=False) 1676 return HttpResponse( json, mimetype='application/javascript') 1677 1678 rdict = {'bad':'false' } 1679 json = simplejson.dumps(rdict, ensure_ascii=False) 1680 return HttpResponse( json, mimetype='application/javascript') 1681 elif action == 'removefromshare': 1682 image_id = request.REQUEST.get('source') 1683 try: 1684 manager.removeImage(image_id) 1685 except Exception, x: 1686 logger.error(traceback.format_exc()) 1687 rdict = {'bad':'true','errs': str(x) } 1688 json = simplejson.dumps(rdict, ensure_ascii=False) 1689 return HttpResponse( json, mimetype='application/javascript') 1690 rdict = {'bad':'false' } 1691 json = simplejson.dumps(rdict, ensure_ascii=False) 1692 return HttpResponse( json, mimetype='application/javascript') 1693 elif action == 'addcomment': 1694 if not request.method == 'POST': 1695 return HttpResponseRedirect(reverse("load_metadata_details", args=[o_type, o_id])) 1696 form_comment = CommentAnnotationForm(data=request.REQUEST.copy()) 1697 if form_comment.is_valid() and o_type is not None and o_id > 0: 1698 content = form_comment.cleaned_data['content'] 1699 manager.createCommentAnnotation(o_type, content) 1700 return HttpResponseRedirect(url) 1701 else: 1702 template = "webclient/annotations/annotation_new_form.html" 1703 context = {'nav':request.session['nav'], 'url':url, 'manager':manager, 'eContext':manager.eContext, 'form_comment':form_comment, 'index':index} 1704 elif action == 'addtag': 1705 if not request.method == 'POST': 1706 return HttpResponseRedirect(reverse("manage_action_containers", args=["newtag", o_type, o_id])) 1707 form_tag = TagAnnotationForm(data=request.REQUEST.copy()) 1708 if form_tag.is_valid() and o_type is not None and o_id > 0: 1709 tag = form_tag.cleaned_data['tag'] 1710 desc = form_tag.cleaned_data['description'] 1711 manager.createTagAnnotation(o_type, tag, desc) 1712 return HttpResponseRedirect(url) 1713 else: 1714 template = "webclient/annotations/annotation_new_form.html" 1715 context = {'nav':request.session['nav'], 'url':url, 'manager':manager, 'eContext':manager.eContext, 'form_tag':form_tag, 'index':index} 1716 elif action == 'addtagonly': 1717 if not request.method == 'POST': 1718 return HttpResponseRedirect(reverse("manage_action_containers", args=["newtagonly"])) 1719 form_tag = TagAnnotationForm(data=request.REQUEST.copy()) 1720 if form_tag.is_valid(): 1721 tag = form_tag.cleaned_data['tag'] 1722 desc = form_tag.cleaned_data['description'] 1723 manager.createTagAnnotationOnly(tag, desc) 1724 return HttpJavascriptRedirect(reverse("load_template", args=["usertags"])) 1725 else: 1726 template = "webclient/annotations/annotation_new_form.html" 1727 context = {'nav':request.session['nav'], 'url':url, 'manager':manager, 'eContext':manager.eContext, 'form_tag':form_tag} 1728 elif action == 'usetag': 1729 if not request.method == 'POST': 1730 return HttpResponseRedirect(reverse("manage_action_containers", args=["usetag", o_type, o_id])) 1731 tag_list = manager.getTagsByObject() 1732 form_tags = TagListForm(data=request.REQUEST.copy(), initial={'tags':tag_list}) 1733 if form_tags.is_valid() and o_type is not None and o_id > 0: 1734 tags = form_tags.cleaned_data['tags'] 1735 manager.createAnnotationLinks(o_type, 'tag', tags) 1736 return HttpResponseRedirect(url) 1737 else: 1738 template = "webclient/annotations/annotation_new_form.html" 1739 context = {'nav':request.session['nav'], 'url':url, 'manager':manager, 'eContext':manager.eContext, 'form_tags':form_tags, 'index':index} 1740 elif action == 'addfile': 1741 if not request.method == 'POST': 1742 return HttpResponseRedirect(reverse("manage_action_containers", args=["newfile", o_type, o_id])) 1743 form_file = UploadFileForm(request.REQUEST.copy(), request.FILES) 1744 if form_file.is_valid() and o_type is not None and o_id > 0: 1745 f = request.FILES['annotation_file'] 1746 manager.createFileAnnotation(o_type, f) 1747 return HttpResponseRedirect(url) 1748 else: 1749 template = "webclient/annotations/annotation_new_form.html" 1750 context = {'nav':request.session['nav'], 'url':url, 'manager':manager, 'eContext':manager.eContext, 'form_file':form_file, 'index':index} 1751 elif action == 'usefile': 1752 if not request.method == 'POST': 1753 return HttpResponseRedirect(reverse("manage_action_containers", args=["usefile", o_type, o_id])) 1754 file_list = manager.getFilesByObject() 1755 form_files = FileListForm(data=request.REQUEST.copy(), initial={'files':file_list}) 1756 if form_files.is_valid() and o_type is not None and o_id > 0: 1757 files = request.POST.getlist('files') 1758 manager.createAnnotationLinks(o_type, 'file', files) 1759 return HttpResponseRedirect(url) 1760 else: 1761 template = "webclient/annotations/annotation_new_form.html" 1762 context = {'nav':request.session['nav'], 'url':url, 'manager':manager, 'eContext':manager.eContext, 'form_files':form_files, 'index':index} 1763 elif action == 'delete': 1764 child = toBoolean(request.REQUEST.get('child')) 1765 anns = toBoolean(request.REQUEST.get('anns')) 1766 try: 1767 handle = manager.deleteItem(child, anns) 1768 request.session['callback'][str(handle)] = {'job_type': 'delete', 'delmany':False,'did':o_id, 'dtype':o_type, 'status':'in progress', 1769 'derror':handle.errors(), 'dreport':_formatReport(handle), 'start_time': datetime.datetime.now()} 1770 request.session.modified = True 1771 except Exception, x: 1772 logger.error('Failed to delete: %r' % {'did':o_id, 'dtype':o_type}, exc_info=True) 1773 rdict = {'bad':'true','errs': str(x) } 1774 else: 1775 rdict = {'bad':'false' } 1776 json = simplejson.dumps(rdict, ensure_ascii=False) 1777 return HttpResponse( json, mimetype='application/javascript') 1778 elif action == 'deletemany': 1779 object_ids = {'image':request.REQUEST.getlist('image'), 'dataset':request.REQUEST.getlist('dataset'), 'project':request.REQUEST.getlist('project'), 'screen':request.REQUEST.getlist('screen'), 'plate':request.REQUEST.getlist('plate'), 'well':request.REQUEST.getlist('well')} 1780 child = toBoolean(request.REQUEST.get('child')) 1781 anns = toBoolean(request.REQUEST.get('anns')) 1782 logger.debug("Delete many: child? %s anns? %s object_ids %s" % (child, anns, object_ids)) 1783 try: 1784 for key,ids in object_ids.iteritems(): 1785 if ids is not None and len(ids) > 0: 1786 handle = manager.deleteObjects(key, ids, child, anns) 1787 dMap = {'job_type': 'delete', 'start_time': datetime.datetime.now(),'status':'in progress', 'derrors':handle.errors(), 1788 'dreport':_formatReport(handle), 'dtype':key} 1789 if len(ids) > 1: 1790 dMap['delmany'] = len(ids) 1791 dMap['did'] = ids 1792 else: 1793 dMap['delmany'] = False 1794 dMap['did'] = ids[0] 1795 request.session['callback'][str(handle)] = dMap 1796 request.session.modified = True 1797 except Exception, x: 1798 logger.error('Failed to delete: %r' % {'did':ids, 'dtype':key}, exc_info=True) 1799 rdict = {'bad':'true','errs': str(x) } 1800 else: 1801 rdict = {'bad':'false' } 1802 json = simplejson.dumps(rdict, ensure_ascii=False) 1803 return HttpResponse( json, mimetype='application/javascript') 1804 1805 t = template_loader.get_template(template) 1806 c = Context(request,context) 1807 logger.debug('TEMPLATE: '+template) 1808 return HttpResponse(t.render(c))
1809
1810 @isUserConnected 1811 -def get_original_file(request, fileId, **kwargs):
1812 1813 conn = None 1814 try: 1815 conn = kwargs["conn"] 1816 except: 1817 logger.error(traceback.format_exc()) 1818 return handlerInternalError("Connection is not available. Please contact your administrator.") 1819 1820 orig_file = conn.getObject("OriginalFile", fileId) 1821 if orig_file is None: 1822 return handlerInternalError("Original File does not exists (id:%s)." % (iid)) 1823 1824 rsp = HttpResponse(orig_file.getFileInChunks()) 1825 mimetype = orig_file.mimetype 1826 if mimetype == "text/x-python": 1827 mimetype = "text/plain" # allows display in browser 1828 rsp['Content-Type'] = mimetype 1829 rsp['Content-Length'] = orig_file.getSize() 1830 #rsp['Content-Disposition'] = 'attachment; filename=%s' % (orig_file.name.replace(" ","_")) 1831 return rsp
1832
1833 1834 @isUserConnected 1835 -def image_as_map(request, imageId, **kwargs):
1836 """ Converts OMERO image into mrc.map file (using tiltpicker utils) and returns the file """ 1837 1838 from omero_ext.tiltpicker.pyami import mrc 1839 from numpy import dstack, zeros, int8 1840 1841 conn = None 1842 try: 1843 conn = kwargs["conn"] 1844 except: 1845 logger.error(traceback.format_exc()) 1846 return handlerInternalError("Connection is not available. Please contact your administrator.") 1847 1848 image = conn.getObject("Image", imageId) 1849 if image is None: 1850 message = "Image ID %s not found in image_as_map" % imageId 1851 logger.error(message) 1852 return handlerInternalError(message) 1853 1854 imageName = image.getName() 1855 downloadName = imageName.endswith(".map") and imageName or "%s.map" % imageName 1856 pixels = image.getPrimaryPixels() 1857 1858 # get a list of numpy planes and make stack 1859 zctList = [(z,0,0) for z in range(image.getSizeZ())] 1860 npList = list(pixels.getPlanes(zctList)) 1861 npStack = dstack(npList) 1862 logger.info("Numpy stack for image_as_map: dtype: %s, range %s-%s" % (npStack.dtype.name, npStack.min(), npStack.max()) ) 1863 1864 # OAV only supports 'float' and 'int8'. Convert anything else to int8 1865 if pixels.getPixelsType().value != 'float' or ('8bit' in kwargs and kwargs['8bit']): 1866 #scale from -127 -> 128 and conver to 8 bit integer 1867 npStack = npStack - npStack.min() # start at 0 1868 npStack = (npStack * 255.0 / npStack.max()) - 127 # range - 127 -> 128 1869 a = zeros(npStack.shape, dtype=int8) 1870 npStack = npStack.round(out=a) 1871 1872 if "maxSize" in kwargs and int(kwargs["maxSize"]) > 0: 1873 sz = int(kwargs["maxSize"]) 1874 targetSize = sz * sz * sz 1875 # if available, use scipy.ndimage to resize 1876 if npStack.size > targetSize: 1877 try: 1878 import scipy.ndimage 1879 from numpy import round 1880 factor = float(targetSize)/ npStack.size 1881 factor = pow(factor,1.0/3) 1882 logger.info("Resizing numpy stack %s by factor of %s" % (npStack.shape, factor)) 1883 npStack = round(scipy.ndimage.interpolation.zoom(npStack, factor), 1) 1884 except ImportError: 1885 logger.info("Failed to import scipy.ndimage for interpolation of 'image_as_map'. Full size: %s" % str(npStack.shape)) 1886 pass 1887 1888 header = {} 1889 header["xlen"] = pixels.physicalSizeX * image.getSizeX() 1890 header["ylen"] = pixels.physicalSizeY * image.getSizeY() 1891 header["zlen"] = pixels.physicalSizeZ * image.getSizeZ() 1892 if header["xlen"] == 0 or header["ylen"] == 0 or header["zlen"] == 0: 1893 header = {} 1894 1895 # write mrc.map to temp file 1896 import tempfile 1897 temp = tempfile.NamedTemporaryFile(suffix='.map') 1898 try: 1899 mrc.write(npStack, temp.name, header) 1900 logger.debug("download file: %r" % {'name':temp.name, 'size':temp.tell()}) 1901 originalFile_data = FileWrapper(temp) 1902 rsp = HttpResponse(originalFile_data) 1903 rsp['Content-Type'] = 'application/force-download' 1904 #rsp['Content-Length'] = temp.tell() 1905 rsp['Content-Length'] =os.path.getsize(temp.name) 1906 rsp['Content-Disposition'] = 'attachment; filename=%s' % downloadName 1907 temp.seek(0) 1908 except Exception, x: 1909 temp.close() 1910 logger.error(traceback.format_exc()) 1911 return handlerInternalError("Cannot generate map (id:%s)." % (imageId)) 1912 return rsp
1913
1914 1915 @isUserConnected 1916 -def archived_files(request, iid, **kwargs):
1917 """ 1918 Downloads the archived file(s) as a single file or as a zip (if more than one file) 1919 """ 1920 conn = None 1921 try: 1922 conn = kwargs["conn"] 1923 except: 1924 logger.error(traceback.format_exc()) 1925 return handlerInternalError("Connection is not available. Please contact your administrator.") 1926 1927 image = conn.getObject("Image", iid) 1928 if image is None: 1929 logger.debug("Cannot download archived file becuase Image does not exist.") 1930 return handlerInternalError("Cannot download archived file becuase Image does not exist (id:%s)." % (iid)) 1931 1932 files = list(image.getArchivedFiles()) 1933 1934 if len(files) == 0: 1935 logger.debug("Tried downloading archived files from image with no files archived.") 1936 return handlerInternalError("This image has no Archived Files.") 1937 1938 if len(files) == 1: 1939 orig_file = files[0] 1940 rsp = HttpResponse(orig_file.getFileInChunks()) 1941 rsp['Content-Length'] = orig_file.getSize() 1942 rsp['Content-Disposition'] = 'attachment; filename=%s' % (orig_file.getName().replace(" ","_")) 1943 else: 1944 import tempfile 1945 temp = tempfile.NamedTemporaryFile(suffix='.archive') 1946 try: 1947 temp_zip_dir = tempfile.mkdtemp() 1948 logger.debug("download dir: %s" % temp_zip_dir) 1949 try: 1950 for a in files: 1951 temp_f = os.path.join(temp_zip_dir, a.name) 1952 f = open(str(temp_f),"wb") 1953 try: 1954 for chunk in a.getFileInChunks(): 1955 f.write(chunk) 1956 finally: 1957 f.close() 1958 1959 # create zip 1960 zip_file = zipfile.ZipFile(temp, 'w', zipfile.ZIP_DEFLATED) 1961 try: 1962 a_files = os.path.join(temp_zip_dir, "*") 1963 for name in glob.glob(a_files): 1964 zip_file.write(name, os.path.basename(name)) 1965 finally: 1966 zip_file.close() 1967 # delete temp dir 1968 finally: 1969 shutil.rmtree(temp_zip_dir, ignore_errors=True) 1970 1971 file_name = "%s.zip" % image.getName().replace(" ","_") 1972 1973 # return the zip or single file 1974 archivedFile_data = FileWrapper(temp) 1975 rsp = HttpResponse(archivedFile_data) 1976 rsp['Content-Length'] = temp.tell() 1977 rsp['Content-Disposition'] = 'attachment; filename=%s' % file_name 1978 temp.seek(0) 1979 except Exception, x: 1980 temp.close() 1981 logger.error(traceback.format_exc()) 1982 return handlerInternalError("Cannot download file (id:%s)." % (iid)) 1983 1984 rsp['Content-Type'] = 'application/force-download' 1985 return rsp
1986
1987 @isUserConnected 1988 -def download_annotation(request, action, iid, **kwargs):
1989 conn = None 1990 try: 1991 conn = kwargs["conn"] 1992 except: 1993 logger.error(traceback.format_exc()) 1994 return handlerInternalError("Connection is not available. Please contact your administrator.") 1995 1996 ann = conn.getObject("Annotation", iid) 1997 if ann is None: 1998 return handlerInternalError("Annotation does not exist (id:%s)." % (iid)) 1999 2000 rsp = HttpResponse(ann.getFileInChunks()) 2001 rsp['Content-Type'] = 'application/force-download' 2002 rsp['Content-Length'] = ann.getFileSize() 2003 rsp['Content-Disposition'] = 'attachment; filename=%s' % (ann.getFileName().replace(" ","_")) 2004 return rsp
2005
2006 @isUserConnected 2007 -def load_public(request, share_id=None, **kwargs):
2008 request.session.modified = True 2009 2010 # SUBTREE TODO: 2011 if share_id is None: 2012 share_id = request.REQUEST.get("o_id") is not None and long(request.REQUEST.get("o_id")) or None 2013 2014 # check menu 2015 menu = request.REQUEST.get("menu") 2016 if menu is not None: 2017 request.session['nav']['menu'] = menu 2018 else: 2019 menu = request.session['nav']['menu'] 2020 # check view 2021 view = request.REQUEST.get("view") 2022 if view is not None: 2023 request.session['nav']['view'] = view 2024 else: 2025 view = request.session['nav']['view'] 2026 2027 # get connection 2028 conn = None 2029 try: 2030 conn = kwargs["conn"] 2031 except: 2032 logger.error(traceback.format_exc()) 2033 return handlerInternalError("Connection is not available. Please contact your administrator.") 2034 2035 conn_share = None 2036 try: 2037 conn_share = kwargs["conn_share"] 2038 except: 2039 logger.error(traceback.format_exc()) 2040 return handlerInternalError("Share connection is not available. Please contact your administrator.") 2041 2042 # get url to redirect 2043 url = None 2044 try: 2045 url = kwargs["url"] 2046 except: 2047 logger.error(traceback.format_exc()) 2048 if url is None: 2049 url = reverse(viewname="load_template", args=[menu]) 2050 2051 # get page 2052 try: 2053 page = int(request.REQUEST['page']) 2054 except: 2055 page = 1 2056 2057 if share_id is not None: 2058 if view == 'tree': 2059 template = "webclient/public/share_subtree.html" 2060 elif view == 'icon': 2061 template = "webclient/public/share_content_icon.html" 2062 controller = BaseShare(conn, conn_share, share_id) 2063 if conn_share is None: 2064 controller.loadShareOwnerContent() 2065 else: 2066 controller.loadShareContent() 2067 else: 2068 template = "webclient/public/share_tree.html" 2069 controller = BaseShare(conn) 2070 controller.getShares() 2071 2072 context = {'nav':request.session['nav'], 'eContext':controller.eContext, 'share':controller} 2073 t = template_loader.get_template(template) 2074 c = Context(request,context) 2075 logger.debug('TEMPLATE: '+template) 2076 return HttpResponse(t.render(c))
2077
2078 ################################################################## 2079 # Basket 2080 2081 @isUserConnected 2082 -def basket_action (request, action=None, **kwargs):
2083 request.session.modified = True 2084 2085 request.session['nav']['menu'] = 'basket' 2086 2087 conn = None 2088 try: 2089 conn = kwargs["conn"] 2090 except: 2091 logger.error(traceback.format_exc()) 2092 return handlerInternalError("Connection is not available. Please contact your administrator.") 2093 2094 url = None 2095 try: 2096 url = kwargs["url"] 2097 except: 2098 logger.error(traceback.format_exc()) 2099 2100 if action == "toshare": 2101 template = "webclient/basket/basket_share_action.html" 2102 basket = BaseBasket(conn) 2103 basket.load_basket(request) 2104 experimenters = list(conn.getExperimenters()) 2105 experimenters.sort(key=lambda x: x.getOmeName().lower()) 2106 selected = [long(i) for i in request.REQUEST.getlist('image')] 2107 form = BasketShareForm(initial={'experimenters':experimenters, 'images':basket.imageInBasket, 'enable':True, 'selected':selected}) 2108 context = {'nav':request.session['nav'], 'eContext':basket.eContext, 'form':form} 2109 elif action == "createshare": 2110 if not request.method == 'POST': 2111 return HttpResponseRedirect(reverse("basket_action")) 2112 basket = BaseBasket(conn) 2113 basket.load_basket(request) 2114 experimenters = list(conn.getExperimenters()) 2115 experimenters.sort(key=lambda x: x.getOmeName().lower()) 2116 form = BasketShareForm(initial={'experimenters':experimenters, 'images':basket.imageInBasket}, data=request.REQUEST.copy()) 2117 if form.is_valid(): 2118 images = form.cleaned_data['image'] 2119 message = form.cleaned_data['message'] 2120 expiration = form.cleaned_data['expiration'] 2121 members = form.cleaned_data['members'] 2122 #guests = request.REQUEST['guests'] 2123 enable = toBoolean(form.cleaned_data['enable']) 2124 try: 2125 host = '%s%s' % (settings.APPLICATION_HOST, reverse("webindex")) 2126 except: 2127 host = '%s://%s:%s%s' % (request.META['wsgi.url_scheme'], request.META['SERVER_NAME'], request.META['SERVER_PORT'], reverse("webindex")) 2128 share = BaseShare(conn) 2129 share.createShare(host, request.session.get('server'), images, message, members, enable, expiration) 2130 return HttpJavascriptRedirect(reverse("load_template", args=["public"])) 2131 else: 2132 template = "webclient/basket/basket_share_action.html" 2133 context = {'nav':request.session['nav'], 'eContext':basket.eContext, 'form':form} 2134 elif action == "todiscuss": 2135 template = "webclient/basket/basket_discussion_action.html" 2136 basket = BaseBasket(conn) 2137 experimenters = list(conn.getExperimenters()) 2138 experimenters.sort(key=lambda x: x.getOmeName().lower()) 2139 form = ShareForm(initial={'experimenters':experimenters, 'enable':True}) 2140 context = {'nav':request.session['nav'], 'eContext':basket.eContext, 'form':form} 2141 elif action == "createdisc": 2142 if not request.method == 'POST': 2143 return HttpResponseRedirect(reverse("basket_action")) 2144 basket = BaseBasket(conn) 2145 experimenters = list(conn.getExperimenters()) 2146 experimenters.sort(key=lambda x: x.getOmeName().lower()) 2147 form = ShareForm(initial={'experimenters':experimenters}, data=request.REQUEST.copy()) 2148 if form.is_valid(): 2149 message = form.cleaned_data['message'] 2150 expiration = form.cleaned_data['expiration'] 2151 members = form.cleaned_data['members'] 2152 #guests = request.REQUEST['guests'] 2153 enable = toBoolean(form.cleaned_data['enable']) 2154 try: 2155 host = '%s%s' % (settings.APPLICATION_HOST, reverse("webindex")) 2156 except: 2157 host = '%s://%s:%s%s' % (request.META['wsgi.url_scheme'], request.META['SERVER_NAME'], request.META['SERVER_PORT'], reverse("webindex")) 2158 share = BaseShare(conn) 2159 share.createDiscussion(host, request.session.get('server'), message, members, enable, expiration) 2160 return HttpJavascriptRedirect(reverse("load_template", args=["public"])) 2161 else: 2162 template = "webclient/basket/basket_discussion_action.html" 2163 context = {'nav':request.session['nav'], 'eContext':basket.eContext, 'form':form} 2164 else: 2165 template = "webclient/basket/basket.html" 2166 2167 basket = BaseBasket(conn) 2168 basket.load_basket(request) 2169 2170 form_active_group = ActiveGroupForm(initial={'activeGroup':basket.eContext['context'].groupId, 'mygroups': basket.eContext['allGroups'], 'url':url}) 2171 2172 context = {'nav':request.session['nav'], 'eContext':basket.eContext, 'basket':basket, 'form_active_group':form_active_group } 2173 2174 t = template_loader.get_template(template) 2175 c = Context(request,context) 2176 logger.debug('TEMPLATE: '+template) 2177 return HttpResponse(t.render(c))
2178
2179 @isUserConnected 2180 -def empty_basket(request, **kwargs):
2181 try: 2182 del request.session['imageInBasket'] 2183 except KeyError: 2184 logger.error(traceback.format_exc()) 2185 2186 #try: 2187 # del request.session['datasetInBasket'] 2188 #except KeyError: 2189 # logger.error(traceback.format_exc()) 2190 2191 request.session['nav']['basket'] = 0 2192 request.session['imageInBasket'] = set() 2193 #request.session['datasetInBasket'] = list() 2194 return HttpResponseRedirect(reverse("basket_action"))
2195
2196 @isUserConnected 2197 -def update_basket(request, **kwargs):
2198 action = None 2199 if request.method == 'POST': 2200 request.session.modified = True 2201 try: 2202 action = request.REQUEST['action'] 2203 except Exception, x: 2204 logger.error(traceback.format_exc()) 2205 return handlerInternalError("Attribute error: 'action' is missed.") 2206 else: 2207 prod = request.REQUEST.get('productId') 2208 ptype = request.REQUEST.get('productType') 2209 if action == 'add': 2210 images = request.REQUEST.getlist('image') 2211 #datasets = request.REQUEST.getlist('datasets') 2212 for i in images: 2213 flag = False 2214 for item in request.session['imageInBasket']: 2215 if item == long(i): 2216 flag = True 2217 break 2218 if not flag: 2219 request.session['imageInBasket'].add(long(i)) 2220 #for i in datasets: 2221 # flag = False 2222 # for item in request.session['datasetInBasket']: 2223 # if item == long(i): 2224 # flag = True 2225 # break 2226 # if not flag: 2227 # request.session['datasetInBasket'].append(long(i)) 2228 elif action == 'del': 2229 if ptype == 'image': 2230 try: 2231 request.session['imageInBasket'].remove(long(prod)) 2232 except: 2233 rv = "Error: could not remove image from the basket." 2234 return HttpResponse(rv) 2235 #elif ptype == 'dataset': 2236 # try: 2237 # request.session['datasetInBasket'].remove(prod) 2238 # except: 2239 # rv = "Error: could not remove image from the basket." 2240 # return HttpResponse(rv) 2241 else: 2242 rv = "Error: This action is not available" 2243 return HttpResponse(rv) 2244 elif action == 'delmany': 2245 images = [long(i) for i in request.REQUEST.getlist('image')] 2246 for i in images: 2247 if i in request.session['imageInBasket']: 2248 request.session['imageInBasket'].remove(long(i)) 2249 else: 2250 rv = "Error: could not remove image from the basket." 2251 return HttpResponse(rv) 2252 2253 total = len(request.session['imageInBasket'])#+len(request.session['datasetInBasket']) 2254 request.session['nav']['basket'] = total 2255 return HttpResponse(total) 2256 else: 2257 return handlerInternalError("Request method error in Basket.")
2258
2259 @isUserConnected 2260 -def manage_myaccount(request, action=None, **kwargs):
2261 template = "webclient/person/myaccount.html" 2262 request.session.modified = True 2263 2264 request.session['nav']['menu'] = 'person' 2265 2266 conn = None 2267 try: 2268 conn = kwargs["conn"] 2269 except: 2270 logger.error(traceback.format_exc()) 2271 return handlerInternalError("Connection is not available. Please contact your administrator.") 2272 2273 url = None 2274 try: 2275 url = kwargs["url"] 2276 except: 2277 logger.error(traceback.format_exc()) 2278 2279 controller = BaseExperimenter(conn) 2280 controller.getMyDetails() 2281 controller.getOwnedGroups() 2282 2283 groups = list(conn.getGroupsMemberOf()) 2284 groups.sort(key=lambda x: x.getName().lower()) 2285 2286 eContext = dict() 2287 eContext['context'] = conn.getEventContext() 2288 eContext['user'] = conn.getUser() 2289 eContext['allGroups'] = groups 2290 2291 form = MyAccountForm(initial={'omename': controller.experimenter.omeName, 'first_name':controller.experimenter.firstName, 2292 'middle_name':controller.experimenter.middleName, 'last_name':controller.experimenter.lastName, 2293 'email':controller.experimenter.email, 'institution':controller.experimenter.institution, 2294 'default_group':controller.defaultGroup, 'groups':controller.otherGroups}) 2295 2296 if action == "save": 2297 form = MyAccountForm(data=request.POST.copy(), initial={'groups':controller.otherGroups}) 2298 if form.is_valid(): 2299 firstName = form.cleaned_data['first_name'] 2300 middleName = form.cleaned_data['middle_name'] 2301 lastName = form.cleaned_data['last_name'] 2302 email = form.cleaned_data['email'] 2303 institution = form.cleaned_data['institution'] 2304 defaultGroup = form.cleaned_data['default_group'] 2305 controller.updateMyAccount(firstName, lastName, email, defaultGroup, middleName, institution) 2306 return HttpResponseRedirect(reverse("myaccount")) 2307 2308 form_active_group = ActiveGroupForm(initial={'activeGroup':eContext['context'].groupId, 'mygroups': eContext['allGroups'], 'url':url}) 2309 2310 context = {'nav':request.session['nav'], 'eContext': eContext, 'controller':controller, 'form':form, 'ldapAuth': controller.ldapAuth, 'form_active_group':form_active_group} 2311 t = template_loader.get_template(template) 2312 c = Context(request,context) 2313 logger.debug('TEMPLATE: '+template) 2314 return HttpResponse(t.render(c))
2315
2316 @isUserConnected 2317 -def change_password(request, **kwargs):
2318 template = "webclient/person/password.html" 2319 request.session.modified = True 2320 2321 request.session['nav']['menu'] = 'person' 2322 2323 conn = None 2324 try: 2325 conn = kwargs["conn"] 2326 except: 2327 logger.error(traceback.format_exc()) 2328 return handlerInternalError("Connection is not available. Please contact your administrator.") 2329 2330 url = None 2331 try: 2332 url = kwargs["url"] 2333 except: 2334 logger.error(traceback.format_exc()) 2335 2336 error = None 2337 if request.method != 'POST': 2338 password_form = ChangePassword() 2339 else: 2340 password_form = ChangePassword(data=request.POST.copy()) 2341 2342 if password_form.is_valid(): 2343 old_password = password_form.cleaned_data['old_password'] 2344 password = password_form.cleaned_data['password'] 2345 try: 2346 conn.changeMyPassword(password, old_password) 2347 except Exception, x: 2348 error = x.message 2349 else: 2350 request.session['password'] = password 2351 return HttpJavascriptResponse("Password was changed successfully") 2352 2353 context = {'nav':request.session['nav'], 'password_form':password_form, 'error':error} 2354 t = template_loader.get_template(template) 2355 c = Context(request, context) 2356 rsp = t.render(c) 2357 return HttpResponse(rsp)
2358
2359 @isUserConnected 2360 -def upload_myphoto(request, action=None, **kwargs):
2361 template = "webclient/person/upload_myphoto.html" 2362 request.session.modified = True 2363 2364 conn = None 2365 try: 2366 conn = kwargs["conn"] 2367 except: 2368 logger.error(traceback.format_exc()) 2369 return handlerInternalError("Connection is not available. Please contact your administrator.") 2370 2371 photo_size = conn.getExperimenterPhotoSize() 2372 form_file = UploadPhotoForm() 2373 2374 request.session['nav']['edit_mode'] = False 2375 if action == "upload": 2376 if request.method == 'POST': 2377 form_file = UploadPhotoForm(request.POST, request.FILES) 2378 if form_file.is_valid(): 2379 controller = BaseUploadFile(conn) 2380 controller.attach_photo(request.FILES['photo']) 2381 return HttpResponseRedirect(reverse("upload_myphoto")) 2382 elif action == "crop": 2383 x1 = long(request.REQUEST.get('x1')) 2384 x2 = long(request.REQUEST.get('x2')) 2385 y1 = long(request.REQUEST.get('y1')) 2386 y2 = long(request.REQUEST.get('y2')) 2387 box = (x1,y1,x2,y2) 2388 conn.cropExperimenterPhoto(box) 2389 return HttpResponseRedirect(reverse("upload_myphoto")) 2390 elif action == "editphoto": 2391 if photo_size is not None: 2392 request.session['nav']['edit_mode'] = True 2393 2394 context = {'nav':request.session['nav'], 'form_file':form_file, 'photo_size':photo_size} 2395 t = template_loader.get_template(template) 2396 c = Context(request,context) 2397 logger.debug('TEMPLATE: '+template) 2398 return HttpResponse(t.render(c))
2399
2400 @isUserConnected 2401 -def help(request, **kwargs):
2402 template = "webclient/help.html" 2403 request.session.modified = True 2404 2405 conn = None 2406 try: 2407 conn = kwargs["conn"] 2408 except: 2409 logger.error(traceback.format_exc()) 2410 return handlerInternalError("Connection is not available. Please contact your administrator.") 2411 2412 url = None 2413 try: 2414 url = kwargs["url"] 2415 except: 2416 logger.error(traceback.format_exc()) 2417 2418 controller = BaseHelp(conn) 2419 2420 form_active_group = ActiveGroupForm(initial={'activeGroup':controller.eContext['context'].groupId, 'mygroups': controller.eContext['allGroups'], 'url':url}) 2421 2422 context = {'nav':request.session['nav'], 'eContext': controller.eContext, 'controller':controller, 'form_active_group':form_active_group} 2423 t = template_loader.get_template(template) 2424 c = Context(request,context) 2425 logger.debug('TEMPLATE: '+template) 2426 return HttpResponse(t.render(c))
2427
2428 @isUserConnected 2429 -def load_calendar(request, year=None, month=None, **kwargs):
2430 template = "webclient/history/calendar.html" 2431 2432 conn = None 2433 try: 2434 conn = kwargs["conn"] 2435 except: 2436 logger.error(traceback.format_exc()) 2437 return handlerInternalError("Connection is not available. Please contact your administrator.") 2438 2439 filter_user_id = request.session.get('nav')['experimenter'] 2440 2441 if year is not None and month is not None: 2442 controller = BaseCalendar(conn=conn, year=year, month=month, eid=filter_user_id) 2443 else: 2444 today = datetime.datetime.today() 2445 controller = BaseCalendar(conn=conn, year=today.year, month=today.month, eid=filter_user_id) 2446 controller.create_calendar() 2447 2448 context = {'nav':request.session['nav'], 'eContext': controller.eContext, 'controller':controller} 2449 t = template_loader.get_template(template) 2450 c = Context(request,context) 2451 logger.debug('TEMPLATE: '+template) 2452 return HttpResponse(t.render(c))
2453
2454 @isUserConnected 2455 -def load_history(request, year, month, day, **kwargs):
2456 2457 template = "webclient/history/history_details.html" 2458 2459 conn = None 2460 try: 2461 conn = kwargs["conn"] 2462 except: 2463 logger.error(traceback.format_exc()) 2464 return handlerInternalError("Connection is not available. Please contact your administrator.") 2465 2466 url = None 2467 try: 2468 url = kwargs["url"] 2469 except: 2470 logger.error(traceback.format_exc()) 2471 2472 try: 2473 page = int(request.REQUEST['page']) 2474 except: 2475 page = 1 2476 2477 cal_type = None 2478 try: 2479 cal_type = request.REQUEST['history_type'] 2480 if cal_type == "all": 2481 cal_type = None 2482 except: 2483 cal_type = None 2484 2485 filter_user_id = request.session.get('nav')['experimenter'] 2486 controller = BaseCalendar(conn=conn, year=year, month=month, day=day, eid=filter_user_id) 2487 controller.get_items(cal_type, page) 2488 2489 #if cal_type is None: 2490 # form_history_type = HistoryTypeForm() 2491 #else: 2492 # form_history_type = HistoryTypeForm(initial={'data_type':cal_type}) 2493 2494 context = {'nav':request.session['nav'], 'url':url, 'eContext': controller.eContext, 'controller':controller}#, 'form_history_type':form_history_type} 2495 t = template_loader.get_template(template) 2496 c = Context(request,context) 2497 logger.debug('TEMPLATE: '+template) 2498 return HttpResponse(t.render(c))
2499
2500 2501 -def getObjectUrl(conn, obj):
2502 """ 2503 This provides a url to browse to the specified omero.model.ObjectI P/D/I, S/P, FileAnnotation etc. 2504 used to display results from the scripting service 2505 E.g webclient/userdata/?path=project=1|dataset=5|image=12601:selected 2506 If the object is a file annotation, try to browse to the parent P/D/I 2507 """ 2508 base_url = reverse(viewname="load_template", args=['userdata']) 2509 2510 # if we have a File Annotation, then we want our URL to be for the parent object... 2511 if isinstance(obj, omero.model.FileAnnotationI): 2512 fa = conn.getObject("Annotation", obj.id.val) 2513 for ptype in ['project', 'dataset', 'image']: 2514 links = fa.getParentLinks(ptype) 2515 for l in links: 2516 obj = l.parent 2517 2518 if isinstance(obj, omero.model.ImageI): 2519 # return path from first Project we find, or None if no Projects 2520 image = conn.getObject("Image", obj.id.val) 2521 for d in image.listParents(): 2522 for p in d.listParents(): 2523 return "%s?path=project=%d|dataset=%d|image=%d:selected" % (base_url, p.id, d.id, image.id) 2524 return None 2525 2526 if isinstance(obj, omero.model.DatasetI): 2527 dataset = conn.getObject("Dataset", obj.id.val) 2528 for p in dataset.listParents(): 2529 return "%s?path=project=%d|dataset=%d:selected" % (base_url, p.id, dataset.id) 2530 return None 2531 2532 if isinstance(obj, omero.model.ProjectI): 2533 return "%s?path=project=%d:selected" % (base_url, obj.id.val) 2534 2535 if isinstance(obj, omero.model.PlateI): 2536 plate = conn.getObject("Plate", obj.id.val) 2537 screen = plate.getParent() 2538 if screen is not None: 2539 return "%s?path=screen=%d|plate=%d:selected" % (base_url, screen.id, plate.id) 2540 return "%s?path=plate=%d:selected" % (base_url, obj.id.val) 2541 2542 if isinstance(obj, omero.model.ScreenI): 2543 return "%s?path=screen=%d:selected" % (base_url, obj.id.val)
2544
2545 2546 ###################### 2547 # Activities window & Progressbar 2548 @isUserConnected 2549 -def progress(request, **kwargs):
2550 """ 2551 Refresh callbacks (delete, scripts etc) and provide json to update Activities window & Progressbar. 2552 The returned json contains details for ALL callbacks in web session, regardless of their status. 2553 We also add counts of jobs, failures and 'in progress' to update status bar. 2554 """ 2555 conn = None 2556 try: 2557 conn = kwargs["conn"] 2558 except: 2559 logger.error(traceback.format_exc()) 2560 return handlerInternalError("Connection is not available. Please contact your administrator.") 2561 2562 in_progress = 0 2563 failure = 0 2564 _purgeCallback(request) 2565 2566 rv = {} 2567 # test each callback for failure, errors, completion, results etc 2568 for cbString in request.session.get('callback').keys(): 2569 job_type = request.session['callback'][cbString]['job_type'] 2570 2571 status = request.session['callback'][cbString]['status'] 2572 if status == "failed": 2573 failure+=1 2574 2575 # update delete 2576 if job_type == 'delete': 2577 if status not in ("failed", "finished"): 2578 try: 2579 handle = omero.api.delete.DeleteHandlePrx.checkedCast(conn.c.ic.stringToProxy(cbString)) 2580 cb = omero.callbacks.DeleteCallbackI(conn.c, handle) 2581 if cb.block(0) is None: # ms #500 2582 err = handle.errors() 2583 request.session['callback'][cbString]['derror'] = err 2584 if err > 0: 2585 logger.error("Status job '%s'error:" % cbString) 2586 logger.error(err) 2587 request.session['callback'][cbString]['status'] = "failed" 2588 request.session['callback'][cbString]['dreport'] = _formatReport(handle) 2589 failure+=1 2590 else: 2591 request.session['callback'][cbString]['status'] = "in progress" 2592 request.session['callback'][cbString]['dreport'] = _formatReport(handle) 2593 in_progress+=1 2594 else: 2595 err = handle.errors() 2596 request.session['callback'][cbString]['derror'] = err 2597 if err > 0: 2598 request.session['callback'][cbString]['status'] = "failed" 2599 request.session['callback'][cbString]['dreport'] = _formatReport(handle) 2600 failure+=1 2601 else: 2602 request.session['callback'][cbString]['status'] = "finished" 2603 request.session['callback'][cbString]['dreport'] = _formatReport(handle) 2604 cb.close() 2605 except Ice.ObjectNotExistException: 2606 request.session['callback'][cbString]['derror'] = 0 2607 request.session['callback'][cbString]['status'] = "finished" 2608 request.session['callback'][cbString]['dreport'] = None 2609 except Exception, x: 2610 logger.error(traceback.format_exc()) 2611 logger.error("Status job '%s'error:" % cbString) 2612 request.session['callback'][cbString]['derror'] = 1 2613 request.session['callback'][cbString]['status'] = "failed" 2614 request.session['callback'][cbString]['dreport'] = str(x) 2615 failure+=1 2616 request.session.modified = True 2617 # make a copy of the map in session, so that we can replace non json-compatible objects, without modifying session 2618 rv[cbString] = copy.copy(request.session['callback'][cbString]) 2619 rv[cbString]['start_time'] = str(request.session['callback'][cbString]['start_time']) 2620 2621 # update scripts 2622 elif job_type == 'script': 2623 # if error on runScript, the cbString is not a ProcessCallback... 2624 if not cbString.startswith('ProcessCallback'): continue # ignore 2625 if status not in ("failed", "finished"): 2626 logger.info("Check callback on script: %s" % cbString) 2627 proc = omero.grid.ScriptProcessPrx.checkedCast(conn.c.ic.stringToProxy(cbString)) 2628 cb = omero.scripts.ProcessCallbackI(conn.c, proc) 2629 # check if we get something back from the handle... 2630 if cb.block(0): # ms. 2631 cb.close() 2632 try: 2633 results = proc.getResults(0) # we can only retrieve this ONCE - must save results 2634 request.session['callback'][cbString]['status'] = "finished" 2635 except Exception, x: 2636 logger.error(traceback.format_exc()) 2637 continue 2638 # value could be rstring, rlong, robject 2639 rMap = {} 2640 for key, value in results.items(): 2641 v = value.getValue() 2642 if key in ("stdout", "stderr", "Message"): 2643 if key in ('stderr', 'stdout'): 2644 v = v.id.val # just save the id of original file 2645 request.session['callback'][cbString][key] = v 2646 else: 2647 if hasattr(v, "id"): # do we have an object (ImageI, FileAnnotationI etc) 2648 obj_data = {'id': v.id.val, 'type': v.__class__.__name__[:-1]} 2649 obj_data['browse_url'] = getObjectUrl(conn, v) 2650 if v.isLoaded() and hasattr(v, "file"): 2651 #try: 2652 mimetypes = {'image/png':'png', 'image/jpeg':'jpeg', 'image/tiff': 'tiff'} 2653 if v.file.mimetype.val in mimetypes: 2654 obj_data['fileType'] = mimetypes[v.file.mimetype.val] 2655 obj_data['fileId'] = v.file.id.val 2656 obj_data['name'] = v.file.name.val 2657 #except: 2658 # pass 2659 if v.isLoaded() and hasattr(v, "name"): # E.g Image, OriginalFile etc 2660 obj_data['name'] = v.name.val 2661 rMap[key] = obj_data 2662 else: 2663 rMap[key] = v 2664 request.session['callback'][cbString]['results'] = rMap 2665 request.session.modified = True 2666 else: 2667 in_progress+=1 2668 2669 # make a copy of the map in session, so that we can replace non json-compatible objects, without modifying session 2670 rv[cbString] = copy.copy(request.session['callback'][cbString]) 2671 rv[cbString]['start_time'] = str(request.session['callback'][cbString]['start_time']) 2672 2673 rv['inprogress'] = in_progress 2674 rv['failure'] = failure 2675 rv['jobs'] = len(request.session['callback']) 2676 2677 return HttpResponse(simplejson.dumps(rv),mimetype='application/javascript') # json
2678
2679 2680 @isUserConnected 2681 -def status_action (request, action=None, **kwargs):
2682 """ 2683 Opens the Activites window, using data from jobs in the request.session['callback']. 2684 Once this window is open, AJAX calls are used to poll the request.session['callback'] and update the page 2685 2686 If the above 'action' == 'clean' then we clear jobs from request.session['callback'] 2687 either a single job (if 'jobKey' is specified in POST) or all jobs (apart from those in progress) 2688 """ 2689 2690 request.session.modified = True 2691 2692 request.session['nav']['menu'] = 'status' 2693 2694 if action == "clean": 2695 if 'jobKey' in request.POST: 2696 jobId = request.POST.get('jobKey') 2697 rv = {} 2698 if jobId in request.session['callback']: 2699 del request.session['callback'][jobId] 2700 request.session.modified = True 2701 rv['removed'] = True 2702 else: 2703 rv['removed'] = False 2704 return HttpResponse(simplejson.dumps(rv),mimetype='application/javascript') 2705 else: 2706 for key, data in request.session['callback'].items(): 2707 if data['status'] != "in progress": 2708 del request.session['callback'][key] 2709 return HttpResponseRedirect(reverse("status")) 2710 2711 elif action == "update": 2712 # try to update the 'attribute' of the job with 'new_value' (or None) 2713 if 'jobKey' in request.POST: 2714 jobId = request.POST.get('jobKey') 2715 rv = {'updated':False} 2716 if jobId in request.session['callback']: 2717 if 'attribute' in request.POST: 2718 attribute = request.POST.get('attribute') 2719 new_value = request.POST.get('new_value', None) 2720 request.session['callback'][jobId][attribute] = new_value 2721 request.session.modified = True 2722 rv['updated'] = True 2723 return HttpResponse(simplejson.dumps(rv),mimetype='application/javascript') 2724 2725 conn = None 2726 try: 2727 conn = kwargs["conn"] 2728 except: 2729 logger.error(traceback.format_exc()) 2730 return handlerInternalError("Connection is not available. Please contact your administrator.") 2731 2732 template = "webclient/status/statusWindow.html" 2733 if request.REQUEST.get('content_only'): 2734 template = "webclient/status/activitiesContent.html" 2735 2736 _purgeCallback(request) 2737 2738 jobs = [] 2739 for key, data in request.session['callback'].items(): 2740 # E.g. key: ProcessCallback/39f77932-c447-40d8-8f99-910b5a531a25 -t:tcp -h 10.211.55.2 -p 54727:tcp -h 10.37.129.2 -p 54727:tcp -h 10.12.2.21 -p 54727 2741 # create id we can use as html id, E.g. 39f77932-c447-40d8-8f99-910b5a531a25 2742 data['id'] = key 2743 if len(key.split(" ")) > 0: 2744 data['id'] = key.split(" ")[0] 2745 if len(data['id'].split("/")) > 1: 2746 data['id'] = data['id'].split("/")[1] 2747 data['key'] = key 2748 jobs.append(data) 2749 2750 jobs.sort(key=lambda x:x['start_time'], reverse=True) 2751 context = {'sizeOfJobs':len(request.session['callback']), 'jobs':jobs } 2752 2753 t = template_loader.get_template(template) 2754 c = Context(request,context) 2755 logger.debug('TEMPLATE: '+template) 2756 return HttpResponse(t.render(c))
2757
2758 #################################################################################### 2759 # User Photo 2760 2761 @isUserConnected 2762 -def load_photo(request, oid=None, **kwargs):
2763 conn = None 2764 try: 2765 conn = kwargs["conn"] 2766 except: 2767 logger.error(traceback.format_exc()) 2768 return handlerInternalError("Connection is not available. Please contact your administrator.") 2769 2770 photo = conn.getExperimenterPhoto(oid) 2771 return HttpResponse(photo, mimetype='image/jpeg')
2772
2773 @isUserConnected 2774 -def myphoto(request, **kwargs):
2775 conn = None 2776 try: 2777 conn = kwargs["conn"] 2778 except: 2779 logger.error(traceback.format_exc()) 2780 return handlerInternalError("Connection is not available. Please contact your administrator.") 2781 2782 photo = conn.getExperimenterPhoto() 2783 return HttpResponse(photo, mimetype='image/jpeg')
2784
2785 #################################################################################### 2786 # Bird's eye view 2787 2788 @isUserConnected 2789 -def render_birds_eye_view (request, iid, size=200, share_id=None, **kwargs):
2790 conn = None 2791 if share_id is not None: 2792 try: 2793 conn = kwargs["conn_share"] 2794 except: 2795 logger.error(traceback.format_exc()) 2796 return handlerInternalError("Connection is not available. Please contact your administrator.") 2797 else: 2798 try: 2799 conn = kwargs["conn"] 2800 except: 2801 logger.error(traceback.format_exc()) 2802 return handlerInternalError("Connection is not available. Please contact your administrator.") 2803 2804 if conn is None: 2805 raise Exception("Connection not available") 2806 2807 return webgateway_views.render_birds_eye_view(request, iid, size=size, _conn=conn, _defcb=conn.defaultThumbnail, **kwargs)
2808
2809 #################################################################################### 2810 # Rendering 2811 2812 @isUserConnected 2813 -def render_thumbnail (request, iid, share_id=None, **kwargs):
2814 conn = None 2815 if share_id is not None: 2816 try: 2817 conn = kwargs["conn_share"] 2818 except: 2819 logger.error(traceback.format_exc()) 2820 return handlerInternalError("Connection is not available. Please contact your administrator.") 2821 else: 2822 try: 2823 conn = kwargs["conn"] 2824 except: 2825 logger.error(traceback.format_exc()) 2826 return handlerInternalError("Connection is not available. Please contact your administrator.") 2827 2828 if conn is None: 2829 raise Exception("Connection not available") 2830 2831 return webgateway_views.render_thumbnail(request, iid, w=80, _conn=conn, _defcb=conn.defaultThumbnail, **kwargs)
2832
2833 @isUserConnected 2834 -def render_thumbnail_resize (request, size, iid, share_id=None, **kwargs):
2835 conn = None 2836 if share_id is not None: 2837 try: 2838 conn = kwargs["conn_share"] 2839 except: 2840 logger.error(traceback.format_exc()) 2841 return handlerInternalError("Connection is not available. Please contact your administrator.") 2842 else: 2843 try: 2844 conn = kwargs["conn"] 2845 except: 2846 logger.error(traceback.format_exc()) 2847 return handlerInternalError("Connection is not available. Please contact your administrator.") 2848 2849 if conn is None: 2850 raise Exception("Connection not available") 2851 2852 return webgateway_views.render_thumbnail(request, iid, w=size, _conn=conn, _defcb=conn.defaultThumbnail, **kwargs)
2853
2854 @isUserConnected 2855 -def render_image (request, iid, z, t, share_id=None, **kwargs):
2856 """ Renders the image with id {{iid}} at {{z}} and {{t}} as jpeg. 2857 Many options are available from the request dict. 2858 I am assuming a single Pixels object on image with id='iid'. May be wrong """ 2859 2860 conn = None 2861 if share_id is not None: 2862 try: 2863 conn = kwargs["conn_share"] 2864 except: 2865 logger.error(traceback.format_exc()) 2866 return handlerInternalError("Connection is not available. Please contact your administrator.") 2867 else: 2868 try: 2869 conn = kwargs["conn"] 2870 except: 2871 logger.error(traceback.format_exc()) 2872 return handlerInternalError("Connection is not available. Please contact your administrator.") 2873 2874 if conn is None: 2875 raise Exception("Connection not available") 2876 2877 return webgateway_views.render_image(request, iid, z, t, _conn=conn, **kwargs)
2878
2879 @isUserConnected 2880 -def render_image_region (request, iid, z, t, server_id=None, share_id=None, _conn=None, **kwargs):
2881 """ Renders the image with id {{iid}} at {{z}} and {{t}} as jpeg. 2882 Many options are available from the request dict. 2883 I am assuming a single Pixels object on image with id='iid'. May be wrong """ 2884 2885 conn = None 2886 if share_id is not None: 2887 try: 2888 conn = kwargs["conn_share"] 2889 except: 2890 logger.error(traceback.format_exc()) 2891 return handlerInternalError("Connection is not available. Please contact your administrator.") 2892 else: 2893 try: 2894 conn = kwargs["conn"] 2895 except: 2896 logger.error(traceback.format_exc()) 2897 return handlerInternalError("Connection is not available. Please contact your administrator.") 2898 2899 if conn is None: 2900 raise Exception("Connection not available") 2901 2902 return webgateway_views.render_image_region(request, iid, z, t, server_id=None, _conn=conn, **kwargs)
2903
2904 @isUserConnected 2905 -def plateGrid_json (request, pid, field=0, server_id=None, _conn=None, **kwargs):
2906 """ This view is responsible for showing well data within plate """ 2907 2908 conn = None 2909 kwargs['viewport_server'] = '/webclient' 2910 try: 2911 conn = kwargs["conn"] 2912 except: 2913 logger.error(traceback.format_exc()) 2914 return handlerInternalError("Connection is not available. Please contact your administrator.") 2915 2916 if conn is None: 2917 raise Exception("Connection not available") 2918 2919 return webgateway_views.plateGrid_json(request, pid, field=field, server_id=None, _conn=None, **kwargs)
2920
2921 @isUserConnected 2922 -def image_viewer (request, iid, share_id=None, **kwargs):
2923 """ This view is responsible for showing pixel data as images """ 2924 2925 conn = None 2926 if share_id is not None: 2927 kwargs['viewport_server'] = '/webclient/%s' % share_id 2928 try: 2929 conn = kwargs["conn_share"] 2930 except: 2931 logger.error(traceback.format_exc()) 2932 return handlerInternalError("Connection is not available. Please contact your administrator.") 2933 else: 2934 kwargs['viewport_server'] = '/webclient' 2935 try: 2936 conn = kwargs["conn"] 2937 except: 2938 logger.error(traceback.format_exc()) 2939 return handlerInternalError("Connection is not available. Please contact your administrator.") 2940 2941 if conn is None: 2942 raise Exception("Connection not available") 2943 2944 return webgateway_views.full_viewer(request, iid, _conn=conn, **kwargs)
2945
2946 2947 @isUserConnected 2948 -def imageData_json (request, iid, share_id=None, **kwargs):
2949 """ Get a dict with image information """ 2950 conn = None 2951 if share_id is not None: 2952 try: 2953 conn = kwargs["conn_share"] 2954 except: 2955 logger.error(traceback.format_exc()) 2956 return handlerInternalError("Connection is not available. Please contact your administrator.") 2957 else: 2958 try: 2959 conn = kwargs["conn"] 2960 except: 2961 logger.error(traceback.format_exc()) 2962 return handlerInternalError("Connection is not available. Please contact your administrator.") 2963 2964 if conn is None: 2965 raise Exception("Connection not available") 2966 2967 return HttpResponse(webgateway_views.imageData_json(request, iid=iid, _conn=conn, **kwargs), mimetype='application/javascript')
2968
2969 @isUserConnected 2970 -def render_row_plot (request, iid, z, t, y, share_id=None, w=1, **kwargs):
2971 """ Get a dict with image information """ 2972 conn = None 2973 if share_id is not None: 2974 try: 2975 conn = kwargs["conn_share"] 2976 except: 2977 logger.error(traceback.format_exc()) 2978 return handlerInternalError("Connection is not available. Please contact your administrator.") 2979 else: 2980 try: 2981 conn = kwargs["conn"] 2982 except: 2983 logger.error(traceback.format_exc()) 2984 return handlerInternalError("Connection is not available. Please contact your administrator.") 2985 2986 if conn is None: 2987 raise Exception("Connection not available") 2988 img = conn.getObject("Image", iid) 2989 2990 return webgateway_views.render_row_plot(request, iid=iid, z=z, t=t, y=y, w=w, _conn=conn, **kwargs)
2991
2992 @isUserConnected 2993 -def render_col_plot (request, iid, z, t, x, share_id=None, w=1, **kwargs):
2994 """ Get a dict with image information """ 2995 conn = None 2996 if share_id is not None: 2997 try: 2998 conn = kwargs["conn_share"] 2999 except: 3000 logger.error(traceback.format_exc()) 3001 return handlerInternalError("Connection is not available. Please contact your administrator.") 3002 else: 3003 try: 3004 conn = kwargs["conn"] 3005 except: 3006 logger.error(traceback.format_exc()) 3007 return handlerInternalError("Connection is not available. Please contact your administrator.") 3008 3009 if conn is None: 3010 raise Exception("Connection not available") 3011 img = conn.getObject("Image", iid) 3012 3013 return webgateway_views.render_col_plot(request, iid=iid, z=z, t=t, x=x, w=w, _conn=conn, **kwargs)
3014
3015 @isUserConnected 3016 -def render_split_channel (request, iid, z, t, share_id=None, **kwargs):
3017 """ Get a dict with image information """ 3018 conn = None 3019 if share_id is not None: 3020 try: 3021 conn = kwargs["conn_share"] 3022 except: 3023 logger.error(traceback.format_exc()) 3024 return handlerInternalError("Connection is not available. Please contact your administrator.") 3025 else: 3026 try: 3027 conn = kwargs["conn"] 3028 except: 3029 logger.error(traceback.format_exc()) 3030 return handlerInternalError("Connection is not available. Please contact your administrator.") 3031 3032 if conn is None: 3033 raise Exception("Connection not available") 3034 img = conn.getObject("Image", iid) 3035 3036 return webgateway_views.render_split_channel(request, iid, z, t, _conn=conn, **kwargs)
3037
3038 3039 # scripting service.... 3040 @isUserConnected 3041 -def list_scripts (request, **kwargs):
3042 """ List the available scripts - Just officical scripts for now """ 3043 3044 conn = kwargs['conn'] 3045 3046 scriptService = conn.getScriptService() 3047 scripts = scriptService.getScripts() 3048 3049 # group scripts into 'folders' (path), named by parent folder name 3050 scriptMenu = {} 3051 for s in scripts: 3052 scriptId = s.id.val 3053 path = s.path.val 3054 name = s.name.val 3055 fullpath = os.path.join(path, name) 3056 if fullpath in settings.SCRIPTS_TO_IGNORE: 3057 logger.info('Ignoring script %r' % fullpath) 3058 continue 3059 displayName = name.replace("_", " ") 3060 3061 if path not in scriptMenu: 3062 folder, name = os.path.split(path) 3063 if len(name) == 0: # path was /path/to/folderName/ - we want 'folderName' 3064 folderName = os.path.basename(folder) 3065 else: # path was /path/to/folderName - we want 'folderName' 3066 folderName = name 3067 folderName = folderName.title().replace("_", " ") 3068 scriptMenu[path] = {'name': folderName, 'scripts': []} 3069 3070 scriptMenu[path]['scripts'].append((scriptId, displayName)) 3071 3072 # convert map into list 3073 scriptList = [] 3074 for path, sData in scriptMenu.items(): 3075 sData['path'] = path # sData map has 'name', 'path', 'scripts' 3076 scriptList.append(sData) 3077 scriptList.sort(key=lambda x:x['name']) 3078 3079 return render_to_response("webclient/scripts/list_scripts.html", {'scriptMenu': scriptList})
3080
3081 @isUserConnected 3082 -def script_ui(request, scriptId, **kwargs):
3083 """ 3084 Generates an html form for the parameters of a defined script. 3085 """ 3086 3087 conn = kwargs['conn'] 3088 scriptService = conn.getScriptService() 3089 3090 params = scriptService.getParams(long(scriptId)) 3091 if params == None: 3092 return HttpResponse() 3093 3094 paramData = {} 3095 3096 paramData["id"] = long(scriptId) 3097 paramData["name"] = params.name.replace("_", " ") 3098 paramData["description"] = params.description 3099 paramData["authors"] = ", ".join([a for a in params.authors]) 3100 paramData["contact"] = params.contact 3101 paramData["version"] = params.version 3102 paramData["institutions"] = ", ".join([i for i in params.institutions]) 3103 3104 inputs = [] # use a list so we can sort by 'grouping' 3105 Data_TypeParam = None 3106 IDsParam = None 3107 for key, param in params.inputs.items(): 3108 i = {} 3109 i["name"] = key.replace("_", " ") 3110 i["key"] = key 3111 if not param.optional: 3112 i["required"] = True 3113 i["description"] = param.description 3114 if param.min: 3115 i["min"] = str(param.min.getValue()) 3116 if param.max: 3117 i["max"] = str(param.max.getValue()) 3118 if param.values: 3119 i["options"] = [v.getValue() for v in param.values.getValue()] 3120 if param.useDefault: 3121 i["default"] = unwrap(param.prototype) 3122 pt = unwrap(param.prototype) 3123 if pt.__class__.__name__ == 'dict': 3124 i["map"] = True 3125 elif pt.__class__.__name__ == 'list': 3126 i["list"] = True 3127 if "default" in i: i["default"] = i["default"][0] 3128 elif pt.__class__ == type(True): 3129 i["boolean"] = True 3130 elif pt.__class__ == type(0) or pt.__class__ == type(long(0)): 3131 i["number"] = "number" # will stop the user entering anything other than numbers. 3132 elif pt.__class__ == type(float(0.0)): 3133 i["number"] = "float" 3134 3135 # if we got a value for this key in the page request, use this as default 3136 if request.REQUEST.get(key, None) is not None: 3137 i["default"] = request.REQUEST.get(key, None) 3138 3139 i["prototype"] = unwrap(param.prototype) # E.g "" (string) or [0] (int list) or 0.0 (float) 3140 i["grouping"] = param.grouping 3141 inputs.append(i) 3142 3143 if key == "IDs": IDsParam = i # remember these... 3144 if key == "Data_Type": Data_TypeParam = i 3145 inputs.sort(key=lambda i: i["grouping"]) 3146 3147 # if we have Data_Type param that has a "default" and "options" - check they match... 3148 if Data_TypeParam is not None and "default" in Data_TypeParam and "options" in Data_TypeParam: 3149 if Data_TypeParam["default"] not in Data_TypeParam["options"]: 3150 IDsParam["default"] = "" # ... if not, don't set IDs 3151 3152 # try to determine hierarchies in the groupings - ONLY handle 1 hierarchy level now (not recursive!) 3153 for i in range(len(inputs)): 3154 if len(inputs) <= i: # we may remove items from inputs as we go - need to check 3155 break 3156 param = inputs[i] 3157 grouping = param["grouping"] # E.g 03 3158 param['children'] = list() 3159 c = 1 3160 while len(inputs) > i+1: 3161 nextParam = inputs[i+1] 3162 nextGrp = inputs[i+1]["grouping"] # E.g. 03.1 3163 if nextGrp.split(".")[0] == grouping: 3164 param['children'].append(inputs[i+1]) 3165 inputs.pop(i+1) 3166 else: 3167 break 3168 3169 paramData["inputs"] = inputs 3170 3171 return render_to_response('webclient/scripts/script_ui.html', {'paramData': paramData, 'scriptId': scriptId})
3172
3173 @isUserConnected 3174 -def script_run(request, scriptId, **kwargs):
3175 """ 3176 Runs a script using values in a POST 3177 """ 3178 conn = kwargs['conn'] 3179 scriptService = conn.getScriptService() 3180 3181 inputMap = {} 3182 3183 sId = long(scriptId) 3184 3185 params = scriptService.getParams(sId) 3186 scriptName = params.name.replace("_", " ").replace(".py", "") 3187 3188 logger.debug("Script: run with request.POST: %s" % request.POST) 3189 3190 for key, param in params.inputs.items(): 3191 prototype = param.prototype 3192 pclass = prototype.__class__ 3193 3194 # handle bool separately, since unchecked checkbox will not be in request.POST 3195 if pclass == omero.rtypes.RBoolI: 3196 value = key in request.POST 3197 inputMap[key] = pclass(value) 3198 continue 3199 3200 if pclass.__name__ == 'RMapI': 3201 keyName = "%s_key" % key 3202 valueName = "%s_value" % key 3203 row = 0 3204 paramMap = {} 3205 while keyName in request.POST: 3206 # the key and value don't have any data-type defined by scripts - just use string 3207 k = str(request.POST[keyName]) 3208 v = str(request.POST[valueName]) 3209 if len(k) > 0 and len(v) > 0: 3210 paramMap[str(k)] = str(v) 3211 row +=1 3212 keyName = "%s_key%d" % (key, row) 3213 valueName = "%s_value%d" % (key, row) 3214 if len(paramMap) > 0: 3215 inputMap[key] = wrap(paramMap) 3216 continue 3217 3218 if key in request.POST: 3219 if pclass == omero.rtypes.RListI: 3220 values = request.POST.getlist(key) 3221 if len(values) == 0: continue 3222 if len(values) == 1: # process comma-separated list 3223 if len(values[0]) == 0: continue 3224 values = values[0].split(",") 3225 3226 # try to determine 'type' of values in our list 3227 listClass = omero.rtypes.rstring 3228 l = prototype.val # list 3229 if len(l) > 0: # check if a value type has been set (first item of prototype list) 3230 listClass = l[0].__class__ 3231 if listClass == int(1).__class__: 3232 listClass = omero.rtypes.rint 3233 if listClass == long(1).__class__: 3234 listClass = omero.rtypes.rlong 3235 3236 # construct our list, using appropriate 'type' 3237 valueList = [] 3238 for v in values: 3239 try: 3240 obj = listClass(str(v.strip())) # convert unicode -> string 3241 except: 3242 logger.debug("Invalid entry for '%s' : %s" % (key, v)) 3243 continue 3244 if isinstance(obj, omero.model.IObject): 3245 valueList.append(omero.rtypes.robject(obj)) 3246 else: 3247 valueList.append(obj) 3248 inputMap[key] = omero.rtypes.rlist(valueList) 3249 3250 # Handle other rtypes: String, Long, Int etc. 3251 else: 3252 value = request.POST[key] 3253 if len(value) == 0: continue 3254 try: 3255 inputMap[key] = pclass(value) 3256 except: 3257 logger.debug("Invalid entry for '%s' : %s" % (key, value)) 3258 continue 3259 3260 logger.debug("Running script %s with params %s" % (scriptName, inputMap)) 3261 try: 3262 handle = scriptService.runScript(sId, inputMap, None) 3263 # E.g. ProcessCallback/4ab13b23-22c9-4b5f-9318-40f9a1acc4e9 -t:tcp -h 10.37.129.2 -p 53154:tcp -h 10.211.55.2 -p 53154:tcp -h 10.12.1.230 -p 53154 3264 jobId = str(handle) 3265 request.session['callback'][jobId] = { 3266 'job_type': "script", 3267 'job_name': scriptName, 3268 'start_time': datetime.datetime.now(), 3269 'status':'in progress'} 3270 request.session.modified = True 3271 except Exception, x: 3272 jobId = str(time()) # E.g. 1312803670.6076391 3273 if x.message == "No processor available.": # omero.ResourceError 3274 logger.info(traceback.format_exc()) 3275 error = None 3276 status = 'no processor available' 3277 message = 'No Processor Available: Please try again later' 3278 else: 3279 logger.error(traceback.format_exc()) 3280 error = traceback.format_exc() 3281 status = 'failed' 3282 message = x.message 3283 # save the error to http session, for display in 'Activities' window 3284 request.session['callback'][jobId] = { 3285 'job_type': "script", 3286 'job_name': scriptName, 3287 'start_time': datetime.datetime.now(), 3288 'status':status, 3289 'Message': message, 3290 'error':error} 3291 request.session.modified = True 3292 # we return this, although it is now ignored (script window closes) 3293 return HttpResponse(simplejson.dumps({'status': status, 'error': error}), mimetype='json') 3294 3295 return HttpResponse(simplejson.dumps({'jobId': jobId, 'status':'in progress'}), mimetype='json')
3296 3297 3298 #################################################################################### 3299 # utils 3300 3301 GOOGLE_URL = "www.google.com"
3302 -def spellchecker(request):
3303 if request.method == 'POST': 3304 lang = request.GET.get("lang", "en") 3305 data = request.raw_post_data 3306 con = httplib.HTTPSConnection(GOOGLE_URL) 3307 con.request("POST", "/tbproxy/spell?lang=%s" % lang, data) 3308 response = con.getresponse() 3309 r_text = response.read() 3310 con.close() 3311 return HttpJavascriptResponse(r_text)
3312