|
1 | 1 | import re
|
2 | 2 | import shutil
|
3 | 3 | import os
|
| 4 | +import json |
4 | 5 | from abc import ABC, abstractmethod
|
5 | 6 | from typing import Any
|
6 | 7 | from loguru import logger
|
| 8 | +import traceback |
7 | 9 |
|
8 | 10 | class ChatFormatter(ABC):
|
9 | 11 | @abstractmethod
|
@@ -41,26 +43,70 @@ def format(self, chat_data: dict[str, Any], image_dir: str | None = 'images') ->
|
41 | 43 |
|
42 | 44 | for bubble in bubbles:
|
43 | 45 | if bubble['type'] == 'user':
|
44 |
| - formatted_chat.append(f"## User:\n\n{bubble['delegate']['a']}\n") |
| 46 | + user_text = ["## User:\n\n"] |
| 47 | + |
| 48 | + if "selections" in bubble and bubble["selections"]: |
| 49 | + user_text.append(f"[selections] \n{"\n".join([s["text"] for s in bubble['selections']])}") |
| 50 | + |
45 | 51 | if 'image' in bubble and tab_image_dir is not None:
|
46 | 52 | image_path = bubble['image']['path']
|
47 | 53 | image_filename = os.path.basename(image_path)
|
48 | 54 | new_image_path = os.path.join(tab_image_dir, image_filename)
|
49 | 55 | shutil.copy(image_path, new_image_path)
|
50 |
| - formatted_chat.append(f"\n") |
| 56 | + user_text.append(f"[image] \n") |
| 57 | + |
| 58 | + if "delegate" in bubble: |
| 59 | + if bubble["delegate"]: |
| 60 | + user_text_text = bubble['delegate']["a"] |
| 61 | + else: |
| 62 | + user_text_text = "" |
| 63 | + elif "text" in bubble: |
| 64 | + if bubble["text"]: |
| 65 | + user_text_text = bubble['text'] |
| 66 | + else: |
| 67 | + user_text_text = "" |
| 68 | + elif "initText" in bubble: |
| 69 | + if bubble["initText"]: |
| 70 | + user_text_text = bubble['rawText'] |
| 71 | + user_text_text = json.loads(bubble["initText"])['root']['children'][0]['children'][0]['text'] |
| 72 | + else: |
| 73 | + user_text_text = "" |
| 74 | + elif "rawText" in bubble: |
| 75 | + if bubble["rawText"]: |
| 76 | + user_text_text = bubble['text'] |
| 77 | + else: |
| 78 | + user_text_text = "" |
| 79 | + else: |
| 80 | + user_text_text = "[ERROR: no user text found]" |
| 81 | + logger.error(f"Couldn't find user text entry in one of the bubbles.") |
| 82 | + logger.debug(f"Bubble:\n{json.dumps(bubble, indent=4)}") |
| 83 | + if user_text_text: |
| 84 | + user_text.append(f"[text] \n{user_text_text}") |
| 85 | + |
| 86 | + user_text.append("\n") |
| 87 | + |
| 88 | + if len(user_text) > 2: |
| 89 | + formatted_chat.append("\n".join(user_text)) |
51 | 90 | elif bubble['type'] == 'ai':
|
52 | 91 | model_type = bubble.get('modelType', 'Unknown')
|
53 | 92 | raw_text = re.sub(r'```python:[^\n]+', '```python', bubble['rawText'])
|
54 | 93 | formatted_chat.append(f"## AI ({model_type}):\n\n{raw_text}\n")
|
55 | 94 |
|
56 | 95 | formatted_chats.append("\n".join(formatted_chat))
|
57 | 96 |
|
| 97 | + logger.success("Chats formatted.") |
58 | 98 | return formatted_chats
|
59 | 99 | except KeyError as e:
|
60 |
| - logger.error(f"KeyError: {e}") |
| 100 | + logger.error(f"KeyError: Missing key {e} in chat data. Ensure the data structure is correct. Full error: {e}") |
61 | 101 | return [f"Error: Missing key {e}"]
|
| 102 | + except FileNotFoundError as e: |
| 103 | + logger.error(f"FileNotFoundError: {e}. Ensure the image paths are correct. Full error: {e}") |
| 104 | + return [f"Error: {e}"] |
| 105 | + except json.JSONDecodeError as e: |
| 106 | + logger.error(f"JSONDecodeError: {e}. Ensure the JSON data is correctly formatted. Full error: {e}") |
| 107 | + return [f"Error: {e}"] |
62 | 108 | except Exception as e:
|
63 |
| - logger.error(f"Unexpected error: {e}") |
| 109 | + logger.error(f"Unexpected error: {e}. Full traceback: {traceback.format_exc()}") |
64 | 110 | return [f"Error: {e}"]
|
65 | 111 |
|
66 | 112 | class FileSaver(ABC):
|
|
0 commit comments