Compare commits

...

8 Commits

Author SHA1 Message Date
Bogdan
5635de96a8 Fixed: Initial state for qBittorrent v5.0
(cherry picked from commit ff724b7f4099284b8062f1625cf07b7822782edf)
2024-11-15 20:01:26 -06:00
Mickaël Thomas
ce59f32023 New: Support stoppedUP and stoppedDL states from qBittorrent
(cherry picked from commit 73a4bdea5247ee87e6bbae95f5325e1f03c88a7f)
2024-11-15 20:01:26 -06:00
bakerboy448
6d675a5207 Fix Goodreads test 2024-11-15 17:57:51 -06:00
Bogdan
b093b23900 Pin ReportGenerator in Azure Pipelines for .NET 6
(cherry picked from commit 50ce480abf043140e209d2d2959fbea8dd5dd2ab)
2024-11-15 15:45:16 -06:00
Weblate
884ac2cb6f Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Fixer <ygj59783@zslsz.com>
Translate-URL: https://translate.servarr.com/projects/servarr/readarr/ro/
Translation: Servarr/Readarr
2024-11-07 17:04:03 +02:00
Weblate
295a6c4255 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Anonymous <noreply@weblate.org>
Translate-URL: https://translate.servarr.com/projects/servarr/readarr/ar/
Translate-URL: https://translate.servarr.com/projects/servarr/readarr/bg/
Translate-URL: https://translate.servarr.com/projects/servarr/readarr/cs/
Translate-URL: https://translate.servarr.com/projects/servarr/readarr/da/
Translate-URL: https://translate.servarr.com/projects/servarr/readarr/de/
Translate-URL: https://translate.servarr.com/projects/servarr/readarr/el/
Translate-URL: https://translate.servarr.com/projects/servarr/readarr/es/
Translate-URL: https://translate.servarr.com/projects/servarr/readarr/fi/
Translate-URL: https://translate.servarr.com/projects/servarr/readarr/fr/
Translate-URL: https://translate.servarr.com/projects/servarr/readarr/he/
Translate-URL: https://translate.servarr.com/projects/servarr/readarr/hi/
Translate-URL: https://translate.servarr.com/projects/servarr/readarr/hr/
Translate-URL: https://translate.servarr.com/projects/servarr/readarr/hu/
Translate-URL: https://translate.servarr.com/projects/servarr/readarr/id/
Translate-URL: https://translate.servarr.com/projects/servarr/readarr/is/
Translate-URL: https://translate.servarr.com/projects/servarr/readarr/it/
Translate-URL: https://translate.servarr.com/projects/servarr/readarr/ja/
Translate-URL: https://translate.servarr.com/projects/servarr/readarr/ko/
Translate-URL: https://translate.servarr.com/projects/servarr/readarr/nb_NO/
Translate-URL: https://translate.servarr.com/projects/servarr/readarr/nl/
Translate-URL: https://translate.servarr.com/projects/servarr/readarr/pl/
Translate-URL: https://translate.servarr.com/projects/servarr/readarr/pt/
Translate-URL: https://translate.servarr.com/projects/servarr/readarr/pt_BR/
Translate-URL: https://translate.servarr.com/projects/servarr/readarr/ro/
Translate-URL: https://translate.servarr.com/projects/servarr/readarr/ru/
Translate-URL: https://translate.servarr.com/projects/servarr/readarr/sv/
Translate-URL: https://translate.servarr.com/projects/servarr/readarr/th/
Translate-URL: https://translate.servarr.com/projects/servarr/readarr/tr/
Translate-URL: https://translate.servarr.com/projects/servarr/readarr/uk/
Translate-URL: https://translate.servarr.com/projects/servarr/readarr/vi/
Translate-URL: https://translate.servarr.com/projects/servarr/readarr/zh_CN/
Translation: Servarr/Readarr
2024-11-05 02:26:50 +02:00
Mark McDowall
74a59d5790 Use current time for cache break in development
(cherry picked from commit 020ed32fcfab1c6fbe57af5ea650300272c93fd7)
2024-11-05 02:25:32 +02:00
Bogdan
ae23e5f187 Bump version to 0.4.4 2024-11-03 11:43:03 +02:00
40 changed files with 490 additions and 140 deletions

View File

@@ -9,7 +9,7 @@ variables:
testsFolder: './_tests'
yarnCacheFolder: $(Pipeline.Workspace)/.yarn
nugetCacheFolder: $(Pipeline.Workspace)/.nuget/packages
majorVersion: '0.4.3'
majorVersion: '0.4.4'
minorVersion: $[counter('minorVersion', 1)]
readarrVersion: '$(majorVersion).$(minorVersion)'
buildName: '$(Build.SourceBranchName).$(readarrVersion)'
@@ -1211,7 +1211,7 @@ stages:
- task: SonarCloudAnalyze@2
condition: eq(variables['System.PullRequest.IsFork'], 'False')
displayName: Publish SonarCloud Results
- task: reportgenerator@5
- task: reportgenerator@5.3.11
displayName: Generate Coverage Report
inputs:
reports: '$(Build.SourcesDirectory)/CoverageResults/**/coverage.opencover.xml'

View File

@@ -178,8 +178,9 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.QBittorrentTests
VerifyWarning(item);
}
[Test]
public void paused_item_should_have_required_properties()
[TestCase("pausedDL")]
[TestCase("stoppedDL")]
public void paused_item_should_have_required_properties(string state)
{
var torrent = new QBittorrentTorrent
{
@@ -188,7 +189,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.QBittorrentTests
Size = 1000,
Progress = 0.7,
Eta = 8640000,
State = "pausedDL",
State = state,
Label = "",
SavePath = ""
};
@@ -200,6 +201,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.QBittorrentTests
}
[TestCase("pausedUP")]
[TestCase("stoppedUP")]
[TestCase("queuedUP")]
[TestCase("uploading")]
[TestCase("stalledUP")]
@@ -397,8 +399,9 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.QBittorrentTests
result.OutputPath.FullPath.Should().Be(Path.Combine(torrent.SavePath, "Droned.S01.12"));
}
[Test]
public void api_261_should_use_content_path()
[TestCase("pausedUP")]
[TestCase("stoppedUP")]
public void api_261_should_use_content_path(string state)
{
var torrent = new QBittorrentTorrent
{
@@ -407,7 +410,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.QBittorrentTests
Size = 1000,
Progress = 0.7,
Eta = 8640000,
State = "pausedUP",
State = state,
Label = "",
SavePath = @"C:\Torrents".AsOsAgnostic(),
ContentPath = @"C:\Torrents\Droned.S01.12".AsOsAgnostic()
@@ -684,44 +687,48 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.QBittorrentTests
item.CanMoveFiles.Should().BeFalse();
}
[Test]
public void should_not_be_removable_and_should_not_allow_move_files_if_max_ratio_is_not_set()
[TestCase("pausedUP")]
[TestCase("stoppedUP")]
public void should_not_be_removable_and_should_not_allow_move_files_if_max_ratio_is_not_set(string state)
{
GivenGlobalSeedLimits(-1);
GivenCompletedTorrent("pausedUP", ratio: 1.0f);
GivenCompletedTorrent(state, ratio: 1.0f);
var item = Subject.GetItems().Single();
item.CanBeRemoved.Should().BeFalse();
item.CanMoveFiles.Should().BeFalse();
}
[Test]
public void should_be_removable_and_should_allow_move_files_if_max_ratio_reached_and_paused()
[TestCase("pausedUP")]
[TestCase("stoppedUP")]
public void should_be_removable_and_should_allow_move_files_if_max_ratio_reached_and_paused(string state)
{
GivenGlobalSeedLimits(1.0f);
GivenCompletedTorrent("pausedUP", ratio: 1.0f);
GivenCompletedTorrent(state, ratio: 1.0f);
var item = Subject.GetItems().Single();
item.CanBeRemoved.Should().BeTrue();
item.CanMoveFiles.Should().BeTrue();
}
[Test]
public void should_be_removable_and_should_allow_move_files_if_overridden_max_ratio_reached_and_paused()
[TestCase("pausedUP")]
[TestCase("stoppedUP")]
public void should_be_removable_and_should_allow_move_files_if_overridden_max_ratio_reached_and_paused(string state)
{
GivenGlobalSeedLimits(2.0f);
GivenCompletedTorrent("pausedUP", ratio: 1.0f, ratioLimit: 0.8f);
GivenCompletedTorrent(state, ratio: 1.0f, ratioLimit: 0.8f);
var item = Subject.GetItems().Single();
item.CanBeRemoved.Should().BeTrue();
item.CanMoveFiles.Should().BeTrue();
}
[Test]
public void should_not_be_removable_if_overridden_max_ratio_not_reached_and_paused()
[TestCase("pausedUP")]
[TestCase("stoppedUP")]
public void should_not_be_removable_if_overridden_max_ratio_not_reached_and_paused(string state)
{
GivenGlobalSeedLimits(0.2f);
GivenCompletedTorrent("pausedUP", ratio: 0.5f, ratioLimit: 0.8f);
GivenCompletedTorrent(state, ratio: 0.5f, ratioLimit: 0.8f);
var item = Subject.GetItems().Single();
item.CanBeRemoved.Should().BeFalse();
@@ -739,33 +746,36 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.QBittorrentTests
item.CanMoveFiles.Should().BeFalse();
}
[Test]
public void should_be_removable_and_should_allow_move_files_if_max_seedingtime_reached_and_paused()
[TestCase("pausedUP")]
[TestCase("stoppedUP")]
public void should_be_removable_and_should_allow_move_files_if_max_seedingtime_reached_and_paused(string state)
{
GivenGlobalSeedLimits(-1, 20);
GivenCompletedTorrent("pausedUP", ratio: 2.0f, seedingTime: 20);
GivenCompletedTorrent(state, ratio: 2.0f, seedingTime: 20);
var item = Subject.GetItems().Single();
item.CanBeRemoved.Should().BeTrue();
item.CanMoveFiles.Should().BeTrue();
}
[Test]
public void should_be_removable_and_should_allow_move_files_if_overridden_max_seedingtime_reached_and_paused()
[TestCase("pausedUP")]
[TestCase("stoppedUP")]
public void should_be_removable_and_should_allow_move_files_if_overridden_max_seedingtime_reached_and_paused(string state)
{
GivenGlobalSeedLimits(-1, 40);
GivenCompletedTorrent("pausedUP", ratio: 2.0f, seedingTime: 20, seedingTimeLimit: 10);
GivenCompletedTorrent(state, ratio: 2.0f, seedingTime: 20, seedingTimeLimit: 10);
var item = Subject.GetItems().Single();
item.CanBeRemoved.Should().BeTrue();
item.CanMoveFiles.Should().BeTrue();
}
[Test]
public void should_not_be_removable_if_overridden_max_seedingtime_not_reached_and_paused()
[TestCase("pausedUP")]
[TestCase("stoppedUP")]
public void should_not_be_removable_if_overridden_max_seedingtime_not_reached_and_paused(string state)
{
GivenGlobalSeedLimits(-1, 20);
GivenCompletedTorrent("pausedUP", ratio: 2.0f, seedingTime: 30, seedingTimeLimit: 40);
GivenCompletedTorrent(state, ratio: 2.0f, seedingTime: 30, seedingTimeLimit: 40);
var item = Subject.GetItems().Single();
item.CanBeRemoved.Should().BeFalse();
@@ -783,66 +793,72 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.QBittorrentTests
item.CanMoveFiles.Should().BeFalse();
}
[Test]
public void should_be_removable_and_should_allow_move_files_if_max_inactive_seedingtime_reached_and_paused()
[TestCase("pausedUP")]
[TestCase("stoppedUP")]
public void should_be_removable_and_should_allow_move_files_if_max_inactive_seedingtime_reached_and_paused(string state)
{
GivenGlobalSeedLimits(-1, maxInactiveSeedingTime: 20);
GivenCompletedTorrent("pausedUP", ratio: 2.0f, lastActivity: DateTimeOffset.UtcNow.Subtract(TimeSpan.FromMinutes(25)).ToUnixTimeSeconds());
GivenCompletedTorrent(state, ratio: 2.0f, lastActivity: DateTimeOffset.UtcNow.Subtract(TimeSpan.FromMinutes(25)).ToUnixTimeSeconds());
var item = Subject.GetItems().Single();
item.CanBeRemoved.Should().BeTrue();
item.CanMoveFiles.Should().BeTrue();
}
[Test]
public void should_be_removable_and_should_allow_move_files_if_overridden_max_inactive_seedingtime_reached_and_paused()
[TestCase("pausedUP")]
[TestCase("stoppedUP")]
public void should_be_removable_and_should_allow_move_files_if_overridden_max_inactive_seedingtime_reached_and_paused(string state)
{
GivenGlobalSeedLimits(-1, maxInactiveSeedingTime: 40);
GivenCompletedTorrent("pausedUP", ratio: 2.0f, seedingTime: 20, inactiveSeedingTimeLimit: 10, lastActivity: DateTimeOffset.UtcNow.Subtract(TimeSpan.FromMinutes(15)).ToUnixTimeSeconds());
GivenCompletedTorrent(state, ratio: 2.0f, seedingTime: 20, inactiveSeedingTimeLimit: 10, lastActivity: DateTimeOffset.UtcNow.Subtract(TimeSpan.FromMinutes(15)).ToUnixTimeSeconds());
var item = Subject.GetItems().Single();
item.CanBeRemoved.Should().BeTrue();
item.CanMoveFiles.Should().BeTrue();
}
[Test]
public void should_not_be_removable_if_overridden_max_inactive_seedingtime_not_reached_and_paused()
[TestCase("pausedUP")]
[TestCase("stoppedUP")]
public void should_not_be_removable_if_overridden_max_inactive_seedingtime_not_reached_and_paused(string state)
{
GivenGlobalSeedLimits(-1, maxInactiveSeedingTime: 20);
GivenCompletedTorrent("pausedUP", ratio: 2.0f, seedingTime: 30, inactiveSeedingTimeLimit: 40, lastActivity: DateTimeOffset.UtcNow.Subtract(TimeSpan.FromMinutes(30)).ToUnixTimeSeconds());
GivenCompletedTorrent(state, ratio: 2.0f, seedingTime: 30, inactiveSeedingTimeLimit: 40, lastActivity: DateTimeOffset.UtcNow.Subtract(TimeSpan.FromMinutes(30)).ToUnixTimeSeconds());
var item = Subject.GetItems().Single();
item.CanBeRemoved.Should().BeFalse();
item.CanMoveFiles.Should().BeFalse();
}
[Test]
public void should_be_removable_and_should_allow_move_files_if_max_seedingtime_reached_but_ratio_not_and_paused()
[TestCase("pausedUP")]
[TestCase("stoppedUP")]
public void should_be_removable_and_should_allow_move_files_if_max_seedingtime_reached_but_ratio_not_and_paused(string state)
{
GivenGlobalSeedLimits(2.0f, 20);
GivenCompletedTorrent("pausedUP", ratio: 1.0f, seedingTime: 30);
GivenCompletedTorrent(state, ratio: 1.0f, seedingTime: 30);
var item = Subject.GetItems().Single();
item.CanBeRemoved.Should().BeTrue();
item.CanMoveFiles.Should().BeTrue();
}
[Test]
public void should_be_removable_and_should_allow_move_files_if_max_inactive_seedingtime_reached_but_ratio_not_and_paused()
[TestCase("pausedUP")]
[TestCase("stoppedUP")]
public void should_be_removable_and_should_allow_move_files_if_max_inactive_seedingtime_reached_but_ratio_not_and_paused(string state)
{
GivenGlobalSeedLimits(2.0f, maxInactiveSeedingTime: 20);
GivenCompletedTorrent("pausedUP", ratio: 1.0f, lastActivity: DateTimeOffset.UtcNow.Subtract(TimeSpan.FromMinutes(25)).ToUnixTimeSeconds());
GivenCompletedTorrent(state, ratio: 1.0f, lastActivity: DateTimeOffset.UtcNow.Subtract(TimeSpan.FromMinutes(25)).ToUnixTimeSeconds());
var item = Subject.GetItems().Single();
item.CanBeRemoved.Should().BeTrue();
item.CanMoveFiles.Should().BeTrue();
}
[Test]
public void should_not_fetch_details_twice()
[TestCase("pausedUP")]
[TestCase("stoppedUP")]
public void should_not_fetch_details_twice(string state)
{
GivenGlobalSeedLimits(-1, 30);
GivenCompletedTorrent("pausedUP", ratio: 2.0f, seedingTime: 20);
GivenCompletedTorrent(state, ratio: 2.0f, seedingTime: 20);
var item = Subject.GetItems().Single();
item.CanBeRemoved.Should().BeFalse();
@@ -854,8 +870,9 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.QBittorrentTests
.Verify(p => p.GetTorrentProperties(It.IsAny<string>(), It.IsAny<QBittorrentSettings>()), Times.Once());
}
[Test]
public void should_get_category_from_the_category_if_set()
[TestCase("pausedUP")]
[TestCase("stoppedUP")]
public void should_get_category_from_the_category_if_set(string state)
{
const string category = "music-readarr";
GivenGlobalSeedLimits(1.0f);
@@ -867,7 +884,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.QBittorrentTests
Size = 1000,
Progress = 1.0,
Eta = 8640000,
State = "pausedUP",
State = state,
Category = category,
SavePath = "",
Ratio = 1.0f
@@ -879,8 +896,9 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.QBittorrentTests
item.Category.Should().Be(category);
}
[Test]
public void should_get_category_from_the_label_if_the_category_is_not_available()
[TestCase("pausedUP")]
[TestCase("stoppedUP")]
public void should_get_category_from_the_label_if_the_category_is_not_available(string state)
{
const string category = "music-readarr";
GivenGlobalSeedLimits(1.0f);
@@ -892,7 +910,7 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.QBittorrentTests
Size = 1000,
Progress = 1.0,
Eta = 8640000,
State = "pausedUP",
State = state,
Label = category,
SavePath = "",
Ratio = 1.0f

View File

@@ -40,7 +40,7 @@ namespace NzbDrone.Core.Test.MetadataSource.Goodreads
[TestCase("Harry Potter and the sorcerer's stone a detailed summary", 72245296)]
[TestCase("B0192CTMYG", 61209488)]
[TestCase("9780439554930", 48517161)]
[TestCase("9780439554930", 3)]
public void successful_book_search(string title, int expected)
{
var result = Subject.Search(title);

View File

@@ -239,7 +239,7 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
// Avoid removing torrents that haven't reached the global max ratio.
// Removal also requires the torrent to be paused, in case a higher max ratio was set on the torrent itself (which is not exposed by the api).
item.CanMoveFiles = item.CanBeRemoved = torrent.State == "pausedUP" && HasReachedSeedLimit(torrent, config);
item.CanMoveFiles = item.CanBeRemoved = torrent.State is "pausedUP" or "stoppedUP" && HasReachedSeedLimit(torrent, config);
switch (torrent.State)
{
@@ -248,7 +248,8 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
item.Message = "qBittorrent is reporting an error";
break;
case "pausedDL": // torrent is paused and has NOT finished downloading
case "stoppedDL": // torrent is stopped and has NOT finished downloading
case "pausedDL": // torrent is paused and has NOT finished downloading (qBittorrent < 5)
item.Status = DownloadItemStatus.Paused;
break;
@@ -259,7 +260,8 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
item.Status = DownloadItemStatus.Queued;
break;
case "pausedUP": // torrent is paused and has finished downloading
case "pausedUP": // torrent is paused and has finished downloading (qBittorent < 5)
case "stoppedUP": // torrent is stopped and has finished downloading
case "uploading": // torrent is being seeded and data is being transferred
case "stalledUP": // torrent is being seeded, but no connection were made
case "queuedUP": // queuing is enabled and torrent is queued for upload

View File

@@ -26,8 +26,6 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
Dictionary<string, QBittorrentLabel> GetLabels(QBittorrentSettings settings);
void SetTorrentSeedingConfiguration(string hash, TorrentSeedConfiguration seedConfiguration, QBittorrentSettings settings);
void MoveTorrentToTopInQueue(string hash, QBittorrentSettings settings);
void PauseTorrent(string hash, QBittorrentSettings settings);
void ResumeTorrent(string hash, QBittorrentSettings settings);
void SetForceStart(string hash, bool enabled, QBittorrentSettings settings);
}

View File

@@ -148,7 +148,7 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
{
request.AddFormParameter("paused", false);
}
else if ((QBittorrentState)settings.InitialState == QBittorrentState.Pause)
else if ((QBittorrentState)settings.InitialState == QBittorrentState.Stop)
{
request.AddFormParameter("paused", true);
}
@@ -178,7 +178,7 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
{
request.AddFormParameter("paused", false);
}
else if ((QBittorrentState)settings.InitialState == QBittorrentState.Pause)
else if ((QBittorrentState)settings.InitialState == QBittorrentState.Stop)
{
request.AddFormParameter("paused", true);
}
@@ -214,7 +214,7 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
catch (DownloadClientException ex)
{
// if setCategory fails due to method not being found, then try older setLabel command for qBittorrent < v.3.3.5
if (ex.InnerException is HttpException && (ex.InnerException as HttpException).Response.StatusCode == HttpStatusCode.NotFound)
if (ex.InnerException is HttpException httpException && httpException.Response.StatusCode == HttpStatusCode.NotFound)
{
var setLabelRequest = BuildRequest(settings).Resource("/command/setLabel")
.Post()
@@ -257,7 +257,7 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
catch (DownloadClientException ex)
{
// qBittorrent rejects all Prio commands with 403: Forbidden if Options -> BitTorrent -> Torrent Queueing is not enabled
if (ex.InnerException is HttpException && (ex.InnerException as HttpException).Response.StatusCode == HttpStatusCode.Forbidden)
if (ex.InnerException is HttpException httpException && httpException.Response.StatusCode == HttpStatusCode.Forbidden)
{
return;
}
@@ -266,22 +266,6 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
}
}
public void PauseTorrent(string hash, QBittorrentSettings settings)
{
var request = BuildRequest(settings).Resource("/command/pause")
.Post()
.AddFormParameter("hash", hash);
ProcessRequest(request, settings);
}
public void ResumeTorrent(string hash, QBittorrentSettings settings)
{
var request = BuildRequest(settings).Resource("/command/resume")
.Post()
.AddFormParameter("hash", hash);
ProcessRequest(request, settings);
}
public void SetForceStart(string hash, bool enabled, QBittorrentSettings settings)
{
var request = BuildRequest(settings).Resource("/command/setForceStart")

View File

@@ -246,14 +246,20 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
request.AddFormParameter("category", settings.MusicCategory);
}
// Note: ForceStart is handled by separate api call
if ((QBittorrentState)settings.InitialState == QBittorrentState.Start)
// Avoid extraneous API version check if initial state is ForceStart
if ((QBittorrentState)settings.InitialState is QBittorrentState.Start or QBittorrentState.Stop)
{
request.AddFormParameter("paused", false);
}
else if ((QBittorrentState)settings.InitialState == QBittorrentState.Pause)
{
request.AddFormParameter("paused", true);
var stoppedParameterName = GetApiVersion(settings) >= new Version(2, 11, 0) ? "stopped" : "paused";
// Note: ForceStart is handled by separate api call
if ((QBittorrentState)settings.InitialState == QBittorrentState.Start)
{
request.AddFormParameter(stoppedParameterName, false);
}
else if ((QBittorrentState)settings.InitialState == QBittorrentState.Stop)
{
request.AddFormParameter(stoppedParameterName, true);
}
}
if (settings.SequentialOrder)
@@ -291,7 +297,7 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
catch (DownloadClientException ex)
{
// setShareLimits was added in api v2.0.1 so catch it case of the unlikely event that someone has api v2.0
if (ex.InnerException is HttpException && (ex.InnerException as HttpException).Response.StatusCode == HttpStatusCode.NotFound)
if (ex.InnerException is HttpException httpException && httpException.Response.StatusCode == HttpStatusCode.NotFound)
{
return;
}
@@ -313,7 +319,7 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
catch (DownloadClientException ex)
{
// qBittorrent rejects all Prio commands with 409: Conflict if Options -> BitTorrent -> Torrent Queueing is not enabled
if (ex.InnerException is HttpException && (ex.InnerException as HttpException).Response.StatusCode == HttpStatusCode.Conflict)
if (ex.InnerException is HttpException httpException && httpException.Response.StatusCode == HttpStatusCode.Conflict)
{
return;
}
@@ -322,22 +328,6 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
}
}
public void PauseTorrent(string hash, QBittorrentSettings settings)
{
var request = BuildRequest(settings).Resource("/api/v2/torrents/pause")
.Post()
.AddFormParameter("hashes", hash);
ProcessRequest(request, settings);
}
public void ResumeTorrent(string hash, QBittorrentSettings settings)
{
var request = BuildRequest(settings).Resource("/api/v2/torrents/resume")
.Post()
.AddFormParameter("hashes", hash);
ProcessRequest(request, settings);
}
public void SetForceStart(string hash, bool enabled, QBittorrentSettings settings)
{
var request = BuildRequest(settings).Resource("/api/v2/torrents/setForceStart")

View File

@@ -1,9 +1,16 @@
using NzbDrone.Core.Annotations;
namespace NzbDrone.Core.Download.Clients.QBittorrent
{
public enum QBittorrentState
{
[FieldOption(Label = "Started")]
Start = 0,
[FieldOption(Label = "Force Started")]
ForceStart = 1,
Pause = 2
[FieldOption(Label = "Stopped")]
Stop = 2
}
}

View File

@@ -642,5 +642,16 @@
"AuthForm": "النماذج (صفحة تسجيل الدخول)",
"Enabled": "ممكن",
"FailedLoadingSearchResults": "فشل تحميل نتائج البحث ، يرجى المحاولة مرة أخرى.",
"DisabledForLocalAddresses": "معطل بسبب العناوين المحلية"
"DisabledForLocalAddresses": "معطل بسبب العناوين المحلية",
"AptUpdater": "استخدم apt لتثبيت التحديث",
"CurrentlyInstalled": "مثبتة حاليا",
"DockerUpdater": "تحديث حاوية عامل الإرساء لتلقي التحديث",
"ExternalUpdater": "تم تكوين {appName} لاستخدام آلية تحديث خارجية",
"InstallLatest": "تثبيت الأحدث",
"OnLatestVersion": "تم بالفعل تثبيت أحدث إصدار من {appName}",
"Script": "النصي",
"UnmappedFiles": "المجلدات غير المعينة",
"UpdateAppDirectlyLoadError": "تعذر تحديث {appName} مباشرة ،",
"Clone": "قريب",
"BuiltIn": "مدمج"
}

View File

@@ -642,5 +642,16 @@
"AuthBasic": "Основно (изскачащ прозорец на браузъра)",
"AuthForm": "Формуляри (Страница за вход)",
"DisabledForLocalAddresses": "Забранено за местни адреси",
"Enabled": "Активирано"
"Enabled": "Активирано",
"AptUpdater": "Използвайте apt, за да инсталирате актуализацията",
"BuiltIn": "Вграден",
"CurrentlyInstalled": "Понастоящем инсталиран",
"ExternalUpdater": "{appName} е конфигуриран да използва външен механизъм за актуализация",
"Script": "Сценарий",
"UnmappedFiles": "Немапирани папки",
"UpdateAppDirectlyLoadError": "Не може да се актуализира {appName} директно,",
"Clone": "Близо",
"DockerUpdater": "актуализирайте контейнера на докера, за да получите актуализацията",
"InstallLatest": "Инсталирайте най-новите",
"OnLatestVersion": "Вече е инсталирана най-новата версия на {appName}"
}

View File

@@ -713,5 +713,16 @@
"Enabled": "Povoleno",
"ApiKey": "Klíč API",
"AuthForm": "Formuláře (přihlašovací stránka)",
"DisabledForLocalAddresses": "Zakázáno pro místní adresy"
"DisabledForLocalAddresses": "Zakázáno pro místní adresy",
"DockerUpdater": "aktualizujte kontejner dockeru, abyste aktualizaci obdrželi",
"ExternalUpdater": "{appName} je nakonfigurován pro použití externího aktualizačního mechanismu",
"FailedToFetchUpdates": "Nepodařilo se načíst aktualizace",
"OnLatestVersion": "Nejnovější verze aplikace {appName} je již nainstalována",
"Script": "Skript",
"UpdateAppDirectlyLoadError": "{appName} nelze aktualizovat přímo,",
"BuiltIn": "Vestavěný",
"InstallLatest": "Nainstalujte nejnovější",
"CurrentlyInstalled": "Aktuálně nainstalováno",
"UnmappedFiles": "Nezmapované složky",
"AptUpdater": "K instalaci aktualizace použijte apt"
}

View File

@@ -657,5 +657,16 @@
"ApiKey": "API-nøgle",
"AddedAuthorSettings": "Indstillinger for tilføjede forfattere",
"AddMissing": "Tilføj manglende",
"AddImportListExclusionHelpText": "Forhindre bog i at blive tilføjet til Readarr via Importer Lister eller Opdater Forfatter"
"AddImportListExclusionHelpText": "Forhindre bog i at blive tilføjet til Readarr via Importer Lister eller Opdater Forfatter",
"AptUpdater": "Brug apt til at installere opdateringen",
"BuiltIn": "Indbygget",
"CurrentlyInstalled": "Aktuelt installeret",
"InstallLatest": "Installer senest",
"Script": "Manuskript",
"UpdateAppDirectlyLoadError": "Kan ikke opdatere {appName} direkte,",
"Clone": "Luk",
"UnmappedFiles": "Ikke-kortlagte mapper",
"DockerUpdater": "opdater docker-containeren for at modtage opdateringen",
"ExternalUpdater": "{appName} er konfigureret til at bruge en ekstern opdateringsmekanisme",
"OnLatestVersion": "Den seneste version af {appName} er allerede installeret"
}

View File

@@ -1063,5 +1063,14 @@
"AuthenticationRequiredUsernameHelpTextWarning": "Gib einen neuen Benutzernamen ein",
"AuthenticationRequiredWarning": "Um unberechtigte Fernzugriffe zu vermeiden benötigt {appName} jetzt , dass Authentifizierung eingeschaltet ist. Du kannst Authentifizierung optional für lokale Adressen ausschalten.",
"DisabledForLocalAddresses": "Für lokale Adressen deaktiviert",
"Enabled": "Aktiviert"
"Enabled": "Aktiviert",
"BuiltIn": "Eingebaut",
"CurrentlyInstalled": "Derzeit installiert",
"InstallLatest": "Jetzt updaten",
"OnLatestVersion": "Die aktuellste Version ist bereits installiert",
"Script": "Skript",
"AptUpdater": "Verwenden Sie apt, um das Update zu installieren",
"DockerUpdater": "Aktualisieren Sie den Docker-Container, um das Update zu erhalten",
"ExternalUpdater": "{appName} wurde so konfiguriert, dass ein externer Update Mechanismus benutzt wird",
"UpdateAppDirectlyLoadError": "{appName} kann nicht direkt aktualisiert werden."
}

View File

@@ -1012,5 +1012,14 @@
"AuthenticationRequiredWarning": "Για να αποτρέψει την απομακρυσμένη πρόσβαση χωρίς έλεγχο ταυτότητας, το {appName} απαιτεί τώρα να ενεργοποιηθεί ο έλεγχος ταυτότητας. Διαμορφώστε τη μέθοδο ελέγχου ταυτότητας και τα διαπιστευτήριά σας. Μπορείτε προαιρετικά να απενεργοποιήσετε τον έλεγχο ταυτότητας από τοπικές διευθύνσεις. Ανατρέξτε στις Συχνές Ερωτήσεις για πρόσθετες πληροφορίες.",
"Enabled": "Ενεργοποιήθηκε",
"ApiKey": "Κλειδί API",
"DisabledForLocalAddresses": "Απενεργοποιήθηκε για τοπικές διευθύνσεις"
"DisabledForLocalAddresses": "Απενεργοποιήθηκε για τοπικές διευθύνσεις",
"AptUpdater": "Χρησιμοποιήστε το apt για να εγκαταστήσετε την ενημέρωση",
"BuiltIn": "Ενσωματωμένο",
"CurrentlyInstalled": "Εγκατεστημένο αυτήν τη στιγμή",
"DockerUpdater": "ενημερώστε το κοντέινερ για να λάβετε την ενημέρωση",
"OnLatestVersion": "Η τελευταία έκδοση του {appName} είναι ήδη εγκατεστημένη",
"Script": "Γραφή",
"UpdateAppDirectlyLoadError": "Δεν είναι δυνατή η απευθείας ενημέρωση του {appName},",
"ExternalUpdater": "Το {appName} έχει ρυθμιστεί να χρησιμοποιεί έναν εξωτερικό μηχανισμό ενημέρωσης",
"InstallLatest": "Εγκατάσταση πιο πρόσφατου"
}

View File

@@ -1101,5 +1101,21 @@
"AuthenticationRequiredPasswordConfirmationHelpTextWarning": "Confirma la nueva contraseña",
"AuthenticationRequiredPasswordHelpTextWarning": "Introduce una nueva contraseña",
"AuthenticationRequiredUsernameHelpTextWarning": "Introduce un nuevo usuario",
"External": "Externa"
"External": "Externa",
"AptUpdater": "Usa apt para instalar la actualización",
"BuiltIn": "Integrado",
"CurrentlyInstalled": "Actualmente instalado",
"DockerUpdater": "Actualiza el contenedor docker para recibir la actualización",
"ExternalUpdater": "{appName} está configurado para usar un mecanismo de actualización externo",
"FailedToFetchSettings": "Error al recuperar la configuración",
"Install": "Instalar",
"OnLatestVersion": "La última versión de {appName} ya está instalada",
"PreviouslyInstalled": "Previamente instalado",
"Script": "Script",
"UpdateAppDirectlyLoadError": "No se pudo actualizar {appName} directamente,",
"FailedToFetchUpdates": "Fallo al buscar las actualizaciones",
"InstallLatest": "Instala el último",
"InstallMajorVersionUpdate": "Instalar actualización",
"InstallMajorVersionUpdateMessage": "Esta actualización instalará una nueva versión principal y podría no ser compatible con tu sistema. ¿Estás seguro que quieres instalar esta actualización?",
"InstallMajorVersionUpdateMessageLink": "Por favor revisa [{domain}]({url}) para más información."
}

View File

@@ -1029,5 +1029,16 @@
"External": "Ulkoinen",
"PasswordConfirmation": "Salasanan vahvistus",
"DisabledForLocalAddresses": "Ei käytössä paikallisille osoitteille",
"ReadarrSupportsMultipleListsForImportingBooksAndAuthorsIntoTheDatabase": "{appName} tukee useita listoja, joilta sarjoja voidaan tuoda tietokantaan."
"ReadarrSupportsMultipleListsForImportingBooksAndAuthorsIntoTheDatabase": "{appName} tukee useita listoja, joilta sarjoja voidaan tuoda tietokantaan.",
"BuiltIn": "Sisäänrakennettu",
"CurrentlyInstalled": "Nykyinen asennettu versio",
"DockerUpdater": "Hanki päivitys päivittämällä Docker-säiliö",
"ExternalUpdater": "{appName} on määritetty käyttämään ulkoista päivitysratkaisua.",
"FailedToFetchUpdates": "Päivitysten nouto epäonnistui",
"InstallLatest": "Asenna uusin",
"OnLatestVersion": "Uusin {appName}-versio on jo asennettu",
"PreviouslyInstalled": "Edellinen asennettu versio",
"Script": "Skripti",
"UpdateAppDirectlyLoadError": "{appName}ia ei voida päivittää suoraan,",
"AptUpdater": "Asenna päivitys APT-työkalun avulla"
}

View File

@@ -1101,5 +1101,21 @@
"Iso639-3": "Codes de langage ISO 639-3, ou 'null', séparés par des virgules",
"SpecificBook": "Livre spécifique",
"SkipSecondarySeriesBooks": "Sauter les livres de séries secondaires",
"SkipPartBooksAndSets": "Livres et coffrets \"Skip part\""
"SkipPartBooksAndSets": "Livres et coffrets \"Skip part\"",
"AptUpdater": "Utiliser apt pour installer la mise à jour",
"BuiltIn": "Intégré",
"CurrentlyInstalled": "Actuellement installé",
"DockerUpdater": "Mettez à jour le conteneur Docker pour recevoir la mise à jour",
"ExternalUpdater": "{appName} est configuré pour utiliser un mécanisme de mise à jour externe",
"FailedToFetchSettings": "Échec de la récupération des paramètres",
"FailedToFetchUpdates": "Échec de la récupération des mises à jour",
"Install": "Installer",
"InstallLatest": "Installer la dernière",
"InstallMajorVersionUpdate": "Installer la mise à jour",
"InstallMajorVersionUpdateMessageLink": "Veuillez consulter [{domain}]({url}) pour plus d'informations.",
"OnLatestVersion": "La dernière version de {appName} est déjà installée",
"PreviouslyInstalled": "Installé précédemment",
"Script": "Script",
"UpdateAppDirectlyLoadError": "Impossible de mettre à jour directement {appName},",
"InstallMajorVersionUpdateMessage": "Cette mise à jour installera une nouvelle version majeure et pourrait ne pas être compatible avec votre système. Êtes-vous sûr de vouloir installer cette mise à jour ?"
}

View File

@@ -676,5 +676,16 @@
"AuthenticationRequiredHelpText": "הגדר עבור אילו קריאות נדרש אימות. עדיף להשאיר את ברירת המחדל.",
"AuthenticationRequiredWarning": "בכדי למנוע גישה מרחוק ללא אימות, {appName} דורש הגדרת אימות.\nהגדר את הפרטים ושיטת האימות. ישנה אפשרות לדלג על אימות מהרשת הביתית שלך. \nבמידת הצורך יש לפנות אל שו״ת למידע נוסף.",
"DisabledForLocalAddresses": "מושבת לכתובות מקומיות",
"Enabled": "מופעל"
"Enabled": "מופעל",
"AptUpdater": "השתמש ב- apt כדי להתקין את העדכון",
"BuiltIn": "נִבנָה בְּ",
"CurrentlyInstalled": "מותקן כעת",
"DockerUpdater": "עדכן את מיכל העגינה לקבל את העדכון",
"ExternalUpdater": "{appName} מוגדר להשתמש במנגנון עדכון חיצוני",
"InstallLatest": "התקן את האחרונה",
"OnLatestVersion": "הגרסה האחרונה של {appName} כבר מותקנת",
"Script": "תַסרִיט",
"UnmappedFiles": "תיקיות לא ממופות",
"UpdateAppDirectlyLoadError": "לא ניתן לעדכן את {appName} ישירות,",
"Clone": "סגור"
}

View File

@@ -640,5 +640,15 @@
"AuthBasic": "बेसिक (ब्राउज़र पॉपअप)",
"AuthForm": "प्रपत्र (लॉग इन पेज)",
"DisabledForLocalAddresses": "स्थानीय पते के लिए अक्षम",
"Enabled": "सक्रिय"
"Enabled": "सक्रिय",
"UnmappedFiles": "बिना मोड़े हुए फोल्डर",
"AptUpdater": "अद्यतन स्थापित करने के लिए उपयुक्त का उपयोग करें",
"BuiltIn": "में निर्मित",
"CurrentlyInstalled": "वर्तमान में स्थापित है",
"DockerUpdater": "अपडेट प्राप्त करने के लिए docker कंटेनर को अपडेट करें",
"InstallLatest": "नवीनतम स्थापित करें",
"OnLatestVersion": "रेडर का नवीनतम संस्करण पहले से ही स्थापित है",
"Script": "लिपि",
"UpdateAppDirectlyLoadError": "सीधे {appName} अद्यतन करने में असमर्थ,",
"Clone": "बंद करे"
}

View File

@@ -224,5 +224,10 @@
"AuthenticationRequired": "Potrebna Autentikacija",
"AuthenticationRequiredPasswordConfirmationHelpTextWarning": "Potvrdi novu lozinku",
"AuthenticationRequiredPasswordHelpTextWarning": "Unesi novu lozinku",
"AuthenticationRequiredUsernameHelpTextWarning": "Unesi novo korisničko ime"
"AuthenticationRequiredUsernameHelpTextWarning": "Unesi novo korisničko ime",
"Reason": "Sezona",
"DeleteSelectedBookFilesMessageText": "Jeste li sigurni da želite obrisati ovaj profil odgode?",
"Clone": "Zatvori",
"BuiltIn": "Ugrađeno",
"AptUpdater": "Koristi apt kako bi instalirao ažuriranje"
}

View File

@@ -1074,5 +1074,16 @@
"External": "Külső",
"PasswordConfirmation": "Jelszó megerősítése",
"AuthBasic": "Alap (böngésző előugró ablak)",
"Enabled": "Engedélyezés"
"Enabled": "Engedélyezés",
"AptUpdater": "A frissítés telepítéséhez használja az apt-t",
"BuiltIn": "Beépített",
"CurrentlyInstalled": "Jelenleg telepítve",
"DockerUpdater": "Frissítse a docker-tárolót a frissítés fogadásához",
"ExternalUpdater": "A {appName} egy külső frissítési mechanizmus használatára van konfigurálva",
"FailedToFetchUpdates": "Nem sikerült lekérni a frissítéseket",
"InstallLatest": "Legfrissebb telepítése",
"OnLatestVersion": "A {appName} legújabb verziója már telepítva van",
"PreviouslyInstalled": "Korábban telepítve",
"Script": "Szkript",
"UpdateAppDirectlyLoadError": "Nem lehetséges közvetlenül frissíteni a {appName}-t"
}

View File

@@ -102,5 +102,9 @@
"AuthenticationRequiredPasswordHelpTextWarning": "Masukkan sandi baru",
"AuthenticationRequiredUsernameHelpTextWarning": "Masukkan nama pengguna baru",
"AuthenticationRequiredWarning": "Untuk mencegah akses jarak jauh tanpa autentikasi, {appName} kini mewajibkan pengaktifkan autentikasi. Kamu dapat menonaktifkan autentikasi dari jaringan lokal.",
"Enabled": "Aktif"
"Enabled": "Aktif",
"AptUpdater": "Gunakan apt untuk memasang pembaruan",
"Clone": "Tutup",
"CurrentlyInstalled": "Saat Ini Terpasang",
"EnableSSL": "Aktifkan RSS"
}

View File

@@ -641,5 +641,16 @@
"DisabledForLocalAddresses": "Óvirkt vegna heimilisfanga",
"Enabled": "Virkt",
"ApiKey": "API lykill",
"AuthBasic": "Grunn (sprettiglugga vafra)"
"AuthBasic": "Grunn (sprettiglugga vafra)",
"Clone": "Lokaðu",
"AptUpdater": "Notaðu apt til að setja uppfærsluna upp",
"BuiltIn": "Innbyggð",
"CurrentlyInstalled": "Nú sett upp",
"DockerUpdater": "uppfærðu bryggjugáminn til að fá uppfærsluna",
"ExternalUpdater": "{appName} er stilltur til að nota ytri uppfærslu",
"InstallLatest": "Settu upp nýjustu",
"OnLatestVersion": "Nýjasta útgáfan af {appName} er þegar uppsett",
"Script": "Handrit",
"UnmappedFiles": "Ókortlagðar möppur",
"UpdateAppDirectlyLoadError": "Ekki er hægt að uppfæra {appName} beint,"
}

View File

@@ -900,5 +900,16 @@
"Fixed": "Fissato",
"MusicBrainzTrackID": "ID Libro MusicBrainz",
"CountImportListsSelected": "{selectedCount} autore/i selezionato/i",
"DownloadClientDelugeSettingsDirectory": "Cartella Download"
"DownloadClientDelugeSettingsDirectory": "Cartella Download",
"UnmappedFiles": "Cartelle Non Mappate",
"AptUpdater": "Usa apt per installare l'aggiornamento",
"BuiltIn": "Incluso",
"CurrentlyInstalled": "Attualmente Installato",
"DockerUpdater": "Aggiorna il container di docker per ricevere l'aggiornamento",
"ExternalUpdater": "{appName} è configurato per utilizzare un meccanismo di aggiornamento esterno",
"InstallLatest": "Installa il più recente",
"OnLatestVersion": "L'ultima versione di {appName} è già installata",
"PreviouslyInstalled": "Precedentemente Installato",
"Script": "Script",
"UpdateAppDirectlyLoadError": "Impossibile aggiornare {appName} direttamente,"
}

View File

@@ -640,5 +640,16 @@
"Enabled": "有効",
"ApiKey": "APIキー",
"AuthBasic": "基本(ブラウザポップアップ)",
"DisabledForLocalAddresses": "ローカルアドレスでは無効"
"DisabledForLocalAddresses": "ローカルアドレスでは無効",
"Clone": "閉じる",
"InstallLatest": "最新のインストール",
"Script": "脚本",
"UnmappedFiles": "マップされていないフォルダ",
"UpdateAppDirectlyLoadError": "{appName}を直接更新できません。",
"AptUpdater": "aptを使用してアップデートをインストールします",
"BuiltIn": "ビルトイン",
"CurrentlyInstalled": "現在インストール中",
"DockerUpdater": "Dockerコンテナを更新して、更新を受信します",
"ExternalUpdater": "{appName}は、外部更新メカニズムを使用するように構成されています",
"OnLatestVersion": "{appName}の最新バージョンはすでにインストールされています"
}

View File

@@ -631,5 +631,13 @@
"AuthBasic": "기본 (브라우저 팝업)",
"AuthForm": "양식 (로그인 페이지)",
"DisabledForLocalAddresses": "로컬 주소에 대해 비활성화됨",
"Enabled": "활성화"
"Enabled": "활성화",
"Clone": "닫기",
"AptUpdater": "apt를 사용하여 업데이트 설치",
"BuiltIn": "내장",
"CurrentlyInstalled": "현재 설치됨",
"DockerUpdater": "Docker 컨테이너를 업데이트하여 업데이트를 받으십시오.",
"ExternalUpdater": "{appName}는 외부 업데이트 메커니즘을 사용하도록 구성됩니다.",
"OnLatestVersion": "최신 버전의 {appName}가 이미 설치되어 있습니다.",
"UpdateAppDirectlyLoadError": "{appName}를 직접 업데이트 할 수 없습니다."
}

View File

@@ -198,5 +198,9 @@
"AuthBasic": "Grunnleggende (nettleser -popup)",
"UnableToAddANewImportListExclusionPleaseTryAgain": "Ikke mulig å legge til ny betingelse, vennligst prøv igjen",
"UnableToAddANewMetadataProfilePleaseTryAgain": "Ikke mulig å legge til ny betingelse, vennligst prøv igjen",
"UnableToAddANewQualityProfilePleaseTryAgain": "Ikke mulig å legge til ny betingelse, vennligst prøv igjen"
"UnableToAddANewQualityProfilePleaseTryAgain": "Ikke mulig å legge til ny betingelse, vennligst prøv igjen",
"Reason": "Sesong",
"Clone": "Lukk",
"AptUpdater": "Bruk apt til å installere oppdateringen",
"BuiltIn": "Bygget inn"
}

View File

@@ -757,5 +757,15 @@
"ChangeCategoryMultipleHint": "Wijzigt downloads naar de 'Post-Import Categorie' van Downloadclient",
"BypassIfAboveCustomFormatScore": "Omzeilen indien boven aangepaste opmaak score",
"BypassIfAboveCustomFormatScoreHelpText": "Schakel omleiding in als de release een score heeft die hoger is dan de geconfigureerde minimale aangepaste formaatscore",
"MinimumCustomFormatScoreHelpText": "Minimumscore aangepast formaat vereist om vertraging voor het voorkeursprotocol te omzeilen"
"MinimumCustomFormatScoreHelpText": "Minimumscore aangepast formaat vereist om vertraging voor het voorkeursprotocol te omzeilen",
"UnmappedFiles": "Niet-toegewezen Mappen",
"AptUpdater": "Gebruik apt om de update te installeren",
"BuiltIn": "Ingebouwd",
"DockerUpdater": "Update de docker container om de update te ontvangen",
"InstallLatest": "Installeer Nieuwste Versie",
"OnLatestVersion": "De nieuwste versie van {appName} is al geïnstalleerd",
"Script": "Script",
"UpdateAppDirectlyLoadError": "Kan {appName} niet rechtstreeks updaten,",
"CurrentlyInstalled": "Momenteel Geïnstalleerd",
"ExternalUpdater": "{appName} is geconfigureerd om een extern update mechanisme te gebruiken"
}

View File

@@ -707,5 +707,16 @@
"Label": "Etykieta",
"CatalogNumber": "numer katalogowy",
"MetadataProfiles": "profil metadanych",
"Publisher": "Wydawca"
"Publisher": "Wydawca",
"Clone": "Zamknij",
"AptUpdater": "Użyj apt, aby zainstalować aktualizację",
"BuiltIn": "Wbudowany",
"CurrentlyInstalled": "Aktualnie zainstalowane",
"ExternalUpdater": "{appName} jest skonfigurowany do korzystania z zewnętrznego mechanizmu aktualizacji",
"InstallLatest": "Zainstaluj najnowsze",
"OnLatestVersion": "Najnowsza wersja {appName} jest już zainstalowana",
"Script": "Scenariusz",
"UnmappedFiles": "Niezmapowane foldery",
"UpdateAppDirectlyLoadError": "Nie można bezpośrednio zaktualizować {appName},",
"DockerUpdater": "zaktualizuj kontener Dockera, aby otrzymać aktualizację"
}

View File

@@ -955,5 +955,14 @@
"AuthenticationRequiredUsernameHelpTextWarning": "Insira um novo Nome de Usuário",
"AuthenticationRequiredWarning": "Para evitar o acesso remoto sem autenticação, {appName} agora exige que a autenticação esteja habilitada. Opcionalmente, você pode desabilitar a autenticação de endereços locais.",
"DisabledForLocalAddresses": "Desativado para endereços locais",
"Enabled": "Ativado"
"Enabled": "Ativado",
"AptUpdater": "Utilize o apt para instalar a atualização",
"BuiltIn": "Incorporado",
"CurrentlyInstalled": "Atualmente instalado",
"InstallLatest": "Instalar o mais recente",
"OnLatestVersion": "A versão mais recente do {appName} já está instalada",
"DockerUpdater": "atualize o contentor do Docker para receber a atualização",
"ExternalUpdater": "O {appName} está definido para usar um mecanismo de atualização externo",
"Script": "Script",
"UpdateAppDirectlyLoadError": "Não foi possível atualizar o {appName} diretamente,"
}

View File

@@ -1101,5 +1101,21 @@
"Enabled": "Habilitado",
"External": "Externo",
"ApiKey": "Chave API",
"PasswordConfirmation": "Confirmação Da Senha"
"PasswordConfirmation": "Confirmação Da Senha",
"AptUpdater": "Usar apt para instalar atualizações",
"BuiltIn": "Embutido",
"Install": "Instalar",
"InstallLatest": "Instalar o mais recente",
"InstallMajorVersionUpdate": "Instalar Atualização",
"OnLatestVersion": "A versão mais recente do {appName} já está instalada",
"PreviouslyInstalled": "Instalado anteriormente",
"Script": "Script",
"UpdateAppDirectlyLoadError": "Incapaz de atualizar o {appName} diretamente,",
"CurrentlyInstalled": "Atualmente instalado",
"DockerUpdater": "Atualize o contêiner docker para receber a atualização",
"ExternalUpdater": "O {appName} está configurado para usar um mecanismo de atualização externo",
"FailedToFetchSettings": "Falha ao buscar configurações",
"FailedToFetchUpdates": "Falha ao buscar atualizações",
"InstallMajorVersionUpdateMessage": "Esta atualização instalará uma nova versão principal e pode não ser compatível com o seu sistema. Tem certeza de que deseja instalar esta atualização?",
"InstallMajorVersionUpdateMessageLink": "Verifique [{domain}]({url}) para obter mais informações."
}

View File

@@ -122,8 +122,8 @@
"Clear": "Șterge",
"ClickToChangeQuality": "Faceți clic pentru a schimba calitatea",
"ClientPriority": "Prioritate client",
"CloneIndexer": "Clonă Indexer",
"CloneProfile": "Clonați profil",
"CloneIndexer": "Clonează Indexer",
"CloneProfile": "Clonează Profil",
"CopyUsingHardlinksHelpTextWarning": "Ocazional, blocarea fișierelor poate împiedica redenumirea fișierelor care sunt însămânțate. Puteți dezactiva temporar însămânțarea și puteți utiliza funcția de redenumire a lui {appName} ca soluție.",
"CreateEmptyAuthorFoldersHelpText": "Creați directoare de film lipsă în timpul scanării discului",
"CreateGroup": "Creați un grup",
@@ -548,7 +548,7 @@
"MoveFiles": "Mută Fișiere",
"MinimumCustomFormatScore": "Scor minim format personalizat",
"CustomFormatScore": "Scorul formatului personalizat",
"CloneCustomFormat": "Clonați format personalizat",
"CloneCustomFormat": "Clonează format personalizat",
"Conditions": "Condiții",
"DeleteCustomFormat": "Ștergeți formatul personalizat",
"DeleteCustomFormatMessageText": "Sigur doriți să ștergeți indexatorul „{0}”?",
@@ -606,7 +606,7 @@
"ApplicationURL": "URL aplicație",
"ApplyChanges": "Aplicați modificări",
"AutomaticAdd": "Adăugare automată",
"CloneCondition": "Clonați condiție",
"CloneCondition": "Clonează condiție",
"InstanceName": "Nume instanță",
"Publisher": "Editor",
"Implementation": "Implementarea",
@@ -660,5 +660,16 @@
"AuthenticationRequiredUsernameHelpTextWarning": "Introduceți un nou nume de utilizator",
"DisabledForLocalAddresses": "Dezactivat pentru adresele locale",
"ApiKey": "Cheie API",
"Enabled": "Activat"
"Enabled": "Activat",
"Clone": "Clonează",
"UnmappedFiles": "Foldere nemapate",
"AptUpdater": "Utilizați apt pentru a instala actualizarea",
"BuiltIn": "Incorporat",
"CurrentlyInstalled": "În prezent instalat",
"DockerUpdater": "Actualizați containerul Docker pentru a primi actualizarea",
"ExternalUpdater": "{appName} este configurat pentru a utiliza un mecanism de actualizare extern",
"InstallLatest": "Instalați cel mai recent",
"OnLatestVersion": "Cea mai recentă versiune a {appName} este deja instalată",
"Script": "Script",
"UpdateAppDirectlyLoadError": "Imposibil de actualizat direct {appName},"
}

View File

@@ -860,5 +860,22 @@
"Books": "Книга",
"LogRotation": "Ротация журналов",
"FilterAnalyticsEvents": "Фильтровать события аналитики",
"FilterSentryEventsHelpText": "Фильтровать известные события ошибок пользователя, чтобы они не отправлялись в виде аналитики."
"FilterSentryEventsHelpText": "Фильтровать известные события ошибок пользователя, чтобы они не отправлялись в виде аналитики.",
"UnmappedFiles": "Несопоставленные папки",
"BuiltIn": "Встроенный",
"CurrentlyInstalled": "Установлено",
"DockerUpdater": "Обновите контейнер Docker, чтобы получить обновление",
"ExternalUpdater": "{appName} настроен на использование внешнего механизма обновления",
"FailedToFetchSettings": "Не удалось загрузить настройки",
"Install": "Установить",
"InstallLatest": "Установить последнюю версию",
"OnLatestVersion": "Последняя версия {appName} уже установлена",
"PreviouslyInstalled": "Ранее установленный",
"Script": "Скрипт",
"AptUpdater": "Использовать apt для установки обновления",
"FailedToFetchUpdates": "Не удалось загрузить обновления",
"InstallMajorVersionUpdate": "Установить обновление",
"InstallMajorVersionUpdateMessage": "Это обновление установит новую версию, которая может не поддерживаться вашей системой. Вы уверены, что хотите установить это обновление?",
"InstallMajorVersionUpdateMessageLink": "Пожалуйста, проверьте [{domain}]({url}) для получения дополнительной информации.",
"UpdateAppDirectlyLoadError": "Невозможно обновить {appName} напрямую,"
}

View File

@@ -873,5 +873,15 @@
"DisabledForLocalAddresses": "Inaktiverad för lokala adresser",
"Enabled": "Aktiverad",
"ApiKey": "API Nyckel",
"AuthForm": "Blanketter (inloggningssida)"
"AuthForm": "Blanketter (inloggningssida)",
"Clone": "Avsluta",
"AptUpdater": "Använd apt för att installera uppdateringen",
"BuiltIn": "Inbyggd",
"CurrentlyInstalled": "För närvarande installerad",
"DockerUpdater": "uppdatera dockerbehållaren för att ta emot uppdateringen",
"ExternalUpdater": "{appName} är konfigurerad för att använda en extern uppdateringsmekanism",
"InstallLatest": "Installera senaste",
"OnLatestVersion": "Den senaste versionen av {appName} är redan installerad",
"Script": "Skript",
"UpdateAppDirectlyLoadError": "Det går inte att uppdatera {appName} direkt,"
}

View File

@@ -642,5 +642,16 @@
"DisabledForLocalAddresses": "ปิดใช้งานสำหรับที่อยู่ท้องถิ่น",
"Enabled": "เปิดใช้งาน",
"AuthBasic": "พื้นฐาน (เบราว์เซอร์ป๊อปอัพ)",
"AuthForm": "แบบฟอร์ม (หน้าเข้าสู่ระบบ)"
"AuthForm": "แบบฟอร์ม (หน้าเข้าสู่ระบบ)",
"BuiltIn": "สร้างขึ้นใน",
"Clone": "ปิด",
"CurrentlyInstalled": "ติดตั้งแล้ว",
"DockerUpdater": "อัปเดตคอนเทนเนอร์นักเทียบท่าเพื่อรับการอัปเดต",
"ExternalUpdater": "{appName} ถูกกำหนดค่าให้ใช้กลไกการอัพเดตภายนอก",
"InstallLatest": "ติดตั้งล่าสุด",
"Script": "สคริปต์",
"UpdateAppDirectlyLoadError": "ไม่สามารถอัปเดต {appName} ได้โดยตรง",
"UnmappedFiles": "โฟลเดอร์ที่ไม่ได้แมป",
"AptUpdater": "ใช้ apt เพื่อติดตั้งการอัปเดต",
"OnLatestVersion": "มีการติดตั้ง {appName} เวอร์ชันล่าสุดแล้ว"
}

View File

@@ -824,5 +824,25 @@
"AuthenticationRequiredPasswordHelpTextWarning": "Yeni şifre girin",
"AuthenticationRequiredUsernameHelpTextWarning": "Yeni kullanıcı adınızı girin",
"AuthenticationRequiredWarning": "Kimlik doğrulaması olmadan uzaktan erişimi engellemek için, {appName}'da artık kimlik doğrulamanın etkinleştirilmesini gerektiriyor. İsteğe bağlı olarak yerel adresler için kimlik doğrulamayı devre dışı bırakabilirsiniz.",
"DeleteSelected": "Seçileni Sil"
"DeleteSelected": "Seçileni Sil",
"UnmappedFiles": "Eşlenmemiş Klasörler",
"Series": "Diziler",
"SmartReplace": "Akıllı Değiştir",
"DashOrSpaceDashDependingOnName": "İsme bağlı olarak Dash veya Space Dash",
"CatalogNumber": "katalog numarası",
"AptUpdater": "Güncellemeyi yüklemek için apt kullanın",
"BuiltIn": "Dahili",
"CurrentlyInstalled": "Şu anda Yüklü",
"ExternalUpdater": "{appName}, harici bir güncelleme mekanizması kullanacak şekilde yapılandırıldı",
"FailedToFetchUpdates": "Güncellemeler getirilemedi",
"PreviouslyInstalled": "Önceden Yüklenmiş",
"Script": "Hazır Metin",
"UpdateAppDirectlyLoadError": "{appName} doğrudan güncellenemiyor,",
"DockerUpdater": "güncellemeyi almak için docker konteynerini güncelleyin",
"Install": "Kur",
"InstallLatest": "En Sonu Yükle",
"InstallMajorVersionUpdate": "Güncellemeyi Kur",
"InstallMajorVersionUpdateMessage": "Bu güncelleştirme yeni bir ana sürüm yükleyecek ve sisteminizle uyumlu olmayabilir. Bu güncelleştirmeyi yüklemek istediğinizden emin misiniz?",
"InstallMajorVersionUpdateMessageLink": "Daha fazla bilgi için lütfen [{domain}]({url}) adresini kontrol edin.",
"OnLatestVersion": "{appName}'ın en son sürümü zaten kurulu"
}

View File

@@ -745,5 +745,15 @@
"CountDownloadClientsSelected": "Вибрано {count} клієнтів завантажувача",
"ReleaseProfiles": "профіль релізу",
"MinimumCustomFormatScoreHelpText": "Мінімальна оцінка користувацького формату, необхідна для обходу затримки для обраного протоколу",
"BypassIfAboveCustomFormatScore": "Пропустити, якщо перевищено оцінку користувацького формату"
"BypassIfAboveCustomFormatScore": "Пропустити, якщо перевищено оцінку користувацького формату",
"UnmappedFiles": "Невідповідні папки",
"AptUpdater": "Використовуйте apt для інсталяції оновлення",
"BuiltIn": "Вбудований",
"ExternalUpdater": "{appName} налаштовано на використання зовнішнього механізму оновлення",
"InstallLatest": "Встановити останній",
"Script": "Сценарій",
"UpdateAppDirectlyLoadError": "Неможливо оновити {appName} безпосередньо,",
"CurrentlyInstalled": "В даний час встановлено",
"DockerUpdater": "Оновіть контейнер docker, щоб отримати оновлення",
"OnLatestVersion": "Остання версія {appName} вже встановлена"
}

View File

@@ -644,5 +644,18 @@
"AuthBasic": "Cơ bản (Cửa sổ bật lên trình duyệt)",
"AuthForm": "Biểu mẫu (Trang đăng nhập)",
"DisabledForLocalAddresses": "Bị vô hiệu hóa đối với địa chỉ địa phương",
"Enabled": "Đã bật"
"Enabled": "Đã bật",
"Clone": "Đóng",
"UseSSL": "Dùng SSL",
"UnmappedFiles": "Thư mục chưa được ánh xạ",
"BuiltIn": "Được xây dựng trong",
"CurrentlyInstalled": "Mới cài đặt",
"DockerUpdater": "cập nhật vùng chứa docker để nhận bản cập nhật",
"InstallLatest": "Cài đặt mới nhất",
"OnLatestVersion": "Phiên bản mới nhất của {appName} đã được cài đặt",
"Script": "Kịch bản",
"UpdateAppDirectlyLoadError": "Không thể cập nhật {appName} trực tiếp,",
"AptUpdater": "Sử dụng apt để cài đặt bản cập nhật",
"ExternalUpdater": "{appName} được định cấu hình để sử dụng cơ chế cập nhật bên ngoài",
"WhySearchesCouldBeFailing": "Nhấp vào đây để tìm hiểu lý do tại sao tìm kiếm thất bại"
}

View File

@@ -1101,5 +1101,20 @@
"SelectIndexerFlags": "选择索引器标志",
"SetIndexerFlags": "设置索引器标志",
"LabelIsRequired": "需要标签",
"NotificationsSettingsUpdateMapPathsFromHelpText": "{appName} 路径,当 {serviceName} 与 {appName} 对资源库路径的识别不一致时,可以使用此设置修改系列路径(需要`更新资源库`"
"NotificationsSettingsUpdateMapPathsFromHelpText": "{appName} 路径,当 {serviceName} 与 {appName} 对资源库路径的识别不一致时,可以使用此设置修改系列路径(需要`更新资源库`",
"AptUpdater": "使用apt安装更新",
"BuiltIn": "内置的",
"CurrentlyInstalled": "已安装",
"ExternalUpdater": "{appName}配置为使用外部更新机制",
"FailedToFetchUpdates": "获取更新失败",
"OnLatestVersion": "已安装最新版的{appName}",
"Script": "脚本",
"DockerUpdater": "更新Docker容器以更新应用",
"Install": "安装",
"InstallLatest": "安装最新版",
"InstallMajorVersionUpdate": "安装更新",
"InstallMajorVersionUpdateMessage": "此更新将安装新的主要版本,这可能与您的系统不兼容。您确定要安装此更新吗?",
"InstallMajorVersionUpdateMessageLink": "请查看 [{domain}]({url}) 以获取更多信息。",
"PreviouslyInstalled": "上次安装",
"UpdateAppDirectlyLoadError": "无法直接更新{appName}"
}

View File

@@ -1,6 +1,8 @@
using System;
using System.Collections.Generic;
using System.Linq;
using NzbDrone.Common.Crypto;
using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Common.Extensions;
namespace Readarr.Http.Frontend.Mappers
@@ -28,6 +30,11 @@ namespace Readarr.Http.Frontend.Mappers
return resourceUrl;
}
if (!RuntimeInfo.IsProduction)
{
return resourceUrl + "?t=" + DateTime.UtcNow.Ticks;
}
var mapper = _diskMappers.Single(m => m.CanHandle(resourceUrl));
var pathToFile = mapper.Map(resourceUrl);
var hash = _hashProvider.ComputeMd5(pathToFile).ToBase64();