Exemple #1
0
    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', {}))
Exemple #2
0
 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)
Exemple #3
0
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)
Exemple #4
0
    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')
Exemple #8
0
    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)
Exemple #9
0
    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
Exemple #10
0
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)
Exemple #11
0
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')