Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

api recursion #267

Merged
merged 5 commits into from
Jan 15, 2025
Merged

api recursion #267

merged 5 commits into from
Jan 15, 2025

Conversation

damongolding
Copy link
Owner

@damongolding damongolding commented Jan 15, 2025

Summary by CodeRabbit

  • Improvements
    • Enhanced image retrieval process for albums with improved retry mechanism.
    • Added robust error handling for image asset retrieval, including specific error messages.
    • Introduced retry logic for retrieving random images from favourites, individuals, and memories.
    • Improved documentation for methods related to image retrieval, clarifying parameters and return values.
    • Updated functionality to accept "today" as a valid input for date ranges in image retrieval.

The changes focus on making the image retrieval process more reliable and informative, with better handling of potential retrieval failures across various functionalities.

@damongolding damongolding added the fix Fix for bug label Jan 15, 2025
Copy link
Contributor

coderabbitai bot commented Jan 15, 2025

Warning

There were issues while running some tools. Please review the errors and either fix the tool’s configuration or disable the tool if it’s a critical failure.

🔧 golangci-lint (1.62.2)

level=warning msg="[runner] Can't run linter goanalysis_metalinter: buildir: failed to load package : could not load export data: no export data for "github.com/damongolding/immich-kiosk/internal/templates/components/image""
level=error msg="Running error: can't run linter goanalysis_metalinter\nbuildir: failed to load package : could not load export data: no export data for "github.com/damongolding/immich-kiosk/internal/templates/components/image""

Walkthrough

The changes in the internal/immich package introduce several modifications to existing methods, implementing enhanced retry logic for image retrieval across functionalities such as albums, favourites, persons, and random images. Each method has been updated to include a retry mechanism that attempts to fetch images multiple times if the initial attempt fails. The documentation has been expanded for clarity, and error handling has been improved to provide specific feedback when no images are found after all retries.

Changes

File Change Summary
internal/immich/immich_album.go - Refactored ImageFromAlbum method to include retry mechanism and updated method signature
- Added new method AlbumImageCount
- Improved error handling and documentation
internal/immich/immich_favourites.go - Refactored RandomImageFromFavourites method to include retry mechanism
- Enhanced error handling and documentation
internal/immich/immich_person.go - Refactored RandomImageOfPerson method to include retry mechanism
- Improved error handling and documentation
internal/immich/immich_random.go - Refactored RandomImage method to include retry mechanism
- Updated documentation for clarity
internal/immich/immich_date.go - Merged logic of randomImageInDateRange into RandomImageInDateRange with added retry mechanism
- Enhanced documentation
internal/immich/immich_memories.go - Refactored RandomMemoryLaneImage method to include retry mechanism
- Updated documentation for clarity
internal/immich/immich_faces.go - Enhanced error handling in CheckForFaces method to prevent fatal termination of the application

Possibly related PRs

  • v0.15.0 #261: The changes in this PR include the addition of a new configuration option KIOSK_DATE, which allows users to specify multiple date ranges for image selection, directly related to the date handling in the main PR.
  • album ordering #265: This PR introduces new constants and a field for album ordering in the configuration, which may relate to how images are retrieved and displayed in the main PR's context of album image handling.
  • add memories asset bucket #266: The addition of a Memories field in the configuration enhances the handling of memory lane assets, which aligns with the main PR's focus on image retrieval and management from albums.

Suggested labels

enhancement

Poem

🐰 Hop, hop, through albums we go,
Retrying images with rabbit-like flow
When first try fails, we bounce right back
Persistence is our coding track!
Immich magic, retry with glee 🖼️

Finishing Touches

  • 📝 Generate Docstrings (Beta)

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@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: 0

🧹 Nitpick comments (4)
internal/immich/immich_album.go (4)

114-121: Consider enhancing the albumID parameter documentation.

The documentation could be more specific about the valid special keywords. Consider listing the supported keywords (AlbumKeywordAll, AlbumKeywordShared, AlbumKeywordFavourites, AlbumKeywordFavorites) in the documentation.


177-177: Consider using iteration instead of recursion for retries.

The current recursive approach for retries could potentially lead to stack overflow in edge cases. Consider refactoring to use a loop-based retry mechanism instead.

-func (i *ImmichAsset) imageFromAlbum(albumID string, albumAssetsOrder ImmichAssetOrder, requestID, deviceID string, isPrefetch bool, retries int) error {
+func (i *ImmichAsset) imageFromAlbum(albumID string, albumAssetsOrder ImmichAssetOrder, requestID, deviceID string, isPrefetch bool) error {
+    for retries := 0; retries < MaxRetries; retries++ {
         if retries >= MaxRetries {
             return fmt.Errorf("No images found for '%s'. Max retries reached.", albumID)
         }
         // ... existing logic ...
-        return i.imageFromAlbum(albumID, albumAssetsOrder, requestID, deviceID, isPrefetch, retries+1)
+        continue
+    }
+    return fmt.Errorf("No images found for '%s'. Max retries reached.", albumID)
 }

Also applies to: 225-226


Line range hint 169-169: Use structured logging consistently.

Replace string concatenation in log messages with structured logging for consistency and better log processing:

-log.Debug(requestID+" No images left in cache. Refreshing and trying again for album", albumID)
+log.Debug("No images left in cache. Refreshing and trying again", "requestID", requestID, "albumID", albumID)

-log.Debug(requestID + " No viable images left in cache. Refreshing and trying again")
+log.Debug("No viable images left in cache. Refreshing and trying again", "requestID", requestID)

Also applies to: 224-224


239-240: Consider wrapping the error with additional context.

When delegating to the internal method, consider wrapping the error with additional context about the operation:

-return i.imageFromAlbum(albumID, albumAssetsOrder, requestID, deviceID, isPrefetch, 0)
+if err := i.imageFromAlbum(albumID, albumAssetsOrder, requestID, deviceID, isPrefetch, 0); err != nil {
+    return fmt.Errorf("failed to fetch image from album %s: %w", albumID, err)
+}
+return nil
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8c27844 and 69ed573.

📒 Files selected for processing (1)
  • internal/immich/immich_album.go (4 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Analyze (typescript)
🔇 Additional comments (1)
internal/immich/immich_album.go (1)

157-159: Verify MaxRetries constant declaration.

The MaxRetries constant is used but not visible in the provided code. Ensure it's properly declared and documented.

✅ Verification successful

MaxRetries constant is properly declared but could benefit from documentation.

The constant is correctly declared in internal/immich/immich.go with a reasonable value of 3 retries. Consider adding a brief documentation comment to explain its purpose and usage context.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for MaxRetries constant declaration
rg -l "MaxRetries.*=.*\d+" 

Length of output: 54


Script:

#!/bin/bash
# View MaxRetries constant declaration with context
rg "MaxRetries.*=.*\d+" -B 2 -A 2 internal/immich/immich.go

Length of output: 139


Script:

#!/bin/bash
# View the complete const block with any preceding documentation
rg "const \(" -B 5 -A 10 internal/immich/immich.go

Length of output: 469

Copy link
Contributor

@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: 0

🧹 Nitpick comments (3)
internal/immich/immich_random.go (1)

26-28: Consider improving the error message format.

The error message could be more consistent with Go's error message style guide.

-		return fmt.Errorf("No images found for random. Max retries reached.")
+		return fmt.Errorf("no images found for random: max retries reached")
internal/immich/immich_favourites.go (2)

97-99: Align error message format with other files.

For consistency, the error message format should match the style used in other files.

-		return fmt.Errorf("No images found for favourites. Max retries reached.")
+		return fmt.Errorf("no images found for favourites: max retries reached")

Line range hint 182-182: Fix typo in comment.

There's a typo in the comment: "cwith" should be "with".

-			// replace cwith cache minus used image
+			// replace with cache minus used image
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 69ed573 and 3a130df.

📒 Files selected for processing (3)
  • internal/immich/immich_favourites.go (3 hunks)
  • internal/immich/immich_person.go (3 hunks)
  • internal/immich/immich_random.go (3 hunks)
🧰 Additional context used
📓 Learnings (1)
internal/immich/immich_person.go (1)
Learnt from: damongolding
PR: damongolding/immich-kiosk#252
File: internal/immich/immich_person.go:101-103
Timestamp: 2025-01-07T16:39:18.914Z
Learning: In immich-kiosk, the `RandomImageOfPerson` function is only called after validating that the person has images through `PersonImageCount` in `gatherAssetBuckets`, so it doesn't need retry limits for handling no-image scenarios. The recursive call is only used for cache refresh.
🔇 Additional comments (5)
internal/immich/immich_random.go (2)

14-19: LGTM! Well-documented public interface.

The public method is well-documented and correctly delegates to the internal implementation with initial retry count.


88-88: Verify retry increment logic.

The retry increment logic appears in two places. Whilst this is correct for the current implementation, we should ensure it's properly tested to avoid potential infinite loops.

Also applies to: 119-119

✅ Verification successful

Retry logic implementation is safe and consistent

The retry mechanism is properly implemented with a global MaxRetries = 3 limit, preventing infinite loops. The increment logic is consistently applied across all image retrieval functions with appropriate error handling.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for test cases covering retry scenarios
rg -l "test.*retry" --type go

Length of output: 31


Script:

#!/bin/bash
# Find the implementation of randomImage and surrounding context
ast-grep --pattern 'func $_ randomImage($$$) {
  $$$
}'

# Search for retry-related constants or variables
rg -i "max.*retries|retry.*limit" --type go

# Find all retry increment patterns
rg "retries\s*\+\s*1" --type go -A 3

Length of output: 4431

internal/immich/immich_person.go (2)

48-55: LGTM! Clear and consistent interface.

The public method follows the same pattern as other files, with clear documentation.


66-68: Consider if retry limits are necessary here.

Based on previous feedback, RandomImageOfPerson is only called after validating that the person has images through PersonImageCount. The retry logic might be unnecessary in this context.

internal/immich/immich_favourites.go (1)

83-95: LGTM! Excellent documentation.

The function documentation is comprehensive and well-structured, following Go's documentation conventions.

Copy link
Contributor

@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

♻️ Duplicate comments (1)
internal/immich/immich_person.go (1)

48-155: 🛠️ Refactor suggestion

Re-evaluate the necessity of the retry mechanism in RandomImageOfPerson

Previous learnings indicate that RandomImageOfPerson is called only after confirming the person has associated images via PersonImageCount. Introducing a retry loop may be redundant and could lead to unnecessary API calls. Consider simplifying the function by removing the retry mechanism and handling cache refresh differently.

As per retrieved learnings:

In immich-kiosk, the `RandomImageOfPerson` function is only called after validating that the person has images through `PersonImageCount` in `gatherAssetBuckets`, so it doesn't need retry limits for handling no-image scenarios. The recursive call is only used for cache refresh.
🧹 Nitpick comments (11)
internal/immich/immich_date.go (2)

75-166: Optimise error handling within the retry loop

In the retry loop, any error encountered (e.g., parsing URL, marshaling request body, API call failures) results in immediate termination of the function without further retries. Consider refining the error handling to retry on transient errors, such as network issues, while failing fast on non-recoverable errors. This will enhance the robustness of the function.


135-136: Simplify conditionals for image filtering

The conditional statement used for filtering images could be more readable by breaking it into multiple lines or adding explanatory comments. This will improve maintainability and clarity of the code.

Apply this diff to enhance readability:

-			if img.Type != ImageType || img.IsTrashed || (img.IsArchived && !requestConfig.ShowArchived) || !i.ratioCheck(&img) {
+			isInvalidType := img.Type != ImageType
+			isTrashed := img.IsTrashed
+			isArchived := img.IsArchived && !requestConfig.ShowArchived
+			isInvalidRatio := !i.ratioCheck(&img)
+			if isInvalidType || isTrashed || isArchived || isInvalidRatio {
internal/immich/immich_person.go (1)

99-100: Handle potential errors when marshalling request body

Using log.Fatal on marshalling errors will terminate the program. It's preferable to return the error to allow the calling function to handle it appropriately.

Apply this diff to return the error instead:

-			log.Fatal("marshaling request body", err)
+			return fmt.Errorf("marshalling request body: %w", err)
internal/immich/immich_favourites.go (4)

84-108: Consider documenting the MaxRetries constant value

The documentation thoroughly explains the retry mechanism but doesn't specify the actual number of retries. Consider adding this information to help users understand the timeout behaviour.


117-170: Consider handling cache deletion errors

The cache deletion operation on line 170 doesn't check for errors. While cache errors might not be critical, logging them could help with debugging cache-related issues.

-			cache.Delete(apiCacheKey)
+			if err := cache.Delete(apiCacheKey); err != nil {
+				log.Debug(requestID + " Failed to delete cache", "error", err)
+			}

174-197: Improve error handling in cache update section

The error handling for cache operations could be more informative. Consider adding context to the error message when marshalling fails.

-					log.Error("Failed to marshal immichAssetsToCache", "error", err)
+					log.Error("Failed to marshal immichAssetsToCache", 
+						"error", err,
+						"deviceID", deviceID,
+						"retryAttempt", retries)

200-204: Enhance error message with retry count

Consider including the number of retry attempts in the error message for better debugging context.

-	return fmt.Errorf("No images found for favourites. Max retries reached.")
+	return fmt.Errorf("No images found for favourites after %d attempts", MaxRetries)
internal/immich/immich_album.go (4)

Line range hint 114-153: Consider extracting error messages as constants

The error messages are well-formed but could be extracted as constants to maintain consistency and ease maintenance.

+const (
+	errGetAllAlbums     = "failed to get all albums: %w"
+	errGetSharedAlbums  = "failed to get shared albums: %w"
+	errGetFavorites     = "failed to get favorite images: %w"
+	errGetAlbumAssets   = "failed to get album assets for album %s: %w"
+)

 func (i *ImmichAsset) AlbumImageCount(albumID string, requestID, deviceID string) (int, error) {
 	switch albumID {
 	case kiosk.AlbumKeywordAll:
 		albums, _, err := i.allAlbums(requestID, deviceID)
 		if err != nil {
-			return 0, fmt.Errorf("failed to get all albums: %w", err)
+			return 0, fmt.Errorf(errGetAllAlbums, err)
 		}

154-167: Add example usage to documentation

Consider adding an example usage section to the documentation to demonstrate typical use cases and parameter values.


170-188: Enhance log message with retry attempt count

Consider adding the retry attempt count to the log message for better debugging context.

-			log.Debug(requestID+" No images left in cache. Refreshing and trying again for album", albumID)
+			log.Debug(requestID+" No images left in cache. Refreshing and trying again for album", 
+				"albumID", albumID,
+				"retryAttempt", retries + 1,
+				"maxRetries", MaxRetries)

209-238: Maintain consistency with favourites implementation

Consider applying the same error handling improvements suggested for the favourites implementation:

  1. Add context to cache operation errors
  2. Include retry count in the final error message
-	return fmt.Errorf("No images found for '%s'. Max retries reached.", albumID)
+	return fmt.Errorf("No images found for album '%s' after %d attempts", albumID, MaxRetries)
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3a130df and 2caec9f.

📒 Files selected for processing (6)
  • internal/immich/immich_album.go (2 hunks)
  • internal/immich/immich_date.go (2 hunks)
  • internal/immich/immich_favourites.go (2 hunks)
  • internal/immich/immich_memories.go (1 hunks)
  • internal/immich/immich_person.go (1 hunks)
  • internal/immich/immich_random.go (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • internal/immich/immich_random.go
🧰 Additional context used
📓 Learnings (1)
internal/immich/immich_person.go (1)
Learnt from: damongolding
PR: damongolding/immich-kiosk#252
File: internal/immich/immich_person.go:101-103
Timestamp: 2025-01-07T16:39:18.914Z
Learning: In immich-kiosk, the `RandomImageOfPerson` function is only called after validating that the person has images through `PersonImageCount` in `gatherAssetBuckets`, so it doesn't need retry limits for handling no-image scenarios. The recursive call is only used for cache refresh.
🔇 Additional comments (1)
internal/immich/immich_memories.go (1)

77-152: Function improvements accepted

The refactoring of RandomMemoryLaneImage enhances readability and simplifies the control flow by replacing recursion with a loop for retries. The caching logic and error handling are well-maintained.

internal/immich/immich_date.go Show resolved Hide resolved
@damongolding damongolding changed the title album recursion api recursion Jan 15, 2025
Copy link
Contributor

@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: 0

🧹 Nitpick comments (6)
internal/immich/immich_album.go (3)

170-175: Consider extracting MaxRetries to a configuration

The retry mechanism is well-implemented, but the MaxRetries constant could be moved to the configuration to allow for runtime adjustments.


180-181: Consider using constants for debug messages

Debug messages are duplicated and could benefit from being defined as constants to maintain consistency and ease maintenance.

+const (
+    msgNoImagesInCache = "No images left in cache. Refreshing and trying again for album"
+    msgNoViableImages  = "No viable images left in cache. Refreshing and trying again"
+)

Also applies to: 240-241


215-230: Improve cache error handling

The cache error handling could be more robust. Consider implementing a retry mechanism for cache updates or degrading gracefully when cache operations fail.

 if requestConfig.Kiosk.Cache {
     // Remove the current image from the slice
     assetsToCache := album
     assetsToCache.Assets = append(album.Assets[:assetIndex], album.Assets[assetIndex+1:]...)
     jsonBytes, err := json.Marshal(assetsToCache)
     if err != nil {
-        log.Error("Failed to marshal assetsToCache", "error", err)
-        return err
+        log.Error("Failed to marshal assetsToCache, continuing without cache update", "error", err)
+        return nil
     }

     // replace with cache minus used asset
     err = cache.Replace(apiCacheKey, jsonBytes)
     if err != nil {
-        log.Debug("Failed to update device cache for album", "albumID", albumID, "deviceID", deviceID)
+        log.Error("Failed to update device cache", 
+            "albumID", albumID, 
+            "deviceID", deviceID,
+            "error", err,
+        )
     }
 }
internal/immich/immich_date.go (2)

75-82: Consider extracting URL parsing to a helper function.

This URL parsing logic is repeated across multiple methods. Consider extracting it to a shared helper function to reduce code duplication.

+func (i *ImmichAsset) parseImmichURL() (*url.URL, error) {
+    return url.Parse(requestConfig.ImmichUrl)
+}

127-129: Cache refresh could be more efficient.

Consider implementing a bulk refresh mechanism instead of deleting and refetching immediately. This could reduce API load during high-traffic periods.

internal/immich/immich_favourites.go (1)

199-201: Enhance debug logging for cache operations.

The current debug message "cache not found!" is not very informative. Consider including more context about the cache operation and the specific key that wasn't found.

-log.Debug("cache not found!")
+log.Debug("Failed to replace cache entry", "key", apiCacheKey, "error", err)
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2caec9f and 176540d.

📒 Files selected for processing (7)
  • internal/immich/immich_album.go (4 hunks)
  • internal/immich/immich_date.go (2 hunks)
  • internal/immich/immich_faces.go (1 hunks)
  • internal/immich/immich_favourites.go (4 hunks)
  • internal/immich/immich_memories.go (2 hunks)
  • internal/immich/immich_person.go (2 hunks)
  • internal/immich/immich_random.go (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • internal/immich/immich_memories.go
  • internal/immich/immich_random.go
🧰 Additional context used
📓 Learnings (1)
internal/immich/immich_person.go (1)
Learnt from: damongolding
PR: damongolding/immich-kiosk#252
File: internal/immich/immich_person.go:101-103
Timestamp: 2025-01-07T16:39:18.914Z
Learning: In immich-kiosk, the `RandomImageOfPerson` function is only called after validating that the person has images through `PersonImageCount` in `gatherAssetBuckets`, so it doesn't need retry limits for handling no-image scenarios. The recursive call is only used for cache refresh.
🔇 Additional comments (8)
internal/immich/immich_album.go (4)

24-24: Consistent error handling implementation looks good!

The use of immichApiFail helper function provides a uniform approach to handling API failures.

Also applies to: 76-76


Line range hint 114-153: Well-structured implementation with comprehensive error handling!

The function effectively handles different album types with proper error wrapping and clear error messages. The documentation is thorough and follows good practices.


191-202: Well-implemented ordering logic!

The implementation efficiently handles both random and ascending order using the standard library's slices package. The AssetsOrdered flag prevents unnecessary reordering.


203-214: Clear and efficient validation logic!

The asset validation criteria are well-structured and clearly documented. The use of descriptive boolean variables makes the code self-documenting.

internal/immich/immich_faces.go (1)

16-18: Improved error handling approach!

The changes enhance robustness by replacing fatal error handling with proper error logging and propagation.

internal/immich/immich_date.go (1)

16-30: Well-documented function with clear explanations!

The comprehensive documentation clearly explains the function's purpose, parameters, and behaviour.

internal/immich/immich_person.go (1)

67-75: Retry mechanism may be unnecessary here.

Based on previous discussions, RandomImageOfPerson is only called after validating that the person has images through PersonImageCount. Consider simplifying this implementation since the retry logic might be redundant.

internal/immich/immich_favourites.go (1)

86-111: Excellent documentation with clear examples!

The documentation thoroughly explains the function's behaviour, retry mechanism, and filtering criteria.

@damongolding damongolding merged commit b4a54d1 into main Jan 15, 2025
6 checks passed
@damongolding damongolding deleted the fix/album-recursion branch January 15, 2025 17:05
@damongolding damongolding restored the fix/album-recursion branch January 16, 2025 09:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
fix Fix for bug
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant