Organize Files into Group-Based Folders

Hey everyone! Here's a script that organizes all files into folders based on the groups in your current tab view.

What Does It Do?

  • Creates a folder for each group (e.g., Date Modified or custom group).
  • Moves files into their respective folders.

Example:

  • If grouped by size, it creates folders like Small (10 - 100 KB) or Medium (100 KB - 1 MB).
  • If grouped by type, it creates folders like PDF, JPG, or MP4.

Desktop 2024-12-15 8-32-46 AM

Features

  • Custom Column Support: It should work with both standard and custom grouping columns.
  • Safe Folder Names: Invalid characters (\ , / , : ) are replaced automatically

Usage

  1. Prepare Grouping: Ensure files are grouped (e.g., by Type , Date Modified , or a custom column).
  2. Run the Script: Activate the script via a button or hotkey.

Notes

  • File Count: Not extensively tested with very large file counts. Performance may vary.
  • Processing Time: Ensure Directory Opus has fully grouped the files before running the script.
  • I'm Not a Developer: ChatGPT did most if not all of the heavy lifting here, so there’s probably plenty of room for optimization. Big shoutout to StevenEdford for making the PDF version of the 13's manual, it made things way easier.
  • Bugs: If you spot anything weird or behaving oddly, feel free to report it. I won’t promise anything, but I’ll check it out when I get the chance.

Download Button

Move to Group Folders.dcf (8.3 KB)

Raw Code

Click to show
function OnClick(clickData) {
    var debug = false; // Set to true to enable debug messages, false to disable

    // Function to log debug messages if debug mode is enabled
    function logDebug(message) {
        if (debug) {
            DOpus.Output(message);
        }
    }

    // Function to sanitize folder names by replacing invalid characters
    function sanitizeFolderName(name) {
        var replacements = {
            '<': 'less than',
            '>': 'greater than',
            ':': '-', // Replace colons with a dash
            '"': "'", // Replace quotes with a single quote
            '/': '_', // Replace slashes with underscores
            '\\': '_', // Replace backslashes with underscores
            '|': '_', // Replace pipes with underscores
            '?': '',  // Remove question marks
            '*': ''   // Remove asterisks
        };

        // Convert the name to a string and replace invalid characters
        name = String(name);
        return name.replace(/[<>:"/\\|?*]/g, function (char) {
            return replacements[char] || '';
        });
    }

    var cmd = clickData.func.command;
    cmd.deselect = false; 
    cmd.ClearFiles();

    var tab = clickData.func.sourcetab;
    if (!tab) {
        logDebug("Could not get the active tab.");
        return;
    }

    tab.Update(); // Ensure the information is up to date
    var format = tab.format;
    if (!format) {
        logDebug("Could not get the tab format.");
        return;
    }

    // Check if the tab is grouped; if not, show a dialog
    if (!format.group_by || format.group_by === "") {
        var dlg = DOpus.Dlg;
        dlg.window = clickData.func.sourcetab.lister;
        dlg.message = "The tab is not grouped by any column. Please set grouping before running this script.";
        dlg.title = "Error";
        dlg.buttons = "OK";
        dlg.icon = "warning";
        dlg.show();
        return;
    }

    logDebug("Grouped by: " + format.group_by);

    var groups = tab.filegroups;
    if (!groups || groups.count === 0) {
        logDebug("No active groups detected. Is grouping really active?");
        return;
    }

    logDebug("Number of groups detected: " + groups.count);

    // Create an array to handle the groups and sort them
    var groupList = [];
    for (var i = 0; i < groups.count; i++) {
        var group = groups(i);
        if (group) {
            groupList.push({ name: group, members: group.members });
        }
    }

    // Sort to ensure "Unspecified" is processed first
    groupList.sort(function (a, b) {
        if (a.name === "Unspecified") return -1;
        if (b.name === "Unspecified") return 1;

        // Standard string comparison
        if (a.name < b.name) return -1;
        if (a.name > b.name) return 1;
        return 0;
    });

    // Process groups using a standard for loop
    for (var i = 0; i < groupList.length; i++) {
        var group = groupList[i];
        var groupName = sanitizeFolderName(group.name);
        var members = group.members;

        if (!members || members.count === 0) {
            logDebug("Empty group detected: " + groupName + ". Skipping folder creation.");
            continue;
        }

        logDebug("Processing group:");
        logDebug("  Name: " + groupName);

        var folderPath = tab.path + "\\" + groupName;
        cmd.RunCommand('CreateFolder NAME="' + folderPath + '"');
        logDebug("  Folder created: " + folderPath);

        var fileList = "";
        for (var j = 0; j < members.count; j++) {
            var member = members(j);
            fileList += '"' + member.realpath + '" ';
        }

        if (fileList.length > 0) {
            cmd.RunCommand('Copy MOVE FILE=' + fileList + ' TO="' + folderPath + '"');
            logDebug("  Files moved to: " + folderPath);
        }
    }

    logDebug("End of group listing.");

	// Turn off grouping at the end
    cmd.RunCommand('SET GROUPBY=off');
    logDebug("Grouping turned off.");

	cmd.RunCommand('Go REFRESH');
}
4 Likes