Skip to content

Conversation

@masterwishx
Copy link
Owner

@masterwishx masterwishx commented Nov 27, 2025

Signed-off-by: DaRK AnGeL [email protected]

Summary by CodeRabbit

  • New Features

    • Added UI option to move empty folders (Yes/No) with Top Folder support; default set to yes. Automatic cleanup of moved empty folders when enabled.
  • Bug Fixes

    • Fixed test-mode comparison handling.
    • Improved logging: remaining files and remaining folders reported separately across cache, array, and unattended moves.
  • Style/UX

    • Simplified form markup, adjusted control styling and inputs, added informational icons and clearer option text.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Nov 27, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Adds a new moveEmptyFolders option (default "yes") to defaults and UI; uses it to include/exclude empty directories from find filters; fixes TESTMODE string comparisons; adds conditional rmdir cleanup for moved empty folders; and separates remaining-item counters/logs into files vs folders.

Changes

Cohort / File(s) Summary
Core mover script
source/ca.mover.tuning/usr/local/emhttp/plugins/ca.mover.tuning/age_mover
Add moveEmptyFolders default handling and persistence in getMoverSettings; adjust createFilteredFilelist to include/exclude empty dirs based on setting; quote TESTMODE comparisons; add conditional post-move rmdir cleanup for moved empty folders; introduce per-type (files vs folders) remaining counters/logs; add LAST_FOLDER_COUNT variable.
Mover UI
source/ca.mover.tuning/usr/local/emhttp/plugins/ca.mover.tuning/Mover.tuning.page
Add moveEmptyFolders UI control and explanatory captions; extend cleanFolders to include Top Folder; simplify select/input markup, add info icons, and adjust help-text visibility/display logic.
Share UI (markup/styling)
source/ca.mover.tuning/usr/local/emhttp/plugins/ca.mover.tuning/Share.tuning.page
Remove narrow CSS class from multiple <select>s, add missing </select> closings, and improve htmlspecialchars usage for file input rendering — styling/markup-only changes.
Defaults
source/ca.mover.tuning/usr/local/emhttp/plugins/ca.mover.tuning/default.cfg
Add moveEmptyFolders="yes" default property.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20–30 minutes

  • Review getMoverSettings: defaulting to "yes", config persistence, and logging.
  • Validate createFilteredFilelist: correctness of generated find filters for include vs exclude empty directories.
  • Inspect processTheMoves: quoted TESTMODE comparisons, dry-run safety around rmdir, correctness of conditionals for ACTION/FILETYPE/MOVE_EMPTY_FOLDERS, and per-type remaining counters/logging updates across branches.
  • Confirm UI wiring: new moveEmptyFolders control binds to config and cleanFolders Top Folder option is handled.

Files/areas needing extra attention:

  • age_mover — ensure rmdir only removes truly empty moved folders and counters remain consistent across branches.
  • Mover.tuning.page — verify UI state toggles and persistence of the new option.
  • default.cfg — ensure default aligns with UI and script semantics.

Possibly related PRs

  • dev-new-fixes-10 #66 — modifies the same age_mover functions and UI options; likely overlaps in config initialization and processTheMoves changes.
  • Dev-new-fixes-20 #99 — addresses empty-folder move/filter logic and per-type handling in age_mover; directly related to moveEmptyFolders behavior.
  • small fix #61 — updates getMoverSettings and createFilteredFilelist; intersects with this PR's filtering and defaulting changes.

Poem

🐇 I hopped through folders, light on my paws,

Moving empties when asked, following new laws.
I count files and folders, tidy each space,
A careful rmdir clears the trace.
Happy logs, neat in their place.

Pre-merge checks and finishing touches

❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Title check ❓ Inconclusive The title 'Dev-new-fixes-21' is vague and generic, using only a branch name without conveying meaningful information about the actual changes. Replace with a descriptive title that summarizes the main changes, such as 'Add moveEmptyFolders option and improve folder logging in age_mover' or similar that reflects the primary functionality added.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch dev-new-fixes-21

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.

@gemini-code-assist
Copy link

Summary of Changes

Hello @masterwishx, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request refines the age_mover script by addressing a minor variable comparison bug and introducing a significant feature for automatic cleanup of empty directories post-move. Additionally, it enhances the clarity of progress reporting during file and folder transfers, making the script more robust and user-friendly.

Highlights

  • Variable Expansion Fix: Corrected the usage of the $TESTMODE variable in a conditional statement to ensure proper string comparison, preventing potential issues in script execution.
  • Empty Folder Cleanup: Implemented new functionality to automatically detect and delete empty directories after files have been successfully moved. This includes checks for .placeholder files and existing subdirectories, with appropriate logging for both live and test modes.
  • Enhanced Progress Logging: Improved the logging messages for remaining items during various move operations (e.g., 'unattended to secondary', 'caches to array') to clearly distinguish between files and folders, providing more precise status updates.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces several fixes and enhancements to the age_mover script. The changes include correctly quoting a variable in a test condition, adding functionality to clean up empty directories after they are moved, and improving log messages to differentiate between files and folders.

While the intent of the changes is good, I've found a few issues:

  • There is a critical bug in the new logic for cleaning empty directories that will cause the script to fail with an error.
  • The enhanced logging has introduced code duplication in a couple of places, which impacts maintainability.

I have provided detailed comments with code suggestions to address these issues. Please review them.

Comment on lines 1884 to 1901
if [ -e "${DIR}/.placeholder" ]; then
file_count=".placeholder"
else
file_count=$(find "$DIR" -type f | wc -l)
fi
# Count subdirectories
dir_count=$(find "$DIR" -mindepth 1 -type d | wc -l)

if [ "$file_count" -eq 0 ] && [ "$dir_count" -eq 0 ] && [ "$file_count" != ".placeholder" ]; then
if [ "$TESTMODE" = "no" ]; then
mvlogger "Deleting moved empty folder: ${DIR}"
rmdir "$DIR"
else
mvlogger "TEST MODE: Would delete moved empty folder: ${DIR}"
fi
else
mvlogger "Not deleting folder: contains $file_count file(s), $dir_count subfolder(s): $DIR"
fi

Choose a reason for hiding this comment

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

critical

The logic for handling .placeholder files is buggy and will cause the script to fail. When a .placeholder file is found, file_count is set to the string ".placeholder". The subsequent condition [ "$file_count" -eq 0 ] then attempts an arithmetic comparison on a string, which results in an integer expression expected error. The logic should be refactored to correctly handle the .placeholder case separately to avoid this runtime error.

Suggested change
if [ -e "${DIR}/.placeholder" ]; then
file_count=".placeholder"
else
file_count=$(find "$DIR" -type f | wc -l)
fi
# Count subdirectories
dir_count=$(find "$DIR" -mindepth 1 -type d | wc -l)
if [ "$file_count" -eq 0 ] && [ "$dir_count" -eq 0 ] && [ "$file_count" != ".placeholder" ]; then
if [ "$TESTMODE" = "no" ]; then
mvlogger "Deleting moved empty folder: ${DIR}"
rmdir "$DIR"
else
mvlogger "TEST MODE: Would delete moved empty folder: ${DIR}"
fi
else
mvlogger "Not deleting folder: contains $file_count file(s), $dir_count subfolder(s): $DIR"
fi
if [ -e "${DIR}/.placeholder" ]; then
mvlogger "Not deleting folder: contains .placeholder file: $DIR"
else
file_count=$(find "$DIR" -type f | wc -l)
# Count subdirectories
dir_count=$(find "$DIR" -mindepth 1 -type d | wc -l)
if [ "$file_count" -eq 0 ] && [ "$dir_count" -eq 0 ]; then
if [ "$TESTMODE" = "no" ]; then
mvlogger "Deleting moved empty folder: ${DIR}"
rmdir "$DIR"
else
mvlogger "TEST MODE: Would delete moved empty folder: ${DIR}"
fi
else
mvlogger "Not deleting folder: contains $file_count file(s), $dir_count subfolder(s): $DIR"
fi
fi

Comment on lines 1915 to 1929
if [[ "$ACTION" =~ "unattended to secondary" ]]; then
mvlogger "$REMAINING_UNATTENDED_FILES files remaining from unattended to secondary ($(bytes_to_human "$REMAINING_UNATTENDED_SIZE"))"
# Check if there are any files or folders left
if [[ "$FILETYPE" = "f" ]]; then
mvlogger "$REMAINING_UNATTENDED_FILES files remaining from unattended to secondary ($(bytes_to_human "$REMAINING_UNATTENDED_SIZE"))"
else
mvlogger "$REMAINING_UNATTENDED_FOLDERS folders remaining from unattended to secondary"
fi
elif [[ "$ACTION" =~ "unattended to primary" ]]; then
mvlogger "$REMAINING_UNATTENDED_FILES files remaining from unattended to primary ($(bytes_to_human "$REMAINING_UNATTENDED_SIZE"))"
# Check if there are any files or folders left
if [[ "$FILETYPE" = "f" ]]; then
mvlogger "$REMAINING_UNATTENDED_FILES files remaining from unattended to primary ($(bytes_to_human "$REMAINING_UNATTENDED_SIZE"))"
else
mvlogger "$REMAINING_UNATTENDED_FOLDERS folders remaining from unattended to primary"
fi
fi

Choose a reason for hiding this comment

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

medium

This block of code contains duplicated logic for logging messages based on FILETYPE. This can be simplified by extracting the common parts and using a variable for the differing part (primary vs secondary), which improves maintainability and readability.

Suggested change
if [[ "$ACTION" =~ "unattended to secondary" ]]; then
mvlogger "$REMAINING_UNATTENDED_FILES files remaining from unattended to secondary ($(bytes_to_human "$REMAINING_UNATTENDED_SIZE"))"
# Check if there are any files or folders left
if [[ "$FILETYPE" = "f" ]]; then
mvlogger "$REMAINING_UNATTENDED_FILES files remaining from unattended to secondary ($(bytes_to_human "$REMAINING_UNATTENDED_SIZE"))"
else
mvlogger "$REMAINING_UNATTENDED_FOLDERS folders remaining from unattended to secondary"
fi
elif [[ "$ACTION" =~ "unattended to primary" ]]; then
mvlogger "$REMAINING_UNATTENDED_FILES files remaining from unattended to primary ($(bytes_to_human "$REMAINING_UNATTENDED_SIZE"))"
# Check if there are any files or folders left
if [[ "$FILETYPE" = "f" ]]; then
mvlogger "$REMAINING_UNATTENDED_FILES files remaining from unattended to primary ($(bytes_to_human "$REMAINING_UNATTENDED_SIZE"))"
else
mvlogger "$REMAINING_UNATTENDED_FOLDERS folders remaining from unattended to primary"
fi
fi
local direction
if [[ "$ACTION" =~ "unattended to secondary" ]]; then
direction="secondary"
elif [[ "$ACTION" =~ "unattended to primary" ]]; then
direction="primary"
fi
if [[ -n "$direction" ]]; then
# Check if there are any files or folders left
if [[ "$FILETYPE" = "f" ]]; then
mvlogger "$REMAINING_UNATTENDED_FILES files remaining from unattended to $direction ($(bytes_to_human "$REMAINING_UNATTENDED_SIZE"))"
else
mvlogger "$REMAINING_UNATTENDED_FOLDERS folders remaining from unattended to $direction"
fi
fi

Comment on lines 1931 to 1951
if [[ "$SOURCE" =~ $PRIMARYSTORAGENAME ]]; then
REMAINING_CACHE_SIZE=$((REMAINING_CACHE_SIZE - FILESIZE))
# Check if there are any files or folders left
if [[ "$FILETYPE" = "f" ]]; then
REMAINING_CACHE_FILES=$((REMAINING_CACHE_FILES - NBLINKS))
mvlogger "$REMAINING_CACHE_FILES files remaining from caches to array ($(bytes_to_human "$REMAINING_CACHE_SIZE"))"
else
REMAINING_CACHE_FOLDERS=$((REMAINING_CACHE_FOLDERS - 1))
mvlogger "$REMAINING_CACHE_FOLDERS folders remaining from caches to array"
fi
mvlogger "$REMAINING_CACHE_FILES files remaining from caches to array ($(bytes_to_human "$REMAINING_CACHE_SIZE"))"
else
REMAINING_ARRAY_SIZE=$((REMAINING_ARRAY_SIZE - FILESIZE))
# Check if there are any files or folders left
if [[ "$FILETYPE" = "f" ]]; then
REMAINING_ARRAY_FILES=$((REMAINING_ARRAY_FILES - NBLINKS))
mvlogger "$REMAINING_ARRAY_FILES files remaining from array to caches ($(bytes_to_human "$REMAINING_ARRAY_SIZE"))"
else
REMAINING_ARRAY_FOLDERS=$((REMAINING_ARRAY_FOLDERS - 1))
mvlogger "$REMAINING_ARRAY_FOLDERS folders remaining from array to caches"
fi
mvlogger "$REMAINING_ARRAY_FILES files remaining from array to caches ($(bytes_to_human "$REMAINING_ARRAY_SIZE"))"
fi

Choose a reason for hiding this comment

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

medium

There is significant code duplication in this if/else block. The logic for decrementing counters and logging is repeated for both cache-to-array and array-to-cache movements. This can be refactored by using local variables to hold the context-specific values and then having a single block for logging. This will make the code more concise and easier to maintain.

                local log_msg
                if [[ "$SOURCE" =~ $PRIMARYSTORAGENAME ]]; then
                    REMAINING_CACHE_SIZE=$((REMAINING_CACHE_SIZE - FILESIZE))
                    # Check if there are any files or folders left
                    if [[ "$FILETYPE" = "f" ]]; then
                        REMAINING_CACHE_FILES=$((REMAINING_CACHE_FILES - NBLINKS))
                        log_msg="$REMAINING_CACHE_FILES files remaining from caches to array ($(bytes_to_human "$REMAINING_CACHE_SIZE"))"
                    else
                        REMAINING_CACHE_FOLDERS=$((REMAINING_CACHE_FOLDERS - 1))
                        log_msg="$REMAINING_CACHE_FOLDERS folders remaining from caches to array"
                    fi
                else
                    REMAINING_ARRAY_SIZE=$((REMAINING_ARRAY_SIZE - FILESIZE))
                    # Check if there are any files or folders left
                    if [[ "$FILETYPE" = "f" ]]; then
                        REMAINING_ARRAY_FILES=$((REMAINING_ARRAY_FILES - NBLINKS))
                        log_msg="$REMAINING_ARRAY_FILES files remaining from array to caches ($(bytes_to_human "$REMAINING_ARRAY_SIZE"))"
                    else
                        REMAINING_ARRAY_FOLDERS=$((REMAINING_ARRAY_FOLDERS - 1))
                        log_msg="$REMAINING_ARRAY_FOLDERS folders remaining from array to caches"
                    fi
                fi
                mvlogger "$log_msg"

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

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3e84991 and 462b551.

📒 Files selected for processing (1)
  • source/ca.mover.tuning/usr/local/emhttp/plugins/ca.mover.tuning/age_mover (3 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Codacy Static Code Analysis
🔇 Additional comments (4)
source/ca.mover.tuning/usr/local/emhttp/plugins/ca.mover.tuning/age_mover (4)

1651-1651: Good defensive quoting fix.

Quoting $TESTMODE prevents word splitting and handles empty values correctly.


1915-1928: LGTM!

The conditional logging correctly distinguishes between files and folders, providing appropriate context (size for files, count only for folders).


1936-1939: LGTM!

Separate logging for files vs. folders from cache to array is consistent with the pattern used elsewhere.


1946-1949: LGTM!

Logging for array-to-cache moves is consistent with the cache-to-array pattern.

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

♻️ Duplicate comments (2)
source/ca.mover.tuning/usr/local/emhttp/plugins/ca.mover.tuning/age_mover (2)

1930-1944: Per-type logging correctly implemented.

The logging now correctly differentiates between files and folders, displaying size information only for files. The code duplication noted in past reviews is a minor concern; the current structure is readable.


1946-1966: Per-type counter updates and logging are correct.

The remaining counters for files and folders are correctly decremented based on FILETYPE, and the log messages appropriately distinguish between files (with size) and folders (without size). The duplication noted in past reviews is a stylistic concern that doesn't affect functionality.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 462b551 and 04e143a.

📒 Files selected for processing (3)
  • source/ca.mover.tuning/usr/local/emhttp/plugins/ca.mover.tuning/Mover.tuning.page (1 hunks)
  • source/ca.mover.tuning/usr/local/emhttp/plugins/ca.mover.tuning/age_mover (5 hunks)
  • source/ca.mover.tuning/usr/local/emhttp/plugins/ca.mover.tuning/default.cfg (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Codacy Static Code Analysis
🔇 Additional comments (6)
source/ca.mover.tuning/usr/local/emhttp/plugins/ca.mover.tuning/default.cfg (1)

34-34: LGTM!

The new moveEmptyFolders configuration option is correctly added with a default value of "yes", which aligns with the default handling in the age_mover script and the new UI control.

source/ca.mover.tuning/usr/local/emhttp/plugins/ca.mover.tuning/Mover.tuning.page (1)

641-644: LGTM!

The new "Top Folder" option for cleanFolders is correctly implemented with a descriptive help text explaining the behavior.

source/ca.mover.tuning/usr/local/emhttp/plugins/ca.mover.tuning/age_mover (4)

695-706: LGTM!

The moveEmptyFolders setting handling follows the established pattern used by other configuration options in this function, with proper defaults and logging.


1081-1086: LGTM!

The find filter correctly adjusts based on MOVE_EMPTY_FOLDERS:

  • When "yes": includes both files and empty directories with -mindepth 1
  • When not "yes": only includes files

The logic is sound and the -mindepth 1 ensures the share root isn't inadvertently matched.


1666-1668: LGTM!

The quoted string comparison [ "$TESTMODE" = "yes" ] is correct and POSIX-compliant.


1892-1918: Previous review issue has been addressed.

The .placeholder handling now correctly uses short-circuit evaluation: the string comparison [ "$file_count" != ".placeholder" ] is evaluated first, preventing the integer comparison [ "$file_count" -eq 0 ] from running when file_count is ".placeholder". This resolves the "integer expression expected" error flagged in earlier reviews.

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

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2cb5ec0 and f21b759.

📒 Files selected for processing (2)
  • source/ca.mover.tuning/usr/local/emhttp/plugins/ca.mover.tuning/Mover.tuning.page (29 hunks)
  • source/ca.mover.tuning/usr/local/emhttp/plugins/ca.mover.tuning/Share.tuning.page (7 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Codacy Static Code Analysis
🔇 Additional comments (4)
source/ca.mover.tuning/usr/local/emhttp/plugins/ca.mover.tuning/Share.tuning.page (1)

430-430: LGTM! Proper output sanitization added.

The addition of htmlspecialchars with ENT_QUOTES | ENT_SUBSTITUTE flags properly escapes user input in HTML attributes, preventing potential XSS vulnerabilities.

Also applies to: 445-445

source/ca.mover.tuning/usr/local/emhttp/plugins/ca.mover.tuning/Mover.tuning.page (3)

626-633: New feature implementation looks good.

The moveEmptyFolders option is properly structured with the label preceding the select element (not inside it), resolving the HTML structure issue from the previous review. The feature includes clear help text explaining its behavior.


239-239: LGTM! Input sanitization added.

User input fields are now properly sanitized using htmlspecialchars, preventing potential XSS vulnerabilities when rendering values in HTML attributes.

Also applies to: 324-324, 343-343, 348-348, 546-546, 562-562


156-163: LGTM! Test mode warning display is well-implemented.

The warning message provides immediate visual feedback when test mode is enabled, using both server-side PHP for initial state and client-side JavaScript for dynamic toggling. The implementation is clean and user-friendly.

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
source/ca.mover.tuning/usr/local/emhttp/plugins/ca.mover.tuning/age_mover (1)

1819-1841: Minor bug in top-level folder logging and redundant .placeholder condition.

In the top-folder cleanup branch:

  • The log line uses count instead of top_folder_count for pluralization and .placeholder checking:
mvlogger "Not deleting top-level folder containing $top_folder_count file$([ "$count" != ".placeholder" ] && echo "s"): ${top_folder}"

count refers to the last per-folder counter, not the top-level one, so the message can be inconsistent.

  • Because top_folder_count is always overwritten by find "$top_folder" -type f | wc -l, it will never be the string .placeholder, making the != ".placeholder" test dead code.

A minimal fix that keeps behavior the same but makes the code correct and clearer:

-                                if [[ "$top_folder_count" != ".placeholder" && "$top_folder_count" -eq 0 ]]; then
+                                if [ "$top_folder_count" -eq 0 ]; then
                                     mvlogger "Deleting empty top-level folder: $top_folder"
                                     # Check if empty top-level folder exist and remove it
                                     [ -d "$top_folder" ] && find "$top_folder" -empty -type d -delete
                                 else
-                                    mvlogger "Not deleting top-level folder containing $top_folder_count file$([ "$count" != ".placeholder" ] && echo "s"): ${top_folder}"
+                                    mvlogger "Not deleting top-level folder containing $top_folder_count file$([ "$top_folder_count" != "1" ] && echo "s"): ${top_folder}"
                                 fi
🧹 Nitpick comments (2)
source/ca.mover.tuning/usr/local/emhttp/plugins/ca.mover.tuning/Mover.tuning.page (1)

622-638: moveEmptyFolders / cleanFolders UX is consistent with backend logic.

The new moveEmptyFolders select (yes/no) and existing cleanFolders (no/yes/topFolder) are correctly named to match age_mover’s MOVE_EMPTY_FOLDERS and CLEANFOLDERS variables and clearly describe behavior (moving vs deleting empty folders). If you want to avoid confusion for users, you might optionally mention in the help text that disabling “Move empty folders” means only folders associated with moved files are affected by “Clean empty folders”, while unrelated empty folders stay put.

source/ca.mover.tuning/usr/local/emhttp/plugins/ca.mover.tuning/age_mover (1)

1082-1087: Find filter for MOVE_EMPTY_FOLDERS is sound; consider symmetric -mindepth 1.

The find expression correctly:

  • Includes -mindepth 1 \( -type f -o -type d -empty \) when MOVE_EMPTY_FOLDERS=="yes" (files plus empty dirs, excluding the share root).
  • Falls back to -type f only when disabled (no directories in the action list).

Functionally this is fine: the share root is a directory, so it’s never selected in the -type f branch. For consistency and to avoid ever touching the root in future changes, you might optionally mirror -mindepth 1 in the else branch:

-        else
-            FINDSTR+=" -type f"
-        fi
+        else
+            FINDSTR+=" -mindepth 1 -type f"
+        fi
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e2abd69 and 11ca46f.

📒 Files selected for processing (2)
  • source/ca.mover.tuning/usr/local/emhttp/plugins/ca.mover.tuning/Mover.tuning.page (27 hunks)
  • source/ca.mover.tuning/usr/local/emhttp/plugins/ca.mover.tuning/age_mover (6 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Codacy Static Code Analysis
🔇 Additional comments (5)
source/ca.mover.tuning/usr/local/emhttp/plugins/ca.mover.tuning/Mover.tuning.page (2)

149-163: Test Mode warning toggle is correctly wired and stateful.

The testmode select, testmode_warning span, and toggleTestModeWarning() function use consistent "yes"/"no" values and correctly initialize the warning visibility from $cfg['testmode']. No functional issues seen.


169-176: Filename validation UI and invalid character input correctly match backend expectations.

The validateFilenames toggle, invalidFileChars text input, and their help text align with the shell-side validation (validate_filename + invalidFileChars handling). Using htmlspecialchars($cfg['invalidFileChars']) prevents HTML injection, and the fixed class='myinvalidFileChars' makes the markup valid and styleable. No further changes needed here.

Also applies to: 189-206, 656-685

source/ca.mover.tuning/usr/local/emhttp/plugins/ca.mover.tuning/age_mover (3)

697-706: MOVE_EMPTY_FOLDERS config handling looks correct and inherits sensibly.

The new moveEmptyFolders block sets a persistent default of "yes" in the global config and logs it, while share override configs inherit the global value unless they define their own moveEmptyFolders. This matches how other settings behave and aligns with the new UI option.


1893-1921: Empty-folder cleanup after moving directories is correct and handles .placeholder safely.

The new “Clean moved empty folders” block only runs for directory actions (FILETYPE=="d") with ACTION containing move and MOVE_EMPTY_FOLDERS="yes", and:

  • Treats .placeholder as a keep-alive marker, avoiding integer comparisons when file_count=".placeholder".
  • Counts both regular files and subdirectories to ensure the directory is truly empty.
  • Respects TESTMODE when deciding whether to rmdir or just log.

This correctly fixes the previous .placeholder integer-comparison issue and ensures moved empty directories are tidied without affecting placeholder-protected folders.


1933-1968: Remaining-items counters and logs are now per-type and much clearer.

The updated remaining-count logic splits files vs folders for unattended/cache/array directions (REMAINING_*_FILES vs REMAINING_*_FOLDERS) and logs them separately. This avoids the previous ambiguity where folders were folded into “files remaining” and matches the new statistics written in moverStatusWrite().

@masterwishx
Copy link
Owner Author

@coderabbitai review last commit

@masterwishx
Copy link
Owner Author

@coderabbitai summarize

@coderabbitai
Copy link

coderabbitai bot commented Nov 28, 2025

Tip

For best results, initiate chat on the files or code changes.

@masterwishx, here's a summary of PR #104:

Summary of Changes

This PR introduces enhanced control and logging for the mover script with the following key improvements:

Core Functionality

  • New Empty Folder Control: Added moveEmptyFolders configuration option (defaults to "yes") to control whether empty directories are moved along with files
  • Empty Folder Cleanup: Automatically cleans up empty folders after files are moved (when enabled)
  • Enhanced Logging: Separated logging for files vs. folders throughout the move process, providing more granular visibility into what's being moved

Configuration & UI

  • New Configuration Option: moveEmptyFolders="yes" added to default.cfg
  • UI Enhancements on Mover.tuning.page:
    • Added moveEmptyFolders toggle option
    • Extended cleanFolders option to include "Top Folder" value
    • Improved UI layout by removing unnecessary style wrappers and adding informational icons
    • Clarified test mode warnings and notification behaviors

Styling Updates

  • Share.tuning.page: Removed "narrow" CSS classes from multiple select elements for better styling consistency

Technical Details

  • Improved filter logic in createFilteredFilelist() to handle empty folder inclusion/exclusion
  • Enhanced processTheMoves() with per-type counters and logging for files and folders
  • Added LAST_FOLDER_COUNT variable for tracking folder counts

Estimated Review Effort: Medium to High

@coderabbitai
Copy link

coderabbitai bot commented Nov 28, 2025

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Get the last commit on the PR branch
git log origin/dev-new-fixes-21 --not origin/master --oneline -1

# Get the commit hash of the last commit
LAST_COMMIT=$(git log origin/dev-new-fixes-21 --not origin/master --format=%H -1)

echo "Last commit hash: $LAST_COMMIT"

# Get the commit message and details
git log -1 --format="%H%n%an%n%ae%n%ad%n%s%n%b" $LAST_COMMIT

# Get the files changed in the last commit
git show --name-status --format="" $LAST_COMMIT

# Get the full diff of the last commit
git show $LAST_COMMIT

Unrecoverable error: Failed to clone repository


@masterwishx I'm unable to access the git repository directly to identify and review the specific last commit. However, I can help you in the following ways:

  1. Trigger a full review of the PR - I can initiate a complete review of all changes in this PR
  2. Review based on the available summary - I can provide feedback based on the AI-generated summary that shows changes to:
    • age_mover - Added moveEmptyFolders functionality with default behavior and per-type logging
    • Mover.tuning.page - UI updates with new moveEmptyFolders option and styling changes
    • default.cfg - Added moveEmptyFolders="yes" configuration
    • Share.tuning.page - Styling updates and markup improvements

Would you like me to trigger a full review of the PR?

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@masterwishx
Copy link
Owner Author

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)

source/ca.mover.tuning/usr/local/emhttp/plugins/ca.mover.tuning/age_mover (1)> 1819-1841: Minor bug in top-level folder logging and redundant .placeholder condition.

In the top-folder cleanup branch:

  • The log line uses count instead of top_folder_count for pluralization and .placeholder checking:
mvlogger "Not deleting top-level folder containing $top_folder_count file$([ "$count" != ".placeholder" ] && echo "s"): ${top_folder}"

count refers to the last per-folder counter, not the top-level one, so the message can be inconsistent.

  • Because top_folder_count is always overwritten by find "$top_folder" -type f | wc -l, it will never be the string .placeholder, making the != ".placeholder" test dead code.

A minimal fix that keeps behavior the same but makes the code correct and clearer:

-                                if [[ "$top_folder_count" != ".placeholder" && "$top_folder_count" -eq 0 ]]; then
+                                if [ "$top_folder_count" -eq 0 ]; then
                                     mvlogger "Deleting empty top-level folder: $top_folder"
                                     # Check if empty top-level folder exist and remove it
                                     [ -d "$top_folder" ] && find "$top_folder" -empty -type d -delete
                                 else
-                                    mvlogger "Not deleting top-level folder containing $top_folder_count file$([ "$count" != ".placeholder" ] && echo "s"): ${top_folder}"
+                                    mvlogger "Not deleting top-level folder containing $top_folder_count file$([ "$top_folder_count" != "1" ] && echo "s"): ${top_folder}"
                                 fi

🧹 Nitpick comments (2)
📜 Review details
Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits
Reviewing files that changed from the base of the PR and between e2abd69 and 11ca46f.

📒 Files selected for processing (2)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
🔇 Additional comments (5)

source/ca.mover.tuning/usr/local/emhttp/plugins/ca.mover.tuning/Mover.tuning.page (2)> 149-163: Test Mode warning toggle is correctly wired and stateful.

The testmode select, testmode_warning span, and toggleTestModeWarning() function use consistent "yes"/"no" values and correctly initialize the warning visibility from $cfg['testmode']. No functional issues seen.

169-176: Filename validation UI and invalid character input correctly match backend expectations.
The validateFilenames toggle, invalidFileChars text input, and their help text align with the shell-side validation (validate_filename + invalidFileChars handling). Using htmlspecialchars($cfg['invalidFileChars']) prevents HTML injection, and the fixed class='myinvalidFileChars' makes the markup valid and styleable. No further changes needed here.
Also applies to: 189-206, 656-685

source/ca.mover.tuning/usr/local/emhttp/plugins/ca.mover.tuning/age_mover (3)> 697-706: MOVE_EMPTY_FOLDERS config handling looks correct and inherits sensibly.

The new moveEmptyFolders block sets a persistent default of "yes" in the global config and logs it, while share override configs inherit the global value unless they define their own moveEmptyFolders. This matches how other settings behave and aligns with the new UI option.

1893-1921: Empty-folder cleanup after moving directories is correct and handles .placeholder safely.
The new “Clean moved empty folders” block only runs for directory actions (FILETYPE=="d") with ACTION containing move and MOVE_EMPTY_FOLDERS="yes", and:

  • Treats .placeholder as a keep-alive marker, avoiding integer comparisons when file_count=".placeholder".
  • Counts both regular files and subdirectories to ensure the directory is truly empty.
  • Respects TESTMODE when deciding whether to rmdir or just log.

This correctly fixes the previous .placeholder integer-comparison issue and ensures moved empty directories are tidied without affecting placeholder-protected folders.

1933-1968: Remaining-items counters and logs are now per-type and much clearer.
The updated remaining-count logic splits files vs folders for unattended/cache/array directions (REMAINING_*_FILES vs REMAINING_*_FOLDERS) and logs them separately. This avoids the previous ambiguity where folders were folded into “files remaining” and matches the new statistics written in moverStatusWrite().

After last commit it's OK?

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

🧹 Nitpick comments (2)
source/ca.mover.tuning/usr/local/emhttp/plugins/ca.mover.tuning/age_mover (2)

1823-1836: Consider clarifying .placeholder logging.

The logic correctly avoids integer comparison errors by checking "$top_folder_count" != ".placeholder" before -eq 0 (line 1831). However, when .placeholder is present, line 1836 logs "Not deleting top-level folder containing .placeholder file: ..." which could be clearer.

Consider handling .placeholder separately for clearer messaging:

                 if [ -e "${top_folder}/.placeholder" ]; then
-                    top_folder_count=".placeholder"
+                    mvlogger "Not deleting top-level folder: contains .placeholder file: ${top_folder}"
                 else
                     # Count files in Top Folder if exist
                     [ -d "$top_folder" ] && top_folder_count="$(find "$top_folder" -type f | wc -l)"
                     mvDebuglogger "Current top folder: $top_folder, Count of files in Top Folder: $top_folder_count" "Clean Top Folder - Start Loop"
-                fi
 
-                if [[ "$top_folder_count" != ".placeholder" && "$top_folder_count" -eq 0 ]]; then
+                    if [[ "$top_folder_count" -eq 0 ]]; then
                         # Check if empty top-level folder exist and remove it
                         [ -d "$top_folder" ] && find "$top_folder" -empty -type d -delete
                         mvlogger "Deleting empty top-level folder: $top_folder"
-                else
+                    else
                         mvlogger "Not deleting top-level folder containing $top_folder_count file$([ "$top_folder_count" != ".placeholder" ] && echo "s"): ${top_folder}"
+                    fi
                 fi

1890-1918: LGTM! Empty folder cleanup logic is correct.

The block correctly handles cleaning moved empty folders:

  • ✅ Checks for .placeholder file before integer comparisons (avoids "integer expression expected" error noted in past reviews)
  • ✅ Counts both files and subdirectories
  • ✅ Only deletes when both counts are 0 and no .placeholder exists
  • ✅ Respects TESTMODE

The logic is sound. Optionally, the .placeholder handling could be refactored similarly to the suggestion for top-level folders (lines 1823-1836) to make logging clearer when .placeholder is present.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8e6967c and 11c00ec.

📒 Files selected for processing (1)
  • source/ca.mover.tuning/usr/local/emhttp/plugins/ca.mover.tuning/age_mover (8 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Codacy Static Code Analysis
🔇 Additional comments (6)
source/ca.mover.tuning/usr/local/emhttp/plugins/ca.mover.tuning/age_mover (6)

73-73: LGTM! Variable initialization follows existing pattern.

The LAST_FOLDER_COUNT variable is initialized consistently with LAST_COUNT above it and is used later for tracking remaining folder counts during cleanup operations.


696-706: LGTM! Configuration handling is consistent.

The moveEmptyFolders configuration follows the established pattern for other settings, with a sensible default of "yes" and proper logging.


1082-1087: LGTM! Find filter correctly implements moveEmptyFolders feature.

The conditional logic properly includes empty directories (-type d -empty) when MOVE_EMPTY_FOLDERS is "yes" and excludes them otherwise. The use of -mindepth 1 ensures the share root itself is not included.


1667-1667: LGTM! Proper quoting of variable.

Quoting "$TESTMODE" is a good defensive practice that prevents word splitting and globbing issues.


1920-1944: LGTM! Per-type logging improves clarity.

The remaining-item counters and logs are now separated by type (files vs folders), making progress messages more precise and easier to understand.


1946-1967: LGTM! Per-type counters and logging are correctly implemented.

The cache/array remaining-item logs now distinguish files from folders, providing clearer progress tracking. The logic correctly decrements REMAINING_CACHE_FILES by NBLINKS (to handle hardlinks) while decrementing REMAINING_CACHE_FOLDERS by 1.

@masterwishx masterwishx merged commit 938463a into master Nov 28, 2025
3 checks passed
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.

2 participants