Afx Javascript Temp

From bernie's
Jump to navigation Jump to search

PNG to image source


var path = '/c/temp/temp2/';
items = ['blue','red','red_o','green','green_o','gray','gray_o'];


var myFile = new File("/c/temp/temp2/pngs.txt");
myFile.open("w");
myFile.encoding = "UTF-8";

var text = "";

for (var i = 0, len = items.length; i < len; i++) {
item = items[i];


    var f = File(path+item+'.png');
    f.encoding = 'BINARY';
    f.open('e');

    var binary;
    binary = f.read().toSource();

    //var myFile = new File("/c/temp/temp2/"+item+".txt");
//            myFile.open("w");
//            myFile.encoding = "UTF-8";
text += item + " = ";

temp = binary.toString();
temp = temp.replace('(new String(','');
temp = temp.replace('))',';');


text += temp;
text += '\n';
            //myFile.write(binary.toString());
            //myFile.write('\n\n');
//            myFile.close();

    //$.writeln(binary);

    f.close();
}


myFile.write(text);

myFile.close();

Watchfolder watcher

tb integrated

//  watchwatchfolder: a tool to look at what's in the watchfolder
//  v1.0 by bernie - mbernadat@gmail.com
//
//
// icons by Mark Jame - http://www.famfamfam.com/lab/icons/silk/ licensed under a Creative Commons Attribution 2.5 License. 
//
//  known limitations (v1.0), to be fixed:
//  -windows only for now
//  -only looks at 1 renderqueue element per AEP file.
//
//
// I coded this like a dirty monkey. I feel sorry if you have to look at this.

// v1.1 updated this 15 year old script for a job, surprised that it still worked-ish!
// 

{
var wf = app.settings.haveSetting("watchwatchfolder", "wfloc")?new Folder(app.settings.getSetting("watchwatchfolder", "wfloc")):null;
var scriptFile = new File($.fileName);
var scriptFolder = scriptFile.parent; //png icons should be here
b=0; //global string that will store the 
var cancelTaskID;
var pal;
var timer = 0;
var refreshRate = 5;  //seconds
var reloadEditTxt;
var firstTime = true;
var shotinfos = new Array();

//global ui names
var refreshBtn;
var list;
var wfStText;
var wfPbar;
var chckBox0;
var chckBox1;
var chckBox2;
var chckBox3;


//states
// 0 - queued, paused           -> gray_o
// 1 - queued, ready to start   -> green_o
// 1 - done, no errors          -> green
// 2 - canceled, errors         -> red
// 3 - paused (?)               -> gray
// 4 - in progress              -> blue



//ui pngs


blue = "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\b\x06\x00\x00\x00\x1F\u00F3\u00FFa\x00\x00\x00\tpHYs\x00\x00\t\u00D7\x00\x00\t\u00D7\x01\u00B1n\x17\u00B7\x00\x00\x00\x19tEXtSoftware\x00www.inkscape.org\u009B\u00EE<\x1A\x00\x00\x00\u00DCIDAT8\u008D\u00A5\u0093\u00B1N\x02A\x14E\u00CF{\u00BB\u0089T\x04$F\u00D8\u0086\u00CE\u00BF\u00D0\u00DE\u00D2X\u0091\u00F8!\u00FE\x0B\u008D\u0095%\r\u00FE\u0085\u00DD~\x01\x1D\x18-\u008C\x15[8\u00D7\u008250\u0082\u00D9\u00D9\u00EC\u00ADf\u0092w\u00CF\u00DC\u00FB\u00921It\u0091wr\x03\u00F9\u00E1\u00C5\x16\u00EF7`s\u00CC\u00F3\u00FF\f;iK\u00F0\u0099\u00EE\u0087e<\u0098e\x0F\x04]AS-Ux\u00B8\x06\u00CA\u00B8\u00824M\u00CAmV!{\u0083\u00BF;\u0090M\u0092\x00\u00B2@\u00F6}\x02\u0080.\u0092\x00(#\u009CL\u00C0 \u00CD\u00CF\x19=\u00DFD\x00{Z\u00F50\x1A\u00B6_\u00CBq\u00DD\u009E\x7F\u00C5\t\u00FA\u0083K\u00D4\u00B8\u00FE\u009D\x02\x1F\u00BF\u00C7\u0083\x17\u00C3\x04c\x03<7\u00D8\x05\u00FEr\f0\x15\u00C0\u00AB\u00EEF\u008FI)j\u00ED+\x18\x05\u00B0nc\u008E\x01b\\Wh\u00A5}\x05g\u0089\u00E9\u00B3-\u00C0\u00BA~\u00E7\x1F\u0090\u00E3<q\u00B2\\\x19\u00D4\x00\x00\x00\x00IEND\u00AEB`\u0082";
red = "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\b\x06\x00\x00\x00\x1F\u00F3\u00FFa\x00\x00\x00\tpHYs\x00\x00\t\u00D7\x00\x00\t\u00D7\x01\u00B1n\x17\u00B7\x00\x00\x00\x19tEXtSoftware\x00www.inkscape.org\u009B\u00EE<\x1A\x00\x00\x00\u00E5IDAT8\u008D\u00A5\u0093;N\x031\x14E\u00CF\u00F5D\u0090\u0092\x06\u0085\u00A4\u00A1c\x01\x14tD\u00CA&\u0090\"X\b{\u00A1\u00A1\u00A2\u00A0%\u008B\x18\th\u00B2\t\x06)\x05P\u0091(\u00E3KE\x14gD\u00F0h^eK>\u00E7}l\u00CB6]\"t\u00A2\u0081\u00DE\u00F6\u00E6\u00F1\u00E2|l\u00B8\u00B3\u00D4\u00FB\x0B\x00\x10|G1\u009D\u0096\u00AF\u00F3\u00F4`\b7\u00D8g\u00FA'\u00AB\u00F0R\u00E8\x12\u0098'-\u00D8\u009C\u00E6\u0094m\u00C2\x12\u00FC\x0E\u00BB3\u00B0\u00879\x02\u00E1\u0088\u00D5\x14H:\u00CE\x11\u0080\nQ7\x05\u00C6G9\u00B8\u00F1\u00E1Z\u00FD*\x11\u00DCO&}vneO\u0084\u00EB\u00B2\u00FCJ\x04\x07\u00AB\u00CF\x01\u0090\u00FB\u00AA\x16\u00BF\u008BM\u00C6\u00A2\u00D6\x10\u00A8\u0084\x1E\u00F6\u0091V\u00B4\u00EAb\u00D6\x10\x10\x19\x11x\u00BE*_n3\u00AB\x00\u00B6\u0087(F\u008A\u00BC\u00B5\u0081S\x01\u009C\u0080\u00AB\u00B6\u0082M\x0B\x0Ez\n\u00EB\u00F0\u00D1V\u00A0\u00AE\u00DF\u00F9\x07\x1F\u0090C\u00FA\u00D1U\r\x03\x00\x00\x00\x00IEND\u00AEB`\u0082";
red_o = "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\b\x06\x00\x00\x00\x1F\u00F3\u00FFa\x00\x00\x00\tpHYs\x00\x00\t\u00D7\x00\x00\t\u00D7\x01\u00B1n\x17\u00B7\x00\x00\x00\x19tEXtSoftware\x00www.inkscape.org\u009B\u00EE<\x1A\x00\x00\x00\u00FEIDAT8\u008D\u00A5\u00931N\x02A\x18\u0085\u00BF7\x18C,L\u00AC\x168\u00C6\u00C6@\u00A5\u00E1\x10\u00C6hg\u00EB\t\u00F0\f^\u00C2\x16\u00B0\u00E4\x02\u0094\u009B(\x16\u009E\u00C1D\u00E9\u00A4\u00D1\u00A8\u00EC\u00FC6\u00EE\u00C2\u00AC\u00BA,\u00D9\u0097L\u00F16\u00EF\u00FFf\u00E7MFfF\x1D\u00B9Z\u00D3\u00C0\u00CE\u00BA\x19w\u00E3c\u0093\u00AE\u008B\u00DF\u00FF\u00D0\u0087\x17\u0097\u00E7\u00C9\u00EC1\b\u009A\u00DC\u0089`*\u00D9m\u00D9\u00B47\x06\u0082# \x04\b\u00DA^~t\u0096<\u00CC\u00CA\x00\u00E3\u00DE\u00A1\f?\u0087B\x07\u0086E\u0098\u00E6\x1B~?\u00C8\x15Kl\u0089t#`=W\x04DK5_*\x00V93\u00C3\u00CC\u00B8\u00E9\u00F7\u009B\u00C3n\u00FC\u0096\u00F9\u00FF\u00D6O\u00EE=\u00F3y\u0089\u00BB\u009F\u008B\b\u00F45\u00EC\u00C5\u0083\u00B2\u00AD\u00F7\u00D0\u00BE\u00C1S\u00E6s@#U\x1BX8\u00DCA\x19\u00C0\u00E4Mi\u00E3\u00E2\x17\x00O\x07\u00C7\u00DDir\x7FU\u00A1\u0083\\\u00AB\x12EG\u009E\u00E7m\u0086C\x00\u00B4\u00C0\u00AA\u00DC@\u00A0\u00FC\b\u00E64qK\u00F7\u00BA-@u\u009F\u00F37\u0085Ir\x0E\u00B9\u008B\u00D4\u0082\x00\x00\x00\x00IEND\u00AEB`\u0082";
green = "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\b\x06\x00\x00\x00\x1F\u00F3\u00FFa\x00\x00\x00\tpHYs\x00\x00\t\u00D7\x00\x00\t\u00D7\x01\u00B1n\x17\u00B7\x00\x00\x00\x19tEXtSoftware\x00www.inkscape.org\u009B\u00EE<\x1A\x00\x00\x00\u00EFIDAT8\u008D\u00A5\u00931J\x03Q\x14E\u00CF}3hJ\x1B\u00D1\u00A4\u00B1s\x01\u00F6\n\u00AEA\x10\u00826\u00EE\"{\u00B1\u00B1\u00B2\u0090t\u008Ak\x10\u00D4&\u009Bp\x04\x0BM\u0095\u0080\u00F97\u00C5\u00A0f\u008C&3\u00CC\u00AB\u00FE\u0087\x7F\u00CF\u00BD\u00EF=\u00BEl\u00D3\u00A6\u00A2\u0095\x1A\u00C8\x17/\x077'G\u00D8\u0097\u00B2\u00F2\u00FF\x04\x00\u00C8\x13R\u00F4\u009F\u00FB\u00C3Q\u00E5a\u00A0s\u00C3>Z\u00EDji*\u00A5C`Tm\u00C1\u00EC\u00D5\u0089\x1D\u00F6\u00D4\u00E8\u00B54\u00AD\u00E8S\u00B7\x0E\u00C0R\x12\u00B1\f\u0090\u00B4]\x07 \u00C8f\u009A\u00FD\u0091\u00C0l\u00C1\u00FA\u00B5\u00DAlv>'E\x05p|u\u00D1\x01r\u00D6M\u00B0D\u00C4\u00C3\u00D9\u00FD\u00B8\x02\u00F8\u00D8\x18\u00EFP\u00C7\x1E\x00\u00BD}\u009D\u00BE\u00D7\u00A8\u008C.PH\u00BA^%MN\u00CE\u00A4\u00BB%\x00\u00B8\x07\u00F1\u00F8t:\x1C\u00D4KQ\u00D6\u00C2\x10\u00A3\u0087xi\"\u00FE\x05H\u00BB\u00C6ES\u00C0\u00CF\f\x1C\u00B7\x11\u00F1\u00DE\x14\u00A0\u00B6\u00DFy\x0E\u00F4\x1CG\u00E7\u00C3S\u00DC\u00E7\x00\x00\x00\x00IEND\u00AEB`\u0082";
green_o = "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\b\x06\x00\x00\x00\x1F\u00F3\u00FFa\x00\x00\x00\tpHYs\x00\x00\t\u00D7\x00\x00\t\u00D7\x01\u00B1n\x17\u00B7\x00\x00\x00\x19tEXtSoftware\x00www.inkscape.org\u009B\u00EE<\x1A\x00\x00\x00\u00FFIDAT8\u008D\u00A5\u0093\u00B1J\x03a\x10\u0084g\u00F6b\b\x16\u0082\u00D5%y\u008C`\u00AB\u00E0+\x18\x11\u00C5FK\u009F >\u0083Oa\u00A91`!X[\n\x1A\x0B\u009FA\u00D0t&\u0095\u00A2\u00B7c\u00A1\u00B9\u00DC\u00FD\u00E2\x1F\u00C3M\u00B70\u00F3\u00B1\u00CC\u00B2\u0094\u0084*\u00B2Ji\x00\u00B5\u00E2\u00D0\u00E9w7(\u009C\x00\u00AC\u00FD\x15\u00F8\u0096\u00DE\u00E1<\x1A\u00EE\r\x1EKF\x13\u00B6A\u00DE\u0088\u00D9E4\u00EFI\x0F\u00F4u\x00e\x00\u0088\u0096\u00BB\u00CE\x1Fv/\u0087\u00B1\u00FCZ\u00BFK\x17G@\u00D0\u0081\u00A4\u0094\u00B0Q|\u00FD\u00B2/(\u0091\u00CD\u008C\u00D9\\@\u00D1\x17\x00\u00946>\u00DF^\u00E6\x03f\u00BE\x1C\u00B0yz\u00D8\x00\u00B8t\u00BB\x7F=\u0089E\x7F|\u00F5\u00A9//q\\\u009F\u00A4\u0084>:g[\u00BD\u00E8\u00F2\u00CB\\\u0081\u00F04\u009Ds\x00\x13\u00B4\x00\u008E\u00CD\u00B8\x1A\x03\u00B8\\\ty\u00F0\x0B\x00\u00A8\r\u00D8\u00DD\u00FD\u00CE\u00E08\x06\bU(\u00D1\u00DA \u009E\x17\t\x07\x00o\n\u00FA\u00C7\x05\u00CA\u009Au \u00BB2\u00B3\u00D7E\x01\u00AC\u00FA\u00CE_\u00A28Y\x00\x13L\u00B1)\x00\x00\x00\x00IEND\u00AEB`\u0082";
gray = "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\b\x06\x00\x00\x00\x1F\u00F3\u00FFa\x00\x00\x00\tpHYs\x00\x00\t\u00D7\x00\x00\t\u00D7\x01\u00B1n\x17\u00B7\x00\x00\x00\x19tEXtSoftware\x00www.inkscape.org\u009B\u00EE<\x1A\x00\x00\x00\u00EEIDAT8\u008D\u00A5\u00931N\u00C3@\x10E\u00DF\x1F[@\x15\u00D1 H\x1A:n\x01\u0097\b\r2\u00CA9\u00B8\x0B\u008Di((\u00D2\u00C0-\u00E8r\t\x1C\u0089\x02\u00D1@\u0080\u00EC\u00A7!\x01;\"\u00B1\u0095\u00A9f\u00A5\u00FDo\u00FF\x1F\u00ED\u00C86\u00DBTl\u00A5\x06\u00F2\u00BF\u0087\u00F1\u00DD\u00CD\x19\u00E8\x1A)\u00FFO\x00 \u00D2{\n]\f\u0087\u00A3I\u00ED\u00A2B\u00976'\u00B0>\u0096a\x16s\u009D\x02\u0093\u00E6K\u00C7ml\u00DB\u009A!O\u00A19\x03\u00BB\u00DF\x06\x10rJ\u008AU\u0080\u00D1A+\x07(\u00CB\u00E6i\n\u008D!\x1A\u00F6\x01\u00B4\x11\u00C0\u00EE\u00DBWV\u00D5\x1C\u0094e\u00B9'\u00C87\u0089\x7FDQ\x14\u00C5k\r\u00D0\u00EB\u00ED\x1C\u009Av\u00BF\u00CA\u00F0\u00BC\u00E8\x7F#|~\u00F4\x15Q!n\u00D7\u0089el\u00FBa\x05\u00A0,\x1B$\u00FBqx>\u00BAj\u00E3bQ\u00CB\b\u00C9\x1E ?u\x11\u00D7\x00\u0081\u008F\x04UW\u00C02B\u008A\u00B8OI/]\x01\u00DAv\u009D\u00BF\x01\u00E7\u008FN\x13\u00B9\u00E9m\u0087\x00\x00\x00\x00IEND\u00AEB`\u0082";
gray_o = "\u0089PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\b\x06\x00\x00\x00\x1F\u00F3\u00FFa\x00\x00\x00\tpHYs\x00\x00\t\u00D7\x00\x00\t\u00D7\x01\u00B1n\x17\u00B7\x00\x00\x00\x19tEXtSoftware\x00www.inkscape.org\u009B\u00EE<\x1A\x00\x00\x00\u00FFIDAT8\u008D\u00A5\u00931N\u00C3@\x14Dg\u00BEC\u0094\x02Y\u00A2r\u0092\u00BB\u00903 9T\u0096\x02-'\bg\u00E0\x14&\x1D\u0089\x14\n.@\u008Fh8\x03R\u0092\x0Eh\x10$\u00DE\u00A1!N\u00BC\u00A0\u00B5\"O\u00F7wg\u009E\u00FE\u00FF\u00AB\u00A5$4\u00915J\x03h\u00ED\x17\u00F3\u00E9\u00ED\x00\u00E4\u008D\x7F\u00FE\u008F\u00BEd\u00B8J\u00D3\u00D1\u008Bg\u00E4\x10\u00C4\u00A3I\u00B3P\u00DA\u0081c+x\n\u00C0\x03\x10=\bwg\u00E7\x17\u00CF!\u00C0|6\u00A1\u00A8\x15\u00E0\u00ED\u0080P\u00E2h\u00AB\u009A\u00F6+\u00BE\n@`7*\\-`\u00DF\u00D7\u00AA^ \u00F9\u00DCD\u00CBz\u00C0\u00CEWv\u0090\u00E7y\u0087\u00C0Q\u0096e\x1F\u00A1\u00F0\u00AF\u00AF\u00BD\u00F5\u0095\x1D\u00C4q;Q\u00B1Y\u00DFO'\u00E3\x10 >\u00B6\x18\u00C2\u00EB\u00B6\u00DE\u008D\u00B0\u00FE\u00EE\u00D1\u00EC]\u0086\u0093\x10\u0080\u0082$]\u00FE\x010\u008A\u00FANzJ\u0087\u00A3\u00EB\x10\u00C0W\u00B9\x03'\u00F5A-\x0E\tW\x00\x06u\t\u00D4\u00BE\u0080\u00AFr\x04g\u00F6\u00E0\x1C\u00DF\x0E\x05\u00B0\u00E9w\u00FE\x01\u00C6z]\u00D4\u0097\x17j\u00EE\x00\x00\x00\x00IEND\u00AEB`\u0082";






var states = [gray_o,green_o,green, red, gray, blue];


function getLogonly(file){
    if(file.name.indexOf("Logs)") != -1){
        return true;
    }
        return false;
 }
function pathToWinPath(path){
	str = path.replace(/\//, "");
	str = str.replace(/\//, ":/");
	str = str.replace(/%20/g, " ");
	str = str.replace(/\//g, "\\");
	return str;
}
function localToRessource(path){
    //windows, for now, the only one available!
    str = "/"+path.replace(":\\", "/");
    str = str.replace(/\\/g, "/");
    str = str.replace(" ", "%20");
    str = str.substring(0,str.lastIndexOf("/"));
    return str;
}
function returnFolderArray(location){
    fold = new Folder(location.toString());
    foldArray = fold.getFiles()
    folderOnly = new Array();
    for(i=0;i<foldArray.length;i++){
        if(foldArray[i] instanceof Folder){
            folderOnly[folderOnly.length] = foldArray[i];
            }
        }
    return folderOnly;
}
function logInfo(logFolderLocation){
    
    curFold = new Folder(logFolderLocation.toString());
    folds = returnFolderArray(logFolderLocation);
    txtfiles = fold.getFiles("*RCF.txt"); //there should only be one
    htmlfiles =  fold.getFiles("*.htm");
    var htmlfile;
    if(htmlfiles[0]){
        htmlfile = htmlfiles[0].toString();
    }
  var info = [logFolderLocation.name.toString(),1,logFolderLocation.toString(),logFolderLocation.name.toString()+"rrr"];
    var fcontents = "";
    if(txtfiles[0]){
        f = txtfiles[0].toString();
        f = new File(f);
        f.open("r","TEXT","????");
        fcontents = f.read();
        f.close();
        var findItems = new RegExp("^(item)[0-9]{1,}(=\()(.*)(\))$","mi");
        v=findItems.exec(fcontents);
        if(v){
            if(v[4].indexOf("Stopped") != -1){
                info=["name",1,v[4].substring(1,v[4].indexOf(","))];  
            }else if(v[4].indexOf("In Progress") != -1){
                info=["name",2,"Rendering"];  
            }else if(v[4].indexOf("Finished") != -1){
                info=["name",0,""];  
            }

        }else{
           // $.writeln("Buggy file");
            info=[logFolderLocation.name.toString(),1,"--Bug--",logFolderLocation.toString()+"eeee"];  
        }
        fold = new Folder(folds[0].toString());
        files = fold.getFiles("*.txt"); 
        firstFile = files[files.length-1]; //used to be first file, works better with last text file
        if(firstFile == undefined || firstFile == null){
              info=[logFolderLocation.name.toString(),1,"Error",htmlfile]; 
        }else{
          
                firstFile.open("r","TEXT","????");
                contents = firstFile.read();
                firstFile.close();
                lines = contents.split("\n");

               info[3] = logFolderLocation.toString();
               info[0] = logFolderLocation.name.toString();
                for(i=0;i<lines.length;i++){
                    phrase ="Rendering started on";
                    info[4] = "n/a";
                    if(s = lines[i].indexOf(phrase) != -1){
                        info[4] = lines[i].substring(s+phrase.length);        
                    }
                    phrase ="Output To: ";
                   
                    
                    if(info[1]==0 ||info[1]==2){

                            if(s = lines[i].indexOf(phrase) != -1){
                                s = lines[i].indexOf(phrase);
                                v = lines[i].substring(s+phrase.length);
                                wfold = v.substring(0,v.lastIndexOf("\\"));

                                f =  wfold.substring(wfold.lastIndexOf("\\")+1,wfold.length);

                                 info[3] =localToRessource(wfold);
                                 $.writeln(info[3])
                                info[0] = f;

                            }
                        }
                
                }

        }
   
    }
  $.writeln(info);
    return info;
            
}
function hasStarted(watchedFolderLocation){
    fold = new Folder(watchedFolderLocation.toString());
    files = fold.getFiles(getLogonly);
    if(files.length>0){
        return true;
    }else{
        return false;
    }
}

function getFilePath(watchedFolderLocation){
    fold = new Folder(watchedFolderLocation.toString());
    files = fold.getFiles(getLogonly);
    alert(files[0].name);
    return files[0].name;
}
/*
function getPercentage(folder){
    myFolder = new Folder(folder);
    files = myFolder.getFiles("*DandyWatch.txt");
    if(files.length != 1){
        return false;
    }
    myTextFile = files[0];    
    myTextFile.open("r","TEXT","????");
    contents = myTextFile.read();
    myTextFile.close();
    lines = contents.split("\n");
    outPutFolder = new Folder(lines[0]);
    files = outPutFolder.getFiles();
    f = files.length;
    writeLn(f+"/"+(lines[1]+1));
    return parseFloat(files.length/(lines[1]+1));
    //var percentage = new Array();
}
//getPercentage(watchfolderLocation+"/"+shot);
*/

function explore(location){
     fold = new Folder(location.toString());
     return fold.execute();     
}
function retrieveArray(){
    var state = 4; //queued, default state
     var vArray = new Array();
    l =0;
    counter=0;
    counter2=0;
    folders = returnFolderArray(wf);
    for(folder in folders){
    l++;
        var out = "";
        if(folders[folder].name != "anonymous"){ //??
            counter2++;
            if(hasStarted(folders[folder])){
                state = 0;
                out = logInfo(folders[folder]);
                //$.writeln(out);
                //out[3] = localToRessource(out[3]);
                                   
            }else{
                state = 4;
                out = [folders[folder].name,4,"",folders[folder].toString()];
            }
            vArray[counter2] =out;
        }

        wfPbar.value = l/folders.length*100;

        if (pal instanceof Window){
            pal.update();
        }else{
            if(counter < Math.round(wfPbar.value/5,0)*5){
                counter +=5;
                clearOutput();
                writeLn(counter+"%");
            }else{
                write(".");
            }
        }
    }
    return vArray;
}
function gather(){
                refreshBtn.text = "refreshing...";
                refreshBtn.enabled = false;
                wfStText.visible = false;
                wfPbar.visible = true;
                shotinfos = retrieveArray();
                list.removeAll();
                for(i=1;i<shotinfos.length;i++){
                    var p = shotinfos[i];
                    addItem(p[0],p[1],p[2]);

                }
                writeLn("Done");
                wfStText.visible = true;
                wfPbar.visible = false;
                
                //set (or not) the timer
                refreshBtn.enabled = true;
                if(parseInt(reloadEditTxt.text) > 0){
                    timer = parseInt(reloadEditTxt.text)/refreshRate;

                    refreshBtn.text = "Click to stop ("+(timer*5)+"s)";
                    cancelTaskID = app.scheduleTask("loop()",refreshRate*1000,1);                
                }else{
                    refreshBtn.text = "Refresh";
                }
}
function watchWatchFolder(thisObj){

        //UI Design
        {
            pal = (thisObj instanceof Panel) ? thisObj : new Window("palette", "WatchFolder", undefined, {resizeable:true});
            var winGfx = pal.graphics;
            var darkColorBrush = winGfx.newPen(winGfx.BrushType.SOLID_COLOR, [0,0,0], 1);
            pal.bounds = [300,200,600,600];        
            var wfLocBtn = pal.add("button", [10,10,105,35],"Set Watchfolder");
            wfStTextContents = ( wf != null)?app.settings.getSetting("watchwatchfolder", "wfloc"):"(not set...)";
            wfStText = pal.add("edittext",[115,12,285,33], wfStTextContents);
                wfStText.active = false;
                wfStText.enabled = false;
            wfPbar = pal.add("progressbar",[115,12,285,33],0,100);
                wfPbar.visible = false;
            var sortStText = pal.add("statictext",[17,42,80,60], "Sort by: ");
            var sortByName = pal.add('radiobutton',[62,40,120,57], 'name');
            var sortByStatus = pal.add('radiobutton',[115,40,170,57], 'status');


            
                sortByName.value = true;
            var bottomElements = pal.add("panel",[10,310,260,360],undefined,{borderStyle:"none"});
            
            bl = 0;
            var arrayV = new Array("green","red","orange","graygreen","gray");      
            
            bottomElements.add('image',[5,bl,20,bl+14],scriptFolder.toString()+"/flag_"+arrayV[0]+".png");
            chckBox0 = bottomElements.add('checkbox',[22,bl,39,bl+16], '');
            chckBox0.value = true;
            chckBox0.helpTip = "Show finished renders";
            
            bottomElements.add('image',[45,bl,60,bl+14],scriptFolder.toString()+"/flag_"+arrayV[1]+".png");
            chckBox1 = bottomElements.add('checkbox',[62,bl,79,bl+16], '');
            chckBox1.value = true;
            chckBox1.helpTip = "Show errors";
            
            bottomElements.add('image',[85,bl,100,bl+14],scriptFolder.toString()+"/flag_"+arrayV[2]+".png");
            chckBox2 = bottomElements.add('checkbox',[103,bl,120,bl+16], '');
            chckBox2.value = true;
            chckBox2.helpTip = "Show rendering";
           
            bottomElements.add('image',[125,bl,140,bl+14],scriptFolder.toString()+"/flag_"+arrayV[4]+".png");
            chckBox3 = bottomElements.add('checkbox',[143,bl,160,bl+16], '');
            chckBox3.value = true;
            chckBox3.helpTip = "Show queued";
            
            bl = 25;
            var reloadStTxt =  bottomElements.add("statictext",[5,bl+2,50,bl+21], "Update: ");
            reloadEditTxt =  bottomElements.add("edittext",[55,bl,90,bl+20], 20);
            reloadEditTxt.enabled=false;
            refreshBtn =  bottomElements.add("button",[100,bl,260,bl+20], "Start");
            reloadEditTxt.helpTip = "in seconds, 0 for manual refresh only.";
            list = pal.add ("ListBox", [10, 65, 260,320], "desc",{numberOfColumns: 2,showHeaders: true});        
            
            
            //list.columnTitles = Array("First Name", "Last"); doesn't work in CS5 apparently
            
         }
     
     
        //UI Callbacks
        {
            wfLocBtn.onClick = function(){
                wfLoc = Folder.selectDialog("Select watchfolder");
                if(wfLoc != null){
                    app.settings.saveSetting("watchwatchfolder", "wfloc",wfLoc.toString());
                    wf = new Folder(wfLoc.toString());
                    if(wf){
                        wfStText.text = wfLoc.toString();
                    }
                }
            }    
            pal.onResize = function(){
                //because using layouts is too confusing for me
                list.bounds = [list.bounds[0],list.bounds[1],pal.bounds[2]-pal.bounds[0]-10,pal.bounds[3]-pal.bounds[1]-100];
                wfStText.bounds = [wfStText.bounds[0],wfStText.bounds[1],pal.bounds[2]-pal.bounds[0]-10,wfStText.bounds[3]];
                wfPbar.bounds = wfStText.bounds;
                bottomElements.bounds = [list.bounds[0],list.bounds[3]+10,list.bounds[2],list.bounds[3]+60];
            }
            list.onDoubleClick = function(){//onChange
                sel = list.selection;
               
                if(list.selection != null){

                    sL=shotinfos.length;

                    for(i=1;i<sL;i++){
                       a=shotinfos[i];

                        if(a[0] == list.selection.toString()){
                            explore(a[3]);
                            break;
                            }
                        }

                }


            }        
            
            
            refreshBtn.onClick = function(){
                if((timer>0 && !firstTime) || !pal.visible){
                        timer = 0;
                       // $.writeln("stopped");
                        refreshBtn.text = "Start";
                        firstTime = true;
                        cancelTask(cancelTaskID);
                }else{
                    if(reloadEditTxt.text == 0 || firstTime){
                            gather();
                            firstTime = false;
                    }
                }
                

            }
            reloadEditTxt.onClick = function(){reloadEditTxt.enabled=true};
            reloadEditTxt.onChange = function(){
                if(reloadEditTxt.text < 10 || (parseInt(reloadEditTxt.text) != reloadEditTxt.text)){
                    timer = 0;
                    reloadEditTxt.text = 0;
                    refreshBtn.text = "Refresh";

                }else{
                    if(timer <= 0){
                        refreshBtn.text = "Start (~ "+eggTimer(reloadEditTxt.text)+")";
                    }
                }
            reloadEditTxt.enabled=false;                
            }
        }
    
    
        //Initialize the whole shebang
            if (pal instanceof Window){
                pal.center();
                pal.show();
            }
	   
        
      return pal;
     }
//reloadEditTxt.notify("onChange");
ui = watchWatchFolder(this);
}

function eggTimer(time){
    if(time<=59){
        time = time+"s";
    }else if(time<=60*4){
        time = Math.floor(time/60)+"m "+(time%60)+"s";
    }else if(time<60*60){
        time = Math.round(time/60,0)+"m";
    }else{
        time = Math.round(time/(60*60),0)+"h";
    }
    return time;
    }
function loop(){
    timer--;
  //  $.writeln(timer+" pal.visible:"+pal.visible);
    refreshBtn.text = "Click to stop ("+eggTimer(timer*5)+")";
    if(timer<=0 || !pal.visible){

        cancelTask(cancelTaskID);
        if(reloadEditTxt.value == 0 || !pal.visible){
          
        }else{
            gather();
        }
    }
}
function cancelTask(id){
        app.cancelTask(id);
    }
function addItem(name,state,msg){

    //var arrayV = new Array(green,green_o,gray,gray_o,red,red_o);
    var item = list.add ('item',name);
    item.image =  File.decode(states[state]);
    //palette.add("image", undefined, File.decode(gray), {name: "image1"}, [10,10]);
    //item.image =  File(scriptFolder.toString()+"/flag_"+arrayV[state]+".png");
    item.subItems[0].text =msg;

}

SimpleWatchfolder WIP

some improvements

/*
WatchFolder.js v1.2
--------------------
By bernie @ berniebernie.fr

This script is a simple palette to automatically send your After Effects file to be processed by the watchfolder
In essence it's a simplified Collect Files > Project only.

Windows only.


Was added:
- A check for missing footage
- Some UIs to turn AFX into a render worker, launch a worker or launch a simple .bat file instead

TBD
- Some way to parse logs to figure what has rendered and what hasn't, cause Adobe's .html file is crap TBH. This is the 'watchfolder watcher' script that I tried to do long time ago.
- set some WF options (flags)

*/
{
    watchfolderLocation = "none";
    watchfolderLocation = (app.settings.haveSetting("watchfolderPrefs", "watchfolderLocation")) ? (app.settings.getSetting("watchfolderPrefs", "watchfolderLocation")) : watchfolderLocation;



    function sendToWF(wf) {
	var m=0;
	var errorList=""
        for(i=1;i<=app.project.numItems;i++){
            if(app.project.items[i] instanceof FootageItem && app.project.items[i].file != null){
                            if(app.project.items[i].footageMissing){
                                m++;
				errorList += app.project.items[i].name + "\n"; // + " > " + app.project.items[i].mainSource.file.path.toString + "\n";
                            }
            }
        }
	if(m!=0){
		alert("There are "+m+" missing footage(s) in the project, the watchfolder will fail.\n\nYou can however batch locally using the aerender button\n\n"+errorList);
	}else{
		// the important part of this script. Creates the RCF (render control file), the undocumented file that will launch the watchfolder process.
		// the way it is created is kind of black-boxy, but this setup works for me.
        	var saved = app.project.file;
        	var curFile = app.project.file.name;
        	curFile = curFile.substring(0, curFile.length - 4);
        	var myFolder = new Folder(wf + "/" + curFile + "_wf/");
        	myFolder.create();
        	writeLn("Copying AEP to watchfolder.");
        	var mySaveFile = new File(myFolder.toString() + "/" + curFile + ".aep");
        	saved.copy(mySaveFile);
        	var myTextFile = new File(myFolder.toString() + "/" + curFile + "_RCF.txt");
        	myTextFile.open("w", "TEXT", "????");
        	var text = "After Effects 13.2v1 Render Control File\nmax_machines=10\nnum_machines=0\ninit=0\nhtml_init=0\nhtml_name=\"\"\n";
        	myTextFile.write(text);
	        myTextFile.close();
        	writeLn("Sent to watchfolder...");
	}
    }

    function setWatchFolder() {
        var tmpfile = new File(String(Folder.desktop) + "/save this temp file with any name in the watchfolder");
        var selectedFolder = tmpfile.saveDlg('Select Watchfolder Location');
        if (selectedFolder) {

            app.settings.saveSetting("watchfolderPrefs", "watchfolderLocation", selectedFolder.path);
            watchfolderLocation = selectedFolder.path;
            return true;
        } else {
            return false;
        }

    }

    function startWatchingFolder() {
        aerenderExe = '"' + Folder(Folder.decode(Folder.appPackage.absoluteURI)).fsName + '\\AfterFX.exe" -m -re -wf "' + Folder(watchfolderLocation).fsName + '"';
        batch = new File(Folder.desktop.toString() + "/launch_WatchFolder.bat");
        if (batch.open("w", "TEXT", "????") == true) {
            batch.write("@echo off\n");
	    // todo add start "" "C:\Program Files\Adobe\Adobe After Effects 2024\Support Files\AfterFX.exe" -noui -m -re -wf .......
            batch.write(aerenderExe);
            batch.close();
            batch.execute();
        } else {
            alert("unable to launch the AfterEffects worker");
        }

    }
    function startAERender() {
	//to add: multiframe rendering
        aerenderExe = '"' + Folder(Folder.decode(Folder.appPackage.absoluteURI)).fsName + '\\aerender.exe" -continueOnMissingFootage -project "' + File(app.project.file).fsName + '"';
        batch = new File(Folder.temp.toString() + "/launch_aerender.bat");
        if (batch.open("w", "TEXT", "????") == true) {
            batch.write("@echo off\n");
            batch.write(aerenderExe);
	    batch.write("\nPAUSE");
            batch.close();
            batch.execute();
        } else {
            alert("unable to launch the aerender.exe");
        }

    }

    function updateUI(dialog) {

    }

    function watchFolderUI(thisObj) {
        var securitySetting = app.preferences.getPrefAsLong("Main Pref Section", "Pref_SCRIPTING_FILE_NETWORK_SECURITY");
        if (securitySetting != 1) {
            alert("You need to check 'Allow Scripts to Write Files and Access Network' in your preferences for this script to work");
        } else {



            var panelGlobal = thisObj;


            /*
            Code for Import https://scriptui.joonas.me
            */

            // DIALOG
            // ======
            var dialog = (panelGlobal instanceof Panel) ? panelGlobal : new Window("palette", "Simple Watchfolder", [100, 100, 300, 300]);
            if (!(panelGlobal instanceof Panel)) dialog.text = "Simple Watchfolder";
            dialog.orientation = "column";

            dialog.alignChildren = ["fill", "top"];
            dialog.spacing = 10;
            dialog.margins = 16;

            var grp = dialog.add("group", undefined, {
                name: "group0"
            });
            grp.alignement = ["fill", "fill"];
            grp.alignChildren = ["fill", "top"];
            grp.orientation = "column";


            grp.add("statictext", undefined, "Simple UI to send the current queue to a watchfolder. Please save before sending to WF as it will copy the current .aep to the watchfolder", {
                multiline: true
            });



            var group1 = grp.add("group", undefined, {name: "group1"});
            group1.orientation = "row";
            group1.alignChildren = ["fill", "top"];
            group1.spacing = 10;
            group1.margins = 0;

            var setWF = group1.add("button", undefined, undefined, {name: "setWF"});
            setWF.text = "Set WatchFolder";

            var openWF = group1.add("button", undefined, undefined, {name: "openWF"});
	    openWF.enabled = (watchfolderLocation=="none")?false:true; 
            openWF.text = "Open WF";


            var curWF = grp.add("statictext", undefined, undefined, {name: "statictext2"});
            curWF.helpTip = "shows current watchfolder";
            curWF.text = "(choose watchfolder)";


            var sendWF = grp.add("button", undefined, undefined, {name: "sendWF"});
            sendWF.helpTip = "save file first!";
            sendWF.text = "Send .aep to Watchfolder";

            var sendAER = grp.add("button", undefined, undefined, {name: "sendAER"});
            sendAER.helpTip = "local cmdline render";
            sendAER.text = "render local aerender.exe batch";

            var group2 = grp.add("group", undefined, {name: "group2"});
            group2.orientation = "row";
            group2.alignChildren = ["fill", "top"];
            group2.spacing = 10;
            group2.margins = 0;

            var launchWorker = group2.add("button", undefined, undefined, {name: "launchWorker"});
            launchWorker.helpTip = "Saves a .bat file to your desktop that launches a worker";
            launchWorker.text = "Launch a worker";
	    launchWorker.enabled = (watchfolderLocation=="none")?false:true;


            var switchToWorker = group2.add("button", undefined, undefined, {name: "switchToWorker"});
            switchToWorker.helpTip = "Turns the current After Effects into a watchfolder worker";
            switchToWorker.text = "Set as worker";
            switchToWorker.enabled = (watchfolderLocation=="none")?false:true;



            dialog.layout.layout(true);
            dialog.layout.resize();
            dialog.onResizing = dialog.onResize = function() {
                this.layout.resize();
            }


	     if (watchfolderLocation != "none") {
                curWF.text = "Folder: " + Folder(watchfolderLocation).fsName;
		}


            setWF.onClick = function() {
                swf = setWatchFolder();
                if (swf) {
                    curWF.text = "Folder: " + Folder(watchfolderLocation).fsName;
		    openWF.enabled = launchWorker.enabled = launchWorker.enabled = true;
                }
            }
            launchWorker.onClick = function() {
                startWatchingFolder();
            }
	    switchToWorker.onClick = function() {
		app.watchFolder(watchfolderLocation);
	    }
            sendAER.onClick = function() {
                startAERender();
            }

            openWF.onClick = function() {
        	var myFolder = new Folder(watchfolderLocation);
		if (ScriptUI.environment.keyboardState.shiftKey === true) {
		        alert("lol");
    		}
        	myFolder.execute();

                //watchfolderLocation
            }
            sendWF.onClick = function() {
                if (watchfolderLocation == "none") {
                    setWatchFolder();
                } else {
                    sendToWF(watchfolderLocation);
                }
            }

        }
    }
    watchFolderUI(this);
}

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

6iJkeH9.png

Very wip. Features and UI don't fully work.

I hate having to go and fill out the outputs of renderqueue items by hand. This would/will automate the creation of render outputs according to variables like the comp's name and folder, the name of the After Effects project, the current date etc...

It still needs work, which will happend if someone ever hires me for AE work again :)
//todo: be able to select existing RQ items instead of simply comps, and edit their existing paths

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

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")));
}

?>