<commit_before>// schemas.js

var express = require('express'),
    Parse = require('parse/node').Parse,
    PromiseRouter = require('./PromiseRouter'),
    Schema = require('./Schema');

var router = new PromiseRouter();

function mongoFieldTypeToSchemaAPIType(type) {
  if (type[0] === '*') {
    return {
      type: 'Pointer',
      targetClass: type.slice(1),
    };
  }
  if (type.startsWith('relation<')) {
    return {
      type: 'Relation',
      targetClass: type.slice('relation<'.length, type.length - 1),
    };
  }
  switch (type) {
    case 'number':   return {type: 'Number'};
    case 'string':   return {type: 'String'};
    case 'boolean':  return {type: 'Boolean'};
    case 'date':     return {type: 'Date'};
    case 'object':   return {type: 'Object'};
    case 'array':    return {type: 'Array'};
    case 'geopoint': return {type: 'GeoPoint'};
    case 'file':     return {type: 'File'};
  }
}

function mongoSchemaAPIResponseFields(schema) {
  fieldNames = Object.keys(schema).filter(key => key !== '_id');
  response = fieldNames.reduce((obj, fieldName) => {
    obj[fieldName] = mongoFieldTypeToSchemaAPIType(schema[fieldName])
    return obj;
  }, {});
  response.ACL = {type: 'ACL'};
  response.createdAt = {type: 'Date'};
  response.updatedAt = {type: 'Date'};
  response.objectId = {type: 'String'};
  return response;
}

function mongoSchemaToSchemaAPIResponse(schema) {
  return {
    className: schema._id,
    fields: mongoSchemaAPIResponseFields(schema),
  };
}

function getAllSchemas(req) {
  if (!req.auth.isMaster) {
    return Promise.resolve({
      status: 401,
      response: {error: 'master key not specified'},
    });
  }
  return req.config.database.collection('_SCHEMA')
  .then(coll => coll.find({}).toArray())
  .then(schemas => ({response: {
    results: schemas.map(mongoSchemaToSchemaAPIResponse)
  }}));
}

function getOneSchema(req) {
  if (!req.auth.isMaster) {
    return Promise.resolve({
      status: 401,
      response: {error: 'unauthorized'},
    });
  }
  return req.config.database.collection('_SCHEMA')
  .then(coll => coll.findOne({'_id': req.params.className}))
  .then(schema => ({response: mongoSchemaToSchemaAPIResponse(schema)}))
  .catch(() => ({
    status: 400,
    response: {
      code: 103,
      error: 'class ' + req.params.className + ' does not exist',
    }
  }));
}

function createSchema(req) {
  if (!req.auth.isMaster) {
    return Promise.resolve({
      status: 401,
      response: {error: 'master key not specified'},
    });
  }
  if (req.params.className && req.body.className) {
    if (req.params.className != req.body.className) {
      return Promise.resolve({
        status: 400,
        response: {
          code: Parse.Error.INVALID_CLASS_NAME,
          error: 'class name mismatch between ' + req.body.className + ' and ' + req.params.className,
        },
      });
    }
  }
  var className = req.params.className || req.body.className;
  if (!className) {
    return Promise.resolve({
      status: 400,
      response: {
        code: 135,
        error: 'POST ' + req.path + ' needs class name',
      },
    });
  }
  return req.config.database.collection('_SCHEMA')
  .then(coll => Schema.load(coll))
  .then(schema => schema.validateClassName(req.body.className))
  .catch(error => {
    console.log(arguments);
    return {response: error};
  })
  .then(newSchema => {
    for (key in newSchema.data) {
    }
    return {response: {}};
  });
}

router.route('GET', '/schemas', getAllSchemas);
router.route('GET', '/schemas/:className', getOneSchema);
router.route('POST', '/schemas', createSchema);
router.route('POST', '/schemas/:className', createSchema);

module.exports = router;
<commit_msg>Schemas POST fix tests<commit_after>// schemas.js

var express = require('express'),
    Parse = require('parse/node').Parse,
    PromiseRouter = require('./PromiseRouter'),
    Schema = require('./Schema');

var router = new PromiseRouter();

function mongoFieldTypeToSchemaAPIType(type) {
  if (type[0] === '*') {
    return {
      type: 'Pointer',
      targetClass: type.slice(1),
    };
  }
  if (type.startsWith('relation<')) {
    return {
      type: 'Relation',
      targetClass: type.slice('relation<'.length, type.length - 1),
    };
  }
  switch (type) {
    case 'number':   return {type: 'Number'};
    case 'string':   return {type: 'String'};
    case 'boolean':  return {type: 'Boolean'};
    case 'date':     return {type: 'Date'};
    case 'object':   return {type: 'Object'};
    case 'array':    return {type: 'Array'};
    case 'geopoint': return {type: 'GeoPoint'};
    case 'file':     return {type: 'File'};
  }
}

function mongoSchemaAPIResponseFields(schema) {
  fieldNames = Object.keys(schema).filter(key => key !== '_id');
  response = fieldNames.reduce((obj, fieldName) => {
    obj[fieldName] = mongoFieldTypeToSchemaAPIType(schema[fieldName])
    return obj;
  }, {});
  response.ACL = {type: 'ACL'};
  response.createdAt = {type: 'Date'};
  response.updatedAt = {type: 'Date'};
  response.objectId = {type: 'String'};
  return response;
}

function mongoSchemaToSchemaAPIResponse(schema) {
  return {
    className: schema._id,
    fields: mongoSchemaAPIResponseFields(schema),
  };
}

function getAllSchemas(req) {
  if (!req.auth.isMaster) {
    return Promise.resolve({
      status: 401,
      response: {error: 'master key not specified'},
    });
  }
  return req.config.database.collection('_SCHEMA')
  .then(coll => coll.find({}).toArray())
  .then(schemas => ({response: {
    results: schemas.map(mongoSchemaToSchemaAPIResponse)
  }}));
}

function getOneSchema(req) {
  if (!req.auth.isMaster) {
    return Promise.resolve({
      status: 401,
      response: {error: 'unauthorized'},
    });
  }
  return req.config.database.collection('_SCHEMA')
  .then(coll => coll.findOne({'_id': req.params.className}))
  .then(schema => ({response: mongoSchemaToSchemaAPIResponse(schema)}))
  .catch(() => ({
    status: 400,
    response: {
      code: 103,
      error: 'class ' + req.params.className + ' does not exist',
    }
  }));
}

function createSchema(req) {
  if (!req.auth.isMaster) {
    return Promise.resolve({
      status: 401,
      response: {error: 'master key not specified'},
    });
  }
  if (req.params.className && req.body.className) {
    if (req.params.className != req.body.className) {
      return Promise.resolve({
        status: 400,
        response: {
          code: Parse.Error.INVALID_CLASS_NAME,
          error: 'class name mismatch between ' + req.body.className + ' and ' + req.params.className,
        },
      });
    }
  }
  var className = req.params.className || req.body.className;
  if (!className) {
    return Promise.resolve({
      status: 400,
      response: {
        code: 135,
        error: 'POST ' + req.path + ' needs class name',
      },
    });
  }
  return req.config.database.loadSchema()
  .then(schema => schema.addClassIfNotExists(className, req.body.fields))
  .then(result => ({ response: mongoSchemaToSchemaAPIResponse(result) }))
  .catch(error => ({
    status: 400,
    response: error,
  }));
}

router.route('GET', '/schemas', getAllSchemas);
router.route('GET', '/schemas/:className', getOneSchema);
router.route('POST', '/schemas', createSchema);
router.route('POST', '/schemas/:className', createSchema);

module.exports = router;
<|endoftext|>


<commit_before>'use strict';

/**
 * Copyright 2015, Yahoo! Inc.
 * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
 */
let path = require('path');

module.exports = {
  description: 'Setup ember-intl',

  normalizeEntityName() {},

  fileMapTokens() {
    return {
      __app__(options) {
        if (options.inAddon) {
          return path.join('tests', 'dummy', 'app');
        } else {
          return path.join('app');
        }
      },
      __config__(options) {
        if (options.inAddon) {
          return path.join('tests', 'dummy', 'config');
        } else {
          return path.join('config');
        }
      },
    };
  },

  afterInstall() {
    this.ui.writeLine(
      "[ember-intl] Don't forget to setup your application-wide locale.  " +
        'Documentation: https://github.com/ember-intl/ember-intl#setting-locale'
    );
  },
};
<commit_msg>docs: Fix bad link in post install (#1586)<commit_after>'use strict';

/**
 * Copyright 2015, Yahoo! Inc.
 * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
 */
let path = require('path');

module.exports = {
  description: 'Setup ember-intl',

  normalizeEntityName() {},

  fileMapTokens() {
    return {
      __app__(options) {
        if (options.inAddon) {
          return path.join('tests', 'dummy', 'app');
        } else {
          return path.join('app');
        }
      },
      __config__(options) {
        if (options.inAddon) {
          return path.join('tests', 'dummy', 'config');
        } else {
          return path.join('config');
        }
      },
    };
  },

  afterInstall() {
    this.ui.writeLine(
      "[ember-intl] Don't forget to configure your application.  " +
        'Documentation: https://ember-intl.github.io/ember-intl/versions/master/docs/quickstart#4-configure-ember-intl'
    );
  },
};
<|endoftext|>


<commit_before>// Copyright (c) 2012 Titanium I.T. LLC. All rights reserved. See LICENSE.txt for details.
/*global desc, task, jake, fail, complete, directory, require, console, process */
(function () {
	"use strict";

	var TESTED_BROWSERS = [
		// "IE 8.0 (Windows)",  // DOES NOT WORK -- no SVG support
		// "IE 9.0 (Windows)",  // DOES NOT WORK -- no Int32Array support and shim causes 'Out of memory' error
		"IE 10.0 (Windows)",
		"Firefox 20.0 (Mac)",
		"Chrome 27.0 (Mac)",
		"Safari 6.0 (Mac)",
		"Safari 6.0 (iOS)"
	];

	var NODE_VERSION = "v0.10.6";

	var lint = require("./build/util/lint_runner.js");
	var karma = require("./build/util/karma_runner.js");
	var version = require("./build/util/version_checker.js");

	desc("Lint and test");
	task("default", ["lint", "test"], function() {
		console.log("\n\nBUILD OK");
	});

	desc("Start Karma server -- run this first");
	task("karma", function() {
		karma.serve(complete, fail);
	}, {async: true});

	desc("Lint everything");
	task("lint", ["nodeVersion"], function () {
		var passed = lint.validateFileList(nodeFilesToLint(), nodeLintOptions(), {});
		passed = lint.validateFileList(browserFilesToLint(), browserLintOptions(), browserLintGlobals()) && passed;
		if (!passed) fail("Lint failed");
	});

	desc("Test browser code");
	task("test", function() {
		karma.runTests(TESTED_BROWSERS, complete, fail);
	}, {async: true});

//	desc("Ensure installed version of Node is same as known-good version");
	task("nodeVersion", [], function() {
		var installedVersion = process.version;
		version.check("Node", !process.env.loose, NODE_VERSION, installedVersion, fail);
	});

	function nodeFilesToLint() {
		var files = new jake.FileList();
		files.include("build/util/**/*.js");
		files.include("Jakefile.js");
		return files.toArray();
	}

	function browserFilesToLint() {
		var files = new jake.FileList();
		files.include("src/*.js");
		return files.toArray();
	}

	function sharedLintOptions() {
		return {
			bitwise:true,
			curly:false,
			eqeqeq:true,
			forin:true,
			immed:true,
			latedef:false,
			newcap:true,
			noarg:true,
			noempty:true,
			nonew:true,
			regexp:true,
			undef:true,
			strict:true,
			trailing:true
		};
	}

	function nodeLintOptions() {
		var options = sharedLintOptions();
		options.node = true;
		return options;
	}

	function browserLintOptions() {
		var options = sharedLintOptions();
		options.browser = true;
		return options;
	}

	function browserLintGlobals() {
		return {
			jdls: true,

			mocha: false,
			describe: false,
			it: false,
			expect: false,
			dump: false,
			beforeEach: false,
			afterEach: false
		};
	}

}());<commit_msg>Updated Firefox 20.0 --> 21.0<commit_after>// Copyright (c) 2012 Titanium I.T. LLC. All rights reserved. See LICENSE.txt for details.
/*global desc, task, jake, fail, complete, directory, require, console, process */
(function () {
	"use strict";

	var TESTED_BROWSERS = [
		// "IE 8.0 (Windows)",  // DOES NOT WORK -- no SVG support
		// "IE 9.0 (Windows)",  // DOES NOT WORK -- no Int32Array support and shim causes 'Out of memory' error
		"IE 10.0 (Windows)",
		"Firefox 21.0 (Mac)",
		"Chrome 27.0 (Mac)",
		"Safari 6.0 (Mac)",
		"Safari 6.0 (iOS)"
	];

	var NODE_VERSION = "v0.10.6";

	var lint = require("./build/util/lint_runner.js");
	var karma = require("./build/util/karma_runner.js");
	var version = require("./build/util/version_checker.js");

	desc("Lint and test");
	task("default", ["lint", "test"], function() {
		console.log("\n\nBUILD OK");
	});

	desc("Start Karma server -- run this first");
	task("karma", function() {
		karma.serve(complete, fail);
	}, {async: true});

	desc("Lint everything");
	task("lint", ["nodeVersion"], function () {
		var passed = lint.validateFileList(nodeFilesToLint(), nodeLintOptions(), {});
		passed = lint.validateFileList(browserFilesToLint(), browserLintOptions(), browserLintGlobals()) && passed;
		if (!passed) fail("Lint failed");
	});

	desc("Test browser code");
	task("test", function() {
		karma.runTests(TESTED_BROWSERS, complete, fail);
	}, {async: true});

//	desc("Ensure installed version of Node is same as known-good version");
	task("nodeVersion", [], function() {
		var installedVersion = process.version;
		version.check("Node", !process.env.loose, NODE_VERSION, installedVersion, fail);
	});

	function nodeFilesToLint() {
		var files = new jake.FileList();
		files.include("build/util/**/*.js");
		files.include("Jakefile.js");
		return files.toArray();
	}

	function browserFilesToLint() {
		var files = new jake.FileList();
		files.include("src/*.js");
		return files.toArray();
	}

	function sharedLintOptions() {
		return {
			bitwise:true,
			curly:false,
			eqeqeq:true,
			forin:true,
			immed:true,
			latedef:false,
			newcap:true,
			noarg:true,
			noempty:true,
			nonew:true,
			regexp:true,
			undef:true,
			strict:true,
			trailing:true
		};
	}

	function nodeLintOptions() {
		var options = sharedLintOptions();
		options.node = true;
		return options;
	}

	function browserLintOptions() {
		var options = sharedLintOptions();
		options.browser = true;
		return options;
	}

	function browserLintGlobals() {
		return {
			jdls: true,

			mocha: false,
			describe: false,
			it: false,
			expect: false,
			dump: false,
			beforeEach: false,
			afterEach: false
		};
	}

}());<|endoftext|>


<commit_before>#!/usr/bin/env node

/*
  Get Basal Information

  Released under MIT license. See the accompanying LICENSE.txt file for
  full terms and conditions

  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  THE SOFTWARE.

*/

var generate = require('oref0/lib/profile/');
function usage ( ) {
        console.log('usage: ', process.argv.slice(0, 2), '<pump_settings.json> <bg_targets.json> <insulin_sensitivities.json> <basal_profile.json> [<max_iob.json>] [<carb_ratios.json>]');
}

if (!module.parent) {

    var pumpsettings_input = process.argv.slice(2, 3).pop()
    if ([null, '--help', '-h', 'help'].indexOf(pumpsettings_input) > 0) {
      usage( );
      process.exit(0)
    }
    var bgtargets_input = process.argv.slice(3, 4).pop()
    var isf_input = process.argv.slice(4, 5).pop()
    var basalprofile_input = process.argv.slice(5, 6).pop()
    var maxiob_input = process.argv.slice(6, 7).pop()
    var carbratio_input = process.argv.slice(7, 8).pop()

    if (!pumpsettings_input || !bgtargets_input || !isf_input || !basalprofile_input) {
        usage( );
        process.exit(1);
    }

    var cwd = process.cwd()
    var pumpsettings_data = require(cwd + '/' + pumpsettings_input);
    var bgtargets_data = require(cwd + '/' + bgtargets_input);
    if (bgtargets_data.units !== 'mg/dL') {
      console.log('BG Target data is expected to be expressed in mg/dL.'
                 , 'Found', bgtargets_data.units, 'in', bgtargets_input, '.');
      process.exit(2);
    }
    var isf_data = require(cwd + '/' + isf_input);
    if (isf_data.units !== 'mg/dL') {
      console.log('ISF is expected to be expressed in mg/dL.'
                 , 'Found', isf_data.units, 'in', isf_input, '.');
      process.exit(2);
    }
    var basalprofile_data = require(cwd + '/' + basalprofile_input);

    var maxiob_data = { max_iob: 0 };
    if (typeof maxiob_input != 'undefined') {
        maxiob_data = require(cwd + '/' + maxiob_input);
    }
    var fs = require('fs');
    var carbratio_data = { };
    //console.log("carbratio_input",carbratio_input);
    if (typeof carbratio_input != 'undefined') {
        try {
            carbratio_data = JSON.parse(fs.readFileSync(carbratio_input, 'utf8'));

        } catch (e) {
            var msg = { error: e, msg: "Could not parse carbratio_data. Optional feature Meal Assist disabled.", file: carbratio_input };
            console.error(msg.msg);
            console.log(JSON.stringify(msg));
            process.exit(1);
        }
        var errors = [ ];

        if (!(carbratio_data.schedule && carbratio_data.schedule[0].start && carbratio_data.schedule[0].ratio)) {
          errors.push({msg: "Carb ratio data should have an array called schedule with a start and ratio fields.", file: carbratio_input, data: carbratio_data});
        } else {
        }
        if (carbratio_data.units != 'grams') {
          errors.push({msg: "Carb ratio should have units field set to 'grams'.", file: carbratio_input, data: carbratio_data});
        }
        if (errors.length) {

          errors.forEach(function (msg) {
            console.error(msg.msg);
          });
          console.log(JSON.stringify(errors));
          process.exit(1);
        }
    }
    //console.log(carbratio_data);
    var inputs = {
      settings: pumpsettings_data
    , targets: bgtargets_data
    , basals: basalprofile_data
    , isf: isf_data
    , max_iob: maxiob_data.max_iob || 0
    , carbratio: carbratio_data
    };

    var profile = generate(inputs);

    console.log(JSON.stringify(profile));
}
<commit_msg>tweak error message<commit_after>#!/usr/bin/env node

/*
  Get Basal Information

  Released under MIT license. See the accompanying LICENSE.txt file for
  full terms and conditions

  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  THE SOFTWARE.

*/

var generate = require('oref0/lib/profile/');
function usage ( ) {
        console.log('usage: ', process.argv.slice(0, 2), '<pump_settings.json> <bg_targets.json> <insulin_sensitivities.json> <basal_profile.json> [<max_iob.json>] [<carb_ratios.json>]');
}

if (!module.parent) {

    var pumpsettings_input = process.argv.slice(2, 3).pop()
    if ([null, '--help', '-h', 'help'].indexOf(pumpsettings_input) > 0) {
      usage( );
      process.exit(0)
    }
    var bgtargets_input = process.argv.slice(3, 4).pop()
    var isf_input = process.argv.slice(4, 5).pop()
    var basalprofile_input = process.argv.slice(5, 6).pop()
    var maxiob_input = process.argv.slice(6, 7).pop()
    var carbratio_input = process.argv.slice(7, 8).pop()

    if (!pumpsettings_input || !bgtargets_input || !isf_input || !basalprofile_input) {
        usage( );
        process.exit(1);
    }

    var cwd = process.cwd()
    var pumpsettings_data = require(cwd + '/' + pumpsettings_input);
    var bgtargets_data = require(cwd + '/' + bgtargets_input);
    if (bgtargets_data.units !== 'mg/dL') {
      console.log('BG Target data is expected to be expressed in mg/dL.'
                 , 'Found', bgtargets_data.units, 'in', bgtargets_input, '.');
      process.exit(2);
    }
    var isf_data = require(cwd + '/' + isf_input);
    if (isf_data.units !== 'mg/dL') {
      console.log('ISF is expected to be expressed in mg/dL.'
                 , 'Found', isf_data.units, 'in', isf_input, '.');
      process.exit(2);
    }
    var basalprofile_data = require(cwd + '/' + basalprofile_input);

    var maxiob_data = { max_iob: 0 };
    if (typeof maxiob_input != 'undefined') {
        maxiob_data = require(cwd + '/' + maxiob_input);
    }
    var fs = require('fs');
    var carbratio_data = { };
    //console.log("carbratio_input",carbratio_input);
    if (typeof carbratio_input != 'undefined') {
        try {
            carbratio_data = JSON.parse(fs.readFileSync(carbratio_input, 'utf8'));

        } catch (e) {
            var msg = { error: e, msg: "Could not parse carbratio_data. Feature Meal Assist enabled but cannot find required carb_ratios.", file: carbratio_input };
            console.error(msg.msg);
            console.log(JSON.stringify(msg));
            process.exit(1);
        }
        var errors = [ ];

        if (!(carbratio_data.schedule && carbratio_data.schedule[0].start && carbratio_data.schedule[0].ratio)) {
          errors.push({msg: "Carb ratio data should have an array called schedule with a start and ratio fields.", file: carbratio_input, data: carbratio_data});
        } else {
        }
        if (carbratio_data.units != 'grams') {
          errors.push({msg: "Carb ratio should have units field set to 'grams'.", file: carbratio_input, data: carbratio_data});
        }
        if (errors.length) {

          errors.forEach(function (msg) {
            console.error(msg.msg);
          });
          console.log(JSON.stringify(errors));
          process.exit(1);
        }
    }
    //console.log(carbratio_data);
    var inputs = {
      settings: pumpsettings_data
    , targets: bgtargets_data
    , basals: basalprofile_data
    , isf: isf_data
    , max_iob: maxiob_data.max_iob || 0
    , carbratio: carbratio_data
    };

    var profile = generate(inputs);

    console.log(JSON.stringify(profile));
}
<|endoftext|>


<commit_before>/**
 * Tencent is pleased to support the open source community by making QMUI Web available.
 * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.
 * Licensed under the MIT License (the "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 * http://opensource.org/licenses/MIT
 *
 * 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.
 */

// 进行 Sass 编译以及雪碧图处理
var argv = require('yargs').argv,
  lazysprite = require('postcss-lazysprite'),
  autoprefixer = require('autoprefixer');

module.exports = function (gulp, common) {
  var _spriteConfig = {
    cssSeparator: '_',
    imagePath: common.config.imagesSourcePath,
    stylesheetRelative: common.config.styleResultPath,
    stylesheetInput: '../project/',
    spritePath: common.config.imagesResultPath,
    smartUpdate: typeof common.config.needsLazyspriteSmartUpdate !== 'undefined' ? common.config.needsLazyspriteSmartUpdate : true,
    nameSpace: common.config.prefix + '_',
    retinaInfix: '_',
    outputExtralCSS: true
  };
  var _styleResultPath = common.config.styleResultPath;
  if (argv.debug) {
    _spriteConfig.logLevel = 'debug';
  }

  gulp.task('sass', '进行 Sass 编译以及雪碧图处理（框架自带 Watch 机制监听 Sass 和图片变化后自行编译，不建议手工调用本方法）', function () {
    var _isOpeningBrowserSyncMod = common.config.browserSyncMod !== 'close';
    return gulp.src('../project/**/*.scss')
      .pipe(common.plugins.plumber({
        errorHandler: function (_error) {
          common.error('SASS', _error);
          common.plugins.util.beep();
        }
      }))
      .pipe(common.plugins.if(common.config.needsSourceMaps, common.plugins.sourcemaps.init()))
      .pipe(common.plugins.if(global.isWatching && global.isHandleStyle, common.plugins.cached('sass')))
      .pipe(common.plugins.sassInheritance({base: '../project/'}))
      .pipe(common.plugins.if(Boolean(argv.debug), common.plugins.debug({title: 'Sass Debug:'})))
      .pipe(common.plugins.sass({
        outputStyle: 'expanded',
        precision: 6
      }).on('error', common.plugins.sass.logError))
      .pipe(common.plugins.postcss([lazysprite(_spriteConfig), autoprefixer({
        flexbox: false,
        browsers: ['defaults', 'last 5 versions', '> 5% in CN', 'not ie < 8']
      })]))
      .pipe(common.plugins.if(common.config.needsSourceMaps, common.plugins.sourcemaps.write('./maps'))) // Source Maps 的 Base 输出目录为 style 输出的目录
      .pipe(gulp.dest(_styleResultPath))
      .pipe(common.plugins.if(_isOpeningBrowserSyncMod, common.reload({stream: true})));
  });
};
<commit_msg>update: optimize the handling of flexbox in autoperfixer<commit_after>/**
 * Tencent is pleased to support the open source community by making QMUI Web available.
 * Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.
 * Licensed under the MIT License (the "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 * http://opensource.org/licenses/MIT
 *
 * 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.
 */

// 进行 Sass 编译以及雪碧图处理
var argv = require('yargs').argv,
  lazysprite = require('postcss-lazysprite'),
  autoprefixer = require('autoprefixer');

module.exports = function (gulp, common) {
  var _spriteConfig = {
    cssSeparator: '_',
    imagePath: common.config.imagesSourcePath,
    stylesheetRelative: common.config.styleResultPath,
    stylesheetInput: '../project/',
    spritePath: common.config.imagesResultPath,
    smartUpdate: typeof common.config.needsLazyspriteSmartUpdate !== 'undefined' ? common.config.needsLazyspriteSmartUpdate : true,
    nameSpace: common.config.prefix + '_',
    retinaInfix: '_',
    outputExtralCSS: true
  };
  var _styleResultPath = common.config.styleResultPath;
  if (argv.debug) {
    _spriteConfig.logLevel = 'debug';
  }

  gulp.task('sass', '进行 Sass 编译以及雪碧图处理（框架自带 Watch 机制监听 Sass 和图片变化后自行编译，不建议手工调用本方法）', function () {
    var _isOpeningBrowserSyncMod = common.config.browserSyncMod !== 'close';
    return gulp.src('../project/**/*.scss')
      .pipe(common.plugins.plumber({
        errorHandler: function (_error) {
          common.error('SASS', _error);
          common.plugins.util.beep();
        }
      }))
      .pipe(common.plugins.if(common.config.needsSourceMaps, common.plugins.sourcemaps.init()))
      .pipe(common.plugins.if(global.isWatching && global.isHandleStyle, common.plugins.cached('sass')))
      .pipe(common.plugins.sassInheritance({base: '../project/'}))
      .pipe(common.plugins.if(Boolean(argv.debug), common.plugins.debug({title: 'Sass Debug:'})))
      .pipe(common.plugins.sass({
        outputStyle: 'expanded',
        precision: 6
      }).on('error', common.plugins.sass.logError))
      .pipe(common.plugins.postcss([lazysprite(_spriteConfig), autoprefixer({
        browsers: ['defaults', 'last 5 versions', '> 5% in CN', 'not ie < 8', 'iOS >= 8']
      })]))
      .pipe(common.plugins.if(common.config.needsSourceMaps, common.plugins.sourcemaps.write('./maps'))) // Source Maps 的 Base 输出目录为 style 输出的目录
      .pipe(gulp.dest(_styleResultPath))
      .pipe(common.plugins.if(_isOpeningBrowserSyncMod, common.reload({stream: true})));
  });
};
<|endoftext|>


<commit_before>var paths         = require('./paths');
var child_process = require('child_process');
var STDOUT        = {
                      write: function(data){
                        process.stdout.write(data.toString());
                      }
                    };

task('default', function(){
  var jake = child_process.spawn('jake', ['-T']);
  jake.stdout.on('data', STDOUT.write);
});

/*
 * Forever
 *
 * accepts arguments: jake list\['--plain'\]
 */

var FOREVER = function(script, arguments){
  var args = [];
  for (argument in arguments) args.push(arguments[argument]);

  child_process.exec('which forever', function(error, stdout, stderr){
    if (!error && stdout) {
      process.env['NODE_ENV'] = 'production'; // production mode
      script(stdout.trim(), args);
    } else {
      console.log('Please install forever first: npm -g install forever');
    }
  });
}

var PID_FILE = __dirname + '/tmp/pids/forever.pid';

var START = function(verb, arguments){
  FOREVER(function(forever_path, arguments){
    var forever = child_process.spawn(forever_path, [
      verb,
      '-m', 5,
      '--append',
      '--minUptime', 2000,
      '--spinSleepTime', 1000,
      '-l', __dirname + '/log/forever.log',
      '-o', __dirname + '/log/forever.stdout.log',
      '-e', __dirname + '/log/forever.stderr.log',
      '--pidFile', PID_FILE,
      'app.js'
    ].concat(arguments));
    forever.stdout.on('data', STDOUT.write);
    forever.stderr.on('data', STDOUT.write);
  }, arguments);
};

desc('forever start');
task('start', function(){
  var args = arguments;
  require('fs').exists(PID_FILE, function(exists){
    if (exists) {
      console.log('Please use "jake stop" to stop current script first.');
      console.log('If problem still exists, manually remove the PID file:');
      console.log('> rm -f ' + PID_FILE);
    } else {
      START('start', args);
    }
  });
});

desc('forever restart');
task('restart', function(){
  var args = arguments;
  require('fs').exists(PID_FILE, function(exists){
    if (exists) {
      START('restart', args);
    } else {
      START('start', args);
    }
  });
});

desc('forever stop');
task('stop', function(){
  FOREVER(function(forever_path, arguments){
    var forever = child_process.spawn(forever_path, [
      'stop',
      '--pidFile', PID_FILE,
      'app.js'
    ].concat(arguments));
    forever.stdout.on('data', STDOUT.write);
    forever.stderr.on('data', STDOUT.write);
  }, arguments);
});

desc('forever list');
task('list', function(){
  FOREVER(function(forever_path, arguments){
    var forever = child_process.spawn(forever_path, [ 'list' ].concat(arguments));
    forever.stdout.on('data', STDOUT.write);
    forever.stderr.on('data', STDOUT.write);
  }, arguments);
});

/*
 * Token
 */

desc('create or update token file');
task('token', function(){
  var rl = require('readline').createInterface({
    input: process.stdin,
    output: process.stdout
  });
  rl.question('Enter your Weixin token: ', function(token){
    if (token.length < 3 || token.length > 32) {
      console.log('What you type does not look like a token. Aborted.');
      rl.close();
      return;
    }
    require('fs').writeFile(paths.weixin.token, JSON.stringify({
      token: token
    }, null, 2) + '\n', function(error){
      console.log( (error ? 'Error saving token to file' :
                            'Token was saved to file') + ': ' + paths.weixin.token + '.');
      rl.close();
    });
  });
});

/*
 * Coordinates
 */

desc('find coordinates');
task('coord', function(){
  var stores_list = require(paths.stores);
  var coord = require(paths.lib.coord);

  function has_coordinates(store) {
    return /^\-?\d+\.\d+$/m.test(store.join('\n'));
  }

  function normalize_address(address) {
    return address.replace(/[\(（,，\/].*$/, '');
  }

  function save_stores_list() {
    var json_string = JSON.stringify(stores_list, null, 2);
    json_string = json_string.replace(/\n\s{8}/g, '').replace(/\n\s{6}\]/g, ']') + '\n';
    require('fs').writeFile('./stores.json', json_string, function(err){
      if (err) console.log('ERROR: ' + err);
    })
  }

  function find_coordinates_to_address(address, __) {
    if (address.length == 0) return;
    var http = require('http');
    http.get('http://api.map.baidu.com/?qt=s&rn=1&wd=' + address, function(res){
      var body = '';
      res.on('data', function (chunk) { body += chunk; });
      res.on('end', function(){
        body = JSON.parse(body);
        if (body.hasOwnProperty('content')) {
          var coordinates;
          if (body['content'] instanceof Array) {
            coordinates = coord.parse_geostring(body['content'][0]['geo']);
          } else {
            coordinates = coord.parse_geostring(body['content']['geo']);
          }
          if (coordinates == null) {
            console.log('WARNING: No coords returned for address: ' + address);
          } else {
            stores_list[__[0]][__[1]][__[2]] = stores_list[__[0]][__[1]][__[2]].concat(coordinates);
            save_stores_list();
          }
        } else {
          address = address.slice(0,-1)
          find_coordinates_to_address(address, __);
          console.log('Trying ' + address + '...');
        }
      });
    });
  }

  loop_p:
  for(var province in stores_list) {
    for(var city in stores_list[province]) {
      for(var i = 0; i < stores_list[province][city].length; i++) {
        var store = stores_list[province][city][i];
        if (!has_coordinates(store)) {
          var address = normalize_address(province + (province != city ? city : '') + store[1] + store[2]);
          find_coordinates_to_address(address, [province, city, i]);
          //break loop_p; //if you want to try one
        }
      }
    }
  }

});
<commit_msg>fix stores.json path<commit_after>var paths         = require('./paths');
var child_process = require('child_process');
var STDOUT        = {
                      write: function(data){
                        process.stdout.write(data.toString());
                      }
                    };

task('default', function(){
  var jake = child_process.spawn('jake', ['-T']);
  jake.stdout.on('data', STDOUT.write);
});

/*
 * Forever
 *
 * accepts arguments: jake list\['--plain'\]
 */

var FOREVER = function(script, arguments){
  var args = [];
  for (argument in arguments) args.push(arguments[argument]);

  child_process.exec('which forever', function(error, stdout, stderr){
    if (!error && stdout) {
      process.env['NODE_ENV'] = 'production'; // production mode
      script(stdout.trim(), args);
    } else {
      console.log('Please install forever first: npm -g install forever');
    }
  });
}

var PID_FILE = __dirname + '/tmp/pids/forever.pid';

var START = function(verb, arguments){
  FOREVER(function(forever_path, arguments){
    var forever = child_process.spawn(forever_path, [
      verb,
      '-m', 5,
      '--append',
      '--minUptime', 2000,
      '--spinSleepTime', 1000,
      '-l', __dirname + '/log/forever.log',
      '-o', __dirname + '/log/forever.stdout.log',
      '-e', __dirname + '/log/forever.stderr.log',
      '--pidFile', PID_FILE,
      'app.js'
    ].concat(arguments));
    forever.stdout.on('data', STDOUT.write);
    forever.stderr.on('data', STDOUT.write);
  }, arguments);
};

desc('forever start');
task('start', function(){
  var args = arguments;
  require('fs').exists(PID_FILE, function(exists){
    if (exists) {
      console.log('Please use "jake stop" to stop current script first.');
      console.log('If problem still exists, manually remove the PID file:');
      console.log('> rm -f ' + PID_FILE);
    } else {
      START('start', args);
    }
  });
});

desc('forever restart');
task('restart', function(){
  var args = arguments;
  require('fs').exists(PID_FILE, function(exists){
    if (exists) {
      START('restart', args);
    } else {
      START('start', args);
    }
  });
});

desc('forever stop');
task('stop', function(){
  FOREVER(function(forever_path, arguments){
    var forever = child_process.spawn(forever_path, [
      'stop',
      '--pidFile', PID_FILE,
      'app.js'
    ].concat(arguments));
    forever.stdout.on('data', STDOUT.write);
    forever.stderr.on('data', STDOUT.write);
  }, arguments);
});

desc('forever list');
task('list', function(){
  FOREVER(function(forever_path, arguments){
    var forever = child_process.spawn(forever_path, [ 'list' ].concat(arguments));
    forever.stdout.on('data', STDOUT.write);
    forever.stderr.on('data', STDOUT.write);
  }, arguments);
});

/*
 * Token
 */

desc('create or update token file');
task('token', function(){
  var rl = require('readline').createInterface({
    input: process.stdin,
    output: process.stdout
  });
  rl.question('Enter your Weixin token: ', function(token){
    if (token.length < 3 || token.length > 32) {
      console.log('What you type does not look like a token. Aborted.');
      rl.close();
      return;
    }
    require('fs').writeFile(paths.weixin.token, JSON.stringify({
      token: token
    }, null, 2) + '\n', function(error){
      console.log( (error ? 'Error saving token to file' :
                            'Token was saved to file') + ': ' + paths.weixin.token + '.');
      rl.close();
    });
  });
});

/*
 * Coordinates
 */

desc('find coordinates');
task('coord', function(){
  var stores_list = require(paths.stores);
  var coord = require(paths.lib.coord);

  function has_coordinates(store) {
    return /^\-?\d+\.\d+$/m.test(store.join('\n'));
  }

  function normalize_address(address) {
    return address.replace(/[\(（,，\/].*$/, '');
  }

  function save_stores_list() {
    var json_string = JSON.stringify(stores_list, null, 2);
    json_string = json_string.replace(/\n\s{8}/g, '').replace(/\n\s{6}\]/g, ']') + '\n';
    require('fs').writeFile(paths.stores, json_string, function(err){
      if (err) console.log('ERROR: ' + err);
    })
  }

  function find_coordinates_to_address(address, __) {
    if (address.length == 0) return;
    var http = require('http');
    http.get('http://api.map.baidu.com/?qt=s&rn=1&wd=' + address, function(res){
      var body = '';
      res.on('data', function (chunk) { body += chunk; });
      res.on('end', function(){
        body = JSON.parse(body);
        if (body.hasOwnProperty('content')) {
          var coordinates;
          if (body['content'] instanceof Array) {
            coordinates = coord.parse_geostring(body['content'][0]['geo']);
          } else {
            coordinates = coord.parse_geostring(body['content']['geo']);
          }
          if (coordinates == null) {
            console.log('WARNING: No coords returned for address: ' + address);
          } else {
            stores_list[__[0]][__[1]][__[2]] = stores_list[__[0]][__[1]][__[2]].concat(coordinates);
            save_stores_list();
          }
        } else {
          address = address.slice(0,-1)
          find_coordinates_to_address(address, __);
          console.log('Trying ' + address + '...');
        }
      });
    });
  }

  loop_p:
  for(var province in stores_list) {
    for(var city in stores_list[province]) {
      for(var i = 0; i < stores_list[province][city].length; i++) {
        var store = stores_list[province][city][i];
        if (!has_coordinates(store)) {
          var address = normalize_address(province + (province != city ? city : '') + store[1] + store[2]);
          find_coordinates_to_address(address, [province, city, i]);
          //break loop_p; //if you want to try one
        }
      }
    }
  }

});
<|endoftext|>


<commit_before>/*
 * Jakefile for Rimu Markup (http://github.com/srackham/rimu).
 */
'use strict';

var pkg = require('./package.json');
var shelljs = require('shelljs');
var child_process = require('child_process');

/* Inputs and outputs */

var RIMU_LIB = 'bin/rimu.js';
var RIMU_LIB_MIN = 'bin/rimu.min.js';
var MAIN_TS = 'src/main.ts';
var SOURCE = shelljs.ls('src/*.ts');
var TESTS = shelljs.ls('test/*.js');
var GH_PAGES_DIR = './gh-pages/';
var RIMUC = './bin/rimuc.js';

var DOCS = [
  {
    src: 'README.md', dst: 'doc/index.html', title: 'Rimu Markup',
    rimucOptions: '--toc'
  },
  {
    src: 'CHANGELOG.md', dst: 'doc/CHANGELOG.html', title: 'Rimu Change Log',
    rimucOptions: '--toc'
  },
  {
    src: 'doc/reference.rmu', dst: 'doc/reference.html', title: 'Rimu Reference',
    rimucOptions: '--toc --prepend "{generate-examples}=\'yes\'"'
  },
  {
    src: 'doc/tips.rmu', dst: 'doc/tips.html', title: 'Rimu Tips',
    rimucOptions: '--toc --prepend "{generate-examples}=\'yes\'"'
  },
  {
    src: 'doc/rimuplayground.rmu', dst: 'doc/rimuplayground.html', title: 'Rimu Playground',
    rimucOptions: '--toc --prepend "{generate-examples}=\'yes\'"'
  }
];

var HTML = [];
DOCS.forEach(function(doc) {
  HTML.push(doc.dst);
});

/* Utility functions. */

/*
 Execute shell commands in parallel then run the `callback` when they have all finished.
 Abort if an error occurs.
 Write command output to the inherited stdout (unless the Jake --quiet option is set).
 Print a status message when each command starts and finishes (unless the Jake --quiet option is set).

 NOTE: This function is similar to the built-in jake.exec function but is twice as fast.
 */
function exec(commands, callback) {
  if (typeof commands === 'string') {
    commands = [commands];
  }
  var remaining = commands.length;
  if (remaining === 0) {
    callback();
  }
  else {
    commands.forEach(function(command) {
      jake.logger.log('Starting: ' + command);
      child_process.exec(command, function(error, stdout, stderr) {
        if (!jake.program.opts.quiet) {
          process.stdout.write(stdout);
        }
        if (error !== null) {
          fail(error, error.code);
        }
        jake.logger.log('Finished: ' + command);
        remaining--;
        if (remaining === 0) {
          callback();
        }
      });
    });
  }
}

/*
 Tasks

 All tasks are synchronous (another task will not run until the current task has completed).
 Consequently all task dependencies are executed asynchronously in declaration order.
 The `exec` function ensures shell commands within each task run in parallel.
 */

desc('Run test task.');
task('default', ['test']);

desc('compile, jslint, test, tslint, build-gh-pages, validate-html.');
task('build', ['test', 'tslint', 'build-gh-pages', 'validate-html']);

desc('Update version number, tag and push to Github and npm. Use vers=x.y.z argument to set a new version number. Finally, rebuild and publish docs website.');
task('release', ['build', 'version', 'tag', 'publish', 'release-gh-pages']);

desc('Lint Javascript and JSON files.');
task('jslint', {async: true}, function() {
  var commands = TESTS.concat([RIMUC]).map(function(file) {
    return 'jshint ' + file;
  });
  commands.push('jsonlint --quiet package.json');
  exec(commands, complete);
});

desc('Lint TypeScript source files.');
task('tslint', {async: true}, function() {
  var commands = SOURCE.map(function(file) {
    return 'tslint ' + file;
  });
  exec(commands, complete);
});

desc('Run tests (recompile if necessary).');
task('test', ['compile', 'jslint'], {async: true}, function() {
  var commands = TESTS.map(function(file) {
    return 'tape ' + file + ' | faucet';
  });
  exec(commands, complete);
});

desc('Compile Typescript to JavaScript then bundle CommonJS and scriptable libraries.');
task('compile', [RIMU_LIB]);

file(RIMU_LIB, [MAIN_TS], {async: true}, function() {
  exec('webpack -d', complete);
});

file(RIMU_LIB_MIN, [MAIN_TS], {async: true}, function() {
  exec('webpack -p --output-filename ' + RIMU_LIB_MIN, function () {
    // Prepend package name and version.
    var preamble = '/* ' + pkg.name + ' ' + pkg.version + ' (' + pkg.repository.url + ') */\n';
    (preamble + shelljs.cat(RIMU_LIB_MIN)).to(RIMU_LIB_MIN);
    complete();
  });
});

desc('Generate HTML documentation');
task('html-docs', [RIMU_LIB_MIN], {async: true}, function() {
  var commands = DOCS.map(function(doc) {
    return 'node ' + RIMUC +
      ' --styled --lint --no-rimurc' +
      ' --output "' + doc.dst + '"' +
      ' --title "' + doc.title + '"' +
      ' ' + doc.rimucOptions + ' ' +
      ' ./examples/.rimurc ./doc/doc-header.rmu ' + doc.src;
  });
  exec(commands, complete);
});

desc('Validate HTML documents with W3C Validator.');
task('validate-html', {async: true}, function() {
  var commands = HTML.map(function(file) {
    return 'nu-html-checker ' + file;
  });
  exec(commands, complete);
});

desc('Display or update the project version number. Use vers=x.y.z argument to set a new version number.');
task('version', {async: true}, function() {
  var version = process.env.vers;
  if (!version) {
    console.log('\nversion: ' + pkg.version);
    complete();
  }
  else {
    if (!version.match(/^\d+\.\d+\.\d+$/)) {
      fail('Invalid version number: ' + version + '\n');
    }
    shelljs.sed('-i', /(\n\s*"version"\s*:\s*)"\d+\.\d+\.\d+"/, '$1' + '"' + version + '"', 'package.json');
    pkg.version = version;
    exec('git commit -m "Bump version number." package.json', complete);
  }
});

desc('Create tag ' + pkg.version);
task('tag', ['test'], {async: true}, function() {
  exec('git tag -a -m "Tag ' + pkg.version + '" ' + pkg.version, complete);
});

desc('Commit changes to local Git repo.');
task('commit', ['test'], {async: true}, function() {
  jake.exec('git commit -a', {interactive: true}, complete);
});

desc('push, publish-npm.');
task('publish', ['push', 'publish-npm']);

desc('Push local commits to Github.');
task('push', ['test'], {async: true}, function() {
  exec('git push -u --tags origin master', complete);
});

desc('Publish to npm.');
task('publish-npm', {async: true}, ['test', RIMU_LIB_MIN], function() {
  exec('npm publish', complete);
});

desc('Rebuild and validate documentation then commit and publish to GitHub Pages');
task('release-gh-pages', ['build-gh-pages', 'commit-gh-pages', 'push-gh-pages']);

desc('Generate documentation and copy to local gh-pages repo');
task('build-gh-pages', ['html-docs', 'validate-html'], function() {
  shelljs.cp('-f', HTML.concat(RIMU_LIB_MIN), GH_PAGES_DIR)
});

desc('Commit changes to local gh-pages repo. Use msg=\'commit message\' to set a custom commit message.');
task('commit-gh-pages', ['test'], {async: true}, function() {
  var msg = process.env.msg;
  if (!msg) {
    msg = 'rebuilt project website';
  }
  shelljs.cd(GH_PAGES_DIR);
  exec('git commit -a -m "' + msg + '"', function () {
    shelljs.cd('..');
    complete();
  });
});

desc('Push gh-pages commits to Github.');
task('push-gh-pages', ['test'], {async: true}, function() {
  shelljs.cd(GH_PAGES_DIR);
  exec('git push origin gh-pages', function () {
    shelljs.cd('..');
    complete();
  });
});
<commit_msg>refactor: Update Jakefile with node 4 ES6 features.<commit_after>/*
 * Jakefile for Rimu Markup (http://github.com/srackham/rimu).
 */
'use strict';

let pkg = require('./package.json');
let shelljs = require('shelljs');
let child_process = require('child_process');

/* Inputs and outputs */

let RIMU_LIB = 'bin/rimu.js';
let RIMU_LIB_MIN = 'bin/rimu.min.js';
let MAIN_TS = 'src/main.ts';
let SOURCE = shelljs.ls('src/*.ts');
let TESTS = shelljs.ls('test/*.js');
let GH_PAGES_DIR = './gh-pages/';
let RIMUC = './bin/rimuc.js';

let DOCS = [
  {
    src: 'README.md', dst: 'doc/index.html', title: 'Rimu Markup',
    rimucOptions: '--toc'
  },
  {
    src: 'CHANGELOG.md', dst: 'doc/CHANGELOG.html', title: 'Rimu Change Log',
    rimucOptions: '--toc'
  },
  {
    src: 'doc/reference.rmu', dst: 'doc/reference.html', title: 'Rimu Reference',
    rimucOptions: '--toc --prepend "{generate-examples}=\'yes\'"'
  },
  {
    src: 'doc/tips.rmu', dst: 'doc/tips.html', title: 'Rimu Tips',
    rimucOptions: '--toc --prepend "{generate-examples}=\'yes\'"'
  },
  {
    src: 'doc/rimuplayground.rmu', dst: 'doc/rimuplayground.html', title: 'Rimu Playground',
    rimucOptions: '--toc --prepend "{generate-examples}=\'yes\'"'
  }
];

let HTML = DOCS.map(doc => doc.dst)

/* Utility functions. */

/*
 Execute shell commands in parallel then run the `callback` when they have all finished.
 Abort if an error occurs.
 Write command output to the inherited stdout (unless the Jake --quiet option is set).
 Print a status message when each command starts and finishes (unless the Jake --quiet option is set).

 NOTE: This function is similar to the built-in jake.exec function but is twice as fast.
 */
function exec(commands, callback) {
  if (typeof commands === 'string') {
    commands = [commands];
  }
  let remaining = commands.length;
  if (remaining === 0) {
    callback();
  }
  else {
    commands.forEach(command => {
      jake.logger.log('Starting: ' + command);
      child_process.exec(command, function(error, stdout, stderr) {
        if (!jake.program.opts.quiet) {
          process.stdout.write(stdout);
        }
        if (error !== null) {
          fail(error, error.code);
        }
        jake.logger.log('Finished: ' + command);
        remaining--;
        if (remaining === 0) {
          callback();
        }
      });
    });
  }
}

/*
 Tasks

 All tasks are synchronous (another task will not run until the current task has completed).
 Consequently all task dependencies are executed asynchronously in declaration order.
 The `exec` function ensures shell commands within each task run in parallel.
 */

desc(`Run test task.`);
task('default', ['test']);

desc(`compile, jslint, test, tslint, build-gh-pages, validate-html.`);
task('build', ['test', 'tslint', 'build-gh-pages', 'validate-html']);

desc(`Update version number, tag and push to Github and npm. Use vers=x.y.z argument to set a new version number. Finally, rebuild and publish docs website.`);
task('release', ['build', 'version', 'tag', 'publish', 'release-gh-pages']);

desc(`Lint Javascript and JSON files.`);
task('jslint', {async: true}, function() {
  let commands = TESTS.concat([RIMUC]).map(function(file) {
    return 'jshint ' + file;
  });
  commands.push('jsonlint --quiet package.json');
  exec(commands, complete);
});

desc(`Lint TypeScript source files.`);
task('tslint', {async: true}, function() {
  let commands = SOURCE.map(file => 'tslint ' + file)
  exec(commands, complete);
});

desc(`Run tests (recompile if necessary).`);
task('test', ['compile', 'jslint'], {async: true}, function() {
  let commands = TESTS.map(file => 'tape ' + file + ' | faucet')
  exec(commands, complete);
});

desc(`Compile Typescript to JavaScript then bundle CommonJS and scriptable libraries.`);
task('compile', [RIMU_LIB]);

file(RIMU_LIB, [MAIN_TS], {async: true}, function() {
  exec('webpack -d', complete);
});

file(RIMU_LIB_MIN, [MAIN_TS], {async: true}, function() {
  exec('webpack -p --output-filename ' + RIMU_LIB_MIN, function () {
    // Prepend package name and version.
    let preamble = `/* ${pkg.name} ${pkg.version} (${pkg.repository.url}) */\n`;
    (preamble + shelljs.cat(RIMU_LIB_MIN)).to(RIMU_LIB_MIN);
    complete();
  });
});

desc(`Generate HTML documentation`);
task('html-docs', [RIMU_LIB_MIN], {async: true}, function() {
  let commands = DOCS.map(doc =>
      'node ' + RIMUC +
      ' --styled --lint --no-rimurc' +
      ' --output "' + doc.dst + '"' +
      ' --title "' + doc.title + '"' +
      ' ' + doc.rimucOptions + ' ' +
      ' ./examples/.rimurc ./doc/doc-header.rmu ' + doc.src
  )
  exec(commands, complete);
});

desc(`Validate HTML documents with W3C Validator.`);
task('validate-html', {async: true}, function() {
  let commands = HTML.map(file => 'nu-html-checker ' + file)
  exec(commands, complete);
});

desc(`Display or update the project version number. Use vers=x.y.z argument to set a new version number.`);
task('version', {async: true}, function() {
  let version = process.env.vers;
  if (!version) {
    console.log(`version: ${pkg.version}`);
    complete();
  }
  else {
    if (!version.match(/^\d+\.\d+\.\d+$/)) {
      fail('Invalid version number: ' + version + '\n');
    }
    shelljs.sed('-i', /(\n\s*"version"\s*:\s*)"\d+\.\d+\.\d+"/, `$1"${version}"`, 'package.json');
    pkg.version = version;
    exec('git commit -m "Bump version number." package.json', complete);
  }
});

desc(`Create tag ${pkg.version}`)
task('tag', ['test'], {async: true}, function() {
  exec('git tag -a -m "Tag ' + pkg.version + '" ' + pkg.version, complete);
});

desc(`Commit changes to local Git repo.`);
task('commit', ['test'], {async: true}, function() {
  jake.exec('git commit -a', {interactive: true}, complete);
});

desc(`push, publish-npm.`);
task('publish', ['push', 'publish-npm']);

desc(`Push local commits to Github.`);
task('push', ['test'], {async: true}, function() {
  exec('git push -u --tags origin master', complete);
});

desc(`Publish to npm.`);
task('publish-npm', {async: true}, ['test', RIMU_LIB_MIN], function() {
  exec('npm publish', complete);
});

desc(`Rebuild and validate documentation then commit and publish to GitHub Pages`);
task('release-gh-pages', ['build-gh-pages', 'commit-gh-pages', 'push-gh-pages']);

desc(`Generate documentation and copy to local gh-pages repo`);
task('build-gh-pages', ['html-docs', 'validate-html'], function() {
  shelljs.cp('-f', HTML.concat(RIMU_LIB_MIN), GH_PAGES_DIR)
});

desc(`Commit changes to local gh-pages repo. Use msg='commit message' to set a custom commit message.`)
task('commit-gh-pages', ['test'], {async: true}, function() {
  let msg = process.env.msg;
  if (!msg) {
    msg = 'rebuilt project website';
  }
  shelljs.cd(GH_PAGES_DIR);
  exec('git commit -a -m "' + msg + '"', function () {
    shelljs.cd('..');
    complete();
  });
});

desc(`Push gh-pages commits to Github.`);
task('push-gh-pages', ['test'], {async: true}, function() {
  shelljs.cd(GH_PAGES_DIR);
  exec('git push origin gh-pages', function () {
    shelljs.cd('..');
    complete();
  });
});
<|endoftext|>


<commit_before>(function () { "use strict";

function parentPath(x) { return x.match(/(\/[\w_-]+)+\/[\w_-]+$/)[1]; }

var _ = require('underscore');
var util = require('util');
var assert = require('assert');

function SchoolsDB (db, config) {
	this.db = db;
	this.cfg = config;
}
util.inherits(SchoolsDB, require('./objects.js').DBSubsystemBase);

function adminlistContainsUser(admins, user) {
	return _.chain(admins).filter(function(a) { return a.status == 'admin' && a.adminid == user.id; }).value().length == 0;
}

function _reqschooladm (f, soft, scdb) {
	var soft = soft || false;

	return function(query, user, access, cb) {
		(parseInt(query.schoolid) == query.schoolid ? function(cont) { cont(); } : _.bind(function(cont) {
			var dbquery = null;
			if (this && this.query) dbquery = _.bind(this.query, this);
			if (scdb && scdb.query) dbquery = _.bind(scdb.query, scdb);

			assert.ok(dbquery);

			dbquery('SELECT id FROM schools WHERE ? IN (id, name, path)', [query.schoolid], function(res) {
				if (res.length == 0)
					query.schoolid = null;
				else
					query.schoolid = res[0].id;

				cont();
			});
		}, this))(_.bind(function() {
			var forward = _.bind(function() { return _.bind(f, this)(query, user, access, cb); }, this);
			if (access.has('schooldb') || (soft && !query.schoolid))
				return forward();

			var lsa = null;
			if (this && this.loadSchoolAdmins) lsa = _.bind(this.loadSchoolAdmins, this);
			if (scdb && scdb.loadSchoolAdmins) lsa = _.bind(scdb.loadSchoolAdmins, scdb);

			assert.ok(lsa);

			lsa(query.schoolid, function(adminlist) {
				if (adminlistContainsUser(adminlist, user))
					cb('permission-denied');
				else
					forward();
			});
		}, this));
	};
}

// only internal
SchoolsDB.prototype.loadSchoolAdmins = function(schoolid, cb) {
	this.query('SELECT sa.schoolid AS schoolid, sa.uid AS adminid, sa.status AS status, users.name AS adminname ' +
		'FROM schools AS c ' +
		'JOIN schools AS p ON c.path LIKE CONCAT(p.path, "%") OR p.id = c.id ' +
		'JOIN schooladmins AS sa ON sa.schoolid = p.id ' +
		'JOIN users ON users.id = sa.uid ' +
		'WHERE c.id = ?', [schoolid], cb);
};

SchoolsDB.prototype.loadSchoolInfo = function(lookfor, user, access, cb) {
	this.query('SELECT schools.id, schools.name, schools.path, descpage, config, eventid, type, targetid, time, srcuser, url AS banner FROM schools ' +
		'LEFT JOIN events ON events.targetid = schools.id AND events.type = "school-create" ' +
		'LEFT JOIN httpresources ON httpresources.groupassoc = schools.id AND httpresources.role = "schools.banner" ' +
		'WHERE ? IN (schools.id, schools.path, schools.name) ' +
		'LIMIT 1', [lookfor], function(res) {
		if (res.length == 0)
			return cb('get-school-info-notfound');

		var s = res[0];
		s.parentPath = null;

		assert.ok(s.eventid);

		if (s.config == '')
			s.config = {};
		else
			s.config = JSON.parse(s.config);

		assert.ok(s.config);

		this.loadSchoolAdmins(s.id, function(admins) {
			s.admins = admins;

			this.query('SELECT * FROM schools AS c WHERE c.path LIKE ?', [s.path + '/%'], function(subschools) {
			this.query('SELECT c.*,u.name AS username,u.id AS uid, url AS profilepic, trustedhtml ' +
				'FROM ecomments AS c '+
				'LEFT JOIN users AS u ON c.commenter = u.id ' +
				'LEFT JOIN httpresources ON httpresources.user = c.commenter AND httpresources.role = "profile.image" '+
				'WHERE c.eventid = ?',
				[s.eventid],
				function(comments) {
				s.comments = comments;
				s.subschools = subschools;

				this.query('SELECT oh.stocktextid AS stockid, oh.stockname, ' +
					'SUM(ABS(money)) AS moneysum, ' +
					'SUM(ABS(money) / (UNIX_TIMESTAMP() - buytime)) AS wsum ' +
					'FROM orderhistory AS oh ' +
					'JOIN schoolmembers AS sm ON sm.uid = oh.userid AND sm.jointime < oh.buytime AND sm.schoolid = ? ' +
					'GROUP BY stocktextid ORDER BY wsum DESC LIMIT 10', [s.id], function(popular) {
					if (s.path.replace(/[^\/]/g, '').length != 1) { // need higher-level
						s.parentPath = parentPath(s.path);
						this.loadSchoolInfo(s.parentPath, user, access, _.bind(function(code, result) {
							assert.equal(code, 'get-school-info-success');

							s.parentSchool = result;

							s.config = _.defaults(s.config, s.parentSchool.config, this.cfg.schoolConfigDefaults);

							cb('get-school-info-success', s);
						}, this));
					} else {
						s.config = _.defaults(s.config, this.cfg.schoolConfigDefaults);

						cb('get-school-info-success', s);
					}
				});
			});
			});
		});
	});
};

SchoolsDB.prototype.getSchoolInfo = function(query, user, access, cb) {
	this.loadSchoolInfo(query.lookfor, user, access, cb);
};

SchoolsDB.prototype.changeDescription = _reqschooladm(function(query, user, access, cb) {
	this.query('UPDATE schools SET descpage = ? WHERE id = ?', [query.descpage, query.schoolid], function() {
		cb('school-change-description-success');
	});
});

SchoolsDB.prototype.changeMemberStatus = _reqschooladm(function(query, user, access, cb) {
	this.query('UPDATE schoolmembers SET pending = 0 WHERE schoolid = ? AND uid = ?', [query.schoolid, query.uid], function() {
		if (query.newstatus == 'member') {
			this.query('DELETE FROM schooladmins WHERE uid = ? AND schoolid = ?', [query.uid, query.schoolid], function() {
				cb('school-change-member-status-success');
			});
		} else {
			this.query('REPLACE INTO schooladmins (schoolid, uid, status) VALUES(?, ?, ?)', [query.schoolid, query.uid, query.status], function() {
				cb('school-change-member-status-success');
			});
		}
	});
});

SchoolsDB.prototype.deleteComment = _reqschooladm(function(query, user, access, cb) {
	this.query('SELECT c.commentid AS cid FROM ecomments AS c ' +
		'JOIN events AS e ON e.eventid = c.eventid ' +
		'WHERE c.commentid = ? AND e.targetid = ? AND e.type = "school-create"',
		[query.commentid, query.schoolid], function(res) {
		if (res.length == 0)
			return cb('permission-denied');

		assert.ok(res.length == 1 && res[0].cid == query.commentid);

		this.query('UPDATE ecomments SET comment = ?, trustedhtml = 1 WHERE commentid = ?',
			['Dieser Kommentar wurde durch die Gruppenadministratoren gelöscht.', query.commentid], function() {
			cb('school-delete-comment-success');
		});
	});
});

SchoolsDB.prototype.kickUser = _reqschooladm(function(query, user, access, cb) {
	this.query('DELETE FROM schoolmembers WHERE uid = ? AND schoolid = ?',
		[query.uid, query.schoolid], function() {
		this.query('DELETE FROM schooladmins WHERE uid = ? AND schoolid = ?',
			[query.uid, query.schoolid], function() {
			cb('school-kick-user-success');
		});
	});
});

SchoolsDB.prototype.createSchool = function(query, user, access, cb_) {
	if (!query.schoolpath)
		query.schoolpath = '/' + query.schoolname.replace(/[^\w_-]/g, '');

	this.locked(['userdb'], cb_, function(cb) {
		this.query('SELECT COUNT(*) AS c FROM schools WHERE path = ?', [query.schoolpath], function(r) {
			assert.equal(r.length, 1);
			if (r[0].c == 1 || !query.schoolname.trim() ||
				!/^(\/[\w_-]+)+$/.test(query.schoolpath)) {
				return cb('create-school-already-exists');
			}

			var createCB = _.bind(function() {
				this.query('INSERT INTO schools (name,path) VALUES(?,?)', [query.schoolname,query.schoolpath], function(res) {
					this.feed({'type': 'school-create', 'targetid': res.insertId, 'srcuser': user.id});

					cb('create-school-success');
				});
			}, this);

			if (query.schoolpath.replace(/[^\/]/g, '').length == 1)
				createCB();
			else this.query('SELECT COUNT(*) AS c FROM schools WHERE path = ?', [parentPath(query.schoolpath)], function(r) {
				assert.equal(r.length, 1);
				if (r[0].c != 1)
					return cb('create-school-missing-parent');

				createCB();
			});
		});
	});
};

SchoolsDB.prototype.listSchools = function(query, user, access, cb) {
	var where = '';
	var params = [];
	if (query.parentPath) {
		where = 'WHERE path LIKE ? OR path = ? ';
		params = params.concat([query.parentPath + '/%', query.parentPath]);
	}

	this.query('SELECT schools.id, schools.name, COUNT(sm.uid) AS usercount, schools.path FROM schools ' +
		'LEFT JOIN schoolmembers AS sm ON sm.schoolid=schools.id AND NOT pending ' +
		where +
		'GROUP BY schools.id', params, cb);
}

SchoolsDB.prototype.publishBanner = function(query, user, access, FileStorageDB, cb) {
	query.__groupassoc__ = query.schoolid;
	query.role = 'schools.banner';

	_reqschooladm(_.bind(FileStorageDB.publish, FileStorageDB), false, this)(query, user, access, cb);
};

SchoolsDB.prototype.createInviteLink = function(query, user, access, UserDB, cb) {
	_reqschooladm(_.bind(UserDB.createInviteLink, UserDB), true, this)(query, user, access, cb);
};

exports.SchoolsDB = SchoolsDB;

})();
<commit_msg><commit_after>(function () { "use strict";

function parentPath(x) { return x.match(/(\/[\w_-]+)+\/[\w_-]+$/)[1]; }

var _ = require('underscore');
var util = require('util');
var assert = require('assert');

function SchoolsDB (db, config) {
	this.db = db;
	this.cfg = config;
}
util.inherits(SchoolsDB, require('./objects.js').DBSubsystemBase);

function adminlistContainsUser(admins, user) {
	return _.chain(admins).filter(function(a) { return a.status == 'admin' && a.adminid == user.id; }).value().length == 0;
}

function _reqschooladm (f, soft, scdb) {
	var soft = soft || false;

	return function(query, user, access, cb) {
		(parseInt(query.schoolid) == query.schoolid ? function(cont) { cont(); } : _.bind(function(cont) {
			var dbquery = null;
			if (this && this.query) dbquery = _.bind(this.query, this);
			if (scdb && scdb.query) dbquery = _.bind(scdb.query, scdb);

			assert.ok(dbquery);

			dbquery('SELECT id FROM schools WHERE ? IN (id, name, path)', [query.schoolid], function(res) {
				if (res.length == 0)
					query.schoolid = null;
				else
					query.schoolid = res[0].id;

				cont();
			});
		}, this))(_.bind(function() {
			var forward = _.bind(function() { return _.bind(f, this)(query, user, access, cb); }, this);
			if (access.has('schooldb') || (soft && !query.schoolid))
				return forward();

			var lsa = null;
			if (this && this.loadSchoolAdmins) lsa = _.bind(this.loadSchoolAdmins, this);
			if (scdb && scdb.loadSchoolAdmins) lsa = _.bind(scdb.loadSchoolAdmins, scdb);

			assert.ok(lsa);

			lsa(query.schoolid, function(adminlist) {
				if (adminlistContainsUser(adminlist, user))
					cb('permission-denied');
				else
					forward();
			});
		}, this));
	};
}

// only internal
SchoolsDB.prototype.loadSchoolAdmins = function(schoolid, cb) {
	this.query('SELECT sa.schoolid AS schoolid, sa.uid AS adminid, sa.status AS status, users.name AS adminname ' +
		'FROM schools AS c ' +
		'JOIN schools AS p ON c.path LIKE CONCAT(p.path, "%") OR p.id = c.id ' +
		'JOIN schooladmins AS sa ON sa.schoolid = p.id ' +
		'JOIN users ON users.id = sa.uid ' +
		'WHERE c.id = ?', [schoolid], cb);
};

SchoolsDB.prototype.loadSchoolInfo = function(lookfor, user, access, cb) {
	this.query('SELECT schools.id, schools.name, schools.path, descpage, config, eventid, type, targetid, time, srcuser, url AS banner FROM schools ' +
		'LEFT JOIN events ON events.targetid = schools.id AND events.type = "school-create" ' +
		'LEFT JOIN httpresources ON httpresources.groupassoc = schools.id AND httpresources.role = "schools.banner" ' +
		'WHERE ? IN (schools.id, schools.path, schools.name) ' +
		'LIMIT 1', [lookfor], function(res) {
		if (res.length == 0)
			return cb('get-school-info-notfound');

		var s = res[0];
		s.parentPath = null;

		assert.ok(s.eventid);

		if (s.config == '')
			s.config = {};
		else
			s.config = JSON.parse(s.config);

		assert.ok(s.config);

		this.loadSchoolAdmins(s.id, function(admins) {
			s.admins = admins;

			this.query('SELECT * FROM schools AS c WHERE c.path LIKE ?', [s.path + '/%'], function(subschools) {
			this.query('SELECT c.*,u.name AS username,u.id AS uid, url AS profilepic, trustedhtml ' +
				'FROM ecomments AS c '+
				'LEFT JOIN users AS u ON c.commenter = u.id ' +
				'LEFT JOIN httpresources ON httpresources.user = c.commenter AND httpresources.role = "profile.image" '+
				'WHERE c.eventid = ?',
				[s.eventid],
				function(comments) {
				s.comments = comments;
				s.subschools = subschools;

				this.query('SELECT oh.stocktextid AS stockid, oh.stockname, ' +
					'SUM(ABS(money)) AS moneysum, ' +
					'SUM(ABS(money) / (UNIX_TIMESTAMP() - buytime)) AS wsum ' +
					'FROM orderhistory AS oh ' +
					'JOIN schoolmembers AS sm ON sm.uid = oh.userid AND sm.jointime < oh.buytime AND sm.schoolid = ? ' +
					'GROUP BY stocktextid ORDER BY wsum DESC LIMIT 10', [s.id], function(popular) {
					if (s.path.replace(/[^\/]/g, '').length != 1) { // need higher-level
						s.parentPath = parentPath(s.path);
						this.loadSchoolInfo(s.parentPath, user, access, _.bind(function(code, result) {
							assert.equal(code, 'get-school-info-success');

							s.parentSchool = result;

							s.config = _.defaults(s.config, s.parentSchool.config, this.cfg.schoolConfigDefaults);

							cb('get-school-info-success', s);
						}, this));
					} else {
						s.config = _.defaults(s.config, this.cfg.schoolConfigDefaults);

						cb('get-school-info-success', s);
					}
				});
			});
			});
		});
	});
};

SchoolsDB.prototype.getSchoolInfo = function(query, user, access, cb) {
	this.loadSchoolInfo(query.lookfor, user, access, cb);
};

SchoolsDB.prototype.changeDescription = _reqschooladm(function(query, user, access, cb) {
	this.query('UPDATE schools SET descpage = ? WHERE id = ?', [query.descpage, query.schoolid], function() {
		cb('school-change-description-success');
	});
});

SchoolsDB.prototype.changeMemberStatus = _reqschooladm(function(query, user, access, cb) {
	this.query('UPDATE schoolmembers SET pending = 0 WHERE schoolid = ? AND uid = ?', [query.schoolid, query.uid], function() {
		if (query.status == 'member') {
			this.query('DELETE FROM schooladmins WHERE uid = ? AND schoolid = ?', [query.uid, query.schoolid], function() {
				cb('school-change-member-status-success');
			});
		} else {
			this.query('REPLACE INTO schooladmins (schoolid, uid, status) VALUES(?, ?, ?)', [query.schoolid, query.uid, query.status], function() {
				cb('school-change-member-status-success');
			});
		}
	});
});

SchoolsDB.prototype.deleteComment = _reqschooladm(function(query, user, access, cb) {
	this.query('SELECT c.commentid AS cid FROM ecomments AS c ' +
		'JOIN events AS e ON e.eventid = c.eventid ' +
		'WHERE c.commentid = ? AND e.targetid = ? AND e.type = "school-create"',
		[query.commentid, query.schoolid], function(res) {
		if (res.length == 0)
			return cb('permission-denied');

		assert.ok(res.length == 1 && res[0].cid == query.commentid);

		this.query('UPDATE ecomments SET comment = ?, trustedhtml = 1 WHERE commentid = ?',
			['Dieser Kommentar wurde durch die Gruppenadministratoren gelöscht.', query.commentid], function() {
			cb('school-delete-comment-success');
		});
	});
});

SchoolsDB.prototype.kickUser = _reqschooladm(function(query, user, access, cb) {
	this.query('DELETE FROM schoolmembers WHERE uid = ? AND schoolid = ?',
		[query.uid, query.schoolid], function() {
		this.query('DELETE FROM schooladmins WHERE uid = ? AND schoolid = ?',
			[query.uid, query.schoolid], function() {
			cb('school-kick-user-success');
		});
	});
});

SchoolsDB.prototype.createSchool = function(query, user, access, cb_) {
	if (!query.schoolpath)
		query.schoolpath = '/' + query.schoolname.replace(/[^\w_-]/g, '');

	this.locked(['userdb'], cb_, function(cb) {
		this.query('SELECT COUNT(*) AS c FROM schools WHERE path = ?', [query.schoolpath], function(r) {
			assert.equal(r.length, 1);
			if (r[0].c == 1 || !query.schoolname.trim() ||
				!/^(\/[\w_-]+)+$/.test(query.schoolpath)) {
				return cb('create-school-already-exists');
			}

			var createCB = _.bind(function() {
				this.query('INSERT INTO schools (name,path) VALUES(?,?)', [query.schoolname,query.schoolpath], function(res) {
					this.feed({'type': 'school-create', 'targetid': res.insertId, 'srcuser': user.id});

					cb('create-school-success');
				});
			}, this);

			if (query.schoolpath.replace(/[^\/]/g, '').length == 1)
				createCB();
			else this.query('SELECT COUNT(*) AS c FROM schools WHERE path = ?', [parentPath(query.schoolpath)], function(r) {
				assert.equal(r.length, 1);
				if (r[0].c != 1)
					return cb('create-school-missing-parent');

				createCB();
			});
		});
	});
};

SchoolsDB.prototype.listSchools = function(query, user, access, cb) {
	var where = '';
	var params = [];
	if (query.parentPath) {
		where = 'WHERE path LIKE ? OR path = ? ';
		params = params.concat([query.parentPath + '/%', query.parentPath]);
	}

	this.query('SELECT schools.id, schools.name, COUNT(sm.uid) AS usercount, schools.path FROM schools ' +
		'LEFT JOIN schoolmembers AS sm ON sm.schoolid=schools.id AND NOT pending ' +
		where +
		'GROUP BY schools.id', params, cb);
}

SchoolsDB.prototype.publishBanner = function(query, user, access, FileStorageDB, cb) {
	query.__groupassoc__ = query.schoolid;
	query.role = 'schools.banner';

	_reqschooladm(_.bind(FileStorageDB.publish, FileStorageDB), false, this)(query, user, access, cb);
};

SchoolsDB.prototype.createInviteLink = function(query, user, access, UserDB, cb) {
	_reqschooladm(_.bind(UserDB.createInviteLink, UserDB), true, this)(query, user, access, cb);
};

exports.SchoolsDB = SchoolsDB;

})();
<|endoftext|>


<commit_before>const ConnectionFactory = require('./factories/connectionFactory.js')
const RustListeners = require('./listeners/rustListeners.js')
const Redis = require('redis')

class Androgee {
  constructor () {
    // Establish a connection to Redis and setup error handling
    this.redis = Redis.createClient({host: 'redis'})

    this.redis.on("error", function (err) {
      console.log("Error " + err);
    })

    // Maintain references to open connections
    this.rustConnection = this.connectRust()

    // Flush Redis and begin our loops
    this.refreshRedis(this)
    setInterval(this.refreshRedis, 3600000, this)
    setInterval(this.minecraftRequestLoop, 60000, this)
  }

  // Flush and refresh Redis
  refreshRedis (self) {
    let existingPlayers = 'There are 0/20 players online:'
    self.redis.get('minecraftPlayers', (err, reply) => {
      if (!err) {
        if (reply !== undefined) { existingPlayers = reply }
        self.redis.flushall((err) => {
          if (!err) {
            console.log('Redis flushed.')
          } else {
            console.log('Failed to flush Redis: ' + err)
          }
        })
        self.redis.set('minecraftPlayers', existingPlayers)
      } else {
        console.log('Failed to reset Minecraft players in Redis: ' + err)
      }
    })
  }

  // Get player list from Minecraft
  minecraftRequestLoop (self) {
    self.redis.get('minecraftPlayers', (err, reply) => {
      if (!err) {
        const diff = require('fast-diff')
        const client = new ConnectionFactory('moddedMinecraft').exec('list', (res) => {
          if (res.body.length > reply.length) {
            var playerListDif = diff(res.body, reply)
            try {
              if (playerListDif.length >= 4) {
                var newPlayers = playerListDif[4][1]
                if (newPlayers.startsWith(',')) {
                  newPlayers = newPlayers.slice(2)
                }
                let msg = 'The following player(s) have joined: ' + '``' + newPlayers + '``'
                console.log(msg)
                self.redis.publish('newMinecraftPlayers', msg)
              }
            } catch (err) {
              console.log('The diff function failed: ' + err)
            }
          }
          self.redis.set('minecraftPlayers', res.body)
        }).connect()
        client.on('error', function (err) {
          console.log(err)
        })
      } else {
        console.log('Minecraft list loop errored out: ' + err)
      }
    })
  }

  connectRust () {
    const connection = new RustListeners(new ConnectionFactory('rust'), this)
    return connection
  }
}
module.exports = Androgee
<commit_msg>error handling<commit_after>const ConnectionFactory = require('./factories/connectionFactory.js')
const RustListeners = require('./listeners/rustListeners.js')
const Redis = require('redis')

class Androgee {
  constructor () {
    // Establish a connection to Redis and setup error handling
    this.redis = Redis.createClient({host: 'localhost'})
    var rustSub = Redis.createClient({host: 'localhost'})

    this.redis.on('error', function (err) {
      console.log("this.redis " + err);
    })

    rustSub.on('error', function (err) {
      console.log("rustSub " + err);
    })

    rustSub.subscribe('RustCommands')
    rustSub.on('message', (channel, message) => {
      this.rustConnection.setTime(message)
    })

    // Maintain references to open connections
    this.rustConnection = this.connectRust()

    // Flush Redis and begin our loops
    this.refreshRedis(this)
    setInterval(this.refreshRedis, 3600000, this)
    setInterval(this.minecraftRequestLoop, 60000, this)
  }

  // Flush and refresh Redis
  refreshRedis (self) {
    let existingPlayers = 'There are 0/20 players online:'
    self.redis.get('minecraftPlayers', (err, reply) => {
      if (!err) {
        if (reply !== undefined) { existingPlayers = reply }
        self.redis.flushall((err) => {
          if (!err) {
            console.log('Redis flushed.')
          } else {
            console.log('Failed to flush Redis: ' + err)
          }
        })
        self.redis.set('minecraftPlayers', existingPlayers)
      } else {
        console.log('Failed to reset Minecraft players in Redis: ' + err)
      }
    })
  }

  // Get player list from Minecraft
  minecraftRequestLoop (self) {
    self.redis.get('minecraftPlayers', (err, reply) => {
      if (!err) {
        const diff = require('fast-diff')
        const client = new ConnectionFactory('moddedMinecraft').exec('list', (res) => {
          if (res.body.length > reply.length) {
            var playerListDif = diff(res.body, reply)
            try {
              if (playerListDif.length >= 4) {
                var newPlayers = playerListDif[4][1]
                if (newPlayers.startsWith(',')) {
                  newPlayers = newPlayers.slice(2)
                }
                let msg = 'The following player(s) have joined: ' + '``' + newPlayers + '``'
                console.log(msg)
                self.redis.publish('newMinecraftPlayers', msg)
              }
            } catch (err) {
              console.log('The diff function failed: ' + err)
            }
          }
          self.redis.set('minecraftPlayers', res.body)
        }).connect()
        client.on('error', function (err) {
          console.log(err)
        })
      } else {
        console.log('Minecraft list loop errored out: ' + err)
      }
    })
  }

  connectRust () {
    const connection = new RustListeners(new ConnectionFactory('rust'), this)
    return connection
  }
}
module.exports = Androgee
<|endoftext|>