コード例 #1
0
ファイル: folder.py プロジェクト: sutartmelson/girder
 def updateFolderAccess(self, folder, access, publicFlags, public, recurse, progress, params):
     user = self.getCurrentUser()
     progress = progress and recurse  # Only enable progress in recursive case
     with ProgressContext(progress, user=user, title='Updating permissions',
                          message='Calculating progress...') as ctx:
         if progress:
             ctx.update(total=self.model('folder').subtreeCount(
                 folder, includeItems=False, user=user,
                 level=AccessType.ADMIN))
         return self.model('folder').setAccessList(
             folder, access, save=True, recurse=recurse, user=user,
             progress=ctx, setPublic=public, publicFlags=publicFlags)
コード例 #2
0
ファイル: collection.py プロジェクト: tymiao1220/girder
    def updateCollectionAccess(self, collection, access, public, recurse, progress, publicFlags):
        user = self.getCurrentUser()
        progress = progress and recurse

        with ProgressContext(progress, user=user, title='Updating permissions',
                             message='Calculating progress...') as ctx:
            if progress:
                ctx.update(total=self._model.subtreeCount(
                    collection, includeItems=False, user=user, level=AccessType.ADMIN))
            return self._model.setAccessList(
                collection, access, save=True, user=user, recurse=recurse,
                progress=ctx, setPublic=public, publicFlags=publicFlags)
コード例 #3
0
ファイル: system.py プロジェクト: snandasena/girder
 def systemConsistencyCheck(self, progress):
     user = self.getCurrentUser()
     title = 'Running system consistency check'
     with ProgressContext(progress, user=user, title=title) as pc:
         results = {}
         pc.update(title='Checking for orphaned records (Step 1 of 3)')
         results['orphansRemoved'] = self._pruneOrphans(pc)
         pc.update(title='Checking for incorrect base parents (Step 2 of 3)')
         results['baseParentsFixed'] = self._fixBaseParents(pc)
         pc.update(title='Checking for incorrect sizes (Step 3 of 3)')
         results['sizesChanged'] = self._recalculateSizes(pc)
         return results
コード例 #4
0
ファイル: file.py プロジェクト: kelliecorona/girder
    def moveFileToAssetstore(self, file, assetstore, progress):
        user = self.getCurrentUser()
        title = 'Moving file "%s" to assetstore "%s"' % (file['name'],
                                                         assetstore['name'])

        with ProgressContext(progress,
                             user=user,
                             title=title,
                             total=file['size']) as ctx:
            return Upload().moveFileToAssetstore(file=file,
                                                 user=user,
                                                 assetstore=assetstore,
                                                 progress=ctx)
コード例 #5
0
 def deleteTale(self, tale, progress):
     user = self.getCurrentUser()
     workspace = Folder().load(tale['workspaceId'],
                               user=user,
                               level=AccessType.ADMIN)
     with ProgressContext(
             progress,
             user=user,
             title='Deleting workspace of {title}'.format(**tale),
             message='Calculating folder size...') as ctx:
         if progress:
             ctx.update(total=Folder().subtreeCount(workspace))
         Folder().remove(workspace, progress=ctx)
     self._model.remove(tale)
コード例 #6
0
    def testFilesystemAssetstoreFindInvalidFiles(self):
        # Create several files in the assetstore, some of which point to real
        # files on disk and some that don't
        folder = six.next(self.model('folder').childFolders(
            parent=self.admin, parentType='user', force=True, limit=1))
        item = self.model('item').createItem('test', self.admin, folder)

        path = os.path.join(
            ROOT_DIR, 'tests', 'cases', 'py_client', 'testdata', 'hello.txt')
        real = self.model('file').createFile(
            name='hello.txt', creator=self.admin, item=item,
            assetstore=self.assetstore, size=os.path.getsize(path))
        real['imported'] = True
        real['path'] = path
        self.model('file').save(real)

        fake = self.model('file').createFile(
            name='fake', creator=self.admin, item=item, size=1, assetstore=self.assetstore)
        fake['path'] = 'nonexistent/path/to/file'
        fake['sha512'] = '...'
        fake = self.model('file').save(fake)

        fakeImport = self.model('file').createFile(
            name='fakeImport', creator=self.admin, item=item, size=1, assetstore=self.assetstore)
        fakeImport['imported'] = True
        fakeImport['path'] = '/nonexistent/path/to/file'
        fakeImport = self.model('file').save(fakeImport)

        adapter = assetstore_utilities.getAssetstoreAdapter(self.assetstore)
        self.assertTrue(inspect.isgeneratorfunction(adapter.findInvalidFiles))

        with ProgressContext(True, user=self.admin, title='test') as p:
            for i, info in enumerate(
                    adapter.findInvalidFiles(progress=p, filters={
                        'imported': True
                    }), 1):
                self.assertEqual(info['reason'], 'missing')
                self.assertEqual(info['file']['_id'], fakeImport['_id'])
            self.assertEqual(i, 1)
            self.assertEqual(p.progress['data']['current'], 2)
            self.assertEqual(p.progress['data']['total'], 2)

            for i, info in enumerate(
                    adapter.findInvalidFiles(progress=p), 1):
                self.assertEqual(info['reason'], 'missing')
                self.assertIn(info['file']['_id'], (fakeImport['_id'], fake['_id']))
            self.assertEqual(i, 2)
            self.assertEqual(p.progress['data']['current'], 3)
            self.assertEqual(p.progress['data']['total'], 3)
コード例 #7
0
def migrate_item(item):
    _file = list(Item().childFiles(item))[0]
    url = _file['linkUrl']
    if url.startswith('https://dashboard.wholetale.org'):
        return 0
    creator = User().load(item['creatorId'], force=True)

    # register url
    entity = Entity(url.strip(), creator)
    provider = HTTPImportProvider()
    try:
        dataMap = provider.lookup(entity)
    except Exception:
        print("  -> Failed to resolve {} as HTTP".format(url))
        print("  -> item_id = {}".format(str(item["_id"])))
        return 0
    ds = dataMap.toDict()

    if not ds['name']:
        print("  -> Item has no name!!!")
        print(ds)
        return 0

    with ProgressContext(True, user=creator,
                         title='Registering resources') as ctx:
        objType, new_item = provider.register(CAT_ROOT,
                                              'folder',
                                              ctx,
                                              creator,
                                              dataMap,
                                              base_url=base_url)

    # find userData and replace with new id
    for user in User().find({'myData': item['_id']}):
        print('  Updating {} in myData for user "{}"'.format(
            item['name'], user['login']))
        user['myData'][user['myData'].index(item['_id'])] = new_item['_id']
        user = User().save(user)

    # find tale dataset and switch id
    for tale in Tale().find({'dataSet.itemId': str(item['_id'])}):
        print('  Updating {} in dataSet of Tale: "{}"'.format(
            item['name'], tale['title']))
        for i, ds in enumerate(tale['dataSet']):
            if ds['itemId'] == str(item['_id']):
                tale['dataSet'][i]['itemId'] = str(new_item['_id'])
                Tale().save(tale)

    return 1
コード例 #8
0
 def testProgress(self, params):
     test = params.get('test', 'success')
     duration = int(params.get('duration', 10))
     startTime = time.time()
     with ProgressContext(True, user=self.getCurrentUser(),
                          title='Progress Test', message='Progress Message',
                          total=duration) as ctx:
         for current in range(duration):
             if self.stop:
                 break
             ctx.update(current=current)
             wait = startTime + current + 1 - time.time()
             if wait > 0:
                 time.sleep(wait)
         if test == 'error':
             raise RestException('Progress error test.')
コード例 #9
0
ファイル: file.py プロジェクト: xinlaoda/HPCCloud
def move_files_to_assetstore(files, totalsize):
    user, token = getCurrentUser(True)
    assetstore = ModelImporter.model('assetstore').getCurrent()
    upload = ModelImporter.model('upload')
    with ProgressContext(True,
                         interval=1.0,
                         message=files[0]['name'],
                         user=user,
                         token=token,
                         total=totalsize,
                         title='Moving files') as ctx:
        for file in files:
            ctx.update(message=file['name'])
            upload.moveFileToAssetstore(file=file,
                                        user=user,
                                        assetstore=assetstore,
                                        progress=ctx)
コード例 #10
0
 def move_resources(self, event, path, root, user=None):
     wt_resources = self._filter_resources(event, level=AccessType.WRITE, user=user)
     progress = event.info["params"].get("progress", False)
     with ProgressContext(
         progress,
         user=user,
         title="Moving resources",
         message="Calculating requirements...",
         total=len(wt_resources),
     ) as ctx:
         for obj in wt_resources:
             source_path = obj["src_path"]
             ctx.update(message="Moving %s %s" % (obj["kind"], source_path.name))
             shutil.move(
                 source_path.as_posix(), (path / source_path.name).as_posix()
             )
             ctx.update(increment=1)
コード例 #11
0
ファイル: folder.py プロジェクト: xinlaoda/girder
    def copyFolder(self, folder, parentType, parentId, name, description, public, progress):
        user = self.getCurrentUser()
        parentType = parentType or folder['parentCollection']
        if parentId:
            parent = self.model(parentType).load(
                id=parentId, user=user, level=AccessType.WRITE, exc=True)
        else:
            parent = None

        with ProgressContext(progress, user=self.getCurrentUser(),
                             title='Copying folder %s' % folder['name'],
                             message='Calculating folder size...') as ctx:
            # Don't do the subtree count if we weren't asked for progress
            if progress:
                ctx.update(total=self._model.subtreeCount(folder))
            return self._model.copyFolder(
                folder, creator=user, name=name, parentType=parentType,
                parent=parent, description=description, public=public, progress=ctx)
コード例 #12
0
ファイル: __init__.py プロジェクト: girder/tape_archive
def _importTar(self, assetstore, folder, path, progress):
    importGroupId = Setting().get(WHITELIST_GROUP_SETTING)
    if not importGroupId:
        raise Exception('Import whitelist group ID is not set')

    user = self.getCurrentUser()
    if importGroupId not in user['groups']:
        raise AccessException('You are not authorized to import tape archive files.')

    if assetstore is None:
        # This is a reasonable fallback behavior, but we may want something more robust.
        # Imported files are weird anyway
        assetstore = Assetstore().getCurrent()

    if assetstore['type'] != AssetstoreType.FILESYSTEM:
        raise Exception('Not a filesystem assetstore: %s' % assetstore['_id'])

    with ProgressContext(progress, user=user, title='Importing data') as ctx:
        getAssetstoreAdapter(assetstore)._importTar(path, folder, ctx, user)
コード例 #13
0
    def importData(self, assetstore, params):
        self.requireParams(('destinationId', 'destinationType'), params)

        parentType = params.pop('destinationType')
        if parentType not in ('folder', 'collection', 'user'):
            raise RestException('The destinationType must be user, folder, or '
                                'collection.')

        user = self.getCurrentUser()
        parent = self.model(parentType).load(
            params.pop('destinationId'), user=user, level=AccessType.ADMIN,
            exc=True)

        progress = self.boolParam('progress', params, default=False)
        with ProgressContext(
                progress, user=user, title='Importing data') as ctx:
            return self.model('assetstore').importData(
                assetstore, parent=parent, parentType=parentType, params=params,
                progress=ctx, user=user)
コード例 #14
0
ファイル: system.py プロジェクト: chrismattmann/girder
 def systemConsistencyCheck(self, params):
     results = {}
     progress = self.boolParam('progress', params, default=False)
     models = ('item', )
     steps = 0
     if progress:
         for model in models:
             count, changed = self.model(model).checkConsistency(
                 stage='count')
             steps += count
     with ProgressContext(progress,
                          user=self.getCurrentUser(),
                          title='Checking system',
                          total=steps,
                          message='Checking system...') as ctx:
         for model in models:
             count, removed = self.model(model).checkConsistency(
                 stage='remove', progress=ctx)
             if removed:
                 results[model + 'Removed'] = removed
         revmodels = list(models)
         revmodels.reverse()
         for model in revmodels:
             count, corrected = self.model(model).checkConsistency(
                 stage='verify', progress=ctx)
             if count:
                 results[model + 'Count'] = count
             if corrected:
                 results[model + 'Corrected'] = corrected
         # TODO:
         # * check that all files are associated with an existing item
         # * check that all files exist within their assetstore and are the
         #   expected size
         # * check that all folders have a valid ancestor tree leading to a
         #   user or collection
         # * check that all folders have the correct baseParentId and
         #   baseParentType
         # * check that all groups contain valid users
         # * check that all resources validate
         # * for filesystem assetstores, find files that are not tracked.
         # * for gridfs assetstores, find chunks that are not tracked.
         # * for s3 assetstores, find elements that are not tracked.
     return results
コード例 #15
0
 def delete_resources(self, event):
     user = self.getCurrentUser()
     wt_resources = self._filter_resources(event, level=AccessType.WRITE, user=user)
     progress = event.info["params"].get("progress", False)
     with ProgressContext(
         progress,
         user=user,
         title="Deleting resources",
         message="Calculating requirements...",
         total=len(wt_resources),
     ) as ctx:
         for obj in wt_resources:
             source_path = obj["src_path"]
             ctx.update(message="Deleting %s %s" % (obj["kind"], source_path.name))
             if obj["kind"] == "folder":
                 shutil.rmtree(source_path.as_posix())
             else:
                 source_path.unlink()
             ctx.update(increment=1)
コード例 #16
0
ファイル: resource.py プロジェクト: mbrukman/girder
 def moveResources(self, resources, parentType, parentId, progress):
     user = self.getCurrentUser()
     parent = self._prepareMoveOrCopy(resources, parentType, parentId)
     total = sum([len(resources[key]) for key in resources])
     with ProgressContext(
             progress, user=user, title='Moving resources',
             message='Calculating requirements...', total=total) as ctx:
         for kind in resources:
             model = self._getResourceModel(kind, 'move')
             for id in resources[kind]:
                 doc = model.load(id=id, user=user, level=AccessType.WRITE, exc=True)
                 ctx.update(message='Moving %s %s' % (kind, doc.get('name', '')))
                 if kind == 'item':
                     if parent['_id'] != doc['folderId']:
                         model.move(doc, parent)
                 elif kind == 'folder':
                     if ((parentType, parent['_id']) !=
                             (doc['parentCollection'], doc['parentId'])):
                         model.move(doc, parent, parentType)
                 ctx.update(increment=1)
コード例 #17
0
    def importData(self, assetstore, params):
        self.requireParams(('parentId', 'path'), params)

        user = self.getCurrentUser()
        parentType = params.get('parentType', 'folder')
        if parentType not in ('user', 'collection', 'folder'):
            raise RestException('Invalid parentType.')

        parent = self.model(parentType).load(params['parentId'], force=True, exc=True)

        progress = self.boolParam('progress', params, default=False)
        client = HdfsClient(
            host=assetstore['hdfs']['host'], port=assetstore['hdfs']['port'], use_trash=False)
        path = params['path']

        with ProgressContext(progress, user=user, title='Importing data from HDFS') as ctx:
            try:
                self._importData(parentType, parent, assetstore, client, path, ctx, user)
            except FileNotFoundException:
                raise RestException('File not found: %s.' % path)
コード例 #18
0
    def importData(self, assetstore, importPath, destinationId,
                   destinationType, progress, leafFoldersAsItems,
                   fileIncludeRegex, fileExcludeRegex):
        user = self.getCurrentUser()
        parent = ModelImporter.model(destinationType).load(
            destinationId, user=user, level=AccessType.ADMIN, exc=True)

        with ProgressContext(progress, user=user,
                             title='Importing data') as ctx:
            return self._model.importData(
                assetstore,
                parent=parent,
                parentType=destinationType,
                params={
                    'fileIncludeRegex': fileIncludeRegex,
                    'fileExcludeRegex': fileExcludeRegex,
                    'importPath': importPath,
                },
                progress=ctx,
                user=user,
                leafFoldersAsItems=leafFoldersAsItems)
コード例 #19
0
ファイル: resource.py プロジェクト: cvlucian/girder
 def delete(self, params):
     """
     Delete a set of resources.
     """
     user = self.getCurrentUser()
     resources = self._validateResourceSet(params)
     total = sum([len(resources[key]) for key in resources])
     progress = self.boolParam('progress', params, default=False)
     with ProgressContext(progress,
                          user=user,
                          title='Deleting resources',
                          message='Calculating size...') as ctx:
         ctx.update(total=total)
         current = 0
         for kind in resources:
             model = self._getResourceModel(kind, 'remove')
             for id in resources[kind]:
                 if (isinstance(model, (acl_mixin.AccessControlMixin,
                                        AccessControlledModel))):
                     doc = model.load(id=id,
                                      user=user,
                                      level=AccessType.ADMIN)
                 else:
                     doc = model.load(id=id)
                 if not doc:
                     raise RestException('Resource %s %s not found.' %
                                         (kind, id))
                 # Don't do a subtree count if we weren't asked for progress
                 if progress:
                     subtotal = model.subtreeCount(doc)
                     if subtotal != 1:
                         total += model.subtreeCount(doc) - 1
                         ctx.update(total=total)
                 model.remove(doc, progress=ctx)
                 if progress:
                     current += subtotal
                     if ctx.progress['data']['current'] != current:
                         ctx.update(current=current,
                                    message='Deleted ' + kind)
コード例 #20
0
 def copy_resources(self, event, path, root, user=None):
     wt_resources = self._filter_resources(event, level=AccessType.READ, user=user)
     progress = event.info["params"].get("progress", False)
     with ProgressContext(
         progress,
         user=user,
         title="Copying resources",
         message="Calculating requirements...",
         total=len(wt_resources),
     ) as ctx:
         for obj in wt_resources:
             source_path = obj["src_path"]
             ctx.update(message="Copying %s %s" % (obj["kind"], source_path.name))
             if obj["kind"] == "folder":
                 shutil.copytree(
                     source_path.as_posix(), (path / source_path.name).as_posix()
                 )
             else:
                 name = source_path.name
                 new_path = ensure_unique_path(path, name)
                 shutil.copy(source_path.as_posix(), new_path.as_posix())
             ctx.update(increment=1)
コード例 #21
0
ファイル: folder.py プロジェクト: chrismattmann/girder
    def updateFolderAccess(self, folder, params):
        self.requireParams('access', params)
        user = self.getCurrentUser()

        public = self.boolParam('public', params)
        recurse = self.boolParam('recurse', params, default=False)
        progress = self.boolParam('progress', params, default=False) and recurse

        try:
            access = json.loads(params['access'])
        except ValueError:
            raise RestException('The access parameter must be JSON.')

        with ProgressContext(progress, user=user, title='Updating permissions',
                             message='Calculating progress...') as ctx:
            if progress:
                ctx.update(total=self.model('folder').subtreeCount(
                    folder, includeItems=False, user=user,
                    level=AccessType.ADMIN))
            return self.model('folder').setAccessList(
                folder, access, save=True, recurse=recurse, user=user,
                progress=ctx, setPublic=public)
コード例 #22
0
ファイル: resource.py プロジェクト: cvlucian/girder
 def copyResources(self, params):
     """
     Copy the specified resources to a new parent folder, user, or
     collection.  Only folder and item resources can be copied with this
     function.
     """
     user, resources, parent, parentType, progress = \
         self._prepareMoveOrCopy(params)
     total = len(resources.get('item', []))
     if 'folder' in resources:
         model = self._getResourceModel('folder')
         for id in resources['folder']:
             folder = model.load(id=id, user=user, level=AccessType.READ)
             if folder:
                 total += model.subtreeCount(folder)
     with ProgressContext(progress,
                          user=user,
                          title='Copying resources',
                          message='Calculating requirements...',
                          total=total) as ctx:
         for kind in resources:
             model = self._getResourceModel(kind)
             for id in resources[kind]:
                 doc = model.load(id=id, user=user, level=AccessType.READ)
                 if not doc:
                     raise RestException('Resource not found. No %s with '
                                         'id %s' % (kind, id))
                 ctx.update(message='Copying %s %s' %
                            (kind, doc.get('name', '')))
                 if kind == 'item':
                     model.copyItem(doc, folder=parent, creator=user)
                     ctx.update(increment=1)
                 elif kind == 'folder':
                     model.copyFolder(doc,
                                      parent=parent,
                                      parentType=parentType,
                                      creator=user,
                                      progress=ctx)
コード例 #23
0
 def copyFolder(self, folder, params):
     user = self.getCurrentUser()
     parentType = params.get('parentType', folder['parentCollection'])
     if 'parentId' in params:
         parentId = params.get('parentId', folder['parentId'])
         parent = self.model(parentType).load(
             id=parentId, user=user, level=AccessType.WRITE, exc=True)
     else:
         parent = None
     name = params.get('name', None)
     description = params.get('description', None)
     public = params.get('public', None)
     progress = self.boolParam('progress', params, default=False)
     with ProgressContext(progress, user=self.getCurrentUser(),
                          title='Copying folder %s' % folder['name'],
                          message='Calculating folder size...') as ctx:
         # Don't do the subtree count if we weren't asked for progress
         if progress:
             ctx.update(total=self.model('folder').subtreeCount(folder))
         return self.model('folder').copyFolder(
             folder, creator=user, name=name, parentType=parentType,
             parent=parent, description=description, public=public,
             progress=ctx)
コード例 #24
0
ファイル: resource.py プロジェクト: mbrukman/girder
 def copyResources(self, resources, parentType, parentId, progress):
     user = self.getCurrentUser()
     parent = self._prepareMoveOrCopy(resources, parentType, parentId)
     total = len(resources.get('item', []))
     if 'folder' in resources:
         model = self._getResourceModel('folder')
         for id in resources['folder']:
             folder = model.load(id=id, user=user, level=AccessType.READ, exc=True)
             total += model.subtreeCount(folder)
     with ProgressContext(
             progress, user=user, title='Copying resources',
             message='Calculating requirements...', total=total) as ctx:
         for kind in resources:
             model = self._getResourceModel(kind)
             for id in resources[kind]:
                 doc = model.load(id=id, user=user, level=AccessType.READ, exc=True)
                 ctx.update(message='Copying %s %s' % (kind, doc.get('name', '')))
                 if kind == 'item':
                     model.copyItem(doc, folder=parent, creator=user)
                     ctx.update(increment=1)
                 elif kind == 'folder':
                     model.copyFolder(
                         doc, parent=parent, parentType=parentType, creator=user, progress=ctx)
コード例 #25
0
 def _progressContext(self, folder, title):
     user = self.getCurrentUser()
     total = self.model('folder').subtreeCount(folder, includeItems=False)
     return ProgressContext(True, user=user, total=total, title=title)
コード例 #26
0
ファイル: __init__.py プロジェクト: girder/tape_archive
def _exportTar(self, assetstore, folder, path, compression, progress):
    user = self.getCurrentUser()
    adapter = getAssetstoreAdapter(assetstore)

    with ProgressContext(progress, user=user, title='Archiving %s' % folder['name']) as ctx:
        adapter._exportTar(path, folder, ctx, user, compression)
コード例 #27
0
    def _testStream(self, user, token=None):
        # Should only work for users or token sessions
        resp = self.request(path='/notification/stream', method='GET')
        self.assertStatus(resp, 401)
        self.assertEqual(resp.json['message'],
                         'You must be logged in or have a valid auth token.')

        resp = self.request(path='/notification/stream',
                            method='GET',
                            user=user,
                            token=token,
                            isJson=False,
                            params={'timeout': 0})
        self.assertStatusOk(resp)
        self.assertEqual(self.getBody(resp), '')

        # Use a very high rate-limit interval so that we don't fail on slow
        # build boxes
        with ProgressContext(True,
                             user=user,
                             token=token,
                             title='Test',
                             total=100,
                             interval=100) as progress:
            progress.update(current=1)

            # Rate limiting should make it so we didn't write the immediate
            # update within the time interval.
            resp = self.request(path='/notification/stream',
                                method='GET',
                                user=user,
                                token=token,
                                isJson=False,
                                params={'timeout': 0})
            messages = self.getSseMessages(resp)
            self.assertEqual(len(messages), 1)
            self.assertEqual(messages[0]['type'], 'progress')
            self.assertEqual(messages[0]['data']['total'], 100)
            self.assertEqual(messages[0]['data']['current'], 0)
            self.assertFalse(
                ProgressState.isComplete(messages[0]['data']['state']))

            # Now use a very short interval to test that we do save changes
            progress.interval = 0.01
            time.sleep(0.02)
            progress.update(current=2)
            resp = self.request(path='/notification/stream',
                                method='GET',
                                user=user,
                                token=token,
                                isJson=False,
                                params={'timeout': 0})
            messages = self.getSseMessages(resp)
            self.assertEqual(len(messages), 1)
            self.assertEqual(messages[0]['data']['current'], 2)
            # If we use a non-numeric value, nothing bad should happen
            time.sleep(0.02)
            progress.update(current='not_a_number')
            resp = self.request(path='/notification/stream',
                                method='GET',
                                user=user,
                                token=token,
                                isJson=False,
                                params={'timeout': 0})
            messages = self.getSseMessages(resp)
            self.assertEqual(len(messages), 1)
            self.assertEqual(messages[0]['data']['current'], 'not_a_number')
            # Updating the progress without saving and then exiting should
            # send the update.
            progress.interval = 1000
            progress.update(current=3)

            # The message should contain a timestamp
            self.assertIn('_girderTime', messages[0])
            self.assertIsInstance(messages[0]['_girderTime'], int)

            # Test that the "since" parameter correctly filters out messages
            since = messages[0]['_girderTime'] + 1
            resp = self.request(path='/notification/stream',
                                method='GET',
                                user=user,
                                token=token,
                                isJson=False,
                                params={
                                    'timeout': 0,
                                    'since': since
                                })
            messages = self.getSseMessages(resp)
            self.assertEqual(len(messages), 0)

        # Exiting the context manager should flush the most recent update.
        resp = self.request(path='/notification/stream',
                            method='GET',
                            user=user,
                            token=token,
                            isJson=False,
                            params={'timeout': 0})
        messages = self.getSseMessages(resp)
        self.assertEqual(len(messages), 1)
        self.assertEqual(messages[0]['data']['current'], 3)

        # Test a ValidationException within the progress context
        try:
            with ProgressContext(True,
                                 user=user,
                                 token=token,
                                 title='Test',
                                 total=100):
                raise ValidationException('Test Message')
        except ValidationException:
            pass

        # Exiting the context manager should flush the most recent update.
        resp = self.request(path='/notification/stream',
                            method='GET',
                            user=user,
                            token=token,
                            isJson=False,
                            params={'timeout': 0})
        messages = self.getSseMessages(resp)
        self.assertEqual(messages[-1]['data']['message'],
                         'Error: Test Message')
コード例 #28
0
ファイル: __init__.py プロジェクト: ziqiangxu/girder
 def computeHashes(self, file, progress):
     with ProgressContext(progress,
                          title='Computing hash: %s' % file['name'],
                          total=file['size'],
                          user=self.getCurrentUser()) as pc:
         return _computeHash(file, progress=pc)
コード例 #29
0
    def buildWebCode(self, progress, dev):
        user = self.getCurrentUser()

        with ProgressContext(progress, user=user, title='Building web client code') as progress:
            install.runWebBuild(dev=dev, progress=progress)
コード例 #30
0
ファイル: assetstore_test.py プロジェクト: simhaonline/girder
    def testMoveBetweenAssetstores(self):
        folder = six.next(Folder().childFolders(self.admin,
                                                parentType='user',
                                                force=True,
                                                filters={'name': 'Public'}))

        resp = self.request(path='/assetstore', method='GET', user=self.admin)
        self.assertStatusOk(resp)
        fs_assetstore = resp.json[0]

        # Clear any old DB data
        base.dropGridFSDatabase('girder_test_assetstore_move_assetstore')
        params = {
            'name': 'New Name',
            'type': AssetstoreType.GRIDFS,
            'db': 'girder_test_assetstore_move_assetstore'
        }
        resp = self.request(path='/assetstore',
                            method='POST',
                            user=self.admin,
                            params=params)
        self.assertStatusOk(resp)
        gridfs_assetstore = resp.json

        # Upload a file - it should go to the fs assetstore
        uploadData = 'helloworld'
        params = {
            'parentType': 'folder',
            'parentId': folder['_id'],
            'name': 'sample1',
            'size': len(uploadData),
            'mimeType': 'text/plain'
        }
        resp = self.request(path='/file',
                            method='POST',
                            user=self.admin,
                            params=params)
        self.assertStatusOk(resp)
        upload = resp.json
        resp = self.request(path='/file/chunk',
                            method='POST',
                            user=self.admin,
                            body=uploadData,
                            params={'uploadId': upload['_id']},
                            type='text/plain')
        self.assertStatusOk(resp)
        self.assertEqual(resp.json['assetstoreId'], fs_assetstore['_id'])
        uploadedFiles = [resp.json]

        # Upload it again targetting a different assetstore
        params['assetstoreId'] = gridfs_assetstore['_id']
        resp = self.request(path='/file',
                            method='POST',
                            user=self.admin,
                            params=params)
        self.assertStatusOk(resp)
        upload = resp.json
        resp = self.request(path='/file/chunk',
                            method='POST',
                            user=self.admin,
                            body=uploadData,
                            params={'uploadId': upload['_id']},
                            type='text/plain')
        self.assertStatusOk(resp)
        self.assertEqual(resp.json['assetstoreId'], gridfs_assetstore['_id'])
        uploadedFiles.append(resp.json)

        # Replace the first file, directing the replacement to a different
        # assetstore
        replaceParams = {
            'size': len(uploadData),
            'assetstoreId': gridfs_assetstore['_id'],
        }
        resp = self.request(path='/file/%s/contents' % uploadedFiles[0]['_id'],
                            method='PUT',
                            user=self.admin,
                            params=replaceParams)
        self.assertStatusOk(resp)
        upload = resp.json

        resp = self.request(path='/file/chunk',
                            method='POST',
                            user=self.admin,
                            body=uploadData,
                            params={'uploadId': upload['_id']},
                            type='text/plain')
        self.assertStatusOk(resp)
        self.assertEqual(resp.json['assetstoreId'], gridfs_assetstore['_id'])
        uploadedFiles[0] = resp.json

        # Move a file from the gridfs assetstore to the filesystem assetstore
        resp = self.request(path='/file/%s/move' % uploadedFiles[0]['_id'],
                            method='PUT',
                            user=self.admin,
                            params={'assetstoreId': fs_assetstore['_id']})
        self.assertStatusOk(resp)
        self.assertEqual(resp.json['assetstoreId'], fs_assetstore['_id'])
        uploadedFiles[0] = resp.json

        # Doing it again shouldn't change it.
        resp = self.request(path='/file/%s/move' % uploadedFiles[0]['_id'],
                            method='PUT',
                            user=self.admin,
                            params={'assetstoreId': fs_assetstore['_id']})
        self.assertStatusOk(resp)
        self.assertEqual(resp.json['assetstoreId'], fs_assetstore['_id'])
        uploadedFiles[0] = resp.json

        # We should be able to move it back
        resp = self.request(path='/file/%s/move' % uploadedFiles[0]['_id'],
                            method='PUT',
                            user=self.admin,
                            params={'assetstoreId': gridfs_assetstore['_id']})
        self.assertStatusOk(resp)
        self.assertEqual(resp.json['assetstoreId'], gridfs_assetstore['_id'])
        uploadedFiles[0] = resp.json

        # Test moving a file of zero length
        params['size'] = 0
        resp = self.request(path='/file',
                            method='POST',
                            user=self.admin,
                            params=params)
        self.assertStatusOk(resp)
        uploadedFiles.append(resp.json)

        resp = self.request(path='/file/%s/move' % uploadedFiles[2]['_id'],
                            method='PUT',
                            user=self.admin,
                            params={'assetstoreId': fs_assetstore['_id']})
        self.assertStatusOk(resp)
        self.assertEqual(resp.json['assetstoreId'], fs_assetstore['_id'])
        uploadedFiles[2] = resp.json

        # Test preventing the move via an event
        def stopMove(event):
            event.preventDefault()

        events.bind('model.upload.movefile', 'assetstore_test', stopMove)
        try:
            resp = self.request(path='/file/%s/move' % uploadedFiles[0]['_id'],
                                method='PUT',
                                user=self.admin,
                                params={'assetstoreId': fs_assetstore['_id']},
                                isJson=False)
            self.assertFalse('Move should have been prevented')
        except AssertionError as exc:
            self.assertIn('could not be moved to assetstore', str(exc))
        events.unbind('model.upload.movefile', 'assetstore_test')

        # Test files big enough to be multi-chunk
        chunkSize = Upload()._getChunkSize()
        data = io.BytesIO(b' ' * chunkSize * 2)
        uploadedFiles.append(Upload().uploadFromFile(data,
                                                     chunkSize * 2,
                                                     'sample',
                                                     parentType='folder',
                                                     parent=folder,
                                                     assetstore=fs_assetstore))
        resp = self.request(path='/file/%s/move' % uploadedFiles[3]['_id'],
                            method='PUT',
                            user=self.admin,
                            params={'assetstoreId': gridfs_assetstore['_id']})
        self.assertStatusOk(resp)
        self.assertEqual(resp.json['assetstoreId'], gridfs_assetstore['_id'])
        uploadedFiles[3] = resp.json

        # Test progress
        size = chunkSize * 2
        data = io.BytesIO(b' ' * size)
        upload = Upload().uploadFromFile(data,
                                         size,
                                         'progress',
                                         parentType='folder',
                                         parent=folder,
                                         assetstore=fs_assetstore)
        params = {'assetstoreId': gridfs_assetstore['_id'], 'progress': True}
        resp = self.request(path='/file/%s/move' % upload['_id'],
                            method='PUT',
                            user=self.admin,
                            params=params)
        self.assertStatusOk(resp)
        self.assertEqual(resp.json['assetstoreId'], gridfs_assetstore['_id'])

        resp = self.request(path='/notification/stream',
                            method='GET',
                            user=self.admin,
                            isJson=False,
                            params={'timeout': 1})
        messages = self.getSseMessages(resp)
        self.assertEqual(len(messages), 1)
        self.assertEqual(messages[0]['type'], 'progress')
        self.assertEqual(messages[0]['data']['current'], size)

        # Test moving imported file

        # Create assetstore to import file into
        params = {
            'name': 'ImportTest',
            'type': AssetstoreType.FILESYSTEM,
            'root': os.path.join(fs_assetstore['root'], 'import')
        }
        resp = self.request(path='/assetstore',
                            method='POST',
                            user=self.admin,
                            params=params)
        self.assertStatusOk(resp)
        import_assetstore = resp.json

        # Import file
        params = {
            'importPath':
            os.path.join(ROOT_DIR, 'tests', 'cases', 'py_client', 'testdata',
                         'world.txt'),
            'destinationType':
            'folder',
        }

        Assetstore().importData(import_assetstore,
                                parent=folder,
                                parentType='folder',
                                params=params,
                                progress=ProgressContext(False),
                                user=self.admin,
                                leafFoldersAsItems=False)

        file = path_util.lookUpPath('/user/admin/Public/world.txt/world.txt',
                                    self.admin)['document']

        # Move file
        params = {
            'assetstoreId': fs_assetstore['_id'],
        }
        resp = self.request(path='/file/%s/move' % file['_id'],
                            method='PUT',
                            user=self.admin,
                            params=params)
        self.assertStatusOk(resp)
        self.assertEqual(resp.json['assetstoreId'], fs_assetstore['_id'])

        # Check that we can still download the file
        resp = self.request(path='/file/%s/download' % file['_id'],
                            user=self.admin,
                            isJson=False)
        self.assertStatusOk(resp)