Passed
Push — master ( b1826e...729ce0 )
by manny
01:49
created

gadgets.coop   A

Complexity

Total Complexity 27

Size/Duplication

Total Lines 123
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 27
eloc 106
dl 0
loc 123
rs 10
c 0
b 0
f 0

7 Methods

Rating   Name   Duplication   Size   Complexity  
A Coop.set_text_if_four_finishers() 0 11 3
A Coop.is_enabled() 0 5 1
B Coop.set_text_if_three_finishers() 0 19 6
B Coop.update_coop_text() 0 25 6
A Coop.get_coop_times() 0 15 5
A Coop.get_coop_text() 0 14 2
A Coop.set_text_if_two_finishers() 0 8 4
1
import logging
2
from datetime import datetime, timedelta, timezone
3
4
from models.race import Entrant, Race
5
6
from .timer import Timer
7
8
9
class Coop:
10
    logger: logging.Logger = logging.Logger("racetime-obs")
11
    enabled = False
12
    partner = None
13
    opponent2 = None
14
    opponent1 = None
15
    source = None
16
    label_source = None
17
    text = " "
18
    label_text = "Race still in progress"
19
20
    def update_coop_text(self, race: Race, full_name):
21
        entrant = race.get_entrant_by_name(full_name)
22
        partner = race.get_entrant_by_name(self.partner)
23
        opponent1 = race.get_entrant_by_name(self.opponent1)
24
        opponent2 = race.get_entrant_by_name(self.opponent2)
25
26
        if (not self.enabled or entrant is None or partner is None
27
                or opponent1 is None or opponent2 is None):
28
            return
29
30
        self.logger.debug(f"use_coop: {self.enabled}")
31
        self.logger.debug(f"entrant name: {full_name}, entrant: {entrant}")
32
        self.logger.debug(f"entrant name: {self.partner}, entrant: {partner}")
33
        self.logger.debug(
34
            f"entrant name: {self.opponent1}, entrant: {opponent1}")
35
        self.logger.debug(
36
            f"entrant name: {self.opponent2}, entrant: {opponent2}")
37
38
        our_total, opponent_total = self.get_coop_times(
39
            entrant, partner, opponent1, opponent2)
40
        self.set_text_if_two_finishers(race, our_total, opponent_total)
41
        self.set_text_if_three_finishers(
42
            race, entrant, partner, opponent1, opponent2)
43
        self.set_text_if_four_finishers(
44
            race, entrant, partner, opponent1, opponent2)
45
46
    def set_text_if_four_finishers(self, race, entrant, partner,
47
                                   opponent1, opponent2):
48
        if race.entrants_count_finished == 4:
49
            our_total = entrant.finish_time + partner.finish_time
50
            opponent_total = opponent1.finish_time + opponent2.finish_time
51
            if our_total < opponent_total:
52
                self.label_text = "We won!!! Average time:"
53
                self.text = Timer.timer_to_str(our_total / 2)
54
            else:
55
                self.label_text = "Opponents won, average time:"
56
                self.text = Timer.timer_to_str(opponent_total / 2)
57
58
    def set_text_if_three_finishers(self, race, entrant, partner,
59
                                    opponent1, opponent2):
60
        if race.entrants_count_finished == 3:
61
            current_timer = datetime.now(timezone.utc) - race.started_at
62
            if not entrant.finish_time:
63
                self.label_text, self.text = self.get_coop_text(
64
                    "I need ", partner, opponent1, opponent2, current_timer)
65
            elif not partner.finish_time:
66
                prefix = partner.user.name + " needs "
67
                self.label_text, self.text = self.get_coop_text(
68
                    prefix, entrant, opponent1, opponent2, current_timer)
69
            elif not opponent1.finish_time:
70
                prefix = opponent1.user.name + " needs "
71
                self.label_text, self.text = self.get_coop_text(
72
                    prefix, opponent2, entrant, partner, current_timer)
73
            elif not opponent2.finish_time:
74
                prefix = opponent2.user.name + " needs "
75
                self.label_text, self.text = self.get_coop_text(
76
                    prefix, opponent1, entrant, partner, current_timer)
77
78
    def set_text_if_two_finishers(self, race, our_total, opponent_total):
79
        if race.entrants_count_finished == 2:
80
            if our_total is not None:
81
                self.label_text = "We won!"
82
                self.text = Timer.timer_to_str(our_total / 2)
83
            elif opponent_total is not None:
84
                self.label_text = "They won. :("
85
                self.text = Timer.timer_to_str(opponent_total / 2)
86
87
    @staticmethod
88
    def get_coop_text(label_text_start: str, finished_partner: Entrant,
89
                      finished1: Entrant, finished2: Entrant,
90
                      current_timer: timedelta):
91
        finished_team_total = finished1.finish_time + finished2.finish_time
92
        time_to_beat = finished_team_total - finished_partner.finish_time
93
        if time_to_beat > current_timer:
94
            coop_text = Timer.timer_to_str(time_to_beat)
95
            coop_label_text = label_text_start + "to finish before"
96
        else:
97
            coop_label_text = str.format(
98
                f"{finished1.user.name} and {finished2.user.name} won")
99
            coop_text = Timer.timer_to_str(finished_team_total / 2)
100
        return coop_label_text, coop_text
101
102
    def get_coop_times(self, entrant, partner, opponent1, opponent2):
103
        our_total = None
104
        opponent_total = None
105
        if entrant.finish_time and partner.finish_time:
106
            our_total = entrant.finish_time + partner.finish_time
107
            self.logger.debug(f"calculated our average is {our_total / 2}")
108
        else:
109
            self.logger.debug("we haven't finished yet")
110
        if opponent1.finish_time and opponent2.finish_time:
111
            opponent_total = opponent1.finish_time + opponent2.finish_time
112
            self.logger.debug(
113
                f"calculated our opponent's average is {opponent_total / 2}")
114
        else:
115
            self.logger.debug("our opponents haven't finished")
116
        return our_total, opponent_total
117
118
    def is_enabled(self) -> bool:
119
        return (
120
            self.enabled and self.label_source != "" and self.source != "" and
121
            self.partner is not None and self.opponent1 is not None and
122
            self.opponent2 is not None
123
        )
124