milenium 0.4.1__tar.gz → 0.4.2__tar.gz

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 (35) hide show
  1. {milenium-0.4.1 → milenium-0.4.2}/PKG-INFO +1 -1
  2. {milenium-0.4.1 → milenium-0.4.2}/milenium/cli.py +102 -51
  3. {milenium-0.4.1 → milenium-0.4.2}/milenium/tui.py +55 -34
  4. {milenium-0.4.1 → milenium-0.4.2}/milenium.egg-info/PKG-INFO +1 -1
  5. {milenium-0.4.1 → milenium-0.4.2}/pyproject.toml +1 -1
  6. {milenium-0.4.1 → milenium-0.4.2}/README.md +0 -0
  7. {milenium-0.4.1 → milenium-0.4.2}/milenium/__init__.py +0 -0
  8. {milenium-0.4.1 → milenium-0.4.2}/milenium/modules/__init__.py +0 -0
  9. {milenium-0.4.1 → milenium-0.4.2}/milenium/modules/aggregator.py +0 -0
  10. {milenium-0.4.1 → milenium-0.4.2}/milenium/modules/breach.py +0 -0
  11. {milenium-0.4.1 → milenium-0.4.2}/milenium/modules/breach_local.py +0 -0
  12. {milenium-0.4.1 → milenium-0.4.2}/milenium/modules/dehashed.py +0 -0
  13. {milenium-0.4.1 → milenium-0.4.2}/milenium/modules/dns_history.py +0 -0
  14. {milenium-0.4.1 → milenium-0.4.2}/milenium/modules/domain.py +0 -0
  15. {milenium-0.4.1 → milenium-0.4.2}/milenium/modules/dorker.py +0 -0
  16. {milenium-0.4.1 → milenium-0.4.2}/milenium/modules/email.py +0 -0
  17. {milenium-0.4.1 → milenium-0.4.2}/milenium/modules/hibp.py +0 -0
  18. {milenium-0.4.1 → milenium-0.4.2}/milenium/modules/ip.py +0 -0
  19. {milenium-0.4.1 → milenium-0.4.2}/milenium/modules/ip_reputation.py +0 -0
  20. {milenium-0.4.1 → milenium-0.4.2}/milenium/modules/leakcheck.py +0 -0
  21. {milenium-0.4.1 → milenium-0.4.2}/milenium/modules/logger.py +0 -0
  22. {milenium-0.4.1 → milenium-0.4.2}/milenium/modules/permutator.py +0 -0
  23. {milenium-0.4.1 → milenium-0.4.2}/milenium/modules/phone.py +0 -0
  24. {milenium-0.4.1 → milenium-0.4.2}/milenium/modules/pwned_passwords.py +0 -0
  25. {milenium-0.4.1 → milenium-0.4.2}/milenium/modules/report.py +0 -0
  26. {milenium-0.4.1 → milenium-0.4.2}/milenium/modules/shodan_lite.py +0 -0
  27. {milenium-0.4.1 → milenium-0.4.2}/milenium/modules/social.py +0 -0
  28. {milenium-0.4.1 → milenium-0.4.2}/milenium/modules/telegram_osint.py +0 -0
  29. {milenium-0.4.1 → milenium-0.4.2}/milenium/modules/username.py +0 -0
  30. {milenium-0.4.1 → milenium-0.4.2}/milenium.egg-info/SOURCES.txt +0 -0
  31. {milenium-0.4.1 → milenium-0.4.2}/milenium.egg-info/dependency_links.txt +0 -0
  32. {milenium-0.4.1 → milenium-0.4.2}/milenium.egg-info/entry_points.txt +0 -0
  33. {milenium-0.4.1 → milenium-0.4.2}/milenium.egg-info/requires.txt +0 -0
  34. {milenium-0.4.1 → milenium-0.4.2}/milenium.egg-info/top_level.txt +0 -0
  35. {milenium-0.4.1 → milenium-0.4.2}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: milenium
3
- Version: 0.4.1
3
+ Version: 0.4.2
4
4
  Summary: OSINT / dox / deanon toolkit
5
5
  Requires-Python: >=3.9
6
6
  Description-Content-Type: text/markdown
@@ -1,79 +1,106 @@
1
1
  import sys
2
+ import json
2
3
  import click
3
4
  from rich.console import Console
4
5
  from rich.table import Table
5
6
  from milenium.modules.logger import TeeLogger
6
- from milenium.modules import username, email, phone, ip, domain, breach, social, report
7
+ from milenium.modules import (
8
+ username, email, phone, ip, domain, breach, social, report,
9
+ dorker, pwned_passwords, breach_local, hibp, dehashed, leakcheck,
10
+ aggregator, shodan_lite, ip_reputation, dns_history, telegram_osint,
11
+ )
12
+ from milenium.tui import SESSION, log_result, draw
7
13
 
8
14
  console = Console()
9
15
 
16
+
10
17
  def _init_logger():
11
18
  logger = TeeLogger("milenium.log", mode="a")
12
19
  sys.stdout = logger
13
20
  return logger
14
21
 
22
+
23
+ def _track(results):
24
+ SESSION["queries"] += 1
25
+ if isinstance(results, dict):
26
+ for v in results.values():
27
+ if isinstance(v, dict) and v.get("found"):
28
+ SESSION["results"] += 1
29
+ log_result(v.get("url", "found"))
30
+
31
+
15
32
  @click.group()
16
33
  def main():
17
34
  """milenium — OSINT / dox / deanon toolkit"""
18
35
  pass
19
36
 
20
- @main.command()
21
- def tui():
22
- """Интерактивный TUI-интерфейс"""
23
- from milenium.tui import interactive
24
- interactive()
25
-
26
-
27
- @main.command()
28
- @click.argument("channel")
29
- def telegram(channel):
30
- """Парсинг публичного Telegram-канала"""
31
- logger = _init_logger()
32
- from milenium.modules import telegram_osint
33
- res = telegram_osint.check_channel(channel)
34
- for k, v in res.items():
35
- console.print(f"[bold]{k}:[/bold] {v}")
36
- logger.close()
37
37
 
38
38
  @main.command()
39
39
  @click.argument("nick")
40
- def user(nick):
41
- """Прогон никнейма по соцсетям"""
40
+ @click.option("--permutations", default=30, help="Сколько вариаций генерить")
41
+ @click.option("--dorks/--no-dorks", default=True, help="Искать через Google Dorks")
42
+ def user(nick, permutations, dorks):
43
+ """Глубокий поиск по нику + вариации + Google Dorks"""
42
44
  logger = _init_logger()
43
- results = username.check(nick)
45
+ lines = [f"=== DEEP SEARCH: {nick} ===", f"Permutations: {permutations}", ""]
46
+
47
+ console.print("[bold cyan]Генерирую вариации...[/bold cyan]")
48
+ results = username.check(nick, permutations=permutations)
49
+ _track(results)
44
50
 
45
- table = Table(title=f"Username: {nick}")
46
- table.add_column("Site")
47
- table.add_column("Status")
51
+ table = Table(title=f"Username: {nick} (+ {len(results)-1} вариаций)")
52
+ table.add_column("Вариация")
53
+ table.add_column("Сайт")
54
+ table.add_column("Статус")
48
55
  table.add_column("URL")
49
- lines = [f"Username: {nick}"]
50
56
 
51
- for site, info in results.items():
52
- status = "[green]found[/green]" if info["found"] else "[red]no[/red]"
53
- table.add_row(site, status, info["url"])
54
- lines.append(f"{site}\t{'FOUND' if info['found'] else 'NO'}\t{info['url']}")
57
+ found_count = 0
58
+ for variant, sites in results.items():
59
+ for site, info in sites.items():
60
+ if info["found"]:
61
+ table.add_row(variant, site, "[green]FOUND[/green]", info["url"])
62
+ lines.append(f"{variant}\t{site}\tFOUND\t{info['url']}")
63
+ found_count += 1
55
64
 
56
65
  console.print(table)
57
- path = report.save_text(lines, name=f"user_{nick}")
58
- console.print(f"\n[bold cyan]Отчёт сохранён:[/bold cyan] {path}")
66
+ console.print(f"[bold green]Найдено: {found_count}[/bold green]")
67
+ lines.append(f"\nTotal found: {found_count}")
68
+
69
+ if dorks:
70
+ console.print("\n[bold cyan]Ищу через Google Dorks...[/bold cyan]")
71
+ dork_results = dorker.search_nick(nick, num=10)
72
+ if dork_results:
73
+ for q, links in dork_results.items():
74
+ console.print(f"\n[bold]{q}[/bold]")
75
+ lines.append(f"\nQUERY: {q}")
76
+ for link in links:
77
+ console.print(f" {link}")
78
+ lines.append(f" {link}")
79
+ else:
80
+ console.print("[yellow]Serper API не настроен[/yellow]")
81
+
82
+ path = report.save_text(lines, name=f"deep_{nick}")
83
+ console.print(f"\n[bold cyan]Отчёт:[/bold cyan] {path}")
59
84
  console.print(f"[bold cyan]Лог:[/bold cyan] {logger.path}")
60
85
  logger.close()
61
86
 
87
+
62
88
  @main.command()
63
89
  @click.argument("mail")
64
90
  def mail(mail):
65
- """Проверка email: MX, соцсети, утечки"""
91
+ """Проверка email: MX, HIBP, Gravatar"""
66
92
  logger = _init_logger()
67
93
  results = email.check(mail)
94
+ _track(results)
68
95
  lines = [f"Email: {mail}"]
69
96
  for k, v in results.items():
70
97
  console.print(f"[bold]{k}:[/bold] {v}")
71
98
  lines.append(f"{k}: {v}")
72
99
  path = report.save_text(lines, name=f"mail_{mail.split('@')[0]}")
73
- console.print(f"\n[bold cyan]Отчёт сохранён:[/bold cyan] {path}")
74
- console.print(f"[bold cyan]Лог:[/bold cyan] {logger.path}")
100
+ console.print(f"\n[bold cyan]Отчёт:[/bold cyan] {path}")
75
101
  logger.close()
76
102
 
103
+
77
104
  @main.command()
78
105
  @click.argument("number")
79
106
  def phone_cmd(number):
@@ -85,42 +112,45 @@ def phone_cmd(number):
85
112
  console.print(f"[bold]{k}:[/bold] {v}")
86
113
  lines.append(f"{k}: {v}")
87
114
  path = report.save_text(lines, name=f"phone_{number.replace('+','')}")
88
- console.print(f"\n[bold cyan]Отчёт сохранён:[/bold cyan] {path}")
89
- console.print(f"[bold cyan]Лог:[/bold cyan] {logger.path}")
115
+ console.print(f"\n[bold cyan]Отчёт:[/bold cyan] {path}")
90
116
  logger.close()
91
117
 
118
+
92
119
  @main.command()
93
120
  @click.argument("address")
94
121
  def ip_cmd(address):
95
122
  """Гео, ASN, reverse DNS, Shodan, репутация"""
96
123
  logger = _init_logger()
97
- from milenium.modules import ip as ip_mod, shodan_lite, ip_reputation
98
- results = ip_mod.check(address)
124
+ results = ip.check(address)
99
125
  results["shodan"] = shodan_lite.check_ip(address)
100
126
  results["reputation"] = ip_reputation.check(address)
101
-
127
+ _track(results)
128
+ lines = [f"IP: {address}"]
102
129
  for k, v in results.items():
103
130
  console.print(f"[bold]{k}:[/bold] {v}")
104
- path = report.save_text([f"{k}: {v}" for k, v in results.items()], name=f"ip_{address.replace('.','_')}")
131
+ lines.append(f"{k}: {v}")
132
+ path = report.save_text(lines, name=f"ip_{address.replace('.','_')}")
105
133
  console.print(f"\n[bold cyan]Отчёт:[/bold cyan] {path}")
106
- console.print(f"[bold cyan]Лог:[/bold cyan] {logger.path}")
107
134
  logger.close()
108
135
 
136
+
109
137
  @main.command()
110
138
  @click.argument("host")
111
139
  def dom(host):
112
- """WHOIS, DNS, subdomains по домену"""
140
+ """WHOIS, DNS, subdomains, crt.sh"""
113
141
  logger = _init_logger()
114
142
  results = domain.check(host)
143
+ results["crt"] = dns_history.check(host)
144
+ _track(results)
115
145
  lines = [f"Domain: {host}"]
116
146
  for k, v in results.items():
117
147
  console.print(f"[bold]{k}:[/bold] {v}")
118
148
  lines.append(f"{k}: {v}")
119
149
  path = report.save_text(lines, name=f"dom_{host.replace('.','_')}")
120
- console.print(f"\n[bold cyan]Отчёт сохранён:[/bold cyan] {path}")
121
- console.print(f"[bold cyan]Лог:[/bold cyan] {logger.path}")
150
+ console.print(f"\n[bold cyan]Отчёт:[/bold cyan] {path}")
122
151
  logger.close()
123
152
 
153
+
124
154
  @main.command()
125
155
  @click.argument("query")
126
156
  def leaks(query):
@@ -132,32 +162,32 @@ def leaks(query):
132
162
  console.print(f"[bold]{k}:[/bold] {v}")
133
163
  lines.append(f"{k}: {v}")
134
164
  path = report.save_text(lines, name=f"leaks_{query.split('@')[0]}")
135
- console.print(f"\n[bold cyan]Отчёт сохранён:[/bold cyan] {path}")
136
- console.print(f"[bold cyan]Лог:[/bold cyan] {logger.path}")
165
+ console.print(f"\n[bold cyan]Отчёт:[/bold cyan] {path}")
137
166
  logger.close()
138
167
 
168
+
139
169
  @main.command()
140
170
  @click.argument("nick")
141
171
  def social_cmd(nick):
142
172
  """Поиск соцсетей по нику"""
143
173
  logger = _init_logger()
144
174
  results = social.check(nick)
175
+ _track(results)
145
176
  lines = [f"Social: {nick}"]
146
177
  for site, info in results.items():
147
178
  status = "FOUND" if info["found"] else "NO"
148
179
  console.print(f"[bold]{site}:[/bold] {status} — {info['url']}")
149
180
  lines.append(f"{site}\t{status}\t{info['url']}")
150
181
  path = report.save_text(lines, name=f"social_{nick}")
151
- console.print(f"\n[bold cyan]Отчёт сохранён:[/bold cyan] {path}")
152
- console.print(f"[bold cyan]Лог:[/bold cyan] {logger.path}")
182
+ console.print(f"\n[bold cyan]Отчёт:[/bold cyan] {path}")
153
183
  logger.close()
154
184
 
185
+
155
186
  @main.command()
156
187
  @click.argument("password")
157
188
  def pwned(password):
158
189
  """Проверить пароль через Pwned Passwords (бесплатно)"""
159
190
  logger = _init_logger()
160
- from milenium.modules import pwned_passwords
161
191
  res = pwned_passwords.check_password(password)
162
192
  if res.get("pwned"):
163
193
  console.print(f"[red]ПАРОЛЬ В УТЕЧКАХ[/red] — встречается {res['count']} раз")
@@ -168,6 +198,17 @@ def pwned(password):
168
198
  logger.close()
169
199
 
170
200
 
201
+ @main.command()
202
+ @click.argument("channel")
203
+ def telegram(channel):
204
+ """Парсинг публичного Telegram-канала"""
205
+ logger = _init_logger()
206
+ res = telegram_osint.check_channel(channel)
207
+ for k, v in res.items():
208
+ console.print(f"[bold]{k}:[/bold] {v}")
209
+ logger.close()
210
+
211
+
171
212
  @main.command()
172
213
  @click.option("--email", default=None)
173
214
  @click.option("--username", default=None)
@@ -177,8 +218,6 @@ def pwned(password):
177
218
  def full(email, username, phone, password, db_path):
178
219
  """Агрегатор: гоняет запрос по всем модулям"""
179
220
  logger = _init_logger()
180
- from milenium.modules import aggregator
181
- import json
182
221
  res = aggregator.run(email=email, username=username, phone=phone,
183
222
  password=password, db_path=db_path)
184
223
  console.print(json.dumps(res, indent=2, ensure_ascii=False))
@@ -187,5 +226,17 @@ def full(email, username, phone, password, db_path):
187
226
  console.print(f"[bold cyan]Лог:[/bold cyan] {logger.path}")
188
227
  logger.close()
189
228
 
229
+
230
+ @main.command()
231
+ def tui():
232
+ """Интерактивный TUI-интерфейс"""
233
+ interactive()
234
+
235
+
236
+ def interactive():
237
+ from milenium.tui import interactive as tui_interactive
238
+ tui_interactive()
239
+
240
+
190
241
  if __name__ == "__main__":
191
242
  main()
@@ -1,5 +1,5 @@
1
1
  import sys
2
- import time
2
+ from datetime import datetime
3
3
  from rich.console import Console
4
4
  from rich.layout import Layout
5
5
  from rich.panel import Panel
@@ -11,7 +11,6 @@ from rich.prompt import Prompt
11
11
 
12
12
  console = Console()
13
13
 
14
- # ASCII-арт "M" в красном стиле
15
14
  ASCII_LOGO = r"""
16
15
  [bold red]
17
16
  ███╗ ███╗ ██╗ ██╗ ███████╗ ███╗ ██╗ ██╗ ██╗ ██╗ ███╗ ███╗
@@ -25,13 +24,11 @@ ASCII_LOGO = r"""
25
24
 
26
25
  BANNER = """
27
26
  [bold red]╔══════════════════════════════════════════════════════════════════════════╗
28
- ║ [bold white]MILENIUM C2[/bold white] [red]|[/red] [bold white]FULLY DESIGNED BY[/bold white] [red]@VexxDev200[/red] ║
29
- ║ [red]|[/red] [bold white]JOIN OUR CHANNELS[/bold white] [red]|[/red] [bold white]TG:[/bold white] [red]@milenium[/red] ║
30
- ║ [red]|[/red] [bold white]DC:[/bold white] [red]milenium[/red] [red]|[/red] [bold white]STATUS:[/bold white] [green]● ONLINE[/green] ║
27
+ ║ [bold white]MILENIUM[/bold white] [red]|[/red] [bold white]DESIGNED BY[/bold white] [red]@VexxDev200[/red] ║
28
+ ║ [red]|[/red] [bold white]TG:[/bold white] [red]@milenium[/red] [red]|[/red] [bold white]DC:[/bold white] [red]milenium[/red] [red]|[/red] [bold white]STATUS:[/bold white] [green]● ONLINE[/green] ║
31
29
  ╚══════════════════════════════════════════════════════════════════════════╝[/bold red]
32
30
  """
33
31
 
34
- # Меню (только интерфейс, никаких реальных функций)
35
32
  MENU_ITEMS = [
36
33
  ("1", "user <ник>", "Поиск по соцсетям + вариации"),
37
34
  ("2", "mail <email>", "MX, HIBP, Gravatar"),
@@ -47,6 +44,23 @@ MENU_ITEMS = [
47
44
  ("Q", "exit", "Выход"),
48
45
  ]
49
46
 
47
+ SESSION = {
48
+ "start": datetime.now(),
49
+ "queries": 0,
50
+ "results": 0,
51
+ "last": [],
52
+ "db_path": None,
53
+ "db_loaded": False,
54
+ }
55
+
56
+
57
+ def log_result(text):
58
+ ts = datetime.now().strftime("%H:%M:%S")
59
+ SESSION["last"].append(f"[red]{ts}[/red] {text}")
60
+ if len(SESSION["last"]) > 15:
61
+ SESSION["last"].pop(0)
62
+
63
+
50
64
  def build_layout():
51
65
  layout = Layout()
52
66
  layout.split_column(
@@ -61,6 +75,7 @@ def build_layout():
61
75
  )
62
76
  return layout
63
77
 
78
+
64
79
  def render_header():
65
80
  logo = Text.from_markup(ASCII_LOGO)
66
81
  banner = Text.from_markup(BANNER)
@@ -68,9 +83,10 @@ def render_header():
68
83
  Align.center(logo + banner),
69
84
  border_style="red",
70
85
  title="[bold red]MILENIUM[/bold red]",
71
- subtitle="[red]v0.4.0[/red]",
86
+ subtitle="[red]v0.4.2[/red]",
72
87
  )
73
88
 
89
+
74
90
  def render_left():
75
91
  table = Table(show_header=False, box=None, padding=(0, 1))
76
92
  table.add_column("Key", style="bold red")
@@ -84,55 +100,60 @@ def render_left():
84
100
  subtitle="[red]выбери команду[/red]",
85
101
  )
86
102
 
103
+
87
104
  def render_center():
88
105
  lines = []
89
- lines.append("[bold red]=== LAYER 7 ===[/bold red]")
90
- for i in range(1, 8):
91
- lines.append(f"[red]{i}[/red] [white]module_{i}[/white]..............[red]url[/red] <port> <time>")
106
+ lines.append("[bold red]=== СТАТИСТИКА СЕССИИ ===[/bold red]")
107
+ uptime = datetime.now() - SESSION["start"]
108
+ mins, secs = divmod(int(uptime.total_seconds()), 60)
109
+ lines.append(f"[white]Uptime:[/white] [red]{mins:02d}:{secs:02d}[/red]")
110
+ lines.append(f"[white]Запросов:[/white] [red]{SESSION['queries']}[/red]")
111
+ lines.append(f"[white]Найдено:[/white] [red]{SESSION['results']}[/red]")
112
+ lines.append(f"[white]База:[/white] [red]{'LOADED' if SESSION['db_loaded'] else 'NOT LOADED'}[/red]")
92
113
  lines.append("")
93
- lines.append("[bold red]=== UDP ===[/bold red]")
94
- for i in range(1, 8):
95
- lines.append(f"[red]{i}[/red] [white]udp_{i}[/white].................[red]ip[/red] <port> <time>")
96
- lines.append("")
97
- lines.append("[bold red]=== TCP ===[/bold red]")
98
- for i in range(1, 8):
99
- lines.append(f"[red]{i}[/red] [white]tcp_{i}[/white].................[red]ip[/red] <port> <time>")
100
- lines.append("")
101
- lines.append("[bold red]=== BOTNET ===[/bold red]")
102
- for i in range(1, 8):
103
- lines.append(f"[red]{i}[/red] [white]bot_{i}[/white].................[red]ip[/red] <port> <time>")
114
+ lines.append("[bold red]=== ПОСЛЕДНИЕ РЕЗУЛЬТАТЫ ===[/bold red]")
115
+ if SESSION["last"]:
116
+ lines.extend(SESSION["last"])
117
+ else:
118
+ lines.append("[white]Пока ничего. Запусти команду.[/white]")
104
119
  return Panel(
105
120
  "\n".join(lines),
106
- title="[bold red]МОДУЛИ[/bold red]",
121
+ title="[bold red]СЕССИЯ[/bold red]",
107
122
  border_style="red",
108
123
  )
109
124
 
125
+
110
126
  def render_right():
111
127
  lines = []
112
- lines.append("[bold red]Roles Needed:[/bold red]")
128
+ lines.append("[bold red]СОСТОЯНИЕ МОДУЛЕЙ:[/bold red]")
113
129
  lines.append("")
114
- lines.append("[white]Requirements:[/white] [red](VIP)[/red]")
115
- lines.append("[white]Requirements:[/white] [red](VIP)[/red]")
116
- lines.append("[white]Requirements:[/white] [red](VIP)[/red]")
117
- lines.append("[white]Requirements:[/white] [red](BOTNET)[/red]")
118
- lines.append("[white]Requirements:[/white] [red](HOLDER)[/red]")
130
+ lines.append("[white]whois:[/white] [green]OK[/green]")
131
+ lines.append("[white]dns:[/white] [green]OK[/green]")
132
+ lines.append("[white]requests:[/white] [green]OK[/green]")
133
+ lines.append("[white]rich:[/white] [green]OK[/green]")
134
+ lines.append("[white]click:[/white] [green]OK[/green]")
135
+ lines.append("[white]phonenumbers:[/white][green]OK[/green]")
136
+ lines.append("[white]bs4:[/white] [green]OK[/green]")
119
137
  lines.append("")
120
- lines.append("[bold red]Network Status:[/bold red]")
121
- lines.append("[green]● ONLINE[/green]")
122
- lines.append("[green]● ONLINE[/green]")
123
- lines.append("[green]● ONLINE[/green]")
138
+ lines.append("[bold red]API-КЛЮЧИ:[/bold red]")
139
+ lines.append("[white]HIBP:[/white] [red]NOT SET[/red]")
140
+ lines.append("[white]DeHashed:[/white] [red]NOT SET[/red]")
141
+ lines.append("[white]LeakCheck:[/white] [red]NOT SET[/red]")
142
+ lines.append("[white]Serper:[/white] [red]NOT SET[/red]")
124
143
  return Panel(
125
144
  "\n".join(lines),
126
145
  title="[bold red]СТАТУС[/bold red]",
127
146
  border_style="red",
128
147
  )
129
148
 
149
+
130
150
  def render_footer():
131
151
  return Panel(
132
152
  Align.center("[bold red]milenium[/bold red] [white]@[/white] [red]VexxDev200[/red] [white]|[/white] [green]SYSTEM READY[/green]"),
133
153
  border_style="red",
134
154
  )
135
155
 
156
+
136
157
  def draw():
137
158
  layout = build_layout()
138
159
  layout["header"].update(render_header())
@@ -142,6 +163,7 @@ def draw():
142
163
  layout["footer"].update(render_footer())
143
164
  return layout
144
165
 
166
+
145
167
  def interactive():
146
168
  console.clear()
147
169
  with Live(draw(), refresh_per_second=4, screen=True) as live:
@@ -152,7 +174,7 @@ def interactive():
152
174
  break
153
175
  if not cmd.strip():
154
176
  continue
155
- # Выполняем реальную CLI-команду
177
+ SESSION["queries"] += 1
156
178
  import shlex
157
179
  from milenium.cli import main
158
180
  args = shlex.split(cmd)
@@ -162,7 +184,6 @@ def interactive():
162
184
  pass
163
185
  except Exception as e:
164
186
  console.print(f"[bold red]Ошибка:[/bold red] {e}")
165
- # Обновляем Live
166
187
  live.update(draw())
167
188
  except KeyboardInterrupt:
168
189
  break
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: milenium
3
- Version: 0.4.1
3
+ Version: 0.4.2
4
4
  Summary: OSINT / dox / deanon toolkit
5
5
  Requires-Python: >=3.9
6
6
  Description-Content-Type: text/markdown
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "milenium"
3
- version = "0.4.1"
3
+ version = "0.4.2"
4
4
  description = "OSINT / dox / deanon toolkit"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.9"
File without changes
File without changes
File without changes