diff --git a/src/assets/Hoyo-Glyphs/StarRailNeue-Sans-Regular.otf b/src/assets/Hoyo-Glyphs/StarRailNeue-Sans-Regular.otf index e2aa90d..8e0ba9f 100644 Binary files a/src/assets/Hoyo-Glyphs/StarRailNeue-Sans-Regular.otf and b/src/assets/Hoyo-Glyphs/StarRailNeue-Sans-Regular.otf differ diff --git a/src/assets/Hoyo-Glyphs/StarRailNeue-Serif-Regular.otf b/src/assets/Hoyo-Glyphs/StarRailNeue-Serif-Regular.otf index d0ccef4..11510b5 100644 Binary files a/src/assets/Hoyo-Glyphs/StarRailNeue-Serif-Regular.otf and b/src/assets/Hoyo-Glyphs/StarRailNeue-Serif-Regular.otf differ diff --git a/src/modules/Core/GachaReport/gacha_report_thread.py b/src/modules/Core/GachaReport/gacha_report_thread.py index 450a0e1..5abe431 100644 --- a/src/modules/Core/GachaReport/gacha_report_thread.py +++ b/src/modules/Core/GachaReport/gacha_report_thread.py @@ -1,5 +1,6 @@ import datetime import json +import os import pathlib import pickle import time @@ -19,46 +20,97 @@ class GachaReportThread(QThread): trigger = Signal(tuple) - def __init__(self, gachaUrl, parent=None): + def __init__(self, gachaUrl, parent=None, isAdd=False): super(GachaReportThread, self).__init__(parent) self.uid = "" self.region_time_zone = "" self.gachaUrl = gachaUrl + self.isAdd = isAdd def run(self): - SRGFExportJsonData = SRGF_DATA_MODEL - gachaList = [] - for key in GACHATYPE.keys(): - end_id = "0" - page = 0 - while True: - apiPerUnit = updateAPI(self.gachaUrl, GACHATYPE[key], 20, page, end_id) - responsePerUnit = json.loads(requests.get(apiPerUnit).content.decode("utf-8")) - if responsePerUnit["data"]: - gachaPerResponse = responsePerUnit["data"]["list"] - if not len(gachaPerResponse): - break - self.uid = responsePerUnit['data']["list"][0]['uid'] - self.region_time_zone = str(responsePerUnit['data']["region_time_zone"]) - self.trigger.emit((0, f"正在获取第{str(page + 1)}页 | {key}", self.uid)) - for i in gachaPerResponse: - gachaList.append(originalToSRGFListUnit(i)) - end_id = responsePerUnit["data"]["list"][-1]["id"] - page += 1 - self.msleep(300) - else: - self.trigger.emit((-1, f"数据获取失败", "请检查:\n你输入URL是否可用\n距离上一次在游戏内打开跃迁记录的时间间隔在一天以内")) - return - pathlib.Path(f"{utils.working_dir}/data/{self.uid}").mkdir(parents=True, exist_ok=True) - SRGFExportJsonData["info"]["export_timestamp"] = int(time.mktime(datetime.datetime.now().timetuple())) - SRGFExportJsonData["info"]["export_app"] = "asta" - SRGFExportJsonData["info"]["export_app_version"] = utils.app_version - SRGFExportJsonData["info"]["srgf_version"] = SRGF_VERSION - SRGFExportJsonData["info"]["region_time_zone"] = int(self.region_time_zone) - SRGFExportJsonData['info']['uid'] = self.uid - SRGFExportJsonData["list"] = gachaList - open(f"{utils.working_dir}/data/{self.uid}/{self.uid}_export_data.json", "w", encoding="utf-8").write( - json.dumps(SRGFExportJsonData, indent=2, sort_keys=True, ensure_ascii=False)) - with open(f"{utils.working_dir}/data/{self.uid}/{self.uid}_data.pickle", 'wb') as f: - pickle.dump(SRGFExportJsonData, f) - self.trigger.emit((1, "跃迁记录更新完毕", self.uid)) + if not self.isAdd: + SRGFExportJsonData = SRGF_DATA_MODEL + gachaList = [] + for key in GACHATYPE.keys(): + end_id = "0" + page = 0 + while True: + apiPerUnit = updateAPI(self.gachaUrl, GACHATYPE[key], 20, page, end_id) + responsePerUnit = json.loads(requests.get(apiPerUnit).content.decode("utf-8")) + if responsePerUnit["data"]: + gachaPerResponse = responsePerUnit["data"]["list"] + if not len(gachaPerResponse): + break + self.uid = responsePerUnit['data']["list"][0]['uid'] + self.region_time_zone = str(responsePerUnit['data']["region_time_zone"]) + self.trigger.emit((0, f"正在获取第{str(page + 1)}页 | {key}", self.uid)) + for i in gachaPerResponse: + gachaList.append(originalToSRGFListUnit(i)) + end_id = responsePerUnit["data"]["list"][-1]["id"] + page += 1 + self.msleep(300) + else: + self.trigger.emit((-1, f"数据获取失败", "请检查:\n你输入URL是否可用\n距离上一次在游戏内打开跃迁记录的时间间隔在一天以内")) + return + pathlib.Path(f"{utils.working_dir}/data/{self.uid}").mkdir(parents=True, exist_ok=True) + SRGFExportJsonData["info"]["export_timestamp"] = int(time.mktime(datetime.datetime.now().timetuple())) + SRGFExportJsonData["info"]["export_app"] = "asta" + SRGFExportJsonData["info"]["export_app_version"] = utils.app_version + SRGFExportJsonData["info"]["srgf_version"] = SRGF_VERSION + SRGFExportJsonData["info"]["region_time_zone"] = int(self.region_time_zone) + SRGFExportJsonData['info']['uid'] = self.uid + SRGFExportJsonData["list"] = gachaList + open(f"{utils.working_dir}/data/{self.uid}/{self.uid}_export_data.json", "w", encoding="utf-8").write( + json.dumps(SRGFExportJsonData, indent=2, sort_keys=True, ensure_ascii=False)) + with open(f"{utils.working_dir}/data/{self.uid}/{self.uid}_data.pickle", 'wb') as f: + pickle.dump(SRGFExportJsonData, f) + self.trigger.emit((1, "跃迁记录更新完毕", self.uid)) + else: + dataPath = f"{utils.working_dir}/data/{self.isAdd}/{self.isAdd}_data.pickle" + if not os.path.exists(dataPath): + self.trigger.emit((-1, f"增量更新失败", + "请检查是否对当前UID进行过全量更新")) + return + data = pickle.load(open(dataPath, 'rb')) + gachaList = data["list"] + for key in GACHATYPE.keys(): + latestId = [i["id"] for i in gachaList if i["gacha_type"] == GACHATYPE[key]] + gachaTypeEnd = False + if latestId: + latestId = latestId[0] + end_id = "0" + page = 0 + while True: + apiPerUnit = updateAPI(self.gachaUrl, GACHATYPE[key], 20, page, end_id) + responsePerUnit = json.loads(requests.get(apiPerUnit).content.decode("utf-8")) + if responsePerUnit["data"]: + gachaPerResponse = responsePerUnit["data"]["list"] + if not len(gachaPerResponse): + break + self.uid = responsePerUnit['data']["list"][0]['uid'] + self.region_time_zone = str(responsePerUnit['data']["region_time_zone"]) + self.trigger.emit((0, f"正在获取第{str(page + 1)}页 | {key}", self.uid)) + for i in gachaPerResponse: + if i["id"] == latestId: + gachaTypeEnd = True + break + gachaList.append(originalToSRGFListUnit(i)) + if gachaTypeEnd: + break + end_id = responsePerUnit["data"]["list"][-1]["id"] + page += 1 + self.msleep(300) + else: + self.trigger.emit((-1, f"数据获取失败", "请检查:\n你输入URL是否可用\n距离上一次在游戏内打开跃迁记录的时间间隔在一天以内")) + return + data["info"]["export_app"] = "asta" + data["info"]["export_app_version"] = utils.app_version + data["info"]["srgf_version"] = SRGF_VERSION + data["info"]["region_time_zone"] = int(self.region_time_zone) + data['info']['uid'] = self.uid + data["list"] = gachaList + open(f"{utils.working_dir}/data/{self.uid}/{self.uid}_export_data.json", "w", encoding="utf-8").write( + json.dumps(data, indent=2, sort_keys=True, ensure_ascii=False)) + with open(f"{utils.working_dir}/data/{self.uid}/{self.uid}_data.pickle", 'wb') as f: + pickle.dump(data, f) + self.trigger.emit((1, "跃迁记录更新完毕", self.uid)) \ No newline at end of file diff --git a/src/modules/Core/GachaReport/gacha_report_utils.py b/src/modules/Core/GachaReport/gacha_report_utils.py index 006c5ce..202b104 100644 --- a/src/modules/Core/GachaReport/gacha_report_utils.py +++ b/src/modules/Core/GachaReport/gacha_report_utils.py @@ -12,7 +12,7 @@ def getDefaultGameDataPath(): return 0, "Game Log Not found" with open(GAME_LOG_PATH, 'r', encoding='utf-8') as f: logFile = f.read() - match = re.match(r'Loading player data from (.*)StarRail_Data.*', logFile) + match = re.search(r'Loading player data from (.*)StarRail_Data.*', logFile) game_path = match.group(1) if match else None logging.info(f"[GachaReport.utils] Game Path get: {game_path}") return game_path diff --git a/src/modules/Views/ViewFunctions/home_functions.py b/src/modules/Views/ViewFunctions/home_functions.py index a1673ca..b4d0a76 100644 --- a/src/modules/Views/ViewFunctions/home_functions.py +++ b/src/modules/Views/ViewFunctions/home_functions.py @@ -23,10 +23,9 @@ def run(self): self.trigger.emit(0, 0, "正在获取信息...", "未知", character1ImagePath) self.trigger.emit(1, 0, "正在获取信息...", "未知", character1ImagePath) upWeaponList = [] - if not os.path.exists(f"{utils.working_dir}/cache/announce.json"): - downloader.downloadFromJson(ANNOUNCE_REQUEST_URL, utils.working_dir + "/cache/", "announce.json") - downloader.downloadFromJson(ANNOUNCE_ICON_REQUEST_URL, utils.working_dir + "/cache/", - "announce_icons.json") + downloader.downloadFromJson(ANNOUNCE_REQUEST_URL, utils.working_dir + "/cache/", "announce.json") + downloader.downloadFromJson(ANNOUNCE_ICON_REQUEST_URL, utils.working_dir + "/cache/", + "announce_icons.json") downloader.downloadFromJson(ANNOUNCE_CURRENT_UP_URL, utils.working_dir + "/cache/", "current_up.json") if os.path.exists(f"{utils.working_dir}/cache/current_up.json") and os.path.exists(f"{utils.working_dir}/cache/announce.json"): originalCurrentUPInfo = json.loads(open(f"{utils.working_dir}/cache/current_up.json", 'r', encoding="utf-8").read())["data"]["list"] diff --git a/src/modules/Views/announcement_frame.py b/src/modules/Views/announcement_frame.py index 0163e8b..9ec7dbe 100644 --- a/src/modules/Views/announcement_frame.py +++ b/src/modules/Views/announcement_frame.py @@ -30,6 +30,12 @@ def __init__(self, parent=None): self.announceData = announcement_functions.get_announce_data() self.announceIconData = announcement_functions.get_announce_icon_data() + if not self.announceData or not self.announceIconData: + logging.info("[Announcement] Get announce.json") + downloader.downloadFromJson(ANNOUNCE_REQUEST_URL, utils.working_dir + "/cache/", "announce.json") + logging.info("[Announcement] Get announce_icon.json") + downloader.downloadFromJson(ANNOUNCE_ICON_REQUEST_URL, utils.working_dir + "/cache/", + "announce_icons.json") self.currentAnnounceHTMLPath = "" self.headerHBox = QHBoxLayout(self) diff --git a/src/modules/Views/gacha_report_frame.py b/src/modules/Views/gacha_report_frame.py index 8217216..ce6b848 100644 --- a/src/modules/Views/gacha_report_frame.py +++ b/src/modules/Views/gacha_report_frame.py @@ -65,12 +65,17 @@ def __init__(self, parent=None): self.headerRightHBox = QHBoxLayout() self.headerRightGachaTypeCombobox = ComboBox(self) self.headerRightUIDSelectCombobox = ComboBox(self) + self.headerRightAddUpdateDropBtn = DropDownPushButton("增量更新", self, FluentIcon.UPDATE) + self.headerRightAddUpdateDropBtnWebCacheAction = Action(FluentIcon.DOCUMENT.icon(), "网页缓存获取") + self.headerRightAddUpdateDropBtnURLAction = Action(FluentIcon.ALIGNMENT.icon(), "手动URL获取") self.headerRightFullUpdateDropBtn = DropDownPushButton("全量更新", self, FluentIcon.UPDATE) self.headerRightFullUpdateDropBtnWebCacheAction = Action(FluentIcon.DOCUMENT.icon(), "网页缓存获取") self.headerRightFullUpdateDropBtnURLAction = Action(FluentIcon.ALIGNMENT.icon(), "手动URL获取") self.headerRightHBox.addWidget(self.headerRightGachaTypeCombobox) self.headerRightHBox.addWidget(self.headerRightUIDSelectCombobox) + self.headerRightHBox.addWidget(self.headerRightAddUpdateDropBtn) self.headerRightHBox.addWidget(self.headerRightFullUpdateDropBtn) + self.headerRightAddUpdateDropBtnMenu = RoundMenu(parent=self) self.headerRightFullUpdateDropBtnMenu = RoundMenu(parent=self) self.headerHBox.addLayout(self.headerLeftVBox) self.headerHBox.addLayout(self.headerRightHBox) @@ -132,6 +137,7 @@ def __init__(self, parent=None): self.setObjectName("GachaReportFrame") StyleSheet.GACHA_REPORT_FRAME.apply(self) + self.initHeaderRightAddUpdateDropBtnActions() self.initHeaderRightFullUpdateDropBtnActions() self.initFrame() @@ -158,6 +164,7 @@ def gachaReportStatusChanged(self, msg: tuple): self.setInteractive(True) self.gachaReportThreadStateTooltip.setState(True) self.gachaReportThreadStateTooltip = None + self.headerRightAddUpdateDropBtn.setEnabled(True) self.headerRightFullUpdateDropBtn.setEnabled(True) self.headerRightGachaTypeCombobox.setEnabled(True) self.initData() @@ -167,17 +174,38 @@ def gachaReportStatusChanged(self, msg: tuple): self.setInteractive(True) self.gachaReportThreadStateTooltip.setState(True) self.gachaReportThreadStateTooltip = None + self.headerRightAddUpdateDropBtn.setEnabled(True) self.headerRightFullUpdateDropBtn.setEnabled(True) self.headerRightGachaTypeCombobox.setEnabled(True) MessageBox("错误", msg[2], self).exec() else: + self.headerRightAddUpdateDropBtn.setEnabled(True) self.headerRightFullUpdateDropBtn.setEnabled(True) + def __headerRightAddUpdateDropBtnWebCache(self): + gachaURL = convertAPI(by_web_cache.getURL(cfg.gameDataFolder.value)) + if gachaURL: + resp = MessageBox("成功", "请求已被获取,是否更新数据?", self) + if resp.exec(): + self.headerRightAddUpdateDropBtn.setEnabled(False) + self.headerRightFullUpdateDropBtn.setEnabled(False) + self.gachaReportThread = GachaReportThread(gachaURL, isAdd=self.currentUID) + self.gachaReportThreadStateTooltip = StateToolTip("更新数据中", "数据更新开始", + self) + self.gachaReportThreadStateTooltip.closedSignal.connect(self.__gachaReportThreadStateTooltipClosed) + self.gachaReportThreadStateTooltip.move(5, 5) + self.gachaReportThreadStateTooltip.show() + self.gachaReportThread.start() + self.gachaReportThread.trigger.connect(self.gachaReportStatusChanged) + else: + InfoBar.error("失败", "无法从游戏缓存中获取请求", InfoBarPosition.TOP_RIGHT, parent=self) + def __headerRightFullUpdateDropBtnWebCache(self): gachaURL = convertAPI(by_web_cache.getURL(cfg.gameDataFolder.value)) if gachaURL: resp = MessageBox("成功", "请求已被获取,是否更新数据?", self) if resp.exec(): + self.headerRightAddUpdateDropBtn.setEnabled(False) self.headerRightFullUpdateDropBtn.setEnabled(False) self.gachaReportThread = GachaReportThread(gachaURL) self.gachaReportThreadStateTooltip = StateToolTip("更新数据中", "数据更新开始", @@ -190,6 +218,27 @@ def __headerRightFullUpdateDropBtnWebCache(self): else: InfoBar.error("失败", "无法从游戏缓存中获取请求", InfoBarPosition.TOP_RIGHT, parent=self) + def __headerRightAddUpdateDropBtnURL(self): + w = URLDialog("输入URL", "请在下方输入 MiHoYo API 的URL", self) + w.exec() + gachaURL = w.textEditWidget.toPlainText() + try: + requests.get(gachaURL) + except requests.exceptions.MissingSchema: + InfoBar.error("错误", "URL格式错误", InfoBarPosition.TOP_RIGHT, parent=self) + return + if gachaURL: + gachaURL = gachaURL.split("game_biz=hk4e_cn")[0] + "game_biz=hk4e_cn" + self.headerRightAddUpdateDropBtn.setEnabled(False) + self.headerRightFullUpdateDropBtn.setEnabled(False) + self.gachaReportThread = GachaReportThread(gachaURL, isAdd=self.currentUID) + self.gachaReportThreadStateTooltip = StateToolTip("更新数据中", "数据更新开始", self) + self.gachaReportThreadStateTooltip.closedSignal.connect(self.__gachaReportThreadStateTooltipClosed) + self.gachaReportThreadStateTooltip.move(5, 5) + self.gachaReportThreadStateTooltip.show() + self.gachaReportThread.start() + self.gachaReportThread.trigger.connect(self.gachaReportStatusChanged) + def __headerRightFullUpdateDropBtnURL(self): w = URLDialog("输入URL", "请在下方输入 MiHoYo API 的URL", self) w.exec() @@ -201,6 +250,7 @@ def __headerRightFullUpdateDropBtnURL(self): return if gachaURL: gachaURL = gachaURL.split("game_biz=hk4e_cn")[0] + "game_biz=hk4e_cn" + self.headerRightAddUpdateDropBtn.setEnabled(False) self.headerRightFullUpdateDropBtn.setEnabled(False) self.gachaReportThread = GachaReportThread(gachaURL) self.gachaReportThreadStateTooltip = StateToolTip("更新数据中", "数据更新开始", self) @@ -210,6 +260,12 @@ def __headerRightFullUpdateDropBtnURL(self): self.gachaReportThread.start() self.gachaReportThread.trigger.connect(self.gachaReportStatusChanged) + def initHeaderRightAddUpdateDropBtnActions(self): + self.headerRightAddUpdateDropBtnWebCacheAction.triggered.connect(self.__headerRightAddUpdateDropBtnWebCache) + self.headerRightAddUpdateDropBtnURLAction.triggered.connect(self.__headerRightAddUpdateDropBtnURL) + self.headerRightAddUpdateDropBtnMenu.addAction(self.headerRightAddUpdateDropBtnWebCacheAction) + self.headerRightAddUpdateDropBtnMenu.addAction(self.headerRightAddUpdateDropBtnURLAction) + def initHeaderRightFullUpdateDropBtnActions(self): self.headerRightFullUpdateDropBtnWebCacheAction.triggered.connect(self.__headerRightFullUpdateDropBtnWebCache) self.headerRightFullUpdateDropBtnURLAction.triggered.connect(self.__headerRightFullUpdateDropBtnURL) @@ -253,7 +309,9 @@ def initFrame(self): self.headerRightGachaTypeCombobox.currentIndexChanged.connect(self.__headerRightGachaTypeComboboxChanged) self.headerRightUIDSelectCombobox.setFixedWidth(160) self.headerRightUIDSelectCombobox.currentIndexChanged.connect(self.__headerRightUIDSelectComboboxChanged) - self.headerRightFullUpdateDropBtn.setFixedWidth(160) + self.headerRightAddUpdateDropBtn.setFixedWidth(150) + self.headerRightAddUpdateDropBtn.setMenu(self.headerRightAddUpdateDropBtnMenu) + self.headerRightFullUpdateDropBtn.setFixedWidth(150) self.headerRightFullUpdateDropBtn.setMenu(self.headerRightFullUpdateDropBtnMenu) self.bottomLeftGachaTable.setFixedWidth(600) @@ -282,9 +340,12 @@ def initFrame(self): self.bottomRightBasicLevel5TotalBtn.setObjectName("level_5") self.bottomRightBasicLevel4TotalBtn.setObjectName("level_4") self.bottomRightBasicLevel3TotalBtn.setObjectName("level_3") - self.bottomRightBasicLevel5TotalBtn.setStyleSheet(style_sheet.component_style_sheet("gacha_report_push_button_5")) - self.bottomRightBasicLevel4TotalBtn.setStyleSheet(style_sheet.component_style_sheet("gacha_report_push_button_4")) - self.bottomRightBasicLevel3TotalBtn.setStyleSheet(style_sheet.component_style_sheet("gacha_report_push_button_3")) + self.bottomRightBasicLevel5TotalBtn.setStyleSheet( + style_sheet.component_style_sheet("gacha_report_push_button_5")) + self.bottomRightBasicLevel4TotalBtn.setStyleSheet( + style_sheet.component_style_sheet("gacha_report_push_button_4")) + self.bottomRightBasicLevel3TotalBtn.setStyleSheet( + style_sheet.component_style_sheet("gacha_report_push_button_3")) self.bottomRightBasicAverage5TotalLabel.setFont(utils.get_font(12)) self.bottomRightBasicAverage4TotalLabel.setFont(utils.get_font(12)) @@ -307,7 +368,8 @@ def initFrame(self): styleSheetManager.deregister(self.bottomRightCompleteAnalysisBtn) self.bottomRightCompleteAnalysisBtn.setObjectName("complete_analysis") self.bottomRightCompleteAnalysisBtn.setText("查看完整分析") - self.bottomRightCompleteAnalysisBtn.setStyleSheet(style_sheet.component_style_sheet("gacha_report_complete_analysis_button")) + self.bottomRightCompleteAnalysisBtn.setStyleSheet( + style_sheet.component_style_sheet("gacha_report_complete_analysis_button")) self.bottomRightAnalysisLabel.setFont(utils.get_font(14)) self.bottomRightAnalysisGuaranteeLabel.setFont(utils.get_font(10)) diff --git a/src/modules/Views/link_frame.py b/src/modules/Views/link_frame.py index 2958164..fe3dc85 100644 --- a/src/modules/Views/link_frame.py +++ b/src/modules/Views/link_frame.py @@ -114,7 +114,7 @@ def __importCardClicked(self): if filePath: logging.info(f"[Link][Import] Get SRGF File: {filePath}") if utils.json_validator(filePath, "srgf"): - logging.info(f"[Sangonomiya][Link] SRGF Import File Path: {filePath}") + logging.info(f"[Asta][Link] SRGF Import File Path: {filePath}") importFile = json.loads(open(filePath, 'r', encoding="utf-8").read()) tmp_uid = importFile["info"]["uid"] tmp_language = importFile["info"]["lang"] diff --git a/src/modules/constant.py b/src/modules/constant.py index 7142954..b8e33c7 100644 --- a/src/modules/constant.py +++ b/src/modules/constant.py @@ -1,4 +1,4 @@ -APP_VERSION = "0.1.9" +APP_VERSION = "0.2.0" UI_VERSION = "0.9.0" SRGF_GACHATYPE = {"2": "2", "1": "1", "11": "11", "12": "12"}