Updating a ps script that reads csv files and renames group layers

Anyone, especially newbies, asking for help with Photoshop Scripting and Photoshop Automation - as opposed to those contributing to discussion about an aspect of Photoshop Scripting

Moderators: Tom, Kukurykus

jeffreynuez
Posts: 2
Joined: Wed Jan 10, 2024 1:24 am

Updating a ps script that reads csv files and renames group layers

Post by jeffreynuez »

I need help updating a script commissioned by William Campbell in 2022. The script reads a csv file and replaces the names of the layer groups in a open psd document file listed in numerical order. The way this script worked is by reading the first column headed "Group Layers" that contained the group layer numbers, then it reads the second column headed "Names" which contains the group layer names. It then replaces the names of the first row of group layers in the psd file with the names in the csv file.

What I need it to do now is two things. First is to update the script so it is able to rename a group layer that contains all of the other layers nested within it. The second is a new feature that will locate the names of a new column that will be added to the end of the group columns headed "Image Links". This column will contain a list of image names. These image names will correspond with a folder of images located next to the csv file. I would like the script to locate the images from the image column and place the image into the nested group layer that its connected with in its row.

If possible I would also like to designate the position of all of the images within the psd file.

It's also fine if it's best to be done with two scripts.

I wanted William to update the script but he is currently unwell and I'm hoping for a speedy recovery. In the meantime I need this update as soon as possible so he gave me the go ahead to get someone to help me modify it because I did pay for it. I'd appreciate anyone that can help me with this script and I would be glad to commission your work on it.
jeffreynuez
Posts: 2
Joined: Wed Jan 10, 2024 1:24 am

Re: Updating a ps script that reads csv files and renames group layers

Post by jeffreynuez »

Here is the script. DM me your email and I can send you examples of the csv files, image files and any other examples.

Code: Select all

(function () {

    var title = "CSV To Template Rename";

    if (!/photoshop/i.test(app.name)) {
        alert("Script for Photoshop", title, false);
        return;
    }

    app.displayDialogs = DialogModes.ERROR;

    // Script variables.
    var dataArray;
    var defaultSettings;
    var doc;
    var doneMessage;
    var error;
    var working;

    // Reusable UI variables.
    var g; // group
    var p; // panel
    var w; // window

    // Permanent UI variables.
    var btnCancel;
    var btnFileData;
    var btnOk;
    var rbComma;
    var rbSemicolon;
    var txtFileData;

    // SETUP

    // Define script variables.
    dataArray = [];

    // Script requires open document.
    if (!app.documents.length) {
        alert("Open a document", title, false);
        return;
    }
    doc = app.activeDocument;

    // DEFAULTS

    defaultSettings = {
        comma: true,
        semicolon: false,
        fileData: ""
    };

    // CREATE WORKING WINDOW

    working = new Window("palette", undefined, undefined, {
        closeButton: false
    });
    working.preferredSize = [300, 80];
    working.add("statictext");
    working.t = working.add("statictext");
    working.add("statictext");
    working.display = function (message) {
        this.t.text = message || "Working... Please wait...";
        this.show();
        this.update();
    };

    // CREATE USER INTERFACE

    w = new Window("dialog", title);
    w.alignChildren = "fill";

    // Panel 'Data file'
    p = w.add("panel", undefined, "Data file (CSV)");
    p.alignChildren = "left";
    p.margins = [18, 24, 18, 18];
    g = p.add("group");
    g.margins = [0, 0, 0, 4];
    g.add("statictext", undefined, "Delimiter:");
    g = g.add("group");
    g.margins = [0, 4, 0, 0];
    rbComma = g.add("radiobutton", undefined, "Comma");
    rbSemicolon = g.add("radiobutton", undefined, "Semicolon");
    g = p.add("group");
    btnFileData = g.add("button", undefined, "File...");
    txtFileData = g.add("statictext", undefined, "", {
        truncate: "middle"
    });
    txtFileData.preferredSize = [300, -1];

    // Action Buttons
    g = w.add("group");
    g.alignment = "center";
    btnOk = g.add("button", undefined, "OK");
    btnCancel = g.add("button", undefined, "Cancel");

    // Panel Copyright
    p = w.add("panel");
    p.add("statictext", undefined, "Playco");

    // SET UI VALUES

    rbComma.value = defaultSettings.comma;
    rbSemicolon.value = defaultSettings.semicolon;
    configureUi();

    // UI ELEMENT EVENT HANDLERS

    // Panel 'Data file'
    rbComma.onClick = clearFileData;
    rbSemicolon.onClick = clearFileData;
    btnFileData.onClick = function () {
        var cf;
        var f;
        var message;
        var validateFile;
        cf = new File(txtFileData.text);
        message = "Select CSV file";
        if (File.fs == "Macintosh") {
            validateFile = function (f) {
                if ((f instanceof Folder) || f.alias || /\.csv$/i.test(f.name)) {
                    return true;
                }
                return false;
            };
        } else {
            // Windows
            validateFile = "Comma Separated Values:*.csv";
        }
        if (cf.exists) {
            f = cf.openDlg(message, validateFile);
        } else {
            f = File.openDialog(message, validateFile);
        }
        if (f) {
            if (/\.csv$/i.test(f.name)) {
                message = readData(f);
                if (!message) { // Success
                    txtFileData.text = File.decode(f.fsName);
                }
            }
            if (message) { // Fail
                clearFileData();
                alert(message, " ", false);
            }
        }
    };

    // Action Buttons
    btnOk.onClick = function () {
        if (!(dataArray && dataArray.length)) {
            alert("Select CSV file", " ", false);
            return;
        }
        w.close(1);
    };
    btnCancel.onClick = function () {
        w.close(0);
    };

    // DISPLAY THE DIALOG

    if (w.show() == 1) {
        doneMessage = "";
        try {
            process();
            doneMessage = "Done";
        } catch (e) {
            error = error || e;
            doneMessage = "An error has occurred." + "\n" + "Line" + " " + error.line + ": " + error.message;
        }
        working.close();
        doneMessage && alert(doneMessage, title, error);
    }

    //====================================================================
    //               END PROGRAM EXECUTION, BEGIN FUNCTIONS
    //====================================================================

    function clearFileData() {
        txtFileData.text = "";
    }

    function configureUi() {
        if (!(rbComma.value || rbSemicolon.value)) {
            rbComma.value = true;
        }
    }

    function parseCsv(data, delimiter) {
        // data: String = contents of a CSV file
        // delimiter: character that separates columns
        //            undefined defaults to comma
        // Returns: Array [[String row, String column]]
        var c = ""; // Character at index.
        var d = delimiter || ","; // Default to comma.
        var endIndex = data.length;
        var index = 0;
        var maxIndex = endIndex - 1;
        var q = false; // "Are we in quotes?"
        var result = []; // Array of rows (array of column arrays).
        var row = []; // Array of columns.
        var v = ""; // Column value.
        while (index < endIndex) {
            c = data[index];
            if (q) { // In quotes.
                if (c == "\"") {
                    // Found quote; look ahead for another.
                    if (index < maxIndex && data[index + 1] == "\"") {
                        // Found another quote means escaped.
                        // Increment and add to column value.
                        index++;
                        v += c;
                    } else {
                        // Next character not a quote; last quote not escaped.
                        q = !q; // Toggle "Are we in quotes?"
                    }
                } else {
                    // Add character to column value.
                    v += c;
                }
            } else { // Not in quotes.
                if (c == "\"") {
                    // Found quote.
                    q = !q; // Toggle "Are we in quotes?"
                } else if (c == "\n" || c == "\r") {
                    // Reached end of line.
                    // Test for CRLF.
                    if (c == "\r" && index < maxIndex) {
                        if (data[index + 1] == "\n") {
                            // Skip trailing newline.
                            index++;
                        }
                    }
                    // Column and row complete.
                    row.push(v);
                    v = "";
                    // Add row to result if first row or length matches first row.
                    if (result.length == 0 || row.length == result[0].length) {
                        result.push(row);
                    }
                    row = [];
                } else if (c == d) {
                    // Found comma; column complete.
                    row.push(v);
                    v = "";
                } else {
                    // Add character to column value.
                    v += c;
                }
            }
            if (index == maxIndex) {
                // Reached end of data; flush.
                if (v.length || c == d) {
                    row.push(v);
                }
                // Add row to result if length matches first row.
                if (row.length == result[0].length) {
                    result.push(row);
                }
                break;
            }
            index++;
        }
        return result;
    }

    function process() {
        var i;
        app.displayDialogs = DialogModes.NO;
        working.display();
        try {
            for (i = 0; i < dataArray.length && i < doc.layerSets.length; i++) {
                doc.layerSets[i].name = dataArray[i][1];
            }
        } finally {
            app.displayDialogs = DialogModes.ERROR;
        }
    }

    function readData(file) {
        var data;
        var header = [];
        if (file.length > 100000) {
            return "Data file size exceeds 100K maximum";
        }
        // Read data file.
        if (!file.open("r")) {
            return "Failed to open data file";
        }
        try {
            data = file.read();
        } catch (e) {
            return "Error reading data file" + ": " + e.message;
        } finally {
            file.close();
        }
        // Parse data file.
        dataArray = parseCsv(data, rbSemicolon.value ? ";" : ",");
        // Two rows minimum.
        if (dataArray.length < 2) {
            return "Data file missing rows";
        }
        // Extract header row.
        header = dataArray.shift();
        // Two columns minimum.
        if (!header || header.length < 2) {
            return "Data file missing columns";
        }
        return null; // Success
    }

})();