Compare commits

...

35 Commits

Author SHA1 Message Date
Qstick
dc3fa51d88 Fixed: Prevent endless loop when calling IndexerUrls for Newznab
Fixes #982
2022-05-01 21:01:51 -05:00
Servarr
88ddb373cc Automated API Docs update 2022-05-01 17:58:09 -05:00
Qstick
895c7c200b Fixed: Default List for Cardigann LegacyLinks 2022-05-01 17:53:10 -05:00
Qstick
4002cb764b New: Auto map known legacy BaseUrls for non-Cardigann 2022-05-01 16:41:48 -05:00
bakerboy448
2820ef9375 Fixed: (BTN) Move to HTTPS
Fixes #979
2022-05-01 15:41:55 -05:00
David Newhall
70fd9b4e30 Typo for myanonamouse. 2022-04-30 19:49:39 -05:00
Weblate
f9bd842d41 Translated using Weblate (Chinese (Simplified) (zh_CN))
Currently translated at 100.0% (446 of 446 strings)

Translated using Weblate (Dutch)

Currently translated at 91.9% (410 of 446 strings)

Translated using Weblate (Dutch)

Currently translated at 91.4% (408 of 446 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 15.2% (68 of 446 strings)

Co-authored-by: M1C <webnar@gmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: lhquark <lhquark@gmail.com>
Co-authored-by: marcosteam <wdy71608161@gmail.com>
Co-authored-by: minermartijn <minermartijn@gmail.com>
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/nl/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/zh_CN/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/zh_Hans/
Translation: Servarr/Prowlarr
2022-04-24 18:30:23 -05:00
bakerboy448
9d3ee4af6d Fixed: (MoreThanTV) Better Response Cleansing
Fixes #928
2022-04-18 19:07:51 -05:00
Qstick
20cc6e3bfb New: SceneHD Indexer 2022-04-16 17:44:59 -05:00
Servarr
d11e043270 Automated API Docs update 2022-04-16 16:17:18 -05:00
Weblate
71e42dafa7 Translated using Weblate (Chinese (Simplified))
Currently translated at 9.6% (43 of 446 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (446 of 446 strings)

Translated using Weblate (French)

Currently translated at 99.7% (445 of 446 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (446 of 446 strings)

Translated using Weblate (Ukrainian)

Currently translated at 16.1% (72 of 446 strings)

Translated using Weblate (Ukrainian)

Currently translated at 16.1% (72 of 446 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 2.9% (13 of 446 strings)

Translated using Weblate (Chinese (Simplified) (zh_CN))

Currently translated at 100.0% (446 of 446 strings)

Translated using Weblate (Arabic)

Currently translated at 74.6% (333 of 446 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (446 of 446 strings)

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (446 of 446 strings)

Translated using Weblate (Vietnamese)

Currently translated at 74.6% (333 of 446 strings)

Translated using Weblate (Turkish)

Currently translated at 74.4% (332 of 446 strings)

Translated using Weblate (Thai)

Currently translated at 74.6% (333 of 446 strings)

Translated using Weblate (Swedish)

Currently translated at 91.2% (407 of 446 strings)

Translated using Weblate (Russian)

Currently translated at 75.5% (337 of 446 strings)

Translated using Weblate (Romanian)

Currently translated at 74.4% (332 of 446 strings)

Translated using Weblate (Portuguese)

Currently translated at 80.7% (360 of 446 strings)

Translated using Weblate (Polish)

Currently translated at 74.6% (333 of 446 strings)

Translated using Weblate (Dutch)

Currently translated at 91.4% (408 of 446 strings)

Translated using Weblate (Korean)

Currently translated at 74.6% (333 of 446 strings)

Translated using Weblate (Japanese)

Currently translated at 74.6% (333 of 446 strings)

Translated using Weblate (Italian)

Currently translated at 78.4% (350 of 446 strings)

Translated using Weblate (Icelandic)

Currently translated at 74.6% (333 of 446 strings)

Translated using Weblate (Hungarian)

Currently translated at 100.0% (446 of 446 strings)

Translated using Weblate (Hungarian)

Currently translated at 100.0% (446 of 446 strings)

Translated using Weblate (Hindi)

Currently translated at 74.6% (333 of 446 strings)

Translated using Weblate (Hebrew)

Currently translated at 74.6% (333 of 446 strings)

Translated using Weblate (French)

Currently translated at 96.6% (431 of 446 strings)

Translated using Weblate (Finnish)

Currently translated at 100.0% (446 of 446 strings)

Translated using Weblate (Spanish)

Currently translated at 80.7% (360 of 446 strings)

Translated using Weblate (Spanish)

Currently translated at 80.7% (360 of 446 strings)

Translated using Weblate (Greek)

Currently translated at 74.4% (332 of 446 strings)

Translated using Weblate (German)

Currently translated at 97.9% (437 of 446 strings)

Translated using Weblate (Danish)

Currently translated at 74.4% (332 of 446 strings)

Translated using Weblate (Czech)

Currently translated at 74.6% (333 of 446 strings)

Translated using Weblate (Bulgarian)

Currently translated at 69.7% (311 of 446 strings)

Translated using Weblate (Chinese (Simplified) (zh_CN))

Currently translated at 99.7% (445 of 446 strings)

Translated using Weblate (Chinese (Simplified) (zh_CN))

Currently translated at 99.7% (445 of 446 strings)

Translated using Weblate (Chinese (Simplified) (zh_CN))

Currently translated at 99.7% (445 of 446 strings)

Co-authored-by: Ana <phampyk@gmail.com>
Co-authored-by: Anonymous <noreply@weblate.org>
Co-authored-by: Csaba <csab0825@gmail.com>
Co-authored-by: Havok Dan <havokdan@yahoo.com.br>
Co-authored-by: Oskari Lavinto <olavinto@protonmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: andrey4korop <andrey999@i.ua>
Co-authored-by: jianjam <jianjam@qq.com>
Co-authored-by: killsover <w904202822@163.com>
Co-authored-by: neoestremi <remidu34070@hotmail.fr>
Co-authored-by: 破晓天 <284062404@qq.com>
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/ar/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/bg/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/cs/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/da/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/de/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/el/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/es/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/fi/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/fr/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/he/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/hi/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/hu/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/is/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/it/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/ja/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/ko/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/nl/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/pl/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/pt/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/pt_BR/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/ro/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/ru/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/sv/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/th/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/tr/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/uk/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/vi/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/zh_CN/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/zh_Hans/
Translation: Servarr/Prowlarr
2022-04-16 16:17:01 -05:00
bakerboy448
51e73205ba Fixed: (MaM) Handle Auth Errors & Session Expiry 2022-04-16 15:56:56 -05:00
Qstick
302ed91d05 Fixed: Remove Indexer if categories were changed to not include in sync
Applies to Full Sync Update

Fixes #912
2022-04-16 15:32:37 -05:00
Qstick
cf01c52c34 Fixed: Sync Indexers on App Edit 2022-04-16 15:23:23 -05:00
Qstick
16f0486da2 Cleanup Config Values
Closes #894
2022-04-16 13:34:16 -05:00
Qstick
7e3dcb338c Fixed: (Cardigann) Handle json field selector that returns arrays
Closes #950
2022-04-16 13:09:21 -05:00
Qstick
828aea14a9 New: Schedule refresh and process monitored download tasks at high priority
Co-Authored-By: Mark McDowall <markus101@users.noreply.github.com>
2022-04-16 12:58:43 -05:00
ta264
b31e27a7ae Centralise image choice, update to latest images
(cherry picked from commit fa1985509d77dedd108286a159749fd5cf9d8599)
2022-04-16 12:53:41 -05:00
Mark McDowall
0f3559e556 Don't return early after re-running checks after startup grace period
Fixes #7147

(cherry picked from commit 06464d720c0d31c22865629062d6da0911d2a01f)
2022-04-16 12:49:52 -05:00
Mark McDowall
9a1bf54c14 Fixed: Delay health check notifications on startup
(cherry picked from commit 07f0db477a91b39c1f4b884775c08a55ada487cf)
2022-04-16 12:49:52 -05:00
Douglas R Andreani
a6eb1bf546 New: Add date picker for custom filter dates
(cherry picked from commit 5a08d5dc248bf1dbaa43264a2a470149cf716a3c)
2022-04-16 12:42:52 -05:00
Qstick
35e561e2c0 Bump Monotorrent to 2.0.5 2022-04-16 12:42:24 -05:00
Qstick
1af5beff31 Remove old DotNetVersion method and dep 2022-04-16 12:41:29 -05:00
Zack Eckersley Pallett
18189d086b New: Add backup size information
Closes #957

(cherry picked from commit 78aeda1a2cc217c367c5c3c6fd281c101b28413c)
2022-04-16 12:37:51 -05:00
Qstick
1b83459927 Fixed: (BeyondHD) Use TryCoerceInt for tmdbId
Fixes #960
2022-04-16 12:33:34 -05:00
Servarr
bb6c068d91 Automated API Docs update 2022-04-14 16:34:00 -05:00
bakerboy448
b85cd92cca Fixed: (TorrentDay) TV Search returning Series not S/E Results
Fixes #816
2022-04-13 19:54:05 -05:00
bakerboy448
9f5d8517e5 Fixed: (CinemaZ and ExoticaZ) Better Log Cleansing 2022-04-13 19:45:35 -05:00
bakerboy448
ce78f91657 Fixed: (exoticaz) Category Parsing
based on jackett fa2025cfd4b538d24a4a11bec6f5b13f8711fce0
2022-04-13 19:45:22 -05:00
3744111
e1b924ab08 Fixed: (Indexer) HDTorrents search imdbid + season/episode 2022-04-13 19:45:08 -05:00
Qstick
3b7bafb78e Bump version to 0.3.0 2022-04-10 12:17:13 -05:00
dependabot[bot]
ca0de18413 Bump moment from 2.29.1 to 2.29.2
Bumps [moment](https://github.com/moment/moment) from 2.29.1 to 2.29.2.
- [Release notes](https://github.com/moment/moment/releases)
- [Changelog](https://github.com/moment/moment/blob/develop/CHANGELOG.md)
- [Commits](https://github.com/moment/moment/compare/2.29.1...2.29.2)

---
updated-dependencies:
- dependency-name: moment
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-10 11:34:28 -05:00
Vladimir Tasic
fb8b65a91b #834 #256 fix for unable to load the Indexes page
#834 #256 fix for unable to load the Indexes page
2022-04-09 21:57:45 -05:00
ta264
b4e0608b3b Fix .editorconfig to disallow this
[common]
2022-04-08 20:20:24 +01:00
ta264
60d9f02830 New: MyAnonamouse freeleech support 2022-04-08 18:28:00 +01:00
86 changed files with 1418 additions and 293 deletions

View File

@@ -19,10 +19,10 @@ indent_size = 4
dotnet_sort_system_directives_first = true
# Avoid "this." and "Me." if not necessary
dotnet_style_qualification_for_field = false:refactoring
dotnet_style_qualification_for_property = false:refactoring
dotnet_style_qualification_for_method = false:refactoring
dotnet_style_qualification_for_event = false:refactoring
dotnet_style_qualification_for_field = false:warning
dotnet_style_qualification_for_property = false:warning
dotnet_style_qualification_for_method = false:warning
dotnet_style_qualification_for_event = false:warning
# Indentation preferences
csharp_indent_block_contents = true
@@ -32,10 +32,6 @@ csharp_indent_case_contents_when_block = true
csharp_indent_switch_labels = true
csharp_indent_labels = flush_left
dotnet_style_qualification_for_field = false:suggestion
dotnet_style_qualification_for_property = false:suggestion
dotnet_style_qualification_for_method = false:suggestion
dotnet_style_qualification_for_event = false:suggestion
dotnet_naming_style.instance_field_style.capitalization = camel_case
dotnet_naming_style.instance_field_style.required_prefix = _

View File

@@ -7,7 +7,9 @@ variables:
outputFolder: './_output'
artifactsFolder: './_artifacts'
testsFolder: './_tests'
majorVersion: '0.2.0'
yarnCacheFolder: $(Pipeline.Workspace)/.yarn
nugetCacheFolder: $(Pipeline.Workspace)/.nuget/packages
majorVersion: '0.3.0'
minorVersion: $[counter('minorVersion', 1)]
prowlarrVersion: '$(majorVersion).$(minorVersion)'
buildName: '$(Build.SourceBranchName).$(prowlarrVersion)'
@@ -16,7 +18,9 @@ variables:
dotnetVersion: '6.0.201'
innoVersion: '6.2.0'
nodeVersion: '16.x'
yarnCacheFolder: $(Pipeline.Workspace)/.yarn
windowsImage: 'windows-2022'
linuxImage: 'ubuntu-20.04'
macImage: 'macOS-11'
trigger:
branches:
@@ -40,7 +44,7 @@ stages:
- job:
displayName: Build Variables
pool:
vmImage: 'ubuntu-18.04'
vmImage: ${{ variables.linuxImage }}
steps:
# Set the build name properly. The 'name' property won't recursively expand so hack here:
- bash: echo "##vso[build.updatebuildnumber]$PROWLARRVERSION"
@@ -66,15 +70,15 @@ stages:
matrix:
Linux:
osName: 'Linux'
imageName: 'ubuntu-18.04'
imageName: ${{ variables.linuxImage }}
enableAnalysis: 'true'
Mac:
osName: 'Mac'
imageName: 'macos-10.15'
imageName: ${{ variables.macImage }}
enableAnalysis: 'false'
Windows:
osName: 'Windows'
imageName: 'windows-2019'
imageName: ${{ variables.windowsImage }}
enableAnalysis: 'false'
pool:
@@ -144,13 +148,13 @@ stages:
matrix:
Linux:
osName: 'Linux'
imageName: 'ubuntu-18.04'
imageName: ${{ variables.linuxImage }}
Mac:
osName: 'Mac'
imageName: 'macos-10.15'
imageName: ${{ variables.macImage }}
Windows:
osName: 'Windows'
imageName: 'windows-2019'
imageName: ${{ variables.windowsImage }}
pool:
vmImage: $(imageName)
steps:
@@ -186,7 +190,7 @@ stages:
- job: Windows_Installer
displayName: Create Installer
pool:
vmImage: 'windows-2019'
vmImage: ${{ variables.windowsImage }}
steps:
- checkout: self
fetchDepth: 1
@@ -219,7 +223,7 @@ stages:
- job: Other_Packages
displayName: Create Standard Packages
pool:
vmImage: 'ubuntu-18.04'
vmImage: ${{ variables.linuxImage }}
steps:
- checkout: self
fetchDepth: 1
@@ -379,7 +383,7 @@ stages:
jobs:
- job: Prepare
pool:
vmImage: 'ubuntu-18.04'
vmImage: ${{ variables.linuxImage }}
steps:
- checkout: none
- task: DownloadPipelineArtifact@2
@@ -403,17 +407,17 @@ stages:
osName: 'Mac'
testName: 'MacCore'
poolName: 'Azure Pipelines'
imageName: 'macos-10.15'
imageName: ${{ variables.macImage }}
WindowsCore:
osName: 'Windows'
testName: 'WindowsCore'
poolName: 'Azure Pipelines'
imageName: 'windows-2019'
imageName: ${{ variables.windowsImage }}
LinuxCore:
osName: 'Linux'
testName: 'LinuxCore'
poolName: 'Azure Pipelines'
imageName: 'ubuntu-18.04'
imageName: ${{ variables.linuxImage }}
FreebsdCore:
osName: 'Linux'
testName: 'FreebsdCore'
@@ -469,7 +473,7 @@ stages:
containerImage: ghcr.io/servarr/testimages:alpine
pool:
vmImage: 'ubuntu-18.04'
vmImage: ${{ variables.linuxImage }}
container: $[ variables['containerImage'] ]
@@ -510,7 +514,7 @@ stages:
jobs:
- job: Prepare
pool:
vmImage: 'ubuntu-18.04'
vmImage: ${{ variables.linuxImage }}
steps:
- checkout: none
- task: DownloadPipelineArtifact@2
@@ -530,17 +534,17 @@ stages:
MacCore:
osName: 'Mac'
testName: 'MacCore'
imageName: 'macos-10.15'
imageName: ${{ variables.macImage }}
pattern: 'Prowlarr.*.osx-core-x64.tar.gz'
WindowsCore:
osName: 'Windows'
testName: 'WindowsCore'
imageName: 'windows-2019'
imageName: ${{ variables.windowsImage }}
pattern: 'Prowlarr.*.windows-core-x64.zip'
LinuxCore:
osName: 'Linux'
testName: 'LinuxCore'
imageName: 'ubuntu-18.04'
imageName: ${{ variables.linuxImage }}
pattern: 'Prowlarr.*.linux-core-x64.tar.gz'
pool:
@@ -645,7 +649,7 @@ stages:
pattern: 'Prowlarr.*.linux-musl-core-x64.tar.gz'
pool:
vmImage: 'ubuntu-18.04'
vmImage: ${{ variables.linuxImage }}
container: $[ variables['containerImage'] ]
@@ -701,17 +705,17 @@ stages:
matrix:
Linux:
osName: 'Linux'
imageName: 'ubuntu-18.04'
imageName: ${{ variables.linuxImage }}
pattern: 'Prowlarr.*.linux-core-x64.tar.gz'
failBuild: true
Mac:
osName: 'Mac'
imageName: 'macos-10.15'
imageName: ${{ variables.macImage }}
pattern: 'Prowlarr.*.osx-core-x64.tar.gz'
failBuild: true
Windows:
osName: 'Windows'
imageName: 'windows-2019'
imageName: ${{ variables.windowsImage }}
pattern: 'Prowlarr.*.windows-core-x64.zip'
failBuild: true
@@ -777,7 +781,7 @@ stages:
jobs:
- job: Prepare
pool:
vmImage: 'ubuntu-18.04'
vmImage: ${{ variables.linuxImage }}
steps:
- checkout: none
- task: DownloadPipelineArtifact@2
@@ -794,10 +798,10 @@ stages:
matrix:
Linux:
osName: 'Linux'
imageName: 'ubuntu-18.04'
imageName: ${{ variables.linuxImage }}
Windows:
osName: 'Windows'
imageName: 'windows-2019'
imageName: ${{ variables.windowsImage }}
pool:
vmImage: $(imageName)
steps:
@@ -832,7 +836,7 @@ stages:
)
pool:
vmImage: windows-2019
vmImage: ${{ variables.windowsImage }}
steps:
- task: UseDotNet@2
@@ -884,7 +888,7 @@ stages:
EnableAnalyzers: 'false'
pool:
vmImage: windows-2019
vmImage: ${{ variables.windowsImage }}
steps:
- task: UseDotNet@2
@@ -941,7 +945,7 @@ stages:
- job:
displayName: Discord Notification
pool:
vmImage: 'ubuntu-18.04'
vmImage: ${{ variables.linuxImage }}
steps:
- task: DownloadPipelineArtifact@2
continueOnError: true

View File

@@ -160,6 +160,7 @@ class DateFilterBuilderRowValue extends Component {
<TextInput
name={NAME}
value={filterValue}
type="date"
placeholder="yyyy-mm-dd"
onChange={this.onValueChange}
/>

View File

@@ -190,7 +190,7 @@ class IndexerIndexRow extends Component {
key={name}
className={styles[column.name]}
>
{appProfile.name}
{appProfile?.name || ''}
</VirtualTableRowCell>
);
}

View File

@@ -8,6 +8,7 @@ import RelativeDateCellConnector from 'Components/Table/Cells/RelativeDateCellCo
import TableRowCell from 'Components/Table/Cells/TableRowCell';
import TableRow from 'Components/Table/TableRow';
import { icons, kinds } from 'Helpers/Props';
import formatBytes from 'Utilities/Number/formatBytes';
import translate from 'Utilities/String/translate';
import RestoreBackupModalConnector from './RestoreBackupModalConnector';
import styles from './BackupRow.css';
@@ -65,6 +66,7 @@ class BackupRow extends Component {
type,
name,
path,
size,
time
} = this.props;
@@ -104,6 +106,10 @@ class BackupRow extends Component {
</Link>
</TableRowCell>
<TableRowCell>
{formatBytes(size)}
</TableRowCell>
<RelativeDateCellConnector
date={time}
/>
@@ -147,6 +153,7 @@ BackupRow.propTypes = {
type: PropTypes.string.isRequired,
name: PropTypes.string.isRequired,
path: PropTypes.string.isRequired,
size: PropTypes.number.isRequired,
time: PropTypes.string.isRequired,
onDeleteBackupPress: PropTypes.func.isRequired
};

View File

@@ -23,6 +23,11 @@ const columns = [
label: translate('Name'),
isVisible: true
},
{
name: 'size',
label: 'Size',
isVisible: true
},
{
name: 'time',
label: translate('Time'),
@@ -127,6 +132,7 @@ class Backups extends Component {
type,
name,
path,
size,
time
} = item;
@@ -137,6 +143,7 @@ class Backups extends Component {
type={type}
name={name}
path={path}
size={size}
time={time}
onDeleteBackupPress={onDeleteBackupPress}
/>

View File

@@ -45,7 +45,7 @@
"jquery": "3.6.0",
"lodash": "4.17.21",
"mobile-detect": "1.4.5",
"moment": "2.29.1",
"moment": "2.29.2",
"mousetrap": "1.6.5",
"normalize.css": "8.0.1",
"prop-types": "15.8.1",

View File

@@ -25,7 +25,7 @@ namespace NzbDrone.Common.Test.InstrumentationTests
[TestCase(@"Req: [POST] https://www3.yggtorrent.nz/user/login: id=mySecret&pass=mySecret&ci_csrf_token=2b51db35e1912ffc138825a12b9933d2")]
[TestCase(@"https://torrentseeds.org/api/torrents/filter?api_token=2b51db35e1912ffc138825a12b9933d2&name=&sortField=created_at&sortDirection=desc&perPage=100&page=1")]
//Indexer Responses
// Indexer and Download Client Responses
// avistaz response
[TestCase(@"""download"":""https:\/\/avistaz.to\/rss\/download\/2b51db35e1910123321025a12b9933d2\/tb51db35e1910123321025a12b9933d2.torrent"",")]
@@ -46,6 +46,10 @@ namespace NzbDrone.Common.Test.InstrumentationTests
[TestCase(@"{ ""Name"" : ""ControlUsername"", ""Value"" : ""mySecret"" }, { ""Name"" : ""ControlPassword"", ""Value"" : ""mySecret"" }, ")]
[TestCase(@"{ ""Name"" : ""Server1.Username"", ""Value"" : ""mySecret"" }, { ""Name"" : ""Server1.Password"", ""Value"" : ""mySecret"" }, ")]
// MTV
[TestCase(@"<link rel=""alternate"" type=""application/rss+xml"" href=""/feeds.php?feed=torrents_notify_2b51db35e1910123321025a12b9933d2&amp;user=(removed)&amp;auth=(removed)&amp;passkey=(removed)&amp;authkey=(removed) title=""MoreThanTV - P.T.N."" />")]
[TestCase(@"href=""/torrents.php?action=download&amp;id=(removed)&amp;authkey=(removed)&amp;torrent_pass=2b51db35e1910123321025a12b9933d2"" title=""Download Torrent""")]
// Sabnzbd
[TestCase(@"http://127.0.0.1:1234/api/call?vv=1&apikey=mySecret")]
[TestCase(@"http://127.0.0.1:1234/api/call?vv=1&ma_username=mySecret&ma_password=mySecret")]

View File

@@ -1,7 +1,4 @@
using System;
using System.Reflection;
using System.Text.RegularExpressions;
using Microsoft.Win32;
using System;
namespace NzbDrone.Common.EnvironmentInfo
{
@@ -19,8 +16,6 @@ namespace NzbDrone.Common.EnvironmentInfo
public class PlatformInfo : IPlatformInfo
{
private static readonly Regex MonoVersionRegex = new Regex(@"(?<=\W|^)(?<version>\d+\.\d+(\.\d+)?(\.\d+)?)(?=\W)", RegexOptions.Compiled | RegexOptions.IgnoreCase);
private static PlatformType _platform;
private static Version _version;
@@ -60,107 +55,5 @@ namespace NzbDrone.Common.EnvironmentInfo
{
return _version;
}
private static Version GetMonoVersion()
{
try
{
var type = Type.GetType("Mono.Runtime");
if (type != null)
{
var displayNameMethod = type.GetMethod("GetDisplayName", BindingFlags.NonPublic | BindingFlags.Static);
if (displayNameMethod != null)
{
var displayName = displayNameMethod.Invoke(null, null).ToString();
var versionMatch = MonoVersionRegex.Match(displayName);
if (versionMatch.Success)
{
return new Version(versionMatch.Groups["version"].Value);
}
}
}
}
catch (Exception ex)
{
Console.WriteLine("Couldnt get Mono version: " + ex.ToString());
}
return new Version();
}
private static Version GetDotNetVersion()
{
try
{
const string subkey = @"SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full\";
using (var ndpKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32).OpenSubKey(subkey))
{
if (ndpKey == null)
{
return new Version(4, 0);
}
var releaseKey = (int)ndpKey.GetValue("Release");
if (releaseKey >= 528040)
{
return new Version(4, 8, 0);
}
if (releaseKey >= 461808)
{
return new Version(4, 7, 2);
}
if (releaseKey >= 461308)
{
return new Version(4, 7, 1);
}
if (releaseKey >= 460798)
{
return new Version(4, 7);
}
if (releaseKey >= 394802)
{
return new Version(4, 6, 2);
}
if (releaseKey >= 394254)
{
return new Version(4, 6, 1);
}
if (releaseKey >= 393295)
{
return new Version(4, 6);
}
if (releaseKey >= 379893)
{
return new Version(4, 5, 2);
}
if (releaseKey >= 378675)
{
return new Version(4, 5, 1);
}
if (releaseKey >= 378389)
{
return new Version(4, 5);
}
}
}
catch (Exception ex)
{
Console.WriteLine("Couldnt get .NET framework version: " + ex.ToString());
}
return new Version(4, 0);
}
}
}

View File

@@ -42,16 +42,16 @@ namespace NzbDrone.Common.Instrumentation
// Deluge
new Regex(@"auth.login\(""(?<secret>[^""]+?)""", RegexOptions.Compiled | RegexOptions.IgnoreCase),
// BroadcastheNet
// BroadcastheNet (;torrent_pass|torrents_notify_ is for MTV)
new Regex(@"""?method""?\s*:\s*""(getTorrents)"",\s*""?params""?\s*:\s*\[\s*""(?<secret>[^""]+?)""", RegexOptions.Compiled | RegexOptions.IgnoreCase),
new Regex(@"getTorrents\(""(?<secret>[^""]+?)""", RegexOptions.Compiled | RegexOptions.IgnoreCase),
new Regex(@"(?<=\?|&)(authkey|torrent_pass)=(?<secret>[^&=]+?)(?=""|&|$)", RegexOptions.Compiled | RegexOptions.IgnoreCase),
new Regex(@"(?<=\?|&|;|=)(authkey|torrent_pass|torrents_notify)[_=](?<secret>[^&=]+?)(?=""|&|$)", RegexOptions.Compiled | RegexOptions.IgnoreCase),
// Plex
new Regex(@"(?<=\?|&)(X-Plex-Client-Identifier|X-Plex-Token)=(?<secret>[^&=]+?)(?= |&|$)", RegexOptions.Compiled | RegexOptions.IgnoreCase),
// Indexer Responses
new Regex(@"avistaz\.[a-z]{2,3}\\\/rss\\\/download\\\/(?<secret>[^&=]+?)\\\/(?<secret>[^&=]+?)\.torrent", RegexOptions.Compiled | RegexOptions.IgnoreCase),
new Regex(@"(?:avistaz|exoticaz|cinemaz|privatehd)\.[a-z]{2,3}\\\/rss\\\/download\\\/(?<secret>[^&=]+?)\\\/(?<secret>[^&=]+?)\.torrent", RegexOptions.Compiled | RegexOptions.IgnoreCase),
new Regex(@",""info_hash"":""(?<secret>[^&=]+?)"",", RegexOptions.Compiled | RegexOptions.IgnoreCase),
new Regex(@",""pass[- _]?key"":""(?<secret>[^&=]+?)"",", RegexOptions.Compiled | RegexOptions.IgnoreCase),
new Regex(@",""rss[- _]?key"":""(?<secret>[^&=]+?)"",", RegexOptions.Compiled | RegexOptions.IgnoreCase),

View File

@@ -18,7 +18,6 @@
<PackageReference Include="System.IO.FileSystem.AccessControl" Version="5.0.0" />
<PackageReference Include="System.Runtime.Loader" Version="4.3.0" />
<PackageReference Include="System.ServiceProcess.ServiceController" Version="6.0.0" />
<PackageReference Include="Microsoft.Win32.Registry" Version="5.0.0" />
</ItemGroup>
<ItemGroup>
<Compile Update="EnsureThat\Resources\ExceptionMessages.Designer.cs">

View File

@@ -0,0 +1,87 @@
using System.Linq;
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Core.Indexers;
using NzbDrone.Core.Test.Framework;
namespace NzbDrone.Core.Test.IndexerTests
{
[TestFixture]
public class IndexerCapabilitiesCategoriesFixture : CoreTest<IndexerCapabilitiesCategories>
{
[Test]
public void should_support_parent_if_child_mapping()
{
Subject.AddCategoryMapping(1, NewznabStandardCategory.MoviesSD, "Filme SD");
var categories = new int[] { 2000 };
var supported = Subject.SupportedCategories(categories);
supported.Should().HaveCount(1);
}
[Test]
public void should_support_category_if_mapped()
{
Subject.AddCategoryMapping(1, NewznabStandardCategory.MoviesSD, "Filme SD");
var categories = new int[] { 2030 };
var supported = Subject.SupportedCategories(categories);
supported.Should().HaveCount(1);
}
[Test]
public void should_not_support_category_if_not_mapped()
{
Subject.AddCategoryMapping(1, NewznabStandardCategory.MoviesSD, "Filme SD");
var categories = new int[] { 2040 };
var supported = Subject.SupportedCategories(categories);
supported.Should().HaveCount(0);
}
[Test]
public void should_get_tracker_category_list()
{
Subject.AddCategoryMapping(1, NewznabStandardCategory.MoviesSD, "Filme SD");
Subject.AddCategoryMapping(2, NewznabStandardCategory.MoviesHD, "Filme HD");
var supported = Subject.GetTrackerCategories();
supported.Should().HaveCount(2);
supported.First().Should().NotBeNull();
supported.First().Should().Be("1");
}
[Test]
public void should_get_category_by_tracker_id()
{
Subject.AddCategoryMapping(1, NewznabStandardCategory.MoviesSD, "Filme SD");
Subject.AddCategoryMapping(2, NewznabStandardCategory.MoviesHD, "Filme HD");
var supported = Subject.MapTrackerCatToNewznab(2.ToString());
supported.Should().HaveCount(2);
supported.First().Should().NotBeNull();
supported.First().Id.Should().Be(NewznabStandardCategory.MoviesHD.Id);
}
[Test]
public void should_get_category_by_tracker_desc()
{
Subject.AddCategoryMapping(1, NewznabStandardCategory.MoviesSD, "Filme SD");
Subject.AddCategoryMapping(2, NewznabStandardCategory.MoviesHD, "Filme HD");
var supported = Subject.MapTrackerCatDescToNewznab("Filme HD");
supported.Should().HaveCount(2);
supported.First().Should().NotBeNull();
supported.First().Id.Should().Be(NewznabStandardCategory.MoviesHD.Id);
}
}
}

View File

@@ -17,6 +17,7 @@ namespace NzbDrone.Core.Applications
IHandleAsync<ProviderDeletedEvent<IIndexer>>,
IHandleAsync<ProviderAddedEvent<IApplication>>,
IHandleAsync<ProviderUpdatedEvent<IIndexer>>,
IHandleAsync<ProviderUpdatedEvent<IApplication>>,
IHandleAsync<ProviderBulkUpdatedEvent<IIndexer>>,
IHandleAsync<ApiKeyChangedEvent>,
IExecute<ApplicationIndexerSyncCommand>
@@ -49,6 +50,19 @@ namespace NzbDrone.Core.Applications
}
}
public void HandleAsync(ProviderUpdatedEvent<IApplication> message)
{
var appDefinition = (ApplicationDefinition)message.Definition;
if (appDefinition.Enable)
{
var app = _applicationsFactory.GetInstance(appDefinition);
var indexers = _indexerFactory.Enabled().Select(i => (IndexerDefinition)i.Definition).ToList();
SyncIndexers(new List<IApplication> { app }, indexers);
}
}
public void HandleAsync(ProviderAddedEvent<IIndexer> message)
{
var enabledApps = _applicationsFactory.SyncEnabled();

View File

@@ -124,7 +124,17 @@ namespace NzbDrone.Core.Applications.Lidarr
if (!lidarrIndexer.Equals(remoteIndexer))
{
_lidarrV1Proxy.UpdateIndexer(lidarrIndexer, Settings);
if (indexer.Capabilities.Categories.SupportedCategories(Settings.SyncCategories.ToArray()).Any())
{
// Update the indexer if it still has categories that match
_lidarrV1Proxy.UpdateIndexer(lidarrIndexer, Settings);
}
else
{
// Else remove it, it no longer should be used
_lidarrV1Proxy.RemoveIndexer(remoteIndexer.Id, Settings);
_appIndexerMapService.Delete(indexerMapping.Id);
}
}
}
else

View File

@@ -124,7 +124,17 @@ namespace NzbDrone.Core.Applications.Radarr
if (!radarrIndexer.Equals(remoteIndexer))
{
_radarrV3Proxy.UpdateIndexer(radarrIndexer, Settings);
if (indexer.Capabilities.Categories.SupportedCategories(Settings.SyncCategories.ToArray()).Any())
{
// Update the indexer if it still has categories that match
_radarrV3Proxy.UpdateIndexer(radarrIndexer, Settings);
}
else
{
// Else remove it, it no longer should be used
_radarrV3Proxy.RemoveIndexer(remoteIndexer.Id, Settings);
_appIndexerMapService.Delete(indexerMapping.Id);
}
}
}
else

View File

@@ -124,7 +124,17 @@ namespace NzbDrone.Core.Applications.Readarr
if (!readarrIndexer.Equals(remoteIndexer))
{
_readarrV1Proxy.UpdateIndexer(readarrIndexer, Settings);
if (indexer.Capabilities.Categories.SupportedCategories(Settings.SyncCategories.ToArray()).Any())
{
// Update the indexer if it still has categories that match
_readarrV1Proxy.UpdateIndexer(readarrIndexer, Settings);
}
else
{
// Else remove it, it no longer should be used
_readarrV1Proxy.RemoveIndexer(remoteIndexer.Id, Settings);
_appIndexerMapService.Delete(indexerMapping.Id);
}
}
}
else

View File

@@ -124,7 +124,17 @@ namespace NzbDrone.Core.Applications.Sonarr
if (!sonarrIndexer.Equals(remoteIndexer))
{
_sonarrV3Proxy.UpdateIndexer(sonarrIndexer, Settings);
if (indexer.Capabilities.Categories.SupportedCategories(Settings.SyncCategories.ToArray()).Any() || indexer.Capabilities.Categories.SupportedCategories(Settings.AnimeSyncCategories.ToArray()).Any())
{
// Update the indexer if it still has categories that match
_sonarrV3Proxy.UpdateIndexer(sonarrIndexer, Settings);
}
else
{
// Else remove it, it no longer should be used
_sonarrV3Proxy.RemoveIndexer(remoteIndexer.Id, Settings);
_appIndexerMapService.Delete(indexerMapping.Id);
}
}
}
else

View File

@@ -114,7 +114,7 @@ namespace NzbDrone.Core.Applications.Whisparr
var appMappings = _appIndexerMapService.GetMappingsForApp(Definition.Id);
var indexerMapping = appMappings.FirstOrDefault(m => m.IndexerId == indexer.Id);
var radarrIndexer = BuildWhisparrIndexer(indexer, indexer.Protocol, indexerMapping?.RemoteIndexerId ?? 0);
var whisparrIndexer = BuildWhisparrIndexer(indexer, indexer.Protocol, indexerMapping?.RemoteIndexerId ?? 0);
var remoteIndexer = _whisparrV3Proxy.GetIndexer(indexerMapping.RemoteIndexerId, Settings);
@@ -122,9 +122,19 @@ namespace NzbDrone.Core.Applications.Whisparr
{
_logger.Debug("Remote indexer found, syncing with current settings");
if (!radarrIndexer.Equals(remoteIndexer))
if (!whisparrIndexer.Equals(remoteIndexer))
{
_whisparrV3Proxy.UpdateIndexer(radarrIndexer, Settings);
if (indexer.Capabilities.Categories.SupportedCategories(Settings.SyncCategories.ToArray()).Any())
{
// Update the indexer if it still has categories that match
_whisparrV3Proxy.UpdateIndexer(whisparrIndexer, Settings);
}
else
{
// Else remove it, it no longer should be used
_whisparrV3Proxy.RemoveIndexer(remoteIndexer.Id, Settings);
_appIndexerMapService.Delete(indexerMapping.Id);
}
}
}
else
@@ -134,8 +144,8 @@ namespace NzbDrone.Core.Applications.Whisparr
if (indexer.Capabilities.Categories.SupportedCategories(Settings.SyncCategories.ToArray()).Any())
{
_logger.Debug("Remote indexer not found, re-adding {0} to Whisparr", indexer.Name);
radarrIndexer.Id = 0;
var newRemoteIndexer = _whisparrV3Proxy.AddIndexer(radarrIndexer, Settings);
whisparrIndexer.Id = 0;
var newRemoteIndexer = _whisparrV3Proxy.AddIndexer(whisparrIndexer, Settings);
_appIndexerMapService.Insert(new AppIndexerMap { AppId = Definition.Id, IndexerId = indexer.Id, RemoteIndexerId = newRemoteIndexer.Id });
}
else

View File

@@ -6,6 +6,7 @@ namespace NzbDrone.Core.Backup
{
public string Name { get; set; }
public BackupType Type { get; set; }
public long Size { get; set; }
public DateTime Time { get; set; }
}
}

View File

@@ -109,6 +109,7 @@ namespace NzbDrone.Core.Backup
{
Name = Path.GetFileName(b),
Type = backupType,
Size = _diskProvider.GetFileSize(b),
Time = _diskProvider.FileGetLastWrite(b)
}));
}

View File

@@ -90,12 +90,6 @@ namespace NzbDrone.Core.Configuration
set { SetValue("LogIndexerResponse", value); }
}
public string DownloadClientWorkingFolders
{
get { return GetValue("DownloadClientWorkingFolders", "_UNPACK_|_FAILED_"); }
set { SetValue("DownloadClientWorkingFolders", value); }
}
public int FirstDayOfWeek
{
get { return GetValueInt("FirstDayOfWeek", (int)CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek); }
@@ -145,13 +139,6 @@ namespace NzbDrone.Core.Configuration
set { SetValue("EnableColorImpairedMode", value); }
}
public int MovieInfoLanguage
{
get { return GetValueInt("MovieInfoLanguage", (int)Language.English); }
set { SetValue("MovieInfoLanguage", value); }
}
public int UILanguage
{
get { return GetValueInt("UILanguage", (int)Language.English); }

View File

@@ -10,9 +10,6 @@ namespace NzbDrone.Core.Configuration
bool IsDefined(string key);
//Download Client
string DownloadClientWorkingFolders { get; set; }
//History
int HistoryCleanupDays { get; set; }
@@ -25,7 +22,6 @@ namespace NzbDrone.Core.Configuration
string TimeFormat { get; set; }
bool ShowRelativeDates { get; set; }
bool EnableColorImpairedMode { get; set; }
int MovieInfoLanguage { get; set; }
int UILanguage { get; set; }
//Internal

View File

@@ -0,0 +1,15 @@
using FluentMigrator;
using NzbDrone.Core.Datastore.Migration.Framework;
namespace NzbDrone.Core.Datastore.Migration
{
[Migration(016)]
public class cleanup_config : NzbDroneMigrationBase
{
protected override void MainDbUpgrade()
{
Delete.FromTable("Config").Row(new { Key = "movieinfolanguage" });
Delete.FromTable("Config").Row(new { Key = "downloadclientworkingfolders" });
}
}
}

View File

@@ -41,7 +41,8 @@ namespace NzbDrone.Core.Datastore
Mapper.Entity<Config>("Config").RegisterModel();
Mapper.Entity<ScheduledTask>("ScheduledTasks").RegisterModel();
Mapper.Entity<ScheduledTask>("ScheduledTasks").RegisterModel()
.Ignore(i => i.Priority);
Mapper.Entity<IndexerDefinition>("Indexers").RegisterModel()
.Ignore(x => x.ImplementationName)
@@ -49,6 +50,7 @@ namespace NzbDrone.Core.Datastore
.Ignore(i => i.Language)
.Ignore(i => i.Encoding)
.Ignore(i => i.IndexerUrls)
.Ignore(i => i.LegacyUrls)
.Ignore(i => i.Protocol)
.Ignore(i => i.Privacy)
.Ignore(i => i.SupportsRss)

View File

@@ -5,10 +5,12 @@ namespace NzbDrone.Core.HealthCheck
public class HealthCheckFailedEvent : IEvent
{
public HealthCheck HealthCheck { get; private set; }
public bool IsInStartupGraceperiod { get; private set; }
public HealthCheckFailedEvent(HealthCheck healthCheck)
public HealthCheckFailedEvent(HealthCheck healthCheck, bool isInStartupGraceperiod)
{
HealthCheck = healthCheck;
IsInStartupGraceperiod = isInStartupGraceperiod;
}
}
}

View File

@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using NLog;
using NzbDrone.Common.Cache;
using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Common.Messaging;
using NzbDrone.Common.Reflection;
using NzbDrone.Core.Lifecycle;
@@ -21,6 +22,7 @@ namespace NzbDrone.Core.HealthCheck
IHandleAsync<ApplicationStartedEvent>,
IHandleAsync<IEvent>
{
private readonly DateTime _startupGracePeriodEndTime;
private readonly IProvideHealthCheck[] _healthChecks;
private readonly IProvideHealthCheck[] _startupHealthChecks;
private readonly IProvideHealthCheck[] _scheduledHealthChecks;
@@ -32,10 +34,14 @@ namespace NzbDrone.Core.HealthCheck
private readonly ICached<HealthCheck> _healthCheckResults;
private bool _hasRunHealthChecksAfterGracePeriod = false;
private bool _isRunningHealthChecksAfterGracePeriod = false;
public HealthCheckService(IEnumerable<IProvideHealthCheck> healthChecks,
IServerSideNotificationService serverSideNotificationService,
IEventAggregator eventAggregator,
ICacheManager cacheManager,
IRuntimeInfo runtimeInfo,
Logger logger)
{
_healthChecks = healthChecks.ToArray();
@@ -49,6 +55,7 @@ namespace NzbDrone.Core.HealthCheck
_startupHealthChecks = _healthChecks.Where(v => v.CheckOnStartup).ToArray();
_scheduledHealthChecks = _healthChecks.Where(v => v.CheckOnSchedule).ToArray();
_eventDrivenHealthChecks = GetEventDrivenHealthChecks();
_startupGracePeriodEndTime = runtimeInfo.StartTime + TimeSpan.FromMinutes(15);
}
public List<HealthCheck> Results()
@@ -87,7 +94,7 @@ namespace NzbDrone.Core.HealthCheck
{
if (_healthCheckResults.Find(result.Source.Name) == null)
{
_eventAggregator.PublishEvent(new HealthCheckFailedEvent(result));
_eventAggregator.PublishEvent(new HealthCheckFailedEvent(result, !_hasRunHealthChecksAfterGracePeriod));
}
_healthCheckResults.Set(result.Source.Name, result);
@@ -121,6 +128,28 @@ namespace NzbDrone.Core.HealthCheck
return;
}
// If we haven't previously re-run health checks after startup grace period run startup checks again and track so they aren't run again.
// Return early after re-running checks to avoid triggering checks multiple times.
if (!_hasRunHealthChecksAfterGracePeriod && !_isRunningHealthChecksAfterGracePeriod && DateTime.UtcNow > _startupGracePeriodEndTime)
{
_isRunningHealthChecksAfterGracePeriod = true;
PerformHealthCheck(_startupHealthChecks);
// Update after running health checks so new failure notifications aren't sent 2x.
_hasRunHealthChecksAfterGracePeriod = true;
// Explicitly notify for any failed checks since existing failed results would not have sent events.
var results = _healthCheckResults.Values.ToList();
foreach (var result in results)
{
_eventAggregator.PublishEvent(new HealthCheckFailedEvent(result, false));
}
_isRunningHealthChecksAfterGracePeriod = false;
}
IEventDrivenHealthCheck[] checks;
if (!_eventDrivenHealthChecks.TryGetValue(message.GetType(), out checks))
{

View File

@@ -205,6 +205,10 @@ namespace NzbDrone.Core.Indexers.Definitions
var details = row.InfoUrl;
var link = row.DownloadLink;
// BHD can return crazy values for tmdb
var tmdbId = row.TmdbId.IsNullOrWhiteSpace() ? 0 : ParseUtil.TryCoerceInt(row.TmdbId.Split("/")[1], out var tmdbResult) ? tmdbResult : 0;
var imdbId = ParseUtil.GetImdbID(row.ImdbId).GetValueOrDefault();
var release = new TorrentInfo
{
Title = row.Name,
@@ -217,8 +221,8 @@ namespace NzbDrone.Core.Indexers.Definitions
Size = row.Size,
Grabs = row.Grabs,
Seeders = row.Seeders,
ImdbId = ParseUtil.GetImdbID(row.ImdbId).GetValueOrDefault(),
TmdbId = row.TmdbId.IsNullOrWhiteSpace() ? 0 : (int)ParseUtil.CoerceLong(row.TmdbId.Split("/")[1]),
ImdbId = imdbId,
TmdbId = tmdbId,
Peers = row.Leechers + row.Seeders,
DownloadVolumeFactor = row.Freeleech || row.Limited ? 0 : row.Promo75 ? 0.25 : row.Promo50 ? 0.5 : row.Promo25 ? 0.75 : 1,
UploadVolumeFactor = 1,

View File

@@ -19,7 +19,9 @@ namespace NzbDrone.Core.Indexers.BroadcastheNet
public override IndexerCapabilities Capabilities => SetCapabilities();
public override TimeSpan RateLimit => TimeSpan.FromSeconds(5);
public override string[] IndexerUrls => new string[] { "http://api.broadcasthe.net/" };
public override string[] IndexerUrls => new string[] { "https://api.broadcasthe.net/" };
public override string[] LegacyUrls => new string[] { "http://api.broadcasthe.net/" };
public override string Description => "BroadcasTheNet (BTN) is an invite-only torrent tracker focused on TV shows";
public BroadcastheNet(IIndexerHttpClient httpClient, IEventAggregator eventAggregator, IIndexerStatusService indexerStatusService, IConfigService configService, Logger logger)

View File

@@ -126,6 +126,7 @@ namespace NzbDrone.Core.Indexers.Cardigann
Description = definition.Description,
Implementation = GetType().Name,
IndexerUrls = definition.Links.ToArray(),
LegacyUrls = definition.Legacylinks.ToArray(),
Settings = new CardigannSettings { DefinitionFile = definition.File },
Protocol = DownloadProtocol.Torrent,
Privacy = definition.Type switch

View File

@@ -256,7 +256,16 @@ namespace NzbDrone.Core.Indexers.Cardigann
return null;
}
value = selection.Value<string>();
if (selection.Type is JTokenType.Array)
{
// turn this json array into a comma delimited string
var valueArray = selection.Value<JArray>();
value = string.Join(",", valueArray);
}
else
{
value = selection.Value<string>();
}
}
if (selector.Case != null)

View File

@@ -29,6 +29,11 @@ namespace NzbDrone.Core.Indexers.Cardigann
// Cardigann yaml classes
public class CardigannDefinition
{
public CardigannDefinition()
{
Legacylinks = new List<string>();
}
public string Id { get; set; }
public List<SettingsField> Settings { get; set; }
public string Name { get; set; }

View File

@@ -4,6 +4,11 @@ namespace NzbDrone.Core.Indexers.Cardigann
{
public class CardigannMetaDefinition
{
public CardigannMetaDefinition()
{
Legacylinks = new List<string>();
}
public string Id { get; set; }
public string File { get; set; }
public string Name { get; set; }

View File

@@ -40,14 +40,14 @@ namespace NzbDrone.Core.Indexers.Definitions
}
};
caps.Categories.AddCategoryMapping(1, NewznabStandardCategory.XXXx264);
caps.Categories.AddCategoryMapping(2, NewznabStandardCategory.XXXPack);
caps.Categories.AddCategoryMapping(3, NewznabStandardCategory.XXXPack);
caps.Categories.AddCategoryMapping(4, NewznabStandardCategory.XXXPack);
caps.Categories.AddCategoryMapping(5, NewznabStandardCategory.XXXDVD);
caps.Categories.AddCategoryMapping(6, NewznabStandardCategory.XXXx264);
caps.Categories.AddCategoryMapping(7, NewznabStandardCategory.XXXImageSet);
caps.Categories.AddCategoryMapping(8, NewznabStandardCategory.XXXImageSet);
caps.Categories.AddCategoryMapping(1, NewznabStandardCategory.XXXx264, "Video Clip");
caps.Categories.AddCategoryMapping(2, NewznabStandardCategory.XXXPack, "Video Pack");
caps.Categories.AddCategoryMapping(3, NewznabStandardCategory.XXXPack, "Siterip Pack");
caps.Categories.AddCategoryMapping(4, NewznabStandardCategory.XXXPack, "Pornstar Pack");
caps.Categories.AddCategoryMapping(5, NewznabStandardCategory.XXXDVD, "DVD");
caps.Categories.AddCategoryMapping(6, NewznabStandardCategory.XXXx264, "BluRay");
caps.Categories.AddCategoryMapping(7, NewznabStandardCategory.XXXImageSet, "Photo Pack");
caps.Categories.AddCategoryMapping(8, NewznabStandardCategory.XXXImageSet, "Books & Magazines");
return caps;
}

View File

@@ -151,9 +151,11 @@ namespace NzbDrone.Core.Indexers.Definitions
{
var searchUrl = Settings.BaseUrl + "torrents.php?" + string.Join(string.Empty, Capabilities.Categories.MapTorznabCapsToTrackers(categories).Select(cat => $"category[]={cat}&"));
var search = new[] { imdbId, term };
var queryCollection = new NameValueCollection
{
{ "search", imdbId ?? term },
{ "search", string.Join(" ", search.Where(s => !string.IsNullOrEmpty(s))) },
{ "active", "0" },
{ "options", "0" }
};
@@ -188,7 +190,7 @@ namespace NzbDrone.Core.Indexers.Definitions
{
var pageableRequests = new IndexerPageableRequestChain();
pageableRequests.Add(GetPagedRequests(string.Format("{0}", searchCriteria.SanitizedSearchTerm), searchCriteria.Categories, searchCriteria.FullImdbId));
pageableRequests.Add(GetPagedRequests(string.Format("{0}", searchCriteria.SanitizedTvSearchString), searchCriteria.Categories, searchCriteria.FullImdbId));
return pageableRequests;
}

View File

@@ -4,10 +4,13 @@ using System.Collections.Specialized;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using FluentValidation;
using Newtonsoft.Json;
using NLog;
using NzbDrone.Common.Http;
using NzbDrone.Common.Serializer;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.Configuration;
using NzbDrone.Core.Indexers.Exceptions;
@@ -21,6 +24,8 @@ namespace NzbDrone.Core.Indexers.Definitions
{
public class MyAnonamouse : TorrentIndexerBase<MyAnonamouseSettings>
{
private static readonly Regex TorrentIdRegex = new Regex(@"tor/download.php\?tid=(?<id>\d+)$");
public override string Name => "MyAnonamouse";
public override string[] IndexerUrls => new string[] { "https://www.myanonamouse.net/" };
@@ -44,6 +49,47 @@ namespace NzbDrone.Core.Indexers.Definitions
return new MyAnonamouseParser(Settings, Capabilities.Categories);
}
public override async Task<byte[]> Download(Uri link)
{
if (Settings.Freeleech)
{
_logger.Debug($"Attempting to use freeleech token for {link.AbsoluteUri}");
var idMatch = TorrentIdRegex.Match(link.AbsoluteUri);
if (idMatch.Success)
{
var id = int.Parse(idMatch.Groups["id"].Value);
var timestamp = DateTimeOffset.Now.ToUnixTimeSeconds();
var freeleechUrl = Settings.BaseUrl + $"json/bonusBuy.php/{timestamp}";
var freeleechRequest = new HttpRequestBuilder(freeleechUrl)
.AddQueryParam("spendtype", "personalFL")
.AddQueryParam("torrentid", id)
.AddQueryParam("timestamp", timestamp.ToString())
.Build();
var indexerReq = new IndexerRequest(freeleechRequest);
var response = await FetchIndexerResponse(indexerReq).ConfigureAwait(false);
var resource = Json.Deserialize<MyAnonamouseFreeleechResponse>(response.Content);
if (resource.Success)
{
_logger.Debug($"Successfully to used freeleech token for torrentid ${id}");
}
else
{
_logger.Debug($"Failed to use freeleech token: ${resource.Error}");
}
}
else
{
_logger.Debug($"Could not get torrent id from link ${link.AbsoluteUri}, skipping freeleech");
}
}
return await base.Download(link).ConfigureAwait(false);
}
protected override IDictionary<string, string> GetCookies()
{
return CookieUtil.CookieHeaderToDictionary("mam_id=" + Settings.MamId);
@@ -271,6 +317,12 @@ namespace NzbDrone.Core.Indexers.Definitions
public IList<ReleaseInfo> ParseResponse(IndexerResponse indexerResponse)
{
// Throw auth errors here before we try to parse
if (indexerResponse.HttpResponse.StatusCode == HttpStatusCode.Forbidden)
{
throw new IndexerAuthException("[403 Forbidden] - mam_session_id expired or invalid");
}
// Throw common http errors here before we try to parse
if (indexerResponse.HttpResponse.StatusCode != HttpStatusCode.OK)
{
@@ -394,13 +446,16 @@ namespace NzbDrone.Core.Indexers.Definitions
[FieldDefinition(1, Label = "Base Url", Type = FieldType.Select, SelectOptionsProviderAction = "getUrls", HelpText = "Select which baseurl Prowlarr will use for requests to the site")]
public string BaseUrl { get; set; }
[FieldDefinition(2, Label = "Mam Id", HelpText = "Mam Session Id (Created Under Profile -> Security)")]
[FieldDefinition(2, Label = "Mam Id", HelpText = "Mam Session Id (Created Under Preferences -> Security)")]
public string MamId { get; set; }
[FieldDefinition(3, Type = FieldType.Checkbox, Label = "Exclude VIP", HelpText = "Exclude VIP Torrents from search results")]
public bool ExcludeVip { get; set; }
[FieldDefinition(4)]
[FieldDefinition(4, Type = FieldType.Checkbox, Label = "Freeleech", HelpText = "Use freeleech token for download")]
public bool Freeleech { get; set; }
[FieldDefinition(5)]
public IndexerBaseSettings BaseSettings { get; set; } = new IndexerBaseSettings();
public NzbDroneValidationResult Validate()
@@ -438,4 +493,10 @@ namespace NzbDrone.Core.Indexers.Definitions
public string Error { get; set; }
public List<MyAnonamouseTorrent> Data { get; set; }
}
public class MyAnonamouseFreeleechResponse
{
public bool Success { get; set; }
public string Error { get; set; }
}
}

View File

@@ -57,6 +57,11 @@ namespace NzbDrone.Core.Indexers.Newznab
return new string[] { Settings.BaseUrl };
}
protected override NewznabSettings GetDefaultBaseUrl(NewznabSettings settings)
{
return settings;
}
public IndexerCapabilities GetCapabilitiesFromSettings()
{
var caps = new IndexerCapabilities();

View File

@@ -0,0 +1,266 @@
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Globalization;
using System.Linq;
using System.Text;
using FluentValidation;
using Newtonsoft.Json.Linq;
using NLog;
using NzbDrone.Common.Extensions;
using NzbDrone.Common.Http;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.Configuration;
using NzbDrone.Core.Indexers.Exceptions;
using NzbDrone.Core.IndexerSearch.Definitions;
using NzbDrone.Core.Messaging.Events;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Indexers.Definitions
{
public class SceneHD : TorrentIndexerBase<SceneHDSettings>
{
public override string Name => "SceneHD";
public override string[] IndexerUrls => new[] { "https://scenehd.org/" };
public override string Description => "SceneHD is Private site for HD TV / MOVIES";
public override string Language => "en-US";
public override Encoding Encoding => Encoding.UTF8;
public override DownloadProtocol Protocol => DownloadProtocol.Torrent;
public override IndexerPrivacy Privacy => IndexerPrivacy.Private;
public override IndexerCapabilities Capabilities => SetCapabilities();
public SceneHD(IIndexerHttpClient httpClient, IEventAggregator eventAggregator, IIndexerStatusService indexerStatusService, IConfigService configService, Logger logger)
: base(httpClient, eventAggregator, indexerStatusService, configService, logger)
{
}
public override IIndexerRequestGenerator GetRequestGenerator()
{
return new SceneHDRequestGenerator() { Settings = Settings, Capabilities = Capabilities };
}
public override IParseIndexerResponse GetParser()
{
return new SceneHDParser(Settings, Capabilities.Categories);
}
protected override bool CheckIfLoginNeeded(HttpResponse httpResponse)
{
return false;
}
private IndexerCapabilities SetCapabilities()
{
var caps = new IndexerCapabilities
{
TvSearchParams = new List<TvSearchParam>
{
TvSearchParam.Q, TvSearchParam.Season, TvSearchParam.Ep
},
MovieSearchParams = new List<MovieSearchParam>
{
MovieSearchParam.Q, MovieSearchParam.ImdbId
},
MusicSearchParams = new List<MusicSearchParam>
{
MusicSearchParam.Q
}
};
caps.Categories.AddCategoryMapping(2, NewznabStandardCategory.MoviesUHD, "Movie/2160");
caps.Categories.AddCategoryMapping(1, NewznabStandardCategory.MoviesHD, "Movie/1080");
caps.Categories.AddCategoryMapping(4, NewznabStandardCategory.MoviesHD, "Movie/720");
caps.Categories.AddCategoryMapping(8, NewznabStandardCategory.MoviesBluRay, "Movie/BD5/9");
caps.Categories.AddCategoryMapping(6, NewznabStandardCategory.TVUHD, "TV/2160");
caps.Categories.AddCategoryMapping(5, NewznabStandardCategory.TVHD, "TV/1080");
caps.Categories.AddCategoryMapping(7, NewznabStandardCategory.TVHD, "TV/720");
caps.Categories.AddCategoryMapping(22, NewznabStandardCategory.MoviesBluRay, "Bluray/Complete");
caps.Categories.AddCategoryMapping(10, NewznabStandardCategory.XXX, "XXX");
caps.Categories.AddCategoryMapping(16, NewznabStandardCategory.MoviesOther, "Subpacks");
caps.Categories.AddCategoryMapping(13, NewznabStandardCategory.AudioVideo, "MVID");
caps.Categories.AddCategoryMapping(9, NewznabStandardCategory.Other, "Other");
return caps;
}
}
public class SceneHDRequestGenerator : IIndexerRequestGenerator
{
public SceneHDSettings Settings { get; set; }
public IndexerCapabilities Capabilities { get; set; }
public string BaseUrl { get; set; }
public SceneHDRequestGenerator()
{
}
private IEnumerable<IndexerRequest> GetPagedRequests(string term, int[] categories, string imdbId = null)
{
var search = new[] { imdbId, term };
var qc = new NameValueCollection
{
{ "api", "" },
{ "passkey", Settings.Passkey },
{ "search", string.Join(" ", search.Where(s => s.IsNotNullOrWhiteSpace())) }
};
foreach (var cat in Capabilities.Categories.MapTorznabCapsToTrackers(categories))
{
qc.Add("categories[" + cat + "]", "1");
}
var searchUrl = string.Format("{0}/browse.php?{1}", Settings.BaseUrl.TrimEnd('/'), qc.GetQueryString());
var request = new IndexerRequest(searchUrl, HttpAccept.Json);
yield return request;
}
public IndexerPageableRequestChain GetSearchRequests(MovieSearchCriteria searchCriteria)
{
var pageableRequests = new IndexerPageableRequestChain();
pageableRequests.Add(GetPagedRequests(string.Format("{0}", searchCriteria.SanitizedSearchTerm), searchCriteria.Categories, searchCriteria.FullImdbId));
return pageableRequests;
}
public IndexerPageableRequestChain GetSearchRequests(MusicSearchCriteria searchCriteria)
{
var pageableRequests = new IndexerPageableRequestChain();
pageableRequests.Add(GetPagedRequests(string.Format("{0}", searchCriteria.SanitizedSearchTerm), searchCriteria.Categories));
return pageableRequests;
}
public IndexerPageableRequestChain GetSearchRequests(TvSearchCriteria searchCriteria)
{
var pageableRequests = new IndexerPageableRequestChain();
pageableRequests.Add(GetPagedRequests(string.Format("{0}", searchCriteria.SanitizedTvSearchString), searchCriteria.Categories, searchCriteria.FullImdbId));
return pageableRequests;
}
public IndexerPageableRequestChain GetSearchRequests(BookSearchCriteria searchCriteria)
{
var pageableRequests = new IndexerPageableRequestChain();
pageableRequests.Add(GetPagedRequests(string.Format("{0}", searchCriteria.SanitizedSearchTerm), searchCriteria.Categories));
return pageableRequests;
}
public IndexerPageableRequestChain GetSearchRequests(BasicSearchCriteria searchCriteria)
{
var pageableRequests = new IndexerPageableRequestChain();
pageableRequests.Add(GetPagedRequests(string.Format("{0}", searchCriteria.SanitizedSearchTerm), searchCriteria.Categories));
return pageableRequests;
}
public Func<IDictionary<string, string>> GetCookies { get; set; }
public Action<IDictionary<string, string>, DateTime?> CookiesUpdater { get; set; }
}
public class SceneHDParser : IParseIndexerResponse
{
private readonly SceneHDSettings _settings;
private readonly IndexerCapabilitiesCategories _categories;
public SceneHDParser(SceneHDSettings settings, IndexerCapabilitiesCategories categories)
{
_settings = settings;
_categories = categories;
}
public IList<ReleaseInfo> ParseResponse(IndexerResponse indexerResponse)
{
var torrentInfos = new List<ReleaseInfo>();
var detailsUrl = _settings.BaseUrl + "details.php?";
var downloadUrl = _settings.BaseUrl + "download.php?";
if (indexerResponse.Content?.Contains("User not found or passkey not set") == true)
{
throw new IndexerAuthException("The passkey is invalid. Check the indexer configuration.");
}
var jsonContent = JArray.Parse(indexerResponse.Content);
foreach (var item in jsonContent)
{
var title = item.Value<string>("name");
var id = item.Value<long>("id");
var details = new Uri(detailsUrl + "id=" + id).AbsoluteUri;
var link = new Uri(downloadUrl + "id=" + id + "&passkey=" + _settings.Passkey).AbsoluteUri;
var publishDate = DateTime.ParseExact(item.Value<string>("added"), "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture);
var dlVolumeFactor = item.Value<int>("is_freeleech") == 1 ? 0 : 1;
var release = new TorrentInfo
{
Title = title,
DownloadUrl = link,
InfoUrl = details,
Guid = details,
Categories = _categories.MapTrackerCatToNewznab(item.Value<string>("category")),
PublishDate = publishDate,
Size = item.Value<long>("size"),
Grabs = item.Value<int>("times_completed"),
Files = item.Value<int>("numfiles"),
Seeders = item.Value<int>("seeders"),
Peers = item.Value<int>("leechers") + item.Value<int>("seeders"),
ImdbId = ParseUtil.GetImdbID(item.Value<string>("imdbid")) ?? 0,
MinimumRatio = 1,
MinimumSeedTime = 0,
DownloadVolumeFactor = dlVolumeFactor,
UploadVolumeFactor = 1
};
torrentInfos.Add(release);
}
return torrentInfos.ToArray();
}
public Action<IDictionary<string, string>, DateTime?> CookiesUpdater { get; set; }
}
public class SceneHDSettingsValidator : AbstractValidator<SceneHDSettings>
{
public SceneHDSettingsValidator()
{
RuleFor(c => c.Passkey).NotEmpty().Length(32);
}
}
public class SceneHDSettings : IIndexerSettings
{
private static readonly SceneHDSettingsValidator Validator = new SceneHDSettingsValidator();
public SceneHDSettings()
{
Passkey = "";
}
[FieldDefinition(1, Label = "Base Url", Type = FieldType.Select, SelectOptionsProviderAction = "getUrls", HelpText = "Select which baseurl Prowlarr will use for requests to the site")]
public string BaseUrl { get; set; }
[FieldDefinition(2, Label = "Passkey", Advanced = false, HelpText = "Site Passkey")]
public string Passkey { get; set; }
[FieldDefinition(3)]
public IndexerBaseSettings BaseSettings { get; set; } = new IndexerBaseSettings();
public NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}
}
}

View File

@@ -153,16 +153,15 @@ namespace NzbDrone.Core.Indexers.Definitions
var catStr = string.Join(";", cats);
searchUrl = searchUrl + "?" + catStr;
searchUrl += ";q=";
if (imdbId.IsNotNullOrWhiteSpace())
{
searchUrl += ";q=" + imdbId;
}
else
{
searchUrl += ";q=" + term.UrlEncode(Encoding.UTF8);
searchUrl += imdbId + " ".UrlEncode(Encoding.UTF8);
}
searchUrl += term.UrlEncode(Encoding.UTF8);
var request = new IndexerRequest(searchUrl, HttpAccept.Rss);
yield return request;

View File

@@ -33,6 +33,7 @@ namespace NzbDrone.Core.Indexers
public override Encoding Encoding => Encoding.UTF8;
public override string Language => "en-US";
public override string[] LegacyUrls => new string[] { };
public override bool FollowRedirect => false;
public override IndexerCapabilities Capabilities { get; protected set; }

View File

@@ -14,6 +14,7 @@ namespace NzbDrone.Core.Indexers
IndexerCapabilities Capabilities { get; }
string[] IndexerUrls { get; }
string[] LegacyUrls { get; }
string Description { get; }
Encoding Encoding { get; }
string Language { get; }

View File

@@ -22,6 +22,7 @@ namespace NzbDrone.Core.Indexers
public abstract string Name { get; }
public abstract string[] IndexerUrls { get; }
public abstract string[] LegacyUrls { get; }
public abstract string Description { get; }
public abstract Encoding Encoding { get; }
public abstract string Language { get; }
@@ -145,11 +146,18 @@ namespace NzbDrone.Core.Indexers
return result.DistinctBy(v => v.Guid).ToList();
}
protected TSettings GetDefaultBaseUrl(TSettings settings)
protected virtual TSettings GetDefaultBaseUrl(TSettings settings)
{
if (settings.BaseUrl.IsNullOrWhiteSpace() && IndexerUrls.First().IsNotNullOrWhiteSpace())
var defaultLink = IndexerUrls.FirstOrDefault();
if (settings.BaseUrl.IsNullOrWhiteSpace() && defaultLink.IsNotNullOrWhiteSpace())
{
settings.BaseUrl = IndexerUrls.First();
settings.BaseUrl = defaultLink;
}
else if (settings.BaseUrl.IsNotNullOrWhiteSpace() && LegacyUrls.Contains(settings.BaseUrl))
{
_logger.Debug(string.Format("Changing legacy site link from {0} to {1}", settings.BaseUrl, defaultLink));
settings.BaseUrl = defaultLink;
}
return settings;

View File

@@ -11,6 +11,7 @@ namespace NzbDrone.Core.Indexers
public class IndexerDefinition : ProviderDefinition
{
public string[] IndexerUrls { get; set; }
public string[] LegacyUrls { get; set; }
public string Description { get; set; }
public Encoding Encoding { get; set; }
public string Language { get; set; }

View File

@@ -110,6 +110,7 @@ namespace NzbDrone.Core.Indexers
}
definition.IndexerUrls = defFile.Links.ToArray();
definition.LegacyUrls = defFile.Legacylinks.ToArray();
definition.Description = defFile.Description;
definition.Language = defFile.Language;
definition.Encoding = Encoding.GetEncoding(defFile.Encoding);
@@ -205,6 +206,7 @@ namespace NzbDrone.Core.Indexers
if (definition.Implementation != typeof(Cardigann.Cardigann).Name)
{
definition.IndexerUrls = provider.IndexerUrls;
definition.LegacyUrls = provider.LegacyUrls;
definition.Privacy = provider.Privacy;
definition.Description = provider.Description;
definition.Encoding = provider.Encoding;

View File

@@ -1,5 +1,6 @@
using System;
using NzbDrone.Core.Datastore;
using NzbDrone.Core.Messaging.Commands;
namespace NzbDrone.Core.Jobs
{
@@ -9,5 +10,11 @@ namespace NzbDrone.Core.Jobs
public int Interval { get; set; }
public DateTime LastExecution { get; set; }
public DateTime LastStartTime { get; set; }
public CommandPriority Priority { get; set; }
public ScheduledTask()
{
Priority = CommandPriority.Low;
}
}
}

View File

@@ -1,4 +1,4 @@
using System.Linq;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using NLog;
@@ -39,7 +39,7 @@ namespace NzbDrone.Core.Jobs
foreach (var task in tasks)
{
_commandQueueManager.Push(task.TypeName, task.LastExecution, task.LastStartTime, CommandPriority.Low, CommandTrigger.Scheduled);
_commandQueueManager.Push(task.TypeName, task.LastExecution, task.LastStartTime, task.Priority, CommandTrigger.Scheduled);
}
}
finally

View File

@@ -2,9 +2,11 @@ using System;
using System.Collections.Generic;
using System.Linq;
using NLog;
using NzbDrone.Common.Cache;
using NzbDrone.Core.Applications;
using NzbDrone.Core.Backup;
using NzbDrone.Core.Configuration;
using NzbDrone.Core.Configuration.Events;
using NzbDrone.Core.HealthCheck;
using NzbDrone.Core.History;
using NzbDrone.Core.Housekeeping;
@@ -28,35 +30,38 @@ namespace NzbDrone.Core.Jobs
private readonly IScheduledTaskRepository _scheduledTaskRepository;
private readonly IConfigService _configService;
private readonly Logger _logger;
private readonly ICached<ScheduledTask> _cache;
public TaskManager(IScheduledTaskRepository scheduledTaskRepository, IConfigService configService, Logger logger)
public TaskManager(IScheduledTaskRepository scheduledTaskRepository, IConfigService configService, ICacheManager cacheManager, Logger logger)
{
_scheduledTaskRepository = scheduledTaskRepository;
_configService = configService;
_cache = cacheManager.GetCache<ScheduledTask>(GetType());
_logger = logger;
}
public IList<ScheduledTask> GetPending()
{
return _scheduledTaskRepository.All()
.Where(c => c.Interval > 0 && c.LastExecution.AddMinutes(c.Interval) < DateTime.UtcNow)
.ToList();
return _cache.Values
.Where(c => c.Interval > 0 && c.LastExecution.AddMinutes(c.Interval) < DateTime.UtcNow)
.ToList();
}
public List<ScheduledTask> GetAll()
{
return _scheduledTaskRepository.All().ToList();
return _cache.Values.ToList();
}
public DateTime GetNextExecution(Type type)
{
var scheduledTask = _scheduledTaskRepository.All().Single(v => v.TypeName == type.FullName);
var scheduledTask = _cache.Find(type.FullName);
return scheduledTask.LastExecution.AddMinutes(scheduledTask.Interval);
}
public void Handle(ApplicationStartedEvent message)
{
var defaultTasks = new[]
var defaultTasks = new List<ScheduledTask>
{
new ScheduledTask { Interval = 5, TypeName = typeof(MessagingCleanupCommand).FullName },
new ScheduledTask { Interval = 6 * 60, TypeName = typeof(ApplicationCheckUpdateCommand).FullName },
@@ -75,7 +80,7 @@ namespace NzbDrone.Core.Jobs
var currentTasks = _scheduledTaskRepository.All().ToList();
_logger.Trace("Initializing jobs. Available: {0} Existing: {1}", defaultTasks.Length, currentTasks.Count);
_logger.Trace("Initializing jobs. Available: {0} Existing: {1}", defaultTasks.Count, currentTasks.Count);
foreach (var job in currentTasks)
{
@@ -97,6 +102,9 @@ namespace NzbDrone.Core.Jobs
currentDefinition.LastExecution = DateTime.UtcNow;
}
currentDefinition.Priority = defaultTask.Priority;
_cache.Set(currentDefinition.TypeName, currentDefinition);
_scheduledTaskRepository.Upsert(currentDefinition);
}
}
@@ -115,8 +123,23 @@ namespace NzbDrone.Core.Jobs
if (scheduledTask != null && message.Command.Body.UpdateScheduledTask)
{
_logger.Trace("Updating last run time for: {0}", scheduledTask.TypeName);
_scheduledTaskRepository.SetLastExecutionTime(scheduledTask.Id, DateTime.UtcNow, message.Command.StartedAt.Value);
var lastExecution = DateTime.UtcNow;
_scheduledTaskRepository.SetLastExecutionTime(scheduledTask.Id, lastExecution, message.Command.StartedAt.Value);
_cache.Find(scheduledTask.TypeName).LastExecution = lastExecution;
_cache.Find(scheduledTask.TypeName).LastStartTime = message.Command.StartedAt.Value;
}
}
public void HandleAsync(ConfigSavedEvent message)
{
var backup = _scheduledTaskRepository.GetDefinition(typeof(BackupCommand));
backup.Interval = GetBackupInterval();
_scheduledTaskRepository.UpdateMany(new List<ScheduledTask> { backup });
_cache.Find(backup.TypeName).Interval = backup.Interval;
}
}
}

View File

@@ -324,5 +324,12 @@
"HistoryCleanupDaysHelpTextWarning": "سيتم تنظيف الملفات الموجودة في سلة المحذوفات الأقدم من عدد الأيام المحدد تلقائيًا",
"OnGrab": "عند الاستيلاء",
"OnHealthIssue": "في قضية الصحة",
"TestAllIndexers": "اختبار كافة المفهرسات"
"TestAllIndexers": "اختبار كافة المفهرسات",
"ConnectionLostMessage": "فقد Whisparr اتصاله بالواجهة الخلفية وسيحتاج إلى إعادة تحميله لاستعادة الوظائف.",
"Link": "الروابط",
"MappedDrivesRunningAsService": "لا تتوفر محركات أقراص الشبكة المعينة عند التشغيل كخدمة Windows. يرجى الاطلاع على التعليمات لمزيد من المعلومات",
"UnableToLoadIndexers": "تعذر تحميل المفهرسات",
"Yes": "نعم",
"GrabReleases": "انتزاع الإصدار",
"No": "لا"
}

View File

@@ -323,5 +323,13 @@
"HistoryCleanupDaysHelpTextWarning": "Файловете в кошчето, по-стари от избрания брой дни, ще се почистват автоматично",
"OnGrab": "На Граб",
"OnHealthIssue": "По здравен въпрос",
"TestAllIndexers": "Тествайте всички индексатори"
"TestAllIndexers": "Тествайте всички индексатори",
"NetCore": ".NET Core",
"GrabReleases": "Grab Release",
"Link": "Връзки",
"No": "Не",
"UnableToLoadIndexers": "Индексаторите не могат да се заредят",
"Yes": "Да",
"ConnectionLostMessage": "Whisparr е загубил връзката си с бекенда и ще трябва да се презареди, за да възстанови функционалността.",
"MappedDrivesRunningAsService": "Картографираните мрежови устройства не са налични, когато се изпълняват като услуга на Windows. Моля, вижте често задаваните въпроси за повече информация"
}

View File

@@ -325,5 +325,11 @@
"MaintenanceRelease": "Údržbové vydání: opravy chyb a další vylepšení. Další podrobnosti najdete v GitHub Commit History",
"OnGrab": "Chyť",
"OnHealthIssue": "K otázce zdraví",
"TestAllIndexers": "Vyzkoušejte všechny indexery"
"TestAllIndexers": "Vyzkoušejte všechny indexery",
"Link": "Odkazy",
"MappedDrivesRunningAsService": "Mapované síťové jednotky nejsou k dispozici, když běží jako služba Windows. Další informace najdete v častých dotazech",
"No": "Ne",
"UnableToLoadIndexers": "Nelze načíst indexery",
"Yes": "Ano",
"GrabReleases": "Uchopte uvolnění"
}

View File

@@ -327,5 +327,12 @@
"HistoryCleanupDaysHelpTextWarning": "Filer i papirkurven, der er ældre end det valgte antal dage, renses automatisk",
"OnGrab": "On Grab",
"OnHealthIssue": "Om sundhedsspørgsmål",
"TestAllIndexers": "Test alle indeksører"
"TestAllIndexers": "Test alle indeksører",
"GrabReleases": "Grab Release",
"Link": "Links",
"MappedDrivesRunningAsService": "Kortlagte netværksdrev er ikke tilgængelige, når de kører som en Windows-tjeneste. Se FAQ for mere information",
"No": "Ingen",
"NetCore": ".NET Core",
"UnableToLoadIndexers": "Kan ikke indlæse indeksatorer",
"Yes": "Ja"
}

View File

@@ -426,5 +426,14 @@
"SemiPrivate": "Halbprivat",
"UnableToLoadApplicationList": "Anwendungsliste kann nicht geladen werden",
"UnableToLoadIndexerProxies": "Indexer-Proxies können nicht geladen werden",
"Website": "Webseite"
"Website": "Webseite",
"Application": "Anwendungen",
"GrabReleases": "Release erfassen",
"Link": "Links",
"MappedDrivesRunningAsService": "Zugeordnete Netzlaufwerke sind nicht verfügbar, wenn Radarr als Windows-Dienst ausgeführt wird. Bitte lesen Sie die FAQ für weitere Informationen",
"No": "Nein",
"SearchTypes": "Suchtyp",
"TVSearchTypes": "Suchtyp",
"UnableToLoadIndexers": "Indexer konnten nicht geladen werden",
"Yes": "Ja"
}

View File

@@ -327,5 +327,12 @@
"OnHealthIssue": "Σχετικά με το θέμα της υγείας",
"TestAllIndexers": "Δοκιμάστε όλους τους δείκτες",
"MaintenanceRelease": "Έκδοση συντήρησης: επιδιορθώσεις σφαλμάτων και άλλες βελτιώσεις. Δείτε το Github Commit History για περισσότερες λεπτομέρειες",
"ConnectionLostMessage": "Το Radarr έχασε τη σύνδεσή του με το backend και θα χρειαστεί να επαναφορτωθεί για να αποκαταστήσει τη λειτουργικότητά του."
"ConnectionLostMessage": "Το Radarr έχασε τη σύνδεσή του με το backend και θα χρειαστεί να επαναφορτωθεί για να αποκαταστήσει τη λειτουργικότητά του.",
"NetCore": ".NET Core",
"GrabReleases": "Πιάσε την απελευθέρωση",
"Link": "Συνδέσεις",
"MappedDrivesRunningAsService": "Οι αντιστοιχισμένες μονάδες δίσκου δικτύου δεν είναι διαθέσιμες κατά την εκτέλεση ως υπηρεσία Windows. Ανατρέξτε στις Συχνές Ερωτήσεις για περισσότερες πληροφορίες",
"No": "Οχι",
"UnableToLoadIndexers": "Δεν είναι δυνατή η φόρτωση του ευρετηρίου",
"Yes": "Ναί"
}

View File

@@ -18,7 +18,7 @@
"Date": "Fecha",
"CustomFilters": "Filtros Personalizados",
"Connections": "Conexiones",
"Connect": "Conectar",
"Connect": "Notificaciones",
"Clear": "Borrar",
"BackupNow": "Hacer copia de seguridad",
"Backup": "Backup",
@@ -146,7 +146,7 @@
"ClientPriority": "Prioridad de Cliente",
"ChangeHasNotBeenSavedYet": "El cambio aún no se ha guardado",
"CertificateValidationHelpText": "Cambiar la rigidez de la validación de la certificación HTTPS",
"CertificateValidation": "Validación de certificado",
"CertificateValidation": "Validación del certificado",
"BypassProxyForLocalAddresses": "Omitir Proxy para Direcciones Locales",
"Branch": "Rama",
"BindAddressHelpText": "Dirección IP4 válida o '*' para todas las interfaces",
@@ -318,7 +318,7 @@
"Yesterday": "Ayer",
"ApplicationStatusCheckAllClientMessage": "Las listas no están disponibles debido a errores",
"ApplicationStatusCheckSingleClientMessage": "Listas no disponibles debido a errores: {0}",
"AllIndexersHiddenDueToFilter": "Todas las películas están ocultas debido al filtro aplicado.",
"AllIndexersHiddenDueToFilter": "Todos los indexadores están ocultas debido al filtro aplicado.",
"DeleteApplicationMessageText": "Seguro que quieres elminiar la notificación '{0}'?",
"IndexerProxyStatusCheckAllClientMessage": "Los indexers no están disponibles debido a errores",
"IndexerProxyStatusCheckSingleClientMessage": "Indexers no disponibles debido a errores: {0}",
@@ -337,5 +337,32 @@
"TestAllIndexers": "Comprobar Todos los Indexers",
"NotificationTriggersHelpText": "Seleccione qué eventos deben activar esta notificación",
"OnApplicationUpdate": "Al actualizar la aplicación",
"OnApplicationUpdateHelpText": "Al actualizar la aplicación"
"OnApplicationUpdateHelpText": "Al actualizar la aplicación",
"AddAppProfile": "Añadir sincronización de perfil de aplicación",
"AddRemoveOnly": "Sólo añadir y eliminar",
"AddedToDownloadClient": "Descarga añadida al cliente",
"AddNewIndexer": "Añadir nuevo indexador",
"AddToDownloadClient": "Añadir descarga al cliente de descargas",
"Applications": "Aplicaciones",
"AppProfileDeleteConfirm": "¿Seguro que quieres eliminar {0}?",
"AppProfileInUse": "Perfil de aplicación en uso",
"AddDownloadClientToProwlarr": "Añadir un cliente de descargas permite a Prowlarr enviar descargas directamente desde la interfaz en una búsqueda manual.",
"Category": "Categoría",
"Application": "Aplicación",
"AppProfile": "Perfil de aplicación",
"AppProfiles": "Perfiles de aplicaciones",
"BookSearch": "Búsqueda de libros",
"BookSearchTypes": "Tipos de búsqueda de libros",
"Categories": "Categorías",
"AddIndexerProxy": "Añadir proxy del indexador",
"Encoding": "Codificación",
"GrabReleases": "Capturar Estreno",
"Link": "Enlaces",
"MappedDrivesRunningAsService": "Las unidades de red asignadas no están disponibles cuando se ejecutan como un servicio de Windows. Consulte las preguntas frecuentes para obtener más información",
"No": "No",
"Notification": "Notificaciones",
"Notifications": "Notificaciones",
"UnableToLoadIndexers": "No se pueden cargar los indexers",
"Yes": "si",
"UserAgentProvidedByTheAppThatCalledTheAPI": "User-Agent proporcionado por la aplicación llamó a la API"
}

View File

@@ -2,7 +2,7 @@
"IndexerProxyStatusCheckSingleClientMessage": "Välityspalvelimet eivät ole käytettävissä virheiden vuoksi: {0}",
"Logging": "Kirjaus",
"LogLevel": "Kirjauksen taso",
"MovieIndexScrollTop": "Elokuvahakemisto: vieritä ylös",
"MovieIndexScrollTop": "Elokuvakirjasto: vieritä ylös",
"Apply": "Käytä",
"ClientPriority": "Lataustyökalun painotus",
"IndexerPriorityHelpText": "Tietolähteen painotus: 1 (korkein) - 50 (matalin). Oletusarvo on 25. Käytetään muutoin tasaveroisten julkaisujen sieppauspäätökseen. Kaikkia käytössä olevia tietolähteitä käytetään edelleen RSS-synkronointiin ja hakuun.",
@@ -10,7 +10,7 @@
"Add": "Lisää",
"Reload": "Lataa uudelleen",
"Indexers": "Tietolähteet",
"MovieIndexScrollBottom": "Elokuvahakemisto: vieritä alas",
"MovieIndexScrollBottom": "Elokuvakirjasto: vieritä alas",
"PtpOldSettingsCheckMessage": "Seuraavat PassThePopcorn-tietolähteet sisältävät vanhentuneita asetuksia, jotka olisi syytä päivittää: {0}",
"SSLCertPassword": "SSL-varmenteen salasana",
"Style": "Tyyli",
@@ -432,7 +432,17 @@
"Link": "Linkit",
"SearchTypes": "Mitä etsitään",
"UnableToLoadIndexers": "Tietolähteiden lataus epäonnistui.",
"Yes": "Joo",
"Yes": "Kyllä",
"MappedDrivesRunningAsService": "Yhdistetyt verkkoasemat eivät ole käytettävissä, kun niitä käytetään Windows-palveluna. Katso lisätietoja UKK: sta",
"No": "Ei"
"No": "Ei",
"BookSearchTypes": "Kirjojen hakutyypit",
"IndexerDetails": "Tietolähteen tiedot",
"IndexerName": "Tietolähteen nimi",
"IndexerSite": "Tietolähteen sivusto",
"MovieSearchTypes": "Elokuvien hakutyypit",
"MusicSearchTypes": "Musiikin hakutyypit",
"NotSupported": "Ei tuettu",
"RawSearchSupported": "Raakahaku tuettu",
"SearchCapabilities": "Hakuominaisuudet",
"TVSearchTypes": "Televisiosarjojen hakutyypit"
}

View File

@@ -12,7 +12,7 @@
"Events": "Événements",
"Edit": "Éditer",
"DownloadClientStatusCheckAllClientMessage": "Aucun client de téléchargement n'est disponible en raison d'échecs",
"DownloadClients": "Clients Télécharg.",
"DownloadClients": "Clients de téléchargement",
"Dates": "Dates",
"Date": "Date",
"Delete": "Supprimer",
@@ -22,11 +22,11 @@
"Clear": "Effacer",
"BackupNow": "Sauvegarder maintenant",
"Backup": "Sauvegarde",
"AppDataLocationHealthCheckMessage": "Mettre à jour ne sera pas possible pour éviter la suppression AppData lors de la mise à jour",
"AppDataLocationHealthCheckMessage": "Mettre à jour ne sera pas possible afin d'éviter de supprimer le dossier AppData lors de la mise à jour",
"Analytics": "Analytique",
"All": "Tout",
"About": "À propos",
"IndexerStatusCheckSingleClientMessage": "Indexeurs indisponibles en raison d'échecs: {0}",
"IndexerStatusCheckSingleClientMessage": "Indexeurs indisponibles en raison d'échecs : {0}",
"DownloadClientStatusCheckSingleClientMessage": "Clients de Téléchargement indisponibles en raison d'échecs: {0}",
"SetTags": "Définir Tags",
"ReleaseStatus": "Statut de la version",
@@ -354,7 +354,7 @@
"Applications": "Applications",
"AppProfileDeleteConfirm": "Voulez-vous vraiment supprimer {0} ?",
"AppProfileInUse": "Profil d'application en cours d'utilisation",
"Apps": "Apps",
"Apps": "Applications",
"Auth": "Auth",
"Category": "Catégorie",
"Custom": "Personnalisé",
@@ -373,7 +373,7 @@
"UnableToAddANewAppProfilePleaseTryAgain": "Impossible d'ajouter un nouveau profil d'application, veuillez réessayer.",
"UnableToLoadAppProfiles": "Impossible de charger les profils d'application",
"Add": "Ajouter",
"SyncLevelFull": "Synchronisation complète : gardera cette application entièrement synchronisée. Les modifications apportées dans Prowlarr sont ensuite synchronisées avec cette application. Toute modification effectuée à distance sera annulée par Prowlarr lors de la prochaine synchronisation.",
"SyncLevelFull": "Synchronisation complète : Maintiendra les indexeurs de cette application entièrement synchronisés. Les modifications apportées aux indexeurs dans Prowlarr sont ensuite synchronisées avec cette application. Toute modification effectuée sur les indexeurs dans l'application sera annulée par Prowlarr lors de la prochaine synchronisation.",
"SyncLevelAddRemove": "Ajouter et supprimer uniquement : lorsque les indexeurs sont ajoutés ou supprimés de Prowlarr, ils mettront à jour cette application à distance.",
"SyncLevel": "Niveau de synchronisation",
"FullSync": "Synchronisation complète",
@@ -407,7 +407,7 @@
"Database": "Base de données",
"HistoryCleanup": "Nettoyage de l'historique",
"IndexerAlreadySetup": "Au moins une instance de l'indexeur est déjà configurée",
"IndexerInfo": "Info de l'indexeur",
"IndexerInfo": "Info sur l'indexeur",
"Private": "Privé",
"Proxies": "Proxies",
"Public": "Publique",
@@ -417,7 +417,7 @@
"QueryOptions": "Options de recherche",
"SearchType": "Type de recherche",
"Categories": "Catégories",
"MassEditor": "Éditeur de masse",
"MassEditor": "Éditer en masse",
"UnableToLoadApplicationList": "Impossible de charger la liste des applications",
"Website": "Site internet",
"AudioSearch": "Recherche de musique",
@@ -426,5 +426,23 @@
"OnApplicationUpdateHelpText": "Lors de la mise à jour de l'app",
"IndexerNoDefCheckMessage": "Les indexeurs ne sont pas définis et ne fonctionneront pas :Merci de les retirer et (ou) les ajouter à nouveau à Prowlarr",
"MovieSearch": "Recherche de films",
"TvSearch": "Recherche de séries TV"
"TvSearch": "Recherche de séries TV",
"Application": "Applications",
"GrabReleases": "Télécharger la/les version(s)",
"Link": "Lien",
"No": "Non",
"SearchTypes": "Types de recherche",
"TVSearchTypes": "Types de recherche de séries/émissions",
"UnableToLoadIndexers": "Impossible de charger les indexeurs",
"Yes": "Oui",
"MappedDrivesRunningAsService": "Les lecteurs réseau mappés ne sont pas disponibles en fonctionnement en tant que service Windows. Veuillez consulter la FAQ pour plus d'informations",
"IndexerDetails": "Détails sur l'indexeur",
"RawSearchSupported": "Recherche brute supportée",
"BookSearchTypes": "Type de recherche de livres",
"IndexerName": "Nom de l'indexeur",
"IndexerSite": "Site de l'indexeur",
"MovieSearchTypes": "Types de recherches de films",
"MusicSearchTypes": "Type de recherche de musiques",
"NotSupported": "Non supporté",
"SearchCapabilities": "Capacités de recherche"
}

View File

@@ -323,5 +323,13 @@
"HistoryCleanupDaysHelpTextWarning": "קבצים בסל המיחזור ישנים יותר ממספר הימים שנבחר ינוקו באופן אוטומטי",
"OnGrab": "על לתפוס",
"OnHealthIssue": "בנושא הבריאות",
"TestAllIndexers": "בדוק את כל האינדקסים"
"TestAllIndexers": "בדוק את כל האינדקסים",
"ConnectionLostMessage": "Whisparr איבד את החיבור ל- backend ויהיה צורך לטעון אותו מחדש כדי לשחזר את הפונקציונליות.",
"GrabReleases": "שחרור תפוס",
"Link": "קישורים",
"NetCore": ".NET Core",
"No": "לא",
"UnableToLoadIndexers": "לא ניתן לטעון אינדקסים",
"Yes": "כן",
"MappedDrivesRunningAsService": "כונני רשת ממופים אינם זמינים כאשר הם פועלים כשירות Windows. אנא עיין בשאלות הנפוצות למידע נוסף"
}

View File

@@ -323,5 +323,13 @@
"MaintenanceRelease": "रखरखाव रिलीज: बग फिक्स और अन्य सुधार। अधिक जानकारी के लिए गितुब कमिट इतिहास देखें",
"Filters": "फ़िल्टर",
"HistoryCleanupDaysHelpText": "स्वचालित सफाई को अक्षम करने के लिए 0 पर सेट करें",
"HistoryCleanupDaysHelpTextWarning": "रीसायकल बिन में चयनित दिनों की तुलना में पुरानी फाइलें अपने आप साफ हो जाएंगी"
"HistoryCleanupDaysHelpTextWarning": "रीसायकल बिन में चयनित दिनों की तुलना में पुरानी फाइलें अपने आप साफ हो जाएंगी",
"NetCore": ".NET कोर",
"ConnectionLostMessage": "रैडियर ने बैकएंड से कनेक्शन खो दिया है और कार्यक्षमता को बहाल करने के लिए इसे फिर से लोड करना होगा।",
"GrabReleases": "पकड़ो रिलीज",
"Yes": "हाँ",
"Link": "लिंक",
"MappedDrivesRunningAsService": "विंडोज सर्विस के रूप में चलने पर मैप्ड नेटवर्क ड्राइव उपलब्ध नहीं हैं। अधिक जानकारी के लिए कृपया FAQ देखें",
"No": "नहीं",
"UnableToLoadIndexers": "अनुक्रमणिका लोड करने में असमर्थ"
}

View File

@@ -426,5 +426,23 @@
"UnableToLoadApplicationList": "Nem sikerült betölteni az alkalmazáslistát",
"Url": "URL",
"UserAgentProvidedByTheAppThatCalledTheAPI": "Az API-t hívó alkalmazás biztosítja a User-Agent szolgáltatást",
"Website": "Weboldal"
"Website": "Weboldal",
"Application": "Alkalmazások",
"GrabReleases": "Release megragadása",
"UnableToLoadIndexers": "Nem lehet betölteni az indexereket",
"Yes": "Igen",
"Link": "Linkek",
"MappedDrivesRunningAsService": "A hozzárendelt hálózati meghajtók nem érhetők el, ha Windows szolgáltatásként futnak. További információkért olvasd át a GYIK-et",
"No": "Nem",
"SearchTypes": "Keresés típusa",
"BookSearchTypes": "Könyvkeresés típusai",
"IndexerDetails": "Indexer adatai",
"IndexerName": "Indexer neve",
"IndexerSite": "Indexer oldal",
"MovieSearchTypes": "Filmkeresés típusai",
"MusicSearchTypes": "Zenekeresés típusai",
"NotSupported": "Nem támogatott",
"RawSearchSupported": "Nyers keresés támogatott",
"SearchCapabilities": "Keresési lehetőségek",
"TVSearchTypes": "TV-Sorozat keresési típusok"
}

View File

@@ -323,5 +323,13 @@
"HistoryCleanupDaysHelpTextWarning": "Skrár í ruslakörfunni eldri en valinn fjöldi daga verða hreinsaðir upp sjálfkrafa",
"OnGrab": "Á grípa",
"OnHealthIssue": "Um heilbrigðismál",
"TestAllIndexers": "Prófaðu alla verðtryggjendur"
"TestAllIndexers": "Prófaðu alla verðtryggjendur",
"NetCore": ".NET algerlega",
"GrabReleases": "Grípa losun",
"Link": "Krækjur",
"MappedDrivesRunningAsService": "Kortlagðar netdrif eru ekki fáanlegar þegar þær eru keyrðar sem Windows þjónusta. Vinsamlegast skoðaðu algengar spurningar fyrir frekari upplýsingar",
"No": "Nei",
"UnableToLoadIndexers": "Ekki er hægt að hlaða Indexers",
"Yes": "Já",
"ConnectionLostMessage": "Whisparr hefur misst tenginguna við bakendann og þarf að endurhlaða hann til að endurheimta virkni."
}

View File

@@ -349,5 +349,11 @@
"OnGrab": "Quando viene prelevato",
"OnHealthIssue": "Quando c'è un problema",
"TestAllIndexers": "Testa tutti gli indexer",
"UserAgentProvidedByTheAppThatCalledTheAPI": "User-Agent esposto dalla app che ha chiamato la API"
"UserAgentProvidedByTheAppThatCalledTheAPI": "User-Agent esposto dalla app che ha chiamato la API",
"GrabReleases": "Preleva Release",
"Link": "Collegamenti",
"MappedDrivesRunningAsService": "I drive di rete mappati non sono disponibili eseguendo come servizio di Windows. Vedere le FAQ per maggiori informazioni",
"No": "No",
"UnableToLoadIndexers": "Non riesco a caricare l'indexer",
"Yes": "Si"
}

View File

@@ -323,5 +323,13 @@
"HistoryCleanupDaysHelpText": "自動クリーンアップを無効にするには、0に設定します",
"OnGrab": "グラブで",
"TestAllIndexers": "すべてのインデクサーをテストする",
"MaintenanceRelease": "メンテナンスリリースバグ修正およびその他の改善。詳細については、Githubのコミット履歴を参照してください"
"MaintenanceRelease": "メンテナンスリリースバグ修正およびその他の改善。詳細については、Githubのコミット履歴を参照してください",
"NetCore": ".NET Core",
"GrabReleases": "グラブリリース",
"Link": "リンク",
"MappedDrivesRunningAsService": "マップされたネットワークドライブは、Windowsサービスとして実行している場合は使用できません。詳細については、FAQを参照してください",
"No": "番号",
"UnableToLoadIndexers": "インデクサーを読み込めません",
"Yes": "はい",
"ConnectionLostMessage": "Whisparrはバックエンドへの接続を失ったため、機能を復元するには再ロードする必要があります。"
}

View File

@@ -240,5 +240,96 @@
"HistoryCleanupDaysHelpTextWarning": "선택한 일 수보다 오래된 휴지통에있는 파일은 자동으로 정리됩니다.",
"OnGrab": "잡기",
"OnHealthIssue": "건강 문제",
"TestAllIndexers": "모든 인덱서 테스트"
"TestAllIndexers": "모든 인덱서 테스트",
"Filters": "필터",
"FocusSearchBox": "포커스 검색 창",
"GeneralSettingsSummary": "포트, SSL, 사용자 이름 / 암호, 프록시, 분석 및 업데이트",
"HideAdvanced": "고급 숨기기",
"IndexerStatusCheckAllClientMessage": "오류로 인해 모든 인덱서를 사용할 수 없습니다.",
"InteractiveSearch": "대화형 검색",
"LastWriteTime": "마지막 쓰기 시간",
"Link": "연결",
"MaintenanceRelease": "유지 관리 출시 : 버그 수정 및 기타 개선. 자세한 내용은 Github 커밋 내역을 참조하십시오.",
"Manual": "설명서",
"MappedDrivesRunningAsService": "Windows 서비스로 실행할 때는 매핑 된 네트워크 드라이브를 사용할 수 없습니다. 자세한 내용은 FAQ를 참조하십시오.",
"No": "아니",
"NoLinks": "링크 없음",
"PendingChangesMessage": "저장하지 않은 변경 사항이 있습니다.이 페이지에서 나가시겠습니까?",
"PendingChangesStayReview": "변경 사항 유지 및 검토",
"Presets": "사전 설정",
"ProxyCheckResolveIpMessage": "구성된 프록시 호스트 {0}의 IP 주소를 확인하지 못했습니다.",
"PtpOldSettingsCheckMessage": "다음 PassThePopcorn 인덱서에는 더 이상 사용되지 않는 설정이 있으며 업데이트해야합니다. {0}",
"Reddit": "레딧",
"TagsSettingsSummary": "모든 태그와 사용 방법을 확인하십시오. 사용하지 않는 태그는 제거 할 수 있습니다.",
"Yesterday": "어제",
"ApplicationStatusCheckAllClientMessage": "실패로 인해 모든 목록을 사용할 수 없습니다.",
"ApplicationStatusCheckSingleClientMessage": "실패로 인해 사용할 수없는 목록 : {0}",
"ReleaseBranchCheckOfficialBranchMessage": "{0} 분기는 유효한 Whisparr 출시 분기가 아닙니다. 업데이트를받을 수 없습니다.",
"ProxyCheckBadRequestMessage": "프록시를 테스트하지 못했습니다. StatusCode : {0}",
"ProxyCheckFailedToTestMessage": "프록시 테스트 실패 : {0}",
"ReleaseStatus": "출시 상태",
"RSS": "RSS",
"Sort": "종류",
"UnsavedChanges": "저장되지 않은 변경 사항",
"UnselectAll": "모두 선택 해제",
"Shutdown": "종료",
"Grabbed": "잡았다",
"General": "일반",
"OAuthPopupMessage": "브라우저에서 팝업을 차단하고 있습니다.",
"Ok": "확인",
"OpenThisModal": "이 모달 열기",
"RefreshMovie": "영화 새로 고침",
"SuggestTranslationChange": "번역 변경 제안",
"Level": "수평",
"UpdateCheckStartupTranslocationMessage": "시작 폴더 '{0}'이 (가) App Translocation 폴더에 있으므로 업데이트를 설치할 수 없습니다.",
"UrlBaseHelpText": "역방향 프록시 지원의 경우 기본값은 비어 있습니다.",
"MovieIndexScrollBottom": "영화 색인 : 아래로 스크롤",
"View": "전망",
"Wiki": "위키",
"EditIndexer": "인덱서 편집",
"Filter": "필터",
"Health": "건강",
"HealthNoIssues": "구성에 문제 없음",
"Info": "정보",
"KeyboardShortcuts": "키보드 단축키",
"MovieIndexScrollTop": "영화 색인 : 상단 스크롤",
"NoTagsHaveBeenAddedYet": "아직 추가 된 태그가 없습니다.",
"PendingChangesDiscardChanges": "변경 사항을 취소하고 나가기",
"Priority": "우선 순위",
"PriorityHelpText": "여러 다운로드 클라이언트의 우선 순위를 지정합니다. 라운드 로빈은 우선 순위가 같은 클라이언트에 사용됩니다.",
"PrioritySettings": "우선 순위",
"SetTags": "태그 설정",
"System": "체계",
"UpdateCheckUINotWritableMessage": "사용자 '{1}'이 (가) UI 폴더 '{0}'에 쓸 수 없기 때문에 업데이트를 설치할 수 없습니다.",
"Warn": "경고",
"HomePage": "홈 페이지",
"Peers": "동료",
"Discord": "불일치",
"Error": "오류",
"Events": "이벤트",
"EventType": "이벤트 유형",
"Failed": "실패한",
"FeatureRequests": "기능 요청",
"IndexerFlags": "인덱서 플래그",
"IndexerLongTermStatusCheckAllClientMessage": "6 시간 이상 오류로 인해 모든 인덱서를 사용할 수 없습니다.",
"IndexerLongTermStatusCheckSingleClientMessage": "6 시간 이상 오류로 인해 인덱서를 사용할 수 없음 : {0}",
"IndexerProxyStatusCheckAllClientMessage": "오류로 인해 모든 인덱서를 사용할 수 없습니다.",
"IndexerProxyStatusCheckSingleClientMessage": "오류로 인해 인덱서를 사용할 수 없음 : {0}",
"IndexerStatusCheckSingleClientMessage": "오류로 인해 인덱서를 사용할 수 없음 : {0}",
"NetCore": ".NET Core",
"Save": "저장",
"SaveSettings": "설정 저장",
"Seeders": "시더",
"SelectAll": "모두 선택",
"ShowAdvanced": "고급보기",
"SystemTimeCheckMessage": "시스템 시간이 1 일 이상 꺼져 있습니다. 예약 된 작업은 시간이 수정 될 때까지 올바르게 실행되지 않을 수 있습니다.",
"TableOptions": "테이블 옵션",
"TableOptionsColumnsMessage": "표시되는 열과 표시되는 순서 선택",
"TagsHelpText": "일치하는 태그가 하나 이상있는 영화에 적용됩니다.",
"Test": "테스트",
"Time": "시간",
"UnableToLoadIndexers": "인덱서를로드 할 수 없습니다.",
"UpdateCheckStartupNotWritableMessage": "'{1}'사용자가 '{0}'시작 폴더에 쓸 수 없기 때문에 업데이트를 설치할 수 없습니다.",
"Yes": "예",
"GrabReleases": "그랩 릴리스"
}

View File

@@ -50,7 +50,7 @@
"Logging": "Logbeheer",
"LogFiles": "Logbestanden",
"Language": "Taal",
"ShowAdvanced": "Toon Gevorderd",
"ShowAdvanced": "Toon Geavanceerd",
"UpdateCheckUINotWritableMessage": "Kan de update niet installeren omdat de UI map '{0}' niet schrijfbaar is voor de gebruiker '{1}'.",
"UpdateCheckStartupTranslocationMessage": "Kan de update niet installeren omdat de map '{0}' zich in een 'App Translocation' map bevindt.",
"UpdateCheckStartupNotWritableMessage": "Kan de update niet installeren omdat de map '{0}' niet schrijfbaar is voor de gebruiker '{1}'.",
@@ -401,7 +401,17 @@
"HistoryCleanupDaysHelpTextWarning": "Bestanden in de prullenbak ouder dan het geselecteerde aantal dagen zullen automatisch opgeschoond worden",
"OnGrab": "Bij Ophalen",
"OnHealthIssue": "Bij Gezondheidsprobleem",
"Filters": "Filter",
"Filters": "Filters",
"TestAllIndexers": "Test Alle Indexeerders",
"UserAgentProvidedByTheAppThatCalledTheAPI": "User-Agent geleverd door de app die de API heeft aangeroepen"
"UserAgentProvidedByTheAppThatCalledTheAPI": "User-Agent geleverd door de app die de API heeft aangeroepen",
"Application": "Applicaties",
"Link": "Koppelingen",
"MappedDrivesRunningAsService": "Toegewezen netwerkstation is niet beschikbaar wanneer Radarr wordt uitgevoerd als een Windows Service. Bekijk de Veelgestelde Vragen voor meer informatie",
"No": "Nee",
"UnableToLoadIndexers": "Indexeerders kunnen niet worden geladen",
"GrabReleases": "Uitgave Ophalen",
"Yes": "Ja",
"OnApplicationUpdateHelpText": "Bij applicatie update",
"Database": "Databasis",
"OnApplicationUpdate": "Bij applicatie update"
}

View File

@@ -323,5 +323,13 @@
"HistoryCleanupDaysHelpText": "Ustaw na 0, aby wyłączyć automatyczne czyszczenie",
"OnGrab": "Na Grab",
"OnHealthIssue": "W kwestii zdrowia",
"TestAllIndexers": "Przetestuj wszystkie indeksatory"
"TestAllIndexers": "Przetestuj wszystkie indeksatory",
"ConnectionLostMessage": "Whisparr utracił połączenie z zapleczem i będzie musiał zostać ponownie załadowany, aby przywrócić funkcjonalność.",
"GrabReleases": "Grab Release",
"No": "Nie",
"NetCore": ".NET Core",
"UnableToLoadIndexers": "Nie można załadować indeksatorów",
"Link": "Spinki do mankietów",
"MappedDrivesRunningAsService": "Zmapowane dyski sieciowe nie są dostępne, gdy działają jako usługa systemu Windows. Więcej informacji można znaleźć w FAQ",
"Yes": "tak"
}

View File

@@ -395,5 +395,14 @@
"TestAllIndexers": "Testar todos os indexadores",
"UserAgentProvidedByTheAppThatCalledTheAPI": "Par Utilizador-Agente fornecido pela aplicação que chamou a API",
"OnApplicationUpdate": "Quando a aplicação atualizar",
"OnApplicationUpdateHelpText": "Quando a aplicação atualizar"
"OnApplicationUpdateHelpText": "Quando a aplicação atualizar",
"Database": "base de dados",
"HistoryCleanupDaysHelpTextWarning": "Ficheiros na reciclagem serão eliminados automaticamente após o número de dias selecionado",
"Application": "Aplicações",
"Link": "Ligações",
"MappedDrivesRunningAsService": "As unidades de rede mapeadas não estão disponíveis quando executadas como um serviço do Windows. Veja as Perguntas mais frequentes para obter mais informações",
"No": "Não",
"UnableToLoadIndexers": "Não foi possível carregar os indexadores",
"Yes": "Sim",
"GrabReleases": "Capturar versão"
}

View File

@@ -40,13 +40,13 @@
"SSLCertPasswordHelpText": "Senha para arquivo pfx",
"StartupDirectory": "Diretório de inicialização",
"SuggestTranslationChange": "Sugerir alteração para a tradução",
"SystemTimeCheckMessage": "A hora do sistema está errada por mais de 1 dia. As tarefas agendadas podem não funcionar corretamente até que a hora seja corrigida",
"SystemTimeCheckMessage": "A hora do sistema está desligada por mais de 1 dia. As tarefas agendadas podem não ser executadas corretamente até que a hora seja corrigida",
"TagsHelpText": "Aplica-se a indexadores com pelo menos uma tag correspondente",
"UILanguageHelpText": "Idioma que o Prowlarr usará para a interface",
"UnableToAddANewIndexerPleaseTryAgain": "Não foi possível adicionar um novo indexador, tente novamente.",
"UnableToLoadGeneralSettings": "Não foi possível carregar as configurações gerais",
"UpdateAutomaticallyHelpText": "Baixar e instalar atualizações automaticamente. Você ainda poderá instalar a partir de Sistema: Atualizações",
"UpdateCheckStartupTranslocationMessage": "Não é possível instalar a atualização porque a pasta de inicialização \"{0}\" está em uma pasta de transposição de aplicativos.",
"UpdateCheckStartupTranslocationMessage": "Não é possível instalar a atualização porque a pasta de inicialização '{0}' está em uma pasta App Translocation.",
"UrlBaseHelpText": "Para suporte de proxy reverso, o padrão é vazio",
"Actions": "Ações",
"Added": "Adicionado",
@@ -174,7 +174,7 @@
"Logging": "Registro em log",
"LogLevel": "Nível do log",
"LogLevelTraceHelpTextWarning": "O registro de rastreamento deve ser ativado apenas temporariamente",
"Logs": "Logs",
"Logs": "Registros",
"MaintenanceRelease": "Lançamento de manutenção: correções de bugs e outras melhorias. Veja o histórico de mudanças no github para mais detalhes",
"Manual": "Manual",
"Mechanism": "Mecanismo",
@@ -211,9 +211,9 @@
"ProwlarrSupportsAnyDownloadClient": "O Prowlarr é compatível com todos os clientes de download listados abaixo.",
"Proxy": "Proxy",
"ProxyBypassFilterHelpText": "Usar \",\" como separador e \"*.\" como curinga para subdomínios",
"ProxyCheckBadRequestMessage": "Falha ao testar o proxy. StatusCode: {0}",
"ProxyCheckBadRequestMessage": "Falha ao testar o proxy. Código de Status: {0}",
"ProxyCheckFailedToTestMessage": "Falha ao testar o proxy: {0}",
"ProxyCheckResolveIpMessage": "Falha ao solucionar o Endereço IP para o Host de proxy configurado {0}",
"ProxyCheckResolveIpMessage": "Falha ao resolver o endereço IP para o host proxy configurado {0}",
"ProxyPasswordHelpText": "Você só precisa inserir um nome de usuário e uma senha se solicitado. Caso contrário, deixe em branco.",
"ProxyType": "Tipo de proxy",
"PtpOldSettingsCheckMessage": "As configurações dos seguintes indexadores do PassThePopcorn são obsoletas e devem ser atualizadas: {0}",
@@ -306,7 +306,7 @@
"UnableToLoadUISettings": "Não foi possível carregar as configurações da interface",
"UnsavedChanges": "Alterações não salvas",
"UnselectAll": "Desmarcar tudo",
"UpdateCheckStartupNotWritableMessage": "Não é possível instalar a atualização porque a pasta de inicialização \"{0}\" não pode ser acessada pelo usuário \"{1}\".",
"UpdateCheckStartupNotWritableMessage": "Não é possível instalar a atualização porque a pasta de inicialização '{0}' não pode ser gravada pelo usuário '{1}'.",
"UpdateCheckUINotWritableMessage": "Não é possível instalar a atualização porque a pasta de interface do usuário '{0}' não é gravável pelo usuário '{1}'.",
"UpdateMechanismHelpText": "Usar o atualizador embutido do Prowlarr ou um script",
"Updates": "Atualizações",
@@ -426,5 +426,23 @@
"SemiPrivate": "Semi-Privado",
"UnableToLoadApplicationList": "Não é possível carregar a lista de aplicativos",
"Url": "Url",
"Website": "Website"
"Website": "Website",
"IndexerDetails": "Detalhes do Indexador",
"IndexerName": "Nome do Indexador",
"IndexerSite": "Site do Indexador",
"MovieSearchTypes": "Tipos de Pesquisa de Filmes",
"MusicSearchTypes": "Tipos de Pesquisa de Músicas",
"NotSupported": "Não Suportado",
"RawSearchSupported": "Pesquisa Bruta Suportada",
"SearchCapabilities": "Recursos de Pesquisa",
"TVSearchTypes": "Tipos de Pesquisa de Seriados",
"BookSearchTypes": "Tipos de Pesquisa de Livros",
"SearchTypes": "Tipo de Pesquisa",
"UnableToLoadIndexers": "Não foi possível carregar os indexadores",
"Yes": "Sim",
"Application": "Aplicativos",
"GrabReleases": "Capturar Versão",
"Link": "Link",
"MappedDrivesRunningAsService": "As unidades de rede mapeadas não estão disponíveis quando executadas como um serviço do Windows. Consulte as Perguntas frequentes para saber mais",
"No": "Não"
}

View File

@@ -328,5 +328,12 @@
"HistoryCleanupDaysHelpTextWarning": "Fișierele din coșul de reciclare mai vechi de numărul de zile selectat vor fi curățate automat",
"OnGrab": "Pe Grab",
"OnHealthIssue": "Cu privire la problema sănătății",
"TestAllIndexers": "Testați toți indexatorii"
"TestAllIndexers": "Testați toți indexatorii",
"Link": "Link-uri",
"NetCore": ".NET Core",
"UnableToLoadIndexers": "Imposibil de încărcat indexatori",
"GrabReleases": "Grab Release",
"MappedDrivesRunningAsService": "Unitățile de rețea mapate nu sunt disponibile atunci când rulează ca serviciu Windows. Vă rugăm să consultați FAQ pentru mai multe informații",
"No": "Nu",
"Yes": "da"
}

View File

@@ -328,5 +328,12 @@
"OnApplicationUpdate": "О обновлении приложения",
"TestAllIndexers": "Тестировать все индексаторы",
"UserAgentProvidedByTheAppThatCalledTheAPI": "User-Agent, представленный приложением, который вызывает API",
"NotificationTriggersHelpText": "Выберите, какие события должны вызвать это уведомление"
"NotificationTriggersHelpText": "Выберите, какие события должны вызвать это уведомление",
"NetCore": ".NET",
"GrabReleases": "Захватить релиз",
"UnableToLoadIndexers": "Не удалось загрузить индексаторы",
"Link": "Ссылки",
"MappedDrivesRunningAsService": "Подключённые сетевые диски недоступны, если программа запущена как сервис. Обратитесь в FAQ за дополнительной информацией",
"No": "Нет",
"Yes": "Да"
}

View File

@@ -402,5 +402,12 @@
"HistoryCleanupDaysHelpTextWarning": "Filer i papperskorgen som är äldre än det valda antalet dagar rensas automatiskt",
"OnGrab": "Vid hämtning",
"OnHealthIssue": "På hälsofrågan",
"TestAllIndexers": "Testa samtliga indexerare"
"TestAllIndexers": "Testa samtliga indexerare",
"GrabReleases": "Hämta utgåva",
"UnableToLoadIndexers": "Det går inte att ladda indexerare",
"Yes": "Ja",
"Application": "Applikationer",
"Link": "Länkar",
"MappedDrivesRunningAsService": "Mappade nätverksenheter är inte tillgängliga när de körs som en Windows-tjänst. Se FAQ för mer information",
"No": "Nej"
}

View File

@@ -323,5 +323,13 @@
"HistoryCleanupDaysHelpText": "ตั้งค่าเป็น 0 เพื่อปิดใช้งานการล้างข้อมูลอัตโนมัติ",
"OnGrab": "บน Grab",
"OnHealthIssue": "เกี่ยวกับปัญหาสุขภาพ",
"TestAllIndexers": "ทดสอบดัชนีทั้งหมด"
"TestAllIndexers": "ทดสอบดัชนีทั้งหมด",
"ConnectionLostMessage": "Whisparr สูญเสียการเชื่อมต่อกับแบ็กเอนด์และจะต้องโหลดใหม่เพื่อกู้คืนฟังก์ชันการทำงาน",
"GrabReleases": "คว้ารีลีส",
"NetCore": ".NET Core",
"MappedDrivesRunningAsService": "ไดรฟ์เครือข่ายที่แมปไม่พร้อมใช้งานเมื่อเรียกใช้เป็นบริการ Windows โปรดดูคำถามที่พบบ่อยสำหรับข้อมูลเพิ่มเติม",
"No": "ไม่",
"Link": "ลิงค์",
"UnableToLoadIndexers": "ไม่สามารถโหลด Indexers",
"Yes": "ใช่"
}

View File

@@ -326,5 +326,13 @@
"Filters": "Filtre",
"OnGrab": "Yakalandığında",
"OnHealthIssue": "Sağlık Sorunu Hakkında",
"TestAllIndexers": "Tüm Dizinleyicileri Test Et"
"TestAllIndexers": "Tüm Dizinleyicileri Test Et",
"ConnectionLostMessage": "Whisparr arka uçla olan bağlantısını kaybetti ve işlevselliği geri yüklemek için yeniden yüklenmesi gerekecek.",
"GrabReleases": "Bırakma",
"No": "Hayır",
"NetCore": ".NET Çekirdeği",
"UnableToLoadIndexers": "Dizinleyiciler yüklenemiyor",
"Yes": "Evet",
"Link": "Bağlantılar",
"MappedDrivesRunningAsService": "Eşlenen ağ sürücüleri, bir Windows Hizmeti olarak çalışırken kullanılamaz. Daha fazla bilgi için lütfen SSS bölümüne bakın"
}

View File

@@ -1 +1,74 @@
{}
{
"BranchUpdateMechanism": "Гілка, що використовується зовнішнім механізмом оновлення",
"CancelPendingTask": "Ви впевнені, що хочете скасувати це незавершене завдання?",
"About": "Деталі",
"AcceptConfirmationModal": "Вікно підтвердження",
"Actions": "Дії",
"Add": "Додати",
"AddDownloadClient": "Додати клієнт завантаження",
"Age": "Вік",
"All": "Всі",
"Analytics": "Аналітика",
"ApiKey": "API Ключ",
"Added": "Додано",
"AddIndexer": "Додати індексатор",
"AddingTag": "Додавання тегу",
"AppDataDirectory": "Каталог AppData",
"AppDataLocationHealthCheckMessage": "Оновлення буде неможливим, щоб запобігти видаленню AppData під час оновлення",
"Apply": "Застосувати",
"ApplyTags": "Застосувати теги",
"BackupNow": "Зробити резервну копію",
"BackupRetentionHelpText": "Автоматичні резервні копії, старіші за період зберігання, очищаються автоматично",
"Component": "Компонент",
"ConnectionLost": "Зв'язок втрачений",
"Connections": "З'єднання",
"ConnectSettings": "Налаштування підключення",
"CouldNotConnectSignalR": "Не вдалося підключитися до SignalR, інтерфейс користувача не оновиться",
"Custom": "Настроюваний",
"CustomFilters": "Користувацькі фільтри",
"Database": "База даних",
"Date": "Дата",
"Dates": "Дати",
"DBMigration": "Міграція БД",
"DeleteBackup": "Видалити резервну копію",
"DeleteBackupMessageText": "Ви впевнені, що хочете видалити резервну копію '{0}'?",
"DeleteDownloadClient": "Видалити клієнт завантаження",
"DeleteDownloadClientMessageText": "Ви впевнені, що хочете видалити клієнт завантаження '{0}'?",
"ApplyTagsHelpTexts3": "Видалити: видалити введені теги",
"ApplyTagsHelpTexts4": "Замінити: Змінити наявні теги на введені теги (залишіть порожнім, щоб очистити всі теги)",
"AreYouSureYouWantToResetYourAPIKey": "Ви впевнені, що хочете скинути свій ключ API?",
"Authentication": "Аутентифікація",
"Automatic": "Автоматичний",
"AutomaticSearch": "Автоматичний пошук",
"Backup": "Резервне копіювання",
"BackupIntervalHelpText": "Інтервал між автоматичним резервним копіюванням",
"Backups": "Резервні копії",
"BeforeUpdate": "Перед оновленням",
"BindAddress": "Прив'язувати адресу",
"Branch": "Гілка",
"BypassProxyForLocalAddresses": "Обійти проксі для локальних адрес",
"Cancel": "Скасувати",
"CertificateValidation": "Перевірка сертифіката",
"ChangeHasNotBeenSavedYet": "Зміни ще не набрали чинності",
"Clear": "Очистити",
"ClientPriority": "Пріоритет клієнта",
"CloneProfile": "Клонувати профіль",
"Close": "Закрити",
"CloseCurrentModal": "Закрити поточне вікно",
"Columns": "Колонки",
"ApplyTagsHelpTexts1": "Як застосувати теги до вибраних фільмів",
"ApplyTagsHelpTexts2": "Додати: додати теги до наявного списку тегів",
"AuthenticationMethodHelpText": "Для доступу до Radarr потрібні ім’я користувача та пароль",
"BackupFolderHelpText": "Відносні шляхи будуть у каталозі AppData Radarr",
"BindAddressHelpText": "Дійсна адреса IPv4 або '*' для всіх інтерфейсів",
"BranchUpdate": "Гілка для оновлення Radarr",
"AllIndexersHiddenDueToFilter": "Всі фільми заховані відповідно до фільтра.",
"AnalyticsEnabledHelpText": "Надсилайте анонімну інформацію про використання та помилки на сервери Radarr. Це включає інформацію про ваш веб-переглядач, які сторінки Radarr WebUI ви використовуєте, звіти про помилки, а також версію ОС і часу виконання. Ми будемо використовувати цю інформацію, щоб визначити пріоритети функцій і виправлення помилок.",
"ConnectionLostAutomaticMessage": "Radarr спробує підключитися автоматично, або ви можете натиснути перезавантажити нижче.",
"ConnectionLostMessage": "Radarr втратив зв’язок із бекендом, і його потрібно перезавантажити, щоб відновити функціональність.",
"Delete": "Видалити",
"DeleteApplicationMessageText": "Ви впевнені, що хочете видалити клієнт завантаження '{0}'?",
"DeleteTagMessageText": "Ви впевнені, що хочете видалити тег {0} ?",
"DeleteIndexerProxyMessageText": "Ви впевнені, що хочете видалити тег {0} ?",
"DeleteNotificationMessageText": "Ви впевнені, що хочете видалити клієнт завантаження '{0}'?"
}

View File

@@ -323,5 +323,13 @@
"OnHealthIssue": "Về vấn đề sức khỏe",
"Filters": "Bộ lọc",
"OnGrab": "Trên Grab",
"TestAllIndexers": "Kiểm tra tất cả các chỉ mục"
"TestAllIndexers": "Kiểm tra tất cả các chỉ mục",
"ConnectionLostMessage": "Whisparr đã mất kết nối với phần phụ trợ và sẽ cần được tải lại để khôi phục chức năng.",
"GrabReleases": "Lấy bản phát hành",
"Link": "Liên kết",
"No": "Không",
"MappedDrivesRunningAsService": "Các ổ đĩa mạng được ánh xạ không khả dụng khi chạy dưới dạng Dịch vụ Windows. Vui lòng xem Câu hỏi thường gặp để biết thêm thông tin",
"UnableToLoadIndexers": "Không thể tải Trình chỉ mục",
"Yes": "Đúng",
"NetCore": ".NET Core"
}

View File

@@ -272,7 +272,7 @@
"Wiki": "Wiki",
"Yesterday": "昨天",
"Torrent": "Torrents",
"Torrents": "Torrents",
"Torrents": "种子",
"Type": "类型",
"UnableToLoadNotifications": "无法加载通知连接",
"RefreshMovie": "刷新影片",
@@ -377,15 +377,15 @@
"Notifications": "通知",
"Notification": "通知",
"NoSearchResultsFound": "无搜索结果,请在下面尝试新的搜索。",
"IndexerVipCheckExpiringClientMessage": "搜刮器VIP特权即将过期{0}",
"IndexerVipCheckExpiredClientMessage": "搜刮器VIP特权已过期{0}",
"IndexerVipCheckExpiringClientMessage": "索引器VIP特权即将过期{0}",
"IndexerVipCheckExpiredClientMessage": "索引器VIP特权已过期{0}",
"IndexerProxy": "搜刮器代理",
"IndexerProxies": "搜刮器代理",
"DeleteIndexerProxy": "删除搜刮器代理",
"AddIndexerProxy": "添加搜刮器代理",
"AppSettingsSummary": "配置Prowlarr与PVR程序交互方式的应用和设置",
"SyncLevelFull": "完全同步:将保持此应用程序完全同步。当在Prowlarr中所做的更改将同步到与此关联的应用程序。任何关联应用上的更改都将在下次同步时被Prowlarr覆盖。",
"SyncLevelAddRemove": "仅添加和删除:当从 Prowlarr 添加或删除时,它将更新与此关联的应用程序。",
"SyncLevelFull": "完全同步:将保持此应用的索引器完全同步。当在Prowlarr中所做的更改将同步到与此关联的应用程序。任何关联应用上的更改都将在下次同步时被Prowlarr覆盖。",
"SyncLevelAddRemove": "仅添加和删除:当索引器从 Prowlarr 添加或删除时,它将更新与此关联的应用程序。",
"SyncAppIndexers": "同步应用索引",
"Stats": "统计数据",
"SettingsSqlLoggingHelpText": "记录来自Prowlarr的所有SQL查询",
@@ -395,7 +395,7 @@
"SettingsIndexerLoggingHelpText": "记录额外的搜刮器数据,包括响应",
"SettingsFilterSentryEventsHelpText": "过滤已知的用户错误事件,不让其作为分析报告发送",
"RedirectHelpText": "重定向搜刮器的传入下载请求并直接传递抓取而不是通过Prowlarr代理请求搜刮器",
"IndexerTagsHelpText": "使用标签来指定默认客户端、搜刮器代理或仅群组搜刮器。",
"IndexerTagsHelpText": "使用标签‎‎指定‎‎索引器‎‎代理或仅用于你组织的‎‎索引器.",
"IndexerSettingsSummary": "配置全局索引器设置,包括代理。",
"HistoryCleanupDaysHelpTextWarning": "回收站中的文件在超出选择的天数后会被自动清理",
"UserAgentProvidedByTheAppThatCalledTheAPI": "由调用API的应用程序提供的User-Agent",
@@ -413,8 +413,8 @@
"IndexerInfo": "索引器信息",
"IndexerNoDefCheckMessage": "索引器没有定义,将无法工作: {0}. 请删除或重新添加到Prowlarr",
"MovieSearch": "搜索电影",
"OnApplicationUpdate": "应用更新",
"OnApplicationUpdateHelpText": "应用更新中,请耐心等待",
"OnApplicationUpdate": "程序更新",
"OnApplicationUpdateHelpText": "在程序更新时",
"Private": "私有",
"Public": "公开",
"QueryOptions": "查询选项",
@@ -423,5 +423,26 @@
"Proxies": "代理",
"SearchType": "搜索类型",
"TvSearch": "搜索剧集",
"UnableToLoadApplicationList": "123"
"UnableToLoadApplicationList": "123",
"BookSearchTypes": "搜索图书类型",
"IndexerDetails": "‎索引器‎‎详细信息‎",
"IndexerName": "‎索引‎‎名字‎",
"IndexerSite": "‎索引‎‎网站‎",
"MovieSearchTypes": "‎影片‎‎搜索‎‎类型‎",
"MusicSearchTypes": "‎音乐‎‎搜索‎‎类型‎",
"NotSupported": "‎不支持‎",
"RawSearchSupported": "‎支持原始‎‎搜索‎",
"SearchCapabilities": "‎搜索‎‎能力‎",
"SemiPrivate": "‎半私有‎",
"TVSearchTypes": "‎电视‎‎搜索‎‎类型‎",
"Url": "Url",
"Website": "‎网站‎",
"GrabReleases": "抓取版本",
"Link": "链接",
"MappedDrivesRunningAsService": "映射的网络驱动器在作为Windows服务运行时不可用。请参阅常见问题解答了解更多信息",
"No": "否",
"Yes": "是",
"Application": "程序",
"SearchTypes": "搜索类型",
"UnableToLoadIndexers": "无法加载搜刮器"
}

View File

@@ -5,5 +5,67 @@
"About": "关于",
"Analytics": "分析",
"AddIndexer": "添加索引器",
"ApiKey": "API密钥"
"ApiKey": "API密钥",
"AddingTag": "添加标签",
"AddAppProfile": "‎添加应用‎‎同步‎‎配置文件‎",
"AddNewIndexer": "添加新的索引器",
"AddRemoveOnly": "仅读写",
"AddIndexerProxy": "添加索引器代理",
"Apply": "应用",
"AddDownloadClientToProwlarr": "添加一个支持 Prowlarr 在执行手动‎‎搜索‎‎时发送资源的下载客户端",
"AddedToDownloadClient": "‎已添加到‎‎客户端‎‎的版本‎",
"ApplyTagsHelpTexts1": "‎如何将标记‎‎应用于‎‎选定的‎‎索引器‎",
"AppProfileInUse": "‎正在使用中的应用配置文件‎",
"Apps": "‎应用程序‎",
"AppSettingsSummary": "‎用于‎‎配置 Prowlarr 如何与您的 PVR 程序交互的应用程序和‎‎设置‎",
"AreYouSureYouWantToResetYourAPIKey": "你‎是否确实要重置 API 密钥‎‎‎?",
"Auth": "‎认证‎",
"Age": "年龄",
"All": "全部",
"AllIndexersHiddenDueToFilter": "所有‎‎索引器‎‎都处于隐藏状态,‎由于应用了‎‎筛选器‎‎。‎",
"AnalyticsEnabledHelpText": "将匿名使用情况和错误信息发送到Prowlarr的服务器。这包括有关您的浏览器中的Prowlarr WebUI页面错误报告以及操作系统运行时版本。我们将使用此信息来确定功能和错误修复的优先级。",
"AppDataDirectory": "‎应用程序数据‎‎目录‎",
"AppDataLocationHealthCheckMessage": "‎无法进行更新以防止在‎‎更新‎‎时删除‎‎应用程序数据‎",
"Applications": "‎应用‎",
"ApplicationStatusCheckAllClientMessage": "‎所有‎‎应用程序‎‎都因故障而不可用‎",
"ApplicationStatusCheckSingleClientMessage": "‎应用程序‎‎因故障而不可用:{0}",
"ApplyTags": "‎应用‎‎标签‎",
"AppProfile": "‎应用配置文件‎",
"AcceptConfirmationModal": "‎接受默认模式‎",
"Actions": "行为",
"AddToDownloadClient": "‎添加‎‎版本以‎‎下载‎‎客户端‎",
"Application": "‎应用‎",
"ApplyTagsHelpTexts2": "‎添加‎‎:将标签‎‎添加到‎‎现有的标签‎‎列表中‎",
"ApplyTagsHelpTexts3": "‎移除‎‎:‎‎移除‎‎输入的标签‎",
"ApplyTagsHelpTexts4": "‎替换‎‎:‎‎将标记替换为‎‎输入的标记(不输入任何标记以‎‎清除‎‎所有标记)‎",
"AppProfileDeleteConfirm": "你‎是否确实要‎‎删除‎‎{0}",
"AppProfiles": "‎应用配置文件‎",
"AppProfileSelectHelpText": "‎应用程序配置文件用于控制应用程序‎‎同步‎‎时‎‎的 RSS、自动搜索交互式搜索设置",
"AudioSearch": "‎音频‎‎搜索‎",
"Authentication": "认证",
"AuthenticationMethodHelpText": "访问 Prowlarr 时需要提供用户名和密码",
"Automatic": "自动化",
"AutomaticSearch": "自动搜索",
"Backup": "备份",
"BackupIntervalHelpText": "自动备份时间间隔",
"Clear": "清除",
"Categories": "目录",
"BackupNow": "立即备份",
"BackupRetentionHelpText": "超过保留时间的自动备份将被自动清除",
"Backups": "备份",
"BindAddressHelpText": "填入有效 IP 地址或使用 '*' 接受所有连接",
"BookSearch": "图书搜索",
"BranchUpdate": "Prowlarr 更新时使用的 Branch",
"Branch": "",
"CertificateValidationHelpText": "设置 HTTPS 认证等级",
"CertificateValidation": "证书认证",
"Category": "目录",
"CancelPendingTask": "取消这个进行的任务?",
"Cancel": "取消",
"BypassProxyForLocalAddresses": "不代理本地 IP 地址",
"BackupFolderHelpText": "Prowlarr 安装目录下的相对路径",
"BindAddress": "绑定地址",
"ChangeHasNotBeenSavedYet": "设置未保存",
"Close": "关闭",
"CloneProfile": "复制配置文件"
}

View File

@@ -0,0 +1,32 @@
using System.Collections.Generic;
namespace NzbDrone.Core.Messaging.Commands
{
public class CommandPriorityComparer : IComparer<CommandStatus>
{
public int Compare(CommandStatus x, CommandStatus y)
{
if (x == CommandStatus.Started && y != CommandStatus.Started)
{
return -1;
}
if (x != CommandStatus.Started && y == CommandStatus.Started)
{
return 1;
}
if (x < y)
{
return -1;
}
if (x > y)
{
return 1;
}
return 0;
}
}
}

View File

@@ -37,6 +37,13 @@ namespace NzbDrone.Core.Notifications
public void Handle(HealthCheckFailedEvent message)
{
// Don't send health check notifications during the start up grace period,
// once that duration expires they they'll be retested and fired off if necessary.
if (message.IsInStartupGraceperiod)
{
return;
}
foreach (var notification in _notificationFactory.OnHealthIssueEnabled())
{
try

View File

@@ -21,7 +21,7 @@
<PackageReference Include="Kveer.XmlRPC" Version="1.1.1" />
<PackageReference Include="System.Data.SQLite.Core.Servarr" Version="1.0.115.5-18" />
<PackageReference Include="System.Text.Json" Version="6.0.2" />
<PackageReference Include="MonoTorrent" Version="1.0.29" />
<PackageReference Include="MonoTorrent" Version="2.0.5" />
<PackageReference Include="YamlDotNet" Version="11.2.1" />
<PackageReference Include="AngleSharp" Version="0.16.1" />
</ItemGroup>

View File

@@ -26,6 +26,8 @@ namespace Prowlarr.Api.V1.Commands
private readonly Debouncer _debouncer;
private readonly Dictionary<int, CommandResource> _pendingUpdates;
private readonly CommandPriorityComparer _commandPriorityComparer = new CommandPriorityComparer();
public CommandController(IManageCommandQueue commandQueueManager,
IBroadcastSignalRMessage signalRBroadcaster,
KnownTypes knownTypes)
@@ -73,7 +75,10 @@ namespace Prowlarr.Api.V1.Commands
[Produces("application/json")]
public List<CommandResource> GetStartedCommands()
{
return _commandQueueManager.All().ToResource();
return _commandQueueManager.All()
.OrderBy(c => c.Status, _commandPriorityComparer)
.ThenByDescending(c => c.Priority)
.ToResource();
}
[RestDeleteById]

View File

@@ -5,7 +5,6 @@ namespace Prowlarr.Api.V1.Config
{
public class DownloadClientConfigResource : RestResource
{
public string DownloadClientWorkingFolders { get; set; }
}
public static class DownloadClientConfigResourceMapper
@@ -14,7 +13,6 @@ namespace Prowlarr.Api.V1.Config
{
return new DownloadClientConfigResource
{
DownloadClientWorkingFolders = model.DownloadClientWorkingFolders
};
}
}

View File

@@ -16,7 +16,6 @@ namespace Prowlarr.Api.V1.Config
public bool ShowRelativeDates { get; set; }
public bool EnableColorImpairedMode { get; set; }
public int MovieInfoLanguage { get; set; }
public int UILanguage { get; set; }
}
@@ -35,7 +34,6 @@ namespace Prowlarr.Api.V1.Config
ShowRelativeDates = model.ShowRelativeDates,
EnableColorImpairedMode = model.EnableColorImpairedMode,
MovieInfoLanguage = model.MovieInfoLanguage,
UILanguage = model.UILanguage
};
}

View File

@@ -15,6 +15,7 @@ namespace Prowlarr.Api.V1.Indexers
public class IndexerResource : ProviderResource<IndexerResource>
{
public string[] IndexerUrls { get; set; }
public string[] LegacyUrls { get; set; }
public string DefinitionName { get; set; }
public string Description { get; set; }
public string Language { get; set; }
@@ -81,6 +82,7 @@ namespace Prowlarr.Api.V1.Indexers
resource.InfoLink = string.Format("https://wiki.servarr.com/prowlarr/supported-indexers#{0}", infoLinkName.ToLower().Replace(' ', '-'));
resource.AppProfileId = definition.AppProfileId;
resource.IndexerUrls = definition.IndexerUrls;
resource.LegacyUrls = definition.LegacyUrls;
resource.Description = definition.Description;
resource.Language = definition.Language;
resource.Encoding = definition.Encoding?.EncodingName ?? null;

View File

@@ -42,6 +42,7 @@ namespace Prowlarr.Api.V1.System.Backup
Name = b.Name,
Path = $"/backup/{b.Type.ToString().ToLower()}/{b.Name}",
Type = b.Type,
Size = b.Size,
Time = b.Time
})
.OrderByDescending(b => b.Time)

View File

@@ -9,6 +9,7 @@ namespace Prowlarr.Api.V1.System.Backup
public string Name { get; set; }
public string Path { get; set; }
public BackupType Type { get; set; }
public long Size { get; set; }
public DateTime Time { get; set; }
}
}

View File

@@ -4544,6 +4544,10 @@
"type": {
"$ref": "#/components/schemas/BackupType"
},
"size": {
"type": "integer",
"format": "int64"
},
"time": {
"type": "string",
"format": "date-time"
@@ -4559,6 +4563,14 @@
],
"type": "string"
},
"BookSearchParam": {
"enum": [
"q",
"title",
"author"
],
"type": "string"
},
"CertificateValidationType": {
"enum": [
"enabled",
@@ -4784,10 +4796,6 @@
"id": {
"type": "integer",
"format": "int32"
},
"downloadClientWorkingFolders": {
"type": "string",
"nullable": true
}
},
"additionalProperties": false
@@ -5259,6 +5267,44 @@
"$ref": "#/components/schemas/IndexerCategory"
},
"nullable": true
},
"supportsRawSearch": {
"type": "boolean"
},
"searchParams": {
"type": "array",
"items": {
"$ref": "#/components/schemas/SearchParam"
},
"nullable": true
},
"tvSearchParams": {
"type": "array",
"items": {
"$ref": "#/components/schemas/TvSearchParam"
},
"nullable": true
},
"movieSearchParams": {
"type": "array",
"items": {
"$ref": "#/components/schemas/MovieSearchParam"
},
"nullable": true
},
"musicSearchParams": {
"type": "array",
"items": {
"$ref": "#/components/schemas/MusicSearchParam"
},
"nullable": true
},
"bookSearchParams": {
"type": "array",
"items": {
"$ref": "#/components/schemas/BookSearchParam"
},
"nullable": true
}
},
"additionalProperties": false
@@ -5464,6 +5510,13 @@
},
"nullable": true
},
"legacyUrls": {
"type": "array",
"items": {
"type": "string"
},
"nullable": true
},
"definitionName": {
"type": "string",
"nullable": true
@@ -5748,6 +5801,29 @@
},
"additionalProperties": false
},
"MovieSearchParam": {
"enum": [
"q",
"imdbId",
"tmdbId",
"imdbTitle",
"imdbYear",
"traktId",
"genre"
],
"type": "string"
},
"MusicSearchParam": {
"enum": [
"q",
"album",
"artist",
"label",
"year",
"genre"
],
"type": "string"
},
"NotificationResource": {
"type": "object",
"properties": {
@@ -5992,6 +6068,12 @@
},
"additionalProperties": false
},
"SearchParam": {
"enum": [
"q"
],
"type": "string"
},
"SelectOption": {
"type": "object",
"properties": {
@@ -6176,6 +6258,20 @@
},
"additionalProperties": false
},
"TvSearchParam": {
"enum": [
"q",
"season",
"ep",
"imdbId",
"tvdbId",
"rId",
"tvMazeId",
"traktId",
"tmdbId"
],
"type": "string"
},
"UiConfigResource": {
"type": "object",
"properties": {
@@ -6209,10 +6305,6 @@
"enableColorImpairedMode": {
"type": "boolean"
},
"movieInfoLanguage": {
"type": "integer",
"format": "int32"
},
"uiLanguage": {
"type": "integer",
"format": "int32"

View File

@@ -4648,10 +4648,10 @@ mobile-detect@1.4.5:
resolved "https://registry.yarnpkg.com/mobile-detect/-/mobile-detect-1.4.5.tgz#da393c3c413ca1a9bcdd9ced653c38281c0fb6ad"
integrity sha512-yc0LhH6tItlvfLBugVUEtgawwFU2sIe+cSdmRJJCTMZ5GEJyLxNyC/NIOAOGk67Fa8GNpOttO3Xz/1bHpXFD/g==
moment@2.29.1:
version "2.29.1"
resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.1.tgz#b2be769fa31940be9eeea6469c075e35006fa3d3"
integrity sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==
moment@2.29.2:
version "2.29.2"
resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.2.tgz#00910c60b20843bcba52d37d58c628b47b1f20e4"
integrity sha512-UgzG4rvxYpN15jgCmVJwac49h9ly9NurikMWGPdVxm8GZD6XjkKPxDTjQQ43gtGgnV3X0cAyWDdP2Wexoquifg==
mousetrap@1.6.5:
version "1.6.5"