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

Source Code for Module omeroweb.webmobile.views

  1  from django.http import HttpResponse, HttpResponseRedirect 
  2  from django.core.urlresolvers import reverse 
  3  from django.shortcuts import render_to_response 
  4  from omeroweb.webgateway.views import getBlitzConnection, _session_logout 
  5  from omeroweb.webgateway import views as webgateway_views 
  6  import settings 
  7  import logging 
  8  import traceback 
  9  import omero 
 10  # use the webclient's gateway connection wrapper 
 11  from webclient.webclient_gateway import OmeroWebGateway 
 12  import webmobile_util 
 13   
 14  logger = logging.getLogger('webmobilewebmobile') 
15 16 17 -def isUserConnected (f):
18 """ 19 connection decorator (wraps methods that require connection) - adapted from webclient.views 20 retrieves connection and passes it to the wrapped method in kwargs 21 TODO: would be nice to refactor isUserConnected from webclient to be usable from here. 22 """ 23 def wrapped (request, *args, **kwargs): 24 #this check the connection exist, if not it will redirect to login page 25 url = request.REQUEST.get('url') 26 if url is None or len(url) == 0: 27 if request.META.get('QUERY_STRING'): 28 url = '%s?%s' % (request.META.get('PATH_INFO'), request.META.get('QUERY_STRING')) 29 else: 30 url = '%s' % (request.META.get('PATH_INFO')) 31 32 conn = None 33 loginUrl = reverse("webmobile_login") 34 try: 35 conn = getBlitzConnection(request, useragent="OMERO.webmobile") 36 except Exception, x: 37 logger.error(traceback.format_exc()) 38 return HttpResponseRedirect("%s?error=%s&url=%s" % (loginUrl, str(x), url)) 39 40 # if we failed to connect - redirect to login page, passing the destination url 41 if conn is None: 42 return HttpResponseRedirect("%s?url=%s" % (loginUrl, url)) 43 44 # if we got a connection, pass it to the wrapped method in kwargs 45 kwargs["error"] = request.REQUEST.get('error') 46 kwargs["conn"] = conn 47 kwargs["url"] = url 48 return f(request, *args, **kwargs)
49 return wrapped 50
51 52 -def groups_members(request):
53 """ 54 List the users of the current group - if permitted 55 """ 56 conn = getBlitzConnection (request, useragent="OMERO.webmobile") 57 if conn is None or not conn.isConnected(): 58 return HttpResponseRedirect(reverse('webmobile_login')) 59 60 groupId = conn.getEventContext().groupId 61 showMembers = True 62 if str(conn.getEventContext().groupPermissions) == "rw----": 63 showMembers = False 64 members = conn.containedExperimenters(groupId) 65 66 groups = [] 67 perms = {"rw----":'private', "rwr---":'read-only', "rwrw--":'collaborative'} 68 for g in conn.getGroupsMemberOf(): 69 try: 70 p = perms[str(g.getDetails().permissions)] 71 except KeyError: 72 p = "" 73 groups.append({ 74 "id": g.id, 75 "name": g.getName(), 76 "permissions": p 77 }) 78 79 return render_to_response('webmobile/groups_members.html', {'client': conn, 'showMembers': showMembers, 80 'members': members, 'groups': groups})
81
82 83 -def switch_group(request, groupId):
84 """ 85 Switch to the specified group, then redirect to index. 86 """ 87 conn = getBlitzConnection (request, useragent="OMERO.webmobile") 88 if conn is None or not conn.isConnected(): 89 return HttpResponseRedirect(reverse('webmobile_login')) 90 91 from webclient.views import change_active_group 92 try: 93 #change_active_group(request, kwargs={'conn': conn}) 94 conn.changeActiveGroup(long(groupId)) # works except after viewing thumbnails in private group! 95 except: 96 logger.error(traceback.format_exc()) 97 return HttpResponse(traceback.format_exc()) 98 99 return HttpResponseRedirect(reverse('webmobile_index'))
100
101 102 @isUserConnected 103 -def change_active_group(request, groupId, **kwargs):
104 try: 105 conn = kwargs["conn"] 106 except: 107 logger.error(traceback.format_exc()) 108 return handlerInternalError("Connection is not available. Please contact your administrator.") 109 110 url = reverse('webmobile_index') 111 112 server = request.session.get('server') 113 username = request.session.get('username') 114 password = request.session.get('password') 115 ssl = request.session.get('ssl') 116 version = request.session.get('version') 117 118 webgateway_views._session_logout(request, request.session.get('server')) 119 120 blitz = settings.SERVER_LIST.get(pk=server) 121 request.session['server'] = blitz.id 122 request.session['host'] = blitz.host 123 request.session['port'] = blitz.port 124 request.session['username'] = username 125 request.session['password'] = password 126 request.session['ssl'] = (True, False)[request.REQUEST.get('ssl') is None] 127 request.session['clipboard'] = {'images': None, 'datasets': None, 'plates': None} 128 request.session['shares'] = dict() 129 request.session['imageInBasket'] = set() 130 blitz_host = "%s:%s" % (blitz.host, blitz.port) 131 request.session['nav']={"error": None, "blitz": blitz_host, "menu": "start", "view": "icon", "basket": 0, "experimenter":None, 'callback':dict()} 132 133 #conn = getBlitzConnection(request, useragent="OMERO.webmobile") 134 135 if conn.changeActiveGroup(groupId): 136 request.session.modified = True 137 else: 138 error = 'You cannot change your group becuase the data is currently processing. You can force it by logging out and logging in again.' 139 url = reverse("webindex")+ ("?error=%s" % error) 140 if request.session.get('nav')['experimenter'] is not None: 141 url += "&experimenter=%s" % request.session.get('nav')['experimenter'] 142 143 request.session['version'] = conn.getServerVersion() 144 145 return HttpResponseRedirect(url)
146
147 148 -def viewer(request, imageId):
149 conn = getBlitzConnection (request, useragent="OMERO.webmobile") 150 if conn is None or not conn.isConnected(): 151 return HttpResponseRedirect(reverse('webmobile_login')) 152 153 image = conn.getObject("Image", imageId) 154 w = image.getSizeX() 155 h = image.getSizeY() 156 157 return render_to_response('webmobile/viewers/viewer_iphone.html', {'image':image})
158
159 160 @isUserConnected 161 -def viewer_big(request, imageId, **kwargs):
162 conn = None 163 try: 164 conn = kwargs["conn"] 165 except: 166 logger.error(traceback.format_exc()) 167 return HttpResponse(traceback.format_exc()) 168 169 image = conn.getImage(imageId) 170 w = image.getWidth() 171 h = image.getHeight() 172 z = image.z_count() /2 173 174 return render_to_response('webmobile/viewers/big_iphone.html', {'image':image, 'w':w, 'h': h, 'z':z})
175
176 177 @isUserConnected 178 -def projects (request, eid=None, **kwargs):
179 """ List the projects owned by the current user, or another user specified by eId """ 180 181 conn = None 182 try: 183 conn = kwargs["conn"] 184 except: 185 logger.error(traceback.format_exc()) 186 return HttpResponse(traceback.format_exc()) 187 188 #projects = filter(lambda x: x.isOwned(), conn.listProjects()) 189 #eId = request.REQUEST.get('experimenter', None) 190 experimenter = None 191 if eid is not None: 192 experimenter = conn.getObject("Experimenter", eid) 193 else: 194 # show current user's projects by default 195 eid = conn.getEventContext().userId 196 197 projs = conn.listProjects(eid=eid) 198 projs = list(projs) 199 200 if request.REQUEST.get('sort', None) == 'recent': 201 projs.sort(key=lambda x: x.creationEventDate()) 202 projs.reverse() 203 else: 204 projs.sort(key=lambda x: x.getName().lower()) 205 ods = conn.listOrphans("Dataset", eid=eid) 206 orphanedDatasets = list(ods) 207 208 return render_to_response('webmobile/browse/projects.html', 209 { 'client':conn, 'projects':projs, 'datasets':orphanedDatasets, 'experimenter':experimenter })
210
211 212 @isUserConnected 213 -def project(request, id, **kwargs):
214 """ Show datasets belonging to the specified project """ 215 216 conn = None 217 try: 218 conn = kwargs["conn"] 219 except: 220 logger.error(traceback.format_exc()) 221 return HttpResponse(traceback.format_exc()) 222 223 prj = conn.getObject("Project", id) 224 return render_to_response('webmobile/browse/project.html', {'client':conn, 'project':prj})
225
226 227 @isUserConnected 228 -def object_details(request, obj_type, id, **kwargs):
229 """ Show project/dataset details: Name, description, owner, annotations etc """ 230 231 conn = None 232 try: 233 conn = kwargs["conn"] 234 except: 235 logger.error(traceback.format_exc()) 236 return HttpResponse(traceback.format_exc()) 237 238 if obj_type == 'project': 239 obj = conn.getObject("Project", id) 240 title = 'Project' 241 elif obj_type == 'dataset': 242 obj = conn.getObject("Dataset", id) 243 title = 'Dataset' 244 anns = getAnnotations(obj) 245 246 parent = obj.getParent() 247 248 return render_to_response('webmobile/browse/object_details.html', {'client': conn, 'object': obj, 'title': title, 249 'annotations':anns, 'obj_type': obj_type})
250
251 252 @isUserConnected 253 -def dataset(request, id, **kwargs):
254 """ Show images in the specified dataset """ 255 256 conn = None 257 try: 258 conn = kwargs["conn"] 259 except: 260 logger.error(traceback.format_exc()) 261 return HttpResponse(traceback.format_exc()) 262 263 ds = conn.getObject("Dataset", id) 264 return render_to_response('webmobile/browse/dataset.html', {'client': conn, 'dataset': ds})
265
266 267 @isUserConnected 268 -def image(request, imageId, **kwargs):
269 """ Show image summary: Name, dimensions, large thumbnail, description, annotations """ 270 271 conn = None 272 try: 273 conn = kwargs["conn"] 274 except: 275 logger.error(traceback.format_exc()) 276 return HttpResponse(traceback.format_exc()) 277 278 img = conn.getObject("Image", imageId) 279 anns = getAnnotations(img) 280 281 return render_to_response('webmobile/browse/image.html', {'client': conn, 'object':img, 'obj_type':'image', 282 'annotations': anns})
283
284 @isUserConnected 285 -def orphaned_images(request, eid, **kwargs):
286 """ Show image summary: Name, dimensions, large thumbnail, description, annotations """ 287 288 conn = None 289 try: 290 conn = kwargs["conn"] 291 except: 292 logger.error(traceback.format_exc()) 293 return HttpResponse(traceback.format_exc()) 294 295 orphans = conn.listOrphans("Image", eid=eid) 296 return render_to_response('webmobile/browse/orphaned_images.html', {'client': conn, 'orphans':orphans})
297
298 299 @isUserConnected 300 -def screens(request, eid=None, **kwargs):
301 """ """ 302 303 conn = None 304 try: 305 conn = kwargs["conn"] 306 except: 307 logger.error(traceback.format_exc()) 308 return HttpResponse(traceback.format_exc()) 309 310 experimenter = None 311 if eid is not None: 312 experimenter = conn.getObject("Experimenter", eid) 313 else: 314 # show current user's screens by default 315 eid = conn.getEventContext().userId 316 317 scrs = conn.listScreens(eid=eid) 318 319 if request.REQUEST.get('sort', None) == 'recent': 320 scrs = list(scrs) 321 scrs.sort(key=lambda x: x.creationEventDate()) 322 scrs.reverse() 323 324 ops = conn.listOrphans("Plate", eid=eid) 325 orphanedPlates = list(ops) 326 327 return render_to_response('webmobile/browse/screens.html', 328 {'client':conn, 'screens':scrs, 'orphans':orphanedPlates, 'experimenter':experimenter })
329
330 331 @isUserConnected 332 -def screen(request, id, **kwargs):
333 """ Show plates in the specified scren """ 334 335 conn = None 336 try: 337 conn = kwargs["conn"] 338 except: 339 logger.error(traceback.format_exc()) 340 return HttpResponse(traceback.format_exc()) 341 342 scrn = conn.getObject("Screen", id) 343 return render_to_response('webmobile/browse/screen.html', {'client': conn, 'screen': scrn})
344
345 346 @isUserConnected 347 -def plate(request, id, **kwargs):
348 """ Show plate - grid of thumbs? """ 349 350 conn = None 351 try: 352 conn = kwargs["conn"] 353 except: 354 logger.error(traceback.format_exc()) 355 return HttpResponse(traceback.format_exc()) 356 357 scrn = conn.getObject("Screen", id) 358 return render_to_response('webmobile/browse/screen.html', {'client': conn, 'screen': scrn})
359
360 361 -def getAnnotations(obj):
362 """ List the annotations and sort into comments, tags, ratings, files etc """ 363 364 comments = list() 365 ratings = list() 366 files = list() 367 tags = list() 368 369 from omero.model import CommentAnnotationI, LongAnnotationI, TagAnnotationI, FileAnnotationI 370 371 for ann in obj.listAnnotations(): 372 if isinstance(ann._obj, CommentAnnotationI): 373 comments.append(ann) 374 elif isinstance(ann._obj, LongAnnotationI): 375 ratings.append(ann) 376 elif isinstance(ann._obj, FileAnnotationI): 377 files.append(ann) 378 elif isinstance(ann._obj, TagAnnotationI): 379 tags.append(ann) 380 381 comments.sort(key=lambda x: x.creationEventDate()) 382 comments.reverse() 383 384 return {"comments":comments, "ratings":ratings, "files":files, "tags":tags}
385
386 387 @isUserConnected 388 -def edit_object(request, obj_type, obj_id, **kwargs):
389 """ 390 Display a page for editing Name and Description of Project/Dataset/Image etc 391 Page 'submit' redirects here with 'name' and 'description' in POST, which 392 will do the edit and return to the object_details page. 393 """ 394 conn = None 395 try: 396 conn = kwargs["conn"] 397 except: 398 logger.error(traceback.format_exc()) 399 return HttpResponse(traceback.format_exc()) 400 401 if obj_type == 'image': 402 obj = conn.getObject("Image", obj_id) 403 title = 'Image' 404 redirect = reverse('webmobile_image', kwargs={'imageId':obj_id}) 405 elif obj_type == 'dataset': 406 obj = conn.getObject("Dataset", obj_id) 407 title = 'Dataset' 408 redirect = reverse('webmobile_dataset_details', kwargs={'id':obj_id}) 409 elif obj_type == 'project': 410 obj = conn.getObject("Project", obj_id) 411 title = 'Project' 412 redirect = reverse('webmobile_project_details', kwargs={'id':obj_id}) 413 414 # if name, description in request, edit and redirect to object_details 415 name = request.REQUEST.get('name', None) 416 if name: 417 obj.setName(name) 418 description = request.REQUEST.get('description', '').strip() 419 if len(description) == 0: 420 description = None 421 obj.setDescription(description) 422 obj.save() 423 return HttpResponseRedirect(redirect) 424 425 return render_to_response('webmobile/browse/edit_object.html', {'client': conn, 'title':title, 'object':obj})
426
427 428 @isUserConnected 429 -def add_comment(request, obj_type, obj_id, **kwargs):
430 """ 431 Adds a comment (from request 'comment') to object 'project', 'dataset', 'image' then 432 redirects to the 'details' page for that object: E.g. project_details page etc. 433 """ 434 conn = None 435 try: 436 conn = kwargs["conn"] 437 except: 438 logger.error(traceback.format_exc()) 439 return HttpResponse(traceback.format_exc()) 440 441 from omero.rtypes import rstring 442 443 redirect = reverse('webmobile_index') # default 444 if obj_type == 'image': 445 l = omero.model.ImageAnnotationLinkI() 446 parent = omero.model.ImageI(obj_id, False) # use unloaded object to avoid update conflicts 447 redirect = reverse('webmobile_image', kwargs={'imageId':obj_id}) 448 elif obj_type == 'dataset': 449 l = omero.model.DatasetAnnotationLinkI() 450 parent = omero.model.DatasetI(obj_id, False) 451 redirect = reverse('webmobile_dataset_details', kwargs={'id':obj_id}) 452 elif obj_type == 'project': 453 l = omero.model.ProjectAnnotationLinkI() 454 parent = omero.model.ProjectI(obj_id, False) 455 redirect = reverse('webmobile_project_details', kwargs={'id':obj_id}) 456 457 comment = request.REQUEST.get('comment', None) 458 if comment is None or (len(comment.strip()) == 0): 459 return HttpResponseRedirect(redirect) 460 461 updateService = conn.getUpdateService() 462 ann = omero.model.CommentAnnotationI() 463 comment = unicode(comment).encode("utf-8").strip() 464 ann.setTextValue(rstring(comment)) 465 ann = updateService.saveAndReturnObject(ann) 466 l.setParent(parent) 467 l.setChild(ann) 468 updateService.saveObject(l) 469 470 return HttpResponseRedirect(redirect)
471
472 473 -def login (request):
474 if request.method == 'POST' and request.REQUEST['server']: 475 blitz = settings.SERVER_LIST.get(pk=request.REQUEST['server']) 476 request.session['server'] = blitz.id 477 request.session['host'] = blitz.host 478 request.session['port'] = blitz.port 479 480 conn = getBlitzConnection (request, useragent="OMERO.webmobile") 481 logger.debug(conn) 482 483 url = request.REQUEST.get("url") 484 485 if conn is None: 486 return render_to_response('webmobile/login.html', {'gw':settings.SERVER_LIST, 'url': url}) 487 488 if url is not None and len(url) != 0: 489 return HttpResponseRedirect(url) 490 else: 491 return HttpResponseRedirect(reverse('webmobile_index'))
492
493 494 -def logout (request):
495 _session_logout(request, request.session['server']) 496 try: 497 del request.session['username'] 498 except KeyError: 499 logger.error(traceback.format_exc()) 500 try: 501 del request.session['password'] 502 except KeyError: 503 logger.error(traceback.format_exc()) 504 505 #request.session.set_expiry(1) 506 return HttpResponseRedirect(reverse('webmobile_login'))
507
508 @isUserConnected 509 -def index (request, eid=None, **kwargs):
510 conn = None 511 try: 512 conn = kwargs["conn"] 513 except: 514 logger.error(traceback.format_exc()) 515 return HttpResponse(traceback.format_exc()) 516 517 experimenter = None 518 if eid is not None: 519 experimenter = conn.getObject("Experimenter", eid) 520 521 return render_to_response('webmobile/index.html', {'client': conn, 'experimenter': experimenter})
522
523 524 @isUserConnected 525 -def recent (request, obj_type, eid=None, **kwargs):
526 conn = None 527 try: 528 conn = kwargs["conn"] 529 except: 530 logger.error(traceback.format_exc()) 531 return HttpResponse(traceback.format_exc()) 532 533 experimenter = None 534 if eid: 535 experimenter = conn.getObject("Experimenter", eid) 536 537 # By default, get 3 each of Projects, Datasets, Images, Ratings, Comments, Tags 538 obj_count = 3 539 obj_types = None 540 if obj_type == 'images': # Get the last 12 images 541 obj_types = ['Image'] 542 obj_count = 12 543 elif obj_type == 'anns': # 4 each of Tags, Comments, Rating 544 obj_types = ['Annotation'] 545 obj_count = 4 546 547 if obj_type == 'rois': 548 recentResults = webmobile_util.listRois(conn, eid) 549 else: 550 recentItems = webmobile_util.listMostRecentObjects(conn, obj_count, obj_types, eid) 551 recentResults = [ webmobile_util.RecentEvent(r) for r in recentItems ] 552 553 # list members for links to other's recent activity 554 groupId = conn.getEventContext().groupId 555 members = conn.containedExperimenters(groupId) 556 557 return render_to_response('webmobile/timeline/recent.html', {'client':conn, 'recent':recentResults, 558 'exp':experimenter, 'members':members, 'obj_type':str(obj_type) })
559
560 @isUserConnected 561 -def recent_full_page (request, **kwargs):
562 """ 563 Mock-up full page for Usability testing of recent views. 564 """ 565 conn = None 566 try: 567 conn = kwargs["conn"] 568 except: 569 logger.error(traceback.format_exc()) 570 return HttpResponse(traceback.format_exc()) 571 572 exp = conn.getObject("Experimenter", conn.getEventContext().userId) 573 574 return render_to_response('webmobile/timeline/recent_full_page.html', {'client':conn, 'exp':exp })
575
576 577 578 @isUserConnected 579 -def collab_annotations (request, myData=True, **kwargs):
580 """ 581 Page displays recent annotations of OTHER users on MY data (myData=True) or 582 MY annotations on data belonging to OTHER users. 583 """ 584 conn = None 585 try: 586 conn = kwargs["conn"] 587 except: 588 logger.error(traceback.format_exc()) 589 return HttpResponse(traceback.format_exc()) 590 591 collabAnns = webmobile_util.listCollabAnnotations(conn, myData) 592 593 return render_to_response('webmobile/timeline/recent_collab.html', {'client':conn, 'recent':collabAnns, 'myData':myData })
594
595 596 -def image_viewer (request, iid, **kwargs):
597 """ This view is responsible for showing pixel data as images """ 598 599 conn = getBlitzConnection (request, useragent="OMERO.webmobile") 600 if conn is None or not conn.isConnected(): 601 return HttpResponseRedirect(reverse('webmobile_login')) 602 603 kwargs['viewport_server'] = '/webclient' 604 605 return webgateway_views.full_viewer(request, iid, _conn=conn, **kwargs)
606