From 072dd18750df61da9be306b153d7a41676c83948 Mon Sep 17 00:00:00 2001 From: Onur Solmaz <2453968+osolmaz@users.noreply.github.com> Date: Thu, 13 Mar 2025 14:14:22 +0100 Subject: [PATCH] Allow setting created_by --- jsondoc/bin/convert_jsondoc.py | 11 +++++++ jsondoc/utils.py | 55 ++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/jsondoc/bin/convert_jsondoc.py b/jsondoc/bin/convert_jsondoc.py index 2f15206..090b656 100644 --- a/jsondoc/bin/convert_jsondoc.py +++ b/jsondoc/bin/convert_jsondoc.py @@ -6,6 +6,7 @@ from jsondoc.convert.html import html_to_jsondoc from jsondoc.convert.markdown import jsondoc_to_markdown from jsondoc.serialize import jsondoc_dump_json, load_jsondoc +from jsondoc.utils import set_created_by ALLOWED_FORMATS = [ "jsondoc", @@ -67,6 +68,7 @@ def convert_to_jsondoc( source_format: str | None = None, target_format: str | None = None, force_page: bool = False, + created_by: str | None = None, ): """ Convert to and from JSON-DOC format. @@ -147,6 +149,8 @@ def convert_to_jsondoc( raise e jsondoc = html_to_jsondoc(html_content, force_page=force_page) + if created_by is not None: + set_created_by(jsondoc, created_by) # Serialize the jsondoc serialized_jsondoc = jsondoc_dump_json(jsondoc, indent=indent) @@ -198,6 +202,12 @@ def main(): help="Force the creation of a page even if the input doesn't " "contain a top-level HTML structure", ) + parser.add_argument( + "--created-by", + type=str, + help="An identifier for the entity that created the JSON-DOC file", + default=None, + ) args = parser.parse_args() try: @@ -208,6 +218,7 @@ def main(): source_format=args.source_format, target_format=args.target_format, force_page=args.force_page, + created_by=args.created_by, ) except (ValueError, RuntimeError) as e: print(e) diff --git a/jsondoc/utils.py b/jsondoc/utils.py index ffaa1a9..38eefdb 100644 --- a/jsondoc/utils.py +++ b/jsondoc/utils.py @@ -139,3 +139,58 @@ def set_dict_recursive(d: dict | list, key: str, value: str): for item in d: if isinstance(item, dict): set_dict_recursive(item, key, value) + + +def set_field_recursive(obj: any, field_name: str, value: any) -> None: + """ + Recursively sets all fields with name 'field_name' to 'value' in the given object. + Works with dictionaries, lists, Pydantic models, and other objects with attributes. + + Args: + obj: The object to traverse (dict, list, Pydantic model, or other object) + field_name: The name of the field to set + value: The value to set the field to + """ + from pydantic import BaseModel + + # Handle dictionary + if isinstance(obj, dict): + for k, v in list(obj.items()): + if k == field_name: + obj[k] = value + else: + set_field_recursive(v, field_name, value) + + # Handle list + elif isinstance(obj, list): + for item in obj: + set_field_recursive(item, field_name, value) + + # Handle Pydantic models + elif isinstance(obj, BaseModel): + # Get the model fields as a dict and process them + data = obj.model_dump() + for k, v in data.items(): + if k == field_name: + setattr(obj, k, value) + else: + model_value = getattr(obj, k) + set_field_recursive(model_value, field_name, value) + + # # Handle other objects with attributes (non-primitive types) + # elif hasattr(obj, "__dict__") and not isinstance( + # obj, (str, int, float, bool, type(None)) + # ): + # for k, v in list(obj.__dict__.items()): + # if k == field_name: + # setattr(obj, k, value) + # else: + # set_field_recursive(v, field_name, value) + + +def set_created_by(obj: any, created_by: str) -> None: + """ + Recursively sets the 'created_by' field to the given value in the given object. + """ + assert isinstance(created_by, str) + set_field_recursive(obj, "created_by", created_by)