From 3fe3bb331c4b7939eff34af791aa69e2094a2611 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maxime=20R=C3=A9aux?= Date: Thu, 26 Feb 2026 11:28:29 +0100 Subject: [PATCH] factorise ranking icon mapper --- .../controller/campaign_controller.py | 45 ++-------------- src/warchron/controller/ranking_icon.py | 54 +++++++++++++++++++ src/warchron/controller/war_controller.py | 41 +------------- 3 files changed, 60 insertions(+), 80 deletions(-) create mode 100644 src/warchron/controller/ranking_icon.py diff --git a/src/warchron/controller/campaign_controller.py b/src/warchron/controller/campaign_controller.py index cc62e0c..88199eb 100644 --- a/src/warchron/controller/campaign_controller.py +++ b/src/warchron/controller/campaign_controller.py @@ -1,15 +1,11 @@ from typing import List, Dict, Tuple, TYPE_CHECKING from PyQt6.QtWidgets import QMessageBox, QDialog -from PyQt6.QtGui import QIcon from warchron.constants import ( RefreshScope, ContextType, ItemType, - Icons, - IconName, - RANK_TO_ICON, ) if TYPE_CHECKING: @@ -28,8 +24,8 @@ from warchron.model.campaign_participant import CampaignParticipant from warchron.model.sector import Sector from warchron.model.tie_manager import TieContext, TieResolver from warchron.model.score_service import ScoreService -from warchron.model.result_checker import ResultChecker from warchron.controller.closure_workflow import CampaignClosureWorkflow +from warchron.controller.ranking_icon import RankingIcon from warchron.view.campaign_dialog import CampaignDialog from warchron.view.campaign_participant_dialog import CampaignParticipantDialog from warchron.view.sector_dialog import SectorDialog @@ -40,41 +36,6 @@ class CampaignController: def __init__(self, app: "AppController"): self.app = app - def _compute_campaign_ranking_icons( - self, war: War, campaign: Campaign - ) -> Dict[str, QIcon]: - scores = ScoreService.compute_scores( - war, - ContextType.CAMPAIGN, - campaign.id, - ) - ranking = ResultChecker.get_effective_ranking( - war, ContextType.CAMPAIGN, campaign.id, scores - ) - icon_map = {} - for rank, group, token_map in ranking: - base_icon = RANK_TO_ICON.get(rank, IconName.VPNTH) - vp = scores[group[0]].victory_points - original_group_size = sum( - 1 for s in scores.values() if s.victory_points == vp - ) - for pid in group: - spent = token_map.get(pid, 0) - if original_group_size == 1: - icon_name = base_icon - elif len(group) == 1: - if spent > 0: - icon_name = getattr(IconName, f"{base_icon.name}BREAK") - else: - icon_name = base_icon - else: - if spent > 0: - icon_name = getattr(IconName, f"{base_icon.name}TIEDRAW") - else: - icon_name = getattr(IconName, f"{base_icon.name}DRAW") - icon_map[pid] = QIcon(Icons.get_pixmap(icon_name)) - return icon_map - def _fill_campaign_details(self, campaign_id: str) -> None: camp = self.app.model.get_campaign(campaign_id) self.app.view.show_campaign_details(name=camp.name, month=camp.month) @@ -98,7 +59,9 @@ class CampaignController: rows: List[CampaignParticipantScoreDTO] = [] icon_map = {} if camp.is_over: - icon_map = self._compute_campaign_ranking_icons(war, camp) + icon_map = RankingIcon.compute_icons( + war, ContextType.CAMPAIGN, campaign_id, scores + ) for camp_part in camp.get_all_campaign_participants(): war_part_id = camp_part.war_participant_id war_part = war.get_war_participant(war_part_id) diff --git a/src/warchron/controller/ranking_icon.py b/src/warchron/controller/ranking_icon.py new file mode 100644 index 0000000..bb7d914 --- /dev/null +++ b/src/warchron/controller/ranking_icon.py @@ -0,0 +1,54 @@ +from typing import Dict + +from PyQt6.QtGui import QIcon + +from warchron.constants import ( + ContextType, + Icons, + IconName, + RANK_TO_ICON, +) +from warchron.model.war import War +from warchron.model.score_service import ParticipantScore +from warchron.model.result_checker import ResultChecker + + +class RankingIcon: + @staticmethod + def compute_icons( + war: War, + context_type: ContextType, + context_id: str, + scores: Dict[str, ParticipantScore], + ) -> Dict[str, QIcon]: + # scores = ScoreService.compute_scores( + # war, + # context_type, + # context_id, + # ) + ranking = ResultChecker.get_effective_ranking( + war, context_type, context_id, scores + ) + icon_map = {} + for rank, group, token_map in ranking: + base_icon = RANK_TO_ICON.get(rank, IconName.VPNTH) + vp = scores[group[0]].victory_points + original_group_size = sum( + 1 for s in scores.values() if s.victory_points == vp + ) + for pid in group: + spent = token_map.get(pid, 0) + if original_group_size == 1: + icon_name = base_icon + elif len(group) == 1: + if spent > 0: + icon_name = getattr(IconName, f"{base_icon.name}BREAK") + else: + icon_name = base_icon + else: + if spent > 0: + icon_name = getattr(IconName, f"{base_icon.name}TIEDRAW") + else: + icon_name = getattr(IconName, f"{base_icon.name}DRAW") + icon_map[pid] = QIcon(Icons.get_pixmap(icon_name)) + return icon_map diff --git a/src/warchron/controller/war_controller.py b/src/warchron/controller/war_controller.py index 5cd0de0..554630e 100644 --- a/src/warchron/controller/war_controller.py +++ b/src/warchron/controller/war_controller.py @@ -1,15 +1,11 @@ from typing import List, Tuple, TYPE_CHECKING, Dict from PyQt6.QtWidgets import QMessageBox, QDialog -from PyQt6.QtGui import QIcon from warchron.constants import ( RefreshScope, ItemType, ContextType, - Icons, - IconName, - RANK_TO_ICON, ) from warchron.model.exception import ( DomainError, @@ -29,8 +25,8 @@ from warchron.model.war_participant import WarParticipant from warchron.model.objective import Objective from warchron.model.tie_manager import TieContext, TieResolver from warchron.model.score_service import ScoreService -from warchron.model.result_checker import ResultChecker from warchron.controller.closure_workflow import WarClosureWorkflow +from warchron.controller.ranking_icon import RankingIcon from warchron.view.war_dialog import WarDialog from warchron.view.objective_dialog import ObjectiveDialog from warchron.view.war_participant_dialog import WarParticipantDialog @@ -41,39 +37,6 @@ class WarController: def __init__(self, app: "AppController"): self.app = app - def _compute_war_ranking_icons(self, war: War) -> Dict[str, QIcon]: - scores = ScoreService.compute_scores( - war, - ContextType.WAR, - war.id, - ) - ranking = ResultChecker.get_effective_ranking( - war, ContextType.WAR, war.id, scores - ) - icon_map = {} - for rank, group, token_map in ranking: - base_icon = RANK_TO_ICON.get(rank, IconName.VPNTH) - vp = scores[group[0]].victory_points - original_group_size = sum( - 1 for s in scores.values() if s.victory_points == vp - ) - for pid in group: - spent = token_map.get(pid, 0) - if original_group_size == 1: - icon_name = base_icon - elif len(group) == 1: - if spent > 0: - icon_name = getattr(IconName, f"{base_icon.name}BREAK") - else: - icon_name = base_icon - else: - if spent > 0: - icon_name = getattr(IconName, f"{base_icon.name}TIEDRAW") - else: - icon_name = getattr(IconName, f"{base_icon.name}DRAW") - icon_map[pid] = QIcon(Icons.get_pixmap(icon_name)) - return icon_map - def _fill_war_details(self, war_id: str) -> None: war = self.app.model.get_war(war_id) self.app.view.show_war_details(name=war.name, year=war.year) @@ -92,7 +55,7 @@ class WarController: rows: List[WarParticipantScoreDTO] = [] icon_map = {} if war.is_over: - icon_map = self._compute_war_ranking_icons(war) + icon_map = RankingIcon.compute_icons(war, ContextType.WAR, war_id, scores) for war_part in war.get_all_war_participants(): player_name = self.app.model.get_player_name(war_part.player_id) score = scores[war_part.id]