From dcb0a0549bff69c5e131aa960be00da9034b5809 Mon Sep 17 00:00:00 2001 From: Nick Hall Date: Tue, 15 Oct 2024 00:27:02 +0100 Subject: [PATCH] Refactor JSON serialization --- gramps/gen/lib/baseobj.py | 12 ++++++++++++ gramps/gen/lib/date.py | 14 ++++++++++++++ gramps/gen/lib/event.py | 13 +++++++++++++ gramps/gen/lib/eventref.py | 10 ++++++++++ gramps/gen/lib/grampstype.py | 16 +++++++++++++++- gramps/gen/lib/mediaref.py | 6 ++++++ gramps/gen/lib/person.py | 10 ++++++++++ gramps/gen/lib/serialize.py | 32 ++++++++------------------------ gramps/gen/lib/styledtext.py | 10 ++++++++++ gramps/gen/lib/styledtexttag.py | 12 ++++++++++++ gramps/gen/lib/tag.py | 16 ++++++++++++++++ 11 files changed, 126 insertions(+), 25 deletions(-) diff --git a/gramps/gen/lib/baseobj.py b/gramps/gen/lib/baseobj.py index f5bf2e6a0cd..91a92b32dba 100644 --- a/gramps/gen/lib/baseobj.py +++ b/gramps/gen/lib/baseobj.py @@ -57,6 +57,18 @@ def unserialize(self, data): Convert a serialized tuple of data to an object. """ + def get_attrs(self): + attr_dict = {"_class": self.__class__.__name__} + for key, value in self.__dict__.items(): + if not key.startswith("_"): + attr_dict[key] = value + return attr_dict + + def set_attrs(self, attr_dict): + for key, value in attr_dict.items(): + if key != "_class": + setattr(self, key, value) + def matches_string(self, pattern, case_sensitive=False): """ Return True if any text data in the object or any of it's child diff --git a/gramps/gen/lib/date.py b/gramps/gen/lib/date.py index e7e957c81b3..7cb9d7d8700 100644 --- a/gramps/gen/lib/date.py +++ b/gramps/gen/lib/date.py @@ -749,6 +749,20 @@ def unserialize(self, data): raise DateError("Invalid date to unserialize") return self + def get_attrs(self): + attr_dict = {"_class": self.__class__.__name__} + for key, value in self.__dict__.items(): + if not key.startswith("_"): + attr_dict[key] = value + return attr_dict + + def set_attrs(self, attr_dict): + for key, value in attr_dict.items(): + if key == "dateval": + value = tuple(value) + if key != "_class": + setattr(self, key, value) + @classmethod def get_schema(cls): """ diff --git a/gramps/gen/lib/event.py b/gramps/gen/lib/event.py index 2fc1980b027..e413902a72f 100644 --- a/gramps/gen/lib/event.py +++ b/gramps/gen/lib/event.py @@ -136,6 +136,19 @@ def serialize(self, no_text_date=False): self.private, ) + def get_attrs(self): + attr_dict = super().get_attrs() + attr_dict["type"] = self.__type + attr_dict["description"] = self.__description + return attr_dict + + def set_attrs(self, attr_dict): + self.__type = attr_dict["type"] + del attr_dict["type"] + self.__description = attr_dict["description"] + del attr_dict["description"] + super().set_attrs(attr_dict) + @classmethod def get_schema(cls): """ diff --git a/gramps/gen/lib/eventref.py b/gramps/gen/lib/eventref.py index 655cc6be7aa..53899d57dff 100644 --- a/gramps/gen/lib/eventref.py +++ b/gramps/gen/lib/eventref.py @@ -86,6 +86,16 @@ def serialize(self): self.__role.serialize(), ) + def get_attrs(self): + attr_dict = super().get_attrs() + attr_dict["role"] = self.__role + return attr_dict + + def set_attrs(self, attr_dict): + self.__role = attr_dict["role"] + del attr_dict["role"] + super().set_attrs(attr_dict) + @classmethod def get_schema(cls): """ diff --git a/gramps/gen/lib/grampstype.py b/gramps/gen/lib/grampstype.py index 8e9d94480b6..9edc14956f6 100644 --- a/gramps/gen/lib/grampstype.py +++ b/gramps/gen/lib/grampstype.py @@ -136,6 +136,19 @@ def __init__(self, value=None): if value is not None: self.set(value) + def get_attrs(self): + attr_dict = {"_class": self.__class__.__name__} + attr_dict["value"] = self.__value + attr_dict["string"] = self.__string + return attr_dict + + def set_attrs(self, attr_dict): + self.__value = attr_dict["value"] + if self.__value == self._CUSTOM: + self.__string = attr_dict["string"] + else: + self.__string = "" + def __set_tuple(self, value): "Set the value/string properties from a tuple." val, strg = self._DEFAULT, "" @@ -225,7 +238,8 @@ def get_schema(cls): "title": _("Type"), "properties": { "_class": {"enum": [cls.__name__]}, - "string": {"type": "string", "title": _("Type")}, + "string": {"type": "string", "title": _("Type String")}, + "value": {"type": "integer", "title": _("Type Value")}, }, } diff --git a/gramps/gen/lib/mediaref.py b/gramps/gen/lib/mediaref.py index 9e52e116080..5896f52ab15 100644 --- a/gramps/gen/lib/mediaref.py +++ b/gramps/gen/lib/mediaref.py @@ -151,6 +151,12 @@ def unserialize(self, data): RefBase.unserialize(self, ref) return self + def set_attrs(self, attr_dict): + rect = attr_dict["rect"] + if rect is not None: + attr_dict["rect"] = tuple(rect) + super().set_attrs(attr_dict) + def get_text_data_child_list(self): """ Return the list of child objects that may carry textual data. diff --git a/gramps/gen/lib/person.py b/gramps/gen/lib/person.py index 1d59671fe86..df5286ed531 100644 --- a/gramps/gen/lib/person.py +++ b/gramps/gen/lib/person.py @@ -322,6 +322,16 @@ def unserialize(self, data): TagBase.unserialize(self, tag_list) return self + def get_attrs(self): + attr_dict = super().get_attrs() + attr_dict["gender"] = self.__gender + return attr_dict + + def set_attrs(self, attr_dict): + self.__gender = attr_dict["gender"] + del attr_dict["gender"] + super().set_attrs(attr_dict) + def _has_handle_reference(self, classname, handle): """ Return True if the object has reference to a given handle of given diff --git a/gramps/gen/lib/serialize.py b/gramps/gen/lib/serialize.py index df0c323bd7a..cdcecbad3ed 100644 --- a/gramps/gen/lib/serialize.py +++ b/gramps/gen/lib/serialize.py @@ -37,38 +37,22 @@ import gramps.gen.lib as lib -def __default(obj): - obj_dict = {"_class": obj.__class__.__name__} - if isinstance(obj, lib.GrampsType): - obj_dict["string"] = getattr(obj, "string") - if isinstance(obj, lib.Date): - if obj.is_empty() and not obj.text: - return None - for key, value in obj.__dict__.items(): - if not key.startswith("_"): - obj_dict[key] = value - for key, value in obj.__class__.__dict__.items(): - if isinstance(value, property): - if key != "year": - obj_dict[key] = getattr(obj, key) - return obj_dict - - def __object_hook(obj_dict): obj = getattr(lib, obj_dict["_class"])() - for key, value in obj_dict.items(): - if key != "_class": - if key in ("dateval", "rect") and value is not None: - value = tuple(value) - if key == "ranges": - value = [tuple(item) for item in value] - setattr(obj, key, value) + obj.set_attrs(obj_dict) if obj_dict["_class"] == "Date": if obj.is_empty() and not obj.text: return None return obj +def __default(obj): + if isinstance(obj, lib.Date): + if obj.is_empty() and not obj.text: + return None + return obj.get_attrs() + + def to_json(obj): """ Encode a Gramps object in JSON format. diff --git a/gramps/gen/lib/styledtext.py b/gramps/gen/lib/styledtext.py index c64ed768055..5c03e72f820 100644 --- a/gramps/gen/lib/styledtext.py +++ b/gramps/gen/lib/styledtext.py @@ -101,6 +101,16 @@ def __init__(self, text="", tags=None): else: self._tags = [] + def get_attrs(self): + attr_dict = {"_class": self.__class__.__name__} + attr_dict["tags"] = self._tags + attr_dict["string"] = self._string + return attr_dict + + def set_attrs(self, attr_dict): + self._tags = attr_dict["tags"] + self._string = attr_dict["string"] + # special methods def __str__(self): diff --git a/gramps/gen/lib/styledtexttag.py b/gramps/gen/lib/styledtexttag.py index dfe3c716f43..fa45b1723fd 100644 --- a/gramps/gen/lib/styledtexttag.py +++ b/gramps/gen/lib/styledtexttag.py @@ -69,6 +69,18 @@ def __init__(self, name=None, value=None, ranges=None): # Current use of StyledTextTag is such that a shallow copy suffices. self.ranges = ranges + def get_attrs(self): + attr_dict = {"_class": self.__class__.__name__} + attr_dict["name"] = self.name + attr_dict["value"] = self.value + attr_dict["ranges"] = self.ranges + return attr_dict + + def set_attrs(self, attr_dict): + self.name = attr_dict["name"] + self.value = attr_dict["value"] + self.ranges = [tuple(item) for item in attr_dict["ranges"]] + def serialize(self): """Convert the object to a serialized tuple of data. diff --git a/gramps/gen/lib/tag.py b/gramps/gen/lib/tag.py index f6fe87d1e31..e1d3a819c91 100644 --- a/gramps/gen/lib/tag.py +++ b/gramps/gen/lib/tag.py @@ -108,6 +108,22 @@ def unserialize(self, data): ) = data return self + def get_attrs(self): + attr_dict = super().get_attrs() + attr_dict["name"] = self.__name + attr_dict["color"] = self.__color + attr_dict["priority"] = self.__priority + return attr_dict + + def set_attrs(self, attr_dict): + self.__name = attr_dict["name"] + del attr_dict["name"] + self.__color = attr_dict["color"] + del attr_dict["color"] + self.__priority = attr_dict["priority"] + del attr_dict["priority"] + super().set_attrs(attr_dict) + @classmethod def get_schema(cls): """