mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-07-10 23:42:36 -07:00
commit
129269c9b5
27 changed files with 605 additions and 150 deletions
104
Ombi.Api.Models/Movie/TmdbMovieDetails.cs
Normal file
104
Ombi.Api.Models/Movie/TmdbMovieDetails.cs
Normal file
|
@ -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<Result> 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<Genre> 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<ProductionCompany> production_companies { get; set; }
|
||||||
|
public List<ProductionCountry> production_countries { get; set; }
|
||||||
|
public string release_date { get; set; }
|
||||||
|
public int revenue { get; set; }
|
||||||
|
public int runtime { get; set; }
|
||||||
|
public List<SpokenLanguage> 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; }
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -54,6 +54,7 @@
|
||||||
<Compile Include="Movie\CouchPotatoProfiles.cs" />
|
<Compile Include="Movie\CouchPotatoProfiles.cs" />
|
||||||
<Compile Include="Movie\CouchPotatoStatus.cs" />
|
<Compile Include="Movie\CouchPotatoStatus.cs" />
|
||||||
<Compile Include="Movie\CouchPotatoApiKey.cs" />
|
<Compile Include="Movie\CouchPotatoApiKey.cs" />
|
||||||
|
<Compile Include="Movie\TmdbMovieDetails.cs" />
|
||||||
<Compile Include="Music\HeadphonesAlbumSearchResult.cs" />
|
<Compile Include="Music\HeadphonesAlbumSearchResult.cs" />
|
||||||
<Compile Include="Music\HeadphonesArtistSearchResult.cs" />
|
<Compile Include="Music\HeadphonesArtistSearchResult.cs" />
|
||||||
<Compile Include="Music\HeadphonesGetIndex.cs" />
|
<Compile Include="Music\HeadphonesGetIndex.cs" />
|
||||||
|
|
|
@ -47,7 +47,7 @@ namespace Ombi.Api.Models.Radarr
|
||||||
{
|
{
|
||||||
public string title { get; set; }
|
public string title { get; set; }
|
||||||
public string sortTitle { get; set; }
|
public string sortTitle { get; set; }
|
||||||
public int sizeOnDisk { get; set; }
|
public double sizeOnDisk { get; set; }
|
||||||
public string status { get; set; }
|
public string status { get; set; }
|
||||||
public string overview { get; set; }
|
public string overview { get; set; }
|
||||||
public string inCinemas { get; set; }
|
public string inCinemas { get; set; }
|
||||||
|
|
|
@ -32,6 +32,8 @@ namespace Ombi.Api
|
||||||
public abstract class MovieBase
|
public abstract class MovieBase
|
||||||
{
|
{
|
||||||
private static readonly string Encrypted = "0T3QNSseexLO7n7UPiJvl70Y+KKnvbeTlsusl7Kwq0hPH0BHOuFNGwksNCjkwqWedyDdI/MJeUR4wtL4bIl0Z+//uHXEaYM/4H2pjeLbH5EWdUe5TTj1AhaIR5PQweamvcienRyFD/3YPCC/+qL5mHkKXBkPumMod3Zb/4yN0Ik=";
|
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"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,12 +25,18 @@
|
||||||
// ************************************************************************/
|
// ************************************************************************/
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using NLog;
|
||||||
|
using NLog.Fluent;
|
||||||
|
using Ombi.Api.Models.Movie;
|
||||||
|
using RestSharp;
|
||||||
using TMDbLib.Client;
|
using TMDbLib.Client;
|
||||||
using TMDbLib.Objects.General;
|
using TMDbLib.Objects.General;
|
||||||
using TMDbLib.Objects.Movies;
|
using TMDbLib.Objects.Movies;
|
||||||
using TMDbLib.Objects.Search;
|
using TMDbLib.Objects.Search;
|
||||||
|
using Movie = TMDbLib.Objects.Movies.Movie;
|
||||||
|
|
||||||
namespace Ombi.Api
|
namespace Ombi.Api
|
||||||
{
|
{
|
||||||
|
@ -39,9 +45,13 @@ namespace Ombi.Api
|
||||||
public TheMovieDbApi()
|
public TheMovieDbApi()
|
||||||
{
|
{
|
||||||
Client = new TMDbClient(ApiKey);
|
Client = new TMDbClient(ApiKey);
|
||||||
|
Api = new ApiRequest();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ApiRequest Api { get; }
|
||||||
public TMDbClient Client { get; set; }
|
public TMDbClient Client { get; set; }
|
||||||
|
private const string BaseUrl = "https://api.themoviedb.org/3/";
|
||||||
|
private static Logger Log = LogManager.GetCurrentClassLogger();
|
||||||
public async Task<List<SearchMovie>> SearchMovie(string searchTerm)
|
public async Task<List<SearchMovie>> SearchMovie(string searchTerm)
|
||||||
{
|
{
|
||||||
var results = await Client.SearchMovie(searchTerm);
|
var results = await Client.SearchMovie(searchTerm);
|
||||||
|
@ -56,7 +66,27 @@ namespace Ombi.Api
|
||||||
public async Task<List<MovieResult>> GetUpcomingMovies()
|
public async Task<List<MovieResult>> GetUpcomingMovies()
|
||||||
{
|
{
|
||||||
var movies = await Client.GetMovieList(MovieListType.Upcoming);
|
var movies = await Client.GetMovieList(MovieListType.Upcoming);
|
||||||
return movies?.Results ?? new List<MovieResult>();
|
return movies?.Results ?? new List<MovieResult>();
|
||||||
|
}
|
||||||
|
|
||||||
|
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<TmdbMovieDetails>(request, new Uri(BaseUrl));
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Log.Error(e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<Movie> GetMovieInformation(int tmdbId)
|
public async Task<Movie> GetMovieInformation(int tmdbId)
|
||||||
|
|
64
Ombi.Core.Migration/Migrations/Version2200.cs
Normal file
64
Ombi.Core.Migration/Migrations/Version2200.cs
Normal file
|
@ -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<CustomizationSettings> custom)
|
||||||
|
{
|
||||||
|
Customization = custom;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Version => 22000;
|
||||||
|
private ISettingsService<CustomizationSettings> 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -69,6 +69,7 @@
|
||||||
<Compile Include="MigrationAttribute.cs" />
|
<Compile Include="MigrationAttribute.cs" />
|
||||||
<Compile Include="MigrationRunner.cs" />
|
<Compile Include="MigrationRunner.cs" />
|
||||||
<Compile Include="Migrations\BaseMigration.cs" />
|
<Compile Include="Migrations\BaseMigration.cs" />
|
||||||
|
<Compile Include="Migrations\Version2200.cs" />
|
||||||
<Compile Include="Migrations\Version1100.cs" />
|
<Compile Include="Migrations\Version1100.cs" />
|
||||||
<Compile Include="Migrations\Version195.cs" />
|
<Compile Include="Migrations\Version195.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
|
|
@ -53,5 +53,7 @@ namespace Ombi.Core.SettingModels
|
||||||
|
|
||||||
public int DefaultLang { get; set; }
|
public int DefaultLang { get; set; }
|
||||||
|
|
||||||
|
public bool NewSearch { get; set; }
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -34,7 +34,6 @@ namespace Ombi.Core.SettingModels
|
||||||
public string EmailSender { get; set; }
|
public string EmailSender { get; set; }
|
||||||
public string EmailUsername { get; set; }
|
public string EmailUsername { get; set; }
|
||||||
public bool Authentication { get; set; }
|
public bool Authentication { get; set; }
|
||||||
public bool EnableUserEmailNotifications { get; set; }
|
|
||||||
public string RecipientEmail { get; set; }
|
public string RecipientEmail { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -32,6 +32,13 @@ namespace Ombi.Core.SettingModels
|
||||||
public string ApiKey { get; set; }
|
public string ApiKey { get; set; }
|
||||||
public string QualityProfile { get; set; }
|
public string QualityProfile { get; set; }
|
||||||
public bool SeasonFolders { get; set; }
|
public bool SeasonFolders { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// This is the root path ID
|
||||||
|
/// </summary>
|
||||||
|
/// <value>
|
||||||
|
/// The root path.
|
||||||
|
/// </value>
|
||||||
public string RootPath { get; set; }
|
public string RootPath { get; set; }
|
||||||
|
public string FullRootPath { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -85,7 +85,7 @@ namespace Ombi.Core
|
||||||
var latest = model.SeasonsRequested?.Equals("Latest", StringComparison.CurrentCultureIgnoreCase);
|
var latest = model.SeasonsRequested?.Equals("Latest", StringComparison.CurrentCultureIgnoreCase);
|
||||||
var specificSeasonRequest = model.SeasonList?.Any();
|
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)
|
if (episodeRequest)
|
||||||
{
|
{
|
||||||
|
|
|
@ -70,7 +70,7 @@ namespace Ombi.Core
|
||||||
{
|
{
|
||||||
int.TryParse(sonarrSettings.QualityProfile, out qualityProfile);
|
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);
|
var series = await GetSonarrSeries(sonarrSettings, model.ProviderId);
|
||||||
|
|
|
@ -66,7 +66,15 @@ namespace Ombi.Services.Jobs
|
||||||
var movies = RadarrApi.GetMovies(settings.ApiKey, settings.FullUri);
|
var movies = RadarrApi.GetMovies(settings.ApiKey, settings.FullUri);
|
||||||
if (movies != null)
|
if (movies != null)
|
||||||
{
|
{
|
||||||
var movieIds = movies.Select(x => x.tmdbId).ToList();
|
var movieIds = new List<int>();
|
||||||
|
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);
|
Cache.Set(CacheKeys.RadarrMovies, movieIds, CacheKeys.TimeFrameMinutes.SchedulerCaching);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -119,14 +119,6 @@ namespace Ombi.Services.Notification
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!settings.EnableUserEmailNotifications)
|
|
||||||
{
|
|
||||||
if (!settings.Enabled)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -237,10 +229,6 @@ namespace Ombi.Services.Notification
|
||||||
|
|
||||||
private async Task EmailAvailableRequest(NotificationModel model, EmailNotificationSettings settings)
|
private async Task EmailAvailableRequest(NotificationModel model, EmailNotificationSettings settings)
|
||||||
{
|
{
|
||||||
if (!settings.EnableUserEmailNotifications)
|
|
||||||
{
|
|
||||||
await Task.FromResult(false);
|
|
||||||
}
|
|
||||||
var email = new EmailBasicTemplate();
|
var email = new EmailBasicTemplate();
|
||||||
var html = email.LoadTemplate(
|
var html = email.LoadTemplate(
|
||||||
$"Ombi: {model.Title} is now available!",
|
$"Ombi: {model.Title} is now available!",
|
||||||
|
|
|
@ -154,7 +154,25 @@ namespace Ombi.Services.Notification
|
||||||
|
|
||||||
// Get the usernames or alias depending if they have an alias
|
// Get the usernames or alias depending if they have an alias
|
||||||
var userNamesWithFeature = users.Select(x => x.UsernameOrAlias).ToList();
|
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();
|
var usersToNotify = userNamesWithFeature.Intersect(model.AllUsers, StringComparer.CurrentCultureIgnoreCase).ToList();
|
||||||
|
|
||||||
if (!usersToNotify.Any())
|
if (!usersToNotify.Any())
|
||||||
|
|
|
@ -27,9 +27,6 @@ namespace Ombi.Store
|
||||||
public string Status { get; set; }
|
public string Status { get; set; }
|
||||||
public bool Approved { 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 DateTime RequestedDate { get; set; }
|
||||||
public bool Available { get; set; }
|
public bool Available { get; set; }
|
||||||
public IssueState Issues { get; set; }
|
public IssueState Issues { get; set; }
|
||||||
|
@ -60,14 +57,9 @@ namespace Ombi.Store
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
var u = new List<string>();
|
var u = new List<string>();
|
||||||
if (!string.IsNullOrEmpty(RequestedBy))
|
|
||||||
{
|
|
||||||
u.Add(RequestedBy);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (RequestedUsers != null && RequestedUsers.Any())
|
if (RequestedUsers != null && RequestedUsers.Any())
|
||||||
{
|
{
|
||||||
u.AddRange(RequestedUsers.Where(requestedUser => requestedUser != RequestedBy));
|
u.AddRange(RequestedUsers);
|
||||||
}
|
}
|
||||||
return u;
|
return u;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,8 @@ Function.prototype.bind = function (parent) {
|
||||||
|
|
||||||
$(function () {
|
$(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 seasonsSource = $("#seasons-template").html();
|
||||||
var musicSource = $("#music-template").html();
|
var musicSource = $("#music-template").html();
|
||||||
var seasonsNumberSource = $("#seasonNumber-template").html();
|
var seasonsNumberSource = $("#seasonNumber-template").html();
|
||||||
|
@ -470,7 +471,11 @@ $(function () {
|
||||||
requested: result.requested,
|
requested: result.requested,
|
||||||
approved: result.approved,
|
approved: result.approved,
|
||||||
available: result.available,
|
available: result.available,
|
||||||
url: result.plexUrl
|
url: result.plexUrl,
|
||||||
|
trailer: result.trailer,
|
||||||
|
homepage: result.homepage,
|
||||||
|
releaseDate: Humanize(result.releaseDate),
|
||||||
|
status: result.status
|
||||||
};
|
};
|
||||||
|
|
||||||
return context;
|
return context;
|
||||||
|
|
37
Ombi.UI/Models/SearchLoadViewModel.cs
Normal file
37
Ombi.UI/Models/SearchLoadViewModel.cs
Normal file
|
@ -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; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -47,5 +47,8 @@ namespace Ombi.UI.Models
|
||||||
public double VoteAverage { get; set; }
|
public double VoteAverage { get; set; }
|
||||||
public int VoteCount { get; set; }
|
public int VoteCount { get; set; }
|
||||||
public bool AlreadyInCp { get; set; }
|
public bool AlreadyInCp { get; set; }
|
||||||
|
public string Trailer { get; set; }
|
||||||
|
public string Homepage { get; set; }
|
||||||
|
public string ImdbId { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -211,8 +211,8 @@ namespace Ombi.UI.Modules.Admin
|
||||||
Get["/headphones"] = _ => Headphones();
|
Get["/headphones"] = _ => Headphones();
|
||||||
Post["/headphones"] = _ => SaveHeadphones();
|
Post["/headphones"] = _ => SaveHeadphones();
|
||||||
|
|
||||||
Get["/newsletter"] = _ => Newsletter();
|
Get["/newsletter", true] = async (x, ct) => await Newsletter();
|
||||||
Post["/newsletter"] = _ => SaveNewsletter();
|
Post["/newsletter", true] = async (x, ct) => await SaveNewsletter();
|
||||||
|
|
||||||
Post["/createapikey"] = x => CreateApiKey();
|
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." });
|
: new JsonResponseModel { Result = false, Message = "Could not update the settings, take a look at the logs." });
|
||||||
}
|
}
|
||||||
|
|
||||||
private Negotiator Newsletter()
|
private async Task<Negotiator> Newsletter()
|
||||||
{
|
{
|
||||||
var settings = NewsLetterService.GetSettings();
|
var settings = await NewsLetterService.GetSettingsAsync();
|
||||||
return View["NewsletterSettings", settings];
|
return View["NewsletterSettings", settings];
|
||||||
}
|
}
|
||||||
|
|
||||||
private Response SaveNewsletter()
|
private async Task<Response> SaveNewsletter()
|
||||||
{
|
{
|
||||||
var settings = this.Bind<NewletterSettings>();
|
var settings = this.Bind<NewletterSettings>();
|
||||||
|
|
||||||
|
@ -859,9 +859,17 @@ namespace Ombi.UI.Modules.Admin
|
||||||
if (!valid.IsValid)
|
if (!valid.IsValid)
|
||||||
{
|
{
|
||||||
var error = valid.SendJsonError();
|
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);
|
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;
|
settings.SendRecentlyAddedEmail = settings.SendRecentlyAddedEmail;
|
||||||
var result = NewsLetterService.SaveSettings(settings);
|
var result = NewsLetterService.SaveSettings(settings);
|
||||||
|
|
||||||
|
|
|
@ -77,7 +77,7 @@ namespace Ombi.UI.Modules
|
||||||
ISettingsService<PlexSettings> plexService, ISettingsService<AuthenticationSettings> auth,
|
ISettingsService<PlexSettings> plexService, ISettingsService<AuthenticationSettings> auth,
|
||||||
IRepository<UsersToNotify> u, ISettingsService<EmailNotificationSettings> email,
|
IRepository<UsersToNotify> u, ISettingsService<EmailNotificationSettings> email,
|
||||||
IIssueService issue, IAnalytics a, IRepository<RequestLimit> rl, ITransientFaultQueue tfQueue, IRepository<PlexContent> content,
|
IIssueService issue, IAnalytics a, IRepository<RequestLimit> rl, ITransientFaultQueue tfQueue, IRepository<PlexContent> content,
|
||||||
ISecurityExtensions security, IMovieSender movieSender, IRadarrCacher radarrCacher, ITraktApi traktApi)
|
ISecurityExtensions security, IMovieSender movieSender, IRadarrCacher radarrCacher, ITraktApi traktApi, ISettingsService<CustomizationSettings> cus)
|
||||||
: base("search", prSettings, security)
|
: base("search", prSettings, security)
|
||||||
{
|
{
|
||||||
Auth = auth;
|
Auth = auth;
|
||||||
|
@ -111,6 +111,7 @@ namespace Ombi.UI.Modules
|
||||||
WatcherCacher = watcherCacher;
|
WatcherCacher = watcherCacher;
|
||||||
RadarrCacher = radarrCacher;
|
RadarrCacher = radarrCacher;
|
||||||
TraktApi = traktApi;
|
TraktApi = traktApi;
|
||||||
|
CustomizationSettings = cus;
|
||||||
|
|
||||||
Get["SearchIndex", "/", true] = async (x, ct) => await RequestLoad();
|
Get["SearchIndex", "/", true] = async (x, ct) => await RequestLoad();
|
||||||
|
|
||||||
|
@ -169,14 +170,22 @@ namespace Ombi.UI.Modules
|
||||||
private ITransientFaultQueue FaultQueue { get; }
|
private ITransientFaultQueue FaultQueue { get; }
|
||||||
private IRepository<RequestLimit> RequestLimitRepo { get; }
|
private IRepository<RequestLimit> RequestLimitRepo { get; }
|
||||||
private IRadarrCacher RadarrCacher { get; }
|
private IRadarrCacher RadarrCacher { get; }
|
||||||
|
private ISettingsService<CustomizationSettings> CustomizationSettings { get; }
|
||||||
private static Logger Log = LogManager.GetCurrentClassLogger();
|
private static Logger Log = LogManager.GetCurrentClassLogger();
|
||||||
|
|
||||||
private async Task<Negotiator> RequestLoad()
|
private async Task<Negotiator> RequestLoad()
|
||||||
{
|
{
|
||||||
|
|
||||||
var settings = await PrService.GetSettingsAsync();
|
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<Response> UpcomingMovies()
|
private async Task<Response> UpcomingMovies()
|
||||||
|
@ -266,17 +275,6 @@ namespace Ombi.UI.Modules
|
||||||
var counter = 0;
|
var counter = 0;
|
||||||
foreach (var movie in apiMovies)
|
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
|
var viewMovie = new SearchMovieViewModel
|
||||||
{
|
{
|
||||||
Adult = movie.Adult,
|
Adult = movie.Adult,
|
||||||
|
@ -294,6 +292,28 @@ namespace Ombi.UI.Modules
|
||||||
VoteAverage = movie.VoteAverage,
|
VoteAverage = movie.VoteAverage,
|
||||||
VoteCount = movie.VoteCount
|
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 canSee = CanUserSeeThisRequest(viewMovie.Id, Security.HasPermissions(User, Permissions.UsersCanViewOnlyOwnRequests), dbMovies);
|
||||||
var plexMovie = Checker.GetMovie(plexMovies.ToArray(), movie.Title, movie.ReleaseDate?.Year.ToString(),
|
var plexMovie = Checker.GetMovie(plexMovies.ToArray(), movie.Title, movie.ReleaseDate?.Year.ToString(),
|
||||||
imdbId);
|
imdbId);
|
||||||
|
@ -989,6 +1009,11 @@ namespace Ombi.UI.Modules
|
||||||
existingRequest.Episodes.AddRange(newEpisodes ?? Enumerable.Empty<EpisodesModel>());
|
existingRequest.Episodes.AddRange(newEpisodes ?? Enumerable.Empty<EpisodesModel>());
|
||||||
|
|
||||||
// It's technically a new request now, so set the status to not approved.
|
// 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;
|
existingRequest.Approved = false;
|
||||||
|
|
||||||
return await AddUserToRequest(existingRequest, settings, fullShowName, true);
|
return await AddUserToRequest(existingRequest, settings, fullShowName, true);
|
||||||
|
@ -1115,54 +1140,7 @@ namespace Ombi.UI.Modules
|
||||||
{
|
{
|
||||||
if (ShouldAutoApprove(RequestType.TvShow))
|
if (ShouldAutoApprove(RequestType.TvShow))
|
||||||
{
|
{
|
||||||
model.Approved = true;
|
return await SendTv(model, sonarrSettings, existingRequest, fullShowName, settings);
|
||||||
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<string>()));
|
|
||||||
}
|
|
||||||
|
|
||||||
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 AddRequest(model, settings, $"{fullShowName} {Resources.UI.Search_SuccessfullyAdded}");
|
return await AddRequest(model, settings, $"{fullShowName} {Resources.UI.Search_SuccessfullyAdded}");
|
||||||
}
|
}
|
||||||
|
@ -1620,5 +1598,56 @@ namespace Ombi.UI.Modules
|
||||||
MostWatched,
|
MostWatched,
|
||||||
Trending
|
Trending
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task<Response> SendTv(RequestedModel model, Task<SonarrSettings> 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<string>()));
|
||||||
|
}
|
||||||
|
|
||||||
|
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 });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -252,6 +252,7 @@
|
||||||
<Compile Include="Models\Requests\RequestsIndexViewModel.cs" />
|
<Compile Include="Models\Requests\RequestsIndexViewModel.cs" />
|
||||||
<Compile Include="Models\RootFolderModel.cs" />
|
<Compile Include="Models\RootFolderModel.cs" />
|
||||||
<Compile Include="Models\ScheduledJobsViewModel.cs" />
|
<Compile Include="Models\ScheduledJobsViewModel.cs" />
|
||||||
|
<Compile Include="Models\SearchLoadViewModel.cs" />
|
||||||
<Compile Include="Models\SearchViewModel.cs" />
|
<Compile Include="Models\SearchViewModel.cs" />
|
||||||
<Compile Include="Models\SearchMusicViewModel.cs" />
|
<Compile Include="Models\SearchMusicViewModel.cs" />
|
||||||
<Compile Include="Models\SearchMovieViewModel.cs" />
|
<Compile Include="Models\SearchMovieViewModel.cs" />
|
||||||
|
|
|
@ -31,20 +31,7 @@
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
|
||||||
<div class="checkbox">
|
|
||||||
|
|
||||||
@if (Model.EnableUserEmailNotifications)
|
|
||||||
{
|
|
||||||
<input type="checkbox" id="EnableUserEmailNotifications" name="EnableUserEmailNotifications" checked="checked"><label for="EnableUserEmailNotifications">Enable user email notifications</label>
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
<input type="checkbox" id="EnableUserEmailNotifications" name="EnableUserEmailNotifications"><label for="EnableUserEmailNotifications">Enable user email notifications</label>
|
|
||||||
}
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div class="checkbox">
|
<div class="checkbox">
|
||||||
|
|
||||||
|
@ -59,7 +46,7 @@
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<small>Please note that if user notifications is enabled, the email will get sent with the SMTP set-up below.</small>
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="EmailHost" class="control-label">SMTP Host name or IP</label>
|
<label for="EmailHost" class="control-label">SMTP Host name or IP</label>
|
||||||
<div class="">
|
<div class="">
|
||||||
|
@ -82,12 +69,15 @@
|
||||||
<input type="text" class="form-control form-control-custom " id="EmailSender" name="EmailSender" value="@Model.EmailSender">
|
<input type="text" class="form-control form-control-custom " id="EmailSender" name="EmailSender" value="@Model.EmailSender">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<small>The sender is who the email will be sent from, this can be for any email including user notification emails (if that is enabled).</small>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="RecipientEmail" class="control-label">Email Recipient</label>
|
<label for="RecipientEmail" class="control-label">Email Recipient</label>
|
||||||
<div>
|
<div>
|
||||||
<input type="text" class="form-control form-control-custom " id="RecipientEmail" name="RecipientEmail" value="@Model.RecipientEmail">
|
<input type="text" class="form-control form-control-custom " id="RecipientEmail" name="RecipientEmail" value="@Model.RecipientEmail">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<small>The recipient email is used for emails going to the administrator.</small>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -16,35 +16,20 @@
|
||||||
<br />
|
<br />
|
||||||
@if (Model.SendRecentlyAddedEmail)
|
@if (Model.SendRecentlyAddedEmail)
|
||||||
{
|
{
|
||||||
<input type="checkbox" id="SendRecentlyAddedEmail" name="SendRecentlyAddedEmail" checked="checked"><label for="SendRecentlyAddedEmail">Enable the newsletter of recently added content</label>
|
<input type="checkbox" id="SendRecentlyAddedEmail" name="SendRecentlyAddedEmail" checked="checked"><label for="SendRecentlyAddedEmail">Enable newsletter</label>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<input type="checkbox" id="SendRecentlyAddedEmail" name="SendRecentlyAddedEmail"><label for="SendRecentlyAddedEmail">Enable the newsletter of recently added content</label>
|
<input type="checkbox" id="SendRecentlyAddedEmail" name="SendRecentlyAddedEmail"><label for="SendRecentlyAddedEmail">Enable newslette</label>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<div class="checkbox">
|
|
||||||
@if (Model.SendToPlexUsers)
|
|
||||||
{
|
|
||||||
<input type="checkbox" id="SendToPlexUsers" name="SendToPlexUsers" checked="checked"><label for="SendToPlexUsers">Send to all of your Plex 'Friends'</label>
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
<input type="checkbox" id="SendToPlexUsers" name="SendToPlexUsers"><label for="SendToPlexUsers">Send to all of your Plex 'Friends'</label>
|
|
||||||
}
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
<br>
|
<label for="CustomUsers" class="control-label">Email Addresses to Send to (For users that are not in your User Management section)</label>
|
||||||
<label for="CustomUsers" class="control-label">Email Addresses to Send to (For users that are not in your Plex Friends)</label>
|
|
||||||
<small>You can add multiple email address by using the ; delimiter</small>
|
<small>You can add multiple email address by using the ; delimiter</small>
|
||||||
<div>
|
<div>
|
||||||
<input type="text" class="form-control form-control-custom " placeholder="first@address.com;second@address.com" id="CustomUsers" name="CustomUsers" value="@Model.CustomUsers">
|
<input type="text" class="form-control form-control-custom " placeholder="first@address.com;second@address.com" id="CustomUsers" name="CustomUsers" value="@Model.CustomUsers">
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
<form class="form-horizontal" method="POST" id="mainForm">
|
<form class="form-horizontal" method="POST" id="mainForm">
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>Sonarr Settings</legend>
|
<legend>Sonarr Settings</legend>
|
||||||
|
|
||||||
|
<input hidden="hidden" name="FullRootPath" id="fullRootPath" value="@Model.FullRootPath"/>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div class="checkbox">
|
<div class="checkbox">
|
||||||
@if (Model.Enabled)
|
@if (Model.Enabled)
|
||||||
|
@ -220,6 +222,8 @@
|
||||||
}
|
}
|
||||||
var qualityProfile = $("#profiles option:selected").val();
|
var qualityProfile = $("#profiles option:selected").val();
|
||||||
var rootFolder = $("#rootFolders option:selected").val();
|
var rootFolder = $("#rootFolders option:selected").val();
|
||||||
|
var rootFolderPath = $('#rootFolders option:selected').text();
|
||||||
|
$('#fullRootPath').val(rootFolderPath);
|
||||||
|
|
||||||
var $form = $("#mainForm");
|
var $form = $("#mainForm");
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="lang" class="control-label">Default Language</label>
|
<label for="lang" class="control-label">Default Language</label>
|
||||||
<div id="langSelect">
|
<div id="langSelect">
|
||||||
|
@ -103,6 +104,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@Html.Checkbox(Model.Settings.NewSearch, "NewSearch", "Use New Search")
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div>
|
<div>
|
||||||
<button type="submit" id="save" class="btn btn-primary-outline">Submit</button>
|
<button type="submit" id="save" class="btn btn-primary-outline">Submit</button>
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
@using Ombi.UI.Helpers
|
@using Ombi.UI.Helpers
|
||||||
@using Ombi.UI.Resources
|
@using Ombi.UI.Resources
|
||||||
|
@inherits Nancy.ViewEngines.Razor.NancyRazorViewBase<Ombi.UI.Models.SearchLoadViewModel>
|
||||||
@{
|
@{
|
||||||
var baseUrl = Html.GetBaseUrl();
|
var baseUrl = Html.GetBaseUrl();
|
||||||
var url = string.Empty;
|
var url = string.Empty;
|
||||||
|
@ -9,6 +10,8 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
<div>
|
<div>
|
||||||
|
|
||||||
|
<div hidden="hidden" id="useNewSearch">@Model.CustomizationSettings.NewSearch</div>
|
||||||
<h1 id="searchTitle">@UI.Search_Title</h1>
|
<h1 id="searchTitle">@UI.Search_Title</h1>
|
||||||
<h4>@UI.Search_Paragraph</h4>
|
<h4>@UI.Search_Paragraph</h4>
|
||||||
<br />
|
<br />
|
||||||
|
@ -16,21 +19,21 @@
|
||||||
|
|
||||||
|
|
||||||
<ul id="nav-tabs" class="nav nav-tabs" role="tablist">
|
<ul id="nav-tabs" class="nav nav-tabs" role="tablist">
|
||||||
@if (Model.SearchForMovies)
|
@if (Model.Settings.SearchForMovies)
|
||||||
{
|
{
|
||||||
<li role="presentation" class="active">
|
<li role="presentation" class="active">
|
||||||
<a id="movieTabButton" href="#MoviesTab" aria-controls="home" role="tab" data-toggle="tab"><i class="fa fa-film"></i> @UI.Search_Movies</a>
|
<a id="movieTabButton" href="#MoviesTab" aria-controls="home" role="tab" data-toggle="tab"><i class="fa fa-film"></i> @UI.Search_Movies</a>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
}
|
}
|
||||||
@if (Model.SearchForTvShows)
|
@if (Model.Settings.SearchForTvShows)
|
||||||
{
|
{
|
||||||
<li role="presentation">
|
<li role="presentation">
|
||||||
<a id="tvTabButton" href="#TvShowTab" aria-controls="profile" role="tab" data-toggle="tab"><i class="fa fa-television"></i> @UI.Search_TvShows</a>
|
<a id="tvTabButton" href="#TvShowTab" aria-controls="profile" role="tab" data-toggle="tab"><i class="fa fa-television"></i> @UI.Search_TvShows</a>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
}
|
}
|
||||||
@if (Model.SearchForMusic)
|
@if (Model.Settings.SearchForMusic)
|
||||||
{
|
{
|
||||||
<li role="presentation">
|
<li role="presentation">
|
||||||
<a href="#MusicTab" aria-controls="profile" role="tab" data-toggle="tab"><i class="fa fa-music"></i>@UI.Search_Albums</a>
|
<a href="#MusicTab" aria-controls="profile" role="tab" data-toggle="tab"><i class="fa fa-music"></i>@UI.Search_Albums</a>
|
||||||
|
@ -41,7 +44,7 @@
|
||||||
|
|
||||||
<!-- Tab panes -->
|
<!-- Tab panes -->
|
||||||
<div class="tab-content">
|
<div class="tab-content">
|
||||||
@if (Model.SearchForMovies)
|
@if (Model.Settings.SearchForMovies)
|
||||||
{
|
{
|
||||||
<!-- Movie tab -->
|
<!-- Movie tab -->
|
||||||
<div role="tabpanel" class="tab-pane active" id="MoviesTab">
|
<div role="tabpanel" class="tab-pane active" id="MoviesTab">
|
||||||
|
@ -70,7 +73,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@if (Model.SearchForTvShows)
|
@if (Model.Settings.SearchForTvShows)
|
||||||
{
|
{
|
||||||
<!-- TV tab -->
|
<!-- TV tab -->
|
||||||
<div role="tabpanel" class="tab-pane" id="TvShowTab">
|
<div role="tabpanel" class="tab-pane" id="TvShowTab">
|
||||||
|
@ -99,7 +102,7 @@
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
@if (Model.SearchForMusic)
|
@if (Model.Settings.SearchForMusic)
|
||||||
{
|
{
|
||||||
<!-- Music tab -->
|
<!-- Music tab -->
|
||||||
<div role="tabpanel" class="tab-pane" id="MusicTab">
|
<div role="tabpanel" class="tab-pane" id="MusicTab">
|
||||||
|
@ -117,8 +120,8 @@
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
<!-- Movie and TV Results template -->
|
|
||||||
<script id="search-template" type="text/x-handlebars-template">
|
<script id="search-templateNew" type="text/x-handlebars-template">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div id="{{id}}imgDiv" class="col-sm-2">
|
<div id="{{id}}imgDiv" class="col-sm-2">
|
||||||
|
|
||||||
|
@ -134,28 +137,192 @@
|
||||||
{{/if_eq}}
|
{{/if_eq}}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-5 ">
|
<div class="col-sm-10">
|
||||||
|
<div>
|
||||||
|
|
||||||
|
<h4>
|
||||||
|
{{#if_eq type "movie"}}
|
||||||
|
<a href="https://www.themoviedb.org/movie/{{id}}/" target="_blank">
|
||||||
|
{{else}}
|
||||||
|
<a href="http://www.imdb.com/title/{{imdb}}/" target="_blank">
|
||||||
|
{{/if_eq}}
|
||||||
|
{{title}} ({{year}})
|
||||||
|
|
||||||
|
{{#if status}}
|
||||||
|
<span class="label label-primary" style="font-size:60%" target="_blank">{{status}}</span>
|
||||||
|
{{/if}}
|
||||||
|
</h4>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
|
||||||
|
<div class="col-md-7 col-xs-7">
|
||||||
|
|
||||||
|
{{#if available}}
|
||||||
|
<span class="label label-success">@UI.Search_Available_on_plex</span>
|
||||||
|
{{else}}
|
||||||
|
{{#if approved}}
|
||||||
|
<span class="label label-info">@UI.Search_Processing_Request</span>
|
||||||
|
{{else if requested}}
|
||||||
|
<span class="label label-warning">@UI.Search_Pending_approval</span>
|
||||||
|
{{else}}
|
||||||
|
<span class="label label-danger">@UI.Search_Not_Requested_Yet</span>
|
||||||
|
{{/if}}
|
||||||
|
{{/if}}
|
||||||
|
{{#if firstAired}}
|
||||||
|
<span class="label label-info" target="_blank">Air Date: {{firstAired}}</span>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if releaseDate}}
|
||||||
|
<span class="label label-info" target="_blank">Release Date: {{releaseDate}}</span>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
|
||||||
|
<span id="{{id}}netflixTab"></span>
|
||||||
|
</div>
|
||||||
|
<!--Info Labels-->
|
||||||
|
<div class="col-md-5 col-xs-5" style="text-align:right;">
|
||||||
|
{{#if homepage}}
|
||||||
|
<a href="{{homepage}}" target="_blank"><span class="label label-info">HomePage</span></a>
|
||||||
|
{{/if}}
|
||||||
|
{{#if trailer}}
|
||||||
|
<a href="{{trailer}}" target="_blank"><span class="label label-info">Trailer</span></a>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<!-- Description -->
|
||||||
|
<p style="font-size:0.9rem !important">{{overview}}</p>
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<form method="POST" action="@url/search/request/{{type}}" id="form{{id}}">
|
||||||
|
<input name="{{type}}Id" type="text" value="{{id}}" hidden="hidden" />
|
||||||
|
{{#if_eq type "movie"}}
|
||||||
|
{{#if_eq available true}}
|
||||||
|
<button style="text-align: right" class="btn btn-success-outline disabled" disabled><i class="fa fa-check"></i> @UI.Search_Available</button>
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<a style="text-align: right" class="btn btn-sm btn-primary-outline" href="{{url}}" target="_blank"><i class="fa fa-eye"></i> @UI.Search_ViewInPlex</a>
|
||||||
|
{{else}}
|
||||||
|
{{#if_eq requested true}}
|
||||||
|
<button style="text-align: right" class="btn btn-primary-outline disabled" disabled><i class="fa fa-check"></i> @UI.Search_Requested</button>
|
||||||
|
{{else}}
|
||||||
|
<button id="{{id}}" style="text-align: right" class="btn btn-primary-outline requestMovie" type="submit"><i class="fa fa-plus"></i> @UI.Search_Request</button>
|
||||||
|
{{/if_eq}}
|
||||||
|
{{/if_eq}}
|
||||||
|
{{/if_eq}}
|
||||||
|
|
||||||
|
{{#if_eq type "tv"}}
|
||||||
|
{{#if_eq tvFullyAvailable true}}
|
||||||
|
@*//TODO Not used yet*@
|
||||||
|
<button style="text-align: right" class="btn btn-success-outline disabled" disabled><i class="fa fa-check"></i> @UI.Search_Available</button><br />
|
||||||
|
{{else}}
|
||||||
|
{{#if_eq enableTvRequestsForOnlySeries true}}
|
||||||
|
<button id="{{id}}" style="text-align: right" class="btn {{#if available}}btn-success-outline{{else}}btn-primary-outline{{/if}} btn-primary-outline dropdownTv" season-select="0" type="button"><i class="fa fa-plus"></i> @UI.Search_Request</button>
|
||||||
|
{{else}}
|
||||||
|
<div class="dropdown">
|
||||||
|
<button id="{{id}}" class="btn {{#if available}}btn-success-outline{{else}}btn-primary-outline{{/if}} dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
|
||||||
|
<i class="fa fa-plus"></i> {{#if available}}@UI.Search_Available{{else}}@UI.Search_Request {{/if}}
|
||||||
|
<span class="caret"></span>
|
||||||
|
</button>
|
||||||
|
<ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
|
||||||
|
<li><a id="{{id}}" season-select="0" class="dropdownTv " href="#">@UI.Search_AllSeasons</a></li>
|
||||||
|
{{#if_eq disableTvRequestsBySeason false}}
|
||||||
|
<li><a id="{{id}}" season-select="1" class="dropdownTv" href="#">@UI.Search_FirstSeason</a></li>
|
||||||
|
<li><a id="{{id}}" season-select="2" class="dropdownTv" href="#">@UI.Search_LatestSeason</a></li>
|
||||||
|
<li><a id="SeasonSelect" data-identifier="{{id}}" data-toggle="modal" data-target="#seasonsModal" href="#">@UI.Search_SelectSeason...</a></li>
|
||||||
|
{{/if_eq}}
|
||||||
|
{{#if_eq disableTvRequestsByEpisode false}}
|
||||||
|
<li><a id="EpisodeSelect" data-identifier="{{id}}" data-toggle="modal" data-target="#episodesModal" href="#">@UI.Search_SelectEpisode...</a></li>
|
||||||
|
{{/if_eq}}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
{{/if_eq}}
|
||||||
|
{{#if available}}
|
||||||
|
<br />
|
||||||
|
<a style="text-align: right" class="btn btn-sm btn-primary-outline" href="{{url}}" target="_blank"><i class="fa fa-eye"></i> @UI.Search_ViewInPlex</a>
|
||||||
|
{{/if}}
|
||||||
|
{{/if_eq}}
|
||||||
|
{{/if_eq}}
|
||||||
|
|
||||||
|
|
||||||
|
<br />
|
||||||
|
</form>
|
||||||
|
{{#if_eq available true}}
|
||||||
|
<form method="POST" action="@url/issues/nonrequestissue/" id="report{{id}}">
|
||||||
|
<input name="providerId" type="text" value="{{id}}" hidden="hidden" />
|
||||||
|
<input name="type" type="text" value="{{type}}" hidden="hidden" />
|
||||||
|
<div class="dropdown">
|
||||||
|
<button id="{{id}}" class="btn btn-sm btn-danger-outline dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
|
||||||
|
<i class="fa fa-exclamation"></i> @UI.Search_ReportIssue
|
||||||
|
<span class="caret"></span>
|
||||||
|
</button>
|
||||||
|
<ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
|
||||||
|
<li><a id="{{id}}" issue-select="0" class="dropdownIssue" href="#">@UI.Issues_WrongAudio</a></li>
|
||||||
|
<li><a id="{{id}}" issue-select="1" class="dropdownIssue" href="#">@UI.Issues_NoSubs</a></li>
|
||||||
|
<li><a id="{{id}}" issue-select="2" class="dropdownIssue" href="#">@UI.Issues_WrongContent</a></li>
|
||||||
|
<li><a id="{{id}}" issue-select="3" class="dropdownIssue" href="#">@UI.Issues_Playback</a></li>
|
||||||
|
<li><a id="{{id}}" issue-select="4" class="dropdownIssue" data-identifier="{{id}}" data-type="{{type}}" href="#" data-toggle="modal" data-target="#issuesModal">@UI.Issues_Other</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
{{/if_eq}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-12">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<hr />
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!-- Movie and TV Results template -->
|
||||||
|
<script id="search-template" type="text/x-handlebars-template">
|
||||||
|
<div class="row">
|
||||||
|
<div id="{{id}}imgDiv" class="col-sm-2">
|
||||||
|
|
||||||
|
{{#if_eq type "movie"}}
|
||||||
|
{{#if posterPath}}
|
||||||
|
<img class="img-responsive" src="https://image.tmdb.org/t/p/w150/{{posterPath}}" alt="poster">
|
||||||
|
{{/if}}
|
||||||
|
{{/if_eq}}
|
||||||
|
{{#if_eq type "tv"}}
|
||||||
|
{{#if posterPath}}
|
||||||
|
<img class="img-responsive" width="150" src="{{posterPath}}" alt="poster">
|
||||||
|
{{/if}}
|
||||||
|
{{/if_eq}}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-8">
|
||||||
<div>
|
<div>
|
||||||
{{#if_eq type "movie"}}
|
{{#if_eq type "movie"}}
|
||||||
<a href="https://www.themoviedb.org/movie/{{id}}/" target="_blank">
|
<a href="https://www.themoviedb.org/movie/{{id}}/" target="_blank">
|
||||||
<h4>{{title}} ({{year}})</h4>
|
<h4>{{title}} ({{year}})</h4>
|
||||||
</a>
|
</a>
|
||||||
{{else}}
|
{{else}}
|
||||||
<a href="http://www.imdb.com/title/{{imdb}}/" target="_blank">
|
<h4>
|
||||||
<h4>{{title}} ({{year}})</h4>
|
<a href="http://www.imdb.com/title/{{imdb}}/" target="_blank">
|
||||||
</a>
|
{{title}} ({{year}})
|
||||||
|
|
||||||
|
</a>{{#if status}}<span class="label label-primary" style="font-size:60%" target="_blank">{{status}}</span>{{/if}}
|
||||||
|
</h4>
|
||||||
{{/if_eq}}
|
{{/if_eq}}
|
||||||
{{#if status}}
|
{{#if status}}
|
||||||
<span class="label label-info" target="_blank">{{status}}</span>
|
<span class="label label-info" target="_blank">{{status}}</span>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{#if homepage}}
|
|
||||||
<a href="{{homepage}}" target="_blank"><span class="label label-info">HomePage</span></a>
|
|
||||||
{{/if}}
|
|
||||||
{{#if trailer}}
|
|
||||||
<a href="{{trailer}}" target="_blank"><span class="label label-info">Trailer</span></a>
|
|
||||||
{{/if}}
|
|
||||||
{{#if firstAired}}
|
{{#if firstAired}}
|
||||||
<span class="label label-info" target="_blank">First Aired: {{firstAired}}</span>
|
<span class="label label-info" target="_blank">Air Date: {{firstAired}}</span>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if releaseDate}}
|
||||||
|
<span class="label label-info" target="_blank">Release Date: {{releaseDate}}</span>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{#if available}}
|
{{#if available}}
|
||||||
<span class="label label-success">@UI.Search_Available_on_plex</span>
|
<span class="label label-success">@UI.Search_Available_on_plex</span>
|
||||||
|
@ -169,14 +336,22 @@
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
|
|
||||||
<span id="{{id}}netflixTab"></span>
|
<span id="{{id}}netflixTab"></span>
|
||||||
|
|
||||||
|
{{#if homepage}}
|
||||||
|
<a href="{{homepage}}" target="_blank"><span class="label label-info">HomePage</span></a>
|
||||||
|
{{/if}}
|
||||||
|
{{#if trailer}}
|
||||||
|
<a href="{{trailer}}" target="_blank"><span class="label label-info">Trailer</span></a>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
<br />
|
<br />
|
||||||
</div>
|
</div>
|
||||||
<p>{{overview}}</p>
|
<p style="font-size:0.9rem !important">{{overview}}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-2 col-sm-push-3">
|
<div class="col-sm-2">
|
||||||
<form method="POST" action="@url/search/request/{{type}}" id="form{{id}}">
|
<form method="POST" action="@url/search/request/{{type}}" id="form{{id}}">
|
||||||
<input name="{{type}}Id" type="text" value="{{id}}" hidden="hidden" />
|
<input name="{{type}}Id" type="text" value="{{id}}" hidden="hidden" />
|
||||||
{{#if_eq type "movie"}}
|
{{#if_eq type "movie"}}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue