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

Source Code for Module omeroweb.webclient.webclient_gateway

   1  #!/usr/bin/env python 
   2  #  
   3  # webclient_gateway 
   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  #         Carlos Neves <carlos(at)glencoesoftware(dot)com>, 2008 
  22  #  
  23  # Version: 1.0 
  24  # 
  25   
  26  import cStringIO 
  27  import traceback 
  28  import logging 
  29   
  30  logger = logging.getLogger('webclient_gateway') 
  31   
  32  try: 
  33      from PIL import Image, ImageDraw # see ticket:2597 
  34  except ImportError: 
  35      try: 
  36          import Image, ImageDraw # see ticket:2597 
  37      except: 
  38          logger.error("You need to install the Python Imaging Library. Get it at http://www.pythonware.com/products/pil/") 
  39          logger.error(traceback.format_exc()) 
  40   
  41  from StringIO import StringIO 
  42   
  43  import time 
  44  from datetime import datetime 
  45  from types import IntType, ListType, TupleType, UnicodeType, StringType 
  46   
  47  import Ice 
  48  import Glacier2 
  49  import omero.gateway 
  50  import omero.scripts 
  51   
  52  import omero_api_IScript_ice 
  53   
  54  from omero.rtypes import * 
  55  from omero.model import FileAnnotationI, TagAnnotationI, \ 
  56                          DatasetI, ProjectI, ImageI, ScreenI, PlateI, \ 
  57                          DetectorI, FilterI, ObjectiveI, InstrumentI, \ 
  58                          LaserI 
  59   
  60  from omero.gateway import TagAnnotationWrapper, ExperimenterWrapper, \ 
  61                  ExperimenterGroupWrapper, WellWrapper, AnnotationWrapper, \ 
  62                  OmeroGatewaySafeCallWrapper 
  63   
  64  from omero.sys import ParametersI 
  65   
  66  from django.utils.encoding import smart_str 
  67  from django.utils.translation import ugettext as _ 
  68  from django.conf import settings 
  69  from django.core.mail import send_mail 
  70  from django.core.mail import EmailMultiAlternatives 
  71   
  72  try: 
  73      PAGE = settings.PAGE 
  74  except: 
  75      PAGE = 200 
  76   
77 -class OmeroWebGateway (omero.gateway.BlitzGateway):
78
79 - def __init__ (self, *args, **kwargs):
80 """ 81 Create the connection wrapper. Does not attempt to connect at this stage 82 Initialises the omero.client 83 84 @param username: User name. If not specified, use 'omero.gateway.anon_user' 85 @type username: String 86 @param passwd: Password. 87 @type passwd: String 88 @param client_obj: omero.client 89 @param group: name of group to try to connect to 90 @type group: String 91 @param clone: If True, overwrite anonymous with False 92 @type clone: Boolean 93 @param try_super: Try to log on as super user ('system' group) 94 @type try_super: Boolean 95 @param host: Omero server host. 96 @type host: String 97 @param port: Omero server port. 98 @type port: Integer 99 @param extra_config: Dictionary of extra configuration 100 @type extra_config: Dict 101 @param secure: Initial underlying omero.client connection type (True=SSL/False=insecure) 102 @type secure: Boolean 103 @param anonymous: 104 @type anonymous: Boolean 105 @param useragent: Log which python clients use this connection. E.g. 'OMERO.webadmin' 106 @type useragent: String 107 108 @param _shareId: Active share ID 109 @type _shareId: Long 110 """ 111 112 super(OmeroWebGateway, self).__init__(*args, **kwargs) 113 self._shareId = None
114
115 - def connect (self, *args, **kwargs):
116 """ 117 Creates or retrieves connection for the given sessionUuid and 118 removes some groups from the event context 119 Returns True if connected. 120 121 @param sUuid: session uuid 122 @type sUuid: omero_model_SessionI 123 @return: Boolean 124 """ 125 126 rv = super(OmeroWebGateway, self).connect(*args,**kwargs) 127 if rv: # No _ctx available otherwise #3218 128 if self._ctx.userName!="guest": 129 self.removeGroupFromContext() 130 return rv
131
132 - def attachToShare (self, share_id):
133 """ 134 Turns on the access control lists attached to the given share for the 135 current session. Warning: this will slow down the execution of the 136 current session for all database reads. Writing to the database will not 137 be allowed. If share does not exist or is not accessible (non-members) or 138 is disabled, then an ValidationException is thrown. 139 140 @param shareId: share id 141 @type shareId: Long 142 """ 143 144 sh = self._proxies['share'].getShare(long(share_id)) 145 if self._shareId is None: 146 self._proxies['share'].activate(sh.id.val) 147 self._shareId = sh.id.val
148
149 - def getShareId(self):
150 """ 151 Returns active share id . 152 153 @return: Share ID 154 @rtype: Long 155 """ 156 157 if self.getEventContext().shareId is not None: 158 if self.getEventContext().shareId != self._shareId and self._shareId > 0: 159 self._shareId = self.getEventContext().shareId 160 return self._shareId
161
162 - def removeGroupFromContext (self):
163 """ 164 Removes group "User" from the current context. 165 """ 166 167 a = self.getAdminService() 168 gr_u = a.lookupGroup('user') 169 try: 170 self._ctx.memberOfGroups.remove(gr_u.id.val) 171 self._ctx.leaderOfGroups.remove(gr_u.id.val) 172 except: 173 pass
174 175 ############################################## 176 # Session methods # 177
178 - def changeActiveGroup(self, gid): # TODO: should be moved to ISession
179 """ 180 Every time session is created default group becomes active group 181 and is loaded with the security for the current user and thread. 182 Public data has to be created in the context of the group where user, 183 who would like to look at these data, is a member of. 184 Public data can be only visible by the member of group and owners. 185 186 @param gid: New active group ID 187 @type gid: Long 188 189 @return: Boolean 190 """ 191 192 try: 193 for k in self._proxies.keys(): 194 self._proxies[k].close() 195 196 self.c.sf.setSecurityContext(omero.model.ExperimenterGroupI(gid, False)) 197 self.getAdminService().setDefaultGroup(self.getUser()._obj, omero.model.ExperimenterGroupI(gid, False)) 198 self._ctx = self.getAdminService().getEventContext() 199 return True 200 except omero.SecurityViolation: 201 logger.error(traceback.format_exc()) 202 return False 203 except: 204 logger.error(traceback.format_exc()) 205 return False
206 207 ############################################## 208 ## Forgotten password ## 209
210 - def isForgottenPasswordSet(self):
211 """ 212 Retrieves a configuration value "omero.resetpassword.config" for 213 Forgotten password form from the backend store. 214 215 @return: Boolean 216 """ 217 218 conf = self.getConfigService() 219 try: 220 return bool(conf.getConfigValue("omero.resetpassword.config").title()) 221 except: 222 logger.error(traceback.format_exc()) 223 return False
224
225 - def reportForgottenPassword(self, username, email):
226 """ 227 Allows to reset the password (temporary password is sent). The 228 given email must match the email for the user listed under the name 229 argument. 230 231 @param username: omename 232 @type username: String 233 @param email: email address 234 @type email: String 235 236 """ 237 238 admin_serv = self.getAdminService() 239 admin_serv.reportForgottenPassword(username, email)
240 241 ############################################## 242 ## IAdmin ## 243
244 - def isAnythingCreated(self):
245 """ 246 Checks if any of the experimenter was created before 247 248 @return: Boolean 249 """ 250 251 q = self.getQueryService() 252 p = omero.sys.Parameters() 253 p.map = {} 254 p.map["default_names"] = rlist([rstring("user"), rstring("system"), rstring("guest")]) 255 f = omero.sys.Filter() 256 f.limit = rint(1) 257 p.theFilter = f 258 sql = "select g from ExperimenterGroup as g where g.name not in (:default_names)" 259 if len(q.findAllByQuery(sql, p)) > 0: 260 return False 261 return True
262
263 - def listLdapAuthExperimenters(self):
264 """ 265 Lists all IDs of experimenters who are authenticated by LDAP 266 (has set dn on password table). 267 268 @return: List of experimetner IDs 269 @rtype: L{Dict of String: Long} 270 """ 271 272 admin_serv = self.getAdminService() 273 return admin_serv.lookupLdapAuthExperimenters()
274
275 - def getLdapAuthExperimenter(self, eid):
276 """ 277 Return DN of the specific experimenter if uses LDAP authentication 278 (has set dn on password table) or None. 279 280 @param eid: experimenter ID 281 @type eid: L{Long} 282 @return: Distinguished Name 283 @rtype: String 284 """ 285 286 admin_serv = self.getAdminService() 287 return admin_serv.lookupLdapAuthExperimenter(long(eid))
288
289 - def getExperimenters(self):
290 """ 291 Return all experimenters apart from current user. 292 293 @return: Generator yielding experimetners list 294 @rtype: L{ExperimenterWrapper} generator 295 296 """ 297 298 q = self.getQueryService() 299 p = omero.sys.Parameters() 300 p.map = {} 301 p.map["id"] = rlong(self.getEventContext().userId) 302 sql = "select e from Experimenter as e where e.id != :id " 303 for e in q.findAllByQuery(sql, p): 304 yield ExperimenterWrapper(self, e)
305 306 #def getCurrentSupervisor(self): 307 # """ 308 # Gets the owner of a group for current user. 309 # 310 # @return: ExperimenterWrapper 311 # """ 312 # 313 # p = omero.sys.ParametersI() 314 # p.map = {} 315 # p.map["id"] = rlong(self.getEventContext().groupId) 316 317 # # TODO: there can now be multiple supervisors 318 # p.page(0,1) 319 # supervisor = self.getQueryService().findByQuery(\ 320 # """select e from ExperimenterGroup as g 321 # join g.groupExperimenterMap as m join m.child as e 322 # where m.owner = true and g.id = :id""", p) 323 # return ExperimenterWrapper(self, supervisor) 324 325 #def getScriptwithDetails(self, sid): 326 # script_serv = self.getScriptService() 327 # return script_serv.getScriptWithDetails(long(sid)) 328 329 #def lookupScripts(self): 330 # script_serv = self.getScriptService() 331 # return script_serv.getScripts() 332
333 - def getServerVersion(self):
334 """ 335 Retrieves a configuration value "omero.version" from the backend store. 336 337 @return: String 338 """ 339 340 conf = self.getConfigService() 341 return conf.getConfigValue("omero.version")
342 343 344 ######################################################### 345 ## From Bram b(dot)gerritsen(at)nki(dot)nl ## 346
347 - def findWellInPlate (self, plate_name, row, column):
348 q = self.getQueryService() 349 p = omero.sys.Parameters() 350 p.map = {} 351 p.map['pname'] = rstring(str(plate_name)) 352 p.map['row'] = rint(int(row)) 353 p.map['column'] = rint(int(column)) 354 355 sql = """select well from Well as well 356 left outer join fetch well.plate as pt 357 left outer join fetch well.wellSamples as ws 358 inner join fetch ws.image as img 359 where well.plate.name = :pname and well.row = :row 360 and well.column = :column""" 361 well = q.findByQuery(sql, p) 362 if well is None: 363 return None 364 else: 365 return WellWrapper(self, well, None)
366 367 368 #################################################################################### 369 ## Container Queries ### 370 #################################################################################### 371
372 - def listTags(self, eid=None):
373 params = omero.sys.ParametersI() 374 params.orphan() 375 params.map = {} 376 params.map['ns'] = rstring(omero.constants.metadata.NSINSIGHTTAGSET) 377 378 sql = "select tg from TagAnnotation tg where ((ns=:ns) or (ns is null and not exists ( select aal from AnnotationAnnotationLink as aal where aal.child=tg.id))) " 379 if eid is not None: 380 params.map["eid"] = rlong(long(eid)) 381 sql+=" and tg.details.owner.id = :eid" 382 383 q = self.getQueryService() 384 for ann in q.findAllByQuery(sql, params): 385 yield TagAnnotationWrapper(self, ann)
386
387 - def countOrphans (self, obj_type, eid=None):
388 links = {'Dataset':('ProjectDatasetLink', DatasetWrapper), 389 'Image':('DatasetImageLink', ImageWrapper), 390 'Plate':('ScreenPlateLink', PlateWrapper)} 391 392 if obj_type not in links: 393 raise TypeError("'%s' is not valid object type. Must use one of %s" % (obj_type, links.keys()) ) 394 395 q = self.getQueryService() 396 p = omero.sys.Parameters() 397 p.map = {} 398 399 links = {'Dataset':('ProjectDatasetLink', DatasetWrapper), 400 'Image':('DatasetImageLink', ImageWrapper), 401 'Plate':('ScreenPlateLink', PlateWrapper)} 402 403 if obj_type not in links: 404 raise TypeError("'%s' is not valid object type. Must use one of %s" % (obj_type, links.keys()) ) 405 406 q = self.getQueryService() 407 p = omero.sys.Parameters() 408 p.map = {} 409 410 if eid is not None: 411 p.map["eid"] = rlong(long(eid)) 412 eidFilter = "obj.details.owner.id=:eid and " 413 eidWsFilter = " and ws.details.owner.id=:eid" 414 else: 415 eidFilter = "" 416 eidWsFilter = "" 417 418 sql = "select count(obj.id) from %s as obj " \ 419 "join obj.details.creationEvent "\ 420 "join obj.details.owner join obj.details.group " \ 421 "where %s" \ 422 "not exists (select obl from %s as obl where " \ 423 "obl.child=obj.id)" % (obj_type, eidFilter, links[obj_type][0]) 424 if obj_type == 'Image': 425 sql += "and not exists ( "\ 426 "select ws from WellSample as ws "\ 427 "where ws.image=obj.id %s)" % eidWsFilter 428 429 rslt = q.projection(sql, p) 430 if len(rslt) > 0: 431 if len(rslt[0]) > 0: 432 return rslt[0][0].val 433 return 0
434 435
436 - def listOrphans (self, obj_type, eid=None, page=None):
437 """ 438 List orphaned Datasets, Images, Plates controlled by the security system, 439 Optionally filter by experimenter 'eid' 440 441 @param obj_type: 'Dataset', 'Image', 'Plate' 442 @param eid: experimenter id 443 @type eid: Long 444 @param page: page number 445 @type page: Long 446 @return: Generator yielding Datasets 447 @rtype: L{DatasetWrapper} generator 448 """ 449 450 links = {'Dataset':('ProjectDatasetLink', DatasetWrapper), 451 'Image':('DatasetImageLink', ImageWrapper), 452 'Plate':('ScreenPlateLink', PlateWrapper)} 453 454 if obj_type not in links: 455 raise TypeError("'%s' is not valid object type. Must use one of %s" % (obj_type, links.keys()) ) 456 457 q = self.getQueryService() 458 p = omero.sys.Parameters() 459 p.map = {} 460 461 if eid is not None: 462 p.map["eid"] = rlong(long(eid)) 463 eidFilter = "obj.details.owner.id=:eid and " 464 eidWsFilter = " and ws.details.owner.id=:eid" 465 else: 466 eidFilter = "" 467 eidWsFilter = "" 468 469 if page is not None: 470 f = omero.sys.Filter() 471 f.limit = rint(PAGE) 472 f.offset = rint((int(page)-1)*PAGE) 473 p.theFilter = f 474 475 sql = "select obj from %s as obj " \ 476 "join fetch obj.details.creationEvent "\ 477 "join fetch obj.details.owner join fetch obj.details.group " % (obj_type) 478 479 sql += "where %s" \ 480 "not exists (select obl from %s as obl where " \ 481 "obl.child=obj.id)" % (eidFilter, links[obj_type][0]) 482 483 if obj_type == 'Image': 484 sql += "and not exists ( "\ 485 "select ws from WellSample as ws "\ 486 "where ws.image=obj.id %s)" % eidWsFilter 487 for e in q.findAllByQuery(sql, p): 488 yield links[obj_type][1](self, e)
489
490 - def listImagesInDataset (self, oid, eid=None, page=None):
491 """ 492 List Images in the given Dataset. 493 Optinally filter by experimenter 'eid' 494 495 @param eid: experimenter id 496 @type eid: Long 497 @param page: page number 498 @type page: Long 499 @return: Generator yielding Images 500 @rtype: L{ImageWrapper} generator 501 """ 502 503 q = self.getQueryService() 504 p = omero.sys.Parameters() 505 p.map = {} 506 p.map["oid"] = rlong(long(oid)) 507 if page is not None: 508 f = omero.sys.Filter() 509 f.limit = rint(PAGE) 510 f.offset = rint((int(page)-1)*PAGE) 511 p.theFilter = f 512 sql = "select im from Image im "\ 513 "join fetch im.details.creationEvent "\ 514 "join fetch im.details.owner join fetch im.details.group " \ 515 "left outer join fetch im.datasetLinks dil "\ 516 "left outer join fetch dil.parent d " \ 517 "where d.id = :oid" 518 if eid is not None: 519 p.map["eid"] = rlong(long(eid)) 520 sql += " and im.details.owner.id=:eid" 521 sql+=" order by im.name ASC" 522 523 for e in q.findAllByQuery(sql, p): 524 kwargs = {'link': omero.gateway.BlitzObjectWrapper(self, e.copyDatasetLinks()[0])} 525 yield ImageWrapper(self, e, None, **kwargs)
526 527 # DATA RETRIVAL BY TAGs
528 - def findTag (self, name, desc=None):
529 """ 530 Retrieves Tag by given Name and description 531 532 @param name name of tag 533 @type name String 534 @param desc description of tag 535 @type desc String 536 @return: TagAnnotation 537 @rtype: AnnotationWrapper 538 """ 539 """TODO: #1015 540 It does not support SPW""" 541 542 query_serv = self.getQueryService() 543 res = list() 544 p = omero.sys.Parameters() 545 p.map = {} 546 p.map["text"] = rstring(str(name)) 547 if desc is not None: 548 p.map["desc"] = rstring(str(desc)) 549 #p.map["eid"] = rlong(self.getEventContext().userId) 550 f = omero.sys.Filter() 551 f.limit = rint(1) 552 p.theFilter = f 553 sql = "select tg from TagAnnotation tg " \ 554 "where tg.textValue=:text" 555 if desc is not None: 556 sql+= " and tg.description=:desc" 557 sql+=" and tg.ns is null order by tg.textValue" 558 res = query_serv.findAllByQuery(sql, p) 559 if len(res) > 0: 560 return TagAnnotationWrapper(self, res[0]) 561 return None
562 563 # AVATAR #
564 - def uploadMyUserPhoto(self, filename, format, data):
565 """ 566 Uploads a photo for the user which will be displayed on his/her profile. 567 This photo will be saved as an OriginalFile object 568 with the given format, and attached to the user's Experimenter 569 object via an File Annotation with 570 the namespace: "openmicroscopy.org/omero/experimenter/photo" (NSEXPERIMENTERPHOTO). 571 If such an OriginalFile instance already exists, 572 it will be overwritten. If more than one photo is present, the oldest 573 version will be modified (i.e. the highest updateEvent id). 574 575 Note: as outlined in ticket:1794, this photo will be placed in the "user" 576 group and therefore will be visible to everyone on the system. 577 578 @param filename name which will be used. 579 @type filename String 580 @param format Format.value string. 'image/jpeg' and 'image/png' are common values. 581 @type format String 582 @param data Data from the image. This will be written to disk. 583 @type data String 584 585 @return ID of the overwritten or newly created user photo OriginalFile object. 586 @rtype Long 587 """ 588 589 admin_serv = self.getAdminService() 590 pid = admin_serv.uploadMyUserPhoto(filename, format, data) 591 if pid is not None: 592 return pid
593
594 - def hasExperimenterPhoto(self, oid=None):
595 """ 596 Check if File annotation with the namespace: 597 "openmicroscopy.org/omero/experimenter/photo" (NSEXPERIMENTERPHOTO) is linked 598 to the given user ID. If user id not set, owned by the current user. 599 600 @param oid experimenter ID 601 @type oid Long 602 @return True or False 603 @rtype Boolean 604 """ 605 606 photo = None 607 meta = self.getMetadataService() 608 try: 609 if oid is None: 610 ann = meta.loadAnnotations("Experimenter", [self.getEventContext().userId], None, None, None).get(self.getEventContext().userId, [])[0] 611 else: 612 ann = meta.loadAnnotations("Experimenter", [long(oid)], None, None, None).get(long(oid), [])[0] 613 if ann is not None: 614 return True 615 else: 616 return False 617 except: 618 return False
619
620 - def getExperimenterPhoto(self, oid=None):
621 """ 622 Get File annotation with the namespace: 623 "openmicroscopy.org/omero/experimenter/photo" (NSEXPERIMENTERPHOTO) linked 624 to the given user ID. If user id not set, owned by the current user. 625 626 @param oid experimenter ID 627 @type oid Long 628 @return Data from the image. 629 @rtype String 630 """ 631 632 photo = None 633 meta = self.getMetadataService() 634 try: 635 if oid is None: 636 ann = meta.loadAnnotations("Experimenter", [self.getEventContext().userId], None, None, None).get(self.getEventContext().userId, []) 637 else: 638 ann = meta.loadAnnotations("Experimenter", [long(oid)], None, None, None).get(long(oid), []) 639 if len(ann) > 0: 640 ann = ann[0] 641 store = self.createRawFileStore() 642 store.setFileId(ann.file.id.val) 643 photo = store.read(0,long(ann.file.size.val)) 644 else: 645 photo = self.getExperimenterDefaultPhoto() 646 except: 647 logger.error(traceback.format_exc()) 648 photo = self.getExperimenterDefaultPhoto() 649 if photo == None: 650 photo = self.getExperimenterDefaultPhoto() 651 return photo
652
653 - def getExperimenterPhotoSize(self, oid=None):
654 """ 655 Get size of File annotation with the namespace: 656 "openmicroscopy.org/omero/experimenter/photo" (NSEXPERIMENTERPHOTO) linked 657 to the given user ID. If user id not set, owned by the current user. 658 659 @param oid experimenter ID 660 @type oid Long 661 @return Tuple including dimention and size of the file 662 @rtype Tuple 663 """ 664 665 photo = None 666 meta = self.getMetadataService() 667 try: 668 if oid is None: 669 ann = meta.loadAnnotations("Experimenter", [self.getEventContext().userId], None, None, None).get(self.getEventContext().userId, [])[0] 670 else: 671 ann = meta.loadAnnotations("Experimenter", [long(oid)], None, None, None).get(long(oid), [])[0] 672 store = self.createRawFileStore() 673 store.setFileId(ann.file.id.val) 674 photo = store.read(0,long(ann.file.size.val)) 675 try: 676 im = Image.open(StringIO(photo)) 677 except: 678 logger.error(traceback.format_exc()) 679 return None 680 else: 681 return (im.size, ann.file.size.val) 682 except: 683 return None
684
685 - def cropExperimenterPhoto(self, box, oid=None):
686 """ 687 Crop File annotation with the namespace: 688 "openmicroscopy.org/omero/experimenter/photo" (NSEXPERIMENTERPHOTO) linked 689 to the given user ID. If user id not set, owned by the current user. 690 New dimentions are defined by squer positions box = (x1,y1,x2,y2) 691 692 @param box tuple of new square positions 693 @type box Tuple 694 @param oid experimenter ID 695 @type oid Long 696 """ 697 # TODO: crop method could be moved to the server side 698 699 photo = None 700 meta = self.getMetadataService() 701 ann = None 702 try: 703 if oid is None: 704 ann = meta.loadAnnotations("Experimenter", [self.getEventContext().userId], None, None, None).get(self.getEventContext().userId, [])[0] 705 else: 706 ann = meta.loadAnnotations("Experimenter", [long(oid)], None, None, None).get(long(oid), [])[0] 707 store = self.createRawFileStore() 708 store.setFileId(ann.file.id.val) 709 photo = store.read(0,long(ann.file.size.val)) 710 except: 711 logger.error(traceback.format_exc()) 712 raise IOError("Photo does not exist.") 713 else: 714 region = None 715 try: 716 im = Image.open(StringIO(photo)) 717 region = im.crop(box) 718 except IOError: 719 logger.error(traceback.format_exc()) 720 raise IOError("Cannot open that photo.") 721 else: 722 imdata=StringIO() 723 region.save(imdata, format=im.format) 724 self.uploadMyUserPhoto(ann.file.name.val, ann.file.mimetype.val, imdata.getvalue())
725
726 - def getExperimenterDefaultPhoto(self):
727 """ 728 If file annotation with the namespace: 729 "openmicroscopy.org/omero/experimenter/photo" (NSEXPERIMENTERPHOTO) 730 is not linked to experimenter this method generate default picture of the person. 731 732 @return Data from the image. 733 @rtype String 734 """ 735 736 img = Image.open(settings.DEFAULT_USER) 737 img.thumbnail((32,32), Image.ANTIALIAS) 738 draw = ImageDraw.Draw(img) 739 f = cStringIO.StringIO() 740 img.save(f, "PNG") 741 f.seek(0) 742 return f.read()
743
744 - def getFileFormat(self, format):
745 """ 746 Get file annotation format for the given value. 747 748 @return Omero File format 749 @rtype String 750 """ 751 query_serv = self.getQueryService() 752 return query_serv.findByString("Format", "value", format).getValue().val;
753 754 ################################################ 755 ## Counters 756
757 - def getCollectionCount(self, parent, child, ids):
758 """ 759 Counts the number of members in a collection for a given object. 760 761 @param parent The fully-qualified classname of the object to be tested 762 @type parent String 763 @param child Name of the property on that class, omitting getters and setters. 764 @type child String 765 @param ids Set of Longs, the ids of the objects to test 766 @type ids L{Long} 767 @return A map from id integer to count integer 768 @rtype L{(Long, Long)} 769 """ 770 container = self.getContainerService() 771 return container.getCollectionCount(parent, child, ids, None)
772 773 ################################################ 774 ## Validators 775
776 - def checkOmeName(self, ome_name, old_omeName=None):
777 if ome_name == old_omeName: 778 return False 779 query_serv = self.getQueryService() 780 p = omero.sys.Parameters() 781 p.map = {} 782 p.map["omeName"] = rstring(smart_str(ome_name)) 783 sql = "select e from Experimenter as e where e.omeName = (:omeName)" 784 exps = query_serv.findAllByQuery(sql, p) 785 if len(exps) > 0: 786 return True 787 else: 788 return False
789
790 - def checkGroupName(self, name, old_name=None):
791 if name == old_name: 792 return False 793 query_serv = self.getQueryService() 794 p = omero.sys.Parameters() 795 p.map = {} 796 p.map["name"] = rstring(smart_str(name)) 797 sql = "select g from ExperimenterGroup as g where g.name = (:name)" 798 grs = query_serv.findAllByQuery(sql, p) 799 if len(grs) > 0: 800 return True 801 else: 802 return False
803
804 - def checkEmail(self, email, old_email=None):
805 if email == "": 806 return False 807 if email == old_email: 808 return False 809 query_serv = self.getQueryService() 810 p = omero.sys.Parameters() 811 p.map = {} 812 p.map["email"] = rstring(smart_str(email)) 813 sql = "select e from Experimenter as e where e.email = (:email)" 814 exps = query_serv.findAllByQuery(sql, p) 815 if len(exps) > 0: 816 return True 817 else: 818 return False
819
820 - def defaultThumbnail(self, size=(120,120)):
821 if isinstance(size, int): 822 size = (size,size) 823 if len(size) == 1: 824 size = (size[0],size[0]) 825 img = Image.open(settings.DEFAULT_IMG) 826 img.thumbnail(size, Image.ANTIALIAS) 827 draw = ImageDraw.Draw(img) 828 f = cStringIO.StringIO() 829 img.save(f, "PNG") 830 f.seek(0) 831 return f.read()
832 833 ############################################## 834 ## Sets methods ## 835
836 - def changeUserPassword(self, omeName, password, my_password):
837 """ 838 Change the password for the a given user. 839 840 @param omeName Experimetner omename 841 @type omeName String 842 @param password Must pass validation in the security sub-system. 843 @type password String 844 @param my_password Must pass validation in the security sub-system. 845 @type my_password String 846 """ 847 admin_serv = self.getAdminService() 848 self.c.sf.setSecurityPassword(my_password) 849 admin_serv.changeUserPassword(omeName, rstring(str(password)))
850
851 - def changeMyPassword(self, password, old_password):
852 """ 853 Change the password for the current user by passing the old password. 854 855 @param password Must pass validation in the security sub-system. 856 @type password String 857 @param old_password Old password 858 @type old_password String 859 @return None or error message if password could not be changed 860 @rtype String 861 """ 862 admin_serv = self.getAdminService() 863 admin_serv.changePasswordWithOldPassword(rstring(str(old_password)), rstring(str(password)))
864
865 - def createExperimenter(self, experimenter, defaultGroup, otherGroups, password):
866 """ 867 Create and return a new user in the given groups with password. 868 869 @param experimenter A new Experimenter instance. 870 @type experimenter ExperimenterI 871 @param defaultGroup Instance of ExperimenterGroup selected as a first active group. 872 @type defaultGroup ExperimenterGroupI 873 @param otherGroups List of ExperimenterGroup instances. Can be empty. 874 @type otherGroups L{ExperimenterGroupI} 875 @param password Must pass validation in the security sub-system. 876 @type password String 877 @return ID of the newly created Experimenter Not null. 878 @rtype Long 879 """ 880 admin_serv = self.getAdminService() 881 return admin_serv.createExperimenterWithPassword(experimenter, rstring(str(password)), defaultGroup, otherGroups)
882
883 - def updateExperimenter(self, experimenter, defaultGroup, addGroups, rmGroups):
884 """ 885 Update an existing user including groups user is a member of. 886 Password cannot be changed by calling that method. 887 888 @param experimenter An existing Experimenter instance. 889 @type experimenter ExperimenterI 890 @param defaultGroup Instance of ExperimenterGroup selected as a new active group. 891 @type defaultGroup ExperimenterGroupI 892 @param addGroups List of new ExperimenterGroup instances user will be a member of. Can be empty. 893 @type addGroups L{ExperimenterGroupI} 894 @param rmGroups List of old ExperimenterGroup instances user no longer be a member of. Can be empty. 895 @type rmGroups L{ExperimenterGroupI} 896 """ 897 898 admin_serv = self.getAdminService() 899 admin_serv.updateExperimenter(experimenter) 900 if len(addGroups) > 0: 901 admin_serv.addGroups(experimenter, addGroups) 902 admin_serv.setDefaultGroup(experimenter, defaultGroup) 903 if len(rmGroups) > 0: 904 admin_serv.removeGroups(experimenter, rmGroups)
905
906 - def setMembersOfGroup(self, group, add_exps, rm_exps):
907 """ 908 Change members of the group. 909 910 @param group An existing ExperimenterGroup instance. 911 @type group ExperimenterGroupI 912 @param add_exps List of new Experimenters instances. Can be empty. 913 @type add_exps L{ExperimenterI} 914 @param rm_exps List of old Experimenters instances no longer be a member of that group. Can be empty. 915 @type rm_exps L{ExperimenterI} 916 """ 917 918 admin_serv = self.getAdminService() 919 for e in add_exps: 920 admin_serv.addGroups(e, [group]) 921 for e in rm_exps: 922 admin_serv.removeGroups(e, [group])
923 924 #def deleteExperimenter(self, experimenter): 925 # """ 926 # Removes a user by removing the password information for that user as well 927 # as all GroupExperimenterMap instances. 928 # 929 # @param user Experimenter to be deleted. Not null. 930 # @type user ExperimenterI 931 # """ 932 # admin_serv = self.getAdminService() 933 # admin_serv.deleteExperimenter(experimenter) 934
935 - def createGroup(self, group, group_owners):
936 """ 937 Create and return a new group with the given owners. 938 939 @param group A new ExperimenterGroup instance. 940 @type group ExperimenterGroupI 941 @param group_owners List of Experimenter instances. Can be empty. 942 @type group_owners L{ExperimenterI} 943 @return ID of the newly created ExperimenterGroup Not null. 944 @rtype Long 945 """ 946 947 admin_serv = self.getAdminService() 948 gr_id = admin_serv.createGroup(group) 949 new_gr = admin_serv.getGroup(gr_id) 950 admin_serv.addGroupOwners(new_gr, group_owners) 951 return gr_id
952
953 - def updateGroup(self, group, add_exps, rm_exps, perm=None):
954 """ 955 Update an existing user including groups user is a member of. 956 Password cannot be changed by calling that method. 957 958 @param group An existing ExperimenterGroup instance. 959 @type group ExperimenterGroupI 960 @param add_exps List of new Experimenter instances. Can be empty. 961 @type add_exps L{ExperimenterI} 962 @param rm_exps List of old Experimenter instances who no longer will be a member of. Can be empty. 963 @type rm_exps L{ExperimenterI} 964 @param perm Permissions set on the given group 965 @type perm PermissionsI 966 """ 967 968 admin_serv = self.getAdminService() 969 # Should we update updateGroup so this would be atomic? 970 admin_serv.updateGroup(group) 971 if perm is not None: 972 logger.warning("WARNING: changePermissions was called!!!") 973 admin_serv.changePermissions(group, perm) 974 self._user = self.getObject("Experimenter", self._userid) 975 admin_serv.addGroupOwners(group, add_exps) 976 admin_serv.removeGroupOwners(group, rm_exps)
977
978 - def updateMyAccount(self, experimenter, defultGroup):
979 """ 980 Allows a user to update his/her own information and set the default group for a given user. 981 @param experimenter A data transfer object. Only the fields: firstName, middleName, 982 lastName, email, and institution are checked. Not null. 983 @type experimenter ExperimenterI 984 @param defultGroup The group which should be set as default group for this user. Not null 985 @type defultGroup ExperimenterGroupI 986 """ 987 admin_serv = self.getAdminService() 988 admin_serv.updateSelf(experimenter) 989 admin_serv.setDefaultGroup(experimenter, defultGroup) 990 self.changeActiveGroup(defultGroup.id.val) 991 self._user = self.getObject("Experimenter", self._userid)
992
993 - def updatePermissions(self, obj, perm):
994 """ 995 Allow to change the permission on the object. 996 997 @param obj An entity or an unloaded reference to an entity. Not null. 998 @type obj ObjectI 999 @param perm The permissions value for this entity. Not null. 1000 @type perm PermissionsI 1001 """ 1002 admin_serv = self.getAdminService() 1003 if perm is not None: 1004 logger.warning("WARNING: changePermissions was called!!!") 1005 admin_serv.changePermissions(obj, perm) 1006 self._user = self.getObject("Experimenter", self._userid)
1007
1008 - def saveObject (self, obj):
1009 """ 1010 Provide method for directly updating object graphs. Act recursively on 1011 the entire object graph, replacing placeholders and details where necessary, 1012 and then "merging" the final graph. This means that the objects that are 1013 passed into methods are copied over to new instances which are then returned. 1014 The original objects should be discarded. 1015 1016 @param obj An entity or an unloaded reference to an entity. Not null. 1017 @type obj ObjectI 1018 """ 1019 u = self.getUpdateService() 1020 u.saveObject(obj)
1021
1022 - def saveArray (self, objs):
1023 """ 1024 Provide method for directly updating list of object graphs. Act recursively on 1025 the entire object graph, replacing placeholders and details where necessary, 1026 and then "merging" the final graph. This means that the objects that are 1027 passed into methods are copied over to new instances which are then returned. 1028 The original objects should be discarded. 1029 1030 @param obj List of entities or an unloaded references to an entity. Not null. 1031 @type obj L{ObjectI} 1032 """ 1033 u = self.getUpdateService() 1034 u.saveArray(objs)
1035
1036 - def saveAndReturnObject (self, obj):
1037 """ 1038 Provide method for directly updating object graphs and return it. Act recursively on 1039 the entire object graph, replacing placeholders and details where necessary, 1040 and then "merging" the final graph. This means that the objects that are 1041 passed into methods are copied over to new instances which are then returned. 1042 The original objects should be discarded. 1043 1044 @param obj An entity or an unloaded reference to an entity. Not null. 1045 @type obj ObjectI 1046 @return Saved object 1047 @rtype ObjectI 1048 """ 1049 u = self.getUpdateService() 1050 res = u.saveAndReturnObject(obj) 1051 res.unload() 1052 obj = omero.gateway.BlitzObjectWrapper(self, res) 1053 return obj
1054
1055 - def saveAndReturnId (self, obj):
1056 """ 1057 Provide method for directly updating object graphs and return ID. Act recursively on 1058 the entire object graph, replacing placeholders and details where necessary, 1059 and then "merging" the final graph. This means that the objects that are 1060 passed into methods are copied over to new instances which are then returned. 1061 The original objects should be discarded. 1062 1063 @param obj An entity or an unloaded reference to an entity. Not null. 1064 @type obj ObjectI 1065 @return ID of saved object 1066 @rtype Long 1067 """ 1068 u = self.getUpdateService() 1069 res = u.saveAndReturnObject(obj) 1070 res.unload() 1071 return res.id.val
1072
1073 - def saveAndReturnFile(self, binary, oFile_id):
1074 """ 1075 Provide method for directly updating a file object and return binary. 1076 1077 @param binary Binary. Not null. 1078 @type binary String 1079 @param oFile_id File Id in order to manage the state of the service. Not null. 1080 @type oFile_id Long 1081 @return Shallow copy of file. 1082 """ 1083 1084 store = self.createRawFileStore() 1085 store.setFileId(oFile_id); 1086 pos = 0 1087 rlen = 0 1088 1089 for chunk in binary.chunks(): 1090 rlen = len(chunk) 1091 store.write(chunk, pos, rlen) 1092 pos = pos + rlen 1093 return store.save()
1094 1095 ############################################## 1096 ## IShare 1097
1098 - def getShare (self, oid):
1099 """ 1100 Gets share for the given share id. 1101 1102 @param oid: Share ID. 1103 @type oid: Long 1104 @return: ShareWrapper or None 1105 @rtype: L{ShareWrapper} 1106 """ 1107 1108 sh_serv = self.getShareService() 1109 sh = sh_serv.getShare(long(oid)) 1110 if sh is not None: 1111 return ShareWrapper(self, sh) 1112 else: 1113 return None
1114
1115 - def getOwnShares(self):
1116 """ 1117 Gets all owned shares for the current user. 1118 1119 @return: Shares that user owns 1120 @rtype: L{ShareWrapper} generator 1121 """ 1122 1123 sh = self.getShareService() 1124 for e in sh.getOwnShares(False): 1125 yield ShareWrapper(self, e)
1126
1127 - def getMemberShares(self):
1128 """ 1129 Gets all shares where current user is a member. 1130 1131 @return: Shares that user is a member of 1132 @rtype: L{ShareWrapper} generator 1133 """ 1134 1135 sh = self.getShareService() 1136 for e in sh.getMemberShares(False): 1137 yield ShareWrapper(self, e)
1138
1139 - def getMemberCount(self, share_ids):
1140 """ 1141 Returns a map from share id to the count of total members (including the 1142 owner). This is represented by ome.model.meta.ShareMember links. 1143 1144 @param share_ids: List of IDs 1145 @type share_ids: List of Longs 1146 @return: Dict of shareId: member-count 1147 @rtype: Dict of long: long 1148 """ 1149 1150 sh = self.getShareService() 1151 return sh.getMemberCount(share_ids)
1152
1153 - def getCommentCount(self, share_ids):
1154 """ 1155 Returns a map from share id to comment count. 1156 1157 @param share_ids: List of IDs 1158 @type share_ids: List of Longs 1159 @return: Dict of shareId: comment-count 1160 @rtype: Dict of long: long 1161 """ 1162 1163 sh = self.getShareService() 1164 return sh.getCommentCount(share_ids)
1165
1166 - def getContents(self, share_id):
1167 """ 1168 Looks up all items belonging to the share, wrapped in object wrapper 1169 1170 @param share_id: share ID 1171 @type share_id: Long 1172 @return: Share contents 1173 @rtype: L{omero.gateway.BlitzObjectWrapper} generator 1174 """ 1175 1176 sh = self.getShareService() 1177 for e in sh.getContents(long(share_id)): 1178 try: 1179 obj = omero.gateway.BlitzObjectWrapper(self, e) 1180 except: 1181 obj = omero.gateway.BlitzObjectWrapper(self,None) 1182 obj._obj = e 1183 yield obj
1184
1185 - def getComments(self, share_id):
1186 """ 1187 Looks up all comments which belong to the share, wrapped in object wrapper 1188 1189 @param share_id: share ID 1190 @type share_id: Long 1191 @return: Share comments 1192 @rtype: L{AnnotationWrapper} generator 1193 """ 1194 1195 sh = self.getShareService() 1196 for e in sh.getComments(long(share_id)): 1197 yield AnnotationWrapper(self, e)
1198
1199 - def getAllMembers(self, share_id):
1200 """ 1201 Get all {@link Experimenter users} who are a member of the share. 1202 1203 @param share_id: share ID 1204 @type share_id: Long 1205 @return: Members of share 1206 @rtype: L{ExperimenterWrapper} generator 1207 """ 1208 1209 sh = self.getShareService() 1210 for e in sh.getAllMembers(long(share_id)): 1211 yield ExperimenterWrapper(self, e)
1212
1213 - def getAllGuests(self, share_id):
1214 """ 1215 Get the email addresses for all share guests. 1216 1217 @param share_id: share ID 1218 @type share_id: Long 1219 @return: List of e-mail addresses 1220 @rtype: List of Strings 1221 """ 1222 1223 sh = self.getShareService() 1224 return sh.getAllGuests(long(share_id))
1225
1226 - def getAllUsers(self, share_id):
1227 """ 1228 Get a single set containing the login names of the users as well email addresses for guests. 1229 1230 @param share_id: share ID 1231 @type share_id: Long 1232 @return: List of usernames and e-mail addresses 1233 @rtype: List of Strings 1234 """ 1235 1236 sh = self.getShareService() 1237 return sh.getAllUsers(long(share_id))
1238
1239 - def prepareRecipients(self, recipients):
1240 recps = list() 1241 for m in recipients: 1242 try: 1243 e = (m.email, m.email.val)[isinstance(m.email, omero.RString)] 1244 if e is not None and e!="": 1245 recps.append(e) 1246 except: 1247 logger.error(traceback.format_exc()) 1248 logger.info(recps) 1249 if len(recps) == 0: 1250 raise AttributeError("Recipients list is empty") 1251 return recps
1252
1253 - def addComment(self, host, blitz_id, share_id, comment):
1254 sh = self.getShareService() 1255 new_cm = sh.addComment(long(share_id), str(comment)) 1256 1257 members = list(self.getAllMembers(long(share_id))) 1258 sh = self.getShare(long(share_id)) 1259 if self.getEventContext().userId != sh.owner.id.val: 1260 members.append(sh.getOwner()) 1261 1262 if sh.active: 1263 try: 1264 for m in members: 1265 try: 1266 if m.id == self.getEventContext().userId: 1267 members.remove(m) 1268 except: 1269 logger.error(traceback.format_exc()) 1270 recipients = self.prepareRecipients(members) 1271 except Exception, x: 1272 logger.error(traceback.format_exc()) 1273 else: 1274 blitz = settings.SERVER_LIST.get(pk=blitz_id) 1275 t = settings.EMAIL_TEMPLATES["add_comment_to_share"] 1276 message = t['text_content'] % (settings.APPLICATION_HOST, blitz_id) 1277 message_html = t['html_content'] % (settings.APPLICATION_HOST, blitz_id, settings.APPLICATION_HOST, blitz_id) 1278 try: 1279 title = 'OMERO.web - new comment for share %i' % share_id 1280 text_content = message 1281 html_content = message_html 1282 msg = EmailMultiAlternatives(title, text_content, settings.SERVER_EMAIL, recipients) 1283 msg.attach_alternative(html_content, "text/html") 1284 msg.send() 1285 logger.error("Email was sent") 1286 except: 1287 logger.error(traceback.format_exc())
1288
1289 - def removeImage(self, share_id, image_id):
1290 sh = self.getShareService() 1291 img = self.getObject("Image", image_id) 1292 sh.removeObject(long(share_id), img._obj)
1293
1294 - def createShare(self, host, blitz_id, image, message, members, enable, expiration=None):
1295 sh = self.getShareService() 1296 q = self.getQueryService() 1297 1298 items = list() 1299 ms = list() 1300 p = omero.sys.Parameters() 1301 p.map = {} 1302 #images 1303 if len(image) > 0: 1304 p.map["ids"] = rlist([rlong(long(a)) for a in image]) 1305 sql = "select im from Image im join fetch im.details.owner join fetch im.details.group where im.id in (:ids) order by im.name" 1306 items.extend(q.findAllByQuery(sql, p)) 1307 1308 #members 1309 if members is not None: 1310 p.map["ids"] = rlist([rlong(long(a)) for a in members]) 1311 sql = "select e from Experimenter e " \ 1312 "where e.id in (:ids) order by e.omeName" 1313 ms = q.findAllByQuery(sql, p) 1314 sid = sh.createShare(message, rtime(expiration), items, ms, [], enable) 1315 sh.addObjects(sid, items) 1316 1317 #send email if avtive 1318 if enable: 1319 try: 1320 recipients = self.prepareRecipients(ms) 1321 except Exception, x: 1322 logger.error(traceback.format_exc()) 1323 else: 1324 t = settings.EMAIL_TEMPLATES["create_share"] 1325 message = t['text_content'] % (settings.APPLICATION_HOST, blitz_id, self.getUser().getFullName()) 1326 message_html = t['html_content'] % (settings.APPLICATION_HOST, blitz_id, settings.APPLICATION_HOST, blitz_id, self.getUser().getFullName()) 1327 1328 try: 1329 title = 'OMERO.web - new share %i' % sid 1330 text_content = message 1331 html_content = message_html 1332 msg = EmailMultiAlternatives(title, text_content, settings.SERVER_EMAIL, recipients) 1333 msg.attach_alternative(html_content, "text/html") 1334 msg.send() 1335 logger.error("Email was sent") 1336 except: 1337 logger.error(traceback.format_exc())
1338
1339 - def updateShareOrDiscussion (self, host, blitz_id, share_id, message, add_members, rm_members, enable, expiration=None):
1340 sh = self.getShareService() 1341 sh.setDescription(long(share_id), message) 1342 sh.setExpiration(long(share_id), rtime(expiration)) 1343 sh.setActive(long(share_id), enable) 1344 if len(add_members) > 0: 1345 sh.addUsers(long(share_id), add_members) 1346 if len(rm_members) > 0: 1347 sh.removeUsers(long(share_id), rm_members) 1348 1349 #send email if avtive 1350 if len(add_members) > 0: 1351 try: 1352 recipients = self.prepareRecipients(add_members) 1353 except Exception, x: 1354 logger.error(traceback.format_exc()) 1355 else: 1356 blitz = settings.SERVER_LIST.get(pk=blitz_id) 1357 t = settings.EMAIL_TEMPLATES["add_member_to_share"] 1358 message = t['text_content'] % (settings.APPLICATION_HOST, blitz_id, self.getUser().getFullName()) 1359 message_html = t['html_content'] % (settings.APPLICATION_HOST, blitz_id, settings.APPLICATION_HOST, blitz_id, self.getUser().getFullName()) 1360 try: 1361 title = 'OMERO.web - update share %i' % share_id 1362 text_content = message 1363 html_content = message_html 1364 msg = EmailMultiAlternatives(title, text_content, settings.SERVER_EMAIL, recipients) 1365 msg.attach_alternative(html_content, "text/html") 1366 msg.send() 1367 logger.error("Email was sent") 1368 except: 1369 logger.error(traceback.format_exc()) 1370 1371 if len(rm_members) > 0: 1372 try: 1373 recipients = self.prepareRecipients(rm_members) 1374 except Exception, x: 1375 logger.error(traceback.format_exc()) 1376 else: 1377 blitz = settings.SERVER_LIST.get(pk=blitz_id) 1378 t = settings.EMAIL_TEMPLATES["remove_member_from_share"] 1379 message = t['text_content'] % (settings.APPLICATION_HOST, blitz_id) 1380 message_html = t['html_content'] % (settings.APPLICATION_HOST, blitz_id, settings.APPLICATION_HOST, blitz_id) 1381 1382 try: 1383 title = 'OMERO.web - update share %i' % share_id 1384 text_content = message 1385 html_content = message_html 1386 msg = EmailMultiAlternatives(title, text_content, settings.SERVER_EMAIL, recipients) 1387 msg.attach_alternative(html_content, "text/html") 1388 msg.send() 1389 logger.error("Email was sent") 1390 except: 1391 logger.error(traceback.format_exc())
1392 1393 1394 ############################################## 1395 ## History methods ## 1396 1397 #def getLastAcquiredImages (self): 1398 # tm = self.getTimelineService() 1399 # p = omero.sys.Parameters() 1400 # p.map = {} 1401 # f = omero.sys.Filter() 1402 # f.ownerId = rlong(self.getEventContext().userId) 1403 # f.groupId = rlong(self.getEventContext().groupId) 1404 # f.limit = rint(6) 1405 # p.theFilter = f 1406 # for e in tm.getMostRecentObjects(['Image'], p, False)["Image"]: 1407 # yield ImageWrapper(self, e) 1408
1409 - def listLastImportedImages (self):
1410 """ 1411 Retrieve most recent imported images 1412 controlled by the security system. 1413 1414 @return: Generator yielding Images 1415 @rtype: L{ImageWrapper} generator 1416 """ 1417 1418 tm = self.getTimelineService() 1419 p = omero.sys.Parameters() 1420 p.map = {} 1421 f = omero.sys.Filter() 1422 f.ownerId = rlong(self.getEventContext().userId) 1423 f.groupId = rlong(self.getEventContext().groupId) 1424 f.limit = rint(10) 1425 p.theFilter = f 1426 for e in tm.getMostRecentObjects(['Image'], p, False)["Image"]: 1427 yield ImageWrapper(self, e)
1428
1429 - def listMostRecentShares (self):
1430 """ 1431 Retrieve most recent shares 1432 controlled by the security system. 1433 1434 @return: Generator yielding SessionAnnotationLink 1435 @rtype: L{ShareWrapper} generator 1436 """ 1437 1438 tm = self.getTimelineService() 1439 p = omero.sys.Parameters() 1440 p.map = {} 1441 f = omero.sys.Filter() 1442 f.ownerId = rlong(self.getEventContext().userId) 1443 f.limit = rint(10) 1444 p.theFilter = f 1445 for e in tm.getMostRecentShareCommentLinks(p): 1446 yield ShareWrapper(self, e.parent)
1447
1448 - def listMostRecentShareComments (self):
1449 """ 1450 Retrieve most recent share comments 1451 controlled by the security system. 1452 1453 @return: Generator yielding SessionAnnotationLink 1454 @rtype: L{SessionCommentWrapper} generator 1455 """ 1456 1457 tm = self.getTimelineService() 1458 p = omero.sys.Parameters() 1459 p.map = {} 1460 f = omero.sys.Filter() 1461 f.ownerId = rlong(self.getEventContext().userId) 1462 f.limit = rint(10) 1463 p.theFilter = f 1464 for e in tm.getMostRecentShareCommentLinks(p): 1465 yield AnnotationWrapper(self, e.child, link=ShareWrapper(self, e.parent))
1466
1467 - def listMostRecentComments (self):
1468 """ 1469 Retrieve most recent comment annotations 1470 controlled by the security system. 1471 1472 @return: Generator yielding BlitzObjectWrapper 1473 @rtype: L{BlitzObjectWrapper} generator 1474 """ 1475 1476 tm = self.getTimelineService() 1477 p = omero.sys.Parameters() 1478 p.map = {} 1479 f = omero.sys.Filter() 1480 f.ownerId = rlong(self.getEventContext().userId) 1481 f.groupId = rlong(self.getEventContext().groupId) 1482 f.limit = rint(10) 1483 p.theFilter = f 1484 for e in tm.getMostRecentAnnotationLinks(None, ['CommentAnnotation'], None, p): 1485 yield omero.gateway.BlitzObjectWrapper(self, e)
1486
1487 - def listMostRecentTags (self):
1488 """ 1489 Retrieve most recent tag annotations 1490 controlled by the security system. 1491 1492 @return: Generator yielding BlitzObjectWrapper 1493 @rtype: L{BlitzObjectWrapper} generator 1494 """ 1495 1496 tm = self.getTimelineService() 1497 p = omero.sys.Parameters() 1498 p.map = {} 1499 f = omero.sys.Filter() 1500 #f.ownerId = rlong(self.getEventContext().userId) 1501 f.groupId = rlong(self.getEventContext().groupId) 1502 f.limit = rint(200) 1503 p.theFilter = f 1504 for e in tm.getMostRecentAnnotationLinks(None, ['TagAnnotation'], None, p): 1505 yield omero.gateway.BlitzObjectWrapper(self, e.child)
1506
1507 - def getDataByPeriod (self, start, end, eid, otype=None, page=None):
1508 """ 1509 Retrieve given data objects by the given period of time 1510 controlled by the security system. 1511 1512 @param start Starting data 1513 @type start Long 1514 @param end Finishing data 1515 @type end Long 1516 @param otype Data type: Project, Dataset, Image 1517 @type otype String 1518 @return: Map of project, dataset and image lists 1519 @rtype: Map 1520 """ 1521 tm = self.getTimelineService() 1522 p = omero.sys.Parameters() 1523 p.map = {} 1524 f = omero.sys.Filter() 1525 f.ownerId = rlong(eid) 1526 f.groupId = rlong(self.getEventContext().groupId) 1527 if page is not None: 1528 f.limit = rint(PAGE) 1529 f.offset = rint((int(page)-1)*PAGE) 1530 else: 1531 f.limit = rint(100) 1532 p.theFilter = f 1533 im_list = list() 1534 ds_list = list() 1535 pr_list = list() 1536 1537 if otype == 'image': 1538 try: 1539 for e in tm.getByPeriod(['Image'], rtime(long(start)), rtime(long(end)), p, True)['Image']: 1540 im_list.append(ImageWrapper(self, e)) 1541 except: 1542 pass 1543 elif otype == 'dataset': 1544 try: 1545 for e in tm.getByPeriod(['Dataset'], rtime(long(start)), rtime(long(end)), p, True)['Dataset']: 1546 ds_list.append(DatasetWrapper(self, e)) 1547 except: 1548 pass 1549 elif otype == 'project': 1550 try: 1551 for e in tm.getByPeriod(['Project'], rtime(long(start)), rtime(long(end)), p, True)['Project']: 1552 pr_list.append(ImageWrapper(self, e)) 1553 except: 1554 pass 1555 else: 1556 res = tm.getByPeriod(['Image', 'Dataset', 'Project'], rtime(long(start)), rtime(long(end)), p, True) 1557 try: 1558 for e in res['Image']: 1559 im_list.append(ImageWrapper(self, e)) 1560 except: 1561 pass 1562 try: 1563 for e in res['Dataset']: 1564 ds_list.append(DatasetWrapper(self, e)) 1565 except: 1566 pass 1567 try: 1568 for e in res['Project']: 1569 pr_list.append(ProjectWrapper(self, e)) 1570 except: 1571 pass 1572 return {'project': pr_list, 'dataset':ds_list, 'image':im_list}
1573
1574 - def countDataByPeriod (self, start, end, eid, otype=None):
1575 """ 1576 Counts given data objects by the given period of time 1577 controlled by the security system. 1578 1579 @param start Starting data 1580 @type start Long 1581 @param end Finishing data 1582 @type end Long 1583 @param otype Data type: Project, Dataset, Image 1584 @type otype String 1585 @return: Counter 1586 @rtype: Long 1587 """ 1588 tm = self.getTimelineService() 1589 p = omero.sys.Parameters() 1590 p.map = {} 1591 f = omero.sys.Filter() 1592 f.ownerId = rlong(eid) 1593 f.groupId = rlong(self.getEventContext().groupId) 1594 p.theFilter = f 1595 if otype == 'image': 1596 return tm.countByPeriod(['Image'], rtime(long(start)), rtime(long(end)), p)['Image'] 1597 elif otype == 'dataset': 1598 return tm.countByPeriod(['Dataset'], rtime(long(start)), rtime(long(end)), p)['Dataset'] 1599 elif otype == 'project': 1600 return tm.countByPeriod(['Project'], rtime(long(start)), rtime(long(end)), p)['Project'] 1601 else: 1602 c = tm.countByPeriod(['Image', 'Dataset', 'Project'], rtime(long(start)), rtime(long(end)), p) 1603 return c['Image']+c['Dataset']+c['Project']
1604
1605 - def getEventsByPeriod (self, start, end, eid):
1606 """ 1607 Retrieve event log objects by the given period of time 1608 controlled by the security system. 1609 1610 @param start Starting data 1611 @type start Long 1612 @param end Finishing data 1613 @type end Long 1614 @return: List of event logs 1615 @rtype: List 1616 """ 1617 tm = self.getTimelineService() 1618 p = omero.sys.Parameters() 1619 p.map = {} 1620 f = omero.sys.Filter() 1621 f.limit = rint(100000) 1622 f.ownerId = rlong(eid) 1623 f.groupId = rlong(self.getEventContext().groupId) 1624 p.theFilter = f 1625 return tm.getEventLogsByPeriod(rtime(start), rtime(end), p)
1626 #yield EventLogWrapper(self, e) 1627 1628 omero.gateway.BlitzGateway = OmeroWebGateway 1629
1630 -class OmeroWebSafeCallWrapper(OmeroGatewaySafeCallWrapper): #pragma: no cover
1631 """ 1632 Function or method wrapper that handles L{Ice.ObjectNotExistException} 1633 by re-creating the server side proxy. 1634 """ 1635
1636 - def handle_exception(self, e, *args, **kwargs):
1637 if e.__class__ is Ice.ObjectNotExistException: 1638 # Restored proxy object re-creation logic from the pre-#5835 1639 # version of # _safeCallWrap() from omero.gateway. (See #6365) 1640 logger.warn('Attempting to re-create proxy and re-call method.') 1641 try: 1642 self.proxyObjectWrapper._obj = \ 1643 self.proxyObjectWrapper._create_func() 1644 func = getattr(self.proxyObjectWrapper._obj, self.attr) 1645 return func(*args, **kwargs) 1646 except Exception, e: 1647 self.debug(e.__class__.__name__, args, kwargs) 1648 raise 1649 else: 1650 super(OmeroWebSafeCallWrapper, self).handle_exception( 1651 e, *args, **kwargs)
1652 1653 1654 omero.gateway.SafeCallWrapper = OmeroWebSafeCallWrapper 1655
1656 -class OmeroWebObjectWrapper (object):
1657 1658 annotation_counter = None 1659
1660 - def countParents (self):
1661 l = self.listParents() 1662 if l is not None: 1663 return len(l)
1664
1665 - def countAnnotations (self):
1666 """ 1667 Count on annotations linked to the object and set the value 1668 on the custom fiels 'annotation_counter'. 1669 1670 @return Counter 1671 """ 1672 1673 if self.annotation_counter is not None: 1674 return self.annotation_counter 1675 else: 1676 container = self._conn.getContainerService() 1677 m = container.getCollectionCount(self._obj.__class__.__name__, type(self._obj).ANNOTATIONLINKS, [self._oid], None) 1678 if m[self._oid] > 0: 1679 self.annotation_counter = m[self._oid] 1680 return self.annotation_counter 1681 else: 1682 return None
1683
1684 - def warpName(self):
1685 """ 1686 Warp name of the object if names is longer then 30 characters. 1687 1688 @return Warped string. 1689 """ 1690 1691 try: 1692 l = len(self.name) 1693 if l < 30: 1694 return self.name 1695 elif l >= 30: 1696 splited = [] 1697 for v in range(0,len(self.name),30): 1698 splited.append(self.name[v:v+30]+"\n") 1699 return "".join(splited) 1700 except: 1701 logger.info(traceback.format_exc()) 1702 return self.name
1703
1704 -class ExperimenterWrapper (OmeroWebObjectWrapper, omero.gateway.ExperimenterWrapper):
1705 """ 1706 omero_model_ExperimenterI class wrapper overwrite omero.gateway.ExperimenterWrapper 1707 and extend OmeroWebObjectWrapper. 1708 """ 1709
1710 - def isEditable(self):
1711 return self.omeName.lower() not in ('guest')
1712 1713 omero.gateway.ExperimenterWrapper = ExperimenterWrapper 1714
1715 -class ExperimenterGroupWrapper (OmeroWebObjectWrapper, omero.gateway.ExperimenterGroupWrapper):
1716 """ 1717 omero_model_ExperimenterGroupI class wrapper overwrite omero.gateway.ExperimenterGroupWrapper 1718 and extend OmeroWebObjectWrapper. 1719 """ 1720
1721 - def isEditable(self):
1722 return self.name.lower() not in ('guest', 'user')
1723 1724 omero.gateway.ExperimenterGroupWrapper = ExperimenterGroupWrapper 1725
1726 -class ProjectWrapper (OmeroWebObjectWrapper, omero.gateway.ProjectWrapper):
1727 """ 1728 omero_model_ProjectI class wrapper overwrite omero.gateway.ProjectWrapper 1729 and extend OmeroWebObjectWrapper. 1730 """ 1731 1732 annotation_counter = None 1733
1734 - def __prepare__ (self, **kwargs):
1735 super(ProjectWrapper, self).__prepare__(**kwargs) 1736 if kwargs.has_key('annotation_counter'): 1737 self.annotation_counter = kwargs['annotation_counter']
1738 1739 omero.gateway.ProjectWrapper = ProjectWrapper 1740
1741 -class DatasetWrapper (OmeroWebObjectWrapper, omero.gateway.DatasetWrapper):
1742 """ 1743 omero_model_DatasetI class wrapper overwrite omero.gateway.DatasetWrapper 1744 and extends OmeroWebObjectWrapper. 1745 """ 1746 1747 annotation_counter = None 1748
1749 - def __prepare__ (self, **kwargs):
1750 super(DatasetWrapper, self).__prepare__(**kwargs) 1751 if kwargs.has_key('annotation_counter'): 1752 self.annotation_counter = kwargs['annotation_counter'] 1753 if kwargs.has_key('link'): 1754 self.link = kwargs.has_key('link') and kwargs['link'] or None
1755 1756 omero.gateway.DatasetWrapper = DatasetWrapper 1757
1758 -class ImageWrapper (OmeroWebObjectWrapper, omero.gateway.ImageWrapper):
1759 """ 1760 omero_model_ImageI class wrapper overwrite omero.gateway.ImageWrapper 1761 and extends OmeroWebObjectWrapper. 1762 """ 1763 1764 annotation_counter = None 1765
1766 - def __prepare__ (self, **kwargs):
1767 super(ImageWrapper, self).__prepare__(**kwargs) 1768 if kwargs.has_key('annotation_counter'): 1769 self.annotation_counter = kwargs['annotation_counter'] 1770 if kwargs.has_key('link'): 1771 self.link = kwargs.has_key('link') and kwargs['link'] or None
1772 1773 """ 1774 This override standard omero.gateway.ImageWrapper.getChannels 1775 and catch exceptions. 1776 """
1777 - def getChannels (self):
1778 try: 1779 return super(ImageWrapper, self).getChannels() 1780 except Exception, x: 1781 logger.error('Failed to load channels:', exc_info=True) 1782 return None
1783 1784 1785 omero.gateway.ImageWrapper = ImageWrapper 1786
1787 -class PlateWrapper (OmeroWebObjectWrapper, omero.gateway.PlateWrapper):
1788 1789 """ 1790 omero_model_PlateI class wrapper overwrite omero.gateway.PlateWrapper 1791 and extends OmeroWebObjectWrapper. 1792 """ 1793 1794 annotation_counter = None 1795
1796 - def __prepare__ (self, **kwargs):
1797 super(PlateWrapper, self).__prepare__(**kwargs) 1798 if kwargs.has_key('annotation_counter'): 1799 self.annotation_counter = kwargs['annotation_counter'] 1800 if kwargs.has_key('link'): 1801 self.link = kwargs.has_key('link') and kwargs['link'] or None
1802
1803 - def _loadPlateAcquisitions(self):
1804 p = omero.sys.Parameters() 1805 p.map = {} 1806 p.map["pid"] = self._obj.id 1807 sql = "select pa from PlateAcquisition as pa join fetch pa.plate as p where p.id=:pid" 1808 self._obj._plateAcquisitionsSeq = self._conn.getQueryService().findAllByQuery(sql, p) 1809 self._obj._plateAcquisitionsLoaded = True
1810
1811 - def countPlateAcquisitions(self):
1812 if self._obj.sizeOfPlateAcquisitions() < 0: 1813 self._loadPlateAcquisitions() 1814 return self._obj.sizeOfPlateAcquisitions()
1815
1816 - def listPlateAcquisitions(self):
1817 if not self._obj._plateAcquisitionsLoaded: 1818 self._loadPlateAcquisitions() 1819 for pa in self._obj.copyPlateAcquisitions(): 1820 yield PlateAcquisitionWrapper(self._conn, pa)
1821
1822 - def getFields (self, pid=None):
1823 """ 1824 Returns tuple of min and max of indexed collection of well samples 1825 per plate acquisition if exists 1826 """ 1827 1828 q = self._conn.getQueryService() 1829 sql = "select minIndex(ws), maxIndex(ws) from Well w " \ 1830 "join w.wellSamples ws where w.plate.id=:oid" 1831 1832 p = omero.sys.Parameters() 1833 p.map = {} 1834 p.map["oid"] = self._obj.id 1835 if pid is not None: 1836 sql += " and ws.plateAcquisition.id=:pid" 1837 p.map["pid"] = rlong(pid) 1838 1839 fields = None 1840 try: 1841 res = [r for r in unwrap(q.projection(sql, p))[0] if r != None] 1842 if len(res) == 2: 1843 fields = tuple(res) 1844 except: 1845 pass 1846 return fields
1847 1848 omero.gateway.PlateWrapper = PlateWrapper 1849
1850 -class WellWrapper (OmeroWebObjectWrapper, omero.gateway.WellWrapper):
1851 """ 1852 omero_model_ImageI class wrapper overwrite omero.gateway.ImageWrapper 1853 and extends OmeroWebObjectWrapper. 1854 """ 1855 1856 annotation_counter = None 1857
1858 - def __prepare__ (self, **kwargs):
1859 super(WellWrapper, self).__prepare__(**kwargs) 1860 if kwargs.has_key('annotation_counter'): 1861 self.annotation_counter = kwargs['annotation_counter'] 1862 if kwargs.has_key('link'): 1863 self.link = kwargs.has_key('link') and kwargs['link'] or None
1864 1865 omero.gateway.WellWrapper = WellWrapper 1866
1867 -class PlateAcquisitionWrapper (OmeroWebObjectWrapper, omero.gateway.BlitzObjectWrapper):
1868 1869 """ 1870 omero_model_PlateI class wrapper overwrite omero.gateway.PlateWrapper 1871 and extends OmeroWebObjectWrapper. 1872 """ 1873 1874 annotation_counter = None 1875
1876 - def __bstrap__ (self):
1877 self.OMERO_CLASS = 'PlateAcquisition'
1878
1879 - def __prepare__ (self, **kwargs):
1880 super(PlateAcquisitionWrapper, self).__prepare__(**kwargs) 1881 if kwargs.has_key('annotation_counter'): 1882 self.annotation_counter = kwargs['annotation_counter']
1883
1884 - def getName (self):
1885 name = super(PlateAcquisitionWrapper, self).getName() 1886 if name is None: 1887 if self.startTime is not None and self.endTime is not None: 1888 name = "%s - %s" % (datetime.fromtimestamp(self.startTime/1000), datetime.fromtimestamp(self.endTime/1000)) 1889 else: 1890 name = "Plate %i" % self.id 1891 return name
1892 name = property(getName) 1893
1894 - def getFields (self):
1895 """ 1896 Returns max of indexed collection of well samples 1897 """ 1898 1899 p = omero.sys.Parameters() 1900 p.map = {} 1901 p.map["oid"] = self._obj.id 1902 1903 q = self._conn.getQueryService() 1904 sql = "select maxIndex(pa.wellSamples)+1 from PlateAcquisition as pa "\ 1905 "where pa.id=:oid" 1906 try: 1907 index = unwrap(q.projection(sql, p))[0][0] 1908 except: 1909 index = -1 1910 return index
1911 1912
1913 -class ScreenWrapper (OmeroWebObjectWrapper, omero.gateway.ScreenWrapper):
1914 """ 1915 omero_model_ScreenI class wrapper overwrite omero.gateway.ScreenWrapper 1916 and extends OmeroWebObjectWrapper. 1917 """ 1918 1919 annotation_counter = None 1920
1921 - def __prepare__ (self, **kwargs):
1922 super(ScreenWrapper, self).__prepare__(**kwargs) 1923 if kwargs.has_key('annotation_counter'): 1924 self.annotation_counter = kwargs['annotation_counter']
1925 1926 omero.gateway.ScreenWrapper = ScreenWrapper 1927
1928 -class EventLogWrapper (omero.gateway.BlitzObjectWrapper):
1929 """ 1930 omero_model_EventLogI class wrapper extends omero.gateway.BlitzObjectWrapper. 1931 """ 1932 1933 LINK_CLASS = "EventLog"
1934
1935 -class ShareWrapper (omero.gateway.BlitzObjectWrapper):
1936 """ 1937 omero_model_ShareI class wrapper extends BlitzObjectWrapper. 1938 """ 1939
1940 - def getShareType(self):
1941 if self.itemCount == 0: 1942 return "Discussion" 1943 else: 1944 return "Share"
1945
1946 - def isEmpty(self):
1947 if self.itemCount == 0: 1948 return True 1949 return False
1950
1951 - def getExpireDate(self):
1952 #workaround for problem of year 2038 1953 try: 1954 d = self.started+self.timeToLive 1955 if d > 2051222400000: 1956 return datetime(2035, 1, 1, 0, 0, 0) 1957 return datetime.fromtimestamp(d / 1000) 1958 except: 1959 logger.info(traceback.format_exc()) 1960 return None
1961
1962 - def getStartDate(self):
1963 """ 1964 Gets the start date of the share 1965 1966 @return: Start Date-time 1967 @rtype: datetime object 1968 """ 1969 1970 return datetime.fromtimestamp(self.getStarted()/1000)
1971
1972 - def getExpirationDate(self):
1973 """ 1974 Gets the end date for the share 1975 1976 @return: End Date-time 1977 @rtype: datetime object 1978 """ 1979 1980 #workaround for problem of year 2038 1981 try: 1982 d = self.started+self.timeToLive 1983 if d > 2051222400: 1984 return datetime(2035, 1, 1, 0, 0, 0) 1985 return datetime.fromtimestamp(d / 1000) 1986 except: 1987 logger.info(traceback.format_exc()) 1988 return None
1989
1990 - def isExpired(self):
1991 """ 1992 Returns True if we are past the end date of the share 1993 1994 @return: True if share expired 1995 @rtype: Boolean 1996 """ 1997 1998 #workaround for problem of year 2038 1999 now = time.time() 2000 try: 2001 d = long(self.started+self.timeToLive) 2002 if (d / 1000) > now: 2003 return False 2004 return True 2005 except: 2006 logger.info(traceback.format_exc()) 2007 return None
2008
2009 - def isOwned(self):
2010 """ 2011 Returns True if share is owned by the current user 2012 2013 @return: True if owned 2014 @rtype: Boolean 2015 """ 2016 2017 try: 2018 if self.owner.id.val == self._conn.getEventContext().userId: 2019 return True 2020 except: 2021 logger.error(traceback.format_exc()) 2022 return False
2023
2024 - def getOwner(self):
2025 """ 2026 The owner of this share 2027 2028 @return: Owner 2029 @rtype: L{ExperimenterWrapper} 2030 """ 2031 2032 return omero.gateway.ExperimenterWrapper(self, self.owner)
2033 2034 # IMPORTANT to update the map of wrappers 'project', 'dataset', 'image' etc. returned by getObjects() 2035 omero.gateway.refreshWrappers() 2036 omero.gateway.KNOWN_WRAPPERS.update({"plateacquisition":PlateAcquisitionWrapper}) 2037