Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Temporal coverage with only start date #3192

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
2 changes: 1 addition & 1 deletion udata/core/dataset/api_fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@
"TemporalCoverage",
{
"start": fields.ISODateTime(description="The temporal coverage start date", required=True),
"end": fields.ISODateTime(description="The temporal coverage end date", required=True),
"end": fields.ISODateTime(description="The temporal coverage end date"),
},
)

Expand Down
15 changes: 10 additions & 5 deletions udata/core/dataset/rdf.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,8 @@ def temporal_to_rdf(daterange, graph=None):
pot = graph.resource(BNode())
pot.set(RDF.type, DCT.PeriodOfTime)
pot.set(DCAT.startDate, Literal(daterange.start))
pot.set(DCAT.endDate, Literal(daterange.end))
if daterange.end:
pot.set(DCAT.endDate, Literal(daterange.end))
return pot


Expand Down Expand Up @@ -327,18 +328,22 @@ def temporal_from_resource(resource):
g = Graph().parse(str(resource.identifier))
resource = g.resource(resource.identifier)
if resource.value(SCHEMA.startDate):
end = resource.value(SCHEMA.endDate)
return db.DateRange(
start=resource.value(SCHEMA.startDate).toPython(),
end=resource.value(SCHEMA.endDate).toPython(),
end=end.toPython() if end else None,
)
elif resource.value(DCAT.startDate):
end = resource.value(DCAT.endDate)
return db.DateRange(
start=resource.value(DCAT.startDate).toPython(),
end=resource.value(DCAT.endDate).toPython(),
end=end.toPython() if end else None,
)
elif resource.value(SCV.min):
end = resource.value(SCV.max)
return db.DateRange(
start=resource.value(SCV.min).toPython(), end=resource.value(SCV.max).toPython()
start=resource.value(SCV.min).toPython(),
end=end.toPython() if end else None,
)


Expand Down Expand Up @@ -674,7 +679,7 @@ def dataset_from_rdf(graph: Graph, dataset=None, node=None, remote_url_prefix: s

temporal_coverage = temporal_from_rdf(d.value(DCT.temporal))
if temporal_coverage:
dataset.temporal_coverage = temporal_from_rdf(d.value(DCT.temporal))
dataset.temporal_coverage = temporal_coverage

provenances = provenances_from_rdf(d)
if provenances:
Expand Down
12 changes: 9 additions & 3 deletions udata/forms/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -694,14 +694,20 @@ def process_formdata(self, valuelist):
value = valuelist[0]
if isinstance(value, str):
start, end = value.split(" - ")
if end is not None:
end = parse(end, yearfirst=True).date()
self.data = db.DateRange(
start=parse(start, yearfirst=True).date(),
end=parse(end, yearfirst=True).date(),
end=end,
)
elif "start" in value and "end" in value:
elif "start" in value:
if value.get("end", None):
end = parse(value["end"], yearfirst=True).date()
else:
end = None
self.data = db.DateRange(
start=parse(value["start"], yearfirst=True).date(),
end=parse(value["end"], yearfirst=True).date(),
end=end,
)
else:
raise validators.ValidationError(_("Unable to parse date range"))
Expand Down
21 changes: 21 additions & 0 deletions udata/tests/api/test_datasets_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -657,6 +657,27 @@ def test_dataset_api_update_deleted(self):
self.assertEqual(Dataset.objects.count(), 1)
self.assertEqual(Dataset.objects.first().description, dataset.description)

def test_update_temporal_coverage(self):
user = self.login()
dataset = DatasetFactory(owner=user)
data = dataset.to_dict()
data["temporal_coverage"] = {
"start": "2024-01-01",
"end": "2024-01-31",
}
response = self.put(url_for("api.dataset", dataset=dataset), data)
self.assert200(response)
dataset.reload()
self.assertEqual("2024-01-01", str(dataset.temporal_coverage.start))
self.assertEqual("2024-01-31", str(dataset.temporal_coverage.end))
data = dataset.to_dict()
data["temporal_coverage"] = {"start": "2024-01-01", "end": None}
response = self.put(url_for("api.dataset", dataset=dataset), data)
self.assert200(response)
dataset.reload()
self.assertEqual("2024-01-01", str(dataset.temporal_coverage.start))
self.assertIsNone(dataset.temporal_coverage.end)

def test_dataset_api_update_contact_point(self):
"""It should update a dataset from the API"""
self.login()
Expand Down
27 changes: 27 additions & 0 deletions udata/tests/dataset/test_dataset_rdf.py
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,19 @@ def test_temporal_coverage(self):
assert pot.value(DCAT.startDate).toPython() == start
assert pot.value(DCAT.endDate).toPython() == end

def test_temporal_coverage_only_start(self):
start = faker.past_date(start_date="-30d")
temporal_coverage = db.DateRange(start=start)
dataset = DatasetFactory(temporal_coverage=temporal_coverage)

d = dataset_to_rdf(dataset)

pot = d.value(DCT.temporal)

assert pot.value(RDF.type).identifier == DCT.PeriodOfTime
assert pot.value(DCAT.startDate).toPython() == start
assert pot.value(DCAT.endDate) is None

def test_from_external_repository(self):
dataset = DatasetFactory(
harvest=HarvestDatasetMetadata(
Expand Down Expand Up @@ -748,6 +761,20 @@ def test_parse_temporal_as_schema_format(self):
assert daterange.start == start
assert daterange.end == end

def test_parse_temporal_as_schema_format_only_start_date(self):
node = BNode()
g = Graph()
start = faker.past_date(start_date="-30d")

g.set((node, RDF.type, DCT.PeriodOfTime))
g.set((node, SCHEMA.startDate, Literal(start)))

daterange = temporal_from_rdf(g.resource(node))

assert isinstance(daterange, db.DateRange)
assert daterange.start == start
assert daterange.end is None

def test_parse_temporal_as_iso_interval(self):
start = faker.past_date(start_date="-30d")
end = faker.future_date(end_date="+30d")
Expand Down