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 rokae/testbench.py
**/__pycache__/ **/__pycache__/
NOTRACK/ NOTRACK/
gui/assets/database/

View File

@@ -1,5 +1,10 @@
{ {
"account": { "username": "admin",
"Fan": "Ka2trNyfHPci26UGt3bVyvFjNuUoW9/0QcBVOR79KIw=" "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"?> <?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0"> <ui version="4.0">
<class>MainWindow</class> <class>App</class>
<widget class="QMainWindow" name="MainWindow"> <widget class="QMainWindow" name="App">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>1100</width> <width>769</width>
<height>550</height> <height>356</height>
</rect> </rect>
</property> </property>
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>1100</width> <width>0</width>
<height>550</height> <height>0</height>
</size> </size>
</property> </property>
<property name="font"> <property name="font">
@@ -25,67 +25,203 @@
<property name="windowTitle"> <property name="windowTitle">
<string>Toolbox</string> <string>Toolbox</string>
</property> </property>
<widget class="QWidget" name="centralwidget"/> <widget class="QWidget" name="centralwidget">
<widget class="QMenuBar" name="menubar"> <layout class="QVBoxLayout" name="verticalLayout">
<property name="geometry"> <item>
<rect> <layout class="QHBoxLayout" name="horizontalLayout" stretch="1,5">
<x>0</x> <item>
<y>0</y> <widget class="QListWidget" name="lw_navigation">
<width>1100</width> <item>
<height>33</height> <property name="text">
</rect> <string>个人</string>
</property> </property>
<widget class="QMenu" name="menu"> </item>
<property name="title"> <item>
<string>文件</string> <property name="text">
</property> <string>实用</string>
<addaction name="action_4"/> </property>
<addaction name="action_3"/> </item>
</widget> <item>
<widget class="QMenu" name="menu_2"> <property name="text">
<property name="title"> <string>效率</string>
<string>帮助</string> </property>
</property> </item>
<addaction name="action_2"/> <item>
</widget> <property name="text">
<widget class="QMenu" name="menu_3"> <string>开发</string>
<property name="title"> </property>
<string>日志</string> </item>
</property> <item>
</widget> <property name="text">
<addaction name="menu"/> <string>设计</string>
<addaction name="menu_3"/> </property>
<addaction name="menu_2"/> </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>110</x>
<y>70</y>
<width>54</width>
<height>16</height>
</rect>
</property>
<property name="text">
<string>1</string>
</property>
</widget>
</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>
<widget class="QStatusBar" name="statusbar"/> <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"> <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> </property>
</action> </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"> <property name="text">
<string>关于</string> <string>关于</string>
</property> </property>
</action> <property name="toolTip">
<action name="actionExit_2"> <string>Ctrl+Alt+A</string>
<property name="text"> </property>
<string>Exit</string> <property name="shortcut">
<string>Ctrl+Alt+A</string>
</property>
<property name="menuRole">
<enum>QAction::MenuRole::NoRole</enum>
</property> </property>
</action> </action>
<action name="action_2"> <action name="ac_quit">
<property name="text">
<string>关于</string>
</property>
</action>
<action name="action_3">
<property name="text"> <property name="text">
<string>退出</string> <string>退出</string>
</property> </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>
<action name="action_4"> <action name="ac_caging">
<property name="text"> <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> </property>
</action> </action>
</widget> </widget>

View File

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

View File

@@ -1,6 +1,7 @@
from pathlib import Path from pathlib import Path
from threading import Lock
base_path = Path(__file__).resolve().parent.parent.parent 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] lock = Lock()
salt = "" account = None
max_db_number = 10

View File

@@ -1,5 +1,4 @@
import sqlite3 import sqlite3
from threading import Lock
import time import time
from codes.common import clibs from codes.common import clibs
@@ -30,10 +29,10 @@ def db_init(db_file):
def db_lock(func): def db_lock(func):
def wrapper(*args, **kwargs): def wrapper(*args, **kwargs):
try: try:
Lock().acquire(True) clibs.lock.acquire(True)
ret = func(*args, **kwargs) ret = func(*args, **kwargs)
finally: finally:
Lock().release() clibs.lock.release()
return ret return ret
return wrapper return wrapper
@@ -47,8 +46,7 @@ def db_backup():
db_file_backup.write_bytes(db_file.read_bytes()) db_file_backup.write_bytes(db_file.read_bytes())
db_dir = clibs.base_path / "assets/database" db_dir = clibs.base_path / "assets/database"
db_list = [db for db in db_dir.glob("*.db")] db_list = [db for db in db_dir.glob("*.db")]
print(f"db_list: {sorted(db_list)}") for db in sorted(db_list)[:-clibs.account["maximum_db_number"]]:
for db in sorted(db_list)[:-clibs.max_db_number]:
db.unlink() db.unlink()
def db_conn(): def db_conn():
@@ -62,3 +60,8 @@ def db_conn():
cursor.execute("PRAGMA mmap_size=30000000000") cursor.execute("PRAGMA mmap_size=30000000000")
cursor.execute("PRAGMA cache_size=200000") cursor.execute("PRAGMA cache_size=200000")
return conn, cursor 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.Cipher import AES
from Crypto import Random from Crypto import Random
from Crypto.Util.Padding import pad, unpad from Crypto.Util.Padding import pad, unpad
from codes.common import clibs
class PassCipher: class PassCipher:
@@ -25,13 +26,12 @@ class PassCipher:
plaintext = unpad(cipher.decrypt(ciphertext), AES.block_size) plaintext = unpad(cipher.decrypt(ciphertext), AES.block_size)
return plaintext.decode("utf-8") return plaintext.decode("utf-8")
@staticmethod
# if __name__ == "__main__": def gen_salt(text: str):
# salt = "my_secret_salt_string" key = ""
# cipher = PassCipher(salt) passwd = {idx: char for idx, char in enumerate(text * 4)}
# original_text = "这是一段需要加密的敏感信息" for idx in range(32):
# encrypted_text = cipher.encrypt(original_text) char_i = 0 if ord(passwd[idx]) - clibs.account["code_dict"][idx] < 0 else ord(passwd[idx]) - clibs.account["code_dict"][idx]
# print(f"加密后的文本: {encrypted_text}") key += chr(char_i)
# decrypted_text = cipher.decrypt(encrypted_text) salt = base64.urlsafe_b64encode(key.encode()).decode()
# print(f"解密后的文本: {decrypted_text}") return salt
# print(f"加解密是否成功: {original_text == decrypted_text}")

View File

@@ -19,8 +19,10 @@ def single_uic(ui_path: str, py_path: str):
except subprocess.CalledProcessError as e: except subprocess.CalledProcessError as e:
print(f"转换失败: {ui_file}\n{e.stderr}", file=sys.stderr) print(f"转换失败: {ui_file}\n{e.stderr}", file=sys.stderr)
def main():
if __name__ == "__main__":
ui_path = clibs.base_path / "assets" / "ui" ui_path = clibs.base_path / "assets" / "ui"
py_path = clibs.base_path / "codes" / "ui" py_path = clibs.base_path / "codes" / "ui"
single_uic(str(ui_path), str(py_path)) 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, QIcon, QImage, QKeySequence, QLinearGradient,
QPainter, QPalette, QPixmap, QRadialGradient, QPainter, QPalette, QPixmap, QRadialGradient,
QTransform) QTransform)
from PySide6.QtWidgets import (QApplication, QMainWindow, QMenu, QMenuBar, from PySide6.QtWidgets import (QApplication, QHBoxLayout, QLabel, QListWidget,
QSizePolicy, QStatusBar, QWidget) QListWidgetItem, QMainWindow, QSizePolicy, QStackedWidget,
QStatusBar, QToolBar, QVBoxLayout, QWidget)
class Ui_MainWindow(object): class Ui_App(object):
def setupUi(self, MainWindow): def setupUi(self, App):
if not MainWindow.objectName(): if not App.objectName():
MainWindow.setObjectName(u"MainWindow") App.setObjectName(u"App")
MainWindow.resize(1100, 550) App.resize(769, 356)
MainWindow.setMinimumSize(QSize(1100, 550)) App.setMinimumSize(QSize(0, 0))
font = QFont() font = QFont()
font.setFamilies([u"Consolas"]) font.setFamilies([u"Consolas"])
font.setPointSize(12) font.setPointSize(12)
MainWindow.setFont(font) App.setFont(font)
self.actionExit = QAction(MainWindow) self.ac_homepage = QAction(App)
self.actionExit.setObjectName(u"actionExit") self.ac_homepage.setObjectName(u"ac_homepage")
self.action = QAction(MainWindow) self.ac_homepage.setMenuRole(QAction.MenuRole.NoRole)
self.action.setObjectName(u"action") self.ac_settings = QAction(App)
self.actionExit_2 = QAction(MainWindow) self.ac_settings.setObjectName(u"ac_settings")
self.actionExit_2.setObjectName(u"actionExit_2") self.ac_settings.setMenuRole(QAction.MenuRole.NoRole)
self.action_2 = QAction(MainWindow) self.ac_logs = QAction(App)
self.action_2.setObjectName(u"action_2") self.ac_logs.setObjectName(u"ac_logs")
self.action_3 = QAction(MainWindow) self.ac_logs.setMenuRole(QAction.MenuRole.NoRole)
self.action_3.setObjectName(u"action_3") self.ac_about = QAction(App)
self.action_4 = QAction(MainWindow) self.ac_about.setObjectName(u"ac_about")
self.action_4.setObjectName(u"action_4") self.ac_about.setMenuRole(QAction.MenuRole.NoRole)
self.centralwidget = QWidget(MainWindow) 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") self.centralwidget.setObjectName(u"centralwidget")
MainWindow.setCentralWidget(self.centralwidget) self.verticalLayout = QVBoxLayout(self.centralwidget)
self.menubar = QMenuBar(MainWindow) self.verticalLayout.setObjectName(u"verticalLayout")
self.menubar.setObjectName(u"menubar") self.horizontalLayout = QHBoxLayout()
self.menubar.setGeometry(QRect(0, 0, 1100, 33)) self.horizontalLayout.setObjectName(u"horizontalLayout")
self.menu = QMenu(self.menubar) self.lw_navigation = QListWidget(self.centralwidget)
self.menu.setObjectName(u"menu") QListWidgetItem(self.lw_navigation)
self.menu_2 = QMenu(self.menubar) QListWidgetItem(self.lw_navigation)
self.menu_2.setObjectName(u"menu_2") QListWidgetItem(self.lw_navigation)
self.menu_3 = QMenu(self.menubar) QListWidgetItem(self.lw_navigation)
self.menu_3.setObjectName(u"menu_3") QListWidgetItem(self.lw_navigation)
MainWindow.setMenuBar(self.menubar) QListWidgetItem(self.lw_navigation)
self.statusbar = QStatusBar(MainWindow) 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") 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.toolBar.addAction(self.ac_homepage)
self.menubar.addAction(self.menu_3.menuAction()) self.toolBar.addAction(self.ac_settings)
self.menubar.addAction(self.menu_2.menuAction()) self.toolBar.addAction(self.ac_logs)
self.menu.addAction(self.action_4) self.toolBar.addAction(self.ac_about)
self.menu.addAction(self.action_3) self.toolBar.addAction(self.ac_caging)
self.menu_2.addAction(self.action_2) self.toolBar.addAction(self.ac_quit)
self.retranslateUi(MainWindow) self.retranslateUi(App)
QMetaObject.connectSlotsByName(MainWindow) self.sw_pages.setCurrentIndex(0)
QMetaObject.connectSlotsByName(App)
# setupUi # setupUi
def retranslateUi(self, MainWindow): def retranslateUi(self, App):
MainWindow.setWindowTitle(QCoreApplication.translate("MainWindow", u"Toolbox", None)) App.setWindowTitle(QCoreApplication.translate("App", u"Toolbox", None))
self.actionExit.setText(QCoreApplication.translate("MainWindow", u"Exit", None)) self.ac_homepage.setText(QCoreApplication.translate("App", u"\u4e3b\u9875", None))
self.action.setText(QCoreApplication.translate("MainWindow", u"\u5173\u4e8e", None)) #if QT_CONFIG(tooltip)
self.actionExit_2.setText(QCoreApplication.translate("MainWindow", u"Exit", None)) self.ac_homepage.setToolTip(QCoreApplication.translate("App", u"Ctrl+Alt+H", None))
self.action_2.setText(QCoreApplication.translate("MainWindow", u"\u5173\u4e8e", None)) #endif // QT_CONFIG(tooltip)
self.action_3.setText(QCoreApplication.translate("MainWindow", u"\u9000\u51fa", None)) #if QT_CONFIG(shortcut)
self.action_4.setText(QCoreApplication.translate("MainWindow", u"\u8bbe\u7f6e", None)) self.ac_homepage.setShortcut(QCoreApplication.translate("App", u"Ctrl+Alt+H", None))
self.menu.setTitle(QCoreApplication.translate("MainWindow", u"\u6587\u4ef6", None)) #endif // QT_CONFIG(shortcut)
self.menu_2.setTitle(QCoreApplication.translate("MainWindow", u"\u5e2e\u52a9", None)) self.ac_settings.setText(QCoreApplication.translate("App", u"\u8bbe\u7f6e", None))
self.menu_3.setTitle(QCoreApplication.translate("MainWindow", u"\u65e5\u5fd7", 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 # retranslateUi

View File

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

View File

@@ -1,13 +1,12 @@
import json import json
import random
import sys import sys
import base64
import time
from typing import Callable, Any from typing import Callable, Any
from PySide6.QtWidgets import QApplication, QWidget, QMessageBox, QMainWindow from PySide6.QtWidgets import QApplication, QWidget, QMessageBox, QMainWindow, QHBoxLayout, QVBoxLayout, QLineEdit, QLabel
from PySide6.QtGui import QIcon, QPixmap, QShortcut from PySide6.QtGui import QIcon, QPixmap, QShortcut, QResizeEvent, QFont, QKeySequence
from PySide6.QtCore import Qt from PySide6.QtCore import Qt,QSize
from codes.ui.login import Ui_login 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.worker import Worker
from codes.common import clibs from codes.common import clibs
from codes.common.secure_encrypt import PassCipher from codes.common.secure_encrypt import PassCipher
@@ -36,45 +35,40 @@ class LoginWindow(QWidget, Ui_login):
self.le_username.setText("") self.le_username.setText("")
self.le_password.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(): def validate_login():
# with open(f"{clibs.base_path}/assets/conf/config.json", mode="rt", encoding="utf-8") as f_conf: nonlocal username, password
# accounts = json.load(f_conf)["account"] with open(f"{clibs.base_path}/assets/conf/config.json", mode="rt", encoding="utf-8") as f_conf:
# username = self.le_username.text() clibs.account = json.load(f_conf)
# if username not in accounts or len(self.le_password.text()) < 8: if username != clibs.account["username"] or len(password) < clibs.account["minimum_password_length"]:
# login_failed() login_failed()
# return False return False
#
# gen_salt() salt = PassCipher.gen_salt(password)
# cipher = PassCipher(clibs.salt) cipher = PassCipher(salt)
# try: # password_encrypt = cipher.encrypt(password)
# password = cipher.decrypt(accounts[username]) # print(f"password_encrypt = {password_encrypt}")
# except ValueError: # exit()
# login_failed() try:
# return False decrypt_password = cipher.decrypt(clibs.account["login_password"])
# except ValueError:
# if password != self.le_password.text(): login_failed()
# login_failed() return False
# return False
if password != decrypt_password:
login_failed()
return False
self.mainWindow = MainWindow() self.mainWindow = MainWindow()
self.mainWindow.show() self.mainWindow.show()
self.close()
self.deleteLater() self.deleteLater()
return True return True
username = self.le_username.text()
password = self.le_password.text()
validate_login() validate_login()
class MainWindow(QMainWindow, Ui_MainWindow): class MainWindow(QMainWindow, Ui_App):
def __init__(self): def __init__(self):
super().__init__() super().__init__()
self.conn = None self.conn = None
@@ -82,12 +76,16 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.thread = None self.thread = None
self.setupUi(self) self.setupUi(self)
self.pre_dos() self.pre_dos()
self.lock_overlay = None
def pre_dos(self): def pre_dos(self):
self.setWindowIcon(QIcon(f"{clibs.base_path}/assets/media/icon.ico")) self.setWindowIcon(QIcon(f"{clibs.base_path}/assets/media/icon.ico"))
db_operation.db_backup() db_operation.db_backup()
self.conn, self.cursor = db_operation.db_conn() 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): def launch(self, func, on_anything: Callable[..., Any] = print, *args, **kwargs):
self.thread = Worker(func, *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.finished.connect(lambda: on_anything({"finished": True}))
self.thread.start() 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__': if __name__ == '__main__':
app = QApplication(sys.argv) app = QApplication(sys.argv)
login = LoginWindow() login = LoginWindow()