This commit is contained in:
Steel City Phantom 2026-05-05 17:03:34 +01:00 committed by GitHub
commit cb18445255
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 100 additions and 4 deletions

View file

@ -78,6 +78,7 @@ function EditImportListModalContent({
qualityProfileId,
searchOnAdd,
tags,
tagExisting,
fields,
} = item;
@ -256,6 +257,18 @@ function EditImportListModalContent({
/>
</FormGroup>
<FormGroup>
<FormLabel>{translate('TagExisting')}</FormLabel>
<FormInputGroup
type={inputTypes.CHECK}
name="tagExisting"
helpText={translate('TagExistingHelpText')}
{...tagExisting}
onChange={handleInputChange}
/>
</FormGroup>
{fields?.length ? (
<div>
{fields.map((field) => {

View file

@ -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}
/>
</FormGroup>
<FormGroup>
<FormLabel>{translate('TagExisting')}</FormLabel>
<FormInputGroup
type={inputTypes.SELECT}
name="tagExisting"
value={tagExisting}
values={enableOptions}
onChange={onInputChange}
/>
</FormGroup>
</ModalBody>
<ModalFooter className={styles.modalFooter}>

View file

@ -82,6 +82,12 @@ const COLUMNS = [
isSortable: true,
isVisible: true,
},
{
name: 'tagExisting',
label: () => translate('TagExisting'),
isSortable: true,
isVisible: true,
},
];
interface ManageImportListsModalContentProps {

View file

@ -5,6 +5,7 @@
.minimumAvailability,
.qualityProfileId,
.rootFolderPath,
.tagExisting,
.implementation {
composes: cell from '~Components/Table/Cells/TableRowCell.css';

View file

@ -8,6 +8,7 @@ interface CssExports {
'name': string;
'qualityProfileId': string;
'rootFolderPath': string;
'tagExisting': string;
'tags': string;
}
export const cssExports: CssExports;

View file

@ -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) {
<TableRowCell className={styles.tags}>
<MovieTagList tags={tags} />
</TableRowCell>
<TableRowCell className={styles.tagExisting}>
{tagExisting ? translate('Yes') : translate('No')}
</TableRowCell>
</TableRow>
);
}

View file

@ -15,6 +15,7 @@ interface ImportList extends Provider {
minRefreshInterval: string;
name: string;
tags: number[];
tagExisting: boolean;
}
export default ImportList;

View file

@ -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);
}
}

View file

@ -16,6 +16,7 @@ public class ImportListDefinition : ProviderDefinition, IEquatable<ImportListDef
public int QualityProfileId { get; set; }
public string RootFolderPath { get; set; }
public bool SearchOnAdd { get; set; }
public bool TagExisting { get; set; }
[MemberwiseEqualityIgnore]
public override bool Enable => Enabled;

View file

@ -76,18 +76,25 @@ private void SyncList(ImportListDefinition definition)
private void ProcessMovieReport(ImportListDefinition importList, ImportListMovie report, List<ImportListExclusion> listExclusions, List<int> dbMovies, List<Movie> 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 =>

View file

@ -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}",

View file

@ -11,6 +11,7 @@ public class ImportListBulkResource : ProviderBulkResource<ImportListBulkResourc
public string RootFolderPath { get; set; }
public int? QualityProfileId { get; set; }
public MovieStatusType? MinimumAvailability { get; set; }
public bool? TagExisting { get; set; }
}
public class ImportListBulkResourceMapper : ProviderBulkResourceMapper<ImportListBulkResource, ImportListDefinition>
@ -29,6 +30,7 @@ public override List<ImportListDefinition> 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;

View file

@ -16,6 +16,7 @@ public class ImportListResource : ProviderResource<ImportListResource>
public ImportListType ListType { get; set; }
public int ListOrder { get; set; }
public TimeSpan MinRefreshInterval { get; set; }
public bool TagExisting { get; set; }
}
public class ImportListResourceMapper : ProviderResourceMapper<ImportListResource, ImportListDefinition>
@ -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;
}

View file

@ -16,7 +16,6 @@ public class ProviderResource<T> : RestResource
public string InfoLink { get; set; }
public ProviderMessage Message { get; set; }
public HashSet<int> Tags { get; set; }
public List<T> Presets { get; set; }
}