from django.db import models from tournaments.models import group_stage from . import SideStoreModel, Round, GroupStage, FederalMatchCategory from django.utils import timezone, formats from datetime import timedelta import uuid from ..utils.extensions import format_seconds class Match(SideStoreModel): id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=True) round = models.ForeignKey(Round, null=True, blank=True, on_delete=models.CASCADE) group_stage = models.ForeignKey(GroupStage, null=True, blank=True, on_delete=models.CASCADE) name = models.CharField(max_length=200, null=True, blank=True) start_date = models.DateTimeField(null=True, blank=True) end_date = models.DateTimeField(null=True, blank=True) index = models.IntegerField(default=0) #order = models.IntegerField(default=0) format = models.IntegerField(default=FederalMatchCategory.NINE_GAMES, choices=FederalMatchCategory.choices, null=True, blank=True) #court = models.CharField(max_length=50, null=True, blank=True) serving_team_id = models.UUIDField(null=True, blank=True) winning_team_id = models.UUIDField(null=True, blank=True) losing_team_id = models.UUIDField(null=True, blank=True) #broadcasted = models.BooleanField(default=False) disabled = models.BooleanField(default=False) court_index = models.IntegerField(null=True, blank=True) confirmed = models.BooleanField(default=False) def __str__(self): names = " / ".join(self.player_names()) return f"{self.stage_name()} #{self.index}: {names}" def tournament(self): if self.round: return self.round.tournament else: return self.group_stage.tournament def tournament_id(self): return self.tournament().id def court_name(self, index): club = None if self.tournament().event: club = self.tournament().event.club if club: return club.court_name(index) elif index is not None: return f"Terrain {index + 1}" return "" def backup_name(self): items = [] if self.round: items.append(self.round.name()) items.append(f" #{self.index}") elif self.group_stage: items.append(self.group_stage.name()) items.append(f"Match #{self.index}") return " ".join(items) def summon_stage_name(self): if self.round: return self.round.name() elif self.group_stage: return "Poule" else: return '--' def stage_name(self): if self.name: return self.name elif self.round: return self.round.name() elif self.group_stage: return self.group_stage.display_name() else: return '--' def player_names(self): return map(lambda ts: ts.player_names(), self.team_scores.all()) def formatted_start_date(self): if self.start_date: timezoned_datetime = timezone.localtime(self.start_date) return formats.date_format(timezoned_datetime, format='H:i') # return formats.date_format(self.start_date, format='H:i') else: return '' # return str(self.start_date) #.strftime("%H:%M") def time_indication(self): if self.end_date: if self.start_date: return self.magic_duration() else: return '' elif self.start_date: if self.started(): return self.formatted_duration() else: timezoned_datetime = timezone.localtime(self.start_date) return formats.date_format(timezoned_datetime, format='l H:i') else: return 'À venir...' def magic_duration(self): seconds = (self.end_date - self.start_date).total_seconds() average_duration = self.average_seconds_duration() if (average_duration / 2) > seconds or seconds > (average_duration * 2): seconds = average_duration return format_seconds(seconds) def average_seconds_duration(self): return 3 * 60 * self.total_number_of_games() def total_number_of_games(self): games = 0.0 for team_score in self.team_scores.all(): games += team_score.estimated_number_of_games() return games def current_duration(self): if self.confirmed and self.start_date: if self.end_date: return (self.end_date - self.start_date).total_seconds() else: current = (timezone.now() - self.start_date).total_seconds() if self.total_number_of_games() > 0 and current < self.average_seconds_duration() * 4: return current elif self.total_number_of_games() == 0 and current < 3 * 60 * 60: return current else: return None # print(current) # print(self.average_seconds_duration()) # print('*******') # if current < self.average_seconds_duration() * 4: # return current # else: # return None # return (timezone.now() - self.start_date).total_seconds() else: return None def started(self): if self.confirmed: if self.end_date: return True elif self.start_date: return timezone.now() > self.start_date return False def should_appear(self): if self.disabled is True: return False return len(self.team_scores.all()) > 0 # elif self.group_stage is None: # if len(self.team_scores.all()) == 2: # return True # else: # return (self.start_date or self.end_date) and len(self.team_scores.all()) > 0 # else: # return len(self.team_scores.all()) > 0 def formatted_duration(self): seconds = self.current_duration() if seconds is None: return '' if seconds > 0: return format_seconds(seconds) # _hours = int(_seconds / 3600) # _minutes = int((_seconds % 3600) / 60) # return f"{_hours:02d}h{_minutes:02d}min" else : seconds = seconds * -1 return format_seconds(seconds) # _hours = int(_seconds / 3600) # _minutes = int((_seconds % 3600) / 60) # return f"{_hours:02d}h{_minutes:02d}min" def live_match(self): title = self.name if self.name else self.backup_name() date = self.formatted_start_date() duration = self.time_indication() court = self.court_name(self.court_index) group_stage_name = None if self.group_stage: group_stage_name = self.group_stage.display_name() ended = self.end_date is not None livematch = LiveMatch(title, date, duration, court, self.started(), ended, group_stage_name) for team_score in self.sorted_team_scores(): if team_score.team_registration: image = team_score.team_registration.logo weight = team_score.team_registration.weight is_winner = team_score.team_registration.id == self.winning_team_id else: image = None weight= None is_winner = False names = team_score.shortened_team_names() scores = team_score.scores_array() walk_out = team_score.walk_out team = Team(image, names, scores, weight, is_winner, walk_out) livematch.add_team(team) return livematch def sorted_team_scores(self): if self.group_stage: return self.team_scores.order_by('team_registration__group_stage_position') else: return self.team_scores.order_by('team_registration__bracket_position') # def non_null_start_date(self): # if self.start_date: # return self.start_date # else: # return timezone.now() + timedelta(days=7) # def sort_value(self): # sort_score = 0 # if self.round.index: # sort_score += 1 / (self.round.index + 1) * 1000 ** 2 # if self.group_stage.index: # sort_score += 1 / (self.group_stage.index + 1) * 1000 # sort_score += self.index # print(sort_score) # return sort_score class Team: def __init__(self, image, names, scores, weight, is_winner, walk_out): # print(f"image = {image}, names= {names}, scores ={scores}, weight={weight}, win={is_winner}") self.image = image self.names = names self.scores = scores self.weight = weight self.is_winner = is_winner self.walk_out = walk_out is not None def to_dict(self): return { "image": self.image, "names": self.names, "scores": self.scores, "weight": self.weight, "is_winner": self.is_winner, "walk_out": self.walk_out, } class LiveMatch: def __init__(self, title, date, duration, court, started, ended, group_stage_name): self.title = title self.date = date self.teams = [] self.duration = duration self.court = court self.started = started self.ended = ended self.has_walk_out = False self.group_stage_name = group_stage_name def add_team(self, team): self.teams.append(team) if team.walk_out is True: self.has_walk_out = True def to_dict(self): return { "title": self.title, "date": self.date, "teams": [team.to_dict() for team in self.teams], "duration": self.duration, "court": self.court, "started": self.started, "ended": self.ended, "has_walk_out": self.has_walk_out, "group_stage_name": self.group_stage_name, } def show_duration(self): for team in self.teams: if team.walk_out and len(team.scores) == 0: return False return True def should_show_scores(self): for team in self.teams: if len(team.scores) > 0: return True return False