From b19912347ad69eae31ce90f1bd79cb73768540eb Mon Sep 17 00:00:00 2001 From: naglepuff Date: Fri, 8 Nov 2024 14:38:37 -0500 Subject: [PATCH 01/12] Update tox config for girder 5 --- requirements-dev.txt | 2 -- requirements-girder5.txt | 6 ++++++ tox.ini | 14 ++++++-------- 3 files changed, 12 insertions(+), 10 deletions(-) create mode 100644 requirements-girder5.txt diff --git a/requirements-dev.txt b/requirements-dev.txt index 92382985f..f8e43d0d3 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,6 +1,4 @@ # Top level dependencies -girder>=3.1.18 -girder-jobs>=3.0.3 -e sources/bioformats -e sources/deepzoom -e sources/dicom diff --git a/requirements-girder5.txt b/requirements-girder5.txt new file mode 100644 index 000000000..d0466d0d7 --- /dev/null +++ b/requirements-girder5.txt @@ -0,0 +1,6 @@ +# Dependencies needed from Girder 5 during prerelease +--pre +girder +girder-jobs +girder-worker +girder-plugin-worker diff --git a/tox.ini b/tox.ini index b91f80485..9a640d01a 100644 --- a/tox.ini +++ b/tox.ini @@ -31,19 +31,15 @@ deps = pytest pytest-cov pytest-custom-exit-code - pytest-girder + pytest-girder==5.0.0a4 pytest-rerunfailures pytest-xdist allowlist_externals = rm - npx -# Run most tests in parallel and conflicting tests sequentially commands = rm -rf build/test/coverage/web_temp - girder build --dev {env:GIRDER_BUILD_OPTIONS} pytest --numprocesses 0 -m 'singular' --cov-config tox.ini --suppress-no-test-exit-code {posargs} pytest --numprocesses {env:PYTEST_NUMPROCESSES:logical} -m 'not singular and not notebook' --cov-config tox.ini --cov-append --suppress-no-test-exit-code {posargs} - - npx nyc report --temp-dir build/test/coverage/web_temp --report-dir build/test/coverage --reporter cobertura --reporter text-summary # Reduce npm chatter setenv = NPM_CONFIG_FUND=false @@ -66,6 +62,7 @@ package=editable passenv = {[testenv:test]passenv} extras = {[testenv:test]extras} deps = + -rrequirements-girder5.txt -rrequirements-dev.txt coverage mock @@ -73,16 +70,18 @@ deps = pytest pytest-cov pytest-custom-exit-code - pytest-girder + pytest-girder==5.0.0a4 pytest-rerunfailures pytest-xdist allowlist_externals = {[testenv:test]allowlist_externals} +# commands_pre = {[testenv:test]commands_pre} commands = {[testenv:test]commands} setenv = {[testenv:test]setenv} [testenv:monkeytype-py{38,39,310,311,312,313}] passenv = {[testenv:test]passenv} deps = + -rrequirements-girder5.txt -rrequirements-dev.txt coverage mock @@ -90,7 +89,7 @@ deps = pytest pytest-cov pytest-custom-exit-code - pytest-girder + pytest-girder==5.0.0a5.dev117 pytest-monkeytype pytest-rerunfailures pytest-xdist @@ -98,7 +97,6 @@ allowlist_externals = {[testenv:test]allowlist_externals} commands = rm -rf build/test/coverage/web_temp -rm ./monkeytype.sqlite3 - girder build --dev pytest --numprocesses 0 -m 'not notebook' --no-cov --suppress-no-test-exit-code --monkeytype-output=./monkeytype.sqlite3 {posargs} - npx nyc report --temp-dir build/test/coverage/web_temp --report-dir build/test/coverage --reporter cobertura --reporter text-summary # After running tox, you can do From c84c9931ba74b15d0670a796a5deb38f449f97c2 Mon Sep 17 00:00:00 2001 From: naglepuff Date: Fri, 22 Nov 2024 14:10:08 -0500 Subject: [PATCH 02/12] Remove girder 3 style logging --- girder/girder_large_image/__init__.py | 2 +- utilities/tasks/large_image_tasks/tasks.py | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/girder/girder_large_image/__init__.py b/girder/girder_large_image/__init__.py index 56333dfc5..8933351f1 100644 --- a/girder/girder_large_image/__init__.py +++ b/girder/girder_large_image/__init__.py @@ -243,7 +243,7 @@ def checkForLargeImageFiles(event): # noqa except Exception: pass # We couldn't automatically set this as a large image - girder.logger.info( + logger.info( 'Saved file %s cannot be automatically used as a largeImage' % str(file['_id'])) diff --git a/utilities/tasks/large_image_tasks/tasks.py b/utilities/tasks/large_image_tasks/tasks.py index 416eb063a..2caabb738 100644 --- a/utilities/tasks/large_image_tasks/tasks.py +++ b/utilities/tasks/large_image_tasks/tasks.py @@ -202,7 +202,6 @@ def cache_histograms_job(job): from girder_jobs.models.job import Job from girder_large_image.models.image_item import ImageItem - from girder import logger kwargs = job['kwargs'] item = ImageItem().load(kwargs.pop('itemId'), force=True) From 7f37dfecae8528d858bce464f05a672183efc809 Mon Sep 17 00:00:00 2001 From: naglepuff Date: Fri, 22 Nov 2024 14:10:45 -0500 Subject: [PATCH 03/12] Remove web client test from python test suite --- girder/test_girder/test_web_client.py | 49 ------------------- .../test_annotation/test_web_client.py | 40 --------------- 2 files changed, 89 deletions(-) delete mode 100644 girder/test_girder/test_web_client.py delete mode 100644 girder_annotation/test_annotation/test_web_client.py diff --git a/girder/test_girder/test_web_client.py b/girder/test_girder/test_web_client.py deleted file mode 100644 index b13645272..000000000 --- a/girder/test_girder/test_web_client.py +++ /dev/null @@ -1,49 +0,0 @@ -import os - -import pytest - -pytestmark = [pytest.mark.girder, pytest.mark.girder_client] - -try: - from pytest_girder.web_client import runWebClientTest -except ImportError: - # Make it easier to test without girder - pass - - -@pytest.mark.singular -@pytest.mark.usefixtures('unbindLargeImage') -@pytest.mark.plugin('large_image') -@pytest.mark.parametrize('spec', [ - 'imageViewerSpec.js', -]) -def testWebClient(boundServer, fsAssetstore, db, spec, girderWorker): - spec = os.path.join(os.path.dirname(__file__), 'web_client_specs', spec) - runWebClientTest(boundServer, spec, 15000) - - -@pytest.mark.usefixtures('unbindLargeImage') -@pytest.mark.plugin('large_image') -@pytest.mark.parametrize('spec', [ - 'largeImageSpec.js', - 'otherFeatures.js', -]) -def testWebClientNoWorker(boundServer, fsAssetstore, db, spec): - spec = os.path.join(os.path.dirname(__file__), 'web_client_specs', spec) - runWebClientTest(boundServer, spec, 15000) - - -@pytest.mark.singular -@pytest.mark.usefixtures('unbindLargeImage') -@pytest.mark.plugin('large_image') -@pytest.mark.parametrize('spec', [ - 'imageViewerSpec.js', -]) -def testWebClientNoStream(boundServer, fsAssetstore, db, spec, girderWorker): - from girder.models.setting import Setting - from girder.settings import SettingKey - - Setting().set(SettingKey.ENABLE_NOTIFICATION_STREAM, False) - - spec = os.path.join(os.path.dirname(__file__), 'web_client_specs', spec) - runWebClientTest(boundServer, spec, 60000) diff --git a/girder_annotation/test_annotation/test_web_client.py b/girder_annotation/test_annotation/test_web_client.py deleted file mode 100644 index 1221bfc6a..000000000 --- a/girder_annotation/test_annotation/test_web_client.py +++ /dev/null @@ -1,40 +0,0 @@ -import os - -import pytest - -pytestmark = [pytest.mark.girder, pytest.mark.girder_client] - -try: - from pytest_girder.web_client import runWebClientTest - - from girder.models.folder import Folder - from girder.models.item import Item -except ImportError: - # Make it easier to test without girder - pass - - -@pytest.mark.usefixtures('unbindLargeImage', 'unbindAnnotation') -@pytest.mark.plugin('large_image_annotation') -@pytest.mark.parametrize('spec', [ - 'annotationListSpec.js', - 'geojsAnnotationSpec.js', - 'geojsSpec.js', -]) -def testWebClientWithAnnotation(boundServer, fsAssetstore, db, spec): - spec = os.path.join(os.path.dirname(__file__), 'web_client_specs', spec) - runWebClientTest(boundServer, spec, 15000) - - -@pytest.mark.usefixtures('unbindLargeImage', 'unbindAnnotation') -@pytest.mark.plugin('large_image_annotation') -def testWebClientAnnotationSpec(boundServer, fsAssetstore, db, admin): - # Create an item in the Public folder - publicFolder = next( - folder for folder in Folder().childFolders(parent=admin, parentType='user', user=admin) - if folder['public'] is True) - Item().createItem('Empty', admin, publicFolder) - - spec = os.path.join(os.path.dirname(__file__), 'web_client_specs', 'annotationSpec.js') - - runWebClientTest(boundServer, spec, 15000) From 56f7a354e6d6b6ca1289b2c2b8bf6415d41e6357 Mon Sep 17 00:00:00 2001 From: naglepuff Date: Fri, 22 Nov 2024 14:40:33 -0500 Subject: [PATCH 04/12] Import WorkerSettings properly --- girder/test_girder/conftest.py | 4 ++-- girder/test_girder/test_large_image.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/girder/test_girder/conftest.py b/girder/test_girder/conftest.py index 295ed9f1b..132c54e14 100644 --- a/girder/test_girder/conftest.py +++ b/girder/test_girder/conftest.py @@ -11,7 +11,7 @@ def unavailableWorker(db): """ Make sure that Girder Worker can't be reached and times out quickly. """ - from girder_worker.girder_plugin.constants import PluginSettings as WorkerSettings + from girder_plugin_worker.constants import PluginSettings as WorkerSettings from girder.models.setting import Setting @@ -47,7 +47,7 @@ def girderWorker(db, girderWorkerProcess): Run an instance of Girder worker, connected to rabbitmq. The rabbitmq service must be running. """ - from girder_worker.girder_plugin.constants import PluginSettings as WorkerSettings + from girder_plugin_worker.constants import PluginSettings as WorkerSettings from girder.models.setting import Setting diff --git a/girder/test_girder/test_large_image.py b/girder/test_girder/test_large_image.py index a6b635b0b..c4d96a1b0 100644 --- a/girder/test_girder/test_large_image.py +++ b/girder/test_girder/test_large_image.py @@ -16,7 +16,7 @@ from girder_jobs.models.job import Job from girder_large_image import constants from girder_large_image.models.image_item import ImageItem - from girder_worker.girder_plugin.status import CustomJobStatus + from girder_plugin_worker.status import CustomJobStatus from girder import events from girder.exceptions import ValidationException From f4e8f8b58260184d8d4fa42cf93b3e73514c76d1 Mon Sep 17 00:00:00 2001 From: naglepuff Date: Mon, 9 Dec 2024 17:32:50 -0500 Subject: [PATCH 05/12] Use test.Dockerfile image for large image tests Also use node 16, since that is what is used by the current girder_test image. --- .circleci/config.yml | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 794935f3e..8bcd5b13f 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -4,7 +4,7 @@ executors: toxandnode: working_directory: ~/project docker: - - image: girder/girder_test:py38-node16 + - image: girder/tox-and-node commands: tox: description: "Run tox" @@ -125,6 +125,12 @@ commands: nvm alias default << parameters.node >> NODE_DIR=$(dirname $(which node)) echo "export PATH=$NODE_DIR:\$PATH" >> $BASH_ENV + - run: + name: Install and build large_image plugin + command: | + npm ci + npm run build + working_directory: girder/girder_large_image/web_client - save_cache: name: Save nvm cache key: v1-nvm-cache-<< parameters.node >> @@ -169,7 +175,7 @@ jobs: - checkout - allservices: version: "3.8" - node: v14 + node: v16 - tox: toxenv: test-py38 - coverage @@ -183,7 +189,7 @@ jobs: - checkout - allservices: version: "3.9" - node: v14 + node: v16 - tox: toxenv: test-py39 - coverage @@ -197,7 +203,7 @@ jobs: - checkout - allservices: version: "3.10" - node: v14 + node: v16 - tox: toxenv: test-py310 - coverage @@ -211,7 +217,7 @@ jobs: - checkout - allservices: version: "3.11" - node: v14 + node: v16 - tox: toxenv: test-py311 - coverage @@ -225,7 +231,7 @@ jobs: - checkout - allservices: version: "3.12" - node: v14 + node: v16 - tox: toxenv: test-py312 - coverage @@ -239,7 +245,7 @@ jobs: - checkout - allservices: version: "3.13" - node: v14 + node: v16 - tox: toxenv: test-py313 environ: TOX_VERBOSE=4 TOX_PREFER_BINARY=1 From 22333fb8896ceb77088678f47e671566fa5beaf2 Mon Sep 17 00:00:00 2001 From: naglepuff Date: Wed, 11 Dec 2024 15:02:04 -0500 Subject: [PATCH 06/12] Pin zarr --- sources/zarr/setup.py | 84 +++++++++++++++++++++++-------------------- 1 file changed, 45 insertions(+), 39 deletions(-) diff --git a/sources/zarr/setup.py b/sources/zarr/setup.py index e7c456902..b9a4c9d3f 100644 --- a/sources/zarr/setup.py +++ b/sources/zarr/setup.py @@ -2,8 +2,8 @@ from setuptools import find_packages, setup -description = 'A OME Zarr tilesource for large_image.' -long_description = description + '\n\nSee the large-image package for more details.' +description = "A OME Zarr tilesource for large_image." +long_description = description + "\n\nSee the large-image package for more details." def prerelease_local_scheme(version): @@ -17,8 +17,8 @@ def prerelease_local_scheme(version): """ from setuptools_scm.version import get_local_node_and_date - if os.getenv('CIRCLE_BRANCH') in ('master', ): - return '' + if os.getenv("CIRCLE_BRANCH") in ("master",): + return "" else: return get_local_node_and_date(version) @@ -26,57 +26,63 @@ def prerelease_local_scheme(version): try: from setuptools_scm import get_version - version = get_version(root='../..', local_scheme=prerelease_local_scheme) - limit_version = f'>={version}' if '+' not in version and not os.getenv('TOX_ENV_NAME') else '' + version = get_version(root="../..", local_scheme=prerelease_local_scheme) + limit_version = ( + f">={version}" if "+" not in version and not os.getenv("TOX_ENV_NAME") else "" + ) except (ImportError, LookupError): - limit_version = '' + limit_version = "" setup( - name='large-image-source-zarr', - use_scm_version={'root': '../..', 'local_scheme': prerelease_local_scheme, - 'fallback_version': '0.0.0'}, + name="large-image-source-zarr", + use_scm_version={ + "root": "../..", + "local_scheme": prerelease_local_scheme, + "fallback_version": "0.0.0", + }, description=description, long_description=long_description, - long_description_content_type='text/x-rst', - license='Apache Software License 2.0', - author='Kitware, Inc.', - author_email='kitware@kitware.com', + long_description_content_type="text/x-rst", + license="Apache Software License 2.0", + author="Kitware, Inc.", + author_email="kitware@kitware.com", classifiers=[ - 'Development Status :: 5 - Production/Stable', - 'License :: OSI Approved :: Apache Software License', - 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.8', - 'Programming Language :: Python :: 3.9', - 'Programming Language :: Python :: 3.10', - 'Programming Language :: Python :: 3.11', - 'Programming Language :: Python :: 3.12', - 'Programming Language :: Python :: 3.13', + "Development Status :: 5 - Production/Stable", + "License :: OSI Approved :: Apache Software License", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ], install_requires=[ - f'large-image{limit_version}', - 'zarr', + f"large-image{limit_version}", + # Pin zarr < 3.0 due to refactoring of stores: https://github.com/zarr-developers/zarr-python/issues/1274 + "zarr<3", # numcodecs and imagecodecs had been required by zarr, but now needs to be asked for - 'imagecodecs', - 'numcodecs', + "imagecodecs", + "numcodecs", # Without imagecodecs-numcodecs, some jpeg encoded data cannot be read - 'imagecodecs-numcodecs!=2024.9.22', + "imagecodecs-numcodecs!=2024.9.22", ], extras_require={ - 'girder': f'girder-large-image{limit_version}', - 'all': [ - 'large-image-converter', + "girder": f"girder-large-image{limit_version}", + "all": [ + "large-image-converter", ], }, - keywords='large_image, tile source', - packages=find_packages(exclude=['test', 'test.*']), - url='https://github.com/girder/large_image', - python_requires='>=3.6', + keywords="large_image, tile source", + packages=find_packages(exclude=["test", "test.*"]), + url="https://github.com/girder/large_image", + python_requires=">=3.6", entry_points={ - 'large_image.source': [ - 'zarr = large_image_source_zarr:ZarrFileTileSource', + "large_image.source": [ + "zarr = large_image_source_zarr:ZarrFileTileSource", ], - 'girder_large_image.source': [ - 'zarr = large_image_source_zarr.girder_source:ZarrGirderTileSource', + "girder_large_image.source": [ + "zarr = large_image_source_zarr.girder_source:ZarrGirderTileSource", ], }, ) From 574cc876cf7f5b86ce57d0c34948b133d69bb516 Mon Sep 17 00:00:00 2001 From: naglepuff Date: Wed, 11 Dec 2024 16:43:57 -0500 Subject: [PATCH 07/12] Update eslint config Ensure that it works with the `girder` global and ignores the `dist/` directory. --- girder/girder_large_image/web_client/package.json | 6 +++++- .../girder_large_image_annotation/web_client/package.json | 6 +++++- .../dicom/large_image_source_dicom/web_client/package.json | 6 +++++- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/girder/girder_large_image/web_client/package.json b/girder/girder_large_image/web_client/package.json index 362657f59..200061347 100644 --- a/girder/girder_large_image/web_client/package.json +++ b/girder/girder_large_image/web_client/package.json @@ -62,7 +62,11 @@ "vue/require-prop-types": "off", "vue/multiline-html-element-content-newline": "off" }, - "root": true + "ignorePatterns": ["dist/**"], + "root": true, + "globals": { + "girder": "readonly" + } }, "eslintIgnore": [ "**/node_modules/" diff --git a/girder_annotation/girder_large_image_annotation/web_client/package.json b/girder_annotation/girder_large_image_annotation/web_client/package.json index c7c244fc4..123eaa9f3 100644 --- a/girder_annotation/girder_large_image_annotation/web_client/package.json +++ b/girder_annotation/girder_large_image_annotation/web_client/package.json @@ -38,7 +38,11 @@ "promise/no-return-wrap": "error", "no-import-assign": "off" }, - "root": true + "ignorePatterns": ["dist/**"], + "root": true, + "globals": { + "girder": "readonly" + } }, "eslintIgnore": [ "**/node_modules/" diff --git a/sources/dicom/large_image_source_dicom/web_client/package.json b/sources/dicom/large_image_source_dicom/web_client/package.json index fc7c881f2..80fa7bf20 100644 --- a/sources/dicom/large_image_source_dicom/web_client/package.json +++ b/sources/dicom/large_image_source_dicom/web_client/package.json @@ -34,7 +34,11 @@ }, "eslintConfig": { "extends": "@girder", - "root": true + "root": true, + "ignorePatterns": ["dist/**"], + "globals": { + "girder": "readonly" + } }, "eslintIgnore": [ "build/", From 3bff2771141b2d77821e29f96ac9de0428856e3d Mon Sep 17 00:00:00 2001 From: naglepuff Date: Wed, 11 Dec 2024 16:44:44 -0500 Subject: [PATCH 08/12] Format client directories --- .../web_client/eventStream.js | 6 +- girder/girder_large_image/web_client/index.js | 2 +- girder/girder_large_image/web_client/main.js | 2 +- .../girder_large_image/web_client/routes.js | 8 +- girder/girder_large_image/web_client/utils.js | 2 +- .../web_client/views/configView.js | 2 +- .../web_client/views/fileList.js | 6 +- .../views/imageViewerSelectWidget.js | 2 +- .../views/imageViewerWidget/base.js | 2 +- .../views/imageViewerWidget/geojs.js | 8 +- .../views/imageViewerWidget/index.js | 2 +- .../views/imageViewerWidget/openlayers.js | 2 +- .../views/imageViewerWidget/slideatlas.js | 2 +- .../web_client/views/itemList.js | 550 +++++++++++++----- .../web_client/views/itemView.js | 6 +- .../web_client/views/itemViewCodemirror.js | 10 +- .../web_client/views/itemViewWidget.js | 2 +- .../web_client/vue/index.js | 10 +- .../web_client/collections/index.js | 2 +- .../web_client/main.js | 2 +- .../web_client/views/configView.js | 6 +- .../web_client/views/index.js | 1 - 22 files changed, 436 insertions(+), 199 deletions(-) diff --git a/girder/girder_large_image/web_client/eventStream.js b/girder/girder_large_image/web_client/eventStream.js index 7f8d31a3f..5064e9b73 100644 --- a/girder/girder_large_image/web_client/eventStream.js +++ b/girder/girder_large_image/web_client/eventStream.js @@ -1,11 +1,11 @@ /* This implements a polling fallback if event streams are disabled on the * server. */ -const eventStream = girder.utilities.eventStream; -const { restRequest } = girder.rest; - import largeImageConfig from './views/configView'; +const eventStream = girder.utilities.eventStream; +const {restRequest} = girder.rest; + eventStream.on('g:eventStream.disable', () => { largeImageConfig.getSettings(() => { if (largeImageConfig.settings['large_image.notification_stream_fallback'] === false) { diff --git a/girder/girder_large_image/web_client/index.js b/girder/girder_large_image/web_client/index.js index 5315732e1..34ee89f56 100644 --- a/girder/girder_large_image/web_client/index.js +++ b/girder/girder_large_image/web_client/index.js @@ -5,5 +5,5 @@ import * as vue from './vue'; export { utils, views, - vue, + vue }; diff --git a/girder/girder_large_image/web_client/main.js b/girder/girder_large_image/web_client/main.js index c6f25fe0d..d83e35770 100644 --- a/girder/girder_large_image/web_client/main.js +++ b/girder/girder_large_image/web_client/main.js @@ -10,7 +10,7 @@ import './views/imageViewerSelectWidget'; // expose symbols under girder.plugins import * as largeImage from './index'; -const { registerPluginNamespace } = girder.pluginUtils; +const {registerPluginNamespace} = girder.pluginUtils; const SearchFieldWidget = girder.views.widgets.SearchFieldWidget; registerPluginNamespace('large_image', largeImage); diff --git a/girder/girder_large_image/web_client/routes.js b/girder/girder_large_image/web_client/routes.js index bae5c5fe2..fe8e5998a 100644 --- a/girder/girder_large_image/web_client/routes.js +++ b/girder/girder_large_image/web_client/routes.js @@ -1,11 +1,11 @@ +import ConfigView from './views/configView'; + const $ = girder.$; const Backbone = girder.Backbone; const events = girder.events; const router = girder.router; -const { exposePluginConfig } = girder.utilities.PluginUtils; -const { parseQueryString, splitRoute } = girder.misc; - -import ConfigView from './views/configView'; +const {exposePluginConfig} = girder.utilities.PluginUtils; +const {parseQueryString, splitRoute} = girder.misc; exposePluginConfig('large_image', 'plugins/large_image/config'); diff --git a/girder/girder_large_image/web_client/utils.js b/girder/girder_large_image/web_client/utils.js index 6c632be33..33a85a7cc 100644 --- a/girder/girder_large_image/web_client/utils.js +++ b/girder/girder_large_image/web_client/utils.js @@ -157,4 +157,4 @@ function setFrameQuad(tileinfo, layer, options) { layer.setFrameQuad.status = status; } -export { setFrameQuad }; +export {setFrameQuad}; diff --git a/girder/girder_large_image/web_client/views/configView.js b/girder/girder_large_image/web_client/views/configView.js index 183daa039..6b45f73a9 100644 --- a/girder/girder_large_image/web_client/views/configView.js +++ b/girder/girder_large_image/web_client/views/configView.js @@ -7,7 +7,7 @@ const events = girder.events; const restRequest = girder.rest.restRequest; const BrowserWidget = girder.views.widgets.BrowserWidget; const PluginConfigBreadcrumbWidget = girder.views.widgets.PluginConfigBreadcrumbWidget; -const { AccessType } = girder.constants; +const {AccessType} = girder.constants; /** * Show the default quota settings for users and collections. diff --git a/girder/girder_large_image/web_client/views/fileList.js b/girder/girder_large_image/web_client/views/fileList.js index b43d7f54e..eaf8c53c9 100644 --- a/girder/girder_large_image/web_client/views/fileList.js +++ b/girder/girder_large_image/web_client/views/fileList.js @@ -3,11 +3,11 @@ import '../stylesheets/fileList.styl'; const $ = girder.$; const _ = girder._; -const { restRequest } = girder.rest; +const {restRequest} = girder.rest; const events = girder.events; const FileListWidget = girder.views.widgets.FileListWidget; -const { wrap } = girder.utilities.PluginUtils; -const { AccessType } = girder.constants; +const {wrap} = girder.utilities.PluginUtils; +const {AccessType} = girder.constants; wrap(FileListWidget, 'render', function (render) { render.call(this); diff --git a/girder/girder_large_image/web_client/views/imageViewerSelectWidget.js b/girder/girder_large_image/web_client/views/imageViewerSelectWidget.js index 942230de2..1cb693e06 100644 --- a/girder/girder_large_image/web_client/views/imageViewerSelectWidget.js +++ b/girder/girder_large_image/web_client/views/imageViewerSelectWidget.js @@ -7,7 +7,7 @@ import FrameSelector from '../vue/components/FrameSelector.vue'; const $ = girder.$; const _ = girder._; -const { wrap } = girder.utilities.PluginUtils; +const {wrap} = girder.utilities.PluginUtils; const eventStream = girder.utilities.EventStream; const ItemView = girder.views.body.ItemView; const View = girder.views.View; diff --git a/girder/girder_large_image/web_client/views/imageViewerWidget/base.js b/girder/girder_large_image/web_client/views/imageViewerWidget/base.js index c72876843..340bcd661 100644 --- a/girder/girder_large_image/web_client/views/imageViewerWidget/base.js +++ b/girder/girder_large_image/web_client/views/imageViewerWidget/base.js @@ -1,6 +1,6 @@ const $ = girder.$; const View = girder.views.View; -const { getApiRoot, restRequest } = girder.rest; +const {getApiRoot, restRequest} = girder.rest; var ImageViewerWidget = View.extend({ initialize: function (settings) { diff --git a/girder/girder_large_image/web_client/views/imageViewerWidget/geojs.js b/girder/girder_large_image/web_client/views/imageViewerWidget/geojs.js index ee1c67a2b..65aef14c7 100644 --- a/girder/girder_large_image/web_client/views/imageViewerWidget/geojs.js +++ b/girder/girder_large_image/web_client/views/imageViewerWidget/geojs.js @@ -3,11 +3,11 @@ import Hammer from '@egjs/hammerjs'; import * as d3 from 'd3'; import ImageViewerWidget from './base'; -import { setFrameQuad } from '../../utils.js'; +import {setFrameQuad} from '../../utils.js'; const $ = girder.$; const _ = girder._; -const { restRequest } = girder.rest; +const {restRequest} = girder.rest; window.hammerjs = Hammer; window.Hammer = Hammer; @@ -37,8 +37,8 @@ var GeojsImageViewerWidget = ImageViewerWidget.extend({ return this; }).then(() => { this.trigger('g:beforeFirstRender', this); - this.render(); - }) + return this.render(); + }); }, render: function () { diff --git a/girder/girder_large_image/web_client/views/imageViewerWidget/index.js b/girder/girder_large_image/web_client/views/imageViewerWidget/index.js index 1d2da84cc..18fe29467 100644 --- a/girder/girder_large_image/web_client/views/imageViewerWidget/index.js +++ b/girder/girder_large_image/web_client/views/imageViewerWidget/index.js @@ -9,5 +9,5 @@ export { leaflet, openlayers, openseadragon, - slideatlas, + slideatlas }; diff --git a/girder/girder_large_image/web_client/views/imageViewerWidget/openlayers.js b/girder/girder_large_image/web_client/views/imageViewerWidget/openlayers.js index a1fd99dc7..b209b17c1 100644 --- a/girder/girder_large_image/web_client/views/imageViewerWidget/openlayers.js +++ b/girder/girder_large_image/web_client/views/imageViewerWidget/openlayers.js @@ -1,7 +1,7 @@ import ImageViewerWidget from './base'; const $ = girder.$; -const { restRequest } = girder.rest; +const {restRequest} = girder.rest; var OpenlayersImageViewerWidget = ImageViewerWidget.extend({ initialize: function (settings) { diff --git a/girder/girder_large_image/web_client/views/imageViewerWidget/slideatlas.js b/girder/girder_large_image/web_client/views/imageViewerWidget/slideatlas.js index f9e3be2c9..9c194555f 100644 --- a/girder/girder_large_image/web_client/views/imageViewerWidget/slideatlas.js +++ b/girder/girder_large_image/web_client/views/imageViewerWidget/slideatlas.js @@ -2,7 +2,7 @@ import ImageViewerWidget from './base'; const $ = girder.$; const Backbone = girder.Backbone; -const { parseQueryString, splitRoute } = girder.misc; +const {parseQueryString, splitRoute} = girder.misc; // var baseSAUrl = 'https://unpkg.com/slideatlas-viewer@4.4.1/dist/'; var baseSAUrl = 'https://cdn.jsdelivr.net/npm/slideatlas-viewer@4/dist/'; diff --git a/girder/girder_large_image/web_client/views/itemList.js b/girder/girder_large_image/web_client/views/itemList.js index f8d54bf76..a819e0f96 100644 --- a/girder/girder_large_image/web_client/views/itemList.js +++ b/girder/girder_large_image/web_client/views/itemList.js @@ -5,18 +5,20 @@ import '../stylesheets/itemList.styl'; import ItemListTemplate from '../templates/itemList.pug'; import {MetadatumWidget, validateMetadataValue} from './metadataWidget'; -const { $, _, Backbone } = girder; -const { wrap } = girder.utilities.PluginUtils; -const { getApiRoot } = girder.rest; -const { getCurrentUser } = girder.auth; -const { AccessType } = girder.constants; -const { formatSize, parseQueryString, splitRoute } = girder.misc; +const {$, _, Backbone} = girder; +const {wrap} = girder.utilities.PluginUtils; +const {getApiRoot} = girder.rest; +const {AccessType} = girder.constants; +const {formatSize, parseQueryString, splitRoute} = girder.misc; const router = girder.router; const HierarchyWidget = girder.views.widgets.HierarchyWidget; -const ItemCollection = girder.collections.ItemCollection +const ItemCollection = girder.collections.ItemCollection; const FolderListWidget = girder.views.widgets.FolderListWidget; const ItemListWidget = girder.views.widgets.ItemListWidget; -ItemCollection.prototype.pageLimit = Math.max(250, ItemCollection.prototype.pageLimit); +ItemCollection.prototype.pageLimit = Math.max( + 250, + ItemCollection.prototype.pageLimit +); function onItemClick(item) { if (this.itemListView && this.itemListView.onItemClick) { @@ -43,20 +45,38 @@ wrap(HierarchyWidget, 'render', function (render) { if (this.parentModel.resourceName !== 'folder') { this.$('.g-folder-list-container').toggleClass('hidden', false); } - if (!this.$('#flattenitemlist').length && this.$('.g-item-list-container').length && this.itemListView && this.itemListView.setFlatten) { - $('button.g-checked-actions-button').parent().after( - '
' - ); - if ((this.itemListView || {})._recurse && this.parentModel.resourceName === 'folder') { + if ( + !this.$('#flattenitemlist').length && + this.$('.g-item-list-container').length && + this.itemListView && + this.itemListView.setFlatten + ) { + $('button.g-checked-actions-button') + .parent() + .after( + '
' + ); + if ( + (this.itemListView || {})._recurse && + this.parentModel.resourceName === 'folder' + ) { this.$('#flattenitemlist').prop('checked', true); - this.$('.g-folder-list-container').toggleClass('hidden', this.itemListView._hideFoldersOnFlatten); + this.$('.g-folder-list-container').toggleClass( + 'hidden', + this.itemListView._hideFoldersOnFlatten + ); } this.events['click #flattenitemlist'] = (evt) => { - this.itemListView.setFlatten(this.$('#flattenitemlist').is(':checked')); + this.itemListView.setFlatten( + this.$('#flattenitemlist').is(':checked') + ); }; this.delegateEvents(); } - if (this.$('#flattenitemlist').length && this.parentModel.get('_modelType') !== 'folder') { + if ( + this.$('#flattenitemlist').length && + this.parentModel.get('_modelType') !== 'folder' + ) { this.$('.li-flatten-item-list').addClass('hidden'); } else { this.$('.li-flatten-item-list').removeClass('hidden'); @@ -91,7 +111,11 @@ wrap(ItemListWidget, 'initialize', function (initialize, settings) { const namedList = this._namedList || this._liconfig.defaultItemList; if (this.$el.closest('.modal-dialog').length) { list = this._liconfig.itemListDialog; - } else if (namedList && this._liconfig.namedItemLists && this._liconfig.namedItemLists[namedList]) { + } else if ( + namedList && + this._liconfig.namedItemLists && + this._liconfig.namedItemLists[namedList] + ) { list = this._liconfig.namedItemLists[namedList]; } else { list = this._liconfig.itemList; @@ -100,7 +124,9 @@ wrap(ItemListWidget, 'initialize', function (initialize, settings) { let group = list.group; group = !group.keys ? {keys: group} : group; group.keys = Array.isArray(group.keys) ? group.keys : [group.keys]; - group.keys = group.keys.filter((g) => !g.includes(',') && !g.includes(':')); + group.keys = group.keys.filter( + (g) => !g.includes(',') && !g.includes(':') + ); if (!group.keys.length) { group = undefined; } @@ -118,15 +144,25 @@ wrap(ItemListWidget, 'initialize', function (initialize, settings) { this.render(); return; } - if (!_.isEqual(val, this._liconfig) && !this.$el.closest('.modal-dialog').length && val) { + if ( + !_.isEqual(val, this._liconfig) && + !this.$el.closest('.modal-dialog').length && + val + ) { this._liconfig = val; const list = this._confList(); if (list.layout && list.layout.flatten !== undefined) { this._recurse = !!list.layout.flatten; - this.parentView.$('#flattenitemlist').prop('checked', this._recurse); + this.parentView + .$('#flattenitemlist') + .prop('checked', this._recurse); } - this._hideFoldersOnFlatten = !!(list.layout && list.layout.flatten === 'only'); - this.parentView.$('.g-folder-list-container').toggleClass('hidden', this._hideFoldersOnFlatten); + this._hideFoldersOnFlatten = !!( + list.layout && list.layout.flatten === 'only' + ); + this.parentView + .$('.g-folder-list-container') + .toggleClass('hidden', this._hideFoldersOnFlatten); } delete this._lastSort; this._liconfig = val; @@ -145,7 +181,12 @@ wrap(ItemListWidget, 'initialize', function (initialize, settings) { }; }); update = true; - } else if (this._confList && this._confList() && this._confList().defaultSort && this._confList().defaultSort.length) { + } else if ( + this._confList && + this._confList() && + this._confList().defaultSort && + this._confList().defaultSort.length + ) { this._lastSort = this._confList().defaultSort; update = true; } @@ -161,16 +202,26 @@ wrap(ItemListWidget, 'initialize', function (initialize, settings) { this.render(); } }); - this.events['click .li-item-list-header.sortable'] = (evt) => sortColumn.call(this, evt); - this.events['click .li-item-list-cell-filter'] = (evt) => itemListCellFilter.call(this, evt); - this.events['click .large_image_metadata.lientry_edit'] = (evt) => itemListMetadataEdit.call(this, evt); - this.events['change .large_image_metadata.lientry_edit'] = (evt) => itemListMetadataEdit.call(this, evt); - this.events['input .large_image_metadata.lientry_edit'] = (evt) => itemListMetadataEdit.call(this, evt); + this.events['click .li-item-list-header.sortable'] = (evt) => + sortColumn.call(this, evt); + this.events['click .li-item-list-cell-filter'] = (evt) => + itemListCellFilter.call(this, evt); + this.events['click .large_image_metadata.lientry_edit'] = (evt) => + itemListMetadataEdit.call(this, evt); + this.events['change .large_image_metadata.lientry_edit'] = (evt) => + itemListMetadataEdit.call(this, evt); + this.events['input .large_image_metadata.lientry_edit'] = (evt) => + itemListMetadataEdit.call(this, evt); this.delegateEvents(); this.setFlatten = (flatten) => { if (!!flatten !== !!this._recurse) { this._recurse = !!flatten; - this.parentView.$('.g-folder-list-container').toggleClass('hidden', this._hideFoldersOnFlatten && this._recurse); + this.parentView + .$('.g-folder-list-container') + .toggleClass( + 'hidden', + this._hideFoldersOnFlatten && this._recurse + ); this._setFilter(); this.render(); } @@ -181,7 +232,9 @@ wrap(ItemListWidget, 'initialize', function (initialize, settings) { wrap(ItemListWidget, 'render', function (render) { this.$el.closest('.modal-dialog').addClass('li-item-list-dialog'); if (!this.$el.children().length) { - this.$el.html(''); + this.$el.html( + '' + ); } /* Chrome limits the number of connections to a single domain, which means @@ -200,13 +253,21 @@ wrap(ItemListWidget, 'render', function (render) { * thumbnails are located. */ function _loadMoreImages(parent) { - var loading = $('.large_image_thumbnail img.loading,.large_image_associated img.loading', parent).length; + var loading = $( + '.large_image_thumbnail img.loading,.large_image_associated img.loading', + parent + ).length; if (maxSimultaneous > loading) { - $('.large_image_thumbnail img.waiting,.large_image_associated img.waiting', parent).slice(0, maxSimultaneous - loading).each(function () { - var img = $(this); - img.removeClass('waiting').addClass('loading'); - img.attr('src', img.attr('deferred-src')); - }); + $( + '.large_image_thumbnail img.waiting,.large_image_associated img.waiting', + parent + ) + .slice(0, maxSimultaneous - loading) + .each(function () { + var img = $(this); + img.removeClass('waiting').addClass('loading'); + img.attr('src', img.attr('deferred-src')); + }); } } @@ -219,32 +280,52 @@ wrap(ItemListWidget, 'render', function (render) { this._needsFetch = false; if (this._lastSort) { this.collection.comparator = _.constant(0); - this.collection.sortField = JSON.stringify(this._lastSort.map((e) => [ - (e.type === 'metadata' ? 'meta.' : '') + e.value, - e.dir === 'down' ? 1 : -1 - ])); + this.collection.sortField = JSON.stringify( + this._lastSort.map((e) => [ + (e.type === 'metadata' ? 'meta.' : '') + e.value, + e.dir === 'down' ? 1 : -1 + ]) + ); } this.collection._totalCount = 0; - this.collection.fetch(_.extend({}, {folderId: this.parentView.parentModel.id}, this.collection.params), true).done(() => { - const oldPages = this._totalPages; - const pages = Math.ceil(this.collection.getTotalCount() / this.collection.pageLimit); - this._totalPages = pages; - // recheck if this has large images - this._hasAnyLargeImage = !!_.some(this.collection.toArray(), function (item) { - return item.has('largeImage'); + this.collection + .fetch( + _.extend( + {}, + {folderId: this.parentView.parentModel.id}, + this.collection.params + ), + true + ) + .done(() => { + const oldPages = this._totalPages; + const pages = Math.ceil( + this.collection.getTotalCount() / + this.collection.pageLimit + ); + this._totalPages = pages; + // recheck if this has large images + this._hasAnyLargeImage = !!_.some( + this.collection.toArray(), + function (item) { + return item.has('largeImage'); + } + ); + this._inFetch = false; + if ( + oldPages !== pages || + this.collection.offset !== this.collection.size() + ) { + this.collection.offset = this.collection.size(); + this.trigger('g:paginated'); + this.collection.trigger('g:changed'); + } else { + itemListRender.apply(this, _.rest(arguments)); + } + if (this._needsFetch) { + this._setSort(); + } }); - this._inFetch = false; - if (oldPages !== pages || this.collection.offset !== this.collection.size()) { - this.collection.offset = this.collection.size(); - this.trigger('g:paginated'); - this.collection.trigger('g:changed'); - } else { - itemListRender.apply(this, _.rest(arguments)); - } - if (this._needsFetch) { - this._setSort(); - } - }); } else { this._needsFetch = true; } @@ -263,14 +344,20 @@ wrap(ItemListWidget, 'render', function (render) { if ((nav.name || '') === (this._namedList || '')) { return false; } - if (!this._liconfig || !this._liconfig.namedItemLists || (nav.name && !this._liconfig.namedItemLists[nav.name])) { + if ( + !this._liconfig || + !this._liconfig.namedItemLists || + (nav.name && !this._liconfig.namedItemLists[nav.name]) + ) { return false; } this._updateNamedList(nav.name, false); if (list.group) { this._generalFilter = ''; list.group.keys.forEach((key) => { - const cell = this.$el.find(`[g-item-cid="${item.cid}"] [column-value="${key}"]`); + const cell = this.$el.find( + `[g-item-cid="${item.cid}"] [column-value="${key}"]` + ); if (cell.length) { addCellToFilter.call(this, cell, false); } @@ -278,7 +365,10 @@ wrap(ItemListWidget, 'render', function (render) { } this._setFilter(false); this._setSort(); - addToRoute({namedList: this._namedList, filter: this._generalFilter}); + addToRoute({ + namedList: this._namedList, + filter: this._generalFilter + }); return true; } if (nav.type === 'open') { @@ -315,7 +405,10 @@ wrap(ItemListWidget, 'render', function (render) { this._unescapePhrase = (val) => { if (val !== undefined) { - val = val.replace('\\\'', '\'').replace('\\"', '"').replace('\\\\', '\\'); + val = val + .replace("\\'", "'") + .replace('\\"', '"') + .replace('\\\\', '\\'); } return val; }; @@ -328,28 +421,46 @@ wrap(ItemListWidget, 'render', function (render) { if (val !== undefined && val !== '' && columns.length) { // a value can be surrounded by single or double quotes, which will // be removed. - const quotedValue = /((?:"((?:[^\\"]|\\\\|\\")*)(?:"|$)|'((?:[^\\']|\\\\|\\')*)(?:'|$)|([^:,\s]+)))/g; + const quotedValue = + /((?:"((?:[^\\"]|\\\\|\\")*)(?:"|$)|'((?:[^\\']|\\\\|\\')*)(?:'|$)|([^:,\s]+)))/g; const phraseRE = new RegExp( new RegExp('((?:' + quotedValue.source + ':|))').source + - /(-?)/.source + - quotedValue.source + - new RegExp('((?:,' + quotedValue.source + ')*)').source, 'g'); + /(-?)/.source + + quotedValue.source + + new RegExp('((?:,' + quotedValue.source + ')*)').source, + 'g' + ); filter = []; [...val.matchAll(phraseRE)].forEach((match) => { - const coltag = this._unescapePhrase(match[5] || match[4] || match[3]); - const phrase = this._unescapePhrase(match[10] || match[9] || match[8]); + const coltag = this._unescapePhrase( + match[5] || match[4] || match[3] + ); + const phrase = this._unescapePhrase( + match[10] || match[9] || match[8] + ); const negation = match[6] === '-'; - var phrases = [{phrase: phrase, exact: match[8] !== undefined}]; + var phrases = [ + {phrase: phrase, exact: match[8] !== undefined} + ]; if (match[11]) { [...match[11].matchAll(quotedValue)].forEach((submatch) => { - const subphrase = this._unescapePhrase(submatch[4] || submatch[3] || submatch[2]); + const subphrase = this._unescapePhrase( + submatch[4] || submatch[3] || submatch[2] + ); // remove dupes? if (subphrase && subphrase.length) { - phrases.push({phrase: subphrase, exact: submatch[2] !== undefined}); + phrases.push({ + phrase: subphrase, + exact: submatch[2] !== undefined + }); } }); } - const key = `${coltag || ''}:` + phrases.map((p) => p.phrase + (p.exact ? '__exact__' : '')).join('|||'); + const key = + `${coltag || ''}:` + + phrases + .map((p) => p.phrase + (p.exact ? '__exact__' : '')) + .join('|||'); if (!phrases.length || usedPhrases[key]) { return; } @@ -361,15 +472,27 @@ wrap(ItemListWidget, 'render', function (render) { * notation, delta is the value of one for the least * significant digit. This will be NaN if phrase is not a * number. */ - const delta = Math.abs(+numval.toString().replace(/\d(?=.*[1-9](0*\.|)0*$)/g, '0').replace(/[1-9]/, '1')); + const delta = Math.abs( + +numval + .toString() + .replace(/\d(?=.*[1-9](0*\.|)0*$)/g, '0') + .replace(/[1-9]/, '1') + ); // escape for regex phrase = phrase.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); columns.forEach((col) => { let key; - if (coltag && - coltag.localeCompare(col.title || col.value, undefined, {sensitivity: 'accent'}) && - coltag.localeCompare(col.value, undefined, {sensitivity: 'accent'}) + if ( + coltag && + coltag.localeCompare( + col.title || col.value, + undefined, + {sensitivity: 'accent'} + ) && + coltag.localeCompare(col.value, undefined, { + sensitivity: 'accent' + }) ) { return; } @@ -379,24 +502,50 @@ wrap(ItemListWidget, 'render', function (render) { key = 'meta.' + col.value; } if (!coltag && !exact) { - const r = new RegExp('^' + (phrase.substr(phrase.length - 1) === ':' ? phrase.substr(0, phrase.length - 1) : phrase), 'i'); - if (r.exec(col.value) || r.exec(col.title || col.value)) { + const r = new RegExp( + '^' + + (phrase.substr(phrase.length - 1) === ':' + ? phrase.substr(0, phrase.length - 1) + : phrase), + 'i' + ); + if ( + r.exec(col.value) || + r.exec(col.title || col.value) + ) { clause.push({[key]: {$exists: true}}); } } if (key && exact) { - clause.push({[key]: {$regex: '^' + phrase + '$', $options: 'i'}}); + clause.push({ + [key]: { + $regex: '^' + phrase + '$', + $options: 'i' + } + }); if (!_.isNaN(numval)) { clause.push({[key]: numval}); } } else if (key) { - clause.push({[key]: {$regex: phrase, $options: 'i'}}); + clause.push({ + [key]: {$regex: phrase, $options: 'i'} + }); if (!_.isNaN(numval)) { clause.push({[key]: numval}); if (numval > 0 && delta) { - clause.push({[key]: {$gte: numval, $lt: numval + delta}}); + clause.push({ + [key]: { + $gte: numval, + $lt: numval + delta + } + }); } else if (numval < 0 && delta) { - clause.push({[key]: {$lte: numval, $gt: numval + delta}}); + clause.push({ + [key]: { + $lte: numval, + $gt: numval + delta + } + }); } } } @@ -405,7 +554,9 @@ wrap(ItemListWidget, 'render', function (render) { if (clause.length > 0) { filter.push(!negation ? {$or: clause} : {$nor: clause}); } else if (!negation) { - filter.push({$or: [{_no_such_value_: '_no_such_value_'}]}); + filter.push({ + $or: [{_no_such_value_: '_no_such_value_'}] + }); } }); if (filter.length === 0) { @@ -425,7 +576,12 @@ wrap(ItemListWidget, 'render', function (render) { let grouping = '_group_:meta.' + group.keys.join(',meta.'); if (group.counts) { for (let [gkey, gval] of Object.entries(group.counts)) { - if (!gkey.includes(',') && !gkey.includes(':') && !gval.includes(',') && !gval.includes(':')) { + if ( + !gkey.includes(',') && + !gkey.includes(':') && + !gval.includes(',') && + !gval.includes(':') + ) { if (gkey !== '_id') { gkey = `meta.${gkey}`; } @@ -439,7 +595,10 @@ wrap(ItemListWidget, 'render', function (render) { if (this._recurse) { filter = '_recurse_:' + (filter || ''); } - if (filter !== this._filter || filter !== (this.collection.params || {}).text) { + if ( + filter !== this._filter || + filter !== (this.collection.params || {}).text + ) { this._filter = filter; this.collection.params = this.collection.params || {}; this.collection.params.text = this._filter; @@ -454,22 +613,34 @@ wrap(ItemListWidget, 'render', function (render) { const folders = [this.parentView.parentModel]; const canHandle = {items: {}, folders: {}}; // TODO: handle checked resources - Object.entries(ItemListWidget.registeredApplications).forEach(([appname, app]) => { - items.forEach((item) => { - const check = app.check('item', item, this.parentView.parentModel); - if (check) { - canHandle.items[item.id] = canHandle.items[item.id] || {}; - canHandle.items[item.id][appname] = check; - } - }); - folders.forEach((folder) => { - const check = app.check('item', folder, this.parentView.parentModel); - if (check) { - canHandle.folders[folder.id] = canHandle.folders[folder.id] || {}; - canHandle.folders[folder.id][appname] = check; - } - }); - }); + Object.entries(ItemListWidget.registeredApplications).forEach( + ([appname, app]) => { + items.forEach((item) => { + const check = app.check( + 'item', + item, + this.parentView.parentModel + ); + if (check) { + canHandle.items[item.id] = + canHandle.items[item.id] || {}; + canHandle.items[item.id][appname] = check; + } + }); + folders.forEach((folder) => { + const check = app.check( + 'item', + folder, + this.parentView.parentModel + ); + if (check) { + canHandle.folders[folder.id] = + canHandle.folders[folder.id] || {}; + canHandle.folders[folder.id][appname] = check; + } + }); + } + ); return canHandle; }; @@ -491,11 +662,17 @@ wrap(ItemListWidget, 'render', function (render) { if ((nav.name || '') === (this._namedList || '')) { return; } - if (!this._liconfig || !this._liconfig.namedItemLists || (nav.name && !this._liconfig.namedItemLists[nav.name])) { + if ( + !this._liconfig || + !this._liconfig.namedItemLists || + (nav.name && !this._liconfig.namedItemLists[nav.name]) + ) { return; } this.collection.forEach((item) => { - item._href = `#folder/${this.parentView.parentModel.id}?namedList=` + (nav.name ? encodeURIComponent(nav.name) : ''); + item._href = + `#folder/${this.parentView.parentModel.id}?namedList=` + + (nav.name ? encodeURIComponent(nav.name) : ''); let filter = ''; if (list.group) { list.group.keys.forEach((col) => { @@ -504,7 +681,10 @@ wrap(ItemListWidget, 'render', function (render) { val = (val || {})[part]; }); if (/[ '\\]/.exec(col)) { - col = "'" + col.replace('\\', '\\\\').replace("'", "\\'") + "'"; + col = + "'" + + col.replace('\\', '\\\\').replace("'", "\\'") + + "'"; } if (val) { val = val.replace('\\', '\\\\').replace('"', '\\"'); @@ -525,7 +705,23 @@ wrap(ItemListWidget, 'render', function (render) { app = apps[nav.name]; } if (!app) { - apps = Object.entries(apps).sort(([name1, app1], [name2, app2]) => { const diff = (app1.priority || 0) - (app2.priority || 0); return diff || (ItemListWidget.registeredApplications[name1].name.toLowerCase() > ItemListWidget.registeredApplications[name2].name.toLowerCase() ? 1 : -1); }); + apps = Object.entries(apps).sort( + ([name1, app1], [name2, app2]) => { + const diff = + (app1.priority || 0) - (app2.priority || 0); + return ( + diff || + (ItemListWidget.registeredApplications[ + name1 + ].name.toLowerCase() > + ItemListWidget.registeredApplications[ + name2 + ].name.toLowerCase() + ? 1 + : -1) + ); + } + ); app = apps[0][1]; } if (app.url && app.url !== true) { @@ -542,68 +738,89 @@ wrap(ItemListWidget, 'render', function (render) { } const root = this.$el.closest('.g-hierarchy-widget'); if (!root.find('.li-item-list-filter').length) { - let base = root.find('.g-hierarchy-actions-header .g-folder-header-buttons').eq(0); + let base = root + .find('.g-hierarchy-actions-header .g-folder-header-buttons') + .eq(0); const func = 'before'; if (!base.length) { - base = root.find('.g-hierarchy-breadcrumb-bar>.breadcrumb>div').eq(0); + base = root + .find('.g-hierarchy-breadcrumb-bar>.breadcrumb>div') + .eq(0); } if (base.length) { base.parent().addClass('li-item-list-filter-parent'); - base[func]('Filter: ' + - '' + - ''); + base[func]( + 'Filter: ' + + '' + + '' + ); if (this._generalFilter) { - root.find('.li-item-list-filter-input').val(this._generalFilter); + root.find('.li-item-list-filter-input').val( + this._generalFilter + ); } - this.parentView.events['change .li-item-list-filter-input'] = this._updateFilter; - this.parentView.events['input .li-item-list-filter-input'] = this._updateFilter; - this.parentView.events['click .li-item-list-filter-clear'] = (evt) => { - this.parentView.$el.find('.li-item-list-filter-input').val(''); + this.parentView.events['change .li-item-list-filter-input'] = + this._updateFilter; + this.parentView.events['input .li-item-list-filter-input'] = + this._updateFilter; + this.parentView.events['click .li-item-list-filter-clear'] = ( + evt + ) => { + this.parentView.$el + .find('.li-item-list-filter-input') + .val(''); this._clearFilter(); }; this.parentView.delegateEvents(); } } - if (!this._lastSort && this._confList() && this._confList().defaultSort && this._confList().defaultSort.length) { + if ( + !this._lastSort && + this._confList() && + this._confList().defaultSort && + this._confList().defaultSort.length + ) { this._lastSort = this._confList().defaultSort; this._setSort(); return; } const availableApps = this.checkApps(); adjustItemHref.call(this, availableApps); - this.$el.html(ItemListTemplate({ - items: this.collection.toArray(), - isParentPublic: this.public, - hasMore: this.collection.hasNextPage(), - formatSize: formatSize, - checkboxes: this._checkboxes, - downloadLinks: this._downloadLinks, - viewLinks: this._viewLinks, - showSizes: this._showSizes, - highlightItem: this._highlightItem, - selectedItemId: (this._selectedItem || {}).id, - paginated: this._paginated, - apiRoot: getApiRoot(), - hasAnyLargeImage: this._hasAnyLargeImage, - itemList: this._confList(), - sort: this._lastSort, - MetadatumWidget: MetadatumWidget, - accessLevel: this.accessLevel, - registeredApps: ItemListWidget.registeredApplications, - availableApps: availableApps, - parentView: this, - AccessType: AccessType - })); + this.$el.html( + ItemListTemplate({ + items: this.collection.toArray(), + isParentPublic: this.public, + hasMore: this.collection.hasNextPage(), + formatSize: formatSize, + checkboxes: this._checkboxes, + downloadLinks: this._downloadLinks, + viewLinks: this._viewLinks, + showSizes: this._showSizes, + highlightItem: this._highlightItem, + selectedItemId: (this._selectedItem || {}).id, + paginated: this._paginated, + apiRoot: getApiRoot(), + hasAnyLargeImage: this._hasAnyLargeImage, + itemList: this._confList(), + sort: this._lastSort, + MetadatumWidget: MetadatumWidget, + accessLevel: this.accessLevel, + registeredApps: ItemListWidget.registeredApplications, + availableApps: availableApps, + parentView: this, + AccessType: AccessType + }) + ); const parent = this.$el; this.$el.find('.large_image_thumbnail').each(function () { @@ -661,19 +878,31 @@ function sortColumn(evt) { type: header.attr('column_type'), value: header.attr('column_value') }; - const curDir = header.hasClass('down') ? 'down' : header.hasClass('up') ? 'up' : null; + const curDir = header.hasClass('down') + ? 'down' + : header.hasClass('up') + ? 'up' + : null; const nextDir = curDir === 'down' ? 'up' : 'down'; - header.toggleClass('down', nextDir === 'down').toggleClass('up', nextDir === 'up'); + header + .toggleClass('down', nextDir === 'down') + .toggleClass('up', nextDir === 'up'); entry.dir = nextDir; const oldSort = this._lastSort; if (!this._lastSort) { this._lastSort = []; } - this._lastSort = this._lastSort.filter((e) => e.type !== entry.type || e.value !== entry.value); + this._lastSort = this._lastSort.filter( + (e) => e.type !== entry.type || e.value !== entry.value + ); this._lastSort.unshift(entry); this._setSort(); if (!_.isEqual(this._lastSort, oldSort)) { - addToRoute({sort: this._lastSort.map((e) => `${e.type}:${e.value}:${e.dir}`).join(',')}); + addToRoute({ + sort: this._lastSort + .map((e) => `${e.type}:${e.value}:${e.dir}`) + .join(',') + }); } } @@ -687,7 +916,10 @@ function addCellToFilter(cell, update) { val = val.replace('\\', '\\\\').replace('"', '\\"'); filter += ` ${col}:"${val}"`; filter = filter.trim(); - this.$el.closest('.g-hierarchy-widget').find('.li-item-list-filter-input').val(filter); + this.$el + .closest('.g-hierarchy-widget') + .find('.li-item-list-filter-input') + .val(filter); this._generalFilter = filter; if (update !== false) { this._setFilter(); @@ -713,7 +945,11 @@ function itemListMetadataEdit(evt) { const column = columns[+ctrl.attr('column-idx')]; let tempValue = ctrl.find('.g-widget-metadata-value-input').val(); tempValue = tempValue.trim(); - let valResult = validateMetadataValue(column, tempValue, this._lastValidationError || (tempValue === '' && !column.required)); + let valResult = validateMetadataValue( + column, + tempValue, + this._lastValidationError || (tempValue === '' && !column.required) + ); if (tempValue === '' && !column.required) { valResult = {value: tempValue}; } @@ -722,7 +958,9 @@ function itemListMetadataEdit(evt) { return false; } this._lastValidationError = false; - const item = this.collection.get(ctrl.closest('[g-item-cid]').attr('g-item-cid')); + const item = this.collection.get( + ctrl.closest('[g-item-cid]').attr('g-item-cid') + ); let value = item.get('meta') || {}; let meta; let key; diff --git a/girder/girder_large_image/web_client/views/itemView.js b/girder/girder_large_image/web_client/views/itemView.js index 99cf325d5..1ef531e59 100644 --- a/girder/girder_large_image/web_client/views/itemView.js +++ b/girder/girder_large_image/web_client/views/itemView.js @@ -3,9 +3,9 @@ import ItemViewWidget from './itemViewWidget'; import '../stylesheets/itemView.styl'; const $ = girder.$; -const { AccessType } = girder.constants; -const { restRequest } = girder.rest; -const { wrap } = girder.utilities.PluginUtils; +const {AccessType} = girder.constants; +const {restRequest} = girder.rest; +const {wrap} = girder.utilities.PluginUtils; const ItemView = girder.views.body.ItemView; wrap(ItemView, 'render', function (render) { diff --git a/girder/girder_large_image/web_client/views/itemViewCodemirror.js b/girder/girder_large_image/web_client/views/itemViewCodemirror.js index 5a4721f23..e588f9b2c 100644 --- a/girder/girder_large_image/web_client/views/itemViewCodemirror.js +++ b/girder/girder_large_image/web_client/views/itemViewCodemirror.js @@ -20,12 +20,12 @@ import itemViewCodemirror from '../templates/itemViewCodemirror.pug'; import '../stylesheets/itemViewCodemirror.styl'; const $ = girder.$; -const { getCurrentUser } = girder.auth; -const { AccessType } = girder.constants; -const { confirm } = girder.dialog; +const {getCurrentUser} = girder.auth; +const {AccessType} = girder.constants; +const {confirm} = girder.dialog; const events = girder.events; -const { restRequest } = girder.rest; -const { wrap } = girder.utilities.PluginUtils; +const {restRequest} = girder.rest; +const {wrap} = girder.utilities.PluginUtils; const ItemView = girder.views.body.ItemView; const View = girder.views.View; diff --git a/girder/girder_large_image/web_client/views/itemViewWidget.js b/girder/girder_large_image/web_client/views/itemViewWidget.js index f994d2d11..c87ba771c 100644 --- a/girder/girder_large_image/web_client/views/itemViewWidget.js +++ b/girder/girder_large_image/web_client/views/itemViewWidget.js @@ -2,7 +2,7 @@ import yaml from 'js-yaml'; import itemViewWidgetTemplate from '../templates/itemView.pug'; -const { getApiRoot } = girder.rest; +const {getApiRoot} = girder.rest; const View = girder.views.View; var ItemViewWidget = View.extend({ diff --git a/girder/girder_large_image/web_client/vue/index.js b/girder/girder_large_image/web_client/vue/index.js index 093413f03..2dce3251a 100644 --- a/girder/girder_large_image/web_client/vue/index.js +++ b/girder/girder_large_image/web_client/vue/index.js @@ -1,8 +1,8 @@ -import CompositeLayers from "./components/CompositeLayers.vue"; -import DualInput from "./components/DualInput.vue"; -import FrameSelector from "./components/FrameSelector.vue"; -import HistogramEditor from "./components/HistogramEditor.vue"; -import PresetsMenu from "./components/PresetsMenu.vue"; +import CompositeLayers from './components/CompositeLayers.vue'; +import DualInput from './components/DualInput.vue'; +import FrameSelector from './components/FrameSelector.vue'; +import HistogramEditor from './components/HistogramEditor.vue'; +import PresetsMenu from './components/PresetsMenu.vue'; export { CompositeLayers, diff --git a/girder_annotation/girder_large_image_annotation/web_client/collections/index.js b/girder_annotation/girder_large_image_annotation/web_client/collections/index.js index 8ab00d859..ae560e16e 100644 --- a/girder_annotation/girder_large_image_annotation/web_client/collections/index.js +++ b/girder_annotation/girder_large_image_annotation/web_client/collections/index.js @@ -3,5 +3,5 @@ import ElementCollection from './ElementCollection'; export { AnnotationCollection, - ElementCollection, + ElementCollection }; diff --git a/girder_annotation/girder_large_image_annotation/web_client/main.js b/girder_annotation/girder_large_image_annotation/web_client/main.js index 170ce2e84..873d8ce35 100644 --- a/girder_annotation/girder_large_image_annotation/web_client/main.js +++ b/girder_annotation/girder_large_image_annotation/web_client/main.js @@ -6,7 +6,7 @@ import './views/imageViewerSelectWidget'; import * as largeImageAnnotation from './index'; const SearchFieldWidget = girder.views.widgets.SearchFieldWidget; -const { registerPluginNamespace } = girder.pluginUtils; +const {registerPluginNamespace} = girder.pluginUtils; registerPluginNamespace('large_image_annotation', largeImageAnnotation); diff --git a/girder_annotation/girder_large_image_annotation/web_client/views/configView.js b/girder_annotation/girder_large_image_annotation/web_client/views/configView.js index b8052d029..2a654efdc 100644 --- a/girder_annotation/girder_large_image_annotation/web_client/views/configView.js +++ b/girder_annotation/girder_large_image_annotation/web_client/views/configView.js @@ -77,16 +77,16 @@ var ConfigView = View.extend({ * fetched. If the settings are already present, this is called * without any delay. */ - getSettings: function(callback) { + getSettings: function (callback) { return girder.plugins.large_image.views.ConfigView.getSettings(callback); }, /** * Clear the settings so that getSettings will refetch them. */ - clearSettings: function() { + clearSettings: function () { return girder.plugins.large_image.views.ConfigView.clearSettings(); - }, + } }); export default ConfigView; diff --git a/girder_annotation/girder_large_image_annotation/web_client/views/index.js b/girder_annotation/girder_large_image_annotation/web_client/views/index.js index 819261880..62a3b9b68 100644 --- a/girder_annotation/girder_large_image_annotation/web_client/views/index.js +++ b/girder_annotation/girder_large_image_annotation/web_client/views/index.js @@ -1,4 +1,3 @@ - import ConfigView from './configView'; import HierarchyWidget from './hierarchyWidget'; import './imageViewerSelectWidget'; From 04a3e13df8437f97511b170090ebf96ce359e4ea Mon Sep 17 00:00:00 2001 From: naglepuff Date: Wed, 11 Dec 2024 17:02:36 -0500 Subject: [PATCH 09/12] Ignore G002 and G004 errors Adding this primarily as a stopgap. It might be worthwhile to go back and clean this issues up before merging the Girder 5 branch. --- pyproject.toml | 2 ++ tox.ini | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 0eb22d599..bea5cbbf8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -36,6 +36,8 @@ lint.ignore = [ "PT011", "PT012", "PT017", + "G002", + "G004" ] line-length = 100 lint.select = [ diff --git a/tox.ini b/tox.ini index 9a640d01a..8c68fb913 100644 --- a/tox.ini +++ b/tox.ini @@ -367,7 +367,7 @@ exclude = */web_client/* */*egg*/* # Ignore missing docstring errors. -ignore = D100,D101,D102,D103,D104,D105,D106,D107,D200,D205,D400,D401,E741,W504,B017,C408 +ignore = D100,D101,D102,D103,D104,D105,D106,D107,D200,D205,D400,D401,E741,W504,B017,C408,G002,G004 per-file-ignores = docs/*.py: E501 [pytest] From c1ba777b9fb2c927ffc98302197766cdc3c705db Mon Sep 17 00:00:00 2001 From: naglepuff Date: Wed, 11 Dec 2024 17:02:45 -0500 Subject: [PATCH 10/12] Format python --- docs/format_examples_datastore.py | 12 ++- girder/girder_large_image/__init__.py | 2 +- .../rest/annotation.py | 2 +- sources/zarr/setup.py | 83 ++++++++++--------- utilities/tasks/large_image_tasks/tasks.py | 1 - 5 files changed, 52 insertions(+), 48 deletions(-) diff --git a/docs/format_examples_datastore.py b/docs/format_examples_datastore.py index 2ee00ff06..ab5126200 100644 --- a/docs/format_examples_datastore.py +++ b/docs/format_examples_datastore.py @@ -100,7 +100,8 @@ examples=[ dict( filename='sample_image.nd2', - # originally from 'https://downloads.openmicroscopy.org/images/ND2/aryeh/MeOh_high_fluo_003.nd2', + # originally from + # 'https://downloads.openmicroscopy.org/images/ND2/aryeh/MeOh_high_fluo_003.nd2', url='https://data.kitware.com/api/v1/file/hashsum/sha512/4e76e490c915b10f646cb516f85a4d36d52aa7eff94715b90222644180e26fef6768493887c05adf182cf0351ba0bce659204041c4698a0f6b08423586788f4d/download', hash='8e23bb594cd18314f9c18e70d736088ae46f8bc696ab7dc047784be416d7a706', ), @@ -127,7 +128,8 @@ examples=[ dict( filename='US-MONO2-8-8x-execho.dcm', - # originally from 'https://downloads.openmicroscopy.org/images/DICOM/samples/US-MONO2-8-8x-execho.dcm', + # originally from + # 'https://downloads.openmicroscopy.org/images/DICOM/samples/US-MONO2-8-8x-execho.dcm', url='https://data.kitware.com/api/v1/file/hashsum/sha512/5332044f887d82c7f3693c6ca180f07accf5f00c2b7b1a3a29ef9ae737d5f1975478b5e2d5846c391987b8051416068f57a7062e848323c700412236b35679db/download', hash='7d3f54806d0315c6cfc8b7371649a242b5ef8f31e0d20221971dd8087f2ff1ea', ), @@ -141,7 +143,8 @@ examples=[ dict( filename='20191025 Test FRET 585. 423, 426.lif', - # originally from 'https://downloads.openmicroscopy.org/images/Leica-LIF/imagesc-30856/20191025%20Test%20FRET%20585.%20423,%20426.lif', + # originally from + # 'https://downloads.openmicroscopy.org/images/Leica-LIF/imagesc-30856/20191025%20Test%20FRET%20585.%20423,%20426.lif', url='https://data.kitware.com/api/v1/file/hashsum/sha512/d25de002d8a81dfcaf6b062b9f429ca85bb81423bc09d3aa33d9d51e9392cc4ace2b8521475e373ceecaf958effd0fade163e7173c467aab66c957da14482ed7/download', hash='8d4ee62868b9616b832c2eb28e7d62ec050fb032e0bc11ea0a392f5c84390c71', ), @@ -155,7 +158,8 @@ examples=[ dict( filename='Animated_PNG_example_bouncing_beach_ball.png', - # originally from 'https://upload.wikimedia.org/wikipedia/commons/1/14/Animated_PNG_example_bouncing_beach_ball.png', + # originally from + # 'https://upload.wikimedia.org/wikipedia/commons/1/14/Animated_PNG_example_bouncing_beach_ball.png', url='https://data.kitware.com/api/v1/file/hashsum/sha512/465ebdc2e81b2576dfc96b34e82db7f968e6d4f32f0fa80ef4bb0e44ed216230e6be1a2e4b11ae301a2905cc582dd24cbd2c360d9567ff7b1dac2c871f6d1e37/download', hash='3b28e2462f1b31d0d15d795e6e58baf397899c3f864be7034bf47939b5bbbc3b', ), diff --git a/girder/girder_large_image/__init__.py b/girder/girder_large_image/__init__.py index 8933351f1..5aa1dc90f 100644 --- a/girder/girder_large_image/__init__.py +++ b/girder/girder_large_image/__init__.py @@ -18,7 +18,6 @@ import hashlib import json import logging -from pathlib import Path import os import re import threading @@ -26,6 +25,7 @@ import warnings from importlib.metadata import PackageNotFoundError from importlib.metadata import version as _importlib_version +from pathlib import Path import yaml from girder_jobs.constants import JobStatus diff --git a/girder_annotation/girder_large_image_annotation/rest/annotation.py b/girder_annotation/girder_large_image_annotation/rest/annotation.py index 20cf6eef3..066290c10 100644 --- a/girder_annotation/girder_large_image_annotation/rest/annotation.py +++ b/girder_annotation/girder_large_image_annotation/rest/annotation.py @@ -39,9 +39,9 @@ from ..models.annotation import Annotation, AnnotationSchema from ..models.annotationelement import Annotationelement - logger = logging.getLogger(__name__) + class AnnotationResource(Resource): def __init__(self): diff --git a/sources/zarr/setup.py b/sources/zarr/setup.py index b9a4c9d3f..998ca1264 100644 --- a/sources/zarr/setup.py +++ b/sources/zarr/setup.py @@ -2,8 +2,8 @@ from setuptools import find_packages, setup -description = "A OME Zarr tilesource for large_image." -long_description = description + "\n\nSee the large-image package for more details." +description = 'A OME Zarr tilesource for large_image.' +long_description = description + '\n\nSee the large-image package for more details.' def prerelease_local_scheme(version): @@ -17,8 +17,8 @@ def prerelease_local_scheme(version): """ from setuptools_scm.version import get_local_node_and_date - if os.getenv("CIRCLE_BRANCH") in ("master",): - return "" + if os.getenv('CIRCLE_BRANCH') in ('master',): + return '' else: return get_local_node_and_date(version) @@ -26,63 +26,64 @@ def prerelease_local_scheme(version): try: from setuptools_scm import get_version - version = get_version(root="../..", local_scheme=prerelease_local_scheme) + version = get_version(root='../..', local_scheme=prerelease_local_scheme) limit_version = ( - f">={version}" if "+" not in version and not os.getenv("TOX_ENV_NAME") else "" + f'>={version}' if '+' not in version and not os.getenv('TOX_ENV_NAME') else '' ) except (ImportError, LookupError): - limit_version = "" + limit_version = '' setup( - name="large-image-source-zarr", + name='large-image-source-zarr', use_scm_version={ - "root": "../..", - "local_scheme": prerelease_local_scheme, - "fallback_version": "0.0.0", + 'root': '../..', + 'local_scheme': prerelease_local_scheme, + 'fallback_version': '0.0.0', }, description=description, long_description=long_description, - long_description_content_type="text/x-rst", - license="Apache Software License 2.0", - author="Kitware, Inc.", - author_email="kitware@kitware.com", + long_description_content_type='text/x-rst', + license='Apache Software License 2.0', + author='Kitware, Inc.', + author_email='kitware@kitware.com', classifiers=[ - "Development Status :: 5 - Production/Stable", - "License :: OSI Approved :: Apache Software License", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.11", - "Programming Language :: Python :: 3.12", - "Programming Language :: Python :: 3.13", + 'Development Status :: 5 - Production/Stable', + 'License :: OSI Approved :: Apache Software License', + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.8', + 'Programming Language :: Python :: 3.9', + 'Programming Language :: Python :: 3.10', + 'Programming Language :: Python :: 3.11', + 'Programming Language :: Python :: 3.12', + 'Programming Language :: Python :: 3.13', ], install_requires=[ - f"large-image{limit_version}", - # Pin zarr < 3.0 due to refactoring of stores: https://github.com/zarr-developers/zarr-python/issues/1274 - "zarr<3", + f'large-image{limit_version}', + # Pin zarr < 3.0 due to refactoring of stores: + # https://github.com/zarr-developers/zarr-python/issues/1274 + 'zarr<3', # numcodecs and imagecodecs had been required by zarr, but now needs to be asked for - "imagecodecs", - "numcodecs", + 'imagecodecs', + 'numcodecs', # Without imagecodecs-numcodecs, some jpeg encoded data cannot be read - "imagecodecs-numcodecs!=2024.9.22", + 'imagecodecs-numcodecs!=2024.9.22', ], extras_require={ - "girder": f"girder-large-image{limit_version}", - "all": [ - "large-image-converter", + 'girder': f'girder-large-image{limit_version}', + 'all': [ + 'large-image-converter', ], }, - keywords="large_image, tile source", - packages=find_packages(exclude=["test", "test.*"]), - url="https://github.com/girder/large_image", - python_requires=">=3.6", + keywords='large_image, tile source', + packages=find_packages(exclude=['test', 'test.*']), + url='https://github.com/girder/large_image', + python_requires='>=3.6', entry_points={ - "large_image.source": [ - "zarr = large_image_source_zarr:ZarrFileTileSource", + 'large_image.source': [ + 'zarr = large_image_source_zarr:ZarrFileTileSource', ], - "girder_large_image.source": [ - "zarr = large_image_source_zarr.girder_source:ZarrGirderTileSource", + 'girder_large_image.source': [ + 'zarr = large_image_source_zarr.girder_source:ZarrGirderTileSource', ], }, ) diff --git a/utilities/tasks/large_image_tasks/tasks.py b/utilities/tasks/large_image_tasks/tasks.py index 2caabb738..c6073fcf9 100644 --- a/utilities/tasks/large_image_tasks/tasks.py +++ b/utilities/tasks/large_image_tasks/tasks.py @@ -202,7 +202,6 @@ def cache_histograms_job(job): from girder_jobs.models.job import Job from girder_large_image.models.image_item import ImageItem - kwargs = job['kwargs'] item = ImageItem().load(kwargs.pop('itemId'), force=True) job = Job().updateJob( From 6f771742f5f5418f5b992025be2eb307ceda07dd Mon Sep 17 00:00:00 2001 From: naglepuff Date: Thu, 12 Dec 2024 12:09:53 -0500 Subject: [PATCH 11/12] Add format-only commits to blame ignore revs --- .git-blame-ignore-revs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index 8e90f1e5f..d31641649 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -17,3 +17,7 @@ dcda95e659a4eaa73cae85ab02f1b89059e63c32 f517ecb2b7d8c454d1374156452be42b87ca3fd1 # PR 1604: Handle ruff linting rule changes e62083dab9a190d94841b3f4089850f43e2c9932 +# PR 1728: Format client and python code +c1ba777b9fb2c927ffc98302197766cdc3c705db +3bff2771141b2d77821e29f96ac9de0428856e3d + From 5e853900511e7669950f52d19d95f6f7c311b335 Mon Sep 17 00:00:00 2001 From: naglepuff Date: Thu, 12 Dec 2024 12:20:45 -0500 Subject: [PATCH 12/12] Use node 20 for tests --- .circleci/config.yml | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 8bcd5b13f..97692a6ef 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -57,6 +57,7 @@ commands: type: string node: type: string + default: v20 steps: - switchpython: version: << parameters.version >> @@ -175,7 +176,6 @@ jobs: - checkout - allservices: version: "3.8" - node: v16 - tox: toxenv: test-py38 - coverage @@ -189,7 +189,6 @@ jobs: - checkout - allservices: version: "3.9" - node: v16 - tox: toxenv: test-py39 - coverage @@ -203,7 +202,6 @@ jobs: - checkout - allservices: version: "3.10" - node: v16 - tox: toxenv: test-py310 - coverage @@ -217,7 +215,6 @@ jobs: - checkout - allservices: version: "3.11" - node: v16 - tox: toxenv: test-py311 - coverage @@ -231,7 +228,6 @@ jobs: - checkout - allservices: version: "3.12" - node: v16 - tox: toxenv: test-py312 - coverage @@ -245,7 +241,6 @@ jobs: - checkout - allservices: version: "3.13" - node: v16 - tox: toxenv: test-py313 environ: TOX_VERBOSE=4 TOX_PREFER_BINARY=1