Started switching the TV over to the new provider (TheTVDB). Currently TV search is partially broken. It will search but we are not mapping all of the details

This commit is contained in:
tidusjar 2016-03-02 17:21:11 +00:00
parent ff81e67ab0
commit 9ce08902d7
15 changed files with 173 additions and 54 deletions

View file

@ -28,7 +28,7 @@ using System.Collections.Generic;
namespace RequestPlex.Api.Models.Tv
{
public class TvShow
public class TvShowSearchResult
{
public int id { get; set; }
public int airedSeason { get; set; }
@ -63,6 +63,6 @@ namespace RequestPlex.Api.Models.Tv
public class TvSearchResult
{
public TvShow[] data { get; set; }
public List<TvShowSearchResult> data { get; set; }
}
}

View file

@ -0,0 +1,55 @@
#region Copyright
// /************************************************************************
// Copyright (c) 2016 Jamie Rees
// File: TvShow.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 RequestPlex.Api.Models.Tv
{
public class TvShow
{
public int id { get; set; }
public string seriesName { get; set; }
public List<string> aliases { get; set; }
public string banner { get; set; }
public int seriesId { get; set; }
public string status { get; set; }
public string firstAired { get; set; }
public string network { get; set; }
public string networkId { get; set; }
public string runtime { get; set; }
public List<string> genre { get; set; }
public string overview { get; set; }
public int lastUpdated { get; set; }
public string airsDayOfWeek { get; set; }
public string airsTime { get; set; }
public string rating { get; set; }
public string imdbId { get; set; }
public string zap2itId { get; set; }
public string added { get; set; }
public int siteRating { get; set; }
}
}

View file

@ -1,7 +1,7 @@
#region Copyright
// /************************************************************************
// Copyright (c) 2016 Jamie Rees
// File: MovieBase.cs
// File: TvBase.cs
// Created By: Jamie Rees
//
// Permission is hereby granted, free of charge, to any person obtaining
@ -30,10 +30,9 @@ using RequestPlex.Helpers;
namespace RequestPlex.Api
{
public abstract class TvBase
public abstract class MovieBase
{
private static readonly string Encrypted = "0T3QNSseexLO7n7UPiJvl70Y+KKnvbeTlsusl7Kwq0hPH0BHOuFNGwksNCjkwqWedyDdI/MJeUR4wtL4bIl0Z+//uHXEaYM/4H2pjeLbH5EWdUe5TTj1AhaIR5PQweamvcienRyFD/3YPCC/+qL5mHkKXBkPumMod3Zb/4yN0Ik=";
protected string ApiKey = StringCipher.Decrypt(Encrypted, "ApiKey");
protected Uri Url = new Uri("http://api.themoviedb.org/3");
}
}

View file

@ -66,10 +66,11 @@
<Compile Include="Models\PlexUserRequest.cs" />
<Compile Include="Models\Tv\Authentication.cs" />
<Compile Include="Models\Tv\TvSearchResult.cs" />
<Compile Include="TvBase.cs" />
<Compile Include="Models\Tv\TvShow.cs" />
<Compile Include="MovieBase.cs" />
<Compile Include="PlexApi.cs" />
<Compile Include="TheMovieDbApi.cs" />
<Compile Include="MovieBase.cs" />
<Compile Include="TvBase.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="TheTvDbApi.cs" />
</ItemGroup>

View file

@ -45,18 +45,21 @@ namespace RequestPlex.Api
/// Authenticates against TheTVDB.
/// </summary>
/// <returns></returns>
public Authentication Authenticate()
public string Authenticate()
{
var request = new RestRequest
{
Method = Method.POST,
Resource = "login"
Resource = "login",
RequestFormat = DataFormat.Json,
};
var apiKey = new { apikey = ApiKey };
var json = JsonConvert.SerializeObject(apiKey);
request.AddBody(json);
request.AddBody(apiKey);
request.AddHeader("Content-Type", "application/json");
return Api.Execute<Authentication>(request, Url);
return Api.Execute<Authentication>(request, Url).token;
}
/// <summary>
@ -72,6 +75,7 @@ namespace RequestPlex.Api
Resource = "refresh_token"
};
request.AddHeader("Authorization", $"Bearer {oldToken}");
request.AddHeader("Content-Type", "application/json");
return Api.Execute<Authentication>(request, Url);
}
@ -86,11 +90,12 @@ namespace RequestPlex.Api
{
var request = new RestRequest
{
Method = Method.POST,
Method = Method.GET,
Resource = "search/series?name={searchTerm}"
};
request.AddUrlSegment("searchTerm", searchTerm);
request.AddHeader("Authorization", $"Bearer {token}");
request.AddHeader("Content-Type", "application/json");
return Api.Execute<TvSearchResult>(request, Url);
}
@ -102,17 +107,18 @@ namespace RequestPlex.Api
/// <param name="tvdbId">The TVDB identifier.</param>
/// <param name="token">The token.</param>
/// <returns></returns>
public TvSearchResult GetInformation(int tvdbId, string token)
public TvShow GetInformation(int tvdbId, string token)
{
var request = new RestRequest
{
Method = Method.POST,
Method = Method.GET,
Resource = "search/{id}"
};
request.AddUrlSegment("id", tvdbId.ToString());
request.AddHeader("Authorization", $"Bearer {token}");
request.AddHeader("Content-Type", "application/json");
return Api.Execute<TvSearchResult>(request, Url);
return Api.Execute<TvShow>(request, Url);
}
}
}

View file

@ -1,7 +1,7 @@
#region Copyright
// /************************************************************************
// Copyright (c) 2016 Jamie Rees
// File: TvBase.cs
// File: MovieBase.cs
// Created By: Jamie Rees
//
// Permission is hereby granted, free of charge, to any person obtaining
@ -24,14 +24,16 @@
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// ************************************************************************/
#endregion
using System;
using RequestPlex.Helpers;
namespace RequestPlex.Api
{
public abstract class MovieBase
public abstract class TvBase
{
private static readonly string Encrypted = "AVdhrVK6XX8anvrQgEyN/qNr9rk8ZPwy7/r1t5t5cKyUEzxcyk0L1v6dSxgE7hTCxvITUX2cWa6VlFMlTMgJWyuPZml7fN3csCHntgd/VGYro6VfNf24snZ/rQ3mf005";
protected string ApiKey = StringCipher.Decrypt(Encrypted, "ApiKey");
protected string Url = "https://api-beta.thetvdb.com/";
protected Uri Url = new Uri("https://api-beta.thetvdb.com/");
}
}

View file

@ -0,0 +1,33 @@
#region Copyright
// /************************************************************************
// Copyright (c) 2016 Jamie Rees
// File: CacheKeys.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 RequestPlex.Core
{
public class CacheKeys
{
public const string TvDbToken = "TheTvDbApiToken";
}
}

View file

@ -62,6 +62,7 @@
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="CacheKeys.cs" />
<Compile Include="ISettingsService.cs" />
<Compile Include="RequestService.cs" />
<Compile Include="SettingModels\SonarrSettings.cs" />

View file

@ -43,7 +43,7 @@ namespace RequestPlex.Core
{
var model = new RequestedModel
{
Tmdbid = tmdbid,
ProviderId = tmdbid,
Type = type
};
@ -52,12 +52,12 @@ namespace RequestPlex.Core
public bool CheckRequest(int tmdbid)
{
return Repo.GetAll().Any(x => x.Tmdbid == tmdbid);
return Repo.GetAll().Any(x => x.ProviderId == tmdbid);
}
public void DeleteRequest(int tmdbId)
{
var entity = Repo.GetAll().FirstOrDefault(x => x.Tmdbid == tmdbId);
var entity = Repo.GetAll().FirstOrDefault(x => x.ProviderId == tmdbId);
Repo.Delete(entity);
}

View file

@ -30,6 +30,8 @@ using System.Linq;
using Mono.Data.Sqlite;
using RequestPlex.Api;
using RequestPlex.Api.Models.Tv;
using RequestPlex.Helpers;
using RequestPlex.Store;
namespace RequestPlex.Core
@ -37,7 +39,7 @@ namespace RequestPlex.Core
public class SettingsService
{
public SettingsModel GetSettings()
public SettingsModel GetSettings(ICacheProvider cache)
{
var db = new DbConfiguration(new SqliteFactory());
var repo = new GenericRepository<SettingsModel>(db);
@ -46,18 +48,20 @@ namespace RequestPlex.Core
return settings;
}
private ICacheProvider Cache { get; set; }
public void AddRequest(int tmdbid, RequestType type)
public void AddRequest(int providerId, RequestType type)
{
var api = new TheMovieDbApi();
var model = new RequestedModel();
if (type == RequestType.Movie)
{
var movieInfo = api.GetMovieInformation(tmdbid).Result;
var movieApi = new TheMovieDbApi();
var movieInfo = movieApi.GetMovieInformation(providerId).Result;
model = new RequestedModel
{
Tmdbid = movieInfo.Id,
ProviderId = movieInfo.Id,
Type = type,
Overview = movieInfo.Overview,
ImdbId = movieInfo.ImdbId,
@ -71,17 +75,23 @@ namespace RequestPlex.Core
}
else
{
var showInfo = api.GetTvShowInformation(tmdbid).Result;
var tvApi = new TheTvDbApi();
var token = GetAuthToken(tvApi);
var showInfo = tvApi.GetInformation(providerId, token);
DateTime firstAir;
DateTime.TryParse(showInfo.firstAired, out firstAir);
model = new RequestedModel
{
Tmdbid = showInfo.Id,
ProviderId = showInfo.id,
Type = type,
Overview = showInfo.Overview,
PosterPath = "http://image.tmdb.org/t/p/w150/" + showInfo.PosterPath,
Title = showInfo.Name,
ReleaseDate = showInfo.FirstAirDate ?? DateTime.MinValue,
Status = showInfo.Status,
Overview = showInfo.overview,
PosterPath = "http://image.tmdb.org/t/p/w150/" + showInfo.banner, // This is incorrect
Title = showInfo.seriesName,
ReleaseDate = firstAir,
Status = showInfo.status,
RequestedDate = DateTime.Now,
Approved = false
};
@ -92,21 +102,25 @@ namespace RequestPlex.Core
repo.Insert(model);
}
public bool CheckRequest(int tmdbid)
public bool CheckRequest(int providerId)
{
var db = new DbConfiguration(new SqliteFactory());
var repo = new GenericRepository<RequestedModel>(db);
return repo.GetAll().Any(x => x.Tmdbid == tmdbid);
return repo.GetAll().Any(x => x.ProviderId == providerId);
}
public void DeleteRequest(int tmdbId)
{
var db = new DbConfiguration(new SqliteFactory());
var repo = new GenericRepository<RequestedModel>(db);
var entity = repo.GetAll().FirstOrDefault(x => x.Tmdbid == tmdbId);
var entity = repo.GetAll().FirstOrDefault(x => x.ProviderId == tmdbId);
repo.Delete(entity);
}
private string GetAuthToken(TheTvDbApi api)
{
return Cache.GetOrSet(CacheKeys.TvDbToken, api.Authenticate, 50);
}
}
}

View file

@ -8,7 +8,7 @@ namespace RequestPlex.Store
public class RequestedModel : Entity
{
// ReSharper disable once IdentifierTypo
public int Tmdbid { get; set; }
public int ProviderId { get; set; }
public string ImdbId { get; set; }
public string Overview { get; set; }
public string Title { get; set; }

View file

@ -20,7 +20,7 @@ CREATE TABLE IF NOT EXISTS Requested
(
Id INTEGER PRIMARY KEY AUTOINCREMENT,
Type INTEGER NOT NULL,
Tmdbid INTEGER NOT NULL,
ProviderId INTEGER NOT NULL,
ImdbId varchar(50),
Overview varchar(50) NOT NULL,
Title varchar(50) NOT NULL,

View file

@ -99,7 +99,8 @@ function tvSearch() {
var query = $("#tvSearchContent").val();
$.ajax("/search/tv/" + query).success(function (results) {
results.forEach(function (result) {
results.data.forEach(function (result) {
var context = buildTvShowContext(result);
var html = searchTemplate(context);
$("#tvList").append(html);

View file

@ -65,7 +65,7 @@ namespace RequestPlex.UI.Modules
var dbMovies = Service.GetAll().Where(x => x.Type == RequestType.Movie);
var viewModel = dbMovies.Select(tv => new RequestViewModel
{
Tmdbid = tv.Tmdbid,
Tmdbid = tv.ProviderId,
Type = tv.Type,
Status = tv.Status,
ImdbId = tv.ImdbId,
@ -88,7 +88,7 @@ namespace RequestPlex.UI.Modules
var dbTv = Service.GetAll().Where(x => x.Type == RequestType.TvShow);
var viewModel = dbTv.Select(tv => new RequestViewModel
{
Tmdbid = tv.Tmdbid,
Tmdbid = tv.ProviderId,
Type = tv.Type,
Status = tv.Status,
ImdbId = tv.ImdbId,
@ -106,9 +106,9 @@ namespace RequestPlex.UI.Modules
return Response.AsJson(viewModel);
}
private Response DeleteRequest(int tmdbId, RequestType type)
private Response DeleteRequest(int providerId, RequestType type)
{
var currentEntity = Service.GetAll().FirstOrDefault(x => x.Tmdbid == tmdbId && x.Type == type);
var currentEntity = Service.GetAll().FirstOrDefault(x => x.ProviderId == providerId && x.Type == type);
Service.Delete(currentEntity);
return Response.AsJson(new { Result = true });
}

View file

@ -2,16 +2,21 @@ using Nancy;
using Nancy.Responses.Negotiation;
using RequestPlex.Api;
using RequestPlex.Api.Models.Tv;
using RequestPlex.Core;
using RequestPlex.Helpers;
using RequestPlex.Store;
namespace RequestPlex.UI.Modules
{
public class SearchModule : NancyModule
{
public SearchModule() : base("search")
public SearchModule(ICacheProvider cache) : base("search")
{
Api = new TheMovieDbApi();
MovieApi = new TheMovieDbApi();
TvApi = new TheTvDbApi();
Cache = cache;
Get["/"] = parameters => RequestLoad();
Get["movie/{searchTerm}"] = parameters => SearchMovie((string)parameters.searchTerm);
@ -23,37 +28,39 @@ namespace RequestPlex.UI.Modules
Post["request/movie"] = parameters => RequestMovie((int)Request.Form.movieId);
Post["request/tv"] = parameters => RequestTvShow((int)Request.Form.tvId, (bool)Request.Form.latest);
}
private TheMovieDbApi Api { get; }
private TheMovieDbApi MovieApi { get; }
private TheTvDbApi TvApi { get; }
private ICacheProvider Cache { get; }
private string AuthToken => Cache.GetOrSet(CacheKeys.TvDbToken, TvApi.Authenticate, 50);
private Negotiator RequestLoad()
{
{
return View["Search/Index"];
}
private Response SearchMovie(string searchTerm)
{
var movies = Api.SearchMovie(searchTerm);
var movies = MovieApi.SearchMovie(searchTerm);
var result = movies.Result;
return Response.AsJson(result);
}
private Response SearchTvShow(string searchTerm)
{
var tvShow = Api.SearchTv(searchTerm);
var result = tvShow.Result;
return Response.AsJson(result);
var tvShow = TvApi.SearchTv(searchTerm, AuthToken);
return Response.AsJson(tvShow);
}
private Response UpcomingMovies()
{
var movies = Api.GetUpcomingMovies();
var movies = MovieApi.GetUpcomingMovies();
var result = movies.Result;
return Response.AsJson(result);
}
private Response CurrentlyPlayingMovies()
{
var movies = Api.GetCurrentPlayingMovies();
var movies = MovieApi.GetCurrentPlayingMovies();
var result = movies.Result;
return Response.AsJson(result);
}