Skip to content

Commit 5e59167

Browse files
committed
copy old quality profile values into new, rename old vs new quality profile model field names
1 parent 914211c commit 5e59167

11 files changed

+226
-81
lines changed

src/frontend/src/app/settings/settings.component.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ export class SettingsComponent implements OnInit, AfterContentChecked {
5050
'open_subtitles_username': [settings['open_subtitles_username']],
5151
'open_subtitles_password': [settings['open_subtitles_password']],
5252
'open_subtitles_auto': [settings['open_subtitles_auto']],
53+
// TODO - use QualityProfile primary key
5354
'quality_profile_tv': [settings['quality_profile_tv'], Validators.required],
5455
'quality_profile_movies': [settings['quality_profile_movies'], Validators.required],
5556
'allow_hardcoded_subs': [settings['allow_hardcoded_subs'], Validators.required],

src/nefarious/api/serializers.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ class NefariousSettingsSerializer(serializers.ModelSerializer):
3030
websocket_url = serializers.SerializerMethodField()
3131
is_debug = serializers.SerializerMethodField()
3232
host_download_path = serializers.SerializerMethodField()
33+
# TODO - need to handle saving
34+
quality_profile_tv = serializers.SerializerMethodField()
35+
quality_profile_movies = serializers.SerializerMethodField()
3336

3437
def get_websocket_url(self, obj):
3538
return settings.WEBSOCKET_URL
@@ -40,6 +43,12 @@ def get_is_debug(self, obj):
4043
def get_host_download_path(self, obj):
4144
return settings.HOST_DOWNLOAD_PATH
4245

46+
def get_quality_profile_tv(self, obj):
47+
return QualityProfileSerializer(obj.quality_profile_tv).data
48+
49+
def get_quality_profile_movies(self, obj):
50+
return QualityProfileSerializer(obj.quality_profile_movies).data
51+
4352
class Meta:
4453
model = NefariousSettings
4554
fields = '__all__'

src/nefarious/migrations/0079_auto_20240726_1500.py

Lines changed: 0 additions & 30 deletions
This file was deleted.
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# Generated by Django 3.0.2 on 2024-07-28 13:12
2+
3+
import django.core.validators
4+
from django.db import migrations, models
5+
import django.db.models.deletion
6+
7+
8+
class Migration(migrations.Migration):
9+
10+
dependencies = [
11+
('nefarious', '0078_nefarioussettings_jackett_filter_index'),
12+
]
13+
14+
operations = [
15+
migrations.CreateModel(
16+
name='QualityProfile',
17+
fields=[
18+
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
19+
('name', models.CharField(max_length=500, unique=True)),
20+
('quality', models.CharField(choices=[('any', 'any'), ('sd', 'sd'), ('hd-720p', 'hd-720p'), ('hd-720p-1080p', 'hd-720p-1080p'), ('hd-1080p', 'hd-1080p'), ('ultra-hd', 'ultra-hd')], max_length=500)),
21+
('min_size_gb', models.DecimalField(blank=True, decimal_places=2, help_text='minimum size (gb) to download', max_digits=10, null=True, validators=[django.core.validators.MinValueValidator(0)])),
22+
('max_size_gb', models.DecimalField(blank=True, decimal_places=2, help_text='maximum size (gb) to download', max_digits=10, null=True, validators=[django.core.validators.MinValueValidator(0)])),
23+
],
24+
),
25+
migrations.AlterModelOptions(
26+
name='nefarioussettings',
27+
options={'verbose_name_plural': 'Settings'},
28+
),
29+
migrations.AddField(
30+
model_name='nefarioussettings',
31+
name='quality_profile_movies_default',
32+
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='quality_profile_movies_default', to='nefarious.QualityProfile'),
33+
),
34+
migrations.AddField(
35+
model_name='nefarioussettings',
36+
name='quality_profile_tv_default',
37+
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='quality_profile_tv_default', to='nefarious.QualityProfile'),
38+
),
39+
migrations.AddField(
40+
model_name='watchmovie',
41+
name='quality_profile',
42+
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='nefarious.QualityProfile'),
43+
),
44+
migrations.AddField(
45+
model_name='watchtvseasonrequest',
46+
name='quality_profile',
47+
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='nefarious.QualityProfile'),
48+
),
49+
migrations.AddField(
50+
model_name='watchtvshow',
51+
name='quality_profile',
52+
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='nefarious.QualityProfile'),
53+
),
54+
]
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
from django.db import migrations, transaction
2+
from nefarious.quality import PROFILES
3+
4+
5+
def populate_quality_profile(apps, schema_editor):
6+
NefariousSettings = apps.get_model('nefarious', 'NefariousSettings')
7+
QualityProfile = apps.get_model('nefarious', 'QualityProfile')
8+
9+
nefarious_settings = NefariousSettings.objects.get()
10+
11+
# copy values from old field
12+
for profile in PROFILES:
13+
QualityProfile.objects.create(
14+
name=profile,
15+
quality=profile,
16+
)
17+
18+
quality_profile_tv = QualityProfile.objects.filter(quality=nefarious_settings.quality_profile_tv).first()
19+
quality_profile_movies = QualityProfile.objects.filter(quality=nefarious_settings.quality_profile_movies).first()
20+
21+
nefarious_settings.quality_profile_tv_default = quality_profile_tv
22+
nefarious_settings.quality_profile_movies_default = quality_profile_movies
23+
24+
with transaction.atomic():
25+
nefarious_settings.save()
26+
27+
28+
class Migration(migrations.Migration):
29+
30+
dependencies = [
31+
('nefarious', '0079_auto_20240728_1312'),
32+
]
33+
34+
operations = [
35+
migrations.RunPython(populate_quality_profile, reverse_code=lambda a, b: None),
36+
]

src/nefarious/migrations/0080_quality_profiles.py

Lines changed: 0 additions & 29 deletions
This file was deleted.
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Generated by Django 3.0.2 on 2024-07-27 21:07
2+
3+
from django.db import migrations, transaction
4+
5+
6+
def populate_quality_profile_media(apps, schema_editor):
7+
QualityProfile = apps.get_model('nefarious', 'QualityProfile')
8+
WatchMovie = apps.get_model('nefarious', 'WatchMovie')
9+
WatchTVShow = apps.get_model('nefarious', 'WatchTVShow')
10+
WatchTVSeasonRequest = apps.get_model('nefarious', 'WatchTVSeasonRequest')
11+
12+
# copy default quality profile into new field
13+
for model in [WatchMovie, WatchTVShow, WatchTVSeasonRequest]:
14+
for media in model.objects.all():
15+
if media.quality_profile_custom:
16+
# find matching quality profile by the quality & type
17+
quality_profile = QualityProfile.objects.filter(
18+
quality=media.quality_profile_custom,
19+
).first()
20+
# assign quality profile
21+
media.quality_profile = quality_profile
22+
# must save in transaction
23+
with transaction.atomic():
24+
media.save()
25+
26+
27+
class Migration(migrations.Migration):
28+
29+
dependencies = [
30+
('nefarious', '0080_populate_quality_profiles'),
31+
]
32+
33+
operations = [
34+
migrations.RunPython(populate_quality_profile_media, reverse_code=lambda a, b: None),
35+
]
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Generated by Django 3.0.2 on 2024-07-28 14:17
2+
3+
from django.db import migrations
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
dependencies = [
9+
('nefarious', '0081_populate_quality_profile_media'),
10+
]
11+
12+
operations = [
13+
migrations.RemoveField(
14+
model_name='nefarioussettings',
15+
name='quality_profile_movies',
16+
),
17+
migrations.RemoveField(
18+
model_name='nefarioussettings',
19+
name='quality_profile_tv',
20+
),
21+
]
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Generated by Django 3.0.2 on 2024-07-28 14:18
2+
3+
from django.db import migrations
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
dependencies = [
9+
('nefarious', '0082_auto_20240728_1417'),
10+
]
11+
12+
operations = [
13+
migrations.RenameField(
14+
model_name='nefarioussettings',
15+
old_name='quality_profile_movies_default',
16+
new_name='quality_profile_movies',
17+
),
18+
migrations.RenameField(
19+
model_name='nefarioussettings',
20+
old_name='quality_profile_tv_default',
21+
new_name='quality_profile_tv',
22+
),
23+
]
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Generated by Django 3.0.2 on 2024-07-28 17:52
2+
3+
from django.db import migrations
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
dependencies = [
9+
('nefarious', '0083_auto_20240728_1418'),
10+
]
11+
12+
operations = [
13+
migrations.RemoveField(
14+
model_name='watchmovie',
15+
name='quality_profile_custom',
16+
),
17+
migrations.RemoveField(
18+
model_name='watchtvseasonrequest',
19+
name='quality_profile_custom',
20+
),
21+
migrations.RemoveField(
22+
model_name='watchtvshow',
23+
name='quality_profile_custom',
24+
),
25+
]

src/nefarious/models.py

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@
44
from django.conf import settings
55
from jsonfield import JSONField
66
from django.db import models
7+
78
from nefarious import media_category
89
from nefarious import quality
910

10-
1111
PERM_CAN_WATCH_IMMEDIATELY_TV = 'can_immediately_watch_tv'
1212
PERM_CAN_WATCH_IMMEDIATELY_MOVIE = 'can_immediately_watch_movie'
1313

@@ -18,6 +18,18 @@
1818
MEDIA_TYPE_TV_EPISODE = 'TV_EPISODE'
1919

2020

21+
class QualityProfile(models.Model):
22+
name = models.CharField(max_length=500, unique=True)
23+
quality = models.CharField(max_length=500, choices=zip(quality.PROFILE_NAMES, quality.PROFILE_NAMES))
24+
min_size_gb = models.DecimalField(
25+
null=True, blank=True, max_digits=10, decimal_places=2, validators=[MinValueValidator(0)], help_text='minimum size (gb) to download')
26+
max_size_gb = models.DecimalField(
27+
null=True, blank=True, max_digits=10, decimal_places=2, validators=[MinValueValidator(0)], help_text='maximum size (gb) to download')
28+
29+
def __str__(self):
30+
return f'{self.name} ({self.quality})'
31+
32+
2133
class NefariousSettings(models.Model):
2234
JACKETT_TOKEN_DEFAULT = 'COPY_YOUR_JACKETT_TOKEN_HERE'
2335

@@ -51,12 +63,8 @@ class NefariousSettings(models.Model):
5163
open_subtitles_user_token = models.CharField(max_length=500, blank=True, null=True, help_text='OpenSubtitles user auth token') # generated in auth flow
5264
open_subtitles_auto = models.BooleanField(default=False, help_text='Whether to automatically download subtitles')
5365

54-
# TODO - remove after migration to new quality profiles table
55-
quality_profile_tv = models.CharField(max_length=500, default=quality.PROFILE_ANY.name, choices=zip(quality.PROFILE_NAMES, quality.PROFILE_NAMES))
56-
quality_profile_movies = models.CharField(max_length=500, default=quality.PROFILE_HD_720P_1080P.name, choices=zip(quality.PROFILE_NAMES, quality.PROFILE_NAMES))
57-
58-
# TODO - define "default" quality profiles per media-type (tv/movies)
59-
quality_profiles = models.ForeignKey('QualityProfile', on_delete=models.CASCADE, null=True)
66+
quality_profile_tv = models.ForeignKey(QualityProfile, on_delete=models.CASCADE, null=True, related_name='quality_profile_tv_default')
67+
quality_profile_movies = models.ForeignKey(QualityProfile, on_delete=models.CASCADE, null=True, related_name='quality_profile_movies_default')
6068

6169
# whether to allow hardcoded subtitles
6270
allow_hardcoded_subs = models.BooleanField(default=False)
@@ -94,23 +102,14 @@ def get_tmdb_poster_url(self, poster_path):
94102
poster_path.lstrip('/'),
95103
)
96104

97-
def should_save_subtitles(self):
105+
def should_save_subtitles(self) -> bool:
98106
return all([
99107
self.open_subtitles_auto,
100108
self.open_subtitles_user_token,
101109
])
102110

103-
104-
class QualityProfile(models.Model):
105-
name = models.CharField(max_length=500, unique=True)
106-
quality = models.CharField(max_length=500, choices=zip(quality.PROFILE_NAMES, quality.PROFILE_NAMES))
107-
min_size_gb = models.DecimalField(
108-
null=True, blank=True, max_digits=10, decimal_places=2, validators=[MinValueValidator(0)], help_text='minimum size to download')
109-
max_size_gb = models.DecimalField(
110-
null=True, blank=True, max_digits=10, decimal_places=2, validators=[MinValueValidator(0)], help_text='maximum size to download')
111-
112-
def __str__(self):
113-
return self.name
111+
class Meta:
112+
verbose_name_plural = "Settings"
114113

115114

116115
class WatchMediaBase(models.Model):
@@ -144,7 +143,7 @@ class WatchMovie(WatchMediaBase):
144143
tmdb_movie_id = models.IntegerField(unique=True)
145144
name = models.CharField(max_length=255)
146145
poster_image_url = models.CharField(max_length=1000)
147-
quality_profile_custom = models.CharField(max_length=500, null=True, blank=True, choices=zip(quality.PROFILE_NAMES, quality.PROFILE_NAMES))
146+
quality_profile = models.ForeignKey(QualityProfile, on_delete=models.CASCADE, null=True)
148147

149148
class Meta:
150149
ordering = ('name',)
@@ -167,7 +166,8 @@ class WatchTVShow(models.Model):
167166
release_date = models.DateField(null=True, blank=True)
168167
auto_watch = models.BooleanField(default=False) # whether to automatically watch future seasons
169168
auto_watch_date_updated = models.DateField(null=True, blank=True) # date auto watch requested/updated
170-
quality_profile_custom = models.CharField(max_length=500, null=True, blank=True, choices=zip(quality.PROFILE_NAMES, quality.PROFILE_NAMES))
169+
quality_profile = models.ForeignKey(QualityProfile, on_delete=models.CASCADE, null=True)
170+
171171

172172
class Meta:
173173
ordering = ('name',)
@@ -190,7 +190,7 @@ class WatchTVSeasonRequest(models.Model):
190190
user = models.ForeignKey(User, on_delete=models.CASCADE)
191191
watch_tv_show = models.ForeignKey(WatchTVShow, on_delete=models.CASCADE)
192192
season_number = models.IntegerField()
193-
quality_profile_custom = models.CharField(max_length=500, null=True, blank=True, choices=zip(quality.PROFILE_NAMES, quality.PROFILE_NAMES))
193+
quality_profile = models.ForeignKey(QualityProfile, on_delete=models.CASCADE, null=True)
194194
collected = models.BooleanField(default=False)
195195
date_added = models.DateTimeField(auto_now_add=True)
196196
date_updated = models.DateTimeField(auto_now=True)

0 commit comments

Comments
 (0)