|
|
@ -16,14 +16,16 @@ namespace Ombi.Api.Plex
|
|
|
|
{
|
|
|
|
{
|
|
|
|
public class PlexApi : IPlexApi
|
|
|
|
public class PlexApi : IPlexApi
|
|
|
|
{
|
|
|
|
{
|
|
|
|
public PlexApi(IApi api, ISettingsService<CustomizationSettings> settings)
|
|
|
|
public PlexApi(IApi api, ISettingsService<CustomizationSettings> settings, ISettingsService<PlexSettings> p)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
Api = api;
|
|
|
|
Api = api;
|
|
|
|
_custom = settings;
|
|
|
|
_custom = settings;
|
|
|
|
|
|
|
|
_plexSettings = p;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private IApi Api { get; }
|
|
|
|
private IApi Api { get; }
|
|
|
|
private readonly ISettingsService<CustomizationSettings> _custom;
|
|
|
|
private readonly ISettingsService<CustomizationSettings> _custom;
|
|
|
|
|
|
|
|
private readonly ISettingsService<PlexSettings> _plexSettings;
|
|
|
|
|
|
|
|
|
|
|
|
private string _app;
|
|
|
|
private string _app;
|
|
|
|
private string ApplicationName
|
|
|
|
private string ApplicationName
|
|
|
@ -69,7 +71,7 @@ namespace Ombi.Api.Plex
|
|
|
|
};
|
|
|
|
};
|
|
|
|
var request = new Request(SignInUri, string.Empty, HttpMethod.Post);
|
|
|
|
var request = new Request(SignInUri, string.Empty, HttpMethod.Post);
|
|
|
|
|
|
|
|
|
|
|
|
AddHeaders(request);
|
|
|
|
await AddHeaders(request);
|
|
|
|
request.AddJsonBody(userModel);
|
|
|
|
request.AddJsonBody(userModel);
|
|
|
|
|
|
|
|
|
|
|
|
var obj = await Api.Request<PlexAuthentication>(request);
|
|
|
|
var obj = await Api.Request<PlexAuthentication>(request);
|
|
|
@ -80,14 +82,14 @@ namespace Ombi.Api.Plex
|
|
|
|
public async Task<PlexStatus> GetStatus(string authToken, string uri)
|
|
|
|
public async Task<PlexStatus> GetStatus(string authToken, string uri)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
var request = new Request(uri, string.Empty, HttpMethod.Get);
|
|
|
|
var request = new Request(uri, string.Empty, HttpMethod.Get);
|
|
|
|
AddHeaders(request, authToken);
|
|
|
|
await AddHeaders(request, authToken);
|
|
|
|
return await Api.Request<PlexStatus>(request);
|
|
|
|
return await Api.Request<PlexStatus>(request);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public async Task<PlexAccount> GetAccount(string authToken)
|
|
|
|
public async Task<PlexAccount> GetAccount(string authToken)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
var request = new Request(GetAccountUri, string.Empty, HttpMethod.Get);
|
|
|
|
var request = new Request(GetAccountUri, string.Empty, HttpMethod.Get);
|
|
|
|
AddHeaders(request, authToken);
|
|
|
|
await AddHeaders(request, authToken);
|
|
|
|
return await Api.Request<PlexAccount>(request);
|
|
|
|
return await Api.Request<PlexAccount>(request);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -95,7 +97,7 @@ namespace Ombi.Api.Plex
|
|
|
|
{
|
|
|
|
{
|
|
|
|
var request = new Request(ServerUri, string.Empty, HttpMethod.Get, ContentType.Xml);
|
|
|
|
var request = new Request(ServerUri, string.Empty, HttpMethod.Get, ContentType.Xml);
|
|
|
|
|
|
|
|
|
|
|
|
AddHeaders(request, authToken);
|
|
|
|
await AddHeaders(request, authToken);
|
|
|
|
|
|
|
|
|
|
|
|
return await Api.Request<PlexServer>(request);
|
|
|
|
return await Api.Request<PlexServer>(request);
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -103,14 +105,14 @@ namespace Ombi.Api.Plex
|
|
|
|
public async Task<PlexContainer> GetLibrarySections(string authToken, string plexFullHost)
|
|
|
|
public async Task<PlexContainer> GetLibrarySections(string authToken, string plexFullHost)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
var request = new Request("library/sections", plexFullHost, HttpMethod.Get);
|
|
|
|
var request = new Request("library/sections", plexFullHost, HttpMethod.Get);
|
|
|
|
AddHeaders(request, authToken);
|
|
|
|
await AddHeaders(request, authToken);
|
|
|
|
return await Api.Request<PlexContainer>(request);
|
|
|
|
return await Api.Request<PlexContainer>(request);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public async Task<PlexContainer> GetLibrary(string authToken, string plexFullHost, string libraryId)
|
|
|
|
public async Task<PlexContainer> GetLibrary(string authToken, string plexFullHost, string libraryId)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
var request = new Request($"library/sections/{libraryId}/all", plexFullHost, HttpMethod.Get);
|
|
|
|
var request = new Request($"library/sections/{libraryId}/all", plexFullHost, HttpMethod.Get);
|
|
|
|
AddHeaders(request, authToken);
|
|
|
|
await AddHeaders(request, authToken);
|
|
|
|
return await Api.Request<PlexContainer>(request);
|
|
|
|
return await Api.Request<PlexContainer>(request);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -128,21 +130,21 @@ namespace Ombi.Api.Plex
|
|
|
|
public async Task<PlexMetadata> GetEpisodeMetaData(string authToken, string plexFullHost, int ratingKey)
|
|
|
|
public async Task<PlexMetadata> GetEpisodeMetaData(string authToken, string plexFullHost, int ratingKey)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
var request = new Request($"/library/metadata/{ratingKey}", plexFullHost, HttpMethod.Get);
|
|
|
|
var request = new Request($"/library/metadata/{ratingKey}", plexFullHost, HttpMethod.Get);
|
|
|
|
AddHeaders(request, authToken);
|
|
|
|
await AddHeaders(request, authToken);
|
|
|
|
return await Api.Request<PlexMetadata>(request);
|
|
|
|
return await Api.Request<PlexMetadata>(request);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public async Task<PlexMetadata> GetMetadata(string authToken, string plexFullHost, int itemId)
|
|
|
|
public async Task<PlexMetadata> GetMetadata(string authToken, string plexFullHost, int itemId)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
var request = new Request($"library/metadata/{itemId}", plexFullHost, HttpMethod.Get);
|
|
|
|
var request = new Request($"library/metadata/{itemId}", plexFullHost, HttpMethod.Get);
|
|
|
|
AddHeaders(request, authToken);
|
|
|
|
await AddHeaders(request, authToken);
|
|
|
|
return await Api.Request<PlexMetadata>(request);
|
|
|
|
return await Api.Request<PlexMetadata>(request);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public async Task<PlexMetadata> GetSeasons(string authToken, string plexFullHost, int ratingKey)
|
|
|
|
public async Task<PlexMetadata> GetSeasons(string authToken, string plexFullHost, int ratingKey)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
var request = new Request($"library/metadata/{ratingKey}/children", plexFullHost, HttpMethod.Get);
|
|
|
|
var request = new Request($"library/metadata/{ratingKey}/children", plexFullHost, HttpMethod.Get);
|
|
|
|
AddHeaders(request, authToken);
|
|
|
|
await AddHeaders(request, authToken);
|
|
|
|
return await Api.Request<PlexMetadata>(request);
|
|
|
|
return await Api.Request<PlexMetadata>(request);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -161,9 +163,9 @@ namespace Ombi.Api.Plex
|
|
|
|
|
|
|
|
|
|
|
|
request.AddQueryString("type", "4");
|
|
|
|
request.AddQueryString("type", "4");
|
|
|
|
AddLimitHeaders(request, start, retCount);
|
|
|
|
AddLimitHeaders(request, start, retCount);
|
|
|
|
AddHeaders(request, authToken);
|
|
|
|
await AddHeaders(request, authToken);
|
|
|
|
|
|
|
|
|
|
|
|
return await Api.Request<PlexContainer>(request);
|
|
|
|
return await Api.Request<PlexContainer>(request);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// <summary>
|
|
|
@ -174,8 +176,8 @@ namespace Ombi.Api.Plex
|
|
|
|
/// <returns></returns>
|
|
|
|
/// <returns></returns>
|
|
|
|
public async Task<PlexFriends> GetUsers(string authToken)
|
|
|
|
public async Task<PlexFriends> GetUsers(string authToken)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
var request = new Request(string.Empty,FriendsUri, HttpMethod.Get, ContentType.Xml);
|
|
|
|
var request = new Request(string.Empty, FriendsUri, HttpMethod.Get, ContentType.Xml);
|
|
|
|
AddHeaders(request, authToken);
|
|
|
|
await AddHeaders(request, authToken);
|
|
|
|
|
|
|
|
|
|
|
|
return await Api.Request<PlexFriends>(request);
|
|
|
|
return await Api.Request<PlexFriends>(request);
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -183,43 +185,40 @@ namespace Ombi.Api.Plex
|
|
|
|
public async Task<PlexMetadata> GetRecentlyAdded(string authToken, string uri, string sectionId)
|
|
|
|
public async Task<PlexMetadata> GetRecentlyAdded(string authToken, string uri, string sectionId)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
var request = new Request($"library/sections/{sectionId}/recentlyAdded", uri, HttpMethod.Get);
|
|
|
|
var request = new Request($"library/sections/{sectionId}/recentlyAdded", uri, HttpMethod.Get);
|
|
|
|
AddHeaders(request, authToken);
|
|
|
|
await AddHeaders(request, authToken);
|
|
|
|
AddLimitHeaders(request, 0, 50);
|
|
|
|
AddLimitHeaders(request, 0, 50);
|
|
|
|
|
|
|
|
|
|
|
|
return await Api.Request<PlexMetadata>(request);
|
|
|
|
return await Api.Request<PlexMetadata>(request);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public async Task<OAuthPin> CreatePin()
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
var request = new Request($"api/v2/pins", "https://plex.tv/", HttpMethod.Post);
|
|
|
|
|
|
|
|
request.AddQueryString("strong", "true");
|
|
|
|
|
|
|
|
AddHeaders(request);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return await Api.Request<OAuthPin>(request);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public async Task<OAuthPin> GetPin(int pinId)
|
|
|
|
public async Task<OAuthPin> GetPin(int pinId)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
var request = new Request($"api/v2/pins/{pinId}", "https://plex.tv/", HttpMethod.Get);
|
|
|
|
var request = new Request($"api/v2/pins/{pinId}", "https://plex.tv/", HttpMethod.Get);
|
|
|
|
AddHeaders(request);
|
|
|
|
await AddHeaders(request);
|
|
|
|
|
|
|
|
|
|
|
|
return await Api.Request<OAuthPin>(request);
|
|
|
|
return await Api.Request<OAuthPin>(request);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public Uri GetOAuthUrl(int pinId, string code, string applicationUrl, bool wizard)
|
|
|
|
public async Task<Uri> GetOAuthUrl(int pinId, string code, string applicationUrl, bool wizard)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
var request = new Request("auth#", "https://app.plex.tv", HttpMethod.Get);
|
|
|
|
var request = new Request("auth#", "https://app.plex.tv", HttpMethod.Get);
|
|
|
|
AddHeaders(request);
|
|
|
|
await AddHeaders(request);
|
|
|
|
var forwardUrl = wizard
|
|
|
|
var forwardUrl = wizard
|
|
|
|
? new Request($"Wizard/OAuth/{pinId}", applicationUrl, HttpMethod.Get)
|
|
|
|
? new Request($"Wizard/OAuth/{pinId}", applicationUrl, HttpMethod.Get)
|
|
|
|
: new Request($"Login/OAuth/{pinId}", applicationUrl, HttpMethod.Get);
|
|
|
|
: new Request($"Login/OAuth/{pinId}", applicationUrl, HttpMethod.Get);
|
|
|
|
|
|
|
|
|
|
|
|
request.AddQueryString("forwardUrl", forwardUrl.FullUri.ToString());
|
|
|
|
request.AddQueryString("forwardUrl", forwardUrl.FullUri.ToString());
|
|
|
|
request.AddQueryString("pinID", pinId.ToString());
|
|
|
|
request.AddQueryString("pinID", pinId.ToString());
|
|
|
|
request.AddQueryString("code", code);
|
|
|
|
request.AddQueryString("code", code);
|
|
|
|
request.AddQueryString("context[device][product]", "Ombi");
|
|
|
|
request.AddQueryString("context[device][product]", ApplicationName);
|
|
|
|
request.AddQueryString("context[device][environment]", "bundled");
|
|
|
|
request.AddQueryString("context[device][environment]", "bundled");
|
|
|
|
request.AddQueryString("clientID", $"OmbiV3");
|
|
|
|
request.AddQueryString("context[device][layout]", "desktop");
|
|
|
|
|
|
|
|
request.AddQueryString("context[device][platform]", "Web");
|
|
|
|
|
|
|
|
request.AddQueryString("context[device][device]", "Ombi (Web)");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var s = await GetSettings();
|
|
|
|
|
|
|
|
await CheckInstallId(s);
|
|
|
|
|
|
|
|
request.AddQueryString("clientID", s.InstallId.ToString("N"));
|
|
|
|
|
|
|
|
|
|
|
|
if (request.FullUri.Fragment.Equals("#"))
|
|
|
|
if (request.FullUri.Fragment.Equals("#"))
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -238,21 +237,25 @@ namespace Ombi.Api.Plex
|
|
|
|
/// </summary>
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="request"></param>
|
|
|
|
/// <param name="request"></param>
|
|
|
|
/// <param name="authToken"></param>
|
|
|
|
/// <param name="authToken"></param>
|
|
|
|
private void AddHeaders(Request request, string authToken)
|
|
|
|
private async Task AddHeaders(Request request, string authToken)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
request.AddHeader("X-Plex-Token", authToken);
|
|
|
|
request.AddHeader("X-Plex-Token", authToken);
|
|
|
|
AddHeaders(request);
|
|
|
|
await AddHeaders(request);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// <summary>
|
|
|
|
/// Adds the main required headers to the Plex Request
|
|
|
|
/// Adds the main required headers to the Plex Request
|
|
|
|
/// </summary>
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="request"></param>
|
|
|
|
/// <param name="request"></param>
|
|
|
|
private void AddHeaders(Request request)
|
|
|
|
private async Task AddHeaders(Request request)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
request.AddHeader("X-Plex-Client-Identifier", $"OmbiV3");
|
|
|
|
var s = await GetSettings();
|
|
|
|
|
|
|
|
await CheckInstallId(s);
|
|
|
|
|
|
|
|
request.AddHeader("X-Plex-Client-Identifier", s.InstallId.ToString("N"));
|
|
|
|
request.AddHeader("X-Plex-Product", ApplicationName);
|
|
|
|
request.AddHeader("X-Plex-Product", ApplicationName);
|
|
|
|
request.AddHeader("X-Plex-Version", "3");
|
|
|
|
request.AddHeader("X-Plex-Version", "3");
|
|
|
|
|
|
|
|
request.AddHeader("X-Plex-Device", "Ombi (Web)");
|
|
|
|
|
|
|
|
request.AddHeader("X-Plex-Platform", "Web");
|
|
|
|
request.AddContentHeader("Content-Type", request.ContentType == ContentType.Json ? "application/json" : "application/xml");
|
|
|
|
request.AddContentHeader("Content-Type", request.ContentType == ContentType.Json ? "application/json" : "application/xml");
|
|
|
|
request.AddHeader("Accept", "application/json");
|
|
|
|
request.AddHeader("Accept", "application/json");
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -262,5 +265,19 @@ namespace Ombi.Api.Plex
|
|
|
|
request.AddHeader("X-Plex-Container-Start", from.ToString());
|
|
|
|
request.AddHeader("X-Plex-Container-Start", from.ToString());
|
|
|
|
request.AddHeader("X-Plex-Container-Size", to.ToString());
|
|
|
|
request.AddHeader("X-Plex-Container-Size", to.ToString());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private async Task CheckInstallId(PlexSettings s)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (s.InstallId == null || s.InstallId == Guid.Empty)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
s.InstallId = Guid.NewGuid();
|
|
|
|
|
|
|
|
await _plexSettings.SaveSettingsAsync(s);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private PlexSettings _settings;
|
|
|
|
|
|
|
|
private async Task<PlexSettings> GetSettings()
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return _settings ?? (_settings = await _plexSettings.GetSettingsAsync());
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|