11"""
2- MKW Wii Submission Service
2+ MKW Submission Service
33==========================
44
55Module path:
6- src/application/services/mkw_submission_service.py
6+ src/application/services/submission_services/ mkw_submission_service.py
77
8- Summary
9- -------
10- Domain-specific implementation of ``AbstractSubmissionService`` for the
11- **Mario Kart Wii TAS Competition**.
12- It understands two file formats:
8+ Summary:
139
14- * ``.rkg`` – single-track ghost file (Time Trials).
15- * ``.rksys`` – multi-track system save dump (Grand Prix / TT batch).
10+ Game-specific implementation of the base submission service for the
11+ Mario Kart Wii TAS Competition.
12+ It understands the following file formats:
13+
14+ * .rkg – single-track ghost file (Time Trials).
15+ * .rksys – game file, used for ghosts across multiple tracks.
16+ * .zip - sending multiple files, of different type.
1617
1718The service chooses the proper parser **at run-time**, based on the single
18- “ accepted file extension” stored in the guild/competition configuration.
19+ accepted file extension stored in the guild/competition configuration.
1920
20- If a user submits multiple times, previous runs are automatically replaced
21- according to the base‐class algorithm.
2221"""
2322
2423from __future__ import annotations
2524
26- from typing import Optional
25+ from typing import Optional , Dict , Type
2726
27+ from application .parsers .parser_strategy import ParserStrategy
28+ from application .parsers .registry import candidates_excluding
2829from application .parsers .rkg_parser_strategy import RkgParserStrategy
2930from application .parsers .rksys_parser_strategy import RksysParserStrategy
3031from application .parsers .file_parser import FileParser
3132from application .parsers .null_parser_strategy import NullParserStrategy # safety
33+ from application .parsers .zip_parser_strategy import ZipParserStrategy
3234
3335from application .services .submission_services .base_submission_service import BaseSubmissionService
3436
4345from domain .entities import SubmissionFile , Submission
4446
4547
48+
4649class MKWSubmissionService (BaseSubmissionService ):
4750 """
4851 Concrete submission service for Mario Kart Wii competitions.
@@ -74,7 +77,7 @@ def __init__(
7477 speed_repo = speed_repo
7578 )
7679
77- # ────────────────────────── required hooks ────────────────────────────
80+ # ────────────────────────── required methods ────────────────────────────
7881 # Pick the correct parser & return the parsed value object
7982 def parse_file (
8083 self ,
@@ -88,9 +91,9 @@ def parse_file(
8891 Raises
8992 ------
9093 ValueError
91- If the bytes do not match either .rkg nor .rksys .
94+ If the bytes do not match any of the accepted formats .
9295 """
93- # `` FileParser`` should already have the right strategy
96+ # FileParser should already have the right strategy
9497 # (because /set-file set it), but we double-check.
9598 strat = self ._parser .strategy
9699 if isinstance (strat , NullParserStrategy ):
@@ -102,12 +105,16 @@ def parse_file(
102105 if strat .supports (file_bytes ):
103106 return strat .parse (file_bytes , uploaded_at_epoch )
104107
105- # Otherwise, fall back to the other parser
106- alt_strat = RkgParserStrategy () if isinstance (strat , RksysParserStrategy ) else RksysParserStrategy ()
107- if alt_strat .supports (file_bytes ):
108- # Swap strategy for the rest of the runtime
109- self ._parser .set_strategy (alt_strat )
110- return alt_strat .parse (file_bytes , uploaded_at_epoch )
108+
109+ # Otherwise, try all other known strategies
110+ strat = self ._parser .strategy
111+ if strat .supports (file_bytes ):
112+ return strat .parse (file_bytes , uploaded_at_epoch )
113+
114+ for alt in candidates_excluding (strat ):
115+ if alt .supports (file_bytes ):
116+ self ._parser .set_strategy (alt )
117+ return alt .parse (file_bytes , uploaded_at_epoch )
111118
112119 raise ValueError ("Unsupported MKW submission file format" )
113120
@@ -118,12 +125,12 @@ def populate_metadata(
118125 file_obj : SubmissionFile ,
119126 ) -> None :
120127 """
121- Extract MKW-specific metadata and copy it onto `` submission`` .
128+ Extract MKW-specific metadata and copy it onto submission.
122129
123130 * run_time → submission.time
124131 * character / vehicle if available (only on RKG), else None
125132 """
126- # If rkg, retrieve run_time, else set to 0 if rksys (or time isn't found)
133+ # If rkg, retrieve run_time, else set to 0 if not an rkg (or time isn't found)
127134 if hasattr (file_obj , "run_time" ):
128135 submission .time = file_obj .run_time or 0.0
129136 else :
0 commit comments