|
| 1 | +import json |
| 2 | +import os |
1 | 3 |
|
2 |
| -__version__ = "0.1.0" |
3 |
| -__author__ = 'Abhay Katheria and Mithilesh Tiwari' |
| 4 | +# Attempt to import from __main__ first for the generate_from_file functionality |
| 5 | +# and create_output_file. If __main__ is not available (e.g. during package import by setup.py), |
| 6 | +# these will be handled by direct calls later if possible. |
| 7 | +try: |
| 8 | + from .__main__ import generate as generate_from_file_path |
| 9 | + from .__main__ import create_output_file |
| 10 | +except ImportError: |
| 11 | + # This might happen if setup.py imports __init__.py before __main__.py is in sys.path in a structured way |
| 12 | + # Or if used in a context where __main__ is not directly runnable as a module entry. |
| 13 | + # We will define fallbacks or ensure direct calls for core logic. |
| 14 | + generate_from_file_path = None # Placeholder, direct file handling will be in convert |
| 15 | + create_output_file = None # Placeholder, direct file writing will be in convert |
| 16 | + |
| 17 | + |
| 18 | +from .theme_1 import html as html_1 |
| 19 | +from .theme_2 import html as html_2 |
| 20 | + |
| 21 | +__version__ = "0.2.0" # Updated version |
| 22 | +__author__ = 'Abhay Katheria, Mithilesh Tiwari, and AI Contributor' |
| 23 | +__all__ = ['convert'] |
| 24 | + |
| 25 | + |
| 26 | +def convert(json_input, theme='1', output_file=None): |
| 27 | + """ |
| 28 | + Converts JSON input to an HTML tree representation. |
| 29 | +
|
| 30 | + :param json_input: JSON data to convert. Can be: |
| 31 | + - A file path (string) to a JSON file. |
| 32 | + - A JSON formatted string. |
| 33 | + - A Python dictionary. |
| 34 | + :param theme: Theme identifier string ('1' or '2'). Defaults to '1'. |
| 35 | + :param output_file: Optional. File path to save the HTML output. |
| 36 | + If None, the HTML string is returned. |
| 37 | + :return: HTML string if output_file is None, otherwise None. |
| 38 | + :raises TypeError: If json_input is not a str, dict. |
| 39 | + :raises ValueError: If json_input string is not a valid JSON or file path. |
| 40 | + """ |
| 41 | + html_string = '' |
| 42 | + json_data = None |
| 43 | + |
| 44 | + if isinstance(json_input, str): |
| 45 | + # Heuristic: if it starts with { or [, it's likely a JSON string. Otherwise, could be a path. |
| 46 | + # This isn't foolproof but covers many common cases. |
| 47 | + is_likely_json_payload = json_input.strip().startswith(("{", "[")) |
| 48 | + |
| 49 | + if os.path.exists(json_input): |
| 50 | + try: |
| 51 | + with open(json_input, 'r', encoding='utf-8') as f: |
| 52 | + json_data = json.load(f) |
| 53 | + except json.JSONDecodeError: # File exists but is not valid JSON |
| 54 | + raise ValueError(f"Invalid JSON in file: {json_input}") |
| 55 | + # FileNotFoundError here would be a race condition if os.path.exists was true moments before. |
| 56 | + # Python's default FileNotFoundError would propagate. |
| 57 | + elif is_likely_json_payload: # Not a file path, but looks like a JSON string |
| 58 | + try: |
| 59 | + json_data = json.loads(json_input) |
| 60 | + except json.JSONDecodeError as e: # Does look like JSON but is malformed |
| 61 | + raise ValueError(f"Malformed JSON string provided: {e}") |
| 62 | + else: # Not an existing file path, and not starting like a JSON payload. |
| 63 | + # Treat as a non-existent file path or invalid input. |
| 64 | + raise ValueError(f"Input string '{json_input}' is not an existing file path and not a recognizable JSON string.") |
| 65 | + elif isinstance(json_input, dict): |
| 66 | + json_data = json_input |
| 67 | + else: |
| 68 | + raise TypeError("json_input must be a file path (str), a JSON string (str), or a dictionary.") |
| 69 | + |
| 70 | + if json_data is None: # Should have been caught by now, but as a safeguard |
| 71 | + raise ValueError("Failed to parse or load JSON input.") |
| 72 | + |
| 73 | + if theme == '1': |
| 74 | + html_string = html_1.create_html_report(json_data) |
| 75 | + elif theme == '2': |
| 76 | + html_string = html_2.create_html_report(json_data) |
| 77 | + else: # Default to theme 1 if an invalid theme is chosen |
| 78 | + html_string = html_1.create_html_report(json_data) |
| 79 | + |
| 80 | + if output_file: |
| 81 | + # Debug prints |
| 82 | + print(f"DEBUG: Attempting to write to output_file: {output_file}") |
| 83 | + print(f"DEBUG: Length of html_string: {len(html_string)}") |
| 84 | + if len(html_string) < 200: # Print a snippet if short |
| 85 | + print(f"DEBUG: HTML_STRING (snippet): {html_string[:100]}...{html_string[-50:]}") |
| 86 | + else: |
| 87 | + print(f"DEBUG: HTML_STRING (snippet): {html_string[:100]}...{html_string[-100:]}") |
| 88 | + |
| 89 | + try: |
| 90 | + with open(output_file, 'w', encoding='utf-8') as f: |
| 91 | + f.write(html_string) |
| 92 | + print(f"DEBUG: Successfully wrote to {output_file}") # Confirm write |
| 93 | + return None # Function signature implies None when writing to file |
| 94 | + except IOError as e: |
| 95 | + print(f"DEBUG: IOError during write: {e}") # Debug IOError |
| 96 | + # Consider how to handle IOErrors, e.g., re-raise or log |
| 97 | + raise IOError(f"Could not write to output file: {output_file}") |
| 98 | + else: |
| 99 | + return html_string |
0 commit comments