<commit_before>var mongoose = require('mongoose')
  , Schema = mongoose.Schema;
var apn = require('apn');

/**
 * Holds the information about a device. This is used to be able to run smart
 * notifications. We can send notifications to the "last active device" and
 * then wait to send to the rest.
 *
 * type Should be either 'ios' or 'android'. Used to send notifications to the
 * correct gateways. More can be added later.
 */
var Device = new Schema({
  user: {type: Schema.Types.ObjectId, ref: 'User'},
  token: String,
  type: String,
  lastActiveDate: Date,
  failedAttempts: Number
});

/**
 * Sends a string to the device.
 * Sets some nice defaults, and takes care of sending to APN or GCM.
 *
 * @message A string to send to the user in a notification.
 */
Device.methods.send = function(message) {
  var options = {
    'gateway': 'gateway.sandbox.push.apple.com'
  };

  var apnConnection = new apn.Connection(options);
  var device = new apn.Device(this.token);
  var note = new apn.Notification();

  note.expiry = Math.floor(Date.now() / 1000) + 3600; // Expires 1 hour from now.
  note.badge = 1;
  note.sound = "ping.aiff";
  note.alert = message;
  note.payload = {'messageFrom': 'Someone'};

  console.log('FIRING AWAY: ' + JSON.stringify(note, null, 4) + ' TO: ' + this.token);

  apnConnection.pushNotification(note, device);
};

module.exports = mongoose.model('Device', Device);
<commit_msg>Switching to prod for dev<commit_after>var mongoose = require('mongoose')
  , Schema = mongoose.Schema;
var apn = require('apn');

/**
 * Holds the information about a device. This is used to be able to run smart
 * notifications. We can send notifications to the "last active device" and
 * then wait to send to the rest.
 *
 * type Should be either 'ios' or 'android'. Used to send notifications to the
 * correct gateways. More can be added later.
 */
var Device = new Schema({
  user: {type: Schema.Types.ObjectId, ref: 'User'},
  token: String,
  type: String,
  lastActiveDate: Date,
  failedAttempts: Number
});

/**
 * Sends a string to the device.
 * Sets some nice defaults, and takes care of sending to APN or GCM.
 *
 * @message A string to send to the user in a notification.
 */
Device.methods.send = function(message) {
  var options = {
//    'gateway': 'gateway.sandbox.push.apple.com'
  };

  var apnConnection = new apn.Connection(options);
  var device = new apn.Device(this.token);
  var note = new apn.Notification();

  note.expiry = Math.floor(Date.now() / 1000) + 3600; // Expires 1 hour from now.
  note.badge = 1;
  note.sound = "ping.aiff";
  note.alert = message;
  note.payload = {'messageFrom': 'Someone'};

  console.log('FIRING AWAY: ' + JSON.stringify(note, null, 4) + ' TO: ' + this.token);

  apnConnection.pushNotification(note, device);
};

module.exports = mongoose.model('Device', Device);
<|endoftext|>


<commit_before>// Save a reference to the global object (`window` in the browser, `global`
// on the server).
var root = this;

// The top-level namespace. All public Backbone classes and modules will
// be attached to this. Exported for both CommonJS and the browser.
var Media, server = false;
if (typeof exports !== 'undefined') {
    Media = exports;
    server = true;
    var uuid = require('node-uuid');
} else {
    Media = root.Media = {};
    var uuid = root.uuid;
}

// Require Underscore, Backbone & BackboneIO, if we're on the server, and it's not already present.
var _ = root._;
if (!_ && (typeof require !== 'undefined')) _ = require('underscore');

var BackboneIO = root.BackboneIO;
if ((typeof require !== 'undefined')) Backbone = require('backbone');

var leadingZero = function (num) {
    return (num < 10) ? "0"+num : num;
}

var toMilliseconds = function (time) {
    if (!time) {
        console.log ("No time");
        return 0;
    }

    var t = time.match(/(\d{2}):(\d{2}):(\d{2})\.(\d*)/);
    t.shift();
    d = moment.duration ({
        hours:        t[0],
        minutes:      t[1],
        seconds:      t[2],
        milliseconds: t[3]*10
    });

    return d.asMilliseconds();
};

var prettyTime =  function (m) {
    d = moment.duration(m);
    var p = leadingZero(d.hours())   + ':'
        + leadingZero(d.minutes()) + ':'
        + leadingZero(d.seconds()) + '.'
        + leadingZero(d.milliseconds()/10);
    return p;
};

var arrayDuration = function (a) {
    return  _.reduce(a, function (m, n) {
        return m + toMilliseconds (n);}, 0);
};

var Media = {};

Media.Model = Backbone.Model.extend({
    urlRoot: "media",
    idAttribute: "_id",
    initialize: function () {
        console.log ('creating new Media.Model');
    },
    validate: function (attrs) {
        console.log ("checking -> ", attrs);
        if (attrs.file && ! attrs.file.length) {
            console.log ('NO file');
            return new Error("file must be defined");
        }
        if (attrs.stat       &&
            (! attrs.stat.mtime ||
             ! attrs.stat.size  ||
             attrs.stat.size <= 4000)) {
            console.log ('NO or BAD stat');
            return new Error("stat must be defined");
        }
    },
    defaults: {
        _id: '',
        stat: {},
        file: "None",
        name: "",
        audio: "None",
        video: "None",
        template: 'mediaview',
        notes: "",
    }
});

/* all methods are overriden in Default.js */
Media.Collection = Backbone.Collection.extend({
    model: Media.Model,
    url: 'media',
    backend: 'mediabackend',
    initialize: function () {
        if (!server) {
            this.bindBackend();

            this.bind('backend', function(method, model) {
                console.log ('got from backend:', method, model);
            });
        }
        console.log ('creating new Media.Collection');

        Backbone.Collection.prototype.initialize.call (this);
    }
});

Media.Piece = Media.Model.extend ({
    urlRoot: 'piece',
    idAttribute: "_id",
    defaults: {
        trim: {
            timein:  0,
            timeout: 0,
        },
        overlay: [],
        starts: 0,
        ends: 0,
    },
    initialize: function (attributes, options) {
        console.log ('creating new Media.Piece');
        if (this.idAttribute in attributes) {
            // we got a Media id, replace it with an uuid.
            if ( !attributes['_id'].match(/-/) ) {
                this.set(this.idAttribute, uuid.v4(), {silent: true});
            }
        }
    },

});

Media.Block = Media.Collection.extend ({
    model: Media.Piece,
    url: 'piece',
    backend: 'blockbackend',
    initialize: function () {
        if (!server)
            this.bindBackend();
        console.log ('creating new Media.Block');
    },

});

Media.List = Media.Model.extend ({
    urlRoot: 'list',
    newCol: function (models, opts) {
        return new Media.Block (models, opts);
    },
    initialize: function () {
        var models = this.get('models')
        var col    = this.get('collection')

        if (!models)
            return false;

        console.log ("creating new Media.List", models, col);
        if (!col || col instanceof Array) {
            console.log ('col is array ! recreating as collection', col, models);
            col = this.newCol(models, {connectable: true});
        }

        var self = this;
        col.wrapper = this;

        col.bind('all', function (a, b) {
            var models = self.get('collection').models;
            self.set({models: models});
            self.update_duration(col);
            console.log ('-----got a change in the force', a, b);
        }, this);

        this.set ({collection: col, models: col.models});
        Media.Model.prototype.initialize.call (this);
    },
    update_duration: function (col) {
        this.set({duration : arrayDuration(col.pluck('durationraw'))});
    },
    pretty_duration: function () {
        return prettyTime (this.get('duration'));
    },

    defaults: {
        collection: null,
        models: [],
        name: null,
        fixed: false,
        duration: 0,
        pos: 0,
    },

    // Set a hash of model attributes, and sync the model to the server.
    // If the server returns an attributes hash that differs, the model's
    // state will be `set` again.
    save: function(key, val, options) {
        var attrs, success, method, xhr, attributes = this.attributes;

        // Handle both `"key", value` and `{key: value}` -style arguments.
        if (key == null || typeof key === 'object') {
            attrs = key;
            options = val;
        } else {
            (attrs = {})[key] = val;
        }

//XXX:
        // If we're not waiting and attributes exist, save acts as `set(attr).save(null, opts)`.
        if (attrs && (!options || !options.wait) && !this.set(attrs, options)) return false;

        options = _.extend({validate: true}, options);

        // Do not persist invalid models.
        if (!this._validate(attrs, options)) return false;

        // Set temporary attributes if `{wait: true}`.
        if (attrs && options.wait) {
            this.attributes = _.extend({}, attributes, attrs);
        }

        // After a successful server-side save, the client is (optionally)
        // updated with the server-side state.
        if (options.parse === void 0) options.parse = true;
        success = options.success;
        options.success = function(model, resp, options) {
            // Ensure attributes are restored during synchronous saves.
            model.attributes = attributes;
            var serverAttrs = model.parse(resp, options);
//XXX:
            delete serverAttrs['collection'];
            if (options.wait) serverAttrs = _.extend(attrs || {}, serverAttrs);
            if (_.isObject(serverAttrs) && !model.set(serverAttrs, options)) {
                return false;
            }
            if (success) success(model, resp, options);
        };

        // Finish configuring and sending the Ajax request.
        method = this.isNew() ? 'create' : (options.patch ? 'patch' : 'update');
        if (method === 'patch') options.attrs = attrs;
        xhr = this.sync(method, this, options);

        // Restore attributes.
        if (attrs && options.wait) this.attributes = attributes;

        return xhr;
    },

});

Media.Universe = Media.Collection.extend ({
    url: 'list',
    model: Media.List,
    backend: 'listbackend',
    initialize: function () {
        if (!server)
            this.bindBackend();
        console.log ('creating new Media.Universe');
    },
});

Media.Occurrence = Media.List.extend ({
    urlRoot: 'occur',
    defaults: {
        event: null,
    },
    initialize: function () {
        console.log ('creating new Media.Occurrence', this);
        this.overlapsWith = [];
    },
    newCol: function (models, opts) {
        return new Media.Occurrence (models, opts);
    },
    update: function (attrs) {
        for (a in this.attributes) {
            if (attrs.hasOwnProperty(a))
                this.set(a, attrs[a]);
        }
    },
    getOverlappingEvents: function() {
        // Get all events that overlap with this one
        var self = this;
        return this.collection.filter(function(oc) {
            return (oc.get('_id') != self.get('_id') &&
                    oc.get('start') < self.get('end') &&
                    oc.get('end') > self.get('start'));
        });
    },
    validate: function(attrs, options) {
        // Do not validate when fetching from the server
        if (options.parse) return;
        // Only save model if it's not overlapping with anything
        var self = this;
        overlapping = this.getOverlappingEvents();
        if (overlapping.length) {
            overlapping.forEach(function(oc) {
                oc.overlapsWith.push(self);
            });
            this.collection.trigger('overlap', true);
            return overlapping
        } else {
            /* When this event is no longer overlapping, the other events could be valid.
               validationError would be unset after this function returns, but I need if before
               I call checkOverlap. Could be improved. */

            delete this.validationError;
            // Prevent infinite loops by first emptying the list
            var overlapsWith = _.clone(this.overlapsWith);
            this.overlapsWith = [];

            overlapsWith.forEach(function(oc) {
                oc.save();
            });

            this.collection.checkOverlap();
        }
    },
});

Media.Schedule = Media.Universe.extend ({
    url: 'occur',
    model: Media.Occurrence,
    backend: 'schedbackend',
    initialize: function () {
        if (!server)
            this.bindBackend();
        console.log ('creating new Media.Schedule');
        this.on('add remove', this.checkOverlap)
    },
    comparator: "start",
    getInvalid: function() {
        return this.filter(function(oc) {
            return oc.validationError
        });
    },
    checkOverlap: function() {
        var elems = this.getInvalid();
        this.trigger('overlap', elems.length);
    }
});

if(server) module.exports = Media;
else root.Media = Media;
<commit_msg>Updating save method to Backbone 1.0 (used to fix a KB collection bug)<commit_after>// Save a reference to the global object (`window` in the browser, `global`
// on the server).
var root = this;

// The top-level namespace. All public Backbone classes and modules will
// be attached to this. Exported for both CommonJS and the browser.
var Media, server = false;
if (typeof exports !== 'undefined') {
    Media = exports;
    server = true;
    var uuid = require('node-uuid');
} else {
    Media = root.Media = {};
    var uuid = root.uuid;
}

// Require Underscore, Backbone & BackboneIO, if we're on the server, and it's not already present.
var _ = root._;
if (!_ && (typeof require !== 'undefined')) _ = require('underscore');

var BackboneIO = root.BackboneIO;
if ((typeof require !== 'undefined')) Backbone = require('backbone');

var leadingZero = function (num) {
    return (num < 10) ? "0"+num : num;
}

var toMilliseconds = function (time) {
    if (!time) {
        console.log ("No time");
        return 0;
    }

    var t = time.match(/(\d{2}):(\d{2}):(\d{2})\.(\d*)/);
    t.shift();
    d = moment.duration ({
        hours:        t[0],
        minutes:      t[1],
        seconds:      t[2],
        milliseconds: t[3]*10
    });

    return d.asMilliseconds();
};

var prettyTime =  function (m) {
    d = moment.duration(m);
    var p = leadingZero(d.hours())   + ':'
        + leadingZero(d.minutes()) + ':'
        + leadingZero(d.seconds()) + '.'
        + leadingZero(d.milliseconds()/10);
    return p;
};

var arrayDuration = function (a) {
    return  _.reduce(a, function (m, n) {
        return m + toMilliseconds (n);}, 0);
};

var Media = {};

Media.Model = Backbone.Model.extend({
    urlRoot: "media",
    idAttribute: "_id",
    initialize: function () {
        console.log ('creating new Media.Model');
    },
    validate: function (attrs) {
        console.log ("checking -> ", attrs);
        if (attrs.file && ! attrs.file.length) {
            console.log ('NO file');
            return new Error("file must be defined");
        }
        if (attrs.stat       &&
            (! attrs.stat.mtime ||
             ! attrs.stat.size  ||
             attrs.stat.size <= 4000)) {
            console.log ('NO or BAD stat');
            return new Error("stat must be defined");
        }
    },
    defaults: {
        _id: '',
        stat: {},
        file: "None",
        name: "",
        audio: "None",
        video: "None",
        template: 'mediaview',
        notes: "",
    }
});

/* all methods are overriden in Default.js */
Media.Collection = Backbone.Collection.extend({
    model: Media.Model,
    url: 'media',
    backend: 'mediabackend',
    initialize: function () {
        if (!server) {
            this.bindBackend();

            this.bind('backend', function(method, model) {
                console.log ('got from backend:', method, model);
            });
        }
        console.log ('creating new Media.Collection');

        Backbone.Collection.prototype.initialize.call (this);
    }
});

Media.Piece = Media.Model.extend ({
    urlRoot: 'piece',
    idAttribute: "_id",
    defaults: {
        trim: {
            timein:  0,
            timeout: 0,
        },
        overlay: [],
        starts: 0,
        ends: 0,
    },
    initialize: function (attributes, options) {
        console.log ('creating new Media.Piece');
        if (this.idAttribute in attributes) {
            // we got a Media id, replace it with an uuid.
            if ( !attributes['_id'].match(/-/) ) {
                this.set(this.idAttribute, uuid.v4(), {silent: true});
            }
        }
    },

});

Media.Block = Media.Collection.extend ({
    model: Media.Piece,
    url: 'piece',
    backend: 'blockbackend',
    initialize: function () {
        if (!server)
            this.bindBackend();
        console.log ('creating new Media.Block');
    },

});

Media.List = Media.Model.extend ({
    urlRoot: 'list',
    newCol: function (models, opts) {
        return new Media.Block (models, opts);
    },
    initialize: function () {
        var models = this.get('models')
        var col    = this.get('collection')

        if (!models)
            return false;

        console.log ("creating new Media.List", models, col);
        if (!col || col instanceof Array) {
            console.log ('col is array ! recreating as collection', col, models);
            col = this.newCol(models, {connectable: true});
        }

        var self = this;
        col.wrapper = this;

        col.bind('all', function (a, b) {
            var models = self.get('collection').models;
            self.set({models: models});
            self.update_duration(col);
            console.log ('-----got a change in the force', a, b);
        }, this);

        this.set ({collection: col, models: col.models});
        Media.Model.prototype.initialize.call (this);
    },
    update_duration: function (col) {
        this.set({duration : arrayDuration(col.pluck('durationraw'))});
    },
    pretty_duration: function () {
        return prettyTime (this.get('duration'));
    },

    defaults: {
        collection: null,
        models: [],
        name: null,
        fixed: false,
        duration: 0,
        pos: 0,
    },

    // Set a hash of model attributes, and sync the model to the server.
    // If the server returns an attributes hash that differs, the model's
    // state will be `set` again.
    save: function(key, val, options) {
        var attrs, method, xhr, attributes = this.attributes;

        // Handle both `"key", value` and `{key: value}` -style arguments.
        if (key == null || typeof key === 'object') {
            attrs = key;
            options = val;
        } else {
            (attrs = {})[key] = val;
        }

//XXX:
        // If we're not waiting and attributes exist, save acts as `set(attr).save(null, opts)`.
        if (attrs && (!options || !options.wait) && !this.set(attrs, options)) return false;

        options = _.extend({validate: true}, options);

        // Do not persist invalid models.
        if (!this._validate(attrs, options)) return false;

        // Set temporary attributes if `{wait: true}`.
        if (attrs && options.wait) {
            this.attributes = _.extend({}, attributes, attrs);
        }

        // After a successful server-side save, the client is (optionally)
        // updated with the server-side state.
        if (options.parse === void 0) options.parse = true;
        var model = this;
        var success = options.success;
        options.success = function(resp) {
            // Ensure attributes are restored during synchronous saves.
            model.attributes = attributes;
            var serverAttrs = model.parse(resp, options);
//XXX:
            delete serverAttrs['collection'];
            if (options.wait) serverAttrs = _.extend(attrs || {}, serverAttrs);
            if (_.isObject(serverAttrs) && !model.set(serverAttrs, options)) {
                return false;
            }
            if (success) success(model, resp, options);
            model.trigger('sync',model, resp, options);
        };

        // Finish configuring and sending the Ajax request.
        method = this.isNew() ? 'create' : (options.patch ? 'patch' : 'update');
        if (method === 'patch') options.attrs = attrs;
        xhr = this.sync(method, this, options);

        // Restore attributes.
        if (attrs && options.wait) this.attributes = attributes;

        return xhr;
    },

});

Media.Universe = Media.Collection.extend ({
    url: 'list',
    model: Media.List,
    backend: 'listbackend',
    initialize: function () {
        if (!server)
            this.bindBackend();
        console.log ('creating new Media.Universe');
    },
});

Media.Occurrence = Media.List.extend ({
    urlRoot: 'occur',
    defaults: {
        event: null,
    },
    initialize: function () {
        console.log ('creating new Media.Occurrence', this);
        this.overlapsWith = [];
    },
    newCol: function (models, opts) {
        return new Media.Occurrence (models, opts);
    },
    update: function (attrs) {
        for (a in this.attributes) {
            if (attrs.hasOwnProperty(a))
                this.set(a, attrs[a]);
        }
    },
    getOverlappingEvents: function() {
        // Get all events that overlap with this one
        var self = this;
        return this.collection.filter(function(oc) {
            return (oc.get('_id') != self.get('_id') &&
                    oc.get('start') < self.get('end') &&
                    oc.get('end') > self.get('start'));
        });
    },
    validate: function(attrs, options) {
        // Do not validate when fetching from the server
        if (options.parse) return;
        // Only save model if it's not overlapping with anything
        var self = this;
        overlapping = this.getOverlappingEvents();
        if (overlapping.length) {
            overlapping.forEach(function(oc) {
                oc.overlapsWith.push(self);
            });
            this.collection.trigger('overlap', true);
            return overlapping
        } else {
            /* When this event is no longer overlapping, the other events could be valid.
               validationError would be unset after this function returns, but I need if before
               I call checkOverlap. Could be improved. */

            delete this.validationError;
            // Prevent infinite loops by first emptying the list
            var overlapsWith = _.clone(this.overlapsWith);
            this.overlapsWith = [];

            overlapsWith.forEach(function(oc) {
                oc.save();
            });

            this.collection.checkOverlap();
        }
    },
});

Media.Schedule = Media.Universe.extend ({
    url: 'occur',
    model: Media.Occurrence,
    backend: 'schedbackend',
    initialize: function () {
        if (!server)
            this.bindBackend();
        console.log ('creating new Media.Schedule');
        this.on('add remove', this.checkOverlap)
    },
    comparator: "start",
    getInvalid: function() {
        return this.filter(function(oc) {
            return oc.validationError
        });
    },
    checkOverlap: function() {
        var elems = this.getInvalid();
        this.trigger('overlap', elems.length);
    }
});

if(server) module.exports = Media;
else root.Media = Media;
<|endoftext|>


<commit_before>var keystone = require('arch-keystone');
var transform = require('model-transform');
var Types = keystone.Field.Types;

var Topic = new keystone.List('Topic', {
	autokey: { from: 'name', path: 'key', unique: true },
});

Topic.add({
  name: { label: '專題名稱', type: String, required: true },
  brief: { label: '前言', type: Types.Html, wysiwyg: true, height: 150 },
  heroVideo: { label: 'Leading Video', type: Types.Relationship, ref: 'Video' },
  heroImage: { label: '首圖', type: Types.ImageRelationship, ref: 'Image' },
  heroImageSize: { label: '首圖尺寸', type: Types.Select, options: 'extend, normal, small', default: 'normal', dependsOn: { heroImage: {'$regex': '.+/i'}}},
  og_title: { label: 'FB分享標題', type: String, require: false},
  og_description: { label: 'FB分享說明', type: String, require: false},
  og_image: { label: 'FB分享縮圖', type: Types.ImageRelationship, ref: 'Image' },
  isFeatured: { label: '置頂', type: Boolean, index: true },
  style: { label: 'CSS', type: Types.Textarea },
  javascript: { label: 'javascript', type: Types.Textarea },
});

Topic.relationship({ ref: 'Post', refPath: 'topics' });

transform.toJSON(Topic);
Topic.register();
<commit_msg>adding the leading field for topic<commit_after>var keystone = require('arch-keystone');
var transform = require('model-transform');
var Types = keystone.Field.Types;

var Topic = new keystone.List('Topic', {
	autokey: { from: 'name', path: 'key', unique: true },
});

Topic.add({
  name: { label: '專題名稱', type: String, required: true },
  brief: { label: '前言', type: Types.Html, wysiwyg: true, height: 150 },
  leading: { label: '標頭樣式', type: Types.Select, options: 'video, slideshow, image', index: true },
  heroVideo: { label: 'Leading Video', type: Types.Relationship, ref: 'Video', dependsOn: { leading: 'video' } },
  heroImage: { label: '首圖', type: Types.ImageRelationship, ref: 'Image', dependsOn: { leading: 'image' } },
  heroImageSize: { label: '首圖尺寸', type: Types.Select, options: 'extend, normal, small', default: 'normal', dependsOn: { heroImage: {'$regex': '.+/i'}}},
  og_title: { label: 'FB分享標題', type: String, require: false},
  og_description: { label: 'FB分享說明', type: String, require: false},
  og_image: { label: 'FB分享縮圖', type: Types.ImageRelationship, ref: 'Image' },
  isFeatured: { label: '置頂', type: Boolean, index: true },
  style: { label: 'CSS', type: Types.Textarea },
  javascript: { label: 'javascript', type: Types.Textarea },
});

Topic.relationship({ ref: 'Post', refPath: 'topics' });

transform.toJSON(Topic);
Topic.register();
<|endoftext|>


<commit_before>var mongoose = require('mongoose');
var bcrypt   = require('bcrypt-nodejs');

// define the schema for our user model
var emailSchema = mongoose.Schema ({
  recipient           : 	String,
  sender              : 	String,
  from                : 	String,
  subject             : 	String,
  bodyPlain           : 	String,
  strippedText        : 	String,
  strippedSignature   : 	String,
  bodyHtml            : 	String,
  strippedHtml        : 	String,
  attachmentCount     : 	Number,
  attachmentx         : 	String,
  messageHeaders      : 	String,
  contentIdMap        : 	String,
  btcAddress          :   String
});
module.exports = mongoose.model('Email', emailSchema);
<commit_msg>add callback, to, from, and type fields to mailSchema<commit_after>var mongoose = require('mongoose');
var bcrypt   = require('bcrypt-nodejs');

// define the schema for our user model
var emailSchema = mongoose.Schema ({
  type                :   String, // "reward" for cced mails or "incoming"
  incomingEmail       :   String, // user_id where user_id@mailman.ninja
  to                  :   String,
  date                :   Date,
  cc                  :   String,
  recipient           : 	String,
  sender              : 	String,
  from                : 	String,
  subject             : 	String,
  subjectStripped     :   String, // subject with the "re", "fwd" stripped
  bodyPlain           : 	String,
  strippedText        : 	String,
  strippedSignature   : 	String,
  bodyHtml            : 	String,
  strippedHtml        : 	String,
  attachmentCount     : 	Number,
  attachmentx         : 	String,
  messageHeaders      : 	String,
  contentIdMap        : 	String,
  btcAddress          :   String, // generated address for the email
  callbackRes         :   Object // the callback when address is paid
});
module.exports = mongoose.model('Email', emailSchema);
<|endoftext|>


<commit_before>var _    = require("underscore"),
    AWS  = require("aws-sdk"),
    Util = require("util");

module.exports = (function () {
  var Photo = function (options) {
    if (typeof options === "undefined") {
      options = {};
    }

    _.defaults(this, _.extend({
      key           : null,
      dateModified  : null
    }, options));

    this.init();
  };

  // Prototype
  Photo.prototype = {
    init: function () {
      this.url = Photo.getBucketUrl() + "/" + this.key;
    }
  };

  // Statics
  Photo.getS3 = function() {
    if (typeof Photo.__S3 === "undefined") {
      // First make sure the config is up-to-date
      AWS.config.update(app.get("config").AWS);

      // Initialize
      var s3 = new AWS.S3();
      Photo.__S3 = s3;
    }

    return Photo.__S3;
  };

  Photo.getBucketUrl = function () {
    return Util.format(
      "https://s3-%s.amazonaws.com/%s",
      app.get("config").AWS.region,
      app.get("config").S3.bucket
    );
  };

  Photo.getPhotos = function (limit, callback) {
    // Default limit parameter
    if (typeof limit === "undefined") {
      limit = 100;
    }

    Photo.getS3().listObjects({
      Bucket  : app.get("config").S3.bucket,
      MaxKeys : limit
    }, function objectsReceived(error, response) {
      try {
        if (error) {
          throw error;
        }

        // Process response
        var photos = [];
        while (response.Contents.length > 0) {
          var photoObject = response.Contents.pop();

          var photo = new Photo({
            key          : photoObject.Key,
            dateModified : photoObject.LastModified
          });

          photos.push(photo);
        }

        callback(null, photos);
      }
      catch (_error) {
        callback (_error, null);
      }
    });
  };

  return Photo;
})();<commit_msg>Only care about objects prefixed by /photos<commit_after>var _    = require("underscore"),
    AWS  = require("aws-sdk"),
    Util = require("util");

module.exports = (function () {
  var Photo = function (options) {
    if (typeof options === "undefined") {
      options = {};
    }

    _.defaults(this, _.extend({
      key           : null,
      dateModified  : null
    }, options));

    this.init();
  };

  // Prototype
  Photo.prototype = {
    init: function () {
      this.url = Photo.getBucketUrl() + "/" + this.key;
    }
  };

  // Statics
  Photo.getS3 = function() {
    if (typeof Photo.__S3 === "undefined") {
      // First make sure the config is up-to-date
      AWS.config.update(app.get("config").AWS);

      // Initialize
      var s3 = new AWS.S3();
      Photo.__S3 = s3;
    }

    return Photo.__S3;
  };

  Photo.getBucketUrl = function () {
    return Util.format(
      "https://s3-%s.amazonaws.com/%s",
      app.get("config").AWS.region,
      app.get("config").S3.bucket
    );
  };

  Photo.getPhotos = function (limit, callback) {
    // Default limit parameter
    if (typeof limit === "undefined") {
      limit = 100;
    }

    Photo.getS3().listObjects({
      Bucket  : app.get("config").S3.bucket,
      MaxKeys : limit,
      Prefix  : "photos/"
    }, function objectsReceived(error, response) {
      try {
        if (error) {
          throw error;
        }

        // Process response
        var photos = [];
        while (response.Contents.length > 0) {
          var photoObject = response.Contents.pop();

          if (photoObject.Key !== "photos/") {
            var photo = new Photo({
              key          : photoObject.Key,
              dateModified : photoObject.LastModified
            });

            photos.push(photo);
          }
        }

        callback(null, photos);
      }
      catch (_error) {
        callback (_error, null);
      }
    });
  };

  return Photo;
})();<|endoftext|>


<commit_before>module.exports = app => {
    return {
        findAll: (params, callback) => {
            return callback([
                {title: "Go Shopping"},
                {title: "Fix notebook"},
            ]);
        }
    };
};
<commit_msg>added models for tasks<commit_after>module.exports = (sequelize, DataType) => {
    const Tasks = sequelize.define("Tasks", {
        id: {
            type: DataType.INTEGER,
            primaryKey: true,
            autoIncrement: true
        },
        title: {
            type: DataType.STRING,
            allowNull: false,
            validate: {
                notEmpty: true
            }
        },
        done: {
            type: DataType.BOOLEAN,
            allowNull: false,
            defaultValue: false
        }
    }, {
        classMethods: {
            associate: (models) => {
                Tasks.belongsTo(models.Users);
                }
            }
        }
    });
    return Tasks;
};

<|endoftext|>


<commit_before>const pipe = require('1-liners/pipe');
const identity = require('1-liners/identity');

export default (plugins) => {
  const transform = plugins.reduce(pipe, identity);
  return (input) => {
    const inputData = input.map((data) => ({data}));
    return transform(inputData);
  };
};
<commit_msg>Update data signature<commit_after>const pipe = require('1-liners/pipe');
const identity = require('1-liners/identity');

export default (plugins) => {
  const transform = plugins.reduce(pipe, identity);
  return (doxOutput) => {
    const input = {
      chunks: doxOutput.map((data) => ({data})),
      version: '1',
      error: null,
    };

    return transform(input);
  };
};
<|endoftext|>


<commit_before>var common = require('./lib/common.js');

module.exports = require('./lib/module.js').module({});

// SAFETY NET (kills the process and the spawns)
process.on('uncaughtException', function (err) {
  common.fatal(err);
});

var sig_handler = function() {
  common.exit(0);
};
process.on('SIGHUP', sig_handler);
process.on('SIGINT', sig_handler);
process.on('SIGQUIT', sig_handler);
process.on('SIGABRT', sig_handler);
process.on('SIGTERM', sig_handler);

<commit_msg>Expose common.js through the breach_module package<commit_after>var common = require('./lib/common.js');

module.exports = require('./lib/module.js').module({});
module.exports.common = common;

// SAFETY NET (kills the process and the spawns)
process.on('uncaughtException', function (err) {
  common.fatal(err);
});

var sig_handler = function() {
  common.exit(0);
};
process.on('SIGHUP', sig_handler);
process.on('SIGINT', sig_handler);
process.on('SIGQUIT', sig_handler);
process.on('SIGABRT', sig_handler);
process.on('SIGTERM', sig_handler);

<|endoftext|>


<commit_before>const convert = require('node-unit-conversion');

function parse_316(data) {
	let parse = {
		arbid     : '0x316',
		msg       : data.msg_f,
		rpm       : parseFloat((parseInt('0x' + data.msg[3].toString(16) + data.msg[2].toString(16)) / 6.4).toFixed(0)),
		ac_clutch : bitmask.test(data.msg[0], 0x40),
		key       : {
			acc   : bitmask.test(data.msg[0], 0x01),
			run   : bitmask.test(data.msg[0], 0x04),
			start : bitmask.test(data.msg[0], 0x10),
		},
		torque : {
			after_interventions  : parseFloat((data.msg[1] / 2.54).toFixed(1)),
			before_interventions : parseFloat((data.msg[4] / 2.54).toFixed(1)),
			loss                 : parseFloat((data.msg[5] / 2.54).toFixed(1)),
			output               : parseFloat((data.msg[7] / 2.54).toFixed(1)),
		},
	};

	// Occasionally the RPM is parses as something less than 50.. no idea why
	if (parse.rpm > 300) update.status('engine.speed', parse.rpm, false);

	update.status('engine.ac_clutch', parse.ac_clutch);

	update.status('engine.torque.after_interventions',  parse.torque.after_interventions,  false);
	update.status('engine.torque.before_interventions', parse.torque.before_interventions, false);
	update.status('engine.torque.loss',                 parse.torque.loss,                 false);
	update.status('engine.torque.output',               parse.torque.output,               false);
}

function parse_329(data) {
	let parse = {
		msg    : '0x329',
		engine : {
			throttle : {
				cruise : parseFloat((data.msg[4] / 2.54).toFixed(2)),
				pedal  : parseFloat((data.msg[5] / 2.54).toFixed(2)),
			},
			atmospheric_pressure : {
				mbar : (data.msg[2] * 2) + 597,
				mmhg : null,
				psi  : null,
			},
		},
		temperature : {
			coolant : {
				c : parseFloat(((data.msg[1] * 0.75) - 48.373).toFixed(2)),
				f : null,
			},
		},
		vehicle : {
			brake    : bitmask.test(data.msg[6], 0x01),
			clutch   : bitmask.test(data.msg[3], 0x01),
			kickdown : bitmask.test(data.msg[6], 0x08),
			cruise   : {
				button : {
					resume : bitmask.test(data.msg[3], 0x40) && bitmask.test(data.msg[3], 0x20),
					minus  : bitmask.test(data.msg[3], 0x40) && !bitmask.test(data.msg[3], 0x20),
					onoff  : bitmask.test(data.msg[3], 0x80),
					plus   : bitmask.test(data.msg[3], 0x20) && !bitmask.test(data.msg[3], 0x40),
					unk1   : bitmask.test(data.msg[3], 0x01),
				},
				status : {
					activating : bitmask.test(data.msg[6], 0x20),
					active     : bitmask.test(data.msg[6], 0x08),
					resume     : bitmask.test(data.msg[6], 0x10),
					unk1       : bitmask.test(data.msg[6], 0x01),
				},
			},
		},
	};

	// Calculate mmhg and psi atmospheric pressure values
	parse.engine.atmospheric_pressure.mmhg = parseFloat((parse.engine.atmospheric_pressure.mbar * 0.75006157818041).toFixed(2));
	parse.engine.atmospheric_pressure.psi  = parseFloat((parse.engine.atmospheric_pressure.mbar * 0.01450377380072).toFixed(2));

	// Calculate fahrenheit temperature values
	parse.temperature.coolant.f = parseFloat(convert(parse.temperature.coolant.c).from('celsius').to('fahrenheit'));

	// Round temperature values
	parse.temperature.coolant.c = Math.round(parse.temperature.coolant.c);
	parse.temperature.coolant.f = Math.round(parse.temperature.coolant.f);

	// Update status object
	update.status('engine.atmospheric_pressure.mbar', parse.engine.atmospheric_pressure.mbar);
	update.status('engine.atmospheric_pressure.mmhg', parse.engine.atmospheric_pressure.mmhg);
	update.status('engine.atmospheric_pressure.psi',  parse.engine.atmospheric_pressure.psi);

	update.status('vehicle.cruise.button.minus', parse.vehicle.cruise.button.minus);
	update.status('vehicle.cruise.button.onoff', parse.vehicle.cruise.button.onoff);
	update.status('vehicle.cruise.button.plus',  parse.vehicle.cruise.button.plus);
	update.status('vehicle.cruise.button.unk1',  parse.vehicle.cruise.button.unk1);

	update.status('vehicle.cruise.status.activating', parse.vehicle.cruise.status.activating);
	update.status('vehicle.cruise.status.active',     parse.vehicle.cruise.status.active);
	update.status('vehicle.cruise.status.resume',     parse.vehicle.cruise.status.resume);
	update.status('vehicle.cruise.status.unk1',       parse.vehicle.cruise.status.unk1);

	update.status('engine.throttle.cruise', parse.engine.throttle.cruise);
	update.status('engine.throttle.pedal',  parse.engine.throttle.pedal);

	update.status('temperature.coolant.f', parse.temperature.coolant.f);

	// Trigger a HUD refresh if coolant temp is updated
	if (update.status('temperature.coolant.c', parse.temperature.coolant.c)) IKE.hud_refresh();

	update.status('vehicle.brake',  parse.vehicle.brake);
	update.status('vehicle.clutch', parse.vehicle.clutch);
}

function parse_545(data) {
	let consumption_current = parseFloat((parseInt('0x' + data.msg[2].toString(16) + data.msg[1].toString(16))).toFixed(0));

	if (consumption_current === DME1.consumption_last) return;

	let parse = {
		msg  : '0x545',
		fuel : {
			consumption : consumption_current - DME1.consumption_last,
		},
	};

	DME1.consumption_last = consumption_current;

	// update.status('fuel.consumption', parse.fuel.consumption);
}

function parse_613(data) {
	let parse = {
		msg  : '0x613',
		fuel : {
			level  : null,
			liters : (data.msg[2] >= 0x80) && data.msg[2] - 0x80 || data.msg[2],
		},
	};

	parse.fuel.level = Math.round((parse.fuel.liters / config.fuel.liters_max) * 100);
	if (parse.fuel.level < 0)   parse.fuel.level = 0;
	if (parse.fuel.level > 100) parse.fuel.level = 100;

	update.status('fuel.level',  parse.fuel.level);
	update.status('fuel.liters', parse.fuel.liters);
}

function parse_615(data) {
	let parse = {
		msg    : '0x615',
		engine : {
			ac_request    : data.msg[0],
			aux_fan_speed : data.msg[1],
		},
		temperature : {
			exterior : {
				c : (data.msg[3] >= 0x80) && data.msg[3] - 0x80 || data.msg[3],
				f : null,
			},
			// This isn't right
			intake : {
				c : (data.msg[6] >= 0x80) && data.msg[6] - 0x80 || data.msg[6],
				f : null,
			},
		},
		vehicle : {
			handbrake : bitmask.test(data.msg[4], 0x02),
		},
	};

	// Calculate fahrenheit temperature values
	parse.temperature.exterior.f = parseFloat(convert(parse.temperature.exterior.c).from('celsius').to('fahrenheit'));
	parse.temperature.intake.f   = parseFloat(convert(parse.temperature.intake.c).from('celsius').to('fahrenheit'));

	// Round temperature values
	parse.temperature.exterior.c = Math.round(parse.temperature.exterior.c);
	parse.temperature.exterior.f = Math.round(parse.temperature.exterior.f);
	parse.temperature.intake.c   = Math.round(parse.temperature.intake.c);
	parse.temperature.intake.f   = Math.round(parse.temperature.intake.f);

	// Update status object
	update.status('engine.ac_request',    parse.engine.ac_request);
	update.status('engine.aux_fan_speed', parse.engine.aux_fan_speed);

	update.status('temperature.exterior.c', parse.temperature.exterior.c);
	update.status('temperature.exterior.f', parse.temperature.exterior.f);

	update.status('vehicle.handbrake', parse.vehicle.handbrake);

	// update.status('temperature.intake.c', parse.temperature.intake.c);
	// update.status('temperature.intake.f', parse.temperature.intake.f);
}

// Parse data sent from module
function parse_out(data) {
	data.command = 'bro';

	switch (data.src.id) {
		case 0x316:
			data.value = 'AC clutch/Throttle/RPM';
			parse_316(data);
			break;

		case 0x329:
			data.value = 'Temp/Brake pedal depressed/Throttle position';
			parse_329(data);
			break;

		case 0x545:
			parse_545(data);
			data.value = 'CEL/Fuel cons/Overheat/Oil temp/Charging/Brake light switch/Cruise control';
			break;

		case 0x610:
			data.value = 'VIN/info';
			break;

		case 0x613:
			data.value = 'Odometer/Running clock/Fuel level [0x615 ACK]';
			parse_613(data);
			break;

		case 0x615:
			data.value = 'A/C request/Outside air temp/Intake air temp/Parking brake/door contacts';
			parse_615(data);
			break;

		default:
			data.value = data.src.id.toString(16);
	}

	// log.bus(data);
}

module.exports = {
	consumption_last : 0,

	parse_out : (data) => { parse_out(data); },
};
<commit_msg>Update<commit_after>const convert = require('node-unit-conversion');

function parse_316(data) {
	let parse = {
		arbid     : '0x316',
		msg       : data.msg_f,
		rpm       : parseFloat((parseInt('0x' + data.msg[3].toString(16) + data.msg[2].toString(16)) / 6.4).toFixed(0)),
		ac_clutch : bitmask.test(data.msg[0], 0x40),
		key       : {
			acc   : bitmask.test(data.msg[0], 0x01),
			run   : bitmask.test(data.msg[0], 0x04),
			start : bitmask.test(data.msg[0], 0x10),
		},
		torque : {
			after_interventions  : parseFloat((data.msg[1] / 2.54).toFixed(1)),
			before_interventions : parseFloat((data.msg[4] / 2.54).toFixed(1)),
			loss                 : parseFloat((data.msg[5] / 2.54).toFixed(1)),
			output               : parseFloat((data.msg[7] / 2.54).toFixed(1)),
		},
	};

	// Occasionally the RPM is parses as something less than 50.. no idea why
	if (parse.rpm > 100 && parse.rpm !== 0) update.status('engine.speed', parse.rpm, false);

	update.status('engine.ac_clutch', parse.ac_clutch);

	update.status('engine.torque.after_interventions',  parse.torque.after_interventions,  false);
	update.status('engine.torque.before_interventions', parse.torque.before_interventions, false);
	update.status('engine.torque.loss',                 parse.torque.loss,                 false);
	update.status('engine.torque.output',               parse.torque.output,               false);
}

function parse_329(data) {
	let parse = {
		msg    : '0x329',
		engine : {
			throttle : {
				cruise : parseFloat((data.msg[4] / 2.54).toFixed(2)),
				pedal  : parseFloat((data.msg[5] / 2.54).toFixed(2)),
			},
			atmospheric_pressure : {
				mbar : (data.msg[2] * 2) + 597,
				mmhg : null,
				psi  : null,
			},
		},
		temperature : {
			coolant : {
				c : parseFloat(((data.msg[1] * 0.75) - 48.373).toFixed(2)),
				f : null,
			},
		},
		vehicle : {
			brake    : bitmask.test(data.msg[6], 0x01),
			clutch   : bitmask.test(data.msg[3], 0x01),
			kickdown : bitmask.test(data.msg[6], 0x08),
			cruise   : {
				button : {
					resume : bitmask.test(data.msg[3], 0x40) && bitmask.test(data.msg[3], 0x20),
					minus  : bitmask.test(data.msg[3], 0x40) && !bitmask.test(data.msg[3], 0x20),
					onoff  : bitmask.test(data.msg[3], 0x80),
					plus   : bitmask.test(data.msg[3], 0x20) && !bitmask.test(data.msg[3], 0x40),
					unk1   : bitmask.test(data.msg[3], 0x01),
				},
				status : {
					activating : bitmask.test(data.msg[6], 0x20),
					active     : bitmask.test(data.msg[6], 0x08),
					resume     : bitmask.test(data.msg[6], 0x10),
					unk1       : bitmask.test(data.msg[6], 0x01),
				},
			},
		},
	};

	// Calculate mmhg and psi atmospheric pressure values
	parse.engine.atmospheric_pressure.mmhg = parseFloat((parse.engine.atmospheric_pressure.mbar * 0.75006157818041).toFixed(2));
	parse.engine.atmospheric_pressure.psi  = parseFloat((parse.engine.atmospheric_pressure.mbar * 0.01450377380072).toFixed(2));

	// Calculate fahrenheit temperature values
	parse.temperature.coolant.f = parseFloat(convert(parse.temperature.coolant.c).from('celsius').to('fahrenheit'));

	// Round temperature values
	parse.temperature.coolant.c = Math.round(parse.temperature.coolant.c);
	parse.temperature.coolant.f = Math.round(parse.temperature.coolant.f);

	// Update status object
	update.status('engine.atmospheric_pressure.mbar', parse.engine.atmospheric_pressure.mbar);
	update.status('engine.atmospheric_pressure.mmhg', parse.engine.atmospheric_pressure.mmhg);
	update.status('engine.atmospheric_pressure.psi',  parse.engine.atmospheric_pressure.psi);

	update.status('vehicle.cruise.button.minus', parse.vehicle.cruise.button.minus);
	update.status('vehicle.cruise.button.onoff', parse.vehicle.cruise.button.onoff);
	update.status('vehicle.cruise.button.plus',  parse.vehicle.cruise.button.plus);
	update.status('vehicle.cruise.button.unk1',  parse.vehicle.cruise.button.unk1);

	update.status('vehicle.cruise.status.activating', parse.vehicle.cruise.status.activating);
	update.status('vehicle.cruise.status.active',     parse.vehicle.cruise.status.active);
	update.status('vehicle.cruise.status.resume',     parse.vehicle.cruise.status.resume);
	update.status('vehicle.cruise.status.unk1',       parse.vehicle.cruise.status.unk1);

	update.status('engine.throttle.cruise', parse.engine.throttle.cruise);
	update.status('engine.throttle.pedal',  parse.engine.throttle.pedal);

	update.status('temperature.coolant.f', parse.temperature.coolant.f);

	// Trigger a HUD refresh if coolant temp is updated
	if (update.status('temperature.coolant.c', parse.temperature.coolant.c)) IKE.hud_refresh();

	update.status('vehicle.brake',  parse.vehicle.brake);
	update.status('vehicle.clutch', parse.vehicle.clutch);
}

function parse_545(data) {
	let consumption_current = parseFloat((parseInt('0x' + data.msg[2].toString(16) + data.msg[1].toString(16))).toFixed(0));

	if (consumption_current === DME1.consumption_last) return;

	let parse = {
		msg  : '0x545',
		fuel : {
			consumption : consumption_current - DME1.consumption_last,
		},
	};

	DME1.consumption_last = consumption_current;

	// update.status('fuel.consumption', parse.fuel.consumption);
}

function parse_613(data) {
	let parse = {
		msg  : '0x613',
		fuel : {
			level  : null,
			liters : (data.msg[2] >= 0x80) && data.msg[2] - 0x80 || data.msg[2],
		},
	};

	parse.fuel.level = Math.round((parse.fuel.liters / config.fuel.liters_max) * 100);
	if (parse.fuel.level < 0)   parse.fuel.level = 0;
	if (parse.fuel.level > 100) parse.fuel.level = 100;

	update.status('fuel.level',  parse.fuel.level);
	update.status('fuel.liters', parse.fuel.liters);
}

function parse_615(data) {
	let parse = {
		msg    : '0x615',
		engine : {
			ac_request    : data.msg[0],
			aux_fan_speed : data.msg[1],
		},
		temperature : {
			exterior : {
				c : (data.msg[3] >= 0x80) && data.msg[3] - 0x80 || data.msg[3],
				f : null,
			},
			// This isn't right
			intake : {
				c : (data.msg[6] >= 0x80) && data.msg[6] - 0x80 || data.msg[6],
				f : null,
			},
		},
		vehicle : {
			handbrake : bitmask.test(data.msg[4], 0x02),
		},
	};

	// Calculate fahrenheit temperature values
	parse.temperature.exterior.f = parseFloat(convert(parse.temperature.exterior.c).from('celsius').to('fahrenheit'));
	parse.temperature.intake.f   = parseFloat(convert(parse.temperature.intake.c).from('celsius').to('fahrenheit'));

	// Round temperature values
	parse.temperature.exterior.c = Math.round(parse.temperature.exterior.c);
	parse.temperature.exterior.f = Math.round(parse.temperature.exterior.f);
	parse.temperature.intake.c   = Math.round(parse.temperature.intake.c);
	parse.temperature.intake.f   = Math.round(parse.temperature.intake.f);

	// Update status object
	update.status('engine.ac_request',    parse.engine.ac_request);
	update.status('engine.aux_fan_speed', parse.engine.aux_fan_speed);

	update.status('temperature.exterior.c', parse.temperature.exterior.c);
	update.status('temperature.exterior.f', parse.temperature.exterior.f);

	update.status('vehicle.handbrake', parse.vehicle.handbrake);

	// update.status('temperature.intake.c', parse.temperature.intake.c);
	// update.status('temperature.intake.f', parse.temperature.intake.f);
}

// Parse data sent from module
function parse_out(data) {
	data.command = 'bro';

	switch (data.src.id) {
		case 0x316:
			data.value = 'AC clutch/Throttle/RPM';
			parse_316(data);
			break;

		case 0x329:
			data.value = 'Temp/Brake pedal depressed/Throttle position';
			parse_329(data);
			break;

		case 0x545:
			parse_545(data);
			data.value = 'CEL/Fuel cons/Overheat/Oil temp/Charging/Brake light switch/Cruise control';
			break;

		case 0x610:
			data.value = 'VIN/info';
			break;

		case 0x613:
			data.value = 'Odometer/Running clock/Fuel level [0x615 ACK]';
			parse_613(data);
			break;

		case 0x615:
			data.value = 'A/C request/Outside air temp/Intake air temp/Parking brake/door contacts';
			parse_615(data);
			break;

		default:
			data.value = data.src.id.toString(16);
	}

	// log.bus(data);
}

module.exports = {
	consumption_last : 0,

	parse_out : (data) => { parse_out(data); },
};
<|endoftext|>


<commit_before>var parseDiceSpec = function (specString) {
    var rawSpec = specString.valMatch(/^([0-9]*)d(%|[0-9]*)(|[+-][0-9]+)$/i, 4);
    if (rawSpec !== false) {
        if (rawSpec[2] === "%") {
            rawSpec[2] = 100;
        }
        return {
            "count": parseInt(rawSpec[1] || 1),
            "sides": parseInt(rawSpec[2] || 6),
            "modifier": parseInt(rawSpec[3] || 0)
        };
    } else {
        return false;
    }
};

var normalizeDiceSpec = function (specString) {
    var diceSpec = parseDiceSpec(specString);

    if (diceSpec["count"] > 1) {
        var count = diceSpec["count"];
    } else {
        var count = "";
    }

    if (diceSpec["sides"] === 100) {
        var sides = "%";
    } else {
        var sides = diceSpec["sides"];
    }

    if (diceSpec["modifier"] > 0) {
        var modifier = "+" + diceSpec["modifier"];
    } else if (diceSpec["modifier"] < 0) {
        var modifier = diceSpec["modifier"];
    } else {
        var modifier = "";
    }

    return (count + "d" + sides + modifier);
};

var dice = function(dbot) {
    var commands = {
        '~roll': function (event) {
            var rolls = [];

            if (event.params.length === 1) {
                event.params.push("d6");
            }

            for (var i = 1; i < event.params.length; i++) {
                var diceSpec = parseDiceSpec(event.params[i]);
                if (diceSpec === false) {
                    rolls.push([event.params[i], false]);
                } else {
                    rolls.push([normalizeDiceSpec(event.params[i]), [], diceSpec["modifier"]]);
                    for (var j = 0; j < diceSpec["count"] ; j++) {
                        rolls[rolls.length-1][1].push(Math.ceil(Math.random() * diceSpec["sides"]));
                    }
                }
            }

            for (var i = 0; i < rolls.length; i++) {
                if (rolls[i][1] === false) {
                    event.reply(rolls[i][0] + ": invalid dice spec");
                } else {
                    if (rolls[i][1].length > 1) {
                        var total = " (total " + rolls[i][1].sum();
                        if (rolls[i][2] != 0) {
                            if (rolls[i][2] > 0) {
                                total += " + ";
                            } else {
                                total += " - ";
                            }
                            total += Math.abs(rolls[i][2]) + " -> " + (rolls[i][1].sum() + rolls[i][2]);
                        }
                        total += ")"
                    } else {
                        var total = "";
                    }
                    event.reply(rolls[i][0] + ": " + rolls[i][1].join(" ") + total);
                }
            }
        }
    };

    return {
        'onLoad': function() {
            return commands;
        },

        'name': 'dice',

        'ignorable': true
    };
}

exports.fetch = function(dbot) {
    return dice(dbot);
};
<commit_msg>dice uses new command return<commit_after>var parseDiceSpec = function (specString) {
    var rawSpec = specString.valMatch(/^([0-9]*)d(%|[0-9]*)(|[+-][0-9]+)$/i, 4);
    if (rawSpec !== false) {
        if (rawSpec[2] === "%") {
            rawSpec[2] = 100;
        }
        return {
            "count": parseInt(rawSpec[1] || 1),
            "sides": parseInt(rawSpec[2] || 6),
            "modifier": parseInt(rawSpec[3] || 0)
        };
    } else {
        return false;
    }
};

var normalizeDiceSpec = function (specString) {
    var diceSpec = parseDiceSpec(specString);

    if (diceSpec["count"] > 1) {
        var count = diceSpec["count"];
    } else {
        var count = "";
    }

    if (diceSpec["sides"] === 100) {
        var sides = "%";
    } else {
        var sides = diceSpec["sides"];
    }

    if (diceSpec["modifier"] > 0) {
        var modifier = "+" + diceSpec["modifier"];
    } else if (diceSpec["modifier"] < 0) {
        var modifier = diceSpec["modifier"];
    } else {
        var modifier = "";
    }

    return (count + "d" + sides + modifier);
};

var dice = function(dbot) {
    var commands = {
        '~roll': function (event) {
            var rolls = [];

            if (event.params.length === 1) {
                event.params.push("d6");
            }

            for (var i = 1; i < event.params.length; i++) {
                var diceSpec = parseDiceSpec(event.params[i]);
                if (diceSpec === false) {
                    rolls.push([event.params[i], false]);
                } else {
                    rolls.push([normalizeDiceSpec(event.params[i]), [], diceSpec["modifier"]]);
                    for (var j = 0; j < diceSpec["count"] ; j++) {
                        rolls[rolls.length-1][1].push(Math.ceil(Math.random() * diceSpec["sides"]));
                    }
                }
            }

            for (var i = 0; i < rolls.length; i++) {
                if (rolls[i][1] === false) {
                    event.reply(rolls[i][0] + ": invalid dice spec");
                } else {
                    if (rolls[i][1].length > 1) {
                        var total = " (total " + rolls[i][1].sum();
                        if (rolls[i][2] != 0) {
                            if (rolls[i][2] > 0) {
                                total += " + ";
                            } else {
                                total += " - ";
                            }
                            total += Math.abs(rolls[i][2]) + " -> " + (rolls[i][1].sum() + rolls[i][2]);
                        }
                        total += ")"
                    } else {
                        var total = "";
                    }
                    event.reply(rolls[i][0] + ": " + rolls[i][1].join(" ") + total);
                }
            }
        }
    };

    return {
        'name': 'dice',
        'commands': commands,
        'ignorable': true
    };
}

exports.fetch = function(dbot) {
    return dice(dbot);
};
<|endoftext|>


<commit_before>var fs = require("fs");
var gpioPath = '/sys/class/gpio/';

/**
 *  changes the value of an entry within the gpio-export.
 *  For more Details of available params, see
 *  https://www.kernel.org/doc/Documentation/gpio/sysfs.txt
 *
 */
function setGpioValue(pin, param, value, runAfter) {
  fs.writeFile(gpioPath + "gpio" + pin + "/" + param, value, function (err) {
    if (err) throw "Error trying to set the value for " + param + " of pin " + pin + " to " + value + " : " + err;
    console.log("Changed " + param + " of Pin " + pin + " to " + value);
    if (runAfter) runAfter();
	 });
}

/**
 * initializes a pin by writing the pinnumber to /sys/class/gpio/export
 * and setting the direction to out
 */
function initPin(pin, runAfter) {
  fs.writeFile(gpioPath + "export", pin, function (err) {
    if (err) throw "Error trying to create the pin " + pin + ":" + err;
    fs.exists(gpioPath + "gpio" + pin + "/value", function (exists) {
       if (!exists) throw "The pin "+pin+" could not be initialized. The Directory "+fs.realpathSync(gpioPath + "gpio" + pin)+" does not exist!";
       setGpioValue(pin, "direction", "out", runAfter);
    });
  });
}

/**
 * checks if the pin was exported and initializes if not
 */
function checkPin(pin, runAfter) {
  fs.exists(gpioPath + "gpio" + pin + "/value", function (exists) {
    if (exists)
		    runAfter();
    else
		    initPin(pin, runAfter);
  });
}

/**
 * called from the eventbus whenever we receive a event to change the state of a device
 */
function changeState(arg) {
  if (!arg.config.gpio) return;

  console.log('GPIO : open ' + arg.id + "=" + arg.open);
  checkPin(arg.config.gpio, function () {
    setGpioValue(arg.config.gpio, "value", arg.open ? 0 : 1, function() {
      arg.sender.events.emit("changedState", arg);
    });
  });
}

/**
 * only for tests in order to read the set value.
 */
function getGpioValue(pin, param) {
   return fs.readFileSync(gpioPath + "gpio" + pin + "/" + param);
}

/**
 * constructor function which registers the changeState-event
 */
module.exports = function () {
  this.getGpioValue = getGpioValue;
  this.init = function (arg) {
    console.log("Start GPIO ...");
    arg.events.on('changeState', changeState);
  };
};
<commit_msg>fixed buffer<commit_after>var fs = require("fs");
var gpioPath = '/sys/class/gpio/';

/**
 *  changes the value of an entry within the gpio-export.
 *  For more Details of available params, see
 *  https://www.kernel.org/doc/Documentation/gpio/sysfs.txt
 *
 */
function setGpioValue(pin, param, value, runAfter) {
  fs.writeFile(gpioPath + "gpio" + pin + "/" + param, value, function (err) {
    if (err) throw "Error trying to set the value for " + param + " of pin " + pin + " to " + value + " : " + err;
    console.log("Changed " + param + " of Pin " + pin + " to " + value);
    if (runAfter) runAfter();
	 });
}

/**
 * initializes a pin by writing the pinnumber to /sys/class/gpio/export
 * and setting the direction to out
 */
function initPin(pin, runAfter) {
  fs.writeFile(gpioPath + "export", pin, function (err) {
    if (err) throw "Error trying to create the pin " + pin + ":" + err;
    fs.exists(gpioPath + "gpio" + pin + "/value", function (exists) {
       if (!exists) throw "The pin "+pin+" could not be initialized. The Directory "+fs.realpathSync(gpioPath + "gpio" + pin)+" does not exist!";
       setGpioValue(pin, "direction", "out", runAfter);
    });
  });
}

/**
 * checks if the pin was exported and initializes if not
 */
function checkPin(pin, runAfter) {
  fs.exists(gpioPath + "gpio" + pin + "/value", function (exists) {
    if (exists)
		    runAfter();
    else
		    initPin(pin, runAfter);
  });
}

/**
 * called from the eventbus whenever we receive a event to change the state of a device
 */
function changeState(arg) {
  if (!arg.config.gpio) return;

  console.log('GPIO : open ' + arg.id + "=" + arg.open);
  checkPin(arg.config.gpio, function () {
    setGpioValue(arg.config.gpio, "value", arg.open ? 0 : 1, function() {
      arg.sender.events.emit("changedState", arg);
    });
  });
}

/**
 * only for tests in order to read the set value.
 */
function getGpioValue(pin, param) {
   return fs.readFileSync(gpioPath + "gpio" + pin + "/" + param, "utf8");
}

/**
 * constructor function which registers the changeState-event
 */
module.exports = function () {
  this.getGpioValue = getGpioValue;
  this.init = function (arg) {
    console.log("Start GPIO ...");
    arg.events.on('changeState', changeState);
  };
};
<|endoftext|>


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

var BASE = 'extensions.auto-confirm@myokoym.net.';
var prefs = require('lib/prefs').prefs;
{
  if (prefs.getDefaultPref(BASE + 'debug') === null)
    prefs.setDefaultPref(BASE + 'debug', false);
}

var log = require('log').log;

var generalUrls = [];
var generalConfigs = [];

function updateConfigs() {
  log("updateConfigs");
  generalUrls = [];
  generalConfigs = [];
  var configs = prefs.getChildren(BASE + 'general');
  for (let config of configs) {
    log(config);
    let url = prefs.getPref(config + '.url');
    if (!url)
      continue;
    generalUrls.push(url);
    generalConfigs.push({
      text:    prefs.getPref(config + '.text'),
      title:   prefs.getPref(config + '.title'),
      action:  prefs.getPref(config + '.action'),
      actions: prefs.getPref(config + '.actions')
    });
  }
  log(JSON.stringify(generalUrls));
  log(JSON.stringify(generalConfigs));
}
updateConfigs();

var timer = Cu.import('resource://gre/modules/Timer.jsm', {});
var updateConfigsTimer;
var listener = {
  domains : [
    BASE + 'general'
  ],
  observe : function(aSubject, aTopic, aData)
  {
    log("observe: start");
    if (aTopic != 'nsPref:changed')
      return;
    log(updateConfigsTimer);
    if (updateConfigsTimer)
      timer.clearTimeout(updateConfigsTimer);
    updateConfigsTimer = timer.setTimeout(function() {
      updateConfigs();
      delete updateConfigsTimer;
    }, 100);
    log("observe: end");
  }
};
prefs.addPrefListener(listener);

prefs.setPref(BASE + 'editing', false);

load('lib/WindowManager');

var TYPE_BROWSER = "navigator:browser";

var global = this;
function handleWindow(aWindow)
{
  log(prefs.getPref(BASE + 'editing'));
  if (prefs.getPref(BASE + 'editing')) {
    return;
  }

  log("handleWindow");
  var doc = aWindow.document;
  if (doc.documentElement.localName === 'dialog' &&
      doc.documentElement.id === 'commonDialog') {
    log("commonDialog");
    handleCommonDialog(aWindow);
    return;
  } else {
    log("generalWindow");
    if (doc.documentElement.getAttribute("windowtype") === TYPE_BROWSER) {
      startObserveTabModalDialogs(aWindow);
    }
    aWindow.addEventListener('load', function onload() {
      aWindow.removeEventListener('load', onload);
      handleGeneralWindow(aWindow);
    });
    return;
  }

}

function handleCommonDialog(aWindow, aRootElement)
{
  var doc = aWindow.document;
  var root = aRootElement /* for tabmodaldialog */ ||
               doc.documentElement /* for common dialog */;
  var commonDialog = root.Dialog /* for tabmodaldialog */ ||
                       aWindow.Dialog /* for common dialog */;
  if (!commonDialog) {
    log("missing common dialog");
    return;
  }
  var args = commonDialog.args;
  log("args: " + JSON.stringify(args));
  var configs = prefs.getChildren(BASE + 'common');
  log("commonDialog: " + configs);
  var matched = false;
  for (let config of configs) {
    let typeMatcher = prefs.getPref(config + '.type');
    if (typeMatcher !== normalizeType(args.promptType))
      continue;
    let textMatcher = prefs.getPref(config + '.text');
    if (textMatcher && !args.text.match(textMatcher))
      continue;
    let titleMatcher = prefs.getPref(config + '.title');
    if (titleMatcher && !args.title.match(titleMatcher))
      continue;

    matched = true;
    log("config: " + config);
    let action = prefs.getPref(config + '.action');
    if (action)
      processAction(aWindow, action, aRootElement);
    let actions = prefs.getPref(config + '.actions');
    if (actions)
      processActions(aWindow, actions, aRootElement);
  }
  if (!matched)
    log("no match");
}

function normalizeType(aType)
{
  switch (aType) {
    case 'alertCheck':
      return 'alert';
    case 'confirmCheck':
      return 'confirm';
    default:
      return aType;
  }
}

function handleGeneralWindow(aWindow)
{
  var doc = aWindow.document;
  var url = aWindow.location.href;
  log("url: " + url);
  var fromIndex = 0;
  while (true) {
    log("fromIndex: " + fromIndex);
    let index = generalUrls.indexOf(url, fromIndex);
    log("index: " + index);
    if (index === -1)
      return;
    let config = generalConfigs[index];
    log("config: " + config);
    if (matchedWindow(aWindow, config)) {
      aWindow.setTimeout(function() {
        let action = config.action;
        if (action)
          processAction(aWindow, action);
        let actions = config.actions;
        if (actions)
          processActions(aWindow, actions);
      }, 500);
      return;
    }
    fromIndex = index + 1;
  }
}

function processActions(aWindow, aActions, aRootElement)
{
  var doc = aWindow.document;
  log("actions: " + aActions);
  for (let action of JSON.parse(aActions)) {
    log("action: " + action);
    processAction(aWindow, action, aRootElement);
  }
}

function processAction(aWindow, aAction, aRootElement)
{
  var doc = aWindow.document;
  var root = aRootElement /* for tabmodaldialog */ ||
               doc.documentElement /* for chrome window */;
  var commonDialog = root.Dialog /* for tabmodaldialog */ ||
                       aWindow.Dialog /* for common dialog */;
  log("action: " + aAction);
  var actions = aAction.match(/^([^;]+);?(.*)/);
  if (actions === null)
    return;
  var action = actions[1];
  var value = actions[2];
  switch (action) {
  case 'accept':
    commonDialog.ui.button0.click();
    log("accept");
    return;
  case 'cancel':
    commonDialog.ui.button1.click();
    log("cancel");
    return;
  case 'click':
    log("click");
    {
      let element = findVisibleElementByLabel(root, value);
      log(element);
      if (typeof element.click === "function") {
        log("element.click(): ready");
        element.click();
        log("element.click(): done");
      } else {
        log("element is not clickable");
        Cu.reportError(new Error("found element is not clickable."));
      }
    }
    return;
  case 'push':
    var buttons = [
      commonDialog.ui.button0,
      commonDialog.ui.button1,
      commonDialog.ui.button2,
      commonDialog.ui.button3
    ];
    for (let index in buttons) {
      var button = buttons[index];
      log("label: " + button.label);
      if (button.label.match(value)) {
        button.click();
        log("push");
        return;
      }
    }
    log("push: no match");
    return;
  case 'input':
    commonDialog.ui.loginTextbox.value = value;
    log("input");
    return;
  case 'check':
    log("check");
    if (value) {
      let element = findVisibleElementByLabel(root, value);
      log("  element: " + element);
      log("  element.checked: ready");
      element.checked = true;
      log("  element.checked: done");
    } else {
      // For commonDialog
      commonDialog.ui.checkbox.checked = true;
      commonDialog.args.checked = true;
    }
    return;
  case 'uncheck':
    log("uncheck");
    if (value) {
      let element = findVisibleElementByLabel(root, value);
      log(element);
      log("  element.checked: ready");
      element.checked = false;
      log("  element.checked: done");
    } else {
      // For commonDialog
      commonDialog.ui.checkbox.checked = true;
      commonDialog.args.checked = false;
    }
    return;
  default:
    log("no action");
    return;
  }
}

function matchedWindow(aWindow, aConfig) {
  log("matchedWindow");
  let textMatcher = aConfig.text;
  log("  textMatcher: " + textMatcher);
  if (textMatcher && !findVisibleElementByLabel(aWindow.document.documentElement, textMatcher))
    return false;
  let titleMatcher = aConfig.title;
  log("  titleMatcher: " + titleMatcher);
  let title = aWindow.document.title;
  if (titleMatcher && !title.match(titleMatcher))
    return false;

  log("  match");
  return  true;
}

function findVisibleElementByLabel(aRootElement, text) {
  log("findVisibleElementByLabel");
  if (text.indexOf('"') !== -1) {
    text = 'concat("' + text.replace(/"/g, '", \'"\', "') + '")';
  } else {
    text = '"' + text + '"';
  }
  var expression = '/descendant::*[contains(@label, ' + text + ')] | ' +
                   '/descendant::*[local-name()="label" or local-name()="description"][contains(@value, ' + text + ')] | ' +
                   '/descendant::*[contains(text(), ' + text + ')]';
  log("  expression: " + expression);
  try {
  var doc = aRootElement.ownerDocument;
  var global = doc.defaultView;
  var elements = doc.evaluate(
                   expression,
                   aRootElement,
                   null,
                   global.XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
                   null
                 );
  } catch(e) {
    log("  error: " + e);
  }
  log("  elements.length: " + elements.snapshotLength);
  for (var i = 0, maxi = elements.snapshotLength; i < maxi; i++)
  {
    let element = elements.snapshotItem(i);
    if (element.clientHeight > 0 &&
        element.clientWidth > 0) {
      return element;
    }
  }

  log("  no visible element");
  return null;
}

var tabModalDialogObservers = new WeakMap();

function handleMutationsOnBrowserWindow(aMutations, aObserver) {
  aMutations.forEach(function(aMutation) {
    if (aMutation.type !== "childList" ||
        !aMutation.addedNodes) {
      return;
    }
    Array.forEach(aMutation.addedNodes, function(aNode) {
      if (aNode.localName !== "tabmodalprompt") {
        return;
      }
      log("handle new tabmodalprompt");
      var window = aNode.ownerDocument.defaultView;
      window.setTimeout(function() {
        // operate the dialog after successfully initialized
        handleCommonDialog(window, aNode);
      }, 0);
    });
  });
}

function startObserveTabModalDialogs(aWindow) {
  var MutationObserver = aWindow.MutationObserver;
  var observer = new MutationObserver(handleMutationsOnBrowserWindow);
  observer.observe(aWindow.document.documentElement, {
    childList: true,
    subtree:   true
  });
  tabModalDialogObservers.set(aWindow, observer);
  aWindow.addEventListener("unload", function onunload() {
    aWindow.removeEventListener("unload", onunload);
    endObserveTabModalDialogs(aWindow);
  });
}

function endObserveTabModalDialogs(aWindow) {
  var observer = tabModalDialogObservers.get(aWindow);
  if (observer) {
    observer.disconnect();
    tabModalDialogObservers.delete(aWindow);
  }
}

WindowManager.getWindows(null).forEach(handleWindow);
WindowManager.addHandler(handleWindow);

function shutdown()
{
  WindowManager.getWindows(null).forEach(endObserveTabModalDialogs);
  tabModalDialogObservers = undefined;
  prefs.setPref(BASE + 'editing', false)
  prefs.removePrefListener(listener);
  WindowManager = undefined;
  global = undefined;
}
<commit_msg>Do common dialog specific operations only when Dialog is defined in the window<commit_after>/*
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

var BASE = 'extensions.auto-confirm@myokoym.net.';
var prefs = require('lib/prefs').prefs;
{
  if (prefs.getDefaultPref(BASE + 'debug') === null)
    prefs.setDefaultPref(BASE + 'debug', false);
}

var log = require('log').log;

var generalUrls = [];
var generalConfigs = [];

function updateConfigs() {
  log("updateConfigs");
  generalUrls = [];
  generalConfigs = [];
  var configs = prefs.getChildren(BASE + 'general');
  for (let config of configs) {
    log(config);
    let url = prefs.getPref(config + '.url');
    if (!url)
      continue;
    generalUrls.push(url);
    generalConfigs.push({
      text:    prefs.getPref(config + '.text'),
      title:   prefs.getPref(config + '.title'),
      action:  prefs.getPref(config + '.action'),
      actions: prefs.getPref(config + '.actions')
    });
  }
  log(JSON.stringify(generalUrls));
  log(JSON.stringify(generalConfigs));
}
updateConfigs();

var timer = Cu.import('resource://gre/modules/Timer.jsm', {});
var updateConfigsTimer;
var listener = {
  domains : [
    BASE + 'general'
  ],
  observe : function(aSubject, aTopic, aData)
  {
    log("observe: start");
    if (aTopic != 'nsPref:changed')
      return;
    log(updateConfigsTimer);
    if (updateConfigsTimer)
      timer.clearTimeout(updateConfigsTimer);
    updateConfigsTimer = timer.setTimeout(function() {
      updateConfigs();
      delete updateConfigsTimer;
    }, 100);
    log("observe: end");
  }
};
prefs.addPrefListener(listener);

prefs.setPref(BASE + 'editing', false);

load('lib/WindowManager');

var TYPE_BROWSER = "navigator:browser";

var global = this;
function handleWindow(aWindow)
{
  log(prefs.getPref(BASE + 'editing'));
  if (prefs.getPref(BASE + 'editing')) {
    return;
  }

  log("handleWindow");
  var doc = aWindow.document;
  if (doc.documentElement.localName === 'dialog' &&
      doc.documentElement.id === 'commonDialog') {
    log("commonDialog");
    handleCommonDialog(aWindow);
    return;
  } else {
    log("generalWindow");
    if (doc.documentElement.getAttribute("windowtype") === TYPE_BROWSER) {
      startObserveTabModalDialogs(aWindow);
    }
    aWindow.addEventListener('load', function onload() {
      aWindow.removeEventListener('load', onload);
      handleGeneralWindow(aWindow);
    });
    return;
  }

}

function handleCommonDialog(aWindow, aRootElement)
{
  var doc = aWindow.document;
  var root = aRootElement /* for tabmodaldialog */ ||
               doc.documentElement /* for common dialog */;
  var commonDialog = root.Dialog /* for tabmodaldialog */ ||
                       aWindow.Dialog /* for common dialog */;
  if (!commonDialog) {
    log("missing common dialog");
    return;
  }
  var args = commonDialog.args;
  log("args: " + JSON.stringify(args));
  var configs = prefs.getChildren(BASE + 'common');
  log("commonDialog: " + configs);
  var matched = false;
  for (let config of configs) {
    let typeMatcher = prefs.getPref(config + '.type');
    if (typeMatcher !== normalizeType(args.promptType))
      continue;
    let textMatcher = prefs.getPref(config + '.text');
    if (textMatcher && !args.text.match(textMatcher))
      continue;
    let titleMatcher = prefs.getPref(config + '.title');
    if (titleMatcher && !args.title.match(titleMatcher))
      continue;

    matched = true;
    log("config: " + config);
    let action = prefs.getPref(config + '.action');
    if (action)
      processAction(aWindow, action, aRootElement);
    let actions = prefs.getPref(config + '.actions');
    if (actions)
      processActions(aWindow, actions, aRootElement);
  }
  if (!matched)
    log("no match");
}

function normalizeType(aType)
{
  switch (aType) {
    case 'alertCheck':
      return 'alert';
    case 'confirmCheck':
      return 'confirm';
    default:
      return aType;
  }
}

function handleGeneralWindow(aWindow)
{
  var doc = aWindow.document;
  var url = aWindow.location.href;
  log("url: " + url);
  var fromIndex = 0;
  while (true) {
    log("fromIndex: " + fromIndex);
    let index = generalUrls.indexOf(url, fromIndex);
    log("index: " + index);
    if (index === -1)
      return;
    let config = generalConfigs[index];
    log("config: " + config);
    if (matchedWindow(aWindow, config)) {
      aWindow.setTimeout(function() {
        let action = config.action;
        if (action)
          processAction(aWindow, action);
        let actions = config.actions;
        if (actions)
          processActions(aWindow, actions);
      }, 500);
      return;
    }
    fromIndex = index + 1;
  }
}

function processActions(aWindow, aActions, aRootElement)
{
  var doc = aWindow.document;
  log("actions: " + aActions);
  for (let action of JSON.parse(aActions)) {
    log("action: " + action);
    processAction(aWindow, action, aRootElement);
  }
}

function processAction(aWindow, aAction, aRootElement)
{
  var doc = aWindow.document;
  var root = aRootElement /* for tabmodaldialog */ ||
               doc.documentElement /* for chrome window */;
  var commonDialog = root.Dialog /* for tabmodaldialog */ ||
                       aWindow.Dialog /* for common dialog */;
  log("action: " + aAction);
  var actions = aAction.match(/^([^;]+);?(.*)/);
  if (actions === null)
    return;
  var action = actions[1];
  var value = actions[2];
  switch (action) {
  case 'accept':
    if (commonDialog) {
    commonDialog.ui.button0.click();
    }
    log("accept");
    return;
  case 'cancel':
    if (commonDialog) {
    commonDialog.ui.button1.click();
    }
    log("cancel");
    return;
  case 'click':
    log("click");
    {
      let element = findVisibleElementByLabel(root, value);
      log(element);
      if (typeof element.click === "function") {
        log("element.click(): ready");
        element.click();
        log("element.click(): done");
      } else {
        log("element is not clickable");
        Cu.reportError(new Error("found element is not clickable."));
      }
    }
    return;
  case 'push':
    var buttons = [];
    if (commonDialog) {
      buttons.push(commonDialog.ui.button0);
      buttons.push(commonDialog.ui.button1);
      buttons.push(commonDialog.ui.button2);
      buttons.push(commonDialog.ui.button3);
    ];
    for (let index in buttons) {
      var button = buttons[index];
      log("label: " + button.label);
      if (button.label.match(value)) {
        button.click();
        log("push");
        return;
      }
    }
    log("push: no match");
    return;
  case 'input':
    if (commonDialog) {
    commonDialog.ui.loginTextbox.value = value;
    }
    log("input");
    return;
  case 'check':
    log("check");
    if (value) {
      let element = findVisibleElementByLabel(root, value);
      log("  element: " + element);
      log("  element.checked: ready");
      element.checked = true;
      log("  element.checked: done");
    } else if (commonDialog) {
      commonDialog.ui.checkbox.checked = true;
      commonDialog.args.checked = true;
    }
    return;
  case 'uncheck':
    log("uncheck");
    if (value) {
      let element = findVisibleElementByLabel(root, value);
      log(element);
      log("  element.checked: ready");
      element.checked = false;
      log("  element.checked: done");
    } else if (commonDialog) {
      commonDialog.ui.checkbox.checked = true;
      commonDialog.args.checked = false;
    }
    return;
  default:
    log("no action");
    return;
  }
}

function matchedWindow(aWindow, aConfig) {
  log("matchedWindow");
  let textMatcher = aConfig.text;
  log("  textMatcher: " + textMatcher);
  if (textMatcher && !findVisibleElementByLabel(aWindow.document.documentElement, textMatcher))
    return false;
  let titleMatcher = aConfig.title;
  log("  titleMatcher: " + titleMatcher);
  let title = aWindow.document.title;
  if (titleMatcher && !title.match(titleMatcher))
    return false;

  log("  match");
  return  true;
}

function findVisibleElementByLabel(aRootElement, text) {
  log("findVisibleElementByLabel");
  if (text.indexOf('"') !== -1) {
    text = 'concat("' + text.replace(/"/g, '", \'"\', "') + '")';
  } else {
    text = '"' + text + '"';
  }
  var expression = '/descendant::*[contains(@label, ' + text + ')] | ' +
                   '/descendant::*[local-name()="label" or local-name()="description"][contains(@value, ' + text + ')] | ' +
                   '/descendant::*[contains(text(), ' + text + ')]';
  log("  expression: " + expression);
  try {
  var doc = aRootElement.ownerDocument;
  var global = doc.defaultView;
  var elements = doc.evaluate(
                   expression,
                   aRootElement,
                   null,
                   global.XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
                   null
                 );
  } catch(e) {
    log("  error: " + e);
  }
  log("  elements.length: " + elements.snapshotLength);
  for (var i = 0, maxi = elements.snapshotLength; i < maxi; i++)
  {
    let element = elements.snapshotItem(i);
    if (element.clientHeight > 0 &&
        element.clientWidth > 0) {
      return element;
    }
  }

  log("  no visible element");
  return null;
}

var tabModalDialogObservers = new WeakMap();

function handleMutationsOnBrowserWindow(aMutations, aObserver) {
  aMutations.forEach(function(aMutation) {
    if (aMutation.type !== "childList" ||
        !aMutation.addedNodes) {
      return;
    }
    Array.forEach(aMutation.addedNodes, function(aNode) {
      if (aNode.localName !== "tabmodalprompt") {
        return;
      }
      log("handle new tabmodalprompt");
      var window = aNode.ownerDocument.defaultView;
      window.setTimeout(function() {
        // operate the dialog after successfully initialized
        handleCommonDialog(window, aNode);
      }, 0);
    });
  });
}

function startObserveTabModalDialogs(aWindow) {
  var MutationObserver = aWindow.MutationObserver;
  var observer = new MutationObserver(handleMutationsOnBrowserWindow);
  observer.observe(aWindow.document.documentElement, {
    childList: true,
    subtree:   true
  });
  tabModalDialogObservers.set(aWindow, observer);
  aWindow.addEventListener("unload", function onunload() {
    aWindow.removeEventListener("unload", onunload);
    endObserveTabModalDialogs(aWindow);
  });
}

function endObserveTabModalDialogs(aWindow) {
  var observer = tabModalDialogObservers.get(aWindow);
  if (observer) {
    observer.disconnect();
    tabModalDialogObservers.delete(aWindow);
  }
}

WindowManager.getWindows(null).forEach(handleWindow);
WindowManager.addHandler(handleWindow);

function shutdown()
{
  WindowManager.getWindows(null).forEach(endObserveTabModalDialogs);
  tabModalDialogObservers = undefined;
  prefs.setPref(BASE + 'editing', false)
  prefs.removePrefListener(listener);
  WindowManager = undefined;
  global = undefined;
}
<|endoftext|>


<commit_before>//Tell jshint (atom package) to stop showing certain irrelevent warnings.
/*jshint esversion: 6 */

var harvesterCapacity = 6;
var upgraderCapacity = 1;

var roleHarvester = require('role.harvester');
var roleUpgrader = require('role.upgrader');
var roleBuilder = require('role.builder');

var clearDeadCreepMemory = function() {
    for(var name in Memory.creeps) {
        if(!Game.creeps[name]) {
            delete Memory.creeps[name];
            console.log('Clearing non-existing creep memory:', name);
        }
    }
};

var getNextSource = function() {
    var harvestSource = 0;
    var sources = Game.spawns.Spawn1.room.find(FIND_SOURCES);
    if (Game.spawns.Spawn1.nextSource === undefined || Game.spawns.Spawn1.nextSource >= sources.length) {
        Game.spawns.Spawn1.nextSource = 0;
    }
    else {
        harvestSource = sources[Game.spawns.Spawn1.nextSource];
        Game.spawns.Spawn1.nextSource += 1;
    }
    return harvestSource;
};

var spawnUpgrader = function() {
    var harvestSource = getNextSource();

    var creepMemory = {role: 'upgrader', source: harvestSource};
    var newName = Game.spawns.Spawn1.createCreep([WORK,CARRY,MOVE], undefined, creepMemory);
    if (newName != -6) {
        console.log('Spawning new upgrader: ' + newName);
    }
};

var spawnHarvester = function () {
    var harvestSource = getNextSource();

    var creepMemory = {role: 'harvester', source: harvestSource};
    var newName = Game.spawns.Spawn1.createCreep([WORK,CARRY,MOVE], undefined, creepMemory);
    if (newName != -6) {
        console.log('Spawning new harvester: ' + newName);
    }
};

module.exports.loop = function () {

    var tower = Game.getObjectById('519170edb0e79b2eeb360e71');
    if(tower) {
        var closestDamagedStructure = tower.pos.findClosestByRange(FIND_STRUCTURES, {
            filter: (structure) => structure.hits < structure.hitsMax
        });
        if(closestDamagedStructure) {
            tower.repair(closestDamagedStructure);
        }

        var closestHostile = tower.pos.findClosestByRange(FIND_HOSTILE_CREEPS);
        if(closestHostile) {
            tower.attack(closestHostile);
        }
    }

    clearDeadCreepMemory();

    var harvesters = _.filter(Game.creeps, (creep) => creep.memory.role == 'harvester');
    console.log('Harvesters: ' + harvesters.length);

    var upgraders = _.filter(Game.creeps, (creep) => creep.memory.role == 'upgrader');
    console.log('Upgraders: ' + upgraders.length);

    if(harvesters.length < harvesterCapacity) {
        spawnHarvester();
    }

    if(upgraders.length < upgraderCapacity) {
        spawnUpgrader();
    }

    for(var name in Game.creeps) {
        var creep = Game.creeps[name];
        if(creep.memory.role == 'harvester') {
            roleHarvester.run(creep);
        }
        if(creep.memory.role == 'upgrader') {
            roleUpgrader.run(creep);
        }
        if(creep.memory.role == 'builder') {
            roleBuilder.run(creep);
        }
    }
};
<commit_msg>Changed spawn memory reference to use spawn.memory.source.<commit_after>//Tell jshint (atom package) to stop showing certain irrelevent warnings.
/*jshint esversion: 6 */

var harvesterCapacity = 6;
var upgraderCapacity = 1;

var roleHarvester = require('role.harvester');
var roleUpgrader = require('role.upgrader');
var roleBuilder = require('role.builder');

var clearDeadCreepMemory = function() {
    for(var name in Memory.creeps) {
        if(!Game.creeps[name]) {
            delete Memory.creeps[name];
            console.log('Clearing non-existing creep memory:', name);
        }
    }
};

var getNextSource = function() {
    var harvestSource = 0;
    var sources = Game.spawns.Spawn1.room.find(FIND_SOURCES);
    if (Game.spawns.Spawn1.memory.nextSource === undefined || Game.spawns.Spawn1.memory.nextSource >= sources.length) {
        Game.spawns.Spawn1.memory.nextSource = 0;
    }
    else {
        harvestSource = Game.spawns.Spawn1.memory.nextSource;
        Game.spawns.Spawn1.memory.nextSource += 1;
    }
    return harvestSource;
};

var spawnUpgrader = function() {
    var harvestSource = getNextSource();

    var creepMemory = {role: 'upgrader', source: harvestSource};
    var newName = Game.spawns.Spawn1.createCreep([WORK,CARRY,MOVE,MOVE], undefined, creepMemory);
    if (newName != -6) {
        console.log('Spawning new upgrader: ' + newName);
    }
};

var spawnHarvester = function () {
    var harvestSource = getNextSource();

    var creepMemory = {role: 'harvester', source: harvestSource};
    var newName = Game.spawns.Spawn1.createCreep([WORK,CARRY,MOVE,MOVE], undefined, creepMemory);
    if (newName != -6) {
        console.log('Spawning new harvester: ' + newName);
    }
};

module.exports.loop = function () {

    var tower = Game.getObjectById('519170edb0e79b2eeb360e71');
    if(tower) {
        var closestDamagedStructure = tower.pos.findClosestByRange(FIND_STRUCTURES, {
            filter: (structure) => structure.hits < structure.hitsMax
        });
        if(closestDamagedStructure) {
            tower.repair(closestDamagedStructure);
        }

        var closestHostile = tower.pos.findClosestByRange(FIND_HOSTILE_CREEPS);
        if(closestHostile) {
            tower.attack(closestHostile);
        }
    }

    clearDeadCreepMemory();

    var harvesters = _.filter(Game.creeps, (creep) => creep.memory.role == 'harvester');
    console.log('Harvesters: ' + harvesters.length);

    var upgraders = _.filter(Game.creeps, (creep) => creep.memory.role == 'upgrader');
    console.log('Upgraders: ' + upgraders.length);

    if(harvesters.length < harvesterCapacity) {
        spawnHarvester();
    }

    if(upgraders.length < upgraderCapacity) {
        spawnUpgrader();
    }

    for(var name in Game.creeps) {
        var creep = Game.creeps[name];
        if(creep.memory.role == 'harvester') {
            roleHarvester.run(creep);
        }
        if(creep.memory.role == 'upgrader') {
            roleUpgrader.run(creep);
        }
        if(creep.memory.role == 'builder') {
            roleBuilder.run(creep);
        }
    }
};
<|endoftext|>