myra-linux 0.1.0__py3-none-any.whl
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.
- Aria_office_manage.py +1985 -0
- Main_normal.py +261 -0
- aria.py +2872 -0
- aria_modules/__init__.py +1 -0
- aria_modules/aria_activation.py +335 -0
- aria_modules/aria_advanced_features.py +1269 -0
- aria_modules/aria_advanced_tools.py +1099 -0
- aria_modules/assets/about/cofounder.png +0 -0
- aria_modules/assets/about/developer.png +0 -0
- aria_modules/assets/fonts/OFL-Poppins.txt +93 -0
- aria_modules/assets/fonts/Poppins-Bold.ttf +0 -0
- aria_modules/assets/fonts/Poppins-ExtraBold.ttf +0 -0
- aria_modules/assets/fonts/Poppins-Medium.ttf +0 -0
- aria_modules/assets/fonts/Poppins-Regular.ttf +0 -0
- aria_modules/assets/fonts/Poppins-SemiBold.ttf +0 -0
- aria_modules/assets/myra_girl.png +0 -0
- aria_modules/assets/myra_logo.png +0 -0
- aria_modules/assets/splash_bg.jpg +0 -0
- aria_modules/assets/ui_reference.png +0 -0
- aria_modules/cloud_database.py +10 -0
- aria_modules/game_install.py +1056 -0
- aria_modules/gemini_rest.py +102 -0
- aria_modules/haarcascade_frontalface_default.xml +33314 -0
- aria_modules/license_client.py +250 -0
- aria_modules/minibar_aria.py +355 -0
- aria_modules/tools.py +2295 -0
- aria_ui.py +818 -0
- camera_vision_module.py +1040 -0
- linux_extra.py +240 -0
- myra/__init__.py +10 -0
- myra/__main__.py +3 -0
- myra/cli.py +141 -0
- myra/config.py +22 -0
- myra_actions.py +327 -0
- myra_apps.py +846 -0
- myra_autostart.py +170 -0
- myra_coder_integration.py +641 -0
- myra_edge_glow.py +274 -0
- myra_float_orb.py +471 -0
- myra_guardian.py +181 -0
- myra_lang.py +133 -0
- myra_linux-0.1.0.dist-info/METADATA +99 -0
- myra_linux-0.1.0.dist-info/RECORD +80 -0
- myra_linux-0.1.0.dist-info/WHEEL +5 -0
- myra_linux-0.1.0.dist-info/entry_points.txt +3 -0
- myra_linux-0.1.0.dist-info/licenses/LICENSE +36 -0
- myra_linux-0.1.0.dist-info/top_level.txt +31 -0
- myra_linux_boot.py +207 -0
- myra_linux_tools.py +314 -0
- myra_pages.py +1246 -0
- myra_prefs.py +71 -0
- myra_quick_features.py +748 -0
- myra_slot.py +39 -0
- myra_splash.py +301 -0
- myra_spotify.py +316 -0
- myra_studio.py +916 -0
- myra_ui.py +1057 -0
- normal_prompt.py +41 -0
- prompt.py +252 -0
- screen_share_module.py +447 -0
- website_builder/__init__.py +5 -0
- website_builder/agents/__init__.py +1 -0
- website_builder/agents/content_agent.py +99 -0
- website_builder/agents/generator_agent.py +249 -0
- website_builder/agents/planner_agent.py +175 -0
- website_builder/config.py +48 -0
- website_builder/database/__init__.py +1 -0
- website_builder/database/projects_db.py +47 -0
- website_builder/deploy/__init__.py +1 -0
- website_builder/deploy/github_service.py +67 -0
- website_builder/deploy/qr_display.py +130 -0
- website_builder/deploy/vercel_service.py +71 -0
- website_builder/main.py +25 -0
- website_builder/preview/__init__.py +1 -0
- website_builder/preview/preview_server.py +47 -0
- website_builder/project/__init__.py +1 -0
- website_builder/project/project_manager.py +32 -0
- website_builder/webforge_integration.py +220 -0
- website_builder/webforge_manager.py +209 -0
- whatsapp_file_sender.py +661 -0
aria_modules/__init__.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# aria_modules package
|
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""
|
|
3
|
+
TITAN v5 β Activation Window [SECURE β Backend API]
|
|
4
|
+
======================================================
|
|
5
|
+
- Firebase Admin SDK / JSON: COMPLETELY REMOVED from client
|
|
6
|
+
- Sirf license_client.py β HTTP POST β api.codeninjavik.in
|
|
7
|
+
- Config stored: C:/Users/<user>/AppData/Roaming/MYRA/license.json
|
|
8
|
+
- EXE + pip install dono mein kaam karta hai
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from myra_slot import slot as _myra_slot
|
|
12
|
+
import sys, json, threading, math, random, time, os, re
|
|
13
|
+
from datetime import datetime, timezone
|
|
14
|
+
from pathlib import Path
|
|
15
|
+
|
|
16
|
+
from PyQt5.QtWidgets import (
|
|
17
|
+
QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout,
|
|
18
|
+
QLabel, QPushButton, QLineEdit, QFrame, QStackedWidget,
|
|
19
|
+
QSizePolicy, QGraphicsOpacityEffect, QScrollArea
|
|
20
|
+
)
|
|
21
|
+
from PyQt5.QtCore import (
|
|
22
|
+
Qt, QTimer, QThread, pyqtSignal, QObject, QPropertyAnimation,
|
|
23
|
+
QEasingCurve, QRect, QSize, QEventLoop
|
|
24
|
+
)
|
|
25
|
+
from PyQt5.QtGui import (
|
|
26
|
+
QColor, QPainter, QPen, QBrush, QLinearGradient,
|
|
27
|
+
QPalette, QFont, QPixmap, QIcon
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
# ββ License client (NO Firebase) βββββββββββββββββββββββββββββββββββββββββββββ
|
|
31
|
+
from aria_modules.license_client import (
|
|
32
|
+
verify_license, load_license, save_license, clear_license,
|
|
33
|
+
is_activated, get_device_id, get_device_info,
|
|
34
|
+
LICENSE_FILE, BACKEND_URL,
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
# ββ Colors ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
38
|
+
BG = "#07091a"; BG2 = "#0c1124"; BG3 = "#111830"; PANEL = "#0f1628"
|
|
39
|
+
ACCENT = "#7c5cfc"; ACC2 = "#a080ff"; CYAN = "#00e5ff"; TEAL = "#00c9a7"
|
|
40
|
+
GOLD = "#ffc947"; TEXT = "#e2e8f8"; MUTED = "#5a6485"; MUTED2 = "#8892b0"
|
|
41
|
+
GREEN = "#00d68f"; RED = "#ff4757"; BORDER = "rgba(124,92,252,0.18)"
|
|
42
|
+
BORDER2 = "rgba(124,92,252,0.35)"
|
|
43
|
+
|
|
44
|
+
# ββ Backward compat aliases βββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
45
|
+
CONFIG_PATH = LICENSE_FILE
|
|
46
|
+
DEVICE_ID = get_device_id()
|
|
47
|
+
KEY_PATTERN = re.compile(r'^(TITAN|MYRA)-[A-Z0-9]{4}-[A-Z0-9]{4,6}$')
|
|
48
|
+
|
|
49
|
+
def validate_key_format(key: str) -> bool:
|
|
50
|
+
return bool(KEY_PATTERN.match(key.strip().upper()))
|
|
51
|
+
|
|
52
|
+
def load_config() -> dict:
|
|
53
|
+
return load_license()
|
|
54
|
+
|
|
55
|
+
def save_config(data: dict) -> None:
|
|
56
|
+
save_license(data)
|
|
57
|
+
|
|
58
|
+
def is_already_activated() -> bool:
|
|
59
|
+
cfg = load_license()
|
|
60
|
+
return bool(
|
|
61
|
+
cfg.get("access_key") and
|
|
62
|
+
cfg.get("device_id") == DEVICE_ID and
|
|
63
|
+
cfg.get("gemini_api_key") and
|
|
64
|
+
cfg.get("display_name")
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
68
|
+
# ACTIVATION WORKER
|
|
69
|
+
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
70
|
+
class ActivationWorker(QObject):
|
|
71
|
+
sig_key_valid = pyqtSignal()
|
|
72
|
+
sig_key_invalid = pyqtSignal(str)
|
|
73
|
+
sig_activated = pyqtSignal(dict)
|
|
74
|
+
|
|
75
|
+
def verify_key(self, key: str):
|
|
76
|
+
key = key.strip().upper()
|
|
77
|
+
# Already locally activated with same key?
|
|
78
|
+
cfg = load_license()
|
|
79
|
+
if (cfg.get("access_key", "").upper() == key and
|
|
80
|
+
cfg.get("device_id") == DEVICE_ID and
|
|
81
|
+
cfg.get("gemini_api_key") and cfg.get("display_name")):
|
|
82
|
+
self.sig_key_valid.emit()
|
|
83
|
+
return
|
|
84
|
+
# Format check only (backend verify on activate)
|
|
85
|
+
if not validate_key_format(key):
|
|
86
|
+
self.sig_key_invalid.emit(
|
|
87
|
+
f"β Invalid key format.\n\nRequired: TITAN-XXXX-XXXXX\nEntered: {key}"
|
|
88
|
+
)
|
|
89
|
+
return
|
|
90
|
+
self.sig_key_valid.emit()
|
|
91
|
+
|
|
92
|
+
def activate(self, key: str, gemini_key: str, display_name: str):
|
|
93
|
+
threading.Thread(
|
|
94
|
+
target=self._activate,
|
|
95
|
+
args=(key, gemini_key, display_name),
|
|
96
|
+
daemon=True
|
|
97
|
+
).start()
|
|
98
|
+
|
|
99
|
+
def _activate(self, key: str, gemini_key: str, display_name: str):
|
|
100
|
+
result = verify_license(
|
|
101
|
+
access_key=key, gemini_api_key=gemini_key, display_name=display_name
|
|
102
|
+
)
|
|
103
|
+
if result.success:
|
|
104
|
+
self.sig_activated.emit(load_license())
|
|
105
|
+
else:
|
|
106
|
+
self.sig_key_invalid.emit(result.error or "β Activation failed. Try again.")
|
|
107
|
+
|
|
108
|
+
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
109
|
+
# ANIMATED BACKGROUND
|
|
110
|
+
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
111
|
+
class AnimatedBg(QWidget):
|
|
112
|
+
def __init__(self, parent=None):
|
|
113
|
+
super().__init__(parent)
|
|
114
|
+
self._particles = [
|
|
115
|
+
{"x": random.uniform(0,1), "y": random.uniform(0,1),
|
|
116
|
+
"vx": random.uniform(-0.0003, 0.0003),
|
|
117
|
+
"vy": random.uniform(-0.0003, 0.0003),
|
|
118
|
+
"r": random.uniform(1,3), "a": random.uniform(0.2, 0.7)}
|
|
119
|
+
for _ in range(55)
|
|
120
|
+
]
|
|
121
|
+
self._t = 0
|
|
122
|
+
t = QTimer(self); t.timeout.connect(_myra_slot(self._tick)); t.start(33)
|
|
123
|
+
|
|
124
|
+
def _tick(self):
|
|
125
|
+
self._t += 1
|
|
126
|
+
for p in self._particles:
|
|
127
|
+
p["x"] = (p["x"] + p["vx"]) % 1.0
|
|
128
|
+
p["y"] = (p["y"] + p["vy"]) % 1.0
|
|
129
|
+
self.update()
|
|
130
|
+
|
|
131
|
+
def paintEvent(self, _):
|
|
132
|
+
W, H = self.width(), self.height()
|
|
133
|
+
p = QPainter(self); p.setRenderHint(QPainter.Antialiasing)
|
|
134
|
+
g = QLinearGradient(0,0,0,H); g.setColorAt(0,QColor("#07091a")); g.setColorAt(1,QColor("#0c0e1f"))
|
|
135
|
+
p.fillRect(0,0,W,H,g)
|
|
136
|
+
pen = QPen()
|
|
137
|
+
for pt in self._particles:
|
|
138
|
+
x,y = int(pt["x"]*W), int(pt["y"]*H)
|
|
139
|
+
c = QColor(ACCENT); c.setAlphaF(pt["a"]*(0.5+0.5*math.sin(self._t*0.04)))
|
|
140
|
+
pen.setColor(c); p.setPen(pen); p.setBrush(QBrush(c))
|
|
141
|
+
# β
FIX: r is a float (random.uniform) β x-r/r*2 become floats too,
|
|
142
|
+
# and PyQt5's drawEllipse(x,y,w,h) overload requires ints, so this
|
|
143
|
+
# raised TypeError on every paint (crashed the activation window).
|
|
144
|
+
r = pt["r"]; p.drawEllipse(int(x-r), int(y-r), int(r*2), int(r*2))
|
|
145
|
+
p.end()
|
|
146
|
+
|
|
147
|
+
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
148
|
+
# UI HELPERS
|
|
149
|
+
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
150
|
+
def _lbl(text, color=TEXT, size=14, bold=False, align=Qt.AlignLeft):
|
|
151
|
+
l = QLabel(text)
|
|
152
|
+
l.setStyleSheet(f"color:{color};font-size:{size}px;font-weight:{'700' if bold else '400'};background:transparent;")
|
|
153
|
+
l.setAlignment(align); return l
|
|
154
|
+
|
|
155
|
+
def _inp(placeholder="", echo=False):
|
|
156
|
+
e = QLineEdit(); e.setPlaceholderText(placeholder)
|
|
157
|
+
if echo: e.setEchoMode(QLineEdit.Password)
|
|
158
|
+
e.setStyleSheet(f"""
|
|
159
|
+
QLineEdit{{background:{BG3};border:1.5px solid {BORDER2};border-radius:10px;
|
|
160
|
+
color:{TEXT};font-size:14px;padding:10px 14px;}}
|
|
161
|
+
QLineEdit:focus{{border:1.5px solid {ACCENT};background:#131a2e;}}
|
|
162
|
+
QLineEdit::placeholder{{color:{MUTED};}}""")
|
|
163
|
+
e.setMinimumHeight(44); return e
|
|
164
|
+
|
|
165
|
+
def _btn(text, primary=True):
|
|
166
|
+
b = QPushButton(text)
|
|
167
|
+
if primary:
|
|
168
|
+
b.setStyleSheet(f"""
|
|
169
|
+
QPushButton{{background:qlineargradient(x1:0,y1:0,x2:1,y2:0,stop:0 {ACCENT},stop:1 {ACC2});
|
|
170
|
+
color:#fff;font-size:14px;font-weight:700;border:none;border-radius:10px;padding:12px 32px;}}
|
|
171
|
+
QPushButton:hover{{background:qlineargradient(x1:0,y1:0,x2:1,y2:0,stop:0 {ACC2},stop:1 {ACCENT});}}
|
|
172
|
+
QPushButton:disabled{{background:{MUTED};color:#333;}}""")
|
|
173
|
+
else:
|
|
174
|
+
b.setStyleSheet(f"QPushButton{{background:transparent;color:{MUTED2};font-size:12px;border:none;padding:6px;}}QPushButton:hover{{color:{ACC2};}}")
|
|
175
|
+
b.setCursor(Qt.PointingHandCursor); return b
|
|
176
|
+
|
|
177
|
+
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
178
|
+
# PANELS
|
|
179
|
+
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
180
|
+
class PanelWelcome(QWidget):
|
|
181
|
+
sig_next = pyqtSignal()
|
|
182
|
+
def __init__(self):
|
|
183
|
+
super().__init__(); self.setAttribute(Qt.WA_TranslucentBackground)
|
|
184
|
+
v = QVBoxLayout(self); v.setContentsMargins(40,40,40,40); v.setSpacing(18)
|
|
185
|
+
v.addStretch(1)
|
|
186
|
+
v.addWidget(_lbl("π€", ACCENT, 52, align=Qt.AlignCenter))
|
|
187
|
+
v.addWidget(_lbl("WELCOME TO", MUTED2, 13, align=Qt.AlignCenter))
|
|
188
|
+
v.addWidget(_lbl("MYRA AI ASSISTANT", ACCENT, 28, bold=True, align=Qt.AlignCenter))
|
|
189
|
+
v.addWidget(_lbl("Your intelligent desktop companion", MUTED2, 13, align=Qt.AlignCenter))
|
|
190
|
+
v.addSpacing(12)
|
|
191
|
+
v.addWidget(_lbl(f"π {BACKEND_URL}", MUTED2, 11, align=Qt.AlignCenter))
|
|
192
|
+
v.addSpacing(20)
|
|
193
|
+
btn = _btn("Get Started β"); btn.setFixedWidth(220); btn.clicked.connect(_myra_slot(self.sig_next))
|
|
194
|
+
h = QHBoxLayout(); h.addStretch(); h.addWidget(btn); h.addStretch(); v.addLayout(h)
|
|
195
|
+
v.addStretch(1)
|
|
196
|
+
|
|
197
|
+
class PanelKey(QWidget):
|
|
198
|
+
sig_back = pyqtSignal(); sig_verified = pyqtSignal(str)
|
|
199
|
+
def __init__(self):
|
|
200
|
+
super().__init__(); self.setAttribute(Qt.WA_TranslucentBackground)
|
|
201
|
+
self._worker = ActivationWorker()
|
|
202
|
+
self._worker.sig_key_valid.connect(self._on_valid)
|
|
203
|
+
self._worker.sig_key_invalid.connect(self._on_invalid)
|
|
204
|
+
v = QVBoxLayout(self); v.setContentsMargins(40,40,40,40); v.setSpacing(14)
|
|
205
|
+
v.addStretch(1)
|
|
206
|
+
v.addWidget(_lbl("π", GOLD, 36, align=Qt.AlignCenter))
|
|
207
|
+
v.addWidget(_lbl("Enter Access Key", TEXT, 22, bold=True, align=Qt.AlignCenter))
|
|
208
|
+
v.addWidget(_lbl("Format: TITAN-XXXX-XXXXX or MYRA-XXXX-XXXXX", MUTED2, 12, align=Qt.AlignCenter))
|
|
209
|
+
v.addSpacing(10)
|
|
210
|
+
self._inp = _inp("TITAN-XXXX-XXXXX"); self._inp.setAlignment(Qt.AlignCenter)
|
|
211
|
+
self._inp.textChanged.connect(_myra_slot(self._on_text)); v.addWidget(self._inp)
|
|
212
|
+
self._err = _lbl("", RED, 12, align=Qt.AlignCenter); self._err.setWordWrap(True); v.addWidget(self._err)
|
|
213
|
+
self._btn = _btn("Verify Key"); self._btn.setFixedWidth(200); self._btn.setEnabled(False)
|
|
214
|
+
self._btn.clicked.connect(_myra_slot(self._verify))
|
|
215
|
+
bh = QHBoxLayout(); bh.addStretch(); bh.addWidget(self._btn); bh.addStretch(); v.addLayout(bh)
|
|
216
|
+
back = _btn("β Back", False); back.clicked.connect(_myra_slot(self.sig_back))
|
|
217
|
+
bh2 = QHBoxLayout(); bh2.addStretch(); bh2.addWidget(back); bh2.addStretch(); v.addLayout(bh2)
|
|
218
|
+
v.addStretch(1)
|
|
219
|
+
|
|
220
|
+
def _on_text(self, t): self._err.setText(""); self._btn.setEnabled(len(t.strip()) >= 5)
|
|
221
|
+
def _verify(self):
|
|
222
|
+
self._btn.setEnabled(False); self._btn.setText("Checkingβ¦"); self._err.setText("")
|
|
223
|
+
self._worker.verify_key(self._inp.text().strip().upper())
|
|
224
|
+
def _on_valid(self):
|
|
225
|
+
self._btn.setText("Verify Key"); self._btn.setEnabled(True)
|
|
226
|
+
self.sig_verified.emit(self._inp.text().strip().upper())
|
|
227
|
+
def _on_invalid(self, msg):
|
|
228
|
+
self._err.setText(msg); self._btn.setText("Verify Key"); self._btn.setEnabled(True)
|
|
229
|
+
|
|
230
|
+
class PanelProfile(QWidget):
|
|
231
|
+
sig_back = pyqtSignal(); sig_activated = pyqtSignal(); sig_error = pyqtSignal(str)
|
|
232
|
+
def __init__(self):
|
|
233
|
+
super().__init__(); self.setAttribute(Qt.WA_TranslucentBackground)
|
|
234
|
+
self._key = ""; self._worker = ActivationWorker()
|
|
235
|
+
self._worker.sig_activated.connect(lambda _: self.sig_activated.emit())
|
|
236
|
+
self._worker.sig_key_invalid.connect(self._on_error)
|
|
237
|
+
v = QVBoxLayout(self); v.setContentsMargins(40,40,40,40); v.setSpacing(12)
|
|
238
|
+
v.addStretch(1)
|
|
239
|
+
v.addWidget(_lbl("π€", CYAN, 36, align=Qt.AlignCenter))
|
|
240
|
+
v.addWidget(_lbl("Complete Your Profile", TEXT, 20, bold=True, align=Qt.AlignCenter))
|
|
241
|
+
v.addWidget(_lbl("Fill in your details to activate.", MUTED2, 12, align=Qt.AlignCenter))
|
|
242
|
+
v.addSpacing(8)
|
|
243
|
+
v.addWidget(_lbl("Display Name", MUTED2, 12))
|
|
244
|
+
self._name = _inp("Your Name (e.g. Vikash)"); v.addWidget(self._name)
|
|
245
|
+
v.addWidget(_lbl("Gemini API Key", MUTED2, 12))
|
|
246
|
+
self._api = _inp("AIzaSy..."); v.addWidget(self._api)
|
|
247
|
+
lnk = _btn("π Get free API key β aistudio.google.com", False)
|
|
248
|
+
lnk.clicked.connect(lambda: __import__("webbrowser").open("https://aistudio.google.com/app/apikey"))
|
|
249
|
+
v.addWidget(lnk)
|
|
250
|
+
self._err = _lbl("", RED, 12, align=Qt.AlignCenter); self._err.setWordWrap(True); v.addWidget(self._err)
|
|
251
|
+
self._btn = _btn("π Activate MYRA"); self._btn.setFixedWidth(220); self._btn.clicked.connect(_myra_slot(self._activate))
|
|
252
|
+
bh = QHBoxLayout(); bh.addStretch(); bh.addWidget(self._btn); bh.addStretch(); v.addLayout(bh)
|
|
253
|
+
back = _btn("β Back", False); back.clicked.connect(_myra_slot(self.sig_back))
|
|
254
|
+
bh2 = QHBoxLayout(); bh2.addStretch(); bh2.addWidget(back); bh2.addStretch(); v.addLayout(bh2)
|
|
255
|
+
v.addStretch(1)
|
|
256
|
+
|
|
257
|
+
def set_key(self, k): self._key = k
|
|
258
|
+
def _activate(self):
|
|
259
|
+
name = self._name.text().strip(); api = self._api.text().strip()
|
|
260
|
+
if not name: self._err.setText("β οΈ Please enter your display name."); return
|
|
261
|
+
if not api: self._err.setText("β οΈ Please enter your Gemini API key."); return
|
|
262
|
+
self._btn.setEnabled(False); self._btn.setText("Activatingβ¦"); self._err.setText("")
|
|
263
|
+
self._worker.activate(self._key, api, name)
|
|
264
|
+
def _on_error(self, msg):
|
|
265
|
+
self._err.setText(msg); self._btn.setText("π Activate MYRA"); self._btn.setEnabled(True)
|
|
266
|
+
|
|
267
|
+
class PanelSuccess(QWidget):
|
|
268
|
+
sig_launch = pyqtSignal()
|
|
269
|
+
def __init__(self):
|
|
270
|
+
super().__init__(); self.setAttribute(Qt.WA_TranslucentBackground)
|
|
271
|
+
v = QVBoxLayout(self); v.setContentsMargins(40,40,40,40); v.setSpacing(16)
|
|
272
|
+
v.addStretch(1)
|
|
273
|
+
v.addWidget(_lbl("β
", GREEN, 52, align=Qt.AlignCenter))
|
|
274
|
+
v.addWidget(_lbl("Activation Successful!", GREEN, 22, bold=True, align=Qt.AlignCenter))
|
|
275
|
+
self._welcome = _lbl("Welcome!", CYAN, 16, align=Qt.AlignCenter); v.addWidget(self._welcome)
|
|
276
|
+
v.addWidget(_lbl("MYRA is ready. Let's go!", MUTED2, 13, align=Qt.AlignCenter))
|
|
277
|
+
v.addSpacing(20)
|
|
278
|
+
self._btn = _btn("π Launch MYRA"); self._btn.setFixedWidth(200); self._btn.clicked.connect(_myra_slot(self.sig_launch))
|
|
279
|
+
bh = QHBoxLayout(); bh.addStretch(); bh.addWidget(self._btn); bh.addStretch(); v.addLayout(bh)
|
|
280
|
+
v.addStretch(1)
|
|
281
|
+
|
|
282
|
+
def set_user(self, name): self._welcome.setText(f"Welcome, {name}! π")
|
|
283
|
+
|
|
284
|
+
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
285
|
+
# MAIN WINDOW
|
|
286
|
+
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
287
|
+
class ActivationWindow(QMainWindow):
|
|
288
|
+
def __init__(self):
|
|
289
|
+
super().__init__()
|
|
290
|
+
self.setWindowTitle("MYRA AI β Activation")
|
|
291
|
+
self.setFixedSize(480, 580)
|
|
292
|
+
self.setWindowFlag(Qt.FramelessWindowHint)
|
|
293
|
+
self.setAttribute(Qt.WA_TranslucentBackground)
|
|
294
|
+
self._drag_pos = None
|
|
295
|
+
|
|
296
|
+
self._bg = AnimatedBg(self); self._bg.setGeometry(0,0,480,580)
|
|
297
|
+
card = QFrame(self); card.setGeometry(24,24,432,532)
|
|
298
|
+
card.setStyleSheet(f"QFrame{{background:rgba(12,17,36,0.92);border:1.5px solid {BORDER2};border-radius:20px;}}")
|
|
299
|
+
|
|
300
|
+
self._stack = QStackedWidget(card); self._stack.setGeometry(0,0,432,532)
|
|
301
|
+
self._stack.setStyleSheet("background:transparent;")
|
|
302
|
+
|
|
303
|
+
self._p_welcome = PanelWelcome()
|
|
304
|
+
self._p_key = PanelKey()
|
|
305
|
+
self._p_profile = PanelProfile()
|
|
306
|
+
self._p_success = PanelSuccess()
|
|
307
|
+
for p in [self._p_welcome, self._p_key, self._p_profile, self._p_success]:
|
|
308
|
+
self._stack.addWidget(p)
|
|
309
|
+
|
|
310
|
+
self._p_welcome.sig_next.connect(lambda: self._stack.setCurrentIndex(1))
|
|
311
|
+
self._p_key.sig_back.connect(lambda: self._stack.setCurrentIndex(0))
|
|
312
|
+
self._p_key.sig_verified.connect(self._on_key_verified)
|
|
313
|
+
self._p_profile.sig_back.connect(lambda: self._stack.setCurrentIndex(1))
|
|
314
|
+
self._p_profile.sig_activated.connect(self._on_activated)
|
|
315
|
+
self._p_success.sig_launch.connect(self.close)
|
|
316
|
+
|
|
317
|
+
close_btn = QPushButton("β", self); close_btn.setGeometry(440,8,32,32)
|
|
318
|
+
close_btn.setStyleSheet(f"QPushButton{{background:rgba(255,71,87,0.15);color:{RED};border:1px solid rgba(255,71,87,0.3);border-radius:16px;font-size:14px;}}QPushButton:hover{{background:{RED};color:white;}}")
|
|
319
|
+
close_btn.clicked.connect(_myra_slot(self.close))
|
|
320
|
+
|
|
321
|
+
def _on_key_verified(self, key):
|
|
322
|
+
self._p_profile.set_key(key); self._stack.setCurrentIndex(2)
|
|
323
|
+
def _on_activated(self):
|
|
324
|
+
cfg = load_license()
|
|
325
|
+
self._p_success.set_user(cfg.get("display_name", cfg.get("user_name", "User")))
|
|
326
|
+
self._stack.setCurrentIndex(3)
|
|
327
|
+
def mousePressEvent(self, e):
|
|
328
|
+
if e.button() == Qt.LeftButton: self._drag_pos = e.globalPos() - self.frameGeometry().topLeft()
|
|
329
|
+
def mouseMoveEvent(self, e):
|
|
330
|
+
if self._drag_pos and e.buttons() == Qt.LeftButton: self.move(e.globalPos() - self._drag_pos)
|
|
331
|
+
def mouseReleaseEvent(self, e): self._drag_pos = None
|
|
332
|
+
|
|
333
|
+
if __name__ == "__main__":
|
|
334
|
+
app = QApplication(sys.argv); app.setStyle("Fusion")
|
|
335
|
+
win = ActivationWindow(); win.show(); sys.exit(app.exec_())
|