Skip to content

Commit 82fcbcc

Browse files
committed
enh: add tool button for creating a collection in the My Data tab (close #93)
1 parent ad764f5 commit 82fcbcc

3 files changed

Lines changed: 73 additions & 34 deletions

File tree

CHANGELOG

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
- fix: cache download resource file size
77
- fix: action button behavior in downloads panel (#94)
88
- fix: action button behavior in uploads panel
9+
- enh: add tool button for creating a collection in the "My Data" tab (#93)
910
- enh: unify action button size, alignment, and spacing across all tabs
1011
- enh: allow sharing individual datasets instead of collections (#32)
1112
- enh: add preview option for dataset description in upload dialog (#52)

dcoraid/api/ckan_api.py

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import logging
77
import numbers
88
import pathlib
9+
import random
910
import traceback
1011
import urllib.parse
1112

@@ -441,20 +442,39 @@ def post(self, api_call, data, dump_json=True, headers=None,
441442

442443
def require_collection(self,
443444
name: str,
444-
title: str = None):
445+
title: str = None,
446+
exist_ok: bool = True,
447+
):
445448
"""Return a collection dict with the given name and optional title
446449
447-
The collection is created if it does not exist already. If the
448-
collection already exists, `title` is ignored.
450+
If a collection by that name already exists, it is returned only
451+
if `exist_ok` is True (in which case `title` is ignored). Otherwise,
452+
a new collection with a modified `name` is created and returned.
449453
"""
450-
# check whether the group exists
451454
try:
452455
col_dict = self.get("group_show", id=name)
453456
except APINotFoundError:
454-
# Create non-existent group
455-
self.post("group_create",
456-
data={"name": name,
457-
"title": title or name,
458-
})
459-
col_dict = self.get("group_show", id=name)
457+
col_dict = None
458+
459+
if exist_ok and col_dict is not None:
460+
return col_dict
461+
else:
462+
rand = ""
463+
title = (title or name).strip()
464+
# create the collection
465+
for ii in range(10):
466+
try:
467+
col_dict = self.post("group_create",
468+
{"title": title,
469+
"name": name + rand,
470+
})
471+
except APIConflictError:
472+
if not rand:
473+
rand += "-"
474+
rand += random.choice("abcdefghijkmpqrstuvwxyz0123456789")
475+
else:
476+
break
477+
else:
478+
raise ValueError("Could not create collection")
479+
460480
return col_dict

dcoraid/gui/panel_my_data/filter_chain_my_data.py

Lines changed: 42 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
1-
import random
2-
31
from PyQt6 import QtCore, QtWidgets
42

5-
from ...api import errors
6-
73
from ..dbview import FilterChain
84
from ..tools import ShowWaitCursor
95
from ..api import get_ckan_api
@@ -20,7 +16,14 @@ def __init__(self, *args, **kwargs):
2016
"""Filter chain with user-related features"""
2117
super(FilterChainMyData, self).__init__(*args, **kwargs)
2218

23-
# Enable the "add to collection tool box"
19+
# Enable "create collection" toolbutton
20+
self.fw_collections.pushButton_custom.setText(
21+
"Create new collection...")
22+
self.fw_collections.pushButton_custom.setVisible(True)
23+
self.fw_collections.pushButton_custom.clicked.connect(
24+
self.on_create_collection)
25+
26+
# Enable the "add to collection" toolbutton
2427
self.fw_datasets.pushButton_custom.setText(
2528
"Add selected datasets to a collection...")
2629
self.fw_datasets.pushButton_custom.setVisible(True)
@@ -42,8 +45,6 @@ def choose_collaborator(self, what_for=None):
4245
# Fetch a list of users
4346
with ShowWaitCursor():
4447
api = get_ckan_api()
45-
# TODO: let the user search for collaborators and add them to a
46-
# memoized list.
4748
users = api.get("user_autocomplete", q="", limit=100)
4849

4950
for_what_for = f" for {what_for}"
@@ -93,7 +94,8 @@ def on_add_datasets_to_collection(self):
9394
"Select a collection",
9495
f"Please choose a collection for "
9596
f"{len(dataset_ids)} datasets.",
96-
[f"{i}: {g['display_name']}" for i, g in enumerate(grps)],
97+
[f"{i}: {g['display_name']} ({g['name']})"
98+
for i, g in enumerate(grps)],
9799
0, # current index
98100
False, # editable
99101
)
@@ -106,22 +108,15 @@ def on_add_datasets_to_collection(self):
106108
"Create a collection",
107109
"Type the name of a collection to create",
108110
)
109-
# create a valid name
110-
name = "".join(
111-
[c.lower() if c.isalnum() else "-" for c in text])
112-
name = name.strip("-")
113-
for ii in range(10):
114-
try:
115-
collection = api.post("group_create",
116-
{"title": text.strip(),
117-
"name": name,
118-
})
119-
except errors.APIConflictError:
120-
name = name + random.choice("abcdefghijkm0123456789")
121-
else:
122-
break
123-
else:
124-
raise ValueError("Could not create collection")
111+
if ok:
112+
# create a valid name
113+
name = "".join(
114+
[c.lower() if c.isalnum() else "-" for c in text])
115+
name = name.strip("-")
116+
# create the collection
117+
collection = api.require_collection(name=name,
118+
title=text,
119+
exist_ok=False)
125120
if ok:
126121
with ShowWaitCursor():
127122
# add all datasets to that collection
@@ -137,6 +132,29 @@ def on_add_datasets_to_collection(self):
137132
self.added_datasets_to_collection.emit(collection,
138133
dataset_ids)
139134

135+
@QtCore.pyqtSlot()
136+
def on_create_collection(self):
137+
text, ok = QtWidgets.QInputDialog.getText(
138+
self,
139+
"Create a collection",
140+
"Type the name of a collection to create",
141+
)
142+
if ok:
143+
api = get_ckan_api()
144+
# create a valid name
145+
name = "".join(
146+
[c.lower() if c.isalnum() else "-" for c in text])
147+
name = name.strip("-")
148+
collection = api.require_collection(name=name,
149+
title=text,
150+
exist_ok=False)
151+
QtWidgets.QMessageBox.information(
152+
self,
153+
"Collection created",
154+
f"You may now add datasets to "
155+
f"collection '{collection['name']}'.",
156+
)
157+
140158
@QtCore.pyqtSlot(str, str)
141159
def on_remove_item(self, id_type, identifier):
142160
"""Remove a dataset from a collection"""

0 commit comments

Comments
 (0)