Files
mark dc1853d1a7 Fix voor langer dan een dag geen quota bijschrijven
timedelta.seconds werkte niet zoals ik had verwacht.
2024-08-05 22:28:36 +02:00

146 lines
4.8 KiB
Python

from django.db import models
from django.contrib.auth.models import User
from .track import Track
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.utils import timezone
from datetime import datetime, timedelta, UTC
from ..spotify import spt
import os
from dotenv import load_dotenv
load_dotenv()
NOMINATIONS_PER_DAY = 10
MAX_QUOTA = 22
class Background(models.Model):
def __str__(self):
return self.name
name = models.CharField(max_length=128)
image = models.ImageField(upload_to="wallpapers/", null=True, blank=True)
repeat = models.BooleanField(default=False)
cover = models.BooleanField(default=False)
color = models.CharField(max_length=32, blank=True)
class Profile(models.Model):
def __str__(self):
return str(self.user)
user = models.OneToOneField(User, on_delete=models.CASCADE)
background = models.ForeignKey(Background, null=True, on_delete=models.SET_NULL)
last_voted = models.ForeignKey(Track, null=True, on_delete=models.SET_NULL)
quota = models.FloatField(default=10.0)
quota_last_updated = models.DateTimeField(default=timezone.now, null=False)
spt_access_token = models.CharField(max_length=256, default="", blank=True, null=True)
spt_refresh_token = models.CharField(max_length=256, default="", blank=True, null=True)
spt_expires = models.DateTimeField(default=None, null=True)
@property
def quota_display(self):
return int(self.quota)
def update_quota(self):
elapsed = timezone.now() - self.quota_last_updated
if elapsed.total_seconds() > 300:
noms_per_second = NOMINATIONS_PER_DAY/(60*60*24)
self.quota += noms_per_second * elapsed.total_seconds()
self.quota = min(self.quota, MAX_QUOTA)
print(f"{self.user.username}: Er zijn {elapsed.total_seconds()}s voorbij, je nieuwe quota is {self.quota}")
self.quota_last_updated = timezone.now()
@property
def can_nominate(self):
"""Is this user allowed to nominate at this point in time?"""
end_date = os.getenv('DATE_NOM_END')
if self.user.is_superuser:
return (True,)
if end_date:
end_date = datetime.fromisoformat(end_date)
if end_date <= datetime.now(tz=UTC):
return (False, "over")
if self.quota < 1:
return (False, "quota")
return (True,)
@property
def can_vote(self):
"""Is this user allowed to vote at this point in time?"""
end_date = os.getenv('DATE_VOTE_END')
if self.user.is_superuser or not end_date:
return True
end_date = datetime.fromisoformat(end_date)
if end_date <= datetime.now(tz=UTC):
return False
return True
@property
def vote_end(self):
return os.getenv('DATE_VOTE_END')
@property
def nominate_end(self):
return os.getenv('DATE_NOM_END')
def init_spt(self, code):
"""Initial setting of spotify tokens from user accept code"""
data = spt.get_token_json(
grant_type='authorization_code',
code=code
)
self.save_spt(data)
def refresh_spt(self):
"""Refreshes expired access token using stored refresh token"""
if self.spt_refresh_token:
data = spt.get_token_json(
grant_type='refresh_token',
refresh_token=self.spt_refresh_token
)
self.save_spt(data)
def save_spt(self, data):
"""Saves tokens from json response"""
access = data.get('access_token', None)
refresh = data.get('refresh_token', self.spt_refresh_token)
expires = data.get('expires_in', 3600)
self.spt_access_token = access
self.spt_refresh_token = refresh
self.spt_expires = timezone.now() + timedelta(seconds=expires - 300)
self.save()
def unlink_spt(self):
self.spt_access_token = None
self.spt_refresh_token = None
self.spt_expires = None
@property
def can_spt(self):
return (
self.spt_access_token and
self.spt_expires and
(timezone.now() < self.spt_expires)
)
def get_or_update_spt(self):
if self.spt_refresh_token:
if not self.can_spt:
self.refresh_spt()
return self.spt_access_token
return None
def save(self, *args, **kwargs):
self.update_quota()
super().save(*args, **kwargs)
@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
if created:
Profile.objects.create(user=instance)
@receiver(post_save, sender=User)
def save_user_profile(sender, instance, **kwargs):
Profile.objects.get_or_create(user=instance)
instance.profile.save()