import enum from django.contrib.postgres import fields from django.db import models class MainappObjects(list): def __init__(self, **kwargs): super().__init__(list(kwargs.keys())) pass @staticmethod def get(**kwargs): return MainappObjects(**kwargs) @staticmethod def filter(**kwargs): return MainappObjects(**kwargs) @staticmethod def order_by(*args): return MainappObjects(**{i: args[i] for i in range(len(args))}) class MainappModel: id = None objects = MainappObjects DoesNotExist = models.ObjectDoesNotExist class MainappForeignKey(models.ForeignKey): to_json = None class Sport(MainappModel, models.Model): name = models.CharField(max_length=20, unique=True) clean_name = models.CharField(max_length=20, unique=True) display_sets = models.BooleanField(default=False) points = fields.JSONField(default=dict) enabled = models.BooleanField(default=False) def __str__(self): return f'#{self.id} {self.name}' class Country(MainappModel, models.Model): name = models.CharField(max_length=30, unique=True) clean_name = models.CharField(max_length=30, unique=True) short_name = models.CharField(max_length=5) source_names = fields.JSONField(default=dict) def __str__(self): return f'#{self.id} {self.name}' class GenderChoice(enum.Enum): MALE = 1 FEMALE = 2 class League(MainappModel, models.Model): sport = MainappForeignKey(Sport, on_delete=models.CASCADE) country = MainappForeignKey(Country, on_delete=models.CASCADE) name = models.CharField(max_length=30, null=False) clean_name = models.CharField(max_length=30, null=False) gender = models.IntegerField(choices=((c.value, c) for c in GenderChoice), null=True, default=None) degree = models.IntegerField(null=False, default=0) schedule_url = models.CharField(max_length=200, null=True, default=None) ranking_url = models.CharField(max_length=200, null=True, default=None) channel_url = models.CharField(max_length=200, null=True, default=None) mdays = models.IntegerField(null=True, default=None) current_mday = models.IntegerField(null=True, default=None) matches_by_mday = models.IntegerField(null=True, default=None) team_count = models.IntegerField(null=False, default=0) rounds = fields.ArrayField(models.CharField(max_length=30), null=True, default=None) groups = fields.ArrayField(models.CharField(max_length=30), null=True, default=None) points = fields.JSONField(null=True, default=None) promotions = fields.JSONField(null=True, default=None) images = fields.JSONField(null=True, default=None) schedule = fields.JSONField(null=True, default=None) tags = fields.ArrayField(models.CharField(max_length=30), null=True, default=None) clean_tags = fields.ArrayField(models.CharField(max_length=30), null=True, default=None) news_count = models.IntegerField(null=False, default=0) error = models.CharField(max_length=100, null=True, default=None) trace = models.CharField(max_length=1000, null=True, default=None) class Meta: constraints = [ models.UniqueConstraint( fields=['sport', 'name', 'gender'], name="custom_unique_league" ) ] @classmethod def navbar_sports(cls): leagues = cls.objects.order_by('sport_id', 'country_id', 'degree') sports = list() for league in leagues: if not sports or league.sport.id != sports[-1].id: sports.append(league.sport) if not hasattr(sports[-1], 'countries'): sports[-1].countries = [league.country] if league.country.id != sports[-1].countries[-1].id: sports[-1].countries.append(league.country) if not hasattr(sports[-1].countries[-1], 'leagues'): sports[-1].countries[-1].leagues = [league] else: sports[-1].countries[-1].leagues.append(league) return sports @property def to_json(self): return { 'id': self.id, 'name': self.name, 'clean_name': self.clean_name, 'images': self.images } def __str__(self): return f'#{self.id} {self.name}' class Team(MainappModel, models.Model): sport = MainappForeignKey(Sport, on_delete=models.CASCADE) country = MainappForeignKey(Country, on_delete=models.CASCADE) name = models.CharField(max_length=30, null=False) clean_name = models.CharField(max_length=30, null=False) short_name = models.CharField(max_length=30, null=True, default=None) long_name = models.CharField(max_length=100, null=True, default=None) gender = models.IntegerField(choices=((c.value, c) for c in GenderChoice), null=True, default=None) names = fields.JSONField(null=True, default=None) url = models.CharField(max_length=200, null=True, default=None) images = fields.JSONField(null=True, default=None) tags = fields.ArrayField(models.CharField(max_length=50), null=True, default=None) clean_tags = fields.ArrayField(models.CharField(max_length=50), null=True, default=None) news_count = models.IntegerField(null=False, default=0) error = models.CharField(max_length=100, null=True, default=None) trace = models.CharField(max_length=1000, null=True, default=None) class Meta: constraints = [ models.UniqueConstraint( fields=['sport', 'name', 'gender'], name="custom_unique_team" ) ] @property def to_json(self): return { 'id': self.id, 'name': self.name, 'clean_name': self.clean_name, 'short_name': self.short_name, 'long_name': self.long_name, 'images': self.images } def __str__(self): return f'#{self.id} {self.name}' class RoleChoice(enum.Enum): GOALKEEPER = 1 DEFENDER = 2 MIDFIELDER = 3 ATTACKER = 4 class FootChoice(enum.Enum): RIGHT = 1 LEFT = 2 BOTH = 3 class Player(MainappModel, models.Model): sport = MainappForeignKey(Sport, on_delete=models.CASCADE) team = MainappForeignKey(Team, on_delete=models.CASCADE, null=True, default=None) country1 = MainappForeignKey(Country, related_name='country1', on_delete=models.CASCADE, null=True, default=None) country2 = MainappForeignKey(Country, related_name='country2', on_delete=models.CASCADE, null=True, default=None) full_name = models.CharField(max_length=100, unique=True) clean_name = models.CharField(max_length=100, unique=True) first_name = models.CharField(max_length=50, null=True, default=None) last_name = models.CharField(max_length=50, null=True, default=None) birth_date = models.DateField(null=True, default=None) image = models.CharField(max_length=200, null=True, default=None) number = models.IntegerField(null=True, default=None) role = models.IntegerField(choices=((c.value, c) for c in RoleChoice), null=True, default=None) position = models.CharField(max_length=50, null=True, default=None) age = models.IntegerField(null=True, default=None) size = models.IntegerField(null=True, default=None) foot = models.IntegerField(choices=((c.value, c) for c in FootChoice), null=True, default=None) contract_end = models.DateField(null=True, default=None) price = models.IntegerField(null=True, default=None) error = models.CharField(max_length=100, null=True, default=None) trace = models.CharField(max_length=1000, null=True, default=None) @property def to_json(self): return { 'id': self.id, 'full_name': self.full_name, 'first_name': self.first_name, 'last_name': self.last_name } class LegChoice(enum.Enum): EMPTY = 0 FIRST = 1 SECOND = 2 REPLAY = 3 class StatusChoice(enum.Enum): FIRST_TIME = 1 HALF_TIME = 2 SECOND_TIME = 3 FIRST_EXTRA = 4 HALF_EXTRA = 5 SECOND_EXTRA = 6 SHOOTOUT = 7 WAIT_SCORES = 8 OVER = 9 POSTPONED = 10 CANCELLED = 11 class WinnerChoice(enum.Enum): HOME = 1 AWAY = 2 DRAW = 3 class ExtraTimeChoice(enum.Enum): EXTRA_TIME = 1 SHOOTOUT = 2 class Match(MainappModel, models.Model): league = MainappForeignKey(League, on_delete=models.CASCADE) team_home = MainappForeignKey(Team, related_name='th', on_delete=models.CASCADE, null=True, default=None) team_away = MainappForeignKey(Team, related_name='ta', on_delete=models.CASCADE, null=True, default=None) player_home = MainappForeignKey(Player, related_name='ph', on_delete=models.CASCADE, null=True, default=None) player_away = MainappForeignKey(Player, related_name='pa', on_delete=models.CASCADE, null=True, default=None) mday = models.IntegerField(null=True, default=None) round = models.CharField(max_length=100, null=True, default=None) leg = models.IntegerField(choices=((c.value, c) for c in LegChoice), null=True, default=None) sign = models.CharField(max_length=1000, unique=True, null=False) base_url = models.CharField(max_length=200, null=True, default=None) score_url = models.CharField(max_length=200, null=True, default=None) live_url = models.CharField(max_length=200, null=True, default=None) tv_channels = fields.ArrayField(models.CharField(max_length=50), null=True, default=None) mday_id = models.IntegerField(null=True, default=None) status = models.IntegerField(choices=((c.value, c) for c in StatusChoice), null=True, default=None) minute = models.CharField(max_length=10, null=True, default=None) start_date = models.DateTimeField(null=True, default=None) end_date = models.DateTimeField(null=True, default=None) home_score = models.IntegerField(null=True, default=None) away_score = models.IntegerField(null=True, default=None) sets_score = fields.JSONField(null=True, default=None) winner = models.IntegerField(choices=((c.value, c) for c in WinnerChoice), null=True, default=None) extra_time = models.IntegerField(choices=((c.value, c) for c in ExtraTimeChoice), null=True, default=None) shootout_home = models.IntegerField(null=True, default=None) shootout_away = models.IntegerField(null=True, default=None) squad = fields.JSONField(null=True, default=None) events = fields.JSONField(null=True, default=None) stats = fields.JSONField(null=True, default=None) live = fields.JSONField(null=True, default=None) last_event = fields.JSONField(null=True, default=None) last_event_date = models.DateTimeField(null=True, default=None) error = models.CharField(max_length=100, null=True, default=None) trace = models.CharField(max_length=1000, null=True, default=None) @property def to_json(self): return { 'id': self.id, 'league': self.league.to_json, 'team_home': self.team_home.to_json if self.team_home else None, 'team_away': self.team_away.to_json if self.team_away else None, 'player_home': self.player_home.to_json if self.player_home else None, 'player_away': self.player_away.to_json if self.player_away else None, 'mday': self.mday, 'round': self.round, 'leg': self.leg, 'status': self.status, 'minute': self.minute, 'start_date': self.start_date, 'home_score': self.home_score, 'away_score': self.away_score, 'sets_score': self.sets_score, 'winner': self.winner, 'extra_time': self.extra_time, 'shootout_home': self.shootout_home, 'shootout_away': self.shootout_away, } class Source(MainappModel, models.Model): sport = MainappForeignKey(Sport, on_delete=models.CASCADE) name = models.CharField(max_length=30, null=False) clean_name = models.CharField(max_length=30, null=False) image_name = models.CharField(max_length=30, null=False) big_image_name = models.CharField(max_length=30, null=False) feed_url = models.CharField(max_length=200, null=False) error = models.CharField(max_length=100, null=True, default=None) trace = models.CharField(max_length=1000, null=True, default=None) class Meta: constraints = [ models.UniqueConstraint( fields=['sport', 'name'], name="custom_unique_source" ) ] def __str__(self): return f'#{self.id} {self.name}' @property def to_json(self): return { 'id': self.id, 'name': self.name, 'clean_name': self.clean_name, 'image_name': self.image_name, 'big_image_name': self.big_image_name } class News(MainappModel, models.Model): source = MainappForeignKey(Source, on_delete=models.CASCADE) league = MainappForeignKey(League, on_delete=models.CASCADE, null=True, default=None) team = MainappForeignKey(Team, on_delete=models.CASCADE, null=True, default=None) title = models.CharField(max_length=500, unique=True) clean_title = models.CharField(max_length=500, unique=True) link = models.CharField(max_length=500, unique=True) pub_date = models.DateTimeField(null=True, default=None) description = models.CharField(max_length=1000, null=True, default=None) image = models.CharField(max_length=500, null=True, default=None) teaser = models.CharField(max_length=2000, null=True, default=None) author = models.CharField(max_length=100, null=True, default=None) content = fields.ArrayField(models.CharField(max_length=5000), null=True, default=None) redirect = models.CharField(max_length=500, null=True, default=None) haystack = models.CharField(max_length=2000, null=True, default=None) tags = fields.ArrayField(models.CharField(max_length=50), null=True, default=None) clean_tags = fields.ArrayField(models.CharField(max_length=50), null=True, default=None) error = models.CharField(max_length=100, null=True, default=None) trace = models.CharField(max_length=1000, null=True, default=None) def __str__(self): return f'#{self.id} {self.title}' @property def to_json(self): # noinspection PyTypeChecker return { 'id': self.id, 'title': self.title, 'clean_title': self.clean_title, 'pub_date': self.pub_date, 'description': self.description, 'link': self.link, 'image': self.image, 'source': self.source.to_json, 'tags': list(zip(self.tags, self.clean_tags)), 'redirect': self.redirect } class Utils: SYMBOLS = { 'á': 'a', 'Á': 'a', 'à': 'e', 'À': 'a', 'â': 'a', 'Â': 'a', 'ä': 'a', 'Ä': 'a', 'ã': 'a', 'ç': 'c', 'é': 'e', 'É': 'e', 'è': 'e', 'È': 'e', 'ê': 'e', 'Ê': 'e', 'ë': 'e', 'Ë': 'e', 'í': 'i', 'Í': 'i', 'ì': 'i', 'Ì': 'i', 'î': 'i', 'Î': 'i', 'ï': 'i', 'Ï': 'i', 'ñ': 'n', 'ó': 'o', 'Ó': 'o', 'ò': 'o', 'Ò': 'o', 'ô': 'o', 'Ô': 'o', 'ö': 'o', 'Ö': 'o', 'ø': 'o', 'ú': 'u', 'Ú': 'u', 'ù': 'u', 'Ù': 'u', 'û': 'u', 'Û': 'u', 'ü': 'u', 'Ü': 'u' } @classmethod def sanitize(cls, s): return ''.join([ c if ord('a') <= ord(c) <= ord('z') or ord('0') <= ord(c) <= ord('9') else chr(ord(c) - ord('A') + ord('a')) if ord('A') <= ord(c) <= ord('Z') else cls.SYMBOLS.get(c, '-') for c in s ]) if s is not None else None