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.
Files changed (192) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +680 -0
  3. package/bin/pomera-ai-commander.js +62 -0
  4. package/core/__init__.py +66 -0
  5. package/core/__pycache__/__init__.cpython-313.pyc +0 -0
  6. package/core/__pycache__/app_context.cpython-313.pyc +0 -0
  7. package/core/__pycache__/async_text_processor.cpython-313.pyc +0 -0
  8. package/core/__pycache__/backup_manager.cpython-313.pyc +0 -0
  9. package/core/__pycache__/backup_recovery_manager.cpython-313.pyc +0 -0
  10. package/core/__pycache__/content_hash_cache.cpython-313.pyc +0 -0
  11. package/core/__pycache__/context_menu.cpython-313.pyc +0 -0
  12. package/core/__pycache__/data_validator.cpython-313.pyc +0 -0
  13. package/core/__pycache__/database_connection_manager.cpython-313.pyc +0 -0
  14. package/core/__pycache__/database_curl_settings_manager.cpython-313.pyc +0 -0
  15. package/core/__pycache__/database_promera_ai_settings_manager.cpython-313.pyc +0 -0
  16. package/core/__pycache__/database_schema.cpython-313.pyc +0 -0
  17. package/core/__pycache__/database_schema_manager.cpython-313.pyc +0 -0
  18. package/core/__pycache__/database_settings_manager.cpython-313.pyc +0 -0
  19. package/core/__pycache__/database_settings_manager_interface.cpython-313.pyc +0 -0
  20. package/core/__pycache__/dialog_manager.cpython-313.pyc +0 -0
  21. package/core/__pycache__/efficient_line_numbers.cpython-313.pyc +0 -0
  22. package/core/__pycache__/error_handler.cpython-313.pyc +0 -0
  23. package/core/__pycache__/error_service.cpython-313.pyc +0 -0
  24. package/core/__pycache__/event_consolidator.cpython-313.pyc +0 -0
  25. package/core/__pycache__/memory_efficient_text_widget.cpython-313.pyc +0 -0
  26. package/core/__pycache__/migration_manager.cpython-313.pyc +0 -0
  27. package/core/__pycache__/migration_test_suite.cpython-313.pyc +0 -0
  28. package/core/__pycache__/migration_validator.cpython-313.pyc +0 -0
  29. package/core/__pycache__/optimized_find_replace.cpython-313.pyc +0 -0
  30. package/core/__pycache__/optimized_pattern_engine.cpython-313.pyc +0 -0
  31. package/core/__pycache__/optimized_search_highlighter.cpython-313.pyc +0 -0
  32. package/core/__pycache__/performance_monitor.cpython-313.pyc +0 -0
  33. package/core/__pycache__/persistence_manager.cpython-313.pyc +0 -0
  34. package/core/__pycache__/progressive_stats_calculator.cpython-313.pyc +0 -0
  35. package/core/__pycache__/regex_pattern_cache.cpython-313.pyc +0 -0
  36. package/core/__pycache__/regex_pattern_library.cpython-313.pyc +0 -0
  37. package/core/__pycache__/search_operation_manager.cpython-313.pyc +0 -0
  38. package/core/__pycache__/settings_defaults_registry.cpython-313.pyc +0 -0
  39. package/core/__pycache__/settings_integrity_validator.cpython-313.pyc +0 -0
  40. package/core/__pycache__/settings_serializer.cpython-313.pyc +0 -0
  41. package/core/__pycache__/settings_validator.cpython-313.pyc +0 -0
  42. package/core/__pycache__/smart_stats_calculator.cpython-313.pyc +0 -0
  43. package/core/__pycache__/statistics_update_manager.cpython-313.pyc +0 -0
  44. package/core/__pycache__/stats_config_manager.cpython-313.pyc +0 -0
  45. package/core/__pycache__/streaming_text_handler.cpython-313.pyc +0 -0
  46. package/core/__pycache__/task_scheduler.cpython-313.pyc +0 -0
  47. package/core/__pycache__/visibility_monitor.cpython-313.pyc +0 -0
  48. package/core/__pycache__/widget_cache.cpython-313.pyc +0 -0
  49. package/core/app_context.py +482 -0
  50. package/core/async_text_processor.py +422 -0
  51. package/core/backup_manager.py +656 -0
  52. package/core/backup_recovery_manager.py +1034 -0
  53. package/core/content_hash_cache.py +509 -0
  54. package/core/context_menu.py +313 -0
  55. package/core/data_validator.py +1067 -0
  56. package/core/database_connection_manager.py +745 -0
  57. package/core/database_curl_settings_manager.py +609 -0
  58. package/core/database_promera_ai_settings_manager.py +447 -0
  59. package/core/database_schema.py +412 -0
  60. package/core/database_schema_manager.py +396 -0
  61. package/core/database_settings_manager.py +1508 -0
  62. package/core/database_settings_manager_interface.py +457 -0
  63. package/core/dialog_manager.py +735 -0
  64. package/core/efficient_line_numbers.py +511 -0
  65. package/core/error_handler.py +747 -0
  66. package/core/error_service.py +431 -0
  67. package/core/event_consolidator.py +512 -0
  68. package/core/mcp/__init__.py +43 -0
  69. package/core/mcp/__pycache__/__init__.cpython-313.pyc +0 -0
  70. package/core/mcp/__pycache__/protocol.cpython-313.pyc +0 -0
  71. package/core/mcp/__pycache__/schema.cpython-313.pyc +0 -0
  72. package/core/mcp/__pycache__/server_stdio.cpython-313.pyc +0 -0
  73. package/core/mcp/__pycache__/tool_registry.cpython-313.pyc +0 -0
  74. package/core/mcp/protocol.py +288 -0
  75. package/core/mcp/schema.py +251 -0
  76. package/core/mcp/server_stdio.py +299 -0
  77. package/core/mcp/tool_registry.py +2345 -0
  78. package/core/memory_efficient_text_widget.py +712 -0
  79. package/core/migration_manager.py +915 -0
  80. package/core/migration_test_suite.py +1086 -0
  81. package/core/migration_validator.py +1144 -0
  82. package/core/optimized_find_replace.py +715 -0
  83. package/core/optimized_pattern_engine.py +424 -0
  84. package/core/optimized_search_highlighter.py +553 -0
  85. package/core/performance_monitor.py +675 -0
  86. package/core/persistence_manager.py +713 -0
  87. package/core/progressive_stats_calculator.py +632 -0
  88. package/core/regex_pattern_cache.py +530 -0
  89. package/core/regex_pattern_library.py +351 -0
  90. package/core/search_operation_manager.py +435 -0
  91. package/core/settings_defaults_registry.py +1087 -0
  92. package/core/settings_integrity_validator.py +1112 -0
  93. package/core/settings_serializer.py +558 -0
  94. package/core/settings_validator.py +1824 -0
  95. package/core/smart_stats_calculator.py +710 -0
  96. package/core/statistics_update_manager.py +619 -0
  97. package/core/stats_config_manager.py +858 -0
  98. package/core/streaming_text_handler.py +723 -0
  99. package/core/task_scheduler.py +596 -0
  100. package/core/update_pattern_library.py +169 -0
  101. package/core/visibility_monitor.py +596 -0
  102. package/core/widget_cache.py +498 -0
  103. package/mcp.json +61 -0
  104. package/package.json +57 -0
  105. package/pomera.py +7483 -0
  106. package/pomera_mcp_server.py +144 -0
  107. package/tools/__init__.py +5 -0
  108. package/tools/__pycache__/__init__.cpython-313.pyc +0 -0
  109. package/tools/__pycache__/ai_tools.cpython-313.pyc +0 -0
  110. package/tools/__pycache__/ascii_art_generator.cpython-313.pyc +0 -0
  111. package/tools/__pycache__/base64_tools.cpython-313.pyc +0 -0
  112. package/tools/__pycache__/base_tool.cpython-313.pyc +0 -0
  113. package/tools/__pycache__/case_tool.cpython-313.pyc +0 -0
  114. package/tools/__pycache__/column_tools.cpython-313.pyc +0 -0
  115. package/tools/__pycache__/cron_tool.cpython-313.pyc +0 -0
  116. package/tools/__pycache__/curl_history.cpython-313.pyc +0 -0
  117. package/tools/__pycache__/curl_processor.cpython-313.pyc +0 -0
  118. package/tools/__pycache__/curl_settings.cpython-313.pyc +0 -0
  119. package/tools/__pycache__/curl_tool.cpython-313.pyc +0 -0
  120. package/tools/__pycache__/diff_viewer.cpython-313.pyc +0 -0
  121. package/tools/__pycache__/email_extraction_tool.cpython-313.pyc +0 -0
  122. package/tools/__pycache__/email_header_analyzer.cpython-313.pyc +0 -0
  123. package/tools/__pycache__/extraction_tools.cpython-313.pyc +0 -0
  124. package/tools/__pycache__/find_replace.cpython-313.pyc +0 -0
  125. package/tools/__pycache__/folder_file_reporter.cpython-313.pyc +0 -0
  126. package/tools/__pycache__/folder_file_reporter_adapter.cpython-313.pyc +0 -0
  127. package/tools/__pycache__/generator_tools.cpython-313.pyc +0 -0
  128. package/tools/__pycache__/hash_generator.cpython-313.pyc +0 -0
  129. package/tools/__pycache__/html_tool.cpython-313.pyc +0 -0
  130. package/tools/__pycache__/huggingface_helper.cpython-313.pyc +0 -0
  131. package/tools/__pycache__/jsonxml_tool.cpython-313.pyc +0 -0
  132. package/tools/__pycache__/line_tools.cpython-313.pyc +0 -0
  133. package/tools/__pycache__/list_comparator.cpython-313.pyc +0 -0
  134. package/tools/__pycache__/markdown_tools.cpython-313.pyc +0 -0
  135. package/tools/__pycache__/mcp_widget.cpython-313.pyc +0 -0
  136. package/tools/__pycache__/notes_widget.cpython-313.pyc +0 -0
  137. package/tools/__pycache__/number_base_converter.cpython-313.pyc +0 -0
  138. package/tools/__pycache__/regex_extractor.cpython-313.pyc +0 -0
  139. package/tools/__pycache__/slug_generator.cpython-313.pyc +0 -0
  140. package/tools/__pycache__/sorter_tools.cpython-313.pyc +0 -0
  141. package/tools/__pycache__/string_escape_tool.cpython-313.pyc +0 -0
  142. package/tools/__pycache__/text_statistics_tool.cpython-313.pyc +0 -0
  143. package/tools/__pycache__/text_wrapper.cpython-313.pyc +0 -0
  144. package/tools/__pycache__/timestamp_converter.cpython-313.pyc +0 -0
  145. package/tools/__pycache__/tool_loader.cpython-313.pyc +0 -0
  146. package/tools/__pycache__/translator_tools.cpython-313.pyc +0 -0
  147. package/tools/__pycache__/url_link_extractor.cpython-313.pyc +0 -0
  148. package/tools/__pycache__/url_parser.cpython-313.pyc +0 -0
  149. package/tools/__pycache__/whitespace_tools.cpython-313.pyc +0 -0
  150. package/tools/__pycache__/word_frequency_counter.cpython-313.pyc +0 -0
  151. package/tools/ai_tools.py +2892 -0
  152. package/tools/ascii_art_generator.py +353 -0
  153. package/tools/base64_tools.py +184 -0
  154. package/tools/base_tool.py +511 -0
  155. package/tools/case_tool.py +309 -0
  156. package/tools/column_tools.py +396 -0
  157. package/tools/cron_tool.py +885 -0
  158. package/tools/curl_history.py +601 -0
  159. package/tools/curl_processor.py +1208 -0
  160. package/tools/curl_settings.py +503 -0
  161. package/tools/curl_tool.py +5467 -0
  162. package/tools/diff_viewer.py +1072 -0
  163. package/tools/email_extraction_tool.py +249 -0
  164. package/tools/email_header_analyzer.py +426 -0
  165. package/tools/extraction_tools.py +250 -0
  166. package/tools/find_replace.py +1751 -0
  167. package/tools/folder_file_reporter.py +1463 -0
  168. package/tools/folder_file_reporter_adapter.py +480 -0
  169. package/tools/generator_tools.py +1217 -0
  170. package/tools/hash_generator.py +256 -0
  171. package/tools/html_tool.py +657 -0
  172. package/tools/huggingface_helper.py +449 -0
  173. package/tools/jsonxml_tool.py +730 -0
  174. package/tools/line_tools.py +419 -0
  175. package/tools/list_comparator.py +720 -0
  176. package/tools/markdown_tools.py +562 -0
  177. package/tools/mcp_widget.py +1417 -0
  178. package/tools/notes_widget.py +973 -0
  179. package/tools/number_base_converter.py +373 -0
  180. package/tools/regex_extractor.py +572 -0
  181. package/tools/slug_generator.py +311 -0
  182. package/tools/sorter_tools.py +459 -0
  183. package/tools/string_escape_tool.py +393 -0
  184. package/tools/text_statistics_tool.py +366 -0
  185. package/tools/text_wrapper.py +431 -0
  186. package/tools/timestamp_converter.py +422 -0
  187. package/tools/tool_loader.py +710 -0
  188. package/tools/translator_tools.py +523 -0
  189. package/tools/url_link_extractor.py +262 -0
  190. package/tools/url_parser.py +205 -0
  191. package/tools/whitespace_tools.py +356 -0
  192. package/tools/word_frequency_counter.py +147 -0
@@ -0,0 +1,422 @@
1
+ """
2
+ Timestamp Converter Module - Date/time conversion utilities
3
+
4
+ This module provides timestamp conversion functionality
5
+ for the Pomera AI Commander application.
6
+
7
+ Features:
8
+ - Unix timestamp to human-readable date
9
+ - Human-readable date to Unix timestamp
10
+ - Multiple date format options
11
+ - Relative time display
12
+ """
13
+
14
+ import tkinter as tk
15
+ from tkinter import ttk
16
+ from datetime import datetime, timezone
17
+ import time
18
+ import re
19
+
20
+
21
+ class TimestampConverterProcessor:
22
+ """Timestamp converter processor."""
23
+
24
+ DATE_FORMATS = {
25
+ "iso": "%Y-%m-%dT%H:%M:%S",
26
+ "iso_date": "%Y-%m-%d",
27
+ "us": "%m/%d/%Y %I:%M:%S %p",
28
+ "us_date": "%m/%d/%Y",
29
+ "eu": "%d/%m/%Y %H:%M:%S",
30
+ "eu_date": "%d/%m/%Y",
31
+ "long": "%B %d, %Y %H:%M:%S",
32
+ "short": "%b %d, %Y %H:%M",
33
+ "rfc2822": "%a, %d %b %Y %H:%M:%S",
34
+ "custom": None
35
+ }
36
+
37
+ @staticmethod
38
+ def unix_to_datetime(timestamp, use_utc=False):
39
+ """Convert Unix timestamp to datetime object."""
40
+ try:
41
+ ts = float(timestamp)
42
+ # Handle milliseconds
43
+ if ts > 1e12:
44
+ ts = ts / 1000
45
+
46
+ if use_utc:
47
+ return datetime.fromtimestamp(ts, tz=timezone.utc)
48
+ else:
49
+ return datetime.fromtimestamp(ts)
50
+ except (ValueError, OSError) as e:
51
+ return None
52
+
53
+ @staticmethod
54
+ def datetime_to_unix(dt):
55
+ """Convert datetime object to Unix timestamp."""
56
+ return int(dt.timestamp())
57
+
58
+ @staticmethod
59
+ def format_datetime(dt, format_name="iso", custom_format=None):
60
+ """Format datetime using specified format."""
61
+ if format_name == "custom" and custom_format:
62
+ fmt = custom_format
63
+ else:
64
+ fmt = TimestampConverterProcessor.DATE_FORMATS.get(format_name, "%Y-%m-%d %H:%M:%S")
65
+
66
+ try:
67
+ return dt.strftime(fmt)
68
+ except Exception:
69
+ return str(dt)
70
+
71
+ @staticmethod
72
+ def parse_datetime(text, format_name="iso", custom_format=None):
73
+ """Parse datetime from string."""
74
+ text = text.strip()
75
+
76
+ # Try to detect Unix timestamp
77
+ if re.match(r'^\d{10,13}$', text):
78
+ ts = float(text)
79
+ if ts > 1e12:
80
+ ts = ts / 1000
81
+ return datetime.fromtimestamp(ts)
82
+
83
+ # Try specified format
84
+ if format_name == "custom" and custom_format:
85
+ fmt = custom_format
86
+ else:
87
+ fmt = TimestampConverterProcessor.DATE_FORMATS.get(format_name)
88
+
89
+ if fmt:
90
+ try:
91
+ return datetime.strptime(text, fmt)
92
+ except ValueError:
93
+ pass
94
+
95
+ # Try common formats
96
+ common_formats = [
97
+ "%Y-%m-%dT%H:%M:%S",
98
+ "%Y-%m-%d %H:%M:%S",
99
+ "%Y-%m-%d",
100
+ "%m/%d/%Y %H:%M:%S",
101
+ "%m/%d/%Y",
102
+ "%d/%m/%Y %H:%M:%S",
103
+ "%d/%m/%Y",
104
+ "%B %d, %Y",
105
+ "%b %d, %Y",
106
+ ]
107
+
108
+ for fmt in common_formats:
109
+ try:
110
+ return datetime.strptime(text, fmt)
111
+ except ValueError:
112
+ continue
113
+
114
+ return None
115
+
116
+ @staticmethod
117
+ def relative_time(dt):
118
+ """Get relative time string (e.g., '2 hours ago')."""
119
+ now = datetime.now()
120
+ diff = now - dt
121
+
122
+ seconds = diff.total_seconds()
123
+
124
+ if seconds < 0:
125
+ # Future
126
+ seconds = abs(seconds)
127
+ suffix = "from now"
128
+ else:
129
+ suffix = "ago"
130
+
131
+ if seconds < 60:
132
+ return f"{int(seconds)} seconds {suffix}"
133
+ elif seconds < 3600:
134
+ minutes = int(seconds / 60)
135
+ return f"{minutes} minute{'s' if minutes != 1 else ''} {suffix}"
136
+ elif seconds < 86400:
137
+ hours = int(seconds / 3600)
138
+ return f"{hours} hour{'s' if hours != 1 else ''} {suffix}"
139
+ elif seconds < 2592000: # 30 days
140
+ days = int(seconds / 86400)
141
+ return f"{days} day{'s' if days != 1 else ''} {suffix}"
142
+ elif seconds < 31536000: # 365 days
143
+ months = int(seconds / 2592000)
144
+ return f"{months} month{'s' if months != 1 else ''} {suffix}"
145
+ else:
146
+ years = int(seconds / 31536000)
147
+ return f"{years} year{'s' if years != 1 else ''} {suffix}"
148
+
149
+ @staticmethod
150
+ def convert_timestamp(text, input_format="unix", output_format="iso",
151
+ use_utc=False, custom_format=None, show_relative=False):
152
+ """Convert timestamp between formats."""
153
+ text = text.strip()
154
+
155
+ if not text:
156
+ return ""
157
+
158
+ # Parse input
159
+ if input_format == "unix":
160
+ dt = TimestampConverterProcessor.unix_to_datetime(text, use_utc)
161
+ else:
162
+ dt = TimestampConverterProcessor.parse_datetime(text, input_format, custom_format)
163
+
164
+ if dt is None:
165
+ return f"Error: Could not parse '{text}'"
166
+
167
+ # Format output
168
+ if output_format == "unix":
169
+ result = str(TimestampConverterProcessor.datetime_to_unix(dt))
170
+ else:
171
+ result = TimestampConverterProcessor.format_datetime(dt, output_format, custom_format)
172
+
173
+ if show_relative:
174
+ relative = TimestampConverterProcessor.relative_time(dt)
175
+ result += f" ({relative})"
176
+
177
+ return result
178
+
179
+ @staticmethod
180
+ def convert_batch(text, input_format="unix", output_format="iso",
181
+ use_utc=False, custom_format=None, show_relative=False):
182
+ """Convert multiple timestamps."""
183
+ lines = text.strip().split('\n')
184
+ results = []
185
+
186
+ for line in lines:
187
+ line = line.strip()
188
+ if line:
189
+ result = TimestampConverterProcessor.convert_timestamp(
190
+ line, input_format, output_format, use_utc, custom_format, show_relative
191
+ )
192
+ results.append(result)
193
+ else:
194
+ results.append('')
195
+
196
+ return '\n'.join(results)
197
+
198
+ @staticmethod
199
+ def get_current_timestamp():
200
+ """Get current Unix timestamp."""
201
+ return str(int(time.time()))
202
+
203
+ @staticmethod
204
+ def get_current_datetime(format_name="iso", custom_format=None):
205
+ """Get current datetime in specified format."""
206
+ return TimestampConverterProcessor.format_datetime(
207
+ datetime.now(), format_name, custom_format
208
+ )
209
+
210
+
211
+ class TimestampConverterWidget(ttk.Frame):
212
+ """Widget for timestamp converter tool."""
213
+
214
+ def __init__(self, parent, app):
215
+ super().__init__(parent)
216
+ self.app = app
217
+ self.processor = TimestampConverterProcessor()
218
+
219
+ self.input_format = tk.StringVar(value="unix")
220
+ self.output_format = tk.StringVar(value="iso")
221
+ self.use_utc = tk.BooleanVar(value=False)
222
+ self.custom_format = tk.StringVar(value="%Y-%m-%d %H:%M:%S")
223
+ self.show_relative = tk.BooleanVar(value=False)
224
+
225
+ self.create_widgets()
226
+ self.load_settings()
227
+
228
+ def create_widgets(self):
229
+ """Creates the widget interface."""
230
+ # Input format
231
+ input_frame = ttk.LabelFrame(self, text="Input Format", padding=10)
232
+ input_frame.pack(fill=tk.X, padx=5, pady=5)
233
+
234
+ formats = [("Unix Timestamp", "unix"), ("ISO 8601", "iso"),
235
+ ("US Date", "us"), ("EU Date", "eu"), ("Auto-detect", "auto")]
236
+
237
+ for i, (text, value) in enumerate(formats):
238
+ ttk.Radiobutton(input_frame, text=text,
239
+ variable=self.input_format, value=value,
240
+ command=self.on_setting_change).grid(row=i//3, column=i%3, sticky=tk.W, padx=5)
241
+
242
+ # Output format
243
+ output_frame = ttk.LabelFrame(self, text="Output Format", padding=10)
244
+ output_frame.pack(fill=tk.X, padx=5, pady=5)
245
+
246
+ output_formats = [
247
+ ("Unix Timestamp", "unix"), ("ISO 8601", "iso"), ("ISO Date", "iso_date"),
248
+ ("US Format", "us"), ("EU Format", "eu"), ("Long", "long"),
249
+ ("Short", "short"), ("RFC 2822", "rfc2822"), ("Custom", "custom")
250
+ ]
251
+
252
+ for i, (text, value) in enumerate(output_formats):
253
+ ttk.Radiobutton(output_frame, text=text,
254
+ variable=self.output_format, value=value,
255
+ command=self.on_setting_change).grid(row=i//3, column=i%3, sticky=tk.W, padx=5)
256
+
257
+ # Custom format
258
+ custom_frame = ttk.Frame(self)
259
+ custom_frame.pack(fill=tk.X, padx=5, pady=5)
260
+
261
+ ttk.Label(custom_frame, text="Custom Format:").pack(side=tk.LEFT)
262
+ ttk.Entry(custom_frame, textvariable=self.custom_format, width=25).pack(side=tk.LEFT, padx=5)
263
+ ttk.Label(custom_frame, text="(e.g., %Y-%m-%d)", font=('TkDefaultFont', 8)).pack(side=tk.LEFT)
264
+
265
+ # Options
266
+ options_frame = ttk.Frame(self)
267
+ options_frame.pack(fill=tk.X, padx=5, pady=5)
268
+
269
+ ttk.Checkbutton(options_frame, text="Use UTC",
270
+ variable=self.use_utc,
271
+ command=self.on_setting_change).pack(side=tk.LEFT, padx=10)
272
+ ttk.Checkbutton(options_frame, text="Show Relative Time",
273
+ variable=self.show_relative,
274
+ command=self.on_setting_change).pack(side=tk.LEFT, padx=10)
275
+
276
+ # Buttons
277
+ buttons_frame = ttk.Frame(self)
278
+ buttons_frame.pack(fill=tk.X, padx=5, pady=10)
279
+
280
+ ttk.Button(buttons_frame, text="Convert",
281
+ command=self.convert).pack(side=tk.LEFT, padx=5)
282
+ ttk.Button(buttons_frame, text="Insert Current Time",
283
+ command=self.insert_current).pack(side=tk.LEFT, padx=5)
284
+
285
+ def load_settings(self):
286
+ """Load settings from the application."""
287
+ settings = self.app.settings.get("tool_settings", {}).get("Timestamp Converter", {})
288
+
289
+ self.input_format.set(settings.get("input_format", "unix"))
290
+ self.output_format.set(settings.get("output_format", "iso"))
291
+ self.use_utc.set(settings.get("use_utc", False))
292
+ self.custom_format.set(settings.get("custom_format", "%Y-%m-%d %H:%M:%S"))
293
+ self.show_relative.set(settings.get("show_relative", False))
294
+
295
+ def save_settings(self):
296
+ """Save current settings to the application."""
297
+ if "Timestamp Converter" not in self.app.settings["tool_settings"]:
298
+ self.app.settings["tool_settings"]["Timestamp Converter"] = {}
299
+
300
+ self.app.settings["tool_settings"]["Timestamp Converter"].update({
301
+ "input_format": self.input_format.get(),
302
+ "output_format": self.output_format.get(),
303
+ "use_utc": self.use_utc.get(),
304
+ "custom_format": self.custom_format.get(),
305
+ "show_relative": self.show_relative.get()
306
+ })
307
+
308
+ self.app.save_settings()
309
+
310
+ def on_setting_change(self, *args):
311
+ """Handle setting changes."""
312
+ self.save_settings()
313
+
314
+ def convert(self):
315
+ """Convert timestamps."""
316
+ active_input_tab = self.app.input_tabs[self.app.input_notebook.index(self.app.input_notebook.select())]
317
+ input_text = active_input_tab.text.get("1.0", tk.END).rstrip('\n')
318
+
319
+ if not input_text.strip():
320
+ return
321
+
322
+ result = TimestampConverterProcessor.convert_batch(
323
+ input_text,
324
+ self.input_format.get(),
325
+ self.output_format.get(),
326
+ self.use_utc.get(),
327
+ self.custom_format.get(),
328
+ self.show_relative.get()
329
+ )
330
+
331
+ active_output_tab = self.app.output_tabs[self.app.output_notebook.index(self.app.output_notebook.select())]
332
+ active_output_tab.text.config(state="normal")
333
+ active_output_tab.text.delete("1.0", tk.END)
334
+ active_output_tab.text.insert("1.0", result)
335
+ active_output_tab.text.config(state="disabled")
336
+
337
+ self.app.update_all_stats()
338
+
339
+ def insert_current(self):
340
+ """Insert current timestamp."""
341
+ if self.output_format.get() == "unix":
342
+ result = TimestampConverterProcessor.get_current_timestamp()
343
+ else:
344
+ result = TimestampConverterProcessor.get_current_datetime(
345
+ self.output_format.get(), self.custom_format.get()
346
+ )
347
+
348
+ active_output_tab = self.app.output_tabs[self.app.output_notebook.index(self.app.output_notebook.select())]
349
+ active_output_tab.text.config(state="normal")
350
+ active_output_tab.text.delete("1.0", tk.END)
351
+ active_output_tab.text.insert("1.0", result)
352
+ active_output_tab.text.config(state="disabled")
353
+
354
+ self.app.update_all_stats()
355
+
356
+
357
+ class TimestampConverter:
358
+ """Main class for Timestamp Converter integration."""
359
+
360
+ def __init__(self):
361
+ self.processor = TimestampConverterProcessor()
362
+
363
+ def create_widget(self, parent, app):
364
+ """Create and return the Timestamp Converter widget."""
365
+ return TimestampConverterWidget(parent, app)
366
+
367
+ def get_default_settings(self):
368
+ """Return default settings for Timestamp Converter."""
369
+ return {
370
+ "input_format": "unix",
371
+ "output_format": "iso",
372
+ "use_utc": False,
373
+ "custom_format": "%Y-%m-%d %H:%M:%S",
374
+ "show_relative": False
375
+ }
376
+
377
+
378
+ # BaseTool-compatible wrapper
379
+ try:
380
+ from tools.base_tool import ToolWithOptions
381
+ from typing import Dict, Any
382
+
383
+ class TimestampConverterV2(ToolWithOptions):
384
+ """
385
+ BaseTool-compatible version of TimestampConverter.
386
+ """
387
+
388
+ TOOL_NAME = "Timestamp Converter"
389
+ TOOL_DESCRIPTION = "Convert between Unix timestamps and human-readable dates"
390
+ TOOL_VERSION = "2.0.0"
391
+
392
+ OPTIONS = [
393
+ ("Unix to ISO", "unix_to_iso"),
394
+ ("Unix to US Format", "unix_to_us"),
395
+ ("Unix to EU Format", "unix_to_eu"),
396
+ ("Date to Unix", "date_to_unix"),
397
+ ("Current Time", "now"),
398
+ ]
399
+ OPTIONS_LABEL = "Conversion"
400
+ USE_DROPDOWN = True
401
+ DEFAULT_OPTION = "unix_to_iso"
402
+
403
+ def process_text(self, input_text: str, settings: Dict[str, Any]) -> str:
404
+ """Process text using the specified conversion."""
405
+ mode = settings.get("mode", "unix_to_iso")
406
+
407
+ if mode == "now":
408
+ import time
409
+ return str(int(time.time()))
410
+ elif mode == "unix_to_iso":
411
+ return TimestampConverterProcessor.convert_batch(input_text, "unix", "iso")
412
+ elif mode == "unix_to_us":
413
+ return TimestampConverterProcessor.convert_batch(input_text, "unix", "us")
414
+ elif mode == "unix_to_eu":
415
+ return TimestampConverterProcessor.convert_batch(input_text, "unix", "eu")
416
+ elif mode == "date_to_unix":
417
+ return TimestampConverterProcessor.convert_batch(input_text, "auto", "unix")
418
+ else:
419
+ return input_text
420
+
421
+ except ImportError:
422
+ pass