Implemented bulk upload by passing a json structure. Added delete all channels, groups and priorities
All checks were successful
AWS Deploy on Push / build (push) Successful in 2m17s

This commit is contained in:
2025-06-12 18:49:20 -05:00
parent b8ac25e301
commit abb467749b
11 changed files with 630 additions and 11 deletions

View File

@@ -14,6 +14,7 @@ from app.models import (
ChannelURLCreate,
ChannelURLResponse,
Group,
Priority, # Added Priority import
)
from app.models.auth import CognitoUser
from app.models.schemas import ChannelURLUpdate
@@ -149,6 +150,41 @@ def update_channel(
return db_channel
@router.delete("/", status_code=status.HTTP_200_OK)
@require_roles("admin")
def delete_channels(
db: Session = Depends(get_db),
user: CognitoUser = Depends(get_current_user),
):
"""Delete all channels"""
count = 0
try:
count = db.query(ChannelDB).count()
# First delete all channels
db.query(ChannelDB).delete()
# Then delete any URLs that are now orphaned (no channel references)
db.query(ChannelURL).filter(
~ChannelURL.channel_id.in_(db.query(ChannelDB.id))
).delete(synchronize_session=False)
# Then delete any groups that are now empty
db.query(Group).filter(~Group.id.in_(db.query(ChannelDB.group_id))).delete(
synchronize_session=False
)
db.commit()
except Exception as e:
print(f"Error deleting channels: {e}")
db.rollback()
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail="Failed to delete channels",
)
return {"deleted": count}
@router.delete("/{channel_id}", status_code=status.HTTP_204_NO_CONTENT)
@require_roles("admin")
def delete_channel(
@@ -241,6 +277,130 @@ def update_channel_group(
return channel
# Bulk Upload and Reset Endpoints
@router.post("/bulk-upload", status_code=status.HTTP_200_OK)
@require_roles("admin")
def bulk_upload_channels(
channels: list[dict],
db: Session = Depends(get_db),
user: CognitoUser = Depends(get_current_user),
):
"""Bulk upload channels from JSON array"""
processed = 0
# Fetch all priorities from the database, ordered by id
priorities = db.query(Priority).order_by(Priority.id).all()
priority_map = {i: p.id for i, p in enumerate(priorities)}
# Get the highest priority_id (which corresponds to the lowest priority level)
max_priority_id = None
if priorities:
max_priority_id = db.query(Priority.id).order_by(Priority.id.desc()).first()[0]
for channel_data in channels:
try:
# Get or create group
group_name = channel_data.get("group-title")
if not group_name:
continue
group = db.query(Group).filter(Group.name == group_name).first()
if not group:
group = Group(name=group_name)
db.add(group)
db.flush() # Use flush to make the group available in the session
db.refresh(group)
# Prepare channel data
urls = channel_data.get("urls", [])
if not isinstance(urls, list):
urls = [urls]
# Assign priorities dynamically based on fetched priorities
url_objects = []
for i, url in enumerate(urls): # Process all URLs
priority_id = priority_map.get(i)
if priority_id is None:
# If index is out of bounds,
# assign the highest priority_id (lowest priority)
if max_priority_id is not None:
priority_id = max_priority_id
else:
print(
f"Warning: No priorities defined in database. "
f"Skipping URL {url}"
)
continue
url_objects.append({"url": url, "priority_id": priority_id})
# Create channel object with required fields
channel_obj = ChannelDB(
tvg_id=channel_data.get("tvg-id", ""),
name=channel_data.get("name", ""),
group_id=group.id,
tvg_name=channel_data.get("tvg-name", ""),
tvg_logo=channel_data.get("tvg-logo", ""),
)
# Upsert channel
existing_channel = (
db.query(ChannelDB)
.filter(
and_(
ChannelDB.group_id == group.id,
ChannelDB.name == channel_obj.name,
)
)
.first()
)
if existing_channel:
# Update existing
existing_channel.tvg_id = channel_obj.tvg_id
existing_channel.tvg_name = channel_obj.tvg_name
existing_channel.tvg_logo = channel_obj.tvg_logo
# Clear and recreate URLs
db.query(ChannelURL).filter(
ChannelURL.channel_id == existing_channel.id
).delete()
for url in url_objects:
db_url = ChannelURL(
channel_id=existing_channel.id,
url=url["url"],
priority_id=url["priority_id"],
in_use=False,
)
db.add(db_url)
else:
# Create new
db.add(channel_obj)
db.flush() # Flush to get the new channel's ID
db.refresh(channel_obj)
# Add URLs for new channel
for url in url_objects:
db_url = ChannelURL(
channel_id=channel_obj.id,
url=url["url"],
priority_id=url["priority_id"],
in_use=False,
)
db.add(db_url)
db.commit() # Commit all changes for this channel atomically
processed += 1
except Exception as e:
print(f"Error processing channel: {channel_data.get('name', 'Unknown')}")
print(f"Exception details: {e}")
db.rollback() # Rollback the entire transaction for the failed channel
continue
return {"processed": processed}
# URL Management Endpoints
@router.post(
"/{channel_id}/urls",

View File

@@ -86,6 +86,28 @@ def update_group(
return db_group
@router.delete("/", status_code=status.HTTP_200_OK)
@require_roles("admin")
def delete_groups(
db: Session = Depends(get_db),
user: CognitoUser = Depends(get_current_user),
):
"""Delete all groups that have no channels (skip groups with channels)"""
groups = db.query(Group).all()
deleted = 0
skipped = 0
for group in groups:
if not group.channels:
db.delete(group)
deleted += 1
else:
skipped += 1
db.commit()
return {"deleted": deleted, "skipped": skipped}
@router.delete("/{group_id}", status_code=status.HTTP_204_NO_CONTENT)
@require_roles("admin")
def delete_group(

View File

@@ -59,6 +59,34 @@ def get_priority(
return priority
@router.delete("/", status_code=status.HTTP_200_OK)
@require_roles("admin")
def delete_priorities(
db: Session = Depends(get_db),
user: CognitoUser = Depends(get_current_user),
):
"""Delete all priorities not in use by channel URLs"""
from app.models.db import ChannelURL
priorities = db.query(Priority).all()
deleted = 0
skipped = 0
for priority in priorities:
in_use = db.scalar(
select(ChannelURL).where(ChannelURL.priority_id == priority.id).limit(1)
)
if not in_use:
db.delete(priority)
deleted += 1
else:
skipped += 1
db.commit()
return {"deleted": deleted, "skipped": skipped}
@router.delete("/{priority_id}", status_code=status.HTTP_204_NO_CONTENT)
@require_roles("admin")
def delete_priority(