Nodes/AAA Metadata System/Flatten Nested Files v0.2
ComfyUI Node

Flatten Nested Files v0.2

Flatten a 40-Folder-Deep Dataset Without Losing the Captions

By EricRollei·Created 10 months ago·Updated 9 months ago· 13
Flatten Nested Files v0.2
    • status_message
    • files_moved
    • paired_files_moved
    • stats_json
    • log_output
    main_directory
    operation_modeflatten_only
    file_typesimages_only
    flatten_depth0
    respect_paired_filestrue
    skip_organized_folderstrue
    organize_by_typefalse
    sidecar_handlingkeep_with_images
    remove_empty_folderstrue
    dry_runfalse
    handle_conflictsrename
    max_scan_depth100
    custom_type_mappings
    custom_folder_mappings
    preserve_source_foldernone

    Downloaded datasets and scraped galleries have a signature look: forty levels of nested folders with one image at the bottom. Training data, captioning jobs, and archive cleanups all hit the same wall - you want everything in one flat directory, and doing it by hand is misery. Flatten Nested Files v2 (displayed as v0.2, the naming is optimistic) recursively walks a directory tree and moves the files up, with an unusually thoughtful feature: it keeps paired files together. That's the thing most flattening scripts get wrong, and it's why this node earns its place.

    The one required input is main_directory plus operation_mode: flatten_only moves everything straight into the target, flatten_and_organize also creates type subfolders (images/, movies/, text/), and organize_only tidies files in place without moving them up. The optional section is where the real control lives: flatten_depth lets you keep the first level of subfolders (useful when each subfolder is a source you want to preserve, like an Instagram profile), respect_paired_files (on by default) moves photo.jpg together with photo.xmp and photo.txt as a unit, and sidecar_handling decides whether captions ride along into the images folder or go to a sidecars folder.

    The rest reads like a checklist of someone who's burned themselves before: dry_run previews without moving anything, handle_conflicts offers rename/skip/overwrite for duplicate filenames, preserve_source_folder prefixes or suffixes the original folder name onto files so you don't lose provenance, remove_empty_folders cleans up after itself, and max_scan_depth guards against pathological nesting. Outputs are status_message, files_moved (INT), paired_files_moved (INT) - a nice touch, because it confirms your captions actually followed their images - plus stats_json and log_output.

    The mechanism is straightforward recursion with smart pairing logic, no magic. The trap is the same as any file-mover: this runs when the workflow executes, so a stray Queue press with dry_run off and handle_conflicts on overwrite is a permanent change. The dry_run default being off is the one thing I'd change about this node.

    Framing honestly: this is a one-author pack with no community footprint, and Flatten is a utility that earns its keep on real dataset work but won't be in anyone's shareable art workflow. If your training folder looks like a fractal, though, this is the tool that flattens it while keeping every .txt caption glued to its image.

    Install the pack and restart:

    cd ComfyUI/custom_nodes
    git clone https://github.com/EricRollei/AAA_Metadata_System
    cd AAA_Metadata_System
    pip install -r requirements.txt
    

    Then the smart path: set dry_run to true, run it, read the log, and only flip dry_run off when the preview matches your mental model. Flattening is reversible in theory; doing it wrong is not.

    CategoryEric/Images

    Inputs (15)

    NameTypeDefaultDescription
    main_directorySTRINGMain directory where all files will be moved to
    operation_modeCOMBOflatten_onlyChoose operation mode: • flatten_only: Move all files directly into main_directory (NO type subfolders) • flatten_and_organize: Move files AND create type subfolders (images/, movies/, etc.) • organize_only: Don't move files up, just organize them in their current locations Note: organize_by_type parameter can override flatten_only to add type folders
    file_typesoptCOMBOimages_onlyWhich files to process: • images_only: .jpg, .png, .webp, .gif, etc. • all_media: Images + videos (.mp4, .mov, etc.) • all_files: Everything including .txt, .pdf, etc.
    flatten_depthoptINT00–10Flatten nested folders to this depth: • 0 = Move ALL files to main directory • 1 = Keep 1st level subfolders, flatten everything inside them • 2 = Keep 2 levels, flatten below that Example: If main=instagram and depth=1, processes each profile folder (alisha.maghi/, 777luckyfish/) independently
    respect_paired_filesoptBOOLEANtrueKeep paired files together (e.g., photo.jpg + photo.xmp + photo.txt). Paired files share the same base filename and are moved as a group.
    skip_organized_foldersoptBOOLEANtrueSkip folders that already have type organization (contain images/, movies/, text/ subfolders). Useful to avoid re-organizing already processed directories.
    organize_by_typeoptBOOLEANfalseCreate type-based subfolders: • images/ for .jpg, .png, etc. • movies/ for .mp4, .mov, etc. • text/ for .txt, .pdf, .md • sidecars/ for .xmp, .json (unless kept with images) • other/ for unrecognized types When True: Always creates type folders (even with flatten_only mode) When False with flatten_only: All files go directly into main_directory
    sidecar_handlingoptCOMBOkeep_with_imagesWhere to put sidecar/metadata files: • keep_with_images: Put .xmp/.json/.txt in images/ folder • separate_folder: Put all sidecars in sidecars/ folder • keep_txt_only: Only .txt with images, others to sidecars/
    remove_empty_foldersoptBOOLEANtrueDelete empty subdirectories after moving files. Leaves a clean directory structure with no leftover empty folders.
    dry_runoptBOOLEANfalsePreview mode - show what WOULD be moved without actually moving anything. Great for testing settings before committing changes.
    handle_conflictsoptCOMBOrenameHow to handle duplicate filenames: • rename: Add (1), (2), etc. to filename • skip: Leave original, don't move duplicate • overwrite: Replace existing file with new one
    max_scan_depthoptINT1001–200Maximum folder nesting depth to scan. Increase if you have very deeply nested folders (46+ levels). Prevents infinite loops and excessive scanning.
    custom_type_mappingsoptSTRINGJSON mapping file extensions to custom folder names. Example: { ".pdf": "documents", ".cr2": "raw_photos", ".psd": "photoshop" } Files with these extensions go to specified folders instead of default type folders.
    custom_folder_mappingsoptSTRINGJSON mapping file TYPES to custom folder names. Example: { "movies": "videos", "images": "photos", "text": "documents" } Renames the default type folders (images→photos, movies→videos, etc.).
    preserve_source_folderoptCOMBOnoneAdd original folder name to filename to preserve context: • none: photo.jpg (no change) • prefix: alisha.maghi_photo.jpg • suffix: photo_alisha.maghi.jpg Useful when flattening to avoid name conflicts and maintain source info.

    Outputs (5)

    NameTypeDescription
    status_messageSTRING
    files_movedINT
    paired_files_movedINT
    stats_jsonSTRING
    log_outputSTRING