from django.conf import settings from django.utils import timezone from django.core.management.base import BaseCommand from django.db import close_old_connections import time import signal import sys import traceback from datetime import timedelta from torrent.models import Torrent from torrent.utils import transmission_handler from app.utils import send_sync_channel_message def update_transmission_data(): data = transmission_handler.get_all_data() updated_torrents = [] for torrent in Torrent.objects.all(): if torrent.id in data and torrent.transmission_data != data[torrent.id]: torrent.transmission_data = data[torrent.id] updated_torrents.append(torrent) if updated_torrents: Torrent.objects.bulk_update(updated_torrents, ["transmission_data"]) send_sync_channel_message("torrent", "transmission_data_updated", { torrent.id: torrent.transmission_data for torrent in updated_torrents }) def clean_old_torrents(): expired_date = timezone.now() - timedelta(days=settings.TORRENT_TTL) Torrent.objects.filter(date_created__lt=expired_date).first().delete() class Command(BaseCommand): task_schedule = { "update_transmission_data": { "func": update_transmission_data, "schedule": 5.0 }, "clean_old_torrents": { "func": clean_old_torrents, "schedule": 60.0 } } histories = {} run = True def handle(self, *args, **options): signal.signal(signal.SIGINT, self.exit_gracefully) signal.signal(signal.SIGTERM, self.exit_gracefully) self.stdout.write(self.style.SUCCESS("start")) while self.run: for name, task in self.task_schedule.items(): if name not in self.histories or time.time() - self.histories[name] > task["schedule"]: self.call_func(name) time.sleep(1) def exit_gracefully(self, signum, frame): self.stdout.write(self.style.SUCCESS("exit")) self.run = False def call_func(self, name): close_old_connections() try: self.task_schedule[name]["func"]() self.histories[name] = time.time() except Exception as e: tb = traceback.format_exc() self.stderr.write(self.style.ERROR(f"Error in {name}: {e}\n{tb}"))