Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .readthedocs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,3 @@ python:
install:

- requirements: docs/requirements.txt

5 changes: 2 additions & 3 deletions backend/app/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from app.models.folder_and_file import FolderFileViewList
from app.models.folders import FolderDB, FolderDBViewList
from app.models.groups import GroupDB
from app.models.licenses import LicenseDB
from app.models.listeners import (
EventListenerDB,
EventListenerJobDB,
Expand All @@ -36,6 +37,7 @@
groups,
jobs,
keycloak,
licenses,
listeners,
metadata,
metadata_datasets,
Expand All @@ -48,7 +50,6 @@
public_visualization,
status,
thumbnails,
licenses,
users,
visualization,
)
Expand All @@ -63,8 +64,6 @@
from motor.motor_asyncio import AsyncIOMotorClient
from pydantic import BaseConfig

from app.models.licenses import LicenseDB

logger = logging.getLogger(__name__)

app = FastAPI(
Expand Down
8 changes: 3 additions & 5 deletions backend/app/models/licenses.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
from datetime import datetime
from typing import List, Optional

from beanie import Document, PydanticObjectId
from pydantic import BaseModel, Field
from typing import Optional

from app.models.authorization import Provenance
from app.models.users import UserOut
from beanie import Document
from pydantic import BaseModel


class LicenseBase(BaseModel):
Expand Down
59 changes: 10 additions & 49 deletions backend/app/routers/datasets.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,15 @@
FolderOut,
FolderPatch,
)
from app.models.licenses import standard_licenses
from app.models.metadata import MetadataDB
from app.models.pages import Paged, _construct_page_metadata, _get_page_query
from app.models.thumbnails import ThumbnailDB
from app.models.users import UserOut
from app.rabbitmq.listeners import submit_dataset_job
from app.routers.authentication import get_admin, get_admin_mode
from app.routers.files import add_file_entry, add_local_file_entry, remove_file_entry
from app.routers.licenses import delete_license
from app.search.connect import delete_document_by_id
from app.search.index import index_dataset, index_file
from beanie import PydanticObjectId
Expand All @@ -53,53 +55,6 @@
from rocrate.model.person import Person
from rocrate.rocrate import ROCrate

from app import dependencies
from app.config import settings
from app.deps.authorization_deps import Authorization, CheckStatus
from app.keycloak_auth import (
get_token,
get_user,
get_current_user,
)
from app.models.authorization import AuthorizationDB, RoleType
from app.models.datasets import (
DatasetBase,
DatasetIn,
DatasetDB,
DatasetOut,
DatasetPatch,
DatasetDBViewList,
DatasetStatus,
)
from app.models.files import (
FileOut,
FileDB,
FileDBViewList,
LocalFileIn,
StorageType,
)
from app.models.folder_and_file import FolderFileViewList
from app.models.folders import (
FolderOut,
FolderIn,
FolderDB,
FolderDBViewList,
FolderPatch,
)
from app.models.metadata import MetadataDB
from app.models.pages import Paged, _get_page_query, _construct_page_metadata
from app.models.thumbnails import ThumbnailDB
from app.models.users import UserOut
from app.rabbitmq.listeners import submit_dataset_job
from app.routers.authentication import get_admin
from app.routers.authentication import get_admin_mode
from app.routers.files import add_file_entry, remove_file_entry, add_local_file_entry
from app.search.connect import (
delete_document_by_id,
)
from app.search.index import index_dataset, index_file
from app.models.licenses import standard_licenses

router = APIRouter()
security = HTTPBearer()

Expand Down Expand Up @@ -452,8 +407,14 @@ async def delete_dataset(
await AuthorizationDB.find(
AuthorizationDB.dataset_id == PydanticObjectId(dataset_id)
).delete()

# don't delete standard license
standard_license_ids = [license.id for license in standard_licenses]
if dataset.license_id not in standard_license_ids:
await delete_license(dataset.license_id)

return {"deleted": dataset_id}
await delete_license(dataset.license_id)

raise HTTPException(status_code=404, detail=f"Dataset {dataset_id} not found")


Expand Down Expand Up @@ -490,7 +451,7 @@ async def get_dataset_folders(
limit: int = 10,
allow: bool = Depends(Authorization("viewer")),
):
if (dataset_db := await DatasetDB.get(PydanticObjectId(dataset_id))) is not None:
if (await DatasetDB.get(PydanticObjectId(dataset_id))) is not None:
if authenticated or public:
query = [
FolderDBViewList.dataset_id == ObjectId(dataset_id),
Expand Down
19 changes: 10 additions & 9 deletions backend/app/routers/licenses.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
from datetime import datetime
from typing import List

from beanie import PydanticObjectId
from fastapi import HTTPException, Depends, APIRouter

from app.keycloak_auth import get_current_user, get_user

from app.models.licenses import LicenseOut, LicenseIn, LicenseDB, LicenseBase
from app.models.licenses import (
LicenseBase,
LicenseDB,
LicenseIn,
LicenseOption,
LicenseOut,
standard_licenses,
)
from app.routers.authentication import get_admin, get_admin_mode

from app.models.licenses import LicenseOption

from app.models.licenses import standard_licenses
from beanie import PydanticObjectId
from fastapi import APIRouter, Depends, HTTPException

router = APIRouter()

Expand Down
15 changes: 14 additions & 1 deletion backend/app/tests/test_datasets.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import os

from app.config import settings
from app.tests.utils import create_dataset, generate_png, user_alt
from app.tests.utils import (
create_dataset,
create_dataset_with_custom_license,
generate_png,
user_alt,
)
from fastapi.testclient import TestClient


Expand All @@ -26,6 +31,14 @@ def test_delete(client: TestClient, headers: dict):
assert response.status_code == 200


def test_delete_with_custom_license(client: TestClient, headers: dict):
dataset_id = create_dataset_with_custom_license(client, headers).get("id")
response = client.delete(
f"{settings.API_V2_STR}/datasets/{dataset_id}", headers=headers
)
assert response.status_code == 200


def test_delete_with_metadata(client: TestClient, headers: dict):
dataset_id = create_dataset(client, headers).get("id")
response = client.post(
Expand Down
9 changes: 1 addition & 8 deletions backend/app/tests/test_license.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,5 @@
from fastapi.testclient import TestClient

from app.config import settings
from app.tests.utils import (
create_dataset,
create_user,
user_example,
)

from fastapi.testclient import TestClient

license_example = {
"name": "test license",
Expand Down
26 changes: 26 additions & 0 deletions backend/app/tests/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,13 @@
"description": "a dataset is a container of files and metadata",
}

license_example = {
"name": "test license",
"description": "test description",
"url": "test url",
"holders": " test holders",
}

filename_example_1 = "test_upload1.csv"
file_content_example_1 = "year,location,count\n2023,Atlanta,4"

Expand Down Expand Up @@ -150,6 +157,25 @@ def create_dataset(client: TestClient, headers: dict):
return response.json()


def create_dataset_with_custom_license(client: TestClient, headers: dict):
"""Creates a test dataset and returns the JSON."""
# create
response = client.post(
f"{settings.API_V2_STR}/licenses/[email protected]",
headers=headers,
json=license_example,
)
license_id = response.json().get("id")
response = client.post(
f"{settings.API_V2_STR}/datasets/?license_id={license_id}",
headers=headers,
json=dataset_example,
)
assert response.status_code == 200
assert response.json().get("id") is not None
return response.json()


def upload_file(
client: TestClient,
headers: dict,
Expand Down
1 change: 0 additions & 1 deletion docs/docs/about.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,3 @@ accessible and easy to maintain code base for contributors.
We are always looking for new collaborators, contributors, and ideas in the space of research data management. If you
are interested in contributing to Clowder v2 please come say hi in [Slack](https://join.slack.com/t/clowder-software/shared_invite/enQtMzQzOTg0Nzk3OTUzLTYwZDlkZDI0NGI4YmI0ZjE5MTZiYmZhZTIyNWE1YzM0NWMwMzIxODNhZTA1Y2E3MTQzOTg1YThiNzkwOWQwYWE). If you are ready to dive into the code, take
a look at [first time issues](https://github.com/clowder-framework/clowder2/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22) in v2.

2 changes: 1 addition & 1 deletion docs/docs/stylesheets/extra.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
--md-primary-fg-color: #1c427d;
--md-primary-fg-color--light: #1c427d;
--md-primary-fg-color--dark: #1c427d;
}
}
2 changes: 1 addition & 1 deletion docs/docs/users/index.md
Original file line number Diff line number Diff line change
@@ -1 +1 @@
# ⚠ Under construction ⚠
# ⚠ Under construction ⚠
2 changes: 1 addition & 1 deletion docs/requirements.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
mkdocs-material
mkdocs-material
63 changes: 43 additions & 20 deletions frontend/src/actions/dataset.js
Original file line number Diff line number Diff line change
Expand Up @@ -205,13 +205,14 @@ export const RECEIVE_DATASET_LICENSE = "RECEIVE_DATASET_LICENSE";

export function fetchDatasetLicense(license_id) {
return (dispatch) => {
return V2.LicensesService.getLicenseApiV2LicensesLicenseIdGet(license_id).then((json) => {
dispatch({
type: RECEIVE_DATASET_LICENSE,
license: json,
receivedAt: Date.now(),
});
})
return V2.LicensesService.getLicenseApiV2LicensesLicenseIdGet(license_id)
.then((json) => {
dispatch({
type: RECEIVE_DATASET_LICENSE,
license: json,
receivedAt: Date.now(),
});
})
.catch((reason) => {
dispatch(handleErrors(reason, fetchDatasetLicense(license_id)));
});
Expand All @@ -222,15 +223,21 @@ export const UPDATE_DATASET_LICENSE = "UPDATE_DATASET_LICENSE";

export function updateDatasetLicense(licenseId, formData) {
return (dispatch) => {
return V2.LicensesService.editLicenseApiV2LicensesLicenseIdPut(licenseId, formData).then((json) => {
dispatch({
type: UPDATE_DATASET_LICENSE,
license: json,
receivedAt: Date.now(),
});
})
return V2.LicensesService.editLicenseApiV2LicensesLicenseIdPut(
licenseId,
formData
)
.then((json) => {
dispatch({
type: UPDATE_DATASET_LICENSE,
license: json,
receivedAt: Date.now(),
});
})
.catch((reason) => {
dispatch(handleErrors(reason, updateDatasetLicense(licenseId, formData)));
dispatch(
handleErrors(reason, updateDatasetLicense(licenseId, formData))
);
});
};
}
Expand Down Expand Up @@ -264,7 +271,10 @@ export function datasetCreated(formData, licenseId, licenseFormData) {
.then((license) => {
licenseId = license.id;
// After saving the license, save the dataset
return V2.DatasetsService.saveDatasetApiV2DatasetsPost(licenseId, formData);
return V2.DatasetsService.saveDatasetApiV2DatasetsPost(
licenseId,
formData
);
})
.then((dataset) => {
dispatch({
Expand All @@ -274,11 +284,19 @@ export function datasetCreated(formData, licenseId, licenseFormData) {
});
})
.catch((reason) => {
dispatch(handleErrors(reason, datasetCreated(formData, licenseId, licenseFormData)));
dispatch(
handleErrors(
reason,
datasetCreated(formData, licenseId, licenseFormData)
)
);
});
} else {
// If licenseFormData is not present, directly save the dataset
return V2.DatasetsService.saveDatasetApiV2DatasetsPost(licenseId, formData)
return V2.DatasetsService.saveDatasetApiV2DatasetsPost(
licenseId,
formData
)
.then((dataset) => {
dispatch({
type: CREATE_DATASET,
Expand All @@ -287,7 +305,12 @@ export function datasetCreated(formData, licenseId, licenseFormData) {
});
})
.catch((reason) => {
dispatch(handleErrors(reason, datasetCreated(formData, licenseId, licenseFormData)));
dispatch(
handleErrors(
reason,
datasetCreated(formData, licenseId, licenseFormData)
)
);
});
}
};
Expand All @@ -297,7 +320,7 @@ export function licenseCreated(formData) {
try {
return V2.LicensesService.saveLicenseApiV2LicensesPost(formData);
} catch (reason) {
(handleErrors(reason, licenseCreated(formData)));
handleErrors(reason, licenseCreated(formData));
}
}

Expand Down
Loading