from django.core.management.base import BaseCommand from tournaments.tasks import background_task_check_confirmation_deadlines from django.utils import timezone import datetime from background_task.models import Task from django.conf import settings class Command(BaseCommand): help = 'Schedule background tasks to run at :00 and :30 of every hour' def handle(self, *args, **options): # Clear existing tasks first to avoid duplicates Task.objects.filter(task_name='tournaments.tasks.check_confirmation_deadlines').delete() # Get the current timezone-aware time now = timezone.now() # Get local timezone for display purposes local_timezone = timezone.get_current_timezone() local_now = now.astimezone(local_timezone) # Calculate time until next interval current_minute = local_now.minute minutes_until_next = settings.BACKGROUND_SCHEDULED_TASK_INTERVAL - (current_minute % settings.BACKGROUND_SCHEDULED_TASK_INTERVAL) next_minute = (current_minute + minutes_until_next) % 60 next_hour = local_now.hour + ((current_minute + minutes_until_next) // 60) # Create a datetime with the next run time in local time first_run_local = local_now.replace( hour=next_hour, minute=next_minute + 1, #let the expiration time be off first second=0, microsecond=0 ) # Handle day rollover if needed if first_run_local < local_now: # This would happen if we crossed midnight first_run_local += datetime.timedelta(days=1) # Calculate seconds from now until the first run seconds_until_first_run = (first_run_local - local_now).total_seconds() if seconds_until_first_run < 0: seconds_until_first_run = 0 # If somehow negative, run immediately # Schedule with seconds delay instead of a specific datetime background_task_check_confirmation_deadlines( schedule=int(seconds_until_first_run), # Delay in seconds before first run repeat=settings.BACKGROUND_SCHEDULED_TASK_INTERVAL * 60 # 30 minutes in seconds ) # Show the message with proper timezone info local_timezone_name = local_timezone.tzname(local_now) self.stdout.write(self.style.SUCCESS( f'Task scheduled to first run at {first_run_local.strftime("%H:%M:%S")} {local_timezone_name} ' f'(in {int(seconds_until_first_run)} seconds) ' f'and then every {settings.BACKGROUND_SCHEDULED_TASK_INTERVAL} minutes' ))