1
0
mirror of https://github.com/Radarr/Radarr.git synced 2026-03-25 17:35:35 -04:00

Compare commits

...

26 Commits

Author SHA1 Message Date
Qstick
74382d7250 New: Rework List Exclusion UI 2022-07-05 23:10:47 -05:00
Qstick
6659bc034c Remove general yarn restore key to avoid cross OS conflict 2022-07-05 17:15:52 -05:00
Qstick
7404793dcf Fixed: Don't call for server notifications on event driven check
[common]
2022-07-03 12:36:53 -05:00
Qstick
d8af17ce3d Rename MovieImportedEvent to MovieFileImportedEvent 2022-07-03 12:35:15 -05:00
bakerboy448
44c912f02d Fixed: Improved parsing WebDL Releases 2022-07-03 11:55:06 -05:00
Alien21
b104368e23 New: adding a link to tmdb in the import combobox movie search results (#7352)
Co-authored-by: Alien21 <alien21@alien21.com>
2022-07-02 18:32:55 -05:00
Qstick
aa0104b6bc Fixed: Housekeeper doesn't remove collections that have MovieMeta from lists 2022-07-02 16:29:12 -05:00
Qstick
69fcd8ec94 Fixed: Notify on Bulk Adds (Lists, Collections, Imports)
Closes #7351
2022-07-02 15:53:56 -05:00
Robin Dadswell
a59928c66a Updated NLog Version (#7365)
[common]
2022-07-02 16:26:59 +01:00
Weblate
1cb7ae11a2 Translated using Weblate (Portuguese (Brazil)) [skip ci]
Currently translated at 100.0% (1144 of 1144 strings)

Translated using Weblate (Hungarian) [skip ci]

Currently translated at 100.0% (1144 of 1144 strings)

Translated using Weblate (Finnish) [skip ci]

Currently translated at 100.0% (1144 of 1144 strings)

Co-authored-by: Csaba <csab0825@gmail.com>
Co-authored-by: Havok Dan <havokdan@yahoo.com.br>
Co-authored-by: Oskari Lavinto <olavinto@protonmail.com>
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/fi/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/hu/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pt_BR/
Translation: Servarr/Radarr
2022-07-02 09:33:13 -05:00
Qstick
ca519047dd Fixed: Migration 208 fails when collection doesn't have name 2022-07-01 19:45:05 -05:00
Qstick
f15a6abde0 Fixed: Don't call AddMovies if no movies to add from Collection 2022-06-26 20:25:50 -05:00
Qstick
2aacebc938 New: Default to IMDb Ratings in Kodi Metadata
Fixes #7071
2022-06-26 20:25:50 -05:00
Weblate
120e9b673e Translated using Weblate (Slovak) [skip ci]
Currently translated at 9.5% (109 of 1143 strings)

Translated using Weblate (Norwegian Bokmål) [skip ci]

Currently translated at 22.3% (256 of 1143 strings)

Translated using Weblate (Chinese (Traditional) (zh_TW)) [skip ci]

Currently translated at 0.1% (2 of 1143 strings)

Translated using Weblate (Portuguese (Brazil)) [skip ci]

Currently translated at 100.0% (1143 of 1143 strings)

Added translation using Weblate (Lithuanian) [skip ci]

Co-authored-by: Anonymous <noreply@weblate.org>
Co-authored-by: Havok Dan <havokdan@yahoo.com.br>
Co-authored-by: Qstick <qstick@gmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: loksum213108 <lok3222003@gmail.com>
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/nb_NO/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pt_BR/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/sk/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/zh_TW/
Translation: Servarr/Radarr
2022-06-26 18:43:59 -05:00
Qstick
0a77a13fa8 New: Separate Ratings Columns
Fixes #7281
2022-06-26 17:23:07 -05:00
Qstick
383f9647c3 Fixed: Add support for more Anime release formats
Ref #6954
2022-06-26 15:30:05 -05:00
Weblate
7f7c672b93 Translated using Weblate (Portuguese) [skip ci]
Currently translated at 98.2% (1123 of 1143 strings)

Translated using Weblate (Hungarian) [skip ci]

Currently translated at 100.0% (1143 of 1143 strings)

Translated using Weblate (Spanish) [skip ci]

Currently translated at 97.9% (1119 of 1143 strings)

Co-authored-by: Csaba <csab0825@gmail.com>
Co-authored-by: RckCell <pabloant86@gmail.com>
Co-authored-by: Vitor Brito <main@vitorbrito.com>
Co-authored-by: Weblate <noreply@weblate.org>
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/es/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/hu/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pt/
Translation: Servarr/Radarr
2022-06-25 18:16:54 -05:00
Servarr
2690ad8fe1 Automated API Docs update 2022-06-25 18:16:32 -05:00
Qstick
801204b6de New: Bulk Edit Collections Profile, Root, Availability
Fixes #7350
2022-06-25 16:01:01 -05:00
Servarr
cb9514abaf Automated API Docs update 2022-06-25 15:30:31 -05:00
Qstick
fd22cb44f6 Fixed: Collections Improvements
Fixes #7383
2022-06-25 15:23:39 -05:00
Qstick
2d68716376 Add back Movie Credits and Alt Titles Indexes 2022-06-23 19:48:41 -05:00
Qstick
b97e76c8b8 Fixed: Validate if equals or child for startup folder
(cherry picked from commit 0991cfe27efd6ddb533227b25754661e18d7e9ad)
2022-06-23 00:34:03 -04:00
bakerboy448
bfad4a8cd1 New: Notifiarr include Media Info in Download Notifications 2022-06-22 18:12:33 -05:00
bakerboy448
61f05710f5 New: Notifiarr moved from webhook to API 2022-06-22 18:12:33 -05:00
Weblate
a8ecefd91f Translated using Weblate (German) [skip ci]
Currently translated at 100.0% (1143 of 1143 strings)

Translated using Weblate (German) [skip ci]

Currently translated at 97.8% (1118 of 1143 strings)

Translated using Weblate (Polish) [skip ci]

Currently translated at 99.9% (1142 of 1143 strings)

Translated using Weblate (Hungarian) [skip ci]

Currently translated at 99.9% (1142 of 1143 strings)

Translated using Weblate (Portuguese (Brazil)) [skip ci]

Currently translated at 100.0% (1143 of 1143 strings)

Co-authored-by: Csaba <csab0825@gmail.com>
Co-authored-by: Havok Dan <havokdan@yahoo.com.br>
Co-authored-by: Marcin <ml.cichy@gmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: reloxx <reloxx@interia.pl>
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/de/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/hu/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pl/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pt_BR/
Translation: Servarr/Radarr
2022-06-22 09:51:52 -05:00
86 changed files with 1000 additions and 379 deletions

View File

@@ -173,7 +173,6 @@ stages:
key: 'yarn | "$(osName)" | yarn.lock'
restoreKeys: |
yarn | "$(osName)"
yarn
path: $(yarnCacheFolder)
displayName: Cache Yarn packages
- bash: ./build.sh --frontend
@@ -976,7 +975,6 @@ stages:
key: 'yarn | "$(osName)" | yarn.lock'
restoreKeys: |
yarn | "$(osName)"
yarn
path: $(yarnCacheFolder)
displayName: Cache Yarn packages
- bash: ./build.sh --lint

View File

@@ -181,12 +181,13 @@ class Blocklist extends Component {
>
<TableBody>
{
items.map((item) => {
items.map((item, index) => {
return (
<BlocklistRowConnector
key={item.id}
isSelected={selectedState[item.id] || false}
columns={columns}
index={index}
{...item}
onSelectedChange={this.onSelectedChange}
/>

View File

@@ -1,9 +1,9 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import HeartRating from 'Components/HeartRating';
import Icon from 'Components/Icon';
import Label from 'Components/Label';
import Link from 'Components/Link/Link';
import TmdbRating from 'Components/TmdbRating';
import Tooltip from 'Components/Tooltip/Tooltip';
import { icons, kinds, sizes, tooltipPositions } from 'Helpers/Props';
import MovieDetailsLinks from 'Movie/Details/MovieDetailsLinks';
@@ -190,7 +190,7 @@ class AddNewMovieSearchResult extends Component {
<div>
<Label size={sizes.LARGE}>
<HeartRating
<TmdbRating
ratings={ratings}
iconSize={13}
/>

View File

@@ -1,4 +1,5 @@
.movie {
.container {
display: flex;
padding: 10px 20px;
width: 100%;
@@ -6,3 +7,19 @@
background-color: $menuItemHoverBackgroundColor;
}
}
.movie {
flex: 1 0 0;
overflow: hidden;
}
.tmdbLink {
composes: link from '~Components/Link/Link.css';
margin-left: auto;
color: $textColor;
}
.tmdbLinkIcon {
margin-left: 10px;
}

View File

@@ -1,6 +1,8 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import Icon from 'Components/Icon';
import Link from 'Components/Link/Link';
import { icons } from 'Helpers/Props';
import ImportMovieTitle from './ImportMovieTitle';
import styles from './ImportMovieSearchResult.css';
@@ -18,6 +20,7 @@ class ImportMovieSearchResult extends Component {
render() {
const {
tmdbId,
title,
year,
studio,
@@ -25,17 +28,30 @@ class ImportMovieSearchResult extends Component {
} = this.props;
return (
<Link
className={styles.movie}
onPress={this.onPress}
>
<ImportMovieTitle
title={title}
year={year}
network={studio}
isExistingMovie={isExistingMovie}
/>
</Link>
<div className={styles.container}>
<Link
className={styles.movie}
onPress={this.onPress}
>
<ImportMovieTitle
title={title}
year={year}
network={studio}
isExistingMovie={isExistingMovie}
/>
</Link>
<Link
className={styles.tmdbLink}
to={`https://www.themoviedb.org/movie/${tmdbId}`}
>
<Icon
className={styles.tmdbLinkIcon}
name={icons.EXTERNAL_LINK}
size={16}
/>
</Link>
</div>
);
}
}

View File

@@ -1,6 +1,9 @@
import _ from 'lodash';
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import AvailabilitySelectInput from 'Components/Form/AvailabilitySelectInput';
import QualityProfileSelectInputConnector from 'Components/Form/QualityProfileSelectInputConnector';
import RootFolderSelectInputConnector from 'Components/Form/RootFolderSelectInputConnector';
import SelectInput from 'Components/Form/SelectInput';
import SpinnerButton from 'Components/Link/SpinnerButton';
import PageContentFooter from 'Components/Page/PageContentFooter';
@@ -22,6 +25,9 @@ class CollectionFooter extends Component {
this.state = {
monitor: NO_CHANGE,
monitored: NO_CHANGE,
qualityProfileId: NO_CHANGE,
minimumAvailability: NO_CHANGE,
rootFolderPath: NO_CHANGE,
destinationRootFolder: null
};
}
@@ -36,7 +42,10 @@ class CollectionFooter extends Component {
if (prevProps.isSaving && !isSaving && !saveError) {
this.setState({
monitored: NO_CHANGE,
monitor: NO_CHANGE
monitor: NO_CHANGE,
qualityProfileId: NO_CHANGE,
rootFolderPath: NO_CHANGE,
minimumAvailability: NO_CHANGE
});
}
@@ -55,7 +64,9 @@ class CollectionFooter extends Component {
onUpdateSelectedPress = () => {
const {
monitor,
monitored
monitored,
qualityProfileId,
minimumAvailability
} = this.state;
const changes = {};
@@ -68,6 +79,14 @@ class CollectionFooter extends Component {
changes.monitor = monitor;
}
if (qualityProfileId !== NO_CHANGE) {
changes.qualityProfileId = qualityProfileId;
}
if (minimumAvailability !== NO_CHANGE) {
changes.minimumAvailability = minimumAvailability;
}
this.props.onUpdateSelectedPress(changes);
};
@@ -82,7 +101,10 @@ class CollectionFooter extends Component {
const {
monitored,
monitor
monitor,
qualityProfileId,
minimumAvailability,
rootFolderPath
} = this.state;
const monitoredOptions = [
@@ -125,6 +147,52 @@ class CollectionFooter extends Component {
/>
</div>
<div className={styles.inputContainer}>
<CollectionFooterLabel
label={translate('QualityProfile')}
isSaving={isSaving && qualityProfileId !== NO_CHANGE}
/>
<QualityProfileSelectInputConnector
name="qualityProfileId"
value={qualityProfileId}
includeNoChange={true}
isDisabled={!selectedCount}
onChange={this.onInputChange}
/>
</div>
<div className={styles.inputContainer}>
<CollectionFooterLabel
label={translate('MinimumAvailability')}
isSaving={isSaving && minimumAvailability !== NO_CHANGE}
/>
<AvailabilitySelectInput
name="minimumAvailability"
value={minimumAvailability}
includeNoChange={true}
isDisabled={!selectedCount}
onChange={this.onInputChange}
/>
</div>
<div className={styles.inputContainer}>
<CollectionFooterLabel
label={translate('RootFolder')}
isSaving={isSaving && rootFolderPath !== NO_CHANGE}
/>
<RootFolderSelectInputConnector
name="rootFolderPath"
value={rootFolderPath}
includeNoChange={true}
isDisabled={!selectedCount}
selectedValueOptions={{ includeFreeSpace: false }}
onChange={this.onInputChange}
/>
</div>
<div className={styles.buttonContainer}>
<div className={styles.buttonContainerContent}>
<CollectionFooterLabel

View File

@@ -1,5 +0,0 @@
.image {
align-content: center;
margin-right: 5px;
vertical-align: -0.125em;
}

File diff suppressed because one or more lines are too long

View File

@@ -22,11 +22,11 @@ class ImdbRating extends PureComponent {
let ratingString = '0.0';
if (rating) {
ratingString = `${rating.value}`;
ratingString = `${rating.value.toFixed(1)}`;
}
return (
<span title={`${rating.votes} votes`}>
<span title={`${rating ? rating.votes : 0} votes`}>
{
!hideIcon &&
<img

View File

@@ -21,9 +21,11 @@ class RottenTomatoRating extends PureComponent {
const rating = ratings.rottenTomatoes;
let ratingString = '0%';
let ratingImage = rtFresh;
if (rating) {
ratingString = `${rating.value}%`;
ratingImage = rating.value > 50 ? rtFresh : rtRotten;
}
return (
@@ -32,7 +34,7 @@ class RottenTomatoRating extends PureComponent {
!hideIcon &&
<img
className={styles.image}
src={rating.value > 50 ? rtFresh : rtRotten}
src={ratingImage}
style={{
height: `${iconSize}px`
}}

View File

@@ -22,7 +22,7 @@ class TmdbRating extends PureComponent {
let ratingString = '0%';
if (rating) {
ratingString = `${rating.value * 10}%`;
ratingString = `${(rating.value * 10).toFixed()}%`;
}
return (

View File

@@ -1,6 +1,6 @@
import PropTypes from 'prop-types';
import React from 'react';
import HeartRating from 'Components/HeartRating';
import TmdbRating from 'Components/TmdbRating';
import { getMovieStatusDetails } from 'Movie/MovieStatus';
import formatRuntime from 'Utilities/Date/formatRuntime';
import getRelativeDate from 'Utilities/Date/getRelativeDate';
@@ -111,7 +111,7 @@ function DiscoverMoviePosterInfo(props) {
if (sortKey === 'ratings' && ratings) {
return (
<div className={styles.info}>
<HeartRating
<TmdbRating
ratings={ratings}
/>
</div>

View File

@@ -1,6 +1,5 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import HeartRating from 'Components/HeartRating';
import Icon from 'Components/Icon';
import ImportListListConnector from 'Components/ImportListListConnector';
import IconButton from 'Components/Link/IconButton';
@@ -8,6 +7,7 @@ import Link from 'Components/Link/Link';
import RelativeDateCellConnector from 'Components/Table/Cells/RelativeDateCellConnector';
import VirtualTableRowCell from 'Components/Table/Cells/VirtualTableRowCell';
import VirtualTableSelectCell from 'Components/Table/Cells/VirtualTableSelectCell';
import TmdbRating from 'Components/TmdbRating';
import Popover from 'Components/Tooltip/Popover';
import AddNewDiscoverMovieModal from 'DiscoverMovie/AddNewDiscoverMovieModal';
import ExcludeMovieModal from 'DiscoverMovie/Exclusion/ExcludeMovieModal';
@@ -245,7 +245,7 @@ class DiscoverMovieRow extends Component {
key={name}
className={styles[name]}
>
<HeartRating
<TmdbRating
ratings={ratings}
/>
</VirtualTableRowCell>

View File

@@ -102,12 +102,21 @@ function MovieIndexSortMenu(props) {
</SortMenuItem>
<SortMenuItem
name="ratings"
name="imdbRating"
sortKey={sortKey}
sortDirection={sortDirection}
onPress={onSortSelect}
>
{translate('Ratings')}
{translate('ImdbRating')}
</SortMenuItem>
<SortMenuItem
name="tmdbRating"
sortKey={sortKey}
sortDirection={sortDirection}
onPress={onSortSelect}
>
{translate('TmdbRating')}
</SortMenuItem>
<SortMenuItem

View File

@@ -77,7 +77,9 @@
flex: 0 0 120px;
}
.ratings {
.imdbRating,
.tmdbRating,
.rottenTomatoesRating {
composes: headerCell from '~Components/Table/VirtualTableHeaderCell.css';
flex: 0 0 80px;

View File

@@ -84,7 +84,9 @@
flex: 0 0 120px;
}
.ratings {
.imdbRating,
.tmdbRating,
.rottenTomatoesRating {
composes: cell;
flex: 0 0 80px;

View File

@@ -1,13 +1,15 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import HeartRating from 'Components/HeartRating';
import Icon from 'Components/Icon';
import ImdbRating from 'Components/ImdbRating';
import IconButton from 'Components/Link/IconButton';
import SpinnerIconButton from 'Components/Link/SpinnerIconButton';
import RottenTomatoRating from 'Components/RottenTomatoRating';
import RelativeDateCellConnector from 'Components/Table/Cells/RelativeDateCellConnector';
import VirtualTableRowCell from 'Components/Table/Cells/VirtualTableRowCell';
import VirtualTableSelectCell from 'Components/Table/Cells/VirtualTableSelectCell';
import TagListConnector from 'Components/TagListConnector';
import TmdbRating from 'Components/TmdbRating';
import Tooltip from 'Components/Tooltip/Tooltip';
import { icons, kinds } from 'Helpers/Props';
import DeleteMovieModal from 'Movie/Delete/DeleteMovieModal';
@@ -349,13 +351,39 @@ class MovieIndexRow extends Component {
);
}
if (name === 'ratings') {
if (name === 'tmdbRating') {
return (
<VirtualTableRowCell
key={name}
className={styles[name]}
>
<HeartRating
<TmdbRating
ratings={ratings}
/>
</VirtualTableRowCell>
);
}
if (name === 'rottenTomatoesRating') {
return (
<VirtualTableRowCell
key={name}
className={styles[name]}
>
<RottenTomatoRating
ratings={ratings}
/>
</VirtualTableRowCell>
);
}
if (name === 'imdbRating') {
return (
<VirtualTableRowCell
key={name}
className={styles[name]}
>
<ImdbRating
ratings={ratings}
/>
</VirtualTableRowCell>

View File

@@ -15,12 +15,13 @@
.tmdbId,
.movieYear {
flex: 0 0 70px;
composes: cell from '~Components/Table/Cells/TableRowCell.css';
width: 80px;
}
.actions {
display: flex;
justify-content: flex-end;
flex: 1 0 auto;
padding-right: 10px;
composes: cell from '~Components/Table/Cells/TableRowCell.css';
width: 70px;
}

View File

@@ -1,13 +1,16 @@
import classNames from 'classnames';
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import Icon from 'Components/Icon';
import Link from 'Components/Link/Link';
import ConfirmModal from 'Components/Modal/ConfirmModal';
import TableRowCell from 'Components/Table/Cells/TableRowCell';
import TableSelectCell from 'Components/Table/Cells/TableSelectCell';
import TableRow from 'Components/Table/TableRow';
import { icons, kinds } from 'Helpers/Props';
import translate from 'Utilities/String/translate';
import EditImportListExclusionModalConnector from './EditImportListExclusionModalConnector';
import styles from './ImportListExclusion.css';
import IconButton from 'Components/Link/IconButton';
class ImportListExclusion extends Component {
@@ -55,28 +58,82 @@ class ImportListExclusion extends Component {
render() {
const {
id,
isSelected,
onSelectedChange,
columns,
movieTitle,
tmdbId,
movieYear
} = this.props;
return (
<div
className={classNames(
styles.importExclusion
)}
>
<div className={styles.tmdbId}>{tmdbId}</div>
<div className={styles.movieTitle}>{movieTitle}</div>
<div className={styles.movieYear}>{movieYear}</div>
<TableRow>
<TableSelectCell
id={id}
isSelected={isSelected}
onSelectedChange={onSelectedChange}
/>
<div className={styles.actions}>
<Link
onPress={this.onEditImportExclusionPress}
>
<Icon name={icons.EDIT} />
</Link>
</div>
{
columns.map((column) => {
const {
name,
isVisible
} = column;
if (!isVisible) {
return null;
}
if (name === 'tmdbId') {
return (
<TableRowCell key={name}>
{tmdbId}
</TableRowCell>
);
}
if (name === 'movieTitle') {
return (
<TableRowCell key={name}>
{movieTitle}
</TableRowCell>
);
}
if (name === 'movieYear') {
return (
<TableRowCell key={name}>
{movieYear}
</TableRowCell>
);
}
if (name === 'actions') {
return (
<TableRowCell
key={name}
className={styles.actions}
>
<IconButton
title={translate('RemoveFromBlocklist')}
name={icons.EDIT}
onPress={this.onEditImportExclusionPress}
/>
<IconButton
title={translate('RemoveFromBlocklist')}
name={icons.REMOVE}
kind={kinds.DANGER}
onPress={this.onDeleteImportExclusionPress}
/>
</TableRowCell>
);
}
return null;
})
}
<EditImportListExclusionModalConnector
id={id}
@@ -94,7 +151,7 @@ class ImportListExclusion extends Component {
onConfirm={this.onConfirmDeleteImportExclusion}
onCancel={this.onDeleteImportExclusionModalClose}
/>
</div>
</TableRow>
);
}
}
@@ -104,6 +161,9 @@ ImportListExclusion.propTypes = {
movieTitle: PropTypes.string.isRequired,
tmdbId: PropTypes.number.isRequired,
movieYear: PropTypes.number.isRequired,
isSelected: PropTypes.bool.isRequired,
columns: PropTypes.arrayOf(PropTypes.object).isRequired,
onSelectedChange: PropTypes.func.isRequired,
onConfirmDeleteImportExclusion: PropTypes.func.isRequired
};

View File

@@ -4,8 +4,12 @@ import FieldSet from 'Components/FieldSet';
import Icon from 'Components/Icon';
import Link from 'Components/Link/Link';
import PageSectionContent from 'Components/Page/PageSectionContent';
import Table from 'Components/Table/Table';
import TableBody from 'Components/Table/TableBody';
import { icons } from 'Helpers/Props';
import translate from 'Utilities/String/translate';
import selectAll from 'Utilities/Table/selectAll';
import toggleSelected from 'Utilities/Table/toggleSelected';
import EditImportListExclusionModalConnector from './EditImportListExclusionModalConnector';
import ImportListExclusion from './ImportListExclusion';
import styles from './ImportListExclusions.css';
@@ -19,6 +23,10 @@ class ImportListExclusions extends Component {
super(props, context);
this.state = {
allSelected: false,
allUnselected: false,
lastToggled: null,
selectedState: {},
isAddImportExclusionModalOpen: false
};
}
@@ -26,6 +34,16 @@ class ImportListExclusions extends Component {
//
// Listeners
onSelectAllChange = ({ value }) => {
this.setState(selectAll(this.state.selectedState, value));
};
onSelectedChange = ({ id, value, shiftKey = false }) => {
this.setState((state) => {
return toggleSelected(state, this.props.items, id, value, shiftKey);
});
};
onAddImportExclusionPress = () => {
this.setState({ isAddImportExclusionModalOpen: true });
};
@@ -41,41 +59,50 @@ class ImportListExclusions extends Component {
const {
items,
onConfirmDeleteImportExclusion,
columns,
...otherProps
} = this.props;
const {
allSelected,
allUnselected,
selectedState
} = this.state;
return (
<FieldSet legend={translate('ListExclusions')}>
<PageSectionContent
errorMessage={translate('UnableToLoadListExclusions')}
{...otherProps}
>
<div className={styles.importListExclusionsHeader}>
<div className={styles.tmdbId}>
TMDb Id
</div>
<div className={styles.title}>
{translate('Title')}
</div>
<div className={styles.movieYear}>
{translate('Year')}
</div>
</div>
<div>
{
items.map((item, index) => {
return (
<ImportListExclusion
key={item.id}
{...item}
{...otherProps}
index={index}
onConfirmDeleteImportExclusion={onConfirmDeleteImportExclusion}
/>
);
})
}
<Table
selectAll={true}
allSelected={allSelected}
allUnselected={allUnselected}
columns={columns}
{...otherProps}
onSelectAllChange={this.onSelectAllChange}
>
<TableBody>
{
items.map((item, index) => {
return (
<ImportListExclusion
key={item.id}
isSelected={selectedState[item.id] || false}
{...item}
{...otherProps}
columns={columns}
index={index}
onSelectedChange={this.onSelectedChange}
onConfirmDeleteImportExclusion={onConfirmDeleteImportExclusion}
/>
);
})
}
</TableBody>
</Table>
</div>
<div className={styles.addImportExclusion}>
@@ -101,6 +128,7 @@ class ImportListExclusions extends Component {
ImportListExclusions.propTypes = {
isFetching: PropTypes.bool.isRequired,
error: PropTypes.object,
columns: PropTypes.arrayOf(PropTypes.object).isRequired,
items: PropTypes.arrayOf(PropTypes.object).isRequired,
onConfirmDeleteImportExclusion: PropTypes.func.isRequired
};

View File

@@ -4,6 +4,7 @@ import createRemoveItemHandler from 'Store/Actions/Creators/createRemoveItemHand
import createSaveProviderHandler from 'Store/Actions/Creators/createSaveProviderHandler';
import createSetSettingValueReducer from 'Store/Actions/Creators/Reducers/createSetSettingValueReducer';
import { createThunk } from 'Store/thunks';
import translate from 'Utilities/String/translate';
//
// Variables
@@ -48,7 +49,34 @@ export default {
items: [],
isSaving: false,
saveError: null,
pendingChanges: {}
pendingChanges: {},
columns: [
{
name: 'tmdbId',
label: 'TmdbId',
isSortable: true,
isVisible: true
},
{
name: 'movieTitle',
label: translate('Title'),
isSortable: true,
isVisible: true
},
{
name: 'movieYear',
label: translate('Year'),
isSortable: true,
isVisible: true
},
{
name: 'actions',
columnLabel: translate('Actions'),
isVisible: true,
isModifiable: false
}
]
},
//

View File

@@ -162,6 +162,14 @@ export const filterPredicates = {
return predicate(rating, filterValue);
},
rottenTomatoesRating: function(item, filterValue, type) {
const predicate = filterTypePredicates[type];
const rating = item.ratings.rottenTomatoes ? item.ratings.rottenTomatoes.value : 0;
return predicate(rating, filterValue);
},
imdbVotes: function(item, filterValue, type) {
const predicate = filterTypePredicates[type];

View File

@@ -254,27 +254,32 @@ export const actionHandlers = handleThunks({
const {
collectionIds,
monitored,
monitor
monitor,
qualityProfileId,
rootFolderPath,
minimumAvailability
} = payload;
const response = {};
const collections = [];
collectionIds.forEach((id) => {
const collectionToUpdate = { id };
if (payload.hasOwnProperty('monitored')) {
collectionToUpdate.monitored = monitored;
}
collections.push(collectionToUpdate);
});
if (payload.hasOwnProperty('monitored')) {
response.monitored = monitored;
}
if (payload.hasOwnProperty('monitor')) {
response.monitorMovies = monitor === 'monitored';
}
response.collections = collections;
if (payload.hasOwnProperty('qualityProfileId')) {
response.qualityProfileId = qualityProfileId;
}
if (payload.hasOwnProperty('minimumAvailability')) {
response.minimumAvailability = minimumAvailability;
}
response.rootFolderPath = rootFolderPath;
response.collectionIds = collectionIds;
dispatch(set({
section,

View File

@@ -178,8 +178,20 @@ export const defaultState = {
isVisible: true
},
{
name: 'ratings',
label: translate('Ratings'),
name: 'tmdbRating',
label: translate('TmdbRating'),
isSortable: true,
isVisible: false
},
{
name: 'rottenTomatoesRating',
label: translate('RottenTomatoesRating'),
isSortable: true,
isVisible: false
},
{
name: 'imdbRating',
label: translate('ImdbRating'),
isSortable: true,
isVisible: false
},
@@ -224,10 +236,22 @@ export const defaultState = {
return originalLanguage.name;
},
ratings: function(item) {
imdbRating: function(item) {
const { ratings = {} } = item;
return ratings.tmdb? ratings.tmdb.value : 0;
return ratings.imdb ? ratings.imdb.value : 0;
},
tmdbRating: function(item) {
const { ratings = {} } = item;
return ratings.tmdb ? ratings.tmdb.value : 0;
},
rottenTomatoesRating: function(item) {
const { ratings = {} } = item;
return ratings.rottenTomatoes ? ratings.rottenTomatoes.value : 0;
}
},
@@ -413,6 +437,11 @@ export const defaultState = {
label: translate('ImdbRating'),
type: filterBuilderTypes.NUMBER
},
{
name: 'rottenTomatoesRating',
label: translate('RottenTomatoesRating'),
type: filterBuilderTypes.NUMBER
},
{
name: 'imdbVotes',
label: translate('ImdbVotes'),

View File

@@ -1,4 +1,6 @@
using System.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using NLog;
using NLog.Fluent;
@@ -8,47 +10,46 @@ namespace NzbDrone.Common.Instrumentation.Extensions
{
public static readonly Logger SentryLogger = LogManager.GetLogger("Sentry");
public static LogBuilder SentryFingerprint(this LogBuilder logBuilder, params string[] fingerprint)
public static LogEventBuilder SentryFingerprint(this LogEventBuilder logBuilder, params string[] fingerprint)
{
return logBuilder.Property("Sentry", fingerprint);
}
public static LogBuilder WriteSentryDebug(this LogBuilder logBuilder, params string[] fingerprint)
public static LogEventBuilder WriteSentryDebug(this LogEventBuilder logBuilder, params string[] fingerprint)
{
return LogSentryMessage(logBuilder, LogLevel.Debug, fingerprint);
}
public static LogBuilder WriteSentryInfo(this LogBuilder logBuilder, params string[] fingerprint)
public static LogEventBuilder WriteSentryInfo(this LogEventBuilder logBuilder, params string[] fingerprint)
{
return LogSentryMessage(logBuilder, LogLevel.Info, fingerprint);
}
public static LogBuilder WriteSentryWarn(this LogBuilder logBuilder, params string[] fingerprint)
public static LogEventBuilder WriteSentryWarn(this LogEventBuilder logBuilder, params string[] fingerprint)
{
return LogSentryMessage(logBuilder, LogLevel.Warn, fingerprint);
}
public static LogBuilder WriteSentryError(this LogBuilder logBuilder, params string[] fingerprint)
public static LogEventBuilder WriteSentryError(this LogEventBuilder logBuilder, params string[] fingerprint)
{
return LogSentryMessage(logBuilder, LogLevel.Error, fingerprint);
}
private static LogBuilder LogSentryMessage(LogBuilder logBuilder, LogLevel level, string[] fingerprint)
private static LogEventBuilder LogSentryMessage(LogEventBuilder logBuilder, LogLevel level, string[] fingerprint)
{
SentryLogger.Log(level)
.CopyLogEvent(logBuilder.LogEventInfo)
SentryLogger.ForLogEvent(level)
.CopyLogEvent(logBuilder.LogEvent)
.SentryFingerprint(fingerprint)
.Write();
.Log();
return logBuilder.Property("Sentry", null);
return logBuilder.Property<string>("Sentry", null);
}
private static LogBuilder CopyLogEvent(this LogBuilder logBuilder, LogEventInfo logEvent)
private static LogEventBuilder CopyLogEvent(this LogEventBuilder logBuilder, LogEventInfo logEvent)
{
return logBuilder.LoggerName(logEvent.LoggerName)
.TimeStamp(logEvent.TimeStamp)
return logBuilder.TimeStamp(logEvent.TimeStamp)
.Message(logEvent.Message, logEvent.Parameters)
.Properties(logEvent.Properties.ToDictionary(v => v.Key, v => v.Value))
.Properties(logEvent.Properties.Select(p => new KeyValuePair<string, object>(p.Key.ToString(), p.Value)))
.Exception(logEvent.Exception);
}
}

View File

@@ -1,13 +1,16 @@
using NLog;
using System;
using System.Text;
using NLog;
using NLog.Targets;
namespace NzbDrone.Common.Instrumentation
{
public class NzbDroneFileTarget : FileTarget
{
protected override string GetFormattedMessage(LogEventInfo logEvent)
protected override void RenderFormattedMessage(LogEventInfo logEvent, StringBuilder target)
{
return CleanseLogMessage.Cleanse(Layout.Render(logEvent));
var result = CleanseLogMessage.Cleanse(Layout.Render(logEvent));
target.Append(result);
}
}
}

View File

@@ -34,6 +34,8 @@ namespace NzbDrone.Common.Instrumentation
var appFolderInfo = new AppFolderInfo(startupContext);
RegisterGlobalFilters();
if (Debugger.IsAttached)
{
RegisterDebugger();
@@ -97,10 +99,21 @@ namespace NzbDrone.Common.Instrumentation
target.Layout = "[${level}] [${threadid}] ${logger}: ${message} ${onexception:inner=${newline}${newline}[v${assembly-version}] ${exception:format=ToString}${newline}${exception:format=Data}${newline}}";
var loggingRule = new LoggingRule("*", LogLevel.Trace, target);
LogManager.Configuration.AddTarget("debugger", target);
LogManager.Configuration.LoggingRules.Add(loggingRule);
}
private static void RegisterGlobalFilters()
{
LogManager.Setup().LoadConfiguration(c =>
{
c.ForLogger("Microsoft.Hosting.Lifetime*").WriteToNil(LogLevel.Info);
c.ForLogger("System*").WriteToNil(LogLevel.Warn);
c.ForLogger("Microsoft*").WriteToNil(LogLevel.Warn);
});
}
private static void RegisterConsole()
{
var level = LogLevel.Trace;

View File

@@ -8,10 +8,10 @@
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="6.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="NLog" Version="4.7.14" />
<PackageReference Include="NLog.Extensions.Logging" Version="1.7.4" />
<PackageReference Include="NLog" Version="5.0.1" />
<PackageReference Include="NLog.Extensions.Logging" Version="5.0.0" />
<PackageReference Include="Sentry" Version="3.15.0" />
<PackageReference Include="NLog.Targets.Syslog" Version="6.0.3" />
<PackageReference Include="NLog.Targets.Syslog" Version="7.0.0" />
<PackageReference Include="SharpZipLib" Version="1.3.3" />
<PackageReference Include="System.Text.Json" Version="6.0.4" />
<PackageReference Include="System.ValueTuple" Version="4.5.0" />

View File

@@ -56,6 +56,51 @@ namespace NzbDrone.Core.Test.Datastore.Migration
movies.First().CollectionTmdbId.Should().Be(collections.First().TmdbId);
}
[Test]
public void should_skip_collection_from_movie_without_name()
{
var db = WithMigrationTestDb(c =>
{
c.Insert.IntoTable("Movies").Row(new
{
Monitored = true,
MinimumAvailability = 4,
ProfileId = 1,
MovieFileId = 0,
MovieMetadataId = 1,
Path = string.Format("/Movies/{0}", "Title"),
});
c.Insert.IntoTable("MovieMetadata").Row(new
{
Title = "Title",
CleanTitle = "CleanTitle",
Status = 3,
Images = new[] { new { CoverType = "Poster" } }.ToJson(),
Recommendations = new[] { 1 }.ToJson(),
Runtime = 90,
OriginalTitle = "Title",
CleanOriginalTitle = "CleanTitle",
OriginalLanguage = 1,
TmdbId = 132456,
Collection = new { TmdbId = 11 }.ToJson(),
LastInfoSync = DateTime.UtcNow,
});
});
var collections = db.Query<Collection208>("SELECT \"Id\", \"Title\", \"TmdbId\", \"Monitored\" FROM \"Collections\"");
collections.Should().HaveCount(1);
collections.First().TmdbId.Should().Be(11);
collections.First().Title.Should().Be("Collection 11");
collections.First().Monitored.Should().BeFalse();
var movies = db.Query<Movie208>("SELECT \"Id\", \"CollectionTmdbId\" FROM \"MovieMetadata\"");
movies.Should().HaveCount(1);
movies.First().CollectionTmdbId.Should().Be(collections.First().TmdbId);
}
[Test]
public void should_not_duplicate_collection()
{

View File

@@ -176,7 +176,7 @@ namespace NzbDrone.Core.Test.HealthCheck.Checks
public void should_return_ok_on_movie_imported_event()
{
GivenFolderExists(_downloadRootPath);
var importEvent = new MovieImportedEvent(new LocalMovie(), new MovieFile(), new List<MovieFile>(), true, new DownloadClientItem());
var importEvent = new MovieFileImportedEvent(new LocalMovie(), new MovieFile(), new List<MovieFile>(), true, new DownloadClientItem());
Subject.Check(importEvent).ShouldBeOk();
}

View File

@@ -91,7 +91,7 @@ namespace NzbDrone.Core.Test.HistoryTests
DownloadId = "abcd"
};
Subject.Handle(new MovieImportedEvent(localMovie, movieFile, new List<MovieFile>(), true, downloadClientItem));
Subject.Handle(new MovieFileImportedEvent(localMovie, movieFile, new List<MovieFile>(), true, downloadClientItem));
Mocker.GetMock<IHistoryRepository>()
.Verify(v => v.Insert(It.Is<MovieHistory>(h => h.SourceTitle == Path.GetFileNameWithoutExtension(localMovie.Path))));

View File

@@ -26,7 +26,7 @@ namespace NzbDrone.Core.Test.Housekeeping.Housekeepers
}
[Test]
public void should_not_delete_unorphaned_collection_items()
public void should_delete_orphaned_collection_with_meta_but_no_movie_items()
{
var collection = Builder<MovieCollection>.CreateNew()
.With(h => h.Id = 3)
@@ -40,6 +40,27 @@ namespace NzbDrone.Core.Test.Housekeeping.Housekeepers
Db.Insert(movie);
Subject.Clean();
AllStoredModels.Should().HaveCount(0);
}
[Test]
public void should_not_delete_unorphaned_collection()
{
var collection = Builder<MovieCollection>.CreateNew()
.With(h => h.Id = 3)
.With(h => h.TmdbId = 123456)
.With(h => h.Title = "Some Credit")
.BuildNew();
Db.Insert(collection);
var movieMeta = Builder<MovieMetadata>.CreateNew().With(m => m.CollectionTmdbId = collection.TmdbId).BuildNew();
Db.Insert(movieMeta);
var movie = Builder<Movie>.CreateNew().With(m => m.MovieMetadataId = movieMeta.Id).BuildNew();
Db.Insert(movie);
Subject.Clean();
AllStoredModels.Should().HaveCount(1);
}

View File

@@ -144,7 +144,7 @@ namespace NzbDrone.Core.Test.MediaFiles.MovieImport
Subject.Import(new List<ImportDecision> { _approvedDecisions.First() }, true);
Mocker.GetMock<IEventAggregator>()
.Verify(v => v.PublishEvent(It.IsAny<MovieImportedEvent>()), Times.Once());
.Verify(v => v.PublishEvent(It.IsAny<MovieFileImportedEvent>()), Times.Once());
}
[Test]

View File

@@ -67,6 +67,35 @@ namespace NzbDrone.Core.Test.ParserTests
Parser.Parser.ParseMovieTitle(postTitle).PrimaryMovieTitle.Should().Be(title);
}
[TestCase("[MTBB] Kimi no Na wa. (2016) v2 [97681524].mkv", "Kimi no Na wa", "MTBB", 2016)]
[TestCase("[sam] Toward the Terra (1980) [BD 1080p TrueHD].mkv", "Toward the Terra", "sam", 1980)]
public void should_parse_anime_movie_title(string postTitle, string title, string releaseGroup, int year)
{
ParsedMovieInfo movie = Parser.Parser.ParseMovieTitle(postTitle);
using (new AssertionScope())
{
movie.PrimaryMovieTitle.Should().Be(title);
movie.ReleaseGroup.Should().Be(releaseGroup);
movie.Year.Should().Be(year);
}
}
[TestCase("[Arid] Cowboy Bebop - Knockin' on Heaven's Door v2 [00F4CDA0].mkv", "Cowboy Bebop - Knockin' on Heaven's Door", "Arid")]
[TestCase("[Baws] Evangelion 1.11 - You Are (Not) Alone v2 (1080p BD HEVC FLAC) [BF42B1C8].mkv", "Evangelion 1 11 - You Are (Not) Alone", "Baws")]
[TestCase("[Arid] 5 Centimeters per Second (BDRip 1920x1080 Hi10 FLAC) [FD8B6FF2].mkv", "5 Centimeters per Second", "Arid")]
[TestCase("[Baws] Evangelion 2.22 - You Can (Not) Advance (1080p BD HEVC FLAC) [56E7A5B8].mkv", "Evangelion 2 22 - You Can (Not) Advance", "Baws")]
[TestCase("[sam] Goblin Slayer - Goblin's Crown [BD 1080p FLAC] [CD298D48].mkv", "Goblin Slayer - Goblin's Crown", "sam")]
[TestCase("[Kulot] Violet Evergarden Gaiden Eien to Jidou Shuki Ningyou [Dual-Audio][BDRip 1920x804 HEVC FLACx2] [91FC62A8].mkv", "Violet Evergarden Gaiden Eien to Jidou Shuki Ningyou", "Kulot")]
public void should_parse_anime_movie_title_without_year(string postTitle, string title, string releaseGroup)
{
ParsedMovieInfo movie = Parser.Parser.ParseMovieTitle(postTitle);
using (new AssertionScope())
{
movie.PrimaryMovieTitle.Should().Be(title);
movie.ReleaseGroup.Should().Be(releaseGroup);
}
}
[TestCase("Movie.Aufbruch.nach.Pandora.Extended.2009.German.DTS.720p.BluRay.x264-SoW", "Movie Aufbruch nach Pandora", "Extended", 2009)]
[TestCase("Drop.Movie.1994.German.AC3D.DL.720p.BluRay.x264-KLASSiGERHD", "Drop Movie", "", 1994)]
[TestCase("Kick.Movie.2.2013.German.DTS.DL.720p.BluRay.x264-Pate", "Kick Movie 2", "", 2013)]

View File

@@ -189,6 +189,7 @@ namespace NzbDrone.Core.Test.ParserTests
[TestCase("Movie.Title.2020.MULTi.1080p.WEB.H264-ALLDAYiN (S:285/L:11)", false)]
[TestCase("Movie Title (2020) MULTi WEB 1080p x264-JiHEFF (S:317/L:28)", false)]
[TestCase("Movie.Titles.2020.1080p.NF.WEB.DD2.0.x264-SNEAkY", false)]
[TestCase("The.Movie.2022.NORDiC.1080p.DV.HDR.WEB.H 265-NiDHUG", false)]
public void should_parse_webdl1080p_quality(string title, bool proper)
{
ParseAndVerifyQuality(title, Source.WEBDL, proper, Resolution.R1080p);
@@ -207,6 +208,7 @@ namespace NzbDrone.Core.Test.ParserTests
[TestCase("Movie.Name.2016.03.14.2160p.WEB.PROPER.h264-spamTV", true)]
[TestCase("[HorribleSubs] Movie Title! 2018 [Web][MKV][h264][2160p][AAC 2.0][Softsubs (HorribleSubs)]", false)]
[TestCase("Movie Name 2020 WEB-DL 4K H265 10bit HDR DDP5.1 Atmos-PTerWEB", false)]
[TestCase("The.Movie.2022.NORDiC.2160p.DV.HDR.WEB.H.265-NiDHUG", false)]
public void should_parse_webdl2160p_quality(string title, bool proper)
{
ParseAndVerifyQuality(title, Source.WEBDL, proper, Resolution.R2160p);

View File

@@ -85,7 +85,7 @@ namespace NzbDrone.Core.Datastore.Migration
var moviePath = reader.GetString(3);
var data = STJson.Deserialize<MovieCollection207>(collection);
if (newCollections.Any(d => d.TmdbId == data.TmdbId))
if (data.TmdbId == 0 || newCollections.Any(d => d.TmdbId == data.TmdbId))
{
continue;
}
@@ -104,12 +104,14 @@ namespace NzbDrone.Core.Datastore.Migration
rootFolderPath = moviePath.GetParentPath();
}
var collectionName = data.Name ?? $"Collection {data.TmdbId}";
newCollections.Add(new MovieCollection208
{
TmdbId = data.TmdbId,
Title = data.Name,
CleanTitle = data.Name.CleanMovieTitle(),
SortTitle = Parser.Parser.NormalizeTitle(data.Name),
Title = collectionName,
CleanTitle = collectionName.CleanMovieTitle(),
SortTitle = Parser.Parser.NormalizeTitle(collectionName),
Added = added,
QualityProfileId = qualityProfileId,
RootFolderPath = rootFolderPath,

View File

@@ -0,0 +1,15 @@
using FluentMigrator;
using NzbDrone.Core.Datastore.Migration.Framework;
namespace NzbDrone.Core.Datastore.Migration
{
[Migration(211)]
public class more_movie_meta_index : NzbDroneMigrationBase
{
protected override void MainDbUpgrade()
{
Create.Index("IX_AlternativeTitles_MovieMetadataId").OnTable("AlternativeTitles").OnColumn("MovieMetadataId");
Create.Index("IX_Credits_MovieMetadataId").OnTable("Credits").OnColumn("MovieMetadataId");
}
}
}

View File

@@ -180,14 +180,14 @@ namespace NzbDrone.Core.Download
}
else
{
_logger.Debug()
_logger.ForDebugEvent()
.Message("No Movies were just imported, but all movies were previously imported, possible issue with download history.")
.Property("MovieId", trackedDownload.RemoteMovie.Movie.Id)
.Property("DownloadId", trackedDownload.DownloadItem.DownloadId)
.Property("Title", trackedDownload.DownloadItem.Title)
.Property("Path", trackedDownload.ImportItem.OutputPath.ToString())
.WriteSentryWarn("DownloadHistoryIncomplete")
.Write();
.Log();
}
trackedDownload.State = TrackedDownloadState.Imported;

View File

@@ -17,7 +17,7 @@ namespace NzbDrone.Core.Download.History
public class DownloadHistoryService : IDownloadHistoryService,
IHandle<MovieGrabbedEvent>,
IHandle<MovieImportedEvent>,
IHandle<MovieFileImportedEvent>,
IHandle<DownloadCompletedEvent>,
IHandle<DownloadFailedEvent>,
IHandle<DownloadIgnoredEvent>,
@@ -120,7 +120,7 @@ namespace NzbDrone.Core.Download.History
_repository.Insert(history);
}
public void Handle(MovieImportedEvent message)
public void Handle(MovieFileImportedEvent message)
{
if (!message.NewDownload)
{

View File

@@ -14,7 +14,7 @@ namespace NzbDrone.Core.Download.TrackedDownloads
public class DownloadMonitoringService : IExecute<RefreshMonitoredDownloadsCommand>,
IExecute<CheckForFinishedDownloadCommand>,
IHandle<MovieGrabbedEvent>,
IHandle<MovieImportedEvent>,
IHandle<MovieFileImportedEvent>,
IHandle<DownloadsProcessedEvent>,
IHandle<TrackedDownloadsRemovedEvent>
{
@@ -167,7 +167,7 @@ namespace NzbDrone.Core.Download.TrackedDownloads
_refreshDebounce.Execute();
}
public void Handle(MovieImportedEvent message)
public void Handle(MovieFileImportedEvent message)
{
_refreshDebounce.Execute();
}

View File

@@ -158,22 +158,32 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Xbmc
{
var setRating = new XElement("ratings");
if (movie.MovieMetadata.Value.Ratings.Tmdb?.Votes > 0)
{
var setRatethemoviedb = new XElement("rating", new XAttribute("name", "themoviedb"), new XAttribute("max", "10"), new XAttribute("default", "true"));
setRatethemoviedb.Add(new XElement("value", movie.MovieMetadata.Value.Ratings.Tmdb.Value));
setRatethemoviedb.Add(new XElement("votes", movie.MovieMetadata.Value.Ratings.Tmdb.Votes));
setRating.Add(setRatethemoviedb);
}
var defaultRatingSet = false;
if (movie.MovieMetadata.Value.Ratings.Imdb?.Votes > 0)
{
var setRateImdb = new XElement("rating", new XAttribute("name", "imdb"), new XAttribute("max", "10"));
var setRateImdb = new XElement("rating", new XAttribute("name", "imdb"), new XAttribute("max", "10"), new XAttribute("default", "true"));
setRateImdb.Add(new XElement("value", movie.MovieMetadata.Value.Ratings.Imdb.Value));
setRateImdb.Add(new XElement("votes", movie.MovieMetadata.Value.Ratings.Imdb.Votes));
defaultRatingSet = true;
setRating.Add(setRateImdb);
}
if (movie.MovieMetadata.Value.Ratings.Tmdb?.Votes > 0)
{
var setRatethemoviedb = new XElement("rating", new XAttribute("name", "themoviedb"), new XAttribute("max", "10"));
setRatethemoviedb.Add(new XElement("value", movie.MovieMetadata.Value.Ratings.Tmdb.Value));
setRatethemoviedb.Add(new XElement("votes", movie.MovieMetadata.Value.Ratings.Tmdb.Votes));
if (!defaultRatingSet)
{
setRatethemoviedb.SetAttributeValue("default", "true");
}
setRating.Add(setRatethemoviedb);
}
details.Add(setRating);
}

View File

@@ -10,7 +10,7 @@ using NzbDrone.Core.ThingiProvider.Events;
namespace NzbDrone.Core.HealthCheck.Checks
{
[CheckOn(typeof(ProviderUpdatedEvent<IImportList>))]
[CheckOn(typeof(MovieImportedEvent), CheckOnCondition.FailedOnly)]
[CheckOn(typeof(MovieFileImportedEvent), CheckOnCondition.FailedOnly)]
[CheckOn(typeof(MovieImportFailedEvent), CheckOnCondition.SuccessfulOnly)]
public class ImportListRootFolderCheck : HealthCheckBase
{

View File

@@ -2,13 +2,15 @@ using System.Collections.Generic;
using System.Linq;
using NzbDrone.Common.Disk;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.Datastore.Events;
using NzbDrone.Core.Localization;
using NzbDrone.Core.Movies.Collections;
using NzbDrone.Core.Movies.Events;
using NzbDrone.Core.RootFolders;
namespace NzbDrone.Core.HealthCheck.Checks
{
[CheckOn(typeof(CollectionEditedEvent), CheckOnCondition.Always)]
[CheckOn(typeof(ModelEvent<RootFolder>))]
public class MovieCollectionRootFolderCheck : HealthCheckBase
{
private readonly IMovieCollectionService _collectionService;

View File

@@ -20,7 +20,7 @@ namespace NzbDrone.Core.HealthCheck.Checks
[CheckOn(typeof(ProviderUpdatedEvent<IDownloadClient>))]
[CheckOn(typeof(ProviderDeletedEvent<IDownloadClient>))]
[CheckOn(typeof(ModelEvent<RemotePathMapping>))]
[CheckOn(typeof(MovieImportedEvent), CheckOnCondition.FailedOnly)]
[CheckOn(typeof(MovieFileImportedEvent), CheckOnCondition.FailedOnly)]
[CheckOn(typeof(MovieImportFailedEvent), CheckOnCondition.SuccessfulOnly)]
public class RemotePathMappingCheck : HealthCheckBase, IProvideHealthCheck
{

View File

@@ -77,12 +77,15 @@ namespace NzbDrone.Core.HealthCheck
.ToDictionary(g => g.Key, g => g.ToArray());
}
private void PerformHealthCheck(IProvideHealthCheck[] healthChecks)
private void PerformHealthCheck(IProvideHealthCheck[] healthChecks, bool performServerChecks = false)
{
var results = healthChecks.Select(c => c.Check())
.ToList();
results.AddRange(_serverSideNotificationService.GetServerChecks());
if (performServerChecks)
{
results.AddRange(_serverSideNotificationService.GetServerChecks());
}
foreach (var result in results)
{
@@ -108,17 +111,17 @@ namespace NzbDrone.Core.HealthCheck
{
if (message.Trigger == CommandTrigger.Manual)
{
PerformHealthCheck(_healthChecks);
PerformHealthCheck(_healthChecks, true);
}
else
{
PerformHealthCheck(_scheduledHealthChecks);
PerformHealthCheck(_scheduledHealthChecks, true);
}
}
public void HandleAsync(ApplicationStartedEvent message)
{
PerformHealthCheck(_startupHealthChecks);
PerformHealthCheck(_startupHealthChecks, true);
}
public void HandleAsync(IEvent message)

View File

@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using NLog;
using NzbDrone.Common.Cache;
using NzbDrone.Common.Cloud;
using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Common.Http;
@@ -23,24 +24,37 @@ namespace NzbDrone.Core.HealthCheck
private readonly IHttpRequestBuilderFactory _cloudRequestBuilder;
private readonly Logger _logger;
public ServerSideNotificationService(IHttpClient client, IConfigFileProvider configFileProvider, IRadarrCloudRequestBuilder cloudRequestBuilder, Logger logger)
private readonly ICached<List<HealthCheck>> _cache;
public ServerSideNotificationService(IHttpClient client,
IConfigFileProvider configFileProvider,
IRadarrCloudRequestBuilder cloudRequestBuilder,
ICacheManager cacheManager,
Logger logger)
{
_client = client;
_configFileProvider = configFileProvider;
_cloudRequestBuilder = cloudRequestBuilder.Services;
_logger = logger;
_cache = cacheManager.GetCache<List<HealthCheck>>(GetType());
}
public List<HealthCheck> GetServerChecks()
{
return _cache.Get("ServerChecks", () => RetrieveServerChecks(), TimeSpan.FromHours(2));
}
private List<HealthCheck> RetrieveServerChecks()
{
var request = _cloudRequestBuilder.Create()
.Resource("/notification")
.AddQueryParam("version", BuildInfo.Version)
.AddQueryParam("os", OsInfo.Os.ToString().ToLowerInvariant())
.AddQueryParam("arch", RuntimeInformation.OSArchitecture)
.AddQueryParam("runtime", PlatformInfo.Platform.ToString().ToLowerInvariant())
.AddQueryParam("branch", _configFileProvider.Branch)
.Build();
.Resource("/notification")
.AddQueryParam("version", BuildInfo.Version)
.AddQueryParam("os", OsInfo.Os.ToString().ToLowerInvariant())
.AddQueryParam("arch", RuntimeInformation.OSArchitecture)
.AddQueryParam("runtime", PlatformInfo.Platform.ToString().ToLowerInvariant())
.AddQueryParam("branch", _configFileProvider.Branch)
.Build();
try
{
_logger.Trace("Getting server side health notifications");

View File

@@ -27,13 +27,13 @@ namespace NzbDrone.Core.History
List<MovieHistory> FindByDownloadId(string downloadId);
List<MovieHistory> GetByMovieId(int movieId, MovieHistoryEventType? eventType);
void UpdateMany(List<MovieHistory> toUpdate);
string FindDownloadId(MovieImportedEvent trackedDownload);
string FindDownloadId(MovieFileImportedEvent trackedDownload);
List<MovieHistory> Since(DateTime date, MovieHistoryEventType? eventType);
}
public class HistoryService : IHistoryService,
IHandle<MovieGrabbedEvent>,
IHandle<MovieImportedEvent>,
IHandle<MovieFileImportedEvent>,
IHandle<DownloadFailedEvent>,
IHandle<MovieFileDeletedEvent>,
IHandle<MovieFileRenamedEvent>,
@@ -97,7 +97,7 @@ namespace NzbDrone.Core.History
_historyRepository.UpdateMany(toUpdate);
}
public string FindDownloadId(MovieImportedEvent trackedDownload)
public string FindDownloadId(MovieFileImportedEvent trackedDownload)
{
_logger.Debug("Trying to find downloadId for {0} from history", trackedDownload.ImportedMovie.Path);
@@ -170,7 +170,7 @@ namespace NzbDrone.Core.History
_historyRepository.Insert(history);
}
public void Handle(MovieImportedEvent message)
public void Handle(MovieFileImportedEvent message)
{
if (!message.NewDownload)
{

View File

@@ -16,12 +16,10 @@ namespace NzbDrone.Core.Housekeeping.Housekeepers
{
using (var mapper = _database.OpenConnection())
{
mapper.Execute(@"DELETE FROM ""Collections""
WHERE ""TmdbId"" IN (
SELECT ""Collections"".""TmdbId"" FROM ""Collections""
LEFT OUTER JOIN ""MovieMetadata""
ON ""Collections"".""TmdbId"" = ""MovieMetadata"".""CollectionTmdbId""
WHERE ""MovieMetadata"".""Id"" IS NULL)");
mapper.Execute(@"DELETE FROM ""Collections"" WHERE ""TmdbId"" IN (SELECT ""X"".""TmdbId"" FROM (SELECT ""Collections"".""TmdbId"", COUNT(""Movies"".""Id"") as ""MovieCount"" FROM ""Collections""
LEFT OUTER JOIN ""MovieMetadata"" ON ""Collections"".""TmdbId"" = ""MovieMetadata"".""CollectionTmdbId""
LEFT OUTER JOIN ""Movies"" ON ""Movies"".""MovieMetadataId"" = ""MovieMetadata"".""Id""
GROUP BY ""Collections"".""Id"") AS ""X"" WHERE ""X"".""MovieCount"" = 0)");
}
}
}

View File

@@ -1,4 +1,4 @@
using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq;
using NLog;
using NLog.Config;
@@ -117,7 +117,6 @@ namespace NzbDrone.Core.Instrumentation
syslogTarget.MessageSend.Protocol = ProtocolType.Udp;
syslogTarget.MessageSend.Udp.Port = syslogPort;
syslogTarget.MessageSend.Udp.Server = syslogServer;
syslogTarget.MessageSend.Udp.ReconnectInterval = 500;
syslogTarget.MessageCreation.Rfc = RfcNumber.Rfc5424;
syslogTarget.MessageCreation.Rfc5424.AppName = _configFileProvider.InstanceName;

View File

@@ -59,7 +59,7 @@
"IndexerRssHealthCheckNoIndexers": "Da keine Indexer mit aktivierter RSS-Synchronisierung verfügbar sind, erfasst Radarr nicht automatisch neue Releases auf",
"IndexerSearchCheckNoAutomaticMessage": "Keine Indexer mit aktivierter automatischer Suche verfügbar. Radarr liefert keine automatischen Suchergebnisse",
"IndexerSearchCheckNoAvailableIndexersMessage": "Alle suchfähigen Indexer sind aufgrund der kürzlichen Indexerfehler vorübergehend nicht verfügbar",
"IndexerSearchCheckNoInteractiveMessage": "Keine Indexer mit interaktiver Suche aktiviert, Radarr liefert keine interaktiven Suchergebnisse",
"IndexerSearchCheckNoInteractiveMessage": "Keine Indexer mit aktivierter interaktiver Suche verfügbar, Radarr liefert keine interaktiven Suchergebnisse",
"IndexerStatusCheckAllClientMessage": "Alle Indexer sind aufgrund von Fehlern nicht verfügbar",
"IndexerStatusCheckSingleClientMessage": "Indexer aufgrund von Fehlern nicht verfügbar: {0}",
"Indexers": "Indexer",
@@ -506,7 +506,7 @@
"ScriptPath": "Script Pfad",
"SetPermissions": "Rechte setzen",
"SetPermissionsLinuxHelpTextWarning": "Ändere diese Einstellung nur, wenn du weißt was sie bewirken.",
"ShouldMonitorHelpText": "Beobachte Filme die von dieser Liste hinzugefügt wurden",
"ShouldMonitorHelpText": "Sollen von dieser Liste hinzugefügte Filme oder Sammlungen als beobachtet hinzugefügt werden",
"ShowAsAllDayEvents": "Als Ganztags Events anzeigen",
"ShowCutoffUnmetIconHelpText": "Symbol zeigen wenn die Qualitätsschwelle noch nicht erreicht wurde",
"ShowMovieInformationHelpText": "Genre und Zertifizierung anzeigen",
@@ -633,7 +633,7 @@
"ShowGenres": "Genres anzeigen",
"ShowCertification": "Zertifikation anzeigen",
"SettingsRuntimeFormat": "Laufzeit Format",
"SearchOnAddHelpText": "Suche nach den Filmen auf der Liste nach dem hinzufügen",
"SearchOnAddHelpText": "Nach Filmen auf dieser Liste suchen, wenn sie der Bibliothek hinzugefügt werden",
"RSSSyncIntervalHelpTextWarning": "Dies wird alle Indexer betreffen. Bitte folge deren Regeln",
"RSSIsNotSupportedWithThisIndexer": "RSS wird von diesem Indexer nicht unterstützt",
"RetryingDownloadInterp": "Herunterladen nochmal versuchen {0} um {1}",
@@ -1116,5 +1116,30 @@
"Collections": "Sammlung",
"MonitorMovies": "Film beobachten",
"NoCollections": "Keine Filme gefunden. Zum Starten solltest du einen Film hinzufügen oder vorhandene Importieren.",
"RssSyncHelpText": "Intervall in Minuten. Zum deaktivieren auf 0 setzen ( Dies wird das automatische Release erfassen deaktivieren )"
"RssSyncHelpText": "Intervall in Minuten. Zum deaktivieren auf 0 setzen ( Dies wird das automatische Release erfassen deaktivieren )",
"CollectionOptions": "Sammlung Optionen",
"ChooseImportMode": "Wähle eine Importmethode",
"CollectionsSelectedInterp": "{0} Ausgewählte Sammlung(en)",
"MovieCollectionMissingRoot": "Fehlender Stammordner für die Filmsammlung: {0}",
"EditCollection": "Sammlung bearbeiten",
"MonitoredCollectionHelpText": "Beobachten zur automatischen Aufnahme von Filmen aus dieser Sammlung in die Bibliothek",
"MovieOnly": "Nur Film",
"ScrollMovies": "Filme scrollen",
"ShowCollectionDetails": "Status der Sammlung anzeigen",
"RefreshCollections": "Sammlungen aktualisieren",
"RefreshMonitoredIntervalHelpText": "Wie häufig die beobachteten Downloads von Download-Clients aktualisiert werden sollen (Min. 1 Minute).",
"ShowOverview": "Übersicht anzeigen",
"ShowPosters": "Plakate anzeigen",
"CollectionShowDetailsHelpText": "Status und Eigenschaften der Sammlung anzeigen",
"CollectionShowPostersHelpText": "Poster der Sammlungseinträge zeigen",
"SearchOnAddCollectionHelpText": "Nach Filmen in dieser Sammlung suchen, wenn sie der Bibliothek hinzugefügt werden",
"CollectionShowOverviewsHelpText": "Sammlungsübersichten anzeigen",
"MonitorCollection": "Sammlung beobachten",
"MovieAndCollection": "Film und Sammlung",
"MovieCollectionMultipleMissingRoots": "Es fehlen mehrere Stammordner für Filmsammlungen: {0}",
"OnMovieAdded": "Bei Film hinzugefügt",
"OnMovieAddedHelpText": "Ausführen wenn ein Film hinzugefügt wurde",
"UnableToLoadCollections": "Sammlungen können nicht geladen werden",
"InstanceName": "Instanzname",
"InstanceNameHelpText": "Instanzname im Browser-Tab und für Syslog-Anwendungsname"
}

View File

@@ -859,6 +859,7 @@
"RootFolderCheckMultipleMessage": "Multiple root folders are missing: {0}",
"RootFolderCheckSingleMessage": "Missing root folder: {0}",
"RootFolders": "Root Folders",
"RottenTomatoesRating": "Tomato Rating",
"RSS": "RSS",
"RSSIsNotSupportedWithThisIndexer": "RSS is not supported with this indexer",
"RSSSync": "RSS Sync",

View File

@@ -1115,5 +1115,9 @@
"AllCollectionsHiddenDueToFilter": "Todas las películas están ocultas debido al filtro aplicado.",
"Collections": "Colección",
"MonitorMovies": "Monitorear Película",
"NoCollections": "No se encontraron películas, para comenzar, querrá agregar una nueva película o importar algunas existentes."
"NoCollections": "No se encontraron películas, para comenzar, querrá agregar una nueva película o importar algunas existentes.",
"ChooseImportMode": "Elegir Modo de Importación",
"CollectionOptions": "Opciones de la Colección",
"CollectionShowDetailsHelpText": "Mostrar el estado y propiedades de la colección",
"CollectionShowOverviewsHelpText": "Mostrar resumenes de la colección"
}

View File

@@ -1115,7 +1115,7 @@
"RefreshMonitoredIntervalHelpText": "Miten usein valvottujen latausten tiedot päivitetään lataustyökaluilta (vähimmäisaika on 1 minuutti).",
"RssSyncHelpText": "Aikaväli minuutteina. Arvo nolla kytkee toiminnon pois käytöstä ja lopettaen samalla automaattisen julkaisujen kaappauksen täysin.",
"InstanceName": "Instanssin nimi",
"InstanceNameHelpText": "Instanssin nimi välilehdellä ja sovelluksen Syslog-nimeksi",
"InstanceNameHelpText": "Instanssin nimi välilehdellä ja järjestelmälokissa",
"AllCollectionsHiddenDueToFilter": "Käytössä oleva suodatin on piilottanut kaikki kokoelmat.",
"Collections": "Kokoelmat",
"MonitorMovies": "Valvo elokuvia",
@@ -1141,5 +1141,6 @@
"CollectionShowOverviewsHelpText": "Näytä kokoelmien katsaukset",
"CollectionOptions": "Kokoelmien valinnat",
"CollectionShowDetailsHelpText": "Näytä kokoelmien tila ja ominaisuudet",
"CollectionShowPostersHelpText": "Näytä kokoelmien julisteet"
"CollectionShowPostersHelpText": "Näytä kokoelmien julisteet",
"RottenTomatoesRating": "Tomaattiarvio"
}

View File

@@ -1137,5 +1137,10 @@
"CollectionOptions": "Gyűjtemény baállítások",
"CollectionShowOverviewsHelpText": "Gyűjtemények áttekintésének megjelenítése",
"CollectionShowDetailsHelpText": "A gyűjtemény állapotának és tulajdonságainak megjelenítése",
"CollectionShowPostersHelpText": "Gyűjteményelemek posztereinek megjelenítése"
"CollectionShowPostersHelpText": "Gyűjteményelemek posztereinek megjelenítése",
"OnMovieAdded": "Film hozzáadásakor",
"OnMovieAddedHelpText": "Film hozzáadásakor",
"ShowPosters": "Poszterek megjelenítése",
"InstanceNameHelpText": "Példánynév a böngésző lapon és a syslog alkalmazás neve",
"RottenTomatoesRating": "Tomato Értékelés"
}

View File

@@ -0,0 +1 @@
{}

View File

@@ -177,5 +177,82 @@
"ColonReplacementFormatHelpText": "Endre hvordan Radarr håndterer kolonerstatning",
"ConnectionLostAutomaticMessage": "Radarr vil forsøke å koble til automatisk, eller du kan klikke oppdater nedenfor.",
"ConnectSettingsSummary": "Varslinger, tilkoblinger til mediaservere/avspillere, og tilpassede scripts",
"CopyUsingHardlinksHelpTextWarning": "I blant kan låste filer forhindre å endre navn på filer som blir delt. Du kan midlertidig deaktivere deling og bruke Raddars navnefunksjon for å jobbe rundt dette."
"CopyUsingHardlinksHelpTextWarning": "I blant kan låste filer forhindre å endre navn på filer som blir delt. Du kan midlertidig deaktivere deling og bruke Raddars navnefunksjon for å jobbe rundt dette.",
"Movies": "Film",
"DeleteCustomFormat": "Klon egendefinert format",
"Deleted": "Slett",
"Indexers": "Indeksere",
"Queued": "Kø",
"Title": "Tittel",
"Updates": "Oppdater",
"Lists": "Liste",
"Search": "Søk",
"Titles": "Tittel",
"Password": "Passord",
"Peers": "Likemenn",
"Port": "Port",
"Posters": "Plakater",
"Protocol": "Protokoll",
"Quality": "kvalitet",
"QualityProfile": "Kvaltietsprofil",
"Ratings": "Vurdering",
"Refresh": "Oppdater",
"Reload": "Likemenn",
"Remove": "Slett",
"Replace": "Erstatt",
"Required": "Kreve",
"Restrictions": "Begrensning",
"RootFolder": "Rotmappe",
"RootFolders": "Rotmappe",
"Runtime": "Kjøretid",
"Scheduled": "Planlagt",
"Seeders": "Delere",
"Settings": "Innstillinger",
"SettingsRemotePathMappingLocalPath": "Lokal sti",
"Torrents": "Torrents",
"Trakt": "Trakt",
"URLBase": "URL Base",
"Username": "Brukernavn",
"Delete": "Slett",
"Info": "Info",
"LocalPath": "Lokal sti",
"Usenet": "Usenet",
"QualityProfiles": "Kvaltietsprofil",
"Queue": "Kø",
"Rating": "Vurdering",
"UI": "Grensesnitt",
"UpdateMechanismHelpText": "Bruk Prowlarrs innebygde oppdaterer eller et skript",
"RSS": "RSS",
"DelayProfile": "Utsetningsprofil",
"DelayProfiles": "Utsetningsprofil",
"Enable": "Aktiver",
"Enabled": "Aktiver",
"Events": "Hendelse",
"Files": "Fil",
"Filter": "Filter",
"Filters": "Filtre",
"Formats": "Format",
"Grab": "Hent",
"Host": "Vert",
"Hostname": "Vertsnavn",
"ICalFeed": "iCal Feed",
"iCalLink": "iCal Link",
"IMDb": "IMDb",
"Indexer": "Indekser",
"Metadata": "metadata",
"Movie": "Film",
"Crew": "Besetning",
"Details": "detaljer",
"RecyclingBin": "Papirkurv",
"Custom": "Tilpass",
"CustomFormat": "Egendefinert format",
"CustomFormats": "Egendefinert format",
"Cutoff": "Avskjæring",
"Disabled": "deaktivert",
"DownloadClient": "Nedlastingsklient",
"DownloadClients": "Nedlastingsklient",
"Language": "språk",
"List": "Liste",
"New": "Ny",
"RemotePathMappings": "Ekstern portmapping"
}

View File

@@ -246,10 +246,10 @@
"ImportMechanismHealthCheckMessage": "Włącz obsługę ukończonego pobierania",
"IndexersSettingsSummary": "Indeksatory i ograniczenia dotyczące wersji",
"InvalidFormat": "Niepoprawny format",
"ChmodFolder": "chmod Folder",
"ChmodFolder": "chmod Folderu",
"ChmodFolderHelpText": "Ósemkowy, stosowany podczas importu / zmiany nazwy do folderów multimedialnych i plików (bez bitów wykonania)",
"ChmodFolderHelpTextWarning": "Działa to tylko wtedy, gdy użytkownik uruchamiający Radarr jest właścicielem pliku. Lepiej jest upewnić się, że klient pobierania prawidłowo ustawia uprawnienia.",
"ChmodGroup": "chmod Group",
"ChmodGroup": "chmod Grupy",
"ChmodGroupHelpText": "Nazwa grupy lub identyfikator. Użyj gid dla zdalnych systemów plików.",
"ChmodGroupHelpTextWarning": "Działa to tylko wtedy, gdy użytkownik uruchamiający Radarr jest właścicielem pliku. Lepiej jest upewnić się, że klient pobierania używa tej samej grupy co Radarr.",
"ListSyncLevelHelpTextWarning": "Pliki filmowe zostaną trwale usunięte, co może spowodować wyczyszczenie biblioteki, jeśli listy są puste",
@@ -259,7 +259,7 @@
"Medium": "Średni",
"Minutes": "Minuty",
"ListExclusions": "Wykluczenia z listy",
"MissingFromDisk": "Radarr nie mógł znaleźć pliku na dysku, więc został odłączony od filmu w bazie danych.",
"MissingFromDisk": "Radarr nie mógł znaleźć pliku na dysku, więc został odłączony od filmu w bazie danych",
"Monday": "poniedziałek",
"MoveFiles": "Przenieś pliki",
"MovieIsRecommend": "Film jest zalecany na podstawie niedawnego dodania",
@@ -484,8 +484,8 @@
"ClickToChangeMovie": "Kliknij, aby zmienić film",
"ClickToChangeQuality": "Kliknij, aby zmienić jakość",
"CloneCustomFormat": "Klonuj format niestandardowy",
"CloneFormatTag": "Clone Format Tag",
"CloneIndexer": "Clone Indexer",
"CloneFormatTag": "Klonuj Tag Formatu",
"CloneIndexer": "Sklonuj Indekser",
"CloneProfile": "Klonuj profil",
"Close": "Blisko",
"ColonReplacement": "Wymiana okrężnicy",
@@ -497,7 +497,7 @@
"Connection": "Połączenie",
"ConnectionLost": "Utracono połączenie",
"ConnectionLostAutomaticMessage": "Radarr spróbuje połączyć się automatycznie lub możesz kliknąć przycisk przeładuj poniżej.",
"ConnectionLostMessage": "Radarr utracił połączenie z zapleczem i będzie musiał zostać ponownie załadowany, aby przywrócić funkcjonalność.",
"ConnectionLostMessage": "Radarr utracił połączenie z silnikiem programu, aby przywrócić funkcjonalność musi zostać zrestartowany.",
"Connections": "Znajomości",
"ConnectSettings": "Ustawienia połączenia",
"ConnectSettingsSummary": "Powiadomienia, połączenia z serwerami / odtwarzaczami multimedialnymi i niestandardowe skrypty",
@@ -545,7 +545,7 @@
"DeleteRestrictionHelpText": "Czy na pewno chcesz usunąć to ograniczenie?",
"DeleteSelectedMovie": "Usuń wybrane filmy",
"DeleteTagMessageText": "Czy na pewno chcesz usunąć tag „{0}”?",
"DeleteTheMovieFolder": "Folder filmów „{0} i cała jego zawartość zostaną usunięte.",
"DeleteTheMovieFolder": "Folder '{0}' i cała jego zawartość zostaną usunięte.",
"DestinationPath": "Ścieżka docelowa",
"DestinationRelativePath": "Względna ścieżka celu",
"DetailedProgressBar": "Szczegółowy pasek postępu",
@@ -570,7 +570,7 @@
"DownloadFailed": "Pobieranie nie udane",
"DownloadFailedInterp": "Pobieranie nie powiodło się: {0}",
"Downloading": "Ściąganie",
"DownloadPropersAndRepacks": "Propers and Repacks",
"DownloadPropersAndRepacks": "Poprawione i przepakowane",
"DownloadPropersAndRepacksHelpTextWarning": "Użyj niestandardowych formatów do automatycznej aktualizacji do Propers / Repacks",
"DownloadWarningCheckDownloadClientForMoreDetails": "Ostrzeżenie dotyczące pobierania: sprawdź klienta pobierania, aby uzyskać więcej informacji",
"Edition": "Wydanie",
@@ -638,8 +638,8 @@
"GoToInterp": "Idź do {0}",
"Grab": "Chwycić",
"Grabbed": "Złapał",
"GrabID": "Grab ID",
"GrabRelease": "Grab Release",
"GrabID": "Pobierz ID",
"GrabRelease": "Pobierz Wydanie",
"GrabReleaseMessageText": "Radarr nie był w stanie określić, dla którego filmu jest to wydanie. Radarr może nie być w stanie automatycznie zaimportować tej wersji. Czy chcesz złapać „{0}”?",
"GrabSelected": "Wybierz wybrane",
"Group": "Grupa",
@@ -650,7 +650,7 @@
"HideAdvanced": "Ukryj zaawansowane",
"History": "Historia",
"Host": "Gospodarz",
"iCalLink": "iCal Link",
"iCalLink": "Łącze do iCal",
"IconForCutoffUnmet": "Ikona Cutoff Unmet",
"IgnoredAddresses": "Ignorowane adresy",
"IgnoreDeletedMovies": "Nie monitoruj usuniętych filmów",
@@ -669,7 +669,7 @@
"IncludeUnknownMovieItemsHelpText": "Pokaż elementy bez filmu w kolejce. Może to obejmować usunięte filmy lub cokolwiek innego w kategorii Radarr",
"ImportMovies": "Importuj filmy",
"IndexerPriority": "Priorytet indeksatora",
"IndexerPriorityHelpText": "Priorytet indeksera od 1 (najwyższy) do 50 (najniższy). Domyślnie: 25. Używany podczas pobierania wydań przy wystąpieniu równoważnych wydań. Przy synchronizacji RSS i wyszukiwaniu, Radarr wciąż będzie korzystał ze wszystkich indekserów.",
"IndexerPriorityHelpText": "Priorytet indeksera od 1 (najwyższy) do 50 (najniższy). Domyślnie: 25. Używany podczas pobierania wydań przy wystąpieniu równoważnych wydań. Przy synchronizacji RSS i wyszukiwaniu, Radarr wciąż będzie korzystał ze wszystkich indekserów",
"Indexers": "Indeksatory",
"IndexerSearchCheckNoAutomaticMessage": "Brak dostępnych indeksatorów z włączoną funkcją automatycznego wyszukiwania, Radarr nie zapewni żadnych automatycznych wyników wyszukiwania",
"IndexerSearchCheckNoAvailableIndexersMessage": "Wszystkie indeksatory z możliwością wyszukiwania są tymczasowo niedostępne z powodu ostatnich błędów indeksatora",
@@ -701,7 +701,7 @@
"Logs": "Dzienniki",
"LookingForReleaseProfiles1": "Szukasz profili wersji? Próbować",
"LookingForReleaseProfiles2": "zamiast.",
"LowerCase": "Małe litery",
"LowerCase": "Z małej litery",
"ManualImportSelectLanguage": "Import ręczny - wybierz język",
"ManualImportSelectMovie": "Import ręczny - wybierz film",
"MappedDrivesRunningAsService": "Zmapowane dyski sieciowe nie są dostępne, gdy działają jako usługa systemu Windows. Więcej informacji można znaleźć w FAQ",
@@ -740,7 +740,7 @@
"MovieInvalidFormat": "Film: nieprawidłowy format",
"MultiLanguage": "Wielojęzyczny",
"Negate": "Negować",
"Negated": "Negated",
"Negated": "Zanegowane",
"NoListRecommendations": "Nie znaleziono żadnych pozycji na liście ani rekomendacji. Aby rozpocząć, musisz dodać nowy film, zaimportować istniejące lub dodać listę.",
"NoTagsHaveBeenAddedYet": "Żadne tagi nie zostały jeszcze dodane",
"Options": "Opcje",
@@ -828,16 +828,16 @@
"RSSSync": "Synchronizacja RSS",
"RSSSyncInterval": "Częstotliwość synchronizacji RSS",
"RSSSyncIntervalHelpTextWarning": "Dotyczy to wszystkich indeksujących, prosimy o przestrzeganie zasad przez nich określonych",
"Runtime": "Runtime",
"Runtime": "Długość",
"Save": "Zapisać",
"SaveChanges": "Zapisz zmiany",
"SaveSettings": "Zapisz ustawienia",
"Scheduled": "Planowy",
"Score": "Wynik",
"Script": "Scenariusz",
"ScriptPath": "Script Path",
"ScriptPath": "Ścieżka do Skryptu",
"SearchAll": "Wyszukaj wszystko",
"SearchCutoffUnmet": "Search Cutoff Unmet",
"SearchCutoffUnmet": "Niespełnione Parametry Wyszukiwania",
"SearchFailedPleaseTryAgainLater": "Wyszukiwanie nie powiodło się, spróbuj ponownie później.",
"SearchFiltered": "Szukaj przefiltrowane",
"SearchForMissing": "Wyszukaj brakujące",
@@ -893,7 +893,7 @@
"Shutdown": "Zamknąć",
"SizeOnDisk": "Rozmiar dysku",
"SkipFreeSpaceCheck": "Pomiń sprawdzanie wolnego miejsca",
"SkipFreeSpaceCheckWhenImportingHelpText": "Użyj, gdy Radarr nie może wykryć wolnego miejsca w folderze głównym filmu",
"SkipFreeSpaceCheckWhenImportingHelpText": "Zaznacz, jeśli Radarr nie będzie wstanie wykryć ilości wolnego miejsca w główny folderze filmów",
"Small": "Mały",
"Socks4": "Skarpetki 4",
"Socks5": "Socks5 (Wsparcie TOR)",
@@ -932,10 +932,10 @@
"Time": "Czas",
"Title": "Tytuł",
"Titles": "Tytuły",
"TMDBId": "TMDb Id",
"TMDBId": "Identyfikator TMDb",
"TmdbIdHelpText": "Identyfikator TMDb filmu do wykluczenia",
"Today": "Dzisiaj",
"TorrentDelay": "Torrent Delay",
"TorrentDelay": "Opóźnienie Torrenta",
"TorrentDelayHelpText": "Opóźnienie w ciągu kilku minut, aby poczekać przed złapaniem torrenta",
"Torrents": "Torrenty",
"TorrentsDisabled": "Torrenty wyłączone",
@@ -946,7 +946,7 @@
"Type": "Rodzaj",
"UI": "UI",
"UILanguage": "Język interfejsu użytkownika",
"UILanguageHelpText": "Język, którego Radarr będzie używać w interfejsie użytkownika",
"UILanguageHelpText": "Język, interfejsu użytkownika używanego przez Radarr",
"UILanguageHelpTextWarning": "Wymagane przeładowanie przeglądarki",
"UISettings": "Ustawienia interfejsu użytkownika",
"UISettingsSummary": "Opcje z osłabionym kalendarzem, datą i kolorem",
@@ -989,7 +989,7 @@
"UnsavedChanges": "Niezapisane zmiany",
"UnselectAll": "Odznacz wszystko",
"UpdateAll": "Aktualizuj wszystko",
"UpperCase": "Duże litery",
"UpperCase": "Z dużej litery",
"UpdateCheckUINotWritableMessage": "Nie można zainstalować aktualizacji, ponieważ użytkownik „{1}” nie ma prawa zapisu w folderze interfejsu użytkownika „{0}”.",
"UpdateMechanismHelpText": "Użyj wbudowanego aktualizatora Radarr lub skryptu",
"UpdateScriptPathHelpText": "Ścieżka do niestandardowego skryptu, który pobiera wyodrębniony pakiet aktualizacji i obsługuje pozostałą część procesu aktualizacji",
@@ -1006,7 +1006,7 @@
"VisitGithubCustomFormatsAphrodite": "Odwiedź wiki, aby uzyskać więcej informacji: ",
"WaitingToProcess": "Czekam na przetworzenie",
"Wanted": "Chciał",
"Warn": "Ostrzec",
"Warn": "Ostrzeż",
"Week": "Tydzień",
"WeekColumnHeader": "Nagłówek kolumny tygodnia",
"Weeks": "Tygodni",
@@ -1043,25 +1043,25 @@
"Download": "Ściągnij",
"DownloadClientCheckDownloadingToRoot": "Klient pobierania {0} umieszcza pliki do pobrania w folderze głównym {1}. Nie należy pobierać do folderu głównego.",
"DeleteFileLabel": "Usuń {0} pliki filmowe",
"UnableToAddRootFolder": "Nie można załadować folderów głównych",
"UnableToAddRootFolder": "Nie można dodać folderu głównego",
"AreYouSureYouWantToRemoveTheSelectedItemsFromBlocklist": "Czy na pewno chcesz usunąć wybrane elementy z czarnej listy?",
"Blocklist": "Czarna lista",
"BlocklistRelease": "Wydanie czarnej listy",
"RemoveFromBlocklist": "Usuń z czarnej listy",
"UnableToLoadBlocklist": "Nie można załadować czarnej listy",
"UnableToLoadBlocklist": "Nie można załadować listy blokowania",
"Blocklisted": "Czarna lista",
"AreYouSureYouWantToRemoveSelectedItemFromQueue": "Czy na pewno chcesz usunąć {0} element {1} z kolejki?",
"BlocklistReleases": "Wydanie czarnej listy",
"Filters": "Filtr",
"Filters": "Filtry",
"LocalPath": "Ścieżka lokalna",
"List": "Listy",
"Rating": "Oceny",
"RemotePath": "Zdalna ścieżka",
"List": "Lista",
"Rating": "Ocena",
"RemotePath": "Ścieżka zdalna",
"SelectLanguages": "Wybierz język",
"AllCollectionsHiddenDueToFilter": "Wszystkie kolekcje są ukryte ze względu na zastosowany filtr.",
"Collections": "Kolekcja",
"Collections": "Kolekcje",
"RssSyncHelpText": "Odstęp w minutach. Ustaw na zero, aby wyłączyć (zatrzyma to wszystkie automatyczne przechwytywanie zwolnień)",
"NoCollections": "Nie znaleziono żadnych filmów. Aby rozpocząć, musisz dodać nowy film lub zaimportować istniejące.",
"NoCollections": "Nie znaleziono żadnych filmów. Aby rozpocząć, musisz dodać nowy film lub zaimportować istniejące",
"MonitorMovies": "Monitoruj film",
"ClickToChangeReleaseGroup": "Kliknij, by zmienić grupę wydającą",
"RemotePathMappingCheckDownloadPermissions": "Radarr widzi film {0}, lecz nie ma do niego dostępu. Najprawdopodobniej to wynik błędu w uprawnieniach dostępu.",
@@ -1078,7 +1078,7 @@
"ManualImportSetReleaseGroup": "Import ręczny - podaj nazwę grupy",
"Never": "Nigdy",
"RemotePathMappingCheckFilesWrongOSPath": "Zdalny klient pobierania {0} zgłosił pliki w {1}, lecz nie jest to poprawna ścieżka {2}. Zmień ustawienia zdalnego mapowania ścieżek i klienta pobierania.",
"RemotePathMappingCheckGenericPermissions": "Klient pobierania {0} umieszcza pobrane pliki w {1}, lecz Radarr nie widzi tego folderu. Być może należy zmienić ustawienia uprawnień dostępu.",
"RemotePathMappingCheckGenericPermissions": "Klient pobierania {0} umieszcza pobrane pliki w {1}, lecz Radarr nie widzi tego folderu. Być może należy zmienić uprawnienia dostępu do folderu.",
"RemoveFailed": "Usuń nieudane",
"RemoveDownloadsAlert": "Ustawienia usuwania zostały przeniesione do ustawień poszczególnych klientów pobierania powyżej.",
"ShowCollectionDetails": "Pokaż stan kolekcji",
@@ -1092,7 +1092,7 @@
"EditCollection": "Edytuj kolekcję",
"From": "z",
"IndexerTagHelpText": "Korzystaj z tego indeksera wyłącznie w przypadku filmów z co najmniej jednym pasującym tagiem. Pozostaw pole puste, by używać do wszystkich filmów.",
"Letterboxd": "Letterboxd",
"Letterboxd": "Z Letterboxd",
"MonitorCollection": "Monitoruj kolekcję",
"MovieAndCollection": "Film i kolekcja",
"MovieCollectionMissingRoot": "Brak katalogu głównego dla kolekcji filmów: {0}",
@@ -1134,5 +1134,12 @@
"TaskUserAgentTooltip": "User-Agent podawany przez aplikację wywołującą API",
"SetReleaseGroup": "Ustaw grupę wydającą",
"SearchOnAddCollectionHelpText": "Po dodaniu do biblioteki wyszukaj filmy z tej kolekcji",
"Database": "Baza danych"
"Database": "Baza danych",
"OnMovieAddedHelpText": "Przy dodaniu filmu",
"ShowPosters": "Pokaż plakaty",
"OnMovieAdded": "Przy dodaniu filmu",
"CollectionShowPostersHelpText": "Pokaż plakaty elementów kolekcji",
"CollectionOptions": "Opcje Kolekcji",
"CollectionShowDetailsHelpText": "Pokaż status i właściwości kolekcji",
"CollectionShowOverviewsHelpText": "Pokaż przegląd kolekcji"
}

View File

@@ -1116,5 +1116,12 @@
"Collections": "Coleção",
"RssSyncHelpText": "Intervalo em minutos. Defina como zero para desativar (isso parará toda a captura automática)",
"MonitorMovies": "Monitorar filme",
"NoCollections": "Nenhum filme encontrado. Para começar, adiciona um novo filme ou importa alguns já existentes."
"NoCollections": "Nenhum filme encontrado. Para começar, adiciona um novo filme ou importa alguns já existentes.",
"MovieAndCollection": "Filme e Coleção",
"CollectionsSelectedInterp": "{0} Coleções Selecionadas",
"EditCollection": "Editar Coleção",
"ChooseImportMode": "Selecionar Modo de Importação",
"InstanceName": "Nome da Instancia",
"CollectionOptions": "Opções de Coleção",
"CollectionShowDetailsHelpText": "Mostrar estado da coleção e proprieades"
}

View File

@@ -19,7 +19,7 @@
"IndexerStatusCheckAllClientMessage": "Todos os indexadores estão indisponíveis devido a falhas",
"IndexersSettingsSummary": "Indexadores e restrições de lançamento",
"IndexerSettings": "Configurações do indexador",
"IndexerSearchCheckNoInteractiveMessage": "Sem indexadores disponíveis com a Pesquisa Interativa habilitada, o Radarr não fornecerá resultados interativos de pesquisa",
"IndexerSearchCheckNoInteractiveMessage": "Nenhum indexador disponível com a Pesquisa Interativa ativada, o Radarr não fornecerá nenhum resultado de pesquisa interativa",
"IndexerSearchCheckNoAvailableIndexersMessage": "Todos os indexadores com capacidade de pesquisa estão temporariamente indisponíveis devido a erros recentes do indexador",
"IndexerSearchCheckNoAutomaticMessage": "Nenhum indexador disponível com a Pesquisa automática habilitada, o Radarr não fornecerá nenhum resultado de pesquisa automática",
"Indexers": "Indexadores",
@@ -668,7 +668,7 @@
"SomeResultsHiddenFilter": "Alguns resultados estão ocultos pelo filtro aplicado",
"Socks5": "Socks5 (suporte ao TOR)",
"Small": "Pequeno",
"SkipFreeSpaceCheckWhenImportingHelpText": "Usar quando o Radarr não conseguir detectar espaço livre da pasta raiz do filme",
"SkipFreeSpaceCheckWhenImportingHelpText": "Usar o Radarr quando for impossível detectar o espaço livre da sua pasta raiz do filme",
"SkipFreeSpaceCheck": "Ignorar verificação de espaço livre",
"SizeOnDisk": "Tamanho em disco",
"Size": "Tamanho",
@@ -961,7 +961,7 @@
"UpdateSelected": "Atualizar selecionado(s)",
"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",
"UpdateMechanismHelpText": "Usar o atualizador embutido do Radarr ou um script",
"UpdateMechanismHelpText": "Usar atualizador integrado do Radarr ou um script",
"UpdateCheckUINotWritableMessage": "Não é possível instalar a atualização porque a pasta de interface do usuário '{0}' não é gravável pelo usuário '{1}'.",
"UpdateCheckStartupTranslocationMessage": "Não é possível instalar a atualização porque a pasta de inicialização '{0}' está em uma pasta App Translocation.",
"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}'.",
@@ -1053,7 +1053,7 @@
"RemotePathMappingCheckImportFailed": "O Radarr não conseguiu importar um filme. Verifique os logs para saber mais.",
"RemotePathMappingCheckFileRemoved": "O arquivo {0} foi removido no meio do processamento.",
"RemotePathMappingCheckDownloadPermissions": "O Radarr pode ver, mas não pode acessar o filme baixado {0}. Provável erro de permissões.",
"RemotePathMappingCheckGenericPermissions": "Cliente para download {0} coloca downloads em {1}, mas o Radarr não pode ver este diretório. Você pode precisar ajustar as permissões da pasta.",
"RemotePathMappingCheckGenericPermissions": "O cliente para download {0} põe os downloads em {1}, mas o Radarr não pode ver esse diretório. Você pode precisar ajustar as permissões da pasta.",
"RemotePathMappingCheckWrongOSPath": "O cliente de download remoto {0} coloca downloads em {1}, mas este não é um caminho {2} válido. Revise seus mapeamentos de caminho remoto e baixe as configurações do cliente.",
"RemotePathMappingCheckLocalWrongOSPath": "O cliente de download local {0} coloca downloads em {1}, mas este não é um caminho {2} válido. Revise as configurações do seu cliente de download.",
"RemotePathMappingCheckLocalFolderMissing": "O cliente de download remoto {0} coloca downloads em {1}, mas esse diretório parece não existir. Mapeamento de caminho remoto provavelmente ausente ou incorreto.",
@@ -1119,7 +1119,7 @@
"AllCollectionsHiddenDueToFilter": "Todos os filmes estão ocultos devido ao filtro aplicado.",
"Collections": "Coleção",
"MonitorMovies": "Monitorar filme",
"NoCollections": "Nenhum filme encontrado. Para começar, adicione um novo filme ou importe alguns existentes.",
"NoCollections": "Nenhum filme encontrado. Para começar, adicione um novo filme ou importe alguns existentes",
"MovieOnly": "Somente Filme",
"UnableToLoadCollections": "Não foi possível carregar as coleções",
"ChooseImportMode": "Escolher o Modo de Importação",
@@ -1141,5 +1141,6 @@
"CollectionOptions": "Opções de Coleção",
"CollectionShowDetailsHelpText": "Mostrar estado e propriedades da coleção",
"CollectionShowOverviewsHelpText": "Mostrar visão geral da coleção",
"CollectionShowPostersHelpText": "Mostrar pôsteres de itens da coleção"
"CollectionShowPostersHelpText": "Mostrar pôsteres de itens da coleção",
"RottenTomatoesRating": "Avaliação Tomato"
}

View File

@@ -110,5 +110,6 @@
"DeleteNotificationMessageText": "Naozaj chcete zmazať značku formátu {0} ?",
"AreYouSureYouWantToRemoveSelectedItemFromQueue": "Naozaj chcete odobrať {0} položku {1} z fronty?",
"ImportCustomFormat": "Pridať vlastný formát",
"DeleteRestrictionHelpText": "Naozaj chcete zmazať tento profil oneskorenia?"
"DeleteRestrictionHelpText": "Naozaj chcete zmazať tento profil oneskorenia?",
"AllCollectionsHiddenDueToFilter": "Všetky filmy sú skryté kvôli použitému filtru."
}

View File

@@ -1,4 +1,7 @@
{
"About": "關於",
"Add": "添加"
"Add": "添加",
"AcceptConfirmationModal": "接受確認模式",
"Actions": "‎行動‎",
"Activity": "‎活動‎"
}

View File

@@ -5,7 +5,7 @@ using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.MediaFiles.Events
{
public class MovieImportedEvent : IEvent
public class MovieFileImportedEvent : IEvent
{
public LocalMovie MovieInfo { get; private set; }
public MovieFile ImportedMovie { get; private set; }
@@ -14,7 +14,7 @@ namespace NzbDrone.Core.MediaFiles.Events
public DownloadClientItemClientInfo DownloadClientInfo { get; set; }
public string DownloadId { get; private set; }
public MovieImportedEvent(LocalMovie movieInfo, MovieFile importedMovie, List<MovieFile> oldFiles, bool newDownload, DownloadClientItem downloadClientItem)
public MovieFileImportedEvent(LocalMovie movieInfo, MovieFile importedMovie, List<MovieFile> oldFiles, bool newDownload, DownloadClientItem downloadClientItem)
{
MovieInfo = movieInfo;
ImportedMovie = importedMovie;

View File

@@ -153,10 +153,10 @@ namespace NzbDrone.Core.MediaFiles.MediaInfo
return "WMA";
}
Logger.Debug()
Logger.ForDebugEvent()
.Message("Unknown audio format: '{0}' in '{1}'.", mediaInfo.RawStreamData, sceneName)
.WriteSentryWarn("UnknownAudioFormatFFProbe", mediaInfo.ContainerFormat, mediaInfo.AudioFormat, audioCodecID)
.Write();
.Log();
return mediaInfo.AudioFormat;
}
@@ -262,10 +262,10 @@ namespace NzbDrone.Core.MediaFiles.MediaInfo
return "";
}
Logger.Debug()
Logger.ForDebugEvent()
.Message("Unknown video format: '{0}' in '{1}'.", mediaInfo.RawStreamData, sceneName)
.WriteSentryWarn("UnknownVideoFormatFFProbe", mediaInfo.ContainerFormat, videoFormat, videoCodecID)
.Write();
.Log();
return result;
}

View File

@@ -144,7 +144,7 @@ namespace NzbDrone.Core.MediaFiles.MovieImport
_extraService.ImportMovie(localMovie, movieFile, copyOnly);
}
_eventAggregator.PublishEvent(new MovieImportedEvent(localMovie, movieFile, oldFiles, newDownload, downloadClientItem));
_eventAggregator.PublishEvent(new MovieFileImportedEvent(localMovie, movieFile, oldFiles, newDownload, downloadClientItem));
}
catch (RootFolderNotFoundException e)
{

View File

@@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.Linq;
using NLog;
using NzbDrone.Core.Messaging.Events;
using NzbDrone.Core.Movies.Events;
@@ -13,6 +14,7 @@ namespace NzbDrone.Core.Movies.Collections
IEnumerable<MovieCollection> GetCollections(IEnumerable<int> ids);
List<MovieCollection> GetAllCollections();
MovieCollection UpdateCollection(MovieCollection collection);
List<MovieCollection> UpdateCollections(List<MovieCollection> collections);
void RemoveCollection(MovieCollection collection);
bool Upsert(MovieCollection collection);
bool UpsertMany(List<MovieCollection> collections);
@@ -23,12 +25,14 @@ namespace NzbDrone.Core.Movies.Collections
private readonly IMovieCollectionRepository _repo;
private readonly IMovieService _movieService;
private readonly IEventAggregator _eventAggregator;
private readonly Logger _logger;
public MovieCollectionService(IMovieCollectionRepository repo, IMovieService movieService, IEventAggregator eventAggregator)
public MovieCollectionService(IMovieCollectionRepository repo, IMovieService movieService, IEventAggregator eventAggregator, Logger logger)
{
_repo = repo;
_movieService = movieService;
_eventAggregator = eventAggregator;
_logger = logger;
}
public MovieCollection AddCollection(MovieCollection newCollection)
@@ -73,6 +77,21 @@ namespace NzbDrone.Core.Movies.Collections
return updatedCollection;
}
public List<MovieCollection> UpdateCollections(List<MovieCollection> collections)
{
_logger.Debug("Updating {0} movie collections", collections.Count);
foreach (var c in collections)
{
_logger.Trace("Updating: {0}", c.Title);
}
_repo.UpdateMany(collections);
_logger.Debug("{0} movie collections updated", collections.Count);
return collections;
}
public void RemoveCollection(MovieCollection collection)
{
_repo.Delete(collection);

View File

@@ -5,11 +5,11 @@ namespace NzbDrone.Core.Movies.Events
{
public class MoviesImportedEvent : IEvent
{
public List<int> MovieIds { get; private set; }
public List<Movie> Movies { get; private set; }
public MoviesImportedEvent(List<int> movieIds)
public MoviesImportedEvent(List<Movie> movies)
{
MovieIds = movieIds;
Movies = movies;
}
}
}

View File

@@ -23,7 +23,7 @@ namespace NzbDrone.Core.Movies
public void Handle(MoviesImportedEvent message)
{
_commandQueueManager.PushMany(message.MovieIds.Select(s => new RefreshMovieCommand(new List<int> { s }, true)).ToList());
_commandQueueManager.PushMany(message.Movies.Select(s => new RefreshMovieCommand(new List<int> { s.Id }, true)).ToList());
}
}
}

View File

@@ -100,7 +100,7 @@ namespace NzbDrone.Core.Movies
{
_movieRepository.InsertMany(newMovies);
_eventAggregator.PublishEvent(new MoviesImportedEvent(newMovies.Select(s => s.Id).ToList()));
_eventAggregator.PublishEvent(new MoviesImportedEvent(newMovies));
return newMovies;
}

View File

@@ -12,7 +12,7 @@ using NzbDrone.Core.Movies.Events;
namespace NzbDrone.Core.Movies
{
public class RefreshCollectionService : IExecute<RefreshCollectionsCommand>, IHandle<CollectionEditedEvent>
public class RefreshCollectionService : IExecute<RefreshCollectionsCommand>
{
private readonly IProvideMovieInfo _movieInfo;
private readonly IMovieCollectionService _collectionService;
@@ -99,21 +99,25 @@ namespace NzbDrone.Core.Movies
{
var existingMovies = _movieService.AllMovieTmdbIds();
var collectionMovies = _movieMetadataService.GetMoviesByCollectionTmdbId(collection.TmdbId);
var moviesToAdd = collectionMovies.Where(m => !existingMovies.Contains(m.TmdbId));
_addMovieService.AddMovies(collectionMovies.Where(m => !existingMovies.Contains(m.TmdbId)).Select(m => new Movie
if (moviesToAdd.Any())
{
TmdbId = m.TmdbId,
Title = m.Title,
ProfileId = collection.QualityProfileId,
RootFolderPath = collection.RootFolderPath,
MinimumAvailability = collection.MinimumAvailability,
AddOptions = new AddMovieOptions
_addMovieService.AddMovies(moviesToAdd.Select(m => new Movie
{
SearchForMovie = collection.SearchOnAdd,
AddMethod = AddMovieMethod.Collection
},
Monitored = true
}).ToList());
TmdbId = m.TmdbId,
Title = m.Title,
ProfileId = collection.QualityProfileId,
RootFolderPath = collection.RootFolderPath,
MinimumAvailability = collection.MinimumAvailability,
AddOptions = new AddMovieOptions
{
SearchForMovie = collection.SearchOnAdd,
AddMethod = AddMovieMethod.Collection
},
Monitored = true
}).ToList());
}
}
}
@@ -151,10 +155,5 @@ namespace NzbDrone.Core.Movies
}
}
}
public void Handle(CollectionEditedEvent message)
{
SyncCollectionMovies(message.Collection);
}
}
}

View File

@@ -6,6 +6,7 @@ using System.Linq;
using FluentValidation.Results;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.HealthCheck;
using NzbDrone.Core.MediaFiles.MediaInfo;
using NzbDrone.Core.Movies;
namespace NzbDrone.Core.Notifications.Notifiarr
@@ -77,6 +78,15 @@ namespace NzbDrone.Core.Notifications.Notifiarr
variables.Add("Radarr_MovieFile_SceneName", movieFile.SceneName ?? string.Empty);
variables.Add("Radarr_MovieFile_SourcePath", sourcePath);
variables.Add("Radarr_MovieFile_SourceFolder", Path.GetDirectoryName(sourcePath));
variables.Add("Radarr_MovieFile_MediaInfo_AudioChannels", MediaInfoFormatter.FormatAudioChannels(movieFile.MediaInfo).ToString());
variables.Add("Radarr_MovieFile_MediaInfo_AudioCodec", MediaInfoFormatter.FormatAudioCodec(movieFile.MediaInfo, null));
variables.Add("Radarr_MovieFile_MediaInfo_AudioLanguages", movieFile.MediaInfo.AudioLanguages.Distinct().ConcatToString(" / "));
variables.Add("Radarr_MovieFile_MediaInfo_Languages", movieFile.MediaInfo.AudioLanguages.ConcatToString(" / "));
variables.Add("Radarr_MovieFile_MediaInfo_Height", movieFile.MediaInfo.Height.ToString());
variables.Add("Radarr_MovieFile_MediaInfo_Width", movieFile.MediaInfo.Width.ToString());
variables.Add("Radarr_MovieFile_MediaInfo_Subtitles", movieFile.MediaInfo.Subtitles.ConcatToString(" / "));
variables.Add("Radarr_MovieFile_MediaInfo_VideoCodec", MediaInfoFormatter.FormatVideoCodec(movieFile.MediaInfo, null));
variables.Add("Radarr_MovieFile_MediaInfo_VideoDynamicRangeType", MediaInfoFormatter.FormatVideoDynamicRangeType(movieFile.MediaInfo));
variables.Add("Radarr_Download_Id", message.DownloadId ?? string.Empty);
variables.Add("Radarr_Download_Client", message.DownloadClientInfo?.Name ?? string.Empty);
variables.Add("Radarr_Download_Client_Type", message.DownloadClientInfo?.Type ?? string.Empty);

View File

@@ -78,8 +78,7 @@ namespace NzbDrone.Core.Notifications.Notifiarr
try
{
var url = settings.Environment == (int)NotifiarrEnvironment.Development ? "https://dev.notifiarr.com" : "https://notifiarr.com";
var requestBuilder = new HttpRequestBuilder(url + "/notifier.php").Post();
requestBuilder.AddFormParameter("api", settings.APIKey).Build();
var requestBuilder = new HttpRequestBuilder(url + "/api/v1/notification/radarr/" + settings.APIKey).Post();
requestBuilder.AddFormParameter("instanceName", settings.InstanceName).Build();
foreach (string key in message.Keys)

View File

@@ -17,9 +17,10 @@ namespace NzbDrone.Core.Notifications
public class NotificationService
: IHandle<MovieRenamedEvent>,
IHandle<MovieGrabbedEvent>,
IHandle<MovieImportedEvent>,
IHandle<MovieFileImportedEvent>,
IHandle<MoviesDeletedEvent>,
IHandle<MovieAddedEvent>,
IHandle<MoviesImportedEvent>,
IHandle<MovieFileDeletedEvent>,
IHandle<HealthCheckFailedEvent>,
IHandle<UpdateInstalledEvent>,
@@ -119,7 +120,7 @@ namespace NzbDrone.Core.Notifications
}
}
public void Handle(MovieImportedEvent message)
public void Handle(MovieFileImportedEvent message)
{
if (!message.NewDownload)
{
@@ -174,6 +175,27 @@ namespace NzbDrone.Core.Notifications
}
}
public void Handle(MoviesImportedEvent message)
{
foreach (var notification in _notificationFactory.OnMovieAddedEnabled())
{
try
{
foreach (var movie in message.Movies)
{
if (ShouldHandleMovie(notification.Definition, movie))
{
notification.OnMovieAdded(movie);
}
}
}
catch (Exception ex)
{
_logger.Warn(ex, "Unable to send OnMovieAdded notification to: " + notification.Definition.Name);
}
}
}
public void Handle(MovieRenamedEvent message)
{
foreach (var notification in _notificationFactory.OnRenameEnabled())

View File

@@ -20,6 +20,18 @@ namespace NzbDrone.Core.Parser
private static readonly Regex[] ReportMovieTitleRegex = new[]
{
//Anime [Subgroup] and Year
new Regex(@"^(?:\[(?<subgroup>.+?)\][-_. ]?)(?<title>(?![(\[]).+?)?(?:(?:[-_\W](?<![)\[!]))*(?<year>(1(8|9)|20)\d{2}(?!p|i|x|\d+|\]|\W\d+)))+.*?(?<hash>\[\w{8}\])?(?:$|\.)", RegexOptions.IgnoreCase | RegexOptions.Compiled),
//Anime [Subgroup] no year, versioned title, hash
new Regex(@"^(?:\[(?<subgroup>.+?)\][-_. ]?)(?<title>(?![(\[]).+?)((v)(?:\d{1,2})(?:([-_. ])))(\[.*)?(?:[\[(][^])])?.*?(?<hash>\[\w{8}\])(?:$|\.)", RegexOptions.IgnoreCase | RegexOptions.Compiled),
//Anime [Subgroup] no year, info in double sets of brackets, hash
new Regex(@"^(?:\[(?<subgroup>.+?)\][-_. ]?)(?<title>(?![(\[]).+?)(\[.*).*?(?<hash>\[\w{8}\])(?:$|\.)", RegexOptions.IgnoreCase | RegexOptions.Compiled),
//Anime [Subgroup] no year, info in parentheses or brackets, hash
new Regex(@"^(?:\[(?<subgroup>.+?)\][-_. ]?)(?<title>(?![(\[]).+)(?:[\[(][^])]).*?(?<hash>\[\w{8}\])(?:$|\.)", RegexOptions.IgnoreCase | RegexOptions.Compiled),
//Some german or french tracker formats (missing year, ...) (Only applies to german and TrueFrench releases) - see ParserFixture for examples and tests - french removed as it broke all movies w/ french titles
new Regex(@"^(?<title>(?![(\[]).+?)((\W|_))(" + EditionRegex + @".{1,3})?(?:(?<!(19|20)\d{2}.*?)(German|TrueFrench))(.+?)(?=((19|20)\d{2}|$))(?<year>(19|20)\d{2}(?!p|i|\d+|\]|\W\d+))?(\W+|_|$)(?!\\)", RegexOptions.IgnoreCase | RegexOptions.Compiled),
@@ -41,7 +53,7 @@ namespace NzbDrone.Core.Parser
new Regex(@"^(?<title>(?![(\[]).+?)?(?:(?:[-_\W](?<![)!]))*(?<year>(1(8|9)|20)\d{2}(?!p|i|\d+|\W\d+)))+(\W+|_|$)(?!\\)", RegexOptions.IgnoreCase | RegexOptions.Compiled),
//As a last resort for movies that have ( or [ in their title.
new Regex(@"^(?<title>.+?)?(?:(?:[-_\W](?<![)\[!]))*(?<year>(1(8|9)|20)\d{2}(?!p|i|\d+|\]|\W\d+)))+(\W+|_|$)(?!\\)", RegexOptions.IgnoreCase | RegexOptions.Compiled),
new Regex(@"^(?<title>.+?)?(?:(?:[-_\W](?<![)\[!]))*(?<year>(1(8|9)|20)\d{2}(?!p|i|\d+|\]|\W\d+)))+(\W+|_|$)(?!\\)", RegexOptions.IgnoreCase | RegexOptions.Compiled)
};
private static readonly Regex[] ReportMovieTitleFolderRegex = new[]
@@ -97,7 +109,7 @@ namespace NzbDrone.Core.Parser
private static readonly Regex ReportImdbId = new Regex(@"(?<imdbid>tt\d{7,8})", RegexOptions.IgnoreCase | RegexOptions.Compiled);
private static readonly Regex ReportTmdbId = new Regex(@"tmdb(id)?-(?<tmdbid>\d+)", RegexOptions.IgnoreCase | RegexOptions.Compiled);
private static readonly RegexReplace SimpleTitleRegex = new RegexReplace(@"(?:(480|540|576|720|1080|2160)[ip]|[xh][\W_]?26[45]|DD\W?5\W1|[<>?*]|848x480|1280x720|1920x1080|3840x2160|4096x2160|(8|10)b(it)?|10-bit)\s*?",
private static readonly RegexReplace SimpleTitleRegex = new RegexReplace(@"(?:(480|540|576|720|1080|2160)[ip]|[xh][\W_]?26[45]|DD\W?5\W1|[<>?*]|848x480|1280x720|1920x1080|3840x2160|4096x2160|(8|10)b(it)?|10-bit)\s*?(?![a-b0-9])",
string.Empty,
RegexOptions.IgnoreCase | RegexOptions.Compiled);

View File

@@ -16,7 +16,7 @@ namespace NzbDrone.Core.Parser
private static readonly Regex SourceRegex = new Regex(@"\b(?:
(?<bluray>M?BluRay|Blu-Ray|HD.?DVD|BD(?!$)|UHDBD|UHD2BD|BDISO|BDMux|BD25|BD50|BR.?DISK)|
(?<webdl>WEB[-_. ]DL(?:mux)?|WEBDL|AmazonHD|iTunesHD|MaxdomeHD|NetflixU?HD|WebHD|[. ]WEB[. ](?:[xh]26[45]|DDP?5[. ]1)|[. ](?-i:WEB)$|(?:\d{3,4}0p)[-. ]WEB[-. ]|[-. ]WEB[-. ]\d{3,4}0p|\b\s\/\sWEB\s\/\s\b|(?:AMZN|NF|DP)[. -]WEB[. -])|
(?<webdl>WEB[-_. ]DL(?:mux)?|WEBDL|AmazonHD|iTunesHD|MaxdomeHD|NetflixU?HD|WebHD|[. ]WEB[. ](?:[xh][ .]?26[45]|DDP?5[. ]1)|[. ](?-i:WEB)$|(?:\d{3,4}0p)[-. ]WEB[-. ]|[-. ]WEB[-. ]\d{3,4}0p|\b\s\/\sWEB\s\/\s\b|(?:AMZN|NF|DP)[. -]WEB[. -])|
(?<webrip>WebRip|Web-Rip|WEBMux)|
(?<hdtv>HDTV)|
(?<bdrip>BDRip|BDLight)|

View File

@@ -19,7 +19,7 @@
<PackageReference Include="FluentValidation" Version="8.6.2" />
<PackageReference Include="SixLabors.ImageSharp" Version="1.0.4" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="NLog" Version="4.7.14" />
<PackageReference Include="NLog" Version="5.0.1" />
<PackageReference Include="System.Data.SQLite.Core.Servarr" Version="1.0.115.5-18" />
<PackageReference Include="MonoTorrent" Version="2.0.5" />
<PackageReference Include="System.Text.Json" Version="6.0.4" />

View File

@@ -9,7 +9,7 @@ namespace NzbDrone.Core.Validation.Paths
private readonly IAppFolderInfo _appFolderInfo;
public StartupFolderValidator(IAppFolderInfo appFolderInfo)
: base("Path cannot be an ancestor of the start up folder")
: base("Path cannot be {relationship} the start up folder")
{
_appFolderInfo = appFolderInfo;
}
@@ -21,7 +21,24 @@ namespace NzbDrone.Core.Validation.Paths
return true;
}
return !_appFolderInfo.StartUpFolder.IsParentPath(context.PropertyValue.ToString());
var startupFolder = _appFolderInfo.StartUpFolder;
var folder = context.PropertyValue.ToString();
if (startupFolder.PathEquals(folder))
{
context.MessageFormatter.AppendArgument("relationship", "set to");
return false;
}
if (startupFolder.IsParentPath(folder))
{
context.MessageFormatter.AppendArgument("relationship", "child of");
return false;
}
return true;
}
}
}

View File

@@ -6,7 +6,7 @@
<PackageReference Include="FluentAssertions" Version="5.10.3" />
<PackageReference Include="FluentValidation" Version="8.6.2" />
<PackageReference Include="Moq" Version="4.16.1" />
<PackageReference Include="NLog" Version="4.7.14" />
<PackageReference Include="NLog" Version="5.0.1" />
<PackageReference Include="NUnit" Version="3.13.2" />
<PackageReference Include="RestSharp" Version="106.15.0" />
</ItemGroup>

View File

@@ -6,7 +6,7 @@
<ItemGroup>
<PackageReference Include="DryIoc.dll" Version="4.8.8" />
<PackageReference Include="DryIoc.Microsoft.DependencyInjection" Version="5.1.0" />
<PackageReference Include="NLog" Version="4.7.14" />
<PackageReference Include="NLog" Version="5.0.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\NzbDrone.Common\Radarr.Common.csproj" />

View File

@@ -4,7 +4,7 @@
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="NLog" Version="4.7.14" />
<PackageReference Include="NLog" Version="5.0.1" />
<PackageReference Include="System.IO.FileSystem.AccessControl" Version="5.0.0" />
</ItemGroup>
<ItemGroup>

View File

@@ -1,10 +1,13 @@
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Mvc;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.Datastore.Events;
using NzbDrone.Core.Messaging.Commands;
using NzbDrone.Core.Messaging.Events;
using NzbDrone.Core.Movies;
using NzbDrone.Core.Movies.Collections;
using NzbDrone.Core.Movies.Commands;
using NzbDrone.Core.Movies.Events;
using NzbDrone.Core.Organizer;
using NzbDrone.SignalR;
@@ -25,13 +28,15 @@ namespace Radarr.Api.V3.Collections
private readonly IMovieMetadataService _movieMetadataService;
private readonly IBuildFileNames _fileNameBuilder;
private readonly INamingConfigService _namingService;
private readonly IManageCommandQueue _commandQueueManager;
public CollectionController(IBroadcastSignalRMessage signalRBroadcaster,
IMovieCollectionService collectionService,
IMovieService movieService,
IMovieMetadataService movieMetadataService,
IBuildFileNames fileNameBuilder,
INamingConfigService namingService)
INamingConfigService namingService,
IManageCommandQueue commandQueueManager)
: base(signalRBroadcaster)
{
_collectionService = collectionService;
@@ -39,6 +44,7 @@ namespace Radarr.Api.V3.Collections
_movieMetadataService = movieMetadataService;
_fileNameBuilder = fileNameBuilder;
_namingService = namingService;
_commandQueueManager = commandQueueManager;
}
protected override CollectionResource GetResourceById(int id)
@@ -67,34 +73,47 @@ namespace Radarr.Api.V3.Collections
}
[HttpPut]
public ActionResult UpdateCollections(CollectionUpdateResource collectionResources)
public ActionResult UpdateCollections(CollectionUpdateResource resource)
{
var collectionsToUpdate = _collectionService.GetCollections(collectionResources.Collections.Select(c => c.Id));
var update = new List<CollectionResource>();
var collectionsToUpdate = _collectionService.GetCollections(resource.CollectionIds);
foreach (var c in collectionResources.Collections)
foreach (var collection in collectionsToUpdate)
{
var collection = collectionsToUpdate.Single(n => n.Id == c.Id);
if (c.Monitored.HasValue)
if (resource.Monitored.HasValue)
{
collection.Monitored = c.Monitored.Value;
collection.Monitored = resource.Monitored.Value;
}
if (collectionResources.MonitorMovies.HasValue)
if (resource.QualityProfileId.HasValue)
{
collection.QualityProfileId = resource.QualityProfileId.Value;
}
if (resource.MinimumAvailability.HasValue)
{
collection.MinimumAvailability = resource.MinimumAvailability.Value;
}
if (resource.RootFolderPath.IsNotNullOrWhiteSpace())
{
collection.RootFolderPath = resource.RootFolderPath;
}
if (resource.MonitorMovies.HasValue)
{
var movies = _movieService.GetMoviesByCollectionTmdbId(collection.TmdbId);
movies.ForEach(c => c.Monitored = collectionResources.MonitorMovies.Value);
movies.ForEach(c => c.Monitored = resource.MonitorMovies.Value);
_movieService.UpdateMovie(movies, true);
}
var updatedCollection = _collectionService.UpdateCollection(collection);
update.Add(updatedCollection.ToResource());
}
return Accepted(update);
var updated = _collectionService.UpdateCollections(collectionsToUpdate.ToList()).ToResource();
_commandQueueManager.Push(new RefreshCollectionsCommand());
return Accepted(updated);
}
private IEnumerable<CollectionResource> MapToResource(List<MovieCollection> collections, List<MovieMetadata> collectionMovies)
@@ -125,7 +144,7 @@ namespace Radarr.Api.V3.Collections
foreach (var movie in _movieMetadataService.GetMoviesByCollectionTmdbId(collection.TmdbId))
{
var movieResource = movie.ToResource();
movieResource.Folder = _fileNameBuilder.GetMovieFolder(new Movie { Title = movie.Title, Year = movie.Year, ImdbId = movie.ImdbId, TmdbId = movie.TmdbId });
movieResource.Folder = _fileNameBuilder.GetMovieFolder(new Movie { MovieMetadata = movie });
resource.Movies.Add(movieResource);
}

View File

@@ -1,11 +1,16 @@
using System;
using System.Collections.Generic;
using NzbDrone.Core.Movies;
namespace Radarr.Api.V3.Collections
{
public class CollectionUpdateResource
{
public List<CollectionUpdateCollectionResource> Collections { get; set; }
public List<int> CollectionIds { get; set; }
public bool? Monitored { get; set; }
public bool? MonitorMovies { get; set; }
public int? QualityProfileId { get; set; }
public string RootFolderPath { get; set; }
public MovieStatusType? MinimumAvailability { get; set; }
}
}

View File

@@ -1,10 +1,8 @@
using System;
using System.Collections.Generic;
using System.Linq;
using FluentValidation;
using Microsoft.AspNetCore.Mvc;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.CustomFormats;
using Radarr.Http;
using Radarr.Http.REST;

View File

@@ -32,7 +32,7 @@ namespace Radarr.Api.V3.Movies
{
[V3ApiController]
public class MovieController : RestControllerWithSignalR<MovieResource, Movie>,
IHandle<MovieImportedEvent>,
IHandle<MovieFileImportedEvent>,
IHandle<MovieFileDeletedEvent>,
IHandle<MovieUpdatedEvent>,
IHandle<MovieEditedEvent>,
@@ -264,7 +264,7 @@ namespace Radarr.Api.V3.Movies
}
[NonAction]
public void Handle(MovieImportedEvent message)
public void Handle(MovieFileImportedEvent message)
{
var availDelay = _configService.AvailabilityDelay;
var translations = _movieTranslationService.GetAllTranslationsForMovieMetadata(message.ImportedMovie.Movie.MovieMetadataId);

View File

@@ -5,7 +5,7 @@
<ItemGroup>
<PackageReference Include="FluentValidation" Version="8.6.2" />
<PackageReference Include="Ical.Net" Version="4.2.0" />
<PackageReference Include="NLog" Version="4.7.14" />
<PackageReference Include="NLog" Version="5.0.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\NzbDrone.Core\Radarr.Core.csproj" />

View File

@@ -8705,33 +8705,36 @@
},
"additionalProperties": false
},
"CollectionUpdateCollectionResource": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"format": "int32"
},
"monitored": {
"type": "boolean",
"nullable": true
}
},
"additionalProperties": false
},
"CollectionUpdateResource": {
"type": "object",
"properties": {
"collections": {
"collectionIds": {
"type": "array",
"items": {
"$ref": "#/components/schemas/CollectionUpdateCollectionResource"
"type": "integer",
"format": "int32"
},
"nullable": true
},
"monitored": {
"type": "boolean",
"nullable": true
},
"monitorMovies": {
"type": "boolean",
"nullable": true
},
"qualityProfileId": {
"type": "integer",
"format": "int32",
"nullable": true
},
"rootFolderPath": {
"type": "string",
"nullable": true
},
"minimumAvailability": {
"$ref": "#/components/schemas/MovieStatusType"
}
},
"additionalProperties": false

View File

@@ -5,7 +5,7 @@
<ItemGroup>
<PackageReference Include="FluentValidation" Version="8.6.2" />
<PackageReference Include="ImpromptuInterface" Version="7.0.1" />
<PackageReference Include="NLog" Version="4.7.14" />
<PackageReference Include="NLog" Version="5.0.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\NzbDrone.Core\Radarr.Core.csproj" />