From 1fbff58bcd256b5e85314c44495f760ba03012fe Mon Sep 17 00:00:00 2001 From: Ian Paul Falatik <63957260+ifalatik@users.noreply.github.com> Date: Sat, 28 Sep 2024 16:55:02 +0200 Subject: [PATCH 01/32] migrate models.py to models directory --- csgomatches/models/__init__.py | 1 + .../{models.py => models/global_models.py} | 27 ++++++++------ csgomatches/utils/scrapers/hltv.py | 37 +++++++++++-------- 3 files changed, 37 insertions(+), 28 deletions(-) create mode 100644 csgomatches/models/__init__.py rename csgomatches/{models.py => models/global_models.py} (96%) diff --git a/csgomatches/models/__init__.py b/csgomatches/models/__init__.py new file mode 100644 index 0000000..6956e54 --- /dev/null +++ b/csgomatches/models/__init__.py @@ -0,0 +1 @@ +from .global_models import * diff --git a/csgomatches/models.py b/csgomatches/models/global_models.py similarity index 96% rename from csgomatches/models.py rename to csgomatches/models/global_models.py index 5fb8933..fd5d119 100644 --- a/csgomatches/models.py +++ b/csgomatches/models/global_models.py @@ -1,16 +1,17 @@ import os import requests +import importlib.resources import twitter + from django.contrib.sites.models import Site from django.db import models -from django.db.models import QuerySet -# Create your models here. +from django.db.models import QuerySet, Manager from django.urls import reverse from django.utils import timezone from django.utils.text import slugify -from . import managers -from .utils.publishing import twitter_api +from csgomatches import managers +from csgomatches.utils.publishing import twitter_api def get_flags_choices()-> list[tuple[str, str]]: @@ -18,12 +19,12 @@ def get_flags_choices()-> list[tuple[str, str]]: returns a list of tuples of all available flags by looking at png files in 'static/csgomatches/flags' """ choices: list[tuple[str, str]] = [] - base_pth = os.path.dirname(os.path.abspath(__file__)) - flags_pth = os.path.join(base_pth, 'static/csgomatches/flags') - for fn in os.listdir(flags_pth): - if fn.endswith('.png'): - short_fn = fn.replace('.png', '') - choices.append((short_fn, short_fn)) + with importlib.resources.path('csgomatches', 'static') as static_folder_path: + flags_folder_path = os.path.join(static_folder_path, 'csgomatches', 'flags') + for fn in os.listdir(flags_folder_path): + if fn.endswith('.png'): + short_fn = fn.replace('.png', '') + choices.append((short_fn, short_fn)) choices.sort(key=lambda x: x[0]) return choices @@ -47,12 +48,12 @@ class Team(models.Model): hltv_id = models.IntegerField(null=True, blank=True) esea_team_id = models.IntegerField(null=True, blank=True) - lineup_set: QuerySet['Lineup'] + lineup_set: managers.LineupQuerySet objects = managers.TeamManager() def get_hltv_id_from_name(self): - from .utils.scrapers.hltv import get_hltv_id_from_team_name + from csgomatches.utils.scrapers.hltv import get_hltv_id_from_team_name return get_hltv_id_from_team_name(team_mdl=self) def get_hltv_team_link(self): @@ -93,6 +94,8 @@ class Lineup(models.Model): active_from = models.DateTimeField(help_text='Set -10 Days to avoid multiple Lineup creations') is_active = models.BooleanField(default=True) + lineupplayer_set: Manager['LineupPlayer'] + objects = managers.LineupQuerySet.as_manager() def get_previous_lineup(self) -> 'Lineup | None': diff --git a/csgomatches/utils/scrapers/hltv.py b/csgomatches/utils/scrapers/hltv.py index 824a586..541b4a7 100644 --- a/csgomatches/utils/scrapers/hltv.py +++ b/csgomatches/utils/scrapers/hltv.py @@ -3,9 +3,10 @@ import requests import websockets +import websockets.asyncio.client from bs4 import BeautifulSoup -from ... import models +from csgomatches.models import Lineup, LineupPlayer, Player, Team def get_hltv_team_name_from_id(hltv_id: int): @@ -25,7 +26,7 @@ def get_hltv_team_name_from_id(hltv_id: int): return team_name -def get_hltv_id_from_team_name(team_mdl: models.Team, return_team_json=False): +def get_hltv_id_from_team_name(team_mdl: Team, return_team_json=False): db_names = [] if team_mdl: db_names.append(team_mdl.name) @@ -39,21 +40,21 @@ def get_hltv_id_from_team_name(team_mdl: models.Team, return_team_json=False): response = requests.get(url=url) response_json = response.json() teams = response_json[0].get("teams") - for team in teams: - hltv_name = team['name'] + for team_dict in teams: + hltv_name = team_dict['name'] print(f"[get_hltv_id_from_team_name] checking if hltv_name={hltv_name} in db_names={db_names}") if hltv_name in db_names: if return_team_json: - return team - return team['id'] + return team_dict + return team_dict['id'] if hltv_name.lower() in db_names_lower: if return_team_json: - return team - return team['id'] + return team_dict + return team_dict['id'] -def build_players(team_mdl: models.Team): +def build_players(team_mdl: Team): """ Player-Dict: { @@ -67,6 +68,9 @@ def build_players(team_mdl: models.Team): :return: """ current_lineup = team_mdl.lineup_set.active_lineups().first() + if not isinstance(current_lineup, Lineup): + raise ValueError(f"current_lineup returned by team.lineup_set.active_lineups().first() is not a Lineup instance: {current_lineup}") + if team_mdl.hltv_id: team_dict = get_hltv_id_from_team_name(team_mdl=team_mdl, return_team_json=True) if not team_dict: @@ -82,7 +86,7 @@ def build_players(team_mdl: models.Team): ingame_name = player_data.get('nickName') hltv_id_url = player_data.get('location') hltv_id = int(hltv_id_url.split("/")[2]) - player, player_created = models.Player.objects.get_or_create( + player, player_created = Player.objects.get_or_create( ingame_name=ingame_name, defaults={ 'first_name': first_name, @@ -105,7 +109,7 @@ def build_players(team_mdl: models.Team): print("existing_lineup_players", existing_lineup_players) if existing_lineup_players.count() == 0: for player in player_instances: - lu_player = models.LineupPlayer( + lu_player = LineupPlayer( player=player, lineup=current_lineup ) @@ -137,7 +141,7 @@ async def get_hlvt_score(match_id: int = 2338003): ws_str2 = '61:42["readyForMatch","{\\"token\\":\\"\\",\\"listID\\":\\"' + str(match_id) + '"\\}"]' ws_str2 = '61:42["readyForScores","{\\"token\\":\\"\\",\\"listIds\\":[' + str(match_id) + ']}"]' results = {} - async with websockets.connect(uri) as websocket: + async with websockets.asyncio.client.connect(uri) as websocket: ret = await websocket.recv() if DEBUGGING: @@ -151,7 +155,8 @@ async def get_hlvt_score(match_id: int = 2338003): if DEBUGGING: print(5, "Send", s) print("Waiting for data") - ret = await asyncio.wait_for(websocket.recv(), timeout=1) + ret = await asyncio.wait_for(websocket.recv(decode=True), timeout=1) + ret = str(ret) if ret.startswith("42["): ret = ret.replace("42[", "[") results = json.loads(ret) @@ -176,8 +181,8 @@ def get_map_name(json_result_list: list = [], map_nr: int = 1): if __name__ == '__main__': r = asyncio.get_event_loop().run_until_complete(get_hlvt_score(2337996)) if not DEBUGGING: - print("Map #1", convert_to_score(r, map_nr=1)) - print("Map #2", convert_to_score(r, map_nr=2)) - print("Map #3", convert_to_score(r, map_nr=3)) + print("Map #1", convert_to_score(r, map_nr=1)) # type: ignore + print("Map #2", convert_to_score(r, map_nr=2)) # type: ignore + print("Map #3", convert_to_score(r, map_nr=3)) # type: ignore else: print("HLTV-Score", r) From 706aa5f912a458e566d3cca379ae66651c99f835 Mon Sep 17 00:00:00 2001 From: Ian Paul Falatik <63957260+ifalatik@users.noreply.github.com> Date: Sun, 29 Sep 2024 10:56:22 +0200 Subject: [PATCH 02/32] migrate Player class to CsPlayer and add abstract Player class --- csgomatches/admin.py | 2 +- csgomatches/drf_api/ser.py | 2 +- .../migrations/0049_rename_player_csplayer.py | 17 +++++++++++++++++ csgomatches/models/__init__.py | 1 + csgomatches/models/cs_models.py | 8 ++++++++ csgomatches/models/global_models.py | 7 ++++--- csgomatches/utils/scrapers/esea.py | 4 ++-- csgomatches/utils/scrapers/hltv.py | 4 ++-- 8 files changed, 36 insertions(+), 9 deletions(-) create mode 100644 csgomatches/migrations/0049_rename_player_csplayer.py create mode 100644 csgomatches/models/cs_models.py diff --git a/csgomatches/admin.py b/csgomatches/admin.py index 527f727..347ce69 100644 --- a/csgomatches/admin.py +++ b/csgomatches/admin.py @@ -244,7 +244,7 @@ def save_global(modeladmin, request, queryset): admin.site.register(models.Map) admin.site.register(models.Match, MatchAdmin) admin.site.register(models.MatchMap, MatchMapAdmin) -admin.site.register(models.Player, PlayerAdmin) +admin.site.register(models.CsPlayer, PlayerAdmin) admin.site.register(models.PlayerRole) admin.site.register(models.Tournament, TournamentAdmin) admin.site.register(models.Game, GameAdmin) diff --git a/csgomatches/drf_api/ser.py b/csgomatches/drf_api/ser.py index 870d77c..98fb0ba 100644 --- a/csgomatches/drf_api/ser.py +++ b/csgomatches/drf_api/ser.py @@ -18,7 +18,7 @@ class Meta: class CSGOPlayerShortSerializer(serializers.ModelSerializer): class Meta: - model = apps.get_model('csgomatches.Player') + model = apps.get_model('csgomatches.CsPlayer') fields = ['ingame_name',] diff --git a/csgomatches/migrations/0049_rename_player_csplayer.py b/csgomatches/migrations/0049_rename_player_csplayer.py new file mode 100644 index 0000000..1dc47b9 --- /dev/null +++ b/csgomatches/migrations/0049_rename_player_csplayer.py @@ -0,0 +1,17 @@ +# Generated by Django 5.1 on 2024-09-28 15:31 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('csgomatches', '0048_alter_match_options'), + ] + + operations = [ + migrations.RenameModel( + old_name='Player', + new_name='CsPlayer', + ), + ] diff --git a/csgomatches/models/__init__.py b/csgomatches/models/__init__.py index 6956e54..e5a8cf8 100644 --- a/csgomatches/models/__init__.py +++ b/csgomatches/models/__init__.py @@ -1 +1,2 @@ from .global_models import * +from .cs_models import * diff --git a/csgomatches/models/cs_models.py b/csgomatches/models/cs_models.py new file mode 100644 index 0000000..070e91c --- /dev/null +++ b/csgomatches/models/cs_models.py @@ -0,0 +1,8 @@ +from django.db import models + +from csgomatches.models import Player + + +class CsPlayer(Player): + hltv_id = models.IntegerField(null=True, blank=True) + esea_user_id = models.IntegerField(null=True, blank=True) diff --git a/csgomatches/models/global_models.py b/csgomatches/models/global_models.py index fd5d119..bc2dd64 100644 --- a/csgomatches/models/global_models.py +++ b/csgomatches/models/global_models.py @@ -71,8 +71,9 @@ class Player(models.Model): ingame_name = models.CharField(max_length=255) first_name = models.CharField(max_length=255) last_name = models.CharField(max_length=255) - hltv_id = models.IntegerField(null=True, blank=True) - esea_user_id = models.IntegerField(null=True, blank=True) + + class Meta: + abstract = True def __str__(self): return f'{self.first_name} "{self.ingame_name}" {self.last_name}' @@ -135,7 +136,7 @@ class Meta: class LineupPlayer(models.Model): - player = models.ForeignKey(Player, on_delete=models.CASCADE) + player = models.ForeignKey('CsPlayer', on_delete=models.CASCADE) role = models.ForeignKey(PlayerRole, on_delete=models.CASCADE, null=True, blank=True) lineup = models.ForeignKey(Lineup, on_delete=models.CASCADE) diff --git a/csgomatches/utils/scrapers/esea.py b/csgomatches/utils/scrapers/esea.py index 1e14f7a..1fa78ef 100644 --- a/csgomatches/utils/scrapers/esea.py +++ b/csgomatches/utils/scrapers/esea.py @@ -17,7 +17,7 @@ """ Run this local, not on a hosted server -Usage: +Usage: /home/christian/workspace/venvs/wannbigspielt/bin/python /home/christian/workspace/src/github/ckw-csgo/csgomatches/utils/scrapers/esea.py """ @@ -335,7 +335,7 @@ def get_esea_team_schedule(): # crawl player pages for wsb_team in apps.get_model('csgomatches.Team').objects.filter(id__in=TEAM_A_MAPPINGS.values()): - first_player_with_esea_user_id = apps.get_model('csgomatches.Player').objects.filter( + first_player_with_esea_user_id = apps.get_model('csgomatches.CsPlayer').objects.filter( esea_user_id__isnull=False, lineupplayer__lineup__team=wsb_team, lineupplayer__lineup__is_active=True, diff --git a/csgomatches/utils/scrapers/hltv.py b/csgomatches/utils/scrapers/hltv.py index 541b4a7..e64a780 100644 --- a/csgomatches/utils/scrapers/hltv.py +++ b/csgomatches/utils/scrapers/hltv.py @@ -6,7 +6,7 @@ import websockets.asyncio.client from bs4 import BeautifulSoup -from csgomatches.models import Lineup, LineupPlayer, Player, Team +from csgomatches.models import Lineup, LineupPlayer, CsPlayer, Team def get_hltv_team_name_from_id(hltv_id: int): @@ -86,7 +86,7 @@ def build_players(team_mdl: Team): ingame_name = player_data.get('nickName') hltv_id_url = player_data.get('location') hltv_id = int(hltv_id_url.split("/")[2]) - player, player_created = Player.objects.get_or_create( + player, player_created = CsPlayer.objects.get_or_create( ingame_name=ingame_name, defaults={ 'first_name': first_name, From 970693242151d59d102b44436e56ccf38109930b Mon Sep 17 00:00:00 2001 From: Ian Paul Falatik <63957260+ifalatik@users.noreply.github.com> Date: Sun, 29 Sep 2024 11:01:56 +0200 Subject: [PATCH 03/32] Add note to PlayerRole class --- csgomatches/models/global_models.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/csgomatches/models/global_models.py b/csgomatches/models/global_models.py index bc2dd64..031d678 100644 --- a/csgomatches/models/global_models.py +++ b/csgomatches/models/global_models.py @@ -80,13 +80,19 @@ def __str__(self): class PlayerRole(models.Model): + """ + The role of a player. + For CS i.e. Fragger, Support, Leader, AWPer, Lurker, (Coach). + Will not be reasonable for some games. + Maybe it's better to implement this as an Enum. + """ name = models.CharField(max_length=255) - # i.e. Fragger, Support, Leader, AWPer, Lurker, Coach - def __str__(self): return self.name + #TODO: Implement checking on LineupPlayer class, whether PlayerRole is reasonable for game. + class Lineup(models.Model): game = models.ForeignKey(Game, null=True, on_delete=models.SET_NULL) From 32a3edd72a63e18466050529240ad9fe177b81c3 Mon Sep 17 00:00:00 2001 From: Ian Paul Falatik <63957260+ifalatik@users.noreply.github.com> Date: Sun, 29 Sep 2024 11:04:09 +0200 Subject: [PATCH 04/32] move comment to correct class --- csgomatches/models/global_models.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/csgomatches/models/global_models.py b/csgomatches/models/global_models.py index 031d678..23455d3 100644 --- a/csgomatches/models/global_models.py +++ b/csgomatches/models/global_models.py @@ -91,7 +91,6 @@ class PlayerRole(models.Model): def __str__(self): return self.name - #TODO: Implement checking on LineupPlayer class, whether PlayerRole is reasonable for game. class Lineup(models.Model): @@ -151,6 +150,9 @@ def __str__(self): return f'{self.player.ingame_name} ({self.role.name})' return f'{self.player.ingame_name} @ {self.lineup.team.name}' + def save(self, *args, **kwargs): + #TODO: Implement checking, whether PlayerRole is reasonable for game. + super().save(*args, **kwargs) class Tournament(models.Model): name = models.CharField(max_length=255) From 885dcd66247581af6a586ca7ae47c653f8048255 Mon Sep 17 00:00:00 2001 From: Ian Paul Falatik <63957260+ifalatik@users.noreply.github.com> Date: Sun, 29 Sep 2024 11:17:41 +0200 Subject: [PATCH 05/32] rename Match -> CsMatch and Tournament -> CsTournament --- csgomatches/admin.py | 7 ++- csgomatches/drf_api/ser.py | 10 ++-- csgomatches/drf_api/views.py | 8 +-- ..._csmatch_rename_tournament_cstournament.py | 21 +++++++ csgomatches/models/cs_models.py | 55 ++++++++++++++++++- csgomatches/models/global_models.py | 50 ++--------------- 6 files changed, 91 insertions(+), 60 deletions(-) create mode 100644 csgomatches/migrations/0050_rename_match_csmatch_rename_tournament_cstournament.py diff --git a/csgomatches/admin.py b/csgomatches/admin.py index 347ce69..b16c0e1 100644 --- a/csgomatches/admin.py +++ b/csgomatches/admin.py @@ -48,7 +48,8 @@ def is_live(self, obj): is_live.boolean = True -class TournamentAdmin(admin.ModelAdmin): +# Currently no generic implementation of ModelAdmin for Tournament class +class CsTournamentAdmin(admin.ModelAdmin): search_fields = ['name', 'name_alt', 'name_hltv', 'name_99dmg'] list_display = ['name', 'name_alt', 'name_hltv', 'name_99dmg'] actions = ['cleanup', 'merge_two'] @@ -242,11 +243,11 @@ def save_global(modeladmin, request, queryset): admin.site.register(models.LineupPlayer, LineupPlayerAdmin) admin.site.register(models.ExternalLink, ExternalLinkAdmin) admin.site.register(models.Map) -admin.site.register(models.Match, MatchAdmin) +admin.site.register(models.CsMatch, MatchAdmin) admin.site.register(models.MatchMap, MatchMapAdmin) admin.site.register(models.CsPlayer, PlayerAdmin) admin.site.register(models.PlayerRole) -admin.site.register(models.Tournament, TournamentAdmin) +admin.site.register(models.CsTournament, CsTournamentAdmin) admin.site.register(models.Game, GameAdmin) admin.site.register(models.StaticPage) diff --git a/csgomatches/drf_api/ser.py b/csgomatches/drf_api/ser.py index 98fb0ba..9af80e6 100644 --- a/csgomatches/drf_api/ser.py +++ b/csgomatches/drf_api/ser.py @@ -6,7 +6,7 @@ class CSGOTournamentSerializer(serializers.ModelSerializer): class Meta: - model = apps.get_model('csgomatches.Tournament') + model = apps.get_model('csgomatches.CsTournament') fields = ['name', 'name_alt', 'name_hltv', 'name_99dmg', 'id'] @@ -70,15 +70,15 @@ def get_livescore_url(self, obj): if obj.hltv_match_id: url = reverse('match_livescore-detail', kwargs={'pk': obj.hltv_match_id}) request = self.context.get('request') - return request.build_absolute_uri(url) + return request.build_absolute_uri(url) # type: ignore def get_html_detail_url(self, obj): url = obj.get_absolute_url() request = self.context.get('request') - return request.build_absolute_uri(url) + return request.build_absolute_uri(url) # type: ignore class Meta: - model = apps.get_model('csgomatches.Match') + model = apps.get_model('csgomatches.CsMatch') fields = ['tournament', 'lineup_a', 'lineup_b', 'slug', 'bestof', 'first_map_at', 'cancelled', 'hltv_match_id', 'livescore_url', 'html_detail_url', 'matchmaps'] @@ -117,7 +117,7 @@ def get_api_match_url(self, obj): if csgo_match: url = reverse('match_all-detail', kwargs={'pk': csgo_match.pk}) request = self.context.get('request') - return request.build_absolute_uri(url) + return request.build_absolute_uri(url) # type: ignore def create(self, validated_data): hltv_match_id = validated_data.get('hltv_match_id') diff --git a/csgomatches/drf_api/views.py b/csgomatches/drf_api/views.py index 49f7f32..0dc762b 100644 --- a/csgomatches/drf_api/views.py +++ b/csgomatches/drf_api/views.py @@ -67,7 +67,7 @@ def get_view_name(self): class TournamentViewSet(CSGOView, viewsets.ReadOnlyModelViewSet): - queryset = apps.get_model('csgomatches.Tournament').objects.all() + queryset = apps.get_model('csgomatches.CsTournament').objects.all() serializer_class = ser.CSGOTournamentSerializer def get_view_name(self): @@ -75,7 +75,7 @@ def get_view_name(self): class MatchViewSet(CSGOView, viewsets.ReadOnlyModelViewSet): - queryset = apps.get_model('csgomatches.Match').objects.all() + queryset = apps.get_model('csgomatches.CsMatch').objects.all() serializer_class = ser.CSGOMatchSerializer def get_view_name(self): @@ -87,7 +87,7 @@ def list(self, request, *args, **kwargs): class MatchUpcomingViewSet(CSGOView, viewsets.ReadOnlyModelViewSet): - queryset = apps.get_model('csgomatches.Match').objects.filter(first_map_at__gte=timezone.now()) + queryset = apps.get_model('csgomatches.CsMatch').objects.filter(first_map_at__gte=timezone.now()) serializer_class = ser.CSGOMatchSerializer def get_view_name(self): @@ -120,7 +120,7 @@ def get_view_name(self): def get_queryset(self): last_7_days = timezone.now() - timezone.timedelta(days=7) - return apps.get_model('csgomatches.Match').objects.filter( + return apps.get_model('csgomatches.CsMatch').objects.filter( hltv_match_id__isnull=False, first_map_at__gte=last_7_days ) diff --git a/csgomatches/migrations/0050_rename_match_csmatch_rename_tournament_cstournament.py b/csgomatches/migrations/0050_rename_match_csmatch_rename_tournament_cstournament.py new file mode 100644 index 0000000..0fd112e --- /dev/null +++ b/csgomatches/migrations/0050_rename_match_csmatch_rename_tournament_cstournament.py @@ -0,0 +1,21 @@ +# Generated by Django 5.1 on 2024-09-29 09:17 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('csgomatches', '0049_rename_player_csplayer'), + ] + + operations = [ + migrations.RenameModel( + old_name='Match', + new_name='CsMatch', + ), + migrations.RenameModel( + old_name='Tournament', + new_name='CsTournament', + ), + ] diff --git a/csgomatches/models/cs_models.py b/csgomatches/models/cs_models.py index 070e91c..5d41ab1 100644 --- a/csgomatches/models/cs_models.py +++ b/csgomatches/models/cs_models.py @@ -1,8 +1,59 @@ from django.db import models +from django.urls import reverse +import requests -from csgomatches.models import Player +import csgomatches.models.global_models as global_models -class CsPlayer(Player): +class CsPlayer(global_models.Player): hltv_id = models.IntegerField(null=True, blank=True) esea_user_id = models.IntegerField(null=True, blank=True) + +class CsTournament(global_models.Tournament): + name_hltv = models.CharField(max_length=255, null=True, blank=True) + name_99dmg = models.CharField(max_length=255, null=True, blank=True) + esea_bracket_id = models.IntegerField(null=True, blank=True) + esea_bracket_team_ids = models.CharField(max_length=255, null=True, blank=True, help_text='Comma Separated') + +class CsMatch(global_models.Match): + tournament = models.ForeignKey(CsTournament, on_delete=models.CASCADE) + + hltv_match_id = models.CharField(max_length=20, null=True, blank=True, help_text='For HLTV Livescore during match') + esea_match_id = models.CharField(max_length=255, null=True, blank=True) + enable_99dmg = models.BooleanField(default=False) + enable_hltv = models.BooleanField(default=True) + + def get_livescore_url(self, request): + if self.hltv_match_id: + url = reverse('match_livescore-detail', kwargs={'pk': self.hltv_match_id}) + return request.build_absolute_uri(url) + + def update_hltv_livescore(self, request) -> None: + # Guard clause in case lineup_a is None + if not self.lineup_a: + return + + url = self.get_livescore_url(request=request) + if url: + response = requests.get(url=url, params={'format': 'json'}).json() + maps = response.get('maps', []) + for map_data in maps: + map_nr = map_data.get('map_nr') + mm_obj = self.matchmap_set.filter(map_nr=map_nr).first() + if mm_obj: + mm_obj.played_map = global_models.Map.objects.filter( + models.Q(name=map_data.get('map_name')) | + models.Q(cs_name=map_data.get('map_name')) + ).first() + score_a, score_b = map_data.get('score_a'), map_data.get('score_b') + swap_score = False + team_a_hltv_id = response.get('team_a_id') + if team_a_hltv_id != self.lineup_a.team.hltv_id: + swap_score = True + + if swap_score: + score_b, score_a = score_a, score_b + + mm_obj.rounds_won_team_a = score_a + mm_obj.rounds_won_team_b = score_b + mm_obj.save() diff --git a/csgomatches/models/global_models.py b/csgomatches/models/global_models.py index 23455d3..4cde84d 100644 --- a/csgomatches/models/global_models.py +++ b/csgomatches/models/global_models.py @@ -1,5 +1,4 @@ import os -import requests import importlib.resources import twitter @@ -157,10 +156,6 @@ def save(self, *args, **kwargs): class Tournament(models.Model): name = models.CharField(max_length=255) name_alt = models.CharField(max_length=255, null=True, blank=True) - name_hltv = models.CharField(max_length=255, null=True, blank=True) - name_99dmg = models.CharField(max_length=255, null=True, blank=True) - esea_bracket_id = models.IntegerField(null=True, blank=True) - esea_bracket_team_ids = models.CharField(max_length=255, null=True, blank=True, help_text='Comma Separated') match_set: QuerySet['Match'] @@ -170,6 +165,7 @@ def __str__(self): return self.name class Meta: + abstract = True ordering = ['name'] @@ -202,17 +198,14 @@ class Match(models.Model): (2, 'Defwin in favour of team B'), ) ) - hltv_match_id = models.CharField(max_length=20, null=True, blank=True, help_text='For HLTV Livescore during match') - esea_match_id = models.CharField(max_length=255, null=True, blank=True) enable_tweet = models.BooleanField(default=True) last_tweet = models.DateTimeField(null=True, blank=True) last_tweet_id = models.CharField(max_length=255, null=True, blank=True) - enable_99dmg = models.BooleanField(default=False) - enable_hltv = models.BooleanField(default=True) matchmap_set: QuerySet['MatchMap'] class Meta: + abstract = True ordering = ['-first_map_at'] verbose_name_plural = "matches" @@ -306,44 +299,9 @@ def save(self, *args, **kwargs): def get_absolute_url(self) -> str: return reverse('match_details', kwargs={'slug': self.slug}) - def get_livescore_url(self, request): - if self.hltv_match_id: - url = reverse('match_livescore-detail', kwargs={'pk': self.hltv_match_id}) - return request.build_absolute_uri(url) - - def update_hltv_livescore(self, request) -> None: - # Guard clause in case lineup_a is None - if not self.lineup_a: - return - - url = self.get_livescore_url(request=request) - if url: - response = requests.get(url=url, params={'format': 'json'}).json() - maps = response.get('maps', []) - for map_data in maps: - map_nr = map_data.get('map_nr') - mm_obj = self.matchmap_set.filter(map_nr=map_nr).first() - if mm_obj: - mm_obj.played_map = Map.objects.filter( - models.Q(name=map_data.get('map_name')) | - models.Q(cs_name=map_data.get('map_name')) - ).first() - score_a, score_b = map_data.get('score_a'), map_data.get('score_b') - swap_score = False - team_a_hltv_id = response.get('team_a_id') - if team_a_hltv_id != self.lineup_a.team.hltv_id: - swap_score = True - - if swap_score: - score_b, score_a = score_a, score_b - - mm_obj.rounds_won_team_a = score_a - mm_obj.rounds_won_team_b = score_b - mm_obj.save() - class MatchMap(models.Model): - match = models.ForeignKey(Match, on_delete=models.CASCADE) + match = models.ForeignKey("CsMatch", on_delete=models.CASCADE) played_map = models.ForeignKey(Map, on_delete=models.CASCADE, null=True, blank=True) rounds_won_team_a = models.IntegerField(default=0) rounds_won_team_b = models.IntegerField(default=0) @@ -453,7 +411,7 @@ class Meta: class ExternalLink(models.Model): - match = models.ForeignKey(Match, on_delete=models.CASCADE) + match = models.ForeignKey("CsMatch", on_delete=models.CASCADE) link_type = models.CharField(max_length=255, choices=( ('hltv_match', 'HLTV'), ('esea_match', 'ESEA Match'), From f94e7d059d5d648b34cf657a1cdd3b8d76138e8b Mon Sep 17 00:00:00 2001 From: Ian Paul Falatik <63957260+ifalatik@users.noreply.github.com> Date: Sun, 29 Sep 2024 11:19:41 +0200 Subject: [PATCH 06/32] Rename CSGOSiteSetting -> SiteSetting --- .../0051_rename_csgositesetting_sitesetting.py | 18 ++++++++++++++++++ csgomatches/models/global_models.py | 2 +- 2 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 csgomatches/migrations/0051_rename_csgositesetting_sitesetting.py diff --git a/csgomatches/migrations/0051_rename_csgositesetting_sitesetting.py b/csgomatches/migrations/0051_rename_csgositesetting_sitesetting.py new file mode 100644 index 0000000..af1047d --- /dev/null +++ b/csgomatches/migrations/0051_rename_csgositesetting_sitesetting.py @@ -0,0 +1,18 @@ +# Generated by Django 5.1 on 2024-09-29 09:19 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('csgomatches', '0050_rename_match_csmatch_rename_tournament_cstournament'), + ('sites', '0002_alter_domain_unique'), + ] + + operations = [ + migrations.RenameModel( + old_name='CSGOSiteSetting', + new_name='SiteSetting', + ), + ] diff --git a/csgomatches/models/global_models.py b/csgomatches/models/global_models.py index 4cde84d..271f4ab 100644 --- a/csgomatches/models/global_models.py +++ b/csgomatches/models/global_models.py @@ -441,7 +441,7 @@ class Meta: ordering = ['match', 'link_flag', 'link_type'] -class CSGOSiteSetting(models.Model): +class SiteSetting(models.Model): site = models.ForeignKey(Site, on_delete=models.CASCADE) main_team = models.ForeignKey('csgomatches.Team', on_delete=models.CASCADE, related_name='main_team_settings') second_team = models.ForeignKey('csgomatches.Team', on_delete=models.CASCADE, related_name='sec_team_settings') From 2babcec318c7d0a00b812ff90d8ad72a48f56f89 Mon Sep 17 00:00:00 2001 From: Ian Paul Falatik <63957260+ifalatik@users.noreply.github.com> Date: Sun, 29 Sep 2024 13:36:11 +0200 Subject: [PATCH 07/32] finish migration Match -> CsMatch --- .../blocks/{match.html => csmatch.html} | 2 +- ...ve_year.html => csmatch_archive_year.html} | 4 +- ...{match_detail.html => csmatch_detail.html} | 42 +++++++++---------- .../{match_list.html => csmatch_list.html} | 4 +- csgomatches/views.py | 9 ++-- 5 files changed, 29 insertions(+), 32 deletions(-) rename csgomatches/templates/csgomatches/blocks/{match.html => csmatch.html} (98%) rename csgomatches/templates/csgomatches/{match_archive_year.html => csmatch_archive_year.html} (91%) rename csgomatches/templates/csgomatches/{match_detail.html => csmatch_detail.html} (59%) rename csgomatches/templates/csgomatches/{match_list.html => csmatch_list.html} (94%) diff --git a/csgomatches/templates/csgomatches/blocks/match.html b/csgomatches/templates/csgomatches/blocks/csmatch.html similarity index 98% rename from csgomatches/templates/csgomatches/blocks/match.html rename to csgomatches/templates/csgomatches/blocks/csmatch.html index cbab549..19d00ba 100644 --- a/csgomatches/templates/csgomatches/blocks/match.html +++ b/csgomatches/templates/csgomatches/blocks/csmatch.html @@ -29,7 +29,7 @@
{{ link.get_link_type_display }}
{% endfor %}
{% if user.is_staff %}
- ❄
+ ❄
{% if match.enable_tweet %}
🐦
{% else %}
diff --git a/csgomatches/templates/csgomatches/match_archive_year.html b/csgomatches/templates/csgomatches/csmatch_archive_year.html
similarity index 91%
rename from csgomatches/templates/csgomatches/match_archive_year.html
rename to csgomatches/templates/csgomatches/csmatch_archive_year.html
index 785e027..226c300 100644
--- a/csgomatches/templates/csgomatches/match_archive_year.html
+++ b/csgomatches/templates/csgomatches/csmatch_archive_year.html
@@ -10,7 +10,7 @@ Keine Matches im Archiv von {{ year.year }} gefunden.
@@ -26,4 +26,4 @@{{ lp.player.ingame_name }}
{% endfor %}
{{ lp.player.ingame_name }}
{% endfor %}
Update-Intervall: {% for c in update_choices %} - {% if c == 0 %}Aus{% else %}{{ c }}s{% endif %} + {% if c == 0 %}Aus{% else %}{{ c }}s{% endif %} {% if not forloop.last %} | {% endif %} {% endfor %}
diff --git a/csgomatches/templates/csgomatches/match_list.html b/csgomatches/templates/csgomatches/csmatch_list.html similarity index 94% rename from csgomatches/templates/csgomatches/match_list.html rename to csgomatches/templates/csgomatches/csmatch_list.html index 9d89de1..b6859ec 100644 --- a/csgomatches/templates/csgomatches/match_list.html +++ b/csgomatches/templates/csgomatches/csmatch_list.html @@ -18,7 +18,7 @@ {% block content %}BIG disband? ;-) Keine kommenden Matches eingetragen.
@@ -35,4 +35,4 @@iCal
, iCal CS
, JSON
]
[API
]
-
+
diff --git a/csgomatches/templates/csgomatches/blocks/box_matchmap.html b/csgomatches/templates/csgomatches/blocks/box_matchmap.html
index ec013b7..b38f966 100644
--- a/csgomatches/templates/csgomatches/blocks/box_matchmap.html
+++ b/csgomatches/templates/csgomatches/blocks/box_matchmap.html
@@ -23,10 +23,10 @@
{% endif %}
{% endcomment %}
{% endif %}
- {{ mm.played_map|default_if_none:"-" }}
+ {{ mm.map|default_if_none:"-" }}
Willkommen! API made by '
@@ -47,7 +47,7 @@ def get_view_name(self):
return "Browse API"
def get_renderers(self):
- rend = super(CSGOAPIRootView, self).get_renderers()
+ rend = super(CsAPIRootView, self).get_renderers()
for r in rend:
if isinstance(r, renderers.BrowsableAPIRenderer):
r.template = 'csgomatches/rest_framework/csgo_api.html'
@@ -55,28 +55,28 @@ def get_renderers(self):
return rend
-class TeamViewSet(CSGOView, viewsets.ReadOnlyModelViewSet):
+class TeamViewSet(CsView, viewsets.ReadOnlyModelViewSet):
"""
- CSGO Teams
+ Cs Teams
"""
queryset = apps.get_model('csgomatches.Team').objects.all()
- serializer_class = ser.CSGOTeamSerializer
+ serializer_class = ser.TeamSerializer
def get_view_name(self):
return 'Teams'
-class TournamentViewSet(CSGOView, viewsets.ReadOnlyModelViewSet):
+class TournamentViewSet(CsView, viewsets.ReadOnlyModelViewSet):
queryset = apps.get_model('csgomatches.CsTournament').objects.all()
- serializer_class = ser.CSGOTournamentSerializer
+ serializer_class = ser.CsTournamentSerializer
def get_view_name(self):
return 'Tournaments'
-class MatchViewSet(CSGOView, viewsets.ReadOnlyModelViewSet):
+class MatchViewSet(CsView, viewsets.ReadOnlyModelViewSet):
queryset = apps.get_model('csgomatches.CsMatch').objects.all()
- serializer_class = ser.CSGOMatchSerializer
+ serializer_class = ser.CsMatchSerializer
def get_view_name(self):
return 'Matches (all)'
@@ -86,9 +86,9 @@ def list(self, request, *args, **kwargs):
return super(MatchViewSet, self).list(request, *args, **kwargs)
-class MatchUpcomingViewSet(CSGOView, viewsets.ReadOnlyModelViewSet):
+class MatchUpcomingViewSet(CsView, viewsets.ReadOnlyModelViewSet):
queryset = apps.get_model('csgomatches.CsMatch').objects.filter(first_map_at__gte=timezone.now())
- serializer_class = ser.CSGOMatchSerializer
+ serializer_class = ser.CsMatchSerializer
def get_view_name(self):
return 'Matches (upcoming)'
@@ -98,9 +98,9 @@ def list(self, request, *args, **kwargs):
return super(MatchUpcomingViewSet, self).list(request, *args, **kwargs)
-class LineupViewSet(CSGOView, viewsets.ReadOnlyModelViewSet):
+class LineupViewSet(CsView, viewsets.ReadOnlyModelViewSet):
queryset = apps.get_model('csgomatches.CsLineup').objects.all()
- serializer_class = ser.CSGOLineupSerializer
+ serializer_class = ser.CsLineupSerializer
def get_view_name(self):
return 'Team Lineups'
@@ -110,7 +110,7 @@ def list(self, request, *args, **kwargs):
return super(LineupViewSet, self).list(request, *args, **kwargs)
-class HLTVLiveScoreViewSet(CSGOView, mixins.RetrieveModelMixin, mixins.ListModelMixin, mixins.CreateModelMixin, viewsets.GenericViewSet):
+class HLTVLiveScoreViewSet(CsView, mixins.RetrieveModelMixin, mixins.ListModelMixin, mixins.CreateModelMixin, viewsets.GenericViewSet):
"""
Get HLTV Live Score from any Match
"""
@@ -127,7 +127,7 @@ def get_queryset(self):
def get_serializer(self, *args, **kwargs):
ser_by_action = {
- 'list': ser.CSGOMatchSerializer,
+ 'list': ser.CsMatchSerializer,
'retrieve': ser.HLTVMatchSerializer,
'create': ser.HLTVMatchSerializer,
}
@@ -147,13 +147,13 @@ def get_object(self):
hltv_match_instance = ser_objects.HLTVMatch(hltv_match_id=hltv_match_id)
return hltv_match_instance
-class MatchMapUpdateView(CSGOView, mixins.RetrieveModelMixin, mixins.UpdateModelMixin, viewsets.GenericViewSet):
+class MatchMapUpdateView(CsView, mixins.RetrieveModelMixin, mixins.UpdateModelMixin, viewsets.GenericViewSet):
permission_classes = (permissions.IsAdminUser, )
authentication_classes = (authentication.BasicAuthentication, )
queryset = apps.get_model('csgomatches.CsMatchMap').objects.all()
- serializer_class = ser.CSGOMatchMapUpdateSerializer
+ serializer_class = ser.CsMatchMapUpdateSerializer
-class FaceitProLeagueMatchesView(CSGOView, viewsets.ViewSet):
+class FaceitProLeagueMatchesView(CsView, viewsets.ViewSet):
serializer_class = ser.FaceitProLeagueMatchesSerializer
def get_instances(self):
From cd2b68ed6b38f77b0626336931da38067485082b Mon Sep 17 00:00:00 2001
From: Ian Paul Falatik <63957260+ifalatik@users.noreply.github.com>
Date: Mon, 2 Dec 2024 12:36:47 +0100
Subject: [PATCH 27/32] fix class name
---
csgomatches/drf_api/urls.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/csgomatches/drf_api/urls.py b/csgomatches/drf_api/urls.py
index 792e11b..3652d08 100644
--- a/csgomatches/drf_api/urls.py
+++ b/csgomatches/drf_api/urls.py
@@ -2,7 +2,7 @@
from csgomatches.drf_api import views
router = routers.DefaultRouter()
-router.APIRootView = views.CSGOAPIRootView
+router.APIRootView = views.CsAPIRootView
router.register(r'team', viewset=views.TeamViewSet)
router.register(r'tournament', viewset=views.TournamentViewSet)
router.register(r'lineup', viewset=views.LineupViewSet)
From 11c37fe8a18617ed8a8f5d05b554f39b131cfdb4 Mon Sep 17 00:00:00 2001
From: Ian Paul Falatik <63957260+ifalatik@users.noreply.github.com>
Date: Mon, 2 Dec 2024 12:37:27 +0100
Subject: [PATCH 28/32] fix related_name property for lineup_set and
matchmap_set in CS implementations
---
.../migrations/0064_alter_csmatchmap_match.py | 19 +++++++++++++++++++
.../migrations/0065_alter_cslineup_team.py | 19 +++++++++++++++++++
csgomatches/models/cs_models.py | 5 +++--
3 files changed, 41 insertions(+), 2 deletions(-)
create mode 100644 csgomatches/migrations/0064_alter_csmatchmap_match.py
create mode 100644 csgomatches/migrations/0065_alter_cslineup_team.py
diff --git a/csgomatches/migrations/0064_alter_csmatchmap_match.py b/csgomatches/migrations/0064_alter_csmatchmap_match.py
new file mode 100644
index 0000000..77d7d80
--- /dev/null
+++ b/csgomatches/migrations/0064_alter_csmatchmap_match.py
@@ -0,0 +1,19 @@
+# Generated by Django 5.1 on 2024-12-02 11:33
+
+import django.db.models.deletion
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('csgomatches', '0063_alter_csmatch_options_alter_csmatchmap_options_and_more'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='csmatchmap',
+ name='match',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='matchmap_set', to='csgomatches.csmatch'),
+ ),
+ ]
diff --git a/csgomatches/migrations/0065_alter_cslineup_team.py b/csgomatches/migrations/0065_alter_cslineup_team.py
new file mode 100644
index 0000000..4553143
--- /dev/null
+++ b/csgomatches/migrations/0065_alter_cslineup_team.py
@@ -0,0 +1,19 @@
+# Generated by Django 5.1 on 2024-12-02 11:35
+
+import django.db.models.deletion
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('csgomatches', '0064_alter_csmatchmap_match'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='cslineup',
+ name='team',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='lineup_set', to='csgomatches.team'),
+ ),
+ ]
diff --git a/csgomatches/models/cs_models.py b/csgomatches/models/cs_models.py
index 3821343..b6a1ef5 100644
--- a/csgomatches/models/cs_models.py
+++ b/csgomatches/models/cs_models.py
@@ -28,6 +28,7 @@ class Meta(global_models.Tournament.Meta):
class CsLineup(global_models.Lineup):
+ team = models.ForeignKey(global_models.Team, on_delete=models.CASCADE, related_name='lineup_set')
class Meta(global_models.Lineup.Meta):
verbose_name = "CS Lineup"
verbose_name_plural = "CS Lineups"
@@ -49,7 +50,7 @@ class CsMatch(global_models.OneOnOneMatch):
enable_99dmg = models.BooleanField(default=False)
enable_hltv = models.BooleanField(default=True)
- matchmap_set: QuerySet["CsMatchMap"]
+ matchmap_set: QuerySet['CsMatchMap']
class Meta(global_models.OneOnOneMatch.Meta):
verbose_name = "CS Match"
@@ -125,7 +126,7 @@ def save(self, *args, **kwargs):
super().save(*args, **kwargs)
class CsMatchMap(global_models.OneOnOneMatchMap):
- match = models.ForeignKey(CsMatch, on_delete=models.CASCADE)
+ match = models.ForeignKey(CsMatch, on_delete=models.CASCADE, related_name='matchmap_set')
map = models.ForeignKey(CsMap, on_delete=models.CASCADE, null=True, blank=True)
map_pick_of = models.ForeignKey(CsLineup, null=True, blank=True, on_delete=models.CASCADE)
From 823deb448abc780ff8437b9ec7c646dc41119bd8 Mon Sep 17 00:00:00 2001
From: Ian Paul Falatik <63957260+ifalatik@users.noreply.github.com>
Date: Mon, 2 Dec 2024 12:38:06 +0100
Subject: [PATCH 29/32] fix matchmap_set type annotation in Match model
---
csgomatches/models/global_models.py | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/csgomatches/models/global_models.py b/csgomatches/models/global_models.py
index 884dfb0..04738a3 100644
--- a/csgomatches/models/global_models.py
+++ b/csgomatches/models/global_models.py
@@ -192,7 +192,7 @@ class Match(models.Model):
last_tweet = models.DateTimeField(null=True, blank=True)
last_tweet_id = models.CharField(max_length=255, null=True, blank=True)
- matchmap_set: QuerySet['OneOnOneMatchMap']
+ matchmap_set: QuerySet['MatchMap']
class Meta:
abstract = True
@@ -238,6 +238,8 @@ class OneOnOneMatch(Match):
lineup_a = models.ForeignKey(Lineup, on_delete=models.CASCADE, related_name='matches_as_lineup_a_set', null=True, blank=True)
lineup_b = models.ForeignKey(Lineup, on_delete=models.CASCADE, related_name='matches_as_lineup_b_set', null=True, blank=True)
+ matchmap_set: QuerySet['OneOnOneMatchMap']
+
class Meta(Match.Meta):
abstract = True
From 2a4eb1b68dc58cf6bfcfd34537800177499e9582 Mon Sep 17 00:00:00 2001
From: Ian Paul Falatik <63957260+ifalatik@users.noreply.github.com>
Date: Mon, 2 Dec 2024 12:55:55 +0100
Subject: [PATCH 30/32] fix save method to use the correct model type for
fetching previous instance
---
csgomatches/models/global_models.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/csgomatches/models/global_models.py b/csgomatches/models/global_models.py
index 04738a3..8636813 100644
--- a/csgomatches/models/global_models.py
+++ b/csgomatches/models/global_models.py
@@ -413,7 +413,7 @@ def send_tweet(self, prev_instance=None, interval=180.) -> None:
def save(self, *args, **kwargs):
prev_instance = None
if self.pk:
- prev_instance = MatchMap.objects.get(pk=self.pk)
+ prev_instance = type(self).objects.get(pk=self.pk)
super(MatchMap, self).save(*args, **kwargs)
first_matchmap = self.match.get_first_matchmap()
From 4f1908ea31344c8955e65b3ea19678df0f6adb0c Mon Sep 17 00:00:00 2001
From: Ian Paul Falatik <63957260+ifalatik@users.noreply.github.com>
Date: Mon, 2 Dec 2024 12:56:11 +0100
Subject: [PATCH 31/32] migrate context_data scorelines to CS2 values
---
.../templates/csgomatches/base/base.html | 8 ++++----
csgomatches/views.py | 20 +++++++++----------
2 files changed, 14 insertions(+), 14 deletions(-)
diff --git a/csgomatches/templates/csgomatches/base/base.html b/csgomatches/templates/csgomatches/base/base.html
index 0301af0..b8272ea 100644
--- a/csgomatches/templates/csgomatches/base/base.html
+++ b/csgomatches/templates/csgomatches/base/base.html
@@ -691,10 +691,10 @@ Fun-Facts: {% block content_header_h1 %}Wann spiel
{% if statistics %}
-
{% endif %}
diff --git a/csgomatches/views.py b/csgomatches/views.py
index bbccc5b..38e9b1b 100644
--- a/csgomatches/views.py
+++ b/csgomatches/views.py
@@ -35,25 +35,25 @@ def get_context_data(self, *args, **kwargs):
ctx = super(IndexView, self).get_context_data(*args, **kwargs)
big = models.Team.objects.get(name="BIG")
statistics = {
- 'last_sixteen_zero': models.MatchMap.objects.filter(
+ 'last_thirteen_zero': models.CsMatchMap.objects.filter(
match__lineup_a__team=big,
- rounds_won_team_a=16,
+ rounds_won_team_a=13,
rounds_won_team_b=0
).order_by('-starting_at').first(),
- 'last_zero_sixteen': models.MatchMap.objects.filter(
+ 'last_zero_thirteen': models.CsMatchMap.objects.filter(
match__lineup_a__team=big,
rounds_won_team_a=0,
- rounds_won_team_b=16
+ rounds_won_team_b=13
).order_by('-starting_at').first(),
- 'last_sixteen_fourteen': models.MatchMap.objects.filter(
+ 'last_thirteen_eleven': models.CsMatchMap.objects.filter(
match__lineup_a__team=big,
- rounds_won_team_a=16,
- rounds_won_team_b=14
+ rounds_won_team_a=13,
+ rounds_won_team_b=11
).order_by('-starting_at').first(),
- 'last_fourteen_sixteen': models.MatchMap.objects.filter(
+ 'last_eleven_thirteen': models.CsMatchMap.objects.filter(
match__lineup_a__team=big,
- rounds_won_team_a=14,
- rounds_won_team_b=16
+ rounds_won_team_a=11,
+ rounds_won_team_b=13
).order_by('-starting_at').first(),
}
ctx.update({
From 1d81700eb8ca6062c065e8d3c8190c9a2220c332 Mon Sep 17 00:00:00 2001
From: Ian Paul Falatik <63957260+ifalatik@users.noreply.github.com>
Date: Mon, 2 Dec 2024 12:58:27 +0100
Subject: [PATCH 32/32] add new line
---
csgomatches/models/cs_models.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/csgomatches/models/cs_models.py b/csgomatches/models/cs_models.py
index b6a1ef5..3e9eb77 100644
--- a/csgomatches/models/cs_models.py
+++ b/csgomatches/models/cs_models.py
@@ -125,6 +125,7 @@ def __str__(self):
def save(self, *args, **kwargs):
super().save(*args, **kwargs)
+
class CsMatchMap(global_models.OneOnOneMatchMap):
match = models.ForeignKey(CsMatch, on_delete=models.CASCADE, related_name='matchmap_set')
map = models.ForeignKey(CsMap, on_delete=models.CASCADE, null=True, blank=True)