feat(main): initial commit

This commit is contained in:
2026-03-08 11:28:59 -04:00
commit 458ceb31b1
66 changed files with 7885 additions and 0 deletions

0
api/routers/__init__.py Normal file
View File

47
api/routers/channel.py Normal file
View File

@@ -0,0 +1,47 @@
from ninja import Router, Schema
from typing import List, Optional
from core.models import Channel, AppUser, Library
from django.shortcuts import get_object_or_404
router = Router(tags=["channel"])
class ChannelSchema(Schema):
id: int
name: str
slug: str
channel_number: Optional[int] = None
description: Optional[str] = None
scheduling_mode: str
library_id: int
owner_user_id: int
class ChannelCreateSchema(Schema):
name: str
slug: str
channel_number: Optional[int] = None
description: Optional[str] = None
library_id: int
owner_user_id: int # Mock Auth User
@router.get("/", response=List[ChannelSchema])
def list_channels(request):
return Channel.objects.all()
@router.get("/{channel_id}", response=ChannelSchema)
def get_channel(request, channel_id: int):
return get_object_or_404(Channel, id=channel_id)
@router.post("/", response={201: ChannelSchema})
def create_channel(request, payload: ChannelCreateSchema):
owner = get_object_or_404(AppUser, id=payload.owner_user_id)
library = get_object_or_404(Library, id=payload.library_id)
channel = Channel.objects.create(
owner_user=owner,
library=library,
name=payload.name,
slug=payload.slug,
channel_number=payload.channel_number,
description=payload.description
)
return 201, channel

38
api/routers/library.py Normal file
View File

@@ -0,0 +1,38 @@
from ninja import Router, Schema
from typing import List, Optional
from core.models import Library, AppUser
from django.shortcuts import get_object_or_404
router = Router(tags=["library"])
class LibrarySchema(Schema):
id: int
name: str
description: Optional[str] = None
visibility: str
owner_user_id: int
class LibraryCreateSchema(Schema):
name: str
description: Optional[str] = None
visibility: Optional[str] = 'private'
owner_user_id: int # In a real app with auth, this would come from request.user
@router.get("/", response=List[LibrarySchema])
def list_libraries(request):
return Library.objects.all()
@router.get("/{library_id}", response=LibrarySchema)
def get_library(request, library_id: int):
return get_object_or_404(Library, id=library_id)
@router.post("/", response={201: LibrarySchema})
def create_library(request, payload: LibraryCreateSchema):
owner = get_object_or_404(AppUser, id=payload.owner_user_id)
library = Library.objects.create(
owner_user=owner,
name=payload.name,
description=payload.description,
visibility=payload.visibility
)
return 201, library

65
api/routers/schedule.py Normal file
View File

@@ -0,0 +1,65 @@
from ninja import Router, Schema
from typing import List, Optional
from core.models import ScheduleTemplate, Channel
from django.shortcuts import get_object_or_404
from datetime import date
router = Router(tags=["schedule"])
class ScheduleTemplateSchema(Schema):
id: int
name: str
description: Optional[str] = None
timezone_name: str
valid_from_date: Optional[date] = None
valid_to_date: Optional[date] = None
priority: int
is_active: bool
channel_id: int
class ScheduleTemplateCreateSchema(Schema):
name: str
description: Optional[str] = None
timezone_name: str
valid_from_date: Optional[date] = None
valid_to_date: Optional[date] = None
priority: int = 0
is_active: bool = True
channel_id: int
@router.get("/template/", response=List[ScheduleTemplateSchema])
def list_schedule_templates(request):
return ScheduleTemplate.objects.all()
@router.get("/template/{template_id}", response=ScheduleTemplateSchema)
def get_schedule_template(request, template_id: int):
return get_object_or_404(ScheduleTemplate, id=template_id)
@router.post("/template/", response={201: ScheduleTemplateSchema})
def create_schedule_template(request, payload: ScheduleTemplateCreateSchema):
channel = get_object_or_404(Channel, id=payload.channel_id)
template = ScheduleTemplate.objects.create(
channel=channel,
name=payload.name,
description=payload.description,
timezone_name=payload.timezone_name,
valid_from_date=payload.valid_from_date,
valid_to_date=payload.valid_to_date,
priority=payload.priority,
is_active=payload.is_active
)
return 201, template
class GenerateScheduleSchema(Schema):
target_date: date
@router.post("/generate/{channel_id}")
def generate_schedule(request, channel_id: int, payload: GenerateScheduleSchema):
channel = get_object_or_404(Channel, id=channel_id)
# Inline import to prevent circular dependency issues during initialization
from core.services.scheduler import ScheduleGenerator
generator = ScheduleGenerator(channel=channel)
airings_created = generator.generate_for_date(payload.target_date)
return {"status": "success", "airings_created": airings_created}

52
api/routers/user.py Normal file
View File

@@ -0,0 +1,52 @@
from ninja import Router
from core.models import AppUser
from django.shortcuts import get_object_or_404
from ninja import Schema
from typing import List, Optional
from datetime import datetime
router = Router()
class UserSchema(Schema):
id: int
username: str
email: str
is_staff: bool
is_superuser: bool
is_active: bool
date_joined: datetime
class UserCreateSchema(Schema):
username: str
email: str
password: str
is_superuser: bool = False
class UserUpdateSchema(Schema):
username: Optional[str] = None
email: Optional[str] = None
is_active: Optional[bool] = None
@router.get("/", response=List[UserSchema])
def list_users(request):
return AppUser.objects.all()
@router.get("/{user_id}", response=UserSchema)
def get_user(request, user_id: int):
return get_object_or_404(AppUser, id=user_id)
@router.post("/", response={201: UserSchema})
def create_user(request, payload: UserCreateSchema):
if payload.is_superuser:
user = AppUser.objects.create_superuser(payload.username, payload.email, payload.password)
else:
user = AppUser.objects.create_user(payload.username, payload.email, payload.password)
return 201, user
@router.patch("/{user_id}", response=UserSchema)
def update_user(request, user_id: int, payload: UserUpdateSchema):
user = get_object_or_404(AppUser, id=user_id)
for attr, value in payload.dict(exclude_unset=True).items():
setattr(user, attr, value)
user.save()
return user