diff --git a/frontend/src/Components/Form/FormInputGroup.js b/frontend/src/Components/Form/FormInputGroup.js
index 6d52ef135..874e42356 100644
--- a/frontend/src/Components/Form/FormInputGroup.js
+++ b/frontend/src/Components/Form/FormInputGroup.js
@@ -282,6 +282,7 @@ FormInputGroup.propTypes = {
includeNoChange: PropTypes.bool,
includeNoChangeDisabled: PropTypes.bool,
selectedValueOptions: PropTypes.object,
+ indexerFlags: PropTypes.number,
pending: PropTypes.bool,
errors: PropTypes.arrayOf(PropTypes.object),
warnings: PropTypes.arrayOf(PropTypes.object),
diff --git a/frontend/src/Components/Form/IndexerFlagsSelectInput.tsx b/frontend/src/Components/Form/IndexerFlagsSelectInput.tsx
index fd3520ceb..8dbd27a70 100644
--- a/frontend/src/Components/Form/IndexerFlagsSelectInput.tsx
+++ b/frontend/src/Components/Form/IndexerFlagsSelectInput.tsx
@@ -4,22 +4,18 @@ import { createSelector } from 'reselect';
import AppState from 'App/State/AppState';
import EnhancedSelectInput from './EnhancedSelectInput';
-interface IndexerFlagsSelectInputProps {
- name: string;
- indexerFlags: number;
- onChange(payload: object): void;
-}
-
const selectIndexerFlagsValues = (selectedFlags: number) =>
createSelector(
(state: AppState) => state.settings.indexerFlags,
(indexerFlags) => {
- const value = indexerFlags.items
- .filter(
- // eslint-disable-next-line no-bitwise
- (item) => (selectedFlags & item.id) === item.id
- )
- .map(({ id }) => id);
+ const value = indexerFlags.items.reduce((acc: number[], { id }) => {
+ // eslint-disable-next-line no-bitwise
+ if ((selectedFlags & id) === id) {
+ acc.push(id);
+ }
+
+ return acc;
+ }, []);
const values = indexerFlags.items.map(({ id, name }) => ({
key: id,
@@ -33,6 +29,12 @@ const selectIndexerFlagsValues = (selectedFlags: number) =>
}
);
+interface IndexerFlagsSelectInputProps {
+ name: string;
+ indexerFlags: number;
+ onChange(payload: object): void;
+}
+
function IndexerFlagsSelectInput(props: IndexerFlagsSelectInputProps) {
const { indexerFlags, onChange } = props;
diff --git a/frontend/src/InteractiveImport/IndexerFlags/SelectIndexerFlagsModal.tsx b/frontend/src/InteractiveImport/IndexerFlags/SelectIndexerFlagsModal.tsx
new file mode 100644
index 000000000..9136554cc
--- /dev/null
+++ b/frontend/src/InteractiveImport/IndexerFlags/SelectIndexerFlagsModal.tsx
@@ -0,0 +1,34 @@
+import React from 'react';
+import Modal from 'Components/Modal/Modal';
+import SelectIndexerFlagsModalContent from './SelectIndexerFlagsModalContent';
+
+interface SelectIndexerFlagsModalProps {
+ isOpen: boolean;
+ indexerFlags: number;
+ modalTitle: string;
+ onIndexerFlagsSelect(indexerFlags: number): void;
+ onModalClose(): void;
+}
+
+function SelectIndexerFlagsModal(props: SelectIndexerFlagsModalProps) {
+ const {
+ isOpen,
+ indexerFlags,
+ modalTitle,
+ onIndexerFlagsSelect,
+ onModalClose,
+ } = props;
+
+ return (
+
+
+
+ );
+}
+
+export default SelectIndexerFlagsModal;
diff --git a/frontend/src/InteractiveImport/IndexerFlags/SelectIndexerFlagsModalContent.css b/frontend/src/InteractiveImport/IndexerFlags/SelectIndexerFlagsModalContent.css
new file mode 100644
index 000000000..72dfb1cb6
--- /dev/null
+++ b/frontend/src/InteractiveImport/IndexerFlags/SelectIndexerFlagsModalContent.css
@@ -0,0 +1,7 @@
+.modalBody {
+ composes: modalBody from '~Components/Modal/ModalBody.css';
+
+ display: flex;
+ flex: 1 1 auto;
+ flex-direction: column;
+}
diff --git a/frontend/src/InteractiveImport/IndexerFlags/SelectIndexerFlagsModalContent.css.d.ts b/frontend/src/InteractiveImport/IndexerFlags/SelectIndexerFlagsModalContent.css.d.ts
new file mode 100644
index 000000000..3fc49a060
--- /dev/null
+++ b/frontend/src/InteractiveImport/IndexerFlags/SelectIndexerFlagsModalContent.css.d.ts
@@ -0,0 +1,7 @@
+// This file is automatically generated.
+// Please do not change this file!
+interface CssExports {
+ 'modalBody': string;
+}
+export const cssExports: CssExports;
+export default cssExports;
diff --git a/frontend/src/InteractiveImport/IndexerFlags/SelectIndexerFlagsModalContent.tsx b/frontend/src/InteractiveImport/IndexerFlags/SelectIndexerFlagsModalContent.tsx
new file mode 100644
index 000000000..f36f46602
--- /dev/null
+++ b/frontend/src/InteractiveImport/IndexerFlags/SelectIndexerFlagsModalContent.tsx
@@ -0,0 +1,75 @@
+import React, { useCallback, useState } from 'react';
+import Form from 'Components/Form/Form';
+import FormGroup from 'Components/Form/FormGroup';
+import FormInputGroup from 'Components/Form/FormInputGroup';
+import FormLabel from 'Components/Form/FormLabel';
+import Button from 'Components/Link/Button';
+import ModalBody from 'Components/Modal/ModalBody';
+import ModalContent from 'Components/Modal/ModalContent';
+import ModalFooter from 'Components/Modal/ModalFooter';
+import ModalHeader from 'Components/Modal/ModalHeader';
+import { inputTypes, kinds, scrollDirections } from 'Helpers/Props';
+import translate from 'Utilities/String/translate';
+import styles from './SelectIndexerFlagsModalContent.css';
+
+interface SelectIndexerFlagsModalContentProps {
+ indexerFlags: number;
+ modalTitle: string;
+ onIndexerFlagsSelect(indexerFlags: number): void;
+ onModalClose(): void;
+}
+
+function SelectIndexerFlagsModalContent(
+ props: SelectIndexerFlagsModalContentProps
+) {
+ const { modalTitle, onIndexerFlagsSelect, onModalClose } = props;
+ const [indexerFlags, setIndexerFlags] = useState(props.indexerFlags);
+
+ const onIndexerFlagsChange = useCallback(
+ ({ value }: { value: number }) => {
+ setIndexerFlags(value);
+ },
+ [setIndexerFlags]
+ );
+
+ const onIndexerFlagsSelectWrapper = useCallback(() => {
+ onIndexerFlagsSelect(indexerFlags);
+ }, [indexerFlags, onIndexerFlagsSelect]);
+
+ return (
+
+
+ {translate('SetIndexerFlagsModalTitle', { modalTitle })}
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default SelectIndexerFlagsModalContent;
diff --git a/frontend/src/InteractiveImport/Interactive/InteractiveImportModalContent.tsx b/frontend/src/InteractiveImport/Interactive/InteractiveImportModalContent.tsx
index 0732171c3..0eea66249 100644
--- a/frontend/src/InteractiveImport/Interactive/InteractiveImportModalContent.tsx
+++ b/frontend/src/InteractiveImport/Interactive/InteractiveImportModalContent.tsx
@@ -26,6 +26,7 @@ import usePrevious from 'Helpers/Hooks/usePrevious';
import useSelectState from 'Helpers/Hooks/useSelectState';
import { align, icons, kinds, scrollDirections } from 'Helpers/Props';
import ImportMode from 'InteractiveImport/ImportMode';
+import SelectIndexerFlagsModal from 'InteractiveImport/IndexerFlags/SelectIndexerFlagsModal';
import InteractiveImport, {
InteractiveImportCommandOptions,
} from 'InteractiveImport/InteractiveImport';
@@ -59,7 +60,13 @@ import getSelectedIds from 'Utilities/Table/getSelectedIds';
import InteractiveImportRow from './InteractiveImportRow';
import styles from './InteractiveImportModalContent.css';
-type SelectType = 'select' | 'movie' | 'releaseGroup' | 'quality' | 'language';
+type SelectType =
+ | 'select'
+ | 'movie'
+ | 'releaseGroup'
+ | 'quality'
+ | 'language'
+ | 'indexerFlags';
type FilterExistingFiles = 'all' | 'new';
@@ -113,6 +120,15 @@ const COLUMNS = [
isSortable: true,
isVisible: true,
},
+ {
+ name: 'indexerFlags',
+ label: React.createElement(Icon, {
+ name: icons.FLAG,
+ title: () => translate('IndexerFlags'),
+ }),
+ isSortable: true,
+ isVisible: true,
+ },
{
name: 'rejections',
label: React.createElement(Icon, {
@@ -257,8 +273,18 @@ function InteractiveImportModalContent(
}
}
+ const showIndexerFlags = items.some((item) => item.indexerFlags);
+
+ if (!showIndexerFlags) {
+ const indexerFlagsColumn = result.find((c) => c.name === 'indexerFlags');
+
+ if (indexerFlagsColumn) {
+ indexerFlagsColumn.isVisible = false;
+ }
+ }
+
return result;
- }, [showMovie]);
+ }, [showMovie, items]);
const selectedIds: number[] = useMemo(() => {
return getSelectedIds(selectedState);
@@ -283,6 +309,10 @@ function InteractiveImportModalContent(
key: 'language',
value: translate('SelectLanguage'),
},
+ {
+ key: 'indexerFlags',
+ value: translate('SelectIndexerFlags'),
+ },
];
if (allowMovieChange) {
@@ -416,7 +446,14 @@ function InteractiveImportModalContent(
const isSelected = selectedIds.indexOf(item.id) > -1;
if (isSelected) {
- const { movie, releaseGroup, quality, languages, movieFileId } = item;
+ const {
+ movie,
+ releaseGroup,
+ quality,
+ languages,
+ indexerFlags,
+ movieFileId,
+ } = item;
if (!movie) {
setInteractiveImportErrorMessage(
@@ -450,6 +487,7 @@ function InteractiveImportModalContent(
releaseGroup,
quality,
languages,
+ indexerFlags,
});
return;
@@ -463,6 +501,7 @@ function InteractiveImportModalContent(
releaseGroup,
quality,
languages,
+ indexerFlags,
downloadId,
movieFileId,
});
@@ -620,6 +659,22 @@ function InteractiveImportModalContent(
[selectedIds, dispatch]
);
+ const onIndexerFlagsSelect = useCallback(
+ (indexerFlags: number) => {
+ dispatch(
+ updateInteractiveImportItems({
+ ids: selectedIds,
+ indexerFlags,
+ })
+ );
+
+ dispatch(reprocessInteractiveImportItems({ ids: selectedIds }));
+
+ setSelectModalOpen(null);
+ },
+ [selectedIds, dispatch]
+ );
+
const errorMessage = getErrorMessage(
error,
translate('InteractiveImportLoadError')
@@ -794,6 +849,14 @@ function InteractiveImportModalContent(
onModalClose={onSelectModalClose}
/>
+
+
columns.find((c) => c.name === 'movie')?.isVisible ?? false,
[columns]
);
+ const isIndexerFlagsColumnVisible = useMemo(
+ () => columns.find((c) => c.name === 'indexerFlags')?.isVisible ?? false,
+ [columns]
+ );
const [selectModalOpen, setSelectModalOpen] = useState(
null
@@ -223,12 +236,34 @@ function InteractiveImportRow(props: InteractiveImportRowProps) {
[id, dispatch, setSelectModalOpen, selectRowAfterChange]
);
+ const onSelectIndexerFlagsPress = useCallback(() => {
+ setSelectModalOpen('indexerFlags');
+ }, [setSelectModalOpen]);
+
+ const onIndexerFlagsSelect = useCallback(
+ (indexerFlags: number) => {
+ dispatch(
+ updateInteractiveImportItem({
+ id,
+ indexerFlags,
+ })
+ );
+
+ dispatch(reprocessInteractiveImportItems({ ids: [id] }));
+
+ setSelectModalOpen(null);
+ selectRowAfterChange();
+ },
+ [id, dispatch, setSelectModalOpen, selectRowAfterChange]
+ );
+
const movieTitle = movie ? movie.title : '';
const showMoviePlaceholder = isSelected && !movie;
const showReleaseGroupPlaceholder = isSelected && !releaseGroup;
const showQualityPlaceholder = isSelected && !quality;
const showLanguagePlaceholder = isSelected && !languages;
+ const showIndexerFlagsPlaceholder = isSelected && !indexerFlags;
return (
@@ -311,6 +346,28 @@ function InteractiveImportRow(props: InteractiveImportRowProps) {
) : null}
+ {isIndexerFlagsColumnVisible ? (
+
+ {showIndexerFlagsPlaceholder ? (
+
+ ) : (
+ <>
+ {indexerFlags ? (
+ }
+ title={translate('IndexerFlags')}
+ body={}
+ position={tooltipPositions.LEFT}
+ />
+ ) : null}
+ >
+ )}
+
+ ) : null}
+
{rejections.length ? (
+
+
);
}
diff --git a/frontend/src/InteractiveImport/InteractiveImport.ts b/frontend/src/InteractiveImport/InteractiveImport.ts
index 000ca1a2d..4e876f852 100644
--- a/frontend/src/InteractiveImport/InteractiveImport.ts
+++ b/frontend/src/InteractiveImport/InteractiveImport.ts
@@ -11,6 +11,7 @@ export interface InteractiveImportCommandOptions {
releaseGroup?: string;
quality: QualityModel;
languages: Language[];
+ indexerFlags: number;
downloadId?: string;
movieFileId?: number;
}
@@ -27,6 +28,7 @@ interface InteractiveImport extends ModelBase {
movie?: Movie;
qualityWeight: number;
customFormats: object[];
+ indexerFlags: number;
rejections: Rejection[];
movieFileId?: number;
}
diff --git a/frontend/src/InteractiveSearch/InteractiveSearchRow.css b/frontend/src/InteractiveSearch/InteractiveSearchRow.css
index 97ac6807a..2268139a7 100644
--- a/frontend/src/InteractiveSearch/InteractiveSearchRow.css
+++ b/frontend/src/InteractiveSearch/InteractiveSearchRow.css
@@ -39,8 +39,7 @@
}
.rejected,
-.indexerFlags,
-.download {
+.indexerFlags {
composes: cell from '~Components/Table/Cells/TableRowCell.css';
width: 50px;
diff --git a/frontend/src/InteractiveSearch/InteractiveSearchRow.tsx b/frontend/src/InteractiveSearch/InteractiveSearchRow.tsx
index 8489ac63d..41b009de3 100644
--- a/frontend/src/InteractiveSearch/InteractiveSearchRow.tsx
+++ b/frontend/src/InteractiveSearch/InteractiveSearchRow.tsx
@@ -11,6 +11,7 @@ import Tooltip from 'Components/Tooltip/Tooltip';
import type DownloadProtocol from 'DownloadClient/DownloadProtocol';
import { icons, kinds, tooltipPositions } from 'Helpers/Props';
import Language from 'Language/Language';
+import IndexerFlags from 'Movie/IndexerFlags';
import MovieFormats from 'Movie/MovieFormats';
import MovieLanguage from 'Movie/MovieLanguage';
import MovieQuality from 'Movie/MovieQuality';
@@ -90,8 +91,8 @@ interface InteractiveSearchRowProps {
customFormats: CustomFormat[];
customFormatScore: number;
mappedMovieId?: number;
+ indexerFlags: number;
rejections: string[];
- indexerFlags: string[];
downloadAllowed: boolean;
isGrabbing: boolean;
isGrabbed: boolean;
@@ -125,8 +126,8 @@ function InteractiveSearchRow(props: InteractiveSearchRowProps) {
customFormatScore,
customFormats,
mappedMovieId,
+ indexerFlags = 0,
rejections = [],
- indexerFlags = [],
downloadAllowed,
isGrabbing = false,
isGrabbed = false,
@@ -276,22 +277,16 @@ function InteractiveSearchRow(props: InteractiveSearchRowProps) {
customFormats.length
)}
tooltip={}
- position={tooltipPositions.TOP}
+ position={tooltipPositions.LEFT}
/>
- {indexerFlags.length ? (
+ {indexerFlags ? (
}
title={translate('IndexerFlags')}
- body={
-
- {indexerFlags.map((flag, index) => {
- return - {flag}
;
- })}
-
- }
+ body={}
position={tooltipPositions.LEFT}
/>
) : null}
diff --git a/frontend/src/Movie/IndexerFlags.tsx b/frontend/src/Movie/IndexerFlags.tsx
new file mode 100644
index 000000000..74e2e033c
--- /dev/null
+++ b/frontend/src/Movie/IndexerFlags.tsx
@@ -0,0 +1,26 @@
+import React from 'react';
+import { useSelector } from 'react-redux';
+import createIndexerFlagsSelector from 'Store/Selectors/createIndexerFlagsSelector';
+
+interface IndexerFlagsProps {
+ indexerFlags: number;
+}
+
+function IndexerFlags({ indexerFlags = 0 }: IndexerFlagsProps) {
+ const allIndexerFlags = useSelector(createIndexerFlagsSelector);
+
+ const flags = allIndexerFlags.items.filter(
+ // eslint-disable-next-line no-bitwise
+ (item) => (indexerFlags & item.id) === item.id
+ );
+
+ return flags.length ? (
+
+ {flags.map((flag, index) => {
+ return - {flag.name}
;
+ })}
+
+ ) : null;
+}
+
+export default IndexerFlags;
diff --git a/frontend/src/MovieFile/Editor/MovieFileEditorRow.css b/frontend/src/MovieFile/Editor/MovieFileEditorRow.css
index a68d41a6f..ae729b9f2 100644
--- a/frontend/src/MovieFile/Editor/MovieFileEditorRow.css
+++ b/frontend/src/MovieFile/Editor/MovieFileEditorRow.css
@@ -57,3 +57,9 @@
width: 55px;
}
+
+.indexerFlags {
+ composes: cell from '~Components/Table/Cells/TableRowCell.css';
+
+ width: 50px;
+}
diff --git a/frontend/src/MovieFile/Editor/MovieFileEditorRow.css.d.ts b/frontend/src/MovieFile/Editor/MovieFileEditorRow.css.d.ts
index d7eafc0fd..a15d0ed8c 100644
--- a/frontend/src/MovieFile/Editor/MovieFileEditorRow.css.d.ts
+++ b/frontend/src/MovieFile/Editor/MovieFileEditorRow.css.d.ts
@@ -9,6 +9,7 @@ interface CssExports {
'dateAdded': string;
'download': string;
'formats': string;
+ 'indexerFlags': string;
'language': string;
'languages': string;
'quality': string;
diff --git a/frontend/src/MovieFile/Editor/MovieFileEditorRow.js b/frontend/src/MovieFile/Editor/MovieFileEditorRow.js
index f7de755ad..5c0604efa 100644
--- a/frontend/src/MovieFile/Editor/MovieFileEditorRow.js
+++ b/frontend/src/MovieFile/Editor/MovieFileEditorRow.js
@@ -1,12 +1,15 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
+import Icon from 'Components/Icon';
import IconButton from 'Components/Link/IconButton';
import ConfirmModal from 'Components/Modal/ConfirmModal';
import RelativeDateCellConnector from 'Components/Table/Cells/RelativeDateCellConnector';
import TableRowCell from 'Components/Table/Cells/TableRowCell';
import TableRow from 'Components/Table/TableRow';
+import Popover from 'Components/Tooltip/Popover';
import Tooltip from 'Components/Tooltip/Tooltip';
import { icons, kinds, tooltipPositions } from 'Helpers/Props';
+import IndexerFlags from 'Movie/IndexerFlags';
import MovieFormats from 'Movie/MovieFormats';
import MovieLanguage from 'Movie/MovieLanguage';
import MovieQuality from 'Movie/MovieQuality';
@@ -82,6 +85,7 @@ class MovieFileEditorRow extends Component {
qualityCutoffNotMet,
customFormats,
customFormatScore,
+ indexerFlags,
languages,
dateAdded,
columns
@@ -143,12 +147,30 @@ class MovieFileEditorRow extends Component {
customFormats.length
)}
tooltip={}
- position={tooltipPositions.TOP}
+ position={tooltipPositions.LEFT}
/>
);
}
+ if (name === 'indexerFlags') {
+ return (
+
+ {indexerFlags ? (
+ }
+ title={translate('IndexerFlags')}
+ body={}
+ position={tooltipPositions.LEFT}
+ />
+ ) : null}
+
+ );
+ }
+
if (name === 'languages') {
return (
translate('IndexerFlags'),
+ label: React.createElement(Icon, {
+ name: icons.FLAG,
+ title: () => translate('IndexerFlags')
+ }),
+ isVisible: false
+ },
{
name: 'dateAdded',
label: () => translate('Added'),
diff --git a/src/NzbDrone.Core/CustomFormats/CustomFormatCalculationService.cs b/src/NzbDrone.Core/CustomFormats/CustomFormatCalculationService.cs
index 6257ae0b8..9d1f6f1a4 100644
--- a/src/NzbDrone.Core/CustomFormats/CustomFormatCalculationService.cs
+++ b/src/NzbDrone.Core/CustomFormats/CustomFormatCalculationService.cs
@@ -78,8 +78,8 @@ namespace NzbDrone.Core.CustomFormats
MovieInfo = movieInfo,
Movie = movie,
Size = blocklist.Size ?? 0,
- IndexerFlags = blocklist.IndexerFlags,
- Languages = blocklist.Languages
+ Languages = blocklist.Languages,
+ IndexerFlags = blocklist.IndexerFlags
};
return ParseCustomFormat(input);
@@ -90,7 +90,7 @@ namespace NzbDrone.Core.CustomFormats
var parsed = Parser.Parser.ParseMovieTitle(history.SourceTitle);
long.TryParse(history.Data.GetValueOrDefault("size"), out var size);
- Enum.TryParse(history.Data.GetValueOrDefault("indexerFlags"), true, out IndexerFlags flags);
+ Enum.TryParse(history.Data.GetValueOrDefault("indexerFlags"), true, out IndexerFlags indexerFlags);
var movieInfo = new ParsedMovieInfo
{
@@ -108,8 +108,8 @@ namespace NzbDrone.Core.CustomFormats
MovieInfo = movieInfo,
Movie = movie,
Size = size,
- IndexerFlags = flags,
- Languages = history.Languages
+ Languages = history.Languages,
+ IndexerFlags = indexerFlags
};
return ParseCustomFormat(input);
@@ -117,7 +117,7 @@ namespace NzbDrone.Core.CustomFormats
public List ParseCustomFormat(LocalMovie localMovie)
{
- var episodeInfo = new ParsedMovieInfo
+ var movieInfo = new ParsedMovieInfo
{
MovieTitles = new List() { localMovie.Movie.Title },
SimpleReleaseTitle = localMovie.SceneName.IsNotNullOrWhiteSpace() ? localMovie.SceneName.SimplifyReleaseTitle() : Path.GetFileName(localMovie.Path).SimplifyReleaseTitle(),
@@ -130,10 +130,11 @@ namespace NzbDrone.Core.CustomFormats
var input = new CustomFormatInput
{
- MovieInfo = episodeInfo,
+ MovieInfo = movieInfo,
Movie = localMovie.Movie,
Size = localMovie.Size,
Languages = localMovie.Languages,
+ IndexerFlags = localMovie.IndexerFlags,
Filename = Path.GetFileName(localMovie.Path)
};
@@ -203,8 +204,8 @@ namespace NzbDrone.Core.CustomFormats
MovieInfo = movieInfo,
Movie = movie,
Size = movieFile.Size,
- IndexerFlags = movieFile.IndexerFlags,
Languages = movieFile.Languages,
+ IndexerFlags = movieFile.IndexerFlags,
Filename = Path.GetFileName(movieFile.RelativePath)
};
diff --git a/src/NzbDrone.Core/CustomFormats/Specifications/IndexerFlagSpecification.cs b/src/NzbDrone.Core/CustomFormats/Specifications/IndexerFlagSpecification.cs
index ccd0abe1c..56f73f8b9 100644
--- a/src/NzbDrone.Core/CustomFormats/Specifications/IndexerFlagSpecification.cs
+++ b/src/NzbDrone.Core/CustomFormats/Specifications/IndexerFlagSpecification.cs
@@ -15,7 +15,7 @@ namespace NzbDrone.Core.CustomFormats
{
if (!Enum.IsDefined(typeof(IndexerFlags), qualityValue))
{
- context.AddFailure(string.Format("Invalid indexer flag condition value: {0}", qualityValue));
+ context.AddFailure($"Invalid indexer flag condition value: {qualityValue}");
}
});
}
@@ -23,17 +23,17 @@ namespace NzbDrone.Core.CustomFormats
public class IndexerFlagSpecification : CustomFormatSpecificationBase
{
- private static readonly IndexerFlagSpecificationValidator Validator = new IndexerFlagSpecificationValidator();
+ private static readonly IndexerFlagSpecificationValidator Validator = new ();
public override int Order => 4;
public override string ImplementationName => "Indexer Flag";
- [FieldDefinition(1, Label = "Flag", Type = FieldType.Select, SelectOptions = typeof(IndexerFlags))]
+ [FieldDefinition(1, Label = "CustomFormatsSpecificationFlag", Type = FieldType.Select, SelectOptions = typeof(IndexerFlags))]
public int Value { get; set; }
protected override bool IsSatisfiedByWithoutNegate(CustomFormatInput input)
{
- return input.IndexerFlags.HasFlag((IndexerFlags)Value) == true;
+ return input.IndexerFlags.HasFlag((IndexerFlags)Value);
}
public override NzbDroneValidationResult Validate()
diff --git a/src/NzbDrone.Core/Download/TrackedDownloads/TrackedDownloadService.cs b/src/NzbDrone.Core/Download/TrackedDownloads/TrackedDownloadService.cs
index 3c395484d..05b3e25c0 100644
--- a/src/NzbDrone.Core/Download/TrackedDownloads/TrackedDownloadService.cs
+++ b/src/NzbDrone.Core/Download/TrackedDownloads/TrackedDownloadService.cs
@@ -140,12 +140,11 @@ namespace NzbDrone.Core.Download.TrackedDownloads
var firstHistoryItem = historyItems.FirstOrDefault();
var grabbedEvent = historyItems.FirstOrDefault(v => v.EventType == MovieHistoryEventType.Grabbed);
- trackedDownload.Indexer = grabbedEvent?.Data["indexer"];
+ trackedDownload.Indexer = grabbedEvent?.Data?.GetValueOrDefault("indexer");
trackedDownload.Added = grabbedEvent?.Date;
if (parsedMovieInfo == null ||
- trackedDownload.RemoteMovie == null ||
- trackedDownload.RemoteMovie.Movie == null)
+ trackedDownload.RemoteMovie?.Movie == null)
{
parsedMovieInfo = Parser.Parser.ParseMovieTitle(firstHistoryItem.SourceTitle);
diff --git a/src/NzbDrone.Core/Indexers/FileList/FileListParser.cs b/src/NzbDrone.Core/Indexers/FileList/FileListParser.cs
index 7adda8192..1b4bbbae7 100644
--- a/src/NzbDrone.Core/Indexers/FileList/FileListParser.cs
+++ b/src/NzbDrone.Core/Indexers/FileList/FileListParser.cs
@@ -39,18 +39,6 @@ namespace NzbDrone.Core.Indexers.FileList
{
var id = result.Id;
- IndexerFlags flags = 0;
-
- if (result.FreeLeech)
- {
- flags |= IndexerFlags.G_Freeleech;
- }
-
- if (result.Internal)
- {
- flags |= IndexerFlags.G_Internal;
- }
-
var imdbId = 0;
if (result.ImdbId != null && result.ImdbId.Length > 2)
{
@@ -68,14 +56,29 @@ namespace NzbDrone.Core.Indexers.FileList
Peers = result.Leechers + result.Seeders,
PublishDate = result.UploadDate,
ImdbId = imdbId,
- IndexerFlags = flags
+ IndexerFlags = GetIndexerFlags(result)
});
}
return torrentInfos.ToArray();
}
- public Action, DateTime?> CookiesUpdater { get; set; }
+ private static IndexerFlags GetIndexerFlags(FileListTorrent item)
+ {
+ IndexerFlags flags = 0;
+
+ if (item.FreeLeech)
+ {
+ flags |= IndexerFlags.G_Freeleech;
+ }
+
+ if (item.Internal)
+ {
+ flags |= IndexerFlags.G_Internal;
+ }
+
+ return flags;
+ }
private string GetDownloadUrl(string torrentId)
{
@@ -95,5 +98,7 @@ namespace NzbDrone.Core.Indexers.FileList
return url.FullUri;
}
+
+ public Action, DateTime?> CookiesUpdater { get; set; }
}
}
diff --git a/src/NzbDrone.Core/Indexers/HDBits/HDBitsParser.cs b/src/NzbDrone.Core/Indexers/HDBits/HDBitsParser.cs
index b14fac3aa..91d35114b 100644
--- a/src/NzbDrone.Core/Indexers/HDBits/HDBitsParser.cs
+++ b/src/NzbDrone.Core/Indexers/HDBits/HDBitsParser.cs
@@ -50,19 +50,6 @@ namespace NzbDrone.Core.Indexers.HDBits
foreach (var result in queryResults)
{
var id = result.Id;
- var internalRelease = result.TypeOrigin == 1;
-
- IndexerFlags flags = 0;
-
- if (result.FreeLeech == "yes")
- {
- flags |= IndexerFlags.G_Freeleech;
- }
-
- if (internalRelease)
- {
- flags |= IndexerFlags.G_Internal;
- }
torrentInfos.Add(new HDBitsInfo
{
@@ -75,16 +62,30 @@ namespace NzbDrone.Core.Indexers.HDBits
Seeders = result.Seeders,
Peers = result.Leechers + result.Seeders,
PublishDate = result.Added.ToUniversalTime(),
- Internal = internalRelease,
ImdbId = result.ImdbInfo?.Id ?? 0,
- IndexerFlags = flags
+ IndexerFlags = GetIndexerFlags(result)
});
}
return torrentInfos.ToArray();
}
- public Action, DateTime?> CookiesUpdater { get; set; }
+ private static IndexerFlags GetIndexerFlags(TorrentQueryResponse item)
+ {
+ IndexerFlags flags = 0;
+
+ if (item.FreeLeech == "yes")
+ {
+ flags |= IndexerFlags.G_Freeleech;
+ }
+
+ if (item.TypeOrigin == 1)
+ {
+ flags |= IndexerFlags.G_Internal;
+ }
+
+ return flags;
+ }
private string GetDownloadUrl(string torrentId)
{
@@ -104,5 +105,7 @@ namespace NzbDrone.Core.Indexers.HDBits
return url.FullUri;
}
+
+ public Action, DateTime?> CookiesUpdater { get; set; }
}
}
diff --git a/src/NzbDrone.Core/Localization/Core/en.json b/src/NzbDrone.Core/Localization/Core/en.json
index 92411ea1c..4b591948e 100644
--- a/src/NzbDrone.Core/Localization/Core/en.json
+++ b/src/NzbDrone.Core/Localization/Core/en.json
@@ -193,6 +193,7 @@
"Clear": "Clear",
"ClearBlocklist": "Clear blocklist",
"ClearBlocklistMessageText": "Are you sure you want to clear all items from the blocklist?",
+ "ClickToChangeIndexerFlags": "Click to change indexer flags",
"ClickToChangeLanguage": "Click to change language",
"ClickToChangeMovie": "Click to change movie",
"ClickToChangeQuality": "Click to change quality",
@@ -255,6 +256,7 @@
"CustomFormatsLoadError": "Unable to load Custom Formats",
"CustomFormatsSettings": "Custom Formats Settings",
"CustomFormatsSettingsSummary": "Custom Formats and Settings",
+ "CustomFormatsSpecificationFlag": "Flag",
"CustomFormatsSpecificationRegularExpression": "Regular Expression",
"CustomFormatsSpecificationRegularExpressionHelpText": "Custom Format RegEx is Case Insensitive",
"Cutoff": "Cutoff",
@@ -1483,6 +1485,7 @@
"SelectDropdown": "Select...",
"SelectFolder": "Select Folder",
"SelectFolderModalTitle": "{modalTitle} - Select Folder",
+ "SelectIndexerFlags": "Select Indexer Flags",
"SelectLanguage": "Select Language",
"SelectLanguageModalTitle": "{modalTitle} - Select Language",
"SelectLanguages": "Select Languages",
@@ -1490,6 +1493,8 @@
"SelectQuality": "Select Quality",
"SelectReleaseGroup": "Select Release Group",
"SendAnonymousUsageData": "Send Anonymous Usage Data",
+ "SetIndexerFlags": "Set Indexer Flags",
+ "SetIndexerFlagsModalTitle": "{modalTitle} - Set Indexer Flags",
"SetPermissions": "Set Permissions",
"SetPermissionsLinuxHelpText": "Should chmod be run when files are imported/renamed?",
"SetPermissionsLinuxHelpTextWarning": "If you're unsure what these settings do, do not alter them.",
diff --git a/src/NzbDrone.Core/MediaFiles/MovieFile.cs b/src/NzbDrone.Core/MediaFiles/MovieFile.cs
index 7e885a5cb..ede888f8c 100644
--- a/src/NzbDrone.Core/MediaFiles/MovieFile.cs
+++ b/src/NzbDrone.Core/MediaFiles/MovieFile.cs
@@ -20,12 +20,12 @@ namespace NzbDrone.Core.MediaFiles
public string OriginalFilePath { get; set; }
public string SceneName { get; set; }
public string ReleaseGroup { get; set; }
- public IndexerFlags IndexerFlags { get; set; }
public QualityModel Quality { get; set; }
- public List Languages { get; set; }
+ public IndexerFlags IndexerFlags { get; set; }
public MediaInfoModel MediaInfo { get; set; }
public string Edition { get; set; }
public Movie Movie { get; set; }
+ public List Languages { get; set; }
public override string ToString()
{
diff --git a/src/NzbDrone.Core/MediaFiles/MovieImport/ImportApprovedMovie.cs b/src/NzbDrone.Core/MediaFiles/MovieImport/ImportApprovedMovie.cs
index 6c151a563..56016dda6 100644
--- a/src/NzbDrone.Core/MediaFiles/MovieImport/ImportApprovedMovie.cs
+++ b/src/NzbDrone.Core/MediaFiles/MovieImport/ImportApprovedMovie.cs
@@ -108,6 +108,10 @@ namespace NzbDrone.Core.MediaFiles.MovieImport
movieFile.IndexerFlags = flags;
}
}
+ else
+ {
+ movieFile.IndexerFlags = localMovie.IndexerFlags;
+ }
bool copyOnly;
switch (importMode)
diff --git a/src/NzbDrone.Core/MediaFiles/MovieImport/Manual/ManualImportFile.cs b/src/NzbDrone.Core/MediaFiles/MovieImport/Manual/ManualImportFile.cs
index 87c500de1..443b24cc6 100644
--- a/src/NzbDrone.Core/MediaFiles/MovieImport/Manual/ManualImportFile.cs
+++ b/src/NzbDrone.Core/MediaFiles/MovieImport/Manual/ManualImportFile.cs
@@ -13,6 +13,7 @@ namespace NzbDrone.Core.MediaFiles.MovieImport.Manual
public QualityModel Quality { get; set; }
public List Languages { get; set; }
public string ReleaseGroup { get; set; }
+ public int IndexerFlags { get; set; }
public string DownloadId { get; set; }
public int MovieId { get; set; }
diff --git a/src/NzbDrone.Core/MediaFiles/MovieImport/Manual/ManualImportItem.cs b/src/NzbDrone.Core/MediaFiles/MovieImport/Manual/ManualImportItem.cs
index 516c0dd5e..a809868fb 100644
--- a/src/NzbDrone.Core/MediaFiles/MovieImport/Manual/ManualImportItem.cs
+++ b/src/NzbDrone.Core/MediaFiles/MovieImport/Manual/ManualImportItem.cs
@@ -20,6 +20,7 @@ namespace NzbDrone.Core.MediaFiles.MovieImport.Manual
public string DownloadId { get; set; }
public List CustomFormats { get; set; }
public int CustomFormatScore { get; set; }
+ public int IndexerFlags { get; set; }
public IEnumerable Rejections { get; set; }
public Movie Movie { get; set; }
diff --git a/src/NzbDrone.Core/MediaFiles/MovieImport/Manual/ManualImportService.cs b/src/NzbDrone.Core/MediaFiles/MovieImport/Manual/ManualImportService.cs
index b93b5bd24..3a257aa8a 100644
--- a/src/NzbDrone.Core/MediaFiles/MovieImport/Manual/ManualImportService.cs
+++ b/src/NzbDrone.Core/MediaFiles/MovieImport/Manual/ManualImportService.cs
@@ -24,7 +24,7 @@ namespace NzbDrone.Core.MediaFiles.MovieImport.Manual
public interface IManualImportService
{
List GetMediaFiles(string path, string downloadId, int? movieId, bool filterExistingFiles);
- ManualImportItem ReprocessItem(string path, string downloadId, int movieId, string releaseGroup, QualityModel quality, List languages);
+ ManualImportItem ReprocessItem(string path, string downloadId, int movieId, string releaseGroup, QualityModel quality, List languages, int indexerFlags);
}
public class ManualImportService : IExecute, IManualImportService
@@ -97,7 +97,7 @@ namespace NzbDrone.Core.MediaFiles.MovieImport.Manual
return ProcessFolder(path, path, downloadId, movieId, filterExistingFiles);
}
- public ManualImportItem ReprocessItem(string path, string downloadId, int movieId, string releaseGroup, QualityModel quality, List languages)
+ public ManualImportItem ReprocessItem(string path, string downloadId, int movieId, string releaseGroup, QualityModel quality, List languages, int indexerFlags)
{
var rootFolder = Path.GetDirectoryName(path);
var movie = _movieService.GetMovie(movieId);
@@ -122,9 +122,10 @@ namespace NzbDrone.Core.MediaFiles.MovieImport.Manual
SceneSource = SceneSource(movie, rootFolder),
ExistingFile = movie.Path.IsParentPath(path),
Size = _diskProvider.GetFileSize(path),
+ ReleaseGroup = releaseGroup.IsNullOrWhiteSpace() ? Parser.Parser.ParseReleaseGroup(path) : releaseGroup,
Languages = languages?.Count <= 1 && (languages?.SingleOrDefault() ?? Language.Unknown) == Language.Unknown ? languageParse : languages,
Quality = (quality?.Quality ?? Quality.Unknown) == Quality.Unknown ? QualityParser.ParseQuality(path) : quality,
- ReleaseGroup = releaseGroup.IsNullOrWhiteSpace() ? Parser.Parser.ParseReleaseGroup(path) : releaseGroup,
+ IndexerFlags = (IndexerFlags)indexerFlags
};
return MapItem(_importDecisionMaker.GetDecision(localMovie, downloadClientItem), rootFolder, downloadId, null);
@@ -320,6 +321,7 @@ namespace NzbDrone.Core.MediaFiles.MovieImport.Manual
item.Languages = decision.LocalMovie.Languages;
item.ReleaseGroup = decision.LocalMovie.ReleaseGroup;
item.Rejections = decision.Rejections;
+ item.IndexerFlags = (int)decision.LocalMovie.IndexerFlags;
return item;
}
@@ -346,9 +348,10 @@ namespace NzbDrone.Core.MediaFiles.MovieImport.Manual
ExistingFile = existingFile,
FileMovieInfo = fileMovieInfo,
Path = file.Path,
+ ReleaseGroup = file.ReleaseGroup,
Quality = file.Quality,
Languages = file.Languages,
- ReleaseGroup = file.ReleaseGroup,
+ IndexerFlags = (IndexerFlags)file.IndexerFlags,
Movie = movie,
Size = 0
};
@@ -373,9 +376,10 @@ namespace NzbDrone.Core.MediaFiles.MovieImport.Manual
// Apply the user-chosen values.
localMovie.Movie = movie;
+ localMovie.ReleaseGroup = file.ReleaseGroup;
localMovie.Quality = file.Quality;
localMovie.Languages = file.Languages;
- localMovie.ReleaseGroup = file.ReleaseGroup;
+ localMovie.IndexerFlags = (IndexerFlags)file.IndexerFlags;
// TODO: Cleanup non-tracked downloads
var importDecision = new ImportDecision(localMovie);
diff --git a/src/NzbDrone.Core/Parser/Model/LocalMovie.cs b/src/NzbDrone.Core/Parser/Model/LocalMovie.cs
index 392833a6a..3d89d349e 100644
--- a/src/NzbDrone.Core/Parser/Model/LocalMovie.cs
+++ b/src/NzbDrone.Core/Parser/Model/LocalMovie.cs
@@ -26,6 +26,7 @@ namespace NzbDrone.Core.Parser.Model
public List OldFiles { get; set; }
public QualityModel Quality { get; set; }
public List Languages { get; set; }
+ public IndexerFlags IndexerFlags { get; set; }
public MediaInfoModel MediaInfo { get; set; }
public bool ExistingFile { get; set; }
public bool SceneSource { get; set; }
diff --git a/src/NzbDrone.Core/Parser/Model/ReleaseInfo.cs b/src/NzbDrone.Core/Parser/Model/ReleaseInfo.cs
index 788ce9a10..d21188c85 100644
--- a/src/NzbDrone.Core/Parser/Model/ReleaseInfo.cs
+++ b/src/NzbDrone.Core/Parser/Model/ReleaseInfo.cs
@@ -108,12 +108,12 @@ namespace NzbDrone.Core.Parser.Model
G_DoubleUpload = 4, // General
PTP_Golden = 8, // PTP
PTP_Approved = 16, // PTP
- G_Internal = 32, // General, internal
+ G_Internal = 32, // General, uploader is an internal release group
[Obsolete]
AHD_Internal = 64, // AHD, internal
- G_Scene = 128, // General, the torrent comes from the "scene"
- G_Freeleech75 = 256, // Currently only used for AHD, signifies a torrent counts towards 75 percent of your download quota.
- G_Freeleech25 = 512, // Currently only used for AHD, signifies a torrent counts towards 25 percent of your download quota.
+ G_Scene = 128, // General, the torrent comes from a "scene" group
+ G_Freeleech75 = 256, // Signifies a torrent counts towards 75 percent of your download quota.
+ G_Freeleech25 = 512, // Signifies a torrent counts towards 25 percent of your download quota.
[Obsolete]
AHD_UserRelease = 1024 // AHD, internal
}
diff --git a/src/Radarr.Api.V3/Indexers/ReleaseResource.cs b/src/Radarr.Api.V3/Indexers/ReleaseResource.cs
index 89d155570..fb2807424 100644
--- a/src/Radarr.Api.V3/Indexers/ReleaseResource.cs
+++ b/src/Radarr.Api.V3/Indexers/ReleaseResource.cs
@@ -45,7 +45,6 @@ namespace Radarr.Api.V3.Indexers
public string InfoUrl { get; set; }
public bool DownloadAllowed { get; set; }
public int ReleaseWeight { get; set; }
- public IEnumerable IndexerFlags { get; set; }
public string Edition { get; set; }
public string MagnetUrl { get; set; }
@@ -53,6 +52,7 @@ namespace Radarr.Api.V3.Indexers
public int? Seeders { get; set; }
public int? Leechers { get; set; }
public DownloadProtocol Protocol { get; set; }
+ public int IndexerFlags { get; set; }
// Sent when queuing an unknown release
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]
@@ -76,7 +76,7 @@ namespace Radarr.Api.V3.Indexers
var parsedMovieInfo = model.RemoteMovie.ParsedMovieInfo;
var remoteMovie = model.RemoteMovie;
var torrentInfo = (model.RemoteMovie.Release as TorrentInfo) ?? new TorrentInfo();
- var indexerFlags = torrentInfo.IndexerFlags.ToString().Split(new string[] { ", " }, StringSplitOptions.None).Where(x => x != "0");
+ var indexerFlags = torrentInfo.IndexerFlags;
// TODO: Clean this mess up. don't mix data from multiple classes, use sub-resources instead? (Got a huge Deja Vu, didn't we talk about this already once?)
return new ReleaseResource
@@ -118,7 +118,7 @@ namespace Radarr.Api.V3.Indexers
Seeders = torrentInfo.Seeders,
Leechers = (torrentInfo.Peers.HasValue && torrentInfo.Seeders.HasValue) ? (torrentInfo.Peers.Value - torrentInfo.Seeders.Value) : (int?)null,
Protocol = releaseInfo.DownloadProtocol,
- IndexerFlags = indexerFlags
+ IndexerFlags = (int)indexerFlags
};
}
diff --git a/src/Radarr.Api.V3/ManualImport/ManualImportController.cs b/src/Radarr.Api.V3/ManualImport/ManualImportController.cs
index 3a270f35a..40f877d7f 100644
--- a/src/Radarr.Api.V3/ManualImport/ManualImportController.cs
+++ b/src/Radarr.Api.V3/ManualImport/ManualImportController.cs
@@ -34,9 +34,10 @@ namespace Radarr.Api.V3.ManualImport
{
foreach (var item in items)
{
- var processedItem = _manualImportService.ReprocessItem(item.Path, item.DownloadId, item.MovieId, item.ReleaseGroup, item.Quality, item.Languages);
+ var processedItem = _manualImportService.ReprocessItem(item.Path, item.DownloadId, item.MovieId, item.ReleaseGroup, item.Quality, item.Languages, item.IndexerFlags);
item.Movie = processedItem.Movie.ToResource(0);
+ item.IndexerFlags = processedItem.IndexerFlags;
item.Rejections = processedItem.Rejections;
item.CustomFormats = processedItem.CustomFormats.ToResource(false);
item.CustomFormatScore = processedItem.CustomFormatScore;
diff --git a/src/Radarr.Api.V3/ManualImport/ManualImportReprocessResource.cs b/src/Radarr.Api.V3/ManualImport/ManualImportReprocessResource.cs
index 5733f145e..659fea56f 100644
--- a/src/Radarr.Api.V3/ManualImport/ManualImportReprocessResource.cs
+++ b/src/Radarr.Api.V3/ManualImport/ManualImportReprocessResource.cs
@@ -19,6 +19,7 @@ namespace Radarr.Api.V3.ManualImport
public string DownloadId { get; set; }
public List CustomFormats { get; set; }
public int CustomFormatScore { get; set; }
+ public int IndexerFlags { get; set; }
public IEnumerable Rejections { get; set; }
}
}
diff --git a/src/Radarr.Api.V3/ManualImport/ManualImportResource.cs b/src/Radarr.Api.V3/ManualImport/ManualImportResource.cs
index c75d3ae9b..b89561403 100644
--- a/src/Radarr.Api.V3/ManualImport/ManualImportResource.cs
+++ b/src/Radarr.Api.V3/ManualImport/ManualImportResource.cs
@@ -26,6 +26,7 @@ namespace Radarr.Api.V3.ManualImport
public string DownloadId { get; set; }
public List CustomFormats { get; set; }
public int CustomFormatScore { get; set; }
+ public int IndexerFlags { get; set; }
public IEnumerable Rejections { get; set; }
}
@@ -58,6 +59,7 @@ namespace Radarr.Api.V3.ManualImport
// QualityWeight
DownloadId = model.DownloadId,
+ IndexerFlags = model.IndexerFlags,
Rejections = model.Rejections
};
}
diff --git a/src/Radarr.Api.V3/MovieFiles/MovieFileResource.cs b/src/Radarr.Api.V3/MovieFiles/MovieFileResource.cs
index 15b19ab7d..9d798d38d 100644
--- a/src/Radarr.Api.V3/MovieFiles/MovieFileResource.cs
+++ b/src/Radarr.Api.V3/MovieFiles/MovieFileResource.cs
@@ -19,16 +19,17 @@ namespace Radarr.Api.V3.MovieFiles
public long Size { get; set; }
public DateTime DateAdded { get; set; }
public string SceneName { get; set; }
- public int IndexerFlags { get; set; }
+ public string ReleaseGroup { get; set; }
+ public string Edition { get; set; }
+ public List Languages { get; set; }
public QualityModel Quality { get; set; }
public List CustomFormats { get; set; }
public int CustomFormatScore { get; set; }
+ public int? IndexerFlags { get; set; }
public MediaInfoResource MediaInfo { get; set; }
+
public string OriginalFilePath { get; set; }
public bool QualityCutoffNotMet { get; set; }
- public List Languages { get; set; }
- public string ReleaseGroup { get; set; }
- public string Edition { get; set; }
}
public static class MovieFileResourceMapper
@@ -78,14 +79,14 @@ namespace Radarr.Api.V3.MovieFiles
Size = model.Size,
DateAdded = model.DateAdded,
SceneName = model.SceneName,
- IndexerFlags = (int)model.IndexerFlags,
Quality = model.Quality,
Languages = model.Languages,
Edition = model.Edition,
ReleaseGroup = model.ReleaseGroup,
MediaInfo = model.MediaInfo.ToResource(model.SceneName),
QualityCutoffNotMet = upgradableSpecification?.QualityCutoffNotMet(movie.QualityProfile, model.Quality) ?? false,
- OriginalFilePath = model.OriginalFilePath
+ OriginalFilePath = model.OriginalFilePath,
+ IndexerFlags = (int)model.IndexerFlags
};
if (formatCalculationService != null)