mirror of
https://github.com/Readarr/Readarr.git
synced 2026-03-29 18:14:28 -04:00
Compare commits
48 Commits
v0.3.11.23
...
v0.3.14.23
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2749479283 | ||
|
|
4cbafa76d8 | ||
|
|
73782cc233 | ||
|
|
de396fe9be | ||
|
|
71cb9e1dd7 | ||
|
|
ee5ed57fcc | ||
|
|
d20a049a5a | ||
|
|
a9f77ace37 | ||
|
|
0341a2ec26 | ||
|
|
d6796bbe1a | ||
|
|
9066f8558c | ||
|
|
c4e37528ee | ||
|
|
5937c952af | ||
|
|
0f4bd3c472 | ||
|
|
cf415e61de | ||
|
|
9865e92cea | ||
|
|
1cf956a9d9 | ||
|
|
8989c55c8c | ||
|
|
dc83e0127e | ||
|
|
34eb312426 | ||
|
|
9d5cdebdb2 | ||
|
|
a0ab224acd | ||
|
|
05aa35a54d | ||
|
|
ca7f8775f5 | ||
|
|
2a01e9b445 | ||
|
|
7d30c7d1ea | ||
|
|
50be87e5a4 | ||
|
|
0572d1ac80 | ||
|
|
d2240514d7 | ||
|
|
ad47dc032d | ||
|
|
6c6df7d7d9 | ||
|
|
2121204064 | ||
|
|
61004ea33f | ||
|
|
54c1c7862e | ||
|
|
43dfdc8bf5 | ||
|
|
0d1ae0ca4e | ||
|
|
9902889a30 | ||
|
|
04d7061030 | ||
|
|
fd201912a9 | ||
|
|
c412701a3d | ||
|
|
7451a66365 | ||
|
|
a6431fdb0b | ||
|
|
060b133f6d | ||
|
|
5ed13b942b | ||
|
|
89f3d8167b | ||
|
|
77b027374f | ||
|
|
650490abb2 | ||
|
|
7d2e215d61 |
@@ -9,13 +9,13 @@ variables:
|
||||
testsFolder: './_tests'
|
||||
yarnCacheFolder: $(Pipeline.Workspace)/.yarn
|
||||
nugetCacheFolder: $(Pipeline.Workspace)/.nuget/packages
|
||||
majorVersion: '0.3.11'
|
||||
majorVersion: '0.3.14'
|
||||
minorVersion: $[counter('minorVersion', 1)]
|
||||
readarrVersion: '$(majorVersion).$(minorVersion)'
|
||||
buildName: '$(Build.SourceBranchName).$(readarrVersion)'
|
||||
sentryOrg: 'servarr'
|
||||
sentryUrl: 'https://sentry.servarr.com'
|
||||
dotnetVersion: '6.0.413'
|
||||
dotnetVersion: '6.0.417'
|
||||
nodeVersion: '16.X'
|
||||
innoVersion: '6.2.0'
|
||||
windowsImage: 'windows-2022'
|
||||
|
||||
@@ -44,6 +44,10 @@
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.filterIcon {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.authorNavigationButtons {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
|
||||
@@ -6,6 +6,7 @@ interface CssExports {
|
||||
'authorUpButton': string;
|
||||
'contentContainer': string;
|
||||
'errorMessage': string;
|
||||
'filterIcon': string;
|
||||
'innerContentBody': string;
|
||||
'metadataMessage': string;
|
||||
'selectedTab': string;
|
||||
|
||||
@@ -239,9 +239,14 @@ class AuthorDetails extends Component {
|
||||
saveError,
|
||||
isDeleting,
|
||||
deleteError,
|
||||
statistics
|
||||
statistics = {}
|
||||
} = this.props;
|
||||
|
||||
const {
|
||||
bookFileCount = 0,
|
||||
totalBookCount = 0
|
||||
} = statistics;
|
||||
|
||||
const {
|
||||
isOrganizeModalOpen,
|
||||
isRetagModalOpen,
|
||||
@@ -435,7 +440,7 @@ class AuthorDetails extends Component {
|
||||
className={styles.tab}
|
||||
selectedClassName={styles.selectedTab}
|
||||
>
|
||||
{translate('BooksTotal', [statistics.totalBookCount])}
|
||||
{translate('BooksTotal', [totalBookCount])}
|
||||
</Tab>
|
||||
|
||||
<Tab
|
||||
@@ -463,7 +468,7 @@ class AuthorDetails extends Component {
|
||||
className={styles.tab}
|
||||
selectedClassName={styles.selectedTab}
|
||||
>
|
||||
{translate('FilesTotal', [statistics.bookFileCount])}
|
||||
{translate('FilesTotal', [bookFileCount])}
|
||||
</Tab>
|
||||
|
||||
{
|
||||
|
||||
@@ -136,8 +136,9 @@
|
||||
}
|
||||
|
||||
.title {
|
||||
font-weight: 300;
|
||||
font-size: 30px;
|
||||
line-height: 50px;
|
||||
line-height: 30px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
import Modal from 'Components/Modal/Modal';
|
||||
import { sizes } from 'Helpers/Props';
|
||||
import AuthorHistoryContentConnector from './AuthorHistoryContentConnector';
|
||||
import AuthorHistoryModalContent from './AuthorHistoryModalContent';
|
||||
|
||||
@@ -14,6 +15,7 @@ function AuthorHistoryModal(props) {
|
||||
return (
|
||||
<Modal
|
||||
isOpen={isOpen}
|
||||
size={sizes.EXTRA_LARGE}
|
||||
onModalClose={onModalClose}
|
||||
>
|
||||
<AuthorHistoryContentConnector
|
||||
|
||||
@@ -5,6 +5,7 @@ import ModalBody from 'Components/Modal/ModalBody';
|
||||
import ModalContent from 'Components/Modal/ModalContent';
|
||||
import ModalFooter from 'Components/Modal/ModalFooter';
|
||||
import ModalHeader from 'Components/Modal/ModalHeader';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import AuthorHistoryTableContent from './AuthorHistoryTableContent';
|
||||
|
||||
class AuthorHistoryModalContent extends Component {
|
||||
@@ -20,7 +21,7 @@ class AuthorHistoryModalContent extends Component {
|
||||
return (
|
||||
<ModalContent onModalClose={onModalClose}>
|
||||
<ModalHeader>
|
||||
History
|
||||
{translate('History')}
|
||||
</ModalHeader>
|
||||
|
||||
<ModalBody>
|
||||
@@ -31,7 +32,7 @@ class AuthorHistoryModalContent extends Component {
|
||||
|
||||
<ModalFooter>
|
||||
<Button onPress={onModalClose}>
|
||||
Close
|
||||
{translate('Close')}
|
||||
</Button>
|
||||
</ModalFooter>
|
||||
</ModalContent>
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.details,
|
||||
.actions {
|
||||
composes: cell from '~Components/Table/Cells/TableRowCell.css';
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
// Please do not change this file!
|
||||
interface CssExports {
|
||||
'actions': string;
|
||||
'details': string;
|
||||
'sourceTitle': string;
|
||||
}
|
||||
export const cssExports: CssExports;
|
||||
|
||||
@@ -2,6 +2,7 @@ import PropTypes from 'prop-types';
|
||||
import React, { Component } from 'react';
|
||||
import HistoryDetailsConnector from 'Activity/History/Details/HistoryDetailsConnector';
|
||||
import HistoryEventTypeCell from 'Activity/History/HistoryEventTypeCell';
|
||||
import BookFormats from 'Book/BookFormats';
|
||||
import BookQuality from 'Book/BookQuality';
|
||||
import Icon from 'Components/Icon';
|
||||
import IconButton from 'Components/Link/IconButton';
|
||||
@@ -11,6 +12,7 @@ import TableRowCell from 'Components/Table/Cells/TableRowCell';
|
||||
import TableRow from 'Components/Table/TableRow';
|
||||
import Popover from 'Components/Tooltip/Popover';
|
||||
import { icons, kinds, tooltipPositions } from 'Helpers/Props';
|
||||
import formatCustomFormatScore from 'Utilities/Number/formatCustomFormatScore';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import styles from './AuthorHistoryRow.css';
|
||||
|
||||
@@ -75,6 +77,8 @@ class AuthorHistoryRow extends Component {
|
||||
sourceTitle,
|
||||
quality,
|
||||
qualityCutoffNotMet,
|
||||
customFormats,
|
||||
customFormatScore,
|
||||
date,
|
||||
data,
|
||||
book
|
||||
@@ -106,11 +110,19 @@ class AuthorHistoryRow extends Component {
|
||||
/>
|
||||
</TableRowCell>
|
||||
|
||||
<TableRowCell>
|
||||
<BookFormats formats={customFormats} />
|
||||
</TableRowCell>
|
||||
|
||||
<TableRowCell>
|
||||
{formatCustomFormatScore(customFormatScore, customFormats.length)}
|
||||
</TableRowCell>
|
||||
|
||||
<RelativeDateCellConnector
|
||||
date={date}
|
||||
/>
|
||||
|
||||
<TableRowCell className={styles.details}>
|
||||
<TableRowCell className={styles.actions}>
|
||||
<Popover
|
||||
anchor={
|
||||
<Icon
|
||||
@@ -127,14 +139,13 @@ class AuthorHistoryRow extends Component {
|
||||
}
|
||||
position={tooltipPositions.LEFT}
|
||||
/>
|
||||
</TableRowCell>
|
||||
|
||||
<TableRowCell className={styles.actions}>
|
||||
{
|
||||
eventType === 'grabbed' &&
|
||||
<IconButton
|
||||
title={translate('MarkAsFailed')}
|
||||
name={icons.REMOVE}
|
||||
size={14}
|
||||
onPress={this.onMarkAsFailedPress}
|
||||
/>
|
||||
}
|
||||
@@ -160,6 +171,8 @@ AuthorHistoryRow.propTypes = {
|
||||
sourceTitle: PropTypes.string.isRequired,
|
||||
quality: PropTypes.object.isRequired,
|
||||
qualityCutoffNotMet: PropTypes.bool.isRequired,
|
||||
customFormats: PropTypes.arrayOf(PropTypes.object),
|
||||
customFormatScore: PropTypes.number.isRequired,
|
||||
date: PropTypes.string.isRequired,
|
||||
data: PropTypes.object.isRequired,
|
||||
fullAuthor: PropTypes.bool.isRequired,
|
||||
|
||||
9
frontend/src/Author/History/AuthorHistoryTable.css
Normal file
9
frontend/src/Author/History/AuthorHistoryTable.css
Normal file
@@ -0,0 +1,9 @@
|
||||
.container {
|
||||
border: 1px solid var(--borderColor);
|
||||
border-radius: 4px;
|
||||
background-color: var(--inputBackgroundColor);
|
||||
|
||||
&:last-of-type {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
7
frontend/src/Author/History/AuthorHistoryTable.css.d.ts
vendored
Normal file
7
frontend/src/Author/History/AuthorHistoryTable.css.d.ts
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
// This file is automatically generated.
|
||||
// Please do not change this file!
|
||||
interface CssExports {
|
||||
'container': string;
|
||||
}
|
||||
export const cssExports: CssExports;
|
||||
export default cssExports;
|
||||
@@ -1,6 +1,7 @@
|
||||
import React from 'react';
|
||||
import AuthorHistoryContentConnector from 'Author/History/AuthorHistoryContentConnector';
|
||||
import AuthorHistoryTableContent from 'Author/History/AuthorHistoryTableContent';
|
||||
import styles from './AuthorHistoryTable.css';
|
||||
|
||||
function AuthorHistoryTable(props) {
|
||||
const {
|
||||
@@ -8,10 +9,12 @@ function AuthorHistoryTable(props) {
|
||||
} = props;
|
||||
|
||||
return (
|
||||
<AuthorHistoryContentConnector
|
||||
component={AuthorHistoryTableContent}
|
||||
{...otherProps}
|
||||
/>
|
||||
<div className={styles.container}>
|
||||
<AuthorHistoryContentConnector
|
||||
component={AuthorHistoryTableContent}
|
||||
{...otherProps}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
.blankpad {
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
padding-left: 2em;
|
||||
}
|
||||
7
frontend/src/Author/History/AuthorHistoryTableContent.css.d.ts
vendored
Normal file
7
frontend/src/Author/History/AuthorHistoryTableContent.css.d.ts
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
// This file is automatically generated.
|
||||
// Please do not change this file!
|
||||
interface CssExports {
|
||||
'blankpad': string;
|
||||
}
|
||||
export const cssExports: CssExports;
|
||||
export default cssExports;
|
||||
@@ -1,12 +1,14 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import React, { Component } from 'react';
|
||||
import Alert from 'Components/Alert';
|
||||
import Icon from 'Components/Icon';
|
||||
import LoadingIndicator from 'Components/Loading/LoadingIndicator';
|
||||
import Table from 'Components/Table/Table';
|
||||
import TableBody from 'Components/Table/TableBody';
|
||||
import { kinds } from 'Helpers/Props';
|
||||
import { icons, kinds } from 'Helpers/Props';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import AuthorHistoryRowConnector from './AuthorHistoryRowConnector';
|
||||
import styles from './AuthorHistoryTableContent.css';
|
||||
|
||||
const columns = [
|
||||
{
|
||||
@@ -15,32 +17,41 @@ const columns = [
|
||||
},
|
||||
{
|
||||
name: 'book',
|
||||
label: 'Book',
|
||||
label: () => translate('Book'),
|
||||
isVisible: true
|
||||
},
|
||||
{
|
||||
name: 'sourceTitle',
|
||||
label: 'Source Title',
|
||||
label: () => translate( 'SourceTitle'),
|
||||
isVisible: true
|
||||
},
|
||||
{
|
||||
name: 'quality',
|
||||
label: 'Quality',
|
||||
label: () => translate('Quality'),
|
||||
isVisible: true
|
||||
},
|
||||
{
|
||||
name: 'customFormats',
|
||||
label: () => translate('CustomFormats'),
|
||||
isSortable: false,
|
||||
isVisible: true
|
||||
},
|
||||
{
|
||||
name: 'customFormatScore',
|
||||
label: React.createElement(Icon, {
|
||||
name: icons.SCORE,
|
||||
title: () => translate('CustomFormatScore')
|
||||
}),
|
||||
isSortable: true,
|
||||
isVisible: true
|
||||
},
|
||||
{
|
||||
name: 'date',
|
||||
label: 'Date',
|
||||
isVisible: true
|
||||
},
|
||||
{
|
||||
name: 'details',
|
||||
label: 'Details',
|
||||
label: () => translate('Date'),
|
||||
isVisible: true
|
||||
},
|
||||
{
|
||||
name: 'actions',
|
||||
label: 'Actions',
|
||||
isVisible: true
|
||||
}
|
||||
];
|
||||
@@ -64,7 +75,7 @@ class AuthorHistoryTableContent extends Component {
|
||||
const hasItems = !!items.length;
|
||||
|
||||
return (
|
||||
<>
|
||||
<div>
|
||||
{
|
||||
isFetching &&
|
||||
<LoadingIndicator />
|
||||
@@ -79,7 +90,7 @@ class AuthorHistoryTableContent extends Component {
|
||||
|
||||
{
|
||||
isPopulated && !hasItems && !error &&
|
||||
<div>
|
||||
<div className={styles.blankpad}>
|
||||
{translate('NoHistory')}
|
||||
</div>
|
||||
}
|
||||
@@ -103,7 +114,7 @@ class AuthorHistoryTableContent extends Component {
|
||||
</TableBody>
|
||||
</Table>
|
||||
}
|
||||
</>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import React from 'react';
|
||||
import Label from 'Components/Label';
|
||||
import { kinds } from 'Helpers/Props';
|
||||
import formatBytes from 'Utilities/Number/formatBytes';
|
||||
import translate from 'Utilities/String/translate';
|
||||
|
||||
function getTooltip(title, quality, size, isMonitored, isCutoffNotMet) {
|
||||
const revision = quality.revision;
|
||||
@@ -28,6 +29,36 @@ function getTooltip(title, quality, size, isMonitored, isCutoffNotMet) {
|
||||
return title;
|
||||
}
|
||||
|
||||
function revisionLabel(className, quality, showRevision) {
|
||||
if (!showRevision) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (quality.revision.isRepack) {
|
||||
return (
|
||||
<Label
|
||||
className={className}
|
||||
kind={kinds.PRIMARY}
|
||||
title={translate('Repack')}
|
||||
>
|
||||
R
|
||||
</Label>
|
||||
);
|
||||
}
|
||||
|
||||
if (quality.revision.version && quality.revision.version > 1) {
|
||||
return (
|
||||
<Label
|
||||
className={className}
|
||||
kind={kinds.PRIMARY}
|
||||
title={translate('Proper')}
|
||||
>
|
||||
P
|
||||
</Label>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function BookQuality(props) {
|
||||
const {
|
||||
className,
|
||||
@@ -35,7 +66,8 @@ function BookQuality(props) {
|
||||
quality,
|
||||
size,
|
||||
isMonitored,
|
||||
isCutoffNotMet
|
||||
isCutoffNotMet,
|
||||
showRevision
|
||||
} = props;
|
||||
|
||||
let kind = kinds.DEFAULT;
|
||||
@@ -50,13 +82,15 @@ function BookQuality(props) {
|
||||
}
|
||||
|
||||
return (
|
||||
<Label
|
||||
className={className}
|
||||
kind={kind}
|
||||
title={getTooltip(title, quality, size, isMonitored, isCutoffNotMet)}
|
||||
>
|
||||
{quality.quality.name}
|
||||
</Label>
|
||||
<span>
|
||||
<Label
|
||||
className={className}
|
||||
kind={kind}
|
||||
title={getTooltip(title, quality, size, isMonitored, isCutoffNotMet)}
|
||||
>
|
||||
{quality.quality.name}
|
||||
</Label>{revisionLabel(className, quality, showRevision)}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -66,12 +100,14 @@ BookQuality.propTypes = {
|
||||
quality: PropTypes.object.isRequired,
|
||||
size: PropTypes.number,
|
||||
isMonitored: PropTypes.bool,
|
||||
isCutoffNotMet: PropTypes.bool
|
||||
isCutoffNotMet: PropTypes.bool,
|
||||
showRevision: PropTypes.bool
|
||||
};
|
||||
|
||||
BookQuality.defaultProps = {
|
||||
title: '',
|
||||
isMonitored: true
|
||||
isMonitored: true,
|
||||
showRevision: false
|
||||
};
|
||||
|
||||
export default BookQuality;
|
||||
|
||||
@@ -99,9 +99,14 @@ class BookDetails extends Component {
|
||||
nextBook,
|
||||
isSearching,
|
||||
onRefreshPress,
|
||||
onSearchPress
|
||||
onSearchPress,
|
||||
statistics = {}
|
||||
} = this.props;
|
||||
|
||||
const {
|
||||
bookFileCount = 0
|
||||
} = statistics;
|
||||
|
||||
const {
|
||||
isOrganizeModalOpen,
|
||||
isRetagModalOpen,
|
||||
@@ -238,21 +243,21 @@ class BookDetails extends Component {
|
||||
className={styles.tab}
|
||||
selectedClassName={styles.selectedTab}
|
||||
>
|
||||
History
|
||||
{translate('History')}
|
||||
</Tab>
|
||||
|
||||
<Tab
|
||||
className={styles.tab}
|
||||
selectedClassName={styles.selectedTab}
|
||||
>
|
||||
Search
|
||||
{translate('Search')}
|
||||
</Tab>
|
||||
|
||||
<Tab
|
||||
className={styles.tab}
|
||||
selectedClassName={styles.selectedTab}
|
||||
>
|
||||
Files
|
||||
{translate('FilesTotal', [bookFileCount])}
|
||||
</Tab>
|
||||
|
||||
{
|
||||
@@ -335,6 +340,7 @@ BookDetails.propTypes = {
|
||||
ratings: PropTypes.object.isRequired,
|
||||
images: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
links: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
statistics: PropTypes.object.isRequired,
|
||||
monitored: PropTypes.bool.isRequired,
|
||||
shortDateFormat: PropTypes.string.isRequired,
|
||||
isSaving: PropTypes.bool.isRequired,
|
||||
|
||||
@@ -117,8 +117,9 @@
|
||||
}
|
||||
|
||||
.title {
|
||||
font-weight: 300;
|
||||
font-size: 30px;
|
||||
line-height: 50px;
|
||||
line-height: 30px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -229,7 +229,6 @@ class BookIndexRow extends Component {
|
||||
className={styles[name]}
|
||||
>
|
||||
{bookFileCount}
|
||||
|
||||
</VirtualTableRowCell>
|
||||
);
|
||||
}
|
||||
|
||||
9
frontend/src/BookFile/Editor/BookFileEditorTable.css
Normal file
9
frontend/src/BookFile/Editor/BookFileEditorTable.css
Normal file
@@ -0,0 +1,9 @@
|
||||
.container {
|
||||
border: 1px solid var(--borderColor);
|
||||
border-radius: 4px;
|
||||
background-color: var(--inputBackgroundColor);
|
||||
|
||||
&:last-of-type {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
7
frontend/src/BookFile/Editor/BookFileEditorTable.css.d.ts
vendored
Normal file
7
frontend/src/BookFile/Editor/BookFileEditorTable.css.d.ts
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
// This file is automatically generated.
|
||||
// Please do not change this file!
|
||||
interface CssExports {
|
||||
'container': string;
|
||||
}
|
||||
export const cssExports: CssExports;
|
||||
export default cssExports;
|
||||
@@ -1,5 +1,6 @@
|
||||
import React from 'react';
|
||||
import BookFileEditorTableContentConnector from './BookFileEditorTableContentConnector';
|
||||
import styles from './BookFileEditorTable.css';
|
||||
|
||||
function BookFileEditorTable(props) {
|
||||
const {
|
||||
@@ -7,9 +8,11 @@ function BookFileEditorTable(props) {
|
||||
} = props;
|
||||
|
||||
return (
|
||||
<BookFileEditorTableContentConnector
|
||||
{...otherProps}
|
||||
/>
|
||||
<div className={styles.container}>
|
||||
<BookFileEditorTableContentConnector
|
||||
{...otherProps}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.filesTable {
|
||||
margin-bottom: 20px;
|
||||
padding-top: 15px;
|
||||
margin: 10px;
|
||||
padding-top: 5px;
|
||||
border: 1px solid var(--borderColor);
|
||||
border-top: 1px solid var(--borderColor);
|
||||
border-radius: 4px;
|
||||
@@ -13,9 +13,15 @@
|
||||
|
||||
.actions {
|
||||
display: flex;
|
||||
margin-right: auto;
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
.selectInput {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.blankpad {
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
padding-left: 2em;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// Please do not change this file!
|
||||
interface CssExports {
|
||||
'actions': string;
|
||||
'blankpad': string;
|
||||
'filesTable': string;
|
||||
'selectInput': string;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import _ from 'lodash';
|
||||
import PropTypes from 'prop-types';
|
||||
import React, { Component } from 'react';
|
||||
import Alert from 'Components/Alert';
|
||||
import SelectInput from 'Components/Form/SelectInput';
|
||||
import SpinnerButton from 'Components/Link/SpinnerButton';
|
||||
import LoadingIndicator from 'Components/Loading/LoadingIndicator';
|
||||
@@ -120,7 +121,7 @@ class BookFileEditorTableContent extends Component {
|
||||
const hasSelectedFiles = this.getSelectedIds().length > 0;
|
||||
|
||||
return (
|
||||
<>
|
||||
<div>
|
||||
{
|
||||
isFetching && !isPopulated ?
|
||||
<LoadingIndicator /> :
|
||||
@@ -129,13 +130,13 @@ class BookFileEditorTableContent extends Component {
|
||||
|
||||
{
|
||||
!isFetching && error ?
|
||||
<div>{error}</div> :
|
||||
<Alert kind={kinds.DANGER}>{error}</Alert> :
|
||||
null
|
||||
}
|
||||
|
||||
{
|
||||
isPopulated && !items.length ?
|
||||
<div>
|
||||
<div className={styles.blankpad}>
|
||||
No book files to manage.
|
||||
</div> :
|
||||
null
|
||||
@@ -173,26 +174,30 @@ class BookFileEditorTableContent extends Component {
|
||||
null
|
||||
}
|
||||
|
||||
<div className={styles.actions}>
|
||||
<SpinnerButton
|
||||
kind={kinds.DANGER}
|
||||
isSpinning={isDeleting}
|
||||
isDisabled={!hasSelectedFiles}
|
||||
onPress={this.onDeletePress}
|
||||
>
|
||||
Delete
|
||||
</SpinnerButton>
|
||||
{
|
||||
isPopulated && items.length ? (
|
||||
<div className={styles.actions}>
|
||||
<SpinnerButton
|
||||
kind={kinds.DANGER}
|
||||
isSpinning={isDeleting}
|
||||
isDisabled={!hasSelectedFiles}
|
||||
onPress={this.onDeletePress}
|
||||
>
|
||||
{translate('Delete')}
|
||||
</SpinnerButton>
|
||||
|
||||
<div className={styles.selectInput}>
|
||||
<SelectInput
|
||||
name="quality"
|
||||
value="selectQuality"
|
||||
values={qualityOptions}
|
||||
isDisabled={!hasSelectedFiles}
|
||||
onChange={this.onQualityChange}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles.selectInput}>
|
||||
<SelectInput
|
||||
name="quality"
|
||||
value="selectQuality"
|
||||
values={qualityOptions}
|
||||
isDisabled={!hasSelectedFiles}
|
||||
onChange={this.onQualityChange}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
) : null
|
||||
}
|
||||
|
||||
<ConfirmModal
|
||||
isOpen={isConfirmDeleteModalOpen}
|
||||
@@ -203,7 +208,7 @@ class BookFileEditorTableContent extends Component {
|
||||
onConfirm={this.onConfirmDelete}
|
||||
onCancel={this.onConfirmDeleteModalClose}
|
||||
/>
|
||||
</>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ class CalendarConnector extends Component {
|
||||
gotoCalendarToday
|
||||
} = this.props;
|
||||
|
||||
registerPagePopulator(this.repopulate);
|
||||
registerPagePopulator(this.repopulate, ['bookFileUpdated', 'bookFileDeleted']);
|
||||
|
||||
if (useCurrentPage) {
|
||||
fetchCalendar();
|
||||
|
||||
@@ -202,6 +202,8 @@ class SignalRConnector extends Component {
|
||||
this.props.dispatchUpdateItem({ section, ...body.resource });
|
||||
} else if (body.action === 'deleted') {
|
||||
this.props.dispatchRemoveItem({ section, id: body.resource.id });
|
||||
|
||||
repopulatePage('bookFileDeleted');
|
||||
}
|
||||
|
||||
// Repopulate the page to handle recently imported file
|
||||
|
||||
@@ -15,5 +15,5 @@
|
||||
"start_url": "../../../../",
|
||||
"theme_color": "#3a3f51",
|
||||
"background_color": "#3a3f51",
|
||||
"display": "standalone"
|
||||
"display": "minimal-ui"
|
||||
}
|
||||
|
||||
@@ -28,6 +28,10 @@
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.quality {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.customFormatScore {
|
||||
composes: cell from '~Components/Table/Cells/TableRowCell.css';
|
||||
|
||||
|
||||
@@ -178,7 +178,7 @@ class InteractiveSearchRow extends Component {
|
||||
</TableRowCell>
|
||||
|
||||
<TableRowCell className={styles.quality}>
|
||||
<BookQuality quality={quality} />
|
||||
<BookQuality quality={quality} showRevision={true} />
|
||||
</TableRowCell>
|
||||
|
||||
<TableRowCell className={styles.customFormatScore}>
|
||||
|
||||
@@ -14,9 +14,11 @@ import Table from 'Components/Table/Table';
|
||||
import TableBody from 'Components/Table/TableBody';
|
||||
import useSelectState from 'Helpers/Hooks/useSelectState';
|
||||
import { kinds } from 'Helpers/Props';
|
||||
import SortDirection from 'Helpers/Props/SortDirection';
|
||||
import {
|
||||
bulkDeleteDownloadClients,
|
||||
bulkEditDownloadClients,
|
||||
setManageDownloadClientsSort,
|
||||
} from 'Store/Actions/settingsActions';
|
||||
import createClientSideCollectionSelector from 'Store/Selectors/createClientSideCollectionSelector';
|
||||
import { SelectStateInputProps } from 'typings/props';
|
||||
@@ -80,6 +82,8 @@ const COLUMNS = [
|
||||
|
||||
interface ManageDownloadClientsModalContentProps {
|
||||
onModalClose(): void;
|
||||
sortKey?: string;
|
||||
sortDirection?: SortDirection;
|
||||
}
|
||||
|
||||
function ManageDownloadClientsModalContent(
|
||||
@@ -94,6 +98,8 @@ function ManageDownloadClientsModalContent(
|
||||
isSaving,
|
||||
error,
|
||||
items,
|
||||
sortKey,
|
||||
sortDirection,
|
||||
}: DownloadClientAppState = useSelector(
|
||||
createClientSideCollectionSelector('settings.downloadClients')
|
||||
);
|
||||
@@ -114,6 +120,13 @@ function ManageDownloadClientsModalContent(
|
||||
|
||||
const selectedCount = selectedIds.length;
|
||||
|
||||
const onSortPress = useCallback(
|
||||
(value: string) => {
|
||||
dispatch(setManageDownloadClientsSort({ sortKey: value }));
|
||||
},
|
||||
[dispatch]
|
||||
);
|
||||
|
||||
const onDeletePress = useCallback(() => {
|
||||
setIsDeleteModalOpen(true);
|
||||
}, [setIsDeleteModalOpen]);
|
||||
@@ -219,6 +232,9 @@ function ManageDownloadClientsModalContent(
|
||||
allSelected={allSelected}
|
||||
allUnselected={allUnselected}
|
||||
onSelectAllChange={onSelectAllChange}
|
||||
sortKey={sortKey}
|
||||
sortDirection={sortDirection}
|
||||
onSortPress={onSortPress}
|
||||
>
|
||||
<TableBody>
|
||||
{items.map((item) => {
|
||||
|
||||
@@ -8,11 +8,13 @@
|
||||
}
|
||||
|
||||
.name {
|
||||
flex: 1 0 300px;
|
||||
@add-mixin truncate;
|
||||
|
||||
flex: 0 1 600px;
|
||||
}
|
||||
|
||||
.foreignId {
|
||||
flex: 0 0 200px;
|
||||
flex: 0 0 100px;
|
||||
}
|
||||
|
||||
.actions {
|
||||
|
||||
@@ -4,12 +4,12 @@
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.foreignId {
|
||||
flex: 0 0 200px;
|
||||
.name {
|
||||
flex: 0 1 600px;
|
||||
}
|
||||
|
||||
.name {
|
||||
flex: 1 0 300px;
|
||||
.foreignId {
|
||||
flex: 0 0 100px;
|
||||
}
|
||||
|
||||
.addImportListExclusion {
|
||||
|
||||
@@ -14,9 +14,11 @@ import Table from 'Components/Table/Table';
|
||||
import TableBody from 'Components/Table/TableBody';
|
||||
import useSelectState from 'Helpers/Hooks/useSelectState';
|
||||
import { kinds } from 'Helpers/Props';
|
||||
import SortDirection from 'Helpers/Props/SortDirection';
|
||||
import {
|
||||
bulkDeleteIndexers,
|
||||
bulkEditIndexers,
|
||||
setManageIndexersSort,
|
||||
} from 'Store/Actions/settingsActions';
|
||||
import createClientSideCollectionSelector from 'Store/Selectors/createClientSideCollectionSelector';
|
||||
import { SelectStateInputProps } from 'typings/props';
|
||||
@@ -80,6 +82,8 @@ const COLUMNS = [
|
||||
|
||||
interface ManageIndexersModalContentProps {
|
||||
onModalClose(): void;
|
||||
sortKey?: string;
|
||||
sortDirection?: SortDirection;
|
||||
}
|
||||
|
||||
function ManageIndexersModalContent(props: ManageIndexersModalContentProps) {
|
||||
@@ -92,6 +96,8 @@ function ManageIndexersModalContent(props: ManageIndexersModalContentProps) {
|
||||
isSaving,
|
||||
error,
|
||||
items,
|
||||
sortKey,
|
||||
sortDirection,
|
||||
}: IndexerAppState = useSelector(
|
||||
createClientSideCollectionSelector('settings.indexers')
|
||||
);
|
||||
@@ -112,6 +118,13 @@ function ManageIndexersModalContent(props: ManageIndexersModalContentProps) {
|
||||
|
||||
const selectedCount = selectedIds.length;
|
||||
|
||||
const onSortPress = useCallback(
|
||||
(value: string) => {
|
||||
dispatch(setManageIndexersSort({ sortKey: value }));
|
||||
},
|
||||
[dispatch]
|
||||
);
|
||||
|
||||
const onDeletePress = useCallback(() => {
|
||||
setIsDeleteModalOpen(true);
|
||||
}, [setIsDeleteModalOpen]);
|
||||
@@ -214,6 +227,9 @@ function ManageIndexersModalContent(props: ManageIndexersModalContentProps) {
|
||||
allSelected={allSelected}
|
||||
allUnselected={allUnselected}
|
||||
onSelectAllChange={onSelectAllChange}
|
||||
sortKey={sortKey}
|
||||
sortDirection={sortDirection}
|
||||
onSortPress={onSortPress}
|
||||
>
|
||||
<TableBody>
|
||||
{items.map((item) => {
|
||||
|
||||
@@ -212,26 +212,24 @@ class MediaManagement extends Component {
|
||||
</FormGroup>
|
||||
|
||||
{
|
||||
settings.importExtraFiles.value &&
|
||||
settings.importExtraFiles.value ?
|
||||
<FormGroup
|
||||
advancedSettings={advancedSettings}
|
||||
isAdvanced={true}
|
||||
>
|
||||
<FormLabel>
|
||||
{translate('ImportExtraFiles')}
|
||||
</FormLabel>
|
||||
<FormLabel>{translate('ImportExtraFiles')}</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.TEXT}
|
||||
name="extraFileExtensions"
|
||||
helpTexts={[
|
||||
translate('ExtraFileExtensionsHelpTexts1'),
|
||||
translate('ExtraFileExtensionsHelpTexts2')
|
||||
translate('ExtraFileExtensionsHelpText'),
|
||||
translate('ExtraFileExtensionsHelpTextsExamples')
|
||||
]}
|
||||
onChange={onInputChange}
|
||||
{...settings.extraFileExtensions}
|
||||
/>
|
||||
</FormGroup>
|
||||
</FormGroup> : null
|
||||
}
|
||||
</FieldSet>
|
||||
}
|
||||
|
||||
@@ -223,6 +223,13 @@ class UISettings extends Component {
|
||||
helpTextWarning={translate('UILanguageHelpTextWarning')}
|
||||
onChange={onInputChange}
|
||||
{...settings.uiLanguage}
|
||||
errors={
|
||||
languages.some((language) => language.key === settings.uiLanguage.value) ?
|
||||
settings.uiLanguage.errors :
|
||||
[
|
||||
...settings.uiLanguage.errors,
|
||||
{ message: translate('InvalidUILanguage') }
|
||||
]}
|
||||
/>
|
||||
</FormGroup>
|
||||
</FieldSet>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { createAction } from 'redux-actions';
|
||||
import { sortDirections } from 'Helpers/Props';
|
||||
import createBulkEditItemHandler from 'Store/Actions/Creators/createBulkEditItemHandler';
|
||||
import createBulkRemoveItemHandler from 'Store/Actions/Creators/createBulkRemoveItemHandler';
|
||||
import createFetchHandler from 'Store/Actions/Creators/createFetchHandler';
|
||||
@@ -7,6 +8,7 @@ import createRemoveItemHandler from 'Store/Actions/Creators/createRemoveItemHand
|
||||
import createSaveProviderHandler, { createCancelSaveProviderHandler } from 'Store/Actions/Creators/createSaveProviderHandler';
|
||||
import createTestAllProvidersHandler from 'Store/Actions/Creators/createTestAllProvidersHandler';
|
||||
import createTestProviderHandler, { createCancelTestProviderHandler } from 'Store/Actions/Creators/createTestProviderHandler';
|
||||
import createSetClientSideCollectionSortReducer from 'Store/Actions/Creators/Reducers/createSetClientSideCollectionSortReducer';
|
||||
import createSetProviderFieldValueReducer from 'Store/Actions/Creators/Reducers/createSetProviderFieldValueReducer';
|
||||
import createSetSettingValueReducer from 'Store/Actions/Creators/Reducers/createSetSettingValueReducer';
|
||||
import { createThunk } from 'Store/thunks';
|
||||
@@ -33,6 +35,7 @@ export const CANCEL_TEST_DOWNLOAD_CLIENT = 'settings/downloadClients/cancelTestD
|
||||
export const TEST_ALL_DOWNLOAD_CLIENTS = 'settings/downloadClients/testAllDownloadClients';
|
||||
export const BULK_EDIT_DOWNLOAD_CLIENTS = 'settings/downloadClients/bulkEditDownloadClients';
|
||||
export const BULK_DELETE_DOWNLOAD_CLIENTS = 'settings/downloadClients/bulkDeleteDownloadClients';
|
||||
export const SET_MANAGE_DOWNLOAD_CLIENTS_SORT = 'settings/downloadClients/setManageDownloadClientsSort';
|
||||
|
||||
//
|
||||
// Action Creators
|
||||
@@ -49,6 +52,7 @@ export const cancelTestDownloadClient = createThunk(CANCEL_TEST_DOWNLOAD_CLIENT)
|
||||
export const testAllDownloadClients = createThunk(TEST_ALL_DOWNLOAD_CLIENTS);
|
||||
export const bulkEditDownloadClients = createThunk(BULK_EDIT_DOWNLOAD_CLIENTS);
|
||||
export const bulkDeleteDownloadClients = createThunk(BULK_DELETE_DOWNLOAD_CLIENTS);
|
||||
export const setManageDownloadClientsSort = createAction(SET_MANAGE_DOWNLOAD_CLIENTS_SORT);
|
||||
|
||||
export const setDownloadClientValue = createAction(SET_DOWNLOAD_CLIENT_VALUE, (payload) => {
|
||||
return {
|
||||
@@ -88,7 +92,9 @@ export default {
|
||||
isTesting: false,
|
||||
isTestingAll: false,
|
||||
items: [],
|
||||
pendingChanges: {}
|
||||
pendingChanges: {},
|
||||
sortKey: 'name',
|
||||
sortDirection: sortDirections.DESCENDING
|
||||
},
|
||||
|
||||
//
|
||||
@@ -121,7 +127,10 @@ export default {
|
||||
|
||||
return selectedSchema;
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
[SET_MANAGE_DOWNLOAD_CLIENTS_SORT]: createSetClientSideCollectionSortReducer(section)
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { createAction } from 'redux-actions';
|
||||
import { sortDirections } from 'Helpers/Props';
|
||||
import createBulkEditItemHandler from 'Store/Actions/Creators/createBulkEditItemHandler';
|
||||
import createBulkRemoveItemHandler from 'Store/Actions/Creators/createBulkRemoveItemHandler';
|
||||
import createFetchHandler from 'Store/Actions/Creators/createFetchHandler';
|
||||
@@ -7,6 +8,7 @@ import createRemoveItemHandler from 'Store/Actions/Creators/createRemoveItemHand
|
||||
import createSaveProviderHandler, { createCancelSaveProviderHandler } from 'Store/Actions/Creators/createSaveProviderHandler';
|
||||
import createTestAllProvidersHandler from 'Store/Actions/Creators/createTestAllProvidersHandler';
|
||||
import createTestProviderHandler, { createCancelTestProviderHandler } from 'Store/Actions/Creators/createTestProviderHandler';
|
||||
import createSetClientSideCollectionSortReducer from 'Store/Actions/Creators/Reducers/createSetClientSideCollectionSortReducer';
|
||||
import createSetProviderFieldValueReducer from 'Store/Actions/Creators/Reducers/createSetProviderFieldValueReducer';
|
||||
import createSetSettingValueReducer from 'Store/Actions/Creators/Reducers/createSetSettingValueReducer';
|
||||
import { createThunk } from 'Store/thunks';
|
||||
@@ -36,6 +38,7 @@ export const CANCEL_TEST_INDEXER = 'settings/indexers/cancelTestIndexer';
|
||||
export const TEST_ALL_INDEXERS = 'settings/indexers/testAllIndexers';
|
||||
export const BULK_EDIT_INDEXERS = 'settings/indexers/bulkEditIndexers';
|
||||
export const BULK_DELETE_INDEXERS = 'settings/indexers/bulkDeleteIndexers';
|
||||
export const SET_MANAGE_INDEXERS_SORT = 'settings/indexers/setManageIndexersSort';
|
||||
|
||||
//
|
||||
// Action Creators
|
||||
@@ -53,6 +56,7 @@ export const cancelTestIndexer = createThunk(CANCEL_TEST_INDEXER);
|
||||
export const testAllIndexers = createThunk(TEST_ALL_INDEXERS);
|
||||
export const bulkEditIndexers = createThunk(BULK_EDIT_INDEXERS);
|
||||
export const bulkDeleteIndexers = createThunk(BULK_DELETE_INDEXERS);
|
||||
export const setManageIndexersSort = createAction(SET_MANAGE_INDEXERS_SORT);
|
||||
|
||||
export const setIndexerValue = createAction(SET_INDEXER_VALUE, (payload) => {
|
||||
return {
|
||||
@@ -92,7 +96,9 @@ export default {
|
||||
isTesting: false,
|
||||
isTestingAll: false,
|
||||
items: [],
|
||||
pendingChanges: {}
|
||||
pendingChanges: {},
|
||||
sortKey: 'name',
|
||||
sortDirection: sortDirections.DESCENDING
|
||||
},
|
||||
|
||||
//
|
||||
@@ -151,7 +157,10 @@ export default {
|
||||
};
|
||||
|
||||
return updateSectionState(state, section, newState);
|
||||
}
|
||||
},
|
||||
|
||||
[SET_MANAGE_INDEXERS_SORT]: createSetClientSideCollectionSortReducer(section)
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@@ -41,6 +41,14 @@ export const defaultState = {
|
||||
},
|
||||
|
||||
columns: [
|
||||
{
|
||||
name: 'select',
|
||||
columnLabel: 'Select',
|
||||
isSortable: false,
|
||||
isVisible: true,
|
||||
isModifiable: false,
|
||||
isHidden: true
|
||||
},
|
||||
{
|
||||
name: 'path',
|
||||
label: 'Path',
|
||||
|
||||
@@ -158,7 +158,7 @@ export const defaultState = {
|
||||
bookFileCount: function(item) {
|
||||
const { statistics = {} } = item;
|
||||
|
||||
return statistics.bookCount || 0;
|
||||
return statistics.bookFileCount || 0;
|
||||
},
|
||||
|
||||
ratings: function(item) {
|
||||
|
||||
@@ -84,11 +84,6 @@ export const defaultState = {
|
||||
label: 'Source Title',
|
||||
isVisible: false
|
||||
},
|
||||
{
|
||||
name: 'sourceTitle',
|
||||
label: 'Source Title',
|
||||
isVisible: false
|
||||
},
|
||||
{
|
||||
name: 'customFormatScore',
|
||||
columnLabel: 'Custom Format Score',
|
||||
|
||||
@@ -5,6 +5,7 @@ import { sortDirections } from 'Helpers/Props';
|
||||
import { createThunk, handleThunks } from 'Store/thunks';
|
||||
import createAjaxRequest from 'Utilities/createAjaxRequest';
|
||||
import updateSectionState from 'Utilities/State/updateSectionState';
|
||||
import naturalExpansion from 'Utilities/String/naturalExpansion';
|
||||
import { set, update, updateItem } from './baseActions';
|
||||
import createFetchHandler from './Creators/createFetchHandler';
|
||||
import createHandleActions from './Creators/createHandleActions';
|
||||
@@ -17,6 +18,7 @@ export const section = 'interactiveImport';
|
||||
|
||||
const booksSection = `${section}.books`;
|
||||
const bookFilesSection = `${section}.bookFiles`;
|
||||
let abortCurrentFetchRequest = null;
|
||||
let abortCurrentRequest = null;
|
||||
let currentIds = [];
|
||||
|
||||
@@ -32,15 +34,17 @@ export const defaultState = {
|
||||
error: null,
|
||||
items: [],
|
||||
pendingChanges: {},
|
||||
sortKey: 'quality',
|
||||
sortDirection: sortDirections.DESCENDING,
|
||||
sortKey: 'path',
|
||||
sortDirection: sortDirections.ASCENDING,
|
||||
secondarySortKey: 'path',
|
||||
secondarySortDirection: sortDirections.ASCENDING,
|
||||
recentFolders: [],
|
||||
importMode: 'chooseImportMode',
|
||||
sortPredicates: {
|
||||
path: function(item, direction) {
|
||||
const path = item.path;
|
||||
|
||||
return path.toLowerCase();
|
||||
return naturalExpansion(path.toLowerCase());
|
||||
},
|
||||
|
||||
author: function(item, direction) {
|
||||
@@ -74,6 +78,8 @@ export const defaultState = {
|
||||
};
|
||||
|
||||
export const persistState = [
|
||||
'interactiveImport.sortKey',
|
||||
'interactiveImport.sortDirection',
|
||||
'interactiveImport.recentFolders',
|
||||
'interactiveImport.importMode'
|
||||
];
|
||||
@@ -122,6 +128,11 @@ export const clearInteractiveImportBookFiles = createAction(CLEAR_INTERACTIVE_IM
|
||||
// Action Handlers
|
||||
export const actionHandlers = handleThunks({
|
||||
[FETCH_INTERACTIVE_IMPORT_ITEMS]: function(getState, payload, dispatch) {
|
||||
if (abortCurrentFetchRequest) {
|
||||
abortCurrentFetchRequest();
|
||||
abortCurrentFetchRequest = null;
|
||||
}
|
||||
|
||||
if (!payload.downloadId && !payload.folder) {
|
||||
dispatch(set({ section, error: { message: '`downloadId` or `folder` is required.' } }));
|
||||
return;
|
||||
@@ -129,12 +140,14 @@ export const actionHandlers = handleThunks({
|
||||
|
||||
dispatch(set({ section, isFetching: true }));
|
||||
|
||||
const promise = createAjaxRequest({
|
||||
const { request, abortRequest } = createAjaxRequest({
|
||||
url: '/manualimport',
|
||||
data: payload
|
||||
}).request;
|
||||
});
|
||||
|
||||
promise.done((data) => {
|
||||
abortCurrentFetchRequest = abortRequest;
|
||||
|
||||
request.done((data) => {
|
||||
dispatch(batchActions([
|
||||
update({ section, data }),
|
||||
|
||||
@@ -147,7 +160,11 @@ export const actionHandlers = handleThunks({
|
||||
]));
|
||||
});
|
||||
|
||||
promise.fail((xhr) => {
|
||||
request.fail((xhr) => {
|
||||
if (xhr.aborted) {
|
||||
return;
|
||||
}
|
||||
|
||||
dispatch(set({
|
||||
section,
|
||||
isFetching: false,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import React, { Component } from 'react';
|
||||
import Alert from 'Components/Alert';
|
||||
import LoadingIndicator from 'Components/Loading/LoadingIndicator';
|
||||
import PageContent from 'Components/Page/PageContent';
|
||||
import PageContentBody from 'Components/Page/PageContentBody';
|
||||
@@ -9,8 +10,12 @@ import PageToolbarSection from 'Components/Page/Toolbar/PageToolbarSection';
|
||||
import TableOptionsModalWrapper from 'Components/Table/TableOptions/TableOptionsModalWrapper';
|
||||
import VirtualTable from 'Components/Table/VirtualTable';
|
||||
import VirtualTableRow from 'Components/Table/VirtualTableRow';
|
||||
import { align, icons, sortDirections } from 'Helpers/Props';
|
||||
import { align, icons, kinds, sortDirections } from 'Helpers/Props';
|
||||
import hasDifferentItemsOrOrder from 'Utilities/Object/hasDifferentItemsOrOrder';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import getSelectedIds from 'Utilities/Table/getSelectedIds';
|
||||
import selectAll from 'Utilities/Table/selectAll';
|
||||
import toggleSelected from 'Utilities/Table/toggleSelected';
|
||||
import UnmappedFilesTableHeader from './UnmappedFilesTableHeader';
|
||||
import UnmappedFilesTableRow from './UnmappedFilesTableRow';
|
||||
|
||||
@@ -23,10 +28,43 @@ class UnmappedFilesTable extends Component {
|
||||
super(props, context);
|
||||
|
||||
this.state = {
|
||||
scroller: null
|
||||
scroller: null,
|
||||
allSelected: false,
|
||||
allUnselected: false,
|
||||
lastToggled: null,
|
||||
selectedState: {}
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.setSelectedState();
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
const {
|
||||
items,
|
||||
sortKey,
|
||||
sortDirection,
|
||||
isDeleting,
|
||||
deleteError
|
||||
} = this.props;
|
||||
|
||||
if (sortKey !== prevProps.sortKey ||
|
||||
sortDirection !== prevProps.sortDirection ||
|
||||
hasDifferentItemsOrOrder(prevProps.items, items)
|
||||
) {
|
||||
this.setSelectedState();
|
||||
}
|
||||
|
||||
const hasFinishedDeleting = prevProps.isDeleting &&
|
||||
!isDeleting &&
|
||||
!deleteError;
|
||||
|
||||
if (hasFinishedDeleting) {
|
||||
this.onSelectAllChange({ value: false });
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Control
|
||||
|
||||
@@ -34,6 +72,68 @@ class UnmappedFilesTable extends Component {
|
||||
this.setState({ scroller: ref });
|
||||
};
|
||||
|
||||
getSelectedIds = () => {
|
||||
if (this.state.allUnselected) {
|
||||
return [];
|
||||
}
|
||||
return getSelectedIds(this.state.selectedState);
|
||||
};
|
||||
|
||||
setSelectedState() {
|
||||
const {
|
||||
items
|
||||
} = this.props;
|
||||
|
||||
const {
|
||||
selectedState
|
||||
} = this.state;
|
||||
|
||||
const newSelectedState = {};
|
||||
|
||||
items.forEach((file) => {
|
||||
const isItemSelected = selectedState[file.id];
|
||||
|
||||
if (isItemSelected) {
|
||||
newSelectedState[file.id] = isItemSelected;
|
||||
} else {
|
||||
newSelectedState[file.id] = false;
|
||||
}
|
||||
});
|
||||
|
||||
const selectedCount = getSelectedIds(newSelectedState).length;
|
||||
const newStateCount = Object.keys(newSelectedState).length;
|
||||
let isAllSelected = false;
|
||||
let isAllUnselected = false;
|
||||
|
||||
if (selectedCount === 0) {
|
||||
isAllUnselected = true;
|
||||
} else if (selectedCount === newStateCount) {
|
||||
isAllSelected = true;
|
||||
}
|
||||
|
||||
this.setState({ selectedState: newSelectedState, allSelected: isAllSelected, allUnselected: isAllUnselected });
|
||||
}
|
||||
|
||||
onSelectAllChange = ({ value }) => {
|
||||
this.setState(selectAll(this.state.selectedState, value));
|
||||
};
|
||||
|
||||
onSelectAllPress = () => {
|
||||
this.onSelectAllChange({ value: !this.state.allSelected });
|
||||
};
|
||||
|
||||
onSelectedChange = ({ id, value, shiftKey = false }) => {
|
||||
this.setState((state) => {
|
||||
return toggleSelected(state, this.props.items, id, value, shiftKey);
|
||||
});
|
||||
};
|
||||
|
||||
onDeleteUnmappedFilesPress = () => {
|
||||
const selectedIds = this.getSelectedIds();
|
||||
|
||||
this.props.deleteUnmappedFiles(selectedIds);
|
||||
};
|
||||
|
||||
rowRenderer = ({ key, rowIndex, style }) => {
|
||||
const {
|
||||
items,
|
||||
@@ -41,6 +141,10 @@ class UnmappedFilesTable extends Component {
|
||||
deleteUnmappedFile
|
||||
} = this.props;
|
||||
|
||||
const {
|
||||
selectedState
|
||||
} = this.state;
|
||||
|
||||
const item = items[rowIndex];
|
||||
|
||||
return (
|
||||
@@ -51,6 +155,8 @@ class UnmappedFilesTable extends Component {
|
||||
<UnmappedFilesTableRow
|
||||
key={item.id}
|
||||
columns={columns}
|
||||
isSelected={selectedState[item.id]}
|
||||
onSelectedChange={this.onSelectedChange}
|
||||
deleteUnmappedFile={deleteUnmappedFile}
|
||||
{...item}
|
||||
/>
|
||||
@@ -63,6 +169,7 @@ class UnmappedFilesTable extends Component {
|
||||
const {
|
||||
isFetching,
|
||||
isPopulated,
|
||||
isDeleting,
|
||||
error,
|
||||
items,
|
||||
columns,
|
||||
@@ -72,13 +179,19 @@ class UnmappedFilesTable extends Component {
|
||||
onSortPress,
|
||||
isScanningFolders,
|
||||
onAddMissingAuthorsPress,
|
||||
deleteUnmappedFiles,
|
||||
...otherProps
|
||||
} = this.props;
|
||||
|
||||
const {
|
||||
scroller
|
||||
scroller,
|
||||
allSelected,
|
||||
allUnselected,
|
||||
selectedState
|
||||
} = this.state;
|
||||
|
||||
const selectedTrackFileIds = this.getSelectedIds();
|
||||
|
||||
return (
|
||||
<PageContent title={translate('UnmappedFiles')}>
|
||||
<PageToolbar>
|
||||
@@ -90,6 +203,13 @@ class UnmappedFilesTable extends Component {
|
||||
isSpinning={isScanningFolders}
|
||||
onPress={onAddMissingAuthorsPress}
|
||||
/>
|
||||
<PageToolbarButton
|
||||
label={translate('DeleteSelected')}
|
||||
iconName={icons.DELETE}
|
||||
isDisabled={selectedTrackFileIds.length === 0}
|
||||
isSpinning={isDeleting}
|
||||
onPress={this.onDeleteUnmappedFilesPress}
|
||||
/>
|
||||
</PageToolbarSection>
|
||||
|
||||
<PageToolbarSection alignContent={align.RIGHT}>
|
||||
@@ -117,9 +237,9 @@ class UnmappedFilesTable extends Component {
|
||||
|
||||
{
|
||||
isPopulated && !error && !items.length &&
|
||||
<div>
|
||||
<Alert kind={kinds.INFO}>
|
||||
Success! My work is done, all files on disk are matched to known books.
|
||||
</div>
|
||||
</Alert>
|
||||
}
|
||||
|
||||
{
|
||||
@@ -138,8 +258,12 @@ class UnmappedFilesTable extends Component {
|
||||
sortDirection={sortDirection}
|
||||
onTableOptionChange={onTableOptionChange}
|
||||
onSortPress={onSortPress}
|
||||
allSelected={allSelected}
|
||||
allUnselected={allUnselected}
|
||||
onSelectAllChange={this.onSelectAllChange}
|
||||
/>
|
||||
}
|
||||
selectedState={selectedState}
|
||||
sortKey={sortKey}
|
||||
sortDirection={sortDirection}
|
||||
/>
|
||||
@@ -153,6 +277,8 @@ class UnmappedFilesTable extends Component {
|
||||
UnmappedFilesTable.propTypes = {
|
||||
isFetching: PropTypes.bool.isRequired,
|
||||
isPopulated: PropTypes.bool.isRequired,
|
||||
isDeleting: PropTypes.bool.isRequired,
|
||||
deleteError: PropTypes.object,
|
||||
error: PropTypes.object,
|
||||
items: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
columns: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
@@ -161,6 +287,7 @@ UnmappedFilesTable.propTypes = {
|
||||
onTableOptionChange: PropTypes.func.isRequired,
|
||||
onSortPress: PropTypes.func.isRequired,
|
||||
deleteUnmappedFile: PropTypes.func.isRequired,
|
||||
deleteUnmappedFiles: PropTypes.func.isRequired,
|
||||
isScanningFolders: PropTypes.bool.isRequired,
|
||||
onAddMissingAuthorsPress: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
@@ -5,7 +5,7 @@ import { connect } from 'react-redux';
|
||||
import { createSelector } from 'reselect';
|
||||
import * as commandNames from 'Commands/commandNames';
|
||||
import withCurrentPage from 'Components/withCurrentPage';
|
||||
import { deleteBookFile, fetchBookFiles, setBookFilesSort, setBookFilesTableOption } from 'Store/Actions/bookFileActions';
|
||||
import { deleteBookFile, deleteBookFiles, fetchBookFiles, setBookFilesSort, setBookFilesTableOption } from 'Store/Actions/bookFileActions';
|
||||
import { executeCommand } from 'Store/Actions/commandActions';
|
||||
import createClientSideCollectionSelector from 'Store/Selectors/createClientSideCollectionSelector';
|
||||
import createCommandExecutingSelector from 'Store/Selectors/createCommandExecutingSelector';
|
||||
@@ -28,7 +28,9 @@ function createMapStateToProps() {
|
||||
items,
|
||||
...otherProps
|
||||
} = bookFiles;
|
||||
|
||||
const unmappedFiles = _.filter(items, { bookId: 0 });
|
||||
|
||||
return {
|
||||
items: unmappedFiles,
|
||||
...otherProps,
|
||||
@@ -57,6 +59,10 @@ function createMapDispatchToProps(dispatch, props) {
|
||||
dispatch(deleteBookFile({ id }));
|
||||
},
|
||||
|
||||
deleteUnmappedFiles(bookFileIds) {
|
||||
dispatch(deleteBookFiles({ bookFileIds }));
|
||||
},
|
||||
|
||||
onAddMissingAuthorsPress() {
|
||||
dispatch(executeCommand({
|
||||
name: commandNames.RESCAN_FOLDERS,
|
||||
@@ -106,7 +112,8 @@ UnmappedFilesTableConnector.propTypes = {
|
||||
onSortPress: PropTypes.func.isRequired,
|
||||
onTableOptionChange: PropTypes.func.isRequired,
|
||||
fetchUnmappedFiles: PropTypes.func.isRequired,
|
||||
deleteUnmappedFile: PropTypes.func.isRequired
|
||||
deleteUnmappedFile: PropTypes.func.isRequired,
|
||||
deleteUnmappedFiles: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
export default withCurrentPage(
|
||||
|
||||
@@ -4,6 +4,7 @@ import IconButton from 'Components/Link/IconButton';
|
||||
import TableOptionsModalWrapper from 'Components/Table/TableOptions/TableOptionsModalWrapper';
|
||||
import VirtualTableHeader from 'Components/Table/VirtualTableHeader';
|
||||
import VirtualTableHeaderCell from 'Components/Table/VirtualTableHeaderCell';
|
||||
import VirtualTableSelectAllHeaderCell from 'Components/Table/VirtualTableSelectAllHeaderCell';
|
||||
import { icons } from 'Helpers/Props';
|
||||
// import hasGrowableColumns from './hasGrowableColumns';
|
||||
import styles from './UnmappedFilesTableHeader.css';
|
||||
@@ -12,6 +13,9 @@ function UnmappedFilesTableHeader(props) {
|
||||
const {
|
||||
columns,
|
||||
onTableOptionChange,
|
||||
allSelected,
|
||||
allUnselected,
|
||||
onSelectAllChange,
|
||||
...otherProps
|
||||
} = props;
|
||||
|
||||
@@ -30,6 +34,17 @@ function UnmappedFilesTableHeader(props) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (name === 'select') {
|
||||
return (
|
||||
<VirtualTableSelectAllHeaderCell
|
||||
key={name}
|
||||
allSelected={allSelected}
|
||||
allUnselected={allUnselected}
|
||||
onSelectAllChange={onSelectAllChange}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
if (name === 'actions') {
|
||||
return (
|
||||
<VirtualTableHeaderCell
|
||||
@@ -71,6 +86,9 @@ function UnmappedFilesTableHeader(props) {
|
||||
|
||||
UnmappedFilesTableHeader.propTypes = {
|
||||
columns: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
allSelected: PropTypes.bool.isRequired,
|
||||
allUnselected: PropTypes.bool.isRequired,
|
||||
onSelectAllChange: PropTypes.func.isRequired,
|
||||
onTableOptionChange: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
|
||||
@@ -20,3 +20,9 @@
|
||||
|
||||
flex: 0 0 100px;
|
||||
}
|
||||
|
||||
.checkInput {
|
||||
composes: input from '~Components/Form/CheckInput.css';
|
||||
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// Please do not change this file!
|
||||
interface CssExports {
|
||||
'actions': string;
|
||||
'checkInput': string;
|
||||
'dateAdded': string;
|
||||
'path': string;
|
||||
'quality': string;
|
||||
|
||||
@@ -6,6 +6,7 @@ import IconButton from 'Components/Link/IconButton';
|
||||
import ConfirmModal from 'Components/Modal/ConfirmModal';
|
||||
import RelativeDateCellConnector from 'Components/Table/Cells/RelativeDateCellConnector';
|
||||
import VirtualTableRowCell from 'Components/Table/Cells/VirtualTableRowCell';
|
||||
import VirtualTableSelectCell from 'Components/Table/Cells/VirtualTableSelectCell';
|
||||
import { icons, kinds } from 'Helpers/Props';
|
||||
import InteractiveImportModal from 'InteractiveImport/InteractiveImportModal';
|
||||
import formatBytes from 'Utilities/Number/formatBytes';
|
||||
@@ -69,7 +70,9 @@ class UnmappedFilesTableRow extends Component {
|
||||
size,
|
||||
dateAdded,
|
||||
quality,
|
||||
columns
|
||||
columns,
|
||||
isSelected,
|
||||
onSelectedChange
|
||||
} = this.props;
|
||||
|
||||
const folder = path.substring(0, Math.max(path.lastIndexOf('/'), path.lastIndexOf('\\')));
|
||||
@@ -93,6 +96,19 @@ class UnmappedFilesTableRow extends Component {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (name === 'select') {
|
||||
return (
|
||||
<VirtualTableSelectCell
|
||||
inputClassName={styles.checkInput}
|
||||
id={id}
|
||||
key={name}
|
||||
isSelected={isSelected}
|
||||
isDisabled={false}
|
||||
onSelectedChange={onSelectedChange}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
if (name === 'path') {
|
||||
return (
|
||||
<VirtualTableRowCell
|
||||
@@ -208,6 +224,8 @@ UnmappedFilesTableRow.propTypes = {
|
||||
quality: PropTypes.object.isRequired,
|
||||
dateAdded: PropTypes.string.isRequired,
|
||||
columns: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
isSelected: PropTypes.bool,
|
||||
onSelectedChange: PropTypes.func.isRequired,
|
||||
deleteUnmappedFile: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
|
||||
11
frontend/src/Utilities/String/naturalExpansion.js
Normal file
11
frontend/src/Utilities/String/naturalExpansion.js
Normal file
@@ -0,0 +1,11 @@
|
||||
const regex = /\d+/g;
|
||||
|
||||
function naturalExpansion(input) {
|
||||
if (!input) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return input.replace(regex, (n) => n.padStart(8, '0'));
|
||||
}
|
||||
|
||||
export default naturalExpansion;
|
||||
@@ -1,9 +1,11 @@
|
||||
const regex = /\b\w+/g;
|
||||
|
||||
function titleCase(input) {
|
||||
if (!input) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return input.replace(/\b\w+/g, (match) => {
|
||||
return input.replace(regex, (match) => {
|
||||
return match.charAt(0).toUpperCase() + match.substr(1).toLowerCase();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ class CutoffUnmetConnector extends Component {
|
||||
gotoCutoffUnmetFirstPage
|
||||
} = this.props;
|
||||
|
||||
registerPagePopulator(this.repopulate, ['bookFileUpdated']);
|
||||
registerPagePopulator(this.repopulate, ['bookFileUpdated', 'bookFileDeleted']);
|
||||
|
||||
if (useCurrentPage) {
|
||||
fetchCutoffUnmet();
|
||||
|
||||
@@ -50,7 +50,7 @@ class MissingConnector extends Component {
|
||||
gotoMissingFirstPage
|
||||
} = this.props;
|
||||
|
||||
registerPagePopulator(this.repopulate, ['bookFileUpdated']);
|
||||
registerPagePopulator(this.repopulate, ['bookFileUpdated', 'bookFileDeleted']);
|
||||
|
||||
if (useCurrentPage) {
|
||||
fetchMissing();
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
"@fortawesome/free-regular-svg-icons": "6.4.0",
|
||||
"@fortawesome/free-solid-svg-icons": "6.4.0",
|
||||
"@fortawesome/react-fontawesome": "0.2.0",
|
||||
"@microsoft/signalr": "6.0.21",
|
||||
"@microsoft/signalr": "6.0.25",
|
||||
"@sentry/browser": "7.51.2",
|
||||
"@sentry/integrations": "7.51.2",
|
||||
"@types/node": "18.16.16",
|
||||
|
||||
@@ -4,10 +4,11 @@
|
||||
<PackageVersion Include="AutoFixture" Version="4.17.0" />
|
||||
<PackageVersion Include="coverlet.collector" Version="3.0.4-preview.27.ge7cb7c3b40" PrivateAssets="all" />
|
||||
<PackageVersion Include="Dapper" Version="2.0.123" />
|
||||
<PackageVersion Include="DryIoc.dll" Version="5.4.1" />
|
||||
<PackageVersion Include="DryIoc.dll" Version="5.4.3" />
|
||||
<PackageVersion Include="DryIoc.Microsoft.DependencyInjection" Version="6.2.0" />
|
||||
<PackageVersion Include="Equ" Version="2.3.0" />
|
||||
<PackageVersion Include="FluentAssertions" Version="5.10.3" />
|
||||
<PackageVersion Include="Polly" Version="8.2.0" />
|
||||
<PackageVersion Include="Servarr.FluentMigrator.Runner" Version="3.3.2.9" />
|
||||
<PackageVersion Include="Servarr.FluentMigrator.Runner.SQLite" Version="3.3.2.9" />
|
||||
<PackageVersion Include="Servarr.FluentMigrator.Runner.Postgres" Version="3.3.2.9" />
|
||||
@@ -16,11 +17,11 @@
|
||||
<PackageVersion Include="ImpromptuInterface" Version="7.0.1" />
|
||||
<PackageVersion Include="LazyCache" Version="2.4.0" />
|
||||
<PackageVersion Include="Mailkit" Version="3.6.0" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.SignalR.Client" Version="6.0.21" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.SignalR.Client" Version="6.0.25" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Caching.Memory" Version="6.0.1" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Configuration" Version="6.0.1" />
|
||||
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="6.0.1" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Hosting.WindowsServices" Version="6.0.1" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Hosting.WindowsServices" Version="6.0.2" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Logging" Version="6.0.0" />
|
||||
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.4.1" />
|
||||
<PackageVersion Include="Microsoft.Win32.Registry" Version="5.0.0" />
|
||||
@@ -32,7 +33,7 @@
|
||||
<PackageVersion Include="NLog.Extensions.Logging" Version="5.2.3" />
|
||||
<PackageVersion Include="NLog" Version="5.1.4" />
|
||||
<PackageVersion Include="NLog.Targets.Syslog" Version="7.0.0" />
|
||||
<PackageVersion Include="Npgsql" Version="7.0.4" />
|
||||
<PackageVersion Include="Npgsql" Version="7.0.6" />
|
||||
<PackageVersion Include="NUnit3TestAdapter" Version="4.2.1" />
|
||||
<PackageVersion Include="NUnit" Version="3.13.3" />
|
||||
<PackageVersion Include="NunitXml.TestLogger" Version="3.0.117" />
|
||||
@@ -59,7 +60,7 @@
|
||||
<PackageVersion Include="System.Security.Principal.Windows" Version="5.0.0" />
|
||||
<PackageVersion Include="System.ServiceProcess.ServiceController" Version="6.0.1" />
|
||||
<PackageVersion Include="System.Text.Encoding.CodePages" Version="6.0.0" />
|
||||
<PackageVersion Include="System.Text.Json" Version="6.0.8" />
|
||||
<PackageVersion Include="System.Text.Json" Version="6.0.9" />
|
||||
<PackageVersion Include="System.ValueTuple" Version="4.5.0" />
|
||||
<PackageVersion Include="TagLibSharp-Lidarr" Version="2.2.0.19" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
using System.Collections.Generic;
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.Annotations;
|
||||
using NzbDrone.Core.Localization;
|
||||
using NzbDrone.Test.Common;
|
||||
using Readarr.Http.ClientSchema;
|
||||
|
||||
@@ -9,6 +12,16 @@ namespace NzbDrone.Api.Test.ClientSchemaTests
|
||||
[TestFixture]
|
||||
public class SchemaBuilderFixture : TestBase
|
||||
{
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
Mocker.GetMock<ILocalizationService>()
|
||||
.Setup(s => s.GetLocalizedString(It.IsAny<string>(), It.IsAny<Dictionary<string, object>>()))
|
||||
.Returns<string, Dictionary<string, object>>((s, d) => s);
|
||||
|
||||
SchemaBuilder.Initialize(Mocker.Container);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_field_for_every_property()
|
||||
{
|
||||
|
||||
@@ -5,6 +5,7 @@ using FluentAssertions;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.Books;
|
||||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.CustomFormats;
|
||||
using NzbDrone.Core.DecisionEngine.Specifications;
|
||||
using NzbDrone.Core.Download.TrackedDownloads;
|
||||
@@ -369,5 +370,31 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||
|
||||
Subject.IsSatisfiedBy(_remoteBook, null).Accepted.Should().BeTrue();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_false_if_same_quality_non_proper_in_queue_and_download_propers_is_do_not_upgrade()
|
||||
{
|
||||
_remoteBook.ParsedBookInfo.Quality = new QualityModel(Quality.FLAC, new Revision(2));
|
||||
_author.QualityProfile.Value.Cutoff = _remoteBook.ParsedBookInfo.Quality.Quality.Id;
|
||||
|
||||
Mocker.GetMock<IConfigService>()
|
||||
.Setup(s => s.DownloadPropersAndRepacks)
|
||||
.Returns(ProperDownloadTypes.DoNotUpgrade);
|
||||
|
||||
var remoteBook = Builder<RemoteBook>.CreateNew()
|
||||
.With(r => r.Author = _author)
|
||||
.With(r => r.Books = new List<Book> { _book })
|
||||
.With(r => r.ParsedBookInfo = new ParsedBookInfo
|
||||
{
|
||||
Quality = new QualityModel(Quality.FLAC)
|
||||
})
|
||||
.With(r => r.Release = _releaseInfo)
|
||||
.With(r => r.CustomFormats = new List<CustomFormat>())
|
||||
.Build();
|
||||
|
||||
GivenQueue(new List<RemoteBook> { remoteBook });
|
||||
|
||||
Subject.IsSatisfiedBy(_remoteBook, null).Accepted.Should().BeFalse();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,8 @@ namespace NzbDrone.Core.Test.ImportListTests
|
||||
|
||||
_importListReports = new List<ImportListItemInfo> { importListItem1 };
|
||||
|
||||
var mockImportList = new Mock<IImportList>();
|
||||
|
||||
Mocker.GetMock<IFetchAndParseImportList>()
|
||||
.Setup(v => v.Fetch())
|
||||
.Returns(_importListReports);
|
||||
@@ -53,6 +55,10 @@ namespace NzbDrone.Core.Test.ImportListTests
|
||||
.Setup(v => v.Get(It.IsAny<int>()))
|
||||
.Returns(new ImportListDefinition { ShouldMonitor = ImportListMonitorType.SpecificBook });
|
||||
|
||||
Mocker.GetMock<IImportListFactory>()
|
||||
.Setup(v => v.AutomaticAddEnabled(It.IsAny<bool>()))
|
||||
.Returns(new List<IImportList> { mockImportList.Object });
|
||||
|
||||
Mocker.GetMock<IFetchAndParseImportList>()
|
||||
.Setup(v => v.Fetch())
|
||||
.Returns(_importListReports);
|
||||
@@ -322,5 +328,31 @@ namespace NzbDrone.Core.Test.ImportListTests
|
||||
t.First().AddOptions.BooksToMonitor.Count == expectedBooksMonitored &&
|
||||
t.First().Monitored == expectedAuthorMonitored), false));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_not_fetch_if_no_lists_are_enabled()
|
||||
{
|
||||
Mocker.GetMock<IImportListFactory>()
|
||||
.Setup(v => v.AutomaticAddEnabled(It.IsAny<bool>()))
|
||||
.Returns(new List<IImportList>());
|
||||
|
||||
Subject.Execute(new ImportListSyncCommand());
|
||||
|
||||
Mocker.GetMock<IFetchAndParseImportList>()
|
||||
.Verify(v => v.Fetch(), Times.Never);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_not_process_if_no_items_are_returned()
|
||||
{
|
||||
Mocker.GetMock<IFetchAndParseImportList>()
|
||||
.Setup(v => v.Fetch())
|
||||
.Returns(new List<ImportListItemInfo>());
|
||||
|
||||
Subject.Execute(new ImportListSyncCommand());
|
||||
|
||||
Mocker.GetMock<IImportListExclusionService>()
|
||||
.Verify(v => v.All(), Times.Never);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
using System;
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.Languages;
|
||||
using NzbDrone.Core.Localization;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
using NzbDrone.Test.Common;
|
||||
|
||||
namespace NzbDrone.Core.Test.Localization
|
||||
{
|
||||
[TestFixture]
|
||||
public class LocalizationServiceFixture : CoreTest<LocalizationService>
|
||||
{
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
Mocker.GetMock<IConfigService>().Setup(m => m.UILanguage).Returns((int)Language.English);
|
||||
|
||||
Mocker.GetMock<IAppFolderInfo>().Setup(m => m.StartUpFolder).Returns(TestContext.CurrentContext.TestDirectory);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_get_string_in_dictionary_if_lang_exists_and_string_exists()
|
||||
{
|
||||
var localizedString = Subject.GetLocalizedString("UiLanguage");
|
||||
|
||||
localizedString.Should().Be("UI Language");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_get_string_in_french()
|
||||
{
|
||||
Mocker.GetMock<IConfigService>().Setup(m => m.UILanguage).Returns((int)Language.French);
|
||||
|
||||
var localizedString = Subject.GetLocalizedString("UiLanguage");
|
||||
|
||||
localizedString.Should().Be("Langue de l'IU");
|
||||
|
||||
ExceptionVerification.ExpectedErrors(1);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_get_string_in_default_dictionary_if_unknown_language_and_string_exists()
|
||||
{
|
||||
Mocker.GetMock<IConfigService>().Setup(m => m.UILanguage).Returns(0);
|
||||
var localizedString = Subject.GetLocalizedString("UiLanguage");
|
||||
|
||||
localizedString.Should().Be("UI Language");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_argument_if_string_doesnt_exists()
|
||||
{
|
||||
var localizedString = Subject.GetLocalizedString("badString");
|
||||
|
||||
localizedString.Should().Be("badString");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_argument_if_string_doesnt_exists_default_lang()
|
||||
{
|
||||
var localizedString = Subject.GetLocalizedString("badString");
|
||||
|
||||
localizedString.Should().Be("badString");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_throw_if_empty_string_passed()
|
||||
{
|
||||
Assert.Throws<ArgumentNullException>(() => Subject.GetLocalizedString(""));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_throw_if_null_string_passed()
|
||||
{
|
||||
Assert.Throws<ArgumentNullException>(() => Subject.GetLocalizedString(null));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -35,16 +35,13 @@ namespace NzbDrone.Core.Test.ParserTests
|
||||
[TestCase("or")]
|
||||
[TestCase("an")]
|
||||
[TestCase("of")]
|
||||
public void should_remove_common_words(string word)
|
||||
public void should_remove_common_words_from_middle_of_title(string word)
|
||||
{
|
||||
var dirtyFormat = new[]
|
||||
{
|
||||
"word.{0}.word",
|
||||
"word {0} word",
|
||||
"word-{0}-word",
|
||||
"word.word.{0}",
|
||||
"word-word-{0}",
|
||||
"word-word {0}",
|
||||
"word-{0}-word"
|
||||
};
|
||||
|
||||
foreach (var s in dirtyFormat)
|
||||
@@ -54,6 +51,27 @@ namespace NzbDrone.Core.Test.ParserTests
|
||||
}
|
||||
}
|
||||
|
||||
[TestCase("the")]
|
||||
[TestCase("and")]
|
||||
[TestCase("or")]
|
||||
[TestCase("an")]
|
||||
[TestCase("of")]
|
||||
public void should_not_remove_common_words_from_end_of_title(string word)
|
||||
{
|
||||
var dirtyFormat = new[]
|
||||
{
|
||||
"word.word.{0}",
|
||||
"word-word-{0}",
|
||||
"word-word {0}"
|
||||
};
|
||||
|
||||
foreach (var s in dirtyFormat)
|
||||
{
|
||||
var dirty = string.Format(s, word);
|
||||
dirty.CleanAuthorName().Should().Be("wordword" + word.ToLower());
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_remove_a_from_middle_of_title()
|
||||
{
|
||||
|
||||
@@ -41,6 +41,23 @@ namespace NzbDrone.Core.Annotations
|
||||
public string Hint { get; set; }
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Property, AllowMultiple = true)]
|
||||
public class FieldTokenAttribute : Attribute
|
||||
{
|
||||
public FieldTokenAttribute(TokenField field, string label = "", string token = "", object value = null)
|
||||
{
|
||||
Label = label;
|
||||
Field = field;
|
||||
Token = token;
|
||||
Value = value?.ToString();
|
||||
}
|
||||
|
||||
public string Label { get; set; }
|
||||
public TokenField Field { get; set; }
|
||||
public string Token { get; set; }
|
||||
public string Value { get; set; }
|
||||
}
|
||||
|
||||
public class FieldSelectOption
|
||||
{
|
||||
public int Value { get; set; }
|
||||
@@ -83,4 +100,11 @@ namespace NzbDrone.Core.Annotations
|
||||
ApiKey,
|
||||
UserName
|
||||
}
|
||||
|
||||
public enum TokenField
|
||||
{
|
||||
Label,
|
||||
HelpText,
|
||||
HelpTextWarning
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using FluentValidation;
|
||||
using FluentValidation.Results;
|
||||
using Newtonsoft.Json;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Cache;
|
||||
using NzbDrone.Common.Disk;
|
||||
@@ -218,11 +219,11 @@ namespace NzbDrone.Core.Books.Calibre
|
||||
double? seriesIndex = null;
|
||||
if (double.TryParse(serieslink?.Position, out var index))
|
||||
{
|
||||
_logger.Trace($"Parsed {serieslink?.Position} as {index}");
|
||||
_logger.Trace("Parsed '{0}' as '{1}'", serieslink.Position, index);
|
||||
seriesIndex = index;
|
||||
}
|
||||
|
||||
_logger.Trace($"Book: {book} Series: {series?.Title}, Position: {seriesIndex}");
|
||||
_logger.Trace("Book: {0} Series: {1}, Position: {2}", book, series?.Title, seriesIndex);
|
||||
|
||||
var cover = edition.Images.FirstOrDefault(x => x.CoverType == MediaCoverTypes.Cover);
|
||||
string image = null;
|
||||
@@ -275,7 +276,9 @@ namespace NzbDrone.Core.Books.Calibre
|
||||
|
||||
var updatedPath = GetOriginalFormat(updated.Formats);
|
||||
|
||||
if (updatedPath != null && updatedPath != file.Path)
|
||||
_logger.Trace("File path from Calibre: '{0}'", updatedPath);
|
||||
|
||||
if (updatedPath.IsNotNullOrWhiteSpace() && updatedPath != file.Path)
|
||||
{
|
||||
_rootFolderWatchingService.ReportFileSystemChangeBeginning(updatedPath);
|
||||
file.Path = updatedPath;
|
||||
@@ -304,6 +307,7 @@ namespace NzbDrone.Core.Books.Calibre
|
||||
|
||||
var request = builder.Build();
|
||||
request.SetContent(payload.ToJson());
|
||||
request.ContentSummary = payload.ToJson(Formatting.None);
|
||||
|
||||
_httpClient.Execute(request);
|
||||
}
|
||||
|
||||
@@ -329,8 +329,8 @@ namespace NzbDrone.Core.Configuration
|
||||
return;
|
||||
}
|
||||
|
||||
// If SSL is enabled and a cert hash is still in the config file disable SSL
|
||||
if (EnableSsl && GetValue("SslCertHash", null).IsNotNullOrWhiteSpace())
|
||||
// If SSL is enabled and a cert hash is still in the config file or cert path is empty disable SSL
|
||||
if (EnableSsl && (GetValue("SslCertHash", null).IsNotNullOrWhiteSpace() || SslCertPath.IsNullOrWhiteSpace()))
|
||||
{
|
||||
SetValue("EnableSsl", false);
|
||||
}
|
||||
|
||||
@@ -9,9 +9,9 @@ namespace NzbDrone.Core.Datastore
|
||||
{
|
||||
public interface IConnectionStringFactory
|
||||
{
|
||||
string MainDbConnectionString { get; }
|
||||
string LogDbConnectionString { get; }
|
||||
string CacheDbConnectionString { get; }
|
||||
DatabaseConnectionInfo MainDbConnection { get; }
|
||||
DatabaseConnectionInfo LogDbConnection { get; }
|
||||
DatabaseConnectionInfo CacheDbConnection { get; }
|
||||
string GetDatabasePath(string connectionString);
|
||||
}
|
||||
|
||||
@@ -23,19 +23,19 @@ namespace NzbDrone.Core.Datastore
|
||||
{
|
||||
_configFileProvider = configFileProvider;
|
||||
|
||||
MainDbConnectionString = _configFileProvider.PostgresHost.IsNotNullOrWhiteSpace() ? GetPostgresConnectionString(_configFileProvider.PostgresMainDb) :
|
||||
MainDbConnection = _configFileProvider.PostgresHost.IsNotNullOrWhiteSpace() ? GetPostgresConnectionString(_configFileProvider.PostgresMainDb) :
|
||||
GetConnectionString(appFolderInfo.GetDatabase());
|
||||
|
||||
LogDbConnectionString = _configFileProvider.PostgresHost.IsNotNullOrWhiteSpace() ? GetPostgresConnectionString(_configFileProvider.PostgresLogDb) :
|
||||
LogDbConnection = _configFileProvider.PostgresHost.IsNotNullOrWhiteSpace() ? GetPostgresConnectionString(_configFileProvider.PostgresLogDb) :
|
||||
GetConnectionString(appFolderInfo.GetLogDatabase());
|
||||
|
||||
CacheDbConnectionString = _configFileProvider.PostgresHost.IsNotNullOrWhiteSpace() ? GetPostgresConnectionString(_configFileProvider.PostgresCacheDb) :
|
||||
CacheDbConnection = _configFileProvider.PostgresHost.IsNotNullOrWhiteSpace() ? GetPostgresConnectionString(_configFileProvider.PostgresCacheDb) :
|
||||
GetConnectionString(appFolderInfo.GetCacheDatabase());
|
||||
}
|
||||
|
||||
public string MainDbConnectionString { get; private set; }
|
||||
public string LogDbConnectionString { get; private set; }
|
||||
public string CacheDbConnectionString { get; private set; }
|
||||
public DatabaseConnectionInfo MainDbConnection { get; private set; }
|
||||
public DatabaseConnectionInfo LogDbConnection { get; private set; }
|
||||
public DatabaseConnectionInfo CacheDbConnection { get; private set; }
|
||||
|
||||
public string GetDatabasePath(string connectionString)
|
||||
{
|
||||
@@ -44,7 +44,7 @@ namespace NzbDrone.Core.Datastore
|
||||
return connectionBuilder.DataSource;
|
||||
}
|
||||
|
||||
private static string GetConnectionString(string dbPath)
|
||||
private static DatabaseConnectionInfo GetConnectionString(string dbPath)
|
||||
{
|
||||
var connectionBuilder = new SQLiteConnectionStringBuilder
|
||||
{
|
||||
@@ -62,21 +62,22 @@ namespace NzbDrone.Core.Datastore
|
||||
connectionBuilder.Add("Full FSync", true);
|
||||
}
|
||||
|
||||
return connectionBuilder.ConnectionString;
|
||||
return new DatabaseConnectionInfo(DatabaseType.SQLite, connectionBuilder.ConnectionString);
|
||||
}
|
||||
|
||||
private string GetPostgresConnectionString(string dbName)
|
||||
private DatabaseConnectionInfo GetPostgresConnectionString(string dbName)
|
||||
{
|
||||
var connectionBuilder = new NpgsqlConnectionStringBuilder();
|
||||
var connectionBuilder = new NpgsqlConnectionStringBuilder
|
||||
{
|
||||
Database = dbName,
|
||||
Host = _configFileProvider.PostgresHost,
|
||||
Username = _configFileProvider.PostgresUser,
|
||||
Password = _configFileProvider.PostgresPassword,
|
||||
Port = _configFileProvider.PostgresPort,
|
||||
Enlist = false
|
||||
};
|
||||
|
||||
connectionBuilder.Database = dbName;
|
||||
connectionBuilder.Host = _configFileProvider.PostgresHost;
|
||||
connectionBuilder.Username = _configFileProvider.PostgresUser;
|
||||
connectionBuilder.Password = _configFileProvider.PostgresPassword;
|
||||
connectionBuilder.Port = _configFileProvider.PostgresPort;
|
||||
connectionBuilder.Enlist = false;
|
||||
|
||||
return connectionBuilder.ConnectionString;
|
||||
return new DatabaseConnectionInfo(DatabaseType.PostgreSQL, connectionBuilder.ConnectionString);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
14
src/NzbDrone.Core/Datastore/DatabaseConnectionInfo.cs
Normal file
14
src/NzbDrone.Core/Datastore/DatabaseConnectionInfo.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
namespace NzbDrone.Core.Datastore
|
||||
{
|
||||
public class DatabaseConnectionInfo
|
||||
{
|
||||
public DatabaseConnectionInfo(DatabaseType databaseType, string connectionString)
|
||||
{
|
||||
DatabaseType = databaseType;
|
||||
ConnectionString = connectionString;
|
||||
}
|
||||
|
||||
public DatabaseType DatabaseType { get; internal set; }
|
||||
public string ConnectionString { get; internal set; }
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ using System;
|
||||
using System.Data.Common;
|
||||
using System.Data.SQLite;
|
||||
using System.Net.Sockets;
|
||||
using System.Threading;
|
||||
using NLog;
|
||||
using Npgsql;
|
||||
using NzbDrone.Common.Disk;
|
||||
@@ -59,30 +60,30 @@ namespace NzbDrone.Core.Datastore
|
||||
|
||||
public IDatabase Create(MigrationContext migrationContext)
|
||||
{
|
||||
string connectionString;
|
||||
DatabaseConnectionInfo connectionInfo;
|
||||
|
||||
switch (migrationContext.MigrationType)
|
||||
{
|
||||
case MigrationType.Main:
|
||||
{
|
||||
connectionString = _connectionStringFactory.MainDbConnectionString;
|
||||
CreateMain(connectionString, migrationContext);
|
||||
connectionInfo = _connectionStringFactory.MainDbConnection;
|
||||
CreateMain(connectionInfo.ConnectionString, migrationContext, connectionInfo.DatabaseType);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case MigrationType.Log:
|
||||
{
|
||||
connectionString = _connectionStringFactory.LogDbConnectionString;
|
||||
CreateLog(connectionString, migrationContext);
|
||||
connectionInfo = _connectionStringFactory.LogDbConnection;
|
||||
CreateLog(connectionInfo.ConnectionString, migrationContext, connectionInfo.DatabaseType);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case MigrationType.Cache:
|
||||
{
|
||||
connectionString = _connectionStringFactory.CacheDbConnectionString;
|
||||
CreateLog(connectionString, migrationContext);
|
||||
connectionInfo = _connectionStringFactory.CacheDbConnection;
|
||||
CreateLog(connectionInfo.ConnectionString, migrationContext, connectionInfo.DatabaseType);
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -97,14 +98,14 @@ namespace NzbDrone.Core.Datastore
|
||||
{
|
||||
DbConnection conn;
|
||||
|
||||
if (connectionString.Contains(".db"))
|
||||
if (connectionInfo.DatabaseType == DatabaseType.SQLite)
|
||||
{
|
||||
conn = SQLiteFactory.Instance.CreateConnection();
|
||||
conn.ConnectionString = connectionString;
|
||||
conn.ConnectionString = connectionInfo.ConnectionString;
|
||||
}
|
||||
else
|
||||
{
|
||||
conn = new NpgsqlConnection(connectionString);
|
||||
conn = new NpgsqlConnection(connectionInfo.ConnectionString);
|
||||
}
|
||||
|
||||
conn.Open();
|
||||
@@ -114,12 +115,12 @@ namespace NzbDrone.Core.Datastore
|
||||
return db;
|
||||
}
|
||||
|
||||
private void CreateMain(string connectionString, MigrationContext migrationContext)
|
||||
private void CreateMain(string connectionString, MigrationContext migrationContext, DatabaseType databaseType)
|
||||
{
|
||||
try
|
||||
{
|
||||
_restoreDatabaseService.Restore();
|
||||
_migrationController.Migrate(connectionString, migrationContext);
|
||||
_migrationController.Migrate(connectionString, migrationContext, databaseType);
|
||||
}
|
||||
catch (SQLiteException e)
|
||||
{
|
||||
@@ -142,15 +143,17 @@ namespace NzbDrone.Core.Datastore
|
||||
{
|
||||
Logger.Error(e, "Failure to connect to Postgres DB, {0} retries remaining", retryCount);
|
||||
|
||||
Thread.Sleep(5000);
|
||||
|
||||
try
|
||||
{
|
||||
_migrationController.Migrate(connectionString, migrationContext);
|
||||
_migrationController.Migrate(connectionString, migrationContext, databaseType);
|
||||
return;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (--retryCount > 0)
|
||||
{
|
||||
System.Threading.Thread.Sleep(5000);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -169,11 +172,11 @@ namespace NzbDrone.Core.Datastore
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateLog(string connectionString, MigrationContext migrationContext)
|
||||
private void CreateLog(string connectionString, MigrationContext migrationContext, DatabaseType databaseType)
|
||||
{
|
||||
try
|
||||
{
|
||||
_migrationController.Migrate(connectionString, migrationContext);
|
||||
_migrationController.Migrate(connectionString, migrationContext, databaseType);
|
||||
}
|
||||
catch (SQLiteException e)
|
||||
{
|
||||
@@ -193,7 +196,7 @@ namespace NzbDrone.Core.Datastore
|
||||
Logger.Error("Unable to recreate logging database automatically. It will need to be removed manually.");
|
||||
}
|
||||
|
||||
_migrationController.Migrate(connectionString, migrationContext);
|
||||
_migrationController.Migrate(connectionString, migrationContext, databaseType);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace NzbDrone.Core.Datastore.Migration.Framework
|
||||
{
|
||||
public interface IMigrationController
|
||||
{
|
||||
void Migrate(string connectionString, MigrationContext migrationContext);
|
||||
void Migrate(string connectionString, MigrationContext migrationContext, DatabaseType databaseType);
|
||||
}
|
||||
|
||||
public class MigrationController : IMigrationController
|
||||
@@ -29,7 +29,7 @@ namespace NzbDrone.Core.Datastore.Migration.Framework
|
||||
_migrationLoggerProvider = migrationLoggerProvider;
|
||||
}
|
||||
|
||||
public void Migrate(string connectionString, MigrationContext migrationContext)
|
||||
public void Migrate(string connectionString, MigrationContext migrationContext, DatabaseType databaseType)
|
||||
{
|
||||
var sw = Stopwatch.StartNew();
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace NzbDrone.Core.Datastore.Migration.Framework
|
||||
|
||||
ServiceProvider serviceProvider;
|
||||
|
||||
var db = connectionString.Contains(".db") ? "sqlite" : "postgres";
|
||||
var db = databaseType == DatabaseType.SQLite ? "sqlite" : "postgres";
|
||||
|
||||
serviceProvider = new ServiceCollection()
|
||||
.AddLogging(b => b.AddNLog())
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NLog;
|
||||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.CustomFormats;
|
||||
using NzbDrone.Core.Download.TrackedDownloads;
|
||||
using NzbDrone.Core.IndexerSearch.Definitions;
|
||||
@@ -15,16 +16,19 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
|
||||
private readonly IQueueService _queueService;
|
||||
private readonly UpgradableSpecification _upgradableSpecification;
|
||||
private readonly ICustomFormatCalculationService _formatService;
|
||||
private readonly IConfigService _configService;
|
||||
private readonly Logger _logger;
|
||||
|
||||
public QueueSpecification(IQueueService queueService,
|
||||
UpgradableSpecification upgradableSpecification,
|
||||
ICustomFormatCalculationService formatService,
|
||||
IConfigService configService,
|
||||
Logger logger)
|
||||
{
|
||||
_queueService = queueService;
|
||||
_upgradableSpecification = upgradableSpecification;
|
||||
_formatService = formatService;
|
||||
_configService = configService;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
@@ -85,6 +89,15 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
|
||||
{
|
||||
return Decision.Reject("Another release is queued and the Quality profile does not allow upgrades");
|
||||
}
|
||||
|
||||
if (_upgradableSpecification.IsRevisionUpgrade(remoteBook.ParsedBookInfo.Quality, subject.ParsedBookInfo.Quality))
|
||||
{
|
||||
if (_configService.DownloadPropersAndRepacks == ProperDownloadTypes.DoNotUpgrade)
|
||||
{
|
||||
_logger.Debug("Auto downloading of propers is disabled");
|
||||
return Decision.Reject("Proper downloading is disabled");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Decision.Accept();
|
||||
|
||||
@@ -70,7 +70,7 @@ namespace NzbDrone.Core.Download.Clients.Flood
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
return result.Where(t => t.IsNotNullOrWhiteSpace());
|
||||
}
|
||||
|
||||
public override string Name => "Flood";
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace NzbDrone.Core.Download.Clients.QBittorrent
|
||||
{
|
||||
public enum QBittorrentContentLayout
|
||||
{
|
||||
Default = 0,
|
||||
Original = 1,
|
||||
Subfolder = 2
|
||||
}
|
||||
}
|
||||
@@ -265,6 +265,15 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
|
||||
{
|
||||
request.AddFormParameter("firstLastPiecePrio", true);
|
||||
}
|
||||
|
||||
if ((QBittorrentContentLayout)settings.ContentLayout == QBittorrentContentLayout.Original)
|
||||
{
|
||||
request.AddFormParameter("contentLayout", "Original");
|
||||
}
|
||||
else if ((QBittorrentContentLayout)settings.ContentLayout == QBittorrentContentLayout.Subfolder)
|
||||
{
|
||||
request.AddFormParameter("contentLayout", "Subfolder");
|
||||
}
|
||||
}
|
||||
|
||||
public void SetTorrentSeedingConfiguration(string hash, TorrentSeedConfiguration seedConfiguration, QBittorrentSettings settings)
|
||||
|
||||
@@ -69,6 +69,9 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
|
||||
[FieldDefinition(12, Label = "First and Last First", Type = FieldType.Checkbox, HelpText = "Download first and last pieces first (qBittorrent 4.1.0+)")]
|
||||
public bool FirstAndLast { get; set; }
|
||||
|
||||
[FieldDefinition(13, Label = "DownloadClientQbittorrentSettingsContentLayout", Type = FieldType.Select, SelectOptions = typeof(QBittorrentContentLayout), HelpText = "DownloadClientQbittorrentSettingsContentLayoutHelpText")]
|
||||
public int ContentLayout { get; set; }
|
||||
|
||||
public NzbDroneValidationResult Validate()
|
||||
{
|
||||
return new NzbDroneValidationResult(Validator.Validate(this));
|
||||
|
||||
@@ -1,15 +1,19 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using FluentValidation.Results;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Disk;
|
||||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.Indexers;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
using NzbDrone.Core.RemotePathMappings;
|
||||
using NzbDrone.Core.ThingiProvider;
|
||||
using NzbDrone.Core.Validation;
|
||||
using Polly;
|
||||
using Polly.Retry;
|
||||
|
||||
namespace NzbDrone.Core.Download
|
||||
{
|
||||
@@ -21,6 +25,37 @@ namespace NzbDrone.Core.Download
|
||||
protected readonly IRemotePathMappingService _remotePathMappingService;
|
||||
protected readonly Logger _logger;
|
||||
|
||||
protected ResiliencePipeline<HttpResponse> RetryStrategy => new ResiliencePipelineBuilder<HttpResponse>()
|
||||
.AddRetry(new RetryStrategyOptions<HttpResponse>
|
||||
{
|
||||
ShouldHandle = static args => args.Outcome switch
|
||||
{
|
||||
{ Result.HasHttpServerError: true } => PredicateResult.True(),
|
||||
{ Result.StatusCode: HttpStatusCode.RequestTimeout } => PredicateResult.True(),
|
||||
_ => PredicateResult.False()
|
||||
},
|
||||
Delay = TimeSpan.FromSeconds(3),
|
||||
MaxRetryAttempts = 2,
|
||||
BackoffType = DelayBackoffType.Exponential,
|
||||
UseJitter = true,
|
||||
OnRetry = args =>
|
||||
{
|
||||
var exception = args.Outcome.Exception;
|
||||
|
||||
if (exception is not null)
|
||||
{
|
||||
_logger.Info(exception, "Request for {0} failed with exception '{1}'. Retrying in {2}s.", Definition.Name, exception.Message, args.RetryDelay.TotalSeconds);
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.Info("Request for {0} failed with status {1}. Retrying in {2}s.", Definition.Name, args.Outcome.Result?.StatusCode, args.RetryDelay.TotalSeconds);
|
||||
}
|
||||
|
||||
return default;
|
||||
}
|
||||
})
|
||||
.Build();
|
||||
|
||||
public abstract string Name { get; }
|
||||
|
||||
public Type ConfigContract => typeof(TSettings);
|
||||
@@ -54,10 +89,7 @@ namespace NzbDrone.Core.Download
|
||||
return GetType().Name;
|
||||
}
|
||||
|
||||
public abstract DownloadProtocol Protocol
|
||||
{
|
||||
get;
|
||||
}
|
||||
public abstract DownloadProtocol Protocol { get; }
|
||||
|
||||
public abstract Task<string> Download(RemoteBook remoteBook, IIndexer indexer);
|
||||
public abstract IEnumerable<DownloadClientItem> GetItems();
|
||||
|
||||
@@ -133,7 +133,9 @@ namespace NzbDrone.Core.Download
|
||||
request.Headers.Accept = "application/x-bittorrent";
|
||||
request.AllowAutoRedirect = false;
|
||||
|
||||
var response = await _httpClient.GetAsync(request);
|
||||
var response = await RetryStrategy
|
||||
.ExecuteAsync(static async (state, _) => await state._httpClient.GetAsync(state.request), (_httpClient, request))
|
||||
.ConfigureAwait(false);
|
||||
|
||||
if (response.StatusCode == HttpStatusCode.MovedPermanently ||
|
||||
response.StatusCode == HttpStatusCode.Found ||
|
||||
|
||||
@@ -47,7 +47,9 @@ namespace NzbDrone.Core.Download
|
||||
var request = indexer?.GetDownloadRequest(url) ?? new HttpRequest(url);
|
||||
request.RateLimitKey = remoteBook?.Release?.IndexerId.ToString();
|
||||
|
||||
var response = await _httpClient.GetAsync(request);
|
||||
var response = await RetryStrategy
|
||||
.ExecuteAsync(static async (state, _) => await state._httpClient.GetAsync(state.request), (_httpClient, request))
|
||||
.ConfigureAwait(false);
|
||||
|
||||
nzbData = response.ResponseData;
|
||||
|
||||
|
||||
@@ -368,6 +368,10 @@ namespace NzbDrone.Core.Extras.Metadata
|
||||
_mediaFileAttributeService.SetFilePermissions(fullPath);
|
||||
}
|
||||
}
|
||||
catch (HttpException ex)
|
||||
{
|
||||
_logger.Warn(ex, "Couldn't download image {0} for {1}. {2}", image.Url, author, ex.Message);
|
||||
}
|
||||
catch (WebException ex)
|
||||
{
|
||||
_logger.Warn(ex, "Couldn't download image {0} for {1}. {2}", image.Url, author, ex.Message);
|
||||
|
||||
@@ -67,41 +67,51 @@ namespace NzbDrone.Core.ImportLists
|
||||
|
||||
private List<Book> SyncAll()
|
||||
{
|
||||
if (_importListFactory.AutomaticAddEnabled().Empty())
|
||||
{
|
||||
_logger.Debug("No import lists with automatic add enabled");
|
||||
|
||||
return new List<Book>();
|
||||
}
|
||||
|
||||
_logger.ProgressInfo("Starting Import List Sync");
|
||||
|
||||
var rssReleases = _listFetcherAndParser.Fetch();
|
||||
var listItems = _listFetcherAndParser.Fetch().ToList();
|
||||
|
||||
var reports = rssReleases.ToList();
|
||||
|
||||
return ProcessReports(reports);
|
||||
return ProcessListItems(listItems);
|
||||
}
|
||||
|
||||
private List<Book> SyncList(ImportListDefinition definition)
|
||||
{
|
||||
_logger.ProgressInfo(string.Format("Starting Import List Refresh for List {0}", definition.Name));
|
||||
_logger.ProgressInfo($"Starting Import List Refresh for List {definition.Name}");
|
||||
|
||||
var rssReleases = _listFetcherAndParser.FetchSingleList(definition);
|
||||
var listItems = _listFetcherAndParser.FetchSingleList(definition).ToList();
|
||||
|
||||
var reports = rssReleases.ToList();
|
||||
|
||||
return ProcessReports(reports);
|
||||
return ProcessListItems(listItems);
|
||||
}
|
||||
|
||||
private List<Book> ProcessReports(List<ImportListItemInfo> reports)
|
||||
private List<Book> ProcessListItems(List<ImportListItemInfo> items)
|
||||
{
|
||||
var processed = new List<Book>();
|
||||
var authorsToAdd = new List<Author>();
|
||||
var booksToAdd = new List<Book>();
|
||||
|
||||
_logger.ProgressInfo("Processing {0} list items", reports.Count);
|
||||
if (items.Count == 0)
|
||||
{
|
||||
_logger.ProgressInfo("No list items to process");
|
||||
|
||||
return new List<Book>();
|
||||
}
|
||||
|
||||
_logger.ProgressInfo("Processing {0} list items", items.Count);
|
||||
|
||||
var reportNumber = 1;
|
||||
|
||||
var listExclusions = _importListExclusionService.All();
|
||||
|
||||
foreach (var report in reports)
|
||||
foreach (var report in items)
|
||||
{
|
||||
_logger.ProgressTrace("Processing list item {0}/{1}", reportNumber, reports.Count);
|
||||
_logger.ProgressTrace("Processing list item {0}/{1}", reportNumber, items.Count);
|
||||
|
||||
reportNumber++;
|
||||
|
||||
@@ -130,7 +140,7 @@ namespace NzbDrone.Core.ImportLists
|
||||
var addedAuthors = _addAuthorService.AddAuthors(authorsToAdd, false);
|
||||
var addedBooks = _addBookService.AddBooks(booksToAdd, false);
|
||||
|
||||
var message = string.Format($"Import List Sync Completed. Items found: {reports.Count}, Authors added: {authorsToAdd.Count}, Books added: {booksToAdd.Count}");
|
||||
var message = string.Format($"Import List Sync Completed. Items found: {items.Count}, Authors added: {authorsToAdd.Count}, Books added: {booksToAdd.Count}");
|
||||
|
||||
_logger.ProgressInfo(message);
|
||||
|
||||
@@ -364,7 +374,7 @@ namespace NzbDrone.Core.ImportLists
|
||||
var existingAuthor = _authorService.FindById(report.AuthorGoodreadsId);
|
||||
|
||||
// Check to see if author excluded
|
||||
var excludedAuthor = listExclusions.Where(s => s.ForeignId == report.AuthorGoodreadsId).SingleOrDefault();
|
||||
var excludedAuthor = listExclusions.SingleOrDefault(s => s.ForeignId == report.AuthorGoodreadsId);
|
||||
|
||||
// Check to see if author in import
|
||||
var existingImportAuthor = authorsToAdd.Find(i => i.ForeignAuthorId == report.AuthorGoodreadsId);
|
||||
@@ -425,16 +435,7 @@ namespace NzbDrone.Core.ImportLists
|
||||
|
||||
public void Execute(ImportListSyncCommand message)
|
||||
{
|
||||
List<Book> processed;
|
||||
|
||||
if (message.DefinitionId.HasValue)
|
||||
{
|
||||
processed = SyncList(_importListFactory.Get(message.DefinitionId.Value));
|
||||
}
|
||||
else
|
||||
{
|
||||
processed = SyncAll();
|
||||
}
|
||||
var processed = message.DefinitionId.HasValue ? SyncList(_importListFactory.Get(message.DefinitionId.Value)) : SyncAll();
|
||||
|
||||
_eventAggregator.PublishEvent(new ImportListSyncCompleteEvent(processed));
|
||||
}
|
||||
|
||||
@@ -53,7 +53,6 @@ namespace NzbDrone.Core.Indexers.Newznab
|
||||
yield return GetDefinition("NZBFinder.ws", GetSettings("https://nzbfinder.ws"));
|
||||
yield return GetDefinition("NZBgeek", GetSettings("https://api.nzbgeek.info"));
|
||||
yield return GetDefinition("nzbplanet.net", GetSettings("https://api.nzbplanet.net"));
|
||||
yield return GetDefinition("OZnzb.com", GetSettings("https://api.oznzb.com"));
|
||||
yield return GetDefinition("SimplyNZBs", GetSettings("https://simplynzbs.com"));
|
||||
yield return GetDefinition("Tabula Rasa", GetSettings("https://www.tabula-rasa.pw", apiPath: @"/api/v1/api"));
|
||||
yield return GetDefinition("Usenet Crawler", GetSettings("https://www.usenet-crawler.com"));
|
||||
|
||||
@@ -85,16 +85,15 @@ namespace NzbDrone.Core.Instrumentation
|
||||
|
||||
log.Level = logEvent.Level.Name;
|
||||
|
||||
var connectionString = _connectionStringFactory.LogDbConnectionString;
|
||||
var connectionInfo = _connectionStringFactory.LogDbConnection;
|
||||
|
||||
//TODO: Probably need more robust way to differentiate what's being used
|
||||
if (connectionString.Contains(".db"))
|
||||
if (connectionInfo.DatabaseType == DatabaseType.SQLite)
|
||||
{
|
||||
WriteSqliteLog(log, connectionString);
|
||||
WriteSqliteLog(log, connectionInfo.ConnectionString);
|
||||
}
|
||||
else
|
||||
{
|
||||
WritePostgresLog(log, connectionString);
|
||||
WritePostgresLog(log, connectionInfo.ConnectionString);
|
||||
}
|
||||
}
|
||||
catch (SQLiteException ex)
|
||||
|
||||
@@ -216,8 +216,6 @@
|
||||
"FileManagement": "إدارة الملفات",
|
||||
"FileDateHelpText": "تغيير تاريخ الملف عند الاستيراد / إعادة الفحص",
|
||||
"FailedDownloadHandling": "فشل معالجة التنزيل",
|
||||
"ExtraFileExtensionsHelpTexts2": "أمثلة: \".sub أو .nfo\" أو \"sub، nfo\"",
|
||||
"ExtraFileExtensionsHelpTexts1": "قائمة مفصولة بفواصل بالملفات الإضافية المراد استيرادها (سيتم استيراد .nfo كـ .nfo-Orig)",
|
||||
"Exception": "استثناء",
|
||||
"ErrorLoadingPreviews": "خطأ في تحميل المعاينات",
|
||||
"ErrorLoadingContents": "خطأ في تحميل المحتويات",
|
||||
@@ -628,5 +626,7 @@
|
||||
"AddNew": "اضف جديد",
|
||||
"System": "النظام",
|
||||
"AllResultsAreHiddenByTheAppliedFilter": "يتم إخفاء جميع النتائج بواسطة عامل التصفية المطبق",
|
||||
"Backup": "دعم"
|
||||
"Backup": "دعم",
|
||||
"ExtraFileExtensionsHelpText": "قائمة مفصولة بفواصل بالملفات الإضافية المراد استيرادها (سيتم استيراد .nfo كـ .nfo-Orig)",
|
||||
"ExtraFileExtensionsHelpTextsExamples": "أمثلة: \".sub أو .nfo\" أو \"sub، nfo\""
|
||||
}
|
||||
|
||||
@@ -122,8 +122,6 @@
|
||||
"ErrorLoadingContents": "Грешка при зареждането на съдържанието",
|
||||
"ErrorLoadingPreviews": "Грешка при зареждането на визуализациите",
|
||||
"Exception": "Изключение",
|
||||
"ExtraFileExtensionsHelpTexts1": "Списък с допълнителни файлове за импортиране, разделени със запетая (.nfo ще бъде импортиран като .nfo-orig)",
|
||||
"ExtraFileExtensionsHelpTexts2": "Примери: '.sub, .nfo' или 'sub, nfo'",
|
||||
"FailedDownloadHandling": "Неуспешно обработване на изтеглянето",
|
||||
"FileDateHelpText": "Променете датата на файла при импортиране / пресканиране",
|
||||
"FileManagement": "Управление на файлове",
|
||||
@@ -628,5 +626,7 @@
|
||||
"AllResultsAreHiddenByTheAppliedFilter": "Всички резултати са скрити от приложения филтър",
|
||||
"Backup": "Архивиране",
|
||||
"MetadataProfiles": "Добави профил на метадата",
|
||||
"MetadataProfile": "Добави профил на метадата"
|
||||
"MetadataProfile": "Добави профил на метадата",
|
||||
"ExtraFileExtensionsHelpText": "Списък с допълнителни файлове за импортиране, разделени със запетая (.nfo ще бъде импортиран като .nfo-orig)",
|
||||
"ExtraFileExtensionsHelpTextsExamples": "Примери: '.sub, .nfo' или 'sub, nfo'"
|
||||
}
|
||||
|
||||
@@ -326,7 +326,6 @@
|
||||
"DownloadClientStatusCheckAllClientMessage": "Tots els clients de descàrrega no estan disponibles a causa d'errors",
|
||||
"DownloadClientStatusCheckSingleClientMessage": "Baixa els clients no disponibles a causa d'errors: {0}",
|
||||
"Duration": "durada",
|
||||
"ExtraFileExtensionsHelpTexts1": "Llista separada per comes de fitxers addicionals per importar (.nfo s'importarà com a .nfo-orig)",
|
||||
"FileWasDeletedByViaUI": "El fitxer s'ha suprimit mitjançant la interfície d'usuari",
|
||||
"GeneralSettingsSummary": "Port, SSL, nom d'usuari/contrasenya, servidor intermediari, analítiques i actualitzacions",
|
||||
"GrabRelease": "Captura novetat",
|
||||
@@ -528,7 +527,6 @@
|
||||
"CutoffUnmet": "Tall no assolit",
|
||||
"DeleteDelayProfileMessageText": "Esteu segur que voleu suprimir aquest perfil de retard?",
|
||||
"DeleteImportListExclusionMessageText": "Esteu segur que voleu suprimir aquesta exclusió de la llista d'importació?",
|
||||
"ExtraFileExtensionsHelpTexts2": "Exemples: '.sub, .nfo' o 'sub,nfo'",
|
||||
"HasPendingChangesSaveChanges": "Desa els canvis",
|
||||
"ICalLink": "Enllaç iCal`",
|
||||
"IgnoredHelpText": "La publicació es rebutjarà si conté un o més dels termes (no distingeix entre majúscules i minúscules)",
|
||||
|
||||
@@ -128,8 +128,6 @@
|
||||
"ErrorLoadingContents": "Chyba při načítání obsahu",
|
||||
"ErrorLoadingPreviews": "Chyba při načítání náhledů",
|
||||
"Exception": "Výjimka",
|
||||
"ExtraFileExtensionsHelpTexts1": "Seznam extra souborů k importu oddělených čárkami (.nfo bude importován jako .nfo-orig)",
|
||||
"ExtraFileExtensionsHelpTexts2": "Příklady: „.sub, .nfo“ nebo „sub, nfo“",
|
||||
"FailedDownloadHandling": "Zpracování stahování se nezdařilo",
|
||||
"FileDateHelpText": "Změnit datum souboru při importu / opětovném skenování",
|
||||
"FileManagement": "Správa souborů",
|
||||
@@ -680,5 +678,10 @@
|
||||
"DownloadClientTagHelpText": "Tohoto klienta pro stahování používat pouze pro filmy s alespoň jednou odpovídající značkou. Pro použití se všemi filmy ponechte prázdné pole.",
|
||||
"AddedAuthorSettings": "Nastavení umělce přidáno",
|
||||
"DownloadClientRemovesCompletedDownloadsHealthCheckMessage": "Klient stahování {downloadClientName} je nastaven na odstranění dokončených stahování. To může vést k tomu, že stahování budou z klienta odstraněna dříve, než je bude moci importovat {1}.",
|
||||
"IndexerTagsHelpText": "Tohoto klienta pro stahování používat pouze pro filmy s alespoň jednou odpovídající značkou. Pro použití se všemi filmy ponechte prázdné pole."
|
||||
"IndexerTagsHelpText": "Tohoto klienta pro stahování používat pouze pro filmy s alespoň jednou odpovídající značkou. Pro použití se všemi filmy ponechte prázdné pole.",
|
||||
"BlocklistReleaseHelpText": "Zabránit {appName}u v opětovném sebrání tohoto vydání",
|
||||
"ListsSettingsSummary": "Seznam k importu",
|
||||
"ExtraFileExtensionsHelpText": "Seznam extra souborů k importu oddělených čárkami (.nfo bude importován jako .nfo-orig)",
|
||||
"ExtraFileExtensionsHelpTextsExamples": "Příklady: „.sub, .nfo“ nebo „sub, nfo“",
|
||||
"ImportLists": "Seznam k importu"
|
||||
}
|
||||
|
||||
@@ -123,8 +123,6 @@
|
||||
"ErrorLoadingContents": "Fejl ved indlæsning af indhold",
|
||||
"ErrorLoadingPreviews": "Fejl ved indlæsning af forhåndsvisning",
|
||||
"Exception": "Undtagelse",
|
||||
"ExtraFileExtensionsHelpTexts1": "Kommasepareret liste over ekstra filer, der skal importeres (.nfo importeres som .nfo-orig)",
|
||||
"ExtraFileExtensionsHelpTexts2": "Eksempler: '.sub, .nfo' eller 'sub, nfo'",
|
||||
"FailedDownloadHandling": "Fejlet Download Håndtering",
|
||||
"FileDateHelpText": "Skift fildato ved import / genscanning",
|
||||
"FileManagement": "Fil Håndtering",
|
||||
@@ -635,5 +633,7 @@
|
||||
"Large": "Stor",
|
||||
"Library": "Bibliotek",
|
||||
"AllResultsAreHiddenByTheAppliedFilter": "Alle resultater skjules af det anvendte filter",
|
||||
"AddNewItem": "Tilføj Ny Genstand"
|
||||
"AddNewItem": "Tilføj Ny Genstand",
|
||||
"ExtraFileExtensionsHelpText": "Kommasepareret liste over ekstra filer, der skal importeres (.nfo importeres som .nfo-orig)",
|
||||
"ExtraFileExtensionsHelpTextsExamples": "Eksempler: '.sub, .nfo' eller 'sub, nfo'"
|
||||
}
|
||||
|
||||
@@ -9,52 +9,52 @@
|
||||
"About": "Über",
|
||||
"AddListExclusion": "Listenausschluss hinzufügen",
|
||||
"AddingTag": "Tag hinzufügen",
|
||||
"AgeWhenGrabbed": "Alter (beim erfassen)",
|
||||
"AlreadyInYourLibrary": "Bereits in deiner Mediathek",
|
||||
"AgeWhenGrabbed": "Alter (zum Zeitpunkt der Entführung)",
|
||||
"AlreadyInYourLibrary": "Bereits in Ihrer Bibliothek",
|
||||
"AlternateTitles": "Alternative Titel",
|
||||
"Analytics": "Analytik",
|
||||
"Analytics": "Analysen",
|
||||
"AnalyticsEnabledHelpText": "Sende anonyme Nutzungs- und Fehlerinformationen an die Server von Readarr. Dazu gehören Informationen über Browser, welche Seiten der Readarr-Weboberfläche aufgerufen wurden, Fehlerberichte sowie Betriebssystem- und Laufzeitversion. Wir werden diese Informationen verwenden, um Funktionen und Fehlerbehebungen zu priorisieren.",
|
||||
"AnalyticsEnabledHelpTextWarning": "Erfordert einen Neustart",
|
||||
"AppDataDirectory": "AppData Ordner",
|
||||
"ApplyTags": "Tags setzen",
|
||||
"AppDataDirectory": "AppData-Verzeichnis",
|
||||
"ApplyTags": "Schlagworte anwenden",
|
||||
"Authentication": "Authentifizierung",
|
||||
"AuthenticationMethodHelpText": "Für den Zugriff auf Readarr sind Benutzername und Passwort erforderlich",
|
||||
"AuthorClickToChangeBook": "Klicken um den Film zu bearbeiten",
|
||||
"AutoRedownloadFailedHelpText": "Automatisch nach einem anderen Release suchen",
|
||||
"AutoRedownloadFailedHelpText": "Suchen Sie automatisch nach einer anderen Version und versuchen Sie, sie herunterzuladen",
|
||||
"AutoUnmonitorPreviouslyDownloadedBooksHelpText": "Auf der Festplatte gelöschte Filme auch automatisch in Radarr nicht mehr beobachten",
|
||||
"Automatic": "Automatisch",
|
||||
"BackupFolderHelpText": "Relative Pfade befinden sich unter Readarrs AppData Ordner",
|
||||
"BackupNow": "Jetzt sichern",
|
||||
"BackupRetentionHelpText": "Automatische Backups, die älter als die Aufbewahrungsfrist sind, werden automatisch gelöscht",
|
||||
"BackupRetentionHelpText": "Automatische Backups, die älter als der Aufbewahrungszeitraum sind, werden automatisch bereinigt",
|
||||
"Backups": "Sicherungen",
|
||||
"BindAddress": "Adresse binden",
|
||||
"BindAddressHelpText": "Gültige IPv4 Adresse oder \"*\" für alle Netzwerke",
|
||||
"BindAddressHelpText": "Gültige IP-Adresse, localhost oder „*“ für alle Schnittstellen",
|
||||
"BookIsDownloading": "Film ist am herunterladen",
|
||||
"BookIsDownloadingInterp": "Film lädt herunter - {0}% {1}",
|
||||
"Branch": "Git-Branch",
|
||||
"Branch": "Branch",
|
||||
"BypassProxyForLocalAddresses": "Proxy für lokale Adressen umgehen",
|
||||
"Calendar": "Kalender",
|
||||
"CalendarWeekColumnHeaderHelpText": "Wird in der Wochenansicht über jeder Spalte angezeigt",
|
||||
"Cancel": "Abbrechen",
|
||||
"CancelMessageText": "Diese laufende Aufgabe wirklich abbrechen?",
|
||||
"CertificateValidation": "Zertifikat Validierung",
|
||||
"CertificateValidationHelpText": "Ändere wie streng die Validierung der HTTPS-Zertifizierung ist. Ändern Sie nicht wenn Ihnen die Risiken nicht bewusst sind.",
|
||||
"ChangeFileDate": "Erstelldatum der Datei anpassen",
|
||||
"CertificateValidation": "Zertifikatsvalidierung",
|
||||
"CertificateValidationHelpText": "Ändern Sie, wie streng die Validierung der HTTPS-Zertifizierung ist. Ändern Sie nichts, es sei denn, Sie verstehen die Risiken.",
|
||||
"ChangeFileDate": "Ändern Sie das Dateidatum",
|
||||
"ChangeHasNotBeenSavedYet": "Änderung wurde noch nicht gespeichert",
|
||||
"ChmodFolder": "chmod Ordner",
|
||||
"ChmodFolderHelpText": "Oktal, wird beim Importieren/Umbenennen von Medienordnern und Dateien angewendet (ohne Ausführungsbits)",
|
||||
"ChmodFolderHelpText": "Oktal, angewendet beim Importieren/Umbenennen auf Medienordner und -dateien (ohne Ausführungsbits)",
|
||||
"ChmodFolderHelpTextWarning": "Dies funktioniert nur, wenn der Benutzer, der Readarr ausführt, der Eigentümer der Datei ist. Es ist besser, sicherzustellen, dass der Download-Client die Berechtigungen richtig setzt.",
|
||||
"ChownGroupHelpText": "Gruppenname oder gid. Verwenden Sie gid für entfernte Dateisysteme.",
|
||||
"ChownGroupHelpText": "Gruppenname oder GID. Verwenden Sie GID für Remote-Dateisysteme.",
|
||||
"ChownGroupHelpTextWarning": "Dies funktioniert nur, wenn der Benutzer, der Radarr ausführt, der Eigentümer der Datei ist. Es ist besser, sicherzustellen, dass der Download-Client die gleiche Gruppe wie Radarr verwendet.",
|
||||
"Clear": "Leeren",
|
||||
"ClickToChangeQuality": "Hier klicken um die Qualität zu ändern",
|
||||
"ClickToChangeQuality": "Klicken Sie, um die Qualität zu ändern",
|
||||
"ClientPriority": "Priorität",
|
||||
"CloneIndexer": "Indexer kopieren",
|
||||
"CloneProfile": "Profil kopieren",
|
||||
"CloneIndexer": "Indexer klonen",
|
||||
"CloneProfile": "Profil klonen",
|
||||
"Close": "Schließen",
|
||||
"Columns": "Spalten",
|
||||
"CompletedDownloadHandling": "Verarbeitung abgeschlossener Downloads",
|
||||
"ConnectSettings": "Eintellungen für Verbindungen",
|
||||
"CompletedDownloadHandling": "Download-Handhabung abgeschlossen",
|
||||
"ConnectSettings": "Verbindungseinstellungen",
|
||||
"Connections": "Verbindungen",
|
||||
"CopyUsingHardlinksHelpText": "Hardlinks erstellen wenn Torrents die noch geseeded werden kopiert werden sollen",
|
||||
"CopyUsingHardlinksHelpTextWarning": "Dateisperren Gelegentlich kann es vorkommen, dass Dateisperren das Umbenennen von Dateien verhindern, die gerade geseeded werden. Sie können das Seeding vorübergehend deaktivieren und die Umbenennungsfunktion von Readarr als Workaround verwenden.",
|
||||
@@ -68,24 +68,22 @@
|
||||
"DelayProfiles": "Verzögerungsprofile",
|
||||
"DelayingDownloadUntilInterp": "Download verzögern bis {0} um {1}",
|
||||
"Delete": "Löschen",
|
||||
"DeleteBackup": "Backup löschen",
|
||||
"DeleteBackupMessageText": "Backup '{0}' wirkich löschen?",
|
||||
"DeleteBackup": "Sicherung löschen",
|
||||
"DeleteBackupMessageText": "Sind Sie sicher, dass Sie die Sicherung „{name}“ löschen möchten?",
|
||||
"DeleteDelayProfile": "Verzögerungsprofil löschen",
|
||||
"DeleteDelayProfileMessageText": "Bist du sicher, dass du dieses Verzögerung-Profil löschen willst?",
|
||||
"DeleteDownloadClient": "Downloader löschen",
|
||||
"DeleteDownloadClientMessageText": "Downloader '{0}' wirklich löschen?",
|
||||
"DeleteDelayProfileMessageText": "Sind Sie sicher, dass Sie dieses Verzögerungsprofil löschen möchten?",
|
||||
"DeleteDownloadClient": "Download-Client löschen",
|
||||
"DeleteDownloadClientMessageText": "Sind Sie sicher, dass Sie den Download-Client „{name}“ löschen möchten?",
|
||||
"DeleteEmptyFolders": "Leere Ordner löschen",
|
||||
"DeleteEmptyFoldersHelpText": "Lösche leere Autorordner während des Scans oder wenn Buchdateien gelöscht werden",
|
||||
"DeleteImportListExclusion": "Importlisten Ausschluss löschen",
|
||||
"DeleteImportListExclusionMessageText": "Bist du sicher, dass du diesen Importlisten Ausschluss löschen willst?",
|
||||
"DeleteImportListMessageText": "Liste '{0}' wirklich löschen?",
|
||||
"DeleteImportListMessageText": "Sind Sie sicher, dass Sie die Liste „{name}“ löschen möchten?",
|
||||
"DeleteIndexer": "Indexer löschen",
|
||||
"DeleteIndexerMessageText": "Indexer '{0}' wirklich löschen?",
|
||||
"DeleteIndexerMessageText": "Sind Sie sicher, dass Sie den Indexer „{name}“ löschen möchten?",
|
||||
"DeleteMetadataProfileMessageText": "Qualitätsprofil '{0}' wirklich löschen?",
|
||||
"DeleteNotification": "Benachrichtigung löschen",
|
||||
"DeleteNotificationMessageText": "Benachrichtigung '{0}' wirklich löschen?",
|
||||
"DeleteQualityProfile": "Qualitätsdefinition löschen",
|
||||
"DeleteQualityProfileMessageText": "Qualitätsprofil '{0}' wirklich löschen?",
|
||||
"DeleteNotificationMessageText": "Sind Sie sicher, dass Sie die Benachrichtigung „{name}“ löschen möchten?",
|
||||
"DeleteQualityProfile": "Qualitätsprofil löschen",
|
||||
"DeleteQualityProfileMessageText": "Sind Sie sicher, dass Sie das Qualitätsprofil „{name}“ löschen möchten?",
|
||||
"DeleteReleaseProfile": "Release-Profil löschen",
|
||||
"DeleteReleaseProfileMessageText": "Bist du sicher, dass du dieses Release-Profil löschen willst?",
|
||||
"DeleteRootFolderMessageText": "Indexer '{0}' wirklich löschen?",
|
||||
@@ -94,11 +92,10 @@
|
||||
"DeleteTag": "Tag löschen",
|
||||
"DeleteTagMessageText": "Tag '{0}' wirklich löschen?",
|
||||
"DestinationPath": "Zielpfad",
|
||||
"DetailedProgressBar": "Erweiterter Fortschrittsbalken",
|
||||
"DetailedProgressBar": "Detaillierter Fortschrittsbalken",
|
||||
"DetailedProgressBarHelpText": "Text auf Fortschrittsbalken anzeigen",
|
||||
"DiskSpace": "Speicherplatz",
|
||||
"DiskSpace": "Festplattenplatz",
|
||||
"Docker": "Docker",
|
||||
"DownloadClient": "Downloader",
|
||||
"DownloadClientSettings": "Downloader Einstellungen",
|
||||
"DownloadClients": "Downloader",
|
||||
"DownloadFailedCheckDownloadClientForMoreDetails": "Download fehlgeschlagen: Prüfe den Downloader für mehr Details",
|
||||
@@ -122,8 +119,6 @@
|
||||
"ErrorLoadingContents": "Fehler beim laden der Inhalte",
|
||||
"ErrorLoadingPreviews": "Fehler beim laden der Vorschauen",
|
||||
"Exception": "Ausnahme",
|
||||
"ExtraFileExtensionsHelpTexts1": "Kommaseparierte Liste von Dateiendungen die als Extra Dateien importiert werden sollen ( .nfo wird in .nfo-orig umbenannt )",
|
||||
"ExtraFileExtensionsHelpTexts2": "Vorschläge: sub, nfo, srt, jpg",
|
||||
"FailedDownloadHandling": "Verarbeitung fehlgeschlagener Downloads",
|
||||
"FileDateHelpText": "Aktualisiere das Erstelldatum beim Import oder Re-Scan",
|
||||
"FileManagement": "Dateiverwaltung",
|
||||
@@ -277,15 +272,15 @@
|
||||
"RemotePathMappings": "Remote-Pfadzuordnungen",
|
||||
"Remove": "Entfernen",
|
||||
"RemoveCompletedDownloadsHelpText": "Importierte Downloads aus dem Downloader Verlauf entfernen",
|
||||
"RemoveFailedDownloadsHelpText": "Fehlgeschlagene Downloads aus dem Downloader Verlauf entfernen",
|
||||
"RemoveFailedDownloadsHelpText": "Entfernen Sie fehlgeschlagene Downloads aus dem Download-Client-Verlauf",
|
||||
"RemoveFilter": "Filter entfernen",
|
||||
"RemoveFromDownloadClient": "Aus dem Downloader entfernen",
|
||||
"RemoveFromDownloadClient": "Vom Download-Client entfernen",
|
||||
"RemoveFromQueue": "Aus der Warteschlage entfernen",
|
||||
"RemoveHelpTextWarning": "Dies wird den Download und alle bereits heruntergeladenen Dateien aus dem Downloader entfernen.",
|
||||
"RemoveSelected": "Auswahl entfernen",
|
||||
"RemoveTagExistingTag": "Vorhandener Tag",
|
||||
"RemoveTagRemovingTag": "Tag entfernen",
|
||||
"RemovedFromTaskQueue": "Aus der Aufgabenwarteschlage entfernt",
|
||||
"RemovedFromTaskQueue": "Aus der Aufgabenwarteschlange entfernt",
|
||||
"RenameBooksHelpText": "Wenn das umbennen deaktiviert ist, wird der vorhandene Dateiname benutzt",
|
||||
"Reorder": "Neu sortieren",
|
||||
"ReplaceIllegalCharacters": "Sonderzeichen ersetzen",
|
||||
@@ -295,15 +290,14 @@
|
||||
"RescanAuthorFolderAfterRefresh": "Nach dem Aktualisieren den Autorordner neu scannen",
|
||||
"Reset": "Zurücksetzen",
|
||||
"ResetAPIKey": "API-Schlüssel zurücksetzen",
|
||||
"ResetAPIKeyMessageText": "Bist du sicher, dass du den API-Schlüssel zurücksetzen willst?",
|
||||
"Restart": "Neustarten",
|
||||
"ResetAPIKeyMessageText": "Sind Sie sicher, dass Sie Ihren API-Schlüssel zurücksetzen möchten?",
|
||||
"Restart": "Neu starten",
|
||||
"RestartNow": "Jetzt neustarten",
|
||||
"RestartReadarr": "Radarr Neustarten",
|
||||
"Restore": "Wiederherstellen",
|
||||
"RestoreBackup": "Backup einspielen",
|
||||
"RestoreBackup": "Sicherung wiederherstellen",
|
||||
"Result": "Ergebnis",
|
||||
"Retention": "Aufbewahrung ( Retention )",
|
||||
"RetentionHelpText": "Nur Usenet: Für eine umbegrenzte Aufbewahrung auf 0 setzen",
|
||||
"RetentionHelpText": "Nur Usenet: Auf Null setzen, um eine unbegrenzte Aufbewahrung festzulegen",
|
||||
"RetryingDownloadInterp": "Herunterladen nochmal versuchen {0} um {1}",
|
||||
"RootFolder": "Stammordner",
|
||||
"RootFolders": "Stammordner",
|
||||
@@ -318,16 +312,14 @@
|
||||
"SearchForMissing": "Suche fehlende",
|
||||
"SearchSelected": "Auswahl suchen",
|
||||
"Security": "Sicherheit",
|
||||
"SendAnonymousUsageData": "Anonyme Nutzungsdaten übertragen",
|
||||
"SendAnonymousUsageData": "Sende anonyme Nutzungsdaten",
|
||||
"SetPermissions": "Rechte setzen",
|
||||
"SetPermissionsLinuxHelpText": "Soll CHMOD ausgeführt werden wenn Datien importiert/umbenannt werden?",
|
||||
"SetPermissionsLinuxHelpTextWarning": "Ändere diese Einstellung nur, wenn du weißt was sie bewirken.",
|
||||
"SetPermissionsLinuxHelpTextWarning": "Wenn Sie nicht sicher sind, was diese Einstellungen bewirken, ändern Sie sie nicht.",
|
||||
"Settings": "Einstellungen",
|
||||
"ShortDateFormat": "Kurzes Datumsformat",
|
||||
"ShowCutoffUnmetIconHelpText": "Symbol zeigen wenn die Qualitätsschwelle noch nicht erreicht wurde",
|
||||
"ShowDateAdded": "Datum \"Hinzugefügt\" anzeigen",
|
||||
"ShowMonitored": "Beobachtete anzeigen",
|
||||
"ShowMonitoredHelpText": "Beobachtungsstatus unter dem Plakat anzeigen",
|
||||
"ShowDateAdded": "Datum der Hinzufügung anzeigen",
|
||||
"ShowPath": "Pfad anzeigen",
|
||||
"ShowQualityProfile": "Qualitätsdefinition anzeigen",
|
||||
"ShowQualityProfileHelpText": "Qualitätsprofil unter dem Plakat anzeigen",
|
||||
@@ -344,9 +336,9 @@
|
||||
"SorryThatBookCannotBeFound": "Schade, dieser Film kann nicht gefunden werden.",
|
||||
"Source": "Quelle",
|
||||
"SourcePath": "Quellpfad",
|
||||
"SslCertPasswordHelpText": "Passwort für die PFX Datei",
|
||||
"SslCertPasswordHelpText": "Passwort für die PFX-Datei",
|
||||
"SslCertPasswordHelpTextWarning": "Erfordert einen Neustart",
|
||||
"SslCertPathHelpText": "Pfad zur PFX Datei",
|
||||
"SslCertPathHelpText": "Pfad zur PFX-Datei",
|
||||
"SslCertPathHelpTextWarning": "Erfordert einen Neustart",
|
||||
"StandardBookFormat": "Standard Filmformat",
|
||||
"StartTypingOrSelectAPathBelow": "Eingeben oder unten auswählen",
|
||||
@@ -360,20 +352,18 @@
|
||||
"SupportsSearchvalueSearchIsNotSupportedWithThisIndexer": "Der Indexer unterstützt keine Suchen",
|
||||
"SupportsSearchvalueWillBeUsedWhenAutomaticSearchesArePerformedViaTheUIOrByReadarr": "Wird für automatische Suchen genutzt die vom Benutzer oder von Radarr gestartet werden",
|
||||
"SupportsSearchvalueWillBeUsedWhenInteractiveSearchIsUsed": "Wird für die manuelle Suche benutzt",
|
||||
"TagIsNotUsedAndCanBeDeleted": "Tag wird nicht benutzt und kann gelöscht werden",
|
||||
"Tags": "Tags",
|
||||
"Tasks": "Aufgaben",
|
||||
"TestAll": "Alle testen",
|
||||
"TestAllClients": "Alle testen",
|
||||
"TestAllIndexers": "Alle testen",
|
||||
"TestAllLists": "Alle testen",
|
||||
"TestAll": "Alle prüfen",
|
||||
"TestAllClients": "Prüfe alle Clients",
|
||||
"TestAllIndexers": "Prüfe alle Indexer",
|
||||
"TestAllLists": "Prüfe alle Listen",
|
||||
"ThisWillApplyToAllIndexersPleaseFollowTheRulesSetForthByThem": "Dies wird alle Indexer betreffen. Bitte folge deren Regeln",
|
||||
"TimeFormat": "Zeitformat",
|
||||
"Title": "Titel",
|
||||
"TorrentDelay": "Torrent Verzögerung",
|
||||
"TorrentDelayHelpText": "Verzögerung in Minuten bevor ein Torrent-Release erfasst wird",
|
||||
"TorrentDelay": "Torrent-Verzögerung",
|
||||
"TorrentDelayHelpText": "Verzögerung in Minuten, bevor ein Torrent herunterladen wird",
|
||||
"Torrents": "Torrents",
|
||||
"TotalFileSize": "Gesamte Dateigröße",
|
||||
"TotalFileSize": "Gesamtdateigröße",
|
||||
"UILanguage": "Oberflächen Sprache ( UI Language )",
|
||||
"UILanguageHelpText": "Sprache für die gesamte Oberfläche",
|
||||
"UILanguageHelpTextWarning": "Seite muss neugeladen werden",
|
||||
@@ -388,7 +378,7 @@
|
||||
"UnableToAddANewQualityProfilePleaseTryAgain": "Das neue Qualitätsprofil konnte nicht hinzugefügt werden, bitte erneut probieren.",
|
||||
"UnableToAddANewRemotePathMappingPleaseTryAgain": "Die neue entfernte Pfadzuordnung konnte nicht hinzugefügt werden, bitte erneut probieren.",
|
||||
"UnableToAddANewRootFolderPleaseTryAgain": "Das neue eigene Format konnte nicht hinzugefügt werden, bitte erneut probieren.",
|
||||
"UnableToLoadBackups": "Backups konnten nicht geladen werden",
|
||||
"UnableToLoadBackups": "Sicherungen können nicht geladen werden",
|
||||
"UnableToLoadDelayProfiles": "Verzögerungsprofile konnten nicht geladen werden",
|
||||
"UnableToLoadDownloadClientOptions": "Downloader Einstellungen konnten nicht geladen werden",
|
||||
"UnableToLoadDownloadClients": "Downloader konnten nicht geladen werden",
|
||||
@@ -407,32 +397,31 @@
|
||||
"UnableToLoadQualityProfiles": "Qualitätsprofile konnten nicht geladen werden",
|
||||
"UnableToLoadReleaseProfiles": "Verzögerungsprofile konnten nicht geladen werden",
|
||||
"UnableToLoadRemotePathMappings": "Entfernte Pfadzuordnungen konnten nicht geladen werden",
|
||||
"UnableToLoadRootFolders": "Stammordner konnten nicht geladen werden",
|
||||
"UnableToLoadRootFolders": "Stammordner können nicht geladen werden",
|
||||
"UnableToLoadTags": "Tags konnten nicht geladen werden",
|
||||
"UnableToLoadTheCalendar": "Kalender konnte nicht geladen werden",
|
||||
"UnableToLoadUISettings": "Oberflächen Einstellungen konnten nicht geladen werden",
|
||||
"Ungroup": "Gruppe entfernen",
|
||||
"Unmonitored": "Nicht beobachtet",
|
||||
"UnmonitoredHelpText": "Nicht beobachtete Filme im iCal-Feed einschließen",
|
||||
"UpdateAll": "Alle aktualisieren",
|
||||
"UpdateAutomaticallyHelpText": "Updates automatisch herunteraden und installieren. Es kann weiterhin unter \"System -> Updates\" ein manuelles Update angestoßen werden",
|
||||
"UpdateAutomaticallyHelpText": "Updates automatisch herunterladen und installieren. Sie können weiterhin über System: Updates installieren",
|
||||
"UpdateMechanismHelpText": "Readarr's Built-In Updater oder ein Script verwenden",
|
||||
"UpdateScriptPathHelpText": "Pfad zu einem benutzerdefinierten Skript, das ein extrahiertes Update-Paket übernimmt und den Rest des Update-Prozesses abwickelt",
|
||||
"Updates": "Updates",
|
||||
"Updates": "Aktualisierung",
|
||||
"UpgradeAllowedHelpText": "Wenn deaktiviert wird die Qualität nicht verbessert",
|
||||
"Uptime": "Laufzeit",
|
||||
"Uptime": "Betriebszeit",
|
||||
"UrlBaseHelpTextWarning": "Erfordert einen Neustart",
|
||||
"UseHardlinksInsteadOfCopy": "Hardlinks anstatt kopieren verwenden",
|
||||
"UseProxy": "Proxy benutzen",
|
||||
"UsenetDelay": "Usenet Verzögerung",
|
||||
"UsenetDelayHelpText": "Verzögerung in Minuten before ein Usenet-Release erfasst wird",
|
||||
"Username": "Benutzername",
|
||||
"UseHardlinksInsteadOfCopy": "Verwende Hardlinks statt Kopieren",
|
||||
"UseProxy": "Verwende Proxy",
|
||||
"UsenetDelay": "Usenet-Verzögerung",
|
||||
"UsenetDelayHelpText": "Verzögerung in Minuten, bevor Sie eine Veröffentlichung aus dem Usenet erhalten",
|
||||
"Username": "Nutzername",
|
||||
"UsingExternalUpdateMechanismBranchToUseToUpdateReadarr": "Branch zum updaten von Radarr",
|
||||
"UsingExternalUpdateMechanismBranchUsedByExternalUpdateMechanism": "Branch für den externen Updateablauf",
|
||||
"Version": "Version",
|
||||
"WeekColumnHeader": "Wochen Spalten Titel",
|
||||
"WeekColumnHeader": "Spaltenüberschrift „Woche“.",
|
||||
"Year": "Jahr",
|
||||
"YesCancel": "Ja, abbrechen",
|
||||
"YesCancel": "Ja Abbrechen",
|
||||
"BindAddressHelpTextWarning": "Erfordert einen Neustart",
|
||||
"LoadingBooksFailed": "Laden der Film-Dateien fehlgeschlagen",
|
||||
"ProxyUsernameHelpText": "Sie müssen nur einen Benutzernamen und ein Passwort eingeben, wenn dies erforderlich ist. Andernfalls lassen Sie sie leer.",
|
||||
@@ -513,12 +502,12 @@
|
||||
"BlocklistRelease": "Release sperren",
|
||||
"RescanAfterRefreshHelpText": "Nach dem aktualisieren des Films, den Filmordner neu scannen",
|
||||
"ShowUnknownAuthorItems": "Unzugeordente Filmeinträge anzeigen",
|
||||
"SelectAll": "Alle wählen",
|
||||
"SelectAll": "Alles auswählen",
|
||||
"SelectedCountBooksSelectedInterp": "{0} Film(e) ausgewählt",
|
||||
"ThisCannotBeCancelled": "Nach dem Start kann dies nicht mehr abgebrochen werden ohne alle Indexer zu deaktivieren.",
|
||||
"UnselectAll": "Keine wählen",
|
||||
"UnselectAll": "Alle abwählen",
|
||||
"UpdateSelected": "Auswahl aktualisieren",
|
||||
"Wanted": "› Gesuchte",
|
||||
"Wanted": "Gesucht",
|
||||
"CreateEmptyAuthorFolders": "Leere Filmordner erstellen",
|
||||
"All": "Alle",
|
||||
"Country": "Land",
|
||||
@@ -582,7 +571,7 @@
|
||||
"TrackNumber": "Titelnummer",
|
||||
"ExistingBooks": "Existierende Bücher",
|
||||
"BookList": "Buchliste",
|
||||
"Continuing": "Fortsetzen",
|
||||
"Continuing": "Fortsetzung",
|
||||
"ExistingItems": "Existierende Artikel",
|
||||
"ForeignIdHelpText": "Die Musicbrainz Id des Autors/Buches die ausgeschlossen werden soll",
|
||||
"IndexersSettingsSummary": "Indexer- und Releasebeschränkungen",
|
||||
@@ -603,7 +592,7 @@
|
||||
"PreviewRetag": "Retag Vorschau",
|
||||
"EnabledHelpText": "Anhaken um Veröffentlichungsprofile zu aktivieren",
|
||||
"EntityName": "Objekt Name",
|
||||
"ShowBanners": "Zeige Banner",
|
||||
"ShowBanners": "Banner anzeigen",
|
||||
"ShowBannersHelpText": "Zeige Banner anstatt Namen",
|
||||
"ImportFailures": "Importfehler",
|
||||
"IndexerIdHelpText": "Angabe, welcher Indexer für das Profil gilt",
|
||||
@@ -630,7 +619,7 @@
|
||||
"StatusEndedContinuing": "Fortfahren",
|
||||
"UnableToLoadMetadataProviderSettings": "Einstellungen für Metadata Provider konnten nicht geladen werden",
|
||||
"UpdatingIsDisabledInsideADockerContainerUpdateTheContainerImageInstead": "Aktualisierung innerhalb des Docker Containers ist deaktiviert. Aktualisieren Sie stattdessen das Container Image.",
|
||||
"Started": "gestartet",
|
||||
"Started": "Gestartet",
|
||||
"ContinuingNoAdditionalBooksAreExpected": "Keine weiteren Bücher werden erwartet",
|
||||
"DefaultMetadataProfileIdHelpText": "Standard Metadaten Profil für in diesem Ordner erkannte Autoren",
|
||||
"DefaultMonitorOptionHelpText": "Welche Bücher sollen beim erstmaligen Hinzufügen von Autoren, die in diesem Ordner gefunden wurden beobachtet werden",
|
||||
@@ -689,7 +678,7 @@
|
||||
"AllowFingerprintingHelpText": "Benutze Fingerabdrücke um die Genauigkeit der Buch Übereinstimmungen zu verbessern",
|
||||
"AllowFingerprintingHelpTextWarning": "Dies erfordert, dass Readarr Teile der Datei ließt, was dazu führt, dass Scans verlangsamt werden und eventuell hohe Schreib-/Netzwerkaktivitäten entstehen.",
|
||||
"AddImportListExclusionHelpText": "Verhindern, dass ein Buch zu Readarr durch Importlisten oder Aktualisierung des Autors hinzugefügt wird",
|
||||
"TimeLeft": "Restzeit",
|
||||
"TimeLeft": "Zeit übrig",
|
||||
"UpdateCheckStartupTranslocationMessage": "Update kann nicht installiert werden, da sich der Startordner '{0}' in einem App Translocation-Ordner befindet.",
|
||||
"PathHelpText": "Stammordner für die Musikbibliothek",
|
||||
"ProxyCheckBadRequestMessage": "Proxy konnte nicht getestet werden. StatusCode: {0}",
|
||||
@@ -758,12 +747,12 @@
|
||||
"AddList": "Liste hinzufügen",
|
||||
"InstanceName": "Instanzname",
|
||||
"InstanceNameHelpText": "Instanzname im Browser-Tab und für Syslog-Anwendungsname",
|
||||
"RestartRequiredHelpTextWarning": "Erfordert einen Neustart",
|
||||
"RestartRequiredHelpTextWarning": "Erfordert einen Neustart, damit die Aktion wirksam wird",
|
||||
"UseCalibreContentServer": "Calibre-Content-Server",
|
||||
"DataExistingBooks": "Beobachte Bücher die Dateien haben oder noch nicht veröffentlicht wurden",
|
||||
"DataFirstBook": "Beobachte das erste Buch. Alle anderen Bücher werden ignoriert",
|
||||
"DataMissingBooks": "Beobachte Bücher, die noch keine Dateien haben oder noch nicht veröffentlicht wurden",
|
||||
"Test": "Testen",
|
||||
"Test": "Prüfen",
|
||||
"DataNone": "Es werden keine Bücher beobachtet",
|
||||
"RenameFiles": "Dateien umbenennen",
|
||||
"LoadingEditionsFailed": "Das Laden der Ausgaben ist fehlgeschlagen",
|
||||
@@ -858,36 +847,36 @@
|
||||
"TagsHelpText": "Gilt für Autoren mit mindestens einem passenden Tag. Leer lassen, um auf alle Autoren anzuwenden",
|
||||
"TagsSettingsSummary": "Verwalten von Autoren-, Profil-, Beschränkungs- und Benachrichtigungs-Tags",
|
||||
"ApplicationURL": "Anwendungs-URL",
|
||||
"ApplicationUrlHelpText": "Die externe URL der Anwendung inklusive http(s)://, Port und URL-Basis",
|
||||
"ApplicationUrlHelpText": "Die externe URL dieser Anwendung, einschließlich http(s)://, Port und URL-Basis",
|
||||
"HardlinkCopyFiles": "Hardlink/Dateien kopieren",
|
||||
"MoveFiles": "Dateien verschieben",
|
||||
"OnApplicationUpdate": "Bei Anwendungsaktualisierung",
|
||||
"OnApplicationUpdateHelpText": "Bei Anwendungsaktualisierung",
|
||||
"ChooseImportMethod": "Wähle eine Importmethode",
|
||||
"ClickToChangeReleaseGroup": "Releasegruppe ändern",
|
||||
"ClickToChangeReleaseGroup": "Klicken Sie hier, um die Release-Gruppe zu ändern",
|
||||
"EnableRssHelpText": "Wird benutzt, wenn Radarr mittels RSS-Sync regelmäßig nach Releases schaut",
|
||||
"Theme": "Design",
|
||||
"ThemeHelpText": "Anwendungsdesign ändern, das 'Auto' Design passt sich an den Light/Dark-Mode deines Systems an. Inspiriert von Theme.Park",
|
||||
"ThemeHelpText": "Ändern Sie das Benutzeroberflächen-Design der Anwendung. Das „Auto“-Design verwendet Ihr Betriebssystemdesign, um den Hell- oder Dunkelmodus festzulegen. Inspiriert vom Theme.Park",
|
||||
"BypassIfHighestQuality": "Ignoriere wenn höchste Qualität",
|
||||
"MinimumCustomFormatScore": "Minimum der eigenen Formate Bewertungspunkte",
|
||||
"CustomFormatScore": "Eigenes Format Bewertungspunkte",
|
||||
"CloneCustomFormat": "Eigenes Format kopieren",
|
||||
"CloneCustomFormat": "Benutzerdefiniertes Format klonen",
|
||||
"Conditions": "Bedingungen",
|
||||
"CopyToClipboard": "In die Zwischenablage kopieren",
|
||||
"CustomFormat": "Eigenes Format",
|
||||
"CustomFormats": "Eigene Formate",
|
||||
"CustomFormat": "Benutzerdefiniertes Format",
|
||||
"CustomFormats": "Benutzerdefinierte Formate",
|
||||
"CutoffFormatScoreHelpText": "Sobald diese eigener Format Bewertung erreicht wird, werden keine neuen Releases erfasst",
|
||||
"DeleteFormatMessageText": "Bist du sicher, dass du das Formatierungstag {0} löschen willst?",
|
||||
"ExportCustomFormat": "Eigenes Format exportieren",
|
||||
"Formats": "Formate",
|
||||
"MinFormatScoreHelpText": "Mindester eigener Format Score bis zum Download",
|
||||
"NegateHelpText": "Wenn aktiviert wird das eigene Format nicht angewendet solange diese {0} Bedingung zutrifft.",
|
||||
"ResetDefinitionTitlesHelpText": "Definitionstitel und Werte zurücksetzen",
|
||||
"ResetDefinitionTitlesHelpText": "Definitionstitel und -werte zurücksetzen",
|
||||
"ResetDefinitions": "Definitionen zurücksetzen",
|
||||
"UpgradesAllowed": "Upgrades erlaubt",
|
||||
"CustomFormatSettings": "Einstellungen für eigene Formate",
|
||||
"DataFutureBooks": "Überwachung von Alben die noch nicht veröffentlicht wurden",
|
||||
"DeleteCustomFormat": "Eigenes Format löschen",
|
||||
"DeleteCustomFormat": "Benutzerdefiniertes Format löschen",
|
||||
"DeleteCustomFormatMessageText": "Bist du sicher, dass du das eigene Format '{0}' löschen willst?",
|
||||
"IncludeCustomFormatWhenRenamingHelpText": "In {Custom Formats} umbennenungs Format",
|
||||
"ResetTitles": "Titel zurücksetzen",
|
||||
@@ -899,21 +888,21 @@
|
||||
"RecycleBinUnableToWriteHealthCheck": "Schreiben in konfigurierten Papierkorbordner nicht möglich: {0}. Stelle sicher, dass dieser Pfad existiert und von dem Benutzer, der Radarr ausführt, beschreibbar ist",
|
||||
"HiddenClickToShow": "Versteckt, klicken zum anzeigen",
|
||||
"HideAdvanced": "Erweiterte Ansicht",
|
||||
"ShowAdvanced": "Einfache Ansicht",
|
||||
"ShownClickToHide": "Angezeigt, zum verstecken klicken",
|
||||
"ColonReplacement": "Doppelpunkt-Ersatz",
|
||||
"ShowAdvanced": "Erweitert anzeigen",
|
||||
"ShownClickToHide": "Angezeigt, zum Ausblenden klicken",
|
||||
"ColonReplacement": "Doppelpunktersatz",
|
||||
"ReplaceWithDash": "Mit Bindestrich ersetzen",
|
||||
"ReplaceWithSpaceDash": "Mit Leerzeichen Bindestrich ersetzen",
|
||||
"ReplaceWithSpaceDashSpace": "Mit Leerzeichen Bindestrich Leerzeichen ersetzen",
|
||||
"ApiKeyValidationHealthCheckMessage": "Bitte den API Schlüssel korrigieren, dieser muss mindestens {0} Zeichen lang sein. Die Änderung kann über die Einstellungen oder die Konfigurationsdatei erfolgen",
|
||||
"ThereWasAnErrorLoadingThisItem": "Beim Laden des Eintrags ist ein Fehler aufgetreten",
|
||||
"ThereWasAnErrorLoadingThisPage": "Beim Laden der Seite ist ein Fehler aufgetreten",
|
||||
"DeleteRemotePathMapping": "Entfernte Pfadzuordnung löschen",
|
||||
"DeleteRemotePathMappingMessageText": "Bist du sicher, dass du das diese entfernte Pfadzuordnung löschen willst?",
|
||||
"DeleteRemotePathMapping": "Remote-Pfad-Zuordnung löschen",
|
||||
"DeleteRemotePathMappingMessageText": "Sind Sie sicher, dass Sie diese Remote-Pfadzuordnung löschen möchten?",
|
||||
"CloneCondition": "Bedingung klonen",
|
||||
"DeleteCondition": "Bedingung löschen",
|
||||
"RemoveSelectedItemBlocklistMessageText": "Bist du sicher, dass du die ausgewählten Einträge aus der Sperrliste entfernen willst?",
|
||||
"ResetQualityDefinitionsMessageText": "Bist du sicher, dass du die Qualitätsdefinitionen zurücksetzen willst?",
|
||||
"ResetQualityDefinitionsMessageText": "Sind Sie sicher, dass Sie Qualitätsdefinitionen zurücksetzen möchten?",
|
||||
"RemoveSelectedItemQueueMessageText": "Bist du sicher, dass du ein Eintrag aus der Warteschlange entfernen willst?",
|
||||
"RemoveSelectedItemsQueueMessageText": "Bist du sicher, dass du {0} Einträge aus der Warteschlange entfernen willst?",
|
||||
"ListRefreshInterval": "Listen Aktualisierungsintervall",
|
||||
@@ -921,7 +910,7 @@
|
||||
"ApplyTagsHelpTextHowToApplyAuthors": "Wie werden Tags zu ausgewählten Indexern zugeteilt",
|
||||
"DeleteSelectedImportLists": "Lösche Einspiel Liste",
|
||||
"DownloadClientTagHelpText": "Benutze den Indexer nur für Filme mit mindesens einen zutreffenden Tag. Leer lassen für alle Filme.",
|
||||
"DeleteSelectedIndexersMessageText": "Indexer '{0}' wirklich löschen?",
|
||||
"DeleteSelectedIndexersMessageText": "Sind Sie sicher, dass Sie {count} ausgewählte(n) Indexer löschen möchten?",
|
||||
"EditSelectedDownloadClients": "Ausgewählte Download Clienten bearbeiten",
|
||||
"Implementation": "Integration",
|
||||
"NoEventsFound": "Keine Events gefunden",
|
||||
@@ -938,24 +927,24 @@
|
||||
"Negated": "Negiert",
|
||||
"ResetQualityDefinitions": "Qualitätsdefinitionen zurücksetzen",
|
||||
"RemoveSelectedItem": "Entferne ausgewählten Eintrag",
|
||||
"RemoveSelectedItems": "Entferne ausgewählte Einträge",
|
||||
"RemoveSelectedItems": "Markierte Einträge löschen",
|
||||
"Required": "Erforderlich",
|
||||
"RedownloadFailed": "Download fehlgeschlagen",
|
||||
"RemoveFailed": "Entfernen fehlgeschlagen",
|
||||
"RemoveFailed": "Entferne fehlgeschlagene",
|
||||
"RemoveCompleted": "Abgeschlossene entfernen",
|
||||
"ApplyChanges": "Änderungen anwenden",
|
||||
"ApplyTagsHelpTextAdd": "Hinzufügen: Füge neu Tags zu den existierenden Tags hinzu",
|
||||
"ApplyTagsHelpTextHowToApplyImportLists": "Wie werden Tags zu ausgewählten Filmen zugeteilt",
|
||||
"ApplyTagsHelpTextHowToApplyIndexers": "Wie werden Tags zu ausgewählten Indexern zugeteilt",
|
||||
"ApplyTagsHelpTextAdd": "Hinzufügen: Fügen Sie die Tags der vorhandenen Tag-Liste hinzu",
|
||||
"ApplyTagsHelpTextHowToApplyImportLists": "So wenden Sie Tags auf die ausgewählten Importlisten an",
|
||||
"ApplyTagsHelpTextHowToApplyIndexers": "So wenden Sie Tags auf die ausgewählten Indexer an",
|
||||
"AutomaticAdd": "Automatisch hinzufügen",
|
||||
"ApplyTagsHelpTextRemove": "Entfernen: Eingegebene Tags entfernen",
|
||||
"ApplyTagsHelpTextReplace": "Ersetzen: Nur eingegebene Tags übernehmen und vorhandene entfernen( keine Tags eingeben um alle zu entfernen )",
|
||||
"ApplyTagsHelpTextHowToApplyDownloadClients": "Wie werden Tags zu ausgewählten Filmen zugeteilt",
|
||||
"ApplyTagsHelpTextRemove": "Entfernen: Die eingegebenen Tags entfernen",
|
||||
"ApplyTagsHelpTextReplace": "Ersetzen: Ersetzen Sie die Tags durch die eingegebenen Tags (geben Sie keine Tags ein, um alle Tags zu löschen).",
|
||||
"ApplyTagsHelpTextHowToApplyDownloadClients": "So wenden Sie Tags auf die ausgewählten Download-Clients an",
|
||||
"CountIndexersSelected": "{0} Indexer ausgewählt",
|
||||
"DeleteSelectedDownloadClients": "Lösche Download Client(s)",
|
||||
"DeleteSelectedDownloadClientsMessageText": "Indexer '{0}' wirklich löschen?",
|
||||
"DeleteSelectedDownloadClientsMessageText": "Sind Sie sicher, dass Sie {count} ausgewählte Download-Clients löschen möchten?",
|
||||
"DeleteSelectedIndexers": "Lösche Indexer",
|
||||
"DeleteSelectedImportListsMessageText": "Indexer '{0}' wirklich löschen?",
|
||||
"DeleteSelectedImportListsMessageText": "Sind Sie sicher, dass Sie {count} ausgewählte Importliste(n) löschen möchten?",
|
||||
"EditSelectedImportLists": "Ausgewählte Einspiel-Liste bearbeten",
|
||||
"EditSelectedIndexers": "Ausgewähle Indexer bearbeiten",
|
||||
"ExistingTag": "Vorhandener Tag",
|
||||
@@ -967,14 +956,14 @@
|
||||
"No": "Nein",
|
||||
"NoChange": "Keine Änderung",
|
||||
"NoDownloadClientsFound": "Keine Download Clienten gefunden",
|
||||
"SetTags": "Tags setzen",
|
||||
"SetTags": "Tags festlegen",
|
||||
"Loading": "Lade",
|
||||
"ConnectionLostReconnect": "Radarr wird automatisch versuchen zu verbinden oder klicke unten auf neuladen.",
|
||||
"ConnectionLostToBackend": "Radarr hat die Verbindung zum Backend verloren und muss neugeladen werden.",
|
||||
"ConnectionLostReconnect": "{appName} wird versuchen, automatisch eine Verbindung herzustellen, oder Sie können unten auf „Neu laden“ klicken.",
|
||||
"ConnectionLostToBackend": "{appName} hat die Verbindung zum Backend verloren und muss neu geladen werden, um die Funktionalität wiederherzustellen.",
|
||||
"NotificationStatusAllClientHealthCheckMessage": "Wegen Fehlern sind keine Applikationen verfügbar",
|
||||
"NotificationStatusSingleClientHealthCheckMessage": "Applikationen wegen folgender Fehler nicht verfügbar: {0}",
|
||||
"TotalSpace": "Speicherkapazität",
|
||||
"Ui": "Oberfläche",
|
||||
"TotalSpace": "Gesamter Speicherplatz",
|
||||
"Ui": "Benutzeroberfläche",
|
||||
"FreeSpace": "Freier Speicher",
|
||||
"Large": "Groß",
|
||||
"LastExecution": "Letzte Ausführung",
|
||||
@@ -987,15 +976,19 @@
|
||||
"LastDuration": "Letzte Dauer",
|
||||
"RecentChanges": "Kürzliche Änderungen",
|
||||
"System": "System",
|
||||
"WhatsNew": "Was gibt's Neues?",
|
||||
"WhatsNew": "Was ist neu?",
|
||||
"NextExecution": "Nächste Ausführung",
|
||||
"NoResultsFound": "Keine Ergebnisse gefunden",
|
||||
"SomeResultsAreHiddenByTheAppliedFilter": "Einige Ergebnisse werden wegen der aktiven Filter nicht angezeigt",
|
||||
"SomeResultsAreHiddenByTheAppliedFilter": "Einige Ergebnisse werden durch den angewendeten Filter ausgeblendet",
|
||||
"Medium": "Medium",
|
||||
"Activity": "Aktivität",
|
||||
"AddNew": "Neue hinzufügen",
|
||||
"Backup": "Backups",
|
||||
"AllResultsAreHiddenByTheAppliedFilter": "Keine Ergebnisse mit den ausgewählten Filtern",
|
||||
"Backup": "Sicherung",
|
||||
"AllResultsAreHiddenByTheAppliedFilter": "Alle Ergebnisse werden durch den angewendeten Filter ausgeblendet",
|
||||
"AppUpdated": "{appName} aktualisiert",
|
||||
"AppUpdatedVersion": "{appName} wurde auf die Version `{version}` aktualisiert. Um die neusten Funktionen zu bekommen lade {appName} neu"
|
||||
"AppUpdatedVersion": "{appName} wurde auf die Version `{version}` aktualisiert. Um die neusten Funktionen zu bekommen lade {appName} neu",
|
||||
"Clone": "Klonen",
|
||||
"AutomaticUpdatesDisabledDocker": "Automatische Updates werden bei Verwendung des Docker-Update-Mechanismus nicht direkt unterstützt. Sie müssen das Container-Image außerhalb von {appName} aktualisieren oder ein Skript verwenden",
|
||||
"AutoAdd": "Automatisch hinzufügen",
|
||||
"WouldYouLikeToRestoreBackup": "Möchten Sie die Sicherung „{name}“ wiederherstellen?"
|
||||
}
|
||||
|
||||
@@ -124,8 +124,6 @@
|
||||
"ErrorLoadingContents": "Σφάλμα κατά τη φόρτωση περιεχομένων",
|
||||
"ErrorLoadingPreviews": "Σφάλμα κατά τη φόρτωση προεπισκοπήσεων",
|
||||
"Exception": "Εξαίρεση",
|
||||
"ExtraFileExtensionsHelpTexts1": "Λίστα πρόσθετων αρχείων που διαχωρίζονται με κόμμα για εισαγωγή (το .nfo θα εισαχθεί ως .nfo-orig)",
|
||||
"ExtraFileExtensionsHelpTexts2": "Παραδείγματα: «.sub, .nfo» ή «sub, nfo»",
|
||||
"FailedDownloadHandling": "Η Διαχείρηση Λήψης Απέτυχε",
|
||||
"FileDateHelpText": "Αλλαγή ημερομηνίας αρχείου κατά την εισαγωγή / επανασύνδεση",
|
||||
"FileManagement": "Διαχείρηση Αρχείων",
|
||||
|
||||
@@ -242,6 +242,7 @@
|
||||
"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",
|
||||
"DeleteSelectedBookFiles": "Delete Selected Book Files",
|
||||
"DeleteSelectedBookFilesMessageText": "Are you sure you want to delete the selected book files?",
|
||||
"DeleteSelectedDownloadClients": "Delete Download Client(s)",
|
||||
@@ -265,6 +266,8 @@
|
||||
"DownloadClientCheckDownloadingToRoot": "Download client {0} places downloads in the root folder {1}. You should not download to a root folder.",
|
||||
"DownloadClientCheckNoneAvailableMessage": "No download client is available",
|
||||
"DownloadClientCheckUnableToCommunicateMessage": "Unable to communicate with {0}.",
|
||||
"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+)",
|
||||
"DownloadClientRemovesCompletedDownloadsHealthCheckMessage": "Download client {0} is set to remove completed downloads. This can result in downloads being removed from your client before {1} can import them.",
|
||||
"DownloadClientSettings": "Download Client Settings",
|
||||
"DownloadClientStatusCheckAllClientMessage": "All download clients are unavailable due to failures",
|
||||
@@ -317,8 +320,8 @@
|
||||
"ExistingTag": "Existing tag",
|
||||
"ExistingTagsScrubbed": "Existing tags scrubbed",
|
||||
"ExportCustomFormat": "Export Custom Format",
|
||||
"ExtraFileExtensionsHelpTexts1": "Comma separated list of extra files to import (.nfo will be imported as .nfo-orig)",
|
||||
"ExtraFileExtensionsHelpTexts2": "Examples: \".sub, .nfo\" or \"sub,nfo\"",
|
||||
"ExtraFileExtensionsHelpText": "Comma separated list of extra files to import (.nfo will be imported as .nfo-orig)",
|
||||
"ExtraFileExtensionsHelpTextsExamples": "Examples: '.sub, .nfo' or 'sub,nfo'",
|
||||
"FailedDownloadHandling": "Failed Download Handling",
|
||||
"FailedToLoadQueue": "Failed to load Queue",
|
||||
"FileDateHelpText": "Change file date on import/rescan",
|
||||
@@ -431,6 +434,7 @@
|
||||
"InstanceName": "Instance Name",
|
||||
"InstanceNameHelpText": "Instance name in tab and for Syslog app name",
|
||||
"Interval": "Interval",
|
||||
"InvalidUILanguage": "Your UI is set to an invalid language, correct it and save your settings",
|
||||
"IsCalibreLibraryHelpText": "Use Calibre Content Server to manipulate library",
|
||||
"IsCutoffCutoff": "Cutoff",
|
||||
"IsCutoffUpgradeUntilThisQualityIsMetOrExceeded": "Upgrade until this quality is met or exceeded",
|
||||
@@ -866,6 +870,7 @@
|
||||
"SorryThatBookCannotBeFound": "Sorry, that book cannot be found.",
|
||||
"Source": "Source",
|
||||
"SourcePath": "Source Path",
|
||||
"SourceTitle": "Source Title",
|
||||
"SpecificBook": "Specific Book",
|
||||
"SslCertPasswordHelpText": "Password for pfx file",
|
||||
"SslCertPasswordHelpTextWarning": "Requires restart to take effect",
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
"CreateEmptyAuthorFoldersHelpText": "Crear carpetas de películas que faltan durante la exploración del disco",
|
||||
"CreateGroup": "Crear grupo",
|
||||
"CutoffHelpText": "Una vez que se alcanze esta calidad, Radarr no descargará películas",
|
||||
"CutoffUnmet": "Corte No Alcanzado",
|
||||
"CutoffUnmet": "Límite no alcanzado",
|
||||
"DBMigration": "Migración de DB",
|
||||
"Dates": "Fechas",
|
||||
"DelayProfile": "Perfil de Retraso",
|
||||
@@ -76,7 +76,7 @@
|
||||
"DeleteDelayProfile": "Borrar Perfil de Retraso",
|
||||
"DeleteDelayProfileMessageText": "Está seguro que quieres borrar este perfil de retraso?",
|
||||
"DeleteDownloadClient": "Borrar Gestor de Descargas",
|
||||
"DeleteDownloadClientMessageText": "¿Seguro que quieres eliminar el cliente de descargas '{name}'?",
|
||||
"DeleteDownloadClientMessageText": "Seguro que quieres eliminar el gestor de descargas '{name}'?",
|
||||
"DeleteEmptyFolders": "Borrar carpetas vacías",
|
||||
"DeleteEmptyFoldersHelpText": "Borrar carpetas vacías durante la exploración del disco y cuando se eliminen archivos",
|
||||
"DeleteImportListExclusion": "Borrar exclusión de lista de importación",
|
||||
@@ -86,7 +86,7 @@
|
||||
"DeleteIndexerMessageText": "Seguro que quieres eliminar el indexer '{name}'?",
|
||||
"DeleteMetadataProfileMessageText": "¿Seguro que quieres eliminar el perfil de metadatos '{name}'?",
|
||||
"DeleteNotification": "Borrar Notificación",
|
||||
"DeleteNotificationMessageText": "¿Seguro que quieres eliminiar la notificación '{name}'?",
|
||||
"DeleteNotificationMessageText": "¿Seguro que quieres eliminar la notificación '{name}'?",
|
||||
"DeleteQualityProfile": "Borrar Perfil de Calidad",
|
||||
"DeleteQualityProfileMessageText": "¿Seguro que quieres eliminar el perfil de calidad {name}?",
|
||||
"DeleteReleaseProfile": "Borrar Perfil de Retraso",
|
||||
@@ -124,8 +124,6 @@
|
||||
"ErrorLoadingContents": "Error al cargar los contenidos",
|
||||
"ErrorLoadingPreviews": "Error al cargar las previsualizaciones",
|
||||
"Exception": "Excepción",
|
||||
"ExtraFileExtensionsHelpTexts1": "Separar con cons la lista de los archivos extra a importar (.nfo será impotado como .nfo-orig)",
|
||||
"ExtraFileExtensionsHelpTexts2": "Ejemplos : '.sub, .nfo' o 'sub,nfo'",
|
||||
"FailedDownloadHandling": "Manipulación de Descargas Fallidas",
|
||||
"FileDateHelpText": "Cambiar la fecha del archivo al importar/rescan",
|
||||
"FileManagement": "Administración de Archivos",
|
||||
@@ -435,7 +433,7 @@
|
||||
"YesCancel": "Sí, Cancelar",
|
||||
"20MinutesTwenty": "20 Minutos: {0}",
|
||||
"DownloadClientCheckDownloadingToRoot": "El cliente de descargas {0} coloca las descargas en la carpeta raíz {1}. No debe descargar a una carpeta raíz.",
|
||||
"MaintenanceRelease": "Lanzamiento de mantenimiento",
|
||||
"MaintenanceRelease": "Lanzamiento de mantenimiento: Corrección de errores y otras mejoras. Ver historial de commits de Github para mas detalle",
|
||||
"ReplaceIllegalCharactersHelpText": "Reemplazar caracteres ilegales. Si está desactivado, Radarr los eliminará si no",
|
||||
"Actions": "Acciones",
|
||||
"Today": "Hoy",
|
||||
@@ -582,7 +580,7 @@
|
||||
"Test": "Test",
|
||||
"InstanceName": "Nombre de Instancia",
|
||||
"InstanceNameHelpText": "Nombre de instancia en pestaña y para nombre de aplicación en Syslog",
|
||||
"Database": "Base de Datos",
|
||||
"Database": "Base de datos",
|
||||
"ManualImportSelectEdition": "Importar Manualmente - Seleccionar Película",
|
||||
"ImportListExclusions": "Borrar exclusión de lista de importación",
|
||||
"ChooseImportMethod": "Elegir Modo de Importación",
|
||||
@@ -597,7 +595,7 @@
|
||||
"Conditions": "Condiciones",
|
||||
"CopyToClipboard": "Copiar al portapapeles",
|
||||
"CustomFormat": "Formatos Personalizados",
|
||||
"CustomFormats": "Formatos Personalizados",
|
||||
"CustomFormats": "Formatos personalizados",
|
||||
"DeleteCustomFormat": "Borrar Formato Personalizado",
|
||||
"DeleteFormatMessageText": "¿Está seguro de que desea eliminar la etiqueta de formato {0}?",
|
||||
"Formats": "Formatos",
|
||||
@@ -642,7 +640,7 @@
|
||||
"BlocklistReleaseHelpText": "Evita que Radarr vuelva a capturar esta película automáticamente",
|
||||
"NoEventsFound": "No se encontraron eventos",
|
||||
"ApplyTagsHelpTextHowToApplyAuthors": "Cómo añadir etiquetas a las películas seleccionadas",
|
||||
"DeleteSelectedIndexersMessageText": "Seguro que quieres eliminar {count} indexer seleccionado(s)?",
|
||||
"DeleteSelectedIndexersMessageText": "¿Está seguro de querer eliminar {count} indexador(es) seleccionado(s)?",
|
||||
"Yes": "Sí",
|
||||
"RedownloadFailed": "La descarga ha fallado",
|
||||
"RemoveCompleted": "Eliminación completada",
|
||||
@@ -655,7 +653,7 @@
|
||||
"ApplyTagsHelpTextRemove": "Eliminar: Eliminar las etiquetas introducidas",
|
||||
"ApplyTagsHelpTextReplace": "Reemplazar: Reemplazar las etiquetas con las etiquetas introducidas (no introducir etiquetas para eliminar todas las etiquetas)",
|
||||
"DeleteSelectedDownloadClients": "Borrar Gestor de Descargas",
|
||||
"DeleteSelectedDownloadClientsMessageText": "¿Estas seguro que quieres eliminar {count} cliente(s) de descarga seleccionado(s)?",
|
||||
"DeleteSelectedDownloadClientsMessageText": "¿Está seguro de querer eliminar {count} cliente(s) de descarga seleccionado(s)?",
|
||||
"DeleteSelectedImportListsMessageText": "Seguro que quieres eliminar {count} lista(s) de importación seleccionada(s)?",
|
||||
"DeleteSelectedIndexers": "Borrar Indexer",
|
||||
"DownloadClientTagHelpText": "Solo utilizar este indexador para películas que coincidan con al menos una etiqueta. Déjelo en blanco para utilizarlo con todas las películas.",
|
||||
@@ -762,5 +760,12 @@
|
||||
"CloneProfile": "Clonar Perfil",
|
||||
"Close": "Cerrar",
|
||||
"CloneIndexer": "Clonar Indexer",
|
||||
"CompletedDownloadHandling": "Manipulación de descargas completas"
|
||||
"CompletedDownloadHandling": "Manipulación de descargas completas",
|
||||
"EnableProfile": "Habilitar perfil",
|
||||
"ListsSettingsSummary": "lista de importación",
|
||||
"ExtraFileExtensionsHelpText": "Separar con cons la lista de los archivos extra a importar (.nfo será impotado como .nfo-orig)",
|
||||
"ExtraFileExtensionsHelpTextsExamples": "Ejemplos : '.sub, .nfo' o 'sub,nfo'",
|
||||
"ImportLists": "lista de importación",
|
||||
"DownloadClientRemovesCompletedDownloadsHealthCheckMessage": "El cliente de descarga {downloadClientName} esta configurado para eliminar las descargas completadas. Esto puede causar que las descargas sean eliminadas del cliente antes que {1} las pueda importar.",
|
||||
"Continuing": "Continua"
|
||||
}
|
||||
|
||||
@@ -123,8 +123,6 @@
|
||||
"ErrorLoadingContents": "Sisällönlatauksen virhe",
|
||||
"ErrorLoadingPreviews": "Virhe ladattaessa esikatselua",
|
||||
"Exception": "Poikkeus",
|
||||
"ExtraFileExtensionsHelpTexts1": "Pilkulla eroteltu lista tuotavista oheistiedostoista (.nfo tuodaan nimellä .nfo-orig).",
|
||||
"ExtraFileExtensionsHelpTexts2": "Esimerkkejä: '.sub, .nfo' tai 'sub, nfo'.",
|
||||
"FailedDownloadHandling": "Latauksen käsittely epäonnistui",
|
||||
"FileDateHelpText": "Muuta tiedoston päiväys tuonnin ja uudelleentarkistuksen yhteydessä.",
|
||||
"FileManagement": "Tiedostojen hallinta",
|
||||
@@ -883,5 +881,7 @@
|
||||
"AutomaticUpdatesDisabledDocker": "Suoraa automaattista päivitystä ei tueta käytettäessä Dockerin päivitysmekanismia. Joko Docker-säiliö on päivitettävä {appName}in ulkopuolella tai päivitys on suoritettava skriptillä.",
|
||||
"AppUpdated": "{appName} on päivitetty",
|
||||
"AppUpdatedVersion": "{appName} on päivitetty versioon {version} ja muutosten käyttöönottamiseksi se on ladattava uudelleen.",
|
||||
"Iso639-3": "ISO 639-3 -kielikoodit tai \"null\" (pilkuin eroteltuna)"
|
||||
"Iso639-3": "ISO 639-3 -kielikoodit tai \"null\" (pilkuin eroteltuna)",
|
||||
"ExtraFileExtensionsHelpText": "Pilkulla eroteltu lista tuotavista oheistiedostoista (.nfo tuodaan nimellä .nfo-orig).",
|
||||
"ExtraFileExtensionsHelpTextsExamples": "Esimerkkejä: '.sub, .nfo' tai 'sub, nfo'."
|
||||
}
|
||||
|
||||
@@ -132,8 +132,6 @@
|
||||
"ErrorLoadingContents": "Erreur lors du chargement du contenu",
|
||||
"ErrorLoadingPreviews": "Erreur lors du chargement des aperçus",
|
||||
"Exception": "Exception",
|
||||
"ExtraFileExtensionsHelpTexts1": "Liste séparée par des virgules des fichiers supplémentaires à importer (.nfo sera importé en tant que .nfo-orig)",
|
||||
"ExtraFileExtensionsHelpTexts2": "Exemples : '.sub, .nfo' ou 'sub,nfo'",
|
||||
"FailedDownloadHandling": "Gestion des échecs de téléchargement",
|
||||
"FileDateHelpText": "Changer la date du fichier lors de l'import/re-scan",
|
||||
"FileNames": "Noms de fichier",
|
||||
@@ -244,7 +242,7 @@
|
||||
"Port": "Port",
|
||||
"PortHelpTextWarning": "Nécessite un redémarrage pour prendre effet",
|
||||
"PortNumber": "Numéro de port",
|
||||
"PosterSize": "Poster taille",
|
||||
"PosterSize": "Taille des affiches",
|
||||
"PreviewRename": "Aperçu Renommer",
|
||||
"Profiles": "Profils",
|
||||
"Proper": "Approprié",
|
||||
@@ -265,7 +263,7 @@
|
||||
"RSSSyncInterval": "Intervalle de synchronisation RSS",
|
||||
"ReadTheWikiForMoreInformation": "Lisez le wiki pour plus d'informations",
|
||||
"ReadarrSupportsAnyIndexerThatUsesTheNewznabStandardAsWellAsOtherIndexersListedBelow": "Readarr prend en charge tout indexeur qui utilise le standard Newznab, ainsi que d'autres indexeurs répertoriés ci-dessous.",
|
||||
"ReadarrTags": "Readarr Tags",
|
||||
"ReadarrTags": "Étiquettes Readarr",
|
||||
"Real": "Réel",
|
||||
"Reason": "Raison",
|
||||
"RecycleBinCleanupDaysHelpText": "Définir sur 0 pour désactiver le nettoyage automatique",
|
||||
@@ -465,7 +463,7 @@
|
||||
"ReplaceIllegalCharactersHelpText": "Remplacer les caractères illégaux. Si non coché, Readarr les supprimera",
|
||||
"Level": "Niveau",
|
||||
"Publisher": "Éditeur",
|
||||
"Label": "Label",
|
||||
"Label": "Libellé",
|
||||
"RemoveFromBlocklist": "Supprimer de la liste noire",
|
||||
"UnableToLoadBlocklist": "Impossible de charger la liste noire",
|
||||
"Component": "Composant",
|
||||
@@ -605,7 +603,7 @@
|
||||
"AuthorIndex": "Index de l'auteur",
|
||||
"BookEditor": "Éditeur de livres",
|
||||
"BookIndex": "Index du livre",
|
||||
"DefaultReadarrTags": "Tags Readarr par défaut",
|
||||
"DefaultReadarrTags": "Étiquettes Readarr par défaut",
|
||||
"AddedAuthorSettings": "Ajout des paramètres de l'auteur",
|
||||
"AllBooks": "Tous les livres",
|
||||
"BookList": "Liste des livres",
|
||||
@@ -675,7 +673,7 @@
|
||||
"BypassIfAboveCustomFormatScore": "Contourner si au-dessus du score du format personnalisé",
|
||||
"BypassIfHighestQuality": "Contourner si la qualité est la plus élevée",
|
||||
"BypassIfAboveCustomFormatScoreHelpText": "Activez le contournement lorsque la version a un score supérieur au score minimum configuré pour le format personnalisé",
|
||||
"CustomFormatScore": "Partition au format personnalisé",
|
||||
"CustomFormatScore": "Score du format personnalisé",
|
||||
"MinimumCustomFormatScore": "Score minimum de format personnalisé",
|
||||
"Theme": "Thème",
|
||||
"ThemeHelpText": "Modifiez le thème de l'interface utilisateur de l'application, le thème « Auto » utilisera le thème de votre système d'exploitation pour définir le mode clair ou sombre. Inspiré par Theme.Park",
|
||||
@@ -713,7 +711,7 @@
|
||||
"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",
|
||||
"DeleteBookFile": "Effacer le fichier du livre",
|
||||
"HiddenClickToShow": "Masqué, cliquez pour afficher",
|
||||
"HideAdvanced": "Masquer param. av.",
|
||||
"HideAdvanced": "Masquer les Options Avancées",
|
||||
"ShowAdvanced": "Afficher les paramètres avancés",
|
||||
"ShownClickToHide": "Affiché, cliquez pour masquer",
|
||||
"ColonReplacement": "Remplacement pour le « deux-points »",
|
||||
@@ -760,7 +758,7 @@
|
||||
"ExistingTag": "Balise existante",
|
||||
"No": "Non",
|
||||
"RemovingTag": "Supprimer la balise",
|
||||
"SetTags": "Définir des balises",
|
||||
"SetTags": "Définir des étiquettes",
|
||||
"CountDownloadClientsSelected": "{selectedCount} client(s) de téléchargement sélectionné(s)",
|
||||
"EditSelectedDownloadClients": "Modifier les clients de téléchargement sélectionnés",
|
||||
"EditSelectedIndexers": "Modifier les indexeurs sélectionnés",
|
||||
@@ -789,7 +787,7 @@
|
||||
"TotalSpace": "Espace total",
|
||||
"Ui": "Interface utilisateur",
|
||||
"Activity": "Activité",
|
||||
"AddNew": "Ajouter une nouvelle",
|
||||
"AddNew": "Ajouter",
|
||||
"Backup": "Sauvegarde",
|
||||
"AutoAdd": "Ajout automatique",
|
||||
"AutomaticUpdatesDisabledDocker": "Les mises à jour automatiques ne sont pas directement prises en charge lors de l'utilisation du mécanisme de mise à jour de Docker. Vous devrez mettre à jour l'image du conteneur en dehors de {appName} ou utiliser un script",
|
||||
@@ -881,7 +879,7 @@
|
||||
"TrackTitle": "Titre de la piste",
|
||||
"UpdatingIsDisabledInsideADockerContainerUpdateTheContainerImageInstead": "La mise à jour est désactivée dans un conteneur Docker. Mettez plutôt à jour l’image du conteneur.",
|
||||
"WatchRootFoldersForFileChanges": "Surveillez les dossiers racine pour les modifications de fichiers",
|
||||
"WriteMetadataTags": "Écrire des balises de métadonnées",
|
||||
"WriteMetadataTags": "Écrire des étiquettes de métadonnées",
|
||||
"IndexerIdHelpText": "Spécifiez à quel indexeur le profil s'applique",
|
||||
"Monitoring": "Surveillance",
|
||||
"UnmappedFiles": "Fichiers non mappés",
|
||||
@@ -925,5 +923,8 @@
|
||||
"EnableProfile": "Activer profil",
|
||||
"Development": "Développement",
|
||||
"FilesTotal": "Fichiers ({0})",
|
||||
"SearchBoxPlaceHolder": "Par ex. Guerre et Paix, goodreads:656, isbn:067003469X, asin:B00JCDK5ME"
|
||||
"SearchBoxPlaceHolder": "Par ex. Guerre et Paix, goodreads:656, isbn:067003469X, asin:B00JCDK5ME",
|
||||
"ExtraFileExtensionsHelpText": "Liste de fichiers supplémentaires séparés par des virgules à importer (.nfo sera importé en tant que .nfo-orig)",
|
||||
"ExtraFileExtensionsHelpTextsExamples": "Exemples : '.sub, .nfo' ou 'sub,nfo'",
|
||||
"UseSSL": "Utiliser SSL"
|
||||
}
|
||||
|
||||
@@ -109,8 +109,6 @@
|
||||
"ErrorLoadingContents": "שגיאה בטעינת התוכן",
|
||||
"ErrorLoadingPreviews": "שגיאה בטעינת תצוגה מקדימה",
|
||||
"Exception": "יוצא מן הכלל",
|
||||
"ExtraFileExtensionsHelpTexts1": "רשימה מופרדת באמצעות פסיקים של קבצים נוספים לייבוא (.nfo יובא כ- nfo-orig)",
|
||||
"ExtraFileExtensionsHelpTexts2": "דוגמאות: '.sub, .nfo' או 'sub, nfo'",
|
||||
"FailedDownloadHandling": "הטיפול בהורדות נכשל",
|
||||
"FileDateHelpText": "שנה את תאריך הקובץ בעת הייבוא / סריקה מחדש",
|
||||
"FileManagement": "ניהול קבצים",
|
||||
@@ -657,5 +655,7 @@
|
||||
"System": "מערכת",
|
||||
"Theme": "ערכת נושא",
|
||||
"TotalSpace": "השטח הכולל",
|
||||
"Publisher": "מוציא לאור"
|
||||
"Publisher": "מוציא לאור",
|
||||
"ExtraFileExtensionsHelpText": "רשימה מופרדת באמצעות פסיקים של קבצים נוספים לייבוא (.nfo יובא כ- nfo-orig)",
|
||||
"ExtraFileExtensionsHelpTextsExamples": "דוגמאות: '.sub, .nfo' או 'sub, nfo'"
|
||||
}
|
||||
|
||||
@@ -114,8 +114,6 @@
|
||||
"ErrorLoadingContents": "सामग्री लोड करने में त्रुटि",
|
||||
"ErrorLoadingPreviews": "पूर्वावलोकन लोड करने में त्रुटि",
|
||||
"Exception": "अपवाद",
|
||||
"ExtraFileExtensionsHelpTexts1": "आयात करने के लिए कोमा ने अतिरिक्त फ़ाइलों की सूची अलग कर दी (.nfo को .nfo- मूल के रूप में आयात किया जाएगा)",
|
||||
"ExtraFileExtensionsHelpTexts2": "उदाहरण: '.sub, .nfo' या 'सब, nfo'",
|
||||
"FailedDownloadHandling": "डाउनलोड हैंडलिंग विफल",
|
||||
"FileDateHelpText": "आयात / रेस्क्यू पर फ़ाइल तिथि बदलें",
|
||||
"FileManagement": "फाइल प्रबंधन",
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
{
|
||||
"AlternateTitles": "Alternatív cím",
|
||||
"AlternateTitles": "Alternatív címek",
|
||||
"Analytics": "Analitika",
|
||||
"AnalyticsEnabledHelpText": "Küldjön névtelen használati és hibainformációkat a Readarr szervereire. Ez magában foglalja a böngészőjéről szóló információkat, mely Readarr WebUI oldalakat használja, a hibajelentést, valamint az operációs rendszer adatait. Ezeket az információkat a funkciók és a hibajavítások rangsorolására használjuk fel.",
|
||||
"AppDataDirectory": "AppData Mappa",
|
||||
"AppDataDirectory": "AppData Könyvtár",
|
||||
"ApplyTags": "Címkék alkalmazása",
|
||||
"Authentication": "Hitelesítés",
|
||||
"AuthenticationMethodHelpText": "Felhasználónév és Jelszó szükséges a Readarr-hoz való hozzáféréshez",
|
||||
"AuthorClickToChangeBook": "Kattints a film módosításához",
|
||||
"AutoRedownloadFailedHelpText": "Másik kiadás automatikus keresése és letöltése",
|
||||
"AutoRedownloadFailedHelpText": "Egy másik kiadás automatikus keresése és letöltése",
|
||||
"AutoUnmonitorPreviouslyDownloadedBooksHelpText": "A lemezről törölt filmeket a Radarr automatikusan eltávolítja a megfigyelt filmek közül",
|
||||
"Automatic": "Automatikus",
|
||||
"BackupFolderHelpText": "Az elérési útvonalak a Readarr AppData könyvtárában lesznek",
|
||||
"BackupNow": "Biztonsági Mentés Most",
|
||||
"BackupRetentionHelpText": "A megőrzési időnél régebbi automatikus biztonsági másolatok automatikusan törlésre kerülnek",
|
||||
"BackupNow": "Biztonsági Mentés",
|
||||
"BackupRetentionHelpText": "A megőrzési időszaknál régebbi automatikus biztonsági másolatok automatikusan törlődnek",
|
||||
"Backups": "Biztonsági mentések",
|
||||
"BindAddress": "Kapcsolási Cím",
|
||||
"BindAddressHelpText": "Érvényes IPv4-cím, vagy „*” minden interfészhez",
|
||||
@@ -27,7 +27,7 @@
|
||||
"CancelMessageText": "Biztosan törlöd ezt a függőben lévő feladatot?",
|
||||
"CertificateValidation": "Tanúsítvány érvényesítése",
|
||||
"CertificateValidationHelpText": "Módosítsa a HTTPS-tanúsítvány-ellenőrzés szigorúságát. Ne változtasson, hacsak nem érti a kockázatokat.",
|
||||
"ChangeFileDate": "Fájl Dátumának Módosítása",
|
||||
"ChangeFileDate": "Fájl dátumának módosítása",
|
||||
"ChangeHasNotBeenSavedYet": "A változások még nem lettek elmentve",
|
||||
"ChmodFolder": "chmod Mappa",
|
||||
"ChmodFolderHelpText": "Octal, importáláskor / átnevezéskor alkalmazva a média mappákra és fájlokra (bitek végrehajtása nélkül)",
|
||||
@@ -35,7 +35,7 @@
|
||||
"ChownGroupHelpText": "Csoport neve vagy gid. A gid használata távoli fájlrendszerekhez.",
|
||||
"ChownGroupHelpTextWarning": "Ez csak akkor működik, ha a Radarrt futtató felhasználó a fájl tulajdonosa. Jobb, ha a letöltési kliens ugyanazt a csoportot használja, mint a Radarr.",
|
||||
"Clear": "Törölni",
|
||||
"ClickToChangeQuality": "Kattints a minőség módosításához",
|
||||
"ClickToChangeQuality": "Kattintson a minőség módosításához",
|
||||
"ClientPriority": "Kliens Prioritás",
|
||||
"CloneIndexer": "Indexer Klónozása",
|
||||
"CloneProfile": "Profil Klónozása",
|
||||
@@ -56,11 +56,11 @@
|
||||
"DelayProfiles": "Késleltetési Profilok",
|
||||
"DelayingDownloadUntilInterp": "Késleltetni a letöltést {0} -tól {1} -ig",
|
||||
"Delete": "Törlés",
|
||||
"DeleteBackup": "Biztonsági Mentés Törlése",
|
||||
"DeleteBackupMessageText": "Biztosan törlöd a(z) „{0}” biztonsági mentést?",
|
||||
"DeleteDelayProfile": "Késleltetési Profil Törlése",
|
||||
"DeleteBackup": "Biztonsági Mentés törlése",
|
||||
"DeleteBackupMessageText": "Biztosan törli a '{name}' biztonsági mentést?",
|
||||
"DeleteDelayProfile": "Késleltetési Profil törlése",
|
||||
"DeleteDelayProfileMessageText": "Biztos hogy törölni szeretnéd ezt a késleltetési profilt?",
|
||||
"DeleteDownloadClient": "Letöltőkliens Törlése",
|
||||
"DeleteDownloadClient": "Letöltőkliens törlése",
|
||||
"DeleteDownloadClientMessageText": "Biztosan törlöd a(z) „{0}” letöltő klienst?",
|
||||
"DeleteEmptyFolders": "Üres Mappa Törlése",
|
||||
"DeleteEmptyFoldersHelpText": "Törölje az üres könyvmappákat a lemezfrissítés és a könyvfájlokfájlok törlése során",
|
||||
@@ -92,7 +92,7 @@
|
||||
"DownloadFailedInterp": "Letöltés sikertelen: {0}",
|
||||
"DownloadPropersAndRepacksHelpTexts1": "Függetlenül attól, hogy automatikusan frissíteni kell-e Propers/Repacks verzióra",
|
||||
"DownloadWarningCheckDownloadClientForMoreDetails": "Letöltési figyelmeztetés: Nézd meg a letöltőkliensed további információért",
|
||||
"Edit": "Szerkesztés",
|
||||
"Edit": "szerkeszt",
|
||||
"Edition": "Kiadás",
|
||||
"Enable": "Aktiválás",
|
||||
"EnableAutomaticAdd": "Engedélyezd az automatikus hozzáadást",
|
||||
@@ -109,16 +109,14 @@
|
||||
"ErrorLoadingContents": "Hiba történt a tartalom betöltésekor",
|
||||
"ErrorLoadingPreviews": "Hiba történt az előnézetek betöltése közben",
|
||||
"Exception": "Kivétel",
|
||||
"ExtraFileExtensionsHelpTexts1": "Az importálandó extra fájlok vesszővel lesznek elválasztva (.nfo .nfo-orig néven lesz importálva)",
|
||||
"ExtraFileExtensionsHelpTexts2": "Például: '.sub, .nfo' vagy 'sub, nfo'",
|
||||
"FailedDownloadHandling": "Nem sikerült a letöltés kezelése",
|
||||
"FileDateHelpText": "A fájl dátumának módosítása az importáláskor / újrakereséskor",
|
||||
"FileManagement": "Fájlkezelő",
|
||||
"FileNames": "Fájlnevek",
|
||||
"Filename": "Fájlnév",
|
||||
"Filename": "Fájl név",
|
||||
"Files": "Fájl",
|
||||
"FirstDayOfWeek": "A Hét Első Napja",
|
||||
"Fixed": "Kijavítva",
|
||||
"Fixed": "Rögzített",
|
||||
"Folder": "Mappa",
|
||||
"Folders": "Mappák",
|
||||
"ForMoreInformationOnTheIndividualDownloadClientsClickOnTheInfoButtons": "Ha többet szeretnél megtudni a különböző letöltési kliensekről, kattints az információs gombokra.",
|
||||
@@ -135,7 +133,7 @@
|
||||
"Group": "Csoport",
|
||||
"HasPendingChangesNoChanges": "Nincsenek változások",
|
||||
"HasPendingChangesSaveChanges": "Változtatások mentése",
|
||||
"History": "Történet",
|
||||
"History": "Előzmény",
|
||||
"Host": "Hoszt",
|
||||
"Hostname": "Hosztnév",
|
||||
"ICalFeed": "iCal-Feed",
|
||||
@@ -143,7 +141,7 @@
|
||||
"ICalLink": "iCal Link(ek)",
|
||||
"IconForCutoffUnmet": "Ikon a Sikertelen Küszöbszint Elérésére",
|
||||
"IconTooltip": "Ütemezve",
|
||||
"IgnoredAddresses": "Ignorált Címek",
|
||||
"IgnoredAddresses": "Ignorált címek",
|
||||
"IgnoredHelpText": "A kiadás elutasításra kerül, ha egy vagy több kifejezést tartalmaz (A kis- és nagybetűket nem vesszük figyelembe)",
|
||||
"IgnoredPlaceHolder": "Új korlátozás hozzáadása",
|
||||
"IllRestartLater": "Később Újraindítom",
|
||||
@@ -171,7 +169,7 @@
|
||||
"LogLevel": "Log Szint",
|
||||
"LogLevelvalueTraceTraceLoggingShouldOnlyBeEnabledTemporarily": "A nyomkövetést csak ideiglenesen szabad engedélyezni",
|
||||
"Logging": "Loggolás",
|
||||
"Logs": "Logok",
|
||||
"Logs": "Naplók",
|
||||
"LongDateFormat": "Hosszú dátumformátum",
|
||||
"MIA": "MIA",
|
||||
"ManualImport": "Manuális Importálás",
|
||||
@@ -212,7 +210,7 @@
|
||||
"OnRenameHelpText": "Átnevezés alatt",
|
||||
"OnUpgradeHelpText": "Minőségjavítás alatt",
|
||||
"OpenBrowserOnStart": "Indításkor nyissa meg a böngészőt",
|
||||
"Options": "Opciók",
|
||||
"Options": "Lehetőségek",
|
||||
"Original": "Eredeti",
|
||||
"Overview": "Áttekintés",
|
||||
"PackageVersion": "Csomagverzió",
|
||||
@@ -226,8 +224,8 @@
|
||||
"PortNumber": "Port száma",
|
||||
"PosterSize": "Poszter mérete",
|
||||
"PreviewRename": "Előnézet átnevezése",
|
||||
"Profiles": "Profil(ok)",
|
||||
"Proper": "Proper",
|
||||
"Profiles": "Profilok",
|
||||
"Proper": "Megfelelő",
|
||||
"PropersAndRepacks": "Properek és Repackok",
|
||||
"Protocol": "Protokoll",
|
||||
"ProtocolHelpText": "Válasszd ki a használni kívánt protokoll(oka)t és melyiket részesíted előnyben, ha az egyébként egyforma kiadások közül választasz",
|
||||
@@ -236,7 +234,7 @@
|
||||
"ProxyType": "Proxy Típusa",
|
||||
"ProxyUsernameHelpText": "Csak akkor kell megadnod felhasználónevet és jelszót, ha szükséges. Egyébként hagyd üresen.",
|
||||
"PublishedDate": "Közzététel dátuma",
|
||||
"Quality": "Minőség",
|
||||
"Quality": "minőség",
|
||||
"QualityDefinitions": "Minőségi meghatározások",
|
||||
"QualityProfile": "Minőségi profil",
|
||||
"QualityProfiles": "Minőségi profilok",
|
||||
@@ -247,7 +245,7 @@
|
||||
"ReadTheWikiForMoreInformation": "Olvasd el a Wiki-t további információkért",
|
||||
"ReadarrSupportsAnyIndexerThatUsesTheNewznabStandardAsWellAsOtherIndexersListedBelow": "A Radarr minden indexert támogat, amely a Newznab szabványt használja, valamint az alább felsorolt egyéb indexereket.",
|
||||
"ReadarrTags": "Radarr Címkék",
|
||||
"Real": "Valódi",
|
||||
"Real": "Igazi",
|
||||
"Reason": "Ok",
|
||||
"RecycleBinCleanupDaysHelpText": "Állítsd 0-ra az automatikus tisztítás letiltásához",
|
||||
"RecycleBinCleanupDaysHelpTextWarning": "A kiválasztott napoknál régebbi fájlok a lomtárban automatikusan törlésre kerülnek",
|
||||
@@ -289,7 +287,7 @@
|
||||
"RestartReadarr": "Radarr Újraindítása",
|
||||
"Restore": "Visszaállítás",
|
||||
"RestoreBackup": "Biztonsági mentés visszaállítása",
|
||||
"Result": "Eredmények",
|
||||
"Result": "Eredmény",
|
||||
"Retention": "Visszatartás",
|
||||
"RetentionHelpText": "Usenet: Állítsa nullára a korlátlan megőrzés beállításához",
|
||||
"RetryingDownloadInterp": "A letöltés újrapróbálása {0} itt {1}",
|
||||
@@ -347,19 +345,19 @@
|
||||
"SupportsSearchvalueSearchIsNotSupportedWithThisIndexer": "A keresés nem támogatott ezzel az Indexerrel",
|
||||
"SupportsSearchvalueWillBeUsedWhenAutomaticSearchesArePerformedViaTheUIOrByReadarr": "Akkor kerül felhasználásra, ha az automatikus kereséseket a kezelőfelületen vagy a Radarr-on keresztül hajtják végre",
|
||||
"SupportsSearchvalueWillBeUsedWhenInteractiveSearchIsUsed": "Interaktív keresés esetén is felhasználható",
|
||||
"TagIsNotUsedAndCanBeDeleted": "A címkét nincs használatban, és törölhető",
|
||||
"TagIsNotUsedAndCanBeDeleted": "A címke nincs használatban, törölhető",
|
||||
"Tasks": "Feladatok",
|
||||
"TestAll": "Összes tesztelése",
|
||||
"TestAll": "Összes Tesztelése",
|
||||
"TestAllClients": "Összes kliens tesztelése",
|
||||
"TestAllIndexers": "Indexerek tesztelése",
|
||||
"TestAllLists": "Összes lista tesztelése",
|
||||
"ThisWillApplyToAllIndexersPleaseFollowTheRulesSetForthByThem": "Ez minden indexerre vonatkozni fog, kérjük, tartsa be az általuk meghatározott szabályokat",
|
||||
"TimeFormat": "Időformátum",
|
||||
"TimeFormat": "Idő formátum",
|
||||
"Title": "Cím",
|
||||
"TorrentDelay": "Torrent késleltetés",
|
||||
"TorrentDelayHelpText": "Eltolás percekben, mielőtt a torrentkliens elkezdi a letöltést",
|
||||
"Torrents": "Torrentek",
|
||||
"TotalFileSize": "Teljes fájl méret",
|
||||
"TotalFileSize": "Összesített fájlméret",
|
||||
"UILanguage": "Felület nyelve",
|
||||
"UILanguageHelpText": "A Radarr által a felhasználói felülethez használt nyelv",
|
||||
"UILanguageHelpTextWarning": "Böngésző újratöltése szükséges",
|
||||
@@ -397,10 +395,10 @@
|
||||
"60MinutesSixty": "60 Perc: {0}",
|
||||
"APIKey": "API Kulcs",
|
||||
"About": "Névjegy",
|
||||
"AddListExclusion": "Kizárási Lista Hozzáadása",
|
||||
"AddListExclusion": "Listakizárás hozzáadása",
|
||||
"AddingTag": "Címke hozzáadása",
|
||||
"AgeWhenGrabbed": "Kora (mikor hozzáadásra került)",
|
||||
"AlreadyInYourLibrary": "Már hozzáadtad",
|
||||
"AgeWhenGrabbed": "Életkor (amikor megragadták)",
|
||||
"AlreadyInYourLibrary": "Már a könyvtárban",
|
||||
"UnableToLoadRemotePathMappings": "Nem lehet betölteni a Távoli útvonal-hozzárendeléseket",
|
||||
"None": "Nincs",
|
||||
"UnableToLoadRootFolders": "Nem lehet betölteni a gyökérmappákat",
|
||||
@@ -686,7 +684,7 @@
|
||||
"ExistingItems": "Meglévő elemek",
|
||||
"SeriesTotal": "Sorozat ({0})",
|
||||
"TooManyBooks": "Hiányzik valamelyik, vagy túl sok a könyv? Módosíts vagy hozzon létre újat",
|
||||
"BlocklistRelease": "Feketelistás Kiadás",
|
||||
"BlocklistRelease": "Blokklista Release",
|
||||
"NoHistoryBlocklist": "Nincs blokkolási előzménylista",
|
||||
"Blocklist": "Feketelista",
|
||||
"RemoveFromBlocklist": "Eltávolítás a feketelistáról",
|
||||
@@ -723,7 +721,7 @@
|
||||
"UseCalibreContentServer": "Használja a Calibre Tartalomkiszolgálót",
|
||||
"All": "Összes",
|
||||
"Wanted": "Keresett",
|
||||
"Disabled": "Letiltott",
|
||||
"Disabled": "Tiltva",
|
||||
"OnAuthorDelete": "A Szerző törlésekor",
|
||||
"OnAuthorDeleteHelpText": "A Szerző törlésekor",
|
||||
"OnBookDelete": "A könyv törlésekor",
|
||||
@@ -784,7 +782,7 @@
|
||||
"IndexerRssHealthCheckNoIndexers": "Nincs elérhető indexer RSS szinkronizálással, így a Readarr nem fogja automatikusan megragadni az új kiadásokat",
|
||||
"IndexerSearchCheckNoAvailableIndexersMessage": "Az összes keresésre képes indexer átmenetileg nem elérhető, a legutóbbi indexelő hibák miatt",
|
||||
"Lists": "Listák",
|
||||
"Metadata": "Metaadat(ok)",
|
||||
"Metadata": "metaadat",
|
||||
"Monitor": "Monitorozni",
|
||||
"MountCheckMessage": "A szerzőt tartalmazó mappa csak olvasható: ",
|
||||
"Queued": "Sorba helyezve",
|
||||
@@ -860,7 +858,7 @@
|
||||
"ApplicationURL": "Alkalmazás URL",
|
||||
"ApplicationUrlHelpText": "Az alkalmazás külső URL-címe, beleértve a http(s)://-t, a portot és az URL-alapot",
|
||||
"ChooseImportMethod": "Importálási mód kiválasztása",
|
||||
"ClickToChangeReleaseGroup": "Kiadási csoport módosítása",
|
||||
"ClickToChangeReleaseGroup": "Kattintson a kiadási csoport módosításához",
|
||||
"HardlinkCopyFiles": "Hardlinkelés/Fájl(ok) Másolása",
|
||||
"MoveFiles": "Fájl(ok) mozgatása",
|
||||
"OnApplicationUpdate": "Alkalmazásfrissítésről",
|
||||
@@ -924,16 +922,16 @@
|
||||
"RemoveFailedDownloads": "Sikertelen letöltések eltávolítása",
|
||||
"SetTags": "Címkék beállítása",
|
||||
"Yes": "Igen",
|
||||
"BlocklistReleases": "Feketelistás Kiadás",
|
||||
"BlocklistReleases": "Feketelista kiadása",
|
||||
"RecycleBinUnableToWriteHealthCheck": "Nem lehet írni a konfigurált lomtár mappába {0}. Győződjön meg arról, hogy ez az elérési útvonal létezik, és az a felhasználó, aki a Sonarr-t futtatja, írási jogosultsággal rendelkezik",
|
||||
"RedownloadFailed": "Letöltés Sikertelen",
|
||||
"RemoveCompleted": "Eltávolítás Kész",
|
||||
"RemoveDownloadsAlert": "Az eltávolításhoz szükséges beállítások átkerültek a fenti táblázatban található egyéni letöltő beállítások közé.",
|
||||
"ApplyTagsHelpTextHowToApplyDownloadClients": "Hogyan adjunk hozzá címkéket a kiválasztott filmhez",
|
||||
"ApplyTagsHelpTextHowToApplyDownloadClients": "Címkék alkalmazása a kiválasztott letöltési kliensekre",
|
||||
"ApplyChanges": "Változások alkalmazása",
|
||||
"ApplyTagsHelpTextAdd": "Hozzáadás: Új címkék hozzáadása a meglévő címkékhez",
|
||||
"ApplyTagsHelpTextHowToApplyImportLists": "Hogyan adjunk hozzá címkéket a kiválasztott filmhez",
|
||||
"ApplyTagsHelpTextHowToApplyIndexers": "Hogyan adjunk hozzá címkéket a kiválasztott filmhez",
|
||||
"ApplyTagsHelpTextAdd": "Hozzáadás: Adja hozzá a címkéket a meglévő címkék listájához",
|
||||
"ApplyTagsHelpTextHowToApplyImportLists": "Címkék alkalmazása a kiválasztott importlistákra",
|
||||
"ApplyTagsHelpTextHowToApplyIndexers": "Címkék alkalmazása a kiválasztott indexelőkre",
|
||||
"ApplyTagsHelpTextRemove": "Eltávolítás: Távolítsa el a beírt címkéket",
|
||||
"CountIndexersSelected": "{0} Indexelő(k) kiválasztva",
|
||||
"DeleteConditionMessageText": "Biztosan törölni akarod a '{0}' feltételt?",
|
||||
@@ -959,7 +957,7 @@
|
||||
"NoResultsFound": "Nem eredményezett találatot",
|
||||
"SomeResultsAreHiddenByTheAppliedFilter": "Néhány találat nem látható az alkalmazott szűrők miatt",
|
||||
"System": "Rendszer",
|
||||
"TotalSpace": "Összes szabad hely",
|
||||
"TotalSpace": "Összesített terület",
|
||||
"Ui": "Felület",
|
||||
"ConnectionLost": "Kapcsolódás Elveszett",
|
||||
"ConnectionLostReconnect": "A Radarr megpróbál automatikusan csatlakozni, vagy kattints a frissítés gombra.",
|
||||
@@ -971,11 +969,16 @@
|
||||
"LastExecution": "Utolsó végrehajtás",
|
||||
"LastWriteTime": "Utolsó írási idő",
|
||||
"Library": "Könyvtár",
|
||||
"Location": "Lokáció",
|
||||
"AllResultsAreHiddenByTheAppliedFilter": "Az alkalmazott szűrők miatt, az összes keresési eredmény rejtve marad",
|
||||
"Location": "Elhelyezkedés",
|
||||
"AllResultsAreHiddenByTheAppliedFilter": "Az összes eredményt elrejti az alkalmazott szűrő",
|
||||
"Activity": "Aktivitás",
|
||||
"AddNew": "Új hozzáadása",
|
||||
"Backup": "Biztonsági Mentés",
|
||||
"Backup": "biztonsági mentés",
|
||||
"Medium": "Közepes",
|
||||
"AutoAdd": "Automatikus hozzáadás"
|
||||
"AutoAdd": "Automatikus hozzáadás",
|
||||
"ExtraFileExtensionsHelpText": "Az importálandó extra fájlok vesszővel lesznek elválasztva (.nfo .nfo-orig néven lesz importálva)",
|
||||
"ExtraFileExtensionsHelpTextsExamples": "Például: '.sub, .nfo' vagy 'sub, nfo'",
|
||||
"Implementation": "Végrehajtás",
|
||||
"Clone": "Klón",
|
||||
"AppUpdated": "{appName} frissítve"
|
||||
}
|
||||
|
||||
@@ -129,8 +129,6 @@
|
||||
"ErrorLoadingContents": "Villa við að hlaða innihald",
|
||||
"ErrorLoadingPreviews": "Villa við að hlaða forskoðun",
|
||||
"Exception": "Undantekning",
|
||||
"ExtraFileExtensionsHelpTexts1": "Komma aðskilinn listi yfir auka skrár til að flytja inn (.nfo verður fluttur inn sem .nfo-orig)",
|
||||
"ExtraFileExtensionsHelpTexts2": "Dæmi: '.sub, .nfo' eða 'sub, nfo'",
|
||||
"FailedDownloadHandling": "Mistókst niðurhalshöndlun",
|
||||
"FileDateHelpText": "Breyttu dagsetningu skráar við innflutning / endurskoðun",
|
||||
"FileManagement": "Skráastjórnun",
|
||||
|
||||
@@ -134,8 +134,6 @@
|
||||
"ErrorLoadingContents": "Errore nel caricare i contenuti",
|
||||
"ErrorLoadingPreviews": "Errore nel caricare le anteprime",
|
||||
"Exception": "Eccezione",
|
||||
"ExtraFileExtensionsHelpTexts1": "Liste di file Extra da importare separate da virgola (.nfo saranno importate come .nfo-orig)",
|
||||
"ExtraFileExtensionsHelpTexts2": "Esempi: '.sub, .nfo' or 'sub,nfo'",
|
||||
"FailedDownloadHandling": "Gestione dei Download Falliti",
|
||||
"FileDateHelpText": "Modifica la data dei file in importazione/rescan",
|
||||
"FileManagement": "Gestione dei File",
|
||||
@@ -724,5 +722,6 @@
|
||||
"ApiKeyValidationHealthCheckMessage": "Aggiorna la tua chiave API in modo che abbia una lunghezza di almeno {0} caratteri. Puoi farlo dalle impostazioni o dal file di configurazione",
|
||||
"AddNew": "Aggiungi Nuovo",
|
||||
"AutomaticAdd": "Aggiungi Automaticamente",
|
||||
"Backup": "Backup"
|
||||
"Backup": "Backup",
|
||||
"CloneCondition": "Duplica Condizione"
|
||||
}
|
||||
|
||||
@@ -71,8 +71,6 @@
|
||||
"ErrorLoadingContents": "コンテンツの読み込み中にエラーが発生しました",
|
||||
"ErrorLoadingPreviews": "プレビューの読み込みエラー",
|
||||
"Exception": "例外",
|
||||
"ExtraFileExtensionsHelpTexts1": "インポートする追加ファイルのコンマ区切りリスト(.nfoは.nfo-origとしてインポートされます)",
|
||||
"ExtraFileExtensionsHelpTexts2": "例: '。sub、.nfo'または 'sub、nfo'",
|
||||
"FailedDownloadHandling": "ダウンロード処理の失敗",
|
||||
"FileDateHelpText": "インポート/再スキャン時にファイルの日付を変更する",
|
||||
"FileManagement": "ファイル管理",
|
||||
@@ -626,5 +624,7 @@
|
||||
"Medium": "中",
|
||||
"NoResultsFound": "結果が見つかりません",
|
||||
"Activity": "アクティビティ",
|
||||
"AddNew": "新しく追加する"
|
||||
"AddNew": "新しく追加する",
|
||||
"ExtraFileExtensionsHelpText": "インポートする追加ファイルのコンマ区切りリスト(.nfoは.nfo-origとしてインポートされます)",
|
||||
"ExtraFileExtensionsHelpTextsExamples": "例: '。sub、.nfo'または 'sub、nfo'"
|
||||
}
|
||||
|
||||
@@ -155,8 +155,6 @@
|
||||
"ErrorLoadingContents": "콘텐츠로드 오류",
|
||||
"ErrorLoadingPreviews": "미리보기를로드하는 중에 오류가 발생했습니다.",
|
||||
"Exception": "예외",
|
||||
"ExtraFileExtensionsHelpTexts1": "가져올 추가 파일의 쉼표로 구분 된 목록 (.nfo는 .nfo-orig로 가져옴)",
|
||||
"ExtraFileExtensionsHelpTexts2": "예 : '.sub, .nfo'또는 'sub, nfo'",
|
||||
"FailedDownloadHandling": "실패한 다운로드 처리",
|
||||
"FileDateHelpText": "가져 오기 / 재검색시 파일 날짜 변경",
|
||||
"FileManagement": "파일 관리",
|
||||
@@ -617,5 +615,7 @@
|
||||
"LastExecution": "마지막 실행",
|
||||
"Activity": "활동",
|
||||
"AddNew": "새로 추가하기",
|
||||
"Backup": "백업"
|
||||
"Backup": "백업",
|
||||
"ExtraFileExtensionsHelpText": "가져올 추가 파일의 쉼표로 구분 된 목록 (.nfo는 .nfo-orig로 가져옴)",
|
||||
"ExtraFileExtensionsHelpTextsExamples": "예 : '.sub, .nfo'또는 'sub, nfo'"
|
||||
}
|
||||
|
||||
@@ -1 +1,7 @@
|
||||
{}
|
||||
{
|
||||
"Actions": "Darbības",
|
||||
"About": "Par",
|
||||
"Activity": "Aktivitāte",
|
||||
"New": "Jauns",
|
||||
"ExportCustomFormat": "Pievienot Pielāgotu Formātu"
|
||||
}
|
||||
|
||||
@@ -18,8 +18,8 @@
|
||||
"About": "Over",
|
||||
"AddListExclusion": "Lijst uitzondering toevoegen",
|
||||
"AddingTag": "Tag wordt toegevoegd",
|
||||
"AgeWhenGrabbed": "Leeftijd (op moment van ophalen)",
|
||||
"AlreadyInYourLibrary": "Reeds in uw bibliotheek",
|
||||
"AgeWhenGrabbed": "Leeftijd (wanneer opgepakt)",
|
||||
"AlreadyInYourLibrary": "Reeds in je bibliotheek",
|
||||
"AlternateTitles": "Alternatieve Titel",
|
||||
"Analytics": "Statistieken",
|
||||
"AnalyticsEnabledHelpText": "Stuur anonieme gebruiks- en foutinformatie naar de servers van Radarr. Dit omvat informatie over uw browser, welke Radarr WebUI pagina's u gebruikt, foutrapportage en OS en runtime versie. We zullen deze informatie gebruiken om prioriteiten te stellen voor functies en het verhelpen van fouten.",
|
||||
@@ -78,18 +78,18 @@
|
||||
"DelayingDownloadUntilInterp": "Vertraag download tot {0} op {1}",
|
||||
"Delete": "Verwijder",
|
||||
"DeleteBackup": "Verwijder Backup",
|
||||
"DeleteBackupMessageText": "Bent u zeker dat u de veiligheidskopie '{0}' wilt verwijderen?",
|
||||
"DeleteBackupMessageText": "Bent u zeker dat u de veiligheidskopie '{name}' wilt verwijderen?",
|
||||
"DeleteDelayProfile": "Verwijder Vertragingsprofiel",
|
||||
"DeleteDelayProfileMessageText": "Weet u zeker dat u dit vertragingsprofiel wilt verwijderen?",
|
||||
"DeleteDownloadClient": "Verwijder Downloader",
|
||||
"DeleteDownloadClientMessageText": "Bent u zeker dat u de downloader '{0}' wilt verwijderen?",
|
||||
"DeleteDownloadClientMessageText": "Bent u zeker dat u de downloader '{name}' wilt verwijderen?",
|
||||
"DeleteEmptyFolders": "Verwijder lege mappen",
|
||||
"DeleteEmptyFoldersHelpText": "Lege mappen verwijderen, tijdens de schijfscan en wanneer filmbestanden worden verwijderd",
|
||||
"DeleteImportListExclusion": "Verwijder van Uitzonderingenlijst",
|
||||
"DeleteImportListExclusionMessageText": "Bent u zeker dat u dit van de uitzonderingenlijst wilt verwijderen?",
|
||||
"DeleteImportListMessageText": "Bent u zeker dat u de lijst '{0}' wilt verwijderen?",
|
||||
"DeleteIndexer": "Verwijder Indexeerder",
|
||||
"DeleteIndexerMessageText": "Bent u zeker dat u de indexeerder '{0}' wilt verwijderen?",
|
||||
"DeleteIndexerMessageText": "Bent u zeker dat u de indexeerder '{name}' wilt verwijderen?",
|
||||
"DeleteMetadataProfileMessageText": "Bent u zeker dat u het kwaliteitsprofiel {name} wilt verwijderen?",
|
||||
"DeleteNotification": "Verwijder Notificatie",
|
||||
"DeleteNotificationMessageText": "Bent u zeker dat u de notificatie '{0}' wilt verwijderen?",
|
||||
@@ -130,8 +130,6 @@
|
||||
"ErrorLoadingContents": "Fout bij laden van inhoud",
|
||||
"ErrorLoadingPreviews": "Fout bij laden van voorvertoningen",
|
||||
"Exception": "Uitzondering",
|
||||
"ExtraFileExtensionsHelpTexts1": "Komma gescheiden lijst met extra bestanden om te importeren (.nfo zal als .nfo-orig worden geïmporteerd)",
|
||||
"ExtraFileExtensionsHelpTexts2": "Voorbeelden: '.sub, .nfo' of 'sub,nfo'",
|
||||
"FailedDownloadHandling": "Mislukte Download Afhandeling",
|
||||
"FileDateHelpText": "Pas bestandsdatum aan tijdens het importeren/herscannen",
|
||||
"FileManagement": "Bestandsbeheer",
|
||||
@@ -650,5 +648,6 @@
|
||||
"Activity": "Activiteit",
|
||||
"AddNew": "Voeg Nieuwe Toe",
|
||||
"AppUpdated": "{appName} is geüpdatet",
|
||||
"AppUpdatedVersion": "{appName} is geüpdatet naar versie '{version}', om de laatste wijzigingen door te voeren moet je mogelijk {appName} herstarten"
|
||||
"AppUpdatedVersion": "{appName} is geüpdatet naar versie '{version}', om de laatste wijzigingen door te voeren moet je mogelijk {appName} herstarten",
|
||||
"AllResultsAreHiddenByTheAppliedFilter": "Alle resultaten zijn verborgen door het toegepaste filter"
|
||||
}
|
||||
|
||||
@@ -95,7 +95,7 @@
|
||||
"ClickToChangeQuality": "Kliknij, aby zmienić jakość",
|
||||
"ClientPriority": "Priorytet klienta",
|
||||
"CloneProfile": "Klonuj profil",
|
||||
"Close": "Blisko",
|
||||
"Close": "Zamknij",
|
||||
"Columns": "Kolumny",
|
||||
"CompletedDownloadHandling": "Ukończono obsługę pobierania",
|
||||
"ConnectSettings": "Ustawienia połączenia",
|
||||
@@ -149,8 +149,6 @@
|
||||
"ErrorLoadingContents": "Błąd podczas ładowania treści",
|
||||
"ErrorLoadingPreviews": "Błąd podczas ładowania podglądów",
|
||||
"Exception": "Wyjątek",
|
||||
"ExtraFileExtensionsHelpTexts1": "Rozdzielana przecinkami lista dodatkowych plików do zaimportowania (.nfo zostanie zaimportowane jako .nfo-orig)",
|
||||
"ExtraFileExtensionsHelpTexts2": "Przykłady: „.sub, .nfo” lub „sub, nfo”",
|
||||
"FailedDownloadHandling": "Nieudana obsługa pobierania",
|
||||
"FileDateHelpText": "Zmień datę pliku przy imporcie / ponownym skanowaniu",
|
||||
"FileManagement": "Zarządzanie plikami",
|
||||
@@ -676,5 +674,7 @@
|
||||
"Activity": "Aktywność",
|
||||
"AddNew": "Dodaj nowy",
|
||||
"Backup": "Kopia zapasowa",
|
||||
"AllResultsAreHiddenByTheAppliedFilter": "Wszystkie wyniki są ukrywane przez zastosowany filtr"
|
||||
"AllResultsAreHiddenByTheAppliedFilter": "Wszystkie wyniki są ukrywane przez zastosowany filtr",
|
||||
"ExtraFileExtensionsHelpText": "Rozdzielana przecinkami lista dodatkowych plików do zaimportowania (.nfo zostanie zaimportowane jako .nfo-orig)",
|
||||
"ExtraFileExtensionsHelpTextsExamples": "Przykłady: „.sub, .nfo” lub „sub, nfo”"
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user