Compare commits

..

23 Commits

Author SHA1 Message Date
Stevie Robinson
4dc3d69a11 Fix RemoveHelpTextWarning > RemoveFromDownloadClientHelpTextWarning
(cherry picked from commit 901b6d20841bfcb2a3724fe27b0fbddf5e41d669)
2023-08-12 04:21:38 +00:00
Weblate
695781dde5 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Weblate <noreply@weblate.org>
Translate-URL: https://translate.servarr.com/projects/servarr/readarr/
Translation: Servarr/Readarr
2023-08-11 21:02:05 +03:00
Servarr
4e8ddd3018 Automated API Docs update [skip ci] 2023-08-11 20:04:43 +03:00
Bogdan
eb67231a45 New: Show successful grabs in Interactive Search with green icon
(cherry picked from commit 366b2b8b52d8375f1f41719a09893136009a5b48)

Closes #2780
2023-08-11 19:51:21 +03:00
Mark McDowall
3d3a458828 New: Add additional logging when renaming extra files
(cherry picked from commit 1ae0dc81f73ef74078f07fd5536a7d9058df649d)

Closes #2782
2023-08-11 19:48:46 +03:00
Bogdan
a11930a03f add @types/lodash 2023-08-11 19:40:21 +03:00
Bogdan
abaf39d67e Add simplified translations 2023-08-11 19:40:01 +03:00
Bogdan
894a5943e4 Simplify column translations
(cherry picked from commit 551ea18caf50353c4c8dbeba5e42d266dbbfb54d)

Closes #2759
2023-08-11 19:14:44 +03:00
Bogdan
be26647afb New: More translations for columns
(cherry picked from commit aee8579d1823b7dfb94c0055fe33b5fb5a7fbf17)

Towards #2733
2023-08-11 18:56:33 +03:00
Mark McDowall
b319a4bce7 Fixed: Translations for columns
(cherry picked from commit 6d53d2a153a98070c42d0619c15902b6bd5dfab4)

Closes #2702
2023-08-11 18:53:50 +03:00
Mark McDowall
f03fd7e95e Fixed: Improve translation loading
(cherry picked from commit 73c5ec1da4dd00301e1b0dddbcea37590a99b045)

Closes #2699
2023-08-11 18:52:34 +03:00
Mark McDowall
7f25a3c4b1 UI loading improvements
Fixed: Caching for dynamically loaded JS files
Fixed: Incorrect caching of initialize.js
(cherry picked from commit f0cb5b81f140c67fa84162e094cc4e0f3476f5da)

Closes #2690
Closes #2696
2023-08-11 18:21:47 +03:00
Weblate
e3247dc505 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Fixer <ygj59783@zslsz.com>
Co-authored-by: Havok Dan <havokdan@yahoo.com.br>
Co-authored-by: Ivan Mazzoli <dreadtank27@gmail.com>
Co-authored-by: Nir Israel Hen <nirisraelh@gmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: byakurau <byakurau1@gmail.com>
Co-authored-by: wilfriedarma <wilfriedarma.collet@gmail.com>
Translate-URL: https://translate.servarr.com/projects/servarr/readarr/
Translate-URL: https://translate.servarr.com/projects/servarr/readarr/fr/
Translate-URL: https://translate.servarr.com/projects/servarr/readarr/he/
Translate-URL: https://translate.servarr.com/projects/servarr/readarr/it/
Translate-URL: https://translate.servarr.com/projects/servarr/readarr/pl/
Translate-URL: https://translate.servarr.com/projects/servarr/readarr/pt_BR/
Translate-URL: https://translate.servarr.com/projects/servarr/readarr/ro/
Translation: Servarr/Readarr
2023-08-10 19:59:14 +03:00
Weblate
3677fd6d34 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Havok Dan <havokdan@yahoo.com.br>
Co-authored-by: Ivan Mazzoli <dreadtank27@gmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: byakurau <byakurau1@gmail.com>
Translate-URL: https://translate.servarr.com/projects/servarr/readarr/it/
Translate-URL: https://translate.servarr.com/projects/servarr/readarr/pl/
Translate-URL: https://translate.servarr.com/projects/servarr/readarr/pt_BR/
Translation: Servarr/Readarr
2023-08-10 19:58:44 +03:00
Bogdan
4f6901b1ff Fixed: Ensure failing providers are marked as failed when testing all
(cherry picked from commit f6c05d4456a5667398319e249614e2eed115621e)
2023-08-10 19:58:25 +03:00
Bogdan
ce820f6f73 Fixed: Detect Docker when using control group v2 2023-08-09 10:48:37 +03:00
Bogdan
53e6cb24b7 Bump version to 0.3.2 2023-08-06 19:27:59 +03:00
Bogdan
7c1ca8acc1 New: Health check for indexers with invalid download client
(cherry picked from commit 377fce6fe15c0875c4bd33f1371a31af79c9310c)

Closes #2760
2023-08-06 19:25:00 +03:00
Bogdan
5e9e578101 Ensure path is valid before watching it
(cherry picked from commit 1245b2c58b5a1b5fb4aee9a4f974ecfb131de2bd)
2023-08-06 19:24:58 +03:00
Bogdan
156407c541 Add @types/redux-actions 2023-08-06 19:12:55 +03:00
Mark McDowall
1ef6c60318 Sync Popover with upstream
(cherry picked from commit bdcfef80d627e777d7932c54cda04cbe7c656ffc)
2023-08-06 19:12:04 +03:00
servarr[bot]
73b3b1848b Filter user issues from Sentry
(cherry picked from commit 03d361f5537bfc0caba1b86085f974570942fdbc)

Co-authored-by: Qstick <qstick@gmail.com>
2023-08-05 21:56:25 +03:00
Weblate
33fbd95707 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Albert <zuozl1992@foxmail.com>
Co-authored-by: Fixer <ygj59783@zslsz.com>
Co-authored-by: Havok Dan <havokdan@yahoo.com.br>
Co-authored-by: Magnus <magnus.fladvad@gmail.com>
Co-authored-by: Stjepan <stjepstjepanovic@gmail.com>
Co-authored-by: Thirrian <matthiaslantermann@gmail.com>
Co-authored-by: stormaac <yxc.frank@gmail.com>
Translate-URL: https://translate.servarr.com/projects/servarr/readarr/fr/
Translate-URL: https://translate.servarr.com/projects/servarr/readarr/hr/
Translate-URL: https://translate.servarr.com/projects/servarr/readarr/nb_NO/
Translate-URL: https://translate.servarr.com/projects/servarr/readarr/nl/
Translate-URL: https://translate.servarr.com/projects/servarr/readarr/pt_BR/
Translate-URL: https://translate.servarr.com/projects/servarr/readarr/ro/
Translate-URL: https://translate.servarr.com/projects/servarr/readarr/zh_CN/
Translation: Servarr/Readarr
2023-08-03 22:55:45 +03:00
105 changed files with 941 additions and 563 deletions

View File

@@ -9,7 +9,7 @@ variables:
testsFolder: './_tests'
yarnCacheFolder: $(Pipeline.Workspace)/.yarn
nugetCacheFolder: $(Pipeline.Workspace)/.nuget/packages
majorVersion: '0.3.1'
majorVersion: '0.3.2'
minorVersion: $[counter('minorVersion', 1)]
readarrVersion: '$(majorVersion).$(minorVersion)'
buildName: '$(Build.SourceBranchName).$(readarrVersion)'

View File

@@ -36,7 +36,7 @@ module.exports = (env) => {
},
entry: {
index: 'index.js'
index: 'index.ts'
},
resolve: {
@@ -98,7 +98,8 @@ module.exports = (env) => {
new HtmlWebpackPlugin({
template: 'frontend/src/index.ejs',
filename: 'index.html',
publicPath: '/'
publicPath: '/',
inject: false
}),
new FileManagerPlugin({

View File

@@ -108,7 +108,7 @@ class RemoveQueueItemModal extends Component {
type={inputTypes.CHECK}
name="remove"
value={remove}
helpTextWarning={translate('RemoveHelpTextWarning')}
helpTextWarning={translate('RemoveFromDownloadClientHelpTextWarning')}
isDisabled={!canIgnore}
onChange={this.onRemoveChange}
/>

View File

@@ -7,13 +7,13 @@ import PageConnector from 'Components/Page/PageConnector';
import ApplyTheme from './ApplyTheme';
import AppRoutes from './AppRoutes';
function App({ store, history, hasTranslationsError }) {
function App({ store, history }) {
return (
<DocumentTitle title={window.Readarr.instanceName}>
<Provider store={store}>
<ConnectedRouter history={history}>
<ApplyTheme>
<PageConnector hasTranslationsError={hasTranslationsError}>
<PageConnector>
<AppRoutes app={App} />
</PageConnector>
</ApplyTheme>
@@ -25,8 +25,7 @@ function App({ store, history, hasTranslationsError }) {
App.propTypes = {
store: PropTypes.object.isRequired,
history: PropTypes.object.isRequired,
hasTranslationsError: PropTypes.bool.isRequired
history: PropTypes.object.isRequired
};
export default App;

View File

@@ -14,14 +14,39 @@ import { inputTypes } from 'Helpers/Props';
import translate from 'Utilities/String/translate';
const nameOptions = [
{ key: 'firstLast', value: translate('NameFirstLast') },
{ key: 'lastFirst', value: translate('NameLastFirst') }
{
key: 'firstLast',
get value() {
return translate('NameFirstLast');
}
},
{
key: 'lastFirst',
get value() {
return translate('NameLastFirst');
}
}
];
const posterSizeOptions = [
{ key: 'small', value: 'Small' },
{ key: 'medium', value: 'Medium' },
{ key: 'large', value: 'Large' }
{
key: 'small',
get value() {
return translate('Small');
}
},
{
key: 'medium',
get value() {
return translate('Medium');
}
},
{
key: 'large',
get value() {
return translate('Large');
}
}
];
class AuthorIndexOverviewOptionsModalContent extends Component {

View File

@@ -14,15 +14,45 @@ import { inputTypes } from 'Helpers/Props';
import translate from 'Utilities/String/translate';
const posterSizeOptions = [
{ key: 'small', value: 'Small' },
{ key: 'medium', value: 'Medium' },
{ key: 'large', value: 'Large' }
{
key: 'small',
get value() {
return translate('Small');
}
},
{
key: 'medium',
get value() {
return translate('Medium');
}
},
{
key: 'large',
get value() {
return translate('Large');
}
}
];
const nameOptions = [
{ key: 'no', value: translate('NoName') },
{ key: 'firstLast', value: translate('NameFirstLast') },
{ key: 'lastFirst', value: translate('NameLastFirst') }
{
key: 'no',
get value() {
return translate('NoName');
}
},
{
key: 'firstLast',
get value() {
return translate('NameFirstLast');
}
},
{
key: 'lastFirst',
get value() {
return translate('NameLastFirst');
}
}
];
class AuthorIndexPosterOptionsModalContent extends Component {

View File

@@ -7,8 +7,18 @@ import { inputTypes } from 'Helpers/Props';
import translate from 'Utilities/String/translate';
const nameOptions = [
{ key: 'firstLast', value: translate('NameFirstLast') },
{ key: 'lastFirst', value: translate('NameLastFirst') }
{
key: 'firstLast',
get value() {
return translate('NameFirstLast');
}
},
{
key: 'lastFirst',
get value() {
return translate('NameLastFirst');
}
}
];
class AuthorIndexTableOptions extends Component {

View File

@@ -6,4 +6,5 @@
.statusIcon {
width: 20px !important;
text-align: center;
}

View File

@@ -206,9 +206,11 @@ class FilterBuilderRow extends Component {
const selectedFilterBuilderProp = this.selectedFilterBuilderProp;
const keyOptions = filterBuilderProps.map((availablePropFilter) => {
const { name, label } = availablePropFilter;
return {
key: availablePropFilter.name,
value: availablePropFilter.label
key: name,
value: typeof label === 'function' ? label() : label
};
}).sort((a, b) => a.value.localeCompare(b.value));

View File

@@ -61,7 +61,7 @@ class SelectInput extends Component {
value={key}
{...otherOptionProps}
>
{optionValue}
{typeof optionValue === 'function' ? optionValue() : optionValue}
</option>
);
})
@@ -75,7 +75,7 @@ SelectInput.propTypes = {
className: PropTypes.string,
disabledClassName: PropTypes.string,
name: PropTypes.string.isRequired,
value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
value: PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.func]).isRequired,
values: PropTypes.arrayOf(PropTypes.object).isRequired,
isDisabled: PropTypes.bool,
hasError: PropTypes.bool,

View File

@@ -41,7 +41,7 @@ class Icon extends PureComponent {
return (
<span
className={containerClassName}
title={title}
title={typeof title === 'function' ? title() : title}
>
{icon}
</span>
@@ -58,7 +58,7 @@ Icon.propTypes = {
name: PropTypes.object.isRequired,
kind: PropTypes.string.isRequired,
size: PropTypes.number.isRequired,
title: PropTypes.string,
title: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
isSpinning: PropTypes.bool.isRequired,
fixedWidth: PropTypes.bool.isRequired
};

View File

@@ -32,7 +32,7 @@ class FilterMenuContent extends Component {
selectedFilterKey={selectedFilterKey}
onPress={onFilterSelect}
>
{filter.label}
{typeof filter.label === 'function' ? filter.label() : filter.label}
</FilterMenuItem>
);
})

View File

@@ -7,7 +7,7 @@ function ErrorPage(props) {
const {
version,
isLocalStorageSupported,
hasTranslationsError,
translationsError,
authorError,
customFiltersError,
tagsError,
@@ -21,8 +21,8 @@ function ErrorPage(props) {
if (!isLocalStorageSupported) {
errorMessage = 'Local Storage is not supported or disabled. A plugin or private browsing may have disabled it.';
} else if (hasTranslationsError) {
errorMessage = 'Failed to load translations from API';
} else if (translationsError) {
errorMessage = getErrorMessage(translationsError, 'Failed to load translations from API');
} else if (authorError) {
errorMessage = getErrorMessage(authorError, 'Failed to load author from API');
} else if (customFiltersError) {
@@ -55,7 +55,7 @@ function ErrorPage(props) {
ErrorPage.propTypes = {
version: PropTypes.string.isRequired,
isLocalStorageSupported: PropTypes.bool.isRequired,
hasTranslationsError: PropTypes.bool.isRequired,
translationsError: PropTypes.object,
authorError: PropTypes.object,
customFiltersError: PropTypes.object,
tagsError: PropTypes.object,

View File

@@ -3,7 +3,7 @@ import React, { Component } from 'react';
import { connect } from 'react-redux';
import { withRouter } from 'react-router-dom';
import { createSelector } from 'reselect';
import { saveDimensions, setIsSidebarVisible } from 'Store/Actions/appActions';
import { fetchTranslations, saveDimensions, setIsSidebarVisible } from 'Store/Actions/appActions';
import { fetchAuthor } from 'Store/Actions/authorActions';
import { fetchBooks } from 'Store/Actions/bookActions';
import { fetchCustomFilters } from 'Store/Actions/customFilterActions';
@@ -52,6 +52,7 @@ const selectIsPopulated = createSelector(
(state) => state.settings.metadataProfiles.isPopulated,
(state) => state.settings.importLists.isPopulated,
(state) => state.system.status.isPopulated,
(state) => state.app.translations.isPopulated,
(
customFiltersIsPopulated,
tagsIsPopulated,
@@ -60,7 +61,8 @@ const selectIsPopulated = createSelector(
qualityProfilesIsPopulated,
metadataProfilesIsPopulated,
importListsIsPopulated,
systemStatusIsPopulated
systemStatusIsPopulated,
translationsIsPopulated
) => {
return (
customFiltersIsPopulated &&
@@ -70,7 +72,8 @@ const selectIsPopulated = createSelector(
qualityProfilesIsPopulated &&
metadataProfilesIsPopulated &&
importListsIsPopulated &&
systemStatusIsPopulated
systemStatusIsPopulated &&
translationsIsPopulated
);
}
);
@@ -84,6 +87,7 @@ const selectErrors = createSelector(
(state) => state.settings.metadataProfiles.error,
(state) => state.settings.importLists.error,
(state) => state.system.status.error,
(state) => state.app.translations.error,
(
customFiltersError,
tagsError,
@@ -92,7 +96,8 @@ const selectErrors = createSelector(
qualityProfilesError,
metadataProfilesError,
importListsError,
systemStatusError
systemStatusError,
translationsError
) => {
const hasError = !!(
customFiltersError ||
@@ -102,7 +107,8 @@ const selectErrors = createSelector(
qualityProfilesError ||
metadataProfilesError ||
importListsError ||
systemStatusError
systemStatusError ||
translationsError
);
return {
@@ -114,7 +120,8 @@ const selectErrors = createSelector(
qualityProfilesError,
metadataProfilesError,
importListsError,
systemStatusError
systemStatusError,
translationsError
};
}
);
@@ -176,6 +183,9 @@ function createMapDispatchToProps(dispatch, props) {
dispatchFetchStatus() {
dispatch(fetchStatus());
},
dispatchFetchTranslations() {
dispatch(fetchTranslations());
},
onResize(dimensions) {
dispatch(saveDimensions(dimensions));
},
@@ -210,6 +220,7 @@ class PageConnector extends Component {
this.props.dispatchFetchImportLists();
this.props.dispatchFetchUISettings();
this.props.dispatchFetchStatus();
this.props.dispatchFetchTranslations();
}
}
@@ -225,7 +236,6 @@ class PageConnector extends Component {
render() {
const {
hasTranslationsError,
isPopulated,
hasError,
dispatchFetchAuthor,
@@ -237,15 +247,15 @@ class PageConnector extends Component {
dispatchFetchImportLists,
dispatchFetchUISettings,
dispatchFetchStatus,
dispatchFetchTranslations,
...otherProps
} = this.props;
if (hasTranslationsError || hasError || !this.state.isLocalStorageSupported) {
if (hasError || !this.state.isLocalStorageSupported) {
return (
<ErrorPage
{...this.state}
{...otherProps}
hasTranslationsError={hasTranslationsError}
/>
);
}
@@ -266,7 +276,6 @@ class PageConnector extends Component {
}
PageConnector.propTypes = {
hasTranslationsError: PropTypes.bool.isRequired,
isPopulated: PropTypes.bool.isRequired,
hasError: PropTypes.bool.isRequired,
isSidebarVisible: PropTypes.bool.isRequired,
@@ -280,6 +289,7 @@ PageConnector.propTypes = {
dispatchFetchImportLists: PropTypes.func.isRequired,
dispatchFetchUISettings: PropTypes.func.isRequired,
dispatchFetchStatus: PropTypes.func.isRequired,
dispatchFetchTranslations: PropTypes.func.isRequired,
onSidebarVisibleChange: PropTypes.func.isRequired
};

View File

@@ -21,28 +21,28 @@ const SIDEBAR_WIDTH = parseInt(dimensions.sidebarWidth);
const links = [
{
iconName: icons.AUTHOR_CONTINUING,
title: 'Library',
title: () => translate('Library'),
to: '/',
alias: '/authors',
children: [
{
title: 'Authors',
title: () => translate('Authors'),
to: '/authors'
},
{
title: 'Books',
title: () => translate('Books'),
to: '/books'
},
{
title: 'Add New',
title: () => translate('AddNew'),
to: '/add/search'
},
{
title: 'Bookshelf',
title: () => translate('Bookshelf'),
to: '/shelf'
},
{
title: 'Unmapped Files',
title: () => translate('UnmappedFiles'),
to: '/unmapped'
}
]
@@ -50,26 +50,26 @@ const links = [
{
iconName: icons.CALENDAR,
title: 'Calendar',
title: () => translate('Calendar'),
to: '/calendar'
},
{
iconName: icons.ACTIVITY,
title: 'Activity',
title: () => translate('Activity'),
to: '/activity/queue',
children: [
{
title: 'Queue',
title: () => translate('Queue'),
to: '/activity/queue',
statusComponent: QueueStatusConnector
},
{
title: 'History',
title: () => translate('History'),
to: '/activity/history'
},
{
title: 'Blocklist',
title: () => translate('Blocklist'),
to: '/activity/blocklist'
}
]
@@ -77,15 +77,15 @@ const links = [
{
iconName: icons.WARNING,
title: 'Wanted',
title: () => translate('Wanted'),
to: '/wanted/missing',
children: [
{
title: 'Missing',
title: () => translate('Missing'),
to: '/wanted/missing'
},
{
title: 'Cutoff Unmet',
title: () => translate('CutoffUnmet'),
to: '/wanted/cutoffunmet'
}
]
@@ -93,55 +93,55 @@ const links = [
{
iconName: icons.SETTINGS,
title: 'Settings',
title: () => translate('Settings'),
to: '/settings',
children: [
{
title: 'Media Management',
title: () => translate('MediaManagement'),
to: '/settings/mediamanagement'
},
{
title: 'Profiles',
title: () => translate('Profiles'),
to: '/settings/profiles'
},
{
title: 'Quality',
title: () => translate('Quality'),
to: '/settings/quality'
},
{
title: translate('CustomFormats'),
title: () => translate('CustomFormats'),
to: '/settings/customformats'
},
{
title: translate('Indexers'),
title: () => translate('Indexers'),
to: '/settings/indexers'
},
{
title: 'Download Clients',
title: () => translate('DownloadClients'),
to: '/settings/downloadclients'
},
{
title: 'Import Lists',
title: () => translate('ImportLists'),
to: '/settings/importlists'
},
{
title: 'Connect',
title: () => translate('Connect'),
to: '/settings/connect'
},
{
title: 'Metadata',
title: () => translate('Metadata'),
to: '/settings/metadata'
},
{
title: 'Tags',
title: () => translate('Tags'),
to: '/settings/tags'
},
{
title: 'General',
title: () => translate('General'),
to: '/settings/general'
},
{
title: 'UI',
title: () => translate('Ui'),
to: '/settings/ui'
}
]
@@ -149,32 +149,32 @@ const links = [
{
iconName: icons.SYSTEM,
title: 'System',
title: () => translate('System'),
to: '/system/status',
children: [
{
title: 'Status',
title: () => translate('Status'),
to: '/system/status',
statusComponent: HealthStatusConnector
},
{
title: 'Tasks',
title: () => translate('Tasks'),
to: '/system/tasks'
},
{
title: 'Backup',
title: () => translate('Backup'),
to: '/system/backup'
},
{
title: 'Updates',
title: () => translate('Updates'),
to: '/system/updates'
},
{
title: 'Events',
title: () => translate('Events'),
to: '/system/events'
},
{
title: 'Log Files',
title: () => translate('LogFiles'),
to: '/system/logs/files'
}
]

View File

@@ -64,7 +64,7 @@ class PageSidebarItem extends Component {
}
<span className={isChildItem ? styles.noIcon : null}>
{title}
{typeof title === 'function' ? title() : title}
</span>
{
@@ -88,7 +88,7 @@ class PageSidebarItem extends Component {
PageSidebarItem.propTypes = {
iconName: PropTypes.object,
title: PropTypes.string.isRequired,
title: PropTypes.oneOfType([PropTypes.string, PropTypes.func]).isRequired,
to: PropTypes.string.isRequired,
isActive: PropTypes.bool,
isActiveParent: PropTypes.bool,

View File

@@ -1,8 +1,10 @@
import React from 'react';
type PropertyFunction<T> = () => T;
interface Column {
name: string;
label: string | React.ReactNode;
label: string | PropertyFunction<string> | React.ReactNode;
columnLabel?: string;
isSortable?: boolean;
isVisible: boolean;

View File

@@ -107,7 +107,7 @@ function Table(props) {
{...getTableHeaderCellProps(otherProps)}
{...column}
>
{column.label}
{typeof column.label === 'function' ? column.label() : column.label}
</TableHeaderCell>
);
})

View File

@@ -30,6 +30,7 @@ class TableHeaderCell extends Component {
const {
className,
name,
label,
columnLabel,
isSortable,
isVisible,
@@ -53,7 +54,8 @@ class TableHeaderCell extends Component {
{...otherProps}
component="th"
className={className}
title={columnLabel}
label={typeof label === 'function' ? label() : label}
title={typeof columnLabel === 'function' ? columnLabel() : columnLabel}
onPress={this.onPress}
>
{children}
@@ -77,7 +79,8 @@ class TableHeaderCell extends Component {
TableHeaderCell.propTypes = {
className: PropTypes.string,
name: PropTypes.string.isRequired,
columnLabel: PropTypes.string,
label: PropTypes.oneOfType([PropTypes.string, PropTypes.func, PropTypes.node]),
columnLabel: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
isSortable: PropTypes.bool,
isVisible: PropTypes.bool,
isModifiable: PropTypes.bool,

View File

@@ -35,7 +35,7 @@ function TableOptionsColumn(props) {
isDisabled={isModifiable === false}
onChange={onVisibleChange}
/>
{label}
{typeof label === 'function' ? label() : label}
</label>
{
@@ -56,7 +56,7 @@ function TableOptionsColumn(props) {
TableOptionsColumn.propTypes = {
name: PropTypes.string.isRequired,
label: PropTypes.string.isRequired,
label: PropTypes.oneOfType([PropTypes.string, PropTypes.func]).isRequired,
isVisible: PropTypes.bool.isRequired,
isModifiable: PropTypes.bool.isRequired,
index: PropTypes.number.isRequired,

View File

@@ -112,7 +112,7 @@ class TableOptionsColumnDragSource extends Component {
<TableOptionsColumn
name={name}
label={label}
label={typeof label === 'function' ? label() : label}
isVisible={isVisible}
isModifiable={isModifiable}
index={index}
@@ -138,7 +138,7 @@ class TableOptionsColumnDragSource extends Component {
TableOptionsColumnDragSource.propTypes = {
name: PropTypes.string.isRequired,
label: PropTypes.string.isRequired,
label: PropTypes.oneOfType([PropTypes.string, PropTypes.func]).isRequired,
isVisible: PropTypes.bool.isRequired,
isModifiable: PropTypes.bool.isRequired,
index: PropTypes.number.isRequired,

View File

@@ -1,5 +1,6 @@
import PropTypes from 'prop-types';
import React from 'react';
import { tooltipPositions } from 'Helpers/Props';
import Tooltip from './Tooltip';
import styles from './Popover.css';
@@ -30,8 +31,13 @@ function Popover(props) {
}
Popover.propTypes = {
className: PropTypes.string,
bodyClassName: PropTypes.string,
anchor: PropTypes.node.isRequired,
title: PropTypes.string.isRequired,
body: PropTypes.oneOfType([PropTypes.string, PropTypes.node]).isRequired
body: PropTypes.oneOfType([PropTypes.string, PropTypes.node]).isRequired,
position: PropTypes.oneOf(tooltipPositions.all),
canFlip: PropTypes.bool
};
export default Popover;

View File

@@ -0,0 +1,8 @@
enum TooltipPosition {
Top = 'top',
Right = 'right',
Bottom = 'bottom',
Left = 'left',
}
export default TooltipPosition;

View File

@@ -69,7 +69,7 @@ const columns = [
name: 'customFormats',
label: React.createElement(Icon, {
name: icons.INTERACTIVE,
title: translate('CustomFormat')
title: () => translate('CustomFormat')
}),
isSortable: true,
isVisible: true
@@ -91,9 +91,9 @@ const filterExistingFilesOptions = {
};
const importModeOptions = [
{ key: 'chooseImportMode', value: translate('ChooseImportMethod'), disabled: true },
{ key: 'move', value: translate('MoveFiles') },
{ key: 'copy', value: translate('HardlinkCopyFiles') }
{ key: 'chooseImportMode', value: () => translate('ChooseImportMethod'), disabled: true },
{ key: 'move', value: () => translate('MoveFiles') },
{ key: 'copy', value: () => translate('HardlinkCopyFiles') }
];
const SELECT = 'select';

View File

@@ -56,7 +56,7 @@ const columns = [
name: 'customFormatScore',
label: React.createElement(Icon, {
name: icons.SCORE,
title: translate('CustomFormatScore')
title: () => translate('CustomFormatScore')
}),
isSortable: true,
isVisible: true

View File

@@ -32,6 +32,18 @@ function getDownloadIcon(isGrabbing, isGrabbed, grabError) {
return icons.DOWNLOAD;
}
function getDownloadKind(isGrabbed, grabError, downloadAllowed) {
if (isGrabbed) {
return kinds.SUCCESS;
}
if (grabError || !downloadAllowed) {
return kinds.DANGER;
}
return kinds.DEFAULT;
}
function getDownloadTooltip(isGrabbing, isGrabbed, grabError) {
if (isGrabbing) {
return '';
@@ -212,7 +224,7 @@ class InteractiveSearchRow extends Component {
{
<SpinnerIconButton
name={getDownloadIcon(isGrabbing, isGrabbed, grabError)}
kind={grabError || !downloadAllowed ? kinds.DANGER : kinds.DEFAULT}
kind={getDownloadKind(isGrabbed, grabError, downloadAllowed)}
title={getDownloadTooltip(isGrabbing, isGrabbed, grabError)}
isSpinning={isGrabbing}
onPress={downloadAllowed ? this.onGrabPress : this.onConfirmGrabPress}

View File

@@ -27,9 +27,25 @@ interface ManageDownloadClientsEditModalContentProps {
const NO_CHANGE = 'noChange';
const enableOptions = [
{ key: NO_CHANGE, value: translate('NoChange'), disabled: true },
{ key: 'enabled', value: translate('Enabled') },
{ key: 'disabled', value: translate('Disabled') },
{
key: NO_CHANGE,
get value() {
return translate('NoChange');
},
disabled: true,
},
{
key: 'enabled',
get value() {
return translate('Enabled');
},
},
{
key: 'disabled',
get value() {
return translate('Disabled');
},
},
];
function ManageDownloadClientsEditModalContent(

View File

@@ -36,37 +36,37 @@ type OnSelectedChangeCallback = React.ComponentProps<
const COLUMNS = [
{
name: 'name',
label: translate('Name'),
label: () => translate('Name'),
isSortable: true,
isVisible: true,
},
{
name: 'implementation',
label: translate('Implementation'),
label: () => translate('Implementation'),
isSortable: true,
isVisible: true,
},
{
name: 'enable',
label: translate('Enabled'),
label: () => translate('Enabled'),
isSortable: true,
isVisible: true,
},
{
name: 'priority',
label: translate('Priority'),
label: () => translate('Priority'),
isSortable: true,
isVisible: true,
},
{
name: 'removeCompletedDownloads',
label: translate('RemoveCompleted'),
label: () => translate('RemoveCompleted'),
isSortable: true,
isVisible: true,
},
{
name: 'removeFailedDownloads',
label: translate('RemoveFailed'),
label: () => translate('RemoveFailed'),
isSortable: true,
isVisible: true,
},

View File

@@ -72,9 +72,24 @@ function TagsModalContent(props: TagsModalContentProps) {
}, [tags, applyTags, onApplyTagsPress]);
const applyTagsOptions = [
{ key: 'add', value: translate('Add') },
{ key: 'remove', value: translate('Remove') },
{ key: 'replace', value: translate('Replace') },
{
key: 'add',
get value() {
return translate('Add');
},
},
{
key: 'remove',
get value() {
return translate('Remove');
},
},
{
key: 'replace',
get value() {
return translate('Replace');
},
},
];
return (

View File

@@ -27,9 +27,25 @@ interface ManageImportListsEditModalContentProps {
const NO_CHANGE = 'noChange';
const autoAddOptions = [
{ key: NO_CHANGE, value: translate('NoChange'), disabled: true },
{ key: 'enabled', value: translate('Enabled') },
{ key: 'disabled', value: translate('Disabled') },
{
key: NO_CHANGE,
get value() {
return translate('NoChange');
},
disabled: true,
},
{
key: 'enabled',
get value() {
return translate('Enabled');
},
},
{
key: 'disabled',
get value() {
return translate('Disabled');
},
},
];
function ManageImportListsEditModalContent(

View File

@@ -36,43 +36,43 @@ type OnSelectedChangeCallback = React.ComponentProps<
const COLUMNS = [
{
name: 'name',
label: translate('Name'),
label: () => translate('Name'),
isSortable: true,
isVisible: true,
},
{
name: 'implementation',
label: translate('Implementation'),
label: () => translate('Implementation'),
isSortable: true,
isVisible: true,
},
{
name: 'qualityProfileId',
label: translate('QualityProfile'),
label: () => translate('QualityProfile'),
isSortable: true,
isVisible: true,
},
{
name: 'metadataProfileId',
label: translate('MetadataProfile'),
label: () => translate('MetadataProfile'),
isSortable: true,
isVisible: true,
},
{
name: 'rootFolderPath',
label: translate('RootFolder'),
label: () => translate('RootFolder'),
isSortable: true,
isVisible: true,
},
{
name: 'enableAutomaticAdd',
label: translate('AutoAdd'),
label: () => translate('AutoAdd'),
isSortable: true,
isVisible: true,
},
{
name: 'tags',
label: translate('Tags'),
label: () => translate('Tags'),
isSortable: true,
isVisible: true,
},

View File

@@ -70,9 +70,24 @@ function TagsModalContent(props: TagsModalContentProps) {
}, [tags, applyTags, onApplyTagsPress]);
const applyTagsOptions = [
{ key: 'add', value: translate('Add') },
{ key: 'remove', value: translate('Remove') },
{ key: 'replace', value: translate('Replace') },
{
key: 'add',
get value() {
return translate('Add');
},
},
{
key: 'remove',
get value() {
return translate('Remove');
},
},
{
key: 'replace',
get value() {
return translate('Replace');
},
},
];
return (

View File

@@ -27,9 +27,25 @@ interface ManageIndexersEditModalContentProps {
const NO_CHANGE = 'noChange';
const enableOptions = [
{ key: NO_CHANGE, value: translate('NoChange'), disabled: true },
{ key: 'enabled', value: translate('Enabled') },
{ key: 'disabled', value: translate('Disabled') },
{
key: NO_CHANGE,
get value() {
return translate('NoChange');
},
disabled: true,
},
{
key: 'enabled',
get value() {
return translate('Enabled');
},
},
{
key: 'disabled',
get value() {
return translate('Disabled');
},
},
];
function ManageIndexersEditModalContent(

View File

@@ -36,43 +36,43 @@ type OnSelectedChangeCallback = React.ComponentProps<
const COLUMNS = [
{
name: 'name',
label: translate('Name'),
label: () => translate('Name'),
isSortable: true,
isVisible: true,
},
{
name: 'implementation',
label: translate('Implementation'),
label: () => translate('Implementation'),
isSortable: true,
isVisible: true,
},
{
name: 'enableRss',
label: translate('EnableRSS'),
label: () => translate('EnableRSS'),
isSortable: true,
isVisible: true,
},
{
name: 'enableAutomaticSearch',
label: translate('EnableAutomaticSearch'),
label: () => translate('EnableAutomaticSearch'),
isSortable: true,
isVisible: true,
},
{
name: 'enableInteractiveSearch',
label: translate('EnableInteractiveSearch'),
label: () => translate('EnableInteractiveSearch'),
isSortable: true,
isVisible: true,
},
{
name: 'priority',
label: translate('Priority'),
label: () => translate('Priority'),
isSortable: true,
isVisible: true,
},
{
name: 'tags',
label: translate('Tags'),
label: () => translate('Tags'),
isSortable: true,
isVisible: true,
},

View File

@@ -70,9 +70,24 @@ function TagsModalContent(props: TagsModalContentProps) {
}, [tags, applyTags, onApplyTagsPress]);
const applyTagsOptions = [
{ key: 'add', value: translate('Add') },
{ key: 'remove', value: translate('Remove') },
{ key: 'replace', value: translate('Replace') },
{
key: 'add',
get value() {
return translate('Add');
},
},
{
key: 'remove',
get value() {
return translate('Remove');
},
},
{
key: 'replace',
get value() {
return translate('Replace');
},
},
];
return (

View File

@@ -11,16 +11,51 @@ import { inputTypes, kinds } from 'Helpers/Props';
import translate from 'Utilities/String/translate';
const writeAudioTagOptions = [
{ key: 'no', value: translate('WriteTagsNo') },
{ key: 'sync', value: translate('WriteTagsSync') },
{ key: 'allFiles', value: translate('WriteTagsAll') },
{ key: 'newFiles', value: translate('WriteTagsNew') }
{
key: 'no',
get value() {
return translate('WriteTagsNo');
}
},
{
key: 'sync',
get value() {
return translate('WriteTagsSync');
}
},
{
key: 'allFiles',
get value() {
return translate('WriteTagsAll');
}
},
{
key: 'newFiles',
get value() {
return translate('WriteTagsNew');
}
}
];
const writeBookTagOptions = [
{ key: 'sync', value: translate('WriteTagsSync') },
{ key: 'allFiles', value: translate('WriteTagsAll') },
{ key: 'newFiles', value: translate('WriteTagsNew') }
{
key: 'sync',
get value() {
return translate('WriteTagsSync');
}
},
{
key: 'allFiles',
get value() {
return translate('WriteTagsAll');
}
},
{
key: 'newFiles',
get value() {
return translate('WriteTagsNew');
}
}
];
function MetadataProvider(props) {

View File

@@ -139,7 +139,7 @@ function Settings() {
className={styles.link}
to="/settings/ui"
>
{translate('UI')}
{translate('Ui')}
</Link>
<div className={styles.summary}>

View File

@@ -4,6 +4,7 @@ import { createThunk, handleThunks } from 'Store/thunks';
import createAjaxRequest from 'Utilities/createAjaxRequest';
import getSectionState from 'Utilities/State/getSectionState';
import updateSectionState from 'Utilities/State/updateSectionState';
import { fetchTranslations as fetchAppTranslations } from 'Utilities/String/translate';
import createHandleActions from './Creators/createHandleActions';
function getDimensions(width, height) {
@@ -41,7 +42,12 @@ export const defaultState = {
isReconnecting: false,
isDisconnected: false,
isRestarting: false,
isSidebarVisible: !getDimensions(window.innerWidth, window.innerHeight).isSmallScreen
isSidebarVisible: !getDimensions(window.innerWidth, window.innerHeight).isSmallScreen,
translations: {
isFetching: true,
isPopulated: false,
error: null
}
};
//
@@ -53,6 +59,7 @@ export const SAVE_DIMENSIONS = 'app/saveDimensions';
export const SET_VERSION = 'app/setVersion';
export const SET_APP_VALUE = 'app/setAppValue';
export const SET_IS_SIDEBAR_VISIBLE = 'app/setIsSidebarVisible';
export const FETCH_TRANSLATIONS = 'app/fetchTranslations';
export const PING_SERVER = 'app/pingServer';
@@ -66,6 +73,7 @@ export const setAppValue = createAction(SET_APP_VALUE);
export const showMessage = createAction(SHOW_MESSAGE);
export const hideMessage = createAction(HIDE_MESSAGE);
export const pingServer = createThunk(PING_SERVER);
export const fetchTranslations = createThunk(FETCH_TRANSLATIONS);
//
// Helpers
@@ -127,6 +135,17 @@ function pingServerAfterTimeout(getState, dispatch) {
export const actionHandlers = handleThunks({
[PING_SERVER]: function(getState, payload, dispatch) {
pingServerAfterTimeout(getState, dispatch);
},
[FETCH_TRANSLATIONS]: async function(getState, payload, dispatch) {
const isFetchingComplete = await fetchAppTranslations();
dispatch(setAppValue({
translations: {
isFetching: false,
isPopulated: isFetchingComplete,
error: isFetchingComplete ? null : 'Failed to load translations from API'
}
}));
}
});

View File

@@ -24,12 +24,12 @@ export const section = 'books';
export const filters = [
{
key: 'all',
label: translate('All'),
label: () => translate('All'),
filters: []
},
{
key: 'monitored',
label: translate('Monitored'),
label: () => translate('Monitored'),
filters: [
{
key: 'monitored',
@@ -40,7 +40,7 @@ export const filters = [
},
{
key: 'unmonitored',
label: translate('Unmonitored'),
label: () => translate('Unmonitored'),
filters: [
{
key: 'monitored',
@@ -51,7 +51,7 @@ export const filters = [
},
{
key: 'missing',
label: translate('Missing'),
label: () => translate('Missing'),
filters: [
{
key: 'monitored',
@@ -67,7 +67,7 @@ export const filters = [
},
{
key: 'wanted',
label: translate('Wanted'),
label: () => translate('Wanted'),
filters: [
{
key: 'monitored',

View File

@@ -60,32 +60,32 @@ export const defaultState = {
columns: [
{
name: 'status',
columnLabel: translate('Status'),
columnLabel: () => translate('Status'),
isSortable: true,
isVisible: true,
isModifiable: false
},
{
name: 'authorMetadata.sortName',
label: translate('Author'),
label: () => translate('Author'),
isSortable: true,
isVisible: true
},
{
name: 'books.title',
label: translate('BookTitle'),
label: () => translate('BookTitle'),
isSortable: true,
isVisible: true
},
{
name: 'books.releaseDate',
label: translate('ReleaseDate'),
label: () => translate('ReleaseDate'),
isSortable: true,
isVisible: false
},
{
name: 'quality',
label: translate('Quality'),
label: () => translate('Quality'),
isSortable: true,
isVisible: true
},
@@ -97,64 +97,64 @@ export const defaultState = {
},
{
name: 'customFormatScore',
columnLabel: translate('CustomFormatScore'),
columnLabel: () => translate('CustomFormatScore'),
label: React.createElement(Icon, {
name: icons.SCORE,
title: translate('CustomFormatScore')
title: () => translate('CustomFormatScore')
}),
isVisible: false
},
{
name: 'protocol',
label: translate('Protocol'),
label: () => translate('Protocol'),
isSortable: true,
isVisible: false
},
{
name: 'indexer',
label: translate('Indexer'),
label: () => translate('Indexer'),
isSortable: true,
isVisible: false
},
{
name: 'downloadClient',
label: translate('DownloadClient'),
label: () => translate('DownloadClient'),
isSortable: true,
isVisible: false
},
{
name: 'title',
label: translate('ReleaseTitle'),
label: () => translate('ReleaseTitle'),
isSortable: true,
isVisible: false
},
{
name: 'size',
label: translate('Size'),
label: () => translate('Size'),
isSortable: true,
isVisible: false
},
{
name: 'outputPath',
label: translate('OutputPath'),
label: () => translate('OutputPath'),
isSortable: false,
isVisible: false
},
{
name: 'estimatedCompletionTime',
label: translate('TimeLeft'),
label: () => translate('TimeLeft'),
isSortable: true,
isVisible: true
},
{
name: 'progress',
label: translate('Progress'),
label: () => translate('Progress'),
isSortable: true,
isVisible: true
},
{
name: 'actions',
columnLabel: translate('Actions'),
columnLabel: () => translate('Actions'),
isVisible: true,
isModifiable: false
}

View File

@@ -199,7 +199,7 @@ export const defaultState = {
},
{
name: 'customFormatScore',
label: translate('CustomFormatScore'),
label: () => translate('CustomFormatScore'),
type: filterBuilderTypes.NUMBER
},
{

View File

@@ -82,34 +82,34 @@ export const defaultState = {
columns: [
{
name: 'level',
columnLabel: translate('Level'),
columnLabel: () => translate('Level'),
isSortable: false,
isVisible: true,
isModifiable: false
},
{
name: 'time',
label: translate('Time'),
label: () => translate('Time'),
isSortable: true,
isVisible: true,
isModifiable: false
},
{
name: 'logger',
label: translate('Component'),
label: () => translate('Component'),
isSortable: false,
isVisible: true,
isModifiable: false
},
{
name: 'message',
label: translate('Message'),
label: () => translate('Message'),
isVisible: true,
isModifiable: false
},
{
name: 'actions',
columnLabel: translate('Actions'),
columnLabel: () => translate('Actions'),
isSortable: true,
isVisible: true,
isModifiable: false

View File

@@ -36,10 +36,17 @@ function mergeColumns(path, initialState, persistedState, computedState) {
const column = initialColumns.find((i) => i.name === persistedColumn.name);
if (column) {
columns.push({
...column,
isVisible: persistedColumn.isVisible
});
const newColumn = {};
// We can't use a spread operator or Object.assign to clone the column
// or any accessors are lost and can break translations.
for (const prop of Object.keys(column)) {
Object.defineProperty(newColumn, prop, Object.getOwnPropertyDescriptor(column, prop));
}
newColumn.isVisible = persistedColumn.isVisible;
columns.push(newColumn);
}
});

View File

@@ -21,17 +21,17 @@ const columns = [
},
{
name: 'name',
label: 'Name',
label: () => translate('Name'),
isVisible: true
},
{
name: 'size',
label: 'Size',
label: () => translate('Size'),
isVisible: true
},
{
name: 'time',
label: 'Time',
label: () => translate('Time'),
isVisible: true
},
{

View File

@@ -19,12 +19,12 @@ import LogFilesTableRow from './LogFilesTableRow';
const columns = [
{
name: 'filename',
label: 'Filename',
label: () => translate('Filename'),
isVisible: true
},
{
name: 'lastWriteTime',
label: 'Last Write Time',
label: () => translate('LastWriteTime'),
isVisible: true
},
{

View File

@@ -15,17 +15,17 @@ import styles from './DiskSpace.css';
const columns = [
{
name: 'path',
label: 'Location',
label: () => translate('Location'),
isVisible: true
},
{
name: 'freeSpace',
label: 'Free Space',
label: () => translate('FreeSpace'),
isVisible: true
},
{
name: 'totalSpace',
label: 'Total Space',
label: () => translate('TotalSpace'),
isVisible: true
},
{

View File

@@ -95,12 +95,12 @@ const columns = [
},
{
name: 'message',
label: 'Message',
label: () => translate('Message'),
isVisible: true
},
{
name: 'actions',
label: 'Actions',
label: () => translate('Actions'),
isVisible: true
}
];

View File

@@ -15,27 +15,27 @@ const columns = [
},
{
name: 'commandName',
label: translate('Name'),
label: () => translate('Name'),
isVisible: true
},
{
name: 'queued',
label: translate('Queued'),
label: () => translate('Queued'),
isVisible: true
},
{
name: 'started',
label: translate('Started'),
label: () => translate('Started'),
isVisible: true
},
{
name: 'ended',
label: translate('Ended'),
label: () => translate('Ended'),
isVisible: true
},
{
name: 'duration',
label: translate('Duration'),
label: () => translate('Duration'),
isVisible: true
},
{

View File

@@ -10,27 +10,27 @@ import ScheduledTaskRowConnector from './ScheduledTaskRowConnector';
const columns = [
{
name: 'name',
label: 'Name',
label: () => translate('Name'),
isVisible: true
},
{
name: 'interval',
label: 'Interval',
label: () => translate('Interval'),
isVisible: true
},
{
name: 'lastExecution',
label: 'Last Execution',
label: () => translate('LastExecution'),
isVisible: true
},
{
name: 'lastDuration',
label: 'Last Duration',
label: () => translate('LastDuration'),
isVisible: true
},
{
name: 'nextExecution',
label: 'Next Execution',
label: () => translate('NextExecution'),
isVisible: true
},
{

View File

@@ -4,14 +4,14 @@ function getTranslations() {
return createAjaxRequest({
global: false,
dataType: 'json',
url: '/localization'
url: '/localization',
}).request;
}
let translations = {};
let translations: Record<string, string> = {};
export function fetchTranslations() {
return new Promise(async(resolve) => {
export async function fetchTranslations(): Promise<boolean> {
return new Promise(async (resolve) => {
try {
const data = await getTranslations();
translations = data.Strings;
@@ -23,12 +23,19 @@ export function fetchTranslations() {
});
}
export default function translate(key, args = []) {
export default function translate(
key: string,
args?: (string | number | boolean)[]
) {
if (!(key in translations)) {
console.debug(key);
}
const translation = translations[key] || key;
if (args) {
return translation.replace(/\{(\d+)\}/g, (match, index) => {
return args[index];
return String(args[index]) ?? match;
});
}

View File

@@ -0,0 +1,15 @@
import { createBrowserHistory } from 'history';
import React from 'react';
import { render } from 'react-dom';
import createAppStore from 'Store/createAppStore';
import App from './App/App';
export async function bootstrap() {
const history = createBrowserHistory();
const store = createAppStore(history);
render(
<App store={store} history={history} />,
document.getElementById('root')
);
}

View File

@@ -48,7 +48,15 @@
/>
<link rel="stylesheet" type="text/css" href="/Content/Fonts/fonts.css">
<!-- webpack bundles head -->
<script>
window.Readarr = {
urlBase: '__URL_BASE__'
};
</script>
<% for (key in htmlWebpackPlugin.files.js) { %><script type="text/javascript" src="<%= htmlWebpackPlugin.files.js[key] %>" data-no-hash></script><% } %>
<% for (key in htmlWebpackPlugin.files.css) { %><link href="<%= htmlWebpackPlugin.files.css[key] %>" rel="stylesheet"></link><% } %>
<title>Readarr</title>
@@ -77,7 +85,4 @@
<div id="portal-root"></div>
<div id="root" class="root"></div>
</body>
<script src="/initialize.js" data-no-hash></script>
<!-- webpack bundles body -->
</html>

View File

@@ -1,26 +0,0 @@
import { createBrowserHistory } from 'history';
import React from 'react';
import { render } from 'react-dom';
import { fetchTranslations } from 'Utilities/String/translate';
import './preload';
import './polyfills';
import 'Styles/globals.css';
import './index.css';
const history = createBrowserHistory();
const hasTranslationsError = !await fetchTranslations();
const { default: createAppStore } = await import('Store/createAppStore');
const { default: App } = await import('./App/App');
const store = createAppStore(history);
render(
<App
store={store}
history={history}
hasTranslationsError={hasTranslationsError}
/>,
document.getElementById('root')
);

19
frontend/src/index.ts Normal file
View File

@@ -0,0 +1,19 @@
import './polyfills';
import 'Styles/globals.css';
import './index.css';
const initializeUrl = `${
window.Readarr.urlBase
}/initialize.json?t=${Date.now()}`;
const response = await fetch(initializeUrl);
window.Readarr = await response.json();
/* eslint-disable no-undef, @typescript-eslint/ban-ts-comment */
// @ts-ignore 2304
__webpack_public_path__ = `${window.Readarr.urlBase}/`;
/* eslint-enable no-undef, @typescript-eslint/ban-ts-comment */
const { bootstrap } = await import('./bootstrap');
await bootstrap();

View File

@@ -1,11 +1,11 @@
{
"compilerOptions": {
"target": "es6",
"target": "esnext",
"allowJs": true,
"checkJs": false,
"baseUrl": "src",
"jsx": "react",
"module": "commonjs",
"module": "esnext",
"moduleResolution": "node",
"noEmit": true,
"esModuleInterop": true,

View File

@@ -20,7 +20,7 @@
"author": "Team Readarr",
"license": "GPL-3.0",
"readmeFilename": "readme.md",
"main": "index.js",
"main": "index.ts",
"browserslist": [
"defaults"
],
@@ -97,6 +97,8 @@
"@babel/preset-env": "7.22.9",
"@babel/preset-react": "7.22.5",
"@babel/preset-typescript": "7.22.5",
"@types/lodash": "4.14.197",
"@types/redux-actions": "2.6.2",
"@typescript-eslint/eslint-plugin": "6.0.0",
"@typescript-eslint/parser": "6.0.0",
"autoprefixer": "10.4.14",

View File

@@ -77,7 +77,9 @@ namespace NzbDrone.Common.EnvironmentInfo
FullName = Name;
}
if (IsLinux && File.Exists("/proc/1/cgroup") && File.ReadAllText("/proc/1/cgroup").Contains("/docker/"))
if (IsLinux &&
((File.Exists("/proc/1/cgroup") && File.ReadAllText("/proc/1/cgroup").Contains("/docker/")) ||
(File.Exists("/proc/1/mountinfo") && File.ReadAllText("/proc/1/mountinfo").Contains("/docker/"))))
{
IsDocker = true;
}

View File

@@ -43,7 +43,13 @@ namespace NzbDrone.Common.Instrumentation.Sentry
"OutOfMemoryException",
// Filter out people stuck in boot loops
"CorruptDatabaseException"
"CorruptDatabaseException",
// Filter SingleInstance Termination Exceptions
"TerminateApplicationException",
// User config issue, root folder missing, etc.
"DirectoryNotFoundException"
};
public static readonly List<string> FilteredExceptionMessages = new List<string>

View File

@@ -1,42 +0,0 @@
using FluentValidation;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.Tv;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.AutoTagging.Specifications
{
public class YearSpecificationValidator : AbstractValidator<YearSpecification>
{
public YearSpecificationValidator()
{
RuleFor(c => c.Min).NotEmpty();
RuleFor(c => c.Min).GreaterThan(0);
RuleFor(c => c.Max).NotEmpty();
RuleFor(c => c.Max).GreaterThan(c => c.Min);
}
}
public class YearSpecification : AutoTaggingSpecificationBase
{
private static readonly YearSpecificationValidator Validator = new ();
public override int Order => 1;
public override string ImplementationName => "Year";
[FieldDefinition(1, Label = "Minimum Year", Type = FieldType.Number)]
public int Min { get; set; }
[FieldDefinition(2, Label = "Maximum Year", Type = FieldType.Number)]
public int Max { get; set; }
protected override bool IsSatisfiedByWithoutNegate(Series series)
{
return series.Year >= Min && series.Year <= Max;
}
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}
}
}

View File

@@ -74,10 +74,19 @@ namespace NzbDrone.Core.Download
{
var result = base.Test(definition);
if ((result == null || result.IsValid) && definition.Id != 0)
if (definition.Id == 0)
{
return result;
}
if (result == null || result.IsValid)
{
_downloadClientStatusService.RecordSuccess(definition.Id);
}
else
{
_downloadClientStatusService.RecordFailure(definition.Id);
}
return result;
}

View File

@@ -12,5 +12,10 @@ namespace NzbDrone.Core.Extras.Files
public DateTime Added { get; set; }
public DateTime LastUpdated { get; set; }
public string Extension { get; set; }
public override string ToString()
{
return $"[{Id}] {RelativePath}";
}
}
}

View File

@@ -81,6 +81,8 @@ namespace NzbDrone.Core.Extras.Files
protected TExtraFile MoveFile(Author author, BookFile bookFile, TExtraFile extraFile, string fileNameSuffix = null)
{
_logger.Trace("Renaming extra file: {0}", extraFile);
var newFolder = Path.GetDirectoryName(bookFile.Path);
var filenameBuilder = new StringBuilder(Path.GetFileNameWithoutExtension(bookFile.Path));
@@ -98,9 +100,13 @@ namespace NzbDrone.Core.Extras.Files
{
try
{
_logger.Trace("Renaming extra file: {0} to {1}", extraFile, newFileName);
_diskProvider.MoveFile(existingFileName, newFileName);
extraFile.RelativePath = author.Path.GetRelativePath(newFileName);
_logger.Trace("Renamed extra file from: {0}", extraFile);
return extraFile;
}
catch (Exception ex)

View File

@@ -0,0 +1,45 @@
using System.Linq;
using NzbDrone.Core.Download;
using NzbDrone.Core.Indexers;
using NzbDrone.Core.Localization;
using NzbDrone.Core.ThingiProvider.Events;
namespace NzbDrone.Core.HealthCheck.Checks
{
[CheckOn(typeof(ProviderUpdatedEvent<IIndexer>))]
[CheckOn(typeof(ProviderDeletedEvent<IIndexer>))]
[CheckOn(typeof(ProviderUpdatedEvent<IDownloadClient>))]
[CheckOn(typeof(ProviderDeletedEvent<IDownloadClient>))]
public class IndexerDownloadClientCheck : HealthCheckBase
{
private readonly IIndexerFactory _indexerFactory;
private readonly IDownloadClientFactory _downloadClientFactory;
public IndexerDownloadClientCheck(IIndexerFactory indexerFactory,
IDownloadClientFactory downloadClientFactory,
ILocalizationService localizationService)
: base(localizationService)
{
_indexerFactory = indexerFactory;
_downloadClientFactory = downloadClientFactory;
}
public override HealthCheck Check()
{
var downloadClientsIds = _downloadClientFactory.All().Where(v => v.Enable).Select(v => v.Id).ToList();
var invalidIndexers = _indexerFactory.All()
.Where(v => v.Enable && v.DownloadClientId > 0 && !downloadClientsIds.Contains(v.DownloadClientId))
.ToList();
if (invalidIndexers.Any())
{
return new HealthCheck(GetType(),
HealthCheckResult.Warning,
string.Format(_localizationService.GetLocalizedString("IndexerDownloadClientHealthCheckMessage"), string.Join(", ", invalidIndexers.Select(v => v.Name).ToArray())),
"#invalid-indexer-download-client-setting");
}
return new HealthCheck(GetType());
}
}
}

View File

@@ -75,10 +75,19 @@ namespace NzbDrone.Core.ImportLists
{
var result = base.Test(definition);
if ((result == null || result.IsValid) && definition.Id != 0)
if (definition.Id == 0)
{
return result;
}
if (result == null || result.IsValid)
{
_importListStatusService.RecordSuccess(definition.Id);
}
else
{
_importListStatusService.RecordFailure(definition.Id);
}
return result;
}

View File

@@ -441,7 +441,6 @@
"SslPortHelpTextWarning": "يتطلب إعادة التشغيل ليصبح ساري المفعول",
"DownloadClientCheckDownloadingToRoot": "يقوم برنامج التنزيل {0} بوضع التنزيلات في المجلد الجذر {1}. يجب ألا تقوم بالتنزيل إلى مجلد جذر.",
"Progress": "التقدم",
"UI": "واجهة المستخدم",
"ReplaceIllegalCharactersHelpText": "استبدل الأحرف غير القانونية. إذا لم يتم تحديده ، فسوف يقوم Radarr بإزالتها بدلاً من ذلك",
"ReleaseTitle": "عنوان الإصدار",
"Actions": "أجراءات",

View File

@@ -441,7 +441,6 @@
"SslCertPathHelpTextWarning": "Изисква рестартиране, за да влезе в сила",
"DownloadClientCheckDownloadingToRoot": "Клиентът за изтегляне {0} поставя изтеглянията в основната папка {1}. Не трябва да изтегляте в основна папка.",
"ReplaceIllegalCharactersHelpText": "Заменете незаконните символи. Ако не е отметнато, Radarr ще ги премахне вместо това",
"UI": "Потребителски интерфейс",
"Actions": "Действия",
"Tomorrow": "Утре",
"Today": "Днес",

View File

@@ -299,7 +299,6 @@
"StartupDirectory": "Directori d'inici",
"Test": "Prova",
"ThisCannotBeCancelled": "No es pot cancel·lar un cop iniciat sense desactivar tots els vostres indexadors.",
"UI": "Interfície",
"UISettings": "Configuració de la interfície",
"UISettingsSummary": "Opcions de calendari, data i color alternats",
"UnableToAddANewDownloadClientPleaseTryAgain": "No es pot afegir un nou client de descàrrega, torneu-ho a provar.",

View File

@@ -440,7 +440,6 @@
"Year": "Rok",
"YesCancel": "Ano, zrušit",
"DownloadClientCheckDownloadingToRoot": "Stahovací klient {0} umístí stažené soubory do kořenové složky {1}. Neměli byste stahovat do kořenové složky.",
"UI": "UI",
"ReplaceIllegalCharactersHelpText": "Nahraďte nepovolené znaky. Pokud není zaškrtnuto, radarr je místo toho odstraní",
"OutputPath": "Výstupní cesta",
"Actions": "Akce",

View File

@@ -443,7 +443,6 @@
"ReplaceIllegalCharactersHelpText": "Udskift ulovlige tegn. Hvis det ikke er markeret, fjerner Radarr dem i stedet",
"ReleaseTitle": "Udgiv titel",
"Actions": "Handlinger",
"UI": "UI",
"Tomorrow": "I morgen",
"Today": "I dag",
"Progress": "Fremskridt",

View File

@@ -489,7 +489,6 @@
"PortHelpText": "Calibre-Content-Server",
"Progress": "Fortschritt",
"ReleaseTitle": "Release Titel",
"UI": "Oberfläche",
"Actions": "Aktionen",
"Today": "Heute",
"Tomorrow": "Morgen",

View File

@@ -441,7 +441,6 @@
"UnableToLoadMetadataProfiles": "Δεν είναι δυνατή η φόρτωση των Καθυστέρησης προφίλ",
"DownloadClientCheckDownloadingToRoot": "Λήψη προγράμματος-πελάτη {0} τοποθετεί λήψεις στον ριζικό φάκελο {1}. Δεν πρέπει να κάνετε λήψη σε έναν ριζικό φάκελο.",
"ReplaceIllegalCharactersHelpText": "Αντικαταστήστε τους παράνομους χαρακτήρες. Εάν δεν είναι επιλεγμένο, το Radarr θα τα καταργήσει",
"UI": "Διεπαφή χρήστη",
"Tomorrow": "Αύριο",
"Today": "Σήμερα",
"Actions": "Ενέργειες",

View File

@@ -6,10 +6,12 @@
"ASIN": "ASIN",
"About": "About",
"Actions": "Actions",
"Activity": "Activity",
"AddImportListExclusionHelpText": "Prevent book from being added to Readarr by Import Lists or Author Refresh",
"AddList": "Add List",
"AddListExclusion": "Add List Exclusion",
"AddMissing": "Add missing",
"AddNew": "Add New",
"AddNewItem": "Add New Item",
"AddedAuthorSettings": "Added Author Settings",
"AddingTag": "Adding tag",
@@ -61,6 +63,7 @@
"Automatic": "Automatic",
"AutomaticAdd": "Automatic Add",
"AutomaticallySwitchEdition": "Automatically Switch Edition",
"Backup": "Backup",
"BackupFolderHelpText": "Relative paths will be under Readarr's AppData directory",
"BackupIntervalHelpText": "Interval to backup the Readarr DB and settings",
"BackupNow": "Backup Now",
@@ -89,6 +92,7 @@
"BookTitle": "Book Title",
"Books": "Books",
"BooksTotal": "Books ({0})",
"Bookshelf": "Bookshelf",
"Branch": "Branch",
"BypassIfAboveCustomFormatScore": "Bypass if Above Custom Format Score",
"BypassIfAboveCustomFormatScoreHelpText": "Enable bypass when release has a score higher than the configured minimum custom format score",
@@ -296,6 +300,7 @@
"EntityName": "Entity Name",
"ErrorLoadingContents": "Error loading contents",
"ErrorLoadingPreviews": "Error loading previews",
"Events": "Events",
"Exception": "Exception",
"ExistingBooks": "Existing Books",
"ExistingItems": "Existing Items",
@@ -331,6 +336,7 @@
"ForeignId": "Foreign ID",
"ForeignIdHelpText": "The Musicbrainz Id of the author/book to exclude",
"Formats": "Formats",
"FreeSpace": "Free Space",
"FutureBooks": "Future Books",
"FutureDays": "Future Days",
"FutureDaysHelpText": "Days for iCal feed to look into the future",
@@ -392,6 +398,7 @@
"IncludeUnknownAuthorItemsHelpText": "Show items without a author in the queue, this could include removed authors, books or anything else in Readarr's category",
"IncludeUnmonitored": "Include Unmonitored",
"Indexer": "Indexer",
"IndexerDownloadClientHealthCheckMessage": "Indexers with invalid download clients: {0}.",
"IndexerDownloadClientHelpText": "Specify which download client is used for grabs from this indexer",
"IndexerIdHelpText": "Specify what indexer the profile applies to",
"IndexerIdHelpTextWarning": "Using a specific indexer with preferred words can lead to duplicate releases being grabbed",
@@ -430,9 +437,14 @@
"ItsEasyToAddANewAuthorOrBookJustStartTypingTheNameOfTheItemYouWantToAdd": "It's easy to add a New Author or Book just start typing the name of the item you want to add",
"Label": "Label",
"Language": "Language",
"Large": "Large",
"LastDuration": "Last Duration",
"LastExecution": "Last Execution",
"LastWriteTime": "Last Write Time",
"LatestBook": "Latest Book",
"LaunchBrowserHelpText": " Open a web browser and navigate to Readarr homepage on app start.",
"Level": "Level",
"Library": "Library",
"LibraryHelpText": "Calibre content server library name. Leave blank for default.",
"ListRefreshInterval": "List Refresh Interval",
"ListWillRefreshEveryInterp": "List will refresh every {0}",
@@ -443,6 +455,7 @@
"LoadingBooksFailed": "Loading books failed",
"LoadingEditionsFailed": "Loading editions failed",
"Local": "Local",
"Location": "Location",
"LogFiles": "Log Files",
"LogLevel": "Log Level",
"LogLevelvalueTraceTraceLoggingShouldOnlyBeEnabledTemporarily": "Trace logging should only be enabled temporarily",
@@ -475,6 +488,7 @@
"MediaManagement": "Media Management",
"MediaManagementSettings": "Media Management Settings",
"MediaManagementSettingsSummary": "Naming, file management settings and root folders",
"Medium": "Medium",
"Message": "Message",
"Metadata": "Metadata",
"MetadataConsumers": "Metadata Consumers",
@@ -540,6 +554,7 @@
"Negated": "Negated",
"New": "New",
"NewBooks": "New Books",
"NextExecution": "Next Execution",
"No": "No",
"NoBackupsAreAvailable": "No backups are available",
"NoChange": "No Change",
@@ -827,6 +842,7 @@
"SkipRedownload": "Skip Redownload",
"SkipRedownloadHelpText": "Prevents Readarr from trying download alternative releases for the removed items",
"SkipSecondarySeriesBooks": "Skip secondary series books",
"Small": "Small",
"SmartReplace": "Smart Replace",
"SorryThatAuthorCannotBeFound": "Sorry, that author cannot be found.",
"SorryThatBookCannotBeFound": "Sorry, that book cannot be found.",
@@ -853,6 +869,7 @@
"SupportsSearchvalueSearchIsNotSupportedWithThisIndexer": "Search is not supported with this indexer",
"SupportsSearchvalueWillBeUsedWhenAutomaticSearchesArePerformedViaTheUIOrByReadarr": "Will be used when automatic searches are performed via the UI or by Readarr",
"SupportsSearchvalueWillBeUsedWhenInteractiveSearchIsUsed": "Will be used when interactive search is used",
"System": "System",
"SystemTimeCheckMessage": "System time is off by more than 1 day. Scheduled tasks may not run correctly until the time is corrected",
"TagIsNotUsedAndCanBeDeleted": "Tag is not used and can be deleted",
"Tags": "Tags",
@@ -885,15 +902,16 @@
"Torrents": "Torrents",
"TotalBookCountBooksTotalBookFileCountBooksWithFilesInterp": "{0} books total. {1} books with files.",
"TotalFileSize": "Total File Size",
"TotalSpace": "Total Space",
"TrackNumber": "Track Number",
"TrackTitle": "Track Title",
"UI": "UI",
"UILanguage": "UI Language",
"UILanguageHelpText": "Language that Readarr will use for UI",
"UILanguageHelpTextWarning": "Browser Reload Required",
"UISettings": "UI Settings",
"UISettingsSummary": "Calendar, date and color impaired options",
"URLBase": "URL Base",
"Ui": "UI",
"UnableToAddANewDownloadClientPleaseTryAgain": "Unable to add a new download client, please try again.",
"UnableToAddANewImportListExclusionPleaseTryAgain": "Unable to add a new import list exclusion, please try again.",
"UnableToAddANewIndexerPleaseTryAgain": "Unable to add a new indexer, please try again.",
@@ -931,7 +949,7 @@
"UnableToLoadTheCalendar": "Unable to load the calendar",
"UnableToLoadUISettings": "Unable to load UI settings",
"Ungroup": "Ungroup",
"UnmappedFiles": "UnmappedFiles",
"UnmappedFiles": "Unmapped Files",
"Unmonitored": "Unmonitored",
"UnmonitoredHelpText": "Include unmonitored books in the iCal feed",
"UnselectAll": "Unselect All",

View File

@@ -446,7 +446,6 @@
"Today": "Hoy",
"ReleaseTitle": "Título del Estreno",
"Progress": "Progreso",
"UI": "UI",
"Tomorrow": "mañana",
"OutputPath": "Ruta de Output",
"BookAvailableButMissing": "Película Disponible pero Ausente",

View File

@@ -443,7 +443,6 @@
"ReplaceIllegalCharactersHelpText": "Korvaa laittomat merkit. Jos ei käytössä, laittomat merkit poistetaan.",
"OutputPath": "Tallennussijainti",
"Progress": "Edistyminen",
"UI": "Käyttöliittymä",
"Actions": "Toiminnot",
"ReleaseTitle": "Julkaisun otsikko",
"Today": "Tänään",

View File

@@ -4,7 +4,7 @@
"60MinutesSixty": "60 Minutes: {0}",
"APIKey": "Clé API",
"About": "À propos",
"AddListExclusion": "Ajouter une exclusion de liste",
"AddListExclusion": "Ajouter une liste d'exclusion",
"BindAddressHelpTextWarning": "Nécessite un redémarrage pour prendre effet",
"ApiKeyHelpTextWarning": "Nécessite un redémarrage pour prendre effet",
"Branch": "Branche",
@@ -23,11 +23,11 @@
"SslPortHelpTextWarning": "Nécessite un redémarrage pour prendre effet",
"SslCertPathHelpTextWarning": "Nécessite un redémarrage pour prendre effet",
"UnableToLoadMetadataProfiles": "Impossible de charger les profils de délai",
"AddingTag": "Ajout d'un tag",
"AddingTag": "Ajouter un tag",
"AgeWhenGrabbed": "Age (au moment du téléchargement)",
"AlreadyInYourLibrary": "Déjà présent dans votre collection",
"AlreadyInYourLibrary": "Déjà disponible dans votre librairie",
"AlternateTitles": "Titre alternatif",
"Analytics": "Analytique",
"Analytics": "Statistiques",
"AnalyticsEnabledHelpText": "Envoyer des informations anonymes sur l'utilisation et les erreurs vers les serveurs de Readarr. Cela inclut des informations sur votre navigateur, quelle page de l'interface web Readarr vous utilisez, les rapports d'erreur ainsi que le SE et sa version. Nous utiliserons ces informations pour prioriser les nouvelles fonctionnalités et les corrections de bugs.",
"AnalyticsEnabledHelpTextWarning": "Nécessite un redémarrage pour prendre effet",
"AppDataDirectory": "Dossier AppData",
@@ -43,7 +43,7 @@
"BackupRetentionHelpText": "Les sauvegardes automatiques plus anciennes que la période de conservation seront automatiquement effacées",
"Backups": "Sauvegardes",
"BindAddress": "Adresse d'attache",
"BindAddressHelpText": "Adresse IPv4 valide, localhost ou '*' pour toutes les interfaces",
"BindAddressHelpText": "Adresse IP valide, localhost ou '*' pour toutes les interfaces",
"BookIsDownloading": "Le livre est en cours de téléchargement",
"BookIsDownloadingInterp": "Le livre est en cours de téléchargement - {0}% {1}",
"BypassProxyForLocalAddresses": "Contourner le proxy pour les adresses locales",
@@ -63,8 +63,8 @@
"Clear": "Effacer",
"ClickToChangeQuality": "Cliquer pour changer la qualité",
"ClientPriority": "Priorité du client",
"CloneIndexer": "Cloner l'indexeur",
"CloneProfile": "Cloner le profil",
"CloneIndexer": "Dupliqué l'indexeur",
"CloneProfile": "Dupliqué le profil",
"Close": "Fermer",
"Columns": "Colonnes",
"CompletedDownloadHandling": "Gestion des téléchargements terminés",
@@ -462,7 +462,6 @@
"ShowReleaseDate": "Afficher la date de sortie",
"ShowTitle": "Afficher le titre",
"TheAuthorFolderAndAllOfItsContentWillBeDeleted": "Le dossier '{0}' et son contenu vont être supprimés.",
"UI": "UI",
"ReplaceIllegalCharactersHelpText": "Remplacer les caractères illégaux. Si non cochée, Readarr les supprimera à la place",
"Level": "Niveau",
"Publisher": "Éditeur",
@@ -473,7 +472,7 @@
"ReleaseBranchCheckOfficialBranchMessage": "La branche {0} n'est pas une branche de version Readarr valide, vous ne recevrez pas de mises à jour",
"Time": "Heure",
"Blocklist": "Liste noire",
"BlocklistRelease": "Mettre cette release sur la liste noire",
"BlocklistRelease": "Version sur liste noire",
"RescanAfterRefreshHelpText": "Réanalyser le dossier de l'auteur après avoir actualisé l'auteur",
"ShowUnknownAuthorItems": "Afficher les éléments avec auteur inconnu",
"SelectAll": "Tout sélectionner",
@@ -484,7 +483,7 @@
"All": "Tout",
"Wanted": "Recherché",
"CreateEmptyAuthorFolders": "Créer des dossiers auteurs vides",
"AppDataLocationHealthCheckMessage": "La mise à jour ne sera pas possible pour empêcher la suppression de AppData lors de la mise à jour",
"AppDataLocationHealthCheckMessage": "La mise à jour ne sera pas possible afin empêcher la suppression de AppData lors de la mise à jour",
"IndexerPriorityHelpText": "Priorité de l'indexeur de 1 (la plus élevée) à 50 (la plus basse). Par défaut : 25. Utilisé pour départager les versions lors des téléchargements. Readarr continuera d'utiliser tous les indexeurs activés pour les synchro RSS et les recherches.",
"Duration": "Durée",
"RemotePathMappingCheckBadDockerPath": "Vous utilisez docker ; le client de téléchargement {0} enregistre les téléchargements dans {1} mais ce n'est pas un chemin valide. Vérifiez vos paramètres de dossier distant et les paramètres de votre client de téléchargement.",
@@ -664,7 +663,7 @@
"MetadataProfile": "profil de métadonnées",
"StatusEndedContinuing": "Continuant",
"Database": "Base de données",
"ApplicationUrlHelpText": "URL externe de cette application, y compris http(s)://, le port et l'URL de base",
"ApplicationUrlHelpText": "URL externe de cette application, y compris http(s)://, le port ainsi que la base de URL",
"ApplicationURL": "URL de l'application",
"ImportListExclusions": "Supprimer les exclusions de liste d'imports",
"ChooseImportMethod": "Choisir une méthode d'importation",
@@ -681,7 +680,7 @@
"Theme": "Thème",
"ThemeHelpText": "Changez le thème de l'interface de l'application. Le thème \"Auto\" utilisera celui de votre système d'exploitation pour définir le mode clair ou foncé. Inspiré par Theme.Park",
"EnableRssHelpText": "Sera utilisé lorsque Readarr recherche périodiquement des sorties via la synchronisation RSS",
"CloneCustomFormat": "Cloner le format personnalisé",
"CloneCustomFormat": "Dupliqué le format personnalisé",
"Conditions": "Conditions",
"CopyToClipboard": "Copier dans le presse-papier",
"CustomFormat": "Format Personnalisé",
@@ -735,7 +734,7 @@
"ResetQualityDefinitions": "Réinitialiser les définitions de qualité",
"ResetQualityDefinitionsMessageText": "Êtes-vous sûr de vouloir réinitialiser les définitions de qualité ?",
"ApplyTagsHelpTextHowToApplyAuthors": "Comment appliquer des étiquettes aux indexeurs sélectionnés",
"ApplyTagsHelpTextRemove": "Retirer : Retire les étiquettes renseignées",
"ApplyTagsHelpTextRemove": "Suprimer : Suprime les étiquettes renseignées",
"AutomaticAdd": "Ajout automatique",
"BlocklistReleaseHelpText": "Empêche Lidarr de récupérer automatiquement cette version",
"NoChange": "Pas de changement",
@@ -747,9 +746,9 @@
"RemoveFailed": "Echec de la suppression",
"ApplyTagsHelpTextHowToApplyDownloadClients": "Comment appliquer des tags au film sélectionné",
"ApplyChanges": "Appliquer les modifications",
"ApplyTagsHelpTextAdd": "Ajouter : Ajouter les étiquettes à la liste des étiquettes existantes",
"ApplyTagsHelpTextAdd": "Ajouter : Ajouter les tags à la liste de tags existantes",
"ApplyTagsHelpTextHowToApplyImportLists": "Comment appliquer des tags au film sélectionné",
"ApplyTagsHelpTextHowToApplyIndexers": "Comment appliquer des étiquettes aux indexeurs sélectionnés",
"ApplyTagsHelpTextHowToApplyIndexers": "Comment appliquer des tags aux indexeurs sélectionnés",
"ApplyTagsHelpTextReplace": "Remplacer : Remplace les tags par les tags renseignés (ne pas renseigner de tags pour effacer tous les tags)",
"CountIndexersSelected": "{0} indexeur(s) sélectionné(s)",
"DeleteSelectedDownloadClients": "Supprimer le client de téléchargement",
@@ -761,5 +760,8 @@
"ExistingTag": "Tag existant",
"No": "Non",
"RemovingTag": "Suppression du tag",
"SetTags": "Définir Tags"
"SetTags": "Définir Tags",
"CountDownloadClientsSelected": "{0} 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"
}

View File

@@ -155,7 +155,7 @@
"IncludeHealthWarningsHelpText": "כלול אזהרות בריאות",
"IncludeUnknownAuthorItemsHelpText": "הצג פריטים ללא סרט בתור. זה יכול לכלול סרטים שהוסרו או כל דבר אחר בקטגוריה של Radarr",
"IncludeUnmonitored": "כלול ללא פיקוח",
"Indexer": "מַפתְחָן",
"Indexer": "אינדקסר",
"IndexerSettings": "הגדרות אינדקס",
"Indexers": "אינדקסים",
"Interval": "הַפסָקָה",
@@ -440,7 +440,6 @@
"SslCertPasswordHelpTextWarning": "נדרש הפעלה מחדש כדי להיכנס לתוקף",
"UnableToLoadMetadataProfiles": "לא ניתן לטעון פרופילי עיכוב",
"DownloadClientCheckDownloadingToRoot": "הורד לקוח {0} ממקם הורדות בתיקיית הבסיס {1}. אתה לא צריך להוריד לתיקיית שורש.",
"UI": "ממשק משתמש",
"ReleaseTitle": "שחרר את הכותרת",
"NotAvailable": "לא זמין",
"Progress": "התקדמות",

View File

@@ -452,7 +452,6 @@
"ShowReleaseDate": "रिलीज की तारीख दिखाएँ",
"ShowTitle": "शीर्षक दिखाओ",
"Tomorrow": "आने वाला कल",
"UI": "यूआई",
"OutputPath": "उत्पादन के पथ",
"RemoveFromBlocklist": "ब्लैकलिस्ट से निकालें",
"UnableToLoadBlocklist": "ब्लैकलिस्ट लोड करने में असमर्थ",

View File

@@ -53,7 +53,6 @@
"Theme": "Tema",
"Title": "Naslov",
"Torrents": "Torrenti",
"UI": "Korisničko Sučelje",
"URLBase": "URL Base",
"Usenet": "Usenet",
"Analytics": "Analitika",
@@ -155,5 +154,29 @@
"DeleteSelectedIndexersMessageText": "Jeste li sigurni da želite obrisati oznaku formata {0}?",
"RemoveSelectedItemQueueMessageText": "Jeste li sigurni da želite izbrisati stavku {0} iz reda?",
"RemoveSelectedItemsQueueMessageText": "Jeste li sigurni da želite izbrisati stavku {0} iz reda?",
"Required": "Zahtjevaj"
"Required": "Zahtjevaj",
"Options": "Opcije",
"Style": "Stil",
"Today": "Danas",
"UnselectAll": "Odznači sve",
"No": "Ne",
"Restart": "Resetiraj",
"RestartNow": "Resetiraj sad",
"Tomorrow": "Sutra",
"Yes": "Da",
"History": "Povijest",
"Save": "Spremi",
"Security": "Sigurnost",
"SelectAll": "Odaberi sve",
"Source": "Izvor",
"Status": "Status",
"Time": "Vrijeme",
"YesCancel": "Da, otkaži",
"Yesterday": "Jučer",
"Year": "Godina",
"Result": "Rezultat",
"UseProxy": "Koristi proxy",
"RemoveFilter": "Ukloni filter",
"Name": "Ime",
"Version": "Verzija"
}

View File

@@ -657,7 +657,6 @@
"WriteAudioTagsScrub": "Meglévő címkék törlése",
"WriteAudioTags": "Audiófájlok címkézése metaadatokkal",
"AudioFileMetadata": "Metaadatok írása az Audió fájl(ok)ba",
"UI": "Felület",
"Tomorrow": "Holnap",
"Today": "Ma",
"ReleaseTitle": "Kiadás címe",

View File

@@ -453,7 +453,6 @@
"ShowTitle": "Sýna titil",
"Today": "Í dag",
"Tomorrow": "Á morgun",
"UI": "HÍ",
"Level": "Stig",
"RemoveFromBlocklist": "Fjarlægja af svörtum lista",
"UnableToLoadBlocklist": "Ekki er hægt að hlaða svartan lista",

View File

@@ -454,7 +454,6 @@
"TheAuthorFolderAndAllOfItsContentWillBeDeleted": "La cartella del film \"{0}\" e tutto il suo contenuto verranno eliminati.",
"Today": "Oggi",
"Tomorrow": "Domani",
"UI": "Interfaccia",
"CloneIndexer": "Clona Indicizzatore",
"RemoveFromBlocklist": "Rimuovi della blacklist",
"Time": "Ora",
@@ -473,7 +472,7 @@
"ShowUnknownAuthorItems": "Mostra film sconosciuti",
"SelectAll": "Seleziona Tutto",
"SelectedCountBooksSelectedInterp": "{0} Film selezionato(i)",
"ThisCannotBeCancelled": "Questo non può essere annullato una volta avviato senza riavviare Radarr.",
"ThisCannotBeCancelled": "Questo non può essere annullato una volta avviato senza disabilitare tutti i tuoi indexers.",
"UnselectAll": "Deseleziona Tutto",
"UpdateSelected": "Aggiorna i Film Selezionati",
"Wanted": "Ricercato",
@@ -660,7 +659,7 @@
"CustomFormats": "Formati Personalizzati",
"CutoffFormatScoreHelpText": "Una volta raggiunto questo formato personalizzato, Radarr non scaricherà più i film",
"DeleteCustomFormat": "Cancella Formato Personalizzato",
"DeleteCustomFormatMessageText": "Sei sicuro di voler eliminare l'indexer '{0}'?",
"DeleteCustomFormatMessageText": "Sei sicuro di voler eliminare il formato personalizzato '{0}'?",
"DeleteFormatMessageText": "Sei sicuro di voler cancellare il formato etichetta {0} ?",
"ExportCustomFormat": "Esporta formato personalizzato",
"Formats": "Formati",
@@ -686,7 +685,7 @@
"RemoveSelectedItem": "Rimuovi elemento selezionato",
"ApplyTagsHelpTextReplace": "Sostituire: Sostituisce le etichette con quelle inserite (non inserire nessuna etichette per eliminarle tutte)",
"ApplyTagsHelpTextHowToApplyAuthors": "Come applicare etichette agli indicizzatori selezionati",
"CountIndexersSelected": "{0} Indicizzatore(i) Selezionato(i)",
"CountIndexersSelected": "{0} indicizzatore(i) selezionato(i)",
"No": "No",
"NoChange": "Nessuna Modifica",
"RemoveCompleted": "Rimuovi completati",
@@ -705,8 +704,8 @@
"ApplyTagsHelpTextHowToApplyIndexers": "Come applicare etichette agli indicizzatori selezionati",
"ApplyTagsHelpTextRemove": "Rimuovi: Rimuove le etichette inserite",
"BlocklistReleaseHelpText": "Impedisci a Lidarr di re-acquisire automaticamente questa versione",
"DeleteRemotePathMapping": "Modifica la Mappatura dei Percorsi Remoti",
"DeleteSelectedDownloadClients": "Cancella il Client di Download",
"DeleteRemotePathMapping": "Elimina la Mappatura dei Percorsi Remoti",
"DeleteSelectedDownloadClients": "Cancella i Client di Download",
"DeleteSelectedDownloadClientsMessageText": "Sei sicuro di voler eliminare l'indexer '{0}'?",
"DeleteSelectedImportLists": "Cancella la lista di importazione",
"DeleteSelectedImportListsMessageText": "Sei sicuro di voler eliminare l'indexer '{0}'?",

View File

@@ -440,7 +440,6 @@
"Year": "年",
"YesCancel": "はい、キャンセル",
"DownloadClientCheckDownloadingToRoot": "ダウンロードクライアント{0}は、ダウンロードをルートフォルダ{1}に配置します。ルートフォルダにダウンロードしないでください。",
"UI": "UI",
"Tomorrow": "明日",
"Today": "今日",
"Actions": "行動",

View File

@@ -443,7 +443,6 @@
"ReplaceIllegalCharactersHelpText": "잘못된 문자를 바꿉니다. 선택하지 않으면 Radarr가 대신 제거합니다.",
"ReleaseTitle": "릴리스 제목",
"Actions": "행위",
"UI": "UI",
"Tomorrow": "내일",
"Today": "오늘",
"Progress": "진행",

View File

@@ -119,7 +119,6 @@
"SettingsRemotePathMappingLocalPath": "Lokal sti",
"Title": "Tittel",
"Torrents": "Torrents",
"UI": "Grensesnitt",
"UpdateMechanismHelpText": "Bruk Prowlarrs innebygde oppdaterer eller et skript",
"URLBase": "URL Base",
"Username": "Brukernavn",
@@ -147,5 +146,7 @@
"AddMissing": "Legg til manglende",
"AddNewItem": "Legg til nytt item",
"45MinutesFourtyFive": "45 Minutter: {0}",
"60MinutesSixty": "60 Minutter: {0}"
"60MinutesSixty": "60 Minutter: {0}",
"ApplyChanges": "Bekreft endringer",
"ApiKeyValidationHealthCheckMessage": "Vennligst oppdater din API-nøkkel til å være minst {0} tegn lang. Du kan gjøre dette via innstillinger eller konfigurasjonsfilen"
}

View File

@@ -17,14 +17,14 @@
"APIKey": "API-sleutel",
"About": "Over",
"AddListExclusion": "Toevoegen aan Uitzonderingenlijst",
"AddingTag": "Tag toevoegen",
"AddingTag": "Tag wordt toegevoegd",
"AgeWhenGrabbed": "Leeftijd (op moment van ophalen)",
"AlreadyInYourLibrary": "Reeds in uw 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.",
"AppDataDirectory": "AppData map",
"ApplyTags": "Tags Toepassen",
"AppDataDirectory": "AppData folder",
"ApplyTags": "Pas Tags Toe",
"Authentication": "Authenticatie",
"AuthenticationMethodHelpText": "Gebruikersnaam en wachtwoord nodig voor toegang tot Radarr",
"AuthorClickToChangeBook": "Klik om film te wijzigen",
@@ -32,7 +32,7 @@
"AutoUnmonitorPreviouslyDownloadedBooksHelpText": "Verwijderde films zullen automatisch als onbewaakt worden gemarkeerd in Radarr",
"Automatic": "Automatisch",
"BackupFolderHelpText": "Relatieve paden zullen t.o.v. de Radarr AppData map bekeken worden",
"BackupNow": "Veiligheidskopie Maken",
"BackupNow": "Nu backup nemen",
"BackupRetentionHelpText": "Automatische veiligheidskopieën ouder dan de retentie periode zullen worden opgeruimd",
"Backups": "Veiligheidskopieën",
"BindAddress": "Gebonden Adres",
@@ -55,7 +55,7 @@
"ChmodFolderHelpTextWarning": "Dit werkt alleen als de gebruiker die Radarr draait de eigenaar is van het bestand. Het is beter om zeker te zijn dat de downloader de juiste rechten zet.",
"ChownGroupHelpText": "Groep naam of gid. Gebruik gid voor externe bestandssystemen.",
"ChownGroupHelpTextWarning": "Dit werkt alleen als de gebruiker die Radarr draait de eigenaar is van het bestand. Het is beter om zeker te zijn dat de downloader dezelfde groep gebruikt als Radarr.",
"Clear": "Wissen",
"Clear": "Wis",
"ClickToChangeQuality": "Klik om kwaliteit te wijzigen",
"ClientPriority": "Client Prioriteit",
"CloneIndexer": "Dupliceer Indexeerder",
@@ -76,8 +76,8 @@
"DelayProfile": "Vertragingsprofiel",
"DelayProfiles": "Vertragingsprofielen",
"DelayingDownloadUntilInterp": "Vertraag download tot {0} op {1}",
"Delete": "Verwijderen",
"DeleteBackup": "Verwijder Veiligheidskopie",
"Delete": "Verwijder",
"DeleteBackup": "Verwijder Backup",
"DeleteBackupMessageText": "Bent u zeker dat u de veiligheidskopie '{0}' wilt verwijderen?",
"DeleteDelayProfile": "Verwijder Vertragingsprofiel",
"DeleteDelayProfileMessageText": "Weet u zeker dat u dit vertragingsprofiel wilt verwijderen?",
@@ -442,7 +442,6 @@
"DownloadClientCheckDownloadingToRoot": "Downloadclient {0} plaatst downloads in de hoofdmap {1}. U mag niet naar een hoofdmap downloaden.",
"MaintenanceRelease": "Onderhoudsuitgave",
"Actions": "Acties",
"UI": "Gebruikersinterface",
"Tomorrow": "Morgen",
"ReplaceIllegalCharactersHelpText": "Vervang illegale karakters. Indien niet aangevinkt, zal Radarr ze in de plaats daarvan verwijderen",
"Progress": "Voortgang",
@@ -458,8 +457,8 @@
"ShowBookTitleHelpText": "Toon filmtitel onder poster",
"Blocklist": "Blokkeerlijst",
"BlocklistRelease": "Uitgave op blokkeerlijst zetten",
"All": "Alles",
"Component": "Onderdeel",
"All": "Alle",
"Component": "Component",
"ConsoleLogLevel": "Console-logboekniveau",
"DeleteBookFileMessageText": "Weet u zeker dat u {0} wilt verwijderen?",
"FilterAnalyticsEvents": "Analytics-gebeurtenissen filteren",
@@ -637,5 +636,15 @@
"ThereWasAnErrorLoadingThisPage": "Er ging iets fout bij het laden van deze pagina",
"ApiKeyValidationHealthCheckMessage": "Maak je API sleutel alsjeblieft minimaal {0} karakters lang. Dit kan gedaan worden via de instellingen of het configuratiebestand",
"ResetDefinitions": "Reset definities",
"ResetTitles": "Reset titels"
"ResetTitles": "Reset titels",
"ApplyTagsHelpTextHowToApplyIndexers": "Hoe tags toepassen op de geselecteerde indexeerders",
"AutomaticAdd": "Automatisch Toevoegen",
"CloneCondition": "Kloon Conditie",
"ApplyTagsHelpTextHowToApplyImportLists": "Hoe tags toepassen op de geselecteerde import lijsten",
"ApplyChanges": "Pas Wijzigingen Toe",
"ApplyTagsHelpTextAdd": "Toevoegen: Voeg de tags toe aan de bestaande tag lijst",
"ApplyTagsHelpTextHowToApplyDownloadClients": "Hoe tags toepassen op de geselecteerde download clients",
"ApplyTagsHelpTextRemove": "Verwijderen: Verwijder de ingevoerde tags",
"ApplyTagsHelpTextReplace": "Vervangen: Vervang de tags met de ingevoerde tags (vul geen tags in om alle tags te wissen)",
"AutoAdd": "Automatisch Toevoegen"
}

View File

@@ -62,7 +62,7 @@
"AnalyticsEnabledHelpText": "Wysyłaj anonimowe informacje o użytkowaniu i błędach do serwerów Radarr. Obejmuje to informacje o Twojej przeglądarce, z których stron Radarr WebUI używasz, raportowanie błędów, a także wersję systemu operacyjnego i środowiska wykonawczego. Wykorzystamy te informacje, aby nadać priorytet funkcjom i poprawkom błędów.",
"AppDataDirectory": "Katalog AppData",
"ApplyTags": "Zastosuj tagi",
"Authentication": "Poświadczenie",
"Authentication": "Autoryzacja",
"AuthenticationMethodHelpText": "Wymagaj nazwy użytkownika i hasła, aby uzyskać dostęp do Radarr",
"AuthorClickToChangeBook": "Kliknij, aby zmienić film",
"AutoRedownloadFailedHelpText": "Automatycznie wyszukuj i próbuj pobrać inną wersję",
@@ -452,7 +452,6 @@
"ShowTitle": "Pokaż Tytuł",
"Today": "Dzisiaj",
"Tomorrow": "Jutro",
"UI": "UI",
"ShowBookTitleHelpText": "Pokaż tytuł filmu pod plakatem",
"Time": "Czas",
"UnableToLoadBlocklist": "Nie można załadować listy blokowania",
@@ -468,7 +467,7 @@
"Level": "Poziom",
"Wanted": "Chciał",
"Blocklist": "Czarna lista",
"BlocklistRelease": "Wydanie czarnej listy",
"BlocklistRelease": "Dodaj wersję do czarnej listy",
"AppDataLocationHealthCheckMessage": "Aktualizacja nie będzie możliwa w celu uniknięcia usunięcia danych aplikacji",
"SearchFiltered": "Szukaj przefiltrowane",
"Disabled": "Wyłączone",
@@ -574,7 +573,7 @@
"ImportListExclusions": "Usuń wykluczenie listy importu",
"ManualImportSelectEdition": "Import ręczny - wybierz film",
"ApplicationURL": "Link do aplikacji",
"ApplicationUrlHelpText": "Zewnętrzny URL tej aplikacji zawiera http(s)://, port i adres URL",
"ApplicationUrlHelpText": "Zewnętrzny URL tej aplikacji zawierający http(s)://, port i adres URL",
"Database": "Baza danych",
"ChooseImportMethod": "Wybierz tryb importu",
"ClickToChangeReleaseGroup": "Kliknij, by zmienić grupę wydającą",
@@ -616,7 +615,7 @@
"ReplaceWithSpaceDashSpace": "Zastąp spacją Dash Space",
"DeleteRemotePathMapping": "Edytuj zdalne mapowanie ścieżki",
"DeleteRemotePathMappingMessageText": "Czy na pewno chcesz usunąć to mapowanie zdalnej ścieżki?",
"BlocklistReleases": "Wydanie czarnej listy",
"BlocklistReleases": "Dodaj wersje do czarnej listy",
"DeleteConditionMessageText": "Czy na pewno chcesz usunąć tag „{0}”?",
"Negated": "Zanegowane",
"RemoveSelectedItem": "Usuń wybrane",
@@ -637,9 +636,9 @@
"RemovingTag": "Usuwanie tagu",
"SetTags": "Ustaw tagi",
"ApplyTagsHelpTextAdd": "Dodaj: dodaj tagi do istniejącej listy tagów",
"ApplyTagsHelpTextHowToApplyDownloadClients": "Jak zastosować tagi do wybranych filmów",
"ApplyTagsHelpTextHowToApplyImportLists": "Jak zastosować tagi do wybranych filmów",
"ApplyTagsHelpTextHowToApplyIndexers": "Jak zastosować tagi do wybranych filmów",
"ApplyTagsHelpTextHowToApplyDownloadClients": "Jak",
"ApplyTagsHelpTextHowToApplyImportLists": "Jak zastosować tagi do wybranych list",
"ApplyTagsHelpTextHowToApplyIndexers": "Jak zastosować tagi do wybranych indeksatorów",
"ApplyTagsHelpTextRemove": "Usuń: usuń wprowadzone tagi",
"RedownloadFailed": "Pobieranie nie udane",
"DeleteSelectedDownloadClients": "Usuń klienta pobierania",
@@ -649,5 +648,7 @@
"NoChange": "Bez zmiany",
"RemoveCompleted": "Usuń zakończone",
"RemoveFailed": "Usuń nieudane",
"Yes": "tak"
"Yes": "tak",
"ApplyChanges": "Zastosuj zmiany",
"ApiKeyValidationHealthCheckMessage": "Zaktualizuj swój klucz API aby był długi na co najmniej {0} znaków. Możesz to zrobić poprzez ustawienia lub plik konfiguracyjny"
}

View File

@@ -654,7 +654,6 @@
"Progress": "Progresso",
"UnableToLoadMetadataProviderSettings": "Não foi possível carregar as definições do fornecedor de metadados",
"Today": "Hoje",
"UI": "IU",
"Tomorrow": "Amanhã",
"UnmappedFiles": "Ficheiros não mapeados",
"UpdateCovers": "Atualizar capas",

View File

@@ -17,23 +17,23 @@
"AgeWhenGrabbed": "Tempo de vida (quando obtido)",
"ApiKeyHelpTextWarning": "Requer reinício para ter efeito",
"LoadingBooksFailed": "Falha ao carregar livros",
"Logs": "Logs",
"MustContain": "Deve conter",
"ProxyPasswordHelpText": "Você só precisa inserir um nome de usuário e uma senha se solicitado. Caso contrário, deixe em branco.",
"Logs": "Registros",
"MustContain": "Deve Conter",
"ProxyPasswordHelpText": "Você só precisa digitar um nome de usuário e senha se for necessário. Caso contrário, deixe-os em branco.",
"SslCertPathHelpTextWarning": "Requer reinício para ter efeito",
"UnableToLoadMetadataProfiles": "Não foi possível carregar os perfis de metadados",
"AddListExclusion": "Adicionar exclusão à lista",
"AddingTag": "Adicionar tag",
"AlreadyInYourLibrary": "Já está na sua biblioteca",
"AlternateTitles": "Títulos alternativos",
"Analytics": "Análises",
"Analytics": "Analítica",
"AnalyticsEnabledHelpText": "Envie informações anônimas de uso e erro para os servidores do Readarr. Isso inclui informações sobre seu navegador, quais páginas da interface Web do Readarr você usa, relatórios de erros, e a versão do sistema operacional e do tempo de execução. Usaremos essas informações para priorizar recursos e correções de bugs.",
"AppDataDirectory": "Diretório AppData",
"ApplyTags": "Aplicar Tags",
"Authentication": "Autenticação",
"AuthenticationMethodHelpText": "Exigir nome de usuário e senha para acessar o Readarr",
"AuthorClickToChangeBook": "Clique para alterar o livro",
"AutoRedownloadFailedHelpText": "Procure automaticamente e tente fazer o download de uma versão diferente",
"AutoRedownloadFailedHelpText": "Procurar automaticamente e tente baixar uma versão diferente",
"AutoUnmonitorPreviouslyDownloadedBooksHelpText": "Livros excluídos do disco deixam de ser monitorados no Readarr automaticamente",
"Automatic": "Automático",
"BackupFolderHelpText": "Os caminhos relativos estarão no diretório AppData do Readarr",
@@ -46,8 +46,8 @@
"BookIsDownloading": "O livro está baixando",
"DiskSpace": "Espaço em Disco",
"Docker": "Docker",
"DownloadClient": "Cliente de download",
"DownloadClientSettings": "Configurações do cliente de download",
"DownloadClient": "Cliente de Download",
"DownloadClientSettings": "Configurações do Cliente de Download",
"DownloadClients": "Clientes de download",
"DownloadFailedCheckDownloadClientForMoreDetails": "Falha no download: verifique o cliente de download para saber mais",
"DownloadFailedInterp": "Falha no download: {0}",
@@ -65,35 +65,35 @@
"HasPendingChangesSaveChanges": "Salvar alterações",
"History": "Histórico",
"Host": "Host",
"Hostname": "Nome do host",
"Hostname": "Hostname",
"ICalFeed": "Feed do iCal",
"ICalHttpUrlHelpText": "Copie este URL em seu(s) cliente(s) ou clique para se inscrever se o seu navegador é compatível com webcal",
"ICalLink": "Link do iCal",
"BookIsDownloadingInterp": "O livro está baixando - {0}% {1}",
"Branch": "Ramo",
"Branch": "Ramificação",
"BypassProxyForLocalAddresses": "Ignorar proxy para endereços locais",
"Calendar": "Calendário",
"CalendarWeekColumnHeaderHelpText": "Mostrar acima de cada coluna quando a semana está na exibição ativa",
"Cancel": "Cancelar",
"CancelMessageText": "Tem certeza que deseja cancelar esta tarefa pendente?",
"CertificateValidation": "Validação do Certificado",
"CertificateValidationHelpText": "Mudar o quão rigorosa é a validação de certificação HTTPS. Não mude a menos que você entenda os riscos.",
"ChangeFileDate": "Mudar Data do Arquivo",
"CertificateValidation": "Validação de Certificado",
"CertificateValidationHelpText": "Altere a rigidez da validação da certificação HTTPS. Não mude a menos que você entenda os riscos.",
"ChangeFileDate": "Alterar Data do Arquivo",
"ChangeHasNotBeenSavedYet": "Mudar o que não foi salvo ainda",
"ChmodFolder": "Pasta chmod",
"ChmodFolderHelpText": "Octal, aplicado durante a importação/renomeação a pastas e arquivos de mídia (sem executar bits)",
"ChmodFolder": "chmod Pasta",
"ChmodFolderHelpText": "Octal, aplicado durante a importação/renomeação de pastas e arquivos de mídia (sem bits de execução)",
"ChmodFolderHelpTextWarning": "Isso só funciona se o usuário que está executando o Readarr for o proprietário do arquivo. É melhor garantir que o cliente de download defina as permissões corretamente.",
"ChownGroupHelpText": "Nome ou ID do grupo. Use a ID para sistemas de arquivos remotos.",
"ChownGroupHelpText": "Nome do grupo ou gid. Use gid para sistemas de arquivos remotos.",
"ChownGroupHelpTextWarning": "Isso só funciona se o usuário que está executando o Readarr for o proprietário do arquivo. É melhor garantir que o cliente de download use o mesmo grupo que o Readarr.",
"Clear": "Limpar",
"ClickToChangeQuality": "Clique para alterar a qualidade",
"ClientPriority": "Prioridade do cliente",
"CloneIndexer": "Clonar indexador",
"CloneProfile": "Clonar perfil",
"ClientPriority": "Prioridade do Cliente",
"CloneIndexer": "Clonar Indexador",
"CloneProfile": "Clonar Perfil",
"Close": "Fechar",
"Columns": "Colunas",
"CompletedDownloadHandling": "Gerenciamento de download concluído",
"ConnectSettings": "Configurações de conexão",
"CompletedDownloadHandling": "Gerenciamento de Downloads Completos",
"ConnectSettings": "Configurações de Conexão",
"Connections": "Conexões",
"CopyUsingHardlinksHelpText": "Os hardlinks permitem que o Readarr importe torrents para a pasta da série sem ocupar espaço extra em disco ou copiar todo o conteúdo do arquivo. Os hardlinks só funcionarão se a origem e o destino estiverem no mesmo volume",
"CopyUsingHardlinksHelpTextWarning": "Ocasionalmente, os bloqueios de arquivo podem impedir a renomeação de arquivos que estão sendo semeados. Você pode desabilitar temporariamente a semeadura e usar a função de renomeação do Readarr como uma solução alternativa.",
@@ -103,43 +103,43 @@
"CutoffUnmet": "Corte não alcançado",
"DBMigration": "Migração de banco de dados",
"Dates": "Datas",
"DelayProfile": "Perfil de atraso",
"DelayProfiles": "Perfis de atraso",
"DelayProfile": "Perfil de Atraso",
"DelayProfiles": "Perfis de Atraso",
"DelayingDownloadUntilInterp": "Atrasando o download até {0} às {1}",
"Delete": "Excluir",
"DeleteBackup": "Excluir Backup",
"DeleteBackupMessageText": "Tem certeza que deseja excluir o backup \"{0}\"?",
"DeleteDelayProfile": "Excluir perfil de atraso",
"DeleteDelayProfile": "Excluir Perfil de Atraso",
"DeleteDelayProfileMessageText": "Tem certeza de que deseja excluir este perfil de atraso?",
"DeleteDownloadClient": "Excluir cliente de download",
"DeleteDownloadClient": "Excluir Cliente de Download",
"DeleteDownloadClientMessageText": "Tem certeza que deseja excluir o cliente de download \"{0}\"?",
"DeleteEmptyFolders": "Excluir pastas vazias",
"DeleteEmptyFoldersHelpText": "Excluir pastas de autor vazias durante a verificação do disco e quando os arquivos de livros forem excluídos",
"DeleteImportListExclusion": "Remover exclusão da lista de importação",
"DeleteImportListExclusion": "Excluir Exclusão da Lista de Importação",
"DeleteImportListExclusionMessageText": "Tem certeza de que deseja excluir esta exclusão da lista de importação?",
"DeleteImportListMessageText": "Tem certeza de que deseja excluir a lista \"{0}\"?",
"DeleteIndexer": "Excluir indexador",
"DeleteIndexer": "Excluir Indexador",
"DeleteIndexerMessageText": "Tem certeza de que deseja excluir o indexador \"{0}\"?",
"DeleteMetadataProfileMessageText": "Tem certeza que deseja excluir o perfil de metadados \"{0}\"?",
"DeleteNotification": "Excluir notificação",
"DeleteNotification": "Excluir Notificação",
"DeleteNotificationMessageText": "Tem certeza de que deseja excluir a notificação \"{0}\"?",
"DeleteQualityProfile": "Excluir perfil de qualidade",
"DeleteQualityProfile": "Excluir Perfil de Qualidade",
"DeleteQualityProfileMessageText": "Tem certeza que deseja excluir o perfil de qualidade \"{0}\"?",
"DeleteReleaseProfile": "Excluir Perfil de Lançamento",
"DeleteReleaseProfileMessageText": "Tem certeza de que deseja excluir este Perfil de Lançamento?",
"DeleteRootFolderMessageText": "Tem certeza de que deseja excluir a pasta raiz \"{0}\"?",
"DeleteRootFolderMessageText": "Tem certeza de que deseja excluir a pasta raiz '{0}'?",
"DeleteSelectedBookFiles": "Excluir arquivos do livro selecionado",
"DeleteSelectedBookFilesMessageText": "Tem certeza de que deseja excluir os arquivos do livro selecionado?",
"DeleteTag": "Excluir tag",
"DeleteTagMessageText": "Tem certeza de que deseja excluir a tag \"{0}\"?",
"DestinationPath": "Caminho de destino",
"DetailedProgressBarHelpText": "Mostrar texto em barra de progresso",
"EnableAutomaticAdd": "Habilitar adição automática",
"EnableAutomaticAdd": "Habilitar Adição Automática",
"EnableAutomaticSearch": "Ativar pesquisa automática",
"EnableColorImpairedMode": "Habilitar modo para daltonismo",
"EnableColorImpairedModeHelpText": "Estilo alterado para permitir que usuários com daltonismo distingam melhor as informações codificadas por cores",
"EnableColorImpairedMode": "Habilitar Modo para Deficientes Visuais",
"EnableColorImpairedModeHelpText": "Estilo alterado para permitir que usuários com deficiência de cor distingam melhor as informações codificadas por cores",
"EnableCompletedDownloadHandlingHelpText": "Importar automaticamente downloads concluídos do cliente de download",
"EnableHelpText": "Habilitar a criação de um arquivo de metadados para este tipo de metadados",
"EnableHelpText": "Habilitar criação de arquivo de metadados para este tipo de metadados",
"EnableInteractiveSearch": "Ativar pesquisa interativa",
"EnableRSS": "Habilitar RSS",
"EnableSSL": "Habilitar SSL",
@@ -152,11 +152,11 @@
"ExtraFileExtensionsHelpTexts2": "Exemplos: \".sub, .nfo\" ou \"sub,nfo\"",
"FailedDownloadHandling": "Falha no gerenciamento de download",
"FileDateHelpText": "Alterar a data do arquivo ao importar/verificar novamente",
"FileManagement": "Gerenciamento de arquivo",
"FileNames": "Nomes dos arquivos",
"FileManagement": "Gerenciamento de Arquivo",
"FileNames": "Nomes de Arquivo",
"Filename": "Nome do arquivo",
"Files": "Arquivos",
"FirstDayOfWeek": "Primeiro dia da semana",
"FirstDayOfWeek": "Primeiro Dia da Semana",
"Fixed": "Corrigido",
"Folder": "Pasta",
"Folders": "Pastas",
@@ -170,11 +170,11 @@
"GrabID": "Obter ID",
"IconForCutoffUnmet": "Ícone para Limite não atingido",
"IconTooltip": "Agendado",
"IgnoredAddresses": "Endereços ignorados",
"IgnoredAddresses": "Endereços Ignorados",
"IgnoredHelpText": "O lançamento será rejeitado se contiver um ou mais desses termos (não diferencia maiúsculas de minúsculas)",
"IgnoredPlaceHolder": "Adicionar nova restrição",
"IllRestartLater": "Reiniciarei mais tarde",
"ImportExtraFiles": "Importar arquivos adicionais",
"ImportExtraFiles": "Importar Arquivos Extras",
"Missing": "Ausente",
"Mode": "Modo",
"ImportExtraFilesHelpText": "Importar arquivos adicionais correspondentes (legendas, nfo, etc.) após importar um arquivo de livro",
@@ -183,10 +183,10 @@
"Importing": "Importando",
"IncludeHealthWarningsHelpText": "Incluir avisos de integridade",
"IncludeUnknownAuthorItemsHelpText": "Mostrar itens sem autor na fila, isso pode incluir autores removidos, livros ou qualquer outra coisa na categoria de Readarr",
"IncludeUnmonitored": "Incluir não monitorados",
"IncludeUnmonitored": "Incluir não monitorado",
"Indexer": "Indexador",
"IndexerPriority": "Prioridade do indexador",
"IndexerSettings": "Configurações do indexador",
"IndexerPriority": "Prioridade do Indexador",
"IndexerSettings": "Configurações do Indexador",
"Indexers": "Indexadores",
"Interval": "Intervalo",
"IsCutoffCutoff": "Limite",
@@ -197,31 +197,31 @@
"LoadingBookFilesFailed": "Falha ao carregar arquivos do livro",
"Local": "Local",
"LogFiles": "Arquivos de registro",
"LogLevel": "Nível do log",
"LogLevel": "Nível de Registro",
"LogLevelvalueTraceTraceLoggingShouldOnlyBeEnabledTemporarily": "O registro de rastreamento deve ser ativado apenas temporariamente",
"Logging": "Registro em log",
"LongDateFormat": "Formato longo da data",
"Logging": "Registrando",
"LongDateFormat": "Formato de Data Longa",
"MIA": "Desaparecidos",
"ManualImport": "Importação manual",
"MarkAsFailed": "Marcar como falhado",
"MarkAsFailedMessageText": "Tem certeza que deseja marcar \"{0}\" como falhado?",
"MaximumLimits": "Limites máximos",
"MaximumSize": "Tamanho máximo",
"MaximumLimits": "Limites Máximos",
"MaximumSize": "Tamanho Máximo",
"MaximumSizeHelpText": "Tamanho máximo para um lançamento a ser obtido, em MB. Digite zero para definir como Ilimitado.",
"Mechanism": "Mecanismo",
"MediaInfo": "Informações da mídia",
"MediaManagementSettings": "Configurações de gerenciamento de mídia",
"MediaManagementSettings": "Configurações de Gerenciamento de Mídia",
"Message": "Mensagem",
"MetadataSettings": "Configurações de metadados",
"MinimumAge": "Tempo de vida mínimo",
"MinimumAgeHelpText": "Somente Usenet: tempo de vida mínimo, em minutos, dos NZBs, para que sejam capturados. Use isto para dar às novas versões tempo de propagar-se em seu fornecedor de Usenet.",
"MinimumFreeSpace": "Mínimo de espaço livre",
"MetadataSettings": "Configurações de Metadados",
"MinimumAge": "Idade Miníma",
"MinimumAgeHelpText": "Somente Usenet: Idade mínima em minutos dos NZBs antes de serem capturados. Use isso para dar aos novos lançamentos tempo para se propagar para seu provedor usenet.",
"MinimumFreeSpace": "Espaço Livre Mínimo",
"MinimumFreeSpaceWhenImportingHelpText": "Impedir a importação se deixar menos do que esta quantidade de espaço em disco disponível",
"MinimumLimits": "Limites mínimos",
"MinimumLimits": "Limites Mínimos",
"MoreInfo": "Mais informações",
"MustNotContain": "Não deve conter",
"MustNotContain": "Não Deve Conter",
"Name": "Nome",
"NamingSettings": "Configurações de nomenclatura",
"NamingSettings": "Configurações de Nomes",
"New": "Novo",
"NoBackupsAreAvailable": "Não há backups disponíveis",
"NoHistory": "Sem histórico.",
@@ -230,8 +230,8 @@
"NoLogFiles": "Nenhum arquivo de log",
"NoMinimumForAnyRuntime": "Sem mínimo para qualquer tempo de execução",
"NoUpdatesAreAvailable": "Nenhuma atualização está disponível",
"None": "Nenhum",
"NotificationTriggers": "Acionadores da notificação",
"None": "Vazio",
"NotificationTriggers": "Gatilhos de Notificação",
"OnGrabHelpText": "Ao obter",
"OnHealthIssueHelpText": "Ao ter problema de integridade",
"OnRenameHelpText": "Ao renomear",
@@ -248,24 +248,24 @@
"Permissions": "Permissões",
"Port": "Porta",
"PortHelpTextWarning": "Requer reinício para ter efeito",
"PortNumber": "Número da porta",
"PortNumber": "Número da Porta",
"PosterSize": "Tamanho do pôster",
"PreviewRename": "Visualizar renomeação",
"Profiles": "Perfis",
"Proper": "Proper",
"PropersAndRepacks": "Propers e repacks",
"Protocol": "Protocolo",
"ProtocolHelpText": "Escolha que protocolo(s) utilizar e qual o preferido ao escolher entre versões iguais",
"ProtocolHelpText": "Escolha qual(is) protocolo(s) usar e qual é o preferido ao escolher entre laçamentos iguais",
"Proxy": "Proxy",
"ProxyBypassFilterHelpText": "Usar \",\" como separador e \"*.\" como curinga para subdomínios",
"ProxyType": "Tipo de proxy",
"ProxyUsernameHelpText": "Você só precisa inserir um nome de usuário e uma senha se solicitado. Caso contrário, deixe em branco.",
"ProxyBypassFilterHelpText": "Use ',' como separador e '*.' como curinga para subdomínios",
"ProxyType": "Tipo de Proxy",
"ProxyUsernameHelpText": "Você só precisa digitar um nome de usuário e senha se for necessário. Caso contrário, deixe-os em branco.",
"PublishedDate": "Data de publicação",
"Quality": "Qualidade",
"QualityDefinitions": "Definições de qualidade",
"QualityDefinitions": "Definições de Qualidade",
"QualityProfile": "Perfil de Qualidade",
"QualityProfiles": "Perfis de qualidade",
"QualitySettings": "Configurações de qualidade",
"QualityProfiles": "Perfis de Qualidade",
"QualitySettings": "Configurações de Qualidade",
"Queue": "Fila",
"RSSSync": "Sincronização RSS",
"RSSSyncInterval": "Intervalo da sincronização RSS",
@@ -278,7 +278,7 @@
"RecycleBinCleanupDaysHelpTextWarning": "Os arquivos na lixeira mais antigos do que o número de dias selecionado serão limpos automaticamente",
"RecycleBinHelpText": "Arquivos de livros vêm para cá quando excluídos, em vez de serem apagados permanentemente",
"RecyclingBin": "Lixeira",
"RecyclingBinCleanup": "Esvaziar lixeira",
"RecyclingBinCleanup": "Esvaziar Lixeira",
"Redownload": "Baixar novamente",
"Refresh": "Atualizar",
"RefreshInformationAndScanDisk": "Atualizar as informações e verificar o disco",
@@ -287,10 +287,10 @@
"ReleaseRejected": "Versão rejeitada",
"ReleaseWillBeProcessedInterp": "A versão será processada {0}",
"Reload": "Recarregar",
"RemotePathMappings": "Mapeamentos de caminho remoto",
"RemotePathMappings": "Mapeamentos de Caminho Remoto",
"Remove": "Remover",
"RemoveCompletedDownloadsHelpText": "Remover downloads importados do histórico do cliente de download",
"RemoveFailedDownloadsHelpText": "Remover downloads com falha do histórico do cliente de download",
"RemoveFailedDownloadsHelpText": "Remova downloads com falha do histórico do cliente de download",
"RemoveFilter": "Remover filtro",
"RemoveFromDownloadClient": "Remover Do Cliente de Download",
"RemoveFromQueue": "Remover da fila",
@@ -300,43 +300,43 @@
"RemoveTagRemovingTag": "Removendo tag",
"RemovedFromTaskQueue": "Removido da fila de tarefas",
"RenameBooksHelpText": "O Readarr usará o nome de arquivo existente se a renomeação estiver desativada",
"Reorder": "Reorganizar",
"ReplaceIllegalCharacters": "Substituir caracteres ilegais",
"Reorder": "Reordenar",
"ReplaceIllegalCharacters": "Substituir Caracteres Ilegais",
"RequiredHelpText": "Essa condição {0} deve corresponder para que o formato personalizado seja aplicado. Caso contrário, uma única partida {0} é suficiente.",
"RequiredPlaceHolder": "Adicionar nova restrição",
"RescanAfterRefreshHelpTextWarning": "O Readarr não detectará automaticamente as alterações nos arquivos se não estiver definido como \"Sempre\"",
"RescanAuthorFolderAfterRefresh": "Reescanear a pasta do autor após a atualização",
"Reset": "Redefinir",
"ResetAPIKey": "Redefinir chave da API",
"ResetAPIKey": "Redefinir chave de API",
"ResetAPIKeyMessageText": "Tem certeza de que deseja redefinir sua chave de API?",
"Restart": "Reiniciar",
"RestartNow": "Reiniciar agora",
"RestartNow": "Reiniciar Agora",
"RestartReadarr": "Reiniciar o Readarr",
"Restore": "Restaurar",
"RestoreBackup": "Restaurar backup",
"Result": "Resultado",
"Retention": "Retenção",
"RetentionHelpText": "Apenas Usenet: use 0 para definir para retenção ilimitada",
"RetentionHelpText": "Somente Usenet: defina como zero para definir a retenção ilimitada",
"RetryingDownloadInterp": "Tentando novamente o download {0} em {1}",
"RootFolder": "Pasta Raiz",
"RootFolders": "Pastas raiz",
"RssSyncIntervalHelpText": "Intervalo em minutos. Defina como zero para desabilitar (isso interromperá todos os downloads automáticos de lançamentos)",
"RootFolders": "Pastas Raiz",
"RssSyncIntervalHelpText": "Intervalo em minutos. Defina como zero para desativar (isso interromperá todas as capturas de lançamentos automáticas)",
"SSLCertPassword": "Senha do certificado SSL",
"SSLCertPath": "Caminho do certificado SSL",
"SSLPort": "Porta SSL",
"Scheduled": "Agendado",
"ScriptPath": "Caminho do script",
"ScriptPath": "Caminho do Script",
"Search": "Pesquisar",
"SearchAll": "Pesquisar tudo",
"SearchForMissing": "Pesquisar ausentes",
"SearchSelected": "Pesquisar selecionado(s)",
"Security": "Segurança",
"SendAnonymousUsageData": "Enviar dados de uso anônimos",
"SetPermissions": "Definir permissões",
"SetPermissions": "Definir Permissões",
"SetPermissionsLinuxHelpText": "O chmod deve ser executado quando os arquivos são importados/renomeados?",
"SetPermissionsLinuxHelpTextWarning": "Se você não tem certeza do que essas configurações fazem, não as altere.",
"SetPermissionsLinuxHelpTextWarning": "Se você não tiver certeza do que essas configurações fazem, não as altere.",
"Settings": "Configurações",
"ShortDateFormat": "Formato curto da data",
"ShortDateFormat": "Formato de Data Curta",
"ShowCutoffUnmetIconHelpText": "Mostrar ícone para arquivos quando o limite não foi atingindo",
"ShowDateAdded": "Mostrar data de adição",
"ShowMonitored": "Mostrar monitorado(s)",
@@ -344,8 +344,8 @@
"ShowPath": "Mostrar caminho",
"ShowQualityProfile": "Mostrar perfil de qualidade",
"ShowQualityProfileHelpText": "Mostrar perfil de qualidade sob o pôster",
"ShowRelativeDates": "Mostrar datas relativas",
"ShowRelativeDatesHelpText": "Mostrar datas absolutas ou relativas (Hoje, Ontem, etc.)",
"ShowRelativeDates": "Mostrar Datas Relativas",
"ShowRelativeDatesHelpText": "Mostrar datas relativas (Hoje/Ontem/etc) ou absolutas",
"ShowSearch": "Mostrar pesquisa",
"ShowSearchActionHelpText": "Mostrar botão de pesquisa ao passar o mouse",
"ShowSizeOnDisk": "Mostrar tamanho no disco",
@@ -372,7 +372,7 @@
"SupportsSearchvalueSearchIsNotSupportedWithThisIndexer": "A pesquisa não é compatível com este indexador",
"SupportsSearchvalueWillBeUsedWhenAutomaticSearchesArePerformedViaTheUIOrByReadarr": "Será usado quando pesquisas automáticas forem realizadas pela interface ou pelo Readarr",
"SupportsSearchvalueWillBeUsedWhenInteractiveSearchIsUsed": "Será usado com a pesquisa interativa",
"TagIsNotUsedAndCanBeDeleted": "A tag não está em uso e pode ser excluída",
"TagIsNotUsedAndCanBeDeleted": "A tag não é usada e pode ser excluída",
"Tags": "Tags",
"Tasks": "Tarefas",
"TestAll": "Testar Tudo",
@@ -380,10 +380,10 @@
"TestAllIndexers": "Testar todos os indexadores",
"TestAllLists": "Testar todas as listas",
"ThisWillApplyToAllIndexersPleaseFollowTheRulesSetForthByThem": "Isso se aplicará a todos os indexadores, siga as regras estabelecidas por eles",
"TimeFormat": "Formato de hora",
"TimeFormat": "Formato da Hora",
"Title": "Título",
"TorrentDelay": "Atraso do torrent",
"TorrentDelayHelpText": "Atraso, em minutos, para aguardar antes de obter um torrent",
"TorrentDelay": "Atraso do Torrent",
"TorrentDelayHelpText": "Demora em minutos para esperar antes de pegar um torrent",
"Torrents": "Torrents",
"TotalFileSize": "Tamanho total do arquivo",
"UILanguage": "Idioma da interface",
@@ -418,23 +418,23 @@
"Unmonitored": "Não monitorado",
"UnmonitoredHelpText": "Incluir livros não monitorados no feed do iCal",
"UpdateAll": "Atualizar tudo",
"UpdateAutomaticallyHelpText": "Baixar e instalar atualizações automaticamente. Você ainda poderá instalar a partir de Sistema: Atualizações",
"UpdateAutomaticallyHelpText": "Baixe e instale atualizações automaticamente. Você ainda poderá instalar a partir do Sistema: Atualizações",
"UpdateMechanismHelpText": "Use o atualizador integrado do Readarr ou um script",
"UpdateScriptPathHelpText": "Caminho para um script personalizado que usa um pacote de atualização extraído e lida com o restante do processo de atualização",
"Updates": "Atualizações",
"UpgradeAllowedHelpText": "Se desabilitada, as qualidades não serão atualizadas",
"Uptime": "Tempo de atividade",
"UrlBaseHelpTextWarning": "Requer reinício para ter efeito",
"UseHardlinksInsteadOfCopy": "Usar Vínculos reais em vez de Copiar",
"UseProxy": "Usar proxy",
"UseHardlinksInsteadOfCopy": "Usar links rígidos ao invés de Copiar",
"UseProxy": "Usar Proxy",
"Usenet": "Usenet",
"UsenetDelay": "Atraso da Usenet",
"UsenetDelayHelpText": "Tempo, em minutos, para aguardar antes de capturar uma versão de Usenet",
"Username": "Nome de usuário",
"UsenetDelayHelpText": "Atraso em minutos para esperar antes de pegar um lançamento da Usenet",
"Username": "Nome do usuário",
"UsingExternalUpdateMechanismBranchToUseToUpdateReadarr": "Ramificação para atualizar o Readarr",
"UsingExternalUpdateMechanismBranchUsedByExternalUpdateMechanism": "Ramificação usada pelo mecanismo de atualização externo",
"Version": "Versão",
"WeekColumnHeader": "Cabeçalho da coluna da semana",
"WeekColumnHeader": "Cabeçalho da Coluna da Semana",
"Year": "Ano",
"YesCancel": "Sim, Cancelar",
"BookFileCountBookCountTotalTotalBookCountInterp": "{0}/{1} (Total: {2})",
@@ -488,7 +488,7 @@
"RescanAfterRefreshHelpText": "Verificar novamente a pasta de autor após atualizar o autor",
"ReplaceIllegalCharactersHelpText": "Substituir caracteres ilegais. Se desmarcada, o Readarr irá removê-los",
"RenameBooks": "Renomear livros",
"ReleaseProfiles": "Perfis de lançamento",
"ReleaseProfiles": "Perfis de Lançamento",
"RefreshInformation": "Atualizar informações",
"RefreshAuthor": "Atualizar autor",
"ReadarrSupportsMultipleListsForImportingBooksAndAuthorsIntoTheDatabase": "O Readarr oferece suporte a várias listas para importar livros e autores para o banco de dados.",
@@ -502,7 +502,7 @@
"PastDaysHelpText": "Dias anteriores a exibir no feed do iCal",
"PasswordHelpText": "Senha do servidor de conteúdo do Calibre",
"OutputFormatHelpText": "Opcionalmente, peça que o Calibre converta para outros formatos ao importar. Lista separada por vírgulas.",
"Other": "Outros",
"Other": "Outro",
"OnReleaseImportHelpText": "Ao importar lançamento",
"OnImportFailureHelpText": "Ao ocorrer falha na importação",
"OnDownloadFailureHelpText": "Ao ocorrer falha no download",
@@ -515,7 +515,7 @@
"MusicBrainzRecordingID": "ID da gravação no MusicBrainz",
"MusicBrainzBookID": "ID do livro no MusicBrainz",
"MusicBrainzAuthorID": "ID do autor no MusicBrainz",
"MonitoringOptions": "Opções de monitoramento",
"MonitoringOptions": "Opções de Monitoramento",
"MonitoredHelpText": "O Readarr pesquisará e baixará o livro",
"MonitoredAuthorIsUnmonitored": "O autor não está sendo monitorado",
"MonitoredAuthorIsMonitored": "O autor está sendo monitorado",
@@ -554,7 +554,7 @@
"IndexerIdHelpText": "Especificar a qual indexador o perfil se aplica",
"ImportLists": "Listas de importação",
"ImportListSettings": "Configurações Gerais da Lista de Importação",
"ImportListExclusions": "Exclusões da lista de importação",
"ImportListExclusions": "Importar Lista de Exclusões",
"ImportFailures": "Falhas na importação",
"IgnoreDeletedBooks": "Ignorar livros excluídos",
"IfYouDontAddAnImportListExclusionAndTheAuthorHasAMetadataProfileOtherThanNoneThenThisBookMayBeReaddedDuringTheNextAuthorRefresh": "Se você não adicionar uma exclusão à lista de importação e o autor tiver um perfil de metadados diferente de \"Nenhum\", este livro poderá ser adicionado novamente durante a próxima atualização do autor.",
@@ -576,7 +576,7 @@
"EntityName": "Nome da entidade",
"EndedAllBooksDownloaded": "Terminado (todos os livros baixados)",
"EnabledHelpText": "Marque para habilitar o perfil de lançamento",
"EnableProfile": "Habilitar perfil",
"EnableProfile": "Habilitar Perfil",
"EnableAutomaticAddHelpText": "Adicionar autor/livros ao Readarr ao sincronizar pela interface ou pelo Readarr",
"EmbedMetadataInBookFiles": "Incorporar metadados nos arquivos do livro",
"EmbedMetadataHelpText": "Pedir ao Calibre para gravar metadados no arquivo do livro",
@@ -588,9 +588,9 @@
"DiscNumber": "Número do disco",
"DiscCount": "Contagem de disco",
"Development": "Desenvolvimento",
"DeleteRootFolder": "Excluir pasta raiz",
"DeleteRootFolder": "Excluir Pasta Raiz",
"DeleteMetadataProfile": "Excluir perfil de metadados",
"DeleteImportList": "Excluir lista de importação",
"DeleteImportList": "Excluir Lista de Importação",
"DeleteFilesHelpText": "Excluir arquivos do livro e pasta do autor",
"DeleteBookFileMessageText": "Tem certeza que deseja excluir {0}?",
"DeleteBookFile": "Excluir arquivo de livro",
@@ -608,7 +608,7 @@
"ConsoleLogLevel": "Nível de log do console",
"CollapseMultipleBooksHelpText": "Recolher vários livros lançados no mesmo dia",
"CollapseMultipleBooks": "Recolher vários livros",
"ChownGroup": "Grupo chown",
"ChownGroup": "chown Grupo",
"CatalogNumber": "Número do Catálogo",
"CalibreUsername": "Nome de usuário do Calibre",
"CalibreUrlBase": "URL base do Calibre",
@@ -664,7 +664,6 @@
"OutputPath": "Caminho de saída",
"Progress": "Progresso",
"ReleaseTitle": "Título do Lançamento",
"UI": "UI",
"Actions": "Ações",
"FilterAuthor": "Filtro de Autor",
"NameFirstLast": "Primeiro Nome Último Nome",
@@ -735,17 +734,17 @@
"OnBookFileDeleteHelpText": "Ao Excluir um Arquivo de Livro",
"OnBookTagUpdate": "Ao Atualizar Etiqueta de um Livro",
"OnDownloadFailure": "Na Falha do Download",
"OnGrab": "Ao obter",
"OnHealthIssue": "Em Problema de Saúde",
"OnGrab": "Ao Baixar",
"OnHealthIssue": "Ao Problema de Saúde",
"OnImportFailure": "Em uma Falha de Importação",
"OnReleaseImport": "Ao Importar Lançamento",
"OnRename": "Ao Renomear",
"OnUpgrade": "Ao Atualizar",
"AppDataLocationHealthCheckMessage": "A atualização não será possível para evitar a exclusão de AppData na atualização",
"IndexerSearchCheckNoInteractiveMessage": "Nenhum indexador disponível com a Pesquisa interativa habilitada, o Readarr não fornecerá nenhum resultado de pesquisa interativa",
"IndexerSearchCheckNoInteractiveMessage": "Nenhum indexador disponível com a Pesquisa Interativa habilitada, o Readarr não fornecerá nenhum resultado de pesquisa interativa",
"ConnectSettingsSummary": "Notificações, conexões com servidores/tocadores de mídia e scripts personalizados",
"DownloadClientStatusCheckAllClientMessage": "Todos os clientes de download estão indisponíveis devido a falhas",
"DownloadClientsSettingsSummary": "Clientes de download, gerenciamento do download e mapeamento remoto de caminhos",
"DownloadClientsSettingsSummary": "Clientes de download, gerenciamento de download e mapeamentos de caminhos remotos",
"Yesterday": "Ontem",
"Connect": "Conectar",
"CouldntFindAnyResultsForTerm": "Não foi possível encontrar nenhum resultado para '{0}'",
@@ -785,7 +784,7 @@
"IndexerStatusCheckSingleClientMessage": "Indexadores indisponíveis devido a falhas: {0}",
"Lists": "Listas",
"MediaManagement": "Gerenciamento de Mídia",
"MediaManagementSettingsSummary": "Nomeação, configurações de gerenciamento de arquivo e pastas raízes",
"MediaManagementSettingsSummary": "Nomenclatura, configurações de gerenciamento de arquivos e pastas raiz",
"Metadata": "Metadados",
"MissingFromDisk": "Readarr não conseguiu encontrar o arquivo no disco, então o arquivo foi desvinculado do livro no banco de dados",
"Monitor": "Monitorar",
@@ -824,14 +823,14 @@
"SettingsRemotePathMappingLocalPath": "Caminho local",
"SettingsRemotePathMappingRemotePath": "Caminho Remoto",
"SettingsRemotePathMappingRemotePathHelpText": "Caminho raiz para o diretório que o Cliente de Download acessa",
"SizeLimit": "Tamanho limite",
"SizeLimit": "Limite de Tamanho",
"SystemTimeCheckMessage": "A hora do sistema está desligada por mais de 1 dia. Tarefas agendadas podem não ser executadas corretamente até que o horário seja corrigido",
"TimeLeft": "Tempo restante",
"TimeLeft": "Tempo Restante",
"UISettingsSummary": "Opções de calendário, data e cores prejudicadas",
"UpdateCheckStartupNotWritableMessage": "Não é possível instalar a atualização porque a pasta de inicialização '{0}' não pode ser gravada pelo usuário '{1}'.",
"UpdateCheckStartupTranslocationMessage": "Não é possível instalar a atualização porque a pasta de inicialização '{0}' está em uma pasta de translocação de aplicativo.",
"TagsSettingsSummary": "Gerenciar etiquetas de autor, perfil, restrição e notificação",
"InstanceNameHelpText": "Nome da instância na guia e para o nome do aplicativo do Syslog",
"InstanceNameHelpText": "Nome da instância na aba e para o nome do aplicativo Syslog",
"AddList": "Adicionar Lista",
"DataExistingBooks": "Monitorar livros que você tem arquivos ou que não foram lançados ainda",
"DataListMonitorAll": "Monitorar autores e todos os livros para cada autor incluído na lista de importação",
@@ -842,8 +841,8 @@
"RenameFiles": "Renomear Arquivos",
"Test": "Testar",
"WriteMetadataTags": "Salvar tags de metadados",
"RestartRequiredHelpTextWarning": "Requer reinicialização para ter efeito",
"InstanceName": "Nome da instância",
"RestartRequiredHelpTextWarning": "Requer reinicialização para entrar em vigor",
"InstanceName": "Nome da Instância",
"ConvertToFormat": "Converter para o Formato",
"DataAllBooks": "Monitorar todos os livros",
"DataFirstBook": "Monitorar o primeiro livro. Todos os outros livros serão ignorados",
@@ -865,7 +864,7 @@
"EnableRssHelpText": "Será usado quando o Readarr procurar periodicamente lançamentos via RSS Sync",
"HardlinkCopyFiles": "Vínculo real/Copiar arquivos",
"MoveFiles": "Mover arquivos",
"OnApplicationUpdate": "Ao atualizar o aplicativo",
"OnApplicationUpdate": "Na Atualização do Aplicativo",
"OnApplicationUpdateHelpText": "Ao atualizar o aplicativo",
"ChooseImportMethod": "Escolha o método de importação",
"ClickToChangeReleaseGroup": "Clique para alterar o grupo do lançamento",
@@ -874,7 +873,7 @@
"BypassIfHighestQuality": "Ignorar se a qualidade mais alta",
"BypassIfHighestQualityHelpText": "Ignorar o atraso quando o lançamento tiver a qualidade habilitada mais alta no perfil de qualidade",
"CustomFormatScore": "Pontuação do formato personalizado",
"MinimumCustomFormatScore": "Pontuação mínima de formato personalizado",
"MinimumCustomFormatScore": "Pontuação Mínima de Formato Personalizado",
"MinimumCustomFormatScoreHelpText": "Pontuação mínima de formato personalizado necessária para ignorar o atraso do protocolo preferido",
"ApiKeyValidationHealthCheckMessage": "Atualize sua chave de API para ter pelo menos {0} caracteres. Você pode fazer isso através das configurações ou do arquivo de configuração",
"DeleteFormat": "Excluir Formato",
@@ -903,7 +902,7 @@
"DeleteCustomFormatMessageText": "Tem certeza de que deseja excluir o formato personalizado '{0}'?",
"ImportListMissingRoot": "Pasta raiz ausente para lista(s) de importação: {0}",
"ImportListMultipleMissingRoots": "Várias pastas raiz estão ausentes para listas de importação: {0}",
"IndexerDownloadClientHelpText": "Especifique qual cliente de download é usado para capturas deste indexador",
"IndexerDownloadClientHelpText": "Especifique qual cliente de download é usado para baixar deste indexador",
"ListRefreshInterval": "Intervalo de atualização da lista",
"ListWillRefreshEveryInterp": "A lista será atualizada a cada {0}",
"ResetDefinitionTitlesHelpText": "Redefinir títulos de definição, bem como valores",
@@ -914,12 +913,12 @@
"HideAdvanced": "Ocultar Avançado",
"ShowAdvanced": "Mostrar Avançado",
"ShownClickToHide": "Mostrado, clique para ocultar",
"ColonReplacement": "Substituição de Dois Pontos",
"ColonReplacement": "Substituto para dois-pontos",
"DashOrSpaceDashDependingOnName": "Traço ou Traço e Espaço dependendo do nome",
"ReplaceWithDash": "Substituir por traço",
"ReplaceWithSpaceDash": "Substituir com Espaço e Traço",
"ReplaceWithDash": "Substituir por Traço",
"ReplaceWithSpaceDash": "Substituir por Espaço e Traço",
"SmartReplace": "Substituição Inteligente",
"ReplaceWithSpaceDashSpace": "Substituir com Espaço e Traço e Espaço",
"ReplaceWithSpaceDashSpace": "Substituir com Espaço, Traço e Espaço",
"DeleteRemotePathMapping": "Excluir Mapeamento de Caminho Remoto",
"BlocklistReleases": "Lançamentos na lista de bloqueio",
"CloneCondition": "Condição de clone",
@@ -952,7 +951,7 @@
"NoDownloadClientsFound": "Nenhum cliente de download encontrado",
"NoImportListsFound": "Nenhuma lista de importação encontrada",
"NoIndexersFound": "Nenhum indexador encontrado",
"RedownloadFailed": "Baixar Novamente Falhou",
"RedownloadFailed": "Redownload falhou",
"RemoveFailedDownloads": "Remover downloads com falha",
"RemoveDownloadsAlert": "As configurações de remoção foram movidas para as configurações individuais do cliente de download na tabela acima.",
"RemoveFailed": "Falha na remoção",
@@ -983,5 +982,6 @@
"No": "Não",
"RemoveCompletedDownloads": "Remover downloads concluídos",
"RemovingTag": "Removendo etiqueta",
"SkipRedownloadHelpText": "Impede Readarr de tentar baixar versões alternativas para os itens removidos"
"SkipRedownloadHelpText": "Impede Readarr de tentar baixar versões alternativas para os itens removidos",
"IndexerDownloadClientHealthCheckMessage": "Indexadores com clientes de download inválidos: {0}."
}

View File

@@ -15,7 +15,7 @@
"DiskSpace": "Spațiul pe disc",
"EnableRSS": "Activați RSS",
"EnableSslHelpText": " Necesită repornirea în funcție de administrator pentru a intra în vigoare",
"Ended": "Finalizat",
"Ended": "Încheiat",
"Grab": "Apuca",
"LoadingBookFilesFailed": "Încărcarea fișierelor film a eșuat",
"LoadingBooksFailed": "Încărcarea fișierelor film a eșuat",
@@ -94,7 +94,6 @@
"AgeWhenGrabbed": "Vârsta (când a fost apucat)",
"AlreadyInYourLibrary": "Deja în biblioteca dvs.",
"AlternateTitles": "Titlu alternativ",
"Authentication": "Autentificare",
"AuthenticationMethodHelpText": "Solicitați numele de utilizator și parola pentru a accesa Radarr",
"AuthorClickToChangeBook": "Faceți clic pentru a schimba filmul",
"AutoRedownloadFailedHelpText": "Căutați automat și încercați să descărcați o versiune diferită",
@@ -138,7 +137,7 @@
"DelayProfiles": "Profile de întârziere",
"DelayingDownloadUntilInterp": "Întârzierea descărcării până la {0} la {1}",
"Delete": "Șterge",
"DeleteBackup": "Ștergeți copie de siguranță",
"DeleteBackup": "Ștergeți copia de rezervă",
"DeleteBackupMessageText": "Sigur doriți să ștergeți copia de siguranță „{0}”?",
"DeleteDelayProfile": "Ștergeți profilul de întârziere",
"DeleteDelayProfileMessageText": "Sigur doriți să ștergeți acest profil de întârziere?",
@@ -192,7 +191,7 @@
"FileDateHelpText": "Schimbați data fișierului la import / rescanare",
"FileManagement": "Administrarea de fișiere",
"FileNames": "Numele fișierelor",
"Filename": "Numele fișierului",
"Filename": "Nume fișier",
"Files": "Fișiere",
"FirstDayOfWeek": "Prima zi a săptămânii",
"Fixed": "Fix",
@@ -450,7 +449,6 @@
"ReplaceIllegalCharactersHelpText": "Înlocuiți personajele ilegale. Dacă nu este bifat, Radarr le va elimina în schimb",
"ShowReleaseDate": "Afișează data lansării",
"ShowTitle": "Arata titlul",
"UI": "Interfață Grafica",
"OutputPath": "Calea pentru Output",
"Progress": "Progres",
"ShowBookTitleHelpText": "Afișați titlul filmului sub afiș",
@@ -546,7 +544,7 @@
"RestartRequiredHelpTextWarning": "Necesită repornire pentru a intra în vigoare",
"Test": "Testează",
"AddList": "Adaugă listă",
"RenameFiles": "Redenumește Fișiere",
"RenameFiles": "Redenumește Fișierele",
"Label": "Etichetă",
"ImportListExclusions": "Ștergeți excluderea listei de import",
"ManualImportSelectEdition": "Import manual - Selectați film",
@@ -571,7 +569,7 @@
"CutoffFormatScoreHelpText": "Odată ce acest scor personalizat este atins, Radarr nu va mai descărca filme",
"DeleteFormatMessageText": "Sigur doriți să ștergeți eticheta format {0}?",
"IncludeCustomFormatWhenRenamingHelpText": "Includeți în formatul de redenumire {Formate personalizate}",
"HiddenClickToShow": "Ascuns, faceți clic pentru a afișa",
"HiddenClickToShow": "Ascuns, faceți clic pentru afișare",
"HideAdvanced": "Ascunde Avansat",
"ShowAdvanced": "Arată setări avansate",
"ShownClickToHide": "Afișat, faceți clic pentru a ascunde",
@@ -601,7 +599,7 @@
"RedownloadFailed": "Descarcare esuata",
"ApplyTagsHelpTextAdd": "Adăugare: adăugați etichetele la lista de etichete existentă",
"ApplyTagsHelpTextHowToApplyImportLists": "Cum se aplică etichete listelor de import selectate",
"ApplyTagsHelpTextHowToApplyDownloadClients": "Cum se aplică etichete filmelor selectate",
"ApplyTagsHelpTextHowToApplyDownloadClients": "Cum se aplică etichete clienților de descărcare selectați",
"ApplyTagsHelpTextHowToApplyIndexers": "Cum se aplică etichete indexatoarelor selectate",
"ApplyTagsHelpTextRemove": "Eliminați: eliminați etichetele introduse",
"ApplyTagsHelpTextReplace": "Înlocuire: înlocuiți etichetele cu etichetele introduse (nu introduceți etichete pentru a șterge toate etichetele)",

View File

@@ -450,7 +450,6 @@
"ShowBookTitleHelpText": "Показать название фильма под постером",
"ShowReleaseDate": "Показать дату выпуска",
"ShowTitle": "Показать название",
"UI": "Пользовательский интерфейс",
"Actions": "Действия",
"Progress": "Прогресс",
"ReleaseTitle": "Название релиза",

View File

@@ -89,7 +89,6 @@
"MetadataProfiles": "profil metadát",
"RecyclingBin": "Kôš",
"Search": "Hľadať",
"UI": "UI",
"UpdateMechanismHelpText": "Použiť vstavaný Prowlarr aktualizátor alebo skript",
"Updates": "Aktualizovať",
"URLBase": "Základ URL",

View File

@@ -450,7 +450,6 @@
"ShowReleaseDate": "Visa släppdatum",
"ShowTitle": "Visa titel",
"Today": "Idag",
"UI": "Användargränssnitt",
"Actions": "Åtgärder",
"BookAvailableButMissing": "Film Tillgänglig, men Saknas",
"NotAvailable": "Inte tillgänglig",

View File

@@ -441,7 +441,6 @@
"YesCancel": "ใช่ยกเลิก",
"DownloadClientCheckDownloadingToRoot": "ดาวน์โหลดไคลเอนต์ {0} จะทำการดาวน์โหลดในโฟลเดอร์รูท {1} คุณไม่ควรดาวน์โหลดไปยังโฟลเดอร์รูท",
"ReplaceIllegalCharactersHelpText": "แทนที่อักขระที่ผิดกฎหมาย หากไม่เลือก Radarr จะลบออกแทน",
"UI": "UI",
"Progress": "ความคืบหน้า",
"NotAvailable": "ไม่สามารถใช้ได้",
"NotMonitored": "ไม่ได้รับการตรวจสอบ",

View File

@@ -452,7 +452,6 @@
"ShowTitle": "Başlığı göster",
"Today": "Bugün",
"Tomorrow": "Yarın",
"UI": "UI",
"Actions": "Etkiler",
"Component": "Bileşen",
"Level": "Seviye",

View File

@@ -448,7 +448,6 @@
"MetadataSettings": "Налаштування метаданих",
"Monitor": "Контрольований",
"Monitored": "Відстежується",
"UI": "Інтерфейс користувача",
"Usenet": "Usenet",
"Logging": "Журналування",
"MaintenanceRelease": "Випуск для обслуговування: виправлення помилок та інші покращення. Щоб отримати докладнішу інформацію, перегляньте історію фіксації Github",

View File

@@ -443,7 +443,6 @@
"ReleaseTitle": "Tiêu đề phát hành",
"Actions": "Hành động",
"ReplaceIllegalCharactersHelpText": "Thay thế các ký tự bất hợp pháp. Nếu không được chọn, Radarr sẽ xóa chúng thay thế",
"UI": "Giao diện người dùng",
"Tomorrow": "Ngày mai",
"Today": "Hôm nay",
"Progress": "Phát triển",

View File

@@ -23,7 +23,7 @@
"BackupFolderHelpText": "相对路径将在Radarr的AppData目录下",
"BackupNow": "马上备份",
"BackupRetentionHelpText": "早于保留周期的自动备份将被自动清除",
"Backups": "备份",
"Backups": "历史备份",
"BindAddress": "绑定地址",
"BindAddressHelpTextWarning": "需重启以生效",
"BookIsDownloading": "影片正在下载中",
@@ -422,7 +422,7 @@
"Version": "版本",
"WeekColumnHeader": "日期格式",
"Year": "年",
"YesCancel": ",取消",
"YesCancel": "确定,取消",
"20MinutesTwenty": "20 分钟:{0}",
"45MinutesFourtyFive": "45分钟: {0}",
"60MinutesSixty": "60分钟: {0}",
@@ -438,13 +438,13 @@
"MaintenanceRelease": "维护版本修复错误及其他改进参见Github提交 查看更多详情",
"DeleteBookFileMessageText": "您确认您想删除吗?",
"ApiKeyHelpTextWarning": "需重启以生效",
"Actions": "作",
"Actions": "作",
"AddMissing": "添加丢失项",
"AddNewItem": "添加新项目",
"DeleteRootFolderMessageText": "您确定要删除索引 '{0}'吗?",
"Progress": "进度",
"Publisher": "发布者",
"Series": "",
"Series": "节目",
"ShowBookTitleHelpText": "在海报下显示电影标题",
"BookAvailableButMissing": "影片可下载,但没有下载",
"ShowReleaseDate": "显示发布日期",
@@ -454,11 +454,10 @@
"NotAvailable": "不可用",
"NotMonitored": "未监控的",
"OutputPath": "输出路径",
"ReleaseTitle": "歌曲发布标题",
"ReleaseTitle": "发布标题",
"TheAuthorFolderAndAllOfItsContentWillBeDeleted": "电影目录 '{0}' 及所有内容都会被删除。",
"Today": "今天",
"Tomorrow": "明天",
"UI": "UI界面",
"UnableToLoadMetadataProfiles": "无法加载元数据配置",
"Label": "标签",
"Component": "组件",
@@ -480,7 +479,7 @@
"All": "全部",
"Level": "等级",
"RemoveFromBlocklist": "从黑名单中移除",
"Blocklist": "阻止列表",
"Blocklist": "黑名单",
"BlocklistRelease": "黑名单版本",
"AllowFingerprinting": "允许指纹识别",
"AllExpandedCollapseAll": "收缩所有",
@@ -921,5 +920,27 @@
"ApplyTagsHelpTextHowToApplyIndexers": "如何将标签应用到已选择的索引器",
"ApplyTagsHelpTextRemove": "移除: 移除已输入的标签",
"ApplyTagsHelpTextReplace": "替换: 用输入的标签替换当前标签 (不输入将会清除所有标签)",
"ApplyTagsHelpTextAdd": "添加: 添加标签至已有的标签列表中"
"ApplyTagsHelpTextAdd": "添加: 添加标签至已有的标签列表中",
"AutoAdd": "自动添加",
"DeleteSelectedIndexers": "删除索引器",
"EditSelectedDownloadClients": "编辑选定的下载客户端",
"EditSelectedImportLists": "编辑选定的导入列表",
"EditSelectedIndexers": "编辑选定的索引器",
"ExistingTag": "已有标签",
"NoEventsFound": "无事件",
"RemoveCompleted": "移除已完成",
"RemoveSelectedItems": "删除所选项目",
"RemovingTag": "移除标签",
"SetTags": "设置标签",
"Yes": "确定",
"BlocklistReleases": "黑名单版本",
"Required": "必须的",
"RemoveFailed": "删除失败",
"RemoveSelectedItem": "删除所选项目",
"DeleteSelectedDownloadClients": "删除下载客户端",
"DeleteSelectedImportLists": "删除导入列表",
"NoChange": "无修改",
"Negated": "无效的",
"No": "否",
"ResetQualityDefinitions": "重置质量定义"
}

View File

@@ -6,6 +6,7 @@ using System.Linq;
using System.Threading.Tasks;
using NLog;
using NzbDrone.Common.Disk;
using NzbDrone.Common.EnsureThat;
using NzbDrone.Common.Extensions;
using NzbDrone.Common.TPL;
using NzbDrone.Core.Configuration;
@@ -116,6 +117,9 @@ namespace NzbDrone.Core.MediaFiles
private void StartWatchingPath(string path)
{
Ensure.That(path, () => path).IsNotNullOrWhiteSpace();
Ensure.That(path, () => path).IsValidPath(PathValidationType.CurrentOs);
// Already being watched
if (_fileSystemWatchers.ContainsKey(path))
{

View File

@@ -4119,18 +4119,6 @@
}
}
},
"/initialize.js": {
"get": {
"tags": [
"InitializeJs"
],
"responses": {
"200": {
"description": "Success"
}
}
}
},
"/api/v1/language": {
"get": {
"tags": [

View File

@@ -1,66 +0,0 @@
using System.Text;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using NzbDrone.Common;
using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Core.Analytics;
using NzbDrone.Core.Configuration;
namespace Readarr.Http.Frontend
{
[Authorize(Policy = "UI")]
[ApiController]
public class InitializeJsController : Controller
{
private readonly IConfigFileProvider _configFileProvider;
private readonly IAnalyticsService _analyticsService;
private static string _apiKey;
private static string _urlBase;
private string _generatedContent;
public InitializeJsController(IConfigFileProvider configFileProvider,
IAnalyticsService analyticsService)
{
_configFileProvider = configFileProvider;
_analyticsService = analyticsService;
_apiKey = configFileProvider.ApiKey;
_urlBase = configFileProvider.UrlBase;
}
[HttpGet("/initialize.js")]
public IActionResult Index()
{
// TODO: Move away from window.Readarr and prefetch the information returned here when starting the UI
return Content(GetContent(), "application/javascript");
}
private string GetContent()
{
if (RuntimeInfo.IsProduction && _generatedContent != null)
{
return _generatedContent;
}
var builder = new StringBuilder();
builder.AppendLine("window.Readarr = {");
builder.AppendLine($" apiRoot: '{_urlBase}/api/v1',");
builder.AppendLine($" apiKey: '{_apiKey}',");
builder.AppendLine($" release: '{BuildInfo.Release}',");
builder.AppendLine($" version: '{BuildInfo.Version.ToString()}',");
builder.AppendLine($" instanceName: '{_configFileProvider.InstanceName.ToString()}',");
builder.AppendLine($" theme: '{_configFileProvider.Theme.ToString()}',");
builder.AppendLine($" branch: '{_configFileProvider.Branch.ToLower()}',");
builder.AppendLine($" analytics: {_analyticsService.IsEnabled.ToString().ToLowerInvariant()},");
builder.AppendLine($" userHash: '{HashUtil.AnonymousToken()}',");
builder.AppendLine($" urlBase: '{_urlBase}',");
builder.AppendLine($" isProduction: {RuntimeInfo.IsProduction.ToString().ToLowerInvariant()}");
builder.AppendLine("};");
_generatedContent = builder.ToString();
return _generatedContent;
}
}
}

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