diff --git a/src/frontend/src/app/api.service.ts b/src/frontend/src/app/api.service.ts index d9c301a1..2e55bd8e 100644 --- a/src/frontend/src/app/api.service.ts +++ b/src/frontend/src/app/api.service.ts @@ -38,6 +38,7 @@ export class ApiService { API_URL_DISCOVER_RT_MOVIES = '/api/discover/rotten-tomatoes/media/movie/'; API_URL_GENRES_MOVIE = '/api/genres/movie/'; API_URL_GENRES_TV = '/api/genres/tv/'; + API_URL_MEDIA_CATEGORIES = '/api/media-categories/'; API_URL_QUALITY_PROFILES = '/api/quality-profiles/'; API_URL_GIT_COMMIT = '/api/git-commit/'; API_URL_IMPORT_MEDIA_TV = '/api/import/media/tv/'; @@ -55,6 +56,7 @@ export class ApiService { public users: any; // staff-only list of all users public settings: any; public qualityProfiles: string[]; + public mediaCategories: string[]; public watchTVSeasons: any[] = []; public watchTVSeasonRequests: any[] = []; public watchTVEpisodes: any[] = []; @@ -179,6 +181,7 @@ export class ApiService { }) ), this.fetchQualityProfiles(), + this.fetchMediaCategories(), ]).pipe( catchError((error) => { console.error(error); @@ -214,6 +217,19 @@ export class ApiService { ); } + public fetchMediaCategories() { + return this.http.get(this.API_URL_MEDIA_CATEGORIES, {headers: this._requestHeaders()}).pipe( + map((data: any) => { + if (data.mediaCategories) { + this.mediaCategories = data.mediaCategories; + } else { + console.error('no media categories'); + } + return this.mediaCategories; + }), + ); + } + public fetchQualityProfiles() { return this.http.get(this.API_URL_QUALITY_PROFILES, {headers: this._requestHeaders()}).pipe( map((data: any) => { diff --git a/src/frontend/src/app/search/search-input.component.ts b/src/frontend/src/app/search/search-input.component.ts index d705c8dc..5534a462 100644 --- a/src/frontend/src/app/search/search-input.component.ts +++ b/src/frontend/src/app/search/search-input.component.ts @@ -21,7 +21,7 @@ export class SearchInputComponent implements OnInit { } ngOnInit() { - this.type = this.apiService.SEARCH_MEDIA_TYPE_MOVIE; + this.type = this.apiService.settings.preferred_media_category; const queryParams = this.route.snapshot.queryParams; diff --git a/src/frontend/src/app/settings/settings.component.html b/src/frontend/src/app/settings/settings.component.html index bbc4dba5..ce199d96 100644 --- a/src/frontend/src/app/settings/settings.component.html +++ b/src/frontend/src/app/settings/settings.component.html @@ -265,6 +265,18 @@ + +
+
Preferences
+
+
+ + +
+
+
Logs
diff --git a/src/frontend/src/app/settings/settings.component.ts b/src/frontend/src/app/settings/settings.component.ts index 93ddb123..89487fe4 100644 --- a/src/frontend/src/app/settings/settings.component.ts +++ b/src/frontend/src/app/settings/settings.component.ts @@ -57,6 +57,7 @@ export class SettingsComponent implements OnInit, AfterContentChecked { 'language': [settings['language'], Validators.required], 'users': new FormArray([]), 'apprise_notification_url': [settings['apprise_notification_url']], + 'preferred_media_category': [settings['preferred_media_category'], Validators.required], }); this.isLoadingUsers = true; @@ -113,6 +114,10 @@ export class SettingsComponent implements OnInit, AfterContentChecked { return this.apiService.qualityProfiles; } + public mediaCategories(): string[] { + return this.apiService.mediaCategories; + } + public addUser() { this.form.get('users').push(this.fb.group({ username: ['', Validators.required], diff --git a/src/nefarious/api/urls.py b/src/nefarious/api/urls.py index 727bc726..f0f28962 100644 --- a/src/nefarious/api/urls.py +++ b/src/nefarious/api/urls.py @@ -32,6 +32,7 @@ path('discover/rotten-tomatoes/media//', views.DiscoverRottenTomatoesMediaView.as_view()), path('import/media//', views.ImportMediaLibraryView.as_view()), path('genres//', views.GenresView.as_view()), + path('media-categories/', views.MediaCategoriesView.as_view()), path('quality-profiles/', views.QualityProfilesView.as_view()), path('auth/', views.ObtainAuthTokenView.as_view()), # authenticates user and returns token path('git-commit/', views.GitCommitView.as_view()), # returns this app's git commit diff --git a/src/nefarious/api/views.py b/src/nefarious/api/views.py index 7e34529e..b219fe0f 100644 --- a/src/nefarious/api/views.py +++ b/src/nefarious/api/views.py @@ -16,6 +16,7 @@ from nefarious.api.serializers import ( WatchMovieSerializer, WatchTVShowSerializer, WatchTVEpisodeSerializer, WatchTVSeasonRequestSerializer, WatchTVSeasonSerializer, TransmissionTorrentSerializer, RottenTomatoesSearchResultsSerializer, ) +from nefarious.media_category import MEDIA_CATEGORIES from nefarious.models import NefariousSettings, WatchMovie, WatchTVShow, WatchTVEpisode, WatchTVSeasonRequest, WatchTVSeason from nefarious.notification import send_message from nefarious.opensubtitles import OpenSubtitles @@ -507,6 +508,14 @@ def get(self, request): return Response({'profiles': [p.name for p in PROFILES]}) +@method_decorator(gzip_page, name='dispatch') +class MediaCategoriesView(views.APIView): + + def get(self, request): + media_category_keys = [category[0] for category in MEDIA_CATEGORIES] + return Response({'mediaCategories': media_category_keys}) + + class ImportMediaLibraryView(views.APIView): def post(self, request, media_type): diff --git a/src/nefarious/media_category.py b/src/nefarious/media_category.py new file mode 100644 index 00000000..b5cb7baf --- /dev/null +++ b/src/nefarious/media_category.py @@ -0,0 +1,7 @@ + +MEDIA_MOVIE_CATEGORY = "movie" +MEDIA_TV_CATEGORY = "tv" +MEDIA_CATEGORIES = ( + (MEDIA_MOVIE_CATEGORY, "Movie"), + (MEDIA_TV_CATEGORY, "TV"), +) diff --git a/src/nefarious/migrations/0074_add_preferred_media_category.py b/src/nefarious/migrations/0074_add_preferred_media_category.py new file mode 100644 index 00000000..71d856ae --- /dev/null +++ b/src/nefarious/migrations/0074_add_preferred_media_category.py @@ -0,0 +1,18 @@ +# Generated by Django 3.0.2 on 2023-11-29 21:40 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('nefarious', '0073_disable_video_detection'), + ] + + operations = [ + migrations.AddField( + model_name='nefarioussettings', + name='preferred_media_category', + field=models.CharField(choices=[('movie', 'Movie'), ('tv', 'TV')], default='movie', max_length=10), + ), + ] diff --git a/src/nefarious/models.py b/src/nefarious/models.py index 73136fca..69a1cc8f 100644 --- a/src/nefarious/models.py +++ b/src/nefarious/models.py @@ -3,6 +3,7 @@ from django.conf import settings from jsonfield import JSONField from django.db import models +from nefarious import media_category from nefarious import quality PERM_CAN_WATCH_IMMEDIATELY_TV = 'can_immediately_watch_tv' @@ -60,6 +61,13 @@ class NefariousSettings(models.Model): # apprise notifications - https://github.com/caronc/apprise apprise_notification_url = models.CharField(max_length=1000, blank=True) + # category of media the user prefers: movie or tv... + preferred_media_category = models.CharField( + max_length=10, + default=media_category.MEDIA_MOVIE_CATEGORY, + choices=media_category.MEDIA_CATEGORIES, + ) + @classmethod def get(cls): if cls.objects.all().count() > 1: