From 1d837900930339d05a860121a41711f505547e09 Mon Sep 17 00:00:00 2001 From: David Manthey Date: Thu, 20 Feb 2020 16:23:49 -0500 Subject: [PATCH] Improve handling imported formats with adjacent files. Add tests to check that this behaves as expected. --- .../girder_large_image/girder_tilesource.py | 53 +++++++++++-------- girder/test_girder/test_large_image.py | 29 +++++++++- 2 files changed, 60 insertions(+), 22 deletions(-) diff --git a/girder/girder_large_image/girder_tilesource.py b/girder/girder_large_image/girder_tilesource.py index 072386d51..eef3d2e72 100644 --- a/girder/girder_large_image/girder_tilesource.py +++ b/girder/girder_large_image/girder_tilesource.py @@ -58,34 +58,45 @@ def getState(self): self.edge, self._jsonstyle) + def mayHaveAdjacentFiles(self, largeImageFile): + if not hasattr(self, '_mayHaveAdjacentFiles'): + largeImageFileId = self.item['largeImage']['fileId'] + # The item has adjacent files if there are any files that are not + # the large image file or an original file it was derived from. + # This is always the case if there are 3 or more files. + fileIds = [str(file['_id']) for file in Item().childFiles(self.item, limit=3)] + knownIds = [str(largeImageFileId)] + if 'originalId' in self.item['largeImage']: + knownIds.append(str(self.item['largeImage']['originalId'])) + self._mayHaveAdjacentFiles = ( + len(fileIds) >= 3 or + fileIds[0] not in knownIds or + fileIds[-1] not in knownIds) + if (any(ext in KnownExtensionsWithAdjacentFiles for ext in largeImageFile['exts']) or + largeImageFile.get('mimeType') in KnownMimeTypesWithAdjacentFiles): + self._mayHaveAdjacentFiles = True + return self._mayHaveAdjacentFiles + def _getLargeImagePath(self): # If self.mayHaveAdjacentFiles is True, we try to use the girder # mount where companion files appear next to each other. + largeImageFileId = self.item['largeImage']['fileId'] + largeImageFile = File().load(largeImageFileId, force=True) try: - largeImageFileId = self.item['largeImage']['fileId'] - if not hasattr(self, 'mayHaveAdjacentFiles'): - # The item has adjacent files if there are any files that - # are not the large image file or an original file it - # was derived from. This is always the case if there are 3 - # or more files. - fileIds = [str(file['_id']) for file in Item().childFiles(self.item, limit=3)] - knownIds = [str(largeImageFileId)] - if 'originalId' in self.item['largeImage']: - knownIds.append(str(self.item['largeImage']['originalId'])) - self.mayHaveAdjacentFiles = ( - len(fileIds) >= 3 or - fileIds[0] not in knownIds or - fileIds[-1] not in knownIds) - largeImageFile = File().load(largeImageFileId, force=True) - if (any(ext in KnownExtensionsWithAdjacentFiles for ext in largeImageFile['exts']) or - largeImageFile.get('mimeType') in KnownMimeTypesWithAdjacentFiles): - self.mayHaveAdjacentFiles = True largeImagePath = None - if self.mayHaveAdjacentFiles and hasattr(File(), 'getGirderMountFilePath'): + if (self.mayHaveAdjacentFiles(largeImageFile) and + hasattr(File(), 'getGirderMountFilePath')): try: - largeImagePath = File().getGirderMountFilePath(largeImageFile) - except FilePathException: + if (largeImageFile.get('imported') and + File().getLocalFilePath(largeImageFile) == largeImageFile['path']): + largeImagePath = largeImageFile['path'] + except Exception: pass + if not largeImagePath: + try: + largeImagePath = File().getGirderMountFilePath(largeImageFile) + except FilePathException: + pass if not largeImagePath: try: largeImagePath = File().getLocalFilePath(largeImageFile) diff --git a/girder/test_girder/test_large_image.py b/girder/test_girder/test_large_image.py index 1daab11b9..11591a9d8 100644 --- a/girder/test_girder/test_large_image.py +++ b/girder/test_girder/test_large_image.py @@ -1,18 +1,20 @@ # -*- coding: utf-8 -*- import json +import mock +import os import pytest import time from girder import events from girder.exceptions import ValidationException +from girder.models.file import File from girder.models.item import Item from girder.models.setting import Setting from girder_jobs.constants import JobStatus from girder_jobs.models.job import Job -# from girder_worker.girder_plugin.constants import PluginSettings as WorkerSettings from girder_worker.girder_plugin.status import CustomJobStatus from girder_large_image import constants @@ -319,3 +321,28 @@ def testListSources(server): resp = server.request(path='/large_image/sources') assert resp.json['tiff']['extensions']['tiff'] > 0 assert resp.json['tiff']['version'] is not None + + +@pytest.mark.usefixtures('unbindLargeImage') +@pytest.mark.plugin('large_image') +def testGetLargeImagePath(server, admin, fsAssetstore): + file = utilities.uploadExternalFile('data/sample_image.ptif.sha512', admin, fsAssetstore) + itemId = str(file['itemId']) + item = Item().load(itemId, user=admin) + ts = ImageItem().tileSource(item) + + with mock.patch.object(File(), 'getGirderMountFilePath', return_value='mockmount'): + path = ts._getLargeImagePath() + abspath = os.path.abspath(path) + assert path != file['path'] + assert path.endswith(file['path']) + ts._mayHaveAdjacentFiles = True + path = ts._getLargeImagePath() + assert path == 'mockmount' + origFile = file + file['imported'] = True + file['path'] = abspath + file = File().save(file) + path = ts._getLargeImagePath() + assert path == abspath + file = File().save(origFile)