diff --git a/Ombi.Api.Models/Movie/TmdbMovieDetails.cs b/Ombi.Api.Models/Movie/TmdbMovieDetails.cs new file mode 100644 index 000000000..4d987ac02 --- /dev/null +++ b/Ombi.Api.Models/Movie/TmdbMovieDetails.cs @@ -0,0 +1,104 @@ +#region Copyright +// /************************************************************************ +// Copyright (c) 2017 Jamie Rees +// File: TmdbMovieDetails.cs +// Created By: Jamie Rees +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// ************************************************************************/ +#endregion + +using System.Collections.Generic; + +namespace Ombi.Api.Models.Movie +{ + + public class Genre + { + public int id { get; set; } + public string name { get; set; } + } + + public class ProductionCompany + { + public string name { get; set; } + public int id { get; set; } + } + + public class ProductionCountry + { + public string iso_3166_1 { get; set; } + public string name { get; set; } + } + + public class SpokenLanguage + { + public string iso_639_1 { get; set; } + public string name { get; set; } + } + + public class Result + { + public string id { get; set; } + public string iso_639_1 { get; set; } + public string iso_3166_1 { get; set; } + public string key { get; set; } + public string name { get; set; } + public string site { get; set; } + public int size { get; set; } + public string type { get; set; } + } + + public class Videos + { + public List results { get; set; } + } + + public class TmdbMovieDetails + { + public bool adult { get; set; } + public string backdrop_path { get; set; } + public object belongs_to_collection { get; set; } + public int budget { get; set; } + public List genres { get; set; } + public string homepage { get; set; } + public int id { get; set; } + public string imdb_id { get; set; } + public string original_language { get; set; } + public string original_title { get; set; } + public string overview { get; set; } + public double popularity { get; set; } + public string poster_path { get; set; } + public List production_companies { get; set; } + public List production_countries { get; set; } + public string release_date { get; set; } + public int revenue { get; set; } + public int runtime { get; set; } + public List spoken_languages { get; set; } + public string status { get; set; } + public string tagline { get; set; } + public string title { get; set; } + public bool video { get; set; } + public double vote_average { get; set; } + public int vote_count { get; set; } + public Videos videos { get; set; } + } + +} \ No newline at end of file diff --git a/Ombi.Api.Models/Ombi.Api.Models.csproj b/Ombi.Api.Models/Ombi.Api.Models.csproj index c180f5624..39df12460 100644 --- a/Ombi.Api.Models/Ombi.Api.Models.csproj +++ b/Ombi.Api.Models/Ombi.Api.Models.csproj @@ -54,6 +54,7 @@ + diff --git a/Ombi.Api.Models/Radarr/RadarrMovieResponse.cs b/Ombi.Api.Models/Radarr/RadarrMovieResponse.cs index 69e48af23..9b5bf0c2b 100644 --- a/Ombi.Api.Models/Radarr/RadarrMovieResponse.cs +++ b/Ombi.Api.Models/Radarr/RadarrMovieResponse.cs @@ -47,7 +47,7 @@ namespace Ombi.Api.Models.Radarr { public string title { get; set; } public string sortTitle { get; set; } - public int sizeOnDisk { get; set; } + public double sizeOnDisk { get; set; } public string status { get; set; } public string overview { get; set; } public string inCinemas { get; set; } diff --git a/Ombi.Api/MovieBase.cs b/Ombi.Api/MovieBase.cs index c21bfcbd2..5d4c820b7 100644 --- a/Ombi.Api/MovieBase.cs +++ b/Ombi.Api/MovieBase.cs @@ -32,6 +32,8 @@ namespace Ombi.Api public abstract class MovieBase { private static readonly string Encrypted = "0T3QNSseexLO7n7UPiJvl70Y+KKnvbeTlsusl7Kwq0hPH0BHOuFNGwksNCjkwqWedyDdI/MJeUR4wtL4bIl0Z+//uHXEaYM/4H2pjeLbH5EWdUe5TTj1AhaIR5PQweamvcienRyFD/3YPCC/+qL5mHkKXBkPumMod3Zb/4yN0Ik="; - protected string ApiKey = StringCipher.Decrypt(Encrypted, "ApiKey"); + private string _apiKey; + + protected string ApiKey => _apiKey ?? (_apiKey = StringCipher.Decrypt(Encrypted, "ApiKey")); } } diff --git a/Ombi.Api/TheMovieDbApi.cs b/Ombi.Api/TheMovieDbApi.cs index 6ccd775dd..ad3f01251 100644 --- a/Ombi.Api/TheMovieDbApi.cs +++ b/Ombi.Api/TheMovieDbApi.cs @@ -25,12 +25,18 @@ // ************************************************************************/ #endregion +using System; using System.Collections.Generic; using System.Threading.Tasks; +using NLog; +using NLog.Fluent; +using Ombi.Api.Models.Movie; +using RestSharp; using TMDbLib.Client; using TMDbLib.Objects.General; using TMDbLib.Objects.Movies; using TMDbLib.Objects.Search; +using Movie = TMDbLib.Objects.Movies.Movie; namespace Ombi.Api { @@ -39,9 +45,13 @@ namespace Ombi.Api public TheMovieDbApi() { Client = new TMDbClient(ApiKey); + Api = new ApiRequest(); } + private ApiRequest Api { get; } public TMDbClient Client { get; set; } + private const string BaseUrl = "https://api.themoviedb.org/3/"; + private static Logger Log = LogManager.GetCurrentClassLogger(); public async Task> SearchMovie(string searchTerm) { var results = await Client.SearchMovie(searchTerm); @@ -56,7 +66,27 @@ namespace Ombi.Api public async Task> GetUpcomingMovies() { var movies = await Client.GetMovieList(MovieListType.Upcoming); - return movies?.Results ?? new List(); + return movies?.Results ?? new List(); + } + + public TmdbMovieDetails GetMovieInformationWithVideos(int tmdbId) + { + var request = new RestRequest { Resource = "movie/{movieId}", Method = Method.GET }; + request.AddUrlSegment("movieId", tmdbId.ToString()); + request.AddQueryParameter("api_key", ApiKey); + request.AddQueryParameter("append_to_response", "videos"); // Get the videos + + try + { + + var obj = Api.ExecuteJson(request, new Uri(BaseUrl)); + return obj; + } + catch (Exception e) + { + Log.Error(e); + return null; + } } public async Task GetMovieInformation(int tmdbId) diff --git a/Ombi.Core.Migration/Migrations/Version2200.cs b/Ombi.Core.Migration/Migrations/Version2200.cs new file mode 100644 index 000000000..a28f852de --- /dev/null +++ b/Ombi.Core.Migration/Migrations/Version2200.cs @@ -0,0 +1,64 @@ +#region Copyright + +// /************************************************************************ +// Copyright (c) 2016 Jamie Rees +// File: Version1100.cs +// Created By: Jamie Rees +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// ************************************************************************/ + +#endregion + +using System.Data; +using NLog; +using Ombi.Core.SettingModels; + +namespace Ombi.Core.Migration.Migrations +{ + [Migration(22000, "v2.20.0.0")] + public class Version2200 : BaseMigration, IMigration + { + public Version2200(ISettingsService custom) + { + Customization = custom; + } + + public int Version => 22000; + private ISettingsService Customization { get; set; } + + + private static Logger Logger = LogManager.GetCurrentClassLogger(); + + public void Start(IDbConnection con) + { + //UpdateCustomSettings(); Turned off the migration for now until the search has been improved on. + //UpdateSchema(con, Version); + } + + private void UpdateCustomSettings() + { + var settings = Customization.GetSettings(); + settings.NewSearch = true; // Use the new search + + Customization.SaveSettings(settings); + } + } +} diff --git a/Ombi.Core.Migration/Ombi.Core.Migration.csproj b/Ombi.Core.Migration/Ombi.Core.Migration.csproj index 222f18fde..06dfda84d 100644 --- a/Ombi.Core.Migration/Ombi.Core.Migration.csproj +++ b/Ombi.Core.Migration/Ombi.Core.Migration.csproj @@ -69,6 +69,7 @@ + diff --git a/Ombi.Core/SettingModels/CustomizationSettings.cs b/Ombi.Core/SettingModels/CustomizationSettings.cs index 2fa664f35..d7aff1e51 100644 --- a/Ombi.Core/SettingModels/CustomizationSettings.cs +++ b/Ombi.Core/SettingModels/CustomizationSettings.cs @@ -53,5 +53,7 @@ namespace Ombi.Core.SettingModels public int DefaultLang { get; set; } + public bool NewSearch { get; set; } + } } \ No newline at end of file diff --git a/Ombi.Core/SettingModels/EmailNotificationSettings.cs b/Ombi.Core/SettingModels/EmailNotificationSettings.cs index 65f55a61a..672588922 100644 --- a/Ombi.Core/SettingModels/EmailNotificationSettings.cs +++ b/Ombi.Core/SettingModels/EmailNotificationSettings.cs @@ -34,7 +34,6 @@ namespace Ombi.Core.SettingModels public string EmailSender { get; set; } public string EmailUsername { get; set; } public bool Authentication { get; set; } - public bool EnableUserEmailNotifications { get; set; } public string RecipientEmail { get; set; } } } \ No newline at end of file diff --git a/Ombi.Core/SettingModels/SonarrSettings.cs b/Ombi.Core/SettingModels/SonarrSettings.cs index ec2edb49a..d8ab8f991 100644 --- a/Ombi.Core/SettingModels/SonarrSettings.cs +++ b/Ombi.Core/SettingModels/SonarrSettings.cs @@ -32,6 +32,13 @@ namespace Ombi.Core.SettingModels public string ApiKey { get; set; } public string QualityProfile { get; set; } public bool SeasonFolders { get; set; } + /// + /// This is the root path ID + /// + /// + /// The root path. + /// public string RootPath { get; set; } + public string FullRootPath { get; set; } } } \ No newline at end of file diff --git a/Ombi.Core/TvSender.cs b/Ombi.Core/TvSender.cs index 14146c17f..3f6d5f86e 100644 --- a/Ombi.Core/TvSender.cs +++ b/Ombi.Core/TvSender.cs @@ -85,7 +85,7 @@ namespace Ombi.Core var latest = model.SeasonsRequested?.Equals("Latest", StringComparison.CurrentCultureIgnoreCase); var specificSeasonRequest = model.SeasonList?.Any(); - var rootFolderPath = model.RootFolderSelected <= 0 ? sonarrSettings.RootPath : await GetRootPath(model.RootFolderSelected, sonarrSettings); + var rootFolderPath = model.RootFolderSelected <= 0 ? sonarrSettings.FullRootPath : await GetRootPath(model.RootFolderSelected, sonarrSettings); if (episodeRequest) { diff --git a/Ombi.Core/TvSenderOld.cs b/Ombi.Core/TvSenderOld.cs index 6d819753e..d3423e291 100644 --- a/Ombi.Core/TvSenderOld.cs +++ b/Ombi.Core/TvSenderOld.cs @@ -70,7 +70,7 @@ namespace Ombi.Core { int.TryParse(sonarrSettings.QualityProfile, out qualityProfile); } - var rootFolderPath = model.RootFolderSelected <= 0 ? sonarrSettings.RootPath : await GetRootPath(model.RootFolderSelected, sonarrSettings); + var rootFolderPath = model.RootFolderSelected <= 0 ? sonarrSettings.FullRootPath : await GetRootPath(model.RootFolderSelected, sonarrSettings); var series = await GetSonarrSeries(sonarrSettings, model.ProviderId); diff --git a/Ombi.Services/Jobs/RadarrCacher.cs b/Ombi.Services/Jobs/RadarrCacher.cs index 7273fb626..fc7338ecf 100644 --- a/Ombi.Services/Jobs/RadarrCacher.cs +++ b/Ombi.Services/Jobs/RadarrCacher.cs @@ -66,7 +66,15 @@ namespace Ombi.Services.Jobs var movies = RadarrApi.GetMovies(settings.ApiKey, settings.FullUri); if (movies != null) { - var movieIds = movies.Select(x => x.tmdbId).ToList(); + var movieIds = new List(); + foreach (var m in movies) + { + if (m.tmdbId > 0) + { + movieIds.Add(m.tmdbId); + } + } + //var movieIds = movies.Select(x => x.tmdbId).ToList(); Cache.Set(CacheKeys.RadarrMovies, movieIds, CacheKeys.TimeFrameMinutes.SchedulerCaching); } } diff --git a/Ombi.Services/Notification/EmailMessageNotification.cs b/Ombi.Services/Notification/EmailMessageNotification.cs index 1de8ef7e6..729726eef 100644 --- a/Ombi.Services/Notification/EmailMessageNotification.cs +++ b/Ombi.Services/Notification/EmailMessageNotification.cs @@ -119,14 +119,6 @@ namespace Ombi.Services.Notification return false; } - if (!settings.EnableUserEmailNotifications) - { - if (!settings.Enabled) - { - return false; - } - } - return true; } @@ -237,10 +229,6 @@ namespace Ombi.Services.Notification private async Task EmailAvailableRequest(NotificationModel model, EmailNotificationSettings settings) { - if (!settings.EnableUserEmailNotifications) - { - await Task.FromResult(false); - } var email = new EmailBasicTemplate(); var html = email.LoadTemplate( $"Ombi: {model.Title} is now available!", diff --git a/Ombi.Services/Notification/NotificationEngine.cs b/Ombi.Services/Notification/NotificationEngine.cs index 01b50898b..49340ca1a 100644 --- a/Ombi.Services/Notification/NotificationEngine.cs +++ b/Ombi.Services/Notification/NotificationEngine.cs @@ -154,7 +154,25 @@ namespace Ombi.Services.Notification // Get the usernames or alias depending if they have an alias var userNamesWithFeature = users.Select(x => x.UsernameOrAlias).ToList(); + Log.Debug("Users with the feature count {0}", userNamesWithFeature.Count); + Log.Debug("Usernames: "); + foreach (var u in userNamesWithFeature) + { + Log.Debug(u); + } + Log.Debug("Users in the requested model count: {0}", model.AllUsers.Count); + Log.Debug("usernames from model: "); + foreach (var modelAllUser in model.AllUsers) + { + Log.Debug(modelAllUser); + } + + if (model.AllUsers == null || !model.AllUsers.Any()) + { + Log.Debug("There are no users in the model.AllUsers, no users to notify"); + return; + } var usersToNotify = userNamesWithFeature.Intersect(model.AllUsers, StringComparer.CurrentCultureIgnoreCase).ToList(); if (!usersToNotify.Any()) diff --git a/Ombi.Store/RequestedModel.cs b/Ombi.Store/RequestedModel.cs index 6d0342a14..c54d68e5c 100644 --- a/Ombi.Store/RequestedModel.cs +++ b/Ombi.Store/RequestedModel.cs @@ -27,9 +27,6 @@ namespace Ombi.Store public string Status { get; set; } public bool Approved { get; set; } - [Obsolete("Use RequestedUsers")] //TODO remove this obsolete property - public string RequestedBy { get; set; } - public DateTime RequestedDate { get; set; } public bool Available { get; set; } public IssueState Issues { get; set; } @@ -60,14 +57,9 @@ namespace Ombi.Store get { var u = new List(); - if (!string.IsNullOrEmpty(RequestedBy)) - { - u.Add(RequestedBy); - } - if (RequestedUsers != null && RequestedUsers.Any()) { - u.AddRange(RequestedUsers.Where(requestedUser => requestedUser != RequestedBy)); + u.AddRange(RequestedUsers); } return u; } diff --git a/Ombi.UI/Content/search.js b/Ombi.UI/Content/search.js index b8f9f5504..fde3077e4 100644 --- a/Ombi.UI/Content/search.js +++ b/Ombi.UI/Content/search.js @@ -24,7 +24,8 @@ Function.prototype.bind = function (parent) { $(function () { - var searchSource = $("#search-template").html(); + var useNewSearch = $('#useNewSearch').text() == 'True'; + var searchSource = useNewSearch ? $("#search-templateNew").html() : $("#search-template").html(); var seasonsSource = $("#seasons-template").html(); var musicSource = $("#music-template").html(); var seasonsNumberSource = $("#seasonNumber-template").html(); @@ -470,7 +471,11 @@ $(function () { requested: result.requested, approved: result.approved, available: result.available, - url: result.plexUrl + url: result.plexUrl, + trailer: result.trailer, + homepage: result.homepage, + releaseDate: Humanize(result.releaseDate), + status: result.status }; return context; diff --git a/Ombi.UI/Models/SearchLoadViewModel.cs b/Ombi.UI/Models/SearchLoadViewModel.cs new file mode 100644 index 000000000..2bdf5078c --- /dev/null +++ b/Ombi.UI/Models/SearchLoadViewModel.cs @@ -0,0 +1,37 @@ +#region Copyright +// /************************************************************************ +// Copyright (c) 2017 Jamie Rees +// File: SearchLoadViewModel.cs +// Created By: Jamie Rees +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// ************************************************************************/ +#endregion + +using Ombi.Core.SettingModels; + +namespace Ombi.UI.Models +{ + public class SearchLoadViewModel + { + public PlexRequestSettings Settings { get; set; } + public CustomizationSettings CustomizationSettings { get; set; } + } +} \ No newline at end of file diff --git a/Ombi.UI/Models/SearchMovieViewModel.cs b/Ombi.UI/Models/SearchMovieViewModel.cs index d0d71bfd9..445f8b3b4 100644 --- a/Ombi.UI/Models/SearchMovieViewModel.cs +++ b/Ombi.UI/Models/SearchMovieViewModel.cs @@ -47,5 +47,8 @@ namespace Ombi.UI.Models public double VoteAverage { get; set; } public int VoteCount { get; set; } public bool AlreadyInCp { get; set; } + public string Trailer { get; set; } + public string Homepage { get; set; } + public string ImdbId { get; set; } } } \ No newline at end of file diff --git a/Ombi.UI/Modules/Admin/AdminModule.cs b/Ombi.UI/Modules/Admin/AdminModule.cs index 0a6f1c7e0..97a610441 100644 --- a/Ombi.UI/Modules/Admin/AdminModule.cs +++ b/Ombi.UI/Modules/Admin/AdminModule.cs @@ -211,8 +211,8 @@ namespace Ombi.UI.Modules.Admin Get["/headphones"] = _ => Headphones(); Post["/headphones"] = _ => SaveHeadphones(); - Get["/newsletter"] = _ => Newsletter(); - Post["/newsletter"] = _ => SaveNewsletter(); + Get["/newsletter", true] = async (x, ct) => await Newsletter(); + Post["/newsletter", true] = async (x, ct) => await SaveNewsletter(); Post["/createapikey"] = x => CreateApiKey(); @@ -845,13 +845,13 @@ namespace Ombi.UI.Modules.Admin : new JsonResponseModel { Result = false, Message = "Could not update the settings, take a look at the logs." }); } - private Negotiator Newsletter() + private async Task Newsletter() { - var settings = NewsLetterService.GetSettings(); + var settings = await NewsLetterService.GetSettingsAsync(); return View["NewsletterSettings", settings]; } - private Response SaveNewsletter() + private async Task SaveNewsletter() { var settings = this.Bind(); @@ -859,9 +859,17 @@ namespace Ombi.UI.Modules.Admin if (!valid.IsValid) { var error = valid.SendJsonError(); - Log.Info("Error validating Headphones settings, message: {0}", error.Message); + Log.Info("Error validating Newsletter settings, message: {0}", error.Message); return Response.AsJson(error); } + + // Make sure emails are setup + var emailSettings = await EmailService.GetSettingsAsync(); + if (!emailSettings.Enabled) + { + return Response.AsJson(new JsonResponseModel { Result = false, Message = "Please enable your email notifications" }); + } + settings.SendRecentlyAddedEmail = settings.SendRecentlyAddedEmail; var result = NewsLetterService.SaveSettings(settings); diff --git a/Ombi.UI/Modules/SearchModule.cs b/Ombi.UI/Modules/SearchModule.cs index fb95ea1e0..4aa29c316 100644 --- a/Ombi.UI/Modules/SearchModule.cs +++ b/Ombi.UI/Modules/SearchModule.cs @@ -77,7 +77,7 @@ namespace Ombi.UI.Modules ISettingsService plexService, ISettingsService auth, IRepository u, ISettingsService email, IIssueService issue, IAnalytics a, IRepository rl, ITransientFaultQueue tfQueue, IRepository content, - ISecurityExtensions security, IMovieSender movieSender, IRadarrCacher radarrCacher, ITraktApi traktApi) + ISecurityExtensions security, IMovieSender movieSender, IRadarrCacher radarrCacher, ITraktApi traktApi, ISettingsService cus) : base("search", prSettings, security) { Auth = auth; @@ -111,6 +111,7 @@ namespace Ombi.UI.Modules WatcherCacher = watcherCacher; RadarrCacher = radarrCacher; TraktApi = traktApi; + CustomizationSettings = cus; Get["SearchIndex", "/", true] = async (x, ct) => await RequestLoad(); @@ -169,14 +170,22 @@ namespace Ombi.UI.Modules private ITransientFaultQueue FaultQueue { get; } private IRepository RequestLimitRepo { get; } private IRadarrCacher RadarrCacher { get; } + private ISettingsService CustomizationSettings { get; } private static Logger Log = LogManager.GetCurrentClassLogger(); private async Task RequestLoad() { var settings = await PrService.GetSettingsAsync(); + var custom = await CustomizationSettings.GetSettingsAsync(); + var searchViewModel = new SearchLoadViewModel + { + Settings = settings, + CustomizationSettings = custom + }; + - return View["Search/Index", settings]; + return View["Search/Index", searchViewModel]; } private async Task UpcomingMovies() @@ -266,17 +275,6 @@ namespace Ombi.UI.Modules var counter = 0; foreach (var movie in apiMovies) { - var imdbId = string.Empty; - if (counter <= 5) // Let's only do it for the first 5 items - { - var movieInfoTask = await MovieApi.GetMovieInformation(movie.Id).ConfigureAwait(false); - - // TODO needs to be careful about this, it's adding extra time to search... - // https://www.themoviedb.org/talk/5807f4cdc3a36812160041f2 - imdbId = movieInfoTask?.ImdbId; - counter++; - } - var viewMovie = new SearchMovieViewModel { Adult = movie.Adult, @@ -294,6 +292,28 @@ namespace Ombi.UI.Modules VoteAverage = movie.VoteAverage, VoteCount = movie.VoteCount }; + + var imdbId = string.Empty; + if (counter <= 5) // Let's only do it for the first 5 items + { + var movieInfo = MovieApi.GetMovieInformationWithVideos(movie.Id); + + // TODO needs to be careful about this, it's adding extra time to search... + // https://www.themoviedb.org/talk/5807f4cdc3a36812160041f2 + viewMovie.ImdbId = movieInfo?.imdb_id; + viewMovie.Homepage = movieInfo?.homepage; + var videoId = movieInfo?.video ?? false + ? movieInfo?.videos?.results?.FirstOrDefault()?.key + : string.Empty; + + viewMovie.Trailer = string.IsNullOrEmpty(videoId) + ? string.Empty + : $"https://www.youtube.com/watch?v={videoId}"; + + counter++; + } + + var canSee = CanUserSeeThisRequest(viewMovie.Id, Security.HasPermissions(User, Permissions.UsersCanViewOnlyOwnRequests), dbMovies); var plexMovie = Checker.GetMovie(plexMovies.ToArray(), movie.Title, movie.ReleaseDate?.Year.ToString(), imdbId); @@ -989,6 +1009,11 @@ namespace Ombi.UI.Modules existingRequest.Episodes.AddRange(newEpisodes ?? Enumerable.Empty()); // It's technically a new request now, so set the status to not approved. + var autoApprove = ShouldAutoApprove(RequestType.TvShow); + if (autoApprove) + { + return await SendTv(model, sonarrSettings, existingRequest, fullShowName, settings); + } existingRequest.Approved = false; return await AddUserToRequest(existingRequest, settings, fullShowName, true); @@ -1115,54 +1140,7 @@ namespace Ombi.UI.Modules { if (ShouldAutoApprove(RequestType.TvShow)) { - model.Approved = true; - var s = await sonarrSettings; - var sender = new TvSenderOld(SonarrApi, SickrageApi, Cache); // TODO put back - if (s.Enabled) - { - var result = await sender.SendToSonarr(s, model); - if (!string.IsNullOrEmpty(result?.title)) - { - if (existingRequest != null) - { - return await UpdateRequest(model, settings, - $"{fullShowName} {Resources.UI.Search_SuccessfullyAdded}"); - } - return - await - AddRequest(model, settings, - $"{fullShowName} {Resources.UI.Search_SuccessfullyAdded}"); - } - Log.Debug("Error with sending to sonarr."); - return - Response.AsJson(ValidationHelper.SendSonarrError(result?.ErrorMessages ?? new List())); - } - - var srSettings = SickRageService.GetSettings(); - if (srSettings.Enabled) - { - var result = sender.SendToSickRage(srSettings, model); - if (result?.result == "success") - { - return await AddRequest(model, settings, - $"{fullShowName} {Resources.UI.Search_SuccessfullyAdded}"); - } - return - Response.AsJson(new JsonResponseModel - { - Result = false, - Message = result?.message ?? Resources.UI.Search_SickrageError - }); - } - - if (!srSettings.Enabled && !s.Enabled) - { - return await AddRequest(model, settings, $"{fullShowName} {Resources.UI.Search_SuccessfullyAdded}"); - } - - return - Response.AsJson(new JsonResponseModel { Result = false, Message = Resources.UI.Search_TvNotSetUp }); - + return await SendTv(model, sonarrSettings, existingRequest, fullShowName, settings); } return await AddRequest(model, settings, $"{fullShowName} {Resources.UI.Search_SuccessfullyAdded}"); } @@ -1620,5 +1598,56 @@ namespace Ombi.UI.Modules MostWatched, Trending } + + private async Task SendTv(RequestedModel model, Task sonarrSettings, RequestedModel existingRequest, string fullShowName, PlexRequestSettings settings) + { + model.Approved = true; + var s = await sonarrSettings; + var sender = new TvSenderOld(SonarrApi, SickrageApi, Cache); // TODO put back + if (s.Enabled) + { + var result = await sender.SendToSonarr(s, model); + if (!string.IsNullOrEmpty(result?.title)) + { + if (existingRequest != null) + { + return await UpdateRequest(model, settings, + $"{fullShowName} {Resources.UI.Search_SuccessfullyAdded}"); + } + return + await + AddRequest(model, settings, + $"{fullShowName} {Resources.UI.Search_SuccessfullyAdded}"); + } + Log.Debug("Error with sending to sonarr."); + return + Response.AsJson(ValidationHelper.SendSonarrError(result?.ErrorMessages ?? new List())); + } + + var srSettings = SickRageService.GetSettings(); + if (srSettings.Enabled) + { + var result = sender.SendToSickRage(srSettings, model); + if (result?.result == "success") + { + return await AddRequest(model, settings, + $"{fullShowName} {Resources.UI.Search_SuccessfullyAdded}"); + } + return + Response.AsJson(new JsonResponseModel + { + Result = false, + Message = result?.message ?? Resources.UI.Search_SickrageError + }); + } + + if (!srSettings.Enabled && !s.Enabled) + { + return await AddRequest(model, settings, $"{fullShowName} {Resources.UI.Search_SuccessfullyAdded}"); + } + + return + Response.AsJson(new JsonResponseModel { Result = false, Message = Resources.UI.Search_TvNotSetUp }); + } } } diff --git a/Ombi.UI/Ombi.UI.csproj b/Ombi.UI/Ombi.UI.csproj index 32f4b17a3..24fa57f52 100644 --- a/Ombi.UI/Ombi.UI.csproj +++ b/Ombi.UI/Ombi.UI.csproj @@ -252,6 +252,7 @@ + diff --git a/Ombi.UI/Views/Admin/EmailNotifications.cshtml b/Ombi.UI/Views/Admin/EmailNotifications.cshtml index 3dfee8f8b..f2d7aab82 100644 --- a/Ombi.UI/Views/Admin/EmailNotifications.cshtml +++ b/Ombi.UI/Views/Admin/EmailNotifications.cshtml @@ -31,20 +31,7 @@ -
-
- @if (Model.EnableUserEmailNotifications) - { - - } - else - { - - } - -
-
@@ -59,7 +46,7 @@
- Please note that if user notifications is enabled, the email will get sent with the SMTP set-up below. +
@@ -82,12 +69,15 @@
+ + The sender is who the email will be sent from, this can be for any email including user notification emails (if that is enabled).
+ The recipient email is used for emails going to the administrator. diff --git a/Ombi.UI/Views/Admin/NewsletterSettings.cshtml b/Ombi.UI/Views/Admin/NewsletterSettings.cshtml index 37ed9d27c..8b0d462ff 100644 --- a/Ombi.UI/Views/Admin/NewsletterSettings.cshtml +++ b/Ombi.UI/Views/Admin/NewsletterSettings.cshtml @@ -16,35 +16,20 @@
@if (Model.SendRecentlyAddedEmail) { - + } else { - + } - -
-
- @if (Model.SendToPlexUsers) - { - - } - else - { - - } - -
-

-
- + You can add multiple email address by using the ; delimiter
diff --git a/Ombi.UI/Views/Admin/Sonarr.cshtml b/Ombi.UI/Views/Admin/Sonarr.cshtml index 8c6405f5d..28e2a9140 100644 --- a/Ombi.UI/Views/Admin/Sonarr.cshtml +++ b/Ombi.UI/Views/Admin/Sonarr.cshtml @@ -15,6 +15,8 @@
Sonarr Settings + +
@if (Model.Enabled) @@ -220,6 +222,8 @@ } var qualityProfile = $("#profiles option:selected").val(); var rootFolder = $("#rootFolders option:selected").val(); + var rootFolderPath = $('#rootFolders option:selected').text(); + $('#fullRootPath').val(rootFolderPath); var $form = $("#mainForm"); diff --git a/Ombi.UI/Views/Customization/Customization.cshtml b/Ombi.UI/Views/Customization/Customization.cshtml index ff2e7a296..583dbabae 100644 --- a/Ombi.UI/Views/Customization/Customization.cshtml +++ b/Ombi.UI/Views/Customization/Customization.cshtml @@ -40,6 +40,7 @@
+
@@ -103,6 +104,7 @@
+ @Html.Checkbox(Model.Settings.NewSearch, "NewSearch", "Use New Search")
diff --git a/Ombi.UI/Views/Search/Index.cshtml b/Ombi.UI/Views/Search/Index.cshtml index efb9228ad..db5b25dd9 100644 --- a/Ombi.UI/Views/Search/Index.cshtml +++ b/Ombi.UI/Views/Search/Index.cshtml @@ -1,5 +1,6 @@ @using Ombi.UI.Helpers @using Ombi.UI.Resources +@inherits Nancy.ViewEngines.Razor.NancyRazorViewBase @{ var baseUrl = Html.GetBaseUrl(); var url = string.Empty; @@ -9,6 +10,8 @@ } }
+ +

@UI.Search_Title

@UI.Search_Paragraph


@@ -16,21 +19,21 @@