das-cli 1.0.12__py3-none-any.whl → 1.0.15__py3-none-any.whl
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.
Potentially problematic release.
This version of das-cli might be problematic. Click here for more details.
- das/cli.py +41 -0
- das/managers/digital_objects_manager.py +46 -0
- das/services/digital_objects.py +44 -0
- {das_cli-1.0.12.dist-info → das_cli-1.0.15.dist-info}/METADATA +31 -1
- {das_cli-1.0.12.dist-info → das_cli-1.0.15.dist-info}/RECORD +9 -7
- {das_cli-1.0.12.dist-info → das_cli-1.0.15.dist-info}/WHEEL +0 -0
- {das_cli-1.0.12.dist-info → das_cli-1.0.15.dist-info}/entry_points.txt +0 -0
- {das_cli-1.0.12.dist-info → das_cli-1.0.15.dist-info}/licenses/LICENSE +0 -0
- {das_cli-1.0.12.dist-info → das_cli-1.0.15.dist-info}/top_level.txt +0 -0
das/cli.py
CHANGED
|
@@ -14,6 +14,7 @@ from das.app import Das
|
|
|
14
14
|
from das.managers.download_manager import DownloadManager
|
|
15
15
|
from das.managers.entries_manager import EntryManager
|
|
16
16
|
from das.managers.search_manager import SearchManager
|
|
17
|
+
from das.managers.digital_objects_manager import DigitalObjectsManager
|
|
17
18
|
from das.common.file_utils import load_file_based_on_extension, parse_data_string
|
|
18
19
|
from das.ai.plugins.dasai import DasAI
|
|
19
20
|
|
|
@@ -51,6 +52,7 @@ class DasCLI:
|
|
|
51
52
|
self.entry_manager = None
|
|
52
53
|
self.search_manager = None
|
|
53
54
|
self.download_manager = None
|
|
55
|
+
self.digital_objects_manager = None
|
|
54
56
|
self.das_ai = None
|
|
55
57
|
|
|
56
58
|
def get_client(self):
|
|
@@ -65,6 +67,7 @@ class DasCLI:
|
|
|
65
67
|
self.entry_manager = EntryManager()
|
|
66
68
|
self.search_manager = SearchManager()
|
|
67
69
|
self.download_manager = DownloadManager()
|
|
70
|
+
self.digital_objects_manager = DigitalObjectsManager()
|
|
68
71
|
# Set SSL verification based on saved config
|
|
69
72
|
if not self.client:
|
|
70
73
|
self.client = Das(self.api_url)
|
|
@@ -409,6 +412,44 @@ def delete_entry(das_ctx, code):
|
|
|
409
412
|
except Exception as e:
|
|
410
413
|
click.secho(f"Error: {e}", fg="red")
|
|
411
414
|
|
|
415
|
+
@entry.command("link-digital-objects")
|
|
416
|
+
@click.option('--entry-code', required=True, help='Entry code to link/unlink digital objects to')
|
|
417
|
+
@click.option('--digital-object-code', '-d', multiple=True, required=True, help='Digital object code. Use multiple times for multiple objects.')
|
|
418
|
+
@click.option('--unlink', is_flag=True, help='Unlink specified digital objects from the entry instead of linking')
|
|
419
|
+
@pass_das_context
|
|
420
|
+
def link_digital_objects(das_ctx, entry_code, digital_object_code, unlink):
|
|
421
|
+
"""Link or unlink existing digital objects to an entry by their codes.
|
|
422
|
+
|
|
423
|
+
Examples:
|
|
424
|
+
|
|
425
|
+
\b
|
|
426
|
+
# Link two digital objects to an entry
|
|
427
|
+
das entry link-digital-objects --entry-code ENT001 -d DO001 -d DO002
|
|
428
|
+
|
|
429
|
+
\b
|
|
430
|
+
# Unlink a digital object from an entry
|
|
431
|
+
das entry link-digital-objects --entry-code ENT001 -d DO003 --unlink
|
|
432
|
+
"""
|
|
433
|
+
try:
|
|
434
|
+
das_ctx.get_client()
|
|
435
|
+
codes = list(digital_object_code)
|
|
436
|
+
if not codes:
|
|
437
|
+
raise click.UsageError("Please provide at least one --digital-object-code")
|
|
438
|
+
|
|
439
|
+
success = das_ctx.digital_objects_manager.link_existing_digital_objects(
|
|
440
|
+
entry_code=entry_code,
|
|
441
|
+
digital_object_code_list=codes,
|
|
442
|
+
is_unlink=unlink,
|
|
443
|
+
)
|
|
444
|
+
|
|
445
|
+
if success:
|
|
446
|
+
action = "unlinked" if unlink else "linked"
|
|
447
|
+
click.secho(f"✓ Successfully {action} {len(codes)} digital object(s) for entry '{entry_code}'", fg="green")
|
|
448
|
+
else:
|
|
449
|
+
click.secho("Operation did not report success.", fg="yellow")
|
|
450
|
+
except Exception as e:
|
|
451
|
+
click.secho(f"Error: {e}", fg="red")
|
|
452
|
+
|
|
412
453
|
@entry.command("create")
|
|
413
454
|
@click.option('--attribute', required=True, help='Attribute name')
|
|
414
455
|
@click.argument('file_path', required=False)
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
from das.common.config import load_api_url
|
|
2
|
+
from das.services.entries import EntriesService
|
|
3
|
+
from das.services.digital_objects import DigitalObjectsService
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class DigitalObjectsManager:
|
|
7
|
+
def __init__(self):
|
|
8
|
+
base_url = load_api_url()
|
|
9
|
+
if base_url is None or base_url == "":
|
|
10
|
+
raise ValueError(f"Base URL is required - {self.__class__.__name__}")
|
|
11
|
+
|
|
12
|
+
self.digital_objects_service = DigitalObjectsService(base_url)
|
|
13
|
+
self.entry_service = EntriesService(base_url)
|
|
14
|
+
|
|
15
|
+
def link_existing_digital_objects(
|
|
16
|
+
self, entry_code: str, digital_object_code_list: list[str], is_unlink: bool = False
|
|
17
|
+
) -> bool:
|
|
18
|
+
"""Attach or detach (unlink) digital objects to an entry using codes."""
|
|
19
|
+
entry_response = self.entry_service.get_entry(entry_code)
|
|
20
|
+
|
|
21
|
+
if entry_response is None:
|
|
22
|
+
raise ValueError(f"Entry with code '{entry_code}' not found")
|
|
23
|
+
|
|
24
|
+
entry_payload = entry_response.get("entry")
|
|
25
|
+
if entry_payload is None:
|
|
26
|
+
raise ValueError(f"Entry with code '{entry_code}' not found")
|
|
27
|
+
|
|
28
|
+
digital_object_id_list: list[str] = []
|
|
29
|
+
|
|
30
|
+
for code in digital_object_code_list:
|
|
31
|
+
do_response = self.entry_service.get_entry(code)
|
|
32
|
+
do_entry = do_response.get("entry") if do_response else None
|
|
33
|
+
if do_entry is None:
|
|
34
|
+
raise ValueError(f"Digital object with code '{code}' not found")
|
|
35
|
+
digital_object_id_list.append(do_entry.get("id"))
|
|
36
|
+
|
|
37
|
+
result = self.digital_objects_service.link_existing_digital_objects(
|
|
38
|
+
attribute_id=entry_response.get("attributeId"),
|
|
39
|
+
entry_id=entry_payload.get("id"),
|
|
40
|
+
digital_object_id_list=digital_object_id_list,
|
|
41
|
+
is_unlink=is_unlink,
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
return result
|
|
45
|
+
|
|
46
|
+
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
from das.common.api import post_data
|
|
2
|
+
from das.common.config import load_token
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class DigitalObjectsService:
|
|
6
|
+
def __init__(self, base_url):
|
|
7
|
+
self.base_url = f"{base_url}/api/services/app/DigitalObject"
|
|
8
|
+
|
|
9
|
+
def link_existing_digital_objects(self, attribute_id: int, entry_id: str, digital_object_id_list: list[str], is_unlink: bool = False):
|
|
10
|
+
"""Link existing digital objects to an entry."""
|
|
11
|
+
token = load_token()
|
|
12
|
+
|
|
13
|
+
if token is None or token == "":
|
|
14
|
+
raise ValueError("Authorization token is required")
|
|
15
|
+
|
|
16
|
+
headers = {
|
|
17
|
+
"Authorization": f"Bearer {token}",
|
|
18
|
+
"Content-Type": "application/json",
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
payload = {
|
|
22
|
+
"attributeId": attribute_id,
|
|
23
|
+
"attributeValueId": entry_id,
|
|
24
|
+
"digitalObjects": [],
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
for digital_object_id in digital_object_id_list:
|
|
28
|
+
payload["digitalObjects"].append(
|
|
29
|
+
{
|
|
30
|
+
"attributeId": attribute_id,
|
|
31
|
+
"attributeValueId": entry_id,
|
|
32
|
+
"digitalObjectId": digital_object_id,
|
|
33
|
+
"isDeleted": is_unlink,
|
|
34
|
+
}
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
response = post_data(
|
|
38
|
+
f"{self.base_url}/LinkExistingDigitalObject", data=payload, headers=headers
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
return response.get("success")
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: das-cli
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.15
|
|
4
4
|
Summary: DAS api client.
|
|
5
5
|
Author: Royal Netherlands Institute for Sea Research
|
|
6
6
|
License-Expression: MIT
|
|
@@ -166,6 +166,23 @@ das entry update --attribute <AttributeName> [--code CODE] <file_path>
|
|
|
166
166
|
# das entry update --attribute core --data [{ 'Code': 'ENT001' }, { 'Code': 'ENT002' }]
|
|
167
167
|
```
|
|
168
168
|
|
|
169
|
+
#### Link or unlink digital objects
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
# Link digital objects by their codes to an entry
|
|
173
|
+
das entry link-digital-objects --entry-code ENT001 -d DO001 -d DO002
|
|
174
|
+
|
|
175
|
+
# Unlink digital objects from an entry
|
|
176
|
+
das entry link-digital-objects --entry-code ENT001 -d DO003 --unlink
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
#### Change ownership
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
# Transfer ownership of one or more entries to a user
|
|
183
|
+
das entry chown --user alice --code ENT001 --code ENT002
|
|
184
|
+
```
|
|
185
|
+
|
|
169
186
|
### Hangfire
|
|
170
187
|
|
|
171
188
|
```bash
|
|
@@ -216,6 +233,19 @@ das config ssl-status
|
|
|
216
233
|
das config reset --force
|
|
217
234
|
```
|
|
218
235
|
|
|
236
|
+
### AI
|
|
237
|
+
|
|
238
|
+
```bash
|
|
239
|
+
# Start interactive DAS AI session (prompts for OpenAI API key if needed)
|
|
240
|
+
das ai enable
|
|
241
|
+
|
|
242
|
+
# Clear saved OpenAI key and auth token
|
|
243
|
+
das ai clear [--force]
|
|
244
|
+
|
|
245
|
+
# Alias for `das ai clear`
|
|
246
|
+
das ai logout [--force]
|
|
247
|
+
```
|
|
248
|
+
|
|
219
249
|
## Python API
|
|
220
250
|
|
|
221
251
|
### Basic Usage
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
das/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
2
|
das/app.py,sha256=kKxN4Vn84SA5Ph3zY13avMG2vrUp-ffpdDkhwYR9Bho,1475
|
|
3
|
-
das/cli.py,sha256=
|
|
3
|
+
das/cli.py,sha256=3BujNatTZXqXGoDNleG8ru4GT_KkUDRQujesAyGRP0w,46971
|
|
4
4
|
das/ai/plugins/dasai.py,sha256=R0X0Vey_GOAtWoqcloB-NATZFtXB_l5b9dfPXocNIbI,2165
|
|
5
5
|
das/ai/plugins/entries/entries_plugin.py,sha256=Dhv6PrguQj5mzxBW6DlCzkmwucszazLQfzwlp9EhIGk,608
|
|
6
6
|
das/authentication/auth.py,sha256=DTtH66Ft6nuuMe7EYvrr3GqGVEGGxE7GmD2fO7vRv4s,1501
|
|
@@ -11,20 +11,22 @@ das/common/entry_fields_constants.py,sha256=5Yh4Ujt70HEF-FsnwVBPBm3DB3HHzQWSWR-9
|
|
|
11
11
|
das/common/enums.py,sha256=jS0frv6717duG_wZNockXMTZ-VfsGu_f8_-lgYGnrcY,1745
|
|
12
12
|
das/common/file_utils.py,sha256=-zePjYsj8iRpQssVQMHDK3Mh5q8FooKJCUCKCXKS6_Y,7006
|
|
13
13
|
das/managers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
14
|
+
das/managers/digital_objects_manager.py,sha256=i6wDx589dEQ58X_pZGON808GkWinymV3PZAZ4TVx1P0,1825
|
|
14
15
|
das/managers/download_manager.py,sha256=NqaLhmjw-4nZq8SVdN0g5MAnbMPEnu-A3A4oXxQ-IZQ,3776
|
|
15
16
|
das/managers/entries_manager.py,sha256=Kc_PN71Bp7VICrxoP9MiDCrUzR7OdUXfX5puDDxtm08,19015
|
|
16
17
|
das/managers/search_manager.py,sha256=kad6-3H-LsYlUVPE7yKEaCuKLpN2w2-eE3Baskg-R-0,4265
|
|
17
18
|
das/services/attributes.py,sha256=78E9f1wNZYxG9Hg5HfX_h1CFmACaMjwD2Y6Ilb7PJGY,2616
|
|
18
19
|
das/services/cache.py,sha256=g-vY51gqGV_1Vpza476PkMqGpuDNo1NbTwQWIIsvO0s,1932
|
|
20
|
+
das/services/digital_objects.py,sha256=_1X1PqQ2X0_0--tO4YRuNXQEiZIyKSPEYSwROliTc8o,1394
|
|
19
21
|
das/services/downloads.py,sha256=YBDFPmjAQHUK0OUdFprW1Ox81nzpKaJE9xQBJyyEz4Q,3060
|
|
20
22
|
das/services/entries.py,sha256=Uspl7LZcNWEnr7ct5_Kn31jMjrkSKV7UXzrN6nb3HF0,4966
|
|
21
23
|
das/services/entry_fields.py,sha256=x2wUDkKNduj9pf4s56hRo0UW-eBhipkU9gFMEjFw5DA,1290
|
|
22
24
|
das/services/hangfire.py,sha256=hidmVP9yb4znzBaJJRyKawYx7oYaBv5OVL-t0BhvN_A,818
|
|
23
25
|
das/services/search.py,sha256=3X_KPb9fs024FhxoTr4j-xY5ymm5rvvzlekxuh8tLdg,1374
|
|
24
26
|
das/services/users.py,sha256=iNijO2UPIEtcpPy8Tkemdxxym9rYLCUyckQHIQj68W0,795
|
|
25
|
-
das_cli-1.0.
|
|
26
|
-
das_cli-1.0.
|
|
27
|
-
das_cli-1.0.
|
|
28
|
-
das_cli-1.0.
|
|
29
|
-
das_cli-1.0.
|
|
30
|
-
das_cli-1.0.
|
|
27
|
+
das_cli-1.0.15.dist-info/licenses/LICENSE,sha256=4EDhysVgQWBlzo0rdUl_k89s-iVfgCcSa1gUx1TM1vA,1124
|
|
28
|
+
das_cli-1.0.15.dist-info/METADATA,sha256=2blsy-4LbMkhGV7T9iipiPDSIk6eSBfQxCrBe_qJkZM,11150
|
|
29
|
+
das_cli-1.0.15.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
30
|
+
das_cli-1.0.15.dist-info/entry_points.txt,sha256=ZrdMae7NcvogQhzM1zun8E8n_QwYq-LpZvoJCr2_I4g,36
|
|
31
|
+
das_cli-1.0.15.dist-info/top_level.txt,sha256=OJsPEeJyJ2rJlpEn2DTPgbMSvYG-6FeD13_m5qLpw3E,4
|
|
32
|
+
das_cli-1.0.15.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|