Add auto-created tracking to Channel model and related serializers

- Introduced `auto_created` and `auto_created_by` fields in the Channel model to track channels created via M3U auto channel sync.
- Updated ChannelSerializer to include these new fields and added a method to retrieve the name of the M3U account that created the channel.
- Modified sync_auto_channels task to set these fields when creating channels and to filter existing channels accordingly.
This commit is contained in:
SergeantPanda 2025-07-13 16:32:52 -05:00
parent ea81cfb1af
commit b91a2286e4
4 changed files with 62 additions and 13 deletions

View file

@ -0,0 +1,25 @@
# Generated by Django 5.1.6 on 2025-01-XX XX:XX
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('dispatcharr_channels', '0022_channelgroupm3uaccount_auto_channel_sync_and_more'),
('m3u', '0003_create_custom_account'),
]
operations = [
migrations.AddField(
model_name='channel',
name='auto_created',
field=models.BooleanField(default=False, help_text='Whether this channel was automatically created via M3U auto channel sync'),
),
migrations.AddField(
model_name='channel',
name='auto_created_by',
field=models.ForeignKey(blank=True, help_text='The M3U account that auto-created this channel', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='auto_created_channels', to='m3u.m3uaccount'),
),
]

View file

@ -277,6 +277,19 @@ class Channel(models.Model):
user_level = models.IntegerField(default=0)
auto_created = models.BooleanField(
default=False,
help_text="Whether this channel was automatically created via M3U auto channel sync"
)
auto_created_by = models.ForeignKey(
"m3u.M3UAccount",
on_delete=models.SET_NULL,
null=True,
blank=True,
related_name="auto_created_channels",
help_text="The M3U account that auto-created this channel"
)
def clean(self):
# Enforce unique channel_number within a given group
existing = Channel.objects.filter(

View file

@ -173,6 +173,8 @@ class ChannelSerializer(serializers.ModelSerializer):
required=False,
)
auto_created_by_name = serializers.SerializerMethodField()
class Meta:
model = Channel
fields = [
@ -188,6 +190,9 @@ class ChannelSerializer(serializers.ModelSerializer):
"uuid",
"logo_id",
"user_level",
"auto_created",
"auto_created_by",
"auto_created_by_name",
]
def to_representation(self, instance):
@ -286,6 +291,12 @@ class ChannelSerializer(serializers.ModelSerializer):
return None
return value # PrimaryKeyRelatedField will handle the conversion to object
def get_auto_created_by_name(self, obj):
"""Get the name of the M3U account that auto-created this channel."""
if obj.auto_created_by:
return obj.auto_created_by.name
return None
class ChannelGroupM3UAccountSerializer(serializers.ModelSerializer):
enabled = serializers.BooleanField()

View file

@ -874,10 +874,11 @@ def sync_auto_channels(account_id):
channel_group=channel_group
)
# Get existing channels in this group that were auto-created (we'll track this via a custom property)
# Get existing auto-created channels in this group that were created by this M3U account
existing_auto_channels = Channel.objects.filter(
channel_group=channel_group,
streams__m3u_account=account
auto_created=True,
auto_created_by=account
).distinct()
# Create a mapping of stream hashes to existing channels
@ -909,14 +910,16 @@ def sync_auto_channels(account_id):
# Get tvc_guide_stationid from custom properties if it exists
tvc_guide_stationid = stream_custom_props.get("tvc-guide-stationid")
# Create the channel
# Create the channel with auto-created tracking
channel = Channel.objects.create(
channel_number=current_channel_number,
name=stream.name,
tvg_id=stream.tvg_id,
tvc_guide_stationid=tvc_guide_stationid,
channel_group=channel_group,
user_level=0 # Default user level
user_level=0, # Default user level
auto_created=True, # Mark as auto-created
auto_created_by=account # Track which M3U account created it
)
# Associate the stream with the channel
@ -954,20 +957,17 @@ def sync_auto_channels(account_id):
continue
# Delete channels that no longer have corresponding streams
# Only delete auto-created channels that were created by this M3U account
channels_to_delete = existing_auto_channels.exclude(id__in=channels_to_keep)
for channel in channels_to_delete:
# Only delete if all streams for this channel are from this M3U account
# and this channel group
all_streams_from_account = all(
s.m3u_account_id == account.id and s.channel_group_id == channel_group.id
for s in channel.streams.all()
)
if all_streams_from_account:
logger.debug(f"Deleting auto channel: {channel.channel_number} - {channel.name}")
# Double-check that this is an auto-created channel by this account
if channel.auto_created and channel.auto_created_by_id == account.id:
logger.debug(f"Deleting auto-created channel: {channel.channel_number} - {channel.name}")
channel.delete()
channels_deleted += 1
else:
logger.warning(f"Skipping deletion of non-auto-created channel: {channel.channel_number} - {channel.name}")
logger.info(f"Auto channel sync complete for account {account.name}: {channels_created} created, {channels_deleted} deleted")
return f"Auto sync: {channels_created} channels created, {channels_deleted} deleted"