Exemple #1
0
    def countFolders(self, collection, user=None, level=None):
        """
        Returns the number of top level folders under this collection. Access
        checking is optional; to circumvent access checks, pass ``level=None``.

        :param collection: The collection.
        :type collection: dict
        :param user: If performing access checks, the user to check against.
        :type user: dict or None
        :param level: The required access level, or None to return the raw
            top-level folder count.
        """
        from girderformindlogger.models.folder import Folder

        fields = () if level is None else ('access', 'public')

        folderModel = Folder()
        folders = folderModel.findWithPermissions(
            {
                'parentId': collection['_id'],
                'parentCollection': 'collection'
            },
            fields=fields,
            user=user,
            level=level)

        return folders.count()
Exemple #2
0
    def _addDefaultFolders(self, event):
        """
        This callback creates "Public" and "Private" folders on a user, after
        it is first created.

        This generally should not be called or overridden directly, but it may
        be unregistered from the `model.user.save.created` event.
        """
        from girderformindlogger.models.folder import Folder
        from girderformindlogger.models.setting import Setting

        if Setting().get(SettingKey.USER_DEFAULT_FOLDERS) == 'public_private':
            user = event.info

            publicFolder = Folder().createFolder(user,
                                                 'Public',
                                                 parentType='user',
                                                 public=True,
                                                 creator=user)
            privateFolder = Folder().createFolder(user,
                                                  'Private',
                                                  parentType='user',
                                                  public=False,
                                                  creator=user)
            # Give the user admin access to their own folders
            Folder().setUserAccess(publicFolder,
                                   user,
                                   AccessType.ADMIN,
                                   save=True)
            Folder().setUserAccess(privateFolder,
                                   user,
                                   AccessType.ADMIN,
                                   save=True)
Exemple #3
0
    def subtreeCount(self, doc, includeItems=True, user=None, level=None):
        """
        Return the size of the folders within the collection.  The collection
        is counted as well.

        :param doc: The collection.
        :param includeItems: Whether items should be included in the count.
        :type includeItems: bool
        :param user: If filtering by permission, the user to filter against.
        :param level: If filtering by permission, the required permission level.
        :type level: AccessLevel
        """
        from girderformindlogger.models.folder import Folder

        count = 1
        folderModel = Folder()
        folders = folderModel.findWithPermissions(
            {
                'parentId': doc['_id'],
                'parentCollection': 'collection'
            },
            fields='access',
            user=user,
            level=level)

        count += sum(
            folderModel.subtreeCount(
                folder, includeItems=includeItems, user=user, level=level)
            for folder in folders)
        return count
Exemple #4
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)
    def parentsToRoot(self, item, user=None, force=False):
        """
        Get the path to traverse to a root of the hierarchy.

        :param item: The item whose root to find
        :type item: dict
        :param user: The user making the request (not required if force=True).
        :type user: dict or None
        :param force: Set to True to skip permission checking. If False, the
            returned models will be filtered.
        :type force: bool
        :returns: an ordered list of dictionaries from root to the current item
        """
        from girderformindlogger.models.folder import Folder

        folderModel = Folder()
        curFolder = folderModel.load(item['profileId'],
                                     user=user,
                                     level=AccessType.READ,
                                     force=force)
        profileIdsToRoot = folderModel.parentsToRoot(curFolder,
                                                     user=user,
                                                     level=AccessType.READ,
                                                     force=force)

        if force:
            profileIdsToRoot.append({'type': 'folder', 'object': curFolder})
        else:
            filteredFolder = folderModel.filter(curFolder, user)
            profileIdsToRoot.append({
                'type': 'folder',
                'object': filteredFolder
            })

        return profileIdsToRoot
Exemple #6
0
    def setUp(self):
        base.TestCase.setUp(self)

        self.admin = User().createUser(email='*****@*****.**',
                                       login='******',
                                       lastName='admin',
                                       firstName='admin',
                                       password='******',
                                       admin=True)
        self.user = User().createUser(email='*****@*****.**',
                                      login='******',
                                      lastName='u',
                                      firstName='u',
                                      password='******')

        self.f1 = Folder().createFolder(self.admin,
                                        'f1',
                                        creator=self.admin,
                                        parentType='user')
        self.f2 = Folder().createFolder(self.admin,
                                        'f2',
                                        creator=self.admin,
                                        parentType='user')
        self.virtual = Folder().createFolder(self.user,
                                             'v',
                                             creator=self.user,
                                             parentType='user')
        self.virtual['isVirtual'] = True
Exemple #7
0
    def testRestEndpoint(self):
        def updateFolder(user):
            return self.request('/folder/%s' % self.f1['_id'],
                                method='PUT',
                                params={
                                    'isVirtual':
                                    True,
                                    'virtualItemsQuery':
                                    json.dumps({'foo': 'bar'}),
                                    'virtualItemsSort':
                                    json.dumps([('meta.someVal',
                                                 SortDir.DESCENDING)])
                                },
                                user=user)

        Folder().setUserAccess(self.f1,
                               self.user,
                               level=AccessType.ADMIN,
                               save=True)

        resp = updateFolder(self.user)
        self.assertStatus(resp, 403)
        self.assertEqual(resp.json['message'],
                         'Must be admin to setup virtual folders.')
        f1 = Folder().load(self.f1['_id'], force=True)
        self.assertNotIn('isVirtual', f1)
        self.assertNotIn('virtualItemsQuery', f1)
        self.assertNotIn('virtualItemsSort', f1)

        resp = updateFolder(self.admin)
        self.assertStatusOk(resp)
        self.assertTrue(Folder().load(self.f1['_id'], force=True)['isVirtual'])
Exemple #8
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 #9
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)
Exemple #10
0
    def fileList(self,
                 doc,
                 user=None,
                 path='',
                 includeMetadata=False,
                 subpath=True,
                 mimeFilter=None,
                 data=True):
        """
        This function generates a list of 2-tuples whose first element is the
        relative path to the file from the collection's root and whose second
        element depends on the value of the `data` flag. If `data=True`, the
        second element will be a generator that will generate the bytes of the
        file data as stored in the assetstore. If `data=False`, the second
        element is the file document itself.

        :param doc: the collection to list.
        :param user: a user used to validate data that is returned.
        :param path: a path prefix to add to the results.
        :param includeMetadata: if True and there is any metadata, include a
                                result which is the JSON string of the
                                metadata.  This is given a name of
                                metadata[-(number).json that is distinct from
                                any file within the item.
        :param subpath: if True, add the collection's name to the path.
        :param mimeFilter: Optional list of MIME types to filter by. Set to
            None to include all files.
        :type mimeFilter: `list or tuple`
        :param data: If True return raw content of each file as stored in the
            assetstore, otherwise return file document.
        :type data: bool
        """
        from girderformindlogger.models.folder import Folder

        if subpath:
            path = os.path.join(path, doc['name'])

        folderModel = Folder()
        # Eagerly evaluate this list, as the MongoDB cursor can time out on long requests
        childFolders = list(
            folderModel.childFolders(parentType='collection',
                                     parent=doc,
                                     user=user,
                                     fields=['name'] +
                                     (['meta'] if includeMetadata else [])))
        for folder in childFolders:
            for (filepath, file) in folderModel.fileList(folder,
                                                         user,
                                                         path,
                                                         includeMetadata,
                                                         subpath=True,
                                                         mimeFilter=mimeFilter,
                                                         data=data):
                yield (filepath, file)
Exemple #11
0
    def _list(self, model, document):
        entries = []
        if model in ('collection', 'user', 'folder'):
            for folder in Folder().childFolders(
                    parent=document, parentType=model, user=self.server.girderUser):
                entries.append(_stat(folder, 'folder'))

        if model == 'folder':
            for item in Folder().childItems(document):
                entries.append(_stat(item, 'item'))
        elif model == 'item':
            for file in Item().childFiles(document):
                entries.append(_stat(file, 'file'))

        return entries
Exemple #12
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', {}))
        def uploadFile(self, params):
            """
            Providing this works around a limitation in phantom that makes us
            unable to upload binary files, or at least ones that contain certain
            byte values. The path parameter should be provided relative to the
            root directory of the repository.
            """
            self.requireParams(('folderId', 'path'), params)

            if params['path'].startswith(
                    '${'):  # relative to plugin e.g. ${my_plugin}/path
                end = params['path'].find('}')
                plugin = params['path'][2:end]
                plugin = getPlugin(plugin)
                if plugin is None:
                    raise Exception('Invalid plugin %s.' % plugin)
                root = os.path.dirname(inspect.getfile(plugin.__class__))
                path = root + params['path'][end + 1:]
            else:  # assume relative to core package
                path = os.path.join(ROOT_DIR, params['path'])
            name = os.path.basename(path)
            folder = Folder().load(params['folderId'], force=True)

            upload = Upload().createUpload(user=self.getCurrentUser(),
                                           name=name,
                                           parentType='folder',
                                           parent=folder,
                                           size=os.path.getsize(path))

            with open(path, 'rb') as fd:
                file = Upload().handleChunk(upload, fd)

            return file
Exemple #14
0
def index_folder(folderId):
    if Folder().load(folderId, force=True) is None:
        raise ValueError('folderId={} was not a valid folder'.format(folderId))
    items = Item().find({'folderId': ObjectId(folderId)})
    subfolders = Folder().find({'parentId': ObjectId(folderId)})

    files = []
    for item in items:
        for file in Item().childFiles(item, fields={'_id': True}):
            fileId = file['_id']
            files.append(fileId)

    for folder in subfolders:
        files += index_folder(folder['_id'])

    return files
    def testFileProcessHandler(self):
        admin, user = self.users

        # Create a collection, folder, and item
        collection = Collection().createCollection('collection1', admin, public=True)
        folder = Folder().createFolder(collection, 'folder1', parentType='collection', public=True)
        item = Item().createItem('item1', admin, folder)

        # Upload non-DICOM files
        self._uploadNonDicomFiles(item, admin)
        nonDicomItem = Item().load(item['_id'], force=True)
        self.assertIsNone(nonDicomItem.get('dicom'))

        # Upload DICOM files
        self._uploadDicomFiles(item, admin)

        # Check if the 'dicomItem' is well processed
        dicomItem = Item().load(item['_id'], force=True)
        self.assertIn('dicom', dicomItem)
        self.assertHasKeys(dicomItem['dicom'], ['meta', 'files'])

        # Check if the files list contain the good keys and all the file are well sorted
        for i in range(0, 4):
            self.assertTrue('_id' in dicomItem['dicom']['files'][i])
            self.assertTrue('name' in dicomItem['dicom']['files'][i])
            self.assertEqual(dicomItem['dicom']['files'][i]['name'], 'dicomFile{}.dcm'.format(i))
            self.assertTrue('SeriesNumber' in dicomItem['dicom']['files'][i]['dicom'])
            self.assertTrue('InstanceNumber' in dicomItem['dicom']['files'][i]['dicom'])
            self.assertTrue('SliceLocation' in dicomItem['dicom']['files'][i]['dicom'])

        # Check the common metadata
        self.assertIsNotNone(dicomItem['dicom']['meta'])
    def testMakeDicomItem(self):
        admin, user = self.users

        # create a collection, folder, and item
        collection = Collection().createCollection('collection2', admin, public=True)
        folder = Folder().createFolder(collection, 'folder2', parentType='collection', public=True)
        item = Item().createItem('item2', admin, folder)

        # Upload files
        self._uploadDicomFiles(item, admin)

        # Check the endpoint 'parseDicom' for an admin user
        dicomItem = Item().load(item['_id'], force=True)
        dicomItem = self._purgeDicomItem(dicomItem)
        path = '/item/%s/parseDicom' % dicomItem.get('_id')
        resp = self.request(path=path, method='POST', user=admin)
        self.assertStatusOk(resp)
        dicomItem = Item().load(item['_id'], force=True)
        self.assertIn('dicom', dicomItem)
        self.assertHasKeys(dicomItem['dicom'], ['meta', 'files'])

        # Check the endpoint 'parseDicom' for an non admin user
        dicomItem = Item().load(item['_id'], force=True)
        dicomItem = self._purgeDicomItem(dicomItem)
        path = '/item/%s/parseDicom' % dicomItem.get('_id')
        resp = self.request(path=path, method='POST', user=user)
        self.assertStatus(resp, 403)
    def testSearchForDicomItem(self):
        admin, user = self.users

        # Create a collection, folder, and item
        collection = Collection().createCollection('collection3', admin, public=True)
        folder = Folder().createFolder(collection, 'folder3', parentType='collection', public=True)
        item = Item().createItem('item3', admin, folder)

        # Upload files
        self._uploadDicomFiles(item, admin)

        # Search for DICOM item with 'brain research' as common key/value
        resp = self.request(path='/resource/search', params={
            'q': 'brain research',
            'mode': 'dicom',
            'types': json.dumps(['item'])
        })
        self.assertStatusOk(resp)
        self.assertEqual(len(resp.json['item']), 1)
        self.assertEqual(resp.json['item'][0]['name'], 'item3')

        # Search for DICOM item with substring 'in resea' as common key/value
        resp = self.request(path='/resource/search', params={
            'q': 'in resea',
            'mode': 'dicom',
            'types': json.dumps(['item'])
        })
        self.assertStatusOk(resp)
        self.assertEqual(len(resp.json['item']), 1)
        self.assertEqual(resp.json['item'][0]['name'], 'item3')
Exemple #18
0
 def setUp(self):
     base.TestCase.setUp(self)
     admin = {
         'email': '*****@*****.**',
         'login': '******',
         'firstName': 'Admin',
         'lastName': 'Last',
         'password': '******',
         'admin': True
     }
     self.admin = User().createUser(**admin)
     user = {
         'email': '*****@*****.**',
         'login': '******',
         'firstName': 'First',
         'lastName': 'Last',
         'password': '******',
         'admin': False
     }
     self.user = User().createUser(**user)
     coll = {
         'name': 'Test Collection',
         'description': 'The description',
         'public': True,
         'creator': self.admin
     }
     self.collection = Collection().createCollection(**coll)
     Folder().createFolder(parent=self.collection,
                           parentType='collection',
                           name='Public',
                           public=True,
                           creator=self.admin)
 def testDicomWithBinaryValues(self):
     # One of the test files in the pydicom module will throw an IOError
     # when parsing metadata.  We should work around that and still be able
     # to import the file
     samplePath = os.path.join(os.path.dirname(os.path.abspath(
         pydicom.__file__)), 'data', 'test_files', 'OBXXXX1A.dcm')
     admin, user = self.users
     # Create a collection, folder, and item
     collection = Collection().createCollection('collection5', admin, public=True)
     folder = Folder().createFolder(collection, 'folder5', parentType='collection', public=True)
     item = Item().createItem('item5', admin, folder)
     # Upload this dicom file
     with open(samplePath, 'rb') as fp, _EventHelper('dicom_viewer.upload.success') as helper:
         dcmFile = Upload().uploadFromFile(
             obj=fp,
             size=os.path.getsize(samplePath),
             name=os.path.basename(samplePath),
             parentType='item',
             parent=item,
             mimeType='application/dicom',
             user=user
         )
         self.assertIsNotNone(dcmFile)
         # Wait for handler success event
         handled = helper.wait()
         self.assertTrue(handled)
     # Check if the 'dicomItem' is well processed
     dicomItem = Item().load(item['_id'], force=True)
     self.assertIn('dicom', dicomItem)
     self.assertHasKeys(dicomItem['dicom'], ['meta', 'files'])
    def isOrphan(self, item):
        """
        Returns True if this item is orphaned (its folder is missing).

        :param item: The item to check.
        :type item: dict
        """
        from girderformindlogger.models.folder import Folder
        return not Folder().load(item.get('profileId'), force=True)
Exemple #21
0
    def copyItem(self,
                 srcItem,
                 creator,
                 name=None,
                 folder=None,
                 description=None):
        """
        Copy an item, including duplicating files and metadata.

        :param srcItem: the item to copy.
        :type srcItem: dict
        :param creator: the user who will own the copied item.
        :param name: The name of the new item.  None to copy the original name.
        :type name: str
        :param folder: The parent folder of the new item.  None to store in the
                same folder as the original item.
        :param description: Description for the new item.  None to copy the
                original description.
        :type description: str
        :returns: the new item.
        """
        from girderformindlogger.models.file import File
        from girderformindlogger.models.folder import Folder

        if name is None:
            name = srcItem['name']
        if folder is None:
            folder = Folder().load(srcItem['folderId'], force=True)
        if description is None:
            description = srcItem['description']
        newItem = self.createItem(folder=folder,
                                  name=name,
                                  creator=creator,
                                  description=description)
        # copy metadata and other extension values
        newItem['meta'] = copy.deepcopy(srcItem['meta'])
        filteredItem = self.filter(newItem, creator)
        for key in srcItem:
            if key not in filteredItem and key not in newItem:
                newItem[key] = copy.deepcopy(srcItem[key])
        # add a reference to the original item
        newItem['copyOfItem'] = srcItem['_id']
        newItem = self.save(newItem, triggerEvents=False)

        # Give listeners a chance to change things
        events.trigger('model.item.copy.prepare', (srcItem, newItem))
        # copy files
        fileModel = File()
        for file in self.childFiles(item=srcItem):
            fileModel.copyFile(file, creator=creator, item=newItem)

        # Reload to get updated size value
        newItem = self.load(newItem['_id'], force=True)
        events.trigger('model.item.copy.after', newItem)
        return newItem
Exemple #22
0
    def testVirtualFolderValidation(self):
        # Can't make folder virtual if it has children
        subfolder = Folder().createFolder(self.f1, 'sub', creator=self.admin)
        self.f1['isVirtual'] = True

        with six.assertRaisesRegex(
                self, ValidationException,
                'Virtual folders may not contain child folders.'):
            Folder().save(self.f1)

        Folder().remove(subfolder)
        item = Item().createItem('i', creator=self.admin, folder=self.f1)

        with six.assertRaisesRegex(
                self, ValidationException,
                'Virtual folders may not contain child items.'):
            Folder().save(self.f1)

        Item().remove(item)
        Folder().save(self.f1)

        # Can't make subfolders or items under a virtual folder
        with six.assertRaisesRegex(
                self, ValidationException,
                'You may not place items under a virtual folder.'):
            Item().createItem('i', creator=self.admin, folder=self.f1)

        with six.assertRaisesRegex(
                self, ValidationException,
                'You may not place folders under a virtual folder.'):
            Folder().createFolder(self.f1, 'f', creator=self.admin)

        # Can't move an item under a virtual folder
        item = Item().createItem('i', creator=self.admin, folder=self.f2)
        with six.assertRaisesRegex(
                self, ValidationException,
                'You may not place items under a virtual folder.'):
            Item().move(item, self.f1)

        # Ensure JSON for query
        self.f1['virtualItemsQuery'] = 'not JSON'
        with six.assertRaisesRegex(
                self, ValidationException,
                'The virtual items query must be valid JSON.'):
            Folder().save(self.f1)

        del self.f1['virtualItemsQuery']
        self.f1['virtualItemsSort'] = 'not JSON'
        with six.assertRaisesRegex(
                self, ValidationException,
                'The virtual items sort must be valid JSON.'):
            Folder().save(self.f1)
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)
Exemple #24
0
    def load(self, info):
        name = 'virtual_folders'
        events.bind('model.folder.validate', name, _validateFolder)
        events.bind('model.item.validate', name, _validateItem)
        events.bind('rest.get.item.before', name, _virtualChildItems)
        events.bind('rest.post.folder.after', name, _folderUpdate)
        events.bind('rest.put.folder/:id.after', name, _folderUpdate)

        Folder().exposeFields(level=AccessType.READ, fields={'isVirtual'})
        Folder().exposeFields(level=AccessType.SITE_ADMIN, fields={
            'virtualItemsQuery', 'virtualItemsSort'})

        for endpoint in (FolderResource.updateFolder, FolderResource.createFolder):
            (endpoint.description
                .param('isVirtual', 'Whether this is a virtual folder.', required=False,
                       dataType='boolean')
                .param('virtualItemsQuery', 'Query to use to do virtual item lookup, as JSON.',
                       required=False)
                .param('virtualItemsSort', 'Sort to use during virtual item lookup, as JSON.',
                       required=False))
Exemple #25
0
def _folderUpdate(self, event):
    params = event.info['params']
    if {'isVirtual', 'virtualItemsQuery', 'virtualItemsSort'} & set(params):
        folder = Folder().load(event.info['returnVal']['_id'], force=True)
        update = False

        if params.get('isVirtual') is not None:
            update = True
            folder['isVirtual'] = params['isVirtual']
        if params.get('virtualItemsQuery') is not None:
            update = True
            folder['virtualItemsQuery'] = params['virtualItemsQuery']
        if params.get('virtualItemsSort') is not None:
            update = True
            folder['virtualItemsSort'] = params['virtualItemsSort']

        if update:
            self.requireAdmin(self.getCurrentUser(), 'Must be admin to setup virtual folders.')
            folder = Folder().filter(Folder().save(folder), rest.getCurrentUser())
            event.preventDefault().addResponse(folder)
Exemple #26
0
 def _pruneOrphans(self, progress):
     count = 0
     models = [File(), Folder(), Item()]
     steps = sum(model.find().count() for model in models)
     progress.update(total=steps, current=0)
     for model in models:
         for doc in model.find():
             progress.update(increment=1)
             if model.isOrphan(doc):
                 model.remove(doc)
                 count += 1
     return count
Exemple #27
0
    def load(self, info):
        getPlugin('jobs').load(info)

        name = 'thumbnails'
        info['apiRoot'].thumbnail = rest.Thumbnail()

        for model in (Item(), Collection(), Folder(), User()):
            model.exposeFields(level=AccessType.READ, fields='_thumbnails')
            events.bind('model.%s.remove' % model.name, name, removeThumbnails)

        events.bind('model.file.remove', name, removeThumbnailLink)
        events.bind('data.process', name, _onUpload)
Exemple #28
0
    def testVirtualQuery(self):
        for i in range(10):
            item = Item().createItem(str(i),
                                     creator=self.admin,
                                     folder=(self.f1, self.f2)[i % 2])
            Item().setMetadata(item, {'someVal': i})

        self.virtual['virtualItemsQuery'] = json.dumps(
            {'meta.someVal': {
                '$gt': 5
            }})
        self.virtual = Folder().save(self.virtual)

        def listItems():
            resp = self.request('/item',
                                user=self.user,
                                params={'folderId': self.virtual['_id']})
            self.assertStatusOk(resp)
            return resp.json

        self.assertEqual(listItems(), [])

        # Grant permission on the first folder
        Folder().setUserAccess(self.f1, self.user, AccessType.READ, save=True)
        self.assertEqual([i['name'] for i in listItems()], ['6', '8'])

        # Grant permission on the second folder
        Folder().setUserAccess(self.f2, self.user, AccessType.READ, save=True)
        self.assertEqual([i['name'] for i in listItems()],
                         ['6', '7', '8', '9'])

        # Add a custom sort
        self.virtual['virtualItemsSort'] = json.dumps([('meta.someVal',
                                                        SortDir.DESCENDING)])
        self.virtual = Folder().save(self.virtual)
        self.assertEqual([i['name'] for i in listItems()],
                         ['9', '8', '7', '6'])

        # Using childItems on a vfolder should not yield any results
        self.assertEqual(list(Folder().childItems(self.virtual)), [])
    def findAssignments(self, applet):
        """
        Find all Assignments for a given Applet.

        :param applet: The ID of the Applet for which to find Assignments.
        :type applet: str
        :returns: list of Assignments
        """
        # validate Applet ID
        try:
            Applet().load(id=applet, force=True)
        except:
            raise ValidationException(
                message='Invalid Applet ID',
                field='applet'
            )
        allAssignments = [
            {
                '_id': a['_id'],
                '_modelType': 'collection'
            } for a in Collection().find({'name': 'Assignments'})
        ] + [
            {
                '_id': a['_id'],
                '_modelType': 'folder'
            } for a in Folder().find({'name': 'Assignments'})
        ]
        foundAssignments = Folder().find(
            {   '$and': [
                    {'$or': [
                        {'meta.applet.@id': str(applet)},
                        {'meta.applet.url': str(applet)}
                    ]},
                    {'$or': [
                        {'parentId': parent['_id']} for parent in allAssignments
                    ]}
                ]
            }
        )
        return(list(foundAssignments))
Exemple #30
0
    def updateSize(self, doc):
        """
        Recursively recomputes the size of this collection and its underlying
        folders and fixes the sizes as needed.

        :param doc: The collection.
        :type doc: dict
        """
        from girderformindlogger.models.folder import Folder

        size = 0
        fixes = 0
        folderModel = Folder()
        folders = folderModel.find({
            'parentId': doc['_id'],
            'parentCollection': 'collection'
        })
        for folder in folders:
            # fix folder size if needed
            _, f = folderModel.updateSize(folder)
            fixes += f
            # get total recursive folder size
            folder = folderModel.load(folder['_id'], force=True)
            size += folderModel.getSizeRecursive(folder)
        # fix value if incorrect
        if size != doc.get('size'):
            self.update({'_id': doc['_id']}, update={'$set': {'size': size}})
            fixes += 1
        return size, fixes