Beispiel #1
0
    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 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 testAnnotationCopy(self, server, admin):
        publicFolder = utilities.namedFolder(admin, 'Public')
        # create annotation on an item
        itemSrc = Item().createItem('sample', admin, publicFolder)
        annot = Annotation().createAnnotation(itemSrc, admin, sampleAnnotation)
        assert Annotation().load(annot['_id'], user=admin) is not None

        # Create a new item
        itemDest = Item().createItem('sample', admin, publicFolder)

        # Copy the annotation from one item to an other
        resp = server.request(path='/annotation/{}/copy'.format(annot['_id']),
                              method='POST',
                              user=admin,
                              params={'itemId': itemDest.get('_id')})
        assert utilities.respStatus(resp) == 200
        itemDest = Item().load(itemDest.get('_id'), level=AccessType.READ)

        # Check if the annotation is in the destination item
        resp = server.request(path='/annotation',
                              method='GET',
                              user=admin,
                              params={
                                  'itemId': itemDest.get('_id'),
                                  'name': 'sample'
                              })
        assert utilities.respStatus(resp) == 200
        assert resp.json is not None
Beispiel #4
0
def _virtualItemPosition(self, event):
    params = event.info['params']

    response = _virtualChildItemsFind(self, params)
    if response is None:
        return  # This is not a virtual folder child listing request
    q, sort, user, limit, offset = response
    itemId = event.info['id']
    item = Item().load(itemId, user=user, level=AccessType.READ)
    if not len(sort):
        raise RestException('Invalid sort mode.')
    filters = []
    for idx in range(len(sort) + 1):
        dir = '$lt' if sort[min(idx,
                                len(sort) -
                                1)][1] == SortDir.ASCENDING else '$gt'
        filter = {}
        for idx2 in range(idx):
            filter[sort[idx2][0]] = item.get(sort[idx2][0])
        if idx < len(sort):
            filter[sort[idx][0]] = {dir: item.get(sort[idx][0])}
        else:
            filter['_id'] = {dir: item['_id']}
        filters.append(filter)
    q = {'$and': [q, {'$or': filters}]}
    items = Item().findWithPermissions(q,
                                       sort=sort,
                                       user=user,
                                       level=AccessType.READ,
                                       limit=limit,
                                       offset=offset)
    event.preventDefault().addResponse(items.count())
Beispiel #5
0
def _updateJob(event):
    """
    Called when a job is saved, updated, or removed.  If this is a large image
    job and it is ended, clean up after it.
    """
    from girder.plugins.jobs.constants import JobStatus
    from girder.plugins.jobs.models.job import Job

    job = event.info[
        'job'] if event.name == 'jobs.job.update.after' else event.info
    meta = job.get('meta', {})
    if (meta.get('creator') != 'large_image' or not meta.get('itemId')
            or meta.get('task') != 'createImageItem'):
        return
    status = job['status']
    if event.name == 'model.job.remove' and status not in (JobStatus.ERROR,
                                                           JobStatus.CANCELED,
                                                           JobStatus.SUCCESS):
        status = JobStatus.CANCELED
    if status not in (JobStatus.ERROR, JobStatus.CANCELED, JobStatus.SUCCESS):
        return
    item = Item().load(meta['itemId'], force=True)
    if not item or 'largeImage' not in item:
        return
    if item.get('largeImage', {}).get('expected'):
        # We can get a SUCCESS message before we get the upload message, so
        # don't clear the expected status on success.
        if status != JobStatus.SUCCESS:
            del item['largeImage']['expected']
    notify = item.get('largeImage', {}).get('notify')
    msg = None
    if notify:
        del item['largeImage']['notify']
        if status == JobStatus.SUCCESS:
            msg = 'Large image created'
        elif status == JobStatus.CANCELED:
            msg = 'Large image creation canceled'
        else:  # ERROR
            msg = 'FAILED: Large image creation failed'
        msg += ' for item %s' % item['name']
    if (status in (JobStatus.ERROR, JobStatus.CANCELED)
            and 'largeImage' in item):
        del item['largeImage']
    Item().save(item)
    if msg and event.name != 'model.job.remove':
        Job().updateJob(job, progressMessage=msg)
    if notify:
        Notification().createNotification(
            type='large_image.finished_image_item',
            data={
                'job_id': job['_id'],
                'item_id': item['_id'],
                'success': status == JobStatus.SUCCESS,
                'status': status
            },
            user={'_id': job.get('userId')},
            expires=datetime.datetime.utcnow() +
            datetime.timedelta(seconds=30))
Beispiel #6
0
def _postUpload(event):
    """
    Called when a file is uploaded. We check the parent item to see if it is
    expecting a large image upload, and if so we register this file as the
    result image.
    """
    fileObj = event.info['file']
    # There may not be an itemId (on thumbnails, for instance)
    if not fileObj.get('itemId'):
        return

    item = Item().load(fileObj['itemId'], force=True, exc=True)

    if item.get(
            'largeImage',
        {}).get('expected') and (fileObj['name'].endswith('.tiff')
                                 or fileObj.get('mimeType') == 'image/tiff'):
        if fileObj.get('mimeType') != 'image/tiff':
            fileObj['mimeType'] = 'image/tiff'
            File().save(fileObj)
        del item['largeImage']['expected']
        item['largeImage']['fileId'] = fileObj['_id']
        item['largeImage']['sourceName'] = 'tiff'
        if fileObj['name'].endswith('.geo.tiff'):
            item['largeImage']['sourceName'] = 'gdal'
        Item().save(item)
Beispiel #7
0
def checkForLargeImageFiles(event):
    file = event.info
    possible = False
    mimeType = file.get('mimeType')
    if mimeType in ('image/tiff', 'image/x-tiff', 'image/x-ptif'):
        possible = True
    exts = [ext.split()[0] for ext in file.get('exts')]
    if set(exts[-2:]).intersection({
            'svs', 'ptif', 'tif', 'tiff', 'ndpi', 'mrxs', 'nc', 'ntf', 'nitf',
            'scn'
    }):
        possible = True
    if not file.get('itemId') or not possible:
        return
    if not Setting().get(constants.PluginSettings.LARGE_IMAGE_AUTO_SET):
        return
    item = Item().load(file['itemId'], force=True, exc=False)
    if not item or item.get('largeImage'):
        return
    try:
        ImageItem().createImageItem(item, file, createJob=False)
    except Exception:
        # We couldn't automatically set this as a large image
        logger.info('Saved file %s cannot be automatically used as a '
                    'largeImage' % str(file['_id']))
Beispiel #8
0
    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'])
Beispiel #9
0
def _uploadComplete(event):
    """
    Called after an upload finishes. We check if our current token is a special
    authorized upload token, and if so, delete it.

    TODO we could alternatively keep a reference count inside each token that authorized
    more than a single upload at a time, and just decrement it here.
    """
    token = getCurrentToken()
    if token and 'authorizedUploadId' in token:
        user = User().load(token['userId'], force=True)
        item = Item().load(event.info['file']['itemId'], force=True)

        # Save the metadata on the item
        item['description'] = token['authorizedUploadDescription']
        item['authorizedUploadEmail'] = token['authorizedUploadEmail']
        Item().save(item)

        text = mail_utils.renderTemplate(
            'authorized_upload.uploadFinished.mako', {
                'itemId': item['_id'],
                'itemName': item['name'],
                'itemDescription': item.get('description', '')
            })
        mail_utils.sendEmail(to=user['email'],
                             subject='Authorized upload complete',
                             text=text)
        Token().remove(token)
Beispiel #10
0
    def testCreationOnUpload(self):
        resp = self.request(
            path='/file', method='POST', user=self.admin, params={
                'parentType': 'folder',
                'parentId': self.publicFolder['_id'],
                'name': 'test.png',
                'size': len(self.image),
                'reference': json.dumps({
                    'thumbnail': {
                        'width': 100
                    }
                })
            })
        self.assertStatusOk(resp)

        resp = self.request(
            path='/file/chunk', method='POST', user=self.admin, body=self.image, params={
                'offset': 0,
                'uploadId': resp.json['_id']
            }, type='image/png')
        self.assertStatusOk(resp)
        self.assertIn('itemId', resp.json)
        itemId = resp.json['itemId']

        start = time.time()
        while time.time() - start < 15:
            # Wait for thumbnail creation
            item = Item().load(itemId, force=True)
            if item.get('_thumbnails'):
                break
            time.sleep(0.1)
        self.assertEqual(len(item['_thumbnails']), 1)
        file = File().load(item['_thumbnails'][0], force=True)
        with File().open(file) as fh:
            self.assertEqual(fh.read(2), b'\xff\xd8')  # jpeg magic number
Beispiel #11
0
    def testCreationOnUpload(self):
        resp = self.request(
            path='/file', method='POST', user=self.admin, params={
                'parentType': 'folder',
                'parentId': self.publicFolder['_id'],
                'name': 'test.png',
                'size': len(self.image),
                'reference': json.dumps({
                    'thumbnail': {
                        'width': 100
                    }
                })
            })
        self.assertStatusOk(resp)

        resp = self.request(
            path='/file/chunk', method='POST', user=self.admin, body=self.image, params={
                'offset': 0,
                'uploadId': resp.json['_id']
            }, type='image/png')
        self.assertStatusOk(resp)
        self.assertIn('itemId', resp.json)
        itemId = resp.json['itemId']

        start = time.time()
        while time.time() - start < 15:
            # Wait for thumbnail creation
            item = Item().load(itemId, force=True)
            if item.get('_thumbnails'):
                break
            time.sleep(0.1)
        self.assertEqual(len(item['_thumbnails']), 1)
        file = File().load(item['_thumbnails'][0], force=True)
        with File().open(file) as fh:
            self.assertEqual(fh.read(2), b'\xff\xd8')  # jpeg magic number
Beispiel #12
0
def _uploadComplete(event):
    """
    Called after an upload finishes. We check if our current token is a special
    authorized upload token, and if so, delete it.

    TODO we could alternatively keep a reference count inside each token that authorized
    more than a single upload at a time, and just decrement it here.
    """
    token = getCurrentToken()
    if token and 'authorizedUploadId' in token:
        user = User().load(token['userId'], force=True)
        item = Item().load(event.info['file']['itemId'], force=True)

        # Save the metadata on the item
        item['description'] = token['authorizedUploadDescription']
        item['authorizedUploadEmail'] = token['authorizedUploadEmail']
        Item().save(item)

        text = mail_utils.renderTemplate('authorized_upload.uploadFinished.mako', {
            'itemId': item['_id'],
            'itemName': item['name'],
            'itemDescription': item.get('description', '')
        })
        mail_utils.sendEmail(to=user['email'], subject='Authorized upload complete', text=text)
        Token().remove(token)
    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'])
Beispiel #14
0
def file_upload_handler(event):
    file = event.info
    item_id = file.get('itemId')
    if item_id is None:
        return

    item = Item().load(item_id, force=True)
    if item and item.get('geometa') is None:
        if create_geometa(item, file):
            events.trigger(GEOMETA_CREATION_EVENT, info=event.info)
Beispiel #15
0
 def testMetadataHandler(self, server, fsAssetstore, admin):
     file = utilities.uploadExternalFile('data/Easy1.png.sha512', admin,
                                         fsAssetstore)
     item = Item().load(file['itemId'], user=admin)
     utilities.uploadTestFile('sample.meta',
                              admin,
                              fsAssetstore,
                              reference=json.dumps({
                                  'identifier':
                                  'NotItemMetadataForItem',
                                  'userId':
                                  str(admin['_id']),
                                  'itemId':
                                  str(item['_id']),
                                  'fileId':
                                  str(file['_id']),
                              }))
     item = Item().load(file['itemId'], user=admin)
     assert item.get('meta', {}).get('sample') is None
     utilities.uploadTestFile('sample.meta',
                              admin,
                              fsAssetstore,
                              reference=json.dumps({
                                  'identifier':
                                  'NotItemMetadata',
                                  'userId':
                                  str(admin['_id']),
                                  'itemId':
                                  str(item['_id']),
                                  'fileId':
                                  str(file['_id']),
                              }))
     starttime = time.time()
     while time.time() < starttime + 10:
         item = Item().load(file['itemId'], user=admin)
         if 'sample' in item.get('meta', {}):
             break
         time.sleep(0.1)
     item = Item().load(file['itemId'], user=admin)
     assert item['meta']['sample'] == 'value'
     assert item['meta']['complex']['key1'] == 'value1'
Beispiel #16
0
    def callback(event):
        job = event.info['job']

        if job['kwargs'].get('fileId') != str(file_id):
            return

        SUCCESS = JobStatus.SUCCESS
        ERROR = JobStatus.ERROR
        CANCELED = JobStatus.CANCELED

        if job['status'] == SUCCESS:
            item_id = job['kwargs']['attachToId']
            item = Item().load(item_id, user=user, level=AccessType.READ)
            thumbnails = item.get("_thumbnails", [])

            if len(thumbnails) > 0:
                thumbnail_id = thumbnails.pop()

                # remove old thumbnails
                if len(thumbnails) > 0:
                    Item().update({'_id': item_id},
                                  {'$set': {
                                      '_thumbnails': [thumbnail_id]
                                  }})
                    for thumb_id in thumbnails:
                        file = File().load(thumb_id,
                                           user=user,
                                           level=AccessType.WRITE)
                        File().remove(file)

                query = {'_id': model_id}
                updates = {}
                updates.setdefault('$set', {})[prop_name] = thumbnail_id
                update_result = super(Base, self).update(query, updates)
                if update_result.matched_count == 0:
                    raise ValidationException('Invalid id (%s)' % model_id)

        if job['status'] in [SUCCESS, ERROR, CANCELED]:
            events.unbind('jobs.job.update.after', str(file_id))

        return
Beispiel #17
0
def checkForLargeImageFiles(event):
    file = event.info
    possible = False
    mimeType = file.get('mimeType')
    if mimeType in girder_tilesource.KnownMimeTypes:
        possible = True
    exts = [ext.split()[0] for ext in file.get('exts') if ext]
    if set(exts[-2:]).intersection(girder_tilesource.KnownExtensions):
        possible = True
    if not file.get('itemId') or not possible:
        return
    if not Setting().get(constants.PluginSettings.LARGE_IMAGE_AUTO_SET):
        return
    item = Item().load(file['itemId'], force=True, exc=False)
    if not item or item.get('largeImage'):
        return
    try:
        ImageItem().createImageItem(item, file, createJob=False)
    except Exception:
        # We couldn't automatically set this as a large image
        girder.logger.info(
            'Saved file %s cannot be automatically used as a largeImage' % str(file['_id']))
Beispiel #18
0
def _handleUpload(event):
    upload, file = event.info['upload'], event.info['file']

    try:
        reference = json.loads(upload.get('reference'))
    except (TypeError, ValueError):
        return

    if isinstance(reference, dict) and 'interactive_thumbnail' in reference:
        item = Item().load(file['itemId'], force=True, exc=True)

        file['interactive_thumbnails_uid'] = file['name']
        file['attachedToId'] = item['_id']
        file['attachedToType'] = 'item'
        file['itemId'] = None
        File().save(file)

        if not item.get('hasInteractiveThumbnail'):
            Item().update({'_id': item['_id']},
                          {'$set': {
                              'hasInteractiveThumbnail': True
                          }},
                          multi=False)
Beispiel #19
0
    def testDicomViewer(self):
        admin, user = self.users

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

        # test initial values
        path = '/item/%s/dicom' % item.get('_id')
        resp = self.request(path=path, user=admin)
        self.assertStatusOk(resp)
        self.assertEqual(resp.json, [])

        path = os.path.join(os.path.split(__file__)[0], 'test.dcm')
        with open(path, 'rb') as fp:
            Upload().uploadFromFile(fp, 25640, 'test.dcm', 'item', item, admin)

        path = os.path.join(os.path.split(__file__)[0], 'not-dicom.dcm')
        with open(path, 'rb') as fp:
            Upload().uploadFromFile(fp, 7590, 'not-dicom.dcm', 'item', item,
                                    admin)

        # test dicom endpoint
        start = time.time()
        while True:
            try:
                path = '/item/%s/dicom' % item.get('_id')
                resp = self.request(path=path, user=admin)
                break
            except AssertionError:
                if time.time() - start > 15:
                    raise
                time.sleep(0.5)

        self.assertStatusOk(resp)

        # one dicom file found
        files = resp.json
        self.assertEqual(len(files), 1)

        # dicom tags present
        file = files[0]
        dicom = file['dicom']
        self.assertEqual(bool(dicom), True)

        # dicom tags correct
        self.assertEqual(dicom['Rows'], 80)
        self.assertEqual(dicom['Columns'], 150)

        # test filters
        path = '/item/%s/dicom' % item.get('_id')
        resp = self.request(path=path, user=admin, params=dict(filters='Rows'))
        self.assertStatusOk(resp)
        dicom = resp.json[0]['dicom']
        self.assertEqual(dicom['Rows'], 80)
        self.assertEqual(dicom.get('Columns'), None)

        # test non-admin force
        path = '/item/%s/dicom' % item.get('_id')
        resp = self.request(path=path, user=user, params=dict(force=True))
        self.assertStatus(resp, 403)
    def testItemAnnotationEndpoints(self, server, user, admin):
        publicFolder = utilities.namedFolder(admin, 'Public')
        # create two annotations on an item
        itemSrc = Item().createItem('sample', admin, publicFolder)
        annot = Annotation().createAnnotation(itemSrc, admin, sampleAnnotation)
        annot = Annotation().setPublic(annot, False, True)
        Annotation().createAnnotation(itemSrc, admin, sampleAnnotationEmpty)
        # Get all annotations for that item as the user
        resp = server.request(path='/annotation/item/{}'.format(
            itemSrc['_id']),
                              user=user)
        assert utilities.respStatus(resp) == 200
        assert len(resp.json) == 1
        assert len(resp.json[0]['annotation']['elements']) == 0

        # Get all annotations for that item as the admin
        resp = server.request(path='/annotation/item/{}'.format(
            itemSrc['_id']),
                              user=admin)
        assert utilities.respStatus(resp) == 200
        annotList = resp.json
        assert len(annotList) == 2
        assert (annotList[0]['annotation']['elements'][0]['center'] ==
                annot['annotation']['elements'][0]['center'])
        assert len(annotList[1]['annotation']['elements']) == 0

        # Create a new item
        itemDest = Item().createItem('sample', admin, publicFolder)

        # Set the annotations on the new item
        resp = server.request(path='/annotation/item/{}'.format(
            itemDest['_id']),
                              method='POST',
                              user=admin,
                              type='application/json',
                              body=json.dumps(annotList))
        assert utilities.respStatus(resp) == 200
        assert resp.json == 2

        # Check if the annotations are in the destination item
        resp = server.request(path='/annotation',
                              method='GET',
                              user=admin,
                              params={
                                  'itemId': itemDest.get('_id'),
                                  'name': 'sample'
                              })
        assert utilities.respStatus(resp) == 200
        assert resp.json is not None

        # Check failure conditions
        resp = server.request(path='/annotation/item/{}'.format(
            itemDest['_id']),
                              method='POST',
                              user=admin,
                              type='application/json',
                              body=json.dumps(['not an object']))
        assert utilities.respStatus(resp) == 400
        resp = server.request(path='/annotation/item/{}'.format(
            itemDest['_id']),
                              method='POST',
                              user=admin,
                              type='application/json',
                              body=json.dumps([{
                                  'key': 'not an annotation'
                              }]))
        assert utilities.respStatus(resp) == 400

        # Delete annotations
        resp = server.request(path='/annotation/item/{}'.format(
            itemDest['_id']),
                              method='DELETE',
                              user=None)
        assert utilities.respStatus(resp) == 401

        resp = server.request(path='/annotation/item/{}'.format(
            itemDest['_id']),
                              method='DELETE',
                              user=admin)
        assert utilities.respStatus(resp) == 200
        assert resp.json == 2
Beispiel #21
0
def itemIsWebsafeVideo(item: Item) -> bool:
    return item.get("meta", {}).get("codec") == "h264"