Bridge: Ability to export folder listing to text file

  • 3
  • Idea
  • Updated 3 months ago
  • (Edited)
Not sure why file management apps don't have functionality to export a folder listing to a text file. Consider this a feature request.

I've also written a quick and dirty script to do this. If you've ever needed this functionality, here ya go. Much easier than the old Batch Rename workaround.

As-is, use at your own risk, no warranty, your mileage may vary, etc. Apache licensed so its Free Software.

Let me know if it doesn't work, I haven't tested on the Mac yet. It will be slow on large folders but I have tested on a folder with 12,000+ items and it worked fine.

/*
FolderListExport created by David M. Converse ©2018. http://www.lumigraphics.com
Last updated 7-30-2018

This script uses Extendscript and ScriptUI to save a text list of the currently selected folder in Bridge.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

#target bridge
if(BridgeTalk.appName == 'bridge'){
    var newCommand = new MenuElement('command', 'Export Folder List...', 'at the end of Tools');
    }

newCommand.onSelect = function (){
    FolderListExport();
    }

function FolderListExport(){
    var FileList = [];
    var items = 0;
    var parentFolder = new Thumbnail(app.document.presentationPath);
    var logPath = '';
    var logFile = File(logPath);
    if(parentFolder.container){
        try{
            app.synchronousMode = true;
            parentFolder.refresh();
            FileList = parentFolder.children;
            items = FileList.length;
            if(items == 0) return;
            logFile = new File('~/Desktop/' + parentFolder.name + '.txt').saveDlg('Create New Log File', '*.txt');
            logFile.open('w:');
            for(var i = 0;i < items;i++){
                logFile.writeln(FileList[i].name);
            }
            logFile.close();
            app.synchronousMode = false;
        }
        catch(e){
            alert('Folder list not saved.');
            }
        }
    else{
        alert('Please select a folder. Collections are not supported.');
        return;
        }
    }
Photo of David Converse

David Converse

  • 441 Posts
  • 128 Reply Likes

Posted 4 months ago

  • 3
Photo of David Converse

David Converse

  • 441 Posts
  • 128 Reply Likes
To use this script. copy from the "/*" to the end, paste into a text editor and save with a ".jsx" extension. In Bridge, open Preferences->Startup Scripts and click the button to reveal the Startup Scripts folder. Drag the .jsx file into that folder and relaunch Bridge. You'll have a new menu item "Tools->Export Folder List..."

Select a folder and then that menu command. Choose the file location and the script will save your folder listing.
Photo of Gime

Gime

  • 16 Posts
  • 5 Reply Likes
To run a "dir > list.txt" on Windows OR an "ls > list.txt" command line on a Mac sounds a bit easier... Hmm? ;) 
Photo of David Converse

David Converse

  • 441 Posts
  • 128 Reply Likes
A lot of people don't know how to use the command line or don't want to. I could have written an Applescript or Powershell script to do this as well, but having a menu command in your graphical file manager is easier.

And choosing a file location in a standard dialog is MUCH easier than figuring out a path to paste in.

Hmm?
Photo of David Converse

David Converse

  • 441 Posts
  • 128 Reply Likes
And yes, Collections are not supported, neither are subfolders. I may mess around with it and add those but I don't really need them myself.
Photo of ken.barber

ken.barber

  • 40 Posts
  • 12 Reply Likes
Looks like an awfully slow way to do 'ls > list.txt' to me.  For a recursive list (i.e., subfolders) it's 'ls -R > textfile.txt'.  Simple.
(Edited)
Photo of David Converse

David Converse

  • 441 Posts
  • 128 Reply Likes
Except that MOST PEOPLE don't know how to use the command line. And hello but ls lists the current directory in the command window. Try walking someone through finding their image folders and changing the working directory.

So, no, its not simple. You've apparently never supported or worked with non-technical designers. Just because you and I are proficient on the command line doesn't mean that anyone else is.
Photo of ken.barber

ken.barber

  • 40 Posts
  • 12 Reply Likes
Does Bridge's scripting language lack a way to invoke a simple shell command?
Photo of Kukurykus

Kukurykus

  • 526 Posts
  • 111 Reply Likes
app.system(commandLine)
Photo of David Converse

David Converse

  • 422 Posts
  • 110 Reply Likes
Yes but not directly from within Bridge. You'd have to already have the script written. And it works differently on the two platforms as I'm sure you know.
Photo of David Converse

David Converse

  • 422 Posts
  • 110 Reply Likes
Plus you still need a way to find paths. Most people don't know how to figure out the pathname they want.

There is a reason that command lines are buried. We aren't in 1982 anymore.
Photo of ken.barber

ken.barber

  • 40 Posts
  • 12 Reply Likes
"It works differently on the two platforms..."  Anyone using the Photoshop suite on Windows isn't doing serious design work.
Photo of David Converse

David Converse

  • 422 Posts
  • 110 Reply Likes
Seriously? That's an ignorant comment and I'm a hardcore Mac user.

A lot of people use the tools that their employers choose to purchase. And Bridge is used by people other than designers.

It's apparent that you are just a troll so please stop commenting and go bother someone else.
Photo of David Converse

David Converse

  • 441 Posts
  • 128 Reply Likes
And here is an updated version. It will now handle collections (which cannot be listed using the command line) and will list hidden files based on the view setting in Bridge.

Same directions to install and use.

------------------------------------------------

/*
FolderListExport created by David M. Converse ©2018
www.lumigraphics.com
Last updated 8-1-2018

This script uses Extendscript and ScriptUI to save a text list of the currently selected folder or collection in Bridge.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

#target bridge
if(BridgeTalk.appName == 'bridge'){
    var newCommand = new MenuElement('command', 'Export Folder List...', 'at the end of Tools');
    }

newCommand.onSelect = function (){
    FolderListExport();
    }

function FolderListExport(){
    var FileList = [];
    var CollList = [];

    try{
        if(app.document.presentationPath){
            var parentFolder = new Thumbnail(app.document.presentationPath);
            }
        else{
            alert('Expanded subfolder listing is not currently supported, sorry.');
            return;
            }
        app.synchronousMode = true;
        parentFolder.refresh();
        if(parentFolder.container){
            FileList = parentFolder.children;
            }
        else{
            CollList = app.getCollections();
            for(var j=0;j < CollList.length; j++){
                if((CollList[j].name + '.filelist') == parentFolder.name){
                    FileList = app.getCollectionMembers(CollList[j]);
                    break;
                    }
                }
            }
        if(FileList.length == 0) return;
        fileWriter(FileList, parentFolder);
        app.synchronousMode = false;
        }
    catch(e){
        alert('List not saved.');
        return;
        }
    }

function fileWriter(FileList, parentFolder){
    var logPath = '';
    var logFile = File(logPath);
    var listing = '';
    var numHidden = 0;
    var txtHidden = '';
   
    try{
        numHidden = FileList.length - app.document.visibleThumbnailsLength;
        if(numHidden != 0){
            txtHidden = ', ' + numHidden + ' Hidden';
            }
        listing = parentFolder.name;
        if(! parentFolder.container){
            listing = parentFolder.name.split('.');
            if(listing.length > 1){
                listing.length--;
                }
            listing = listing.join('.') + ' Collection';
            }
        logFile = new File('~/Desktop/' + listing + '.txt').saveDlg('Create New Log File', '*.txt');
        logFile.open('w:');
        if(parentFolder.container){
            logFile.writeln(parentFolder.spec.fullName);
            }
        else{
            logFile.writeln(listing);
            }
        logFile.writeln(app.document.visibleThumbnailsLength + ' Items' + txtHidden + '.\r\r');
        for(var i = 0;i < FileList.length;i++){
            listing = FileList[i].name;
            if(FileList[i].container){
                listing = listing + ' (Folder)';
                }
            if(! FileList[i].hidden || numHidden == 0){
                logFile.writeln(listing);
                }
            }
        logFile.close();
        }
    catch(e){
        alert('Could not save listing.');
        return;
        }
    }

Photo of Kukurykus

Kukurykus

  • 640 Posts
  • 155 Reply Likes
Regarding properties. Probelem is I had to make a loop over all stacks to sort them, and then make another loop over already sorted. That wasn't my intenition, as I wanted to avoid 2 loops, or even one full loop. My goal was to make a loop over already sorted stacks by Bridge, so when I reach some stack that fits my expectations I can break loop.

This way it's better to make loop over all stacks only once, as now I know there is no other way. Bridge does not allow for other solution untill like you noticed I put stacks to an array and sort them by my order before make another loop.
(Edited)
Photo of David Converse

David Converse

  • 441 Posts
  • 128 Reply Likes
Yeah I'm not sure how you avoid that. If you could read the values during the first loop it would be best, instead of doing so twice. Maybe make a feature request for sorting and naming stacks?
Photo of Kukurykus

Kukurykus

  • 640 Posts
  • 155 Reply Likes
I'm affraid dealing with current settings is easier than expecting Bridge team is going to change that specific behaviuor for stacks or anything. You know good as me there is no chance even for easier and more usefull functionalities many people would appreciate.
Photo of David Converse

David Converse

  • 441 Posts
  • 128 Reply Likes
If you could name stacks, that alone might fix the problem.
Photo of Kukurykus

Kukurykus

  • 640 Posts
  • 155 Reply Likes
Yes, that would be best option. For now Stacks names are associated with name of first file / folder they contain. That is useless as we don't know which file / folder is first in certain stack array untill we make a loop over stacks. Unfortunatelly we can't also check from file perspective is it in some stack. We can only find all stacks in first instance, and then see their files / folders array. Not in the other order, what makes it's really bad, especially like I wrote earlier there's no way to call some thumbnail to check if that's item of some stack, before we weren't called some stack to see what are its thumbnails.
(Edited)
Photo of Stephen Marsh

Stephen Marsh

  • 74 Posts
  • 15 Reply Likes
Addressing a point made earlier in the thread, I agree that for many a GUI beats a CLI... However just because one prefers a GUI, does not mean that one has to miss out on the power of CLI based tools. Here are some examples using ExifTool and Apple Automator to create a contextual service command:

http://prepression.blogspot.com/2016/12/automator-diy-exiftool-gui-services.html
Photo of David Converse

David Converse

  • 441 Posts
  • 128 Reply Likes
I'm perfectly comfortable with a CLI but most people have never used one. And despite being a hardcore Mac user, there is value in cross-platform tools.

I could easily write an AppleScript and a Powershell script to do this, but not inside of Bridge and not with the integration.

Most people cannot program, simple fact. And your suggestion is off-topic because this is about a solution for BRIDGE on both Windows and Mac.
Photo of Kukurykus

Kukurykus

  • 640 Posts
  • 155 Reply Likes
btw I noticed '.container' is usless in Bridge if I'm right. You can use directly '.children'

So when actively selected thumbnail is a folder it gives array of content, but if a file then just undefined without error. I know you probably do it for readability.

Similary it is with '.children.length'. When it's folder with conent you get length of it, but if it's a file then you get the same result as that would be empty folder, so 0.

Both doesn't need to use try...catch statement.
(Edited)
Photo of David Converse

David Converse

  • 441 Posts
  • 128 Reply Likes
Using .container lets you know if it is a folder. so if(thumbnail.container) tells me if it is a file or folder. A folder can be empty.

And using a catch statement lets me deal with cases like the Desktop, which throws an error for presentationPath. Its also easier to debug, I can add an alert (e + e.line) to tell me what broke.

I could list content an alternate way- wait until it loads, select all, then loop through the selected files and write the name of each one. That's actually almost as fast as what I'm doing now. However, if a folder is partially loaded, there isn't a way to force load it so you get an incomplete selection and export.
Photo of Kukurykus

Kukurykus

  • 640 Posts
  • 155 Reply Likes
Actually yes. There would be no difference if folder was empty. Both file and empty folder would result as 0, so we couldn't know which is folder and which a file. There's some other way to see is our thumbnail a folder. That's less convinient, but shorter of two characters though :)

For example when file / folder is selected:

new Thumbnail(app.document.selections[0]).container

new Thumbnail(app.document.selections[0]).type[4]


For container it's false / true, while for type[4] it's undefined / e.


Regarding sorting stacks I found you can do it by a trick, as all are stored in .BridgeSort hidden by default file. Instead of making first loop to collect all, we can rewrite order of stacks in that file, so visible stacks will not be read by date, but name.


Photo of David Converse

David Converse

  • 441 Posts
  • 128 Reply Likes
Interesting that they have undocumented sort behavior.

Selections can be either a container or a file, but some folders have buggy behavior. Not sure how much is getting fixed for future releases.