diff --git a/apps/vod/migrations/0001_initial.py b/apps/vod/migrations/0001_initial.py index 5c4de33d..3777c735 100644 --- a/apps/vod/migrations/0001_initial.py +++ b/apps/vod/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 5.2.4 on 2025-08-08 13:41 +# Generated by Django 5.2.4 on 2025-08-21 14:34 import django.db.models.deletion import uuid @@ -11,7 +11,7 @@ class Migration(migrations.Migration): dependencies = [ ('dispatcharr_channels', '0023_stream_stream_stats_stream_stream_stats_updated_at'), - ('m3u', '0012_alter_m3uaccount_refresh_interval'), + ('m3u', '0016_m3uaccount_priority'), ] operations = [ @@ -25,9 +25,9 @@ class Migration(migrations.Migration): ('year', models.IntegerField(blank=True, null=True)), ('rating', models.CharField(blank=True, max_length=10, null=True)), ('genre', models.CharField(blank=True, max_length=255, null=True)), - ('duration', models.IntegerField(blank=True, help_text='Duration in minutes', null=True)), - ('tmdb_id', models.CharField(blank=True, db_index=True, help_text='TMDB ID for metadata', max_length=50, null=True)), - ('imdb_id', models.CharField(blank=True, db_index=True, help_text='IMDB ID for metadata', max_length=50, null=True)), + ('duration_secs', models.IntegerField(blank=True, help_text='Duration in seconds', null=True)), + ('tmdb_id', models.CharField(blank=True, help_text='TMDB ID for metadata', max_length=50, null=True, unique=True)), + ('imdb_id', models.CharField(blank=True, help_text='IMDB ID for metadata', max_length=50, null=True, unique=True)), ('custom_properties', models.JSONField(blank=True, help_text='Additional metadata and properties for the movie', null=True)), ('created_at', models.DateTimeField(auto_now_add=True)), ('updated_at', models.DateTimeField(auto_now=True)), @@ -37,7 +37,6 @@ class Migration(migrations.Migration): 'verbose_name': 'Movie', 'verbose_name_plural': 'Movies', 'ordering': ['name'], - 'unique_together': {('name', 'year', 'imdb_id'), ('name', 'year', 'tmdb_id')}, }, ), migrations.CreateModel( @@ -50,8 +49,8 @@ class Migration(migrations.Migration): ('year', models.IntegerField(blank=True, null=True)), ('rating', models.CharField(blank=True, max_length=10, null=True)), ('genre', models.CharField(blank=True, max_length=255, null=True)), - ('tmdb_id', models.CharField(blank=True, db_index=True, help_text='TMDB ID for metadata', max_length=50, null=True)), - ('imdb_id', models.CharField(blank=True, db_index=True, help_text='IMDB ID for metadata', max_length=50, null=True)), + ('tmdb_id', models.CharField(blank=True, help_text='TMDB ID for metadata', max_length=50, null=True, unique=True)), + ('imdb_id', models.CharField(blank=True, help_text='IMDB ID for metadata', max_length=50, null=True, unique=True)), ('custom_properties', models.JSONField(blank=True, help_text='Additional metadata and properties for the series', null=True)), ('created_at', models.DateTimeField(auto_now_add=True)), ('updated_at', models.DateTimeField(auto_now=True)), @@ -61,7 +60,6 @@ class Migration(migrations.Migration): 'verbose_name': 'Series', 'verbose_name_plural': 'Series', 'ordering': ['name'], - 'unique_together': {('name', 'year', 'imdb_id'), ('name', 'year', 'tmdb_id')}, }, ), migrations.CreateModel( @@ -73,11 +71,12 @@ class Migration(migrations.Migration): ('description', models.TextField(blank=True, null=True)), ('air_date', models.DateField(blank=True, null=True)), ('rating', models.CharField(blank=True, max_length=10, null=True)), - ('duration', models.IntegerField(blank=True, help_text='Duration in minutes', null=True)), + ('duration_secs', models.IntegerField(blank=True, help_text='Duration in seconds', null=True)), ('season_number', models.IntegerField(blank=True, null=True)), ('episode_number', models.IntegerField(blank=True, null=True)), ('tmdb_id', models.CharField(blank=True, db_index=True, help_text='TMDB ID for metadata', max_length=50, null=True)), ('imdb_id', models.CharField(blank=True, db_index=True, help_text='IMDB ID for metadata', max_length=50, null=True)), + ('custom_properties', models.JSONField(blank=True, help_text='Custom properties for this episode', null=True)), ('created_at', models.DateTimeField(auto_now_add=True)), ('updated_at', models.DateTimeField(auto_now=True)), ('series', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='episodes', to='vod.series')), @@ -86,7 +85,6 @@ class Migration(migrations.Migration): 'verbose_name': 'Episode', 'verbose_name_plural': 'Episodes', 'ordering': ['series__name', 'season_number', 'episode_number'], - 'unique_together': {('series', 'season_number', 'episode_number')}, }, ), migrations.CreateModel( @@ -105,6 +103,43 @@ class Migration(migrations.Migration): 'unique_together': {('name', 'category_type')}, }, ), + migrations.CreateModel( + name='M3USeriesRelation', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('external_series_id', models.CharField(help_text='External series ID from M3U provider', max_length=255)), + ('custom_properties', models.JSONField(blank=True, help_text='Provider-specific data', null=True)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('updated_at', models.DateTimeField(auto_now=True)), + ('last_episode_refresh', models.DateTimeField(blank=True, help_text='Last time episodes were refreshed', null=True)), + ('m3u_account', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='series_relations', to='m3u.m3uaccount')), + ('series', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='m3u_relations', to='vod.series')), + ('category', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='vod.vodcategory')), + ], + options={ + 'verbose_name': 'M3U Series Relation', + 'verbose_name_plural': 'M3U Series Relations', + }, + ), + migrations.CreateModel( + name='M3UMovieRelation', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('stream_id', models.CharField(help_text='External stream ID from M3U provider', max_length=255)), + ('container_extension', models.CharField(blank=True, max_length=10, null=True)), + ('custom_properties', models.JSONField(blank=True, help_text='Provider-specific data like quality, language, etc.', null=True)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('updated_at', models.DateTimeField(auto_now=True)), + ('last_advanced_refresh', models.DateTimeField(blank=True, help_text='Last time advanced data was fetched from provider', null=True)), + ('m3u_account', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='movie_relations', to='m3u.m3uaccount')), + ('movie', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='m3u_relations', to='vod.movie')), + ('category', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='vod.vodcategory')), + ], + options={ + 'verbose_name': 'M3U Movie Relation', + 'verbose_name_plural': 'M3U Movie Relations', + }, + ), migrations.CreateModel( name='M3UEpisodeRelation', fields=[ @@ -123,44 +158,24 @@ class Migration(migrations.Migration): 'unique_together': {('m3u_account', 'stream_id')}, }, ), - migrations.CreateModel( - name='M3USeriesRelation', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('external_series_id', models.CharField(help_text='External series ID from M3U provider', max_length=255)), - ('custom_properties', models.JSONField(blank=True, help_text='Provider-specific data', null=True)), - ('created_at', models.DateTimeField(auto_now_add=True)), - ('updated_at', models.DateTimeField(auto_now=True)), - ('last_episode_refresh', models.DateTimeField(blank=True, help_text='Last time episodes were refreshed', null=True)), - ('m3u_account', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='series_relations', to='m3u.m3uaccount')), - ('series', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='m3u_relations', to='vod.series')), - ('category', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='vod.vodcategory')), - ], - options={ - 'verbose_name': 'M3U Series Relation', - 'verbose_name_plural': 'M3U Series Relations', - 'unique_together': {('m3u_account', 'external_series_id')}, - }, + migrations.AddConstraint( + model_name='movie', + constraint=models.UniqueConstraint(condition=models.Q(('tmdb_id__isnull', True), ('imdb_id__isnull', True)), fields=('name', 'year'), name='unique_movie_name_year_no_external_id'), ), - migrations.CreateModel( - name='M3UMovieRelation', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('url', models.URLField(max_length=2048)), - ('stream_id', models.CharField(help_text='External stream ID from M3U provider', max_length=255)), - ('container_extension', models.CharField(blank=True, max_length=10, null=True)), - ('custom_properties', models.JSONField(blank=True, help_text='Provider-specific data like quality, language, etc.', null=True)), - ('created_at', models.DateTimeField(auto_now_add=True)), - ('updated_at', models.DateTimeField(auto_now=True)), - ('last_advanced_refresh', models.DateTimeField(blank=True, help_text='Last time advanced data was fetched from provider', null=True)), - ('m3u_account', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='movie_relations', to='m3u.m3uaccount')), - ('movie', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='m3u_relations', to='vod.movie')), - ('category', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='vod.vodcategory')), - ], - options={ - 'verbose_name': 'M3U Movie Relation', - 'verbose_name_plural': 'M3U Movie Relations', - 'unique_together': {('m3u_account', 'stream_id')}, - }, + migrations.AddConstraint( + model_name='series', + constraint=models.UniqueConstraint(condition=models.Q(('tmdb_id__isnull', True), ('imdb_id__isnull', True)), fields=('name', 'year'), name='unique_series_name_year_no_external_id'), + ), + migrations.AlterUniqueTogether( + name='episode', + unique_together={('series', 'season_number', 'episode_number')}, + ), + migrations.AlterUniqueTogether( + name='m3useriesrelation', + unique_together={('m3u_account', 'external_series_id')}, + ), + migrations.AlterUniqueTogether( + name='m3umovierelation', + unique_together={('m3u_account', 'stream_id')}, ), ] diff --git a/apps/vod/migrations/0002_episode_custom_properties.py b/apps/vod/migrations/0002_episode_custom_properties.py deleted file mode 100644 index 2035a47e..00000000 --- a/apps/vod/migrations/0002_episode_custom_properties.py +++ /dev/null @@ -1,16 +0,0 @@ -# Generated by Django A.I. on 2025-08-09 -from django.db import migrations, models - -class Migration(migrations.Migration): - - dependencies = [ - ('vod', '0001_initial'), - ] - - operations = [ - migrations.AddField( - model_name='episode', - name='custom_properties', - field=models.JSONField(blank=True, null=True, help_text='Custom properties for this episode'), - ), - ] diff --git a/apps/vod/migrations/0003_duration_secs.py b/apps/vod/migrations/0003_duration_secs.py deleted file mode 100644 index 0a3e81a0..00000000 --- a/apps/vod/migrations/0003_duration_secs.py +++ /dev/null @@ -1,31 +0,0 @@ -# Generated by Django A.I. on 2025-08-09 -from django.db import migrations, models - -class Migration(migrations.Migration): - - dependencies = [ - ('vod', '0002_episode_custom_properties'), - ] - - operations = [ - migrations.RenameField( - model_name='movie', - old_name='duration', - new_name='duration_secs', - ), - migrations.AlterField( - model_name='movie', - name='duration_secs', - field=models.IntegerField(blank=True, null=True, help_text='Duration in seconds'), - ), - migrations.RenameField( - model_name='episode', - old_name='duration', - new_name='duration_secs', - ), - migrations.AlterField( - model_name='episode', - name='duration_secs', - field=models.IntegerField(blank=True, null=True, help_text='Duration in seconds'), - ), - ] diff --git a/apps/vod/migrations/0004_alter_movie_unique_together_and_more.py b/apps/vod/migrations/0004_alter_movie_unique_together_and_more.py deleted file mode 100644 index f06f3886..00000000 --- a/apps/vod/migrations/0004_alter_movie_unique_together_and_more.py +++ /dev/null @@ -1,50 +0,0 @@ -# Generated by Django 5.2.4 on 2025-08-18 22:34 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('dispatcharr_channels', '0023_stream_stream_stats_stream_stream_stats_updated_at'), - ('vod', '0003_duration_secs'), - ] - - operations = [ - migrations.AlterUniqueTogether( - name='movie', - unique_together=set(), - ), - migrations.AlterUniqueTogether( - name='series', - unique_together=set(), - ), - migrations.AlterField( - model_name='movie', - name='imdb_id', - field=models.CharField(blank=True, help_text='IMDB ID for metadata', max_length=50, null=True, unique=True), - ), - migrations.AlterField( - model_name='movie', - name='tmdb_id', - field=models.CharField(blank=True, help_text='TMDB ID for metadata', max_length=50, null=True, unique=True), - ), - migrations.AlterField( - model_name='series', - name='imdb_id', - field=models.CharField(blank=True, help_text='IMDB ID for metadata', max_length=50, null=True, unique=True), - ), - migrations.AlterField( - model_name='series', - name='tmdb_id', - field=models.CharField(blank=True, help_text='TMDB ID for metadata', max_length=50, null=True, unique=True), - ), - migrations.AddConstraint( - model_name='movie', - constraint=models.UniqueConstraint(condition=models.Q(('tmdb_id__isnull', True), ('imdb_id__isnull', True)), fields=('name', 'year'), name='unique_movie_name_year_no_external_id'), - ), - migrations.AddConstraint( - model_name='series', - constraint=models.UniqueConstraint(condition=models.Q(('tmdb_id__isnull', True), ('imdb_id__isnull', True)), fields=('name', 'year'), name='unique_series_name_year_no_external_id'), - ), - ] diff --git a/apps/vod/migrations/0005_remove_m3umovierelation_url.py b/apps/vod/migrations/0005_remove_m3umovierelation_url.py deleted file mode 100644 index bde8e845..00000000 --- a/apps/vod/migrations/0005_remove_m3umovierelation_url.py +++ /dev/null @@ -1,17 +0,0 @@ -# Generated by Django 5.2.4 on 2025-08-19 15:07 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('vod', '0004_alter_movie_unique_together_and_more'), - ] - - operations = [ - migrations.RemoveField( - model_name='m3umovierelation', - name='url', - ), - ]