Skip to content
Snippets Groups Projects
Commit 90d30342 authored by Sabine Schröder's avatar Sabine Schröder
Browse files

#17, #9: patch API produces changelog entries for 'SingleValue' and...

#17, #9: patch API produces changelog entries for 'SingleValue' and 'Comprehensive' (also additions for #7 to be found in this commit)
parent 870ac743
No related branches found
No related tags found
No related merge requests found
Pipeline #48008 passed
......@@ -16,7 +16,7 @@ from . import models
from .models import StationmetaCore, StationmetaChangelog, stationmeta_core_stationmeta_roles_table, \
stationmeta_core_stationmeta_annotations_table, \
CZ_enum, CV_enum, ST_enum, TA_enum
from toardb.generic.models import RS_enum, RC_enum
from toardb.generic.models import RS_enum, RC_enum, AK_enum, CL_enum
from .schemas import get_coordinates_from_geom, get_geom_from_coordinates, StationmetaCreate, StationmetaPatch, Coordinates
from pydantic import ValidationError
from toardb.utils.utils import get_value_from_str, get_str_from_value
......@@ -197,6 +197,15 @@ def create_stationmeta(db: Session, stationmeta: StationmetaCreate):
def patch_stationmeta(db: Session, description: str, station_id: int, stationmeta: StationmetaPatch):
stationmeta_dict = stationmeta.dict()
# delete empty fields from stationmeta_dict already at this place, to be able to
# distinguish between "single value correction in metadata" and "comprehensive metadata revision"
# (see controlled vocabulary "CL_vocabulary")
stationmeta_dict2 = {k: v for k, v in stationmeta_dict.items() if v is not None}
number_of_elements = len(stationmeta_dict2)
if (number_of_elements == 1):
type_of_change = get_value_from_str(CL_enum,"SingleValue")
else:
type_of_change = get_value_from_str(CL_enum,"Comprehensive")
roles_data = stationmeta_dict.pop('roles', None)
annotations_data = stationmeta_dict.pop('annotations', None)
aux_images_data = stationmeta_dict.pop('aux_images', None)
......@@ -207,37 +216,41 @@ def patch_stationmeta(db: Session, description: str, station_id: int, stationmet
# there's a mismatch with coordinates --> how to automatically switch back and forth?!
# ==> the following two commands are not working
# ==> workaround
# stationmeta_dict2 = {k: v for k, v in stationmeta_dict.items() if v is not None}
# db.query(models.StationmetaCore).filter(models.StationmetaCore.id == stationm_id).update(stationmeta_dict2)
db_obj = models.StationmetaCore(**stationmeta_dict)
tmp_coordinates = db_obj.coordinates
db_stationmeta = db.query(models.StationmetaCore).get(station_id)
db_stationmeta.coordinates = get_geom_from_coordinates(db_stationmeta.coordinates)
old_value="{"
number_of_commas = number_of_elements - 1
for k, v in stationmeta_dict.items():
if v is not None:
# prepare changelog entry/entries
desc = description + f"; field: {k}"
db_changelog = StationmetaChangelog(description=desc, station_id=station_id, author_id=1, type_of_change=1)
db_changelog.old_value=str(getattr(db_stationmeta,k))
# prepare changelog entry
if (number_of_commas == 0):
old_value=old_value + f"'{k}': " + str(getattr(db_stationmeta,k)) + '}'
else:
old_value=old_value + f"'{k}': " + str(getattr(db_stationmeta,k)) + ','
number_of_commas = number_of_commas - 1
setattr(db_stationmeta,k,stationmeta_dict[k])
db_changelog.new_value=str(getattr(db_stationmeta,k))
db.add(db_changelog)
result = db.commit()
db.refresh(db_stationmeta)
# store roles and update association table
if roles_data:
for r in roles_data:
# prepare changelog entry/entries
desc = description + f"; add role"
db_changelog = StationmetaChangelog(description=desc, station_id=station_id, author_id=1, type_of_change=1)
description = description + f"; add role"
db_old_roles = get_stationmeta_roles(db, station_id)
oldvalue=''
old_value = old_value + "'roles': {"
for oldr in db_old_roles:
old_role = get_stationmeta_role_by_id(db, oldr.role_id)
oldvalue=oldvalue + "{'role': '" + get_str_from_value(RC_enum,old_role.role) + \
old_value=old_value + "{'role': '" + get_str_from_value(RC_enum,old_role.role) + \
"', 'status': '" + get_str_from_value(RS_enum,old_role.status) + \
"', 'contact_id': " + str(old_role.contact_id) + '}'
db_changelog.old_value=oldvalue
if (number_of_commas == 0):
old_value=old_value + '}'
else:
old_value=old_value + ','
number_of_commas = number_of_commas - 1
for r in roles_data:
db_role = models.StationmetaRole(**r)
db_role.role = get_value_from_str(RC_enum,db_role.role)
db_role.status = get_value_from_str(RS_enum,db_role.status)
......@@ -251,11 +264,24 @@ def patch_stationmeta(db: Session, description: str, station_id: int, stationmet
db.refresh(db_role)
role_id = db_role.id
db.execute(insert(stationmeta_core_stationmeta_roles_table).values(station_id=station_id, role_id=role_id))
db_changelog.new_value=oldvalue + str(r)
db.add(db_changelog)
db.commit()
# store annotations and update association table
if annotations_data:
# prepare changelog entry/entries
description = description + f"; add annotation"
db_old_annotations = get_stationmeta_annotations(db, station_id)
for olda in db_old_annotations:
old_annotation = get_stationmeta_annotation_by_id(db, olda.annotation_id)
old_value=old_value + "{'kind': '" + get_str_from_value(RC_enum,old_role.kind) + \
"', 'text': '" + get_str_from_value(RS_enum,old_role.status) + \
"', 'date_added': '" + get_str_from_value(RS_enum,old_role.status) + \
"', 'approved': '" + get_str_from_value(RS_enum,old_role.status) + \
"', 'contributor_id': " + str(old_role.contact_id) + '}'
if (number_of_commas == 0):
old_value=old_value + '}'
else:
old_value=old_value + ','
number_of_commas = number_of_commas - 1
for a in annotations_data:
db_annotation = models.StationmetaAnnotation(**a)
# check whether annotation is already present in database
......@@ -309,6 +335,9 @@ def patch_stationmeta(db: Session, description: str, station_id: int, stationmet
db.add(db_globalservice)
db.commit()
db.refresh(db_globalservice)
db_changelog = StationmetaChangelog(description=description, station_id=station_id, author_id=1, type_of_change=type_of_change,
old_value=old_value, new_value=str(stationmeta_dict2))
db.add(db_changelog)
db.commit()
# there's a mismatch with coordinates --> how to automatically switch back and forth?!
db_stationmeta.coordinates = tmp_coordinates
......
......@@ -11,7 +11,7 @@ from geoalchemy2.shape import to_shape
import datetime as dt
from .models import CZ_enum, CV_enum, ST_enum, TA_enum, TC_enum, \
TR_enum, DL_enum
from toardb.generic.models import RC_enum, RS_enum
from toardb.generic.models import RC_enum, RS_enum, AK_enum, CL_enum
from toardb.contacts.schemas import Contact
......@@ -118,6 +118,10 @@ class StationmetaAnnotationBase(BaseModel):
approved: bool
contributor_id: int
@validator('kind')
def check_kind(cls, v):
return tuple(filter(lambda x: x.value == int(v), AK_enum))[0].string
class StationmetaAnnotationPatch(BaseModel):
kind: int = None
......@@ -126,6 +130,10 @@ class StationmetaAnnotationPatch(BaseModel):
approved: bool = None
contributor_id: int = None
@validator('kind')
def check_kind(cls, v):
return tuple(filter(lambda x: x.value == int(v), AK_enum))[0].string
class StationmetaAnnotationCreate(StationmetaAnnotationBase):
pass
......@@ -460,6 +468,12 @@ class StationmetaChangelogBase(BaseModel):
author_id: int
type_of_change: int
@validator('type_of_change')
def check_role(cls, v):
return tuple(filter(lambda x: x.value == int(v), CL_enum))[0].string
class Config:
orm_mode = True
class StationmetaChangelog(StationmetaChangelogBase):
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment