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,1217 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Generator Tools Module for Promera AI Commander
|
|
3
|
+
|
|
4
|
+
This module provides various text generation tools including:
|
|
5
|
+
- Strong Password Generator
|
|
6
|
+
- Repeating Text Generator
|
|
7
|
+
- Lorem Ipsum Generator
|
|
8
|
+
- UUID/GUID Generator
|
|
9
|
+
|
|
10
|
+
Author: Promera AI Commander
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
import tkinter as tk
|
|
14
|
+
from tkinter import ttk
|
|
15
|
+
import string
|
|
16
|
+
import random
|
|
17
|
+
import json
|
|
18
|
+
import uuid
|
|
19
|
+
import base64
|
|
20
|
+
import hashlib
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class GeneratorTools:
|
|
24
|
+
"""A class containing various text generation tools."""
|
|
25
|
+
|
|
26
|
+
def __init__(self):
|
|
27
|
+
"""Initialize the GeneratorTools class."""
|
|
28
|
+
self.tools = {
|
|
29
|
+
"Strong Password Generator": self.strong_password,
|
|
30
|
+
"Repeating Text Generator": self.repeating_text,
|
|
31
|
+
"Lorem Ipsum Generator": self.lorem_ipsum,
|
|
32
|
+
"UUID/GUID Generator": self.uuid_generator,
|
|
33
|
+
"Random Email Generator": self.random_email_generator
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
def get_available_tools(self):
|
|
37
|
+
"""Returns a list of available generator tools."""
|
|
38
|
+
return list(self.tools.keys())
|
|
39
|
+
|
|
40
|
+
def get_default_settings(self):
|
|
41
|
+
"""Returns default settings for all generator tools."""
|
|
42
|
+
return {
|
|
43
|
+
"Strong Password Generator": {"length": 20, "numbers": "", "symbols": "", "letters_percent": 70, "numbers_percent": 20, "symbols_percent": 10},
|
|
44
|
+
"Repeating Text Generator": {"times": 5, "separator": "+"},
|
|
45
|
+
"Lorem Ipsum Generator": {"count": 5, "type": "paragraphs", "format": "plain", "ordered": False},
|
|
46
|
+
"UUID/GUID Generator": {"version": 4, "format": "standard", "case": "lowercase", "count": 1, "namespace": "dns", "name": ""},
|
|
47
|
+
"Random Email Generator": {"count": 5, "separator_type": "list", "separator": ",", "domain_type": "random", "domain": "example.com"},
|
|
48
|
+
"ASCII Art Generator": {"font": "standard", "width": 80},
|
|
49
|
+
"Hash Generator": {"algorithms": ["md5", "sha256"], "uppercase": False},
|
|
50
|
+
"Slug Generator": {"separator": "-", "lowercase": True, "transliterate": True, "max_length": 0, "remove_stopwords": False}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
def process_text(self, input_text, tool_name, settings):
|
|
54
|
+
"""Process text using the specified generator tool."""
|
|
55
|
+
if tool_name not in self.tools:
|
|
56
|
+
return f"Error: Unknown tool '{tool_name}'"
|
|
57
|
+
|
|
58
|
+
return self.tools[tool_name](input_text, settings)
|
|
59
|
+
|
|
60
|
+
@staticmethod
|
|
61
|
+
def strong_password(input_text, settings):
|
|
62
|
+
"""Generates a strong, random password with specified character distribution."""
|
|
63
|
+
length = settings.get("length", 20)
|
|
64
|
+
numbers = settings.get("numbers", "")
|
|
65
|
+
symbols = settings.get("symbols", "")
|
|
66
|
+
letters_percent = settings.get("letters_percent", 70)
|
|
67
|
+
numbers_percent = settings.get("numbers_percent", 20)
|
|
68
|
+
symbols_percent = settings.get("symbols_percent", 10)
|
|
69
|
+
|
|
70
|
+
if not isinstance(length, int) or length <= 0:
|
|
71
|
+
return "Error: Password length must be a positive number."
|
|
72
|
+
|
|
73
|
+
# Validate percentages
|
|
74
|
+
total_percent = letters_percent + numbers_percent + symbols_percent
|
|
75
|
+
if total_percent != 100:
|
|
76
|
+
return "Error: Percentages must add up to 100%."
|
|
77
|
+
|
|
78
|
+
# Character sets
|
|
79
|
+
letters = string.ascii_letters
|
|
80
|
+
digits = string.digits
|
|
81
|
+
special_chars = string.punctuation
|
|
82
|
+
|
|
83
|
+
# Calculate character counts with ±5% approximation
|
|
84
|
+
def calculate_count(percent, total_length):
|
|
85
|
+
base_count = int((percent / 100) * total_length)
|
|
86
|
+
# Allow ±5% variation (rounded to nearest integer)
|
|
87
|
+
variation = max(1, int(0.05 * total_length))
|
|
88
|
+
min_count = max(0, base_count - variation)
|
|
89
|
+
max_count = min(total_length, base_count + variation)
|
|
90
|
+
return random.randint(min_count, max_count)
|
|
91
|
+
|
|
92
|
+
letters_count = calculate_count(letters_percent, length)
|
|
93
|
+
numbers_count = calculate_count(numbers_percent, length)
|
|
94
|
+
symbols_count = length - letters_count - numbers_count
|
|
95
|
+
|
|
96
|
+
# Ensure we don't exceed total length
|
|
97
|
+
if symbols_count < 0:
|
|
98
|
+
# Adjust if we went over
|
|
99
|
+
excess = abs(symbols_count)
|
|
100
|
+
if letters_count >= excess:
|
|
101
|
+
letters_count -= excess
|
|
102
|
+
symbols_count = 0
|
|
103
|
+
else:
|
|
104
|
+
numbers_count -= (excess - letters_count)
|
|
105
|
+
letters_count = 0
|
|
106
|
+
symbols_count = 0
|
|
107
|
+
|
|
108
|
+
# Generate password parts
|
|
109
|
+
password_chars = []
|
|
110
|
+
|
|
111
|
+
# Add letters
|
|
112
|
+
password_chars.extend(random.choices(letters, k=letters_count))
|
|
113
|
+
|
|
114
|
+
# Add numbers
|
|
115
|
+
password_chars.extend(random.choices(digits, k=numbers_count))
|
|
116
|
+
|
|
117
|
+
# Add symbols
|
|
118
|
+
password_chars.extend(random.choices(special_chars, k=symbols_count))
|
|
119
|
+
|
|
120
|
+
# Ensure we have the exact length
|
|
121
|
+
while len(password_chars) < length:
|
|
122
|
+
password_chars.append(random.choice(letters + digits + special_chars))
|
|
123
|
+
|
|
124
|
+
# Shuffle the password
|
|
125
|
+
random.shuffle(password_chars)
|
|
126
|
+
password = ''.join(password_chars)
|
|
127
|
+
|
|
128
|
+
# Ensure included numbers and symbols are present
|
|
129
|
+
must_include = numbers + symbols
|
|
130
|
+
if must_include and len(must_include) <= length:
|
|
131
|
+
password_list = list(password)
|
|
132
|
+
for i, char in enumerate(must_include):
|
|
133
|
+
if i < len(password_list):
|
|
134
|
+
password_list[i] = char
|
|
135
|
+
random.shuffle(password_list)
|
|
136
|
+
password = "".join(password_list)
|
|
137
|
+
|
|
138
|
+
return password
|
|
139
|
+
|
|
140
|
+
@staticmethod
|
|
141
|
+
def repeating_text(input_text, settings):
|
|
142
|
+
"""Repeats the input text a specified number of times."""
|
|
143
|
+
times = settings.get("times", 5)
|
|
144
|
+
separator = settings.get("separator", "+")
|
|
145
|
+
|
|
146
|
+
if not isinstance(times, int) or times < 0:
|
|
147
|
+
return "Error: 'Times' must be a non-negative number."
|
|
148
|
+
return separator.join([input_text] * times)
|
|
149
|
+
|
|
150
|
+
@staticmethod
|
|
151
|
+
def lorem_ipsum(input_text, settings):
|
|
152
|
+
"""Generates Lorem Ipsum text in various formats."""
|
|
153
|
+
count = settings.get("count", 5)
|
|
154
|
+
text_type = settings.get("type", "paragraphs")
|
|
155
|
+
format_type = settings.get("format", "plain")
|
|
156
|
+
ordered = settings.get("ordered", False)
|
|
157
|
+
|
|
158
|
+
# Validation
|
|
159
|
+
if not isinstance(count, int) or count <= 0:
|
|
160
|
+
return "Error: Count must be a positive integer."
|
|
161
|
+
|
|
162
|
+
if format_type not in ['plain', 'html', 'markdown', 'json']:
|
|
163
|
+
return "Error: Format must be one of: 'plain', 'html', 'markdown', 'json'."
|
|
164
|
+
|
|
165
|
+
# Lorem ipsum word bank
|
|
166
|
+
lorem_words = [
|
|
167
|
+
"lorem", "ipsum", "dolor", "sit", "amet", "consectetur", "adipiscing", "elit",
|
|
168
|
+
"sed", "do", "eiusmod", "tempor", "incididunt", "ut", "labore", "et", "dolore",
|
|
169
|
+
"magna", "aliqua", "enim", "ad", "minim", "veniam", "quis", "nostrud",
|
|
170
|
+
"exercitation", "ullamco", "laboris", "nisi", "aliquip", "ex", "ea", "commodo",
|
|
171
|
+
"consequat", "duis", "aute", "irure", "in", "reprehenderit", "voluptate",
|
|
172
|
+
"velit", "esse", "cillum", "fugiat", "nulla", "pariatur", "excepteur", "sint",
|
|
173
|
+
"occaecat", "cupidatat", "non", "proident", "sunt", "culpa", "qui", "officia",
|
|
174
|
+
"deserunt", "mollit", "anim", "id", "est", "laborum", "at", "vero", "eos",
|
|
175
|
+
"accusamus", "accusantium", "doloremque", "laudantium", "totam", "rem",
|
|
176
|
+
"aperiam", "eaque", "ipsa", "quae", "ab", "illo", "inventore", "veritatis"
|
|
177
|
+
]
|
|
178
|
+
|
|
179
|
+
def generate_sentence():
|
|
180
|
+
"""Generate a single sentence."""
|
|
181
|
+
length = random.randint(8, 20)
|
|
182
|
+
words = random.choices(lorem_words, k=length)
|
|
183
|
+
words[0] = words[0].capitalize()
|
|
184
|
+
return " ".join(words) + "."
|
|
185
|
+
|
|
186
|
+
def generate_paragraph():
|
|
187
|
+
"""Generate a single paragraph."""
|
|
188
|
+
sentences = [generate_sentence() for _ in range(random.randint(3, 8))]
|
|
189
|
+
return " ".join(sentences)
|
|
190
|
+
|
|
191
|
+
# Generate content based on type
|
|
192
|
+
if text_type == "words":
|
|
193
|
+
content = random.choices(lorem_words, k=count)
|
|
194
|
+
elif text_type == "sentences":
|
|
195
|
+
content = [generate_sentence() for _ in range(count)]
|
|
196
|
+
elif text_type == "paragraphs":
|
|
197
|
+
content = [generate_paragraph() for _ in range(count)]
|
|
198
|
+
elif text_type == "bytes":
|
|
199
|
+
# Generate text up to specified byte count
|
|
200
|
+
text = ""
|
|
201
|
+
while len(text.encode('utf-8')) < count:
|
|
202
|
+
text += generate_sentence() + " "
|
|
203
|
+
content = [text[:count]]
|
|
204
|
+
else:
|
|
205
|
+
return "Error: Invalid text type."
|
|
206
|
+
|
|
207
|
+
# Format output
|
|
208
|
+
if format_type == "plain":
|
|
209
|
+
if text_type == "words":
|
|
210
|
+
return " ".join(content)
|
|
211
|
+
elif text_type == "sentences":
|
|
212
|
+
return " ".join(content)
|
|
213
|
+
elif text_type == "paragraphs":
|
|
214
|
+
return "\n\n".join(content)
|
|
215
|
+
else: # bytes
|
|
216
|
+
return content[0]
|
|
217
|
+
|
|
218
|
+
elif format_type == "html":
|
|
219
|
+
if text_type == "words":
|
|
220
|
+
return "<span>" + " ".join(content) + "</span>"
|
|
221
|
+
elif text_type == "sentences":
|
|
222
|
+
if ordered:
|
|
223
|
+
items = "".join([f"<li>{sentence}</li>" for sentence in content])
|
|
224
|
+
return f"<ol>{items}</ol>"
|
|
225
|
+
else:
|
|
226
|
+
items = "".join([f"<li>{sentence}</li>" for sentence in content])
|
|
227
|
+
return f"<ul>{items}</ul>"
|
|
228
|
+
elif text_type == "paragraphs":
|
|
229
|
+
paragraphs = "".join([f"<p>{para}</p>" for para in content])
|
|
230
|
+
return paragraphs
|
|
231
|
+
else: # bytes
|
|
232
|
+
return f"<div>{content[0]}</div>"
|
|
233
|
+
|
|
234
|
+
elif format_type == "markdown":
|
|
235
|
+
if text_type == "words":
|
|
236
|
+
return " ".join(content)
|
|
237
|
+
elif text_type == "sentences":
|
|
238
|
+
if ordered:
|
|
239
|
+
items = "\n".join([f"{i+1}. {sentence}" for i, sentence in enumerate(content)])
|
|
240
|
+
else:
|
|
241
|
+
items = "\n".join([f"- {sentence}" for sentence in content])
|
|
242
|
+
return items
|
|
243
|
+
elif text_type == "paragraphs":
|
|
244
|
+
return "\n\n".join(content)
|
|
245
|
+
else: # bytes
|
|
246
|
+
return content[0]
|
|
247
|
+
|
|
248
|
+
elif format_type == "json":
|
|
249
|
+
return json.dumps({
|
|
250
|
+
"type": text_type,
|
|
251
|
+
"count": len(content),
|
|
252
|
+
"content": content
|
|
253
|
+
}, indent=2)
|
|
254
|
+
|
|
255
|
+
return "Error: Unknown format type."
|
|
256
|
+
|
|
257
|
+
@staticmethod
|
|
258
|
+
def uuid_generator(input_text, settings):
|
|
259
|
+
"""Generates UUID/GUID in various formats and versions."""
|
|
260
|
+
version = settings.get("version", 4)
|
|
261
|
+
format_type = settings.get("format", "standard")
|
|
262
|
+
case = settings.get("case", "lowercase")
|
|
263
|
+
count = settings.get("count", 1)
|
|
264
|
+
namespace_name = settings.get("namespace", "dns")
|
|
265
|
+
name = settings.get("name", "")
|
|
266
|
+
|
|
267
|
+
# Validation
|
|
268
|
+
if not isinstance(count, int) or count <= 0:
|
|
269
|
+
return "Error: Count must be a positive integer."
|
|
270
|
+
|
|
271
|
+
if version not in [1, 3, 4, 5]:
|
|
272
|
+
return "Error: UUID version must be 1, 3, 4, or 5."
|
|
273
|
+
|
|
274
|
+
if version in [3, 5] and not name:
|
|
275
|
+
return "Error: Name is required for UUID versions 3 and 5."
|
|
276
|
+
|
|
277
|
+
# Predefined namespaces
|
|
278
|
+
namespaces = {
|
|
279
|
+
"dns": uuid.NAMESPACE_DNS,
|
|
280
|
+
"url": uuid.NAMESPACE_URL,
|
|
281
|
+
"oid": uuid.NAMESPACE_OID,
|
|
282
|
+
"x500": uuid.NAMESPACE_X500
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
def generate_single_uuid():
|
|
286
|
+
"""Generate a single UUID based on version."""
|
|
287
|
+
if version == 1:
|
|
288
|
+
return uuid.uuid1()
|
|
289
|
+
elif version == 3:
|
|
290
|
+
if namespace_name not in namespaces:
|
|
291
|
+
return None
|
|
292
|
+
return uuid.uuid3(namespaces[namespace_name], name)
|
|
293
|
+
elif version == 4:
|
|
294
|
+
return uuid.uuid4()
|
|
295
|
+
elif version == 5:
|
|
296
|
+
if namespace_name not in namespaces:
|
|
297
|
+
return None
|
|
298
|
+
return uuid.uuid5(namespaces[namespace_name], name)
|
|
299
|
+
|
|
300
|
+
def format_uuid(uuid_obj):
|
|
301
|
+
"""Format UUID according to specified format and case."""
|
|
302
|
+
if uuid_obj is None:
|
|
303
|
+
return "Error: Invalid namespace."
|
|
304
|
+
|
|
305
|
+
uuid_str = str(uuid_obj)
|
|
306
|
+
|
|
307
|
+
# Apply case formatting
|
|
308
|
+
if case == "uppercase":
|
|
309
|
+
uuid_str = uuid_str.upper()
|
|
310
|
+
elif case == "lowercase":
|
|
311
|
+
uuid_str = uuid_str.lower()
|
|
312
|
+
|
|
313
|
+
# Apply format
|
|
314
|
+
if format_type == "standard":
|
|
315
|
+
return uuid_str
|
|
316
|
+
elif format_type == "hex":
|
|
317
|
+
return uuid_str.replace("-", "")
|
|
318
|
+
elif format_type == "microsoft":
|
|
319
|
+
return "{" + uuid_str + "}"
|
|
320
|
+
elif format_type == "urn":
|
|
321
|
+
return "urn:uuid:" + uuid_str
|
|
322
|
+
elif format_type == "base64":
|
|
323
|
+
return base64.b64encode(uuid_obj.bytes).decode('ascii')
|
|
324
|
+
elif format_type == "c_array":
|
|
325
|
+
bytes_list = list(uuid_obj.bytes)
|
|
326
|
+
hex_values = [f"0x{b:02x}" for b in bytes_list]
|
|
327
|
+
# Format as C array with proper line breaks
|
|
328
|
+
formatted = "{ " + ", ".join(hex_values[:8]) + ",\n " + ", ".join(hex_values[8:]) + " }"
|
|
329
|
+
return formatted
|
|
330
|
+
elif format_type == "nil":
|
|
331
|
+
return "00000000-0000-0000-0000-000000000000"
|
|
332
|
+
else:
|
|
333
|
+
return uuid_str
|
|
334
|
+
|
|
335
|
+
# Generate UUIDs
|
|
336
|
+
results = []
|
|
337
|
+
for _ in range(count):
|
|
338
|
+
if format_type == "nil":
|
|
339
|
+
# Special case for nil UUID
|
|
340
|
+
nil_uuid = uuid.UUID('00000000-0000-0000-0000-000000000000')
|
|
341
|
+
results.append(format_uuid(nil_uuid))
|
|
342
|
+
else:
|
|
343
|
+
uuid_obj = generate_single_uuid()
|
|
344
|
+
if uuid_obj is None:
|
|
345
|
+
return "Error: Invalid namespace for name-based UUID."
|
|
346
|
+
results.append(format_uuid(uuid_obj))
|
|
347
|
+
|
|
348
|
+
# Return results
|
|
349
|
+
if count == 1:
|
|
350
|
+
return results[0]
|
|
351
|
+
else:
|
|
352
|
+
return "\n".join(results)
|
|
353
|
+
|
|
354
|
+
@staticmethod
|
|
355
|
+
def random_email_generator(input_text, settings):
|
|
356
|
+
"""Generates random email addresses."""
|
|
357
|
+
count = settings.get("count", 5)
|
|
358
|
+
separator_type = settings.get("separator_type", "list")
|
|
359
|
+
separator = settings.get("separator", ",")
|
|
360
|
+
domain_type = settings.get("domain_type", "random")
|
|
361
|
+
domain = settings.get("domain", "example.com")
|
|
362
|
+
|
|
363
|
+
# Validation
|
|
364
|
+
if not isinstance(count, int) or count <= 0:
|
|
365
|
+
return "Error: Count must be a positive integer."
|
|
366
|
+
|
|
367
|
+
# Common first names and last names for generating realistic emails
|
|
368
|
+
first_names = [
|
|
369
|
+
"john", "jane", "mike", "sarah", "david", "lisa", "chris", "anna", "james", "mary",
|
|
370
|
+
"robert", "jennifer", "michael", "linda", "william", "elizabeth", "richard", "barbara",
|
|
371
|
+
"joseph", "susan", "thomas", "jessica", "charles", "karen", "daniel", "nancy",
|
|
372
|
+
"matthew", "betty", "anthony", "helen", "mark", "sandra", "donald", "donna",
|
|
373
|
+
"steven", "carol", "paul", "ruth", "andrew", "sharon", "joshua", "michelle",
|
|
374
|
+
"kenneth", "laura", "kevin", "sarah", "brian", "kimberly", "george", "deborah",
|
|
375
|
+
"edward", "dorothy", "ronald", "lisa", "timothy", "nancy", "jason", "karen"
|
|
376
|
+
]
|
|
377
|
+
|
|
378
|
+
last_names = [
|
|
379
|
+
"smith", "johnson", "williams", "brown", "jones", "garcia", "miller", "davis",
|
|
380
|
+
"rodriguez", "martinez", "hernandez", "lopez", "gonzalez", "wilson", "anderson",
|
|
381
|
+
"thomas", "taylor", "moore", "jackson", "martin", "lee", "perez", "thompson",
|
|
382
|
+
"white", "harris", "sanchez", "clark", "ramirez", "lewis", "robinson", "walker",
|
|
383
|
+
"young", "allen", "king", "wright", "scott", "torres", "nguyen", "hill",
|
|
384
|
+
"flores", "green", "adams", "nelson", "baker", "hall", "rivera", "campbell",
|
|
385
|
+
"mitchell", "carter", "roberts", "gomez", "phillips", "evans", "turner", "diaz"
|
|
386
|
+
]
|
|
387
|
+
|
|
388
|
+
# Common domain names for random domain generation
|
|
389
|
+
random_domains = [
|
|
390
|
+
"gmail.com", "yahoo.com", "hotmail.com", "outlook.com", "aol.com",
|
|
391
|
+
"icloud.com", "protonmail.com", "mail.com", "zoho.com", "fastmail.com",
|
|
392
|
+
"example.com", "test.com", "demo.org", "sample.net", "placeholder.io"
|
|
393
|
+
]
|
|
394
|
+
|
|
395
|
+
def generate_single_email():
|
|
396
|
+
"""Generate a single random email address."""
|
|
397
|
+
# Generate username part
|
|
398
|
+
first = random.choice(first_names)
|
|
399
|
+
last = random.choice(last_names)
|
|
400
|
+
|
|
401
|
+
# Various username patterns
|
|
402
|
+
patterns = [
|
|
403
|
+
f"{first}.{last}",
|
|
404
|
+
f"{first}{last}",
|
|
405
|
+
f"{first}_{last}",
|
|
406
|
+
f"{first}{random.randint(1, 999)}",
|
|
407
|
+
f"{first}.{last}{random.randint(1, 99)}",
|
|
408
|
+
f"{first[0]}{last}",
|
|
409
|
+
f"{first}{last[0]}",
|
|
410
|
+
f"{first}.{last[0]}",
|
|
411
|
+
f"{first[0]}.{last}"
|
|
412
|
+
]
|
|
413
|
+
|
|
414
|
+
username = random.choice(patterns)
|
|
415
|
+
|
|
416
|
+
# Generate domain part
|
|
417
|
+
if domain_type == "random":
|
|
418
|
+
email_domain = random.choice(random_domains)
|
|
419
|
+
else:
|
|
420
|
+
email_domain = domain
|
|
421
|
+
|
|
422
|
+
return f"{username}@{email_domain}"
|
|
423
|
+
|
|
424
|
+
# Generate emails
|
|
425
|
+
emails = []
|
|
426
|
+
for _ in range(count):
|
|
427
|
+
emails.append(generate_single_email())
|
|
428
|
+
|
|
429
|
+
# Format output based on separator type
|
|
430
|
+
if separator_type == "list":
|
|
431
|
+
return "\n".join(emails)
|
|
432
|
+
else:
|
|
433
|
+
return separator.join(emails)
|
|
434
|
+
|
|
435
|
+
|
|
436
|
+
class GeneratorToolsWidget:
|
|
437
|
+
"""Widget for the Generator Tools tabbed interface."""
|
|
438
|
+
|
|
439
|
+
def __init__(self, generator_tools):
|
|
440
|
+
"""Initialize the GeneratorToolsWidget."""
|
|
441
|
+
self.generator_tools = generator_tools
|
|
442
|
+
self.main_app = None
|
|
443
|
+
|
|
444
|
+
# Variables for Strong Password Generator
|
|
445
|
+
self.pw_len_var = None
|
|
446
|
+
self.pw_num_var = None
|
|
447
|
+
self.pw_sym_var = None
|
|
448
|
+
self.pw_letters_percent_var = None
|
|
449
|
+
self.pw_numbers_percent_var = None
|
|
450
|
+
self.pw_symbols_percent_var = None
|
|
451
|
+
|
|
452
|
+
# Variables for Repeating Text Generator
|
|
453
|
+
self.repeat_times_var = None
|
|
454
|
+
self.repeat_sep_var = None
|
|
455
|
+
|
|
456
|
+
# Variables for Lorem Ipsum Generator
|
|
457
|
+
self.lorem_count_var = None
|
|
458
|
+
self.lorem_type_var = None
|
|
459
|
+
self.lorem_format_var = None
|
|
460
|
+
self.lorem_ordered_var = None
|
|
461
|
+
|
|
462
|
+
# Variables for UUID/GUID Generator
|
|
463
|
+
self.uuid_version_var = None
|
|
464
|
+
self.uuid_format_var = None
|
|
465
|
+
self.uuid_case_var = None
|
|
466
|
+
self.uuid_count_var = None
|
|
467
|
+
self.uuid_namespace_var = None
|
|
468
|
+
self.uuid_name_var = None
|
|
469
|
+
|
|
470
|
+
# Variables for Random Email Generator
|
|
471
|
+
self.email_count_var = None
|
|
472
|
+
self.email_separator_type_var = None
|
|
473
|
+
self.email_separator_var = None
|
|
474
|
+
self.email_domain_type_var = None
|
|
475
|
+
self.email_domain_var = None
|
|
476
|
+
|
|
477
|
+
def create_widget(self, parent, main_app):
|
|
478
|
+
"""Create and return the main widget."""
|
|
479
|
+
self.main_app = main_app
|
|
480
|
+
|
|
481
|
+
# Create main frame
|
|
482
|
+
main_frame = ttk.Frame(parent)
|
|
483
|
+
|
|
484
|
+
# Create notebook for tabs
|
|
485
|
+
self.notebook = ttk.Notebook(main_frame)
|
|
486
|
+
self.notebook.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)
|
|
487
|
+
|
|
488
|
+
# Create tabs
|
|
489
|
+
self.create_password_generator_tab()
|
|
490
|
+
self.create_repeating_text_tab()
|
|
491
|
+
self.create_lorem_ipsum_tab()
|
|
492
|
+
self.create_uuid_generator_tab()
|
|
493
|
+
self.create_email_generator_tab()
|
|
494
|
+
self.create_ascii_art_generator_tab()
|
|
495
|
+
self.create_hash_generator_tab()
|
|
496
|
+
self.create_slug_generator_tab()
|
|
497
|
+
|
|
498
|
+
return main_frame
|
|
499
|
+
|
|
500
|
+
def create_password_generator_tab(self):
|
|
501
|
+
"""Create the Strong Password Generator tab."""
|
|
502
|
+
tab_frame = ttk.Frame(self.notebook)
|
|
503
|
+
self.notebook.add(tab_frame, text="Strong Password Generator")
|
|
504
|
+
|
|
505
|
+
# Get current settings
|
|
506
|
+
settings = self.main_app.settings["tool_settings"].get("Generator Tools", {}).get("Strong Password Generator", {})
|
|
507
|
+
|
|
508
|
+
# Length setting
|
|
509
|
+
length_frame = ttk.Frame(tab_frame)
|
|
510
|
+
length_frame.pack(fill=tk.X, padx=10, pady=5)
|
|
511
|
+
|
|
512
|
+
ttk.Label(length_frame, text="Password Length:").pack(side=tk.LEFT)
|
|
513
|
+
self.pw_len_var = tk.StringVar(value=str(settings.get("length", 20)))
|
|
514
|
+
length_entry = ttk.Entry(length_frame, textvariable=self.pw_len_var, width=10)
|
|
515
|
+
length_entry.pack(side=tk.LEFT, padx=(5, 0))
|
|
516
|
+
|
|
517
|
+
# Character distribution sliders
|
|
518
|
+
distribution_frame = ttk.LabelFrame(tab_frame, text="Character Distribution (%)")
|
|
519
|
+
distribution_frame.pack(fill=tk.X, padx=10, pady=5)
|
|
520
|
+
|
|
521
|
+
# Letters percentage slider
|
|
522
|
+
letters_frame = ttk.Frame(distribution_frame)
|
|
523
|
+
letters_frame.pack(fill=tk.X, padx=5, pady=2)
|
|
524
|
+
|
|
525
|
+
ttk.Label(letters_frame, text="Letters:", width=12).pack(side=tk.LEFT)
|
|
526
|
+
self.pw_letters_percent_var = tk.IntVar(value=settings.get("letters_percent", 70))
|
|
527
|
+
letters_slider = ttk.Scale(letters_frame, from_=0, to=100, orient=tk.HORIZONTAL,
|
|
528
|
+
variable=self.pw_letters_percent_var, command=self.update_percentages)
|
|
529
|
+
letters_slider.pack(side=tk.LEFT, fill=tk.X, expand=True, padx=(5, 5))
|
|
530
|
+
letters_label = ttk.Label(letters_frame, text="70%", width=5)
|
|
531
|
+
letters_label.pack(side=tk.RIGHT)
|
|
532
|
+
self.pw_letters_label = letters_label
|
|
533
|
+
|
|
534
|
+
# Numbers percentage slider
|
|
535
|
+
numbers_frame = ttk.Frame(distribution_frame)
|
|
536
|
+
numbers_frame.pack(fill=tk.X, padx=5, pady=2)
|
|
537
|
+
|
|
538
|
+
ttk.Label(numbers_frame, text="Numbers:", width=12).pack(side=tk.LEFT)
|
|
539
|
+
self.pw_numbers_percent_var = tk.IntVar(value=settings.get("numbers_percent", 20))
|
|
540
|
+
numbers_slider = ttk.Scale(numbers_frame, from_=0, to=100, orient=tk.HORIZONTAL,
|
|
541
|
+
variable=self.pw_numbers_percent_var, command=self.update_percentages)
|
|
542
|
+
numbers_slider.pack(side=tk.LEFT, fill=tk.X, expand=True, padx=(5, 5))
|
|
543
|
+
numbers_label = ttk.Label(numbers_frame, text="20%", width=5)
|
|
544
|
+
numbers_label.pack(side=tk.RIGHT)
|
|
545
|
+
self.pw_numbers_label = numbers_label
|
|
546
|
+
|
|
547
|
+
# Symbols percentage slider
|
|
548
|
+
symbols_frame = ttk.Frame(distribution_frame)
|
|
549
|
+
symbols_frame.pack(fill=tk.X, padx=5, pady=2)
|
|
550
|
+
|
|
551
|
+
ttk.Label(symbols_frame, text="Symbols:", width=12).pack(side=tk.LEFT)
|
|
552
|
+
self.pw_symbols_percent_var = tk.IntVar(value=settings.get("symbols_percent", 10))
|
|
553
|
+
symbols_slider = ttk.Scale(symbols_frame, from_=0, to=100, orient=tk.HORIZONTAL,
|
|
554
|
+
variable=self.pw_symbols_percent_var, command=self.update_percentages)
|
|
555
|
+
symbols_slider.pack(side=tk.LEFT, fill=tk.X, expand=True, padx=(5, 5))
|
|
556
|
+
symbols_label = ttk.Label(symbols_frame, text="10%", width=5)
|
|
557
|
+
symbols_label.pack(side=tk.RIGHT)
|
|
558
|
+
self.pw_symbols_label = symbols_label
|
|
559
|
+
|
|
560
|
+
# Total percentage display
|
|
561
|
+
total_frame = ttk.Frame(distribution_frame)
|
|
562
|
+
total_frame.pack(fill=tk.X, padx=5, pady=2)
|
|
563
|
+
|
|
564
|
+
ttk.Label(total_frame, text="Total:", width=12, font=('TkDefaultFont', 9, 'bold')).pack(side=tk.LEFT)
|
|
565
|
+
self.pw_total_label = ttk.Label(total_frame, text="100%", width=5, font=('TkDefaultFont', 9, 'bold'))
|
|
566
|
+
self.pw_total_label.pack(side=tk.RIGHT)
|
|
567
|
+
|
|
568
|
+
# Numbers setting
|
|
569
|
+
numbers_include_frame = ttk.Frame(tab_frame)
|
|
570
|
+
numbers_include_frame.pack(fill=tk.X, padx=10, pady=5)
|
|
571
|
+
|
|
572
|
+
ttk.Label(numbers_include_frame, text="Must Include Numbers:").pack(side=tk.LEFT)
|
|
573
|
+
self.pw_num_var = tk.StringVar(value=settings.get("numbers", ""))
|
|
574
|
+
numbers_entry = ttk.Entry(numbers_include_frame, textvariable=self.pw_num_var, width=20)
|
|
575
|
+
numbers_entry.pack(side=tk.LEFT, padx=(5, 0))
|
|
576
|
+
|
|
577
|
+
# Symbols setting
|
|
578
|
+
symbols_include_frame = ttk.Frame(tab_frame)
|
|
579
|
+
symbols_include_frame.pack(fill=tk.X, padx=10, pady=5)
|
|
580
|
+
|
|
581
|
+
ttk.Label(symbols_include_frame, text="Must Include Symbols:").pack(side=tk.LEFT)
|
|
582
|
+
self.pw_sym_var = tk.StringVar(value=settings.get("symbols", ""))
|
|
583
|
+
symbols_entry = ttk.Entry(symbols_include_frame, textvariable=self.pw_sym_var, width=20)
|
|
584
|
+
symbols_entry.pack(side=tk.LEFT, padx=(5, 0))
|
|
585
|
+
|
|
586
|
+
# Generate button
|
|
587
|
+
button_frame = ttk.Frame(tab_frame)
|
|
588
|
+
button_frame.pack(fill=tk.X, padx=10, pady=10)
|
|
589
|
+
|
|
590
|
+
generate_btn = ttk.Button(button_frame, text="Generate Password",
|
|
591
|
+
command=lambda: self.generate_password())
|
|
592
|
+
generate_btn.pack(side=tk.LEFT)
|
|
593
|
+
|
|
594
|
+
# Initialize percentage display
|
|
595
|
+
self.update_percentages()
|
|
596
|
+
|
|
597
|
+
def create_repeating_text_tab(self):
|
|
598
|
+
"""Create the Repeating Text Generator tab."""
|
|
599
|
+
tab_frame = ttk.Frame(self.notebook)
|
|
600
|
+
self.notebook.add(tab_frame, text="Repeating Text Generator")
|
|
601
|
+
|
|
602
|
+
# Get current settings
|
|
603
|
+
settings = self.main_app.settings["tool_settings"].get("Generator Tools", {}).get("Repeating Text Generator", {})
|
|
604
|
+
|
|
605
|
+
# Times setting
|
|
606
|
+
times_frame = ttk.Frame(tab_frame)
|
|
607
|
+
times_frame.pack(fill=tk.X, padx=10, pady=5)
|
|
608
|
+
|
|
609
|
+
ttk.Label(times_frame, text="Repeat Times:").pack(side=tk.LEFT)
|
|
610
|
+
self.repeat_times_var = tk.StringVar(value=str(settings.get("times", 5)))
|
|
611
|
+
times_entry = ttk.Entry(times_frame, textvariable=self.repeat_times_var, width=10)
|
|
612
|
+
times_entry.pack(side=tk.LEFT, padx=(5, 0))
|
|
613
|
+
|
|
614
|
+
# Separator setting
|
|
615
|
+
separator_frame = ttk.Frame(tab_frame)
|
|
616
|
+
separator_frame.pack(fill=tk.X, padx=10, pady=5)
|
|
617
|
+
|
|
618
|
+
ttk.Label(separator_frame, text="Separator:").pack(side=tk.LEFT)
|
|
619
|
+
self.repeat_sep_var = tk.StringVar(value=settings.get("separator", "+"))
|
|
620
|
+
separator_entry = ttk.Entry(separator_frame, textvariable=self.repeat_sep_var, width=20)
|
|
621
|
+
separator_entry.pack(side=tk.LEFT, padx=(5, 0))
|
|
622
|
+
|
|
623
|
+
# Generate button
|
|
624
|
+
button_frame = ttk.Frame(tab_frame)
|
|
625
|
+
button_frame.pack(fill=tk.X, padx=10, pady=10)
|
|
626
|
+
|
|
627
|
+
repeat_btn = ttk.Button(button_frame, text="Generate Repeated Text",
|
|
628
|
+
command=lambda: self.generate_repeated_text())
|
|
629
|
+
repeat_btn.pack(side=tk.LEFT)
|
|
630
|
+
|
|
631
|
+
def create_lorem_ipsum_tab(self):
|
|
632
|
+
"""Create the Lorem Ipsum Generator tab."""
|
|
633
|
+
tab_frame = ttk.Frame(self.notebook)
|
|
634
|
+
self.notebook.add(tab_frame, text="Lorem Ipsum Generator")
|
|
635
|
+
|
|
636
|
+
# Get current settings
|
|
637
|
+
settings = self.main_app.settings["tool_settings"].get("Generator Tools", {}).get("Lorem Ipsum Generator", {})
|
|
638
|
+
|
|
639
|
+
# Count setting
|
|
640
|
+
count_frame = ttk.Frame(tab_frame)
|
|
641
|
+
count_frame.pack(fill=tk.X, padx=10, pady=5)
|
|
642
|
+
|
|
643
|
+
ttk.Label(count_frame, text="Count:").pack(side=tk.LEFT)
|
|
644
|
+
self.lorem_count_var = tk.StringVar(value=str(settings.get("count", 5)))
|
|
645
|
+
count_entry = ttk.Entry(count_frame, textvariable=self.lorem_count_var, width=10)
|
|
646
|
+
count_entry.pack(side=tk.LEFT, padx=(5, 0))
|
|
647
|
+
|
|
648
|
+
# Type selection (radio buttons)
|
|
649
|
+
type_frame = ttk.LabelFrame(tab_frame, text="Type")
|
|
650
|
+
type_frame.pack(fill=tk.X, padx=10, pady=5)
|
|
651
|
+
|
|
652
|
+
self.lorem_type_var = tk.StringVar(value=settings.get("type", "paragraphs"))
|
|
653
|
+
|
|
654
|
+
type_options = [
|
|
655
|
+
("Words", "words"),
|
|
656
|
+
("Sentences", "sentences"),
|
|
657
|
+
("Paragraphs", "paragraphs"),
|
|
658
|
+
("Bytes", "bytes")
|
|
659
|
+
]
|
|
660
|
+
|
|
661
|
+
for text, value in type_options:
|
|
662
|
+
ttk.Radiobutton(type_frame, text=text, variable=self.lorem_type_var,
|
|
663
|
+
value=value).pack(side=tk.LEFT, padx=5)
|
|
664
|
+
|
|
665
|
+
# Format selection (radio buttons)
|
|
666
|
+
format_frame = ttk.LabelFrame(tab_frame, text="Format")
|
|
667
|
+
format_frame.pack(fill=tk.X, padx=10, pady=5)
|
|
668
|
+
|
|
669
|
+
self.lorem_format_var = tk.StringVar(value=settings.get("format", "plain"))
|
|
670
|
+
|
|
671
|
+
format_options = [
|
|
672
|
+
("Plain", "plain"),
|
|
673
|
+
("HTML", "html"),
|
|
674
|
+
("Markdown", "markdown"),
|
|
675
|
+
("JSON", "json")
|
|
676
|
+
]
|
|
677
|
+
|
|
678
|
+
for text, value in format_options:
|
|
679
|
+
ttk.Radiobutton(format_frame, text=text, variable=self.lorem_format_var,
|
|
680
|
+
value=value).pack(side=tk.LEFT, padx=5)
|
|
681
|
+
|
|
682
|
+
# Ordered checkbox (for lists)
|
|
683
|
+
ordered_frame = ttk.Frame(tab_frame)
|
|
684
|
+
ordered_frame.pack(fill=tk.X, padx=10, pady=5)
|
|
685
|
+
|
|
686
|
+
self.lorem_ordered_var = tk.BooleanVar(value=settings.get("ordered", False))
|
|
687
|
+
ordered_check = ttk.Checkbutton(ordered_frame, text="Ordered (for lists)",
|
|
688
|
+
variable=self.lorem_ordered_var)
|
|
689
|
+
ordered_check.pack(side=tk.LEFT)
|
|
690
|
+
|
|
691
|
+
# Generate button
|
|
692
|
+
button_frame = ttk.Frame(tab_frame)
|
|
693
|
+
button_frame.pack(fill=tk.X, padx=10, pady=10)
|
|
694
|
+
|
|
695
|
+
lorem_btn = ttk.Button(button_frame, text="Generate",
|
|
696
|
+
command=lambda: self.generate_lorem_ipsum())
|
|
697
|
+
lorem_btn.pack(side=tk.LEFT)
|
|
698
|
+
|
|
699
|
+
def create_uuid_generator_tab(self):
|
|
700
|
+
"""Create the UUID/GUID Generator tab."""
|
|
701
|
+
tab_frame = ttk.Frame(self.notebook)
|
|
702
|
+
self.notebook.add(tab_frame, text="UUID/GUID Generator")
|
|
703
|
+
|
|
704
|
+
# Get current settings
|
|
705
|
+
settings = self.main_app.settings["tool_settings"].get("Generator Tools", {}).get("UUID/GUID Generator", {})
|
|
706
|
+
|
|
707
|
+
# Create top row frame for UUID Version and Name-based settings
|
|
708
|
+
top_row_frame = ttk.Frame(tab_frame)
|
|
709
|
+
top_row_frame.pack(fill=tk.X, padx=10, pady=5)
|
|
710
|
+
|
|
711
|
+
# UUID Version selection (left side)
|
|
712
|
+
version_frame = ttk.LabelFrame(top_row_frame, text="UUID Version")
|
|
713
|
+
version_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=(0, 5))
|
|
714
|
+
|
|
715
|
+
self.uuid_version_var = tk.IntVar(value=settings.get("version", 4))
|
|
716
|
+
|
|
717
|
+
version_options = [
|
|
718
|
+
("Version 1 (Time-based)", 1),
|
|
719
|
+
("Version 3 (MD5 Name-based)", 3),
|
|
720
|
+
("Version 4 (Random)", 4),
|
|
721
|
+
("Version 5 (SHA-1 Name-based)", 5)
|
|
722
|
+
]
|
|
723
|
+
|
|
724
|
+
for text, value in version_options:
|
|
725
|
+
ttk.Radiobutton(version_frame, text=text, variable=self.uuid_version_var,
|
|
726
|
+
value=value, command=self.update_uuid_fields).pack(anchor=tk.W, padx=5, pady=2)
|
|
727
|
+
|
|
728
|
+
# Name-based UUID settings (right side, for versions 3 and 5)
|
|
729
|
+
self.uuid_namebased_frame = ttk.LabelFrame(top_row_frame, text="Name-based Settings")
|
|
730
|
+
self.uuid_namebased_frame.pack(side=tk.RIGHT, fill=tk.BOTH, expand=True, padx=(5, 0))
|
|
731
|
+
|
|
732
|
+
# Namespace selection
|
|
733
|
+
namespace_frame = ttk.Frame(self.uuid_namebased_frame)
|
|
734
|
+
namespace_frame.pack(fill=tk.X, padx=5, pady=2)
|
|
735
|
+
|
|
736
|
+
ttk.Label(namespace_frame, text="Namespace:").pack(side=tk.LEFT)
|
|
737
|
+
self.uuid_namespace_var = tk.StringVar(value=settings.get("namespace", "dns"))
|
|
738
|
+
namespace_combo = ttk.Combobox(namespace_frame, textvariable=self.uuid_namespace_var,
|
|
739
|
+
values=["dns", "url", "oid", "x500"], state="readonly", width=15)
|
|
740
|
+
namespace_combo.pack(side=tk.LEFT, padx=(5, 0))
|
|
741
|
+
|
|
742
|
+
# Name input
|
|
743
|
+
name_frame = ttk.Frame(self.uuid_namebased_frame)
|
|
744
|
+
name_frame.pack(fill=tk.X, padx=5, pady=2)
|
|
745
|
+
|
|
746
|
+
ttk.Label(name_frame, text="Name:").pack(side=tk.LEFT)
|
|
747
|
+
self.uuid_name_var = tk.StringVar(value=settings.get("name", ""))
|
|
748
|
+
name_entry = ttk.Entry(name_frame, textvariable=self.uuid_name_var, width=25)
|
|
749
|
+
name_entry.pack(side=tk.LEFT, padx=(5, 0), fill=tk.X, expand=True)
|
|
750
|
+
|
|
751
|
+
# Output Format selection
|
|
752
|
+
format_frame = ttk.LabelFrame(tab_frame, text="Output Format")
|
|
753
|
+
format_frame.pack(fill=tk.X, padx=10, pady=5)
|
|
754
|
+
|
|
755
|
+
self.uuid_format_var = tk.StringVar(value=settings.get("format", "standard"))
|
|
756
|
+
|
|
757
|
+
format_options = [
|
|
758
|
+
("Standard (8-4-4-4-12)", "standard"),
|
|
759
|
+
("Hex (32 chars)", "hex"),
|
|
760
|
+
("Microsoft GUID {}", "microsoft"),
|
|
761
|
+
("URN format", "urn"),
|
|
762
|
+
("Base64", "base64"),
|
|
763
|
+
("C Array", "c_array"),
|
|
764
|
+
("Nil UUID", "nil")
|
|
765
|
+
]
|
|
766
|
+
|
|
767
|
+
# Create two columns for format options
|
|
768
|
+
format_left = ttk.Frame(format_frame)
|
|
769
|
+
format_left.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
|
|
770
|
+
format_right = ttk.Frame(format_frame)
|
|
771
|
+
format_right.pack(side=tk.RIGHT, fill=tk.BOTH, expand=True)
|
|
772
|
+
|
|
773
|
+
for i, (text, value) in enumerate(format_options):
|
|
774
|
+
parent = format_left if i < 4 else format_right
|
|
775
|
+
ttk.Radiobutton(parent, text=text, variable=self.uuid_format_var,
|
|
776
|
+
value=value).pack(anchor=tk.W, padx=5, pady=1)
|
|
777
|
+
|
|
778
|
+
# Case selection
|
|
779
|
+
case_frame = ttk.LabelFrame(tab_frame, text="Case")
|
|
780
|
+
case_frame.pack(fill=tk.X, padx=10, pady=5)
|
|
781
|
+
|
|
782
|
+
self.uuid_case_var = tk.StringVar(value=settings.get("case", "lowercase"))
|
|
783
|
+
|
|
784
|
+
case_options = [
|
|
785
|
+
("Lowercase", "lowercase"),
|
|
786
|
+
("Uppercase", "uppercase")
|
|
787
|
+
]
|
|
788
|
+
|
|
789
|
+
for text, value in case_options:
|
|
790
|
+
ttk.Radiobutton(case_frame, text=text, variable=self.uuid_case_var,
|
|
791
|
+
value=value).pack(side=tk.LEFT, padx=5)
|
|
792
|
+
|
|
793
|
+
# Count setting
|
|
794
|
+
count_frame = ttk.Frame(tab_frame)
|
|
795
|
+
count_frame.pack(fill=tk.X, padx=10, pady=5)
|
|
796
|
+
|
|
797
|
+
ttk.Label(count_frame, text="Count:").pack(side=tk.LEFT)
|
|
798
|
+
self.uuid_count_var = tk.StringVar(value=str(settings.get("count", 1)))
|
|
799
|
+
count_entry = ttk.Entry(count_frame, textvariable=self.uuid_count_var, width=10)
|
|
800
|
+
count_entry.pack(side=tk.LEFT, padx=(5, 0))
|
|
801
|
+
|
|
802
|
+
# Generate button
|
|
803
|
+
button_frame = ttk.Frame(tab_frame)
|
|
804
|
+
button_frame.pack(fill=tk.X, padx=10, pady=10)
|
|
805
|
+
|
|
806
|
+
uuid_btn = ttk.Button(button_frame, text="Generate",
|
|
807
|
+
command=lambda: self.generate_uuid())
|
|
808
|
+
uuid_btn.pack(side=tk.LEFT)
|
|
809
|
+
|
|
810
|
+
# Initialize field visibility
|
|
811
|
+
self.update_uuid_fields()
|
|
812
|
+
|
|
813
|
+
def create_email_generator_tab(self):
|
|
814
|
+
"""Create the Random Email Generator tab."""
|
|
815
|
+
tab_frame = ttk.Frame(self.notebook)
|
|
816
|
+
self.notebook.add(tab_frame, text="Random Email Generator")
|
|
817
|
+
|
|
818
|
+
# Get current settings
|
|
819
|
+
settings = self.main_app.settings["tool_settings"].get("Generator Tools", {}).get("Random Email Generator", {})
|
|
820
|
+
|
|
821
|
+
# Count setting
|
|
822
|
+
count_frame = ttk.Frame(tab_frame)
|
|
823
|
+
count_frame.pack(fill=tk.X, padx=10, pady=5)
|
|
824
|
+
|
|
825
|
+
ttk.Label(count_frame, text="Count:").pack(side=tk.LEFT)
|
|
826
|
+
self.email_count_var = tk.StringVar(value=str(settings.get("count", 5)))
|
|
827
|
+
count_entry = ttk.Entry(count_frame, textvariable=self.email_count_var, width=10)
|
|
828
|
+
count_entry.pack(side=tk.LEFT, padx=(5, 0))
|
|
829
|
+
|
|
830
|
+
# Separator type selection (radio buttons)
|
|
831
|
+
separator_type_frame = ttk.LabelFrame(tab_frame, text="Output Format")
|
|
832
|
+
separator_type_frame.pack(fill=tk.X, padx=10, pady=5)
|
|
833
|
+
|
|
834
|
+
self.email_separator_type_var = tk.StringVar(value=settings.get("separator_type", "list"))
|
|
835
|
+
|
|
836
|
+
separator_type_options = [
|
|
837
|
+
("List (\\n separator)", "list"),
|
|
838
|
+
("Custom Separator", "custom")
|
|
839
|
+
]
|
|
840
|
+
|
|
841
|
+
for text, value in separator_type_options:
|
|
842
|
+
ttk.Radiobutton(separator_type_frame, text=text, variable=self.email_separator_type_var,
|
|
843
|
+
value=value, command=self.update_email_separator_field).pack(side=tk.LEFT, padx=5)
|
|
844
|
+
|
|
845
|
+
# Custom separator field
|
|
846
|
+
self.email_separator_frame = ttk.Frame(tab_frame)
|
|
847
|
+
self.email_separator_frame.pack(fill=tk.X, padx=10, pady=5)
|
|
848
|
+
|
|
849
|
+
ttk.Label(self.email_separator_frame, text="Separator:").pack(side=tk.LEFT)
|
|
850
|
+
self.email_separator_var = tk.StringVar(value=settings.get("separator", ","))
|
|
851
|
+
separator_entry = ttk.Entry(self.email_separator_frame, textvariable=self.email_separator_var, width=10)
|
|
852
|
+
separator_entry.pack(side=tk.LEFT, padx=(5, 0))
|
|
853
|
+
|
|
854
|
+
# Domain type selection (radio buttons)
|
|
855
|
+
domain_type_frame = ttk.LabelFrame(tab_frame, text="Domain")
|
|
856
|
+
domain_type_frame.pack(fill=tk.X, padx=10, pady=5)
|
|
857
|
+
|
|
858
|
+
self.email_domain_type_var = tk.StringVar(value=settings.get("domain_type", "random"))
|
|
859
|
+
|
|
860
|
+
domain_type_options = [
|
|
861
|
+
("Random", "random"),
|
|
862
|
+
("Custom Domain", "custom")
|
|
863
|
+
]
|
|
864
|
+
|
|
865
|
+
for text, value in domain_type_options:
|
|
866
|
+
ttk.Radiobutton(domain_type_frame, text=text, variable=self.email_domain_type_var,
|
|
867
|
+
value=value, command=self.update_email_domain_field).pack(side=tk.LEFT, padx=5)
|
|
868
|
+
|
|
869
|
+
# Custom domain field
|
|
870
|
+
self.email_domain_frame = ttk.Frame(tab_frame)
|
|
871
|
+
self.email_domain_frame.pack(fill=tk.X, padx=10, pady=5)
|
|
872
|
+
|
|
873
|
+
ttk.Label(self.email_domain_frame, text="Domain:").pack(side=tk.LEFT)
|
|
874
|
+
self.email_domain_var = tk.StringVar(value=settings.get("domain", "example.com"))
|
|
875
|
+
domain_entry = ttk.Entry(self.email_domain_frame, textvariable=self.email_domain_var, width=30)
|
|
876
|
+
domain_entry.pack(side=tk.LEFT, padx=(5, 0))
|
|
877
|
+
|
|
878
|
+
# Generate button
|
|
879
|
+
button_frame = ttk.Frame(tab_frame)
|
|
880
|
+
button_frame.pack(fill=tk.X, padx=10, pady=10)
|
|
881
|
+
|
|
882
|
+
email_btn = ttk.Button(button_frame, text="Generate",
|
|
883
|
+
command=lambda: self.generate_emails())
|
|
884
|
+
email_btn.pack(side=tk.LEFT)
|
|
885
|
+
|
|
886
|
+
# Initialize field visibility
|
|
887
|
+
self.update_email_separator_field()
|
|
888
|
+
self.update_email_domain_field()
|
|
889
|
+
|
|
890
|
+
def update_uuid_fields(self):
|
|
891
|
+
"""Update UUID field visibility based on selected version."""
|
|
892
|
+
if hasattr(self, 'uuid_version_var') and hasattr(self, 'uuid_namebased_frame'):
|
|
893
|
+
version = self.uuid_version_var.get()
|
|
894
|
+
if version in [3, 5]:
|
|
895
|
+
# Show name-based settings for versions 3 and 5
|
|
896
|
+
self.uuid_namebased_frame.pack(side=tk.RIGHT, fill=tk.BOTH, expand=True, padx=(5, 0))
|
|
897
|
+
else:
|
|
898
|
+
# Hide name-based settings for versions 1 and 4
|
|
899
|
+
self.uuid_namebased_frame.pack_forget()
|
|
900
|
+
|
|
901
|
+
def update_email_separator_field(self):
|
|
902
|
+
"""Update email separator field visibility based on selected type."""
|
|
903
|
+
if hasattr(self, 'email_separator_type_var') and hasattr(self, 'email_separator_frame'):
|
|
904
|
+
separator_type = self.email_separator_type_var.get()
|
|
905
|
+
if separator_type == "custom":
|
|
906
|
+
# Show separator field for custom separator
|
|
907
|
+
self.email_separator_frame.pack(fill=tk.X, padx=10, pady=5)
|
|
908
|
+
else:
|
|
909
|
+
# Hide separator field for list format
|
|
910
|
+
self.email_separator_frame.pack_forget()
|
|
911
|
+
|
|
912
|
+
def update_email_domain_field(self):
|
|
913
|
+
"""Update email domain field visibility based on selected type."""
|
|
914
|
+
if hasattr(self, 'email_domain_type_var') and hasattr(self, 'email_domain_frame'):
|
|
915
|
+
domain_type = self.email_domain_type_var.get()
|
|
916
|
+
if domain_type == "custom":
|
|
917
|
+
# Show domain field for custom domain
|
|
918
|
+
self.email_domain_frame.pack(fill=tk.X, padx=10, pady=5)
|
|
919
|
+
else:
|
|
920
|
+
# Hide domain field for random domain
|
|
921
|
+
self.email_domain_frame.pack_forget()
|
|
922
|
+
|
|
923
|
+
def update_percentages(self, *args):
|
|
924
|
+
"""Update percentage labels and ensure they add up to 100%."""
|
|
925
|
+
if hasattr(self, 'pw_letters_percent_var'):
|
|
926
|
+
letters_percent = self.pw_letters_percent_var.get()
|
|
927
|
+
numbers_percent = self.pw_numbers_percent_var.get()
|
|
928
|
+
symbols_percent = self.pw_symbols_percent_var.get()
|
|
929
|
+
|
|
930
|
+
total = letters_percent + numbers_percent + symbols_percent
|
|
931
|
+
|
|
932
|
+
# Update labels
|
|
933
|
+
self.pw_letters_label.config(text=f"{letters_percent}%")
|
|
934
|
+
self.pw_numbers_label.config(text=f"{numbers_percent}%")
|
|
935
|
+
self.pw_symbols_label.config(text=f"{symbols_percent}%")
|
|
936
|
+
|
|
937
|
+
# Update total label with color coding
|
|
938
|
+
if total == 100:
|
|
939
|
+
self.pw_total_label.config(text=f"{total}%", foreground="green")
|
|
940
|
+
else:
|
|
941
|
+
self.pw_total_label.config(text=f"{total}%", foreground="red")
|
|
942
|
+
|
|
943
|
+
def generate_password(self):
|
|
944
|
+
"""Generate a password and update the output."""
|
|
945
|
+
try:
|
|
946
|
+
length = int(self.pw_len_var.get())
|
|
947
|
+
numbers = self.pw_num_var.get()
|
|
948
|
+
symbols = self.pw_sym_var.get()
|
|
949
|
+
letters_percent = self.pw_letters_percent_var.get()
|
|
950
|
+
numbers_percent = self.pw_numbers_percent_var.get()
|
|
951
|
+
symbols_percent = self.pw_symbols_percent_var.get()
|
|
952
|
+
|
|
953
|
+
settings = {
|
|
954
|
+
"length": length,
|
|
955
|
+
"numbers": numbers,
|
|
956
|
+
"symbols": symbols,
|
|
957
|
+
"letters_percent": letters_percent,
|
|
958
|
+
"numbers_percent": numbers_percent,
|
|
959
|
+
"symbols_percent": symbols_percent
|
|
960
|
+
}
|
|
961
|
+
|
|
962
|
+
result = self.generator_tools.strong_password("", settings)
|
|
963
|
+
self.main_app.update_output_text(result)
|
|
964
|
+
|
|
965
|
+
# Save settings
|
|
966
|
+
self.save_settings()
|
|
967
|
+
|
|
968
|
+
except ValueError:
|
|
969
|
+
self.main_app.update_output_text("Error: Invalid password length")
|
|
970
|
+
|
|
971
|
+
def generate_repeated_text(self):
|
|
972
|
+
"""Generate repeated text and update the output."""
|
|
973
|
+
try:
|
|
974
|
+
# Get input text
|
|
975
|
+
active_input_tab = self.main_app.input_tabs[self.main_app.input_notebook.index(self.main_app.input_notebook.select())]
|
|
976
|
+
input_text = active_input_tab.text.get("1.0", tk.END).strip()
|
|
977
|
+
|
|
978
|
+
if not input_text:
|
|
979
|
+
self.main_app.update_output_text("Error: No input text provided")
|
|
980
|
+
return
|
|
981
|
+
|
|
982
|
+
times = int(self.repeat_times_var.get())
|
|
983
|
+
separator = self.repeat_sep_var.get()
|
|
984
|
+
|
|
985
|
+
settings = {
|
|
986
|
+
"times": times,
|
|
987
|
+
"separator": separator
|
|
988
|
+
}
|
|
989
|
+
|
|
990
|
+
result = self.generator_tools.repeating_text(input_text, settings)
|
|
991
|
+
self.main_app.update_output_text(result)
|
|
992
|
+
|
|
993
|
+
# Save settings
|
|
994
|
+
self.save_settings()
|
|
995
|
+
|
|
996
|
+
except ValueError:
|
|
997
|
+
self.main_app.update_output_text("Error: Invalid repeat times value")
|
|
998
|
+
|
|
999
|
+
def generate_lorem_ipsum(self):
|
|
1000
|
+
"""Generate Lorem Ipsum text and update the output."""
|
|
1001
|
+
try:
|
|
1002
|
+
count = int(self.lorem_count_var.get())
|
|
1003
|
+
text_type = self.lorem_type_var.get()
|
|
1004
|
+
format_type = self.lorem_format_var.get()
|
|
1005
|
+
ordered = self.lorem_ordered_var.get()
|
|
1006
|
+
|
|
1007
|
+
settings = {
|
|
1008
|
+
"count": count,
|
|
1009
|
+
"type": text_type,
|
|
1010
|
+
"format": format_type,
|
|
1011
|
+
"ordered": ordered
|
|
1012
|
+
}
|
|
1013
|
+
|
|
1014
|
+
result = self.generator_tools.lorem_ipsum("", settings)
|
|
1015
|
+
self.main_app.update_output_text(result)
|
|
1016
|
+
|
|
1017
|
+
# Save settings
|
|
1018
|
+
self.save_settings()
|
|
1019
|
+
|
|
1020
|
+
except ValueError:
|
|
1021
|
+
self.main_app.update_output_text("Error: Invalid count value")
|
|
1022
|
+
|
|
1023
|
+
def generate_uuid(self):
|
|
1024
|
+
"""Generate UUID/GUID and update the output."""
|
|
1025
|
+
try:
|
|
1026
|
+
version = self.uuid_version_var.get()
|
|
1027
|
+
format_type = self.uuid_format_var.get()
|
|
1028
|
+
case = self.uuid_case_var.get()
|
|
1029
|
+
count = int(self.uuid_count_var.get())
|
|
1030
|
+
namespace = self.uuid_namespace_var.get()
|
|
1031
|
+
name = self.uuid_name_var.get()
|
|
1032
|
+
|
|
1033
|
+
settings = {
|
|
1034
|
+
"version": version,
|
|
1035
|
+
"format": format_type,
|
|
1036
|
+
"case": case,
|
|
1037
|
+
"count": count,
|
|
1038
|
+
"namespace": namespace,
|
|
1039
|
+
"name": name
|
|
1040
|
+
}
|
|
1041
|
+
|
|
1042
|
+
result = self.generator_tools.uuid_generator("", settings)
|
|
1043
|
+
self.main_app.update_output_text(result)
|
|
1044
|
+
|
|
1045
|
+
# Save settings
|
|
1046
|
+
self.save_settings()
|
|
1047
|
+
|
|
1048
|
+
except ValueError:
|
|
1049
|
+
self.main_app.update_output_text("Error: Invalid count value")
|
|
1050
|
+
|
|
1051
|
+
def generate_emails(self):
|
|
1052
|
+
"""Generate random emails and update the output."""
|
|
1053
|
+
try:
|
|
1054
|
+
count = int(self.email_count_var.get())
|
|
1055
|
+
separator_type = self.email_separator_type_var.get()
|
|
1056
|
+
separator = self.email_separator_var.get()
|
|
1057
|
+
domain_type = self.email_domain_type_var.get()
|
|
1058
|
+
domain = self.email_domain_var.get()
|
|
1059
|
+
|
|
1060
|
+
settings = {
|
|
1061
|
+
"count": count,
|
|
1062
|
+
"separator_type": separator_type,
|
|
1063
|
+
"separator": separator,
|
|
1064
|
+
"domain_type": domain_type,
|
|
1065
|
+
"domain": domain
|
|
1066
|
+
}
|
|
1067
|
+
|
|
1068
|
+
result = self.generator_tools.random_email_generator("", settings)
|
|
1069
|
+
self.main_app.update_output_text(result)
|
|
1070
|
+
|
|
1071
|
+
# Save settings
|
|
1072
|
+
self.save_settings()
|
|
1073
|
+
|
|
1074
|
+
except ValueError:
|
|
1075
|
+
self.main_app.update_output_text("Error: Invalid count value")
|
|
1076
|
+
|
|
1077
|
+
def save_settings(self):
|
|
1078
|
+
"""Save current settings to the main app."""
|
|
1079
|
+
if not self.main_app:
|
|
1080
|
+
return
|
|
1081
|
+
|
|
1082
|
+
# Ensure the Generator Tools settings exist
|
|
1083
|
+
if "Generator Tools" not in self.main_app.settings["tool_settings"]:
|
|
1084
|
+
self.main_app.settings["tool_settings"]["Generator Tools"] = {}
|
|
1085
|
+
|
|
1086
|
+
# Save Strong Password Generator settings
|
|
1087
|
+
try:
|
|
1088
|
+
self.main_app.settings["tool_settings"]["Generator Tools"]["Strong Password Generator"] = {
|
|
1089
|
+
"length": int(self.pw_len_var.get()),
|
|
1090
|
+
"numbers": self.pw_num_var.get(),
|
|
1091
|
+
"symbols": self.pw_sym_var.get(),
|
|
1092
|
+
"letters_percent": self.pw_letters_percent_var.get(),
|
|
1093
|
+
"numbers_percent": self.pw_numbers_percent_var.get(),
|
|
1094
|
+
"symbols_percent": self.pw_symbols_percent_var.get()
|
|
1095
|
+
}
|
|
1096
|
+
except (ValueError, AttributeError):
|
|
1097
|
+
pass
|
|
1098
|
+
|
|
1099
|
+
# Save Repeating Text Generator settings
|
|
1100
|
+
try:
|
|
1101
|
+
self.main_app.settings["tool_settings"]["Generator Tools"]["Repeating Text Generator"] = {
|
|
1102
|
+
"times": int(self.repeat_times_var.get()),
|
|
1103
|
+
"separator": self.repeat_sep_var.get()
|
|
1104
|
+
}
|
|
1105
|
+
except (ValueError, AttributeError):
|
|
1106
|
+
pass
|
|
1107
|
+
|
|
1108
|
+
# Save Lorem Ipsum Generator settings
|
|
1109
|
+
try:
|
|
1110
|
+
self.main_app.settings["tool_settings"]["Generator Tools"]["Lorem Ipsum Generator"] = {
|
|
1111
|
+
"count": int(self.lorem_count_var.get()),
|
|
1112
|
+
"type": self.lorem_type_var.get(),
|
|
1113
|
+
"format": self.lorem_format_var.get(),
|
|
1114
|
+
"ordered": self.lorem_ordered_var.get()
|
|
1115
|
+
}
|
|
1116
|
+
except (ValueError, AttributeError):
|
|
1117
|
+
pass
|
|
1118
|
+
|
|
1119
|
+
# Save UUID/GUID Generator settings
|
|
1120
|
+
try:
|
|
1121
|
+
self.main_app.settings["tool_settings"]["Generator Tools"]["UUID/GUID Generator"] = {
|
|
1122
|
+
"version": self.uuid_version_var.get(),
|
|
1123
|
+
"format": self.uuid_format_var.get(),
|
|
1124
|
+
"case": self.uuid_case_var.get(),
|
|
1125
|
+
"count": int(self.uuid_count_var.get()),
|
|
1126
|
+
"namespace": self.uuid_namespace_var.get(),
|
|
1127
|
+
"name": self.uuid_name_var.get()
|
|
1128
|
+
}
|
|
1129
|
+
except (ValueError, AttributeError):
|
|
1130
|
+
pass
|
|
1131
|
+
|
|
1132
|
+
# Save Random Email Generator settings
|
|
1133
|
+
try:
|
|
1134
|
+
self.main_app.settings["tool_settings"]["Generator Tools"]["Random Email Generator"] = {
|
|
1135
|
+
"count": int(self.email_count_var.get()),
|
|
1136
|
+
"separator_type": self.email_separator_type_var.get(),
|
|
1137
|
+
"separator": self.email_separator_var.get(),
|
|
1138
|
+
"domain_type": self.email_domain_type_var.get(),
|
|
1139
|
+
"domain": self.email_domain_var.get()
|
|
1140
|
+
}
|
|
1141
|
+
except (ValueError, AttributeError):
|
|
1142
|
+
pass
|
|
1143
|
+
|
|
1144
|
+
# Save ASCII Art Generator settings
|
|
1145
|
+
try:
|
|
1146
|
+
if hasattr(self.main_app, 'ascii_art_generator') and self.main_app.ascii_art_generator:
|
|
1147
|
+
if "ASCII Art Generator" not in self.main_app.settings["tool_settings"]:
|
|
1148
|
+
self.main_app.settings["tool_settings"]["ASCII Art Generator"] = {}
|
|
1149
|
+
# Settings are saved by the widget itself
|
|
1150
|
+
except (ValueError, AttributeError):
|
|
1151
|
+
pass
|
|
1152
|
+
|
|
1153
|
+
# Save Hash Generator settings
|
|
1154
|
+
try:
|
|
1155
|
+
if hasattr(self.main_app, 'hash_generator') and self.main_app.hash_generator:
|
|
1156
|
+
if "Hash Generator" not in self.main_app.settings["tool_settings"]:
|
|
1157
|
+
self.main_app.settings["tool_settings"]["Hash Generator"] = {}
|
|
1158
|
+
# Settings are saved by the widget itself
|
|
1159
|
+
except (ValueError, AttributeError):
|
|
1160
|
+
pass
|
|
1161
|
+
|
|
1162
|
+
# Save Slug Generator settings
|
|
1163
|
+
try:
|
|
1164
|
+
if hasattr(self.main_app, 'slug_generator') and self.main_app.slug_generator:
|
|
1165
|
+
if "Slug Generator" not in self.main_app.settings["tool_settings"]:
|
|
1166
|
+
self.main_app.settings["tool_settings"]["Slug Generator"] = {}
|
|
1167
|
+
# Settings are saved by the widget itself
|
|
1168
|
+
except (ValueError, AttributeError):
|
|
1169
|
+
pass
|
|
1170
|
+
|
|
1171
|
+
# Save settings to file
|
|
1172
|
+
self.main_app.save_settings()
|
|
1173
|
+
|
|
1174
|
+
def create_ascii_art_generator_tab(self):
|
|
1175
|
+
"""Create the ASCII Art Generator tab."""
|
|
1176
|
+
tab_frame = ttk.Frame(self.notebook)
|
|
1177
|
+
self.notebook.add(tab_frame, text="ASCII Art Generator")
|
|
1178
|
+
|
|
1179
|
+
try:
|
|
1180
|
+
from tools.ascii_art_generator import ASCIIArtGenerator
|
|
1181
|
+
if hasattr(self.main_app, 'ascii_art_generator') and self.main_app.ascii_art_generator:
|
|
1182
|
+
widget = self.main_app.ascii_art_generator.create_widget(tab_frame, self.main_app)
|
|
1183
|
+
widget.pack(fill=tk.BOTH, expand=True)
|
|
1184
|
+
else:
|
|
1185
|
+
ttk.Label(tab_frame, text="ASCII Art Generator module not available").pack(padx=10, pady=10)
|
|
1186
|
+
except ImportError:
|
|
1187
|
+
ttk.Label(tab_frame, text="ASCII Art Generator module not available").pack(padx=10, pady=10)
|
|
1188
|
+
|
|
1189
|
+
def create_hash_generator_tab(self):
|
|
1190
|
+
"""Create the Hash Generator tab."""
|
|
1191
|
+
tab_frame = ttk.Frame(self.notebook)
|
|
1192
|
+
self.notebook.add(tab_frame, text="Hash Generator")
|
|
1193
|
+
|
|
1194
|
+
try:
|
|
1195
|
+
from tools.hash_generator import HashGenerator
|
|
1196
|
+
if hasattr(self.main_app, 'hash_generator') and self.main_app.hash_generator:
|
|
1197
|
+
widget = self.main_app.hash_generator.create_widget(tab_frame, self.main_app)
|
|
1198
|
+
widget.pack(fill=tk.BOTH, expand=True)
|
|
1199
|
+
else:
|
|
1200
|
+
ttk.Label(tab_frame, text="Hash Generator module not available").pack(padx=10, pady=10)
|
|
1201
|
+
except ImportError:
|
|
1202
|
+
ttk.Label(tab_frame, text="Hash Generator module not available").pack(padx=10, pady=10)
|
|
1203
|
+
|
|
1204
|
+
def create_slug_generator_tab(self):
|
|
1205
|
+
"""Create the Slug Generator tab."""
|
|
1206
|
+
tab_frame = ttk.Frame(self.notebook)
|
|
1207
|
+
self.notebook.add(tab_frame, text="Slug Generator")
|
|
1208
|
+
|
|
1209
|
+
try:
|
|
1210
|
+
from tools.slug_generator import SlugGenerator
|
|
1211
|
+
if hasattr(self.main_app, 'slug_generator') and self.main_app.slug_generator:
|
|
1212
|
+
widget = self.main_app.slug_generator.create_widget(tab_frame, self.main_app)
|
|
1213
|
+
widget.pack(fill=tk.BOTH, expand=True)
|
|
1214
|
+
else:
|
|
1215
|
+
ttk.Label(tab_frame, text="Slug Generator module not available").pack(padx=10, pady=10)
|
|
1216
|
+
except ImportError:
|
|
1217
|
+
ttk.Label(tab_frame, text="Slug Generator module not available").pack(padx=10, pady=10)
|