feat(main): commit
This commit is contained in:
@@ -1,16 +1,29 @@
|
||||
from django.core.management.base import BaseCommand
|
||||
from core.models import AppUser, Library, Channel, MediaItem, Airing, ScheduleTemplate
|
||||
from core.services.scheduler import ScheduleGenerator
|
||||
from django.utils import timezone
|
||||
from datetime import timedelta
|
||||
from datetime import timedelta, date
|
||||
import textwrap
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = "Displays a beautifully formatted terminal dashboard of the current backend state."
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument('--channel', type=int, help='Inspect specific channel schedule')
|
||||
parser.add_argument('--test-generate', action='store_true', help='Trigger generation for today if inspecting a channel')
|
||||
|
||||
def get_color(self, text, code):
|
||||
"""Helper to wrap string in bash color codes"""
|
||||
return f"\033[{code}m{text}\033[0m"
|
||||
|
||||
def handle(self, *args, **options):
|
||||
channel_id = options.get('channel')
|
||||
test_generate = options.get('test_generate')
|
||||
|
||||
if channel_id:
|
||||
self.inspect_channel(channel_id, test_generate)
|
||||
return
|
||||
|
||||
# 1. Gather Aggregate Metrics
|
||||
total_users = AppUser.objects.count()
|
||||
total_libraries = Library.objects.count()
|
||||
@@ -46,7 +59,7 @@ class Command(BaseCommand):
|
||||
for c in channels:
|
||||
status_color = "1;32" if c.is_active else "1;31"
|
||||
status_text = "ACTIVE" if c.is_active else "INACTIVE"
|
||||
self.stdout.write(f"\n 📺 [{c.channel_number or '-'}] {c.name} ({self.get_color(status_text, status_color)})")
|
||||
self.stdout.write(f"\n 📺 [{c.id}] {c.name} (Ch {c.channel_number or '-'}) ({self.get_color(status_text, status_color)})")
|
||||
|
||||
# Show templates
|
||||
templates = c.scheduletemplate_set.filter(is_active=True).order_by('-priority')
|
||||
@@ -57,4 +70,40 @@ class Command(BaseCommand):
|
||||
blocks_count = t.scheduleblock_set.count()
|
||||
self.stdout.write(f" 📄 Template: {t.name} (Priority {t.priority}) -> {blocks_count} Blocks")
|
||||
|
||||
self.stdout.write(f"\nUse {self.get_color('--channel <id>', '1;37')} to inspect detailed schedule.\n")
|
||||
|
||||
def inspect_channel(self, channel_id, test_generate):
|
||||
try:
|
||||
channel = Channel.objects.get(id=channel_id)
|
||||
except Channel.DoesNotExist:
|
||||
self.stdout.write(self.get_color(f"Error: Channel {channel_id} not found.", "1;31"))
|
||||
return
|
||||
|
||||
if test_generate:
|
||||
self.stdout.write(self.get_color(f"\nTriggering schedule generation for {channel.name}...", "1;33"))
|
||||
generator = ScheduleGenerator(channel)
|
||||
count = generator.generate_for_date(date.today())
|
||||
self.stdout.write(f"Done. Created {self.get_color(str(count), '1;32')} new airings.")
|
||||
|
||||
now = timezone.now()
|
||||
end_window = now + timedelta(hours=12)
|
||||
|
||||
airings = Airing.objects.filter(
|
||||
channel=channel,
|
||||
ends_at__gt=now,
|
||||
starts_at__lt=end_window
|
||||
).select_related('media_item').order_by('starts_at')
|
||||
|
||||
self.stdout.write(self.get_color(f"\n=== Schedule for {channel.name} (Next 12h) ===", "1;34"))
|
||||
|
||||
if not airings:
|
||||
self.stdout.write(self.get_color(" (No airings scheduled in this window)", "1;33"))
|
||||
else:
|
||||
for a in airings:
|
||||
time_str = f"{a.starts_at.strftime('%H:%M')} - {a.ends_at.strftime('%H:%M')}"
|
||||
if a.starts_at <= now <= a.ends_at:
|
||||
self.stdout.write(f" {self.get_color('▶ ON AIR', '1;32')} {self.get_color(time_str, '1;37')} | {a.media_item.title}")
|
||||
else:
|
||||
self.stdout.write(f" {time_str} | {a.media_item.title}")
|
||||
|
||||
self.stdout.write("\n")
|
||||
|
||||
Reference in New Issue
Block a user