368 lines
14 KiB
Python
368 lines
14 KiB
Python
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=False)
|
|
current_mday = models.IntegerField(null=True, default=False)
|
|
matches_by_mday = models.IntegerField(null=True, default=False)
|
|
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:
|
|
unique_together = (('sport', 'name', 'gender'), ('sport', 'clean_name', 'gender'))
|
|
|
|
@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
|
|
|
|
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:
|
|
unique_together = (('sport', 'name', 'gender'), ('sport', 'clean_name', 'gender'))
|
|
|
|
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)
|
|
|
|
|
|
class LegChoice(enum.Enum):
|
|
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)
|
|
t_home = MainappForeignKey(Team, related_name='t_home', on_delete=models.CASCADE, null=True, default=None)
|
|
t_away = MainappForeignKey(Team, related_name='t_away', on_delete=models.CASCADE, null=True, default=None)
|
|
p_home = MainappForeignKey(Player, related_name='p_home', on_delete=models.CASCADE, null=True, default=None)
|
|
p_away = MainappForeignKey(Player, related_name='p_away', on_delete=models.CASCADE, null=True, default=None)
|
|
|
|
mday = models.IntegerField(null=True, default=None)
|
|
mday_id = 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)
|
|
|
|
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)
|
|
|
|
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)
|
|
|
|
class Meta:
|
|
unique_together = (('league', 't_home', 't_away', 'p_home', 'p_away', 'mday', 'round', 'leg'), )
|
|
|
|
|
|
class Tag:
|
|
def __init__(self, name):
|
|
self.name = name
|
|
self.clean_name = Utils.sanitize(self.name)
|
|
|
|
@property
|
|
def to_json(self):
|
|
return {
|
|
'name': self.name,
|
|
'clean_name': self.clean_name
|
|
}
|
|
|
|
|
|
class Source(MainappModel, models.Model):
|
|
name = models.CharField(max_length=30, unique=True)
|
|
clean_name = models.CharField(max_length=30, unique=True)
|
|
image_name = models.CharField(max_length=30, unique=True)
|
|
big_image_name = models.CharField(max_length=30, unique=True)
|
|
|
|
urls = fields.JSONField(default=dict)
|
|
|
|
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.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):
|
|
sport = MainappForeignKey(Sport, on_delete=models.CASCADE)
|
|
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)
|
|
|
|
@property
|
|
def tag_objects(self):
|
|
# noinspection PyTypeChecker
|
|
return [Tag(tag) for tag in self.tags] if self.tags else []
|
|
|
|
def __str__(self):
|
|
return f'#{self.id} {self.title}'
|
|
|
|
@property
|
|
def to_json(self):
|
|
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': [tag.to_json for tag in self.tag_objects],
|
|
'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
|