<commit_before>///////////////////////////////////////////
// MODULE IMPORTS
///////////////////////////////////////////

var express = require('express');
var passport = require('passport')
var OAuth2Strategy = require('passport-oauth').OAuth2Strategy;
var request = require('request');
// local module
var appConfig = require('./appConfig');

///////////////////////////////////////////
//  COMMON FUNCTIONS
///////////////////////////////////////////

// simplified request handling
function handleRequest(user, options, callback) {
  request({
        'uri' : appConfig.requestUrl + options.uri,
        'body' : options.body,
        'method' : options.method,
        'headers' :  { 'Authorization': 'Bearer ' + user.accessToken,
	               'Content-Type': 'application/json'}
  },
  function(error, response, body) {
    if(error) {
      callback(user,null);
      return;
    }

    if (response.statusCode === 200) {
      callback(user,JSON.parse(body));
    } else {
      callback(user,response.statusCode);
    }
  });
};

// require token for session enabled request
// thanks slc sdk...
function requireToken() {
  return function(req, res, next) {
     if (req.session.passport.user &&
         findUser(req)) {
       next();
     }
     else {
       res.redirect('/login');
     }
   }
}

///////////////////////////////////////////
// PERSISTENT SESSION SETUP
// Note : Use a real store
///////////////////////////////////////////

var users = [];

// retrieve user for request
function findUser(request) {
  return users[request.session.passport.user];
};

// store user in persistent storage for passport
passport.serializeUser(function(user, done) {
  users[user.user_id] = user;
  done(null, user.user_id);
});

// retrieve user from persistent store for passport
passport.deserializeUser(function(id, done) {
  var user = users[id];
  done(null, user);
});

///////////////////////////////////////////
// APP AND MODULE CONFIG
///////////////////////////////////////////

// setup oauth through passport
passport.use('slc', new OAuth2Strategy({
    authorizationURL: appConfig.oauth.authorizationUrl,
    tokenURL: appConfig.oauth.tokenUrl,
    clientID: appConfig.oauth.clientId,
    clientSecret: appConfig.oauth.clientSecret,
    callbackURL: appConfig.oauth.callbackUrl
  },
  function(accessToken, refreshToken, profile, done) {
    var fakeUser = { 'accessToken' : accessToken };
    var options =  { 'method' : 'GET',
                     'uri' : '/system/session/check' };
    var callback = function(user, data) {
      var fullUser = null;
      if(data  && data.user_id) {
        fullUser = data;
        fullUser.accessToken = user.accessToken;
      }
      done(null, fullUser);
    };
    handleRequest(fakeUser,options,callback);
  }
));

// setup express server
var app = express();
app.configure(function() {
  app.use(express.cookieParser());
  app.use(express.bodyParser());
  // session initialization
  app.use(express.session({ secret: appConfig.sessionSecret }));
  // passpport initialization
  app.use(passport.initialize());
  app.use(passport.session());
  // set location for css, javasript, images
  app.use(express.static(__dirname + '/public'));
  // setup jade
  app.set('views', __dirname + '/views');
  app.set('view engine', 'jade');
});

///////////////////////////////////////////
// SESSION HANDLING REQUEST HANDLERS
///////////////////////////////////////////

// entry point for slc auth
app.get('/auth/slc', passport.authenticate('slc'));

// callback for slc auth
app.get('/auth/slc/callback',
  passport.authenticate('slc', { successRedirect: '/',
                                 failureRedirect: '/login' }));

// login setup
app.get('/login', function(req, res){
  res.render('login.jade',{ 'title' : 'My App - Login' });
});

// logout handler
app.get('/logout', requireToken(), function(req, res) {
  handleRequest(findUser(req),
                { 'method' : 'GET', 'uri' : '/system/session/logout' },
		function(user, data) {
                  res.redirect('/login');
		});
});

///////////////////////////////////////////
// APP SPECIFIC REQUEST HANDLERS
///////////////////////////////////////////

app.get('/', requireToken(), function(req, res) {
  res.redirect('/dashboard');
});

app.get('/dashboard', requireToken(), function(req, res) {
  res.render('index.jade',{ 'title' : 'My App' });
});

app.get('/schools', requireToken(), function(req, res) {
  handleRequest(findUser(req),
                { 'method' : 'GET', 'uri' : '/schools' },
		function(user, data) {
                  res.render('schools.jade',{ 'title' : 'My App - Schools', 'schools' : data });
		});
});

app.get('/students', requireToken(), function(req, res) {
  handleRequest(findUser(req),
                { 'method' : 'GET', 'uri' : '/students' },
		function(user, data) {
                  res.render('students.jade',{ 'title' : 'My App - Students', 'students' : data });
		});
});

///////////////////////////////////////////
// APP STARTUP
///////////////////////////////////////////

app.listen(appConfig.port);
console.log('Listening on port ' + appConfig.port);
<commit_msg>added content-length handling for put and post<commit_after>///////////////////////////////////////////
// MODULE IMPORTS
///////////////////////////////////////////

var express = require('express');
var passport = require('passport')
var OAuth2Strategy = require('passport-oauth').OAuth2Strategy;
var request = require('request');
// local module
var appConfig = require('./appConfig');

///////////////////////////////////////////
//  COMMON FUNCTIONS
///////////////////////////////////////////

// simplified request handling
function handleRequest(user, options, callback) {
  var headers =  { 'Authorization': 'Bearer ' + user.accessToken,
                   'Content-Type': 'application/json'};
  var method = options.method.toUpperCase();
  if(method=='PUT' || method=='POST') {
    options.body = JSON.stringify(options.body);
    headers['Content-Length'] = options.body.length; // Setting up content length in the request header
  }

  request({
        'uri' : appConfig.requestUrl + options.uri,
        'body' : options.body,
        'method' : options.method,
        'headers' : headers
  },
  function(error, response, body) {
    if(error) {
      callback(user,null);
      return;
    }

    if (response.statusCode === 200) {
      callback(user,JSON.parse(body));
    } else {
      callback(user,response.statusCode);
    }
  });
};

// require token for session enabled request
// thanks slc sdk...
function requireToken() {
  return function(req, res, next) {
     if (req.session.passport.user &&
         findUser(req)) {
       next();
     }
     else {
       res.redirect('/login');
     }
   }
}

///////////////////////////////////////////
// PERSISTENT SESSION SETUP
// Note : Use a real store
///////////////////////////////////////////

var users = [];

// retrieve user for request
function findUser(request) {
  return users[request.session.passport.user];
};

// store user in persistent storage for passport
passport.serializeUser(function(user, done) {
  users[user.user_id] = user;
  done(null, user.user_id);
});

// retrieve user from persistent store for passport
passport.deserializeUser(function(id, done) {
  var user = users[id];
  done(null, user);
});

///////////////////////////////////////////
// APP AND MODULE CONFIG
///////////////////////////////////////////

// setup oauth through passport
passport.use('slc', new OAuth2Strategy({
    authorizationURL: appConfig.oauth.authorizationUrl,
    tokenURL: appConfig.oauth.tokenUrl,
    clientID: appConfig.oauth.clientId,
    clientSecret: appConfig.oauth.clientSecret,
    callbackURL: appConfig.oauth.callbackUrl
  },
  function(accessToken, refreshToken, profile, done) {
    var fakeUser = { 'accessToken' : accessToken };
    var options =  { 'method' : 'GET',
                     'uri' : '/system/session/check' };
    var callback = function(user, data) {
      var fullUser = null;
      if(data  && data.user_id) {
        fullUser = data;
        fullUser.accessToken = user.accessToken;
      }
      done(null, fullUser);
    };
    handleRequest(fakeUser,options,callback);
  }
));

// setup express server
var app = express();
app.configure(function() {
  app.use(express.cookieParser());
  app.use(express.bodyParser());
  // session initialization
  app.use(express.session({ secret: appConfig.sessionSecret }));
  // passpport initialization
  app.use(passport.initialize());
  app.use(passport.session());
  // set location for css, javasript, images
  app.use(express.static(__dirname + '/public'));
  // setup jade
  app.set('views', __dirname + '/views');
  app.set('view engine', 'jade');
});

///////////////////////////////////////////
// SESSION HANDLING REQUEST HANDLERS
///////////////////////////////////////////

// entry point for slc auth
app.get('/auth/slc', passport.authenticate('slc'));

// callback for slc auth
app.get('/auth/slc/callback',
  passport.authenticate('slc', { successRedirect: '/',
                                 failureRedirect: '/login' }));

// login setup
app.get('/login', function(req, res){
  res.render('login.jade',{ 'title' : 'My App - Login' });
});

// logout handler
app.get('/logout', requireToken(), function(req, res) {
  handleRequest(findUser(req),
                { 'method' : 'GET', 'uri' : '/system/session/logout' },
		function(user, data) {
                  res.redirect('/login');
		});
});

///////////////////////////////////////////
// APP SPECIFIC REQUEST HANDLERS
///////////////////////////////////////////

app.get('/', requireToken(), function(req, res) {
  res.redirect('/dashboard');
});

app.get('/dashboard', requireToken(), function(req, res) {
  res.render('index.jade',{ 'title' : 'My App' });
});

app.get('/schools', requireToken(), function(req, res) {
  handleRequest(findUser(req),
                { 'method' : 'GET', 'uri' : '/schools' },
		function(user, data) {
                  res.render('schools.jade',{ 'title' : 'My App - Schools', 'schools' : data });
		});
});

app.get('/students', requireToken(), function(req, res) {
  handleRequest(findUser(req),
                { 'method' : 'GET', 'uri' : '/students' },
		function(user, data) {
                  res.render('students.jade',{ 'title' : 'My App - Students', 'students' : data });
		});
});

///////////////////////////////////////////
// APP STARTUP
///////////////////////////////////////////

app.listen(appConfig.port);
console.log('Listening on port ' + appConfig.port);
<|endoftext|>


<commit_before>'use strict'

var leader = require('./')('chat')
var eos = require('end-of-stream')
var sockets = []

leader.on('leader', function () {
  console.log('!! I am the the leader now', process.pid)
})

leader.on('connection', function (sock) {
  sock.write('!! connected to ' + process.pid)
  sock.write('\n')

  sockets.forEach(function (other) {
    other.pipe(sock, { end: false }).pipe(other, { end: false })
  })

  sockets.push(sock)

  eos(sock, function () {
    sockets.splice(sockets.indexOf(sock), 1)
  })
})

leader.on('client', function (sock) {
  process.stdout.pipe(sock).pipe(process.stdout)
})

<commit_msg>Updated example.<commit_after>'use strict'

var leader = require('./')('chat')
var eos = require('end-of-stream')
var sockets = []
var popts = { end: false }

leader.on('leader', function () {
  console.log('!! I am the the leader now', process.pid)
})

leader.on('connection', function (sock) {
  sock.write('!! connected to ' + process.pid)
  sock.write('\n')

  sockets.forEach(function (other) {
    other.pipe(sock, popts).pipe(other, popts)
  })

  sockets.push(sock)

  eos(sock, function () {
    sockets.splice(sockets.indexOf(sock), 1)
  })
})

leader.on('client', function (sock) {
  process.stdout.pipe(sock, popts).pipe(process.stdout, popts)
})

<|endoftext|>


<commit_before>// Instantiate TaskQueue, and pass callback functions.
// The instance is also referenced within itself, to allow access to instance
// properties.  I'm not crazy about this approach. (ie. 'q.total' etc)
var q = new TaskQueue({
    completed : function() {
      console.log("taskQueueCompletedCallback");
    },
    added : function(){
      var loaded = q.total - q.queued + 1;
      console.log("taskQueueAddCallback: "+ loaded + "/" + q.total);
    },
    removed : function(){
      var loaded = q.total - q.queued;
      console.log("taskQueueRemoveCallback: " + loaded + "/" + q.total);
    }
  }),
  // Collecting a list of tasks, with artificial delay to display async behavior.
  // Task functions must accept a callback. Currently, the instance must be
  // passed as the 'this' value when calling the callback. (Not crazy about
  // this setup either)
  tasks = [
    function(cb){var rand = Math.floor(Math.random() * 1000); setTimeout( function () { console.log("a : " + rand/1000); cb.call(q); }, rand );},
    function(cb){var rand = Math.floor(Math.random() * 1000); setTimeout( function () { console.log("b : " + rand/1000); cb.call(q); }, rand );},
    function(cb){var rand = Math.floor(Math.random() * 1000); setTimeout( function () { console.log("c : " + rand/1000); cb.call(q); }, rand );},
    function(cb){var rand = Math.floor(Math.random() * 1000); setTimeout( function () { console.log("d : " + rand/1000); cb.call(q); }, rand );},
    function(cb){var rand = Math.floor(Math.random() * 1000); setTimeout( function () { console.log("e : " + rand/1000); cb.call(q); }, rand );}
  ],
  task;

// Add/Execute Collected Tasks
for (task in tasks) {
  if (tasks.hasOwnProperty(task)) {
    q.add(tasks[task]);
  }
}
<commit_msg>Simplified example for adding tasks, reducing extraneous code.<commit_after>// Instantiate TaskQueue, and define callback functions.
// The instance is also referenced within itself, to allow access to instance
// properties.  I'm not crazy about this approach. (ie. 'q.total' etc)
var q = new TaskQueue({
    completed : function () {
        console.log("taskQueueCompletedCallback");
    },
    added : function () {
        var loaded = q.total - q.queued + 1;
        console.log("taskQueueAddCallback: "+ loaded + "/" + q.total);
    },
    removed : function () {
        var loaded = q.total - q.queued;
        console.log("taskQueueRemoveCallback: " + loaded + "/" + q.total);
    }
  });

// Add & execute tasks.
// These example tasks contain an artificial delay to mimic async behavior.
// Task functions must accept a callback. Currently, the instance must be
// passed as the 'this' value when calling the callback. (Not crazy about
// this approach either)
q.add( function (cb) { var rand = Math.floor(Math.random() * 1000); setTimeout( function () { console.log("a : " + rand/1000); cb.call(q); }, rand ); } );
q.add( function (cb) { var rand = Math.floor(Math.random() * 1000); setTimeout( function () { console.log("b : " + rand/1000); cb.call(q); }, rand ); } );
q.add( function (cb) { var rand = Math.floor(Math.random() * 1000); setTimeout( function () { console.log("c : " + rand/1000); cb.call(q); }, rand ); } );
q.add( function (cb) { var rand = Math.floor(Math.random() * 1000); setTimeout( function () { console.log("d : " + rand/1000); cb.call(q); }, rand ); } );
q.add( function (cb) { var rand = Math.floor(Math.random() * 1000); setTimeout( function () { console.log("e : " + rand/1000); cb.call(q); }, rand ); } );
<|endoftext|>


<commit_before>require({
  baseUrl: './src'
}, [ 'html-janitor' ], function (HTMLJanitor) {
  var janitor = new HTMLJanitor({
    tags: {
      p: []
    }
  });

  var p = document.createElement('p');
  p.setAttribute('style', 'font-size: 16px;');
  p.setAttribute('class', 'example-class');
  console.log(janitor.clean(p.outerHTML));
});
<commit_msg>Update example too<commit_after>require({
  baseUrl: './src'
}, [ 'html-janitor' ], function (HTMLJanitor) {
  var janitor = new HTMLJanitor({
    tags: {
      p: { foo: undefined, bar: 'baz' }
    }
  });

  var p = document.createElement('p');
  p.setAttribute('style', 'font-size: 16px;');
  p.setAttribute('bar', 'baz');
  console.log(janitor.clean(p.outerHTML));
});
<|endoftext|>


<commit_before>'use strict';

//Require the module
const TinyCrashReporter = require('./index');

//Initiate the module
//Module accepts a boolean on whether to stop execution on expception, defaults to true
TinyCrashReporter(false);

//If an error occurs, crash reporter will catch and log it
someMissingObject.someMissingFunction();

console.log(`This code shouldn't execute`);<commit_msg>Updated example<commit_after>'use strict';

//Require the module
const TinyCrashReporter = require('./index');

//Initiate the module
//Module accepts a boolean on whether to stop execution on expception, defaults to true
TinyCrashReporter(true);

//If an error occurs, crash reporter will catch and log it
someMissingObject.someMissingFunction();

console.log(`This code shouldn't execute`);<|endoftext|>


<commit_before>// ==UserScript==
// @name            FarmTimer
// @namespace       https://github.com/MyRequiem/comfortablePlayingInGW
// @description     Выводит таймер для фермы рядом с "Об игре | Форум". Звуковое оповещение когда пора полить/собрать.
// @id              comfortablePlayingInGW@MyRequiem
// @updateURL       https://raw.githubusercontent.com/MyRequiem/comfortablePlayingInGW/master/separatedScripts/FarmTimer/farmTimer.meta.js
// @downloadURL     https://raw.githubusercontent.com/MyRequiem/comfortablePlayingInGW/master/separatedScripts/FarmTimer/farmTimer.user.js
// @include         http://www.gwars.ru/*
// @grant           none
// @license         MIT
// @version         2.14-011018
// @author          MyRequiem [http://www.gwars.ru/info.php?id=2095458]
// ==/UserScript==

/*global unsafeWindow */
/*jslint browser: true, maxlen: 80, vars: true, regexp: true, nomen: true
    devel: true
*/

/*eslint-env browser */
/*eslint no-useless-escape: 'warn', linebreak-style: ['error', 'unix'],
    quotes: ['error', 'single'], semi: ['error', 'always'],
    eqeqeq: 'error', curly: 'error'
*/

/*jscs:disable requireMultipleVarDecl, requireVarDeclFirst */
/*jscs:disable disallowKeywords, disallowDanglingUnderscores */
/*jscs:disable validateIndentation */

(function () {
    'use strict';

    // ============================ НАСТРОЙКИ ==================================
        // звук когда пора поливать/собирать(0 - без звука)
    var farmSound = 8,
        // повторять звук не чаще чем один раз в X секунд (0 - не повторять)
        soundInterval = 120;
    // ========================= КОНЕЦ НАСТРОЕК ================================

    /**
     * @class General
     * @constructor
     */
    var General = function () {
        /**
         * @property root
         * @type {Object}
         */
        this.root = this.getRoot();
        /**
         * @property doc
         * @type {Object}
         */
        this.doc = this.root.document;
        /**
         * @property loc
         * @type {String}
         */
        this.loc = this.root.location.href;
        /**
         * @property st
         * @type {Object}
         */
        this.st = this.root.localStorage;
        /**
         * @property STNAME
         * @type {String}
         */
        this.STNAME = 'farmTimer';
        /**
         * @property myID
         * @type {String}
         */
        this.myID = /(^|;) ?uid=([^;]*)(;|$)/.exec(this.doc.cookie)[2];
        /**
         * @property DESIGN_VERSION
         * @type {String}
         */
        this.DESIGN_VERSION = /(^|;) ?version=([^;]*)(;|$)/.
                exec(this.doc.cookie)[2];
    };

    /**
     * @lends General.prototype
     */
    General.prototype = {
        /**
         * @method getRoot
         * @return  {Object}
         */
        getRoot: function () {
            var rt = typeof unsafeWindow;
            return rt !== 'undefined' ? unsafeWindow : window;
        },

        /**
         * @method setData
         * @param   {Array} data
         */
        setData: function (data) {
            this.st.setItem(this.STNAME, data.join('|'));
        },

        /**
         * @method getData
         * @return  {Array}
         */
        getData: function () {
            var stData = this.st.getItem(this.STNAME);
            if (stData) {
                return stData.split('|');
            }

            stData = ['', '', '', ''];
            this.setData(stData);
            return stData;
        }
    };

    var general = new General();

    /**
     * @class GetTopPanel
     * @constructor
     */
    var GetTopPanel = function () {
        /**
         * @method init
         * @return  {HTMLElement|null}
         */
        this.init = function () {
            // ищем верхнюю панель "MyRequiem [603/603] ... 21:01, 3095 онлайн"
            var topPanel;

            if (general.DESIGN_VERSION === 'v2') {  // новый дизайн
                topPanel = general.doc.querySelector('td.gw-header-col2 ' +
                        'td[width="50%"][valign="middle"]');
                if (topPanel) {
                    topPanel.setAttribute('style', 'width: 70%;');
                }
            } else {
                topPanel = general.doc.
                    querySelector('td.txt[align="left"] nobr:first-child');
                if (topPanel) {
                    topPanel.parentNode.setAttribute('style', 'width: 70%;');
                }
            }

            return topPanel;
        };
    };

    /**
     * @class PlaySound
     * @constructor
     */
    var PlaySound = function () {
        /**
         * @method init
         * @param   {int|String}    sound
         */
        this.init = function (sound) {
            if (sound && sound !== '0') {
                var audio = general.doc.querySelector('#cpingw_audio');
                if (!audio) {
                    audio = general.doc.createElement('audio');
                    audio.setAttribute('id', 'cpingw_audio');
                    var divAudio = general.doc.createElement('div');
                    divAudio.setAttribute('style', 'display: none;');
                    divAudio.appendChild(audio);
                    general.doc.body.appendChild(divAudio);
                }

                audio.volume = 0.3;
                audio.src = '/sounds/' + sound + '.ogg';
                // noinspection JSIgnoredPromiseFromCall
                audio.play();
            }
        };
    };

    /**
     * @class GetRandom
     * @constructor
     */
    var GetRandom = function () {
        /**
         * @method init
         * @param   {int}   a
         * @param   {int}   b
         * @return  {int}
         */
        this.init = function (a, b) {
            return Math.round(a + (b - a) * Math.random());
        };
    };

    /**
     * @class FarmTimer
     * @constructor
     */
    var FarmTimer = function () {
        /**
         * @property farmLink
         * @type {HTMLLinkElement|null}
         */
        this.farmLink = null;
        /**
         * @property checkInterval
         * @type {int}
         */
        this.checkInterval = 0;

        /**
         * @method setRedLink
         * @param   {String}    str
         */
        this.setRedLink = function (str) {
            var action = str === '2' ? 'Собрать' : 'Полить';
            this.farmLink.setAttribute('style', 'color: #FF0000; ' +
                    'font-weight: bold; text-decoration: none;');
            this.farmLink.innerHTML = '[' + action + ']';
        };

        /**
         * @method checkState
         */
        this.checkState = function () {
            if (!(/bold/.test(this.farmLink.getAttribute('style')))) {
                if (this.checkInterval) {
                    general.root.clearInterval(this.checkInterval);
                }

                return;
            }

            var stData = general.getData();
            if (!stData[0]) {
                this.farmLink.innerHTML = '';
                return;
            }

            var timeNow = new Date().getTime(),
                time = +stData[0];

            if (timeNow <= time) {
                this.farmLink.setAttribute('style', 'color: #0000FF; ' +
                        'text-decoration: none;');
                stData[3] = '';
                general.setData(stData);
                this.showTimer(+((time - timeNow) / 1000).toFixed(0));
            }
        };

        /**
         * @method setReminder
         */
        this.setReminder = function () {
            var stData = general.getData();
            if (!stData[0]) {
                this.farmLink.innerHTML = '';
                return;
            }

            this.setRedLink(stData[1]);

            var _this = this;
            this.checkInterval = general.root.setInterval(function () {
                _this.checkState();
            }, 2000);

            if (!farmSound) {
                return;
            }

            var timeNow = new Date().getTime();
            if (timeNow < +stData[0]) {
                return;
            }

            var soundTime = +stData[2],
                intrvl = soundInterval * 1000,
                random = new GetRandom();

            // пора проигрывать звук
            if (timeNow - soundTime >= intrvl) {
                // в настройках указано не повторять звук
                if (!intrvl) {
                    // если звук еще не был проигран
                    if (!stData[3]) {
                        stData[3] = '1';
                        general.setData(stData);
                        new PlaySound().init(farmSound);
                    }

                    return;
                }

                stData[2] = timeNow;
                general.setData(stData);
                general.root.setTimeout(function () {
                    _this.setReminder();
                }, intrvl + random.init(1000, 10000));

                new PlaySound().init(farmSound);
            } else if (intrvl) {
                general.root.setTimeout(function () {
                    _this.setReminder();
                }, intrvl - (timeNow - soundTime) + random.init(1000, 10000));
            }
        };

        /**
         * @method showTimer
         * @param   {int}   sec
         */
        this.showTimer = function (sec) {
            var min,
                s,
                h;

            if (!sec) {
                this.setReminder();
                return;
            }

            s = sec;
            h = Math.floor(s / 3600);
            s -= h * 3600;
            min = Math.floor(s / 60);
            s -= min * 60;

            this.farmLink.innerHTML = '[' + (h < 10 ? '0' + h : h) + ':' +
                (min < 10 ? '0' + min : min) + ':' +
                (s < 10 ? '0' + s : s) + ']';

            sec -= 1;
            if (sec > -1) {
                var _this = this;
                general.root.setTimeout(function () {
                    _this.showTimer(sec);
                }, 1000);
            } else {
                general.root.setTimeout(this.setReminder,
                                new GetRandom().init(1000, 3000));
            }
        };

        /**
         * @method init
         */
        this.init = function () {
            if (!general.st) {
                alert('Ваш браузер не поддерживает технологию localStorage.' +
                    '\nMyRequiеm рекомендует вам установить один из\n' +
                    'ниже перечисленных браузеров или удалите скрипт\n' +
                    'FarmTimer\n\nFireFox 4+\nOpera 11+\n' +
                    'Chrome 12+');

                return;
            }

            /** localStorage:
             * [0] - время полива/сбора
             * [1] - действие (Полить|Собрать)
             * [2] - время последнего проигрывания звука
             * [3] - звук проигран?
             */
            var stData = general.getData(),
                timeNow = new Date().getTime();

            // на ферме запоминаем данные, выходим
            if (/\/ferma\.php/.test(general.loc)) {
                // не на своей ферме
                if ((/id=\d+/.test(general.loc)) &&
                        (/id=(\d+)/.exec(general.loc)[1]) !== general.myID) {
                    return;
                }

                var actionStr = /Ближайшее действие:.*[собрать|полить].*\(.*\)/.
                        exec(general.doc.querySelector('td[width="400"]' +
                                '[valign="top"]').innerHTML);

                if (!actionStr) {
                    stData[0] = '';
                    general.setData(stData);
                    return;
                }

                var aStr = actionStr[0];
                var action = /собрать/.test(aStr) ? '2' : '1';

                if (/уже пора/.test(aStr)) {
                    general.setData([timeNow, action, timeNow, '1']);
                    return;
                }

                var timeLeft = +(/через (\d+) мин/.exec(aStr)[1]);
                general.setData([timeNow + timeLeft * 60 * 1000,
                    action, timeNow, '']);

                return;
            }

            var topPanel = new GetTopPanel().init();
            if (!topPanel || !stData[0]) {
                return;
            }

            this.farmLink = general.doc.createElement('a');
            this.farmLink.setAttribute('style', 'color: #0000FF; ' +
                    'text-decoration: none;');
            this.farmLink.href = 'http://www.gwars.ru/ferma.php?id=' +
                general.myID;
            this.farmLink.setAttribute('target', '_blank');
            // noinspection JSCheckFunctionSignatures
            topPanel.appendChild(general.doc.createTextNode(' | '));
            topPanel.appendChild(this.farmLink);

            if (timeNow >= +stData[0]) {
                this.setRedLink(stData[1]);
                var _this = this;
                general.root.setTimeout(function () {
                    _this.showTimer(0);
                }, new GetRandom().init(1000, 3000));

                return;
            }

            this.showTimer(+((+stData[0] - timeNow) / 1000).toFixed(0));
        };
    };

    new FarmTimer().init();

}());

<commit_msg>farmTimer.user.js: PlaySound from github<commit_after>// ==UserScript==
// @name            FarmTimer
// @namespace       https://github.com/MyRequiem/comfortablePlayingInGW
// @description     Выводит таймер для фермы рядом с "Об игре | Форум". Звуковое оповещение когда пора полить/собрать.
// @id              comfortablePlayingInGW@MyRequiem
// @updateURL       https://raw.githubusercontent.com/MyRequiem/comfortablePlayingInGW/master/separatedScripts/FarmTimer/farmTimer.meta.js
// @downloadURL     https://raw.githubusercontent.com/MyRequiem/comfortablePlayingInGW/master/separatedScripts/FarmTimer/farmTimer.user.js
// @include         http://www.gwars.ru/*
// @grant           none
// @license         MIT
// @version         2.15-131018
// @author          MyRequiem [http://www.gwars.ru/info.php?id=2095458]
// ==/UserScript==

/*global unsafeWindow */
/*jslint browser: true, maxlen: 80, vars: true, regexp: true, nomen: true
    devel: true
*/

/*eslint-env browser */
/*eslint no-useless-escape: 'warn', linebreak-style: ['error', 'unix'],
    quotes: ['error', 'single'], semi: ['error', 'always'],
    eqeqeq: 'error', curly: 'error'
*/

/*jscs:disable requireMultipleVarDecl, requireVarDeclFirst */
/*jscs:disable disallowKeywords, disallowDanglingUnderscores */
/*jscs:disable validateIndentation */

(function () {
    'use strict';

    // ============================ НАСТРОЙКИ ==================================
        // звук когда пора поливать/собирать(0 - без звука)
    var farmSound = 8,
        // повторять звук не чаще чем один раз в X секунд (0 - не повторять)
        soundInterval = 120;
    // ========================= КОНЕЦ НАСТРОЕК ================================

    /**
     * @class General
     * @constructor
     */
    var General = function () {
        /**
         * @property root
         * @type {Object}
         */
        this.root = this.getRoot();
        /**
         * @property doc
         * @type {Object}
         */
        this.doc = this.root.document;
        /**
         * @property loc
         * @type {String}
         */
        this.loc = this.root.location.href;
        /**
         * @property st
         * @type {Object}
         */
        this.st = this.root.localStorage;
        /**
         * @property STNAME
         * @type {String}
         */
        this.STNAME = 'farmTimer';
        /**
         * @property myID
         * @type {String}
         */
        this.myID = /(^|;) ?uid=([^;]*)(;|$)/.exec(this.doc.cookie)[2];
        /**
         * @property DESIGN_VERSION
         * @type {String}
         */
        this.DESIGN_VERSION = /(^|;) ?version=([^;]*)(;|$)/.
                exec(this.doc.cookie)[2];
    };

    /**
     * @lends General.prototype
     */
    General.prototype = {
        /**
         * @method getRoot
         * @return  {Object}
         */
        getRoot: function () {
            var rt = typeof unsafeWindow;
            return rt !== 'undefined' ? unsafeWindow : window;
        },

        /**
         * @method setData
         * @param   {Array} data
         */
        setData: function (data) {
            this.st.setItem(this.STNAME, data.join('|'));
        },

        /**
         * @method getData
         * @return  {Array}
         */
        getData: function () {
            var stData = this.st.getItem(this.STNAME);
            if (stData) {
                return stData.split('|');
            }

            stData = ['', '', '', ''];
            this.setData(stData);
            return stData;
        }
    };

    var general = new General();

    /**
     * @class GetTopPanel
     * @constructor
     */
    var GetTopPanel = function () {
        /**
         * @method init
         * @return  {HTMLElement|null}
         */
        this.init = function () {
            // ищем верхнюю панель "MyRequiem [603/603] ... 21:01, 3095 онлайн"
            var topPanel;

            if (general.DESIGN_VERSION === 'v2') {  // новый дизайн
                topPanel = general.doc.querySelector('td.gw-header-col2 ' +
                        'td[width="50%"][valign="middle"]');
                if (topPanel) {
                    topPanel.setAttribute('style', 'width: 70%;');
                }
            } else {
                topPanel = general.doc.
                    querySelector('td.txt[align="left"] nobr:first-child');
                if (topPanel) {
                    topPanel.parentNode.setAttribute('style', 'width: 70%;');
                }
            }

            return topPanel;
        };
    };

    /**
     * @class PlaySound
     * @constructor
     */
    var PlaySound = function () {
        /**
         * @method init
         * @param   {int|String}    sound
         */
        this.init = function (sound) {
            if (sound && sound !== '0') {
                var audio = general.doc.querySelector('#cpingw_audio');
                if (!audio) {
                    audio = general.doc.createElement('audio');
                    audio.setAttribute('id', 'cpingw_audio');
                    var divAudio = general.doc.createElement('div');
                    divAudio.setAttribute('style', 'display: none;');
                    divAudio.appendChild(audio);
                    general.doc.body.appendChild(divAudio);
                }

                audio.volume = 0.3;
                audio.src = 'https://raw.githubusercontent.com/MyRequiem/' +
                    'comfortablePlayingInGW/master/sounds/' + sound + '.ogg';
                // noinspection JSIgnoredPromiseFromCall
                audio.play();
            }
        };
    };

    /**
     * @class GetRandom
     * @constructor
     */
    var GetRandom = function () {
        /**
         * @method init
         * @param   {int}   a
         * @param   {int}   b
         * @return  {int}
         */
        this.init = function (a, b) {
            return Math.round(a + (b - a) * Math.random());
        };
    };

    /**
     * @class FarmTimer
     * @constructor
     */
    var FarmTimer = function () {
        /**
         * @property farmLink
         * @type {HTMLLinkElement|null}
         */
        this.farmLink = null;
        /**
         * @property checkInterval
         * @type {int}
         */
        this.checkInterval = 0;

        /**
         * @method setRedLink
         * @param   {String}    str
         */
        this.setRedLink = function (str) {
            var action = str === '2' ? 'Собрать' : 'Полить';
            this.farmLink.setAttribute('style', 'color: #FF0000; ' +
                    'font-weight: bold; text-decoration: none;');
            this.farmLink.innerHTML = '[' + action + ']';
        };

        /**
         * @method checkState
         */
        this.checkState = function () {
            if (!(/bold/.test(this.farmLink.getAttribute('style')))) {
                if (this.checkInterval) {
                    general.root.clearInterval(this.checkInterval);
                }

                return;
            }

            var stData = general.getData();
            if (!stData[0]) {
                this.farmLink.innerHTML = '';
                return;
            }

            var timeNow = new Date().getTime(),
                time = +stData[0];

            if (timeNow <= time) {
                this.farmLink.setAttribute('style', 'color: #0000FF; ' +
                        'text-decoration: none;');
                stData[3] = '';
                general.setData(stData);
                this.showTimer(+((time - timeNow) / 1000).toFixed(0));
            }
        };

        /**
         * @method setReminder
         */
        this.setReminder = function () {
            var stData = general.getData();
            if (!stData[0]) {
                this.farmLink.innerHTML = '';
                return;
            }

            this.setRedLink(stData[1]);

            var _this = this;
            this.checkInterval = general.root.setInterval(function () {
                _this.checkState();
            }, 2000);

            if (!farmSound) {
                return;
            }

            var timeNow = new Date().getTime();
            if (timeNow < +stData[0]) {
                return;
            }

            var soundTime = +stData[2],
                intrvl = soundInterval * 1000,
                random = new GetRandom();

            // пора проигрывать звук
            if (timeNow - soundTime >= intrvl) {
                // в настройках указано не повторять звук
                if (!intrvl) {
                    // если звук еще не был проигран
                    if (!stData[3]) {
                        stData[3] = '1';
                        general.setData(stData);
                        new PlaySound().init(farmSound);
                    }

                    return;
                }

                stData[2] = timeNow;
                general.setData(stData);
                general.root.setTimeout(function () {
                    _this.setReminder();
                }, intrvl + random.init(1000, 10000));

                new PlaySound().init(farmSound);
            } else if (intrvl) {
                general.root.setTimeout(function () {
                    _this.setReminder();
                }, intrvl - (timeNow - soundTime) + random.init(1000, 10000));
            }
        };

        /**
         * @method showTimer
         * @param   {int}   sec
         */
        this.showTimer = function (sec) {
            var min,
                s,
                h;

            if (!sec) {
                this.setReminder();
                return;
            }

            s = sec;
            h = Math.floor(s / 3600);
            s -= h * 3600;
            min = Math.floor(s / 60);
            s -= min * 60;

            this.farmLink.innerHTML = '[' + (h < 10 ? '0' + h : h) + ':' +
                (min < 10 ? '0' + min : min) + ':' +
                (s < 10 ? '0' + s : s) + ']';

            sec -= 1;
            if (sec > -1) {
                var _this = this;
                general.root.setTimeout(function () {
                    _this.showTimer(sec);
                }, 1000);
            } else {
                general.root.setTimeout(this.setReminder,
                                new GetRandom().init(1000, 3000));
            }
        };

        /**
         * @method init
         */
        this.init = function () {
            if (!general.st) {
                alert('Ваш браузер не поддерживает технологию localStorage.' +
                    '\nMyRequiеm рекомендует вам установить один из\n' +
                    'ниже перечисленных браузеров или удалите скрипт\n' +
                    'FarmTimer\n\nFireFox 4+\nOpera 11+\n' +
                    'Chrome 12+');

                return;
            }

            /** localStorage:
             * [0] - время полива/сбора
             * [1] - действие (Полить|Собрать)
             * [2] - время последнего проигрывания звука
             * [3] - звук проигран?
             */
            var stData = general.getData(),
                timeNow = new Date().getTime();

            // на ферме запоминаем данные, выходим
            if (/\/ferma\.php/.test(general.loc)) {
                // не на своей ферме
                if ((/id=\d+/.test(general.loc)) &&
                        (/id=(\d+)/.exec(general.loc)[1]) !== general.myID) {
                    return;
                }

                var actionStr = /Ближайшее действие:.*[собрать|полить].*\(.*\)/.
                        exec(general.doc.querySelector('td[width="400"]' +
                                '[valign="top"]').innerHTML);

                if (!actionStr) {
                    stData[0] = '';
                    general.setData(stData);
                    return;
                }

                var aStr = actionStr[0];
                var action = /собрать/.test(aStr) ? '2' : '1';

                if (/уже пора/.test(aStr)) {
                    general.setData([timeNow, action, timeNow, '1']);
                    return;
                }

                var timeLeft = +(/через (\d+) мин/.exec(aStr)[1]);
                general.setData([timeNow + timeLeft * 60 * 1000,
                    action, timeNow, '']);

                return;
            }

            var topPanel = new GetTopPanel().init();
            if (!topPanel || !stData[0]) {
                return;
            }

            this.farmLink = general.doc.createElement('a');
            this.farmLink.setAttribute('style', 'color: #0000FF; ' +
                    'text-decoration: none;');
            this.farmLink.href = 'http://www.gwars.ru/ferma.php?id=' +
                general.myID;
            this.farmLink.setAttribute('target', '_blank');
            // noinspection JSCheckFunctionSignatures
            topPanel.appendChild(general.doc.createTextNode(' | '));
            topPanel.appendChild(this.farmLink);

            if (timeNow >= +stData[0]) {
                this.setRedLink(stData[1]);
                var _this = this;
                general.root.setTimeout(function () {
                    _this.showTimer(0);
                }, new GetRandom().init(1000, 3000));

                return;
            }

            this.showTimer(+((+stData[0] - timeNow) / 1000).toFixed(0));
        };
    };

    new FarmTimer().init();

}());

<|endoftext|>


<commit_before>const Joi = require('joi');
const serviceService = require('../services/service-service');
const { Service } = require('../models/');
const { ServiceSchema } = require('../models/schemas');
const { createUserError } = require('../../utils');

/**
 * Fetch all the services from the database.
 *
 * @param req Request
 * @param res Response
 * @return {Promise.<void>} Nothing
 */
async function getAllServices(req, res) {
    const { start, end } = req.params;

    const services = await serviceService.getAllServices(start, end);

    res.json(services);
}

/**
 * Create a service.
 *
 * @param req Request
 * @param res Response
 * @return {Promise.<void>} Nothing
 */
async function createService(req, res) {
    const schema = Joi.array()
        .items(ServiceSchema.requiredKeys(
            'startingDate',
            'endingDate',
            'nbMax'
        ))
        .min(1);

    const { error } = schema.validate(req.body);
    if (error) throw createUserError('BadRequest', error.details.message);

    let newService = new Service({
        ...req.body
    });

    newService = await serviceService.createService(newService, req.body);

    res.json(newService);
}

/**
 * Get a service by its id.
 *
 * @param req Request
 * @param res Response
 * @return {Promise.<void>} Nothing
 */
async function getServiceById(req, res) {
    const serviceId = req.params.id;

    const service = await serviceService.getServiceById(serviceId);

    res.json(service);
}

/**
 * Update a service.
 *
 * @param req Request
 * @param res Response
 * @return {Promise.<void>} Nothing
 */
async function updateService(req, res) {
    const schema = ServiceSchema.min(1);

    const { error } = schema.validate(req.body);
    if (error) throw createUserError('BadRequest', error.details.message);

    let newService = new Service({
        ...req.body
    });

    const serviceId = req.params.id;

    newService = await serviceService.updateService(serviceId, newService, req.body);

    res.json(newService);
}

/**
 * Delete a service.
 *
 * @param req Request
 * @param res Response
 * @return {Promise.<void>} Nothing
 */
async function deleteService(req, res) {
    const serviceId = req.params.id;

    const service = await serviceService.deleteService(serviceId);

    res.json(service);
}

/**
 * Return a default template for now.
 * At the end, should return an array of templates.
 *
 * @param req Request
 * @param res Response
 * @return {Promise.<void>} Nothing
 */
async function getServicesTemplate(req, res) {

    const template = await serviceService.getServicesTemplate();

    res.json(template);
}

module.exports = {
    getAllServices,
    createService,
    updateService,
    getServiceById,
    deleteService,
    getServicesTemplate,
};
<commit_msg>ajout de CREATE et DELETE Services<commit_after>const Joi = require('joi');
const serviceService = require('../services/service-service');
const { Service } = require('../models/');
const { ServiceSchema } = require('../models/schemas');
const { createUserError } = require('../../utils');

/**
 * Fetch all the services from the database.
 *
 * @param req Request
 * @param res Response
 * @return {Promise.<void>} Nothing
 */
async function getAllServices(req, res) {
    const { start, end } = req.params;

    const services = await serviceService.getAllServices(start, end);

    res.json(services);
}

/**
 * Create a service.
 *
 * @param req Request
 * @param res Response
 * @return {Promise.<void>} Nothing
 */
async function createService(req, res) {
    const schema = Joi.array()
        .items(ServiceSchema.requiredKeys(
            'startingDate',
            'endingDate',
            'nbMax'
        ))
        .min(1);

    const { error } = schema.validate(req.body);
    if (error) throw createUserError('BadRequest', error.details.message);

    let newService = new Service({
        ...req.body
    });

    newService = await serviceService.createService(newService, req.body);

    res.json(newService);
}

/**
 * Get a service by its id.
 *
 * @param req Request
 * @param res Response
 * @return {Promise.<void>} Nothing
 */
async function getServiceById(req, res) {
    const serviceId = req.params.id;

    const service = await serviceService.getServiceById(serviceId);

    res.json(service);
}

/**
 * Update a service.
 *
 * @param req Request
 * @param res Response
 * @return {Promise.<void>} Nothing
 */
async function updateService(req, res) {
    const schema = ServiceSchema.min(1);

<<<<<<< HEAD
    const { error } = schema.validate(req.body);
    if (error) throw createUserError('BadRequest', error.details.message);

=======
    // FIXME We should check the type of each provided field, instead of just the presence
    /*if (!checkStructure(req.body, ['startAt', 'endAt', 'nbMax', 'category'])) {
        throw createUserError(
            'BadRequest',
            'The body has missing properties, needed: [\'startAt\', \'endAt\', \'nbMax\', \'category\']'
        );
    }
*/
>>>>>>> ajout de CREATE et DELETE Services
    let newService = new Service({
        ...req.body
    });

    const serviceId = req.params.id;

    newService = await serviceService.updateService(serviceId, newService, req.body);

    res.json(newService);
}

/**
 * Delete a service.
 *
 * @param req Request
 * @param res Response
 * @return {Promise.<void>} Nothing
 */
async function deleteService(req, res) {
    const serviceId = req.params.id;

    const service = await serviceService.deleteService(serviceId);

    res.json(service);
}

/**
 * Return a default template for now.
 * At the end, should return an array of templates.
 *
 * @param req Request
 * @param res Response
 * @return {Promise.<void>} Nothing
 */
async function getServicesTemplate(req, res) {

    const template = await serviceService.getServicesTemplate();

    res.json(template);
}

module.exports = {
    getAllServices,
    createService,
    updateService,
    getServiceById,
    deleteService,
    getServicesTemplate,
};
<|endoftext|>


<commit_before>const slapp = require('./slapp.js').get();
const fs = require('fs')
const request = require('request');
var github = require('./github.js');

// Hyper links detection regex
var LINKS_REGEX = /(\b(https?|ftp|file|http):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig;
// Max buffer length before pushing to github
const LINKS_BUFFER_MAX_LENGTH = 10;

var isTrackingLinks = false;
var links = [];
var linksDetector = new RegExp(LINKS_REGEX);

/**
 * This function receives a slapp message and stores the message text in a buffer if it finds an hyper link in it
 * @param {object} msg the message sent by slapp that is meant to be archived
 */
function receive(msg){
  if(isTrackingLinks)
		if(linksDetector.test(msg.body.event.text)){
			links[links.length]=msg.body.event.text;
      if(links.length == LINKS_BUFFER_MAX_LENGTH){
        links_push();
      }
    }
}
slapp.command('/links','(.*)', (msg, text, value)  => {
  slapp.client.users.info({token:msg.meta.bot_token,user:msg.body.user_id}, (err, data) => {
    if( data.user.is_admin){
      if(!text)
        msg.respond("Options for /links: \n" +
                "\`print\` prints the current links buffer waiting to be pushed to Wordpress.\n" +
                "\`start\` starts links tracking.\n" +
                "\`stop\` stops links tracking.\n"
              );
      else if(text == 'print')
        links_print(msg);
      else if(text == 'start')
        links_start(msg);
      else if(text == 'refresh')
        links_refresh(msg);
      else if(text == 'stop')
        links_stop(msg);
      else {
        msg.respond("Please use /links to print the available options \n");
      }
    }
    else {
      msg.respond("Sorry, you're not an admin");
    }
  })
})
/**
 * This function prints the messages stored in the buffer and not yet pushed to github
 * @param {object} msg the command message sent by slapp to print
 */
function links_print(msg){
	if(isTrackingLinks){
		if(links.length==0){
			msg.respond("No links posted yet.");
		}
		else{
		  var str = '\`Links waiting to be sent to Wordpress\` \n';
		  for(var i=0;i<links.length;i++) {
				str = str + '\n'
		    str = str + links[i] + '\n';
		  }
		  msg.respond(str)
		}
	}
	else {
		msg.respond("Links tracking is not in progress.");
	}
}
function start(){
  isTrackingLinks=true;
}
/**
 * This function starts the links detection and storage
 * @param {object} msg the message received from slapp following the user command
 */
function links_start(msg){
  if(github.getToken() !=''){
  	if(!isTrackingLinks){
  		isTrackingLinks=true;
  	msg.respond("Links tracking started.");
  	}
  	else {
  		msg.respond("Links tracking is already in progress.");
  	}
  }else{
    msg.respond("Please set the github token first using /github [Token].");
  }

}
/**
 * This function stops the links detection and storage
 * @param {object} msg the message received from slapp following the user command
 */
function links_stop(msg){
	if(isTrackingLinks){
		isTrackingLinks=false;
		msg.respond("Links tracking stopped.");
	}
	else {
		msg.respond("Links tracking already stopped.");
	}
}
/**
 * This function clears the buffer
 * @param {object} msg the message received from slapp following the user command
 */
function links_refresh(msg){
	links = [];
	msg.respond("Stored links deleted.");
}
/**
 * This function that handles the module behaviour when the server is about to restart
 */
function handle_restart(){
  if(links.length){
    links_push();
  }
}
/**
 * This function pushes the content of the buffer to github
 */
function links_push(){
	var filePath = "https://raw.githubusercontent.com/NeuroTechX/ntx_slack_resources/master/_pages/slack-links.md";
	request.get(filePath, function (fileerror, fileresponse, fileBody) {
  	if (!fileerror && fileresponse.statusCode == 200) {
			fileBody+="
";
			for(var i=0;i<links.length;i++){
				fileBody+="
" + links[i] + "
";
			}
			fileBody+="
";
      var content = Buffer.from(fileBody, 'ascii');
      var b64content = content.toString('base64');
			var blobPath = "https://api.github.com/repos/NeuroTechX/ntx_slack_resources/contents/_pages/slack-links.md";
      var options = {
        url: blobPath,
        headers: {
          'User-Agent': 'Edubot-GitHub-App'
        }
      };
			request.get(options, function (bloberror, blobresponse, blobBody) {
	    	if (!bloberror && blobresponse.statusCode == 200) {
          var shaStr = JSON.parse(blobBody).sha;
          ("Sha str")
					github.get().repos.updateFile({
						owner:"NeuroTechX",
						repo:"ntx_slack_resources",
						path:"_pages/slack-links.md",
						message:"Edubot Push",
						content:b64content,
						sha: shaStr
					}, function(err, res) {
                links = [];
              });

				}
			});
  	}
	});
}
module.exports = {
  receive:receive,
  handle_restart:handle_restart,
  start:start
}
<commit_msg>links direct push<commit_after>const slapp = require('./slapp.js').get();
const fs = require('fs')
const request = require('request');
var github = require('./github.js');

// Hyper links detection regex
var LINKS_REGEX = /(\b(https?|ftp|file|http):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig;
// Max buffer length before pushing to github
// const LINKS_BUFFER_MAX_LENGTH = 10;

var isTrackingLinks = false;
var links = [];
var linksDetector = new RegExp(LINKS_REGEX);

/**
 * This function receives a slapp message and stores the message text in a buffer if it finds an hyper link in it
 * @param {object} msg the message sent by slapp that is meant to be archived
 */
function receive(msg){
  if(isTrackingLinks)
		if(linksDetector.test(msg.body.event.text)){
			links[links.length]=msg.body.event.text;
      //if(links.length == LINKS_BUFFER_MAX_LENGTH){
      links_push();
      //}
    }
}
slapp.command('/links','(.*)', (msg, text, value)  => {
  slapp.client.users.info({token:msg.meta.bot_token,user:msg.body.user_id}, (err, data) => {
    if( data.user.is_admin){
      if(!text)
        msg.respond("Options for /links: \n" +
                "\`print\` prints the current links buffer waiting to be pushed to Wordpress.\n" +
                "\`start\` starts links tracking.\n" +
                "\`stop\` stops links tracking.\n"
              );
      else if(text == 'print')
        links_print(msg);
      else if(text == 'start')
        links_start(msg);
      else if(text == 'refresh')
        links_refresh(msg);
      else if(text == 'stop')
        links_stop(msg);
      else {
        msg.respond("Please use /links to print the available options \n");
      }
    }
    else {
      msg.respond("Sorry, you're not an admin");
    }
  })
})
/**
 * This function prints the messages stored in the buffer and not yet pushed to github
 * @param {object} msg the command message sent by slapp to print
 */
function links_print(msg){
	if(isTrackingLinks){
		if(links.length==0){
			msg.respond("No links posted yet.");
		}
		else{
		  var str = '\`Links waiting to be sent to Wordpress\` \n';
		  for(var i=0;i<links.length;i++) {
				str = str + '\n'
		    str = str + links[i] + '\n';
		  }
		  msg.respond(str)
		}
	}
	else {
		msg.respond("Links tracking is not in progress.");
	}
}
function start(){
  isTrackingLinks=true;
}
/**
 * This function starts the links detection and storage
 * @param {object} msg the message received from slapp following the user command
 */
function links_start(msg){
  if(github.getToken() !=''){
  	if(!isTrackingLinks){
  		isTrackingLinks=true;
  	msg.respond("Links tracking started.");
  	}
  	else {
  		msg.respond("Links tracking is already in progress.");
  	}
  }else{
    msg.respond("Please set the github token first using /github [Token].");
  }

}
/**
 * This function stops the links detection and storage
 * @param {object} msg the message received from slapp following the user command
 */
function links_stop(msg){
	if(isTrackingLinks){
		isTrackingLinks=false;
		msg.respond("Links tracking stopped.");
	}
	else {
		msg.respond("Links tracking already stopped.");
	}
}
/**
 * This function clears the buffer
 * @param {object} msg the message received from slapp following the user command
 */
function links_refresh(msg){
	links = [];
	msg.respond("Stored links deleted.");
}
/**
 * This function that handles the module behaviour when the server is about to restart
 */
function handle_restart(){
  if(links.length){
    links_push();
  }
}
/**
 * This function pushes the content of the buffer to github
 */
function links_push(){
	var filePath = "https://raw.githubusercontent.com/NeuroTechX/ntx_slack_resources/master/_pages/slack-links.md";
  var propertiesObject = { access_token:github.getToken()};
	request.get({url:filePath, qs:propertiesObject}, function (fileerror, fileresponse, fileBody) {
  	if (!fileerror && fileresponse.statusCode == 200) {
			fileBody+="
";
			for(var i=0;i<links.length;i++){
				fileBody+="
" + links[i] + "
";
			}
			fileBody+="
";
      var content = Buffer.from(fileBody, 'ascii');
      var b64content = content.toString('base64');
			var blobPath = "https://api.github.com/repos/NeuroTechX/ntx_slack_resources/contents/_pages/slack-links.md";
      var options = {
        url: blobPath,
        headers: {
          'User-Agent': 'Edubot-GitHub-App'
        }
      };
			request.get(options, function (bloberror, blobresponse, blobBody) {
	    	if (!bloberror && blobresponse.statusCode == 200) {
          var shaStr = JSON.parse(blobBody).sha;
          ("Sha str")
					github.get().repos.updateFile({
						owner:"NeuroTechX",
						repo:"ntx_slack_resources",
						path:"_pages/slack-links.md",
						message:"Edubot Push",
						content:b64content,
						sha: shaStr
					}, function(err, res) {
                links = [];
              });

				}
			});
  	}
	});
}
module.exports = {
  receive:receive,
  handle_restart:handle_restart,
  start:start
}
<|endoftext|>


<commit_before>INTROS = [
	"Sorry I'm late,",
    "Sorry for the delay,",
	"I know I'm late, but",
	"I apologize for being late,",
	"Sorry about the time,",
	"Sorry about this, but",
	"So sorry about this, but"
];

PEOPLE = ["wife", "husband", "brother", "kid", "kids", "grandma", "grandpa", "mother", "father", "friend", "girlfriend", "boyfriend", "robot butler", "dog", "cat", "hamster", "doctor", "chicken"];

PLACES_FOR_PEOPLE = ["doctor", "airport", "supermarket", "pharmacy", "hospital", "cemetary", "zoo", "school", "university", "furniture store", "asylum", "divorce lawyer"];

THINGS_THAT_BREAK = ["car", "computer", "laptop", "monitor", "mouse", "keyboard", "oven", "fridge", "VR headset", "body", "brain", "shoes", "Unity", "Photoshop", "Excel", "bicycle", "motorcycle", "bicycle helmet", "motorcycle helmet", "bed", "chair", "table", "phone", "excuse generator"];

ACTIVITIES = ["driving", "sleeping", "on my way home", "doing groceries", "finishing my tasks", "working overtime", "being busy", "working hard", "going to the airport", "on the train", "swimming", "taking a shower", "feeding my cat", "feeding my dog", "on the phone", "binge drinking", "smoking weed", "faking statistics", "watering the plants", "playing video games", "planning", "drinking coffee", "doing drugs", "coming up with an excuse"];

THINGS_TO_LOSE = ["glasses", "wallet", "sanity", "beer", "shit", "password", "money", "Facebook password", "Trello account", "keys", "inheritance", "claim to the throne", "trust", "shirt", "clothes", "underwear", "cocaine", "argument", "dignity", "excuse", "homework"];

THINGS_TO_CRASH = ["computer", "car", "bicycle", "motorcycle", "Unity", "Photoshop", "Playstation", "stock market portfolio"];

EMOTIONS = ["angry", "sad", "depressed", "happy", "hungry", "sick", "impatient", "annoyed", "excited"];

DESTROYED = ["lost", "crushed", "dropped", "burned", "broke", "forgot", "ate"];

TIMES = ["yesterday", "today", "now", "the other day", "last year", "just now", "recently", "this morning"];

function generateExcuse()
{
	return generateIntro() + " " + generateReason() + ".";
}

function generateIntro()
{
	return draw(INTROS);
}

function generateReason()
{
	return draw([
		iHadToTakeXtoY,
		myXBrokeDownWhileY,
		iLostSomething,
		myXWasStolen,
		myXAteMyY,
		someonesEmotion,
		iWasBusy
	])();
}

function iWasBusy() {
	return "I was busy " + activity();
}

function iHadToTakeXtoY() {
	return "I had to take " + someonePassive() + " to the " + draw(PLACES_FOR_PEOPLE) + when();
}

function myXBrokeDownWhileY() {
	return "my " + draw(THINGS_THAT_BREAK) + " broke down" + when();
}

function iLostSomething() {
	return someoneActive() + " lost " + someones() + draw(THINGS_TO_LOSE) + when();
}

function destroyedSomething() {
	return someoneActive() + " " + draw(DESTROYED) + someones() + draw(THINGS_THAT_BREAK) + when();
}

function myXWasStolen() {
	return someoneElse() + " stole " + someones() + draw(THINGS_TO_LOSE.concat(THINGS_THAT_BREAK).concat(PEOPLE)) + when();
}

function myXAteMyY() {
	return someoneActive() + " ate " + someones() + draw(THINGS_TO_LOSE.concat(THINGS_THAT_BREAK).concat(PEOPLE)) + when();
}

function someonesEmotion() {
	return someoneActive() + " got " + draw(EMOTIONS) + " because " + someoneWas() + activity() + when();
}

function someones() {
	return draw(["my ","your ", "someone's ", "my " + draw(PEOPLE) + "'s "]);
}

function someoneActive() {
	return draw(["I", "my " + draw(PEOPLE)]);
}

function someonePassive() {
	return someones() + draw(PEOPLE);
}

function someoneWas() {
	return draw(["I was ", someones() + draw(PEOPLE) + " was "]);
}

function someoneElse() {
	return "my " + draw(PEOPLE);
}

function activity() {
	return draw([
		function() { return draw(ACTIVITIES) },
		function() { return draw(ACTIVITIES) + " with " + someoneElse() }
	])();
}

function when() {
	return draw([
		function() { return "" },
		function() { return " " + draw(TIMES)},
		function() { return " while I was " + draw(ACTIVITIES)},
		function() { return " at the " + draw(PLACES_FOR_PEOPLE)},
		function() { return " while I was taking my " + draw(PEOPLE) + " to the " + draw(PLACES_FOR_PEOPLE)},
		function() { return ", so I spent too much time " + draw(ACTIVITIES)},
		function() { return " because " + generateReason() },
		function() { return " when " + generateReason() }
	])();
}
<commit_msg>Add arrested excuses<commit_after>INTROS = [
	"Sorry I'm late,",
    "Sorry for the delay,",
	"I know I'm late, but",
	"I apologize for being late,",
	"Sorry about the time,",
	"Sorry about this, but",
	"So sorry about this, but"
];

PEOPLE = ["wife", "husband", "brother", "kid", "kids", "grandma", "grandpa", "mother", "father", "friend", "girlfriend", "boyfriend", "imaginary friend", "dog", "cat", "hamster", "doctor", "chicken"];

PLACES_FOR_PEOPLE = ["doctor", "airport", "supermarket", "pharmacy", "hospital", "cemetary", "zoo", "school", "university", "furniture store", "asylum", "divorce lawyer", "police", "restaurant"];

THINGS_THAT_BREAK = ["car", "computer", "laptop", "monitor", "mouse", "keyboard", "oven", "fridge", "VR headset", "body", "brain", "shoes", "Unity", "Photoshop", "Excel", "bicycle", "motorcycle", "bicycle helmet", "motorcycle helmet", "bed", "chair", "table", "phone", "excuse generator"];

ACTIVITIES = ["driving", "sleeping", "on my way home", "doing groceries", "finishing my tasks", "working overtime", "being busy", "working hard", "going to the airport", "on the train", "swimming", "taking a shower", "feeding my cat", "feeding my dog", "on the phone", "binge drinking", "smoking weed", "faking statistics", "watering the plants", "playing video games", "planning", "drinking coffee", "doing drugs", "coming up with an excuse"];

THINGS_TO_LOSE = ["glasses", "wallet", "sanity", "beer", "shit", "password", "money", "Facebook password", "Trello account", "keys", "inheritance", "claim to the throne", "trust", "shirt", "clothes", "underwear", "cocaine", "argument", "dignity", "excuse", "homework"];

THINGS_TO_CRASH = ["computer", "car", "bicycle", "motorcycle", "Unity", "Photoshop", "Playstation", "stock market portfolio"];

EMOTIONS = ["angry", "sad", "depressed", "happy", "hungry", "sick", "impatient", "annoyed", "excited"];

DESTROYED = ["lost", "crushed", "dropped", "burned", "broke", "forgot", "ate"];

TIMES = ["yesterday", "today", "now", "the other day", "last year", "just now", "recently", "this morning"];

function generateExcuse()
{
	return generateIntro() + " " + generateReason() + ".";
}

function generateIntro()
{
	return draw(INTROS);
}

function generateReason()
{
	return draw([
		iHadToTakeXtoY,
		myXBrokeDownWhileY,
		iLostSomething,
		myXWasStolen,
		myXAteMyY,
		someonesEmotion,
		iWasBusy,
		iGotArrested,
	])();
}

function iGotArrested() {
	return "I " + draw(["got ","almost got "]) + draw([
		function() { return "arrested for " + activity() },
		function() { return "arrested" + when() },
		function() { return "caught " + activity() }
	])();
}

function iWasBusy() {
	return "I was busy " + activity();
}

function iHadToTakeXtoY() {
	return "I had to take " + someonePassive() + " to the " + draw(PLACES_FOR_PEOPLE) + when();
}

function myXBrokeDownWhileY() {
	return "my " + draw(THINGS_THAT_BREAK) + " broke down" + when();
}

function iLostSomething() {
	return someoneActive() + " lost " + someones() + draw(THINGS_TO_LOSE) + when();
}

function destroyedSomething() {
	return someoneActive() + " " + draw(DESTROYED) + someones() + draw(THINGS_THAT_BREAK) + when();
}

function myXWasStolen() {
	return someoneElse() + " stole " + someones() + draw(THINGS_TO_LOSE.concat(THINGS_THAT_BREAK).concat(PEOPLE)) + when();
}

function myXAteMyY() {
	return someoneActive() + " ate " + someones() + draw(THINGS_TO_LOSE.concat(THINGS_THAT_BREAK).concat(PEOPLE)) + when();
}

function someonesEmotion() {
	return someoneActive() + " got " + draw(EMOTIONS) + " because " + someoneWas() + activity() + when();
}

function someones() {
	return draw(["my ","your ", "someone's ", "my " + draw(PEOPLE) + "'s "]);
}

function someoneActive() {
	return draw(["I", "my " + draw(PEOPLE)]);
}

function someonePassive() {
	return someones() + draw(PEOPLE);
}

function someoneWas() {
	return draw(["I was ", someones() + draw(PEOPLE) + " was "]);
}

function someoneElse() {
	return "my " + draw(PEOPLE);
}

function activity() {
	return draw([
		function() { return draw(ACTIVITIES) },
		function() { return draw(ACTIVITIES) + " with " + someoneElse() }
	])();
}

function when() {
	return draw([
		function() { return "" },
		function() { return " " + draw(TIMES)},
		function() { return " while I was " + draw(ACTIVITIES)},
		function() { return " at the " + draw(PLACES_FOR_PEOPLE)},
		function() { return " while I was taking my " + draw(PEOPLE) + " to the " + draw(PLACES_FOR_PEOPLE)},
		function() { return ", so I spent too much time " + draw(ACTIVITIES)},
		function() { return " because " + generateReason() },
		function() { return " when " + generateReason() }
	])();
}
<|endoftext|>


<commit_before>module.exports = {
  test_page: 'tests/index.html?hidepassed',
  disable_watching: true,
  launch_in_ci: [
    'Chrome'
  ],
  launch_in_dev: [
    'Chrome'
  ],
  browser_args: {
    Chrome: {
      mode: 'ci',
      args: [
        '--disable-gpu',
        '--headless',
        '--remote-debugging-port=0',
        '--window-size=1440,900'
      ]
    }
  }
};
<commit_msg>Add no sandbox<commit_after>module.exports = {
  test_page: 'tests/index.html?hidepassed',
  disable_watching: true,
  launch_in_ci: [
    'Chrome'
  ],
  launch_in_dev: [
    'Chrome'
  ],
  browser_args: {
    Chrome: {
      mode: 'ci',
      args: [
        // --no-sandbox is needed when running Chrome inside a container
        process.env.TRAVIS ? '--no-sandbox' : null,

        '--disable-gpu',
        '--headless',
        '--remote-debugging-port=0',
        '--window-size=1440,900'
      ].filter(Boolean)
    }
  }
};
<|endoftext|>


<commit_before>/*jshint node:true*/
module.exports = {
  "framework": "qunit",
  "test_page": "tests/index.html?hidepassed&coverage",
  "disable_watching": true,
  "launch_in_ci": [
    "Chrome"
  ],
  "launch_in_dev": [
    "Chrome"
  ]
};
<commit_msg>Switch to Firefox<commit_after>/*jshint node:true*/
module.exports = {
  "framework": "qunit",
  "test_page": "tests/index.html?hidepassed&coverage",
  "disable_watching": true,
  "launch_in_ci": [
    "Firefox"
  ],
  "launch_in_dev": [
    "Firefox"
  ]
};
<|endoftext|>


<commit_before>exports.path = require('path')
exports.APP_DIR = exports.path.resolve(__dirname, 'javascript')

exports.entry = {
  MediumEditorPack: exports.APP_DIR + '/EntryForm/MediumEditorPack.js',
  EntryList: exports.APP_DIR + '/EntryList/index.jsx',
  AuthorList: exports.APP_DIR + '/AuthorList/index.jsx',
  EntryForm: exports.APP_DIR + '/EntryForm/EntryForm.js',
  PublishBar: exports.APP_DIR + '/PublishBar/index.jsx',
  TagBar: exports.APP_DIR + '/TagBar/index.jsx',
  Settings: exports.APP_DIR + '/Settings/index.jsx',
  Feature: exports.APP_DIR + '/Feature/index.jsx',
  Navbar: exports.APP_DIR + '/Navbar/index.jsx',
  AuthorBar: exports.APP_DIR + '/AuthorBar/index.jsx',
  Tooltip: exports.APP_DIR + '/Tooltip/index.js',
  Caption: exports.APP_DIR + '/Caption/index.js',
  Sortable: exports.APP_DIR + '/Sortable/index.js'
}
<commit_msg>Publish vs PublishBar was confusing. Now just Publish<commit_after>exports.path = require('path')
exports.APP_DIR = exports.path.resolve(__dirname, 'javascript')

exports.entry = {
  MediumEditorPack: exports.APP_DIR + '/EntryForm/MediumEditorPack.js',
  EntryList: exports.APP_DIR + '/EntryList/index.jsx',
  AuthorList: exports.APP_DIR + '/AuthorList/index.jsx',
  EntryForm: exports.APP_DIR + '/EntryForm/EntryForm.js',
  Publish: exports.APP_DIR + '/Publish/index.jsx',
  TagBar: exports.APP_DIR + '/TagBar/index.jsx',
  Settings: exports.APP_DIR + '/Settings/index.jsx',
  Feature: exports.APP_DIR + '/Feature/index.jsx',
  Navbar: exports.APP_DIR + '/Navbar/index.jsx',
  AuthorBar: exports.APP_DIR + '/AuthorBar/index.jsx',
  Tooltip: exports.APP_DIR + '/Tooltip/index.js',
  Caption: exports.APP_DIR + '/Caption/index.js',
  Sortable: exports.APP_DIR + '/Sortable/index.js'
}
<|endoftext|>


<commit_before>/* eslint-env node */

module.exports = {
  test_page: 'tests/index.html?hidepassed',
  disable_watching: true,
  launch_in_ci: [
    'Chrome'
  ],
  launch_in_dev: [ ],
  browser_args: {
    Chrome: [
      '--disable-gpu',
      '--headless',
      '--remote-debugging-port=9222',
      '--window-size=1440,900'
    ]
  }
};
<commit_msg>Fix Chrome tests on Travis<commit_after>/* eslint-env node */

module.exports = {
  test_page: 'tests/index.html?hidepassed',
  disable_watching: true,
  launch_in_ci: [
    'Chrome'
  ],
  launch_in_dev: [ ],
  browser_args: {
    Chrome: [
      // --no-sandbox is needed when running Chrome inside a container
      process.env.TRAVIS ? '--no-sandbox' : null,
      '--disable-gpu',
      '--headless',
      '--remote-debugging-port=9222',
      '--window-size=1440,900'
    ]
  }
};
<|endoftext|>


<commit_before>/*jshint node:true*/
module.exports = {
  "framework": "qunit",
  "test_page": "tests/index.html?hidepassed&coverage",
  "disable_watching": true,
  "launch_in_ci": [
    "Firefox"
  ],
  "launch_in_dev": [
    "Firefox"
  ]
};
<commit_msg>Chrome again<commit_after>/*jshint node:true*/
module.exports = {
  "framework": "qunit",
  "test_page": "tests/index.html?hidepassed&coverage",
  "disable_watching": true,
  "launch_in_ci": [
    "Chrome"
  ],
  "launch_in_dev": [
    "Chrome"
  ]
};
<|endoftext|>