diff --git a/CHANGELOG.md b/CHANGELOG.md index f83641e45..5f2948060 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,17 +1,115 @@ # Changelog - -## v3.0.4119 (2019-1-09) +## v3.0.4256 (2019-02-18) ### **New Features** -- Added a new Custom Page, this will allow you to completely change the page via a WYSIWYG editor! [TidusJar] +- Update discord link to follow the scheme of other links. [Tom McClellan] -- Added the ability to search movies via the movie db with a different language! [tidusjar] +- Update issue templates. [Jamie] -- Added the ability to specify a year when searching for movies. [tidusjar] +- Update README.md. [Jamie] -- Made the newsletter use the default lanuage code set in the Ombi settings for movie information. [TidusJar] +- Update CHANGELOG.md. [Jamie] + +- Added the functionality to remove a user from getting notifications to their mobile device #2780. [tidusjar] + +- Added a demo mode, this will only show movies and shows that are in the public domain. Dam that stupid fruit company. [tidusjar] + +- Added Actor Searching for Movies! [TidusJar] + +- Added the ability to change where the View on Emby link goes to #2730. [TidusJar] + +- Added the request queue to the notifications UI so you can turn it off per notification agent #2747. [TidusJar] + +- Added new classes to the posters #2732. [TidusJar] + +### **Fixes** + +- Fix: src/Ombi/package.json to reduce vulnerabilities. [snyk-bot] + +- Fixed #2801 this is when a season is not correctly monitored in sonarr when approved by an admin. [tidusjar] + +- Small improvements to try and mitigate #2750. [tidusjar] + +- Removed some areas where we clear out the cache. This should help with DB locking #2750. [tidusjar] + +- Fixed #2810. [tidusjar] + +- Cannot create an issue comment with the API #2811. [tidusjar] + +- Set the local domain if the Application URL is set for the HELO or EHLO commands. #2636. [tidusjar] + +- New translations en.json (Spanish) [Jamie] + +- Delete ISSUE_TEMPLATE.md. [Jamie] + +- More minor grammatical edits. [Andrew Metzger] + +- Minor grammatical edits. [Andrew Metzger] + +- Fixed #2802 the issue where "Issues" were not being deleted correctly. [tidusjar] + +- Fixed #2797. [tidusjar] + +- New translations en.json (Dutch) [Jamie] + +- New translations en.json (Spanish) [Jamie] + +- New translations en.json (Portuguese, Brazilian) [Jamie] + +- Fixed #2786. [tidusjar] + +- Fixed #2756. [tidusjar] + +- Ignore the UserName header as part of the Api is the value is an empty string. [tidusjar] + +- Fixed #2759. [tidusjar] + +- Did #2756. [TidusJar] + +- Fixed the exception that sometimes makes ombi fallover. [TidusJar] + +- New translations en.json (Swedish) [Jamie] + +- New translations en.json (Swedish) [Jamie] + +- New translations en.json (Swedish) [Jamie] + +- New translations en.json (Swedish) [Jamie] + +- New translations en.json (Swedish) [Jamie] + +- New translations en.json (Swedish) [Jamie] + +- New translations en.json (Swedish) [Jamie] + +- New translations en.json (Swedish) [Jamie] + +- New translations en.json (Swedish) [Jamie] + +- New translations en.json (Swedish) [Jamie] + +- Log the error to the ui to figure out what's going on with #2755. [tidusjar] + +- Small fix when denying a request with a reason, we wasn't updating the ui. [TidusJar] + +- Make sure we can only set the ApiAlias when using the API Key. [tidusjar] + +- #2363 Added the ability to pass any username into the API using the ApiAlias header. [tidusjar] + +- Removed the Add user to Plex from Ombi. [tidusjar] + + +## v3.0.4119 (2019-01-09) + +### **New Features** + +- Update CHANGELOG.md. [Jamie] + +- Added a page where the admin can write/style/basically do whatever they want with e.g. FAQ for the users #2715 This needs to be enabled in the Customization Settings and then it's all configured on the page. [TidusJar] + +- Updated the AspnetCore.App package to remove the CVE-2019-0564 vulnerability. [TidusJar] - Added a global language flag that now applies to the search by default. [tidusjar] @@ -21,28 +119,114 @@ - Added {AvailableDate} as a Notification Variable, this is the date the request was marked as available. See here: https://github.com/tidusjar/Ombi/wiki/Notification-Template-Variables. [tidusjar] -- Updated the Newsletter template! Better mail client support [d1slact0r] +- Added the ability to search movies via the movie db with a different language! [tidusjar] -- Updated boostrap #2694. [TidusJar] +- Added the ability to specify a year when searching for movies. [tidusjar] -- Added the ability to deny a request with a reason. [TidusJar] +- Update NewsletterTemplate.html. [d1slact0r] -- Updated to .net core 2.2 and included a linux-arm64 build. [aptalca] +- Update NewsletterTemplate.html. [d1slact0r] -- Make the newsletter BCC the users rather than creating a million newsletters (Hopefully will stop SMTP providers from marking as spam). This does mean that the custom user customization in the newsletter will no longer work. [TidusJar] +- Update NewsletterTemplate.html. [d1slact0r] + +- Update HtmlTemplateGenerator.cs. [d1slact0r] + +- Update NewsletterTemplate.html. [d1slact0r] + +- Update HtmlTemplateGenerator.cs. [d1slact0r] + +- Update NewsletterTemplate.html. [d1slact0r] + +- Update NewsletterTemplate.html. [d1slact0r] + +- Update NewsletterTemplate.html. [d1slact0r] + +- Update HtmlTemplateGenerator.cs. [d1slact0r] + +- Updated boostrap #2694. [Jamie] + +- Added the ability to deny a request with a reason. [TidusJar] + +- Update EmbyEpisodeSync.cs. [Jamie] -- New translations [TidusJar] +- Updated to .net core 2.2 and included a linux-arm64 build. [TidusJar] ### **Fixes** +- There is now a new Job in ombi that will clear out the Plex/Emby data and recache. This will prevent the issues going forward that we have when Ombi and the Media server fall out of sync with deletions/updates #2641 #2362 #1566. [TidusJar] + +- Potentially fix #2726. [TidusJar] + +- New translations en.json (Spanish) [Jamie] + +- New translations en.json (Spanish) [Jamie] + +- New translations en.json (Dutch) [Jamie] + +- Fixed #2725 and #2721. [TidusJar] + +- Made the newsletter use the default lanuage code set in the Ombi settings for movie information. [TidusJar] + +- Save the language code against the request so we can use it later e.g. Sending to the DVR apps. [tidusjar] + - Fixed #2716. [tidusjar] +- Make the newsletter BCC the users rather than creating a million newsletters (Hopefully will stop SMTP providers from marking as spam). This does mean that the custom user customization in the newsletter will no longer work. [TidusJar] + - If we don't know the Plex agent, then see if it's a ImdbId, if it's not check the string for any episode and season hints #2695. [tidusjar] +- New translations en.json (Swedish) [Jamie] + +- New translations en.json (Spanish) [Jamie] + +- New translations en.json (Portuguese, Brazilian) [Jamie] + +- New translations en.json (Polish) [Jamie] + +- New translations en.json (Norwegian) [Jamie] + +- New translations en.json (Italian) [Jamie] + +- New translations en.json (German) [Jamie] + +- New translations en.json (French) [Jamie] + +- New translations en.json (Dutch) [Jamie] + +- New translations en.json (Danish) [Jamie] + +- New translations en.json (Dutch) [Jamie] + +- New translations en.json (Dutch) [Jamie] + +- New translations en.json (Dutch) [Jamie] + +- Made the search results the language specified in the search refinement. [tidusjar] + - Fixed #2704. [tidusjar] +- Now it is fixed :) [d1slact0r] + +- Android please be nice now. [d1slact0r] + +- Fixed title bit better. [d1slact0r] + +- Fixed titles. [d1slact0r] + +- This should fix the build for sure (stupid quotes) [d1slact0r] + +- Fixes build. [d1slact0r] + +- Rewritten the whole newsletter template. [d1slact0r] + - Fixed #2697. [tidusjar] +- Add linux-arm runtime identifier. [aptalca] + +- Add back arm packages. [aptalca] + +- Add arm32 package. [aptalca] + - Fixed #2691. [tidusjar] - Fixed linting. [TidusJar] @@ -51,10 +235,13 @@ - Fixed #2678. [TidusJar] +- Deny reason for movie requests. [TidusJar] + - Set the landing and login pages background refresh to 15 seconds rather than 10 and 7. [TidusJar] - Fixed a bug with us thinking future dated emby episodes are not available, Consoldated the emby and plex search rules (since they have the same logic) [TidusJar] +- Fixed build. [TidusJar] ## v3.0.4036 (2018-12-11) diff --git a/README.md b/README.md index 61cda24f3..814bb9bb9 100644 --- a/README.md +++ b/README.md @@ -10,11 +10,19 @@ ____ [![Paypal](https://img.shields.io/badge/paypal-donate-yellow.svg)](https://paypal.me/PlexRequestsNet) ___ -Get it on Google Play -Get it on App Store +[![Twitter](https://img.shields.io/twitter/follow/tidusjar.svg?style=social)](https://twitter.com/intent/follow?screen_name=tidusjar) + +Follow me developing Ombi! + +[![Twitch](https://img.shields.io/badge/Twitch-Watch-blue.svg?style=flat-square&logo=twitch)](https://twitch.tv/tiusjar) +___ +Get it on Google Play +
+_**Note:** There is no longer an iOS app due to complications outside of our control._ + ___ We also now have merch up on Teespring! @@ -34,6 +42,7 @@ Here are some of the features Ombi V3 has: * Now working without crashes on Linux. * Lets users request Movies, Music, and TV Shows (whether it being the entire series, an entire season, or even single episodes.) * Easily manage your requests +* Allows you to set specific users to automatically have requests approved and added to the relevant service (Sonarr/Radarr/Lidarr/Couchpotato etc) * User management system (supports plex.tv, Emby and local accounts) * A landing page that will give you the availability of your Plex/Emby server and also add custom notification text to inform your users of downtime. * Allows your users to get custom notifications! @@ -41,7 +50,7 @@ Here are some of the features Ombi V3 has: * Will show if the request is already on plex or even if it's already monitored. * Automatically updates the status of requests when they are available on Plex/Emby * Slick, responsive and mobile friendly UI -* Ombi will automatically update itself :) +* Ombi will automatically update itself :) (YMMV) * Very fast! ### Integration diff --git a/src/Ombi.Api/Api.cs b/src/Ombi.Api/Api.cs index 19dab7530..e405b6bca 100644 --- a/src/Ombi.Api/Api.cs +++ b/src/Ombi.Api/Api.cs @@ -41,7 +41,7 @@ namespace Ombi.Api { if (!request.IgnoreErrors) { - LogError(request, httpResponseMessage); + await LogError(request, httpResponseMessage); } if (request.Retry) @@ -105,7 +105,7 @@ namespace Ombi.Api { if (!request.IgnoreErrors) { - LogError(request, httpResponseMessage); + await LogError(request, httpResponseMessage); } } // do something with the response @@ -126,7 +126,7 @@ namespace Ombi.Api { if (!request.IgnoreErrors) { - LogError(request, httpResponseMessage); + await LogError(request, httpResponseMessage); } } } @@ -149,10 +149,15 @@ namespace Ombi.Api } } - private void LogError(Request request, HttpResponseMessage httpResponseMessage) + private async Task LogError(Request request, HttpResponseMessage httpResponseMessage) { Logger.LogError(LoggingEvents.Api, $"StatusCode: {httpResponseMessage.StatusCode}, Reason: {httpResponseMessage.ReasonPhrase}, RequestUri: {request.FullUri}"); + if (Logger.IsEnabled(LogLevel.Debug)) + { + var content = await httpResponseMessage.Content.ReadAsStringAsync(); + Logger.LogDebug(content); + } } } } diff --git a/src/Ombi.Core/Engine/Demo/DemoMovieSearchEngine.cs b/src/Ombi.Core/Engine/Demo/DemoMovieSearchEngine.cs new file mode 100644 index 000000000..86582fb4d --- /dev/null +++ b/src/Ombi.Core/Engine/Demo/DemoMovieSearchEngine.cs @@ -0,0 +1,106 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Security.Principal; +using System.Text; +using System.Threading.Tasks; +using AutoMapper; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; +using Ombi.Api.TheMovieDb; +using Ombi.Api.TheMovieDb.Models; +using Ombi.Config; +using Ombi.Core.Authentication; +using Ombi.Core.Models.Requests; +using Ombi.Core.Models.Search; +using Ombi.Core.Rule.Interfaces; +using Ombi.Core.Settings; +using Ombi.Helpers; +using Ombi.Settings.Settings.Models; +using Ombi.Store.Entities; +using Ombi.Store.Repository; + +namespace Ombi.Core.Engine.Demo +{ + public class DemoMovieSearchEngine : MovieSearchEngine, IDemoMovieSearchEngine + { + public DemoMovieSearchEngine(IPrincipal identity, IRequestServiceMain service, IMovieDbApi movApi, IMapper mapper, + ILogger logger, IRuleEvaluator r, OmbiUserManager um, ICacheService mem, ISettingsService s, + IRepository sub, IOptions lists) + : base(identity, service, movApi, mapper, logger, r, um, mem, s, sub) + { + _demoLists = lists.Value; + } + + private readonly DemoLists _demoLists; + + public async Task> Search(string search) + { + var result = await MovieApi.SearchMovie(search, null, "en"); + + for (var i = 0; i < result.Count; i++) + { + if (!_demoLists.Movies.Contains(result[i].Id)) + { + result.RemoveAt(i); + } + } + if(result.Count > 0) + return await TransformMovieResultsToResponse(result.Take(MovieLimit)); // Take x to stop us overloading the API + return null; + } + + public async Task> NowPlayingMovies() + { + var rand = new Random(); + var responses = new List(); + for (int i = 0; i < 10; i++) + { + var item = rand.Next(_demoLists.Movies.Length); + var movie = _demoLists.Movies[item]; + if (responses.Any(x => x.Id == movie)) + { + i--; + continue; + } + var movieResult = await MovieApi.GetMovieInformationWithExtraInfo(movie); + var viewMovie = Mapper.Map(movieResult); + + responses.Add(await ProcessSingleMovie(viewMovie)); + } + + return responses; + } + + public async Task> PopularMovies() + { + return await NowPlayingMovies(); + } + + + public async Task> TopRatedMovies() + { + return await NowPlayingMovies(); + } + + public async Task> UpcomingMovies() + { + + return await NowPlayingMovies(); + } + } + + public interface IDemoMovieSearchEngine + { + Task> NowPlayingMovies(); + + Task> PopularMovies(); + + Task> Search(string search); + + Task> TopRatedMovies(); + + Task> UpcomingMovies(); + + } +} diff --git a/src/Ombi.Core/Engine/Demo/DemoTvSearchEngine.cs b/src/Ombi.Core/Engine/Demo/DemoTvSearchEngine.cs new file mode 100644 index 000000000..edf9c430d --- /dev/null +++ b/src/Ombi.Core/Engine/Demo/DemoTvSearchEngine.cs @@ -0,0 +1,96 @@ +using AutoMapper; +using Microsoft.Extensions.Options; +using Ombi.Api.Trakt; +using Ombi.Api.TvMaze; +using Ombi.Config; +using Ombi.Core.Authentication; +using Ombi.Core.Models.Requests; +using Ombi.Core.Models.Search; +using Ombi.Core.Rule.Interfaces; +using Ombi.Core.Settings; +using Ombi.Core.Settings.Models.External; +using Ombi.Helpers; +using Ombi.Settings.Settings.Models; +using Ombi.Store.Entities; +using Ombi.Store.Repository; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Security.Principal; +using System.Threading.Tasks; + +namespace Ombi.Core.Engine.Demo +{ + public class DemoTvSearchEngine : TvSearchEngine, IDemoTvSearchEngine + { + + public DemoTvSearchEngine(IPrincipal identity, IRequestServiceMain service, ITvMazeApi tvMaze, IMapper mapper, + ISettingsService plexSettings, ISettingsService embySettings, IPlexContentRepository repo, + IEmbyContentRepository embyRepo, ITraktApi trakt, IRuleEvaluator r, OmbiUserManager um, ICacheService memCache, + ISettingsService s, IRepository sub, IOptions lists) + : base(identity, service, tvMaze, mapper, plexSettings, embySettings, repo, embyRepo, trakt, r, um, memCache, s, sub) + { + _demoLists = lists.Value; + } + + private readonly DemoLists _demoLists; + + public async Task> Search(string search) + { + var searchResult = await TvMazeApi.Search(search); + + for (var i = 0; i < searchResult.Count; i++) + { + if (!_demoLists.TvShows.Contains(searchResult[i].show?.externals?.thetvdb ?? 0)) + { + searchResult.RemoveAt(i); + } + } + + if (searchResult != null) + { + var retVal = new List(); + foreach (var tvMazeSearch in searchResult) + { + if (tvMazeSearch.show.externals == null || !(tvMazeSearch.show.externals?.thetvdb.HasValue ?? false)) + { + continue; + } + retVal.Add(ProcessResult(tvMazeSearch)); + } + return retVal; + } + return null; + } + + public async Task> NowPlayingMovies() + { + var rand = new Random(); + var responses = new List(); + for (int i = 0; i < 10; i++) + { + var item = rand.Next(_demoLists.TvShows.Length); + var tv = _demoLists.TvShows[item]; + if (responses.Any(x => x.Id == tv)) + { + i--; + continue; + } + + var movieResult = await TvMazeApi.ShowLookup(tv); + responses.Add(ProcessResult(movieResult)); + } + + return responses; + } + + + + } + + public interface IDemoTvSearchEngine + { + Task> Search(string search); + Task> NowPlayingMovies(); + } +} diff --git a/src/Ombi.Core/Engine/Interfaces/IMovieEngine.cs b/src/Ombi.Core/Engine/Interfaces/IMovieEngine.cs index b80d132d1..9b4cd9831 100644 --- a/src/Ombi.Core/Engine/Interfaces/IMovieEngine.cs +++ b/src/Ombi.Core/Engine/Interfaces/IMovieEngine.cs @@ -19,5 +19,6 @@ namespace Ombi.Core Task LookupImdbInformation(int theMovieDbId, string langCode = null); Task> SimilarMovies(int theMovieDbId, string langCode); + Task> SearchActor(string search, string langaugeCode); } } \ No newline at end of file diff --git a/src/Ombi.Core/Engine/MovieRequestEngine.cs b/src/Ombi.Core/Engine/MovieRequestEngine.cs index b584a4bed..456ba267a 100644 --- a/src/Ombi.Core/Engine/MovieRequestEngine.cs +++ b/src/Ombi.Core/Engine/MovieRequestEngine.cs @@ -83,7 +83,8 @@ namespace Ombi.Core.Engine Approved = false, RequestedUserId = userDetails.Id, Background = movieInfo.BackdropPath, - LangCode = model.LanguageCode + LangCode = model.LanguageCode, + RequestedByAlias = model.RequestedByAlias }; var usDates = movieInfo.ReleaseDates?.Results?.FirstOrDefault(x => x.IsoCode == "US"); @@ -325,6 +326,7 @@ namespace Ombi.Core.Engine return new RequestEngineResult { + Result = true, Message = "Request successfully deleted", }; } diff --git a/src/Ombi.Core/Engine/MovieSearchEngine.cs b/src/Ombi.Core/Engine/MovieSearchEngine.cs index 5e56e8abd..84cb8afcf 100644 --- a/src/Ombi.Core/Engine/MovieSearchEngine.cs +++ b/src/Ombi.Core/Engine/MovieSearchEngine.cs @@ -31,11 +31,11 @@ namespace Ombi.Core.Engine Logger = logger; } - private IMovieDbApi MovieApi { get; } - private IMapper Mapper { get; } + protected IMovieDbApi MovieApi { get; } + protected IMapper Mapper { get; } private ILogger Logger { get; } - private const int MovieLimit = 10; + protected const int MovieLimit = 10; /// /// Lookups the imdb information. @@ -54,8 +54,6 @@ namespace Ombi.Core.Engine /// /// Searches the specified movie. /// - /// The search. - /// public async Task> Search(string search, int? year, string langaugeCode) { langaugeCode = await DefaultLanguageCode(langaugeCode); @@ -68,6 +66,33 @@ namespace Ombi.Core.Engine return null; } + public async Task> SearchActor(string search, string langaugeCode) + { + langaugeCode = await DefaultLanguageCode(langaugeCode); + var people = await MovieApi.SearchByActor(search, langaugeCode); + var person = people?.results?.Count > 0 ? people.results.FirstOrDefault() : null; + + var resultSet = new List(); + if (person == null) + { + return resultSet; + } + + // Get this person movie credits + var credits = await MovieApi.GetActorMovieCredits(person.id, langaugeCode); + // Grab results from both cast and crew, prefer items in cast. we can handle directors like this. + var movieResults = (from role in credits.cast select new { Id = role.id, Title = role.title, ReleaseDate = role.release_date }).ToList(); + movieResults.AddRange((from job in credits.crew select new { Id = job.id, Title = job.title, ReleaseDate = job.release_date }).ToList()); + + movieResults = movieResults.Take(10).ToList(); + foreach (var movieResult in movieResults) + { + resultSet.Add(await LookupImdbInformation(movieResult.Id, langaugeCode)); + } + + return resultSet; + } + /// /// Get similar movies to the id passed in /// @@ -159,7 +184,7 @@ namespace Ombi.Core.Engine return null; } - private async Task> TransformMovieResultsToResponse( + protected async Task> TransformMovieResultsToResponse( IEnumerable movies) { var viewMovies = new List(); @@ -170,24 +195,25 @@ namespace Ombi.Core.Engine return viewMovies; } - private async Task ProcessSingleMovie(SearchMovieViewModel viewMovie, bool lookupExtraInfo = false) + protected async Task ProcessSingleMovie(SearchMovieViewModel viewMovie, bool lookupExtraInfo = false) { - if (lookupExtraInfo) + if (lookupExtraInfo && viewMovie.ImdbId.IsNullOrEmpty()) { var showInfo = await MovieApi.GetMovieInformation(viewMovie.Id); viewMovie.Id = showInfo.Id; // TheMovieDbId viewMovie.ImdbId = showInfo.ImdbId; - var usDates = viewMovie.ReleaseDates?.Results?.FirstOrDefault(x => x.IsoCode == "US"); - viewMovie.DigitalReleaseDate = usDates?.ReleaseDate?.FirstOrDefault(x => x.Type == ReleaseDateType.Digital)?.ReleaseDate; } + var usDates = viewMovie.ReleaseDates?.Results?.FirstOrDefault(x => x.IsoCode == "US"); + viewMovie.DigitalReleaseDate = usDates?.ReleaseDate?.FirstOrDefault(x => x.Type == ReleaseDateType.Digital)?.ReleaseDate; + viewMovie.TheMovieDbId = viewMovie.Id.ToString(); await RunSearchRules(viewMovie); // This requires the rules to be run first to populate the RequestId property await CheckForSubscription(viewMovie); - + return viewMovie; } diff --git a/src/Ombi.Core/Engine/MusicRequestEngine.cs b/src/Ombi.Core/Engine/MusicRequestEngine.cs index 66be18cf6..8457de515 100644 --- a/src/Ombi.Core/Engine/MusicRequestEngine.cs +++ b/src/Ombi.Core/Engine/MusicRequestEngine.cs @@ -83,7 +83,8 @@ namespace Ombi.Core.Engine Title = album.title, Disk = album.images?.FirstOrDefault(x => x.coverType.Equals("disc"))?.url, Cover = album.images?.FirstOrDefault(x => x.coverType.Equals("cover"))?.url, - ForeignArtistId = album?.artist?.foreignArtistId ?? string.Empty + ForeignArtistId = album?.artist?.foreignArtistId ?? string.Empty, + RequestedByAlias = model.RequestedByAlias }; if (requestModel.Cover.IsNullOrEmpty()) { diff --git a/src/Ombi.Core/Engine/TvRequestEngine.cs b/src/Ombi.Core/Engine/TvRequestEngine.cs index ddcc22d7b..58144d3ce 100644 --- a/src/Ombi.Core/Engine/TvRequestEngine.cs +++ b/src/Ombi.Core/Engine/TvRequestEngine.cs @@ -385,6 +385,7 @@ namespace Ombi.Core.Engine foreach (var ep in s.Episodes) { ep.Approved = true; + ep.Requested = true; } } diff --git a/src/Ombi.Core/Engine/TvSearchEngine.cs b/src/Ombi.Core/Engine/TvSearchEngine.cs index c8e958002..3a1fead18 100644 --- a/src/Ombi.Core/Engine/TvSearchEngine.cs +++ b/src/Ombi.Core/Engine/TvSearchEngine.cs @@ -40,8 +40,8 @@ namespace Ombi.Core.Engine EmbyContentRepo = embyRepo; } - private ITvMazeApi TvMazeApi { get; } - private IMapper Mapper { get; } + protected ITvMazeApi TvMazeApi { get; } + protected IMapper Mapper { get; } private ISettingsService PlexSettings { get; } private ISettingsService EmbySettings { get; } private IPlexContentRepository PlexContentRepo { get; } @@ -99,7 +99,7 @@ namespace Ombi.Core.Engine { Url = e.url, Title = e.name, - AirDate = DateTime.Parse(e.airstamp ?? DateTime.MinValue.ToString()), + AirDate = e.airstamp.HasValue() ? DateTime.Parse(e.airstamp) : DateTime.MinValue, EpisodeNumber = e.number, }); @@ -112,7 +112,7 @@ namespace Ombi.Core.Engine { Url = e.url, Title = e.name, - AirDate = DateTime.Parse(e.airstamp ?? DateTime.MinValue.ToString()), + AirDate = e.airstamp.HasValue() ? DateTime.Parse(e.airstamp) : DateTime.MinValue, EpisodeNumber = e.number, }); } @@ -149,7 +149,7 @@ namespace Ombi.Core.Engine return processed; } - private IEnumerable ProcessResults(IEnumerable items) + protected IEnumerable ProcessResults(IEnumerable items) { var retVal = new List(); foreach (var tvMazeSearch in items) @@ -159,7 +159,7 @@ namespace Ombi.Core.Engine return retVal; } - private SearchTvShowViewModel ProcessResult(T tvMazeSearch) + protected SearchTvShowViewModel ProcessResult(T tvMazeSearch) { return Mapper.Map(tvMazeSearch); } diff --git a/src/Ombi.Core/Helpers/TvShowRequestBuilder.cs b/src/Ombi.Core/Helpers/TvShowRequestBuilder.cs index 334284484..56d227ad0 100644 --- a/src/Ombi.Core/Helpers/TvShowRequestBuilder.cs +++ b/src/Ombi.Core/Helpers/TvShowRequestBuilder.cs @@ -72,6 +72,7 @@ namespace Ombi.Core.Helpers SeasonRequests = new List(), Title = ShowInfo.name, ReleaseYear = FirstAir, + RequestedByAlias = model.RequestedByAlias, SeriesType = ShowInfo.genres.Any( s => s.Equals("Anime", StringComparison.InvariantCultureIgnoreCase)) ? SeriesType.Anime : SeriesType.Standard }; diff --git a/src/Ombi.Core/Models/Requests/MovieRequestViewModel.cs b/src/Ombi.Core/Models/Requests/MovieRequestViewModel.cs index 92e221abd..5a79d2982 100644 --- a/src/Ombi.Core/Models/Requests/MovieRequestViewModel.cs +++ b/src/Ombi.Core/Models/Requests/MovieRequestViewModel.cs @@ -24,11 +24,20 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // ************************************************************************/ #endregion + +using Newtonsoft.Json; + namespace Ombi.Core.Models.Requests { public class MovieRequestViewModel { public int TheMovieDbId { get; set; } public string LanguageCode { get; set; } = "en"; + + /// + /// This is only set from a HTTP Header + /// + [JsonIgnore] + public string RequestedByAlias { get; set; } } } \ No newline at end of file diff --git a/src/Ombi.Core/Models/Requests/MusicArtistRequestViewModel.cs b/src/Ombi.Core/Models/Requests/MusicArtistRequestViewModel.cs index 4c3426c9e..cd799406b 100644 --- a/src/Ombi.Core/Models/Requests/MusicArtistRequestViewModel.cs +++ b/src/Ombi.Core/Models/Requests/MusicArtistRequestViewModel.cs @@ -3,5 +3,6 @@ public class MusicAlbumRequestViewModel { public string ForeignAlbumId { get; set; } + public string RequestedByAlias { get; set; } } } \ No newline at end of file diff --git a/src/Ombi.Core/Models/Requests/TvRequestViewModel.cs b/src/Ombi.Core/Models/Requests/TvRequestViewModel.cs index 78f9edd6d..c17925b1b 100644 --- a/src/Ombi.Core/Models/Requests/TvRequestViewModel.cs +++ b/src/Ombi.Core/Models/Requests/TvRequestViewModel.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using Newtonsoft.Json; namespace Ombi.Core.Models.Requests { @@ -9,6 +10,8 @@ namespace Ombi.Core.Models.Requests public bool FirstSeason { get; set; } public int TvDbId { get; set; } public List Seasons { get; set; } = new List(); + [JsonIgnore] + public string RequestedByAlias { get; set; } } public class SeasonsViewModel diff --git a/src/Ombi.Core/Rule/Rules/Search/ExistingRule.cs b/src/Ombi.Core/Rule/Rules/Search/ExistingRule.cs index 965fcdfaf..2d4482ba9 100644 --- a/src/Ombi.Core/Rule/Rules/Search/ExistingRule.cs +++ b/src/Ombi.Core/Rule/Rules/Search/ExistingRule.cs @@ -1,4 +1,5 @@ -using System.Linq; +using System; +using System.Linq; using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; using Ombi.Core.Models.Search; @@ -87,11 +88,11 @@ namespace Ombi.Core.Rule.Rules.Search } } - if (request.SeasonRequests.Any() && request.SeasonRequests.All(x => x.Episodes.All(e => e.Available))) + if (request.SeasonRequests.Any() && request.SeasonRequests.All(x => x.Episodes.All(e => e.Available && e.AirDate > DateTime.MinValue))) { request.FullyAvailable = true; } - if (request.SeasonRequests.Any() && request.SeasonRequests.All(x => x.Episodes.Any(e => e.Available))) + if (request.SeasonRequests.Any() && request.SeasonRequests.All(x => x.Episodes.Any(e => e.Available && e.AirDate > DateTime.MinValue))) { request.PartlyAvailable = true; } diff --git a/src/Ombi.Core/Senders/MovieSender.cs b/src/Ombi.Core/Senders/MovieSender.cs index 9124eb9c9..567df43b5 100644 --- a/src/Ombi.Core/Senders/MovieSender.cs +++ b/src/Ombi.Core/Senders/MovieSender.cs @@ -49,7 +49,6 @@ namespace Ombi.Core.Senders { try { - var cpSettings = await CouchPotatoSettings.GetSettingsAsync(); //var watcherSettings = await WatcherSettings.GetSettingsAsync(); var radarrSettings = await RadarrSettings.GetSettingsAsync(); @@ -76,7 +75,7 @@ namespace Ombi.Core.Senders } catch (Exception e) { - Log.LogError(e, "Error when seing movie to DVR app, added to the request queue"); + Log.LogError(e, "Error when sending movie to DVR app, added to the request queue"); // Check if already in request quee var existingQueue = await _requestQueuRepository.FirstOrDefaultAsync(x => x.RequestId == model.Id); diff --git a/src/Ombi.Core/Senders/TvSender.cs b/src/Ombi.Core/Senders/TvSender.cs index f0784a4ca..9a25ca9c0 100644 --- a/src/Ombi.Core/Senders/TvSender.cs +++ b/src/Ombi.Core/Senders/TvSender.cs @@ -16,6 +16,7 @@ using Ombi.Settings.Settings.Models.External; using Ombi.Store.Entities; using Ombi.Store.Entities.Requests; using Ombi.Store.Repository; +using Remotion.Linq.Parsing.Structure.IntermediateModel; namespace Ombi.Core.Senders { @@ -57,7 +58,7 @@ namespace Ombi.Core.Senders var sonarr = await SonarrSettings.GetSettingsAsync(); if (sonarr.Enabled) { - var result = await SendToSonarr(model); + var result = await SendToSonarr(model, sonarr); if (result != null) { return new SenderResult @@ -109,7 +110,7 @@ namespace Ombi.Core.Senders catch (Exception e) { Logger.LogError(e, "Exception thrown when sending a movie to DVR app, added to the request queue"); - // Check if already in request quee + // Check if already in request queue var existingQueue = await _requestQueueRepository.FirstOrDefaultAsync(x => x.RequestId == model.Id); if (existingQueue != null) { @@ -134,7 +135,7 @@ namespace Ombi.Core.Senders return new SenderResult { Success = false, - Message = "Something wen't wrong!" + Message = "Something went wrong!" }; } @@ -150,13 +151,8 @@ namespace Ombi.Core.Senders /// /// /// - public async Task SendToSonarr(ChildRequests model) + public async Task SendToSonarr(ChildRequests model, SonarrSettings s) { - var s = await SonarrSettings.GetSettingsAsync(); - if (!s.Enabled) - { - return null; - } if (string.IsNullOrEmpty(s.ApiKey)) { return null; @@ -319,10 +315,19 @@ namespace Ombi.Core.Senders foreach (var season in model.SeasonRequests) { - var sonarrSeason = sonarrEpList.Where(x => x.seasonNumber == season.SeasonNumber); - var sonarrEpCount = sonarrSeason.Count(); + var sonarrEpisodeList = sonarrEpList.Where(x => x.seasonNumber == season.SeasonNumber).ToList(); + var sonarrEpCount = sonarrEpisodeList.Count; var ourRequestCount = season.Episodes.Count; + var ourEpisodes = season.Episodes.Select(x => x.EpisodeNumber).ToList(); + var unairedEpisodes = sonarrEpisodeList.Where(x => x.airDateUtc > DateTime.UtcNow).Select(x => x.episodeNumber).ToList(); + + //// Check if we have requested all the latest episodes, if we have then monitor + //// NOTE, not sure if needed since ombi ui displays future episodes anyway... + //ourEpisodes.AddRange(unairedEpisodes); + //var distinctEpisodes = ourEpisodes.Distinct().ToList(); + //var missingEpisodes = Enumerable.Range(distinctEpisodes.Min(), distinctEpisodes.Count).Except(distinctEpisodes); + var existingSeason = result.seasons.FirstOrDefault(x => x.seasonNumber == season.SeasonNumber); if (existingSeason == null) @@ -332,7 +337,7 @@ namespace Ombi.Core.Senders } - if (sonarrEpCount == ourRequestCount) + if (sonarrEpCount == ourRequestCount /*|| !missingEpisodes.Any()*/) { // We have the same amount of requests as all of the episodes in the season. diff --git a/src/Ombi.DependencyInjection/IocExtensions.cs b/src/Ombi.DependencyInjection/IocExtensions.cs index 09dbf4e79..68a363706 100644 --- a/src/Ombi.DependencyInjection/IocExtensions.cs +++ b/src/Ombi.DependencyInjection/IocExtensions.cs @@ -53,6 +53,7 @@ using Ombi.Updater; using PlexContentCacher = Ombi.Schedule.Jobs.Plex; using Ombi.Api.Telegram; using Ombi.Core.Authentication; +using Ombi.Core.Engine.Demo; using Ombi.Core.Processor; using Ombi.Schedule.Jobs.Lidarr; using Ombi.Schedule.Jobs.Plex.Interfaces; @@ -92,6 +93,8 @@ namespace Ombi.DependencyInjection services.AddTransient(); services.AddTransient(); services.AddTransient(); + services.AddTransient(); + services.AddTransient(); } public static void RegisterHttp(this IServiceCollection services) { diff --git a/src/Ombi.Helpers/DemoLists.cs b/src/Ombi.Helpers/DemoLists.cs new file mode 100644 index 000000000..c0d0dd77f --- /dev/null +++ b/src/Ombi.Helpers/DemoLists.cs @@ -0,0 +1,11 @@ +namespace Ombi.Config +{ + public class DemoLists + { + public bool Enabled { get; set; } + public int[] Movies { get; set; } + public int[] TvShows { get; set; } + } + + +} \ No newline at end of file diff --git a/src/Ombi.Helpers/DemoSingleton.cs b/src/Ombi.Helpers/DemoSingleton.cs new file mode 100644 index 000000000..22b6b2f31 --- /dev/null +++ b/src/Ombi.Helpers/DemoSingleton.cs @@ -0,0 +1,13 @@ +namespace Ombi.Helpers +{ + public class DemoSingleton + { + private static DemoSingleton instance; + + private DemoSingleton() { } + + public static DemoSingleton Instance => instance ?? (instance = new DemoSingleton()); + + public bool Demo { get; set; } + } +} \ No newline at end of file diff --git a/src/Ombi.Helpers/EmbyHelper.cs b/src/Ombi.Helpers/EmbyHelper.cs index 567bcfe7e..a9967f21f 100644 --- a/src/Ombi.Helpers/EmbyHelper.cs +++ b/src/Ombi.Helpers/EmbyHelper.cs @@ -7,11 +7,16 @@ namespace Ombi.Helpers { public class EmbyHelper { - public static string GetEmbyMediaUrl(string mediaId) + public static string GetEmbyMediaUrl(string mediaId, string customerServerUrl = null) { - var url = - $"http://app.emby.media/#!/itemdetails.html?id={mediaId}"; - return url; + if (customerServerUrl.HasValue()) + { + return $"{customerServerUrl}#!/itemdetails.html?id={mediaId}"; + } + else + { + return $"https://app.emby.media/#!/itemdetails.html?id={mediaId}"; + } } } } diff --git a/src/Ombi.Helpers/OmbiRoles.cs b/src/Ombi.Helpers/OmbiRoles.cs index e0cfc5398..02a480fdf 100644 --- a/src/Ombi.Helpers/OmbiRoles.cs +++ b/src/Ombi.Helpers/OmbiRoles.cs @@ -15,5 +15,6 @@ public const string Disabled = nameof(Disabled); public const string ReceivesNewsletter = nameof(ReceivesNewsletter); public const string ManageOwnRequests = nameof(ManageOwnRequests); + public const string EditCustomPage = nameof(EditCustomPage); } } \ No newline at end of file diff --git a/src/Ombi.Notifications.Templates/EmailBasicTemplate.cs b/src/Ombi.Notifications.Templates/EmailBasicTemplate.cs index b29122be0..fc80de193 100644 --- a/src/Ombi.Notifications.Templates/EmailBasicTemplate.cs +++ b/src/Ombi.Notifications.Templates/EmailBasicTemplate.cs @@ -13,7 +13,7 @@ namespace Ombi.Notifications.Templates if (string.IsNullOrEmpty(_templateLocation)) { #if DEBUG - _templateLocation = Path.Combine(Directory.GetCurrentDirectory(), "bin", "Debug", "netcoreapp2.0", "Templates", + _templateLocation = Path.Combine(Directory.GetCurrentDirectory(), "bin", "Debug", "netcoreapp2.2", "Templates", "BasicTemplate.html"); #else _templateLocation = Path.Combine(Directory.GetCurrentDirectory(), "Templates","BasicTemplate.html"); diff --git a/src/Ombi.Notifications/Agents/DiscordNotification.cs b/src/Ombi.Notifications/Agents/DiscordNotification.cs index c0671fc90..77580e5e4 100644 --- a/src/Ombi.Notifications/Agents/DiscordNotification.cs +++ b/src/Ombi.Notifications/Agents/DiscordNotification.cs @@ -56,148 +56,42 @@ namespace Ombi.Notifications.Agents protected override async Task NewRequest(NotificationOptions model, DiscordNotificationSettings settings) { - var parsed = await LoadTemplate(NotificationAgent.Discord, NotificationType.NewRequest, model); - if (parsed.Disabled) - { - Logger.LogInformation($"Template {NotificationType.NewRequest} is disabled for {NotificationAgent.Discord}"); - return; - } - var notification = new NotificationMessage - { - Message = parsed.Message, - }; - - notification.Other.Add("image", parsed.Image); - await Send(notification, settings); + await Run(model, settings, NotificationType.NewRequest); } protected override async Task NewIssue(NotificationOptions model, DiscordNotificationSettings settings) { - var parsed = await LoadTemplate(NotificationAgent.Discord, NotificationType.Issue, model); - if (parsed.Disabled) - { - Logger.LogInformation($"Template {NotificationType.Issue} is disabled for {NotificationAgent.Discord}"); - return; - } - var notification = new NotificationMessage - { - Message = parsed.Message, - }; - notification.Other.Add("image", parsed.Image); - await Send(notification, settings); + await Run(model, settings, NotificationType.Issue); } protected override async Task IssueComment(NotificationOptions model, DiscordNotificationSettings settings) { - var parsed = await LoadTemplate(NotificationAgent.Discord, NotificationType.IssueComment, model); - if (parsed.Disabled) - { - Logger.LogInformation($"Template {NotificationType.IssueComment} is disabled for {NotificationAgent.Discord}"); - return; - } - var notification = new NotificationMessage - { - Message = parsed.Message, - }; - notification.Other.Add("image", parsed.Image); - await Send(notification, settings); + await Run(model, settings, NotificationType.IssueComment); } protected override async Task IssueResolved(NotificationOptions model, DiscordNotificationSettings settings) { - var parsed = await LoadTemplate(NotificationAgent.Discord, NotificationType.IssueResolved, model); - if (parsed.Disabled) - { - Logger.LogInformation($"Template {NotificationType.IssueResolved} is disabled for {NotificationAgent.Discord}"); - return; - } - var notification = new NotificationMessage - { - Message = parsed.Message, - }; - notification.Other.Add("image", parsed.Image); - await Send(notification, settings); + await Run(model, settings, NotificationType.IssueResolved); } protected override async Task AddedToRequestQueue(NotificationOptions model, DiscordNotificationSettings settings) { - var user = string.Empty; - var title = string.Empty; - var image = string.Empty; - if (model.RequestType == RequestType.Movie) - { - user = MovieRequest.RequestedUser.UserAlias; - title = MovieRequest.Title; - image = MovieRequest.PosterPath; - } - else if (model.RequestType == RequestType.TvShow) - { - user = TvRequest.RequestedUser.UserAlias; - title = TvRequest.ParentRequest.Title; - image = TvRequest.ParentRequest.PosterPath; - } - else if (model.RequestType == RequestType.Album) - { - user = AlbumRequest.RequestedUser.UserAlias; - title = AlbumRequest.Title; - image = AlbumRequest.Cover; - } - var message = $"Hello! The user '{user}' has requested {title} but it could not be added. This has been added into the requests queue and will keep retrying"; - var notification = new NotificationMessage - { - Message = message - }; - notification.Other.Add("image", image); - await Send(notification, settings); + await Run(model, settings, NotificationType.ItemAddedToFaultQueue); } protected override async Task RequestDeclined(NotificationOptions model, DiscordNotificationSettings settings) { - var parsed = await LoadTemplate(NotificationAgent.Discord, NotificationType.RequestDeclined, model); - if (parsed.Disabled) - { - Logger.LogInformation($"Template {NotificationType.RequestDeclined} is disabled for {NotificationAgent.Discord}"); - return; - } - var notification = new NotificationMessage - { - Message = parsed.Message, - }; - notification.Other.Add("image", parsed.Image); - await Send(notification, settings); + await Run(model, settings, NotificationType.RequestDeclined); } protected override async Task RequestApproved(NotificationOptions model, DiscordNotificationSettings settings) { - var parsed = await LoadTemplate(NotificationAgent.Discord, NotificationType.RequestApproved, model); - if (parsed.Disabled) - { - Logger.LogInformation($"Template {NotificationType.RequestApproved} is disabled for {NotificationAgent.Discord}"); - return; - } - var notification = new NotificationMessage - { - Message = parsed.Message, - }; - - notification.Other.Add("image", parsed.Image); - await Send(notification, settings); + await Run(model, settings, NotificationType.RequestApproved); } protected override async Task AvailableRequest(NotificationOptions model, DiscordNotificationSettings settings) { - var parsed = await LoadTemplate(NotificationAgent.Discord, NotificationType.RequestAvailable, model); - if (parsed.Disabled) - { - Logger.LogInformation($"Template {NotificationType.RequestAvailable} is disabled for {NotificationAgent.Discord}"); - return; - } - var notification = new NotificationMessage - { - Message = parsed.Message, - }; - notification.Other.Add("image", parsed.Image); - await Send(notification, settings); + await Run(model, settings, NotificationType.RequestAvailable); } protected override async Task Send(NotificationMessage model, DiscordNotificationSettings settings) @@ -242,5 +136,21 @@ namespace Ombi.Notifications.Agents }; await Send(notification, settings); } + + private async Task Run(NotificationOptions model, DiscordNotificationSettings settings, NotificationType type) + { + var parsed = await LoadTemplate(NotificationAgent.Discord, type, model); + if (parsed.Disabled) + { + Logger.LogInformation($"Template {type} is disabled for {NotificationAgent.Discord}"); + return; + } + var notification = new NotificationMessage + { + Message = parsed.Message, + }; + notification.Other.Add("image", parsed.Image); + await Send(notification, settings); + } } } diff --git a/src/Ombi.Notifications/Agents/EmailNotification.cs b/src/Ombi.Notifications/Agents/EmailNotification.cs index 9621fed43..a7f9334fb 100644 --- a/src/Ombi.Notifications/Agents/EmailNotification.cs +++ b/src/Ombi.Notifications/Agents/EmailNotification.cs @@ -89,7 +89,6 @@ namespace Ombi.Notifications.Agents } else { - // Send to admin message.To = settings.AdminEmail; } @@ -183,37 +182,21 @@ namespace Ombi.Notifications.Agents protected override async Task AddedToRequestQueue(NotificationOptions model, EmailNotificationSettings settings) { - var email = new EmailBasicTemplate(); - var user = string.Empty; - var title = string.Empty; - var img = string.Empty; - if (model.RequestType == RequestType.Movie) + if (!model.Recipient.HasValue()) { - user = MovieRequest.RequestedUser.UserAlias; - title = MovieRequest.Title; - img = $"https://image.tmdb.org/t/p/w300/{MovieRequest.PosterPath}"; + return; } - else + var message = await LoadTemplate(NotificationType.ItemAddedToFaultQueue, model, settings); + if (message == null) { - user = TvRequest.RequestedUser.UserAlias; - title = TvRequest.ParentRequest.Title; - img = TvRequest.ParentRequest.PosterPath; + return; } - var html = email.LoadTemplate( - $"{Customization.ApplicationName}: A request could not be added.", - $"Hello! The user '{user}' has requested {title} but it could not be added. This has been added into the requests queue and will keep retrying", img, Customization.Logo); - - var message = new NotificationMessage - { - Message = html, - Subject = $"{Customization.ApplicationName}: A request could not be added", - To = settings.AdminEmail, - }; - - var plaintext = $"Hello! The user '{user}' has requested {title} but it could not be added. This has been added into the requests queue and will keep retrying"; + var plaintext = await LoadPlainTextMessage(NotificationType.ItemAddedToFaultQueue, model, settings); message.Other.Add("PlainTextBody", plaintext); + // Issues resolved should be sent to the user + message.To = settings.AdminEmail; await Send(message, settings); } diff --git a/src/Ombi.Notifications/Agents/MattermostNotification.cs b/src/Ombi.Notifications/Agents/MattermostNotification.cs index 62c5505c5..f64a0fe21 100644 --- a/src/Ombi.Notifications/Agents/MattermostNotification.cs +++ b/src/Ombi.Notifications/Agents/MattermostNotification.cs @@ -46,20 +46,7 @@ namespace Ombi.Notifications.Agents protected override async Task NewRequest(NotificationOptions model, MattermostNotificationSettings settings) { - var parsed = await LoadTemplate(NotificationAgent.Mattermost, NotificationType.NewRequest, model); - if (parsed.Disabled) - { - Logger.LogInformation($"Template {NotificationType.NewRequest} is disabled for {NotificationAgent.Mattermost}"); - return; - } - var notification = new NotificationMessage - { - Message = parsed.Message, - }; - - AddOtherInformation(model, notification, parsed); - //notification.Other.Add("overview", model.RequestType == RequestType.Movie ? base.MovieRequest.Overview : TvRequest.); - await Send(notification, settings); + await Run(model, settings, NotificationType.NewRequest); } private void AddOtherInformation(NotificationOptions model, NotificationMessage notification, @@ -71,125 +58,37 @@ namespace Ombi.Notifications.Agents protected override async Task NewIssue(NotificationOptions model, MattermostNotificationSettings settings) { - var parsed = await LoadTemplate(NotificationAgent.Mattermost, NotificationType.Issue, model); - if (parsed.Disabled) - { - Logger.LogInformation($"Template {NotificationType.Issue} is disabled for {NotificationAgent.Mattermost}"); - return; - } - var notification = new NotificationMessage - { - Message = parsed.Message, - }; - AddOtherInformation(model, notification, parsed); - await Send(notification, settings); + await Run(model, settings, NotificationType.Issue); } protected override async Task IssueComment(NotificationOptions model, MattermostNotificationSettings settings) { - var parsed = await LoadTemplate(NotificationAgent.Mattermost, NotificationType.IssueComment, model); - if (parsed.Disabled) - { - Logger.LogInformation($"Template {NotificationType.IssueComment} is disabled for {NotificationAgent.Mattermost}"); - return; - } - var notification = new NotificationMessage - { - Message = parsed.Message, - }; - AddOtherInformation(model, notification, parsed); - await Send(notification, settings); + await Run(model, settings, NotificationType.IssueComment); } protected override async Task IssueResolved(NotificationOptions model, MattermostNotificationSettings settings) { - var parsed = await LoadTemplate(NotificationAgent.Mattermost, NotificationType.IssueResolved, model); - if (parsed.Disabled) - { - Logger.LogInformation($"Template {NotificationType.IssueResolved} is disabled for {NotificationAgent.Mattermost}"); - return; - } - var notification = new NotificationMessage - { - Message = parsed.Message, - }; - AddOtherInformation(model, notification, parsed); - await Send(notification, settings); + await Run(model, settings, NotificationType.IssueResolved); } protected override async Task AddedToRequestQueue(NotificationOptions model, MattermostNotificationSettings settings) { - var user = string.Empty; - var title = string.Empty; - var image = string.Empty; - if (model.RequestType == RequestType.Movie) - { - user = MovieRequest.RequestedUser.UserAlias; - title = MovieRequest.Title; - image = MovieRequest.PosterPath; - } - else - { - user = TvRequest.RequestedUser.UserAlias; - title = TvRequest.ParentRequest.Title; - image = TvRequest.ParentRequest.PosterPath; - } - var message = $"Hello! The user '{user}' has requested {title} but it could not be added. This has been added into the requests queue and will keep retrying"; - var notification = new NotificationMessage - { - Message = message - }; - notification.Other.Add("image", image); - await Send(notification, settings); + await Run(model, settings, NotificationType.ItemAddedToFaultQueue); } protected override async Task RequestDeclined(NotificationOptions model, MattermostNotificationSettings settings) { - var parsed = await LoadTemplate(NotificationAgent.Mattermost, NotificationType.RequestDeclined, model); - if (parsed.Disabled) - { - Logger.LogInformation($"Template {NotificationType.RequestDeclined} is disabled for {NotificationAgent.Mattermost}"); - return; - } - var notification = new NotificationMessage - { - Message = parsed.Message, - }; - AddOtherInformation(model, notification, parsed); - await Send(notification, settings); + await Run(model, settings, NotificationType.RequestDeclined); } protected override async Task RequestApproved(NotificationOptions model, MattermostNotificationSettings settings) { - var parsed = await LoadTemplate(NotificationAgent.Mattermost, NotificationType.RequestApproved, model); - if (parsed.Disabled) - { - Logger.LogInformation($"Template {NotificationType.RequestApproved} is disabled for {NotificationAgent.Mattermost}"); - return; - } - var notification = new NotificationMessage - { - Message = parsed.Message, - }; - - AddOtherInformation(model, notification, parsed); - await Send(notification, settings); + await Run(model, settings, NotificationType.RequestApproved); } protected override async Task AvailableRequest(NotificationOptions model, MattermostNotificationSettings settings) { - var parsed = await LoadTemplate(NotificationAgent.Mattermost, NotificationType.RequestAvailable, model); - if (parsed.Disabled) - { - Logger.LogInformation($"Template {NotificationType.RequestAvailable} is disabled for {NotificationAgent.Mattermost}"); - return; - } - var notification = new NotificationMessage - { - Message = parsed.Message, - }; - AddOtherInformation(model, notification, parsed); - await Send(notification, settings); + await Run(model, settings, NotificationType.RequestAvailable); } protected override async Task Send(NotificationMessage model, MattermostNotificationSettings settings) @@ -228,5 +127,21 @@ namespace Ombi.Notifications.Agents }; await Send(notification, settings); } + + private async Task Run(NotificationOptions model, MattermostNotificationSettings settings, NotificationType type) + { + var parsed = await LoadTemplate(NotificationAgent.Mattermost, type, model); + if (parsed.Disabled) + { + Logger.LogInformation($"Template {type} is disabled for {NotificationAgent.Mattermost}"); + return; + } + var notification = new NotificationMessage + { + Message = parsed.Message, + }; + AddOtherInformation(model, notification, parsed); + await Send(notification, settings); + } } } diff --git a/src/Ombi.Notifications/Agents/MobileNotification.cs b/src/Ombi.Notifications/Agents/MobileNotification.cs index de904ecfd..4e3e55fc4 100644 --- a/src/Ombi.Notifications/Agents/MobileNotification.cs +++ b/src/Ombi.Notifications/Agents/MobileNotification.cs @@ -130,23 +130,18 @@ namespace Ombi.Notifications.Agents protected override async Task AddedToRequestQueue(NotificationOptions model, MobileNotificationSettings settings) { - string user; - string title; - if (model.RequestType == RequestType.Movie) - { - user = MovieRequest.RequestedUser.UserAlias; - title = MovieRequest.Title; - } - else + + var parsed = await LoadTemplate(NotificationAgent.Mobile, NotificationType.ItemAddedToFaultQueue, model); + if (parsed.Disabled) { - user = TvRequest.RequestedUser.UserAlias; - title = TvRequest.ParentRequest.Title; + _logger.LogInformation($"Template {NotificationType.ItemAddedToFaultQueue} is disabled for {NotificationAgent.Mobile}"); + return; } - var message = $"Hello! The user '{user}' has requested {title} but it could not be added. This has been added into the requests queue and will keep retrying"; var notification = new NotificationMessage { - Message = message + Message = parsed.Message, }; + // Get admin devices var playerIds = await GetAdmins(NotificationType.Test); await Send(playerIds, notification, settings, model); @@ -294,6 +289,5 @@ namespace Ombi.Notifications.Agents } } } - } } \ No newline at end of file diff --git a/src/Ombi.Notifications/Agents/PushbulletNotification.cs b/src/Ombi.Notifications/Agents/PushbulletNotification.cs index 8440ad319..91a8120b2 100644 --- a/src/Ombi.Notifications/Agents/PushbulletNotification.cs +++ b/src/Ombi.Notifications/Agents/PushbulletNotification.cs @@ -44,131 +44,43 @@ namespace Ombi.Notifications.Agents protected override async Task NewRequest(NotificationOptions model, PushbulletSettings settings) { - var parsed = await LoadTemplate(NotificationAgent.Pushbullet, NotificationType.NewRequest, model); - if (parsed.Disabled) - { - Logger.LogInformation($"Template {NotificationType.NewRequest} is disabled for {NotificationAgent.Pushbullet}"); - return; - } - var notification = new NotificationMessage - { - Message = parsed.Message, - }; - - await Send(notification, settings); + await Run(model, settings, NotificationType.NewRequest); } + protected override async Task NewIssue(NotificationOptions model, PushbulletSettings settings) { - var parsed = await LoadTemplate(NotificationAgent.Pushbullet, NotificationType.Issue, model); - if (parsed.Disabled) - { - Logger.LogInformation($"Template {NotificationType.Issue} is disabled for {NotificationAgent.Pushbullet}"); - return; - } - var notification = new NotificationMessage - { - Message = parsed.Message, - }; - await Send(notification, settings); + await Run(model, settings, NotificationType.Issue); } protected override async Task IssueComment(NotificationOptions model, PushbulletSettings settings) { - var parsed = await LoadTemplate(NotificationAgent.Pushbullet, NotificationType.IssueComment, model); - if (parsed.Disabled) - { - Logger.LogInformation($"Template {NotificationType.IssueComment} is disabled for {NotificationAgent.Pushbullet}"); - return; - } - var notification = new NotificationMessage - { - Message = parsed.Message, - }; - await Send(notification, settings); + await Run(model, settings, NotificationType.IssueComment); } protected override async Task IssueResolved(NotificationOptions model, PushbulletSettings settings) { - var parsed = await LoadTemplate(NotificationAgent.Pushbullet, NotificationType.IssueResolved, model); - if (parsed.Disabled) - { - Logger.LogInformation($"Template {NotificationType.IssueResolved} is disabled for {NotificationAgent.Pushbullet}"); - return; - } - var notification = new NotificationMessage - { - Message = parsed.Message, - }; - await Send(notification, settings); + await Run(model, settings, NotificationType.IssueResolved); } protected override async Task AddedToRequestQueue(NotificationOptions model, PushbulletSettings settings) { - string user; - string title; - if (model.RequestType == RequestType.Movie) - { - user = MovieRequest.RequestedUser.UserAlias; - title = MovieRequest.Title; - } - else - { - user = TvRequest.RequestedUser.UserAlias; - title = TvRequest.ParentRequest.Title; - } - var message = $"Hello! The user '{user}' has requested {title} but it could not be added. This has been added into the requests queue and will keep retrying"; - var notification = new NotificationMessage - { - Message = message - }; - await Send(notification, settings); + await Run(model, settings, NotificationType.ItemAddedToFaultQueue); } protected override async Task RequestDeclined(NotificationOptions model, PushbulletSettings settings) { - var parsed = await LoadTemplate(NotificationAgent.Pushbullet, NotificationType.RequestDeclined, model); - if (parsed.Disabled) - { - Logger.LogInformation($"Template {NotificationType.RequestDeclined} is disabled for {NotificationAgent.Pushbullet}"); - return; - } - var notification = new NotificationMessage - { - Message = parsed.Message, - }; - await Send(notification, settings); + await Run(model, settings, NotificationType.RequestDeclined); } protected override async Task RequestApproved(NotificationOptions model, PushbulletSettings settings) { - var parsed = await LoadTemplate(NotificationAgent.Pushbullet, NotificationType.RequestApproved, model); - if (parsed.Disabled) - { - Logger.LogInformation($"Template {NotificationType.RequestApproved} is disabled for {NotificationAgent.Pushbullet}"); - return; - } - var notification = new NotificationMessage - { - Message = parsed.Message, - }; - - await Send(notification, settings); + await Run(model, settings, NotificationType.RequestApproved); } protected override async Task AvailableRequest(NotificationOptions model, PushbulletSettings settings) { - var parsed = await LoadTemplate(NotificationAgent.Pushbullet, NotificationType.RequestAvailable, model); - if (parsed.Disabled) - { - Logger.LogInformation($"Template {NotificationType.RequestAvailable} is disabled for {NotificationAgent.Pushbullet}"); - return; - } - var notification = new NotificationMessage - { - Message = parsed.Message, - }; - await Send(notification, settings); + await Run(model, settings, NotificationType.RequestAvailable); } protected override async Task Send(NotificationMessage model, PushbulletSettings settings) @@ -192,5 +104,22 @@ namespace Ombi.Notifications.Agents }; await Send(notification, settings); } + + private async Task Run(NotificationOptions model, PushbulletSettings settings, NotificationType type) + { + var parsed = await LoadTemplate(NotificationAgent.Pushbullet, type, model); + if (parsed.Disabled) + { + Logger.LogInformation($"Template {type} is disabled for {NotificationAgent.Pushbullet}"); + return; + } + + var notification = new NotificationMessage + { + Message = parsed.Message, + }; + + await Send(notification, settings); + } } } diff --git a/src/Ombi.Notifications/Agents/PushoverNotification.cs b/src/Ombi.Notifications/Agents/PushoverNotification.cs index 0d1675f82..d41e6d911 100644 --- a/src/Ombi.Notifications/Agents/PushoverNotification.cs +++ b/src/Ombi.Notifications/Agents/PushoverNotification.cs @@ -45,132 +45,42 @@ namespace Ombi.Notifications.Agents protected override async Task NewRequest(NotificationOptions model, PushoverSettings settings) { - var parsed = await LoadTemplate(NotificationAgent.Pushover, NotificationType.NewRequest, model); - if (parsed.Disabled) - { - Logger.LogInformation($"Template {NotificationType.NewRequest} is disabled for {NotificationAgent.Pushover}"); - return; - } - var notification = new NotificationMessage - { - Message = parsed.Message, - }; - - await Send(notification, settings); + await Run(model, settings, NotificationType.NewRequest); } protected override async Task NewIssue(NotificationOptions model, PushoverSettings settings) { - var parsed = await LoadTemplate(NotificationAgent.Pushover, NotificationType.Issue, model); - if (parsed.Disabled) - { - Logger.LogInformation($"Template {NotificationType.Issue} is disabled for {NotificationAgent.Pushover}"); - return; - } - var notification = new NotificationMessage - { - Message = parsed.Message, - }; - await Send(notification, settings); + await Run(model, settings, NotificationType.Issue); } protected override async Task IssueComment(NotificationOptions model, PushoverSettings settings) { - var parsed = await LoadTemplate(NotificationAgent.Pushover, NotificationType.IssueComment, model); - if (parsed.Disabled) - { - Logger.LogInformation($"Template {NotificationType.IssueComment} is disabled for {NotificationAgent.Pushover}"); - return; - } - var notification = new NotificationMessage - { - Message = parsed.Message, - }; - await Send(notification, settings); + await Run(model, settings, NotificationType.IssueComment); } protected override async Task IssueResolved(NotificationOptions model, PushoverSettings settings) { - var parsed = await LoadTemplate(NotificationAgent.Pushover, NotificationType.IssueResolved, model); - if (parsed.Disabled) - { - Logger.LogInformation($"Template {NotificationType.IssueResolved} is disabled for {NotificationAgent.Pushover}"); - return; - } - var notification = new NotificationMessage - { - Message = parsed.Message, - }; - await Send(notification, settings); + await Run(model, settings, NotificationType.IssueResolved); } protected override async Task AddedToRequestQueue(NotificationOptions model, PushoverSettings settings) { - string user; - string title; - if (model.RequestType == RequestType.Movie) - { - user = MovieRequest.RequestedUser.UserAlias; - title = MovieRequest.Title; - } - else - { - user = TvRequest.RequestedUser.UserAlias; - title = TvRequest.ParentRequest.Title; - } - var message = $"Hello! The user '{user}' has requested {title} but it could not be added. This has been added into the requests queue and will keep retrying"; - var notification = new NotificationMessage - { - Message = message - }; - await Send(notification, settings); + await Run(model, settings, NotificationType.ItemAddedToFaultQueue); } protected override async Task RequestDeclined(NotificationOptions model, PushoverSettings settings) { - var parsed = await LoadTemplate(NotificationAgent.Pushover, NotificationType.RequestDeclined, model); - if (parsed.Disabled) - { - Logger.LogInformation($"Template {NotificationType.RequestDeclined} is disabled for {NotificationAgent.Pushover}"); - return; - } - var notification = new NotificationMessage - { - Message = parsed.Message, - }; - await Send(notification, settings); + await Run(model, settings, NotificationType.RequestDeclined); } protected override async Task RequestApproved(NotificationOptions model, PushoverSettings settings) { - var parsed = await LoadTemplate(NotificationAgent.Pushover, NotificationType.RequestApproved, model); - if (parsed.Disabled) - { - Logger.LogInformation($"Template {NotificationType.RequestApproved} is disabled for {NotificationAgent.Pushover}"); - return; - } - var notification = new NotificationMessage - { - Message = parsed.Message, - }; - - await Send(notification, settings); + await Run(model, settings, NotificationType.RequestApproved); } protected override async Task AvailableRequest(NotificationOptions model, PushoverSettings settings) { - var parsed = await LoadTemplate(NotificationAgent.Pushover, NotificationType.RequestAvailable, model); - if (parsed.Disabled) - { - Logger.LogInformation($"Template {NotificationType.RequestAvailable} is disabled for {NotificationAgent.Pushover}"); - return; - } - - var notification = new NotificationMessage - { - Message = parsed.Message, - }; - await Send(notification, settings); + await Run(model, settings, NotificationType.RequestAvailable); } protected override async Task Send(NotificationMessage model, PushoverSettings settings) @@ -195,5 +105,21 @@ namespace Ombi.Notifications.Agents }; await Send(notification, settings); } + + private async Task Run(NotificationOptions model, PushoverSettings settings, NotificationType type) + { + var parsed = await LoadTemplate(NotificationAgent.Pushover, type, model); + if (parsed.Disabled) + { + Logger.LogInformation($"Template {type} is disabled for {NotificationAgent.Pushover}"); + return; + } + + var notification = new NotificationMessage + { + Message = parsed.Message, + }; + await Send(notification, settings); + } } } diff --git a/src/Ombi.Notifications/Agents/SlackNotification.cs b/src/Ombi.Notifications/Agents/SlackNotification.cs index fdbd7ba64..58b2da651 100644 --- a/src/Ombi.Notifications/Agents/SlackNotification.cs +++ b/src/Ombi.Notifications/Agents/SlackNotification.cs @@ -54,138 +54,42 @@ namespace Ombi.Notifications.Agents protected override async Task NewRequest(NotificationOptions model, SlackNotificationSettings settings) { - var parsed = await LoadTemplate(NotificationAgent.Slack, NotificationType.NewRequest, model); - if (parsed.Disabled) - { - Logger.LogInformation($"Template {NotificationType.NewRequest} is disabled for {NotificationAgent.Slack}"); - return; - } - var notification = new NotificationMessage - { - Message = parsed.Message, - }; - - notification.Other.Add("image", parsed.Image); - await Send(notification, settings); + await Run(model, settings, NotificationType.NewRequest); } protected override async Task NewIssue(NotificationOptions model, SlackNotificationSettings settings) { - var parsed = await LoadTemplate(NotificationAgent.Slack, NotificationType.Issue, model); - if (parsed.Disabled) - { - Logger.LogInformation($"Template {NotificationType.Issue} is disabled for {NotificationAgent.Slack}"); - return; - } - var notification = new NotificationMessage - { - Message = parsed.Message, - }; - notification.Other.Add("image", parsed.Image); - await Send(notification, settings); + await Run(model, settings, NotificationType.Issue); } protected override async Task IssueComment(NotificationOptions model, SlackNotificationSettings settings) { - var parsed = await LoadTemplate(NotificationAgent.Slack, NotificationType.IssueComment, model); - if (parsed.Disabled) - { - Logger.LogInformation($"Template {NotificationType.IssueComment} is disabled for {NotificationAgent.Slack}"); - return; - } - var notification = new NotificationMessage - { - Message = parsed.Message, - }; - notification.Other.Add("image", parsed.Image); - await Send(notification, settings); + await Run(model, settings, NotificationType.IssueComment); } protected override async Task IssueResolved(NotificationOptions model, SlackNotificationSettings settings) { - var parsed = await LoadTemplate(NotificationAgent.Slack, NotificationType.IssueResolved, model); - if (parsed.Disabled) - { - Logger.LogInformation($"Template {NotificationType.IssueResolved} is disabled for {NotificationAgent.Slack}"); - return; - } - var notification = new NotificationMessage - { - Message = parsed.Message, - }; - notification.Other.Add("image", parsed.Image); - await Send(notification, settings); + await Run(model, settings, NotificationType.IssueResolved); } protected override async Task AddedToRequestQueue(NotificationOptions model, SlackNotificationSettings settings) { - var user = string.Empty; - var title = string.Empty; - if (model.RequestType == RequestType.Movie) - { - user = MovieRequest.RequestedUser.UserAlias; - title = MovieRequest.Title; - } - else - { - user = TvRequest.RequestedUser.UserAlias; - title = TvRequest.ParentRequest.Title; - } - var message = $"Hello! The user '{user}' has requested {title} but it could not be added. This has been added into the requests queue and will keep retrying"; - var notification = new NotificationMessage - { - Message = message - }; - await Send(notification, settings); + await Run(model, settings, NotificationType.ItemAddedToFaultQueue); } protected override async Task RequestDeclined(NotificationOptions model, SlackNotificationSettings settings) { - var parsed = await LoadTemplate(NotificationAgent.Slack, NotificationType.RequestDeclined, model); - if (parsed.Disabled) - { - Logger.LogInformation($"Template {NotificationType.RequestDeclined} is disabled for {NotificationAgent.Slack}"); - return; - } - var notification = new NotificationMessage - { - Message = parsed.Message, - }; - notification.Other.Add("image", parsed.Image); - await Send(notification, settings); + await Run(model, settings, NotificationType.RequestAvailable); } protected override async Task RequestApproved(NotificationOptions model, SlackNotificationSettings settings) { - var parsed = await LoadTemplate(NotificationAgent.Slack, NotificationType.RequestApproved, model); - if (parsed.Disabled) - { - Logger.LogInformation($"Template {NotificationType.RequestApproved} is disabled for {NotificationAgent.Slack}"); - return; - } - var notification = new NotificationMessage - { - Message = parsed.Message, - }; - - notification.Other.Add("image", parsed.Image); - await Send(notification, settings); + await Run(model, settings, NotificationType.RequestApproved); } protected override async Task AvailableRequest(NotificationOptions model, SlackNotificationSettings settings) { - var parsed = await LoadTemplate(NotificationAgent.Slack, NotificationType.RequestAvailable, model); - if (parsed.Disabled) - { - Logger.LogInformation($"Template {NotificationType.RequestAvailable} is disabled for {NotificationAgent.Slack}"); - return; - } - var notification = new NotificationMessage - { - Message = parsed.Message, - }; - notification.Other.Add("image", parsed.Image); - await Send(notification, settings); + await Run(model, settings, NotificationType.RequestAvailable); } protected override async Task Send(NotificationMessage model, SlackNotificationSettings settings) @@ -218,5 +122,21 @@ namespace Ombi.Notifications.Agents }; await Send(notification, settings); } + + private async Task Run(NotificationOptions model, SlackNotificationSettings settings, NotificationType type) + { + var parsed = await LoadTemplate(NotificationAgent.Slack, type, model); + if (parsed.Disabled) + { + Logger.LogInformation($"Template {type} is disabled for {NotificationAgent.Slack}"); + return; + } + var notification = new NotificationMessage + { + Message = parsed.Message, + }; + notification.Other.Add("image", parsed.Image); + await Send(notification, settings); + } } } diff --git a/src/Ombi.Notifications/Agents/TelegramNotification.cs b/src/Ombi.Notifications/Agents/TelegramNotification.cs index 8e4c4e898..3acfc7331 100644 --- a/src/Ombi.Notifications/Agents/TelegramNotification.cs +++ b/src/Ombi.Notifications/Agents/TelegramNotification.cs @@ -41,134 +41,42 @@ namespace Ombi.Notifications.Agents protected override async Task NewRequest(NotificationOptions model, TelegramSettings settings) { - var parsed = await LoadTemplate(NotificationAgent.Telegram, NotificationType.NewRequest, model); - if (parsed.Disabled) - { - Logger.LogInformation($"Template {NotificationType.NewRequest} is disabled for {NotificationAgent.Telegram}"); - return; - } - var notification = new NotificationMessage - { - Message = parsed.Message, - }; - - await Send(notification, settings); + await Run(model, settings, NotificationType.NewRequest); } protected override async Task NewIssue(NotificationOptions model, TelegramSettings settings) { - var parsed = await LoadTemplate(NotificationAgent.Telegram, NotificationType.Issue, model); - if (parsed.Disabled) - { - Logger.LogInformation($"Template {NotificationType.Issue} is disabled for {NotificationAgent.Telegram}"); - return; - } - var notification = new NotificationMessage - { - Message = parsed.Message, - }; - await Send(notification, settings); + await Run(model, settings, NotificationType.Issue); } protected override async Task IssueComment(NotificationOptions model, TelegramSettings settings) { - var parsed = await LoadTemplate(NotificationAgent.Telegram, NotificationType.IssueComment, model); - if (parsed.Disabled) - { - Logger.LogInformation($"Template {NotificationType.IssueComment} is disabled for {NotificationAgent.Telegram}"); - return; - } - var notification = new NotificationMessage - { - Message = parsed.Message, - }; - await Send(notification, settings); + await Run(model, settings, NotificationType.IssueComment); } protected override async Task IssueResolved(NotificationOptions model, TelegramSettings settings) { - var parsed = await LoadTemplate(NotificationAgent.Telegram, NotificationType.IssueResolved, model); - if (parsed.Disabled) - { - Logger.LogInformation($"Template {NotificationType.IssueResolved} is disabled for {NotificationAgent.Telegram}"); - return; - } - var notification = new NotificationMessage - { - Message = parsed.Message, - }; - await Send(notification, settings); + await Run(model, settings, NotificationType.IssueResolved); } protected override async Task AddedToRequestQueue(NotificationOptions model, TelegramSettings settings) { - var user = string.Empty; - var title = string.Empty; - var image = string.Empty; - if (model.RequestType == RequestType.Movie) - { - user = MovieRequest.RequestedUser.UserAlias; - title = MovieRequest.Title; - image = MovieRequest.PosterPath; - } - else - { - user = TvRequest.RequestedUser.UserAlias; - title = TvRequest.ParentRequest.Title; - image = TvRequest.ParentRequest.PosterPath; - } - var message = $"Hello! The user '{user}' has requested {title} but it could not be added. This has been added into the requests queue and will keep retrying"; - var notification = new NotificationMessage - { - Message = message - }; - await Send(notification, settings); + await Run(model, settings, NotificationType.ItemAddedToFaultQueue); } protected override async Task RequestDeclined(NotificationOptions model, TelegramSettings settings) { - var parsed = await LoadTemplate(NotificationAgent.Telegram, NotificationType.RequestDeclined, model); - if (parsed.Disabled) - { - Logger.LogInformation($"Template {NotificationType.RequestDeclined} is disabled for {NotificationAgent.Telegram}"); - return; - } - var notification = new NotificationMessage - { - Message = parsed.Message, - }; - await Send(notification, settings); + await Run(model, settings, NotificationType.RequestDeclined); } protected override async Task RequestApproved(NotificationOptions model, TelegramSettings settings) { - var parsed = await LoadTemplate(NotificationAgent.Telegram, NotificationType.RequestApproved, model); - if (parsed.Disabled) - { - Logger.LogInformation($"Template {NotificationType.RequestApproved} is disabled for {NotificationAgent.Telegram}"); - return; - } - var notification = new NotificationMessage - { - Message = parsed.Message ?? string.Empty, - }; - - await Send(notification, settings); + await Run(model, settings, NotificationType.RequestApproved); } protected override async Task AvailableRequest(NotificationOptions model, TelegramSettings settings) { - var parsed = await LoadTemplate(NotificationAgent.Telegram, NotificationType.RequestAvailable, model); - if (parsed.Disabled) - { - Logger.LogInformation($"Template {NotificationType.RequestAvailable} is disabled for {NotificationAgent.Telegram}"); - return; - } - var notification = new NotificationMessage - { - Message = parsed.Message, - }; - await Send(notification, settings); + await Run(model, settings, NotificationType.RequestAvailable); } protected override async Task Send(NotificationMessage model, TelegramSettings settings) @@ -192,5 +100,20 @@ namespace Ombi.Notifications.Agents }; await Send(notification, settings); } + + private async Task Run(NotificationOptions model, TelegramSettings settings, NotificationType type) + { + var parsed = await LoadTemplate(NotificationAgent.Telegram, type, model); + if (parsed.Disabled) + { + Logger.LogInformation($"Template {type} is disabled for {NotificationAgent.Telegram}"); + return; + } + var notification = new NotificationMessage + { + Message = parsed.Message, + }; + await Send(notification, settings); + } } } diff --git a/src/Ombi.Notifications/BaseNotification.cs b/src/Ombi.Notifications/BaseNotification.cs index 57eafedd9..001f68f45 100644 --- a/src/Ombi.Notifications/BaseNotification.cs +++ b/src/Ombi.Notifications/BaseNotification.cs @@ -26,8 +26,6 @@ namespace Ombi.Notifications MovieRepository = movie; TvRepository = tv; CustomizationSettings = customization; - Settings.ClearCache(); - CustomizationSettings.ClearCache(); RequestSubscription = sub; _log = log; AlbumRepository = album; @@ -55,14 +53,12 @@ namespace Ombi.Notifications public async Task NotifyAsync(NotificationOptions model) { - Settings.ClearCache(); var configuration = await GetConfiguration(); await NotifyAsync(model, configuration); } public async Task NotifyAsync(NotificationOptions model, Settings.Settings.Models.Settings settings) { - Settings.ClearCache(); if (settings == null) await NotifyAsync(model); var notificationSettings = (T)settings; diff --git a/src/Ombi.Notifications/GenericEmailProvider.cs b/src/Ombi.Notifications/GenericEmailProvider.cs index d3f207234..653670ef7 100644 --- a/src/Ombi.Notifications/GenericEmailProvider.cs +++ b/src/Ombi.Notifications/GenericEmailProvider.cs @@ -5,6 +5,7 @@ using MailKit.Net.Smtp; using Microsoft.Extensions.Logging; using MimeKit; using Ombi.Core.Settings; +using Ombi.Helpers; using Ombi.Notifications.Models; using Ombi.Notifications.Templates; using Ombi.Settings.Settings.Models; diff --git a/src/Ombi.Schedule/Jobs/Emby/EmbyContentSync.cs b/src/Ombi.Schedule/Jobs/Emby/EmbyContentSync.cs index 7002eec41..e22c0ca51 100644 --- a/src/Ombi.Schedule/Jobs/Emby/EmbyContentSync.cs +++ b/src/Ombi.Schedule/Jobs/Emby/EmbyContentSync.cs @@ -28,7 +28,6 @@ namespace Ombi.Schedule.Jobs.Emby _repo = repo; _episodeSync = epSync; _metadata = metadata; - _settings.ClearCache(); } private readonly ILogger _logger; @@ -87,7 +86,7 @@ namespace Ombi.Schedule.Jobs.Emby await _api.GetCollection(movie.Id, server.ApiKey, server.AdministratorId, server.FullUri); foreach (var item in movieInfo.Items) { - await ProcessMovies(item, mediaToAdd); + await ProcessMovies(item, mediaToAdd, server); } processed++; @@ -96,7 +95,7 @@ namespace Ombi.Schedule.Jobs.Emby { processed++; // Regular movie - await ProcessMovies(movie, mediaToAdd); + await ProcessMovies(movie, mediaToAdd, server); } } @@ -138,7 +137,7 @@ namespace Ombi.Schedule.Jobs.Emby Title = tvShow.Name, Type = EmbyMediaType.Series, EmbyId = tvShow.Id, - Url = EmbyHelper.GetEmbyMediaUrl(tvShow.Id), + Url = EmbyHelper.GetEmbyMediaUrl(tvShow.Id, server.ServerHostname), AddedAt = DateTime.UtcNow }); } @@ -164,7 +163,7 @@ namespace Ombi.Schedule.Jobs.Emby await _repo.AddRange(mediaToAdd); } - private async Task ProcessMovies(EmbyMovie movieInfo, ICollection content) + private async Task ProcessMovies(EmbyMovie movieInfo, ICollection content, EmbyServers server) { // Check if it exists var existingMovie = await _repo.GetByEmbyId(movieInfo.Id); @@ -179,7 +178,7 @@ namespace Ombi.Schedule.Jobs.Emby Title = movieInfo.Name, Type = EmbyMediaType.Movie, EmbyId = movieInfo.Id, - Url = EmbyHelper.GetEmbyMediaUrl(movieInfo.Id), + Url = EmbyHelper.GetEmbyMediaUrl(movieInfo.Id, server.ServerHostname), AddedAt = DateTime.UtcNow, }); } diff --git a/src/Ombi.Schedule/Jobs/Emby/EmbyEpisodeSync.cs b/src/Ombi.Schedule/Jobs/Emby/EmbyEpisodeSync.cs index 2bb417d3d..962b08cda 100644 --- a/src/Ombi.Schedule/Jobs/Emby/EmbyEpisodeSync.cs +++ b/src/Ombi.Schedule/Jobs/Emby/EmbyEpisodeSync.cs @@ -49,7 +49,6 @@ namespace Ombi.Schedule.Jobs.Emby _settings = s; _repo = repo; _avaliabilityChecker = checker; - _settings.ClearCache(); } private readonly ISettingsService _settings; diff --git a/src/Ombi.Schedule/Jobs/Emby/EmbyUserImporter.cs b/src/Ombi.Schedule/Jobs/Emby/EmbyUserImporter.cs index 2dadd4bd4..280a61ab4 100644 --- a/src/Ombi.Schedule/Jobs/Emby/EmbyUserImporter.cs +++ b/src/Ombi.Schedule/Jobs/Emby/EmbyUserImporter.cs @@ -50,8 +50,6 @@ namespace Ombi.Schedule.Jobs.Emby _log = log; _embySettings = embySettings; _userManagementSettings = ums; - _userManagementSettings.ClearCache(); - _embySettings.ClearCache(); } private readonly IEmbyApi _api; diff --git a/src/Ombi.Schedule/Jobs/Lidarr/LidarrAlbumSync.cs b/src/Ombi.Schedule/Jobs/Lidarr/LidarrAlbumSync.cs index d19fe561a..2a50b5b38 100644 --- a/src/Ombi.Schedule/Jobs/Lidarr/LidarrAlbumSync.cs +++ b/src/Ombi.Schedule/Jobs/Lidarr/LidarrAlbumSync.cs @@ -1,19 +1,16 @@ using System; using System.Collections.Generic; -using System.Threading; using System.Threading.Tasks; using Hangfire; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Internal; using Microsoft.Extensions.Logging; using Ombi.Api.Lidarr; -using Ombi.Api.Radarr; using Ombi.Core.Settings; using Ombi.Helpers; using Ombi.Settings.Settings.Models.External; using Ombi.Store.Context; using Ombi.Store.Entities; -using Serilog; using ILogger = Microsoft.Extensions.Logging.ILogger; namespace Ombi.Schedule.Jobs.Lidarr @@ -29,7 +26,6 @@ namespace Ombi.Schedule.Jobs.Lidarr _ctx = ctx; _job = job; _availability = availability; - _lidarrSettings.ClearCache(); } private readonly ISettingsService _lidarrSettings; diff --git a/src/Ombi.Schedule/Jobs/Lidarr/LidarrArtistSync.cs b/src/Ombi.Schedule/Jobs/Lidarr/LidarrArtistSync.cs index 4117ee44a..e9a64f2a3 100644 --- a/src/Ombi.Schedule/Jobs/Lidarr/LidarrArtistSync.cs +++ b/src/Ombi.Schedule/Jobs/Lidarr/LidarrArtistSync.cs @@ -1,19 +1,16 @@ using System; using System.Collections.Generic; -using System.Threading; using System.Threading.Tasks; using Hangfire; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Internal; using Microsoft.Extensions.Logging; using Ombi.Api.Lidarr; -using Ombi.Api.Radarr; using Ombi.Core.Settings; using Ombi.Helpers; using Ombi.Settings.Settings.Models.External; using Ombi.Store.Context; using Ombi.Store.Entities; -using Serilog; using ILogger = Microsoft.Extensions.Logging.ILogger; namespace Ombi.Schedule.Jobs.Lidarr @@ -29,7 +26,6 @@ namespace Ombi.Schedule.Jobs.Lidarr _ctx = ctx; _job = background; _albumSync = album; - _lidarrSettings.ClearCache(); } private readonly ISettingsService _lidarrSettings; diff --git a/src/Ombi.Schedule/Jobs/Ombi/Interfaces/IssuesPurge.cs b/src/Ombi.Schedule/Jobs/Ombi/Interfaces/IssuesPurge.cs index 92ca31071..5af4b565d 100644 --- a/src/Ombi.Schedule/Jobs/Ombi/Interfaces/IssuesPurge.cs +++ b/src/Ombi.Schedule/Jobs/Ombi/Interfaces/IssuesPurge.cs @@ -28,9 +28,9 @@ namespace Ombi.Schedule.Jobs.Ombi return; } - var now = DateTime.Now.AddDays(-settings.DaysAfterResolvedToDelete).Date; + var deletionDate = DateTime.Now.AddDays(settings.DaysAfterResolvedToDelete).Date; var resolved = _issuesRepository.GetAll().Where(x => x.Status == IssueStatus.Resolved); - var toDelete = resolved.Where(x => x.ResovledDate.HasValue && x.ResovledDate.Value.Date <= now); + var toDelete = resolved.Where(x => x.ResovledDate.HasValue && x.ResovledDate.Value.Date >= deletionDate); foreach (var d in toDelete) { diff --git a/src/Ombi.Schedule/Jobs/Ombi/MediaDatabaseRefresh.cs b/src/Ombi.Schedule/Jobs/Ombi/MediaDatabaseRefresh.cs index baa7fdcae..ed0bf227f 100644 --- a/src/Ombi.Schedule/Jobs/Ombi/MediaDatabaseRefresh.cs +++ b/src/Ombi.Schedule/Jobs/Ombi/MediaDatabaseRefresh.cs @@ -10,28 +10,23 @@ using Ombi.Schedule.Jobs.Emby; using Ombi.Schedule.Jobs.Plex.Interfaces; using Ombi.Store.Repository; -namespace Ombi.Schedule.Jobs.Plex +namespace Ombi.Schedule.Jobs.Ombi { public class MediaDatabaseRefresh : IMediaDatabaseRefresh { - public MediaDatabaseRefresh(ISettingsService s, ILogger log, IPlexApi plexApi, - IPlexContentRepository plexRepo, IPlexContentSync c, IEmbyContentRepository embyRepo, IEmbyContentSync embySync) + public MediaDatabaseRefresh(ISettingsService s, ILogger log, + IPlexContentRepository plexRepo, IEmbyContentRepository embyRepo, IEmbyContentSync embySync) { _settings = s; _log = log; - _api = plexApi; _plexRepo = plexRepo; - _plexContentSync = c; _embyRepo = embyRepo; _embyContentSync = embySync; - _settings.ClearCache(); } private readonly ISettingsService _settings; private readonly ILogger _log; - private readonly IPlexApi _api; private readonly IPlexContentRepository _plexRepo; - private readonly IPlexContentSync _plexContentSync; private readonly IEmbyContentRepository _embyRepo; private readonly IEmbyContentSync _embyContentSync; diff --git a/src/Ombi.Schedule/Jobs/Ombi/NewsletterJob.cs b/src/Ombi.Schedule/Jobs/Ombi/NewsletterJob.cs index ba4bd5c62..6c59f4c0f 100644 --- a/src/Ombi.Schedule/Jobs/Ombi/NewsletterJob.cs +++ b/src/Ombi.Schedule/Jobs/Ombi/NewsletterJob.cs @@ -16,6 +16,7 @@ using Ombi.Api.TheMovieDb; using Ombi.Api.TheMovieDb.Models; using Ombi.Api.TvMaze; using Ombi.Core.Settings; +using Ombi.Core.Settings.Models.External; using Ombi.Helpers; using Ombi.Notifications; using Ombi.Notifications.Models; @@ -36,7 +37,7 @@ namespace Ombi.Schedule.Jobs.Ombi ISettingsService emailSettings, INotificationTemplatesRepository templateRepo, UserManager um, ISettingsService newsletter, ILogger log, ILidarrApi lidarrApi, IRepository albumCache, ISettingsService lidarrSettings, - ISettingsService ombiSettings) + ISettingsService ombiSettings, ISettingsService plexSettings, ISettingsService embySettings) { _plex = plex; _emby = emby; @@ -49,16 +50,13 @@ namespace Ombi.Schedule.Jobs.Ombi _emailSettings = emailSettings; _newsletterSettings = newsletter; _userManager = um; - _emailSettings.ClearCache(); - _customizationSettings.ClearCache(); - _newsletterSettings.ClearCache(); _log = log; _lidarrApi = lidarrApi; _lidarrAlbumRepository = albumCache; _lidarrSettings = lidarrSettings; _ombiSettings = ombiSettings; - _ombiSettings.ClearCache(); - _lidarrSettings.ClearCache(); + _plexSettings = plexSettings; + _embySettings = embySettings; } private readonly IPlexContentRepository _plex; @@ -77,6 +75,8 @@ namespace Ombi.Schedule.Jobs.Ombi private readonly ILidarrApi _lidarrApi; private readonly IRepository _lidarrAlbumRepository; private readonly ISettingsService _lidarrSettings; + private readonly ISettingsService _plexSettings; + private readonly ISettingsService _embySettings; public async Task Start(NewsletterSettings settings, bool test) { @@ -132,6 +132,8 @@ namespace Ombi.Schedule.Jobs.Ombi _log.LogInformation("Plex Episodes to send: {0}", plexEpisodesToSend.Count()); _log.LogInformation("Emby Episodes to send: {0}", embyEpisodesToSend.Count()); + var plexSettings = await _plexSettings.GetSettingsAsync(); + var embySettings = await _embySettings.GetSettingsAsync(); var body = string.Empty; if (test) { @@ -140,11 +142,11 @@ namespace Ombi.Schedule.Jobs.Ombi var plext = _plex.GetAllEpisodes().Include(x => x.Series).OrderByDescending(x => x.Series.AddedAt).Take(10).ToHashSet(); var embyt = _emby.GetAllEpisodes().Include(x => x.Series).OrderByDescending(x => x.AddedAt).Take(10).ToHashSet(); var lidarr = lidarrContent.OrderByDescending(x => x.AddedAt).Take(10).ToHashSet(); - body = await BuildHtml(plexm, embym, plext, embyt, lidarr, settings); + body = await BuildHtml(plexm, embym, plext, embyt, lidarr, settings, embySettings, plexSettings); } else { - body = await BuildHtml(plexContentMoviesToSend, embyContentMoviesToSend, plexEpisodesToSend, embyEpisodesToSend, lidarrContentAlbumsToSend, settings); + body = await BuildHtml(plexContentMoviesToSend, embyContentMoviesToSend, plexEpisodesToSend, embyEpisodesToSend, lidarrContentAlbumsToSend, settings, embySettings, plexSettings); if (body.IsNullOrEmpty()) { return; @@ -333,7 +335,8 @@ namespace Ombi.Schedule.Jobs.Ombi } private async Task BuildHtml(IQueryable plexContentToSend, IQueryable embyContentToSend, - HashSet plexEpisodes, HashSet embyEp, HashSet albums, NewsletterSettings settings) + HashSet plexEpisodes, HashSet embyEp, HashSet albums, NewsletterSettings settings, EmbySettings embySettings, + PlexSettings plexSettings) { var ombiSettings = await _ombiSettings.GetSettingsAsync(); var sb = new StringBuilder(); @@ -349,8 +352,16 @@ namespace Ombi.Schedule.Jobs.Ombi sb.Append(""); sb.Append(""); sb.Append(""); - await ProcessPlexMovies(plexMovies, sb, ombiSettings.DefaultLanguageCode); - await ProcessEmbyMovies(embyMovies, sb, ombiSettings.DefaultLanguageCode); + if (plexSettings.Enable) + { + await ProcessPlexMovies(plexMovies, sb, ombiSettings.DefaultLanguageCode); + } + + if (embySettings.Enable) + { + await ProcessEmbyMovies(embyMovies, sb, ombiSettings.DefaultLanguageCode); + } + sb.Append(""); sb.Append("
"); sb.Append(""); @@ -367,8 +378,16 @@ namespace Ombi.Schedule.Jobs.Ombi sb.Append(""); sb.Append(""); sb.Append(""); - await ProcessPlexTv(plexEpisodes, sb); - await ProcessEmbyTv(embyEp, sb); + if (plexSettings.Enable) + { + await ProcessPlexTv(plexEpisodes, sb); + } + + if (embySettings.Enable) + { + await ProcessEmbyTv(embyEp, sb); + } + sb.Append(""); sb.Append("
"); sb.Append(""); diff --git a/src/Ombi.Schedule/Jobs/Ombi/OmbiAutomaticUpdater.cs b/src/Ombi.Schedule/Jobs/Ombi/OmbiAutomaticUpdater.cs index 5ec8978b6..783fe5f9d 100644 --- a/src/Ombi.Schedule/Jobs/Ombi/OmbiAutomaticUpdater.cs +++ b/src/Ombi.Schedule/Jobs/Ombi/OmbiAutomaticUpdater.cs @@ -5,18 +5,13 @@ using System.IO; using System.IO.Compression; using System.Linq; using System.Net; -using System.Net.Http; using System.Reflection; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; using Hangfire; -using Hangfire.Console; using Hangfire.Server; using Microsoft.Extensions.Logging; - -using Ombi.Api.Service; -using Ombi.Api.Service.Models; using Ombi.Core.Processor; using Ombi.Core.Settings; using Ombi.Helpers; @@ -40,7 +35,6 @@ namespace Ombi.Schedule.Jobs.Ombi Settings = s; _processProvider = proc; _appConfig = appConfig; - Settings.ClearCache(); } private ILogger Logger { get; } diff --git a/src/Ombi.Schedule/Jobs/Ombi/RefreshMetadata.cs b/src/Ombi.Schedule/Jobs/Ombi/RefreshMetadata.cs index d58c29ddc..c9ba5c6b3 100644 --- a/src/Ombi.Schedule/Jobs/Ombi/RefreshMetadata.cs +++ b/src/Ombi.Schedule/Jobs/Ombi/RefreshMetadata.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Threading.Tasks; using Hangfire; using Microsoft.Extensions.Logging; +using Ombi.Api.Emby; using Ombi.Api.TheMovieDb; using Ombi.Api.TheMovieDb.Models; using Ombi.Api.TvMaze; @@ -21,7 +22,8 @@ namespace Ombi.Schedule.Jobs.Ombi { public RefreshMetadata(IPlexContentRepository plexRepo, IEmbyContentRepository embyRepo, ILogger log, ITvMazeApi tvApi, ISettingsService plexSettings, - IMovieDbApi movieApi, ISettingsService embySettings, IPlexAvailabilityChecker plexAvailability, IEmbyAvaliabilityChecker embyAvaliability) + IMovieDbApi movieApi, ISettingsService embySettings, IPlexAvailabilityChecker plexAvailability, IEmbyAvaliabilityChecker embyAvaliability, + IEmbyApi embyApi) { _plexRepo = plexRepo; _embyRepo = embyRepo; @@ -32,6 +34,7 @@ namespace Ombi.Schedule.Jobs.Ombi _embySettings = embySettings; _plexAvailabilityChecker = plexAvailability; _embyAvaliabilityChecker = embyAvaliability; + _embyApi = embyApi; } private readonly IPlexContentRepository _plexRepo; @@ -43,6 +46,7 @@ namespace Ombi.Schedule.Jobs.Ombi private readonly ITvMazeApi _tvApi; private readonly ISettingsService _plexSettings; private readonly ISettingsService _embySettings; + private readonly IEmbyApi _embyApi; public async Task Start() { @@ -54,11 +58,11 @@ namespace Ombi.Schedule.Jobs.Ombi { await StartPlex(); } - + var embySettings = await _embySettings.GetSettingsAsync(); if (embySettings.Enable) { - await StartEmby(); + await StartEmby(embySettings); } } catch (Exception e) @@ -123,9 +127,9 @@ namespace Ombi.Schedule.Jobs.Ombi await StartPlexTv(allTv); } - private async Task StartEmby() + private async Task StartEmby(EmbySettings s) { - await StartEmbyMovies(); + await StartEmbyMovies(s); await StartEmbyTv(); } @@ -158,7 +162,7 @@ namespace Ombi.Schedule.Jobs.Ombi _plexRepo.UpdateWithoutSave(show); } tvCount++; - if (tvCount >= 20) + if (tvCount >= 75) { await _plexRepo.SaveChangesAsync(); tvCount = 0; @@ -198,7 +202,7 @@ namespace Ombi.Schedule.Jobs.Ombi _embyRepo.UpdateWithoutSave(show); } tvCount++; - if (tvCount >= 20) + if (tvCount >= 75) { await _embyRepo.SaveChangesAsync(); tvCount = 0; @@ -229,7 +233,7 @@ namespace Ombi.Schedule.Jobs.Ombi _plexRepo.UpdateWithoutSave(movie); } movieCount++; - if (movieCount >= 20) + if (movieCount >= 75) { await _plexRepo.SaveChangesAsync(); movieCount = 0; @@ -239,31 +243,56 @@ namespace Ombi.Schedule.Jobs.Ombi await _plexRepo.SaveChangesAsync(); } - private async Task StartEmbyMovies() + private async Task StartEmbyMovies(EmbySettings settings) { var allMovies = _embyRepo.GetAll().Where(x => x.Type == EmbyMediaType.Movie && (!x.TheMovieDbId.HasValue() || !x.ImdbId.HasValue())); int movieCount = 0; foreach (var movie in allMovies) { - var hasImdb = movie.ImdbId.HasValue(); - var hasTheMovieDb = movie.TheMovieDbId.HasValue(); + movie.ImdbId.HasValue(); + movie.TheMovieDbId.HasValue(); // Movies don't really use TheTvDb - if (!hasImdb) + // Check if it even has 1 ID + if (!movie.HasImdb && !movie.HasTheMovieDb) { - var imdbId = await GetImdbId(hasTheMovieDb, false, movie.Title, movie.TheMovieDbId, string.Empty); + // Ok this sucks, + // The only think I can think that has happened is that we scanned Emby before Emby has got the metadata + // So let's recheck emby to see if they have got the metadata now + _log.LogInformation($"Movie {movie.Title} does not have a ImdbId or TheMovieDbId, so rechecking emby"); + foreach (var server in settings.Servers) + { + _log.LogInformation($"Checking server {server.Name} for upto date metadata"); + var movieInfo = await _embyApi.GetMovieInformation(movie.EmbyId, server.ApiKey, server.AdministratorId, + server.FullUri); + + if (movieInfo.ProviderIds?.Imdb.HasValue() ?? false) + { + movie.ImdbId = movieInfo.ProviderIds.Imdb; + } + + if (movieInfo.ProviderIds?.Tmdb.HasValue() ?? false) + { + movie.TheMovieDbId = movieInfo.ProviderIds.Tmdb; + } + } + } + + if (!movie.HasImdb) + { + var imdbId = await GetImdbId(movie.HasTheMovieDb, false, movie.Title, movie.TheMovieDbId, string.Empty); movie.ImdbId = imdbId; _embyRepo.UpdateWithoutSave(movie); } - if (!hasTheMovieDb) + if (!movie.HasTheMovieDb) { - var id = await GetTheMovieDbId(false, hasImdb, string.Empty, movie.ImdbId, movie.Title, true); + var id = await GetTheMovieDbId(false, movie.HasImdb, string.Empty, movie.ImdbId, movie.Title, true); movie.TheMovieDbId = id; _embyRepo.UpdateWithoutSave(movie); } movieCount++; - if (movieCount >= 20) + if (movieCount >= 75) { await _embyRepo.SaveChangesAsync(); movieCount = 0; diff --git a/src/Ombi.Schedule/Jobs/Ombi/WelcomeEmail.cs b/src/Ombi.Schedule/Jobs/Ombi/WelcomeEmail.cs index e260ebed3..f98072e9e 100644 --- a/src/Ombi.Schedule/Jobs/Ombi/WelcomeEmail.cs +++ b/src/Ombi.Schedule/Jobs/Ombi/WelcomeEmail.cs @@ -20,8 +20,6 @@ namespace Ombi.Schedule.Jobs.Ombi _email = provider; _templates = template; _customizationSettings = c; - email.ClearCache(); - _customizationSettings.ClearCache(); } private readonly ISettingsService _emailSettings; diff --git a/src/Ombi.Schedule/Jobs/Plex/PlexContentSync.cs b/src/Ombi.Schedule/Jobs/Plex/PlexContentSync.cs index c39b80c1f..964832b44 100644 --- a/src/Ombi.Schedule/Jobs/Plex/PlexContentSync.cs +++ b/src/Ombi.Schedule/Jobs/Plex/PlexContentSync.cs @@ -57,7 +57,6 @@ namespace Ombi.Schedule.Jobs.Plex EpisodeSync = epsiodeSync; Metadata = metadataRefresh; Checker = checker; - plex.ClearCache(); } private ISettingsService Plex { get; } diff --git a/src/Ombi.Schedule/Jobs/Plex/PlexEpisodeSync.cs b/src/Ombi.Schedule/Jobs/Plex/PlexEpisodeSync.cs index 5652d126b..6ab5a5941 100644 --- a/src/Ombi.Schedule/Jobs/Plex/PlexEpisodeSync.cs +++ b/src/Ombi.Schedule/Jobs/Plex/PlexEpisodeSync.cs @@ -26,7 +26,6 @@ namespace Ombi.Schedule.Jobs.Plex _api = plexApi; _repo = repo; _availabilityChecker = a; - _settings.ClearCache(); } private readonly ISettingsService _settings; diff --git a/src/Ombi.Schedule/Jobs/Plex/PlexUserImporter.cs b/src/Ombi.Schedule/Jobs/Plex/PlexUserImporter.cs index 4f6bf2550..105e8876d 100644 --- a/src/Ombi.Schedule/Jobs/Plex/PlexUserImporter.cs +++ b/src/Ombi.Schedule/Jobs/Plex/PlexUserImporter.cs @@ -24,8 +24,6 @@ namespace Ombi.Schedule.Jobs.Plex _log = log; _plexSettings = plexSettings; _userManagementSettings = ums; - _userManagementSettings.ClearCache(); - _plexSettings.ClearCache(); } private readonly IPlexApi _api; diff --git a/src/Ombi.Schedule/Jobs/Radarr/RadarrSync.cs b/src/Ombi.Schedule/Jobs/Radarr/RadarrSync.cs index 5c954def8..f61747ac6 100644 --- a/src/Ombi.Schedule/Jobs/Radarr/RadarrSync.cs +++ b/src/Ombi.Schedule/Jobs/Radarr/RadarrSync.cs @@ -22,7 +22,6 @@ namespace Ombi.Schedule.Jobs.Radarr RadarrApi = radarrApi; Logger = log; _ctx = ctx; - RadarrSettings.ClearCache(); } private ISettingsService RadarrSettings { get; } diff --git a/src/Ombi.Schedule/Jobs/SickRage/SickRageSync.cs b/src/Ombi.Schedule/Jobs/SickRage/SickRageSync.cs index 92e0c2d55..2c8d03b1d 100644 --- a/src/Ombi.Schedule/Jobs/SickRage/SickRageSync.cs +++ b/src/Ombi.Schedule/Jobs/SickRage/SickRageSync.cs @@ -22,7 +22,6 @@ namespace Ombi.Schedule.Jobs.SickRage _api = api; _log = l; _ctx = ctx; - _settings.ClearCache(); } private readonly ISettingsService _settings; diff --git a/src/Ombi.Schedule/Jobs/Sonarr/SonarrSync.cs b/src/Ombi.Schedule/Jobs/Sonarr/SonarrSync.cs index e4c00c726..c77e23394 100644 --- a/src/Ombi.Schedule/Jobs/Sonarr/SonarrSync.cs +++ b/src/Ombi.Schedule/Jobs/Sonarr/SonarrSync.cs @@ -25,7 +25,6 @@ namespace Ombi.Schedule.Jobs.Sonarr _api = api; _log = l; _ctx = ctx; - _settings.ClearCache(); } private readonly ISettingsService _settings; diff --git a/src/Ombi.Settings/Settings/Models/External/EmbySettings.cs b/src/Ombi.Settings/Settings/Models/External/EmbySettings.cs index 96df77281..595733dc1 100644 --- a/src/Ombi.Settings/Settings/Models/External/EmbySettings.cs +++ b/src/Ombi.Settings/Settings/Models/External/EmbySettings.cs @@ -14,6 +14,7 @@ namespace Ombi.Core.Settings.Models.External public string Name { get; set; } public string ApiKey { get; set; } public string AdministratorId { get; set; } + public string ServerHostname { get; set; } public bool EnableEpisodeSearching { get; set; } } } \ No newline at end of file diff --git a/src/Ombi.Settings/Settings/SettingsService.cs b/src/Ombi.Settings/Settings/SettingsService.cs index 3162c34c2..57ae482a2 100644 --- a/src/Ombi.Settings/Settings/SettingsService.cs +++ b/src/Ombi.Settings/Settings/SettingsService.cs @@ -61,7 +61,7 @@ namespace Ombi.Settings.Settings var model = obj; return model; - }, DateTime.Now.AddHours(2)); + }, DateTime.Now.AddHours(5)); } public bool SaveSettings(T model) diff --git a/src/Ombi.Store/Context/OmbiContext.cs b/src/Ombi.Store/Context/OmbiContext.cs index 3d8c05daa..47b245603 100644 --- a/src/Ombi.Store/Context/OmbiContext.cs +++ b/src/Ombi.Store/Context/OmbiContext.cs @@ -87,43 +87,6 @@ namespace Ombi.Store.Context public void Seed() { - // VACUUM; - Database.ExecuteSqlCommand("VACUUM;"); - - // Make sure we have the roles - var newsletterRole = Roles.Where(x => x.Name == OmbiRoles.ReceivesNewsletter); - if (!newsletterRole.Any()) - { - Roles.Add(new IdentityRole(OmbiRoles.ReceivesNewsletter) - { - NormalizedName = OmbiRoles.ReceivesNewsletter.ToUpper() - }); - SaveChanges(); - } - var requestMusicRole = Roles.Where(x => x.Name == OmbiRoles.RequestMusic); - if (!requestMusicRole.Any()) - { - Roles.Add(new IdentityRole(OmbiRoles.RequestMusic) - { - NormalizedName = OmbiRoles.RequestMusic.ToUpper() - }); - Roles.Add(new IdentityRole(OmbiRoles.AutoApproveMusic) - { - NormalizedName = OmbiRoles.AutoApproveMusic.ToUpper() - }); - SaveChanges(); - } - - var manageOwnRequestsRole = Roles.Where(x => x.Name == OmbiRoles.ManageOwnRequests); - if (!manageOwnRequestsRole.Any()) - { - Roles.Add(new IdentityRole(OmbiRoles.ManageOwnRequests) - { - NormalizedName = OmbiRoles.ManageOwnRequests.ToUpper() - }); - SaveChanges(); - } - // Make sure we have the API User var apiUserExists = Users.Any(x => x.UserName.Equals("Api", StringComparison.CurrentCultureIgnoreCase)); if (!apiUserExists) @@ -209,7 +172,15 @@ namespace Ombi.Store.Context }; break; case NotificationType.ItemAddedToFaultQueue: - continue; + notificationToAdd = new NotificationTemplates + { + NotificationType = notificationType, + Message = "Hello! The user '{UserName}' has requested {Title} but it could not be added. This has been added into the requests queue and will keep retrying", + Subject = "Item Added To Retry Queue", + Agent = agent, + Enabled = true, + }; + break; case NotificationType.WelcomeEmail: notificationToAdd = new NotificationTemplates { diff --git a/src/Ombi.Store/Context/SettingsContext.cs b/src/Ombi.Store/Context/SettingsContext.cs index af5c91d20..6a53e598f 100644 --- a/src/Ombi.Store/Context/SettingsContext.cs +++ b/src/Ombi.Store/Context/SettingsContext.cs @@ -66,5 +66,10 @@ namespace Ombi.Store.Context SaveChanges(); } + + ~SettingsContext() + { + + } } } \ No newline at end of file diff --git a/src/Ombi.Store/Entities/OmbiUser.cs b/src/Ombi.Store/Entities/OmbiUser.cs index 801a50cb1..edb9708a9 100644 --- a/src/Ombi.Store/Entities/OmbiUser.cs +++ b/src/Ombi.Store/Entities/OmbiUser.cs @@ -34,7 +34,7 @@ namespace Ombi.Store.Entities public bool IsEmbyConnect => UserType == UserType.EmbyUser && EmbyConnectUserId.HasValue(); [NotMapped] - public string UserAlias => string.IsNullOrEmpty(Alias) ? UserName : Alias; + public virtual string UserAlias => string.IsNullOrEmpty(Alias) ? UserName : Alias; [NotMapped] public bool EmailLogin { get; set; } diff --git a/src/Ombi.Store/Entities/Requests/BaseRequest.cs b/src/Ombi.Store/Entities/Requests/BaseRequest.cs index f224032f1..596041a51 100644 --- a/src/Ombi.Store/Entities/Requests/BaseRequest.cs +++ b/src/Ombi.Store/Entities/Requests/BaseRequest.cs @@ -17,6 +17,7 @@ namespace Ombi.Store.Entities.Requests public DateTime MarkedAsDenied { get; set; } public string DeniedReason { get; set; } public RequestType RequestType { get; set; } + public string RequestedByAlias { get; set; } [ForeignKey(nameof(RequestedUserId))] public OmbiUser RequestedUser { get; set; } diff --git a/src/Ombi.Store/Entities/Requests/SeasonRequests.cs b/src/Ombi.Store/Entities/Requests/SeasonRequests.cs index 521cf5b94..6abaa4de3 100644 --- a/src/Ombi.Store/Entities/Requests/SeasonRequests.cs +++ b/src/Ombi.Store/Entities/Requests/SeasonRequests.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations.Schema; +using System.Globalization; using Ombi.Store.Entities; using Ombi.Store.Entities.Requests; @@ -27,9 +28,10 @@ namespace Ombi.Store.Repository.Requests public bool Approved { get; set; } public bool Requested { get; set; } - public int SeasonId { get; set; } [ForeignKey(nameof(SeasonId))] public SeasonRequests Season { get; set; } + + [NotMapped] public string AirDateDisplay => AirDate == DateTime.MinValue ? "Unknown" : AirDate.ToString(CultureInfo.InvariantCulture); } } \ No newline at end of file diff --git a/src/Ombi.Store/Entities/Requests/TvRequests.cs b/src/Ombi.Store/Entities/Requests/TvRequests.cs index 432bc88ab..5e33c016f 100644 --- a/src/Ombi.Store/Entities/Requests/TvRequests.cs +++ b/src/Ombi.Store/Entities/Requests/TvRequests.cs @@ -17,10 +17,6 @@ namespace Ombi.Store.Entities.Requests public DateTime ReleaseDate { get; set; } public string Status { get; set; } - /// - /// This is so we can correctly send the right amount of seasons to Sonarr - /// - [NotMapped] public int TotalSeasons { get; set; } public List ChildRequests { get; set; } diff --git a/src/Ombi.Store/Migrations/20190116212601_RequestedByAlias.Designer.cs b/src/Ombi.Store/Migrations/20190116212601_RequestedByAlias.Designer.cs new file mode 100644 index 000000000..45197bdfb --- /dev/null +++ b/src/Ombi.Store/Migrations/20190116212601_RequestedByAlias.Designer.cs @@ -0,0 +1,1212 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Ombi.Store.Context; + +namespace Ombi.Store.Migrations +{ + [DbContext(typeof(OmbiContext))] + [Migration("20190116212601_RequestedByAlias")] + partial class RequestedByAlias + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "2.2.1-servicing-10028"); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken(); + + b.Property("Name") + .HasMaxLength(256); + + b.Property("NormalizedName") + .HasMaxLength(256); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasName("RoleNameIndex"); + + b.ToTable("AspNetRoles"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ClaimType"); + + b.Property("ClaimValue"); + + b.Property("RoleId") + .IsRequired(); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ClaimType"); + + b.Property("ClaimValue"); + + b.Property("UserId") + .IsRequired(); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider"); + + b.Property("ProviderKey"); + + b.Property("ProviderDisplayName"); + + b.Property("UserId") + .IsRequired(); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId"); + + b.Property("RoleId"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId"); + + b.Property("LoginProvider"); + + b.Property("Name"); + + b.Property("Value"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.ApplicationConfiguration", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Type"); + + b.Property("Value"); + + b.HasKey("Id"); + + b.ToTable("ApplicationConfiguration"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Audit", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("AuditArea"); + + b.Property("AuditType"); + + b.Property("DateTime"); + + b.Property("Description"); + + b.Property("User"); + + b.HasKey("Id"); + + b.ToTable("Audit"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.CouchPotatoCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("TheMovieDbId"); + + b.HasKey("Id"); + + b.ToTable("CouchPotatoCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.EmbyContent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("AddedAt"); + + b.Property("EmbyId") + .IsRequired(); + + b.Property("ImdbId"); + + b.Property("ProviderId"); + + b.Property("TheMovieDbId"); + + b.Property("Title"); + + b.Property("TvDbId"); + + b.Property("Type"); + + b.Property("Url"); + + b.HasKey("Id"); + + b.ToTable("EmbyContent"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.EmbyEpisode", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("AddedAt"); + + b.Property("EmbyId"); + + b.Property("EpisodeNumber"); + + b.Property("ImdbId"); + + b.Property("ParentId"); + + b.Property("ProviderId"); + + b.Property("SeasonNumber"); + + b.Property("TheMovieDbId"); + + b.Property("Title"); + + b.Property("TvDbId"); + + b.HasKey("Id"); + + b.HasIndex("ParentId"); + + b.ToTable("EmbyEpisode"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.GlobalSettings", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Content"); + + b.Property("SettingsName"); + + b.HasKey("Id"); + + b.ToTable("GlobalSettings"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.LidarrAlbumCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("AddedAt"); + + b.Property("ArtistId"); + + b.Property("ForeignAlbumId"); + + b.Property("Monitored"); + + b.Property("PercentOfTracks"); + + b.Property("ReleaseDate"); + + b.Property("Title"); + + b.Property("TrackCount"); + + b.HasKey("Id"); + + b.ToTable("LidarrAlbumCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.LidarrArtistCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ArtistId"); + + b.Property("ArtistName"); + + b.Property("ForeignArtistId"); + + b.Property("Monitored"); + + b.HasKey("Id"); + + b.ToTable("LidarrArtistCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.NotificationTemplates", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Agent"); + + b.Property("Enabled"); + + b.Property("Message"); + + b.Property("NotificationType"); + + b.Property("Subject"); + + b.HasKey("Id"); + + b.ToTable("NotificationTemplates"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.NotificationUserId", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("AddedAt"); + + b.Property("PlayerId"); + + b.Property("UserId"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("NotificationUserId"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.OmbiUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("AccessFailedCount"); + + b.Property("Alias"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken(); + + b.Property("Email") + .HasMaxLength(256); + + b.Property("EmailConfirmed"); + + b.Property("EmbyConnectUserId"); + + b.Property("EpisodeRequestLimit"); + + b.Property("LastLoggedIn"); + + b.Property("LockoutEnabled"); + + b.Property("LockoutEnd"); + + b.Property("MovieRequestLimit"); + + b.Property("MusicRequestLimit"); + + b.Property("NormalizedEmail") + .HasMaxLength(256); + + b.Property("NormalizedUserName") + .HasMaxLength(256); + + b.Property("PasswordHash"); + + b.Property("PhoneNumber"); + + b.Property("PhoneNumberConfirmed"); + + b.Property("ProviderUserId"); + + b.Property("SecurityStamp"); + + b.Property("TwoFactorEnabled"); + + b.Property("UserAccessToken"); + + b.Property("UserName") + .HasMaxLength(256); + + b.Property("UserType"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasName("UserNameIndex"); + + b.ToTable("AspNetUsers"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexEpisode", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("EpisodeNumber"); + + b.Property("GrandparentKey"); + + b.Property("Key"); + + b.Property("ParentKey"); + + b.Property("SeasonNumber"); + + b.Property("Title"); + + b.HasKey("Id"); + + b.HasIndex("GrandparentKey"); + + b.ToTable("PlexEpisode"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexSeasonsContent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ParentKey"); + + b.Property("PlexContentId"); + + b.Property("PlexServerContentId"); + + b.Property("SeasonKey"); + + b.Property("SeasonNumber"); + + b.HasKey("Id"); + + b.HasIndex("PlexServerContentId"); + + b.ToTable("PlexSeasonsContent"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexServerContent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("AddedAt"); + + b.Property("ImdbId"); + + b.Property("Key"); + + b.Property("Quality"); + + b.Property("ReleaseYear"); + + b.Property("TheMovieDbId"); + + b.Property("Title"); + + b.Property("TvDbId"); + + b.Property("Type"); + + b.Property("Url"); + + b.HasKey("Id"); + + b.ToTable("PlexServerContent"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.RadarrCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("HasFile"); + + b.Property("TheMovieDbId"); + + b.HasKey("Id"); + + b.ToTable("RadarrCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.RecentlyAddedLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("AddedAt"); + + b.Property("AlbumId"); + + b.Property("ContentId"); + + b.Property("ContentType"); + + b.Property("EpisodeNumber"); + + b.Property("SeasonNumber"); + + b.Property("Type"); + + b.HasKey("Id"); + + b.ToTable("RecentlyAddedLog"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.RequestQueue", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Completed"); + + b.Property("Dts"); + + b.Property("Error"); + + b.Property("RequestId"); + + b.Property("RetryCount"); + + b.Property("Type"); + + b.HasKey("Id"); + + b.ToTable("RequestQueue"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.RequestSubscription", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("RequestId"); + + b.Property("RequestType"); + + b.Property("UserId"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("RequestSubscription"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.AlbumRequest", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Approved"); + + b.Property("ArtistName"); + + b.Property("Available"); + + b.Property("Cover"); + + b.Property("Denied"); + + b.Property("DeniedReason"); + + b.Property("Disk"); + + b.Property("ForeignAlbumId"); + + b.Property("ForeignArtistId"); + + b.Property("MarkedAsApproved"); + + b.Property("MarkedAsAvailable"); + + b.Property("MarkedAsDenied"); + + b.Property("Rating"); + + b.Property("ReleaseDate"); + + b.Property("RequestType"); + + b.Property("RequestedByAlias"); + + b.Property("RequestedDate"); + + b.Property("RequestedUserId"); + + b.Property("Title"); + + b.HasKey("Id"); + + b.HasIndex("RequestedUserId"); + + b.ToTable("AlbumRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.ChildRequests", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Approved"); + + b.Property("Available"); + + b.Property("Denied"); + + b.Property("DeniedReason"); + + b.Property("IssueId"); + + b.Property("MarkedAsApproved"); + + b.Property("MarkedAsAvailable"); + + b.Property("MarkedAsDenied"); + + b.Property("ParentRequestId"); + + b.Property("RequestType"); + + b.Property("RequestedByAlias"); + + b.Property("RequestedDate"); + + b.Property("RequestedUserId"); + + b.Property("SeriesType"); + + b.Property("Title"); + + b.HasKey("Id"); + + b.HasIndex("ParentRequestId"); + + b.HasIndex("RequestedUserId"); + + b.ToTable("ChildRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.IssueCategory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Value"); + + b.HasKey("Id"); + + b.ToTable("IssueCategory"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.IssueComments", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Comment"); + + b.Property("Date"); + + b.Property("IssuesId"); + + b.Property("UserId"); + + b.HasKey("Id"); + + b.HasIndex("IssuesId"); + + b.HasIndex("UserId"); + + b.ToTable("IssueComments"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.Issues", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Description"); + + b.Property("IssueCategoryId"); + + b.Property("IssueId"); + + b.Property("ProviderId"); + + b.Property("RequestId"); + + b.Property("RequestType"); + + b.Property("ResovledDate"); + + b.Property("Status"); + + b.Property("Subject"); + + b.Property("Title"); + + b.Property("UserReportedId"); + + b.HasKey("Id"); + + b.HasIndex("IssueCategoryId"); + + b.HasIndex("IssueId"); + + b.HasIndex("UserReportedId"); + + b.ToTable("Issues"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.MovieRequests", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Approved"); + + b.Property("Available"); + + b.Property("Background"); + + b.Property("Denied"); + + b.Property("DeniedReason"); + + b.Property("DigitalReleaseDate"); + + b.Property("ImdbId"); + + b.Property("IssueId"); + + b.Property("LangCode"); + + b.Property("MarkedAsApproved"); + + b.Property("MarkedAsAvailable"); + + b.Property("MarkedAsDenied"); + + b.Property("Overview"); + + b.Property("PosterPath"); + + b.Property("QualityOverride"); + + b.Property("ReleaseDate"); + + b.Property("RequestType"); + + b.Property("RequestedByAlias"); + + b.Property("RequestedDate"); + + b.Property("RequestedUserId"); + + b.Property("RootPathOverride"); + + b.Property("Status"); + + b.Property("TheMovieDbId"); + + b.Property("Title"); + + b.HasKey("Id"); + + b.HasIndex("RequestedUserId"); + + b.ToTable("MovieRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.RequestLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("EpisodeCount"); + + b.Property("RequestDate"); + + b.Property("RequestId"); + + b.Property("RequestType"); + + b.Property("UserId"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("RequestLog"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.TvRequests", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Background"); + + b.Property("ImdbId"); + + b.Property("Overview"); + + b.Property("PosterPath"); + + b.Property("QualityOverride"); + + b.Property("ReleaseDate"); + + b.Property("RootFolder"); + + b.Property("Status"); + + b.Property("Title"); + + b.Property("TvDbId"); + + b.HasKey("Id"); + + b.ToTable("TvRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.SickRageCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("TvDbId"); + + b.HasKey("Id"); + + b.ToTable("SickRageCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.SickRageEpisodeCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("EpisodeNumber"); + + b.Property("SeasonNumber"); + + b.Property("TvDbId"); + + b.HasKey("Id"); + + b.ToTable("SickRageEpisodeCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.SonarrCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("TvDbId"); + + b.HasKey("Id"); + + b.ToTable("SonarrCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.SonarrEpisodeCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("EpisodeNumber"); + + b.Property("HasFile"); + + b.Property("SeasonNumber"); + + b.Property("TvDbId"); + + b.HasKey("Id"); + + b.ToTable("SonarrEpisodeCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Tokens", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Token"); + + b.Property("UserId"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("Tokens"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.UserNotificationPreferences", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Agent"); + + b.Property("Enabled"); + + b.Property("UserId"); + + b.Property("Value"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserNotificationPreferences"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.UserQualityProfiles", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("RadarrQualityProfile"); + + b.Property("RadarrRootPath"); + + b.Property("SonarrQualityProfile"); + + b.Property("SonarrQualityProfileAnime"); + + b.Property("SonarrRootPath"); + + b.Property("SonarrRootPathAnime"); + + b.Property("UserId"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserQualityProfiles"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Votes", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Date"); + + b.Property("Deleted"); + + b.Property("RequestId"); + + b.Property("RequestType"); + + b.Property("UserId"); + + b.Property("VoteType"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("Votes"); + }); + + modelBuilder.Entity("Ombi.Store.Repository.Requests.EpisodeRequests", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("AirDate"); + + b.Property("Approved"); + + b.Property("Available"); + + b.Property("EpisodeNumber"); + + b.Property("Requested"); + + b.Property("SeasonId"); + + b.Property("Title"); + + b.Property("Url"); + + b.HasKey("Id"); + + b.HasIndex("SeasonId"); + + b.ToTable("EpisodeRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Repository.Requests.SeasonRequests", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ChildRequestId"); + + b.Property("SeasonNumber"); + + b.HasKey("Id"); + + b.HasIndex("ChildRequestId"); + + b.ToTable("SeasonRequests"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole") + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole") + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("Ombi.Store.Entities.OmbiUser") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("Ombi.Store.Entities.EmbyEpisode", b => + { + b.HasOne("Ombi.Store.Entities.EmbyContent", "Series") + .WithMany("Episodes") + .HasForeignKey("ParentId") + .HasPrincipalKey("EmbyId"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.NotificationUserId", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany("NotificationUserIds") + .HasForeignKey("UserId"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexEpisode", b => + { + b.HasOne("Ombi.Store.Entities.PlexServerContent", "Series") + .WithMany("Episodes") + .HasForeignKey("GrandparentKey") + .HasPrincipalKey("Key") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexSeasonsContent", b => + { + b.HasOne("Ombi.Store.Entities.PlexServerContent") + .WithMany("Seasons") + .HasForeignKey("PlexServerContentId"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.RequestSubscription", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.AlbumRequest", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "RequestedUser") + .WithMany() + .HasForeignKey("RequestedUserId"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.ChildRequests", b => + { + b.HasOne("Ombi.Store.Entities.Requests.TvRequests", "ParentRequest") + .WithMany("ChildRequests") + .HasForeignKey("ParentRequestId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("Ombi.Store.Entities.OmbiUser", "RequestedUser") + .WithMany() + .HasForeignKey("RequestedUserId"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.IssueComments", b => + { + b.HasOne("Ombi.Store.Entities.Requests.Issues", "Issues") + .WithMany("Comments") + .HasForeignKey("IssuesId"); + + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.Issues", b => + { + b.HasOne("Ombi.Store.Entities.Requests.IssueCategory", "IssueCategory") + .WithMany() + .HasForeignKey("IssueCategoryId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("Ombi.Store.Entities.Requests.ChildRequests") + .WithMany("Issues") + .HasForeignKey("IssueId"); + + b.HasOne("Ombi.Store.Entities.Requests.MovieRequests") + .WithMany("Issues") + .HasForeignKey("IssueId"); + + b.HasOne("Ombi.Store.Entities.OmbiUser", "UserReported") + .WithMany() + .HasForeignKey("UserReportedId"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.MovieRequests", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "RequestedUser") + .WithMany() + .HasForeignKey("RequestedUserId"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.RequestLog", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Tokens", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.UserNotificationPreferences", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany("UserNotificationPreferences") + .HasForeignKey("UserId"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.UserQualityProfiles", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Votes", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + }); + + modelBuilder.Entity("Ombi.Store.Repository.Requests.EpisodeRequests", b => + { + b.HasOne("Ombi.Store.Repository.Requests.SeasonRequests", "Season") + .WithMany("Episodes") + .HasForeignKey("SeasonId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("Ombi.Store.Repository.Requests.SeasonRequests", b => + { + b.HasOne("Ombi.Store.Entities.Requests.ChildRequests", "ChildRequest") + .WithMany("SeasonRequests") + .HasForeignKey("ChildRequestId") + .OnDelete(DeleteBehavior.Cascade); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Ombi.Store/Migrations/20190116212601_RequestedByAlias.cs b/src/Ombi.Store/Migrations/20190116212601_RequestedByAlias.cs new file mode 100644 index 000000000..1e55c2f6e --- /dev/null +++ b/src/Ombi.Store/Migrations/20190116212601_RequestedByAlias.cs @@ -0,0 +1,40 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Ombi.Store.Migrations +{ + public partial class RequestedByAlias : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "RequestedByAlias", + table: "MovieRequests", + nullable: true); + + migrationBuilder.AddColumn( + name: "RequestedByAlias", + table: "ChildRequests", + nullable: true); + + migrationBuilder.AddColumn( + name: "RequestedByAlias", + table: "AlbumRequests", + nullable: true); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "RequestedByAlias", + table: "MovieRequests"); + + migrationBuilder.DropColumn( + name: "RequestedByAlias", + table: "ChildRequests"); + + migrationBuilder.DropColumn( + name: "RequestedByAlias", + table: "AlbumRequests"); + } + } +} diff --git a/src/Ombi.Store/Migrations/20190216224539_Roles.Designer.cs b/src/Ombi.Store/Migrations/20190216224539_Roles.Designer.cs new file mode 100644 index 000000000..f0aeb88bc --- /dev/null +++ b/src/Ombi.Store/Migrations/20190216224539_Roles.Designer.cs @@ -0,0 +1,1212 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Ombi.Store.Context; + +namespace Ombi.Store.Migrations +{ + [DbContext(typeof(OmbiContext))] + [Migration("20190216224539_Roles")] + partial class Roles + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "2.2.1-servicing-10028"); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken(); + + b.Property("Name") + .HasMaxLength(256); + + b.Property("NormalizedName") + .HasMaxLength(256); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasName("RoleNameIndex"); + + b.ToTable("AspNetRoles"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ClaimType"); + + b.Property("ClaimValue"); + + b.Property("RoleId") + .IsRequired(); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ClaimType"); + + b.Property("ClaimValue"); + + b.Property("UserId") + .IsRequired(); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider"); + + b.Property("ProviderKey"); + + b.Property("ProviderDisplayName"); + + b.Property("UserId") + .IsRequired(); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId"); + + b.Property("RoleId"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId"); + + b.Property("LoginProvider"); + + b.Property("Name"); + + b.Property("Value"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.ApplicationConfiguration", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Type"); + + b.Property("Value"); + + b.HasKey("Id"); + + b.ToTable("ApplicationConfiguration"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Audit", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("AuditArea"); + + b.Property("AuditType"); + + b.Property("DateTime"); + + b.Property("Description"); + + b.Property("User"); + + b.HasKey("Id"); + + b.ToTable("Audit"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.CouchPotatoCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("TheMovieDbId"); + + b.HasKey("Id"); + + b.ToTable("CouchPotatoCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.EmbyContent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("AddedAt"); + + b.Property("EmbyId") + .IsRequired(); + + b.Property("ImdbId"); + + b.Property("ProviderId"); + + b.Property("TheMovieDbId"); + + b.Property("Title"); + + b.Property("TvDbId"); + + b.Property("Type"); + + b.Property("Url"); + + b.HasKey("Id"); + + b.ToTable("EmbyContent"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.EmbyEpisode", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("AddedAt"); + + b.Property("EmbyId"); + + b.Property("EpisodeNumber"); + + b.Property("ImdbId"); + + b.Property("ParentId"); + + b.Property("ProviderId"); + + b.Property("SeasonNumber"); + + b.Property("TheMovieDbId"); + + b.Property("Title"); + + b.Property("TvDbId"); + + b.HasKey("Id"); + + b.HasIndex("ParentId"); + + b.ToTable("EmbyEpisode"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.GlobalSettings", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Content"); + + b.Property("SettingsName"); + + b.HasKey("Id"); + + b.ToTable("GlobalSettings"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.LidarrAlbumCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("AddedAt"); + + b.Property("ArtistId"); + + b.Property("ForeignAlbumId"); + + b.Property("Monitored"); + + b.Property("PercentOfTracks"); + + b.Property("ReleaseDate"); + + b.Property("Title"); + + b.Property("TrackCount"); + + b.HasKey("Id"); + + b.ToTable("LidarrAlbumCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.LidarrArtistCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ArtistId"); + + b.Property("ArtistName"); + + b.Property("ForeignArtistId"); + + b.Property("Monitored"); + + b.HasKey("Id"); + + b.ToTable("LidarrArtistCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.NotificationTemplates", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Agent"); + + b.Property("Enabled"); + + b.Property("Message"); + + b.Property("NotificationType"); + + b.Property("Subject"); + + b.HasKey("Id"); + + b.ToTable("NotificationTemplates"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.NotificationUserId", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("AddedAt"); + + b.Property("PlayerId"); + + b.Property("UserId"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("NotificationUserId"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.OmbiUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("AccessFailedCount"); + + b.Property("Alias"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken(); + + b.Property("Email") + .HasMaxLength(256); + + b.Property("EmailConfirmed"); + + b.Property("EmbyConnectUserId"); + + b.Property("EpisodeRequestLimit"); + + b.Property("LastLoggedIn"); + + b.Property("LockoutEnabled"); + + b.Property("LockoutEnd"); + + b.Property("MovieRequestLimit"); + + b.Property("MusicRequestLimit"); + + b.Property("NormalizedEmail") + .HasMaxLength(256); + + b.Property("NormalizedUserName") + .HasMaxLength(256); + + b.Property("PasswordHash"); + + b.Property("PhoneNumber"); + + b.Property("PhoneNumberConfirmed"); + + b.Property("ProviderUserId"); + + b.Property("SecurityStamp"); + + b.Property("TwoFactorEnabled"); + + b.Property("UserAccessToken"); + + b.Property("UserName") + .HasMaxLength(256); + + b.Property("UserType"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasName("UserNameIndex"); + + b.ToTable("AspNetUsers"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexEpisode", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("EpisodeNumber"); + + b.Property("GrandparentKey"); + + b.Property("Key"); + + b.Property("ParentKey"); + + b.Property("SeasonNumber"); + + b.Property("Title"); + + b.HasKey("Id"); + + b.HasIndex("GrandparentKey"); + + b.ToTable("PlexEpisode"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexSeasonsContent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ParentKey"); + + b.Property("PlexContentId"); + + b.Property("PlexServerContentId"); + + b.Property("SeasonKey"); + + b.Property("SeasonNumber"); + + b.HasKey("Id"); + + b.HasIndex("PlexServerContentId"); + + b.ToTable("PlexSeasonsContent"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexServerContent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("AddedAt"); + + b.Property("ImdbId"); + + b.Property("Key"); + + b.Property("Quality"); + + b.Property("ReleaseYear"); + + b.Property("TheMovieDbId"); + + b.Property("Title"); + + b.Property("TvDbId"); + + b.Property("Type"); + + b.Property("Url"); + + b.HasKey("Id"); + + b.ToTable("PlexServerContent"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.RadarrCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("HasFile"); + + b.Property("TheMovieDbId"); + + b.HasKey("Id"); + + b.ToTable("RadarrCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.RecentlyAddedLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("AddedAt"); + + b.Property("AlbumId"); + + b.Property("ContentId"); + + b.Property("ContentType"); + + b.Property("EpisodeNumber"); + + b.Property("SeasonNumber"); + + b.Property("Type"); + + b.HasKey("Id"); + + b.ToTable("RecentlyAddedLog"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.RequestQueue", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Completed"); + + b.Property("Dts"); + + b.Property("Error"); + + b.Property("RequestId"); + + b.Property("RetryCount"); + + b.Property("Type"); + + b.HasKey("Id"); + + b.ToTable("RequestQueue"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.RequestSubscription", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("RequestId"); + + b.Property("RequestType"); + + b.Property("UserId"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("RequestSubscription"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.AlbumRequest", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Approved"); + + b.Property("ArtistName"); + + b.Property("Available"); + + b.Property("Cover"); + + b.Property("Denied"); + + b.Property("DeniedReason"); + + b.Property("Disk"); + + b.Property("ForeignAlbumId"); + + b.Property("ForeignArtistId"); + + b.Property("MarkedAsApproved"); + + b.Property("MarkedAsAvailable"); + + b.Property("MarkedAsDenied"); + + b.Property("Rating"); + + b.Property("ReleaseDate"); + + b.Property("RequestType"); + + b.Property("RequestedByAlias"); + + b.Property("RequestedDate"); + + b.Property("RequestedUserId"); + + b.Property("Title"); + + b.HasKey("Id"); + + b.HasIndex("RequestedUserId"); + + b.ToTable("AlbumRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.ChildRequests", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Approved"); + + b.Property("Available"); + + b.Property("Denied"); + + b.Property("DeniedReason"); + + b.Property("IssueId"); + + b.Property("MarkedAsApproved"); + + b.Property("MarkedAsAvailable"); + + b.Property("MarkedAsDenied"); + + b.Property("ParentRequestId"); + + b.Property("RequestType"); + + b.Property("RequestedByAlias"); + + b.Property("RequestedDate"); + + b.Property("RequestedUserId"); + + b.Property("SeriesType"); + + b.Property("Title"); + + b.HasKey("Id"); + + b.HasIndex("ParentRequestId"); + + b.HasIndex("RequestedUserId"); + + b.ToTable("ChildRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.IssueCategory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Value"); + + b.HasKey("Id"); + + b.ToTable("IssueCategory"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.IssueComments", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Comment"); + + b.Property("Date"); + + b.Property("IssuesId"); + + b.Property("UserId"); + + b.HasKey("Id"); + + b.HasIndex("IssuesId"); + + b.HasIndex("UserId"); + + b.ToTable("IssueComments"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.Issues", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Description"); + + b.Property("IssueCategoryId"); + + b.Property("IssueId"); + + b.Property("ProviderId"); + + b.Property("RequestId"); + + b.Property("RequestType"); + + b.Property("ResovledDate"); + + b.Property("Status"); + + b.Property("Subject"); + + b.Property("Title"); + + b.Property("UserReportedId"); + + b.HasKey("Id"); + + b.HasIndex("IssueCategoryId"); + + b.HasIndex("IssueId"); + + b.HasIndex("UserReportedId"); + + b.ToTable("Issues"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.MovieRequests", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Approved"); + + b.Property("Available"); + + b.Property("Background"); + + b.Property("Denied"); + + b.Property("DeniedReason"); + + b.Property("DigitalReleaseDate"); + + b.Property("ImdbId"); + + b.Property("IssueId"); + + b.Property("LangCode"); + + b.Property("MarkedAsApproved"); + + b.Property("MarkedAsAvailable"); + + b.Property("MarkedAsDenied"); + + b.Property("Overview"); + + b.Property("PosterPath"); + + b.Property("QualityOverride"); + + b.Property("ReleaseDate"); + + b.Property("RequestType"); + + b.Property("RequestedByAlias"); + + b.Property("RequestedDate"); + + b.Property("RequestedUserId"); + + b.Property("RootPathOverride"); + + b.Property("Status"); + + b.Property("TheMovieDbId"); + + b.Property("Title"); + + b.HasKey("Id"); + + b.HasIndex("RequestedUserId"); + + b.ToTable("MovieRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.RequestLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("EpisodeCount"); + + b.Property("RequestDate"); + + b.Property("RequestId"); + + b.Property("RequestType"); + + b.Property("UserId"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("RequestLog"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.TvRequests", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Background"); + + b.Property("ImdbId"); + + b.Property("Overview"); + + b.Property("PosterPath"); + + b.Property("QualityOverride"); + + b.Property("ReleaseDate"); + + b.Property("RootFolder"); + + b.Property("Status"); + + b.Property("Title"); + + b.Property("TvDbId"); + + b.HasKey("Id"); + + b.ToTable("TvRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.SickRageCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("TvDbId"); + + b.HasKey("Id"); + + b.ToTable("SickRageCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.SickRageEpisodeCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("EpisodeNumber"); + + b.Property("SeasonNumber"); + + b.Property("TvDbId"); + + b.HasKey("Id"); + + b.ToTable("SickRageEpisodeCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.SonarrCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("TvDbId"); + + b.HasKey("Id"); + + b.ToTable("SonarrCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.SonarrEpisodeCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("EpisodeNumber"); + + b.Property("HasFile"); + + b.Property("SeasonNumber"); + + b.Property("TvDbId"); + + b.HasKey("Id"); + + b.ToTable("SonarrEpisodeCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Tokens", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Token"); + + b.Property("UserId"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("Tokens"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.UserNotificationPreferences", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Agent"); + + b.Property("Enabled"); + + b.Property("UserId"); + + b.Property("Value"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserNotificationPreferences"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.UserQualityProfiles", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("RadarrQualityProfile"); + + b.Property("RadarrRootPath"); + + b.Property("SonarrQualityProfile"); + + b.Property("SonarrQualityProfileAnime"); + + b.Property("SonarrRootPath"); + + b.Property("SonarrRootPathAnime"); + + b.Property("UserId"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserQualityProfiles"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Votes", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Date"); + + b.Property("Deleted"); + + b.Property("RequestId"); + + b.Property("RequestType"); + + b.Property("UserId"); + + b.Property("VoteType"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("Votes"); + }); + + modelBuilder.Entity("Ombi.Store.Repository.Requests.EpisodeRequests", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("AirDate"); + + b.Property("Approved"); + + b.Property("Available"); + + b.Property("EpisodeNumber"); + + b.Property("Requested"); + + b.Property("SeasonId"); + + b.Property("Title"); + + b.Property("Url"); + + b.HasKey("Id"); + + b.HasIndex("SeasonId"); + + b.ToTable("EpisodeRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Repository.Requests.SeasonRequests", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ChildRequestId"); + + b.Property("SeasonNumber"); + + b.HasKey("Id"); + + b.HasIndex("ChildRequestId"); + + b.ToTable("SeasonRequests"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole") + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole") + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("Ombi.Store.Entities.OmbiUser") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("Ombi.Store.Entities.EmbyEpisode", b => + { + b.HasOne("Ombi.Store.Entities.EmbyContent", "Series") + .WithMany("Episodes") + .HasForeignKey("ParentId") + .HasPrincipalKey("EmbyId"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.NotificationUserId", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany("NotificationUserIds") + .HasForeignKey("UserId"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexEpisode", b => + { + b.HasOne("Ombi.Store.Entities.PlexServerContent", "Series") + .WithMany("Episodes") + .HasForeignKey("GrandparentKey") + .HasPrincipalKey("Key") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexSeasonsContent", b => + { + b.HasOne("Ombi.Store.Entities.PlexServerContent") + .WithMany("Seasons") + .HasForeignKey("PlexServerContentId"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.RequestSubscription", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.AlbumRequest", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "RequestedUser") + .WithMany() + .HasForeignKey("RequestedUserId"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.ChildRequests", b => + { + b.HasOne("Ombi.Store.Entities.Requests.TvRequests", "ParentRequest") + .WithMany("ChildRequests") + .HasForeignKey("ParentRequestId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("Ombi.Store.Entities.OmbiUser", "RequestedUser") + .WithMany() + .HasForeignKey("RequestedUserId"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.IssueComments", b => + { + b.HasOne("Ombi.Store.Entities.Requests.Issues", "Issues") + .WithMany("Comments") + .HasForeignKey("IssuesId"); + + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.Issues", b => + { + b.HasOne("Ombi.Store.Entities.Requests.IssueCategory", "IssueCategory") + .WithMany() + .HasForeignKey("IssueCategoryId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("Ombi.Store.Entities.Requests.ChildRequests") + .WithMany("Issues") + .HasForeignKey("IssueId"); + + b.HasOne("Ombi.Store.Entities.Requests.MovieRequests") + .WithMany("Issues") + .HasForeignKey("IssueId"); + + b.HasOne("Ombi.Store.Entities.OmbiUser", "UserReported") + .WithMany() + .HasForeignKey("UserReportedId"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.MovieRequests", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "RequestedUser") + .WithMany() + .HasForeignKey("RequestedUserId"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.RequestLog", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Tokens", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.UserNotificationPreferences", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany("UserNotificationPreferences") + .HasForeignKey("UserId"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.UserQualityProfiles", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Votes", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + }); + + modelBuilder.Entity("Ombi.Store.Repository.Requests.EpisodeRequests", b => + { + b.HasOne("Ombi.Store.Repository.Requests.SeasonRequests", "Season") + .WithMany("Episodes") + .HasForeignKey("SeasonId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("Ombi.Store.Repository.Requests.SeasonRequests", b => + { + b.HasOne("Ombi.Store.Entities.Requests.ChildRequests", "ChildRequest") + .WithMany("SeasonRequests") + .HasForeignKey("ChildRequestId") + .OnDelete(DeleteBehavior.Cascade); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Ombi.Store/Migrations/20190216224539_Roles.cs b/src/Ombi.Store/Migrations/20190216224539_Roles.cs new file mode 100644 index 000000000..9c2f91c12 --- /dev/null +++ b/src/Ombi.Store/Migrations/20190216224539_Roles.cs @@ -0,0 +1,32 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; +using Ombi.Helpers; + +namespace Ombi.Store.Migrations +{ + public partial class Roles : Migration + { + protected override void Up(MigrationBuilder mb) + { + // Make sure we have the roles + InsertRole(mb, OmbiRoles.ReceivesNewsletter); + InsertRole(mb, OmbiRoles.RequestMusic); + InsertRole(mb, OmbiRoles.AutoApproveMusic); + InsertRole(mb, OmbiRoles.ManageOwnRequests); + InsertRole(mb, OmbiRoles.EditCustomPage); + } + + private void InsertRole(MigrationBuilder mb, string role) + { + mb.Sql($@" +INSERT INTO AspnetRoles(Id, ConcurrencyStamp, Name, NormalizedName) +SELECT '{Guid.NewGuid().ToString()}','{Guid.NewGuid().ToString()}','{role}', '{role.ToUpper()}' +WHERE NOT EXISTS(SELECT 1 FROM AspnetRoles WHERE Name = '{role}');"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + + } + } +} diff --git a/src/Ombi.Store/Migrations/20190216231519_TvRequestsTotalSeasons.Designer.cs b/src/Ombi.Store/Migrations/20190216231519_TvRequestsTotalSeasons.Designer.cs new file mode 100644 index 000000000..7341ff5fe --- /dev/null +++ b/src/Ombi.Store/Migrations/20190216231519_TvRequestsTotalSeasons.Designer.cs @@ -0,0 +1,1214 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Ombi.Store.Context; + +namespace Ombi.Store.Migrations +{ + [DbContext(typeof(OmbiContext))] + [Migration("20190216231519_TvRequestsTotalSeasons")] + partial class TvRequestsTotalSeasons + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "2.2.1-servicing-10028"); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken(); + + b.Property("Name") + .HasMaxLength(256); + + b.Property("NormalizedName") + .HasMaxLength(256); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasName("RoleNameIndex"); + + b.ToTable("AspNetRoles"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ClaimType"); + + b.Property("ClaimValue"); + + b.Property("RoleId") + .IsRequired(); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ClaimType"); + + b.Property("ClaimValue"); + + b.Property("UserId") + .IsRequired(); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider"); + + b.Property("ProviderKey"); + + b.Property("ProviderDisplayName"); + + b.Property("UserId") + .IsRequired(); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId"); + + b.Property("RoleId"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId"); + + b.Property("LoginProvider"); + + b.Property("Name"); + + b.Property("Value"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.ApplicationConfiguration", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Type"); + + b.Property("Value"); + + b.HasKey("Id"); + + b.ToTable("ApplicationConfiguration"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Audit", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("AuditArea"); + + b.Property("AuditType"); + + b.Property("DateTime"); + + b.Property("Description"); + + b.Property("User"); + + b.HasKey("Id"); + + b.ToTable("Audit"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.CouchPotatoCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("TheMovieDbId"); + + b.HasKey("Id"); + + b.ToTable("CouchPotatoCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.EmbyContent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("AddedAt"); + + b.Property("EmbyId") + .IsRequired(); + + b.Property("ImdbId"); + + b.Property("ProviderId"); + + b.Property("TheMovieDbId"); + + b.Property("Title"); + + b.Property("TvDbId"); + + b.Property("Type"); + + b.Property("Url"); + + b.HasKey("Id"); + + b.ToTable("EmbyContent"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.EmbyEpisode", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("AddedAt"); + + b.Property("EmbyId"); + + b.Property("EpisodeNumber"); + + b.Property("ImdbId"); + + b.Property("ParentId"); + + b.Property("ProviderId"); + + b.Property("SeasonNumber"); + + b.Property("TheMovieDbId"); + + b.Property("Title"); + + b.Property("TvDbId"); + + b.HasKey("Id"); + + b.HasIndex("ParentId"); + + b.ToTable("EmbyEpisode"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.GlobalSettings", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Content"); + + b.Property("SettingsName"); + + b.HasKey("Id"); + + b.ToTable("GlobalSettings"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.LidarrAlbumCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("AddedAt"); + + b.Property("ArtistId"); + + b.Property("ForeignAlbumId"); + + b.Property("Monitored"); + + b.Property("PercentOfTracks"); + + b.Property("ReleaseDate"); + + b.Property("Title"); + + b.Property("TrackCount"); + + b.HasKey("Id"); + + b.ToTable("LidarrAlbumCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.LidarrArtistCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ArtistId"); + + b.Property("ArtistName"); + + b.Property("ForeignArtistId"); + + b.Property("Monitored"); + + b.HasKey("Id"); + + b.ToTable("LidarrArtistCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.NotificationTemplates", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Agent"); + + b.Property("Enabled"); + + b.Property("Message"); + + b.Property("NotificationType"); + + b.Property("Subject"); + + b.HasKey("Id"); + + b.ToTable("NotificationTemplates"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.NotificationUserId", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("AddedAt"); + + b.Property("PlayerId"); + + b.Property("UserId"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("NotificationUserId"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.OmbiUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("AccessFailedCount"); + + b.Property("Alias"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken(); + + b.Property("Email") + .HasMaxLength(256); + + b.Property("EmailConfirmed"); + + b.Property("EmbyConnectUserId"); + + b.Property("EpisodeRequestLimit"); + + b.Property("LastLoggedIn"); + + b.Property("LockoutEnabled"); + + b.Property("LockoutEnd"); + + b.Property("MovieRequestLimit"); + + b.Property("MusicRequestLimit"); + + b.Property("NormalizedEmail") + .HasMaxLength(256); + + b.Property("NormalizedUserName") + .HasMaxLength(256); + + b.Property("PasswordHash"); + + b.Property("PhoneNumber"); + + b.Property("PhoneNumberConfirmed"); + + b.Property("ProviderUserId"); + + b.Property("SecurityStamp"); + + b.Property("TwoFactorEnabled"); + + b.Property("UserAccessToken"); + + b.Property("UserName") + .HasMaxLength(256); + + b.Property("UserType"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasName("UserNameIndex"); + + b.ToTable("AspNetUsers"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexEpisode", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("EpisodeNumber"); + + b.Property("GrandparentKey"); + + b.Property("Key"); + + b.Property("ParentKey"); + + b.Property("SeasonNumber"); + + b.Property("Title"); + + b.HasKey("Id"); + + b.HasIndex("GrandparentKey"); + + b.ToTable("PlexEpisode"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexSeasonsContent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ParentKey"); + + b.Property("PlexContentId"); + + b.Property("PlexServerContentId"); + + b.Property("SeasonKey"); + + b.Property("SeasonNumber"); + + b.HasKey("Id"); + + b.HasIndex("PlexServerContentId"); + + b.ToTable("PlexSeasonsContent"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexServerContent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("AddedAt"); + + b.Property("ImdbId"); + + b.Property("Key"); + + b.Property("Quality"); + + b.Property("ReleaseYear"); + + b.Property("TheMovieDbId"); + + b.Property("Title"); + + b.Property("TvDbId"); + + b.Property("Type"); + + b.Property("Url"); + + b.HasKey("Id"); + + b.ToTable("PlexServerContent"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.RadarrCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("HasFile"); + + b.Property("TheMovieDbId"); + + b.HasKey("Id"); + + b.ToTable("RadarrCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.RecentlyAddedLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("AddedAt"); + + b.Property("AlbumId"); + + b.Property("ContentId"); + + b.Property("ContentType"); + + b.Property("EpisodeNumber"); + + b.Property("SeasonNumber"); + + b.Property("Type"); + + b.HasKey("Id"); + + b.ToTable("RecentlyAddedLog"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.RequestQueue", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Completed"); + + b.Property("Dts"); + + b.Property("Error"); + + b.Property("RequestId"); + + b.Property("RetryCount"); + + b.Property("Type"); + + b.HasKey("Id"); + + b.ToTable("RequestQueue"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.RequestSubscription", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("RequestId"); + + b.Property("RequestType"); + + b.Property("UserId"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("RequestSubscription"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.AlbumRequest", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Approved"); + + b.Property("ArtistName"); + + b.Property("Available"); + + b.Property("Cover"); + + b.Property("Denied"); + + b.Property("DeniedReason"); + + b.Property("Disk"); + + b.Property("ForeignAlbumId"); + + b.Property("ForeignArtistId"); + + b.Property("MarkedAsApproved"); + + b.Property("MarkedAsAvailable"); + + b.Property("MarkedAsDenied"); + + b.Property("Rating"); + + b.Property("ReleaseDate"); + + b.Property("RequestType"); + + b.Property("RequestedByAlias"); + + b.Property("RequestedDate"); + + b.Property("RequestedUserId"); + + b.Property("Title"); + + b.HasKey("Id"); + + b.HasIndex("RequestedUserId"); + + b.ToTable("AlbumRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.ChildRequests", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Approved"); + + b.Property("Available"); + + b.Property("Denied"); + + b.Property("DeniedReason"); + + b.Property("IssueId"); + + b.Property("MarkedAsApproved"); + + b.Property("MarkedAsAvailable"); + + b.Property("MarkedAsDenied"); + + b.Property("ParentRequestId"); + + b.Property("RequestType"); + + b.Property("RequestedByAlias"); + + b.Property("RequestedDate"); + + b.Property("RequestedUserId"); + + b.Property("SeriesType"); + + b.Property("Title"); + + b.HasKey("Id"); + + b.HasIndex("ParentRequestId"); + + b.HasIndex("RequestedUserId"); + + b.ToTable("ChildRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.IssueCategory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Value"); + + b.HasKey("Id"); + + b.ToTable("IssueCategory"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.IssueComments", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Comment"); + + b.Property("Date"); + + b.Property("IssuesId"); + + b.Property("UserId"); + + b.HasKey("Id"); + + b.HasIndex("IssuesId"); + + b.HasIndex("UserId"); + + b.ToTable("IssueComments"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.Issues", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Description"); + + b.Property("IssueCategoryId"); + + b.Property("IssueId"); + + b.Property("ProviderId"); + + b.Property("RequestId"); + + b.Property("RequestType"); + + b.Property("ResovledDate"); + + b.Property("Status"); + + b.Property("Subject"); + + b.Property("Title"); + + b.Property("UserReportedId"); + + b.HasKey("Id"); + + b.HasIndex("IssueCategoryId"); + + b.HasIndex("IssueId"); + + b.HasIndex("UserReportedId"); + + b.ToTable("Issues"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.MovieRequests", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Approved"); + + b.Property("Available"); + + b.Property("Background"); + + b.Property("Denied"); + + b.Property("DeniedReason"); + + b.Property("DigitalReleaseDate"); + + b.Property("ImdbId"); + + b.Property("IssueId"); + + b.Property("LangCode"); + + b.Property("MarkedAsApproved"); + + b.Property("MarkedAsAvailable"); + + b.Property("MarkedAsDenied"); + + b.Property("Overview"); + + b.Property("PosterPath"); + + b.Property("QualityOverride"); + + b.Property("ReleaseDate"); + + b.Property("RequestType"); + + b.Property("RequestedByAlias"); + + b.Property("RequestedDate"); + + b.Property("RequestedUserId"); + + b.Property("RootPathOverride"); + + b.Property("Status"); + + b.Property("TheMovieDbId"); + + b.Property("Title"); + + b.HasKey("Id"); + + b.HasIndex("RequestedUserId"); + + b.ToTable("MovieRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.RequestLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("EpisodeCount"); + + b.Property("RequestDate"); + + b.Property("RequestId"); + + b.Property("RequestType"); + + b.Property("UserId"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("RequestLog"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.TvRequests", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Background"); + + b.Property("ImdbId"); + + b.Property("Overview"); + + b.Property("PosterPath"); + + b.Property("QualityOverride"); + + b.Property("ReleaseDate"); + + b.Property("RootFolder"); + + b.Property("Status"); + + b.Property("Title"); + + b.Property("TotalSeasons"); + + b.Property("TvDbId"); + + b.HasKey("Id"); + + b.ToTable("TvRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.SickRageCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("TvDbId"); + + b.HasKey("Id"); + + b.ToTable("SickRageCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.SickRageEpisodeCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("EpisodeNumber"); + + b.Property("SeasonNumber"); + + b.Property("TvDbId"); + + b.HasKey("Id"); + + b.ToTable("SickRageEpisodeCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.SonarrCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("TvDbId"); + + b.HasKey("Id"); + + b.ToTable("SonarrCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.SonarrEpisodeCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("EpisodeNumber"); + + b.Property("HasFile"); + + b.Property("SeasonNumber"); + + b.Property("TvDbId"); + + b.HasKey("Id"); + + b.ToTable("SonarrEpisodeCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Tokens", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Token"); + + b.Property("UserId"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("Tokens"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.UserNotificationPreferences", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Agent"); + + b.Property("Enabled"); + + b.Property("UserId"); + + b.Property("Value"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserNotificationPreferences"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.UserQualityProfiles", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("RadarrQualityProfile"); + + b.Property("RadarrRootPath"); + + b.Property("SonarrQualityProfile"); + + b.Property("SonarrQualityProfileAnime"); + + b.Property("SonarrRootPath"); + + b.Property("SonarrRootPathAnime"); + + b.Property("UserId"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserQualityProfiles"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Votes", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Date"); + + b.Property("Deleted"); + + b.Property("RequestId"); + + b.Property("RequestType"); + + b.Property("UserId"); + + b.Property("VoteType"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("Votes"); + }); + + modelBuilder.Entity("Ombi.Store.Repository.Requests.EpisodeRequests", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("AirDate"); + + b.Property("Approved"); + + b.Property("Available"); + + b.Property("EpisodeNumber"); + + b.Property("Requested"); + + b.Property("SeasonId"); + + b.Property("Title"); + + b.Property("Url"); + + b.HasKey("Id"); + + b.HasIndex("SeasonId"); + + b.ToTable("EpisodeRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Repository.Requests.SeasonRequests", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ChildRequestId"); + + b.Property("SeasonNumber"); + + b.HasKey("Id"); + + b.HasIndex("ChildRequestId"); + + b.ToTable("SeasonRequests"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole") + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole") + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("Ombi.Store.Entities.OmbiUser") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("Ombi.Store.Entities.EmbyEpisode", b => + { + b.HasOne("Ombi.Store.Entities.EmbyContent", "Series") + .WithMany("Episodes") + .HasForeignKey("ParentId") + .HasPrincipalKey("EmbyId"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.NotificationUserId", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany("NotificationUserIds") + .HasForeignKey("UserId"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexEpisode", b => + { + b.HasOne("Ombi.Store.Entities.PlexServerContent", "Series") + .WithMany("Episodes") + .HasForeignKey("GrandparentKey") + .HasPrincipalKey("Key") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexSeasonsContent", b => + { + b.HasOne("Ombi.Store.Entities.PlexServerContent") + .WithMany("Seasons") + .HasForeignKey("PlexServerContentId"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.RequestSubscription", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.AlbumRequest", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "RequestedUser") + .WithMany() + .HasForeignKey("RequestedUserId"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.ChildRequests", b => + { + b.HasOne("Ombi.Store.Entities.Requests.TvRequests", "ParentRequest") + .WithMany("ChildRequests") + .HasForeignKey("ParentRequestId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("Ombi.Store.Entities.OmbiUser", "RequestedUser") + .WithMany() + .HasForeignKey("RequestedUserId"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.IssueComments", b => + { + b.HasOne("Ombi.Store.Entities.Requests.Issues", "Issues") + .WithMany("Comments") + .HasForeignKey("IssuesId"); + + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.Issues", b => + { + b.HasOne("Ombi.Store.Entities.Requests.IssueCategory", "IssueCategory") + .WithMany() + .HasForeignKey("IssueCategoryId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("Ombi.Store.Entities.Requests.ChildRequests") + .WithMany("Issues") + .HasForeignKey("IssueId"); + + b.HasOne("Ombi.Store.Entities.Requests.MovieRequests") + .WithMany("Issues") + .HasForeignKey("IssueId"); + + b.HasOne("Ombi.Store.Entities.OmbiUser", "UserReported") + .WithMany() + .HasForeignKey("UserReportedId"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.MovieRequests", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "RequestedUser") + .WithMany() + .HasForeignKey("RequestedUserId"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.RequestLog", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Tokens", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.UserNotificationPreferences", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany("UserNotificationPreferences") + .HasForeignKey("UserId"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.UserQualityProfiles", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Votes", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + }); + + modelBuilder.Entity("Ombi.Store.Repository.Requests.EpisodeRequests", b => + { + b.HasOne("Ombi.Store.Repository.Requests.SeasonRequests", "Season") + .WithMany("Episodes") + .HasForeignKey("SeasonId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("Ombi.Store.Repository.Requests.SeasonRequests", b => + { + b.HasOne("Ombi.Store.Entities.Requests.ChildRequests", "ChildRequest") + .WithMany("SeasonRequests") + .HasForeignKey("ChildRequestId") + .OnDelete(DeleteBehavior.Cascade); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Ombi.Store/Migrations/20190216231519_TvRequestsTotalSeasons.cs b/src/Ombi.Store/Migrations/20190216231519_TvRequestsTotalSeasons.cs new file mode 100644 index 000000000..0bae50c15 --- /dev/null +++ b/src/Ombi.Store/Migrations/20190216231519_TvRequestsTotalSeasons.cs @@ -0,0 +1,23 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Ombi.Store.Migrations +{ + public partial class TvRequestsTotalSeasons : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "TotalSeasons", + table: "TvRequests", + nullable: false, + defaultValue: 0); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "TotalSeasons", + table: "TvRequests"); + } + } +} diff --git a/src/Ombi.Store/Migrations/OmbiContextModelSnapshot.cs b/src/Ombi.Store/Migrations/OmbiContextModelSnapshot.cs index 9baf6712b..466011d43 100644 --- a/src/Ombi.Store/Migrations/OmbiContextModelSnapshot.cs +++ b/src/Ombi.Store/Migrations/OmbiContextModelSnapshot.cs @@ -14,7 +14,7 @@ namespace Ombi.Store.Migrations { #pragma warning disable 612, 618 modelBuilder - .HasAnnotation("ProductVersion", "2.2.0-rtm-35687"); + .HasAnnotation("ProductVersion", "2.2.1-servicing-10028"); modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => { @@ -583,6 +583,8 @@ namespace Ombi.Store.Migrations b.Property("RequestType"); + b.Property("RequestedByAlias"); + b.Property("RequestedDate"); b.Property("RequestedUserId"); @@ -621,6 +623,8 @@ namespace Ombi.Store.Migrations b.Property("RequestType"); + b.Property("RequestedByAlias"); + b.Property("RequestedDate"); b.Property("RequestedUserId"); @@ -749,6 +753,8 @@ namespace Ombi.Store.Migrations b.Property("RequestType"); + b.Property("RequestedByAlias"); + b.Property("RequestedDate"); b.Property("RequestedUserId"); @@ -813,6 +819,8 @@ namespace Ombi.Store.Migrations b.Property("Title"); + b.Property("TotalSeasons"); + b.Property("TvDbId"); b.HasKey("Id"); diff --git a/src/Ombi.Tests/TestStartup.cs b/src/Ombi.Tests/TestStartup.cs index fad346df0..07d54a936 100644 --- a/src/Ombi.Tests/TestStartup.cs +++ b/src/Ombi.Tests/TestStartup.cs @@ -1,71 +1,71 @@ -using System; -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Http.Features.Authentication; -using Microsoft.AspNetCore.Identity; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Options; -using Moq; -using Ombi.Api.Emby; -using Ombi.Api.Plex; -using Ombi.Core.Authentication; -using Ombi.Core.Settings; -using Ombi.Core.Settings.Models.External; -using Ombi.Models.Identity; -using Ombi.Store.Context; -using Ombi.Store.Entities; -using Ombi.Store.Repository; +//using System; +//using Microsoft.AspNetCore.Builder; +//using Microsoft.AspNetCore.Hosting; +//using Microsoft.AspNetCore.Http; +//using Microsoft.AspNetCore.Http.Features.Authentication; +//using Microsoft.AspNetCore.Identity; +//using Microsoft.Extensions.DependencyInjection; +//using Microsoft.Extensions.Options; +//using Moq; +//using Ombi.Api.Emby; +//using Ombi.Api.Plex; +//using Ombi.Core.Authentication; +//using Ombi.Core.Settings; +//using Ombi.Core.Settings.Models.External; +//using Ombi.Models.Identity; +//using Ombi.Store.Context; +//using Ombi.Store.Entities; +//using Ombi.Store.Repository; -namespace Ombi.Tests -{ - public class TestStartup - { - public IServiceProvider ConfigureServices(IServiceCollection services) - { - var _plexApi = new Mock(); - var _embyApi = new Mock(); - var _tokenSettings = new Mock>(); - var _embySettings = new Mock>(); - var _plexSettings = new Mock>(); - var audit = new Mock(); - var tokenRepo = new Mock(); +//namespace Ombi.Tests +//{ +// public class TestStartup +// { +// public IServiceProvider ConfigureServices(IServiceCollection services) +// { +// var _plexApi = new Mock(); +// var _embyApi = new Mock(); +// var _tokenSettings = new Mock>(); +// var _embySettings = new Mock>(); +// var _plexSettings = new Mock>(); +// var audit = new Mock(); +// var tokenRepo = new Mock(); - services.AddEntityFrameworkInMemoryDatabase() - .AddDbContext(); - services.AddIdentity() - .AddEntityFrameworkStores().AddUserManager(); +// services.AddEntityFrameworkInMemoryDatabase() +// .AddDbContext(); +// services.AddIdentity() +// .AddEntityFrameworkStores().AddUserManager(); - services.AddTransient(x => _plexApi.Object); - services.AddTransient(x => _embyApi.Object); - services.AddTransient(x => _tokenSettings.Object); - services.AddTransient(x => _embySettings.Object); - services.AddTransient(x => _plexSettings.Object); - services.AddTransient(x => audit.Object); - services.AddTransient(x => tokenRepo.Object); - // Taken from https://github.com/aspnet/MusicStore/blob/dev/test/MusicStore.Test/ManageControllerTest.cs (and modified) - var context = new DefaultHttpContext(); - context.Features.Set(new HttpAuthenticationFeature()); - services.AddSingleton(h => new HttpContextAccessor { HttpContext = context }); +// services.AddTransient(x => _plexApi.Object); +// services.AddTransient(x => _embyApi.Object); +// services.AddTransient(x => _tokenSettings.Object); +// services.AddTransient(x => _embySettings.Object); +// services.AddTransient(x => _plexSettings.Object); +// services.AddTransient(x => audit.Object); +// services.AddTransient(x => tokenRepo.Object); +// // Taken from https://github.com/aspnet/MusicStore/blob/dev/test/MusicStore.Test/ManageControllerTest.cs (and modified) +// var context = new DefaultHttpContext(); +// context.Features.Set(new HttpAuthenticationFeature()); +// services.AddSingleton(h => new HttpContextAccessor { HttpContext = context }); - services.Configure(options => - { - options.Password.RequireDigit = false; - options.Password.RequiredLength = 1; - options.Password.RequireLowercase = false; - options.Password.RequireNonAlphanumeric = false; - options.Password.RequireUppercase = false; - options.User.AllowedUserNameCharacters = string.Empty; - }); +// services.Configure(options => +// { +// options.Password.RequireDigit = false; +// options.Password.RequiredLength = 1; +// options.Password.RequireLowercase = false; +// options.Password.RequireNonAlphanumeric = false; +// options.Password.RequireUppercase = false; +// options.User.AllowedUserNameCharacters = string.Empty; +// }); - return services.BuildServiceProvider(); +// return services.BuildServiceProvider(); - } +// } - public void Configure(IApplicationBuilder app, IHostingEnvironment env) - { +// public void Configure(IApplicationBuilder app, IHostingEnvironment env) +// { - } - } -} \ No newline at end of file +// } +// } +//} \ No newline at end of file diff --git a/src/Ombi.Tests/TokenControllerTests.cs b/src/Ombi.Tests/TokenControllerTests.cs index ec0e616ac..0fb1e9200 100644 --- a/src/Ombi.Tests/TokenControllerTests.cs +++ b/src/Ombi.Tests/TokenControllerTests.cs @@ -1,60 +1,60 @@ -using System.Net.Http; -using System.Threading.Tasks; -using AutoMapper; -using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Http.Features.Authentication; -using Microsoft.AspNetCore.Identity; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Options; -using Moq; -using NUnit.Framework; -using Ombi.Api.Emby; -using Ombi.Api.Plex; -using Ombi.Controllers; -using Ombi.Core.Authentication; -using Ombi.Core.Settings; -using Ombi.Core.Settings.Models.External; -using Ombi.Models.Identity; -using Ombi.Notifications; -using Ombi.Schedule.Jobs.Ombi; -using Ombi.Settings.Settings.Models; -using Ombi.Settings.Settings.Models.Notifications; -using Ombi.Store.Context; -using Ombi.Store.Entities; -using Ombi.Store.Repository; -using Microsoft.AspNetCore.Hosting.Server; -using Microsoft.AspNetCore.TestHost; -using Newtonsoft.Json; -using Ombi.Models; +//using System.Net.Http; +//using System.Threading.Tasks; +//using AutoMapper; +//using Microsoft.AspNetCore.Hosting; +//using Microsoft.AspNetCore.Http; +//using Microsoft.AspNetCore.Http.Features.Authentication; +//using Microsoft.AspNetCore.Identity; +//using Microsoft.Extensions.DependencyInjection; +//using Microsoft.Extensions.Options; +//using Moq; +//using NUnit.Framework; +//using Ombi.Api.Emby; +//using Ombi.Api.Plex; +//using Ombi.Controllers; +//using Ombi.Core.Authentication; +//using Ombi.Core.Settings; +//using Ombi.Core.Settings.Models.External; +//using Ombi.Models.Identity; +//using Ombi.Notifications; +//using Ombi.Schedule.Jobs.Ombi; +//using Ombi.Settings.Settings.Models; +//using Ombi.Settings.Settings.Models.Notifications; +//using Ombi.Store.Context; +//using Ombi.Store.Entities; +//using Ombi.Store.Repository; +//using Microsoft.AspNetCore.Hosting.Server; +//using Microsoft.AspNetCore.TestHost; +//using Newtonsoft.Json; +//using Ombi.Models; -namespace Ombi.Tests -{ - [TestFixture] - [Ignore("TODO")] - public class TokenControllerTests - { - [SetUp] - public void Setup() - { - _testServer = new TestServer(new WebHostBuilder() - .UseStartup()); - _client = _testServer.CreateClient(); - } +//namespace Ombi.Tests +//{ +// [TestFixture] +// [Ignore("TODO")] +// public class TokenControllerTests +// { +// [SetUp] +// public void Setup() +// { +// _testServer = new TestServer(new WebHostBuilder() +// .UseStartup()); +// _client = _testServer.CreateClient(); +// } - private TestServer _testServer; - private HttpClient _client; +// private TestServer _testServer; +// private HttpClient _client; - [Test] - public async Task GetToken_FromValid_LocalUser() - { - var model = new UserAuthModel - { - Password = "a", - Username = "a" - }; - HttpResponseMessage response = await _client.PostAsync("/api/v1/token", new StringContent(JsonConvert.SerializeObject(model)) ); - } - } -} \ No newline at end of file +// [Test] +// public async Task GetToken_FromValid_LocalUser() +// { +// var model = new UserAuthModel +// { +// Password = "a", +// Username = "a" +// }; +// HttpResponseMessage response = await _client.PostAsync("/api/v1/token", new StringContent(JsonConvert.SerializeObject(model)) ); +// } +// } +//} \ No newline at end of file diff --git a/src/Ombi.TheMovieDbApi/IMovieDbApi.cs b/src/Ombi.TheMovieDbApi/IMovieDbApi.cs index 5fa5b73bd..43d8b02c1 100644 --- a/src/Ombi.TheMovieDbApi/IMovieDbApi.cs +++ b/src/Ombi.TheMovieDbApi/IMovieDbApi.cs @@ -19,5 +19,7 @@ namespace Ombi.Api.TheMovieDb Task Find(string externalId, ExternalSource source); Task GetTvExternals(int theMovieDbId); Task GetTVInfo(string themoviedbid); + Task> SearchByActor(string searchTerm, string langCode); + Task GetActorMovieCredits(int actorId, string langCode); } } \ No newline at end of file diff --git a/src/Ombi.TheMovieDbApi/Models/ActorCredits.cs b/src/Ombi.TheMovieDbApi/Models/ActorCredits.cs new file mode 100644 index 000000000..cb27bc677 --- /dev/null +++ b/src/Ombi.TheMovieDbApi/Models/ActorCredits.cs @@ -0,0 +1,51 @@ +namespace Ombi.Api.TheMovieDb.Models +{ + public class ActorCredits + { + public Cast[] cast { get; set; } + public Crew[] crew { get; set; } + public int id { get; set; } + } + + public class Cast + { + public string character { get; set; } + public string credit_id { get; set; } + public string poster_path { get; set; } + public int id { get; set; } + public bool video { get; set; } + public int vote_count { get; set; } + public bool adult { get; set; } + public string backdrop_path { get; set; } + public int?[] genre_ids { get; set; } + public string original_language { get; set; } + public string original_title { get; set; } + public float popularity { get; set; } + public string title { get; set; } + public float vote_average { get; set; } + public string overview { get; set; } + public string release_date { get; set; } + } + + public class Crew + { + public int id { get; set; } + public string department { get; set; } + public string original_language { get; set; } + public string original_title { get; set; } + public string job { get; set; } + public string overview { get; set; } + public int vote_count { get; set; } + public bool video { get; set; } + public string release_date { get; set; } + public float vote_average { get; set; } + public string title { get; set; } + public float popularity { get; set; } + public int?[] genre_ids { get; set; } + public string backdrop_path { get; set; } + public bool adult { get; set; } + public string poster_path { get; set; } + public string credit_id { get; set; } + } + +} \ No newline at end of file diff --git a/src/Ombi.TheMovieDbApi/Models/ActorSearchResult.cs b/src/Ombi.TheMovieDbApi/Models/ActorSearchResult.cs new file mode 100644 index 000000000..b16b35ab9 --- /dev/null +++ b/src/Ombi.TheMovieDbApi/Models/ActorSearchResult.cs @@ -0,0 +1,33 @@ +namespace Ombi.Api.TheMovieDb.Models +{ + + public class ActorResult + { + public float popularity { get; set; } + public int id { get; set; } + public string profile_path { get; set; } + public string name { get; set; } + public Known_For[] known_for { get; set; } + public bool adult { get; set; } + } + + public class Known_For + { + public float vote_average { get; set; } + public int vote_count { get; set; } + public int id { get; set; } + public bool video { get; set; } + public string media_type { get; set; } + public string title { get; set; } + public float popularity { get; set; } + public string poster_path { get; set; } + public string original_language { get; set; } + public string original_title { get; set; } + public int[] genre_ids { get; set; } + public string backdrop_path { get; set; } + public bool adult { get; set; } + public string overview { get; set; } + public string release_date { get; set; } + } + +} \ No newline at end of file diff --git a/src/Ombi.TheMovieDbApi/TheMovieDbApi.cs b/src/Ombi.TheMovieDbApi/TheMovieDbApi.cs index 0500171c9..79ccc5bb7 100644 --- a/src/Ombi.TheMovieDbApi/TheMovieDbApi.cs +++ b/src/Ombi.TheMovieDbApi/TheMovieDbApi.cs @@ -43,6 +43,27 @@ namespace Ombi.Api.TheMovieDb return await Api.Request(request); } + public async Task> SearchByActor(string searchTerm, string langCode) + { + var request = new Request($"search/person", BaseUri, HttpMethod.Get); + request.FullUri = request.FullUri.AddQueryParameter("api_key", ApiToken); + request.FullUri = request.FullUri.AddQueryParameter("query", searchTerm); + request.FullUri = request.FullUri.AddQueryParameter("language", langCode); + + var result = await Api.Request>(request); + return result; + } + + public async Task GetActorMovieCredits(int actorId, string langCode) + { + var request = new Request($"person/{actorId}/movie_credits", BaseUri, HttpMethod.Get); + request.FullUri = request.FullUri.AddQueryParameter("api_key", ApiToken); + request.FullUri = request.FullUri.AddQueryParameter("language", langCode); + + var result = await Api.Request(request); + return result; + } + public async Task> SearchTv(string searchTerm) { var request = new Request($"search/tv", BaseUri, HttpMethod.Get); diff --git a/src/Ombi/ApiKeyMiddlewear.cs b/src/Ombi/ApiKeyMiddlewear.cs index f3c956df4..e8fa02d78 100644 --- a/src/Ombi/ApiKeyMiddlewear.cs +++ b/src/Ombi/ApiKeyMiddlewear.cs @@ -8,6 +8,7 @@ using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; using Ombi.Core.Authentication; using Ombi.Core.Settings; +using Ombi.Helpers; using Ombi.Settings.Settings.Models; namespace Ombi @@ -98,6 +99,10 @@ namespace Ombi if (context.Request.Headers.Keys.Contains("UserName", StringComparer.InvariantCultureIgnoreCase)) { var username = context.Request.Headers["UserName"].FirstOrDefault(); + if (username.IsNullOrEmpty()) + { + UseApiUser(context); + } var um = context.RequestServices.GetService(); var user = await um.Users.FirstOrDefaultAsync(x => x.UserName.Equals(username, StringComparison.InvariantCultureIgnoreCase)); @@ -114,13 +119,18 @@ namespace Ombi } else { - var identity = new GenericIdentity("API"); - var principal = new GenericPrincipal(identity, new[] { "Admin", "ApiUser" }); - context.User = principal; + UseApiUser(context); } await next.Invoke(context); } } + + private void UseApiUser(HttpContext context) + { + var identity = new GenericIdentity("API"); + var principal = new GenericPrincipal(identity, new[] { "Admin", "ApiUser" }); + context.User = principal; + } } } \ No newline at end of file diff --git a/src/Ombi/ClientApp/app/app.component.ts b/src/Ombi/ClientApp/app/app.component.ts index d865e6604..7005f147c 100644 --- a/src/Ombi/ClientApp/app/app.component.ts +++ b/src/Ombi/ClientApp/app/app.component.ts @@ -4,7 +4,7 @@ import { NavigationStart, Router } from "@angular/router"; import { TranslateService } from "@ngx-translate/core"; import { AuthService } from "./auth/auth.service"; import { ILocalUser } from "./auth/IUserLogin"; -import { IdentityService, NotificationService } from "./services"; +import { CustomPageService, IdentityService, NotificationService } from "./services"; import { JobService, SettingsService } from "./services"; import { ICustomizationSettings, ICustomPage } from "./interfaces"; @@ -35,7 +35,8 @@ export class AppComponent implements OnInit { private readonly jobService: JobService, public readonly translate: TranslateService, private readonly identityService: IdentityService, - private readonly platformLocation: PlatformLocation) { + private readonly platformLocation: PlatformLocation, + private readonly customPageService: CustomPageService) { const base = this.platformLocation.getBaseHrefFromDOM(); if (base.length > 1) { @@ -57,7 +58,7 @@ export class AppComponent implements OnInit { this.settingsService.getCustomization().subscribe(x => { this.customizationSettings = x; if(this.customizationSettings.useCustomPage) { - this.settingsService.getCustomPage().subscribe(c => { + this.customPageService.getCustomPage().subscribe(c => { this.customPageSettings = c; if(!this.customPageSettings.title) { this.customPageSettings.title = "Custom Page"; diff --git a/src/Ombi/ClientApp/app/app.module.ts b/src/Ombi/ClientApp/app/app.module.ts index 6917cc85b..a68405f75 100644 --- a/src/Ombi/ClientApp/app/app.module.ts +++ b/src/Ombi/ClientApp/app/app.module.ts @@ -39,7 +39,7 @@ import { ImageService } from "./services"; import { LandingPageService } from "./services"; import { NotificationService } from "./services"; import { SettingsService } from "./services"; -import { IssuesService, JobService, PlexTvService, StatusService } from "./services"; +import { CustomPageService, IssuesService, JobService, PlexTvService, StatusService } from "./services"; const routes: Routes = [ { path: "*", component: PageNotFoundComponent }, @@ -144,6 +144,7 @@ export function JwtTokenGetter() { JobService, IssuesService, PlexTvService, + CustomPageService, ], bootstrap: [AppComponent], }) diff --git a/src/Ombi/ClientApp/app/custompage/custompage.component.ts b/src/Ombi/ClientApp/app/custompage/custompage.component.ts index f346bef2b..61094e793 100644 --- a/src/Ombi/ClientApp/app/custompage/custompage.component.ts +++ b/src/Ombi/ClientApp/app/custompage/custompage.component.ts @@ -2,7 +2,7 @@ import { FormBuilder, FormGroup, Validators } from "@angular/forms"; import { DomSanitizer } from "@angular/platform-browser"; import { AuthService } from "../auth/auth.service"; -import { NotificationService, SettingsService } from "../services"; +import { CustomPageService, NotificationService } from "../services"; @Component({ templateUrl: "./custompage.component.html", @@ -14,7 +14,7 @@ export class CustomPageComponent implements OnInit { public isEditing: boolean; public isAdmin: boolean; - constructor(private auth: AuthService, private settings: SettingsService, private fb: FormBuilder, + constructor(private auth: AuthService, private settings: CustomPageService, private fb: FormBuilder, private notificationService: NotificationService, private sanitizer: DomSanitizer) { } @@ -29,7 +29,7 @@ export class CustomPageComponent implements OnInit { fontAwesomeIcon: [x.fontAwesomeIcon, [Validators.required]], }); }); - this.isAdmin = this.auth.hasRole("admin") || this.auth.hasRole("poweruser"); + this.isAdmin = this.auth.hasRole("EditCustomPage"); } public onSubmit() { diff --git a/src/Ombi/ClientApp/app/interfaces/IRequestModel.ts b/src/Ombi/ClientApp/app/interfaces/IRequestModel.ts index 343db5acc..f187db0b8 100644 --- a/src/Ombi/ClientApp/app/interfaces/IRequestModel.ts +++ b/src/Ombi/ClientApp/app/interfaces/IRequestModel.ts @@ -87,6 +87,7 @@ export interface IBaseRequest { requestedUser: IUser; canApprove: boolean; title: string; + requestedByAlias: string; } export interface ITvRequests { @@ -145,6 +146,7 @@ export interface IEpisodesRequests { episodeNumber: number; title: string; airDate: Date; + airDateDisplay: string; url: string; available: boolean; requested: boolean; diff --git a/src/Ombi/ClientApp/app/interfaces/ISettings.ts b/src/Ombi/ClientApp/app/interfaces/ISettings.ts index 1f62a2c8d..070dabb8d 100644 --- a/src/Ombi/ClientApp/app/interfaces/ISettings.ts +++ b/src/Ombi/ClientApp/app/interfaces/ISettings.ts @@ -41,6 +41,7 @@ export interface IEmbyServer extends IExternalSettings { apiKey: string; administratorId: string; enableEpisodeSearching: boolean; + serverHostname: string; } export interface IPlexSettings extends ISettings { diff --git a/src/Ombi/ClientApp/app/login/login.component.ts b/src/Ombi/ClientApp/app/login/login.component.ts index 4a9ad4aaf..34edcd687 100644 --- a/src/Ombi/ClientApp/app/login/login.component.ts +++ b/src/Ombi/ClientApp/app/login/login.component.ts @@ -161,7 +161,8 @@ export class LoginComponent implements OnDestroy, OnInit { } }, err => { - this.notify.error(err.statusText); + console.log(err); + this.notify.error(err.body); this.router.navigate(["login"]); }); diff --git a/src/Ombi/ClientApp/app/requests/movierequests.component.html b/src/Ombi/ClientApp/app/requests/movierequests.component.html index f8ea31950..6f3b4dd00 100644 --- a/src/Ombi/ClientApp/app/requests/movierequests.component.html +++ b/src/Ombi/ClientApp/app/requests/movierequests.component.html @@ -1,36 +1,39 @@
- + -