mirror of
https://github.com/jellyfin/jellyfin-plugin-opensubtitles.git
synced 2024-11-23 06:09:51 +00:00
10.9 support (#115)
This commit is contained in:
parent
6d8ee4eb7a
commit
ecc270c915
@ -8,8 +8,8 @@ using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace Jellyfin.Plugin.OpenSubtitles.API
|
||||
{
|
||||
namespace Jellyfin.Plugin.OpenSubtitles.API;
|
||||
|
||||
/// <summary>
|
||||
/// The open subtitles plugin controller.
|
||||
/// </summary>
|
||||
@ -48,7 +48,7 @@ namespace Jellyfin.Plugin.OpenSubtitles.API
|
||||
if (response.Body.Contains("message\":", StringComparison.Ordinal))
|
||||
{
|
||||
var err = JsonSerializer.Deserialize<ErrorResponse>(response.Body);
|
||||
if (err != null)
|
||||
if (err is not null)
|
||||
{
|
||||
msg = string.Equals(err.Message, "You cannot consume this service", StringComparison.Ordinal) ? "Invalid API key provided" : err.Message;
|
||||
}
|
||||
@ -57,7 +57,7 @@ namespace Jellyfin.Plugin.OpenSubtitles.API
|
||||
return Unauthorized(new { Message = msg });
|
||||
}
|
||||
|
||||
if (response.Data != null)
|
||||
if (response.Data is not null)
|
||||
{
|
||||
await OpenSubtitlesHandler.OpenSubtitles.LogOutAsync(response.Data, key, CancellationToken.None).ConfigureAwait(false);
|
||||
}
|
||||
@ -65,4 +65,3 @@ namespace Jellyfin.Plugin.OpenSubtitles.API
|
||||
return Ok(new { Downloads = response.Data?.User?.AllowedDownloads ?? 0 });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
using MediaBrowser.Model.Plugins;
|
||||
|
||||
namespace Jellyfin.Plugin.OpenSubtitles.Configuration
|
||||
{
|
||||
namespace Jellyfin.Plugin.OpenSubtitles.Configuration;
|
||||
|
||||
/// <summary>
|
||||
/// The plugin configuration.
|
||||
/// </summary>
|
||||
@ -27,4 +27,3 @@ namespace Jellyfin.Plugin.OpenSubtitles.Configuration
|
||||
/// </summary>
|
||||
public bool CredentialsInvalid { get; set; } = false;
|
||||
}
|
||||
}
|
||||
|
@ -19,8 +19,8 @@ using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Providers;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Jellyfin.Plugin.OpenSubtitles
|
||||
{
|
||||
namespace Jellyfin.Plugin.OpenSubtitles;
|
||||
|
||||
/// <summary>
|
||||
/// The open subtitle downloader.
|
||||
/// </summary>
|
||||
@ -31,7 +31,7 @@ namespace Jellyfin.Plugin.OpenSubtitles
|
||||
private DateTime? _limitReset;
|
||||
private DateTime? _lastRatelimitLog;
|
||||
private IReadOnlyList<string>? _languages;
|
||||
private string _customApiKey;
|
||||
private PluginConfiguration? _configuration;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="OpenSubtitleDownloader"/> class.
|
||||
@ -40,22 +40,17 @@ namespace Jellyfin.Plugin.OpenSubtitles
|
||||
/// <param name="httpClientFactory">The <see cref="IHttpClientFactory"/> for creating Http Clients.</param>
|
||||
public OpenSubtitleDownloader(ILogger<OpenSubtitleDownloader> logger, IHttpClientFactory httpClientFactory)
|
||||
{
|
||||
Instance = this;
|
||||
_logger = logger;
|
||||
|
||||
var version = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version!.ToString();
|
||||
|
||||
OpenSubtitlesRequestHelper.Instance = new OpenSubtitlesRequestHelper(httpClientFactory, version);
|
||||
|
||||
OpenSubtitlesPlugin.Instance!.ConfigurationChanged += (_, _) =>
|
||||
{
|
||||
_customApiKey = GetOptions().CustomApiKey;
|
||||
// force a login next time a request is made
|
||||
_login = null;
|
||||
};
|
||||
|
||||
_customApiKey = GetOptions().CustomApiKey;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the downloader instance.
|
||||
/// </summary>
|
||||
public static OpenSubtitleDownloader? Instance { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the API key that will be used for requests.
|
||||
/// </summary>
|
||||
@ -63,7 +58,7 @@ namespace Jellyfin.Plugin.OpenSubtitles
|
||||
{
|
||||
get
|
||||
{
|
||||
return !string.IsNullOrWhiteSpace(_customApiKey) ? _customApiKey : OpenSubtitlesPlugin.ApiKey;
|
||||
return !string.IsNullOrWhiteSpace(_configuration?.CustomApiKey) ? _configuration.CustomApiKey : OpenSubtitlesPlugin.ApiKey;
|
||||
}
|
||||
}
|
||||
|
||||
@ -95,7 +90,7 @@ namespace Jellyfin.Plugin.OpenSubtitles
|
||||
|
||||
if (request.IsAutomated && _login?.User?.RemainingDownloads <= 0)
|
||||
{
|
||||
if (_lastRatelimitLog == null || DateTime.UtcNow.Subtract(_lastRatelimitLog.Value).TotalSeconds > 60)
|
||||
if (_lastRatelimitLog is null || DateTime.UtcNow.Subtract(_lastRatelimitLog.Value).TotalSeconds > 60)
|
||||
{
|
||||
_logger.LogInformation("Daily download limit reached, returning no results for automated task");
|
||||
_lastRatelimitLog = DateTime.UtcNow;
|
||||
@ -188,12 +183,13 @@ namespace Jellyfin.Plugin.OpenSubtitles
|
||||
|
||||
bool MediaFilter(ResponseData x) =>
|
||||
x.Attributes?.FeatureDetails?.FeatureType == (request.ContentType == VideoContentType.Episode ? "Episode" : "Movie")
|
||||
&& request.ContentType == VideoContentType.Episode
|
||||
&& x.Attributes?.Files?.Count > 0 && x.Attributes.Files[0].FileId != null
|
||||
&& (request.ContentType == VideoContentType.Episode
|
||||
? x.Attributes.FeatureDetails.SeasonNumber == request.ParentIndexNumber
|
||||
&& x.Attributes.FeatureDetails.EpisodeNumber == request.IndexNumber
|
||||
: x.Attributes?.FeatureDetails?.ImdbId == imdbId;
|
||||
: x.Attributes?.FeatureDetails?.ImdbId == imdbId);
|
||||
|
||||
if (searchResponse.Data == null)
|
||||
if (searchResponse.Data is null)
|
||||
{
|
||||
return Enumerable.Empty<RemoteSubtitleInfo>();
|
||||
}
|
||||
@ -217,8 +213,7 @@ namespace Jellyfin.Plugin.OpenSubtitles
|
||||
Name = i.Attributes?.Release,
|
||||
DateCreated = i.Attributes?.UploadDate,
|
||||
IsHashMatch = i.Attributes?.MovieHashMatch
|
||||
})
|
||||
.Where(i => !string.Equals(i.Format, "sub", StringComparison.OrdinalIgnoreCase) && !string.Equals(i.Format, "idx", StringComparison.OrdinalIgnoreCase));
|
||||
});
|
||||
}
|
||||
|
||||
private async Task<SubtitleResponse> GetSubtitlesInternal(string id, CancellationToken cancellationToken)
|
||||
@ -251,21 +246,26 @@ namespace Jellyfin.Plugin.OpenSubtitles
|
||||
}
|
||||
|
||||
await Login(cancellationToken).ConfigureAwait(false);
|
||||
if (_login == null)
|
||||
if (_login is null)
|
||||
{
|
||||
throw new AuthenticationException("Unable to login");
|
||||
}
|
||||
|
||||
var idParts = id.Split('-', 3);
|
||||
var idParts = id.Split('-');
|
||||
if (idParts.Length != 3)
|
||||
{
|
||||
throw new FormatException(string.Format(CultureInfo.InvariantCulture, "Invalid subtitle id format: {0}", id));
|
||||
}
|
||||
|
||||
var format = idParts[0];
|
||||
var language = idParts[1];
|
||||
var ossId = idParts[2];
|
||||
var fileId = int.Parse(idParts[2], CultureInfo.InvariantCulture);
|
||||
|
||||
var fid = int.Parse(ossId, CultureInfo.InvariantCulture);
|
||||
var info = await OpenSubtitlesHandler.OpenSubtitles
|
||||
.GetSubtitleLinkAsync(fileId, format, _login, ApiKey, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
var info = await OpenSubtitlesHandler.OpenSubtitles.GetSubtitleLinkAsync(fid, _login, ApiKey, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
if (info.Data?.ResetTime != null)
|
||||
if (info.Data?.ResetTime is not null)
|
||||
{
|
||||
_limitReset = info.Data.ResetTime;
|
||||
_logger.LogDebug("Updated expiration time to {ResetTime}", _limitReset);
|
||||
@ -277,7 +277,7 @@ namespace Jellyfin.Plugin.OpenSubtitles
|
||||
{
|
||||
case HttpStatusCode.NotAcceptable when info.Data?.Remaining <= 0:
|
||||
{
|
||||
if (_login.User != null)
|
||||
if (_login.User is not null)
|
||||
{
|
||||
_login.User.RemainingDownloads = 0;
|
||||
}
|
||||
@ -297,14 +297,14 @@ namespace Jellyfin.Plugin.OpenSubtitles
|
||||
msg = string.Format(
|
||||
CultureInfo.InvariantCulture,
|
||||
"Invalid response for file {0}: {1}\n\n{2}",
|
||||
fid,
|
||||
fileId,
|
||||
info.Code,
|
||||
msg);
|
||||
|
||||
throw new HttpRequestException(msg);
|
||||
}
|
||||
|
||||
if (_login.User != null)
|
||||
if (_login.User is not null)
|
||||
{
|
||||
_login.User.RemainingDownloads = info.Data?.Remaining;
|
||||
_logger.LogInformation("Remaining downloads: {RemainingDownloads}", _login.User.RemainingDownloads);
|
||||
@ -315,7 +315,7 @@ namespace Jellyfin.Plugin.OpenSubtitles
|
||||
var msg = string.Format(
|
||||
CultureInfo.InvariantCulture,
|
||||
"Failed to obtain download link for file {0}: {1} (empty response)",
|
||||
fid,
|
||||
fileId,
|
||||
info.Code);
|
||||
|
||||
throw new HttpRequestException(msg);
|
||||
@ -328,7 +328,7 @@ namespace Jellyfin.Plugin.OpenSubtitles
|
||||
var msg = string.Format(
|
||||
CultureInfo.InvariantCulture,
|
||||
"Subtitle with Id {0} could not be downloaded: {1}",
|
||||
ossId,
|
||||
fileId,
|
||||
res.Code);
|
||||
|
||||
throw new HttpRequestException(msg);
|
||||
@ -339,39 +339,38 @@ namespace Jellyfin.Plugin.OpenSubtitles
|
||||
|
||||
private async Task Login(CancellationToken cancellationToken)
|
||||
{
|
||||
if (_login != null && DateTime.UtcNow < _login.ExpirationDate)
|
||||
if (_configuration is null || (_login is not null && DateTime.UtcNow < _login.ExpirationDate))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var options = GetOptions();
|
||||
if (string.IsNullOrWhiteSpace(options.Username) || string.IsNullOrWhiteSpace(options.Password))
|
||||
if (string.IsNullOrWhiteSpace(_configuration.Username) || string.IsNullOrWhiteSpace(_configuration.Password))
|
||||
{
|
||||
throw new AuthenticationException("Account username and/or password are not set up");
|
||||
}
|
||||
|
||||
if (options.CredentialsInvalid)
|
||||
if (_configuration.CredentialsInvalid)
|
||||
{
|
||||
_logger.LogDebug("Skipping login due to credentials being invalid");
|
||||
return;
|
||||
}
|
||||
|
||||
var loginResponse = await OpenSubtitlesHandler.OpenSubtitles.LogInAsync(
|
||||
options.Username,
|
||||
options.Password,
|
||||
_configuration.Username,
|
||||
_configuration.Password,
|
||||
ApiKey,
|
||||
cancellationToken).ConfigureAwait(false);
|
||||
|
||||
if (!loginResponse.Ok)
|
||||
{
|
||||
// 400 = Using email, 401 = invalid credentials, 403 = invalid api key
|
||||
if ((loginResponse.Code == HttpStatusCode.BadRequest && options.Username.Contains('@', StringComparison.OrdinalIgnoreCase))
|
||||
if ((loginResponse.Code == HttpStatusCode.BadRequest && _configuration.Username.Contains('@', StringComparison.OrdinalIgnoreCase))
|
||||
|| loginResponse.Code == HttpStatusCode.Unauthorized
|
||||
|| (loginResponse.Code == HttpStatusCode.Forbidden && ApiKey == options.CustomApiKey))
|
||||
|| (loginResponse.Code == HttpStatusCode.Forbidden && ApiKey == _configuration.CustomApiKey))
|
||||
{
|
||||
_logger.LogError("Login failed due to invalid credentials/API key, invalidating them ({Code} - {Body})", loginResponse.Code, loginResponse.Body);
|
||||
options.CredentialsInvalid = true;
|
||||
OpenSubtitlesPlugin.Instance!.SaveConfiguration(options);
|
||||
_configuration.CredentialsInvalid = true;
|
||||
OpenSubtitlesPlugin.Instance!.SaveConfiguration(_configuration);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -390,7 +389,7 @@ namespace Jellyfin.Plugin.OpenSubtitles
|
||||
|
||||
private async Task UpdateUserInfo(CancellationToken cancellationToken)
|
||||
{
|
||||
if (_login == null)
|
||||
if (_login is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -414,11 +413,11 @@ namespace Jellyfin.Plugin.OpenSubtitles
|
||||
language = "pt-PT";
|
||||
}
|
||||
|
||||
if (_languages == null || _languages.Count == 0)
|
||||
if (_languages is null || _languages.Count == 0)
|
||||
{
|
||||
var res = await OpenSubtitlesHandler.OpenSubtitles.GetLanguageList(ApiKey, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
if (!res.Ok || res.Data?.Data == null)
|
||||
if (!res.Ok || res.Data?.Data is null)
|
||||
{
|
||||
throw new HttpRequestException(string.Format(CultureInfo.InvariantCulture, "Failed to get language list: {0}", res.Code));
|
||||
}
|
||||
@ -427,7 +426,7 @@ namespace Jellyfin.Plugin.OpenSubtitles
|
||||
}
|
||||
|
||||
var found = _languages.FirstOrDefault(x => string.Equals(x, language, StringComparison.OrdinalIgnoreCase));
|
||||
if (found != null)
|
||||
if (found is not null)
|
||||
{
|
||||
return found;
|
||||
}
|
||||
@ -440,7 +439,10 @@ namespace Jellyfin.Plugin.OpenSubtitles
|
||||
throw new NotSupportedException(string.Format(CultureInfo.InvariantCulture, "Language '{0}' is not supported", language));
|
||||
}
|
||||
|
||||
private PluginConfiguration GetOptions()
|
||||
=> OpenSubtitlesPlugin.Instance!.Configuration;
|
||||
internal void ConfigurationChanged(PluginConfiguration e)
|
||||
{
|
||||
_configuration = e;
|
||||
// force a login next time a request is made
|
||||
_login = null;
|
||||
}
|
||||
}
|
||||
|
@ -2,8 +2,8 @@
|
||||
using System.Net;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace Jellyfin.Plugin.OpenSubtitles.OpenSubtitlesHandler.Models
|
||||
{
|
||||
namespace Jellyfin.Plugin.OpenSubtitles.OpenSubtitlesHandler.Models;
|
||||
|
||||
/// <summary>
|
||||
/// The api response.
|
||||
/// </summary>
|
||||
@ -78,4 +78,3 @@ namespace Jellyfin.Plugin.OpenSubtitles.OpenSubtitlesHandler.Models
|
||||
/// </summary>
|
||||
public bool Ok => (int)Code >= 200 && (int)Code <= 299;
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Jellyfin.Plugin.OpenSubtitles.OpenSubtitlesHandler.Models
|
||||
{
|
||||
namespace Jellyfin.Plugin.OpenSubtitles.OpenSubtitlesHandler.Models;
|
||||
|
||||
/// <summary>
|
||||
/// The error response.
|
||||
/// </summary>
|
||||
@ -13,4 +13,3 @@ namespace Jellyfin.Plugin.OpenSubtitles.OpenSubtitlesHandler.Models
|
||||
[JsonPropertyName("message")]
|
||||
public string? Message { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
using System.Net;
|
||||
|
||||
namespace Jellyfin.Plugin.OpenSubtitles.OpenSubtitlesHandler.Models
|
||||
{
|
||||
namespace Jellyfin.Plugin.OpenSubtitles.OpenSubtitlesHandler.Models;
|
||||
|
||||
/// <summary>
|
||||
/// The http response.
|
||||
/// </summary>
|
||||
@ -29,4 +29,3 @@ namespace Jellyfin.Plugin.OpenSubtitles.OpenSubtitlesHandler.Models
|
||||
/// </summary>
|
||||
public string Reason { get; init; } = string.Empty;
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Jellyfin.Plugin.OpenSubtitles.OpenSubtitlesHandler.Models
|
||||
{
|
||||
namespace Jellyfin.Plugin.OpenSubtitles.OpenSubtitlesHandler.Models;
|
||||
|
||||
/// <summary>
|
||||
/// The jwt payload.
|
||||
/// </summary>
|
||||
@ -13,4 +13,3 @@ namespace Jellyfin.Plugin.OpenSubtitles.OpenSubtitlesHandler.Models
|
||||
[JsonPropertyName("exp")]
|
||||
public long Exp { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Jellyfin.Plugin.OpenSubtitles.OpenSubtitlesHandler.Models
|
||||
{
|
||||
namespace Jellyfin.Plugin.OpenSubtitles.OpenSubtitlesHandler.Models;
|
||||
|
||||
/// <summary>
|
||||
/// The login model.
|
||||
/// </summary>
|
||||
@ -24,4 +24,3 @@ namespace Jellyfin.Plugin.OpenSubtitles.OpenSubtitlesHandler.Models
|
||||
/// </summary>
|
||||
public string CustomApiKey { get; set; } = null!;
|
||||
}
|
||||
}
|
||||
|
@ -2,8 +2,8 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Jellyfin.Plugin.OpenSubtitles.OpenSubtitlesHandler.Models.Responses
|
||||
{
|
||||
namespace Jellyfin.Plugin.OpenSubtitles.OpenSubtitlesHandler.Models.Responses;
|
||||
|
||||
/// <summary>
|
||||
/// The attributes response.
|
||||
/// </summary>
|
||||
@ -69,4 +69,3 @@ namespace Jellyfin.Plugin.OpenSubtitles.OpenSubtitlesHandler.Models.Responses
|
||||
[JsonPropertyName("moviehash_match")]
|
||||
public bool? MovieHashMatch { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Jellyfin.Plugin.OpenSubtitles.OpenSubtitlesHandler.Models.Responses
|
||||
{
|
||||
namespace Jellyfin.Plugin.OpenSubtitles.OpenSubtitlesHandler.Models.Responses;
|
||||
|
||||
/// <summary>
|
||||
/// The encapsulated language list.
|
||||
/// </summary>
|
||||
@ -14,4 +14,3 @@ namespace Jellyfin.Plugin.OpenSubtitles.OpenSubtitlesHandler.Models.Responses
|
||||
[JsonPropertyName("data")]
|
||||
public IReadOnlyList<LanguageInfo>? Data { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Jellyfin.Plugin.OpenSubtitles.OpenSubtitlesHandler.Models.Responses
|
||||
{
|
||||
namespace Jellyfin.Plugin.OpenSubtitles.OpenSubtitlesHandler.Models.Responses;
|
||||
|
||||
/// <summary>
|
||||
/// The encapsulated user info.
|
||||
/// </summary>
|
||||
@ -13,4 +13,3 @@ namespace Jellyfin.Plugin.OpenSubtitles.OpenSubtitlesHandler.Models.Responses
|
||||
[JsonPropertyName("data")]
|
||||
public UserInfo? Data { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Jellyfin.Plugin.OpenSubtitles.OpenSubtitlesHandler.Models.Responses
|
||||
{
|
||||
namespace Jellyfin.Plugin.OpenSubtitles.OpenSubtitlesHandler.Models.Responses;
|
||||
|
||||
/// <summary>
|
||||
/// The feature details.
|
||||
/// </summary>
|
||||
@ -31,4 +31,3 @@ namespace Jellyfin.Plugin.OpenSubtitles.OpenSubtitlesHandler.Models.Responses
|
||||
[JsonPropertyName("episode_number")]
|
||||
public int? EpisodeNumber { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Jellyfin.Plugin.OpenSubtitles.OpenSubtitlesHandler.Models.Responses
|
||||
{
|
||||
namespace Jellyfin.Plugin.OpenSubtitles.OpenSubtitlesHandler.Models.Responses;
|
||||
|
||||
/// <summary>
|
||||
/// The language info.
|
||||
/// </summary>
|
||||
@ -13,4 +13,3 @@ namespace Jellyfin.Plugin.OpenSubtitles.OpenSubtitlesHandler.Models.Responses
|
||||
[JsonPropertyName("language_code")]
|
||||
public string? Code { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -3,8 +3,8 @@ using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Jellyfin.Plugin.OpenSubtitles.OpenSubtitlesHandler.Models.Responses
|
||||
{
|
||||
namespace Jellyfin.Plugin.OpenSubtitles.OpenSubtitlesHandler.Models.Responses;
|
||||
|
||||
/// <summary>
|
||||
/// The login info.
|
||||
/// </summary>
|
||||
@ -52,4 +52,3 @@ namespace Jellyfin.Plugin.OpenSubtitles.OpenSubtitlesHandler.Models.Responses
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Jellyfin.Plugin.OpenSubtitles.OpenSubtitlesHandler.Models.Responses
|
||||
{
|
||||
namespace Jellyfin.Plugin.OpenSubtitles.OpenSubtitlesHandler.Models.Responses;
|
||||
|
||||
/// <summary>
|
||||
/// The response data.
|
||||
/// </summary>
|
||||
@ -13,4 +13,3 @@ namespace Jellyfin.Plugin.OpenSubtitles.OpenSubtitlesHandler.Models.Responses
|
||||
[JsonPropertyName("attributes")]
|
||||
public Attributes? Attributes { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -2,8 +2,8 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Jellyfin.Plugin.OpenSubtitles.OpenSubtitlesHandler.Models.Responses
|
||||
{
|
||||
namespace Jellyfin.Plugin.OpenSubtitles.OpenSubtitlesHandler.Models.Responses;
|
||||
|
||||
/// <summary>
|
||||
/// The search result.
|
||||
/// </summary>
|
||||
@ -27,4 +27,3 @@ namespace Jellyfin.Plugin.OpenSubtitles.OpenSubtitlesHandler.Models.Responses
|
||||
[JsonPropertyName("data")]
|
||||
public IReadOnlyList<ResponseData> Data { get; set; } = Array.Empty<ResponseData>();
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Jellyfin.Plugin.OpenSubtitles.OpenSubtitlesHandler.Models.Responses
|
||||
{
|
||||
namespace Jellyfin.Plugin.OpenSubtitles.OpenSubtitlesHandler.Models.Responses;
|
||||
|
||||
/// <summary>
|
||||
/// The sub file.
|
||||
/// </summary>
|
||||
@ -11,6 +11,5 @@ namespace Jellyfin.Plugin.OpenSubtitles.OpenSubtitlesHandler.Models.Responses
|
||||
/// Gets or sets the file id.
|
||||
/// </summary>
|
||||
[JsonPropertyName("file_id")]
|
||||
public int FileId { get; set; }
|
||||
}
|
||||
public int? FileId { get; set; }
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
using System;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Jellyfin.Plugin.OpenSubtitles.OpenSubtitlesHandler.Models.Responses
|
||||
{
|
||||
namespace Jellyfin.Plugin.OpenSubtitles.OpenSubtitlesHandler.Models.Responses;
|
||||
|
||||
/// <summary>
|
||||
/// The subtitle download info.
|
||||
/// </summary>
|
||||
@ -26,4 +26,3 @@ namespace Jellyfin.Plugin.OpenSubtitles.OpenSubtitlesHandler.Models.Responses
|
||||
[JsonPropertyName("reset_time_utc")]
|
||||
public DateTime? ResetTime { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Jellyfin.Plugin.OpenSubtitles.OpenSubtitlesHandler.Models.Responses
|
||||
{
|
||||
namespace Jellyfin.Plugin.OpenSubtitles.OpenSubtitlesHandler.Models.Responses;
|
||||
|
||||
/// <summary>
|
||||
/// The uploader.
|
||||
/// </summary>
|
||||
@ -13,4 +13,3 @@ namespace Jellyfin.Plugin.OpenSubtitles.OpenSubtitlesHandler.Models.Responses
|
||||
[JsonPropertyName("name")]
|
||||
public string? Name { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
using System;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Jellyfin.Plugin.OpenSubtitles.OpenSubtitlesHandler.Models.Responses
|
||||
{
|
||||
namespace Jellyfin.Plugin.OpenSubtitles.OpenSubtitlesHandler.Models.Responses;
|
||||
|
||||
/// <summary>
|
||||
/// The user info.
|
||||
/// </summary>
|
||||
@ -26,4 +26,3 @@ namespace Jellyfin.Plugin.OpenSubtitles.OpenSubtitlesHandler.Models.Responses
|
||||
[JsonPropertyName("reset_time_utc")]
|
||||
public DateTime ResetTime { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -7,8 +7,8 @@ using System.Threading.Tasks;
|
||||
using Jellyfin.Plugin.OpenSubtitles.OpenSubtitlesHandler.Models;
|
||||
using Jellyfin.Plugin.OpenSubtitles.OpenSubtitlesHandler.Models.Responses;
|
||||
|
||||
namespace Jellyfin.Plugin.OpenSubtitles.OpenSubtitlesHandler
|
||||
{
|
||||
namespace Jellyfin.Plugin.OpenSubtitles.OpenSubtitlesHandler;
|
||||
|
||||
/// <summary>
|
||||
/// The open subtitles helper class.
|
||||
/// </summary>
|
||||
@ -70,17 +70,23 @@ namespace Jellyfin.Plugin.OpenSubtitles.OpenSubtitlesHandler
|
||||
/// Get the subtitle link.
|
||||
/// </summary>
|
||||
/// <param name="file">The subtitle file.</param>
|
||||
/// <param name="format">The subtitle format.</param>
|
||||
/// <param name="user">The user information.</param>
|
||||
/// <param name="apiKey">The api key.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>The subtitle download info.</returns>
|
||||
public static async Task<ApiResponse<SubtitleDownloadInfo>> GetSubtitleLinkAsync(int file, LoginInfo user, string apiKey, CancellationToken cancellationToken)
|
||||
public static async Task<ApiResponse<SubtitleDownloadInfo>> GetSubtitleLinkAsync(
|
||||
int file,
|
||||
string format,
|
||||
LoginInfo user,
|
||||
string apiKey,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
ArgumentException.ThrowIfNullOrEmpty(user.Token);
|
||||
|
||||
var headers = new Dictionary<string, string> { { "Authorization", user.Token } };
|
||||
|
||||
var body = new { file_id = file };
|
||||
var body = new { file_id = file, sub_format = format };
|
||||
var response = await RequestHandler.SendRequestAsync("/download", HttpMethod.Post, body, headers, apiKey, 1, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
return new ApiResponse<SubtitleDownloadInfo>(response, $"file id: {file}");
|
||||
@ -142,7 +148,7 @@ namespace Jellyfin.Plugin.OpenSubtitles.OpenSubtitlesHandler
|
||||
|
||||
last = new ApiResponse<SearchResult>(response, $"url: {url}", $"page: {current}");
|
||||
|
||||
if (!last.Ok || last.Data == null)
|
||||
if (!last.Ok || last.Data is null)
|
||||
{
|
||||
break;
|
||||
}
|
||||
@ -179,4 +185,3 @@ namespace Jellyfin.Plugin.OpenSubtitles.OpenSubtitlesHandler
|
||||
return new ApiResponse<EncapsulatedLanguageList>(response);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10,8 +10,8 @@ using System.Net.Http.Json;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Jellyfin.Plugin.OpenSubtitles.OpenSubtitlesHandler
|
||||
{
|
||||
namespace Jellyfin.Plugin.OpenSubtitles.OpenSubtitlesHandler;
|
||||
|
||||
/// <summary>
|
||||
/// Http util helper.
|
||||
/// </summary>
|
||||
@ -75,7 +75,7 @@ namespace Jellyfin.Plugin.OpenSubtitles.OpenSubtitlesHandler
|
||||
var client = _clientFactory.CreateClient("Default");
|
||||
|
||||
HttpContent? content = null;
|
||||
if (method != HttpMethod.Get && body != null)
|
||||
if (method != HttpMethod.Get && body is not null)
|
||||
{
|
||||
content = JsonContent.Create(body);
|
||||
}
|
||||
@ -88,7 +88,7 @@ namespace Jellyfin.Plugin.OpenSubtitles.OpenSubtitlesHandler
|
||||
Headers =
|
||||
{
|
||||
UserAgent = { new ProductInfoHeaderValue("Jellyfin-Plugin-OpenSubtitles", _version) },
|
||||
Accept = { new MediaTypeWithQualityHeaderValue("*/*") }
|
||||
Accept = { new MediaTypeWithQualityHeaderValue("*/*") },
|
||||
}
|
||||
};
|
||||
|
||||
@ -111,4 +111,3 @@ namespace Jellyfin.Plugin.OpenSubtitles.OpenSubtitlesHandler
|
||||
return (resBody, resHeaders, result.StatusCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,8 +9,8 @@ using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using Jellyfin.Plugin.OpenSubtitles.OpenSubtitlesHandler.Models;
|
||||
|
||||
namespace Jellyfin.Plugin.OpenSubtitles.OpenSubtitlesHandler
|
||||
{
|
||||
namespace Jellyfin.Plugin.OpenSubtitles.OpenSubtitlesHandler;
|
||||
|
||||
/// <summary>
|
||||
/// The request handler.
|
||||
/// </summary>
|
||||
@ -154,4 +154,3 @@ namespace Jellyfin.Plugin.OpenSubtitles.OpenSubtitlesHandler
|
||||
return url.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,8 +6,8 @@ using MediaBrowser.Common.Plugins;
|
||||
using MediaBrowser.Model.Plugins;
|
||||
using MediaBrowser.Model.Serialization;
|
||||
|
||||
namespace Jellyfin.Plugin.OpenSubtitles
|
||||
{
|
||||
namespace Jellyfin.Plugin.OpenSubtitles;
|
||||
|
||||
/// <summary>
|
||||
/// The open subtitles plugin.
|
||||
/// </summary>
|
||||
@ -27,6 +27,13 @@ namespace Jellyfin.Plugin.OpenSubtitles
|
||||
: base(applicationPaths, xmlSerializer)
|
||||
{
|
||||
Instance = this;
|
||||
|
||||
ConfigurationChanged += (_, _) =>
|
||||
{
|
||||
OpenSubtitleDownloader.Instance?.ConfigurationChanged(this.Configuration);
|
||||
};
|
||||
|
||||
OpenSubtitleDownloader.Instance?.ConfigurationChanged(this.Configuration);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@ -60,4 +67,3 @@ namespace Jellyfin.Plugin.OpenSubtitles
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
18
Jellyfin.Plugin.OpenSubtitles/PluginServiceRegistrator.cs
Normal file
18
Jellyfin.Plugin.OpenSubtitles/PluginServiceRegistrator.cs
Normal file
@ -0,0 +1,18 @@
|
||||
using MediaBrowser.Controller;
|
||||
using MediaBrowser.Controller.Plugins;
|
||||
using MediaBrowser.Controller.Subtitles;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace Jellyfin.Plugin.OpenSubtitles;
|
||||
|
||||
/// <summary>
|
||||
/// Register subtitle provider.
|
||||
/// </summary>
|
||||
public class PluginServiceRegistrator : IPluginServiceRegistrator
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public void RegisterServices(IServiceCollection serviceCollection, IServerApplicationHost applicationHost)
|
||||
{
|
||||
serviceCollection.AddSingleton<ISubtitleProvider, OpenSubtitleDownloader>();
|
||||
}
|
||||
}
|
@ -2,9 +2,9 @@
|
||||
<div data-role="content">
|
||||
<div class="content-primary">
|
||||
<form id="OpenSubtitlesConfigForm">
|
||||
<div style="display: none;" id="expiredCredentialsWarning" class="padded-left padded-right padded-bottom emby-select-withcolor">
|
||||
<h2 style="color: #ff2828;"><strong>Warning!</strong></h2>
|
||||
<p>Your login credentials seem to have changed, please update them in order for the plugin to work.</p>
|
||||
<div style="display: none;" id="expiredCredentialsWarning" class="padded-left padded-right padded-bottom padded-top emby-select-withcolor">
|
||||
<h2 style="color: #ff2828; margin: 0;"><strong>Warning!</strong></h2>
|
||||
<p style="margin: 0;">Your login credentials seem to have changed, please update them in order for the plugin to work.</p>
|
||||
</div>
|
||||
<h3 class="sectionTitle sectionTitle-cards"><b>In order for this plugin to work you need to enter your OpenSubtitles.com account info below</b></h3>
|
||||
<div class="inputContainer">
|
||||
|
@ -26,7 +26,7 @@ This is a plugin allows you to download subtitles from [Open Subtitles](https://
|
||||
|
||||
## Build
|
||||
|
||||
1. To build this plugin you will need [.Net 6.x](https://dotnet.microsoft.com/download/dotnet/6.0).
|
||||
1. To build this plugin you will need [.Net 8.x](https://dotnet.microsoft.com/download/dotnet/8.0).
|
||||
|
||||
2. Build plugin with following command
|
||||
```
|
||||
|
@ -6,7 +6,7 @@ targetAbi: "10.9.0.0"
|
||||
framework: "net8.0"
|
||||
owner: "jellyfin"
|
||||
overview: "Download subtitles for your media"
|
||||
description: "Download subtitles from the internet to use with your media files."
|
||||
description: "Download subtitles from the internet to use with your media files. (Requires configuration)"
|
||||
category: "Metadata"
|
||||
artifacts:
|
||||
- "Jellyfin.Plugin.OpenSubtitles.dll"
|
||||
|
Loading…
Reference in New Issue
Block a user