def getContext(self): """ Get a list of folders with given search parameters. Currently accepted search modes are: 1. Searching by parentId and parentType, with optional additional filtering by the name field (exact match) or using full text search within a single parent folder. Pass a "name" parameter or "text" parameter to invoke these additional filters. 2. Searching with full text search across all folders in the system. Simply pass a "text" parameter for this mode. """ context = FolderModel().findOne({ 'name': 'JSON-LD', 'parentCollection': 'collection', 'parentId': CollectionModel().findOne({ 'name': 'Context' }).get('_id') }) if context: return (context.get('meta', {})) user = self.getCurrentUser() context = FolderModel().setMetadata( folder=FolderModel().createFolder( parent=CollectionModel().createCollection( name="Context", creator=user, public=True, reuseExisting=True ), name="JSON-LD", parentType='collection', public=True, creator=user, reuseExisting=True ), metadata={ "@context": { "@language": "en-US", "@base": rest.getApiUrl(), "reprolib": REPROLIB_CANONICAL, "http://schema.org/url": { "@type": "@id" } } } ) return (context.get('meta', {}))
def getSkin(lang="en-US"): """ Function to return the context for the current instance. :param language: ISO language string, optional :type language: None :returns: context dict """ contextCollection = CollectionModel().findOne({'name': 'Context'}) skinFolder = FolderModel().findOne({ 'name': 'Skin', 'parentCollection': 'collection', 'parentId': contextCollection.get('_id') }) if contextCollection else None defaultSkin = { 'name': '', 'colors': { 'primary': '#000000', 'secondary': '#FFFFFF' }, 'about': '' } skin = skinFolder.get( 'meta', defaultSkin) if skinFolder is not None else defaultSkin for s in ['name', 'about']: lookup = jsonld_expander.getByLanguage( skin.get(s, ""), lang if lang and lang not in ["@context.@language", ""] else None) skin[s] = lookup if lookup and lookup not in [ None, [{}], ] else jsonld_expander.getByLanguage(skin[s], None) skin[s] = jsonld_expander.fileObjectToStr(skin[s][0]) if isinstance( skin[s], list) and len(skin[s]) else skin[s] return (skin)
def getModelCollection(modelType): """ Returns the Collection named for the given modelType, creating if not already extant. :param modelType: 'activity', 'screen', etc. :type modelType: str :returns: dict """ from girderformindlogger.models import pluralize name = pluralize(modelType).title() collection = CollectionModel().findOne({'name': name}) if not collection: collection = CollectionModel().createCollection(name=name, public=True, reuseExisting=True) return (collection)
def afterPostPutCollection(event): # This will only trigger if no exceptions (for access, invalid id, etc.) are thrown extraParams = event.info['params'] if 'terms' in extraParams: collectionResponse = event.info['returnVal'] collectionId = collectionResponse['_id'] terms = extraParams['terms'] CollectionModel().update({'_id': collectionId}, {'$set': { 'terms': terms }}) collectionResponse['terms'] = terms event.addResponse(collectionResponse)
def __init__(self): super(Collection, self).__init__() self.resourceName = 'collection' self._model = CollectionModel() self.route('DELETE', (':id',), self.deleteCollection) self.route('GET', (), self.find) self.route('GET', (':id',), self.getCollection) self.route('GET', (':id', 'details'), self.getCollectionDetails) self.route('GET', ('details',), self.getCollectionsDetails) self.route('GET', (':id', 'download'), self.downloadCollection) self.route('GET', (':id', 'access'), self.getCollectionAccess) self.route('POST', (), self.createCollection) self.route('PUT', (':id',), self.updateCollection) self.route('PUT', (':id', 'access'), self.updateCollectionAccess) self.route('PUT', (':id', 'metadata'), self.setMetadata) self.route('DELETE', (':id', 'metadata'), self.deleteMetadata)
def getByLanguage(object, tag=None): """ Function to get a value or IRI by a language tag following https://tools.ietf.org/html/bcp47. :param object: The JSON-LD Object to language-parse :type object: dict or list :param tag: The language tag to use. :type tag: str :returns: str, either a literal or an IRI. """ if not tag: from girderformindlogger.api.v1.context import Context tag = FolderModel().findOne({ 'name': 'JSON-LD', 'parentCollection': 'collection', 'parentId': CollectionModel().findOne({ 'name': 'Context' }).get('_id') }) tag = tag.get('meta', {}).get('@context', {}).get('@language') if tag else None if isinstance(tag, str): tags = getMoreGeneric(tag) tags = tags + ["@{}".format(t) for t in tags] tags.sort(key=len, reverse=True) if isinstance(object, dict): return (getFromLongestMatchingKey(object, tags, caseInsensitive=True)) if isinstance(object, list): return ([ getFromLongestMatchingValue(objectList=object, listOfValues=tags, keyToMatch='@language', caseInsensitive=True) ]) if isinstance(object, str): return (object)
def load(self, info): # Augment the collection creation and edit routes to accept a terms field events.bind('rest.post.collection.after', 'terms', afterPostPutCollection) events.bind('rest.put.collection/:id.after', 'terms', afterPostPutCollection) for handler in [ Collection.createCollection, Collection.updateCollection ]: handler.description.param('terms', 'The Terms of Use for the collection.', required=False) # Expose the terms field on all collections CollectionModel().exposeFields(level=AccessType.READ, fields={'terms'}) # Add endpoint for registered users to accept terms info['apiRoot'].collection.route('POST', (':id', 'acceptTerms'), acceptCollectionTerms) # Expose the terms field on all users User().exposeFields(level=AccessType.ADMIN, fields={'terms'})
def createApplet(self, name, protocol={}, user=None, roles=None, constraints=None): """ Method to create an Applet. :param name: Name for the Applet :type name: str :param protocol: Protocol to link to this Applet, with one or both keys: {`_id`, `url`} :type protocol: dict :param user: User creating Applet :type user: dict :param roles: Roles to set to this Applet :type roles: dict or None :param constraints: Constraints to set to this Applet :type constraints: dict or None """ from girderformindlogger.utility import jsonld_expander if user == None: raise AccessException("You must be logged in to create an applet.") appletsCollection = CollectionModel().findOne({"name": "Applets"}) # create the Applets collection if it isn't there! if not appletsCollection: CollectionModel().createCollection('Applets') appletsCollection = CollectionModel().findOne({"name": "Applets"}) # create new applet applet = self.setMetadata( folder=self.createFolder(parent=appletsCollection, name=name, parentType='collection', public=True, creator=user, allowRename=True), metadata={ 'protocol': protocol, 'applet': constraints if constraints is not None and isinstance(constraints, dict) else {} }) appletGroupName = "Default {} ({})".format(name, str(applet.get('_id', ''))) print("Name: {}".format(appletGroupName)) # Create user groups for role in USER_ROLES.keys(): try: group = GroupModel().createGroup( name="{} {}s".format(appletGroupName, role.title()), creator=user, public=False if role == 'user' else True) except ValidationException: numero = 0 numberedName = appletGroupName while GroupModel().findOne(query={'name': numberedName}): numero += 1 numberedName = "{} {} {}s".format(appletGroupName, str(numero), role.title()) group = GroupModel().createGroup( name=numberedName, creator=user, public=False if role == 'user' else True) self.setGroupRole(doc=applet, group=group, role=role, currentUser=user, force=False) return (jsonld_expander.formatLdObject(applet, 'applet', user))
def _invite(applet, user, role, rsvp, subject): """ Helper function to invite a user to an applet. :param applet: Applet to invite user to :type applet: AppletModel :param user: ID (canonical or applet-specific) or email address of user to invite :type user: string :param role: Role to invite user to :type role: string :param rsvp: Require user acceptance? :type rsvp: boolean :param subject: Subject about 'user' role can inform or about which 'reviewer' role can review :type subject: string or literal :returns: New assignment (dictionary) """ if role not in USER_ROLE_KEYS: raise ValidationException('Invalid role.', 'role') thisUser = Applet().getCurrentUser() user = user if user else str(thisUser['_id']) if mail_utils.validateEmailAddress(user): user = UserModel().hash(user) if bool(rsvp): groupName = {'title': '{} {}s'.format(str(applet.get('_id')), role)} groupName['lower'] = groupName.get('title', '').lower() group = GroupModel().findOne(query={'lowerName': groupName['lower']}) if not group or group is None: group = GroupModel().createGroup( name=groupName['title'], creator=thisUser, public=bool(role in ['manager', 'reviewer'])) try: assignments = CollectionModel().createCollection(name="Assignments", public=True, reuseExisting=True) assignmentType = 'collection' except AccessException: assignments, assignmentType = selfAssignment() appletAssignment = list(FolderModel().childFolders( parent=assignments, parentType=assignmentType, user=thisUser, filters={ 'meta.applet.@id': str(applet['_id']) if '_id' in applet else None })) appletAssignment = appletAssignment[0] if len( appletAssignment) else FolderModel().setMetadata( FolderModel().createFolder( parent=assignments, name=FolderModel().preferredName(applet), parentType=assignmentType, public=False, creator=thisUser, allowRename=True, reuseExisting=False), { 'applet': { '@id': str(applet['_id']) if '_id' in applet else None } }) meta = appletAssignment.get('meta', {}) members = meta.get('members', []) if meta.get('members') is not None else [] cUser = getUserCipher(appletAssignment, user) subject = subject.upper() if subject is not None and subject.upper( ) in SPECIAL_SUBJECTS else getUserCipher( appletAssignment, str(thisUser['_id']) if subject is None else subject) thisAppletAssignment = { '@id': str(cUser), 'roles': { role: True if role not in ['reviewer', 'user'] else [subject] } } for i, u in enumerate(members): if '@id' in u and u["@id"] == str(cUser): thisAppletAssignment = members.pop(i) if 'roles' not in thisAppletAssignment: thisAppletAssignment['roles'] = {} thisAppletAssignment['roles'][role] = True if role not in [ 'reviewer', 'user' ] else [subject] if (subject in SPECIAL_SUBJECTS) or ( 'reviewer' not in thisAppletAssignment['roles']) else list( set(thisAppletAssignment['roles']['reviewer'] + [subject]).difference(set(SPECIAL_SUBJECTS)) ) if "ALL" not in thisAppletAssignment['roles'][ 'reviewer'] else ["ALL"] members.append(thisAppletAssignment) meta['members'] = members appletAssignment = FolderModel().setMetadata(appletAssignment, meta) authorizeReviewers(appletAssignment) return (appletAssignment)
def createApplet(self, name, protocol={}, user=None, roles=None, constraints=None, appletName=None): """ Method to create an Applet. :param name: Name for the Applet :type name: str :param protocol: Protocol to link to this Applet, with one or both keys: {`_id`, `url`} :type protocol: dict :param user: User creating Applet :type user: dict :param roles: Roles to set to this Applet :type roles: dict or None :param constraints: Constraints to set to this Applet :type constraints: dict or None """ from girderformindlogger.utility import jsonld_expander if user == None: raise AccessException("You must be logged in to create an applet.") appletsCollection = CollectionModel().findOne({"name": "Applets"}) # create the Applets collection if it isn't there! if not appletsCollection: CollectionModel().createCollection('Applets') appletsCollection = CollectionModel().findOne({"name": "Applets"}) appletName = self.validateAppletName(appletName, appletsCollection, user) # create new applet applet = self.setMetadata( folder=self.createFolder(parent=appletsCollection, name=name, parentType='collection', public=True, creator=user, allowRename=True, appletName=appletName), metadata={ 'protocol': protocol, 'applet': constraints if constraints is not None and isinstance(constraints, dict) else {} }) appletGroupName = "Default {} ({})".format(name, str(applet.get('_id', ''))) print("Name: {}".format(appletGroupName)) # Create user groups role2AccessLevel = { 'user': AccessType.READ, 'coordinator': AccessType.ADMIN, 'manager': AccessType.ADMIN, 'editor': AccessType.WRITE, 'reviewer': AccessType.READ } accessList = applet.get('access', {}) accessList['groups'] = [] for role in USER_ROLES.keys(): try: group = GroupModel().createGroup( name="{} {}s".format(appletGroupName, role.title()), creator=user, public=False if role == 'user' else True) accessList['groups'].append({ 'id': ObjectId(group['_id']), 'level': role2AccessLevel[role] }) except ValidationException: numero = 0 numberedName = appletGroupName while GroupModel().findOne(query={'name': numberedName}): numero += 1 numberedName = "{} {} {}s".format(appletGroupName, str(numero), role.title()) group = GroupModel().createGroup( name=numberedName, creator=user, public=False if role == 'user' else True) self.setGroupRole(doc=applet, group=group, role=role, currentUser=user, force=False) self.setAccessList(applet, accessList) self.update({'_id': ObjectId(applet['_id'])}, {'$set': { 'access': applet.get('access', {}) }}) from girderformindlogger.models.profile import Profile # give all roles to creator of an applet profile = Profile().createProfile(applet, user, 'manager') profile = Profile().load(profile['_id'], force=True) profile['roles'] = list(USER_ROLES.keys()) Profile().save(profile, False) UserModel().appendApplet(UserModel().load(user['_id'], force=True), applet['_id'], USER_ROLES.keys()) return (jsonld_expander.formatLdObject(applet, 'applet', user, refreshCache=False))