<commit_before>'use strict';

var crypto = require('crypto');
var CustomStats = require('webpack-custom-stats-patch');

var DEFAULT_PARAMS = {
  customStatsKey: 'sprockets',
  sriKey: 'integrity'
};

function SprocketsStatsWebpackPlugin(options) {
  var params = options || {};
  var subresourceIntegrity = (params.subResourceIntegrity === undefined ? true : params.subResourceIntegrity);

  this._customStatsKey = options.customStatsKey || 'sprockets';
  this._sriKey = params.sriKey || 'integrity';

  if (subresourceIntegrity) {
    try {
      var sriPlugin = require('@mikechau/sri-webpack-plugin');
      this._sriEnabled = true;
    } catch(err) {
      this._sriEnabled = false;
    }
  }
};

SprocketsStatsWebpackPlugin.prototype.apply = function(compiler) {
  var customStatsKey = this._customStatsKey;
  var sriKey = this._sriKey;
  var sriEnabled = this._sriEnabled;
  var sprockets = {};

  compiler.plugin('this-compilation', function(compilation) {
    compilation.plugin('optimize-assets', function(assets, callback) {
      Object.keys(assets).forEach(function(file) {
        var asset = assets[file];
        var content;

        sprockets[file] = {
          size: asset.size(),
          digest: crypto.createHash('md5').update(content).digest('hex')
        };
      });

      callback();
    });
  });

  compiler.plugin('after-emit', function(compilation, callback) {
    var stats = new CustomStats(compilation);

    stats.addCustomStat(customStatsKey, sprockets);

    callback();
  });
};

module.exports = SprocketsStatsWebpackPlugin;
<commit_msg>Save source to variable<commit_after>'use strict';

var crypto = require('crypto');
var CustomStats = require('webpack-custom-stats-patch');

var DEFAULT_PARAMS = {
  customStatsKey: 'sprockets',
  sriKey: 'integrity'
};

function SprocketsStatsWebpackPlugin(options) {
  var params = options || {};
  var subresourceIntegrity = (params.subResourceIntegrity === undefined ? true : params.subResourceIntegrity);

  this._customStatsKey = options.customStatsKey || 'sprockets';
  this._sriKey = params.sriKey || 'integrity';

  if (subresourceIntegrity) {
    try {
      var sriPlugin = require('@mikechau/sri-webpack-plugin');
      this._sriEnabled = true;
    } catch(err) {
      this._sriEnabled = false;
    }
  }
};

SprocketsStatsWebpackPlugin.prototype.apply = function(compiler) {
  var customStatsKey = this._customStatsKey;
  var sriKey = this._sriKey;
  var sriEnabled = this._sriEnabled;
  var sprockets = {};

  compiler.plugin('this-compilation', function(compilation) {
    compilation.plugin('optimize-assets', function(assets, callback) {
      Object.keys(assets).forEach(function(file) {
        var asset = assets[file];
        var content = asset.source();

        sprockets[file] = {
          size: asset.size(),
          digest: crypto.createHash('md5').update(content).digest('hex')
        };
      });

      callback();
    });
  });

  compiler.plugin('after-emit', function(compilation, callback) {
    var stats = new CustomStats(compilation);

    stats.addCustomStat(customStatsKey, sprockets);

    callback();
  });
};

module.exports = SprocketsStatsWebpackPlugin;
<|endoftext|>


<commit_before>var debug  = require('debug')('npm-me')
var stats  = require('npm-stats')()
var map    = require('map-limit')
var semver = require('semver')
var got    = require('got')

module.exports = function(user, done) {
  stats.user(user).list(function(err, list) {
    if (err) return done(err)

    map(list, 25, function(pkg, next) {
      stats.module(pkg).info(function(err, data) {
        if (err) return next(err)

        var versions = Object.keys(data.versions)
        var latest   = versions.sort(function(a, b) {
          return semver.compare(b, a)
        }).shift()

        if (!latest) return next()
        var lastPublisher = (
             data.versions[latest]._npmUser
          && data.versions[latest]._npmUser.name
          && data.versions[latest]._npmUser.name === user
        )

        var firstPublisher = data.maintainers.shift()
        firstPublisher = firstPublisher && firstPublisher.name

        if (!lastPublisher && !firstPublisher) return next()

        debug(pkg)
        got('http://api.npmjs.org/downloads/point/last-month/' + pkg, function(err, body) {
          if (err) return next(err)

          next(null, {
              name: pkg
            , count: JSON.parse(body).downloads
          })
        })
      })
    }, done)
  })
}
<commit_msg>Ignore semver errors on packages<commit_after>var debug  = require('debug')('npm-me')
var stats  = require('npm-stats')()
var map    = require('map-limit')
var semver = require('semver')
var got    = require('got')

module.exports = function(user, done) {
  stats.user(user).list(function(err, list) {
    if (err) return done(err)

    map(list, 25, function(pkg, next) {
      stats.module(pkg).info(function(err, data) {
        if (err) return next(err)

        var versions = Object.keys(data.versions)
        var latest   = versions.sort(function(a, b) {
          try {
            return semver.compare(b, a)
          } catch (err) {
            return -1
          }
        }).shift()

        if (!latest) return next()
        var lastPublisher = (
             data.versions[latest]._npmUser
          && data.versions[latest]._npmUser.name
          && data.versions[latest]._npmUser.name === user
        )

        var firstPublisher = data.maintainers.shift()
        firstPublisher = firstPublisher && firstPublisher.name

        if (!lastPublisher && !firstPublisher) return next()

        debug(pkg)
        got('http://api.npmjs.org/downloads/point/last-month/' + pkg, function(err, body) {
          if (err) return next(err)

          next(null, {
              name: pkg
            , count: JSON.parse(body).downloads
          })
        })
      })
    }, done)
  })
}
<|endoftext|>


<commit_before>var patch = function(a, b) {
  Object.keys(b).forEach(function(key){
    a[key] = b[key];
  });
  return a;
};

var P = Object.create(HTMLElement.prototype, {
  editable: {
    get: function(){ return this.getAttribute('editable') == 'true'; }
  },

  env: {
    get: function(){ return this.readAttributeAsJson('data-environment'); }
  },

  config: {
    get: function(){ return this.readAttributeAsJson('data-config'); }
  },

  userstate: {
    get: function(){ return this.readAttributeAsJson('data-userstate'); }
  }
});

P.readAttributeAsJson = function(name) {
  if(!this.hasAttribute(name)) { return {}; };
  return JSON.parse(this.getAttribute(name));
};

P.attachedCallback = function(){
  console.log('attached');
  this.iframe = document.createElement('iframe');
  this.iframe.src = this.getAttribute('src');
  this.iframe.addEventListener('message', this.handleMessage.bind(this));

  this.appendChild(this.iframe);
};

P.attributeChangedCallback = function(name, old, value){
  switch(name) {
    case 'editable':
      this.sendMessage('editableChanged', { editable: this.editable });
      // Compat
      this.sendMessage('setEditable', { editable: this.editable });
      break;

    case 'data-config':
      this.sendMessage('attributesChanged', this.config);
      break;

    case 'data-userstate':
      this.sendMessage('learnerStateChanged', this.userstate);
      break;
  }
};

P.handleMessage = function(e){
  if(e.detail.event) {
    var event = e.detail.event;
    var data = e.detail.data;

    console.log('↖', event, data);

    var handler = this.messageHandlers[event];
    if(handler) {
      return handler.call(this, data);
    } else {
      // Can't handle that, re-translating event
      var evt = new CustomEvent(event, { detail: data, bubbles: true });
      this.dispatchEvent(evt);
    }
  }
};

P.sendMessage = function(event, data){
  var message = { event: event };
  if(data) { message.data = data; }
  if(this.iframe && this.iframe.contentWindow) {
    this.iframe.contentWindow.postMessage(message, '*');
    console.log('↘', message.event, message.data);
  }
};

P.messageHandlers = {
  startListening: function(){
    this.sendMessage('environmentChanged', this.env);
    this.sendMessage('attributesChanged', this.config);
    this.sendMessage('learnerstateChanged', this.userstate);
    this.sendMessage('editableChanged', { editable: this.editable });
    // Compat
    this.sendMessage('setEditable', { editable: this.editable });
    this.sendMessage('attached');
  },

  setHeight: function(data){
    var height = Math.min(data.pixels, 720);
    this.iframe.style.height = height + 'px';
  },

  setAttributes: function(data){
    var config = this.readAttributeAsJson('data-config');
    patch(config, data);
    this.setAttribute('data-config', JSON.stringify(config));
  },

  setLearnerState: function(data) {
    var userstate = this.readAttributeAsJson('data-userstate');
    patch(userstate, data);
    this.setAttribute('data-userstate', JSON.stringify(userstate));
  },

  getPath: function(data) {
    console.warn('getPath/setPath are obsolete');
    var assetUrlTemplate = this.env && this.env.assetUrlTemplate;
    if(assetUrlTemplate) {
      var url = assetUrlTemplate.replace('<%= id %>', data.assetId );
      this.sendMessage('setPath', { url: url});
    }
  }
};

window.addEventListener('message', function(e){
  var iframes = document.querySelectorAll('versal-iframe-launcher > iframe');
  Array.prototype.forEach.call(iframes, function(iframe){
    if(iframe.contentWindow == e.source) {
      iframe.dispatchEvent(new CustomEvent('message', { detail: e.data }));
    }
  });
});

document.registerElement('versal-iframe-launcher', { prototype: P });
<commit_msg>Don't transparently pass on all unrecognised events.<commit_after>var patch = function(a, b) {
  Object.keys(b).forEach(function(key){
    a[key] = b[key];
  });
  return a;
};

var P = Object.create(HTMLElement.prototype, {
  editable: {
    get: function(){ return this.getAttribute('editable') == 'true'; }
  },

  env: {
    get: function(){ return this.readAttributeAsJson('data-environment'); }
  },

  config: {
    get: function(){ return this.readAttributeAsJson('data-config'); }
  },

  userstate: {
    get: function(){ return this.readAttributeAsJson('data-userstate'); }
  }
});

P.readAttributeAsJson = function(name) {
  if(!this.hasAttribute(name)) { return {}; };
  return JSON.parse(this.getAttribute(name));
};

P.attachedCallback = function(){
  console.log('attached');
  this.iframe = document.createElement('iframe');
  this.iframe.src = this.getAttribute('src');
  this.iframe.addEventListener('message', this.handleMessage.bind(this));

  this.appendChild(this.iframe);
};

P.attributeChangedCallback = function(name, old, value){
  switch(name) {
    case 'editable':
      this.sendMessage('editableChanged', { editable: this.editable });
      // Compat
      this.sendMessage('setEditable', { editable: this.editable });
      break;

    case 'data-config':
      this.sendMessage('attributesChanged', this.config);
      break;

    case 'data-userstate':
      this.sendMessage('learnerStateChanged', this.userstate);
      break;
  }
};

P.handleMessage = function(e){
  if(e.detail.event) {
    var event = e.detail.event;
    var data = e.detail.data;

    console.log('↖', event, data);

    var handler = this.messageHandlers[event];
    if(handler) {
      handler.call(this, data);
    } else {
      console.error('Unknown event received: ' + event);
      this.fireEvent('error', {message: 'Unknown event received: ' + event});
    }
  }
};

P.sendMessage = function(event, data){
  var message = { event: event };
  if(data) { message.data = data; }
  if(this.iframe && this.iframe.contentWindow) {
    this.iframe.contentWindow.postMessage(message, '*');
    console.log('↘', message.event, message.data);
  }
};

P.fireEvent = function(event, data) {
  var evt = new CustomEvent(event, { detail: data, bubbles: true });
  this.dispatchEvent(evt);
};

P.messageHandlers = {
  startListening: function(){
    this.sendMessage('environmentChanged', this.env);
    this.sendMessage('attributesChanged', this.config);
    this.sendMessage('learnerstateChanged', this.userstate);
    this.sendMessage('editableChanged', { editable: this.editable });
    // Compat
    this.sendMessage('setEditable', { editable: this.editable });
    this.sendMessage('attached');
  },

  setHeight: function(data){
    var height = Math.min(data.pixels, 720);
    this.iframe.style.height = height + 'px';
  },

  setAttributes: function(data){
    var config = this.readAttributeAsJson('data-config');
    patch(config, data);
    this.setAttribute('data-config', JSON.stringify(config));
  },

  setLearnerState: function(data) {
    var userstate = this.readAttributeAsJson('data-userstate');
    patch(userstate, data);
    this.setAttribute('data-userstate', JSON.stringify(userstate));
  },

  getPath: function(data) {
    console.warn('getPath/setPath are obsolete');
    var assetUrlTemplate = this.env && this.env.assetUrlTemplate;
    if(assetUrlTemplate) {
      var url = assetUrlTemplate.replace('<%= id %>', data.assetId );
      this.sendMessage('setPath', { url: url});
    }
  },

  setPropertySheetAttributes: function(data) { this.fireEvent('setPropertySheetAttributes', data); },
  setEmpty: function(data) { this.fireEvent('setEmpty', data); },
  track: function(data) { this.fireEvent('track', data); },
  error: function(data) { this.fireEvent('error', data); },
  changeBlocking: function(data) { this.fireEvent('changeBlocking', data); },
  requestAsset: function(data) { this.fireEvent('requestAsset', data); }
};

window.addEventListener('message', function(e){
  var iframes = document.querySelectorAll('versal-iframe-launcher > iframe');
  Array.prototype.forEach.call(iframes, function(iframe){
    if(iframe.contentWindow == e.source) {
      iframe.dispatchEvent(new CustomEvent('message', { detail: e.data }));
    }
  });
});

document.registerElement('versal-iframe-launcher', { prototype: P });
<|endoftext|>


<commit_before>const amqp = require('amqplib');
const http = require('http');
const rabbitConfig = require('rabbit-config.js');

const state = {
    connection: null,
    channel: null,
    config: {},
}

const _ = {
    contentToBuffer,
    generateConfiguration,
    create,
    // connection,
    channel,
    createQueues,
    createExchanges,
    createPolicies,
    createUpstreams,
    bindQueues,
    findExchange,
    createConsumers,
    close,
};

// API for interacting with Rabbit MQ
// ==================================
// Public APIs
// - initialize - shouldn't be called all the time only on reconnection
// - channel
// - publishTo
// - consumeFrom
// - queue

class RMQ {
    constructor() {
        this.initialize;
    }

    get initialize() {
        const self = this;

        const promises = [];

        if (!Object.keys(state.config).length) {
            promises.push(_.generateConfiguration());
        }

        return Promise.all(promises)
            .then(() => _.create())
    }

    get config() {
        return state.config;
    }

    get state() {
        return state;
    }

    get channel() {
        return _.channel();
    }

    get close() {
        return _.close();
    }

    publishTo(q, action, content, options) {
        return channel()
            .then(Channel => {
                const queue = state.config.queues.filter(arr => arr.name === q)[0].actions[action];

                const exchange = _.findExchange(queue.source);
                const buffer = _.contentToBuffer(content);

                const results = Channel.publish(exchange.key, queue.routingKey, buffer, options);

                // blocking loop
                while (!results) { console.info('broadcasting'); };

                if (!results) throw new Error(results);

                return results;
            })
            .catch(err => { throw new Error(err); });
    }

    consumeFrom(q, action, callback) {
        const queue = state.config.queues.filter(arr => arr.name === q)[0];

        return new Promise((resolve, reject) => {
            _.channel()
                .then(channel => {
                    channel.consume(`${queue.key}.${action}`, (msg) => callback(msg, channel));
                })
                .catch(err => reject(err));
        });
    }

    queue(q, action, content, options) {
        const queue = state.config.queues.filter(arr => arr.name = q)[0];

        return _.channel()
            .then(Channel => {
                return Channel.sendToQueue(`${queue.key}.${action}`, _.contentToBuffer(content), options);
            })
    }
}

module.exports = new RMQ();

// -------------------------------------

function contentToBuffer(content) {
    return (typeof content === 'object')
        ? new Buffer(JSON.stringify(content))
        : new Buffer(content);
}

function generateConfiguration() {
    return new Promise((resolve, reject) => {
        state.config = {
            protocol: (process.env.RABBITMQ_SSL_ENABLED) ? 'amqps://' : 'amqp://',
            user: process.env.RABBITMQ_DEFAULT_USER || null,
            pass: process.env.RABBITMQ_DEFAULT_PASS || null,
            host: process.env.RABBITMQ_HOST || null,
            port: process.env.RABBITMQ_PORT || 5672,
            adminPort: process.env.RABBITMQ_ADMIN_PORT || 15672,
            queues: [],
            exchanges: [],
            policies: [],
            upstreams: [],
        };

        state.config.url = `${state.config.protocol}${state.config.user}:${state.config.pass}@${state.config.host}`,

        Object.keys(rabbitConfig).reduce((acc, key) => {
            acc[key] = rabbitConfig[key];

            return acc;
        }, state.config);

        return resolve(state.config);
    });
}

function create() {
    const promises = [];

    if (!state.config) {
        promises.push(generateConfiguration());
    }

    return Promise.all(promises)
        .then(() => {
            if (!state.config) {
                throw new Error('No Configuration');
            }

            return;
        })
        .then(() => _.createQueues())
        .then(() => _.createExchanges())
        .then(() => _.createPolicies())
        .then(() => _.createUpstreams())
        .then(() => _.bindQueues())
        .then(() => _.createConsumers())
}

function channel() {
    return amqp.connect(state.config.url)
        .then(con => con.createChannel())
        .then(ch => state.channel = ch)
        .catch(err => { throw err; });
}

function createQueues() {
    return _.channel()
        .then(Channel => Promise.all(state.config.queues.reduce((acc, q) => {
            Object.keys(q.actions).forEach(action => {
                acc.concat([Channel.assertQueue(`${q.key}.${action}`, q.actions[action].options)]);
            });

            return acc;
        }, [Channel])))
}

function createExchanges() {
    return _.channel()
        .then(Channel => Promise.all(state.config.exchanges.reduce((acc, x) => {
            acc.concat([Channel.assertExchange(x.key, x.type, x.options)]);

            return acc;
        }, [Channel])))
}

function createPolicies() {
    const promises = state.config.policies.reduce((acc, p) => {
        acc.concat([createPolicy(p)]);
        return acc;
    }, []);

    return Promise.all(promises)

    function createPolicy(policy) {
        policy.vhost = policy.vhost || '/';

        const options = {
            method: 'PUT',
            path: `/api/policies/${encodeURIComponent(policy.vhost)}/${encodeURIComponent(policy.name)}`,
            auth: `${state.config.user}:${state.config.pass}`,
            hostname: `${state.config.host}`,
            port: state.config.adminPort,
            headers: {
                'Content-Type': 'application/json',
            },
        };

        return new Promise((resolve, reject) => {
            const req = http.request(options, res => resolve(res));

            req.on('error', err => reject(err));

            req.write(JSON.stringify(policy));

            req.end();
        });
    }
}

function createUpstreams() {
    return Promise.all(state.config.upstreams.reduce((acc, u) => {
        return acc.concat([_.createUpstream(u)]);
    }, []))

    function createUpstream(upstream) {
        upstream.vhost = upstream.vhost || '/';
        const path = `${encodeURIComponent(upstream.vhost)}/${encodeURIComponent(upstream.name)}`;

        const options = {
            method: 'PUT',
            path: `/api/parameters/federation-upstream/${path}`,
            auth: `${state.config.user}:${state.config.pass}`,
            hostname: `${state.config.host}`,
            port: state.config.adminPort,
            headers: {
                'Content-Type': 'application/json',
            },
        };

        return new Promise((resolve, reject) => {
            const req = http.request(options, res => resolve(res));
            req.on('error', err => reject(err));
            req.write(JSON.stringify(upstream));
            req.end();
        })
    }
}

function bindQueues() {
    return _.channel()
        .then(Channel => Promise.all(state.config.queues.reduce((acc, q) => {
            Object.keys(q.actions).forEach(action => {
                const queue = q.actions[action];

                const exchange = _.findExchange(queue.source);
                const queueAction = `${q.key}.${action}`;
                const routing = queue.pattern || queue.routingKey;

                if (exchange && !queue.noBind) {
                    acc.concat([
                        Channel.bindQueue(queueAction, exchange.key, routing),
                    ]);
                }
            });

            return acc;
        }, [Channel])))
}

function findExchange(name) {
    return state.config.exchanges.find(obj => obj.name === name);
}

function createConsumers() {
    return _.channel()
        .then(Channel => {
            state.config.queues.forEach(q => {
                Object.keys(q.actions).forEach(action => {
                    const queue = q.actions[action];

                    if (queue.consume && _.findExchange(queue.source)) {
                        Channel.consume(`${q.key}.${action}`, (msg) => queue.consume(msg, Channel));
                    }
                });
            });
        })
}

function close() {
    return Promise.resolve()
        .then(() => state.channel.close())
        .then(() => {
            state.channel = undefined
        });
}
<commit_msg>promised consuming, prevent race conditions<commit_after>const amqp = require('amqplib');
const http = require('http');
const rabbitConfig = require('rabbit-config.js');

const state = {
    connection: null,
    channel: null,
    config: {},
};

const _ = {
    contentToBuffer,
    generateConfiguration,
    create,
    // connection,
    channel,
    createQueues,
    createExchanges,
    createPolicies,
    createUpstreams,
    bindQueues,
    findExchange,
    createConsumers,
    close,
};

// API for interacting with Rabbit MQ
// ==================================
// Public APIs
// - initialize - shouldn't be called all the time only on reconnection
// - channel
// - publishTo
// - consumeFrom
// - queue

class RMQ {
    constructor() {
        this.initialize();
    }

    initialize() {
        const promises = [];

        if (!Object.keys(state.config).length) {
            promises.push(_.generateConfiguration());
        }

        return Promise.all(promises)
            .then(() => _.create());
    }

    get config() {
        return state.config;
    }

    get state() {
        return state;
    }

    get channel() {
        return _.channel();
    }

    get close() {
        return _.close();
    }

    publishTo(q, action, content, options) {
        return channel()
            .then(Channel => {
                const queue = state.config.queues.filter(arr => arr.name === q)[0].actions[action];

                const exchange = _.findExchange(queue.source);
                const buffer = _.contentToBuffer(content);

                const results = Channel.publish(exchange.key, queue.routingKey, buffer, options);

                // blocking loop
                while (!results) { console.info('broadcasting'); };

                if (!results) throw new Error(results);

                return results;
            })
            .catch(err => { throw new Error(err); });
    }

    /**
     * Wait for the queue to be created
     * @param q {String} Queue key
     * @param action {String} Queue action
     * @param opts {Object} An object that might carry options for channel.assertQueue
     * @returns {Promise}
     */
    assertQueue(q, action, opts = {}) {
        const queue = state.config.queues.filter(arr => arr.name === q)[0];

        if (!q) {
            return Promise.reject(`No queue ${q} with action ${action} found`);
        }

        return _.channel()
        .then(() => {
            return state.channel.assertQueue(`${queue.key}.${action}`, opts);
        });
    }

    /**
     * Set consuming callback to the queue that might not has been yet created
     * @param q {String} Queue key
     * @param action {String} Queue action
     * @param callback {Function} An object that might carry options for channel.assertQueue
     */
    consumeFromWaitQueue(q, action, callback) {
        this.assertQueue(q, action)
        .then(() => {
            this.consumeFrom(q, action, (msg, _channel) => {
                callback(msg, _channel);
            });
        })
        .catch((err) => { throw err; });
    }

    consumeFrom(q, action, callback) {
        const queue = state.config.queues.filter(arr => arr.name === q)[0];

        return new Promise((resolve, reject) => {
            _.channel()
                .then(channel => {
                    channel.consume(`${queue.key}.${action}`, (msg) => callback(msg, channel));
                })
                .catch(err => reject(err));
        });
    }

    queue(q, action, content, options) {
        const queue = state.config.queues.filter(arr => arr.name = q)[0];

        return _.channel()
            .then(Channel => {
                return Channel.sendToQueue(`${queue.key}.${action}`, _.contentToBuffer(content), options);
            });
    }
}

module.exports = new RMQ();

// -------------------------------------

function contentToBuffer(content) {
    return (typeof content === 'object')
        ? new Buffer(JSON.stringify(content))
        : new Buffer(content);
}

function generateConfiguration() {
    return new Promise((resolve, reject) => {
        state.config = {
            protocol: (process.env.RABBITMQ_SSL_ENABLED) ? 'amqps://' : 'amqp://',
            user: process.env.RABBITMQ_DEFAULT_USER || null,
            pass: process.env.RABBITMQ_DEFAULT_PASS || null,
            host: process.env.RABBITMQ_HOST || null,
            port: process.env.RABBITMQ_PORT || 5672,
            adminPort: process.env.RABBITMQ_ADMIN_PORT || 15672,
            queues: [],
            exchanges: [],
            policies: [],
            upstreams: [],
        };

        state.config.url = `${state.config.protocol}${state.config.user}:${state.config.pass}@${state.config.host}`;

        Object.keys(rabbitConfig).reduce((acc, key) => {
            acc[key] = rabbitConfig[key];

            return acc;
        }, state.config);

        return resolve(state.config);
    });
}

function create() {
    const promises = [];

    if (!state.config) {
        promises.push(generateConfiguration());
    }

    return Promise.all(promises)
        .then(() => {
            if (!state.config) {
                throw new Error('No Configuration');
            }

            return;
        })
        .then(() => _.createQueues())
        .then(() => _.createExchanges())
        .then(() => _.createPolicies())
        .then(() => _.createUpstreams())
        .then(() => _.bindQueues())
        .then(() => _.createConsumers())
}

function channel() {
    return amqp.connect(state.config.url)
        .then(con => con.createChannel())
        .then(ch => state.channel = ch)
        .catch(err => { throw err; });
}

function createQueues() {
    return _.channel()
        .then(Channel => Promise.all(state.config.queues.reduce((acc, q) => {
            Object.keys(q.actions).forEach(action => {
                acc.concat([Channel.assertQueue(`${q.key}.${action}`, q.actions[action].options)]);
            });

            return acc;
        }, [Channel])));
}

function createExchanges() {
    return _.channel()
        .then(Channel => Promise.all(state.config.exchanges.reduce((acc, x) => {
            acc.concat([Channel.assertExchange(x.key, x.type, x.options)]);

            return acc;
        }, [Channel])));
}

function createPolicies() {
    const promises = state.config.policies.reduce((acc, p) => {
        acc.concat([createPolicy(p)]);
        return acc;
    }, []);

    return Promise.all(promises);

    function createPolicy(policy) {
        policy.vhost = policy.vhost || '/';

        const options = {
            method: 'PUT',
            path: `/api/policies/${encodeURIComponent(policy.vhost)}/${encodeURIComponent(policy.name)}`,
            auth: `${state.config.user}:${state.config.pass}`,
            hostname: `${state.config.host}`,
            port: state.config.adminPort,
            headers: {
                'Content-Type': 'application/json',
            },
        };

        return new Promise((resolve, reject) => {
            const req = http.request(options, res => resolve(res));

            req.on('error', err => reject(err));

            req.write(JSON.stringify(policy));

            req.end();
        });
    }
}

function createUpstreams() {
    return Promise.all(state.config.upstreams.reduce((acc, u) => {
        return acc.concat([_.createUpstream(u)]);
    }, []));

    function createUpstream(upstream) {
        upstream.vhost = upstream.vhost || '/';
        const path = `${encodeURIComponent(upstream.vhost)}/${encodeURIComponent(upstream.name)}`;

        const options = {
            method: 'PUT',
            path: `/api/parameters/federation-upstream/${path}`,
            auth: `${state.config.user}:${state.config.pass}`,
            hostname: `${state.config.host}`,
            port: state.config.adminPort,
            headers: {
                'Content-Type': 'application/json',
            },
        };

        return new Promise((resolve, reject) => {
            const req = http.request(options, res => resolve(res));
            req.on('error', err => reject(err));
            req.write(JSON.stringify(upstream));
            req.end();
        });
    }
}

function bindQueues() {
    return _.channel()
        .then(Channel => Promise.all(state.config.queues.reduce((acc, q) => {
            Object.keys(q.actions).forEach(action => {
                const queue = q.actions[action];

                const exchange = _.findExchange(queue.source);
                const queueAction = `${q.key}.${action}`;
                const routing = queue.pattern || queue.routingKey;

                if (exchange && !queue.noBind) {
                    acc.concat([
                        Channel.bindQueue(queueAction, exchange.key, routing),
                    ]);
                }
            });

            return acc;
        }, [Channel])));
}

function findExchange(name) {
    return state.config.exchanges.find(obj => obj.name === name);
}

function createConsumers() {
    return _.channel()
        .then(Channel => {
            state.config.queues.forEach(q => {
                Object.keys(q.actions).forEach(action => {
                    const queue = q.actions[action];

                    if (queue.consume && _.findExchange(queue.source)) {
                        Channel.consume(`${q.key}.${action}`, (msg) => queue.consume(msg, Channel));
                    }
                });
            });
        });
}

function close() {
    return Promise.resolve()
        .then(() => { return state.channel ? state.channel.close() : Promise.resolve(); })
        .then(() => {
            state.channel = undefined;
        });
}
<|endoftext|>


<commit_before>var fetch = fetch || require('node-fetch')

function jsref(ob, opts={}) {
  if (typeof ob !== 'object') return ob
  var $ref = opts.$ref || '$ref', refs = opts.refs || {}, root = 'http://localhost/', vals = []
  var find = url => fetch(url.indexOf('http') ? (opts.root||root)+url : url, opts.http).then(res => res.json())

  function extRef(url) {
    var [url,ref] = url.split('#')
    ref = (ref && ref.length) ? ref : opts.frag
    var rec = (opts.find||find)(url).then(rec => ref ? setRef('#'+ref,rec) : rec)
    return opts.deep ? rec.then(getRef) : rec
  }

  function setRef(ref, val=ob) {
    if (ref[0] != '#') return opts.lazy ? extRef(ref) : vals.push(extRef(ref))
    var keys = ref.substr(1).split(/[\.\/]/)
    if (!keys[0].length) keys.shift()
    while(val && keys.length) val = val[keys.shift()]
    return val
  }

  function getRef(ob) {
    if (ob && ob[$ref] && (!opts.like || RegExp(opts.like).test(ob[$ref]))) {
      if (!refs[ob[$ref]]) refs[ob[$ref]] = setRef(ob[$ref])
    } else for (var i in ob) if (typeof ob[i] === 'object') getRef(ob[i])
    return ob
  }

  function fixRef(ob) {
    if (ob && ob[$ref]) return fixRef(refs[ob[$ref]]) || ob
    for (var k in ob) if (typeof ob[k] === 'object') ob[k] = fixRef(ob[k])
    return ob
  }

  getRef(ob)

  return opts.lazy ? Promise.resolve(fixRef(ob)) : Promise.all(vals).then(recs => {
    for (var r in refs) if (!isNaN(refs[r])) refs[r] = recs[refs[r]-1]
    return fixRef(ob)
  })
}

if (typeof module == 'object') module.exports = jsref<commit_msg>format<commit_after>var fetch = fetch || require('node-fetch')

function jsref(ob, opts={}) {
  if (typeof ob !== 'object') return ob
  var $ref = opts.$ref||'$ref', refs = opts.refs||{}, root = opts.root||'http://localhost/', vals = []
  var find = url => fetch(url.indexOf('http') ? root+url : url, opts.http).then(res => res.json())

  function extRef(url) {
    var [url,ref] = url.split('#')
    ref = (ref && ref.length) ? ref : opts.frag
    var rec = (opts.find||find)(url).then(rec => ref ? setRef('#'+ref,rec) : rec)
    return opts.deep ? rec.then(getRef) : rec
  }

  function setRef(ref, val=ob) {
    if (ref[0] != '#') return opts.lazy ? extRef(ref) : vals.push(extRef(ref))
    var keys = ref.substr(1).split(/[\.\/]/)
    if (!keys[0].length) keys.shift()
    while(val && keys.length) val = val[keys.shift()]
    return val
  }

  function getRef(ob) {
    if (ob && ob[$ref] && (!opts.like || RegExp(opts.like).test(ob[$ref]))) {
      if (!refs[ob[$ref]]) refs[ob[$ref]] = setRef(ob[$ref])
    } else for (var i in ob) if (typeof ob[i] === 'object') getRef(ob[i])
    return ob
  }

  function fixRef(ob) {
    if (ob && ob[$ref]) return fixRef(refs[ob[$ref]]) || ob
    for (var k in ob) if (typeof ob[k] === 'object') ob[k] = fixRef(ob[k])
    return ob
  }

  getRef(ob)

  return opts.lazy ? Promise.resolve(fixRef(ob)) : Promise.all(vals).then(recs => {
    for (var r in refs) if (!isNaN(refs[r])) refs[r] = recs[refs[r]-1]
    return fixRef(ob)
  })
}

if (typeof module == 'object') module.exports = jsref<|endoftext|>


<commit_before>var path = require('path');

var pattern = function(file) {
  return {pattern: file, included: true, served: true, watched: false};
};

var framework = function(files) {
  files.unshift(pattern(path.join(__dirname, 'adapter.coffee')));
  files.unshift(pattern(path.join(__dirname, 'node_modules/chai/chai.js')));
};

framework.$inject = ['config.files'];
module.exports = {'framework:chai': ['factory', framework]};<commit_msg>No coffee<commit_after>var path = require('path');

var pattern = function(file) {
  return {pattern: file, included: true, served: true, watched: false};
};

var framework = function(files) {
  files.unshift(pattern(path.join(__dirname, 'adapter.js')));
  files.unshift(pattern(path.join(__dirname, 'node_modules/chai/chai.js')));
};

framework.$inject = ['config.files'];
module.exports = {'framework:chai': ['factory', framework]};<|endoftext|>


<commit_before>'use strict';

var winston = require.main.require('winston');
var async = require.main.require('async');
var nconf = require.main.require('nconf');
var url = require.main.require('url');
var Meta = require.main.require('./src/meta');
var Posts = require.main.require('./src/posts');
var Topics = require.main.require('./src/topics');
var Privileges = require.main.require('./src/privileges');
var Plugins = require.main.require('./src/plugins');
var SocketHelpers = require.main.require('./src/socket.io/helpers');
var User = require.main.require('./src/user');
var hostEmailer = require.main.require('./src/emailer');
var SendGrid;
var Emailer = {};

Emailer.hostname = url.parse(nconf.get('url')).hostname;
Emailer.receiptRegex = new RegExp('^reply-([\\d]+)@' + Emailer.hostname + '$');

Emailer.init = function (data, callback) {
	var render = function (req, res) {
		var destinationURL = nconf.get('url') + '/plugins/emailer-sendgrid/webhook';
		res.render('admin/plugins/emailer-sendgrid', { destinationURL: destinationURL });
	};

	Meta.settings.get('sendgrid', function (err, settings) {
		if (!err && settings && settings.apiKey) {
			SendGrid = require('@sendgrid/mail');
			SendGrid.setApiKey(settings.apiKey);
		} else {
			winston.error('[plugins/emailer-sendgrid] API key not set!');
		}

		var multipart = module.parent.require('connect-multiparty');
		var multipartMiddleware = multipart();

		data.router.get('/admin/plugins/emailer-sendgrid', data.middleware.admin.buildHeader, render);
		data.router.get('/api/admin/plugins/emailer-sendgrid', render);
		data.router.post('/plugins/emailer-sendgrid/webhook', multipartMiddleware, Emailer.receive);

		if (typeof callback === 'function') {
			callback();
		}
	});
};

Emailer.receive = function (req, res) {
	Plugins.fireHook('filter:plugins.emailer.receive', {
		req: req,
		res: res,
		service: 'sendgrid',
	}, function (err, data) {
		if (err) {
			Emailer.handleError(err, data.req.body);
			return res.sendStatus(200);
		}

		async.waterfall([
			async.apply(Emailer.verifyEvent, data.req.body),
			Emailer.resolveUserOrGuest,
			Emailer.processEvent,
			Emailer.notifyUsers,
		], function (err, eventObj) {
			if (err) {
				Emailer.handleError(err, eventObj);
			}

			res.sendStatus(200);
		});
	});
};

Emailer.verifyEvent = function (eventObj, next) {
	var pid = eventObj.to.match(Emailer.receiptRegex);

	if (pid && pid.length && pid[1]) {
		pid = pid[1];
		eventObj.pid = pid;
		Posts.getPostField(pid, 'tid', function (err, tid) {
			if (!err && tid) {
				eventObj.tid = tid;
				next(null, eventObj);
			} else {
				if (!tid) { winston.warn('[emailer.sendgrid.verifyEvent] Could not retrieve tid'); }
				next(new Error('invalid-data'));
			}
		});
	} else {
		winston.warn('[emailer.sendgrid.verifyEvent] Could not locate post id');
		next(new Error('invalid-data'), eventObj);
	}
};

Emailer.resolveUserOrGuest = function (eventObj, callback) {
// This method takes the event object, reads the sender email and resolves it to a uid
// if the email is set in the system. If not, and guest posting is enabled, the email
// is treated as a guest instead.
	var envelope = JSON.parse(eventObj.envelope);
	User.getUidByEmail(envelope.from, function (err, uid) {
		if (err) {
			return callback(err);
		}

		if (uid) {
			eventObj.uid = uid;
			callback(null, eventObj);
		} else {
			// See if guests can post to the category in question
			async.waterfall([
				async.apply(Topics.getTopicField, eventObj.tid, 'cid'),
				function (cid, next) {
					Privileges.categories.groupPrivileges(cid, 'guests', next);
				},
			], function (err, privileges) {
				if (err) {
					return callback(privileges);
				}

				if (privileges['groups:topics:reply']) {
					eventObj.uid = 0;

					if (parseInt(Meta.config.allowGuestHandles, 10) === 1) {
						if (eventObj.msg.from_name && eventObj.msg.from_name.length) {
							eventObj.handle = eventObj.msg.from_name;
						} else {
							eventObj.handle = eventObj.msg.from_email;
						}
					}

					callback(null, eventObj);
				} else {
					// Guests can't post here
					winston.verbose('[emailer.sendgrid] Received reply by guest to pid ' + eventObj.pid + ', but guests are not allowed to post here.');
					callback(new Error('[[error:no-privileges]]'));
				}
			});
		}
	});
};

Emailer.processEvent = function (eventObj, callback) {
	winston.verbose('[emailer.sendgrid] Processing incoming email reply by uid ' + eventObj.uid + ' to pid ' + eventObj.pid);
	Topics.reply({
		uid: eventObj.uid,
		toPid: eventObj.pid,
		tid: eventObj.tid,
		content: require('node-email-reply-parser')(eventObj.text, true),
		handle: (eventObj.uid === 0 && eventObj.hasOwnProperty('handle') ? eventObj.handle : undefined),
	}, callback);
};

Emailer.notifyUsers = function (postData, next) {
	var result = {
		posts: [postData],
		privileges: {
			'topics:reply': true,
		},
		'reputation:disabled': parseInt(Meta.config['reputation:disabled'], 10) === 1,
		'downvote:disabled': parseInt(Meta.config['downvote:disabled'], 10) === 1,
	};

	SocketHelpers.notifyOnlineUsers(parseInt(postData.uid, 10), result);
	next();
};

Emailer.send = function (data, callback) {
	if (SendGrid) {
		Meta.settings.get('sendgrid', function (err, settings) {
			if (err) {
				return callback(err);
			}

			data.headers = data.headers || {};	// pre core v1.10.2

			async.waterfall([
				function (next) {
					if (data.fromUid) {
						next(null, data.fromUid);
					} else if (data._raw.notification && data._raw.notification.pid) {
						Posts.getPostField(data._raw.notification.pid, 'uid', next);
					} else {
						next(null, false);
					}
				},
				function (uid, next) {
					if (uid === false) { return next(null, {}); }

					User.getSettings(uid, function (err, settings) {
						if (err) {
							return next(err);
						}

						if (settings.showemail) {
							User.getUserFields(parseInt(uid, 10), ['email', 'username'], function (err, userData) {
								if (err) {
									return next(err);
								}

								next(null, userData);
							});
						} else {
							User.getUserFields(parseInt(uid, 10), ['username'], function (err, userData) {
								if (err) {
									return next(err);
								}

								next(null, userData);
							});
						}
					});
				},
				function (userData, next) {
					let replyTo;
					if (data._raw.notification && data._raw.notification.pid && settings.inbound_enabled === 'on') {
						replyTo = 'reply-' + data._raw.notification.pid + '@' + Emailer.hostname;
					}

					SendGrid.send({
						to: data.to,
						toname: data.toName,
						subject: data.subject,
						from: data.from,
						fromname: data.from_name || userData.username || undefined,
						text: data.text,
						html: data.html,
						headers: data.headers,
						reply_to: replyTo,
					}, next);
				},
			], function (err) {
				if (!err) {
					winston.verbose('[emailer.sendgrid] Sent `' + data.template + '` email to uid ' + data.uid);
					callback(null, data);
				} else {
					winston.warn('[emailer.sendgrid] Unable to send `' + data.template + '` email to uid ' + data.uid + '!!');
					winston.warn('[emailer.sendgrid] Error Stringified:' + JSON.stringify(err));
					callback(err);
				}
			});
		});
	} else {
		winston.warn('[plugins/emailer-sendgrid] API user and key not set, not sending email as SendGrid object is not instantiated.');
		callback(null, data);
	}
};

Emailer.handleError = function (err, eventObj) {
	var envelope = JSON.parse(eventObj.envelope);

	if (err) {
		switch (err.message) {
		case '[[error:no-privileges]]':
		case 'invalid-data':
			// Bounce a return back to sender
			hostEmailer.sendToEmail('bounce', envelope.from, Meta.config.defaultLang || 'en-GB', {
				site_title: Meta.config.title || 'NodeBB',
				subject: 'Re: ' + eventObj.subject,
				messageBody: eventObj.html,
			}, function (err) {
				if (err) {
					winston.error('[emailer.sendgrid] Unable to bounce email back to sender! ' + err.message);
				} else {
					winston.verbose('[emailer.sendgrid] Bounced email back to sender (' + envelope.from + ')');
				}
			});
			break;
		}
	}
};

Emailer.admin = {
	menu: function (custom_header, callback) {
		custom_header.plugins.push({
			route: '/plugins/emailer-sendgrid',
			icon: 'fa-envelope-o',
			name: 'Emailer (SendGrid)',
		});

		callback(null, custom_header);
	},
};

module.exports = Emailer;
<commit_msg>fix: from name properly<commit_after>'use strict';

var winston = require.main.require('winston');
var async = require.main.require('async');
var nconf = require.main.require('nconf');
var url = require.main.require('url');
var Meta = require.main.require('./src/meta');
var Posts = require.main.require('./src/posts');
var Topics = require.main.require('./src/topics');
var Privileges = require.main.require('./src/privileges');
var Plugins = require.main.require('./src/plugins');
var SocketHelpers = require.main.require('./src/socket.io/helpers');
var User = require.main.require('./src/user');
var hostEmailer = require.main.require('./src/emailer');
var SendGrid;
var Emailer = {};

Emailer.hostname = url.parse(nconf.get('url')).hostname;
Emailer.receiptRegex = new RegExp('^reply-([\\d]+)@' + Emailer.hostname + '$');

Emailer.init = function (data, callback) {
	var render = function (req, res) {
		var destinationURL = nconf.get('url') + '/plugins/emailer-sendgrid/webhook';
		res.render('admin/plugins/emailer-sendgrid', { destinationURL: destinationURL });
	};

	Meta.settings.get('sendgrid', function (err, settings) {
		if (!err && settings && settings.apiKey) {
			SendGrid = require('@sendgrid/mail');
			SendGrid.setApiKey(settings.apiKey);
		} else {
			winston.error('[plugins/emailer-sendgrid] API key not set!');
		}

		var multipart = module.parent.require('connect-multiparty');
		var multipartMiddleware = multipart();

		data.router.get('/admin/plugins/emailer-sendgrid', data.middleware.admin.buildHeader, render);
		data.router.get('/api/admin/plugins/emailer-sendgrid', render);
		data.router.post('/plugins/emailer-sendgrid/webhook', multipartMiddleware, Emailer.receive);

		if (typeof callback === 'function') {
			callback();
		}
	});
};

Emailer.receive = function (req, res) {
	Plugins.fireHook('filter:plugins.emailer.receive', {
		req: req,
		res: res,
		service: 'sendgrid',
	}, function (err, data) {
		if (err) {
			Emailer.handleError(err, data.req.body);
			return res.sendStatus(200);
		}

		async.waterfall([
			async.apply(Emailer.verifyEvent, data.req.body),
			Emailer.resolveUserOrGuest,
			Emailer.processEvent,
			Emailer.notifyUsers,
		], function (err, eventObj) {
			if (err) {
				Emailer.handleError(err, eventObj);
			}

			res.sendStatus(200);
		});
	});
};

Emailer.verifyEvent = function (eventObj, next) {
	var pid = eventObj.to.match(Emailer.receiptRegex);

	if (pid && pid.length && pid[1]) {
		pid = pid[1];
		eventObj.pid = pid;
		Posts.getPostField(pid, 'tid', function (err, tid) {
			if (!err && tid) {
				eventObj.tid = tid;
				next(null, eventObj);
			} else {
				if (!tid) { winston.warn('[emailer.sendgrid.verifyEvent] Could not retrieve tid'); }
				next(new Error('invalid-data'));
			}
		});
	} else {
		winston.warn('[emailer.sendgrid.verifyEvent] Could not locate post id');
		next(new Error('invalid-data'), eventObj);
	}
};

Emailer.resolveUserOrGuest = function (eventObj, callback) {
// This method takes the event object, reads the sender email and resolves it to a uid
// if the email is set in the system. If not, and guest posting is enabled, the email
// is treated as a guest instead.
	var envelope = JSON.parse(eventObj.envelope);
	User.getUidByEmail(envelope.from, function (err, uid) {
		if (err) {
			return callback(err);
		}

		if (uid) {
			eventObj.uid = uid;
			callback(null, eventObj);
		} else {
			// See if guests can post to the category in question
			async.waterfall([
				async.apply(Topics.getTopicField, eventObj.tid, 'cid'),
				function (cid, next) {
					Privileges.categories.groupPrivileges(cid, 'guests', next);
				},
			], function (err, privileges) {
				if (err) {
					return callback(privileges);
				}

				if (privileges['groups:topics:reply']) {
					eventObj.uid = 0;

					if (parseInt(Meta.config.allowGuestHandles, 10) === 1) {
						if (eventObj.msg.from_name && eventObj.msg.from_name.length) {
							eventObj.handle = eventObj.msg.from_name;
						} else {
							eventObj.handle = eventObj.msg.from_email;
						}
					}

					callback(null, eventObj);
				} else {
					// Guests can't post here
					winston.verbose('[emailer.sendgrid] Received reply by guest to pid ' + eventObj.pid + ', but guests are not allowed to post here.');
					callback(new Error('[[error:no-privileges]]'));
				}
			});
		}
	});
};

Emailer.processEvent = function (eventObj, callback) {
	winston.verbose('[emailer.sendgrid] Processing incoming email reply by uid ' + eventObj.uid + ' to pid ' + eventObj.pid);
	Topics.reply({
		uid: eventObj.uid,
		toPid: eventObj.pid,
		tid: eventObj.tid,
		content: require('node-email-reply-parser')(eventObj.text, true),
		handle: (eventObj.uid === 0 && eventObj.hasOwnProperty('handle') ? eventObj.handle : undefined),
	}, callback);
};

Emailer.notifyUsers = function (postData, next) {
	var result = {
		posts: [postData],
		privileges: {
			'topics:reply': true,
		},
		'reputation:disabled': parseInt(Meta.config['reputation:disabled'], 10) === 1,
		'downvote:disabled': parseInt(Meta.config['downvote:disabled'], 10) === 1,
	};

	SocketHelpers.notifyOnlineUsers(parseInt(postData.uid, 10), result);
	next();
};

Emailer.send = function (data, callback) {
	if (SendGrid) {
		Meta.settings.get('sendgrid', function (err, settings) {
			if (err) {
				return callback(err);
			}

			data.headers = data.headers || {};	// pre core v1.10.2

			async.waterfall([
				function (next) {
					if (data.fromUid) {
						next(null, data.fromUid);
					} else if (data._raw.notification && data._raw.notification.pid) {
						Posts.getPostField(data._raw.notification.pid, 'uid', next);
					} else {
						next(null, false);
					}
				},
				function (uid, next) {
					if (uid === false) { return next(null, {}); }

					User.getSettings(uid, function (err, settings) {
						if (err) {
							return next(err);
						}

						if (settings.showemail) {
							User.getUserFields(parseInt(uid, 10), ['email', 'username'], function (err, userData) {
								if (err) {
									return next(err);
								}

								next(null, userData);
							});
						} else {
							User.getUserFields(parseInt(uid, 10), ['username'], function (err, userData) {
								if (err) {
									return next(err);
								}

								next(null, userData);
							});
						}
					});
				},
				function (userData, next) {
					let replyTo;
					if (data._raw.notification && data._raw.notification.pid && settings.inbound_enabled === 'on') {
						replyTo = 'reply-' + data._raw.notification.pid + '@' + Emailer.hostname;
					}
					let from = data.from;
					if (data.from_name || userData.username) {
						from = (data.from_name || userData.username) + ' <' + data.from + '>';
					}
					SendGrid.send({
						to: data.to,
						toname: data.toName,
						subject: data.subject,
						from: from,
						text: data.text,
						html: data.html,
						headers: data.headers,
						reply_to: replyTo,
					}, next);
				},
			], function (err) {
				if (!err) {
					winston.verbose('[emailer.sendgrid] Sent `' + data.template + '` email to uid ' + data.uid);
					callback(null, data);
				} else {
					winston.warn('[emailer.sendgrid] Unable to send `' + data.template + '` email to uid ' + data.uid + '!!');
					winston.warn('[emailer.sendgrid] Error Stringified:' + JSON.stringify(err));
					callback(err);
				}
			});
		});
	} else {
		winston.warn('[plugins/emailer-sendgrid] API user and key not set, not sending email as SendGrid object is not instantiated.');
		callback(null, data);
	}
};

Emailer.handleError = function (err, eventObj) {
	var envelope = JSON.parse(eventObj.envelope);

	if (err) {
		switch (err.message) {
		case '[[error:no-privileges]]':
		case 'invalid-data':
			// Bounce a return back to sender
			hostEmailer.sendToEmail('bounce', envelope.from, Meta.config.defaultLang || 'en-GB', {
				site_title: Meta.config.title || 'NodeBB',
				subject: 'Re: ' + eventObj.subject,
				messageBody: eventObj.html,
			}, function (err) {
				if (err) {
					winston.error('[emailer.sendgrid] Unable to bounce email back to sender! ' + err.message);
				} else {
					winston.verbose('[emailer.sendgrid] Bounced email back to sender (' + envelope.from + ')');
				}
			});
			break;
		}
	}
};

Emailer.admin = {
	menu: function (custom_header, callback) {
		custom_header.plugins.push({
			route: '/plugins/emailer-sendgrid',
			icon: 'fa-envelope-o',
			name: 'Emailer (SendGrid)',
		});

		callback(null, custom_header);
	},
};

module.exports = Emailer;
<|endoftext|>


<commit_before>var router = require('ramrod')(),
  http = require('http'),
  couchdb = require('felix-couchdb'),
  redwahlib = require('./lib/redwah.js'),
  client = couchdb.createClient(),
  db = client.db('redwah'),
  redwah = {
    version: "0.0.1"
  };

router.on('postlist|post', function (req, res) {
  redwahlib.processPost(req, function (err, params) {
    if (err) {
      res.writeHead(err);
      res.end(JSON.stringify(params));
    } else {
      var listDocument = {
        "name": params.name,
        "items": [],
        "createdAt": new Date().getTime(),
        "lastUpdated": new Date().getTime()
      };
      console.log('got post request');
      db.saveDoc(listDocument, function (err, doc) {
        res.writeHead(201);
        res.end(JSON.stringify(doc));
      });
    }
  });
});

router.on('getlist|get', function (req, res, params) {
  res.writeHead(200);
  db.getDoc(params.id, function (err, doc) {
    if (err) {
      res.writeHead(404);
      res.end(JSON.stringify({ "error": "Unable to locate resource."}));
    } else {
      res.writeHead(200);
      res.end(JSON.stringify(doc));
    }
  });
});

router.on('*', function (req, res) {
  res.writeHead(200);
  res.end(JSON.stringify(redwah));
});

// Enumerate routes

['list', 'item'].forEach(function (obj) {
  ['post', 'get', 'put', 'del'].forEach(function (method) {
    router[method](obj, method + obj);
  });
});

db.exists(function (err, dbExists) {
  if (!dbExists) {
    console.log('db does not exist');
    db.create(function (err) {
      if (err) { throw new Error (JSON.stringify(err)); }
      console.log('redwah db created');
    });
  }
});

http.createServer(function (req, res) {
  router.dispatch(req, res);
}).listen(3000);
<commit_msg>removed unnecessary console.log<commit_after>var router = require('ramrod')(),
  http = require('http'),
  couchdb = require('felix-couchdb'),
  redwahlib = require('./lib/redwah.js'),
  client = couchdb.createClient(),
  db = client.db('redwah'),
  redwah = {
    version: "0.0.1"
  };

router.on('postlist|post', function (req, res) {
  redwahlib.processPost(req, function (err, params) {
    if (err) {
      res.writeHead(err);
      res.end(JSON.stringify(params));
    } else {
      var listDocument = {
        "name": params.name,
        "items": [],
        "createdAt": new Date().getTime(),
        "lastUpdated": new Date().getTime()
      };
      db.saveDoc(listDocument, function (err, doc) {
        res.writeHead(201);
        res.end(JSON.stringify(doc));
      });
    }
  });
});

router.on('getlist|get', function (req, res, params) {
  res.writeHead(200);
  db.getDoc(params.id, function (err, doc) {
    if (err) {
      res.writeHead(404);
      res.end(JSON.stringify({ "error": "Unable to locate resource."}));
    } else {
      res.writeHead(200);
      res.end(JSON.stringify(doc));
    }
  });
});

router.on('*', function (req, res) {
  res.writeHead(200);
  res.end(JSON.stringify(redwah));
});

// Enumerate routes

['list', 'item'].forEach(function (obj) {
  ['post', 'get', 'put', 'del'].forEach(function (method) {
    router[method](obj, method + obj);
  });
});

db.exists(function (err, dbExists) {
  if (!dbExists) {
    console.log('db does not exist');
    db.create(function (err) {
      if (err) { throw new Error (JSON.stringify(err)); }
      console.log('redwah db created');
    });
  }
});

http.createServer(function (req, res) {
  router.dispatch(req, res);
}).listen(3000);
<|endoftext|>


<commit_before>'use strict';

/**
 * Underverse is backlog state manager. The items in the backlog can have
 * various of states:

 * - undefined: This items is not fetched or received yet.
 * - 0: The item is currently beeing fetched.
 * - 1: The item is fetched
 *
 * The underverse tells you when your id's are out of sync and if there are
 * messages to be fetched. It assumes that your ids are numbers and are issued
 * in order.
 *
 * @constructor
 * @param {Number} size The size of the backlog
 * @api public
 */
function Underverse(size) {
  if (!(this instanceof Underverse)) return new Underverse(size);

  this.size = size || 10000;          // The size of the backlog
  this.ring = new Array(this.size);   // The ring we are going to abuse
  this.cursor = -1;                   // Current position of the cursor
}

Underverse.prototype.__proto__ = require('events').EventEmitter.prototype;

/**
 * A new message is recieved, mark the position of the ring as fetched.
 *
 * @param {Number} id
 * @returns {Boolean} The message was in order.
 * @api public
 */
Underverse.prototype.received = function received(id) {
  if (id > this.size) return false;

  this.ring[id] = 1;

  //
  // Check if the message was successor of our previous received message.
  //
  if (this.next(id)) {
    this.cursor = id;
    return true;
  }

  //
  // Find all the missing items between the received id and the current cursor
  // position.
  //
  var underverse = this
    , missing;

  missing = this.slice(this.cursor + 1, id).filter(function filter(position) {
    return this.ring[position] === undefined;
  }, this);

  //
  // There aren't items missing, so everything is probably still being fetched.
  //
  if (!missing.length) return false;

  this.emit('fetch', missing, function fetching(complete) {
    var state = complete ? 1 : 0;

    missing.forEach(function missing(position) {
      this.ring[position] = state;
    }, this);
  }.bind(this));

  return false;
};

/**
 * Check if the received messages was is the successor of our previous message.
 *
 * @param {Number} id Message id or index of the backlog
 * @returns {Boolean}
 * @api private
 */
Underverse.prototype.next = function next(id) {
  var overflowing = this.cursor === this.size
    , overflown = overflowing && id === 0;

  //
  // The backlog has overflown as it reached it maxed capacity and the backlog
  // cursor has been reset to 0
  //
  if (overflown) this.overflow();

  return overflown || id - 1 === this.cursor;
};

/**
 * The ring has reached it's starting point again.
 *
 * @api private
 */
Underverse.prototype.overflow = function overflow() {
  this.ring = new Array(this.size);
};

/**
 * Set the initial position of the cursor.
 *
 * @param {Number} cursor
 * @api public
 */
Underverse.prototype.initialize = function initialize(cursor) {
  this.cursor = +cursor;
};

/**
 * Get a slice of the ring.
 *
 * @param {Number} start The first item that should be sliced of
 * @param {Nunber} until Until this item is reached.
 * @returns {Array}
 * @api private
 */
Underverse.prototype.slice = function slice(start, end) {
  if (start > this.size || start < 0) start = 0;
  if (end > this.size || end < 0) end = 0;

  var cursor = start
    , sliced = [];

  //
  // The values are the same return nothing.
  //
  if (end === start) return sliced;

  while (cursor !== end) {
    sliced.push(cursor);

    cursor = cursor + 1;
    if (cursor > this.size) cursor = 0;
  }

  return sliced;
};

//
// Expose the module
//
module.exports = Underverse;
<commit_msg>[minor] Always return false if we are not yet initialized [minor] The `cursor` method should fill the gap and set it to 1; [minor] Internals renaming<commit_after>'use strict';

/**
 * Underverse is backlog state manager. The items in the backlog can have
 * various of states:

 * - undefined: This items is not fetched or received yet.
 * - 0: The item is currently beeing fetched.
 * - 1: The item is fetched
 *
 * The underverse tells you when your id's are out of sync and if there are
 * messages to be fetched. It assumes that your ids are numbers and are issued
 * in order.
 *
 * @constructor
 * @param {Number} size The size of the backlog
 * @param {Number} cursor Initial start position
 * @api public
 */
function Underverse(size, cursor) {
  if (!(this instanceof Underverse)) return new Underverse(size);

  this.size = size || 10000;            // The size of the backlog.
  this.ring = new Array(this.size);     // The ring we are going to abuse.
  this.position = isNaN(+cursor)        // Current position of the cursor.
    ? 'inactive'
    : +cursor;
}

Underverse.prototype.__proto__ = require('events').EventEmitter.prototype;

/**
 * A new message is recieved, mark the position of the ring as fetched.
 *
 * @param {Number} id
 * @returns {Boolean} The message was in order or should be queued.
 * @api public
 */
Underverse.prototype.received = function received(id) {
  if (id > this.size) return false;
  this.ring[id] = 1;

  //
  // The cursor position hasn't been set yet.
  //
  if (this.position === 'inactive') return false;

  //
  // Check if the message was successor of our previous received message.
  //
  if (this.next(id)) {
    this.position = id;
    return true;
  }

  //
  // Find all the missing items between the received id and the current cursor
  // position.
  //
  var underverse = this
    , missing;

  missing = this.slice(this.position + 1, id).filter(function filter(position) {
    return this.ring[position] === undefined;
  }, this);

  //
  // There aren't items missing, so everything is probably still being fetched.
  //
  if (!missing.length) return false;

  this.emit('fetch', missing, function fetching(complete) {
    var state = complete ? 1 : 0;

    missing.forEach(function missing(position) {
      this.ring[position] = state;
    }, this);
  }.bind(this));

  return false;
};

/**
 * Check if the received messages was is the successor of our previous message.
 *
 * @param {Number} id Message id or index of the backlog
 * @returns {Boolean}
 * @api private
 */
Underverse.prototype.next = function next(id) {
  var overflowing = this.position === this.size
    , overflown = overflowing && id === 0;

  //
  // The backlog has overflown as it reached it maxed capacity and the backlog
  // cursor has been reset to 0
  //
  if (overflown) this.overflow();

  return overflown || id - 1 === this.position;
};

/**
 * The ring has reached it's starting point again.
 *
 * @api private
 */
Underverse.prototype.overflow = function overflow() {
  this.ring = new Array(this.size);
};

/**
 * Set the initial position of the cursor.
 *
 * @param {Number} id
 * @api public
 */
Underverse.prototype.start = Underverse.prototype.cursor = function initialize(id) {
  this.position = +id;

  this.slice(0, this.position).forEach(function mark(cursor) {
    this.ring[cursor] = 1;
  }, this);
};

/**
 * Get a slice of the ring.
 *
 * @param {Number} start The first item that should be sliced of
 * @param {Nunber} until Until this item is reached.
 * @returns {Array}
 * @api private
 */
Underverse.prototype.slice = function slice(start, end) {
  if (start > this.size || start < 0) start = 0;
  if (end > this.size || end < 0) end = 0;

  var cursor = start
    , sliced = [];

  //
  // The values are the same return nothing.
  //
  if (end === start) return sliced;

  while (cursor !== end) {
    sliced.push(cursor);

    cursor = cursor + 1;
    if (cursor > this.size) cursor = 0;
  }

  return sliced;
};

//
// Expose the module
//
module.exports = Underverse;
<|endoftext|>


<commit_before>const q = require('q')
const fs = require('fs')
const path = require('path')
const async = require('async')
const appDir = process.env.PWD + '/'

//Imports
const math = require('./lib/math.js')
const ocr = require('./lib/ocr.js')
const user = require('./lib/user.js')
const utils = require('./lib/utils.js')
const api = require('./api/main.js')

//Exports
module.exports = {
  api: api,
  math: math,
  ocr: ocr,
  utils: utils,
  user: user
}
<commit_msg>Change initialization process<commit_after>const q = require('q')
const fs = require('fs')
const path = require('path')
const async = require('async')
const appDir = process.env.PWD + '/'

const db = require('./lib/mongoose.js')()
module.exports.db = db

const math = require('./lib/math.js')
module.exports.math = math

const ocr = require('./lib/ocr.js')
module.exports.ocr = ocr

const user = require('./lib/user.js')
module.exports.user = user

const utils = require('./lib/utils.js')
module.exports.utils = utils

const api = require('./api/main.js')
module.exports.api = api
<|endoftext|>


<commit_before>/* eslint-env node */
'use strict';

function debugMacros(features) {
  let plugins = [
    [
      require.resolve('babel-plugin-debug-macros'),
      {
        flags: [
          {
            source: 'ember-m3/feature-flags',
            flags: features,
          },
        ],
      },
      '@ember-data/canary-features-stripping',
    ],
  ];

  return plugins;
}

module.exports = {
  name: 'ember-m3',

  init() {
    this._super.init.apply(this, arguments);

    let features;
    try {
      features = this.project.require('@ember-data/private-build-infra/src/features');
    } catch (e) {
      features = { CUSTOM_MODEL_CLASS: false };
    }

    this.options = this.options || {};
    this.options.babel = this.options.babel || {};
    // this ensures that the same `@ember-data/canary-features` processing that the various
    // ember-data addons do is done in the dummy app
    this.options.babel.plugins = [...debugMacros(features)];

    this.options.babel.loose = true;
  },
};
<commit_msg>Fix canary feature imports (#459)<commit_after>/* eslint-env node */
'use strict';

function debugMacros(features) {
  let plugins = [
    [
      require.resolve('babel-plugin-debug-macros'),
      {
        flags: [
          {
            source: 'ember-m3/feature-flags',
            flags: features,
          },
        ],
      },
      '@ember-data/canary-features-stripping',
    ],
  ];

  return plugins;
}

module.exports = {
  name: 'ember-m3',

  init() {
    this._super.init.apply(this, arguments);

    let features;
    try {
      features = this.project.require('@ember-data/private-build-infra/src/features')();
    } catch (e) {
      features = { CUSTOM_MODEL_CLASS: false };
    }

    this.options = this.options || {};
    this.options.babel = this.options.babel || {};
    // this ensures that the same `@ember-data/canary-features` processing that the various
    // ember-data addons do is done in the dummy app
    this.options.babel.plugins = [...debugMacros(features)];

    this.options.babel.loose = true;
  },
};
<|endoftext|>


<commit_before>module.exports = {
    parser: 'babel-eslint',
    extends: [
        'airbnb',
        'plugin:ava/recommended',
    ],
    plugins: [
        'import',
        'ava',
    ],
    rules: {
        indent: ['error', 4, {
            SwitchCase: 1,
            MemberExpression: 1,
            VariableDeclarator: 1,
            outerIIFEBody: 1,
            FunctionDeclaration: {
                parameters: 1,
                body: 1,
            },
            FunctionExpression: {
                parameters: 1,
                body: 1,
            },
        }],
        'valid-jsdoc': 'error',
        strict: 'error',
        'no-sync': 'error',
        'no-inline-comments': 'error',
        'no-use-before-define': ['error', 'nofunc'],
        'no-restricted-syntax': ['error', 'ForInStatement', 'LabeledStatement', 'WithStatement'],
        'max-len': ['error', 150, 4, {
            ignoreUrls: true,
            ignoreComments: false,
            ignoreRegExpLiterals: true,
            ignoreStrings: true,
            ignoreTemplateLiterals: true,
        }],
        'import/order': ['error', {
            groups: ['builtin', 'external', 'parent', 'sibling', 'index'],
        }],
        'import/named': 'error',
        'import/default': 'error',
        'import/namespace': 'error',
        'react/jsx-filename-extension': ['error', { extensions: ['.js', '.jsx'] }],
        'react/jsx-indent': ['error', 4],
    },
};
<commit_msg>Fix JSX attribute indentation<commit_after>module.exports = {
    parser: 'babel-eslint',
    extends: [
        'airbnb',
        'plugin:ava/recommended',
    ],
    plugins: [
        'import',
        'ava',
    ],
    rules: {
        indent: ['error', 4, {
            SwitchCase: 1,
            MemberExpression: 1,
            VariableDeclarator: 1,
            outerIIFEBody: 1,
            FunctionDeclaration: {
                parameters: 1,
                body: 1,
            },
            FunctionExpression: {
                parameters: 1,
                body: 1,
            },
        }],
        'valid-jsdoc': 'error',
        strict: 'error',
        'no-sync': 'error',
        'no-inline-comments': 'error',
        'no-use-before-define': ['error', 'nofunc'],
        'no-restricted-syntax': ['error', 'ForInStatement', 'LabeledStatement', 'WithStatement'],
        'max-len': ['error', 150, 4, {
            ignoreUrls: true,
            ignoreComments: false,
            ignoreRegExpLiterals: true,
            ignoreStrings: true,
            ignoreTemplateLiterals: true,
        }],
        'import/order': ['error', {
            groups: ['builtin', 'external', 'parent', 'sibling', 'index'],
        }],
        'import/named': 'error',
        'import/default': 'error',
        'import/namespace': 'error',
        'react/jsx-filename-extension': ['error', { extensions: ['.js', '.jsx'] }],
        'react/jsx-indent': ['error', 4],
        'react/jsx-indent-props': ['error', 4],
    },
};
<|endoftext|>


<commit_before>var botkit = require('botkit')
var morgan = require('morgan')

// default port to 8080 for local dev
var PORT = process.env.PORT || 8080

var controller = botkit.slackbot()
var beepboop = require('beepboop-botkit').start(controller, {
  debug: true
})

// This is for populating botkit's storage w/ the corresponding team info so slash commands work
// Once a bot scales beyond 1 process this approach has some limitations
beepboop.on('add_resource', function (message) {
  var slackTeamId = message.resource.SlackTeamID
  console.log('team %s added, storing in botkit storage...', slackTeamId)

  // Get a handle on the team's botkit worker/bot
  var resource = Object.keys(beepboop.workers).filter(function (key) {
    var entry = beepboop.workers[key]
    console.log('entry: ', JSON.stringify(entry))
    return entry.resource && entry.resource.SlackTeamID === slackTeamId
  })[0]
  if (!resource) {
    console.log('Cannot find a matching resource for team %s', slackTeamId)
    return
  }

  console.log('loading team info for new resource: ', resource.worker)
  console.log('api: ', resource.worker.api)
  // Fill botkit's storage w/ corresponding team info
  resource.worker.api.team.info({}, function (err, response) {
    if (err) {
      console.log('Error getting team info for team %s: %s', slackTeamId, err.message)
      return
    }

    controller.saveTeam(response.team, function (err, team) {
      if (err) {
        console.log('Error saving team info for team %s: %s', slackTeamId, err.message)
        return
      }

      console.log('Saved the team information...')
    })
  })
})

controller.setupWebserver(PORT, function (err, webserver) {
  if (err) {
    console.error(err)
    process.exit(1)
  }

  // Add an http logger
  webserver.use(morgan('dev'))
  // Setup our slash command webhook endpoints
  controller.createWebhookEndpoints(webserver)
})

controller.on('slash_command', function (bot, message) {
  switch (message.command) {
    case 'beepboop':
      var response = 'boopbeep'

      bot.replyPublic(message, response)
      break
    default:
      bot.replyPrivate(message, "Sorry, I'm not sure what that command is")
  }
})
<commit_msg>fixing reference to resource<commit_after>var botkit = require('botkit')
var morgan = require('morgan')

// default port to 8080 for local dev
var PORT = process.env.PORT || 8080

var controller = botkit.slackbot()
var beepboop = require('beepboop-botkit').start(controller, {
  debug: true
})

// This is for populating botkit's storage w/ the corresponding team info so slash commands work
// Once a bot scales beyond 1 process this approach has some limitations
beepboop.on('add_resource', function (message) {
  var slackTeamId = message.resource.SlackTeamID
  console.log('team %s added, storing in botkit storage...', slackTeamId)

  // Get a handle on the team's botkit worker/bot
  var resourceId = Object.keys(beepboop.workers).filter(function (key) {
    var entry = beepboop.workers[key]
    console.log('entry: ', JSON.stringify(entry))
    return entry.resource && entry.resource.SlackTeamID === slackTeamId
  })[0]
  if (!resourceId) {
    console.log('Cannot find a matching resource for team %s', slackTeamId)
    return
  }

  var resource = beepboop.workers[resourceId]
  console.log('loading team info for new resource: ', resource.worker)
  console.log('api: ', resource.worker.api)
  // Fill botkit's storage w/ corresponding team info
  resource.worker.api.team.info({}, function (err, response) {
    if (err) {
      console.log('Error getting team info for team %s: %s', slackTeamId, err.message)
      return
    }

    controller.saveTeam(response.team, function (err, team) {
      if (err) {
        console.log('Error saving team info for team %s: %s', slackTeamId, err.message)
        return
      }

      console.log('Saved the team information...')
    })
  })
})

controller.setupWebserver(PORT, function (err, webserver) {
  if (err) {
    console.error(err)
    process.exit(1)
  }

  // Add an http logger
  webserver.use(morgan('dev'))
  // Setup our slash command webhook endpoints
  controller.createWebhookEndpoints(webserver)
})

controller.on('slash_command', function (bot, message) {
  switch (message.command) {
    case 'beepboop':
      var response = 'boopbeep'

      bot.replyPublic(message, response)
      break
    default:
      bot.replyPrivate(message, "Sorry, I'm not sure what that command is")
  }
})
<|endoftext|>


<commit_before>var closest = require('closest');
var assign = require('object-assign');
var scrollTo = require('scroll-to-element');

var eventHandler;

function destroy() {
  document.removeEventListener('click', eventHandler, false);
}

function init(options) {

  destroy();

  options = assign({
    updateUrl: true
  }, options);

  eventHandler = function(ev) {
    var link = closest(ev.target, "a[href*='#']", true);
    if (link) {
      ev.preventDefault();
      if (history.pushState && options.updateUrl) {
        history.pushState(null, null, link.hash || '#');
      }
      scrollTo(link.hash || 'html');
    }
  };

  document.addEventListener('click', eventHandler, false);
}

module.exports = {
  init: init,
  destroy: destroy
};
<commit_msg>pass options to scroll-to-element<commit_after>var closest = require('closest');
var assign = require('object-assign');
var scrollTo = require('scroll-to-element');

var eventHandler;

function destroy() {
  document.removeEventListener('click', eventHandler, false);
}

function init(options) {

  destroy();

  options = assign({
    updateUrl: true
  }, options);

  eventHandler = function(ev) {
    var link = closest(ev.target, "a[href*='#']", true);
    if (link) {
      ev.preventDefault();
      if (history.pushState && options.updateUrl) {
        history.pushState(null, null, link.hash || '#');
      }
      scrollTo(link.hash || 'html', options);
    }
  };

  document.addEventListener('click', eventHandler, false);
}

module.exports = {
  init: init,
  destroy: destroy
};
<|endoftext|>


<commit_before>/* globals process */
'use strict'

// other
const bigInt = require('big-integer')

// twitter api
const twitterParse = require('twitter-url-parser')
const twitterAPI = require('node-twitter-api')
const twitter = new twitterAPI({
  consumerKey: process.env.TWITTER_CONSUMER_KEY,
  consumerSecret: process.env.TWITTER_CONSUMER_SECRET,
  callback: process.env.TWITTER_OAUTH_CALLBACK || 'http://localhost:8080/oauth'
})

// redis
const redis = require('redis')
const client = redis.createClient(process.env.REDIS_URL)

client.on('error', (error) => {
  console.log(error)
})

// express
const express = require('express')
const app = express()
const bodyParser = require('body-parser')

app.use(bodyParser.json())

// request body:
// id
// text
// username
app.post('/', (req, res) => {
  const twitterId = twitterParse(req.body.link).id
  client.hgetall('access', (error, access) => {
    if (error) {
      console.log(error)
    } else if (access) {
      twitter.search(
        {
          q: req.body.text,
          max_id: bigInt(twitterId).minus(1).toString()
        },
        access.token,
        access.tokenSecret,
        (error, data, response) => {
          if (error) {
            console.log(error)
          }
          else if (data && data.statuses && data.statuses[0]) {
            twitter.statuses(
              'update',
              {
                status: '@' + req.body.username + ' @' + data.statuses[0].user.screen_name + ' https://twitter.com/' + data.statuses[0].user.screen_name + '/status/' + data.statuses[0].id_str,
                in_reply_to_status_id: twitterId
              },
              access.token,
              access.tokenSecret,
              (error, data, response) => {
                if (error) {
                  console.log(error)
                }
              }
            )
          }
        })
    }
  })
  res.end()
})

app.get('/authenticate', (req, res) => {
  twitter.getRequestToken((error, requestToken, requestTokenSecret, results) => {
    if (error) {
      console.log('Error getting OAuth request token : ' + error)
    } else {
      client.del('request')
      client.hmset('request', 'token', requestToken, 'tokenSecret', requestTokenSecret, (error, result) => {
        if (error) {
          console.log(error)
        } else {
          res.redirect(twitter.getAuthUrl(requestToken))
        }
      })

    }
  })
})

app.get('/oauth', (req, res) => {
  client.hgetall('request', (error, request) => {
    if (error) {
      console.log(error)
    } else if (request) {
      twitter.getAccessToken(
        request.token,
        request.tokenSecret,
        req.query.oauth_verifier,
        (error, accessToken, accessTokenSecret, results) => {
          if (error) {
            console.log(error)
          } else {
            twitter.verifyCredentials(
              accessToken,
              accessTokenSecret,
              {},
              (error, data, response) => {
                if (error) {
                  console.log(error)
                } else {
                  client.del('access')
                  client.hmset('access', 'token', accessToken, 'tokenSecret', accessTokenSecret, (error, result) => {
                    if (error) {
                      console.log(error)
                    } else {
                      res.send(data['screen_name'])
                    }
                  })
                }
              })
          }
        })
    }
  })
})

app.listen(process.env.PORT || 8080, () => console.log('listening ' + (process.env.PORT || 8080)))
<commit_msg>troubleshoot json messages<commit_after>/* globals process */
'use strict'

// other
const bigInt = require('big-integer')

// twitter api
const twitterParse = require('twitter-url-parser')
const twitterAPI = require('node-twitter-api')
const twitter = new twitterAPI({
  consumerKey: process.env.TWITTER_CONSUMER_KEY,
  consumerSecret: process.env.TWITTER_CONSUMER_SECRET,
  callback: process.env.TWITTER_OAUTH_CALLBACK || 'http://localhost:8080/oauth'
})

// redis
const redis = require('redis')
const client = redis.createClient(process.env.REDIS_URL)

client.on('error', (error) => {
  console.log(error)
})

// express
const express = require('express')
const app = express()
const bodyParser = require('body-parser')

app.use(bodyParser.text())

// request body:
// id
// text
// username
app.post('/', (req, res) => {
  console.log(req.body)
  res.end()
  return

  const twitterId = twitterParse(req.body.link).id
  client.hgetall('access', (error, access) => {
    if (error) {
      console.log(error)
    } else if (access) {
      twitter.search(
        {
          q: req.body.text,
          max_id: bigInt(twitterId).minus(1).toString()
        },
        access.token,
        access.tokenSecret,
        (error, data, response) => {
          if (error) {
            console.log(error)
          }
          else if (data && data.statuses && data.statuses[0]) {
            twitter.statuses(
              'update',
              {
                status: 'ney'//'@' + req.body.username + ' @' + data.statuses[0].user.screen_name + ' https://twitter.com/' + data.statuses[0].user.screen_name + '/status/' + data.statuses[0].id_str,
                //in_reply_to_status_id: twitterId
              },
              access.token,
              access.tokenSecret,
              (error, data, response) => {
                if (error) {
                  console.log(error)
                }
              }
            )
          }
        })
    }
  })
  res.end()
})

app.get('/authenticate', (req, res) => {
  twitter.getRequestToken((error, requestToken, requestTokenSecret, results) => {
    if (error) {
      console.log('Error getting OAuth request token : ' + error)
    } else {
      client.del('request')
      client.hmset('request', 'token', requestToken, 'tokenSecret', requestTokenSecret, (error, result) => {
        if (error) {
          console.log(error)
        } else {
          res.redirect(twitter.getAuthUrl(requestToken))
        }
      })

    }
  })
})

app.get('/oauth', (req, res) => {
  client.hgetall('request', (error, request) => {
    if (error) {
      console.log(error)
    } else if (request) {
      twitter.getAccessToken(
        request.token,
        request.tokenSecret,
        req.query.oauth_verifier,
        (error, accessToken, accessTokenSecret, results) => {
          if (error) {
            console.log(error)
          } else {
            twitter.verifyCredentials(
              accessToken,
              accessTokenSecret,
              {},
              (error, data, response) => {
                if (error) {
                  console.log(error)
                } else {
                  client.del('access')
                  client.hmset('access', 'token', accessToken, 'tokenSecret', accessTokenSecret, (error, result) => {
                    if (error) {
                      console.log(error)
                    } else {
                      res.send(data['screen_name'])
                    }
                  })
                }
              })
          }
        })
    }
  })
})

app.listen(process.env.PORT || 8080, () => console.log('listening ' + (process.env.PORT || 8080)))
<|endoftext|>


<commit_before>var Accessory, hap, Service, Characteristic, UUIDGen;

var FFMPEG = require('./ffmpeg').FFMPEG;

var http = require('http');
var qs = require('querystring');
var concat = require('concat-stream');

module.exports = function (homebridge) {
    Accessory = homebridge.platformAccessory;
    hap = homebridge.hap;
    Service = hap.Service;
    Characteristic = hap.Characteristic;
    UUIDGen = homebridge.hap.uuid;

    homebridge.registerPlatform("homebridge-videodoorbell", "Video-doorbell", videodoorbellPlatform, true);
}

function videodoorbellPlatform(log, config, api) {
    var self = this;

    self.log = log;
    self.config = config || {};
    self.binaryState = 0; // switch state, default is OFF

    if (api) {
        self.api = api;

        if (api.version < 2.1) {
            throw new Error("Unexpected API version.");
        }

        self.api.on('didFinishLaunching', self.didFinishLaunching.bind(this));
    }
}

videodoorbellPlatform.prototype.configureAccessory = function (accessory) {
    // Won't be invoked
}

videodoorbellPlatform.prototype.getState = function (callback) {
    var self = this;

    console.log("Power state is %s", self.binaryState);
    callback(null, self.binaryState);
}

// Method to handle identify request
videodoorbellPlatform.prototype.identify = function (primaryService, paired, callback) {
    console.log("Identify requested!");

    // Dbg:
    console.log("Ding Dong!");
    primaryService.getCharacteristic(Characteristic.ProgrammableSwitchEvent).setValue(0);
    callback();
}

videodoorbellPlatform.prototype.EventWithAccessory = function (accessory) {
    console.log("Ding Dong!");
    accessory.getService(Service.Doorbell).getCharacteristic(Characteristic.ProgrammableSwitchEvent).setValue(0);
}

videodoorbellPlatform.prototype.didFinishLaunching = function () {
    var self = this;

    if (self.config.cameras) {
        var configuredAccessories = [];

        var cameras = self.config.cameras;
        cameras.forEach(function (cameraConfig) {
            var cameraName = cameraConfig.name;
            var videoConfig = cameraConfig.videoConfig;
            var webserverPort = videoConfig.port || 5005;

            if (!cameraName || !videoConfig) {
                console.log("Missing parameters.");
                return;
            }

            var uuid = UUIDGen.generate(cameraName);
            var videodoorbellAccessory = new Accessory(cameraName, uuid, hap.Accessory.Categories.VIDEO_DOORBELL);

            // Doorbell has to be the primary service
            var primaryService = new Service.Doorbell(cameraName);
            primaryService.getCharacteristic(Characteristic.ProgrammableSwitchEvent).on('get', self.getState.bind(this));

            // Setup and configure the camera services
            var cameraSource = new FFMPEG(hap, cameraConfig);
            videodoorbellAccessory.configureCameraSource(cameraSource);

            // Setup HomeKit doorbell service
            videodoorbellAccessory.addService(primaryService);

            // Identify
            videodoorbellAccessory.on('identify', self.identify.bind(this, primaryService));

            // We do not need the following 'required' services
            //var speakerService = new Service.Speaker("Speaker");
            //videodoorbellAccessory.addService(speakerService);

            configuredAccessories.push(videodoorbellAccessory);

            // DBG: Fire an event 10s after start
            //setTimeout(function () {
            //console.log("Ding Dong Ding");
            //primaryService.getCharacteristic(Characteristic.ProgrammableSwitchEvent).setValue(0);
            //}.bind(this), 10000);

            videodoorbellAccessory.createBellEvent = throttle(function() {
                self.EventWithAccessory(videodoorbellAccessory);
                self.log("Video-doorbell %s rang!", cameraName);
            }, 10000);

            // Create http-server to trigger doorbell from outside:
            // curl -X POST -d 'ding=dong&dong=ding' http://HOMEBRIDGEIP:PORT
            videodoorbellAccessory.server = http.createServer(function (req, res) {
                req.pipe(concat(function (body) {
                  var params = qs.parse(body.toString());
                  res.end(JSON.stringify(params) + '\n');
                  // todo: add validation
                  videodoorbellAccessory.createBellEvent();
                }));
            });

            //var server = http.createServer(self.handleRequest.bind(this));
            videodoorbellAccessory.server.listen(webserverPort, function () {
                console.log("Video-doorbell %s is listening on port %s", cameraName, webserverPort);
            }.bind(this));

            videodoorbellAccessory.server.on('error', function (err) {
                console.log("Video-doorbell %s Port %s Server %s ", cameraName, webserverPort, err);
            }.bind(this));
        });

        self.api.publishCameraAccessories("Video-doorbell", configuredAccessories);
    }
}

function throttle(fn, threshold, scope) {
  threshold || (threshold = 250);
  var last, deferTimer;
  return function() {
    var context = scope || this;
    var now = +new Date, args = arguments;
    if (last && now < last + threshold) {
    } else {
      last = now;
      fn.apply(context, args);
    }
  };
}

//videodoorbellPlatform.prototype.handleRequest = function (request, response) {

//    //console.log("Video-doorbell: request");
//    request.pipe(concat(function (body) {
//        var params = qs.parse(body.toString());
//        response.end(JSON.stringify(params) + '\n');
//        // todo: add validation
//        self.EventWithAccessory(videodoorbellAccessory);
//    }));
//}
<commit_msg>Actually use port config value<commit_after>var Accessory, hap, Service, Characteristic, UUIDGen;

var FFMPEG = require('./ffmpeg').FFMPEG;

var http = require('http');
var qs = require('querystring');
var concat = require('concat-stream');

module.exports = function (homebridge) {
    Accessory = homebridge.platformAccessory;
    hap = homebridge.hap;
    Service = hap.Service;
    Characteristic = hap.Characteristic;
    UUIDGen = homebridge.hap.uuid;

    homebridge.registerPlatform("homebridge-videodoorbell", "Video-doorbell", videodoorbellPlatform, true);
}

function videodoorbellPlatform(log, config, api) {
    var self = this;

    self.log = log;
    self.config = config || {};
    self.binaryState = 0; // switch state, default is OFF

    if (api) {
        self.api = api;

        if (api.version < 2.1) {
            throw new Error("Unexpected API version.");
        }

        self.api.on('didFinishLaunching', self.didFinishLaunching.bind(this));
    }
}

videodoorbellPlatform.prototype.configureAccessory = function (accessory) {
    // Won't be invoked
}

videodoorbellPlatform.prototype.getState = function (callback) {
    var self = this;

    console.log("Power state is %s", self.binaryState);
    callback(null, self.binaryState);
}

// Method to handle identify request
videodoorbellPlatform.prototype.identify = function (primaryService, paired, callback) {
    console.log("Identify requested!");

    // Dbg:
    console.log("Ding Dong!");
    primaryService.getCharacteristic(Characteristic.ProgrammableSwitchEvent).setValue(0);
    callback();
}

videodoorbellPlatform.prototype.EventWithAccessory = function (accessory) {
    console.log("Ding Dong!");
    accessory.getService(Service.Doorbell).getCharacteristic(Characteristic.ProgrammableSwitchEvent).setValue(0);
}

videodoorbellPlatform.prototype.didFinishLaunching = function () {
    var self = this;

    if (self.config.cameras) {
        var configuredAccessories = [];

        var cameras = self.config.cameras;
        cameras.forEach(function (cameraConfig) {
            var cameraName = cameraConfig.name;
            var videoConfig = cameraConfig.videoConfig;
            var webserverPort = cameraConfig.port || 5005;

            if (!cameraName || !videoConfig) {
                console.log("Missing parameters.");
                return;
            }

            var uuid = UUIDGen.generate(cameraName);
            var videodoorbellAccessory = new Accessory(cameraName, uuid, hap.Accessory.Categories.VIDEO_DOORBELL);

            // Doorbell has to be the primary service
            var primaryService = new Service.Doorbell(cameraName);
            primaryService.getCharacteristic(Characteristic.ProgrammableSwitchEvent).on('get', self.getState.bind(this));

            // Setup and configure the camera services
            var cameraSource = new FFMPEG(hap, cameraConfig);
            videodoorbellAccessory.configureCameraSource(cameraSource);

            // Setup HomeKit doorbell service
            videodoorbellAccessory.addService(primaryService);

            // Identify
            videodoorbellAccessory.on('identify', self.identify.bind(this, primaryService));

            // We do not need the following 'required' services
            //var speakerService = new Service.Speaker("Speaker");
            //videodoorbellAccessory.addService(speakerService);

            configuredAccessories.push(videodoorbellAccessory);

            // DBG: Fire an event 10s after start
            //setTimeout(function () {
            //console.log("Ding Dong Ding");
            //primaryService.getCharacteristic(Characteristic.ProgrammableSwitchEvent).setValue(0);
            //}.bind(this), 10000);

            videodoorbellAccessory.createBellEvent = throttle(function() {
                self.EventWithAccessory(videodoorbellAccessory);
                self.log("Video-doorbell %s rang!", cameraName);
            }, 10000);

            // Create http-server to trigger doorbell from outside:
            // curl -X POST -d 'ding=dong&dong=ding' http://HOMEBRIDGEIP:PORT
            videodoorbellAccessory.server = http.createServer(function (req, res) {
                req.pipe(concat(function (body) {
                  var params = qs.parse(body.toString());
                  res.end(JSON.stringify(params) + '\n');
                  // todo: add validation
                  videodoorbellAccessory.createBellEvent();
                }));
            });

            //var server = http.createServer(self.handleRequest.bind(this));
            videodoorbellAccessory.server.listen(webserverPort, function () {
                console.log("Video-doorbell %s is listening on port %s", cameraName, webserverPort);
            }.bind(this));

            videodoorbellAccessory.server.on('error', function (err) {
                console.log("Video-doorbell %s Port %s Server %s ", cameraName, webserverPort, err);
            }.bind(this));
        });

        self.api.publishCameraAccessories("Video-doorbell", configuredAccessories);
    }
}

function throttle(fn, threshold, scope) {
  threshold || (threshold = 250);
  var last, deferTimer;
  return function() {
    var context = scope || this;
    var now = +new Date, args = arguments;
    if (last && now < last + threshold) {
    } else {
      last = now;
      fn.apply(context, args);
    }
  };
}

//videodoorbellPlatform.prototype.handleRequest = function (request, response) {

//    //console.log("Video-doorbell: request");
//    request.pipe(concat(function (body) {
//        var params = qs.parse(body.toString());
//        response.end(JSON.stringify(params) + '\n');
//        // todo: add validation
//        self.EventWithAccessory(videodoorbellAccessory);
//    }));
//}
<|endoftext|>


<commit_before>'use strict';

var gutil = require('gulp-util'),
	through2 = require('through2'),
	path = require('path');

module.exports = function () {
	return through2.obj(function (file, encoding, done) {
		this.push(file);

		if (!(/gulpfile.js/).test(file.path)) { return; }

		gutil.log('gulp-reload saw',
			gutil.colors.magenta(path.basename(file.path)),
			'and reloading now');

		this.unpipe();

		if (!process.env.RELOAD) {
			while (true) {
				require('shelljs').exec('RELOAD=true ' + process.argv.join(' '));
			}
		}

		process.exit(0);

		done();
	});
};
<commit_msg>Fixup passing through non-gulpfiles<commit_after>'use strict';

var gutil = require('gulp-util'),
	through2 = require('through2'),
	path = require('path');

module.exports = function () {
	return through2.obj(function (file, encoding, done) {
		if (!(/gulpfile.js/).test(file.path)) {
			this.push(file);
			done();
			return;
		}

		gutil.log('gulp-reload saw',
			gutil.colors.magenta(path.basename(file.path)),
			'and reloading now');

		if (!process.env.RELOAD) {
			while (true) {
				require('shelljs').exec('RELOAD=true ' + process.argv.join(' '));
			}
		}

		process.exit(0);

	});
};
<|endoftext|>