diff --git a/tagstudio/src/core/json_typing.py b/tagstudio/src/core/json_typing.py new file mode 100644 index 00000000..ee3dc2d3 --- /dev/null +++ b/tagstudio/src/core/json_typing.py @@ -0,0 +1,33 @@ +from typing import TypedDict + +class Json_Libary(TypedDict("",{"ts-version":str})): + #"ts-version": str + tags: "list[Json_Tag]" + collations: "list[Json_Collation]" + fields: list #TODO + macros: "list[Json_Macro]" + entries: "list[Json_Entry]" + +class Json_Base(TypedDict): + id: int + +class Json_Tag(Json_Base,total=False): + name: str + aliases: list[str] + color: str + shorthand: str + subtag_ids: list[int] + +class Json_Collation(Json_Base,total=False): + title: str + e_ids_and_pages: list[list[int]] + sort_order: str + cover_id: int + +class Json_Entry(Json_Base,total=False): + filename: str + path: str + fields: list[dict] #TODO + +class Json_Macro(Json_Base,total=False): + ... #TODO \ No newline at end of file diff --git a/tagstudio/src/core/library.py b/tagstudio/src/core/library.py index 230fffdd..5e208563 100644 --- a/tagstudio/src/core/library.py +++ b/tagstudio/src/core/library.py @@ -14,9 +14,9 @@ import time import traceback import xml.etree.ElementTree as ET from enum import Enum - import ujson +from src.core.json_typing import Json_Collation, Json_Entry, Json_Libary, Json_Tag from src.core import ts_core from src.core.utils.str import strip_punctuation from src.core.utils.web import strip_web_protocol @@ -84,13 +84,14 @@ class Entry: and self.path == __value.path and self.fields == __value.fields) - def compressed_dict(self) -> dict: + def compressed_dict(self) -> Json_Entry: """ An alternative to __dict__ that only includes fields containing non-default data. """ - obj = {} - obj['id'] = self.id + obj: Json_Entry = { + "id": self.id + } if self.filename: obj['filename'] = self.filename if self.path: @@ -198,13 +199,14 @@ class Tag: else: return (f'{self.name}') - def compressed_dict(self) -> dict: + def compressed_dict(self) -> Json_Tag: """ An alternative to __dict__ that only includes fields containing non-default data. """ - obj = {} - obj["id"] = self.id + obj: Json_Tag = { + "id":self.id + } if self.name: obj["name"] = self.name if self.shorthand: @@ -262,13 +264,14 @@ class Collation: and self.path == __value.path and self.fields == __value.fields) - def compressed_dict(self) -> dict: + def compressed_dict(self) -> Json_Collation: """ An alternative to __dict__ that only includes fields containing non-default data. """ - obj = {} - obj['id'] = self.id + obj: Json_Collation = { + "id":self.id + } if self.title: obj['title'] = self.title if self.e_ids_and_pages: @@ -349,7 +352,7 @@ class Library: # Map of every Tag ID to the index of the Tag in self.tags. self._tag_id_to_index_map: dict[int, int] = {} - self.default_tags = [ + self.default_tags: list[Json_Tag] = [ { "id": 0, "name": "Archived", @@ -576,13 +579,13 @@ class Library: if not os.path.isdir(full_collage_path): os.mkdir(full_collage_path) - - def verify_default_tags(self, tag_list: list) -> list: + + def verify_default_tags(self, tag_list: list[Json_Tag]) -> list[Json_Tag]: """ Ensures that the default builtin tags are present in the Library's save file. Takes in and returns the tag dictionary from the JSON file. """ - missing: list[int] = [] + missing: list[Json_Tag] = [] for dt in self.default_tags: if dt['id'] not in [t['id'] for t in tag_list]: @@ -610,7 +613,7 @@ class Library: try: with open(os.path.normpath(f'{path}/{ts_core.TS_FOLDER_NAME}/ts_library.json'), 'r', encoding='utf-8') as f: - json_dump = ujson.load(f) + json_dump: Json_Libary = ujson.load(f) self.library_dir = str(path) self.verify_ts_folders() major, minor, patch = json_dump['ts-version'].split('.') @@ -828,8 +831,9 @@ class Library: Creates a JSON serialized string from the Library object. Used in saving the library to disk. """ - file_to_save = {"ts-version": ts_core.VERSION, - "ignored_extensions": [], + + file_to_save: Json_Libary = {"ts-version": ts_core.VERSION, + "ignored_extensions": [], "tags": [], "collations": [], "fields": [],