<commit_before>/*
* Pym.js is library that resizes an iframe based on the width of the parent and the resulting height of the child.
* Check out the docs at http://foo or the readme at README.md for usage.
*/

var pym = (function() {
    var lib = {};

    var _isSafeMessage = function(e, settings) {
        /*
        * Check the message to make sure it comes from an acceptable xdomain.
        * Defaults to '*' but can be overriden in config.
        */
        if (settings.xdomain !== '*') {
            // If origin doesn't match our xdomain, return.
            if (!e.origin.match(new RegExp(settings.xdomain + '$'))) { return; }
        }

        return true;
    }

    lib.Parent = function(id, url, config) {
        /*
        * A global function for setting up a responsive parent.
        * Use the config object to override the default settings.
        */
        this.id = id;
        this.url = url;
        this.el = document.getElementById(id);

        this.settings = {
            xdomain: '*'
        };

        this.constructIframe = function() {
            /*
            * A function which handles constructing an iframe inside a given element.
            */

            // Calculate the width of this element.
            var width = this.el.offsetWidth.toString();

            // Create an iframe element attached to the document.
            var node = document.createElement("iframe");

            // If the URL contains querystring bits, use them.
            // Otherwise, just create a set of valid params.
            if (this.url.indexOf('?') < 0) {
                this.url += '?';
            } else {
                this.url += '&';
            }

            // Append the initial width as a querystring parameter.
            node.src = this.url + 'initialWidth=' + width + '&childId=' + this.id;

            // Set some attributes to this proto-iframe.
            node.setAttribute('width', '100%');
            node.setAttribute('scrolling', 'no');
            node.setAttribute('marginheight', '0');
            node.setAttribute('frameborder', '0');

            // Append the iframe to our element.
            this.el.appendChild(node);

            // Add an event listener that will handle redrawing the child on resize.
            var that = this;
            window.addEventListener('resize', function(e) {
                that.sendWidthToChild();
            });
        }

        this.processChildMessage = function(e) {
            /*
            * Process a new message from the child.
            * Used to set the height on our iframe.
            */
            if (!_isSafeMessage(e, this.settings)) { return; }

            // Grab the message from the child and parse it.
            var match = e.data.match(/^responsivechild (\S+) (\d+)$/);

            // If there's no match or too many matches in the message, punt.
            if (!match || match.length !== 3) {
                return false;
            }

            // Get the ID from the message.
            var childId = match[1];

            // Is this message for me?
            if (childId != this.id) {
                return;
            }

            // Get the child's height from the message.
            var height = parseInt(match[2]);

            // Update the height.
            this.el.getElementsByTagName('iframe')[0].setAttribute('height', height + 'px');
        }

        this.sendWidthToChild = function() {
            /*
            * Transmit the current iframe width to the child.
            */

            // Get the width of the element.
            var width = this.el.offsetWidth.toString();

            // Pass the width out to the child so it can compute the height.
            this.el.getElementsByTagName('iframe')[0].contentWindow.postMessage('responsiveparent ' + this.id + ' ' + width, '*');
        }

        // Add any overrides to settings coming from config.
        for (var key in config) {
            this.settings[key] = config[key];
        }

        // Add a listener for processing messages from the child.
        var that = this;
        window.addEventListener('message', function(e) {
            return that.processChildMessage(e)
        }, false);

        // Construct the iframe in the container element.
        this.constructIframe();

        return this;
    };

    lib.Child = function(config) {
        /*
        * A global function for setting up a responsive child.
        * Use the config object to override the default settings.
        */
        this.parentWidth = null;
        this.id = null;

        this.settings = {
            renderCallback: null,
            xdomain: '*',
            polling: 0
        };

        this.getParameterByName = function(name) {
            /*
            * Generic function for parsing URL params.
            * Via http://stackoverflow.com/questions/901115/how-can-i-get-query-string-values-in-javascript
            */
            var regex = new RegExp("[\\?&]" + name.replace(/[\[]/, '\\\[').replace(/[\]]/, '\\\]') + '=([^&#]*)');
            var results = regex.exec(location.search);
            return results === null ? '' : decodeURIComponent(results[1].replace(/\+/g, " "));
        };

        this.sendHeightToParent = function() {
            /*
            * Transmit the current iframe height to the parent.
            * Make this callable from external scripts in case they update the body out of sequence.
            */

            // Get the child's height.
            var height = document.getElementsByTagName('body')[0].offsetHeight.toString();

            // Send the height to the parent.
            window.top.postMessage('responsivechild ' + this.id + ' '+ height, '*');
        };

        this.processParentMessage = function(e) {
            /*
            * Process a new message from parent frame.
            */

            // First, punt if this isn't from an acceptable xdomain.
            if (!_isSafeMessage(e, this.settings)) { return; }

            // Get the message from the parent.
            var match = e.data.match(/^responsiveparent (\S+) (\d+)$/);

            // If there's no match or it's a bad format, punt.
            if (!match || match.length !== 3) { return; }

            // Get the ID out of the message.
            // TKTK: error
            //this.id = match[1];

            // Get the width out of the message.
            var width = parseInt(match[2]);

            // Change the width if it's different.
            if (width != this.parentWidth) {
                this.parentWidth = width;

                // Call the callback function if it exists.
                if (this.settings.renderCallback) {
                    this.settings.renderCallback(width);
                }

                // Send the height back to the parent.
                this.sendHeightToParent();
            }
        };

        // Initialize settings with overrides.
        for (var key in config) { this.settings[key] = config[key]; }

        // Set up a listener to handle any incoming messages.
        var that = this;
        window.addEventListener('message', function(e) {
            that.processParentMessage(e);
        }, false);

        // Identify what ID the parent knows this child as.
        this.id = this.getParameterByName('childId');

        // Get the initial width from a URL parameter.
        var width = parseInt(this.getParameterByName('initialWidth'));

        // If there's a callback function, call it.
        if (this.settings.renderCallback) {
            this.settings.renderCallback(width);
        }

        // Send the initial height to the parent.
        this.sendHeightToParent();

        // If we're configured to poll, create a setInterval to handle that.
        if (this.settings.polling) {
            window.setInterval(this.sendHeightToParent, this.settings.polling);
        }

        return this;
    };

    return lib;
}());
<commit_msg>Double-check child got right message.<commit_after>/*
* Pym.js is library that resizes an iframe based on the width of the parent and the resulting height of the child.
* Check out the docs at http://foo or the readme at README.md for usage.
*/

var pym = (function() {
    var lib = {};

    var _isSafeMessage = function(e, settings) {
        /*
        * Check the message to make sure it comes from an acceptable xdomain.
        * Defaults to '*' but can be overriden in config.
        */
        if (settings.xdomain !== '*') {
            // If origin doesn't match our xdomain, return.
            if (!e.origin.match(new RegExp(settings.xdomain + '$'))) { return; }
        }

        return true;
    }

    lib.Parent = function(id, url, config) {
        /*
        * A global function for setting up a responsive parent.
        * Use the config object to override the default settings.
        */
        this.id = id;
        this.url = url;
        this.el = document.getElementById(id);

        this.settings = {
            xdomain: '*'
        };

        this.constructIframe = function() {
            /*
            * A function which handles constructing an iframe inside a given element.
            */

            // Calculate the width of this element.
            var width = this.el.offsetWidth.toString();

            // Create an iframe element attached to the document.
            var node = document.createElement("iframe");

            // If the URL contains querystring bits, use them.
            // Otherwise, just create a set of valid params.
            if (this.url.indexOf('?') < 0) {
                this.url += '?';
            } else {
                this.url += '&';
            }

            // Append the initial width as a querystring parameter.
            node.src = this.url + 'initialWidth=' + width + '&childId=' + this.id;

            // Set some attributes to this proto-iframe.
            node.setAttribute('width', '100%');
            node.setAttribute('scrolling', 'no');
            node.setAttribute('marginheight', '0');
            node.setAttribute('frameborder', '0');

            // Append the iframe to our element.
            this.el.appendChild(node);

            // Add an event listener that will handle redrawing the child on resize.
            var that = this;
            window.addEventListener('resize', function(e) {
                that.sendWidthToChild();
            });
        }

        this.processChildMessage = function(e) {
            /*
            * Process a new message from the child.
            * Used to set the height on our iframe.
            */
            if (!_isSafeMessage(e, this.settings)) { return; }

            // Grab the message from the child and parse it.
            var match = e.data.match(/^responsivechild (\S+) (\d+)$/);

            // If there's no match or too many matches in the message, punt.
            if (!match || match.length !== 3) {
                return false;
            }

            // Get the ID from the message.
            var childId = match[1];

            // Is this message for me?
            if (childId != this.id) {
                return;
            }

            // Get the child's height from the message.
            var height = parseInt(match[2]);

            // Update the height.
            this.el.getElementsByTagName('iframe')[0].setAttribute('height', height + 'px');
        }

        this.sendWidthToChild = function() {
            /*
            * Transmit the current iframe width to the child.
            */

            // Get the width of the element.
            var width = this.el.offsetWidth.toString();

            // Pass the width out to the child so it can compute the height.
            this.el.getElementsByTagName('iframe')[0].contentWindow.postMessage('responsiveparent ' + this.id + ' ' + width, '*');
        }

        // Add any overrides to settings coming from config.
        for (var key in config) {
            this.settings[key] = config[key];
        }

        // Add a listener for processing messages from the child.
        var that = this;
        window.addEventListener('message', function(e) {
            return that.processChildMessage(e)
        }, false);

        // Construct the iframe in the container element.
        this.constructIframe();

        return this;
    };

    lib.Child = function(config) {
        /*
        * A global function for setting up a responsive child.
        * Use the config object to override the default settings.
        */
        this.parentWidth = null;
        this.id = null;

        this.settings = {
            renderCallback: null,
            xdomain: '*',
            polling: 0
        };

        this.getParameterByName = function(name) {
            /*
            * Generic function for parsing URL params.
            * Via http://stackoverflow.com/questions/901115/how-can-i-get-query-string-values-in-javascript
            */
            var regex = new RegExp("[\\?&]" + name.replace(/[\[]/, '\\\[').replace(/[\]]/, '\\\]') + '=([^&#]*)');
            var results = regex.exec(location.search);
            return results === null ? '' : decodeURIComponent(results[1].replace(/\+/g, " "));
        };

        this.sendHeightToParent = function() {
            /*
            * Transmit the current iframe height to the parent.
            * Make this callable from external scripts in case they update the body out of sequence.
            */

            // Get the child's height.
            var height = document.getElementsByTagName('body')[0].offsetHeight.toString();

            // Send the height to the parent.
            window.top.postMessage('responsivechild ' + this.id + ' '+ height, '*');
        };

        this.processParentMessage = function(e) {
            /*
            * Process a new message from parent frame.
            */

            // First, punt if this isn't from an acceptable xdomain.
            if (!_isSafeMessage(e, this.settings)) { return; }

            // Get the message from the parent.
            var match = e.data.match(/^responsiveparent (\S+) (\d+)$/);

            // If there's no match or it's a bad format, punt.
            if (!match || match.length !== 3) { return; }

            // Get the ID out of the message.
            var id = match[1];

            // Ensure message is meant for this child
            if (id != this.id) {
                return;
            }

            // Get the width out of the message.
            var width = parseInt(match[2]);

            // Change the width if it's different.
            if (width != this.parentWidth) {
                this.parentWidth = width;

                // Call the callback function if it exists.
                if (this.settings.renderCallback) {
                    this.settings.renderCallback(width);
                }

                // Send the height back to the parent.
                this.sendHeightToParent();
            }
        };

        // Initialize settings with overrides.
        for (var key in config) { this.settings[key] = config[key]; }

        // Set up a listener to handle any incoming messages.
        var that = this;
        window.addEventListener('message', function(e) {
            that.processParentMessage(e);
        }, false);

        // Identify what ID the parent knows this child as.
        this.id = this.getParameterByName('childId');

        // Get the initial width from a URL parameter.
        var width = parseInt(this.getParameterByName('initialWidth'));

        // If there's a callback function, call it.
        if (this.settings.renderCallback) {
            this.settings.renderCallback(width);
        }

        // Send the initial height to the parent.
        this.sendHeightToParent();

        // If we're configured to poll, create a setInterval to handle that.
        if (this.settings.polling) {
            window.setInterval(this.sendHeightToParent, this.settings.polling);
        }

        return this;
    };

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


<commit_before>const moment = require('moment-timezone')
const line = require('../lines/index')
const sql = require('mssql')
const connection = require('../db/connection.js')
const wlg = require('./nz-wlg.js')
const cache = require('../cache.js')

let rtFn = function() {
  return {}
}
cache.preReady.push(() => {
  if (global.config.prefix === 'nz-akl') {
    rtFn = require('../realtime/nz-akl.js').getTripsCachedAuckland
  }
})

var station = {
  stopInfo: function(req, res) {
    if (req.params.station) {
      station._stopInfo(req.params.station).then(function(data) {
        res.send(data)
      }).catch(function(err) {
        res.status(404).send(err)
      })
    } else {
      res.status(404).send({
        'error': 'please specify a station'
      })
    }
  },
  _stopInfo: function(stop) {
    return new Promise(function(resolve, reject) {
      stop = stop.trim()

      // returns data
      let override = false
      if (global.config.prefix === 'nz-wlg' && wlg.badStops.indexOf(stop) > -1) {
        override = stop
        stop = stop + '1'
      }

      const sqlRequest = connection.get().request()
      sqlRequest.input('stop_id', sql.VarChar, stop)
      sqlRequest.query(`
        SELECT
          stops.stop_code as stop_id,
          stops.stop_name,
          stops.stop_desc,
          stops.stop_lat,
          stops.stop_lon,
          stops.zone_id,
          stops.location_type,
          stops.parent_station,
          stops.stop_timezone,
          stops.wheelchair_boarding,
          routes.route_type
        FROM
          stops
        LEFT JOIN
          stop_times
        ON stop_times.id = (
            SELECT TOP 1 id
            FROM    stop_times
            WHERE
            stop_times.stop_id = stops.stop_id
        )
        LEFT JOIN trips ON trips.trip_id = stop_times.trip_id
        LEFT JOIN routes on routes.route_id = trips.route_id
        WHERE
          stops.stop_code = @stop_id
      `).then((result) => {
        const data = result.recordset[0]
        data.prefix = global.config.prefix
        delete data.uid
        if (override) {
          data.stop_id = override
        }
        resolve(data)
      }).catch(err => {
        return reject({
          error: 'station not found'
        })
      })
    })
  },
  stopTimes: function(req, res) {
    // option in the future?
    // let fastData = false
    // if (req.params.fast === 'fast') {
    //   fastData = true
    // }
    if (!req.params.station) {
      return res.status(404).send({
        'error': 'please x specify a station'
      })
    }

    req.params.station = req.params.station.trim()

    let sending = {
      provider: 'sql-server'
    }

    const time = moment().tz('Pacific/Auckland')
    let currentTime = new Date(Date.UTC(1970,0,1,time.hour(),time.minute()))
    if (req.params.time) {
      const split = req.params.time.split(':')
      let tentativeDate = new Date(Date.UTC(1970,0,1,split[0],split[1]))
      if (tentativeDate.toString !== 'Invalid Date') {
        currentTime = tentativeDate
      }
    }
    sending.currentTime = currentTime.getTime()/1000

    const today = new Date(0)
    today.setFullYear(time.year())
    today.setUTCMonth(time.month())
    today.setUTCDate(time.date())

    // midnight fix
    if (time.hour() < 5) {
      today.setTime(today.getTime() - (1000 * 60 * 60 * 24))
    }

    // combines train stations platforms together
    let procedure = 'GetStopTimes'
    if (global.config.prefix === 'nz-wlg' && wlg.badStops.indexOf(req.params.station) > -1) {
      procedure = 'GetMultipleStopTimes'
    }

    const realtimeTrips = []
    connection.get().request()
      .input('stop_id', sql.VarChar(100), req.params.station)
      .input('departure_time', sql.Time, currentTime)
      .input('date', sql.Date, today)
      .execute(procedure)
      .then((trips) => {
        sending.trips = trips.recordset.map((record) => {
          record.departure_time_seconds = new Date(record.departure_time).getTime()/1000
          if (record.departure_time_24) {
            record.departure_time_seconds += 86400
          }
          record.arrival_time_seconds = record.departure_time_seconds

          record.route_color = line.getColor(record.route_short_name)

          // 30mins of realtime
          if (record.departure_time_seconds < (sending.currentTime + 1800) || record.departure_time_24) {
            realtimeTrips.push(record.trip_id)
          }

          delete record.arrival_time
          delete record.arrival_time_24
          delete record.departure_time
          delete record.departure_time_24
          return record
        })

        sending.realtime = rtFn(realtimeTrips)
        res.send(sending)

      }).catch(function(err) {
        res.status(500).send(err)
      })
  },
  timetable: function(req, res) {
    if (parseInt(req.params.direction) > 2 || parseInt(req.params.direction) < 0) {
      return res.status(400).send({error: 'Direction is not valid.'})
    }
    let sending = {}

    const time = moment().tz('Pacific/Auckland')
    const currentTime = new Date(Date.UTC(1970,0,1,time.hour(),time.minute()))

    const today = new Date(0)
    today.setFullYear(time.year())
    today.setUTCMonth(time.month())
    today.setUTCDate(time.date())

    // combines train stations platforms together
    let procedure = 'GetTimetable'
    if (global.config.prefix === 'nz-wlg' && wlg.badStops.indexOf(req.params.station) > -1) {
      procedure = 'GetMultipleTimetable'
    }

    connection.get().request()
      .input('stop_id', sql.VarChar(100), req.params.station)
      .input('route_short_name', sql.VarChar(50), req.params.route)
      .input('date', sql.Date, today)
      .input('direction', sql.Int, req.params.direction)
      .execute(procedure)
      .then((trips) => {
        sending.trips = trips.recordset.map((record) => {
          record.departure_time_seconds = new Date(record.departure_time || record.arrival_time).getTime()/1000
          if (record.departure_time_24 || record.arrival_time_24) {
            record.arrival_time_seconds += 86400
          }
          record.arrival_time_seconds = record.departure_time_seconds

          record.route_color = line.getColor(req.params.route)
          record.currentTime = currentTime.getTime()/1000

          delete record.departure_time
          delete record.departure_time_24
          return record
        })
        res.send(sending.trips)
      }).catch(function(err) {
        res.status(500).send(err)
      })
  }
}
module.exports = station<commit_msg>Fix Mapping Waiting Auckland<commit_after>const moment = require('moment-timezone')
const line = require('../lines/index')
const sql = require('mssql')
const connection = require('../db/connection.js')
const wlg = require('./nz-wlg.js')
const cache = require('../cache.js')

let rtFn = function() {
  return {}
}
cache.preReady.push(() => {
  if (global.config.prefix === 'nz-akl') {
    rtFn = require('../realtime/nz-akl.js').getTripsCachedAuckland
  }
})

var station = {
  stopInfo: function(req, res) {
    if (req.params.station) {
      station._stopInfo(req.params.station).then(function(data) {
        res.send(data)
      }).catch(function(err) {
        res.status(404).send(err)
      })
    } else {
      res.status(404).send({
        'error': 'please specify a station'
      })
    }
  },
  _stopInfo: function(stop) {
    return new Promise(function(resolve, reject) {
      stop = stop.trim()

      // returns data
      let override = false
      if (global.config.prefix === 'nz-wlg' && wlg.badStops.indexOf(stop) > -1) {
        override = stop
        stop = stop + '1'
      }

      const sqlRequest = connection.get().request()
      sqlRequest.input('stop_id', sql.VarChar, stop)
      sqlRequest.query(`
        SELECT
          stops.stop_code as stop_id,
          stops.stop_name,
          stops.stop_desc,
          stops.stop_lat,
          stops.stop_lon,
          stops.zone_id,
          stops.location_type,
          stops.parent_station,
          stops.stop_timezone,
          stops.wheelchair_boarding,
          routes.route_type
        FROM
          stops
        LEFT JOIN
          stop_times
        ON stop_times.id = (
            SELECT TOP 1 id
            FROM    stop_times
            WHERE
            stop_times.stop_id = stops.stop_id
        )
        LEFT JOIN trips ON trips.trip_id = stop_times.trip_id
        LEFT JOIN routes on routes.route_id = trips.route_id
        WHERE
          stops.stop_code = @stop_id
      `).then((result) => {
        const data = result.recordset[0]
        data.prefix = global.config.prefix
        delete data.uid
        if (override) {
          data.stop_id = override
        }
        resolve(data)
      }).catch(err => {
        return reject({
          error: 'station not found'
        })
      })
    })
  },
  stopTimes: function(req, res) {
    // option in the future?
    // let fastData = false
    // if (req.params.fast === 'fast') {
    //   fastData = true
    // }
    if (!req.params.station) {
      return res.status(404).send({
        'error': 'please x specify a station'
      })
    }

    req.params.station = req.params.station.trim()

    let sending = {
      provider: 'sql-server'
    }

    const time = moment().tz('Pacific/Auckland')
    let currentTime = new Date(Date.UTC(1970,0,1,time.hour(),time.minute()))
    let midnightOverride = false
    if (req.params.time) {
      const split = req.params.time.split(':')
      let tentativeDate = new Date(Date.UTC(1970,0,1,split[0],split[1]))
      if (tentativeDate.toString !== 'Invalid Date') {
        currentTime = tentativeDate
        midnightOverride = true
      }
    }
    sending.currentTime = currentTime.getTime()/1000

    const today = new Date(0)
    today.setFullYear(time.year())
    today.setUTCMonth(time.month())
    today.setUTCDate(time.date())

    // midnight fix
    if (time.hour() < 5 && midnightOverride === false) {
      today.setTime(today.getTime() - (1000 * 60 * 60 * 24))
    }

    // combines train stations platforms together
    let procedure = 'GetStopTimes'
    if (global.config.prefix === 'nz-wlg' && wlg.badStops.indexOf(req.params.station) > -1) {
      procedure = 'GetMultipleStopTimes'
    }

    const realtimeTrips = []
    connection.get().request()
      .input('stop_id', sql.VarChar(100), req.params.station)
      .input('departure_time', sql.Time, currentTime)
      .input('date', sql.Date, today)
      .execute(procedure)
      .then((trips) => {
        sending.trips = trips.recordset.map((record) => {
          record.departure_time_seconds = new Date(record.departure_time).getTime()/1000
          if (record.departure_time_24) {
            record.departure_time_seconds += 86400
          }
          record.arrival_time_seconds = record.departure_time_seconds

          record.route_color = line.getColor(record.route_short_name)

          // 30mins of realtime
          if (record.departure_time_seconds < (sending.currentTime + 1800) || record.departure_time_24) {
            realtimeTrips.push(record.trip_id)
          }

          delete record.arrival_time
          delete record.arrival_time_24
          delete record.departure_time
          delete record.departure_time_24
          return record
        })

        sending.realtime = rtFn(realtimeTrips)
        res.send(sending)

      }).catch(function(err) {
        res.status(500).send(err)
      })
  },
  timetable: function(req, res) {
    if (parseInt(req.params.direction) > 2 || parseInt(req.params.direction) < 0) {
      return res.status(400).send({error: 'Direction is not valid.'})
    }
    let sending = {}

    const time = moment().tz('Pacific/Auckland')
    const currentTime = new Date(Date.UTC(1970,0,1,time.hour(),time.minute()))

    const today = new Date(0)
    today.setFullYear(time.year())
    today.setUTCMonth(time.month())
    today.setUTCDate(time.date())

    // combines train stations platforms together
    let procedure = 'GetTimetable'
    if (global.config.prefix === 'nz-wlg' && wlg.badStops.indexOf(req.params.station) > -1) {
      procedure = 'GetMultipleTimetable'
    }

    connection.get().request()
      .input('stop_id', sql.VarChar(100), req.params.station)
      .input('route_short_name', sql.VarChar(50), req.params.route)
      .input('date', sql.Date, today)
      .input('direction', sql.Int, req.params.direction)
      .execute(procedure)
      .then((trips) => {
        sending.trips = trips.recordset.map((record) => {
          record.departure_time_seconds = new Date(record.departure_time || record.arrival_time).getTime()/1000
          if (record.departure_time_24 || record.arrival_time_24) {
            record.arrival_time_seconds += 86400
          }
          record.arrival_time_seconds = record.departure_time_seconds

          record.route_color = line.getColor(req.params.route)
          record.currentTime = currentTime.getTime()/1000

          delete record.departure_time
          delete record.departure_time_24
          return record
        })
        res.send(sending.trips)
      }).catch(function(err) {
        res.status(500).send(err)
      })
  }
}
module.exports = station<|endoftext|>


<commit_before>/* global describe, it, xit */
/* jslint node: true, esnext: true */

"use strict";

import fetch from 'isomorphic-fetch';

const btoa = require('btoa');

const XML_HEADER = '<?xml version="1.0" encoding="utf-8"?>';
const XML_CONTENT_TYPE = 'text/xml';

const NS_S = 'svn:';
const NS_D = 'DAV:';

const NS_SVN_DAV = "http://subversion.tigris.org/xmlns/dav/";
const NS_SVN_DAV_DEPTH = NS_SVN_DAV + "svn/depth";
const NS_SVN_DAV_MERGINFO = NS_SVN_DAV + "svn/mergeinfo";
const NS_SVN_DAV_LOG_REVPROPS = NS_SVN_DAV + "svn/log-revprops";
const NS_SVN_DAV_ATOMIC_REVPROPS = NS_SVN_DAV + "svn/atomic-revprops";
const NS_SVN_DAV_PARTIAL_REPLAY = NS_SVN_DAV + "svn/partial-replay";

const DAVFeatures = {
  '1': {},
  '2': {},
  'version-control': {},
  'checkout': {},
  'working-resource': {},
  'merge': {},
  'baseline': {},
  'activity': {},
  'version-controlled-collection': {},
  'http://subversion.tigris.org/xmlns/dav/svn/inherited-props': {},
  'http://subversion.tigris.org/xmlns/dav/svn/inline-props': {},
  'http://subversion.tigris.org/xmlns/dav/svn/reverse-file-revs': {},
  'http://subversion.tigris.org/xmlns/dav/svn/ephemeral-txnprops': {},
  'http://subversion.tigris.org/xmlns/dav/svn/replay-rev-resource': {},
  [NS_SVN_DAV_MERGINFO]: {},
  [NS_SVN_DAV_PARTIAL_REPLAY]: {},
  [NS_SVN_DAV_DEPTH]: {},
  [NS_SVN_DAV_LOG_REVPROPS]: {},
  [NS_SVN_DAV_ATOMIC_REVPROPS]: {}
};

const SVNHeaders = [
  'SVN-Repository-UUID',
  'SVN-Repository-Root',
  'SVN-Rev-Root-Stub', // /svn/delivery_notes/!svn/rvr
  'SVN-Rev-Stub', // /svn/delivery_notes/!svn/rev
  'SVN-Txn-Root-Stub', // /svn/delivery_notes/!svn/vtxr
  'SVN-Txn-Stub', // /svn/delivery_notes/!svn/txn

  'SVN-Me-Resource', // /svn/delivery_notes/!svn/me
  'SVN-Rev-Root-Stub', // /svn/delivery_notes/!svn/rvr

  'SVN-Youngest-Rev', // Integer
  'SVN-Allow-Bulk-Updates', // Prefer
  'SVN-Supported-Posts', // create-txn create-txn-with-props
  'SVN-Repository-MergeInfo' // yes
];

const SVN = {
  toString() {
      return "svn";
    },
    get basicAuthorization() {
      return 'Basic ' + btoa(this.credentials.user + ':' + this.credentials.password);
    },
    get vccDefault() {
      return [this.attributes['SVN-Repository-Root'], "!svn/vcc/default"].join('/');
    },
    get davHeader() {
      return [NS_SVN_DAV_DEPTH, NS_SVN_DAV_MERGINFO, NS_SVN_DAV_LOG_REVPROPS].join(',');
    },
    propfind(url, properties, depth = 1) {
      const xmls = [XML_HEADER, '<D:propfind xmlns:D="DAV:">'];

      if (properties) {
        for (let p in properties) {
          xmls.push(`<D:prop><${p} xmlns=\"${properties[p]}\"/></D:prop>`);
        }
      } else {
        xmls.push('<D:allprop/>');
      }

      xmls.push('</D:propfind>');

      return fetch(url, {
        method: 'PROPFIND',
        body: xmls.join('\n'),
        headers: {
          "authorization": this.basicAuthorization,
          "dav": this.davHeader,
          "depth": depth,
          "content-type": XML_CONTENT_TYPE
        }
      });
    },
    report(url, start, end) {
      if (end - start > 1000) start = end - 1000;

      const xmls = [XML_HEADER, '<S:log-report xmlns:S="svn:">'];
      xmls.push(`<S:start-revision>${start}</S:start-revision>`);
      xmls.push(`<S:end-revision>${end}</S:end-revision>`);
      ['svn:author', 'svn:date', 'svn:log'].forEach(item => {
        xmls.push(`<S:revprop>${item}</S:revprop>`);
      });

      xmls.push('<S:path/>');
      xmls.push('</S:log-report>');

      return fetch(url, {
        method: 'REPORT',
        body: xmls.join('\n'),
        headers: {
          "authorization": this.basicAuthorization,
          "dav": this.davHeader,
          "content-type": XML_CONTENT_TYPE
        }
      });
    }
};

/*
OPTIONS /svn/delivery_notes HTTP/1.1
Host: subversion.assembla.com
Authorization: Basic YXJsYWM3NzpzdGFydDEyMw==
User-Agent: SVN/1.9.2 (x86_64-apple-darwin15.0.0) serf/1.3.8
Content-Type: text/xml
Connection: keep-alive
Accept-Encoding: gzip
DAV: http://subversion.tigris.org/xmlns/dav/svn/depth
DAV: http://subversion.tigris.org/xmlns/dav/svn/mergeinfo
DAV: http://subversion.tigris.org/xmlns/dav/svn/log-revprops
Content-Length: 131

<?xml version="1.0" encoding="utf-8"?><D:options xmlns:D="DAV:"><D:activity-collection-set></D:activity-collection-set></D:options>
*/

export function init(url, options) {

  const attributes = {};
  const davFeatures = new Set();
  const allowedMethods = new Set();

  const svn = Object.create(SVN, {
    credentials: {
      get() {
        return options.credentials;
      }
    },
    attributes: {
      get() {
        return attributes;
      }
    },
    davFeatures: {
      get() {
        return davFeatures;
      }
    },
    allowedMethods: {
      get() {
        return allowedMethods;
      }
    }
  });

  /*
  OPTIONS /svn/delivery_notes/data HTTP/1.1
  Host: subversion.assembla.com
  Authorization: Basic XXX
  User-Agent: SVN/1.9.2 (x86_64-apple-darwin15.0.0) serf/1.3.8
  Content-Type: text/xml
  Connection: keep-alive
  Accept-Encoding: gzip
  DAV: http://subversion.tigris.org/xmlns/dav/svn/depth
  DAV: http://subversion.tigris.org/xmlns/dav/svn/mergeinfo
  DAV: http://subversion.tigris.org/xmlns/dav/svn/log-revprops
  Content-Length: 131

  <?xml version="1.0" encoding="utf-8"?><D:options xmlns:D="DAV:"><D:activity-collection-set></D:activity-collection-set></D:options>
  */

  return fetch(url, {
    method: 'OPTIONS',
    body: [XML_HEADER, '<D:options xmlns:D="DAV:">', '<D:activity-collection-set></D:activity-collection-set>',
      '</D:options>'
    ].join(''),
    headers: {
      "authorization": svn.basicAuthorization,
      "dav": svn.davHeader,
      //'user-agent': 'SVN/1.9.2 (x86_64-apple-darwin15.0.0) serf/1.3.8',
      //'connection': "keep-alive",
      "content-type": XML_CONTENT_TYPE
    }
  }).then(response => {
    const headers = response.headers._headers;

    //console.log(`Headers ${JSON.stringify(headers)}`);
    //console.log(`RAW headers: ${JSON.stringify(headers.raw)}`);

    SVNHeaders.forEach(h => {
      if (headers[h]) {
        attributes[h] = headers[h];
        console.log(`${h}: ${headers[h]}`);
      }
    });

    headerIntoSet(headers.dav, davFeatures);
    headerIntoSet(headers.allow, allowedMethods);

    attributes['SVN-Youngest-Rev'] = parseInt(headers['SVN-Youngest-Rev'], 10);

    //console.log(`rev: ${headers['SVN-Youngest-Rev']}`);
    //console.log(`Attributes: ${JSON.stringify(attributes)}`);
    return svn;
  });
}

function headerIntoSet(header, target) {
  if (header) {
    header.forEach(h => h.split(/\s*,\s*/).forEach(e => target.add(e)));
  }
}
<commit_msg>fix: use const for loop variables too<commit_after>/* global describe, it, xit */
/* jslint node: true, esnext: true */

"use strict";

import fetch from 'isomorphic-fetch';

const btoa = require('btoa');

const XML_HEADER = '<?xml version="1.0" encoding="utf-8"?>';
const XML_CONTENT_TYPE = 'text/xml';

const NS_S = 'svn:';
const NS_D = 'DAV:';

const NS_SVN_DAV = "http://subversion.tigris.org/xmlns/dav/";
const NS_SVN_DAV_DEPTH = NS_SVN_DAV + "svn/depth";
const NS_SVN_DAV_MERGINFO = NS_SVN_DAV + "svn/mergeinfo";
const NS_SVN_DAV_LOG_REVPROPS = NS_SVN_DAV + "svn/log-revprops";
const NS_SVN_DAV_ATOMIC_REVPROPS = NS_SVN_DAV + "svn/atomic-revprops";
const NS_SVN_DAV_PARTIAL_REPLAY = NS_SVN_DAV + "svn/partial-replay";

const DAVFeatures = {
  '1': {},
  '2': {},
  'version-control': {},
  'checkout': {},
  'working-resource': {},
  'merge': {},
  'baseline': {},
  'activity': {},
  'version-controlled-collection': {},
  'http://subversion.tigris.org/xmlns/dav/svn/inherited-props': {},
  'http://subversion.tigris.org/xmlns/dav/svn/inline-props': {},
  'http://subversion.tigris.org/xmlns/dav/svn/reverse-file-revs': {},
  'http://subversion.tigris.org/xmlns/dav/svn/ephemeral-txnprops': {},
  'http://subversion.tigris.org/xmlns/dav/svn/replay-rev-resource': {},
  [NS_SVN_DAV_MERGINFO]: {},
  [NS_SVN_DAV_PARTIAL_REPLAY]: {},
  [NS_SVN_DAV_DEPTH]: {},
  [NS_SVN_DAV_LOG_REVPROPS]: {},
  [NS_SVN_DAV_ATOMIC_REVPROPS]: {}
};

const SVNHeaders = [
  'SVN-Repository-UUID',
  'SVN-Repository-Root',
  'SVN-Rev-Root-Stub', // /svn/delivery_notes/!svn/rvr
  'SVN-Rev-Stub', // /svn/delivery_notes/!svn/rev
  'SVN-Txn-Root-Stub', // /svn/delivery_notes/!svn/vtxr
  'SVN-Txn-Stub', // /svn/delivery_notes/!svn/txn

  'SVN-Me-Resource', // /svn/delivery_notes/!svn/me
  'SVN-Rev-Root-Stub', // /svn/delivery_notes/!svn/rvr

  'SVN-Youngest-Rev', // Integer
  'SVN-Allow-Bulk-Updates', // Prefer
  'SVN-Supported-Posts', // create-txn create-txn-with-props
  'SVN-Repository-MergeInfo' // yes
];

const SVN = {
  toString() {
      return "svn";
    },
    get basicAuthorization() {
      return 'Basic ' + btoa(this.credentials.user + ':' + this.credentials.password);
    },
    get vccDefault() {
      return [this.attributes['SVN-Repository-Root'], "!svn/vcc/default"].join('/');
    },
    get davHeader() {
      return [NS_SVN_DAV_DEPTH, NS_SVN_DAV_MERGINFO, NS_SVN_DAV_LOG_REVPROPS].join(',');
    },
    propfind(url, properties, depth = 1) {
      const xmls = [XML_HEADER, '<D:propfind xmlns:D="DAV:">'];

      if (properties) {
        for (const p in properties) {
          xmls.push(`<D:prop><${p} xmlns=\"${properties[p]}\"/></D:prop>`);
        }
      } else {
        xmls.push('<D:allprop/>');
      }

      xmls.push('</D:propfind>');

      return fetch(url, {
        method: 'PROPFIND',
        body: xmls.join('\n'),
        headers: {
          "authorization": this.basicAuthorization,
          "dav": this.davHeader,
          "depth": depth,
          "content-type": XML_CONTENT_TYPE
        }
      });
    },
    report(url, start, end) {
      if (end - start > 1000) start = end - 1000;

      const xmls = [XML_HEADER, '<S:log-report xmlns:S="svn:">'];
      xmls.push(`<S:start-revision>${start}</S:start-revision>`);
      xmls.push(`<S:end-revision>${end}</S:end-revision>`);
      ['svn:author', 'svn:date', 'svn:log'].forEach(item => {
        xmls.push(`<S:revprop>${item}</S:revprop>`);
      });

      xmls.push('<S:path/>');
      xmls.push('</S:log-report>');

      return fetch(url, {
        method: 'REPORT',
        body: xmls.join('\n'),
        headers: {
          "authorization": this.basicAuthorization,
          "dav": this.davHeader,
          "content-type": XML_CONTENT_TYPE
        }
      });
    }
};

/*
OPTIONS /svn/delivery_notes HTTP/1.1
Host: subversion.assembla.com
Authorization: Basic YXJsYWM3NzpzdGFydDEyMw==
User-Agent: SVN/1.9.2 (x86_64-apple-darwin15.0.0) serf/1.3.8
Content-Type: text/xml
Connection: keep-alive
Accept-Encoding: gzip
DAV: http://subversion.tigris.org/xmlns/dav/svn/depth
DAV: http://subversion.tigris.org/xmlns/dav/svn/mergeinfo
DAV: http://subversion.tigris.org/xmlns/dav/svn/log-revprops
Content-Length: 131

<?xml version="1.0" encoding="utf-8"?><D:options xmlns:D="DAV:"><D:activity-collection-set></D:activity-collection-set></D:options>
*/

export function init(url, options) {

  const attributes = {};
  const davFeatures = new Set();
  const allowedMethods = new Set();

  const svn = Object.create(SVN, {
    credentials: {
      get() {
        return options.credentials;
      }
    },
    attributes: {
      get() {
        return attributes;
      }
    },
    davFeatures: {
      get() {
        return davFeatures;
      }
    },
    allowedMethods: {
      get() {
        return allowedMethods;
      }
    }
  });

  /*
  OPTIONS /svn/delivery_notes/data HTTP/1.1
  Host: subversion.assembla.com
  Authorization: Basic XXX
  User-Agent: SVN/1.9.2 (x86_64-apple-darwin15.0.0) serf/1.3.8
  Content-Type: text/xml
  Connection: keep-alive
  Accept-Encoding: gzip
  DAV: http://subversion.tigris.org/xmlns/dav/svn/depth
  DAV: http://subversion.tigris.org/xmlns/dav/svn/mergeinfo
  DAV: http://subversion.tigris.org/xmlns/dav/svn/log-revprops
  Content-Length: 131

  <?xml version="1.0" encoding="utf-8"?><D:options xmlns:D="DAV:"><D:activity-collection-set></D:activity-collection-set></D:options>
  */

  return fetch(url, {
    method: 'OPTIONS',
    body: [XML_HEADER, '<D:options xmlns:D="DAV:">', '<D:activity-collection-set></D:activity-collection-set>',
      '</D:options>'
    ].join(''),
    headers: {
      "authorization": svn.basicAuthorization,
      "dav": svn.davHeader,
      //'user-agent': 'SVN/1.9.2 (x86_64-apple-darwin15.0.0) serf/1.3.8',
      //'connection': "keep-alive",
      "content-type": XML_CONTENT_TYPE
    }
  }).then(response => {
    const headers = response.headers._headers;

    //console.log(`Headers ${JSON.stringify(headers)}`);
    //console.log(`RAW headers: ${JSON.stringify(headers.raw)}`);

    SVNHeaders.forEach(h => {
      if (headers[h]) {
        attributes[h] = headers[h];
        console.log(`${h}: ${headers[h]}`);
      }
    });

    headerIntoSet(headers.dav, davFeatures);
    headerIntoSet(headers.allow, allowedMethods);

    attributes['SVN-Youngest-Rev'] = parseInt(headers['SVN-Youngest-Rev'], 10);

    //console.log(`rev: ${headers['SVN-Youngest-Rev']}`);
    //console.log(`Attributes: ${JSON.stringify(attributes)}`);
    return svn;
  });
}

function headerIntoSet(header, target) {
  if (header) {
    header.forEach(h => h.split(/\s*,\s*/).forEach(e => target.add(e)));
  }
}
<|endoftext|>


<commit_before>/**
 * Created by peter on 9/9/16.
 */

// ==UserScript==
// @name                Elbow Grease
// @namespace	        http://v.numag.net/grease/
// @description	        grab torrents for direct download
// @include		http://bt.aisex.com/bt/*
// ==/UserScript==

var myRequest = new Request('http://v.numag.net/grease', {method: 'POST', body: '{"url":"http://www.jandown.com/link.php?ref=QU8lml7MET"}'});
var myHeaders = new Headers();
myHeaders.append('Content-Type', 'application/json');
var myInit = { method: 'POST',
    headers: myHeaders,
    mode: 'cors',
    cache: 'default' };
fetch(myRequest,myInit).then(function(response) {
    console.info(response);
})<commit_msg>userscript<commit_after>/**
 * Created by peter on 9/9/16.
 */

// ==UserScript==
// @name                Elbow Grease
// @namespace	        http://v.numag.net/grease/
// @description	        grab torrents for direct download
// @include		http://bt.aisex.com/bt/*
// ==/UserScript==

var myRequest = new Request('http://v.numag.net/grease', {method: 'POST', body: '{"url":"http://www.jandown.com/link.php?ref=QU8lml7MET"}'});
var myHeaders = new Headers();
myHeaders.append('Content-Type', 'application/json');
var myInit = { method: 'POST',
    headers: myHeaders,
    mode: 'cors',
    cache: 'default' };
fetch(myRequest,myInit).then(function(response) {
    response.json().then(function(json) {
        console.info(response);
    });
})<|endoftext|>


<commit_before>import {stringify} from "querystring"
import {createSign} from "crypto"
import {Readable} from "stream"
import {request} from "https"
import {parse} from "url"

const OAUTH2_URL = "https://accounts.google.com/o/oauth2/token"
const GRANT_TYPE = "urn:ietf:params:oauth:grant-type:jwt-bearer"
const JWT_HEADER = {alg: "RS256", typ: "JWT"}

export class Token {
  constructor(email, key, scopes, options = {}) {
    this.email = email
    this.key = key
    this.scopes = scopes

    this.ttl = options.ttl || 3600000 // 1 hour
    this.pad = options.pad || 60000 // refresh 1m before expiration
  }

  get(cb) {
    let now = Date.now()

    if (this.cached && now < this.cached.expiresAt) {
      return setImmediate(cb, null, this.cached.value)
    }

    this.fetch((err, token) => {
      if (err) return cb(err)

      this.cached = {
        value: token,
        expiresAt: now + (token.expires_in * 1000) - this.pad
      }

      cb(null, token)
    })
  }

  fetch(cb) {
    if (typeof this.key._read == "function") {
      let key = ""

      this.key.on("data", data => key += data)
      this.key.on("error", cb)
      this.key.on("end", () => {
        this.key = key
        this.fetch(cb)
      })

      return
    }

    let now = Date.now()

    let claims = {
      iss: this.email,
      scope: this.scopes.join(" "),
      aud: OAUTH2_URL,
      iat: Math.floor((now           ) / 1000),
      exp: Math.floor((now + this.ttl) / 1000)
    }

    let data = [JWT_HEADER, claims]
      .map(JSON.stringify)
      .map(Buffer)
      .map(x => x.toString("base64"))
      .join(".")

    let sig = createSign("RSA-SHA256")
      .update(data)
      .sign(this.key, "base64")

    let body = stringify({
      grant_type: GRANT_TYPE,
      assertion: [data, sig].join(".")
    })

    let options = parse(OAUTH2_URL)
    options.method = "POST"
    options.headers = {"Content-Type": "application/x-www-form-urlencoded"}

    let req = request(options, res => {
      let json = ""
      res.on("data", data => json += data)
      res.on("end", () => {
        try {
          let token = JSON.parse(json)

          "error" in token
            ? cb(new Error(`Token error: ${token.error}`))
            : cb(null, token)
        }

        catch (err) { cb(err) }
      })
    })

    req.on("error", cb)
    req.end(body)
  }

  createReadStream() {
    let rs = new Readable({objectMode: true})

    rs._read = () => {
      rs._read = wait
      fetch()
    }

    let wait = () => {
      setTimeout(fetch, this.ttl - this.pad)
    }

    let fetch = () => {
      this.fetch((err, token) => {
        err ? rs.emit("error", err) : rs.push(token)
      })
    }

    return rs
  }
}
<commit_msg>prevent 0.10/0.11 weirdness due to Buffer args<commit_after>import {stringify} from "querystring"
import {createSign} from "crypto"
import {Readable} from "stream"
import {request} from "https"
import {parse} from "url"

const OAUTH2_URL = "https://accounts.google.com/o/oauth2/token"
const GRANT_TYPE = "urn:ietf:params:oauth:grant-type:jwt-bearer"
const JWT_HEADER = {alg: "RS256", typ: "JWT"}

export class Token {
  constructor(email, key, scopes, options = {}) {
    this.email = email
    this.key = key
    this.scopes = scopes

    this.ttl = options.ttl || 3600000 // 1 hour
    this.pad = options.pad || 60000 // refresh 1m before expiration
  }

  get(cb) {
    let now = Date.now()

    if (this.cached && now < this.cached.expiresAt) {
      return setImmediate(cb, null, this.cached.value)
    }

    this.fetch((err, token) => {
      if (err) return cb(err)

      this.cached = {
        value: token,
        expiresAt: now + (token.expires_in * 1000) - this.pad
      }

      cb(null, token)
    })
  }

  fetch(cb) {
    if (typeof this.key._read == "function") {
      let key = ""

      this.key.on("data", data => key += data)
      this.key.on("error", cb)
      this.key.on("end", () => {
        this.key = key
        this.fetch(cb)
      })

      return
    }

    let now = Date.now()

    let claims = {
      iss: this.email,
      scope: this.scopes.join(" "),
      aud: OAUTH2_URL,
      iat: Math.floor((now           ) / 1000),
      exp: Math.floor((now + this.ttl) / 1000)
    }

    let data = [JWT_HEADER, claims]
      .map(x => Buffer(JSON.stringify(x)).toString("base64"))
      .join(".")

    let sig = createSign("RSA-SHA256")
      .update(data)
      .sign(this.key, "base64")

    let body = stringify({
      grant_type: GRANT_TYPE,
      assertion: [data, sig].join(".")
    })

    let options = parse(OAUTH2_URL)
    options.method = "POST"
    options.headers = {"Content-Type": "application/x-www-form-urlencoded"}

    let req = request(options, res => {
      let json = ""
      res.on("data", data => json += data)
      res.on("end", () => {
        try {
          let token = JSON.parse(json)

          "error" in token
            ? cb(new Error(`Token error: ${token.error}`))
            : cb(null, token)
        }

        catch (err) { cb(err) }
      })
    })

    req.on("error", cb)
    req.end(body)
  }

  createReadStream() {
    let rs = new Readable({objectMode: true})

    rs._read = () => {
      rs._read = wait
      fetch()
    }

    let wait = () => {
      setTimeout(fetch, this.ttl - this.pad)
    }

    let fetch = () => {
      this.fetch((err, token) => {
        err ? rs.emit("error", err) : rs.push(token)
      })
    }

    return rs
  }
}
<|endoftext|>


<commit_before>/**
 * Created by momchillgorchev on 28/10/15.
 */

Meteor.startup(function(){

    return Meteor.methods({

        /**
         * Not used
         * @param to
         * @param from
         * @param subject
         * @param text
         */
        sendEmail: function (to, from, subject, text) {

            check([to, from, subject, text], [String]);

            // Let other method calls from the same client start running,
            // without waiting for the email sending to complete.
            this.unblock();

            Email.send({
                to: to,
                from: from,
                subject: subject,
                text: text
            });
        },

        /**
         * Add endpoint to the DB
         * @param service - object containing the new service data
         * @returns {*} - _id of the newly created entry
         */
        addEndpoint: function(requestData){
            if(requestData){
                var service = requestData.data;
                // Validate the service URL
                if(service.url.match(core.VALID_URL) !== null){

                    // Check for existing entry with that URL
                    var existingRecord = Endpoints.findOne({url: service.url, owner: requestData.owner});
                    if(existingRecord === undefined){

                        // Reset status
                        service.status = null;
                        // Find the next available id
                        var existingEntries = Endpoints.find({owner: requestData.owner}).count();
                        service.order = existingEntries + 1;
                        service.owner = Meteor.userId();
                        // And insert to DB
                        // log('Before insert', service);
                        var newEntry = Endpoints.insert(service);
                        if(newEntry){
                            service._id = newEntry;
                            Meteor.call('checkSingleService', service, function(err, res){
                                return !err;
                            });

                            return true;
                        }

                    } else {
                        throw new Meteor.Error(409, 'Service URL already exist');
                    }

                } else {
                    // Throw an error for not valid URL
                    throw new Meteor.Error(500, 'Not a valid URL: ['+ service.url +']');
                }
            }
            // Empty input
            return false;
        },

        /**
         * Removes DB entry by _id
         * @param id
         * @returns {*|any}
         */
        deleteEndpoint: function(id){

            // If valid input return the result of the DB operation
            // Else false
            return id ? Endpoints.remove({_id: id}) : false;
        },

        /**
         * Update DB entry with data passed from the client
         * @param data
         * @returns {boolean}
         */
        updateEndpointInfo: function(data){
            // This will be an existing service every time
            // But its a good measure as this method call
            // is coming from the client
            var service = Endpoints.find({_id: data.id}, {}).fetch();
            if(service.length){
                // Select by _id and update
                Endpoints.update(
                    {
                        _id: data.id
                    },
                    {
                        $set: {
                            name: data.name,
                            url: data.url,
                            info: data.info,
                            status: data.status
                        }
                    }
                );
                return true;
            }
            return false;
        },

        /**
         * Updates endpoint status
         * @param service - endpoint to update
         */
        updateEndpointStatus: function(service){

            if(service){
                try{
                    // Select by URL and update
                    return Endpoints.update({url: service.url},
                        {
                            $set: {
                                lastStatusCode: service.lastStatusCode,
                                status: service.status
                            }
                        }
                    );

                } catch(e){
                    throw new Meteor.Error(500, 'Internal Server Error');
                }
            }
        },

        /**
         * Set new order to endpoints after client side rearrange (drag and drop)
         * @param endpoints -
         * Array of objects containing the ID to be updated
         * and the new order numerical value
         */
        updateEndpointsOrder: function(endpoints){

            // Check input
            check(endpoints, Array);

            // Iterate and update
            for(var i = 0, count = endpoints.length; i < count; i++){

                var current = endpoints[i];

                // Select by ID and update the order field
                Endpoints.update({_id: current.itemId},
                    {
                        $set: {
                            order: current.newOrder
                        }
                    }
                );
            }

            return true;
        },

        /**
         * Ping single service to check the status
         * Built to be reusable from the client and internal server processes
         * @param service - Object containing the service details
         * @returns {any} - Returns the result of updateEndpointStatus method
         */
        checkSingleService: function(service){

            // Validate the input
            // This is necessary as this method is used by the client as well
            check(service, Object);

            // Request the db entry and compare urls
            // This is necessary as this method is used by the client as well
            var dbEntry = Endpoints.findOne({_id: service._id}),
                result, actualStatus;

            // If everything match
            if(service.url === dbEntry.url){

                // Init check call
                try{
                    // Plain GET request, needs to be updated when
                    // specifying a method is implemented
                    result = HTTP[service.method](service.url, {});

                    // Keep the orange status
                    // Or look for 'updated manually' flag (not implemented)
                    if(dbEntry.status === 'orange' || result.statusCode !== 200){
                        actualStatus = 'orange';
                    } else if(result.statusCode === '503'){
                        actualStatus = 'red';
                    } else {
                        actualStatus = 'green';
                    }

                    // [DEBUG]
                    //log('Status color code after ping: '+ dbEntry.status);

                    // Update with new response data
                    dbEntry.lastStatusCode = result.statusCode;
                    dbEntry.status = actualStatus;

                // Catch any exceptions
                } catch(e){

                    // [DEBUG]
                    log(e);
                    //// TODO handle all error codes
                    //result.statusCode = '501';
                    //error = true;

                    dbEntry.status = 'red';
                    dbEntry.lastStatusCode = '503';

                    // TODO Implement send email here
                    // If alert is set for this service

                }

                // [DEBUG]
                //console.log('updateEndpointStatus called with:', service);

                // Update the DB
                return Meteor.call('updateEndpointStatus', dbEntry);

            }

        },

        /**
         * Run HTTP call for each entry in the DB
         * @returns {boolean}
         */
        checkServicesStatus: function(){

            // Allow other messages to use the DDP
            this.unblock();
            // Get the DB data
            var allServices = Endpoints.find({owner: Meteor.userId()}).fetch(),
                error = false;

            // Iterate over all entries
            // This needs to be updated when pagination is implemented
            // Right now it doesn't scale
            for(var i = 0, count = allServices.length; i < count; i++){
                var current = allServices[i];

                // [DEBUG]
                //log('Calling '+ current.url);

                // Call method to check single service
                Meteor.call('checkSingleService', current, function(err, res){
                    //log(err ? err : res);
                });
            }
            return !error;
        },

        dropDB: function(){
            return Endpoints.remove({});
        }
    });

});
<commit_msg>Adding personalised mongo queries<commit_after>/**
 * Created by momchillgorchev on 28/10/15.
 */

Meteor.startup(function(){

    return Meteor.methods({

        /**
         * Not used
         * @param to
         * @param from
         * @param subject
         * @param text
         */
        sendEmail: function (to, from, subject, text) {

            check([to, from, subject, text], [String]);

            // Let other method calls from the same client start running,
            // without waiting for the email sending to complete.
            this.unblock();

            Email.send({
                to: to,
                from: from,
                subject: subject,
                text: text
            });
        },

        /**
         * Add endpoint to the DB
         * @param service - object containing the new service data
         * @returns {*} - _id of the newly created entry
         */
        addEndpoint: function(requestData){
            if(requestData){
                var service = requestData.data;
                // Validate the service URL
                if(service.url.match(core.VALID_URL) !== null){

                    // Check for existing entry with that URL
                    var existingRecord = Endpoints.findOne({url: service.url, owner: requestData.owner});
                    if(existingRecord === undefined){

                        // Reset status
                        service.status = null;
                        // Find the next available id
                        var existingEntries = Endpoints.find({owner: requestData.owner}).count();
                        service.order = existingEntries + 1;
                        service.owner = Meteor.userId();
                        // And insert to DB
                        // log('Before insert', service);
                        var newEntry = Endpoints.insert(service);
                        if(newEntry){
                            service._id = newEntry;
                            Meteor.call('checkSingleService', service, function(err, res){
                                return !err;
                            });

                            return true;
                        }

                    } else {
                        throw new Meteor.Error(409, 'Service URL already exist');
                    }

                } else {
                    // Throw an error for not valid URL
                    throw new Meteor.Error(500, 'Not a valid URL: ['+ service.url +']');
                }
            }
            // Empty input
            return false;
        },

        /**
         * Removes DB entry by _id
         * @param id
         * @returns {*|any}
         */
        deleteEndpoint: function(id){

            // If valid input return the result of the DB operation
            // Else false
            return id ? Endpoints.remove({_id: id}) : false;
        },

        /**
         * Update DB entry with data passed from the client
         * @param data
         * @returns {boolean}
         */
        updateEndpointInfo: function(data){
            // This will be an existing service every time
            // But its a good measure as this method call
            // is coming from the client
            var service = Endpoints.find({_id: data.id}, {}).fetch();
            if(service.length){
                // Select by _id and update
                Endpoints.update(
                    {
                        _id: data.id
                    },
                    {
                        $set: {
                            name: data.name,
                            url: data.url,
                            info: data.info,
                            status: data.status
                        }
                    }
                );
                return true;
            }
            return false;
        },

        /**
         * Updates endpoint status
         * @param service - endpoint to update
         */
        updateEndpointStatus: function(service){

            if(service){
                try{
                    // Select by URL and update
                    return Endpoints.update({url: service.url, owner: Meteor.userId()},
                        {
                            $set: {
                                lastStatusCode: service.lastStatusCode,
                                status: service.status
                            }
                        }
                    );

                } catch(e){
                    throw new Meteor.Error(500, 'Internal Server Error');
                }
            }
        },

        /**
         * Set new order to endpoints after client side rearrange (drag and drop)
         * @param endpoints -
         * Array of objects containing the ID to be updated
         * and the new order numerical value
         */
        updateEndpointsOrder: function(endpoints){

            // Check input
            check(endpoints, Array);

            // Iterate and update
            for(var i = 0, count = endpoints.length; i < count; i++){

                var current = endpoints[i];

                // Select by ID and update the order field
                Endpoints.update({_id: current.itemId, owner: Meteor.userId()},
                    {
                        $set: {
                            order: current.newOrder
                        }
                    }
                );
            }

            return true;
        },

        /**
         * Ping single service to check the status
         * Built to be reusable from the client and internal server processes
         * @param service - Object containing the service details
         * @returns {any} - Returns the result of updateEndpointStatus method
         */
        checkSingleService: function(service){

            // Validate the input
            // This is necessary as this method is used by the client as well
            check(service, Object);

            // Request the db entry and compare urls
            // This is necessary as this method is used by the client as well
            var dbEntry = Endpoints.findOne({_id: service._id, owner: Meteor.userId()}),
                result, actualStatus;

            // If everything match
            if(service.url === dbEntry.url){

                // Init check call
                try{
                    // Plain request
                    result = HTTP[service.method](service.url, {});

                    // Keep the orange status
                    // Or look for 'updated manually' flag (not implemented)
                    if(dbEntry.status === 'orange' || result.statusCode !== 200){
                        actualStatus = 'orange';
                    } else if(result.statusCode === '503'){
                        actualStatus = 'red';
                    } else {
                        actualStatus = 'green';
                    }

                    // [DEBUG]
                    //log('Status color code after ping: '+ dbEntry.status);

                    // Update with new response data
                    dbEntry.lastStatusCode = result.statusCode;
                    dbEntry.status = actualStatus;

                // Catch any exceptions
                } catch(e){

                    // [DEBUG]
                    log(e);
                    //// TODO handle all error codes
                    //result.statusCode = '501';
                    //error = true;

                    dbEntry.status = 'red';
                    dbEntry.lastStatusCode = '503';

                    // TODO Implement send email here
                    // If alert is set for this service

                }

                // [DEBUG]
                //console.log('updateEndpointStatus called with:', service);

                // Update the DB
                return Meteor.call('updateEndpointStatus', dbEntry);

            }

        },

        /**
         * Run HTTP call for each entry in the DB
         * @returns {boolean}
         */
        checkServicesStatus: function(){

            // Allow other messages to use the DDP
            this.unblock();
            // Get the DB data
            var allServices = Endpoints.find({owner: Meteor.userId()}).fetch(),
                error = false;

            // Iterate over all entries
            // This needs to be updated when pagination is implemented
            // Right now it doesn't scale
            for(var i = 0, count = allServices.length; i < count; i++){
                var current = allServices[i];

                // [DEBUG]
                //log('Calling '+ current.url);

                // Call method to check single service
                Meteor.call('checkSingleService', current, function(err, res){
                    //log(err ? err : res);
                });
            }
            return !error;
        },

        dropDB: function(){
            return Endpoints.remove({});
        }
    });

});
<|endoftext|>


<commit_before>/*jslint node: true */
'use strict';

var jpp = require('json-path-processor'),
    promise = require('promise'),

promise_all = function (tasks) {
    var values = [],
        keys = [],
        I,
        all = 0;

    for (I in tasks) {
        if (tasks.hasOwnProperty(I)) {
            all++;
            values.push(tasks[I]);
            keys.push(I);
        }
    }

    return promise.all(values).then(function (V) {
        var ret = {};

        for (I=0;I<all;I++) {
            ret[keys[I]] = V[I];
        }

        return ret;
    });
},

subtask = function (tasks) {
    var typeOf = typeof tasks,
        P;

    switch (typeOf) {
    case 'object':
        P = promise_all(tasks);
        break;
    case 'function':
    case 'array':
        P = new promise(tasks);
        break;
    default:
        P = promise.resolve(tasks);
    }
    this.then = P.then;
},

SUBTASK = function(tasks) {
    return new subtask(tasks);
};

subtask.prototype.pick = function (path) {
    return this.then(function (O) {
        return jpp(O, path);
    });
};

SUBTASK.isSubtask = function (O) {
    return O instanceof subtask;
};

SUBTASK.before = function (taskCreator, doFunc, This) {
    return function () {
        var result = doFunc.apply(This || this, [taskCreator, arguments]);

        if (result instanceof subtask) {
            return result;
        }

        if (result) {
            return SUBTASK(result);
        }

        return taskCreator.apply(This || this, arguments) || SUBTASK();
    };
};

module.exports = SUBTASK;
<commit_msg>remove .before() , it can be replaced by cache-manager package<commit_after>/*jslint node: true */
'use strict';

var jpp = require('json-path-processor'),
    promise = require('promise'),

promise_all = function (tasks) {
    var values = [],
        keys = [],
        I,
        all = 0;

    for (I in tasks) {
        if (tasks.hasOwnProperty(I)) {
            all++;
            values.push(tasks[I]);
            keys.push(I);
        }
    }

    return promise.all(values).then(function (V) {
        var ret = {};

        for (I=0;I<all;I++) {
            ret[keys[I]] = V[I];
        }

        return ret;
    });
},

subtask = function (tasks) {
    var typeOf = typeof tasks,
        P;

    switch (typeOf) {
    case 'object':
        P = promise_all(tasks);
        break;
    case 'function':
    case 'array':
        P = new promise(tasks);
        break;
    default:
        P = promise.resolve(tasks);
    }
    this.then = P.then;
},

SUBTASK = function(tasks) {
    return new subtask(tasks);
};

subtask.prototype.pick = function (path) {
    return this.then(function (O) {
        return jpp(O, path);
    });
};

SUBTASK.isSubtask = function (O) {
    return O instanceof subtask;
};

module.exports = SUBTASK;
<|endoftext|>


<commit_before>'use strict'

let emptyToNull = (data, outputData) => {
		for (let key in data) {
			let currentValue = null

			if (data[key] instanceof Array) {
				currentValue = emptyToNull(data[key], [])
			} else if (typeof data[key] === 'object') {
				currentValue = emptyToNull(data[key], {})
			} else if (data[key] === '') {
				currentValue = null
			} else {
				currentValue = data[key]
			}

			if (outputData instanceof Array) {
				outputData.push(currentValue)
				continue;
			}
			outputData[key] = currentValue
		}
		return outputData
	},
	getNested = (parent, field) => {
		if ((typeof parent !== 'object') || (typeof field !== 'string')) {
			return null
		}
		let fieldData = field.split('.'),
			currentElement = parent
		for (let i in fieldData) {
			let innerElement = fieldData[i]
			if (!currentElement || !currentElement[innerElement]) {
				return currentElement
			}
			currentElement = currentElement[innerElement]
		}
		return currentElement
	},
	changeKeyCase = (keyMap, input, outputType) => {
		let str = ''
			inputType = ''
		if (outputType === 'upper') {
			inputType = 'lower'
		} else if (outputType === 'lower') {
			inputType = 'upper'
		}

		if (typeof input === 'object') {
			str = JSON.stringify(input)
			keyMap.forEach((e, i) => {
				str = str.replace(new RegExp(`/("${e[inputType]}":)/g`), `"${e[outputType]}":`)
			})
		} else if (typeof input === 'string') {
			keyMap.forEach((e, i) => {
				str = str.replace(new RegExp(`/(?${e[inputType]}=)/g`), `?${e[outputType]}=`).replace(new RegExp(`/(&${e[inputType]}=)/g`), `&${e[outputType]}=`)
			})
		} else {
			str = input
		}
		return str
	}

module.exports = {emptyToNull, getNested, changeKeyCase}
<commit_msg>toolbelt fix<commit_after>'use strict'

let emptyToNull = (data, outputData) => {
		for (let key in data) {
			let currentValue = null

			if (data[key] instanceof Array) {
				currentValue = emptyToNull(data[key], [])
			} else if (typeof data[key] === 'object') {
				currentValue = emptyToNull(data[key], {})
			} else if (data[key] === '') {
				currentValue = null
			} else {
				currentValue = data[key]
			}

			if (outputData instanceof Array) {
				outputData.push(currentValue)
				continue;
			}
			outputData[key] = currentValue
		}
		return outputData
	},
	getNested = (parent, field) => {
		if ((typeof parent !== 'object') || (typeof field !== 'string')) {
			return null
		}
		let fieldData = field.split('.'),
			currentElement = parent
		for (let i in fieldData) {
			let innerElement = fieldData[i]
			if (!currentElement || !currentElement[innerElement]) {
				return currentElement
			}
			currentElement = currentElement[innerElement]
		}
		return currentElement
	},
	changeKeyCase = (keyMap, input, outputType) => {
		let str = '',
			inputType = ''
		if (outputType === 'upper') {
			inputType = 'lower'
		} else if (outputType === 'lower') {
			inputType = 'upper'
		}

		if (typeof input === 'object') {
			str = JSON.stringify(input)
			keyMap.forEach((e, i) => {
				str = str.replace(new RegExp(`/("${e[inputType]}":)/g`), `"${e[outputType]}":`)
			})
		} else if (typeof input === 'string') {
			keyMap.forEach((e, i) => {
				str = str.replace(new RegExp(`/(?${e[inputType]}=)/g`), `?${e[outputType]}=`).replace(new RegExp(`/(&${e[inputType]}=)/g`), `&${e[outputType]}=`)
			})
		} else {
			str = input
		}
		return str
	}

module.exports = {emptyToNull, getNested, changeKeyCase}
<|endoftext|>


<commit_before>/**
 * Module dependencies
 */

var _ = require('lodash'),
  async = require('async'),
  getRelations = require('../../../utils/getRelations');

/**
 * Try and synchronize the underlying physical-layer schema
 * to work with our app's collections. (i.e. models)
 *
 * @param  {Function} cb
 */
module.exports = function(cb) {
  var self = this;

  //
  // TODO:
  // Refuse to run this migration strategy in production.
  //

  // Find any junctionTables that reference this collection
  var relations = getRelations({
    schema: self.query.waterline.schema,
    parentCollection: self.collection
  });

  var backupData;

  // Check that collection exists--
  self.describe(function afterDescribe(err, attrs) {
    if(err) return cb(err);

    // if it doesn't go ahead and add it and get out
    if(!attrs) return self.define(cb);

    //
    // TODO:
    // Take a look and see if anything important has changed.
    // If it has (at all), we still have to follow the naive strategy below,
    // but it will at least save time in the general case.
    // (because it really sucks to have to wait for all of this to happen
    //  every time you initialize Waterline.)
    //

    //
    // OK so we have to fix up the schema and migrate the data...
    //
    // ... we'll let Waterline do it for us.
    //
    // Load all data from this collection into memory.
    // If this doesn't work, crash to avoid corrupting any data.
    // (see `waterline/lib/adapter/ddl/README.md` for more info about this)
    //
    self.find({}, function (err, existingData) {
      if (err) {
        //
        // TODO:
        // If this was a memory error, log a more useful error
        // explaining what happened.
        //
        return cb(err);
      }

      //
      // From this point forward, we must be very careful.
      //
      backupData = _.cloneDeep(existingData);

      // Now we'll drop the collection.
      self.drop(relations, function (err) {
        if (err) return uhoh(err, backupData, cb);

        // Now we'll redefine the collection.
        self.define(function (err) {
          if (err) return uhoh(err, backupData, cb);

          // Now we'll create the `backupData` again,
          // being careful not to run any lifecycle callbacks
          // and disable automatic updating of `createdAt` and
          // `updatedAt` attributes:
          //
          // ((((TODO: actually be careful about said things))))
          //
          var MAX_SIMUL_CREATES = 20;
          async.eachLimit(backupData, MAX_SIMUL_CREATES, function (record, next) {
            self.create(record, next);
          }, function (err) {
            if (err) return uhoh(err, backupData, cb);

            // Done.
            return cb();
          });

        }); // </define>
      }); // </drop>
    }); // </find>

    //
    // The old way-- (doesn't always work, and is way more
    // complex than we should spend time on for now)
    //
    //   ||      ||      ||      ||      ||      ||
    //   \/      \/      \/      \/      \/      \/
    //
    // Otherwise, if it *DOES* exist, we'll try and guess what changes need to be made
    // self.alter(function(err) {
    //   if(err) return cb(err);
    //   cb();
    // });

  });
};

/**
 * uh oh.
 *
 * If we can't persist the data again, we'll log an error message, then
 * stream the data to stdout as JSON to make sure that it gets persisted
 * SOMEWHERE at least.
 *
 * (this is another reason this automigration strategy cannot be used in
 * production currently..)
 *
 * @param  {[type]}   err        [description]
 * @param  {[type]}   backupData [description]
 * @param  {Function} cb         [description]
 * @return {[type]}              [description]
 */

function uhoh (err, backupData, cb) {

  console.error('Waterline encountered a fatal error when trying to perform the `alter` auto-migration strategy.');
  console.error('In a couple of seconds, the data (cached in memory) will be logged to stdout.');
  console.error('(a failsafe put in place to preserve development data)');
  console.error();
  console.error('In the mean time, here\'s the error:');
  console.error();
  console.error(err);
  console.error();
  console.error();

  setTimeout(function () {
    console.error('================================');
    console.error('Data backup:');
    console.error('================================');
    console.error('');
    console.log(backupData);
    return cb(err);
  }, 1200);

}
<commit_msg>use createEach instead of an async create<commit_after>/**
 * Module dependencies
 */

var _ = require('lodash'),
  async = require('async'),
  getRelations = require('../../../utils/getRelations');

/**
 * Try and synchronize the underlying physical-layer schema
 * to work with our app's collections. (i.e. models)
 *
 * @param  {Function} cb
 */
module.exports = function(cb) {
  var self = this;

  //
  // TODO:
  // Refuse to run this migration strategy in production.
  //

  // Find any junctionTables that reference this collection
  var relations = getRelations({
    schema: self.query.waterline.schema,
    parentCollection: self.collection
  });

  var backupData;

  // Check that collection exists--
  self.describe(function afterDescribe(err, attrs) {
    if(err) return cb(err);

    // if it doesn't go ahead and add it and get out
    if(!attrs) return self.define(cb);

    //
    // TODO:
    // Take a look and see if anything important has changed.
    // If it has (at all), we still have to follow the naive strategy below,
    // but it will at least save time in the general case.
    // (because it really sucks to have to wait for all of this to happen
    //  every time you initialize Waterline.)
    //

    //
    // OK so we have to fix up the schema and migrate the data...
    //
    // ... we'll let Waterline do it for us.
    //
    // Load all data from this collection into memory.
    // If this doesn't work, crash to avoid corrupting any data.
    // (see `waterline/lib/adapter/ddl/README.md` for more info about this)
    //
    self.find({}, function (err, existingData) {
      if (err) {
        //
        // TODO:
        // If this was a memory error, log a more useful error
        // explaining what happened.
        //
        return cb(err);
      }

      //
      // From this point forward, we must be very careful.
      //
      backupData = _.cloneDeep(existingData);

      // Now we'll drop the collection.
      self.drop(relations, function (err) {
        if (err) return uhoh(err, backupData, cb);

        // Now we'll redefine the collection.
        self.define(function (err) {
          if (err) return uhoh(err, backupData, cb);

          // Now we'll create the `backupData` again,
          // being careful not to run any lifecycle callbacks
          // and disable automatic updating of `createdAt` and
          // `updatedAt` attributes:
          //
          // ((((TODO: actually be careful about said things))))
          //
          self.createEach(backupData, function(err) {
            if (err) return uhoh(err, backupData, cb);

            // Done.
            return cb();
          });

        }); // </define>
      }); // </drop>
    }); // </find>

    //
    // The old way-- (doesn't always work, and is way more
    // complex than we should spend time on for now)
    //
    //   ||      ||      ||      ||      ||      ||
    //   \/      \/      \/      \/      \/      \/
    //
    // Otherwise, if it *DOES* exist, we'll try and guess what changes need to be made
    // self.alter(function(err) {
    //   if(err) return cb(err);
    //   cb();
    // });

  });
};

/**
 * uh oh.
 *
 * If we can't persist the data again, we'll log an error message, then
 * stream the data to stdout as JSON to make sure that it gets persisted
 * SOMEWHERE at least.
 *
 * (this is another reason this automigration strategy cannot be used in
 * production currently..)
 *
 * @param  {[type]}   err        [description]
 * @param  {[type]}   backupData [description]
 * @param  {Function} cb         [description]
 * @return {[type]}              [description]
 */

function uhoh (err, backupData, cb) {

  console.error('Waterline encountered a fatal error when trying to perform the `alter` auto-migration strategy.');
  console.error('In a couple of seconds, the data (cached in memory) will be logged to stdout.');
  console.error('(a failsafe put in place to preserve development data)');
  console.error();
  console.error('In the mean time, here\'s the error:');
  console.error();
  console.error(err);
  console.error();
  console.error();

  setTimeout(function () {
    console.error('================================');
    console.error('Data backup:');
    console.error('================================');
    console.error('');
    console.log(backupData);
    return cb(err);
  }, 1200);

}
<|endoftext|>


<commit_before>import { Command } from 'commander'
import semver from 'semver'
import uniqBy from 'lodash.uniqby'
import { version } from '../package.json'
import { fetchRemote } from './remote'
import { fetchCommits } from './commits'
import { parseReleases, sortReleases } from './releases'
import { compileTemplate } from './template'
import { parseLimit, readJson, writeFile, fileExists, log, formatBytes } from './utils'

const DEFAULT_OPTIONS = {
  output: 'CHANGELOG.md',
  template: 'compact',
  remote: 'origin',
  commitLimit: 3,
  backfillLimit: 3,
  tagPrefix: ''
}

const PACKAGE_FILE = 'package.json'
const PACKAGE_OPTIONS_KEY = 'auto-changelog'
const OPTIONS_DOTFILE = '.auto-changelog'

function getOptions (argv, pkg, dotOptions) {
  const options = new Command()
    .option('-o, --output [file]', `output file, default: ${DEFAULT_OPTIONS.output}`)
    .option('-t, --template [template]', `specify template to use [compact, keepachangelog, json], default: ${DEFAULT_OPTIONS.template}`)
    .option('-r, --remote [remote]', `specify git remote to use for links, default: ${DEFAULT_OPTIONS.remote}`)
    .option('-p, --package', 'use version from package.json as latest release')
    .option('-v, --latest-version [version]', 'use specified version as latest release')
    .option('-u, --unreleased', 'include section for unreleased changes')
    .option('-l, --commit-limit [count]', `number of commits to display per release, default: ${DEFAULT_OPTIONS.commitLimit}`, parseLimit)
    .option('-b, --backfill-limit [count]', `number of commits to backfill empty releases with, default: ${DEFAULT_OPTIONS.backfillLimit}`, parseLimit)
    .option('-i, --issue-url [url]', 'override url for issues, use {id} for issue id')
    .option('--issue-pattern [regex]', 'override regex pattern for issues in commit messages')
    .option('--breaking-pattern [regex]', 'regex pattern for breaking change commits')
    .option('--ignore-commit-pattern [regex]', 'pattern to ignore when parsing commits')
    .option('--tag-pattern [regex]', 'override regex pattern for release tags')
    .option('--tag-prefix [prefix]', 'prefix used in version tags')
    .option('--starting-commit [hash]', 'starting commit to use for changelog generation')
    .option('--include-branch [branch]', 'one or more branches to include commits from, comma separated', str => str.split(','))
    .option('--release-summary', 'use tagged commit message body as release summary')
    .version(version)
    .parse(argv)

  if (!pkg) {
    if (options.package) {
      throw new Error('package.json could not be found')
    }
    return {
      ...DEFAULT_OPTIONS,
      ...dotOptions,
      ...options
    }
  }
  return {
    ...DEFAULT_OPTIONS,
    ...dotOptions,
    ...pkg[PACKAGE_OPTIONS_KEY],
    ...options
  }
}

function getLatestVersion (options, pkg, commits) {
  if (options.latestVersion) {
    if (!semver.valid(options.latestVersion)) {
      throw new Error('--latest-version must be a valid semver version')
    }
    return options.latestVersion
  }
  if (options.package) {
    const prefix = commits.some(c => /^v/.test(c.tag)) ? 'v' : ''
    return `${prefix}${pkg.version}`
  }
  return null
}

async function getReleases (commits, remote, latestVersion, options) {
  let releases = parseReleases(commits, remote, latestVersion, options)
  if (options.includeBranch) {
    for (const branch of options.includeBranch) {
      const commits = await fetchCommits(remote, options, branch)
      releases = [
        ...releases,
        ...parseReleases(commits, remote, latestVersion, options)
      ]
    }
  }
  return uniqBy(releases, 'tag').sort(sortReleases)
}

export default async function run (argv) {
  log('Fetching config…')
  const pkg = await fileExists(PACKAGE_FILE) && await readJson(PACKAGE_FILE)
  const dotOptions = await fileExists(OPTIONS_DOTFILE) && await readJson(OPTIONS_DOTFILE)
  const options = getOptions(argv, pkg, dotOptions)
  log('Fetching remote…')
  const remote = await fetchRemote(options.remote)
  const commitProgress = bytes => log(`Fetching commits… ${formatBytes(bytes)} loaded`)
  const commits = await fetchCommits(remote, options, null, commitProgress)
  log('Generating changelog…')
  const latestVersion = getLatestVersion(options, pkg, commits)
  const releases = await getReleases(commits, remote, latestVersion, options)
  const changelog = await compileTemplate(options.template, { releases })
  await writeFile(options.output, changelog)
  const bytes = Buffer.byteLength(changelog, 'utf8')
  log(`${formatBytes(bytes)} written to ${options.output}\n`)
}
<commit_msg>Remove initial info log<commit_after>import { Command } from 'commander'
import semver from 'semver'
import uniqBy from 'lodash.uniqby'
import { version } from '../package.json'
import { fetchRemote } from './remote'
import { fetchCommits } from './commits'
import { parseReleases, sortReleases } from './releases'
import { compileTemplate } from './template'
import { parseLimit, readJson, writeFile, fileExists, log, formatBytes } from './utils'

const DEFAULT_OPTIONS = {
  output: 'CHANGELOG.md',
  template: 'compact',
  remote: 'origin',
  commitLimit: 3,
  backfillLimit: 3,
  tagPrefix: ''
}

const PACKAGE_FILE = 'package.json'
const PACKAGE_OPTIONS_KEY = 'auto-changelog'
const OPTIONS_DOTFILE = '.auto-changelog'

function getOptions (argv, pkg, dotOptions) {
  const options = new Command()
    .option('-o, --output [file]', `output file, default: ${DEFAULT_OPTIONS.output}`)
    .option('-t, --template [template]', `specify template to use [compact, keepachangelog, json], default: ${DEFAULT_OPTIONS.template}`)
    .option('-r, --remote [remote]', `specify git remote to use for links, default: ${DEFAULT_OPTIONS.remote}`)
    .option('-p, --package', 'use version from package.json as latest release')
    .option('-v, --latest-version [version]', 'use specified version as latest release')
    .option('-u, --unreleased', 'include section for unreleased changes')
    .option('-l, --commit-limit [count]', `number of commits to display per release, default: ${DEFAULT_OPTIONS.commitLimit}`, parseLimit)
    .option('-b, --backfill-limit [count]', `number of commits to backfill empty releases with, default: ${DEFAULT_OPTIONS.backfillLimit}`, parseLimit)
    .option('-i, --issue-url [url]', 'override url for issues, use {id} for issue id')
    .option('--issue-pattern [regex]', 'override regex pattern for issues in commit messages')
    .option('--breaking-pattern [regex]', 'regex pattern for breaking change commits')
    .option('--ignore-commit-pattern [regex]', 'pattern to ignore when parsing commits')
    .option('--tag-pattern [regex]', 'override regex pattern for release tags')
    .option('--tag-prefix [prefix]', 'prefix used in version tags')
    .option('--starting-commit [hash]', 'starting commit to use for changelog generation')
    .option('--include-branch [branch]', 'one or more branches to include commits from, comma separated', str => str.split(','))
    .option('--release-summary', 'use tagged commit message body as release summary')
    .version(version)
    .parse(argv)

  if (!pkg) {
    if (options.package) {
      throw new Error('package.json could not be found')
    }
    return {
      ...DEFAULT_OPTIONS,
      ...dotOptions,
      ...options
    }
  }
  return {
    ...DEFAULT_OPTIONS,
    ...dotOptions,
    ...pkg[PACKAGE_OPTIONS_KEY],
    ...options
  }
}

function getLatestVersion (options, pkg, commits) {
  if (options.latestVersion) {
    if (!semver.valid(options.latestVersion)) {
      throw new Error('--latest-version must be a valid semver version')
    }
    return options.latestVersion
  }
  if (options.package) {
    const prefix = commits.some(c => /^v/.test(c.tag)) ? 'v' : ''
    return `${prefix}${pkg.version}`
  }
  return null
}

async function getReleases (commits, remote, latestVersion, options) {
  let releases = parseReleases(commits, remote, latestVersion, options)
  if (options.includeBranch) {
    for (const branch of options.includeBranch) {
      const commits = await fetchCommits(remote, options, branch)
      releases = [
        ...releases,
        ...parseReleases(commits, remote, latestVersion, options)
      ]
    }
  }
  return uniqBy(releases, 'tag').sort(sortReleases)
}

export default async function run (argv) {
  const pkg = await fileExists(PACKAGE_FILE) && await readJson(PACKAGE_FILE)
  const dotOptions = await fileExists(OPTIONS_DOTFILE) && await readJson(OPTIONS_DOTFILE)
  const options = getOptions(argv, pkg, dotOptions)
  log('Fetching remote…')
  const remote = await fetchRemote(options.remote)
  const commitProgress = bytes => log(`Fetching commits… ${formatBytes(bytes)} loaded`)
  const commits = await fetchCommits(remote, options, null, commitProgress)
  log('Generating changelog…')
  const latestVersion = getLatestVersion(options, pkg, commits)
  const releases = await getReleases(commits, remote, latestVersion, options)
  const changelog = await compileTemplate(options.template, { releases })
  await writeFile(options.output, changelog)
  const bytes = Buffer.byteLength(changelog, 'utf8')
  log(`${formatBytes(bytes)} written to ${options.output}\n`)
}
<|endoftext|>


<commit_before>'use strict';

const path = require('path');
const serverRootPath = path.normalize(path.join(__dirname, '../../'));

module.exports = {
    development: {
        rootPath: serverRootPath,
        port: 3000,
        db: {
            port: 27017,
            domain: "localhost",
            name: "developer_scope",
            connection: 'mongodb://localhost:27017/developer_scope'
        }
    },
    production: {
        port: process.env.NODE_PORT,
        rootPath: serverRootPath,
        db: {
            port: process.env.MONGO_DB_PORT,
            domain: process.env.MONGO_DB_DOMAIN,
            name: process.env.MONGO_DB_NAME,
            connection: process.env.MONGODB_CONNECTION_STRING
        }
    }
};<commit_msg>Update mongodb production config<commit_after>'use strict';

const path = require('path');
const serverRootPath = path.normalize(path.join(__dirname, '../../'));

module.exports = {
    development: {
        rootPath: serverRootPath,
        port: 3000,
        db: {
            port: 27017,
            domain: "localhost",
            name: "developer_scope",
            connection: 'mongodb://localhost:27017/developer_scope'
        }
    },
    production: {
        port: process.env.NODE_PORT,
        rootPath: serverRootPath,
        db: {
            port: process.env.MONGODB_PORT,
            domain: process.env.MONGODB_DOMAIN,
            name: process.env.MONGODB_NAME,
            connection: process.env.MONGODB_CONNECTION_STRING
        }
    }
};<|endoftext|>


<commit_before>define(['backbone', 'backbone-validation'], function(Backbone) {

  var Visit = Backbone.Model.extend({
    idAttribute: 'VISIT',
    urlRoot: '/proposal/visits',

    initialize: function(options) {
      this.on('change', this.addDate, this)
      this.addDate()
    },

    validation: {
        COMMENTS: {
            required: false,
            pattern: 'wwsdash',
        }
    },

    addDate: function() {
        this.attributes.STISO = new Date(this.get('STISO'))
        this.attributes.ENISO = new Date(this.get('ENISO'))
        this.attributes.LEN = (this.attributes.ENISO - this.attributes.STISO)/(3600*1000)
        this.attributes.VISITDETAIL = this.get('VISIT')+' ('+this.get('BL')+': '+this.get('ST')+')'
    }

  })

  _.extend(Visit.prototype, Backbone.Validation.mixin)
  return Visit

})<commit_msg>Restrict result of visit duration calculation to 2 decimal places.<commit_after>define(['backbone', 'backbone-validation'], function(Backbone) {

  var Visit = Backbone.Model.extend({
    idAttribute: 'VISIT',
    urlRoot: '/proposal/visits',

    initialize: function(options) {
      this.on('change', this.addDate, this)
      this.addDate()
    },

    validation: {
        COMMENTS: {
            required: false,
            pattern: 'wwsdash',
        }
    },

    addDate: function() {
        this.attributes.STISO = new Date(this.get('STISO'))
        this.attributes.ENISO = new Date(this.get('ENISO'))
        this.attributes.LEN = +((this.attributes.ENISO - this.attributes.STISO)/(3600*1000)).toFixed(2);
        this.attributes.VISITDETAIL = this.get('VISIT')+' ('+this.get('BL')+': '+this.get('ST')+')'
    }

  })

  _.extend(Visit.prototype, Backbone.Validation.mixin)
  return Visit

})<|endoftext|>


<commit_before>/**
 * Copyright (c) 2012, Ryuichi Okumura. All rights reserved.
 * Code licensed under the BSD License:
 * https://github.com/okuryu/node-iyql/blob/master/LICENSE.md
 */
'use strict';

var fs = require('fs'),
  path = require('path'),
  repl = require('repl'),
  querystring = require('querystring'),
  url = require('url'),
  nopt = require('nopt'),
  request = require('request'),
  knownOptions = {
    endpoint: url,
    env: url,
    help: Boolean,
    ssl: Boolean,
    version: Boolean
  },
  shortHands = {
    p: ['--endpoint'],
    e: ['--env'],
    h: ['--help'],
    s: ['--ssl'],
    v: ['--version']
  },
  options = nopt(knownOptions, shortHands);

function showHelp() {
  var help = 'Usage: iyql [options]\n' +
    '\n' +
    'Options:\n' +
    '  -p, --endpoint set YQL endpoint URL. default: ' +
    'http://query.yahooapis.com/v1/public/yql\n' +
    '  -e, --env      set YQL env URL\n' +
    '  -h, --help     print help\n' +
    '  -s, --ssl      use HTTPS endpoint\n' +
    '  -v, --version  print version\n';

  process.stdout.write(help);
}

function showVersion() {
  var version = require('../package.json').version;

  process.stdout.write('v' + version + '\n');
}

function replCallback(cmd, context, filename, callback) {
  var endpoint,
    query = cmd.slice(1).slice(0, -2),
    qs = querystring.stringify({
      diagnostics: 'true',
      debug: 'true',
      env: options.env || 'http://www.datatables.org/alltables.env',
      format: 'json',
      q: query
    });

  if (options.endpoint) {
    endpoint = options.endpoint;
  } else {
    endpoint = options.ssl ? 'https' : 'http';
    endpoint += '://query.yahooapis.com/v1/public/yql';
  }

  request(endpoint + '?' + qs, function (error, response, body) {
    callback(JSON.stringify(JSON.parse(body), null, 2));
  });
}

function main() {
  if (options.help) {
    showHelp();
    process.exit();
  } else if (options.version) {
    showVersion();
    process.exit();
  }

  repl.start({
    prompt: 'iyql> ',
    eval: replCallback,
    ignoreUndefined: true
  });
}

exports.route = function () {
  main();
};
<commit_msg>Fix missing first character from inputs<commit_after>/**
 * Copyright (c) 2012, Ryuichi Okumura. All rights reserved.
 * Code licensed under the BSD License:
 * https://github.com/okuryu/node-iyql/blob/master/LICENSE.md
 */
'use strict';

var fs = require('fs'),
  path = require('path'),
  repl = require('repl'),
  querystring = require('querystring'),
  url = require('url'),
  nopt = require('nopt'),
  request = require('request'),
  knownOptions = {
    endpoint: url,
    env: url,
    help: Boolean,
    ssl: Boolean,
    version: Boolean
  },
  shortHands = {
    p: ['--endpoint'],
    e: ['--env'],
    h: ['--help'],
    s: ['--ssl'],
    v: ['--version']
  },
  options = nopt(knownOptions, shortHands);

function showHelp() {
  var help = 'Usage: iyql [options]\n' +
    '\n' +
    'Options:\n' +
    '  -p, --endpoint set YQL endpoint URL. default: ' +
    'http://query.yahooapis.com/v1/public/yql\n' +
    '  -e, --env      set YQL env URL\n' +
    '  -h, --help     print help\n' +
    '  -s, --ssl      use HTTPS endpoint\n' +
    '  -v, --version  print version\n';

  process.stdout.write(help);
}

function showVersion() {
  var version = require('../package.json').version;

  process.stdout.write('v' + version + '\n');
}

function replCallback(cmd, context, filename, callback) {
  var endpoint,
    query = cmd.trim(),
    qs = querystring.stringify({
      diagnostics: 'true',
      debug: 'true',
      env: options.env || 'http://www.datatables.org/alltables.env',
      format: 'json',
      q: query
    });

  if (options.endpoint) {
    endpoint = options.endpoint;
  } else {
    endpoint = options.ssl ? 'https' : 'http';
    endpoint += '://query.yahooapis.com/v1/public/yql';
  }

  request(endpoint + '?' + qs, function (error, response, body) {
    callback(JSON.stringify(JSON.parse(body), null, 2));
  });
}

function main() {
  if (options.help) {
    showHelp();
    process.exit();
  } else if (options.version) {
    showVersion();
    process.exit();
  }

  repl.start({
    prompt: 'iyql> ',
    eval: replCallback,
    ignoreUndefined: true
  });
}

exports.route = function () {
  main();
};
<|endoftext|>