<commit_before>/*
 * Geddy JavaScript Web development framework
 * Copyright 2112 Matthew Eernisse (mde@fleegix.org)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
*/
var Flash = require('./flash').Flash
  , utils = require('utilities');

var session = new (function () {
  var KEY_LENGTH = 32;

  this.store = null;

  this.createStore = function (type, callback) {
    var key
      , constructor;

    if (type === 'mongo') {
      type = 'mongodb';
    }
    if (type === 'couch') {
      type = 'couchdb';
    }

    key = geddy.string.capitalize(type);
    constructor = require('./stores/' + type)[key];

    session.store = new constructor(callback);
  };

})();

session.Session = function (controller, callback) {
  var self = this
    , cookies = controller.cookies
    , keyName = geddy.config.sessions.key
    , sid = cookies.get(keyName);

  this.id = null;
  this.controller = controller;
  this.data = null;
  this.expires = this.controller.accessTime +
      (geddy.config.sessions.expiry * 1000);
  this.flash = null;

  this.setId(sid);

  setTimeout(function () {
    self.init(callback);
  }, 0);
};

session.Session.prototype = new function () {
  this.setId = function (s) {
    var sid = s || geddy.string.uuid(128)
      , cookies = this.controller.cookies
      , keyName = geddy.config.sessions.key
      , opts = {
          expires: (new Date(this.expires)).toGMTString()
        };

    cookies.set(keyName, sid, opts);
    this.id = sid;
  };

  this.init = function (appCallback) {
    var self = this;
    var localCallback = function (result) {
      self.data = result;
      if (self.isExpired()) {
        self.reset(appCallback);
      }
      else {
        self.flash = new Flash(self, geddy.config.flashes);
        appCallback();
      }
    };
    session.store.read(this, localCallback);
  };

  this.isExpired = function () {
    var expired = false
      , lastAccess = this.get('accessTime');
    if (lastAccess) {
      lastAccess = parseInt(lastAccess, 10);
      if (this.controller.accessTime >
        (lastAccess + this.expiry)) {
          expired = true;
        }
    }
    return expired;
  };

  this.reset = function (callback) {
    this.setId();
    this.data = {};
    this.flash = null;
    if (typeof callback == 'function') {
      callback();
    }
  };

  this.get = function (key) {
    return this.data[key];
  };

  this.set = function (key, val) {
    this.data[key] = val;
  };

  this.unset = function (key) {
    delete this.data[key];
  };

  this.close = function (appCallback) {
    this.flash.close();
    session.store.write(this, appCallback);
  };

  this.toJSON = function () {
    return utils.mixin({}, this.data);
  };

}();

module.exports = session;
<commit_msg>Stop calling capitalize from the geddy global<commit_after>/*
 * Geddy JavaScript Web development framework
 * Copyright 2112 Matthew Eernisse (mde@fleegix.org)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
*/
var Flash = require('./flash').Flash
  , utils = require('utilities');

var session = new (function () {
  var KEY_LENGTH = 32;

  this.store = null;

  this.createStore = function (type, callback) {
    var key
      , constructor;

    if (type === 'mongo') {
      type = 'mongodb';
    }
    if (type === 'couch') {
      type = 'couchdb';
    }

    key = utils.string.capitalize(type);
    constructor = require('./stores/' + type)[key];

    session.store = new constructor(callback);
  };

})();

session.Session = function (controller, callback) {
  var self = this
    , cookies = controller.cookies
    , keyName = geddy.config.sessions.key
    , sid = cookies.get(keyName);

  this.id = null;
  this.controller = controller;
  this.data = null;
  this.expires = this.controller.accessTime +
      (geddy.config.sessions.expiry * 1000);
  this.flash = null;

  this.setId(sid);

  setTimeout(function () {
    self.init(callback);
  }, 0);
};

session.Session.prototype = new function () {
  this.setId = function (s) {
    var sid = s || geddy.string.uuid(128)
      , cookies = this.controller.cookies
      , keyName = geddy.config.sessions.key
      , opts = {
          expires: (new Date(this.expires)).toGMTString()
        };

    cookies.set(keyName, sid, opts);
    this.id = sid;
  };

  this.init = function (appCallback) {
    var self = this;
    var localCallback = function (result) {
      self.data = result;
      if (self.isExpired()) {
        self.reset(appCallback);
      }
      else {
        self.flash = new Flash(self, geddy.config.flashes);
        appCallback();
      }
    };
    session.store.read(this, localCallback);
  };

  this.isExpired = function () {
    var expired = false
      , lastAccess = this.get('accessTime');
    if (lastAccess) {
      lastAccess = parseInt(lastAccess, 10);
      if (this.controller.accessTime >
        (lastAccess + this.expiry)) {
          expired = true;
        }
    }
    return expired;
  };

  this.reset = function (callback) {
    this.setId();
    this.data = {};
    this.flash = null;
    if (typeof callback == 'function') {
      callback();
    }
  };

  this.get = function (key) {
    return this.data[key];
  };

  this.set = function (key, val) {
    this.data[key] = val;
  };

  this.unset = function (key) {
    delete this.data[key];
  };

  this.close = function (appCallback) {
    this.flash.close();
    session.store.write(this, appCallback);
  };

  this.toJSON = function () {
    return utils.mixin({}, this.data);
  };

}();

module.exports = session;
<|endoftext|>


<commit_before>const instance = require('../helpers/weak_cache');

module.exports = async function sessionHandler(ctx, next) {
  ctx.oidc.session = new Proxy(await ctx.oidc.provider.Session.get(ctx), {
    set(obj, prop, value) {
      if (prop === 'touched') {
        Reflect.defineProperty(obj, 'touched', { writable: true, value });
      } else if (prop === 'destroyed') {
        Reflect.defineProperty(obj, 'destroyed', { configurable: false, writable: true, value });
        Reflect.defineProperty(obj, 'touched', { configurable: false, writable: false, value: false });
      } else {
        Reflect.set(obj, prop, value);
        Reflect.defineProperty(obj, 'touched', { writable: true, value: true });
      }
      return true;
    },
  });

  try {
    await next();
  } finally {
    const sessionCookieName = ctx.oidc.provider.cookieName('session');
    const stateCookieName = ctx.oidc.provider.cookieName('state');
    const longRegexp = new RegExp(`^(${sessionCookieName}|${stateCookieName}\\.[^=]+)(?:\\.sig)?=`);

    // refresh the session duration
    if ((!ctx.oidc.session.new || ctx.oidc.session.touched) && !ctx.oidc.session.destroyed) {
      ctx.cookies.set(sessionCookieName, ctx.oidc.session.id, instance(ctx.oidc.provider).configuration('cookies.long'));
      await ctx.oidc.session.save();
    }

    // TODO: revert this back to its original state once
    // https://github.com/pillarjs/cookies/issues/109 lands
    if (ctx.response.get('set-cookie')) {
      ctx.response.get('set-cookie').forEach((cookie, index, ary) => {
        if (!cookie.includes('samesite=')) {
          ary[index] = cookie = `${cookie}; samesite=none`; // eslint-disable-line no-param-reassign, no-multi-assign
        }

        if (ctx.oidc.session.transient && cookie.includes('expires=') && !cookie.includes('expires=Thu, 01 Jan 1970') && cookie.match(longRegexp)) {
          ary[index] = cookie.replace(/(; ?expires=([\w\d:, ]+))/, ''); // eslint-disable-line no-param-reassign
        }
      });
    }
  }
};
<commit_msg>fix: avoid sending "samesite=none" to webkit browsers due to their bug<commit_after>const instance = require('../helpers/weak_cache');

module.exports = async function sessionHandler(ctx, next) {
  ctx.oidc.session = new Proxy(await ctx.oidc.provider.Session.get(ctx), {
    set(obj, prop, value) {
      if (prop === 'touched') {
        Reflect.defineProperty(obj, 'touched', { writable: true, value });
      } else if (prop === 'destroyed') {
        Reflect.defineProperty(obj, 'destroyed', { configurable: false, writable: true, value });
        Reflect.defineProperty(obj, 'touched', { configurable: false, writable: false, value: false });
      } else {
        Reflect.set(obj, prop, value);
        Reflect.defineProperty(obj, 'touched', { writable: true, value: true });
      }
      return true;
    },
  });

  try {
    await next();
  } finally {
    const sessionCookieName = ctx.oidc.provider.cookieName('session');
    const stateCookieName = ctx.oidc.provider.cookieName('state');
    const longRegexp = new RegExp(`^(${sessionCookieName}|${stateCookieName}\\.[^=]+)(?:\\.sig)?=`);

    // refresh the session duration
    if ((!ctx.oidc.session.new || ctx.oidc.session.touched) && !ctx.oidc.session.destroyed) {
      ctx.cookies.set(sessionCookieName, ctx.oidc.session.id, instance(ctx.oidc.provider).configuration('cookies.long'));
      await ctx.oidc.session.save();
    }

    const isWebKit = /webkit/i.test(ctx.get('user-agent'));

    if (ctx.response.get('set-cookie')) {
      ctx.response.get('set-cookie').forEach((cookie, index, ary) => {
        /* eslint-disable no-param-reassign, no-multi-assign */
        // TODO: remove when https://github.com/pillarjs/cookies/issues/109 lands
        if (!cookie.includes('samesite=')) {
          ary[index] = cookie = `${cookie}; samesite=none`;
        }

        // WebKit treats unrecognized (yet) "None" value as "Strict" instead
        // https://bugs.webkit.org/show_bug.cgi?id=198181
        // TODO: remove when no longer needed
        if (isWebKit && cookie.includes('; samesite=none')) {
          ary[index] = cookie = cookie.replace('; samesite=none', '');
        }

        if (ctx.oidc.session.transient && cookie.includes('expires=') && !cookie.includes('expires=Thu, 01 Jan 1970') && cookie.match(longRegexp)) {
          ary[index] = cookie.replace(/(; ?expires=([\w\d:, ]+))/, '');
        }
        /* eslint-enable */
      });
    }
  }
};
<|endoftext|>


<commit_before>/**
 * @depend util/core.js
 */
/*jslint eqeqeq: false, onevar: false*/
/*global module, require, sinon, process, setImmediate, setTimeout*/
/**
 * Stub behavior
 *
 * @author Christian Johansen (christian@cjohansen.no)
 * @author Tim Fischbach (mail@timfischbach.de)
 * @license BSD
 *
 * Copyright (c) 2010-2013 Christian Johansen
 */
"use strict";

(function (sinon) {
    var slice = Array.prototype.slice;
    var join = Array.prototype.join;

    var nextTick = (function () {
        if (typeof process === "object" && typeof process.nextTick === "function") {
            return process.nextTick;
        } else if (typeof setImmediate === "function") {
            return setImmediate;
        } else {
            return function (callback) {
                setTimeout(callback, 0);
            };
        }
    })();

    function throwsException(error, message) {
        if (typeof error == "string") {
            this.exception = new Error(message || "");
            this.exception.name = error;
        } else if (!error) {
            this.exception = new Error("Error");
        } else {
            this.exception = error;
        }

        return this;
    }

    function getCallback(behavior, args) {
        var callArgAt = behavior.callArgAt;

        if (callArgAt < 0) {
            var callArgProp = behavior.callArgProp;

            for (var i = 0, l = args.length; i < l; ++i) {
                if (!callArgProp && typeof args[i] == "function") {
                    return args[i];
                }

                if (callArgProp && args[i] &&
                    typeof args[i][callArgProp] == "function") {
                    return args[i][callArgProp];
                }
            }

            return null;
        }

        return args[callArgAt];
    }

    function makeApi(sinon) {
        function getCallbackError(behavior, func, args) {
            if (behavior.callArgAt < 0) {
                var msg;

                if (behavior.callArgProp) {
                    msg = sinon.functionName(behavior.stub) +
                        " expected to yield to '" + behavior.callArgProp +
                        "', but no object with such a property was passed.";
                } else {
                    msg = sinon.functionName(behavior.stub) +
                        " expected to yield, but no callback was passed.";
                }

                if (args.length > 0) {
                    msg += " Received [" + join.call(args, ", ") + "]";
                }

                return msg;
            }

            return "argument at index " + behavior.callArgAt + " is not a function: " + func;
        }

        function callCallback(behavior, args) {
            if (typeof behavior.callArgAt == "number") {
                var func = getCallback(behavior, args);

                if (typeof func != "function") {
                    throw new TypeError(getCallbackError(behavior, func, args));
                }

                if (behavior.callbackAsync) {
                    nextTick(function() {
                        func.apply(behavior.callbackContext, behavior.callbackArguments);
                    });
                } else {
                    func.apply(behavior.callbackContext, behavior.callbackArguments);
                }
            }
        }

        var proto = {
            create: function(stub) {
                var behavior = sinon.extend({}, sinon.behavior);
                delete behavior.create;
                behavior.stub = stub;

                return behavior;
            },

            isPresent: function() {
                return (typeof this.callArgAt == 'number' ||
                        this.exception ||
                        typeof this.returnArgAt == 'number' ||
                        this.returnThis ||
                        this.returnValueDefined);
            },

            invoke: function(context, args) {
                callCallback(this, args);

                if (this.exception) {
                    throw this.exception;
                } else if (typeof this.returnArgAt == 'number') {
                    return args[this.returnArgAt];
                } else if (this.returnThis) {
                    return context;
                }

                return this.returnValue;
            },

            onCall: function(index) {
                return this.stub.onCall(index);
            },

            onFirstCall: function() {
                return this.stub.onFirstCall();
            },

            onSecondCall: function() {
                return this.stub.onSecondCall();
            },

            onThirdCall: function() {
                return this.stub.onThirdCall();
            },

            withArgs: function(/* arguments */) {
                throw new Error('Defining a stub by invoking "stub.onCall(...).withArgs(...)" is not supported. ' +
                                'Use "stub.withArgs(...).onCall(...)" to define sequential behavior for calls with certain arguments.');
            },

            callsArg: function callsArg(pos) {
                if (typeof pos != "number") {
                    throw new TypeError("argument index is not number");
                }

                this.callArgAt = pos;
                this.callbackArguments = [];
                this.callbackContext = undefined;
                this.callArgProp = undefined;
                this.callbackAsync = false;

                return this;
            },

            callsArgOn: function callsArgOn(pos, context) {
                if (typeof pos != "number") {
                    throw new TypeError("argument index is not number");
                }
                if (typeof context != "object") {
                    throw new TypeError("argument context is not an object");
                }

                this.callArgAt = pos;
                this.callbackArguments = [];
                this.callbackContext = context;
                this.callArgProp = undefined;
                this.callbackAsync = false;

                return this;
            },

            callsArgWith: function callsArgWith(pos) {
                if (typeof pos != "number") {
                    throw new TypeError("argument index is not number");
                }

                this.callArgAt = pos;
                this.callbackArguments = slice.call(arguments, 1);
                this.callbackContext = undefined;
                this.callArgProp = undefined;
                this.callbackAsync = false;

                return this;
            },

            callsArgOnWith: function callsArgWith(pos, context) {
                if (typeof pos != "number") {
                    throw new TypeError("argument index is not number");
                }
                if (typeof context != "object") {
                    throw new TypeError("argument context is not an object");
                }

                this.callArgAt = pos;
                this.callbackArguments = slice.call(arguments, 2);
                this.callbackContext = context;
                this.callArgProp = undefined;
                this.callbackAsync = false;

                return this;
            },

            yields: function () {
                this.callArgAt = -1;
                this.callbackArguments = slice.call(arguments, 0);
                this.callbackContext = undefined;
                this.callArgProp = undefined;
                this.callbackAsync = false;

                return this;
            },

            yieldsOn: function (context) {
                if (typeof context != "object") {
                    throw new TypeError("argument context is not an object");
                }

                this.callArgAt = -1;
                this.callbackArguments = slice.call(arguments, 1);
                this.callbackContext = context;
                this.callArgProp = undefined;
                this.callbackAsync = false;

                return this;
            },

            yieldsTo: function (prop) {
                this.callArgAt = -1;
                this.callbackArguments = slice.call(arguments, 1);
                this.callbackContext = undefined;
                this.callArgProp = prop;
                this.callbackAsync = false;

                return this;
            },

            yieldsToOn: function (prop, context) {
                if (typeof context != "object") {
                    throw new TypeError("argument context is not an object");
                }

                this.callArgAt = -1;
                this.callbackArguments = slice.call(arguments, 2);
                this.callbackContext = context;
                this.callArgProp = prop;
                this.callbackAsync = false;

                return this;
            },

            "throws": throwsException,
            throwsException: throwsException,

            returns: function returns(value) {
                this.returnValue = value;
                this.returnValueDefined = true;

                return this;
            },

            returnsArg: function returnsArg(pos) {
                if (typeof pos != "number") {
                    throw new TypeError("argument index is not number");
                }

                this.returnArgAt = pos;

                return this;
            },

            returnsThis: function returnsThis() {
                this.returnThis = true;

                return this;
            }
        };

        // create asynchronous versions of callsArg* and yields* methods
        for (var method in proto) {
            // need to avoid creating anotherasync versions of the newly added async methods
            if (proto.hasOwnProperty(method) &&
                method.match(/^(callsArg|yields)/) &&
                !method.match(/Async/)) {
                proto[method + 'Async'] = (function (syncFnName) {
                    return function () {
                        var result = this[syncFnName].apply(this, arguments);
                        this.callbackAsync = true;
                        return result;
                    };
                })(method);
            }
        }

        sinon.behavior = proto;
        return proto;
    }

    var isNode = typeof module !== "undefined" && module.exports && typeof require == "function";
    var isAMD = typeof define === 'function' && typeof define.amd === 'object' && define.amd;

    function loadDependencies(require, exports, module) {
        var sinon = require('./util/core');
        module.exports = makeApi(sinon);
    }

    if (isAMD) {
        define(loadDependencies);
    } else if (isNode) {
        loadDependencies(require, module.exports, module);
    } else if (!sinon) {
        return;
    } else {
        makeApi(sinon);
    }
}(typeof sinon == "object" && sinon || null));
<commit_msg>Lint lib/sinon/behavior.js<commit_after>/**
 * @depend util/core.js
 */
/**
 * Stub behavior
 *
 * @author Christian Johansen (christian@cjohansen.no)
 * @author Tim Fischbach (mail@timfischbach.de)
 * @license BSD
 *
 * Copyright (c) 2010-2013 Christian Johansen
 */
"use strict";

(function (sinon) {
    var slice = Array.prototype.slice;
    var join = Array.prototype.join;

    var nextTick = (function () {
        if (typeof process === "object" && typeof process.nextTick === "function") {
            return process.nextTick;
        } else if (typeof setImmediate === "function") {
            return setImmediate;
        } else {
            return function (callback) {
                setTimeout(callback, 0);
            };
        }
    })();

    function throwsException(error, message) {
        if (typeof error == "string") {
            this.exception = new Error(message || "");
            this.exception.name = error;
        } else if (!error) {
            this.exception = new Error("Error");
        } else {
            this.exception = error;
        }

        return this;
    }

    function getCallback(behavior, args) {
        var callArgAt = behavior.callArgAt;

        if (callArgAt < 0) {
            var callArgProp = behavior.callArgProp;

            for (var i = 0, l = args.length; i < l; ++i) {
                if (!callArgProp && typeof args[i] == "function") {
                    return args[i];
                }

                if (callArgProp && args[i] &&
                    typeof args[i][callArgProp] == "function") {
                    return args[i][callArgProp];
                }
            }

            return null;
        }

        return args[callArgAt];
    }

    function makeApi(sinon) {
        function getCallbackError(behavior, func, args) {
            if (behavior.callArgAt < 0) {
                var msg;

                if (behavior.callArgProp) {
                    msg = sinon.functionName(behavior.stub) +
                        " expected to yield to '" + behavior.callArgProp +
                        "', but no object with such a property was passed.";
                } else {
                    msg = sinon.functionName(behavior.stub) +
                        " expected to yield, but no callback was passed.";
                }

                if (args.length > 0) {
                    msg += " Received [" + join.call(args, ", ") + "]";
                }

                return msg;
            }

            return "argument at index " + behavior.callArgAt + " is not a function: " + func;
        }

        function callCallback(behavior, args) {
            if (typeof behavior.callArgAt == "number") {
                var func = getCallback(behavior, args);

                if (typeof func != "function") {
                    throw new TypeError(getCallbackError(behavior, func, args));
                }

                if (behavior.callbackAsync) {
                    nextTick(function () {
                        func.apply(behavior.callbackContext, behavior.callbackArguments);
                    });
                } else {
                    func.apply(behavior.callbackContext, behavior.callbackArguments);
                }
            }
        }

        var proto = {
            create: function create(stub) {
                var behavior = sinon.extend({}, sinon.behavior);
                delete behavior.create;
                behavior.stub = stub;

                return behavior;
            },

            isPresent: function isPresent() {
                return (typeof this.callArgAt == "number" ||
                        this.exception ||
                        typeof this.returnArgAt == "number" ||
                        this.returnThis ||
                        this.returnValueDefined);
            },

            invoke: function invoke(context, args) {
                callCallback(this, args);

                if (this.exception) {
                    throw this.exception;
                } else if (typeof this.returnArgAt == "number") {
                    return args[this.returnArgAt];
                } else if (this.returnThis) {
                    return context;
                }

                return this.returnValue;
            },

            onCall: function onCall(index) {
                return this.stub.onCall(index);
            },

            onFirstCall: function onFirstCall() {
                return this.stub.onFirstCall();
            },

            onSecondCall: function onSecondCall() {
                return this.stub.onSecondCall();
            },

            onThirdCall: function onThirdCall() {
                return this.stub.onThirdCall();
            },

            withArgs: function withArgs(/* arguments */) {
                throw new Error("Defining a stub by invoking \"stub.onCall(...).withArgs(...)\" is not supported. " +
                                "Use \"stub.withArgs(...).onCall(...)\" to define sequential behavior for calls with certain arguments.");
            },

            callsArg: function callsArg(pos) {
                if (typeof pos != "number") {
                    throw new TypeError("argument index is not number");
                }

                this.callArgAt = pos;
                this.callbackArguments = [];
                this.callbackContext = undefined;
                this.callArgProp = undefined;
                this.callbackAsync = false;

                return this;
            },

            callsArgOn: function callsArgOn(pos, context) {
                if (typeof pos != "number") {
                    throw new TypeError("argument index is not number");
                }
                if (typeof context != "object") {
                    throw new TypeError("argument context is not an object");
                }

                this.callArgAt = pos;
                this.callbackArguments = [];
                this.callbackContext = context;
                this.callArgProp = undefined;
                this.callbackAsync = false;

                return this;
            },

            callsArgWith: function callsArgWith(pos) {
                if (typeof pos != "number") {
                    throw new TypeError("argument index is not number");
                }

                this.callArgAt = pos;
                this.callbackArguments = slice.call(arguments, 1);
                this.callbackContext = undefined;
                this.callArgProp = undefined;
                this.callbackAsync = false;

                return this;
            },

            callsArgOnWith: function callsArgWith(pos, context) {
                if (typeof pos != "number") {
                    throw new TypeError("argument index is not number");
                }
                if (typeof context != "object") {
                    throw new TypeError("argument context is not an object");
                }

                this.callArgAt = pos;
                this.callbackArguments = slice.call(arguments, 2);
                this.callbackContext = context;
                this.callArgProp = undefined;
                this.callbackAsync = false;

                return this;
            },

            yields: function () {
                this.callArgAt = -1;
                this.callbackArguments = slice.call(arguments, 0);
                this.callbackContext = undefined;
                this.callArgProp = undefined;
                this.callbackAsync = false;

                return this;
            },

            yieldsOn: function (context) {
                if (typeof context != "object") {
                    throw new TypeError("argument context is not an object");
                }

                this.callArgAt = -1;
                this.callbackArguments = slice.call(arguments, 1);
                this.callbackContext = context;
                this.callArgProp = undefined;
                this.callbackAsync = false;

                return this;
            },

            yieldsTo: function (prop) {
                this.callArgAt = -1;
                this.callbackArguments = slice.call(arguments, 1);
                this.callbackContext = undefined;
                this.callArgProp = prop;
                this.callbackAsync = false;

                return this;
            },

            yieldsToOn: function (prop, context) {
                if (typeof context != "object") {
                    throw new TypeError("argument context is not an object");
                }

                this.callArgAt = -1;
                this.callbackArguments = slice.call(arguments, 2);
                this.callbackContext = context;
                this.callArgProp = prop;
                this.callbackAsync = false;

                return this;
            },

            throws: throwsException,
            throwsException: throwsException,

            returns: function returns(value) {
                this.returnValue = value;
                this.returnValueDefined = true;

                return this;
            },

            returnsArg: function returnsArg(pos) {
                if (typeof pos != "number") {
                    throw new TypeError("argument index is not number");
                }

                this.returnArgAt = pos;

                return this;
            },

            returnsThis: function returnsThis() {
                this.returnThis = true;

                return this;
            }
        };

        // create asynchronous versions of callsArg* and yields* methods
        for (var method in proto) {
            // need to avoid creating anotherasync versions of the newly added async methods
            if (proto.hasOwnProperty(method) &&
                method.match(/^(callsArg|yields)/) &&
                !method.match(/Async/)) {
                proto[method + "Async"] = (function (syncFnName) {
                    return function () {
                        var result = this[syncFnName].apply(this, arguments);
                        this.callbackAsync = true;
                        return result;
                    };
                })(method);
            }
        }

        sinon.behavior = proto;
        return proto;
    }

    var isNode = typeof module !== "undefined" && module.exports && typeof require == "function";
    var isAMD = typeof define === "function" && typeof define.amd === "object" && define.amd;

    function loadDependencies(require, exports, module) {
        var sinon = require("./util/core");
        module.exports = makeApi(sinon);
    }

    if (isAMD) {
        define(loadDependencies);
    } else if (isNode) {
        loadDependencies(require, module.exports, module);
    } else if (!sinon) {
        return;
    } else {
        makeApi(sinon);
    }
}(typeof sinon == "object" && sinon || null));
<|endoftext|>


<commit_before>// oleksiy krivoshey

var net = require('net');
var sirvlogProtocol = require('./sirvlog_protocol');
var syslogProtocol = require('./syslog_protocol');
//var util = require("util");
var async = require("async");
var _ = require('underscore');

var elastical = require('elastical');

exports.SirvlogServer = SirvlogServer = function (opts) {

    this.options = opts;
    this.servers = {};

    this.indexName = null;
    this.messagesCache = [];

    this.elasticClient = new elastical.Client(this.options.elasticsearch.hostname, this.options.elasticsearch.options);

    this.rotateIndex();

    // check if we need to create new index
    setInterval(this.rotateIndex.bind(this), 60*1000);

    // send bulk operation once per second
    setInterval(this.bulkIndex.bind(this), 1000);

    var shutdownFunc = function () {
        console.log("Gracefully shutting down service")
        process.removeListener('SIGINT', shutdownFunc);
        process.removeListener('SIGTERM', shutdownFunc);

        async.parallel(
            _.map(this.servers, function(server, name){
                return function(cb){
                    server.close(cb.bind(cb, null, name));
                }
            })
        , function(err, names){
            console.log('all connections closed (' + names + '), exiting');
            process.exit()
        });

    }.bind(this);

    process.setMaxListeners(0);

    process.on('SIGINT', shutdownFunc);
    process.on('SIGTERM', shutdownFunc);

    this.startTCPServer('sirvlog', sirvlogProtocol, this.options.network.port.sirvlog);

    this.startTCPServer('syslog', syslogProtocol, this.options.network.port.syslog);
}

// starts sirvlog protocol server
SirvlogServer.prototype.startTCPServer = function (name, protocol, port) {

    var logPrefix = '['+name+'] ';

    this.servers[name] = net.createServer(function (sc) { //'connection' listener

        var shutdownFunc = function (socket) {
            socket.end();
            setTimeout(function (socket) {
                if(socket.destroyed) {
                    return;
                }
                console.error(logPrefix + 'Failed to close connection with ' + socket.remoteAddress + ':' + socket.remotePort + ' in 3 secs, doing force-close');
                socket.destroy();
            }.bind(this, socket), 3000);
        }.bind(this, sc);

        process.on('SIGINT', shutdownFunc);
        process.on('SIGTERM', shutdownFunc);

        var connectionErrors = 0;

        console.log(logPrefix + 'Incoming connection from ' + sc.remoteAddress);

        sc.on('end', function () {
            console.log(logPrefix + 'Connection closed');
            process.removeListener('SIGINT', shutdownFunc);
            process.removeListener('SIGTERM', shutdownFunc);
        }.bind(this));

        var filterCtx = {
            remoteAddress: sc.remoteAddress,
            remotePort: sc.remotePort
        }

        protocol.createProtocol(sc).
            on('receive', function (message) { // log message received

                this.processMessage(message, filterCtx);

            }.bind(this)).
            on('error', function (e) { // parse or processing error from protocol
                console.error(e);
                if (connectionErrors++ >= 5) {
                    console.warn(logPrefix + 'Too many errors from ' + sc.remoteAddress + ', closing connection');
                    sc.destroy();
                }
            }.bind(this));

    }.bind(this));

    this.servers[name].listen(port, this.options.network.bind, function () { //'listening' listener

        console.log(logPrefix + 'Listening on ', this.servers[name].address());
    }.bind(this));

};

SirvlogServer.prototype.processMessage = function(messageObj, filterCtx){

    if (this.options.messageTTL) { // set ttl (ms)
        messageObj._ttl = this.options.messageTTL;
    }

    // replace 'custom' field with facility-dependant
    messageObj.receivedTs = Date.now();

    var customName = messageObj.facility.replace(/(\W|\s)/g, '-').replace(/-+/g, '-').toLowerCase();

    messageObj[customName] = messageObj.custom;

    delete messageObj.custom;

    // run through filters
    for (var i = 0; i < this.options.filters.length; i++) {
        var stop = this.options.filters[i].apply(messageObj, [filterCtx]);

        if (stop === null) { // message dropped by filter
            //console.log('message dropped by filter');
            return;
        } else if (stop === false) { // stop filter processing
            //console.log('stop processing by filters');
            break;
        }
    }

    this.messagesCache.push({
        create: {
            index: this.indexName,
            type: 'message',
            data: messageObj
        }
    });
};

SirvlogServer.prototype.bulkIndex = function (facility) {

    var count = this.messagesCache.length;

    if(count){
        this.elasticClient.bulk(this.messagesCache, function(err, res){
            if (err) {
                console.error('ElasticSearch.bulk() failed: ' + err);
            } else {
                this.messagesCache.splice(0, count);
            }
        }.bind(this));
    }
};

SirvlogServer.prototype.getIndexName = function () {
    var d = new Date();
    var m = d.getMonth() + 1;

    //facility = facility.replace(/(\W|\s)/g, '-');

    var newIndexName = this.options.elasticsearch.index.prefix + '-' + d.getFullYear() + '-' + (m < 10 ? ('0' + m) : m);

    if (/(weekly|daily)/.test(this.options.elasticsearch.index.rotate)) {
        if (this.options.elasticsearch.index.rotate == 'weekly') {
            d = new Date(d - ((d.getDay() + 6) % 7) * 24 * 60 * 60 * 1000); // get last Monday date
        }
        var day = d.getDate();
        newIndexName += '-' + (day < 10 ? ('0' + day) : day);
    }

    return newIndexName;//.replace(/-+/g, '-').toLowerCase();
}

SirvlogServer.prototype.rotateIndex = function () {

    var newIndexName = this.getIndexName();

    this.elasticClient.indexExists(newIndexName, function(err, exists){
        if (err) {
            console.error('Failed to verify index "'+ newIndexName +'": ' + err);
            cb.call(null, err);
        } else if(!exists){
            this.elasticClient.createIndex(newIndexName, {
                'settings': this.options.elasticsearch.index.settings,
                'mappings': {
                    message : {
                        date_detection: false,
                        _ttl : {
                            enabled : true
                        },
                        properties:{
                            level: {
                                type: 'byte'
                            }
                        }
                    }
                }
            }, function(err, index, res){
                if (err) {
                    console.error('Failed to create index "'+ newIndexName +'": ' + err);
                } else {
                    console.log('Created new index: ' + newIndexName);
                    this.indexName = newIndexName;
                }
            }.bind(this));
        } else { // index already exists
            this.indexName = newIndexName;
        }
    }.bind(this));

}

exports.createServer = function (argv) {
    return new SirvlogServer(argv);
};

<commit_msg>Fix indexRotate method<commit_after>// oleksiy krivoshey

var net = require('net');
var sirvlogProtocol = require('./sirvlog_protocol');
var syslogProtocol = require('./syslog_protocol');
//var util = require("util");
var async = require("async");
var _ = require('underscore');

var elastical = require('elastical');

exports.SirvlogServer = SirvlogServer = function (opts) {

    this.options = opts;
    this.servers = {};

    this.indexName = null;
    this.messagesCache = [];

    this.elasticClient = new elastical.Client(this.options.elasticsearch.hostname, this.options.elasticsearch.options);

    this.rotateIndex();

    // check if we need to create new index
    setInterval(this.rotateIndex.bind(this), 60*1000);

    // send bulk operation once per second
    setInterval(this.bulkIndex.bind(this), 1000);

    var shutdownFunc = function () {
        console.log("Gracefully shutting down service")
        process.removeListener('SIGINT', shutdownFunc);
        process.removeListener('SIGTERM', shutdownFunc);

        async.parallel(
            _.map(this.servers, function(server, name){
                return function(cb){
                    server.close(cb.bind(cb, null, name));
                }
            })
        , function(err, names){
            console.log('all connections closed (' + names + '), exiting');
            process.exit()
        });

    }.bind(this);

    process.setMaxListeners(0);

    process.on('SIGINT', shutdownFunc);
    process.on('SIGTERM', shutdownFunc);

    this.startTCPServer('sirvlog', sirvlogProtocol, this.options.network.port.sirvlog);

    this.startTCPServer('syslog', syslogProtocol, this.options.network.port.syslog);
}

// starts sirvlog protocol server
SirvlogServer.prototype.startTCPServer = function (name, protocol, port) {

    var logPrefix = '['+name+'] ';

    this.servers[name] = net.createServer(function (sc) { //'connection' listener

        var shutdownFunc = function (socket) {
            socket.end();
            setTimeout(function (socket) {
                if(socket.destroyed) {
                    return;
                }
                console.error(logPrefix + 'Failed to close connection with ' + socket.remoteAddress + ':' + socket.remotePort + ' in 3 secs, doing force-close');
                socket.destroy();
            }.bind(this, socket), 3000);
        }.bind(this, sc);

        process.on('SIGINT', shutdownFunc);
        process.on('SIGTERM', shutdownFunc);

        var connectionErrors = 0;

        console.log(logPrefix + 'Incoming connection from ' + sc.remoteAddress);

        sc.on('end', function () {
            console.log(logPrefix + 'Connection closed');
            process.removeListener('SIGINT', shutdownFunc);
            process.removeListener('SIGTERM', shutdownFunc);
        }.bind(this));

        var filterCtx = {
            remoteAddress: sc.remoteAddress,
            remotePort: sc.remotePort
        }

        protocol.createProtocol(sc).
            on('receive', function (message) { // log message received

                this.processMessage(message, filterCtx);

            }.bind(this)).
            on('error', function (e) { // parse or processing error from protocol
                console.error(e);
                if (connectionErrors++ >= 5) {
                    console.warn(logPrefix + 'Too many errors from ' + sc.remoteAddress + ', closing connection');
                    sc.destroy();
                }
            }.bind(this));

    }.bind(this));

    this.servers[name].listen(port, this.options.network.bind, function () { //'listening' listener

        console.log(logPrefix + 'Listening on ', this.servers[name].address());
    }.bind(this));

};

SirvlogServer.prototype.processMessage = function(messageObj, filterCtx){

    if (this.options.messageTTL) { // set ttl (ms)
        messageObj._ttl = this.options.messageTTL;
    }

    // replace 'custom' field with facility-dependant
    messageObj.receivedTs = Date.now();

    var customName = messageObj.facility.replace(/(\W|\s)/g, '-').replace(/-+/g, '-').toLowerCase();

    messageObj[customName] = messageObj.custom;

    delete messageObj.custom;

    // run through filters
    for (var i = 0; i < this.options.filters.length; i++) {
        var stop = this.options.filters[i].apply(messageObj, [filterCtx]);

        if (stop === null) { // message dropped by filter
            //console.log('message dropped by filter');
            return;
        } else if (stop === false) { // stop filter processing
            //console.log('stop processing by filters');
            break;
        }
    }

    this.messagesCache.push({
        create: {
            index: this.indexName,
            type: 'message',
            data: messageObj
        }
    });
};

SirvlogServer.prototype.bulkIndex = function (facility) {

    var count = this.messagesCache.length;

    if(count){
        this.elasticClient.bulk(this.messagesCache, function(err, res){
            if (err) {
                console.error('ElasticSearch.bulk() failed: ' + err);
            } else {
                this.messagesCache.splice(0, count);
            }
        }.bind(this));
    }
};

SirvlogServer.prototype.getIndexName = function () {
    var d = new Date();
    var m = d.getMonth() + 1;

    //facility = facility.replace(/(\W|\s)/g, '-');

    var newIndexName = this.options.elasticsearch.index.prefix + '-' + d.getFullYear() + '-' + (m < 10 ? ('0' + m) : m);

    if (/(weekly|daily)/.test(this.options.elasticsearch.index.rotate)) {
        if (this.options.elasticsearch.index.rotate == 'weekly') {
            d = new Date(d - ((d.getDay() + 6) % 7) * 24 * 60 * 60 * 1000); // get last Monday date
        }
        var day = d.getDate();
        newIndexName += '-' + (day < 10 ? ('0' + day) : day);
    }

    return newIndexName;//.replace(/-+/g, '-').toLowerCase();
}

SirvlogServer.prototype.rotateIndex = function () {

    var newIndexName = this.getIndexName();

    this.elasticClient.indexExists(newIndexName, function(err, exists){
        if (err) {
            console.error('Failed to verify index "'+ newIndexName +'": ' + err);
            return;
        }

        if(!exists){
            this.elasticClient.createIndex(newIndexName, {
                'settings': this.options.elasticsearch.index.settings,
                'mappings': {
                    message : {
                        date_detection: false,
                        _ttl : {
                            enabled : true
                        },
                        properties:{
                            level: {
                                type: 'byte'
                            }
                        }
                    }
                }
            }, function(err, index, res){
                if (err) {
                    console.error('Failed to create index "'+ newIndexName +'": ' + err);
                } else {
                    console.log('Created new index: ' + newIndexName);
                    this.indexName = newIndexName;
                }
            }.bind(this));
        } else { // index already exists
            this.indexName = newIndexName;
        }
    }.bind(this));

}

exports.createServer = function (argv) {
    return new SirvlogServer(argv);
};

<|endoftext|>


<commit_before>'use strict';

var QEmitter = require('qemitter'),
    signalHandler = new QEmitter();

module.exports = signalHandler;

process.on('SIGHUP', notifyAndExit(1));
process.on('SIGINT', notifyAndExit(2));
process.on('SIGTERM', notifyAndExit(15));

function notifyAndExit(signalNo) {
    return function() {
        signalHandler.emitAndWait('exit')
            .then(function() {
                console.log('Done.');
                process.exit(128 + signalNo);
            })
            .done();
    };
}
<commit_msg>Force quite on second Ctrl+C<commit_after>'use strict';

var QEmitter = require('qemitter'),
    signalHandler = new QEmitter();

module.exports = signalHandler;

process.on('SIGHUP', notifyAndExit(1));
process.on('SIGINT', notifyAndExit(2));
process.on('SIGTERM', notifyAndExit(15));

var callCount = 0;

function notifyAndExit(signalNo) {
    var exitCode = 128 + signalNo;

    return function() {
        if (callCount++ > 0) {
            console.log('Force quit.');
            process.exit(exitCode);
        }

        signalHandler.emitAndWait('exit')
            .then(function() {
                console.log('Done.');
                process.exit(exitCode);
            })
            .done();
    };
}
<|endoftext|>


<commit_before>'use strict';

var SpotifyWebApi = require('spotify-web-api-node');
var Player = require('player');

const searchWords = "shape of you artist:Ed Sheeran";
//"sugar artist:Maroon 5";
//"I don't wanna live forever";

var logger;
var spotifyApi;
var player = new Player();

var SpotifyPlayer = function(option, log) {
    this.logger = log;
    this.config = option;

    if (!logger) {
        logger = require('humix-logger').createLogger('spotify-player', { consoleLevel: 'debug', filename: 'spotify-player.log' });
    }

    logger.info('SpotifyPlayer instance created.');
};

SpotifyPlayer.prototype.init = function() {
    var self = this;

    // credentials are optional
    self.spotifyApi = new SpotifyWebApi({
        clientId: self.config.spotify.clientId,
        clientSecret: self.config.spotify.clientSecret,
        //  redirectUri : 'http://www.example.com/callback'
    });

    // Retrieve an access token
    self.spotifyApi.clientCredentialsGrant()
        .then(function(data) {
            logger.info('The access token expires in ' + data.body['expires_in']);
            logger.info('The access token is ' + data.body['access_token']);

            // Save the access token so that it's used in future calls
            self.spotifyApi.setAccessToken(data.body['access_token']);
        }, function(err) {
            logger.info('Something went wrong when retrieving an access token', err.message);
        });

    initPlayer();
}

function initPlayer() {

    // event: on playing
    player.on('playing', function(item) {
        logger.info('im playing... src: ' + JSON.stringify(item));
    });

    // event: on playend
    player.on('playend', function(item) {
        // return a playend item
        logger.info('src: ' + item + ' play done, switching to next one ...');

    });

    // event: on error
    player.on('error', function(err) {
        // when error occurs
        logger.info(err);
    });
}

SpotifyPlayer.prototype.playSong = function(songName, artistName) {

    var self = this;

    var query = songName;
    if (artistName) {
        query += ' artist:' + artistName;
    }

    logger.info('query for track on Spotify: ' + query);

    self.spotifyApi.search(query, ['track'], { limit: 15, offset: 0 })
        .then(function(data) {
            logger.info('====== Track for "' + query + '" ======');

            var playIndex = 0;
            if (player.list) {
                playIndex = player.list.length;
            }

            for (var i in data.body.tracks.items) {
                if (i != 0) {
                    logger.info('--------------------');
                }
                var trackObj = data.body.tracks.items[i];

                logger.info(' Album: ' + trackObj.album.name);
                logger.info(' Artist: ' + trackObj.artists[0].name);
                logger.info(' Track: ' + trackObj.name);
                logger.info(' Preview URL: ' + trackObj.preview_url);

                player.add(trackObj.preview_url);
            }

            if (data.body.tracks.items.length > 0) {
                if (player && player.playing) {
                    player.stop();

                    // Wait for 1 second to play
                    var workaround = setInterval(() => {
                        player.play(playIndex);
                        clearInterval(workaround);
                    }, 1000);
                } else {
                    player.play(playIndex);
                }
            }
        }, function(err) {
            logger.error(err);
        });
};

SpotifyPlayer.prototype.pausePlaying = function() {
    if (player && !player.paused) {
        player.pause();
    }
};

SpotifyPlayer.prototype.resumePlaying = function() {
    if (player && player.paused) {
        player.pause();
    }
};

SpotifyPlayer.prototype.stopPlaying = function() {
    player.stop();
};

// Search artist
/*
spotifyApi.search("Ed Sheeran", ['artist'], { limit : 5, offset : 1 })
  .then(function(data) {
    console.log('Artist for "Ed Shreen": ', data.body);
  }, function(err) {
    console.error(err);
  });*/

// Search Track
/*

*/
// Get Ed Sheeran' albums
/*
spotifyApi.getArtistAlbums('607oAIdIe0j0JCsch5U3nD')
  .then(function(data) {
    console.log('Artist albums', data.body);
  }, function(err) {
    console.error(err);
  });
*/

module.exports = SpotifyPlayer;<commit_msg>Check the player.playing is needed.<commit_after>'use strict';

var SpotifyWebApi = require('spotify-web-api-node');
var Player = require('player');

const searchWords = "shape of you artist:Ed Sheeran";
//"sugar artist:Maroon 5";
//"I don't wanna live forever";

var logger;
var spotifyApi;
var player = new Player();

var SpotifyPlayer = function(option, log) {
    this.logger = log;
    this.config = option;

    if (!logger) {
        logger = require('humix-logger').createLogger('spotify-player', { consoleLevel: 'debug', filename: 'spotify-player.log' });
    }

    logger.info('SpotifyPlayer instance created.');
};

SpotifyPlayer.prototype.init = function() {
    var self = this;

    // credentials are optional
    self.spotifyApi = new SpotifyWebApi({
        clientId: self.config.spotify.clientId,
        clientSecret: self.config.spotify.clientSecret,
        //  redirectUri : 'http://www.example.com/callback'
    });

    // Retrieve an access token
    self.spotifyApi.clientCredentialsGrant()
        .then(function(data) {
            logger.info('The access token expires in ' + data.body['expires_in']);
            logger.info('The access token is ' + data.body['access_token']);

            // Save the access token so that it's used in future calls
            self.spotifyApi.setAccessToken(data.body['access_token']);
        }, function(err) {
            logger.info('Something went wrong when retrieving an access token', err.message);
        });

    initPlayer();
}

function initPlayer() {

    // event: on playing
    player.on('playing', function(item) {
        logger.info('im playing... src: ' + JSON.stringify(item));
    });

    // event: on playend
    player.on('playend', function(item) {
        // return a playend item
        logger.info('src: ' + item + ' play done, switching to next one ...');

    });

    // event: on error
    player.on('error', function(err) {
        // when error occurs
        logger.info(err);
    });
}

SpotifyPlayer.prototype.playSong = function(songName, artistName) {

    var self = this;

    var query = songName;
    if (artistName) {
        query += ' artist:' + artistName;
    }

    logger.info('query for track on Spotify: ' + query);

    self.spotifyApi.search(query, ['track'], { limit: 15, offset: 0 })
        .then(function(data) {
            logger.info('====== Track for "' + query + '" ======');

            var playIndex = 0;
            if (player.list) {
                playIndex = player.list.length;
            }

            for (var i in data.body.tracks.items) {
                if (i != 0) {
                    logger.info('--------------------');
                }
                var trackObj = data.body.tracks.items[i];

                logger.info(' Album: ' + trackObj.album.name);
                logger.info(' Artist: ' + trackObj.artists[0].name);
                logger.info(' Track: ' + trackObj.name);
                logger.info(' Preview URL: ' + trackObj.preview_url);

                player.add(trackObj.preview_url);
            }

            if (data.body.tracks.items.length > 0) {
                if (player && player.playing) {
                    player.stop();

                    // Wait for 1 second to play
                    var workaround = setInterval(() => {
                        player.play(playIndex);
                        clearInterval(workaround);
                    }, 1000);
                } else {
                    player.play(playIndex);
                }
            }
        }, function(err) {
            logger.error(err);
        });
};

SpotifyPlayer.prototype.pausePlaying = function() {
    if (player && player.playing && !player.paused) {
        player.pause();
    }
};

SpotifyPlayer.prototype.resumePlaying = function() {
    if (player && player.playing && player.paused) {
        player.pause();
    }
};

SpotifyPlayer.prototype.stopPlaying = function() {
    player.stop();
};

// Search artist
/*
spotifyApi.search("Ed Sheeran", ['artist'], { limit : 5, offset : 1 })
  .then(function(data) {
    console.log('Artist for "Ed Shreen": ', data.body);
  }, function(err) {
    console.error(err);
  });*/

// Search Track
/*

*/
// Get Ed Sheeran' albums
/*
spotifyApi.getArtistAlbums('607oAIdIe0j0JCsch5U3nD')
  .then(function(data) {
    console.log('Artist albums', data.body);
  }, function(err) {
    console.error(err);
  });
*/

module.exports = SpotifyPlayer;<|endoftext|>


<commit_before>var SpotifyWebApi = require('spotify-web-api-node');
var Player = require('player');

const searchWords = "shape of you artist:Ed Sheeran";
//"sugar artist:Maroon 5";
//"I don't wanna live forever";

var logger;
var spotifyApi;
var player = new Player();

var SpotifyPlayer = function(option, log) {
  this.logger = log;
  this.config = option;

  if (!logger) {
    logger = require('humix-logger').createLogger('spotify-player', { consoleLevel: 'debug', filename: 'spotify-player.log' });
  }

  logger.info('SpotifyPlayer instance created.');
};

SpotifyPlayer.prototype.init = function() {
  var self = this;

  // credentials are optional
  self.spotifyApi = new SpotifyWebApi({
    clientId : self.config.spotify.clientId,
    clientSecret : self.config.spotify.clientSecret,
    //  redirectUri : 'http://www.example.com/callback'
  });

  // Retrieve an access token
  self.spotifyApi.clientCredentialsGrant()
    .then(function(data) {
      logger.info('The access token expires in ' + data.body['expires_in']);
      logger.info('The access token is ' + data.body['access_token']);

      // Save the access token so that it's used in future calls
      self.spotifyApi.setAccessToken(data.body['access_token']);
    }, function(err) {
      logger.info('Something went wrong when retrieving an access token', err.message);
  });

  // event: on playing
  player.on('playing', function(item) {
    logger.info('im playing... src: ' + item);
  });

  // event: on playend
  player.on('playend', function(item) {
    // return a playend item
    logger.info('src: ' + item + ' play done, switching to next one ...');

  });

  // event: on error
  player.on('error', function(err) {
    // when error occurs
    logger.info(err);
  });
}

SpotifyPlayer.prototype.playSong = function(songName, artistName) {

  var self = this;

  var query = songName;
  if (artistName) {
      query += ' artist:' + artistName;
  }

  logger.info('query for track on Spotify: ' + query);

  self.spotifyApi.search(query, ['track'], {limit: 5, offset: 1})
    .then(function(data) {
      logger.info('====== Track for "' + query + '" ======');

      for (var i in data.body.tracks.items) {
        if (i != 0) {
          logger.info('--------------------');
        }
        var trackObj = data.body.tracks.items[i];

        logger.info(' Album: ' + trackObj.album.name);
        logger.info(' Artist: ' + trackObj.artists[0].name);
        logger.info(' Track: ' + trackObj.name);

        player.add(trackObj.preview_url);
      }

      if (data.body.tracks.items.length > 0) {
        if (!player.playing()) {
          player.play();
        }
      }
    }, function(err) {
      logger.error(err);
    });
};

SpotifyPlayer.prototype.pausePlaying = function() {
  var self = this;

  self.player.pause();
};

SpotifyPlayer.prototype.stopPlaying = function() {
  var self = this;

  self.player.stop();
};

// Search artist
/*
spotifyApi.search("Ed Sheeran", ['artist'], { limit : 5, offset : 1 })
  .then(function(data) {
    console.log('Artist for "Ed Shreen": ', data.body);
  }, function(err) {
    console.error(err);
  });*/

// Search Track
/*

*/
// Get Ed Sheeran' albums
/*
spotifyApi.getArtistAlbums('607oAIdIe0j0JCsch5U3nD')
  .then(function(data) {
    console.log('Artist albums', data.body);
  }, function(err) {
    console.error(err);
  });
*/

module.exports = SpotifyPlayer;<commit_msg>Fixes a issue for the player.<commit_after>var SpotifyWebApi = require('spotify-web-api-node');
var Player = require('player');

const searchWords = "shape of you artist:Ed Sheeran";
//"sugar artist:Maroon 5";
//"I don't wanna live forever";

var logger;
var spotifyApi;
var player = new Player();

var SpotifyPlayer = function(option, log) {
  this.logger = log;
  this.config = option;

  if (!logger) {
    logger = require('humix-logger').createLogger('spotify-player', { consoleLevel: 'debug', filename: 'spotify-player.log' });
  }

  logger.info('SpotifyPlayer instance created.');
};

SpotifyPlayer.prototype.init = function() {
  var self = this;

  // credentials are optional
  self.spotifyApi = new SpotifyWebApi({
    clientId : self.config.spotify.clientId,
    clientSecret : self.config.spotify.clientSecret,
    //  redirectUri : 'http://www.example.com/callback'
  });

  // Retrieve an access token
  self.spotifyApi.clientCredentialsGrant()
    .then(function(data) {
      logger.info('The access token expires in ' + data.body['expires_in']);
      logger.info('The access token is ' + data.body['access_token']);

      // Save the access token so that it's used in future calls
      self.spotifyApi.setAccessToken(data.body['access_token']);
    }, function(err) {
      logger.info('Something went wrong when retrieving an access token', err.message);
  });

  // event: on playing
  player.on('playing', function(item) {
    logger.info('im playing... src: ' + item);
  });

  // event: on playend
  player.on('playend', function(item) {
    // return a playend item
    logger.info('src: ' + item + ' play done, switching to next one ...');

  });

  // event: on error
  player.on('error', function(err) {
    // when error occurs
    logger.info(err);
  });
}

SpotifyPlayer.prototype.playSong = function(songName, artistName) {

  var self = this;

  var query = songName;
  if (artistName) {
      query += ' artist:' + artistName;
  }

  logger.info('query for track on Spotify: ' + query);

  self.spotifyApi.search(query, ['track'], {limit: 5, offset: 1})
    .then(function(data) {
      logger.info('====== Track for "' + query + '" ======');

      for (var i in data.body.tracks.items) {
        if (i != 0) {
          logger.info('--------------------');
        }
        var trackObj = data.body.tracks.items[i];

        logger.info(' Album: ' + trackObj.album.name);
        logger.info(' Artist: ' + trackObj.artists[0].name);
        logger.info(' Track: ' + trackObj.name);

        player.add(trackObj.preview_url);
      }

      if (data.body.tracks.items.length > 0) {
        if (!player.playing) {
          player.play();
        }
      }
    }, function(err) {
      logger.error(err);
    });
};

SpotifyPlayer.prototype.pausePlaying = function() {
  var self = this;

  self.player.pause();
};

SpotifyPlayer.prototype.stopPlaying = function() {
  var self = this;

  self.player.stop();
};

// Search artist
/*
spotifyApi.search("Ed Sheeran", ['artist'], { limit : 5, offset : 1 })
  .then(function(data) {
    console.log('Artist for "Ed Shreen": ', data.body);
  }, function(err) {
    console.error(err);
  });*/

// Search Track
/*

*/
// Get Ed Sheeran' albums
/*
spotifyApi.getArtistAlbums('607oAIdIe0j0JCsch5U3nD')
  .then(function(data) {
    console.log('Artist albums', data.body);
  }, function(err) {
    console.error(err);
  });
*/

module.exports = SpotifyPlayer;<|endoftext|>


<commit_before>"use strict"

const math = require("mathjs")

// Math functions for nonlinearity
function sigmoid(value) {
    return 1/(1+math.pow(math.e, -value))
}

// derivative of sigmoid
function deriv(y) {
    return y * (1-y)
}

// both arrays must be of the same length
function multiplyElements(arr1, arr2) {
    arr1.forEach(function(index) {
        arr1[index] = arr1[index] * arr2[index];
    })
    return arr1
}

// must be vertical matrix
function getAveError(m1) {
    let sum = 0
    m1 = math.transpose(m1)
    let len = (m1.size())[1]

    for (let i = 0; i < len; i++) {
        sum += m1.subset(math.index(0,i))
    }
    return math.abs(sum / len)
}
// TODO: make a function that sets x and y

// Input Data
const x = math.matrix([[0, 0, 1],
                     [0, 1, 1],
                     [1, 0, 1],
                     [1, 1, 1]])

// Output Data
const y = math.transpose(math.matrix([[0, 0, 1, 1]]))

const layer0 = x
let layer1
let layer1_error
let layer1_delta
let layer2
let layer2_error
let layer2_delta
let hiddenLayerSize
let error
let minError = 100
let synapse0
let synapse1
let minSynapse0
let minSynapse1

const hlSizes = [(x.size())[1], (x.size())[1] - 1, (x.size())[1] + 1]
const alphas = [0.1, 1, 10]
const dropout_percent = 0.2;

let count = 1;

for (let alphaIndex = 0; alphaIndex < 3; alphaIndex++) {

    // Iterate over 3 hidden layer sizes to get the best one
    for (let hlSizeIndex = 0; hlSizeIndex < 3; hlSizeIndex++) {

        // Weights
        hiddenLayerSize = hlSizes[hlSizeIndex]
        synapse0 = math.random([3, hiddenLayerSize], -1, 1)
        synapse1 = math.random([hiddenLayerSize, 1], -1, 1)

        for (let i = 0; i < 40000; i++) {
            // forward propagation
            layer1 = math.multiply(layer0, synapse0).map(sigmoid)
            // dropout
            layer1.forEach(function(index) {
                let rand = math.random()
                if(rand < dropout_percent)
                    layer1[index] = 0
                layer1[index] *= 1.0/(1-dropout_percent)
            })
            layer2 = math.multiply(layer1, synapse1).map(sigmoid)
            // compare estimate with actual output
            layer2_error = math.subtract(y, layer2)
            // use slope of sigmoid to update values
            layer2_delta = multiplyElements(layer2_error, layer2.map(deriv))
            // distribute error over synapse 1
            layer1_error = math.multiply(layer2_delta, math.transpose(synapse1))
            // use slope of sigmoid to update values
            layer1_delta = multiplyElements(layer1_error, layer1.map(deriv))
            // compare estimate with actual output
            // update weights
            synapse0 = math.add(synapse0, math.multiply(math.transpose(layer0), layer1_delta))
            synapse1 = math.add(synapse1, math.multiply(math.transpose(layer1), layer2_delta))
            if(i % 10000 == 0) {
                if (i == 0) {
                    console.log(count)
                    count++
                }
                console.log(i)
            }
        }
        let currentError = getAveError(layer2_error)
        if (currentError < minError) {
            minError = currentError
            minSynapse1 = synapse1
            minSynapse0 = synapse0
        }
    }
}
console.log("Output of training data after training")
let test = math.multiply(x, minSynapse0).map(sigmoid)
console.log(math.multiply(test, minSynapse1).map(sigmoid))

// Test Cases for function
let testX = math.matrix([[0, 1, 0]])
console.log("Output of [0,1,0]")
let testl1 = math.multiply(testX, minSynapse0).map(sigmoid)
console.log(math.multiply(testl1, minSynapse1).map(sigmoid))

testX = math.matrix([[1, 1, 0]])
console.log("Output of [1,1,0]")
testl1 = math.multiply(testX, minSynapse0).map(sigmoid)
console.log(math.multiply(testl1, minSynapse1).map(sigmoid))

console.log("Final Synapse0")
console.log(minSynapse0)
console.log("Final Synapse1")
console.log(minSynapse1)
<commit_msg>testing for other logical operators<commit_after>"use strict"

const math = require("mathjs")

// Math functions for nonlinearity
function sigmoid(value) {
    return 1/(1+math.pow(math.e, -value))
}

// derivative of sigmoid
function deriv(y) {
    return y * (1-y)
}

// both arrays must be of the same length
function multiplyElements(arr1, arr2) {
    arr1.forEach(function(index) {
        arr1[index] = arr1[index] * arr2[index];
    })
    return arr1
}

// must be vertical matrix
function getAveError(m1) {
    let sum = 0
    m1 = math.transpose(m1)
    let len = (m1.size())[1]

    for (let i = 0; i < len; i++) {
        sum += math.abs(m1.subset(math.index(0,i)))
    }
    return math.abs(sum / len)
}
// TODO: make a function that sets x and y

// Input Data
const x = math.matrix([[0, 0, 1, 1],
                       [0, 0, 1, 1],
                       [0, 0, 1, 1],
                       [0, 0, 1, 1],
                       [0, 1, 1, 1],
                       [0, 1, 1, 1],
                       [0, 1, 1, 1],
                       [0, 1, 1, 1],
                       [1, 0, 1, 1],
                       [1, 0, 1, 1],
                       [1, 0, 1, 1],
                       [1, 0, 1, 1],
                       [1, 1, 1, 1],
                       [1, 1, 1, 1],
                       [1, 1, 1, 1],
                       [1, 1, 1, 1]])

// Output Data
const y = math.transpose(math.matrix([[0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]]))

const layer0 = x
let layer1
let layer1_error
let layer1_delta
let layer2
let layer2_error
let layer2_delta
let hiddenLayerSize
let error
let minError = 100
let synapse0
let synapse1
let minSynapse0
let minSynapse1

const hlSizes = [(x.size())[1], (x.size())[1] - 1, (x.size())[1] + 1]
const alphas = [0.1, 1, 10]
const dropout_percent = 0.2;

let count = 1;

for (let alphaIndex = 0; alphaIndex < 3; alphaIndex++) {

    // Iterate over 3 hidden layer sizes to get the best one
    for (let hlSizeIndex = 0; hlSizeIndex < 3; hlSizeIndex++) {

        // Weights
        hiddenLayerSize = hlSizes[hlSizeIndex]
        synapse0 = math.random([x.size()[1], hiddenLayerSize], -1, 1)
        synapse1 = math.random([hiddenLayerSize, 1], -1, 1)

        for (let i = 0; i < 40000; i++) {
            // forward propagation
            layer1 = math.multiply(layer0, synapse0).map(sigmoid)
            // dropout
            layer1.forEach(function(index) {
                let rand = math.random()
                if(rand < dropout_percent)
                    layer1[index] = 0
                layer1[index] *= 1.0/(1-dropout_percent)
            })
            layer2 = math.multiply(layer1, synapse1).map(sigmoid)
            // compare estimate with actual output
            layer2_error = math.subtract(y, layer2)
            // use slope of sigmoid to update values
            layer2_delta = multiplyElements(layer2_error, layer2.map(deriv))
            // distribute error over synapse 1
            layer1_error = math.multiply(layer2_delta, math.transpose(synapse1))
            // use slope of sigmoid to update values
            layer1_delta = multiplyElements(layer1_error, layer1.map(deriv))
            // compare estimate with actual output
            // update weights
            synapse0 = math.add(synapse0, math.multiply(math.transpose(layer0), layer1_delta))
            synapse1 = math.add(synapse1, math.multiply(math.transpose(layer1), layer2_delta))
            if(i % 10000 == 0) {
                if (i == 0) {
                    console.log(count)
                    count++
                }
                else
                    console.log(i)
            }
        }
        let currentError = getAveError(layer2_error)
        if (currentError < minError) {
            minError = currentError
            minSynapse1 = synapse1
            minSynapse0 = synapse0
        }
    }
}

console.log("Min Error")
console.log(minError)

console.log("Output of training data after training")
let test = math.multiply(x, minSynapse0).map(sigmoid)
console.log(math.multiply(test, minSynapse1).map(sigmoid))

// Test Cases for function
let testX = math.matrix([[0, 1, 1, 1]])
console.log("Output of [0, 1, 1, 1]")
let testl1 = math.multiply(testX, minSynapse0).map(sigmoid)
console.log(math.multiply(testl1, minSynapse1).map(sigmoid))

testX = math.matrix([[0, 0, 1, 1]])
console.log("Output of [0, 0, 1, 1]")
testl1 = math.multiply(testX, minSynapse0).map(sigmoid)
console.log(math.multiply(testl1, minSynapse1).map(sigmoid))

testX = math.matrix([[1, 0, 1, 1]])
console.log("Output of [1, 0, 1, 1]")
testl1 = math.multiply(testX, minSynapse0).map(sigmoid)
console.log(math.multiply(testl1, minSynapse1).map(sigmoid))

testX = math.matrix([[1, 1, 1, 1]])
console.log("Output of [1, 1, 1, 1]")
testl1 = math.multiply(testX, minSynapse0).map(sigmoid)
console.log(math.multiply(testl1, minSynapse1).map(sigmoid))

console.log("Final Synapse0")
console.log(minSynapse0)
console.log("Final Synapse1")
console.log(minSynapse1)
<|endoftext|>


<commit_before>/*
 * statsFilelist
 * https://github.com/anseki/stats-filelist
 *
 * Copyright (c) 2018 anseki
 * Licensed under the MIT license.
 */

'use strict';

var
  DEFAULT_OPTIONS = {
    filter: true,
    recursive: true,
    clearCache: false,
    listOf: null
  },
  fs = require('fs'),
  pathUtil = require('path'),
  cache = {};

function parseDirEntries(dirPath, filter, options, callback) {

  function parseEntries() {

    function addStats(stats) { // extended stats
      var filterRes = filter(stats); // include, exit, stop, recursive

      if (filterRes.include) {
        list.push(stats);
      }

      if (filterRes.stop) {
        options.stopParse = true;
        process.nextTick(parseEntries);
      } else {
        if (filterRes.exit) { entries = []; }
        if (stats.isDirectory() && filterRes.recursive) {
          parseDirEntries(stats.path, filter, options, function(statsList) {
            list = list.concat(statsList);
            process.nextTick(parseEntries);
          });
        } else {
          process.nextTick(parseEntries);
        }
      }
    }

    var path = entries.shift(), fullPath, stats;

    if (!path || options.stopParse) { // finished
      callback(list);
    } else {
      fullPath = pathUtil.resolve(path);
      if ((stats = path2stats(fullPath))) { // cache
        addStats(stats);
      } else {
        fs.stat(path, function(error, stats) {
          if (error) { throw error; }
          addStats(path2stats(fullPath, stats, path));
        });
      }
    }
  }

  var list = [], entries;

  fs.readdir(dirPath, function(error, nameList) {
    if (error) { throw error; }
    entries = nameList.map(
      function(name) { return pathUtil.join(dirPath, name); });
    process.nextTick(parseEntries);
  });
}

function parseDirEntriesSync(dirPath, filter, options) {
  var list = [], entries = fs.readdirSync(dirPath).map(
    function(name) { return pathUtil.join(dirPath, name); }),
    path, fullPath, stats, filterRes;

  while (true) {
    if (!(path = entries.shift()) || options.stopParse) { // finished
      return(list);
    } else {
      fullPath = pathUtil.resolve(path);
      stats = path2stats(fullPath) || path2stats(fullPath, fs.statSync(path), path);
      filterRes = filter(stats); // include, exit, stop, recursive

      if (filterRes.include) {
        list.push(stats);
      }

      if (filterRes.stop) {
        options.stopParse = true;
      } else {
        if (filterRes.exit) { entries = []; }
        if (stats.isDirectory() && filterRes.recursive) {
          list = list.concat(parseDirEntriesSync(stats.path, filter, options));
        }
      }
    }
  }
}

function path2stats(fullPath, stats, path) {
  if (stats) {
    stats.path = path;
    stats.fullPath = fullPath;
    stats.dirPath = pathUtil.dirname(fullPath);
    stats.name = pathUtil.basename(fullPath);
    stats.extension = pathUtil.extname(fullPath).replace(/^\./, '');
    cache[fullPath] = stats;
  }
  return cache[fullPath];
}

function fixFilter(options) {
  var filter = options.filter, type = typeof filter;
  return (
    filter instanceof RegExp ?
      function(stats) {
        return { include: filter.test(stats.fullPath),
          recursive: options.recursive };
      } :
    type === 'function' ?
      function(stats) {
        var res = filter(stats);
        if (typeof res !== 'object') {
          res = { include: !!res, recursive: options.recursive };
        } else if (typeof res.recursive !== 'boolean') {
          res.recursive = options.recursive;
        }
        return res;
      } :
    type === 'string' ?
      function(stats) {
        var fullPath = stats.fullPath,
          searchValue = filter.replace(/[\/\\]/g, pathUtil.sep);
        if (process.platform === 'win32') {
          fullPath = fullPath.toLowerCase();
          searchValue = searchValue.toLowerCase();
        }
        return { include: fullPath.indexOf(searchValue) > -1,
          recursive: options.recursive };
      } :
    type === 'boolean' ?
      function() { return { include: filter, recursive: options.recursive }; } :
    function() { return { include: true, recursive: options.recursive }; }
  );
}

function addUniqueStats(stats, list, added) {
  (Array.isArray(stats) ? stats : [stats]).forEach(function(stats) {
    if (!added[stats.fullPath]) {
      added[stats.fullPath] = true;
      list.push(stats);
    }
  });
}

function getList(list, listOf) {
  return list.map(function(stats) {
    return typeof stats[listOf] === 'function' ? stats[listOf]() : stats[listOf];
  });
}

function parseArgStartDirs(startDirs) {
  return !startDirs ? ['.'] :
    (Array.isArray(startDirs) ? startDirs : [startDirs])
      .filter(function(dir) { return !!dir; }); // copy
}

function parseArgOptions(index, args) {
  return Object.keys(DEFAULT_OPTIONS).reduce(function(options, optionName) {
      if (typeof options[optionName] === 'undefined') {
        options[optionName] = DEFAULT_OPTIONS[optionName];
      }
      return options;
    },
    args.length - 1 < index ? {} :
    args[index] && typeof args[index] === 'object' &&
      !(args[index] instanceof RegExp) ? args[index] :
    { filter: args[index], recursive: args[index + 1] }
  );
}

// Another args: (startDirs, callback, filter, recursive)
exports.get = function(startDirs, callback, options) {

  function parseDirs() {

    function addStats(stats) { // extended stats
      if (stats.isDirectory()) {
        parseDirEntries(stats.path, filter, options, function(statsList) {
          addUniqueStats(statsList, list, added);
          process.nextTick(parseDirs);
        });
      } else {
        addUniqueStats(stats, list, added);
        process.nextTick(parseDirs);
      }
    }

    var path = startDirs.shift(), fullPath, stats;

    if (!path || options.stopParse) { // finished
      delete options.stopParse; // It might be reused.
      if (typeof callback === 'function') {
        callback(options.listOf ? getList(list, options.listOf) : list);
      }
    } else {
      fullPath = pathUtil.resolve(path);
      if ((stats = path2stats(fullPath))) { // cache
        addStats(stats);
      } else {
        fs.stat(path, function(error, stats) {
          if (error) { throw error; }
          addStats(path2stats(fullPath, stats, path));
        });
      }
    }
  }

  var filter, list = [], added = {};

  startDirs = parseArgStartDirs(startDirs);
  options = parseArgOptions(2, arguments);

  if (options.clearCache) { cache = {}; }
  filter = fixFilter(options);
  delete options.stopParse; // It might be reused.

  process.nextTick(parseDirs);
};

// Another args: (startDirs, filter, recursive)
exports.getSync = function(startDirs, options) {

  var filter, list = [], added = {},
    path, fullPath, stats;

  startDirs = parseArgStartDirs(startDirs);
  options = parseArgOptions(1, arguments);

  if (options.clearCache) { cache = {}; }
  filter = fixFilter(options);
  delete options.stopParse; // It might be reused.

  while (true) {
    if (!(path = startDirs.shift()) || options.stopParse) { // finished
      delete options.stopParse; // It might be reused.
      return options.listOf ? getList(list, options.listOf) : list;
    } else {
      fullPath = pathUtil.resolve(path);
      stats = path2stats(fullPath) || path2stats(fullPath, fs.statSync(path), path);
      addUniqueStats(stats.isDirectory() ?
        parseDirEntriesSync(stats.path, filter, options) : stats, list, added);
    }
  }
};
<commit_msg>Ignore entries by name.<commit_after>/*
 * statsFilelist
 * https://github.com/anseki/stats-filelist
 *
 * Copyright (c) 2018 anseki
 * Licensed under the MIT license.
 */

'use strict';

var
  DEFAULT_OPTIONS = {
    filter: true,
    recursive: true,
    clearCache: false,
    listOf: null
  },
  EXCLUDE_NAMES = ['System Volume Information'],
  fs = require('fs'),
  pathUtil = require('path'),
  cache = {};

function parseDirEntries(dirPath, filter, options, callback) {

  function parseEntries() {

    function addStats(stats) { // extended stats
      var filterRes = filter(stats); // include, exit, stop, recursive

      if (filterRes.include) {
        list.push(stats);
      }

      if (filterRes.stop) {
        options.stopParse = true;
        process.nextTick(parseEntries);
      } else {
        if (filterRes.exit) { entries = []; }
        if (stats.isDirectory() && filterRes.recursive) {
          parseDirEntries(stats.path, filter, options, function(statsList) {
            list = list.concat(statsList);
            process.nextTick(parseEntries);
          });
        } else {
          process.nextTick(parseEntries);
        }
      }
    }

    var path = entries.shift(), fullPath, stats;

    if (!path || options.stopParse) { // finished
      callback(list);
    } else {
      fullPath = pathUtil.resolve(path);
      if ((stats = path2stats(fullPath))) { // cache
        addStats(stats);
      } else {
        fs.stat(path, function(error, stats) {
          if (error) { throw error; }
          addStats(path2stats(fullPath, stats, path));
        });
      }
    }
  }

  var list = [], entries;

  fs.readdir(dirPath, function(error, nameList) {
    if (error) { throw error; }
    entries = nameList
      .filter(function(name) { return !EXCLUDE_NAMES.includes(name); })
      .map(function(name) { return pathUtil.join(dirPath, name); });
    process.nextTick(parseEntries);
  });
}

function parseDirEntriesSync(dirPath, filter, options) {
  var list = [],
    entries = fs.readdirSync(dirPath)
      .filter(function(name) { return !EXCLUDE_NAMES.includes(name); })
      .map(function(name) { return pathUtil.join(dirPath, name); }),
    path, fullPath, stats, filterRes;

  while (true) {
    if (!(path = entries.shift()) || options.stopParse) { // finished
      return(list);
    } else {
      fullPath = pathUtil.resolve(path);
      stats = path2stats(fullPath) || path2stats(fullPath, fs.statSync(path), path);
      filterRes = filter(stats); // include, exit, stop, recursive

      if (filterRes.include) {
        list.push(stats);
      }

      if (filterRes.stop) {
        options.stopParse = true;
      } else {
        if (filterRes.exit) { entries = []; }
        if (stats.isDirectory() && filterRes.recursive) {
          list = list.concat(parseDirEntriesSync(stats.path, filter, options));
        }
      }
    }
  }
}

function path2stats(fullPath, stats, path) {
  if (stats) {
    stats.path = path;
    stats.fullPath = fullPath;
    stats.dirPath = pathUtil.dirname(fullPath);
    stats.name = pathUtil.basename(fullPath);
    stats.extension = pathUtil.extname(fullPath).replace(/^\./, '');
    cache[fullPath] = stats;
  }
  return cache[fullPath];
}

function fixFilter(options) {
  var filter = options.filter, type = typeof filter;
  return (
    filter instanceof RegExp ?
      function(stats) {
        return { include: filter.test(stats.fullPath),
          recursive: options.recursive };
      } :
    type === 'function' ?
      function(stats) {
        var res = filter(stats);
        if (typeof res !== 'object') {
          res = { include: !!res, recursive: options.recursive };
        } else if (typeof res.recursive !== 'boolean') {
          res.recursive = options.recursive;
        }
        return res;
      } :
    type === 'string' ?
      function(stats) {
        var fullPath = stats.fullPath,
          searchValue = filter.replace(/[\/\\]/g, pathUtil.sep);
        if (process.platform === 'win32') {
          fullPath = fullPath.toLowerCase();
          searchValue = searchValue.toLowerCase();
        }
        return { include: fullPath.indexOf(searchValue) > -1,
          recursive: options.recursive };
      } :
    type === 'boolean' ?
      function() { return { include: filter, recursive: options.recursive }; } :
    function() { return { include: true, recursive: options.recursive }; }
  );
}

function addUniqueStats(stats, list, added) {
  (Array.isArray(stats) ? stats : [stats]).forEach(function(stats) {
    if (!added[stats.fullPath]) {
      added[stats.fullPath] = true;
      list.push(stats);
    }
  });
}

function getList(list, listOf) {
  return list.map(function(stats) {
    return typeof stats[listOf] === 'function' ? stats[listOf]() : stats[listOf];
  });
}

function parseArgStartDirs(startDirs) {
  return !startDirs ? ['.'] :
    (Array.isArray(startDirs) ? startDirs : [startDirs])
      .filter(function(dir) { return !!dir; }); // copy
}

function parseArgOptions(index, args) {
  return Object.keys(DEFAULT_OPTIONS).reduce(function(options, optionName) {
      if (typeof options[optionName] === 'undefined') {
        options[optionName] = DEFAULT_OPTIONS[optionName];
      }
      return options;
    },
    args.length - 1 < index ? {} :
    args[index] && typeof args[index] === 'object' &&
      !(args[index] instanceof RegExp) ? args[index] :
    { filter: args[index], recursive: args[index + 1] }
  );
}

// Another args: (startDirs, callback, filter, recursive)
exports.get = function(startDirs, callback, options) {

  function parseDirs() {

    function addStats(stats) { // extended stats
      if (stats.isDirectory()) {
        parseDirEntries(stats.path, filter, options, function(statsList) {
          addUniqueStats(statsList, list, added);
          process.nextTick(parseDirs);
        });
      } else {
        addUniqueStats(stats, list, added);
        process.nextTick(parseDirs);
      }
    }

    var path = startDirs.shift(), fullPath, stats;

    if (!path || options.stopParse) { // finished
      delete options.stopParse; // It might be reused.
      if (typeof callback === 'function') {
        callback(options.listOf ? getList(list, options.listOf) : list);
      }
    } else {
      fullPath = pathUtil.resolve(path);
      if ((stats = path2stats(fullPath))) { // cache
        addStats(stats);
      } else {
        fs.stat(path, function(error, stats) {
          if (error) { throw error; }
          addStats(path2stats(fullPath, stats, path));
        });
      }
    }
  }

  var filter, list = [], added = {};

  startDirs = parseArgStartDirs(startDirs);
  options = parseArgOptions(2, arguments);

  if (options.clearCache) { cache = {}; }
  filter = fixFilter(options);
  delete options.stopParse; // It might be reused.

  process.nextTick(parseDirs);
};

// Another args: (startDirs, filter, recursive)
exports.getSync = function(startDirs, options) {

  var filter, list = [], added = {},
    path, fullPath, stats;

  startDirs = parseArgStartDirs(startDirs);
  options = parseArgOptions(1, arguments);

  if (options.clearCache) { cache = {}; }
  filter = fixFilter(options);
  delete options.stopParse; // It might be reused.

  while (true) {
    if (!(path = startDirs.shift()) || options.stopParse) { // finished
      delete options.stopParse; // It might be reused.
      return options.listOf ? getList(list, options.listOf) : list;
    } else {
      fullPath = pathUtil.resolve(path);
      stats = path2stats(fullPath) || path2stats(fullPath, fs.statSync(path), path);
      addUniqueStats(stats.isDirectory() ?
        parseDirEntriesSync(stats.path, filter, options) : stats, list, added);
    }
  }
};
<|endoftext|>


<commit_before>/**
 * Fires sunlight based events provided a latitude and longitude.
 * Returns a {@link module:sunlight.SunlightMonitor} instance.
 * @module sunlight
 * @see module:sunlight.SunlightMonitor
 */

var MODULE_NAME = 'sunlight';
var IMPLEMENTS = MODULE_NAME;
var INJECT = ['logger', 'config', 'states'];
var STATE_TYPE = MODULE_NAME;
var sunlightMonitor = require('./sunlight-monitor');

function factory(services) {
  var logger = services.logger.getLogger('sunlight');
  var states = services.states;
  var config = services.config;
  var location = config.location || {};

  var monitor = sunlightMonitor.monitor({
    logger: logger,
    latitude: location.latitude,
    longitude: location.longitude
  });

  monitor.on('light', function(lightState) {
    states.emitState(STATE_TYPE, lightState.value);
  });

  states.addType(STATE_TYPE, {
    getCurrent: function() {
      return monitor.current;
    }
  });

 return sunlightMonitor;
}

module.exports = exports = factory;
exports.$implements = IMPLEMENTS;
exports.$inject = INJECT;

<commit_msg>not returning correct value<commit_after>/**
 * Fires sunlight based events provided a latitude and longitude.
 * Returns a {@link module:sunlight.SunlightMonitor} instance.
 * @module sunlight
 * @see module:sunlight.SunlightMonitor
 */

var MODULE_NAME = 'sunlight';
var IMPLEMENTS = MODULE_NAME;
var INJECT = ['logger', 'config', 'states'];
var STATE_TYPE = MODULE_NAME;
var sunlightMonitor = require('./sunlight-monitor');

function factory(services) {
  var logger = services.logger.getLogger('sunlight');
  var states = services.states;
  var config = services.config;
  var location = config.location || {};

  var monitor = sunlightMonitor.monitor({
    logger: logger,
    latitude: location.latitude,
    longitude: location.longitude
  });

  monitor.on('light', function(lightState) {
    states.emitState(STATE_TYPE, lightState.value);
  });

  states.addType(STATE_TYPE, {
    getCurrent: function() {
      return monitor.current;
    }
  });

 return monitor;
}

module.exports = exports = factory;
exports.$implements = IMPLEMENTS;
exports.$inject = INJECT;

<|endoftext|>


<commit_before>/*
Copyright (c) 2012, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://yuilibrary.com/license/
*/

exports.cssstamp = function (options, blob, done) {
    options = options || {};

    options.stamp = options.stamp || '';

    var result = blob.result + options.stamp + '\n';

    done(null, new blob.constructor(result, blob));
};
<commit_msg>Added carriage return to css stamp<commit_after>/*
Copyright (c) 2012, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://yuilibrary.com/license/
*/

exports.cssstamp = function (options, blob, done) {
    options = options || {};

    options.stamp = options.stamp || '';

    var result = blob.result + '\n' + options.stamp + '\n';

    done(null, new blob.constructor(result, blob));
};
<|endoftext|>