10.9 support (#115)

This commit is contained in:
MBR-0001 2024-04-03 23:32:56 +02:00 committed by Cody Robibero
parent 6d8ee4eb7a
commit ecc270c915
28 changed files with 1221 additions and 1211 deletions

View File

@ -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 });
}
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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; }
}
}

View File

@ -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;
}
}

View File

@ -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; }
}
}

View File

@ -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!;
}
}

View File

@ -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; }
}
}

View File

@ -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; }
}
}

View File

@ -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; }
}
}

View File

@ -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; }
}
}

View File

@ -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; }
}
}

View File

@ -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
}
}
}
}

View File

@ -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; }
}
}

View File

@ -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>();
}
}

View File

@ -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; }
}

View File

@ -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; }
}
}

View File

@ -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; }
}
}

View File

@ -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; }
}
}

View File

@ -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);
}
}
}

View File

@ -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);
}
}
}

View File

@ -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();
}
}
}

View File

@ -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
};
}
}
}

View 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>();
}
}

View File

@ -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">

View File

@ -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
```

View File

@ -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"