function install (gyp, argv, callback) {

  // ensure no double-callbacks happen
  function cb (err) {
    if (cb.done) return
    cb.done = true
    if (err) {
      gyp.verbose('got an error, rolling back install')
      // roll-back the install if anything went wrong
      gyp.commands.remove([ version ], function (err2) {
        callback(err)
      })
    } else {
      callback(null, version)
    }
  }


  // Determine which node dev files version we are installing
  var versionStr = argv[0] || gyp.opts.target || process.version
  gyp.verbose('input version string', versionStr)

  // parse the version to normalize and ensure it's valid
  var version = semver.parse(versionStr)
  if (!version) {
    return callback(new Error('Invalid version number: ' + versionStr))
  }

  // "legacy" versions are 0.7 and 0.6
  var isLegacy = semver.lt(versionStr, '0.8.0')
  gyp.verbose('installing legacy version?', isLegacy)

  if (semver.lt(versionStr, '0.6.0')) {
    return callback(new Error('Minimum target version is `0.6` or greater. Got: ' + versionStr))
  }

  // 0.x.y-pre versions are not published yet. Use previous release.
  if (version[5] === '-pre') {
    version[3] = +version[3] - 1
    version[5] = null
    gyp.verbose('-pre version detected, adjusting patch version')
  }

  // flatten version into String
  version = version.slice(1, 4).join('.')
  gyp.verbose('installing version', version)


  // TODO: Make ~/.node-gyp configurable
  var devDir = path.resolve(process.env.HOME, '.node-gyp', version)

  // If '--ensure' was passed, then don't *always* install the version,
  // check if it is already installed, and only install when needed
  if (gyp.opts.ensure) {
    gyp.verbose('--ensure was passed, so won\'t reinstall if already installed')
    fs.stat(devDir, function (err, stat) {
      if (err) {
        if (err.code == 'ENOENT') {
          gyp.verbose('version not already installed, continuing with install', version)
          go()
        } else {
          cb(err)
        }
        return
      }
      gyp.verbose('version is already installed, need to check "installVersion"')
      var installVersionFile = path.resolve(devDir, 'installVersion')
      fs.readFile(installVersionFile, 'ascii', function (err, ver) {
        if (err && err.code != 'ENOENT') {
          return cb(err)
        }
        var installVersion = parseInt(ver, 10) || 0
        gyp.verbose('got "installVersion":', installVersion)
        gyp.verbose('needs "installVersion":', gyp.package.installVersion)
        if (installVersion < gyp.package.installVersion) {
          gyp.verbose('version is no good; reinstalling')
          go()
        } else {
          gyp.verbose('version is good')
          cb()
        }
      })
    })
  } else {
    go()
  }

  function download(url,onError) {
    gyp.info('downloading:', url)
    var requestOpts = {
        uri: url
      , onResponse: true
    }

    // basic support for a proxy server
    var proxyUrl = gyp.opts.proxy
                || process.env.http_proxy
                || process.env.HTTP_PROXY
                || process.env.npm_config_proxy
    if (proxyUrl) {
      gyp.verbose('using proxy:', proxyUrl)
      requestOpts.proxy = proxyUrl
    }
    return request(requestOpts, onError)
  }

  function go () {

  // first create the dir for the node dev files
  mkdir(devDir, function (err) {
    if (err) return cb(err)

    // TODO: Detect if it was actually created or if it already existed
    gyp.verbose('created:', devDir)

    // now download the node tarball
    var tarballUrl = distUrl + '/v' + version + '/node-v' + version + '.tar.gz'
      , badDownload = false
      , extractCount = 0
      , gunzip = zlib.createGunzip()
      , extracter = tar.Extract({ path: devDir, strip: 1, filter: isValid })

    // checks if a file to be extracted from the tarball is valid.
    // only .h header files and the gyp files get extracted
    function isValid () {
      var name = this.path.substring(devDir.length + 1)
        , _valid = valid(name)
      if (name === '' && this.type === 'Directory') {
        // the first directory entry is ok
        return true
      }
      if (_valid) {
        gyp.verbose('extracted file from tarball', name)
        extractCount++
      } else {
        // invalid
      }
      return _valid
    }

    gunzip.on('error', cb)
    extracter.on('error', cb)
    extracter.on('end', afterTarball)

    // download the tarball, gunzip and extract!
    var req = download(tarballUrl, downloadError)
      .pipe(gunzip)
      .pipe(extracter)

    // something went wrong downloading the tarball?
    function downloadError (err, res) {
      if (err || res.statusCode != 200) {
        badDownload = true
        cb(err || new Error(res.statusCode + ' status code downloading tarball'))
      }
    }

    // invoked after the tarball has finished being extracted
    function afterTarball () {
      if (badDownload) return
      if (extractCount === 0) {
        return cb(new Error('There was a fatal problem while downloading/extracting the tarball'))
      }
      gyp.verbose('done parsing tarball')
      var async = 0

      if (isLegacy) {
        // copy over the files from the `legacy` dir
        async++
        copyLegacy(deref)
      }

      if (win) {
        // need to download node.lib
        async++
        downloadNodeLib(deref)
      }

      // write the "installVersion" file
      async++
      var installVersionPath = path.resolve(devDir, 'installVersion')
      fs.writeFile(installVersionPath, gyp.package.installVersion + '\n', deref)

      if (async === 0) {
        // no async tasks required
        cb()
      }

      function deref (err) {
        if (err) return cb(err)
        --async || cb()
      }
    }

    function copyLegacy (done) {
      // legacy versions of node (< 0.8) require the legacy files to be copied
      // over since they contain many bugfixes from the current node build system
      gyp.verbose('copying "legacy" gyp configuration files for version', version)

      var legacyDir = path.resolve(__dirname, '..', 'legacy')
      gyp.verbose('using "legacy" dir', legacyDir)
      gyp.verbose('copying to "dev" dir', devDir)

      var reader = fstream.Reader({ path: legacyDir, type: 'Directory' })
        , writer = fstream.Writer({ path: devDir, type: 'Directory' })

      reader.on('entry', function onEntry (entry) {
        gyp.verbose('reading entry', entry.path)
        entry.on('entry', onEntry)
      })

      reader.on('error', done)
      writer.on('error', done)

      // Like `cp -rpf`
      reader.pipe(writer)

      reader.on('end', done)
    }

    function downloadNodeLib (done) {
      gyp.verbose('on Windows; need to download `node.lib`...')
      // TODO: windows 64-bit support
      var releaseDir = path.resolve(devDir, 'Release')
        , debugDir = path.resolve(devDir, 'Debug')
        , nodeLibUrl = distUrl + '/v' + version + '/node.lib'

      gyp.verbose('Release dir', releaseDir)
      gyp.verbose('Debug dir', debugDir)
      gyp.verbose('`node.lib` url', nodeLibUrl)
      // TODO: parallelize mkdirs
      mkdir(releaseDir, function (err) {
        if (err) return done(err)
        mkdir(debugDir, function (err) {
          if (err) return done(err)
          // TODO: clean this mess up, written in a hastemode-9000
          var badDownload = false
          var res = download(nodeLibUrl, function (err, res) {
            if (err || res.statusCode != 200) {
              badDownload = true
              done(err || new Error(res.statusCode + ' status code downloading node.lib'))
            }
          })
          var releaseDirNodeLib = path.resolve(releaseDir, 'node.lib')
            , debugDirNodeLib = path.resolve(debugDir, 'node.lib')
            , rws = fs.createWriteStream(releaseDirNodeLib)
            , dws = fs.createWriteStream(debugDirNodeLib)
          gyp.verbose('streaming to', releaseDirNodeLib)
          gyp.verbose('streaming to', debugDirNodeLib)
          res.pipe(rws)
          res.pipe(dws)
          res.on('end', function () {
            if (badDownload) return
            done()
          })
        })
      })
    }


  })

  }

  /**
   * Checks if a given filename is "valid" for this installation.
   */

  function valid (file) {
      // header files
    return minimatch(file, '*.h', { matchBase: true })
      // non-legacy versions of node also extract the gyp build files
      || (!isLegacy &&
            (minimatch(file, '*.gypi', { matchBase: true })
          || minimatch(file, 'tools/gyp_addon')
          || (minimatch(file, 'tools/gyp/**') && !minimatch(file, 'tools/gyp/test/**'))
            )
         )
  }

}
Example #2
0
FSWatcher.prototype._emit = function(event, path, val1, val2, val3) {
  if (this.options.cwd) path = sysPath.relative(this.options.cwd, path);
  var args = [event, path];
  if (val3 !== undefined) args.push(val1, val2, val3);
  else if (val2 !== undefined) args.push(val1, val2);
  else if (val1 !== undefined) args.push(val1);

  var awf = this.options.awaitWriteFinish;
  if (awf && this._pendingWrites[path]) {
    this._pendingWrites[path].lastChange = new Date();
    return this;
  }

  if (this.options.atomic) {
    if (event === 'unlink') {
      this._pendingUnlinks[path] = args;
      setTimeout(function() {
        Object.keys(this._pendingUnlinks).forEach(function(path) {
          this.emit.apply(this, this._pendingUnlinks[path]);
          this.emit.apply(this, ['all'].concat(this._pendingUnlinks[path]));
          delete this._pendingUnlinks[path];
        }.bind(this));
      }.bind(this), typeof this.options.atomic === "number"
        ? this.options.atomic
        : 100);
      return this;
    } else if (event === 'add' && this._pendingUnlinks[path]) {
      event = args[0] = 'change';
      delete this._pendingUnlinks[path];
    }
  }

  var emitEvent = function() {
    this.emit.apply(this, args);
    if (event !== 'error') this.emit.apply(this, ['all'].concat(args));
  }.bind(this);

  if (awf && (event === 'add' || event === 'change') && this._readyEmitted) {
    var awfEmit = function(err, stats) {
      if (err) {
        event = args[0] = 'error';
        args[1] = err;
        emitEvent();
      } else if (stats) {
        // if stats doesn't exist the file must have been deleted
        if (args.length > 2) {
          args[2] = stats;
        } else {
          args.push(stats);
        }
        emitEvent();
      }
    };

    this._awaitWriteFinish(path, awf.stabilityThreshold, event, awfEmit);
    return this;
  }

  if (event === 'change') {
    if (!this._throttle('change', path, 50)) return this;
  }

  if (
    this.options.alwaysStat && val1 === undefined &&
    (event === 'add' || event === 'addDir' || event === 'change')
  ) {
    var fullPath = this.options.cwd ? sysPath.join(this.options.cwd, path) : path;
    fs.stat(fullPath, function(error, stats) {
      // Suppress event when fs.stat fails, to avoid sending undefined 'stat'
      if (error || !stats) return;

      args.push(stats);
      emitEvent();
    });
  } else {
    emitEvent();
  }

  return this;
};
Example #3
0
        function search(dirs) {

            if (dirs.length == 0) {

                // Can't find matches[1] in any of the this.docroot directories,
                // return 404.

                notFound();
                return;

            }

            var filename = path.join(dirs[0], matches[1]);

            if (filename.indexOf(dirs[0]) !== 0) {

                // Hack attempt; docroot is not a parent of the requested file,
                // return 404.

                notFound();
                return;

            }

            fs.stat(filename, function (error, stat) {

                if (error) {

                    // filename doesn't exist (in this directory), try the next
                    // one.

                    search(dirs.slice(1));
                    return;

                }

                if (stat.isFile()) {

                    // File exists, try to read it

                    var contentType = mime.extToType(path.extname(filename));
                    var encoding = contentType.slice(0, 4) !== "text" ? "binary" : "utf8"; // TODO Not reliable!

                    fs.readFile(filename, encoding, function (error, body) {

                        if (error) {

                            // Couldn't return cat() file (unreadable?), return 404.

                            notFound();
                            return;

                        }

                        res.writeHead(200, {
                            "content-type": contentType,
                            "content-length": body.length
                        });

                        res.write(body, encoding);
                        res.end();

                    });

                } else {

                    // Exists, but not a file (directory?).  Return 404.

                    notFound();
                    return;

                }

            });

            return;

        }
Example #4
0
function read(req, options, file, callback) {
  var scope = this;
  var fo = typeof file === 'object' && file.file;
  if(fo) {
    fo = file;
    file = file.file;
  }
  file = resolve(file);
  //console.log('read file %s', file);
  var log = this.log, recursive = options.recursive, item = {};
  var filter = options.filter;
  fs.stat(file, function(err, stats) {
    var exists = !err && typeof stats === 'object';
    if(typeof filter === 'function' && !filter(file, options, err, stats)) {
      if(options.warn) {
        log.warn('ignore %s', file);
      }
      return callback(null);
    }

    if(!exists && options.warn) {
      log.warn('file %s (%s)', file, err.code);
    }

    function load(file, dir, stats, callback) {
      if(!exists && !options.all) return callback(null);
      item = {file: fo || fileobject(file, dir),
        stats: stats, err: err, exists: exists};

      if(options.patterns && !match(item.file, options.patterns)) {
        console.log('match on glob patterns %j', options.patterns);
        return callback(null);
      }

      if(exists && options.require) {
        var res = include(file);
        if(res instanceof Error) {
          item.err = res;
          if(options.warn) {
            log.warn('file %s (%s)', file, (res.message || '').toLowerCase());
          }
        }else{
          //console.dir('asign to item');
          item.doc = res;
        }
      }
      //console.log('callback item %s', item.file.file);
      callback(null, item);
    }

    function readlist(item, file, concat, cb) {
      if(concat) item = path.join(file, item);
      //console.log('read item %s', item);
      fs.stat(item, function(err, stats) {
        if(err) return callback(err);
        if(stats && stats.isFile()) {
          //console.log('loading item %s', item);
          return load(item, file, stats, cb);
        }
        cb(null);
      })
    }

    if(stats && stats.isDirectory()) {
      if(recursive) {
        //console.log('recursive walk on %s', file);
        walk(file, function(err, files) {
          if(err) return callback(err);
          //console.dir(files);
          async.concatSeries(files, function(item, callback) {
            //console.log('walk recursive item %s', item);
            readlist(item, file, false, callback);
          }, function(err, results) {
            return callback(err, results);
          })
        })
      }else{
        //console.log('read non-recursive directory %s', file);
        fs.readdir(file, function(err, files) {
          if(err) return callback(err);
          async.concatSeries(files, function(item, callback) {
            readlist(item, file, true, callback);
          }, function(err, results) {
            return callback(err, results);
          })
        })
      }
    }else {
      load(file, path.dirname(file), stats, callback);
    }
  });
}
Example #5
0
self.reload();self.refresh();return true};Async.prototype.complete=function(fn){return this.run(fn)};Async.prototype.run=function(fn){var self=this;self._isRunning=true;if(fn)self.onComplete.push(fn);self.refresh();return self};Async.prototype.isRunning=function(name){var self=this;if(!name)return self._isRunning;var task=self.tasksPending[name];if(!task)return false;return task.isRunning===1};Async.prototype.isWaiting=function(name){var self=this;var task=self.tasksPending[name];if(!task)return false;return task.isRunning===0};Async.prototype.isPending=function(name){var self=this;var task=self.tasksPending[name];if(!task)return false;return true};Async.prototype.timeout=function(name,timeout){var self=this;if(timeout<=0||typeof timeout===UNDEFINED){delete self.tasksTimeout[name];return self}self.tasksTimeout[name]=timeout;return self};Async.prototype.refresh=function(name){var self=this;if(!self._isRunning)return self;self._count=self.tasksAll.length;for(var i=0;i<self._count;i++){var task=self.tasksPending[self.tasksAll[i]];if(task.isRunning!==0)continue;if(task.waiting!==null&&typeof self.tasksWaiting[task.waiting]!==UNDEFINED)continue;task.run()}if(self._count===0){self._isRunning=false;self.emit("complete");self.emit("percentage",100);self._max=0;var complete=self.onComplete;var length=complete.length;self.onComplete=[];for(var i=0;i<length;i++){try{complete[i]()}catch(ex){self.emit("error",ex)}}}return self};function FileList(){this.pending=[];this.pendingDirectory=[];this.directory=[];this.file=[];this.onComplete=null;this.onFilter=null}FileList.prototype.reset=function(){var self=this;self.file=[];self.directory=[];self.pendingDirectory=[]};FileList.prototype.walk=function(directory){var self=this;if(directory instanceof Array){var length=directory.length;for(var i=0;i<length;i++)self.pendingDirectory.push(directory[i]);self.next();return}fs.readdir(directory,function(err,arr){if(err)return self.next();var length=arr.length;for(var i=0;i<length;i++)self.pending.push(path.join(directory,arr[i]));self.next()})};FileList.prototype.stat=function(path){var self=this;fs.stat(path,function(err,stats){if(err)return self.next();if(stats.isDirectory()&&(self.onFilter===null||self.onFilter(path,true))){self.directory.push(path);self.pendingDirectory.push(path);self.next();return}if(self.onFilter===null||self.onFilter(path,false))self.file.push(path);self.next()})};FileList.prototype.next=function(){var self=this;if(self.pending.length>0){var item=self.pending.shift();self.stat(item);return}if(self.pendingDirectory.length>0){var directory=self.pendingDirectory.shift();self.walk(directory);return}self.onComplete(self.file,self.directory)};exports.Async=Async;exports.sync=function(fn,owner){return function(){var args=[].slice.call(arguments);var params;var callback;var executed=false;var self=owner||this;args.push(function(){params=arguments;if(!executed&&callback){executed=true;callback.apply(self,params)}});fn.apply(self,args);return function(cb){callback=cb;if(!executed&&params){executed=true;callback.apply(self,params)}}}};exports.async=function(fn){return function(complete){var self=this;var generator=fn();next(null);function next(err,result){var g;try{switch(err===null){case true:g=generator.next(result);break;case false:g=generator.throw(err);break}}catch(e){if(complete){if(typeof complete===OBJECT&&complete.view500)complete.view500(e);else complete(e)}return}if(g.done){if(complete&&typeof complete!==OBJECT)complete(null,g.value);return}if(typeof g.value!==FUNCTION){next.call(self,null,g.value);return}try{g.value.call(self,function(){next.apply(self,arguments)})}catch(e){setImmediate(function(){next.call(self,e)})}}return generator.value}};global.async=exports.async;global.sync=exports.sync;
Example #6
0
var fs = require("fs");
fs.stat("nexttick.js",function(err, stats){
  if(stats) { console.log("nexttick.js Exists 1"); }
});
setImmediate(function(){
  console.log("Immediate Timer 1 Executed");
});
setImmediate(function(){
  console.log("Immediate Timer 2 Executed");
});
setImmediate(function(){
  console.log("Immediate Timer 3 Executed");
});
setImmediate(function(){
  console.log("Immediate Timer 4 Executed");
});



process.nextTick(function(){
  console.log("Next Tick 1 Executed");
});
process.nextTick(function(){
  console.log("Next Tick 2 Executed");
});
Example #7
0
 async.filter(hosts, function (host, callback) {
   fs.stat([config['data-directory'], host].join("/"), function (err, stat) {
     callback(!stat.isFile() && (match ? host.match(match) : true));
   });
 }, function (data) {
Example #8
0
Box.upload = function (req,res,next) {
  if(req.session.accessedClouds.box) {
    fs.stat(req.files.file.path, function (err, stats) {
      restler.post("https://upload.box.com/api/2.0/files/content", {
        headers:{'Authorization': 'Bearer ' + req.session.box_access_token},
        multipart: true,
        data: {
          "folder_id": "0",
          "filename": restler.file(path.join(req.files.file.path), req.files.file.originalname, stats.size, req.files.file.originalname, req.files.file.mimetype)
        }
      }).on("complete", function (err, response, body) {
          // TODO: Error catch
          // status code 409 signifies that a file with the same name is already in this folder, need to catch for this
          if(JSON.parse(response.statusCode)) {
            // repeat file name error catch here
          }
          next();
      });
    });
  } else {
    next();
  }
};
Example #9
0
 this.dummy.runHooks(function (err) {
   if (err) {
     return err;
   }
   fs.stat('app/scripts/models/application-model.js', done);
 });
Example #10
0
                    fs.stat(binPath, (err, stats) => {
                        if (stats && stats.isFile()) {
                            filesToPush.push(binPath);
                        } else {
                            callback(errMsg.badNumberOfADXFiles);
                            return;
                        }
                        const qexPath = path.resolve(path.join(self.configurator.path, common.QEX_PATH, name + '.qex'));
                        fs.stat(qexPath, (err, stats) => {
                            if (stats && stats.isFile()) {
                                filesToPush.push(qexPath);
                            }
                            const previewPath = path.resolve(path.join(self.configurator.path, 'preview.png'));
                            fs.stat(previewPath, (err, stats) => {
                                if (stats && stats.isFile()) {
                                    filesToPush.push(previewPath);
                                }
                                uploadAvailableFiles(self, filesToPush, article.id, (err, attachments) => {
                                    if (err) {
                                        callback(err);
                                        return;
                                    }

                                    self.writeSuccess(successMsg.zenDeskAttachmentsUploaded);

                                    const replacements = [
                                        {
                                            pattern : /\{\{ADXQexFileURL\}\}/gi,
                                            replacement : (attachments.qex && attachments.qex.id) ?  ('<li>To download the qex file, <a href="/hc/en-us/article_attachments/' + attachments.qex.id + '/' + attachments.qex.name + '">click here</a></li>') : ""
                                        },
                                        {
                                            pattern : /\{\{ADXFileURL\}\}/gi,
                                            replacement : '<a href="/hc/en-us/article_attachments/' + attachments.adx.id + '/' + attachments.adx.name + '">click here</a>'
                                        }
                                    ];

                                    // TODO::We should upload the file to the demo server from this app
                                    //'/hc/en-us/article_attachments/' + attachmentsIDs.png.id + '/' + attachmentsIDs.png.name 
                                    const urlToPointAt = self.options.demoUrl || '';
                                    replacements.push({
                                        pattern         : /\{\{ADXPreview\}\}/gi,
                                        replacement     : (attachments.png && attachments.png.id)? '<p><a href="' + urlToPointAt + '" target="_blank"> <img style="max-width: 100%;" src="/hc/en-us/article_attachments/' + attachments.png.id + '/' + attachments.png.name + '" alt="" /> </a></p>' : "ad"
                                    });
                                    replacements.push({
                                        pattern         : /\{\{ADXLiveDemo\}\}/gi,
                                        replacement     : (!self.options.demoUrl) ? '' : '<li><a href="' + self.options.demoUrl + '" target="_blank">To access to the live survey, click on the picture above.</a></li>'
                                    });
                                    const articleUpdated = common.evalTemplate(article.body, {}, replacements);
                                    self.client.translations.updateForArticle(article.id, 'en-us', {body:articleUpdated}, (err) => {
                                        if (err) {
                                            callback(err);
                                            return;
                                        }
                                        self.writeSuccess(successMsg.zenDeskTranslationUpdated);
                                        self.client.articles.update(article.id, article, (err) => {
                                            if (!err) {
                                                self.writeSuccess(successMsg.zenDeskArticleUpdated);
                                            }
                                            if (typeof callback === 'function') {
                                                callback(err);
                                            }
                                        });
                                    });
                                });
                            });
                        });
                    });
Example #11
0
 topic:function(){
     fs.stat('test.txt',this.callback);
 },
Example #12
0
//      q.push(medias);
      if (pages--) {
        if (pagination.next) {
          pagination.next(handler);
        } else {
          cb(result_set);
        }
      } else {
        cb(result_set);
      }
    } else {
      cb(result_set);
    }
  };

  api.tag_media_recent(tag, {count: 33}, handler);

}

var search_tag = process.argv[2];
var output_dir = './output/' + search_tag;

fs.stat(output_dir, function (d, r) {
  if (d && d.code == 'ENOENT'){
    console.log(output_dir);
    fs.mkdirSync(output_dir);
  }
  dl(search_tag, output_dir, 100);
});

Example #13
0
function staticHandle(req, res, next) {
  var urlParsed = url.parse(req.url);
  var filePath = path.join(config.staticFileRootDirPath, urlParsed.pathname === '/' ? 'index.html' :  urlParsed.pathname)
  fs.stat(filePath, function (err, stats) {
    if (err) {
      next()
    } else if (stats.isFile() /* file */) {
      // server as static file
      fs.readFile(filePath, function(err, buffer) {
        if (isHtmlPage(buffer)) {
          // add something nasty in it, that's where bird dev-tool exists
          var $ = cheerio.load(buffer.toString('utf-8'));
          $('head').append('<script type="text/javascript">' + BIRD_EXTEND_SCRIPT + '</script>')
          var o = Object.assign({}, config);
          o.jar = undefined;
          $('head').append('<script type="text/javascript">window.birdv2.config=' + JSON.stringify(o) + '</script>')
          if (config.dev_tool) {
            $('head').append('<script type="text/javascript">' + BIRD_USER_SCRIPT + '</script>')
            // console.log($.html())
          }
          res.setHeader('Content-Type', mime.lookup('.html'));
          res.write($.html())
          res.end();
        } else {
          var mimeType = mime.lookup(path.extname(filePath));
          res.setHeader('Content-Type', mimeType);
          res.write(buffer);
          res.end();
        }
      })
    } else if (stats.isDirectory() /* directory */) {
      var AUTO_INDEX; 
      if (Array.isArray(config.autoIndex)) {
        AUTO_INDEX = config.autoIndex
      } else {
        AUTO_INDEX = config.autoIndex ? config.autoIndex.split(/\x20+/) : ['index.html']
      }
      if (AUTO_INDEX) {
        var fp;
        for (var i = 0; i < AUTO_INDEX.length; i++) {
          fp = path.join(filePath, AUTO_INDEX[i]);
          if (isFile(fp)) {
            filePath = fp;
            fs.readFile(filePath, function(err, buffer) {
              var mimeType = mime.lookup(path.extname(filePath));
              res.setHeader('Content-Type', mimeType);
              res.write(buffer);
              res.end();
            });
            break;
          }
        }
        // if (!isFile(filePath)) {
        //   emptyPage(res, filePath);
        // }
      }
    } else {
      // shit happens
      next()
    }
  })
}
Example #14
0
 async.filter(absolutePaths, function(absolutePath, callback) {
   fs.stat(absolutePath, function(err, stat) {
     callback(!err && stat && stat.isDirectory());
   });
 }, function(filteredFiles) {
Example #15
0
SendStream.prototype.pipe = function (res) {
    var self = this
        , args = arguments
        , root = this._root;

    // references
    this.res = res;

    // decode the path
    var path = utils.decode(this.path)
    if (path === -1) return this.error(400)

    // null byte(s)
    if (~path.indexOf('\0')) return this.error(400);

    var parts
    if (root !== null) {
        // join / normalize from optional root dir
        path = normalize(join(root, path))
        root = normalize(root)

        // malicious path
        if (path.substr(0, root.length) !== root) {
            debug('malicious path "%s"', path)
            return this.error(403)
        }

        // explode path parts
        parts = path.substr(root.length + 1).split(sep)
    } else {
        // ".." is malicious without "root"
        if (upPathRegexp.test(path)) {
            debug('malicious path "%s"', path)
            return this.error(403)
        }

        // explode path parts
        parts = normalize(path).split(sep)

        // resolve the path
        path = resolve(path)
    }

    // dotfile handling
    if (containsDotFile(parts)) {
        var access = this._dotfiles

        // legacy support
        if (access === undefined) {
            access = parts[parts.length - 1][0] === '.'
                ? (this._hidden ? 'allow' : 'ignore')
                : 'allow'
        }

        debug('%s dotfile "%s"', access, path)
        switch (access) {
            case 'allow':
                break
            case 'deny':
                return this.error(403)
            case 'ignore':
            default:
                return this.error(404)
        }
    }

    // index file support
    if (this._index.length && this.path[this.path.length - 1] === '/') {
        this.sendIndex(path);
        return res;
    }

    debug('stat "%s"', path);
    fs.stat(path, function (err, stat) {
        if (err) return self.onStatError(err);
        if (stat.isDirectory()) return self.redirect(self.path);
        self.emit('file', path, stat);
        self.send(path, stat);
    });

    return res;
};
Example #16
0
 asyncc.each(options.files, (file, cb) => fs.stat(file, cb), function (err, files) {
Example #17
0
const checkFile = function(path, time, callback) {
  fs.stat(path, (err, stats) => {
    // We can ignore "no such file"-errors as this function intends to remove the file anyway.
    // These errors can ocurr when another method cleans up after themselves right between the cleaner doing a `fs.readdir` and `fs.stat`.
    if (err && err.code === 'ENOENT') {
      // There is nothing further to do if the file has been removed
      return callback();

      // If we get an error that is not a "no such file"-error, something is probably wrong
    }

    if (err) {
      log().error({ err, path }, 'Could not get the metadata for a file.');
      return callback(err);
    }

    // Only try to unlink file resources that have expired
    if (stats && stats.isFile() && stats.atime.getTime() < time) {
      log().info({ path, lastModified: stats.atime.getTime(), expires: time }, 'Deleting expired temporary file.');
      fs.unlink(path, err => {
        // Only report the error if it's not a "no such file"-error
        if (err && err.code !== 'ENOENT') {
          log().error({ err, path }, 'Could not delete an expired temporary file.');
          return callback(err);
        }

        callback();
      });
    } else {
      callback();
    }
  });
};
Example #18
0
 var pathHandle = function (realPath) {
     fs.stat(realPath, function (err, stats) {
         if (err) {
             if (typeof callback === "function") {
                 callback(req, res);
             } else {
                 //console.log(req.url + " 404");
                 res.writeHead(404, {"Content-Type": "text/plain"});
                 res.write("This request URL " + pathname + " was not found on this server.");
                 res.end();
             }
         } else {
             if (stats.isDirectory()) {
                 realPath = path.join(realPath, "/", config.Welcome.file);
                 pathHandle(realPath);
             } else {
                 res.setHeader('Accept-Ranges', 'bytes');
                 var ext = path.extname(realPath);
                 ext = ext ? ext.slice(1) : 'unknown';
                 var contentType = mime[ext] || "text/plain";
                 res.setHeader("Content-Type", contentType);
                 var lastModified = stats.mtime.toUTCString();
                 var ifModifiedSince = "If-Modified-Since".toLowerCase();
                 res.setHeader("Last-Modified", lastModified);
                 //jsp动态文件简单支持
                 if (ext === "jsp") {
                     var content = fs.readFileSync(realPath, "utf-8");
                     content = content.replace(/<%@ page.*|.*%>/g, "");
                     content = content.replace(/<jsp:include page="(.*)"\/>/g, function (strpath) {
                         return fs.readFileSync(path.join(path.dirname(realPath), strpath.replace(/^[^"]+"|"[^"]+$/g,"")), "utf-8");
                     });
                     res.write(content);
                     res.end();
                     return false;
                 }
                 if (ext.match(config.Expires.fileMatch)) {
                     var expires = new Date();
                     expires.setTime(expires.getTime() + config.Expires.maxAge * 1000);
                     res.setHeader("Expires", expires.toUTCString());
                     res.setHeader("Cache-Control", "max-age=" + config.Expires.maxAge);
                 }
                 if (req.headers[ifModifiedSince] && lastModified === req.headers[ifModifiedSince]) {
                     //console.log(req.url + " 304");
                     res.writeHead(304, "Not Modified");
                     res.end();
                 } else {
                     var compressHandle = function (raw, statusCode, reasonPhrase) {
                         var stream = raw;
                         var acceptEncoding = req.headers['accept-encoding'] || "";
                         var matched = ext.match(config.Compress.match);
                         if (matched && acceptEncoding.match(/\bgzip\b/)) {
                             res.setHeader("Content-Encoding", "gzip");
                             stream = raw.pipe(zlib.createGzip());
                         } else if (matched && acceptEncoding.match(/\bdeflate\b/)) {
                             res.setHeader("Content-Encoding", "deflate");
                             stream = raw.pipe(zlib.createDeflate());
                         }
                         //console.log(req.url + " " + statusCode);
                         res.writeHead(statusCode, reasonPhrase);
                         stream.pipe(res);
                     };
                     var raw = {};
                     if (req.headers["range"]) {
                         var range = utils.parseRange(req.headers["range"], stats.size);
                         if (range) {
                             res.setHeader("Content-Range", "bytes " + range.start + "-" + range.end + "/" + stats.size);
                             res.setHeader("Content-Length", (range.end - range.start + 1));
                             raw = fs.createReadStream(realPath, {"start": range.start, "end": range.end});
                             compressHandle(raw, 206, "Partial Content");
                         } else {
                             //console.log(req.url + " 416");
                             res.removeHeader("Content-Length");
                             res.writeHead(416, "Request Range Not Satisfiable");
                             res.end();
                         }
                     } else {
                         raw = fs.createReadStream(realPath);
                         compressHandle(raw, 200, "Ok");
                     }
                 }
             }
         }
     });
 };
Example #19
0
 rm('a', client, config).then(function() {
   fs.stat('/tmp/thumb/a', function(err, stat) {
     expect(stat).toBe(undefined);
     done();
   });
 });
 const stat = yield cb => fs.stat(file, cb);
Example #21
0
    this.httpSend = function(msg, block, callback) {
        var self = this;
        var method = block.method.toLowerCase();
        var hasFileBody = block.hasFileBody;
        var hasBody = !hasFileBody && ("head|get|delete".indexOf(method) === -1);
        var format = getRequestFormat.call(this, hasBody, block);
        var obj = getQueryAndUrl(msg, block, format, self.config);
        var query = obj.query;
        var url = this.config.url ? this.config.url + obj.url : obj.url;

        var path = url;
        var protocol = this.config.protocol || this.constants.protocol || "http";
        var host = block.host || this.config.host || this.constants.host;
        var port = this.config.port || this.constants.port || (protocol == "https" ? 443 : 80);
        var proxyUrl;
        if (this.config.proxy !== undefined) {
            proxyUrl = this.config.proxy;
        } else {
            proxyUrl = process.env.HTTPS_PROXY || process.env.HTTP_PROXY;
        }
        if (proxyUrl) {
            path = Url.format({
                protocol: protocol,
                hostname: host,
                port: port,
                pathname: path
            });

            if (!/^(http|https):\/\//.test(proxyUrl))
                proxyUrl = "https://" + proxyUrl;

            var parsedUrl = Url.parse(proxyUrl);
            protocol = parsedUrl.protocol.replace(":", "");
            host = parsedUrl.hostname;
            port = parsedUrl.port || (protocol == "https" ? 443 : 80);
        }
        if (!hasBody && query.length)
            path += "?" + query.join("&");

        var headers = {
            "host": host,
            "content-length": "0"
        };
        if (hasBody) {
            if (format == "json")
                query = JSON.stringify(query);
            else if (format != "raw")
                query = query.join("&");
            headers["content-length"] = Buffer.byteLength(query, "utf8");
            headers["content-type"] = format == "json"
                ? "application/json; charset=utf-8"
                : format == "raw"
                    ? "text/plain; charset=utf-8"
                    : "application/x-www-form-urlencoded; charset=utf-8";
        }
        if (this.auth) {
            var basic;
            switch (this.auth.type) {
                case "oauth":
                    if (this.auth.token) {
                        path += (path.indexOf("?") === -1 ? "?" : "&") +
                            "access_token=" + encodeURIComponent(this.auth.token);
                    } else {
                        path += (path.indexOf("?") === -1 ? "?" : "&") +
                            "client_id=" + encodeURIComponent(this.auth.key) +
                            "&client_secret=" + encodeURIComponent(this.auth.secret);
                    }
                    break;
                case "token":
                    headers.authorization = "token " + this.auth.token;
                    break;
                case "basic":
                    basic = new Buffer(this.auth.username + ":" + this.auth.password, "ascii").toString("base64");
                    headers.authorization = "Basic " + basic;
                    break;
                default:
                    break;
            }
        }

        function callCallback(err, result) {
            if (callback) {
                var cb = callback;
                callback = undefined;
                cb(err, result);
            }
        }

        function addCustomHeaders(customHeaders) {
            Object.keys(customHeaders).forEach(function(header) {
                var headerLC = header.toLowerCase();
                if (self.requestHeaders.indexOf(headerLC) == -1)
                    return;
                headers[headerLC] = customHeaders[header];
            });
        }
        addCustomHeaders(Util.extend(msg.headers || {}, this.config.headers));

        if (!headers["user-agent"])
            headers["user-agent"] = "NodeJS HTTP Client";

        if (!("accept" in headers))
            headers.accept = this.config.requestMedia || this.constants.requestMedia;

        var options = {
            host: host,
            port: port,
            path: path,
            method: method,
            headers: headers
        };

        if (this.config.rejectUnauthorized !== undefined)
            options.rejectUnauthorized = this.config.rejectUnauthorized;

        if (this.debug)
            console.log("REQUEST: ", options);

        function httpSendRequest() {
            var req = require(protocol).request(options, function(res) {
                if (self.debug) {
                    console.log("STATUS: " + res.statusCode);
                    console.log("HEADERS: " + JSON.stringify(res.headers));
                }
                res.setEncoding("utf8");
                var data = "";
                res.on("data", function(chunk) {
                    data += chunk;
                });
                res.on("error", function(err) {
                    callCallback(err);
                });
                res.on("end", function() {
                    if (res.statusCode >= 400 && res.statusCode < 600 || res.statusCode < 10) {
                        callCallback(new error.HttpError(data, res.statusCode));
                    } else {
                        res.data = data;
                        callCallback(null, res);
                    }
                });
            });

            var timeout = (block.timeout !== undefined) ? block.timeout : self.config.timeout;
            if (timeout) {
                req.setTimeout(timeout);
            }

            req.on("error", function(e) {
                if (self.debug)
                    console.log("problem with request: " + e.message);
                callCallback(e.message);
            });

            req.on("timeout", function() {
                if (self.debug)
                    console.log("problem with request: timed out");
                callCallback(new error.GatewayTimeout());
            });

            // write data to request body
            if (hasBody && query.length) {
                if (self.debug)
                    console.log("REQUEST BODY: " + query + "\n");
                req.write(query + "\n");
            }

            if (block.hasFileBody) {
              var stream = fs.createReadStream(msg.filePath);
              stream.pipe(req);
            } else {
              req.end();
            }
        }
        if (hasFileBody) {
            fs.stat(msg.filePath, function(err, stat) {
                if (err) {
                    callCallback(err);
                } else {
                    headers["content-length"] = stat.size;
                    headers["content-type"] = mime.lookup(msg.name);
                    httpSendRequest();
                }
            });
        } else {
            httpSendRequest();
        }
    };
Example #22
0
 function (next) {
     fs.stat(that._file, next);
 },
Example #23
0
 function(file, include) {
   fs.stat(path.resolve(cwd, file), function(err, stats) {
     include(!err && !stats.isDirectory());
   });
 },
Example #24
0
function _respond(req, res, respondObj, next) {
  var responder = respondObj.responder;
  var url = utils.processUrl(req);
  var originalPattern = respondObj.pattern;

  var pattern = typeof originalPattern === 'string' ? new RegExp(originalPattern) : originalPattern;

  /**
   * For directory mapping
   */
  var extDirectoryOfRequestUrl;
  var localDirectory;

  log.debug('before fix responder: ' + responder);

  responder = fixResponder(url, pattern, responder);

  log.debug('after fix responder: ' + responder);

  if(typeof responder === 'string'){

    var disablePostCache = req.method === 'POST' && respondObj.cache && !respondObj.cachePost;

    if(httpRxg.test(responder) || disablePostCache){
      if(disablePostCache) {
        log.info('Cache disabled for POST request: ' + url);
        responder = url;
      }
      responders.respondFromWebFile(responder, req, res, next);
    }else{
      if(respondObj.cache && utils.cacheFolder && responder.indexOf('/') !== 0) {
        responder = utils.cacheFolder + '/' + responder;
        log.debug('changing responder name to '+ responder);
      }
      fs.stat(responder, function(err, stat){
        if(err){
          if(respondObj.cache) {
            // not a real error: file not cached yet
            log.info('caching '+url+' -> '+responder);
            responders.respondAndCacheFromWebFile(url, responder, req, res, next);
          } else {
            log.error(err.message + ' for (' + url + ')' +
                ' then directly forward it!');
            next();
          }
        }else{
          if(stat.isFile()){ // local file
            responders.respondFromLocalFile(responder, req, res, next);
          }else if(stat.isDirectory()){ // directory mapping
            var urlWithoutQS = utils.processUrlWithQSAbandoned(url);
            var directoryPattern = url.match(pattern)[0];
            extDirectoryOfRequestUrl = urlWithoutQS.substr(
                urlWithoutQS.indexOf(directoryPattern) + directoryPattern.length);
            localDirectory = path.join(responder,
                path.dirname(extDirectoryOfRequestUrl));

            utils.findFile(localDirectory,
                path.basename(extDirectoryOfRequestUrl),
                function(err, file){
                  log.debug('Find local file: ' + file + ' for (' + url + ')');
                  if(err){
                    log.error(err.message + ' for (' + url + ')' +
                        ' then directly forward it!');
                    next();
                  }else{
                    responders.respondFromLocalFile(file, req, res, next);
                  }
            });
          }
        }
      });
    }
  }else if(Array.isArray(responder)){
    responders.respondFromCombo({
      dir: null,
      src: responder
    }, req, res, next);
  }else if(typeof responder === 'object' && responder !== null){
    responders.respondFromCombo({
      dir: responder.dir,
      src: responder.src
    }, req, res, next);
  }else{
    log.error('Responder for ' + url + 'is invalid!');
    next();
  }

}
Example #25
0
var Twig=function(a){function b(a,b){var c=Object.prototype.toString.call(b).slice(8,-1);return b!==undefined&&b!==null&&c===a}function c(b,c){var d,e,f="/",g=[],h;if(b.url)d=b.url;else{if(!b.path)throw new a.Error("Cannot extend an inline template.");var i=require("path"),j=i.sep||f,k=new RegExp("^\\.{1,2}"+j.replace("\\","\\\\"));b.base!==undefined&&c.match(k)==null?(c=c.replace(b.base,""),d=b.base+j):d=b.path,d=d.replace(j+j,j),f=j}e=d.split(f),e.pop(),e=e.concat(c.split(f));while(e.length>0)h=e.shift(),h!="."&&(h==".."&&g.length>0&&g[g.length-1]!=".."?g.pop():g.push(h));return g.join(f)}return"use strict",a.trace=!1,a.debug=!1,a.cache=!0,a.placeholders={parent:"{{|PARENT|}}"},a.Error=function(a){this.message=a,this.name="TwigException",this.type="TwigException"},a.Error.prototype.toString=function(){return this.name+": "+this.message},a.log={trace:function(){a.trace&&console&&console.log(Array.prototype.slice.call(arguments))},debug:function(){a.debug&&console&&console.log(Array.prototype.slice.call(arguments))}},a.token={},a.token.type={output:"output",logic:"logic",comment:"comment",raw:"raw"},a.token.definitions={output:{type:a.token.type.output,open:"{{",close:"}}"},logic:{type:a.token.type.logic,open:"{%",close:"%}"},comment:{type:a.token.type.comment,open:"{#",close:"#}"}},a.token.strings=['"',"'"],a.token.findStart=function(b){var c={position:null,def:null},d,e,f;for(d in a.token.definitions)a.token.definitions.hasOwnProperty(d)&&(e=a.token.definitions[d],f=b.indexOf(e.open),a.log.trace("Twig.token.findStart: ","Searching for ",e.open," found at ",f),f>=0&&(c.position===null||f<c.position)&&(c.position=f,c.def=e));return c},a.token.findEnd=function(b,c,d){var e=null,f=!1,g=0,h=null,i=null,j=null,k=null,l=null,m=null,n,o;while(!f){h=null,i=null,j=b.indexOf(c.close,g);if(!(j>=0))throw new a.Error("Unable to find closing bracket '"+c.close+"'"+" opened near template position "+d);e=j,f=!0,o=a.token.strings.length;for(n=0;n<o;n+=1)l=b.indexOf(a.token.strings[n],g),l>0&&l<j&&(h===null||l<h)&&(h=l,i=a.token.strings[n]);if(h!==null){k=h+1,e=null,f=!1;for(;;){m=b.indexOf(i,k);if(m<0)throw"Unclosed string in template";if(b.substr(m-1,1)!=="\\"){g=m+1;break}k=m+1}}}return e},a.tokenize=function(b){var c=[],d=0,e=null,f=null;while(b.length>0)e=a.token.findStart(b),a.log.trace("Twig.tokenize: ","Found token: ",e),e.position!==null?(e.position>0&&c.push({type:a.token.type.raw,value:b.substring(0,e.position)}),b=b.substr(e.position+e.def.open.length),d+=e.position+e.def.open.length,f=a.token.findEnd(b,e.def,d),a.log.trace("Twig.tokenize: ","Token ends at ",f),c.push({type:e.def.type,value:b.substring(0,f).trim()}),b=b.substr(f+e.def.close.length),d+=f+e.def.close.length):(c.push({type:a.token.type.raw,value:b}),b="");return c},a.compile=function(b){var c=[],d=[],e=[],f=null,g=null,h=null,i=null,j=null,k=null,l=null,m=null,n=null;while(b.length>0){f=b.shift(),a.log.trace("Compiling token ",f);switch(f.type){case a.token.type.raw:d.length>0?e.push(f):c.push(f);break;case a.token.type.logic:g=a.logic.compile.apply(this,[f]),l=g.type,m=a.logic.handler[l].open,n=a.logic.handler[l].next,a.log.trace("Twig.compile: ","Compiled logic token to ",g," next is: ",n," open is : ",m);if(m!==undefined&&!m){i=d.pop(),j=a.logic.handler[i.type];if(j.next.indexOf(l)<0)throw new Error(l+" not expected after a "+i.type);i.output=i.output||[],i.output=i.output.concat(e),e=[],k={type:a.token.type.logic,token:i},d.length>0?e.push(k):c.push(k)}n!==undefined&&n.length>0?(a.log.trace("Twig.compile: ","Pushing ",g," to logic stack."),d.length>0&&(i=d.pop(),i.output=i.output||[],i.output=i.output.concat(e),d.push(i),e=[]),d.push(g)):m!==undefined&&m&&(k={type:a.token.type.logic,token:g},d.length>0?e.push(k):c.push(k));break;case a.token.type.comment:break;case a.token.type.output:a.expression.compile.apply(this,[f]),d.length>0?e.push(f):c.push(f)}a.log.trace("Twig.compile: "," Output: ",c," Logic Stack: ",d," Pending Output: ",e)}if(d.length>0)throw h=d.pop(),new Error("Unable to find an end tag for "+h.type+", expecting one of "+h.next);return c},a.parse=function(b,c){var d=[],e=!0,f=this;return c=c||{},b.forEach(function(g){a.log.debug("Twig.parse: ","Parsing token: ",g);switch(g.type){case a.token.type.raw:d.push(g.value);break;case a.token.type.logic:var h=g.token,i=a.logic.parse.apply(f,[h,c,e]);i.chain!==undefined&&(e=i.chain),i.context!==undefined&&(c=i.context),i.output!==undefined&&d.push(i.output);break;case a.token.type.comment:break;case a.token.type.output:a.log.debug("Twig.parse: ","Output token: ",g.stack),d.push(a.expression.parse.apply(f,[g.stack,c]))}}),d.join("")},a.prepare=function(b){var c,d;return a.log.debug("Twig.prepare: ","Tokenizing ",b),d=a.tokenize.apply(this,[b]),a.log.debug("Twig.prepare: ","Compiling ",d),c=a.compile.apply(this,[d]),a.log.debug("Twig.prepare: ","Compiled ",c),c},a.Templates={registry:{}},a.validateId=function(b){if(b==="prototype")throw new a.Error(b+" is not a valid twig identifier");if(a.Templates.registry.hasOwnProperty(b))throw new a.Error("There is already a template with the ID "+b);return!0},a.Templates.save=function(b){if(b.id===undefined)throw new a.Error("Unable to save template with no id");a.Templates.registry[b.id]=b},a.Templates.load=function(b){return a.Templates.registry.hasOwnProperty(b)?a.Templates.registry[b]:null},a.Templates.loadRemote=function(b,c,d,e){var f=c.id,g=c.method,h=c.async,i=c.precompiled,j=null;h===undefined&&(h=!0),f===undefined&&(f=b),c.id=f;if(a.cache&&a.Templates.registry.hasOwnProperty(f))return d&&d(a.Templates.registry[f]),a.Templates.registry[f];if(g=="ajax"){if(typeof XMLHttpRequest=="undefined")throw new a.Error("Unsupported platform: Unable to do remote requests because there is no XMLHTTPRequest implementation");var k=new XMLHttpRequest;k.onreadystatechange=function(){var e=null;k.readyState==4&&(a.log.debug("Got template ",k.responseText),i===!0?e=JSON.parse(k.responseText):e=k.responseText,c.url=b,c.data=e,j=new a.Template(c),d&&d(j))},k.open("GET",b,h),k.send()}else(function(){var f=require("fs"),g=require("path"),k=null,l=function(f,g){if(f){e&&e(f);return}i===!0&&(g=JSON.parse(g)),c.data=g,c.path=b,j=new a.Template(c),d&&d(j)};if(h===!0)f.stat(b,function(c,d){if(c||!d.isFile())throw new a.Error("Unable to find template file "+b);f.readFile(b,"utf8",l)});else{if(!f.statSync(b).isFile())throw new a.Error("Unable to find template file "+b);k=f.readFileSync(b,"utf8"),l(undefined,k)}})();return h===!1?j:!0},a.Template=function(c){var d=c.data,e=c.id,f=c.blocks,g=c.base,h=c.path,i=c.url,j=c.options;this.id=e,this.base=g,this.path=h,this.url=i,this.options=j,this.reset(f),b("String",d)?this.tokens=a.prepare.apply(this,[d]):this.tokens=d,e!==undefined&&a.Templates.save(this)},a.Template.prototype.reset=function(b){a.log.debug("Twig.Template.reset","Reseting template "+this.id),this.blocks={},this.child={blocks:b||{}},this.extend=null},a.Template.prototype.render=function(b,d){d=d||{};var e,f;return this.context=b||{},this.reset(),d.blocks&&(this.blocks=d.blocks),e=a.parse.apply(this,[this.tokens,this.context]),this.extend?(f=c(this,this.extend),this.parent=a.Templates.loadRemote(f,{method:this.url?"ajax":"fs",base:this.base,async:!1,id:f,options:this.options}),this.parent.render(this.context,{blocks:this.blocks})):d.output=="blocks"?this.blocks:e},a.Template.prototype.importFile=function(b){var d=c(this,b),e=a.Templates.loadRemote(d,{method:this.url?"ajax":"fs",async:!1,options:this.options,id:d});return e},a.Template.prototype.importBlocks=function(a,b){var c=this.importFile(a),d=this.context,e=this,f;b=b||!1,c.render(d),Object.keys(c.blocks).forEach(function(a){if(b||e.blocks[a]===undefined)e.blocks[a]=c.blocks[a]})},a.Template.prototype.compile=function(b){return a.compiler.compile(this,b)},a}(Twig||{});(function(){"use strict",String.prototype.trim||(String.prototype.trim=function(){return this.replace(/^\s+|\s+$/g,"")}),Array.prototype.indexOf||(Array.prototype.indexOf=function(a){if(this===void 0||this===null)throw new TypeError;var b=Object(this),c=b.length>>>0;if(c===0)return-1;var d=0;arguments.length>0&&(d=Number(arguments[1]),d!==d?d=0:d!==0&&d!==Infinity&&d!==-Infinity&&(d=(d>0||-1)*Math.floor(Math.abs(d))));if(d>=c)return-1;var e=d>=0?d:Math.max(c-Math.abs(d),0);for(;e<c;e++)if(e in b&&b[e]===a)return e;return-1}),Array.prototype.forEach||(Array.prototype.forEach=function(a,b){var c,d;if(this==null)throw new TypeError(" this is null or not defined");var e=Object(this),f=e.length>>>0;if({}.toString.call(a)!="[object Function]")throw new TypeError(a+" is not a function");b&&(c=b),d=0;while(d<f){var g;d in e&&(g=e[d],a.call(c,g,d,e)),d++}}),Object.keys||(Object.keys=function(a){if(a!==Object(a))throw new TypeError("Object.keys called on non-object");var b=[],c;for(c in a)Object.prototype.hasOwnProperty.call(a,c)&&b.push(c);return b})})();var Twig=function(a){a.lib={};var b=function(){function a(a){return Object.prototype.toString.call(a).slice(8,-1).toLowerCase()}function c(a,b){for(var c=[];b>0;c[--b]=a);return c.join("")}var d=function(){return d.cache.hasOwnProperty(arguments[0])||(d.cache[arguments[0]]=d.parse(arguments[0])),d.format.call(null,d.cache[arguments[0]],arguments)};return d.format=function(d,e){var f=1,g=d.length,h="",i,j=[],k,l,m,n,o,p;for(k=0;k<g;k++){h=a(d[k]);if(h==="string")j.push(d[k]);else if(h==="array"){m=d[k];if(m[2]){i=e[f];for(l=0;l<m[2].length;l++){if(!i.hasOwnProperty(m[2][l]))throw b('[sprintf] property "%s" does not exist',m[2][l]);i=i[m[2][l]]}}else m[1]?i=e[m[1]]:i=e[f++];if(/[^s]/.test(m[8])&&a(i)!="number")throw b("[sprintf] expecting number but found %s",a(i));switch(m[8]){case"b":i=i.toString(2);break;case"c":i=String.fromCharCode(i);break;case"d":i=parseInt(i,10);break;case"e":i=m[7]?i.toExponential(m[7]):i.toExponential();break;case"f":i=m[7]?parseFloat(i).toFixed(m[7]):parseFloat(i);break;case"o":i=i.toString(8);break;case"s":i=(i=String(i))&&m[7]?i.substring(0,m[7]):i;break;case"u":i=Math.abs(i);break;case"x":i=i.toString(16);break;case"X":i=i.toString(16).toUpperCase()}i=/[def]/.test(m[8])&&m[3]&&i>=0?"+"+i:i,o=m[4]?m[4]=="0"?"0":m[4].charAt(1):" ",p=m[6]-String(i).length,n=m[6]?c(o,p):"",j.push(m[5]?i+n:n+i)}}return j.join("")},d.cache={},d.parse=function(a){var b=a,c=[],d=[],e=0;while(b){if((c=/^[^\x25]+/.exec(b))!==null)d.push(c[0]);else if((c=/^\x25{2}/.exec(b))!==null)d.push("%");else{if((c=/^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(b))===null)throw"[sprintf] huh?";if(c[2]){e|=1;var f=[],g=c[2],h=[];if((h=/^([a-z_][a-z_\d]*)/i.exec(g))===null)throw"[sprintf] huh?";f.push(h[1]);while((g=g.substring(h[0].length))!=="")if((h=/^\.([a-z_][a-z_\d]*)/i.exec(g))!==null)f.push(h[1]);else{if((h=/^\[(\d+)\]/.exec(g))===null)throw"[sprintf] huh?";f.push(h[1])}c[2]=f}else e|=2;if(e===3)throw"[sprintf] mixing positional and named placeholders is not (yet) supported";d.push(c)}b=b.substring(c[0].length)}return d},d}(),c=function(a,c){return c.unshift(a),b.apply(null,c)};return a.lib.sprintf=b,a.lib.vsprintf=c,function(){function f(a){return(a=Math.abs(a)%100)%10==1&&a!=11?"st":a%10==2&&a!=12?"nd":a%10==3&&a!=13?"rd":"th"}function g(a){var b=new Date(a.getFullYear()+1,0,4);return(b-a)/864e5<7&&(a.getDay()+6)%7<(b.getDay()+6)%7?b.getFullYear():a.getMonth()>0||a.getDate()>=4?a.getFullYear():a.getFullYear()-((a.getDay()+6)%7-a.getDate()>2?1:0)}function h(a){var b=new Date(g(a),0,4);return b.setDate(b.getDate()-(b.getDay()+6)%7),parseInt((a-b)/6048e5)+1}var b="Sun,Mon,Tue,Wed,Thu,Fri,Sat".split(","),c="Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday".split(","),d="Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec".split(","),e="January,February,March,April,May,June,July,August,September,October,November,December".split(",");a.lib.formatDate=function(a,i){if(typeof i!="string"||/^\s*$/.test(i))return a+"";var j=new Date(a.getFullYear(),0,1),k=a;return i.replace(/[dDjlNSwzWFmMntLoYyaABgGhHisu]/g,function(a){switch(a){case"d":return("0"+k.getDate()).replace(/^.+(..)$/,"$1");case"D":return b[k.getDay()];case"j":return k.getDate();case"l":return c[k.getDay()];case"N":return(k.getDay()+6)%7+1;case"S":return f(k.getDate());case"w":return k.getDay();case"z":return Math.ceil((j-k)/864e5);case"W":return("0"+h(k)).replace(/^.(..)$/,"$1");case"F":return e[k.getMonth()];case"m":return("0"+(k.getMonth()+1)).replace(/^.+(..)$/,"$1");case"M":return d[k.getMonth()];case"n":return k.getMonth()+1;case"t":return(new Date(k.getFullYear(),k.getMonth()+1,-1)).getDate();case"L":return(new Date(k.getFullYear(),1,29)).getDate()==29?1:0;case"o":return g(k);case"Y":return k.getFullYear();case"y":return(k.getFullYear()+"").replace(/^.+(..)$/,"$1");case"a":return k.getHours()<12?"am":"pm";case"A":return k.getHours()<12?"AM":"PM";case"B":return Math.floor(((k.getUTCHours()+1)%24+k.getUTCMinutes()/60+k.getUTCSeconds()/3600)*1e3/24);case"g":return k.getHours()%12!=0?k.getHours()%12:12;case"G":return k.getHours();case"h":return("0"+(k.getHours()%12!=0?k.getHours()%12:12)).replace(/^.+(..)$/,"$1");case"H":return("0"+k.getHours()).replace(/^.+(..)$/,"$1");case"i":return("0"+k.getMinutes()).replace(/^.+(..)$/,"$1");case"s":return("0"+k.getSeconds()).replace(/^.+(..)$/,"$1");case"u":return k.getMilliseconds()}})}}(),a.lib.strip_tags=function(a,b){b=(((b||"")+"").toLowerCase().match(/<[a-z][a-z0-9]*>/g)||[]).join("");var c=/<\/?([a-z][a-z0-9]*)\b[^>]*>/gi,d=/<!--[\s\S]*?-->|<\?(?:php)?[\s\S]*?\?>/gi;return a.replace(d,"").replace(c,function(a,c){return b.indexOf("<"+c.toLowerCase()+">")>-1?a:""})},a.lib.strtotime=function(a,b){var c,d,e,f,g="";a=a.replace(/\s{2,}|^\s|\s$/g," "),a=a.replace(/[\t\r\n]/g,"");if(a==="now")return b===null||isNaN(b)?(new Date).getTime()/1e3|0:b|0;if(!isNaN(g=Date.parse(a)))return g/1e3|0;b?b=new Date(b*1e3):b=new Date,a=a.toLowerCase();var h={day:{sun:0,mon:1,tue:2,wed:3,thu:4,fri:5,sat:6},mon:["jan","feb","mar","apr","may","jun","jul","aug","sep","oct","nov","dec"]},i=function(a){var c=a[2]&&a[2]==="ago",d=(d=a[0]==="last"?-1:1)*(c?-1:1);switch(a[0]){case"last":case"next":switch(a[1].substring(0,3)){case"yea":b.setFullYear(b.getFullYear()+d);break;case"wee":b.setDate(b.getDate()+d*7);break;case"day":b.setDate(b.getDate()+d);break;case"hou":b.setHours(b.getHours()+d);break;case"min":b.setMinutes(b.getMinutes()+d);break;case"sec":b.setSeconds(b.getSeconds()+d);break;case"mon":if(a[1]==="month"){b.setMonth(b.getMonth()+d);break};default:var e=h.day[a[1].substring(0,3)];if(typeof e!="undefined"){var f=e-b.getDay();f===0?f=7*d:f>0?a[0]==="last"&&(f-=7):a[0]==="next"&&(f+=7),b.setDate(b.getDate()+f),b.setHours(0,0,0,0)}}break;default:if(!/\d+/.test(a[0]))return!1;d*=parseInt(a[0],10);switch(a[1].substring(0,3)){case"yea":b.setFullYear(b.getFullYear()+d);break;case"mon":b.setMonth(b.getMonth()+d);break;case"wee":b.setDate(b.getDate()+d*7);break;case"day":b.setDate(b.getDate()+d);break;case"hou":b.setHours(b.getHours()+d);break;case"min":b.setMinutes(b.getMinutes()+d);break;case"sec":b.setSeconds(b.getSeconds()+d)}}return!0};e=a.match(/^(\d{2,4}-\d{2}-\d{2})(?:\s(\d{1,2}:\d{2}(:\d{2})?)?(?:\.(\d+))?)?$/);if(e!==null)return e[2]?e[3]||(e[2]+=":00"):e[2]="00:00:00",f=e[1].split(/-/g),f[1]=h.mon[f[1]-1]||f[1],f[0]=+f[0],f[0]=f[0]>=0&&f[0]<=69?"20"+(f[0]<10?"0"+f[0]:f[0]+""):f[0]>=70&&f[0]<=99?"19"+f[0]:f[0]+"",parseInt(this.strtotime(f[2]+" "+f[1]+" "+f[0]+" "+e[2])+(e[4]?e[4]/1e3:""),10);var j="([+-]?\\d+\\s(years?|months?|weeks?|days?|hours?|min|minutes?|sec|seconds?|sun\\.?|sunday|mon\\.?|monday|tue\\.?|tuesday|wed\\.?|wednesday|thu\\.?|thursday|fri\\.?|friday|sat\\.?|saturday)|(last|next)\\s(years?|months?|weeks?|days?|hours?|min|minutes?|sec|seconds?|sun\\.?|sunday|mon\\.?|monday|tue\\.?|tuesday|wed\\.?|wednesday|thu\\.?|thursday|fri\\.?|friday|sat\\.?|saturday))(\\sago)?";e=a.match(new RegExp(j,"gi"));if(e===null)return!1;for(c=0,d=e.length;c<d;c++)if(!i(e[c].split(" ")))return!1;return b.getTime()/1e3|0},a.lib.is=function(a,b){var c=Object.prototype.toString.call(b).slice(8,-1);return b!==undefined&&b!==null&&c===a},a.lib.copy=function(a){var b={},c;for(c in a)b[c]=a[c];return b},a}(Twig||{}),Twig=function(a){"use strict",a.logic={},a.logic.type={if_:"Twig.logic.type.if",endif:"Twig.logic.type.endif",for_:"Twig.logic.type.for",endfor:"Twig.logic.type.endfor",else_:"Twig.logic.type.else",elseif:"Twig.logic.type.elseif",set:"Twig.logic.type.set",filter:"Twig.logic.type.filter",endfilter:"Twig.logic.type.endfilter",block:"Twig.logic.type.block",endblock:"Twig.logic.type.endblock",extends_:"Twig.logic.type.extends",use:"Twig.logic.type.use",include:"Twig.logic.type.include"},a.logic.definitions=[{type:a.logic.type.if_,regex:/^if\s+([^\s].+)$/,next:[a.logic.type.else_,a.logic.type.elseif,a.logic.type.endif],open:!0,compile:function(b){var c=b.match[1];return b.stack=a.expression.compile.apply(this,[{type:a.expression.type.expression,value:c}]).stack,delete b.match,b},parse:function(b,c,d){var e="",f=a.expression.parse.apply(this,[b.stack,c]);return d=!0,f&&(d=!1,e=a.parse.apply(this,[b.output,c])),{chain:d,output:e}}},{type:a.logic.type.elseif,regex:/^elseif\s+([^\s].*)$/,next:[a.logic.type.else_,a.logic.type.elseif,a.logic.type.endif],open:!1,compile:function(b){var c=b.match[1];return b.stack=a.expression.compile.apply(this,[{type:a.expression.type.expression,value:c}]).stack,delete b.match,b},parse:function(b,c,d){var e="";return d&&a.expression.parse.apply(this,[b.stack,c])===!0&&(d=!1,e=a.parse.apply(this,[b.output,c])),{chain:d,output:e}}},{type:a.logic.type.else_,regex:/^else$/,next:[a.logic.type.endif,a.logic.type.endfor],open:!1,parse:function(b,c,d){var e="";return d&&(e=a.parse.apply(this,[b.output,c])),{chain:d,output:e}}},{type:a.logic.type.endif,regex:/^endif$/,next:[],open:!1},{type:a.logic.type.for_,regex:/^for\s+([a-zA-Z0-9_,\s]+)\s+in\s+([^\s].*?)(?:\s+if\s+([^\s].*))?$/,next:[a.logic.type.else_,a.logic.type.endfor],open:!0,compile:function(b){var c=b.match[1],d=b.match[2],e=b.match[3],f=null;b.key_var=null,b.value_var=null;if(c.indexOf(",")>=0){f=c.split(",");if(f.length!==2)throw new a.Error("Invalid expression in for loop: "+c);b.key_var=f[0].trim(),b.value_var=f[1].trim()}else b.value_var=c;return b.expression=a.expression.compile.apply(this,[{type:a.expression.type.expression,value:d}]).stack,e&&(b.conditional=a.expression.compile.apply(this,[{type:a.expression.type.expression,value:e}]).stack),delete b.match,b},parse:function(b,c,d){var e=a.expression.parse.apply(this,[b.expression,c]),f=[],g,h=0,i,j=this,k=b.conditional,l=function(a,b){var d=k!==undefined;return{index:a+1,index0:a,revindex:d?undefined:b-a,revindex0:d?undefined:b-a-1,first:a===0,last:d?undefined:a===b-1,length:d?undefined:b,parent:c}},m=function(d,e){var i=a.lib.copy(c);i[b.value_var]=e,b.key_var&&(i[b.key_var]=d),i.loop=l(h,g);if(k===undefined||a.expression.parse.apply(j,[k,i]))f.push(a.parse.apply(j,[b.output,i])),h+=1};return e instanceof Array?(g=e.length,e.forEach(function(a){var b=h;m(b,a)})):e instanceof Object&&(e._keys!==undefined?i=e._keys:i=Object.keys(e),g=i.length,i.forEach(function(a){if(a==="_keys")return;m(a,e[a])})),d=f.length===0,{chain:d,output:f.join("")}}},{type:a.logic.type.endfor,regex:/^endfor$/,next:[],open:!1},{type:a.logic.type.set,regex:/^set\s+([a-zA-Z0-9_,\s]+)\s*=\s*(.+)$/,next:[],open:!0,compile:function(b){var c=b.match[1].trim(),d=b.match[2],e=a.expression.compile.apply(this,[{type:a.expression.type.expression,value:d}]).stack;return b.key=c,b.expression=e,delete b.match,b},parse:function(b,c,d){var e=a.expression.parse.apply(this,[b.expression,c]),f=b.key;return this.context[f]=e,c[f]=e,{chain:d,context:c}}},{type:a.logic.type.filter,regex:/^filter\s+(.+)$/,next:[a.logic.type.endfilter],open:!0,compile:function(b){var c="|"+b.match[1].trim();return b.stack=a.expression.compile.apply(this,[{type:a.expression.type.expression,value:c}]).stack,delete b.match,b},parse:function(b,c,d){var e=a.parse.apply(this,[b.output,c]),f=[{type:a.expression.type.string,value:e}].concat(b.stack),g=a.expression.parse.apply(this,[f,c]);return{chain:d,output:g}}},{type:a.logic.type.endfilter,regex:/^endfilter$/,next:[],open:!1},{type:a.logic.type.block,regex:/^block\s+([a-zA-Z0-9_]+)$/,next:[a.logic.type.endblock],open:!0,compile:function(a){return a.block=a.match[1].trim(),delete a.match,a},parse:function(b,c,d){var e="",f="",g=this.blocks[b.block]&&this.blocks[b.block].indexOf(a.placeholders.parent)>-1;if(this.blocks[b.block]===undefined||g)e=a.expression.parse.apply(this,[{type:a.expression.type.string,value:a.parse.apply(this,[b.output,c])},c]),g?this.blocks[b.block]=this.blocks[b.block].replace(a.placeholders.parent,e):this.blocks[b.block]=e;return this.child.blocks[b.block]?f=this.child.blocks[b.block]:f=this.blocks[b.block],{chain:d,output:f}}},{type:a.logic.type.endblock,regex:/^endblock$/,next:[],open:!1},{type:a.logic.type.extends_,regex:/^extends\s+(.+)$/,next:[],open:!0,compile:function(b){var c=b.match[1].trim();return delete b.match,b.stack=a.expression.compile.apply(this,[{type:a.expression.type.expression,value:c}]).stack,b},parse:function(b,c,d){var e=a.expression.parse.apply(this,[b.stack,c]);return this.extend=e,{chain:d,output:""}}},{type:a.logic.type.use,regex:/^use\s+(.+)$/,next:[],open:!0,compile:function(b){var c=b.match[1].trim();return delete b.match,b.stack=a.expression.compile.apply(this,[{type:a.expression.type.expression,value:c}]).stack,b},parse:function(b,c,d){var e=a.expression.parse.apply(this,[b.stack,c]);return this.importBlocks(e),{chain:d,output:""}}},{type:a.logic.type.include,regex:/^include\s+(ignore missing\s+)?(.+?)\s*(?:with\s+(.+?))?\s*(only)?$/,next:[],open:!0,compile:function(b){var c=b.match,d=c[1]!==undefined,e=c[2].trim(),f=c[3],g=c[4]!==undefined;return delete b.match,b.only=g,b.includeMissing=d,b.stack=a.expression.compile.apply(this,[{type:a.expression.type.expression,value:e}]).stack,f!==undefined&&(b.withStack=a.expression.compile.apply(this,[{type:a.expression.type.expression,value:f.trim()}]).stack),b},parse:function(b,c,d){var e={},f,g,h;if(!b.only)for(g in c)c.hasOwnProperty(g)&&(e[g]=c[g]);if(b.withStack!==undefined){f=a.expression.parse.apply(this,[b.withStack,c]);for(g in f)f.hasOwnProperty(g)&&(e[g]=f[g])}var i=a.expression.parse.apply(this,[b.stack,e]);return h=this.importFile(i),{chain:d,output:h.render(e)}}}],a.logic.handler={},a.logic.extendType=function(b,c){c=c||"Twig.logic.type"+b,a.logic.type[b]=c},a.logic.extend=function(b){if(!b.type)throw new a.Error("Unable to extend logic definition. No type provided for "+b);if(a.logic.type[b.type])throw new a.Error("Unable to extend logic definitions. Type "+b.type+" is already defined.");a.logic.extendType(b.type),a.logic.handler[b.type]=b};while(a.logic.definitions.length>0)a.logic.extend(a.logic.definitions.shift());return a.logic.compile=function(b){var c=b.value.trim(),d=a.logic.tokenize.apply(this,[c]),e=a.logic.handler[d.type];return e.compile&&(d=e.compile.apply(this,[d]),a.log.trace("Twig.logic.compile: ","Compiled logic token to ",d)),d},a.logic.tokenize=function(b){var c={},d=null,e=null,f=null,g=null,h=null,i=null;b=b.trim();for(d in a.logic.handler)if(a.logic.handler.hasOwnProperty(d)){e=a.logic.handler[d].type,f=a.logic.handler[d].regex,g=[],f instanceof Array?g=f:g.push(f);while(g.length>0){h=g.shift(),i=h.exec(b.trim());if(i!==null)return c.type=e,c.match=i,a.log.trace("Twig.logic.tokenize: ","Matched a ",e," regular expression of ",i),c}}throw new a.Error("Unable to parse '"+b.trim()+"'")},a.logic.parse=function(b,c,d){var e="",f;return c=c||{},a.log.debug("Twig.logic.parse: ","Parsing logic token ",b),f=a.logic.handler[b.type],f.parse&&(e=f.parse.apply(this,[b,c,d])),e},a}(Twig||{}),Twig=function(a){"use strict",a.expression={},a.expression.reservedWords=["true","false","null"],a.expression.type={comma:"Twig.expression.type.comma",operator:{unary:"Twig.expression.type.operator.unary",binary:"Twig.expression.type.operator.binary"},string:"Twig.expression.type.string",bool:"Twig.expression.type.bool",array:{start:"Twig.expression.type.array.start",end:"Twig.expression.type.array.end"},object:{start:"Twig.expression.type.object.start",end:"Twig.expression.type.object.end"},parameter:{start:"Twig.expression.type.parameter.start",end:"Twig.expression.type.parameter.end"},key:{period:"Twig.expression.type.key.period",brackets:"Twig.expression.type.key.brackets"},filter:"Twig.expression.type.filter",_function:"Twig.expression.type._function",variable:"Twig.expression.type.variable",number:"Twig.expression.type.number",_null:"Twig.expression.type.null",test:"Twig.expression.type.test"},a.expression.set={operations:[a.expression.type.filter,a.expression.type.operator.unary,a.expression.type.operator.binary,a.expression.type.array.end,a.expression.type.object.end,a.expression.type.parameter.end,a.expression.type.comma,a.expression.type.test],expressions:[a.expression.type._function,a.expression.type.bool,a.expression.type.string,a.expression.type.variable,a.expression.type.number,a.expression.type._null,a.expression.type.parameter.start,a.expression.type.array.start,a.expression.type.object.start]},a.expression.set.operations_extended=a.expression.set.operations.concat([a.expression.type.key.period,a.expression.type.key.brackets]),a.expression.fn={compile:{push:function(a,b,c){c.push(a)},push_both:function(a,b,c){c.push(a),b.push(a)}},parse:{push:function(a,b,c){b.push(a)},push_value:function(a,b,c){b.push(a.value)}}},a.expression.definitions=[{type:a.expression.type.test,regex:/^is\s+(not)?\s*([a-zA-Z_][a-zA-Z0-9_]*)/,next:a.expression.set.operations.concat([a.expression.type.parameter.start]),compile:function(a,b,c){a.filter=a.match[2],a.modifier=a.match[1],delete a.match,delete a.value,c.push(a)},parse:function(b,c,d){var e=c.pop(),f=b.params&&a.expression.parse.apply(this,[b.params,d]),g=a.test(b.filter,e,f);b.modifier=="not"?c.push(!g):c.push(g)}},{type:a.expression.type.comma,regex:/^,/,next:a.expression.set.expressions,compile:function(b,c,d){var e=c.length-1,f;delete b.match,delete b.value;for(;e>=0;e--){f=c.pop();if(f.type===a.expression.type.object.start||f.type===a.expression.type.parameter.start||f.type===a.expression.type.array.start){c.push(f);break}d.push(f)}d.push(b)}},{type:a.expression.type.operator.binary,regex:/(^[\+\-~%\?\:]|^[!=]==?|^[!<>]=?|^\*\*?|^\/\/?|^and\s+|^or\s+|^in\s+|^not in\s+|^\.\.)/,next:a.expression.set.expressions.concat([a.expression.type.operator.unary]),compile:function(b,c,d){delete b.match,b.value=b.value.trim();var e=b.value,f=a.expression.operator.lookup(e,b);a.log.trace("Twig.expression.compile: ","Operator: ",f," from ",e);while(c.length>0&&(c[c.length-1].type==a.expression.type.operator.unary||c[c.length-1].type==a.expression.type.operator.binary)&&(f.associativity===a.expression.operator.leftToRight&&f.precidence>=c[c.length-1].precidence||f.associativity===a.expression.operator.rightToLeft&&f.precidence>c[c.length-1].precidence)){var g=c.pop();d.push(g)}if(e===":"){if(!c[c.length-1]||c[c.length-1].value!=="?"){var h=d.pop();if(h.type!==a.expression.type.string&&h.type!==a.expression.type.variable&&h.type!==a.expression.type.number)throw new a.Error("Unexpected value before ':' of "+h.type+" = "+h.value);b.key=h.value,d.push(b);return}}else c.push(f)},parse:function(b,c,d){b.key?c.push(b):a.expression.operator.parse(b.value,c)}},{type:a.expression.type.operator.unary,regex:/(^not\s+)/,next:a.expression.set.expressions,compile:function(b,c,d){delete b.match,b.value=b.value.trim();var e=b.value,f=a.expression.operator.lookup(e,b);a.log.trace("Twig.expression.compile: ","Operator: ",f," from ",e);while(c.length>0&&(c[c.length-1].type==a.expression.type.operator.unary||c[c.length-1].type==a.expression.type.operator.binary)&&(f.associativity===a.expression.operator.leftToRight&&f.precidence>=c[c.length-1].precidence||f.associativity===a.expression.operator.rightToLeft&&f.precidence>c[c.length-1].precidence)){var g=c.pop();d.push(g)}c.push(f)},parse:function(b,c,d){a.expression.operator.parse(b.value,c)}},{type:a.expression.type.string,regex:/^(["'])(?:(?=(\\?))\2.)*?\1/,next:a.expression.set.operations,compile:function(b,c,d){var e=b.value;delete b.match,e.substring(0,1)==='"'?e=e.replace('\\"','"'):e=e.replace("\\'","'"),b.value=e.substring(1,e.length-1),a.log.trace("Twig.expression.compile: ","String value: ",b.value),d.push(b)},parse:a.expression.fn.parse.push_value},{type:a.expression.type.parameter.start,regex:/^\(/,next:a.expression.set.expressions.concat([a.expression.type.parameter.end]),compile:a.expression.fn.compile.push_both,parse:a.expression.fn.parse.push},{type:a.expression.type.parameter.end,regex:/^\)/,next:a.expression.set.operations_extended,compile:function(b,c,d){var e,f=b;e=c.pop();while(c.length>0&&e.type!=a.expression.type.parameter.start)d.push(e),e=c.pop();var g=[];while(b.type!==a.expression.type.parameter.start)g.unshift(b),b=d.pop();g.unshift(b);var h=!1;b=d[d.length-1],b===undefined||b.type!==a.expression.type._function&&b.type!==a.expression.type.filter&&b.type!==a.expression.type.test&&b.type!==a.expression.type.key.brackets&&b.type!==a.expression.type.key.period?(f.expression=!0,g.pop(),g.shift(),f.params=g,d.push(f)):(f.expression=!1,b.params=g)},parse:function(b,c,d){var e=[],f=!1,g=null;if(b.expression)g=a.expression.parse.apply(this,[b.params,d]),c.push(g);else{while(c.length>0){g=c.pop();if(g&&g.type&&g.type==a.expression.type.parameter.start){f=!0;break}e.unshift(g)}if(!f)throw new a.Error("Expected end of parameter set.");c.push(e)}}},{type:a.expression.type.array.start,regex:/^\[/,next:a.expression.set.expressions.concat([a.expression.type.array.end]),compile:a.expression.fn.compile.push_both,parse:a.expression.fn.parse.push},{type:a.expression.type.array.end,regex:/^\]/,next:a.expression.set.operations_extended,compile:function(b,c,d){var e=c.length-1,f;for(;e>=0;e--){f=c.pop();if(f.type===a.expression.type.array.start)break;d.push(f)}d.push(b)},parse:function(b,c,d){var e=[],f=!1,g=null;while(c.length>0){g=c.pop();if(g.type&&g.type==a.expression.type.array.start){f=!0;break}e.unshift(g)}if(!f)throw new a.Error("Expected end of array.");c.push(e)}},{type:a.expression.type.object.start,regex:/^\{/,next:a.expression.set.expressions.concat([a.expression.type.object.end]),compile:a.expression.fn.compile.push_both,parse:a.expression.fn.parse.push},{type:a.expression.type.object.end,regex:/^\}/,next:a.expression.set.operations_extended,compile:function(b,c,d){var e=c.length-1,f;for(;e>=0;e--){f=c.pop();if(f&&f.type===a.expression.type.object.start)break;d.push(f)}d.push(b)},parse:function(b,c,d){var e={},f=!1,g=null,h=null,i=!1,j=null;while(c.length>0){g=c.pop();if(g&&g.type&&g.type===a.expression.type.object.start){f=!0;break}if(g&&g.type&&(g.type===a.expression.type.operator.binary||g.type===a.expression.type.operator.unary)&&g.key){if(!i)throw new a.Error("Missing value for key '"+g.key+"' in object definition.");e[g.key]=j,e._keys===undefined&&(e._keys=[]),e._keys.unshift(g.key),j=null,i=!1}else i=!0,j=g}if(!f)throw new a.Error("Unexpected end of object.");c.push(e)}},{type:a.expression.type.filter,regex:/^\|\s?([a-zA-Z_][a-zA-Z0-9_\-]*)/,next:a.expression.set.operations_extended.concat([a.expression.type.parameter.start]),compile:function(a,b,c){a.value=a.match[1],c.push(a)},parse:function(b,c,d){var e=c.pop(),f=b.params&&a.expression.parse.apply(this,[b.params,d]);c.push(a.filter.apply(this,[b.value,e,f]))}},{type:a.expression.type._function,regex:/^([a-zA-Z_][a-zA-Z0-9_]*)\s*\(/,next:a.expression.type.parameter.start,transform:function(a,b){return"("},compile:function(a,b,c){var d=a.match[1];a.fn=d,delete a.match,delete a.value,c.push(a)},parse:function(b,c,d){var e=b.params&&a.expression.parse.apply(this,[b.params,d]),f=b.fn,g;if(a.functions[f])g=a.functions[f].apply(this,e);else{if(typeof d[f]!="function")throw new a.Error(f+" function does not exist and is not defined in the context");g=d[f].apply(d,e)}c.push(g)}},{type:a.expression.type.variable,regex:/^[a-zA-Z_][a-zA-Z0-9_]*/,next:a.expression.set.operations_extended.concat([a.expression.type.parameter.start]),compile:a.expression.fn.compile.push,validate:function(b,c){return a.expression.reservedWords.indexOf(b[0])==-1},parse:function(b,c,d){var e=a.expression.resolve(d[b.value],d);c.push(e)}},{type:a.expression.type.key.period,regex:/^\.([a-zA-Z0-9_]+)/,next:a.expression.set.operations_extended.concat([a.expression.type.parameter.start]),compile:function(a,b,c){a.key=a.match[1],delete a.match,delete a.value,c.push(a)},parse:function(b,c,d){var e=b.params&&a.expression.parse.apply(this,[b.params
var mkdirp=require("../");var path=require("path");var fs=require("fs");var exists=fs.exists||path.exists;var test=require("tap").test;var _0777=parseInt("0777",8);var _0755=parseInt("0755",8);test("async perm",function(b){b.plan(5);var a="/tmp/"+(Math.random()*(1<<30)).toString(16);mkdirp(a,_0755,function(c){b.ifError(c);exists(a,function(d){b.ok(d,"file created");fs.stat(a,function(f,e){b.ifError(f);b.equal(e.mode&_0777,_0755);b.ok(e.isDirectory(),"target not a directory")})})})});test("async root perm",function(a){mkdirp("/tmp",_0755,function(b){if(b){a.fail(b)}a.end()});a.end()});
    this.files.forEach(function(f) {
      // there should be only 1 file in source, but just to make sure...
      var filepath = f.src[0];
      var field    = f.dest;

      // Warn on and remove invalid source files (if nonull was set).
      if (!grunt.file.exists(filepath)) {
        grunt.fail.warn('Source file "' + filepath + '" not found.');
        return false;
      }

      // get file size (necessary for multipart upload)
      fs.stat(filepath, function(err, stats) {
        if (err) {
          grunt.fail.warn('Error: ' + err);
          done(err);
        } else if (stats.isFile()) {
          var fileSize = stats.size;
          grunt.log.writeln('Uploading "' + filepath + '" as "' + field + '"');
          // build request data (because of dynamic key in data object)
          var reqData = {};
          reqData[field] = rest.file(filepath, null, fileSize, null, null);
          // HTTP request
          rest.request(options.url, {
            method: options.method,
            multipart: true,
            data: reqData
          }).on('complete', function(data, response) {
            if (response.statusCode === 200) {
              grunt.log.ok('Upload successful of "' + filepath + '" as "' + field + '" - ' + options.method + ' @ ' + options.url);
            } else {
              grunt.fail.warn('Failed uploading "' + filepath + '" as "' + field + '" (status code: ' + response.statusCode + ') - ' + options.method + ' @ ' + options.url);
            }
            // callback once upload is done
            done(data);
          });
        }
      });
    });
Example #28
0
 batch.push(function(done){
     fs.stat(join(dir, file), done);
 });
Example #29
0
  (function checkFile (target) {
    var fullname = path.join(self.dirname, target);

    //
    // Creates the `WriteStream` and then flushes any
    // buffered messages.
    //
    function createAndFlush (size) {
      if (self._stream) {
        self._stream.end();
        self._stream.destroySoon();
      }

      self._size = size;
      self.filename = target;
      self._stream = fs.createWriteStream(fullname, self.options);

      //
      // We need to listen for drain events when
      // write() returns false. This can make node
      // mad at times.
      //
      self._stream.setMaxListeners(Infinity);

      //
      // When the current stream has finished flushing
      // then we can be sure we have finished opening
      // and thus can emit the `open` event.
      //
      self.once('flush', function () {
        self.opening = false;
        self.emit('open', fullname);
      });

      //
      // Remark: It is possible that in the time it has taken to find the
      // next logfile to be written more data than `maxsize` has been buffered,
      // but for sensible limits (10s - 100s of MB) this seems unlikely in less
      // than one second.
      //
      self.flush();
    }

    fs.stat(fullname, function (err, stats) {
      if (err) {
        if (err.code !== 'ENOENT') {
          return self.emit('error', err);
        }

        return createAndFlush(0);
      }

      if (!stats || (self.maxsize && stats.size >= self.maxsize)) {
        //
        // If `stats.size` is greater than the `maxsize` for
        // this instance then try again
        //
        return checkFile(self._getFile(true));
      }

      var now = new Date();
      if (self._year < now.getFullYear() || self._month < now.getMonth() || self._date < now.getDate() || self._hour < now.getHours() || self._minute < now.getMinutes()) {
        self._year   = now.getFullYear();
        self._month  = now.getMonth();
        self._date   = now.getDate();
        self._hour   = now.getHours();
        self._minute = now.getMinutes();
        self._created  = 0;
        return checkFile(self._getFile());
      }

      createAndFlush(stats.size);
    });
  })(this._getFile());
Example #30
0
    return function tilePng(req, res, next) {
        //First, just see if a style change request is coming in.
        var args;

        //Grab POST or QueryString args depending on type
        if (req.method.toLowerCase() == "post") {
            //If a post, then arguments will be members of the this.req.body property
            args = req.body;
        }
        else if (req.method.toLowerCase() == "get") {
            //If request is a get, then args will be members of the this.req.query property
            args = req.query;
        }

        var style;
        var fromCache = true;
        var className = "default"; //by default.

        //see if user is trying to override cartocss style
        if (JSON.stringify(args) != '{}') {
            if (args.style) {
                style = args.style;
            }
            if (args.fromCache == "false") {
                fromCache = false;
            }
            if (args.className) {
                className = args.className;
            }
        }

        //if user overrides cache, or provides a custom style, update the map renderer then exit. Subsequent requests will use the udpated item.
        if (style) {
            if (style) {
                map.clearStyles(); //get rid of old styles.
                map.addStyle(style); //Set new style
            }
            if (className) {
                map.datasources[0].sourceName = className || "default";
            }
            //Get out of here.
            res.end("Updated styling for this endpoint.");
        }

        var tileCoordinate, bounds;
        // verify arguments
        tileCoordinate = req.path.match(/(\d+)\/(\d+)\/(\d+)\.png$/);
        if (!tileCoordinate) {
            return next();
        }

        // slice the regexp down to usable size      
        tileCoordinate = tileCoordinate.slice(1, 4).map(Number);

        var tileName = req.path.split("/").join("-");

        if (fromCache == false) {
            //Render it
            dynamicRenderTile();
        }
        else {
            //See if file exists on disk.  If so, then use it, otherwise, render it and respond.
            fs.stat(options.cachePath + '/' + tileName, function (err, stat) {
                if (!err) {
                    fs.readFile(options.cachePath + '/' + tileName, function (err, contents) {
                        //serve file from disk
                        console.log("Serving " + tileName + " from disk.");
                        res.writeHead(200, { 'Content-Type': 'image/png' });
                        res.end(contents, 'binary');
                    });
                } else {
                    //No file, render it
                    dynamicRenderTile();
                }
            });
        }

        function dynamicRenderTile() {
            // set the bounds and render
            bounds = Projector.util.tileToMeters(tileCoordinate[1], tileCoordinate[2], tileCoordinate[0]);
            map.render({
                bounds: { minX: bounds[0], minY: bounds[1], maxX: bounds[2], maxY: bounds[3] },
                width: 256,
                height: 256,
                zoom: tileCoordinate[0],
                callback: function (err, canvas) {
                    // TODO: catche the error
                    var stream = canvas.createPNGStream();
                    stream.pipe(res);

                    var out = fs.createWriteStream(options.cachePath + '/' + tileName)

                    stream.on('data', function (chunk) {
                        out.write(chunk);
                    });

                    stream.on('end', function () {
                        out.end();
                        console.log('saved png - ' + tileName);
                    });
                }
            });
        }
    };