Skip to content

Conversation

@nopoz
Copy link

@nopoz nopoz commented Jan 16, 2026

Summary

Adds a new ExcludedPeople setting that allows users to exclude specific Immich people IDs from the slideshow when using the People filter. This mirrors the existing ExcludedAlbums functionality.

Use Case

When displaying photos of specific people (e.g., family members), users may want to exclude photos that also contain certain other people. For example:

  • Show photos of [bob, suzy]
  • But exclude any photos that also contain [bertha, joe]

Changes

Core Implementation

  • ImmichFrame.Core/Interfaces/IServerSettings.cs - Added ExcludedPeople property to IAccountSettings interface
  • ImmichFrame.WebApi/Models/ServerSettings.cs - Added ExcludedPeople property to ServerAccountSettings
  • ImmichFrame.WebApi/Helpers/Config/ServerSettingsV1.cs - Added V1 backward compatibility support
  • ImmichFrame.Core/Logic/Pool/PeopleAssetsPool.cs - Implemented exclusion logic following the AlbumAssetsPool pattern:
    1. Fetch all assets for people in ExcludedPeople
    2. Fetch all assets for people in People
    3. Filter out excluded assets using WhereExcludes()

Test Updates

  • ImmichFrame.Core.Tests/Logic/Pool/PersonAssetsPoolTests.cs - Added mock for ExcludedPeople
  • ImmichFrame.WebApi.Tests/Resources/TestV2.json - Added ExcludedPeople test data
  • ImmichFrame.WebApi.Tests/Resources/TestV2.yml - Added ExcludedPeople test data

Documentation/Examples

  • docker/Settings.example.json - Added ExcludedPeople example
  • docker/Settings.example.yml - Added ExcludedPeople example
  • docker/example.env - Added ExcludedPeople environment variable

Example Configuration

Accounts:
  - ImmichServerUrl: http://your-server:2283
    ApiKey: "your-api-key"
    People:
      - "00000000-0000-0000-0000-000000000001" # person to include
      - "00000000-0000-0000-0000-000000000002" # person to include
    ExcludedPeople:
      - "00000000-0000-0000-0000-000000000003" # person to exclude
      - "00000000-0000-0000-0000-000000000004" # person to exclude

How It Works

The filtering happens at load time in PersonAssetsPool.LoadAssets():
1. Assets for all ExcludedPeople are fetched first
2. Assets for all People are fetched
3. Any asset appearing in both sets is removed from the final result
4. Results are cached and fed into the prefetch queue

This means if a photo contains both an included person AND an excluded person, that photo will not be displayed.

Test Plan

- All existing tests pass
- Docker build succeeds
- Manual testing with real Immich server

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

* **New Features**
* Per-account ExcludedPeople list to prevent specific people’s assets from being processed or shown.
* Exclusions are honored during asset loading and post-processing.

* **Configuration**
* ExcludedPeople supported in JSON, YAML, and environment configuration examples.

* **Tests**
* Test data and test setup updated to cover the new people exclusion behavior.

<sub>✏️ Tip: You can customize this high-level summary in your review settings.</sub>
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

@coderabbitai
Copy link

coderabbitai bot commented Jan 16, 2026

📝 Walkthrough

Walkthrough

Adds an ExcludedPeople list across settings, test fixtures, and config samples, and updates PeopleAssetsPool to load excluded people’s assets and filter them out from the final asset set returned by LoadAssets.

Changes

Cohort / File(s) Summary
Core interface & pool logic
ImmichFrame.Core/Interfaces/IServerSettings.cs, ImmichFrame.Core/Logic/Pool/PeopleAssetsPool.cs
Added ExcludedPeople property to account settings interface usage. Refactored PeopleAssetsPool: extracted LoadAssetsForPerson helper, load assets for both included and excluded people, then filter out excluded assets via WhereExcludes on asset Id.
Web API models & adapters
ImmichFrame.WebApi/Models/ServerSettings.cs, ImmichFrame.WebApi/Helpers/Config/ServerSettingsV1.cs
Added ExcludedPeople (List) to ServerAccountSettings and ServerSettingsV1; exposed via AccountSettingsV1Adapter getter; default-initialized to an empty list.
Tests & test resources
ImmichFrame.Core.Tests/Logic/Pool/PersonAssetsPoolTests.cs, ImmichFrame.WebApi.Tests/Resources/TestV2.json, ImmichFrame.WebApi.Tests/Resources/TestV2.yml
Test setup and fixtures updated to initialize ExcludedPeople arrays (matching sample GUIDs) to ensure tests run with the new field present.
Config examples
docker/Settings.example.json, docker/Settings.example.yml, docker/example.env
Added ExcludedPeople entries to example JSON/YAML and an ExcludedPeople environment variable example to demonstrate configuration usage.

Sequence Diagram

sequenceDiagram
    participant Client
    participant Pool as PeopleAssetsPool
    participant Helper as LoadAssetsForPerson
    participant API as AssetAPI

    Client->>Pool: LoadAssets(accountSettings, filter)
    Note over Pool: Iterate accountSettings.People
    loop included people
        Pool->>Helper: LoadAssetsForPerson(personId, ct)
        Helper->>API: Fetch IMAGE assets (paged) with Exif & People
        API-->>Helper: Page of assets
        Helper-->>Pool: Accumulate assets
    end
    Note over Pool: Iterate accountSettings.ExcludedPeople
    loop excluded people
        Pool->>Helper: LoadAssetsForPerson(excludedPersonId, ct)
        Helper->>API: Fetch IMAGE assets (paged) with Exif & People
        API-->>Helper: Page of assets
        Helper-->>Pool: Accumulate excluded assets
    end
    Note over Pool: Filter out excludedPersonAssets by Id (WhereExcludes)
    Pool-->>Client: Return filtered assets
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I hop through lists both old and new,
I fetch each face and shuffle through,
Excluded names I gently skip,
Clean pools restored with carrot-zip,
A tiny hop, a joyful view!

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title accurately and specifically describes the main change: adding an ExcludedPeople setting to filter out specific people from results, which is the core objective across all modified files.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@ImmichFrame.Core/Logic/Pool/PeopleAssetsPool.cs`:
- Around line 49-53: In PeopleAssetsPool (file PeopleAssetsPool.cs) the
pagination uses while (total == batchSize) but should loop while the current
page returned a full batch; change the loop condition to check the returned item
count (e.g., personInfo.Assets.Items.Count == batchSize or lastPageCount ==
batchSize) and remove the unused total variable; ensure you continue
incrementing page and adding personInfo.Assets.Items to assets until a page
returns fewer than batchSize items.
🧹 Nitpick comments (1)
ImmichFrame.Core.Tests/Logic/Pool/PersonAssetsPoolTests.cs (1)

42-42: Consider adding tests for the exclusion behavior.

The mock setup for ExcludedPeople is correct and mirrors the AlbumAssetsPoolTests pattern. However, there are no tests verifying that assets from excluded people are actually filtered out from the results.

Consider adding test cases similar to AlbumAssetsPoolTests.LoadAssets_NoIncludedAlbums_ReturnsEmpty (see relevant snippet at lines 73-84) to verify:

  1. Assets belonging to excluded people are removed from results
  2. Assets appearing in both included and excluded people are omitted

@3rob3
Copy link
Collaborator

3rob3 commented Jan 17, 2026

I'm surprised this was so simple. It has been awhile since I attempted this, but I thought there was an Immich API issue where something (albums maybe?) didn't include person info?

@3rob3 3rob3 added the enhancement New feature or request label Jan 17, 2026
@JW-CH JW-CH self-requested a review January 17, 2026 21:52
@nopoz
Copy link
Author

nopoz commented Jan 17, 2026

I'm surprised this was so simple. It has been awhile since I attempted this, but I thought there was an Immich API issue where something (albums maybe?) didn't include person info?

You're right, there is a limitation with the Album results.

The Issue with Albums on the Immich side:

  1. getAlbumInfo has no withPeople parameter - it only accepts id, key, and withoutAssets (lines 940-966 in the OpenAPI spec)
  2. people is NOT a required field in AssetResponseDto - Looking at the OpenAPI spec (line 9299-9319), the required fields are: checksum, deviceAssetId, deviceId, duration, fileCreatedAt, etc. The people field (line 9245-9250) is optional.
  3. Other endpoints have withPeople - The searchMetadata and searchRandom endpoints have WithPeople = true parameters, which is why they can request people data. Album fetching doesn't have this option.

The implication: When you call GetAlbumInfoAsync, the assets returned may have People = null because Immich doesn't guarantee that field is populated without explicit request.

To clarify the intent of this PR, the ExcludedPeople feature only filters out specific people from the People results because of the above limitations.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants