diff --git a/PlexRequests.UI/Content/search.js b/PlexRequests.UI/Content/search.js index 1096290ed..610f1399d 100644 --- a/PlexRequests.UI/Content/search.js +++ b/PlexRequests.UI/Content/search.js @@ -274,7 +274,10 @@ $(function () { voteAverage: result.voteAverage, year: year, type: "movie", - imdb: result.imdbId + imdb: result.imdbId, + requested: result.requested, + approved: result.approved, + available: result.available }; return context; @@ -290,7 +293,10 @@ $(function () { overview: result.overview, year: year, type: "tv", - imdb: result.imdbId + imdb: result.imdbId, + requested: result.requested, + approved: result.approved, + available: result.available }; return context; } @@ -307,7 +313,10 @@ $(function () { coverArtUrl: result.coverArtUrl, artist: result.artist, releaseType: result.releaseType, - country: result.country + country: result.country, + requested: result.requested, + approved: result.approved, + available: result.available }; return context; diff --git a/PlexRequests.UI/Models/SearchMovieViewModel.cs b/PlexRequests.UI/Models/SearchMovieViewModel.cs new file mode 100644 index 000000000..dc7c51a33 --- /dev/null +++ b/PlexRequests.UI/Models/SearchMovieViewModel.cs @@ -0,0 +1,50 @@ +#region Copyright +// /************************************************************************ +// Copyright (c) 2016 Jamie Rees +// File: SearchTvShowViewModel.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; +using System.Collections.Generic; + +namespace PlexRequests.UI.Models +{ + public class SearchMovieViewModel : SearchViewModel + { + public bool Adult { get; set; } + public string BackdropPath { get; set; } + public List GenreIds { get; set; } + public int Id { get; set; } + public string OriginalLanguage { get; set; } + public string OriginalTitle { get; set; } + public string Overview { get; set; } + public double Popularity { get; set; } + public string PosterPath { get; set; } + public DateTime? ReleaseDate { get; set; } + public string Title { get; set; } + public bool Video { get; set; } + public double VoteAverage { get; set; } + public int VoteCount { get; set; } + } +} \ No newline at end of file diff --git a/PlexRequests.UI/Models/SearchMusicViewModel.cs b/PlexRequests.UI/Models/SearchMusicViewModel.cs index 94d3e6d1e..66d140a12 100644 --- a/PlexRequests.UI/Models/SearchMusicViewModel.cs +++ b/PlexRequests.UI/Models/SearchMusicViewModel.cs @@ -1,41 +1,41 @@ -#region Copyright -// /************************************************************************ -// Copyright (c) 2016 Jamie Rees -// File: SearchMusicViewModel.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 -namespace PlexRequests.UI.Models -{ - public class SearchMusicViewModel - { - public string Id { get; set; } - public string Overview { get; set; } - public string CoverArtUrl { get; set; } - public string Title { get; set; } - public string Artist { get; set; } - public string ReleaseDate { get; set; } - public int TrackCount { get; set; } - public string ReleaseType { get; set; } - public string Country { get; set; } - } +#region Copyright +// /************************************************************************ +// Copyright (c) 2016 Jamie Rees +// File: SearchMusicViewModel.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 +namespace PlexRequests.UI.Models +{ + public class SearchMusicViewModel : SearchViewModel + { + public string Id { get; set; } + public string Overview { get; set; } + public string CoverArtUrl { get; set; } + public string Title { get; set; } + public string Artist { get; set; } + public string ReleaseDate { get; set; } + public int TrackCount { get; set; } + public string ReleaseType { get; set; } + public string Country { get; set; } + } } \ No newline at end of file diff --git a/PlexRequests.UI/Models/SearchTvShowViewModel.cs b/PlexRequests.UI/Models/SearchTvShowViewModel.cs index ee6de42d1..2ed46beff 100644 --- a/PlexRequests.UI/Models/SearchTvShowViewModel.cs +++ b/PlexRequests.UI/Models/SearchTvShowViewModel.cs @@ -29,7 +29,7 @@ using System.Collections.Generic; namespace PlexRequests.UI.Models { - public class SearchTvShowViewModel + public class SearchTvShowViewModel : SearchViewModel { public int Id { get; set; } public string SeriesName { get; set; } diff --git a/PlexRequests.UI/Models/SearchViewModel.cs b/PlexRequests.UI/Models/SearchViewModel.cs new file mode 100644 index 000000000..776b9d2b1 --- /dev/null +++ b/PlexRequests.UI/Models/SearchViewModel.cs @@ -0,0 +1,37 @@ +#region Copyright +// /************************************************************************ +// Copyright (c) 2016 Jamie Rees +// File: SearchTvShowViewModel.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 + + +namespace PlexRequests.UI.Models +{ + public class SearchViewModel + { + public bool Approved { get; set; } + public bool Requested { get; set; } + public bool Available { get; set; } + } +} \ No newline at end of file diff --git a/PlexRequests.UI/Modules/SearchModule.cs b/PlexRequests.UI/Modules/SearchModule.cs index 5b541091c..7e001c489 100644 --- a/PlexRequests.UI/Modules/SearchModule.cs +++ b/PlexRequests.UI/Modules/SearchModule.cs @@ -48,6 +48,9 @@ using PlexRequests.Services.Notification; using PlexRequests.Store; using PlexRequests.UI.Helpers; using PlexRequests.UI.Models; +using System.Threading.Tasks; +using TMDbLib.Objects.Search; +using PlexRequests.Api.Models.Tv; namespace PlexRequests.UI.Modules { @@ -109,7 +112,8 @@ namespace PlexRequests.UI.Modules private IHeadphonesApi HeadphonesApi { get; } private static Logger Log = LogManager.GetCurrentClassLogger(); - private bool IsAdmin { + private bool IsAdmin + { get { return Context.CurrentUser.IsAuthenticated(); @@ -124,29 +128,168 @@ namespace PlexRequests.UI.Modules return View["Search/Index", settings]; } + private Response UpcomingMovies() + { + Log.Trace("Loading upcoming movies"); + + return ProcessMovies(new Task>(() => + { + return MovieApi.GetUpcomingMovies().Result.Select(x => new SearchMovie() + { + Adult = x.Adult, + BackdropPath = x.BackdropPath, + GenreIds = x.GenreIds, + Id = x.Id, + OriginalLanguage = x.OriginalLanguage, + OriginalTitle = x.OriginalTitle, + Overview = x.Overview, + Popularity = x.Popularity, + PosterPath = x.PosterPath, + ReleaseDate = x.ReleaseDate, + Title = x.Title, + Video = x.Video, + VoteAverage = x.VoteAverage, + VoteCount = x.VoteCount + }).ToList(); + })); + } + + private Response CurrentlyPlayingMovies() + { + Log.Trace("Loading currently playing movies"); + + return ProcessMovies(new Task>(() => + { + return MovieApi.GetCurrentPlayingMovies().Result.Select(x => new SearchMovie() + { + Adult = x.Adult, + BackdropPath = x.BackdropPath, + GenreIds = x.GenreIds, + Id = x.Id, + OriginalLanguage = x.OriginalLanguage, + OriginalTitle = x.OriginalTitle, + Overview = x.Overview, + Popularity = x.Popularity, + PosterPath = x.PosterPath, + ReleaseDate = x.ReleaseDate, + Title = x.Title, + Video = x.Video, + VoteAverage = x.VoteAverage, + VoteCount = x.VoteCount + }).ToList(); + })); + } + private Response SearchMovie(string searchTerm) { Log.Trace("Searching for Movie {0}", searchTerm); - var movies = MovieApi.SearchMovie(searchTerm); - var result = movies.Result; - return Response.AsJson(result); + + return ProcessMovies(new Task>(() => + { + return MovieApi.SearchMovie(searchTerm).Result; + })); + } + + private Response ProcessMovies(Task> apiTask) + { + List taskList = new List(); + + List apiMovies = new List(); + + apiTask.ContinueWith((t) => + { + apiMovies = t.Result; + }); + taskList.Add(apiTask); + apiTask.Start(); + + Dictionary dbMovies = new Dictionary(); + taskList.Add(Task.Factory.StartNew(() => + { + return RequestService.GetAll().Where(x => x.Type == RequestType.Movie); + + }).ContinueWith((t) => + { + dbMovies = t.Result.ToDictionary(x => x.ProviderId); + })); + + Task.WaitAll(taskList.ToArray()); + + List viewMovies = new List(); + foreach (SearchMovie movie in apiMovies) + { + var viewMovie = new SearchMovieViewModel() + { + Adult = movie.Adult, + BackdropPath = movie.BackdropPath, + GenreIds = movie.GenreIds, + Id = movie.Id, + OriginalLanguage = movie.OriginalLanguage, + OriginalTitle = movie.OriginalTitle, + Overview = movie.Overview, + Popularity = movie.Popularity, + PosterPath = movie.PosterPath, + ReleaseDate = movie.ReleaseDate, + Title = movie.Title, + Video = movie.Video, + VoteAverage = movie.VoteAverage, + VoteCount = movie.VoteCount + }; + + if (dbMovies.ContainsKey(movie.Id)) + { + var dbm = dbMovies[movie.Id]; + + viewMovie.Requested = true; + viewMovie.Approved = dbm.Approved; + viewMovie.Available = dbm.Available; + } + + viewMovies.Add(viewMovie); + } + + return Response.AsJson(viewMovies); } private Response SearchTvShow(string searchTerm) { Log.Trace("Searching for TV Show {0}", searchTerm); - //var tvShow = TvApi.SearchTv(searchTerm, AuthToken); - var tvShow = new TvMazeApi().Search(searchTerm); - if (!tvShow.Any()) + + List taskList = new List(); + + List apiTv = new List(); + taskList.Add(Task.Factory.StartNew(() => + { + return new TvMazeApi().Search(searchTerm); + + }).ContinueWith((t) => + { + apiTv = t.Result; + })); + + Dictionary dbTv = new Dictionary(); + taskList.Add(Task.Factory.StartNew(() => + { + return RequestService.GetAll().Where(x => x.Type == RequestType.TvShow); + + }).ContinueWith((t) => + { + dbTv = t.Result.ToDictionary(x => x.ProviderId); + })); + + Task.WaitAll(taskList.ToArray()); + + if (!apiTv.Any()) { Log.Trace("TV Show data is null"); return Response.AsJson(""); } - var model = new List(); - foreach (var t in tvShow) + + var viewTv = new List(); + foreach (var t in apiTv) { - model.Add(new SearchTvShowViewModel + var viewT = new SearchTvShowViewModel { // We are constructing the banner with the id: // http://thetvdb.com/banners/_cache/posters/ID-1.jpg @@ -161,24 +304,56 @@ namespace PlexRequests.UI.Modules Runtime = t.show.runtime.ToString(), SeriesId = t.show.id, SeriesName = t.show.name, + Status = t.show.status + }; - Status = t.show.status, - }); + if (t.show.externals.thetvdb != null && dbTv.ContainsKey((int)t.show.externals.thetvdb)) + { + var dbt = dbTv[(int)t.show.externals.thetvdb]; + + viewT.Requested = true; + viewT.Approved = dbt.Approved; + viewT.Available = dbt.Available; + } + + viewTv.Add(viewT); } Log.Trace("Returning TV Show results: "); - Log.Trace(model.DumpJson()); - return Response.AsJson(model); + Log.Trace(viewTv.DumpJson()); + return Response.AsJson(viewTv); } private Response SearchMusic(string searchTerm) { - var albums = MusicBrainzApi.SearchAlbum(searchTerm); - var releases = albums.releases ?? new List(); - var model = new List(); - foreach (var a in releases) + List taskList = new List(); + + List apiAlbums = new List(); + taskList.Add(Task.Factory.StartNew(() => + { + return MusicBrainzApi.SearchAlbum(searchTerm); + + }).ContinueWith((t) => { - model.Add(new SearchMusicViewModel + apiAlbums = t.Result.releases ?? new List(); + })); + + Dictionary dbAlbum = new Dictionary(); + taskList.Add(Task.Factory.StartNew(() => + { + return RequestService.GetAll().Where(x => x.Type == RequestType.Album); + + }).ContinueWith((t) => + { + dbAlbum = t.Result.ToDictionary(x => x.MusicBrainzId); + })); + + Task.WaitAll(taskList.ToArray()); + + var viewAlbum = new List(); + foreach (var a in apiAlbums) + { + var viewA = new SearchMusicViewModel { Title = a.title, Id = a.id, @@ -188,27 +363,20 @@ namespace PlexRequests.UI.Modules TrackCount = a.TrackCount, ReleaseType = a.status, Country = a.country - }); - } - return Response.AsJson(model); - } + }; - private Response UpcomingMovies() // TODO : Not used - { - var movies = MovieApi.GetUpcomingMovies(); - var result = movies.Result; - Log.Trace("Movie Upcoming Results: "); - Log.Trace(result.DumpJson()); - return Response.AsJson(result); - } + if (!string.IsNullOrEmpty(a.id) && dbAlbum.ContainsKey(a.id)) + { + var dba = dbAlbum[a.id]; - private Response CurrentlyPlayingMovies() // TODO : Not used - { - var movies = MovieApi.GetCurrentPlayingMovies(); - var result = movies.Result; - Log.Trace("Movie Currently Playing Results: "); - Log.Trace(result.DumpJson()); - return Response.AsJson(result); + viewA.Requested = true; + viewA.Approved = dba.Approved; + viewA.Available = dba.Available; + } + + viewAlbum.Add(viewA); + } + return Response.AsJson(viewAlbum); } private Response RequestMovie(int movieId) @@ -241,7 +409,7 @@ namespace PlexRequests.UI.Modules try { - if (CheckIfTitleExistsInPlex(movieInfo.Title, movieInfo.ReleaseDate?.Year.ToString(),null, PlexType.Movie)) + if (CheckIfTitleExistsInPlex(movieInfo.Title, movieInfo.ReleaseDate?.Year.ToString(), null, PlexType.Movie)) { return Response.AsJson(new JsonResponseModel { Result = false, Message = $"{fullMovieName} is already in Plex!" }); } @@ -502,7 +670,7 @@ namespace PlexRequests.UI.Modules Log.Debug("This is a new request"); - + var albumInfo = MusicBrainzApi.GetAlbum(releaseId); DateTime release; DateTimeHelper.CustomParse(albumInfo.ReleaseEvents?.FirstOrDefault()?.date, out release); @@ -581,7 +749,7 @@ namespace PlexRequests.UI.Modules Message = $"{model.Title} was successfully added!" }); } - + var result = RequestService.AddRequest(model); return Response.AsJson(new JsonResponseModel { diff --git a/PlexRequests.UI/PlexRequests.UI.csproj b/PlexRequests.UI/PlexRequests.UI.csproj index e822b1a70..e7076ef55 100644 --- a/PlexRequests.UI/PlexRequests.UI.csproj +++ b/PlexRequests.UI/PlexRequests.UI.csproj @@ -170,7 +170,9 @@ + + diff --git a/PlexRequests.UI/Views/Search/Index.cshtml b/PlexRequests.UI/Views/Search/Index.cshtml index e5c316a79..3f89e1c14 100644 --- a/PlexRequests.UI/Views/Search/Index.cshtml +++ b/PlexRequests.UI/Views/Search/Index.cshtml @@ -124,21 +124,29 @@
- {{#if_eq type "movie"}} - - {{/if_eq}} - {{#if_eq type "tv"}} - + {{#if_eq available true}} + + {{else}} + {{#if_eq requested true}} + + {{else}} + {{#if_eq type "movie"}} + + {{/if_eq}} + {{#if_eq type "tv"}} + + {{/if_eq}} + {{/if_eq}} {{/if_eq}}

@@ -181,8 +189,15 @@
- - + {{#if_eq available true}} + + {{else}} + {{#if_eq requested true}} + + {{else}} + + {{/if_eq}} + {{/if_eq}}
Track Count: {{trackCount}} Country: {{country}}