mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-07-16 02:02:55 -07:00
Additional movie information
This commit is contained in:
parent
1ddb6c7f01
commit
16c94f2414
7 changed files with 316 additions and 14 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\CouchPotatoStatus.cs" />
|
||||
<Compile Include="Movie\CouchPotatoApiKey.cs" />
|
||||
<Compile Include="Movie\TmdbMovieDetails.cs" />
|
||||
<Compile Include="Music\HeadphonesAlbumSearchResult.cs" />
|
||||
<Compile Include="Music\HeadphonesArtistSearchResult.cs" />
|
||||
<Compile Include="Music\HeadphonesGetIndex.cs" />
|
||||
|
|
|
@ -32,6 +32,8 @@ namespace Ombi.Api
|
|||
public abstract class MovieBase
|
||||
{
|
||||
private static readonly string Encrypted = "0T3QNSseexLO7n7UPiJvl70Y+KKnvbeTlsusl7Kwq0hPH0BHOuFNGwksNCjkwqWedyDdI/MJeUR4wtL4bIl0Z+//uHXEaYM/4H2pjeLbH5EWdUe5TTj1AhaIR5PQweamvcienRyFD/3YPCC/+qL5mHkKXBkPumMod3Zb/4yN0Ik=";
|
||||
protected string ApiKey = StringCipher.Decrypt(Encrypted, "ApiKey");
|
||||
private string _apiKey;
|
||||
|
||||
protected string ApiKey => _apiKey ?? (_apiKey = StringCipher.Decrypt(Encrypted, "ApiKey"));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,12 +25,17 @@
|
|||
// ************************************************************************/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using NLog.Fluent;
|
||||
using Ombi.Api.Models.Movie;
|
||||
using RestSharp;
|
||||
using TMDbLib.Client;
|
||||
using TMDbLib.Objects.General;
|
||||
using TMDbLib.Objects.Movies;
|
||||
using TMDbLib.Objects.Search;
|
||||
using Movie = TMDbLib.Objects.Movies.Movie;
|
||||
|
||||
namespace Ombi.Api
|
||||
{
|
||||
|
@ -39,9 +44,12 @@ namespace Ombi.Api
|
|||
public TheMovieDbApi()
|
||||
{
|
||||
Client = new TMDbClient(ApiKey);
|
||||
Api = new ApiRequest();
|
||||
}
|
||||
|
||||
private ApiRequest Api { get; }
|
||||
public TMDbClient Client { get; set; }
|
||||
private const string BaseUrl = "https://api.themoviedb.org/3/";
|
||||
public async Task<List<SearchMovie>> SearchMovie(string searchTerm)
|
||||
{
|
||||
var results = await Client.SearchMovie(searchTerm);
|
||||
|
@ -56,7 +64,27 @@ namespace Ombi.Api
|
|||
public async Task<List<MovieResult>> GetUpcomingMovies()
|
||||
{
|
||||
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)
|
||||
|
|
|
@ -47,5 +47,8 @@ namespace Ombi.UI.Models
|
|||
public double VoteAverage { get; set; }
|
||||
public int VoteCount { get; set; }
|
||||
public bool AlreadyInCp { get; set; }
|
||||
public string Trailer { get; set; }
|
||||
public string Homepage { get; set; }
|
||||
public string ImdbId { get; set; }
|
||||
}
|
||||
}
|
|
@ -266,17 +266,6 @@ namespace Ombi.UI.Modules
|
|||
var counter = 0;
|
||||
foreach (var movie in apiMovies)
|
||||
{
|
||||
var imdbId = string.Empty;
|
||||
if (counter <= 5) // Let's only do it for the first 5 items
|
||||
{
|
||||
var movieInfoTask = await MovieApi.GetMovieInformation(movie.Id).ConfigureAwait(false);
|
||||
|
||||
// TODO needs to be careful about this, it's adding extra time to search...
|
||||
// https://www.themoviedb.org/talk/5807f4cdc3a36812160041f2
|
||||
imdbId = movieInfoTask?.ImdbId;
|
||||
counter++;
|
||||
}
|
||||
|
||||
var viewMovie = new SearchMovieViewModel
|
||||
{
|
||||
Adult = movie.Adult,
|
||||
|
@ -294,6 +283,28 @@ namespace Ombi.UI.Modules
|
|||
VoteAverage = movie.VoteAverage,
|
||||
VoteCount = movie.VoteCount
|
||||
};
|
||||
|
||||
var imdbId = string.Empty;
|
||||
if (counter <= 5) // Let's only do it for the first 5 items
|
||||
{
|
||||
var movieInfo = MovieApi.GetMovieInformationWithVideos(movie.Id);
|
||||
|
||||
// TODO needs to be careful about this, it's adding extra time to search...
|
||||
// https://www.themoviedb.org/talk/5807f4cdc3a36812160041f2
|
||||
viewMovie.ImdbId = movieInfo?.imdb_id;
|
||||
viewMovie.Homepage = movieInfo?.homepage;
|
||||
var videoId = movieInfo?.video ?? false
|
||||
? movieInfo?.videos?.results?.FirstOrDefault()?.key
|
||||
: string.Empty;
|
||||
|
||||
viewMovie.Trailer = string.IsNullOrEmpty(videoId)
|
||||
? string.Empty
|
||||
: $"https://www.youtube.com/watch?v={videoId}";
|
||||
|
||||
counter++;
|
||||
}
|
||||
|
||||
|
||||
var canSee = CanUserSeeThisRequest(viewMovie.Id, Security.HasPermissions(User, Permissions.UsersCanViewOnlyOwnRequests), dbMovies);
|
||||
var plexMovie = Checker.GetMovie(plexMovies.ToArray(), movie.Title, movie.ReleaseDate?.Year.ToString(),
|
||||
imdbId);
|
||||
|
|
|
@ -117,8 +117,161 @@
|
|||
</div>
|
||||
}
|
||||
|
||||
<!-- 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-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="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}}
|
||||
|
||||
<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>
|
||||
<!-- Description -->
|
||||
<p style="font-size:0.9rem !important">{{overview}}</p>
|
||||
<br />
|
||||
<br />
|
||||
|
||||
<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-template2" type="text/x-handlebars-template">
|
||||
<div class="row">
|
||||
<div id="{{id}}imgDiv" class="col-sm-2">
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue