add lock window function, and did some improvements for the whole structure

This commit is contained in:
2025-09-10 19:28:03 +08:00
parent 648dedb611
commit 34c74bf3d0
19 changed files with 544 additions and 168 deletions

1
.gitignore vendored
View File

@@ -3,3 +3,4 @@
rokae/testbench.py
**/__pycache__/
NOTRACK/
gui/assets/database/

View File

@@ -1,5 +1,10 @@
{
"account": {
"Fan": "Ka2trNyfHPci26UGt3bVyvFjNuUoW9/0QcBVOR79KIw="
}
"username": "admin",
"login_password": "MkzWVYJoL5o2wDJOsExlS+qCElrJj+P6Rxiy89XwP7I=",
"unlock_password": "MkzWVYJoL5o2wDJOsExlS+qCElrJj+P6Rxiy89XwP7I=",
"code_dict": [4, 11, 4, 31, 22, 12, 19, 23, 7, 16, 7, 23, 1, 8, 7, 18, 27, 32, 28, 25, 7, 32, 9, 15, 2, 32, 0, 12, 26, 15, 14, 17],
"minimum_password_length": 8,
"maximum_db_number": 10,
"api_ali": "",
"api_wechat": ""
}

Binary file not shown.

Binary file not shown.

View File

@@ -1,19 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<class>App</class>
<widget class="QMainWindow" name="App">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1100</width>
<height>550</height>
<width>769</width>
<height>356</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>1100</width>
<height>550</height>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="font">
@@ -25,67 +25,203 @@
<property name="windowTitle">
<string>Toolbox</string>
</property>
<widget class="QWidget" name="centralwidget"/>
<widget class="QMenuBar" name="menubar">
<widget class="QWidget" name="centralwidget">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout" stretch="1,5">
<item>
<widget class="QListWidget" name="lw_navigation">
<item>
<property name="text">
<string>个人</string>
</property>
</item>
<item>
<property name="text">
<string>实用</string>
</property>
</item>
<item>
<property name="text">
<string>效率</string>
</property>
</item>
<item>
<property name="text">
<string>开发</string>
</property>
</item>
<item>
<property name="text">
<string>设计</string>
</property>
</item>
<item>
<property name="text">
<string>工作</string>
</property>
</item>
</widget>
</item>
<item>
<widget class="QStackedWidget" name="sw_pages">
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="page">
<widget class="QLabel" name="label_3">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1100</width>
<height>33</height>
<x>110</x>
<y>70</y>
<width>54</width>
<height>16</height>
</rect>
</property>
<widget class="QMenu" name="menu">
<property name="title">
<string>文件</string>
</property>
<addaction name="action_4"/>
<addaction name="action_3"/>
</widget>
<widget class="QMenu" name="menu_2">
<property name="title">
<string>帮助</string>
</property>
<addaction name="action_2"/>
</widget>
<widget class="QMenu" name="menu_3">
<property name="title">
<string>日志</string>
<property name="text">
<string>1</string>
</property>
</widget>
<addaction name="menu"/>
<addaction name="menu_3"/>
<addaction name="menu_2"/>
</widget>
<widget class="QWidget" name="page_2">
<widget class="QLabel" name="label_2">
<property name="geometry">
<rect>
<x>100</x>
<y>130</y>
<width>54</width>
<height>16</height>
</rect>
</property>
<property name="text">
<string>2</string>
</property>
</widget>
</widget>
<widget class="QWidget" name="page_3">
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>130</x>
<y>70</y>
<width>54</width>
<height>16</height>
</rect>
</property>
<property name="text">
<string>3</string>
</property>
</widget>
</widget>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QStatusBar" name="statusbar"/>
<action name="actionExit">
<widget class="QToolBar" name="toolBar">
<property name="windowTitle">
<string>toolBar</string>
</property>
<property name="movable">
<bool>false</bool>
</property>
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
<addaction name="ac_homepage"/>
<addaction name="ac_settings"/>
<addaction name="ac_logs"/>
<addaction name="ac_about"/>
<addaction name="ac_caging"/>
<addaction name="ac_quit"/>
</widget>
<action name="ac_homepage">
<property name="text">
<string>Exit</string>
<string>主页</string>
</property>
<property name="toolTip">
<string>Ctrl+Alt+H</string>
</property>
<property name="shortcut">
<string>Ctrl+Alt+H</string>
</property>
<property name="menuRole">
<enum>QAction::MenuRole::NoRole</enum>
</property>
</action>
<action name="action">
<action name="ac_settings">
<property name="text">
<string>设置</string>
</property>
<property name="toolTip">
<string>Ctrl+Alt+S</string>
</property>
<property name="shortcut">
<string>Ctrl+Alt+S</string>
</property>
<property name="menuRole">
<enum>QAction::MenuRole::NoRole</enum>
</property>
</action>
<action name="ac_logs">
<property name="text">
<string>日志</string>
</property>
<property name="toolTip">
<string>Ctrl+Alt+L</string>
</property>
<property name="shortcut">
<string>Ctrl+Alt+L</string>
</property>
<property name="menuRole">
<enum>QAction::MenuRole::NoRole</enum>
</property>
</action>
<action name="ac_about">
<property name="text">
<string>关于</string>
</property>
</action>
<action name="actionExit_2">
<property name="text">
<string>Exit</string>
<property name="toolTip">
<string>Ctrl+Alt+A</string>
</property>
<property name="shortcut">
<string>Ctrl+Alt+A</string>
</property>
<property name="menuRole">
<enum>QAction::MenuRole::NoRole</enum>
</property>
</action>
<action name="action_2">
<property name="text">
<string>关于</string>
</property>
</action>
<action name="action_3">
<action name="ac_quit">
<property name="text">
<string>退出</string>
</property>
<property name="toolTip">
<string>Ctrl+Alt+Q</string>
</property>
<property name="shortcut">
<string>Ctrl+Alt+Q</string>
</property>
<property name="menuRole">
<enum>QAction::MenuRole::NoRole</enum>
</property>
</action>
<action name="action_4">
<action name="ac_caging">
<property name="text">
<string>设置</string>
<string>锁定</string>
</property>
<property name="toolTip">
<string>Ctrl+Alt+C</string>
</property>
<property name="shortcut">
<string>Ctrl+Alt+C</string>
</property>
<property name="menuRole">
<enum>QAction::MenuRole::NoRole</enum>
</property>
</action>
</widget>

View File

@@ -183,6 +183,9 @@
<property name="text">
<string>登录</string>
</property>
<property name="autoDefault">
<bool>true</bool>
</property>
</widget>
</item>
<item>
@@ -197,6 +200,9 @@
<property name="text">
<string>取消</string>
</property>
<property name="autoDefault">
<bool>true</bool>
</property>
</widget>
</item>
</layout>

View File

@@ -1,6 +1,7 @@
from pathlib import Path
from threading import Lock
base_path = Path(__file__).resolve().parent.parent.parent
code_dict = [4, 11, 4, 31, 22, 12, 19, 23, 7, 16, 7, 23, 1, 8, 7, 18, 27, 32, 28, 25, 7, 32, 9, 15, 2, 32, 0, 12, 26, 15, 14, 17]
salt = ""
max_db_number = 10
lock = Lock()
account = None

View File

@@ -1,5 +1,4 @@
import sqlite3
from threading import Lock
import time
from codes.common import clibs
@@ -30,10 +29,10 @@ def db_init(db_file):
def db_lock(func):
def wrapper(*args, **kwargs):
try:
Lock().acquire(True)
clibs.lock.acquire(True)
ret = func(*args, **kwargs)
finally:
Lock().release()
clibs.lock.release()
return ret
return wrapper
@@ -47,8 +46,7 @@ def db_backup():
db_file_backup.write_bytes(db_file.read_bytes())
db_dir = clibs.base_path / "assets/database"
db_list = [db for db in db_dir.glob("*.db")]
print(f"db_list: {sorted(db_list)}")
for db in sorted(db_list)[:-clibs.max_db_number]:
for db in sorted(db_list)[:-clibs.account["maximum_db_number"]]:
db.unlink()
def db_conn():
@@ -62,3 +60,8 @@ def db_conn():
cursor.execute("PRAGMA mmap_size=30000000000")
cursor.execute("PRAGMA cache_size=200000")
return conn, cursor
@db_lock
def db_close(conn, cursor):
cursor.close()
conn.close()

View File

@@ -3,6 +3,7 @@ import hashlib
from Crypto.Cipher import AES
from Crypto import Random
from Crypto.Util.Padding import pad, unpad
from codes.common import clibs
class PassCipher:
@@ -25,13 +26,12 @@ class PassCipher:
plaintext = unpad(cipher.decrypt(ciphertext), AES.block_size)
return plaintext.decode("utf-8")
# if __name__ == "__main__":
# salt = "my_secret_salt_string"
# cipher = PassCipher(salt)
# original_text = "这是一段需要加密的敏感信息"
# encrypted_text = cipher.encrypt(original_text)
# print(f"加密后的文本: {encrypted_text}")
# decrypted_text = cipher.decrypt(encrypted_text)
# print(f"解密后的文本: {decrypted_text}")
# print(f"加解密是否成功: {original_text == decrypted_text}")
@staticmethod
def gen_salt(text: str):
key = ""
passwd = {idx: char for idx, char in enumerate(text * 4)}
for idx in range(32):
char_i = 0 if ord(passwd[idx]) - clibs.account["code_dict"][idx] < 0 else ord(passwd[idx]) - clibs.account["code_dict"][idx]
key += chr(char_i)
salt = base64.urlsafe_b64encode(key.encode()).decode()
return salt

View File

@@ -19,8 +19,10 @@ def single_uic(ui_path: str, py_path: str):
except subprocess.CalledProcessError as e:
print(f"转换失败: {ui_file}\n{e.stderr}", file=sys.stderr)
if __name__ == "__main__":
def main():
ui_path = clibs.base_path / "assets" / "ui"
py_path = clibs.base_path / "codes" / "ui"
single_uic(str(ui_path), str(py_path))
if __name__ == "__main__":
main()

View File

@@ -16,70 +16,171 @@ from PySide6.QtGui import (QAction, QBrush, QColor, QConicalGradient,
QIcon, QImage, QKeySequence, QLinearGradient,
QPainter, QPalette, QPixmap, QRadialGradient,
QTransform)
from PySide6.QtWidgets import (QApplication, QMainWindow, QMenu, QMenuBar,
QSizePolicy, QStatusBar, QWidget)
from PySide6.QtWidgets import (QApplication, QHBoxLayout, QLabel, QListWidget,
QListWidgetItem, QMainWindow, QSizePolicy, QStackedWidget,
QStatusBar, QToolBar, QVBoxLayout, QWidget)
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
if not MainWindow.objectName():
MainWindow.setObjectName(u"MainWindow")
MainWindow.resize(1100, 550)
MainWindow.setMinimumSize(QSize(1100, 550))
class Ui_App(object):
def setupUi(self, App):
if not App.objectName():
App.setObjectName(u"App")
App.resize(769, 356)
App.setMinimumSize(QSize(0, 0))
font = QFont()
font.setFamilies([u"Consolas"])
font.setPointSize(12)
MainWindow.setFont(font)
self.actionExit = QAction(MainWindow)
self.actionExit.setObjectName(u"actionExit")
self.action = QAction(MainWindow)
self.action.setObjectName(u"action")
self.actionExit_2 = QAction(MainWindow)
self.actionExit_2.setObjectName(u"actionExit_2")
self.action_2 = QAction(MainWindow)
self.action_2.setObjectName(u"action_2")
self.action_3 = QAction(MainWindow)
self.action_3.setObjectName(u"action_3")
self.action_4 = QAction(MainWindow)
self.action_4.setObjectName(u"action_4")
self.centralwidget = QWidget(MainWindow)
App.setFont(font)
self.ac_homepage = QAction(App)
self.ac_homepage.setObjectName(u"ac_homepage")
self.ac_homepage.setMenuRole(QAction.MenuRole.NoRole)
self.ac_settings = QAction(App)
self.ac_settings.setObjectName(u"ac_settings")
self.ac_settings.setMenuRole(QAction.MenuRole.NoRole)
self.ac_logs = QAction(App)
self.ac_logs.setObjectName(u"ac_logs")
self.ac_logs.setMenuRole(QAction.MenuRole.NoRole)
self.ac_about = QAction(App)
self.ac_about.setObjectName(u"ac_about")
self.ac_about.setMenuRole(QAction.MenuRole.NoRole)
self.ac_quit = QAction(App)
self.ac_quit.setObjectName(u"ac_quit")
self.ac_quit.setMenuRole(QAction.MenuRole.NoRole)
self.ac_caging = QAction(App)
self.ac_caging.setObjectName(u"ac_caging")
self.ac_caging.setMenuRole(QAction.MenuRole.NoRole)
self.centralwidget = QWidget(App)
self.centralwidget.setObjectName(u"centralwidget")
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QMenuBar(MainWindow)
self.menubar.setObjectName(u"menubar")
self.menubar.setGeometry(QRect(0, 0, 1100, 33))
self.menu = QMenu(self.menubar)
self.menu.setObjectName(u"menu")
self.menu_2 = QMenu(self.menubar)
self.menu_2.setObjectName(u"menu_2")
self.menu_3 = QMenu(self.menubar)
self.menu_3.setObjectName(u"menu_3")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QStatusBar(MainWindow)
self.verticalLayout = QVBoxLayout(self.centralwidget)
self.verticalLayout.setObjectName(u"verticalLayout")
self.horizontalLayout = QHBoxLayout()
self.horizontalLayout.setObjectName(u"horizontalLayout")
self.lw_navigation = QListWidget(self.centralwidget)
QListWidgetItem(self.lw_navigation)
QListWidgetItem(self.lw_navigation)
QListWidgetItem(self.lw_navigation)
QListWidgetItem(self.lw_navigation)
QListWidgetItem(self.lw_navigation)
QListWidgetItem(self.lw_navigation)
self.lw_navigation.setObjectName(u"lw_navigation")
self.horizontalLayout.addWidget(self.lw_navigation)
self.sw_pages = QStackedWidget(self.centralwidget)
self.sw_pages.setObjectName(u"sw_pages")
self.page = QWidget()
self.page.setObjectName(u"page")
self.label_3 = QLabel(self.page)
self.label_3.setObjectName(u"label_3")
self.label_3.setGeometry(QRect(110, 70, 54, 16))
self.sw_pages.addWidget(self.page)
self.page_2 = QWidget()
self.page_2.setObjectName(u"page_2")
self.label_2 = QLabel(self.page_2)
self.label_2.setObjectName(u"label_2")
self.label_2.setGeometry(QRect(100, 130, 54, 16))
self.sw_pages.addWidget(self.page_2)
self.page_3 = QWidget()
self.page_3.setObjectName(u"page_3")
self.label = QLabel(self.page_3)
self.label.setObjectName(u"label")
self.label.setGeometry(QRect(130, 70, 54, 16))
self.sw_pages.addWidget(self.page_3)
self.horizontalLayout.addWidget(self.sw_pages)
self.horizontalLayout.setStretch(0, 1)
self.horizontalLayout.setStretch(1, 5)
self.verticalLayout.addLayout(self.horizontalLayout)
App.setCentralWidget(self.centralwidget)
self.statusbar = QStatusBar(App)
self.statusbar.setObjectName(u"statusbar")
MainWindow.setStatusBar(self.statusbar)
App.setStatusBar(self.statusbar)
self.toolBar = QToolBar(App)
self.toolBar.setObjectName(u"toolBar")
self.toolBar.setMovable(False)
App.addToolBar(Qt.ToolBarArea.TopToolBarArea, self.toolBar)
self.menubar.addAction(self.menu.menuAction())
self.menubar.addAction(self.menu_3.menuAction())
self.menubar.addAction(self.menu_2.menuAction())
self.menu.addAction(self.action_4)
self.menu.addAction(self.action_3)
self.menu_2.addAction(self.action_2)
self.toolBar.addAction(self.ac_homepage)
self.toolBar.addAction(self.ac_settings)
self.toolBar.addAction(self.ac_logs)
self.toolBar.addAction(self.ac_about)
self.toolBar.addAction(self.ac_caging)
self.toolBar.addAction(self.ac_quit)
self.retranslateUi(MainWindow)
self.retranslateUi(App)
QMetaObject.connectSlotsByName(MainWindow)
self.sw_pages.setCurrentIndex(0)
QMetaObject.connectSlotsByName(App)
# setupUi
def retranslateUi(self, MainWindow):
MainWindow.setWindowTitle(QCoreApplication.translate("MainWindow", u"Toolbox", None))
self.actionExit.setText(QCoreApplication.translate("MainWindow", u"Exit", None))
self.action.setText(QCoreApplication.translate("MainWindow", u"\u5173\u4e8e", None))
self.actionExit_2.setText(QCoreApplication.translate("MainWindow", u"Exit", None))
self.action_2.setText(QCoreApplication.translate("MainWindow", u"\u5173\u4e8e", None))
self.action_3.setText(QCoreApplication.translate("MainWindow", u"\u9000\u51fa", None))
self.action_4.setText(QCoreApplication.translate("MainWindow", u"\u8bbe\u7f6e", None))
self.menu.setTitle(QCoreApplication.translate("MainWindow", u"\u6587\u4ef6", None))
self.menu_2.setTitle(QCoreApplication.translate("MainWindow", u"\u5e2e\u52a9", None))
self.menu_3.setTitle(QCoreApplication.translate("MainWindow", u"\u65e5\u5fd7", None))
def retranslateUi(self, App):
App.setWindowTitle(QCoreApplication.translate("App", u"Toolbox", None))
self.ac_homepage.setText(QCoreApplication.translate("App", u"\u4e3b\u9875", None))
#if QT_CONFIG(tooltip)
self.ac_homepage.setToolTip(QCoreApplication.translate("App", u"Ctrl+Alt+H", None))
#endif // QT_CONFIG(tooltip)
#if QT_CONFIG(shortcut)
self.ac_homepage.setShortcut(QCoreApplication.translate("App", u"Ctrl+Alt+H", None))
#endif // QT_CONFIG(shortcut)
self.ac_settings.setText(QCoreApplication.translate("App", u"\u8bbe\u7f6e", None))
#if QT_CONFIG(tooltip)
self.ac_settings.setToolTip(QCoreApplication.translate("App", u"Ctrl+Alt+S", None))
#endif // QT_CONFIG(tooltip)
#if QT_CONFIG(shortcut)
self.ac_settings.setShortcut(QCoreApplication.translate("App", u"Ctrl+Alt+S", None))
#endif // QT_CONFIG(shortcut)
self.ac_logs.setText(QCoreApplication.translate("App", u"\u65e5\u5fd7", None))
#if QT_CONFIG(tooltip)
self.ac_logs.setToolTip(QCoreApplication.translate("App", u"Ctrl+Alt+L", None))
#endif // QT_CONFIG(tooltip)
#if QT_CONFIG(shortcut)
self.ac_logs.setShortcut(QCoreApplication.translate("App", u"Ctrl+Alt+L", None))
#endif // QT_CONFIG(shortcut)
self.ac_about.setText(QCoreApplication.translate("App", u"\u5173\u4e8e", None))
#if QT_CONFIG(tooltip)
self.ac_about.setToolTip(QCoreApplication.translate("App", u"Ctrl+Alt+A", None))
#endif // QT_CONFIG(tooltip)
#if QT_CONFIG(shortcut)
self.ac_about.setShortcut(QCoreApplication.translate("App", u"Ctrl+Alt+A", None))
#endif // QT_CONFIG(shortcut)
self.ac_quit.setText(QCoreApplication.translate("App", u"\u9000\u51fa", None))
#if QT_CONFIG(tooltip)
self.ac_quit.setToolTip(QCoreApplication.translate("App", u"Ctrl+Alt+Q", None))
#endif // QT_CONFIG(tooltip)
#if QT_CONFIG(shortcut)
self.ac_quit.setShortcut(QCoreApplication.translate("App", u"Ctrl+Alt+Q", None))
#endif // QT_CONFIG(shortcut)
self.ac_caging.setText(QCoreApplication.translate("App", u"\u9501\u5b9a", None))
#if QT_CONFIG(tooltip)
self.ac_caging.setToolTip(QCoreApplication.translate("App", u"Ctrl+Alt+C", None))
#endif // QT_CONFIG(tooltip)
#if QT_CONFIG(shortcut)
self.ac_caging.setShortcut(QCoreApplication.translate("App", u"Ctrl+Alt+C", None))
#endif // QT_CONFIG(shortcut)
__sortingEnabled = self.lw_navigation.isSortingEnabled()
self.lw_navigation.setSortingEnabled(False)
___qlistwidgetitem = self.lw_navigation.item(0)
___qlistwidgetitem.setText(QCoreApplication.translate("App", u"\u4e2a\u4eba", None));
___qlistwidgetitem1 = self.lw_navigation.item(1)
___qlistwidgetitem1.setText(QCoreApplication.translate("App", u"\u5b9e\u7528", None));
___qlistwidgetitem2 = self.lw_navigation.item(2)
___qlistwidgetitem2.setText(QCoreApplication.translate("App", u"\u6548\u7387", None));
___qlistwidgetitem3 = self.lw_navigation.item(3)
___qlistwidgetitem3.setText(QCoreApplication.translate("App", u"\u5f00\u53d1", None));
___qlistwidgetitem4 = self.lw_navigation.item(4)
___qlistwidgetitem4.setText(QCoreApplication.translate("App", u"\u8bbe\u8ba1", None));
___qlistwidgetitem5 = self.lw_navigation.item(5)
___qlistwidgetitem5.setText(QCoreApplication.translate("App", u"\u5de5\u4f5c", None));
self.lw_navigation.setSortingEnabled(__sortingEnabled)
self.label_3.setText(QCoreApplication.translate("App", u"1", None))
self.label_2.setText(QCoreApplication.translate("App", u"2", None))
self.label.setText(QCoreApplication.translate("App", u"3", None))
self.toolBar.setWindowTitle(QCoreApplication.translate("App", u"toolBar", None))
# retranslateUi

View File

@@ -109,12 +109,14 @@ class Ui_login(object):
font2.setPointSize(12)
font2.setBold(True)
self.pb_login.setFont(font2)
self.pb_login.setAutoDefault(True)
self.horizontalLayout.addWidget(self.pb_login)
self.pb_cancel = QPushButton(login)
self.pb_cancel.setObjectName(u"pb_cancel")
self.pb_cancel.setFont(font2)
self.pb_cancel.setAutoDefault(True)
self.horizontalLayout.addWidget(self.pb_cancel)

View File

@@ -1,13 +1,12 @@
import json
import random
import sys
import base64
import time
from typing import Callable, Any
from PySide6.QtWidgets import QApplication, QWidget, QMessageBox, QMainWindow
from PySide6.QtGui import QIcon, QPixmap, QShortcut
from PySide6.QtCore import Qt
from PySide6.QtWidgets import QApplication, QWidget, QMessageBox, QMainWindow, QHBoxLayout, QVBoxLayout, QLineEdit, QLabel
from PySide6.QtGui import QIcon, QPixmap, QShortcut, QResizeEvent, QFont, QKeySequence
from PySide6.QtCore import Qt,QSize
from codes.ui.login import Ui_login
from codes.ui.app import Ui_MainWindow
from codes.ui.app import Ui_App
from codes.common.worker import Worker
from codes.common import clibs
from codes.common.secure_encrypt import PassCipher
@@ -36,45 +35,40 @@ class LoginWindow(QWidget, Ui_login):
self.le_username.setText("")
self.le_password.setText("")
def gen_salt():
clibs.salt = ""
key = ""
passwd = {idx: char for idx, char in enumerate(self.le_password.text() * 4)}
for idx in range(32):
char_i = 0 if ord(passwd[idx]) - clibs.code_dict[idx] < 0 else ord(passwd[idx]) - clibs.code_dict[idx]
key += chr(char_i)
clibs.salt = base64.urlsafe_b64encode(key.encode()).decode()
def validate_login():
# with open(f"{clibs.base_path}/assets/conf/config.json", mode="rt", encoding="utf-8") as f_conf:
# accounts = json.load(f_conf)["account"]
# username = self.le_username.text()
# if username not in accounts or len(self.le_password.text()) < 8:
# login_failed()
# return False
#
# gen_salt()
# cipher = PassCipher(clibs.salt)
# try:
# password = cipher.decrypt(accounts[username])
# except ValueError:
# login_failed()
# return False
#
# if password != self.le_password.text():
# login_failed()
# return False
nonlocal username, password
with open(f"{clibs.base_path}/assets/conf/config.json", mode="rt", encoding="utf-8") as f_conf:
clibs.account = json.load(f_conf)
if username != clibs.account["username"] or len(password) < clibs.account["minimum_password_length"]:
login_failed()
return False
salt = PassCipher.gen_salt(password)
cipher = PassCipher(salt)
# password_encrypt = cipher.encrypt(password)
# print(f"password_encrypt = {password_encrypt}")
# exit()
try:
decrypt_password = cipher.decrypt(clibs.account["login_password"])
except ValueError:
login_failed()
return False
if password != decrypt_password:
login_failed()
return False
self.mainWindow = MainWindow()
self.mainWindow.show()
self.close()
self.deleteLater()
return True
username = self.le_username.text()
password = self.le_password.text()
validate_login()
class MainWindow(QMainWindow, Ui_MainWindow):
class MainWindow(QMainWindow, Ui_App):
def __init__(self):
super().__init__()
self.conn = None
@@ -82,12 +76,16 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.thread = None
self.setupUi(self)
self.pre_dos()
self.lock_overlay = None
def pre_dos(self):
self.setWindowIcon(QIcon(f"{clibs.base_path}/assets/media/icon.ico"))
db_operation.db_backup()
self.conn, self.cursor = db_operation.db_conn()
# bindings
self.ac_quit.triggered.connect(self.close)
self.ac_caging.triggered.connect(self.lock_window)
self.ac_logs.triggered.connect(lambda : print("test ac log"))
def launch(self, func, on_anything: Callable[..., Any] = print, *args, **kwargs):
self.thread = Worker(func, *args, **kwargs)
@@ -97,6 +95,127 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.thread.finished.connect(lambda: on_anything({"finished": True}))
self.thread.start()
def lock_window(self):
def unlock():
def check_failed():
QMessageBox.warning(self, "错误", "\n密码错误,请重新输入!")
le_password.clear()
le_password.setFocus()
password = le_password.text()
if len(password) < clibs.account["minimum_password_length"]:
check_failed()
return False
salt = PassCipher.gen_salt(password)
cipher = PassCipher(salt)
try:
decrypt_password = cipher.decrypt(clibs.account["unlock_password"])
except ValueError:
check_failed()
return False
if password != decrypt_password:
check_failed()
return False
self.lock_overlay.deleteLater()
self.lock_overlay = None
self.set_shortcuts(True)
return True
def gen_lock_screen():
# generate lock screen
v_layout = QVBoxLayout(self.lock_overlay) # v layout
v_layout.setObjectName(u"v_layout")
h_layout = QHBoxLayout() # h layout
h_layout.setObjectName(u"h_layout")
h_layout.setContentsMargins(-1, -1, 10, 50)
lb_e_1 = QLabel(self.lock_overlay)
lb_e_1.setObjectName(u"lb_e_1")
h_layout.addWidget(lb_e_1)
lb_password = QLabel(self.lock_overlay)
lb_password.setObjectName(u"lb_password")
lb_password.setMinimumSize(QSize(100, 0))
lb_password.setMaximumSize(QSize(100, 16777215))
font = QFont()
font.setFamilies([u"Consolas"])
font.setPointSize(14)
font.setBold(True)
font.setItalic(True)
lb_password.setFont(font)
lb_password.setAlignment(Qt.AlignmentFlag.AlignCenter)
lb_password.setText("Password")
h_layout.addWidget(lb_password)
le_password = QLineEdit(self.lock_overlay)
le_password.setObjectName(u"le_password")
le_password.setMinimumSize(QSize(200, 0))
le_password.setFont(font)
le_password.setEchoMode(QLineEdit.EchoMode.Password)
h_layout.addWidget(le_password)
lb_e_2 = QLabel(self.lock_overlay)
lb_e_2.setObjectName(u"lb_e_2")
h_layout.addWidget(lb_e_2)
h_layout.setStretch(0, 5)
h_layout.setStretch(1, 2)
h_layout.setStretch(2, 3)
h_layout.setStretch(3, 5)
v_layout.addLayout(h_layout)
return le_password
self.set_shortcuts(False)
if not self.lock_overlay:
self.lock_overlay = QWidget(self)
self.lock_overlay.setObjectName("w_overlay")
cx = random.random()
cy = random.random()
stop1 = random.random()
stop2 = random.random()
angle = random.randint(0, 360)
self.lock_overlay.setStyleSheet(f"""background: qconicalgradient(cx:{cx}, cy:{cy}, angle:{angle}, stop:0 #f6f8fa, stop:{stop1} #eef1f5, stop:{stop2} #dce1e8);""")
# self.lock_overlay.setStyleSheet("""background: qconicalgradient(cx:0.5, cy:0.5, angle:45, stop:0 #f6f8fa, stop:0.5 #eef1f5, stop:1 #dce1e8);""")
le_password = gen_lock_screen()
le_password.returnPressed.connect(unlock)
self.lock_overlay.setGeometry(self.rect())
self.lock_overlay.show()
le_password.setFocus()
def set_shortcuts(self, stat: bool = True):
if stat:
self.ac_homepage.setShortcut(QKeySequence("Ctrl+Alt+H"))
self.ac_settings.setShortcut(QKeySequence("Ctrl+Alt+S"))
self.ac_logs.setShortcut(QKeySequence("Ctrl+Alt+L"))
self.ac_about.setShortcut(QKeySequence("Ctrl+Alt+A"))
self.ac_caging.setShortcut(QKeySequence("Ctrl+Alt+C"))
self.ac_quit.setShortcut(QKeySequence("Ctrl+Alt+Q"))
else:
self.ac_homepage.setShortcut(QKeySequence())
self.ac_settings.setShortcut(QKeySequence())
self.ac_logs.setShortcut(QKeySequence())
self.ac_about.setShortcut(QKeySequence())
self.ac_caging.setShortcut(QKeySequence())
self.ac_quit.setShortcut(QKeySequence())
def resizeEvent(self, event: QResizeEvent):
super().resizeEvent(event)
if self.lock_overlay:
self.lock_overlay.setGeometry(self.rect())
def closeEvent(self, event):
reply = QMessageBox.question(self, "退出", "\n程序可能在运行,确定要退出吗?")
if reply == QMessageBox.StandardButton.Yes:
db_operation.db_close(self.conn, self.cursor)
event.accept()
else:
event.ignore()
if __name__ == '__main__':
app = QApplication(sys.argv)
login = LoginWindow()