mirror of
https://github.com/jellyfin/jellyfin-plugin-opensubtitles.git
synced 2024-11-27 00:10:50 +00:00
Merge branch 'master' into api-key
This commit is contained in:
commit
87c8e967dd
1
.github/workflows/build-dotnet.yml
vendored
1
.github/workflows/build-dotnet.yml
vendored
@ -20,7 +20,6 @@ jobs:
|
||||
uses: actions/setup-dotnet@v1
|
||||
with:
|
||||
dotnet-version: 6.0.x
|
||||
include-prerelease: true
|
||||
|
||||
- name: Build Jellyfin Plugin
|
||||
uses: oddstr13/jellyfin-plugin-repository-manager@v0.4.2
|
||||
|
1
.github/workflows/codeql-analysis.yml
vendored
1
.github/workflows/codeql-analysis.yml
vendored
@ -31,7 +31,6 @@ jobs:
|
||||
uses: actions/setup-dotnet@v1
|
||||
with:
|
||||
dotnet-version: 6.0.x
|
||||
include-prerelease: true
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v1
|
||||
|
1
.github/workflows/test-dotnet.yml
vendored
1
.github/workflows/test-dotnet.yml
vendored
@ -20,7 +20,6 @@ jobs:
|
||||
uses: actions/setup-dotnet@v1
|
||||
with:
|
||||
dotnet-version: 6.0.x
|
||||
include-prerelease: true
|
||||
|
||||
- name: Install dependencies
|
||||
run: dotnet restore
|
||||
|
22
.github/workflows/update-release-draft.yml
vendored
22
.github/workflows/update-release-draft.yml
vendored
@ -1,11 +1,16 @@
|
||||
# Automates creation of Release Drafts using Release Drafter
|
||||
name: Update Release Draft
|
||||
name: Update Release Draft & Create Release Bump PR
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
paths-ignore:
|
||||
- build.yaml
|
||||
workflow_dispatch:
|
||||
repository_dispatch:
|
||||
types:
|
||||
- update-prep-command
|
||||
|
||||
jobs:
|
||||
update_release_draft:
|
||||
@ -23,9 +28,9 @@ jobs:
|
||||
- name: Setup YQ
|
||||
uses: chrisdickinson/setup-yq@latest
|
||||
with:
|
||||
yq-version: v4.9.6
|
||||
yq-version: v4.12.2
|
||||
|
||||
- name: Parse changelog
|
||||
- name: Set-up Environment
|
||||
run: |
|
||||
TAG="${{ steps.draft.outputs.tag_name }}"
|
||||
echo "VERSION=${TAG#v}" >> $GITHUB_ENV
|
||||
@ -41,16 +46,22 @@ jobs:
|
||||
cat cl.md >> $GITHUB_ENV
|
||||
echo "EOF" >> $GITHUB_ENV
|
||||
|
||||
echo "HAS_CHANGES=$(grep -qie 'No changes$' cl.md && echo false || echo true)" >> $GITHUB_ENV
|
||||
rm cl.md
|
||||
|
||||
- name: Checkout repository
|
||||
echo "ABI_VERSION=$(curl -s https://api.jellyfin.org/openapi/jellyfin-openapi-stable.json | jq -r '.info.version').0" >> $GITHUB_ENV
|
||||
|
||||
- name: Checkout Repository
|
||||
if: ${{ env.HAS_CHANGES == 'true' }}
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Update build.yaml
|
||||
if: ${{ env.HAS_CHANGES == 'true' }}
|
||||
run: |
|
||||
yq eval '.version = env(VERSION) | .changelog = strenv(CHANGELOG) | .changelog style="literal"' -i build.yaml
|
||||
yq eval '.version = env(VERSION) | .targetAbi = env(ABI_VERSION) | .changelog = strenv(CHANGELOG) | .changelog style="literal"' -i build.yaml
|
||||
|
||||
- name: Commit Changes
|
||||
if: ${{ env.HAS_CHANGES == 'true' }}
|
||||
run: |
|
||||
git config user.name "jellyfin-bot"
|
||||
git config user.email "team@jellyfin.org"
|
||||
@ -59,6 +70,7 @@ jobs:
|
||||
git push -f origin prepare-${{ env.VERSION }}
|
||||
|
||||
- name: Create or Update PR
|
||||
if: ${{ env.HAS_CHANGES == 'true' }}
|
||||
uses: k3rnels-actions/pr-update@v1
|
||||
with:
|
||||
token: ${{ secrets.JF_BOT_TOKEN }}
|
||||
|
@ -26,7 +26,6 @@ namespace Jellyfin.Plugin.OpenSubtitles
|
||||
/// </summary>
|
||||
public class OpenSubtitleDownloader : ISubtitleProvider
|
||||
{
|
||||
private static readonly CultureInfo _usCulture = CultureInfo.ReadOnly(new CultureInfo("en-US"));
|
||||
private readonly ILogger<OpenSubtitleDownloader> _logger;
|
||||
private LoginInfo? _login;
|
||||
private DateTime? _limitReset;
|
||||
@ -86,8 +85,8 @@ namespace Jellyfin.Plugin.OpenSubtitles
|
||||
{
|
||||
throw new ArgumentNullException(nameof(request));
|
||||
}
|
||||
|
||||
long.TryParse(request.GetProviderId(MetadataProvider.Imdb)?.TrimStart('t') ?? string.Empty, NumberStyles.Any, _usCulture, out var imdbId);
|
||||
|
||||
long.TryParse(request.GetProviderId(MetadataProvider.Imdb)?.TrimStart('t') ?? string.Empty, NumberStyles.Any, CultureInfo.InvariantCulture, out var imdbId);
|
||||
|
||||
if (request.ContentType == VideoContentType.Episode && (!request.IndexNumber.HasValue || !request.ParentIndexNumber.HasValue || string.IsNullOrEmpty(request.SeriesName)))
|
||||
{
|
||||
@ -108,10 +107,11 @@ namespace Jellyfin.Plugin.OpenSubtitles
|
||||
string hash;
|
||||
try
|
||||
{
|
||||
await using (var fileStream = File.OpenRead(request.MediaPath))
|
||||
{
|
||||
hash = OpenSubtitlesRequestHelper.ComputeHash(fileStream);
|
||||
}
|
||||
#pragma warning disable CA2007
|
||||
await using var fileStream = File.OpenRead(request.MediaPath);
|
||||
#pragma warning restore CA2007
|
||||
|
||||
hash = OpenSubtitlesRequestHelper.ComputeHash(fileStream);
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
@ -122,21 +122,29 @@ namespace Jellyfin.Plugin.OpenSubtitles
|
||||
{
|
||||
{ "languages", language },
|
||||
{ "moviehash", hash },
|
||||
{ "type", request.ContentType == VideoContentType.Episode ? "episode" : "movie" },
|
||||
{ "query", request.ContentType == VideoContentType.Episode ? request.SeriesName : Path.GetFileName(request.MediaPath) }
|
||||
{ "type", request.ContentType == VideoContentType.Episode ? "episode" : "movie" }
|
||||
};
|
||||
|
||||
// If we have the IMDb ID we use that, otherwise query with the details
|
||||
if (imdbId != 0)
|
||||
{
|
||||
options.Add("imdb_id", imdbId.ToString(_usCulture));
|
||||
options.Add("imdb_id", imdbId.ToString(CultureInfo.InvariantCulture));
|
||||
}
|
||||
else
|
||||
{
|
||||
options.Add("query", Path.GetFileName(request.MediaPath));
|
||||
|
||||
if (request.ContentType == VideoContentType.Episode)
|
||||
{
|
||||
options.Add("season_number", request.ParentIndexNumber?.ToString(_usCulture) ?? string.Empty);
|
||||
options.Add("episode_number", request.IndexNumber?.ToString(_usCulture) ?? string.Empty);
|
||||
if (request.ParentIndexNumber.HasValue)
|
||||
{
|
||||
options.Add("season_number", request.ParentIndexNumber.Value.ToString(CultureInfo.InvariantCulture));
|
||||
}
|
||||
|
||||
if (request.IndexNumber.HasValue)
|
||||
{
|
||||
options.Add("episode_number", request.IndexNumber.Value.ToString(CultureInfo.InvariantCulture));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -232,16 +240,13 @@ namespace Jellyfin.Plugin.OpenSubtitles
|
||||
var language = idParts[1];
|
||||
var ossId = idParts[2];
|
||||
|
||||
var fid = int.Parse(ossId, _usCulture);
|
||||
var fid = int.Parse(ossId, CultureInfo.InvariantCulture);
|
||||
|
||||
var info = await OpenSubtitlesHandler.OpenSubtitles.GetSubtitleLinkAsync(fid, _login, ApiKey, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
if (info.Data?.Message != null && info.Data.Message.Contains("UTC", StringComparison.Ordinal))
|
||||
if (info.Data?.ResetTime != null)
|
||||
{
|
||||
// "Your quota will be renewed in 20 hours and 52 minutes (2021-08-24 12:02:10 UTC) "
|
||||
var str = info.Data.Message.Split('(')[1].Trim().Replace(" UTC)", "Z", StringComparison.Ordinal);
|
||||
_limitReset = DateTime.Parse(str, _usCulture, DateTimeStyles.AdjustToUniversal);
|
||||
|
||||
_limitReset = info.Data.ResetTime;
|
||||
_logger.LogDebug("Updated expiration time to {ResetTime}", _limitReset);
|
||||
}
|
||||
|
||||
@ -288,7 +293,7 @@ namespace Jellyfin.Plugin.OpenSubtitles
|
||||
{
|
||||
var msg = string.Format(
|
||||
CultureInfo.InvariantCulture,
|
||||
"Failed to obtain download link for file {0}: {1}",
|
||||
"Failed to obtain download link for file {0}: {1} (empty response)",
|
||||
fid,
|
||||
info.Code);
|
||||
|
||||
|
@ -82,6 +82,6 @@ namespace OpenSubtitlesHandler.Models
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the request was successful.
|
||||
/// </summary>
|
||||
public bool Ok => (int)Code < 400;
|
||||
public bool Ok => (int)Code >= 200 && (int)Code <= 299;
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
using System.Text.Json.Serialization;
|
||||
using System;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace OpenSubtitlesHandler.Models.Responses
|
||||
{
|
||||
@ -24,5 +25,11 @@ namespace OpenSubtitlesHandler.Models.Responses
|
||||
/// </summary>
|
||||
[JsonPropertyName("message")]
|
||||
public string? Message { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the reset time.
|
||||
/// </summary>
|
||||
[JsonPropertyName("reset_time_utc")]
|
||||
public DateTime? ResetTime { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -120,11 +120,6 @@ namespace OpenSubtitlesHandler
|
||||
{
|
||||
var opts = System.Web.HttpUtility.ParseQueryString(string.Empty);
|
||||
|
||||
foreach (var (key, value) in options.OrderBy(x => x.Key))
|
||||
{
|
||||
opts.Add(key, value);
|
||||
}
|
||||
|
||||
var max = -1;
|
||||
var current = 1;
|
||||
|
||||
@ -134,11 +129,21 @@ namespace OpenSubtitlesHandler
|
||||
|
||||
do
|
||||
{
|
||||
opts.Set("page", current.ToString(CultureInfo.InvariantCulture));
|
||||
opts.Clear();
|
||||
|
||||
if (current > 1)
|
||||
{
|
||||
options["page"] = current.ToString(CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
foreach (var (key, value) in options.OrderBy(x => x.Key))
|
||||
{
|
||||
opts.Add(key.ToLower(CultureInfo.InvariantCulture), value.ToLower(CultureInfo.InvariantCulture));
|
||||
}
|
||||
|
||||
response = await RequestHandler.SendRequestAsync($"/subtitles?{opts}", HttpMethod.Get, null, null, apiKey, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
last = new ApiResponse<SearchResult>(response, $"options: {options}", $"page: {current}");
|
||||
last = new ApiResponse<SearchResult>(response, $"query: {opts}", $"page: {current}");
|
||||
|
||||
if (!last.Ok || last.Data == null)
|
||||
{
|
||||
|
10
build.yaml
10
build.yaml
@ -1,9 +1,9 @@
|
||||
name: "Open Subtitles"
|
||||
guid: "4b9ed42f-5185-48b5-9803-6ff2989014c4"
|
||||
imageUrl: "https://repo.jellyfin.org/releases/plugin/images/jellyfin-plugin-opensubtitles.png"
|
||||
version: "12"
|
||||
targetAbi: "10.7.7.0"
|
||||
framework: "net5.0"
|
||||
version: "15"
|
||||
targetAbi: "10.8.0.0"
|
||||
framework: "net6.0"
|
||||
owner: "jellyfin"
|
||||
overview: "Download subtitles for your media"
|
||||
description: "Download subtitles from the internet to use with your media files."
|
||||
@ -12,5 +12,5 @@ artifacts:
|
||||
- "Jellyfin.Plugin.OpenSubtitles.dll"
|
||||
- "OpenSubtitlesHandler.dll"
|
||||
changelog: |2-
|
||||
### Bug Fixes ###
|
||||
- Fixes, language improvements, code cleanup & error logging (#67) @MBR-0001
|
||||
### Code or Repo Maintenance ###
|
||||
- Fix build.yaml, fix new build errors (#81) @crobibero
|
||||
|
@ -1,9 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RuleSet Name="Rules for Jellyfin.Server" Description="Code analysis rules for Jellyfin.Server.csproj" ToolsVersion="14.0">
|
||||
<Rules AnalyzerId="StyleCop.Analyzers" RuleNamespace="StyleCop.Analyzers">
|
||||
<!-- disable warning CA1040: Avoid empty interfaces -->
|
||||
<Rule Id="CA1040" Action="Info" />
|
||||
|
||||
<!-- disable warning SA1009: Closing parenthesis should be followed by a space. -->
|
||||
<Rule Id="SA1009" Action="None" />
|
||||
<!-- disable warning SA1011: Closing square bracket should be followed by a space. -->
|
||||
@ -12,6 +9,8 @@
|
||||
<Rule Id="SA1101" Action="None" />
|
||||
<!-- disable warning SA1108: Block statements should not contain embedded comments -->
|
||||
<Rule Id="SA1108" Action="None" />
|
||||
<!-- disable warning SA1118: Parameter must not span multiple lines. -->
|
||||
<Rule Id="SA1118" Action="None" />
|
||||
<!-- disable warning SA1128:: Put constructor initializers on their own line -->
|
||||
<Rule Id="SA1128" Action="None" />
|
||||
<!-- disable warning SA1130: Use lambda syntax -->
|
||||
@ -39,9 +38,19 @@
|
||||
</Rules>
|
||||
|
||||
<Rules AnalyzerId="Microsoft.CodeAnalysis.NetAnalyzers" RuleNamespace="Microsoft.Design">
|
||||
<!-- error on CA1305: Specify IFormatProvider -->
|
||||
<Rule Id="CA1305" Action="Error" />
|
||||
<!-- error on CA1725: Parameter names should match base declaration -->
|
||||
<Rule Id="CA1725" Action="Error" />
|
||||
<!-- error on CA1725: Call async methods when in an async method -->
|
||||
<Rule Id="CA1727" Action="Error" />
|
||||
<!-- error on CA1843: Do not use 'WaitAll' with a single task -->
|
||||
<Rule Id="CA1843" Action="Error" />
|
||||
<!-- error on CA2016: Forward the CancellationToken parameter to methods that take one
|
||||
or pass in 'CancellationToken.None' explicitly to indicate intentionally not propagating the token -->
|
||||
<Rule Id="CA2016" Action="Error" />
|
||||
<!-- error on CA2254: Template should be a static expression -->
|
||||
<Rule Id="CA2254" Action="Error" />
|
||||
|
||||
<!-- disable warning CA1014: Mark assemblies with CLSCompliantAttribute -->
|
||||
<Rule Id="CA1014" Action="Info" />
|
||||
@ -51,12 +60,19 @@
|
||||
<Rule Id="CA1031" Action="Info" />
|
||||
<!-- disable warning CA1032: Implement standard exception constructors -->
|
||||
<Rule Id="CA1032" Action="Info" />
|
||||
<!-- disable warning CA1040: Avoid empty interfaces -->
|
||||
<Rule Id="CA1040" Action="Info" />
|
||||
<!-- disable warning CA1062: Validate arguments of public methods -->
|
||||
<Rule Id="CA1062" Action="Info" />
|
||||
<!-- TODO: enable when false positives are fixed -->
|
||||
<!-- disable warning CA1508: Avoid dead conditional code -->
|
||||
<Rule Id="CA1508" Action="Info" />
|
||||
<!-- disable warning CA1716: Identifiers should not match keywords -->
|
||||
<Rule Id="CA1716" Action="Info" />
|
||||
<!-- disable warning CA1720: Identifiers should not contain type names -->
|
||||
<Rule Id="CA1720" Action="Info" />
|
||||
<!-- disable warning CA1724: Type names should not match namespaces -->
|
||||
<Rule Id="CA1724" Action="Info" />
|
||||
<!-- disable warning CA1805: Do not initialize unnecessarily -->
|
||||
<Rule Id="CA1805" Action="Info" />
|
||||
<!-- disable warning CA1812: internal class that is apparently never instantiated.
|
||||
@ -67,6 +83,8 @@
|
||||
<Rule Id="CA1822" Action="Info" />
|
||||
<!-- disable warning CA2000: Dispose objects before losing scope -->
|
||||
<Rule Id="CA2000" Action="Info" />
|
||||
<!-- disable warning CA2253: Named placeholders should not be numeric values -->
|
||||
<Rule Id="CA2253" Action="Info" />
|
||||
<!-- disable warning CA5394: Do not use insecure randomness -->
|
||||
<Rule Id="CA5394" Action="Info" />
|
||||
|
||||
@ -80,6 +98,8 @@
|
||||
<Rule Id="CA1303" Action="None" />
|
||||
<!-- disable warning CA1308: Normalize strings to uppercase -->
|
||||
<Rule Id="CA1308" Action="None" />
|
||||
<!-- disable warning CA1848: Use the LoggerMessage delegates -->
|
||||
<Rule Id="CA1848" Action="None" />
|
||||
<!-- disable warning CA2101: Specify marshaling for P/Invoke string arguments -->
|
||||
<Rule Id="CA2101" Action="None" />
|
||||
<!-- disable warning CA2234: Pass System.Uri objects instead of strings -->
|
||||
|
Loading…
Reference in New Issue
Block a user