import logging import datetime from django import forms from django.utils import timezone from django.core.validators import MaxValueValidator, MinValueValidator from django.utils.translation import gettext_lazy as _ from .models import Timer, TimerType logger = logging.getLogger(__name__) class TimerForm(forms.ModelForm): class Meta: model = Timer fields = ('details', 'system', 'planet_moon', 'structure', 'timer_type', 'objective', 'important', 'corp_timer') def __init__(self, *args, **kwargs): self.user = kwargs.pop('user', None) if 'instance' in kwargs and kwargs['instance'] is not None: # Do conversion from db datetime to days/hours/minutes # for appropriate fields current_time = timezone.now() td = kwargs['instance'].eve_time - current_time initial = kwargs.pop('initial', dict()) if 'days_left' not in initial: initial.update({'days_left': td.days}) if 'hours_left' not in initial: initial.update({'hours_left': td.seconds // 3600}) if 'minutes_left' not in initial: initial.update({'minutes_left': td.seconds // 60 % 60}) kwargs.update({'initial': initial}) super().__init__(*args, **kwargs) structure_choices = [('POCO', 'POCO'), ('I-HUB', 'I-HUB'), ('TCU', 'TCU'), ('POS[S]', 'POS[S]'), ('POS[M]', 'POS[M]'), ('POS[L]', 'POS[L]'), ('Astrahus', 'Astrahus'), ('Fortizar', 'Fortizar'), ('Keepstar', 'Keepstar'), ('Raitaru', 'Raitaru'), ('Azbel', 'Azbel'), ('Sotiyo', 'Sotiyo'), ('Athanor', 'Athanor'), ('Tatara', 'Tatara'), ('Pharolux Cyno Beacon', 'Pharolux Cyno Beacon'), ('Tenebrex Cyno Jammer', 'Tenebrex Cyno Jammer'), ('Ansiblex Jump Gate', 'Ansiblex Jump Gate'), ('Moon Mining Cycle', 'Moon Mining Cycle'), (_('Other'), _('Other'))] objective_choices = [('Friendly', _('Friendly')), ('Hostile', _('Hostile')), ('Neutral', _('Neutral'))] details = forms.CharField(max_length=254, required=True, label=_('Details')) system = forms.CharField(max_length=254, required=True, label=_("System")) planet_moon = forms.CharField(max_length=254, label=_("Planet/Moon"), required=False, initial="") structure = forms.ChoiceField(choices=structure_choices, required=True, label=_("Structure Type")) timer_type = forms.ChoiceField(choices=TimerType.choices, label=_("Timer Type")) objective = forms.ChoiceField(choices=objective_choices, required=True, label=_("Objective")) absolute_checkbox = forms.BooleanField(label=_("Absolute Timer"), required=False, initial=False) absolute_time = forms.CharField(required=False,label=_("Date and Time")) days_left = forms.IntegerField(required=False, label=_("Days Remaining"), validators=[MinValueValidator(0)]) hours_left = forms.IntegerField(required=False, label=_("Hours Remaining"), validators=[MinValueValidator(0), MaxValueValidator(23)]) minutes_left = forms.IntegerField(required=False, label=_("Minutes Remaining"), validators=[MinValueValidator(0), MaxValueValidator(59)]) important = forms.BooleanField(label=_("Important"), required=False) corp_timer = forms.BooleanField(label=_("Corp-Restricted"), required=False) def save(self, commit=True): timer = super().save(commit=False) # Get character character = self.user.profile.main_character corporation = character.corporation logger.debug("Determined timer save request on behalf " "of character {} corporation {}".format(character, corporation)) days_left = self.cleaned_data['days_left'] hours_left = self.cleaned_data['hours_left'] minutes_left = self.cleaned_data['minutes_left'] absolute_time = self.cleaned_data['absolute_time'] if days_left or hours_left or minutes_left: # Calculate future time future_time = datetime.timedelta(days=days_left, hours=hours_left, minutes=minutes_left) current_time = timezone.now() eve_time = current_time + future_time logger.debug(f"Determined timer eve time is {eve_time} - current time {current_time}, adding {future_time}") elif absolute_time: # Use absolute time eve_time = absolute_time else: raise ValueError("Either future time or absolute time must be provided.") timer.eve_time = eve_time timer.eve_character = character timer.eve_corp = corporation timer.user = self.user if commit: timer.save() return timer