1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 import cStringIO
28 import traceback
29 import logging
30
31 logger = logging.getLogger(__name__)
32
33 try:
34 from PIL import Image, ImageDraw
35 except ImportError:
36 try:
37 import Image, ImageDraw
38 except:
39 logger.error("You need to install the Python Imaging Library. Get it at http://www.pythonware.com/products/pil/")
40 logger.error(traceback.format_exc())
41
42 from StringIO import StringIO
43
44 import time
45 from datetime import datetime
46 from types import IntType, ListType, TupleType, UnicodeType, StringType
47
48 import Ice
49 import Glacier2
50 import omero.gateway
51 import omero.scripts
52
53 from omero.rtypes import *
54 from omero.model import FileAnnotationI, TagAnnotationI, \
55 DatasetI, ProjectI, ImageI, ScreenI, PlateI, \
56 DetectorI, FilterI, ObjectiveI, InstrumentI, \
57 LaserI, ExperimenterI, ExperimenterGroupI
58
59 from omero.gateway import FileAnnotationWrapper, TagAnnotationWrapper, ExperimenterWrapper, \
60 ExperimenterGroupWrapper, WellWrapper, AnnotationWrapper, \
61 OmeroGatewaySafeCallWrapper, CommentAnnotationWrapper
62
63 from omero.sys import ParametersI
64
65 from django.utils.encoding import smart_str
66 from django.utils.translation import ugettext as _
67 from django.conf import settings
68 from django.core.mail import send_mail
69 from django.core.mail import EmailMultiAlternatives
70
71 from omeroweb.connector import Server
72
73 try:
74 import hashlib
75 hash_sha1 = hashlib.sha1
76 except:
77 import sha
78 hash_sha1 = sha.new
79
80
93
94
96
98 """
99 Create the connection wrapper. Does not attempt to connect at this stage
100 Initialises the omero.client
101
102 @param username: User name. If not specified, use 'omero.gateway.anon_user'
103 @type username: String
104 @param passwd: Password.
105 @type passwd: String
106 @param client_obj: omero.client
107 @param group: name of group to try to connect to
108 @type group: String
109 @param clone: If True, overwrite anonymous with False
110 @type clone: Boolean
111 @param try_super: Try to log on as super user ('system' group)
112 @type try_super: Boolean
113 @param host: Omero server host.
114 @type host: String
115 @param port: Omero server port.
116 @type port: Integer
117 @param extra_config: Dictionary of extra configuration
118 @type extra_config: Dict
119 @param secure: Initial underlying omero.client connection type (True=SSL/False=insecure)
120 @type secure: Boolean
121 @param anonymous:
122 @type anonymous: Boolean
123 @param useragent: Log which python clients use this connection. E.g. 'OMERO.webadmin'
124 @type useragent: String
125
126 @param _shareId: Active share ID
127 @type _shareId: Long
128 """
129
130 super(OmeroWebGateway, self).__init__(*args, **kwargs)
131 self._shareId = None
132
133
135 """
136 Returns active share id .
137
138 @return: Share ID
139 @rtype: Long
140 """
141
142 if self.getEventContext().shareId is not None:
143 if self.getEventContext().shareId != self._shareId and self._shareId > 0:
144 self._shareId = self.getEventContext().shareId
145 return self._shareId
146
147
148
149
150
152 """
153 Every time session is created default group becomes active group
154 and is loaded with the security for the current user and thread.
155 Public data has to be created in the context of the group where user,
156 who would like to look at these data, is a member of.
157 Public data can be only visible by the member of group and owners.
158
159 @param gid: New active group ID
160 @type gid: Long
161
162 @return: Boolean
163 """
164
165 try:
166 for k in self._proxies.keys():
167 self._proxies[k].close()
168
169 self.c.sf.setSecurityContext(ExperimenterGroupI(gid, False))
170 self.getAdminService().setDefaultGroup(self.getUser()._obj, ExperimenterGroupI(gid, False))
171 self._ctx = self.getAdminService().getEventContext()
172 return True
173 except omero.SecurityViolation:
174 logger.error(traceback.format_exc())
175 return False
176 except:
177 logger.error(traceback.format_exc())
178 return False
179
180
181
182
184 """
185 Retrieves a configuration value "omero.resetpassword.config" for
186 Forgotten password form from the backend store.
187
188 @return: Boolean
189 """
190
191 conf = self.getConfigService()
192 try:
193 return bool(conf.getConfigValue("omero.resetpassword.config").title())
194 except:
195 logger.error(traceback.format_exc())
196 return False
197
199 """
200 Allows to reset the password (temporary password is sent). The
201 given email must match the email for the user listed under the name
202 argument.
203
204 @param username: omename
205 @type username: String
206 @param email: email address
207 @type email: String
208
209 """
210
211 admin_serv = self.getAdminService()
212 admin_serv.reportForgottenPassword(username, email)
213
214
215
216
218 """
219 Checks if any of the experimenter was created before
220
221 @return: Boolean
222 """
223
224 q = self.getQueryService()
225 p = omero.sys.Parameters()
226 p.map = {}
227 p.map["default_names"] = rlist([rstring("user"), rstring("system"), rstring("guest")])
228 f = omero.sys.Filter()
229 f.limit = rint(1)
230 p.theFilter = f
231 sql = "select g from ExperimenterGroup as g where g.name not in (:default_names)"
232 if len(q.findAllByQuery(sql, p, self.SERVICE_OPTS)) > 0:
233 return False
234 return True
235
237 """
238 Lists all IDs of experimenters who are authenticated by LDAP
239 (has set dn on password table).
240
241 @return: List of experimetner IDs
242 @rtype: L{Dict of String: Long}
243 """
244
245 admin_serv = self.getAdminService()
246 return admin_serv.lookupLdapAuthExperimenters()
247
249 """
250 Return DN of the specific experimenter if uses LDAP authentication
251 (has set dn on password table) or None.
252
253 @param eid: experimenter ID
254 @type eid: L{Long}
255 @return: Distinguished Name
256 @rtype: String
257 """
258
259 admin_serv = self.getAdminService()
260 return admin_serv.lookupLdapAuthExperimenter(long(eid))
261
263 """
264 Return all experimenters apart from current user.
265
266 @return: Generator yielding experimetners list
267 @rtype: L{ExperimenterWrapper} generator
268
269 """
270
271 q = self.getQueryService()
272 p = omero.sys.Parameters()
273 p.map = {}
274 p.map["id"] = rlong(self.getEventContext().userId)
275 sql = "select e from Experimenter as e where e.id != :id "
276 for e in q.findAllByQuery(sql, p, self.SERVICE_OPTS):
277 yield ExperimenterWrapper(self, e)
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
307 """
308 Retrieves a configuration value "omero.version" from the backend store.
309
310 @return: String
311 """
312
313 conf = self.getConfigService()
314 return conf.getConfigValue("omero.version")
315
316
317
318
319
321 q = self.getQueryService()
322 p = omero.sys.Parameters()
323 p.map = {}
324 p.map['pname'] = rstring(str(plate_name))
325 p.map['row'] = rint(int(row))
326 p.map['column'] = rint(int(column))
327
328 sql = """select well from Well as well
329 left outer join fetch well.plate as pt
330 left outer join fetch well.wellSamples as ws
331 inner join fetch ws.image as img
332 where well.plate.name = :pname and well.row = :row
333 and well.column = :column"""
334 well = q.findByQuery(sql, p, self.SERVICE_OPTS)
335 if well is None:
336 return None
337 else:
338 return WellWrapper(self, well, None)
339
340
341
342
343
344
359
361 links = {'Dataset':('ProjectDatasetLink', DatasetWrapper),
362 'Image':('DatasetImageLink', ImageWrapper),
363 'Plate':('ScreenPlateLink', PlateWrapper)}
364
365 if obj_type not in links:
366 raise TypeError("'%s' is not valid object type. Must use one of %s" % (obj_type, links.keys()) )
367
368 q = self.getQueryService()
369 p = omero.sys.Parameters()
370 p.map = {}
371
372 links = {'Dataset':('ProjectDatasetLink', DatasetWrapper),
373 'Image':('DatasetImageLink', ImageWrapper),
374 'Plate':('ScreenPlateLink', PlateWrapper)}
375
376 if obj_type not in links:
377 raise TypeError("'%s' is not valid object type. Must use one of %s" % (obj_type, links.keys()) )
378
379 q = self.getQueryService()
380 p = omero.sys.Parameters()
381 p.map = {}
382
383 if eid is not None:
384 p.map["eid"] = rlong(long(eid))
385 eidFilter = "obj.details.owner.id=:eid and "
386 eidWsFilter = " and ws.details.owner.id=:eid"
387 else:
388 eidFilter = ""
389 eidWsFilter = ""
390
391 sql = "select count(obj.id) from %s as obj " \
392 "join obj.details.creationEvent "\
393 "join obj.details.owner join obj.details.group " \
394 "where %s" \
395 "not exists (select obl from %s as obl where " \
396 "obl.child=obj.id)" % (obj_type, eidFilter, links[obj_type][0])
397 if obj_type == 'Image':
398 sql += "and not exists ( "\
399 "select ws from WellSample as ws "\
400 "where ws.image=obj.id %s)" % eidWsFilter
401
402 rslt = q.projection(sql, p, self.SERVICE_OPTS)
403 if len(rslt) > 0:
404 if len(rslt[0]) > 0:
405 return rslt[0][0].val
406 return 0
407
409 """
410 List Images in the given Dataset.
411 Optinally filter by experimenter 'eid'
412
413 @param eid: experimenter id
414 @type eid: Long
415 @param page: page number
416 @type page: Long
417 @return: Generator yielding Images
418 @rtype: L{ImageWrapper} generator
419 """
420
421 q = self.getQueryService()
422 p = omero.sys.ParametersI()
423 p.map["oid"] = rlong(long(oid))
424 if page is not None:
425 p.page(((int(page)-1)*settings.PAGE), settings.PAGE)
426 if load_pixels:
427 pixels = "join fetch im.pixels "
428 else:
429 pixels = ""
430 sql = "select im from Image im "\
431 "join fetch im.details.creationEvent "\
432 "join fetch im.details.owner join fetch im.details.group " \
433 "left outer join fetch im.datasetLinks dil "\
434 "left outer join fetch dil.parent d %s" \
435 "where d.id = :oid" % pixels
436 if eid is not None:
437 p.map["eid"] = rlong(long(eid))
438 sql += " and im.details.owner.id=:eid"
439 sql+=" order by im.name ASC"
440
441 for e in q.findAllByQuery(sql, p, self.SERVICE_OPTS):
442 kwargs = {'link': omero.gateway.BlitzObjectWrapper(self, e.copyDatasetLinks()[0])}
443 yield ImageWrapper(self, e, None, **kwargs)
444
445
446 - def findTag (self, name, desc=None):
447 """
448 Retrieves Tag by given Name and description
449
450 @param name name of tag
451 @type name String
452 @param desc description of tag
453 @type desc String
454 @return: TagAnnotation
455 @rtype: AnnotationWrapper
456 """
457 """TODO: #1015
458 It does not support SPW"""
459
460 query_serv = self.getQueryService()
461 res = list()
462 p = omero.sys.Parameters()
463 p.map = {}
464 p.map["text"] = rstring(str(name))
465 if desc is not None:
466 p.map["desc"] = rstring(str(desc))
467
468 f = omero.sys.Filter()
469 f.limit = rint(1)
470 p.theFilter = f
471 sql = "select tg from TagAnnotation tg " \
472 "where tg.textValue=:text"
473 if desc is not None:
474 sql+= " and tg.description=:desc"
475 sql+=" and tg.ns is null order by tg.textValue"
476 res = query_serv.findAllByQuery(sql, p, self.SERVICE_OPTS)
477 if len(res) > 0:
478 return TagAnnotationWrapper(self, res[0])
479 return None
480
481
483 """
484 Uploads a photo for the user which will be displayed on his/her profile.
485 This photo will be saved as an OriginalFile object
486 with the given format, and attached to the user's Experimenter
487 object via an File Annotation with
488 the namespace: "openmicroscopy.org/omero/experimenter/photo" (NSEXPERIMENTERPHOTO).
489 If such an OriginalFile instance already exists,
490 it will be overwritten. If more than one photo is present, the oldest
491 version will be modified (i.e. the highest updateEvent id).
492
493 Note: as outlined in ticket:1794, this photo will be placed in the "user"
494 group and therefore will be visible to everyone on the system.
495
496 @param filename name which will be used.
497 @type filename String
498 @param format Format.value string. 'image/jpeg' and 'image/png' are common values.
499 @type format String
500 @param data Data from the image. This will be written to disk.
501 @type data String
502
503 @return ID of the overwritten or newly created user photo OriginalFile object.
504 @rtype Long
505 """
506
507 admin_serv = self.getAdminService()
508 pid = admin_serv.uploadMyUserPhoto(filename, format, data)
509 if pid is not None:
510 return pid
511
513 """
514 Check if File annotation with the namespace:
515 "openmicroscopy.org/omero/experimenter/photo" (NSEXPERIMENTERPHOTO) is linked
516 to the given user ID. If user id not set, owned by the current user.
517
518 @param oid experimenter ID
519 @type oid Long
520 @return True or False
521 @rtype Boolean
522 """
523
524 meta = self.getMetadataService()
525 try:
526 if oid is None:
527 ann = meta.loadAnnotations("Experimenter", [self.getEventContext().userId], None, None, None).get(self.getEventContext().userId, [])
528 else:
529 ann = meta.loadAnnotations("Experimenter", [long(oid)], None, None, None).get(long(oid), [])
530 if len(ann) > 0:
531 return True
532 else:
533 return False
534 except:
535 logger.error(traceback.format_exc())
536 return False
537
539 """
540 Get File annotation with the namespace:
541 "openmicroscopy.org/omero/experimenter/photo" (NSEXPERIMENTERPHOTO) linked
542 to the given user ID. If user id not set, owned by the current user.
543
544 @param oid experimenter ID
545 @type oid Long
546 @return Data from the image.
547 @rtype String
548 """
549
550 photo = None
551 meta = self.getMetadataService()
552 try:
553 if oid is None:
554 ann = meta.loadAnnotations("Experimenter", [self.getEventContext().userId], None, None, None).get(self.getEventContext().userId, [])
555 else:
556 ann = meta.loadAnnotations("Experimenter", [long(oid)], None, None, None).get(long(oid), [])
557 if len(ann) > 0:
558 ann = ann[0]
559 store = self.createRawFileStore()
560 store.setFileId(ann.file.id.val)
561 photo = store.read(0,long(ann.file.size.val))
562 else:
563 photo = self.getExperimenterDefaultPhoto()
564 except:
565 logger.error(traceback.format_exc())
566 photo = self.getExperimenterDefaultPhoto()
567 if photo == None:
568 photo = self.getExperimenterDefaultPhoto()
569 return photo
570
572 """
573 Get size of File annotation with the namespace:
574 "openmicroscopy.org/omero/experimenter/photo" (NSEXPERIMENTERPHOTO) linked
575 to the given user ID. If user id not set, owned by the current user.
576
577 @param oid experimenter ID
578 @type oid Long
579 @return Tuple including dimention and size of the file
580 @rtype Tuple
581 """
582
583 photo = None
584 meta = self.getMetadataService()
585 try:
586 if oid is None:
587 ann = meta.loadAnnotations("Experimenter", [self.getEventContext().userId], None, None, None).get(self.getEventContext().userId, [])[0]
588 else:
589 ann = meta.loadAnnotations("Experimenter", [long(oid)], None, None, None).get(long(oid), [])[0]
590 store = self.createRawFileStore()
591 store.setFileId(ann.file.id.val)
592 photo = store.read(0,long(ann.file.size.val))
593 try:
594 im = Image.open(StringIO(photo))
595 except:
596 logger.error(traceback.format_exc())
597 return None
598 else:
599 return (im.size, ann.file.size.val)
600 except:
601 return None
602
604 ann = None
605 meta = self.getMetadataService()
606 try:
607 if oid is None:
608 ann = meta.loadAnnotations("Experimenter", [self.getEventContext().userId], None, None, None).get(self.getEventContext().userId, [])[0]
609 else:
610 ann = meta.loadAnnotations("Experimenter", [long(oid)], None, None, None).get(long(oid), [])[0]
611 except:
612 logger.error(traceback.format_exc())
613 raise IOError("Photo does not exist.")
614 else:
615 exp = self.getUser()
616 links = exp._getAnnotationLinks()
617
618
619 for l in links:
620 self.deleteObjectDirect(l)
621 self.deleteObjects("/Annotation", [ann.id.val])
622
624 """
625 Crop File annotation with the namespace:
626 "openmicroscopy.org/omero/experimenter/photo" (NSEXPERIMENTERPHOTO) linked
627 to the given user ID. If user id not set, owned by the current user.
628 New dimentions are defined by squer positions box = (x1,y1,x2,y2)
629
630 @param box tuple of new square positions
631 @type box Tuple
632 @param oid experimenter ID
633 @type oid Long
634 """
635
636
637 photo = None
638 meta = self.getMetadataService()
639 ann = None
640 try:
641 if oid is None:
642 ann = meta.loadAnnotations("Experimenter", [self.getEventContext().userId], None, None, None).get(self.getEventContext().userId, [])[0]
643 else:
644 ann = meta.loadAnnotations("Experimenter", [long(oid)], None, None, None).get(long(oid), [])[0]
645 store = self.createRawFileStore()
646 store.setFileId(ann.file.id.val)
647 photo = store.read(0,long(ann.file.size.val))
648 except:
649 logger.error(traceback.format_exc())
650 raise IOError("Photo does not exist.")
651 else:
652 region = None
653 try:
654 im = Image.open(StringIO(photo))
655 region = im.crop(box)
656 except IOError:
657 logger.error(traceback.format_exc())
658 raise IOError("Cannot open that photo.")
659 else:
660 imdata=StringIO()
661 region.save(imdata, format=im.format)
662 self.uploadMyUserPhoto(ann.file.name.val, ann.file.mimetype.val, imdata.getvalue())
663
665 """
666 If file annotation with the namespace:
667 "openmicroscopy.org/omero/experimenter/photo" (NSEXPERIMENTERPHOTO)
668 is not linked to experimenter this method generate default picture of the person.
669
670 @return Data from the image.
671 @rtype String
672 """
673
674 img = Image.open(settings.DEFAULT_USER)
675 img.thumbnail((150,150), Image.ANTIALIAS)
676 draw = ImageDraw.Draw(img)
677 f = cStringIO.StringIO()
678 img.save(f, "PNG")
679 f.seek(0)
680 return f.read()
681
691
692
693
694
696 """
697 Counts the number of members in a collection for a given object.
698
699 @param parent The fully-qualified classname of the object to be tested
700 @type parent String
701 @param child Name of the property on that class, omitting getters and setters.
702 @type child String
703 @param ids Set of Longs, the ids of the objects to test
704 @type ids L{Long}
705 @return A map from id integer to count integer
706 @rtype L{(Long, Long)}
707 """
708 container = self.getContainerService()
709 return container.getCollectionCount(parent, child, ids, None, self.SERVICE_OPTS)
710
711
712
713
715 if ome_name == old_omeName:
716 return False
717 query_serv = self.getQueryService()
718 p = omero.sys.Parameters()
719 p.map = {}
720 p.map["omeName"] = rstring(smart_str(ome_name))
721 sql = "select e from Experimenter as e where e.omeName = (:omeName)"
722 exps = query_serv.findAllByQuery(sql, p, self.SERVICE_OPTS)
723 if len(exps) > 0:
724 return True
725 else:
726 return False
727
729 if name == old_name:
730 return False
731 query_serv = self.getQueryService()
732 p = omero.sys.Parameters()
733 p.map = {}
734 p.map["name"] = rstring(smart_str(name))
735 sql = "select g from ExperimenterGroup as g where g.name = (:name)"
736 grs = query_serv.findAllByQuery(sql, p, self.SERVICE_OPTS)
737 if len(grs) > 0:
738 return True
739 else:
740 return False
741
743 if email == "":
744 return False
745 if email == old_email:
746 return False
747 query_serv = self.getQueryService()
748 p = omero.sys.Parameters()
749 p.map = {}
750 p.map["email"] = rstring(smart_str(email))
751 sql = "select e from Experimenter as e where e.email = (:email)"
752 exps = query_serv.findAllByQuery(sql, p, self.SERVICE_OPTS)
753 if len(exps) > 0:
754 return True
755 else:
756 return False
757
758
759
760
762 """
763 Change the password for the a given user.
764
765 @param omeName Experimetner omename
766 @type omeName String
767 @param password Must pass validation in the security sub-system.
768 @type password String
769 @param my_password Must pass validation in the security sub-system.
770 @type my_password String
771 """
772 admin_serv = self.getAdminService()
773 self.c.sf.setSecurityPassword(my_password)
774 admin_serv.changeUserPassword(omeName, rstring(str(password)))
775
777 """
778 Change the password for the current user by passing the old password.
779
780 @param password Must pass validation in the security sub-system.
781 @type password String
782 @param old_password Old password
783 @type old_password String
784 @return None or error message if password could not be changed
785 @rtype String
786 """
787 admin_serv = self.getAdminService()
788 admin_serv.changePasswordWithOldPassword(rstring(str(old_password)), rstring(str(password)))
789
790 - def createExperimenter(self, omeName, firstName, lastName, email, isAdmin, isActive, defaultGroup, otherGroups, password, middleName=None, institution=None):
791 """
792 Create and return a new user in the given groups with password.
793 @param omeName A new username.
794 @type omeName String
795 @param firstName A new first name.
796 @type firstName String
797 @param lastName A new last name.
798 @type lastName String
799 @param email A new email.
800 @type email String
801 @param isAdmin An Admin permission.
802 @type isAdmin Boolean
803 @param isActive Active user (user can log in).
804 @type isActive Boolean
805 @param defaultGroup Instance of ExperimenterGroup selected as a first active group.
806 @type defaultGroup ExperimenterGroupI
807 @param otherGroups List of ExperimenterGroup instances. Can be empty.
808 @type otherGroups L{ExperimenterGroupI}
809 @param password Must pass validation in the security sub-system.
810 @type password String
811 @param middleName A middle name.
812 @type middleName String
813 @param institution An institution.
814 @type institution String
815 @return ID of the newly created Experimenter Not null.
816 @rtype Long
817 """
818 experimenter = ExperimenterI()
819 experimenter.omeName = rstring(str(omeName))
820 experimenter.firstName = rstring(str(firstName))
821 experimenter.middleName = middleName is not None and rstring(str(middleName)) or None
822 experimenter.lastName = rstring(str(lastName))
823 experimenter.email = rstring(str(email))
824 experimenter.institution = (institution!="" and institution is not None) and rstring(str(institution)) or None
825
826 listOfGroups = list()
827
828 if isAdmin:
829 g = self.getObject("ExperimenterGroup", attributes={'name':'system'})
830 listOfGroups.append(g._obj)
831
832
833 if isActive:
834 g = self.getObject("ExperimenterGroup", attributes={'name':'user'})
835 listOfGroups.append(g._obj)
836
837 for g in otherGroups:
838 listOfGroups.append(g._obj)
839
840 admin_serv = self.getAdminService()
841 return admin_serv.createExperimenterWithPassword(experimenter, rstring(str(password)), defaultGroup._obj, listOfGroups)
842
843 - def updateExperimenter(self, experimenter, omeName, firstName, lastName, email, isAdmin, isActive, defaultGroup, otherGroups, middleName=None, institution=None):
844 """
845 Update an existing user including groups user is a member of.
846 Password cannot be changed by calling that method.
847 @param experimenter An existing Experimenter instance.
848 @type experimenter ExperimenterWrapper
849 @param omeName A new username.
850 @type omeName String
851 @param firstName A new first name.
852 @type firstName String
853 @param lastName A new last name.
854 @type lastName String
855 @param email A new email.
856 @type email String
857 @param isAdmin An Admin permission.
858 @type isAdmin Boolean
859 @param isActive Active user (user can log in).
860 @type isActive Boolean
861 @param defaultGroup Instance of ExperimenterGroup selected as a first active group.
862 @type defaultGroup ExperimenterGroupI
863 @param otherGroups List of ExperimenterGroup instances. Can be empty.
864 @type otherGroups L{ExperimenterGroupI}
865 @param middleName A middle name.
866 @type middleName String
867 @param institution An institution.
868 @type institution String
869 """
870 up_exp = experimenter._obj
871 up_exp.omeName = rstring(str(omeName))
872 up_exp.firstName = rstring(str(firstName))
873 up_exp.middleName = middleName is not None and rstring(str(middleName)) or None
874 up_exp.lastName = rstring(str(lastName))
875 up_exp.email = rstring(str(email))
876 up_exp.institution = (institution!="" and institution is not None) and rstring(str(institution)) or None
877
878
879 old_groups = list()
880 for ogr in up_exp.copyGroupExperimenterMap():
881 if ogr is None:
882 continue
883 old_groups.append(ogr.parent)
884
885
886 new_groups = list()
887
888
889 new_groups.append(defaultGroup._obj)
890
891
892 if isAdmin:
893 g = self.getObject("ExperimenterGroup", attributes={'name':'system'})
894 if defaultGroup.id != g.id:
895 new_groups.append(g._obj)
896
897
898 if isActive:
899 g = self.getObject("ExperimenterGroup", attributes={'name':'user'})
900 new_groups.append(g._obj)
901
902
903 for g in otherGroups:
904 new_groups.append(g._obj)
905
906 addGroups = list()
907 rmGroups = list()
908
909
910 for ogr in old_groups:
911 flag = False
912 for ngr in new_groups:
913 if ngr.id.val == ogr.id.val:
914 flag = True
915 if not flag:
916 rmGroups.append(ogr)
917
918
919 for ngr in new_groups:
920 flag = False
921 for ogr in old_groups:
922 if ogr.id.val == ngr.id.val:
923 flag = True
924 if not flag:
925 addGroups.append(ngr)
926
927 admin_serv = self.getAdminService()
928 admin_serv.updateExperimenter(up_exp)
929 if len(addGroups) > 0:
930 admin_serv.addGroups(up_exp, addGroups)
931 admin_serv.setDefaultGroup(up_exp, defaultGroup._obj)
932 if len(rmGroups) > 0:
933 admin_serv.removeGroups(up_exp, rmGroups)
934
936 """
937 Change members of the group. Returns a list of existing group members
938 that could not be removed from the group because it is their only group.
939
940 @param group An existing ExperimenterGroup instance.
941 @type group ExperimenterGroupI
942 @param new_members List of new new Experimenter Ids.
943 @type new_members L{Long}
944 @return List of Experimenters not removed from group
945 @rtype List of L{ExperimenterWrapper}
946 """
947
948 experimenters = list(self.getObjects("Experimenter"))
949
950 new_membersIds = [nm.id for nm in new_members]
951
952 old_members = group.getMembers()
953 old_membersIds = [om.id for om in old_members]
954
955 old_available = list()
956 for e in experimenters:
957 if e.id not in old_membersIds:
958 old_available.append(e)
959 old_availableIds = [oa.id for oa in old_available]
960
961 new_available = list()
962 for e in experimenters:
963 if e.id not in new_membersIds:
964 new_available.append(e)
965
966 new_availableIds = [na.id for na in new_available]
967
968 rm_exps = list(set(old_membersIds) - set(new_membersIds))
969 add_exps = list(set(old_availableIds) - set(new_availableIds))
970
971 to_remove = list()
972 to_add = list()
973 for e in experimenters:
974 if e.id in rm_exps:
975
976
977 to_remove.append(e._obj)
978 if e.id in add_exps:
979 to_add.append(e._obj)
980
981 admin_serv = self.getAdminService()
982 userGid = admin_serv.getSecurityRoles().userGroupId
983 failures = []
984 for e in to_add:
985 admin_serv.addGroups(e, [group._obj])
986 for e in to_remove:
987
988 gs = [l.parent.id.val for l in e.copyGroupExperimenterMap() if l.parent.id.val != userGid]
989 if len(gs) == 1:
990 failures.append(ExperimenterWrapper(self, e))
991 continue
992 admin_serv.removeGroups(e, [group._obj])
993 return failures
994
996 """
997 Change members of the group.
998
999 @param group An existing ExperimenterGroup instance.
1000 @type group ExperimenterGroupI
1001 @param new_members List of new new Experimenter Ids.
1002 @type new_members L{Long}
1003 """
1004
1005 experimenters = list(self.getObjects("Experimenter"))
1006
1007 new_ownersIds = [no.id for no in new_owners]
1008
1009 old_owners = group.getOwners()
1010 old_ownersIds = [oo.id for oo in old_owners]
1011
1012 old_available = list()
1013 for e in experimenters:
1014 if e.id not in old_ownersIds:
1015 old_available.append(e)
1016 old_availableIds = [oa.id for oa in old_available]
1017
1018 new_available = list()
1019 for e in experimenters:
1020 if e.id not in new_ownersIds:
1021 new_available.append(e)
1022
1023 new_availableIds = [na.id for na in new_available]
1024
1025 rm_exps = list(set(old_ownersIds) - set(new_ownersIds))
1026 add_exps = list(set(old_availableIds) - set(new_availableIds))
1027
1028 to_remove = list()
1029 to_add = list()
1030 for e in experimenters:
1031 if e.id in rm_exps:
1032
1033
1034 to_remove.append(e._obj)
1035 if e.id in add_exps:
1036 to_add.append(e._obj)
1037
1038 admin_serv = self.getAdminService()
1039 admin_serv.addGroupOwners(group._obj, to_add)
1040 admin_serv.removeGroupOwners(group._obj, to_remove)
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053 - def createGroup(self, name, permissions, owners=list(), description=None):
1054 """
1055 Create and return a new group with the given owners.
1056
1057 @param group A new ExperimenterGroup instance.
1058 @type group ExperimenterGroupI
1059 @param owners List of Experimenter instances. Can be empty.
1060 @type owners L{ExperimenterI}
1061 @param permissions Permissions instances.
1062 @type permissions L{PermissionsI}
1063 @return ID of the newly created ExperimenterGroup Not null.
1064 @rtype Long
1065 """
1066 new_gr = ExperimenterGroupI()
1067 new_gr.name = rstring(str(name))
1068 new_gr.description = (description!="" and description is not None) and rstring(str(description)) or None
1069 new_gr.details.permissions = permissions
1070
1071 admin_serv = self.getAdminService()
1072 gr_id = admin_serv.createGroup(new_gr)
1073 group = admin_serv.getGroup(gr_id)
1074
1075 listOfOwners = list()
1076 for exp in owners:
1077 listOfOwners.append(exp._obj)
1078
1079 admin_serv.addGroupOwners(group, listOfOwners)
1080 return gr_id
1081
1082 - def updateGroup(self, group, name, permissions, owners=list(), description=None):
1083 """
1084 Update an existing user including groups user is a member of.
1085 Password cannot be changed by calling that method.
1086
1087 @param group A new ExperimenterGroup instance.
1088 @type group ExperimenterGroupI
1089 @param name A new group name.
1090 @type name String
1091 @param permissions Permissions instances.
1092 @type permissions L{PermissionsI}
1093 @param owners List of Experimenter instances. Can be empty.
1094 @type owners L{ExperimenterI}
1095 @param description A description.
1096 @type description String
1097
1098 """
1099
1100 up_gr = group._obj
1101 up_gr.name = rstring(str(name))
1102 up_gr.description = (description!="" and description is not None) and rstring(str(description)) or None
1103
1104
1105
1106 old_owners = list()
1107 for oex in up_gr.copyGroupExperimenterMap():
1108 if oex is None:
1109 continue
1110 if oex.owner.val:
1111 old_owners.append(oex.child)
1112
1113 add_exps = list()
1114 rm_exps = list()
1115
1116
1117 for oex in old_owners:
1118 flag = False
1119 for nex in owners:
1120 if nex._obj.id.val == oex.id.val:
1121 flag = True
1122 if not flag:
1123 rm_exps.append(oex)
1124
1125
1126 for nex in owners:
1127 flag = False
1128 for oex in old_owners:
1129 if oex.id.val == nex._obj.id.val:
1130 flag = True
1131 if not flag:
1132 add_exps.append(nex._obj)
1133
1134 admin_serv = self.getAdminService()
1135
1136 admin_serv.updateGroup(up_gr)
1137 if permissions is not None:
1138 logger.warning("WARNING: changePermissions was called!!!")
1139 admin_serv.changePermissions(up_gr, permissions)
1140 admin_serv.addGroupOwners(up_gr, add_exps)
1141 admin_serv.removeGroupOwners(up_gr, rm_exps)
1142
1143 - def updateMyAccount(self, experimenter, firstName, lastName, email, defaultGroupId, middleName=None, institution=None):
1144 """
1145 Allows a user to update his/her own information and set the default group for a given user.
1146 @param experimenter A data transfer object. Only the fields: firstName, middleName,
1147 lastName, email, and institution are checked. Not null.
1148 @type experimenter ExperimenterWrapper
1149 @param firstName A new first name.
1150 @type firstName String
1151 @param lastName A new last name.
1152 @type lastName String
1153 @param email A new email.
1154 @type email String
1155 @param defaultGroup Instance of ExperimenterGroup selected as a first active group.
1156 @type defaultGroup ExperimenterGroupI
1157 @param middleName A middle name.
1158 @type middleName String
1159 @param institution An institution.
1160 @type institution String
1161 """
1162
1163 up_exp = experimenter._obj
1164 up_exp.firstName = rstring(str(firstName))
1165 up_exp.middleName = middleName is not None and rstring(str(middleName)) or None
1166 up_exp.lastName = rstring(str(lastName))
1167 up_exp.email = rstring(str(email))
1168 up_exp.institution = (institution!="" and institution is not None) and rstring(str(institution)) or None
1169
1170 admin_serv = self.getAdminService()
1171 admin_serv.updateSelf(up_exp)
1172 defultGroup = self.getObject("ExperimenterGroup", long(defaultGroupId))._obj
1173 admin_serv.setDefaultGroup(up_exp, defultGroup)
1174 self.changeActiveGroup(defultGroup.id)
1175
1177 """
1178 Sets the default group for the specified experimenter, or current user if not specified.
1179 """
1180 group_id = long(group_id)
1181 exp_id = exp_id is not None and long(exp_id) or self.getEventContext().userId
1182 admin_serv = self.getAdminService()
1183 admin_serv.setDefaultGroup(ExperimenterI(exp_id, False), ExperimenterGroupI(group_id, False))
1184
1186 """
1187 Allow to change the permission on the object.
1188
1189 @param obj A wrapped entity or an unloaded reference to an entity. Not null.
1190 @type obj BlitzObjectWrapper
1191 @param perm The permissions value for this entity. Not null.
1192 @type perm PermissionsI
1193 """
1194
1195 admin_serv = self.getAdminService()
1196 if permissions is not None:
1197 logger.warning("WARNING: changePermissions was called!!!")
1198 admin_serv.changePermissions(obj._obj, permissions)
1199
1201 """
1202 Provide method for directly updating object graphs. Act recursively on
1203 the entire object graph, replacing placeholders and details where necessary,
1204 and then "merging" the final graph. This means that the objects that are
1205 passed into methods are copied over to new instances which are then returned.
1206 The original objects should be discarded.
1207
1208 @param obj An entity or an unloaded reference to an entity. Not null.
1209 @type obj ObjectI
1210 """
1211 u = self.getUpdateService()
1212 u.saveObject(obj, self.SERVICE_OPTS)
1213
1215 """
1216 Provide method for directly updating list of object graphs. Act recursively on
1217 the entire object graph, replacing placeholders and details where necessary,
1218 and then "merging" the final graph. This means that the objects that are
1219 passed into methods are copied over to new instances which are then returned.
1220 The original objects should be discarded.
1221
1222 @param obj List of entities or an unloaded references to an entity. Not null.
1223 @type obj L{ObjectI}
1224 """
1225 u = self.getUpdateService()
1226 u.saveArray(objs, self.SERVICE_OPTS)
1227
1229 """
1230 Provide method for directly updating object graphs and return it. Act recursively on
1231 the entire object graph, replacing placeholders and details where necessary,
1232 and then "merging" the final graph. This means that the objects that are
1233 passed into methods are copied over to new instances which are then returned.
1234 The original objects should be discarded.
1235
1236 @param obj An entity or an unloaded reference to an entity. Not null.
1237 @type obj ObjectI
1238 @return Saved object
1239 @rtype ObjectI
1240 """
1241 u = self.getUpdateService()
1242 res = u.saveAndReturnObject(obj, self.SERVICE_OPTS)
1243 res.unload()
1244 obj = omero.gateway.BlitzObjectWrapper(self, res)
1245 return obj
1246
1248 """
1249 Provide method for directly updating object graphs and return ID. Act recursively on
1250 the entire object graph, replacing placeholders and details where necessary,
1251 and then "merging" the final graph. This means that the objects that are
1252 passed into methods are copied over to new instances which are then returned.
1253 The original objects should be discarded.
1254
1255 @param obj An entity or an unloaded reference to an entity. Not null.
1256 @type obj ObjectI
1257 @return ID of saved object
1258 @rtype Long
1259 """
1260 u = self.getUpdateService()
1261 res = u.saveAndReturnObject(obj, self.SERVICE_OPTS)
1262 res.unload()
1263 return res.id.val
1264
1266 """
1267 Provide method for directly updating a file object and return binary.
1268
1269 @param binary Binary. Not null.
1270 @type binary String
1271 @param oFile_id File Id in order to manage the state of the service. Not null.
1272 @type oFile_id Long
1273 @return Shallow copy of file.
1274 """
1275
1276 store = self.createRawFileStore()
1277 store.setFileId(oFile_id, self.SERVICE_OPTS);
1278 pos = 0
1279 rlen = 0
1280 hash = hash_sha1()
1281
1282 for chunk in binary.chunks():
1283 rlen = len(chunk)
1284 store.write(chunk, pos, rlen)
1285 hash.update(chunk)
1286 pos = pos + rlen
1287 ofile = store.save(self.SERVICE_OPTS)
1288 store.close()
1289
1290 serverhash = ofile.sha1.val
1291 clienthash = hash.hexdigest()
1292
1293 if serverhash != clienthash:
1294 msg = "SHA-1 checksums do not match in file upload: client has %s but server has %s" % (clienthash, serverhash)
1295 logger.error(msg)
1296 raise Exception(msg)
1297
1298 return ofile
1299
1300
1301
1302
1304 """
1305 Gets share for the given share id.
1306
1307 @param oid: Share ID.
1308 @type oid: Long
1309 @return: ShareWrapper or None
1310 @rtype: L{ShareWrapper}
1311 """
1312
1313 sh_serv = self.getShareService()
1314 sh = sh_serv.getShare(long(oid))
1315 if sh is not None:
1316 return ShareWrapper(self, sh)
1317 else:
1318 return None
1319
1321 """
1322 Gets all owned shares for the current user.
1323
1324 @return: Shares that user owns
1325 @rtype: L{ShareWrapper} generator
1326 """
1327
1328 sh = self.getShareService()
1329 for e in sh.getOwnShares(False):
1330 yield ShareWrapper(self, e)
1331
1333 """
1334 Gets all shares where current user is a member.
1335
1336 @return: Shares that user is a member of
1337 @rtype: L{ShareWrapper} generator
1338 """
1339
1340 sh = self.getShareService()
1341 for e in sh.getMemberShares(False):
1342 yield ShareWrapper(self, e)
1343
1345 """
1346 Returns a map from share id to the count of total members (including the
1347 owner). This is represented by ome.model.meta.ShareMember links.
1348
1349 @param share_ids: List of IDs
1350 @type share_ids: List of Longs
1351 @return: Dict of shareId: member-count
1352 @rtype: Dict of long: long
1353 """
1354
1355 sh = self.getShareService()
1356 return sh.getMemberCount(share_ids)
1357
1370
1371 - def getContents(self, share_id):
1372 """
1373 Looks up all items belonging to the share, wrapped in object wrapper
1374
1375 @param share_id: share ID
1376 @type share_id: Long
1377 @return: Share contents
1378 @rtype: L{omero.gateway.BlitzObjectWrapper} generator
1379 """
1380
1381 sh = self.getShareService()
1382 for e in sh.getContents(long(share_id)):
1383 try:
1384 obj = omero.gateway.BlitzObjectWrapper(self, e)
1385 except:
1386 obj = omero.gateway.BlitzObjectWrapper(self,None)
1387 obj._obj = e
1388 yield obj
1389
1403
1405 """
1406 Get all {@link Experimenter users} who are a member of the share.
1407
1408 @param share_id: share ID
1409 @type share_id: Long
1410 @return: Members of share
1411 @rtype: L{ExperimenterWrapper} generator
1412 """
1413
1414 sh = self.getShareService()
1415 for e in sh.getAllMembers(long(share_id)):
1416 yield ExperimenterWrapper(self, e)
1417
1419 """
1420 Get the email addresses for all share guests.
1421
1422 @param share_id: share ID
1423 @type share_id: Long
1424 @return: List of e-mail addresses
1425 @rtype: List of Strings
1426 """
1427
1428 sh = self.getShareService()
1429 return sh.getAllGuests(long(share_id))
1430
1432 """
1433 Get a single set containing the login names of the users as well email addresses for guests.
1434
1435 @param share_id: share ID
1436 @type share_id: Long
1437 @return: List of usernames and e-mail addresses
1438 @rtype: List of Strings
1439 """
1440
1441 sh = self.getShareService()
1442 return sh.getAllUsers(long(share_id))
1443
1445 recps = list()
1446 for m in recipients:
1447 try:
1448 if m.email is not None and m.email!="":
1449 recps.append(m.email)
1450 except:
1451 logger.error(traceback.format_exc())
1452 logger.info(recps)
1453 if len(recps) == 0:
1454 raise AttributeError("Recipients list is empty")
1455 return recps
1456
1493
1495 sh = self.getShareService()
1496 img = self.getObject("Image", image_id)
1497 sh.removeObject(long(share_id), img._obj)
1498
1499 - def createShare(self, host, blitz_id, image, message, members, enable, expiration=None):
1500 sh = self.getShareService()
1501 q = self.getQueryService()
1502
1503 items = list()
1504 ms = list()
1505 p = omero.sys.Parameters()
1506 p.map = {}
1507
1508 if len(image) > 0:
1509 p.map["ids"] = rlist([rlong(long(a)) for a in image])
1510 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"
1511 items.extend(q.findAllByQuery(sql, p, self.SERVICE_OPTS))
1512
1513
1514 if members is not None:
1515 p.map["ids"] = rlist([rlong(long(a)) for a in members])
1516 sql = "select e from Experimenter e " \
1517 "where e.id in (:ids) order by e.omeName"
1518 ms = q.findAllByQuery(sql, p, self.SERVICE_OPTS)
1519 sid = sh.createShare(message, rtime(expiration), items, ms, [], enable)
1520
1521
1522 if enable:
1523 try:
1524 recipients = self.prepareRecipients(ms)
1525 except Exception, x:
1526 logger.error(traceback.format_exc())
1527 else:
1528 t = settings.EMAIL_TEMPLATES["create_share"]
1529 message = t['text_content'] % (host, blitz_id, self.getUser().getFullName())
1530 message_html = t['html_content'] % (host, blitz_id, host, blitz_id, self.getUser().getFullName())
1531
1532 try:
1533 title = 'OMERO.web - new share %i' % sid
1534 text_content = message
1535 html_content = message_html
1536 msg = EmailMultiAlternatives(title, text_content, settings.SERVER_EMAIL, recipients)
1537 msg.attach_alternative(html_content, "text/html")
1538 msg.send()
1539 logger.error("Email was sent")
1540 except:
1541 logger.error(traceback.format_exc())
1542
1543 - def updateShareOrDiscussion (self, host, blitz_id, share_id, message, add_members, rm_members, enable, expiration=None):
1544 sh = self.getShareService()
1545 sh.setDescription(long(share_id), message)
1546 sh.setExpiration(long(share_id), rtime(expiration))
1547 sh.setActive(long(share_id), enable)
1548 if len(add_members) > 0:
1549 sh.addUsers(long(share_id), add_members)
1550 if len(rm_members) > 0:
1551 sh.removeUsers(long(share_id), rm_members)
1552
1553
1554 if len(add_members) > 0:
1555 try:
1556 recipients = self.prepareRecipients(add_members)
1557 except Exception, x:
1558 logger.error(traceback.format_exc())
1559 else:
1560 blitz = Server.get(pk=blitz_id)
1561 t = settings.EMAIL_TEMPLATES["add_member_to_share"]
1562 message = t['text_content'] % (host, blitz_id, self.getUser().getFullName())
1563 message_html = t['html_content'] % (host, blitz_id, host, blitz_id, self.getUser().getFullName())
1564 try:
1565 title = 'OMERO.web - update share %i' % share_id
1566 text_content = message
1567 html_content = message_html
1568 msg = EmailMultiAlternatives(title, text_content, settings.SERVER_EMAIL, recipients)
1569 msg.attach_alternative(html_content, "text/html")
1570 msg.send()
1571 logger.error("Email was sent")
1572 except:
1573 logger.error(traceback.format_exc())
1574
1575 if len(rm_members) > 0:
1576 try:
1577 recipients = self.prepareRecipients(rm_members)
1578 except Exception, x:
1579 logger.error(traceback.format_exc())
1580 else:
1581 blitz = Server.get(pk=blitz_id)
1582 t = settings.EMAIL_TEMPLATES["remove_member_from_share"]
1583 message = t['text_content'] % (host, blitz_id)
1584 message_html = t['html_content'] % (host, blitz_id, host, blitz_id)
1585
1586 try:
1587 title = 'OMERO.web - update share %i' % share_id
1588 text_content = message
1589 html_content = message_html
1590 msg = EmailMultiAlternatives(title, text_content, settings.SERVER_EMAIL, recipients)
1591 msg.attach_alternative(html_content, "text/html")
1592 msg.send()
1593 logger.error("Email was sent")
1594 except:
1595 logger.error(traceback.format_exc())
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1614 """
1615 Retrieve most recent imported images
1616 controlled by the security system.
1617
1618 @return: Generator yielding Images
1619 @rtype: L{ImageWrapper} generator
1620 """
1621
1622 tm = self.getTimelineService()
1623 p = omero.sys.Parameters()
1624 p.map = {}
1625 f = omero.sys.Filter()
1626 f.ownerId = rlong(self.getEventContext().userId)
1627 f.groupId = rlong(self.getEventContext().groupId)
1628 f.limit = rint(10)
1629 p.theFilter = f
1630 for e in tm.getMostRecentObjects(['Image'], p, False, self.SERVICE_OPTS)["Image"]:
1631 yield ImageWrapper(self, e)
1632
1634 """
1635 Retrieve most recent shares
1636 controlled by the security system.
1637
1638 @return: Generator yielding SessionAnnotationLink
1639 @rtype: L{ShareWrapper} generator
1640 """
1641
1642 tm = self.getTimelineService()
1643 p = omero.sys.Parameters()
1644 p.map = {}
1645 f = omero.sys.Filter()
1646 f.ownerId = rlong(self.getEventContext().userId)
1647 f.limit = rint(10)
1648 p.theFilter = f
1649 for e in tm.getMostRecentShareCommentLinks(p, self.SERVICE_OPTS):
1650 yield ShareWrapper(self, e.parent)
1651
1670
1690
1710
1712 """
1713 Retrieve given data objects by the given period of time
1714 controlled by the security system.
1715
1716 @param start Starting data
1717 @type start Long
1718 @param end Finishing data
1719 @type end Long
1720 @param otype Data type: Project, Dataset, Image
1721 @type otype String
1722 @return: Map of project, dataset and image lists
1723 @rtype: Map
1724 """
1725 tm = self.getTimelineService()
1726
1727 p = omero.sys.ParametersI()
1728 p.exp(eid)
1729 if page is not None:
1730 p.page(((int(page)-1)*settings.PAGE), settings.PAGE)
1731 else:
1732 p.page(None, 100)
1733
1734 im_list = list()
1735 ds_list = list()
1736 pr_list = list()
1737
1738 if otype is not None and otype in ("Image", "Dataset", "Project"):
1739 otype = otype.title()
1740 for e in tm.getByPeriod([otype], rtime(long(start)), rtime(long(end)), p, True, self.SERVICE_OPTS)[otype]:
1741 wrapper = KNOWN_WRAPPERS.get(otype.title(), None)
1742 im_list.append(wrapper(self, e))
1743 else:
1744 res = tm.getByPeriod(['Image', 'Dataset', 'Project'], rtime(long(start)), rtime(long(end)), p, True, self.SERVICE_OPTS)
1745 try:
1746 for e in res['Image']:
1747 im_list.append(ImageWrapper(self, e))
1748 except:
1749 pass
1750 try:
1751 for e in res['Dataset']:
1752 ds_list.append(DatasetWrapper(self, e))
1753 except:
1754 pass
1755 try:
1756 for e in res['Project']:
1757 pr_list.append(ProjectWrapper(self, e))
1758 except:
1759 pass
1760 return {'project': pr_list, 'dataset':ds_list, 'image':im_list}
1761
1763 """
1764 Counts given data objects by the given period of time
1765 controlled by the security system.
1766
1767 @param start Starting data
1768 @type start Long
1769 @param end Finishing data
1770 @type end Long
1771 @param otype Data type: Project, Dataset, Image
1772 @type otype String
1773 @return: Counter
1774 @rtype: Long
1775 """
1776 tm = self.getTimelineService()
1777 p = omero.sys.Parameters()
1778 p.map = {}
1779 f = omero.sys.Filter()
1780 f.ownerId = rlong(eid)
1781
1782 p.theFilter = f
1783 if otype == 'image':
1784 return tm.countByPeriod(['Image'], rtime(long(start)), rtime(long(end)), p, self.SERVICE_OPTS)['Image']
1785 elif otype == 'dataset':
1786 return tm.countByPeriod(['Dataset'], rtime(long(start)), rtime(long(end)), p, self.SERVICE_OPTS)['Dataset']
1787 elif otype == 'project':
1788 return tm.countByPeriod(['Project'], rtime(long(start)), rtime(long(end)), p, self.SERVICE_OPTS)['Project']
1789 else:
1790 c = tm.countByPeriod(['Image', 'Dataset', 'Project'], rtime(long(start)), rtime(long(end)), p, self.SERVICE_OPTS)
1791 return c['Image']+c['Dataset']+c['Project']
1792
1794 """
1795 Retrieve event log objects by the given period of time
1796 controlled by the security system.
1797
1798 @param start Starting data
1799 @type start Long
1800 @param end Finishing data
1801 @type end Long
1802 @return: List of event logs
1803 @rtype: List
1804 """
1805 tm = self.getTimelineService()
1806 p = omero.sys.Parameters()
1807 p.map = {}
1808 f = omero.sys.Filter()
1809 f.limit = rint(100000)
1810 try:
1811 f.groupId = rlong(self.SERVICE_OPTS.getOmeroGroup())
1812 except:
1813 f.groupId = rlong(self.getEventContext().groupId)
1814 f.ownerId = rlong(eid or self.getEventContext().userId)
1815 p.theFilter = f
1816 service_opts = self.createServiceOptsDict()
1817 service_opts.setOmeroGroup(str(f.groupId.val))
1818 return tm.getEventLogsByPeriod(rtime(start), rtime(end), p, service_opts)
1819
1820
1821 omero.gateway.BlitzGateway = OmeroWebGateway
1822
1824 """
1825 Function or method wrapper that handles L{Ice.ObjectNotExistException}
1826 by re-creating the server side proxy.
1827 """
1828
1830 if e.__class__ is Ice.ObjectNotExistException:
1831
1832
1833 logger.warn('Attempting to re-create proxy and re-call method.')
1834 try:
1835 self.proxyObjectWrapper._obj = \
1836 self.proxyObjectWrapper._create_func()
1837 func = getattr(self.proxyObjectWrapper._obj, self.attr)
1838 return func(*args, **kwargs)
1839 except Exception, e:
1840 self.debug(e.__class__.__name__, args, kwargs)
1841 raise
1842 else:
1843 super(OmeroWebSafeCallWrapper, self).handle_exception(
1844 e, *args, **kwargs)
1845
1846
1847 omero.gateway.SafeCallWrapper = OmeroWebSafeCallWrapper
1848
1850
1851 annotation_counter = None
1852
1854 l = self.listParents()
1855 if l is not None:
1856 return len(l)
1857
1876
1878 p = None
1879 if self.details.getPermissions() is None:
1880 return 'unknown'
1881 else:
1882 p = self.details.getPermissions()
1883 if p.isGroupWrite():
1884 flag = 'Read-Write'
1885 elif p.isGroupAnnotate():
1886 flag = 'Read-Annotate'
1887 elif p.isGroupRead():
1888 flag = 'Read-Only'
1889 elif p.isUserRead():
1890 flag = 'Private'
1891 else:
1892 flag = p
1893 return flag
1894
1896 """
1897 Warp name of the object if names is longer then 30 characters.
1898
1899 @return Warped string.
1900 """
1901
1902 try:
1903 l = len(self.name)
1904 if l < 30:
1905 return self.name
1906 elif l >= 30:
1907 splited = []
1908 for v in range(0,len(self.name),30):
1909 splited.append(self.name[v:v+30]+"\n")
1910 return "".join(splited)
1911 except:
1912 logger.info(traceback.format_exc())
1913 return self.name
1914
1916 """
1917 Returns a string that can be used as classes on an html element to
1918 indicate the permissions flags of the object. E.g. "canEdit canLink"
1919 Flags/classes are canEdit, canAnnotate, canLink, canDelete
1920 """
1921 flags = []
1922 if self.canEdit(): flags.append("canEdit")
1923 if self.canAnnotate(): flags.append("canAnnotate")
1924 if self.canLink(): flags.append("canLink")
1925 if self.canDelete(): flags.append("canDelete")
1926 if self.canChgrp(): flags.append("canChgrp")
1927 return " ".join(flags)
1928
1929
1931 """
1932 omero_model_ExperimenterI class wrapper overwrite omero.gateway.ExperimenterWrapper
1933 and extend OmeroWebObjectWrapper.
1934 """
1935
1936 ldapUser = None
1937
1942
1944 return self.omeName.lower() not in ('guest')
1945
1947 """
1948 Return DN of the specific experimenter if uses LDAP authentication
1949 (has set dn on password table) or None.
1950 @param eid: experimenter ID
1951 @type eid: L{Long}
1952 @return: Distinguished Name
1953 @rtype: String
1954 """
1955
1956 if self.ldapUser == None:
1957 admin_serv = self._conn.getAdminService()
1958 self.ldapUser = admin_serv.lookupLdapAuthExperimenter(self.id)
1959 return self.ldapUser
1960
1962 geMap = self.copyGroupExperimenterMap()
1963 if self.sizeOfGroupExperimenterMap() > 0 and geMap[0] is not None:
1964 return ExperimenterGroupWrapper(self._conn, geMap[0].parent)
1965 return None
1966
1968 for gem in self.copyGroupExperimenterMap():
1969 if gem is None:
1970 continue
1971 flag = False
1972 if gem.parent.name.val in excluded_names:
1973 flag = True
1974 if gem.parent.id.val in excluded_ids:
1975 flag = True
1976 if not flag:
1977 yield ExperimenterGroupWrapper(self._conn, gem.parent)
1978
1979 omero.gateway.ExperimenterWrapper = ExperimenterWrapper
1980
1982 """
1983 omero_model_ExperimenterGroupI class wrapper overwrite omero.gateway.ExperimenterGroupWrapper
1984 and extend OmeroWebObjectWrapper.
1985 """
1986
1988 return self.name.lower() not in ('guest', 'user')
1989
1991 """
1992 Returns lists of 'leaders' and 'members' of the specified group (default is current group)
1993 as a dict with those keys.
1994
1995 @return: {'leaders': list L{ExperimenterWrapper}, 'colleagues': list L{ExperimenterWrapper}}
1996 @rtype: dict
1997 """
1998 summary = self._conn.groupSummary(self.getId())
1999 self.leaders = summary["leaders"]
2000 self.leaders.sort(key=lambda x: x.getLastName().lower())
2001 self.colleagues = summary["colleagues"]
2002 self.colleagues.sort(key=lambda x: x.getLastName().lower())
2003
2005 for gem in self.copyGroupExperimenterMap():
2006 if gem is None:
2007 continue
2008 if gem.owner.val:
2009 yield ExperimenterWrapper(self._conn, gem.child)
2010
2016
2018 for gem in self.copyGroupExperimenterMap():
2019 if gem is None:
2020 continue
2021 flag = False
2022 if gem.child.omeName.val in excluded_omename:
2023 flag = True
2024 if gem.parent.id.val in excluded_ids:
2025 flag = True
2026 if not flag:
2027 yield ExperimenterWrapper(self._conn, gem.child)
2028
2030 if self.name == "user":
2031 return True
2032 elif self.name == "system":
2033 return True
2034 elif self.name == "guest":
2035 return True
2036 else:
2037 False
2038
2039 omero.gateway.ExperimenterGroupWrapper = ExperimenterGroupWrapper
2040
2041 -class ProjectWrapper (OmeroWebObjectWrapper, omero.gateway.ProjectWrapper):
2042 """
2043 omero_model_ProjectI class wrapper overwrite omero.gateway.ProjectWrapper
2044 and extend OmeroWebObjectWrapper.
2045 """
2046
2047 annotation_counter = None
2048
2053
2054 omero.gateway.ProjectWrapper = ProjectWrapper
2055
2056 -class DatasetWrapper (OmeroWebObjectWrapper, omero.gateway.DatasetWrapper):
2057 """
2058 omero_model_DatasetI class wrapper overwrite omero.gateway.DatasetWrapper
2059 and extends OmeroWebObjectWrapper.
2060 """
2061
2062 annotation_counter = None
2063
2070
2071 omero.gateway.DatasetWrapper = DatasetWrapper
2072
2073 -class ImageWrapper (OmeroWebObjectWrapper, omero.gateway.ImageWrapper):
2074 """
2075 omero_model_ImageI class wrapper overwrite omero.gateway.ImageWrapper
2076 and extends OmeroWebObjectWrapper.
2077 """
2078
2079 annotation_counter = None
2080
2087
2088 """
2089 This override standard omero.gateway.ImageWrapper.getChannels
2090 and catch exceptions.
2091 """
2098
2100 """
2101 This determines whether we want to show the paths of
2102 Original Imported Files.
2103 """
2104 return False
2105
2107 """
2108 Until we update the BlitzGateway to use the newer
2109 getImportedImageFiles() method, we must delegate to
2110 the older getArchivedFiles() method.
2111 """
2112 return super(ImageWrapper, self).getArchivedFiles()
2113
2115 """
2116 Until we update the BlitzGateway to use the newer
2117 countImportedImageFiles() method, we must delegate to
2118 the older countArchivedFiles() method.
2119 """
2120 return super(ImageWrapper, self).countArchivedFiles()
2121
2122 omero.gateway.ImageWrapper = ImageWrapper
2123
2124 -class PlateWrapper (OmeroWebObjectWrapper, omero.gateway.PlateWrapper):
2125
2126 """
2127 omero_model_PlateI class wrapper overwrite omero.gateway.PlateWrapper
2128 and extends OmeroWebObjectWrapper.
2129 """
2130
2131 annotation_counter = None
2132
2139
2140 omero.gateway.PlateWrapper = PlateWrapper
2141
2142 -class WellWrapper (OmeroWebObjectWrapper, omero.gateway.WellWrapper):
2143 """
2144 omero_model_ImageI class wrapper overwrite omero.gateway.ImageWrapper
2145 and extends OmeroWebObjectWrapper.
2146 """
2147
2148 annotation_counter = None
2149
2156
2157 omero.gateway.WellWrapper = WellWrapper
2158
2160
2161 """
2162 omero_model_PlateI class wrapper overwrite omero.gateway.PlateWrapper
2163 and extends OmeroWebObjectWrapper.
2164 """
2165
2166 annotation_counter = None
2167
2172
2173 omero.gateway.PlateAcquisitionWrapper = PlateAcquisitionWrapper
2174
2175 -class ScreenWrapper (OmeroWebObjectWrapper, omero.gateway.ScreenWrapper):
2176 """
2177 omero_model_ScreenI class wrapper overwrite omero.gateway.ScreenWrapper
2178 and extends OmeroWebObjectWrapper.
2179 """
2180
2181 annotation_counter = None
2182
2187
2188 omero.gateway.ScreenWrapper = ScreenWrapper
2189
2191 """
2192 omero_model_EventLogI class wrapper extends omero.gateway.BlitzObjectWrapper.
2193 """
2194
2195 LINK_CLASS = "EventLog"
2196
2198 """
2199 omero_model_ShareI class wrapper extends BlitzObjectWrapper.
2200 """
2201
2203 if self.itemCount == 0:
2204 return "Discussion"
2205 else:
2206 return "Share"
2207
2209 if self.itemCount == 0:
2210 return True
2211 return False
2212
2214 """
2215 Gets the end date for the share
2216
2217 @return: End Date-time
2218 @rtype: datetime object
2219 """
2220
2221
2222 try:
2223 d = self.started+self.timeToLive
2224 if d > 2051222400000:
2225 return datetime(2035, 1, 1, 0, 0, 0)
2226 return datetime.fromtimestamp(d / 1000)
2227 except:
2228 logger.info(traceback.format_exc())
2229 return None
2230
2232 """
2233 Gets the start date of the share
2234
2235 @return: Start Date-time
2236 @rtype: datetime object
2237 """
2238
2239 return datetime.fromtimestamp(self.getStarted()/1000)
2240
2242 """
2243 Returns True if we are past the end date of the share
2244
2245 @return: True if share expired
2246 @rtype: Boolean
2247 """
2248
2249
2250 now = time.time()
2251 try:
2252 d = long(self.started+self.timeToLive)
2253 if (d / 1000) > now:
2254 return False
2255 return True
2256 except:
2257 logger.info(traceback.format_exc())
2258 return None
2259
2261 """
2262 Returns True if share is owned by the current user
2263
2264 @return: True if owned
2265 @rtype: Boolean
2266 """
2267
2268 try:
2269 if self.owner.id.val == self._conn.getEventContext().userId:
2270 return True
2271 except:
2272 logger.error(traceback.format_exc())
2273 return False
2274
2276 """
2277 The owner of this share
2278
2279 @return: Owner
2280 @rtype: L{ExperimenterWrapper}
2281 """
2282
2283 return omero.gateway.ExperimenterWrapper(self._conn, self.owner)
2284
2285 omero.gateway.refreshWrappers()
2286