Wed Mar 22 2017
Copied to clipboard! Copy reply
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
  • 277
  • 278
  • 279
  • 280
  • 281
  • 282
  • 283
  • 284
  • 285
  • 286
  • 287
  • 288
  • 289
  • 290
  • 291
  • 292
  • 293
  • 294
  • 295
  • 296
  • 297
  • 298
  • 299
  • 300
  • 301
  • 302
  • 303
  • 304
  • 305
  • 306
  • 307
  • 308
  • 309
  • 310
  • 311
  • 312
  • 313
  • 314
  • 315
  • 316
  • 317
  • 318
  • 319
  • 320
  • 321
  • 322
  • 323
  • 324
  • 325
  • 326
  • 327
  • 328
  • 329
  • 330
  • 331
  • 332
  • 333
  • 334
  • 335
  • 336
  • 337
  • 338
  • 339
  • 340
  • 341
  • 342
  • 343
  • 344
  • 345
  • 346
  • 347
  • 348
  • 349
  • 350
  • 351
  • 352
  • 353
  • 354
  • 355
  • 356
  • 357
  • 358
  • 359
  • 360
  • 361
  • 362
  • 363
  • 364
  • 365
  • 366
  • 367
  • 368
  • 369
  • 370
  • 371
  • 372
  • 373
  • 374
  • 375
  • 376
  • 377
  • 378
  • 379
  • 380
  • 381
  • 382
  • 383
  • 384
  • 385
  • 386
  • 387
  • 388
  • 389
  • 390
var fs = require('fs');
var lo_ = require('lodash');
var path = require('path')
//npm install uglify-js@1.3.5
var jsp = require("uglify-js").parser;
var pro = require("uglify-js").uglify;
var clog = console.log;

    /*
     * Try to have this in a path relative to deploy folder,
     * so it will work out of the box if someone tries to
     * to go through the deployment process on their machine
     * instead of the ashclp00 server
     */
    var envslash = path.sep;
    var workingPath = path.dirname(__dirname) + envslash
    var promospath = workingPath + "../data/promos.json";
    var pagesjsonpath = workingPath + "../data/pages.json";
    var productspath = workingPath + "../data/pony.json";
    var shellpath = __dirname + envslash + "rsishell.js";
    console.log("vinoth"+workingPath)
    var rsifolderpath = workingPath + "../rsi" + envslash;
    var queryinpath = workingPath + "queryops.json";

var basecart = 'https://secure.rosettastone.com/us_en_store_view/checkout/cart/add/';

var applypromodiscounts = require(__dirname+envslash+"applypromodiscounts.js");



//language configs for other than default: rsiparser -a -his
switch(process.argv.slice(-1)[0])
{
    case '-his':
            //console.log("Config: Hispanic US");
            basecart = "https://secure.rosettastone.com/hispanic_store_view/checkout/cart/add/"
            promospath = workingPath + "data/promos.json";
            pagesjsonpath = workingPath + "data/pages-his.json";
            rsifolderpath = workingPath + envslash + "rsi-his" + envslash;
            queryinpath = workingPath + "queryops-his.json";
        break;
    default:
        //console.log("Config: Default (US/Eng)");
}

//remove when pages.json
// eval(fs.readFileSync(pagesjsonpath).toString());
var pages = JSON.parse( fs.readFileSync(pagesjsonpath) );


//var pages = JSON.parse( fs.readFileSync(pagesjsonpath) );
//console.log("Loaded pages.json...");
var qbpromos = JSON.parse( fs.readFileSync(promospath) ).promos;


//console.log("Loaded qbpromos...");
var qbprod = JSON.parse( fs.readFileSync(promospath) ).prodinfo;

//console.log("Loaded qb prod info...");
var products = JSON.parse( fs.readFileSync(productspath) );
//console.log("Loaded products...");
var querytargets = JSON.parse(fs.readFileSync(queryinpath));
//console.log("Loaded query targets");
//transform 1st arg in each array to regexp:
querytargets = lo_.map(querytargets, function(v){ v[0] = new RegExp(v[0]); return v; })

var arg = process.argv.slice(2,3);

function descendparse(obj, patharr) {
  patharr = patharr || [];
  if (typeof obj !== "object")
  {
    patharr.push("#" + obj.toString());
    return [patharr];
  }
  else
  {
    var ret = [];
    for(var i in obj)
    {
      var prepend = patharr.slice();
      var subpaths = descendparse(obj[i], prepend.concat(i));
      for(var j=0,l=subpaths.length; j < l; j++)
      {
        ret.push(subpaths[j]);
      }
    }
    return ret;
  }
}

function parseProducts(products) {
    var ret = [];
    var keys = lo_.keys(products);
    lo_.each(keys, function(v){
        var langcode = v;
        var parsed = descendparse(products[v]);
        var lang = parsed.shift()[1].slice(1);
        // console.log("parsed:");
        // console.log(parsed);
        var interpreted = lo_(parsed).map(function(v){
            var ret;
            if(!(v instanceof Array === true && v.length >= 1))
              {return false;}
            ret = {};
            //shift off "products"
            v.shift();
            if(v[0] === "course")
            {
              ret.family = "course";
              ret.cat = langcode;
              ret.lvl = v[1];
              ret.sku = v[4] && v[4].slice(1);
              ret.media = v[2];
              ret.promokey = (ret.media + "_" + ret.lvl).toUpperCase();
              return ret;
            }
            else if(v[0] === "totale")
            {
              ret.family = "totale";
              ret.cat = langcode;
              ret.lvl = v[2];
              ret.sku = v[4] && v[4].slice(1);
              ret.media = v[1];
              ret.promokey = ("TO" + ret.media.slice(0, 3) + "_" + ret.lvl).toUpperCase();
              return ret;
            }
            else
            {
               return false;
            }
        })
        .compact()
        .valueOf();
        // console.log("interp");
        // console.log(interpreted);
        ret = ret.concat(interpreted);
    });

    return ret;
}

function preparecode(cd) {

    try {
        var ast = jsp.parse(cd); // parse code and get the initial AST
    }
    catch(e) {
        console.log(e);
        return false;
    }
    ast = pro.ast_mangle(ast); // get a new AST with mangled names
    ast = pro.ast_squeeze(ast); // get an AST with compression optimizations
    var final_code = pro.gen_code(ast); // compressed code here

    return final_code;
}

function getcartapi(cat,sku,pc) {

    if(!(cat && sku))
    {
        return false;
    }

    //switch(process.argv.slice(-1)[0])
    //var _base = basecart;
    //hispanic_store_view
    var _pc = pc ? '/?pc=' + pc : "";

    return (
        basecart
        + 'sku/' + sku + '/'
        + 'category_id/' + cat.toLowerCase()
        + _pc
    );
}

function getcartEEapi(cat,sku,pc,eeObject) {

    if(!(cat && sku))
    {
        return false;
    }

    //switch(process.argv.slice(-1)[0])
    //var _base = basecart;
    //hispanic_store_view
    var _pc = pc ? '/?pc=' + pc : "";

    return (
        basecart
        + 'cid/' + eeObject.cid + '/'
        + 'gl/' + eeObject.gl + '/'
        + 'sl/' + eeObject.sl + '/'
        + 'sku/' + sku + '/'
        + 'category_id/' + cat.toLowerCase()
        + _pc
    );
}

function processRSI(rsi, processRSI_cb) {
    
    console.log('Processing ' + rsi + '...');
    
    var rsidata = pages[rsi];
    
    if(!rsidata)
    {
        processRSI_cb("RSI does not exist.");
        return;
    }
    var promocode = rsidata.promo || "";
    var promodata = qbpromos[promocode];
    var productsarray = parseProducts(products);

    var isEE = typeof rsidata['ee'] != "undefined" ? true : false;
    var eeObject = {};
   
    if(isEE){
        if(
            typeof rsidata['ee']['gl'] != "undefined" && 
            typeof rsidata['ee']['sl'] != "undefined" &&
            typeof rsidata['ee']['cid'] != "undefined"
        ){
            eeObject.gl =  rsidata['ee']['gl']      
            eeObject.sl =  rsidata['ee']['sl']      
            eeObject.cid =  rsidata['ee']['cid']    
        }else{
            processRSI_cb("EE parameters missing");
            return;
        }            
    }

    /*
     * Auto calculate 5pay and percenrageoff,
     * ONLY if it's not present in the rsi object.
     */
    var promoprice;
    try {
        var promoprice = qbpromos[promocode]['BOX_S5'].price
    } catch (e) {
        if (e) console.log('[rsiparser] promocode is not in promos.json: ', promocode)
    }

    if (promoprice) {
        if (!rsidata.header.fivePay) {
            rsidata.header.fivePay = Math.ceil(promoprice/5)
        }
        if (!rsidata.percentoff) {
            var diff = 499 - parseInt(promoprice)
            rsidata.percentoff = Math.floor((diff/499)*100)
        }
    }

    //


    productsarray = lo_.map(productsarray, function(v){
        
        var prodinfo = (qbprod && qbprod[v.promokey.split("_")[0]]);
        prodinfo = prodinfo && prodinfo[v.promokey.split("_")[1]];
        v.desc = (!!prodinfo && prodinfo["qb_desc"]) || "";
        v.img = (!!prodinfo && prodinfo["qb_img"]) || "";
        v.name = (!!prodinfo && prodinfo["qb_name"]) || "";
        v.msrp = (!!prodinfo && prodinfo["qb_price"]) || "";

        v.code = (promodata && promodata[v.promokey] && promodata[v.promokey].code ) || "";
        v.price = (promodata && promodata[v.promokey] && promodata[v.promokey].price );
        v.language = products[v.cat] && products[v.cat].language;
        
        v.cart = (!isEE) ? getcartapi(v.cat, v.sku, v.code) : getcartEEapi(v.cat, v.sku, v.code, eeObject);

        
        //no price listed in promos; Panic and get it from 'sitewide'
        if(!v.price)
        {
            //console.log(v.promokey);
            //console.log(Object.keys(qbpromos["sitewide"]));
            v.price = (qbpromos["sitewide"][v.promokey] && qbpromos["sitewide"][v.promokey].price );
            v.code = (qbpromos["sitewide"][v.promokey] && qbpromos["sitewide"][v.promokey].code ) || v.code;
        }
        //As a last resort, suppress products with no price...
        if(!v.cart)
        {
            //no cart link for product: suppress and report
            //console.log("Suppressing: " + v.cat + v.promokey + ' ...no sku/cart');
            return false;
        }
        if(!v.price)
        {
            //no price for product: suppress and report
            //console.log("Suppressing: " + v.cat + '::' + v.promokey + ' ...no price');
            return false;
        }
        //If specified, take a further %age discount off the marked promo price.
        /*if (rsidata.header.discount) {
            v.price = Math.ceil(v.price * (1-rsidata.header.discount));
        }*/
        return v;
    });
    productsarray = lo_.compact(productsarray);
        
    //productsarray set
    //console.log(querytargets[0][0]);
    var queriestoapply = lo_.filter(querytargets,function(v){
        return v[0] && v[0].test && v[0].test(rsi);
    });
    //console.log(queriestoapply);
    lo_.each(queriestoapply, function(v){
        //apply the query to matching products
        var productselector = v[1];
        var application = v[2];
        var prodstmp = lo_(productsarray)
            .map(function(v){ return lo_.every(productselector, function(selectval,selectkey){
                    //i.e. "If every property in the product matches every property in the selector, apply the operation"
                    return v[selectkey] && v[selectkey] == selectval;
                }) ? lo_.assign(v, application) : v;
            }).value();
        //console.log(prodstmp);
        productsarray = prodstmp;
    });
    var rsikvpairs = [];
    var rsikeys = Object.getOwnPropertyNames(rsidata);
    var k;
    while(rsikeys.length)
    {
        k = rsikeys[0];
        rsikvpairs.push([k,JSON.stringify(rsidata[k])]);
        rsikeys.shift();
    }
    //console.log(rsi);
    //console.log(JSON.stringify(rsidata));




    rsikvpairs.push(["rsi", (rsi && "'" + rsi + "'") || "'sitewide'"]);
    var rsiprops = lo_.map(rsikvpairs, function(v){
        return "RSI." + v[0] + " = " + v[1] + ";";
    });
    rsiprops = rsiprops.join("\n");
    var shelltext = fs.readFileSync(shellpath, "utf-8");
    var rsijs = shelltext.replace("####PRODUCTS####", JSON.stringify(productsarray)).replace("####RSIPROPERTIES####", rsiprops);

    rsijs = preparecode(rsijs);

    processRSI_cb(!rsijs, rsijs, rsi);

}

function RSIHandler(e,r,_rsicode){
        _rsicode = _rsicode || "sitewide";
        if(!e)
        {
            if(!fs.existsSync(rsifolderpath + _rsicode + envslash)) {
                fs.mkdirSync(rsifolderpath + _rsicode + envslash);
            }
            // Drop the model inside rsi/<pagename>modle.js  and globals/models/<pagename>.js           
            fs.writeFileSync(rsifolderpath + _rsicode + envslash + "model.js", r);
            fs.writeFileSync(workingPath + '../deploy/globals/models/' + _rsicode + '.js', r)
        }
        else
        {
            console.log("Error processing RSI: " + e);
        }
}

qbpromos = applypromodiscounts(qbpromos);


if ((arg && arg[0]) === "-a")
{
    //console.log("Compiling all RSIs...");
    var allrsi = Object.keys(pages);
    
    while(allrsi.length)
    {
        processRSI(allrsi.pop(), RSIHandler);
    }
}
else
{
    processRSI(arg, RSIHandler);
}
// var shelltxt = fs.readFileSync(shellpath, "utf-8");
// console.log(preparecode(shelltxt));