tidusjar 9 years ago
commit f092d64f53

@ -24,6 +24,9 @@
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// ************************************************************************/ // ************************************************************************/
#endregion #endregion
using Newtonsoft.Json;
namespace PlexRequests.Core.SettingModels namespace PlexRequests.Core.SettingModels
{ {
public sealed class PlexSettings : ExternalSettings public sealed class PlexSettings : ExternalSettings
@ -36,5 +39,6 @@ namespace PlexRequests.Core.SettingModels
public bool EnableTvEpisodeSearching { get; set; } public bool EnableTvEpisodeSearching { get; set; }
public string PlexAuthToken { get; set; } public string PlexAuthToken { get; set; }
public string MachineIdentifier { get; set; }
} }
} }

@ -26,6 +26,7 @@
#endregion #endregion
using System; using System;
using System.Linq;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using Mono.Data.Sqlite; using Mono.Data.Sqlite;
@ -66,6 +67,11 @@ namespace PlexRequests.Core
{ {
MigrateToVersion1900(); MigrateToVersion1900();
} }
if(version > 1899 && version <= 1910)
{
MigrateToVersion1910();
}
} }
return Db.DbConnection().ConnectionString; return Db.DbConnection().ConnectionString;
@ -244,5 +250,30 @@ namespace PlexRequests.Core
Log.Error(e); Log.Error(e);
} }
} }
/// <summary>
/// Migrates to version1910.
/// </summary>
public void MigrateToVersion1910()
{
try
{
// Get the new machine Identifier
var settings = new SettingsServiceV2<PlexSettings>(new SettingsJsonRepository(Db, new MemoryCacheProvider()));
var plex = settings.GetSettings();
if (!string.IsNullOrEmpty(plex.PlexAuthToken))
{
var api = new PlexApi(new ApiRequest());
var server = api.GetServer(plex.PlexAuthToken); // Get the server info
plex.MachineIdentifier = server.Server.FirstOrDefault(x => x.AccessToken == plex.PlexAuthToken)?.MachineIdentifier;
settings.SaveSettings(plex); // Save the new settings
}
}
catch (Exception e)
{
Log.Error(e);
}
}
} }
} }

@ -61,6 +61,12 @@ namespace PlexRequests.Helpers.Tests
return PlexHelper.GetSeasonNumberFromTitle(title); return PlexHelper.GetSeasonNumberFromTitle(title);
} }
[TestCaseSource(nameof(MediaUrls))]
public string GetPlexMediaUrlTest(string machineId, string mediaId)
{
return PlexHelper.GetPlexMediaUrl(machineId, mediaId);
}
private static IEnumerable<TestCaseData> PlexGuids private static IEnumerable<TestCaseData> PlexGuids
{ {
get get
@ -75,6 +81,15 @@ namespace PlexRequests.Helpers.Tests
} }
} }
private static IEnumerable<TestCaseData> MediaUrls
{
get
{
yield return new TestCaseData("abcd","99").Returns("https://app.plex.tv/web/app#!/server/abcd/details/%2Flibrary%2Fmetadata%2F99").SetName("Test 1");
yield return new TestCaseData("a54d1db669799308cd704b791f331eca6648b952", "51").Returns("https://app.plex.tv/web/app#!/server/a54d1db669799308cd704b791f331eca6648b952/details/%2Flibrary%2Fmetadata%2F51").SetName("Test 2");
}
}
private static IEnumerable<TestCaseData> SeasonNumbers private static IEnumerable<TestCaseData> SeasonNumbers
{ {
get get

@ -95,6 +95,13 @@ namespace PlexRequests.Helpers
return 0; return 0;
} }
public static string GetPlexMediaUrl(string machineId, string mediaId)
{
var url =
$"https://app.plex.tv/web/app#!/server/{machineId}/details/%2Flibrary%2Fmetadata%2F{mediaId}";
return url;
}
} }
public class EpisodeModelHelper public class EpisodeModelHelper

@ -242,6 +242,7 @@ namespace PlexRequests.Services.Tests
} }
}); });
CacheMock.Setup(x => x.Get<List<PlexSearch>>(CacheKeys.PlexLibaries)).Returns(cachedMovies); CacheMock.Setup(x => x.Get<List<PlexSearch>>(CacheKeys.PlexLibaries)).Returns(cachedMovies);
SettingsMock.Setup(x => x.GetSettings()).Returns(F.Create<PlexSettings>());
var movies = Checker.GetPlexMovies(); var movies = Checker.GetPlexMovies();
Assert.That(movies.Any(x => x.ProviderId == "1212")); Assert.That(movies.Any(x => x.ProviderId == "1212"));
@ -258,6 +259,7 @@ namespace PlexRequests.Services.Tests
new Directory1 {Type = "show", Title = "title1", Year = "2016", ProviderId = "1212", Seasons = new List<Directory1>()} new Directory1 {Type = "show", Title = "title1", Year = "2016", ProviderId = "1212", Seasons = new List<Directory1>()}
} }
}); });
SettingsMock.Setup(x => x.GetSettings()).Returns(F.Create<PlexSettings>());
CacheMock.Setup(x => x.Get<List<PlexSearch>>(CacheKeys.PlexLibaries)).Returns(cachedTv); CacheMock.Setup(x => x.Get<List<PlexSearch>>(CacheKeys.PlexLibaries)).Returns(cachedTv);
var movies = Checker.GetPlexTvShows(); var movies = Checker.GetPlexTvShows();

@ -42,6 +42,9 @@ namespace PlexRequests.Services.Interfaces
List<PlexAlbum> GetPlexAlbums(); List<PlexAlbum> GetPlexAlbums();
bool IsAlbumAvailable(PlexAlbum[] plexAlbums, string title, string year, string artist); bool IsAlbumAvailable(PlexAlbum[] plexAlbums, string title, string year, string artist);
bool IsEpisodeAvailable(string theTvDbId, int season, int episode); bool IsEpisodeAvailable(string theTvDbId, int season, int episode);
PlexAlbum GetAlbum(PlexAlbum[] plexAlbums, string title, string year, string artist);
PlexMovie GetMovie(PlexMovie[] plexMovies, string title, string year, string providerId = null);
PlexTvShow GetTvShow(PlexTvShow[] plexShows, string title, string year, string providerId = null, int[] seasons = null);
/// <summary> /// <summary>
/// Gets the episode's stored in the cache. /// Gets the episode's stored in the cache.
/// </summary> /// </summary>

@ -162,6 +162,7 @@ namespace PlexRequests.Services.Jobs
public List<PlexMovie> GetPlexMovies() public List<PlexMovie> GetPlexMovies()
{ {
var settings = Plex.GetSettings();
var movies = new List<PlexMovie>(); var movies = new List<PlexMovie>();
var libs = Cache.Get<List<PlexSearch>>(CacheKeys.PlexLibaries); var libs = Cache.Get<List<PlexSearch>>(CacheKeys.PlexLibaries);
if (libs != null) if (libs != null)
@ -179,6 +180,7 @@ namespace PlexRequests.Services.Jobs
ReleaseYear = video.Year, ReleaseYear = video.Year,
Title = video.Title, Title = video.Title,
ProviderId = video.ProviderId, ProviderId = video.ProviderId,
Url = PlexHelper.GetPlexMediaUrl(settings.MachineIdentifier, video.RatingKey)
})); }));
} }
} }
@ -186,6 +188,12 @@ namespace PlexRequests.Services.Jobs
} }
public bool IsMovieAvailable(PlexMovie[] plexMovies, string title, string year, string providerId = null) public bool IsMovieAvailable(PlexMovie[] plexMovies, string title, string year, string providerId = null)
{
var movie = GetMovie(plexMovies, title, year, providerId);
return movie != null;
}
public PlexMovie GetMovie(PlexMovie[] plexMovies, string title, string year, string providerId = null)
{ {
var advanced = !string.IsNullOrEmpty(providerId); var advanced = !string.IsNullOrEmpty(providerId);
foreach (var movie in plexMovies) foreach (var movie in plexMovies)
@ -195,20 +203,21 @@ namespace PlexRequests.Services.Jobs
if (!string.IsNullOrEmpty(movie.ProviderId) && if (!string.IsNullOrEmpty(movie.ProviderId) &&
movie.ProviderId.Equals(providerId, StringComparison.InvariantCultureIgnoreCase)) movie.ProviderId.Equals(providerId, StringComparison.InvariantCultureIgnoreCase))
{ {
return true; return movie;
} }
} }
if (movie.Title.Equals(title, StringComparison.CurrentCultureIgnoreCase) && if (movie.Title.Equals(title, StringComparison.CurrentCultureIgnoreCase) &&
movie.ReleaseYear.Equals(year, StringComparison.CurrentCultureIgnoreCase)) movie.ReleaseYear.Equals(year, StringComparison.CurrentCultureIgnoreCase))
{ {
return true; return movie;
} }
} }
return false; return null;
} }
public List<PlexTvShow> GetPlexTvShows() public List<PlexTvShow> GetPlexTvShows()
{ {
var settings = Plex.GetSettings();
var shows = new List<PlexTvShow>(); var shows = new List<PlexTvShow>();
var libs = Cache.Get<List<PlexSearch>>(CacheKeys.PlexLibaries); var libs = Cache.Get<List<PlexSearch>>(CacheKeys.PlexLibaries);
if (libs != null) if (libs != null)
@ -228,7 +237,9 @@ namespace PlexRequests.Services.Jobs
Title = x.Title, Title = x.Title,
ReleaseYear = x.Year, ReleaseYear = x.Year,
ProviderId = x.ProviderId, ProviderId = x.ProviderId,
Seasons = x.Seasons?.Select(d => PlexHelper.GetSeasonNumberFromTitle(d.Title)).ToArray() Seasons = x.Seasons?.Select(d => PlexHelper.GetSeasonNumberFromTitle(d.Title)).ToArray(),
Url = PlexHelper.GetPlexMediaUrl(settings.MachineIdentifier, x.RatingKey)
})); }));
} }
} }
@ -236,6 +247,14 @@ namespace PlexRequests.Services.Jobs
} }
public bool IsTvShowAvailable(PlexTvShow[] plexShows, string title, string year, string providerId = null, int[] seasons = null) public bool IsTvShowAvailable(PlexTvShow[] plexShows, string title, string year, string providerId = null, int[] seasons = null)
{
var show = GetTvShow(plexShows, title, year, providerId, seasons);
return show != null;
}
public PlexTvShow GetTvShow(PlexTvShow[] plexShows, string title, string year, string providerId = null,
int[] seasons = null)
{ {
var advanced = !string.IsNullOrEmpty(providerId); var advanced = !string.IsNullOrEmpty(providerId);
foreach (var show in plexShows) foreach (var show in plexShows)
@ -246,23 +265,23 @@ namespace PlexRequests.Services.Jobs
{ {
if (seasons.Any(season => show.Seasons.Contains(season))) if (seasons.Any(season => show.Seasons.Contains(season)))
{ {
return true; return show;
} }
return false; return null;
} }
if (!string.IsNullOrEmpty(show.ProviderId) && if (!string.IsNullOrEmpty(show.ProviderId) &&
show.ProviderId.Equals(providerId, StringComparison.InvariantCultureIgnoreCase)) show.ProviderId.Equals(providerId, StringComparison.InvariantCultureIgnoreCase))
{ {
return true; return show;
} }
} }
if (show.Title.Equals(title, StringComparison.CurrentCultureIgnoreCase) && if (show.Title.Equals(title, StringComparison.CurrentCultureIgnoreCase) &&
show.ReleaseYear.Equals(year, StringComparison.CurrentCultureIgnoreCase)) show.ReleaseYear.Equals(year, StringComparison.CurrentCultureIgnoreCase))
{ {
return true; return show;
} }
} }
return false; return null;
} }
public bool IsEpisodeAvailable(string theTvDbId, int season, int episode) public bool IsEpisodeAvailable(string theTvDbId, int season, int episode)
@ -332,6 +351,7 @@ namespace PlexRequests.Services.Jobs
public List<PlexAlbum> GetPlexAlbums() public List<PlexAlbum> GetPlexAlbums()
{ {
var settings = Plex.GetSettings();
var albums = new List<PlexAlbum>(); var albums = new List<PlexAlbum>();
var libs = Cache.Get<List<PlexSearch>>(CacheKeys.PlexLibaries); var libs = Cache.Get<List<PlexSearch>>(CacheKeys.PlexLibaries);
if (libs != null) if (libs != null)
@ -348,7 +368,8 @@ namespace PlexRequests.Services.Jobs
{ {
Title = x.Title, Title = x.Title,
ReleaseYear = x.Year, ReleaseYear = x.Year,
Artist = x.ParentTitle Artist = x.ParentTitle,
Url = PlexHelper.GetPlexMediaUrl(settings.MachineIdentifier, x.RatingKey)
})); }));
} }
} }
@ -359,7 +380,13 @@ namespace PlexRequests.Services.Jobs
{ {
return plexAlbums.Any(x => return plexAlbums.Any(x =>
x.Title.Contains(title) && x.Title.Contains(title) &&
//x.ReleaseYear.Equals(year, StringComparison.CurrentCultureIgnoreCase) && x.Artist.Equals(artist, StringComparison.CurrentCultureIgnoreCase));
}
public PlexAlbum GetAlbum(PlexAlbum[] plexAlbums, string title, string year, string artist)
{
return plexAlbums.FirstOrDefault(x =>
x.Title.Contains(title) &&
x.Artist.Equals(artist, StringComparison.CurrentCultureIgnoreCase)); x.Artist.Equals(artist, StringComparison.CurrentCultureIgnoreCase));
} }

@ -5,5 +5,6 @@
public string Title { get; set; } public string Title { get; set; }
public string Artist { get; set; } public string Artist { get; set; }
public string ReleaseYear { get; set; } public string ReleaseYear { get; set; }
public string Url { get; set; }
} }
} }

@ -5,5 +5,6 @@
public string Title { get; set; } public string Title { get; set; }
public string ReleaseYear { get; set; } public string ReleaseYear { get; set; }
public string ProviderId { get; set; } public string ProviderId { get; set; }
public string Url { get; set; }
} }
} }

@ -6,5 +6,6 @@
public string ReleaseYear { get; set; } public string ReleaseYear { get; set; }
public string ProviderId { get; set; } public string ProviderId { get; set; }
public int[] Seasons { get; set; } public int[] Seasons { get; set; }
public string Url { get; set; }
} }
} }

@ -104,7 +104,14 @@ namespace PlexRequests.Services.Notification
private bool ValidateConfiguration(EmailNotificationSettings settings) private bool ValidateConfiguration(EmailNotificationSettings settings)
{ {
if (string.IsNullOrEmpty(settings.EmailHost) || string.IsNullOrEmpty(settings.EmailUsername) || string.IsNullOrEmpty(settings.EmailPassword) || string.IsNullOrEmpty(settings.RecipientEmail) || string.IsNullOrEmpty(settings.EmailPort.ToString())) if (settings.Authentication)
{
if (string.IsNullOrEmpty(settings.EmailUsername) || string.IsNullOrEmpty(settings.EmailPassword))
{
return false;
}
}
if (string.IsNullOrEmpty(settings.EmailHost) || string.IsNullOrEmpty(settings.RecipientEmail) || string.IsNullOrEmpty(settings.EmailPort.ToString()))
{ {
return false; return false;
} }

@ -444,7 +444,8 @@ $(function () {
imdb: result.imdbId, imdb: result.imdbId,
requested: result.requested, requested: result.requested,
approved: result.approved, approved: result.approved,
available: result.available available: result.available,
url: result.plexUrl
}; };
return context; return context;
@ -465,7 +466,8 @@ $(function () {
approved: result.approved, approved: result.approved,
available: result.available, available: result.available,
episodes: result.episodes, episodes: result.episodes,
tvFullyAvailable: result.tvFullyAvailable tvFullyAvailable: result.tvFullyAvailable,
url: result.plexUrl
}; };
return context; return context;
} }
@ -485,7 +487,8 @@ $(function () {
country: result.country, country: result.country,
requested: result.requested, requested: result.requested,
approved: result.approved, approved: result.approved,
available: result.available available: result.available,
url: result.plexUrl
}; };
return context; return context;

@ -118,9 +118,10 @@ namespace PlexRequests.UI.Helpers
public static IHtmlString LoadDateTimePickerAsset(this HtmlHelpers helper) public static IHtmlString LoadDateTimePickerAsset(this HtmlHelpers helper)
{ {
var startUrl = GetBaseUrl(); var content = GetBaseUrl();
var sb = new StringBuilder(); var sb = new StringBuilder();
var startUrl = $"{content}/Content";
sb.AppendLine($"<link rel=\"stylesheet\" href=\"{startUrl}/datepicker.min.css\" type=\"text/css\"/>"); sb.AppendLine($"<link rel=\"stylesheet\" href=\"{startUrl}/datepicker.min.css\" type=\"text/css\"/>");
sb.AppendLine($"<script src=\"{startUrl}/bootstrap-datetimepicker.min.js\"></script>"); sb.AppendLine($"<script src=\"{startUrl}/bootstrap-datetimepicker.min.js\"></script>");

@ -33,5 +33,6 @@ namespace PlexRequests.UI.Models
public bool Approved { get; set; } public bool Approved { get; set; }
public bool Requested { get; set; } public bool Requested { get; set; }
public bool Available { get; set; } public bool Available { get; set; }
public string PlexUrl { get; set; }
} }
} }

@ -31,5 +31,6 @@ namespace PlexRequests.UI.Models
public const string UsernameKey = "Username"; public const string UsernameKey = "Username";
public const string ClientDateTimeOffsetKey = "ClientDateTimeOffset"; public const string ClientDateTimeOffsetKey = "ClientDateTimeOffset";
public const string UserWizardPlexAuth = nameof(UserWizardPlexAuth); public const string UserWizardPlexAuth = nameof(UserWizardPlexAuth);
public const string UserWizardMachineId = nameof(UserWizardMachineId);
} }
} }

@ -161,7 +161,7 @@ namespace PlexRequests.UI.Modules
Post["/couchpotato"] = _ => SaveCouchPotato(); Post["/couchpotato"] = _ => SaveCouchPotato();
Get["/plex"] = _ => Plex(); Get["/plex"] = _ => Plex();
Post["/plex"] = _ => SavePlex(); Post["/plex", true] = async (x, ct) => await SavePlex();
Get["/sonarr"] = _ => Sonarr(); Get["/sonarr"] = _ => Sonarr();
Post["/sonarr"] = _ => SaveSonarr(); Post["/sonarr"] = _ => SaveSonarr();
@ -377,7 +377,7 @@ namespace PlexRequests.UI.Modules
return View["Plex", settings]; return View["Plex", settings];
} }
private Response SavePlex() private async Task<Response> SavePlex()
{ {
var plexSettings = this.Bind<PlexSettings>(); var plexSettings = this.Bind<PlexSettings>();
var valid = this.Validate(plexSettings); var valid = this.Validate(plexSettings);
@ -386,8 +386,11 @@ namespace PlexRequests.UI.Modules
return Response.AsJson(valid.SendJsonError()); return Response.AsJson(valid.SendJsonError());
} }
//Lookup identifier
var server = PlexApi.GetServer(plexSettings.PlexAuthToken);
plexSettings.MachineIdentifier = server.Server.FirstOrDefault(x => x.AccessToken == plexSettings.PlexAuthToken)?.MachineIdentifier;
var result = PlexService.SaveSettings(plexSettings); var result = await PlexService.SaveSettingsAsync(plexSettings);
return Response.AsJson(result return Response.AsJson(result
? new JsonResponseModel { Result = true, Message = "Successfully Updated the Settings for Plex!" } ? new JsonResponseModel { Result = true, Message = "Successfully Updated the Settings for Plex!" }

@ -122,7 +122,7 @@ namespace PlexRequests.UI.Modules
{ {
get get
{ {
if (Context?.CurrentUser == null) if (!LoggedIn)
{ {
return false; return false;
} }
@ -130,6 +130,9 @@ namespace PlexRequests.UI.Modules
return claims.Contains(UserClaims.Admin) || claims.Contains(UserClaims.PowerUser); return claims.Contains(UserClaims.Admin) || claims.Contains(UserClaims.PowerUser);
} }
} }
protected bool LoggedIn => Context?.CurrentUser != null;
protected string Culture { get; set; } protected string Culture { get; set; }
protected const string CultureCookieName = "_culture"; protected const string CultureCookieName = "_culture";
protected Response SetCookie() protected Response SetCookie()

@ -30,6 +30,7 @@ using System.Dynamic;
using Nancy; using Nancy;
using Nancy.Authentication.Forms; using Nancy.Authentication.Forms;
using Nancy.Extensions; using Nancy.Extensions;
using Nancy.Linker;
using Nancy.Responses.Negotiation; using Nancy.Responses.Negotiation;
using Nancy.Security; using Nancy.Security;
@ -42,20 +43,22 @@ namespace PlexRequests.UI.Modules
{ {
public class LoginModule : BaseModule public class LoginModule : BaseModule
{ {
public LoginModule(ISettingsService<PlexRequestSettings> pr, ICustomUserMapper m) : base(pr) public LoginModule(ISettingsService<PlexRequestSettings> pr, ICustomUserMapper m, IResourceLinker linker) : base(pr)
{ {
UserMapper = m; UserMapper = m;
Get["/login"] = _ => Get["/login"] = _ =>
{ {
if (LoggedIn)
{ {
var url = linker.BuildRelativeUri(Context, "SearchIndex");
return Response.AsRedirect(url.ToString());
}
dynamic model = new ExpandoObject(); dynamic model = new ExpandoObject();
model.Redirect = Request.Query.redirect.Value ?? string.Empty; model.Redirect = Request.Query.redirect.Value ?? string.Empty;
model.Errored = Request.Query.error.HasValue; model.Errored = Request.Query.error.HasValue;
var adminCreated = UserMapper.DoUsersExist(); var adminCreated = UserMapper.DoUsersExist();
model.AdminExists = adminCreated; model.AdminExists = adminCreated;
return View["Index", model]; return View["Index", model];
}
}; };
Get["/logout"] = x => this.LogoutAndRedirect(!string.IsNullOrEmpty(BaseUrl) ? $"~/{BaseUrl}/" : "~/"); Get["/logout"] = x => this.LogoutAndRedirect(!string.IsNullOrEmpty(BaseUrl) ? $"~/{BaseUrl}/" : "~/");
@ -80,7 +83,8 @@ namespace PlexRequests.UI.Modules
} }
Session[SessionKeys.UsernameKey] = username; Session[SessionKeys.UsernameKey] = username;
Session[SessionKeys.ClientDateTimeOffsetKey] = dtOffset; Session[SessionKeys.ClientDateTimeOffsetKey] = dtOffset;
if(redirect.Contains("userlogin")){ if (redirect.Contains("userlogin"))
{
redirect = !string.IsNullOrEmpty(BaseUrl) ? $"/{BaseUrl}/search" : "/search"; redirect = !string.IsNullOrEmpty(BaseUrl) ? $"/{BaseUrl}/search" : "/search";
} }
return this.LoginAndRedirect(userId.Value, expiry, redirect); return this.LoginAndRedirect(userId.Value, expiry, redirect);

@ -110,7 +110,7 @@ namespace PlexRequests.UI.Modules
Get["movie/{searchTerm}", true] = async (x, ct) => await SearchMovie((string)x.searchTerm); Get["movie/{searchTerm}", true] = async (x, ct) => await SearchMovie((string)x.searchTerm);
Get["tv/{searchTerm}", true] = async (x, ct) => await SearchTvShow((string)x.searchTerm); Get["tv/{searchTerm}", true] = async (x, ct) => await SearchTvShow((string)x.searchTerm);
Get["music/{searchTerm}", true] = async (x, ct) => await SearchMusic((string)x.searchTerm); Get["music/{searchTerm}", true] = async (x, ct) => await SearchAlbum((string)x.searchTerm);
Get["music/coverArt/{id}"] = p => GetMusicBrainzCoverArt((string)p.id); Get["music/coverArt/{id}"] = p => GetMusicBrainzCoverArt((string)p.id);
Get["movie/upcoming", true] = async (x, ct) => await UpcomingMovies(); Get["movie/upcoming", true] = async (x, ct) => await UpcomingMovies();
@ -252,9 +252,11 @@ namespace PlexRequests.UI.Modules
VoteCount = movie.VoteCount VoteCount = movie.VoteCount
}; };
var canSee = CanUserSeeThisRequest(viewMovie.Id, settings.UsersCanViewOnlyOwnRequests, dbMovies); var canSee = CanUserSeeThisRequest(viewMovie.Id, settings.UsersCanViewOnlyOwnRequests, dbMovies);
if (Checker.IsMovieAvailable(plexMovies.ToArray(), movie.Title, movie.ReleaseDate?.Year.ToString())) var plexMovie = Checker.GetMovie(plexMovies.ToArray(), movie.Title, movie.ReleaseDate?.Year.ToString());
if (plexMovie != null)
{ {
viewMovie.Available = true; viewMovie.Available = true;
viewMovie.PlexUrl = plexMovie.Url;
} }
else if (dbMovies.ContainsKey(movie.Id) && canSee) // compare to the requests db else if (dbMovies.ContainsKey(movie.Id) && canSee) // compare to the requests db
{ {
@ -343,9 +345,12 @@ namespace PlexRequests.UI.Modules
providerId = viewT.Id.ToString(); providerId = viewT.Id.ToString();
} }
if (Checker.IsTvShowAvailable(plexTvShows.ToArray(), t.show.name, t.show.premiered?.Substring(0, 4), providerId)) var plexShow = Checker.GetTvShow(plexTvShows.ToArray(), t.show.name, t.show.premiered?.Substring(0, 4),
providerId);
if (plexShow != null)
{ {
viewT.Available = true; viewT.Available = true;
viewT.PlexUrl = plexShow.Url;
} }
else if (t.show?.externals?.thetvdb != null) else if (t.show?.externals?.thetvdb != null)
{ {
@ -371,7 +376,7 @@ namespace PlexRequests.UI.Modules
return Response.AsJson(viewTv); return Response.AsJson(viewTv);
} }
private async Task<Response> SearchMusic(string searchTerm) private async Task<Response> SearchAlbum(string searchTerm)
{ {
Analytics.TrackEventAsync(Category.Search, Action.Album, searchTerm, Username, CookieHelper.GetAnalyticClientId(Cookies)); Analytics.TrackEventAsync(Category.Search, Action.Album, searchTerm, Username, CookieHelper.GetAnalyticClientId(Cookies));
var apiAlbums = new List<Release>(); var apiAlbums = new List<Release>();
@ -405,9 +410,11 @@ namespace PlexRequests.UI.Modules
DateTime release; DateTime release;
DateTimeHelper.CustomParse(a.ReleaseEvents?.FirstOrDefault()?.date, out release); DateTimeHelper.CustomParse(a.ReleaseEvents?.FirstOrDefault()?.date, out release);
var artist = a.ArtistCredit?.FirstOrDefault()?.artist; var artist = a.ArtistCredit?.FirstOrDefault()?.artist;
if (Checker.IsAlbumAvailable(plexAlbums.ToArray(), a.title, release.ToString("yyyy"), artist?.name)) var plexAlbum = Checker.GetAlbum(plexAlbums.ToArray(), a.title, release.ToString("yyyy"), artist?.name);
if (plexAlbum != null)
{ {
viewA.Available = true; viewA.Available = true;
viewA.PlexUrl = plexAlbum.Url;
} }
if (!string.IsNullOrEmpty(a.id) && dbAlbum.ContainsKey(a.id)) if (!string.IsNullOrEmpty(a.id) && dbAlbum.ContainsKey(a.id))
{ {

@ -34,7 +34,7 @@ using Nancy.Extensions;
using Nancy.ModelBinding; using Nancy.ModelBinding;
using Nancy.Responses.Negotiation; using Nancy.Responses.Negotiation;
using Nancy.Validation; using Nancy.Validation;
using NLog;
using PlexRequests.Api.Interfaces; using PlexRequests.Api.Interfaces;
using PlexRequests.Core; using PlexRequests.Core;
using PlexRequests.Core.SettingModels; using PlexRequests.Core.SettingModels;
@ -84,6 +84,8 @@ namespace PlexRequests.UI.Modules
private ICustomUserMapper Mapper { get; } private ICustomUserMapper Mapper { get; }
private IAnalytics Analytics { get; } private IAnalytics Analytics { get; }
private static Logger Log = LogManager.GetCurrentClassLogger();
private Response PlexAuth() private Response PlexAuth()
{ {
@ -106,6 +108,7 @@ namespace PlexRequests.UI.Modules
var servers = PlexApi.GetServer(model.user.authentication_token); var servers = PlexApi.GetServer(model.user.authentication_token);
var firstServer = servers.Server.FirstOrDefault(); var firstServer = servers.Server.FirstOrDefault();
return Response.AsJson(new { Result = true, firstServer?.Port, Ip = firstServer?.LocalAddresses, firstServer?.Scheme }); return Response.AsJson(new { Result = true, firstServer?.Port, Ip = firstServer?.LocalAddresses, firstServer?.Scheme });
} }
@ -119,6 +122,20 @@ namespace PlexRequests.UI.Modules
} }
form.PlexAuthToken = Session[SessionKeys.UserWizardPlexAuth].ToString(); // Set the auth token from the previous form form.PlexAuthToken = Session[SessionKeys.UserWizardPlexAuth].ToString(); // Set the auth token from the previous form
// Get the machine ID from the settings (This could have changed)
try
{
var servers = PlexApi.GetServer(form.PlexAuthToken);
var firstServer = servers.Server.FirstOrDefault(x => x.AccessToken == form.PlexAuthToken);
Session[SessionKeys.UserWizardMachineId] = firstServer?.MachineIdentifier;
}
catch (Exception e)
{
// Probably bad settings, just continue
Log.Error(e);
}
var result = await PlexSettings.SaveSettingsAsync(form); var result = await PlexSettings.SaveSettingsAsync(form);
if (result) if (result)
{ {

@ -440,4 +440,7 @@
<data name="Requests_ReleaseDate_Unavailable" xml:space="preserve"> <data name="Requests_ReleaseDate_Unavailable" xml:space="preserve">
<value>There is no information available for the release date</value> <value>There is no information available for the release date</value>
</data> </data>
<data name="Search_ViewInPlex" xml:space="preserve">
<value>View In Plex</value>
</data>
</root> </root>

@ -987,6 +987,15 @@ namespace PlexRequests.UI.Resources {
} }
} }
/// <summary>
/// Looks up a localized string similar to View In Plex.
/// </summary>
public static string Search_ViewInPlex {
get {
return ResourceManager.GetString("Search_ViewInPlex", resourceCulture);
}
}
/// <summary> /// <summary>
/// Looks up a localized string similar to You have reached your weekly request limit for Albums! Please contact your admin.. /// Looks up a localized string similar to You have reached your weekly request limit for Albums! Please contact your admin..
/// </summary> /// </summary>

@ -175,6 +175,8 @@
{{#if_eq type "movie"}} {{#if_eq type "movie"}}
{{#if_eq available true}} {{#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> <button style="text-align: right" class="btn btn-success-outline disabled" disabled><i class="fa fa-check"></i> @UI.Search_Available</button>
<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}} {{else}}
{{#if_eq requested true}} {{#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> <button style="text-align: right" class="btn btn-primary-outline disabled" disabled><i class="fa fa-check"></i> @UI.Search_Requested</button>
@ -186,7 +188,8 @@
{{#if_eq type "tv"}} {{#if_eq type "tv"}}
{{#if_eq tvFullyAvailable true}} {{#if_eq tvFullyAvailable true}}
@*//TODO Not used yet*@ @*//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> <button style="text-align: right" class="btn btn-success-outline disabled" disabled><i class="fa fa-check"></i> @UI.Search_Available</button><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}} {{else}}
<div class="dropdown"> <div class="dropdown">
<button id="{{id}}" class="btn btn-primary-outline dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true"> <button id="{{id}}" class="btn btn-primary-outline dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
@ -259,7 +262,8 @@
<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 available true}} {{#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> <button style="text-align: right" class="btn btn-success-outline disabled" disabled><i class="fa fa-check"></i> @UI.Search_Available</button><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}} {{else}}
{{#if_eq requested true}} {{#if_eq requested true}}
<button style="text-align: right" class="btn btn-success-outline disabled" disabled><i class="fa fa-check"></i> @UI.Search_Requested</button> <button style="text-align: right" class="btn btn-success-outline disabled" disabled><i class="fa fa-check"></i> @UI.Search_Requested</button>

Loading…
Cancel
Save