1
0
mirror of https://github.com/Radarr/Radarr.git synced 2026-03-29 18:15:37 -04:00

Compare commits

...

29 Commits

Author SHA1 Message Date
Bogdan
bdc4aade0f Use extra release fields in PassThePopcorn parser 2023-12-24 06:56:48 +02:00
Weblate
b2300dbf41 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Dimitri <dimitridroeck@gmail.com>
Co-authored-by: Pietro Ribeiro <xxb1exuv6@mozmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/fr/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pt/
Translation: Servarr/Radarr
2023-12-23 23:31:39 +02:00
Weblate
44289d30f9 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Aitzol Garmendia <aitzolgarmendia@gmail.com>
Co-authored-by: Andrés Reyes Monge <armonge@gmail.com>
Co-authored-by: Fixer <ygj59783@zslsz.com>
Co-authored-by: Michael Schönenberger <muchi94@gmail.com>
Co-authored-by: VisoTC <szlytlyt@outlook.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: ηg <jonas.konrath@icloud.com>
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/de/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/es/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/tr/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/zh_CN/
Translation: Servarr/Radarr
2023-12-22 04:24:19 +02:00
luz paz
260fb88f85 Fix various typos
Found via `codespell -q 3`

(cherry picked from commit 209a250079fdf7ad2bc9168f81bfb45b9531d6b3)
2023-12-19 20:18:54 +02:00
Bogdan
119cdf6f09 Fixed: Cleanup orphaned import list movies by movie metadata 2023-12-18 00:51:59 +02:00
Bogdan
c8d30fd214 Cleanup convert root folders to TS 2023-12-17 23:23:08 +02:00
Bogdan
7e9e528d3b Fixed: Ignore empty tags when adding items to Flood
Fixed #8145
2023-12-17 22:09:13 +02:00
Bogdan
8554c0d9cb Refactor movie alternative titles connector 2023-12-17 19:57:22 +02:00
Bogdan
22cc34b4fe Bump version to 5.2.6 2023-12-17 16:01:10 +02:00
Weblate
990785ebfc Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Fixer <ygj59783@zslsz.com>
Co-authored-by: Menno Liefstingh <mennoliefstingh@gmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: lifeisfreedom048 <koyuncu.ozgur@gmail.com>
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/nl/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/tr/
Translation: Servarr/Radarr
2023-12-16 02:41:57 +02:00
Bogdan
957be99401 Fixed: Bump media info revision for DV HDR10Plus 2023-12-16 02:41:34 +02:00
Bogdan
4bcde25e29 Improve messaging for accepted Custom Formats scoring upgrades
Co-authored-by: bakerboy448 <55419169+bakerboy448@users.noreply.github.com>

Closes #9496
2023-12-16 00:38:05 +02:00
Bogdan
1d70f36e7d New: 3D and HDR metadata for Trakt connection 2023-12-15 17:13:47 +02:00
Bogdan
cc0a448bc8 New: Rate limiting for Trakt connection 2023-12-15 17:13:47 +02:00
Bogdan
c9e977baea Simplify mapping in Trakt connection 2023-12-15 17:13:47 +02:00
Mark McDowall
6cb9a46cd4 Fixed: Imported movies updating on Calendar
(cherry picked from commit 5a3bc49392b700650a34536ff3794bce614f64a4)

Closes #9491
2023-12-15 16:50:06 +02:00
Agneev Mukherjee
eef379277a Enable browser navigation buttons for PWA
(cherry picked from commit da9a60691f363323565a293ed9eaeb6349ceccb6)

Closes #9487
2023-12-15 16:36:28 +02:00
Chad A Simmons
41fef47684 New: Support for DV HDR10Plus from media info 2023-12-15 03:36:32 +02:00
Weblate
fcda6faf3d Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: ROSERAT Ugo <roserat.ugo@gmail.com>
Co-authored-by: RicardoVelaC <ricardovelac@gmail.com>
Co-authored-by: SHUAI.W <x@ousui.org>
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/es/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/fr/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/lv/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/zh_CN/
Translation: Servarr/Radarr
2023-12-13 16:41:49 +02:00
Bogdan
79bbf9c50b Fixed: Movie status label in add movie search results 2023-12-12 21:55:41 +02:00
Bogdan
43d2f2804b New: IMDb ratings and genres in add movie search results 2023-12-12 21:55:09 +02:00
Qstick
fa62f3f66a Fixed: Correctly handle Migration when PG Host has ".db"
(cherry picked from commit 97ee24507f4306e3b62c3d00cd3ade6a09d1b957)

Closes #9478
2023-12-12 15:36:21 +02:00
Bogdan
229d91fe40 Implement DatabaseConnectionInfo
Co-authored-by: Qstick <qstick@gmail.com>
2023-12-12 15:36:14 +02:00
Bogdan
2673d1eee4 Fixed: Movie poster in search results after adding
Fixes #8029
2023-12-11 19:30:31 +02:00
Bogdan
e59fd1118f Fixed: Downloading status post-adding movie 2023-12-11 19:27:05 +02:00
Bogdan
c1fd33b152 Fix categories for NZBFinder 2023-12-10 15:50:19 +02:00
Bogdan
2f58c8676f Bump dotnet to 6.0.25 2023-12-10 15:35:59 +02:00
Fossil
defc448304 Update NZBFinder categories and remove OZnzb & NZB-Tortuga from default definitions (#9474)
NZB Finder will consolidate WEBDL & X265 into SD,HD,UHD so removed 2080 and 2090 categories.

OZnzb and NZB Tortuga are dead so removed it from the presets list.
2023-12-10 15:14:13 +02:00
Bogdan
3ec3358728 Bump version to 5.2.5 2023-12-10 13:47:06 +02:00
67 changed files with 446 additions and 529 deletions

View File

@@ -9,13 +9,13 @@ variables:
testsFolder: './_tests'
yarnCacheFolder: $(Pipeline.Workspace)/.yarn
nugetCacheFolder: $(Pipeline.Workspace)/.nuget/packages
majorVersion: '5.2.4'
majorVersion: '5.2.6'
minorVersion: $[counter('minorVersion', 2000)]
radarrVersion: '$(majorVersion).$(minorVersion)'
buildName: '$(Build.SourceBranchName).$(radarrVersion)'
sentryOrg: 'servarr'
sentryUrl: 'https://sentry.servarr.com'
dotnetVersion: '6.0.413'
dotnetVersion: '6.0.417'
nodeVersion: '16.X'
innoVersion: '6.2.0'
windowsImage: 'windows-2022'

View File

@@ -85,8 +85,13 @@
margin-top: 20px;
}
.studio,
.genres {
margin-left: 5px;
}
.links {
margin-left: 8px;
margin-left: 5px;
pointer-events: all;
}

View File

@@ -5,6 +5,7 @@ interface CssExports {
'certification': string;
'content': string;
'exclusionIcon': string;
'genres': string;
'icons': string;
'links': string;
'overlay': string;
@@ -14,6 +15,7 @@ interface CssExports {
'runtime': string;
'searchResult': string;
'statusContainer': string;
'studio': string;
'title': string;
'titleContainer': string;
'titleRow': string;

View File

@@ -1,6 +1,7 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import Icon from 'Components/Icon';
import ImdbRating from 'Components/ImdbRating';
import Label from 'Components/Label';
import Link from 'Components/Link/Link';
import TmdbRating from 'Components/TmdbRating';
@@ -61,6 +62,7 @@ class AddNewMovieSearchResult extends Component {
titleSlug,
year,
studio,
genres,
status,
overview,
ratings,
@@ -76,6 +78,7 @@ class AddNewMovieSearchResult extends Component {
hasFile,
isAvailable,
movieFile,
queueItem,
runtime,
movieRuntimeFormat,
certification
@@ -197,13 +200,46 @@ class AddNewMovieSearchResult extends Component {
/>
</Label>
{
ratings.imdb ?
<Label size={sizes.LARGE}>
<ImdbRating
ratings={ratings}
iconSize={13}
/>
</Label> :
null
}
{
!!studio &&
<Label size={sizes.LARGE}>
{studio}
<Icon
name={icons.STUDIO}
size={13}
/>
<span className={styles.studio}>
{studio}
</span>
</Label>
}
{
genres.length > 0 ?
<Label size={sizes.LARGE}>
<Icon
name={icons.GENRE}
size={13}
/>
<span className={styles.genres}>
{genres.slice(0, 3).join(', ')}
</span>
</Label> :
null
}
<Tooltip
anchor={
<Label
@@ -215,15 +251,15 @@ class AddNewMovieSearchResult extends Component {
/>
<span className={styles.links}>
Links
{translate('Links')}
</span>
</Label>
}
tooltip={
<MovieDetailsLinks
tmdbId={tmdbId}
youTubeTrailerId={youTubeTrailerId}
imdbId={imdbId}
youTubeTrailerId={youTubeTrailerId}
/>
}
canFlip={true}
@@ -237,6 +273,7 @@ class AddNewMovieSearchResult extends Component {
hasMovieFiles={hasFile}
monitored={monitored}
isAvailable={isAvailable}
queueItem={queueItem}
id={id}
useLabel={true}
colorImpairedMode={colorImpairedMode}
@@ -273,6 +310,7 @@ AddNewMovieSearchResult.propTypes = {
titleSlug: PropTypes.string.isRequired,
year: PropTypes.number.isRequired,
studio: PropTypes.string,
genres: PropTypes.arrayOf(PropTypes.string),
status: PropTypes.string.isRequired,
overview: PropTypes.string,
ratings: PropTypes.object.isRequired,
@@ -283,15 +321,19 @@ AddNewMovieSearchResult.propTypes = {
isExclusionMovie: PropTypes.bool.isRequired,
isSmallScreen: PropTypes.bool.isRequired,
id: PropTypes.number,
queueItems: PropTypes.arrayOf(PropTypes.object),
monitored: PropTypes.bool.isRequired,
hasFile: PropTypes.bool.isRequired,
isAvailable: PropTypes.bool.isRequired,
movieFile: PropTypes.object,
queueItem: PropTypes.object,
colorImpairedMode: PropTypes.bool,
runtime: PropTypes.number.isRequired,
movieRuntimeFormat: PropTypes.string.isRequired,
certification: PropTypes.string
};
AddNewMovieSearchResult.defaultProps = {
genres: []
};
export default AddNewMovieSearchResult;

View File

@@ -10,14 +10,18 @@ function createMapStateToProps() {
createExistingMovieSelector(),
createExclusionMovieSelector(),
createDimensionsSelector(),
(state) => state.queue.details.items,
(state, { internalId }) => internalId,
(state) => state.settings.ui.item.movieRuntimeFormat,
(isExistingMovie, isExclusionMovie, dimensions, internalId, movieRuntimeFormat) => {
(isExistingMovie, isExclusionMovie, dimensions, queueItems, internalId, movieRuntimeFormat) => {
const queueItem = queueItems.find((item) => internalId > 0 && item.movieId === internalId);
return {
existingMovieId: internalId,
isExistingMovie,
isExclusionMovie,
isSmallScreen: dimensions.isSmallScreen,
queueItem,
movieRuntimeFormat
};
}

View File

@@ -32,7 +32,7 @@
.contentContainer {
z-index: $popperZIndex;
margin-top: 4px;
/* 400px container witdh with 8px padding on each side */
/* 400px container width with 8px padding on each side */
width: 384px;
}

View File

@@ -55,7 +55,7 @@ class CalendarConnector extends Component {
gotoCalendarToday
} = this.props;
registerPagePopulator(this.repopulate);
registerPagePopulator(this.repopulate, ['movieFileUpdated', 'movieFileDeleted']);
if (useCurrentPage) {
fetchCalendar();

View File

@@ -167,7 +167,7 @@ class SignalRConnector extends Component {
const resource = body.resource;
const status = resource.status;
// Both sucessful and failed commands need to be
// Both successful and failed commands need to be
// completed, otherwise they spin until they timeout.
if (status === 'completed' || status === 'failed') {
@@ -187,6 +187,8 @@ class SignalRConnector extends Component {
repopulatePage('movieFileUpdated');
} else if (body.action === 'deleted') {
this.props.dispatchRemoveItem({ section, id: body.resource.id });
repopulatePage('movieFileDeleted');
}
};

View File

@@ -15,5 +15,5 @@
"start_url": "../../../../",
"theme_color": "#3a3f51",
"background_color": "#3a3f51",
"display": "standalone"
"display": "minimal-ui"
}

View File

@@ -6,31 +6,43 @@ import MovieTitlesTableContent from './MovieTitlesTableContent';
function createMapStateToProps() {
return createSelector(
(state, { movieId }) => movieId,
(state) => state.movies,
(movies) => {
return movies;
(movieId, movies) => {
const {
isFetching,
isPopulated,
error,
items
} = movies;
const alternateTitles = items.find((m) => m.id === movieId)?.alternateTitles;
return {
isFetching,
isPopulated,
error,
alternateTitles
};
}
);
}
const mapDispatchToProps = {
// fetchMovies
};
class MovieTitlesTableContentConnector extends Component {
//
// Render
render() {
const movie = this.props.items.filter((obj) => {
return obj.id === this.props.movieId;
});
const {
alternateTitles,
...otherProps
} = this.props;
return (
<MovieTitlesTableContent
{...this.props}
items={movie[0].alternateTitles}
{...otherProps}
items={alternateTitles}
/>
);
}
@@ -38,7 +50,11 @@ class MovieTitlesTableContentConnector extends Component {
MovieTitlesTableContentConnector.propTypes = {
movieId: PropTypes.number.isRequired,
items: PropTypes.arrayOf(PropTypes.object).isRequired
alternateTitles: PropTypes.arrayOf(PropTypes.object).isRequired
};
export default connect(createMapStateToProps, mapDispatchToProps)(MovieTitlesTableContentConnector);
MovieTitlesTableContentConnector.defaultProps = {
alternateTitles: []
};
export default connect(createMapStateToProps)(MovieTitlesTableContentConnector);

View File

@@ -1,82 +0,0 @@
import PropTypes from 'prop-types';
import React from 'react';
import Label from 'Components/Label';
import IconButton from 'Components/Link/IconButton';
import Link from 'Components/Link/Link';
import TableRowCell from 'Components/Table/Cells/TableRowCell';
import TableRow from 'Components/Table/TableRow';
import { icons, kinds } from 'Helpers/Props';
import formatBytes from 'Utilities/Number/formatBytes';
import translate from 'Utilities/String/translate';
import styles from './RootFolderRow.css';
function RootFolderRow(props) {
const {
id,
path,
accessible,
freeSpace,
unmappedFolders,
onDeletePress
} = props;
const isUnavailable = !accessible;
return (
<TableRow>
<TableRowCell>
{
isUnavailable ?
<div className={styles.unavailablePath}>
{path}
<Label
className={styles.unavailableLabel}
kind={kinds.DANGER}
>
{translate('Unavailable')}
</Label>
</div> :
<Link
className={styles.link}
to={`/add/import/${id}`}
>
{path}
</Link>
}
</TableRowCell>
<TableRowCell className={styles.freeSpace}>
{(isUnavailable || isNaN(freeSpace)) ? '-' : formatBytes(freeSpace)}
</TableRowCell>
<TableRowCell className={styles.unmappedFolders}>
{isUnavailable ? '-' : unmappedFolders.length}
</TableRowCell>
<TableRowCell className={styles.actions}>
<IconButton
title={translate('RemoveRootFolder')}
name={icons.REMOVE}
onPress={onDeletePress}
/>
</TableRowCell>
</TableRow>
);
}
RootFolderRow.propTypes = {
id: PropTypes.number.isRequired,
path: PropTypes.string.isRequired,
accessible: PropTypes.bool.isRequired,
freeSpace: PropTypes.number,
unmappedFolders: PropTypes.arrayOf(PropTypes.object).isRequired,
onDeletePress: PropTypes.func.isRequired
};
RootFolderRow.defaultProps = {
unmappedFolders: []
};
export default RootFolderRow;

View File

@@ -1,92 +0,0 @@
import PropTypes from 'prop-types';
import React from 'react';
import Alert from 'Components/Alert';
import LoadingIndicator from 'Components/Loading/LoadingIndicator';
import Table from 'Components/Table/Table';
import TableBody from 'Components/Table/TableBody';
import { kinds } from 'Helpers/Props';
import translate from 'Utilities/String/translate';
import RootFolderRowConnector from './RootFolderRowConnector';
const rootFolderColumns = [
{
name: 'path',
get label() {
return translate('Path');
},
isVisible: true
},
{
name: 'freeSpace',
get label() {
return translate('FreeSpace');
},
isVisible: true
},
{
name: 'unmappedFolders',
get label() {
return translate('UnmappedFolders');
},
isVisible: true
},
{
name: 'actions',
isVisible: true
}
];
function RootFolders(props) {
const {
isFetching,
isPopulated,
error,
items
} = props;
if (isFetching && !isPopulated) {
return (
<LoadingIndicator />
);
}
if (!isFetching && !!error) {
return (
<Alert kind={kinds.DANGER}>
{translate('UnableToLoadRootFolders')}
</Alert>
);
}
return (
<Table
columns={rootFolderColumns}
>
<TableBody>
{
items.map((rootFolder) => {
return (
<RootFolderRowConnector
key={rootFolder.id}
id={rootFolder.id}
path={rootFolder.path}
accessible={rootFolder.accessible}
freeSpace={rootFolder.freeSpace}
unmappedFolders={rootFolder.unmappedFolders}
/>
);
})
}
</TableBody>
</Table>
);
}
RootFolders.propTypes = {
isFetching: PropTypes.bool.isRequired,
isPopulated: PropTypes.bool.isRequired,
error: PropTypes.object,
items: PropTypes.arrayOf(PropTypes.object).isRequired
};
export default RootFolders;

View File

@@ -1,72 +0,0 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import FileBrowserModal from 'Components/FileBrowser/FileBrowserModal';
import Icon from 'Components/Icon';
import Button from 'Components/Link/Button';
import { icons, kinds, sizes } from 'Helpers/Props';
import translate from 'Utilities/String/translate';
import styles from './AddRootFolder.css';
class AddRootFolder extends Component {
//
// Lifecycle
constructor(props, context) {
super(props, context);
this.state = {
isAddNewRootFolderModalOpen: false
};
}
//
// Lifecycle
onAddNewRootFolderPress = () => {
this.setState({ isAddNewRootFolderModalOpen: true });
};
onNewRootFolderSelect = ({ value }) => {
this.props.onNewRootFolderSelect(value);
};
onAddRootFolderModalClose = () => {
this.setState({ isAddNewRootFolderModalOpen: false });
};
//
// Render
render() {
return (
<div className={styles.addRootFolderButtonContainer}>
<Button
kind={kinds.PRIMARY}
size={sizes.LARGE}
onPress={this.onAddNewRootFolderPress}
>
<Icon
className={styles.importButtonIcon}
name={icons.DRIVE}
/>
{translate('AddRootFolder')}
</Button>
<FileBrowserModal
isOpen={this.state.isAddNewRootFolderModalOpen}
name="rootFolderPath"
value=""
onChange={this.onNewRootFolderSelect}
onModalClose={this.onAddRootFolderModalClose}
/>
</div>
);
}
}
AddRootFolder.propTypes = {
onNewRootFolderSelect: PropTypes.func.isRequired
};
export default AddRootFolder;

View File

@@ -130,7 +130,10 @@ export const actionHandlers = handleThunks({
promise.done((data) => {
const updatedItem = _.cloneDeep(data);
updatedItem.internalId = updatedItem.id;
updatedItem.id = updatedItem.tmdbId;
delete updatedItem.images;
const actions = [
updateItem({ section: 'movies', ...data }),
updateItem({ section: 'addMovie', ...updatedItem }),

View File

@@ -28,7 +28,7 @@
"@fortawesome/free-solid-svg-icons": "6.4.0",
"@fortawesome/react-fontawesome": "0.2.0",
"@juggle/resize-observer": "3.4.0",
"@microsoft/signalr": "6.0.21",
"@microsoft/signalr": "6.0.25",
"@sentry/browser": "7.51.2",
"@sentry/integrations": "7.51.2",
"@types/node": "18.16.8",

View File

@@ -47,7 +47,7 @@ namespace NzbDrone.Common.Test.Http
// Use mirrors for tests that use two hosts
var candidates = new[] { "httpbin1.servarr.com" };
// httpbin.org is broken right now, occassionally redirecting to https if it's unavailable.
// httpbin.org is broken right now, occasionally redirecting to https if it's unavailable.
_httpBinHost = mainHost;
_httpBinHosts = candidates.Where(IsTestSiteAvailable).ToArray();

View File

@@ -67,7 +67,7 @@ namespace NzbDrone.Common.EnvironmentInfo
}
catch (Exception ex)
{
_logger.Warn(ex, "Coudn't set app folder permission");
_logger.Warn(ex, "Couldn't set app folder permission");
}
}

View File

@@ -123,7 +123,7 @@ namespace NzbDrone.Common.Instrumentation.Sentry
_debounce = new SentryDebounce();
// initialize to true and reconfigure later
// Otherwise it will default to false and any errors occuring
// Otherwise it will default to false and any errors occurring
// before config file gets read will not be filtered
FilterEvents = true;
SentryEnabled = true;

View File

@@ -260,7 +260,7 @@ namespace NzbDrone.Common.OAuth
}
/// <summary>
/// Creates a request elements concatentation value to send with a request.
/// Creates a request elements concatenation value to send with a request.
/// This is also known as the signature base.
/// </summary>
/// <seealso href="http://oauth.net/core/1.0#rfc.section.9.1.3"/>

View File

@@ -4,17 +4,17 @@
<DefineConstants Condition="'$(RuntimeIdentifier)' == 'linux-musl-x64' or '$(RuntimeIdentifier)' == 'linux-musl-arm64'">ISMUSL</DefineConstants>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="DryIoc.dll" Version="5.4.1" />
<PackageReference Include="DryIoc.dll" Version="5.4.3" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.1" />
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="6.0.2" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="NLog" Version="5.2.3" />
<PackageReference Include="NLog.Extensions.Logging" Version="5.3.3" />
<PackageReference Include="Npgsql" Version="7.0.4" />
<PackageReference Include="Npgsql" Version="7.0.6" />
<PackageReference Include="Sentry" Version="3.23.1" />
<PackageReference Include="NLog.Targets.Syslog" Version="7.0.0" />
<PackageReference Include="SharpZipLib" Version="1.3.3" />
<PackageReference Include="System.Text.Json" Version="6.0.8" />
<PackageReference Include="System.Text.Json" Version="6.0.9" />
<PackageReference Include="System.ValueTuple" Version="4.5.0" />
<PackageReference Include="System.Data.SQLite.Core.Servarr" Version="1.0.115.5-18" />
<PackageReference Include="System.Configuration.ConfigurationManager" Version="6.0.1" />

View File

@@ -215,7 +215,7 @@ namespace NzbDrone.Common
if (dacls.Contains(authenticatedUsersDacl))
{
// Permssions already set
// Permissions already set
return;
}

View File

@@ -4,6 +4,7 @@ using NUnit.Framework;
using NzbDrone.Core.Housekeeping.Housekeepers;
using NzbDrone.Core.ImportLists;
using NzbDrone.Core.ImportLists.ImportListMovies;
using NzbDrone.Core.Movies;
using NzbDrone.Core.Test.Framework;
namespace NzbDrone.Core.Test.Housekeeping.Housekeepers
@@ -42,8 +43,13 @@ namespace NzbDrone.Core.Test.Housekeeping.Housekeepers
{
GivenImportList();
var movieMetadata = Builder<MovieMetadata>.CreateNew().BuildNew();
Db.Insert(movieMetadata);
var status = Builder<ImportListMovie>.CreateNew()
.With(h => h.ListId = _importList.Id)
.With(b => b.MovieMetadataId = movieMetadata.Id)
.BuildNew();
Db.Insert(status);

View File

@@ -15,6 +15,7 @@ namespace NzbDrone.Core.Test.MediaFiles.MediaInfo.MediaInfoFormatterTests
[TestCase(HdrFormat.Hdr10Plus, "HDR10Plus")]
[TestCase(HdrFormat.DolbyVision, "DV")]
[TestCase(HdrFormat.DolbyVisionHdr10, "DV HDR10")]
[TestCase(HdrFormat.DolbyVisionHdr10Plus, "DV HDR10Plus")]
[TestCase(HdrFormat.DolbyVisionHlg, "DV HLG")]
[TestCase(HdrFormat.DolbyVisionSdr, "DV SDR")]
public void should_format_video_dynamic_range_type(HdrFormat format, string expectedVideoDynamicRangeType)

View File

@@ -116,6 +116,8 @@ namespace NzbDrone.Core.Test.MediaFiles.MediaInfo
[TestCase(10, "bt2020", "smpte2084", "FFMpegCore.HdrDynamicMetadataSpmte2094", null, HdrFormat.Hdr10Plus)]
[TestCase(10, "bt2020", "smpte2084", "FFMpegCore.DoviConfigurationRecordSideData", null, HdrFormat.DolbyVision)]
[TestCase(10, "bt2020", "smpte2084", "FFMpegCore.DoviConfigurationRecordSideData", 1, HdrFormat.DolbyVisionHdr10)]
[TestCase(10, "bt2020", "smpte2084", "FFMpegCore.DoviConfigurationRecordSideData,FFMpegCore.HdrDynamicMetadataSpmte2094", 1, HdrFormat.DolbyVisionHdr10Plus)]
[TestCase(10, "bt2020", "smpte2084", "FFMpegCore.DoviConfigurationRecordSideData,FFMpegCore.HdrDynamicMetadataSpmte2094", 6, HdrFormat.DolbyVisionHdr10Plus)]
[TestCase(10, "bt2020", "smpte2084", "FFMpegCore.DoviConfigurationRecordSideData", 2, HdrFormat.DolbyVisionSdr)]
[TestCase(10, "bt2020", "smpte2084", "FFMpegCore.DoviConfigurationRecordSideData", 4, HdrFormat.DolbyVisionHlg)]
public void should_detect_hdr_correctly(int bitDepth, string colourPrimaries, string transferFunction, string sideDataTypes, int? doviConfigId, HdrFormat expected)

View File

@@ -48,13 +48,14 @@ namespace NzbDrone.Core.Test.NotificationTests
Subject.Definition = _traktDefinition;
}
private void GiventValidMediaInfo(Quality quality, string audioChannels, string audioFormat, string scanType)
private void GiventValidMediaInfo(Quality quality, string audioChannels, string audioFormat, string scanType, HdrFormat hdrFormat = HdrFormat.None)
{
_downloadMessage.MovieFile.MediaInfo = new MediaInfoModel
{
AudioChannelPositions = audioChannels,
AudioFormat = audioFormat,
ScanType = scanType
ScanType = scanType,
VideoHdrFormat = hdrFormat
};
_downloadMessage.MovieFile.Quality.Quality = quality;
@@ -72,7 +73,7 @@ namespace NzbDrone.Core.Test.NotificationTests
[Test]
public void should_add_collection_movie_if_valid_mediainfo()
{
GiventValidMediaInfo(Quality.Bluray1080p, "5.1", "DTS", "Progressive");
GiventValidMediaInfo(Quality.Bluray2160p, "5.1", "DTS", "Progressive", HdrFormat.DolbyVisionHdr10);
Subject.OnDownload(_downloadMessage);
@@ -80,15 +81,16 @@ namespace NzbDrone.Core.Test.NotificationTests
.Verify(v => v.AddToCollection(It.Is<TraktCollectMoviesResource>(t =>
t.Movies.First().Audio == "dts" &&
t.Movies.First().AudioChannels == "5.1" &&
t.Movies.First().Resolution == "hd_1080p" &&
t.Movies.First().MediaType == "bluray"),
t.Movies.First().Resolution == "uhd_4k" &&
t.Movies.First().MediaType == "bluray" &&
t.Movies.First().Hdr == "hdr10"),
It.IsAny<string>()), Times.Once());
}
[Test]
public void should_format_audio_channels_to_one_decimal_when_adding_collection_movie()
{
GiventValidMediaInfo(Quality.Bluray1080p, "2.0", "DTS", "Progressive");
GiventValidMediaInfo(Quality.Bluray2160p, "2.0", "DTS", "Progressive", HdrFormat.DolbyVisionHdr10);
Subject.OnDownload(_downloadMessage);
@@ -96,8 +98,9 @@ namespace NzbDrone.Core.Test.NotificationTests
.Verify(v => v.AddToCollection(It.Is<TraktCollectMoviesResource>(t =>
t.Movies.First().Audio == "dts" &&
t.Movies.First().AudioChannels == "2.0" &&
t.Movies.First().Resolution == "hd_1080p" &&
t.Movies.First().MediaType == "bluray"),
t.Movies.First().Resolution == "uhd_4k" &&
t.Movies.First().MediaType == "bluray" &&
t.Movies.First().Hdr == "hdr10"),
It.IsAny<string>()), Times.Once());
}
}

View File

@@ -9,8 +9,8 @@ namespace NzbDrone.Core.Datastore
{
public interface IConnectionStringFactory
{
string MainDbConnectionString { get; }
string LogDbConnectionString { get; }
DatabaseConnectionInfo MainDbConnection { get; }
DatabaseConnectionInfo LogDbConnection { get; }
string GetDatabasePath(string connectionString);
}
@@ -22,15 +22,15 @@ namespace NzbDrone.Core.Datastore
{
_configFileProvider = configFileProvider;
MainDbConnectionString = _configFileProvider.PostgresHost.IsNotNullOrWhiteSpace() ? GetPostgresConnectionString(_configFileProvider.PostgresMainDb) :
MainDbConnection = _configFileProvider.PostgresHost.IsNotNullOrWhiteSpace() ? GetPostgresConnectionString(_configFileProvider.PostgresMainDb) :
GetConnectionString(appFolderInfo.GetDatabase());
LogDbConnectionString = _configFileProvider.PostgresHost.IsNotNullOrWhiteSpace() ? GetPostgresConnectionString(_configFileProvider.PostgresLogDb) :
LogDbConnection = _configFileProvider.PostgresHost.IsNotNullOrWhiteSpace() ? GetPostgresConnectionString(_configFileProvider.PostgresLogDb) :
GetConnectionString(appFolderInfo.GetLogDatabase());
}
public string MainDbConnectionString { get; private set; }
public string LogDbConnectionString { get; private set; }
public DatabaseConnectionInfo MainDbConnection { get; private set; }
public DatabaseConnectionInfo LogDbConnection { get; private set; }
public string GetDatabasePath(string connectionString)
{
@@ -39,7 +39,7 @@ namespace NzbDrone.Core.Datastore
return connectionBuilder.DataSource;
}
private static string GetConnectionString(string dbPath)
private static DatabaseConnectionInfo GetConnectionString(string dbPath)
{
var connectionBuilder = new SQLiteConnectionStringBuilder
{
@@ -57,21 +57,22 @@ namespace NzbDrone.Core.Datastore
connectionBuilder.Add("Full FSync", true);
}
return connectionBuilder.ConnectionString;
return new DatabaseConnectionInfo(DatabaseType.SQLite, connectionBuilder.ConnectionString);
}
private string GetPostgresConnectionString(string dbName)
private DatabaseConnectionInfo GetPostgresConnectionString(string dbName)
{
var connectionBuilder = new NpgsqlConnectionStringBuilder();
var connectionBuilder = new NpgsqlConnectionStringBuilder
{
Database = dbName,
Host = _configFileProvider.PostgresHost,
Username = _configFileProvider.PostgresUser,
Password = _configFileProvider.PostgresPassword,
Port = _configFileProvider.PostgresPort,
Enlist = false
};
connectionBuilder.Database = dbName;
connectionBuilder.Host = _configFileProvider.PostgresHost;
connectionBuilder.Username = _configFileProvider.PostgresUser;
connectionBuilder.Password = _configFileProvider.PostgresPassword;
connectionBuilder.Port = _configFileProvider.PostgresPort;
connectionBuilder.Enlist = false;
return connectionBuilder.ConnectionString;
return new DatabaseConnectionInfo(DatabaseType.PostgreSQL, connectionBuilder.ConnectionString);
}
}
}

View File

@@ -0,0 +1,14 @@
namespace NzbDrone.Core.Datastore
{
public class DatabaseConnectionInfo
{
public DatabaseConnectionInfo(DatabaseType databaseType, string connectionString)
{
DatabaseType = databaseType;
ConnectionString = connectionString;
}
public DatabaseType DatabaseType { get; internal set; }
public string ConnectionString { get; internal set; }
}
}

View File

@@ -2,6 +2,7 @@ using System;
using System.Data.Common;
using System.Data.SQLite;
using System.Net.Sockets;
using System.Threading;
using NLog;
using Npgsql;
using NzbDrone.Common.Disk;
@@ -60,22 +61,22 @@ namespace NzbDrone.Core.Datastore
public IDatabase Create(MigrationContext migrationContext)
{
string connectionString;
DatabaseConnectionInfo connectionInfo;
switch (migrationContext.MigrationType)
{
case MigrationType.Main:
{
connectionString = _connectionStringFactory.MainDbConnectionString;
CreateMain(connectionString, migrationContext);
connectionInfo = _connectionStringFactory.MainDbConnection;
CreateMain(connectionInfo.ConnectionString, migrationContext, connectionInfo.DatabaseType);
break;
}
case MigrationType.Log:
{
connectionString = _connectionStringFactory.LogDbConnectionString;
CreateLog(connectionString, migrationContext);
connectionInfo = _connectionStringFactory.LogDbConnection;
CreateLog(connectionInfo.ConnectionString, migrationContext, connectionInfo.DatabaseType);
break;
}
@@ -90,14 +91,14 @@ namespace NzbDrone.Core.Datastore
{
DbConnection conn;
if (connectionString.Contains(".db"))
if (connectionInfo.DatabaseType == DatabaseType.SQLite)
{
conn = SQLiteFactory.Instance.CreateConnection();
conn.ConnectionString = connectionString;
conn.ConnectionString = connectionInfo.ConnectionString;
}
else
{
conn = new NpgsqlConnection(connectionString);
conn = new NpgsqlConnection(connectionInfo.ConnectionString);
}
conn.Open();
@@ -107,12 +108,12 @@ namespace NzbDrone.Core.Datastore
return db;
}
private void CreateMain(string connectionString, MigrationContext migrationContext)
private void CreateMain(string connectionString, MigrationContext migrationContext, DatabaseType databaseType)
{
try
{
_restoreDatabaseService.Restore();
_migrationController.Migrate(connectionString, migrationContext);
_migrationController.Migrate(connectionString, migrationContext, databaseType);
}
catch (SQLiteException e)
{
@@ -135,15 +136,17 @@ namespace NzbDrone.Core.Datastore
{
Logger.Error(e, "Failure to connect to Postgres DB, {0} retries remaining", retryCount);
Thread.Sleep(5000);
try
{
_migrationController.Migrate(connectionString, migrationContext);
_migrationController.Migrate(connectionString, migrationContext, databaseType);
return;
}
catch (Exception ex)
{
if (--retryCount > 0)
{
System.Threading.Thread.Sleep(5000);
continue;
}
@@ -162,11 +165,11 @@ namespace NzbDrone.Core.Datastore
}
}
private void CreateLog(string connectionString, MigrationContext migrationContext)
private void CreateLog(string connectionString, MigrationContext migrationContext, DatabaseType databaseType)
{
try
{
_migrationController.Migrate(connectionString, migrationContext);
_migrationController.Migrate(connectionString, migrationContext, databaseType);
}
catch (SQLiteException e)
{
@@ -186,7 +189,7 @@ namespace NzbDrone.Core.Datastore
Logger.Error("Unable to recreate logging database automatically. It will need to be removed manually.");
}
_migrationController.Migrate(connectionString, migrationContext);
_migrationController.Migrate(connectionString, migrationContext, databaseType);
}
catch (Exception e)
{

View File

@@ -87,7 +87,7 @@ namespace NzbDrone.Core.Datastore
}
/// <summary>
/// Visits the memeber access expression. To be implemented by user.
/// Visits the member access expression. To be implemented by user.
/// </summary>
/// <param name="expression"></param>
/// <returns></returns>

View File

@@ -14,7 +14,7 @@ namespace NzbDrone.Core.Datastore.Migration.Framework
{
public interface IMigrationController
{
void Migrate(string connectionString, MigrationContext migrationContext);
void Migrate(string connectionString, MigrationContext migrationContext, DatabaseType databaseType);
}
public class MigrationController : IMigrationController
@@ -29,7 +29,7 @@ namespace NzbDrone.Core.Datastore.Migration.Framework
_migrationLoggerProvider = migrationLoggerProvider;
}
public void Migrate(string connectionString, MigrationContext migrationContext)
public void Migrate(string connectionString, MigrationContext migrationContext, DatabaseType databaseType)
{
var sw = Stopwatch.StartNew();
@@ -37,7 +37,7 @@ namespace NzbDrone.Core.Datastore.Migration.Framework
ServiceProvider serviceProvider;
var db = connectionString.Contains(".db") ? "sqlite" : "postgres";
var db = databaseType == DatabaseType.SQLite ? "sqlite" : "postgres";
serviceProvider = new ServiceCollection()
.AddLogging(b => b.AddNLog())

View File

@@ -108,7 +108,7 @@ namespace NzbDrone.Core.DecisionEngine
private int ComparePeersIfTorrent(DownloadDecision x, DownloadDecision y)
{
// Different protocols should get caught when checking the preferred protocol,
// since we're dealing with the same movie in our comparisions
// since we're dealing with the same movie in our comparisons
if (x.RemoteMovie.Release.DownloadProtocol != DownloadProtocol.Torrent ||
y.RemoteMovie.Release.DownloadProtocol != DownloadProtocol.Torrent)
{

View File

@@ -78,7 +78,12 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
return false;
}
_logger.Debug("New item has a better custom format score");
_logger.Debug("New item's custom formats [{0}] ({1}) improve on [{2}] ({3}), accepting",
newCustomFormats.ConcatToString(),
newFormatScore,
currentCustomFormats.ConcatToString(),
currentFormatScore);
return true;
}

View File

@@ -78,7 +78,7 @@ namespace NzbDrone.Core.Download.Clients.Flood
}
}
return result;
return result.Where(t => t.IsNotNullOrWhiteSpace());
}
public override string Name => "Flood";

View File

@@ -141,7 +141,8 @@ namespace NzbDrone.Core.Download.Clients.Transmission
private TransmissionResponse GetSessionVariables(TransmissionSettings settings)
{
// Retrieve transmission information such as the default download directory, bandwith throttling and seed ratio.
// Retrieve transmission information such as the default download directory, bandwidth throttling and seed ratio.
return ProcessRequest("session-get", null, settings);
}

View File

@@ -40,7 +40,8 @@ namespace NzbDrone.Core.Extras.Metadata
foreach (var possibleMetadataFile in filterResult.FilesOnDisk)
{
// Don't process files that have known Subtitle file extensions (saves a bit of unecessary processing)
// Don't process files that have known Subtitle file extensions (saves a bit of unnecessary processing)
if (SubtitleFileExtensions.Extensions.Contains(Path.GetExtension(possibleMetadataFile)))
{
continue;

View File

@@ -13,15 +13,33 @@ namespace NzbDrone.Core.Housekeeping.Housekeepers
}
public void Clean()
{
CleanupOrphanedByImportLists();
CleanupOrphanedByMovieMetadata();
}
private void CleanupOrphanedByImportLists()
{
using var mapper = _database.OpenConnection();
mapper.Execute(@"DELETE FROM ""ImportListMovies""
WHERE ""Id"" IN (
SELECT ""ImportListMovies"".""Id"" FROM ""ImportListMovies""
LEFT OUTER JOIN ""ImportLists""
ON ""ImportListMovies"".""ListId"" = ""ImportLists"".""Id""
WHERE ""ImportLists"".""Id"" IS NULL)");
WHERE ""Id"" IN (
SELECT ""ImportListMovies"".""Id""
FROM ""ImportListMovies""
LEFT OUTER JOIN ""ImportLists"" ON ""ImportListMovies"".""ListId"" = ""ImportLists"".""Id""
WHERE ""ImportLists"".""Id"" IS NULL)");
}
private void CleanupOrphanedByMovieMetadata()
{
using var mapper = _database.OpenConnection();
mapper.Execute(@"DELETE FROM ""ImportListMovies""
WHERE ""Id"" IN (
SELECT ""ImportListMovies"".""Id""
FROM ""ImportListMovies""
LEFT OUTER JOIN ""MovieMetadata"" ON ""ImportListMovies"".""MovieMetadataId"" = ""MovieMetadata"".""Id""
WHERE ""MovieMetadata"".""Id"" IS NULL)");
}
}
}

View File

@@ -93,7 +93,7 @@ namespace NzbDrone.Core.ImportLists
if (excludedMovie != null)
{
_logger.Debug("{0} [{1}] Rejected due to list exlcusion", report.TmdbId, report.Title);
_logger.Debug("{0} [{1}] Rejected due to list exclusion", report.TmdbId, report.Title);
return;
}

View File

@@ -48,13 +48,11 @@ namespace NzbDrone.Core.Indexers.Newznab
{
yield return GetDefinition("DOGnzb", GetSettings("https://api.dognzb.cr"));
yield return GetDefinition("DrunkenSlug", GetSettings("https://drunkenslug.com"));
yield return GetDefinition("Nzb-Tortuga", GetSettings("https://www.nzb-tortuga.com"));
yield return GetDefinition("Nzb.su", GetSettings("https://api.nzb.su"));
yield return GetDefinition("NZBCat", GetSettings("https://nzb.cat"));
yield return GetDefinition("NZBFinder.ws", GetSettings("https://nzbfinder.ws", categories: new[] { 2030, 2040, 2045, 2050, 2060, 2070, 2080, 2090 }));
yield return GetDefinition("NZBFinder.ws", GetSettings("https://nzbfinder.ws", categories: new[] { 2030, 2040, 2045, 2050, 2060, 2070 }));
yield return GetDefinition("NZBgeek", GetSettings("https://api.nzbgeek.info"));
yield return GetDefinition("nzbplanet.net", GetSettings("https://api.nzbplanet.net"));
yield return GetDefinition("OZnzb.com", GetSettings("https://api.oznzb.com"));
yield return GetDefinition("SimplyNZBs", GetSettings("https://simplynzbs.com"));
yield return GetDefinition("Tabula Rasa", GetSettings("https://www.tabula-rasa.pw", apiPath: @"/api/v1/api"));
yield return GetDefinition("Usenet Crawler", GetSettings("https://www.usenet-crawler.com"));

View File

@@ -91,6 +91,10 @@ namespace NzbDrone.Core.Indexers.PassThePopcorn
Scene = torrent.Scene,
Approved = torrent.Checked,
ImdbId = result.ImdbId.IsNotNullOrWhiteSpace() ? int.Parse(result.ImdbId) : 0,
Source = torrent.Source,
Container = torrent.Container,
Codec = torrent.Codec,
Resolution = torrent.Resolution,
IndexerFlags = flags
});
}

View File

@@ -88,16 +88,15 @@ namespace NzbDrone.Core.Instrumentation
log.Level = logEvent.Level.Name;
var connectionString = _connectionStringFactory.LogDbConnectionString;
var connectionInfo = _connectionStringFactory.LogDbConnection;
// TODO: Probably need more robust way to differentiate what's being used
if (connectionString.Contains(".db"))
if (connectionInfo.DatabaseType == DatabaseType.SQLite)
{
WriteSqliteLog(log, connectionString);
WriteSqliteLog(log, connectionInfo.ConnectionString);
}
else
{
WritePostgresLog(log, connectionString);
WritePostgresLog(log, connectionInfo.ConnectionString);
}
}
catch (NpgsqlException ex)
@@ -136,8 +135,10 @@ namespace NzbDrone.Core.Instrumentation
private void WriteSqliteLog(Log log, string connectionString)
{
using (var connection =
new SQLiteConnection(connectionString).OpenAndReturn())
SQLiteFactory.Instance.CreateConnection())
{
connection.ConnectionString = connectionString;
connection.Open();
using (var sqlCommand = connection.CreateCommand())
{
sqlCommand.CommandText = INSERT_COMMAND;

View File

@@ -301,7 +301,7 @@
"UsenetDelayHelpText": "Verzögerung in Minuten before ein Usenet-Release erfasst wird",
"WhitelistedHardcodedSubsHelpText": "Hier gesetzte Untertitel Tags werden nciht als hartcodiert erachtet",
"EnableAutoHelpText": "Wenn aktiviert werden Filme dieser Liste automatisch hinzugefügt",
"AddImportExclusionHelpText": "Automatisches ( wieder- ) hinzufügen durch Listen verhindern",
"AddImportExclusionHelpText": "Automatisches ( wieder- ) hinzufügen zu {appName} durch Listen verhindern",
"AgeWhenGrabbed": "Alter (beim erfassen)",
"AllowHardcodedSubs": "Hartcodierte Untertitel erlauben",
"AlreadyInYourLibrary": "Bereits in deiner Mediathek",
@@ -952,12 +952,12 @@
"AptUpdater": "Benutze 'apt' um das Update zu installieren",
"Always": "Immer",
"AllResultsHiddenFilter": "Keine Ergebnisse mit den ausgewählten Filtern",
"AllMoviesInPathHaveBeenImported": "Alle Filme in {0} wurden importiert",
"AllMoviesInPathHaveBeenImported": "Alle Filme in {path} wurden importiert",
"AllFiles": "Alle Dateien",
"AfterManualRefresh": "Nach manuellen aktualisieren",
"AddToDownloadQueue": "Zur Downloadwarteschlange hinzufügen",
"AddRootFolder": "Stammordner hinzufügen",
"AddQualityProfile": "Qualitätsprofil hinzufügen",
"AddQualityProfile": "Qualitäts Profil hinzufügen",
"AddedToDownloadQueue": "Zur Downloadwarteschlange hinzugefügt",
"AddDownloadClient": "Downloadmanager hinzufügen",
"AddCustomFormat": "Eigenes Format hinzufügen",
@@ -1178,7 +1178,7 @@
"IMDbId": "TMDb ID",
"DisabledForLocalAddresses": "Für Lokale Adressen deaktivieren",
"AddCondition": "Bedingung hinzufügen",
"AddAutoTag": "Automatisches Tag hinzufügen",
"AddAutoTag": "Automatischen Tag hinzufügen",
"AppUpdated": "{appName} aktualisiert",
"AddConditionImplementation": "Bedingung hinzufügen - {implementationName}",
"AddImportList": "Importliste hinzufügen",
@@ -1189,5 +1189,16 @@
"AddConnectionImplementation": "Verbindung hinzufügen - {implementationName}",
"AddDownloadClientImplementation": "Download-Client hinzufügen - {implementationName}",
"AddIndexerImplementation": "Indexer hinzufügen - {implementationName}",
"AppUpdatedVersion": "{appName} wurde auf die Version `{version}` aktualisiert. Um die neusten Funktionen zu bekommen lade {appName} neu"
"AppUpdatedVersion": "{appName} wurde auf die Version `{version}` aktualisiert. Um die neusten Funktionen zu bekommen lade {appName} neu",
"AuthenticationRequiredPasswordConfirmationHelpTextWarning": "Neues Passwort bestätigen",
"AllTitles": "Alle Titel",
"AuthenticationRequired": "Authentifizierung benötigt",
"AuthenticationRequiredHelpText": "Ändern, welche anfragen Authentifizierung benötigen. Ändere nichts wenn du dir nicht des Risikos bewusst bist.",
"AudioLanguages": "Audio Sprachen",
"AuthenticationMethodHelpTextWarning": "Bitte wähle eine gültige Authentifizierungsmethode aus",
"AuthenticationRequiredPasswordHelpTextWarning": "Gib ein neues Passwort ein",
"AuthenticationRequiredUsernameHelpTextWarning": "Gib einen neuen Benutzernamen ein",
"AuthenticationRequiredWarning": "Um unberechtigte Fernzugriffe zu vermeiden benötigt {appName} jetzt , dass Authentifizierung eingeschaltet ist. Du kannst Authentifizierung optional für lokale Adressen ausschalten.",
"AutoRedownloadFailed": "Erneuter Download fehlgeschlagen",
"AutoRedownloadFailedFromInteractiveSearch": "Erneuter Download aus Interaktiver Suche fehlgeschlagen"
}

View File

@@ -28,7 +28,7 @@
"DownloadClientStatusCheckSingleClientMessage": "Gestores de descargas no disponibles debido a errores: {downloadClientNames}",
"DownloadClientStatusCheckAllClientMessage": "Los gestores de descargas no están disponibles debido a errores",
"DownloadClients": "Gestores de Descargas",
"DownloadClientCheckUnableToCommunicateMessage": "Incapaz de comunicarse con {downloadClientName}.",
"DownloadClientCheckUnableToCommunicateMessage": "Incapaz de comunicarse con {downloadClientName}. {errorMessage}",
"DownloadClientCheckNoneAvailableMessage": "Ningún gestor de descargas disponible",
"DiskSpace": "Espacio en Disco",
"Discover": "Descubrir",
@@ -632,15 +632,15 @@
"EnableInteractiveSearchHelpText": "Se usará cuando se utilice la búsqueda interactiva",
"EnableAutomaticSearchHelpText": "Se usará cuando las búsquedas automáticas se realicen desde el UI o por {appName}",
"EnableAutomaticSearchHelpTextWarning": "Se usará cuando se utilice la búsqueda interactiva",
"DownloadWarning": "Alerta de descarga: {0}",
"DownloadWarning": "Alerta de descarga: {warningMessage}",
"Downloading": "Descargando",
"DownloadFailed": "La descarga ha fallado",
"DownloadClientUnavailable": "El gestor de descargas no está disponible",
"DeleteTagMessageText": "¿Seguro que quieres eliminar la etiqueta '{label}'?",
"DeleteTagMessageText": "¿Está seguro de querer eliminar la etiqueta '{label}'?",
"DeleteRestrictionHelpText": "Seguro que quieres eliminar esta restricción?",
"DeleteNotificationMessageText": "¿Seguro que quieres eliminiar la notificación '{name}'?",
"DeleteNotificationMessageText": "¿Seguro que quieres eliminar la notificación '{name}'?",
"DeleteBackupMessageText": "Seguro que quieres eliminar la copia de seguridad '{name}'?",
"DeleteDownloadClientMessageText": "¿Seguro que quieres eliminar el cliente de descargas '{name}'?",
"DeleteDownloadClientMessageText": "Seguro que quieres eliminar el gestor de descargas '{name}'?",
"DeleteIndexerMessageText": "Seguro que quieres eliminar el indexer '{name}'?",
"Cutoff": "Requisito",
"ClickToChangeMovie": "Clic para cambiar película",
@@ -693,7 +693,7 @@
"MinutesSixty": "60 Minutos: {0}",
"MinutesNinety": "90 Minutos: {0}",
"MinutesHundredTwenty": "120 Minutos: {0}",
"MaintenanceRelease": "Lanzamiento de mantenimiento: arregla bugs y otras mejoras. Ve a Github Commit History para más detalles",
"MaintenanceRelease": "Lanzamiento de mantenimiento: Corrección de errores y otras mejoras. Ver historial de commits de Github para mas detalle",
"LoadingMovieFilesFailed": "La carga de los archivos ha fallado",
"LoadingMovieExtraFilesFailed": "La carga de los extras de la película ha fallado",
"LoadingMovieCreditsFailed": "La carga de los créditos de la película ha fallado",
@@ -1132,7 +1132,7 @@
"CloneCondition": "Clonar Condición",
"DeleteAutoTag": "Eliminar Etiquetado Automático",
"DeleteAutoTagHelpText": "¿Está seguro de querer eliminar el etiquetado automático '{name}'?",
"DeleteSelectedDownloadClientsMessageText": "¿Estas seguro que quieres eliminar {count} cliente(s) de descarga seleccionado(s)?",
"DeleteSelectedDownloadClientsMessageText": "¿Está seguro de querer eliminar {count} cliente(s) de descarga seleccionado(s)?",
"EditAutoTag": "Editar Etiquetado Automático",
"EditSelectedDownloadClients": "Editar Clientes de Descarga Seleccionados",
"EditSelectedIndexers": "Editar Indexadores Seleccionados",
@@ -1185,7 +1185,7 @@
"DeleteImportListMessageText": "Seguro que quieres eliminar la lista '{name}'?",
"DeleteSelectedImportListsMessageText": "Seguro que quieres eliminar {count} lista(s) de importación seleccionada(s)?",
"AppUpdatedVersion": "{appName} ha sido actualizado a la versión `{version}`, para obtener los cambios más recientes necesitará recargar {appName}",
"DeleteSelectedIndexersMessageText": "Seguro que quieres eliminar {count} indexer seleccionado(s)?",
"DeleteSelectedIndexersMessageText": "¿Está seguro de querer eliminar {count} indexador(es) seleccionado(s)?",
"DisabledForLocalAddresses": "Desactivado para direcciones locales",
"DeletedReasonManual": "El archivo fue borrado por vía UI",
"DeletedReasonMissingFromDisk": "{appName} no ha podido encontrar el archivo en el disco, por lo que se ha desvinculado de la película en la base de datos",
@@ -1204,5 +1204,32 @@
"CopyToClipboard": "Copiar al portapapeles",
"CloneCustomFormat": "Clonar formato personalizado",
"CloneProfile": "Clonar Perfil",
"Close": "Cerrar"
"Close": "Cerrar",
"DownloadClientsLoadError": "No se puden cargar los gestores de descargas",
"EditConnectionImplementation": "Editar notificación - {implementationName}",
"EditImportListImplementation": "Añadir lista de importación - {implementationName}",
"EditIndexerImplementation": "Editar indexador - {implementationName}",
"FormatShortTimeSpanHours": "{hours} hora(s)",
"FormatShortTimeSpanMinutes": "{minutes} minuto(s)",
"FormatShortTimeSpanSeconds": "{seconds} segundo(s)",
"FormatTimeSpanDays": "{days}d {time}",
"EditDownloadClientImplementation": "Añadir Cliente de Descarga - {implementationName}",
"EnableProfile": "Habilitar perfil",
"FormatAgeDay": "día",
"FormatAgeHour": "hora",
"FormatAgeHours": "horas",
"FormatAgeMinute": "minuto",
"FormatAgeMinutes": "minutos",
"FormatRuntimeHours": "{hours}h",
"FormatRuntimeMinutes": "{minutes}m",
"FormatDateTimeRelative": "{relativeDay}, {formattedDate} {formattedTime}",
"FormatDateTime": "{formattedDate} {formattedTime}",
"UnknownEventTooltip": "Evento desconocído",
"FormatAgeDays": "días",
"False": "Falso",
"DownloadIgnored": "Descarga ignorada",
"FailedToFetchUpdates": "Fallo al buscar las actualizaciones",
"FailedToUpdateSettings": "Fallo al actualizar los ajustes",
"EditConditionImplementation": "Editar Condición - {implementationName}",
"DownloadClientRemovesCompletedDownloadsHealthCheckMessage": "El cliente de descarga {downloadClientName} esta configurado para eliminar las descargas completadas. Esto puede causar que las descargas sean eliminadas del cliente antes que {1} las pueda importar."
}

View File

@@ -1,17 +1,17 @@
{
"IndexerStatusCheckAllClientMessage": "Tous les indexeurs sont indisponibles en raison d'échecs",
"IndexerSearchCheckNoInteractiveMessage": "Aucun indexeur disponible avec la recherche interactive activée, {appName} ne fournira aucun résultat de recherche interactive",
"IndexerSearchCheckNoInteractiveMessage": "Aucun indexeur disponible avec la recherche interactive activée, {appName} ne fournira aucun résultat de recherche interactif",
"IndexerSearchCheckNoAvailableIndexersMessage": "Tous les indexeurs compatibles avec la recherche sont temporairement indisponibles en raison d'erreurs d'indexation récentes",
"IndexerSearchCheckNoAutomaticMessage": "Aucun indexeur disponible avec la recherche automatique activée, {appName} ne fournira aucun résultat de recherche automatique",
"Indexers": "Indexeurs",
"ImportTipsMessage": "Quelques conseils pour assurer le bon déroulement de l'importation :",
"ImportMechanismHealthCheckMessage": "Activer la gestion des téléchargements terminés",
"ImportHeader": "Importez une bibliothèque organisée existante pour ajouter des films à {appName}",
"ImportHeader": "Importer une bibliothèque organisée existante pour ajouter des films à {appName}",
"Import": "Importer",
"iCalLink": "Lien iCal",
"Host": "Hôte",
"History": "Historique",
"HideAdvanced": "Masquer param. av.",
"HideAdvanced": "Masquer les Options Avancées",
"Health": "Santé",
"GrabSelected": "Saisir la sélection",
"General": "Général",
@@ -55,13 +55,13 @@
"AddNewMessage": "C'est facile d'ajouter un nouveau film, vous n'avez juste qu'à saisir le nom du film que vous voulez ajouter",
"AddMovies": "Ajouter des films",
"AddExclusion": "Ajouter une exclusion",
"AddNew": "Ajouter une nouvelle",
"AddNew": "Ajouter un élément",
"Activity": "Activité",
"About": "À propos",
"CustomFormatsSettingsSummary": "Paramètres de formats personnalisés",
"IndexerStatusCheckSingleClientMessage": "Indexeurs indisponibles en raison d'échecs : {indexerNames}",
"DownloadClientStatusCheckSingleClientMessage": "Clients de Téléchargement indisponibles en raison d'échecs: {downloadClientNames}",
"SetTags": "Définir des balises",
"SetTags": "Définir des étiquettes",
"ReleaseTitle": "Titre de la version",
"ReleaseStatus": "Statut de la version",
"ReleaseGroup": "Groupe de versions",
@@ -71,7 +71,7 @@
"UnselectAll": "Tout désélectionner",
"Unmonitored": "Non surveillé",
"UISettingsSummary": "Calendrier, date et les options d'altération des couleurs",
"TagsSettingsSummary": "Voir toutes les balises et comment elles sont utilisées. Les balises inutilisées peuvent être supprimées",
"TagsSettingsSummary": "Voir toutes les étiquettes et comment elles sont utilisées. Les étiquettes inutilisées peuvent être supprimées",
"Style": "Style",
"Studio": "Studio",
"Status": "État",
@@ -99,7 +99,7 @@
"Restrictions": "Restrictions",
"RestoreBackup": "Restaurer la sauvegarde",
"RenameFiles": "Renommer les fichiers",
"Renamed": "Renommer",
"Renamed": "Renommé",
"RemoveSelected": "Enlever la sélection",
"RemovedMovieCheckSingleMessage": "Le film {movie} a été supprimé de TMDb",
"RemovedMovieCheckMultipleMessage": "Les films {movies} ont été supprimés de TMDb",
@@ -141,7 +141,7 @@
"MountCheckMessage": "Le montage contenant un chemin de film est monté en lecture seule: ",
"MoreInfo": "Plus d'informations",
"Month": "Mois",
"ListsSettingsSummary": "Importer listes, listes d'exclusions",
"ListsSettingsSummary": "Importer des Listes, exclure des listes",
"ListExclusions": "Liste des exclusions",
"IndexersSettingsSummary": "Indexeurs et restrictions de version",
"Grabbed": "Saisie",
@@ -235,7 +235,7 @@
"RejectionCount": "Nombre de rejets",
"Peers": "Peers",
"Organize": "Organiser",
"Ok": "Ok",
"Ok": "OK",
"OAuthPopupMessage": "Les pop-ups sont bloquées par votre navigateur",
"Name": "Nom",
"MoveFiles": "Déplacer des fichiers",
@@ -248,7 +248,7 @@
"NoIssuesWithYourConfiguration": "Aucun problème avec votre configuration",
"HardlinkCopyFiles": "Lien physique/Copie de fichiers",
"Extension": "Extension",
"CustomFormatScore": "Partition au format personnalisé",
"CustomFormatScore": "Score du format personnalisé",
"SystemTimeCheckMessage": "L'heure du système est décalée de plus d'un jour. Les tâches planifiées peuvent ne pas s'exécuter correctement tant que l'heure ne sera pas corrigée",
"ShowMonitored": "Afficher le chemin",
"SettingsWeekColumnHeaderHelpText": "Affiché au dessus de chaque colonne quand \"Semaine\" est l'affichage actif",
@@ -282,7 +282,7 @@
"SearchMovie": "Rechercher le film",
"RecentFolders": "Dossiers récents",
"QuickImport": "Déplacer automatiquement",
"PosterSize": "Poster taille",
"PosterSize": "Taille des affiches",
"Posters": "Affiches",
"PosterOptions": "Poster options",
"PendingChangesStayReview": "Rester et vérifier les modifications",
@@ -415,7 +415,7 @@
"BranchUpdateMechanism": "Branche utilisée par le mécanisme de mise à jour extérieur",
"BranchUpdate": "Branche à utiliser pour mettre à jour {appName}",
"BeforeUpdate": "Avant la mise à jour",
"ApplyTagsHelpTextHowToApplyMovies": "Comment appliquer des tags au film sélectionné",
"ApplyTagsHelpTextHowToApplyMovies": "Comment appliquer des étiquettes aux films sélectionnés",
"DeleteDownloadClientMessageText": "Voulez-vous supprimer le client de téléchargement « {name} » ?",
"DeleteBackupMessageText": "Voulez-vous supprimer la sauvegarde « {name} » ?",
"ErrorLoadingContents": "Erreur lors du chargement du contenu",
@@ -543,15 +543,15 @@
"GrabReleaseMessageText": "{appName} n'a pas été en mesure de déterminer à quel film cette version était destinée. {appName} peut être incapable d'importer automatiquement cette version. Voulez-vous récupérer '{0}' ?",
"ExtraFileExtensionsHelpTexts1": "Liste séparée par des virgules des fichiers supplémentaires à importer (.nfo sera importé en tant que .nfo-orig)",
"YouCanAlsoSearch": "Vous pouvez également effectuer une recherche à l'aide de l'ID TMDb ou de l'ID IMDb d'un film. par exemple : `tmdb:71663`",
"WhitelistedSubtitleTags": "Balises de sous-titres sur liste blanche",
"WhitelistedHardcodedSubsHelpText": "Les balises de sous-titres définies ici ne seront pas considérées comme codées en dur",
"WhitelistedSubtitleTags": "Étiquettes de sous-titres sur liste blanche",
"WhitelistedHardcodedSubsHelpText": "Les étiquettes de sous-titres définies ici ne seront pas considérées comme codées en dur",
"WeekColumnHeader": "En-tête de colonne de la semaine",
"UsenetDelayHelpText": "Délai en minutes avant de récupérer une release de Usenet",
"Uptime": "Disponibilité",
"UpgradeUntilThisQualityIsMetOrExceeded": "Mise à niveau jusqu'à ce que cette qualité soit atteinte ou dépassée",
"UpgradeAllowedHelpText": "Si désactivé, les qualités ne seront pas améliorées",
"UpdateScriptPathHelpText": "Chemin d'accès à un script personnalisé qui prend un package de mise à jour extrait et gère le reste du processus de mise à jour",
"UpdateMechanismHelpText": "Utiliser le programme de mise à jour intégré de {appName} ou un script",
"UpdateMechanismHelpText": "Utilisez le programme de mise à jour intégré de {appName} ou un script",
"UpdateAutomaticallyHelpText": "Téléchargez et installez automatiquement les mises à jour. Vous pourrez toujours installer à partir du système : mises à jour",
"Unreleased": "Version non disponible",
"UnmonitoredHelpText": "Inclure les films non surveillés dans le flux iCal",
@@ -843,7 +843,7 @@
"Hours": "Heures",
"HomePage": "Page d'accueil",
"HttpHttps": "HTTP(S)",
"ImportLibrary": "Import bibliothèque",
"ImportLibrary": "Importer biblio.",
"MovieIsRecommend": "Le film est recommandé en fonction de l'ajout récent",
"NoAltTitle": "Pas de titres alternatifs.",
"NoLinks": "Aucun liens",
@@ -1034,7 +1034,7 @@
"OriginalLanguage": "Langue originale",
"Rating": "Notation",
"RemotePath": "Chemin distant",
"RemotePathMappingCheckFilesBadDockerPath": "Vous utilisez docker; {0} signifie les téléchargement dans {1} mais ce n'est pas un dossier valide. Vérifiez vos paramètres de dossier distant et les paramètres de votre client de téléchargement.",
"RemotePathMappingCheckFilesBadDockerPath": "Vous utilisez Docker ; le client de téléchargement {downloadClientName} a signalé des fichiers dans {path}, mais ce n'est pas un chemin valide pour {osName}. Vérifiez vos mappages de chemins distants et les paramètres de votre client de téléchargement.",
"RemotePathMappingCheckWrongOSPath": "Le client de téléchargement distant {downloadClientName} met les téléchargements dans {path} mais ce chemin {osName} est invalide. Vérifiez vos paramètres de chemins distants et les paramètres de votre client de téléchargement.",
"RemoveCompleted": "Supprimer terminé",
"Database": "Base de données",
@@ -1238,7 +1238,7 @@
"MovieImported": "Film importé",
"SelectDropdown": "Sélectionner...",
"SelectLanguageModalTitle": "{modalTitle} Sélectionner la langue",
"RemoveTagsAutomatically": "Supprimer les balises automatiquement",
"RemoveTagsAutomatically": "Supprimer automatiquement les étiquettes",
"TablePageSizeHelpText": "Nombre d'éléments à afficher sur chaque page",
"UnknownEventTooltip": "Événement inconnu",
"AppUpdated": "{appName} mis à jour",
@@ -1254,8 +1254,8 @@
"OrganizeLoadError": "Erreur lors du chargement des aperçus",
"EditImportListImplementation": "Modifier la liste d'importation - {implementationName}",
"EditIndexerImplementation": "Modifier l'indexeur - {implementationName}",
"MovieFileDeleted": "À la suppression d'un fichier vidéo",
"MovieFileDeletedTooltip": "À la suppression d'un fichier vidéo",
"MovieFileDeleted": "Fichier du film supprimé",
"MovieFileDeletedTooltip": "Fichier du film supprimé",
"BlocklistReleaseHelpText": "Empêche {appName} de récupérer automatiquement cette version",
"InteractiveImportLoadError": "Impossible de charger les éléments d'importation manuelle",
"MovieSearchResultsLoadError": "Impossible de charger les résultats de cette recherche de films. Réessayez plus tard",
@@ -1322,7 +1322,7 @@
"MovieGrabbedHistoryTooltip": "Film extrait de {indexer} et envoyé à {downloadClient}",
"RemoveQueueItem": "Supprimer {sourceTitle}",
"OverrideGrabModalTitle": "Remplacer et récupérer - {title}",
"RemoveTagsAutomaticallyHelpText": "Supprimez automatiquement les balises si les conditions ne sont pas remplies",
"RemoveTagsAutomaticallyHelpText": "Supprimez automatiquement les étiquettes si les conditions ne sont pas remplies",
"InfoUrl": "URL d'informations",
"ListRefreshInterval": "Intervalle d'actualisation de la liste",
"Parse": "Analyser",

View File

@@ -1 +1,15 @@
{}
{
"About": "Par",
"AcceptConfirmationModal": "Apstiprināt Apstiprināšanas Modālu",
"Actions": "Darbības",
"Activity": "Aktivitāte",
"Add": "Pievienot",
"AddAutoTag": "Pievienot Automātisko Tagu",
"AddCondition": "Pievienot Nosacījumu",
"AddCustomFormat": "Pievienot Pielāgotu Formātu",
"AddConditionImplementation": "Pievienot Nosacījumu - {implementationName}",
"AddConnection": "Pievienot Savienojumu",
"AddConnectionImplementation": "Pievienot Savienojumu - {implementationName}",
"AddDelayProfile": "Pievienot Aizkaves Profilu",
"AddDownloadClient": "Pievienot Lejupielādes Klientu"
}

View File

@@ -58,7 +58,7 @@
"AddNewTmdbIdMessage": "Je kunt ook zoeken met het TMDb id van een film. Bijv. tmdb:71663",
"AddNewMessage": "Het is gemakkelijk om een nieuwe film toe te voegen, begin gewoon met de naam te typen van de film die je wilt toevoegen",
"AddNew": "Nieuwe toevoegen",
"AddExclusion": "Uitzondering toevoegen",
"AddExclusion": "Uitzondering Toevoegen",
"AddMovies": "Film(s) Toevoegen",
"Activity": "Activiteit",
"About": "Over",
@@ -645,9 +645,9 @@
"DeleteTagMessageText": "Bent u zeker dat u de tag '{0}' wilt verwijderen?",
"DeleteRestrictionHelpText": "Bent u zeker dat u deze restrictie wilt verwijderen?",
"DeleteNotificationMessageText": "Bent u zeker dat u de notificatie '{0}' wilt verwijderen?",
"DeleteIndexerMessageText": "Bent u zeker dat u de indexeerder '{0}' wilt verwijderen?",
"DeleteDownloadClientMessageText": "Bent u zeker dat u de downloader '{0}' wilt verwijderen?",
"DeleteBackupMessageText": "Bent u zeker dat u de veiligheidskopie '{0}' wilt verwijderen?",
"DeleteIndexerMessageText": "Bent u zeker dat u de indexeerder '{name}' wilt verwijderen?",
"DeleteDownloadClientMessageText": "Bent u zeker dat u de downloader '{name}' wilt verwijderen?",
"DeleteBackupMessageText": "Bent u zeker dat u de veiligheidskopie '{name}' wilt verwijderen?",
"Cutoff": "Drempel",
"ClickToChangeMovie": "Klik om film te wijzigen",
"CheckDownloadClientForDetails": "controleer downloader voor meer details",
@@ -692,7 +692,7 @@
"ForMoreInformationOnTheIndividualDownloadClients": "Voor meer informatie over de individuele download applicaties, klik op de info knoppen.",
"FailedLoadingSearchResults": "Laden van zoekresultaten is mislukt, gelieve opnieuw te proberen.",
"ExtraFileExtensionsHelpTexts1": "Komma gescheiden lijst met extra bestanden om te importeren (.nfo zal als .nfo-orig worden geïmporteerd)",
"CouldNotFindResults": "Kon geen resultaten vinden voor '{0}'",
"CouldNotFindResults": "Kon geen resultaten vinden voor '{term}'",
"ApplyTagsHelpTextHowToApplyMovies": "Hoe tags toe te passen op de geselecteerd films",
"BackupsLoadError": "Kon geen veiligheidskopieën laden",
"TagIsNotUsedAndCanBeDeleted": "Tag is niet in gebruik en kan verwijderd worden",
@@ -1102,10 +1102,10 @@
"DownloadClientTagHelpText": "Gebruik deze indexer alleen voor films met ten minste één overeenkomende tag. Laat leeg om te gebruiken met alle films.",
"DeleteDelayProfileMessageText": "Weet u zeker dat u dit vertragingsprofiel wilt verwijderen?",
"RemoveSelectedItemQueueMessageText": "Weet je zeker dat je {0} van de wachtrij wilt verwijderen?",
"CountIndexersSelected": "{0} Indexer(s) Geselecteerd",
"CountIndexersSelected": "{count} Indexer(s) Geselecteerd",
"DeleteSelectedIndexers": "Verwijder Indexeerder",
"ResetAPIKeyMessageText": "Bent u zeker dat u uw API-sleutel wilt resetten?",
"DeleteConditionMessageText": "Bent u zeker dat u de lijst '{0}' wilt verwijderen?",
"DeleteConditionMessageText": "Bent u zeker dat u de lijst '{name}' wilt verwijderen?",
"DeleteCustomFormatMessageText": "Bent u zeker dat u de indexeerder '{customFormatName}' wilt verwijderen?",
"DeleteFormatMessageText": "Weet je zeker dat je formaat tag {0} wilt verwijderen?",
"DeleteImportListExclusionMessageText": "Bent u zeker dat u dit van de uitzonderingenlijst wilt verwijderen?",
@@ -1128,7 +1128,7 @@
"AddConditionImplementation": "Voeg voorwaarde toe - {implementationName}",
"AddConnection": "Voeg connectie toe",
"AddConnectionImplementation": "Voeg connectie toe - {implementationName}",
"AddDownloadClientImplementation": "Voeg Downloadclient toe - {implementationName}",
"AddDownloadClientImplementation": "Voeg Downloadclient Toe - {implementationName}",
"AddIndexerImplementation": "Indexeerder toevoegen - {implementationName}",
"DeleteQualityProfileMessageText": "Bent u zeker dat u het kwaliteitsprofiel {name} wilt verwijderen?",
"AppUpdated": "{appName} is geüpdatet",

View File

@@ -274,7 +274,7 @@
"Cancel": "Cancelar",
"Calendar": "Calendário",
"BackupNow": "Criar cópia de segurança",
"Backup": "Cópia de segurança",
"Backup": "Backup",
"AudioInfo": "Informações do áudio",
"Apply": "Aplicar",
"Analytics": "Análise",
@@ -468,7 +468,7 @@
"BindAddressHelpText": "Endereço de IP válido, localhost ou \"*\" para todas as interfaces",
"BindAddress": "Endereço de vínculo",
"Backups": "Cópias de segurança",
"BackupFolderHelpText": "Caminhos relativos estarão na pasta AppData do {appName}",
"BackupFolderHelpText": "Caminhos relativos estarão no diretório AppData do {appName}",
"BackupIntervalHelpText": "Intervalo entre cópias de segurança automáticas",
"BackupRetentionHelpText": "Cópias de segurança automáticas anteriores ao período de retenção serão eliminadas automaticamente",
"Cutoff": "Limite",
@@ -1189,5 +1189,6 @@
"DeleteImportList": "Eliminar Lista de Importação",
"DeleteImportListMessageText": "Tem a certeza de que pretende eliminar a lista '{name}'?",
"DownloadClientRemovesCompletedDownloadsHealthCheckMessage": "O cliente de descarregamento {downloadClientName} está definido para remover descarregamentos concluídos. Isto pode fazer com que as transferências sejam removidas do seu cliente antes de {1} as poder importar.",
"AppUpdated": "{appName} Atualizado"
"AppUpdated": "{appName} Atualizado",
"AuthenticationRequiredPasswordConfirmationHelpTextWarning": "Confirmar nova senha"
}

View File

@@ -1006,6 +1006,9 @@
"DeleteRemotePathMappingMessageText": "Bu uzak yol eşlemesini silmek istediğinizden emin misiniz?",
"AddAutoTag": "Otomatik Etiket Ekle",
"AddCondition": "Koşul Ekle",
"AddConditionImplementation": "Koşul Ekle - {uygulama Adı}",
"AddConnection": "Bağlantı Ekle"
"AddConditionImplementation": "Koşul Ekle - {implementationName}",
"AddConnection": "Bağlantı Ekle",
"AddIndexerImplementation": "Koşul Ekle - {implementationName}",
"AddConnectionImplementation": "Koşul Ekle - {implementationName}",
"EditIndexerImplementation": "Koşul Ekle - {implementationName}"
}

View File

@@ -1,6 +1,6 @@
{
"About": "关于",
"DownloadClientCheckUnableToCommunicateMessage": "无法与{downloadClientName}进行通讯",
"DownloadClientCheckUnableToCommunicateMessage": "无法与{downloadClientName}进行通讯{errorMessage}",
"DownloadClientCheckNoneAvailableMessage": "无可用的下载客户端",
"DownloadClient": "下载客户端",
"Donations": "赞助",
@@ -70,7 +70,7 @@
"AuthForm": "表单(登陆页面)",
"AuthBasic": "基础(浏览器弹出对话框)",
"AppDataDirectory": "AppData目录",
"ApiKey": "API Key",
"ApiKey": "接口密钥 (API Key)",
"Backups": "历史备份",
"BindAddress": "绑定地址",
"BranchUpdate": "更新{appName}的分支",
@@ -294,7 +294,7 @@
"Monday": "星期一",
"MissingNotMonitored": "缺少(未监控)",
"MissingMonitoredAndConsideredAvailable": "缺少(监控中)",
"Missing": "缺",
"Missing": "缺",
"MinutesSixty": "60分钟: {0}",
"MinutesNinety": "90分钟: {0}",
"MinutesHundredTwenty": "120分钟: {0}",
@@ -394,8 +394,8 @@
"Ended": "已完结",
"Error": "错误",
"EnableSslHelpText": " 重启生效",
"EnableSSL": "启用SSL",
"EnableRSS": "启用RSS",
"EnableSSL": "启用 SSL",
"EnableRSS": "启用 RSS",
"EnableInteractiveSearchHelpTextWarning": "该索引器不支持搜索",
"EnableInteractiveSearchHelpText": "当手动搜索启用时使用",
"EnableInteractiveSearch": "启用手动搜索",
@@ -735,7 +735,7 @@
"ReleaseRejected": "发布被拒绝",
"UnmappedFilesOnly": "仅限未映射的文件",
"Quality": "媒体质量",
"TheLogLevelDefault": "默认的日志等级为Info”,可以被修改在",
"TheLogLevelDefault": "默认的日志等级为 \"Info\", 可以在 [常规设置] 中修改 (/settings/general)",
"RestartReloadNote": "注意:{appName}将在恢复过程中自动重启并重新加载UI。",
"RequiredRestrictionPlaceHolder": "添加新限制",
"PhysicalRelease": "碟片版发布日期",
@@ -882,7 +882,7 @@
"UsenetDisabled": "Usenet已关闭",
"VisitGithubCustomFormatsAphrodite": "访问wiki获取更多详细信息 ",
"WaitingToProcess": "等待处理",
"Wanted": "想要的",
"Wanted": "已追踪",
"Warn": "警告",
"Week": "周",
"WhitelistedHardcodedSubsHelpText": "这里设置的字幕标签不会被认为是硬编码的",
@@ -982,7 +982,7 @@
"DownloadClientCheckDownloadingToRoot": "下载客户端{downloadClientName}将下载内容放在根文件夹{path}中。您不应该下载到根文件夹。",
"DeleteFileLabel": "删除 {0} 电影文件",
"ImportListMultipleMissingRoots": "导入列表中缺失多个根目录文件夹",
"ImportListMissingRoot": "在导入列表中缺少根目录文件夹",
"ImportListMissingRoot": "在导入列表中缺少根目录文件夹: {rootFolderInfo}",
"BypassDelayIfHighestQuality": "如果达到最高质量,则跳过",
"NotificationTriggersHelpText": "选择触发此通知的事件",
"From": "来自",
@@ -1004,7 +1004,7 @@
"RemoveFromBlocklist": "从黑名单中移除",
"Blocklisted": "黑名单",
"BlocklistReleases": "黑名单版本",
"IndexerTagHelpText": "仅对至少有一个匹配标的电影使用此索引器。留空则适用于所有电影。",
"IndexerTagHelpText": "仅对至少有一个匹配标的电影使用此索引器。留空则适用于所有电影。",
"RemotePathMappingCheckFileRemoved": "文件{path} 在处理的过程中被部分删除。",
"RemotePathMappingCheckFilesGenericPermissions": "下载{1}中客户端{0}报告的文件,但{appName}无法看到此目录。您可能需要调整文件夹的权限。",
"RemotePathMappingCheckGenericPermissions": "下载客户端{downloadClientName}将下载放置在{path}中,但 {appName} 无法看到此目录。您可能需要调整文件夹的权限。",
@@ -1338,5 +1338,13 @@
"ClearBlocklist": "清空黑名单",
"ClearBlocklistMessageText": "你确定要将黑名单中的所有项目清空吗?",
"PasswordConfirmation": "确认密码",
"InteractiveSearchModalHeader": "交互式搜索"
"InteractiveSearchModalHeader": "交互式搜索",
"UpdaterLogFiles": "更新器日志文件",
"EnableProfile": "启用配置",
"FailedToFetchUpdates": "获取更新失败",
"FailedToUpdateSettings": "更新配置失败",
"WhySearchesCouldBeFailing": "单击此处了解搜索失败的原因",
"LogFilesLocation": "日志文件位于: {location}",
"PackageVersionInfo": "{packageVersion} 由 {packageAuthor} 制作",
"PreviouslyInstalled": "上次安装"
}

View File

@@ -10,6 +10,7 @@ namespace NzbDrone.Core.MediaFiles.MediaInfo
DolbyVision,
DolbyVisionHdr10,
DolbyVisionSdr,
DolbyVisionHlg
DolbyVisionHlg,
DolbyVisionHdr10Plus
}
}

View File

@@ -320,6 +320,8 @@ namespace NzbDrone.Core.MediaFiles.MediaInfo
return "DV";
case HdrFormat.DolbyVisionHdr10:
return "DV HDR10";
case HdrFormat.DolbyVisionHdr10Plus:
return "DV HDR10Plus";
case HdrFormat.DolbyVisionHlg:
return "DV HLG";
case HdrFormat.DolbyVisionSdr:

View File

@@ -22,7 +22,7 @@ namespace NzbDrone.Core.MediaFiles.MediaInfo
private readonly List<FFProbePixelFormat> _pixelFormats;
public const int MINIMUM_MEDIA_INFO_SCHEMA_REVISION = 8;
public const int CURRENT_MEDIA_INFO_SCHEMA_REVISION = 10;
public const int CURRENT_MEDIA_INFO_SCHEMA_REVISION = 11;
private static readonly string[] ValidHdrColourPrimaries = { "bt2020" };
private static readonly string[] HlgTransferFunctions = { "bt2020-10", "arib-std-b67" };
@@ -188,12 +188,14 @@ namespace NzbDrone.Core.MediaFiles.MediaInfo
if (TryGetSideData<DoviConfigurationRecordSideData>(sideData, out var dovi))
{
var hasHdr10Plus = TryGetSideData<HdrDynamicMetadataSpmte2094>(sideData, out _);
return dovi.DvBlSignalCompatibilityId switch
{
1 => HdrFormat.DolbyVisionHdr10,
1 => hasHdr10Plus ? HdrFormat.DolbyVisionHdr10Plus : HdrFormat.DolbyVisionHdr10,
2 => HdrFormat.DolbyVisionSdr,
4 => HdrFormat.DolbyVisionHlg,
6 => HdrFormat.DolbyVisionHdr10,
6 => hasHdr10Plus ? HdrFormat.DolbyVisionHdr10Plus : HdrFormat.DolbyVisionHdr10,
_ => HdrFormat.DolbyVision
};
}

View File

@@ -79,7 +79,7 @@ namespace NzbDrone.Core.Notifications.Mailgun
const string body = "This is a test message from Radarr, though Mailgun.";
_proxy.SendNotification(title, body, Settings);
_logger.Info("Successsfully sent email though Mailgun.");
_logger.Info("Successfully sent email though Mailgun.");
}
catch (Exception ex)
{

View File

@@ -37,7 +37,7 @@ namespace NzbDrone.Core.Notifications.Emby
[FieldDefinition(3, Label = "API Key", Privacy = PrivacyLevel.ApiKey)]
public string ApiKey { get; set; }
[FieldDefinition(4, Label = "Send Notifications", HelpText = "Have MediaBrowser send notfications to configured providers", Type = FieldType.Checkbox)]
[FieldDefinition(4, Label = "Send Notifications", HelpText = "Have MediaBrowser send notifications to configured providers", Type = FieldType.Checkbox)]
public bool Notify { get; set; }
[FieldDefinition(5, Label = "Update Library", HelpText = "Update Library on Import, Rename or Delete?", Type = FieldType.Checkbox)]

View File

@@ -8,10 +8,16 @@ namespace NzbDrone.Core.Notifications.Trakt.Resource
[JsonProperty(PropertyName = "collected_at")]
public DateTime CollectedAt { get; set; }
public string Resolution { get; set; }
public string Hdr { get; set; }
[JsonProperty(PropertyName = "audio_channels")]
public string AudioChannels { get; set; }
public string Audio { get; set; }
[JsonProperty(PropertyName = "media_type")]
public string MediaType { get; set; }
[JsonProperty(PropertyName = "3d")]
public bool Is3D { get; set; }
}
}

View File

@@ -154,6 +154,7 @@ namespace NzbDrone.Core.Notifications.Trakt
};
var traktResolution = MapResolution(movieFile.Quality.Quality.Resolution, movieFile.MediaInfo?.ScanType);
var hdr = MapHdr(movieFile);
var mediaType = MapMediaType(movieFile.Quality.Quality.Source);
var audio = MapAudio(movieFile);
var audioChannels = MapAudioChannels(movieFile);
@@ -164,9 +165,11 @@ namespace NzbDrone.Core.Notifications.Trakt
Year = movie.Year,
CollectedAt = DateTime.Now,
Resolution = traktResolution,
Hdr = hdr,
MediaType = mediaType,
AudioChannels = audioChannels,
Audio = audio,
Is3D = movieFile.MediaInfo?.VideoMultiViewCount > 1,
Ids = new TraktMovieIdsResource
{
Tmdb = movie.MovieMetadata.Value.TmdbId,
@@ -200,119 +203,76 @@ namespace NzbDrone.Core.Notifications.Trakt
private string MapMediaType(QualitySource source)
{
var traktSource = string.Empty;
switch (source)
var traktSource = source switch
{
case QualitySource.BLURAY:
traktSource = "bluray";
break;
case QualitySource.WEBDL:
traktSource = "digital";
break;
case QualitySource.WEBRIP:
traktSource = "digital";
break;
case QualitySource.DVD:
traktSource = "dvd";
break;
case QualitySource.TV:
traktSource = "dvd";
break;
}
QualitySource.BLURAY => "bluray",
QualitySource.WEBDL => "digital",
QualitySource.WEBRIP => "digital",
QualitySource.DVD => "dvd",
QualitySource.TV => "dvd",
_ => string.Empty
};
return traktSource;
}
private string MapResolution(int resolution, string scanType)
{
var traktResolution = string.Empty;
var scanIdentifier = scanType.IsNotNullOrWhiteSpace() && TraktInterlacedTypes.InterlacedTypes.Contains(scanType) ? "i" : "p";
var scanIdentifier = scanType.IsNotNullOrWhiteSpace() && TraktInterlacedTypes.interlacedTypes.Contains(scanType) ? "i" : "p";
switch (resolution)
var traktResolution = resolution switch
{
case 2160:
traktResolution = "uhd_4k";
break;
case 1080:
traktResolution = $"hd_1080{scanIdentifier}";
break;
case 720:
traktResolution = "hd_720p";
break;
case 576:
traktResolution = $"sd_576{scanIdentifier}";
break;
case 480:
traktResolution = $"sd_480{scanIdentifier}";
break;
}
2160 => "uhd_4k",
1080 => $"hd_1080{scanIdentifier}",
720 => "hd_720p",
576 => $"sd_576{scanIdentifier}",
480 => $"sd_480{scanIdentifier}",
_ => string.Empty
};
return traktResolution;
}
private string MapHdr(MovieFile movieFile)
{
var traktHdr = movieFile.MediaInfo?.VideoHdrFormat switch
{
HdrFormat.DolbyVision or HdrFormat.DolbyVisionSdr => "dolby_vision",
HdrFormat.Hdr10 or HdrFormat.DolbyVisionHdr10 => "hdr10",
HdrFormat.Hdr10Plus or HdrFormat.DolbyVisionHdr10Plus => "hdr10_plus",
HdrFormat.Hlg10 or HdrFormat.DolbyVisionHlg => "hlg",
_ => null
};
return traktHdr;
}
private string MapAudio(MovieFile movieFile)
{
var traktAudioFormat = string.Empty;
var audioCodec = movieFile.MediaInfo != null ? MediaInfoFormatter.FormatAudioCodec(movieFile.MediaInfo, movieFile.SceneName) : string.Empty;
switch (audioCodec)
var traktAudioFormat = audioCodec switch
{
case "AC3":
traktAudioFormat = "dolby_digital";
break;
case "EAC3":
traktAudioFormat = "dolby_digital_plus";
break;
case "TrueHD":
traktAudioFormat = "dolby_truehd";
break;
case "EAC3 Atmos":
traktAudioFormat = "dolby_digital_plus_atmos";
break;
case "TrueHD Atmos":
traktAudioFormat = "dolby_atmos";
break;
case "DTS":
case "DTS-ES":
traktAudioFormat = "dts";
break;
case "DTS-HD MA":
traktAudioFormat = "dts_ma";
break;
case "DTS-HD HRA":
traktAudioFormat = "dts_hr";
break;
case "DTS-X":
traktAudioFormat = "dts_x";
break;
case "MP3":
traktAudioFormat = "mp3";
break;
case "MP2":
traktAudioFormat = "mp2";
break;
case "Vorbis":
traktAudioFormat = "ogg";
break;
case "WMA":
traktAudioFormat = "wma";
break;
case "AAC":
traktAudioFormat = "aac";
break;
case "PCM":
traktAudioFormat = "lpcm";
break;
case "FLAC":
traktAudioFormat = "flac";
break;
case "Opus":
traktAudioFormat = "ogg_opus";
break;
}
"AC3" => "dolby_digital",
"EAC3" => "dolby_digital_plus",
"TrueHD" => "dolby_truehd",
"EAC3 Atmos" => "dolby_digital_plus_atmos",
"TrueHD Atmos" => "dolby_atmos",
"DTS" => "dts",
"DTS-ES" => "dts",
"DTS-HD MA" => "dts_ma",
"DTS-HD HRA" => "dts_hr",
"DTS-X" => "dts_x",
"MP3" => "mp3",
"MP2" => "mp2",
"Vorbis" => "ogg",
"WMA" => "wma",
"AAC" => "aac",
"PCM" => "lpcm",
"FLAC" => "flac",
"Opus" => "ogg_opus",
_ => string.Empty
};
return traktAudioFormat;
}

View File

@@ -5,16 +5,9 @@ namespace NzbDrone.Core.Notifications.Trakt
{
public static class TraktInterlacedTypes
{
private static HashSet<string> _interlacedTypes;
static TraktInterlacedTypes()
public static readonly HashSet<string> InterlacedTypes = new (StringComparer.OrdinalIgnoreCase)
{
_interlacedTypes = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
{
"Interlaced", "MBAFF", "PAFF"
};
}
public static HashSet<string> interlacedTypes => _interlacedTypes;
"Interlaced", "MBAFF", "PAFF"
};
}
}

View File

@@ -1,3 +1,4 @@
using System;
using System.Net.Http;
using NLog;
using NzbDrone.Common.Extensions;
@@ -76,6 +77,7 @@ namespace NzbDrone.Core.Notifications.Trakt
{
var request = new HttpRequestBuilder(RenewUri)
.AddQueryParam("refresh_token", refreshToken)
.WithRateLimit(2)
.Build();
return _httpClient.Get<TraktAuthRefreshResource>(request)?.Resource ?? null;
@@ -85,6 +87,7 @@ namespace NzbDrone.Core.Notifications.Trakt
{
var request = new HttpRequestBuilder(URL).Resource(resource).Build();
request.RateLimit = TimeSpan.FromSeconds(2);
request.Headers.Accept = HttpAccept.Json.Value;
request.Method = method;

View File

@@ -77,7 +77,7 @@ namespace NzbDrone.Core.Notifications.Twitter
using (var reader = new StreamReader(responseStream))
{
var responseBody = reader.ReadToEnd();
_logger.Trace("Reponse: {0} Status Code: {1}", responseBody, httpResponse.StatusCode);
_logger.Trace("Response: {0} Status Code: {1}", responseBody, httpResponse.StatusCode);
throw new TwitterException("Error received from Twitter: " + responseBody, ex);
}
}

View File

@@ -360,7 +360,7 @@ namespace NzbDrone.Core.Organizer
new Dictionary<string, int>(FileNameBuilderTokenEqualityComparer.Instance)
{
{ MediaInfoVideoDynamicRangeToken, 5 },
{ MediaInfoVideoDynamicRangeTypeToken, 10 }
{ MediaInfoVideoDynamicRangeTypeToken, 11 }
};
private void AddMediaInfoTokens(Dictionary<string, Func<TokenMatch, string>> tokenHandlers, MovieFile movieFile)

View File

@@ -7,7 +7,7 @@
<PackageReference Include="Diacritical.Net" Version="1.0.4" />
<PackageReference Include="Equ" Version="2.3.0" />
<PackageReference Include="MailKit" Version="3.6.0" />
<PackageReference Include="Npgsql" Version="7.0.4" />
<PackageReference Include="Npgsql" Version="7.0.6" />
<PackageReference Include="Servarr.FFMpegCore" Version="4.7.0-26" />
<PackageReference Include="Servarr.FFprobe" Version="5.1.4.112" />
<PackageReference Include="System.Memory" Version="4.5.5" />
@@ -24,7 +24,7 @@
<PackageReference Include="NLog" Version="5.2.3" />
<PackageReference Include="System.Data.SQLite.Core.Servarr" Version="1.0.115.5-18" />
<PackageReference Include="MonoTorrent" Version="2.0.7" />
<PackageReference Include="System.Text.Json" Version="6.0.8" />
<PackageReference Include="System.Text.Json" Version="6.0.9" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\NzbDrone.Common\Radarr.Common.csproj" />

View File

@@ -7,7 +7,7 @@
<PackageReference Include="System.Text.Encoding.CodePages" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="6.0.2" />
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerGen" Version="6.5.0" />
<PackageReference Include="DryIoc.dll" Version="5.4.1" />
<PackageReference Include="DryIoc.dll" Version="5.4.3" />
<PackageReference Include="DryIoc.Microsoft.DependencyInjection" Version="6.2.0" />
</ItemGroup>
<ItemGroup>

View File

@@ -80,7 +80,7 @@ namespace NzbDrone.Host
case ApplicationModes.RegisterUrl:
{
_logger.Debug("Regiser URL selected");
_logger.Debug("Register URL selected");
_remoteAccessAdapter.MakeAccessible(false);
_appFolderFactory.SetPermissions();

View File

@@ -4,7 +4,7 @@
<OutputType>Library</OutputType>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="6.0.21" />
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="6.0.25" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\NzbDrone.Test.Common\Radarr.Test.Common.csproj" />

View File

@@ -3,7 +3,7 @@
<TargetFrameworks>net6.0</TargetFrameworks>
</PropertyGroup>
<!--
The netstandard veresion here doesn't work in net framework
The netstandard version here doesn't work in net framework
See https://github.com/xamarin/XamarinComponents/issues/282
-->
<ItemGroup>

View File

@@ -4,7 +4,7 @@
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
</PropertyGroup>
<!--
The netstandard veresion here doesn't work in net framework
The netstandard version here doesn't work in net framework
See https://github.com/xamarin/XamarinComponents/issues/282
-->
<ItemGroup>

View File

@@ -4,7 +4,7 @@
<TargetFrameworks>net6.0</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="DryIoc.dll" Version="5.4.1" />
<PackageReference Include="DryIoc.dll" Version="5.4.3" />
<PackageReference Include="DryIoc.Microsoft.DependencyInjection" Version="6.2.0" />
<PackageReference Include="NLog" Version="5.2.3" />
</ItemGroup>

View File

@@ -1207,10 +1207,10 @@
resolved "https://registry.yarnpkg.com/@juggle/resize-observer/-/resize-observer-3.4.0.tgz#08d6c5e20cf7e4cc02fd181c4b0c225cd31dbb60"
integrity sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA==
"@microsoft/signalr@6.0.21":
version "6.0.21"
resolved "https://registry.yarnpkg.com/@microsoft/signalr/-/signalr-6.0.21.tgz#b45f335df7011abba831cb3d7974b58da7e725c7"
integrity sha512-3MWhSUE7AxkQs3QBuJ/spJJpg1mAHo0/6yRGhs5+Hew3Z+iqYrHVfo0yTElC7W2bVA9t3fW3jliQ9rBN0OvJLA==
"@microsoft/signalr@6.0.25":
version "6.0.25"
resolved "https://registry.yarnpkg.com/@microsoft/signalr/-/signalr-6.0.25.tgz#009f043066d383e2de41a483bd7e02bfd74d3cf8"
integrity sha512-8AzrpxS+E0yn1tXSlv7+UlURLmSxTQDgbvOT0pGKXjZT7MkhnDP+/GLuk7veRtUjczou/x32d9PHhYlr2NBy6Q==
dependencies:
abort-controller "^3.0.0"
eventsource "^1.0.7"