diff --git a/API_AuthLiteDelivery.py b/API_AuthLiteDelivery.py index 726f861..d5d4c1e 100644 --- a/API_AuthLiteDelivery.py +++ b/API_AuthLiteDelivery.py @@ -120,7 +120,7 @@ def parseUpdateIni(iniText): return final_message if __name__ == '__main__': - urlList = parseRawDelivery(getRawDelivery()) + urlList = parseRawDelivery(getRawDelivery("1.40")) for url in urlList: iniText = getUpdateIniFromURL(url) message = parseUpdateIni(iniText) diff --git a/Best50_To_Diving_Fish.py b/Best50_To_Diving_Fish.py index 1f1202a..029ecf9 100644 --- a/Best50_To_Diving_Fish.py +++ b/Best50_To_Diving_Fish.py @@ -5,7 +5,13 @@ from loguru import logger from HelperGetUserMusicDetail import getUserFullMusicDetail from HelperMusicDB import getMusicTitle import requests +import rapidjson as json +class divingFishAuthFailError(Exception): + pass + +class divingFishCommError(Exception): + pass # 水鱼查分器的 API 地址 BASE_URL = 'https://www.diving-fish.com/api/maimaidxprober' @@ -44,20 +50,32 @@ def apiDivingFish(method:str, apiPath:str, importToken:str, data=None): logger.info(f'水鱼查分器请求结果:{response.status_code}') logger.debug(f'水鱼查分器回应:{response.text}') - if response.status_code != 200: - return False - return response.json() + finalResponseTextDecode = response.text.encode('utf-8').decode('unicode_escape') + logger.debug(f'水鱼查分器回应解码后:{finalResponseTextDecode}') + match response.status_code: + case 200: + return response.json() + case 500: + raise divingFishAuthFailError + case _: + raise divingFishCommError def getFishRecords(importToken: str) -> dict: + '''获取水鱼查分器的成绩''' return apiDivingFish('GET', '/player/records', importToken) def updateFishRecords(importToken: str, records: list[dict]) -> dict: + '''上传成绩到水鱼查分器''' return apiDivingFish('POST', '/player/update_records', importToken, records) def resetFishRecords(fishImportToken:str): '''重置水鱼查分器的用户数据''' return apiDivingFish('DELETE', '/player/delete_records', fishImportToken) +def getFishUserInfo(userQQ:int): + '''按QQ获取水鱼查分器的用户信息''' + return apiDivingFish('POST', '/query/player', "", {"qq": userQQ}) + def maimaiUserMusicDetailToDivingFishFormat(userMusicDetailList) -> list: '''舞萌的 UserMusicDetail 成绩格式转换成水鱼的格式''' divingFishList = [] @@ -97,22 +115,46 @@ def isVaildFishToken(importToken:str): 有效返回 True,无效返回 False''' result = apiDivingFish('GET', '/player/records', importToken) logger.debug(f"水鱼查分器 Token 检查结果:{result}") - if result == False: - logger.info("检查出了一个无效的水鱼token") + if result: + return True + return False + +def implGetUserCurrentDXRating(userQQ:int): + '''获取用户当前的 DX RATING''' + try: + playerData = getFishUserInfo(userQQ) + playerRating = playerData['rating'] + logger.info(f"用户 {userQQ} 的 DX RATING 是 {playerRating}") + except Exception as e: + logger.warning(f"无法获取用户 {userQQ} 的 DX RATING: {e}") return False - return True + return playerRating def implUserMusicToDivingFish(userId:int, fishImportToken:str): - '''上传所有成绩到水鱼的参考实现,返回成绩的数量或者False''' + '''上传所有成绩到水鱼的参考实现。 + 返回一个 int 的 ErrorCode。 + 0: Success + 1: Get User Music Fail + 2: Auth Fail + 3: Comm Error + ''' logger.info("开始尝试上传舞萌成绩到水鱼查分器!") - userFullMusicDetailList = getUserFullMusicDetail(userId) - logger.info("成功得到成绩!转换成水鱼格式..") - divingFishData = maimaiUserMusicDetailToDivingFishFormat(userFullMusicDetailList) - logger.info("转换成功!开始上传水鱼..") - if not updateFishRecords(fishImportToken, divingFishData): - logger.error("上传失败!") - return False - return len(divingFishData) + try: + userFullMusicDetailList = getUserFullMusicDetail(userId) + logger.info("成功得到成绩!转换成水鱼格式..") + divingFishData = maimaiUserMusicDetailToDivingFishFormat(userFullMusicDetailList) + logger.info("转换成功!开始上传水鱼..") + except Exception as e: + logger.error(f"获取成绩失败!{e}") + return 1 + try: + updateFishRecords(fishImportToken, divingFishData) + except divingFishAuthFailError: + logger.error("水鱼查分器认证失败!") + return 2 + except divingFishCommError: + logger.error("水鱼查分器通讯失败!") + return 3 def generateDebugTestScore(): '''生成测试成绩''' @@ -137,8 +179,7 @@ def generateDebugTestScore(): if __name__ == '__main__': if True: - userId = testUid2 - importToken = testImportToken + importToken = "b230686d65c90fae594162707304bc66b5322a4591e56870a7ac6fd8e1b5244404e4973d194c4a87a31a8177d2f69150674c2924484808b69a2388ab3d0db7b7" #currentLoginTimestamp = generateTimestamp() #implUserMusicToDivingFish(userId, importToken) - implResetFishUser(importToken) + implGetUserCurrentDXRating(1723464362) diff --git a/Config.py b/Config.py index ebb56ed..f4e779e 100644 --- a/Config.py +++ b/Config.py @@ -11,4 +11,4 @@ loginBonusDBPathFallback = "./maimaiDX-Api/Data/loginBonusDB.json" musicDBPathFallback = "./maimaiDX-Api/Data/musicDB.json" # 日本精工,安全防漏 -from MyConfig import * +#from MyConfig import * diff --git a/HelperUserAll.py b/HelperUserAll.py index 8f85d38..a90e76e 100644 --- a/HelperUserAll.py +++ b/HelperUserAll.py @@ -5,6 +5,27 @@ from datetime import datetime from Config import * from HelperGetUserThing import implGetUser_ +from HelperGetUserMusicDetail import getUserMusicDetail +from loguru import logger + +def isNewMusicType(userId, musicId, level) -> str: + """判断这首 musicId 在 isNewMusicDetailList 应该填什么 + 0: Edit + 1: Insert + 一次只能处理一首歌,所以返回值是 str + + 未完工,仅供测试 + """ + userMusicDetailList = getUserMusicDetail(userId, musicId, 1)['userMusicList'][0]['userMusicDetailList'] + logger.info(userMusicDetailList) + try: + if userMusicDetailList[0]['musicId'] == musicId and userMusicDetailList[0]['level'] == level: + logger.info(f"We think {musicId} Level {level} should use EDIT.") + return "0" + except: + return "1" + + def generateFullUserAll(userId, currentLoginResult, currentLoginTimestamp, currentUserData2, currentPlaySpecial): """从服务器取得必要的数据并构建一个比较完整的 UserAll"""