Skip to content
Snippets Groups Projects
Commit aed808e6 authored by Romin's avatar Romin :eye:
Browse files

Switched to isodate and support new type timedelta

parent 2d2abf14
No related branches found
No related tags found
No related merge requests found
......@@ -46,8 +46,8 @@ setuptools.setup(
keywords=["Coscine", "RWTH Aachen", "Research Data Management"],
install_requires=[
"boto3",
"isodate",
"pyshacl",
"python-dateutil",
"rdflib",
"requests",
"requests-cache",
......
......@@ -10,7 +10,7 @@ Provides common classes shared among multiple modules.
"""
from datetime import date, datetime
from dateutil.parser import parse as dateutil_parse
from isodate import parse_datetime
class MaintenanceNotice:
......@@ -54,7 +54,7 @@ class MaintenanceNotice:
Date when the maintenance goes active.
"""
value: str = self._data.get("startsDate") or "1998-01-01"
return dateutil_parse(value).date()
return parse_datetime(value).date()
@property
def ends_date(self) -> date:
......@@ -62,7 +62,7 @@ class MaintenanceNotice:
Date when the maintenance ends.
"""
value = self._data.get("endsDate") or "1998-01-01"
return dateutil_parse(value).date()
return parse_datetime(value).date()
def __init__(self, data: dict) -> None:
self._data = data
......@@ -134,7 +134,7 @@ class ApiToken:
Timestamp of when the API token was created.
"""
value = self._data.get("creationDate") or "1998-01-01"
return dateutil_parse(value).date()
return parse_datetime(value).date()
@property
def expires(self) -> date:
......@@ -142,7 +142,7 @@ class ApiToken:
Timestamp of when the API token will expire.
"""
value = self._data.get("expiryDate") or "1998-01-01"
return dateutil_parse(value).date()
return parse_datetime(value).date()
@property
def expired(self) -> bool:
......
......@@ -11,15 +11,15 @@ Provides functions and classes around the handling of metadata.
from __future__ import annotations
from typing import TYPE_CHECKING, TypeAlias
from datetime import date, datetime, time
from datetime import date, datetime, time, timedelta
from threading import Lock
from decimal import Decimal
import random
import logging
from string import ascii_letters
from dateutil.parser import parse as dateutil_parse
from requests.compat import urlparse
from tabulate import tabulate
from isodate import parse_duration, parse_datetime, parse_date, parse_time
import rdflib
import pyshacl
from coscine.exceptions import NotFoundError
......@@ -33,7 +33,7 @@ logger = logging.getLogger(__name__)
# Type Alias according to PEP 613 for supported metadata value types
FormType: TypeAlias = (
bool | date | datetime | Decimal | int | float | str | time
bool | date | datetime | Decimal | int | float | str | time | timedelta
)
# XML Schema datatype to Python native type lookup table
......@@ -60,7 +60,7 @@ XSD_TYPES: dict[str, type] = {
"boolean": bool,
"date": date,
"dateTime": datetime,
"duration": datetime,
"duration": timedelta,
"gDay": datetime,
"gMonth": datetime,
"gMonthDay": datetime,
......@@ -545,11 +545,13 @@ class FormField:
if self.has_vocabulary:
return self.vocabulary.resolve(value)
if self.datatype == datetime:
return dateutil_parse(value)
return parse_datetime(value)
if self.datatype == date:
return dateutil_parse(value).date()
return parse_date(value)
if self.datatype == time:
return dateutil_parse(value).time()
return parse_time(value)
if self.datatype == timedelta:
return parse_duration(value)
if self.datatype == int:
return int(value)
if self.datatype == float:
......@@ -1053,6 +1055,7 @@ class MetadataForm:
datetime: datetime.now(),
date: datetime.now().date(),
time: datetime.now().time(),
timedelta: timedelta(2),
int: random.randint(1, 16),
float: random.random() * 123.0,
Decimal: Decimal(random.randint(1, 42)),
......
......@@ -15,7 +15,7 @@ from os.path import isdir
from posixpath import join as join_paths
from datetime import date
from textwrap import wrap
from dateutil.parser import parse as dateutil_parse
from isodate import parse_datetime, parse_date
from tabulate import tabulate
from coscine.common import (
Discipline,
......@@ -201,7 +201,7 @@ class ProjectInvitation:
Timestamp of when the invitation expires.
"""
value = self._data.get("expirationDate") or ""
return dateutil_parse(value).date()
return parse_date(value)
@property
def email(self) -> str:
......@@ -305,7 +305,7 @@ class Project:
Start of project lifecycle timestamp.
"""
value = self._data.get("startDate") or "1998-01-01"
return dateutil_parse(value).date()
return parse_date(value)
@start_date.setter
def start_date(self, value: date) -> None:
......@@ -317,7 +317,7 @@ class Project:
End of project lifecycle timestamp.
"""
value = self._data.get("endDate") or "1998-01-01"
return dateutil_parse(value).date()
return parse_date(value)
@end_date.setter
def end_date(self, value: date) -> None:
......@@ -379,7 +379,7 @@ class Project:
or missing.
"""
value = self._data.get("creationDate") or "1998-01-01"
return dateutil_parse(value).date()
return parse_date(value)
@property
def organizations(self) -> list[Organization]:
......@@ -431,7 +431,9 @@ class Project:
("Name", self.name),
("Display Name", self.display_name),
("Description", "\n".join(wrap(self.description))),
("Principal Investigators", self.principal_investigators),
("Principal Investigators", "\n".join(
wrap(self.principal_investigators)
)),
("Disciplines", "\n".join([str(it) for it in self.disciplines])),
("Organizations", "\n".join(
[str(it) for it in self.organizations]
......
......@@ -19,7 +19,7 @@ from posixpath import join as join_paths
import logging
from textwrap import wrap
from urllib.parse import urlparse, parse_qs
from dateutil.parser import parse as dateutil_parse
from isodate import parse_datetime, parse_date
from requests_toolbelt import MultipartEncoder, MultipartEncoderMonitor
from tabulate import tabulate
from tqdm import tqdm
......@@ -371,7 +371,7 @@ class Resource:
Timestamp of when the resource was created.
"""
value = self._data.get("dateCreated") or "1998-01-01"
return dateutil_parse(value).date()
return parse_date(value)
@property
def creator(self) -> str:
......@@ -970,7 +970,7 @@ class FileObject:
Timestamp of when the file has been uploaded.
"""
value = self._data.get("creationDate") or "1998-01-01"
return dateutil_parse(value).date()
return parse_date(value)
@property
def modified(self) -> date:
......@@ -978,7 +978,7 @@ class FileObject:
Timestamp of when the file was recently modified.
"""
value = self._data.get("changeDate") or "1998-01-01"
return dateutil_parse(value).date()
return parse_date(value)
@property
def is_folder(self) -> bool:
......@@ -1039,23 +1039,23 @@ class FileObject:
)
self.client.delete(uri)
def metadata(self) -> FileMetadata | None:
def metadata(self, refresh: bool = True) -> FileMetadata | None:
"""
Returns the metadata of the file. This might use a cached version
of file metadata or make a request, if no cached version is available.
"""
if not self._metadata:
if (not self._metadata) and refresh:
data = self.resource.metadata(path=self.path)
self.assign_metadata(data)
return self._metadata
def metadata_form(self) -> MetadataForm:
def metadata_form(self, refresh: bool = True) -> MetadataForm:
"""
Returns the metadata of the file or an empty metadata form if
no metadata has been attached to the file.
"""
form = MetadataForm(self.resource)
metadata = self.metadata()
metadata = self.metadata(refresh=refresh)
if metadata:
form.parse(metadata)
return form
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment