Skip to content

Prevent delete_collections from removing localized configured collections - #3532

Open
antwanchild wants to merge 5 commits into
Kometa-Team:nightlyfrom
antwanchild:fix/localized-delete-collections
Open

Prevent delete_collections from removing localized configured collections#3532
antwanchild wants to merge 5 commits into
Kometa-Team:nightlyfrom
antwanchild:fix/localized-delete-collections

Conversation

@antwanchild

@antwanchild antwanchild commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

What type of PR is this?

  • Bug Fix (non-breaking change which fixes an issue)
  • Feature/Tweak (non-breaking change which adds new functionality or enhances existing functionality)
  • Breaking Change (fix or feature that would break any existing functionality for users)
  • Documentation Update
  • Chore (maintenance, dependency bumps, housekeeping - no functional change)
  • Other

Description

This PR prevents delete_collections from deleting configured collections whose current Plex titles are localized or produced by a custom name override when operations run before collections.

The fix is not specific to French. It reads the selected language from each collection file or collection-level override, validates it against Kometa's supported translation keys, and resolves that language dynamically. If a particular collection has no name in the selected translation, its English name remains a safe fallback.

With configured: false, managed: true, and language: fr, the supplied reproduction compared a French Plex title such as Collections Classement only against the English mapping name Chart Collections. The title was classified as unconfigured, deleted, and recreated later in the same run.

When delete_collections.configured is set, the configured-name precheck expands the collection's name-related template attributes without constructing a collection or calling Plex. It treats every supported representation as an alias for the same configured collection. The original if configured is not None: guard remains in place, so reporting, asset-only, and other collection operations do not trigger template or translation resolution.

Observed impact

The supplied 28,545-line debug log showed 54 configured collections deleted and recreated: 30 movie collections and 24 show collections.

Configured/mapping name Existing Plex/final name Previous result New result
Chart Collections Collections Classement Deleted and recreated Retained
TMDb Popular 🌍 Films populaires dans le monde Deleted and recreated Retained
Streaming Collections Collections Diffusion Deleted and recreated Retained
Apple TV Movies Films de Apple TV Deleted and recreated Retained
Genre Collections Collections Genre Deleted and recreated Retained
Action Movies Action Films Deleted and recreated Retained

Every unique deleted title in the log subsequently appeared as a collection's resolved final name.

Configured-name aliases

Name source Example Purpose
YAML mapping name Chart Collections Preserves the existing configured-name behavior
Explicit/custom name 🌍 Films populaires dans le monde Protects name_*, name_format, and direct name overrides
English translation Chart Collections Preserves migration compatibility and provides translation fallback
Selected-language translation Collections Classement Protects localized Plex titles in any supported language
Localized template variables Localized key name, library type, and limit Matches the substitutions used to produce final collection names

The resolver works on a deep copy of collection data, so the deletion precheck does not mutate the definition that will later be used by CollectionBuilder. A failure resolving one collection is isolated to that collection and logged at debug level.

Language coverage

Scenario Coverage
File-level selected language Dynamically resolves any key in translation_keys
Collection-level language override Overrides the file language
Missing collection name in selected translation Retains the English alias
Latin-script examples French, German, and Spanish passed
Non-Latin-script example Japanese passed

Validation

Check Result
Full pytest suite 1,488 passed
Focused operations suite 73 passed
Cross-language matrix French, German, Spanish, and Japanese passed
Collection-level language override Passed
Missing-translation English fallback Passed
configured is not None resolution guard Preserved
Zero-valued limit substitution Passed
Custom name override regression Passed
Generated dynamic collection regression Passed
Mapping-name fallback regression Passed
Black Passed
isort Passed
flake8 Passed
git diff --check Passed
pyspelling Not run locally because aspell is unavailable

Related Issues [optional]

Have you updated the Documentation to reflect changes (if necessary)?

  • Yes
  • No
  • Not Applicable

This corrects internal configured-name matching; no configuration attributes or user workflows changed.

Have you updated the JSON Schema files (if necessary)?

  • Yes
  • No
  • Not Applicable

No supported attributes, accepted values, or configuration structures changed.

Have you updated the CHANGELOG.md?

  • Yes
  • No

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes a delete_collections false-positive deletion scenario when library operations run before collections: configured collections whose current Plex titles are localized (or come from custom name overrides/template expansion) are now recognized as configured and retained.

Changes:

  • Added configured-collection name alias resolution that accounts for mapping names, explicit/custom names, English translations, and selected-language translations (including template-variable substitution).
  • Updated delete_collections configured-name precheck to use the expanded alias set per collection file entry.
  • Added focused unit tests for multi-language alias resolution behavior and updated the changelog.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
modules/operations.py Adds name-alias resolution helpers and uses them to prevent deleting localized/custom-titled configured collections before the collection builder runs.
tests/test_operations.py Adds test coverage for alias resolution across languages, custom overrides, and dynamic collection data.
CHANGELOG.md Documents the bug fix under Fixed.
Suppressed comments (1)

modules/operations.py:127

  • limit is treated as falsy, so a valid limit: 0 (or any falsy numeric limit) would be dropped and <<limit>> would not be substituted. This can break configured-name alias matching for templates that include <<limit>>.
    translation_key = str(data[methods["translation_key"]]) if "translation_key" in methods and data[methods["translation_key"]] else None
    key_name = str(data[methods["key_name"]]) if "key_name" in methods and data[methods["key_name"]] else None
    limit = data[methods["limit"]] if "limit" in methods and data[methods["limit"]] else None
    translation_prefix = str(data[methods["translation_prefix"]]) if "translation_prefix" in methods and data[methods["translation_prefix"]] else ""

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread modules/operations.py Outdated
Comment thread modules/operations.py Outdated

@badja-dev badja-dev left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Close to mergeable. The fix correctly generalises the earlier English-only translation workaround (#3168) into a full alias resolver that mirrors CollectionBuilder's real template/language resolution logic (confirmed against modules/builder.py's own template and language handling), it's well covered by new tests, and CI is fully green

The new alias resolution now runs unconditionally whenever any collection operation is enabled, not just when delete_collections.configured is actually in use, which is a behavior change beyond what the PR describes. One minor cleanup item (dead code) is not blocking

Comment thread modules/operations.py
@antwanchild
antwanchild force-pushed the fix/localized-delete-collections branch from dbb02c1 to d31592b Compare September 2, 2026 04:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants