<commit_before>/*jshint esnext:true*/
/*globals module:true, require:true, process:true*/

/*
 * Grunt Task File
 * ---------------
 *
 * Task: S3
 * Description: Move files to and from s3
 * Dependencies: knox, async, underscore.deferred
 *
 */

module.exports = function (grunt) {

  const _ = require('underscore');
  const path = require('path');
  const s3 = require('./lib/s3').init(grunt);

  /**
   * Grunt aliases.
   */
  var log = grunt.log;

  /**
   * Transfer files to/from s3.
   *
   * Uses global s3 grunt config.
   */
  grunt.registerTask('s3', 'Publishes files to s3.', function () {
    var done = this.async();
    var config = _.defaults(s3.getConfig(), {
      upload: [],
      download: [],
      del: [],
      copy: []
    });

    var transfers = [];

    config.upload.forEach(function(upload) {
      // Expand list of files to upload.
      var files = grunt.file.expandFiles(upload.src);

      files.forEach(function(file) {
        file = path.resolve(file);
        upload.src = path.resolve(grunt.template.process(upload.src));

        // If there is only 1 file and it matches the original file wildcard,
        // we know this is a single file transfer. Otherwise, we need to build
        // the destination.
        var dest;
        if (files.length === 1 && file === upload.src) {
          dest = upload.dest;
        }
        else {
          if (upload.rel) {
            dest = path.join(upload.dest, path.relative(grunt.file.expandDirs(upload.rel)[0], file));
          }
          else {
            dest = path.join(upload.dest, path.basename(file));
          }
        }

        transfers.push(s3.upload(file, dest, upload));
      });
    });

    config.download.forEach(function(download) {
      transfers.push(s3.download(download.src, download.dest, download));
    });

    config.del.forEach(function(del) {
      transfers.push(s3.del(del.src, del));
    });

    config.copy.forEach(function(copy) {
      transfers.push(s3.copy(copy.src, copy.dest, copy));
    });

    var total = transfers.length;
    var errors = 0;

    // Keep a running total of errors/completions as the transfers complete.
    transfers.forEach(function(transfer) {
      transfer.done(function(msg) {
        log.ok(msg);
      });

      transfer.fail(function(msg) {
        log.error(msg);
        ++errors;
      });

      transfer.always(function() {
        // If this was the last transfer to complete, we're all done.
        if (--total === 0) {
          done(!errors);
        }
      });
    });
  });

};

<commit_msg>Add template support for s3.upload.<commit_after>/*jshint esnext:true*/
/*globals module:true, require:true, process:true*/

/*
 * Grunt Task File
 * ---------------
 *
 * Task: S3
 * Description: Move files to and from s3
 * Dependencies: knox, async, underscore.deferred
 *
 */

module.exports = function (grunt) {

  const _ = require('underscore');
  const path = require('path');
  const s3 = require('./lib/s3').init(grunt);

  /**
   * Grunt aliases.
   */
  var log = grunt.log;

  /**
   * Transfer files to/from s3.
   *
   * Uses global s3 grunt config.
   */
  grunt.registerTask('s3', 'Publishes files to s3.', function () {
    var done = this.async();
    var config = _.defaults(s3.getConfig(), {
      upload: [],
      download: [],
      del: [],
      copy: []
    });

    var transfers = [];

    config.upload.forEach(function(upload) {
      // Expand list of files to upload.
      var files = grunt.file.expandFiles(upload.src),
          destPath = grunt.template.process(upload.dest);

      files.forEach(function(file) {
        file = path.resolve(file);
        upload.src = path.resolve(grunt.template.process(upload.src));

        // If there is only 1 file and it matches the original file wildcard,
        // we know this is a single file transfer. Otherwise, we need to build
        // the destination.
        var dest;
        if (files.length === 1 && file === upload.src) {
          dest = destPath;
        }
        else {
          if (upload.rel) {
            dest = path.join(destPath, path.relative(grunt.file.expandDirs(upload.rel)[0], file));
          }
          else {
            dest = path.join(destPath, path.basename(file));
          }
        }

        transfers.push(s3.upload(file, dest, upload));
      });
    });

    config.download.forEach(function(download) {
      transfers.push(s3.download(download.src, download.dest, download));
    });

    config.del.forEach(function(del) {
      transfers.push(s3.del(del.src, del));
    });

    config.copy.forEach(function(copy) {
      transfers.push(s3.copy(copy.src, copy.dest, copy));
    });

    var total = transfers.length;
    var errors = 0;

    // Keep a running total of errors/completions as the transfers complete.
    transfers.forEach(function(transfer) {
      transfer.done(function(msg) {
        log.ok(msg);
      });

      transfer.fail(function(msg) {
        log.error(msg);
        ++errors;
      });

      transfer.always(function() {
        // If this was the last transfer to complete, we're all done.
        if (--total === 0) {
          done(!errors);
        }
      });
    });
  });

};

<|endoftext|>


<commit_before>"use strict";

angular.module('arethusa.morph').factory('bspMorphRetriever', function(configurator) {
  // Might want to read in language and engine dynamically later
  // also make factory out of it, so that we could use several
  // bsp instances with different settings
  var resource = configurator.provideResource('bspMorphRetriever');

  var getWord = function(word) {
    return resource.get({ 'word': word });
  };

  var deleteUnwantedKeys = function(obj, keys) {
    keys.forEach(function(el) {
      delete obj[el];
    });
  };

  var flattenAttributes= function(form, toFlatten) {
    toFlatten.forEach(function(el) {
      var attr = form[el];
      if (attr) {
        form[el] = attr.$;
      }
    });
  };

  var renameAttributes = function(form, renamers) {
    for (var oldName in renamers) {
      var newName = renamers[oldName];
      var val = form[oldName];
      delete form[oldName];
      form[newName] = val;
    }
  };

  var renameValues = function(form, renamers) {
    for (var key in renamers) {
      var val = form[key];
      var naming = renamers[key];
      if (val === naming[0]) {
        form[key] = naming[1];
      }
    }
  };

  return {
    getData: function(string, callback) {
      getWord(string).then(function(res) {
        try {
          // The body can contain a single object or an array of objects.
          // Can also be undefined, in that case we will just throw an exception
          // eventually - and we will end up in catch path and just return
          // an empty array.
          var entries = arethusaUtil.toAry(res.RDF.Annotation.Body);
          var results = arethusaUtil.inject([], entries, function(results, el) {
            var entry = el.rest.entry;
            var lemma = entry.dict.hdwd.$;
            var lexInvUri = entry.uri;
            // We might have multiple inflections for each entry and need to wrap
            // the array vs. object problem again.
            arethusaUtil.toAry(entry.infl).forEach(function(form) {
              // form is an object with some key/val pairs we have no use for right
              // now - we just ditch them. The rest we take and form another object,
              // which will wrap up the morphological attributes and contain lemma
              // information.
              // There are actually more than these original 3 - we might want to do
              // this differently at some point.
              deleteUnwantedKeys(form, ['term', 'stemtype']);

              // If the form has a case attribute, it wrapped in another object we
              // don't want and need. Flatten it to a plain expression.
              // The same goes for part of speech.
              flattenAttributes(form, ['case', 'pofs']);

              // These renaming stuff could probably be configurable...
              renameAttributes(form, {'pofs': 'pos'});
              renameValues(form, { 'pos' : ['verb\nparticiple', 'participle']});

              results.push({
                lexInvUri: lexInvUri,
                lemma: lemma,
                attributes: form,
                origin: 'bsp/morpheus'
              });
            });
          });
          callback(results);
        } catch(err) {
          return [];
        }
      });
      return [];
    }
  };
});
<commit_msg>Have to use res.data in bspMorphRetriever<commit_after>"use strict";

angular.module('arethusa.morph').factory('bspMorphRetriever', function(configurator) {
  // Might want to read in language and engine dynamically later
  // also make factory out of it, so that we could use several
  // bsp instances with different settings
  var resource = configurator.provideResource('bspMorphRetriever');

  var getWord = function(word) {
    return resource.get({ 'word': word });
  };

  var deleteUnwantedKeys = function(obj, keys) {
    keys.forEach(function(el) {
      delete obj[el];
    });
  };

  var flattenAttributes= function(form, toFlatten) {
    toFlatten.forEach(function(el) {
      var attr = form[el];
      if (attr) {
        form[el] = attr.$;
      }
    });
  };

  var renameAttributes = function(form, renamers) {
    for (var oldName in renamers) {
      var newName = renamers[oldName];
      var val = form[oldName];
      delete form[oldName];
      form[newName] = val;
    }
  };

  var renameValues = function(form, renamers) {
    for (var key in renamers) {
      var val = form[key];
      var naming = renamers[key];
      if (val === naming[0]) {
        form[key] = naming[1];
      }
    }
  };

  return {
    getData: function(string, callback) {
      getWord(string).then(function(res) {
        try {
          // The body can contain a single object or an array of objects.
          // Can also be undefined, in that case we will just throw an exception
          // eventually - and we will end up in catch path and just return
          // an empty array.
          var entries = arethusaUtil.toAry(res.data.RDF.Annotation.Body);
          var results = arethusaUtil.inject([], entries, function(results, el) {
            var entry = el.rest.entry;
            var lemma = entry.dict.hdwd.$;
            var lexInvUri = entry.uri;
            // We might have multiple inflections for each entry and need to wrap
            // the array vs. object problem again.
            arethusaUtil.toAry(entry.infl).forEach(function(form) {
              // form is an object with some key/val pairs we have no use for right
              // now - we just ditch them. The rest we take and form another object,
              // which will wrap up the morphological attributes and contain lemma
              // information.
              // There are actually more than these original 3 - we might want to do
              // this differently at some point.
              deleteUnwantedKeys(form, ['term', 'stemtype']);

              // If the form has a case attribute, it wrapped in another object we
              // don't want and need. Flatten it to a plain expression.
              // The same goes for part of speech.
              flattenAttributes(form, ['case', 'pofs']);

              // These renaming stuff could probably be configurable...
              renameAttributes(form, {'pofs': 'pos'});
              renameValues(form, { 'pos' : ['verb\nparticiple', 'participle']});

              results.push({
                lexInvUri: lexInvUri,
                lemma: lemma,
                attributes: form,
                origin: 'bsp/morpheus'
              });
            });
          });
          callback(results);
        } catch(err) {
          return [];
        }
      });
      return [];
    }
  };
});
<|endoftext|>


<commit_before>/*
Gulp is used to managed all sass/css and javascript resources.

You can use `gulp watch` to rebuild the custom css and js on change and
`gulp brwosersync` for automatically pushing changed reqources to the browser
*/

var gulp       = require('gulp'),
    concat     = require('gulp-concat'),
    gulpif     = require('gulp-if'),
    sass       = require('gulp-sass'),
    sourcemaps = require('gulp-sourcemaps'),
    uglify     = require('gulp-uglify'),
    exec       = require('child_process').exec;

// browsersync will only be used with the browsersync task
var browsersync = require('browser-sync').create();
var use_browsersync = false;

// setting this to false makes debugging easier and building the js a hundred times faster
var use_uglify = true;

var paths = {
    source_styles: ["html/css/*.scss"],
    source_js: ["html/js/**/*.js", "html/bower/**/*.js", "!html/js/build/*.js"],
    build_js: ["html/js/build/*.js"],
    php: ["protected/**/*.php"],
    std_js: [
        "html/bower/typeahead.js/dist/typeahead.bundle.min.js",
        "html/bower/bootstrap-sass/assets/javascripts/bootstrap.min.js",
        "html/js/jquery-ui-1.11.2.custom.min.js",
        "html/js/scrollintoview.js",
        "html/js/material/ripples.min.js",
        "html/js/material/material.min.js",
        "html/js/custom/*.js",
    ],
    leaflet_js: [
        "html/js/build/ba-grenzen-geojson.js",
        "html/bower/leaflet/dist/leaflet.js",
        "html/bower/Leaflet.draw/dist/leaflet.draw.js",
        "html/bower/leaflet.locatecontrol/dist/L.Control.Locate.min.js",
        "html/js/Leaflet.Fullscreen/Control.FullScreen.js",
        "html/js/Leaflet.Control.Geocoder/Control.Geocoder.js",
        "html/js/leaflet.spiderfy.js",
        "html/js/leaflet.textmarkers.js",
        "html/js/antraegekarte.jquery.js",
    ],
    pdfjs_js: [
        "html/pdfjs/web/compatibility.js",
        "html/pdfjs/web/l10n.js",
        "html/pdfjs/build/pdf.js",
        "html/pdfjs/web/viewer.js",
    ],
    pdfjs_css: [
        "html/pdfjs/web/viewer.css",
    ],
}

gulp.task('default', ['std.js', 'leaflet.js', 'sass', 'pdfjs']);

gulp.task('watch', ['default'], function () {
    use_uglify = false; // much better performance
    gulp.watch(paths.source_js, ['std.js']);
    gulp.watch(paths.source_styles, ['sass']);
});

gulp.task('browsersync', ['watch'], function() {
    use_browsersync = true;
    browsersync.init({
        proxy: "ratsinformant.local"
    });

    gulp.watch(paths.build_js).on("change", browsersync.reload);
    gulp.watch(paths.php     ).on("change", browsersync.reload);
});

// helper tasks

gulp.task('std.js', function () {
    return gulp.src(paths.std_js)
        .pipe(concat('std.js'))
        .pipe(gulpif(use_uglify, uglify()))
        .pipe(gulp.dest('html/js/build/'));
});

gulp.task('leaflet.js', ['ba-grenzen-geojson'], function () {
    return gulp.src(paths.leaflet_js)
        .pipe(concat('leaflet.js'))
        .pipe(gulpif(use_uglify, uglify()))
        .pipe(gulp.dest('html/js/build/'));
});

gulp.task('sass', function () {
    return gulp.src(paths.source_styles)
        .pipe(sourcemaps.init())
        .pipe(sass({
            outputStyle: 'compressed'
        }).on('error', sass.logError))
        .pipe(sourcemaps.write('./'))
        .pipe(gulp.dest('html/css/build/'))
        .pipe(gulpif(use_browsersync, browsersync.stream({match: "**/*.css"})));
});

gulp.task('ba-grenzen-geojson', function () {
    return exec('protected/yiic bagrenzengeojson html/js/build/ba-grenzen-geojson.js');
});

gulp.task('pdfjs', ['pdfjs.js', 'pdfjs.css'])

gulp.task('pdfjs.js', function () {
    return gulp.src(paths.pdfjs_js)
        .pipe(concat('build.js'))
        .pipe(gulpif(use_uglify, uglify()))
        .pipe(gulp.dest('html/pdfjs/web/'));
});

gulp.task('pdfjs.css', function () {
    return gulp.src(paths.pdfjs_css)
        .pipe(concat('build.css'))
        .pipe(sourcemaps.init())
        .pipe(sass({
            outputStyle: 'compressed'
        }).on('error', sass.logError))
        .pipe(sourcemaps.write('./'))
        .pipe(gulp.dest('html/pdfjs/web/'))
        .pipe(gulpif(use_browsersync, browsersync.stream({match: "**/*.css"})));
});
<commit_msg>Bereichsauswahl auf der Karte reparieren<commit_after>/*
Gulp is used to managed all sass/css and javascript resources.

You can use `gulp watch` to rebuild the custom css and js on change and
`gulp brwosersync` for automatically pushing changed reqources to the browser
*/

var gulp       = require('gulp'),
    concat     = require('gulp-concat'),
    gulpif     = require('gulp-if'),
    sass       = require('gulp-sass'),
    sourcemaps = require('gulp-sourcemaps'),
    uglify     = require('gulp-uglify'),
    exec       = require('child_process').exec;

// browsersync will only be used with the browsersync task
var browsersync = require('browser-sync').create();
var use_browsersync = false;

// setting this to false makes debugging easier and building the js a hundred times faster
var use_uglify = true;

var paths = {
    source_styles: ["html/css/*.scss"],
    source_js: ["html/js/**/*.js", "html/bower/**/*.js", "!html/js/build/*.js"],
    build_js: ["html/js/build/*.js"],
    php: ["protected/**/*.php"],
    std_js: [
        "html/bower/typeahead.js/dist/typeahead.bundle.min.js",
        "html/bower/bootstrap-sass/assets/javascripts/bootstrap.min.js",
        "html/js/jquery-ui-1.11.2.custom.min.js",
        "html/js/scrollintoview.js",
        "html/js/material/ripples.min.js",
        "html/js/material/material.min.js",
        "html/js/custom/*.js",
    ],
    leaflet_js: [
        "html/js/build/ba-grenzen-geojson.js",
        "html/bower/leaflet/dist/leaflet.js",
        "html/bower/leaflet.draw/dist/leaflet.draw.js",
        "html/bower/leaflet.locatecontrol/dist/L.Control.Locate.min.js",
        "html/js/Leaflet.Control.Geocoder/Control.Geocoder.js",
        "html/js/leaflet.spiderfy.js",
        "html/js/leaflet.textmarkers.js",
        "html/js/antraegekarte.jquery.js",
    ],
    pdfjs_js: [
        "html/pdfjs/web/compatibility.js",
        "html/pdfjs/web/l10n.js",
        "html/pdfjs/build/pdf.js",
        "html/pdfjs/web/viewer.js",
    ],
    pdfjs_css: [
        "html/pdfjs/web/viewer.css",
    ],
}

gulp.task('default', ['std.js', 'leaflet.js', 'sass', 'pdfjs']);

gulp.task('watch', ['default'], function () {
    use_uglify = false; // much better performance
    gulp.watch(paths.source_js, ['std.js']);
    gulp.watch(paths.source_styles, ['sass']);
});

gulp.task('browsersync', ['watch'], function() {
    use_browsersync = true;
    browsersync.init({
        proxy: "ratsinformant.local"
    });

    gulp.watch(paths.build_js).on("change", browsersync.reload);
    gulp.watch(paths.php     ).on("change", browsersync.reload);
});

// helper tasks

gulp.task('std.js', function () {
    return gulp.src(paths.std_js)
        .pipe(concat('std.js'))
        .pipe(gulpif(use_uglify, uglify()))
        .pipe(gulp.dest('html/js/build/'));
});

gulp.task('leaflet.js', ['ba-grenzen-geojson'], function () {
    return gulp.src(paths.leaflet_js)
        .pipe(concat('leaflet.js'))
        .pipe(gulpif(use_uglify, uglify()))
        .pipe(gulp.dest('html/js/build/'));
});

gulp.task('sass', function () {
    return gulp.src(paths.source_styles)
        .pipe(sourcemaps.init())
        .pipe(sass({
            outputStyle: 'compressed'
        }).on('error', sass.logError))
        .pipe(sourcemaps.write('./'))
        .pipe(gulp.dest('html/css/build/'))
        .pipe(gulpif(use_browsersync, browsersync.stream({match: "**/*.css"})));
});

gulp.task('ba-grenzen-geojson', function () {
    return exec('protected/yiic bagrenzengeojson html/js/build/ba-grenzen-geojson.js');
});

gulp.task('pdfjs', ['pdfjs.js', 'pdfjs.css'])

gulp.task('pdfjs.js', function () {
    return gulp.src(paths.pdfjs_js)
        .pipe(concat('build.js'))
        .pipe(gulpif(use_uglify, uglify()))
        .pipe(gulp.dest('html/pdfjs/web/'));
});

gulp.task('pdfjs.css', function () {
    return gulp.src(paths.pdfjs_css)
        .pipe(concat('build.css'))
        .pipe(sourcemaps.init())
        .pipe(sass({
            outputStyle: 'compressed'
        }).on('error', sass.logError))
        .pipe(sourcemaps.write('./'))
        .pipe(gulp.dest('html/pdfjs/web/'))
        .pipe(gulpif(use_browsersync, browsersync.stream({match: "**/*.css"})));
});
<|endoftext|>


<commit_before>var util = require('util');
var EventEmitter = require('events').EventEmitter;

module.exports = Hardware;

function Hardware() {
  EventEmitter.call(this);
  const that = this;
  //this.ledBusy=ledBusy; //

  robot.setup(); // Set up GPIO ports
  ledBusy();

  this.status = {
    startedOn:new Date(),
    //sensors:null,
    leds:[null,null],
    motors:[0,0],
    power:"on"
  }

  this.update=()=>{myexit(0); this.status.power="updating...";};
  this.restart=()=>{myexit(10); this.status.power="restarting...";};
  this.kill=()=>{myexit(20); this.status.power="terminating...";};

  this.led1_switch=()=> { robot.setLED(1,(robot.getLED(1)?0:1)); }
  this.led2_switch=()=> { robot.setLED(2,(robot.getLED(2)?0:1)); }
  this.forward=()=> { ledBusy(); robot.setMotor("left",1); robot.setMotor("right",1); resheduleStop(); }
  this.backwards=()=> { ledBusy(); robot.setMotor("left",1,1); robot.setMotor("right",1,1); resheduleStop(); }
  this.stop=()=> { motorStop(); unsheduleStop();}
  this.left=()=> { ledBusy(); robot.setMotor("left",0); robot.setMotor("right",1); resheduleStop(); }
  this.right=()=> { ledBusy(); robot.setMotor("left",1); robot.setMotor("right",0); resheduleStop(); }

  this.setDirection=(d)=> { //x,y
    if (d.x==0){
      //prosto
      if (d.y==0) {
        motorStop();
      } else {
        var reverse = d.y>0?0:1;
        ledBusy(); robot.setMotor("left",1,reverse); robot.setMotor("right",1,reverse);
      }
    } else {
      //skrecamy
      ledBusy();
      if (d.y==0) {
        //w miejscu
        robot.setMotor("left",1,d.x<0?1:0); robot.setMotor("right",1,d.x>0?1:0);
      } else {
        //w ruchu
        var dir = d.y==1?0:1;
        robot.setMotor("left",d.x==d.y?1:0,dir); robot.setMotor("right",d.x!=d.y?1:0,dir);
      }
    }
  }

  function myexit(code) {
      robot.setLED(1, 1);
      robot.setLED(2, 1);
      broadcast("Server closing in 1 sec. Code: "+code);
      setTimeout(function(){process.exit(code);}, 1000);
  }

  function broadcast(message) {
      //process.stdout.write(message+"\n");
      that.emit('message', message);
  }

  function sensorOrNull() {
    try {
      var i2c = require('i2c-bus');
      var MPU6050 = require('i2c-mpu6050');

      var address = 0x68;
      var i2c1 = i2c.openSync(1);

      var sensor = new MPU6050(i2c1, address);
      return sensor;
    } catch (e) {
      return null;
    }
  }

  const sensor = sensorOrNull();

  this.sensorReadSync = function() {
    if (sensor!=null) {
      return sensor.readSync();
    } else {
      return null;
    }
  }

  function emitStatusUpdated() {
    that.emit("statusUpdated", that.status);
  }

  function runSensors() {
    that.status.sensors = that.sensorReadSync();
    emitStatusUpdated();
  }

  if (sensor!=null) {
    setInterval(runSensors, 500);
  }
}

util.inherits(Hardware, EventEmitter);

//var util = require('util');
//var EventEmitter = require('events').EventEmitter;

var RaspiRobot = require("./raspirobot.js").RaspiRobot, // Import the library
    robot = new RaspiRobot();

function ledBusy(){
    robot.setLED(1, 1); // Turn on LED 1
    robot.setLED(2, 0); // Turn off LED 2
}

function motorStop() {
  robot.setLED(1,0);
  robot.setLED(2,1);
  robot.setMotor("left",0);
  robot.setMotor("right",0);
}

var stopScheduledTimeout = setTimeout(motorStop, 250)

function unsheduleStop() {
  clearTimeout(stopScheduledTimeout);
}

function resheduleStop() {
    unsheduleStop();
    stopScheduledTimeout = setTimeout(motorStop, 250);
}
<commit_msg>enableSensorsStreaming<commit_after>var util = require('util');
var EventEmitter = require('events').EventEmitter;

module.exports = Hardware;

function Hardware() {
  EventEmitter.call(this);
  const that = this;
  //this.ledBusy=ledBusy; //

  robot.setup(); // Set up GPIO ports
  ledBusy();

  this.status = {
    startedOn:new Date(),
    //sensors:null,
    leds:[null,null],
    motors:[0,0],
    power:"on"
  }

  this.update=()=>{myexit(0); this.status.power="updating...";};
  this.restart=()=>{myexit(10); this.status.power="restarting...";};
  this.kill=()=>{myexit(20); this.status.power="terminating...";};

  this.led1_switch=()=> { robot.setLED(1,(robot.getLED(1)?0:1)); }
  this.led2_switch=()=> { robot.setLED(2,(robot.getLED(2)?0:1)); }
  this.forward=()=> { ledBusy(); robot.setMotor("left",1); robot.setMotor("right",1); resheduleStop(); }
  this.backwards=()=> { ledBusy(); robot.setMotor("left",1,1); robot.setMotor("right",1,1); resheduleStop(); }
  this.stop=()=> { motorStop(); unsheduleStop();}
  this.left=()=> { ledBusy(); robot.setMotor("left",0); robot.setMotor("right",1); resheduleStop(); }
  this.right=()=> { ledBusy(); robot.setMotor("left",1); robot.setMotor("right",0); resheduleStop(); }

  this.setDirection=(d)=> { //x,y
    if (d.x==0){
      //prosto
      if (d.y==0) {
        motorStop();
      } else {
        var reverse = d.y>0?0:1;
        ledBusy(); robot.setMotor("left",1,reverse); robot.setMotor("right",1,reverse);
      }
    } else {
      //skrecamy
      ledBusy();
      if (d.y==0) {
        //w miejscu
        robot.setMotor("left",1,d.x<0?1:0); robot.setMotor("right",1,d.x>0?1:0);
      } else {
        //w ruchu
        var dir = d.y==1?0:1;
        robot.setMotor("left",d.x==d.y?1:0,dir); robot.setMotor("right",d.x!=d.y?1:0,dir);
      }
    }
  }

  function myexit(code) {
      robot.setLED(1, 1);
      robot.setLED(2, 1);
      broadcast("Server closing in 1 sec. Code: "+code);
      setTimeout(function(){process.exit(code);}, 1000);
  }

  function broadcast(message) {
      //process.stdout.write(message+"\n");
      that.emit('message', message);
  }

  function sensorOrNull() {
    try {
      var i2c = require('i2c-bus');
      var MPU6050 = require('i2c-mpu6050');

      var address = 0x68;
      var i2c1 = i2c.openSync(1);

      var sensor = new MPU6050(i2c1, address);
      return sensor;
    } catch (e) {
      return null;
    }
  }

  const sensor = sensorOrNull();

  this.sensorReadSync = function() {
    if (sensor!=null) {
      return sensor.readSync();
    } else {
      return null;
    }
  }

  this._enableSensorsStreaming=false;
  function enableSensorsStreaming(enable) {
    this._enableSensorsStreaming=enable;
  }

  function emitStatusUpdated() {
    that.emit("statusUpdated", that.status);
  }

  function runSensors() {
    that.status.sensors = that.sensorReadSync();
    emitStatusUpdated();
  }

  function streamSensorsIfEnabled() {
    if (this._enableSensorsStreaming) {
      runSensors();
    }
  }

  if (sensor!=null) {
    setInterval(streamSensorsIfEnabled, 500);
  }
}

util.inherits(Hardware, EventEmitter);

//var util = require('util');
//var EventEmitter = require('events').EventEmitter;

var RaspiRobot = require("./raspirobot.js").RaspiRobot, // Import the library
    robot = new RaspiRobot();

function ledBusy(){
    robot.setLED(1, 1); // Turn on LED 1
    robot.setLED(2, 0); // Turn off LED 2
}

function motorStop() {
  robot.setLED(1,0);
  robot.setLED(2,1);
  robot.setMotor("left",0);
  robot.setMotor("right",0);
}

var stopScheduledTimeout = setTimeout(motorStop, 250)

function unsheduleStop() {
  clearTimeout(stopScheduledTimeout);
}

function resheduleStop() {
    unsheduleStop();
    stopScheduledTimeout = setTimeout(motorStop, 250);
}
<|endoftext|>


<commit_before>/*
 * # DEPENDENCIES #
 */
var path = require('path');
var fs = require('fs');

/*
 * Variables that depend on each other
 */

// paths
var lessonRoot = '..';
var buildRoot = path.join(lessonRoot, 'build');
var builderRoot = path.basename(__dirname);
var assetRoot = path.join(buildRoot, 'assets');
var sourceFolder = 'src';
var sourceRoot = path.join(lessonRoot, sourceFolder);

var collections = fs.readdirSync(sourceRoot).filter(function(file) {
  return fs.statSync(path.join(sourceRoot, file)).isDirectory();
});

/*
 * Export. Independent variables can be put here directly.
 */
var config = {
  assetRoot:      assetRoot,
  buildRoot:      buildRoot,
  builderRoot:    builderRoot,
  lessonRoot:     lessonRoot,
  sourceRoot:     sourceRoot,
  // folder names
  playlistFolder: 'playlists',
  sourceFolder:   sourceFolder,
  sourceRoot:     sourceRoot,
  // collections
  collections:    collections,
  // github webhook for automatic building
  // Payload URL will be http://ghHost:ghPort/ghPath
  ghHost:         '0.0.0.0', // 0.0.0.0 listen on all interfaces
  ghPort:         3034,
  ghPath:         '/',
  ghMergeCommand:  '../deploy.sh',
  ghSecret:       'secret',
  // link crawling
  productionCrawlStart: 'http://arve0.github.io/example_lessons/',
  // level names
  levelNames: {
    1: 'Novice',
    2: 'Apprentice',
    3: 'Journeyman',
    4: 'Expert',
    5: 'Master',
    6: 'Champion'
  }
};

module.exports = config;
<commit_msg>collections: allow src/folder not being a collection<commit_after>/*
 * # DEPENDENCIES #
 */
var path = require('path');
var globby = require('globby');

/*
 * Variables that depend on each other
 */

// paths
var lessonRoot = '..';
var buildRoot = path.join(lessonRoot, 'build');
var builderRoot = path.basename(__dirname);
var assetRoot = path.join(buildRoot, 'assets');
var sourceFolder = 'src';
var sourceRoot = path.join(lessonRoot, sourceFolder);

/**
 * Collections
 * Collections are folders which contain an index.md file.
 * This allows for redirections, e.g., empty index.html with
 * <script> window.location = "newUrl" </script>
 */
var collectionIndexPath = sourceRoot + '/*/index.md';
var collectionIndexes = globby.sync(collectionIndexPath);
var collections = collectionIndexes.map(function(value){
  // ["../src/python/index.md", ...] -> ["python", ...]
  var start = sourceRoot.length + 1;
  var length = value.indexOf('/index.md') - start;
  return value.substr(start, length);
});

/*
 * Export. Independent variables can be put here directly.
 */
var config = {
  assetRoot:      assetRoot,
  buildRoot:      buildRoot,
  builderRoot:    builderRoot,
  lessonRoot:     lessonRoot,
  sourceRoot:     sourceRoot,
  // folder names
  playlistFolder: 'playlists',
  sourceFolder:   sourceFolder,
  sourceRoot:     sourceRoot,
  // collections
  collections:    collections,
  // github webhook for automatic building
  // Payload URL will be http://ghHost:ghPort/ghPath
  ghHost:         '0.0.0.0', // 0.0.0.0 listen on all interfaces
  ghPort:         3034,
  ghPath:         '/',
  ghMergeCommand:  '../deploy.sh',
  ghSecret:       'secret',
  // link crawling
  productionCrawlStart: 'http://arve0.github.io/example_lessons/',
  // level names
  levelNames: {
    1: 'Novice',
    2: 'Apprentice',
    3: 'Journeyman',
    4: 'Expert',
    5: 'Master',
    6: 'Champion'
  }
};

module.exports = config;
<|endoftext|>


<commit_before>const got = require('got');
const url = require('url');
const is = require('@sindresorhus/is');
const { isVersion, sortVersions } = require('../versioning')('pep440');

module.exports = {
  getPkgReleases,
};

function normalizeName(input) {
  return input.toLowerCase().replace(/-/g, '_');
}

async function getPkgReleases(purl, config = {}) {
  const { fullname: depName } = purl;
  let hostUrl = 'https://pypi.org/pypi/';
  if (!is.empty(config.registryUrls)) {
    [hostUrl] = config.registryUrls;
  }
  if (process.env.PIP_INDEX_URL) {
    [hostUrl] = [process.env.PIP_INDEX_URL];
  }
  const lookupUrl = url.resolve(hostUrl, `${depName}/json`);
  try {
    const dependency = {};
    const rep = await got(lookupUrl, {
      json: true,
    });
    const dep = rep && rep.body;
    if (!dep) {
      logger.debug({ depName }, 'pip package not found');
      return null;
    }
    if (
      !(dep.info && normalizeName(dep.info.name) === normalizeName(depName))
    ) {
      logger.warn(
        { lookupUrl, lookupName: depName, returnedName: dep.info.name },
        'Returned name does not match with requested name'
      );
      return null;
    }
    if (dep.info && dep.info.home_page) {
      if (dep.info.home_page.startsWith('https://github.com')) {
        dependency.repositoryUrl = dep.info.home_page;
      } else {
        dependency.homepage = dep.info.home_page;
      }
    }
    dependency.releases = [];
    if (dep.releases) {
      const versions = Object.keys(dep.releases)
        .filter(isVersion)
        .sort(sortVersions);
      dependency.releases = versions.map(version => ({
        version,
        releaseTimestamp: (dep.releases[version][0] || {}).upload_time,
      }));
    }
    return dependency;
  } catch (err) {
    logger.info('pypi dependency not found: ' + depName);
    return null;
  }
}
<commit_msg>refactor(pypi): manual repositories map<commit_after>const got = require('got');
const url = require('url');
const is = require('@sindresorhus/is');
const { isVersion, sortVersions } = require('../versioning')('pep440');

module.exports = {
  getPkgReleases,
};

function normalizeName(input) {
  return input.toLowerCase().replace(/-/g, '_');
}

async function getPkgReleases(purl, config = {}) {
  const { fullname: depName } = purl;
  let hostUrl = 'https://pypi.org/pypi/';
  if (!is.empty(config.registryUrls)) {
    [hostUrl] = config.registryUrls;
  }
  if (process.env.PIP_INDEX_URL) {
    [hostUrl] = [process.env.PIP_INDEX_URL];
  }
  const lookupUrl = url.resolve(hostUrl, `${depName}/json`);
  try {
    const dependency = {};
    const rep = await got(lookupUrl, {
      json: true,
    });
    const dep = rep && rep.body;
    if (!dep) {
      logger.debug({ depName }, 'pip package not found');
      return null;
    }
    if (
      !(dep.info && normalizeName(dep.info.name) === normalizeName(depName))
    ) {
      logger.warn(
        { lookupUrl, lookupName: depName, returnedName: dep.info.name },
        'Returned name does not match with requested name'
      );
      return null;
    }
    if (dep.info && dep.info.home_page) {
      if (dep.info.home_page.startsWith('https://github.com')) {
        dependency.repositoryUrl = dep.info.home_page;
      } else {
        dependency.homepage = dep.info.home_page;
      }
    }
    const manualRepositories = {
      mkdocs: 'https://github.com/mkdocs/mkdocs',
    };
    dependency.repositoryUrl =
      dependency.repositoryUrl || manualRepositories[depName];
    dependency.releases = [];
    if (dep.releases) {
      const versions = Object.keys(dep.releases)
        .filter(isVersion)
        .sort(sortVersions);
      dependency.releases = versions.map(version => ({
        version,
        releaseTimestamp: (dep.releases[version][0] || {}).upload_time,
      }));
    }
    return dependency;
  } catch (err) {
    logger.info('pypi dependency not found: ' + depName);
    return null;
  }
}
<|endoftext|>


<commit_before>var express     = require('express'),
    ejs         = require('ejs'),
    path        = require('path'),
    http        = require('http'),
    bodyParser  = require('body-parser'),
    mongoose    = require('mongoose'),
    nodemailer = require('nodemailer'),
    app         = express();

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));

var port = process.env.PORT || 3000;

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');

app.use(express.static('public'));

require('./app/app.js')(app);

var uristring =
   process.env.MONGOLAB_URI ||
   process.env.MONGOHQ_URL ||
   'mongodb://localhost/';

mongoose.connect(uristring, function(err) {
    if(err) {
        console.log('connection error', err);
    } else {
        app.listen(port);
        console.log("Rebel Mail mailer up on " + port);
        console.log('connection successful');
    }
});
<commit_msg>hreokue changes<commit_after>var express     = require('express'),
    ejs         = require('ejs'),
    path        = require('path'),
    http        = require('http'),
    bodyParser  = require('body-parser'),
    mongoose    = require('mongoose'),
    nodemailer = require('nodemailer'),
    app         = express();

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));

var port = process.env.PORT || 3000;

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');

app.use(express.static('public'));

require('./app/app.js')(app);

var uristring =
   process.env.MONGODB_URI ||
   process.env.PROD_MONGODB ||
   'mongodb://localhost/';

mongoose.connect(uristring, function(err) {
    if(err) {
        console.log('connection error', err);
    } else {
        app.listen(port);
        console.log("Rebel Mail mailer up on " + port);
        console.log('connection successful');
    }
});
<|endoftext|>


<commit_before>var masterTeamList = {
  'A5 18 Bob': false,
  'A5 18 Katie': false,
  'A5 18 Duane': true,
  'A5 17 Jing': true,
  'A5 17 Marc': true,
  'A5 16 Gabe': true,
  'A5 16 Gary': true,
  'A5 16 Matt': true,
  'A5 15 Scoba': true,
  'A5 15 JJ': true,
  'A5 15 Earl': true,
  'A5 15 Erik': true,
  'A5 14 Suzanne': true,
  'A5 14 Karen': true,
  'A5 14 Betty': true,
  'A5 14 LA': true,
  'A5 14 Tory': true,
  'A5 13 PC': true,
  'A5 13 Nikki': true,
  'A5 13 Anna': true,
  'A5 13 Haley': true,
  'A5 13 Tina': true,
  'A5 12 Jing': true,
  'A5 12 Bri': true,
  'A5 12 Keyaira': true,
  'A5 12 Erin': true,
  'A5 12 Sarah': true,
  'A5 12 Denise': true,
  'A5 11 Walter': true,
  'A5 11 Shelley': true,
  'A5 11 Yuri': true,
  'A5 10 Haley': true,
  'A5 10 Jon': true,
  'A5 18 Marc': true,
  'A5 18 Kip': true,
  'A5 16 Erin': true,
  'A5 14 Kip': true,
  'GA5 18 April': true,
  'GA5 18 Marlon': true,
  'GA5 17 Suzanne': true,
  'GA5 17 Alex': true,
  'GA5 16 Kelsey': true,
  'GA5 16 Jessica': true,
  'GA5 16 Christine': true,
  'GA5 15 Mike': true,
  'GA5 15 Jaileen': true,
  'GA5 15 Karen': true,
  'GA5 15 Scott': true,
  'GA5 14 Sandy': true,
  'GA5 14 Kaylin': true,
  'GA5 14 Brianna': true,
  'GA5 13 Alexis': true,
  'GA5 13 Cate': true,
  'GA5 12 Jasmine': true,
  'GA5 11 Susan': true,
  'A5 South 18 Joe': true,
  'Tsunami 18 Kele/Joe': false
};

var aauSession1 = {
  // AAU Session 1
  'A5 183 Duane': { playing: false, rank: 3 },
  'A5 South 18 Joe': { playing: false, rank: 4 },
  'GA5 18 April': { playing: false, rank: 5 },
  'GA5 18 Marlon': { playing: false, rank: 6 },
  'A5 151 SCOBA': { playing: false, rank: 21 },
  'A5 152 JJ': { playing: false, rank: 22 },
  'A5 153 Earl': { playing: false, rank: 23 },
  'A5 South 15 Jason': { playing: false, rank: 25 },
  'A5 South 15 Robert': { playing: false, rank: 26 },
  'GA5 15 Jaileen': { playing: false, rank: 29 },
  'A5 141 Suzanne': { playing: false, rank: 31 },
  'A5 143 Betty': { playing: false, rank: 33 },
  'A5 145 Tory': { playing: false, rank: 35 },
  'A5 South 14 Dave/Joe': { playing: false, rank: 36 },
  'A5 131 PC': { playing: false, rank: 37 },
  'A5 132 Nikki': { playing: false, rank: 38 },
  'A5 133 Hybrid': { playing: false, rank: 39 },
  'A5 135 Tina': { playing: false, rank: 41 },
  'A5 121 Jing': { playing: false, rank: 42 },
  'A5 111 Walter': { playing: false, rank: 43 },
  'A5 101 Haley': { playing: false, rank: 44 },
  // AAU Boys
  'A5 18 Marc': { playing: false, rank: 45 },
  'A5 16 Erin': { playing: false, rank: 46 },
  'A5 14 Kip': { playing: false, rank: 47 }
};

var aauSession2 = {
  // AAU Session 2
  'A5 171 Jing': { playing: true, rank: 7 },
  'A5 172 Marc': { playing: true, rank: 8 },
  'A5 South 17 James': { playing: true, rank: 9 },
  'A5 161 Gabe': { playing: true, rank: 13 },
  'A5 162 Gary': { playing: true, rank: 14 },
  'A5 South 16 Joe': { playing: true, rank: 15 }
};

var aauSession3 = {
  // AAU Session 3
  'A5 181 Bob': { playing: true, rank: 1 },
  'A5 182 Katie': { playing: true, rank: 2 },
  'A5 South 17 Jamie': { playing: true, rank: 10 },
  'GA5 17 Alex': { playing: true, rank: 12 },
  'A5 163 Matt': { playing: true, rank: 13 },
  'A5 South 16 Hannah': { playing: true, rank: 16 },
  'A5 South 16 Derrick': { playing: true, rank: 17 },
  'GA5 16 Kelsey': { playing: true, rank: 18 },
  'GA5 16 Jessica': { playing: true, rank: 19 },
  'GA5 16 Christine': { playing: true, rank: 20 },
  'A5 154 Erik': { playing: true, rank: 24 },
  'A5 South 15 Charlette': { playing: true, rank: 27 },
  'GA5 15 Karen': { playing: true, rank: 30 }
};

// module.exports = Object.assign({}, morningTeamsPlaying, afternoonTeamsPlaying);
module.exports = Object.assign({}, aauSession2, aauSession3);
// module.exports = Object.assign({}, aauSession2);
<commit_msg>Get the team list into one format.<commit_after>var masterTeamList = {
  'A5 18 Bob': { playing: true, rank: 1 },
  'A5 18 Katie': { playing: true, rank: 2 },
  'A5 18 Duane': { playing: true, rank: 3 },
  'A5 17 Jing': { playing: true, rank: 6 },
  'A5 17 Marc': { playing: true, rank: 7 },
  'A5 16 Gabe': { playing: true, rank: 10 },
  'A5 16 Gary': { playing: true, rank: 11 },
  'A5 16 Matt': { playing: true, rank: 12 },
  'A5 15 Scoba': { playing: true, rank: 16 },
  'A5 15 JJ': { playing: true, rank: 17 },
  'A5 15 Earl': { playing: true, rank: 18 },
  'A5 15 Erik': { playing: true, rank: 19 },
  'A5 14 Suzanne': { playing: true, rank: 23 },
  'A5 14 Karen': { playing: true, rank: 24 },
  'A5 14 Betty': { playing: true, rank: 25 },
  'A5 14 LA': { playing: true, rank: 26 },
  'A5 14 Tory': { playing: true, rank: 27 },
  'A5 13 PC': { playing: true, rank: 31 },
  'A5 13 Nikki': { playing: true, rank: 32 },
  'A5 13 Anna': { playing: true, rank: 33 },
  'A5 13 Haley': { playing: true, rank: 34 },
  'A5 13 Tina': { playing: true, rank: 35 },
  'A5 12 Jing': { playing: true, rank: 38 },
  'A5 12 Bri': { playing: true, rank: 39 },
  'A5 12 Keyaira': { playing: true, rank: 40 },
  'A5 12 Erin': { playing: true, rank: 41 },
  'A5 12 Sarah': { playing: true, rank: 42 },
  'A5 12 Denise': { playing: true, rank: 43 },
  'A5 11 Walter': { playing: true, rank: 45 },
  'A5 11 Shelley': { playing: true, rank: 46 },
  'A5 11 Yuri': { playing: true, rank: 47 },
  'A5 10 Haley': { playing: true, rank: 49 },
  'A5 10 Jon': { playing: true, rank: 50 },
  'A5 18 Marc': { playing: true, rank: 51 },
  'A5 18 Kip': { playing: true, rank: 52 },
  'A5 16 Erin': { playing: true, rank: 53 },
  'A5 14 Kip': { playing: true, rank: 54 },
  'GA5 18 April': { playing: true, rank: 4 },
  'GA5 18 Marlon': { playing: true, rank: 5 },
  'GA5 17 Suzanne': { playing: true, rank: 8 },
  'GA5 17 Alex': { playing: true, rank: 9 },
  'GA5 16 Kelsey': { playing: true, rank: 13 },
  'GA5 16 Jessica': { playing: true, rank: 14 },
  'GA5 16 Christine': { playing: true, rank: 15 },
  'GA5 15 Jaileen': { playing: true, rank: 20 },
  'GA5 15 Karen': { playing: true, rank: 21 },
  'GA5 15 Scott': { playing: true, rank: 22 },
  'GA5 14 Sandy': { playing: true, rank: 28 },
  'GA5 14 Kaylin': { playing: true, rank: 29 },
  'GA5 14 Brianna': { playing: true, rank: 30 },
  'GA5 13 Alexis': { playing: true, rank: 36 },
  'GA5 13 Cate': { playing: true, rank: 37 },
  'GA5 12 Jasmine': { playing: true, rank: 44 },
  'GA5 11 Susan': { playing: true, rank: 48 }
};

var aauSession1 = {
  // AAU Session 1
  'A5 183 Duane': { playing: false, rank: 3 },
  'A5 South 18 Joe': { playing: false, rank: 4 },
  'GA5 18 April': { playing: false, rank: 5 },
  'GA5 18 Marlon': { playing: false, rank: 6 },
  'A5 151 SCOBA': { playing: false, rank: 21 },
  'A5 152 JJ': { playing: false, rank: 22 },
  'A5 153 Earl': { playing: false, rank: 23 },
  'A5 South 15 Jason': { playing: false, rank: 25 },
  'A5 South 15 Robert': { playing: false, rank: 26 },
  'GA5 15 Jaileen': { playing: false, rank: 29 },
  'A5 141 Suzanne': { playing: false, rank: 31 },
  'A5 143 Betty': { playing: false, rank: 33 },
  'A5 145 Tory': { playing: false, rank: 35 },
  'A5 South 14 Dave/Joe': { playing: false, rank: 36 },
  'A5 131 PC': { playing: false, rank: 37 },
  'A5 132 Nikki': { playing: false, rank: 38 },
  'A5 133 Hybrid': { playing: false, rank: 39 },
  'A5 135 Tina': { playing: false, rank: 41 },
  'A5 121 Jing': { playing: false, rank: 42 },
  'A5 111 Walter': { playing: false, rank: 43 },
  'A5 101 Haley': { playing: false, rank: 44 },
  // AAU Boys
  'A5 18 Marc': { playing: false, rank: 45 },
  'A5 16 Erin': { playing: false, rank: 46 },
  'A5 14 Kip': { playing: false, rank: 47 }
};

var aauSession2 = {
  // AAU Session 2
  'A5 171 Jing': { playing: true, rank: 7 },
  'A5 172 Marc': { playing: true, rank: 8 },
  'A5 South 17 James': { playing: true, rank: 9 },
  'A5 161 Gabe': { playing: true, rank: 13 },
  'A5 162 Gary': { playing: true, rank: 14 },
  'A5 South 16 Joe': { playing: true, rank: 15 }
};

var aauSession3 = {
  // AAU Session 3
  'A5 181 Bob': { playing: true, rank: 1 },
  'A5 182 Katie': { playing: true, rank: 2 },
  'A5 South 17 Jamie': { playing: true, rank: 10 },
  'GA5 17 Alex': { playing: true, rank: 12 },
  'A5 163 Matt': { playing: true, rank: 13 },
  'A5 South 16 Hannah': { playing: true, rank: 16 },
  'A5 South 16 Derrick': { playing: true, rank: 17 },
  'GA5 16 Kelsey': { playing: true, rank: 18 },
  'GA5 16 Jessica': { playing: true, rank: 19 },
  'GA5 16 Christine': { playing: true, rank: 20 },
  'A5 154 Erik': { playing: true, rank: 24 },
  'A5 South 15 Charlette': { playing: true, rank: 27 },
  'GA5 15 Karen': { playing: true, rank: 30 }
};

// module.exports = Object.assign({}, morningTeamsPlaying, afternoonTeamsPlaying);
module.exports = Object.assign({}, aauSession2, aauSession3);
// module.exports = Object.assign({}, aauSession2);
<|endoftext|>


<commit_before>var gulp = require('gulp');
var _ = require('lodash');
var path = require('path');
var mkdirp = require('mkdirp');
var Rsync = require('rsync');
var Promise = require('bluebird');
var eslint = require('gulp-eslint');
var rimraf = require('rimraf');
var zip = require('gulp-zip');
var fs = require('fs');
var spawn = require('child_process').spawn;
var minimist = require('minimist');
var util = require('gulp-util');

var pkg = require('./package.json');
var packageName = pkg.name;

// in their own sub-directory to not interfere with Gradle
var buildDir = path.resolve(__dirname, 'build/gulp');
var targetDir = path.resolve(__dirname, 'target/gulp');
var buildTarget = path.resolve(buildDir, 'kibana', packageName);
var pathToPkgConfig = './package.json';

var include = [
  '*.json',
  'LICENSE',
  'README.md',
  'index.js',
  'init.js',
  'server',
  'lib',
  'public',
  'phantomjs'
];

var knownOptions = {
  string: 'kibanahomepath',
  string: 'version',
  default: { kibanahomepath: '../kibi-internal' }
};
var options = minimist(process.argv.slice(2), knownOptions);
var kibanaPluginDir = path.resolve(__dirname, options.kibanahomepath + '/plugins/' + packageName);

function syncPluginTo(dest, done) {
  mkdirp(dest, function (err) {
    if (err) return done(err);
    Promise.all(include.map(function (name) {
      var source = path.resolve(__dirname, name);
      return new Promise(function (resolve, reject) {
        var rsync = new Rsync();
        rsync
          .source(source)
          .destination(dest)
          .flags('uav')
          .recursive(true)
          .set('delete')
          .output(function (data) {
            process.stdout.write(data.toString('utf8'));
          });
        rsync.execute(function (err) {
          if (err) {
            console.log(err);
            return reject(err);
          }
          resolve();
        });
      });
    })).then(function () {
      return new Promise(function (resolve, reject) {
        mkdirp(path.join(buildTarget, 'node_modules'), function (err) {
          if (err) return reject(err);
          resolve();
        });
      });
    }).then(function () {
      spawn('npm', ['install', '--production'], {
        cwd: dest,
        stdio: 'inherit'
      });
    }).then(function () {
      spawn('npm', ['install', 'https://@github.com:sirensolutions/gun-master.git'], {
        cwd: dest,
        stdio: 'inherit'
      }).on('close', done);
    }).catch(done);
  });
}

function applyVersion(path, version) {
  var pkgConfig = JSON.parse(fs.readFileSync(path, 'utf8'));
  pkgConfig.kibana.version = version;
  fs.writeFileSync(path, JSON.stringify(pkgConfig, null, 2), 'utf8');
}

gulp.task('sync', function (done) {
  syncPluginTo(kibanaPluginDir, done);
});

gulp.task('lint', function (done) {
  return gulp.src([
    'index.js',
    'init.js',
    'public/**/*.js',
    'server/**/*.js',
    '!**/webpackShims/**'
  ]).pipe(eslint()).pipe(eslint.formatEach()).pipe(eslint.failOnError());
});

gulp.task('clean', function (done) {
  Promise.each([buildDir, targetDir], function (dir) {
    return new Promise(function (resolve, reject) {
      rimraf(dir, function (err) {
        if (err) return reject(err);
        resolve();
      });
    });
  }).nodeify(done);
});

gulp.task('build', ['clean'], function (done) {
  if (options.version) {
    applyVersion(pathToPkgConfig, options.version);
  }
  syncPluginTo(buildTarget, done);
});

gulp.task('package', ['build'], function (done) {
  return gulp.src([
    path.join(buildDir, '**', '*')
  ])
    .pipe(zip(options.version ? packageName + '-v' + options.version  + '.zip' : packageName + '.zip'))
    .pipe(gulp.dest(targetDir));
});

gulp.task('dev', ['sync'], function (done) {
  gulp.watch([
    'index.js',
    'init.js',
    '*.json',
    'public/**/*',
    'server/**/*'
  ], ['sync', 'lint']);
});

gulp.task('test', ['sync'], function (done) {
  spawn('grunt', ['test:server', 'test:browser', '--grep=' + (util.env.grep ? util.env.grep : 'Sentinl')], {
    cwd: options.kibanahomepath,
    stdio: 'inherit'
  }).on('error', (err) => {
    throw err;
  }).on('close', done);
});

gulp.task('testserver', ['sync'], function (done) {
  spawn('grunt', ['test:server', '--grep=' + (util.env.grep ? util.env.grep : 'Sentinl')], {
    cwd: options.kibanahomepath,
    stdio: 'inherit'
  }).on('error', (err) => {
    throw err;
  }).on('close', done);
});

gulp.task('testbrowser', ['sync'], function (done) {
  spawn('grunt', ['test:browser', '--grep=' + (util.env.grep ? util.env.grep : 'Sentinl')], {
    cwd: options.kibanahomepath,
    stdio: 'inherit'
  }).on('error', (err) => {
    throw err;
  }).on('close', done);
});

gulp.task('testdev', ['sync'], function (done) {
  spawn('grunt', ['test:dev', '--browser=Chrome'], {
    cwd: options.kibanahomepath,
    stdio: 'inherit'
  }).on('error', (err) => {
    throw err;
  }).on('close', done);
});

gulp.task('coverage', ['sync'], function (done) {
  spawn('grunt', ['test:coverage', '--grep=Sentinl'], {
    cwd: options.kibanahomepath,
    stdio: 'inherit'
  }).on('error', (err) => {
    throw err;
  }).on('close', done);
});
<commit_msg>Make npm automatically detect a protocol to use to install gun-master lib.<commit_after>var gulp = require('gulp');
var _ = require('lodash');
var path = require('path');
var mkdirp = require('mkdirp');
var Rsync = require('rsync');
var Promise = require('bluebird');
var eslint = require('gulp-eslint');
var rimraf = require('rimraf');
var zip = require('gulp-zip');
var fs = require('fs');
var spawn = require('child_process').spawn;
var minimist = require('minimist');
var util = require('gulp-util');

var pkg = require('./package.json');
var packageName = pkg.name;

// in their own sub-directory to not interfere with Gradle
var buildDir = path.resolve(__dirname, 'build/gulp');
var targetDir = path.resolve(__dirname, 'target/gulp');
var buildTarget = path.resolve(buildDir, 'kibana', packageName);
var pathToPkgConfig = './package.json';

var include = [
  '*.json',
  'LICENSE',
  'README.md',
  'index.js',
  'init.js',
  'server',
  'lib',
  'public',
  'phantomjs'
];

var knownOptions = {
  string: 'kibanahomepath',
  string: 'version',
  default: { kibanahomepath: '../kibi-internal' }
};
var options = minimist(process.argv.slice(2), knownOptions);
var kibanaPluginDir = path.resolve(__dirname, options.kibanahomepath + '/plugins/' + packageName);

function syncPluginTo(dest, done) {
  mkdirp(dest, function (err) {
    if (err) return done(err);
    Promise.all(include.map(function (name) {
      var source = path.resolve(__dirname, name);
      return new Promise(function (resolve, reject) {
        var rsync = new Rsync();
        rsync
          .source(source)
          .destination(dest)
          .flags('uav')
          .recursive(true)
          .set('delete')
          .output(function (data) {
            process.stdout.write(data.toString('utf8'));
          });
        rsync.execute(function (err) {
          if (err) {
            console.log(err);
            return reject(err);
          }
          resolve();
        });
      });
    })).then(function () {
      return new Promise(function (resolve, reject) {
        mkdirp(path.join(buildTarget, 'node_modules'), function (err) {
          if (err) return reject(err);
          resolve();
        });
      });
    }).then(function () {
      spawn('npm', ['install', '--production'], {
        cwd: dest,
        stdio: 'inherit'
      });
    }).then(function () {
      spawn('npm', ['install', 'sirensolutions/gun-master.git'], {
        cwd: dest,
        stdio: 'inherit'
      }).on('close', done);
    }).catch(done);
  });
}

function applyVersion(path, version) {
  var pkgConfig = JSON.parse(fs.readFileSync(path, 'utf8'));
  pkgConfig.kibana.version = version;
  fs.writeFileSync(path, JSON.stringify(pkgConfig, null, 2), 'utf8');
}

gulp.task('sync', function (done) {
  syncPluginTo(kibanaPluginDir, done);
});

gulp.task('lint', function (done) {
  return gulp.src([
    'index.js',
    'init.js',
    'public/**/*.js',
    'server/**/*.js',
    '!**/webpackShims/**'
  ]).pipe(eslint()).pipe(eslint.formatEach()).pipe(eslint.failOnError());
});

gulp.task('clean', function (done) {
  Promise.each([buildDir, targetDir], function (dir) {
    return new Promise(function (resolve, reject) {
      rimraf(dir, function (err) {
        if (err) return reject(err);
        resolve();
      });
    });
  }).nodeify(done);
});

gulp.task('build', ['clean'], function (done) {
  if (options.version) {
    applyVersion(pathToPkgConfig, options.version);
  }
  syncPluginTo(buildTarget, done);
});

gulp.task('package', ['build'], function (done) {
  return gulp.src([
    path.join(buildDir, '**', '*')
  ])
    .pipe(zip(options.version ? packageName + '-v' + options.version  + '.zip' : packageName + '.zip'))
    .pipe(gulp.dest(targetDir));
});

gulp.task('dev', ['sync'], function (done) {
  gulp.watch([
    'index.js',
    'init.js',
    '*.json',
    'public/**/*',
    'server/**/*'
  ], ['sync', 'lint']);
});

gulp.task('test', ['sync'], function (done) {
  spawn('grunt', ['test:server', 'test:browser', '--grep=' + (util.env.grep ? util.env.grep : 'Sentinl')], {
    cwd: options.kibanahomepath,
    stdio: 'inherit'
  }).on('error', (err) => {
    throw err;
  }).on('close', done);
});

gulp.task('testserver', ['sync'], function (done) {
  spawn('grunt', ['test:server', '--grep=' + (util.env.grep ? util.env.grep : 'Sentinl')], {
    cwd: options.kibanahomepath,
    stdio: 'inherit'
  }).on('error', (err) => {
    throw err;
  }).on('close', done);
});

gulp.task('testbrowser', ['sync'], function (done) {
  spawn('grunt', ['test:browser', '--grep=' + (util.env.grep ? util.env.grep : 'Sentinl')], {
    cwd: options.kibanahomepath,
    stdio: 'inherit'
  }).on('error', (err) => {
    throw err;
  }).on('close', done);
});

gulp.task('testdev', ['sync'], function (done) {
  spawn('grunt', ['test:dev', '--browser=Chrome'], {
    cwd: options.kibanahomepath,
    stdio: 'inherit'
  }).on('error', (err) => {
    throw err;
  }).on('close', done);
});

gulp.task('coverage', ['sync'], function (done) {
  spawn('grunt', ['test:coverage', '--grep=Sentinl'], {
    cwd: options.kibanahomepath,
    stdio: 'inherit'
  }).on('error', (err) => {
    throw err;
  }).on('close', done);
});
<|endoftext|>


<commit_before>
var fs = require('fs');
var defaultConfigFile = './config/application-defaults.json'
var configFile = './config/application.json'
var configurationFile = fs.existsSync(configFile) ? configFile : defaultConfigFile;
var configuration = JSON.parse(fs.readFileSync(configurationFile));

var Token = require('./app/models/Token');
var TokenActions = require('./app/actions/TokenActions')(Token);
var createTokenValidator = require('./app/createTokenValidator');
var TokensApi = require('./app/TokensApi');
var mongoose = require('mongoose');
var logger = require('morgan');

var router = require('./app/router');
var swaggerMiddleware = require('./app/swaggerMiddleware')({ overrides: __dirname + '/swagger-ui/' });

var authenticator = require('./app/authenticator')({
	url: configuration.cirrus.url,
	request: require('request')
});

var tokensApi = new TokensApi({tokenActions: TokenActions});

module.exports = {
	tokensApi: tokensApi,
	authenticator: authenticator,
	createTokenValidator: createTokenValidator,
	mongoose: mongoose,
	configFile: require(configurationFile),
	router: router,
	swaggerMiddleware: swaggerMiddleware,
	logger: logger
};
<commit_msg>export config attributes to fetch config parameters when starting the webserver<commit_after>
var fs = require('fs');
var defaultConfigFile = './config/application-defaults.json'
var configFile = './config/application.json'
var configurationFile = fs.existsSync(configFile) ? configFile : defaultConfigFile;
var configuration = JSON.parse(fs.readFileSync(configurationFile));

var Token = require('./app/models/Token');
var TokenActions = require('./app/actions/TokenActions')(Token);
var createTokenValidator = require('./app/createTokenValidator');
var TokensApi = require('./app/TokensApi');
var mongoose = require('mongoose');
var logger = require('morgan');

var router = require('./app/router');
var swaggerMiddleware = require('./app/swaggerMiddleware')({ overrides: __dirname + '/swagger-ui/' });

var authenticator = require('./app/authenticator')({
	url: configuration.cirrus.url,
	request: require('request')
});

var tokensApi = new TokensApi({tokenActions: TokenActions});

module.exports = {
	tokensApi: tokensApi,
	authenticator: authenticator,
	createTokenValidator: createTokenValidator,
	mongoose: mongoose,
	configFile: require(configurationFile),
	router: router,
	swaggerMiddleware: swaggerMiddleware,
	logger: logger,
	configuration: configuration
};
<|endoftext|>


<commit_before>'use strict';

/*
 * Module dependencies.
 */
var _ = require('lodash'),
	mongoose = require('mongoose'),
	Schema = mongoose.Schema,
	serverJSON = require('../../../../local_files/ui/server.ui.json'),
	Helper = require('../../../../custom_objects/Helper'),
	async = require('async'),
	ValidationError = require('mongoose/lib/error/validation'),
	ValidatorError =  require('mongoose/lib/error/validator');

var validateNameProperty = function(property)
{
	var regEx = new RegExp(/^[\d\w\-\s]{5,30}$/);
	console.log('property: ' + property);
	return regEx.test(property);
};

/**
 * Event Schema
 */
var EventSchema = new Schema({
	name: {
		type: String,
		required: 'name.empty',
		//match: [new RegExp(serverJSON.api.events.name.invalid.regex), 'name.invalid'],
		//validate: [validateNameProperty, serverJSON.api.events.errors._2],
		trim: true
	},
	created: {
		type: Date,
		default: Date.now
	},
	location:{
		//type: Object,
		//required: 'Please fill location name',
		name: {
			type: String,
			default: '',
			trim: true
		},
		address: {
			type: String,
			required: 'location.address.empty',
			//match: [new RegExp(serverJSON.api.events.location.address.invalid.regex), 'location.address.invalid'],
			trim: true
		},
		lat: {
			type: Number,
			//required: serverJSON.api.events.errors._3,
			default: -1
		},
		lng: {
			type: Number,
			//required: serverJSON.api.events.errors._4,
			default: -1
		}
	},
	date:{
		type: Date,
		required: 'date.empty',
		//match: [new RegExp(serverJSON.api.events.date.invalid.regex), 'date.invalid'],
	},
	time:{
		type: Date,
		required: 'time.empty',
		//match: [new RegExp(serverJSON.api.events.time.invalid.regex), 'time.invalid'],
	},
	voteEnabled:{
		type:Boolean,
		default:true
	},
	minimumVotes:{
		type:Number,
		required: 'minimumVotes.empty'
	},
	votes:
	{
		yes:
		{
			type: [Schema.ObjectId],
			ref: 'User',
			validate:
			[
				{
					validator: Helper.isValidObjectIDs,
					msg: 'votes.yes.invalid'
				},
				{
					validator: Helper.isUniqueArray,
					msg: 'votes.yes.duplicate'
				}
			]
		},
		no:
		{
			type: [Schema.ObjectId],
			ref: 'User',
			validate:
			[
				{
					validator: Helper.isValidObjectIDs,
					msg: 'votes.no.invalid'
				},
				{
					validator: Helper.isUniqueArray,
					msg: 'votes.no.duplicate'
				}
			]
		},
	},

	message:{
		type: String,
		required: 'message.empty'
	},
	group: {
		type: Schema.ObjectId,
		ref: 'Group',
		//required: serverJSON.api.events.group.empty,
		validate:
		[
			{
				validator: Helper.isValidObjectID,
				msg: 'group.invalid'
			}
		]
	},
	user: {
		type: Schema.ObjectId,
		ref: 'User'
	}
});

EventSchema.statics.functionsArray = [

];

EventSchema.statics.objectIDAtts = [
	{
		name: 'user',
		model: 'User'
	},
	{
		name: 'group',
		model: 'Group'
	},
	{
		name: 'votes.yes',
		model: 'User'
	},
	{
		name: 'votes.no',
		model: 'User'
	}
];

EventSchema.statics.title = serverJSON.constants.events;
EventSchema.statics.errPath = 'api.events';
EventSchema.statics.attsToShow = ['_id', 'name', 'location', 'date', 'time', 'voteEnabled', 'minimumVotes', 'votes', 'message'];

/*********** Validate Functions **************/
EventSchema.path('group').validate(function (id,respond) {

	var Group = mongoose.model('Group');
	var query = {
		_id : id
	};

	console.log('validate group: ' + id);

	Helper.find(Group,query,function(err,mod) {

		if(err || !mod)
			respond(false);
		else
			respond(true);
	});

},'group.exist');

EventSchema.path('votes.yes').validate(function (ids,respond) {

	if(ids.length === 0)
		respond(true);

	var User = mongoose.model('User');
	var query = {
    	_id:
    	{
    		$in: ids
    	}
    };

	console.log('validate votes "yes"' + ids);

	Helper.find(User,query,function(err,mods) {

		if(err || !mods || ids.length !== mods.length)
			respond(false);
		else
			respond(true);
	});

},'votes.yes.exist');

EventSchema.path('votes.no').validate(function (ids,respond) {

	if(ids.length === 0)
		respond(true);

	var User = mongoose.model('User');
	var query = {
    	_id:
    	{
    		$in: ids
    	}
    };

	console.log('validate votes "no"' + ids);

	Helper.find(User,query,function(err,mods) {

		if(err || !mods || ids.length !== mods.length)
			respond(false);
		else
			respond(true);
	});

},'votes.no.exist');

/*********** END Validate Functions **************/

/*********** PRE Functions ***********/
EventSchema.pre('save', function (next) {

	console.log('event pre save: ' + this);

	var yesArr = [];
	var noArr = [];
	var i = null;

	for(i = 0; i < this.votes.yes.length; ++i)
		yesArr.push(this.votes.yes[i].toString());

	for(i = 0; i < this.votes.no.length; ++i)
		noArr.push(this.votes.no[i].toString());

	console.log('yesArr: ' + yesArr);
	console.log('noArr: ' + noArr);

	var intersection = _.intersection(yesArr,noArr);

	console.log('intersection: ' + intersection);
	if(intersection.length)
	{
		var err = new ValidationError(this);
		err.errors.votes = new ValidatorError('votes.yes', 'votes.yes.duplicate', 'notunique', '');

	  	console.log(err);

	  	next(err);
	 }
	 else
	 	next();
});

/*********** END PRE Functions ***********/

mongoose.model('Event', EventSchema);
<commit_msg>showing group attribute for events<commit_after>'use strict';

/*
 * Module dependencies.
 */
var _ = require('lodash'),
	mongoose = require('mongoose'),
	Schema = mongoose.Schema,
	serverJSON = require('../../../../local_files/ui/server.ui.json'),
	Helper = require('../../../../custom_objects/Helper'),
	async = require('async'),
	ValidationError = require('mongoose/lib/error/validation'),
	ValidatorError =  require('mongoose/lib/error/validator');

var validateNameProperty = function(property)
{
	var regEx = new RegExp(/^[\d\w\-\s]{5,30}$/);
	console.log('property: ' + property);
	return regEx.test(property);
};

/**
 * Event Schema
 */
var EventSchema = new Schema({
	name: {
		type: String,
		required: 'name.empty',
		//match: [new RegExp(serverJSON.api.events.name.invalid.regex), 'name.invalid'],
		//validate: [validateNameProperty, serverJSON.api.events.errors._2],
		trim: true
	},
	created: {
		type: Date,
		default: Date.now
	},
	location:{
		//type: Object,
		//required: 'Please fill location name',
		name: {
			type: String,
			default: '',
			trim: true
		},
		address: {
			type: String,
			required: 'location.address.empty',
			//match: [new RegExp(serverJSON.api.events.location.address.invalid.regex), 'location.address.invalid'],
			trim: true
		},
		lat: {
			type: Number,
			//required: serverJSON.api.events.errors._3,
			default: -1
		},
		lng: {
			type: Number,
			//required: serverJSON.api.events.errors._4,
			default: -1
		}
	},
	date:{
		type: Date,
		required: 'date.empty',
		//match: [new RegExp(serverJSON.api.events.date.invalid.regex), 'date.invalid'],
	},
	time:{
		type: Date,
		required: 'time.empty',
		//match: [new RegExp(serverJSON.api.events.time.invalid.regex), 'time.invalid'],
	},
	voteEnabled:{
		type:Boolean,
		default:true
	},
	minimumVotes:{
		type:Number,
		required: 'minimumVotes.empty'
	},
	votes:
	{
		yes:
		{
			type: [Schema.ObjectId],
			ref: 'User',
			validate:
			[
				{
					validator: Helper.isValidObjectIDs,
					msg: 'votes.yes.invalid'
				},
				{
					validator: Helper.isUniqueArray,
					msg: 'votes.yes.duplicate'
				}
			]
		},
		no:
		{
			type: [Schema.ObjectId],
			ref: 'User',
			validate:
			[
				{
					validator: Helper.isValidObjectIDs,
					msg: 'votes.no.invalid'
				},
				{
					validator: Helper.isUniqueArray,
					msg: 'votes.no.duplicate'
				}
			]
		},
	},

	message:{
		type: String,
		required: 'message.empty'
	},
	group: {
		type: Schema.ObjectId,
		ref: 'Group',
		//required: serverJSON.api.events.group.empty,
		validate:
		[
			{
				validator: Helper.isValidObjectID,
				msg: 'group.invalid'
			}
		]
	},
	user: {
		type: Schema.ObjectId,
		ref: 'User'
	}
});

EventSchema.statics.functionsArray = [

];

EventSchema.statics.objectIDAtts = [
	{
		name: 'user',
		model: 'User'
	},
	{
		name: 'group',
		model: 'Group'
	},
	{
		name: 'votes.yes',
		model: 'User'
	},
	{
		name: 'votes.no',
		model: 'User'
	}
];

EventSchema.statics.title = serverJSON.constants.events;
EventSchema.statics.errPath = 'api.events';
EventSchema.statics.attsToShow = ['_id', 'name', 'location', 'date', 'time', 'voteEnabled', 'minimumVotes', 'votes', 'message', 'group'];

/*********** Validate Functions **************/
EventSchema.path('group').validate(function (id,respond) {

	var Group = mongoose.model('Group');
	var query = {
		_id : id
	};

	console.log('validate group: ' + id);

	Helper.find(Group,query,function(err,mod) {

		if(err || !mod)
			respond(false);
		else
			respond(true);
	});

},'group.exist');

EventSchema.path('votes.yes').validate(function (ids,respond) {

	if(ids.length === 0)
		respond(true);

	var User = mongoose.model('User');
	var query = {
    	_id:
    	{
    		$in: ids
    	}
    };

	console.log('validate votes "yes"' + ids);

	Helper.find(User,query,function(err,mods) {

		if(err || !mods || ids.length !== mods.length)
			respond(false);
		else
			respond(true);
	});

},'votes.yes.exist');

EventSchema.path('votes.no').validate(function (ids,respond) {

	if(ids.length === 0)
		respond(true);

	var User = mongoose.model('User');
	var query = {
    	_id:
    	{
    		$in: ids
    	}
    };

	console.log('validate votes "no"' + ids);

	Helper.find(User,query,function(err,mods) {

		if(err || !mods || ids.length !== mods.length)
			respond(false);
		else
			respond(true);
	});

},'votes.no.exist');

/*********** END Validate Functions **************/

/*********** PRE Functions ***********/
EventSchema.pre('save', function (next) {

	console.log('event pre save: ' + this);

	var yesArr = [];
	var noArr = [];
	var i = null;

	for(i = 0; i < this.votes.yes.length; ++i)
		yesArr.push(this.votes.yes[i].toString());

	for(i = 0; i < this.votes.no.length; ++i)
		noArr.push(this.votes.no[i].toString());

	console.log('yesArr: ' + yesArr);
	console.log('noArr: ' + noArr);

	var intersection = _.intersection(yesArr,noArr);

	console.log('intersection: ' + intersection);
	if(intersection.length)
	{
		var err = new ValidationError(this);
		err.errors.votes = new ValidatorError('votes.yes', 'votes.yes.duplicate', 'notunique', '');

	  	console.log(err);

	  	next(err);
	 }
	 else
	 	next();
});

/*********** END PRE Functions ***********/

mongoose.model('Event', EventSchema);
<|endoftext|>


<commit_before>/*jslint node: true*/
"use strict";

var webid = require('webid');
var debug = require('./logging').login;

function loginHandler(req, res, next) {
    var ldp = req.app.locals.ldp;
    if (!ldp.webid) {
        setEmptySession(req);
        return next();
    }
    if (req.session.userId && req.session.identified) {
        debug("User: " + req.session.userId);
        res.set('User', req.session.userId);
        return next();
    } else {
        var certificate = req.connection.getPeerCertificate();
        if (!(certificate === null || Object.keys(certificate).length === 0))  {
            var verifAgent = new webid.VerificationAgent(certificate);
            verifAgent.verify(function(err, result) {
                if (err) {
                    var message;
                    switch (err) {
                    case 'certificateProvidedSAN':
                        message = 'No valide Certificate Alternative Name in your certificate';
                        break;
                    case 'profileWellFormed':
                        message = 'Can\'t load your foaf file (RDF may not be valid)';
                        break;
                    case 'falseWebID':
                        message = 'Your certificate public key is not the one of the FOAF file';
                        break;
                    case 'profileAllKeysWellFormed':
                        message = "Missformed WebID";
                        break;
                    default:
                        message = "Unknown WebID error";
                        break;
                    }
                    debug("Error processing certificate: " + message);
                    setEmptySession(req);
                    return res.status(403).send(message);
                } else {
                    req.session.userId = result;
                    req.session.identified = true;
                    debug("Identified user: " + req.session.userId);
                    res.set('User', req.session.userId);
                    return next();
                }
            });
        } else {
            debug("Empty certificate");
            setEmptySession(req);
            next();
        }
    }

    function setEmptySession(req) {
        req.session.userId = "";
        req.session.identified = false;
    }
}

exports.loginHandler = loginHandler;
<commit_msg>Improved error message for keys that don't match in WebID-TLS<commit_after>/*jslint node: true*/
"use strict";

var webid = require('webid');
var debug = require('./logging').login;

function loginHandler(req, res, next) {
    var ldp = req.app.locals.ldp;
    if (!ldp.webid) {
        setEmptySession(req);
        return next();
    }
    if (req.session.userId && req.session.identified) {
        debug("User: " + req.session.userId);
        res.set('User', req.session.userId);
        return next();
    } else {
        var certificate = req.connection.getPeerCertificate();
        if (!(certificate === null || Object.keys(certificate).length === 0))  {
            var verifAgent = new webid.VerificationAgent(certificate);
            verifAgent.verify(function(err, result) {
                if (err) {
                    var message;
                    switch (err) {
                    case 'certificateProvidedSAN':
                        message = 'No valide Certificate Alternative Name in your certificate';
                        break;
                    case 'profileWellFormed':
                        message = 'Can\'t load your foaf file (RDF may not be valid)';
                        break;
                    case 'falseWebID':
                        message = 'Your certificate public key is not the one of the FOAF file';
                        break;
                    case 'profileAllKeysWellFormed':
                        message = "Certificate public key does not match the one found in the WebID profile.";
                        break;
                    default:
                        message = "Unknown WebID error";
                        break;
                    }
                    debug("Error processing certificate: " + message);
                    setEmptySession(req);
                    return res.status(403).send(message);
                } else {
                    req.session.userId = result;
                    req.session.identified = true;
                    debug("Identified user: " + req.session.userId);
                    res.set('User', req.session.userId);
                    return next();
                }
            });
        } else {
            debug("Empty certificate");
            setEmptySession(req);
            next();
        }
    }

    function setEmptySession(req) {
        req.session.userId = "";
        req.session.identified = false;
    }
}

exports.loginHandler = loginHandler;
<|endoftext|>


<commit_before>/**
 * Copyright 2014 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

var conn = require('../common/connection.js'),
    entity = require('./entity.js'),
    Query = require('./query.js').Query,
    util = require('../common/util.js');

var DATASTORE_BASE_URL = 'https://www.googleapis.com/datastore/v1beta2/datasets',
    SCOPES = [
      'https://www.googleapis.com/auth/datastore',
      'https://www.googleapis.com/auth/userinfo.email'],
    MODE_NON_TRANSACTIONAL = 'NON_TRANSACTIONAL',
    MODE_TRANSACTIONAL = 'TRANSACTIONAL';

/**
 * Transaction represents a Datastore transaction.
 */
function Transaction(conn, datasetId) {
  this.conn = conn;
  this.datasetId = datasetId;
  // the default transaction has no id.
  // if id is not set, run operations non-transactional.
  this.id = null;
  this.isFinalized = false;
}

/**
 * Begins starts a remote transaction and identifies the current
 * transaction instance with the remote transaction's ID.
 */
Transaction.prototype.begin = function(callback) {
  var that = this;
  this.makeReq('beginTransaction', null, function(err, resp) {
    if (!err) {
      that.id = resp;
    }
    callback && callback(err);
  });
};

/**
 * Rollback rollsback a transaction remotely and finalizes
 * the current transaction instance.
 */
Transaction.prototype.rollback = function(callback) {
  var that = this;
  var req = { transaction: this.id };
  this.makeReq('rollback', req, function(err, resp) {
    if (!err) {
      that.isFinalized = true;
    }
    callback && callback(err);
  });
};

/**
 * Commit commits the remote transaction and finalizes the
 * current transaction insance.
 */
Transaction.prototype.commit = function(callback) {
  var that = this;
  var req = { transaction: this.id };
  this.makeReq('commit', req, function(err, resp) {
    if (!err) {
      that.isFinalized = true;
    }
    callback && callback(err);
  });
};

/**
 * Finalize commits a transction if it's not finalized yet.
 */
Transaction.prototype.finalize = function(callback) {
  if (!this.isFinalized) {
    return this.commit(callback);
  }
  callback();
};

/**
 * Get retrieves the objects identified with the specified key in the
 * current transaction.
 * @param  {Array}    key
 * @param  {Function} callback
 */
Transaction.prototype.get = function(key, callback) {
  this.getAll([key], function(err, keys, objs) {
    if (err || objs.length < 0) {
      return callback(err);
    }
    return callback(null, keys[0], objs[0]);
  });
};

/**
 * Gets all objects identified with the specified list of keys
 * in the current transaction.
 * @param  {Array<Array>}   keys
 * @param  {Function}       callback
 */
Transaction.prototype.getAll = function(keys, callback) {
  keysProto = [];
  keys.forEach(function(k) {
    keysProto.push(entity.keyToKeyProto(this.id, k));
  });
  var req = { keys: keysProto };
  if (this.id) {
    req.transaction = this.id;
  }
  this.makeReq(
      'lookup', req, function(err, resp) {
    if (err) {
      return callback(err);
    }
    var results = [], keys = [];
    resp.found.forEach(function(f) {
      keys.push(entity.keyFromKeyProto(f.entity.key));
      results.push(entity.entityFromEntityProto(f.entity));
    });
    callback && callback(null, keys, results);
  });
};

/**
 * Inserts or updates the specified the object in the current
 * transaction. If the provided key is incomplete, inserts the object
 * and returns the generated identifier.
 * @param  {Array}    key
 * @param  {Object}   obj
 * @param  {Function} callback
 */
Transaction.prototype.save = function(key, obj, callback) {
  this.saveAll([key], [obj], function(err, keys) {
    if (err || !keys) {
      return callback(err);
    }
    if (keys[0]) {
      return callback(err, keys[0]);
    }
    callback();
  });
};

/**
 * Inserts or upates the specified objects in the current transaction.
 * If a key is incomplete, its associated object is inserted and
 * generated identifier is returned.
 * @param  {Array<Array>}   keys
 * @param  {Array<Object>}  objs
 * @param  {Function} callback
 */
Transaction.prototype.saveAll = function(keys, objs, callback) {
  if (keys.length != objs.length) {
    throw new Error('The length of the keys don\'t match the length of the objects');
  }
  var insertIndexes = [];
  var req = {
    mode: MODE_NON_TRANSACTIONAL,
    mutation: {
      upsert: [],
      insertAutoId: []
    }
  };
  if (this.id) {
    req.transaction = this.id;
    req.mode = MODE_TRANSACTIONAL;
  }
  for (var i = 0; i < keys.length; i++) {
    var e = entity.entityToEntityProto(objs[i]);
    e.key = entity.keyToKeyProto(this.id, keys[i]);
    if (entity.isKeyComplete(keys[i])) {
      req.mutation.upsert.push(e);
    } else {
      insertIndexes.push(i);
      req.mutation.insertAutoId.push(e);
    }
  }
  this.makeReq(
      'commit', req, function(err, resp) {
    if (err || !resp) {
      return callback(err);
    }
    resp.mutationResult.insertAutoIdKeys = resp.mutationResult.insertAutoIdKeys || [];
    var i = 0;
    resp.mutationResult.insertAutoIdKeys.forEach(function(item) {
      keys[insertIndexes[i++]] = entity.keyFromKeyProto(item);
    });
    callback(null, keys);
  });
};

/**
 * Deletes the entitiy identified with the specified key in the
 * current transaction.
 * @param  {Array}    key
 * @param  {Function} callback
 */
Transaction.prototype.del = function(key, callback) {
  this.delAll([key], callback);
};

/**
 * Deletes all entities identified with the specified list of keys
 * in the current transaction.
 * @param  {Array<Array>}  keys
 * @param  {Function}      callback
 */
Transaction.prototype.delAll = function(keys, callback) {
  keysProto = [];
  keys.forEach(function(k) {
    keysProto.push(entity.keyToKeyProto(this.id, k));
  });
  var req = {
    mode: MODE_NON_TRANSACTIONAL,
    mutation: {
      'delete': keysProto
    }
  };
  if (this.id) {
    req.transaction = this.id;
    req.mode = MODE_TRANSACTIONAL;
  }
  this.makeReq('commit', req, function(err, resp) {
    callback && callback(err);
  });
};

/**
 * Runs a query in the current transaction. If more results are
 * available, a query to retrieve the next page is provided to
 * the callback function. Example:
 *
 * t.runQuery(q, function(err, keys, objs, nextQuery) {
 *   if (err) return;
 *   // if next page is available, retrieve more results
 *   if (nextQuery) {
 *     t.runQuery(nextQuery, ...);
 *   }
 * });
 * @param  {Query}    q
 * @param  {Function} opt_callback
 */
Transaction.prototype.runQuery = function(q, opt_callback) {
  var req = {
    readOptions: {
      transaction: this.id
    },
    query: entity.queryToQueryProto(q)
  };
  if (q.namespace) {
    req.partitionId = {
      namespace: q.namespace
    };
  }
  this.makeReq('runQuery', req, function(err, resp) {
    if (err || !resp.batch || !resp.batch.entityResults) {
      return opt_callback && opt_callback(err);
    }
    var results = resp.batch.entityResults,
        keys = [], objs = [];
    results.forEach(function(r) {
      keys.push(entity.keyFromKeyProto(r.entity.key));
      objs.push(entity.entityFromEntityProto(r.entity));
    });
    var nextQuery = null;
    if (resp.batch.endCursor && resp.batch.endCursor != q.startVal) {
      nextQuery = q.start(resp.batch.endCursor);
    }
    opt_callback && opt_callback(err, keys, objs, nextQuery);
  });
};

Transaction.prototype.mapQuery = function(q, mapperFn, opt_callback) {
  throw new Error('not yet implemented');
};

/**
 * Makes a request to the API endpoint.
 */
Transaction.prototype.makeReq = function(method, req, callback) {
  // TODO(jbd): Switch to protobuf API.
  this.conn.req({
    method: 'POST',
    uri: DATASTORE_BASE_URL + '/' + this.datasetId + '/' + method,
    json: req
  }, function(err, res, body) {
    if (body && body.error) {
      return callback(body.error, null);
    }
    callback(err, body);
  });
};

/**
 * Creates a new dataset with the provided options.
 * @param {object} opts             Dataset identifier options.
 * @param {string} opts.id          Dataset ID, this is your project ID
 *                                  from Google Developer Console.
 * @param {string} opts.email       Client email of the service account.
 * @param {string} opts.pemFilepath The path to the pem file.
 */
function Dataset(opts) {
  opts = opts || {};
  var id = opts.projectId || '';

  if (id.indexOf("s~") < 0 && id.indexOf("e~") < 0) {
    id = "s~" + id;
  }

  this.id = id;
  this.transaction = new Transaction(new conn.Connection({
    email: opts.email,
    privateKey: opts.pemFilePath,
    scopes: SCOPES
  }), this.id);
}

/**
 * Creates a query from the current dataset to query the specified
 * kinds.
 * @param  {Array<String>} kinds A list of kinds to query.
 * @return {Query}
 */
Dataset.prototype.createQuery = function(kinds) {
  kinds = util.arrayize(kinds);
  return new Query('', kinds);
};

/**
 * Creates a query for collections identified with the specified
 * namespace and kinds.
 *
 * Example usage:
 *   ds.createQueryNS('zoo', ['Lion', 'Chimp'])
 * @param  {string} ns      Namespace to query entities from.
 * @param  {Array<object>}  A list of kinds to query.
 * @return {Query}
 */
Dataset.prototype.createQueryNS = function(ns, kinds) {
  kinds = util.arrayize(kinds);
  return new Query(ns, kinds);
};

/**
 * Gets the object identified with the provided key.
 * @param  {Key}        key       A non-incomplete key.
 * @param  {Function}   callback  The callback function.
 */
Dataset.prototype.get = function(key, callback) {
  this.transaction.get(key, callback);
};

Dataset.prototype.getAll = function(keys, callback) {
  this.transaction.getAll(keys, callback);
};

Dataset.prototype.save = function(key, obj, callback) {
  this.transaction.save(key, obj, callback);
};

Dataset.prototype.saveAll = function(keys, objs, callback) {
  this.transaction.saveAll(keys, objs, callback);
};

Dataset.prototype.del = function(key, callback) {
  this.transaction.del(key, callback);
};

Dataset.prototype.delAll = function(keys, callback) {
  this.transaction.delAll(keys, callback);
};

Dataset.prototype.runQuery = function(q, callback) {
  this.transaction.runQuery(q, callback);
};

Dataset.prototype.runInTransaction = function(fn, callback) {
  var t = new Transaction(this.transaction.conn, this.id);
  var done = function() {
    t.finalize(callback);
  };
  t.begin(function(err, id) {
    if (err) {
      return callback(err);
    }
    fn(t, done);
  });
};

Dataset.prototype.allocateIds = function(incompleteKey, n, callback) {
  if (entity.isKeyComplete(incompleteKey)) {
    throw new Error('An incomplete key should be provided.')
  }
  var incompleteKeys = [];
  for (var i = 0; i < n; i++) {
    incompleteKeys.push(entity.keyToKeyProto(this.id, incompleteKey));
  }
  this.transaction.makeReq(
      'allocateIds', { keys: incompleteKeys }, function(err, resp) {
    if (err) {
      return callback(err);
    }
    var keys = [];
    resp.keys.forEach(function(k) {
      keys.push(entity.keyFromKeyProto(k));
    });
    callback(null ,keys);
  });
};

/**
 * Exports Dataset.
 * @type {Dataset}
 */
module.exports.Dataset = Dataset;

/**
 * Exports Transaction.
 * @type {Transaction}
 */
module.exports.Transaction = Transaction;
<commit_msg>Fixes for runInTransaction<commit_after>/**
 * Copyright 2014 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

var conn = require('../common/connection.js'),
    entity = require('./entity.js'),
    Query = require('./query.js').Query,
    util = require('../common/util.js');

var DATASTORE_BASE_URL = 'https://www.googleapis.com/datastore/v1beta2/datasets',
    SCOPES = [
      'https://www.googleapis.com/auth/datastore',
      'https://www.googleapis.com/auth/userinfo.email'],
    MODE_NON_TRANSACTIONAL = 'NON_TRANSACTIONAL',
    MODE_TRANSACTIONAL = 'TRANSACTIONAL';

/**
 * Transaction represents a Datastore transaction.
 */
function Transaction(conn, datasetId) {
  this.conn = conn;
  this.datasetId = datasetId;
  // the default transaction has no id.
  // if id is not set, run operations non-transactional.
  this.id = null;
  this.isFinalized = false;
}

/**
 * Begins starts a remote transaction and identifies the current
 * transaction instance with the remote transaction's ID.
 */
Transaction.prototype.begin = function(callback) {
  var that = this;
  this.makeReq('beginTransaction', null, function(err, resp) {
    if (!err) {
      that.id = resp.transaction;
    }
    callback && callback(err);
  });
};

/**
 * Rollback rollsback a transaction remotely and finalizes
 * the current transaction instance.
 */
Transaction.prototype.rollback = function(callback) {
  var that = this;
  var req = { transaction: this.id };
  this.makeReq('rollback', req, function(err, resp) {
    if (!err) {
      that.isFinalized = true;
    }
    callback && callback(err);
  });
};

/**
 * Commit commits the remote transaction and finalizes the
 * current transaction instance.
 */
Transaction.prototype.commit = function(callback) {
  var that = this;
  var req = { transaction: this.id };
  this.makeReq('commit', req, function(err, resp) {
    if (!err) {
      that.isFinalized = true;
      that.id = null;
    }
    callback && callback(err);
  });
};

/**
 * Finalize commits a transaction if it's not finalized yet.
 */
Transaction.prototype.finalize = function(callback) {
  if (!this.isFinalized) {
    return this.commit(callback);
  }
  callback();
};

/**
 * Get retrieves the objects identified with the specified key in the
 * current transaction.
 * @param  {Array}    key
 * @param  {Function} callback
 */
Transaction.prototype.get = function(key, callback) {
  this.getAll([key], function(err, keys, objs) {
    if (err || objs.length < 0) {
      return callback(err);
    }
    return callback(null, keys[0], objs[0]);
  });
};

/**
 * Gets all objects identified with the specified list of keys
 * in the current transaction.
 * @param  {Array<Array>}   keys
 * @param  {Function}       callback
 */
Transaction.prototype.getAll = function(keys, callback) {
  keysProto = [];
  keys.forEach(function(k) {
    keysProto.push(entity.keyToKeyProto(this.id, k));
  });
  var req = { keys: keysProto };
  if (this.id) {
    req.transaction = this.id;
  }
  this.makeReq(
      'lookup', req, function(err, resp) {
    if (err) {
      return callback(err);
    }
    var results = [], keys = [];
    resp.found.forEach(function(f) {
      keys.push(entity.keyFromKeyProto(f.entity.key));
      results.push(entity.entityFromEntityProto(f.entity));
    });
    callback && callback(null, keys, results);
  });
};

/**
 * Inserts or updates the specified the object in the current
 * transaction. If the provided key is incomplete, inserts the object
 * and returns the generated identifier.
 * @param  {Array}    key
 * @param  {Object}   obj
 * @param  {Function} callback
 */
Transaction.prototype.save = function(key, obj, callback) {
  this.saveAll([key], [obj], function(err, keys) {
    if (err || !keys) {
      return callback(err);
    }
    if (keys[0]) {
      return callback(err, keys[0]);
    }
    callback();
  });
};

/**
 * Inserts or upates the specified objects in the current transaction.
 * If a key is incomplete, its associated object is inserted and
 * generated identifier is returned.
 * @param  {Array<Array>}   keys
 * @param  {Array<Object>}  objs
 * @param  {Function} callback
 */
Transaction.prototype.saveAll = function(keys, objs, callback) {
  if (keys.length != objs.length) {
    throw new Error('The length of the keys don\'t match the length of the objects');
  }
  var insertIndexes = [];
  var req = {
    mode: MODE_NON_TRANSACTIONAL,
    mutation: {
      upsert: [],
      insertAutoId: []
    }
  };
  if (this.id) {
    req.transaction = this.id;
    req.mode = MODE_TRANSACTIONAL;
  }
  for (var i = 0; i < keys.length; i++) {
    var e = entity.entityToEntityProto(objs[i]);
    e.key = entity.keyToKeyProto(this.datasetId, keys[i]);
    if (entity.isKeyComplete(keys[i])) {
      req.mutation.upsert.push(e);
    } else {
      insertIndexes.push(i);
      req.mutation.insertAutoId.push(e);
    }
  }
  this.makeReq(
      'commit', req, function(err, resp) {
    if (err || !resp) {
      return callback(err);
    }
    resp.mutationResult.insertAutoIdKeys = resp.mutationResult.insertAutoIdKeys || [];
    var i = 0;
    resp.mutationResult.insertAutoIdKeys.forEach(function(item) {
      keys[insertIndexes[i++]] = entity.keyFromKeyProto(item);
    });
    callback(null, keys);
  });
};

/**
 * Deletes the entitiy identified with the specified key in the
 * current transaction.
 * @param  {Array}    key
 * @param  {Function} callback
 */
Transaction.prototype.del = function(key, callback) {
  this.delAll([key], callback);
};

/**
 * Deletes all entities identified with the specified list of keys
 * in the current transaction.
 * @param  {Array<Array>}  keys
 * @param  {Function}      callback
 */
Transaction.prototype.delAll = function(keys, callback) {
  keysProto = [];
  keys.forEach(function(k) {
    keysProto.push(entity.keyToKeyProto(this.id, k));
  });
  var req = {
    mode: MODE_NON_TRANSACTIONAL,
    mutation: {
      'delete': keysProto
    }
  };
  if (this.id) {
    req.transaction = this.id;
    req.mode = MODE_TRANSACTIONAL;
  }
  this.makeReq('commit', req, function(err, resp) {
    callback && callback(err);
  });
};

/**
 * Runs a query in the current transaction. If more results are
 * available, a query to retrieve the next page is provided to
 * the callback function. Example:
 *
 * t.runQuery(q, function(err, keys, objs, nextQuery) {
 *   if (err) return;
 *   // if next page is available, retrieve more results
 *   if (nextQuery) {
 *     t.runQuery(nextQuery, ...);
 *   }
 * });
 * @param  {Query}    q
 * @param  {Function} opt_callback
 */
Transaction.prototype.runQuery = function(q, opt_callback) {
  var req = {
    readOptions: {
      transaction: this.id
    },
    query: entity.queryToQueryProto(q)
  };
  if (q.namespace) {
    req.partitionId = {
      namespace: q.namespace
    };
  }
  this.makeReq('runQuery', req, function(err, resp) {
    if (err || !resp.batch || !resp.batch.entityResults) {
      return opt_callback && opt_callback(err);
    }
    var results = resp.batch.entityResults,
        keys = [], objs = [];
    results.forEach(function(r) {
      keys.push(entity.keyFromKeyProto(r.entity.key));
      objs.push(entity.entityFromEntityProto(r.entity));
    });
    var nextQuery = null;
    if (resp.batch.endCursor && resp.batch.endCursor != q.startVal) {
      nextQuery = q.start(resp.batch.endCursor);
    }
    opt_callback && opt_callback(err, keys, objs, nextQuery);
  });
};

Transaction.prototype.mapQuery = function(q, mapperFn, opt_callback) {
  throw new Error('not yet implemented');
};

/**
 * Makes a request to the API endpoint.
 */
Transaction.prototype.makeReq = function(method, req, callback) {
  // TODO(jbd): Switch to protobuf API.
  // Always pass a value for json to automagically get headers/response parsing.
  req = req || {};
  this.conn.req({
    method: 'POST',
    uri: DATASTORE_BASE_URL + '/' + this.datasetId + '/' + method,
    json: req
  }, function(err, res, body) {
    if (body && body.error) {
      return callback(body.error, null);
    }
    callback(err, body);
  });
};

/**
 * Creates a new dataset with the provided options.
 * @param {object} opts             Dataset identifier options.
 * @param {string} opts.id          Dataset ID, this is your project ID
 *                                  from Google Developer Console.
 * @param {string} opts.email       Client email of the service account.
 * @param {string} opts.pemFilepath The path to the pem file.
 */
function Dataset(opts) {
  opts = opts || {};
  var id = opts.projectId || '';

  if (id.indexOf("s~") < 0 && id.indexOf("e~") < 0) {
    id = "s~" + id;
  }

  this.id = id;
  this.transaction = new Transaction(new conn.Connection({
    email: opts.email,
    privateKey: opts.pemFilePath,
    scopes: SCOPES
  }), this.id);
}

/**
 * Creates a query from the current dataset to query the specified
 * kinds.
 * @param  {Array<String>} kinds A list of kinds to query.
 * @return {Query}
 */
Dataset.prototype.createQuery = function(kinds) {
  kinds = util.arrayize(kinds);
  return new Query('', kinds);
};

/**
 * Creates a query for collections identified with the specified
 * namespace and kinds.
 *
 * Example usage:
 *   ds.createQueryNS('zoo', ['Lion', 'Chimp'])
 * @param  {string} ns      Namespace to query entities from.
 * @param  {Array<object>}  A list of kinds to query.
 * @return {Query}
 */
Dataset.prototype.createQueryNS = function(ns, kinds) {
  kinds = util.arrayize(kinds);
  return new Query(ns, kinds);
};

/**
 * Gets the object identified with the provided key.
 * @param  {Key}        key       A non-incomplete key.
 * @param  {Function}   callback  The callback function.
 */
Dataset.prototype.get = function(key, callback) {
  this.transaction.get(key, callback);
};

Dataset.prototype.getAll = function(keys, callback) {
  this.transaction.getAll(keys, callback);
};

Dataset.prototype.save = function(key, obj, callback) {
  this.transaction.save(key, obj, callback);
};

Dataset.prototype.saveAll = function(keys, objs, callback) {
  this.transaction.saveAll(keys, objs, callback);
};

Dataset.prototype.del = function(key, callback) {
  this.transaction.del(key, callback);
};

Dataset.prototype.delAll = function(keys, callback) {
  this.transaction.delAll(keys, callback);
};

Dataset.prototype.runQuery = function(q, callback) {
  this.transaction.runQuery(q, callback);
};

Dataset.prototype.runInTransaction = function(fn, callback) {
  var t = new Transaction(this.transaction.conn, this.id);
  var done = function() {
    t.finalize(callback);
  };
  t.begin(function(err, id) {
    if (err) {
      return callback(err);
    }
    fn(t, done);
  });
};

Dataset.prototype.allocateIds = function(incompleteKey, n, callback) {
  if (entity.isKeyComplete(incompleteKey)) {
    throw new Error('An incomplete key should be provided.')
  }
  var incompleteKeys = [];
  for (var i = 0; i < n; i++) {
    incompleteKeys.push(entity.keyToKeyProto(this.id, incompleteKey));
  }
  this.transaction.makeReq(
      'allocateIds', { keys: incompleteKeys }, function(err, resp) {
    if (err) {
      return callback(err);
    }
    var keys = [];
    resp.keys.forEach(function(k) {
      keys.push(entity.keyFromKeyProto(k));
    });
    callback(null ,keys);
  });
};

/**
 * Exports Dataset.
 * @type {Dataset}
 */
module.exports.Dataset = Dataset;

/**
 * Exports Transaction.
 * @type {Transaction}
 */
module.exports.Transaction = Transaction;
<|endoftext|>