girder-import-tracker 5.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (23) hide show
  1. girder_import_tracker-5.0.0/MANIFEST.in +3 -0
  2. girder_import_tracker-5.0.0/PKG-INFO +29 -0
  3. girder_import_tracker-5.0.0/README.md +3 -0
  4. girder_import_tracker-5.0.0/girder_import_tracker/__init__.py +33 -0
  5. girder_import_tracker-5.0.0/girder_import_tracker/girder_worker_plugin.py +140 -0
  6. girder_import_tracker-5.0.0/girder_import_tracker/models.py +45 -0
  7. girder_import_tracker-5.0.0/girder_import_tracker/rest.py +146 -0
  8. girder_import_tracker-5.0.0/girder_import_tracker/utils.py +126 -0
  9. girder_import_tracker-5.0.0/girder_import_tracker/web_client/dist/girder-plugin-import-tracker.umd.cjs +18 -0
  10. girder_import_tracker-5.0.0/girder_import_tracker/web_client/dist/style.css +1 -0
  11. girder_import_tracker-5.0.0/girder_import_tracker.egg-info/PKG-INFO +29 -0
  12. girder_import_tracker-5.0.0/girder_import_tracker.egg-info/SOURCES.txt +21 -0
  13. girder_import_tracker-5.0.0/girder_import_tracker.egg-info/dependency_links.txt +1 -0
  14. girder_import_tracker-5.0.0/girder_import_tracker.egg-info/entry_points.txt +5 -0
  15. girder_import_tracker-5.0.0/girder_import_tracker.egg-info/not-zip-safe +1 -0
  16. girder_import_tracker-5.0.0/girder_import_tracker.egg-info/requires.txt +2 -0
  17. girder_import_tracker-5.0.0/girder_import_tracker.egg-info/top_level.txt +1 -0
  18. girder_import_tracker-5.0.0/plugin.cmake +1 -0
  19. girder_import_tracker-5.0.0/plugin_tests/__init__.py +0 -0
  20. girder_import_tracker-5.0.0/plugin_tests/test_load.py +8 -0
  21. girder_import_tracker-5.0.0/pyproject.toml +6 -0
  22. girder_import_tracker-5.0.0/setup.cfg +4 -0
  23. girder_import_tracker-5.0.0/setup.py +66 -0
@@ -0,0 +1,3 @@
1
+ prune girder_import_tracker/web_client
2
+ include girder_import_tracker/web_client/dist/girder-plugin-import-tracker.umd.cjs
3
+ include girder_import_tracker/web_client/dist/style.css
@@ -0,0 +1,29 @@
1
+ Metadata-Version: 2.4
2
+ Name: girder-import-tracker
3
+ Version: 5.0.0
4
+ Summary: A Girder plugin for data import tracking
5
+ Home-page: https://github.com/girder/girder/tree/master/plugins/import_tracker
6
+ Author: Kitware, Inc.
7
+ Author-email: kitware@kitware.com
8
+ License: Apache 2.0
9
+ Keywords: girder-plugin,import_tracker
10
+ Classifier: Development Status :: 5 - Production/Stable
11
+ Classifier: Natural Language :: English
12
+ Classifier: Programming Language :: Python :: 3
13
+ Description-Content-Type: text/markdown
14
+ Requires-Dist: girder-jobs>=3.0.3
15
+ Requires-Dist: girder>=3.1.23
16
+ Dynamic: author
17
+ Dynamic: author-email
18
+ Dynamic: classifier
19
+ Dynamic: description
20
+ Dynamic: description-content-type
21
+ Dynamic: home-page
22
+ Dynamic: keywords
23
+ Dynamic: license
24
+ Dynamic: requires-dist
25
+ Dynamic: summary
26
+
27
+ # import-tracker
28
+
29
+ A Girder plugin for data import tracking in HistomicsUI
@@ -0,0 +1,3 @@
1
+ # import-tracker
2
+
3
+ A Girder plugin for data import tracking in HistomicsUI
@@ -0,0 +1,33 @@
1
+ from pathlib import Path
2
+
3
+ from girder import plugin
4
+
5
+ from .rest import getImport, listAllImports, listImports, moveFolder
6
+
7
+
8
+ class GirderPlugin(plugin.GirderPlugin):
9
+ DISPLAY_NAME = 'import_tracker'
10
+
11
+ def load(self, info):
12
+ plugin.getPlugin('jobs').load(info)
13
+
14
+ info['apiRoot'].assetstore.route('GET', (':id', 'imports'), listImports)
15
+ info['apiRoot'].assetstore.route('GET', ('all_imports',), listAllImports)
16
+ info['apiRoot'].assetstore.route('GET', ('import', ':id'), getImport)
17
+
18
+ info['apiRoot'].assetstore.importData.description.param(
19
+ 'excludeExisting',
20
+ 'If true, then a file with an import path that is already in the '
21
+ 'system is not imported, even if it is not in the destination '
22
+ 'hierarchy.', dataType='boolean', required=False, default=False
23
+ )
24
+
25
+ info['apiRoot'].folder.route('PUT', (':id', 'move'), moveFolder)
26
+
27
+ plugin.registerPluginStaticContent(
28
+ plugin='import-tracker',
29
+ css=['style.css'],
30
+ js=['girder-plugin-import-tracker.umd.cjs'],
31
+ staticDir=Path(__file__).parent / 'web_client' / 'dist',
32
+ tree=info['serverRoot']
33
+ )
@@ -0,0 +1,140 @@
1
+ import time
2
+
3
+ from girder_jobs.constants import JobStatus
4
+ from girder_jobs.models.job import Job
5
+ from girder_worker import GirderWorkerPluginABC
6
+
7
+ from girder import events
8
+ from girder.models.file import File
9
+ from girder.utility.abstract_assetstore_adapter import AbstractAssetstoreAdapter
10
+
11
+ from .models import AssetstoreImport, ImportTrackerCancelError
12
+
13
+
14
+ def wrapShouldImportFile():
15
+ baseShouldImportFile = AbstractAssetstoreAdapter.shouldImportFile
16
+
17
+ def shouldImportFileWrapper(self, path, params):
18
+ jobRec = params.get('_job')
19
+ job = None
20
+ if jobRec:
21
+ job = Job().load(jobRec['id'], force=True, includeLog=False)
22
+ if job['status'] == JobStatus.CANCELED:
23
+ raise ImportTrackerCancelError()
24
+ if time.time() - jobRec['lastlog'] > 10:
25
+ Job().updateJob(
26
+ job,
27
+ log='%s - Checked %d, skipped %d; checking %s\n' % (
28
+ time.strftime('%Y-%m-%d %H:%M:%S'),
29
+ jobRec['count'], jobRec['skip'], path),
30
+ overwrite=(jobRec['logcount'] > 1000))
31
+ if jobRec['logcount'] > 1000:
32
+ jobRec['logcount'] = 0
33
+ jobRec['logcount'] += 1
34
+ jobRec['lastlog'] = time.time()
35
+ result = True
36
+ if params.get('excludeExisting'):
37
+ idx1 = ([('assetstoreId', 1), ('path', 1)], {})
38
+ idx2 = ([('assetstoreId', 1), ('s3Key', 1)], {})
39
+ if idx1 not in File()._indices:
40
+ File().ensureIndex(idx1)
41
+ if idx2 not in File()._indices:
42
+ File().ensureIndex(idx2)
43
+ if File().findOne({
44
+ 'assetstoreId': self.assetstore['_id'],
45
+ '$or': [{'path': path}, {'s3Key': path}],
46
+ 'imported': True
47
+ }):
48
+ result = False
49
+ if result:
50
+ result = baseShouldImportFile(self, path, params)
51
+ if jobRec:
52
+ if not result:
53
+ jobRec['skip'] += 1
54
+ else:
55
+ jobRec['count'] += 1
56
+ return result
57
+
58
+ AbstractAssetstoreAdapter.shouldImportFile = shouldImportFileWrapper
59
+
60
+
61
+ def createImportRecord(event: events.Event):
62
+ info = event.info
63
+ path = info['params']['importPath']
64
+ record_data = {
65
+ 'destinationId': info['parent']['_id'],
66
+ 'destinationType': info['parentType'],
67
+ 'importPath': path,
68
+ 'leafFoldersAsItems': str(info['params'].get('leafFoldersAsItems', False)).lower(),
69
+ 'progress': str(info['progress'].on).lower(),
70
+ **info['params']
71
+ }
72
+
73
+ job = Job().createJob(
74
+ title='Import from %s : %s' % (info['assetstore']['name'], path),
75
+ type='assetstore_import',
76
+ public=False,
77
+ user=info['user'],
78
+ kwargs=info['params'],
79
+ )
80
+ job = Job().updateJob(job, '%s - Starting import from %s : %s\n' % (
81
+ time.strftime('%Y-%m-%d %H:%M:%S'),
82
+ info['assetstore']['name'], path,
83
+ ), status=JobStatus.RUNNING)
84
+
85
+ # We mutate the params dict in-place as a side-effect, unfortunately.
86
+ info['params']['_job'] = {
87
+ 'id': str(job['_id']),
88
+ 'count': 0,
89
+ 'skip': 0,
90
+ 'lastlog': time.time(),
91
+ 'logcount': 0,
92
+ }
93
+
94
+ if 'fileIncludeRegex' in info['params']:
95
+ record_data['fileIncludeRegex'] = info['params']['fileIncludeRegex']
96
+ if 'fileExcludeRegex' in info['params']:
97
+ record_data['fileExcludeRegex'] = info['params']['fileExcludeRegex']
98
+ if 'excludeExisting' in info['params']:
99
+ record_data['excludeExisting'] = str(info['params']['excludeExisting']).lower()
100
+
101
+ import_record = AssetstoreImport().createAssetstoreImport(info['assetstore'], record_data)
102
+ event.addResponse({'importRecord': import_record})
103
+
104
+
105
+ def finalizeImportRecord(event: events.Event):
106
+ job_info = event.info['params']['_job']
107
+ job = Job().load(job_info['id'], force=True, includeLog=False)
108
+
109
+ if 'exception' in event.info:
110
+ exc = event.info['exception']
111
+ if isinstance(exc, ImportTrackerCancelError):
112
+ success = 'canceled'
113
+ Job().updateJob(job, '%s - Canceled\n' % time.strftime('%Y-%m-%d %H:%M:%S'))
114
+ else:
115
+ success = False
116
+ Job().updateJob(job, '%s - Failed with %s' % (
117
+ time.strftime('%Y-%m-%d %H:%M:%S'),
118
+ exc,
119
+ ), status=JobStatus.ERROR)
120
+ else:
121
+ success = True
122
+ Job().updateJob(job, '%s - Finished. Checked %d, skipped %d\n' % (
123
+ time.strftime('%Y-%m-%d %H:%M:%S'),
124
+ job_info['count'], job_info['skip'],
125
+ ), status=JobStatus.SUCCESS)
126
+
127
+ pre_event = event.info['pre_event']
128
+ for response in pre_event.responses:
129
+ if isinstance(response, dict) and 'importRecord' in response:
130
+ AssetstoreImport().markEnded(response['importRecord'], success)
131
+ break
132
+
133
+
134
+ class ImportTrackerWorkerPlugin(GirderWorkerPluginABC):
135
+ def __init__(self, app, *args, **kwargs):
136
+ wrapShouldImportFile()
137
+
138
+ events.bind('assetstore_import.before', 'import_tracker', createImportRecord)
139
+ events.bind('assetstore_import.after', 'import_tracker', finalizeImportRecord)
140
+ events.bind('assetstore_import.error', 'import_tracker', finalizeImportRecord)
@@ -0,0 +1,45 @@
1
+ from datetime import datetime
2
+
3
+ from bson.objectid import ObjectId
4
+
5
+ from girder.exceptions import ValidationException
6
+ from girder.models.model_base import Model
7
+
8
+
9
+ class AssetstoreImport(Model):
10
+ """A model that tracks assetstore import events."""
11
+
12
+ def initialize(self):
13
+ self.name = 'assetstoreImport'
14
+
15
+ def validate(self, doc):
16
+ fields = {'name', 'started', 'assetstoreId', 'params'}
17
+ missing_keys = fields - doc.keys()
18
+ if missing_keys:
19
+ raise ValidationException('Fields missing.', ','.join(missing_keys))
20
+
21
+ return doc
22
+
23
+ def createAssetstoreImport(self, assetstore, params):
24
+ now = datetime.utcnow()
25
+ record = self.save(
26
+ {
27
+ 'name': now.isoformat(),
28
+ 'started': now,
29
+ 'assetstoreId': ObjectId(assetstore['_id']),
30
+ 'params': {k: v for k, v in sorted(params.items())},
31
+ }
32
+ )
33
+ return record
34
+
35
+ def markEnded(self, record, success=None):
36
+ now = datetime.utcnow()
37
+ record['ended'] = now
38
+ if success is not None:
39
+ record['success'] = success
40
+ record = self.save(record)
41
+ return record
42
+
43
+
44
+ class ImportTrackerCancelError(Exception):
45
+ pass
@@ -0,0 +1,146 @@
1
+ from bson.objectid import ObjectId
2
+
3
+ from girder.api import access
4
+ from girder.api.describe import Description, autoDescribeRoute
5
+ from girder.api.rest import boundHandler
6
+ from girder.constants import AccessType, SortDir
7
+ from girder.models.assetstore import Assetstore
8
+ from girder.models.folder import Folder
9
+ from girder.utility import model_importer, path
10
+
11
+ from . import utils
12
+ from .models import AssetstoreImport
13
+
14
+
15
+ def processCursor(cursor, user):
16
+ lookedupAssetstores = {}
17
+ results = list(cursor)
18
+
19
+ for row in results:
20
+ if row['assetstoreId'] not in lookedupAssetstores:
21
+ assetstore = list(Assetstore().find({'_id': row['assetstoreId']}))
22
+ lookedupAssetstores[row['assetstoreId']] = assetstore[0][
23
+ 'name'] if assetstore else None
24
+
25
+ row['_assetstoreName'] = (
26
+ lookedupAssetstores[row['assetstoreId']] or row['assetstoreId'])
27
+ model = model_importer.ModelImporter.model(row['params']['destinationType'])
28
+ doc = model.load(row['params']['destinationId'], user=user)
29
+ if doc:
30
+ row['_destinationPath'] = path.getResourcePath(
31
+ row['params']['destinationType'],
32
+ doc,
33
+ user=user
34
+ )
35
+ else:
36
+ row['_destinationPath'] = 'does not exist'
37
+ return results
38
+
39
+
40
+ def getImports(query=None, user=None, unique=False, limit=None, offset=None, sort=None):
41
+ if not unique:
42
+ cursor = AssetstoreImport().find(
43
+ query or {},
44
+ limit=limit,
45
+ offset=offset,
46
+ sort=sort,
47
+ )
48
+ else:
49
+ cursor = AssetstoreImport().collection.aggregate([
50
+ {'$match': query or {}},
51
+ {'$sort': {k: v for k, v in sort}},
52
+ {'$addFields': {
53
+ 'normalizedParams': {'$arrayToObject': {'$filter': {
54
+ 'input': {'$objectToArray': '$params'},
55
+ 'as': 'field',
56
+ 'cond': {'$and': [{
57
+ '$not': {'$or': [
58
+ {'$eq': ['$$field.k', 'params']},
59
+ {'$eq': ['$$field.k', 'progress']}
60
+ ]},
61
+ }, {
62
+ '$not': {'$or': [
63
+ {'$eq': ['$$field.v', None]},
64
+ {'$eq': ['$$field.v', '']}
65
+ ]},
66
+ }]}
67
+ }}},
68
+ }},
69
+ {'$group': {
70
+ '_id': {
71
+ 'assetstoreId': '$assetstoreId',
72
+ 'params': '$normalizedParams'
73
+ },
74
+ '_count': {'$sum': 1},
75
+ 'started': {'$first': '$started'},
76
+ 'ended': {'$first': '$ended'},
77
+ 'first_id': {'$first': '$_id'},
78
+ }},
79
+ {'$project': {
80
+ 'assetstoreId': '$_id.assetstoreId',
81
+ 'params': '$_id.params',
82
+ '_count': '$_count',
83
+ 'started': '$started',
84
+ 'ended': '$ended',
85
+ '_id': '$first_id',
86
+ }},
87
+ {'$sort': {k: v for k, v in sort}},
88
+ {'$skip': offset or 0},
89
+ {'$limit': limit or 0}
90
+ ])
91
+ return processCursor(cursor, user)
92
+
93
+
94
+ @access.admin
95
+ @boundHandler
96
+ @autoDescribeRoute(
97
+ Description('List all imports for a given assetstore.')
98
+ .param('id', 'An assetstore ID', paramType='path')
99
+ .param('unique', 'If true, only show unique imports', required=False,
100
+ dataType='boolean', default=False)
101
+ .pagingParams(defaultSort='started', defaultSortDir=SortDir.DESCENDING)
102
+ )
103
+ def listImports(self, id, unique, limit, offset, sort):
104
+ return getImports(
105
+ {'assetstoreId': ObjectId(id)},
106
+ self.getCurrentUser(), unique, limit, offset, sort)
107
+
108
+
109
+ @access.admin
110
+ @boundHandler
111
+ @autoDescribeRoute(
112
+ Description('List all past imports for all assetstores.')
113
+ .param('unique', 'If true, only show unique imports', required=False,
114
+ dataType='boolean', default=False)
115
+ .pagingParams(defaultSort='started', defaultSortDir=SortDir.DESCENDING)
116
+ )
117
+ def listAllImports(self, unique, limit, offset, sort):
118
+ return getImports(
119
+ None,
120
+ self.getCurrentUser(), unique, limit, offset, sort)
121
+
122
+
123
+ @access.admin
124
+ @boundHandler
125
+ @autoDescribeRoute(
126
+ Description('Get import for record from ID.')
127
+ .modelParam('id', 'ID of an import', model=AssetstoreImport)
128
+ )
129
+ def getImport(self, assetstoreImport):
130
+ return assetstoreImport
131
+
132
+
133
+ @access.admin
134
+ @boundHandler
135
+ @autoDescribeRoute(
136
+ Description('Move folder contents to an assetstore.')
137
+ .modelParam('id', 'Source folder ID', model=Folder, level=AccessType.WRITE)
138
+ .modelParam('assetstoreId', 'Destination assetstore ID', model=Assetstore, paramType='formData')
139
+ .param('ignoreImported', 'Ignore files that have been directly imported', dataType='boolean',
140
+ default=True, required=True)
141
+ .param('progress', 'Whether to record progress on the move.', dataType='boolean', default=False,
142
+ required=False)
143
+ )
144
+ def moveFolder(self, folder, assetstore, ignoreImported, progress):
145
+ user = self.getCurrentUser()
146
+ utils.moveFolder.delay(user, folder, assetstore, ignoreImported, progress)
@@ -0,0 +1,126 @@
1
+ import time
2
+
3
+ from bson.objectid import ObjectId
4
+ from girder_jobs.constants import JobStatus
5
+ from girder_jobs.models.job import Job
6
+ from girder_worker.app import app
7
+
8
+ from girder.models.file import File
9
+ from girder.models.folder import Folder
10
+ from girder.models.upload import Upload
11
+ from girder.utility.progress import ProgressContext
12
+
13
+ from .models import ImportTrackerCancelError
14
+
15
+
16
+ def moveFile(file, folder, user, assetstore, progress, job):
17
+ # check if the move has been canceled
18
+ job = Job().load(job['_id'], force=True)
19
+ if job['status'] == JobStatus.CANCELED:
20
+ raise ImportTrackerCancelError()
21
+
22
+ message = f'Moving {folder["name"]}/{file["name"]}\n'
23
+ job = Job().updateJob(job, log=f'{time.strftime("%Y-%m-%d %H:%M:%S")} - {message}')
24
+ progress.update(message=message)
25
+
26
+ return Upload().moveFileToAssetstore(file, user, assetstore, progress=progress)
27
+
28
+
29
+ @app.task(queue='local')
30
+ def moveFolder(user, folder, assetstore, ignoreImported, progress):
31
+ """
32
+ Move a folder to a different assetstore.
33
+
34
+ :param user: the user requesting the move.
35
+ :param folder: the folder to move.
36
+ :param assetstore: the target assetstore.
37
+ :param ignoreImported: if True, do not move imported files.
38
+ :param progress: a boolean specifying if progress should be reported.
39
+ """
40
+ job = Job().createJob(
41
+ title='Move folder "%s" to assetstore "%s"' % (
42
+ folder['name'], assetstore['name']),
43
+ type='folder_move', public=False, user=user,
44
+ )
45
+ job = Job().updateJob(job, '%s - Starting folder move "%s" to assetstore "%s" (%s)\n' % (
46
+ time.strftime(
47
+ '%Y-%m-%d %H:%M:%S'), folder['name'], assetstore['name'], assetstore['_id']
48
+ ), status=JobStatus.RUNNING)
49
+
50
+ result = None
51
+ try:
52
+ with ProgressContext(progress, user=user,
53
+ title='Moving folder "%s" (%s) to assetstore "%s" (%s)' % (
54
+ folder['name'],
55
+ folder['_id'],
56
+ assetstore['name'],
57
+ assetstore['_id'])) as ctx:
58
+ try:
59
+ result = _moveLeafFiles(
60
+ folder, user, assetstore, ignoreImported, ctx, job)
61
+
62
+ Job().updateJob(job, '%s - Finished folder move.\n' % (
63
+ time.strftime('%Y-%m-%d %H:%M:%S'),
64
+ ), status=JobStatus.SUCCESS)
65
+
66
+ except ImportTrackerCancelError:
67
+ return 'Job canceled'
68
+
69
+ except Exception as exc:
70
+ Job().updateJob(job, '%s - Failed with %s\n' % (
71
+ time.strftime('%Y-%m-%d %H:%M:%S'),
72
+ exc,
73
+ ), status=JobStatus.ERROR)
74
+
75
+ return result
76
+
77
+
78
+ def _moveLeafFiles(folder, user, assetstore, ignoreImported, progress, job):
79
+ # check if the move has been canceled
80
+ job = Job().load(job['_id'], force=True)
81
+ if job['status'] == JobStatus.CANCELED:
82
+ raise ImportTrackerCancelError()
83
+
84
+ Folder().updateFolder(folder)
85
+
86
+ # only move files that are not already in the assetstore
87
+ query = {'assetstoreId': {'$ne': ObjectId(assetstore['_id'])}}
88
+
89
+ # ignore imported files if desired
90
+ if ignoreImported:
91
+ query['imported'] = {'$ne': True}
92
+
93
+ child_folders = Folder().childFolders(folder, 'folder', user=user)
94
+ child_items = Folder().childItems(folder, filters=query)
95
+
96
+ uploads = []
97
+
98
+ def tryToMoveFile(file):
99
+ try:
100
+ upload = moveFile(file, folder, user, assetstore, progress, job)
101
+ uploads.append(upload)
102
+ except Exception as e:
103
+ # Ignore failed move of files
104
+ Job().updateJob(
105
+ job,
106
+ log=f'{time.strftime("%Y-%m-%d %H:%M:%S")} - Failed to move {file["name"]}: {e}\n'
107
+ )
108
+
109
+ # get all files attached to an object
110
+ def moveAttachedFiles(attachedToId):
111
+ for attached_file in File().find({'attachedToId': attachedToId, **query}):
112
+ tryToMoveFile(attached_file)
113
+
114
+ moveAttachedFiles(folder['_id'])
115
+ for item in child_items:
116
+ # upload all attached files for each item
117
+ moveAttachedFiles(item['_id'])
118
+
119
+ for file in File().find({'itemId': ObjectId(item['_id']), **query}):
120
+ tryToMoveFile(file)
121
+
122
+ for child_folder in child_folders:
123
+ uploads += _moveLeafFiles(child_folder, user, assetstore,
124
+ ignoreImported, progress, job)
125
+
126
+ return uploads
@@ -0,0 +1,18 @@
1
+ (function(x){typeof define=="function"&&define.amd?define(x):x()})(function(){"use strict";function x(u,e,i,t){if(e===!1||e==null||!e&&(u==="class"||u==="style"))return"";if(e===!0)return" "+(t?u:u+'="'+u+'"');var r=typeof e;return r!=="object"&&r!=="function"||typeof e.toJSON!="function"||(e=e.toJSON()),typeof e=="string"||(e=JSON.stringify(e),i||e.indexOf('"')===-1)?(i&&(e=e0(e))," "+u+'="'+e+'"'):" "+u+"='"+e.replace(/'/g,"&#39;")+"'"}function e0(u){var e=""+u,i=t0.exec(e);if(!i)return u;var t,r,F,c="";for(t=i.index,r=0;t<e.length;t++){switch(e.charCodeAt(t)){case 34:F="&quot;";break;case 38:F="&amp;";break;case 60:F="&lt;";break;case 62:F="&gt;";break;default:continue}r!==t&&(c+=e.substring(r,t)),r=t+1,c+=F}return r!==t?c+e.substring(r,t):c}var t0=/["&<>]/;function N(u,e,i,t){if(!(u instanceof Error))throw u;if(!(typeof window>"u"&&e||t))throw u.message+=" on line "+i,u;var r,F,c,l;try{t=t||require("fs").readFileSync(e,{encoding:"utf8"}),r=3,F=t.split(`
2
+ `),c=Math.max(i-r,0),l=Math.min(F.length,i+r)}catch(m){return u.message+=" - could not read from "+e+" ("+m.message+")",void N(u,null,i)}r=F.slice(c,l).map(function(m,v){var h=v+c+1;return(h==i?" > ":" ")+h+"| "+m}).join(`
3
+ `),u.path=e;try{u.message=(e||"Pug")+":"+i+`
4
+ `+r+`
5
+
6
+ `+u.message}catch{}throw u}function r0(u){var e="",i,t;try{var r=u||{};(function(F){t=1,i="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/assetstoreButtonsExtension.pug",e=e+'<div class="g-assetstore-button-container">',t=2,i="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/assetstoreButtonsExtension.pug",e=e+"<a"+(' class="g-view-imports btn btn-sm btn-primary"'+x("href",F,!0,!1))+">",t=3,i="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/assetstoreButtonsExtension.pug",e=e+'<i class="icon-link-ext"></i>',t=4,i="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/assetstoreButtonsExtension.pug",e=e+" View past imports</a></div>"}).call(this,"importsPageLink"in r?r.importsPageLink:typeof importsPageLink<"u"?importsPageLink:void 0)}catch(F){N(F,i,t)}return e}function o(u,e,i,t){if(e===!1||e==null||!e&&(u==="class"||u==="style"))return"";if(e===!0)return" "+(t?u:u+'="'+u+'"');var r=typeof e;return r!=="object"&&r!=="function"||typeof e.toJSON!="function"||(e=e.toJSON()),typeof e=="string"||(e=JSON.stringify(e),i||e.indexOf('"')===-1)?(i&&(e=s(e))," "+u+'="'+e+'"'):" "+u+"='"+e.replace(/'/g,"&#39;")+"'"}function s(u){var e=""+u,i=u0.exec(e);if(!i)return u;var t,r,F,c="";for(t=i.index,r=0;t<e.length;t++){switch(e.charCodeAt(t)){case 34:F="&quot;";break;case 38:F="&amp;";break;case 60:F="&lt;";break;case 62:F="&gt;";break;default:continue}r!==t&&(c+=e.substring(r,t)),r=t+1,c+=F}return r!==t?c+e.substring(r,t):c}var u0=/["&<>]/;function Y(u,e,i,t){if(!(u instanceof Error))throw u;if(!(typeof window>"u"&&e||t))throw u.message+=" on line "+i,u;var r,F,c,l;try{t=t||require("fs").readFileSync(e,{encoding:"utf8"}),r=3,F=t.split(`
7
+ `),c=Math.max(i-r,0),l=Math.min(F.length,i+r)}catch(m){return u.message+=" - could not read from "+e+" ("+m.message+")",void Y(u,null,i)}r=F.slice(c,l).map(function(m,v){var h=v+c+1;return(h==i?" > ":" ")+h+"| "+m}).join(`
8
+ `),u.path=e;try{u.message=(e||"Pug")+":"+i+`
9
+ `+r+`
10
+
11
+ `+u.message}catch{}throw u}function i0(u){var e="",i,t,r;try{var F=u||{};(function(c,l,C,w,E,S,Q,X,R,k,j,w0){r=1,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+'<div class="it-controls">',r=2,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",w0?(r=12,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",S?(r=17,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"<a"+(' class="g-view-imports btn btn-sm btn-primary"'+o("href",`#assetstore/${S}/imports`,!0,!1))+">",r=18,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+'<i class="icon-link-ext"></i>',r=19,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"View all past Imports</a>"):(r=13,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+'<a class="g-view-imports btn btn-sm btn-primary" href="#assetstore/all_imports">',r=14,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+'<i class="icon-link-ext"></i>',r=15,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"View all past Imports</a>")):(r=3,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",S?(r=8,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"<a"+(' class="g-view-imports btn btn-sm btn-primary"'+o("href",`#assetstore/${S}/unique_imports`,!0,!1))+">",r=9,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+'<i class="icon-link-ext"></i>',r=10,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"View unique past Imports</a>"):(r=4,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+'<a class="g-view-imports btn btn-sm btn-primary" href="#assetstore/all_unique_imports">',r=5,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+'<i class="icon-link-ext"></i>',r=6,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"View unique past Imports</a>")),e=e+"</div>",r=20,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+'<table class="g-imports-list-table">',r=21,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug";var E=!1,w=!1,C=!1,k=[],j=!1;r=27,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",(function(){var n=X;if(typeof n.length=="number")for(var a=0,d=n.length;a<d;a++){var p=n[a];r=28,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",(p.get("params").fileIncludeRegex||p.get("params").fileExcludeRegex)&&(r=29,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",E=l),r=30,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",p.get("params").leafFoldersAsItems&&p.get("params").leafFoldersAsItems!=="false"&&(r=31,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",w=!0),r=32,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",c.keys(p.get("params")).forEach(_=>{["importPath","destinationId","leafFoldersAsItems","progress","fileIncludeRegex","fileExcludeRegex","params"].indexOf(_)<0&&k.indexOf(_)<0&&k.push(_)}),r=33,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",p.get("_count")&&(r=34,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",j=!0),r=35,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",p.get("params").importPath&&(r=36,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",C=!0)}else{var d=0;for(var a in n){d++;var p=n[a];r=28,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",(p.get("params").fileIncludeRegex||p.get("params").fileExcludeRegex)&&(r=29,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",E=l),r=30,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",p.get("params").leafFoldersAsItems&&p.get("params").leafFoldersAsItems!=="false"&&(r=31,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",w=!0),r=32,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",c.keys(p.get("params")).forEach(g=>{["importPath","destinationId","leafFoldersAsItems","progress","fileIncludeRegex","fileExcludeRegex","params"].indexOf(g)<0&&k.indexOf(g)<0&&k.push(g)}),r=33,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",p.get("_count")&&(r=34,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",j=!0),r=35,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",p.get("params").importPath&&(r=36,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",C=!0)}}}).call(this),r=37,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"<thead>",r=38,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"<tr>",r=39,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"<th>",r=39,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"Actions</th>",r=40,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",j&&(r=41,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"<th>",r=41,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"Repeats</th>"),r=42,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"<th>",r=42,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"Started</th>",r=43,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"<th>",r=43,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"Ended</th>",r=44,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"<th>",r=44,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"Assetstore Name</th>",r=45,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",C&&(r=46,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"<th>",r=46,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"Import Path</th>"),r=48,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"<th>",r=48,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"Destination Path</th>",r=49,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",w&&(r=50,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"<th>",r=50,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"Leafed Folders</th>"),r=51,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",E&&(r=52,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"<th>",r=52,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"File Include Regex</th>",r=53,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"<th>",r=53,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"File Exclude Regex</th>"),r=54,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",(function(){var n=k;if(typeof n.length=="number")for(var a=0,d=n.length;a<d;a++){var p=n[a];r=55,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"<th>",r=55,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+s((i=p.replace(/([A-Z])/g," $1").replace(/^./,_=>_.toUpperCase()))==null?"":i)+"</th>"}else{var d=0;for(var a in n){d++;var p=n[a];r=55,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"<th>",r=55,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+s((i=p.replace(/([A-Z])/g," $1").replace(/^./,g=>g.toUpperCase()))==null?"":i)+"</th>"}}}).call(this),e=e+"</tr></thead>",r=56,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"<tbody>",r=57,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",(function(){var n=X;if(typeof n.length=="number")for(var a=0,d=n.length;a<d;a++){var p=n[a];r=58,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"<tr>",r=59,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"<td>",r=60,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",Q.includes(p.get("assetstoreId"))&&(r=61,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+'<div class="g-imports-buttons">',r=62,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"<button"+(' class="re-import-btn btn btn-sm btn-success"'+o("index",a,!0,!1)+o("disabled",p.get("_destinationPath")=="does not exist",!0,!1))+">",r=63,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+'<i class="icon-cw"></i>',r=64,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+" Re-Import</button>",r=65,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"<button"+(' class="re-import-edit-btn btn btn-sm btn-primary"'+o("index",a,!0,!1)+' data-toggle="tooltip" title="Edit Import Parameters"')+">",r=66,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+'<i class="icon-pencil"></i></button></div>'),e=e+"</td>",r=67,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",j&&(r=68,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"<td"+(o("data-id",p.get("_count"),!0,!1)+' data-toggle="tooltip"'+o("title",p.get("_count")!==1?`Imported ${p.get("_count")} times`:"Imported once",!0,!1))+">",r=69,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"<span>",r=69,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+s((i=p.get("_count"))==null?"":i)+"</span></td>"),r=70,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"<td"+(o("data-id",p.get("started"),!0,!1)+' data-toggle="tooltip"'+o("title",p.get("started"),!0,!1))+">",r=71,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"<span>",r=71,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+s((i=R(p.get("started")).format("YYYY-MM-DD HH:mm:ss.SSS"))==null?"":i)+"</span></td>",r=72,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"<td"+(o("data-id",p.get("ended"),!0,!1)+' data-toggle="tooltip"'+o("title",p.get("ended")||"",!0,!1))+">",r=73,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"<span>",r=73,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+s((i=p.get("ended")?R(p.get("ended")).format("YYYY-MM-DD HH:mm:ss.SSS"):"")==null?"":i)+"</span></td>",r=74,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"<td"+(o("data-id",p.get("_assetstoreName"),!0,!1)+' data-toggle="tooltip"'+o("title",p.get("_assetstoreName"),!0,!1))+">",r=75,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"<span>",r=75,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+s((i=p.get("_assetstoreName"))==null?"":i)+"</span></td>",r=76,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",C&&(r=77,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"<td"+(o("data-id",p.get("params").importPath,!0,!1)+' data-toggle="tooltip"'+o("title",p.get("params").importPath,!0,!1))+">",r=78,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"<span>",r=78,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+s((i=(p.get("params").importPath||"").replaceAll(/(?!^)\//g,"/­"))==null?"":i)+"</span></td>"),r=79,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"<td"+(o("data-id",p.get("params").destinationId,!0,!1)+' data-toggle="tooltip"'+o("title",p.get("_destinationPath")+`
12
+ `+p.get("params").destinationId,!0,!1))+">",r=80,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"<span>",r=80,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+s((i=(p.get("_destinationPath")||"").replaceAll(/(?!^)\//g,"/­"))==null?"":i)+"</span></td>",r=81,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",w&&(r=82,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"<td>",r=83,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"<span>",r=83,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+s((i=p.get("params").leafFoldersAsItems)==null?"":i)+"</span></td>"),r=84,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",E&&(r=85,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"<td>",r=86,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"<span>",r=86,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+s((i=p.get("params").fileIncludeRegex)==null?"":i)+"</span></td>",r=87,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"<td>",r=88,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"<span>",r=88,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+s((i=p.get("params").fileExcludeRegex)==null?"":i)+"</span></td>"),r=89,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",(function(){var _=k;if(typeof _.length=="number")for(var y=0,T=_.length;y<T;y++){var g=_[y];r=90,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"<td>",r=91,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"<span>",r=91,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+s((i=p.get("params")[g])==null?"":i)+"</span></td>"}else{var T=0;for(var y in _){T++;var g=_[y];r=90,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"<td>",r=91,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"<span>",r=91,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+s((i=p.get("params")[g])==null?"":i)+"</span></td>"}}}).call(this),e=e+"</tr>"}else{var d=0;for(var a in n){d++;var p=n[a];r=58,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"<tr>",r=59,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"<td>",r=60,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",Q.includes(p.get("assetstoreId"))&&(r=61,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+'<div class="g-imports-buttons">',r=62,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"<button"+(' class="re-import-btn btn btn-sm btn-success"'+o("index",a,!0,!1)+o("disabled",p.get("_destinationPath")=="does not exist",!0,!1))+">",r=63,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+'<i class="icon-cw"></i>',r=64,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+" Re-Import</button>",r=65,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"<button"+(' class="re-import-edit-btn btn btn-sm btn-primary"'+o("index",a,!0,!1)+' data-toggle="tooltip" title="Edit Import Parameters"')+">",r=66,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+'<i class="icon-pencil"></i></button></div>'),e=e+"</td>",r=67,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",j&&(r=68,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"<td"+(o("data-id",p.get("_count"),!0,!1)+' data-toggle="tooltip"'+o("title",p.get("_count")!==1?`Imported ${p.get("_count")} times`:"Imported once",!0,!1))+">",r=69,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"<span>",r=69,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+s((i=p.get("_count"))==null?"":i)+"</span></td>"),r=70,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"<td"+(o("data-id",p.get("started"),!0,!1)+' data-toggle="tooltip"'+o("title",p.get("started"),!0,!1))+">",r=71,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"<span>",r=71,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+s((i=R(p.get("started")).format("YYYY-MM-DD HH:mm:ss.SSS"))==null?"":i)+"</span></td>",r=72,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"<td"+(o("data-id",p.get("ended"),!0,!1)+' data-toggle="tooltip"'+o("title",p.get("ended")||"",!0,!1))+">",r=73,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"<span>",r=73,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+s((i=p.get("ended")?R(p.get("ended")).format("YYYY-MM-DD HH:mm:ss.SSS"):"")==null?"":i)+"</span></td>",r=74,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"<td"+(o("data-id",p.get("_assetstoreName"),!0,!1)+' data-toggle="tooltip"'+o("title",p.get("_assetstoreName"),!0,!1))+">",r=75,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"<span>",r=75,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+s((i=p.get("_assetstoreName"))==null?"":i)+"</span></td>",r=76,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",C&&(r=77,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"<td"+(o("data-id",p.get("params").importPath,!0,!1)+' data-toggle="tooltip"'+o("title",p.get("params").importPath,!0,!1))+">",r=78,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"<span>",r=78,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+s((i=(p.get("params").importPath||"").replaceAll(/(?!^)\//g,"/­"))==null?"":i)+"</span></td>"),r=79,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"<td"+(o("data-id",p.get("params").destinationId,!0,!1)+' data-toggle="tooltip"'+o("title",p.get("_destinationPath")+`
13
+ `+p.get("params").destinationId,!0,!1))+">",r=80,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"<span>",r=80,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+s((i=(p.get("_destinationPath")||"").replaceAll(/(?!^)\//g,"/­"))==null?"":i)+"</span></td>",r=81,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",w&&(r=82,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"<td>",r=83,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"<span>",r=83,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+s((i=p.get("params").leafFoldersAsItems)==null?"":i)+"</span></td>"),r=84,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",E&&(r=85,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"<td>",r=86,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"<span>",r=86,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+s((i=p.get("params").fileIncludeRegex)==null?"":i)+"</span></td>",r=87,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"<td>",r=88,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"<span>",r=88,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+s((i=p.get("params").fileExcludeRegex)==null?"":i)+"</span></td>"),r=89,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",(function(){var g=k;if(typeof g.length=="number")for(var $=0,D=g.length;$<D;$++){var M=g[$];r=90,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"<td>",r=91,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"<span>",r=91,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+s((i=p.get("params")[M])==null?"":i)+"</span></td>"}else{var D=0;for(var $ in g){D++;var M=g[$];r=90,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"<td>",r=91,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+"<span>",r=91,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+s((i=p.get("params")[M])==null?"":i)+"</span></td>"}}}).call(this),e=e+"</tr>"}}}).call(this),e=e+"</tbody></table>",r=93,t="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/importList.pug",e=e+'<div class="g-imports-pagination"></div>'}).call(this,"Object"in F?F.Object:typeof Object<"u"?Object:void 0,"True"in F?F.True:typeof True<"u"?True:void 0,"anyImportPath"in F?F.anyImportPath:typeof anyImportPath<"u"?anyImportPath:void 0,"anyLeafed"in F?F.anyLeafed:typeof anyLeafed<"u"?anyLeafed:void 0,"anyRegex"in F?F.anyRegex:typeof anyRegex<"u"?anyRegex:void 0,"assetstoreId"in F?F.assetstoreId:typeof assetstoreId<"u"?assetstoreId:void 0,"assetstores"in F?F.assetstores:typeof assetstores<"u"?assetstores:void 0,"imports"in F?F.imports:typeof imports<"u"?imports:void 0,"moment"in F?F.moment:typeof moment<"u"?moment:void 0,"otherParams"in F?F.otherParams:typeof otherParams<"u"?otherParams:void 0,"showCount"in F?F.showCount:typeof showCount<"u"?showCount:void 0,"unique"in F?F.unique:typeof unique<"u"?unique:void 0)}catch(c){Y(c,t,r)}return e}const C0="",V=girder.$,F0=girder.views.widgets.PaginateWidget,p0=girder.collections.Collection,J=girder.models.AssetstoreModel,{SORT_DESC:c0}=girder.constants,o0=girder.moment,s0=girder.views.View,U=girder.router,{restRequest:a0}=girder.rest;var I=s0.extend({events:{"click .re-import-btn":function(u){const e=Number(V(u.currentTarget).attr("index")),i=this.imports[e];if(i===void 0)return;const t=new J({_id:i.get("assetstoreId")}),r=i.get("params").destinationType,F=i.get("params").destinationId;t.off("g:imported").on("g:imported",function(){U.navigate(r+"/"+F,{trigger:!0})},this).on("g:error",function(c){this.$(".g-validation-failed-message").text(c.responseJSON.message)},this),t.once("g:fetched",()=>{t.import(i.get("params"))}).fetch()},"click .re-import-edit-btn":function(u){const e=Number(V(u.currentTarget).attr("index")),i=this.imports[e];if(i===void 0)return;const t=(c,l)=>{new J({_id:c}).once("g:fetched",()=>{U.navigate(`assetstore/${c}/re-import/${l}`,{trigger:!0})}).fetch()},r=i.get("assetstoreId"),F=i.get("_id");t(r,F)}},initialize({id:u,unique:e}){this._unique=e,this._assetstoreId=u,this.imports=[];const i=u?`${u}/imports`:"all_imports";this.collection=new p0,this.collection.altUrl=`assetstore/${i}`,this.collection.sortField="started",this.collection.sortDir=c0,this.collection.params={unique:e||!1},this.listenTo(this.collection,"update reset",this._updateData),this.paginateWidget=new F0({collection:this.collection,parentView:this}),a0({url:"assetstore",data:{limit:0}}).done(t=>{this.assetstores=t.map(r=>r._id),this.collection.fetch({},!0)})},_updateData(){this.imports=this.collection.toArray(),this.render()},render(){return this.$el.html(i0({imports:this.imports,assetstores:this.assetstores,moment:o0,unique:this._unique,assetstoreId:this._assetstoreId})),this.$el.tooltip(),this.paginateWidget.setElement(this.$(".g-imports-pagination")).render(),this}});const l0=girder.models.AssetstoreModel,m0=girder.views.View,{AssetstoreType:P}=girder.constants,n0=girder.router,g0=girder.events,{restRequest:B}=girder.rest,A=(u,e)=>{g0.trigger("g:alert",{icon:"cancel",text:`Could not re-import: ${e}`,type:"danger"}),n0.navigate(`assetstore/${u}/import`,{trigger:!0,replace:!0})};var d0=m0.extend({initialize({assetstoreId:u,importId:e}){this.importId=e,this.assetstoreId=u,this.type="",B({url:`assetstore/import/${e}`,error:null}).done(i=>{if(!i){A(this.assetstoreId,`Unable to find import ${e}`);return}this.import=i;const t=new l0({_id:u});t.once("g:fetched",()=>{const r=t.get("type");r===P.FILESYSTEM?this.type="filesystem":r===P.S3?this.type="s3":r===P.DICOMWEB?this.type="dwas":r===P.GIRDER?this.type="gas":A(this.assetstoreId,`Unsupported assetstore type '${r}'`),this.render()}).fetch()}).fail(()=>{A(this.assetstoreId,"Unable to fetch base import information")})},render(){const u=this.import.params,e=u.destinationId,i=u.destinationType,t=u.excludeExisting?"true":"false";return this.$(`#g-${this.type}-import-path`).val(u.importPath),this.$(`#g-${this.type}-import-dest-type`).val(i),this.$(`#g-${this.type}-import-dest-id`).val(e),this.$(`#g-${this.type}-import-leaf-items`).val(u.leafFoldersAsItems),this.$(`#g-${this.type}-import-exclude-existing`).val(t),this.type==="dwas"&&(this.$(`#g-${this.type}-import-filters`).val(u.filters),this.$(`#g-${this.type}-import-limit`).val(u.limit)),B({url:`resource/${e}/path`,method:"GET",data:{type:i},error:null}).done(r=>{this.$(`#g-${this.type}-import-dest-id`).val(`${e} (${r})`)}).fail(()=>{this.$(`#g-${this.type}-import-dest-id`).val("")}),this}});function H(u,e,i,t){if(e===!1||e==null||!e&&(u==="class"||u==="style"))return"";if(e===!0)return" "+(t?u:u+'="'+u+'"');var r=typeof e;return r!=="object"&&r!=="function"||typeof e.toJSON!="function"||(e=e.toJSON()),typeof e=="string"||(e=JSON.stringify(e),i||e.indexOf('"')===-1)?(i&&(e=_0(e))," "+u+'="'+e+'"'):" "+u+"='"+e.replace(/'/g,"&#39;")+"'"}function _0(u){var e=""+u,i=h0.exec(e);if(!i)return u;var t,r,F,c="";for(t=i.index,r=0;t<e.length;t++){switch(e.charCodeAt(t)){case 34:F="&quot;";break;case 38:F="&amp;";break;case 60:F="&lt;";break;case 62:F="&gt;";break;default:continue}r!==t&&(c+=e.substring(r,t)),r=t+1,c+=F}return r!==t?c+e.substring(r,t):c}var h0=/["&<>]/;function W(u,e,i,t){if(!(u instanceof Error))throw u;if(!(typeof window>"u"&&e||t))throw u.message+=" on line "+i,u;var r,F,c,l;try{t=t||require("fs").readFileSync(e,{encoding:"utf8"}),r=3,F=t.split(`
14
+ `),c=Math.max(i-r,0),l=Math.min(F.length,i+r)}catch(m){return u.message+=" - could not read from "+e+" ("+m.message+")",void W(u,null,i)}r=F.slice(c,l).map(function(m,v){var h=v+c+1;return(h==i?" > ":" ")+h+"| "+m}).join(`
15
+ `),u.path=e;try{u.message=(e||"Pug")+":"+i+`
16
+ `+r+`
17
+
18
+ `+u.message}catch{}throw u}function z(u){var e="",i,t;try{var r=u||{};(function(F){t=1,i="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/excludeExistingInput.pug",e=e+'<div class="form-group">',t=2,i="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/excludeExistingInput.pug",e=e+"<label"+H("for","g-"+F+"-import-exclude-existing",!0,!1)+">",t=2,i="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/excludeExistingInput.pug",e=e+"Exclude Existing Files</label>",t=3,i="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/excludeExistingInput.pug",e=e+"<select"+(' class="form-control"'+H("id","g-"+F+"-import-exclude-existing",!0,!1))+">",t=4,i="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/excludeExistingInput.pug",e=e+'<option value="false">',t=4,i="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/excludeExistingInput.pug",e=e+"False</option>",t=5,i="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/excludeExistingInput.pug",e=e+'<option value="true">',t=5,i="/home/circleci/project/girder/plugins/import_tracker/girder_import_tracker/web_client/templates/excludeExistingInput.pug",e=e+"True</option></select></div>"}).call(this,"type"in r?r.type:typeof type<"u"?type:void 0)}catch(F){W(F,i,t)}return e}girder.events.on("g:appload.before",()=>{const u=girder.plugins.jobs.JobStatus,e=u.isCancelable;u.isCancelable=function(i){return["assetstore_import","folder_move"].includes(i.get("type"))?![u.CANCELED,u.SUCCESS,u.ERROR].includes(i.get("status")):e(i)}});const k0=girder.$,{AssetstoresView:G,FilesystemImportView:q,S3ImportView:O}=girder.views.body,{CollectionModel:f0,FolderModel:b0,UserModel:E0}=girder.models,{wrap:L}=girder.utilities.PluginUtils,f=girder.events,b=girder.router;L(G,"render",function(u){u.call(this),window.setTimeout(()=>{this.$el.find(".g-current-assetstores-container .g-body-title").after('<a class="g-view-imports btn btn-sm btn-primary" href="#assetstore/all_unique_imports"><i class="icon-link-ext"></i>View all past Imports</a>');const e=this.collection;this.$(".g-assetstore-import-button-container").after(function(){const i=e.get(k0(this).closest(".g-assetstore-buttons").find("[cid]").attr("cid"));return r0({importsPageLink:`#assetstore/${i.id}/unique_imports`})})},0)}),L(q,"render",function(u){u.call(this),this.$(".form-group").last().after(z({type:"filesystem"}))}),L(O,"render",function(u){u.call(this),this.$(".form-group").last().after(z({type:"s3"}))});const Z=(u,e)=>{const i=u._browserWidgetView,t=u.$(`#g-${e}-import-dest-type`).val(),F=u.$(`#g-${e}-import-dest-id`).val().trim().split(/\s/)[0],c={collection:f0,folder:b0,user:E0};if(F&&t in c){const l=new c[t]({_id:F});l.once("g:fetched",()=>{(!i.root||i.root.id!==l.id)&&(i.root=l,i._renderRootSelection())}).on("g:error",m=>{m.status===400&&f.trigger("g:alert",{icon:"cancel",text:`No ${t.toUpperCase()} with ID ${F} found.`,type:"danger",timeout:4e3})}).fetch({ignoreError:!0})}};L(q,"_openBrowser",function(u){Z(this,"filesystem"),u.call(this)}),L(O,"_openBrowser",function(u){Z(this,"s3"),u.call(this)});const K=(u,e)=>{const i=u.$(`#g-${e}-import-dest-id`).val().trim().split(/\s/)[0],t=u.$(`#g-${e}-import-dest-type`).val(),r=u.$(`#g-${e}-import-exclude-existing`).val(),F={destinationId:i,destinationType:t,excludeExisting:r,progress:!0};e==="filesystem"&&(F.leafFoldersAsItems=u.$(`#g-${e}-import-leaf-items`).val()),e==="dwas"?(F.filters=u.$(`#g-${e}-import-filters`).val().trim(),F.limit=u.$(`#g-${e}-import-limit`).val().trim()):F.importPath=u.$(`#g-${e}-import-path`).val().trim(),u.$(".g-validation-failed-message").empty(),u.$(`.g-submit-${e}-import`).addClass("disabled");let c=u.assetstore;c=c.off().on("g:imported",function(){b.navigate(t+"/"+i,{trigger:!0})},u).on("g:error",function(l){u.$(`.g-submit-${e}-import`).removeClass("disabled"),u.$(".g-validation-failed-message").html(l.responseJSON.message)},u),c.import(F)};q.prototype.events["submit .g-filesystem-import-form"]=function(u){u.preventDefault(),K(this,"filesystem")},O.prototype.events["submit .g-s3-import-form"]=function(u){u.preventDefault(),K(this,"s3")},b.route("assetstore/:id/imports","importsPage",function(u){f.trigger("g:navigateTo",I,{id:u})}),b.route("assetstore/:id/unique_imports","importsPage",function(u){f.trigger("g:navigateTo",I,{id:u,unique:!0})}),b.route("assetstore/all_imports","importsPage",function(){f.trigger("g:navigateTo",I)}),b.route("assetstore/all_unique_imports","importsPage",function(){f.trigger("g:navigateTo",I,{unique:!0})}),b.route("assetstore/:id/re-import/:prev","assetstoreImport",function(u,e){f.trigger("g:navigateTo",d0,{assetstoreId:u,importId:e}),G.import(u)})});
@@ -0,0 +1 @@
1
+ .check-menu-dropdown{position:relative;width:20px;left:-2px}.check-menu-dropdown .g-job-check-menu-button{padding:2px 1px 0 2px}.check-menu-dropdown .g-job-check-menu-button i{position:relative;top:-3px}.g-imports-list-table{width:100%;hyphenate-character:""}.g-imports-list-table th{border-bottom:1px solid #a5a5a5;padding:0 10px}.g-imports-list-table tbody>tr{transition:background .1s linear;border-bottom:1px solid #d7d7d7}.g-imports-list-table tbody>tr td{padding:3px 5px}.g-imports-list-table tbody>tr:hover{background-color:#ddd}.g-imports-list-table tbody>tr.g-highlight{background-color:#f1db74}.g-imports-list-table tbody>tr button+button{margin-left:5px}.g-imports-list-table tbody>tr .g-imports-buttons{display:flex;padding-right:1em}.g-job-list-header{padding-bottom:10px}#g-job-checkbox-menu{display:inline}a.g-job-checkbox-menu-link{display:inline-block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#333}.g-job-filter-container{margin-top:7px}.g-job-filter-container>div{float:left;margin-right:10px}.g-job-filter-container>.checkbox{margin:0 0 0 10px}.g-job-filter-container .dropdown .dropdown-menu ul{list-style-type:none;padding:0;margin:0}.g-job-filter-container .dropdown .checkbox{margin:8px}.g-job-filter-container .dropdown .checkbox.g-job-checkall{padding-bottom:8px;border-bottom:1px solid #ddd}.g-page-size-container{float:right;margin-top:7px}.g-page-size-container>span{margin-right:10px}ul.g-jobs{margin:10px 0}.g-jobs-graph{height:calc(100vh - 230px);overflow-y:hidden;overflow-x:auto}.g-no-job-record{text-align:center}.g-job-worker-task-info{margin-top:10px}.it-controls{margin-bottom:10px}
@@ -0,0 +1,29 @@
1
+ Metadata-Version: 2.4
2
+ Name: girder-import-tracker
3
+ Version: 5.0.0
4
+ Summary: A Girder plugin for data import tracking
5
+ Home-page: https://github.com/girder/girder/tree/master/plugins/import_tracker
6
+ Author: Kitware, Inc.
7
+ Author-email: kitware@kitware.com
8
+ License: Apache 2.0
9
+ Keywords: girder-plugin,import_tracker
10
+ Classifier: Development Status :: 5 - Production/Stable
11
+ Classifier: Natural Language :: English
12
+ Classifier: Programming Language :: Python :: 3
13
+ Description-Content-Type: text/markdown
14
+ Requires-Dist: girder-jobs>=3.0.3
15
+ Requires-Dist: girder>=3.1.23
16
+ Dynamic: author
17
+ Dynamic: author-email
18
+ Dynamic: classifier
19
+ Dynamic: description
20
+ Dynamic: description-content-type
21
+ Dynamic: home-page
22
+ Dynamic: keywords
23
+ Dynamic: license
24
+ Dynamic: requires-dist
25
+ Dynamic: summary
26
+
27
+ # import-tracker
28
+
29
+ A Girder plugin for data import tracking in HistomicsUI
@@ -0,0 +1,21 @@
1
+ MANIFEST.in
2
+ README.md
3
+ plugin.cmake
4
+ pyproject.toml
5
+ setup.py
6
+ girder_import_tracker/__init__.py
7
+ girder_import_tracker/girder_worker_plugin.py
8
+ girder_import_tracker/models.py
9
+ girder_import_tracker/rest.py
10
+ girder_import_tracker/utils.py
11
+ girder_import_tracker.egg-info/PKG-INFO
12
+ girder_import_tracker.egg-info/SOURCES.txt
13
+ girder_import_tracker.egg-info/dependency_links.txt
14
+ girder_import_tracker.egg-info/entry_points.txt
15
+ girder_import_tracker.egg-info/not-zip-safe
16
+ girder_import_tracker.egg-info/requires.txt
17
+ girder_import_tracker.egg-info/top_level.txt
18
+ girder_import_tracker/web_client/dist/girder-plugin-import-tracker.umd.cjs
19
+ girder_import_tracker/web_client/dist/style.css
20
+ plugin_tests/__init__.py
21
+ plugin_tests/test_load.py
@@ -0,0 +1,5 @@
1
+ [girder.plugin]
2
+ import_tracker = girder_import_tracker:GirderPlugin
3
+
4
+ [girder_worker_plugins]
5
+ import_tracker = girder_import_tracker.girder_worker_plugin:ImportTrackerWorkerPlugin
@@ -0,0 +1,2 @@
1
+ girder-jobs>=3.0.3
2
+ girder>=3.1.23
@@ -0,0 +1 @@
1
+ girder_import_tracker
@@ -0,0 +1 @@
1
+ add_standard_plugin_tests(PACKAGE "girder_import_tracker")
File without changes
@@ -0,0 +1,8 @@
1
+ import pytest
2
+
3
+ from girder.plugin import loadedPlugins
4
+
5
+
6
+ @pytest.mark.plugin('import_tracker')
7
+ def test_import(server):
8
+ assert 'import_tracker' in loadedPlugins()
@@ -0,0 +1,6 @@
1
+ [build-system]
2
+ requires = ["setuptools", "setuptools-scm"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [tool.setuptools_scm]
6
+ fallback_version = "0.0.0"
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,66 @@
1
+ import os
2
+ import re
3
+
4
+ from setuptools import find_packages, setup
5
+
6
+
7
+ def prerelease_local_scheme(version):
8
+ """Return local scheme version unless building on master in CircleCI.
9
+
10
+ This function returns the local scheme version number
11
+ (e.g. 0.0.0.dev<N>+g<HASH>) unless building on CircleCI for a
12
+ pre-release in which case it ignores the hash and produces a
13
+ PEP440 compliant pre-release version number (e.g. 0.0.0.dev<N>).
14
+ """
15
+ from setuptools_scm.version import get_local_node_and_date
16
+
17
+ # this regex allows us to publish pypi packages from master, our LTS maintenance branches, and
18
+ # our next major version integration branches
19
+ pattern = r'master|[0-9]+\.x-maintenance|v[0-9]+-integration'
20
+
21
+ if re.match(pattern, os.getenv('CIRCLE_BRANCH', '')):
22
+ return ''
23
+ else:
24
+ return get_local_node_and_date(version)
25
+
26
+
27
+ with open('README.md') as readme_file:
28
+ readme = readme_file.read()
29
+
30
+
31
+ setup(
32
+ name='girder-import-tracker',
33
+ use_scm_version={'root': '../..', 'local_scheme': prerelease_local_scheme},
34
+ setup_requires=[
35
+ 'setuptools-scm',
36
+ 'setuptools-git',
37
+ ],
38
+ description='A Girder plugin for data import tracking',
39
+ long_description=readme,
40
+ long_description_content_type='text/markdown',
41
+ author='Kitware, Inc.',
42
+ author_email='kitware@kitware.com',
43
+ url='https://github.com/girder/girder/tree/master/plugins/import_tracker',
44
+ license='Apache 2.0',
45
+ classifiers=[
46
+ 'Development Status :: 5 - Production/Stable',
47
+ 'Natural Language :: English',
48
+ 'Programming Language :: Python :: 3',
49
+ ],
50
+ install_requires=[
51
+ 'girder-jobs>=3.0.3',
52
+ 'girder>=3.1.23',
53
+ ],
54
+ include_package_data=True,
55
+ keywords='girder-plugin, import_tracker',
56
+ packages=find_packages(exclude=['plugin_tests']),
57
+ zip_safe=False,
58
+ entry_points={
59
+ 'girder.plugin': [
60
+ 'import_tracker = girder_import_tracker:GirderPlugin'
61
+ ],
62
+ 'girder_worker_plugins': [
63
+ 'import_tracker = girder_import_tracker.girder_worker_plugin:ImportTrackerWorkerPlugin'
64
+ ],
65
+ }
66
+ )