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(self): skinFolder = Folder().findOne({ 'name': 'Skin', 'parentCollection': 'collection', 'parentId': Collection().findOne({ 'name': 'Context' }).get('_id') }) blankSkin = { 'name': '', 'colors': { 'primary': '#000000', 'secondary': '#FFFFFF' }, 'about': '' } skin = skinFolder.get('meta', blankSkin) ab = getByLanguage(skin.get('about')) dSkin = { "about": ab if isinstance(ab, str) else ab.get('@value', ab.get('@id', '')) if isinstance(ab, dict) else '', "colors": skin.get('colors', blankSkin.get('colors')), "name": getByLanguage(skin.get('name')) } return (dSkin)
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 createHistoryFolders(self, protocolId, user): protocol = self.load(protocolId, force=True) updated = False # add folder to save historical data if not protocol['meta'].get('historyId', None): historyFolder = FolderModel().createFolder(name='history of ' + protocol['name'], parent=protocol, parentType='folder', public=False, creator=user, allowRename=True, reuseExisting=False) protocol['meta']['historyId'] = historyFolder['_id'] updated = True else: historyFolder = FolderModel().load(protocol['meta']['historyId'], force=True) if not historyFolder.get('meta', {}).get('referenceId', None): referencesFolder = FolderModel().createFolder( name='reference of history data for ' + protocol['name'], parent=historyFolder, parentType='folder', public=False, creator=user, allowRename=True, reuseExisting=False, ) historyFolder = FolderModel().setMetadata( historyFolder, {'referenceId': referencesFolder['_id']}) else: referencesFolder = FolderModel().load( historyFolder['meta']['referenceId'], force=True) # add folder to save contents if not protocol['meta'].get('contentId', None): contentFolder = FolderModel().createFolder(name='content of ' + protocol['name'], parent=protocol, parentType='folder', public=False, creator=user, allowRename=True, reuseExisting=False) protocol['meta']['contentId'] = contentFolder['_id'] updated = True if updated: protocol = self.setMetadata(protocol, protocol['meta']) return (historyFolder, referencesFolder)
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 _virtualChildItems(self, event): params = event.info['params'] if 'folderId' not in params: return # This is not a child listing request user = self.getCurrentUser() folder = Folder().load(params['folderId'], user=user, level=AccessType.READ) if not folder.get('isVirtual') or 'virtualItemsQuery' not in folder: return # Parent is not a virtual folder, proceed as normal limit, offset, sort = self.getPagingParameters(params, defaultSortField='name') q = json_util.loads(folder['virtualItemsQuery']) if 'virtualItemsSort' in folder: sort = json.loads(folder['virtualItemsSort']) item = Item() # These items may reside in folders that the user cannot read, so we must filter items = item.filterResultsByPermission( item.find(q, sort=sort), user, level=AccessType.READ, limit=limit, offset=offset) event.preventDefault().addResponse([item.filter(i, user) for i in items])
def _validateFolder(event): doc = event.info if 'isVirtual' in doc and not isinstance(doc['isVirtual'], bool): raise ValidationException('The isVirtual field must be boolean.', field='isVirtual') if doc.get('isVirtual'): # Make sure it doesn't have children if list(Folder().childItems(doc, limit=1)): raise ValidationException( 'Virtual folders may not contain child items.', field='isVirtual') if list(Folder().find({ 'parentId': doc['_id'], 'parentCollection': 'folder' }, limit=1)): raise ValidationException( 'Virtual folders may not contain child folders.', field='isVirtual') if doc['parentCollection'] == 'folder': parent = Folder().load(event.info['parentId'], force=True, exc=True) if parent.get('isVirtual'): raise ValidationException( 'You may not place folders under a virtual folder.', field='folderId') if 'virtualItemsQuery' in doc: try: json.loads(doc['virtualItemsQuery']) except (TypeError, ValueError): raise ValidationException( 'The virtual items query must be valid JSON.', field='virtualItemsQuery') if 'virtualItemsSort' in doc: try: json.loads(doc['virtualItemsSort']) except (TypeError, ValueError): raise ValidationException( 'The virtual items sort must be valid JSON.', field='virtualItemsSort')
def load(self, user, level=AccessType.ADMIN, reviewer=None, force=False, applet=None, subject=None): """ We override load in order to ensure the folder has certain fields within it, and if not, we add them lazily at read time. :param user: The user for whom to get the ResponseFolder. :type id: dict :param reviewer: The user to check access against. :type user: dict or None :param level: The required access type for the object. :type level: AccessType :param reviewer: The user trying to see the data. :type reviewer: dict :param applet: ID of Applet to which we are loading responses. "Responses" Folder containing all such Folders if None. :type applet: str or None :param subject: Applet-specific ID for response subject if getting responses about a specific subject. :type subject: str or None :returns: Folder or list of Folders """ responseFolder = Folder().load(id=Folder().createFolder( parent=user, parentType='user', name='Responses', creator=user, reuseExisting=True, public=False).get('_id'), user=reviewer, level=AccessType.READ) accessList = Folder().getFullAccessList(responseFolder) accessList = { k: [{ "id": i.get('id'), "level": AccessType.ADMIN if i.get('id') == str(user.get('_id')) else i.get('level') } for i in accessList[k]] for k in accessList } if str(user.get('_id')) not in [ u.get('id') for u in accessList.get('users', []) ]: accessList.get('users', {}).append({ "id": str(user.get('_id')), "level": AccessType.ADMIN }) Folder().setAccessList(responseFolder, accessList) if applet: responseFolders = [] allResponseFolders = list(Folder().childFolders( parent=responseFolder, parentType='folder', user=reviewer)) subjectResponseFolders = list( itertools.chain.from_iterable([ list(Folder().childFolders(parent=appletResponsesFolder, parentType='folder', user=reviewer)) for appletResponsesFolder in allResponseFolders ])) if subject: assignments = Assignment().findAssignments(applet.get('_id')) subjectFilter = [ getUserCipher(appletAssignment, subject) for appletAssignment in assignments ] subjectResponseFolders = [ sRF for sRF in subjectResponseFolders if sRF.get('name') in subjectFilter or srf.get('subject', {}).get('@id') in subjectFilter ] responseFolders += list(Folder().find({ '$and': [{ '$or': [{ 'meta.applet.@id': str(applet) }, { 'meta.applet.url': str(applet) }] }, { '$or': [{ 'parentId': parent['_id'] } for parent in subjectResponseFolders] }] })) if len(responseFolders) == 1: return (responseFolders[0]) else: return (responseFolders) return (responseFolder)
def getHistoryDataFromItemIRIs(self, protocolId, IRIGroup): from girderformindlogger.models.item import Item as ItemModel from girderformindlogger.utility import jsonld_expander protocol = self.load(protocolId, force=True) items = {} activities = {} itemReferences = {} result = { 'items': items, 'activities': activities, 'itemReferences': itemReferences } if 'historyId' not in protocol.get('meta', {}): return result historyFolder = FolderModel().load(protocol['meta']['historyId'], force=True) if 'referenceId' not in historyFolder.get('meta', {}): return result referencesFolder = FolderModel().load( historyFolder['meta']['referenceId'], force=True) itemModel = ItemModel() for IRI in IRIGroup: reference = itemModel.findOne({ 'folderId': referencesFolder['_id'], 'meta.identifier': IRI }) if not reference: continue history = reference['meta']['history'] for version in IRIGroup[IRI]: if version not in itemReferences: itemReferences[version] = {} inserted = False for i in range(0, len(history)): if self.compareVersions(version, history[i]['version']) <= 0: if not history[i].get('reference', None): continue if history[i]['reference'] not in items: (modelType, referenceId) = history[i]['reference'].split('/') model = MODELS()[modelType]().findOne( {'_id': ObjectId(referenceId)}) items[history[i] ['reference']] = jsonld_expander.loadCache( model['cached']) activityId = str(model['meta']['activityId']) if activityId not in activities: activities[ activityId] = jsonld_expander.loadCache( FolderModel().load( activityId, force=True)['cached']) if history[i]['reference']: itemReferences[version][IRI] = history[i][ 'reference'] inserted = True break if not inserted: itemReferences[version][ IRI] = None # this is same as latest version return result
def cycleModels(IRIset, modelType=None, meta={}): from girderformindlogger.constants import HIERARCHY, REPROLIB_TYPES from girderformindlogger.models.folder import Folder as FolderModel from girderformindlogger.models.item import Item as ItemModel from girderformindlogger.utility.jsonld_expander import reprolibCanonize cachedDoc = None primary = [modelType] if isinstance( modelType, str) else [] if modelType is None else modelType secondary = [m for m in HIERARCHY if m not in primary] del modelType if len(primary): query = { '$and': [ { # search by type '$or': [{ 'meta.{}.@type'.format(modelType): { "$in": [ t for t in [ reprolibCanonize(REPROLIB_TYPES[modelType] ), 'reproschema:{}'. format(suffix), 'reprolib:{}'.format( suffix), 'reprolib:schemas/{}'.format( suffix), suffix ] if t is not None ] for suffix in [REPROLIB_TYPES[modelType].split('/')[-1]] } } for modelType in primary if modelType in REPROLIB_TYPES] }, { # search by url '$or': [{ 'meta.{}.url'.format(modelType): { '$in': list(IRIset) } } for modelType in primary if modelType in REPROLIB_TYPES] }, *[{ 'meta.{}'.format(key): meta[key] } for key in meta] ] } cachedDoc = (FolderModel() if not any(['screen' in primary, 'item' in primary]) else ItemModel()).findOne(query) if cachedDoc is None: query = { '$and': [{ '$or': [{ 'meta.{}.@type'.format(modelType): { "$in": [ t for t in [ reprolibCanonize(REPROLIB_TYPES[modelType]), 'reproschema:{}'.format( suffix), 'reprolib:{}'.format(suffix), 'reprolib:schemas/{}'.format(suffix), suffix ] if t is not None ] for suffix in [REPROLIB_TYPES[modelType].split('/')[-1]] } } for modelType in secondary if modelType in REPROLIB_TYPES] }, { '$or': [{ 'meta.{}.url'.format(modelType): { '$in': list(IRIset) } } for modelType in secondary if modelType in REPROLIB_TYPES] }, *[{ 'meta.{}'.format(key): meta[key] } for key in meta]] } cachedDoc = FolderModel().findOne(query) if cachedDoc is None: cachedDoc = ItemModel().findOne(query) if cachedDoc is None: return (None, None) modelType = [ rt for rt in list(REPROLIB_TYPES.keys()) if '@type' in cachedDoc.get('meta', {}).get(rt, {}) ] modelType = modelType[0] if len(modelType) else None print("Found {}/{}".format(modelType, str(cachedDoc['_id']))) return (modelType, cachedDoc)
def _validateItem(event): parent = Folder().load(event.info['folderId'], force=True, exc=True) if parent.get('isVirtual'): raise ValidationException( 'You may not place items under a virtual folder.', field='folderId')