das-cli 1.0.0__tar.gz → 1.0.2__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.
Potentially problematic release.
This version of das-cli might be problematic. Click here for more details.
- {das_cli-1.0.0/das_cli.egg-info → das_cli-1.0.2}/PKG-INFO +1 -1
- {das_cli-1.0.0 → das_cli-1.0.2}/das/cli.py +40 -0
- {das_cli-1.0.0 → das_cli-1.0.2}/das/managers/entries_manager.py +23 -0
- {das_cli-1.0.0 → das_cli-1.0.2}/das/services/entries.py +26 -0
- das_cli-1.0.2/das/services/users.py +25 -0
- {das_cli-1.0.0 → das_cli-1.0.2/das_cli.egg-info}/PKG-INFO +1 -1
- {das_cli-1.0.0 → das_cli-1.0.2}/das_cli.egg-info/SOURCES.txt +1 -0
- {das_cli-1.0.0 → das_cli-1.0.2}/pyproject.toml +3 -3
- {das_cli-1.0.0 → das_cli-1.0.2}/LICENSE +0 -0
- {das_cli-1.0.0 → das_cli-1.0.2}/MANIFEST.in +0 -0
- {das_cli-1.0.0 → das_cli-1.0.2}/README.md +0 -0
- {das_cli-1.0.0 → das_cli-1.0.2}/das/__init__.py +0 -0
- {das_cli-1.0.0 → das_cli-1.0.2}/das/ai/plugins/dasai.py +0 -0
- {das_cli-1.0.0 → das_cli-1.0.2}/das/ai/plugins/entries/entries_plugin.py +0 -0
- {das_cli-1.0.0 → das_cli-1.0.2}/das/app.py +0 -0
- {das_cli-1.0.0 → das_cli-1.0.2}/das/authentication/auth.py +0 -0
- {das_cli-1.0.0 → das_cli-1.0.2}/das/authentication/secure_input.py +0 -0
- {das_cli-1.0.0 → das_cli-1.0.2}/das/common/api.py +0 -0
- {das_cli-1.0.0 → das_cli-1.0.2}/das/common/config.py +0 -0
- {das_cli-1.0.0 → das_cli-1.0.2}/das/common/entry_fields_constants.py +0 -0
- {das_cli-1.0.0 → das_cli-1.0.2}/das/common/enums.py +0 -0
- {das_cli-1.0.0 → das_cli-1.0.2}/das/common/file_utils.py +0 -0
- {das_cli-1.0.0 → das_cli-1.0.2}/das/managers/__init__.py +0 -0
- {das_cli-1.0.0 → das_cli-1.0.2}/das/managers/download_manager.py +0 -0
- {das_cli-1.0.0 → das_cli-1.0.2}/das/managers/search_manager.py +0 -0
- {das_cli-1.0.0 → das_cli-1.0.2}/das/services/attributes.py +0 -0
- {das_cli-1.0.0 → das_cli-1.0.2}/das/services/cache.py +0 -0
- {das_cli-1.0.0 → das_cli-1.0.2}/das/services/downloads.py +0 -0
- {das_cli-1.0.0 → das_cli-1.0.2}/das/services/entry_fields.py +0 -0
- {das_cli-1.0.0 → das_cli-1.0.2}/das/services/hangfire.py +0 -0
- {das_cli-1.0.0 → das_cli-1.0.2}/das/services/search.py +0 -0
- {das_cli-1.0.0 → das_cli-1.0.2}/das_cli.egg-info/dependency_links.txt +0 -0
- {das_cli-1.0.0 → das_cli-1.0.2}/das_cli.egg-info/entry_points.txt +0 -0
- {das_cli-1.0.0 → das_cli-1.0.2}/das_cli.egg-info/requires.txt +0 -0
- {das_cli-1.0.0 → das_cli-1.0.2}/das_cli.egg-info/top_level.txt +0 -0
- {das_cli-1.0.0 → das_cli-1.0.2}/setup.cfg +0 -0
- {das_cli-1.0.0 → das_cli-1.0.2}/tests/__init__.py +0 -0
- {das_cli-1.0.0 → das_cli-1.0.2}/tests/attributes_test.py +0 -0
- {das_cli-1.0.0 → das_cli-1.0.2}/tests/download_manager_test.py +0 -0
- {das_cli-1.0.0 → das_cli-1.0.2}/tests/entries_manager_test.py +0 -0
- {das_cli-1.0.0 → das_cli-1.0.2}/tests/entries_service_test.py +0 -0
- {das_cli-1.0.0 → das_cli-1.0.2}/tests/entries_test.py +0 -0
- {das_cli-1.0.0 → das_cli-1.0.2}/tests/file_utils_test.py +0 -0
- {das_cli-1.0.0 → das_cli-1.0.2}/tests/run_tests.py +0 -0
- {das_cli-1.0.0 → das_cli-1.0.2}/tests/search_manager_test.py +0 -0
|
@@ -221,6 +221,8 @@ def search_entries(das_ctx, attribute, query, max_results, page, sort_by, sort_o
|
|
|
221
221
|
def get_entry(das_ctx, entry_id, output_format):
|
|
222
222
|
"""Get detailed information about a single entry by ID"""
|
|
223
223
|
try:
|
|
224
|
+
# Ensure client and entry_manager are initialized
|
|
225
|
+
das_ctx.get_client()
|
|
224
226
|
# Reusing the entry manager to get entry details by ID
|
|
225
227
|
entry = das_ctx.entry_manager.get_entry(entry_id)
|
|
226
228
|
|
|
@@ -318,6 +320,8 @@ def update_entry(das_ctx, attribute, code=None, file_path=None, data=None):
|
|
|
318
320
|
das entry update --attribute core --data [{ 'Code': 'ENT001', ... }, { 'Code': 'ENT002', ... }]
|
|
319
321
|
"""
|
|
320
322
|
try:
|
|
323
|
+
# Ensure client and entry_manager are initialized
|
|
324
|
+
das_ctx.get_client()
|
|
321
325
|
if not file_path and not data:
|
|
322
326
|
raise click.UsageError("Please provide either a file path or data string")
|
|
323
327
|
|
|
@@ -437,6 +441,8 @@ def create_entry(das_ctx, attribute, file_path=None, data=None):
|
|
|
437
441
|
das entry create --attribute core --data [{ 'Name': 'Entry 1', ... }, { 'Name': 'Entry 2', ... }]
|
|
438
442
|
"""
|
|
439
443
|
try:
|
|
444
|
+
# Ensure client and entry_manager are initialized
|
|
445
|
+
das_ctx.get_client()
|
|
440
446
|
if not file_path and not data:
|
|
441
447
|
raise click.UsageError("Please provide either a file path or data string")
|
|
442
448
|
|
|
@@ -514,6 +520,8 @@ def get_entry(das_ctx, code=None, id=None):
|
|
|
514
520
|
raise click.UsageError("Please provide either an entry code or ID")
|
|
515
521
|
|
|
516
522
|
try:
|
|
523
|
+
# Ensure client and entry_manager are initialized
|
|
524
|
+
das_ctx.get_client()
|
|
517
525
|
# Pass client as a named parameter to avoid conflicts with 'id' parameter
|
|
518
526
|
entry = das_ctx.entry_manager.get(code=code, id=id)
|
|
519
527
|
if entry:
|
|
@@ -549,6 +557,38 @@ def get_entry(das_ctx, code=None, id=None):
|
|
|
549
557
|
except Exception as e:
|
|
550
558
|
click.secho(f"Error: {e}", fg="red")
|
|
551
559
|
|
|
560
|
+
@entry.command("chown")
|
|
561
|
+
@click.option('--user', 'user_name', required=True, help='New owner username')
|
|
562
|
+
@click.option('--code', '-c', multiple=True, required=True, help='Entry code to transfer. Can be used multiple times.')
|
|
563
|
+
@pass_das_context
|
|
564
|
+
def chown_entries(das_ctx, user_name, code):
|
|
565
|
+
"""Change ownership of one or more entries by their codes.
|
|
566
|
+
|
|
567
|
+
Example:
|
|
568
|
+
|
|
569
|
+
\b
|
|
570
|
+
das entry chown --user alice --code ENT001 --code ENT002
|
|
571
|
+
"""
|
|
572
|
+
try:
|
|
573
|
+
# Ensure services are initialized
|
|
574
|
+
das_ctx.get_client()
|
|
575
|
+
|
|
576
|
+
entry_codes = list(code)
|
|
577
|
+
if not entry_codes:
|
|
578
|
+
raise click.UsageError("Please provide at least one --code")
|
|
579
|
+
|
|
580
|
+
result = das_ctx.entry_manager.chown(user_name=user_name, entry_code_list=entry_codes)
|
|
581
|
+
|
|
582
|
+
# If API returns a plain success or list, just report success
|
|
583
|
+
click.secho("✓ Ownership updated successfully!", fg="green")
|
|
584
|
+
if isinstance(result, dict):
|
|
585
|
+
# Show minimal feedback if available
|
|
586
|
+
updated = result.get('updated') or result.get('result') or result
|
|
587
|
+
if updated:
|
|
588
|
+
click.echo(json.dumps(updated, indent=2))
|
|
589
|
+
except Exception as e:
|
|
590
|
+
click.secho(f"Error: {e}", fg="red")
|
|
591
|
+
|
|
552
592
|
# Attribute commands group
|
|
553
593
|
@cli.group()
|
|
554
594
|
def attribute():
|
|
@@ -6,6 +6,7 @@ from das.services.entry_fields import EntryFieldsService
|
|
|
6
6
|
from das.services.entries import EntriesService
|
|
7
7
|
from das.common.entry_fields_constants import DIGITAL_OBJECT_INPUT, SELECT_COMBO_INPUT
|
|
8
8
|
from das.services.search import SearchService
|
|
9
|
+
from das.services.users import UsersService
|
|
9
10
|
|
|
10
11
|
|
|
11
12
|
class EntryManager:
|
|
@@ -20,6 +21,7 @@ class EntryManager:
|
|
|
20
21
|
self.entry_fields_service = EntryFieldsService(base_url)
|
|
21
22
|
self.search_service = SearchService(base_url)
|
|
22
23
|
self.attribute_service = AttributesService(base_url)
|
|
24
|
+
self.user_service = UsersService(base_url)
|
|
23
25
|
|
|
24
26
|
def get_entry(self, entry_id: str):
|
|
25
27
|
"""Get entry details by ID"""
|
|
@@ -425,6 +427,27 @@ class EntryManager:
|
|
|
425
427
|
else:
|
|
426
428
|
raise ValueError("Unsupported file type. Supported types are: .json, .csv, .xlsx")
|
|
427
429
|
|
|
430
|
+
def chown(self, user_name: str, entry_code_list: list[str]):
|
|
431
|
+
|
|
432
|
+
user = self.user_service.get_user(user_name)
|
|
433
|
+
|
|
434
|
+
if user is None:
|
|
435
|
+
raise ValueError(f"User '{user_name}' not found")
|
|
436
|
+
|
|
437
|
+
if not entry_code_list:
|
|
438
|
+
raise ValueError("Entry code list is required")
|
|
439
|
+
|
|
440
|
+
entry_list_ids = []
|
|
441
|
+
|
|
442
|
+
for entry_code in entry_code_list:
|
|
443
|
+
entry = self.get(code=entry_code)
|
|
444
|
+
entry_list_ids.append(entry.get('ID') if entry.get('ID') else entry.get('id'))
|
|
445
|
+
|
|
446
|
+
if not entry_list_ids:
|
|
447
|
+
raise ValueError("Entry list IDs is empty")
|
|
448
|
+
|
|
449
|
+
return self.entry_service.chown(new_user_id=user.get('id'), entry_list_ids=entry_list_ids)
|
|
450
|
+
|
|
428
451
|
if __name__ == "__main__":
|
|
429
452
|
manager = EntryManager()
|
|
430
453
|
entry = manager.get(id="8d2841c9-e307-4971-bd2b-70da0d7a7534")
|
|
@@ -130,3 +130,29 @@ class EntriesService():
|
|
|
130
130
|
else:
|
|
131
131
|
raise ValueError(response.get('error'))
|
|
132
132
|
|
|
133
|
+
def chown(self, new_user_id: int, entry_list_ids: list[str]):
|
|
134
|
+
"""Change the owner of a list of entries."""
|
|
135
|
+
token = load_token()
|
|
136
|
+
|
|
137
|
+
if (token is None or token == ""):
|
|
138
|
+
raise ValueError("Authorization token is required")
|
|
139
|
+
|
|
140
|
+
headers = {
|
|
141
|
+
"Authorization": f"Bearer {token}",
|
|
142
|
+
"Content-Type": "application/json"
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
url = f"{self.base_url}/ChangeOwner"
|
|
146
|
+
|
|
147
|
+
payload = {
|
|
148
|
+
"newOwnerId": new_user_id,
|
|
149
|
+
"entryIdList": entry_list_ids
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
response = post_data(url, data=payload, headers=headers)
|
|
153
|
+
|
|
154
|
+
if response.get('success') == True:
|
|
155
|
+
return response.get('result')
|
|
156
|
+
else:
|
|
157
|
+
raise ValueError(response.get('error'))
|
|
158
|
+
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
from das.common.api import delete_data, get_data, post_data, put_data
|
|
2
|
+
from das.common.config import load_token
|
|
3
|
+
|
|
4
|
+
class UsersService:
|
|
5
|
+
def __init__(self, base_url):
|
|
6
|
+
self.base_url = f"{base_url}/api/services/app/User"
|
|
7
|
+
|
|
8
|
+
def get_user(self, user_name: str):
|
|
9
|
+
token = load_token()
|
|
10
|
+
|
|
11
|
+
if (token is None or token == ""):
|
|
12
|
+
raise ValueError("Authorization token is required")
|
|
13
|
+
|
|
14
|
+
headers = {
|
|
15
|
+
"Authorization": f"Bearer {token}"
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
url = f"{self.base_url}/GetUsers?filter={user_name}"
|
|
19
|
+
|
|
20
|
+
response = get_data(url, headers=headers)
|
|
21
|
+
|
|
22
|
+
if response.get('success') == True:
|
|
23
|
+
return response.get('result').get('items')[0]
|
|
24
|
+
else:
|
|
25
|
+
raise ValueError(response.get('error'))
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
[build-system]
|
|
2
|
-
requires = ["setuptools>=
|
|
2
|
+
requires = ["setuptools>=77.0.0", "wheel"]
|
|
3
3
|
build-backend = "setuptools.build_meta"
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "das-cli"
|
|
7
|
-
version = "1.0.
|
|
7
|
+
version = "1.0.2"
|
|
8
8
|
authors = [
|
|
9
9
|
{ name="Royal Netherlands Institute for Sea Research" },
|
|
10
10
|
]
|
|
@@ -16,6 +16,7 @@ classifiers = [
|
|
|
16
16
|
"Operating System :: OS Independent",
|
|
17
17
|
]
|
|
18
18
|
license = "MIT"
|
|
19
|
+
license-files = ["LICENSE"]
|
|
19
20
|
|
|
20
21
|
dependencies = [
|
|
21
22
|
"click>=8.2.1",
|
|
@@ -36,7 +37,6 @@ ai = ["semantic-kernel>=1.37.0"]
|
|
|
36
37
|
|
|
37
38
|
[tool.setuptools]
|
|
38
39
|
include-package-data = true
|
|
39
|
-
license-files = ["LICENSE"]
|
|
40
40
|
|
|
41
41
|
[tool.setuptools.packages.find]
|
|
42
42
|
include = ["das*"]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|