<commit_before>/* RESTfull module */

(function(){
    'use strict';

    if(!global.cloudcmd)
        return console.log(
             '# rest.js'                                        + '\n'  +
             '# -----------'                                    + '\n'  +
             '# Module is part of Cloud Commander,'             + '\n'  +
             '# used for work with REST API.'                   + '\n'  +
             '# If you wont to see at work set rest: true'      + '\n'  +
             '# and api_url in config.json'                     + '\n'  +
             '# http://coderaiser.github.com/cloudcmd'          + '\n');

    var main        = global.cloudcmd.main,
        fs          = main.fs,
        Util        = main.util,
        CloudFunc   = main.cloudfunc,
        dir         = main.dir,
        diff        = main.diff,
        OK          = 200,
        Header      = main.generateHeaders({
            name:'api.json'
        });

    /**
     * rest interface
     * @pParams {request, responce}
     */
    exports.api = function(pParams){
        var lRet = main.checkParams(pParams);
        if(lRet){
            var lAPIURL     = main.config.api_url,
                p           = pParams;

            lRet = Util.isContainStr(p.name, lAPIURL);
            if( lRet ){
                p.name = Util.removeStrOneTime(p.name, lAPIURL);
                sendData( pParams);
            }
        }
        return lRet;
    };

    /**
     * send data
     *
     * @param pRes
     * @param pData
     */
    function send(pParams){
        var lRes            = pParams.response,
            lData           = pParams.data;

        lRes.writeHead(OK, Header);
        lRes.end( JSON.stringify(lData) );
    }

    /**
     * getting data on method and command
     *
     * @param pParams {command, method, body, requrest, response}
     */
    function sendData(pParams){
        var p, lRet = main.checkParams(pParams);
        if(lRet){
            p   = pParams;

            lRet    = Util.isContainStrAtBegin(p.name, CloudFunc.FS);
            if (lRet)
                onFS(pParams);
            else {
                if(p.name[0] === '/')
                    p.command = Util.removeStrOneTime(p.name, '/');

                switch(p.request.method){
                    case 'GET':
                        lRet = onGET(pParams);
                        break;

                    case 'PUT':
                        getBody(p.request, function(pBody){
                            p.body = pBody;
                            onPUT(p);
                        });
                        break;
                    }
            }
        }
        return lRet;
    }

    function onFS(pParams){
        var p, lWriteStream, lSize, lQuery,
            lRet = main.checkParams(pParams);
        if(lRet){
            p       = pParams,
            lQuery  = main.getQuery(p.request);

            p.name  = Util.removeStrOneTime(p.name, CloudFunc.FS) || '/';
            switch(p.request.method){
                case 'GET':
                    if( Util.strCmp(lQuery, 'size') )
                        dir.getSize(p.name, function(pErr, pSize){
                            if(!pErr){
                                lSize = CloudFunc.getShortSize(pSize);
                                console.log(lSize);
                                main.sendResponse(p, lSize);
                            }
                            else
                                main.sendError(p, pErr);
                        });
                    else
                        fs.stat(p.name, function(pError, pStat){
                            if(!pError)
                                if( pStat.isDirectory() )
                                    main.commander.getDirContent(p.name, function(pError, pData){
                                        if(!pError){
                                            p.name += '.json';
                                            p.data = Util.stringifyJSON(pData);
                                            main.sendResponse(p);
                                        }
                                        else
                                            main.sendError(p, pError);
                                    });
                                else
                                    main.sendFile(p);
                            else
                                main.sendError(p, pError);

                        });
                break;

                case 'PUT':
                    if (lQuery === 'dir')
                        fs.mkdir(p.name, function(pError){
                            if(!pError)
                                main.sendResponse(pParams, 'Folder ' + p.name + ' created.');
                            else
                                main.sendError(pParams, pError);
                        });
                    else if(lQuery === 'patch') {
                        getBody(p.request, function(pPatch) {
                            fs.readFile(p.name, function(pError, pData) {
                                var lDiff, lStr = pData.toString();

                                if (pError)
                                    main.sendError(pParams, pError);
                                else {
                                    var lRet = Util.tryCatchLog(function(){
                                        lDiff = diff.applyPatch(lStr, pPatch);
                                    });

                                    if (lDiff && !lRet)
                                        fs.writeFile(p.name, lDiff, function(){
                                            if (pError)
                                                main.sendError(pParams, pError);
                                            else
                                                main.sendResponse(pParams, 'write ' + p.name);
                                        });
                                    else
                                        main.sendError(pParams, lRet || lDiff);
                                }
                            });
                        });
                    }
                    else {
                        lWriteStream    = fs.createWriteStream(p.name);

                        lWriteStream.on('error', function(pError){
                            main.sendError(pParams, pError);
                        });

                        p.request.on('end', function(){
                            main.sendResponse(pParams, 'writ: ' + p.name);
                        });

                        //p.request.pipe(process.stdout);
                        p.request.pipe(lWriteStream);
                    }
                    break;
                case 'DELETE':
                    if(lQuery === 'dir')
                        fs.rmdir(p.name, function(pError){
                            if(!pError)
                                main.sendResponse(pParams, 'Folder ' + p.name + ' deleted.');
                            else
                                main.sendError(pParams, pError);
                            });
                    else if(lQuery === 'files'){
                        getBody(p.request, function(pBody){
                            var lFiles  = Util.parseJSON(pBody),
                                n       = lFiles.length,
                                lDir    = p.name,
                                log     = Util.retExec(Util.log),
                                lAssync = 0;

                            function stat(pStat){
                                var lRet =  Util.checkObjTrue(pStat, 'params') &&
                                            Util.checkObjTrue(pStat.params, 'name');

                                if(lRet){
                                    var p       = pStat,
                                        d       = p.params;

                                    ++lAssync;

                                    if( p.error ){
                                        main.sendError(pParams, p.error);
                                        Util.log(p.error);
                                    }
                                    else
                                        if(p.data.isDirectory())
                                            fs.rmdir(d.name, log);

                                        else if(p.data.isFile())
                                            fs.unlink(d.name, log);

                                    if(lAssync === n && !p.error)
                                        main.sendResponse(pParams, 'Files deleted: ' + pBody);
                                }
                            }

                            for(var i = 0; i < n; i ++){
                                var lName = lDir + lFiles[i];
                                Util.log(lName);
                                fs.stat(lName, Util.call(stat, {
                                    name: lName
                                }));
                            }
                        });
                    }else
                        fs.unlink(p.name, function(pError){
                            if(!pError)
                                main.sendResponse(pParams, 'File ' + p.name + ' delete.');
                            else
                                main.sendError(pParams, pError);
                        });

                    break;
                }
        }
        return lRet;
    }

    /**
     * process data on GET request
     *
     * @param pParams {command, method, body, requrest, response}
     */
    function onGET(pParams){
        var lRet = main.checkParams(pParams);
        if(lRet){
            var p       = pParams,
                lCmd    = p.command;

            switch(lCmd){
                case '':
                    p.data = {
                        info: 'Cloud Commander API v1'
                    };
                    send(p);
                    break;

                case 'proxy':

                    break;

                case 'zip':
                    main.sendFile(pParams);
                    break;

                case 'kill':
                    p.data = {
                        mesage: 'Cloud Commander was killed'
                    };
                    send(p);
                    break;
                default:
                    p.data = {
                        error: 'command not found'
                    };
                    send(p);
                    break;
            }
        }

        return lRet;
    }

    /**
     * process data on PUT request
     *
     * @param pParams {command, method, body, requrest, response}
     */
    function onPUT(pParams){
        var lRet        = main.checkParams(pParams, ['body']);
        if(lRet){
            var p       = pParams,
                lCmd    = p.command,
                lFiles  = Util.parseJSON(p.body);
            console.log(p.body);
            switch(lCmd){
                case 'auth':
                    main.auth(p.body, function(pTocken){
                        send({
                            response: p.response,
                            data: pTocken
                        });
                    });
                    break;

                case 'cmd':
                    main.child_process.exec(p.body, function(pError, pStdout, pStderr){
                        var lError = pError || pStderr;
                        if(!lError)
                            main.sendResponse(pParams, pStdout);
                        else
                            main.sendError(pParams, lError);
                    });
                    break;

                case 'mv':
                    if( Util.checkObjTrue(lFiles, ['from', 'to']) )
                        fs.rename(lFiles.from, lFiles.to, function(pError){
                            if(!pError)
                                main.sendResponse(pParams);
                            else
                                main.sendError(pParams, pError);
                        });
                    else
                        main.sendError(pParams, p.data);
                    break;

                case 'cp':
                     if( Util.checkObjTrue(lFiles, ['from', 'to']) ){
                        var l               = lFiles,
                            lReadStream     = fs.createReadStream(l.from),
                            lWriteStream    = fs.createWriteStream(l.to),

                            lError          = function(pError){
                                main.sendError(pParams, pError);
                            };

                            lWriteStream.on('error', lError);
                            lReadStream.on('error', lError);

                            lReadStream.on('end', function(){
                                main.sendResponse(pParams, 'copied to: ' + l.to);
                            });

                        lReadStream.pipe(lWriteStream);
                    }
                    else
                        main.sendError(pParams, p.data);
                    break;
                default:
                    send(pParams);
                    break;
                }
            }

        return lRet;
    }

    /**
     * get body of url query
     *
     * @param pReq
     * @param pCallBack
     */
    function getBody(pReq, pCallBack){
        var lBody = '';

        pReq.on('data', function(chunk){
            lBody += chunk.toString();
        });

        pReq.on('end', function() {
            Util.exec(pCallBack, lBody);
        });
    }

})();
<commit_msg>chore(rest) lRet: global -> local<commit_after>/* RESTfull module */

(function(){
    'use strict';

    if(!global.cloudcmd)
        return console.log(
             '# rest.js'                                        + '\n'  +
             '# -----------'                                    + '\n'  +
             '# Module is part of Cloud Commander,'             + '\n'  +
             '# used for work with REST API.'                   + '\n'  +
             '# If you wont to see at work set rest: true'      + '\n'  +
             '# and api_url in config.json'                     + '\n'  +
             '# http://coderaiser.github.com/cloudcmd'          + '\n');

    var main        = global.cloudcmd.main,
        fs          = main.fs,
        Util        = main.util,
        CloudFunc   = main.cloudfunc,
        dir         = main.dir,
        diff        = main.diff,
        OK          = 200,
        Header      = main.generateHeaders({
            name:'api.json'
        });

    /**
     * rest interface
     * @pParams {request, responce}
     */
    exports.api = function(pParams){
        var lRet = main.checkParams(pParams);
        if(lRet){
            var lAPIURL     = main.config.api_url,
                p           = pParams;

            lRet = Util.isContainStr(p.name, lAPIURL);
            if( lRet ){
                p.name = Util.removeStrOneTime(p.name, lAPIURL);
                sendData( pParams);
            }
        }
        return lRet;
    };

    /**
     * send data
     *
     * @param pRes
     * @param pData
     */
    function send(pParams){
        var lRes            = pParams.response,
            lData           = pParams.data;

        lRes.writeHead(OK, Header);
        lRes.end( JSON.stringify(lData) );
    }

    /**
     * getting data on method and command
     *
     * @param pParams {command, method, body, requrest, response}
     */
    function sendData(pParams){
        var p, lRet = main.checkParams(pParams);
        if(lRet){
            p   = pParams;

            lRet    = Util.isContainStrAtBegin(p.name, CloudFunc.FS);
            if (lRet)
                onFS(pParams);
            else {
                if(p.name[0] === '/')
                    p.command = Util.removeStrOneTime(p.name, '/');

                switch(p.request.method){
                    case 'GET':
                        lRet = onGET(pParams);
                        break;

                    case 'PUT':
                        getBody(p.request, function(pBody){
                            p.body = pBody;
                            onPUT(p);
                        });
                        break;
                    }
            }
        }
        return lRet;
    }

    function onFS(pParams){
        var p, lWriteStream, lSize, lQuery,
            lRet = main.checkParams(pParams);
        if(lRet){
            p       = pParams,
            lQuery  = main.getQuery(p.request);

            p.name  = Util.removeStrOneTime(p.name, CloudFunc.FS) || '/';
            switch(p.request.method){
                case 'GET':
                    if( Util.strCmp(lQuery, 'size') )
                        dir.getSize(p.name, function(pErr, pSize){
                            if(!pErr){
                                lSize = CloudFunc.getShortSize(pSize);
                                console.log(lSize);
                                main.sendResponse(p, lSize);
                            }
                            else
                                main.sendError(p, pErr);
                        });
                    else
                        fs.stat(p.name, function(pError, pStat){
                            if(!pError)
                                if( pStat.isDirectory() )
                                    main.commander.getDirContent(p.name, function(pError, pData){
                                        if(!pError){
                                            p.name += '.json';
                                            p.data = Util.stringifyJSON(pData);
                                            main.sendResponse(p);
                                        }
                                        else
                                            main.sendError(p, pError);
                                    });
                                else
                                    main.sendFile(p);
                            else
                                main.sendError(p, pError);

                        });
                break;

                case 'PUT':
                    if (lQuery === 'dir')
                        fs.mkdir(p.name, function(pError){
                            if(!pError)
                                main.sendResponse(pParams, 'Folder ' + p.name + ' created.');
                            else
                                main.sendError(pParams, pError);
                        });
                    else if(lQuery === 'patch') {
                        getBody(p.request, function(pPatch) {
                            fs.readFile(p.name, function(pError, pData) {
                                var lRet, lDiff, lStr = pData.toString();

                                if (pError)
                                    main.sendError(pParams, pError);
                                else {
                                    lRet = Util.tryCatchLog(function(){
                                        lDiff = diff.applyPatch(lStr, pPatch);
                                    });

                                    if (lDiff && !lRet)
                                        fs.writeFile(p.name, lDiff, function(){
                                            if (pError)
                                                main.sendError(pParams, pError);
                                            else
                                                main.sendResponse(pParams, 'write ' + p.name);
                                        });
                                    else
                                        main.sendError(pParams, lRet || lDiff);
                                }
                            });
                        });
                    }
                    else {
                        lWriteStream    = fs.createWriteStream(p.name);

                        lWriteStream.on('error', function(pError){
                            main.sendError(pParams, pError);
                        });

                        p.request.on('end', function(){
                            main.sendResponse(pParams, 'writ: ' + p.name);
                        });

                        //p.request.pipe(process.stdout);
                        p.request.pipe(lWriteStream);
                    }
                    break;
                case 'DELETE':
                    if(lQuery === 'dir')
                        fs.rmdir(p.name, function(pError){
                            if(!pError)
                                main.sendResponse(pParams, 'Folder ' + p.name + ' deleted.');
                            else
                                main.sendError(pParams, pError);
                            });
                    else if(lQuery === 'files'){
                        getBody(p.request, function(pBody){
                            var lFiles  = Util.parseJSON(pBody),
                                n       = lFiles.length,
                                lDir    = p.name,
                                log     = Util.retExec(Util.log),
                                lAssync = 0;

                            function stat(pStat){
                                var lRet =  Util.checkObjTrue(pStat, 'params') &&
                                            Util.checkObjTrue(pStat.params, 'name');

                                if(lRet){
                                    var p       = pStat,
                                        d       = p.params;

                                    ++lAssync;

                                    if( p.error ){
                                        main.sendError(pParams, p.error);
                                        Util.log(p.error);
                                    }
                                    else
                                        if(p.data.isDirectory())
                                            fs.rmdir(d.name, log);

                                        else if(p.data.isFile())
                                            fs.unlink(d.name, log);

                                    if(lAssync === n && !p.error)
                                        main.sendResponse(pParams, 'Files deleted: ' + pBody);
                                }
                            }

                            for(var i = 0; i < n; i ++){
                                var lName = lDir + lFiles[i];
                                Util.log(lName);
                                fs.stat(lName, Util.call(stat, {
                                    name: lName
                                }));
                            }
                        });
                    }else
                        fs.unlink(p.name, function(pError){
                            if(!pError)
                                main.sendResponse(pParams, 'File ' + p.name + ' delete.');
                            else
                                main.sendError(pParams, pError);
                        });

                    break;
                }
        }
        return lRet;
    }

    /**
     * process data on GET request
     *
     * @param pParams {command, method, body, requrest, response}
     */
    function onGET(pParams){
        var lRet = main.checkParams(pParams);
        if(lRet){
            var p       = pParams,
                lCmd    = p.command;

            switch(lCmd){
                case '':
                    p.data = {
                        info: 'Cloud Commander API v1'
                    };
                    send(p);
                    break;

                case 'proxy':

                    break;

                case 'zip':
                    main.sendFile(pParams);
                    break;

                case 'kill':
                    p.data = {
                        mesage: 'Cloud Commander was killed'
                    };
                    send(p);
                    break;
                default:
                    p.data = {
                        error: 'command not found'
                    };
                    send(p);
                    break;
            }
        }

        return lRet;
    }

    /**
     * process data on PUT request
     *
     * @param pParams {command, method, body, requrest, response}
     */
    function onPUT(pParams){
        var lRet        = main.checkParams(pParams, ['body']);
        if(lRet){
            var p       = pParams,
                lCmd    = p.command,
                lFiles  = Util.parseJSON(p.body);
            console.log(p.body);
            switch(lCmd){
                case 'auth':
                    main.auth(p.body, function(pTocken){
                        send({
                            response: p.response,
                            data: pTocken
                        });
                    });
                    break;

                case 'cmd':
                    main.child_process.exec(p.body, function(pError, pStdout, pStderr){
                        var lError = pError || pStderr;
                        if(!lError)
                            main.sendResponse(pParams, pStdout);
                        else
                            main.sendError(pParams, lError);
                    });
                    break;

                case 'mv':
                    if( Util.checkObjTrue(lFiles, ['from', 'to']) )
                        fs.rename(lFiles.from, lFiles.to, function(pError){
                            if(!pError)
                                main.sendResponse(pParams);
                            else
                                main.sendError(pParams, pError);
                        });
                    else
                        main.sendError(pParams, p.data);
                    break;

                case 'cp':
                     if( Util.checkObjTrue(lFiles, ['from', 'to']) ){
                        var l               = lFiles,
                            lReadStream     = fs.createReadStream(l.from),
                            lWriteStream    = fs.createWriteStream(l.to),

                            lError          = function(pError){
                                main.sendError(pParams, pError);
                            };

                            lWriteStream.on('error', lError);
                            lReadStream.on('error', lError);

                            lReadStream.on('end', function(){
                                main.sendResponse(pParams, 'copied to: ' + l.to);
                            });

                        lReadStream.pipe(lWriteStream);
                    }
                    else
                        main.sendError(pParams, p.data);
                    break;
                default:
                    send(pParams);
                    break;
                }
            }

        return lRet;
    }

    /**
     * get body of url query
     *
     * @param pReq
     * @param pCallBack
     */
    function getBody(pReq, pCallBack){
        var lBody = '';

        pReq.on('data', function(chunk){
            lBody += chunk.toString();
        });

        pReq.on('end', function() {
            Util.exec(pCallBack, lBody);
        });
    }

})();
<|endoftext|>


<commit_before>/* RESTfull module */

(function(){
    'use strict';

    if(!global.cloudcmd)
        return console.log(
             '# rest.js'                                        + '\n'  +
             '# -----------'                                    + '\n'  +
             '# Module is part of Cloud Commander,'             + '\n'  +
             '# used for work with REST API.'                   + '\n'  +
             '# If you wont to see at work set rest: true'      + '\n'  +
             '# and api_url in config.json'                     + '\n'  +
             '# http://coderaiser.github.com/cloudcmd'          + '\n');

    var main        = global.cloudcmd.main,
        Util        = main.util,
        CloudFunc   = main.cloudfunc,

        OK          = 200,
        Header      = main.generateHeaders({
            name:'api.json'
        });

    /**
     * rest interface
     * @pParams {request, responce}
     */
    exports.api = function(pParams){
        var lRet,
            lReq    = pParams.request,
            lRes    = pParams.response,
            lUrl    = lReq.url,
            lMethod = lReq.method,
            lConfig = main.config,
            lAPIURL = lConfig.api_url;

        if( Util.isContainStr(lUrl, lAPIURL) ){
            lRet = true;

            getBody(lReq, function(pBody){
                var lCommand = Util.removeStr(lUrl, lAPIURL),
                    lData = getData({
                        command     : lCommand,
                        method      : lMethod,
                        body        : pBody,
                        request     : lReq,
                        response    : lRes
                    });

                if(lData)
                    send({
                        response : lRes,
                        data     : lData
                    });
            });
        }

        return lRet;
    };

    /**
     * send data
     *
     * @param pRes
     * @param pData
     */
    function send(pParams){
        var lRes            = pParams.response,
            lData           = pParams.data;

        lRes.writeHead(OK, Header);
        lRes.end( JSON.stringify(lData) );
    }

    /**
     * getting data on method and command
     *
     * @param pParams {command, method, body, requrest, response}
     */
    function getData(pParams){
        var lResult,
            lCmd    = pParams.command,
            lMethod = pParams.method;

        if( Util.isContainStr(lCmd, CloudFunc.FS) )
            lResult = onFS({
                request : pParams.request,
                response: pParams.response,
                method  : lMethod,
                name    : lCmd
            });

        if(lCmd[0] === '/'){
            lCmd = Util.removeStr(lCmd, '/');
            pParams.command = lCmd;
        }

        if(!lResult)
            switch(lMethod){
                case 'GET':
                    lResult = onGET(pParams);
                    break;

                case 'PUT':
                    lResult = onPUT(pParams);
                    break;
                }

        return lResult;
    }

    function onFS(pParams){
        var lResult,
            lMethod = pParams.method,
            lName   = Util.removeStr(pParams.name, CloudFunc.FS);

        switch(lMethod){
            case 'GET':
                main.commander.getDirContent(lName, function(pError, pData){
                    if(!pError){
                        pParams.request.url += '.json';
                        pParams.name = lName;
                        pParams.data = Util.stringifyJSON(pData);
                        main.sendResponse(pParams);
                    }
                    else
                        main.sendError(pParams, pError);
                });

                break;

            case 'PUT':
                lResult = onPUT(pParams);
                break;
            }

        return lResult;
    }

    /**
     * process data on GET request
     *
     * @param pParams {command, method, body, requrest, response}
     */
    function onGET(pParams){
        var lResult = {error: 'command not found'},
            lCmd    = pParams.command;

        switch(lCmd){
            case '':
                lResult = {info: 'Cloud Commander API v1'};
                break;

            case 'kill':
                pParams.data = {
                    mesage: 'Cloud Commander was killed'
                };
                send(pParams);
                lResult = null;
                break;
        }

        return lResult;
    }

    /**
     * process data on PUT request
     *
     * @param pParams {command, method, body, requrest, response}
     */
    function onPUT(pParams){
        var lResult = {error: 'command not found'},
            lCmd    = pParams.command,
            lBody   = pParams.body,
            lRes    = pParams.response;

        switch(lCmd){
            case 'auth':
                main.auth(lBody, function(pTocken){
                    send({
                        response: lRes,
                        data: pTocken
                    });
                });

                lResult = false;
                break;

            case 'read':
                console.log(lBody);
                var lFiles = lBody;

                if( Util.isString(lFiles) ){
                    pParams.name = lFiles;
                    main.sendFile(pParams);

                    lResult = null;
                }

                break;
        }

        return lResult;
    }

    /**
     * get body of url query
     *
     * @param pReq
     * @param pCallBack
     */
    function getBody(pReq, pCallBack){
        var lBody = '';

        pReq.on('data', function(chunk){
            lBody += chunk.toString();
        });

        pReq.on('end', function() {
            Util.exec(pCallBack, lBody);
        });
    }

})();
<commit_msg>minor changes<commit_after>/* RESTfull module */

(function(){
    'use strict';

    if(!global.cloudcmd)
        return console.log(
             '# rest.js'                                        + '\n'  +
             '# -----------'                                    + '\n'  +
             '# Module is part of Cloud Commander,'             + '\n'  +
             '# used for work with REST API.'                   + '\n'  +
             '# If you wont to see at work set rest: true'      + '\n'  +
             '# and api_url in config.json'                     + '\n'  +
             '# http://coderaiser.github.com/cloudcmd'          + '\n');

    var main        = global.cloudcmd.main,
        Util        = main.util,
        OK          = 200,
        Header      = main.generateHeaders({
            name:'api.json'
        });

    /**
     * rest interface
     * @pParams {request, responce}
     */
    exports.api = function(pParams){
        var lRet,
            lReq    = pParams.request,
            lRes    = pParams.response,
            lUrl    = lReq.url,
            lMethod = lReq.method,
            lConfig = main.config,
            lAPIURL = lConfig.api_url;

        if( Util.isContainStr(lUrl, lAPIURL) ){
            lRet = true;

            getBody(lReq, function(pBody){
                var lCommand = Util.removeStr(lUrl, lAPIURL),
                    lData = getData({
                        command     : lCommand,
                        method      : lMethod,
                        body        : pBody,
                        request     : lReq,
                        response    : lRes
                    });

                if(lData)
                    send({
                        response : lRes,
                        data     : lData
                    });
            });
        }

        return lRet;
    };

    /**
     * send data
     *
     * @param pRes
     * @param pData
     */
    function send(pParams){
        var lRes            = pParams.response,
            lData           = pParams.data;

        lRes.writeHead(OK, Header);
        lRes.end( JSON.stringify(lData) );
    }

    /**
     * getting data on method and command
     *
     * @param pParams {command, method, body, requrest, response}
     */
    function getData(pParams){
        var lResult,
            lCmd    = pParams.command,
            lMethod = pParams.method;

        if( Util.isContainStr(lCmd, 'fs') )
            lResult = onFS({
                request : pParams.request,
                response: pParams.response,
                method  : lMethod,
                name    : lCmd
            });

        if(lCmd[0] === '/'){
            lCmd = Util.removeStr(lCmd, '/');
            pParams.command = lCmd;
        }

        if(!lResult)
            switch(lMethod){
                case 'GET':
                    lResult = onGET(pParams);
                    break;

                case 'PUT':
                    lResult = onPUT(pParams);
                    break;
                }

        return lResult;
    }

    function onFS(pParams){
        var lResult,
            lMethod = pParams.method,
            lName   = Util.removeStr(pParams.name, 'fs');

        switch(lMethod){
            case 'GET':
                main.commander.getDirContent(lName, function(pError, pData){
                    if(!pError){
                        pParams.request.url += '.json';
                        pParams.name = lName;
                        pParams.data = Util.stringifyJSON(pData);
                        main.sendResponse(pParams);
                    }
                    else
                        main.sendError(pParams, pError);
                });

                break;

            case 'PUT':
                lResult = onPUT(pParams);
                break;
            }

        return lResult;
    }

    /**
     * process data on GET request
     *
     * @param pParams {command, method, body, requrest, response}
     */
    function onGET(pParams){
        var lResult = {error: 'command not found'},
            lCmd    = pParams.command;

        switch(lCmd){
            case '':
                lResult = {info: 'Cloud Commander API v1'};
                break;

            case 'kill':
                pParams.data = {
                    mesage: 'Cloud Commander was killed'
                };
                send(pParams);
                lResult = null;
                break;
        }

        return lResult;
    }

    /**
     * process data on PUT request
     *
     * @param pParams {command, method, body, requrest, response}
     */
    function onPUT(pParams){
        var lResult = {error: 'command not found'},
            lCmd    = pParams.command,
            lBody   = pParams.body,
            lRes    = pParams.response;

        switch(lCmd){
            case 'auth':
                main.auth(lBody, function(pTocken){
                    send({
                        response: lRes,
                        data: pTocken
                    });
                });

                lResult = false;
                break;

            case 'read':
                console.log(lBody);
                var lFiles = lBody;

                if( Util.isString(lFiles) ){
                    pParams.name = lFiles;
                    main.sendFile(pParams);

                    lResult = null;
                }

                break;
        }

        return lResult;
    }

    /**
     * get body of url query
     *
     * @param pReq
     * @param pCallBack
     */
    function getBody(pReq, pCallBack){
        var lBody = '';

        pReq.on('data', function(chunk){
            lBody += chunk.toString();
        });

        pReq.on('end', function() {
            Util.exec(pCallBack, lBody);
        });
    }

})();
<|endoftext|>


<commit_before>/**
 * Module dependencies.
 */
var format = require('util').format;
var isArray = require('util').isArray;

var srcName='sessionData';
//var _ = require('lodash');

/**
 * Expose `sessionData()` function on requests.
 *
 * @return {Function}
 * @api public
 */
module.exports = function sessionData(options) {
//  console.log ('%s options:%s',srcName,options);
  options = options || {};
//  console.log ('%s options:%s',srcName,options);
  var safe = (options.unsafe === undefined) ? true : !options.unsafe;
//  console.log ('%s safe:%s',srcName,safe);

  return function(req, res, next) {
    if (req.sessionData && safe) {
    	console.log ('%s req.sessionData:%s',srcName,req.sessionData);
    	return next();
    }
    req.sessionData = _sessionData;
    next();
  }
}

/**
 * Queue sessionData `value` of the given `Variable`.
 *
 * Examples:
 *
 * Regular behavior:
 *      req.sessionData('var01', 'value01');
 *      req.sessionData('var01', 'value02');
 *      req.sessionData('var01', 'value03');
 *      req.sessionData('var02', 'value20');
 *      req.sessionData('var02', 'value21');
 *      // req.sessionData('var01') => value01,value02,value03
 *      // req.sessionData('var01') => []
 *      // req.sessionData('var02') => value20,value21
 *      // req.sessionData('var02') => []
 *
 * Special behavior: config:
 *      req.sessionData('keyconf01','confvalue01', 'setup');
 *	   	req.sessionData('keyconf02','confvalue01', 'setup');
 *		req.sessionData('keyconf03','confvalue02', 'read');
 *      // req.sessionData() => { var01 :[], var02: ['value20'], var03: ['value30','value31'] }
 *
 * Special behavior: breadcrumb
 *      req.sessionData('breadcrumb', 'value10');
 *      req.sessionData('breadcrumb', 'value11');
 *      req.sessionData('breadcrumb', 'value12');
 *      // req.sessionData('breadcrumb') => value12
 *      // req.sessionData('back') => value12

 *
 *
 * Formatting:
 *
 * sessionData notifications also support arbitrary formatting support.
 * For example you may pass variable arguments to `req.sessionData()`
 * and use the %s specifier to be replaced by the associated argument:
 *
 *     req.sessionData('info', 'email has been sent to %s.', userName);
 *
 * Formatting uses `util.format()`, which is available on Node 0.6+.
 *
 * @param {String} variable (key)
 * @param {String} value    (value of the key)
 * @param {String} parameter (
 * @return {Array|Object|Number}
 * @api public
 */
function _sessionData(variable, value, parameter) {

	if (this.session === undefined) throw Error('req.sessionData() requires sessions');

	var values = this.session.sessionData = this.session.sessionData || {};

	if (variable && value) {

		// Special handling for configuration
		if (parameter=='setup') {
			delete values[variable];
		}

		// Special handling for breadcrumb
		if (variable == 'breadcrumb') {
			// Do not Add the same Last Url (in case of refresh
			if (value=='back') {
//				console.log('%s values[variable].length',srcName,values[variable].length)
				if (values[variable].length < 2 ) {
					return values[variable][0]
				} else {
					values[variable].pop();
					return values[variable].pop();
				}
			} else {
				if (values[variable] && (values[variable][values[variable].length-1] == value)){
					return;
				}
			}
		}

		// util.format is available in Node.js 0.6+
		if (arguments.length > 2 && format && parameter != 'setup' && parameter != 'read') {
			var args = Array.prototype.slice.call(arguments, 1);
			value = format.apply(undefined, args);
		} else if (isArray(value)) {
			value.forEach(function(val){
				(values[variable] = values[variable] || []).push(val);
			});
			return values[variable].length;
		}
		return (values[variable] = values[variable] || []).push(value);
	} else if (variable) {
		var arr = values[variable];
		if ((variable != 'breadcrumb') &&  (parameter != 'read')){
			delete values[variable];
		}
		return arr || [];
	} else {
		this.session._sessionData = {};
		return values;
	}
}<commit_msg>Add read (read wihout removing) and setup (write and replace)<commit_after>/**
 * Module dependencies.
 */
var format = require('util').format;
var isArray = require('util').isArray;

var srcName='sessionData';
//var _ = require('lodash');

/**
 * Expose `sessionData()` function on requests.
 *
 * @return {Function}
 * @api public
 */
module.exports = function sessionData(options) {
//  console.log ('%s options:%s',srcName,options);
  options = options || {};
//  console.log ('%s options:%s',srcName,options);
  var safe = (options.unsafe === undefined) ? true : !options.unsafe;
//  console.log ('%s safe:%s',srcName,safe);

  return function(req, res, next) {
    if (req.sessionData && safe) {
    	console.log ('%s req.sessionData:%s',srcName,req.sessionData);
    	return next();
    }
    req.sessionData = _sessionData;
    next();
  }
}

/**
 * Queue sessionData `value` of the given `Variable`.
 *
 * Examples:
 *
 * Regular behavior:
 *      req.sessionData('var01', 'value01');
 *      req.sessionData('var01', 'value02');
 *      req.sessionData('var01', 'value03');
 *      req.sessionData('var02', 'value20');
 *      req.sessionData('var02', 'value21');
 *      // req.sessionData('var01') => value01,value02,value03
 *      // req.sessionData('var01') => []
 *      // req.sessionData('var02') => value20,value21
 *      // req.sessionData('var02') => []
 *
 * Special behavior: config:
 *      req.sessionData('keyconf01','confvalue01', 'setup');
 *	   	req.sessionData('keyconf02','confvalue01', 'setup');
 *		req.sessionData('keyconf03','confvalue02', 'read');
 *      // req.sessionData() => { var01 :[], var02: ['value20'], var03: ['value30','value31'] }
 *
 * Special behavior: breadcrumb
 *      req.sessionData('breadcrumb', 'value10');
 *      req.sessionData('breadcrumb', 'value11');
 *      req.sessionData('breadcrumb', 'value12');
 *      // req.sessionData('breadcrumb') => value12
 *      // req.sessionData('back') => value12
 *
 * Formatting:
 *
 * sessionData notifications also support arbitrary formatting support.
 * For example you may pass variable arguments to `req.sessionData()`
 * and use the %s specifier to be replaced by the associated argument:
 *
 *     req.sessionData('info', 'email has been sent to %s.', userName);
 *
 * Formatting uses `util.format()`, which is available on Node 0.6+.
 *
 * @param {String} variable (key)
 * @param {String} value    (value of the key)
 * @param {String} parameter (
 * @return {Array|Object|Number}
 * @api public
 */
function _sessionData(variable, value, parameter) {

	if (this.session === undefined) throw Error('req.sessionData() requires sessions');

	var values = this.session.sessionData = this.session.sessionData || {};

	if (variable && value) {

		// Special handling for configuration
		if (parameter=='setup') {
			delete values[variable];
		}

		// Special handling for breadcrumb
		if (variable == 'breadcrumb') {
			// Do not Add the same Last Url (in case of refresh
			if (value=='back') {
//				console.log('%s values[variable].length',srcName,values[variable].length)
				if (values[variable].length < 2 ) {
					return values[variable][0]
				} else {
					values[variable].pop();
					return values[variable].pop();
				}
			} else {
				if (values[variable] && (values[variable][values[variable].length-1] == value)){
					return;
				}
			}
		}

		// util.format is available in Node.js 0.6+
		if (arguments.length > 2 && format && parameter != 'setup' && parameter != 'read') {
			var args = Array.prototype.slice.call(arguments, 1);
			value = format.apply(undefined, args);
		} else if (isArray(value)) {
			value.forEach(function(val){
				(values[variable] = values[variable] || []).push(val);
			});
			return values[variable].length;
		}
		return (values[variable] = values[variable] || []).push(value);
	} else if (variable) {
		var arr = values[variable];
		if ((variable != 'breadcrumb') &&  (parameter != 'read')){
			delete values[variable];
		}
		return arr || [];
	} else {
		this.session._sessionData = {};
		return values;
	}
}<|endoftext|>


<commit_before>var fs = require('fs');
var shell = require('shelljs');
module.exports = function (version, cb) {
  // npm
  if (shell.test('-f', 'package.json')) {
    var pkgJson = fs.readFileSync('package.json', 'utf8');
    var pkg = JSON.parse(pkgJson);
    pkg.version = version;
    fs.writeFileSync('package.json', JSON.stringify(pkg, null, 2), 'utf8');
  }

  // bower
  if (shell.test('-f', 'bower.json')) {
    shell.exec('node -e "f = \'./bower.json\'; p = require(f); p.version = \'' + version + '\'; require(\'fs\').writeFileSync(f, JSON.stringify(p, null, 2));"');
  }

  // component
  if (shell.test('-f', 'component.json')) {
    shell.exec('node -e "f = \'./component.json\'; p = require(f); p.version = \'' + version + '\'; require(\'fs\').writeFileSync(f, JSON.stringify(p, null, 2));"');
  }

  // Python
  if (shell.test('-f', 'setup.py')) {
    shell.exec('node -e "fs = require(\'fs\'); f = \'./setup.py\'; p = fs.readFileSync(f, \'utf8\'); v = \'' + version + '\'; p = p.replace(/version=\'\\d+.\\d+.\\d+\'/, \'version=\\\'\' + v + \'\\\'\'); fs.writeFileSync(f, p, \'utf8\');"');
  }

  // Callback
  cb();
};<commit_msg>Added TODO note for later<commit_after>var fs = require('fs');
var shell = require('shelljs');
module.exports = function (version, cb) {
  // npm
  if (shell.test('-f', 'package.json')) {
    // TODO: Consider async stream mutate file onto itself
    var pkgJson = fs.readFileSync('package.json', 'utf8');
    var pkg = JSON.parse(pkgJson);
    pkg.version = version;
    fs.writeFileSync('package.json', JSON.stringify(pkg, null, 2), 'utf8');
  }

  // bower
  if (shell.test('-f', 'bower.json')) {
    shell.exec('node -e "f = \'./bower.json\'; p = require(f); p.version = \'' + version + '\'; require(\'fs\').writeFileSync(f, JSON.stringify(p, null, 2));"');
  }

  // component
  if (shell.test('-f', 'component.json')) {
    shell.exec('node -e "f = \'./component.json\'; p = require(f); p.version = \'' + version + '\'; require(\'fs\').writeFileSync(f, JSON.stringify(p, null, 2));"');
  }

  // Python
  if (shell.test('-f', 'setup.py')) {
    shell.exec('node -e "fs = require(\'fs\'); f = \'./setup.py\'; p = fs.readFileSync(f, \'utf8\'); v = \'' + version + '\'; p = p.replace(/version=\'\\d+.\\d+.\\d+\'/, \'version=\\\'\' + v + \'\\\'\'); fs.writeFileSync(f, p, \'utf8\');"');
  }

  // Callback
  cb();
};<|endoftext|>


<commit_before>var root = this;

// Unveil.js
// =============================================================================

var uv = {};

// Constants
// -----------------------------------------------------------------------------

uv.EPSILON     = 0.0001;
uv.MAX_FLOAT   = 3.4028235e+38;
uv.MIN_FLOAT   = -3.4028235e+38;
uv.MAX_INT     = 2147483647;
uv.MIN_INT     = -2147483648;

// Utilities
// -----------------------------------------------------------------------------

uv.inherit = function (f) {
  function G() {}
  G.prototype = f.prototype || f;
  return new G();
};

uv.each = function(obj, iterator, context) {
  if (obj.forEach) {
    obj.forEach(iterator, context);
  } else {
    for (var key in obj) {
      if (hasOwnProperty.call(obj, key)) iterator.call(context, obj[key], key, obj);
    }
  }
  return obj;
};

uv.rest = function(array, index, guard) {
  return Array.prototype.slice.call(array, (index === undefined || guard) ? 1 : index);
};

uv.include = function(arr, target) {
  return arr.indexOf(target) != -1;
};

uv.select = uv.filter = function(obj, iterator, context) {
  if (obj.filter === Array.prototype.filter)
    return obj.filter(iterator, context);
  var results = [];
  uv.each(obj, function(value, index, list) {
    iterator.call(context, value, index, list) && results.push(value);
  });
  return results;
};

uv.extend = function(obj) {
  uv.rest(arguments).forEach(function(source) {
    for (var prop in source) obj[prop] = source[prop];
  });
  return obj;
};

// SortedHash
// =============================================================================

// Constructor
// Initializes a Sorted Hash
uv.SortedHash = function (data) {
  var that = this;
  this.data = {};
  this.keyOrder = [];
  this.length = 0;

  if (data instanceof Array) {
    uv.each(data, function(datum, index) {
      that.set(index, datum);
    });
  } else if (data instanceof Object) {
    uv.each(data, function(datum, key) {
      that.set(key, datum);
    });
  }
};

// Returns a copy of the sorted hash
// Used by transformation methods
uv.SortedHash.prototype.clone = function () {
  var copy = new uv.SortedHash();
  copy.length = this.length;
  uv.each(this.data, function(value, key) {
    copy.data[key] = value;
  });
  copy.keyOrder = this.keyOrder.slice(0, this.keyOrder.length);
  return copy;
};

// Set a value at a given key
// Parameters:
//   * key [String]
uv.SortedHash.prototype.set = function (key, value, targetIndex) {
  if (key === undefined)
    return this;

  if (!this.data[key]) {
    if (targetIndex) { // insert at a given index
      var front = this.select(function(item, key, index) {
        return index < targetIndex;
      });

      var back = this.select(function(item, key, index) {
        return index >= targetIndex;
      });

      this.keyOrder = [].concat(front.keyOrder);
      this.keyOrder.push(key);
      this.keyOrder = this.keyOrder.concat(back.keyOrder);
    } else {
      this.keyOrder.push(key);
    }
    this.length += 1;
  }

  this.data[key] = value;
  return this;
};

// Get value at given key
// Parameters:
//   * key [String]
uv.SortedHash.prototype.get = function (key) {
  return this.data[key];
};

// Remove entry at given key
// Parameters:
//   * key [String]
uv.SortedHash.prototype.del = function (key) {
  if (this.data[key]) {
    this.keyOrder.splice($.inArray(key, this.keyOrder), 1);
    delete this.data[key];
    this.length -= 1;
  }
  return this;
};

// Get value at given index
// Parameters:
//   * index [Number]
uv.SortedHash.prototype.at = function (index) {
  var key = this.keyOrder[index];
  return this.data[key];
};

// Get first item
uv.SortedHash.prototype.first = function () {
  return this.at(0);
};

// Get last item
uv.SortedHash.prototype.last = function () {
  return this.at(this.length-1);
};

// Returns for an index the corresponding key
// Parameters:
//   * index [Number]
uv.SortedHash.prototype.key = function (index) {
  return this.keyOrder[index];
};

// Returns for a given key the corresponding index
uv.SortedHash.prototype.index = function(key) {
  return this.keyOrder.indexOf(key);
};

// Iterate over values contained in the SortedHash
// Parameters:
//   * [Function]
uv.SortedHash.prototype.each = function (f) {
  var that = this;
  uv.each(this.keyOrder, function(key, index) {
    f.call(that, that.data[key], key, index);
  });
  return this;
};

// Iterate over values contained in the SortedHash
// Parameters:
//   * [Function]
// uv.SortedHash.prototype.eachKey = function (f) {
//   var that = this;
//   uv.each(this.keyOrder, function (key, index) {
//     f.call(that, key, that.data[key]);
//   });
//   return this;
// };

// Convert to an ordinary JavaScript Array containing
// the values
//
// Returns:
//   * Array of items
uv.SortedHash.prototype.values = function () {
  var result = [];
  this.each(function(value, key, index) {
    result.push(value);
  });
  return result;
};

// Convert to an ordinary JavaScript Array containing
// key value pairs — used for sorting
//
// Returns:
//   * Array of key value pairs
uv.SortedHash.prototype.toArray = function () {
  var result = [];

  this.each(function(value, key) {
    result.push({key: key, value: value});
  });

  return result;
};

// Map the SortedHash to your needs
// Parameters:
//   * [Function]
uv.SortedHash.prototype.map = function (f) {
  var result = this.clone(),
      that = this;
  result.each(function(item, key, index) {
    result.data[that.key(index)] = f.call(result, item);
  });
  return result;
};

// Select items that match some conditions expressed by a matcher function
// Parameters:
//   * [Function] matcher function
uv.SortedHash.prototype.select = function (f) {
  var result = new uv.SortedHash(),
      that = this;

  this.each(function(value, key, index) {
    if (f.call(that, value, key, index)) {
      result.set(key, value);
    }
  });
  return result;
};

// Performs a sort on the SortedHash
// Parameters:
//   * comparator [Function] A comparator function
// Returns:
//   * The now re-sorted SortedHash (for chaining)
uv.SortedHash.prototype.sort = function (comparator) {
  var result = this.clone();
      sortedKeys = result.toArray().sort(comparator);

  // update keyOrder
  result.keyOrder = $.map(sortedKeys, function(k) {
    return k.key;
  });

  return result;
};

// Performs an intersection with the given SortedHash
// Parameters:
//   * sortedHash [SortedHash]
uv.SortedHash.prototype.intersect = function(sortedHash) {
  var that = this,
  result = new uv.SortedHash();

  this.each(function(value, key) {
    sortedHash.each(function(value2, key2) {
      if (key === key2) {
        result.set(key, value);
      }
    });
  });
  return result;
};

// Performs an union with the given SortedHash
// Parameters:
//   * sortedHash [SortedHash]
uv.SortedHash.prototype.union = function(sortedHash) {
  var that = this,
  result = new uv.SortedHash();

  this.each(function(value, key) {
    if (!result.get(key))
      result.set(key, value);
  });
  sortedHash.each(function(value, key) {
    if (!result.get(key))
      result.set(key, value);
  });
  return result;
};

// Aggregators
//-----------------------------------------------------------------------------

uv.Aggregators = {};

uv.Aggregators.SUM = function (values) {
  var result = 0;

  values.each(function(value, key, index) {
    result += value;
  });

  return result;
};

uv.Aggregators.MIN = function (values) {
  var result = Infinity;
  values.each(function(value, key, index) {
    if (value < result) {
      result = value;
    }
  });
  return result;
};

uv.Aggregators.MAX = function (values) {
  var result = -Infinity;
  values.each(function(value, key, index) {
    if (value > result) {
      result = value;
    }
  });
  return result;
};

uv.Aggregators.AVG = function (values) {
  return uv.Aggregators.SUM(values) / values.length;
};

uv.Aggregators.COUNT = function (values) {
  return values.length;
};

// Comparators
//-----------------------------------------------------------------------------

uv.Comparators = {};

uv.Comparators.ASC = function(item1, item2) {
  return item1.value === item2.value ? 0 : (item1.value < item2.value ? -1 : 1);
};

uv.Comparators.DESC = function(item1, item2) {
  return item1.value === item2.value ? 0 : (item1.value > item2.value ? -1 : 1);
};<commit_msg>Implemented SortedHash#delete.<commit_after>var root = this;

// Unveil.js
// =============================================================================

var uv = {};

// Constants
// -----------------------------------------------------------------------------

uv.EPSILON     = 0.0001;
uv.MAX_FLOAT   = 3.4028235e+38;
uv.MIN_FLOAT   = -3.4028235e+38;
uv.MAX_INT     = 2147483647;
uv.MIN_INT     = -2147483648;

// Utilities
// -----------------------------------------------------------------------------

uv.inherit = function (f) {
  function G() {}
  G.prototype = f.prototype || f;
  return new G();
};

uv.each = function(obj, iterator, context) {
  if (obj.forEach) {
    obj.forEach(iterator, context);
  } else {
    for (var key in obj) {
      if (hasOwnProperty.call(obj, key)) iterator.call(context, obj[key], key, obj);
    }
  }
  return obj;
};

uv.rest = function(array, index, guard) {
  return Array.prototype.slice.call(array, (index === undefined || guard) ? 1 : index);
};

uv.include = function(arr, target) {
  return arr.indexOf(target) != -1;
};

uv.select = uv.filter = function(obj, iterator, context) {
  if (obj.filter === Array.prototype.filter)
    return obj.filter(iterator, context);
  var results = [];
  uv.each(obj, function(value, index, list) {
    iterator.call(context, value, index, list) && results.push(value);
  });
  return results;
};

uv.extend = function(obj) {
  uv.rest(arguments).forEach(function(source) {
    for (var prop in source) obj[prop] = source[prop];
  });
  return obj;
};

// SortedHash
// =============================================================================

// Constructor
// Initializes a Sorted Hash
uv.SortedHash = function (data) {
  var that = this;
  this.data = {};
  this.keyOrder = [];
  this.length = 0;

  if (data instanceof Array) {
    uv.each(data, function(datum, index) {
      that.set(index, datum);
    });
  } else if (data instanceof Object) {
    uv.each(data, function(datum, key) {
      that.set(key, datum);
    });
  }
};

// Returns a copy of the sorted hash
// Used by transformation methods
uv.SortedHash.prototype.clone = function () {
  var copy = new uv.SortedHash();
  copy.length = this.length;
  uv.each(this.data, function(value, key) {
    copy.data[key] = value;
  });
  copy.keyOrder = this.keyOrder.slice(0, this.keyOrder.length);
  return copy;
};

// Set a value at a given key
// Parameters:
//   * key [String]
uv.SortedHash.prototype.set = function (key, value, targetIndex) {
  if (key === undefined)
    return this;

  if (!this.data[key]) {
    if (targetIndex) { // insert at a given index
      var front = this.select(function(item, key, index) {
        return index < targetIndex;
      });

      var back = this.select(function(item, key, index) {
        return index >= targetIndex;
      });

      this.keyOrder = [].concat(front.keyOrder);
      this.keyOrder.push(key);
      this.keyOrder = this.keyOrder.concat(back.keyOrder);
    } else {
      this.keyOrder.push(key);
    }
    this.length += 1;
  }

  this.data[key] = value;
  return this;
};

// Remove a given key from the Hash
uv.SortedHash.prototype.delete = function (key) {
  delete this.data[key];
  this.keyOrder.splice(this.index(key), 1);
  this.length -= 1;
  return this;
};

// Get value at given key
// Parameters:
//   * key [String]
uv.SortedHash.prototype.get = function (key) {
  return this.data[key];
};

// Remove entry at given key
// Parameters:
//   * key [String]
uv.SortedHash.prototype.del = function (key) {
  if (this.data[key]) {
    this.keyOrder.splice($.inArray(key, this.keyOrder), 1);
    delete this.data[key];
    this.length -= 1;
  }
  return this;
};

// Get value at given index
// Parameters:
//   * index [Number]
uv.SortedHash.prototype.at = function (index) {
  var key = this.keyOrder[index];
  return this.data[key];
};

// Get first item
uv.SortedHash.prototype.first = function () {
  return this.at(0);
};

// Get last item
uv.SortedHash.prototype.last = function () {
  return this.at(this.length-1);
};

// Returns for an index the corresponding key
// Parameters:
//   * index [Number]
uv.SortedHash.prototype.key = function (index) {
  return this.keyOrder[index];
};

// Returns for a given key the corresponding index
uv.SortedHash.prototype.index = function(key) {
  return this.keyOrder.indexOf(key);
};

// Iterate over values contained in the SortedHash
// Parameters:
//   * [Function]
uv.SortedHash.prototype.each = function (f) {
  var that = this;
  uv.each(this.keyOrder, function(key, index) {
    f.call(that, that.data[key], key, index);
  });
  return this;
};

// Convert to an ordinary JavaScript Array containing
// the values
//
// Returns:
//   * Array of items
uv.SortedHash.prototype.values = function () {
  var result = [];
  this.each(function(value, key, index) {
    result.push(value);
  });
  return result;
};

// Returns all keys in current order
uv.SortedHash.prototype.keys = function () {
  return this.keyOrder;
};

// Convert to an ordinary JavaScript Array containing
// key value pairs — used for sorting
//
// Returns:
//   * Array of key value pairs
uv.SortedHash.prototype.toArray = function () {
  var result = [];

  this.each(function(value, key) {
    result.push({key: key, value: value});
  });

  return result;
};

// Map the SortedHash to your needs
// Parameters:
//   * [Function]
uv.SortedHash.prototype.map = function (f) {
  var result = this.clone(),
      that = this;
  result.each(function(item, key, index) {
    result.data[that.key(index)] = f.call(result, item);
  });
  return result;
};

// Select items that match some conditions expressed by a matcher function
// Parameters:
//   * [Function] matcher function
uv.SortedHash.prototype.select = function (f) {
  var result = new uv.SortedHash(),
      that = this;

  this.each(function(value, key, index) {
    if (f.call(that, value, key, index)) {
      result.set(key, value);
    }
  });
  return result;
};

// Performs a sort on the SortedHash
// Parameters:
//   * comparator [Function] A comparator function
// Returns:
//   * The now re-sorted SortedHash (for chaining)
uv.SortedHash.prototype.sort = function (comparator) {
  var result = this.clone();
      sortedKeys = result.toArray().sort(comparator);

  // update keyOrder
  result.keyOrder = $.map(sortedKeys, function(k) {
    return k.key;
  });

  return result;
};

// Performs an intersection with the given SortedHash
// Parameters:
//   * sortedHash [SortedHash]
uv.SortedHash.prototype.intersect = function(sortedHash) {
  var that = this,
  result = new uv.SortedHash();

  this.each(function(value, key) {
    sortedHash.each(function(value2, key2) {
      if (key === key2) {
        result.set(key, value);
      }
    });
  });
  return result;
};

// Performs an union with the given SortedHash
// Parameters:
//   * sortedHash [SortedHash]
uv.SortedHash.prototype.union = function(sortedHash) {
  var that = this,
  result = new uv.SortedHash();

  this.each(function(value, key) {
    if (!result.get(key))
      result.set(key, value);
  });
  sortedHash.each(function(value, key) {
    if (!result.get(key))
      result.set(key, value);
  });
  return result;
};

// Aggregators
//-----------------------------------------------------------------------------

uv.Aggregators = {};

uv.Aggregators.SUM = function (values) {
  var result = 0;

  values.each(function(value, key, index) {
    result += value;
  });

  return result;
};

uv.Aggregators.MIN = function (values) {
  var result = Infinity;
  values.each(function(value, key, index) {
    if (value < result) {
      result = value;
    }
  });
  return result;
};

uv.Aggregators.MAX = function (values) {
  var result = -Infinity;
  values.each(function(value, key, index) {
    if (value > result) {
      result = value;
    }
  });
  return result;
};

uv.Aggregators.AVG = function (values) {
  return uv.Aggregators.SUM(values) / values.length;
};

uv.Aggregators.COUNT = function (values) {
  return values.length;
};

// Comparators
//-----------------------------------------------------------------------------

uv.Comparators = {};

uv.Comparators.ASC = function(item1, item2) {
  return item1.value === item2.value ? 0 : (item1.value < item2.value ? -1 : 1);
};

uv.Comparators.DESC = function(item1, item2) {
  return item1.value === item2.value ? 0 : (item1.value > item2.value ? -1 : 1);
};

<|endoftext|>


<commit_before>
function Spec (name, js, hb) {
  this.name = name
  this.js   = js
  this.hb   = hb
}

function extractJS (source) {
  return /``js\s([^(``)]+)```/gi.exec(source)[1]
}
function extractHB (source) {
  return /``hb\s([^(``)]+)```/gi.exec(source)[1]
}

function parseSpecification (source) {
  var openTagRegexp = new RegExp('<spec name="([0-9A-Za-z-_]+)">', 'g')
  var closingTag = '</spec>'

  var specs = [],
      match = null

  while ((match = openTagRegexp.exec(source)) != null) {
    var openingIndex = match.index,
        closingIndex = source.indexOf(closingTag, openingIndex)
    // String source of the spec
    var spec = source.slice(openingIndex + match[0].length, closingIndex)
    spec = spec.trim()
    // Pull out the name of the spec
    var name = match[1]
    // Extract the two sources from the spec body
    var jsSource, hbSource;
    try {
      jsSource = extractJS(spec)
    } catch(err) {
      throw new Error('Failed to find JavaScript source in '+name+' spec')
    }
    try {
      hbSource = extractHB(spec)
    } catch(err) {
      throw new Error('Failed to find Hummingbird source in '+name+' spec')
    }
    specs.push(new Spec(name, jsSource.trim(), hbSource.trim()))
  }
  return specs
}// parseSpecification

module.exports = {
  parseSpecification: parseSpecification,
  Spec: Spec
}
<commit_msg>Make sure specs can include `(` and `)` characters in their bodies without causing a parse error.<commit_after>
function Spec (name, js, hb) {
  this.name = name
  this.js   = js
  this.hb   = hb
}

function extractJS (source) {
  return /```js\s([^``]+)```/gi.exec(source)[1]
}
function extractHB (source) {
  return /```hb\s([^``]+)```/gi.exec(source)[1]
}

function parseSpecification (source) {
  var openTagRegexp = new RegExp('<spec name="([0-9A-Za-z-_]+)">', 'g')
  var closingTag = '</spec>'

  var specs = [],
      match = null

  while ((match = openTagRegexp.exec(source)) != null) {
    var openingIndex = match.index,
        closingIndex = source.indexOf(closingTag, openingIndex)
    // String source of the spec
    var spec = source.slice(openingIndex + match[0].length, closingIndex)
    spec = spec.trim()
    // Pull out the name of the spec
    var name = match[1]
    // Extract the two sources from the spec body
    var jsSource, hbSource;
    try {
      jsSource = extractJS(spec)
    } catch(err) {
      throw new Error('Failed to find JavaScript source in '+name+' spec')
    }
    try {
      hbSource = extractHB(spec)
    } catch(err) {
      throw new Error('Failed to find Hummingbird source in '+name+' spec')
    }
    specs.push(new Spec(name, jsSource.trim(), hbSource.trim()))
  }
  return specs
}// parseSpecification

module.exports = {
  parseSpecification: parseSpecification,
  Spec: Spec
}
<|endoftext|>


<commit_before>// Spine routing, based on Backbone's implementation.
//  Backbone.js 0.3.3
//  (c) 2010 Jeremy Ashkenas, DocumentCloud Inc.
//  Backbone may be freely distributed under the MIT license.
//  For all details and documentation:
//  http://documentcloud.github.com/backbone
//
// For usage, see examples/route.html

(function(Spine, $){
  var Route = Spine.Route = Spine.Class.create();

  var hashStrip = /^#*/;

  Route.extend({
    routes: [],

    historySupport: ("history" in window),
    history: false,

    add: function(path, callback){
      if (typeof path == "object")
        for(var p in path) this.add(p, path[p]);
      else
        this.routes.push(this.init(path, callback));
    },

    setup: function(useHistory){
      if (typeof useHistory != "undefined")
        this.history = this.historySupport && useHistory;

      if ( this.history )
        $(window).bind("popstate", this.proxy(this.change));
      else
        $(window).bind("hashchange", this.proxy(this.change));
      this.change();
    },

    navigate: function(){
      var path = Spine.makeArray(arguments).join("/");
      if (this.path == path) return;
      this.path = path;

      if (this.history)
        history.pushState({},
          document.title,
          this.getHost() + this.path
        );
      else
        window.location.hash = this.path;
    },

    // Private

    getPath: function(){
      return window.location.pathname;
    },

    getHash: function(){
      return window.location.hash;
    },

    getHost: function(){
      return((document.location + "").replace(
        this.getPath() + this.getHash(), ""
      ));
    },

    getFragment: function(){
      return this.getHash().replace(hashStrip, "");
    },

    change: function(e){
      var path = (this.history ? this.getPath() : this.getFragment());
      if (path == this.path) return;
      this.path = path;
      for (var i=0; i < this.routes.length; i++)
        if (this.routes[i].match(path)) return;
    }
  });

  var namedParam   = /:([\w\d]+)/g;
  var splatParam   = /\*([\w\d]+)/g;
  var escapeRegExp = /[-[\]{}()+?.,\\^$|#\s]/g;

  Route.include({
    init: function(path, callback){
      this.callback = callback;
      if (typeof path == "string") {
        path = path.replace(escapeRegExp, "\\$&")
                   .replace(namedParam, "([^\/]*)")
                   .replace(splatParam, "(.*?)");

        this.route = new RegExp('^' + path + '$');
      } else {
        this.route = path;
      }
    },

    match: function(path){
      var match = this.route.exec(path)
      if ( !match ) return false;
      var params = match.slice(1);
      this.callback.apply(this.callback, params);
      return true;
    }
  });

  Spine.Controller.fn.route = function(path, callback){
    Spine.Route.add(path, this.proxy(callback));
  };

  Spine.Controller.fn.routes = function(routes){
    for(var path in routes)
      this.route(path, routes[path]);
  };

  Spine.Controller.fn.navigate = function(){
    Spine.Route.navigate.apply(Spine.Route, arguments);
  };
})(Spine, Spine.$);<commit_msg>slight API change to routing setup<commit_after>// Spine routing, based on Backbone's implementation.
//  Backbone.js 0.3.3
//  (c) 2010 Jeremy Ashkenas, DocumentCloud Inc.
//  Backbone may be freely distributed under the MIT license.
//  For all details and documentation:
//  http://documentcloud.github.com/backbone
//
// For usage, see examples/route.html

(function(Spine, $){
  var Route = Spine.Route = Spine.Class.create();

  var hashStrip = /^#*/;

  Route.extend({
    routes: [],

    historySupport: ("history" in window),
    history: false,

    add: function(path, callback){
      if (typeof path == "object")
        for(var p in path) this.add(p, path[p]);
      else
        this.routes.push(this.init(path, callback));
    },

    setup: function(options){
      if (options && options.history)
        this.history = this.historySupport && options.history;

      if ( this.history )
        $(window).bind("popstate", this.proxy(this.change));
      else
        $(window).bind("hashchange", this.proxy(this.change));
      this.change();
    },

    navigate: function(){
      var path = Spine.makeArray(arguments).join("/");
      if (this.path == path) return;
      this.path = path;

      if (this.history)
        history.pushState({},
          document.title,
          this.getHost() + this.path
        );
      else
        window.location.hash = this.path;
    },

    // Private

    getPath: function(){
      return window.location.pathname;
    },

    getHash: function(){
      return window.location.hash;
    },

    getHost: function(){
      return((document.location + "").replace(
        this.getPath() + this.getHash(), ""
      ));
    },

    getFragment: function(){
      return this.getHash().replace(hashStrip, "");
    },

    change: function(e){
      var path = (this.history ? this.getPath() : this.getFragment());
      if (path == this.path) return;
      this.path = path;
      for (var i=0; i < this.routes.length; i++)
        if (this.routes[i].match(path)) return;
    }
  });

  var namedParam   = /:([\w\d]+)/g;
  var splatParam   = /\*([\w\d]+)/g;
  var escapeRegExp = /[-[\]{}()+?.,\\^$|#\s]/g;

  Route.include({
    init: function(path, callback){
      this.callback = callback;
      if (typeof path == "string") {
        path = path.replace(escapeRegExp, "\\$&")
                   .replace(namedParam, "([^\/]*)")
                   .replace(splatParam, "(.*?)");

        this.route = new RegExp('^' + path + '$');
      } else {
        this.route = path;
      }
    },

    match: function(path){
      var match = this.route.exec(path)
      if ( !match ) return false;
      var params = match.slice(1);
      this.callback.apply(this.callback, params);
      return true;
    }
  });

  Spine.Controller.fn.route = function(path, callback){
    Spine.Route.add(path, this.proxy(callback));
  };

  Spine.Controller.fn.routes = function(routes){
    for(var path in routes)
      this.route(path, routes[path]);
  };

  Spine.Controller.fn.navigate = function(){
    Spine.Route.navigate.apply(Spine.Route, arguments);
  };
})(Spine, Spine.$);<|endoftext|>