Compare commits

..

No commits in common. "develop" and "v2.10.1.4589" have entirely different histories.

139 changed files with 396 additions and 1491 deletions

View file

@ -60,7 +60,6 @@ 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
View file

@ -158,12 +158,34 @@ 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/

View file

@ -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.13.1' majorVersion: '2.10.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-22.04' linuxImage: 'ubuntu-20.04'
macImage: 'macOS-13' macImage: 'macOS-13'
trigger: trigger:

View file

@ -188,7 +188,7 @@ module.exports = (env) => {
loose: true, loose: true,
debug: false, debug: false,
useBuiltIns: 'entry', useBuiltIns: 'entry',
corejs: '3.41' corejs: '3.39'
} }
] ]
] ]

View file

@ -172,8 +172,7 @@ function HistoryDetails(props) {
if (eventType === 'downloadFailed') { if (eventType === 'downloadFailed') {
const { const {
message, message
indexer
} = data; } = data;
return ( return (
@ -193,14 +192,6 @@ function HistoryDetails(props) {
null null
} }
{
indexer ? (
<DescriptionListItem
title={translate('Indexer')}
data={indexer}
/>
) : null}
{ {
message ? message ?
<DescriptionListItem <DescriptionListItem

View file

@ -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, sizes, tooltipPositions } from 'Helpers/Props'; import { icons, inputTypes, kinds, 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 size={sizes.MEDIUM}> <FormGroup>
<FormLabel> <FormLabel>
{translate('Monitored')} {translate('Monitored')}
</FormLabel> </FormLabel>
@ -107,10 +107,9 @@ class EditArtistModalContent extends Component {
/> />
</FormGroup> </FormGroup>
<FormGroup size={sizes.MEDIUM}> <FormGroup>
<FormLabel> <FormLabel>
{translate('MonitorNewItems')} {translate('MonitorNewItems')}
<Popover <Popover
anchor={ anchor={
<Icon <Icon
@ -133,7 +132,7 @@ class EditArtistModalContent extends Component {
/> />
</FormGroup> </FormGroup>
<FormGroup size={sizes.MEDIUM}> <FormGroup>
<FormLabel> <FormLabel>
{translate('QualityProfile')} {translate('QualityProfile')}
</FormLabel> </FormLabel>
@ -147,10 +146,10 @@ class EditArtistModalContent extends Component {
</FormGroup> </FormGroup>
{ {
showMetadataProfile ? showMetadataProfile &&
<FormGroup size={sizes.MEDIUM}> <FormGroup>
<FormLabel> <FormLabel>
{translate('MetadataProfile')} Metadata Profile
<Popover <Popover
anchor={ anchor={
@ -174,11 +173,10 @@ class EditArtistModalContent extends Component {
{...metadataProfileId} {...metadataProfileId}
onChange={onInputChange} onChange={onInputChange}
/> />
</FormGroup> : </FormGroup>
null
} }
<FormGroup size={sizes.MEDIUM}> <FormGroup>
<FormLabel> <FormLabel>
{translate('Path')} {translate('Path')}
</FormLabel> </FormLabel>
@ -191,7 +189,7 @@ class EditArtistModalContent extends Component {
/> />
</FormGroup> </FormGroup>
<FormGroup size={sizes.MEDIUM}> <FormGroup>
<FormLabel> <FormLabel>
{translate('Tags')} {translate('Tags')}
</FormLabel> </FormLabel>
@ -211,7 +209,7 @@ class EditArtistModalContent extends Component {
kind={kinds.DANGER} kind={kinds.DANGER}
onPress={onDeleteArtistPress} onPress={onDeleteArtistPress}
> >
{translate('Delete')} Delete
</Button> </Button>
<Button <Button

View file

@ -20,8 +20,6 @@ import HintedSelectInputSelectedValue from './HintedSelectInputSelectedValue';
import TextInput from './TextInput'; import TextInput from './TextInput';
import styles from './EnhancedSelectInput.css'; import styles from './EnhancedSelectInput.css';
const MINIMUM_DISTANCE_FROM_EDGE = 10;
function isArrowKey(keyCode) { function isArrowKey(keyCode) {
return keyCode === keyCodes.UP_ARROW || keyCode === keyCodes.DOWN_ARROW; return keyCode === keyCodes.UP_ARROW || keyCode === keyCodes.DOWN_ARROW;
} }
@ -139,9 +137,18 @@ class EnhancedSelectInput extends Component {
// Listeners // Listeners
onComputeMaxHeight = (data) => { onComputeMaxHeight = (data) => {
const {
top,
bottom
} = data.offsets.reference;
const windowHeight = window.innerHeight; const windowHeight = window.innerHeight;
data.styles.maxHeight = windowHeight - MINIMUM_DISTANCE_FROM_EDGE; if ((/^botton/).test(data.placement)) {
data.styles.maxHeight = windowHeight - bottom;
} else {
data.styles.maxHeight = top;
}
return data; return data;
}; };
@ -450,10 +457,6 @@ class EnhancedSelectInput extends Component {
order: 851, order: 851,
enabled: true, enabled: true,
fn: this.onComputeMaxHeight fn: this.onComputeMaxHeight
},
preventOverflow: {
enabled: true,
boundariesElement: 'viewport'
} }
}} }}
> >

View file

@ -83,6 +83,13 @@
} }
@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;
} }

View file

@ -224,58 +224,10 @@ 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';

View file

@ -4,7 +4,7 @@
line-height: 1.52857143; line-height: 1.52857143;
} }
@media only screen and (max-width: $breakpointMedium) { @media only screen and (max-width: $breakpointSmall) {
.cell { .cell {
white-space: nowrap; white-space: nowrap;
} }

View file

@ -7,7 +7,7 @@
white-space: nowrap; white-space: nowrap;
} }
@media only screen and (max-width: $breakpointMedium) { @media only screen and (max-width: $breakpointSmall) {
.cell { .cell {
white-space: nowrap; white-space: nowrap;
} }

View file

@ -10,7 +10,7 @@
border-collapse: collapse; border-collapse: collapse;
} }
@media only screen and (max-width: $breakpointMedium) { @media only screen and (max-width: $breakpointSmall) {
.tableContainer { .tableContainer {
min-width: 100%; min-width: 100%;
width: fit-content; width: fit-content;

View file

@ -9,7 +9,7 @@
margin-left: 10px; margin-left: 10px;
} }
@media only screen and (max-width: $breakpointMedium) { @media only screen and (max-width: $breakpointSmall) {
.headerCell { .headerCell {
white-space: nowrap; white-space: nowrap;
} }

View file

@ -60,7 +60,7 @@
height: 25px; height: 25px;
} }
@media only screen and (max-width: $breakpointMedium) { @media only screen and (max-width: $breakpointSmall) {
.pager { .pager {
flex-wrap: wrap; flex-wrap: wrap;
} }

View file

@ -9,7 +9,7 @@
margin-left: 10px; margin-left: 10px;
} }
@media only screen and (max-width: $breakpointMedium) { @media only screen and (max-width: $breakpointSmall) {
.headerCell { .headerCell {
white-space: nowrap; white-space: nowrap;
} }

View file

@ -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: Column[] = [ const COLUMNS = [
{ {
name: 'name', name: 'name',
label: () => translate('Name'), label: () => translate('Name'),
@ -56,6 +56,8 @@ const COLUMNS: Column[] = [
interface ManageCustomFormatsModalContentProps { interface ManageCustomFormatsModalContentProps {
onModalClose(): void; onModalClose(): void;
sortKey?: string;
sortDirection?: SortDirection;
} }
function ManageCustomFormatsModalContent( function ManageCustomFormatsModalContent(

View file

@ -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: Column[] = [ const COLUMNS = [
{ {
name: 'name', name: 'name',
label: () => translate('Name'), label: () => translate('Name'),
@ -82,6 +82,8 @@ const COLUMNS: Column[] = [
interface ManageDownloadClientsModalContentProps { interface ManageDownloadClientsModalContentProps {
onModalClose(): void; onModalClose(): void;
sortKey?: string;
sortDirection?: SortDirection;
} }
function ManageDownloadClientsModalContent( function ManageDownloadClientsModalContent(

View file

@ -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: Column[] = [ const COLUMNS = [
{ {
name: 'name', name: 'name',
label: () => translate('Name'), label: () => translate('Name'),
@ -82,6 +82,8 @@ const COLUMNS: Column[] = [
interface ManageIndexersModalContentProps { interface ManageIndexersModalContentProps {
onModalClose(): void; onModalClose(): void;
sortKey?: string;
sortDirection?: SortDirection;
} }
function ManageIndexersModalContent(props: ManageIndexersModalContentProps) { function ManageIndexersModalContent(props: ManageIndexersModalContentProps) {

View file

@ -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('RemoveRootFolder')} title={translate('DeleteRootFolder')}
message={translate('RemoveRootFolderArtistsMessageText', { name })} message={translate('DeleteRootFolderMessageText', { name })}
confirmLabel={translate('Remove')} confirmLabel={translate('Delete')}
onConfirm={this.onConfirmDeleteRootFolder} onConfirm={this.onConfirmDeleteRootFolder}
onCancel={this.onDeleteRootFolderModalClose} onCancel={this.onDeleteRootFolderModalClose}
/> />

View file

@ -24,7 +24,7 @@
height: 20px; height: 20px;
} }
.track { .bar {
top: 9px; top: 9px;
margin: 0 5px; margin: 0 5px;
height: 3px; height: 3px;
@ -36,7 +36,7 @@
} }
} }
.thumb { .handle {
top: 1px; top: 1px;
z-index: 0 !important; z-index: 0 !important;
width: 18px; width: 18px;

View file

@ -1,6 +1,8 @@
// 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;
@ -8,9 +10,7 @@ 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;

View file

@ -55,27 +55,6 @@ 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
@ -195,7 +174,6 @@ 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}
@ -204,9 +182,9 @@ class QualityDefinition extends Component {
withTracks={true} withTracks={true}
allowCross={false} allowCross={false}
snapDragDisabled={true} snapDragDisabled={true}
pearling={true} className={styles.slider}
renderThumb={this.thumbRenderer} trackClassName={styles.bar}
renderTrack={this.trackRenderer} thumbClassName={styles.handle}
onChange={this.onSliderChange} onChange={this.onSliderChange}
onAfterChange={this.onAfterSliderChange} onAfterChange={this.onAfterSliderChange}
/> />

View file

@ -151,7 +151,7 @@ export const defaultState = {
{ {
name: 'genres', name: 'genres',
label: () => translate('Genres'), label: () => translate('Genres'),
isSortable: true, isSortable: false,
isVisible: false isVisible: false
}, },
{ {

View file

@ -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,16 +77,15 @@ class LogFiles extends Component {
<PageContentBody> <PageContentBody>
<Alert> <Alert>
<div> <div>
{translate('LogFilesLocation', { Log files are located in: {location}
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>
{ {

View file

@ -270,7 +270,7 @@ function Updates() {
{generalSettingsError ? ( {generalSettingsError ? (
<Alert kind={kinds.DANGER}> <Alert kind={kinds.DANGER}>
{translate('FailedToFetchSettings')} {translate('FailedToUpdateSettings')}
</Alert> </Alert>
) : null} ) : null}

View file

@ -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.41.0", "core-js": "3.39.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",

View file

@ -1,7 +1,5 @@
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
{ {
@ -11,10 +9,9 @@ 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(IBroadcastSignalRMessage signalRBroadcaster, IDownloadClientFactory downloadClientFactory) public DownloadClientController(IDownloadClientFactory downloadClientFactory)
: base(signalRBroadcaster, downloadClientFactory, "downloadclient", ResourceMapper, BulkResourceMapper) : base(downloadClientFactory, "downloadclient", ResourceMapper, BulkResourceMapper)
{ {
SharedValidator.RuleFor(c => c.Priority).InclusiveBetween(1, 50);
} }
} }
} }

View file

@ -1,6 +1,7 @@
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
@ -10,7 +11,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 string WikiUrl { get; set; } public HttpUri WikiUrl { get; set; }
} }
public static class HealthResourceMapper public static class HealthResourceMapper
@ -28,7 +29,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.FullUri WikiUrl = model.WikiUrl
}; };
} }

View file

@ -3,7 +3,6 @@ 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
{ {
@ -13,12 +12,11 @@ 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(IBroadcastSignalRMessage signalRBroadcaster, public ImportListController(IImportListFactory importListFactory,
IImportListFactory importListFactory,
RootFolderExistsValidator rootFolderExistsValidator, RootFolderExistsValidator rootFolderExistsValidator,
QualityProfileExistsValidator qualityProfileExistsValidator, QualityProfileExistsValidator qualityProfileExistsValidator,
MetadataProfileExistsValidator metadataProfileExistsValidator) MetadataProfileExistsValidator metadataProfileExistsValidator)
: base(signalRBroadcaster, importListFactory, "importlist", ResourceMapper, BulkResourceMapper) : base(importListFactory, "importlist", ResourceMapper, BulkResourceMapper)
{ {
SharedValidator.RuleFor(c => c.RootFolderPath).Cascade(CascadeMode.Stop) SharedValidator.RuleFor(c => c.RootFolderPath).Cascade(CascadeMode.Stop)
.IsValidPath() .IsValidPath()

View file

@ -1,8 +1,6 @@
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
{ {
@ -12,12 +10,9 @@ 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(IBroadcastSignalRMessage signalRBroadcaster, public IndexerController(IndexerFactory indexerFactory, DownloadClientExistsValidator downloadClientExistsValidator)
IndexerFactory indexerFactory, : base(indexerFactory, "indexer", ResourceMapper, BulkResourceMapper)
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);
} }
} }

View file

@ -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.4.0" /> <PackageReference Include="NLog" Version="5.3.4" />
<PackageReference Include="System.IO.Abstractions" Version="17.0.24" /> <PackageReference Include="System.IO.Abstractions" Version="17.0.24" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View file

@ -2,7 +2,6 @@ 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
{ {
@ -12,8 +11,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(IBroadcastSignalRMessage signalRBroadcaster, IMetadataFactory metadataFactory) public MetadataController(IMetadataFactory metadataFactory)
: base(signalRBroadcaster, metadataFactory, "metadata", ResourceMapper, BulkResourceMapper) : base(metadataFactory, "metadata", ResourceMapper, BulkResourceMapper)
{ {
} }

View file

@ -2,7 +2,6 @@ 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
{ {
@ -12,8 +11,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(IBroadcastSignalRMessage signalRBroadcaster, NotificationFactory notificationFactory) public NotificationController(NotificationFactory notificationFactory)
: base(signalRBroadcaster, notificationFactory, "notification", ResourceMapper, BulkResourceMapper) : base(notificationFactory, "notification", ResourceMapper, BulkResourceMapper)
{ {
} }

View file

@ -7,19 +7,12 @@ 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> : RestControllerWithSignalR<TProviderResource, TProviderDefinition>, public abstract class ProviderControllerBase<TProviderResource, TBulkProviderResource, TProvider, TProviderDefinition> : RestController<TProviderResource>
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()
@ -29,13 +22,11 @@ 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(IBroadcastSignalRMessage signalRBroadcaster, protected ProviderControllerBase(IProviderFactory<TProvider,
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;
@ -270,24 +261,6 @@ 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();

View file

@ -4,7 +4,6 @@ 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;
@ -28,22 +27,11 @@ namespace Lidarr.Api.V1.RemotePathMappings
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)
@ -53,7 +41,7 @@ namespace Lidarr.Api.V1.RemotePathMappings
[RestPostById] [RestPostById]
[Consumes("application/json")] [Consumes("application/json")]
public ActionResult<RemotePathMappingResource> CreateMapping([FromBody] RemotePathMappingResource resource) public ActionResult<RemotePathMappingResource> CreateMapping(RemotePathMappingResource resource)
{ {
var model = resource.ToModel(); var model = resource.ToModel();
@ -74,7 +62,7 @@ namespace Lidarr.Api.V1.RemotePathMappings
} }
[RestPutById] [RestPutById]
public ActionResult<RemotePathMappingResource> UpdateMapping([FromBody] RemotePathMappingResource resource) public ActionResult<RemotePathMappingResource> UpdateMapping(RemotePathMappingResource resource)
{ {
var mapping = resource.ToModel(); var mapping = resource.ToModel();

View file

@ -92,7 +92,7 @@ namespace Lidarr.Api.V1.System.Backup
} }
[HttpPost("restore/upload")] [HttpPost("restore/upload")]
[RequestFormLimits(MultipartBodyLengthLimit = 5000000000)] [RequestFormLimits(MultipartBodyLengthLimit = 1000000000)]
public object UploadAndRestore() public object UploadAndRestore()
{ {
var files = Request.Form.Files; var files = Request.Form.Files;

View file

@ -1,5 +1,4 @@
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;
@ -24,8 +23,6 @@ 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)

View file

@ -9808,8 +9808,7 @@
"nullable": true "nullable": true
}, },
"wikiUrl": { "wikiUrl": {
"type": "string", "$ref": "#/components/schemas/HttpUri"
"nullable": true
} }
}, },
"additionalProperties": false "additionalProperties": false
@ -10063,6 +10062,48 @@
}, },
"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": {

View file

@ -1,14 +1,9 @@
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;
@ -21,15 +16,11 @@ 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, IAppFolderInfo appFolderInfo, Logger logger) public AuthenticationController(IAuthenticationService authService, IConfigFileProvider configFileProvider)
{ {
_authService = authService; _authService = authService;
_configFileProvider = configFileProvider; _configFileProvider = configFileProvider;
_appFolderInfo = appFolderInfo;
_logger = logger;
} }
[HttpPost("login")] [HttpPost("login")]
@ -54,23 +45,7 @@ namespace Lidarr.Http.Authentication
IsPersistent = resource.RememberMe == "on" IsPersistent = resource.RememberMe == "on"
}; };
try
{
await HttpContext.SignInAsync(AuthenticationType.Forms.ToString(), new ClaimsPrincipal(new ClaimsIdentity(claims, "Cookies", "user", "identifier")), authProperties); 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))
{ {

View file

@ -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.4.0" /> <PackageReference Include="NLog" Version="5.3.4" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\NzbDrone.Core\Lidarr.Core.csproj" /> <ProjectReference Include="..\NzbDrone.Core\Lidarr.Core.csproj" />

View file

@ -40,16 +40,15 @@ 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, TimeSpan.FromMinutes(3)); driver = new ChromeDriver(service, options, new TimeSpan(0, 3, 0));
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.Navigate().GoToUrl("http://localhost:8686"); driver.Url = "http://localhost:8686";
var page = new PageBase(driver); var page = new PageBase(driver);
page.WaitForNoSpinner(); page.WaitForNoSpinner();
@ -69,7 +68,7 @@ namespace NzbDrone.Automation.Test
{ {
try try
{ {
var image = (driver as ITakesScreenshot).GetScreenshot(); var image = ((ITakesScreenshot)driver).GetScreenshot();
image.SaveAsFile($"./{name}_test_screenshot.png", ScreenshotImageFormat.Png); image.SaveAsFile($"./{name}_test_screenshot.png", ScreenshotImageFormat.Png);
} }
catch (Exception ex) catch (Exception ex)

View file

@ -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="134.0.6998.16500" /> <PackageReference Include="Selenium.WebDriver.ChromeDriver" Version="111.0.5563.6400" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\NzbDrone.Test.Common\Lidarr.Test.Common.csproj" /> <ProjectReference Include="..\NzbDrone.Test.Common\Lidarr.Test.Common.csproj" />

View file

@ -1,17 +1,19 @@
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 IWebDriver _driver; private readonly RemoteWebDriver _driver;
public PageBase(IWebDriver driver) public PageBase(RemoteWebDriver 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)

View file

@ -3,7 +3,6 @@ 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;
@ -307,26 +306,9 @@ namespace NzbDrone.Common.Disk
{ {
Ensure.That(path, () => path).IsValidPath(PathValidationType.CurrentOs); Ensure.That(path, () => path).IsValidPath(PathValidationType.CurrentOs);
var files = GetFiles(path, recursive).ToList(); var files = GetFiles(path, recursive);
files.ForEach(RemoveReadOnly); files.ToList().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);
} }

View file

@ -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, WebExceptionStatus.Timeout, null); throw new WebException("Http request timed out", ex.InnerException, WebExceptionStatus.Timeout, null);
} }
} }

View file

@ -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.2.0" /> <PackageReference Include="IPAddressRange" Version="6.1.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.4.0" /> <PackageReference Include="NLog" Version="5.3.4" />
<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.3" /> <PackageReference Include="NLog.Layouts.ClefJsonLayout" Version="1.0.2" />
<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.6.1" /> <PackageReference Include="System.ValueTuple" Version="4.5.0" />
<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" />

View file

@ -1,4 +1,3 @@
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;
@ -7,7 +6,7 @@ namespace NzbDrone.Common
{ {
public class PathEqualityComparer : IEqualityComparer<string> public class PathEqualityComparer : IEqualityComparer<string>
{ {
public static readonly PathEqualityComparer Instance = new (); public static readonly PathEqualityComparer Instance = new PathEqualityComparer();
private PathEqualityComparer() private PathEqualityComparer()
{ {
@ -19,8 +18,6 @@ namespace NzbDrone.Common
} }
public int GetHashCode(string obj) public int GetHashCode(string obj)
{
try
{ {
if (OsInfo.IsWindows) if (OsInfo.IsWindows)
{ {
@ -29,10 +26,5 @@ namespace NzbDrone.Common
return obj.CleanFilePath().Normalize().GetHashCode(); return obj.CleanFilePath().Normalize().GetHashCode();
} }
catch (ArgumentException ex)
{
throw new ArgumentException($"Invalid path: {obj}", ex);
}
}
} }
} }

View file

@ -6,7 +6,6 @@ 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;
@ -118,9 +117,7 @@ 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)

View file

@ -103,7 +103,6 @@ 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>();

View file

@ -80,7 +80,7 @@ namespace NzbDrone.Core.Test.ImportListTests
} }
[Test] [Test]
[Ignore("Pending mapping fixes", Until = "2025-10-20 00:00:00Z")] [Ignore("Pending mapping fixes", Until = "2025-04-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-10-20 00:00:00Z")] [Ignore("Pending mapping fixes", Until = "2025-04-20 00:00:00Z")]
public void map_album_should_work() public void map_album_should_work()
{ {
UseRealHttp(); UseRealHttp();

View file

@ -14,7 +14,6 @@ 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-08-01 00:00:00Z")]
public class SkyHookProxyFixture : CoreTest<SkyHookProxy> public class SkyHookProxyFixture : CoreTest<SkyHookProxy>
{ {
private MetadataProfile _metadataProfile; private MetadataProfile _metadataProfile;

View file

@ -12,7 +12,6 @@ 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-08-01 00:00:00Z")]
public class SkyHookProxySearchFixture : CoreTest<SkyHookProxy> public class SkyHookProxySearchFixture : CoreTest<SkyHookProxy>
{ {
[SetUp] [SetUp]

View file

@ -129,9 +129,6 @@ 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);

View file

@ -11,7 +11,6 @@ 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);
} }
} }

View file

@ -252,7 +252,7 @@ namespace NzbDrone.Core.Datastore
protected void Delete(SqlBuilder builder) protected void Delete(SqlBuilder builder)
{ {
var sql = builder.AddDeleteTemplate(typeof(TModel)); var sql = builder.AddDeleteTemplate(typeof(TModel)).LogQuery();
using (var conn = _database.OpenConnection()) using (var conn = _database.OpenConnection())
{ {

View file

@ -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(/|$)|/\.timemachine", RegexOptions.Compiled); private static readonly Regex _regexSpecialDrive = new Regex("^/var/lib/(docker|rancher|kubelet)(/|$)|^/(boot|etc)(/|$)|/docker(/var)?/aufs(/|$)", RegexOptions.Compiled);
public DiskSpaceService(IDiskProvider diskProvider, public DiskSpaceService(IDiskProvider diskProvider,
IRootFolderService rootFolderService, IRootFolderService rootFolderService,
@ -38,10 +38,7 @@ namespace NzbDrone.Core.DiskSpace
var optionalRootFolders = GetFixedDisksRootPaths().Except(importantRootFolders).Distinct().ToList(); var optionalRootFolders = GetFixedDisksRootPaths().Except(importantRootFolders).Distinct().ToList();
var diskSpace = GetDiskSpace(importantRootFolders) var diskSpace = GetDiskSpace(importantRootFolders).Concat(GetDiskSpace(optionalRootFolders, true)).ToList();
.Concat(GetDiskSpace(optionalRootFolders, true))
.OrderBy(d => d.Path, StringComparer.OrdinalIgnoreCase)
.ToList();
return diskSpace; return diskSpace;
} }
@ -57,7 +54,7 @@ namespace NzbDrone.Core.DiskSpace
private IEnumerable<string> GetFixedDisksRootPaths() private IEnumerable<string> GetFixedDisksRootPaths()
{ {
return _diskProvider.GetMounts() return _diskProvider.GetMounts()
.Where(d => d.DriveType is DriveType.Fixed or DriveType.Network) .Where(d => d.DriveType == DriveType.Fixed)
.Where(d => !_regexSpecialDrive.IsMatch(d.RootDirectory)) .Where(d => !_regexSpecialDrive.IsMatch(d.RootDirectory))
.Select(d => d.RootDirectory); .Select(d => d.RootDirectory);
} }

View file

@ -9,7 +9,6 @@ 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,10 +28,9 @@ 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, localizationService, blocklistService, logger) : base(torrentFileInfoReader, httpClient, configService, diskProvider, remotePathMappingService, blocklistService, logger)
{ {
_proxy = proxy; _proxy = proxy;
} }

View file

@ -9,7 +9,6 @@ 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;
@ -31,10 +30,9 @@ 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, localizationService, blocklistService, logger) : base(torrentFileInfoReader, httpClient, configService, diskProvider, remotePathMappingService, blocklistService, logger)
{ {
_scanWatchFolder = scanWatchFolder; _scanWatchFolder = scanWatchFolder;

View file

@ -7,7 +7,6 @@ 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;
@ -26,9 +25,8 @@ 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, localizationService, logger) : base(httpClient, configService, diskProvider, remotePathMappingService, nzbValidationService, logger)
{ {
_scanWatchFolder = scanWatchFolder; _scanWatchFolder = scanWatchFolder;

View file

@ -9,7 +9,6 @@ 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,10 +27,9 @@ 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, localizationService, blocklistService, logger) : base(torrentFileInfoReader, httpClient, configService, diskProvider, remotePathMappingService, blocklistService, logger)
{ {
_proxy = proxy; _proxy = proxy;
} }

View file

@ -11,7 +11,6 @@ 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;
@ -38,10 +37,9 @@ 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, localizationService, blocklistService, logger) : base(torrentFileInfoReader, httpClient, configService, diskProvider, remotePathMappingService, blocklistService, logger)
{ {
_dsInfoProxy = dsInfoProxy; _dsInfoProxy = dsInfoProxy;
_dsTaskProxySelector = dsTaskProxySelector; _dsTaskProxySelector = dsTaskProxySelector;

View file

@ -9,7 +9,6 @@ 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;
@ -35,9 +34,8 @@ 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, localizationService, logger) : base(httpClient, configService, diskProvider, remotePathMappingService, nzbValidationService, logger)
{ {
_dsInfoProxy = dsInfoProxy; _dsInfoProxy = dsInfoProxy;
_dsTaskProxySelector = dsTaskProxySelector; _dsTaskProxySelector = dsTaskProxySelector;

View file

@ -9,7 +9,6 @@ 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;
@ -29,10 +28,9 @@ 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, localizationService, blocklistService, logger) : base(torrentFileInfoReader, httpClient, configService, diskProvider, remotePathMappingService, blocklistService, logger)
{ {
_proxy = proxy; _proxy = proxy;
_downloadSeedConfigProvider = downloadSeedConfigProvider; _downloadSeedConfigProvider = downloadSeedConfigProvider;

View file

@ -9,7 +9,6 @@ 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;
@ -26,10 +25,9 @@ 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, localizationService, blocklistService, logger) : base(torrentFileInfoReader, httpClient, configService, diskProvider, remotePathMappingService, blocklistService, logger)
{ {
_proxy = proxy; _proxy = proxy;
} }

View file

@ -8,7 +8,6 @@ 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;
@ -26,10 +25,9 @@ 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, localizationService, blocklistService, logger) : base(torrentFileInfoReader, httpClient, configService, diskProvider, remotePathMappingService, blocklistService, logger)
{ {
_proxy = proxy; _proxy = proxy;
} }

View file

@ -8,7 +8,6 @@ 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;
@ -25,9 +24,8 @@ 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, localizationService, logger) : base(httpClient, configService, diskProvider, remotePathMappingService, nzbValidationService, logger)
{ {
_proxy = proxy; _proxy = proxy;
} }

View file

@ -10,7 +10,6 @@ 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;
@ -29,9 +28,8 @@ 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, localizationService, logger) : base(httpClient, configService, diskProvider, remotePathMappingService, nzbValidationService, logger)
{ {
_proxy = proxy; _proxy = proxy;
} }

View file

@ -9,7 +9,6 @@ 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;
@ -24,9 +23,8 @@ 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, localizationService, logger) : base(configService, diskProvider, remotePathMappingService, logger)
{ {
_httpClient = httpClient; _httpClient = httpClient;
} }

View file

@ -10,7 +10,6 @@ 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;
@ -36,10 +35,9 @@ 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, localizationService, blocklistService, logger) : base(torrentFileInfoReader, httpClient, configService, diskProvider, remotePathMappingService, blocklistService, logger)
{ {
_proxySelector = proxySelector; _proxySelector = proxySelector;

View file

@ -10,7 +10,6 @@ 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;
@ -27,9 +26,8 @@ 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, localizationService, logger) : base(httpClient, configService, diskProvider, remotePathMappingService, nzbValidationService, logger)
{ {
_proxy = proxy; _proxy = proxy;
} }

View file

@ -8,7 +8,6 @@ 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;
@ -25,10 +24,9 @@ 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, localizationService, blocklistService, logger) : base(proxy, torrentFileInfoReader, httpClient, configService, diskProvider, remotePathMappingService, blocklistService, logger)
{ {
} }

View file

@ -9,7 +9,6 @@ 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,10 +28,9 @@ 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, localizationService, blocklistService, logger) : base(torrentFileInfoReader, httpClient, configService, diskProvider, remotePathMappingService, blocklistService, logger)
{ {
_proxy = proxy; _proxy = proxy;
} }
@ -103,11 +101,7 @@ namespace NzbDrone.Core.Download.Clients.Transmission
if (!torrent.ErrorString.IsNullOrWhiteSpace()) if (!torrent.ErrorString.IsNullOrWhiteSpace())
{ {
item.Status = DownloadItemStatus.Warning; item.Status = DownloadItemStatus.Warning;
item.Message = _localizationService.GetLocalizedString("DownloadClientItemErrorMessage", new Dictionary<string, object> item.Message = torrent.ErrorString;
{
{ "clientName", Name },
{ "message", torrent.ErrorString }
});
} }
else if (torrent.TotalSize == 0) else if (torrent.TotalSize == 0)
{ {

View file

@ -5,7 +5,6 @@ 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;
@ -24,10 +23,9 @@ 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, localizationService, blocklistService, logger) : base(proxy, torrentFileInfoReader, httpClient, configService, diskProvider, remotePathMappingService, blocklistService, logger)
{ {
} }

View file

@ -12,7 +12,6 @@ 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;
@ -36,10 +35,9 @@ 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, localizationService, blocklistService, logger) : base(torrentFileInfoReader, httpClient, configService, diskProvider, remotePathMappingService, blocklistService, logger)
{ {
_proxy = proxy; _proxy = proxy;
_rTorrentDirectoryValidator = rTorrentDirectoryValidator; _rTorrentDirectoryValidator = rTorrentDirectoryValidator;

View file

@ -10,7 +10,6 @@ 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;
@ -30,10 +29,9 @@ 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, localizationService, blocklistService, logger) : base(torrentFileInfoReader, httpClient, configService, diskProvider, remotePathMappingService, blocklistService, logger)
{ {
_proxy = proxy; _proxy = proxy;

View file

@ -8,7 +8,6 @@ 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;
@ -24,7 +23,6 @@ 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>()
@ -79,13 +77,11 @@ 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;
} }

View file

@ -1,4 +1,3 @@
using System;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Xml; using System.Xml;
@ -15,13 +14,10 @@ namespace NzbDrone.Core.Download
public class NzbValidationService : IValidateNzbs public class NzbValidationService : IValidateNzbs
{ {
public void Validate(string filename, byte[] fileContent) public void Validate(string filename, byte[] fileContent)
{
try
{ {
var reader = new StreamReader(new MemoryStream(fileContent)); var reader = new StreamReader(new MemoryStream(fileContent));
using (var xmlTextReader = XmlReader.Create(reader, using (var xmlTextReader = XmlReader.Create(reader, new XmlReaderSettings { DtdProcessing = DtdProcessing.Ignore, IgnoreComments = true }))
new XmlReaderSettings { DtdProcessing = DtdProcessing.Ignore, IgnoreComments = true }))
{ {
var xDoc = XDocument.Load(xmlTextReader); var xDoc = XDocument.Load(xmlTextReader);
var nzb = xDoc.Root; var nzb = xDoc.Root;
@ -41,8 +37,7 @@ namespace NzbDrone.Core.Download
if (!nzb.Name.LocalName.Equals("nzb")) if (!nzb.Name.LocalName.Equals("nzb"))
{ {
throw new InvalidNzbException( throw new InvalidNzbException("Invalid NZB: Unexpected root element. Expected 'nzb' found '{0}' [{1}]", nzb.Name.LocalName, filename);
"Invalid NZB: Unexpected root element. Expected 'nzb' found '{0}' [{1}]", nzb.Name.LocalName, filename);
} }
var ns = nzb.Name.Namespace; var ns = nzb.Name.Namespace;
@ -54,15 +49,5 @@ namespace NzbDrone.Core.Download
} }
} }
} }
catch (InvalidNzbException)
{
// Throw the original exception
throw;
}
catch (Exception ex)
{
throw new InvalidNzbException("Invalid NZB: Unable to parse [{0}]", ex, filename);
}
}
} }
} }

View file

@ -10,7 +10,6 @@ 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;
@ -31,10 +30,9 @@ 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, localizationService, logger) : base(configService, diskProvider, remotePathMappingService, logger)
{ {
_httpClient = httpClient; _httpClient = httpClient;
_blocklistService = blocklistService; _blocklistService = blocklistService;
@ -172,7 +170,7 @@ namespace NzbDrone.Core.Download
} }
catch (HttpException ex) catch (HttpException ex)
{ {
if (ex.Response.StatusCode is HttpStatusCode.NotFound or HttpStatusCode.Gone) if (ex.Response.StatusCode == HttpStatusCode.NotFound)
{ {
_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);

View file

@ -6,7 +6,6 @@ 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;
@ -25,9 +24,8 @@ 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, localizationService, logger) : base(configService, diskProvider, remotePathMappingService, logger)
{ {
_httpClient = httpClient; _httpClient = httpClient;
_nzbValidationService = nzbValidationService; _nzbValidationService = nzbValidationService;
@ -48,7 +46,6 @@ 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))
@ -60,7 +57,7 @@ namespace NzbDrone.Core.Download
} }
catch (HttpException ex) catch (HttpException ex)
{ {
if (ex.Response.StatusCode is HttpStatusCode.NotFound or HttpStatusCode.Gone) if (ex.Response.StatusCode == HttpStatusCode.NotFound)
{ {
_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);

View file

@ -10,9 +10,6 @@ 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()
{ {

View file

@ -104,7 +104,6 @@ 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)
@ -112,11 +111,10 @@ namespace NzbDrone.Core.History
builder.Where<EntityHistory>(h => h.EventType == eventType); builder.Where<EntityHistory>(h => h.EventType == eventType);
} }
return _database.QueryJoined<EntityHistory, Artist, Album, Track>(builder, (history, artist, album, track) => return _database.QueryJoined<EntityHistory, Artist, Album>(builder, (history, artist, album) =>
{ {
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();
} }

View file

@ -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.ToUniversalTime().ToString("s") + "Z"); history.Data.Add("PublishedDate", message.Album.Release.PublishDate.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,9 +267,7 @@ 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("ReleaseGroup", message.TrackedDownload?.RemoteAlbum?.ParsedAlbumInfo?.ReleaseGroup ?? message.Data.GetValueOrDefault(EntityHistory.RELEASE_GROUP)); history.Data.Add("Size", message.TrackedDownload?.DownloadItem.TotalSize.ToString());
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);
} }
@ -419,7 +417,6 @@ 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);
} }

View file

@ -1,7 +1,6 @@
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;
@ -45,11 +44,6 @@ 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);

View file

@ -13,8 +13,6 @@ 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());
} }
} }

View file

@ -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.2" /> <PackageReference Include="System.Memory" Version="4.6.0" />
<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.4.0" /> <PackageReference Include="NLog" Version="5.3.4" />
<PackageReference Include="NLog.Extensions.Logging" Version="5.4.0" /> <PackageReference Include="NLog.Extensions.Logging" Version="5.3.15" />
<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.10" /> <PackageReference Include="Npgsql" Version="7.0.9" />
<PackageReference Include="SpotifyAPI.Web" Version="5.1.1" /> <PackageReference Include="SpotifyAPI.Web" Version="5.1.1" />
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.9" /> <PackageReference Include="SixLabors.ImageSharp" Version="3.1.7" />
<PackageReference Include="MonoTorrent" Version="2.0.7" /> <PackageReference Include="MonoTorrent" Version="2.0.7" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View file

@ -759,11 +759,5 @@
"Preferred": "يفضل", "Preferred": "يفضل",
"Today": "اليوم", "Today": "اليوم",
"MappedNetworkDrivesWindowsService": "لا تتوفر محركات أقراص الشبكة المعينة عند التشغيل كخدمة Windows. يرجى الاطلاع على التعليمات لمزيد من المعلومات", "MappedNetworkDrivesWindowsService": "لا تتوفر محركات أقراص الشبكة المعينة عند التشغيل كخدمة Windows. يرجى الاطلاع على التعليمات لمزيد من المعلومات",
"DownloadClientSettingsRecentPriority": "أولوية العميل", "DownloadClientSettingsRecentPriority": "أولوية العميل"
"CheckDownloadClientForDetails": "تحقق من برنامج التحميل لمزيد من التفاصيل",
"Downloaded": "تم التنزيل",
"Paused": "متوقف مؤقتًا",
"Pending": "قيد الانتظار",
"WaitingToImport": "في انتظار الاستيراد",
"WaitingToProcess": "في انتظار المعالجة"
} }

View file

@ -829,11 +829,5 @@
"Album": "албум", "Album": "албум",
"AutoAdd": "Автоматично добавяне", "AutoAdd": "Автоматично добавяне",
"CatalogNumber": "каталожен номер", "CatalogNumber": "каталожен номер",
"Discography": "дискография", "Discography": "дискография"
"CheckDownloadClientForDetails": "проверете клиента за изтегляне за повече подробности",
"WaitingToImport": "Изчаква се импортиране",
"WaitingToProcess": "Изчаква се обработка",
"Downloaded": "Изтеглено",
"Paused": "На пауза",
"Pending": "В очакване"
} }

View file

@ -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 llançament?", "DeleteReleaseProfileMessageText": "Esteu segur que voleu suprimir aquest perfil de retard?",
"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 historial.", "NoHistory": "Sense història",
"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": "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", "CopyUsingHardlinksHelpText": "Utilitzeu els enllaços durs quan intenteu copiar fitxers de torrents que encara s'estan sembrant",
"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 {date} a les {time}", "DelayingDownloadUntil": "S'està retardant la baixada fins a les {0} a les {1}",
"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": "Importació fallida: {0}", "ImportFailedInterp": "ImportFailedInterp",
"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": "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.", "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.",
"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 '{name}'?", "DeleteFormatMessageText": "Esteu segur que voleu suprimir l'etiqueta de format {0} ?",
"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 {0}.", "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}.",
"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 música descarregada {0}. Probablement s'ha produït un error en els permisos.", "RemotePathMappingCheckDownloadPermissions": "{appName} pot veure però no accedir a la pel·lícula baixada {0}. Error de permisos probable.",
"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 música. Comproveu els vostres registres per obtenir-ne més detalls.", "RemotePathMappingCheckImportFailed": "{appName} no ha pogut importar una pel·lícula. Comproveu els vostres registres per a obtenir més informació.",
"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 condició '{name}'?", "DeleteConditionMessageText": "Esteu segur que voleu suprimir la notificació '{0}'?",
"DeleteSelectedDownloadClients": "Suprimeix els clients seleccionats de baixada", "DeleteSelectedDownloadClients": "Suprimeix el client de descàrrega",
"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 '{folder}' es crearà automàticament", "AddNewArtistRootFolderHelpText": "La subcarpeta '{0}' 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 {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.", "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.",
"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 {0} 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 {length} 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": "{selectedCount} client(s) de baixada seleccionat(s)", "CountDownloadClientsSelected": "{count} 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 {0}?", "DeleteTrackFileMessageText": "Esteu segur que voleu suprimir '{path}'?",
"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 '{title}'?", "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}\"?",
"IndexerFlags": "Indicadors de l'indexador", "IndexerFlags": "Indicadors de l'indexador",
"MonitorNoAlbums": "Cap", "MonitorNoAlbums": "Cap",
"Rejections": "Rebutjats", "Rejections": "Rebutjats",
@ -984,248 +984,5 @@
"UpdateFiltered": "Actualitza filtrats", "UpdateFiltered": "Actualitza filtrats",
"IndexerSettingsApiUrl": "URL de l'API", "IndexerSettingsApiUrl": "URL de l'API",
"CountCustomFormatsSelected": "{count} format(s) personalitzat(s) seleccionat(s)", "CountCustomFormatsSelected": "{count} format(s) personalitzat(s) seleccionat(s)",
"Install": "Instal·la", "Install": "Instal·la"
"CheckDownloadClientForDetails": "Consulteu el client de descàrrega per a obtenir més detalls",
"DownloadWarning": "Avís de baixada: {warningMessage}",
"Downloaded": "S'ha baixat",
"ImportFailed": "La importació ha fallat: {sourceTitle}",
"Paused": "En pausa",
"Pending": "Pendents",
"WaitingToImport": "Sestà esperant per a importar",
"WaitingToProcess": "Sestà 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 lartista",
"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ó"
} }

View file

@ -917,14 +917,5 @@
"DoNotBlocklistHint": "Odstraň bez přidání do seznamu blokování", "DoNotBlocklistHint": "Odstraň bez přidání do seznamu blokování",
"DownloadClientAriaSettingsDirectoryHelpText": "Volitelné umístění pro stahování, pokud chcete použít výchozí umístění Aria2, ponechte prázdné", "DownloadClientAriaSettingsDirectoryHelpText": "Volitelné umístění pro stahování, pokud chcete použít výchozí umístění Aria2, ponechte prázdné",
"DownloadClientQbittorrentSettingsContentLayout": "Rozvržení obsahu", "DownloadClientQbittorrentSettingsContentLayout": "Rozvržení obsahu",
"DownloadClientQbittorrentSettingsContentLayoutHelpText": "Zda použít rozvržení obsahu nakonfigurované v qBittorrentu, původní rozvržení z torrentu nebo vždy vytvořit podsložku (qBittorrent 4.3.2+)", "DownloadClientQbittorrentSettingsContentLayoutHelpText": "Zda použít rozvržení obsahu nakonfigurované v qBittorrentu, původní rozvržení z torrentu nebo vždy vytvořit podsložku (qBittorrent 4.3.2+)"
"DownloadClientDelugeSettingsDirectoryCompletedHelpText": "Nepovinné - umístění kam přesunout dokončená stahování, pokud ponecháte prázné, použije se výchozí umístění Deluge",
"DownloadClientDelugeSettingsDirectoryHelpText": "Nepovinné - umístění stahovaných souborů, pokud ponecháte prázné, použije se výchozí umístění Deluge",
"WaitingToImport": "Čekání na import",
"WaitingToProcess": "Čekání na zpracování",
"DownloadClientDelugeSettingsDirectoryCompleted": "Adresář kam přesunout po dokončení",
"CheckDownloadClientForDetails": "zkontrolujte klienta pro stahování pro více informací",
"Downloaded": "Staženo",
"Paused": "Pozastaveno",
"Pending": "čekající"
} }

View file

@ -798,13 +798,5 @@
"Episode": "afsnit", "Episode": "afsnit",
"MetadataProfile": "metadataprofil", "MetadataProfile": "metadataprofil",
"Min": "Min", "Min": "Min",
"DownloadClientSettingsRecentPriority": "Kundens prioritet", "DownloadClientSettingsRecentPriority": "Kundens prioritet"
"Pending": "Verserende",
"ImportFailed": "Import mislykkedes: »{sourceTitle}«",
"CheckDownloadClientForDetails": "tjek download klient for flere detaljer",
"DownloadWarning": "Downloadadvarsel: »{warningMessage}«",
"Downloaded": "Downloadet",
"Paused": "Pauset",
"WaitingToImport": "Venter på at importere",
"WaitingToProcess": "Venter på at behandle"
} }

View file

@ -1349,15 +1349,5 @@
"Inactive": "Inaktiv", "Inactive": "Inaktiv",
"AlbumInfo": "Album Informationen", "AlbumInfo": "Album Informationen",
"Banners": "Banner", "Banners": "Banner",
"DeleteArtistFolders": "Künstlerordner löschen", "DeleteArtistFolders": "Künstlerordner löschen"
"ImportFailed": "Import fehlgeschlagen: {sourceTitle}",
"DownloadWarning": "Download Warnung: {warningMessage}",
"Downloaded": "Heruntergeladen",
"Pending": "Ausstehend",
"PendingDownloadClientUnavailable": "Ausstehend - Download-Client nicht verfügbar",
"UnableToImportAutomatically": "Kann nicht automatisch importiert werden",
"CheckDownloadClientForDetails": "Weitere Informationen finden Sie im Download-Client",
"Paused": "Pausiert",
"WaitingToImport": "Warten auf Import",
"WaitingToProcess": "Warten auf Bearbeitung"
} }

View file

@ -1121,11 +1121,5 @@
"Min": "Ελάχ", "Min": "Ελάχ",
"Today": "Σήμερα", "Today": "Σήμερα",
"MappedNetworkDrivesWindowsService": "Οι αντιστοιχισμένες μονάδες δίσκου δικτύου δεν είναι διαθέσιμες κατά την εκτέλεση ως υπηρεσία Windows. Ανατρέξτε στις Συχνές Ερωτήσεις για περισσότερες πληροφορίες", "MappedNetworkDrivesWindowsService": "Οι αντιστοιχισμένες μονάδες δίσκου δικτύου δεν είναι διαθέσιμες κατά την εκτέλεση ως υπηρεσία Windows. Ανατρέξτε στις Συχνές Ερωτήσεις για περισσότερες πληροφορίες",
"DownloadClientSettingsRecentPriority": "Προτεραιότητα πελάτη", "DownloadClientSettingsRecentPriority": "Προτεραιότητα πελάτη"
"Pending": "εκκρεμής",
"WaitingToImport": "Αναμονή για εισαγωγή",
"WaitingToProcess": "Αναμονή για επεξεργασία",
"CheckDownloadClientForDetails": "ελέγξτε το πρόγραμμα-πελάτη λήψης για περισσότερες λεπτομέρειες",
"Downloaded": "Κατεβασμένα",
"Paused": "Σε παύση"
} }

View file

@ -256,7 +256,6 @@
"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",
@ -335,6 +334,8 @@
"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)",
@ -382,7 +383,6 @@
"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,8 +486,6 @@
"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",
@ -690,7 +688,6 @@
"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",
@ -1027,8 +1024,6 @@
"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?",
@ -1223,7 +1218,6 @@
"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",

View file

@ -1349,15 +1349,5 @@
"DownloadClientSettingsOlderPriorityAlbumHelpText": "Prioridad a usar cuando se capturen álbumes lanzados hace más de 14 días", "DownloadClientSettingsOlderPriorityAlbumHelpText": "Prioridad a usar cuando se capturen álbumes lanzados hace más de 14 días",
"NotificationsSettingsWebhookHeaders": "Cabeceras", "NotificationsSettingsWebhookHeaders": "Cabeceras",
"NoMediumInformation": "Ninguna información del medio disponible.", "NoMediumInformation": "Ninguna información del medio disponible.",
"TracksLoadError": "No se pudo cargar las pistas", "TracksLoadError": "No se pudo cargar las pistas"
"CheckDownloadClientForDetails": "Revisar el cliente de descarga para más detalles",
"DownloadWarning": "Alerta de descarga: {warningMessage}",
"Downloaded": "Descargado",
"ImportFailed": "La importación falló: {sourceTitle}",
"Paused": "Pausado",
"Pending": "Pendiente",
"PendingDownloadClientUnavailable": "Pendiente - El cliente de descarga no está disponible",
"UnableToImportAutomatically": "No se pudo importar automáticamente",
"WaitingToImport": "Esperar para importar",
"WaitingToProcess": "Esperar al proceso"
} }

View file

@ -963,7 +963,7 @@
"Small": "Pieni", "Small": "Pieni",
"RemoveSelectedItems": "Poista valitut kohteet", "RemoveSelectedItems": "Poista valitut kohteet",
"ResetTitles": "Palauta nimet", "ResetTitles": "Palauta nimet",
"AddNewArtistRootFolderHelpText": "Alikansio \"{folder}\" luodaan automaattisesti.", "AddNewArtistRootFolderHelpText": "\"{folder}\" -alikansio 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 niiden nykyiseen juurikansioon voidaan niiden kansioiden nimet päivittää vastaamaan päivittynyttä nimikettä tai nimeämiskaavaa.", "ArtistsEditRootFolderHelpText": "Siirtämällä esittäjät samaan 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.",
@ -1349,15 +1349,5 @@
"NotificationsTagsArtistHelpText": "Ilmoita vain vähintään yhdellä täsmäävällä tunnisteella merkityistä esittäjistä.", "NotificationsTagsArtistHelpText": "Ilmoita vain vähintään yhdellä täsmäävällä tunnisteella merkityistä esittäjistä.",
"NotificationsSettingsWebhookHeaders": "Otsakkeet", "NotificationsSettingsWebhookHeaders": "Otsakkeet",
"TracksLoadError": "Virhe ladattaessa kappaleita.", "TracksLoadError": "Virhe ladattaessa kappaleita.",
"NoMediumInformation": "Julkaisumuodon tietoja ei ole saatavilla.", "NoMediumInformation": "Julkaisumuodon tietoja ei ole saatavilla."
"DownloadWarning": "Latausvaroitus: {warningMessage}",
"UnableToImportAutomatically": "Virhe automaattituonnissa.",
"WaitingToImport": "Odottaa tuontia",
"WaitingToProcess": "Odottaa käsittelyä",
"CheckDownloadClientForDetails": "katso lisätietoja latauspalvelusta",
"Downloaded": "Ladattu",
"Paused": "Keskeytetty",
"Pending": "Odottaa",
"PendingDownloadClientUnavailable": "Odottaa Latauspalvelu ei ole käytettävissä",
"ImportFailed": "Tuonti epäonnistui: {sourceTitle}"
} }

View file

@ -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 musique téléchargé {0}. Il s'agit probablement d'une erreur de permissions.", "RemotePathMappingCheckDownloadPermissions": "{appName} peut voir mais ne peut accéder au film 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 une musique. Vérifier vos logs pour plus de détails.", "RemotePathMappingCheckImportFailed": "{appName} a échoué en important un Film. 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.",
@ -1340,24 +1340,5 @@
"DownloadClientSettingsRecentPriority": "Priorité récente", "DownloadClientSettingsRecentPriority": "Priorité récente",
"PostImportCategory": "Catégorie après l'importation", "PostImportCategory": "Catégorie après l'importation",
"ManageFormats": "Gérer les formats", "ManageFormats": "Gérer les formats",
"NotificationsSettingsWebhookHeaders": "En-têtes", "NotificationsSettingsWebhookHeaders": "En-têtes"
"ImportFailed": "Échec de l'importation : {sourceTitle}",
"CheckDownloadClientForDetails": "Pour plus de détails, consultez le client de téléchargement",
"DownloadWarning": "Avertissement de téléchargement : {warningMessage}",
"Downloaded": "Téléchargé",
"Paused": "En pause",
"Pending": "En attente",
"PendingDownloadClientUnavailable": "En attente Le client de téléchargement n'est pas disponible",
"UnableToImportAutomatically": "Impossible d'importer automatiquement",
"WaitingToImport": "En attente d'import",
"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"
} }

View file

@ -797,11 +797,5 @@
"Min": "דקה", "Min": "דקה",
"Preferred": "מועדף", "Preferred": "מועדף",
"MappedNetworkDrivesWindowsService": "כונני רשת ממופים אינם זמינים כאשר הם פועלים כשירות Windows. אנא עיין בשאלות הנפוצות למידע נוסף", "MappedNetworkDrivesWindowsService": "כונני רשת ממופים אינם זמינים כאשר הם פועלים כשירות Windows. אנא עיין בשאלות הנפוצות למידע נוסף",
"DownloadClientSettingsRecentPriority": "עדיפות לקוח", "DownloadClientSettingsRecentPriority": "עדיפות לקוח"
"Paused": "מושהית",
"CheckDownloadClientForDetails": "בדוק את לקוח ההורדות לפרטים נוספים",
"Downloaded": "הורד",
"Pending": "ממתין ל",
"WaitingToImport": "ממתין לייבוא",
"WaitingToProcess": "מחכה לעיבוד"
} }

View file

@ -753,11 +753,5 @@
"Preferred": "पसंदीदा", "Preferred": "पसंदीदा",
"Today": "आज", "Today": "आज",
"MappedNetworkDrivesWindowsService": "विंडोज सर्विस के रूप में चलने पर मैप्ड नेटवर्क ड्राइव उपलब्ध नहीं हैं। अधिक जानकारी के लिए कृपया FAQ देखें", "MappedNetworkDrivesWindowsService": "विंडोज सर्विस के रूप में चलने पर मैप्ड नेटवर्क ड्राइव उपलब्ध नहीं हैं। अधिक जानकारी के लिए कृपया FAQ देखें",
"DownloadClientSettingsRecentPriority": "ग्राहक प्राथमिकता", "DownloadClientSettingsRecentPriority": "ग्राहक प्राथमिकता"
"Downloaded": "डाउनलोड",
"CheckDownloadClientForDetails": "अधिक विवरण के लिए डाउनलोड क्लाइंट की जाँच करें",
"Paused": "रोके गए",
"Pending": "विचाराधीन",
"WaitingToImport": "आयात की प्रतीक्षा में",
"WaitingToProcess": "प्रक्रिया की प्रतीक्षा की जा रही है"
} }

View file

@ -307,6 +307,5 @@
"DeleteSelectedTrackFilesMessageText": "Jeste li sigurni da želite obrisati ovaj profil odgode?", "DeleteSelectedTrackFilesMessageText": "Jeste li sigurni da želite obrisati ovaj profil odgode?",
"AddDelayProfileError": "Neuspješno dodavanje profila odgode, molimo pokušaj ponovno.", "AddDelayProfileError": "Neuspješno dodavanje profila odgode, molimo pokušaj ponovno.",
"Today": "Danas", "Today": "Danas",
"DownloadClientSettingsRecentPriority": "Prioritet Klijenata", "DownloadClientSettingsRecentPriority": "Prioritet Klijenata"
"CheckDownloadClientForDetails": "provjerite klienta za preuzimanje za još detalja"
} }

View file

@ -1229,14 +1229,5 @@
"Today": "Ma", "Today": "Ma",
"DownloadClientSettingsOlderPriority": "Régebbi prioritás", "DownloadClientSettingsOlderPriority": "Régebbi prioritás",
"DownloadClientSettingsRecentPriority": "Legutóbbi prioritás", "DownloadClientSettingsRecentPriority": "Legutóbbi prioritás",
"PostImportCategory": "Import utáni kategória", "PostImportCategory": "Import utáni kategória"
"CheckDownloadClientForDetails": "További részletekért ellenőrizze a letöltési klienst",
"DownloadWarning": "Letöltési figyelmeztetés: {warningMessage}",
"Downloaded": "Letöltve",
"Paused": "Szüneteltetve",
"Pending": "Függőben levő",
"PendingDownloadClientUnavailable": "Függőben A letöltési kliens nem érhető el",
"ImportFailed": "Sikertelen importálás: {sourceTitle}",
"WaitingToImport": "Várakozás importálásra",
"WaitingToProcess": "Várakozás feldolgozásra"
} }

Some files were not shown because too many files have changed in this diff Show more