mirror of
https://github.com/lidarr/lidarr.git
synced 2025-07-06 13:02:23 -07:00
Compare commits
66 commits
v2.10.3.46
...
develop
Author | SHA1 | Date | |
---|---|---|---|
|
91f06801ca | ||
|
dc61618711 | ||
|
fd00a5627c | ||
|
66ea1b1dfb | ||
|
72fa05cf41 | ||
|
c51b5c6fba | ||
|
efebab9ba2 | ||
|
47c32c9963 | ||
|
9f229bb684 | ||
|
f9b2e57696 | ||
|
4b48edab0a | ||
|
e087574de7 | ||
|
8877cf99f1 | ||
|
a56e5b3f9a | ||
|
5bb1949ea2 | ||
|
979042948d | ||
|
ebe59b18d9 | ||
|
086a451dff | ||
|
1bcb82eed0 | ||
|
ae9b4cec75 | ||
|
ed777de015 | ||
|
96f956a5d6 | ||
|
68a8f40746 | ||
|
c518cf63e7 | ||
|
da55b8578a | ||
|
234c29ef49 | ||
|
de169e8a1f | ||
|
4b300a448a | ||
|
785bcfda0b | ||
|
94ea751ad2 | ||
|
0c172b58f1 | ||
|
ea2ee70208 | ||
|
8b63928a25 | ||
|
7217e891f7 | ||
|
345bbcd992 | ||
|
bd9d7ba085 | ||
|
3937bebfea | ||
|
767b0930a5 | ||
|
c3f0fc640c | ||
|
9dbcc79436 | ||
|
3dd04cecbf | ||
|
d8850af019 | ||
|
fbfd24e226 | ||
|
d9562c701e | ||
|
d21ad2ad68 | ||
|
556f0ea54b | ||
|
e4a36ca388 | ||
|
1045684935 | ||
|
9ba71ae6b1 | ||
|
89b9352fef | ||
|
c83332e58c | ||
|
4677a1115a | ||
|
6150a57596 | ||
|
13f6b1a086 | ||
|
8027ab5d2e | ||
|
5bdc119b98 | ||
|
1b9b57ae9b | ||
|
c28a97cafd | ||
|
099d19a04d | ||
|
d381463b60 | ||
|
a86bd8e862 | ||
|
4bea38ab9c | ||
|
950c51bc59 | ||
|
18f13fe7f8 | ||
|
f8d4b3a59b | ||
|
5cf9624e55 |
116 changed files with 1139 additions and 349 deletions
1
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
1
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
|
@ -60,6 +60,7 @@ body:
|
||||||
- Master
|
- Master
|
||||||
- Develop
|
- Develop
|
||||||
- Nightly
|
- Nightly
|
||||||
|
- Plugins (experimental)
|
||||||
- Other (This issue will be closed)
|
- Other (This issue will be closed)
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
|
|
28
.gitignore
vendored
28
.gitignore
vendored
|
@ -158,34 +158,12 @@ Thumbs.db
|
||||||
/tools/Addins/*
|
/tools/Addins/*
|
||||||
packages.config.md5sum
|
packages.config.md5sum
|
||||||
|
|
||||||
|
|
||||||
# Common IntelliJ Platform excludes
|
|
||||||
|
|
||||||
# User specific
|
|
||||||
**/.idea/**/workspace.xml
|
|
||||||
**/.idea/**/tasks.xml
|
|
||||||
**/.idea/shelf/*
|
|
||||||
**/.idea/dictionaries
|
|
||||||
**/.idea/.idea.Radarr.Posix
|
|
||||||
**/.idea/.idea.Radarr.Windows
|
|
||||||
|
|
||||||
# Sensitive or high-churn files
|
|
||||||
**/.idea/**/dataSources/
|
|
||||||
**/.idea/**/dataSources.ids
|
|
||||||
**/.idea/**/dataSources.xml
|
|
||||||
**/.idea/**/dataSources.local.xml
|
|
||||||
**/.idea/**/sqlDataSources.xml
|
|
||||||
**/.idea/**/dynamic.xml
|
|
||||||
|
|
||||||
# Rider
|
|
||||||
# Rider auto-generates .iml files, and contentModel.xml
|
|
||||||
**/.idea/**/*.iml
|
|
||||||
**/.idea/**/contentModel.xml
|
|
||||||
**/.idea/**/modules.xml
|
|
||||||
|
|
||||||
# ignore node_modules symlink
|
# ignore node_modules symlink
|
||||||
node_modules
|
node_modules
|
||||||
node_modules.nosync
|
node_modules.nosync
|
||||||
|
|
||||||
# API doc generation
|
# API doc generation
|
||||||
.config/
|
.config/
|
||||||
|
|
||||||
|
# Ignore Jetbrains IntelliJ Workspace Directories
|
||||||
|
.idea/
|
||||||
|
|
|
@ -9,7 +9,7 @@ variables:
|
||||||
testsFolder: './_tests'
|
testsFolder: './_tests'
|
||||||
yarnCacheFolder: $(Pipeline.Workspace)/.yarn
|
yarnCacheFolder: $(Pipeline.Workspace)/.yarn
|
||||||
nugetCacheFolder: $(Pipeline.Workspace)/.nuget/packages
|
nugetCacheFolder: $(Pipeline.Workspace)/.nuget/packages
|
||||||
majorVersion: '2.10.3'
|
majorVersion: '2.13.1'
|
||||||
minorVersion: $[counter('minorVersion', 1076)]
|
minorVersion: $[counter('minorVersion', 1076)]
|
||||||
lidarrVersion: '$(majorVersion).$(minorVersion)'
|
lidarrVersion: '$(majorVersion).$(minorVersion)'
|
||||||
buildName: '$(Build.SourceBranchName).$(lidarrVersion)'
|
buildName: '$(Build.SourceBranchName).$(lidarrVersion)'
|
||||||
|
@ -19,7 +19,7 @@ variables:
|
||||||
nodeVersion: '20.X'
|
nodeVersion: '20.X'
|
||||||
innoVersion: '6.2.0'
|
innoVersion: '6.2.0'
|
||||||
windowsImage: 'windows-2022'
|
windowsImage: 'windows-2022'
|
||||||
linuxImage: 'ubuntu-20.04'
|
linuxImage: 'ubuntu-22.04'
|
||||||
macImage: 'macOS-13'
|
macImage: 'macOS-13'
|
||||||
|
|
||||||
trigger:
|
trigger:
|
||||||
|
|
|
@ -188,7 +188,7 @@ module.exports = (env) => {
|
||||||
loose: true,
|
loose: true,
|
||||||
debug: false,
|
debug: false,
|
||||||
useBuiltIns: 'entry',
|
useBuiltIns: 'entry',
|
||||||
corejs: '3.39'
|
corejs: '3.41'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
|
|
@ -172,7 +172,8 @@ function HistoryDetails(props) {
|
||||||
|
|
||||||
if (eventType === 'downloadFailed') {
|
if (eventType === 'downloadFailed') {
|
||||||
const {
|
const {
|
||||||
message
|
message,
|
||||||
|
indexer
|
||||||
} = data;
|
} = data;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -192,6 +193,14 @@ function HistoryDetails(props) {
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
indexer ? (
|
||||||
|
<DescriptionListItem
|
||||||
|
title={translate('Indexer')}
|
||||||
|
data={indexer}
|
||||||
|
/>
|
||||||
|
) : null}
|
||||||
|
|
||||||
{
|
{
|
||||||
message ?
|
message ?
|
||||||
<DescriptionListItem
|
<DescriptionListItem
|
||||||
|
|
|
@ -15,7 +15,7 @@ import ModalContent from 'Components/Modal/ModalContent';
|
||||||
import ModalFooter from 'Components/Modal/ModalFooter';
|
import ModalFooter from 'Components/Modal/ModalFooter';
|
||||||
import ModalHeader from 'Components/Modal/ModalHeader';
|
import ModalHeader from 'Components/Modal/ModalHeader';
|
||||||
import Popover from 'Components/Tooltip/Popover';
|
import Popover from 'Components/Tooltip/Popover';
|
||||||
import { icons, inputTypes, kinds, tooltipPositions } from 'Helpers/Props';
|
import { icons, inputTypes, kinds, sizes, tooltipPositions } from 'Helpers/Props';
|
||||||
import translate from 'Utilities/String/translate';
|
import translate from 'Utilities/String/translate';
|
||||||
import styles from './EditArtistModalContent.css';
|
import styles from './EditArtistModalContent.css';
|
||||||
|
|
||||||
|
@ -93,7 +93,7 @@ class EditArtistModalContent extends Component {
|
||||||
|
|
||||||
<ModalBody>
|
<ModalBody>
|
||||||
<Form {...otherProps}>
|
<Form {...otherProps}>
|
||||||
<FormGroup>
|
<FormGroup size={sizes.MEDIUM}>
|
||||||
<FormLabel>
|
<FormLabel>
|
||||||
{translate('Monitored')}
|
{translate('Monitored')}
|
||||||
</FormLabel>
|
</FormLabel>
|
||||||
|
@ -107,9 +107,10 @@ class EditArtistModalContent extends Component {
|
||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
|
|
||||||
<FormGroup>
|
<FormGroup size={sizes.MEDIUM}>
|
||||||
<FormLabel>
|
<FormLabel>
|
||||||
{translate('MonitorNewItems')}
|
{translate('MonitorNewItems')}
|
||||||
|
|
||||||
<Popover
|
<Popover
|
||||||
anchor={
|
anchor={
|
||||||
<Icon
|
<Icon
|
||||||
|
@ -132,7 +133,7 @@ class EditArtistModalContent extends Component {
|
||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
|
|
||||||
<FormGroup>
|
<FormGroup size={sizes.MEDIUM}>
|
||||||
<FormLabel>
|
<FormLabel>
|
||||||
{translate('QualityProfile')}
|
{translate('QualityProfile')}
|
||||||
</FormLabel>
|
</FormLabel>
|
||||||
|
@ -146,10 +147,10 @@ class EditArtistModalContent extends Component {
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
|
|
||||||
{
|
{
|
||||||
showMetadataProfile &&
|
showMetadataProfile ?
|
||||||
<FormGroup>
|
<FormGroup size={sizes.MEDIUM}>
|
||||||
<FormLabel>
|
<FormLabel>
|
||||||
Metadata Profile
|
{translate('MetadataProfile')}
|
||||||
|
|
||||||
<Popover
|
<Popover
|
||||||
anchor={
|
anchor={
|
||||||
|
@ -173,10 +174,11 @@ class EditArtistModalContent extends Component {
|
||||||
{...metadataProfileId}
|
{...metadataProfileId}
|
||||||
onChange={onInputChange}
|
onChange={onInputChange}
|
||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup> :
|
||||||
|
null
|
||||||
}
|
}
|
||||||
|
|
||||||
<FormGroup>
|
<FormGroup size={sizes.MEDIUM}>
|
||||||
<FormLabel>
|
<FormLabel>
|
||||||
{translate('Path')}
|
{translate('Path')}
|
||||||
</FormLabel>
|
</FormLabel>
|
||||||
|
@ -189,7 +191,7 @@ class EditArtistModalContent extends Component {
|
||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
|
|
||||||
<FormGroup>
|
<FormGroup size={sizes.MEDIUM}>
|
||||||
<FormLabel>
|
<FormLabel>
|
||||||
{translate('Tags')}
|
{translate('Tags')}
|
||||||
</FormLabel>
|
</FormLabel>
|
||||||
|
@ -209,7 +211,7 @@ class EditArtistModalContent extends Component {
|
||||||
kind={kinds.DANGER}
|
kind={kinds.DANGER}
|
||||||
onPress={onDeleteArtistPress}
|
onPress={onDeleteArtistPress}
|
||||||
>
|
>
|
||||||
Delete
|
{translate('Delete')}
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
|
|
|
@ -83,13 +83,6 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
@media only screen and (max-width: $breakpointMedium) {
|
@media only screen and (max-width: $breakpointMedium) {
|
||||||
.modal.small,
|
|
||||||
.modal.medium {
|
|
||||||
width: 90%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media only screen and (max-width: $breakpointSmall) {
|
|
||||||
.modalContainer {
|
.modalContainer {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
}
|
}
|
||||||
|
|
|
@ -172,7 +172,7 @@ class SignalRConnector extends Component {
|
||||||
const status = resource.status;
|
const status = resource.status;
|
||||||
|
|
||||||
// Both successful and failed commands need to be
|
// Both successful and failed commands need to be
|
||||||
// completed, otherwise they spin until they timeout.
|
// completed, otherwise they spin until they time out.
|
||||||
|
|
||||||
if (status === 'completed' || status === 'failed') {
|
if (status === 'completed' || status === 'failed') {
|
||||||
this.props.dispatchFinishCommand(resource);
|
this.props.dispatchFinishCommand(resource);
|
||||||
|
@ -224,10 +224,58 @@ class SignalRConnector extends Component {
|
||||||
repopulatePage('trackFileUpdated');
|
repopulatePage('trackFileUpdated');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
handleDownloadclient = ({ action, resource }) => {
|
||||||
|
const section = 'settings.downloadClients';
|
||||||
|
|
||||||
|
if (action === 'created' || action === 'updated') {
|
||||||
|
this.props.dispatchUpdateItem({ section, ...resource });
|
||||||
|
} else if (action === 'deleted') {
|
||||||
|
this.props.dispatchRemoveItem({ section, id: resource.id });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
handleHealth = () => {
|
handleHealth = () => {
|
||||||
this.props.dispatchFetchHealth();
|
this.props.dispatchFetchHealth();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
handleImportlist = ({ action, resource }) => {
|
||||||
|
const section = 'settings.importLists';
|
||||||
|
|
||||||
|
if (action === 'created' || action === 'updated') {
|
||||||
|
this.props.dispatchUpdateItem({ section, ...resource });
|
||||||
|
} else if (action === 'deleted') {
|
||||||
|
this.props.dispatchRemoveItem({ section, id: resource.id });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
handleIndexer = ({ action, resource }) => {
|
||||||
|
const section = 'settings.indexers';
|
||||||
|
|
||||||
|
if (action === 'created' || action === 'updated') {
|
||||||
|
this.props.dispatchUpdateItem({ section, ...resource });
|
||||||
|
} else if (action === 'deleted') {
|
||||||
|
this.props.dispatchRemoveItem({ section, id: resource.id });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
handleMetadata = ({ action, resource }) => {
|
||||||
|
const section = 'settings.metadata';
|
||||||
|
|
||||||
|
if (action === 'updated') {
|
||||||
|
this.props.dispatchUpdateItem({ section, ...resource });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
handleNotification = ({ action, resource }) => {
|
||||||
|
const section = 'settings.notifications';
|
||||||
|
|
||||||
|
if (action === 'created' || action === 'updated') {
|
||||||
|
this.props.dispatchUpdateItem({ section, ...resource });
|
||||||
|
} else if (action === 'deleted') {
|
||||||
|
this.props.dispatchRemoveItem({ section, id: resource.id });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
handleArtist = (body) => {
|
handleArtist = (body) => {
|
||||||
const action = body.action;
|
const action = body.action;
|
||||||
const section = 'artist';
|
const section = 'artist';
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
line-height: 1.52857143;
|
line-height: 1.52857143;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media only screen and (max-width: $breakpointSmall) {
|
@media only screen and (max-width: $breakpointMedium) {
|
||||||
.cell {
|
.cell {
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media only screen and (max-width: $breakpointSmall) {
|
@media only screen and (max-width: $breakpointMedium) {
|
||||||
.cell {
|
.cell {
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media only screen and (max-width: $breakpointSmall) {
|
@media only screen and (max-width: $breakpointMedium) {
|
||||||
.tableContainer {
|
.tableContainer {
|
||||||
min-width: 100%;
|
min-width: 100%;
|
||||||
width: fit-content;
|
width: fit-content;
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media only screen and (max-width: $breakpointSmall) {
|
@media only screen and (max-width: $breakpointMedium) {
|
||||||
.headerCell {
|
.headerCell {
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,7 +60,7 @@
|
||||||
height: 25px;
|
height: 25px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media only screen and (max-width: $breakpointSmall) {
|
@media only screen and (max-width: $breakpointMedium) {
|
||||||
.pager {
|
.pager {
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media only screen and (max-width: $breakpointSmall) {
|
@media only screen and (max-width: $breakpointMedium) {
|
||||||
.headerCell {
|
.headerCell {
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,11 +10,11 @@ import ModalBody from 'Components/Modal/ModalBody';
|
||||||
import ModalContent from 'Components/Modal/ModalContent';
|
import ModalContent from 'Components/Modal/ModalContent';
|
||||||
import ModalFooter from 'Components/Modal/ModalFooter';
|
import ModalFooter from 'Components/Modal/ModalFooter';
|
||||||
import ModalHeader from 'Components/Modal/ModalHeader';
|
import ModalHeader from 'Components/Modal/ModalHeader';
|
||||||
|
import Column from 'Components/Table/Column';
|
||||||
import Table from 'Components/Table/Table';
|
import Table from 'Components/Table/Table';
|
||||||
import TableBody from 'Components/Table/TableBody';
|
import TableBody from 'Components/Table/TableBody';
|
||||||
import useSelectState from 'Helpers/Hooks/useSelectState';
|
import useSelectState from 'Helpers/Hooks/useSelectState';
|
||||||
import { kinds } from 'Helpers/Props';
|
import { kinds } from 'Helpers/Props';
|
||||||
import SortDirection from 'Helpers/Props/SortDirection';
|
|
||||||
import {
|
import {
|
||||||
bulkDeleteCustomFormats,
|
bulkDeleteCustomFormats,
|
||||||
bulkEditCustomFormats,
|
bulkEditCustomFormats,
|
||||||
|
@ -34,7 +34,7 @@ type OnSelectedChangeCallback = React.ComponentProps<
|
||||||
typeof ManageCustomFormatsModalRow
|
typeof ManageCustomFormatsModalRow
|
||||||
>['onSelectedChange'];
|
>['onSelectedChange'];
|
||||||
|
|
||||||
const COLUMNS = [
|
const COLUMNS: Column[] = [
|
||||||
{
|
{
|
||||||
name: 'name',
|
name: 'name',
|
||||||
label: () => translate('Name'),
|
label: () => translate('Name'),
|
||||||
|
@ -56,8 +56,6 @@ const COLUMNS = [
|
||||||
|
|
||||||
interface ManageCustomFormatsModalContentProps {
|
interface ManageCustomFormatsModalContentProps {
|
||||||
onModalClose(): void;
|
onModalClose(): void;
|
||||||
sortKey?: string;
|
|
||||||
sortDirection?: SortDirection;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function ManageCustomFormatsModalContent(
|
function ManageCustomFormatsModalContent(
|
||||||
|
|
|
@ -10,11 +10,11 @@ import ModalBody from 'Components/Modal/ModalBody';
|
||||||
import ModalContent from 'Components/Modal/ModalContent';
|
import ModalContent from 'Components/Modal/ModalContent';
|
||||||
import ModalFooter from 'Components/Modal/ModalFooter';
|
import ModalFooter from 'Components/Modal/ModalFooter';
|
||||||
import ModalHeader from 'Components/Modal/ModalHeader';
|
import ModalHeader from 'Components/Modal/ModalHeader';
|
||||||
|
import Column from 'Components/Table/Column';
|
||||||
import Table from 'Components/Table/Table';
|
import Table from 'Components/Table/Table';
|
||||||
import TableBody from 'Components/Table/TableBody';
|
import TableBody from 'Components/Table/TableBody';
|
||||||
import useSelectState from 'Helpers/Hooks/useSelectState';
|
import useSelectState from 'Helpers/Hooks/useSelectState';
|
||||||
import { kinds } from 'Helpers/Props';
|
import { kinds } from 'Helpers/Props';
|
||||||
import SortDirection from 'Helpers/Props/SortDirection';
|
|
||||||
import {
|
import {
|
||||||
bulkDeleteDownloadClients,
|
bulkDeleteDownloadClients,
|
||||||
bulkEditDownloadClients,
|
bulkEditDownloadClients,
|
||||||
|
@ -35,7 +35,7 @@ type OnSelectedChangeCallback = React.ComponentProps<
|
||||||
typeof ManageDownloadClientsModalRow
|
typeof ManageDownloadClientsModalRow
|
||||||
>['onSelectedChange'];
|
>['onSelectedChange'];
|
||||||
|
|
||||||
const COLUMNS = [
|
const COLUMNS: Column[] = [
|
||||||
{
|
{
|
||||||
name: 'name',
|
name: 'name',
|
||||||
label: () => translate('Name'),
|
label: () => translate('Name'),
|
||||||
|
@ -82,8 +82,6 @@ const COLUMNS = [
|
||||||
|
|
||||||
interface ManageDownloadClientsModalContentProps {
|
interface ManageDownloadClientsModalContentProps {
|
||||||
onModalClose(): void;
|
onModalClose(): void;
|
||||||
sortKey?: string;
|
|
||||||
sortDirection?: SortDirection;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function ManageDownloadClientsModalContent(
|
function ManageDownloadClientsModalContent(
|
||||||
|
|
|
@ -10,11 +10,11 @@ import ModalBody from 'Components/Modal/ModalBody';
|
||||||
import ModalContent from 'Components/Modal/ModalContent';
|
import ModalContent from 'Components/Modal/ModalContent';
|
||||||
import ModalFooter from 'Components/Modal/ModalFooter';
|
import ModalFooter from 'Components/Modal/ModalFooter';
|
||||||
import ModalHeader from 'Components/Modal/ModalHeader';
|
import ModalHeader from 'Components/Modal/ModalHeader';
|
||||||
|
import Column from 'Components/Table/Column';
|
||||||
import Table from 'Components/Table/Table';
|
import Table from 'Components/Table/Table';
|
||||||
import TableBody from 'Components/Table/TableBody';
|
import TableBody from 'Components/Table/TableBody';
|
||||||
import useSelectState from 'Helpers/Hooks/useSelectState';
|
import useSelectState from 'Helpers/Hooks/useSelectState';
|
||||||
import { kinds } from 'Helpers/Props';
|
import { kinds } from 'Helpers/Props';
|
||||||
import SortDirection from 'Helpers/Props/SortDirection';
|
|
||||||
import {
|
import {
|
||||||
bulkDeleteIndexers,
|
bulkDeleteIndexers,
|
||||||
bulkEditIndexers,
|
bulkEditIndexers,
|
||||||
|
@ -35,7 +35,7 @@ type OnSelectedChangeCallback = React.ComponentProps<
|
||||||
typeof ManageIndexersModalRow
|
typeof ManageIndexersModalRow
|
||||||
>['onSelectedChange'];
|
>['onSelectedChange'];
|
||||||
|
|
||||||
const COLUMNS = [
|
const COLUMNS: Column[] = [
|
||||||
{
|
{
|
||||||
name: 'name',
|
name: 'name',
|
||||||
label: () => translate('Name'),
|
label: () => translate('Name'),
|
||||||
|
@ -82,8 +82,6 @@ const COLUMNS = [
|
||||||
|
|
||||||
interface ManageIndexersModalContentProps {
|
interface ManageIndexersModalContentProps {
|
||||||
onModalClose(): void;
|
onModalClose(): void;
|
||||||
sortKey?: string;
|
|
||||||
sortDirection?: SortDirection;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function ManageIndexersModalContent(props: ManageIndexersModalContentProps) {
|
function ManageIndexersModalContent(props: ManageIndexersModalContentProps) {
|
||||||
|
|
|
@ -94,9 +94,9 @@ class RootFolder extends Component {
|
||||||
<ConfirmModal
|
<ConfirmModal
|
||||||
isOpen={this.state.isDeleteRootFolderModalOpen}
|
isOpen={this.state.isDeleteRootFolderModalOpen}
|
||||||
kind={kinds.DANGER}
|
kind={kinds.DANGER}
|
||||||
title={translate('DeleteRootFolder')}
|
title={translate('RemoveRootFolder')}
|
||||||
message={translate('DeleteRootFolderMessageText', { name })}
|
message={translate('RemoveRootFolderArtistsMessageText', { name })}
|
||||||
confirmLabel={translate('Delete')}
|
confirmLabel={translate('Remove')}
|
||||||
onConfirm={this.onConfirmDeleteRootFolder}
|
onConfirm={this.onConfirmDeleteRootFolder}
|
||||||
onCancel={this.onDeleteRootFolderModalClose}
|
onCancel={this.onDeleteRootFolderModalClose}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -24,19 +24,19 @@
|
||||||
height: 20px;
|
height: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.bar {
|
.track {
|
||||||
top: 9px;
|
top: 9px;
|
||||||
margin: 0 5px;
|
margin: 0 5px;
|
||||||
height: 3px;
|
height: 3px;
|
||||||
background-color: var(--sliderAccentColor);
|
background-color: var(--sliderAccentColor);
|
||||||
box-shadow: 0 0 0 #000;
|
box-shadow: 0 0 0 #000;
|
||||||
|
|
||||||
&:nth-child(3n+1) {
|
&:nth-child(3n + 1) {
|
||||||
background-color: #ddd;
|
background-color: #ddd;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.handle {
|
.thumb {
|
||||||
top: 1px;
|
top: 1px;
|
||||||
z-index: 0 !important;
|
z-index: 0 !important;
|
||||||
width: 18px;
|
width: 18px;
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
// This file is automatically generated.
|
// This file is automatically generated.
|
||||||
// Please do not change this file!
|
// Please do not change this file!
|
||||||
interface CssExports {
|
interface CssExports {
|
||||||
'bar': string;
|
|
||||||
'handle': string;
|
|
||||||
'kilobitsPerSecond': string;
|
'kilobitsPerSecond': string;
|
||||||
'quality': string;
|
'quality': string;
|
||||||
'qualityDefinition': string;
|
'qualityDefinition': string;
|
||||||
|
@ -10,7 +8,9 @@ interface CssExports {
|
||||||
'sizeLimit': string;
|
'sizeLimit': string;
|
||||||
'sizes': string;
|
'sizes': string;
|
||||||
'slider': string;
|
'slider': string;
|
||||||
|
'thumb': string;
|
||||||
'title': string;
|
'title': string;
|
||||||
|
'track': string;
|
||||||
}
|
}
|
||||||
export const cssExports: CssExports;
|
export const cssExports: CssExports;
|
||||||
export default cssExports;
|
export default cssExports;
|
||||||
|
|
|
@ -55,6 +55,27 @@ class QualityDefinition extends Component {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Control
|
||||||
|
|
||||||
|
trackRenderer(props, state) {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
{...props}
|
||||||
|
className={styles.track}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
thumbRenderer(props, state) {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
{...props}
|
||||||
|
className={styles.thumb}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Listeners
|
// Listeners
|
||||||
|
|
||||||
|
@ -174,6 +195,7 @@ class QualityDefinition extends Component {
|
||||||
|
|
||||||
<div className={styles.sizeLimit}>
|
<div className={styles.sizeLimit}>
|
||||||
<ReactSlider
|
<ReactSlider
|
||||||
|
className={styles.slider}
|
||||||
min={slider.min}
|
min={slider.min}
|
||||||
max={slider.max}
|
max={slider.max}
|
||||||
step={slider.step}
|
step={slider.step}
|
||||||
|
@ -182,9 +204,9 @@ class QualityDefinition extends Component {
|
||||||
withTracks={true}
|
withTracks={true}
|
||||||
allowCross={false}
|
allowCross={false}
|
||||||
snapDragDisabled={true}
|
snapDragDisabled={true}
|
||||||
className={styles.slider}
|
pearling={true}
|
||||||
trackClassName={styles.bar}
|
renderThumb={this.thumbRenderer}
|
||||||
thumbClassName={styles.handle}
|
renderTrack={this.trackRenderer}
|
||||||
onChange={this.onSliderChange}
|
onChange={this.onSliderChange}
|
||||||
onAfterChange={this.onAfterSliderChange}
|
onAfterChange={this.onAfterSliderChange}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -151,7 +151,7 @@ export const defaultState = {
|
||||||
{
|
{
|
||||||
name: 'genres',
|
name: 'genres',
|
||||||
label: () => translate('Genres'),
|
label: () => translate('Genres'),
|
||||||
isSortable: false,
|
isSortable: true,
|
||||||
isVisible: false
|
isVisible: false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import Alert from 'Components/Alert';
|
import Alert from 'Components/Alert';
|
||||||
import Link from 'Components/Link/Link';
|
|
||||||
import LoadingIndicator from 'Components/Loading/LoadingIndicator';
|
import LoadingIndicator from 'Components/Loading/LoadingIndicator';
|
||||||
|
import InlineMarkdown from 'Components/Markdown/InlineMarkdown';
|
||||||
import PageContent from 'Components/Page/PageContent';
|
import PageContent from 'Components/Page/PageContent';
|
||||||
import PageContentBody from 'Components/Page/PageContentBody';
|
import PageContentBody from 'Components/Page/PageContentBody';
|
||||||
import PageToolbar from 'Components/Page/Toolbar/PageToolbar';
|
import PageToolbar from 'Components/Page/Toolbar/PageToolbar';
|
||||||
|
@ -77,15 +77,16 @@ class LogFiles extends Component {
|
||||||
<PageContentBody>
|
<PageContentBody>
|
||||||
<Alert>
|
<Alert>
|
||||||
<div>
|
<div>
|
||||||
Log files are located in: {location}
|
{translate('LogFilesLocation', {
|
||||||
|
location
|
||||||
|
})}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{
|
{currentLogView === 'Log Files' ? (
|
||||||
currentLogView === 'Log Files' &&
|
<div>
|
||||||
<div>
|
<InlineMarkdown data={translate('TheLogLevelDefault')} />
|
||||||
The log level defaults to 'Info' and can be changed in <Link to="/settings/general">General Settings</Link>
|
</div>
|
||||||
</div>
|
) : null}
|
||||||
}
|
|
||||||
</Alert>
|
</Alert>
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
|
@ -270,7 +270,7 @@ function Updates() {
|
||||||
|
|
||||||
{generalSettingsError ? (
|
{generalSettingsError ? (
|
||||||
<Alert kind={kinds.DANGER}>
|
<Alert kind={kinds.DANGER}>
|
||||||
{translate('FailedToUpdateSettings')}
|
{translate('FailedToFetchSettings')}
|
||||||
</Alert>
|
</Alert>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
|
|
|
@ -109,7 +109,7 @@
|
||||||
"babel-loader": "9.2.1",
|
"babel-loader": "9.2.1",
|
||||||
"babel-plugin-inline-classnames": "2.0.1",
|
"babel-plugin-inline-classnames": "2.0.1",
|
||||||
"babel-plugin-transform-react-remove-prop-types": "0.4.24",
|
"babel-plugin-transform-react-remove-prop-types": "0.4.24",
|
||||||
"core-js": "3.39.0",
|
"core-js": "3.41.0",
|
||||||
"css-loader": "6.7.3",
|
"css-loader": "6.7.3",
|
||||||
"css-modules-typescript-loader": "4.0.1",
|
"css-modules-typescript-loader": "4.0.1",
|
||||||
"eslint": "8.57.1",
|
"eslint": "8.57.1",
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
|
using FluentValidation;
|
||||||
using Lidarr.Http;
|
using Lidarr.Http;
|
||||||
using NzbDrone.Core.Download;
|
using NzbDrone.Core.Download;
|
||||||
|
using NzbDrone.SignalR;
|
||||||
|
|
||||||
namespace Lidarr.Api.V1.DownloadClient
|
namespace Lidarr.Api.V1.DownloadClient
|
||||||
{
|
{
|
||||||
|
@ -9,9 +11,10 @@ namespace Lidarr.Api.V1.DownloadClient
|
||||||
public static readonly DownloadClientResourceMapper ResourceMapper = new ();
|
public static readonly DownloadClientResourceMapper ResourceMapper = new ();
|
||||||
public static readonly DownloadClientBulkResourceMapper BulkResourceMapper = new ();
|
public static readonly DownloadClientBulkResourceMapper BulkResourceMapper = new ();
|
||||||
|
|
||||||
public DownloadClientController(IDownloadClientFactory downloadClientFactory)
|
public DownloadClientController(IBroadcastSignalRMessage signalRBroadcaster, IDownloadClientFactory downloadClientFactory)
|
||||||
: base(downloadClientFactory, "downloadclient", ResourceMapper, BulkResourceMapper)
|
: base(signalRBroadcaster, downloadClientFactory, "downloadclient", ResourceMapper, BulkResourceMapper)
|
||||||
{
|
{
|
||||||
|
SharedValidator.RuleFor(c => c.Priority).InclusiveBetween(1, 50);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Lidarr.Http.REST;
|
using Lidarr.Http.REST;
|
||||||
using NzbDrone.Common.Http;
|
|
||||||
using NzbDrone.Core.HealthCheck;
|
using NzbDrone.Core.HealthCheck;
|
||||||
|
|
||||||
namespace Lidarr.Api.V1.Health
|
namespace Lidarr.Api.V1.Health
|
||||||
|
@ -11,7 +10,7 @@ namespace Lidarr.Api.V1.Health
|
||||||
public string Source { get; set; }
|
public string Source { get; set; }
|
||||||
public HealthCheckResult Type { get; set; }
|
public HealthCheckResult Type { get; set; }
|
||||||
public string Message { get; set; }
|
public string Message { get; set; }
|
||||||
public HttpUri WikiUrl { get; set; }
|
public string WikiUrl { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class HealthResourceMapper
|
public static class HealthResourceMapper
|
||||||
|
@ -29,7 +28,7 @@ namespace Lidarr.Api.V1.Health
|
||||||
Source = model.Source.Name,
|
Source = model.Source.Name,
|
||||||
Type = model.Type,
|
Type = model.Type,
|
||||||
Message = model.Message,
|
Message = model.Message,
|
||||||
WikiUrl = model.WikiUrl
|
WikiUrl = model.WikiUrl.FullUri
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ using Lidarr.Http;
|
||||||
using NzbDrone.Core.ImportLists;
|
using NzbDrone.Core.ImportLists;
|
||||||
using NzbDrone.Core.Validation;
|
using NzbDrone.Core.Validation;
|
||||||
using NzbDrone.Core.Validation.Paths;
|
using NzbDrone.Core.Validation.Paths;
|
||||||
|
using NzbDrone.SignalR;
|
||||||
|
|
||||||
namespace Lidarr.Api.V1.ImportLists
|
namespace Lidarr.Api.V1.ImportLists
|
||||||
{
|
{
|
||||||
|
@ -12,11 +13,12 @@ namespace Lidarr.Api.V1.ImportLists
|
||||||
public static readonly ImportListResourceMapper ResourceMapper = new ();
|
public static readonly ImportListResourceMapper ResourceMapper = new ();
|
||||||
public static readonly ImportListBulkResourceMapper BulkResourceMapper = new ();
|
public static readonly ImportListBulkResourceMapper BulkResourceMapper = new ();
|
||||||
|
|
||||||
public ImportListController(IImportListFactory importListFactory,
|
public ImportListController(IBroadcastSignalRMessage signalRBroadcaster,
|
||||||
RootFolderExistsValidator rootFolderExistsValidator,
|
IImportListFactory importListFactory,
|
||||||
QualityProfileExistsValidator qualityProfileExistsValidator,
|
RootFolderExistsValidator rootFolderExistsValidator,
|
||||||
MetadataProfileExistsValidator metadataProfileExistsValidator)
|
QualityProfileExistsValidator qualityProfileExistsValidator,
|
||||||
: base(importListFactory, "importlist", ResourceMapper, BulkResourceMapper)
|
MetadataProfileExistsValidator metadataProfileExistsValidator)
|
||||||
|
: base(signalRBroadcaster, importListFactory, "importlist", ResourceMapper, BulkResourceMapper)
|
||||||
{
|
{
|
||||||
SharedValidator.RuleFor(c => c.RootFolderPath).Cascade(CascadeMode.Stop)
|
SharedValidator.RuleFor(c => c.RootFolderPath).Cascade(CascadeMode.Stop)
|
||||||
.IsValidPath()
|
.IsValidPath()
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
|
using FluentValidation;
|
||||||
using Lidarr.Http;
|
using Lidarr.Http;
|
||||||
using NzbDrone.Core.Indexers;
|
using NzbDrone.Core.Indexers;
|
||||||
using NzbDrone.Core.Validation;
|
using NzbDrone.Core.Validation;
|
||||||
|
using NzbDrone.SignalR;
|
||||||
|
|
||||||
namespace Lidarr.Api.V1.Indexers
|
namespace Lidarr.Api.V1.Indexers
|
||||||
{
|
{
|
||||||
|
@ -10,9 +12,12 @@ namespace Lidarr.Api.V1.Indexers
|
||||||
public static readonly IndexerResourceMapper ResourceMapper = new ();
|
public static readonly IndexerResourceMapper ResourceMapper = new ();
|
||||||
public static readonly IndexerBulkResourceMapper BulkResourceMapper = new ();
|
public static readonly IndexerBulkResourceMapper BulkResourceMapper = new ();
|
||||||
|
|
||||||
public IndexerController(IndexerFactory indexerFactory, DownloadClientExistsValidator downloadClientExistsValidator)
|
public IndexerController(IBroadcastSignalRMessage signalRBroadcaster,
|
||||||
: base(indexerFactory, "indexer", ResourceMapper, BulkResourceMapper)
|
IndexerFactory indexerFactory,
|
||||||
|
DownloadClientExistsValidator downloadClientExistsValidator)
|
||||||
|
: base(signalRBroadcaster, indexerFactory, "indexer", ResourceMapper, BulkResourceMapper)
|
||||||
{
|
{
|
||||||
|
SharedValidator.RuleFor(c => c.Priority).InclusiveBetween(1, 50);
|
||||||
SharedValidator.RuleFor(c => c.DownloadClientId).SetValidator(downloadClientExistsValidator);
|
SharedValidator.RuleFor(c => c.DownloadClientId).SetValidator(downloadClientExistsValidator);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
<PackageReference Include="System.Reflection.TypeExtensions" Version="4.7.0" />
|
<PackageReference Include="System.Reflection.TypeExtensions" Version="4.7.0" />
|
||||||
<PackageReference Include="FluentValidation" Version="9.5.4" />
|
<PackageReference Include="FluentValidation" Version="9.5.4" />
|
||||||
<PackageReference Include="Ical.Net" Version="4.3.1" />
|
<PackageReference Include="Ical.Net" Version="4.3.1" />
|
||||||
<PackageReference Include="NLog" Version="5.3.4" />
|
<PackageReference Include="NLog" Version="5.4.0" />
|
||||||
<PackageReference Include="System.IO.Abstractions" Version="17.0.24" />
|
<PackageReference Include="System.IO.Abstractions" Version="17.0.24" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
@ -2,6 +2,7 @@ using System;
|
||||||
using Lidarr.Http;
|
using Lidarr.Http;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using NzbDrone.Core.Extras.Metadata;
|
using NzbDrone.Core.Extras.Metadata;
|
||||||
|
using NzbDrone.SignalR;
|
||||||
|
|
||||||
namespace Lidarr.Api.V1.Metadata
|
namespace Lidarr.Api.V1.Metadata
|
||||||
{
|
{
|
||||||
|
@ -11,8 +12,8 @@ namespace Lidarr.Api.V1.Metadata
|
||||||
public static readonly MetadataResourceMapper ResourceMapper = new ();
|
public static readonly MetadataResourceMapper ResourceMapper = new ();
|
||||||
public static readonly MetadataBulkResourceMapper BulkResourceMapper = new ();
|
public static readonly MetadataBulkResourceMapper BulkResourceMapper = new ();
|
||||||
|
|
||||||
public MetadataController(IMetadataFactory metadataFactory)
|
public MetadataController(IBroadcastSignalRMessage signalRBroadcaster, IMetadataFactory metadataFactory)
|
||||||
: base(metadataFactory, "metadata", ResourceMapper, BulkResourceMapper)
|
: base(signalRBroadcaster, metadataFactory, "metadata", ResourceMapper, BulkResourceMapper)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ using System;
|
||||||
using Lidarr.Http;
|
using Lidarr.Http;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using NzbDrone.Core.Notifications;
|
using NzbDrone.Core.Notifications;
|
||||||
|
using NzbDrone.SignalR;
|
||||||
|
|
||||||
namespace Lidarr.Api.V1.Notifications
|
namespace Lidarr.Api.V1.Notifications
|
||||||
{
|
{
|
||||||
|
@ -11,8 +12,8 @@ namespace Lidarr.Api.V1.Notifications
|
||||||
public static readonly NotificationResourceMapper ResourceMapper = new ();
|
public static readonly NotificationResourceMapper ResourceMapper = new ();
|
||||||
public static readonly NotificationBulkResourceMapper BulkResourceMapper = new ();
|
public static readonly NotificationBulkResourceMapper BulkResourceMapper = new ();
|
||||||
|
|
||||||
public NotificationController(NotificationFactory notificationFactory)
|
public NotificationController(IBroadcastSignalRMessage signalRBroadcaster, NotificationFactory notificationFactory)
|
||||||
: base(notificationFactory, "notification", ResourceMapper, BulkResourceMapper)
|
: base(signalRBroadcaster, notificationFactory, "notification", ResourceMapper, BulkResourceMapper)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,12 +7,19 @@ using Lidarr.Http.REST.Attributes;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using NzbDrone.Common.Extensions;
|
using NzbDrone.Common.Extensions;
|
||||||
using NzbDrone.Common.Serializer;
|
using NzbDrone.Common.Serializer;
|
||||||
|
using NzbDrone.Core.Datastore.Events;
|
||||||
|
using NzbDrone.Core.Messaging.Events;
|
||||||
using NzbDrone.Core.ThingiProvider;
|
using NzbDrone.Core.ThingiProvider;
|
||||||
|
using NzbDrone.Core.ThingiProvider.Events;
|
||||||
using NzbDrone.Core.Validation;
|
using NzbDrone.Core.Validation;
|
||||||
|
using NzbDrone.SignalR;
|
||||||
|
|
||||||
namespace Lidarr.Api.V1
|
namespace Lidarr.Api.V1
|
||||||
{
|
{
|
||||||
public abstract class ProviderControllerBase<TProviderResource, TBulkProviderResource, TProvider, TProviderDefinition> : RestController<TProviderResource>
|
public abstract class ProviderControllerBase<TProviderResource, TBulkProviderResource, TProvider, TProviderDefinition> : RestControllerWithSignalR<TProviderResource, TProviderDefinition>,
|
||||||
|
IHandle<ProviderAddedEvent<TProvider>>,
|
||||||
|
IHandle<ProviderUpdatedEvent<TProvider>>,
|
||||||
|
IHandle<ProviderDeletedEvent<TProvider>>
|
||||||
where TProviderDefinition : ProviderDefinition, new()
|
where TProviderDefinition : ProviderDefinition, new()
|
||||||
where TProvider : IProvider
|
where TProvider : IProvider
|
||||||
where TProviderResource : ProviderResource<TProviderResource>, new()
|
where TProviderResource : ProviderResource<TProviderResource>, new()
|
||||||
|
@ -22,11 +29,13 @@ namespace Lidarr.Api.V1
|
||||||
private readonly ProviderResourceMapper<TProviderResource, TProviderDefinition> _resourceMapper;
|
private readonly ProviderResourceMapper<TProviderResource, TProviderDefinition> _resourceMapper;
|
||||||
private readonly ProviderBulkResourceMapper<TBulkProviderResource, TProviderDefinition> _bulkResourceMapper;
|
private readonly ProviderBulkResourceMapper<TBulkProviderResource, TProviderDefinition> _bulkResourceMapper;
|
||||||
|
|
||||||
protected ProviderControllerBase(IProviderFactory<TProvider,
|
protected ProviderControllerBase(IBroadcastSignalRMessage signalRBroadcaster,
|
||||||
|
IProviderFactory<TProvider,
|
||||||
TProviderDefinition> providerFactory,
|
TProviderDefinition> providerFactory,
|
||||||
string resource,
|
string resource,
|
||||||
ProviderResourceMapper<TProviderResource, TProviderDefinition> resourceMapper,
|
ProviderResourceMapper<TProviderResource, TProviderDefinition> resourceMapper,
|
||||||
ProviderBulkResourceMapper<TBulkProviderResource, TProviderDefinition> bulkResourceMapper)
|
ProviderBulkResourceMapper<TBulkProviderResource, TProviderDefinition> bulkResourceMapper)
|
||||||
|
: base(signalRBroadcaster)
|
||||||
{
|
{
|
||||||
_providerFactory = providerFactory;
|
_providerFactory = providerFactory;
|
||||||
_resourceMapper = resourceMapper;
|
_resourceMapper = resourceMapper;
|
||||||
|
@ -261,6 +270,24 @@ namespace Lidarr.Api.V1
|
||||||
return Content(data.ToJson(), "application/json");
|
return Content(data.ToJson(), "application/json");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[NonAction]
|
||||||
|
public virtual void Handle(ProviderAddedEvent<TProvider> message)
|
||||||
|
{
|
||||||
|
BroadcastResourceChange(ModelAction.Created, message.Definition.Id);
|
||||||
|
}
|
||||||
|
|
||||||
|
[NonAction]
|
||||||
|
public virtual void Handle(ProviderUpdatedEvent<TProvider> message)
|
||||||
|
{
|
||||||
|
BroadcastResourceChange(ModelAction.Updated, message.Definition.Id);
|
||||||
|
}
|
||||||
|
|
||||||
|
[NonAction]
|
||||||
|
public virtual void Handle(ProviderDeletedEvent<TProvider> message)
|
||||||
|
{
|
||||||
|
BroadcastResourceChange(ModelAction.Deleted, message.ProviderId);
|
||||||
|
}
|
||||||
|
|
||||||
protected virtual void Validate(TProviderDefinition definition, bool includeWarnings)
|
protected virtual void Validate(TProviderDefinition definition, bool includeWarnings)
|
||||||
{
|
{
|
||||||
var validationResult = definition.Settings.Validate();
|
var validationResult = definition.Settings.Validate();
|
||||||
|
|
|
@ -4,6 +4,7 @@ using Lidarr.Http;
|
||||||
using Lidarr.Http.REST;
|
using Lidarr.Http.REST;
|
||||||
using Lidarr.Http.REST.Attributes;
|
using Lidarr.Http.REST.Attributes;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using NzbDrone.Common.Extensions;
|
||||||
using NzbDrone.Core.RemotePathMappings;
|
using NzbDrone.Core.RemotePathMappings;
|
||||||
using NzbDrone.Core.Validation.Paths;
|
using NzbDrone.Core.Validation.Paths;
|
||||||
|
|
||||||
|
@ -21,17 +22,28 @@ namespace Lidarr.Api.V1.RemotePathMappings
|
||||||
_remotePathMappingService = remotePathMappingService;
|
_remotePathMappingService = remotePathMappingService;
|
||||||
|
|
||||||
SharedValidator.RuleFor(c => c.Host)
|
SharedValidator.RuleFor(c => c.Host)
|
||||||
.NotEmpty();
|
.NotEmpty();
|
||||||
|
|
||||||
// We cannot use IsValidPath here, because it's a remote path, possibly other OS.
|
// We cannot use IsValidPath here, because it's a remote path, possibly other OS.
|
||||||
SharedValidator.RuleFor(c => c.RemotePath)
|
SharedValidator.RuleFor(c => c.RemotePath)
|
||||||
.NotEmpty();
|
.NotEmpty();
|
||||||
|
|
||||||
|
SharedValidator.RuleFor(c => c.RemotePath)
|
||||||
|
.Must(remotePath => remotePath.IsNotNullOrWhiteSpace() && !remotePath.StartsWith(" "))
|
||||||
|
.WithMessage("Remote Path '{PropertyValue}' must not start with a space");
|
||||||
|
|
||||||
|
SharedValidator.RuleFor(c => c.RemotePath)
|
||||||
|
.Must(remotePath => remotePath.IsNotNullOrWhiteSpace() && !remotePath.EndsWith(" "))
|
||||||
|
.WithMessage("Remote Path '{PropertyValue}' must not end with a space");
|
||||||
|
|
||||||
SharedValidator.RuleFor(c => c.LocalPath)
|
SharedValidator.RuleFor(c => c.LocalPath)
|
||||||
.Cascade(CascadeMode.Stop)
|
.Cascade(CascadeMode.Stop)
|
||||||
.IsValidPath()
|
.IsValidPath()
|
||||||
.SetValidator(mappedNetworkDriveValidator)
|
.SetValidator(mappedNetworkDriveValidator)
|
||||||
.SetValidator(pathExistsValidator);
|
.SetValidator(pathExistsValidator)
|
||||||
|
.SetValidator(new SystemFolderValidator())
|
||||||
|
.NotEqual("/")
|
||||||
|
.WithMessage("Cannot be set to '/'");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override RemotePathMappingResource GetResourceById(int id)
|
public override RemotePathMappingResource GetResourceById(int id)
|
||||||
|
@ -41,7 +53,7 @@ namespace Lidarr.Api.V1.RemotePathMappings
|
||||||
|
|
||||||
[RestPostById]
|
[RestPostById]
|
||||||
[Consumes("application/json")]
|
[Consumes("application/json")]
|
||||||
public ActionResult<RemotePathMappingResource> CreateMapping(RemotePathMappingResource resource)
|
public ActionResult<RemotePathMappingResource> CreateMapping([FromBody] RemotePathMappingResource resource)
|
||||||
{
|
{
|
||||||
var model = resource.ToModel();
|
var model = resource.ToModel();
|
||||||
|
|
||||||
|
@ -62,7 +74,7 @@ namespace Lidarr.Api.V1.RemotePathMappings
|
||||||
}
|
}
|
||||||
|
|
||||||
[RestPutById]
|
[RestPutById]
|
||||||
public ActionResult<RemotePathMappingResource> UpdateMapping(RemotePathMappingResource resource)
|
public ActionResult<RemotePathMappingResource> UpdateMapping([FromBody] RemotePathMappingResource resource)
|
||||||
{
|
{
|
||||||
var mapping = resource.ToModel();
|
var mapping = resource.ToModel();
|
||||||
|
|
||||||
|
|
|
@ -92,7 +92,7 @@ namespace Lidarr.Api.V1.System.Backup
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost("restore/upload")]
|
[HttpPost("restore/upload")]
|
||||||
[RequestFormLimits(MultipartBodyLengthLimit = 1000000000)]
|
[RequestFormLimits(MultipartBodyLengthLimit = 5000000000)]
|
||||||
public object UploadAndRestore()
|
public object UploadAndRestore()
|
||||||
{
|
{
|
||||||
var files = Request.Form.Files;
|
var files = Request.Form.Files;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using FluentValidation;
|
||||||
using Lidarr.Http;
|
using Lidarr.Http;
|
||||||
using Lidarr.Http.REST;
|
using Lidarr.Http.REST;
|
||||||
using Lidarr.Http.REST.Attributes;
|
using Lidarr.Http.REST.Attributes;
|
||||||
|
@ -23,6 +24,8 @@ namespace Lidarr.Api.V1.Tags
|
||||||
: base(signalRBroadcaster)
|
: base(signalRBroadcaster)
|
||||||
{
|
{
|
||||||
_tagService = tagService;
|
_tagService = tagService;
|
||||||
|
|
||||||
|
SharedValidator.RuleFor(c => c.Label).NotEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override TagResource GetResourceById(int id)
|
public override TagResource GetResourceById(int id)
|
||||||
|
|
|
@ -9808,7 +9808,8 @@
|
||||||
"nullable": true
|
"nullable": true
|
||||||
},
|
},
|
||||||
"wikiUrl": {
|
"wikiUrl": {
|
||||||
"$ref": "#/components/schemas/HttpUri"
|
"type": "string",
|
||||||
|
"nullable": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"additionalProperties": false
|
"additionalProperties": false
|
||||||
|
@ -10062,48 +10063,6 @@
|
||||||
},
|
},
|
||||||
"additionalProperties": false
|
"additionalProperties": false
|
||||||
},
|
},
|
||||||
"HttpUri": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"fullUri": {
|
|
||||||
"type": "string",
|
|
||||||
"nullable": true,
|
|
||||||
"readOnly": true
|
|
||||||
},
|
|
||||||
"scheme": {
|
|
||||||
"type": "string",
|
|
||||||
"nullable": true,
|
|
||||||
"readOnly": true
|
|
||||||
},
|
|
||||||
"host": {
|
|
||||||
"type": "string",
|
|
||||||
"nullable": true,
|
|
||||||
"readOnly": true
|
|
||||||
},
|
|
||||||
"port": {
|
|
||||||
"type": "integer",
|
|
||||||
"format": "int32",
|
|
||||||
"nullable": true,
|
|
||||||
"readOnly": true
|
|
||||||
},
|
|
||||||
"path": {
|
|
||||||
"type": "string",
|
|
||||||
"nullable": true,
|
|
||||||
"readOnly": true
|
|
||||||
},
|
|
||||||
"query": {
|
|
||||||
"type": "string",
|
|
||||||
"nullable": true,
|
|
||||||
"readOnly": true
|
|
||||||
},
|
|
||||||
"fragment": {
|
|
||||||
"type": "string",
|
|
||||||
"nullable": true,
|
|
||||||
"readOnly": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"additionalProperties": false
|
|
||||||
},
|
|
||||||
"ImportListBulkResource": {
|
"ImportListBulkResource": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
|
|
@ -1,9 +1,14 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
|
using System.Security.Cryptography;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using System.Xml;
|
||||||
using Microsoft.AspNetCore.Authentication;
|
using Microsoft.AspNetCore.Authentication;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using NLog;
|
||||||
|
using NzbDrone.Common.EnvironmentInfo;
|
||||||
using NzbDrone.Common.Extensions;
|
using NzbDrone.Common.Extensions;
|
||||||
using NzbDrone.Core.Authentication;
|
using NzbDrone.Core.Authentication;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
|
@ -16,11 +21,15 @@ namespace Lidarr.Http.Authentication
|
||||||
{
|
{
|
||||||
private readonly IAuthenticationService _authService;
|
private readonly IAuthenticationService _authService;
|
||||||
private readonly IConfigFileProvider _configFileProvider;
|
private readonly IConfigFileProvider _configFileProvider;
|
||||||
|
private readonly IAppFolderInfo _appFolderInfo;
|
||||||
|
private readonly Logger _logger;
|
||||||
|
|
||||||
public AuthenticationController(IAuthenticationService authService, IConfigFileProvider configFileProvider)
|
public AuthenticationController(IAuthenticationService authService, IConfigFileProvider configFileProvider, IAppFolderInfo appFolderInfo, Logger logger)
|
||||||
{
|
{
|
||||||
_authService = authService;
|
_authService = authService;
|
||||||
_configFileProvider = configFileProvider;
|
_configFileProvider = configFileProvider;
|
||||||
|
_appFolderInfo = appFolderInfo;
|
||||||
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost("login")]
|
[HttpPost("login")]
|
||||||
|
@ -45,7 +54,23 @@ namespace Lidarr.Http.Authentication
|
||||||
IsPersistent = resource.RememberMe == "on"
|
IsPersistent = resource.RememberMe == "on"
|
||||||
};
|
};
|
||||||
|
|
||||||
await HttpContext.SignInAsync(AuthenticationType.Forms.ToString(), new ClaimsPrincipal(new ClaimsIdentity(claims, "Cookies", "user", "identifier")), authProperties);
|
try
|
||||||
|
{
|
||||||
|
await HttpContext.SignInAsync(AuthenticationType.Forms.ToString(), new ClaimsPrincipal(new ClaimsIdentity(claims, "Cookies", "user", "identifier")), authProperties);
|
||||||
|
}
|
||||||
|
catch (CryptographicException e)
|
||||||
|
{
|
||||||
|
if (e.InnerException is XmlException)
|
||||||
|
{
|
||||||
|
_logger.Error(e, "Failed to authenticate user due to corrupt XML. Please remove all XML files from {0} and restart Lidarr", Path.Combine(_appFolderInfo.AppDataFolder, "asp"));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_logger.Error(e, "Failed to authenticate user. {0}", e.Message);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Unauthorized();
|
||||||
|
}
|
||||||
|
|
||||||
if (returnUrl.IsNullOrWhiteSpace() || !Url.IsLocalUrl(returnUrl))
|
if (returnUrl.IsNullOrWhiteSpace() || !Url.IsLocalUrl(returnUrl))
|
||||||
{
|
{
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="FluentValidation" Version="9.5.4" />
|
<PackageReference Include="FluentValidation" Version="9.5.4" />
|
||||||
<PackageReference Include="ImpromptuInterface" Version="7.0.1" />
|
<PackageReference Include="ImpromptuInterface" Version="7.0.1" />
|
||||||
<PackageReference Include="NLog" Version="5.3.4" />
|
<PackageReference Include="NLog" Version="5.4.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\NzbDrone.Core\Lidarr.Core.csproj" />
|
<ProjectReference Include="..\NzbDrone.Core\Lidarr.Core.csproj" />
|
||||||
|
|
|
@ -40,15 +40,16 @@ namespace NzbDrone.Automation.Test
|
||||||
var service = ChromeDriverService.CreateDefaultService();
|
var service = ChromeDriverService.CreateDefaultService();
|
||||||
|
|
||||||
// Timeout as windows automation tests seem to take alot longer to get going
|
// Timeout as windows automation tests seem to take alot longer to get going
|
||||||
driver = new ChromeDriver(service, options, new TimeSpan(0, 3, 0));
|
driver = new ChromeDriver(service, options, TimeSpan.FromMinutes(3));
|
||||||
|
|
||||||
driver.Manage().Window.Size = new System.Drawing.Size(1920, 1080);
|
driver.Manage().Window.Size = new System.Drawing.Size(1920, 1080);
|
||||||
|
driver.Manage().Window.FullScreen();
|
||||||
|
|
||||||
_runner = new NzbDroneRunner(LogManager.GetCurrentClassLogger(), null);
|
_runner = new NzbDroneRunner(LogManager.GetCurrentClassLogger(), null);
|
||||||
_runner.KillAll();
|
_runner.KillAll();
|
||||||
_runner.Start(true);
|
_runner.Start(true);
|
||||||
|
|
||||||
driver.Url = "http://localhost:8686";
|
driver.Navigate().GoToUrl("http://localhost:8686");
|
||||||
|
|
||||||
var page = new PageBase(driver);
|
var page = new PageBase(driver);
|
||||||
page.WaitForNoSpinner();
|
page.WaitForNoSpinner();
|
||||||
|
@ -68,7 +69,7 @@ namespace NzbDrone.Automation.Test
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var image = ((ITakesScreenshot)driver).GetScreenshot();
|
var image = (driver as ITakesScreenshot).GetScreenshot();
|
||||||
image.SaveAsFile($"./{name}_test_screenshot.png", ScreenshotImageFormat.Png);
|
image.SaveAsFile($"./{name}_test_screenshot.png", ScreenshotImageFormat.Png);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Selenium.Support" Version="3.141.0" />
|
<PackageReference Include="Selenium.Support" Version="3.141.0" />
|
||||||
<PackageReference Include="Selenium.WebDriver.ChromeDriver" Version="111.0.5563.6400" />
|
<PackageReference Include="Selenium.WebDriver.ChromeDriver" Version="134.0.6998.16500" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\NzbDrone.Test.Common\Lidarr.Test.Common.csproj" />
|
<ProjectReference Include="..\NzbDrone.Test.Common\Lidarr.Test.Common.csproj" />
|
||||||
|
|
|
@ -1,19 +1,17 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using OpenQA.Selenium;
|
using OpenQA.Selenium;
|
||||||
using OpenQA.Selenium.Remote;
|
|
||||||
using OpenQA.Selenium.Support.UI;
|
using OpenQA.Selenium.Support.UI;
|
||||||
|
|
||||||
namespace NzbDrone.Automation.Test.PageModel
|
namespace NzbDrone.Automation.Test.PageModel
|
||||||
{
|
{
|
||||||
public class PageBase
|
public class PageBase
|
||||||
{
|
{
|
||||||
private readonly RemoteWebDriver _driver;
|
private readonly IWebDriver _driver;
|
||||||
|
|
||||||
public PageBase(RemoteWebDriver driver)
|
public PageBase(IWebDriver driver)
|
||||||
{
|
{
|
||||||
_driver = driver;
|
_driver = driver;
|
||||||
driver.Manage().Window.Maximize();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public IWebElement FindByClass(string className, int timeout = 5)
|
public IWebElement FindByClass(string className, int timeout = 5)
|
||||||
|
|
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.IO.Abstractions;
|
using System.IO.Abstractions;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Threading;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common.EnsureThat;
|
using NzbDrone.Common.EnsureThat;
|
||||||
using NzbDrone.Common.EnvironmentInfo;
|
using NzbDrone.Common.EnvironmentInfo;
|
||||||
|
@ -306,9 +307,26 @@ namespace NzbDrone.Common.Disk
|
||||||
{
|
{
|
||||||
Ensure.That(path, () => path).IsValidPath(PathValidationType.CurrentOs);
|
Ensure.That(path, () => path).IsValidPath(PathValidationType.CurrentOs);
|
||||||
|
|
||||||
var files = GetFiles(path, recursive);
|
var files = GetFiles(path, recursive).ToList();
|
||||||
|
|
||||||
files.ToList().ForEach(RemoveReadOnly);
|
files.ForEach(RemoveReadOnly);
|
||||||
|
|
||||||
|
var attempts = 0;
|
||||||
|
|
||||||
|
while (attempts < 3 && files.Any())
|
||||||
|
{
|
||||||
|
EmptyFolder(path);
|
||||||
|
|
||||||
|
if (GetFiles(path, recursive).Any())
|
||||||
|
{
|
||||||
|
// Wait for IO operations to complete after emptying the folder since they aren't always
|
||||||
|
// instantly removed and it can lead to false positives that files are still present.
|
||||||
|
Thread.Sleep(3000);
|
||||||
|
}
|
||||||
|
|
||||||
|
attempts++;
|
||||||
|
files = GetFiles(path, recursive).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
_fileSystem.Directory.Delete(path, recursive);
|
_fileSystem.Directory.Delete(path, recursive);
|
||||||
}
|
}
|
||||||
|
|
|
@ -141,7 +141,7 @@ namespace NzbDrone.Common.Http.Dispatchers
|
||||||
}
|
}
|
||||||
catch (OperationCanceledException ex) when (cts.IsCancellationRequested)
|
catch (OperationCanceledException ex) when (cts.IsCancellationRequested)
|
||||||
{
|
{
|
||||||
throw new WebException("Http request timed out", ex.InnerException, WebExceptionStatus.Timeout, null);
|
throw new WebException("Http request timed out", ex, WebExceptionStatus.Timeout, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,17 +6,17 @@
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="DryIoc.dll" Version="5.4.3" />
|
<PackageReference Include="DryIoc.dll" Version="5.4.3" />
|
||||||
<PackageReference Include="IPAddressRange" Version="6.1.0" />
|
<PackageReference Include="IPAddressRange" Version="6.2.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.1" />
|
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.1" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||||
<PackageReference Include="NLog" Version="5.3.4" />
|
<PackageReference Include="NLog" Version="5.4.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="6.0.2" />
|
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="6.0.2" />
|
||||||
<PackageReference Include="NLog.Layouts.ClefJsonLayout" Version="1.0.2" />
|
<PackageReference Include="NLog.Layouts.ClefJsonLayout" Version="1.0.3" />
|
||||||
<PackageReference Include="Sentry" Version="4.0.2" />
|
<PackageReference Include="Sentry" Version="4.0.2" />
|
||||||
<PackageReference Include="SharpZipLib" Version="1.4.2" />
|
<PackageReference Include="SharpZipLib" Version="1.4.2" />
|
||||||
<PackageReference Include="System.IO.Abstractions" Version="17.0.24" />
|
<PackageReference Include="System.IO.Abstractions" Version="17.0.24" />
|
||||||
<PackageReference Include="System.Text.Json" Version="6.0.10" />
|
<PackageReference Include="System.Text.Json" Version="6.0.10" />
|
||||||
<PackageReference Include="System.ValueTuple" Version="4.5.0" />
|
<PackageReference Include="System.ValueTuple" Version="4.6.1" />
|
||||||
<PackageReference Include="System.Data.SQLite.Core.Servarr" Version="1.0.115.5-18" />
|
<PackageReference Include="System.Data.SQLite.Core.Servarr" Version="1.0.115.5-18" />
|
||||||
<PackageReference Include="System.Runtime.Loader" Version="4.3.0" />
|
<PackageReference Include="System.Runtime.Loader" Version="4.3.0" />
|
||||||
<PackageReference Include="System.Configuration.ConfigurationManager" Version="6.0.1" />
|
<PackageReference Include="System.Configuration.ConfigurationManager" Version="6.0.1" />
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using NzbDrone.Common.EnvironmentInfo;
|
using NzbDrone.Common.EnvironmentInfo;
|
||||||
using NzbDrone.Common.Extensions;
|
using NzbDrone.Common.Extensions;
|
||||||
|
@ -6,7 +7,7 @@ namespace NzbDrone.Common
|
||||||
{
|
{
|
||||||
public class PathEqualityComparer : IEqualityComparer<string>
|
public class PathEqualityComparer : IEqualityComparer<string>
|
||||||
{
|
{
|
||||||
public static readonly PathEqualityComparer Instance = new PathEqualityComparer();
|
public static readonly PathEqualityComparer Instance = new ();
|
||||||
|
|
||||||
private PathEqualityComparer()
|
private PathEqualityComparer()
|
||||||
{
|
{
|
||||||
|
@ -19,12 +20,19 @@ namespace NzbDrone.Common
|
||||||
|
|
||||||
public int GetHashCode(string obj)
|
public int GetHashCode(string obj)
|
||||||
{
|
{
|
||||||
if (OsInfo.IsWindows)
|
try
|
||||||
{
|
{
|
||||||
return obj.CleanFilePath().Normalize().ToLower().GetHashCode();
|
if (OsInfo.IsWindows)
|
||||||
}
|
{
|
||||||
|
return obj.CleanFilePath().Normalize().ToLower().GetHashCode();
|
||||||
|
}
|
||||||
|
|
||||||
return obj.CleanFilePath().Normalize().GetHashCode();
|
return obj.CleanFilePath().Normalize().GetHashCode();
|
||||||
|
}
|
||||||
|
catch (ArgumentException ex)
|
||||||
|
{
|
||||||
|
throw new ArgumentException($"Invalid path: {obj}", ex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ using System.ComponentModel;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common.EnvironmentInfo;
|
using NzbDrone.Common.EnvironmentInfo;
|
||||||
using NzbDrone.Common.Model;
|
using NzbDrone.Common.Model;
|
||||||
|
@ -117,7 +118,9 @@ namespace NzbDrone.Common.Processes
|
||||||
UseShellExecute = false,
|
UseShellExecute = false,
|
||||||
RedirectStandardError = true,
|
RedirectStandardError = true,
|
||||||
RedirectStandardOutput = true,
|
RedirectStandardOutput = true,
|
||||||
RedirectStandardInput = true
|
RedirectStandardInput = true,
|
||||||
|
StandardOutputEncoding = Encoding.UTF8,
|
||||||
|
StandardErrorEncoding = Encoding.UTF8
|
||||||
};
|
};
|
||||||
|
|
||||||
if (environmentVariables != null)
|
if (environmentVariables != null)
|
||||||
|
|
|
@ -103,6 +103,7 @@ namespace NzbDrone.Core.Test.DiskSpace
|
||||||
[TestCase("/var/lib/docker")]
|
[TestCase("/var/lib/docker")]
|
||||||
[TestCase("/some/place/docker/aufs")]
|
[TestCase("/some/place/docker/aufs")]
|
||||||
[TestCase("/etc/network")]
|
[TestCase("/etc/network")]
|
||||||
|
[TestCase("/Volumes/.timemachine/ABC123456-A1BC-12A3B45678C9/2025-05-13-181401.backup")]
|
||||||
public void should_not_check_diskspace_for_irrelevant_mounts(string path)
|
public void should_not_check_diskspace_for_irrelevant_mounts(string path)
|
||||||
{
|
{
|
||||||
var mount = new Mock<IMount>();
|
var mount = new Mock<IMount>();
|
||||||
|
|
|
@ -80,7 +80,7 @@ namespace NzbDrone.Core.Test.ImportListTests
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
[Ignore("Pending mapping fixes", Until = "2025-04-20 00:00:00Z")]
|
[Ignore("Pending mapping fixes", Until = "2025-10-20 00:00:00Z")]
|
||||||
public void map_artist_should_work()
|
public void map_artist_should_work()
|
||||||
{
|
{
|
||||||
UseRealHttp();
|
UseRealHttp();
|
||||||
|
@ -159,7 +159,7 @@ namespace NzbDrone.Core.Test.ImportListTests
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
[Ignore("Pending mapping fixes", Until = "2025-04-20 00:00:00Z")]
|
[Ignore("Pending mapping fixes", Until = "2025-10-20 00:00:00Z")]
|
||||||
public void map_album_should_work()
|
public void map_album_should_work()
|
||||||
{
|
{
|
||||||
UseRealHttp();
|
UseRealHttp();
|
||||||
|
|
|
@ -14,6 +14,7 @@ using NzbDrone.Core.Test.Framework;
|
||||||
namespace NzbDrone.Core.Test.MetadataSource.SkyHook
|
namespace NzbDrone.Core.Test.MetadataSource.SkyHook
|
||||||
{
|
{
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
|
[Ignore("Waiting for metadata to be back again", Until = "2025-07-01 00:00:00Z")]
|
||||||
public class SkyHookProxyFixture : CoreTest<SkyHookProxy>
|
public class SkyHookProxyFixture : CoreTest<SkyHookProxy>
|
||||||
{
|
{
|
||||||
private MetadataProfile _metadataProfile;
|
private MetadataProfile _metadataProfile;
|
||||||
|
|
|
@ -12,6 +12,7 @@ using NzbDrone.Test.Common;
|
||||||
namespace NzbDrone.Core.Test.MetadataSource.SkyHook
|
namespace NzbDrone.Core.Test.MetadataSource.SkyHook
|
||||||
{
|
{
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
|
[Ignore("Waiting for metadata to be back again", Until = "2025-07-01 00:00:00Z")]
|
||||||
public class SkyHookProxySearchFixture : CoreTest<SkyHookProxy>
|
public class SkyHookProxySearchFixture : CoreTest<SkyHookProxy>
|
||||||
{
|
{
|
||||||
[SetUp]
|
[SetUp]
|
||||||
|
|
|
@ -129,6 +129,9 @@ namespace NzbDrone.Core.Test.ParserTests
|
||||||
[TestCase("Green Day - Father Of All [FLAC (M4A) 24-bit Lossless]", null, 0, 0)]
|
[TestCase("Green Day - Father Of All [FLAC (M4A) 24-bit Lossless]", null, 0, 0)]
|
||||||
[TestCase("Green_Day-Father_Of_All_FLAC_M4A_24_bit_Lossless", null, 0, 0)]
|
[TestCase("Green_Day-Father_Of_All_FLAC_M4A_24_bit_Lossless", null, 0, 0)]
|
||||||
[TestCase("Green.Day-Father.Of.All.FLAC.M4A.24.bit.Lossless", null, 0, 0)]
|
[TestCase("Green.Day-Father.Of.All.FLAC.M4A.24.bit.Lossless", null, 0, 0)]
|
||||||
|
[TestCase("Linkin Park - Studio Collection 2000-2012 (2013) [WEB FLAC24-44.1]", null, 0, 0)]
|
||||||
|
[TestCase("Linkin Park - Studio Collection 2000-2012 (2013) [WEB FLAC24bit]", null, 0, 0)]
|
||||||
|
[TestCase("Linkin Park - Studio Collection 2000-2012 (2013) [WEB FLAC24-bit]", null, 0, 0)]
|
||||||
public void should_parse_flac_24bit_quality(string title, string desc, int bitrate, int sampleSize)
|
public void should_parse_flac_24bit_quality(string title, string desc, int bitrate, int sampleSize)
|
||||||
{
|
{
|
||||||
ParseAndVerifyQuality(title, desc, bitrate, Quality.FLAC_24, sampleSize);
|
ParseAndVerifyQuality(title, desc, bitrate, Quality.FLAC_24, sampleSize);
|
||||||
|
|
|
@ -11,6 +11,7 @@ namespace NzbDrone.Core.CustomFormats
|
||||||
{
|
{
|
||||||
RuleFor(c => c.Min).GreaterThanOrEqualTo(0);
|
RuleFor(c => c.Min).GreaterThanOrEqualTo(0);
|
||||||
RuleFor(c => c.Max).GreaterThan(c => c.Min);
|
RuleFor(c => c.Max).GreaterThan(c => c.Min);
|
||||||
|
RuleFor(c => c.Max).LessThanOrEqualTo(double.MaxValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -252,7 +252,7 @@ namespace NzbDrone.Core.Datastore
|
||||||
|
|
||||||
protected void Delete(SqlBuilder builder)
|
protected void Delete(SqlBuilder builder)
|
||||||
{
|
{
|
||||||
var sql = builder.AddDeleteTemplate(typeof(TModel)).LogQuery();
|
var sql = builder.AddDeleteTemplate(typeof(TModel));
|
||||||
|
|
||||||
using (var conn = _database.OpenConnection())
|
using (var conn = _database.OpenConnection())
|
||||||
{
|
{
|
||||||
|
|
|
@ -21,7 +21,7 @@ namespace NzbDrone.Core.DiskSpace
|
||||||
private readonly IRootFolderService _rootFolderService;
|
private readonly IRootFolderService _rootFolderService;
|
||||||
private readonly Logger _logger;
|
private readonly Logger _logger;
|
||||||
|
|
||||||
private static readonly Regex _regexSpecialDrive = new Regex("^/var/lib/(docker|rancher|kubelet)(/|$)|^/(boot|etc)(/|$)|/docker(/var)?/aufs(/|$)", RegexOptions.Compiled);
|
private static readonly Regex _regexSpecialDrive = new Regex(@"^/var/lib/(docker|rancher|kubelet)(/|$)|^/(boot|etc)(/|$)|/docker(/var)?/aufs(/|$)|/\.timemachine", RegexOptions.Compiled);
|
||||||
|
|
||||||
public DiskSpaceService(IDiskProvider diskProvider,
|
public DiskSpaceService(IDiskProvider diskProvider,
|
||||||
IRootFolderService rootFolderService,
|
IRootFolderService rootFolderService,
|
||||||
|
@ -38,7 +38,10 @@ namespace NzbDrone.Core.DiskSpace
|
||||||
|
|
||||||
var optionalRootFolders = GetFixedDisksRootPaths().Except(importantRootFolders).Distinct().ToList();
|
var optionalRootFolders = GetFixedDisksRootPaths().Except(importantRootFolders).Distinct().ToList();
|
||||||
|
|
||||||
var diskSpace = GetDiskSpace(importantRootFolders).Concat(GetDiskSpace(optionalRootFolders, true)).ToList();
|
var diskSpace = GetDiskSpace(importantRootFolders)
|
||||||
|
.Concat(GetDiskSpace(optionalRootFolders, true))
|
||||||
|
.OrderBy(d => d.Path, StringComparer.OrdinalIgnoreCase)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
return diskSpace;
|
return diskSpace;
|
||||||
}
|
}
|
||||||
|
@ -54,7 +57,7 @@ namespace NzbDrone.Core.DiskSpace
|
||||||
private IEnumerable<string> GetFixedDisksRootPaths()
|
private IEnumerable<string> GetFixedDisksRootPaths()
|
||||||
{
|
{
|
||||||
return _diskProvider.GetMounts()
|
return _diskProvider.GetMounts()
|
||||||
.Where(d => d.DriveType == DriveType.Fixed)
|
.Where(d => d.DriveType is DriveType.Fixed or DriveType.Network)
|
||||||
.Where(d => !_regexSpecialDrive.IsMatch(d.RootDirectory))
|
.Where(d => !_regexSpecialDrive.IsMatch(d.RootDirectory))
|
||||||
.Select(d => d.RootDirectory);
|
.Select(d => d.RootDirectory);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ using NzbDrone.Common.Extensions;
|
||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Core.Blocklisting;
|
using NzbDrone.Core.Blocklisting;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
|
using NzbDrone.Core.Localization;
|
||||||
using NzbDrone.Core.MediaFiles.TorrentInfo;
|
using NzbDrone.Core.MediaFiles.TorrentInfo;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
using NzbDrone.Core.RemotePathMappings;
|
using NzbDrone.Core.RemotePathMappings;
|
||||||
|
@ -28,9 +29,10 @@ namespace NzbDrone.Core.Download.Clients.Aria2
|
||||||
IConfigService configService,
|
IConfigService configService,
|
||||||
IDiskProvider diskProvider,
|
IDiskProvider diskProvider,
|
||||||
IRemotePathMappingService remotePathMappingService,
|
IRemotePathMappingService remotePathMappingService,
|
||||||
|
ILocalizationService localizationService,
|
||||||
IBlocklistService blocklistService,
|
IBlocklistService blocklistService,
|
||||||
Logger logger)
|
Logger logger)
|
||||||
: base(torrentFileInfoReader, httpClient, configService, diskProvider, remotePathMappingService, blocklistService, logger)
|
: base(torrentFileInfoReader, httpClient, configService, diskProvider, remotePathMappingService, localizationService, blocklistService, logger)
|
||||||
{
|
{
|
||||||
_proxy = proxy;
|
_proxy = proxy;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ using NzbDrone.Common.Extensions;
|
||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Core.Blocklisting;
|
using NzbDrone.Core.Blocklisting;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
|
using NzbDrone.Core.Localization;
|
||||||
using NzbDrone.Core.MediaFiles.TorrentInfo;
|
using NzbDrone.Core.MediaFiles.TorrentInfo;
|
||||||
using NzbDrone.Core.Organizer;
|
using NzbDrone.Core.Organizer;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
|
@ -30,9 +31,10 @@ namespace NzbDrone.Core.Download.Clients.Blackhole
|
||||||
IConfigService configService,
|
IConfigService configService,
|
||||||
IDiskProvider diskProvider,
|
IDiskProvider diskProvider,
|
||||||
IRemotePathMappingService remotePathMappingService,
|
IRemotePathMappingService remotePathMappingService,
|
||||||
|
ILocalizationService localizationService,
|
||||||
IBlocklistService blocklistService,
|
IBlocklistService blocklistService,
|
||||||
Logger logger)
|
Logger logger)
|
||||||
: base(torrentFileInfoReader, httpClient, configService, diskProvider, remotePathMappingService, blocklistService, logger)
|
: base(torrentFileInfoReader, httpClient, configService, diskProvider, remotePathMappingService, localizationService, blocklistService, logger)
|
||||||
{
|
{
|
||||||
_scanWatchFolder = scanWatchFolder;
|
_scanWatchFolder = scanWatchFolder;
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ using NzbDrone.Common.Disk;
|
||||||
using NzbDrone.Common.Extensions;
|
using NzbDrone.Common.Extensions;
|
||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
|
using NzbDrone.Core.Localization;
|
||||||
using NzbDrone.Core.Organizer;
|
using NzbDrone.Core.Organizer;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
using NzbDrone.Core.RemotePathMappings;
|
using NzbDrone.Core.RemotePathMappings;
|
||||||
|
@ -25,8 +26,9 @@ namespace NzbDrone.Core.Download.Clients.Blackhole
|
||||||
IDiskProvider diskProvider,
|
IDiskProvider diskProvider,
|
||||||
IRemotePathMappingService remotePathMappingService,
|
IRemotePathMappingService remotePathMappingService,
|
||||||
IValidateNzbs nzbValidationService,
|
IValidateNzbs nzbValidationService,
|
||||||
|
ILocalizationService localizationService,
|
||||||
Logger logger)
|
Logger logger)
|
||||||
: base(httpClient, configService, diskProvider, remotePathMappingService, nzbValidationService, logger)
|
: base(httpClient, configService, diskProvider, remotePathMappingService, nzbValidationService, localizationService, logger)
|
||||||
{
|
{
|
||||||
_scanWatchFolder = scanWatchFolder;
|
_scanWatchFolder = scanWatchFolder;
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ using NzbDrone.Common.Extensions;
|
||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Core.Blocklisting;
|
using NzbDrone.Core.Blocklisting;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
|
using NzbDrone.Core.Localization;
|
||||||
using NzbDrone.Core.MediaFiles.TorrentInfo;
|
using NzbDrone.Core.MediaFiles.TorrentInfo;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
using NzbDrone.Core.RemotePathMappings;
|
using NzbDrone.Core.RemotePathMappings;
|
||||||
|
@ -27,9 +28,10 @@ namespace NzbDrone.Core.Download.Clients.Deluge
|
||||||
IConfigService configService,
|
IConfigService configService,
|
||||||
IDiskProvider diskProvider,
|
IDiskProvider diskProvider,
|
||||||
IRemotePathMappingService remotePathMappingService,
|
IRemotePathMappingService remotePathMappingService,
|
||||||
|
ILocalizationService localizationService,
|
||||||
IBlocklistService blocklistService,
|
IBlocklistService blocklistService,
|
||||||
Logger logger)
|
Logger logger)
|
||||||
: base(torrentFileInfoReader, httpClient, configService, diskProvider, remotePathMappingService, blocklistService, logger)
|
: base(torrentFileInfoReader, httpClient, configService, diskProvider, remotePathMappingService, localizationService, blocklistService, logger)
|
||||||
{
|
{
|
||||||
_proxy = proxy;
|
_proxy = proxy;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Core.Blocklisting;
|
using NzbDrone.Core.Blocklisting;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
using NzbDrone.Core.Download.Clients.DownloadStation.Proxies;
|
using NzbDrone.Core.Download.Clients.DownloadStation.Proxies;
|
||||||
|
using NzbDrone.Core.Localization;
|
||||||
using NzbDrone.Core.MediaFiles.TorrentInfo;
|
using NzbDrone.Core.MediaFiles.TorrentInfo;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
using NzbDrone.Core.RemotePathMappings;
|
using NzbDrone.Core.RemotePathMappings;
|
||||||
|
@ -37,9 +38,10 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation
|
||||||
IConfigService configService,
|
IConfigService configService,
|
||||||
IDiskProvider diskProvider,
|
IDiskProvider diskProvider,
|
||||||
IRemotePathMappingService remotePathMappingService,
|
IRemotePathMappingService remotePathMappingService,
|
||||||
|
ILocalizationService localizationService,
|
||||||
IBlocklistService blocklistService,
|
IBlocklistService blocklistService,
|
||||||
Logger logger)
|
Logger logger)
|
||||||
: base(torrentFileInfoReader, httpClient, configService, diskProvider, remotePathMappingService, blocklistService, logger)
|
: base(torrentFileInfoReader, httpClient, configService, diskProvider, remotePathMappingService, localizationService, blocklistService, logger)
|
||||||
{
|
{
|
||||||
_dsInfoProxy = dsInfoProxy;
|
_dsInfoProxy = dsInfoProxy;
|
||||||
_dsTaskProxySelector = dsTaskProxySelector;
|
_dsTaskProxySelector = dsTaskProxySelector;
|
||||||
|
|
|
@ -9,6 +9,7 @@ using NzbDrone.Common.Extensions;
|
||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
using NzbDrone.Core.Download.Clients.DownloadStation.Proxies;
|
using NzbDrone.Core.Download.Clients.DownloadStation.Proxies;
|
||||||
|
using NzbDrone.Core.Localization;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
using NzbDrone.Core.RemotePathMappings;
|
using NzbDrone.Core.RemotePathMappings;
|
||||||
using NzbDrone.Core.ThingiProvider;
|
using NzbDrone.Core.ThingiProvider;
|
||||||
|
@ -34,8 +35,9 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation
|
||||||
IDiskProvider diskProvider,
|
IDiskProvider diskProvider,
|
||||||
IRemotePathMappingService remotePathMappingService,
|
IRemotePathMappingService remotePathMappingService,
|
||||||
IValidateNzbs nzbValidationService,
|
IValidateNzbs nzbValidationService,
|
||||||
|
ILocalizationService localizationService,
|
||||||
Logger logger)
|
Logger logger)
|
||||||
: base(httpClient, configService, diskProvider, remotePathMappingService, nzbValidationService, logger)
|
: base(httpClient, configService, diskProvider, remotePathMappingService, nzbValidationService, localizationService, logger)
|
||||||
{
|
{
|
||||||
_dsInfoProxy = dsInfoProxy;
|
_dsInfoProxy = dsInfoProxy;
|
||||||
_dsTaskProxySelector = dsTaskProxySelector;
|
_dsTaskProxySelector = dsTaskProxySelector;
|
||||||
|
|
|
@ -9,6 +9,7 @@ using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Core.Blocklisting;
|
using NzbDrone.Core.Blocklisting;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
using NzbDrone.Core.Download.Clients.Flood.Models;
|
using NzbDrone.Core.Download.Clients.Flood.Models;
|
||||||
|
using NzbDrone.Core.Localization;
|
||||||
using NzbDrone.Core.MediaFiles.TorrentInfo;
|
using NzbDrone.Core.MediaFiles.TorrentInfo;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
using NzbDrone.Core.RemotePathMappings;
|
using NzbDrone.Core.RemotePathMappings;
|
||||||
|
@ -28,9 +29,10 @@ namespace NzbDrone.Core.Download.Clients.Flood
|
||||||
IConfigService configService,
|
IConfigService configService,
|
||||||
IDiskProvider diskProvider,
|
IDiskProvider diskProvider,
|
||||||
IRemotePathMappingService remotePathMappingService,
|
IRemotePathMappingService remotePathMappingService,
|
||||||
|
ILocalizationService localizationService,
|
||||||
IBlocklistService blocklistService,
|
IBlocklistService blocklistService,
|
||||||
Logger logger)
|
Logger logger)
|
||||||
: base(torrentFileInfoReader, httpClient, configService, diskProvider, remotePathMappingService, blocklistService, logger)
|
: base(torrentFileInfoReader, httpClient, configService, diskProvider, remotePathMappingService, localizationService, blocklistService, logger)
|
||||||
{
|
{
|
||||||
_proxy = proxy;
|
_proxy = proxy;
|
||||||
_downloadSeedConfigProvider = downloadSeedConfigProvider;
|
_downloadSeedConfigProvider = downloadSeedConfigProvider;
|
||||||
|
|
|
@ -9,6 +9,7 @@ using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Core.Blocklisting;
|
using NzbDrone.Core.Blocklisting;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
using NzbDrone.Core.Download.Clients.FreeboxDownload.Responses;
|
using NzbDrone.Core.Download.Clients.FreeboxDownload.Responses;
|
||||||
|
using NzbDrone.Core.Localization;
|
||||||
using NzbDrone.Core.MediaFiles.TorrentInfo;
|
using NzbDrone.Core.MediaFiles.TorrentInfo;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
using NzbDrone.Core.RemotePathMappings;
|
using NzbDrone.Core.RemotePathMappings;
|
||||||
|
@ -25,9 +26,10 @@ namespace NzbDrone.Core.Download.Clients.FreeboxDownload
|
||||||
IConfigService configService,
|
IConfigService configService,
|
||||||
IDiskProvider diskProvider,
|
IDiskProvider diskProvider,
|
||||||
IRemotePathMappingService remotePathMappingService,
|
IRemotePathMappingService remotePathMappingService,
|
||||||
|
ILocalizationService localizationService,
|
||||||
IBlocklistService blocklistService,
|
IBlocklistService blocklistService,
|
||||||
Logger logger)
|
Logger logger)
|
||||||
: base(torrentFileInfoReader, httpClient, configService, diskProvider, remotePathMappingService, blocklistService, logger)
|
: base(torrentFileInfoReader, httpClient, configService, diskProvider, remotePathMappingService, localizationService, blocklistService, logger)
|
||||||
{
|
{
|
||||||
_proxy = proxy;
|
_proxy = proxy;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Core.Blocklisting;
|
using NzbDrone.Core.Blocklisting;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
using NzbDrone.Core.Download.Clients.Hadouken.Models;
|
using NzbDrone.Core.Download.Clients.Hadouken.Models;
|
||||||
|
using NzbDrone.Core.Localization;
|
||||||
using NzbDrone.Core.MediaFiles.TorrentInfo;
|
using NzbDrone.Core.MediaFiles.TorrentInfo;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
using NzbDrone.Core.RemotePathMappings;
|
using NzbDrone.Core.RemotePathMappings;
|
||||||
|
@ -25,9 +26,10 @@ namespace NzbDrone.Core.Download.Clients.Hadouken
|
||||||
IConfigService configService,
|
IConfigService configService,
|
||||||
IDiskProvider diskProvider,
|
IDiskProvider diskProvider,
|
||||||
IRemotePathMappingService remotePathMappingService,
|
IRemotePathMappingService remotePathMappingService,
|
||||||
|
ILocalizationService localizationService,
|
||||||
IBlocklistService blocklistService,
|
IBlocklistService blocklistService,
|
||||||
Logger logger)
|
Logger logger)
|
||||||
: base(torrentFileInfoReader, httpClient, configService, diskProvider, remotePathMappingService, blocklistService, logger)
|
: base(torrentFileInfoReader, httpClient, configService, diskProvider, remotePathMappingService, localizationService, blocklistService, logger)
|
||||||
{
|
{
|
||||||
_proxy = proxy;
|
_proxy = proxy;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ using NzbDrone.Common.Disk;
|
||||||
using NzbDrone.Common.Extensions;
|
using NzbDrone.Common.Extensions;
|
||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
|
using NzbDrone.Core.Localization;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
using NzbDrone.Core.RemotePathMappings;
|
using NzbDrone.Core.RemotePathMappings;
|
||||||
using NzbDrone.Core.Validation;
|
using NzbDrone.Core.Validation;
|
||||||
|
@ -24,8 +25,9 @@ namespace NzbDrone.Core.Download.Clients.NzbVortex
|
||||||
IDiskProvider diskProvider,
|
IDiskProvider diskProvider,
|
||||||
IRemotePathMappingService remotePathMappingService,
|
IRemotePathMappingService remotePathMappingService,
|
||||||
IValidateNzbs nzbValidationService,
|
IValidateNzbs nzbValidationService,
|
||||||
|
ILocalizationService localizationService,
|
||||||
Logger logger)
|
Logger logger)
|
||||||
: base(httpClient, configService, diskProvider, remotePathMappingService, nzbValidationService, logger)
|
: base(httpClient, configService, diskProvider, remotePathMappingService, nzbValidationService, localizationService, logger)
|
||||||
{
|
{
|
||||||
_proxy = proxy;
|
_proxy = proxy;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ using NzbDrone.Common.Extensions;
|
||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
using NzbDrone.Core.Exceptions;
|
using NzbDrone.Core.Exceptions;
|
||||||
|
using NzbDrone.Core.Localization;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
using NzbDrone.Core.RemotePathMappings;
|
using NzbDrone.Core.RemotePathMappings;
|
||||||
using NzbDrone.Core.Validation;
|
using NzbDrone.Core.Validation;
|
||||||
|
@ -28,8 +29,9 @@ namespace NzbDrone.Core.Download.Clients.Nzbget
|
||||||
IDiskProvider diskProvider,
|
IDiskProvider diskProvider,
|
||||||
IRemotePathMappingService remotePathMappingService,
|
IRemotePathMappingService remotePathMappingService,
|
||||||
IValidateNzbs nzbValidationService,
|
IValidateNzbs nzbValidationService,
|
||||||
|
ILocalizationService localizationService,
|
||||||
Logger logger)
|
Logger logger)
|
||||||
: base(httpClient, configService, diskProvider, remotePathMappingService, nzbValidationService, logger)
|
: base(httpClient, configService, diskProvider, remotePathMappingService, nzbValidationService, localizationService, logger)
|
||||||
{
|
{
|
||||||
_proxy = proxy;
|
_proxy = proxy;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ using NzbDrone.Common.Extensions;
|
||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
using NzbDrone.Core.Indexers;
|
using NzbDrone.Core.Indexers;
|
||||||
|
using NzbDrone.Core.Localization;
|
||||||
using NzbDrone.Core.Organizer;
|
using NzbDrone.Core.Organizer;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
using NzbDrone.Core.RemotePathMappings;
|
using NzbDrone.Core.RemotePathMappings;
|
||||||
|
@ -23,8 +24,9 @@ namespace NzbDrone.Core.Download.Clients.Pneumatic
|
||||||
IConfigService configService,
|
IConfigService configService,
|
||||||
IDiskProvider diskProvider,
|
IDiskProvider diskProvider,
|
||||||
IRemotePathMappingService remotePathMappingService,
|
IRemotePathMappingService remotePathMappingService,
|
||||||
|
ILocalizationService localizationService,
|
||||||
Logger logger)
|
Logger logger)
|
||||||
: base(configService, diskProvider, remotePathMappingService, logger)
|
: base(configService, diskProvider, remotePathMappingService, localizationService, logger)
|
||||||
{
|
{
|
||||||
_httpClient = httpClient;
|
_httpClient = httpClient;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ using NzbDrone.Common.Extensions;
|
||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Core.Blocklisting;
|
using NzbDrone.Core.Blocklisting;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
|
using NzbDrone.Core.Localization;
|
||||||
using NzbDrone.Core.MediaFiles.TorrentInfo;
|
using NzbDrone.Core.MediaFiles.TorrentInfo;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
using NzbDrone.Core.RemotePathMappings;
|
using NzbDrone.Core.RemotePathMappings;
|
||||||
|
@ -35,9 +36,10 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
|
||||||
IDiskProvider diskProvider,
|
IDiskProvider diskProvider,
|
||||||
IRemotePathMappingService remotePathMappingService,
|
IRemotePathMappingService remotePathMappingService,
|
||||||
ICacheManager cacheManager,
|
ICacheManager cacheManager,
|
||||||
|
ILocalizationService localizationService,
|
||||||
IBlocklistService blocklistService,
|
IBlocklistService blocklistService,
|
||||||
Logger logger)
|
Logger logger)
|
||||||
: base(torrentFileInfoReader, httpClient, configService, diskProvider, remotePathMappingService, blocklistService, logger)
|
: base(torrentFileInfoReader, httpClient, configService, diskProvider, remotePathMappingService, localizationService, blocklistService, logger)
|
||||||
{
|
{
|
||||||
_proxySelector = proxySelector;
|
_proxySelector = proxySelector;
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ using NzbDrone.Common.Extensions;
|
||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
using NzbDrone.Core.Exceptions;
|
using NzbDrone.Core.Exceptions;
|
||||||
|
using NzbDrone.Core.Localization;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
using NzbDrone.Core.RemotePathMappings;
|
using NzbDrone.Core.RemotePathMappings;
|
||||||
using NzbDrone.Core.Validation;
|
using NzbDrone.Core.Validation;
|
||||||
|
@ -26,8 +27,9 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd
|
||||||
IDiskProvider diskProvider,
|
IDiskProvider diskProvider,
|
||||||
IRemotePathMappingService remotePathMappingService,
|
IRemotePathMappingService remotePathMappingService,
|
||||||
IValidateNzbs nzbValidationService,
|
IValidateNzbs nzbValidationService,
|
||||||
|
ILocalizationService localizationService,
|
||||||
Logger logger)
|
Logger logger)
|
||||||
: base(httpClient, configService, diskProvider, remotePathMappingService, nzbValidationService, logger)
|
: base(httpClient, configService, diskProvider, remotePathMappingService, nzbValidationService, localizationService, logger)
|
||||||
{
|
{
|
||||||
_proxy = proxy;
|
_proxy = proxy;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ using NzbDrone.Common.Extensions;
|
||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Core.Blocklisting;
|
using NzbDrone.Core.Blocklisting;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
|
using NzbDrone.Core.Localization;
|
||||||
using NzbDrone.Core.MediaFiles.TorrentInfo;
|
using NzbDrone.Core.MediaFiles.TorrentInfo;
|
||||||
using NzbDrone.Core.RemotePathMappings;
|
using NzbDrone.Core.RemotePathMappings;
|
||||||
|
|
||||||
|
@ -24,9 +25,10 @@ namespace NzbDrone.Core.Download.Clients.Transmission
|
||||||
IConfigService configService,
|
IConfigService configService,
|
||||||
IDiskProvider diskProvider,
|
IDiskProvider diskProvider,
|
||||||
IRemotePathMappingService remotePathMappingService,
|
IRemotePathMappingService remotePathMappingService,
|
||||||
|
ILocalizationService localizationService,
|
||||||
IBlocklistService blocklistService,
|
IBlocklistService blocklistService,
|
||||||
Logger logger)
|
Logger logger)
|
||||||
: base(proxy, torrentFileInfoReader, httpClient, configService, diskProvider, remotePathMappingService, blocklistService, logger)
|
: base(proxy, torrentFileInfoReader, httpClient, configService, diskProvider, remotePathMappingService, localizationService, blocklistService, logger)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ using NzbDrone.Common.Extensions;
|
||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Core.Blocklisting;
|
using NzbDrone.Core.Blocklisting;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
|
using NzbDrone.Core.Localization;
|
||||||
using NzbDrone.Core.MediaFiles.TorrentInfo;
|
using NzbDrone.Core.MediaFiles.TorrentInfo;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
using NzbDrone.Core.RemotePathMappings;
|
using NzbDrone.Core.RemotePathMappings;
|
||||||
|
@ -28,9 +29,10 @@ namespace NzbDrone.Core.Download.Clients.Transmission
|
||||||
IConfigService configService,
|
IConfigService configService,
|
||||||
IDiskProvider diskProvider,
|
IDiskProvider diskProvider,
|
||||||
IRemotePathMappingService remotePathMappingService,
|
IRemotePathMappingService remotePathMappingService,
|
||||||
|
ILocalizationService localizationService,
|
||||||
IBlocklistService blocklistService,
|
IBlocklistService blocklistService,
|
||||||
Logger logger)
|
Logger logger)
|
||||||
: base(torrentFileInfoReader, httpClient, configService, diskProvider, remotePathMappingService, blocklistService, logger)
|
: base(torrentFileInfoReader, httpClient, configService, diskProvider, remotePathMappingService, localizationService, blocklistService, logger)
|
||||||
{
|
{
|
||||||
_proxy = proxy;
|
_proxy = proxy;
|
||||||
}
|
}
|
||||||
|
@ -101,7 +103,11 @@ namespace NzbDrone.Core.Download.Clients.Transmission
|
||||||
if (!torrent.ErrorString.IsNullOrWhiteSpace())
|
if (!torrent.ErrorString.IsNullOrWhiteSpace())
|
||||||
{
|
{
|
||||||
item.Status = DownloadItemStatus.Warning;
|
item.Status = DownloadItemStatus.Warning;
|
||||||
item.Message = torrent.ErrorString;
|
item.Message = _localizationService.GetLocalizedString("DownloadClientItemErrorMessage", new Dictionary<string, object>
|
||||||
|
{
|
||||||
|
{ "clientName", Name },
|
||||||
|
{ "message", torrent.ErrorString }
|
||||||
|
});
|
||||||
}
|
}
|
||||||
else if (torrent.TotalSize == 0)
|
else if (torrent.TotalSize == 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -5,6 +5,7 @@ using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Core.Blocklisting;
|
using NzbDrone.Core.Blocklisting;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
using NzbDrone.Core.Download.Clients.Transmission;
|
using NzbDrone.Core.Download.Clients.Transmission;
|
||||||
|
using NzbDrone.Core.Localization;
|
||||||
using NzbDrone.Core.MediaFiles.TorrentInfo;
|
using NzbDrone.Core.MediaFiles.TorrentInfo;
|
||||||
using NzbDrone.Core.RemotePathMappings;
|
using NzbDrone.Core.RemotePathMappings;
|
||||||
|
|
||||||
|
@ -23,9 +24,10 @@ namespace NzbDrone.Core.Download.Clients.Vuze
|
||||||
IConfigService configService,
|
IConfigService configService,
|
||||||
IDiskProvider diskProvider,
|
IDiskProvider diskProvider,
|
||||||
IRemotePathMappingService remotePathMappingService,
|
IRemotePathMappingService remotePathMappingService,
|
||||||
|
ILocalizationService localizationService,
|
||||||
IBlocklistService blocklistService,
|
IBlocklistService blocklistService,
|
||||||
Logger logger)
|
Logger logger)
|
||||||
: base(proxy, torrentFileInfoReader, httpClient, configService, diskProvider, remotePathMappingService, blocklistService, logger)
|
: base(proxy, torrentFileInfoReader, httpClient, configService, diskProvider, remotePathMappingService, localizationService, blocklistService, logger)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@ using NzbDrone.Core.Blocklisting;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
using NzbDrone.Core.Download.Clients.rTorrent;
|
using NzbDrone.Core.Download.Clients.rTorrent;
|
||||||
using NzbDrone.Core.Exceptions;
|
using NzbDrone.Core.Exceptions;
|
||||||
|
using NzbDrone.Core.Localization;
|
||||||
using NzbDrone.Core.MediaFiles.TorrentInfo;
|
using NzbDrone.Core.MediaFiles.TorrentInfo;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
using NzbDrone.Core.RemotePathMappings;
|
using NzbDrone.Core.RemotePathMappings;
|
||||||
|
@ -35,9 +36,10 @@ namespace NzbDrone.Core.Download.Clients.RTorrent
|
||||||
IRemotePathMappingService remotePathMappingService,
|
IRemotePathMappingService remotePathMappingService,
|
||||||
IDownloadSeedConfigProvider downloadSeedConfigProvider,
|
IDownloadSeedConfigProvider downloadSeedConfigProvider,
|
||||||
IRTorrentDirectoryValidator rTorrentDirectoryValidator,
|
IRTorrentDirectoryValidator rTorrentDirectoryValidator,
|
||||||
|
ILocalizationService localizationService,
|
||||||
IBlocklistService blocklistService,
|
IBlocklistService blocklistService,
|
||||||
Logger logger)
|
Logger logger)
|
||||||
: base(torrentFileInfoReader, httpClient, configService, diskProvider, remotePathMappingService, blocklistService, logger)
|
: base(torrentFileInfoReader, httpClient, configService, diskProvider, remotePathMappingService, localizationService, blocklistService, logger)
|
||||||
{
|
{
|
||||||
_proxy = proxy;
|
_proxy = proxy;
|
||||||
_rTorrentDirectoryValidator = rTorrentDirectoryValidator;
|
_rTorrentDirectoryValidator = rTorrentDirectoryValidator;
|
||||||
|
|
|
@ -10,6 +10,7 @@ using NzbDrone.Common.Extensions;
|
||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Core.Blocklisting;
|
using NzbDrone.Core.Blocklisting;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
|
using NzbDrone.Core.Localization;
|
||||||
using NzbDrone.Core.MediaFiles.TorrentInfo;
|
using NzbDrone.Core.MediaFiles.TorrentInfo;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
using NzbDrone.Core.RemotePathMappings;
|
using NzbDrone.Core.RemotePathMappings;
|
||||||
|
@ -29,9 +30,10 @@ namespace NzbDrone.Core.Download.Clients.UTorrent
|
||||||
IConfigService configService,
|
IConfigService configService,
|
||||||
IDiskProvider diskProvider,
|
IDiskProvider diskProvider,
|
||||||
IRemotePathMappingService remotePathMappingService,
|
IRemotePathMappingService remotePathMappingService,
|
||||||
|
ILocalizationService localizationService,
|
||||||
IBlocklistService blocklistService,
|
IBlocklistService blocklistService,
|
||||||
Logger logger)
|
Logger logger)
|
||||||
: base(torrentFileInfoReader, httpClient, configService, diskProvider, remotePathMappingService, blocklistService, logger)
|
: base(torrentFileInfoReader, httpClient, configService, diskProvider, remotePathMappingService, localizationService, blocklistService, logger)
|
||||||
{
|
{
|
||||||
_proxy = proxy;
|
_proxy = proxy;
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ using NzbDrone.Common.Disk;
|
||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
using NzbDrone.Core.Indexers;
|
using NzbDrone.Core.Indexers;
|
||||||
|
using NzbDrone.Core.Localization;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
using NzbDrone.Core.RemotePathMappings;
|
using NzbDrone.Core.RemotePathMappings;
|
||||||
using NzbDrone.Core.ThingiProvider;
|
using NzbDrone.Core.ThingiProvider;
|
||||||
|
@ -23,6 +24,7 @@ namespace NzbDrone.Core.Download
|
||||||
protected readonly IConfigService _configService;
|
protected readonly IConfigService _configService;
|
||||||
protected readonly IDiskProvider _diskProvider;
|
protected readonly IDiskProvider _diskProvider;
|
||||||
protected readonly IRemotePathMappingService _remotePathMappingService;
|
protected readonly IRemotePathMappingService _remotePathMappingService;
|
||||||
|
protected readonly ILocalizationService _localizationService;
|
||||||
protected readonly Logger _logger;
|
protected readonly Logger _logger;
|
||||||
|
|
||||||
protected ResiliencePipeline<HttpResponse> RetryStrategy => new ResiliencePipelineBuilder<HttpResponse>()
|
protected ResiliencePipeline<HttpResponse> RetryStrategy => new ResiliencePipelineBuilder<HttpResponse>()
|
||||||
|
@ -77,11 +79,13 @@ namespace NzbDrone.Core.Download
|
||||||
protected DownloadClientBase(IConfigService configService,
|
protected DownloadClientBase(IConfigService configService,
|
||||||
IDiskProvider diskProvider,
|
IDiskProvider diskProvider,
|
||||||
IRemotePathMappingService remotePathMappingService,
|
IRemotePathMappingService remotePathMappingService,
|
||||||
|
ILocalizationService localizationService,
|
||||||
Logger logger)
|
Logger logger)
|
||||||
{
|
{
|
||||||
_configService = configService;
|
_configService = configService;
|
||||||
_diskProvider = diskProvider;
|
_diskProvider = diskProvider;
|
||||||
_remotePathMappingService = remotePathMappingService;
|
_remotePathMappingService = remotePathMappingService;
|
||||||
|
_localizationService = localizationService;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Xml;
|
using System.Xml;
|
||||||
|
@ -15,39 +16,53 @@ namespace NzbDrone.Core.Download
|
||||||
{
|
{
|
||||||
public void Validate(string filename, byte[] fileContent)
|
public void Validate(string filename, byte[] fileContent)
|
||||||
{
|
{
|
||||||
var reader = new StreamReader(new MemoryStream(fileContent));
|
try
|
||||||
|
|
||||||
using (var xmlTextReader = XmlReader.Create(reader, new XmlReaderSettings { DtdProcessing = DtdProcessing.Ignore, IgnoreComments = true }))
|
|
||||||
{
|
{
|
||||||
var xDoc = XDocument.Load(xmlTextReader);
|
var reader = new StreamReader(new MemoryStream(fileContent));
|
||||||
var nzb = xDoc.Root;
|
|
||||||
|
|
||||||
if (nzb == null)
|
using (var xmlTextReader = XmlReader.Create(reader,
|
||||||
|
new XmlReaderSettings { DtdProcessing = DtdProcessing.Ignore, IgnoreComments = true }))
|
||||||
{
|
{
|
||||||
throw new InvalidNzbException("Invalid NZB: No Root element [{0}]", filename);
|
var xDoc = XDocument.Load(xmlTextReader);
|
||||||
}
|
var nzb = xDoc.Root;
|
||||||
|
|
||||||
// nZEDb has an bug in their error reporting code spitting out invalid http status codes
|
if (nzb == null)
|
||||||
if (nzb.Name.LocalName.Equals("error") &&
|
{
|
||||||
nzb.TryGetAttributeValue("code", out var code) &&
|
throw new InvalidNzbException("Invalid NZB: No Root element [{0}]", filename);
|
||||||
nzb.TryGetAttributeValue("description", out var description))
|
}
|
||||||
{
|
|
||||||
throw new InvalidNzbException("Invalid NZB: Contains indexer error: {0} - {1}", code, description);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!nzb.Name.LocalName.Equals("nzb"))
|
// nZEDb has an bug in their error reporting code spitting out invalid http status codes
|
||||||
{
|
if (nzb.Name.LocalName.Equals("error") &&
|
||||||
throw new InvalidNzbException("Invalid NZB: Unexpected root element. Expected 'nzb' found '{0}' [{1}]", nzb.Name.LocalName, filename);
|
nzb.TryGetAttributeValue("code", out var code) &&
|
||||||
}
|
nzb.TryGetAttributeValue("description", out var description))
|
||||||
|
{
|
||||||
|
throw new InvalidNzbException("Invalid NZB: Contains indexer error: {0} - {1}", code, description);
|
||||||
|
}
|
||||||
|
|
||||||
var ns = nzb.Name.Namespace;
|
if (!nzb.Name.LocalName.Equals("nzb"))
|
||||||
var files = nzb.Elements(ns + "file").ToList();
|
{
|
||||||
|
throw new InvalidNzbException(
|
||||||
|
"Invalid NZB: Unexpected root element. Expected 'nzb' found '{0}' [{1}]", nzb.Name.LocalName, filename);
|
||||||
|
}
|
||||||
|
|
||||||
if (files.Empty())
|
var ns = nzb.Name.Namespace;
|
||||||
{
|
var files = nzb.Elements(ns + "file").ToList();
|
||||||
throw new InvalidNzbException("Invalid NZB: No files [{0}]", filename);
|
|
||||||
|
if (files.Empty())
|
||||||
|
{
|
||||||
|
throw new InvalidNzbException("Invalid NZB: No files [{0}]", filename);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch (InvalidNzbException)
|
||||||
|
{
|
||||||
|
// Throw the original exception
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
throw new InvalidNzbException("Invalid NZB: Unable to parse [{0}]", ex, filename);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ using NzbDrone.Core.Blocklisting;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
using NzbDrone.Core.Exceptions;
|
using NzbDrone.Core.Exceptions;
|
||||||
using NzbDrone.Core.Indexers;
|
using NzbDrone.Core.Indexers;
|
||||||
|
using NzbDrone.Core.Localization;
|
||||||
using NzbDrone.Core.MediaFiles.TorrentInfo;
|
using NzbDrone.Core.MediaFiles.TorrentInfo;
|
||||||
using NzbDrone.Core.Organizer;
|
using NzbDrone.Core.Organizer;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
|
@ -30,9 +31,10 @@ namespace NzbDrone.Core.Download
|
||||||
IConfigService configService,
|
IConfigService configService,
|
||||||
IDiskProvider diskProvider,
|
IDiskProvider diskProvider,
|
||||||
IRemotePathMappingService remotePathMappingService,
|
IRemotePathMappingService remotePathMappingService,
|
||||||
|
ILocalizationService localizationService,
|
||||||
IBlocklistService blocklistService,
|
IBlocklistService blocklistService,
|
||||||
Logger logger)
|
Logger logger)
|
||||||
: base(configService, diskProvider, remotePathMappingService, logger)
|
: base(configService, diskProvider, remotePathMappingService, localizationService, logger)
|
||||||
{
|
{
|
||||||
_httpClient = httpClient;
|
_httpClient = httpClient;
|
||||||
_blocklistService = blocklistService;
|
_blocklistService = blocklistService;
|
||||||
|
@ -170,7 +172,7 @@ namespace NzbDrone.Core.Download
|
||||||
}
|
}
|
||||||
catch (HttpException ex)
|
catch (HttpException ex)
|
||||||
{
|
{
|
||||||
if (ex.Response.StatusCode == HttpStatusCode.NotFound)
|
if (ex.Response.StatusCode is HttpStatusCode.NotFound or HttpStatusCode.Gone)
|
||||||
{
|
{
|
||||||
_logger.Error(ex, "Downloading torrent file for album '{0}' failed since it no longer exists ({1})", remoteAlbum.Release.Title, torrentUrl);
|
_logger.Error(ex, "Downloading torrent file for album '{0}' failed since it no longer exists ({1})", remoteAlbum.Release.Title, torrentUrl);
|
||||||
throw new ReleaseUnavailableException(remoteAlbum.Release, "Downloading torrent failed", ex);
|
throw new ReleaseUnavailableException(remoteAlbum.Release, "Downloading torrent failed", ex);
|
||||||
|
|
|
@ -6,6 +6,7 @@ using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
using NzbDrone.Core.Exceptions;
|
using NzbDrone.Core.Exceptions;
|
||||||
using NzbDrone.Core.Indexers;
|
using NzbDrone.Core.Indexers;
|
||||||
|
using NzbDrone.Core.Localization;
|
||||||
using NzbDrone.Core.Organizer;
|
using NzbDrone.Core.Organizer;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
using NzbDrone.Core.RemotePathMappings;
|
using NzbDrone.Core.RemotePathMappings;
|
||||||
|
@ -24,8 +25,9 @@ namespace NzbDrone.Core.Download
|
||||||
IDiskProvider diskProvider,
|
IDiskProvider diskProvider,
|
||||||
IRemotePathMappingService remotePathMappingService,
|
IRemotePathMappingService remotePathMappingService,
|
||||||
IValidateNzbs nzbValidationService,
|
IValidateNzbs nzbValidationService,
|
||||||
|
ILocalizationService localizationService,
|
||||||
Logger logger)
|
Logger logger)
|
||||||
: base(configService, diskProvider, remotePathMappingService, logger)
|
: base(configService, diskProvider, remotePathMappingService, localizationService, logger)
|
||||||
{
|
{
|
||||||
_httpClient = httpClient;
|
_httpClient = httpClient;
|
||||||
_nzbValidationService = nzbValidationService;
|
_nzbValidationService = nzbValidationService;
|
||||||
|
@ -46,6 +48,7 @@ namespace NzbDrone.Core.Download
|
||||||
{
|
{
|
||||||
var request = indexer?.GetDownloadRequest(url) ?? new HttpRequest(url);
|
var request = indexer?.GetDownloadRequest(url) ?? new HttpRequest(url);
|
||||||
request.RateLimitKey = remoteAlbum?.Release?.IndexerId.ToString();
|
request.RateLimitKey = remoteAlbum?.Release?.IndexerId.ToString();
|
||||||
|
request.AllowAutoRedirect = true;
|
||||||
|
|
||||||
var response = await RetryStrategy
|
var response = await RetryStrategy
|
||||||
.ExecuteAsync(static async (state, _) => await state._httpClient.GetAsync(state.request), (_httpClient, request))
|
.ExecuteAsync(static async (state, _) => await state._httpClient.GetAsync(state.request), (_httpClient, request))
|
||||||
|
@ -57,7 +60,7 @@ namespace NzbDrone.Core.Download
|
||||||
}
|
}
|
||||||
catch (HttpException ex)
|
catch (HttpException ex)
|
||||||
{
|
{
|
||||||
if (ex.Response.StatusCode == HttpStatusCode.NotFound)
|
if (ex.Response.StatusCode is HttpStatusCode.NotFound or HttpStatusCode.Gone)
|
||||||
{
|
{
|
||||||
_logger.Error(ex, "Downloading nzb file for album '{0}' failed since it no longer exists ({1})", remoteAlbum.Release.Title, url);
|
_logger.Error(ex, "Downloading nzb file for album '{0}' failed since it no longer exists ({1})", remoteAlbum.Release.Title, url);
|
||||||
throw new ReleaseUnavailableException(remoteAlbum.Release, "Downloading nzb failed", ex);
|
throw new ReleaseUnavailableException(remoteAlbum.Release, "Downloading nzb failed", ex);
|
||||||
|
|
|
@ -10,6 +10,9 @@ namespace NzbDrone.Core.History
|
||||||
{
|
{
|
||||||
public const string DOWNLOAD_CLIENT = "downloadClient";
|
public const string DOWNLOAD_CLIENT = "downloadClient";
|
||||||
public const string RELEASE_SOURCE = "releaseSource";
|
public const string RELEASE_SOURCE = "releaseSource";
|
||||||
|
public const string RELEASE_GROUP = "releaseGroup";
|
||||||
|
public const string SIZE = "size";
|
||||||
|
public const string INDEXER = "indexer";
|
||||||
|
|
||||||
public EntityHistory()
|
public EntityHistory()
|
||||||
{
|
{
|
||||||
|
|
|
@ -104,6 +104,7 @@ namespace NzbDrone.Core.History
|
||||||
var builder = Builder()
|
var builder = Builder()
|
||||||
.Join<EntityHistory, Artist>((h, a) => h.ArtistId == a.Id)
|
.Join<EntityHistory, Artist>((h, a) => h.ArtistId == a.Id)
|
||||||
.Join<EntityHistory, Album>((h, a) => h.AlbumId == a.Id)
|
.Join<EntityHistory, Album>((h, a) => h.AlbumId == a.Id)
|
||||||
|
.LeftJoin<EntityHistory, Track>((h, t) => h.TrackId == t.Id)
|
||||||
.Where<EntityHistory>(x => x.Date >= date);
|
.Where<EntityHistory>(x => x.Date >= date);
|
||||||
|
|
||||||
if (eventType.HasValue)
|
if (eventType.HasValue)
|
||||||
|
@ -111,10 +112,11 @@ namespace NzbDrone.Core.History
|
||||||
builder.Where<EntityHistory>(h => h.EventType == eventType);
|
builder.Where<EntityHistory>(h => h.EventType == eventType);
|
||||||
}
|
}
|
||||||
|
|
||||||
return _database.QueryJoined<EntityHistory, Artist, Album>(builder, (history, artist, album) =>
|
return _database.QueryJoined<EntityHistory, Artist, Album, Track>(builder, (history, artist, album, track) =>
|
||||||
{
|
{
|
||||||
history.Artist = artist;
|
history.Artist = artist;
|
||||||
history.Album = album;
|
history.Album = album;
|
||||||
|
history.Track = track;
|
||||||
return history;
|
return history;
|
||||||
}).OrderBy(h => h.Date).ToList();
|
}).OrderBy(h => h.Date).ToList();
|
||||||
}
|
}
|
||||||
|
|
|
@ -157,7 +157,7 @@ namespace NzbDrone.Core.History
|
||||||
history.Data.Add("Age", message.Album.Release.Age.ToString());
|
history.Data.Add("Age", message.Album.Release.Age.ToString());
|
||||||
history.Data.Add("AgeHours", message.Album.Release.AgeHours.ToString());
|
history.Data.Add("AgeHours", message.Album.Release.AgeHours.ToString());
|
||||||
history.Data.Add("AgeMinutes", message.Album.Release.AgeMinutes.ToString());
|
history.Data.Add("AgeMinutes", message.Album.Release.AgeMinutes.ToString());
|
||||||
history.Data.Add("PublishedDate", message.Album.Release.PublishDate.ToString("s") + "Z");
|
history.Data.Add("PublishedDate", message.Album.Release.PublishDate.ToUniversalTime().ToString("s") + "Z");
|
||||||
history.Data.Add("DownloadClient", message.DownloadClient);
|
history.Data.Add("DownloadClient", message.DownloadClient);
|
||||||
history.Data.Add("Size", message.Album.Release.Size.ToString());
|
history.Data.Add("Size", message.Album.Release.Size.ToString());
|
||||||
history.Data.Add("DownloadUrl", message.Album.Release.DownloadUrl);
|
history.Data.Add("DownloadUrl", message.Album.Release.DownloadUrl);
|
||||||
|
@ -267,7 +267,9 @@ namespace NzbDrone.Core.History
|
||||||
|
|
||||||
history.Data.Add("DownloadClient", message.DownloadClient);
|
history.Data.Add("DownloadClient", message.DownloadClient);
|
||||||
history.Data.Add("Message", message.Message);
|
history.Data.Add("Message", message.Message);
|
||||||
history.Data.Add("Size", message.TrackedDownload?.DownloadItem.TotalSize.ToString());
|
history.Data.Add("ReleaseGroup", message.TrackedDownload?.RemoteAlbum?.ParsedAlbumInfo?.ReleaseGroup ?? message.Data.GetValueOrDefault(EntityHistory.RELEASE_GROUP));
|
||||||
|
history.Data.Add("Size", message.TrackedDownload?.DownloadItem.TotalSize.ToString() ?? message.Data.GetValueOrDefault(EntityHistory.SIZE));
|
||||||
|
history.Data.Add("Indexer", message.TrackedDownload?.RemoteAlbum?.Release?.Indexer ?? message.Data.GetValueOrDefault(EntityHistory.INDEXER));
|
||||||
|
|
||||||
_historyRepository.Insert(history);
|
_historyRepository.Insert(history);
|
||||||
}
|
}
|
||||||
|
@ -417,6 +419,7 @@ namespace NzbDrone.Core.History
|
||||||
history.Data.Add("Message", message.Message);
|
history.Data.Add("Message", message.Message);
|
||||||
history.Data.Add("ReleaseGroup", message.TrackedDownload?.RemoteAlbum?.ParsedAlbumInfo?.ReleaseGroup);
|
history.Data.Add("ReleaseGroup", message.TrackedDownload?.RemoteAlbum?.ParsedAlbumInfo?.ReleaseGroup);
|
||||||
history.Data.Add("Size", message.TrackedDownload?.DownloadItem.TotalSize.ToString());
|
history.Data.Add("Size", message.TrackedDownload?.DownloadItem.TotalSize.ToString());
|
||||||
|
history.Data.Add("Indexer", message.TrackedDownload?.RemoteAlbum?.Release?.Indexer);
|
||||||
|
|
||||||
historyToAdd.Add(history);
|
historyToAdd.Add(history);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using NzbDrone.Common.Extensions;
|
||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Core.IndexerSearch.Definitions;
|
using NzbDrone.Core.IndexerSearch.Definitions;
|
||||||
|
|
||||||
|
@ -44,6 +45,11 @@ namespace NzbDrone.Core.Indexers.FileList
|
||||||
|
|
||||||
private IEnumerable<IndexerRequest> GetRequest(string searchType, IEnumerable<int> categories, string parameters)
|
private IEnumerable<IndexerRequest> GetRequest(string searchType, IEnumerable<int> categories, string parameters)
|
||||||
{
|
{
|
||||||
|
if (categories.Empty())
|
||||||
|
{
|
||||||
|
yield break;
|
||||||
|
}
|
||||||
|
|
||||||
var categoriesQuery = string.Join(",", categories.Distinct());
|
var categoriesQuery = string.Join(",", categories.Distinct());
|
||||||
|
|
||||||
var baseUrl = string.Format("{0}/api.php?action={1}&category={2}{3}", Settings.BaseUrl.TrimEnd('/'), searchType, categoriesQuery, parameters);
|
var baseUrl = string.Format("{0}/api.php?action={1}&category={2}{3}", Settings.BaseUrl.TrimEnd('/'), searchType, categoriesQuery, parameters);
|
||||||
|
|
|
@ -13,6 +13,8 @@ namespace NzbDrone.Core.Indexers.FileList
|
||||||
RuleFor(c => c.Username).NotEmpty();
|
RuleFor(c => c.Username).NotEmpty();
|
||||||
RuleFor(c => c.Passkey).NotEmpty();
|
RuleFor(c => c.Passkey).NotEmpty();
|
||||||
|
|
||||||
|
RuleFor(c => c.Categories).NotEmpty();
|
||||||
|
|
||||||
RuleFor(c => c.SeedCriteria).SetValidator(_ => new SeedCriteriaSettingsValidator());
|
RuleFor(c => c.SeedCriteria).SetValidator(_ => new SeedCriteriaSettingsValidator());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
<PackageReference Include="MailKit" Version="4.8.0" />
|
<PackageReference Include="MailKit" Version="4.8.0" />
|
||||||
<PackageReference Include="Polly" Version="8.5.2" />
|
<PackageReference Include="Polly" Version="8.5.2" />
|
||||||
<PackageReference Include="System.Text.Json" Version="6.0.10" />
|
<PackageReference Include="System.Text.Json" Version="6.0.10" />
|
||||||
<PackageReference Include="System.Memory" Version="4.6.0" />
|
<PackageReference Include="System.Memory" Version="4.6.2" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Cryptography.KeyDerivation" Version="6.0.35" />
|
<PackageReference Include="Microsoft.AspNetCore.Cryptography.KeyDerivation" Version="6.0.35" />
|
||||||
<PackageReference Include="Microsoft.Data.SqlClient" Version="2.1.7" />
|
<PackageReference Include="Microsoft.Data.SqlClient" Version="2.1.7" />
|
||||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.1" />
|
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.1" />
|
||||||
|
@ -20,14 +20,14 @@
|
||||||
<PackageReference Include="Servarr.FluentMigrator.Runner.Postgres" Version="3.3.2.9" />
|
<PackageReference Include="Servarr.FluentMigrator.Runner.Postgres" Version="3.3.2.9" />
|
||||||
<PackageReference Include="FluentValidation" Version="9.5.4" />
|
<PackageReference Include="FluentValidation" Version="9.5.4" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||||
<PackageReference Include="NLog" Version="5.3.4" />
|
<PackageReference Include="NLog" Version="5.4.0" />
|
||||||
<PackageReference Include="NLog.Extensions.Logging" Version="5.3.15" />
|
<PackageReference Include="NLog.Extensions.Logging" Version="5.4.0" />
|
||||||
<PackageReference Include="NLog.Targets.Syslog" Version="7.0.0" />
|
<PackageReference Include="NLog.Targets.Syslog" Version="7.0.0" />
|
||||||
<PackageReference Include="System.IO.Abstractions" Version="17.0.24" />
|
<PackageReference Include="System.IO.Abstractions" Version="17.0.24" />
|
||||||
<PackageReference Include="TagLibSharp-Lidarr" Version="2.2.0.27" />
|
<PackageReference Include="TagLibSharp-Lidarr" Version="2.2.0.27" />
|
||||||
<PackageReference Include="Npgsql" Version="7.0.9" />
|
<PackageReference Include="Npgsql" Version="7.0.10" />
|
||||||
<PackageReference Include="SpotifyAPI.Web" Version="5.1.1" />
|
<PackageReference Include="SpotifyAPI.Web" Version="5.1.1" />
|
||||||
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.7" />
|
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.9" />
|
||||||
<PackageReference Include="MonoTorrent" Version="2.0.7" />
|
<PackageReference Include="MonoTorrent" Version="2.0.7" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
"BindAddress": "Adreça d'enllaç",
|
"BindAddress": "Adreça d'enllaç",
|
||||||
"DeleteQualityProfileMessageText": "Esteu segur que voleu suprimir el perfil de qualitat '{name}'?",
|
"DeleteQualityProfileMessageText": "Esteu segur que voleu suprimir el perfil de qualitat '{name}'?",
|
||||||
"DeleteReleaseProfile": "Suprimeix el perfil de llançament",
|
"DeleteReleaseProfile": "Suprimeix el perfil de llançament",
|
||||||
"DeleteReleaseProfileMessageText": "Esteu segur que voleu suprimir aquest perfil de retard?",
|
"DeleteReleaseProfileMessageText": "Esteu segur que voleu suprimir aquest perfil de llançament?",
|
||||||
"DownloadClients": "Descàrrega Clients",
|
"DownloadClients": "Descàrrega Clients",
|
||||||
"EnableColorImpairedMode": "Activa el mode amb alteracions del color",
|
"EnableColorImpairedMode": "Activa el mode amb alteracions del color",
|
||||||
"EnableHelpText": "Activa la creació de fitxers de metadades per a aquest tipus de metadades",
|
"EnableHelpText": "Activa la creació de fitxers de metadades per a aquest tipus de metadades",
|
||||||
|
@ -82,7 +82,7 @@
|
||||||
"TorrentDelayHelpText": "Retard en minuts per a esperar abans de capturar un torrent",
|
"TorrentDelayHelpText": "Retard en minuts per a esperar abans de capturar un torrent",
|
||||||
"Torrents": "Torrents",
|
"Torrents": "Torrents",
|
||||||
"UnableToLoadGeneralSettings": "No es pot carregar la configuració general",
|
"UnableToLoadGeneralSettings": "No es pot carregar la configuració general",
|
||||||
"UnableToLoadHistory": "No es pot carregar l'historial",
|
"UnableToLoadHistory": "No es pot carregar l'historial.",
|
||||||
"UnableToLoadImportListExclusions": "No es poden carregar les exclusions de la llista",
|
"UnableToLoadImportListExclusions": "No es poden carregar les exclusions de la llista",
|
||||||
"UnableToLoadIndexerOptions": "No es poden carregar les opcions de l'indexador",
|
"UnableToLoadIndexerOptions": "No es poden carregar les opcions de l'indexador",
|
||||||
"RemoveCompleted": "S'ha eliminat",
|
"RemoveCompleted": "S'ha eliminat",
|
||||||
|
@ -134,7 +134,7 @@
|
||||||
"MoreInfo": "Més informació",
|
"MoreInfo": "Més informació",
|
||||||
"NoBackupsAreAvailable": "No hi ha còpies de seguretat disponibles",
|
"NoBackupsAreAvailable": "No hi ha còpies de seguretat disponibles",
|
||||||
"NETCore": ".NET",
|
"NETCore": ".NET",
|
||||||
"NoHistory": "Sense història",
|
"NoHistory": "Sense historial.",
|
||||||
"NoLeaveIt": "No, deixa-ho",
|
"NoLeaveIt": "No, deixa-ho",
|
||||||
"NotificationTriggers": "Activadors de notificacions",
|
"NotificationTriggers": "Activadors de notificacions",
|
||||||
"NoUpdatesAreAvailable": "No hi ha actualitzacions disponibles",
|
"NoUpdatesAreAvailable": "No hi ha actualitzacions disponibles",
|
||||||
|
@ -243,7 +243,7 @@
|
||||||
"ChownGroupHelpText": "Nom del grup o gid. Utilitzeu gid per a sistemes de fitxers remots.",
|
"ChownGroupHelpText": "Nom del grup o gid. Utilitzeu gid per a sistemes de fitxers remots.",
|
||||||
"ChownGroupHelpTextWarning": "Això només funciona si l'usuari que executa {appName} és el propietari del fitxer. És millor assegurar-se que el client de descàrrega utilitza el mateix grup que {appName}.",
|
"ChownGroupHelpTextWarning": "Això només funciona si l'usuari que executa {appName} és el propietari del fitxer. És millor assegurar-se que el client de descàrrega utilitza el mateix grup que {appName}.",
|
||||||
"ConnectSettings": "Configuració de connexió",
|
"ConnectSettings": "Configuració de connexió",
|
||||||
"CopyUsingHardlinksHelpText": "Utilitzeu els enllaços durs quan intenteu copiar fitxers de torrents que encara s'estan sembrant",
|
"CopyUsingHardlinksHelpText": "Els enllaços durs permeten que {appName} importi torrents de sembra a la carpeta de l'artista sense prendre espai extra al disc o copiar tot el contingut del fitxer. Els enllaços durs només funcionaran si l'origen i la destinació estan en el mateix volum",
|
||||||
"CopyUsingHardlinksHelpTextWarning": "De tant en tant, els bloquejos de fitxers poden impedir reanomenar els fitxers que s'estan sembrant. Podeu desactivar temporalment la compartició i utilitzar la funció de reanomenar de {appName} com a solució.",
|
"CopyUsingHardlinksHelpTextWarning": "De tant en tant, els bloquejos de fitxers poden impedir reanomenar els fitxers que s'estan sembrant. Podeu desactivar temporalment la compartició i utilitzar la funció de reanomenar de {appName} com a solució.",
|
||||||
"CreateEmptyArtistFolders": "Creeu carpetes buides per a les pel·lícules",
|
"CreateEmptyArtistFolders": "Creeu carpetes buides per a les pel·lícules",
|
||||||
"CreateEmptyArtistFoldersHelpText": "Creeu carpetes de pel·lícules que falten durant l'exploració del disc",
|
"CreateEmptyArtistFoldersHelpText": "Creeu carpetes de pel·lícules que falten durant l'exploració del disc",
|
||||||
|
@ -252,7 +252,7 @@
|
||||||
"CutoffUnmet": "Tall no assolit",
|
"CutoffUnmet": "Tall no assolit",
|
||||||
"Dates": "Dates",
|
"Dates": "Dates",
|
||||||
"DatabaseMigration": "Migració de BD",
|
"DatabaseMigration": "Migració de BD",
|
||||||
"DelayingDownloadUntil": "S'està retardant la baixada fins a les {0} a les {1}",
|
"DelayingDownloadUntil": "S'està retardant la baixada fins a les {date} a les {time}",
|
||||||
"DelayProfile": "Perfil de retard",
|
"DelayProfile": "Perfil de retard",
|
||||||
"DelayProfiles": "Perfils de retard",
|
"DelayProfiles": "Perfils de retard",
|
||||||
"Delete": "Suprimeix",
|
"Delete": "Suprimeix",
|
||||||
|
@ -311,7 +311,7 @@
|
||||||
"IllRestartLater": "Reinicia més tard",
|
"IllRestartLater": "Reinicia més tard",
|
||||||
"ImportExtraFiles": "Importa fitxers addicionals",
|
"ImportExtraFiles": "Importa fitxers addicionals",
|
||||||
"ImportExtraFilesHelpText": "Importeu fitxers addicionals coincidents (subtítols, nfo, etc.) després d'importar un fitxer de pel·lícula",
|
"ImportExtraFilesHelpText": "Importeu fitxers addicionals coincidents (subtítols, nfo, etc.) després d'importar un fitxer de pel·lícula",
|
||||||
"ImportFailedInterp": "ImportFailedInterp",
|
"ImportFailedInterp": "Importació fallida: {0}",
|
||||||
"Importing": "S'està important",
|
"Importing": "S'està important",
|
||||||
"IncludeUnmonitored": "Inclou no monitorat",
|
"IncludeUnmonitored": "Inclou no monitorat",
|
||||||
"Indexer": "Indexador",
|
"Indexer": "Indexador",
|
||||||
|
@ -323,7 +323,7 @@
|
||||||
"LogFiles": "Fitxers de registre",
|
"LogFiles": "Fitxers de registre",
|
||||||
"LogLevel": "Nivell de registre",
|
"LogLevel": "Nivell de registre",
|
||||||
"MaximumSize": "Mida màxima",
|
"MaximumSize": "Mida màxima",
|
||||||
"MaximumSizeHelpText": "Mida màxima per a una versió que es pot capturar en MB. Establiu a zero per establir-lo en il·limitat",
|
"MaximumSizeHelpText": "Mida màxima per a una versió que es pot capturar en MB. Establiu a zero per establir-lo en il·limitat.",
|
||||||
"Mechanism": "Mecanisme",
|
"Mechanism": "Mecanisme",
|
||||||
"MediaInfo": "Informació de mitjans",
|
"MediaInfo": "Informació de mitjans",
|
||||||
"MediaManagementSettings": "Configuració de gestió de mitjans",
|
"MediaManagementSettings": "Configuració de gestió de mitjans",
|
||||||
|
@ -462,7 +462,7 @@
|
||||||
"Progress": "Progrés",
|
"Progress": "Progrés",
|
||||||
"SizeLimit": "Límit de mida",
|
"SizeLimit": "Límit de mida",
|
||||||
"Backup": "Còpia de seguretat",
|
"Backup": "Còpia de seguretat",
|
||||||
"IndexerTagHelpText": "Utilitzeu aquest indexador només per a pel·lícules amb almenys una etiqueta coincident. Deixeu-ho en blanc per utilitzar-ho amb totes les pel·lícules.",
|
"IndexerTagHelpText": "Només utilitza aquest indexador per a pel·lícules que coincideixin amb almenys una etiqueta. Deixar en blanc per a utilitzar-ho amb totes les pel·lícules.",
|
||||||
"Info": "Informació",
|
"Info": "Informació",
|
||||||
"InstanceName": "Nom de la instància",
|
"InstanceName": "Nom de la instància",
|
||||||
"InteractiveImport": "Importació interactiva",
|
"InteractiveImport": "Importació interactiva",
|
||||||
|
@ -593,7 +593,7 @@
|
||||||
"CouldntFindAnyResultsForTerm": "No s'ha pogut trobar cap resultat per a '{0}'",
|
"CouldntFindAnyResultsForTerm": "No s'ha pogut trobar cap resultat per a '{0}'",
|
||||||
"DeleteCustomFormat": "Suprimeix el format personalitzat",
|
"DeleteCustomFormat": "Suprimeix el format personalitzat",
|
||||||
"DeleteCustomFormatMessageText": "Esteu segur que voleu suprimir l'indexador '{0}'?",
|
"DeleteCustomFormatMessageText": "Esteu segur que voleu suprimir l'indexador '{0}'?",
|
||||||
"DeleteFormatMessageText": "Esteu segur que voleu suprimir l'etiqueta de format {0} ?",
|
"DeleteFormatMessageText": "Esteu segur que voleu suprimir l'etiqueta de format '{name}'?",
|
||||||
"DownloadPropersAndRepacksHelpTextWarning": "Utilitzeu formats personalitzats per a actualitzacions automàtiques a Propers/Repacks",
|
"DownloadPropersAndRepacksHelpTextWarning": "Utilitzeu formats personalitzats per a actualitzacions automàtiques a Propers/Repacks",
|
||||||
"DownloadedUnableToImportCheckLogsForDetails": "Baixat: no es pot importar: comproveu els registres per obtenir-ne més detalls",
|
"DownloadedUnableToImportCheckLogsForDetails": "Baixat: no es pot importar: comproveu els registres per obtenir-ne més detalls",
|
||||||
"ExportCustomFormat": "Exporta el format personalitzat",
|
"ExportCustomFormat": "Exporta el format personalitzat",
|
||||||
|
@ -601,7 +601,7 @@
|
||||||
"FailedLoadingSearchResults": "No s'han pogut carregar els resultats de la cerca, torneu-ho a provar.",
|
"FailedLoadingSearchResults": "No s'han pogut carregar els resultats de la cerca, torneu-ho a provar.",
|
||||||
"Formats": "Formats",
|
"Formats": "Formats",
|
||||||
"IncludeCustomFormatWhenRenamingHelpText": "Inclou en {Custom Formats} el format de canvi de nom",
|
"IncludeCustomFormatWhenRenamingHelpText": "Inclou en {Custom Formats} el format de canvi de nom",
|
||||||
"ItsEasyToAddANewArtistJustStartTypingTheNameOfTheArtistYouWantToAdd": "És fàcil afegir una pel·lícula nova, només cal que comenceu a escriure el nom de la pel·lícula que voleu afegir",
|
"ItsEasyToAddANewArtistJustStartTypingTheNameOfTheArtistYouWantToAdd": "És fàcil afegir una pel·lícula nova, només cal que comenceu a escriure el nom de la pel·lícula que voleu afegir.",
|
||||||
"MinFormatScoreHelpText": "La puntuació mínima de format personalitzada per a la baixada",
|
"MinFormatScoreHelpText": "La puntuació mínima de format personalitzada per a la baixada",
|
||||||
"Monitor": "Monitora",
|
"Monitor": "Monitora",
|
||||||
"NegateHelpText": "Si està marcat, el format personalitzat no s'aplicarà si la condició {0} coincideix.",
|
"NegateHelpText": "Si està marcat, el format personalitzat no s'aplicarà si la condició {0} coincideix.",
|
||||||
|
@ -614,7 +614,7 @@
|
||||||
"UnableToLoadInteractiveSearch": "No es poden carregar els resultats d'aquesta cerca de pel·lícules. Torna-ho a provar més tard",
|
"UnableToLoadInteractiveSearch": "No es poden carregar els resultats d'aquesta cerca de pel·lícules. Torna-ho a provar més tard",
|
||||||
"TheArtistFolderStrongpathstrongAndAllOfItsContentWillBeDeleted": "La carpeta de pel·lícules '{0}' i tot el seu contingut es suprimiran.",
|
"TheArtistFolderStrongpathstrongAndAllOfItsContentWillBeDeleted": "La carpeta de pel·lícules '{0}' i tot el seu contingut es suprimiran.",
|
||||||
"CustomFormat": "Format personalitzat",
|
"CustomFormat": "Format personalitzat",
|
||||||
"CustomFormatRequiredHelpText": "La condició {0} ha de coincidir perquè s'apliqui el format personalitzat. En cas contrari, n'hi ha prou amb una única coincidència de {1}.",
|
"CustomFormatRequiredHelpText": "La condició {0} ha de coincidir perquè s'apliqui el format personalitzat. En cas contrari, n'hi ha prou amb una única coincidència de {0}.",
|
||||||
"CustomFormatSettings": "Configuració de formats personalitzats",
|
"CustomFormatSettings": "Configuració de formats personalitzats",
|
||||||
"CustomFormats": "Formats personalitzats",
|
"CustomFormats": "Formats personalitzats",
|
||||||
"Customformat": "Formats personalitzats",
|
"Customformat": "Formats personalitzats",
|
||||||
|
@ -643,13 +643,13 @@
|
||||||
"ProxyCheckBadRequestMessage": "No s'ha pogut provar el servidor intermediari. Codi d'estat: {0}",
|
"ProxyCheckBadRequestMessage": "No s'ha pogut provar el servidor intermediari. Codi d'estat: {0}",
|
||||||
"ProxyCheckResolveIpMessage": "No s'ha pogut resoldre l'adreça IP de l'amfitrió intermediari configurat {0}",
|
"ProxyCheckResolveIpMessage": "No s'ha pogut resoldre l'adreça IP de l'amfitrió intermediari configurat {0}",
|
||||||
"RemotePathMappingCheckBadDockerPath": "Esteu utilitzant docker; el client de baixada {0} col·loca les baixades a {1}, però el camí {2} no és vàlid. Reviseu els mapes de camins remots i la configuració del client de baixada.",
|
"RemotePathMappingCheckBadDockerPath": "Esteu utilitzant docker; el client de baixada {0} col·loca les baixades a {1}, però el camí {2} no és vàlid. Reviseu els mapes de camins remots i la configuració del client de baixada.",
|
||||||
"RemotePathMappingCheckDownloadPermissions": "{appName} pot veure però no accedir a la pel·lícula baixada {0}. Error de permisos probable.",
|
"RemotePathMappingCheckDownloadPermissions": "{appName} pot veure però no accedir a la música descarregada {0}. Probablement s'ha produït un error en els permisos.",
|
||||||
"RemotePathMappingCheckDockerFolderMissing": "Esteu utilitzant docker; el client de baixada {0} col·loca les baixades a {1}, però sembla que aquest directori no existeix dins del contenidor. Reviseu els mapes de camins remots i la configuració dels volums del contenidor.",
|
"RemotePathMappingCheckDockerFolderMissing": "Esteu utilitzant docker; el client de baixada {0} col·loca les baixades a {1}, però sembla que aquest directori no existeix dins del contenidor. Reviseu els mapes de camins remots i la configuració dels volums del contenidor.",
|
||||||
"RemotePathMappingCheckFilesBadDockerPath": "Esteu utilitzant docker; el client de baixada{0} ha informat de fitxers a {1}, però el camí {2} no és vàlid. Reviseu els mapes de camins remots i la configuració del client de baixada.",
|
"RemotePathMappingCheckFilesBadDockerPath": "Esteu utilitzant docker; el client de baixada{0} ha informat de fitxers a {1}, però el camí {2} no és vàlid. Reviseu els mapes de camins remots i la configuració del client de baixada.",
|
||||||
"RemotePathMappingCheckFilesLocalWrongOSPath": "El client de baixada local {0} ha informat de fitxers a {1}, però el camí {2} no és vàlid. Reviseu la configuració del vostre client de baixada.",
|
"RemotePathMappingCheckFilesLocalWrongOSPath": "El client de baixada local {0} ha informat de fitxers a {1}, però el camí {2} no és vàlid. Reviseu la configuració del vostre client de baixada.",
|
||||||
"RemotePathMappingCheckFilesWrongOSPath": "El client de baixada remota {0} ha informat de fitxers a {1}, però el camí {2} no és vàlid. Reviseu els mapes de camins remots i baixeu la configuració del client.",
|
"RemotePathMappingCheckFilesWrongOSPath": "El client de baixada remota {0} ha informat de fitxers a {1}, però el camí {2} no és vàlid. Reviseu els mapes de camins remots i baixeu la configuració del client.",
|
||||||
"RemotePathMappingCheckGenericPermissions": "El client de baixada {0} col·loca les baixades a {1} però {appName} no pot veure aquest directori. És possible que hàgiu d'ajustar els permisos de la carpeta.",
|
"RemotePathMappingCheckGenericPermissions": "El client de baixada {0} col·loca les baixades a {1} però {appName} no pot veure aquest directori. És possible que hàgiu d'ajustar els permisos de la carpeta.",
|
||||||
"RemotePathMappingCheckImportFailed": "{appName} no ha pogut importar una pel·lícula. Comproveu els vostres registres per a obtenir més informació.",
|
"RemotePathMappingCheckImportFailed": "{appName} no ha pogut importar música. Comproveu els vostres registres per obtenir-ne més detalls.",
|
||||||
"RemotePathMappingCheckLocalWrongOSPath": "El client de baixada local {0} col·loca les baixades a {1}, però el camí {2} no és vàlid. Reviseu la configuració del vostre client de baixada.",
|
"RemotePathMappingCheckLocalWrongOSPath": "El client de baixada local {0} col·loca les baixades a {1}, però el camí {2} no és vàlid. Reviseu la configuració del vostre client de baixada.",
|
||||||
"RemotePathMappingCheckRemoteDownloadClient": "El client de baixada remota {0} ha informat de fitxers a {1}, però sembla que aquest directori no existeix. És probable que falti el mapa de camins remots.",
|
"RemotePathMappingCheckRemoteDownloadClient": "El client de baixada remota {0} ha informat de fitxers a {1}, però sembla que aquest directori no existeix. És probable que falti el mapa de camins remots.",
|
||||||
"RootFolderCheckMultipleMessage": "Falten diverses carpetes arrel: {0}",
|
"RootFolderCheckMultipleMessage": "Falten diverses carpetes arrel: {0}",
|
||||||
|
@ -677,8 +677,8 @@
|
||||||
"BlocklistReleases": "Llista de llançaments bloquejats",
|
"BlocklistReleases": "Llista de llançaments bloquejats",
|
||||||
"BlocklistReleaseHelpText": "Impedeix que {appName} torni a capturar aquesta versió automàticament",
|
"BlocklistReleaseHelpText": "Impedeix que {appName} torni a capturar aquesta versió automàticament",
|
||||||
"FailedToLoadQueue": "No s'ha pogut carregar la cua",
|
"FailedToLoadQueue": "No s'ha pogut carregar la cua",
|
||||||
"DeleteConditionMessageText": "Esteu segur que voleu suprimir la notificació '{0}'?",
|
"DeleteConditionMessageText": "Esteu segur que voleu suprimir la condició '{name}'?",
|
||||||
"DeleteSelectedDownloadClients": "Suprimeix el client de descàrrega",
|
"DeleteSelectedDownloadClients": "Suprimeix els clients seleccionats de baixada",
|
||||||
"DeleteSelectedIndexers": "Suprimeix l'indexador(s)",
|
"DeleteSelectedIndexers": "Suprimeix l'indexador(s)",
|
||||||
"DeleteSelectedIndexersMessageText": "Esteu segur que voleu suprimir {count} indexador(s) seleccionat(s)?",
|
"DeleteSelectedIndexersMessageText": "Esteu segur que voleu suprimir {count} indexador(s) seleccionat(s)?",
|
||||||
"DownloadClientSortingCheckMessage": "El client de baixada {0} té l'ordenació {1} activada per a la categoria de {appName}. Hauríeu de desactivar l'ordenació al vostre client de descàrrega per evitar problemes d'importació.",
|
"DownloadClientSortingCheckMessage": "El client de baixada {0} té l'ordenació {1} activada per a la categoria de {appName}. Hauríeu de desactivar l'ordenació al vostre client de descàrrega per evitar problemes d'importació.",
|
||||||
|
@ -721,7 +721,7 @@
|
||||||
"ImportListRootFolderMissingRootHealthCheckMessage": "Falta la carpeta arrel per a les llistes d'importació: {0}",
|
"ImportListRootFolderMissingRootHealthCheckMessage": "Falta la carpeta arrel per a les llistes d'importació: {0}",
|
||||||
"ImportListRootFolderMultipleMissingRootsHealthCheckMessage": "Falten diverses carpetes arrel per a les llistes d'importació: {0}",
|
"ImportListRootFolderMultipleMissingRootsHealthCheckMessage": "Falten diverses carpetes arrel per a les llistes d'importació: {0}",
|
||||||
"Enabled": "Habilitat",
|
"Enabled": "Habilitat",
|
||||||
"AddNewArtistRootFolderHelpText": "La subcarpeta '{0}' es crearà automàticament",
|
"AddNewArtistRootFolderHelpText": "La subcarpeta '{folder}' es crearà automàticament",
|
||||||
"Priority": "Prioritat",
|
"Priority": "Prioritat",
|
||||||
"DeleteSpecification": "Esborra especificació",
|
"DeleteSpecification": "Esborra especificació",
|
||||||
"BypassIfHighestQualityHelpText": "Evita el retard quan la versió té la qualitat activada més alta al perfil de qualitat amb el protocol preferit",
|
"BypassIfHighestQualityHelpText": "Evita el retard quan la versió té la qualitat activada més alta al perfil de qualitat amb el protocol preferit",
|
||||||
|
@ -826,15 +826,15 @@
|
||||||
"Unlimited": "Il·limitat",
|
"Unlimited": "Il·limitat",
|
||||||
"Artist": "artista",
|
"Artist": "artista",
|
||||||
"BypassIfAboveCustomFormatScore": "Ometre si està per sobre de la puntuació de format personalitzada",
|
"BypassIfAboveCustomFormatScore": "Ometre si està per sobre de la puntuació de format personalitzada",
|
||||||
"DownloadClientRemovesCompletedDownloadsHealthCheckMessage": "El client de baixada {downloadClientName} està configurat per eliminar les baixades completades. Això pot provocar que les baixades s'eliminin del vostre client abans que {1} pugui importar-les.",
|
"DownloadClientRemovesCompletedDownloadsHealthCheckMessage": "El client de baixada {0} està configurat per eliminar les baixades completades. Això pot provocar que les baixades s'eliminin del vostre client abans que {1} pugui importar-les.",
|
||||||
"EditConnectionImplementation": "Afegeix una connexió - {implementationName}",
|
"EditConnectionImplementation": "Afegeix una connexió - {implementationName}",
|
||||||
"Episode": "Episodi",
|
"Episode": "Episodi",
|
||||||
"AddImportListExclusionAlbumHelpText": "Eviteu que els àlbums s'afegeixin a {appName} per llistes",
|
"AddImportListExclusionAlbumHelpText": "Eviteu que els àlbums s'afegeixin a {appName} per llistes",
|
||||||
"ImportLists": "llista d'importació",
|
"ImportLists": "llista d'importació",
|
||||||
"ApiKeyValidationHealthCheckMessage": "Actualitzeu la vostra clau de l'API perquè tingui almenys {length} caràcters. Podeu fer-ho mitjançant la configuració o el fitxer de configuració",
|
"ApiKeyValidationHealthCheckMessage": "Actualitzeu la vostra clau de l'API perquè tingui almenys {0} caràcters. Podeu fer-ho mitjançant la configuració o el fitxer de configuració",
|
||||||
"BypassIfAboveCustomFormatScoreHelpText": "Habiliteu l'omissió quan la versió tingui una puntuació superior a la puntuació mínima per al format personalitzat",
|
"BypassIfAboveCustomFormatScoreHelpText": "Habiliteu l'omissió quan la versió tingui una puntuació superior a la puntuació mínima per al format personalitzat",
|
||||||
"Artists": "artista",
|
"Artists": "artista",
|
||||||
"CountDownloadClientsSelected": "{count} client(s) de baixada seleccionat(s)",
|
"CountDownloadClientsSelected": "{selectedCount} client(s) de baixada seleccionat(s)",
|
||||||
"EditReleaseProfile": "Afegeix un perfil de llançament",
|
"EditReleaseProfile": "Afegeix un perfil de llançament",
|
||||||
"ReleaseProfiles": "Perfils de llançament",
|
"ReleaseProfiles": "Perfils de llançament",
|
||||||
"ExtraFileExtensionsHelpTextsExamples": "Exemples: '.sub, .nfo' o 'sub,nfo'",
|
"ExtraFileExtensionsHelpTextsExamples": "Exemples: '.sub, .nfo' o 'sub,nfo'",
|
||||||
|
@ -859,7 +859,7 @@
|
||||||
"AutoRedownloadFailedFromInteractiveSearch": "Tornar a baixar baixades fallades des de la cerca interactiva",
|
"AutoRedownloadFailedFromInteractiveSearch": "Tornar a baixar baixades fallades des de la cerca interactiva",
|
||||||
"AutoRedownloadFailed": "Tornar a baixar les baixades fallades",
|
"AutoRedownloadFailed": "Tornar a baixar les baixades fallades",
|
||||||
"StatusEndedContinuing": "Continua",
|
"StatusEndedContinuing": "Continua",
|
||||||
"DeleteTrackFileMessageText": "Esteu segur que voleu suprimir '{path}'?",
|
"DeleteTrackFileMessageText": "Esteu segur que voleu suprimir {0}?",
|
||||||
"NoCutoffUnmetItems": "No hi ha elements de tall no assolits",
|
"NoCutoffUnmetItems": "No hi ha elements de tall no assolits",
|
||||||
"Release": " Llançament",
|
"Release": " Llançament",
|
||||||
"DeleteEmptyFoldersHelpText": "Suprimeix les carpetes de sèries buides durant l'exploració del disc i quan s'esborren els fitxers de sèries",
|
"DeleteEmptyFoldersHelpText": "Suprimeix les carpetes de sèries buides durant l'exploració del disc i quan s'esborren els fitxers de sèries",
|
||||||
|
@ -914,7 +914,7 @@
|
||||||
"DownloadClientDelugeSettingsDirectoryCompleted": "Directori al qual es mou quan s'hagi completat",
|
"DownloadClientDelugeSettingsDirectoryCompleted": "Directori al qual es mou quan s'hagi completat",
|
||||||
"DownloadClientDelugeSettingsDirectoryCompletedHelpText": "Ubicació opcional de les baixades completades, deixeu-lo en blanc per utilitzar la ubicació predeterminada de Deluge",
|
"DownloadClientDelugeSettingsDirectoryCompletedHelpText": "Ubicació opcional de les baixades completades, deixeu-lo en blanc per utilitzar la ubicació predeterminada de Deluge",
|
||||||
"DownloadClientDelugeSettingsDirectoryHelpText": "Ubicació opcional de les baixades completades, deixeu-lo en blanc per utilitzar la ubicació predeterminada de Deluge",
|
"DownloadClientDelugeSettingsDirectoryHelpText": "Ubicació opcional de les baixades completades, deixeu-lo en blanc per utilitzar la ubicació predeterminada de Deluge",
|
||||||
"GrabReleaseUnknownArtistOrAlbumMessageText": "{appName} no ha pogut determinar per a quina pel·lícula era aquest llançament. És possible que {appName} no pugui importar automàticament aquesta versió. Voleu capturar \"{0}\"?",
|
"GrabReleaseUnknownArtistOrAlbumMessageText": "{appName} no ha pogut determinar per a quina pel·lícula era aquest llançament. És possible que {appName} no pugui importar automàticament aquesta versió. Voleu capturar '{title}'?",
|
||||||
"IndexerFlags": "Indicadors de l'indexador",
|
"IndexerFlags": "Indicadors de l'indexador",
|
||||||
"MonitorNoAlbums": "Cap",
|
"MonitorNoAlbums": "Cap",
|
||||||
"Rejections": "Rebutjats",
|
"Rejections": "Rebutjats",
|
||||||
|
@ -992,5 +992,240 @@
|
||||||
"Paused": "En pausa",
|
"Paused": "En pausa",
|
||||||
"Pending": "Pendents",
|
"Pending": "Pendents",
|
||||||
"WaitingToImport": "S’està esperant per a importar",
|
"WaitingToImport": "S’està esperant per a importar",
|
||||||
"WaitingToProcess": "S’està esperant per a processar"
|
"WaitingToProcess": "S’està esperant per a processar",
|
||||||
|
"DefaultMonitorOptionHelpText": "Quins àlbums s'han de controlar en afegir inicialment per als artistes detectats en aquesta carpeta",
|
||||||
|
"DownloadedImporting": "'Descarregat - Important'",
|
||||||
|
"ExpandItemsByDefault": "Expandeix els elements per defecte",
|
||||||
|
"HideAlbums": "Oculta els àlbums",
|
||||||
|
"PathHelpText": "Carpeta arrel que conté la vostra biblioteca de música",
|
||||||
|
"AllAlbums": "Tots els àlbums",
|
||||||
|
"AllowFingerprintingHelpText": "Utilitza l'empremta digital per millorar la precisió de la coincidència de la pista",
|
||||||
|
"DefaultTagsHelpText": "Etiquetes {appName} per defecte per als artistes detectats en aquesta carpeta",
|
||||||
|
"ShowNextAlbumHelpText": "Mostra el següent àlbum sota el cartell",
|
||||||
|
"TheAlbumsFilesWillBeDeleted": "Els fitxers de l'àlbum s'eliminaran.",
|
||||||
|
"TrackCount": "Comptador de pistes",
|
||||||
|
"TrackDownloaded": "Pista descarregada",
|
||||||
|
"TrackFiles": "Fitxers de pista",
|
||||||
|
"ArtistNameHelpText": "El nom de l'artista/àlbum a excloure (pot ser qualsevol cosa significativa)",
|
||||||
|
"ContinuingNoAdditionalAlbumsAreExpected": "No s'espera cap àlbum addicional",
|
||||||
|
"ContinuingMoreAlbumsAreExpected": "S'espera més àlbums",
|
||||||
|
"AddedArtistSettings": "Configuració d'artista afegida",
|
||||||
|
"AlbumDetails": "Detalls de l'àlbum",
|
||||||
|
"AlbumHasNotAired": "L'àlbum no s'ha emès",
|
||||||
|
"AlbumInfo": "Informació de l'àlbum",
|
||||||
|
"AlbumIsDownloading": "L'àlbum s'està baixant",
|
||||||
|
"AlbumIsNotMonitored": "L'àlbum no està monitoritzat",
|
||||||
|
"AlbumRelease": "Publicació de l'àlbum",
|
||||||
|
"AlbumReleaseDate": "Data de publicació de l'àlbum",
|
||||||
|
"AlbumStatus": "Estat de l'àlbum",
|
||||||
|
"AlbumStudio": "Estudi d'àlbum",
|
||||||
|
"AlbumStudioTracksDownloaded": "{trackFileCount}/{totalTrackCount} pistes baixades",
|
||||||
|
"AlbumStudioTruncated": "Només es mostren els últims 20 àlbums, ves als detalls per veure tots els àlbums",
|
||||||
|
"AlbumType": "Tipus d'àlbum",
|
||||||
|
"AllAlbumsData": "Controla tots els àlbums excepte els especials",
|
||||||
|
"AllArtistAlbums": "Tots els àlbums d'artista",
|
||||||
|
"AllMonitoringOptionHelpText": "Monitora els artistes i tots els àlbums de cada artista inclosos a la llista d'importació",
|
||||||
|
"AllowFingerprintingHelpTextWarning": "Això requereix que {appName} llegeixi parts del fitxer que alentiran els escanejos i poden causar una activitat de disc o xarxa alta.",
|
||||||
|
"AnchorTooltip": "Aquest fitxer ja és a la vostra biblioteca per a una versió que esteu important",
|
||||||
|
"AnyReleaseOkHelpText": "{appName} canviarà automàticament a la versió que coincideixi amb les pistes baixades",
|
||||||
|
"ArtistClickToChangeAlbum": "Feu clic per canviar l'àlbum",
|
||||||
|
"ArtistEditor": "Editor d'artistes",
|
||||||
|
"ArtistFolderFormat": "Format de carpeta d'artista",
|
||||||
|
"ArtistIsMonitored": "L'artista està monitoritzat",
|
||||||
|
"ArtistMonitoring": "Seguiment de l'artista",
|
||||||
|
"ArtistProgressBarText": "{trackFileCount} / {trackCount} (Total: {totalTrackCount}, Baixada: {downloadingCount})",
|
||||||
|
"ArtistType": "Tipus d'artista",
|
||||||
|
"ArtistsEditRootFolderHelpText": "Moure artistes a la mateixa carpeta arrel es pot utilitzar per a canviar el nom de les carpetes d'artista perquè coincideixin amb el nom o el format de nom actualitzat",
|
||||||
|
"AutomaticallySwitchRelease": "Commuta automàticament la versió",
|
||||||
|
"BackupIntervalHelpText": "Interval per a fer una còpia de seguretat de la base de dades {appName} i de la configuració",
|
||||||
|
"BannerOptions": "Opcions del bàner",
|
||||||
|
"ContinuingAllTracksDownloaded": "Continuant (totes les pistes baixades)",
|
||||||
|
"DashOrSpaceDashDependingOnName": "Traç o guió d'espai depenent del nom",
|
||||||
|
"DelayProfileArtistTagsHelpText": "Aplica als artistes amb almenys una etiqueta coincident",
|
||||||
|
"DownloadClientSettingsRecentPriorityAlbumHelpText": "Prioritat a utilitzar en capturar àlbums publicats en els últims 14 dies",
|
||||||
|
"IsShowingMonitoredMonitorSelected": "Monitor seleccionat",
|
||||||
|
"LidarrSupportsMultipleListsForImportingAlbumsAndArtistsIntoTheDatabase": "{appName} admet múltiples llistes per importar àlbums i artistes a la base de dades.",
|
||||||
|
"MediumFormat": "Format mitjà",
|
||||||
|
"MetadataSettingsArtistSummary": "Crea fitxers de metadades quan s'importin pistes o s'actualitzi l'artista",
|
||||||
|
"MissingTracks": "Manquen pistes",
|
||||||
|
"MonitorAlbum": "Àlbum del monitor",
|
||||||
|
"MonitorArtists": "Monitora els artistes",
|
||||||
|
"MonitorExistingAlbums": "Àlbums existents",
|
||||||
|
"MonitorFirstAlbum": "Primer àlbum",
|
||||||
|
"NoTracksInThisMedium": "No hi ha pistes en aquest suport",
|
||||||
|
"NotificationsSettingsUpdateMapPathsToHelpText": "{serviceName} camí, utilitzat per modificar els camins de sèrie quan {serviceName} veu la ubicació del camí de la biblioteca diferent de {appName} (requereix 'Biblioteca d'actualització')",
|
||||||
|
"OneAlbum": "1 àlbum",
|
||||||
|
"Retag": "Reetiqueta",
|
||||||
|
"SearchForAllCutoffUnmetAlbums": "Cerca tots els àlbums de Cutoff Unmet",
|
||||||
|
"SecondaryAlbumTypes": "Tipus d'àlbum secundari",
|
||||||
|
"SetAppTags": "Estableix {appName} etiquetes",
|
||||||
|
"ShouldMonitorExisting": "Monitora els àlbums existents",
|
||||||
|
"ShouldMonitorExistingHelpText": "Monitora automàticament els àlbums d'aquesta llista que ja estan a {appName}",
|
||||||
|
"ShouldMonitorHelpText": "Monitora els artistes i àlbums afegits d'aquesta llista",
|
||||||
|
"ShowLastAlbum": "Mostra l'últim àlbum",
|
||||||
|
"TagAudioFilesWithMetadata": "Etiqueta els fitxers d'àudio amb metadades",
|
||||||
|
"TrackFileMissingTooltip": "Falta el fitxer de la pista",
|
||||||
|
"TrackNaming": "Nom de la pista",
|
||||||
|
"TrackProgress": "Progrés de la pista",
|
||||||
|
"TrackStatus": "Estat de la pista",
|
||||||
|
"SpecificMonitoringOptionHelpText": "Monitora els artistes, però només supervisa els àlbums inclosos explícitament a la llista",
|
||||||
|
"OnAlbumDelete": "En suprimir l'àlbum",
|
||||||
|
"TrackFileDeletedTooltip": "S'ha suprimit el fitxer de pista",
|
||||||
|
"TrackFileTagsUpdatedTooltip": "S'han actualitzat les etiquetes dels fitxers de seguiment",
|
||||||
|
"MonitoringOptionsHelpText": "Quins àlbums s'han de controlar després d'afegir l'artista (ajust d'un sol cop)",
|
||||||
|
"Proceed": "Procedeix",
|
||||||
|
"SelectArtist": "Selecciona l'artista",
|
||||||
|
"AllowArtistChangeClickToChangeArtist": "Feu clic per canviar l'artista",
|
||||||
|
"FutureAlbums": "Àlbums futurs",
|
||||||
|
"ArtistName": "Nom de l'artista",
|
||||||
|
"MonitorNoNewAlbums": "Sense àlbums nous",
|
||||||
|
"IsExpandedShowTracks": "Mostra les pistes",
|
||||||
|
"MonitorMissingAlbums": "Manquen àlbums",
|
||||||
|
"ShowAlbumCount": "Mostra el comptador d'àlbums",
|
||||||
|
"AreYouSure": "N'estàs segur?",
|
||||||
|
"Banners": "Bàners",
|
||||||
|
"NoneMonitoringOptionHelpText": "No monitoris artistes ni àlbums",
|
||||||
|
"DownloadedWaitingToImport": "'Descarregat - Esperant a importar'",
|
||||||
|
"EpisodeDoesNotHaveAnAbsoluteEpisodeNumber": "L'episodi no té un número d'episodi absolut",
|
||||||
|
"NoMediumInformation": "No hi ha informació de suport disponible.",
|
||||||
|
"MissingTracksArtistNotMonitored": "Manquen pistes (l'artista no està monitoritzat)",
|
||||||
|
"NotDiscography": "No discografia",
|
||||||
|
"NotificationsSettingsUpdateMapPathsFromHelpText": "{appName} camí, utilitzat per modificar els camins de sèrie quan {serviceName} veu la ubicació del camí de la biblioteca diferent de {appName} (requereix 'Biblioteca d'actualització')",
|
||||||
|
"NotificationsTagsArtistHelpText": "Envia només notificacions per a artistes amb almenys una etiqueta coincident",
|
||||||
|
"Playlist": "Reproducció",
|
||||||
|
"PrimaryAlbumTypes": "Tipus d'àlbum principal",
|
||||||
|
"PrimaryTypes": "Tipus primaris",
|
||||||
|
"TrackArtist": "Artista de la pista",
|
||||||
|
"TrackImported": "S'ha importat la pista",
|
||||||
|
"DownloadImported": "Baixada importada",
|
||||||
|
"ForeignId": "Id estranger",
|
||||||
|
"Inactive": "Inactiu",
|
||||||
|
"EditArtist": "Edita l'artista",
|
||||||
|
"ReleasesHelpText": "Canvia el llançament d'aquest àlbum",
|
||||||
|
"ShouldSearch": "Cerca elements nous",
|
||||||
|
"GoToArtistListing": "Ves a la llista d'artistes",
|
||||||
|
"SelectAlbum": "Selecciona l'àlbum",
|
||||||
|
"SceneNumberHasntBeenVerifiedYet": "El número d'escena encara no s'ha verificat",
|
||||||
|
"SelectTracks": "Selecciona les pistes",
|
||||||
|
"ArtistIsUnmonitored": "L'artista no està monitoritzat",
|
||||||
|
"DefaultQualityProfileIdHelpText": "Perfil de qualitat predeterminat per als artistes detectats en aquesta carpeta",
|
||||||
|
"ExistingAlbums": "Àlbums existents",
|
||||||
|
"GroupInformation": "Informació del grup",
|
||||||
|
"MatchedToAlbums": "Coincideix amb els àlbums",
|
||||||
|
"MusicbrainzId": "Id del Musicbrainz",
|
||||||
|
"ThereWasAnErrorLoadingThisItem": "S'ha produït un error en carregar aquest element",
|
||||||
|
"SearchBoxPlaceHolder": "p. ex. Trencant Benjamin, lidarr:854a1807-025b-42a8-ba8c-2a39717f1d25",
|
||||||
|
"ShowNextAlbum": "Mostra l'àlbum següent",
|
||||||
|
"MediaCount": "Comptador de mitjans",
|
||||||
|
"MissingAlbums": "Manquen àlbums",
|
||||||
|
"MissingTracksArtistMonitored": "Pistes que falten (controlat per l'artista)",
|
||||||
|
"MonitorFutureAlbums": "Àlbums futurs",
|
||||||
|
"MusicBrainzAlbumID": "ID de l'àlbum del MusicBrainz",
|
||||||
|
"NextAlbum": "Àlbum següent",
|
||||||
|
"AlbumTitle": "Títol de l'àlbum",
|
||||||
|
"AllExpandedExpandAll": "Expandeix-ho tot",
|
||||||
|
"MonitorNewAlbums": "Àlbums nous",
|
||||||
|
"LatestAlbum": "Últim àlbum",
|
||||||
|
"RemoveSelectedItemBlocklistMessageText": "Esteu segur que voleu eliminar els elements seleccionats de la llista de bloqueigs?",
|
||||||
|
"RenameTracks": "Canvia el nom de les pistes",
|
||||||
|
"ThereWasAnErrorLoadingThisPage": "S'ha produït un error en carregar aquesta pàgina",
|
||||||
|
"TrackFileCounttotalTrackCountTracksDownloadedInterp": "{0}/{1} pistes baixades",
|
||||||
|
"TrackFileRenamedTooltip": "S'ha canviat el nom del fitxer de pista",
|
||||||
|
"WriteMetadataToAudioFiles": "Escriu les metadades als fitxers d'àudio",
|
||||||
|
"HasMonitoredAlbumsNoMonitoredAlbumsForThisArtist": "No hi ha àlbums supervisats per a aquest artista",
|
||||||
|
"SearchAlbum": "Cerca un àlbum",
|
||||||
|
"ForNewImportsOnly": "Només per a importacions noves",
|
||||||
|
"CollapseMultipleAlbums": "Redueix diversos àlbums",
|
||||||
|
"CollapseMultipleAlbumsHelpText": "Redueix diversos àlbums que es publiquen el mateix dia",
|
||||||
|
"CombineWithExistingFiles": "Combina amb els fitxers existents",
|
||||||
|
"CountAlbums": "{albumCount} àlbums",
|
||||||
|
"Deceased": "Defunció",
|
||||||
|
"DefaultDelayProfileArtist": "Aquest és el perfil per defecte. S'aplica a tots els artistes que no tenen un perfil explícit.",
|
||||||
|
"DefaultLidarrTags": "Etiquetes {appName} per defecte",
|
||||||
|
"DefaultMetadataProfileIdHelpText": "Perfil predeterminat de metadades per als artistes detectats en aquesta carpeta",
|
||||||
|
"DeleteArtist": "Suprimeix l'artista seleccionat",
|
||||||
|
"DeleteArtistFolder": "Suprimeix la carpeta d'artista",
|
||||||
|
"DeleteArtistFolderCountWithFilesConfirmation": "Esteu segur que voleu suprimir {count} artistes seleccionats i tots els continguts?",
|
||||||
|
"DeleteFilesHelpText": "Suprimeix els fitxers de la pista i la carpeta de l'artista",
|
||||||
|
"DeleteSelectedArtists": "Suprimeix els artistes seleccionats",
|
||||||
|
"DeleteTrackFile": "Suprimeix el fitxer de pista",
|
||||||
|
"EditSelectedArtists": "Edita els artistes seleccionats",
|
||||||
|
"EmbedCoverArtHelpText": "Incrusta l'art de l'àlbum Lidarr en fitxers d'àudio en escriure etiquetes",
|
||||||
|
"EmbedCoverArtInAudioFiles": "Incrusta la caràtula en fitxers d'àudio",
|
||||||
|
"EnableAutomaticAddHelpText": "Afegeix un artista/àlbum a {appName} quan es realitzen les sincronitzacions a través de la interfície d'usuari o per {appName}",
|
||||||
|
"EnabledHelpText": "Marqueu-ho per a habilitar el perfil de la versió",
|
||||||
|
"EndedAllTracksDownloaded": "Finalitzat (totes les pistes baixades)",
|
||||||
|
"ExistingAlbumsData": "Monitora els àlbums que tenen fitxers o encara no s'han publicat",
|
||||||
|
"ExpandBroadcastByDefaultHelpText": "Transmissió",
|
||||||
|
"ExpandEPByDefaultHelpText": "Eps",
|
||||||
|
"ExpandSingleByDefaultHelpText": "Individuals",
|
||||||
|
"FilterAlbumPlaceholder": "Filtra l'àlbum",
|
||||||
|
"FilterArtistPlaceholder": "Filtra l'artista",
|
||||||
|
"FirstAlbum": "Primer àlbum",
|
||||||
|
"FirstAlbumData": "Controla els primers àlbums. Tots els altres àlbums seran ignorats",
|
||||||
|
"ForeignIdHelpText": "L'ID del Musicbrainz de l'artista/àlbum a excloure",
|
||||||
|
"FutureAlbumsData": "Monitora els àlbums que encara no s'han publicat",
|
||||||
|
"HideTracks": "Oculta les pistes",
|
||||||
|
"ICalTagsArtistHelpText": "Feed només contindrà artistes amb almenys una etiqueta coincident",
|
||||||
|
"IfYouDontAddAnImportListExclusionAndTheArtistHasAMetadataProfileOtherThanNoneThenThisAlbumMayBeReaddedDuringTheNextArtistRefresh": "Si no afegiu una exclusió de la llista d'importació i l'artista té un perfil de metadades diferent de 'None'.",
|
||||||
|
"ImportCompleteFailed": "Ha fallat la importació",
|
||||||
|
"ImportListTagsHelpText": "Etiquetes que s'afegiran a la importació des d'aquesta llista",
|
||||||
|
"IndexerIdHelpText": "Especifiqueu a quin indexador s'aplica el perfil",
|
||||||
|
"IsExpandedHideAlbums": "Oculta els àlbums",
|
||||||
|
"IsExpandedHideTracks": "Oculta les pistes",
|
||||||
|
"IsExpandedShowAlbums": "Mostra els àlbums",
|
||||||
|
"IsInUseCantDeleteAMetadataProfileThatIsAttachedToAnArtistOrImportList": "No es pot suprimir un perfil de metadades que està adjuntat a un artista o a una llista d'importació",
|
||||||
|
"IsInUseCantDeleteAQualityProfileThatIsAttachedToAnArtistOrImportList": "No es pot suprimir un perfil de qualitat que estigui adjuntat a un artista o a una llista d'importació",
|
||||||
|
"IsShowingMonitoredUnmonitorSelected": "Unmonitor seleccionat",
|
||||||
|
"LastAlbum": "Últim àlbum",
|
||||||
|
"LatestAlbumData": "Monitoritza els últims àlbums i futurs àlbums",
|
||||||
|
"ManageTracks": "Gestiona les pistes",
|
||||||
|
"MatchedToArtist": "Coincideix amb l'artista",
|
||||||
|
"MassAlbumsCutoffUnmetWarning": "Esteu segur que voleu cercar tots els ‘{0}’ àlbums sense límits satisfets?",
|
||||||
|
"MissingAlbumsData": "Monitora els àlbums que no tenen fitxers o que encara no s'han publicat",
|
||||||
|
"MonitorAlbumExistingOnlyWarning": "Aquest és un ajust ajustat de la configuració monitoritzada per a cada àlbum. Utilitzeu l'opció Artist/Edit per controlar què passa amb els àlbums nous",
|
||||||
|
"MonitorAllAlbums": "Tots els àlbums",
|
||||||
|
"MonitorArtist": "Monitora l’artista",
|
||||||
|
"MonitorLastestAlbum": "Últim àlbum",
|
||||||
|
"MonitorNewItems": "Monitora els àlbums nous",
|
||||||
|
"MonitorNewItemsHelpText": "Quins àlbums nous s'han de controlar",
|
||||||
|
"MonitoredHelpText": "Baixa els àlbums monitoritzats d'aquest artista",
|
||||||
|
"MultiDiscTrackFormat": "Format de pista multidisc",
|
||||||
|
"MusicBrainzArtistID": "ID de l'artista del MusicBrainz",
|
||||||
|
"NoneData": "No es controlarà cap àlbum",
|
||||||
|
"OnArtistAdd": "En afegir l'artista",
|
||||||
|
"Retagged": "Reetiquetat",
|
||||||
|
"RecycleBinUnableToWriteHealthCheck": "No s'ha pogut escriure a la carpeta de contenidors de reciclatge configurada: {0}. Assegureu-vos que aquest camí existeix i que l'usuari que executa {appName} pot escriure",
|
||||||
|
"RefreshArtist": "Actualitza l'artista",
|
||||||
|
"ReleaseProfileTagArtistHelpText": "Els perfils de llançament s'aplicaran als artistes amb almenys una etiqueta coincident. Deixa en blanc per aplicar a tots els artistes",
|
||||||
|
"ReplaceExistingFiles": "Substitueix els fitxers existents",
|
||||||
|
"RetagSelectedArtists": "Reetiqueta els artistes seleccionats",
|
||||||
|
"SearchForAllCutoffUnmetAlbumsConfirmationCount": "Esteu segur que voleu cercar tots els {totalRecords} àlbums tallats Unmet?",
|
||||||
|
"SearchForAllMissingAlbums": "Cerca tots els àlbums que falten",
|
||||||
|
"SearchForAllMissingAlbumsConfirmationCount": "Esteu segur que voleu cercar tots els {totalRecords} àlbums que manquen?",
|
||||||
|
"SearchForMonitoredAlbums": "Cerca àlbums monitoritzats",
|
||||||
|
"SecondaryTypes": "Tipus secundaris",
|
||||||
|
"SelectAlbumRelease": "Selecciona la publicació de l'àlbum",
|
||||||
|
"SelectedCountArtistsSelectedInterp": "{selectedCount} Artistes seleccionats",
|
||||||
|
"ShowTitleHelpText": "Mostra el nom de l'artista sota el cartell",
|
||||||
|
"SkipRedownloadHelpText": "Evita que {appName} intenti baixar versions alternatives per als elements eliminats",
|
||||||
|
"SpecificAlbum": "Àlbum específic",
|
||||||
|
"TotalTrackCountTracksTotalTrackFileCountTracksWithFilesInterp": "{0} pistes totals. {1} pistes amb fitxers.",
|
||||||
|
"TrackFilesCountMessage": "No hi ha fitxers de pista",
|
||||||
|
"TrackFilesLoadError": "No s'han pogut carregar els fitxers de pista",
|
||||||
|
"TrackMissingFromDisk": "Falta la pista del disc",
|
||||||
|
"TracksLoadError": "No s'han pogut carregar les pistes",
|
||||||
|
"WriteAudioTagsHelpTextWarning": "En seleccionar ‘Tots els fitxers’ s'alteraran els fitxers existents quan s'importin.",
|
||||||
|
"DeleteArtistFolders": "Suprimeix les carpetes d'artista",
|
||||||
|
"DownloadClientSettingsOlderPriorityAlbumHelpText": "Prioritat a utilitzar en capturar àlbums publicats fa més de 14 dies",
|
||||||
|
"EditMetadata": "Edita les metadades",
|
||||||
|
"NewAlbums": "Àlbums nous",
|
||||||
|
"NoAlbums": "Sense àlbums",
|
||||||
|
"NoMissingItems": "No falten elements",
|
||||||
|
"OnArtistDelete": "En suprimir l'artista",
|
||||||
|
"OnTrackRetag": "En reetiquetar la pista",
|
||||||
|
"RootFolderPathHelpText": "Els elements de la llista de carpetes arrel s'afegiran a",
|
||||||
|
"ScrubAudioTagsHelpText": "Elimina les etiquetes existents dels fitxers, deixant només les afegides per {appName}.",
|
||||||
|
"ScrubExistingTags": "Neteja les etiquetes existents",
|
||||||
|
"Disambiguation": "Desambiguació"
|
||||||
}
|
}
|
||||||
|
|
|
@ -256,6 +256,7 @@
|
||||||
"CreateEmptyArtistFolders": "Create empty artist folders",
|
"CreateEmptyArtistFolders": "Create empty artist folders",
|
||||||
"CreateEmptyArtistFoldersHelpText": "Create missing artist folders during disk scan",
|
"CreateEmptyArtistFoldersHelpText": "Create missing artist folders during disk scan",
|
||||||
"CreateGroup": "Create group",
|
"CreateGroup": "Create group",
|
||||||
|
"CurrentlyInstalled": "Currently Installed",
|
||||||
"Custom": "Custom",
|
"Custom": "Custom",
|
||||||
"CustomFilter": "Custom Filter",
|
"CustomFilter": "Custom Filter",
|
||||||
"CustomFilters": "Custom Filters",
|
"CustomFilters": "Custom Filters",
|
||||||
|
@ -334,8 +335,6 @@
|
||||||
"DeleteReleaseProfileMessageText": "Are you sure you want to delete this release profile?",
|
"DeleteReleaseProfileMessageText": "Are you sure you want to delete this release profile?",
|
||||||
"DeleteRemotePathMapping": "Delete Remote Path Mapping",
|
"DeleteRemotePathMapping": "Delete Remote Path Mapping",
|
||||||
"DeleteRemotePathMappingMessageText": "Are you sure you want to delete this remote path mapping?",
|
"DeleteRemotePathMappingMessageText": "Are you sure you want to delete this remote path mapping?",
|
||||||
"DeleteRootFolder": "Delete Root Folder",
|
|
||||||
"DeleteRootFolderMessageText": "Are you sure you want to delete the root folder '{name}'?",
|
|
||||||
"DeleteSelected": "Delete Selected",
|
"DeleteSelected": "Delete Selected",
|
||||||
"DeleteSelectedArtists": "Delete Selected Artists",
|
"DeleteSelectedArtists": "Delete Selected Artists",
|
||||||
"DeleteSelectedCustomFormats": "Delete Custom Format(s)",
|
"DeleteSelectedCustomFormats": "Delete Custom Format(s)",
|
||||||
|
@ -383,6 +382,7 @@
|
||||||
"DownloadClientDelugeSettingsDirectoryCompleted": "Move When Completed Directory",
|
"DownloadClientDelugeSettingsDirectoryCompleted": "Move When Completed Directory",
|
||||||
"DownloadClientDelugeSettingsDirectoryCompletedHelpText": "Optional location to move completed downloads to, leave blank to use the default Deluge location",
|
"DownloadClientDelugeSettingsDirectoryCompletedHelpText": "Optional location to move completed downloads to, leave blank to use the default Deluge location",
|
||||||
"DownloadClientDelugeSettingsDirectoryHelpText": "Optional location to put downloads in, leave blank to use the default Deluge location",
|
"DownloadClientDelugeSettingsDirectoryHelpText": "Optional location to put downloads in, leave blank to use the default Deluge location",
|
||||||
|
"DownloadClientItemErrorMessage": "{clientName} is reporting an error: {message}",
|
||||||
"DownloadClientPriorityHelpText": "Download Client Priority from 1 (Highest) to 50 (Lowest). Default: 1. Round-Robin is used for clients with the same priority.",
|
"DownloadClientPriorityHelpText": "Download Client Priority from 1 (Highest) to 50 (Lowest). Default: 1. Round-Robin is used for clients with the same priority.",
|
||||||
"DownloadClientQbittorrentSettingsContentLayout": "Content Layout",
|
"DownloadClientQbittorrentSettingsContentLayout": "Content Layout",
|
||||||
"DownloadClientQbittorrentSettingsContentLayoutHelpText": "Whether to use qBittorrent's configured content layout, the original layout from the torrent or always create a subfolder (qBittorrent 4.3.2+)",
|
"DownloadClientQbittorrentSettingsContentLayoutHelpText": "Whether to use qBittorrent's configured content layout, the original layout from the torrent or always create a subfolder (qBittorrent 4.3.2+)",
|
||||||
|
@ -486,6 +486,8 @@
|
||||||
"ExtraFileExtensionsHelpTextsExamples": "Examples: '.sub, .nfo' or 'sub,nfo'",
|
"ExtraFileExtensionsHelpTextsExamples": "Examples: '.sub, .nfo' or 'sub,nfo'",
|
||||||
"FailedDownloadHandling": "Failed Download Handling",
|
"FailedDownloadHandling": "Failed Download Handling",
|
||||||
"FailedLoadingSearchResults": "Failed to load search results, please try again.",
|
"FailedLoadingSearchResults": "Failed to load search results, please try again.",
|
||||||
|
"FailedToFetchSettings": "Failed to fetch settings",
|
||||||
|
"FailedToFetchUpdates": "Failed to fetch updates",
|
||||||
"FailedToLoadQueue": "Failed to load Queue",
|
"FailedToLoadQueue": "Failed to load Queue",
|
||||||
"False": "False",
|
"False": "False",
|
||||||
"FileDateHelpText": "Change file date on import/rescan",
|
"FileDateHelpText": "Change file date on import/rescan",
|
||||||
|
@ -688,6 +690,7 @@
|
||||||
"LocalPathHelpText": "Path that {appName} should use to access the remote path locally",
|
"LocalPathHelpText": "Path that {appName} should use to access the remote path locally",
|
||||||
"Location": "Location",
|
"Location": "Location",
|
||||||
"LogFiles": "Log Files",
|
"LogFiles": "Log Files",
|
||||||
|
"LogFilesLocation": "Log files are located in: {location}",
|
||||||
"LogLevel": "Log Level",
|
"LogLevel": "Log Level",
|
||||||
"LogLevelvalueTraceTraceLoggingShouldOnlyBeEnabledTemporarily": "Trace logging should only be enabled temporarily",
|
"LogLevelvalueTraceTraceLoggingShouldOnlyBeEnabledTemporarily": "Trace logging should only be enabled temporarily",
|
||||||
"LogSizeLimit": "Log Size Limit",
|
"LogSizeLimit": "Log Size Limit",
|
||||||
|
@ -1024,6 +1027,8 @@
|
||||||
"RemoveQueueItemRemovalMethod": "Removal Method",
|
"RemoveQueueItemRemovalMethod": "Removal Method",
|
||||||
"RemoveQueueItemRemovalMethodHelpTextWarning": "'Remove from Download Client' will remove the download and the file(s) from the download client.",
|
"RemoveQueueItemRemovalMethodHelpTextWarning": "'Remove from Download Client' will remove the download and the file(s) from the download client.",
|
||||||
"RemoveQueueItemsRemovalMethodHelpTextWarning": "'Remove from Download Client' will remove the downloads and the files from the download client.",
|
"RemoveQueueItemsRemovalMethodHelpTextWarning": "'Remove from Download Client' will remove the downloads and the files from the download client.",
|
||||||
|
"RemoveRootFolder": "Remove Root Folder",
|
||||||
|
"RemoveRootFolderArtistsMessageText": "Are you sure you want to remove the root folder '{name}'? Files and folders will not be deleted from disk, and artists in this root folder will not be removed from {appName}.",
|
||||||
"RemoveSelected": "Remove Selected",
|
"RemoveSelected": "Remove Selected",
|
||||||
"RemoveSelectedItem": "Remove Selected Item",
|
"RemoveSelectedItem": "Remove Selected Item",
|
||||||
"RemoveSelectedItemBlocklistMessageText": "Are you sure you want to remove the selected items from the blocklist?",
|
"RemoveSelectedItemBlocklistMessageText": "Are you sure you want to remove the selected items from the blocklist?",
|
||||||
|
@ -1218,6 +1223,7 @@
|
||||||
"TestParsing": "Test Parsing",
|
"TestParsing": "Test Parsing",
|
||||||
"TheAlbumsFilesWillBeDeleted": "The album's files will be deleted.",
|
"TheAlbumsFilesWillBeDeleted": "The album's files will be deleted.",
|
||||||
"TheArtistFolderStrongpathstrongAndAllOfItsContentWillBeDeleted": "The artist folder '{0}' and all of its content will be deleted.",
|
"TheArtistFolderStrongpathstrongAndAllOfItsContentWillBeDeleted": "The artist folder '{0}' and all of its content will be deleted.",
|
||||||
|
"TheLogLevelDefault": "The log level defaults to 'Debug' and can be changed in [General Settings](/settings/general)",
|
||||||
"Theme": "Theme",
|
"Theme": "Theme",
|
||||||
"ThemeHelpText": "Change Application UI Theme, 'Auto' Theme will use your OS Theme to set Light or Dark mode. Inspired by Theme.Park",
|
"ThemeHelpText": "Change Application UI Theme, 'Auto' Theme will use your OS Theme to set Light or Dark mode. Inspired by Theme.Park",
|
||||||
"ThereWasAnErrorLoadingThisItem": "There was an error loading this item",
|
"ThereWasAnErrorLoadingThisItem": "There was an error loading this item",
|
||||||
|
|
|
@ -963,7 +963,7 @@
|
||||||
"Small": "Pieni",
|
"Small": "Pieni",
|
||||||
"RemoveSelectedItems": "Poista valitut kohteet",
|
"RemoveSelectedItems": "Poista valitut kohteet",
|
||||||
"ResetTitles": "Palauta nimet",
|
"ResetTitles": "Palauta nimet",
|
||||||
"AddNewArtistRootFolderHelpText": "\"{folder}\" -alikansio luodaan automaattisesti.",
|
"AddNewArtistRootFolderHelpText": "Alikansio \"{folder}\" luodaan automaattisesti.",
|
||||||
"AuthenticationRequiredUsernameHelpTextWarning": "Syötä uusi käyttäjätunnus",
|
"AuthenticationRequiredUsernameHelpTextWarning": "Syötä uusi käyttäjätunnus",
|
||||||
"AutoAdd": "Automaattilisäys",
|
"AutoAdd": "Automaattilisäys",
|
||||||
"DownloadClientRemovesCompletedDownloadsHealthCheckMessage": "Latauspalvelu {0} on määritetty poistamaan valmistuneet lataukset, jonka seuraksena ne saatetaan poistaa ennen kuin {1} ehtii tuoda niitä.",
|
"DownloadClientRemovesCompletedDownloadsHealthCheckMessage": "Latauspalvelu {0} on määritetty poistamaan valmistuneet lataukset, jonka seuraksena ne saatetaan poistaa ennen kuin {1} ehtii tuoda niitä.",
|
||||||
|
@ -1058,7 +1058,7 @@
|
||||||
"SomeResultsAreHiddenByTheAppliedFilter": "Aktiivinen suodatin piilottaa joitakin tuloksia.",
|
"SomeResultsAreHiddenByTheAppliedFilter": "Aktiivinen suodatin piilottaa joitakin tuloksia.",
|
||||||
"RemotePathMappingCheckFileRemoved": "Tiedosto \"{0}\" poistettiin kesken käsittelyn.",
|
"RemotePathMappingCheckFileRemoved": "Tiedosto \"{0}\" poistettiin kesken käsittelyn.",
|
||||||
"AddListExclusionHelpText": "Estä {appName}ia lisäämästä esittäjää listoilta.",
|
"AddListExclusionHelpText": "Estä {appName}ia lisäämästä esittäjää listoilta.",
|
||||||
"ArtistsEditRootFolderHelpText": "Siirtämällä esittäjät samaan juurikansioon voidaan niiden kansioiden nimet päivittää vastaamaan päivittynyttä nimikettä tai nimeämiskaavaa.",
|
"ArtistsEditRootFolderHelpText": "Siirtämällä esittäjät niiden nykyiseen juurikansioon voidaan niiden kansioiden nimet päivittää vastaamaan päivittynyttä nimikettä tai nimeämiskaavaa.",
|
||||||
"DownloadClientAriaSettingsDirectoryHelpText": "Vaihtoehtoinen latausten tallennussijainti. Käytä Aria2:n oletusta jättämällä tyhjäksi.",
|
"DownloadClientAriaSettingsDirectoryHelpText": "Vaihtoehtoinen latausten tallennussijainti. Käytä Aria2:n oletusta jättämällä tyhjäksi.",
|
||||||
"DeleteArtistFoldersHelpText": "Poista esittäjäkansiot ja niiden kaikki sisältö.",
|
"DeleteArtistFoldersHelpText": "Poista esittäjäkansiot ja niiden kaikki sisältö.",
|
||||||
"ChangeCategoryHint": "Vaihtaa latauksen kategoriaksi latauspalvelun \"Tuonnin jälkeinen kategoria\" -asetuksen kategorian.",
|
"ChangeCategoryHint": "Vaihtaa latauksen kategoriaksi latauspalvelun \"Tuonnin jälkeinen kategoria\" -asetuksen kategorian.",
|
||||||
|
|
|
@ -690,7 +690,7 @@
|
||||||
"ResetDefinitions": "Réinitialiser les définitions",
|
"ResetDefinitions": "Réinitialiser les définitions",
|
||||||
"ResetTitles": "Réinitialiser les titres",
|
"ResetTitles": "Réinitialiser les titres",
|
||||||
"HiddenClickToShow": "Masqué, cliquez pour afficher",
|
"HiddenClickToShow": "Masqué, cliquez pour afficher",
|
||||||
"RemotePathMappingCheckDownloadPermissions": "{appName} peut voir mais ne peut accéder au film téléchargé {0}. Il s'agit probablement d'une erreur de permissions.",
|
"RemotePathMappingCheckDownloadPermissions": "{appName} peut voir mais ne peut accéder au musique téléchargé {0}. Il s'agit probablement d'une erreur de permissions.",
|
||||||
"RemotePathMappingCheckDockerFolderMissing": "Vous utilisez docker ; {0} enregistre les téléchargements dans {1} mais ce dossier n'est pas présent dans ce conteneur. Vérifiez vos paramètres de dossier distant et les paramètres de votre conteneur docker.",
|
"RemotePathMappingCheckDockerFolderMissing": "Vous utilisez docker ; {0} enregistre les téléchargements dans {1} mais ce dossier n'est pas présent dans ce conteneur. Vérifiez vos paramètres de dossier distant et les paramètres de votre conteneur docker.",
|
||||||
"ShownClickToHide": "Affiché, cliquez pour masquer",
|
"ShownClickToHide": "Affiché, cliquez pour masquer",
|
||||||
"ApiKeyValidationHealthCheckMessage": "Veuillez mettre à jour votre clé API pour qu'elle contienne au moins {0} caractères. Vous pouvez le faire via les paramètres ou le fichier de configuration",
|
"ApiKeyValidationHealthCheckMessage": "Veuillez mettre à jour votre clé API pour qu'elle contienne au moins {0} caractères. Vous pouvez le faire via les paramètres ou le fichier de configuration",
|
||||||
|
@ -729,7 +729,7 @@
|
||||||
"RemotePathMappingCheckFilesWrongOSPath": "Le client de téléchargement distant {0} met les téléchargements dans {1} mais il ne s'agit pas d'un chemin {2} valide. Vérifiez les paramètres de votre client de téléchargement.",
|
"RemotePathMappingCheckFilesWrongOSPath": "Le client de téléchargement distant {0} met les téléchargements dans {1} mais il ne s'agit pas d'un chemin {2} valide. Vérifiez les paramètres de votre client de téléchargement.",
|
||||||
"RemotePathMappingCheckFolderPermissions": "{appName} peut voir mais pas accéder au répertoire de téléchargement {0}. Erreur d'autorisations probable.",
|
"RemotePathMappingCheckFolderPermissions": "{appName} peut voir mais pas accéder au répertoire de téléchargement {0}. Erreur d'autorisations probable.",
|
||||||
"RemotePathMappingCheckGenericPermissions": "Le client de téléchargement {0} met les téléchargements dans {1} mais {appName} ne peut voir ce répertoire. Il est possible que vous ayez besoin d'ajuster les permissions de ce dossier.",
|
"RemotePathMappingCheckGenericPermissions": "Le client de téléchargement {0} met les téléchargements dans {1} mais {appName} ne peut voir ce répertoire. Il est possible que vous ayez besoin d'ajuster les permissions de ce dossier.",
|
||||||
"RemotePathMappingCheckImportFailed": "{appName} a échoué en important un Film. Vérifier vos logs pour plus de détails.",
|
"RemotePathMappingCheckImportFailed": "{appName} a échoué en important une musique. Vérifier vos logs pour plus de détails.",
|
||||||
"RemotePathMappingCheckLocalFolderMissing": "Le client de téléchargement distant {0} met les téléchargements dans {1} mais ce chemin ne semble pas exister. Vérifiez vos paramètres de chemins distants.",
|
"RemotePathMappingCheckLocalFolderMissing": "Le client de téléchargement distant {0} met les téléchargements dans {1} mais ce chemin ne semble pas exister. Vérifiez vos paramètres de chemins distants.",
|
||||||
"RemotePathMappingCheckLocalWrongOSPath": "Le client de téléchargement {0} met les téléchargements dans {1} mais il ne s'agit pas d'un chemin {2} valide. Vérifiez les paramètres de votre client de téléchargement.",
|
"RemotePathMappingCheckLocalWrongOSPath": "Le client de téléchargement {0} met les téléchargements dans {1} mais il ne s'agit pas d'un chemin {2} valide. Vérifiez les paramètres de votre client de téléchargement.",
|
||||||
"RemotePathMappingCheckRemoteDownloadClient": "Le client de téléchargement distant {0} met les téléchargements dans {1} mais ce chemin ne semble pas exister. Vérifiez vos paramètres de chemins distants.",
|
"RemotePathMappingCheckRemoteDownloadClient": "Le client de téléchargement distant {0} met les téléchargements dans {1} mais ce chemin ne semble pas exister. Vérifiez vos paramètres de chemins distants.",
|
||||||
|
@ -1350,5 +1350,14 @@
|
||||||
"PendingDownloadClientUnavailable": "En attente – Le client de téléchargement n'est pas disponible",
|
"PendingDownloadClientUnavailable": "En attente – Le client de téléchargement n'est pas disponible",
|
||||||
"UnableToImportAutomatically": "Impossible d'importer automatiquement",
|
"UnableToImportAutomatically": "Impossible d'importer automatiquement",
|
||||||
"WaitingToImport": "En attente d'import",
|
"WaitingToImport": "En attente d'import",
|
||||||
"WaitingToProcess": "En attente de traitement"
|
"WaitingToProcess": "En attente de traitement",
|
||||||
|
"DefaultDelayProfileArtist": "Il s'agit du profil par défaut. Il s'applique à tous les artistes qui n'ont pas de profil explicite.",
|
||||||
|
"DelayProfileArtistTagsHelpText": "S'applique aux artistes avec au moins une balise correspondante",
|
||||||
|
"ICalTagsArtistHelpText": "Le flux ne contiendra que des artistes ayant au moins un tag correspondant",
|
||||||
|
"NoMediumInformation": "Aucune information sur le support n'est disponible.",
|
||||||
|
"DownloadClientSettingsOlderPriorityAlbumHelpText": "Priorité à utiliser lors de la récupération des albums sortis il y a plus de 14 jours",
|
||||||
|
"DownloadClientSettingsRecentPriorityAlbumHelpText": "Priorité à utiliser lors de la récupération des albums sortis au cours des 14 derniers jours",
|
||||||
|
"NotificationsTagsArtistHelpText": "Envoyer des notifications uniquement pour les artistes ayant au moins un tag correspondant",
|
||||||
|
"ReleaseProfileTagArtistHelpText": "Les profils de sortie s'appliqueront aux artistes ayant au moins un tag correspondant. Laisser vide pour appliquer à tous les artistes",
|
||||||
|
"TracksLoadError": "Impossible de charger les pistes"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1061,5 +1061,6 @@
|
||||||
"ImportFailed": "Importazione fallita: {sourceTitle}",
|
"ImportFailed": "Importazione fallita: {sourceTitle}",
|
||||||
"Paused": "In Pausa",
|
"Paused": "In Pausa",
|
||||||
"Pending": "In Attesa",
|
"Pending": "In Attesa",
|
||||||
"UnableToImportAutomatically": "Impossibile Importare Automaticamente"
|
"UnableToImportAutomatically": "Impossibile Importare Automaticamente",
|
||||||
|
"AlbumCount": "Numero album"
|
||||||
}
|
}
|
||||||
|
|
|
@ -286,5 +286,7 @@
|
||||||
"IgnoredPlaceHolder": "Legg til ny begrensning",
|
"IgnoredPlaceHolder": "Legg til ny begrensning",
|
||||||
"AddImportList": "Ny Importliste",
|
"AddImportList": "Ny Importliste",
|
||||||
"AddNewArtistRootFolderHelpText": "Undermappa \"{folder}\" vil bli automatisk laget",
|
"AddNewArtistRootFolderHelpText": "Undermappa \"{folder}\" vil bli automatisk laget",
|
||||||
"CheckDownloadClientForDetails": "sjekk nedlastningsklienten for mer informasjon"
|
"CheckDownloadClientForDetails": "sjekk nedlastningsklienten for mer informasjon",
|
||||||
|
"TBA": "Venter",
|
||||||
|
"History": "Historikk"
|
||||||
}
|
}
|
||||||
|
|
|
@ -595,7 +595,7 @@
|
||||||
"CustomFormatSettings": "Eigen Formaten Instellingen",
|
"CustomFormatSettings": "Eigen Formaten Instellingen",
|
||||||
"CustomFormats": "Eigen Formaten",
|
"CustomFormats": "Eigen Formaten",
|
||||||
"Customformat": "Eigen Formaat",
|
"Customformat": "Eigen Formaat",
|
||||||
"CutoffFormatScoreHelpText": "Wanneer deze eigen formaat score is behaald, zal {appName} niet langer films downloaden",
|
"CutoffFormatScoreHelpText": "Wanneer deze aangepaste formaatscore is behaald, zal {appName} niet langer albumuitgaven downloaden",
|
||||||
"DeleteCustomFormat": "Verwijder Eigen Formaat",
|
"DeleteCustomFormat": "Verwijder Eigen Formaat",
|
||||||
"DeleteCustomFormatMessageText": "Bent u zeker dat u de indexeerder '{0}' wilt verwijderen?",
|
"DeleteCustomFormatMessageText": "Bent u zeker dat u de indexeerder '{0}' wilt verwijderen?",
|
||||||
"DeleteFormatMessageText": "Weet je zeker dat je formaat tag {0} wilt verwijderen?",
|
"DeleteFormatMessageText": "Weet je zeker dat je formaat tag {0} wilt verwijderen?",
|
||||||
|
@ -879,7 +879,7 @@
|
||||||
"BlocklistOnly": "Alleen bloklijst",
|
"BlocklistOnly": "Alleen bloklijst",
|
||||||
"ChangeCategoryHint": "Verandert download naar de 'Post-Import Categorie' van Downloadclient",
|
"ChangeCategoryHint": "Verandert download naar de 'Post-Import Categorie' van Downloadclient",
|
||||||
"ClearBlocklist": "Blokkeerlijst wissen",
|
"ClearBlocklist": "Blokkeerlijst wissen",
|
||||||
"Clone": "Kloon",
|
"Clone": "Dupliceren",
|
||||||
"CustomFormatsSpecificationRegularExpression": "Reguliere expressie",
|
"CustomFormatsSpecificationRegularExpression": "Reguliere expressie",
|
||||||
"CustomFormatsSpecificationRegularExpressionHelpText": "Aangepaste opmaak RegEx is hoofdletterongevoelig",
|
"CustomFormatsSpecificationRegularExpressionHelpText": "Aangepaste opmaak RegEx is hoofdletterongevoelig",
|
||||||
"CustomFormatsSettingsTriggerInfo": "Een Aangepast Formaat wordt toegepast op een uitgave of bestand als het overeenkomt met ten minste één van de verschillende condities die zijn gekozen.",
|
"CustomFormatsSettingsTriggerInfo": "Een Aangepast Formaat wordt toegepast op een uitgave of bestand als het overeenkomt met ten minste één van de verschillende condities die zijn gekozen.",
|
||||||
|
|
|
@ -1031,5 +1031,9 @@
|
||||||
"CheckDownloadClientForDetails": "verifique o cliente de transferências para obter mais detalhes",
|
"CheckDownloadClientForDetails": "verifique o cliente de transferências para obter mais detalhes",
|
||||||
"DownloadWarning": "Alerta de transferência: {warningMessage}",
|
"DownloadWarning": "Alerta de transferência: {warningMessage}",
|
||||||
"Pending": "Pendente",
|
"Pending": "Pendente",
|
||||||
"WaitingToImport": "Aguardando para importar"
|
"WaitingToImport": "Aguardando para importar",
|
||||||
|
"TBA": "TBA",
|
||||||
|
"ThereWasAnErrorLoadingThisItem": "Houve um erro ao carregar este item",
|
||||||
|
"ThereWasAnErrorLoadingThisPage": "Houve um erro ao carregar esta página",
|
||||||
|
"EpisodeDoesNotHaveAnAbsoluteEpisodeNumber": "Episódio não tem um número de episódio absoluto"
|
||||||
}
|
}
|
||||||
|
|
|
@ -834,7 +834,7 @@
|
||||||
"Absolute": "Абсолютный",
|
"Absolute": "Абсолютный",
|
||||||
"RecycleBinUnableToWriteHealthCheck": "Не удается выполнить запись в настроенную папку корзины: {path}. Убедитесь, что этот путь существует и доступен для записи пользователем, запускающим {appName}",
|
"RecycleBinUnableToWriteHealthCheck": "Не удается выполнить запись в настроенную папку корзины: {path}. Убедитесь, что этот путь существует и доступен для записи пользователем, запускающим {appName}",
|
||||||
"AddListExclusionHelpText": "Запретить добавление серий в {appName} по спискам",
|
"AddListExclusionHelpText": "Запретить добавление серий в {appName} по спискам",
|
||||||
"AddNewArtistRootFolderHelpText": "Подпапка \"{0}\" будет создана автоматически",
|
"AddNewArtistRootFolderHelpText": "Подпапка \"{folder}\" будет создана автоматически",
|
||||||
"AuthenticationRequiredHelpText": "Отредактируйте, для каких запросов требуется авторизация. Не изменяйте, если не понимаете риски.",
|
"AuthenticationRequiredHelpText": "Отредактируйте, для каких запросов требуется авторизация. Не изменяйте, если не понимаете риски.",
|
||||||
"DeleteArtistFolderCountConfirmation": "Вы уверены, что хотите удалить {count} выбранных индексатора?",
|
"DeleteArtistFolderCountConfirmation": "Вы уверены, что хотите удалить {count} выбранных индексатора?",
|
||||||
"RenameFiles": "Переименовать файлы",
|
"RenameFiles": "Переименовать файлы",
|
||||||
|
@ -1108,5 +1108,8 @@
|
||||||
"Pending": "В ожидании",
|
"Pending": "В ожидании",
|
||||||
"PendingDownloadClientUnavailable": "Ожидание – Клиент для загрузки недоступен",
|
"PendingDownloadClientUnavailable": "Ожидание – Клиент для загрузки недоступен",
|
||||||
"SkipFreeSpaceCheckHelpText": "Используете, когда {appName} не может верно определить свободное место в вашей корневой папке",
|
"SkipFreeSpaceCheckHelpText": "Используете, когда {appName} не может верно определить свободное место в вашей корневой папке",
|
||||||
"ManageFormats": "Управлять форматами"
|
"ManageFormats": "Управлять форматами",
|
||||||
|
"AddArtistWithName": "Добавить {artistName}",
|
||||||
|
"AddNewAlbum": "Добавить новый альбом",
|
||||||
|
"AddMetadataProfile": "Добавить мета-данные профиля"
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
"BackupRetentionHelpText": "Автоматичні резервні копії, старіші за період зберігання, очищаються автоматично",
|
"BackupRetentionHelpText": "Автоматичні резервні копії, старіші за період зберігання, очищаються автоматично",
|
||||||
"ChmodFolderHelpText": "Восьмеричний, застосовується при імпорті/перейменуванні до медіа-папок та файлів (без бітів виконання)",
|
"ChmodFolderHelpText": "Восьмеричний, застосовується при імпорті/перейменуванні до медіа-папок та файлів (без бітів виконання)",
|
||||||
"CompletedDownloadHandling": "Обробка завершених завантажень",
|
"CompletedDownloadHandling": "Обробка завершених завантажень",
|
||||||
"CopyUsingHardlinksHelpText": "Використання жорстких посилань, коли намагаєтеся скопіювати файли з торентів, які все ще завантажуються",
|
"CopyUsingHardlinksHelpText": "Жорсткі посилання дозволяють {appName} імпортувати торренти, що роздаються, до папки виконавця без зайвого місця на диску або копіювання всього вмісту файлу. Жорсткі посилання працюватимуть лише якщо джерело та призначення знаходяться на одному томі",
|
||||||
"DeleteBackupMessageText": "Ви впевнені, що хочете видалити резервну копію \"{name}\"?",
|
"DeleteBackupMessageText": "Ви впевнені, що хочете видалити резервну копію \"{name}\"?",
|
||||||
"DeleteDownloadClientMessageText": "Ви впевнені, що хочете видалити клієнт завантаження '{name}'?",
|
"DeleteDownloadClientMessageText": "Ви впевнені, що хочете видалити клієнт завантаження '{name}'?",
|
||||||
"AlreadyInYourLibrary": "Вже у вашій бібліотеці",
|
"AlreadyInYourLibrary": "Вже у вашій бібліотеці",
|
||||||
|
@ -55,12 +55,12 @@
|
||||||
"ResetAPIKeyMessageText": "Ви впевнені, що хочете скинути свій ключ API?",
|
"ResetAPIKeyMessageText": "Ви впевнені, що хочете скинути свій ключ API?",
|
||||||
"ShowQualityProfile": "Додати профіль якості",
|
"ShowQualityProfile": "Додати профіль якості",
|
||||||
"AnalyticsEnabledHelpText": "Надсилайте анонімну інформацію про використання та помилки на сервери {appName}. Це включає інформацію про ваш веб-переглядач, які сторінки {appName} WebUI ви використовуєте, звіти про помилки, а також версію ОС і часу виконання. Ми будемо використовувати цю інформацію, щоб визначити пріоритети функцій і виправлення помилок.",
|
"AnalyticsEnabledHelpText": "Надсилайте анонімну інформацію про використання та помилки на сервери {appName}. Це включає інформацію про ваш веб-переглядач, які сторінки {appName} WebUI ви використовуєте, звіти про помилки, а також версію ОС і часу виконання. Ми будемо використовувати цю інформацію, щоб визначити пріоритети функцій і виправлення помилок.",
|
||||||
"DeleteMetadataProfileMessageText": "Ви впевнені, що хочете видалити цей профіль затримки?",
|
"DeleteMetadataProfileMessageText": "Ви впевнені, що хочете видалити профіль метаданих '{name}'",
|
||||||
"DeleteNotificationMessageText": "Ви впевнені, що хочете видалити сповіщення '{name}'?",
|
"DeleteNotificationMessageText": "Ви впевнені, що хочете видалити сповіщення '{name}'?",
|
||||||
"DeleteQualityProfileMessageText": "Ви впевнені, що хочете видалити профіль якості '{name}'?",
|
"DeleteQualityProfileMessageText": "Ви впевнені, що хочете видалити профіль якості '{name}'?",
|
||||||
"DeleteReleaseProfile": "Видалити профіль випуску",
|
"DeleteReleaseProfile": "Видалити профіль випуску",
|
||||||
"DeleteReleaseProfileMessageText": "Ви впевнені, що хочете видалити цей профіль затримки?",
|
"DeleteReleaseProfileMessageText": "Ви впевнені, що хочете видалити цей профіль випуску?",
|
||||||
"DeleteRootFolderMessageText": "Ви впевнені, що хочете видалити тег {0} ?",
|
"DeleteRootFolderMessageText": "Ви впевнені, що хочете видалити кореневу папку '{name}'?",
|
||||||
"DeleteTagMessageText": "Ви впевнені, що хочете видалити тег '{label}'?",
|
"DeleteTagMessageText": "Ви впевнені, що хочете видалити тег '{label}'?",
|
||||||
"IsCutoffCutoff": "Припинення",
|
"IsCutoffCutoff": "Припинення",
|
||||||
"CertificateValidationHelpText": "Змініть суворість перевірки сертифікації HTTPS. Не змінюйте, якщо не розумієте ризики.",
|
"CertificateValidationHelpText": "Змініть суворість перевірки сертифікації HTTPS. Не змінюйте, якщо не розумієте ризики.",
|
||||||
|
@ -470,7 +470,7 @@
|
||||||
"AddImportListExclusion": "Додати виняток до списку імпорту",
|
"AddImportListExclusion": "Додати виняток до списку імпорту",
|
||||||
"AddConnection": "Додати Підключення",
|
"AddConnection": "Додати Підключення",
|
||||||
"AddConnectionImplementation": "Додати Підключення - {implementationName}",
|
"AddConnectionImplementation": "Додати Підключення - {implementationName}",
|
||||||
"Absolute": "Абсолютний",
|
"Absolute": "Загальний",
|
||||||
"AddAutoTag": "Додати Авто Тег",
|
"AddAutoTag": "Додати Авто Тег",
|
||||||
"AddAutoTagError": "Не вдалося додати новий авто тег, спробуйте ще раз.",
|
"AddAutoTagError": "Не вдалося додати новий авто тег, спробуйте ще раз.",
|
||||||
"AddConditionError": "Не вдалося додати нову умову, спробуйте ще раз.",
|
"AddConditionError": "Не вдалося додати нову умову, спробуйте ще раз.",
|
||||||
|
@ -620,7 +620,7 @@
|
||||||
"UnmonitoredHelpText": "Включайте неконтрольовані фільми в канал iCal",
|
"UnmonitoredHelpText": "Включайте неконтрольовані фільми в канал iCal",
|
||||||
"Posters": "Плакати",
|
"Posters": "Плакати",
|
||||||
"Priority": "Пріоритет",
|
"Priority": "Пріоритет",
|
||||||
"RemotePathMappingCheckImportFailed": "{appName} не вдалося імпортувати фільм. Подробиці перевірте у своїх журналах.",
|
"RemotePathMappingCheckImportFailed": "{appName} не вдалося імпортувати музику. Перегляньте журнали для деталей",
|
||||||
"SslPortHelpTextWarning": "Щоб набуло чинності, потрібно перезапустити",
|
"SslPortHelpTextWarning": "Щоб набуло чинності, потрібно перезапустити",
|
||||||
"ApiKeyValidationHealthCheckMessage": "Будь ласка оновіть ключ API, щоб він містив принаймні {length} символів. Ви можете зробити це в налаштуваннях або в файлі конфігурації",
|
"ApiKeyValidationHealthCheckMessage": "Будь ласка оновіть ключ API, щоб він містив принаймні {length} символів. Ви можете зробити це в налаштуваннях або в файлі конфігурації",
|
||||||
"CustomFilter": "Користувацькі фільтри",
|
"CustomFilter": "Користувацькі фільтри",
|
||||||
|
@ -694,7 +694,7 @@
|
||||||
"LongDateFormat": "Довгий формат дати",
|
"LongDateFormat": "Довгий формат дати",
|
||||||
"MaintenanceRelease": "Випуск для обслуговування: виправлення помилок та інші покращення. Щоб отримати докладнішу інформацію, перегляньте історію фіксації Github",
|
"MaintenanceRelease": "Випуск для обслуговування: виправлення помилок та інші покращення. Щоб отримати докладнішу інформацію, перегляньте історію фіксації Github",
|
||||||
"ReleaseDate": "Дати випуску",
|
"ReleaseDate": "Дати випуску",
|
||||||
"RemotePathMappingCheckDownloadPermissions": "{appName} може бачити, але не має доступу до завантаженого фільму {path}. Ймовірна помилка дозволів.",
|
"RemotePathMappingCheckDownloadPermissions": "{appName} бачить, але не має доступу до завантаженої музики{0}. Ймовірно, помилка дозволів.",
|
||||||
"UnableToLoadCustomFormats": "Не вдалося завантажити спеціальні формати",
|
"UnableToLoadCustomFormats": "Не вдалося завантажити спеціальні формати",
|
||||||
"ShownAboveEachColumnWhenWeekIsTheActiveView": "Відображається над кожним стовпцем, коли тиждень є активним переглядом",
|
"ShownAboveEachColumnWhenWeekIsTheActiveView": "Відображається над кожним стовпцем, коли тиждень є активним переглядом",
|
||||||
"Table": "Таблиця",
|
"Table": "Таблиця",
|
||||||
|
@ -923,5 +923,289 @@
|
||||||
"Pending": "В очікуванні",
|
"Pending": "В очікуванні",
|
||||||
"WaitingToImport": "Очікування імпорту",
|
"WaitingToImport": "Очікування імпорту",
|
||||||
"WaitingToProcess": "Очікування обробки",
|
"WaitingToProcess": "Очікування обробки",
|
||||||
"CheckDownloadClientForDetails": "перевірте клієнт завантаження, щоб дізнатися більше"
|
"CheckDownloadClientForDetails": "перевірте клієнт завантаження, щоб дізнатися більше",
|
||||||
|
"DashOrSpaceDashDependingOnName": "Тире або пробіл залежно від імені",
|
||||||
|
"EpisodeDoesNotHaveAnAbsoluteEpisodeNumber": "Епізод не має абсолютного номера епізоду",
|
||||||
|
"ExpandOtherByDefaultHelpText": "Інше",
|
||||||
|
"ImportListTagsHelpText": "Теги, які будуть додані при імпорті з цього списку",
|
||||||
|
"IndexerIdHelpText": "Вкажіть, до якого індексатору застосовується профіль",
|
||||||
|
"IsShowingMonitoredUnmonitorSelected": "Не відстежувати вибрані",
|
||||||
|
"RemoveSelectedItemBlocklistMessageText": "Ви впевнені, що хочете видалити вибрані елементи з чорного списку?",
|
||||||
|
"RootFolderPathHelpText": "Елементи списку кореневих тек будуть додані в",
|
||||||
|
"ThereWasAnErrorLoadingThisItem": "Сталася помилка при завантаженні цього елемента",
|
||||||
|
"ThereWasAnErrorLoadingThisPage": "Сталася помилка під час завантаження цієї сторінки",
|
||||||
|
"AllExpandedExpandAll": "Розгорнути все",
|
||||||
|
"NoMissingItems": "Немає відсутніх елементів",
|
||||||
|
"TBA": "Будь ласка, перевірте пізніше",
|
||||||
|
"IsShowingMonitoredMonitorSelected": "Відстеження вибрано",
|
||||||
|
"SceneNumberHasntBeenVerifiedYet": "Номер сцени ще не перевірено",
|
||||||
|
"EnabledHelpText": "Установіть прапорець, щоб увімкнути профіль релізу",
|
||||||
|
"Loading": "Завантаження",
|
||||||
|
"NoCutoffUnmetItems": "Не має елементів що не досягли порогу",
|
||||||
|
"NotificationsEmbySettingsUpdateLibraryHelpText": "Оновити бібліотеку при імпорті, перейменуванні або видаленні",
|
||||||
|
"NotificationsSettingsUpdateMapPathsFromHelpText": "Шлях {appName}, який використовується для зміни шляхів до серіалів, коли {serviceName} бачить шлях до бібліотеки інакше, ніж {appName} (необхідно 'Оновити бібліотеку')",
|
||||||
|
"NotificationsSettingsUpdateMapPathsToHelpText": "Шлях {serviceName}, що використовується для зміни шляхів до серіалів, коли {serviceName} бачить шлях до бібліотеки інакше, ніж {appName} (потрібно 'Оновити бібліотеку')",
|
||||||
|
"Select...": "Вибрати...",
|
||||||
|
"DeleteSelectedDownloadClients": "Видалити вибрані клієнти завантаження",
|
||||||
|
"DownloadImported": "Завантажено імпортовано",
|
||||||
|
"DownloadedWaitingToImport": "'Завантажено - Очікує імпорту'",
|
||||||
|
"FirstAlbum": "Перший альбом",
|
||||||
|
"FutureAlbumsData": "Відстежувати альбоми, які ще не вийшли",
|
||||||
|
"IsExpandedHideAlbums": "Приховати альбоми",
|
||||||
|
"ManualDownload": "Завантажити вручну",
|
||||||
|
"ArtistIsUnmonitored": "Виконавець не відстежується",
|
||||||
|
"ForeignId": "Зовнішній ідентифікатор",
|
||||||
|
"IndexerIdHelpTextWarning": "Використання певного індексатора з бажаними словами може призвести до завантаження дублікатів релізів",
|
||||||
|
"ArtistsEditRootFolderHelpText": "Переміщення виконавців до однієї кореневої папки може використовуватися для перейменування папок виконавців відповідно до оновленого імені або формату найменування",
|
||||||
|
"AllowFingerprintingHelpText": "Використовувати створення аудіовідбитків для покращення точності зіставлення треків",
|
||||||
|
"CollapseMultipleAlbumsHelpText": "Згорнути кілька альбомів, що виходять в один день",
|
||||||
|
"ContinuingNoAdditionalAlbumsAreExpected": "Додаткових альбомів не очікується",
|
||||||
|
"DownloadClientSortingCheckMessage": "Для клієнта завантаження {0} увімкнено сортування для категорії {appName}. Вам слід вимкнути сортування у вашому клієнті завантаження, щоб уникнути проблем з імпортом",
|
||||||
|
"AnchorTooltip": "Цей файл вже є у вашій бібліотеці для релізу, який ви зараз імпортуєте",
|
||||||
|
"CollapseMultipleAlbums": "Згорнути кілька альбомів",
|
||||||
|
"ExpandEPByDefaultHelpText": "EP (міні-альбоми)",
|
||||||
|
"ForNewImportsOnly": "Лише для нових імпортів",
|
||||||
|
"MetadataProfile": "Профіль метаданих",
|
||||||
|
"EditMetadataProfile": "Редагувати профіль метаданих",
|
||||||
|
"EmbedCoverArtHelpText": "Вбудовувати обкладинку альбому Lidarr у аудіофайли під час запису тегів",
|
||||||
|
"AreYouSure": "Ви впевнені?",
|
||||||
|
"DelayProfileArtistTagsHelpText": "Застосовується до виконавців, які мають хоча б один відповідний тег",
|
||||||
|
"FilterArtistPlaceholder": "Фільтрувати виконавця",
|
||||||
|
"HasMonitoredAlbumsNoMonitoredAlbumsForThisArtist": "Для цього виконавця немає жодних альбомів, що відстежуються",
|
||||||
|
"IsExpandedHideFileInfo": "Приховати інформацію про файл",
|
||||||
|
"ArtistIsMonitored": "Виконавець відстежується",
|
||||||
|
"CustomFormatRequiredHelpText": "Ця {0}-а умова повинна збігатися, щоб застосувався власний формат. Інакше достатньо одного {0}-го збігу",
|
||||||
|
"ICalTagsArtistHelpText": "Стрічка міститиме лише виконавців, які мають хоча б один відповідний тег",
|
||||||
|
"MetadataConsumers": "Споживачі метаданих",
|
||||||
|
"ArtistNameHelpText": "Назва виконавця/альбому, який потрібно виключити (може бути будь-якою значущою)",
|
||||||
|
"DefaultMonitorOptionHelpText": "Які альбоми слід відстежувати при початковому додаванні для виконавців, виявлених у цій папці",
|
||||||
|
"ExistingAlbums": "Існуючі альбоми",
|
||||||
|
"IfYouDontAddAnImportListExclusionAndTheArtistHasAMetadataProfileOtherThanNoneThenThisAlbumMayBeReaddedDuringTheNextArtistRefresh": "Якщо ви не додасте виключення зі списку імпорту, і виконавець матиме профіль метаданих, відмінний від \"Немає\", цей альбом може бути повторно додано під час наступного оновлення виконавця",
|
||||||
|
"IsInUseCantDeleteAQualityProfileThatIsAttachedToAnArtistOrImportList": "Неможливо видалити профіль якості, який пов'язаний з виконавцем або списком імпорту",
|
||||||
|
"DeleteMetadataProfile": "Видалити профіль метаданих",
|
||||||
|
"DownloadClientRemovesCompletedDownloadsHealthCheckMessage": "Для клієнта завантаження {0} налаштовано видалення завершених завантажень. Це може призвести до видалення завантажень з вашого клієнта до того, як {1} зможе їх імпортувати",
|
||||||
|
"ForeignIdHelpText": "Ідентифікатор MusicBrainz виконавця/альбому, який потрібно виключити",
|
||||||
|
"MassAlbumsCutoffUnmetWarning": "Ви впевнені, що хочете виконати пошук для всіх альбомів, де не досягнуто порогового значення '{0}'?",
|
||||||
|
"IsExpandedShowAlbums": "Показати альбоми",
|
||||||
|
"IsInUseCantDeleteAMetadataProfileThatIsAttachedToAnArtistOrImportList": "Неможливо видалити профіль метаданих, який пов'язаний з виконавцем або списком імпорту",
|
||||||
|
"MetadataSettingsArtistSummary": "Створювати файли метаданих під час імпорту треків або оновлення інформації про виконавця",
|
||||||
|
"MissingAlbumsData": "Відстежувати альбоми, які не мають файлів або ще не вийшли",
|
||||||
|
"MissingTracksArtistNotMonitored": "Відсутні треки (виконавець не відстежується)",
|
||||||
|
"MonitorAlbumExistingOnlyWarning": "Це одноразове коригування налаштування відстеження для кожного альбому. Використовуйте опцію в розділі \"Виконавець/Редагувати\", щоб контролювати, що відбуватиметься з новими доданими альбомами",
|
||||||
|
"FutureDaysHelpText": "Днів для перегляду майбутніх подій у стрічці iCal",
|
||||||
|
"CountImportListsSelected": "Вибрано {selectedCount} списків імпорту",
|
||||||
|
"DateAdded": "Дата додавання",
|
||||||
|
"MissingAlbums": "Відсутні альбоми",
|
||||||
|
"DeleteTrackFile": "Видалити файл треку",
|
||||||
|
"MonitorFutureAlbums": "Майбутні альбоми",
|
||||||
|
"MonitorLastestAlbum": "Останній альбом",
|
||||||
|
"MonitorMissingAlbums": "Відсутні альбоми",
|
||||||
|
"MonitorNewAlbums": "Нові альбоми",
|
||||||
|
"MonitorNewItemsHelpText": "Які нові альбоми слід відстежувати",
|
||||||
|
"MultiDiscTrackFormat": "Формат треків на кількох дисках",
|
||||||
|
"CombineWithExistingFiles": "Об'єднати з існуючими файлами",
|
||||||
|
"ContinuingAllTracksDownloaded": "Продовжити (Усі треки завантажено)",
|
||||||
|
"ContinuingMoreAlbumsAreExpected": "Очікуються інші альбоми",
|
||||||
|
"CountAlbums": "{albumCount} альбомів",
|
||||||
|
"CountIndexersSelected": "Вибрано {selectedCount} індексаторів",
|
||||||
|
"Country": "Країна",
|
||||||
|
"Deceased": "Помер(ла)",
|
||||||
|
"DefaultDelayProfileArtist": "Це профіль за замовчуванням. Він застосовується до всіх виконавців, які не мають явного профілю.",
|
||||||
|
"DefaultLidarrTags": "Теги {appName} за замовчуванням",
|
||||||
|
"DefaultMetadataProfileIdHelpText": "Профіль метаданих за замовчуванням для виконавців, виявлених у цій папці",
|
||||||
|
"DefaultQualityProfileIdHelpText": "Профіль якості за замовчуванням для виконавців, виявлених у цій папці",
|
||||||
|
"DefaultTagsHelpText": "Теги {appName} за замовчуванням для виконавців, виявлених у цій папці",
|
||||||
|
"DeleteArtist": "Видалити вибраного виконавця",
|
||||||
|
"DeleteArtistFolder": "Видалити папку виконавця",
|
||||||
|
"DeleteArtistFolders": "Видалити папки виконавців",
|
||||||
|
"DeleteFilesHelpText": "Видалити файли треків та папку виконавця",
|
||||||
|
"DeleteFormat": "Видалити формат",
|
||||||
|
"DeleteSelectedArtists": "Видалити вибраних виконавців",
|
||||||
|
"Discography": "Дискографія",
|
||||||
|
"DownloadClientSettingsRecentPriorityAlbumHelpText": "Пріоритет, який використовуватиметься при завантаженні альбомів, випущених протягом останніх 14 днів",
|
||||||
|
"DownloadPropersAndRepacksHelpTexts2": "Використовуйте \"Не надавати перевагу\", щоб сортувати за оцінкою бажаного слова, а не за належними назвами/перепакуваннями",
|
||||||
|
"DownloadedImporting": "'Завантажено - Імпортується'",
|
||||||
|
"DownloadedUnableToImportCheckLogsForDetails": "'Завантажено - Неможливо імпортувати: деталі дивіться в журналах'",
|
||||||
|
"EditArtist": "Редагувати виконавця",
|
||||||
|
"EditMetadata": "Редагувати метадані",
|
||||||
|
"EditSelectedArtists": "Редагувати вибраних виконавців",
|
||||||
|
"EmbedCoverArtInAudioFiles": "Вбудувати обкладинку в аудіофайли",
|
||||||
|
"EnableAutomaticAddHelpText": "Додавати виконавців/альбоми до {appName} під час синхронізації через інтерфейс користувача або {appName}",
|
||||||
|
"EndedAllTracksDownloaded": "Закінчено (Усі треки завантажено)",
|
||||||
|
"EntityName": "Назва сутності",
|
||||||
|
"ExistingAlbumsData": "Відстежувати альбоми, які мають файли або ще не вийшли",
|
||||||
|
"ExistingTagsScrubbed": "Наявні теги очищено",
|
||||||
|
"ExpandBroadcastByDefaultHelpText": "Трансляція",
|
||||||
|
"ExpandItemsByDefault": "Розгорнути елементи за замовчуванням",
|
||||||
|
"ExpandSingleByDefaultHelpText": "Сингли",
|
||||||
|
"FilterAlbumPlaceholder": "Фільтрувати альбом",
|
||||||
|
"FirstAlbumData": "Відстежувати перші альбоми. Усі інші альбоми буде проігноровано",
|
||||||
|
"FutureAlbums": "Майбутні альбоми",
|
||||||
|
"FutureDays": "Майбутні дні",
|
||||||
|
"GoToArtistListing": "Перейти до списку виконавців",
|
||||||
|
"GroupInformation": "Інформація про групу",
|
||||||
|
"HideAlbums": "Приховати альбоми",
|
||||||
|
"HideTracks": "Приховати треки",
|
||||||
|
"ImportCompleteFailed": "Імпорт не вдався",
|
||||||
|
"ImportFailures": "Збої імпорту",
|
||||||
|
"ImportListSettings": "Загальні налаштування списку імпорту",
|
||||||
|
"ImportListSpecificSettings": "Специфічні налаштування списку імпорту",
|
||||||
|
"Inactive": "Неактивний",
|
||||||
|
"IndexerDownloadClientHealthCheckMessage": "Індексатори з недійсними клієнтами завантаження: {0}.",
|
||||||
|
"IsExpandedShowFileInfo": "Показати інформацію про файл",
|
||||||
|
"IsExpandedShowTracks": "Показати треки",
|
||||||
|
"LastAlbum": "Останній альбом",
|
||||||
|
"LatestAlbum": "Найновіший альбом",
|
||||||
|
"LatestAlbumData": "Відстежувати останні та майбутні альбоми",
|
||||||
|
"LidarrSupportsMultipleListsForImportingAlbumsAndArtistsIntoTheDatabase": "{appName} підтримує кілька списків для імпорту альбомів та виконавців до бази даних",
|
||||||
|
"ListWillRefreshEveryInterp": "Список оновлюватиметься кожні {0}",
|
||||||
|
"MatchedToAlbums": "Збіги з альбомами",
|
||||||
|
"MatchedToArtist": "Збіги з виконавцем",
|
||||||
|
"MediaCount": "Кількість медіафайлів",
|
||||||
|
"MediumFormat": "Формат носія",
|
||||||
|
"MetadataProfileIdHelpText": "Елементи списку профілю метаданих слід додавати з",
|
||||||
|
"MetadataProfiles": "Профілі метаданих",
|
||||||
|
"MonitorAlbum": "Відстежувати альбом",
|
||||||
|
"MonitorArtist": "Відстежувати виконавця",
|
||||||
|
"MonitorArtists": "Відстежувати виконавців",
|
||||||
|
"MonitorExistingAlbums": "Наявні альбоми",
|
||||||
|
"MonitorFirstAlbum": "Перший альбом",
|
||||||
|
"MonitorNoNewAlbums": "Немає нових альбомів",
|
||||||
|
"MonitoredHelpText": "Завантажити відстежувані альбоми цього виконавця",
|
||||||
|
"MonitoringOptionsHelpText": "Які альбоми слід відстежувати після додавання виконавця (одноразове налаштування)",
|
||||||
|
"DownloadClientSettingsOlderPriorityAlbumHelpText": "Пріоритет, який використовуватиметься при завантаженні альбомів, випущених понад 14 днів тому",
|
||||||
|
"MissingTracks": "Відсутні треки",
|
||||||
|
"MissingTracksArtistMonitored": "Відсутні треки (виконавець відстежується)",
|
||||||
|
"AddMetadataProfile": "Додати профіль метаданих",
|
||||||
|
"AddedArtistSettings": "Додано налаштування артиста",
|
||||||
|
"AlbumCount": "Кількість альбомів",
|
||||||
|
"AlbumHasNotAired": "Альбом не був випущений",
|
||||||
|
"AlbumInfo": "Інформація про альбом",
|
||||||
|
"AlbumIsNotMonitored": "Альбом не моніториться",
|
||||||
|
"AlbumRelease": "Випуск альбому",
|
||||||
|
"AlbumStudio": "Студійний альбом",
|
||||||
|
"AllArtistAlbums": "Усі альбоми виконавця",
|
||||||
|
"AllMonitoringOptionHelpText": "Відстежувати виконавців та всі альбоми кожного виконавця, включеного до списку імпорту",
|
||||||
|
"AllowArtistChangeClickToChangeArtist": "Натисніть, щоб змінити виконавця",
|
||||||
|
"AllowFingerprinting": "Дозволити створення аудіовідбитків",
|
||||||
|
"AllowFingerprintingHelpTextWarning": "Для цього програмі 1 {appName} потрібно зчитати частини файлу, що сповільнить сканування та може спричинити високу активність диска або мережі",
|
||||||
|
"AnyReleaseOkHelpText": "{appName} автоматично перемкнеться на реліз, який найкраще відповідає завантаженим трекам",
|
||||||
|
"ArtistClickToChangeAlbum": "Натисніть, щоб змінити альбом",
|
||||||
|
"ArtistEditor": "Редактор виконавця",
|
||||||
|
"ArtistFolderFormat": "Формат папки виконавця",
|
||||||
|
"ArtistProgressBarText": "Завантажено файлів: {trackFileCount} / Всього треків у файлах: {trackCount} (Всього треків у релізі: {totalTrackCount}, Завантажується треків: {downloadingCount})",
|
||||||
|
"AutomaticallySwitchRelease": "Автоматично вибирати реліз",
|
||||||
|
"BannerOptions": "Параметри банера",
|
||||||
|
"Banners": "Банери",
|
||||||
|
"CatalogNumber": "Каталожний номер",
|
||||||
|
"Disambiguation": "Розрізнення",
|
||||||
|
"DiscCount": "Кількість дисків",
|
||||||
|
"DiscNumber": "Номер диску",
|
||||||
|
"IsExpandedHideTracks": "Приховати треки",
|
||||||
|
"ManageTracks": "Керувати треками",
|
||||||
|
"ScrubExistingTags": "Очистити існуючі теги",
|
||||||
|
"PathHelpText": "Коренева папка, що містить вашу музичну бібліотеку",
|
||||||
|
"RecycleBinUnableToWriteHealthCheck": "Не вдається записати до налаштованої папки кошика: {0}. Переконайтеся, що цей шлях існує і доступний для запису користувачем, який запустив {appName}",
|
||||||
|
"SelectArtist": "Вибрати виконавця",
|
||||||
|
"ShowNextAlbumHelpText": "Показувати наступний альбом під постером",
|
||||||
|
"ShouldMonitorExistingHelpText": "Автоматично відстежувати альбоми зі цього списку, які вже є в {appName}",
|
||||||
|
"UnableToLoadInteractiveSearch": "Не вдалося завантажити результати для цього пошуку альбому. Спробуйте пізніше",
|
||||||
|
"SpecificMonitoringOptionHelpText": "Відстежувати виконавців, але відстежувати лише альбоми, явно включені до списку",
|
||||||
|
"SearchForAllMissingAlbumsConfirmationCount": "Ви впевнені, що хочете шукати всі {totalRecords} відсутніх альбомів?",
|
||||||
|
"NoHistoryBlocklist": "Немає історії заблокованих елементів",
|
||||||
|
"QualityProfileIdHelpText": "Елементи списку профілів якості слід додавати за допомогою",
|
||||||
|
"ShouldSearchHelpText": "Пошук в індексаторах нових доданих елементів. Обережно використовуйте для великих списків.",
|
||||||
|
"NotificationsEmbySettingsSendNotificationsHelpText": "Відправляти сповіщення MediaBrowser на налаштовані провайдери",
|
||||||
|
"TrackFileRenamedTooltip": "Файл треку перейменовано",
|
||||||
|
"TrackMissingFromDisk": "Трек відсутній на диску",
|
||||||
|
"WatchLibraryForChangesHelpText": "Автоматично сканувати при зміні файлів у кореневій папці",
|
||||||
|
"MonitorNewItems": "Відстежувати нові альбоми",
|
||||||
|
"ReleaseProfileTagArtistHelpText": "Профілі випуску застосовуватимуться до виконавців, які мають хоча б один відповідний тег. Залиште порожнім, щоб застосувати до всіх виконавців",
|
||||||
|
"ReplaceExistingFiles": "Замінити існуючі файли",
|
||||||
|
"Retag": "Перетегувати",
|
||||||
|
"Retagged": "Перетеговано",
|
||||||
|
"TotalTrackCountTracksTotalTrackFileCountTracksWithFilesInterp": "Всього {0} треків. {1} треків з файлами.",
|
||||||
|
"UnableToLoadMetadataProviderSettings": "Не вдалося завантажити налаштування постачальника метаданих",
|
||||||
|
"RenameTracks": "Перейменувати треки",
|
||||||
|
"NoMediumInformation": "Інформація про носій недоступна",
|
||||||
|
"NotificationsTagsArtistHelpText": "Надсилати сповіщення лише для виконавців, які мають хоча б один відповідний тег",
|
||||||
|
"OnArtistAdd": "При додаванні виконавця",
|
||||||
|
"OnArtistDelete": "При видаленні виконавця",
|
||||||
|
"OnImportFailure": "При помилці імпорту",
|
||||||
|
"OneAlbum": "1 альбом",
|
||||||
|
"PastDays": "Минулі дні",
|
||||||
|
"PastDaysHelpText": "Кількість днів для перегляду минулих подій у фіді iCa",
|
||||||
|
"Playlist": "Плейлист",
|
||||||
|
"ProfilesSettingsArtistSummary": "Якість, метадані, затримка та профілі випуску",
|
||||||
|
"RetagSelectedArtists": "Перетегувати вибраних виконавців",
|
||||||
|
"SearchBoxPlaceHolder": "напр., Breaking Benjamin, lidarr:854a1807-025b-42a8-ba8c-2a39717f1d25",
|
||||||
|
"SearchForAllCutoffUnmetAlbums": "Пошук усіх альбомів, які не відповідають критерію відсікання",
|
||||||
|
"SecondaryAlbumTypes": "Другорядні типи альбомів",
|
||||||
|
"SecondaryTypes": "Другорядні типи",
|
||||||
|
"ShouldMonitorExisting": "Відстежувати існуючі альбоми",
|
||||||
|
"ShowBannersHelpText": "Показувати банери замість назв",
|
||||||
|
"SkipRedownloadHelpText": "Запобігає спробам {appName} завантажувати альтернативні випуски для видалених елементів.",
|
||||||
|
"ReleasesHelpText": "Змінити випуск для цього альбому",
|
||||||
|
"MusicBrainzAlbumID": "MusicBrainz Альбом ID",
|
||||||
|
"MusicBrainzArtistID": "MusicBrainz викаонавець ID",
|
||||||
|
"NoTracksInThisMedium": "На цьому носії немає треків",
|
||||||
|
"OnReleaseImport": "При імпорті релізу",
|
||||||
|
"SearchForAllCutoffUnmetAlbumsConfirmationCount": "Ви впевнені, що хочете шукати всі {totalRecords} альбомів, які не відповідають критерію відсікання?",
|
||||||
|
"SelectTracks": "Вибрати треки",
|
||||||
|
"TrackArtist": "Виконавець треку",
|
||||||
|
"TrackCount": "Кількість треків",
|
||||||
|
"TrackDownloaded": "Трек завантажено",
|
||||||
|
"TrackFileCounttotalTrackCountTracksDownloadedInterp": "Завантажено {0} з {1} треків",
|
||||||
|
"WriteMetadataToAudioFiles": "Записувати метадані до аудіофайлів",
|
||||||
|
"WriteAudioTagsHelpTextWarning": "Вибір \"Усі файли\" змінить існуючі файли під час їх імпорту.",
|
||||||
|
"WriteMetadataTags": "Записати теги метаданих",
|
||||||
|
"MusicBrainzRecordingID": "MusicBrainz запису ID",
|
||||||
|
"MusicBrainzReleaseID": "MusicBrainz релізу ID",
|
||||||
|
"MusicBrainzTrackID": "MusicBrainz Track ID",
|
||||||
|
"MusicbrainzId": "Musicbrainz Id",
|
||||||
|
"NewAlbums": "Нові альбоми",
|
||||||
|
"NextAlbum": "Наступний альбом",
|
||||||
|
"NoAlbums": "Немає альбомів",
|
||||||
|
"NoneData": "Жоден альбом не буде відстежуватися",
|
||||||
|
"NoneMonitoringOptionHelpText": "Не відстежувати виконавців або альбоми",
|
||||||
|
"NotDiscography": "Не дискографія",
|
||||||
|
"OnAlbumDelete": "При видаленні альбому",
|
||||||
|
"OnDownloadFailure": "При помилці завантаження",
|
||||||
|
"OnTrackRetag": "При перетегуванні треку",
|
||||||
|
"PathHelpTextWarning": "Це має відрізнятися від каталогу, куди ваш клієнт завантажує файли",
|
||||||
|
"PreviewRetag": "Попередній перегляд перетегування",
|
||||||
|
"PrimaryAlbumTypes": "Основні типи альбомів",
|
||||||
|
"PrimaryTypes": "Основні типи",
|
||||||
|
"Proceed": "Продовжити",
|
||||||
|
"RefreshArtist": "Оновити виконавця",
|
||||||
|
"ScrubAudioTagsHelpText": "Видалити існуючі теги з файлів, залишивши лише ті, що додані {appName}.",
|
||||||
|
"SearchAlbum": "Пошук альбому",
|
||||||
|
"SearchForAllMissingAlbums": "Пошук усіх відсутніх альбомів",
|
||||||
|
"SearchForMonitoredAlbums": "Пошук відстежуваних альбомів",
|
||||||
|
"SelectAlbum": "Вибрати альбом",
|
||||||
|
"SelectAlbumRelease": "Вибрати випуск альбому",
|
||||||
|
"SelectedCountArtistsSelectedInterp": "Вибрано {selectedCount} виконавця(ів)",
|
||||||
|
"SetAppTags": "Встановити теги {appName}.",
|
||||||
|
"ShouldMonitorHelpText": "Відстежувати виконавців та альбоми, додані з цього списку",
|
||||||
|
"ShouldSearch": "Пошук нових елементів",
|
||||||
|
"ShowAlbumCount": "Показати кількість альбомів",
|
||||||
|
"ShowLastAlbum": "Показати останній альбом",
|
||||||
|
"ShowName": "Показати назву",
|
||||||
|
"ShowNextAlbum": "Показати наступний альбом",
|
||||||
|
"ShowTitleHelpText": "Показувати ім'я виконавця під постером",
|
||||||
|
"SpecificAlbum": "Конкретний альбом",
|
||||||
|
"TagAudioFilesWithMetadata": "Тегувати аудіофайли метаданими",
|
||||||
|
"TheAlbumsFilesWillBeDeleted": "Файли альбому буде видалено",
|
||||||
|
"TrackFileDeletedTooltip": "Файл треку видалено",
|
||||||
|
"TrackFileMissingTooltip": "Файл треку відсутній",
|
||||||
|
"TrackFileTagsUpdatedTooltip": "Теги файлу треку оновлено",
|
||||||
|
"TrackFiles": "Файли треків",
|
||||||
|
"TrackFilesLoadError": "Не вдалося завантажити файли треків",
|
||||||
|
"TrackImported": "Трек імпортовано",
|
||||||
|
"TrackNaming": "Іменування треків",
|
||||||
|
"TrackProgress": "Прогрес треку",
|
||||||
|
"TrackStatus": "Статус треку",
|
||||||
|
"TracksLoadError": "Не вдалося завантажити треки",
|
||||||
|
"UpdatingIsDisabledInsideADockerContainerUpdateTheContainerImageInstead": "Оновлення вимкнено всередині контейнера Docker. Оновіть образ контейнера.",
|
||||||
|
"WatchRootFoldersForFileChanges": "Слідкувати за змінами файлів у кореневих папках"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1337,7 +1337,7 @@
|
||||||
"DownloadClientSettingsRecentPriority": "最近优先",
|
"DownloadClientSettingsRecentPriority": "最近优先",
|
||||||
"PostImportCategory": "导入后分类",
|
"PostImportCategory": "导入后分类",
|
||||||
"NotificationsSettingsWebhookHeaders": "标头",
|
"NotificationsSettingsWebhookHeaders": "标头",
|
||||||
"DefaultDelayProfileArtist": "This is the default profile. It applies to all artists that don't have an explicit profile.",
|
"DefaultDelayProfileArtist": "这是默认的配置。此配置用于所有的没有配置的艺术家",
|
||||||
"CheckDownloadClientForDetails": "查看下载客户端了解更多详细信息",
|
"CheckDownloadClientForDetails": "查看下载客户端了解更多详细信息",
|
||||||
"DownloadWarning": "下载警告:{warningMessage}",
|
"DownloadWarning": "下载警告:{warningMessage}",
|
||||||
"UnableToImportAutomatically": "无法自动导入",
|
"UnableToImportAutomatically": "无法自动导入",
|
||||||
|
@ -1347,5 +1347,9 @@
|
||||||
"Pending": "挂起",
|
"Pending": "挂起",
|
||||||
"PendingDownloadClientUnavailable": "挂起 - 下载客户端不可用",
|
"PendingDownloadClientUnavailable": "挂起 - 下载客户端不可用",
|
||||||
"WaitingToImport": "等待导入",
|
"WaitingToImport": "等待导入",
|
||||||
"WaitingToProcess": "等待处理"
|
"WaitingToProcess": "等待处理",
|
||||||
|
"DelayProfileArtistTagsHelpText": "应用到至少有一个标签匹配的艺术家",
|
||||||
|
"AlbumInfo": "专辑 信息",
|
||||||
|
"DownloadClientSettingsOlderPriorityAlbumHelpText": "优先使用14天前发布的专辑",
|
||||||
|
"DownloadClientSettingsRecentPriorityAlbumHelpText": "优先使用过去14天内发布的专辑"
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,5 +4,9 @@
|
||||||
"Always": "总是",
|
"Always": "总是",
|
||||||
"Analytics": "分析",
|
"Analytics": "分析",
|
||||||
"Username": "用户名",
|
"Username": "用户名",
|
||||||
"Activity": "活动"
|
"Activity": "活动",
|
||||||
|
"UseProxy": "使用代理",
|
||||||
|
"Uptime": "运行时间",
|
||||||
|
"Warn": "警告",
|
||||||
|
"Updates": "更新"
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,6 +65,10 @@ namespace NzbDrone.Core.MediaFiles
|
||||||
_logger.Debug("Removing existing track file: {0}", file);
|
_logger.Debug("Removing existing track file: {0}", file);
|
||||||
_recycleBinProvider.DeleteFile(trackFilePath, subfolder);
|
_recycleBinProvider.DeleteFile(trackFilePath, subfolder);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_logger.Warn("Existing track file missing from disk: {0}", trackFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
moveFileResult.OldFiles.Add(file);
|
moveFileResult.OldFiles.Add(file);
|
||||||
_mediaFileService.Delete(file, DeleteMediaFileReason.Upgrade);
|
_mediaFileService.Delete(file, DeleteMediaFileReason.Upgrade);
|
||||||
|
|
|
@ -19,26 +19,34 @@ namespace NzbDrone.Core.Music
|
||||||
|
|
||||||
public bool ShouldRefresh(Album album)
|
public bool ShouldRefresh(Album album)
|
||||||
{
|
{
|
||||||
if (album.LastInfoSync < DateTime.UtcNow.AddDays(-60))
|
try
|
||||||
{
|
{
|
||||||
_logger.Trace("Album {0} last updated more than 60 days ago, should refresh.", album.Title);
|
if (album.LastInfoSync < DateTime.UtcNow.AddDays(-60))
|
||||||
return true;
|
{
|
||||||
}
|
_logger.Trace("Album {0} last updated more than 60 days ago, should refresh.", album.Title);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (album.LastInfoSync >= DateTime.UtcNow.AddHours(-12))
|
if (album.LastInfoSync >= DateTime.UtcNow.AddHours(-12))
|
||||||
{
|
{
|
||||||
_logger.Trace("Album {0} last updated less than 12 hours ago, should not be refreshed.", album.Title);
|
_logger.Trace("Album {0} last updated less than 12 hours ago, should not be refreshed.", album.Title);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (album.ReleaseDate > DateTime.UtcNow.AddDays(-30))
|
||||||
|
{
|
||||||
|
_logger.Trace("album {0} released less than 30 days ago, should refresh.", album.Title);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
_logger.Trace("Album {0} released long ago and recently refreshed, should not be refreshed.", album.Title);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
catch (Exception e)
|
||||||
if (album.ReleaseDate > DateTime.UtcNow.AddDays(-30))
|
|
||||||
{
|
{
|
||||||
_logger.Trace("album {0} released less than 30 days ago, should refresh.", album.Title);
|
_logger.Error(e, "Unable to determine if album should refresh, will try to refresh.");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
_logger.Trace("Album {0} released long ago and recently refreshed, should not be refreshed.", album.Title);
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,40 +22,48 @@ namespace NzbDrone.Core.Music
|
||||||
|
|
||||||
public bool ShouldRefresh(Artist artist)
|
public bool ShouldRefresh(Artist artist)
|
||||||
{
|
{
|
||||||
if (artist.LastInfoSync == null)
|
try
|
||||||
{
|
{
|
||||||
_logger.Trace("Artist {0} was just added, should refresh.", artist.Name);
|
if (artist.LastInfoSync == null)
|
||||||
return true;
|
{
|
||||||
}
|
_logger.Trace("Artist {0} was just added, should refresh.", artist.Name);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (artist.LastInfoSync < DateTime.UtcNow.AddDays(-30))
|
if (artist.LastInfoSync < DateTime.UtcNow.AddDays(-30))
|
||||||
{
|
{
|
||||||
_logger.Trace("Artist {0} last updated more than 30 days ago, should refresh.", artist.Name);
|
_logger.Trace("Artist {0} last updated more than 30 days ago, should refresh.", artist.Name);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (artist.LastInfoSync >= DateTime.UtcNow.AddHours(-12))
|
if (artist.LastInfoSync >= DateTime.UtcNow.AddHours(-12))
|
||||||
{
|
{
|
||||||
_logger.Trace("Artist {0} last updated less than 12 hours ago, should not be refreshed.", artist.Name);
|
_logger.Trace("Artist {0} last updated less than 12 hours ago, should not be refreshed.", artist.Name);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (artist.Metadata.Value.Status == ArtistStatusType.Continuing && artist.LastInfoSync < DateTime.UtcNow.AddDays(-2))
|
||||||
|
{
|
||||||
|
_logger.Trace("Artist {0} is continuing and has not been refreshed in 2 days, should refresh.", artist.Name);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
var lastAlbum = _albumService.GetAlbumsByArtist(artist.Id).MaxBy(e => e.ReleaseDate);
|
||||||
|
|
||||||
|
if (lastAlbum != null && lastAlbum.ReleaseDate > DateTime.UtcNow.AddDays(-30))
|
||||||
|
{
|
||||||
|
_logger.Trace("Last album in {0} aired less than 30 days ago, should refresh.", artist.Name);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
_logger.Trace("Artist {0} ended long ago, should not be refreshed.", artist.Name);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
catch (Exception e)
|
||||||
if (artist.Metadata.Value.Status == ArtistStatusType.Continuing && artist.LastInfoSync < DateTime.UtcNow.AddDays(-2))
|
|
||||||
{
|
{
|
||||||
_logger.Trace("Artist {0} is continuing and has not been refreshed in 2 days, should refresh.", artist.Name);
|
_logger.Error(e, "Unable to determine if artist should refresh, will try to refresh.");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
var lastAlbum = _albumService.GetAlbumsByArtist(artist.Id).MaxBy(e => e.ReleaseDate);
|
|
||||||
|
|
||||||
if (lastAlbum != null && lastAlbum.ReleaseDate > DateTime.UtcNow.AddDays(-30))
|
|
||||||
{
|
|
||||||
_logger.Trace("Last album in {0} aired less than 30 days ago, should refresh.", artist.Name);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
_logger.Trace("Artist {0} ended long ago, should not be refreshed.", artist.Name);
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -347,7 +347,7 @@ namespace NzbDrone.Core.Notifications.CustomScript
|
||||||
{
|
{
|
||||||
if (artist == null)
|
if (artist == null)
|
||||||
{
|
{
|
||||||
return null;
|
return new List<string>();
|
||||||
}
|
}
|
||||||
|
|
||||||
return _tagRepository.GetTags(artist.Tags)
|
return _tagRepository.GetTags(artist.Tags)
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue