Difference between revisions of "Afx Javascript Temp"

From bernie's
Jump to navigation Jump to search
Line 82: Line 82:
<pre>
<pre>
//todo: be able to select existing RQ items instead of simply comps, and edit their existing paths
//todo: be able to select existing RQ items instead of simply comps, and edit their existing paths
 
function e(s) {
 
$.writeln(s)
function e(s){$.writeln(s)} //debug fn
} //debug fn
 
var win;
var win;


function renderAll(){
function renderAll() {
//prefTemplate = (app.settings.haveSetting("renderCompWithTemplate", "template"))?(app.settings.getSetting("renderCompWithTemplate", "template")):false;
//prefTemplate = (app.settings.haveSetting("renderCompWithTemplate", "template"))?(app.settings.getSetting("renderCompWithTemplate", "template")):false;
sel = app.project.selection;
sel = app.project.selection;
if (sel.length > 0) {
if(sel.length>0){
 
//needs a comp to create a render item to get templates
//needs a comp to create a render item to get templates
getTemplateUI(sel[0]);
getTemplateUI(sel[0]);
//if ui worked fine, there should be a template setting string, if there's a bug or user cancelled, fuck it.
//if ui worked fine, there should be a template setting string, if there's a bug or user cancelled, fuck it.
 
prefTemplate = (app.settings.haveSetting("renderCompWithTemplate", "template")) ? (app.settings.getSetting("renderCompWithTemplate", "template")) : false;
prefTemplate = (app.settings.haveSetting("renderCompWithTemplate", "template"))?(app.settings.getSetting("renderCompWithTemplate", "template")):false;
if (prefTemplate != false && prefTemplate != "null") {
 
for (i = 0; i < sel.length; i++) {
if(prefTemplate != false && prefTemplate != "null" ){
renderCompWithTemplate(sel[i], prefTemplate)
for(i=0;i<sel.length;i++){
 
renderCompWithTemplate(sel[i],prefTemplate)  
 
}
}
 
} else {
}else{
 
 
writeLn("Send to renderqueue cancelled.");
writeLn("Send to renderqueue cancelled.");
}
}
}else{
} else {
alert("Select at least one comp or render queue element");
alert("Select at least one comp or render queue element");
}
}
}
}


function getTemplateUI(nullComp){
function getTemplateUI(nullComp) {
 
// get previous render settings, so we can use it as default selection later
// get previous render settings, so we can use it as default selection later
 
prefTemplate = (app.settings.haveSetting("renderCompWithTemplate", "template")) ? (app.settings.getSetting("renderCompWithTemplate", "template")) : false;
prefTemplate = (app.settings.haveSetting("renderCompWithTemplate", "template"))?(app.settings.getSetting("renderCompWithTemplate", "template")):false;
 
// void render settings if user clicks cancel, to be changed
// void render settings if user clicks cancel, to be changed
 
app.settings.saveSetting("renderCompWithTemplate", "template", "null");
app.settings.saveSetting("renderCompWithTemplate", "template","null");
 
ai = app.project.activeItem;
ai = app.project.activeItem;
// must have at least one comp selected, and the project saved to know where to place the renders
// must have at least one comp selected, and the project saved to know where to place the renders
// eventually the user shouldn't have to save his AEP, but have it appear as a warning somewhere that he should
// eventually the user shouldn't have to save his AEP, but have it appear as a warning somewhere that he should
 
if (nullComp != null && nullComp instanceof CompItem && app.project.file != null) {
if( nullComp != null && nullComp instanceof CompItem && app.project.file != null ){
rq = app.project.renderQueue;
rq = app.project.renderQueue;
//create null render comp to fetch templates, delete it right afterwards
//create null render comp to fetch templates, delete it right afterwards
 
rqitem = rq.items.add(nullComp);
rqitem = rq.items.add( nullComp );
rqtemplates = rqitem.outputModules[1].templates;
rqtemplates = rqitem.outputModules[1].templates;
rqitem.remove();
rqitem.remove();
// dockable window to do
// dockable window to do
//res = "dialog { properties:{ resizeable:true }, preferredSize: [690, 20],  alignChildren: 'fill',orientation:'column',\
//res = "dialog { properties:{ resizeable:true }, preferredSize: [690, 20],  alignChildren: 'fill',orientation:'column',\
Line 185: Line 155:
}, \
}, \
}";
}";
// get/set the display path preference (it will always be unix style internally) 1=windows 0=mac/unix
// get/set the display path preference (it will always be unix style internally) 1=windows 0=mac/unix
 
//input base text  
//input base text  
explanationText = "Here are variables you can use:\n";
explanationText = "Here are variables you can use:\n";
explanationText += "\t{compname} {compfolder} {projpath} {compid}\n";
explanationText += "\t{compname} {compfolder} {projpath} {compid}\n";
explanationText += "\t{projname} {date} (using date:y/m/d)";
explanationText += "\t{projname} {date} (using date:y/m/d)";
explanationText += "\t[#], [##], [####] (padding)\n";
explanationText += "\t[#], [##], [####] (padding)\n";
explanationText += "You can write '/../' to go 'up' one directory ";
explanationText += "You can write '/../' to go 'up' one directory ";
 
// create window resource
// create window resource
 
win = new Window(res);
win = new Window (res);
//set the preferred template
       
        //set the preferred template
 
preferredItem = 0;
preferredItem = 0;
 
for (i = 0; i < rqtemplates.length; i++) {
for(i=0;i<rqtemplates.length;i++){
 
//skip hidden templates
//skip hidden templates
if(rqtemplates[i].indexOf('_HIDDEN') != 0 ){
if (rqtemplates[i].indexOf('_HIDDEN') != 0) {
item = win.templatesPnl.templates.add ('item',rqtemplates[i]);
item = win.templatesPnl.templates.add('item', rqtemplates[i]);
if(rqtemplates[i] == prefTemplate){
if (rqtemplates[i] == prefTemplate) {
preferredItem = i;
preferredItem = i;
}
}
Line 219: Line 176:
}
}
win.templatesPnl.templates.selection = win.templatesPnl.templates.items[preferredItem];
win.templatesPnl.templates.selection = win.templatesPnl.templates.items[preferredItem];
// can't add newline \n character in res, so fill in text now
// can't add newline \n character in res, so fill in text now
win.filePnl.explainPathText.text = explanationText;
win.filePnl.explainPathText.text = explanationText;
// set os choice radio button, figure out if it's in prefs  
// set os choice radio button, figure out if it's in prefs  
// eventually users shouldn't see this, the script should be tailored for mac or windows
// eventually users shouldn't see this, the script should be tailored for mac or windows
os = $.os.toLowerCase().indexOf("windows") != -1;
os = $.os.toLowerCase().indexOf("windows") != -1;
 
if (app.settings.haveSetting("renderCompWithTemplate", "oschoice")) {
if( app.settings.haveSetting("renderCompWithTemplate", "oschoice") ){
os = (app.settings.getSetting("renderCompWithTemplate", "oschoice") == 1) ? 1 : 0;
os = ( app.settings.getSetting("renderCompWithTemplate", "oschoice") == 1 ) ? 1 : 0 ;
} else {
}else{
app.settings.saveSetting("renderCompWithTemplate", "oschoice", os);
app.settings.saveSetting("renderCompWithTemplate", "oschoice", os);
}
}
win.filePnl.pathRbs.unixStylePathRb.value = !os;
win.filePnl.pathRbs.unixStylePathRb.value = !os;
// set path template box, if it doesn't have one, use a default;
// set path template box, if it doesn't have one, use a default;
inputBox = win.filePnl.edithPathGrp.editPathBox;
inputBox = win.filePnl.edithPathGrp.editPathBox;
outPutBox = win.filePnl.showPathText;
outPutBox = win.filePnl.showPathText;
var pathTemplate = "";
var pathTemplate = "";
 
if (app.settings.haveSetting("renderCompWithTemplate", "pathtemplate")) {
if( app.settings.haveSetting("renderCompWithTemplate", "pathtemplate") ){
pathTemplate = app.settings.getSetting("renderCompWithTemplate", "pathtemplate");
pathTemplate = app.settings.getSetting("renderCompWithTemplate", "pathtemplate");
}else{
} else {
pathTemplate = "{projpath}/RENDER/{date:ymd}_{compname}/{compname}.[####]";
pathTemplate = "{projpath}/RENDER/{date:ymd}_{compname}/{compname}.[####]";
app.settings.saveSetting("renderCompWithTemplate", "pathtemplate", pathTemplate);
app.settings.saveSetting("renderCompWithTemplate", "pathtemplate", pathTemplate);
}
}
inputBox.text = pathTemplate;
inputBox.text = pathTemplate;
//add ui callbacks
//add ui callbacks
//call once, to fill the result text box
//call once, to fill the result text box
updatePath(inputBox, outPutBox);
updatePath(inputBox, outPutBox);
 
inputBox.onChange = inputBox.onChanging = function() {
inputBox.onChange = inputBox.onChanging = function() { updatePath(inputBox, outPutBox) };
updatePath(inputBox, outPutBox)
 
};
/*-----TO BE CUT---------*/
/*-----TO BE CUT---------*/
win.filePnl.pathRbs.unixStylePathRb.onClick = win.filePnl.pathRbs.winStylePathRb.onClick = function() {
win.filePnl.pathRbs.unixStylePathRb.onClick = win.filePnl.pathRbs.winStylePathRb.onClick = function() {
//save preferences
//save preferences
 
app.settings.saveSetting("renderCompWithTemplate", "oschoice", (!win.filePnl.pathRbs.unixStylePathRb.value) ? 1 : 0);
app.settings.saveSetting("renderCompWithTemplate", "oschoice", (!win.filePnl.pathRbs.unixStylePathRb.value)?1:0);
updatePath(inputBox, outPutBox);
updatePath(inputBox, outPutBox);
}
}
/*-----END CUT-----------*/
/*-----END CUT-----------*/
 
win.filePnl.edithPathGrp.testBtn.onClick = function() {
 
fp = descriptionToFilePath("", 1, inputBox.text, 0);
win.filePnl.edithPathGrp.testBtn.onClick = function(){
fp = descriptionToFilePath("",1,inputBox.text, 0);
fpFolder = new Folder(fp);
fpFolder = new Folder(fp);
e(fpFolder.absoluteURI);
e(fpFolder.absoluteURI);
}
}
 
win.buttons.okBtn.onClick = function() {
win.buttons.okBtn.onClick = function(){
//save preferences
//save preferences
prefTemplate = win.templatesPnl.templates.selection;
prefTemplate = win.templatesPnl.templates.selection;
app.settings.saveSetting("renderCompWithTemplate", "pathtemplate", inputBox.text);
app.settings.saveSetting("renderCompWithTemplate", "pathtemplate", inputBox.text);
//app.settings.saveSetting("renderCompWithTemplate", "oschoice", (!win.filePnl.pathRbs.unixStylePathRb.value)?1:0);
//app.settings.saveSetting("renderCompWithTemplate", "oschoice", (!win.filePnl.pathRbs.unixStylePathRb.value)?1:0);
app.settings.saveSetting("renderCompWithTemplate", "template",prefTemplate);
app.settings.saveSetting("renderCompWithTemplate", "template", prefTemplate);
win.close();
win.close();
}
}
win.layout.layout(true);
win.layout.layout(true);
 
win.onResizing = win.onResize = function() {
win.onResizing = win.onResize = function () {this.layout.resize()};
this.layout.resize()
};
win.center();
win.center();
win.show();
win.show();
 
} else {
}else{
 
//alert dialogs suck, but they are efficient
//alert dialogs suck, but they are efficient
alert("Select at least one comp to render, and make sure your After Effects file is saved to disk.");
alert("Select at least one comp to render, and make sure your After Effects file is saved to disk.");
}
}
}
}


function resizeUI(windowObj){
function resizeUI(windowObj) {
//nasty function which creates a new textbox to figure out how big the editbox is, so no text is clipped
//nasty function which creates a new textbox to figure out how big the editbox is, so no text is clipped
var textbox = windowObj.filePnl.edithPathGrp.editPathBox;
var textbox = windowObj.filePnl.edithPathGrp.editPathBox;
//var testbutton = windowObj.filePnl.edithPathGrp.testBtn;
//var testbutton = windowObj.filePnl.edithPathGrp.testBtn;
 
g = windowObj.filePnl.add("group", [0, 0, 0, 0]);
g = windowObj.filePnl.add("group", [0,0,0,0]);
g.enabled = g.visible = false;
g.enabled = g.visible = false;
tmp = g.add("edittext", undefined, textbox.text, {enabled:false, visible:false});
tmp = g.add("edittext", undefined, textbox.text, {
 
enabled: false,
visible: false
});
var preferredWidth = tmp.preferredSize[0];
var preferredWidth = tmp.preferredSize[0];
//e("newpref: "+r.preferredSize[0]);
//e("newpref: "+r.preferredSize[0]);
windowObj.filePnl.remove(g);
windowObj.filePnl.remove(g);
 
textbox.size = [preferredWidth, textbox.preferredSize[1]];
textbox.size = [preferredWidth, textbox.preferredSize[1] ];
//testbutton.size = testbutton.preferredSize;
//testbutton.size = testbutton.preferredSize;
windowObj.layout.layout(true);
windowObj.layout.layout(true);
}
}


function updatePath( inputRes, outputRes){
function updatePath(inputRes, outputRes) {
os = (app.settings.getSetting("renderCompWithTemplate", "oschoice") == 1) ? 1 : 0;
os = ( app.settings.getSetting("renderCompWithTemplate", "oschoice") == 1 ) ? 1 : 0 ;
input = inputRes.text;
input = inputRes.text;
 
input = descriptionToFilePath("", 1, input, 1);
input = descriptionToFilePath("",1,input, 1);
input = setPathStyle(input, !os); //backslashes to slashes
input = setPathStyle(input, !os) ; //backslashes to slashes
outputRes.text = input;
outputRes.text = input;
resizeUI(inputRes.parent.parent.parent);
resizeUI(inputRes.parent.parent.parent);
//windowObj.layout.layout(true);
//windowObj.layout.layout(true);
}
}


function descriptionToFilePath(comp, rqid, descriptionString,forDisplay){
function descriptionToFilePath(comp, rqid, descriptionString, forDisplay) {
 
// takes a description like {projpath}/{projname}_{compname}/{compname}_[#####] and transforms it into a usable unix path
// takes a description like {projpath}/{projname}_{compname}/{compname}_[#####] and transforms it into a usable unix path
// if there is no comp fed, use the first in the selection.
// if there is no comp fed, use the first in the selection.
// 'forDisplay' int decides if it's for display (add frame count and turn %20s to spaces) or actual path to be used
// 'forDisplay' int decides if it's for display (add frame count and turn %20s to spaces) or actual path to be used
// 'rqid' is the number of the comp in the renderqueue, default is 1
// 'rqid' is the number of the comp in the renderqueue, default is 1
var str = descriptionString;
var str = descriptionString;
 
if (comp == "" || comp == null) {
if(comp == "" || comp == null){
comp = app.project.selection[0];
comp = app.project.selection[0];
}
}
var projName = app.project.file.name.toString();
var projName = app.project.file.name.toString();
//standard stuff, comp path name etc....
//standard stuff, comp path name etc....
str = str.replace(/\{projpath\}/gi, app.project.file.path.toString());
str = str.replace(/\{projpath\}/gi, app.project.file.path.toString());
projName = projName.substr(0, projName.lastIndexOf('.')) || projName;
projName = projName.substr(0, projName.lastIndexOf('.')) || projName;
str = str.replace(/\{projname\}/gi, projName);
str = str.replace(/\{projname\}/gi, projName);
str = str.replace(/\{compname\}/gi, comp.name);
str = str.replace(/\{compname\}/gi, comp.name);
var parentFolder = (comp.parentFolder.name == "Root") ? "" : comp.parentFolder.name ;
var parentFolder = (comp.parentFolder.name == "Root") ? "" : comp.parentFolder.name;
str = str.replace(/\{compfolder\}/gi, parentFolder);
str = str.replace(/\{compfolder\}/gi, parentFolder);
//if we use {id}, make sure it's padded  
//if we use {id}, make sure it's padded  
var rq = app.project.renderQueue;
var rq = app.project.renderQueue;
str = str.replace(/\{id\}/gi, pad(rq.items.length.toString().length, rqid.toString(),"0") );
str = str.replace(/\{id\}/gi, pad(rq.items.length.toString().length, rqid.toString(), "0"));
 
 
//figure out padding, if it's forDisplay, show it to the user
//figure out padding, if it's forDisplay, show it to the user
startPad = str.indexOf("[#");
startPad = str.indexOf("[#");
endPad = str.lastIndexOf("#]");
endPad = str.lastIndexOf("#]");
 
if (startPad > 0 && endPad > 0 && endPad > startPad && forDisplay) {
if(startPad > 0 && endPad > 0 && endPad > startPad && forDisplay){
startFrame = comp.workAreaStart / comp.frameDuration;
startFrame = comp.workAreaStart/comp.frameDuration;
str = str.substring(0, startPad) + pad(endPad - startPad, startFrame.toString(), "0") + str.substring(endPad + 2, str.length);
str = str.substring(0,startPad)+pad(endPad-startPad, startFrame.toString(), "0")+str.substring(endPad+2,str.length);
}
}
//date
//date
var datesArray = str.split("{date:");
var datesArray = str.split("{date:");
var tempstr = "";
var tempstr = "";
 
if (datesArray.length > 0) {
if(datesArray.length > 0){
 
var today = new Date();
var today = new Date();
var dd = today.getDate().toString();
var dd = today.getDate().toString();
var mm = (today.getMonth()+1).toString();
var mm = (today.getMonth() + 1).toString();
var yyyy = today.getFullYear();
var yyyy = today.getFullYear();
tempstr = datesArray[0];
tempstr = datesArray[0];
 
for (i = 1; i < datesArray.length; i++) {
for(i = 1 ; i < datesArray.length; i++ ){
endBracketPos = datesArray[i].indexOf("}");
endBracketPos = datesArray[i].indexOf("}");
nextBracketPos = datesArray[i].indexOf("{");
nextBracketPos = datesArray[i].indexOf("{");
nextBracketPos = (nextBracketPos == -1)? 9999 : nextBracketPos; //case if date is the last used tag
nextBracketPos = (nextBracketPos == -1) ? 9999 : nextBracketPos; //case if date is the last used tag
if(endBracketPos > -1 && endBracketPos < nextBracketPos){
if (endBracketPos > -1 && endBracketPos < nextBracketPos) {
dateString = datesArray[i].substring(0, endBracketPos );
dateString = datesArray[i].substring(0, endBracketPos);
dateString = dateString.replace(/y/gi, yyyy);
dateString = dateString.replace(/y/gi, yyyy);
dateString = dateString.replace(/d/gi, pad(2, dd, "0"));
dateString = dateString.replace(/d/gi, pad(2, dd, "0"));
dateString = dateString.replace(/m/gi, pad(2, mm, "0"));
dateString = dateString.replace(/m/gi, pad(2, mm, "0"));
tempstr += dateString + datesArray[i].substring(endBracketPos+1,datesArray[i].length);
tempstr += dateString + datesArray[i].substring(endBracketPos + 1, datesArray[i].length);
}else{
} else {
tempstr = str;
tempstr = str;
}
}
Line 410: Line 316:
str = tempstr;
str = tempstr;
}
}
 
if (forDisplay) {
if(forDisplay){
str += ".ext";
str += ".ext";
}
}
return str;
return str;
}
}


function renderCompWithTemplate(comp,template){
function renderCompWithTemplate(comp, template) {
//sends the comp to the renderqueue with the selected file path, creating folders and subfolders if needed
//sends the comp to the renderqueue with the selected file path, creating folders and subfolders if needed
rq = app.project.renderQueue;
rq = app.project.renderQueue;
rqitem = rq.items.add(comp);
rqitem = rq.items.add(comp);
rqtemplates = rqitem.outputModules[1].templates;
rqtemplates = rqitem.outputModules[1].templates;
filename = app.project.file.name;
filename = app.project.file.name;
filepath = app.project.file.toString();
filepath = app.project.file.toString();
projpath = filepath.slice(0,filepath.length-filename.length);
projpath = filepath.slice(0, filepath.length - filename.length);
 
savePath = projpath + comp.name + "/" + filename.slice(0, filename.length - 4) + "/";
savePath = projpath+comp.name+"/"+filename.slice(0,filename.length-4)+"/";
saveFile = comp.name + ".[####].tif";
saveFile = comp.name+".[####].tif";
saveFolder = new Folder(savePath);
saveFolder = new Folder(savePath);
saveFolder.create();
saveFolder.create();
rqitem.outputModules[1].file = new File(savePath+"/"+saveFile);
rqitem.outputModules[1].file = new File(savePath + "/" + saveFile);
rqitem.outputModules[1].applyTemplate(template);
rqitem.outputModules[1].applyTemplate(template);
}
}


function setPathStyle(path, toUnixPath){
function setPathStyle(path, toUnixPath) {
// takes a string and creates either a unix path like /c/my%20folder/ if toUnixPath is set to true
// takes a string and creates either a unix path like /c/my%20folder/ if toUnixPath is set to true
// or a windows path like c:\my folder\. Returns false if there's a problem (tbd)
// or a windows path like c:\my folder\. Returns false if there's a problem (tbd)
if(!toUnixPath){
if (!toUnixPath) {
//unix -> win
//unix -> win
path = path.replace(/\//, "");
path = path.replace(/\//, "");
Line 448: Line 348:
path = path.replace(/\//g, "\\");
path = path.replace(/\//g, "\\");
path = path.charAt(0).toUpperCase() + path.slice(1);
path = path.charAt(0).toUpperCase() + path.slice(1);
}else{
} else {
path = "/"+path.replace(":\\", "/");
path = "/" + path.replace(":\\", "/");
path = path.replace(/\\/g, "/");
path = path.replace(/\\/g, "/");
path = path.replace(" ", "%20");
path = path.replace(" ", "%20");
Line 457: Line 357:
}
}


function pad(width, string, padding) {  
function pad(width, string, padding) {
return (width <= string.length) ? string : pad(width, padding + string, padding);
return (width <= string.length) ? string : pad(width, padding + string, padding);
}
}
renderAll();
renderAll();



Revision as of 12:43, 3 January 2024

Keyframes and Layers counter

wip, doesn't work with animated shapes for now


layersCount = 0;
keyframesCount = 0;
collection = app.project.items;
for(i = 1;i<=collection.length;i++){
    curItem = collection[i];
    if(curItem instanceof CompItem){
        len = curItem.layers.length;
        layersCount += len;
        for(j = 1;j<=len;j++){
            curLayer = curItem.layers[j];
            for(k = 1;k <= curLayer.numProperties;k++){
                for(l = 1;l <= curLayer.property(k).numProperties; l++){
                    //$.writeln(keyframesCount);
                    if(curLayer.property(k).property(l).numProperties>0){
                         for(m = 1;m <= curLayer.property(k).property(l).numProperties; m++){
                            nKeys = curLayer.property(k).property(l).property(m).numKeys;
                            if(nKeys > 0){
                                 keyframesCount += nKeys;
                            }
                            //ugh i wish i was better at recursiveness
                            //$.writeln(curLayer.property(k).property(l).property(m).matchName);
                            //$.writeln(curLayer.property(k).property(l).property(m).numKeys);     
                        }
                    }else{
                            nkeys = curLayer.property(k).property(l).numKeys;
                            if(nKeys > 0){
                                keyframesCount += nKeys;
                            }
                            //keyframesCount += curLayer.property(k).property(l).numKeys;
                            //$.writeln(curLayer.property(k).property(l).matchName);
                            //$.writeln(curLayer.property(k).property(l).numKeys);     
                    }
                }  
            }
        }
    }
}
alert(keyframesCount+" keyframes found and\n"+layersCount+" layers counted in the project");
    
    
function iterateProperties(prop){
           // $.writeln(prop.numProperties);    
    if(prop.numProperties > 0){
        for(i = 1;i<=prop.numProperties;i++){
            iterateProperties(prop.property(i));
        }
    }else{
    //    $.writeln(prop.matchName);
    }
    //$.writeln(prop.matchName);
}
//alert(app.project.items[2])

Batch render project items

Select project footage and it will render them with the chosen rq preset

template = "QTJPG2000"; // chosen by hand, for now

selectedItems = app.project.selection;
rq = app.project.renderQueue;

for(i=0;i<selectedItems.length;i++){
    
    item = selectedItems[i];
    path = item.mainSource.file.path.toString()+'/'+item.name;
    p = app.project.items.addComp(item.name,item.width,item.height,1.0,item.duration,item.frameRate);
    p.layers.add(item);
    rqitem = rq.items.add(p);
	rqitem.outputModules[1].file = new File(path);
	rqitem.outputModules[1].applyTemplate(template);
    
}

Auto Comp to Renderqueue with Template

//todo: be able to select existing RQ items instead of simply comps, and edit their existing paths
function e(s) {
	$.writeln(s)
} //debug fn
var win;

function renderAll() {
	//prefTemplate = (app.settings.haveSetting("renderCompWithTemplate", "template"))?(app.settings.getSetting("renderCompWithTemplate", "template")):false;
	sel = app.project.selection;
	if (sel.length > 0) {
		//needs a comp to create a render item to get templates
		getTemplateUI(sel[0]);
		//if ui worked fine, there should be a template setting string, if there's a bug or user cancelled, fuck it.
		prefTemplate = (app.settings.haveSetting("renderCompWithTemplate", "template")) ? (app.settings.getSetting("renderCompWithTemplate", "template")) : false;
		if (prefTemplate != false && prefTemplate != "null") {
			for (i = 0; i < sel.length; i++) {
				renderCompWithTemplate(sel[i], prefTemplate)
			}
		} else {
			writeLn("Send to renderqueue cancelled.");
		}
	} else {
		alert("Select at least one comp or render queue element");
	}
}

function getTemplateUI(nullComp) {
	// get previous render settings, so we can use it as default selection later
	prefTemplate = (app.settings.haveSetting("renderCompWithTemplate", "template")) ? (app.settings.getSetting("renderCompWithTemplate", "template")) : false;
	// void render settings if user clicks cancel, to be changed
	app.settings.saveSetting("renderCompWithTemplate", "template", "null");
	ai = app.project.activeItem;
	// must have at least one comp selected, and the project saved to know where to place the renders
	// eventually the user shouldn't have to save his AEP, but have it appear as a warning somewhere that he should
	if (nullComp != null && nullComp instanceof CompItem && app.project.file != null) {
		rq = app.project.renderQueue;
		//create null render comp to fetch templates, delete it right afterwards
		rqitem = rq.items.add(nullComp);
		rqtemplates = rqitem.outputModules[1].templates;
		rqitem.remove();
		// dockable window to do
		//res = "dialog { properties:{ resizeable:true }, preferredSize: [690, 20],  alignChildren: 'fill',orientation:'column',\
		res = "dialog {  \
				properties:{ resizeable:true }, alignChildren: 'fill',orientation:'column',\
				templatesPnl: Panel { \
					orientation:'column', alignChildren:['left', 'top'],text: 'Choose a rendering template',\
					templates: DropDownList {}, \
				}, \
				filePnl: Panel { \
					orientation:'column', alignChildren:['left', 'top'],text: 'Display Paths',\
					pathRbs: Group { \
						orientation:'row',  alignment: 'left', alignChildren:['left', 'bottom'] \
						txt: StaticText { alignment:'left', text:'File path style:' }, \
						unixStylePathRb: RadioButton { text:'Unix (mac)' }, \
						winStylePathRb: RadioButton { text:'Windows', value:true } \
					}, \
					showPathText: StaticText {alignment: 'fill'},  \
					edithPathGrp: Group { \
						orientation:'row', spacing:2, alignment: 'left', \
						editPathBox: EditText { alignment: ['fill','center'],  margins: 8, text:'', properties:{borderless:true}},  \
						testBtn: Button { alignement:[center','center'], text:'Test', properties:{name:'test'} } ,\
					}, \
					explainPathText: StaticText {alignment: 'fill', properties:{multiline: true } }, \
					explainPathTextGrp: Group { \
						orientation:'row',  alignment: 'left', alignChildren:['left', 'center'] \
						c1: StaticText {alignment: 'fill', properties:{multiline: true } },  \
						c2: StaticText {alignment: 'fill', properties:{multiline: true } } \
					}  \
				}, \
				buttons: Group { orientation: 'row', alignment: 'right', \
					okBtn: Button { text:'OK', properties:{name:'ok'} }, \
					cancelBtn: Button { text:'Cancel', properties:{name:'cancel'} }, \
				}, \
			}";
		// get/set the display path preference (it will always be unix style internally) 1=windows 0=mac/unix
		//input base text 
		explanationText = "Here are variables you can use:\n";
		explanationText += "\t{compname} {compfolder} {projpath} {compid}\n";
		explanationText += "\t{projname} {date} (using date:y/m/d)";
		explanationText += "\t[#], [##], [####] (padding)\n";
		explanationText += "You can write '/../' to go 'up' one directory ";
		// create window resource
		win = new Window(res);
		//set the preferred template
		preferredItem = 0;
		for (i = 0; i < rqtemplates.length; i++) {
			//skip hidden templates
			if (rqtemplates[i].indexOf('_HIDDEN') != 0) {
				item = win.templatesPnl.templates.add('item', rqtemplates[i]);
				if (rqtemplates[i] == prefTemplate) {
					preferredItem = i;
				}
			}
		}
		win.templatesPnl.templates.selection = win.templatesPnl.templates.items[preferredItem];
		// can't add newline \n character in res, so fill in text now
		win.filePnl.explainPathText.text = explanationText;
		// set os choice radio button, figure out if it's in prefs 
		// eventually users shouldn't see this, the script should be tailored for mac or windows
		os = $.os.toLowerCase().indexOf("windows") != -1;
		if (app.settings.haveSetting("renderCompWithTemplate", "oschoice")) {
			os = (app.settings.getSetting("renderCompWithTemplate", "oschoice") == 1) ? 1 : 0;
		} else {
			app.settings.saveSetting("renderCompWithTemplate", "oschoice", os);
		}
		win.filePnl.pathRbs.unixStylePathRb.value = !os;
		// set path template box, if it doesn't have one, use a default;
		inputBox = win.filePnl.edithPathGrp.editPathBox;
		outPutBox = win.filePnl.showPathText;
		var pathTemplate = "";
		if (app.settings.haveSetting("renderCompWithTemplate", "pathtemplate")) {
			pathTemplate = app.settings.getSetting("renderCompWithTemplate", "pathtemplate");
		} else {
			pathTemplate = "{projpath}/RENDER/{date:ymd}_{compname}/{compname}.[####]";
			app.settings.saveSetting("renderCompWithTemplate", "pathtemplate", pathTemplate);
		}
		inputBox.text = pathTemplate;
		//add ui callbacks
		//call once, to fill the result text box
		updatePath(inputBox, outPutBox);
		inputBox.onChange = inputBox.onChanging = function() {
			updatePath(inputBox, outPutBox)
		};
		/*-----TO BE CUT---------*/
		win.filePnl.pathRbs.unixStylePathRb.onClick = win.filePnl.pathRbs.winStylePathRb.onClick = function() {
			//save preferences
			app.settings.saveSetting("renderCompWithTemplate", "oschoice", (!win.filePnl.pathRbs.unixStylePathRb.value) ? 1 : 0);
			updatePath(inputBox, outPutBox);
		}
		/*-----END CUT-----------*/
		win.filePnl.edithPathGrp.testBtn.onClick = function() {
			fp = descriptionToFilePath("", 1, inputBox.text, 0);
			fpFolder = new Folder(fp);
			e(fpFolder.absoluteURI);
		}
		win.buttons.okBtn.onClick = function() {
			//save preferences
			prefTemplate = win.templatesPnl.templates.selection;
			app.settings.saveSetting("renderCompWithTemplate", "pathtemplate", inputBox.text);
			//app.settings.saveSetting("renderCompWithTemplate", "oschoice", (!win.filePnl.pathRbs.unixStylePathRb.value)?1:0);
			app.settings.saveSetting("renderCompWithTemplate", "template", prefTemplate);
			win.close();
		}
		win.layout.layout(true);
		win.onResizing = win.onResize = function() {
			this.layout.resize()
		};
		win.center();
		win.show();
	} else {
		//alert dialogs suck, but they are efficient
		alert("Select at least one comp to render, and make sure your After Effects file is saved to disk.");
	}
}

function resizeUI(windowObj) {
	//nasty function which creates a new textbox to figure out how big the editbox is, so no text is clipped
	var textbox = windowObj.filePnl.edithPathGrp.editPathBox;
	//var testbutton = windowObj.filePnl.edithPathGrp.testBtn;
	g = windowObj.filePnl.add("group", [0, 0, 0, 0]);
	g.enabled = g.visible = false;
	tmp = g.add("edittext", undefined, textbox.text, {
		enabled: false,
		visible: false
	});
	var preferredWidth = tmp.preferredSize[0];
	//e("newpref: "+r.preferredSize[0]);
	windowObj.filePnl.remove(g);
	textbox.size = [preferredWidth, textbox.preferredSize[1]];
	//testbutton.size = testbutton.preferredSize;
	windowObj.layout.layout(true);
}

function updatePath(inputRes, outputRes) {
	os = (app.settings.getSetting("renderCompWithTemplate", "oschoice") == 1) ? 1 : 0;
	input = inputRes.text;
	input = descriptionToFilePath("", 1, input, 1);
	input = setPathStyle(input, !os); //backslashes to slashes
	outputRes.text = input;
	resizeUI(inputRes.parent.parent.parent);
	//windowObj.layout.layout(true);
}

function descriptionToFilePath(comp, rqid, descriptionString, forDisplay) {
	// takes a description like {projpath}/{projname}_{compname}/{compname}_[#####] and transforms it into a usable unix path
	// if there is no comp fed, use the first in the selection.
	// 'forDisplay' int decides if it's for display (add frame count and turn %20s to spaces) or actual path to be used
	// 'rqid' is the number of the comp in the renderqueue, default is 1
	var str = descriptionString;
	if (comp == "" || comp == null) {
		comp = app.project.selection[0];
	}
	var projName = app.project.file.name.toString();
	//standard stuff, comp path name etc....
	str = str.replace(/\{projpath\}/gi, app.project.file.path.toString());
	projName = projName.substr(0, projName.lastIndexOf('.')) || projName;
	str = str.replace(/\{projname\}/gi, projName);
	str = str.replace(/\{compname\}/gi, comp.name);
	var parentFolder = (comp.parentFolder.name == "Root") ? "" : comp.parentFolder.name;
	str = str.replace(/\{compfolder\}/gi, parentFolder);
	//if we use {id}, make sure it's padded 
	var rq = app.project.renderQueue;
	str = str.replace(/\{id\}/gi, pad(rq.items.length.toString().length, rqid.toString(), "0"));
	//figure out padding, if it's forDisplay, show it to the user
	startPad = str.indexOf("[#");
	endPad = str.lastIndexOf("#]");
	if (startPad > 0 && endPad > 0 && endPad > startPad && forDisplay) {
		startFrame = comp.workAreaStart / comp.frameDuration;
		str = str.substring(0, startPad) + pad(endPad - startPad, startFrame.toString(), "0") + str.substring(endPad + 2, str.length);
	}
	//date
	var datesArray = str.split("{date:");
	var tempstr = "";
	if (datesArray.length > 0) {
		var today = new Date();
		var dd = today.getDate().toString();
		var mm = (today.getMonth() + 1).toString();
		var yyyy = today.getFullYear();
		tempstr = datesArray[0];
		for (i = 1; i < datesArray.length; i++) {
			endBracketPos = datesArray[i].indexOf("}");
			nextBracketPos = datesArray[i].indexOf("{");
			nextBracketPos = (nextBracketPos == -1) ? 9999 : nextBracketPos; //case if date is the last used tag
			if (endBracketPos > -1 && endBracketPos < nextBracketPos) {
				dateString = datesArray[i].substring(0, endBracketPos);
				dateString = dateString.replace(/y/gi, yyyy);
				dateString = dateString.replace(/d/gi, pad(2, dd, "0"));
				dateString = dateString.replace(/m/gi, pad(2, mm, "0"));
				tempstr += dateString + datesArray[i].substring(endBracketPos + 1, datesArray[i].length);
			} else {
				tempstr = str;
			}
		}
		str = tempstr;
	}
	if (forDisplay) {
		str += ".ext";
	}
	return str;
}

function renderCompWithTemplate(comp, template) {
	//sends the comp to the renderqueue with the selected file path, creating folders and subfolders if needed
	rq = app.project.renderQueue;
	rqitem = rq.items.add(comp);
	rqtemplates = rqitem.outputModules[1].templates;
	filename = app.project.file.name;
	filepath = app.project.file.toString();
	projpath = filepath.slice(0, filepath.length - filename.length);
	savePath = projpath + comp.name + "/" + filename.slice(0, filename.length - 4) + "/";
	saveFile = comp.name + ".[####].tif";
	saveFolder = new Folder(savePath);
	saveFolder.create();
	rqitem.outputModules[1].file = new File(savePath + "/" + saveFile);
	rqitem.outputModules[1].applyTemplate(template);
}

function setPathStyle(path, toUnixPath) {
	// takes a string and creates either a unix path like /c/my%20folder/ if toUnixPath is set to true
	// or a windows path like c:\my folder\. Returns false if there's a problem (tbd)
	if (!toUnixPath) {
		//unix -> win
		path = path.replace(/\//, "");
		path = path.replace(/\//, ":/");
		path = path.replace(/%20/g, " ");
		path = path.replace(/\//g, "\\");
		path = path.charAt(0).toUpperCase() + path.slice(1);
	} else {
		path = "/" + path.replace(":\\", "/");
		path = path.replace(/\\/g, "/");
		path = path.replace(" ", "%20");
		//path = path.substring(0,path.lastIndexOf("/"));
	}
	return path;
}

function pad(width, string, padding) {
	return (width <= string.length) ? string : pad(width, padding + string, padding);
}
renderAll();

create effect creator

ui

function e(s){
	$.writeln(s);
}

/*

var windowObj;
function ui(thisObj) {
	windowObj = (thisObj instanceof Panel) ? thisObj : new Window("palette", "ui_test", [100, 100, 300, 300]);
	addButton("flip",windowObj);
	return windowObj;
}*/


function addButton(buttonname,ui){
	//ui.add("button", [0, 0, 20, 20], But_01[0]);
	return ui.add("button", undefined, buttonname);
}





function ui(thisObj){
    pan = (thisObj instanceof Panel) ? thisObj : new Window("palette", "Watchfolder", [100, 100, 300, 300]);
    var securitySetting = app.preferences.getPrefAsLong("Main Pref Section", "Pref_SCRIPTING_FILE_NETWORK_SECURITY");
    if (securitySetting != 1) {
        pan.add("statictext",[15,15,300,45],"Set prefs and re-launch");
        alert("You need to check \"Allow Scripts to Write Files and Access Network\" in your preferences for this script to work");
     }else{
                var res = 
            "group { \
                        alignment: ['fill','fill'], \
                        alignChildren: ['fill','top'], \
                        orientation: 'column', \
                            setWF: Button {text: 'add btn' ,preferredSize:[-1,30]} , \
                            sendWF: Button {text: 'Send To Watchfolder' ,preferredSize:[-1,30]} , \
                    }";	
            pan.grp = pan.add(res);        
            pan.grp.setWF.onClick = function () {
            	addButton("joe",pan.grp);
            	resfreshUI(pan);
                    }
            pan.grp.sendWF.onClick = function () {
                }
            resfreshUI(pan);    
            /*
            pan.layout.layout(true);
            pan.layout.resize();
            pan.onResizing = pan.onResize = function () {this.layout.resize();}*/
            return pan;
    }
}

function resfreshUI(src){
	src.layout.layout(true);
	src.layout.resize();
	src.onResizing = pan.onResize = function () {this.layout.resize();}

}

ui(this);


fn

function e(s){
	$.writeln(s);
}

// to be done:
// 		save keys
// 		save masks
//		save text if text layer, camera zoom if camera etc
//		use FFX as custom values

function grabEffects(layers){
	
	var buffer = "";
	var chosenLayerName = "curLayer";

	for (i=0;i<layers.length;i++){

		effs = layers[i].property("ADBE Effect Parade");

		for(j=1;j<=effs.numProperties;j++){

			//create the effects, no matter if properties below have values

			buffer += "\n\tprop = "+ chosenLayerName +".Effects.addProperty(\""+ effs.property(j).matchName +"\");\n";
			buffer += "\tprop.name = \""+ effs.property(j).name +"\";\n";
			buffer += "\tprop.enabled = "+ effs.property(j).enabled +";\n";

			for(k=1;k<=effs.property(j).numProperties;k++){

				curProp = effs.property(j).property(k);
				
				//only add value if it's non-default

				if(curProp.isModified){

					curPropValue = propType(curProp);

					// if it returns -1, it's (probably) a useless 'parent' property, skip

					if( curPropValue != -1){
						
						// /!\ if it'sa  custom value type, there's little to no way of using it in a script, so we can comment it out and warn the user -- there are also false positives, ^but they should be ignored with '-1' as curpropvalue

						buffer += "\t\t// "+curProp.name+((curPropValue===false)?" /!\\ Can't use this custom data! could be a false negative, but unlikely ":"")+"\n";                                        
						buffer += "\t\t"+((curPropValue===false)?"//":"") + "prop.property(\""+curProp.matchName+"\").setValue(" + curPropValue + ");\n";
						
						// if there is an expression and it's enabled, use it

						if(curProp.expression != "" && curProp.expressionEnabled){
							buffer += "\t\t"+((curPropValue===false)?"//":"") + "prop.property(\""+curProp.matchName+"\").expression = \""+curProp.expression+"\";\n";
						}
					}
				}
			}
		}
	}

	return buffer;
}

function outputCode(){
	
	effectsLayers = app.project.activeItem.selectedLayers; //use effects from all selected layers

	buffer = "";
	if(effectsLayers.length>0){
		buffer = "var selectedLayers = app.project.activeItem.selectedLayers;\n";
		buffer += "for (i=0;i<selectedLayers.length;i++){\n";
		buffer += "\n\tcurLayer = selectedLayers[i];\n"; 
		buffer += grabEffects(effectsLayers) + "\n}";
		//e(buffer);
	}
	return buffer;
}


e(outputCode());
e("\n------------------------------------------------------");


 function propType(property){

	returnvalue = false;
	
	e("--->"+property.name+" "+property.propertyValueType+"\n"); //debug
	//e("--->"+property.name+" "+property.canVaryOverTime+"\n"); //debug		
	
	switch(property.propertyValueType){

		case PropertyValueType.ThreeD_SPATIAL:
			returnvalue = "["+property.value[0]+","+property.value[1]+","+property.value[2]+"]";
			break;
		case PropertyValueType.ThreeD:
			returnvalue = "["+property.value[0]+","+property.value[1]+","+property.value[2]+"]";
			break;

		case PropertyValueType.TwoD_SPATIAL:
			returnvalue = "["+property.value[0]+","+property.value[1]+"]";
			break;
		case PropertyValueType.TwoD:
			returnvalue = "["+property.value[0]+","+property.value[1]+"]";
			break;			

		case PropertyValueType.OneD:
			returnvalue = property.value;
			break;		

		case PropertyValueType.COLOR:
			returnvalue = "["+property.value[0]+","+property.value[1]+","+property.value[2]+","+property.value[3]+"]";
			break;

		case PropertyValueType.LAYER_INDEX:
			returnvalue = property.value;
			break;

		case PropertyValueType.MASK_INDEX:
			returnvalue = property.value;
			break;			

		//no way to store custom value but FFX, tbd
		case PropertyValueType.CUSTOM_VALUE:
			returnvalue = false;
			break;

		// if we land on default, it is _most likely_ a property 'parent' with no real use
		default:
			//e("using default: --->"+property.name+" "+property.propertyValueType+"\n")
			returnvalue = -1;
			break;
	}
	return (returnvalue);
 }

left to right

function e(s){
	//debug
    $.writeln(s);
}


function replaceLR(s){
    
    s = s.replace(/left/g, "right");
    s = s.replace(/Left/g, "Right");
    s = s.replace(/LEFT/, "RIGHT");
    return s;
}


function checkImportLeftRight(layer){

	// is it a footage layer (includes solids etc.. not Comps)
	if(layer.source instanceof FootageItem){
		
		//is it a footage item (.exr)
		if(layer.source.file != null){
			path = layer.source.mainSource.file.toString();
	
			 //check path, if it has 'left' in it, grab 'right' and import and replace footage
			if(path.toLowerCase().indexOf("left") > -1){

				rightPath = replaceLR(path);
				rightFile = new File(replaceLR(path));

				//if file exists, import right file, replace layer with it
				if(rightFile.exists){
					
					
					var io = new ImportOptions(rightFile);
					if(io.canImportAs(ImportAsType.FOOTAGE)){
					
						io.importAs = ImportAsType.FOOTAGE;
						io.sequence = true;
						src = app.project.importFile(io);
						
						return(layer.replaceSource(src,1));
						
					}else{
						return false
					}



				}else{
					alert("file not found! "+rightPath);
					return false
				}
			}
	
		}
	}
}

/*
a = app.project.activeItem;

for(i=1;i<=a.layers.length;i++){
 //e(a.layers[i].name);
 e(checkImportLeftRight(a.layers[i]));
    //if it's footage

}

for(i = 1;i<app.project.numItems;i++){
	e(i+" "+app.project.items[i].name); 
}
// 3 and 4
*/
function new3dComp(leftcomp,rightcomp){
	threedcomp = leftcomp.name.replace(/left/g,"3D");
	w = leftcomp.width;
	h = leftcomp.height;
	duration = leftcomp.duration;
	frameRate = leftcomp.frameRate;
	newComp = app.project.items.addComp(threedcomp, w , h , 1.0, duration, frameRate);


	
	newComp.layers.add(rightcomp);
	newComp.layers.add(leftcomp);
	
	threed = newComp.layers.addSolid([1,1,1],"3D Glasses",w,h,1.0);
	threed.adjustmentLayer = true;
	
	threedglasses = threed.Effects.addProperty("ADBE 3D Glasses2");
	threedglasses.property("Left View").setValue(2);
	threedglasses.property("Right View").setValue(3);
	threedglasses.property("3D View").setValue(12);

}
new3dComp(app.project.items[3],app.project.items[4]);



//e(app.project.activeItem.name+" --- ")

Output .SRT from layer markers

function pad10(n){
    return (n<10)?"0"+n:n;
}
function pad100(n){
    return (n<100)?"0"+pad10(n):n;
}

function formatTime(time){
    time =~~ (time*1000)/1000;

    var hrs = ~~(time / 3600);
    var mins = ~~((time % 3600) / 60);
    var secs =  ~~(time % 60);    
    var ms = ~~((time-Math.floor(time))*1000);
    
    time = pad10(hrs)+":"+pad10(mins)+":"+pad10(secs)+","+pad100(ms);
    return time;
}

data = "";
var ai = app.project.activeItem;
if ( ai instanceof CompItem && ai.selectedLayers.length == 1) {
    var m = ai.selectedLayers[0].marker;
    for(i=1;i<=m.numKeys;i++){
        data += i;
        data += "\n"+ formatTime(m.keyTime(i))+" --> "+ formatTime(m.keyTime(i)+m.keyValue(i).duration);
        data += "\n"+m.keyValue(i).comment;
        data += "\n";
       }
}


alert(data)

//result:
//
//1
//00:03:16,945 --> 00:03:17,364
//testing comment 1
//
//2
//01:59:47,228 --> 01:59:49,396
//second subtitle at 2 hours in
//

Shift keys

function e(str){
      $.writeln(str);
}
function getLayerFromProperty(prop){
    return prop.propertyGroup(prop.propertyDepth)
}
var c = app.project.activeItem;
if( c != null){
    var props = c.selectedProperties;

    //e(props[0].matchName);
    for(i = 0;i<props.length;i++){
        e("\n---------------------------\n"+props[i].matchName+" / "+getLayerFromProperty(props[i]).name);
        k = props[i].selectedKeys;
        for(keyVar in k){
            //k[keyVar]
            
            
           // e( ); 
           e(props[i].keyTime(k[keyVar])); 
           //e(k[keyVar]); 
        }
    //CANT FUCKING NUDGE KEYFRAMES
      //  e(props[i].selectedKeys);
    }
}



Selection tool palette

{
//tmpdir = $.getenv("tmp");
    function toolWindow(thisObj){
        function drawUI(){
            var my_palette = new Window("palette","Selection Tool");
            my_palette.bounds = [300,200,300,285];
            /*var button1 = addScriptButton(my_palette,[l_button_left,   5, l_button_right, 25], 
                    "Find and Replace Text",    demosDirectory, "Find and Replace Text.jsx");
            var button3 = addScriptButton(my_palette,[l_button_left,  30, l_button_right, 50], 
                    "Scale Composition", 		demosDirectory, "Scale Composition.jsx");
            var button4 = addScriptButton(my_palette,[l_button_left,  55, l_button_right, 75], 
                    "Scale Selected Layers", demosDirectory, "Scale Selected Layers.jsx");

            var button6 = addScriptButton(my_palette,[r_button_left,   5, r_button_right, 25], 
                    "Sort Layers by In Point",     demosDirectory, "Sort Layers by In Point.jsx");
            var button8 = addScriptButton(my_palette,[r_button_left,  30, r_button_right, 50], 
                    "Render and Email",    myDirectory,    "Render and Email.jsx");

            var button12 = addHelpButton(my_palette,[r_button_left,  55, r_button_right, 75]);*/

            my_palette.show();
        }
    drawUI();
    }
 toolWindow(this);
}

Make .bat file (WIP)

function pathToWinPath(path){
    var str = path.toString().replace(/\//, "");
    str = str.replace(/\//, ":/");
    str = str.replace(/%20/g, " ");
    str = str.replace(/\//g, "\\");
    return str;
}


function createBat(){
    d = new Date();
    m = d.getMonth()+1;
    j = d.getDate();
    if(m<10){
        m="0"+m;
    }
    if(j<10){
        j="0"+j;
    }

    var txtFile = new File("~/Desktop/ae_render"+m+"_"+j+".bat");
    alert(pathToWinPath(app.project.file));
    txtFile.open("w","TEXT","????");
    txtFile.close();
}

res =
"dialog { \
    allGroups: Panel {\
        orientation:'column',\
        alignChildren:'fill',\
        text:'Options', \
        chckOff: Checkbox {text:'Shutdown PC when finished'}, \
        chckAppend: Checkbox {text:'Append (instead of overwriting)'},\
        aePath: Group {orientation:'row',align:'fill', alignChildren:['fill','center'],\
            aeLocBtn: Button {text:' aerender.exe location : '}, \
            aeLocTst: StaticText {text:'C:\\Program fil...'}} \
        okCancel: Group {orientation:'row',align:'fill', alignChildren:'center',\
            okBtn: Button { text:'OK', properties:{name:'ok'}} , \
            cancelBtn: Button { text:'Cancel', properties:{name:'cancel'}},\
        }\
    }\
}";

win = new Window (res);
win.allGroups.chckAppend.value = true;
win.center();
win.show();

Carnet De Voyage rangement

//rangement pour carnet de voyage
app.beginUndoGroup("CDV Rangement");
boolVal = false;
sel = app.project.selection;
if(sel.length == 1){
    shot = sel[0];
    allItems = app.project.items;
    sortItems = new Array();
    for(i=1;i<=allItems.length;i++){
        if(!(allItems[i] instanceof FolderItem)){
            if(allItems[i].parentFolder.name == "Root"){
                sortItems[sortItems.length] = allItems[i];
            }
        }else{
            if(allItems[i].parentFolder.name == "Root"){
                    sortItems[sortItems.length] = allItems[i];
            }        
        }
    }
    t = app.project.items.addFolder("ELMTS");
    for(i=0;i<=sortItems.length-1;i++){
        if(sortItems[i] != shot){
        sortItems[i].parentFolder = t;
        }
    }
}
if(app.project.renderQueue.item(1).outputModules.length == 2){ //copie d'un output module à la main nécéssaire
    fileP = app.project.renderQueue.item(1).outputModules[1].file.toString();
    fileP = fileP.replace("/m/EPISODE","/b/EPISODE");
    fileP = new File(fileP);
    app.project.renderQueue.item(1).outputModules[2].file = fileP;
    app.project.renderQueue.item(1).outputModules[2].applyTemplate("PNGSeq");
    var curFile = app.project.file.name;
    curFile = curFile.substring(0,curFile.length-4);
    var pth = app.project.file.path+"/"+curFile+"_MOV+PNG.aep";
    var mySaveFile = new File(pth);        
    app.project.save(mySaveFile);
}else{
    writeLn("Duplicate output modules first");
}
app.endUndoGroup();

Chat

JSX

var myPalette = buildUI(this);

    if (myPalette != null && myPalette instanceof Window) {
        myPalette.show()
        }

    function buildUI (thisObject) {

    if (thisObject instanceof Panel) {
        var myWindow = thisObject;
        } else { 
        var myWindow = new Window ("palette", "My Window");
        }

g = myWindow.add("group");
g.orientation = "row";
g.alignChildren = "left";
//g.alignement = "top";
bt1 = g.add("button",undefined,"test");
bt1.onClick = bob;
//myWindow.myPanel.titleText = myWindow.myPanel.add("staticText");
//myWindow.myPanel.titleText.text =  "Move After Render v1.0";  

myWindow.layout.layout(true);
//myWindow.layout = new AutoLayoutManager(myWindow);
//myWindow.layout.resize();
return myWindow;
} 
h = 0;
function bob(){
//    alert();
    w = this.parent.parent;
    p = this.parent;
    h++;
    bt2 = p.add("button",undefined,"test"+h);  
      bt2.alignement = ["left","top"];
    if(h%3==0){

       
        bt2.helpTip = "TTTTT";
        }
    bt2.onClick = flup;
   //w.update();
   w.layout.layout(1); 
  // w.layout.resize();

//    w.show();
    }

function flup(){
    f = new Folder($.fileName);
    f = new Folder(f.parent+"/shelves/");
   if(!f.exists){f.create()};
    cfg = new File(f.parent+"/shelves/shelves.cfg");
    cfg.open('e');
    cfg.write(this.onClick);
    cfg.close();
    cfg.execute();
}
function pop(){
    f = new Folder($.fileName);
    fi = new File(f.parent+"/shelves/testShelf.jsx");
    fi.open('e');
    eval(fi.read());
    }
----------------
function grab(){
    var reply = "";
    c = new Socket;
    if (c.open ("berniebernie.fr:80")) {
        if(c.writeln ("GET /dump/afx/chat.php  HTTP/1.0\nHost: berniebernie.fr\n")){
            reply = decodeURIComponent(c.read(1000));
            reply = reply.split("--afx chat file log--");
            reply = reply[1];
        }else{
             return 0;
        }
        c.close();
    }else{
             return 0;
    }
    return reply;
}
function talk(str){
    var reply = "";
    c = new Socket;
    if (c.open ("berniebernie.fr:80")) {
        if(c.writeln ("GET /dump/afx/chat.php?msg="+str+"  HTTP/1.0\nHost: berniebernie.fr\n")){
            reply = decodeURIComponent(c.read(1000));
            reply = reply.split("--afx chat file log--");
            reply = reply[1];
        }else{
             return 0;
        }
        c.close();
    }else{
             return 0;
    }
    return reply;
}
//alert(grab());
alert(talk("flipflap"));

////////////////
app.preferences.getPrefAsLong("Main Pref Section","Pref_SCRIPTING_FILE_NETWORK_SECURITY"

Php

<?php
$myFile = "testFile.txt";
if(isset($_GET['msg']) && $_GET['msg'] != ""){
    $fh = fopen($myFile, 'a') or die("can't open file");
    fwrite($fh, ($_GET['msg']."\n"));
    fclose($fh);    
}else{
    //$fh = fopen($myFile, 'r') or die("can't open file");
    //include$str = $str, true);
    //header("Content-Type: plain/text"); 
    echo encodeURIComponent(file_get_contents("testFile.txt"));
    //echo nl2br(htmlentities(file_get_contents("testFile.txt")));
}

?>