I would love to have some simple scripts to move or copy a file into a specific folder. In particular I would like to have a script that does the following:
- Duplicate the session file and up-rev the file name from 01 to 02 (or whatever number comes next)
- Move the original session file into a foldewr within the session folder called "old".
- Christian Scheuer @chrscheuer2019-11-18 20:02:10.727Z
Hi @sbiss
You can get inspiration to #1 in my package Pro Tools Utilities: "Save Session As New Version"
Christian Scheuer @chrscheuer2019-11-18 20:06:56.674Z2019-11-18 20:38:38.110Z
For number 2:
To move a file, you'll need to use the action
sf.file.move
, like:sf.file.move({ sourcePath: oldPath, destinationPath: newPath, });
The slight issue with doing this is you shouldn't try to move the existing file before Pro Tools is surely done saving the new file, otherwise you might run into problems. AFAIK there's no way for us to know for sure that PT is done saving, so we would need to add an arbitrary wait of about 1s.
Anyway, to put the file move command together with the existing script, do something like this:
function saveSessionAsNewVersion() { //First save the current version sf.ui.proTools.getMenuItem('File', 'Save').elementClick({}, function () { }); //can be disabled //Get our filename without extension var fileNameWithoutExtension = sf.ui.proTools.mainWindow.invalidate().sessionPath.split('/').slice(-1)[0].split('.').slice(0, -1).join('.'); //Create a new name (get the name and suffixed number - if your session name was 'My Session 42' then save 'My Session ' in grps[1] and '42' in grps[2]) var grps = fileNameWithoutExtension.match(/^(.+?)(\d+)$/); //Construct a new name based on the prefix and the number (+1), followed by the '.ptx' suffix. If there was no number, just add ' 2' var newNumber = !grps || grps.length === 0 || isNaN(Number(grps[2])) ? '_2' : ((Number(grps[2]) + 1) + ''); var newName = (grps ? grps[1] : (fileNameWithoutExtension)) + newNumber + '.ptx'; //Invoke File Save As. sf.ui.proTools.getMenuItem('File', 'Save As...').elementClick(); //Wait for the Save dialog to appear var dlg = sf.ui.proTools.windows.invalidate().whoseTitle.is('Save').waitFor().element; //Enter the new name dlg.textFields.first.value.value = newName; //Click Save dlg.buttons.whoseTitle.is('Save').first.elementClick(); } function moveFileToOldSessions(path) { var oldSessionsDir = path.split('/').slice(0, -1).join('/') + '/Old Sessions'; var filename = path.split('/').slice(-1)[0]; //Make sure "Old Sessions" dir exists sf.file.directoryCreate({ path: oldSessionsDir, }); //Move file there sf.file.move({ sourcePath: path, destinationPath: oldSessionsDir + '/' + filename, }); } sf.ui.proTools.mainWindow.invalidate(); var oldSessionPath = sf.ui.proTools.mainWindow.sessionPath; saveSessionAsNewVersion(); sf.wait({ intervalMs: 1000 }); moveFileToOldSessions(oldSessionPath);
Note, please test on a test session first, not on production session, since this handles files, so you want to be extra sure that it works as intended :)
Christian Scheuer @chrscheuer2019-11-18 20:38:51.669Z
@sbiss I edited my post with an update to the script, so please copy/paste it again
Christian Scheuer @chrscheuer2019-11-18 20:42:39.062Z
Actually I think my logic was flawed around the need for a "wait", since the script actually first saves the existing session, and then saves the new version. This way we should be sure that the existing file has been fully written by the time we get to moving the file. Of course that would need testing.
- SSteve Bissinger @sbiss2019-11-18 20:54:10.914Z
Works perfectly! Except it saves my "Session 01" as "Session 2". But that is a relatively minor issue.
- In reply tochrscheuer⬆:JJonathan Grossman @Jonathan_Grossman
This script works great....how can I add a function that creates a folder in the bounced mixes folder with the name of the current version session ending in MIXES AND STEMS
Christian Scheuer @chrscheuer2020-05-26 15:37:46.791Z
Something like this?
var sessionPath = sf.ui.proTools.mainWindow.sessionPath; var sessionDir = sessionPath.split('/').slice(0, -1).join('/'); var sessionName = sessionPath.split('/').slice(-1)[0].split('.').slice(0, -1).join('.'); var mixesDir = `${sessionDir}/Bounced Files/${sessionName} MIXES AND STEMS`; //Make sure the mixes directory exists sf.file.directoryCreate({ path: mixesDir, });
- JJonathan Grossman @Jonathan_Grossman
That ALMOST works...the new MIXES AND STEMS folder is created with the prior version ProTools session name, not the newly created one.
Christian Scheuer @chrscheuer2020-05-26 16:15:49.824Z
var sessionPath = sf.ui.proTools.mainWindow.invalidate().sessionPath; var sessionDir = sessionPath.split('/').slice(0, -1).join('/'); var sessionName = sessionPath.split('/').slice(-1)[0].split('.').slice(0, -1).join('.'); var mixesDir = `${sessionDir}/Bounced Files/${sessionName} MIXES AND STEMS`; //Make sure the mixes directory exists sf.file.directoryCreate({ path: mixesDir, });
- JJonathan Grossman @Jonathan_Grossman
Wammo!!!! Thank you Christian. Another 40 hours added to my free time by using efficicent macros!
Christian Scheuer @chrscheuer2020-05-26 16:20:43.824Z
Yay - awesome :D
- In reply toJonathan_Grossman⬆:SSteve Bissinger @sbiss2020-05-26 17:08:48.168Z
Just so I understand, are you inserting this script into the above script and if so where?
- JJonathan Grossman @Jonathan_Grossman
at the bottom
- In reply toJonathan_Grossman⬆:JJonathan Grossman @Jonathan_Grossman
Sooo....one thing I didn' think of.
I'd like to make the first MIXES AND STEMS FOLDER with the current version name. In other words, a macro that does what this one does, without doing the "save as" first.
Trying this....but not working.
var sessionPath = sf.ui.proTools.mainWindow.invalidate().sessionPath;
var sessionPath = sf.ui.proTools.mainWindow.sessionPath;
var sessionName = sessionPath.split('/').slice(-1)[0].split('.').slice(0, -1).join('.');
var mixesDir =${sessionDir}/Bounced Files/${sessionName}_MIXES AND STEMS
;//Make sure the mixes directory exists
sf.file.directoryCreate({
path: mixesDir,
});sf.appleScript.finder.open(newDir);
sf.ui.finder.appActivateMainWindow();
sf.ui.finder.windows.first.windowMove({
position: { x: 300, y: 200 },
size: { x: 1600, y: 500 },
});sf.wait({intervalMs:503});
//Make sure Pro Tools Main Window is active
sf.ui.proTools.appActivateMainWindow();
}
main();
- In reply tochrscheuer⬆:JJonathan Grossman @Jonathan_Grossman
so another mod on this one. I'd like the macro to save as & rename the session with the suffix "_MIX_V1" and create the folder with the session name +MIXES AND STEMS. However, if I already have a "MIX_V1", then I'd like it to go to the next number. Here's how I have created it in 2 different scripts (with obvious scripting repetition) that I'd like to simplify and marry into one script with an IF/THEN variable.
PART 1:
function saveSessionAsNewVersion() {
//First save the current version sf.ui.proTools.getMenuItem('File', 'Save').elementClick({}, function () { }); //can be disabled //Get our filename without extension var fileNameWithoutExtension = sf.ui.proTools.mainWindow.invalidate().sessionPath.split('/').slice(-1)[0].split('.').slice(0, -1).join('.'); //Create a new name (get the name and suffixed number - if your session name was 'My Session 42' then save 'My Session ' in grps[1] and '42' in grps[2]) var grps = fileNameWithoutExtension.match(/^(.+?)(\d+)$/); //Construct a new name based on the prefix + MIX_V1 var newName = (fileNameWithoutExtension) + '_MIX_V1.ptx'; //Invoke File Save As. sf.ui.proTools.getMenuItem('File', 'Save As...').elementClick(); //Wait for the Save dialog to appear var dlg = sf.ui.proTools.windows.invalidate().whoseTitle.is('Save').waitFor().element; //Enter the new name dlg.textFields.first.value.value = newName; //Click Save dlg.buttons.whoseTitle.is('Save').first.elementClick();
}
function moveFileToOldSessions(path) {
var oldSessionsDir = path.split('/').slice(0, -1).join('/') + '/Old Sessions';
var filename = path.split('/').slice(-1)[0];//Make sure "Old Sessions" dir exists sf.file.directoryCreate({ path: oldSessionsDir, }); //Move file there sf.file.move({ sourcePath: path, destinationPath: oldSessionsDir + '/' + filename, });
}
sf.ui.proTools.mainWindow.invalidate();
var oldSessionPath = sf.ui.proTools.mainWindow.sessionPath;saveSessionAsNewVersion();
sf.wait({ intervalMs: 1000 });
moveFileToOldSessions(oldSessionPath);
var sessionPath = sf.ui.proTools.mainWindow.invalidate().sessionPath;
var sessionDir = sessionPath.split('/').slice(0, -1).join('/');
var sessionName = sessionPath.split('/').slice(-1)[0].split('.').slice(0, -1).join('.');
var mixesDir =${sessionDir}/Bounced Files/${sessionName}_MIXES AND STEMS
;//Make sure the mixes directory exists
sf.file.directoryCreate({
path: mixesDir,
});PART 2:
function saveSessionAsNewVersion() {
//First save the current version sf.ui.proTools.getMenuItem('File', 'Save').elementClick({}, function () { }); //can be disabled //Get our filename without extension var fileNameWithoutExtension = sf.ui.proTools.mainWindow.invalidate().sessionPath.split('/').slice(-1)[0].split('.').slice(0, -1).join('.'); //Create a new name (get the name and suffixed number - if your session name was 'My Session 42' then save 'My Session ' in grps[1] and '42' in grps[2]) var grps = fileNameWithoutExtension.match(/^(.+?)(\d+)$/); //Construct a new name based on the prefix and the number (+1), followed by the '.ptx' suffix. If there was no number, just add ' 2' var newNumber = !grps || grps.length === 0 || isNaN(Number(grps[2])) ? '_2' : ((Number(grps[2]) + 1) + ''); var newName = (grps ? grps[1] : (fileNameWithoutExtension)) + newNumber + '.ptx'; //Invoke File Save As. sf.ui.proTools.getMenuItem('File', 'Save As...').elementClick(); //Wait for the Save dialog to appear var dlg = sf.ui.proTools.windows.invalidate().whoseTitle.is('Save').waitFor().element; //Enter the new name dlg.textFields.first.value.value = newName; //Click Save dlg.buttons.whoseTitle.is('Save').first.elementClick();
}
function moveFileToOldSessions(path) {
var oldSessionsDir = path.split('/').slice(0, -1).join('/') + '/Old Sessions';
var filename = path.split('/').slice(-1)[0];//Make sure "Old Sessions" dir exists sf.file.directoryCreate({ path: oldSessionsDir, }); //Move file there sf.file.move({ sourcePath: path, destinationPath: oldSessionsDir + '/' + filename, });
}
sf.ui.proTools.mainWindow.invalidate();
var oldSessionPath = sf.ui.proTools.mainWindow.sessionPath;saveSessionAsNewVersion();
sf.wait({ intervalMs: 1000 });
moveFileToOldSessions(oldSessionPath);
var sessionPath = sf.ui.proTools.mainWindow.invalidate().sessionPath;
var sessionDir = sessionPath.split('/').slice(0, -1).join('/');
var sessionName = sessionPath.split('/').slice(-1)[0].split('.').slice(0, -1).join('.');
var mixesDir =${sessionDir}/Bounced Files/${sessionName}_MIXES AND STEMS
;//Make sure the mixes directory exists
sf.file.directoryCreate({
path: mixesDir,
});
- In reply tochrscheuer⬆:MMatt Cahill @Matt_Cahill
Hi @chrscheuer
Trying to find your Pro Tools Utilities package but I can't see it on the store?
Christian Scheuer @chrscheuer2023-01-12 18:51:55.498Z
That has been deprecated in favor of the official Pro Tools package that comes with all versions of SF :)
- MMatt Cahill @Matt_Cahill
Okay awesome, thank you Christian!
- JIn reply tosbiss⬆:Jeremy Bowker @Jeremy_Bowker
This is all very impressive! Is there a way to have it "up-rev" a session when when an underscore and initials are appended to the end of a session name? Example: "SessionName_01_JD"
Christian Scheuer @chrscheuer2021-07-20 11:49:46.960Z
Hi Jeremy,
Try this (untested):
/**@callback OnGetNewNameCallback * @param {{ fileNameWithoutExtension: string }} args * @return {string} */ /** * @param {object} args * @param {OnGetNewNameCallback} args.onGetNewName */ function saveSessionAsNewVersion({ onGetNewName }) { //First save the current version sf.ui.proTools.getMenuItem('File', 'Save').elementClick({}, function () { }); //can be disabled //Get our filename without extension var fileNameWithoutExtension = sf.ui.proTools.mainWindow.invalidate().sessionPath.split('/').slice(-1)[0].split('.').slice(0, -1).join('.'); var newName = onGetNewName({ fileNameWithoutExtension }); //Invoke File Save As. sf.ui.proTools.getMenuItem('File', 'Save As...').elementClick(); //Wait for the Save dialog to appear var dlg = sf.ui.proTools.windows.invalidate().whoseTitle.is('Save').waitFor().element; //Enter the new name dlg.textFields.first.value.value = newName; //Click Save dlg.buttons.whoseTitle.is('Save').first.elementClick(); } /** * @param {string} path */ function moveFileToOldSessions(path) { var oldSessionsDir = path.split('/').slice(0, -1).join('/') + '/Old Sessions'; var filename = path.split('/').slice(-1)[0]; //Make sure "Old Sessions" dir exists sf.file.directoryCreate({ path: oldSessionsDir, }); //Move file there sf.file.move({ sourcePath: path, destinationPath: oldSessionsDir + '/' + filename, }); } function main() { sf.ui.proTools.mainWindow.invalidate(); var oldSessionPath = sf.ui.proTools.mainWindow.sessionPath; saveSessionAsNewVersion({ onGetNewName: ({ fileNameWithoutExtension }) => { //Create a new name (get the name and suffixed number - if your session name was 'My Session 42' then save 'My Session ' in grps[1] and '42' in grps[2]) var grps = fileNameWithoutExtension.match(/^(.+?)(\d+)(_[a-zA-Z]+)?$/); //Construct a new name based on the prefix and the number (+1), followed by a potential '_INITIALS' suffix, and then the '.ptx' extension. //If there was no number, just add '_2' var newNumber = !grps || grps.length === 0 || isNaN(Number(grps[2])) ? '_2' : ((Number(grps[2]) + 1) + ''); const str = s => s === undefined ? '' : s; var newName = (grps ? grps[1] : (fileNameWithoutExtension)) + newNumber + str(grps && grps[3]) + '.ptx'; return newName; } }); sf.wait({ intervalMs: 1000 }); moveFileToOldSessions(oldSessionPath); } main();
- JJeremy Bowker @Jeremy_Bowker
Well... THIS is amazing! Thank you. I ended up needing to add a brief wait right after "Invoke File Save As" and it works like a charm. Thank you @chrscheuer !
- SIn reply tosbiss⬆:Steve Bissinger @sbiss2021-07-20 16:46:27.385Z
This has been on my to do list. Amazing! Typically our naming uses "01", "02", etc, instead of "1", "2". Is there a tweak to add a zero until the version reaches "10"?
- AIn reply tosbiss⬆:Alvin Wee @Alvin_Wee
Following up on this guys. I modified one of script from here and it only works maybe 30% of the time to what Jeremy's saying
Context: I also add the "01" "02" and "03" for my save versions. I have a script here that i modified from one of the scripts here I seem to run into weird errors. like once it gets to the "Save as" window and then just freezing there wihtout chanign the numbers and after the delay just pops up the error message:
*Element was not found or removed after waiting 5000
ms (Save Session as New Version: Line 19)
*I'd appreciate any feedback. Thank you!
//First save the current version //sf.ui.proTools.getMenuItem('File', 'Save').elementClick({}, function(){}); //can be disabled //Get our filename without extension var fileNameWithoutExtension = sf.ui.proTools.mainWindow.invalidate().sessionPath.split('/').slice(-1)[0].split('.').slice(0, -1).join('.'); //Create a new name (get the name and suffixed number - if your session name was 'My Session 42' then save 'My Session ' in grps[1] and '42' in grps[2]) var grps = fileNameWithoutExtension.match(/^(.+?)(\d+)$/); //Construct a new name based on the prefix and the number (+1), followed by the '.ptx' suffix. If there was no number, just add '02' var newNumber = !grps || grps.length === 0 || isNaN(Number(grps[2])) ? '02' : ("0" + ((Number(grps[2]) + 1) + '')).slice(-2); var newName = (grps ? grps[1] : (fileNameWithoutExtension)) + newNumber; //Invoke File Save As. sf.ui.proTools.getMenuItem('File', 'Save As...').elementClick(); //Wait for the Save dialog to appear var dlg = sf.ui.proTools.windows.invalidate().whoseTitle.is('Save').waitFor().element; //Enter the new name dlg.textFields.first.value.value = newName; //sf.keyboard.type({ text: newName }); //Click Save dlg.buttons.whoseTitle.is('Save').first.elementClick();
EDITED becuase i pasted the wrong code.