dev 02012149
This commit is contained in:
159
da_ext_settings.py
Normal file
159
da_ext_settings.py
Normal file
@@ -0,0 +1,159 @@
|
||||
# coding: utf8
|
||||
from PySide6 import QtWidgets, QtCore
|
||||
|
||||
|
||||
class PushButtonWithId(QtWidgets.QPushButton):
|
||||
|
||||
clicked_with_id = QtCore.Signal(str)
|
||||
|
||||
def __init__(self, ids: str, parent: QtWidgets.QWidget = None, title: str = ""):
|
||||
super().__init__(title, parent)
|
||||
self.ids = ids
|
||||
self.clicked.connect(self.on_self_clicked)
|
||||
|
||||
def on_self_clicked(self):
|
||||
self.clicked_with_id.emit(self.ids)
|
||||
|
||||
|
||||
class DaExtSettings(QtWidgets.QDialog):
|
||||
|
||||
def __init__(self, parent: QtWidgets.QWidget = None):
|
||||
super().__init__(parent)
|
||||
self.setWindowTitle("设置")
|
||||
|
||||
self.vly_m = QtWidgets.QVBoxLayout()
|
||||
self.setLayout(self.vly_m)
|
||||
|
||||
self.gbx_exec = QtWidgets.QGroupBox("执行文件路径", self)
|
||||
self.vly_m.addWidget(self.gbx_exec)
|
||||
|
||||
self.gly_gbx_exec = QtWidgets.QGridLayout()
|
||||
self.gbx_exec.setLayout(self.gly_gbx_exec)
|
||||
|
||||
self.lb_exec_chrome = QtWidgets.QLabel("Chrome", self)
|
||||
self.lb_exec_edge = QtWidgets.QLabel("Edge", self)
|
||||
self.lb_exec_brave = QtWidgets.QLabel("Brave", self)
|
||||
self.lne_exec_chrome = QtWidgets.QLineEdit(self)
|
||||
self.lne_exec_edge = QtWidgets.QLineEdit(self)
|
||||
self.lne_exec_brave = QtWidgets.QLineEdit(self)
|
||||
self.pbn_exec_chrome = PushButtonWithId("ChromeExec", self, "选择")
|
||||
self.pbn_exec_edge = PushButtonWithId("EdgeExec", self, "选择")
|
||||
self.pbn_exec_brave = PushButtonWithId("BraveExec", self, "选择")
|
||||
|
||||
self.gly_gbx_exec.addWidget(self.lb_exec_chrome, 0, 0)
|
||||
self.gly_gbx_exec.addWidget(self.lb_exec_edge, 1, 0)
|
||||
self.gly_gbx_exec.addWidget(self.lb_exec_brave, 2, 0)
|
||||
self.gly_gbx_exec.addWidget(self.lne_exec_chrome, 0, 1)
|
||||
self.gly_gbx_exec.addWidget(self.lne_exec_edge, 1, 1)
|
||||
self.gly_gbx_exec.addWidget(self.lne_exec_brave, 2, 1)
|
||||
self.gly_gbx_exec.addWidget(self.pbn_exec_chrome, 0, 2)
|
||||
self.gly_gbx_exec.addWidget(self.pbn_exec_edge, 1, 2)
|
||||
self.gly_gbx_exec.addWidget(self.pbn_exec_brave, 2, 2)
|
||||
|
||||
self.gbx_data = QtWidgets.QGroupBox("用户数据路径", self)
|
||||
self.vly_m.addWidget(self.gbx_data)
|
||||
|
||||
self.gly_gbx_data = QtWidgets.QGridLayout()
|
||||
self.gbx_data.setLayout(self.gly_gbx_data)
|
||||
|
||||
self.lb_data_chrome = QtWidgets.QLabel("Chrome", self)
|
||||
self.lb_data_edge = QtWidgets.QLabel("Edge", self)
|
||||
self.lb_data_brave = QtWidgets.QLabel("Brave", self)
|
||||
self.lne_data_chrome = QtWidgets.QLineEdit(self)
|
||||
self.lne_data_edge = QtWidgets.QLineEdit(self)
|
||||
self.lne_data_brave = QtWidgets.QLineEdit(self)
|
||||
self.pbn_data_chrome = PushButtonWithId("ChromeData", self, "选择")
|
||||
self.pbn_data_edge = PushButtonWithId("EdgeData", self, "选择")
|
||||
self.pbn_data_brave = PushButtonWithId("BraveData", self, "选择")
|
||||
|
||||
self.gly_gbx_data.addWidget(self.lb_data_chrome, 0, 0)
|
||||
self.gly_gbx_data.addWidget(self.lb_data_edge, 1, 0)
|
||||
self.gly_gbx_data.addWidget(self.lb_data_brave, 2, 0)
|
||||
self.gly_gbx_data.addWidget(self.lne_data_chrome, 0, 1)
|
||||
self.gly_gbx_data.addWidget(self.lne_data_edge, 1, 1)
|
||||
self.gly_gbx_data.addWidget(self.lne_data_brave, 2, 1)
|
||||
self.gly_gbx_data.addWidget(self.pbn_data_chrome, 0, 2)
|
||||
self.gly_gbx_data.addWidget(self.pbn_data_edge, 1, 2)
|
||||
self.gly_gbx_data.addWidget(self.pbn_data_brave, 2, 2)
|
||||
|
||||
self.hly_bot = QtWidgets.QHBoxLayout()
|
||||
self.pbn_save = QtWidgets.QPushButton("保存", self)
|
||||
self.pbn_cancel = QtWidgets.QPushButton("取消", self)
|
||||
|
||||
self.hly_bot.addStretch(1)
|
||||
self.hly_bot.addWidget(self.pbn_save)
|
||||
self.hly_bot.addWidget(self.pbn_cancel)
|
||||
|
||||
self.vly_m.addLayout(self.hly_bot)
|
||||
self.vly_m.addStretch(1)
|
||||
|
||||
self.pbn_save.clicked.connect(self.on_pbn_save_clicked)
|
||||
self.pbn_cancel.clicked.connect(self.on_pbn_cancel_clicked)
|
||||
|
||||
self.pbn_exec_chrome.clicked_with_id.connect(self.on_pbn_exec_n_clicked_with_id)
|
||||
self.pbn_exec_edge.clicked_with_id.connect(self.on_pbn_exec_n_clicked_with_id)
|
||||
self.pbn_exec_brave.clicked_with_id.connect(self.on_pbn_exec_n_clicked_with_id)
|
||||
|
||||
self.pbn_data_chrome.clicked_with_id.connect(self.on_pbn_data_n_clicked_with_id)
|
||||
self.pbn_data_edge.clicked_with_id.connect(self.on_pbn_data_n_clicked_with_id)
|
||||
self.pbn_data_brave.clicked_with_id.connect(self.on_pbn_data_n_clicked_with_id)
|
||||
|
||||
self.read_settings()
|
||||
|
||||
def sizeHint(self):
|
||||
return QtCore.QSize(540, 140)
|
||||
|
||||
def read_settings(self):
|
||||
us = QtCore.QSettings()
|
||||
chrome_exec = str(us.value("ChromeExec", ""))
|
||||
edge_exec = str(us.value("EdgeExec", ""))
|
||||
brave_exec = str(us.value("BraveExec", ""))
|
||||
|
||||
chrome_data = str(us.value("ChromeData", ""))
|
||||
edge_data = str(us.value("EdgeData", ""))
|
||||
brave_data = str(us.value("BraveData", ""))
|
||||
|
||||
self.lne_exec_chrome.setText(chrome_exec)
|
||||
self.lne_exec_edge.setText(edge_exec)
|
||||
self.lne_exec_brave.setText(brave_exec)
|
||||
|
||||
self.lne_data_chrome.setText(chrome_data)
|
||||
self.lne_data_edge.setText(edge_data)
|
||||
self.lne_data_brave.setText(brave_data)
|
||||
|
||||
def on_pbn_exec_n_clicked_with_id(self, ids: str):
|
||||
filename, _ = QtWidgets.QFileDialog.getOpenFileName(self, f"选择 {ids}")
|
||||
if len(filename) == 0:
|
||||
return
|
||||
if ids == "ChromeExec":
|
||||
self.lne_exec_chrome.setText(filename)
|
||||
elif ids == "EdgeExec":
|
||||
self.lne_exec_edge.setText(filename)
|
||||
elif ids == "BraveExec":
|
||||
self.lne_exec_brave.setText(filename)
|
||||
|
||||
def on_pbn_data_n_clicked_with_id(self, ids: str):
|
||||
dirname = QtWidgets.QFileDialog.getExistingDirectory(self, f"选择 {ids}")
|
||||
if len(dirname) == 0:
|
||||
return
|
||||
if ids == "ChromeData":
|
||||
self.lne_data_chrome.setText(dirname)
|
||||
elif ids == "EdgeData":
|
||||
self.lne_data_edge.setText(dirname)
|
||||
elif ids == "BraveData":
|
||||
self.lne_data_brave.setText(dirname)
|
||||
|
||||
def on_pbn_save_clicked(self):
|
||||
us = QtCore.QSettings()
|
||||
us.setValue("ChromeExec", self.lne_exec_chrome.text())
|
||||
us.setValue("EdgeExec", self.lne_exec_edge.text())
|
||||
us.setValue("BraveExec", self.lne_exec_brave.text())
|
||||
|
||||
us.setValue("ChromeData", self.lne_data_chrome.text())
|
||||
us.setValue("EdgeData", self.lne_data_edge.text())
|
||||
us.setValue("BraveData", self.lne_data_brave.text())
|
||||
|
||||
self.accept()
|
||||
|
||||
def on_pbn_cancel_clicked(self):
|
||||
self.reject()
|
||||
157
da_show_profiles.py
Normal file
157
da_show_profiles.py
Normal file
@@ -0,0 +1,157 @@
|
||||
# coding: utf8
|
||||
import os
|
||||
from pathlib import Path
|
||||
from PySide6 import QtWidgets, QtCore, QtGui
|
||||
from util_ext import ProfilesData, DeleteThread, DeleteThreadManager
|
||||
from global_vars import accept_warning
|
||||
|
||||
|
||||
def sort_profiles_id_func(profile_id: str) -> int:
|
||||
if profile_id == "Default":
|
||||
return 0
|
||||
else:
|
||||
seq = profile_id.split(" ", 1)[-1]
|
||||
try:
|
||||
return int(seq)
|
||||
except ValueError:
|
||||
# if the id is weird
|
||||
return 999
|
||||
|
||||
|
||||
class ProfilesModel(QtCore.QAbstractTableModel):
|
||||
|
||||
def __init__(self,
|
||||
profiles_data: ProfilesData,
|
||||
ext_id: str,
|
||||
profiles: list[str],
|
||||
parent=None):
|
||||
super().__init__(parent)
|
||||
self.ext_id = ext_id
|
||||
self.profiles = profiles
|
||||
self.profiles.sort(key=sort_profiles_id_func)
|
||||
self.profiles_data = profiles_data
|
||||
|
||||
def rowCount(self, parent: QtCore.QModelIndex = ...):
|
||||
return len(self.profiles)
|
||||
|
||||
def columnCount(self, parent: QtCore.QModelIndex = ...):
|
||||
return 2
|
||||
|
||||
def data(self, index: QtCore.QModelIndex, role: int = ...):
|
||||
row = index.row()
|
||||
col = index.column()
|
||||
|
||||
if col == 0:
|
||||
if role == QtCore.Qt.ItemDataRole.DisplayRole:
|
||||
return self.profiles[row]
|
||||
elif col == 1:
|
||||
if role == QtCore.Qt.ItemDataRole.DisplayRole:
|
||||
return self.profiles_data[self.profiles[row]].name
|
||||
|
||||
def headerData(self, section: int, orientation: QtCore.Qt.Orientation, role: int = ...):
|
||||
if role == QtCore.Qt.ItemDataRole.DisplayRole:
|
||||
if section == 0:
|
||||
return "ID"
|
||||
if section == 1:
|
||||
return "名称"
|
||||
|
||||
|
||||
class DaShowProfiles(QtWidgets.QDialog):
|
||||
|
||||
def __init__(self,
|
||||
browser: str,
|
||||
is_chrome_compat: bool,
|
||||
profiles_data: ProfilesData,
|
||||
ext_id: str,
|
||||
ext_name: str,
|
||||
ext_icon: QtGui.QIcon,
|
||||
profiles: list[str],
|
||||
parent: QtWidgets.QWidget = None):
|
||||
super().__init__(parent)
|
||||
self.setWindowTitle(ext_name)
|
||||
self.setWindowIcon(ext_icon)
|
||||
self.browser = browser
|
||||
self.is_chrome_compat = is_chrome_compat
|
||||
|
||||
self.process = QtCore.QProcess(self)
|
||||
|
||||
# ========== UI ==============
|
||||
|
||||
self.vly_m = QtWidgets.QVBoxLayout()
|
||||
self.setLayout(self.vly_m)
|
||||
|
||||
self.lne_info = QtWidgets.QLineEdit(ext_id, self)
|
||||
self.lne_info.setReadOnly(True)
|
||||
self.vly_m.addWidget(self.lne_info)
|
||||
|
||||
self.trv_profiles = QtWidgets.QTreeView(self)
|
||||
self.trv_profiles.setSelectionMode(QtWidgets.QAbstractItemView.SelectionMode.ExtendedSelection)
|
||||
self.vly_m.addWidget(self.trv_profiles)
|
||||
|
||||
self.pgb_del = QtWidgets.QProgressBar(self)
|
||||
self.pgb_del.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
|
||||
self.vly_m.addWidget(self.pgb_del)
|
||||
|
||||
self.hly_bot = QtWidgets.QHBoxLayout()
|
||||
self.pbn_delete_selected = QtWidgets.QPushButton("删除所选", self)
|
||||
self.pbn_open = QtWidgets.QPushButton("打开", self)
|
||||
self.pbn_cancel = QtWidgets.QPushButton("取消", self)
|
||||
self.hly_bot.addWidget(self.pbn_delete_selected)
|
||||
self.hly_bot.addStretch(1)
|
||||
self.hly_bot.addWidget(self.pbn_open)
|
||||
self.hly_bot.addWidget(self.pbn_cancel)
|
||||
self.vly_m.addLayout(self.hly_bot)
|
||||
|
||||
self.profiles_model = ProfilesModel(profiles_data, ext_id, profiles, self)
|
||||
self.trv_profiles.setModel(self.profiles_model)
|
||||
|
||||
self.pbn_delete_selected.clicked.connect(self.on_pbn_delete_selected_clicked)
|
||||
self.pbn_open.clicked.connect(self.on_pbn_open_clicked)
|
||||
self.pbn_cancel.clicked.connect(self.reject)
|
||||
|
||||
def sizeHint(self):
|
||||
return QtCore.QSize(400, 360)
|
||||
|
||||
def on_pbn_open_clicked(self):
|
||||
us = QtCore.QSettings()
|
||||
exec_path = str(us.value(f"{self.browser}Exec", ""))
|
||||
if len(exec_path) == 0 or not os.path.exists(exec_path):
|
||||
QtWidgets.QMessageBox.critical(self, "错误", f"无法找到 {self.browser} 浏览器的执行路径")
|
||||
return
|
||||
|
||||
indexes = self.trv_profiles.selectedIndexes()
|
||||
cmd = rf'"{exec_path}" --profile-directory="{{0}}"'
|
||||
for idx in indexes:
|
||||
if idx.column() != 0:
|
||||
continue
|
||||
profile_id = self.profiles_model.data(idx, QtCore.Qt.ItemDataRole.DisplayRole)
|
||||
# setProgram 不行,不知道为什么,莫名其妙
|
||||
self.process.startCommand(cmd.format(profile_id))
|
||||
self.process.waitForFinished(10000)
|
||||
|
||||
def on_pbn_delete_selected_clicked(self):
|
||||
us = QtCore.QSettings()
|
||||
user_data_path = str(us.value(f"{self.browser}Data", ""))
|
||||
if self.browser == "Chrome" and self.is_chrome_compat:
|
||||
pref_name = "Preferences"
|
||||
else:
|
||||
pref_name = "Secure Preferences"
|
||||
|
||||
indexes = self.trv_profiles.selectedIndexes()
|
||||
total = len(indexes) // 2
|
||||
if accept_warning(self, True, "警告", f"确定要删除这 {total} 项吗?"):
|
||||
return
|
||||
|
||||
del_thd_mgr = DeleteThreadManager(total, self.pgb_del, self)
|
||||
|
||||
for idx in indexes:
|
||||
if idx.column() != 0:
|
||||
continue
|
||||
profile_id = self.profiles_model.data(idx, QtCore.Qt.ItemDataRole.DisplayRole)
|
||||
del_thd = DeleteThread(
|
||||
str(Path(user_data_path, profile_id)),
|
||||
pref_name,
|
||||
[self.lne_info.text()],
|
||||
self
|
||||
)
|
||||
del_thd_mgr.start(del_thd)
|
||||
50
main.py
50
main.py
@@ -1,15 +1,63 @@
|
||||
# coding: utf8
|
||||
import os
|
||||
import sys
|
||||
from PySide6 import QtWidgets
|
||||
from pathlib import Path
|
||||
from PySide6 import QtWidgets, QtCore
|
||||
from mw_dailycheck import MwDailyCheck
|
||||
|
||||
import daily_check_rc
|
||||
|
||||
version = (0, 1, 0)
|
||||
|
||||
ORG_NAME = "JnPrograms"
|
||||
APP_NAME = "DailyCheck"
|
||||
|
||||
|
||||
def set_default_settings():
|
||||
plat = sys.platform
|
||||
user_path = os.path.expanduser("~")
|
||||
user_data_path_map = {
|
||||
"win32": {
|
||||
"Chrome": Path(user_path, r"AppData\Local\Google\Chrome\User Data"),
|
||||
"Edge": Path(user_path, r"AppData\Local\Microsoft\Edge\User Data"),
|
||||
"Brave": Path(user_path, r"AppData\Local\BraveSoftware\Brave-Browser\User Data"),
|
||||
},
|
||||
"darwin": {
|
||||
"Chrome": Path(user_path, "Library/Application Support/Google/Chrome"),
|
||||
"Edge": Path(user_path, "Library/Application Support/Microsoft Edge"),
|
||||
"Brave": Path(user_path, "Library/Application Support/BraveSoftware/Brave-Browser"),
|
||||
},
|
||||
}
|
||||
exec_path_map = {
|
||||
"win32": {
|
||||
"Chrome": r"C:\Program Files\Google\Chrome\Application\chrome.exe",
|
||||
"Edge": r"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe",
|
||||
"Brave": r"C:\Program Files\BraveSoftware\Brave-Browser\Application\brave.exe",
|
||||
},
|
||||
"darwin": {
|
||||
"Chrome": r"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
|
||||
"Edge": r"/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge",
|
||||
"Brave": r"/Applications/Brave Browser.app/Contents/MacOS/Brave Browser",
|
||||
},
|
||||
}
|
||||
user_data_path = user_data_path_map[plat]
|
||||
exec_path = exec_path_map[plat]
|
||||
us = QtCore.QSettings()
|
||||
us.setValue("ChromeExec", exec_path["Chrome"])
|
||||
us.setValue("EdgeExec", exec_path["Edge"])
|
||||
us.setValue("BraveExec", exec_path["Brave"])
|
||||
us.setValue("ChromeData", user_data_path["Chrome"])
|
||||
us.setValue("EdgeData", user_data_path["Edge"])
|
||||
us.setValue("BraveData", user_data_path["Brave"])
|
||||
|
||||
|
||||
def main():
|
||||
app = QtWidgets.QApplication(sys.argv)
|
||||
app.setOrganizationName(ORG_NAME)
|
||||
app.setApplicationName(APP_NAME)
|
||||
|
||||
set_default_settings()
|
||||
|
||||
win = MwDailyCheck(version)
|
||||
win.show()
|
||||
return app.exec()
|
||||
|
||||
@@ -96,6 +96,5 @@ class MwDailyCheck(QtWidgets.QMainWindow):
|
||||
}
|
||||
unknown_all.update(unknown_isp_manu)
|
||||
|
||||
with open(ex_file, "w", encoding="utf8") as f:
|
||||
json.dump(unknown_all, f, indent=4, ensure_ascii=False)
|
||||
ex_file.write_text(json.dumps(unknown_all, indent=4, ensure_ascii=False), "utf8")
|
||||
QtWidgets.QMessageBox.information(self, "提示", f"已导出到 {ex_file}")
|
||||
|
||||
152
util_ext.py
152
util_ext.py
@@ -1,31 +1,14 @@
|
||||
# coding: utf8
|
||||
import os
|
||||
import sys
|
||||
import json
|
||||
import shutil
|
||||
from pathlib import Path
|
||||
# from typing import Callable
|
||||
from PySide6 import QtCore, QtWidgets
|
||||
from dataclasses import dataclass, field
|
||||
from global_vars import get_with_chained_keys
|
||||
|
||||
|
||||
PLAT = sys.platform
|
||||
USER_PATH = os.path.expanduser("~")
|
||||
|
||||
USER_DATA_PATH_MAP = {
|
||||
"win32": {
|
||||
"Chrome": Path(USER_PATH, "AppData", "Local", "Google", "Chrome", "User Data"),
|
||||
"Edge": Path(USER_PATH, "AppData", "Local", "Microsoft", "Edge", "User Data"),
|
||||
"Brave": Path(USER_PATH, "AppData", "Local", "BraveSoftware", "Brave-Browser", "User Data"),
|
||||
},
|
||||
"darwin": {
|
||||
"Chrome": Path(USER_PATH, "Library", "Application Support", "Google", "Chrome"),
|
||||
"Edge": Path(USER_PATH, "Library", "Application Support", "Microsoft Edge"),
|
||||
"Brave": Path(USER_PATH, "Library", "Application Support", "BraveSoftware", "Brave-Browser"),
|
||||
},
|
||||
}
|
||||
|
||||
USER_DATA_PATH = USER_DATA_PATH_MAP[PLAT]
|
||||
|
||||
|
||||
@dataclass
|
||||
class ProfileNode(object):
|
||||
gaia_given_name: str
|
||||
@@ -38,8 +21,11 @@ class ProfileNode(object):
|
||||
ProfilesData = dict[str, ProfileNode]
|
||||
|
||||
|
||||
def scan_profiles(browser: str) -> ProfilesData:
|
||||
local_state_path = Path(USER_DATA_PATH[browser], "Local State")
|
||||
def scan_profiles(user_data_path: str) -> ProfilesData:
|
||||
local_state_path = Path(user_data_path, "Local State")
|
||||
if not local_state_path.exists():
|
||||
return {}
|
||||
|
||||
local_state_data: dict = json.loads(local_state_path.read_text(encoding="utf8"))
|
||||
info_cache_data: dict = get_with_chained_keys(local_state_data, ["profile", "info_cache"])
|
||||
|
||||
@@ -61,6 +47,7 @@ def scan_profiles(browser: str) -> ProfilesData:
|
||||
|
||||
@dataclass
|
||||
class ExtensionNode(object):
|
||||
# ids: str
|
||||
icon: str
|
||||
name: str
|
||||
# path: str
|
||||
@@ -86,18 +73,22 @@ def get_extension_icon_path(ext_icons: dict[str, str], ext_path: str, profile_pa
|
||||
return str(full_path)
|
||||
|
||||
|
||||
def scan_extensions(browser: str, is_chrome_compat=False) -> ExtensionsData:
|
||||
profile_data = scan_profiles(browser)
|
||||
def scan_extensions(browser: str, is_chrome_compat=False) -> tuple[ExtensionsData, ProfilesData]:
|
||||
us = QtCore.QSettings()
|
||||
user_data_path = str(us.value(f"{browser}Data", ""))
|
||||
if len(user_data_path) == 0 or not Path(user_data_path).exists():
|
||||
return {}, {}
|
||||
|
||||
profile_data = scan_profiles(user_data_path)
|
||||
extensions_data: ExtensionsData = {}
|
||||
|
||||
browser_data_path = USER_DATA_PATH[browser]
|
||||
if browser == "Chrome" and is_chrome_compat:
|
||||
pref_file = "Preferences"
|
||||
else:
|
||||
pref_file = "Secure Preferences"
|
||||
|
||||
for profile_id in profile_data:
|
||||
profile_path = Path(browser_data_path, profile_id)
|
||||
profile_path = Path(user_data_path, profile_id)
|
||||
secure_pref_path = Path(profile_path, pref_file)
|
||||
secure_pref_data: dict = json.loads(secure_pref_path.read_text(encoding="utf8"))
|
||||
ext_settings_data: dict = get_with_chained_keys(secure_pref_data, ["extensions", "settings"], dict())
|
||||
@@ -122,6 +113,7 @@ def scan_extensions(browser: str, is_chrome_compat=False) -> ExtensionsData:
|
||||
|
||||
if ext_id not in extensions_data:
|
||||
ext_node = ExtensionNode(
|
||||
# ids=ext_id,
|
||||
icon=get_extension_icon_path(ext_manifest.get("icons", {}), ext_path, profile_path),
|
||||
name=ext_manifest.get("name", ""),
|
||||
# path=ext_data.get("path", ""),
|
||||
@@ -132,4 +124,110 @@ def scan_extensions(browser: str, is_chrome_compat=False) -> ExtensionsData:
|
||||
ext_node = extensions_data[ext_id]
|
||||
ext_node.profiles += [profile_id]
|
||||
|
||||
return extensions_data
|
||||
return extensions_data, profile_data
|
||||
|
||||
|
||||
# ================== Deletion ====================
|
||||
|
||||
|
||||
def delete_extensions(profile_path: str, pref_name: str, ext_ids: list[str]) -> tuple[int, int]:
|
||||
total = len(ext_ids)
|
||||
|
||||
e_pref_path = Path(profile_path, pref_name)
|
||||
e_pref_data = json.loads(e_pref_path.read_text("utf8")) # type: dict
|
||||
ext_set_data = get_with_chained_keys(e_pref_data, ["extensions", "settings"]) # type: dict
|
||||
if ext_set_data is None:
|
||||
return 0, total
|
||||
|
||||
s_pref_path = Path(profile_path, "Secure Preferences")
|
||||
pref_path = Path(profile_path, "Preferences")
|
||||
s_pref_data = json.loads(s_pref_path.read_text("utf8")) # type: dict
|
||||
pref_data = json.loads(pref_path.read_text("utf8")) # type: dict
|
||||
|
||||
macs = get_with_chained_keys(s_pref_data, ["protection", "macs", "extensions", "settings"]) # type: dict
|
||||
if macs is None:
|
||||
return 0, total
|
||||
|
||||
success = 0
|
||||
for ids in ext_ids:
|
||||
c1 = ext_set_data.pop(ids, None)
|
||||
c2 = macs.pop(ids, None)
|
||||
if None not in (c1, c2):
|
||||
success += 1
|
||||
|
||||
pinned_ext = get_with_chained_keys(pref_data, ["extensions", "pinned_extensions"]) # type: list
|
||||
if pinned_ext is not None:
|
||||
for ids in ext_ids:
|
||||
if ids in pinned_ext:
|
||||
pinned_ext.remove(ids)
|
||||
|
||||
s_pref_path.write_text(json.dumps(s_pref_data, ensure_ascii=False), "utf8")
|
||||
pref_path.write_text(json.dumps(pref_data, ensure_ascii=False), "utf8")
|
||||
|
||||
extensions_path_d = Path(profile_path, "Extensions")
|
||||
for ids in ext_ids:
|
||||
# 对于离线安装的插件,目录可能不在这个位置,所以就不删了
|
||||
ext_folder_path = Path(extensions_path_d, ids)
|
||||
if ext_folder_path.exists():
|
||||
shutil.rmtree(ext_folder_path, ignore_errors=True)
|
||||
|
||||
return success, total
|
||||
|
||||
|
||||
class DeleteThread(QtCore.QThread):
|
||||
|
||||
deleted = QtCore.Signal(int, int)
|
||||
|
||||
def __init__(self,
|
||||
profile_path: str,
|
||||
pref_name: str,
|
||||
ext_ids: list[str],
|
||||
parent: QtCore.QObject = None):
|
||||
super().__init__(parent)
|
||||
self.profile_path = profile_path
|
||||
self.pref_name = pref_name
|
||||
self.ext_ids = ext_ids
|
||||
self.finished.connect(self.deleteLater)
|
||||
|
||||
def run(self):
|
||||
success, total = delete_extensions(self.profile_path, self.pref_name, self.ext_ids)
|
||||
self.deleted.emit(success, total)
|
||||
|
||||
|
||||
class DeleteThreadManager(QtCore.QObject):
|
||||
|
||||
def __init__(self, total: int, progress_bar: QtWidgets.QProgressBar, parent: QtWidgets.QDialog):
|
||||
super().__init__(parent)
|
||||
self.deletion_progress = 0
|
||||
self.success_deletion = 0
|
||||
self.fail_deletion = 0
|
||||
self.total_for_deletion = total
|
||||
self.deletion_info = "成功:{success} 个;失败:{fail} 个;总共 {total} 个。"
|
||||
self.progress_bar = progress_bar
|
||||
self.parent = parent
|
||||
|
||||
self.progress_bar.setMaximum(total)
|
||||
self.progress_bar.setValue(0)
|
||||
|
||||
self.progress_bar.valueChanged.connect(self.on_pgb_del_value_changed)
|
||||
|
||||
def start(self, thread: DeleteThread):
|
||||
thread.deleted.connect(self.on_del_thd_deleted)
|
||||
thread.start()
|
||||
|
||||
def on_del_thd_deleted(self, success: int, total: int):
|
||||
self.success_deletion += success
|
||||
self.deletion_progress += total
|
||||
self.fail_deletion += total - success
|
||||
self.progress_bar.setValue(self.deletion_progress)
|
||||
|
||||
def on_pgb_del_value_changed(self, value: int):
|
||||
if value == self.total_for_deletion:
|
||||
QtWidgets.QMessageBox.information(
|
||||
self.parent, "删除结果", self.deletion_info.format(
|
||||
success=self.success_deletion,
|
||||
fail=self.fail_deletion,
|
||||
total=self.total_for_deletion
|
||||
)
|
||||
)
|
||||
self.parent.accept()
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
# coding: utf8
|
||||
from PySide6 import QtWidgets, QtCore, QtGui
|
||||
from util_ext import scan_extensions, ExtensionsData
|
||||
from util_ext import scan_extensions, ExtensionsData, ProfilesData
|
||||
from global_vars import (
|
||||
ExtensionStatusRole,
|
||||
ExtensionIdRole,
|
||||
)
|
||||
from da_ext_settings import DaExtSettings
|
||||
from da_show_profiles import DaShowProfiles
|
||||
|
||||
|
||||
class UiWgExtensions(object):
|
||||
@@ -24,6 +26,7 @@ class UiWgExtensions(object):
|
||||
self.cbx_unknown.setChecked(True)
|
||||
self.cbx_chrome_compat = QtWidgets.QCheckBox("谷歌兼容模式", window)
|
||||
self.pbn_update = QtWidgets.QPushButton("更新", window)
|
||||
self.pbn_settings = QtWidgets.QPushButton("设置", window)
|
||||
self.hly_top.addWidget(self.cmbx_browsers)
|
||||
self.hly_top.addWidget(self.cbx_safe)
|
||||
self.hly_top.addWidget(self.cbx_unsafe)
|
||||
@@ -31,6 +34,7 @@ class UiWgExtensions(object):
|
||||
self.hly_top.addStretch(1)
|
||||
self.hly_top.addWidget(self.cbx_chrome_compat)
|
||||
self.hly_top.addWidget(self.pbn_update)
|
||||
self.hly_top.addWidget(self.pbn_settings)
|
||||
|
||||
self.lv_extensions = QtWidgets.QListView(window)
|
||||
self.vly_m.addWidget(self.lv_extensions)
|
||||
@@ -40,6 +44,7 @@ class BaseExtensionsListModel(QtCore.QAbstractListModel):
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
self.all_profiles = {} # type: ProfilesData
|
||||
self.all_extensions = {} # type: ExtensionsData
|
||||
self.names = [] # type: list[tuple[str, str]]
|
||||
self.icons = {} # type: dict[str, QtGui.QIcon]
|
||||
@@ -51,11 +56,12 @@ class BaseExtensionsListModel(QtCore.QAbstractListModel):
|
||||
|
||||
def update_ext(self, browser: str, is_chrome_compat=False):
|
||||
"""内部用"""
|
||||
self.all_profiles.clear()
|
||||
self.all_extensions.clear()
|
||||
self.names.clear()
|
||||
self.icons.clear()
|
||||
|
||||
self.all_extensions = scan_extensions(browser, is_chrome_compat)
|
||||
self.all_extensions, self.all_profiles = scan_extensions(browser, is_chrome_compat)
|
||||
for ext_id in self.all_extensions:
|
||||
name = self.all_extensions[ext_id].name
|
||||
icon = self.all_extensions[ext_id].icon
|
||||
@@ -168,6 +174,12 @@ class WgExtensions(QtWidgets.QWidget):
|
||||
self.ui.cbx_unsafe.clicked.connect(self.on_cbx_unsafe_clicked)
|
||||
self.ui.cbx_unknown.clicked.connect(self.on_cbx_unknown_clicked)
|
||||
self.ui.pbn_update.clicked.connect(self.on_pbn_update_clicked)
|
||||
self.ui.pbn_settings.clicked.connect(self.on_pbn_settings_clicked)
|
||||
self.ui.lv_extensions.doubleClicked.connect(self.on_lv_extensions_double_clicked)
|
||||
|
||||
def on_pbn_settings_clicked(self):
|
||||
da_es = DaExtSettings(self)
|
||||
da_es.exec()
|
||||
|
||||
def get_current_browser(self) -> str:
|
||||
return self.ui.cmbx_browsers.currentData(QtCore.Qt.ItemDataRole.DisplayRole)
|
||||
@@ -225,6 +237,22 @@ class WgExtensions(QtWidgets.QWidget):
|
||||
def on_pbn_update_clicked(self):
|
||||
self.update_model(self.get_current_browser())
|
||||
|
||||
def on_lv_extensions_double_clicked(self, index: QtCore.QModelIndex):
|
||||
model = self.ext_list_models[self.get_current_browser()]
|
||||
ext_id = model.data(index, ExtensionIdRole)
|
||||
node = model.all_extensions[ext_id]
|
||||
da_sp = DaShowProfiles(
|
||||
self.get_current_browser(),
|
||||
self.ui.cbx_chrome_compat.isChecked(),
|
||||
model.all_profiles,
|
||||
ext_id,
|
||||
node.name,
|
||||
model.icons[ext_id],
|
||||
node.profiles,
|
||||
self
|
||||
)
|
||||
da_sp.exec()
|
||||
|
||||
def update_safe(self, safe_info: dict):
|
||||
for browser in self.ext_list_models:
|
||||
self.ext_list_models[browser].update_safe_info(safe_info)
|
||||
|
||||
Reference in New Issue
Block a user