Skip to content

Commit

Permalink
Merge pull request #396 from DigitalSlideArchive/folder-api
Browse files Browse the repository at this point in the history
Add some folder API endpoints.
  • Loading branch information
manthey authored Jan 23, 2024
2 parents 70bc26d + 836145f commit 6eabcf0
Showing 1 changed file with 66 additions and 4 deletions.
70 changes: 66 additions & 4 deletions wsi_deid/rest.py
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,9 @@ def __init__(self, apiRoot):
self.route('PUT', ('item', ':id', 'action', ':action'), self.itemAction)
self.route('PUT', ('item', ':id', 'action', 'refile'), self.refileItem)
self.route('POST', ('item', ':id', 'action', 'refile', ':tokenId'), self.refileItemFull)
self.route('PUT', ('folder', ':id', 'action', ':action'), self.folderAction)
self.route('POST', ('folder', ':id', 'action', 'refile', ':tokenId'),
self.refileFolderFull)
self.route('PUT', ('action', 'bulkRefile'), self.refileItems)
self.route('PUT', ('item', ':id', 'redactList'), self.setRedactList)
self.route('GET', ('item', ':id', 'refileList'), self.getRefileList)
Expand Down Expand Up @@ -673,36 +676,66 @@ def itemListAction(self, ids, action):
return
user = self.getCurrentUser()
items = [Item().load(id=id, user=user, level=AccessType.READ) for id in ids]
self._itemListAction(action, items, user)
return len(items)

def _itemListAction(self, action, items, user):
actionfunc, actionargs, actname, pp = self._actionForItem(items[0], user, action)
with ItemActionLock:
ItemActionList.extend(items)
try:
with ProgressContext(
True, user=user, title='%s items' % pp.capitalize(),
message='%s %s' % (pp.capitalize(), items[0]['name']),
total=len(ids), current=0
total=len(items), current=0
) as ctx:
try:
for idx, item in enumerate(items):
actionfunc, actionargs, actname, pp = self._actionForItem(
item, user, action)
ctx.update(
message='%s %s' % (pp.capitalize(), item['name']),
total=len(ids), current=idx)
total=len(items), current=idx)
try:
actionfunc(*actionargs)
except Exception:
logger.exception('Failed to %s item' % actname)
ctx.update('Error %s %s' % (pp, item['name']))
raise
ctx.update(message='Done %s' % pp, total=len(ids), current=len(ids))
ctx.update(message='Done %s' % pp, total=len(items), current=len(items))
except Exception:
pass
finally:
with ItemActionLock:
for item in items:
ItemActionList.remove(item)

@autoDescribeRoute(
Description('Perform an action on a folder of items.')
.modelParam('id', 'The folder ID', model=Folder, level=AccessType.READ)
.param('action', 'Action to perform on the item. One of process, '
'reject, quarantine, unquarantine, finish, ocr.', paramType='path',
enum=['process', 'reject', 'quarantine', 'unquarantine', 'finish', 'ocr'])
.param('limit', 'Maximum number of items in folder to process',
required=False, dataType='int')
.param('recurse', 'Return items recursively under this folder.',
dataType='boolean', default=False, required=False)
.errorResponse()
)
@access.user
def folderAction(self, folder, action, limit=None, recurse=False):
setResponseTimeLimit(86400)
user = self.getCurrentUser()
text = '_recurse_:' if recurse else None
filters = {'largeImage.fileId': {'$exists': True}}
limit = int(limit or 0)
sort = [('lowerName', SortDir.ASCENDING)]
items = list(self._item_find(
folder['_id'], text=text, name=None, limit=limit, offset=0,
sort=sort, filters=filters))
self._itemListAction(action, items, user)
return len(items)

@autoDescribeRoute(
Description('Get the list of known and allowed image names for refiling.')
.modelParam('id', model=Item, level=AccessType.READ)
Expand Down Expand Up @@ -781,7 +814,7 @@ def refileItem(self, item, imageId, tokenId):
return item

@autoDescribeRoute(
Description('Perform an action on an item.')
Description('Refile an item with a specific token ID.')
.responseClass('Item')
# Allow all users to do redaction actions; change to WRITE otherwise
.modelParam('id', model=Item, level=AccessType.READ)
Expand All @@ -798,6 +831,35 @@ def refileItemFull(self, item, tokenId, refileData):
item, user, tokenId, imageId, {imageId: {'fields': refileData}})
return item

@autoDescribeRoute(
Description('Refile items in a folder with a specific token ID.')
.modelParam('id', 'The folder ID', model=Folder, level=AccessType.READ)
.param('tokenId', 'The new tokenId', required=True)
.param('limit', 'Maximum number of items in folder to process',
required=False, dataType='int')
.param('recurse', 'Return items recursively under this folder.',
dataType='boolean', default=False, required=False)
)
@access.user
def refileFolderFull(self, folder, tokenId, limit=None, recurse=False):
setResponseTimeLimit(86400)
user = self.getCurrentUser()
text = '_recurse_:' if recurse else None
filters = {'largeImage.fileId': {'$exists': True}}
sort = [('lowerName', SortDir.ASCENDING)]
processedImageIds = []
limit = int(limit or 0)
for item in self._item_find(
folder['_id'], text=text, name=None, limit=limit, offset=0,
sort=sort, filters=filters):
imageId = TokenOnlyPrefix + tokenId
uploadInfo = item.get('wsi_uploadInfo')
if uploadInfo and TokenOnlyPrefix + imageId in uploadInfo:
imageId = TokenOnlyPrefix + imageId
item = process.refile_image(item, user, tokenId, imageId, uploadInfo)
processedImageIds += [imageId]
return processedImageIds

@autoDescribeRoute(
Description('Refile multiple images at once.')
.jsonParam('imageRefileData', 'Data used to refile images', paramType='body')
Expand Down

0 comments on commit 6eabcf0

Please sign in to comment.