Skip to content

Commit 16f088a

Browse files
committed
fix: 处理 curseforge 响应错误的情况
HMCL-dev/HMCL#3904
1 parent a62057b commit 16f088a

File tree

7 files changed

+57
-13
lines changed

7 files changed

+57
-13
lines changed

mcim_sync/config.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ class ConfigModel(BaseModel):
6161
interval: JobInterval = JobInterval()
6262
max_workers: int = 8
6363
curseforge_chunk_size: int = 1000
64-
modrinth_chunk_size: int = 1000
64+
modrinth_chunk_size: int = 100
6565
curseforge_delay: Union[float, int] = 1
6666
modrinth_delay: Union[float, int] = 1
6767
curseforge_api_key: str = "<api key>"

mcim_sync/sync/curseforge.py

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ def sync_mod_all_files(
116116

117117
def sync_mod_all_files_at_once(
118118
modId: int, latestFiles: List[dict], need_to_cache: bool = True
119-
) -> int:
119+
) -> Optional[int]:
120120
res = get_mod_files(modId, index=0, pageSize=10000)
121121

122122
append_model_from_files_res(
@@ -127,11 +127,16 @@ def sync_mod_all_files_at_once(
127127

128128
page = Pagination(**res["pagination"])
129129

130+
if page.resultCount != page.totalCount:
131+
log.warning(
132+
f"ResultCount {page.resultCount} != TotalCount {page.totalCount} for mod {modId}, response maybe incomplete, passing sync"
133+
)
134+
return None
130135
removed_count = mongodb_engine.remove(
131136
File, File.modId == modId, query.not_in(File.id, file_id_list)
132137
)
133138
log.info(
134-
f"Finished sync mod {modId}, total {page.totalCount} files, removed {removed_count} files"
139+
f"Finished sync mod {modId}, total {page.totalCount} files, resultCount {page.resultCount}, removed {removed_count} files"
135140
)
136141

137142
return page.totalCount
@@ -144,8 +149,6 @@ def sync_mod(modId: int) -> Optional[ProjectDetail]:
144149
res = get_mod(modId)
145150
mod_model = Mod(**res)
146151
if mod_model.gameId == 432:
147-
submitter.add(mod_model)
148-
149152
# version_count = sync_mod_all_files(
150153
# modId,
151154
# latestFiles=res["latestFiles"],
@@ -158,13 +161,19 @@ def sync_mod(modId: int) -> Optional[ProjectDetail]:
158161
need_to_cache=True if res["classId"] == 6 else False,
159162
)
160163

164+
if version_count is None:
165+
return None
166+
161167
return ProjectDetail(
162168
id=res["id"],
163169
name=res["name"],
164170
version_count=version_count,
165171
)
166172
else:
167173
log.debug(f"Mod {modId} gameId is not 432")
174+
175+
# 最后再添加,以防未成功刷新版本列表而更新 Mod 信息
176+
submitter.add(mod_model)
168177
except ResponseCodeException as e:
169178
if e.status_code == 404:
170179
log.error(f"Mod {modId} not found!")
@@ -227,10 +236,12 @@ def sync_categories(
227236
else:
228237
raise e
229238

239+
230240
class ModsSearchSortField(int, Enum):
231241
"""
232242
https://docs.curseforge.com/rest-api/#tocS_ModsSearchSortField
233243
"""
244+
234245
Featured = 1
235246
Popularity = 2
236247
LastUpdated = 3
@@ -249,6 +260,7 @@ class ModLoaderType(int, Enum):
249260
"""
250261
https://docs.curseforge.com/rest-api/#tocS_ModLoaderType
251262
"""
263+
252264
Any = 0
253265
Forge = 1
254266
Cauldron = 2
@@ -257,13 +269,16 @@ class ModLoaderType(int, Enum):
257269
Quilt = 5
258270
NeoForge = 6
259271

272+
260273
class ModsSearchSortOrder(str, Enum):
261274
"""
262275
'asc' if sort is in ascending order, 'desc' if sort is in descending order
263276
"""
277+
264278
ASC = "asc"
265279
DESC = "desc"
266280

281+
267282
@retry(stop=stop_after_attempt(3), wait=wait_fixed(1))
268283
def fetch_search_result(
269284
gameId: int = 432,
@@ -282,7 +297,8 @@ def fetch_search_result(
282297
primaryAuthorId: Optional[int] = None,
283298
slug: Optional[str] = None,
284299
index: Optional[int] = None,
285-
pageSize: Optional[int] = 50):
300+
pageSize: Optional[int] = 50,
301+
):
286302
"""
287303
Fetch search result from CurseForge API.
288304
"""
@@ -304,12 +320,12 @@ def fetch_search_result(
304320
primaryAuthorId=primaryAuthorId,
305321
slug=slug,
306322
index=index,
307-
pageSize=pageSize
323+
pageSize=pageSize,
308324
)
309325
return res
310326
except ResponseCodeException as e:
311327
if e.status_code == 404:
312328
log.error("Search result not found!")
313329
return None
314330
else:
315-
raise e
331+
raise e

mcim_sync/tasks/curseforge.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,21 @@ def refresh_curseforge_with_modify_date() -> bool:
5555
else:
5656
curseforge_pool.shutdown()
5757

58+
failed_count = len(curseforge_expired_modids) - len(projects_detail_info)
59+
failed_modids = [
60+
modid for modid in curseforge_expired_modids if modid not in projects_detail_info
61+
]
62+
log.info(
63+
f"CurseForge expired data sync finished, total: {len(curseforge_expired_modids)}, "
64+
f"success: {len(projects_detail_info)}, failed: {failed_count}, "
65+
f"failed modids: {failed_modids if failed_modids else 'None'}"
66+
)
67+
5868
if config.telegram_bot:
5969
notification = RefreshNotification(
6070
platform=Platform.CURSEFORGE,
6171
projects_detail_info=projects_detail_info,
72+
failed_count=failed_count,
6273
)
6374
notification.send_to_telegram()
6475
log.info("CurseForge refresh message sent to telegram.")

mcim_sync/utils/model_submitter/__init__.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,11 @@ def close(self) -> None:
6060
self.flush()
6161
log.debug(f"ModelSubmitter finished, total submitted: {self.total_submitted}")
6262

63+
def clear(self) -> None:
64+
"""清空待保存的模型"""
65+
self.models.clear()
66+
log.debug("Cleared pending models.")
67+
6368
@property
6469
def pending_count(self) -> int:
6570
"""待保存的模型数量"""

mcim_sync/utils/telegram/__init__.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,14 +144,23 @@ def send_to_telegram(cls) -> int:
144144
class RefreshNotification(Notification):
145145
platform: Platform
146146
projects_detail_info: List[ProjectDetail]
147+
failed_count = 0 # 失败的模组数量
147148

148-
def __init__(self, platform: Platform, projects_detail_info: List[ProjectDetail]):
149+
def __init__(
150+
self,
151+
platform: Platform,
152+
projects_detail_info: List[ProjectDetail],
153+
failed_count: Optional[int] = 0,
154+
):
149155
self.platform = platform
150156
self.projects_detail_info = projects_detail_info
157+
self.failed_count = failed_count if failed_count is not None else 0
151158

152159
def send_to_telegram(self) -> int:
153160
sync_message = escape_markdown(
154-
f"{self.platform.value} 缓存刷新完成,共刷新 {len(self.projects_detail_info)} 个模组",
161+
f"{self.platform.value} 缓存刷新完成,共刷新 {len(self.projects_detail_info)} 个模组, {self.failed_count} 个模组刷新失败\n"
162+
if self.failed_count > 0
163+
else f"{self.platform.value} 缓存刷新完成,共刷新 {len(self.projects_detail_info)} 个模组\n"
155164
)
156165
if self.projects_detail_info:
157166
sync_message += make_project_detail_blockquote(self.projects_detail_info)

start.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ def main():
9292
year="*",
9393
),
9494
name="curseforge_categories_refresh",
95-
next_run_time=datetime.datetime.now(), # 立即执行一次任务
95+
# next_run_time=datetime.datetime.now(), # 立即执行一次任务
9696
)
9797

9898
if config.job_config.modrinth_tags:
@@ -109,7 +109,7 @@ def main():
109109
year="*",
110110
),
111111
name="modrinth_refresh_tags",
112-
next_run_time=datetime.datetime.now(), # 立即执行一次任务
112+
# next_run_time=datetime.datetime.now(), # 立即执行一次任务
113113
)
114114

115115
if config.telegram_bot and config.job_config.global_statistics:

tests/conftest.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@
44
import pytest
55
import os
66

7-
config: dict = json.loads(os.environ.get("CONFIG"))
7+
if not os.path.exists("config.json"):
8+
config: dict = json.loads(os.environ.get("CONFIG"))
9+
else:
10+
config = json.load(open("config.json", "r", encoding="utf-8"))
811
headers = {
912
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3",
1013
"Accept": "application/json",

0 commit comments

Comments
 (0)