diff --git a/frontend/src/Settings/ImportLists/ImportLists/EditImportListModalContent.tsx b/frontend/src/Settings/ImportLists/ImportLists/EditImportListModalContent.tsx
index 2b06cc2e78..64398debbb 100644
--- a/frontend/src/Settings/ImportLists/ImportLists/EditImportListModalContent.tsx
+++ b/frontend/src/Settings/ImportLists/ImportLists/EditImportListModalContent.tsx
@@ -78,6 +78,7 @@ function EditImportListModalContent({
qualityProfileId,
searchOnAdd,
tags,
+ tagExisting,
fields,
} = item;
@@ -256,6 +257,18 @@ function EditImportListModalContent({
/>
+
+ {translate('TagExisting')}
+
+
+
+
{fields?.length ? (
{fields.map((field) => {
diff --git a/frontend/src/Settings/ImportLists/ImportLists/Manage/Edit/ManageImportListsEditModalContent.tsx b/frontend/src/Settings/ImportLists/ImportLists/Manage/Edit/ManageImportListsEditModalContent.tsx
index 74b1662207..5c55519a79 100644
--- a/frontend/src/Settings/ImportLists/ImportLists/Manage/Edit/ManageImportListsEditModalContent.tsx
+++ b/frontend/src/Settings/ImportLists/ImportLists/Manage/Edit/ManageImportListsEditModalContent.tsx
@@ -18,6 +18,7 @@ interface SavePayload {
qualityProfileId?: number;
minimumAvailability?: string;
rootFolderPath?: string;
+ tagExisting?: boolean;
}
interface ManageImportListsEditModalContentProps {
@@ -62,7 +63,7 @@ function ManageImportListsEditModalContent(
);
const [minimumAvailability, setMinimumAvailability] = useState(NO_CHANGE);
const [rootFolderPath, setRootFolderPath] = useState(NO_CHANGE);
-
+ const [tagExisting, setTagExisting] = useState(NO_CHANGE);
const save = useCallback(() => {
let hasChanges = false;
const payload: SavePayload = {};
@@ -91,6 +92,10 @@ function ManageImportListsEditModalContent(
hasChanges = true;
payload.rootFolderPath = rootFolderPath;
}
+ if (tagExisting !== NO_CHANGE) {
+ hasChanges = true;
+ payload.tagExisting = tagExisting === 'enabled';
+ }
if (hasChanges) {
onSavePress(payload);
@@ -103,6 +108,7 @@ function ManageImportListsEditModalContent(
qualityProfileId,
minimumAvailability,
rootFolderPath,
+ tagExisting,
onSavePress,
onModalClose,
]);
@@ -124,6 +130,9 @@ function ManageImportListsEditModalContent(
case 'rootFolderPath':
setRootFolderPath(value as string);
break;
+ case 'tagExisting':
+ setTagExisting(value as string);
+ break;
default:
console.warn(`EditImportListModalContent Unknown Input: '${name}'`);
}
@@ -199,6 +208,18 @@ function ManageImportListsEditModalContent(
onChange={onInputChange}
/>
+
+
+ {translate('TagExisting')}
+
+
+
diff --git a/frontend/src/Settings/ImportLists/ImportLists/Manage/ManageImportListsModalContent.tsx b/frontend/src/Settings/ImportLists/ImportLists/Manage/ManageImportListsModalContent.tsx
index b73132eb85..23acb0b4bf 100644
--- a/frontend/src/Settings/ImportLists/ImportLists/Manage/ManageImportListsModalContent.tsx
+++ b/frontend/src/Settings/ImportLists/ImportLists/Manage/ManageImportListsModalContent.tsx
@@ -82,6 +82,12 @@ const COLUMNS = [
isSortable: true,
isVisible: true,
},
+ {
+ name: 'tagExisting',
+ label: () => translate('TagExisting'),
+ isSortable: true,
+ isVisible: true,
+ },
];
interface ManageImportListsModalContentProps {
diff --git a/frontend/src/Settings/ImportLists/ImportLists/Manage/ManageImportListsModalRow.css b/frontend/src/Settings/ImportLists/ImportLists/Manage/ManageImportListsModalRow.css
index 7045ed925b..f18c48db21 100644
--- a/frontend/src/Settings/ImportLists/ImportLists/Manage/ManageImportListsModalRow.css
+++ b/frontend/src/Settings/ImportLists/ImportLists/Manage/ManageImportListsModalRow.css
@@ -5,6 +5,7 @@
.minimumAvailability,
.qualityProfileId,
.rootFolderPath,
+.tagExisting,
.implementation {
composes: cell from '~Components/Table/Cells/TableRowCell.css';
diff --git a/frontend/src/Settings/ImportLists/ImportLists/Manage/ManageImportListsModalRow.css.d.ts b/frontend/src/Settings/ImportLists/ImportLists/Manage/ManageImportListsModalRow.css.d.ts
index c6cb99a370..78ff64f037 100644
--- a/frontend/src/Settings/ImportLists/ImportLists/Manage/ManageImportListsModalRow.css.d.ts
+++ b/frontend/src/Settings/ImportLists/ImportLists/Manage/ManageImportListsModalRow.css.d.ts
@@ -8,6 +8,7 @@ interface CssExports {
'name': string;
'qualityProfileId': string;
'rootFolderPath': string;
+ 'tagExisting': string;
'tags': string;
}
export const cssExports: CssExports;
diff --git a/frontend/src/Settings/ImportLists/ImportLists/Manage/ManageImportListsModalRow.tsx b/frontend/src/Settings/ImportLists/ImportLists/Manage/ManageImportListsModalRow.tsx
index 7cc9c272f1..cb25677406 100644
--- a/frontend/src/Settings/ImportLists/ImportLists/Manage/ManageImportListsModalRow.tsx
+++ b/frontend/src/Settings/ImportLists/ImportLists/Manage/ManageImportListsModalRow.tsx
@@ -19,6 +19,7 @@ interface ManageImportListsModalRowProps {
minimumAvailability: string;
implementation: string;
tags: number[];
+ tagExisting: boolean;
enabled: boolean;
enableAuto: boolean;
columns: Column[];
@@ -38,6 +39,7 @@ function ManageImportListsModalRow(props: ManageImportListsModalRowProps) {
enabled,
enableAuto,
tags,
+ tagExisting,
onSelectedChange,
} = props;
@@ -91,6 +93,10 @@ function ManageImportListsModalRow(props: ManageImportListsModalRowProps) {
+
+
+ {tagExisting ? translate('Yes') : translate('No')}
+
);
}
diff --git a/frontend/src/typings/ImportList.ts b/frontend/src/typings/ImportList.ts
index 42d805b065..69672d4d0d 100644
--- a/frontend/src/typings/ImportList.ts
+++ b/frontend/src/typings/ImportList.ts
@@ -15,6 +15,7 @@ interface ImportList extends Provider {
minRefreshInterval: string;
name: string;
tags: number[];
+ tagExisting: boolean;
}
export default ImportList;
diff --git a/src/NzbDrone.Core/Datastore/Migration/243_add_tag_existing_to_importlists.cs b/src/NzbDrone.Core/Datastore/Migration/243_add_tag_existing_to_importlists.cs
new file mode 100644
index 0000000000..cf26ab3954
--- /dev/null
+++ b/src/NzbDrone.Core/Datastore/Migration/243_add_tag_existing_to_importlists.cs
@@ -0,0 +1,13 @@
+using FluentMigrator;
+using NzbDrone.Core.Datastore.Migration.Framework;
+
+namespace NzbDrone.Core.Datastore.Migration;
+
+[Migration(243)]
+public class add_tag_existing_to_importlists : NzbDroneMigrationBase
+{
+ protected override void MainDbUpgrade()
+ {
+ Alter.Table("ImportLists").AddColumn("TagExisting").AsBoolean().WithDefaultValue(false);
+ }
+}
diff --git a/src/NzbDrone.Core/ImportLists/ImportListDefinition.cs b/src/NzbDrone.Core/ImportLists/ImportListDefinition.cs
index 277f26eb29..268b7d27b1 100644
--- a/src/NzbDrone.Core/ImportLists/ImportListDefinition.cs
+++ b/src/NzbDrone.Core/ImportLists/ImportListDefinition.cs
@@ -16,6 +16,7 @@ public class ImportListDefinition : ProviderDefinition, IEquatable Enabled;
diff --git a/src/NzbDrone.Core/ImportLists/ImportListSyncService.cs b/src/NzbDrone.Core/ImportLists/ImportListSyncService.cs
index b96e07a0fb..9d48ff61d2 100644
--- a/src/NzbDrone.Core/ImportLists/ImportListSyncService.cs
+++ b/src/NzbDrone.Core/ImportLists/ImportListSyncService.cs
@@ -76,18 +76,25 @@ private void SyncList(ImportListDefinition definition)
private void ProcessMovieReport(ImportListDefinition importList, ImportListMovie report, List listExclusions, List dbMovies, List moviesToAdd)
{
- if (report.TmdbId == 0 || !importList.EnableAuto)
+ if (report.TmdbId == 0)
{
return;
}
- // Check to see if movie in DB
+ // Check to see if movie in DB and maybe apply tags
if (dbMovies.Contains(report.TmdbId))
{
+ TagExisting(importList, report);
_logger.Debug("{0} [{1}] Rejected, Movie Exists in DB", report.TmdbId, report.Title);
return;
}
+ // Now that retro-tags are applied, end if auto import is disabled
+ if (!importList.EnableAuto)
+ {
+ return;
+ }
+
// Check to see if movie excluded
var excludedMovie = listExclusions.SingleOrDefault(s => s.TmdbId == report.TmdbId);
@@ -123,6 +130,26 @@ private void ProcessMovieReport(ImportListDefinition importList, ImportListMovie
}
}
+ private void TagExisting(ImportListDefinition importList, ImportListMovie report)
+ {
+ if (importList.TagExisting)
+ {
+ var movie = _movieService.FindByTmdbId(report.TmdbId);
+
+ var preCount = movie.Tags.Count;
+ foreach (var tag in importList.Tags)
+ {
+ movie.Tags.Add(tag);
+ }
+
+ if (preCount != movie.Tags.Count)
+ {
+ _movieService.UpdateMovie(movie);
+ _logger.Debug("{0} [{1}] Tagged existing movie", report.TmdbId, report.Title);
+ }
+ }
+ }
+
private void ProcessListItems(ImportListFetchResult listFetchResult)
{
listFetchResult.Movies = listFetchResult.Movies.DistinctBy(x =>
diff --git a/src/NzbDrone.Core/Localization/Core/en.json b/src/NzbDrone.Core/Localization/Core/en.json
index 283f20cade..90274ff5cc 100644
--- a/src/NzbDrone.Core/Localization/Core/en.json
+++ b/src/NzbDrone.Core/Localization/Core/en.json
@@ -1697,6 +1697,8 @@
"Result": "Result",
"Retention": "Retention",
"RetentionHelpText": "Usenet only: Set to zero to set for unlimited retention",
+ "TagExistingHelpText": "Tag existing movies in {appName}",
+ "TagExisting": "Tag Existing",
"RetryingDownloadOn": "Retrying download on {date} at {time}",
"RootFolder": "Root Folder",
"RootFolderCheckMultipleMessage": "Multiple root folders are missing: {rootFolderPaths}",
diff --git a/src/Radarr.Api.V3/ImportLists/ImportListBulkResource.cs b/src/Radarr.Api.V3/ImportLists/ImportListBulkResource.cs
index c7633785e9..73e6712c63 100644
--- a/src/Radarr.Api.V3/ImportLists/ImportListBulkResource.cs
+++ b/src/Radarr.Api.V3/ImportLists/ImportListBulkResource.cs
@@ -11,6 +11,7 @@ public class ImportListBulkResource : ProviderBulkResource
@@ -29,6 +30,7 @@ public override List UpdateModel(ImportListBulkResource re
existing.RootFolderPath = resource.RootFolderPath ?? existing.RootFolderPath;
existing.QualityProfileId = resource.QualityProfileId ?? existing.QualityProfileId;
existing.MinimumAvailability = resource.MinimumAvailability ?? existing.MinimumAvailability;
+ existing.TagExisting = resource.TagExisting ?? existing.TagExisting;
});
return existingDefinitions;
diff --git a/src/Radarr.Api.V3/ImportLists/ImportListResource.cs b/src/Radarr.Api.V3/ImportLists/ImportListResource.cs
index 7093f08eaf..27eabb0d89 100644
--- a/src/Radarr.Api.V3/ImportLists/ImportListResource.cs
+++ b/src/Radarr.Api.V3/ImportLists/ImportListResource.cs
@@ -16,6 +16,7 @@ public class ImportListResource : ProviderResource
public ImportListType ListType { get; set; }
public int ListOrder { get; set; }
public TimeSpan MinRefreshInterval { get; set; }
+ public bool TagExisting { get; set; }
}
public class ImportListResourceMapper : ProviderResourceMapper
@@ -39,6 +40,7 @@ public override ImportListResource ToResource(ImportListDefinition definition)
resource.ListType = definition.ListType;
resource.ListOrder = (int)definition.ListType;
resource.MinRefreshInterval = definition.MinRefreshInterval;
+ resource.TagExisting = definition.TagExisting;
return resource;
}
@@ -61,6 +63,7 @@ public override ImportListDefinition ToModel(ImportListResource resource, Import
definition.MinimumAvailability = resource.MinimumAvailability;
definition.ListType = resource.ListType;
definition.MinRefreshInterval = resource.MinRefreshInterval;
+ definition.TagExisting = resource.TagExisting;
return definition;
}
diff --git a/src/Radarr.Api.V3/ProviderResource.cs b/src/Radarr.Api.V3/ProviderResource.cs
index c5e8a1cd6f..2af43b9f38 100644
--- a/src/Radarr.Api.V3/ProviderResource.cs
+++ b/src/Radarr.Api.V3/ProviderResource.cs
@@ -16,7 +16,6 @@ public class ProviderResource : RestResource
public string InfoLink { get; set; }
public ProviderMessage Message { get; set; }
public HashSet Tags { get; set; }
-
public List Presets { get; set; }
}