pomera-ai-commander 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +680 -0
- package/bin/pomera-ai-commander.js +62 -0
- package/core/__init__.py +66 -0
- package/core/__pycache__/__init__.cpython-313.pyc +0 -0
- package/core/__pycache__/app_context.cpython-313.pyc +0 -0
- package/core/__pycache__/async_text_processor.cpython-313.pyc +0 -0
- package/core/__pycache__/backup_manager.cpython-313.pyc +0 -0
- package/core/__pycache__/backup_recovery_manager.cpython-313.pyc +0 -0
- package/core/__pycache__/content_hash_cache.cpython-313.pyc +0 -0
- package/core/__pycache__/context_menu.cpython-313.pyc +0 -0
- package/core/__pycache__/data_validator.cpython-313.pyc +0 -0
- package/core/__pycache__/database_connection_manager.cpython-313.pyc +0 -0
- package/core/__pycache__/database_curl_settings_manager.cpython-313.pyc +0 -0
- package/core/__pycache__/database_promera_ai_settings_manager.cpython-313.pyc +0 -0
- package/core/__pycache__/database_schema.cpython-313.pyc +0 -0
- package/core/__pycache__/database_schema_manager.cpython-313.pyc +0 -0
- package/core/__pycache__/database_settings_manager.cpython-313.pyc +0 -0
- package/core/__pycache__/database_settings_manager_interface.cpython-313.pyc +0 -0
- package/core/__pycache__/dialog_manager.cpython-313.pyc +0 -0
- package/core/__pycache__/efficient_line_numbers.cpython-313.pyc +0 -0
- package/core/__pycache__/error_handler.cpython-313.pyc +0 -0
- package/core/__pycache__/error_service.cpython-313.pyc +0 -0
- package/core/__pycache__/event_consolidator.cpython-313.pyc +0 -0
- package/core/__pycache__/memory_efficient_text_widget.cpython-313.pyc +0 -0
- package/core/__pycache__/migration_manager.cpython-313.pyc +0 -0
- package/core/__pycache__/migration_test_suite.cpython-313.pyc +0 -0
- package/core/__pycache__/migration_validator.cpython-313.pyc +0 -0
- package/core/__pycache__/optimized_find_replace.cpython-313.pyc +0 -0
- package/core/__pycache__/optimized_pattern_engine.cpython-313.pyc +0 -0
- package/core/__pycache__/optimized_search_highlighter.cpython-313.pyc +0 -0
- package/core/__pycache__/performance_monitor.cpython-313.pyc +0 -0
- package/core/__pycache__/persistence_manager.cpython-313.pyc +0 -0
- package/core/__pycache__/progressive_stats_calculator.cpython-313.pyc +0 -0
- package/core/__pycache__/regex_pattern_cache.cpython-313.pyc +0 -0
- package/core/__pycache__/regex_pattern_library.cpython-313.pyc +0 -0
- package/core/__pycache__/search_operation_manager.cpython-313.pyc +0 -0
- package/core/__pycache__/settings_defaults_registry.cpython-313.pyc +0 -0
- package/core/__pycache__/settings_integrity_validator.cpython-313.pyc +0 -0
- package/core/__pycache__/settings_serializer.cpython-313.pyc +0 -0
- package/core/__pycache__/settings_validator.cpython-313.pyc +0 -0
- package/core/__pycache__/smart_stats_calculator.cpython-313.pyc +0 -0
- package/core/__pycache__/statistics_update_manager.cpython-313.pyc +0 -0
- package/core/__pycache__/stats_config_manager.cpython-313.pyc +0 -0
- package/core/__pycache__/streaming_text_handler.cpython-313.pyc +0 -0
- package/core/__pycache__/task_scheduler.cpython-313.pyc +0 -0
- package/core/__pycache__/visibility_monitor.cpython-313.pyc +0 -0
- package/core/__pycache__/widget_cache.cpython-313.pyc +0 -0
- package/core/app_context.py +482 -0
- package/core/async_text_processor.py +422 -0
- package/core/backup_manager.py +656 -0
- package/core/backup_recovery_manager.py +1034 -0
- package/core/content_hash_cache.py +509 -0
- package/core/context_menu.py +313 -0
- package/core/data_validator.py +1067 -0
- package/core/database_connection_manager.py +745 -0
- package/core/database_curl_settings_manager.py +609 -0
- package/core/database_promera_ai_settings_manager.py +447 -0
- package/core/database_schema.py +412 -0
- package/core/database_schema_manager.py +396 -0
- package/core/database_settings_manager.py +1508 -0
- package/core/database_settings_manager_interface.py +457 -0
- package/core/dialog_manager.py +735 -0
- package/core/efficient_line_numbers.py +511 -0
- package/core/error_handler.py +747 -0
- package/core/error_service.py +431 -0
- package/core/event_consolidator.py +512 -0
- package/core/mcp/__init__.py +43 -0
- package/core/mcp/__pycache__/__init__.cpython-313.pyc +0 -0
- package/core/mcp/__pycache__/protocol.cpython-313.pyc +0 -0
- package/core/mcp/__pycache__/schema.cpython-313.pyc +0 -0
- package/core/mcp/__pycache__/server_stdio.cpython-313.pyc +0 -0
- package/core/mcp/__pycache__/tool_registry.cpython-313.pyc +0 -0
- package/core/mcp/protocol.py +288 -0
- package/core/mcp/schema.py +251 -0
- package/core/mcp/server_stdio.py +299 -0
- package/core/mcp/tool_registry.py +2345 -0
- package/core/memory_efficient_text_widget.py +712 -0
- package/core/migration_manager.py +915 -0
- package/core/migration_test_suite.py +1086 -0
- package/core/migration_validator.py +1144 -0
- package/core/optimized_find_replace.py +715 -0
- package/core/optimized_pattern_engine.py +424 -0
- package/core/optimized_search_highlighter.py +553 -0
- package/core/performance_monitor.py +675 -0
- package/core/persistence_manager.py +713 -0
- package/core/progressive_stats_calculator.py +632 -0
- package/core/regex_pattern_cache.py +530 -0
- package/core/regex_pattern_library.py +351 -0
- package/core/search_operation_manager.py +435 -0
- package/core/settings_defaults_registry.py +1087 -0
- package/core/settings_integrity_validator.py +1112 -0
- package/core/settings_serializer.py +558 -0
- package/core/settings_validator.py +1824 -0
- package/core/smart_stats_calculator.py +710 -0
- package/core/statistics_update_manager.py +619 -0
- package/core/stats_config_manager.py +858 -0
- package/core/streaming_text_handler.py +723 -0
- package/core/task_scheduler.py +596 -0
- package/core/update_pattern_library.py +169 -0
- package/core/visibility_monitor.py +596 -0
- package/core/widget_cache.py +498 -0
- package/mcp.json +61 -0
- package/package.json +57 -0
- package/pomera.py +7483 -0
- package/pomera_mcp_server.py +144 -0
- package/tools/__init__.py +5 -0
- package/tools/__pycache__/__init__.cpython-313.pyc +0 -0
- package/tools/__pycache__/ai_tools.cpython-313.pyc +0 -0
- package/tools/__pycache__/ascii_art_generator.cpython-313.pyc +0 -0
- package/tools/__pycache__/base64_tools.cpython-313.pyc +0 -0
- package/tools/__pycache__/base_tool.cpython-313.pyc +0 -0
- package/tools/__pycache__/case_tool.cpython-313.pyc +0 -0
- package/tools/__pycache__/column_tools.cpython-313.pyc +0 -0
- package/tools/__pycache__/cron_tool.cpython-313.pyc +0 -0
- package/tools/__pycache__/curl_history.cpython-313.pyc +0 -0
- package/tools/__pycache__/curl_processor.cpython-313.pyc +0 -0
- package/tools/__pycache__/curl_settings.cpython-313.pyc +0 -0
- package/tools/__pycache__/curl_tool.cpython-313.pyc +0 -0
- package/tools/__pycache__/diff_viewer.cpython-313.pyc +0 -0
- package/tools/__pycache__/email_extraction_tool.cpython-313.pyc +0 -0
- package/tools/__pycache__/email_header_analyzer.cpython-313.pyc +0 -0
- package/tools/__pycache__/extraction_tools.cpython-313.pyc +0 -0
- package/tools/__pycache__/find_replace.cpython-313.pyc +0 -0
- package/tools/__pycache__/folder_file_reporter.cpython-313.pyc +0 -0
- package/tools/__pycache__/folder_file_reporter_adapter.cpython-313.pyc +0 -0
- package/tools/__pycache__/generator_tools.cpython-313.pyc +0 -0
- package/tools/__pycache__/hash_generator.cpython-313.pyc +0 -0
- package/tools/__pycache__/html_tool.cpython-313.pyc +0 -0
- package/tools/__pycache__/huggingface_helper.cpython-313.pyc +0 -0
- package/tools/__pycache__/jsonxml_tool.cpython-313.pyc +0 -0
- package/tools/__pycache__/line_tools.cpython-313.pyc +0 -0
- package/tools/__pycache__/list_comparator.cpython-313.pyc +0 -0
- package/tools/__pycache__/markdown_tools.cpython-313.pyc +0 -0
- package/tools/__pycache__/mcp_widget.cpython-313.pyc +0 -0
- package/tools/__pycache__/notes_widget.cpython-313.pyc +0 -0
- package/tools/__pycache__/number_base_converter.cpython-313.pyc +0 -0
- package/tools/__pycache__/regex_extractor.cpython-313.pyc +0 -0
- package/tools/__pycache__/slug_generator.cpython-313.pyc +0 -0
- package/tools/__pycache__/sorter_tools.cpython-313.pyc +0 -0
- package/tools/__pycache__/string_escape_tool.cpython-313.pyc +0 -0
- package/tools/__pycache__/text_statistics_tool.cpython-313.pyc +0 -0
- package/tools/__pycache__/text_wrapper.cpython-313.pyc +0 -0
- package/tools/__pycache__/timestamp_converter.cpython-313.pyc +0 -0
- package/tools/__pycache__/tool_loader.cpython-313.pyc +0 -0
- package/tools/__pycache__/translator_tools.cpython-313.pyc +0 -0
- package/tools/__pycache__/url_link_extractor.cpython-313.pyc +0 -0
- package/tools/__pycache__/url_parser.cpython-313.pyc +0 -0
- package/tools/__pycache__/whitespace_tools.cpython-313.pyc +0 -0
- package/tools/__pycache__/word_frequency_counter.cpython-313.pyc +0 -0
- package/tools/ai_tools.py +2892 -0
- package/tools/ascii_art_generator.py +353 -0
- package/tools/base64_tools.py +184 -0
- package/tools/base_tool.py +511 -0
- package/tools/case_tool.py +309 -0
- package/tools/column_tools.py +396 -0
- package/tools/cron_tool.py +885 -0
- package/tools/curl_history.py +601 -0
- package/tools/curl_processor.py +1208 -0
- package/tools/curl_settings.py +503 -0
- package/tools/curl_tool.py +5467 -0
- package/tools/diff_viewer.py +1072 -0
- package/tools/email_extraction_tool.py +249 -0
- package/tools/email_header_analyzer.py +426 -0
- package/tools/extraction_tools.py +250 -0
- package/tools/find_replace.py +1751 -0
- package/tools/folder_file_reporter.py +1463 -0
- package/tools/folder_file_reporter_adapter.py +480 -0
- package/tools/generator_tools.py +1217 -0
- package/tools/hash_generator.py +256 -0
- package/tools/html_tool.py +657 -0
- package/tools/huggingface_helper.py +449 -0
- package/tools/jsonxml_tool.py +730 -0
- package/tools/line_tools.py +419 -0
- package/tools/list_comparator.py +720 -0
- package/tools/markdown_tools.py +562 -0
- package/tools/mcp_widget.py +1417 -0
- package/tools/notes_widget.py +973 -0
- package/tools/number_base_converter.py +373 -0
- package/tools/regex_extractor.py +572 -0
- package/tools/slug_generator.py +311 -0
- package/tools/sorter_tools.py +459 -0
- package/tools/string_escape_tool.py +393 -0
- package/tools/text_statistics_tool.py +366 -0
- package/tools/text_wrapper.py +431 -0
- package/tools/timestamp_converter.py +422 -0
- package/tools/tool_loader.py +710 -0
- package/tools/translator_tools.py +523 -0
- package/tools/url_link_extractor.py +262 -0
- package/tools/url_parser.py +205 -0
- package/tools/whitespace_tools.py +356 -0
- package/tools/word_frequency_counter.py +147 -0
|
@@ -0,0 +1,393 @@
|
|
|
1
|
+
"""
|
|
2
|
+
String Escape/Unescape Tool Module - String encoding utilities
|
|
3
|
+
|
|
4
|
+
This module provides string escape and unescape functionality for various formats
|
|
5
|
+
for the Pomera AI Commander application.
|
|
6
|
+
|
|
7
|
+
Features:
|
|
8
|
+
- JSON Escape/Unescape
|
|
9
|
+
- HTML Escape/Unescape
|
|
10
|
+
- URL Encode/Decode
|
|
11
|
+
- XML Escape/Unescape
|
|
12
|
+
- JavaScript Escape/Unescape
|
|
13
|
+
- SQL Escape
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
import tkinter as tk
|
|
17
|
+
from tkinter import ttk
|
|
18
|
+
import html
|
|
19
|
+
import json
|
|
20
|
+
import re
|
|
21
|
+
from urllib.parse import quote, unquote, quote_plus, unquote_plus
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class StringEscapeProcessor:
|
|
25
|
+
"""String escape processor with multiple format support."""
|
|
26
|
+
|
|
27
|
+
@staticmethod
|
|
28
|
+
def json_escape(text):
|
|
29
|
+
"""Escape string for JSON."""
|
|
30
|
+
return json.dumps(text)[1:-1] # Remove surrounding quotes
|
|
31
|
+
|
|
32
|
+
@staticmethod
|
|
33
|
+
def json_unescape(text):
|
|
34
|
+
"""Unescape JSON string."""
|
|
35
|
+
try:
|
|
36
|
+
return json.loads(f'"{text}"')
|
|
37
|
+
except json.JSONDecodeError:
|
|
38
|
+
return f"Error: Invalid JSON escape sequence"
|
|
39
|
+
|
|
40
|
+
@staticmethod
|
|
41
|
+
def html_escape(text):
|
|
42
|
+
"""Escape string for HTML."""
|
|
43
|
+
return html.escape(text, quote=True)
|
|
44
|
+
|
|
45
|
+
@staticmethod
|
|
46
|
+
def html_unescape(text):
|
|
47
|
+
"""Unescape HTML entities."""
|
|
48
|
+
return html.unescape(text)
|
|
49
|
+
|
|
50
|
+
@staticmethod
|
|
51
|
+
def url_encode(text, plus_spaces=False):
|
|
52
|
+
"""URL encode string."""
|
|
53
|
+
if plus_spaces:
|
|
54
|
+
return quote_plus(text)
|
|
55
|
+
return quote(text, safe='')
|
|
56
|
+
|
|
57
|
+
@staticmethod
|
|
58
|
+
def url_decode(text, plus_spaces=False):
|
|
59
|
+
"""URL decode string."""
|
|
60
|
+
try:
|
|
61
|
+
if plus_spaces:
|
|
62
|
+
return unquote_plus(text)
|
|
63
|
+
return unquote(text)
|
|
64
|
+
except Exception as e:
|
|
65
|
+
return f"Error: {str(e)}"
|
|
66
|
+
|
|
67
|
+
@staticmethod
|
|
68
|
+
def xml_escape(text):
|
|
69
|
+
"""Escape string for XML."""
|
|
70
|
+
replacements = [
|
|
71
|
+
('&', '&'),
|
|
72
|
+
('<', '<'),
|
|
73
|
+
('>', '>'),
|
|
74
|
+
('"', '"'),
|
|
75
|
+
("'", '''),
|
|
76
|
+
]
|
|
77
|
+
result = text
|
|
78
|
+
for char, entity in replacements:
|
|
79
|
+
result = result.replace(char, entity)
|
|
80
|
+
return result
|
|
81
|
+
|
|
82
|
+
@staticmethod
|
|
83
|
+
def xml_unescape(text):
|
|
84
|
+
"""Unescape XML entities."""
|
|
85
|
+
replacements = [
|
|
86
|
+
('&', '&'),
|
|
87
|
+
('<', '<'),
|
|
88
|
+
('>', '>'),
|
|
89
|
+
('"', '"'),
|
|
90
|
+
(''', "'"),
|
|
91
|
+
]
|
|
92
|
+
result = text
|
|
93
|
+
for entity, char in replacements:
|
|
94
|
+
result = result.replace(entity, char)
|
|
95
|
+
# Handle numeric entities
|
|
96
|
+
result = re.sub(r'&#(\d+);', lambda m: chr(int(m.group(1))), result)
|
|
97
|
+
result = re.sub(r'&#x([0-9a-fA-F]+);', lambda m: chr(int(m.group(1), 16)), result)
|
|
98
|
+
return result
|
|
99
|
+
|
|
100
|
+
@staticmethod
|
|
101
|
+
def javascript_escape(text):
|
|
102
|
+
"""Escape string for JavaScript."""
|
|
103
|
+
replacements = [
|
|
104
|
+
('\\', '\\\\'),
|
|
105
|
+
("'", "\\'"),
|
|
106
|
+
('"', '\\"'),
|
|
107
|
+
('\n', '\\n'),
|
|
108
|
+
('\r', '\\r'),
|
|
109
|
+
('\t', '\\t'),
|
|
110
|
+
('\b', '\\b'),
|
|
111
|
+
('\f', '\\f'),
|
|
112
|
+
]
|
|
113
|
+
result = text
|
|
114
|
+
for char, escaped in replacements:
|
|
115
|
+
result = result.replace(char, escaped)
|
|
116
|
+
return result
|
|
117
|
+
|
|
118
|
+
@staticmethod
|
|
119
|
+
def javascript_unescape(text):
|
|
120
|
+
"""Unescape JavaScript string."""
|
|
121
|
+
replacements = [
|
|
122
|
+
('\\n', '\n'),
|
|
123
|
+
('\\r', '\r'),
|
|
124
|
+
('\\t', '\t'),
|
|
125
|
+
('\\b', '\b'),
|
|
126
|
+
('\\f', '\f'),
|
|
127
|
+
('\\"', '"'),
|
|
128
|
+
("\\'", "'"),
|
|
129
|
+
('\\\\', '\\'),
|
|
130
|
+
]
|
|
131
|
+
result = text
|
|
132
|
+
for escaped, char in replacements:
|
|
133
|
+
result = result.replace(escaped, char)
|
|
134
|
+
# Handle unicode escapes
|
|
135
|
+
result = re.sub(r'\\u([0-9a-fA-F]{4})', lambda m: chr(int(m.group(1), 16)), result)
|
|
136
|
+
return result
|
|
137
|
+
|
|
138
|
+
@staticmethod
|
|
139
|
+
def sql_escape(text):
|
|
140
|
+
"""Escape string for SQL (single quotes)."""
|
|
141
|
+
return text.replace("'", "''")
|
|
142
|
+
|
|
143
|
+
@staticmethod
|
|
144
|
+
def sql_unescape(text):
|
|
145
|
+
"""Unescape SQL string."""
|
|
146
|
+
return text.replace("''", "'")
|
|
147
|
+
|
|
148
|
+
@staticmethod
|
|
149
|
+
def process_text(input_text, format_type, mode, settings=None):
|
|
150
|
+
"""Process text using the specified format and mode."""
|
|
151
|
+
settings = settings or {}
|
|
152
|
+
|
|
153
|
+
if format_type == "json":
|
|
154
|
+
if mode == "escape":
|
|
155
|
+
return StringEscapeProcessor.json_escape(input_text)
|
|
156
|
+
else:
|
|
157
|
+
return StringEscapeProcessor.json_unescape(input_text)
|
|
158
|
+
|
|
159
|
+
elif format_type == "html":
|
|
160
|
+
if mode == "escape":
|
|
161
|
+
return StringEscapeProcessor.html_escape(input_text)
|
|
162
|
+
else:
|
|
163
|
+
return StringEscapeProcessor.html_unescape(input_text)
|
|
164
|
+
|
|
165
|
+
elif format_type == "url":
|
|
166
|
+
plus_spaces = settings.get("plus_spaces", False)
|
|
167
|
+
if mode == "escape":
|
|
168
|
+
return StringEscapeProcessor.url_encode(input_text, plus_spaces)
|
|
169
|
+
else:
|
|
170
|
+
return StringEscapeProcessor.url_decode(input_text, plus_spaces)
|
|
171
|
+
|
|
172
|
+
elif format_type == "xml":
|
|
173
|
+
if mode == "escape":
|
|
174
|
+
return StringEscapeProcessor.xml_escape(input_text)
|
|
175
|
+
else:
|
|
176
|
+
return StringEscapeProcessor.xml_unescape(input_text)
|
|
177
|
+
|
|
178
|
+
elif format_type == "javascript":
|
|
179
|
+
if mode == "escape":
|
|
180
|
+
return StringEscapeProcessor.javascript_escape(input_text)
|
|
181
|
+
else:
|
|
182
|
+
return StringEscapeProcessor.javascript_unescape(input_text)
|
|
183
|
+
|
|
184
|
+
elif format_type == "sql":
|
|
185
|
+
if mode == "escape":
|
|
186
|
+
return StringEscapeProcessor.sql_escape(input_text)
|
|
187
|
+
else:
|
|
188
|
+
return StringEscapeProcessor.sql_unescape(input_text)
|
|
189
|
+
|
|
190
|
+
else:
|
|
191
|
+
return f"Unknown format: {format_type}"
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
class StringEscapeWidget(ttk.Frame):
|
|
195
|
+
"""Widget for string escape tool."""
|
|
196
|
+
|
|
197
|
+
def __init__(self, parent, app):
|
|
198
|
+
super().__init__(parent)
|
|
199
|
+
self.app = app
|
|
200
|
+
self.processor = StringEscapeProcessor()
|
|
201
|
+
|
|
202
|
+
self.format_type = tk.StringVar(value="json")
|
|
203
|
+
self.mode = tk.StringVar(value="escape")
|
|
204
|
+
self.plus_spaces = tk.BooleanVar(value=False)
|
|
205
|
+
|
|
206
|
+
self.create_widgets()
|
|
207
|
+
self.load_settings()
|
|
208
|
+
|
|
209
|
+
def create_widgets(self):
|
|
210
|
+
"""Creates the widget interface."""
|
|
211
|
+
# Format selection
|
|
212
|
+
format_frame = ttk.LabelFrame(self, text="Format", padding=10)
|
|
213
|
+
format_frame.pack(fill=tk.X, padx=5, pady=5)
|
|
214
|
+
|
|
215
|
+
formats = [
|
|
216
|
+
("JSON", "json"),
|
|
217
|
+
("HTML", "html"),
|
|
218
|
+
("URL", "url"),
|
|
219
|
+
("XML", "xml"),
|
|
220
|
+
("JavaScript", "javascript"),
|
|
221
|
+
("SQL", "sql"),
|
|
222
|
+
]
|
|
223
|
+
|
|
224
|
+
for i, (text, value) in enumerate(formats):
|
|
225
|
+
ttk.Radiobutton(format_frame, text=text,
|
|
226
|
+
variable=self.format_type, value=value,
|
|
227
|
+
command=self.on_setting_change).grid(row=i//3, column=i%3, sticky=tk.W, padx=5, pady=2)
|
|
228
|
+
|
|
229
|
+
# Mode selection
|
|
230
|
+
mode_frame = ttk.LabelFrame(self, text="Mode", padding=10)
|
|
231
|
+
mode_frame.pack(fill=tk.X, padx=5, pady=5)
|
|
232
|
+
|
|
233
|
+
ttk.Radiobutton(mode_frame, text="Escape",
|
|
234
|
+
variable=self.mode, value="escape",
|
|
235
|
+
command=self.on_setting_change).pack(side=tk.LEFT, padx=10)
|
|
236
|
+
ttk.Radiobutton(mode_frame, text="Unescape",
|
|
237
|
+
variable=self.mode, value="unescape",
|
|
238
|
+
command=self.on_setting_change).pack(side=tk.LEFT, padx=10)
|
|
239
|
+
|
|
240
|
+
# URL-specific options
|
|
241
|
+
self.url_options_frame = ttk.LabelFrame(self, text="URL Options", padding=10)
|
|
242
|
+
self.url_options_frame.pack(fill=tk.X, padx=5, pady=5)
|
|
243
|
+
|
|
244
|
+
ttk.Checkbutton(self.url_options_frame, text="Use + for spaces (form encoding)",
|
|
245
|
+
variable=self.plus_spaces,
|
|
246
|
+
command=self.on_setting_change).pack(anchor=tk.W)
|
|
247
|
+
|
|
248
|
+
# Process button
|
|
249
|
+
ttk.Button(self, text="Process",
|
|
250
|
+
command=self.process).pack(pady=10)
|
|
251
|
+
|
|
252
|
+
# Update URL options visibility
|
|
253
|
+
self.update_url_options()
|
|
254
|
+
|
|
255
|
+
def update_url_options(self):
|
|
256
|
+
"""Show/hide URL options based on format selection."""
|
|
257
|
+
if self.format_type.get() == "url":
|
|
258
|
+
self.url_options_frame.pack(fill=tk.X, padx=5, pady=5)
|
|
259
|
+
else:
|
|
260
|
+
self.url_options_frame.pack_forget()
|
|
261
|
+
|
|
262
|
+
def load_settings(self):
|
|
263
|
+
"""Load settings from the application."""
|
|
264
|
+
settings = self.app.settings.get("tool_settings", {}).get("String Escape Tool", {})
|
|
265
|
+
|
|
266
|
+
self.format_type.set(settings.get("format", "json"))
|
|
267
|
+
self.mode.set(settings.get("mode", "escape"))
|
|
268
|
+
self.plus_spaces.set(settings.get("plus_spaces", False))
|
|
269
|
+
self.update_url_options()
|
|
270
|
+
|
|
271
|
+
def save_settings(self):
|
|
272
|
+
"""Save current settings to the application."""
|
|
273
|
+
if "String Escape Tool" not in self.app.settings["tool_settings"]:
|
|
274
|
+
self.app.settings["tool_settings"]["String Escape Tool"] = {}
|
|
275
|
+
|
|
276
|
+
self.app.settings["tool_settings"]["String Escape Tool"].update({
|
|
277
|
+
"format": self.format_type.get(),
|
|
278
|
+
"mode": self.mode.get(),
|
|
279
|
+
"plus_spaces": self.plus_spaces.get()
|
|
280
|
+
})
|
|
281
|
+
|
|
282
|
+
self.app.save_settings()
|
|
283
|
+
|
|
284
|
+
def on_setting_change(self, *args):
|
|
285
|
+
"""Handle setting changes."""
|
|
286
|
+
self.update_url_options()
|
|
287
|
+
self.save_settings()
|
|
288
|
+
|
|
289
|
+
def process(self):
|
|
290
|
+
"""Process the input text."""
|
|
291
|
+
active_input_tab = self.app.input_tabs[self.app.input_notebook.index(self.app.input_notebook.select())]
|
|
292
|
+
input_text = active_input_tab.text.get("1.0", tk.END).rstrip('\n')
|
|
293
|
+
|
|
294
|
+
if not input_text:
|
|
295
|
+
return
|
|
296
|
+
|
|
297
|
+
settings = {"plus_spaces": self.plus_spaces.get()}
|
|
298
|
+
result = StringEscapeProcessor.process_text(
|
|
299
|
+
input_text,
|
|
300
|
+
self.format_type.get(),
|
|
301
|
+
self.mode.get(),
|
|
302
|
+
settings
|
|
303
|
+
)
|
|
304
|
+
|
|
305
|
+
active_output_tab = self.app.output_tabs[self.app.output_notebook.index(self.app.output_notebook.select())]
|
|
306
|
+
active_output_tab.text.config(state="normal")
|
|
307
|
+
active_output_tab.text.delete("1.0", tk.END)
|
|
308
|
+
active_output_tab.text.insert("1.0", result)
|
|
309
|
+
active_output_tab.text.config(state="disabled")
|
|
310
|
+
|
|
311
|
+
self.app.update_all_stats()
|
|
312
|
+
|
|
313
|
+
|
|
314
|
+
class StringEscapeTool:
|
|
315
|
+
"""Main class for String Escape Tool integration."""
|
|
316
|
+
|
|
317
|
+
def __init__(self):
|
|
318
|
+
self.processor = StringEscapeProcessor()
|
|
319
|
+
|
|
320
|
+
def create_widget(self, parent, app):
|
|
321
|
+
"""Create and return the String Escape Tool widget."""
|
|
322
|
+
return StringEscapeWidget(parent, app)
|
|
323
|
+
|
|
324
|
+
def get_default_settings(self):
|
|
325
|
+
"""Return default settings for String Escape Tool."""
|
|
326
|
+
return {
|
|
327
|
+
"format": "json",
|
|
328
|
+
"mode": "escape",
|
|
329
|
+
"plus_spaces": False
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
def process_text(self, input_text, format_type, mode, settings=None):
|
|
333
|
+
"""Process text using the specified format and mode."""
|
|
334
|
+
return StringEscapeProcessor.process_text(input_text, format_type, mode, settings)
|
|
335
|
+
|
|
336
|
+
|
|
337
|
+
# BaseTool-compatible wrapper
|
|
338
|
+
try:
|
|
339
|
+
from tools.base_tool import ToolWithOptions
|
|
340
|
+
from typing import Dict, Any
|
|
341
|
+
|
|
342
|
+
class StringEscapeToolV2(ToolWithOptions):
|
|
343
|
+
"""
|
|
344
|
+
BaseTool-compatible version of StringEscapeTool.
|
|
345
|
+
"""
|
|
346
|
+
|
|
347
|
+
TOOL_NAME = "String Escape Tool"
|
|
348
|
+
TOOL_DESCRIPTION = "Escape/unescape strings for JSON, HTML, URL, XML"
|
|
349
|
+
TOOL_VERSION = "2.0.0"
|
|
350
|
+
|
|
351
|
+
OPTIONS = [
|
|
352
|
+
("JSON Escape", "json_escape"),
|
|
353
|
+
("JSON Unescape", "json_unescape"),
|
|
354
|
+
("HTML Escape", "html_escape"),
|
|
355
|
+
("HTML Unescape", "html_unescape"),
|
|
356
|
+
("URL Encode", "url_encode"),
|
|
357
|
+
("URL Decode", "url_decode"),
|
|
358
|
+
("XML Escape", "xml_escape"),
|
|
359
|
+
("XML Unescape", "xml_unescape"),
|
|
360
|
+
]
|
|
361
|
+
OPTIONS_LABEL = "Operation"
|
|
362
|
+
USE_DROPDOWN = True
|
|
363
|
+
DEFAULT_OPTION = "json_escape"
|
|
364
|
+
|
|
365
|
+
def __init__(self):
|
|
366
|
+
super().__init__()
|
|
367
|
+
self._processor = StringEscapeProcessor()
|
|
368
|
+
|
|
369
|
+
def process_text(self, input_text: str, settings: Dict[str, Any]) -> str:
|
|
370
|
+
"""Process text using the specified escape operation."""
|
|
371
|
+
mode = settings.get("mode", "json_escape")
|
|
372
|
+
|
|
373
|
+
if mode == "json_escape":
|
|
374
|
+
return StringEscapeProcessor.json_escape(input_text)
|
|
375
|
+
elif mode == "json_unescape":
|
|
376
|
+
return StringEscapeProcessor.json_unescape(input_text)
|
|
377
|
+
elif mode == "html_escape":
|
|
378
|
+
return StringEscapeProcessor.html_escape(input_text)
|
|
379
|
+
elif mode == "html_unescape":
|
|
380
|
+
return StringEscapeProcessor.html_unescape(input_text)
|
|
381
|
+
elif mode == "url_encode":
|
|
382
|
+
return StringEscapeProcessor.url_encode(input_text)
|
|
383
|
+
elif mode == "url_decode":
|
|
384
|
+
return StringEscapeProcessor.url_decode(input_text)
|
|
385
|
+
elif mode == "xml_escape":
|
|
386
|
+
return StringEscapeProcessor.xml_escape(input_text)
|
|
387
|
+
elif mode == "xml_unescape":
|
|
388
|
+
return StringEscapeProcessor.xml_unescape(input_text)
|
|
389
|
+
else:
|
|
390
|
+
return input_text
|
|
391
|
+
|
|
392
|
+
except ImportError:
|
|
393
|
+
pass
|