<commit_before>/**
 * @author EmmanuelOlaojo
 * @since 6/15/16
 */
var mongoose = require("mongoose");

var Lint = function(db, collection, options){
  if(!db) throw new Error("No database specified");
  if(!collection) throw new Error("No collection specified");
  if(options && Object.keys(options).length) options = cleanOptions(options);

  var self = this;
  var TaskMdl;
  collection = collection.toString();
  db = db.toString();

  mongoose.connect(db, options);
  TaskMdl = require("../models/task")(collection);
  self.Task = require("./task")(mongoose, TaskMdl);
};

function cleanOptions(options){
  if(!(options.user && options.pass)) throw new Error("options object must contain keys: 'user' && 'pass'");

  return{
    user: options.user
    , pass: options.pass
  }
}<commit_msg>Added connect function to lint<commit_after>/**
 * @author EmmanuelOlaojo
 * @since 6/15/16
 */
var mongoose = require("mongoose");

var Lint = function(){
  var lint = this;
  var TaskMdl;

  lint.connect = function(db, collection, options){
    if(!db) throw new Error("No database specified");
    if(!collection) throw new Error("No collection specified");
    if(options && Object.keys(options).length) options = cleanOptions(options);

    collection = collection.toString();
    db = db.toString();

    mongoose.connect(db, options);
    TaskMdl = require("../models/task")(collection);
    lint.Task = require("./task")(mongoose, TaskMdl);
  };
};

function cleanOptions(options){
  if(!(options.user && options.pass)) throw new Error("options object must contain keys: 'user' && 'pass'");

  return{
    user: options.user
    , pass: options.pass
  }
}

module.exports = Lint;<|endoftext|>


<commit_before>var microformats = require('microformat-node'),
    options = {};
var jade = require('jade');
var xml = require('xml');

exports.update = function (baseUrl, date, callback) {
  var url = baseUrl + date.format('YYYY-MM-DD');
  microformats.parseUrl(url, options, function (err, data) {
    if (err) callback(err);
    data.updated = date;
    data.url = url;
    jade.renderFile('./views/content.jade', {
      pretty: true,
      log: data
    }, function (err, html) {
      if (err) callback (err);
      data.encoded = xml({content: { _attr: { type:'html'}, _cdata: html }});
      callback(null, data);
    });
  });
};<commit_msg>Lets try without the pretty option<commit_after>var microformats = require('microformat-node'),
    options = {};
var jade = require('jade');
var xml = require('xml');

exports.update = function (baseUrl, date, callback) {
  var url = baseUrl + date.format('YYYY-MM-DD');
  microformats.parseUrl(url, options, function (err, data) {
    if (err) callback(err);
    data.updated = date;
    data.url = url;
    jade.renderFile('./views/content.jade', {
      pretty: false,
      log: data
    }, function (err, html) {
      if (err) callback (err);
      data.encoded = xml({content: { _attr: { type:'html'}, _cdata: html }});
      callback(null, data);
    });
  });
};<|endoftext|>


<commit_before>'use strict';

module.exports = () => function * (next) {
    try {
        yield next;
    } catch (err) {
        // If the error shouldn't be exposed, output a 500 error
        if (!err.expose) {
            this.body = { code: 'INTERNAL', message: 'Internal server error' };
            this.status = 500;
        // Normal exposed error
        } else {
            this.body = { code: err.code || 'UNSPECIFIED', message: err.message };
            this.status = err.status || 500;
        }

        // Emit the error so that it can be logged
        this.app.emit('error', err, this);
    }
};
<commit_msg>Dot not emit errors that were handled.<commit_after>'use strict';

module.exports = () => function * (next) {
    try {
        yield next;
    } catch (err) {
        // If the error shouldn't be exposed, output a 500 error
        if (!err.expose) {
            this.body = { code: 'INTERNAL', message: 'Internal server error' };
            this.status = 500;
            this.app.emit('error', err, this);  // Emit the error so that it can be logged
        // Normal exposed error
        } else {
            this.body = { code: err.code || 'UNSPECIFIED', message: err.message };
            this.status = err.status || 500;
        }
    }
};
<|endoftext|>


<commit_before>/**
 *
 * @licstart  The following is the entire license notice for the JavaScript code in this file.
 *
 * Load records into a data store while filtering, preprocessing and matching & merging them in the process
 *
 * Copyright (c) 2015 University Of Helsinki (The National Library Of Finland)
 *
 * This file is part of record-loader
 *
 * record-loader is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * @licend  The above is the entire license notice
 * for the JavaScript code in this page.
 *
 **/

/* istanbul ignore next: umd wrapper */
(function (root, factory) {

    'use strict';

    if (typeof define === 'function' && define.amd) {
        define(['es6-polyfills/lib/promise', 'loglevel', 'jjv', 'jjve', '../resources/config-schema.json'], factory);
    } else if (typeof module === 'object' && module.exports) {
        module.exports = factory(require('es6-polyfills/lib/promise'), require('loglevel'), require('jjv'), require('jjve'), require('../resources/config-schema.json'));
    }

}(this, factory));

function factory(Promise, log, jjv, jjve, schema)
{

    'use strict';

    return function(input_data, modules, config) {

	var processed_records_indices = [];
	var transaction_retries;
	var results = {
	    processed: 0,
	    skipped: 0,
	    recordStore: {
		created: 0,
		updated: 0,
		deleted: 0
	    },
	    transactions: []
	};

	function validateConfig()
	{

	    var env = jjv();
	    var je = jjve(env);
	    var errors = env.validate(schema, config, {
		useDefault: true
	    });

	    if (errors) {
		throw new Error(JSON.stringify(je(schema, config, errors), undefined, 4));
	    }

	}

	function initialise()
	{

	    function initialiseModule(module_type, is_processor) {
		if (is_processor) {
		    if (module_type in modules.processors) {

			modules.processors[module_type] = modules.processors[module_type](config.moduleParameters.processors[module_type]);

			if (module_type === 'match' || module_type === 'load') {
			    modules.processors[module_type].setRecordStore(modules.recordStore);
			}

			if (modules.converter) {
			    modules.processors[module_type].setConverter(modules.converter);
			}

		    }
		} else if (module_type in modules) {
		    modules[module_type] = modules[module_type](config.moduleParameters[module_type]);
		}
	    }

	    modules = modules === undefined ? {} : modules;
	    config = config === undefined ? {} : config;

	    try {
		validateConfig();
	    } catch (excp) {
		if (excp instanceof Object) {
		    throw new Error("Configuration doesn't validate against schema: "+JSON.stringify(excp, undefined, 2));
		} else {
		    throw excp;
		}
	    }

	    log.setLevel(config.logging.level);
	    log.debug('Configuration: '+JSON.stringify( config, null, 2 ));

	    Object.keys(modules).filter(function(key) {
		return key !== 'processors';
	    }).forEach(function(key) {
		initialiseModule(key);
	    });

	    if ('processors' in modules) {
		Object.keys(modules.processors).forEach(function(key) {
		    initialiseModule(key, 1);
		});
	    }

	}

	function processRecordSet(previous_results_or_first_run)
	{
	    log.debug('processRecordSet');
	    if (previous_results_or_first_run === undefined) {
		return Promise.resolve(results);
	    } else {
		if (typeof previous_results_or_first_run === 'object') {

		    var previous_results = Array.isArray(previous_results_or_first_run) ? previous_results_or_first_run : [previous_results_or_first_run];

		    previous_results.forEach(function(previous_result) {
			Object.keys(previous_result).forEach(function(key) {
			    if (key === 'recordStore') {
				Object.keys(previous_result.recordStore).forEach(function(record_store_key) {
				    results.recordStore[record_store_key] += previous_result.recordStore[record_store_key];
				});
			    } else if (previous_result[key]) {
				/**
				 * @internal Adds to 'processed' or 'skipped'
				 */
				results[key]++;
			    }
			});
		    });

		}

		return getRecordData().then(handleRecordData).then(processRecordSet);
	    }
	}

	function getRecordData(current)
	{
	    log.debug('getRecordData');
	    if (current) {
		return modules.recordSet.current();
	    } else {
		return modules.recordSet.next().then(function(record_data) {
		    if (record_data.data !== undefined && processed_records_indices.indexOf(record_data.index) >= 0) {
			log.debug('Skipping already processed record at index ' + record_data.index);
			return getRecordData();
		    } else {
			return record_data;
		    }
		});
	    }
	}

	function handleRecordData(record_data)
	{
	    log.debug('handleRecordData');
	    if (Array.isArray(record_data)) {
		transaction_retries = 0;
		return startRecordDataTransaction(record_data);
	    } else if (record_data.data === undefined) {
		return Promise.resolve();
	    } else {
		return processRecord(record_data);
	    }
	}

	function startRecordDataTransaction(records)
	{

	    var transaction_results = [];

	    function iterate(list)
	    {

		var record = list.shift();

		if (record === undefined) {

		    log.debug('Transaction complete');
		    modules.recordStore.toggleTransaction();

		    results.transactions.push({
			retries: transaction_retries
		    });

		    return Promise.resolve(transaction_results);

		} else {
		    return processRecord(record).then(
			function(result) {
			    transaction_results.push(result);
			    return iterate(list);
			},
			function(reason) {
			    log.info('Transaction failed');
			    if (config.processing.transaction.enableRollback) {
				return modules.recordStore.rollback().then(function() {

				    var rejection_message;

				    if (typeof config.processing.transaction.retryAfterRollback === 'boolean' && config.processing.transaction.retryAfterRollback === true || typeof config.processing.transaction.retryAfterRollback === 'number' && transaction_retries < config.processing.transaction.retryAfterRollback) {
					transaction_retries++;
					return startRecordDataTransaction(records);
				    } else {
					rejection_message = transaction_retries > 0
					    ? 'Transaction failed after ' + transaction_retries + ' retries: '
					    : 'Transaction failed: ';
					return Promise.reject(new Error(rejection_message + reason.message));
				    }

				});
			    } else {
				return Promise.reject(new Error('Transaction failed: ' + reason.message));
			    }
			}
		    );
		}
	    }

	    log.info('Starting transaction for ' + records.length + ' records');
	    modules.recordStore.toggleTransaction(1);

	    /**
	     * @todo Does this backfire if our record data is Huge?
	     */
	    return iterate(records.slice());

	}

	function processRecord(record_data, skip_setting_index_as_processed)
	{
	    log.debug('processRecord');

	    var promise;
	    var steps = ['filter', 'preprocess', 'match', 'merge', 'load'];
	    var result = {
		processed: 0,
		skipped: 0,
		recordStore: {
		    created: 0,
		    updated: 0,
		    deleted: 0
		}
	    };

	    /**
	     * 1) If step is undefined, resolve with result.
	     * 2) If no module is available, reject
	     * 3) If step is 'preprocess' and record is undefined, set skipped and resolve with result.
	     * 4) If promise is undefined, create new promise with module's run method. Otherwise and the method as thenable to the promise
	     */
	    function iterate(step)
	    {

		if (step === undefined) {

		    return promise.then(function(load_report) {

			if (!result.skipped) {
			    result.processed = 1;
			}

			if (load_report !== undefined && config.processing.target === 'load') {
			    Object.keys(load_report).forEach(function(key) {
				result.recordStore[key] = load_report[key];
			    });
			}

			if (!skip_setting_index_as_processed) {
			    processed_records_indices.push(record_data.index);
			}

			return Promise.resolve(result);

		    });

		} else if (modules.processors[step] === undefined) {

		    var error = new Error('Target processing step cannot be reached because of a invalid/undefined processor: ' + step);

		    if (!promise) {
			return Promise.reject(error);
		    } else {
			return promise.then(function() {
			    throw error;
			});
		    }
		} else if (step === 'filter') {
		    promise = modules.processors[step].run(record_data.data);
		} else if (step === 'preprocess') {

		    promise = promise.then(function(record) {
			if (record === undefined) {
			    result.skipped = 1;
			    return Promise.resolve();
			} else {
			    return modules.processors.preprocess.run(record);
			}
		    });

		} else {
		    promise = promise.then(function(value) {
			if (value) {
			    return modules.processors[step].run.apply(undefined, Array.isArray(value) ? value : [value]);
			} else {
			    return Promise.resolve();
			}
		    });
		}

		return iterate(step === config.processing.target ? undefined : steps.shift());

	    }

	    return iterate(steps.shift());

	}

	try {
	    initialise();
	    return modules.recordSet.initialise(input_data).then(function(){
		return processRecordSet(1);
	    });
	} catch (excp) {
	    return Promise.reject(excp);
	}

    };

}<commit_msg>Implement & fix various things. Implement better results handling (resultsLevel, fix #4 (Implement 'findRelatedRecords')<commit_after>/**
 *
 * @licstart  The following is the entire license notice for the JavaScript code in this file.
 *
 * Load records into a data store while filtering, preprocessing and matching & merging them in the process
 *
 * Copyright (c) 2015 University Of Helsinki (The National Library Of Finland)
 *
 * This file is part of record-loader
 *
 * record-loader is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * @licend  The above is the entire license notice
 * for the JavaScript code in this file.
 *
 **/

/* istanbul ignore next: umd wrapper */
(function(root, factory) {

    'use strict';

    if (typeof define === 'function' && define.amd) {
        define(['es6-polyfills/lib/promise', 'es6-polyfills/lib/object', 'loglevel', 'jjv', 'jjve', '../resources/config-schema.json'], factory);
    } else if (typeof module === 'object' && module.exports) {
        module.exports = factory(require('es6-polyfills/lib/promise'), require('es6-polyfills/lib/object'), require('loglevel'), require('jjv'), require('jjve'), require('../resources/config-schema.json'));
    }

}(this, factory));

function factory(Promise, Object, log, jjv, jjve, schema)
{

    'use strict';

    return function(input_data, modules, config) {

	var processed_records_indices = [];
	var transaction_retries;
	var results = {
	    processed: 0,
	    skipped: 0,
	    recordStore: {
		created: 0,
		updated: 0,
		deleted: 0
	    },
	    merged: 0,
	    transactions: []
	};

	function validateConfig()
	{

	    var env = jjv();
	    var je = jjve(env);
	    var errors = env.validate(schema, config, {
		useDefault: true
	    });

	    if (errors) {
		throw new Error(JSON.stringify(je(schema, config, errors), undefined, 4));
	    }

	}

	function initialise()
	{

	    function initialiseModule(module_type, is_processor) {
		if (is_processor) {
		    if (module_type in modules.processors) {

			modules.processors[module_type] = modules.processors[module_type](config.moduleParameters.processors[module_type]);

			if (module_type === 'match' || module_type === 'load') {
			    modules.processors[module_type].setRecordStore(modules.recordStore);
			}

			if (module_type === 'merge' || module_type === 'load') {
			    modules.processors[module_type].setResultsLevel(config.processing.resultsLevel);
			}

			if (modules.converter) {
			    modules.processors[module_type].setConverter(modules.converter);
			}

		    }
		} else if (module_type in modules) {
		    modules[module_type] = modules[module_type](config.moduleParameters[module_type]);
		}
	    }

	    modules = modules === undefined ? {} : modules;
	    config = config === undefined ? {} : config;

	    try {
		validateConfig();
	    } catch (excp) {
		throw new Error("Configuration doesn't validate against schema: "+excp.message);
	    }

//
	    (function(){
		var originalFactory = log.methodFactory;
		log.methodFactory = function (methodName, logLevel, loggerName) {

		    var rawMethod;

		    if (typeof process !== undefined && process.hasOwnProperty('stderr') && process.hasOwnProperty('stdout') && process.hasOwnProperty('stdin')) {
			methodName = 'error';
		    }

		    rawMethod = originalFactory(methodName, logLevel, loggerName);

		    return function (message) {
			rawMethod(message);
		    };
		};
	    }());
//

	    log.setLevel(config.logging.level);
	    log.debug('Configuration: '+JSON.stringify( config, null, 2 ));

	    Object.keys(modules).filter(function(key) {
		return key !== 'processors';
	    }).forEach(function(key) {
		initialiseModule(key);
	    });

	    if ('processors' in modules) {
		Object.keys(modules.processors).forEach(function(key) {
		    initialiseModule(key, 1);
		});
	    }

	}

	function processRecordSet(previous_results_or_first_run)
	{
	    log.debug('processRecordSet');
	    if (previous_results_or_first_run === undefined) {
		return Promise.resolve(results);
	    } else {
		if (typeof previous_results_or_first_run === 'object') {

		    var previous_results = Array.isArray(previous_results_or_first_run) ? previous_results_or_first_run : [previous_results_or_first_run];

		    if (config.processing.resultsLevel !== 'total' && !results.hasOwnProperty('records')) {
			results.records = [];
		    }

		    previous_results.forEach(function(previous_result) {

			var record_level_results;

			if (config.processing.resultsLevel !== 'total') {

			    record_level_results = JSON.parse(JSON.stringify(previous_result));

			    delete record_level_results.processed;
			    delete record_level_results.skipped;
			    delete record_level_results.transactions;

			    results.records.push(record_level_results);

			}

			Object.keys(previous_result).forEach(function(key) {
			    if (key === 'recordStore') {
				Object.keys(previous_result.recordStore).forEach(function(record_store_key) {
				    results.recordStore[record_store_key] += previous_result.recordStore[record_store_key].length;
				});
			    } else if (key === 'merged') {
				results.merged += previous_result.merged.length > 1 ?  previous_result.merged.length : 0;
			    } else if (previous_result[key]) {
				/**
				 * @internal Adds to 'processed' or 'skipped'
				 */
				results[key]++;
			    }
			});

		    });

		}

		return getRecordData().then(handleRecordData).then(processRecordSet);
	    }
	}

	function getRecordData()
	{
	    log.debug('getRecordData');
	    return modules.recordSet.next().then(function(record_data) {
		if (record_data !== undefined && processed_records_indices.indexOf(record_data.index) >= 0) {
		    log.debug('Skipping already processed record at index ' + record_data.index);
		    return getRecordData();
		} else {
		    return record_data;
		}
	    });
	}

	function handleRecordData(record_data)
	{
	    log.debug('handleRecordData');
	    if (record_data === undefined ) {
		return Promise.resolve();
	    } else if (Array.isArray(record_data)) {
		transaction_retries = 0;
		return startRecordDataTransaction(record_data);
	    } else {
		return processRecord(record_data);
	    }
	}

	function startRecordDataTransaction(records)
	{

	    var transaction_results = [],
	    processed_indices = [];

	    function iterate(list)
	    {

		var record = list.shift();

		if (record === undefined) {

		    log.debug('Transaction complete');
		    modules.recordStore.toggleTransaction();

		    results.transactions.push({
			retries: transaction_retries
		    });

		    Array.prototype.push.apply(processed_records_indices, processed_indices);

		    return Promise.resolve(transaction_results);

		} else {
		    return processRecord(record, 1).then(
			function(result) {
			    transaction_results.push(result);
			    processed_indices.push(record.index);
			    return iterate(list);
			},
			function(reason) {
			    log.info('Transaction failed');
			    if (config.processing.transaction.enableRollback) {
				return modules.recordStore.rollback().then(function() {

				    var rejection_message;

				    if (typeof config.processing.transaction.retryAfterRollback === 'boolean' && config.processing.transaction.retryAfterRollback === true || typeof config.processing.transaction.retryAfterRollback === 'number' && transaction_retries < config.processing.transaction.retryAfterRollback) {
					transaction_retries++;
					return startRecordDataTransaction(records);
				    } else {
					rejection_message = transaction_retries > 0
					    ? 'Transaction failed after ' + transaction_retries + ' retries: '
					    : 'Transaction failed: ';
					return Promise.reject(new Error(rejection_message + reason.message));
				    }

				});
			    } else {
				return Promise.reject(new Error('Transaction failed: ' + reason.message));
			    }
			}
		    );
		}
	    }

	    log.info('Starting transaction for ' + records.length + ' records');
	    modules.recordStore.toggleTransaction(1);

	    /**
	     * @todo Does this backfire if our record data is Huge?
	     */
	    return iterate(records.slice());

	}

	function processRecord(record_data, skip_setting_index_as_processed)
	{
	    log.debug('processRecord');

	    var promise;
	    var steps = ['filter', 'preprocess', 'match', 'merge', 'load'];
	    var result = {
		processed: 0,
		skipped: 0,
		recordStore: {
		    created: [],
		    updated: [],
		    deleted: []
		},
		merged: []
	    };

	    /**
	     * 1) If step is undefined, resolve with result.
	     * 2) If no module is available, reject
	     * 3) If step is 'preprocess' and record is undefined, set skipped and resolve with result.
	     * 4) If promise is undefined, create new promise with module's run method. Otherwise and the method as thenable to the promise
	     */
	    function iterate(step)
	    {

		if (step === undefined) {

		    return promise.then(function(value) {

			if (!result.skipped) {
			    result.processed = 1;
			}

			if (value) {
			    if (config.processing.target === 'load') {
				Object.assign(result.recordStore, value[0]);
			    } else {

				if (config.processing.resultsLevel === 'debug') {
				    result.data = value[0];
				}

				if (config.processing.target === 'merge' && value.length > 1) {
				    result.merged = value[1];
				}

			    }
			}

			if (!skip_setting_index_as_processed) {
			    processed_records_indices.push(record_data.index);
			}

			return Promise.resolve(result);

		    });

		} else if (modules.processors[step] === undefined) {

		    var error = new Error('Target processing step cannot be reached because of a invalid/undefined processor: ' + step);

		    if (!promise) {
			return Promise.reject(error);
		    } else {
			return promise.then(function() {
			    throw error;
			});
		    }
		} else if (step === 'filter') {
		    promise = modules.processors[step].run(record_data.data);
		} else if (step === 'preprocess') {

		    promise = promise.then(function(record) {
			if (record === undefined) {
			    result.skipped = 1;
			    return Promise.resolve();
			} else {
			    return modules.processors.preprocess.run(record);
			}
		    });

		} else {
		    promise = promise.then(function(value) {

			if (value) {

			    if (step === 'load') {

				if (value.length > 0) {
				    result.merged = value[1];
				}

				if (config.processing.resultsLevel === 'debug') {
				    result.data = value[0];
				}

			    }

			    return modules.processors[step].run.apply(undefined, Array.isArray(value) ? value : [value]);

			} else {
			    throw new Error("Cannot proceed to step '" + step + "' because previous processor returned undefined");
			}
		    });
		}

		return iterate(step === config.processing.target ? undefined : steps.shift());

	    }

	    return iterate(steps.shift());

	}

	try {
	    initialise();
	    return modules.recordSet.initialise(input_data, config.processing.findRelatedRecords).then(function(){
		return processRecordSet(1);
	    });
	} catch (excp) {
	    return Promise.reject(excp);
	}

    };

}<|endoftext|>


<commit_before>'use babel';

// eslint-disable-next-line import/extensions, import/no-extraneous-dependencies
import { CompositeDisposable } from 'atom';
import fs from 'fs-plus';
import path from 'path';
import * as helpers from 'atom-linter';
import rangeHelpers from './rangeHelpers';

// Local variables
const parseRegex = /(\d+):(\d+):\s(([A-Z])\d{2,3})\s+(.*)/g;

const extractRange = ({ code, message, lineNumber, colNumber, textEditor }) => {
  let result;
  const line = lineNumber - 1;
  switch (code) {
    case 'C901':
      result = rangeHelpers.tooComplex(textEditor, message, line);
      break;
    case 'F401':
      result = rangeHelpers.importedUnused(textEditor, message, line);
      break;
    case 'H201':
      // H201 - no 'except:' at least use 'except Exception:'

      // For some reason this rule marks the ":" as the location by default
      result = {
        line,
        col: colNumber - 7,
        endCol: colNumber,
      };
      break;
    case 'H501':
      result = rangeHelpers.noLocalsString(textEditor, line);
      break;
    case 'E999':
      // E999 - SyntaxError: unexpected EOF while parsing

      // Workaround for https://gitlab.com/pycqa/flake8/issues/237
      result = {
        line,
        col: colNumber - 2,
      };
      break;
    default:
      result = {
        line,
        col: colNumber - 1,
      };
      break;
  }

  if (Object.hasOwnProperty.call(result, 'endCol')) {
    return [
      [result.line, result.col],
      [result.line, result.endCol],
    ];
  }

  let range;
  try {
    range = helpers.rangeFromLineNumber(textEditor, result.line, result.col);
  } catch (e) {
    // rangeFromLineNumber encountered a problem, throw the result and report
    // to the user.
    throw result;
  }

  return range;
};

const applySubstitutions = (givenExecPath, projDir) => {
  let execPath = givenExecPath;
  const projectName = path.basename(projDir);
  execPath = execPath.replace(/\$PROJECT_NAME/i, projectName);
  execPath = execPath.replace(/\$PROJECT/i, projDir);
  const paths = execPath.split(';');
  for (let i = 0; i < paths.length; i += 1) {
    if (fs.existsSync(paths[i])) {
      return paths[i];
    }
  }
  return execPath;
};

const getVersionString = async (versionPath) => {
  if (!Object.hasOwnProperty.call(getVersionString, 'cache')) {
    getVersionString.cache = new Map();
  }
  if (!getVersionString.cache.has(versionPath)) {
    getVersionString.cache.set(versionPath,
      await helpers.exec(versionPath, ['--version']));
  }
  return getVersionString.cache.get(versionPath);
};

export default {
  activate() {
    require('atom-package-deps').install('linter-flake8');

    this.subscriptions = new CompositeDisposable();
    this.subscriptions.add(
      atom.config.observe('linter-flake8.disableTimeout', (value) => {
        this.disableTimeout = value;
      })
    );
    this.subscriptions.add(
      atom.config.observe('linter-flake8.projectConfigFile', (value) => {
        this.projectConfigFile = value;
      })
    );
    this.subscriptions.add(
      atom.config.observe('linter-flake8.maxLineLength', (value) => {
        this.maxLineLength = value;
      })
    );
    this.subscriptions.add(
      atom.config.observe('linter-flake8.ignoreErrorCodes', (value) => {
        this.ignoreErrorCodes = value;
      })
    );
    this.subscriptions.add(
      atom.config.observe('linter-flake8.maxComplexity', (value) => {
        this.maxComplexity = value;
      })
    );
    this.subscriptions.add(
      atom.config.observe('linter-flake8.selectErrors', (value) => {
        this.selectErrors = value;
      })
    );
    this.subscriptions.add(
      atom.config.observe('linter-flake8.hangClosing', (value) => {
        this.hangClosing = value;
      })
    );
    this.subscriptions.add(
      atom.config.observe('linter-flake8.executablePath', (value) => {
        this.executablePath = value;
      })
    );
    this.subscriptions.add(
      atom.config.observe('linter-flake8.pycodestyleErrorsToWarnings', (value) => {
        this.pycodestyleErrorsToWarnings = value;
      })
    );
    this.subscriptions.add(
      atom.config.observe('linter-flake8.flakeErrors', (value) => {
        this.flakeErrors = value;
      })
    );
  },

  deactivate() {
    this.subscriptions.dispose();
  },

  provideLinter() {
    return {
      name: 'Flake8',
      grammarScopes: ['source.python', 'source.python.django'],
      scope: 'file',
      lintOnFly: true,
      lint: async (textEditor) => {
        const filePath = textEditor.getPath();
        const fileText = textEditor.getText();

        const parameters = ['--format=default'];

        const projectPath = atom.project.relativizePath(filePath)[0];
        const baseDir = projectPath !== null ? projectPath : path.dirname(filePath);
        const configFilePath = await helpers.findCachedAsync(baseDir, this.projectConfigFile);

        if (this.projectConfigFile && baseDir !== null && configFilePath !== null) {
          parameters.push('--config', configFilePath);
        } else {
          if (this.maxLineLength) {
            parameters.push('--max-line-length', this.maxLineLength);
          }
          if (this.ignoreErrorCodes.length) {
            parameters.push('--ignore', this.ignoreErrorCodes.join(','));
          }
          if (this.maxComplexity) {
            parameters.push('--max-complexity', this.maxComplexity);
          }
          if (this.hangClosing) {
            parameters.push('--hang-closing');
          }
          if (this.selectErrors.length) {
            parameters.push('--select', this.selectErrors.join(','));
          }
        }

        parameters.push('-');

        const execPath = fs.normalize(applySubstitutions(this.executablePath, baseDir));
        const options = {
          stdin: fileText,
          cwd: path.dirname(textEditor.getPath()),
          stream: 'both',
        };
        if (this.disableTimeout) {
          options.timeout = Infinity;
        }

        const result = await helpers.exec(execPath, parameters, options);

        if (textEditor.getText() !== fileText) {
          // Editor contents have changed, tell Linter not to update
          return null;
        }

        if (result.stderr && result.stderr.length && atom.inDevMode()) {
          // eslint-disable-next-line no-console
          console.log(`flake8 stderr: ${result.stderr}`);
        }
        const messages = [];

        let match = parseRegex.exec(result.stdout);
        while (match !== null) {
          const line = Number.parseInt(match[1], 10) || 0;
          const col = Number.parseInt(match[2], 10) || 0;
          const isErr = (match[4] === 'E' && !this.pycodestyleErrorsToWarnings)
            || (match[4] === 'F' && this.flakeErrors);

          try {
            const range = extractRange({
              code: match[3],
              message: match[5],
              lineNumber: line,
              colNumber: col,
              textEditor,
            });
            messages.push({
              type: isErr ? 'Error' : 'Warning',
              text: `${match[3]} — ${match[5]}`,
              filePath,
              range,
            });
          } catch (e) {
            const flake8Version = await getVersionString(execPath);
            const issueURL = 'https://github.com/AtomLinter/linter-flake8/issues/new';
            const title = encodeURIComponent(`Flake8 rule '${match[3]}' reported an invalid point`);
            const body = encodeURIComponent([
              `Flake8 reported an invalid point for the rule \`${match[3]}\`, ` +
              `with the messge \`${match[5]}\`.`,
              '', '',
              '<!-- If at all possible, please include code that shows this issue! -->',
              '', '',
              'Debug information:',
              `Atom version: ${atom.getVersion()}`,
              `Flake8 version: \`${flake8Version}\``,
            ].join('\n'));
            const newIssueURL = `${issueURL}?title=${title}&body=${body}`;
            messages.push({
              type: 'Error',
              severity: 'error',
              html: 'ERROR: Flake8 provided an invalid point! See the trace for details. ' +
                `<a href="${newIssueURL}">Report this!</a>`,
              filePath,
              range: helpers.rangeFromLineNumber(textEditor, 0),
              trace: [
                {
                  type: 'Trace',
                  text: `Original message: ${match[3]} — ${match[5]}`,
                  filePath,
                  severity: 'info',
                },
                {
                  type: 'Trace',
                  text: `Requested point: ${e.line}:${e.col}`,
                  filePath,
                  severity: 'info',
                },
              ],
            });
          }

          match = parseRegex.exec(result.stdout);
        }
        return messages;
      },
    };
  },
};
<commit_msg>Move trace generation to a function<commit_after>'use babel';

// eslint-disable-next-line import/extensions, import/no-extraneous-dependencies
import { CompositeDisposable } from 'atom';
import fs from 'fs-plus';
import path from 'path';
import * as helpers from 'atom-linter';
import rangeHelpers from './rangeHelpers';

// Local variables
const parseRegex = /(\d+):(\d+):\s(([A-Z])\d{2,3})\s+(.*)/g;

const extractRange = ({ code, message, lineNumber, colNumber, textEditor }) => {
  let result;
  const line = lineNumber - 1;
  switch (code) {
    case 'C901':
      result = rangeHelpers.tooComplex(textEditor, message, line);
      break;
    case 'F401':
      result = rangeHelpers.importedUnused(textEditor, message, line);
      break;
    case 'H201':
      // H201 - no 'except:' at least use 'except Exception:'

      // For some reason this rule marks the ":" as the location by default
      result = {
        line,
        col: colNumber - 7,
        endCol: colNumber,
      };
      break;
    case 'H501':
      result = rangeHelpers.noLocalsString(textEditor, line);
      break;
    case 'E999':
      // E999 - SyntaxError: unexpected EOF while parsing

      // Workaround for https://gitlab.com/pycqa/flake8/issues/237
      result = {
        line,
        col: colNumber - 2,
      };
      break;
    default:
      result = {
        line,
        col: colNumber - 1,
      };
      break;
  }

  if (Object.hasOwnProperty.call(result, 'endCol')) {
    return [
      [result.line, result.col],
      [result.line, result.endCol],
    ];
  }

  let range;
  try {
    range = helpers.rangeFromLineNumber(textEditor, result.line, result.col);
  } catch (e) {
    // rangeFromLineNumber encountered a problem, throw the result and report
    // to the user.
    throw result;
  }

  return range;
};

const applySubstitutions = (givenExecPath, projDir) => {
  let execPath = givenExecPath;
  const projectName = path.basename(projDir);
  execPath = execPath.replace(/\$PROJECT_NAME/i, projectName);
  execPath = execPath.replace(/\$PROJECT/i, projDir);
  const paths = execPath.split(';');
  for (let i = 0; i < paths.length; i += 1) {
    if (fs.existsSync(paths[i])) {
      return paths[i];
    }
  }
  return execPath;
};

const getVersionString = async (versionPath) => {
  if (!Object.hasOwnProperty.call(getVersionString, 'cache')) {
    getVersionString.cache = new Map();
  }
  if (!getVersionString.cache.has(versionPath)) {
    getVersionString.cache.set(versionPath,
      await helpers.exec(versionPath, ['--version']));
  }
  return getVersionString.cache.get(versionPath);
};

const generateInvalidPointTrace = async (execPath, match, filePath, textEditor, point) => {
  const flake8Version = await getVersionString(execPath);
  const issueURL = 'https://github.com/AtomLinter/linter-flake8/issues/new';
  const title = encodeURIComponent(`Flake8 rule '${match[3]}' reported an invalid point`);
  const body = encodeURIComponent([
    `Flake8 reported an invalid point for the rule \`${match[3]}\`, ` +
    `with the messge \`${match[5]}\`.`,
    '', '',
    '<!-- If at all possible, please include code that shows this issue! -->',
    '', '',
    'Debug information:',
    `Atom version: ${atom.getVersion()}`,
    `Flake8 version: \`${flake8Version}\``,
  ].join('\n'));
  const newIssueURL = `${issueURL}?title=${title}&body=${body}`;
  return {
    type: 'Error',
    severity: 'error',
    html: 'ERROR: Flake8 provided an invalid point! See the trace for details. ' +
      `<a href="${newIssueURL}">Report this!</a>`,
    filePath,
    range: helpers.rangeFromLineNumber(textEditor, 0),
    trace: [
      {
        type: 'Trace',
        text: `Original message: ${match[3]} — ${match[5]}`,
        filePath,
        severity: 'info',
      },
      {
        type: 'Trace',
        text: `Requested point: ${point.line}:${point.col}`,
        filePath,
        severity: 'info',
      },
    ],
  };
};

export default {
  activate() {
    require('atom-package-deps').install('linter-flake8');

    this.subscriptions = new CompositeDisposable();
    this.subscriptions.add(
      atom.config.observe('linter-flake8.disableTimeout', (value) => {
        this.disableTimeout = value;
      })
    );
    this.subscriptions.add(
      atom.config.observe('linter-flake8.projectConfigFile', (value) => {
        this.projectConfigFile = value;
      })
    );
    this.subscriptions.add(
      atom.config.observe('linter-flake8.maxLineLength', (value) => {
        this.maxLineLength = value;
      })
    );
    this.subscriptions.add(
      atom.config.observe('linter-flake8.ignoreErrorCodes', (value) => {
        this.ignoreErrorCodes = value;
      })
    );
    this.subscriptions.add(
      atom.config.observe('linter-flake8.maxComplexity', (value) => {
        this.maxComplexity = value;
      })
    );
    this.subscriptions.add(
      atom.config.observe('linter-flake8.selectErrors', (value) => {
        this.selectErrors = value;
      })
    );
    this.subscriptions.add(
      atom.config.observe('linter-flake8.hangClosing', (value) => {
        this.hangClosing = value;
      })
    );
    this.subscriptions.add(
      atom.config.observe('linter-flake8.executablePath', (value) => {
        this.executablePath = value;
      })
    );
    this.subscriptions.add(
      atom.config.observe('linter-flake8.pycodestyleErrorsToWarnings', (value) => {
        this.pycodestyleErrorsToWarnings = value;
      })
    );
    this.subscriptions.add(
      atom.config.observe('linter-flake8.flakeErrors', (value) => {
        this.flakeErrors = value;
      })
    );
  },

  deactivate() {
    this.subscriptions.dispose();
  },

  provideLinter() {
    return {
      name: 'Flake8',
      grammarScopes: ['source.python', 'source.python.django'],
      scope: 'file',
      lintOnFly: true,
      lint: async (textEditor) => {
        const filePath = textEditor.getPath();
        const fileText = textEditor.getText();

        const parameters = ['--format=default'];

        const projectPath = atom.project.relativizePath(filePath)[0];
        const baseDir = projectPath !== null ? projectPath : path.dirname(filePath);
        const configFilePath = await helpers.findCachedAsync(baseDir, this.projectConfigFile);

        if (this.projectConfigFile && baseDir !== null && configFilePath !== null) {
          parameters.push('--config', configFilePath);
        } else {
          if (this.maxLineLength) {
            parameters.push('--max-line-length', this.maxLineLength);
          }
          if (this.ignoreErrorCodes.length) {
            parameters.push('--ignore', this.ignoreErrorCodes.join(','));
          }
          if (this.maxComplexity) {
            parameters.push('--max-complexity', this.maxComplexity);
          }
          if (this.hangClosing) {
            parameters.push('--hang-closing');
          }
          if (this.selectErrors.length) {
            parameters.push('--select', this.selectErrors.join(','));
          }
        }

        parameters.push('-');

        const execPath = fs.normalize(applySubstitutions(this.executablePath, baseDir));
        const options = {
          stdin: fileText,
          cwd: path.dirname(textEditor.getPath()),
          stream: 'both',
        };
        if (this.disableTimeout) {
          options.timeout = Infinity;
        }

        const result = await helpers.exec(execPath, parameters, options);

        if (textEditor.getText() !== fileText) {
          // Editor contents have changed, tell Linter not to update
          return null;
        }

        if (result.stderr && result.stderr.length && atom.inDevMode()) {
          // eslint-disable-next-line no-console
          console.log(`flake8 stderr: ${result.stderr}`);
        }
        const messages = [];

        let match = parseRegex.exec(result.stdout);
        while (match !== null) {
          const line = Number.parseInt(match[1], 10) || 0;
          const col = Number.parseInt(match[2], 10) || 0;
          const isErr = (match[4] === 'E' && !this.pycodestyleErrorsToWarnings)
            || (match[4] === 'F' && this.flakeErrors);

          try {
            const range = extractRange({
              code: match[3],
              message: match[5],
              lineNumber: line,
              colNumber: col,
              textEditor,
            });
            messages.push({
              type: isErr ? 'Error' : 'Warning',
              text: `${match[3]} — ${match[5]}`,
              filePath,
              range,
            });
          } catch (point) {
            messages.push(await generateInvalidPointTrace(
              execPath, match, filePath, textEditor, point));
          }

          match = parseRegex.exec(result.stdout);
        }
        return messages;
      },
    };
  },
};
<|endoftext|>


<commit_before>var MISSION_ID = false;
var db = firebase.database();

var UPLINK = {
	set: function(path, value){
		var ref = db.ref('missions/' + MISSION_ID + '/' + path);
			ref.set(value);
	},
	push: function(path, value){
		var ref = db.ref('missions/' + MISSION_ID + '/' + path);
			ref.push(value);
	}
}

var STATE = {
	id: false,
	data: {},
	usingInterface: function(itf){
		var state = this;
		var res = false;
		for(var c in state.data.controls){
			var panels = state.data.controls[c].panels;
			for(var p in panels){
				var panel = panels[p];
				if(panel.interface === itf){
					res = true;
					break;
				}
			}
			if(res){
				break;
			}
		}
		return res;
	},
	installInterface: function(panel, itf){
		var state = this;
		//console.log(state.data);
		state.data.controls[state.id][panel].interface = itf;
		UPLINK.set('controls/' + state.id + '/' + panel + '/interface', itf);
	},
	calledTask: function(tid){
		var state = this;
		return (state.data.tasks[state.data.tasks.length-1] === tid);
		//return (state.data.tasks.indexOf(tid) > -1);
		//return false;
	},
	reserveTask: function(tid){
		var state = this;
		state.data.tasks.push(tid);
		UPLINK.push('tasks', tid);
		/*state.data.controls[state.id][panel].task = tid;
		UPLINK.set('controls/' + state.id + '/' + panel + '/task', tid);*/
	}
}

var Terminal = {
	limit: 11,
	startTime: Date.now(),
	print: function(message){
		var terminal = document.getElementById('terminal-mission');
		terminal.innerHTML = '
' + message + '
';
	},
	startTimer: function(tid){
		var tmn = this;
		tmn.startTime = Date.now();
		var itx = setInterval(function(){
			var elapsed = Date.now() - tmn.startTime;
			var remaining = (tmn.limit * 1000) - elapsed;
			var per = remaining / (tmn.limit * 1000);
			console.log(per, tmn.startTime, remaining);
			if(per < 0){
				clearInterval(itx);
				console.log('Failed Task: ' + tid);
				var MistakeEvent = new CustomEvent('taskmistake', {
					detail: {
						id: tid,
						reason: 'Ran out of time!'
					}
				});
				window.dispatchEvent(MistakeEvent);
			}
			else{
				var terminal = document.getElementById('terminal-mission');
				terminal.style.opacity = per;
			}
		}, 1000);
	}
}

var LOCAL = {
	panels: false
}

function removeAtPath(path){
	var ref = db.ref(path);
		ref.off();
		ref.remove();
}

function createMission(key){
	removeAtPath('missions/' + key);
	removeAtPath('players/' + key);
	removeAtPath('results/' + key);
	removeAtPath('start/' + key);
	removeAtPath('tasks/' + key);
	var ref = db.ref('missions/' + key);
	var setup = ref.set({
		tasks: {'init': 'init_task'}
	});
	return setup;
}

var CAN_START = false;
var PUSH_ID = false;

function sendTask(){
	var controlsRef = db.ref('missions/' + MISSION_ID + '/controls');
	controlsRef.once('value', function(snapshot){
		var controls = snapshot.val();
		var members = [];
		for(var member in controls){
			var panels = [];
			for(var p in controls[member]){
				if(member !== STATE.id){
					var panel = controls[member][p];
					console.log(panel)
					if(!panel.task){
						panels.push({
							id: p,
							interface: panel.interface
						});
					}
				}
			}
			if(panels.length > 0){
				members.push({
					player: member,
					panels: panels
				});
			}
		}
		if(members.length > 1){
			members = members.sort(function(a, b){
				return b.panels.length - a.panels.length;
			});
		}
		if(members.length > 0){
			var assignTo = members[0];
			var pidx = Math.floor(assignTo.panels.length * Math.random());
			console.log(pidx, assignTo.panels);
			var itf = assignTo.panels[pidx].interface;
			var panel_id = assignTo.panels[pidx].id;
			var tid = TaskManager.getTask(itf);
			if(tid){
				var inbox = db.ref('tasks/' + MISSION_ID + '/' + assignTo.player);
				var promise = inbox.push({
					origin: STATE.id,
					panel: panel_id,
					interface: itf,
					task: tid,
					assigned: Date.now()
				});
				promise.then(function(done){
					var task = TASKS[tid];
					Terminal.print(task.instruction);
					Terminal.startTimer(tid);
				});
			}
			else{
				console.error('All out of Usable Tasks!');
				var resRef = db.ref('results/' + MISSION_ID);
				resRef.push({
					disaster: true,
					reason: 'All out of Usable Tasks!'
				});
			}
		}
		else{
			console.log('No one to send tasks to.');
			Terminal.print('You look nice today.');
		}
	});
}

function join(mission, player){

	MISSION_ID = mission;
	STATE.id = player;

	var startB = document.getElementById('start');
		startB.addEventListener('click', function(e){
			if(CAN_START){
				db.ref('start/' + MISSION_ID).set(true);
			}
		});

	db.ref('start/' + MISSION_ID).on('value', function(snapshot){
		var start = snapshot.val();
		if(start){
			// Start Game
			console.log('Started Game.');
			var wel = document.getElementById('welcome');
			wel.style.display = 'none';
			sendTask();
		}
	});

	db.ref('start/' + MISSION_ID).set(false);

	var playersRef = db.ref('players/' + MISSION_ID)
	playersRef.on('child_added', function(snapshot){
		var val = snapshot.val();
		var playersPanel = document.getElementById('players');
			playersPanel.innerHTML += val.player + ' joined the mission.
';
	});
	playersRef.push({
		player: STATE.id,
		loaded: false
	}).then(function(joined){
		PUSH_ID = joined.key;
		playersRef.once('value', function(playersSnap){
			var val = playersSnap.val();
			var pc = 0;
			for(var i in val){
				pc++;
				if(val[i].player === STATE.id){
					break;
				}
			}
			console.log('You are Player #' + pc);
			var itfs = PLAYER_ITFS[pc-1];
			STATE.data.controls = {};
			STATE.data.controls[STATE.id] = {};
			loadPanels(itfs);
		});
	});

	playersRef.on('value', function(snapshot){
		var playersMap = snapshot.val();
		var waiting = false;
		var counter = 0;
		for(var i in playersMap){
			var p = playersMap[i];
			if(!p.loaded){
				waiting = true;
			}
			counter++;
		}
		if(counter < 2){
			waiting = true;
		}
		if(!waiting){
			CAN_START = true;
			startB.disabled = false;
			console.log('All players are ready to start the mission.')
		}
		else{
			CAN_START = false;
			startB.disabled = true;
			console.log('Players are not ready to start the mission.')
		}
	});

}

function loadPanels(itfs){
	var promises = [];
	var panels = document.getElementsByClassName('panel-module');
	var map = {};
	for(var p = 0; p < itfs.length; p++){
		var panel = panels[p];
		var itf = itfs[p];
		//console.log(STATE.data.controls[STATE.id], panel.id)
		map[panel.id] = {interface: itf};
		promises.push(ControlModule(panel.id, itf));
	}
	STATE.data.controls[STATE.id] = map;
	UPLINK.set('controls/' + STATE.id, map);
	Promise.all(promises).then(function(modules){
		var panelMap = {};
		console.log('modules', modules)
		for(var m = 0; m < modules.length; m++){
			var mp = modules[m];
			panelMap[mp.panel] = mp;
		}
		console.log('panelMap', panelMap)
		LOCAL.panels = panelMap;
		console.log('All panels loaded');
		connect();
	});
}

function connect(){
	var configured = false;
	var ref = db.ref('missions/' + MISSION_ID);
	ref.on('value', function(snapshot){
		var val = snapshot.val();
		var tasks = [];
		for(var t in val.tasks){
			tasks.push(val.tasks[t]);
		}
		val.tasks = tasks;
		STATE.data = val;
		if(!configured){
			configured = true;
			console.log('Connected to Firebase.');
			init();
		}
	});
}

function init(){
	var originMap = {};
	// Listen for completions
	window.addEventListener('taskcompleted', function(e){
		// Victory
		var resRef = db.ref('results/' + MISSION_ID);
		resRef.push({success: true});
		var returnTo = originMap[e.detail.id];
		var outbox = db.ref('tasks/' + MISSION_ID + '/' + returnTo);
		outbox.push({
			completed: true,
			by: STATE.id
		});
		//sendTask(); This should never run here (Sunny + Graph Theory)
	});
	// Listen for mistakes
	window.addEventListener('taskmistake', function(e){
		// Failure
		var resRef = db.ref('results/' + MISSION_ID);
		resRef.push({success: false});
	});
	var inbox = db.ref('tasks/' + MISSION_ID + '/' + STATE.id);
	inbox.on('child_added', function(snapshot){
		var newTask = snapshot.val();
		if(newTask.completed){
			sendTask();
		}
		else{
			var panel = LOCAL.panels[newTask.panel];
			console.log(newTask)
				panel.startTask(newTask.task);
				originMap[newTask.task] = newTask.origin;
		}
	});
	db.ref('players/' + MISSION_ID + '/' + PUSH_ID + '/loaded').set(true);
	console.log('Ready to start mission.');
	// Keep Score
	var winRef = db.ref('results/' + MISSION_ID)
	winRef.on('value', function(snapshot){
		var val = snapshot.val();
		var victory = 0;
		var failure = 0;
		for(var i in val){
			var node = val[i];
			if(node.success){
				victory++;
			}
			else{
				failure++;
			}
			if(node.disaster){
				alert('System failure! Mission cannot be completed.');
				break;
			}
			if(failure >= 3){
				// END GAME
				alert('Too many critical errors. Mission failed.');
				break;
			}
			if(victory >= 7){
				// WIN GAME
				alert('Mission success! Connection established.');
				break;
			}
		}
		console.log('Successful: ', victory, 'Errors: ', failure);
	});
}<commit_msg>Turn off listener to results ref when game ends<commit_after>var MISSION_ID = false;
var db = firebase.database();

var UPLINK = {
	set: function(path, value){
		var ref = db.ref('missions/' + MISSION_ID + '/' + path);
			ref.set(value);
	},
	push: function(path, value){
		var ref = db.ref('missions/' + MISSION_ID + '/' + path);
			ref.push(value);
	}
}

var STATE = {
	id: false,
	data: {},
	usingInterface: function(itf){
		var state = this;
		var res = false;
		for(var c in state.data.controls){
			var panels = state.data.controls[c].panels;
			for(var p in panels){
				var panel = panels[p];
				if(panel.interface === itf){
					res = true;
					break;
				}
			}
			if(res){
				break;
			}
		}
		return res;
	},
	installInterface: function(panel, itf){
		var state = this;
		//console.log(state.data);
		state.data.controls[state.id][panel].interface = itf;
		UPLINK.set('controls/' + state.id + '/' + panel + '/interface', itf);
	},
	calledTask: function(tid){
		var state = this;
		return (state.data.tasks[state.data.tasks.length-1] === tid);
		//return (state.data.tasks.indexOf(tid) > -1);
		//return false;
	},
	reserveTask: function(tid){
		var state = this;
		state.data.tasks.push(tid);
		UPLINK.push('tasks', tid);
		/*state.data.controls[state.id][panel].task = tid;
		UPLINK.set('controls/' + state.id + '/' + panel + '/task', tid);*/
	}
}

var Terminal = {
	limit: 11,
	startTime: Date.now(),
	print: function(message){
		var terminal = document.getElementById('terminal-mission');
		terminal.innerHTML = '
' + message + '
';
	},
	startTimer: function(tid){
		var tmn = this;
		tmn.startTime = Date.now();
		var itx = setInterval(function(){
			var elapsed = Date.now() - tmn.startTime;
			var remaining = (tmn.limit * 1000) - elapsed;
			var per = remaining / (tmn.limit * 1000);
			console.log(per, tmn.startTime, remaining);
			if(per < 0){
				clearInterval(itx);
				console.log('Failed Task: ' + tid);
				var MistakeEvent = new CustomEvent('taskmistake', {
					detail: {
						id: tid,
						reason: 'Ran out of time!'
					}
				});
				window.dispatchEvent(MistakeEvent);
			}
			else{
				var terminal = document.getElementById('terminal-mission');
				terminal.style.opacity = per;
			}
		}, 1000);
	}
}

var LOCAL = {
	panels: false
}

function removeAtPath(path){
	var ref = db.ref(path);
		ref.off();
		ref.remove();
}

function createMission(key){
	removeAtPath('missions/' + key);
	removeAtPath('players/' + key);
	removeAtPath('results/' + key);
	removeAtPath('start/' + key);
	removeAtPath('tasks/' + key);
	var ref = db.ref('missions/' + key);
	var setup = ref.set({
		tasks: {'init': 'init_task'}
	});
	return setup;
}

var CAN_START = false;
var PUSH_ID = false;

function sendTask(){
	var controlsRef = db.ref('missions/' + MISSION_ID + '/controls');
	controlsRef.once('value', function(snapshot){
		var controls = snapshot.val();
		var members = [];
		for(var member in controls){
			var panels = [];
			for(var p in controls[member]){
				if(member !== STATE.id){
					var panel = controls[member][p];
					console.log(panel)
					if(!panel.task){
						panels.push({
							id: p,
							interface: panel.interface
						});
					}
				}
			}
			if(panels.length > 0){
				members.push({
					player: member,
					panels: panels
				});
			}
		}
		if(members.length > 1){
			members = members.sort(function(a, b){
				return b.panels.length - a.panels.length;
			});
		}
		if(members.length > 0){
			var assignTo = members[0];
			var pidx = Math.floor(assignTo.panels.length * Math.random());
			console.log(pidx, assignTo.panels);
			var itf = assignTo.panels[pidx].interface;
			var panel_id = assignTo.panels[pidx].id;
			var tid = TaskManager.getTask(itf);
			if(tid){
				var inbox = db.ref('tasks/' + MISSION_ID + '/' + assignTo.player);
				var promise = inbox.push({
					origin: STATE.id,
					panel: panel_id,
					interface: itf,
					task: tid,
					assigned: Date.now()
				});
				promise.then(function(done){
					var task = TASKS[tid];
					Terminal.print(task.instruction);
					Terminal.startTimer(tid);
				});
			}
			else{
				console.error('All out of Usable Tasks!');
				var resRef = db.ref('results/' + MISSION_ID);
				resRef.push({
					disaster: true,
					reason: 'All out of Usable Tasks!'
				});
			}
		}
		else{
			console.log('No one to send tasks to.');
			Terminal.print('You look nice today.');
		}
	});
}

function join(mission, player){

	MISSION_ID = mission;
	STATE.id = player;

	var startB = document.getElementById('start');
		startB.addEventListener('click', function(e){
			if(CAN_START){
				db.ref('start/' + MISSION_ID).set(true);
			}
		});

	db.ref('start/' + MISSION_ID).on('value', function(snapshot){
		var start = snapshot.val();
		if(start){
			// Start Game
			console.log('Started Game.');
			var wel = document.getElementById('welcome');
			wel.style.display = 'none';
			sendTask();
		}
	});

	db.ref('start/' + MISSION_ID).set(false);

	var playersRef = db.ref('players/' + MISSION_ID)
	playersRef.on('child_added', function(snapshot){
		var val = snapshot.val();
		var playersPanel = document.getElementById('players');
			playersPanel.innerHTML += val.player + ' joined the mission.
';
	});
	playersRef.push({
		player: STATE.id,
		loaded: false
	}).then(function(joined){
		PUSH_ID = joined.key;
		playersRef.once('value', function(playersSnap){
			var val = playersSnap.val();
			var pc = 0;
			for(var i in val){
				pc++;
				if(val[i].player === STATE.id){
					break;
				}
			}
			console.log('You are Player #' + pc);
			var itfs = PLAYER_ITFS[pc-1];
			STATE.data.controls = {};
			STATE.data.controls[STATE.id] = {};
			loadPanels(itfs);
		});
	});

	playersRef.on('value', function(snapshot){
		var playersMap = snapshot.val();
		var waiting = false;
		var counter = 0;
		for(var i in playersMap){
			var p = playersMap[i];
			if(!p.loaded){
				waiting = true;
			}
			counter++;
		}
		if(counter < 2){
			waiting = true;
		}
		if(!waiting){
			CAN_START = true;
			startB.disabled = false;
			console.log('All players are ready to start the mission.')
		}
		else{
			CAN_START = false;
			startB.disabled = true;
			console.log('Players are not ready to start the mission.')
		}
	});

}

function loadPanels(itfs){
	var promises = [];
	var panels = document.getElementsByClassName('panel-module');
	var map = {};
	for(var p = 0; p < itfs.length; p++){
		var panel = panels[p];
		var itf = itfs[p];
		//console.log(STATE.data.controls[STATE.id], panel.id)
		map[panel.id] = {interface: itf};
		promises.push(ControlModule(panel.id, itf));
	}
	STATE.data.controls[STATE.id] = map;
	UPLINK.set('controls/' + STATE.id, map);
	Promise.all(promises).then(function(modules){
		var panelMap = {};
		console.log('modules', modules)
		for(var m = 0; m < modules.length; m++){
			var mp = modules[m];
			panelMap[mp.panel] = mp;
		}
		console.log('panelMap', panelMap)
		LOCAL.panels = panelMap;
		console.log('All panels loaded');
		connect();
	});
}

function connect(){
	var configured = false;
	var ref = db.ref('missions/' + MISSION_ID);
	ref.on('value', function(snapshot){
		var val = snapshot.val();
		var tasks = [];
		for(var t in val.tasks){
			tasks.push(val.tasks[t]);
		}
		val.tasks = tasks;
		STATE.data = val;
		if(!configured){
			configured = true;
			console.log('Connected to Firebase.');
			init();
		}
	});
}

function init(){
	var originMap = {};
	// Listen for completions
	window.addEventListener('taskcompleted', function(e){
		// Victory
		var resRef = db.ref('results/' + MISSION_ID);
		resRef.push({success: true});
		var returnTo = originMap[e.detail.id];
		var outbox = db.ref('tasks/' + MISSION_ID + '/' + returnTo);
		outbox.push({
			completed: true,
			by: STATE.id
		});
		//sendTask(); This should never run here (Sunny + Graph Theory)
	});
	// Listen for mistakes
	window.addEventListener('taskmistake', function(e){
		// Failure
		var resRef = db.ref('results/' + MISSION_ID);
		resRef.push({success: false});
	});
	var inbox = db.ref('tasks/' + MISSION_ID + '/' + STATE.id);
	inbox.on('child_added', function(snapshot){
		var newTask = snapshot.val();
		if(newTask.completed){
			sendTask();
		}
		else{
			var panel = LOCAL.panels[newTask.panel];
			console.log(newTask)
				panel.startTask(newTask.task);
				originMap[newTask.task] = newTask.origin;
		}
	});
	db.ref('players/' + MISSION_ID + '/' + PUSH_ID + '/loaded').set(true);
	console.log('Ready to start mission.');
	// Keep Score
	var winRef = db.ref('results/' + MISSION_ID)
	winRef.on('value', function(snapshot){
		var val = snapshot.val();
		var victory = 0;
		var failure = 0;
		for(var i in val){
			var node = val[i];
			if(node.success){
				victory++;
			}
			else{
				failure++;
			}
			if(node.disaster){
				alert('System failure! Mission cannot be completed.');
				winRef.off();
				break;
			}
			if(failure >= 3){
				// END GAME
				alert('Too many critical errors. Mission failed.');
				winRef.off();
				break;
			}
			if(victory >= 7){
				// WIN GAME
				alert('Mission success! Connection established.');
				winRef.off();
				break;
			}
		}
		console.log('Successful: ', victory, 'Errors: ', failure);
	});
}<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

"use strict";

let { Cc, Ci, Cu } = require("chrome");

let { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
let { console } = Cu.import("resource://gre/modules/devtools/Console.jsm", {});

let gDebug = true;
let gPrefix = "superskua: ";
function log(x) {
  if (gDebug) {
    console.log(gPrefix + x);
  }
}

let gSuperfishPEM =
  "MIIC9TCCAl6gAwIBAgIJANL8E4epRNznMA0GCSqGSIb3DQEBBQUAMFsxGDAWBgNV" +
  "BAoTD1N1cGVyZmlzaCwgSW5jLjELMAkGA1UEBxMCU0YxCzAJBgNVBAgTAkNBMQsw" +
  "CQYDVQQGEwJVUzEYMBYGA1UEAxMPU3VwZXJmaXNoLCBJbmMuMB4XDTE0MDUxMjE2" +
  "MjUyNloXDTM0MDUwNzE2MjUyNlowWzEYMBYGA1UEChMPU3VwZXJmaXNoLCBJbmMu" +
  "MQswCQYDVQQHEwJTRjELMAkGA1UECBMCQ0ExCzAJBgNVBAYTAlVTMRgwFgYDVQQD" +
  "Ew9TdXBlcmZpc2gsIEluYy4wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOjz" +
  "Shh2Xxk/sc9Y6X9DBwmVgDXFD/5xMSeBmRImIKXfj2r8QlU57gk4idngNsSsAYJb" +
  "1Tnm+Y8HiN/+7vahFM6pdEXY/fAXVyqC4XouEpNarIrXFWPRt5tVgA9YvBxJ7SBi" +
  "3bZMpTrrHD2g/3pxptMQeDOuS8Ic/ZJKocPnQaQtAgMBAAGjgcAwgb0wDAYDVR0T" +
  "BAUwAwEB/zAdBgNVHQ4EFgQU+5izU38URC7o7tUJml4OVoaoNYgwgY0GA1UdIwSB" +
  "hTCBgoAU+5izU38URC7o7tUJml4OVoaoNYihX6RdMFsxGDAWBgNVBAoTD1N1cGVy" +
  "ZmlzaCwgSW5jLjELMAkGA1UEBxMCU0YxCzAJBgNVBAgTAkNBMQswCQYDVQQGEwJV" +
  "UzEYMBYGA1UEAxMPU3VwZXJmaXNoLCBJbmMuggkA0vwTh6lE3OcwDQYJKoZIhvcN" +
  "AQEFBQADgYEApHyg7ApKx3DEcWjzOyLi3JyN0JL+c35yK1VEmxu0Qusfr76645Oj" +
  "1IsYwpTws6a9ZTRMzST4GQvFFQra81eLqYbPbMPuhC+FCxkUF5i0DNSWi+kczJXJ" +
  "TtCqSwGl9t9JEoFqvtW+znZ9TqyLiOMw7TGEUI+88VAqW0qmXnwPcfo=";

// Due to bug 1045907, the nsIX509Cert object must not be garbage-collected.
// Otherwise, the distrust bit will be lost.
let gSuperfishCert = null;

// We need to ensure the proxy is uninstalled or we DoS users
function isSuperFishUninstalled() {
  try {
    let registry = Cc["@mozilla.org/windows-registry-key;1"].
                      createInstance(Ci.nsIWindowsRegKey);
    registry.open(Ci.nsIWindowsRegKey.ROOT_KEY_LOCAL_MACHINE,
                  "SOFTWARE\\MICROSOFT\\WINDOWS\\CURRENTVERSION\\UNINSTALL",
                  Ci.nsIWindowsRegKey.ACCESS_READ);
    if (registry.hasChild("Superfish Inc. VisualDiscovery")) {
      return false;
    }
  } catch (ex) {

  }
  return true;
}

function distrustThatParticularRoot() {
  let certdb = Cc["@mozilla.org/security/x509certdb;1"]
                 .getService(Ci.nsIX509CertDB);
  gSuperfishCert = certdb.constructX509FromBase64(gSuperfishPEM);
  certdb.setCertTrustFromString(gSuperfishCert, "pu,pu,pu");

  // Clear any active sessions/tickets
  let sdr = Cc["@mozilla.org/security/sdr;1"]
              .getService(Ci.nsISecretDecoderRing);
  sdr.logoutAndTeardown();
}

let gInitialized = false;

exports.main = function(options, callbacks) {
  if (!gInitialized &&
      (options.loadReason == "startup" ||
       options.loadReason == "install" ||
       options.loadReason == "enable")) {
    log("initializing");
    try {
      if (isSuperfishUninstalled()) {
        distrustThatParticularRoot();
      } else {
        log("Superfish is still installed; not removing root");
      }
    } catch (error) {
      log("distrusting Superfish root failed: " + error);
    }
    gInitialized = true;
  }
};
<commit_msg>added OS check so we don't do install checks on Linux, OS X<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

"use strict";

let { Cc, Ci, Cu } = require("chrome");

let { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
let { console } = Cu.import("resource://gre/modules/devtools/Console.jsm", {});

let gDebug = true;
let gPrefix = "superskua: ";
function log(x) {
  if (gDebug) {
    console.log(gPrefix + x);
  }
}

let gSuperfishPEM =
  "MIIC9TCCAl6gAwIBAgIJANL8E4epRNznMA0GCSqGSIb3DQEBBQUAMFsxGDAWBgNV" +
  "BAoTD1N1cGVyZmlzaCwgSW5jLjELMAkGA1UEBxMCU0YxCzAJBgNVBAgTAkNBMQsw" +
  "CQYDVQQGEwJVUzEYMBYGA1UEAxMPU3VwZXJmaXNoLCBJbmMuMB4XDTE0MDUxMjE2" +
  "MjUyNloXDTM0MDUwNzE2MjUyNlowWzEYMBYGA1UEChMPU3VwZXJmaXNoLCBJbmMu" +
  "MQswCQYDVQQHEwJTRjELMAkGA1UECBMCQ0ExCzAJBgNVBAYTAlVTMRgwFgYDVQQD" +
  "Ew9TdXBlcmZpc2gsIEluYy4wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOjz" +
  "Shh2Xxk/sc9Y6X9DBwmVgDXFD/5xMSeBmRImIKXfj2r8QlU57gk4idngNsSsAYJb" +
  "1Tnm+Y8HiN/+7vahFM6pdEXY/fAXVyqC4XouEpNarIrXFWPRt5tVgA9YvBxJ7SBi" +
  "3bZMpTrrHD2g/3pxptMQeDOuS8Ic/ZJKocPnQaQtAgMBAAGjgcAwgb0wDAYDVR0T" +
  "BAUwAwEB/zAdBgNVHQ4EFgQU+5izU38URC7o7tUJml4OVoaoNYgwgY0GA1UdIwSB" +
  "hTCBgoAU+5izU38URC7o7tUJml4OVoaoNYihX6RdMFsxGDAWBgNVBAoTD1N1cGVy" +
  "ZmlzaCwgSW5jLjELMAkGA1UEBxMCU0YxCzAJBgNVBAgTAkNBMQswCQYDVQQGEwJV" +
  "UzEYMBYGA1UEAxMPU3VwZXJmaXNoLCBJbmMuggkA0vwTh6lE3OcwDQYJKoZIhvcN" +
  "AQEFBQADgYEApHyg7ApKx3DEcWjzOyLi3JyN0JL+c35yK1VEmxu0Qusfr76645Oj" +
  "1IsYwpTws6a9ZTRMzST4GQvFFQra81eLqYbPbMPuhC+FCxkUF5i0DNSWi+kczJXJ" +
  "TtCqSwGl9t9JEoFqvtW+znZ9TqyLiOMw7TGEUI+88VAqW0qmXnwPcfo=";

// Due to bug 1045907, the nsIX509Cert object must not be garbage-collected.
// Otherwise, the distrust bit will be lost.
let gSuperfishCert = null;

// We need to ensure the proxy is uninstalled or we DoS users
function isSuperFishInstalled() {
  try {
    // Check we're on Windows
    var osString = Cc["@mozilla.org/xre/app-info;1"]
                     .getService(Components.interfaces.nsIXULRuntime).OS;
    if ('WINNT' !== osString) {
      log("Superfish root removal is windows only");
      return false;
    }

    // Test for the superfish uninstall key; if present, it's still
    // installed
    let registry = Cc["@mozilla.org/windows-registry-key;1"]
                     .createInstance(Ci.nsIWindowsRegKey);
    registry.open(Ci.nsIWindowsRegKey.ROOT_KEY_LOCAL_MACHINE,
                  "SOFTWARE\\MICROSOFT\\WINDOWS\\CURRENTVERSION\\UNINSTALL",
                  Ci.nsIWindowsRegKey.ACCESS_READ);
    if (registry.hasChild("Superfish Inc. VisualDiscovery")) {
      return true;
    }
  } catch (ex) {

  }
  return false;
}

function distrustThatParticularRoot() {
  let certdb = Cc["@mozilla.org/security/x509certdb;1"]
                 .getService(Ci.nsIX509CertDB);
  gSuperfishCert = certdb.constructX509FromBase64(gSuperfishPEM);
  certdb.setCertTrustFromString(gSuperfishCert, "pu,pu,pu");

  // Clear any active sessions/tickets
  let sdr = Cc["@mozilla.org/security/sdr;1"]
              .getService(Ci.nsISecretDecoderRing);
  sdr.logoutAndTeardown();
}

let gInitialized = false;

exports.main = function(options, callbacks) {
  if (!gInitialized &&
      (options.loadReason == "startup" ||
       options.loadReason == "install" ||
       options.loadReason == "enable")) {
    log("initializing");
    try {
      if (isSuperfishInstalled()) {
        distrustThatParticularRoot();
      } else {
        log("Superfish is still installed; not removing root");
      }
    } catch (error) {
      log("distrusting Superfish root failed: " + error);
    }
    gInitialized = true;
  }
};
<|endoftext|>


<commit_before>const cp = require("child_process");
const { shell } = require("electron");
const { AutoLanguageClient } = require("atom-languageclient");
const {
  detectVirtualEnv,
  detectPipEnv,
  replacePipEnvPathVar,
  sanitizeConfig
} = require("./utils");

// Ref: https://github.com/nteract/hydrogen/blob/master/lib/autocomplete-provider.js#L33
// adapted from http://stackoverflow.com/q/5474008
const PYTHON_REGEX = /(([^\d\W]|[\u00A0-\uFFFF])[\w.\u00A0-\uFFFF]*)|\.$/;

class PythonLanguageClient extends AutoLanguageClient {
  getGrammarScopes() {
    return ["source.python", "python"];
  }

  getLanguageName() {
    return "Python";
  }

  getServerName() {
    return "pyls";
  }

  getRootConfigurationKey() {
    return "ide-python";
  }

  activate() {
    // Remove deprecated option
    atom.config.unset("ide-python.pylsPath");
    super.activate();
  }

  mapConfigurationObject(configuration) {
    return {
      pyls: {
        configurationSources: configuration.pylsConfigurationSources,
        rope: sanitizeConfig(configuration.rope),
        plugins: configuration.pylsPlugins
      }
    };
  }

  async startServerProcess(projectPath) {
    const venvPath =
      (await detectPipEnv(projectPath)) ||
      (await detectVirtualEnv(projectPath));
    const pylsEnvironment = Object.assign({}, process.env);
    if (venvPath) {
      pylsEnvironment["VIRTUAL_ENV"] = venvPath;
    }
    const python = replacePipEnvPathVar(
      atom.config.get("ide-python.python"),
      venvPath
    );
    const childProcess = cp.spawn(python, ["-m", "pyls"], {
      cwd: projectPath,
      env: pylsEnvironment
    });
    childProcess.on("error", err => {
      const description =
        err.code == "ENOENT"
          ? `No Python interpreter found at \`${python}\`.`
          : `Could not spawn the Python interpreter \`${python}\`.`;
      atom.notifications.addError(
        "`ide-python` could not launch your Python runtime.",
        {
          dismissable: true,
          description: `${description}<p>If you have Python installed please set "Python Executable" setting correctly. If you do not please install Python.</p>`
        }
      );
    });

    childProcess.on("close", (code, signal) => {
      if (code !== 0 && signal == null) {
        atom.notifications.addError(
          "Unable to start the Python language server.",
          {
            dismissable: true,
            buttons: [
              {
                text: "Install Instructions",
                onDidClick: () =>
                  atom.workspace.open("atom://config/packages/ide-python")
              },
              {
                text: "Download Python",
                onDidClick: () =>
                  shell.openExternal("https://www.python.org/downloads/")
              }
            ],
            description:
              "Make sure to install `pyls` 0.19 or newer by running:\n" +
              "```\n" +
              `${python} -m pip install 'python-language-server[all]'\n` +
              "```"
          }
        );
      }
    });
    return childProcess;
  }

  async getSuggestions(request) {
    if (!PYTHON_REGEX.test(request.prefix)) return null;
    return super.getSuggestions(request);
  }

  deactivate() {
    return Promise.race([super.deactivate(), this.createTimeoutPromise(2000)]);
  }

  createTimeoutPromise(milliseconds) {
    return new Promise((resolve, reject) => {
      let timeout = setTimeout(() => {
        clearTimeout(timeout);
        this.logger.error(
          `Server failed to shutdown in ${milliseconds}ms, forcing termination`
        );
        resolve();
      }, milliseconds);
    });
  }
}

module.exports = new PythonLanguageClient();
<commit_msg>Add debugger functions to main entry<commit_after>const cp = require("child_process");
const { shell } = require("electron");
const { AutoLanguageClient } = require("atom-languageclient");
const {
  detectVirtualEnv,
  detectPipEnv,
  replacePipEnvPathVar,
  sanitizeConfig
} = require("./utils");

import { createDebuggerProvider, activate as debuggerActivate, dispose as debuggerDispose } from "./debugger/main"

// Ref: https://github.com/nteract/hydrogen/blob/master/lib/autocomplete-provider.js#L33
// adapted from http://stackoverflow.com/q/5474008
const PYTHON_REGEX = /(([^\d\W]|[\u00A0-\uFFFF])[\w.\u00A0-\uFFFF]*)|\.$/;

class PythonLanguageClient extends AutoLanguageClient {
  getGrammarScopes() {
    return ["source.python", "python"];
  }

  getLanguageName() {
    return "Python";
  }

  getServerName() {
    return "pyls";
  }

  getRootConfigurationKey() {
    return "ide-python";
  }

  activate() {
    // Remove deprecated option
    atom.config.unset("ide-python.pylsPath");
    super.activate();
    debuggerActivate();
  }

  mapConfigurationObject(configuration) {
    return {
      pyls: {
        configurationSources: configuration.pylsConfigurationSources,
        rope: sanitizeConfig(configuration.rope),
        plugins: configuration.pylsPlugins
      }
    };
  }

  async startServerProcess(projectPath) {
    const venvPath =
      (await detectPipEnv(projectPath)) ||
      (await detectVirtualEnv(projectPath));
    const pylsEnvironment = Object.assign({}, process.env);
    if (venvPath) {
      pylsEnvironment["VIRTUAL_ENV"] = venvPath;
    }
    const python = replacePipEnvPathVar(
      atom.config.get("ide-python.python"),
      venvPath
    );
    const childProcess = cp.spawn(python, ["-m", "pyls"], {
      cwd: projectPath,
      env: pylsEnvironment
    });
    childProcess.on("error", err => {
      const description =
        err.code == "ENOENT"
          ? `No Python interpreter found at \`${python}\`.`
          : `Could not spawn the Python interpreter \`${python}\`.`;
      atom.notifications.addError(
        "`ide-python` could not launch your Python runtime.",
        {
          dismissable: true,
          description: `${description}<p>If you have Python installed please set "Python Executable" setting correctly. If you do not please install Python.</p>`
        }
      );
    });

    childProcess.on("close", (code, signal) => {
      if (code !== 0 && signal == null) {
        atom.notifications.addError(
          "Unable to start the Python language server.",
          {
            dismissable: true,
            buttons: [
              {
                text: "Install Instructions",
                onDidClick: () =>
                  atom.workspace.open("atom://config/packages/ide-python")
              },
              {
                text: "Download Python",
                onDidClick: () =>
                  shell.openExternal("https://www.python.org/downloads/")
              }
            ],
            description:
              "Make sure to install `pyls` 0.19 or newer by running:\n" +
              "```\n" +
              `${python} -m pip install 'python-language-server[all]'\n` +
              "```"
          }
        );
      }
    });
    return childProcess;
  }

  async getSuggestions(request) {
    if (!PYTHON_REGEX.test(request.prefix)) return null;
    return super.getSuggestions(request);
  }

  deactivate() {
    debuggerDispose();
    return Promise.race([super.deactivate(), this.createTimeoutPromise(2000)]);
  }

  createTimeoutPromise(milliseconds) {
    return new Promise((resolve, reject) => {
      let timeout = setTimeout(() => {
        clearTimeout(timeout);
        this.logger.error(
          `Server failed to shutdown in ${milliseconds}ms, forcing termination`
        );
        resolve();
      }, milliseconds);
    });
  }
}

module.exports = {...new PythonLanguageClient(), createDebuggerProvider};
<|endoftext|>


<commit_before>
var fs = require('fs');
var optimist = require('optimist');
var winston = require('winston');
var argv = optimist.boolean(['t', 'h', 'm', 's'])
        .alias({
            'h': 'help',
            'm': 'all-maps',
            'o': 'host',
            'r': 'replay-dir',
            's': 'series',
            't': 'all-teams'
        })
        .describe({
            'h': 'Prints usage',
            'm': 'Runs all teams specified on all maps in maps/',
            'o': 'Specify a host for the tournament for VsWorld',
            'r': 'Specify the directory to save the replays in',
            's': 'Players play the maps in series instead 1 by 1',
            't': 'Runs all teams in teams/ on the specified maps'
        })
        .argv;

var runMatches = require('./runMatches').runMatches;
var validate = require('./validate');

var LOG_LEVEL = 'warning';
winston.remove(winston.transports.Console);
winston.add(winston.transports.Console, {level: LOG_LEVEL});

function printHelp() {
    console.log('Usage:');
    console.log('  archon [options] [maps] [teams]');
    console.log('  (replays saved in replays/ folder');
    console.log('Example:');
    console.log('  archon maps/map1.xml teams/team1/ teams/team2/');
    console.log(' ');
    optimist.showHelp();
}

(function() {
    var host, maps, teams, validateTeams, validateMaps;

    if (argv.h) {
        printHelp();
        return;
    }

    var mapsTeams = validate.getMapsAndTeams(argv._);
    maps = mapsTeams[0];
    teams = mapsTeams[1];
    if (argv.m) {
        maps = validate.removeSystemFolders(fs.readdirSync('maps/'));
    }
    if (argv.t) {
        teams = validate.removeSystemFolders(fs.readdirSync('teams/'));
    }
    if (argv.host) {
        host = validate.stripLeadingPaths([argv.host])[0];
        while(teams.indexOf(host) !== -1) {
            teams.splice(teams.indexOf(host), 1);
        }
    }
    try {
        validateTeams = teams.slice(0);
        if (host) {
            validateTeams.push(host)
        }
        validateMaps = maps.slice(0);
        validate.validate(validateMaps, validateTeams, argv.s);
    } catch (e) {
        console.log('Looks like one of the inputs is wrong!');
        console.log(' ');
        printHelp();
        throw e;
    }
    runMatches(maps, teams, host, argv.s);
}).call(this);<commit_msg>Added a couple comments, Merry Christmas!<commit_after>
var fs = require('fs');
var optimist = require('optimist');
var winston = require('winston');
// set up all the optimist params
var argv = optimist.boolean(['t', 'h', 'm', 's'])
        .alias({
            'h': 'help',
            'm': 'all-maps',
            'o': 'host',
            'r': 'replay-dir',
            's': 'series',
            't': 'all-teams'
        })
        .describe({
            'h': 'Prints usage',
            'm': 'Runs all teams specified on all maps in maps/',
            'o': 'Specify a host for the tournament for VsWorld',
            'r': 'Specify the directory to save the replays in',
            's': 'Players play the maps in series instead 1 by 1',
            't': 'Runs all teams in teams/ on the specified maps'
        })
        .argv;

var runMatches = require('./runMatches').runMatches;
var validate = require('./validate');

var LOG_LEVEL = 'warning';
winston.remove(winston.transports.Console);
winston.add(winston.transports.Console, {level: LOG_LEVEL});

// prints the help function
function printHelp() {
    console.log('Usage:');
    console.log('  archon [options] [maps] [teams]');
    console.log('  (replays saved in replays/ folder');
    console.log('Example:');
    console.log('  archon maps/map1.xml teams/team1/ teams/team2/');
    console.log(' ');
    optimist.showHelp();
}

(function() {
    var host, maps, teams, validateTeams, validateMaps;

    if (argv.h) {
        printHelp();
        return;
    }

    var mapsTeams = validate.getMapsAndTeams(argv._);
    maps = mapsTeams[0];
    teams = mapsTeams[1];
    if (argv.m) {
        maps = validate.removeSystemFolders(fs.readdirSync('maps/'));
    }
    if (argv.t) {
        teams = validate.removeSystemFolders(fs.readdirSync('teams/'));
    }
    if (argv.host) {
        host = validate.stripLeadingPaths([argv.host])[0];
        while(teams.indexOf(host) !== -1) {
            teams.splice(teams.indexOf(host), 1);
        }
    }
    try {
        validateTeams = teams.slice(0);
        if (host) {
            validateTeams.push(host)
        }
        validateMaps = maps.slice(0);
        validate.validate(validateMaps, validateTeams, argv.s);
    } catch (e) {
        console.log('Looks like one of the inputs is wrong!');
        console.log(' ');
        printHelp();
        throw e;
    }
    runMatches(maps, teams, host, argv.s);
}).call(this);<|endoftext|>