plastron-cli 4.6.2__tar.gz → 4.7.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 (42) hide show
  1. {plastron_cli-4.6.2 → plastron_cli-4.7.0}/PKG-INFO +39 -1
  2. {plastron_cli-4.6.2 → plastron_cli-4.7.0}/README.md +38 -0
  3. plastron_cli-4.7.0/VERSION +1 -0
  4. plastron_cli-4.7.0/src/plastron/cli/commands/fixpageorder.py +106 -0
  5. {plastron_cli-4.6.2 → plastron_cli-4.7.0}/src/plastron/cli/commands/importcommand.py +6 -5
  6. {plastron_cli-4.6.2 → plastron_cli-4.7.0}/src/plastron/cli/commands/load.py +2 -1
  7. plastron_cli-4.7.0/src/plastron/cli/commands/replace.py +65 -0
  8. {plastron_cli-4.6.2 → plastron_cli-4.7.0}/src/plastron/cli/commands/update.py +17 -3
  9. {plastron_cli-4.6.2 → plastron_cli-4.7.0}/src/plastron_cli.egg-info/PKG-INFO +39 -1
  10. {plastron_cli-4.6.2 → plastron_cli-4.7.0}/src/plastron_cli.egg-info/SOURCES.txt +2 -0
  11. plastron_cli-4.6.2/VERSION +0 -1
  12. {plastron_cli-4.6.2 → plastron_cli-4.7.0}/pyproject.toml +0 -0
  13. {plastron_cli-4.6.2 → plastron_cli-4.7.0}/setup.cfg +0 -0
  14. {plastron_cli-4.6.2 → plastron_cli-4.7.0}/src/plastron/cli/__init__.py +0 -0
  15. {plastron_cli-4.6.2 → plastron_cli-4.7.0}/src/plastron/cli/commands/__init__.py +0 -0
  16. {plastron_cli-4.6.2 → plastron_cli-4.7.0}/src/plastron/cli/commands/annotate.py +0 -0
  17. {plastron_cli-4.6.2 → plastron_cli-4.7.0}/src/plastron/cli/commands/create.py +0 -0
  18. {plastron_cli-4.6.2 → plastron_cli-4.7.0}/src/plastron/cli/commands/delete.py +0 -0
  19. {plastron_cli-4.6.2 → plastron_cli-4.7.0}/src/plastron/cli/commands/echo.py +0 -0
  20. {plastron_cli-4.6.2 → plastron_cli-4.7.0}/src/plastron/cli/commands/export.py +0 -0
  21. {plastron_cli-4.6.2 → plastron_cli-4.7.0}/src/plastron/cli/commands/extractocr.py +0 -0
  22. {plastron_cli-4.6.2 → plastron_cli-4.7.0}/src/plastron/cli/commands/find.py +0 -0
  23. {plastron_cli-4.6.2 → plastron_cli-4.7.0}/src/plastron/cli/commands/imgsize.py +0 -0
  24. {plastron_cli-4.6.2 → plastron_cli-4.7.0}/src/plastron/cli/commands/list.py +0 -0
  25. {plastron_cli-4.6.2 → plastron_cli-4.7.0}/src/plastron/cli/commands/ping.py +0 -0
  26. {plastron_cli-4.6.2 → plastron_cli-4.7.0}/src/plastron/cli/commands/publish.py +0 -0
  27. {plastron_cli-4.6.2 → plastron_cli-4.7.0}/src/plastron/cli/commands/reindex.py +0 -0
  28. {plastron_cli-4.6.2 → plastron_cli-4.7.0}/src/plastron/cli/commands/set.py +0 -0
  29. {plastron_cli-4.6.2 → plastron_cli-4.7.0}/src/plastron/cli/commands/stub.py +0 -0
  30. {plastron_cli-4.6.2 → plastron_cli-4.7.0}/src/plastron/cli/commands/unpublish.py +0 -0
  31. {plastron_cli-4.6.2 → plastron_cli-4.7.0}/src/plastron/cli/commands/verify.py +0 -0
  32. {plastron_cli-4.6.2 → plastron_cli-4.7.0}/src/plastron/cli/handlers/__init__.py +0 -0
  33. {plastron_cli-4.6.2 → plastron_cli-4.7.0}/src/plastron/cli/handlers/mapped-csv.py +0 -0
  34. {plastron_cli-4.6.2 → plastron_cli-4.7.0}/src/plastron/cli/handlers/reel.py +0 -0
  35. {plastron_cli-4.6.2 → plastron_cli-4.7.0}/src/plastron/cli/handlers/turtle.py +0 -0
  36. {plastron_cli-4.6.2 → plastron_cli-4.7.0}/src/plastron_cli.egg-info/dependency_links.txt +0 -0
  37. {plastron_cli-4.6.2 → plastron_cli-4.7.0}/src/plastron_cli.egg-info/entry_points.txt +0 -0
  38. {plastron_cli-4.6.2 → plastron_cli-4.7.0}/src/plastron_cli.egg-info/requires.txt +0 -0
  39. {plastron_cli-4.6.2 → plastron_cli-4.7.0}/src/plastron_cli.egg-info/top_level.txt +0 -0
  40. {plastron_cli-4.6.2 → plastron_cli-4.7.0}/tests/test_cli.py +0 -0
  41. {plastron_cli-4.6.2 → plastron_cli-4.7.0}/tests/test_embedded_objects.py +0 -0
  42. {plastron_cli-4.6.2 → plastron_cli-4.7.0}/tests/test_update_command.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: plastron-cli
3
- Version: 4.6.2
3
+ Version: 4.7.0
4
4
  Summary: Plastron command line client
5
5
  Author-email: University of Maryland Libraries <lib-ssdr@umd.edu>, Josh Westgard <westgard@umd.edu>, Peter Eichman <peichman@umd.edu>, Mohamed Abdul Rasheed <mohideen@umd.edu>, Ben Wallberg <wallberg@umd.edu>, David Steelman <dsteelma@umd.edu>, Marc Andreu Grillo Aguilar <aguilarm@umd.edu>
6
6
  Requires-Python: >=3.10
@@ -221,6 +221,24 @@ optional arguments:
221
221
  resource in the result list
222
222
  ```
223
223
 
224
+ ### Fix Page Order (fixpageorder)
225
+
226
+ ```text
227
+ $ plastron fixpageorder --help
228
+ usage: plastron fixpageorder [-h] [-f URIS_FILE] [-n] [uris ...]
229
+
230
+ Fix the order of pages in an object, using the page titles as a guide
231
+
232
+ positional arguments:
233
+ uris URIs of objects to fix
234
+
235
+ options:
236
+ -h, --help show this help message and exit
237
+ -f URIS_FILE, --uris-file URIS_FILE
238
+ file containing URIs of objects to fix
239
+ -n, --dry-run dry run; do not actually modify the pages
240
+ ```
241
+
224
242
  ### Image Size (imgsize)
225
243
 
226
244
  ```text
@@ -371,6 +389,26 @@ COMMANDS:
371
389
  CamelFcrepoSolrIndexingDestinations: direct:solr.Index,direct:solr.LegacyIndex
372
390
  ```
373
391
 
392
+ ### Replace (replace)
393
+
394
+ ```text
395
+ $ plastron replace --help
396
+ usage: plastron replace [-h] [--binary-file BINARY_FILE] [--mime-type MIME_TYPE] URI|PATH
397
+
398
+ Replace a binary resource in the repository
399
+
400
+ positional arguments:
401
+ URI|PATH URI or repository path of the resource to replace
402
+
403
+ options:
404
+ -h, --help show this help message and exit
405
+ --binary-file BINARY_FILE
406
+ local path to the binary file
407
+ --mime-type MIME_TYPE
408
+ use this MIME type instead of auto-detecting based on the BINARY_FILE
409
+
410
+ ```
411
+
374
412
  ### Stub (stub)
375
413
 
376
414
  ```text
@@ -199,6 +199,24 @@ optional arguments:
199
199
  resource in the result list
200
200
  ```
201
201
 
202
+ ### Fix Page Order (fixpageorder)
203
+
204
+ ```text
205
+ $ plastron fixpageorder --help
206
+ usage: plastron fixpageorder [-h] [-f URIS_FILE] [-n] [uris ...]
207
+
208
+ Fix the order of pages in an object, using the page titles as a guide
209
+
210
+ positional arguments:
211
+ uris URIs of objects to fix
212
+
213
+ options:
214
+ -h, --help show this help message and exit
215
+ -f URIS_FILE, --uris-file URIS_FILE
216
+ file containing URIs of objects to fix
217
+ -n, --dry-run dry run; do not actually modify the pages
218
+ ```
219
+
202
220
  ### Image Size (imgsize)
203
221
 
204
222
  ```text
@@ -349,6 +367,26 @@ COMMANDS:
349
367
  CamelFcrepoSolrIndexingDestinations: direct:solr.Index,direct:solr.LegacyIndex
350
368
  ```
351
369
 
370
+ ### Replace (replace)
371
+
372
+ ```text
373
+ $ plastron replace --help
374
+ usage: plastron replace [-h] [--binary-file BINARY_FILE] [--mime-type MIME_TYPE] URI|PATH
375
+
376
+ Replace a binary resource in the repository
377
+
378
+ positional arguments:
379
+ URI|PATH URI or repository path of the resource to replace
380
+
381
+ options:
382
+ -h, --help show this help message and exit
383
+ --binary-file BINARY_FILE
384
+ local path to the binary file
385
+ --mime-type MIME_TYPE
386
+ use this MIME type instead of auto-detecting based on the BINARY_FILE
387
+
388
+ ```
389
+
352
390
  ### Stub (stub)
353
391
 
354
392
  ```text
@@ -0,0 +1 @@
1
+ 4.7.0
@@ -0,0 +1,106 @@
1
+ import logging
2
+ import re
3
+ from argparse import Namespace, FileType
4
+ from collections.abc import Iterable
5
+
6
+ from plastron.cli import get_uris
7
+ from plastron.cli.commands import BaseCommand
8
+ from plastron.models.ore import Proxy
9
+ from plastron.repo import RepositoryResource
10
+ from plastron.repo.pcdm import PCDMObjectResource
11
+
12
+ logger = logging.getLogger(__name__)
13
+
14
+
15
+ def configure_cli(subparsers):
16
+ parser = subparsers.add_parser(
17
+ name='fixpageorder',
18
+ description='Fix the order of pages in an object, using the page titles as a guide',
19
+ )
20
+ parser.add_argument(
21
+ '-f', '--uris-file',
22
+ action='store',
23
+ type=FileType(),
24
+ help='file containing URIs of objects to fix'
25
+ )
26
+ parser.add_argument(
27
+ '-n', '--dry-run',
28
+ action='store_true',
29
+ help='dry run; do not actually modify the pages',
30
+ )
31
+ parser.add_argument(
32
+ 'uris',
33
+ nargs='*',
34
+ help='URIs of objects to fix',
35
+ )
36
+ parser.set_defaults(cmd_name='fixpageorder')
37
+
38
+
39
+ class Command(BaseCommand):
40
+ def __call__(self, args: Namespace):
41
+ # mimicking a click.Context object to bridge between argparse and click commands
42
+ ctx = Namespace(obj=self.context)
43
+ return fix_page_order(ctx, uris=get_uris(args), dry_run=args.dry_run)
44
+
45
+
46
+ def fix_page_order(ctx: Namespace, uris: Iterable[str], dry_run: bool = False):
47
+ page_pattern = re.compile(r'page (\d+)', re.IGNORECASE)
48
+ for uri in uris:
49
+ logger.info(f'Retrieving {uri}...')
50
+ resource = ctx.obj.repo.get_resource(uri, PCDMObjectResource)
51
+ proxy_by_page: dict[int, Proxy] = {}
52
+ proxy_by_uri: dict[str, Proxy] = {}
53
+ resource_by_uri: dict[str, RepositoryResource] = {}
54
+ logger.info('Checking proxies...')
55
+ for proxy in resource.get_proxies():
56
+ resource_by_uri[proxy.url] = proxy
57
+ proxy_obj = proxy.describe(Proxy)
58
+ title = str(proxy_obj.title)
59
+ if m := page_pattern.search(title):
60
+ proxy_by_page[int(m.group(1))] = proxy_obj
61
+ proxy_by_uri[proxy.url] = proxy_obj
62
+ else:
63
+ raise RuntimeError(f'Could not find page number in "{proxy_obj.title}"')
64
+
65
+ logger.info('Current order:')
66
+ for page_n, proxy_obj in proxy_by_page.items():
67
+ logger.info(f'{page_n:3d}: {proxy_obj.uri} ({proxy_obj.title})')
68
+
69
+ sorted_pages = [proxy_by_page[i] for i in sorted(proxy_by_page.keys())]
70
+
71
+ logger.info('Desired order:')
72
+ for page_n, proxy_obj in enumerate(sorted_pages, 1):
73
+ logger.info(f'{page_n:3d}: {proxy_obj.uri} ({proxy_obj.title})')
74
+
75
+ if list(proxy_by_page.values()) == sorted_pages:
76
+ logger.info(f'No changes to needed; skipping {uri}')
77
+ continue
78
+
79
+ logger.info(f'Modifications required for {uri}')
80
+
81
+ if dry_run:
82
+ logger.info(f'Dry run; skipping modifications to the proxies of {uri}')
83
+ continue
84
+
85
+ with ctx.obj.repo.transaction():
86
+ for page_n, proxy_obj in enumerate(sorted_pages, 1):
87
+ logger.info(f'Checking whether {proxy_obj.uri} ({proxy_obj.title}) needs an update...')
88
+
89
+ prev_proxy = proxy_by_page.get(page_n - 1, None)
90
+ next_proxy = proxy_by_page.get(page_n + 1, None)
91
+
92
+ if prev_proxy:
93
+ proxy_obj.prev = prev_proxy
94
+ else:
95
+ proxy_obj.prev.clear()
96
+
97
+ if next_proxy:
98
+ proxy_obj.next = next_proxy
99
+ else:
100
+ proxy_obj.next.clear()
101
+
102
+ if proxy_obj.has_changes:
103
+ logger.info(f'Updating {proxy_obj.uri} ({proxy_obj.title})')
104
+ resource_by_uri[proxy_obj.uri].update()
105
+ else:
106
+ logger.info('No changes to {proxy_obj.uri} ({proxy_obj.title})')
@@ -1,15 +1,16 @@
1
1
  import csv
2
2
  import logging
3
- from argparse import FileType, ArgumentTypeError, Namespace
3
+ from argparse import ArgumentTypeError, FileType, Namespace
4
4
  from typing import TextIO
5
5
 
6
6
  from plastron.cli.commands import BaseCommand
7
- from plastron.jobs.importjob.ndnp import NDNPBatch, write_import_csv
8
- from plastron.jobs.importjob import ImportConfig, ImportJob
9
7
  from plastron.jobs import Jobs
10
- from plastron.models import get_model_from_name, ModelClassNotFoundError
8
+ from plastron.jobs.importjob import ImportConfig, ImportJob
9
+ from plastron.jobs.importjob.ndnp import NDNPBatch, write_import_csv
11
10
  from plastron.utils import datetimestamp, uri_or_curie
12
11
 
12
+ from plastron.models import ModelClassNotFoundError, get_model_from_name
13
+
13
14
  logger = logging.getLogger(__name__)
14
15
 
15
16
 
@@ -212,7 +213,7 @@ class Command(BaseCommand):
212
213
  if args.convert_from is not None:
213
214
  if args.convert_from == 'ndnp':
214
215
  params = dict(args.convert_params or [])
215
- batch = NDNPBatch(params['dir'], params['batch_file'])
216
+ batch = NDNPBatch(**params)
216
217
  logger.info(f'Converting NDNP batch at {batch.batch_file} to import job {args.job_id}')
217
218
  job = jobs.create_job(job_class=ImportJob, config=ImportConfig(
218
219
  job_id=args.job_id,
@@ -9,6 +9,7 @@ from time import sleep
9
9
 
10
10
  from plastron.client import Client, ClientError
11
11
  from plastron.cli.commands import BaseCommand
12
+ from plastron.client.transactions import transaction
12
13
  from plastron.repo import DataReadError
13
14
  from plastron.cli import ConfigError
14
15
  from plastron.jobs import ItemLog
@@ -247,7 +248,7 @@ def load_item(client: Client, batch_item, args, extra=None):
247
248
 
248
249
  if args.use_transactions:
249
250
  # open transaction
250
- with client.transaction(keep_alive=90) as txn_client: # type: TransactionClient
251
+ with transaction(client, keep_alive=90) as txn_client: # type: TransactionClient
251
252
  # create item and its components
252
253
  try:
253
254
  load_item_internal(txn_client, item, args, extra)
@@ -0,0 +1,65 @@
1
+ import logging
2
+ from argparse import Namespace
3
+
4
+ from rdflib import Literal
5
+
6
+ from plastron.cli.commands import BaseCommand
7
+ from plastron.files import LocalFileSource
8
+ from plastron.models.pcdm import PCDMFile
9
+ from plastron.repo import Repository, BinaryResource, RepositoryError
10
+
11
+ logger = logging.getLogger(__name__)
12
+
13
+
14
+ def configure_cli(subparsers):
15
+ parser = subparsers.add_parser(
16
+ name='replace',
17
+ description='Replace a binary resource in the repository'
18
+ )
19
+ parser.add_argument(
20
+ '--binary-file',
21
+ help='local path to the binary file',
22
+ )
23
+ parser.add_argument(
24
+ '--mime-type',
25
+ help='use this MIME type instead of auto-detecting based on the BINARY_FILE',
26
+ )
27
+ parser.add_argument(
28
+ 'location',
29
+ help='URI or repository path of the resource to replace',
30
+ metavar='URI|PATH',
31
+ )
32
+ parser.set_defaults(cmd_name='replace')
33
+
34
+
35
+ class Command(BaseCommand):
36
+ def __call__(self, args: Namespace):
37
+ # mimicking a click.Context object to bridge between argparse and click commands
38
+ ctx = Namespace(obj=self.context)
39
+ return replace(ctx, location=args.location, binary_filename=args.binary_file, mime_type=args.mime_type)
40
+
41
+
42
+ def replace(ctx, location: str, binary_filename: str, mime_type: str = None):
43
+ repo: Repository = ctx.obj.repo
44
+ try:
45
+ resource = repo.get_resource(location, BinaryResource).read()
46
+ except RepositoryError as e:
47
+ raise RuntimeError(str(e)) from e
48
+
49
+ if not resource.exists:
50
+ raise RuntimeError(f'Resource {resource.url} not found')
51
+
52
+ source = LocalFileSource(binary_filename)
53
+
54
+ try:
55
+ with repo.transaction():
56
+ resource.update_binary(source, mime_type=mime_type)
57
+ logger.info(f'Updating metadata for {resource.url}')
58
+ file = resource.describe(PCDMFile)
59
+ file.title = Literal(source.filename)
60
+ resource.update()
61
+
62
+ print(resource.url)
63
+
64
+ except RepositoryError as e:
65
+ raise RuntimeError(str(e)) from e
@@ -2,10 +2,11 @@ import logging
2
2
  from argparse import FileType, Namespace
3
3
 
4
4
  from plastron.cli.commands import BaseCommand
5
+ from plastron.jobs import ItemLog
5
6
  from plastron.jobs.updatejob import UpdateJob
6
- from plastron.models import get_model_from_name
7
7
  from plastron.utils import parse_predicate_list
8
- from plastron.jobs import ItemLog
8
+
9
+ from plastron.models import get_model_from_name
9
10
 
10
11
  logger = logging.getLogger(__name__)
11
12
 
@@ -88,9 +89,22 @@ class Command(BaseCommand):
88
89
 
89
90
  traverse = parse_predicate_list(args.recursive) if args.recursive is not None else []
90
91
 
92
+ uris = set()
93
+
94
+ if args.file:
95
+ try:
96
+ with open(args.file, 'r') as f:
97
+ file_uris = [line.strip() for line in f if line.strip()]
98
+ uris = uris | set(file_uris)
99
+ except FileNotFoundError:
100
+ raise RuntimeError(f"File {args.file} not found")
101
+
102
+ if args.uris:
103
+ uris = uris | set(args.uris)
104
+
91
105
  update_job = UpdateJob(
92
106
  repo=self.context.repo,
93
- uris=args.uris,
107
+ uris=uris,
94
108
  sparql_update=sparql_update,
95
109
  model_class=model_class,
96
110
  traverse=traverse,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: plastron-cli
3
- Version: 4.6.2
3
+ Version: 4.7.0
4
4
  Summary: Plastron command line client
5
5
  Author-email: University of Maryland Libraries <lib-ssdr@umd.edu>, Josh Westgard <westgard@umd.edu>, Peter Eichman <peichman@umd.edu>, Mohamed Abdul Rasheed <mohideen@umd.edu>, Ben Wallberg <wallberg@umd.edu>, David Steelman <dsteelma@umd.edu>, Marc Andreu Grillo Aguilar <aguilarm@umd.edu>
6
6
  Requires-Python: >=3.10
@@ -221,6 +221,24 @@ optional arguments:
221
221
  resource in the result list
222
222
  ```
223
223
 
224
+ ### Fix Page Order (fixpageorder)
225
+
226
+ ```text
227
+ $ plastron fixpageorder --help
228
+ usage: plastron fixpageorder [-h] [-f URIS_FILE] [-n] [uris ...]
229
+
230
+ Fix the order of pages in an object, using the page titles as a guide
231
+
232
+ positional arguments:
233
+ uris URIs of objects to fix
234
+
235
+ options:
236
+ -h, --help show this help message and exit
237
+ -f URIS_FILE, --uris-file URIS_FILE
238
+ file containing URIs of objects to fix
239
+ -n, --dry-run dry run; do not actually modify the pages
240
+ ```
241
+
224
242
  ### Image Size (imgsize)
225
243
 
226
244
  ```text
@@ -371,6 +389,26 @@ COMMANDS:
371
389
  CamelFcrepoSolrIndexingDestinations: direct:solr.Index,direct:solr.LegacyIndex
372
390
  ```
373
391
 
392
+ ### Replace (replace)
393
+
394
+ ```text
395
+ $ plastron replace --help
396
+ usage: plastron replace [-h] [--binary-file BINARY_FILE] [--mime-type MIME_TYPE] URI|PATH
397
+
398
+ Replace a binary resource in the repository
399
+
400
+ positional arguments:
401
+ URI|PATH URI or repository path of the resource to replace
402
+
403
+ options:
404
+ -h, --help show this help message and exit
405
+ --binary-file BINARY_FILE
406
+ local path to the binary file
407
+ --mime-type MIME_TYPE
408
+ use this MIME type instead of auto-detecting based on the BINARY_FILE
409
+
410
+ ```
411
+
374
412
  ### Stub (stub)
375
413
 
376
414
  ```text
@@ -10,6 +10,7 @@ src/plastron/cli/commands/echo.py
10
10
  src/plastron/cli/commands/export.py
11
11
  src/plastron/cli/commands/extractocr.py
12
12
  src/plastron/cli/commands/find.py
13
+ src/plastron/cli/commands/fixpageorder.py
13
14
  src/plastron/cli/commands/imgsize.py
14
15
  src/plastron/cli/commands/importcommand.py
15
16
  src/plastron/cli/commands/list.py
@@ -17,6 +18,7 @@ src/plastron/cli/commands/load.py
17
18
  src/plastron/cli/commands/ping.py
18
19
  src/plastron/cli/commands/publish.py
19
20
  src/plastron/cli/commands/reindex.py
21
+ src/plastron/cli/commands/replace.py
20
22
  src/plastron/cli/commands/set.py
21
23
  src/plastron/cli/commands/stub.py
22
24
  src/plastron/cli/commands/unpublish.py
@@ -1 +0,0 @@
1
- 4.6.2
File without changes