<commit_before>module.exports = {
  name: 'Multiple Bot Owners',
  version: '1.0.0',
  isCommandExtension: false,
  isEventExtension: false,
  isEditorExtension: true,

  fields: [],
  defaultFields: {},

  size () {
    return { height: 500, width: 500 }
  },

  html (data) {
    return `

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.8.0/css/bulma.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.12.1/css/all.min.css">

  The addition or removal of owners requires a bot restart.

  Current Owners

  Add owners

    <input id="ownerinput" class="input" type="text" placeholder="User ID">

`
  },

  init (document) {
    try {
      const fs = require('fs')
      const path = require('path')

      const filepath = path.join(__dirname, '../data', 'multiple_bot_owners.json')

      let botOwners = []

      function loadOwners () {
        if (!fs.existsSync(filepath)) {
          fs.writeFileSync(filepath, JSON.stringify(botOwners))
        } else {
          botOwners = JSON.parse(fs.readFileSync(filepath, 'utf8'))
        }

        botOwners.forEach(owner => {
          if (owner && /^\d+$/.test(owner)) {
            addOwnerHTML(owner)
          }
        })
      }

      function addOwnerHTML (owner) {
        document.getElementById('current-owners').innerHTML += `

 <input id="${owner}_INPUT" class="input" type="text" placeholder="User ID" disabled
				value="${owner}">

				`
      }

      document.delOwner = function (element) {
        const owner = element && element.value
        const element2 = document.getElementById(`${owner}_DIV`)
        alert(`${owner} was removed.`)
        if (!owner) return

        botOwners.splice(botOwners.indexOf(owner), 1)

        element.parentNode.removeChild(element)
        element2.parentNode.removeChild(element2)

        fs.writeFileSync(filepath, JSON.stringify(botOwners, null, 2))
      }

      document.addOwner = function (owner = false) {
        if (!owner) owner = document.getElementById('ownerinput').value

        if (!owner) {
          return alert('MultipleBotOwners\nYou must enter a value!')
        } else if (!/^\d+$/.test(owner)) {
          return alert(`MultipleBotOwners\nThe inputted value can only be a discord ID.\nYou put ${owner}.`)
        } else if (botOwners.includes(owner)) {
          return alert('MultipleBotOwners\nThat ID already exists!.')
        }

        addOwnerHTML(owner)
        botOwners.push(owner)
        fs.writeFileSync(filepath, JSON.stringify(botOwners))

        return 'ADDED'
      }
      loadOwners()
    } catch (error) {
      alert('MultipleBotOwners Error: \n' + error)
    }
  },

  close () {},

  mod (DBM) {
    const { Actions, Files } = DBM

    const fs = require('fs')
    const path = require('path')

    try {
      const filepath = path.join(__dirname, '../data', 'multiple_bot_owners.json')

      let botOwners = []

      if (!fs.existsSync(filepath)) {
        fs.writeFileSync(filepath, JSON.stringify(botOwners))
      } else {
        botOwners = JSON.parse(fs.readFileSync(filepath, 'utf8'))
      }

      Actions.checkConditions = function (msg, cmd) {
        const isServer = Boolean(msg.guild && msg.member)
        const restriction = parseInt(cmd.restriction)
        const permissions = cmd.permissions
        switch (restriction) {
          case 0:
            if (isServer) {
              return this.checkPermissions(msg, permissions)
            } else {
              return true
            }
          case 1:
            return isServer && this.checkPermissions(msg, permissions)
          case 2:
            return isServer && msg.guild.owner === msg.member
          case 3:
            return !isServer
          case 4:
            return (botOwners.length > 0 && botOwners.includes(msg.author.id)) ||
              (Files.data.settings.ownerId && msg.author.id === Files.data.settings.ownerId)
          default:
            return true
        }
      }
    } catch (error) {
      console.error('MultipleBotOwners_ERROR:\n' + error)
    }

    console.log('Multiple Bot Owners Extension Loaded!')
  }
}
<commit_msg>Fixed eslint errors (disabling most)<commit_after>/* eslint-disable no-undef */
module.exports = {
  name: 'Multiple Bot Owners',
  version: '1.0.0',
  isCommandExtension: false,
  isEventExtension: false,
  isEditorExtension: true,

  fields: [],
  defaultFields: {},

  size () {
    return { height: 500, width: 500 }
  },

  html (data) {
    return `

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.8.0/css/bulma.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.12.1/css/all.min.css">

  The addition or removal of owners requires a bot restart.

  Current Owners

  Add owners

    <input id="ownerinput" class="input" type="text" placeholder="User ID">

`
  },

  init (document) {
    try {
      const fs = require('fs')
      const path = require('path')

      const filepath = path.join(__dirname, '../data', 'multiple_bot_owners.json')

      let botOwners = []

      // eslint-disable-next-line no-inner-declarations
      function loadOwners () {
        if (!fs.existsSync(filepath)) {
          fs.writeFileSync(filepath, JSON.stringify(botOwners))
        } else {
          botOwners = JSON.parse(fs.readFileSync(filepath, 'utf8'))
        }

        botOwners.forEach(owner => {
          if (owner && /^\d+$/.test(owner)) {
            addOwnerHTML(owner)
          }
        })
      }

      // eslint-disable-next-line no-inner-declarations
      function addOwnerHTML (owner) {
        document.getElementById('current-owners').innerHTML += `

 <input id="${owner}_INPUT" class="input" type="text" placeholder="User ID" disabled
          value="${owner}">

        `
      }

      document.delOwner = function (element) {
        const owner = element && element.value
        const element2 = document.getElementById(`${owner}_DIV`)
        alert(`${owner} was removed.`)
        if (!owner) return

        botOwners.splice(botOwners.indexOf(owner), 1)

        element.parentNode.removeChild(element)
        element2.parentNode.removeChild(element2)

        fs.writeFileSync(filepath, JSON.stringify(botOwners, null, 2))
      }

      document.addOwner = function (owner = false) {
        if (!owner) owner = document.getElementById('ownerinput').value

        if (!owner) {
          return alert('MultipleBotOwners\nYou must enter a value!')
        } else if (!/^\d+$/.test(owner)) {
          return alert(`MultipleBotOwners\nThe inputted value can only be a discord ID.\nYou put ${owner}.`)
        } else if (botOwners.includes(owner)) {
          return alert('MultipleBotOwners\nThat ID already exists!.')
        }

        addOwnerHTML(owner)
        botOwners.push(owner)
        fs.writeFileSync(filepath, JSON.stringify(botOwners))

        return 'ADDED'
      }
      loadOwners()
    } catch (error) {
      alert('MultipleBotOwners Error: \n' + error)
    }
  },

  close () {},

  mod (DBM) {
    const { Actions, Files } = DBM

    const fs = require('fs')
    const path = require('path')

    try {
      const filepath = path.join(__dirname, '../data', 'multiple_bot_owners.json')

      let botOwners = []

      if (!fs.existsSync(filepath)) {
        fs.writeFileSync(filepath, JSON.stringify(botOwners))
      } else {
        botOwners = JSON.parse(fs.readFileSync(filepath, 'utf8'))
      }

      Actions.checkConditions = function (msg, cmd) {
        const isServer = Boolean(msg.guild && msg.member)
        const restriction = parseInt(cmd.restriction)
        const permissions = cmd.permissions
        switch (restriction) {
          case 0:
            if (isServer) {
              return this.checkPermissions(msg, permissions)
            } else {
              return true
            }
          case 1:
            return isServer && this.checkPermissions(msg, permissions)
          case 2:
            return isServer && msg.guild.owner === msg.member
          case 3:
            return !isServer
          case 4:
            return (botOwners.length > 0 && botOwners.includes(msg.author.id)) ||
              (Files.data.settings.ownerId && msg.author.id === Files.data.settings.ownerId)
          default:
            return true
        }
      }
    } catch (error) {
      console.error('MultipleBotOwners_ERROR:\n' + error)
    }

    console.log('Multiple Bot Owners Extension Loaded!')
  }
}
<|endoftext|>


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

var app = express();

require('./config/middleware.js')(app, express);
// require('./config/routes.js')(app, express);

var port = process.env.PORT || 3333;
var server = app.listen(port, function() {
  console.log('Server listening on port: ' + port);
});

module.exports = {
  app: app
};
<commit_msg>(feat) Expose route handlers for testing<commit_after>var express = require('express');
var app = express();

require('./config/middleware.js')(app, express);
require('./config/routes.js')(app, express);

// Uncomment for testing server routes
require('./config/worker.js').productRankByState('NY');
require('./config/worker.js').birthsInRange('bank', 2015);

var port = process.env.PORT || 3333;
var server = app.listen(port, function() {
  console.log('Server listening on port: ' + port);
  console.log(process.env.PORT, typeof ''+process.env.KEY);
});

module.exports = {
  app: app
};
<|endoftext|>


<commit_before>/**
 * CareWheels - Group Status Controller
 *
 */
angular.module('careWheels').controller('groupStatusController',
  function ($scope, $interval, $state, $ionicPopup, GroupInfo, User, PaymentService) {

    var groupArray = GroupInfo.groupInfo();

    // the groupInfo object is not available immediately, spin until available
    var initGroupInfo = setInterval(function () {
      var groupArray = GroupInfo.groupInfo();
      //console.log(groupArray);
      if (groupArray[0] != null) {
        clearInterval(initGroupInfo);
        // app on load
        console.log('hit group controller');
        getLoggedInUser(groupArray);
        setGroupArray(groupArray);
      }
    }, 50);

    /** automatically go through each user square, and
     *  find each 'red' alert, and fade that element in
     *  and out. (flashing effect)
     * */
    $interval(function () {
      /* jQuery element to fade in and out */
      var alertArray = [
        $('#topLeftAlert'),
        $('#topRightAlert'),
        $('#bottomLeftAlert'),
        $('#bottomRightAlert')
      ];
      for (var i = 0; i < alertArray.length; i++) {
        if (alertArray[i].css('background-color') === 'rgb(255, 0, 0)') {
          alertArray[i].fadeOut("slow");
          alertArray[i].fadeIn("slow");
        }
      }
    }, 2000);

    $scope.group = [
      { // center, self
        name: '',
        username: '',
        balance: '0.0',
        image: '',
        userSelected: '',
        displayedError: GroupInfo.getSensorError(),
        selfUserIndex: -1

      },
      { // top left @ index 1
        name: '',
        username: '',
        status: '',
        image: '',
        alertLevelColor: '',
        error: false
      },
      { // top right @ index 2
        name: '',
        username: '',
        status: '',
        image: '',
        alertLevelColor: '',
        error: false
      },
      { // bottom left @ index 3
        name: '',
        username: '',
        status: '',
        image: '',
        alertLevelColor: '',
        error: false
      },
      { // bottom right @ index 4
        name: '',
        username: '',
        status: '',
        image: '',
        alertLevelColor: '',
        error: false
      }
    ];

    /* click/press events */
    $scope.clickTopLeft = function () {
      clickUser(1);
    };
    $scope.clickTopRight = function () {
      clickUser(2);
    };
    $scope.clickBottomLeft = function () {
      clickUser(3);
    };
    $scope.clickBottomRight = function () {
      clickUser(4);
    };
    $scope.clickCenter = function () {
    };
    $scope.clickCareBank = function () {
    };

    // console.log("Calling memberSummary Payment:");
    // PaymentService.memberSummary(1.0);

    // lets figure out which user logged in at this point
    function getLoggedInUser(groupInfo) {
      console.log('group controller: getloggedinuser()');
      var user = User.credentials();
      // error unable to load user object;
      if (user == null){
        console.log('group controller: user not found');
        $scope.group[0].selfUserIndex = -1;
      }

      // loop through the groupInfo array to find the user who
      // logged in.
      for (var i = 0; i < groupInfo.length; i++) {
        console.log('logged in as:', user.username, '  and comparing with:', groupInfo[i].username);

        if (user.username == groupInfo[i].username){
          $scope.group[0].selfUserIndex = i; // gotcha!
          console.log('group controller: user found @ index', i);
          return true;
        }

      }

    }

    // now lets set the scope variables for the group view.
    function setGroupArray(groupArray) {
      var currentUser = 0;
      var fridgeAlert, medsAlert;

      var loggedInUserIndex = $scope.group[0].selfUserIndex;
      console.log('setGroupArray, logged in user at index', loggedInUserIndex);

      // next lets set the data for the user that logged in,
      // this is reserved at index zero.
      $scope.group[currentUser].image = groupArray[loggedInUserIndex].photoUrl;
      $scope.group[currentUser].username = groupArray[loggedInUserIndex].username;
      $scope.group[currentUser].name = groupArray[loggedInUserIndex].name;
      $scope.group[currentUser].balance = trimZeros(groupArray[loggedInUserIndex].balance);

      currentUser++; // = 1 at this point

      // put everyone else into the array
      for (var i = 0; i < 5; i++){
        // skip the user who logged in
        console.log('looping at index:', i);
        if(i != $scope.group[0].selfUserIndex){
          console.log('placing groupInfo member', i, 'into scope index', currentUser);
          $scope.group[currentUser].image = groupArray[i].photoUrl;
          $scope.group[currentUser].username = groupArray[i].username;
          $scope.group[currentUser].name = groupArray[i].name;

          try{
            fridgeAlert = groupArray[i].analysisData.fridgeAlertLevel;
            medsAlert = groupArray[i].analysisData.medsAlertLevel;
            $scope.group[currentUser].status = $scope.getAlertColor(fridgeAlert, medsAlert, i);
          }
          catch (Exception) {
            $scope.group[currentUser].status = 'grey';
            $scope.group[currentUser].error = true;
          }
          currentUser++;
        }
        else{
          console.log('skipping member', i, 'this is user who logged in');
        }
        // on the last element of the loop, now check health
        if (i == 4) {
          console.log('on last element');
          if(!GroupInfo.getSensorError())
            $scope.checkGroupHealth();
        }

      }

        //var userCount = 0;
      //// first lets set the group up, at index 1-4
      //for (var i = 0; i < 5; i++) {
      //  userCount++;
      //  if (i != $scope.group[0].selfUserIndex) {
      //    $scope.group[userCount].image = groupArray[i].photoUrl;
      //    $scope.group[userCount].username = groupArray[i].username;
      //    $scope.group[userCount].name = groupArray[i].name;
      //
      //    try {
      //      var fridgeAlert = groupArray[userCount].analysisData.fridgeAlertLevel;
      //      var medsAlert = groupArray[userCount].analysisData.medsAlertLevel;
      //      $scope.group[userCount].status = $scope.getAlertColor(fridgeAlert, medsAlert, i);
      //    }

      //  }
      //
      //}

    }

    //removes insignificant zeros
    function trimZeros(input) {
      var number = parseFloat(input);
      return number.toString();

    }

    function clickUser(index) {
      if (!$scope.group[index].error) {
        PaymentService.sensorDataView(0.1, $scope.group[index].alertLevelColor);
        $scope.group[0].userSelected = $scope.group[index].name;
        GroupInfo.setMember_new($scope.group[index].username);
        $state.go('app.individualStatus');
      }
    }

    // An error popup dialog
    function displayError(errorString) {
      var alertPopup = $ionicPopup.alert({
        title: '
Unable to load sensor data for:
',
        template: '
' + errorString + '
',
        buttons: [{ // Array[Object] (optional). Buttons to place in the popup footer.
          text: 'Okay',
          type: 'button-calm'
        }]
      });
      alertPopup.then(function (res) {

      });
    }

    /**
     * returns a string of of the color code depending on the
     * alert level. This string is used with ng-class, to
     * append the color class onto the div
     * */
    $scope.getAlertColor = function (fridgeAlert, medsAlert, index) {
      console.log('hit getAlertColor:', fridgeAlert, medsAlert, index);

      // check for null params
      if (fridgeAlert == null || medsAlert == null)
        return '';

      var fridge = parseInt(fridgeAlert);
      var meds = parseInt(medsAlert);
      var alertString = '';

      // check for acceptable bounds
      if (meds < 0 || meds > 2 || fridge < 0 || fridge > 2)
        alertString = ''; // error state
      // check for null
      else if (fridge == 2 || meds == 2)
        alertString = 'red';
      else if (fridge == 1 || meds == 1)
        alertString = 'yellow';
      else if (fridge == 0 || meds == 0)
        alertString = 'blue';
      $scope.group[index].alertLevelColor = alertString;
      return alertString;
    };

    $scope.checkGroupHealth = function () {
      console.log('hit checkGroupHealth();')
      //create a template string
      var errorList = [];
      var errorCount = 0;
      for (var i = 1; i < $scope.group.length; i++) {
        if ($scope.group[i].error) {
          errorCount++;
          errorList.push(String($scope.group[i].name));
        }
        // on the last element now
        if (i == $scope.group.length - 1) {
          // no errors? then return
          if (errorCount == 0){
            GroupInfo.setSensorError(false);
            return true;
          }

          // error found! set the error variable
          if(errorCount > 0)
            GroupInfo.setSensorError(true);

          //lets craft up a string to be displayed
          var errorString = '';
          for (var j = 0; j < errorList.length; j++) {
            errorString += errorList[j];
            if (j < errorList.length - 2)
              errorString += ', ';
            else if (j == errorList.length - 2)
              errorString += ' and ';
            else if (j == errorList.length - 1) {
              // were done, display error message now
              if (!$scope.group[0].displayedError) {
                $scope.group[0].displayedError = true;
                displayError(errorString);
              }

            }
          }
        }
      }
    };

  });
<commit_msg>removed console logs, and cleaned up code<commit_after>/**
 * CareWheels - Group Status Controller
 *
 */
angular.module('careWheels').controller('groupStatusController',
  function ($scope, $interval, $state, $ionicPopup, GroupInfo, User, PaymentService) {

    // the groupInfo object is not available immediately, spin until available
    var initGroupInfo = setInterval(function () {
      var groupArray = GroupInfo.groupInfo();
      if (groupArray[0] != null) {
        clearInterval(initGroupInfo);
        getLoggedInUser(groupArray);
        setGroupArray(groupArray);
      }
    }, 50);

    /** automatically go through each user square, and
     *  find each 'red' alert, and fade that element in
     *  and out. (flashing effect)
     * */
    $interval(function () {
      /* jQuery element to fade in and out */
      var alertArray = [
        $('#topLeftAlert'),
        $('#topRightAlert'),
        $('#bottomLeftAlert'),
        $('#bottomRightAlert')
      ];
      for (var i = 0; i < alertArray.length; i++) {
        if (alertArray[i].css('background-color') === 'rgb(255, 0, 0)') {
          alertArray[i].fadeOut("slow");
          alertArray[i].fadeIn("slow");
        }
      }
    }, 2000);

    $scope.group = [
      { // center, self
        name: '',
        username: '',
        balance: '0.0',
        image: '',
        userSelected: '',
        displayedError: GroupInfo.getSensorError(),
        selfUserIndex: -1

      },
      { // top left @ index 1
        name: '',
        username: '',
        status: '',
        image: '',
        alertLevelColor: '',
        error: false
      },
      { // top right @ index 2
        name: '',
        username: '',
        status: '',
        image: '',
        alertLevelColor: '',
        error: false
      },
      { // bottom left @ index 3
        name: '',
        username: '',
        status: '',
        image: '',
        alertLevelColor: '',
        error: false
      },
      { // bottom right @ index 4
        name: '',
        username: '',
        status: '',
        image: '',
        alertLevelColor: '',
        error: false
      }
    ];

    /* click/press events */
    $scope.clickTopLeft = function () {
      clickUser(1);
    };
    $scope.clickTopRight = function () {
      clickUser(2);
    };
    $scope.clickBottomLeft = function () {
      clickUser(3);
    };
    $scope.clickBottomRight = function () {
      clickUser(4);
    };
    $scope.clickCenter = function () {
    };
    $scope.clickCareBank = function () {
    };

    // lets figure out which user logged in at this point
    function getLoggedInUser(groupInfo) {
      var user = User.credentials();
      // error unable to load user object;
      if (user == null){
        $scope.group[0].selfUserIndex = -1;
      }

      // loop through the groupInfo array to find the user who
      // logged in.
      for (var i = 0; i < groupInfo.length; i++) {
        if (user.username == groupInfo[i].username){
          $scope.group[0].selfUserIndex = i; // gotcha!
          return true;
        }
      }
    }

    // now lets set the scope variables for the group view.
    function setGroupArray(groupArray) {
      var currentUser = 0;
      var fridgeAlert, medsAlert;

      var loggedInUserIndex = $scope.group[0].selfUserIndex;

      // next lets set the data for the user that logged in,
      // this is reserved at index zero.
      $scope.group[currentUser].image = groupArray[loggedInUserIndex].photoUrl;
      $scope.group[currentUser].username = groupArray[loggedInUserIndex].username;
      $scope.group[currentUser].name = groupArray[loggedInUserIndex].name;
      $scope.group[currentUser].balance = trimZeros(groupArray[loggedInUserIndex].balance);

      currentUser++; // = 1 at this point

      // put everyone else into the array
      for (var i = 0; i < 5; i++){
        // skip the user who logged in
        if(i != $scope.group[0].selfUserIndex){
          $scope.group[currentUser].image = groupArray[i].photoUrl;
          $scope.group[currentUser].username = groupArray[i].username;
          $scope.group[currentUser].name = groupArray[i].name;

          try{
            fridgeAlert = groupArray[i].analysisData.fridgeAlertLevel;
            medsAlert = groupArray[i].analysisData.medsAlertLevel;
            $scope.group[currentUser].status = $scope.getAlertColor(fridgeAlert, medsAlert, i);
          }
          catch (Exception) {
            $scope.group[currentUser].status = 'grey';
            $scope.group[currentUser].error = true;
          }
          currentUser++;
        }
        // on the last element of the loop, now check health
        if (i == 4) {
          if(!GroupInfo.getSensorError())
            $scope.checkGroupHealth();
        }

      }
    }

    //removes insignificant zeros
    function trimZeros(input) {
      var number = parseFloat(input);
      return number.toString();
    }

    function clickUser(index) {
      if (!$scope.group[index].error) {
        PaymentService.sensorDataView(0.1, $scope.group[index].alertLevelColor);
        $scope.group[0].userSelected = $scope.group[index].name;
        GroupInfo.setMember_new($scope.group[index].username);
        $state.go('app.individualStatus');
      }
    }

    // An error popup dialog
    function displayError(errorString) {
      var alertPopup = $ionicPopup.alert({
        title: '
Unable to load sensor data for:
',
        template: '
' + errorString + '
',
        buttons: [{ // Array[Object] (optional). Buttons to place in the popup footer.
          text: 'Okay',
          type: 'button-calm'
        }]
      });
      alertPopup.then(function (res) {

      });
    }

    /**
     * returns a string of of the color code depending on the
     * alert level. This string is used with ng-class, to
     * append the color class onto the div
     * */
    $scope.getAlertColor = function (fridgeAlert, medsAlert, index) {
      // check for null params
      if (fridgeAlert == null || medsAlert == null)
        return '';

      var fridge = parseInt(fridgeAlert);
      var meds = parseInt(medsAlert);
      var alertString = '';

      // check for acceptable bounds
      if (meds < 0 || meds > 2 || fridge < 0 || fridge > 2)
        alertString = ''; // error state
      // check for null
      else if (fridge == 2 || meds == 2)
        alertString = 'red';
      else if (fridge == 1 || meds == 1)
        alertString = 'yellow';
      else if (fridge == 0 || meds == 0)
        alertString = 'blue';
      $scope.group[index].alertLevelColor = alertString;
      return alertString;
    };

    $scope.checkGroupHealth = function () {
      //create a template string
      var errorList = [];
      var errorCount = 0;
      for (var i = 1; i < $scope.group.length; i++) {
        if ($scope.group[i].error) {
          errorCount++;
          errorList.push(String($scope.group[i].name));
        }
        // on the last element now
        if (i == $scope.group.length - 1) {
          // no errors? then return
          if (errorCount == 0){
            GroupInfo.setSensorError(false);
            return true;
          }
          // error found! set the error variable
          if(errorCount > 0)
            GroupInfo.setSensorError(true);

          //lets craft up a string to be displayed
          var errorString = '';
          for (var j = 0; j < errorList.length; j++) {
            errorString += errorList[j];
            if (j < errorList.length - 2)
              errorString += ', ';
            else if (j == errorList.length - 2)
              errorString += ' and ';
            else if (j == errorList.length - 1) {
              // were done, display error message now
              if (!$scope.group[0].displayedError) {
                $scope.group[0].displayedError = true;
                displayError(errorString);
              }
            }
          }
        }
      }
    };

  });
<|endoftext|>


<commit_before>import '../src'
import bufferEqual from 'buffer-equal'
import gulp from 'gulp'
import rump from 'rump'
import timeout from 'timeout-then'
import {colors} from 'gulp-util'
import {readFile, writeFile} from 'mz/fs'
import {sep} from 'path'
import {spy} from 'sinon'

const {stripColor} = colors

describe('tasks', function() {
  this.timeout(0)

  beforeEach(() => {
    rump.configure({paths: {
      source: {root: 'test/fixtures', static: ''},
      destination: {root: 'tmp'},
    }})
  })

  it('are added and defined', () => {
    const callback = spy()
    rump.on('gulp:main', callback)
    rump.on('gulp:static', callback)
    rump.addGulpTasks({prefix: 'spec'})
    callback.should.be.calledTwice()
    gulp.tasks['spec:info:static'].should.be.ok()
    gulp.tasks['spec:build:static'].should.be.ok()
    gulp.tasks['spec:watch:static'].should.be.ok()
  })

  it('display correct information in info task', () => {
    const logs = [],
          {log} = console
    console.log = (...args) => logs.push(stripColor(args.join(' ')))
    gulp.start('spec:info')
    console.log = log
    logs.slice(-6).should.eql([
      '',
      '--- Static v0.7.0',
      `Static files from test${sep}fixtures are copied to tmp`,
      'Affected files:',
      'index.html',
      '',
    ])
  })

  describe('for building', () => {
    let original

    before(async() => {
      original = await readFile('test/fixtures/index.html')
      await new Promise(resolve => {
        gulp.task('postbuild', ['spec:watch'], resolve)
        gulp.start('postbuild')
      })
    })

    beforeEach(() => timeout(1000))

    afterEach(() => writeFile('test/fixtures/index.html', original))

    it('handles updates', async() => {
      bufferEqual(original, await readFile('tmp/index.html')).should.be.true()
      await writeFile('test/fixtures/index.html', '
New
')
      await timeout(1000)
      bufferEqual(original, await readFile('tmp/index.html')).should.be.false()
    })
  })
})
<commit_msg>Test for not displaying info if no files are available<commit_after>import '../src'
import bufferEqual from 'buffer-equal'
import gulp from 'gulp'
import rump from 'rump'
import timeout from 'timeout-then'
import {colors} from 'gulp-util'
import {readFile, writeFile} from 'mz/fs'
import {sep} from 'path'
import {spy} from 'sinon'

const {stripColor} = colors

describe('tasks', function() {
  this.timeout(0)

  afterEach(() => {
    rump.configure({paths: {
      source: {root: 'test/fixtures', static: ''},
      destination: {root: 'tmp'},
    }})
  })

  it('are added and defined', () => {
    const callback = spy()
    rump.on('gulp:main', callback)
    rump.on('gulp:static', callback)
    rump.addGulpTasks({prefix: 'spec'})
    callback.should.be.calledTwice()
    gulp.tasks['spec:info:static'].should.be.ok()
    gulp.tasks['spec:build:static'].should.be.ok()
    gulp.tasks['spec:watch:static'].should.be.ok()
  })

  it('display correct information in info task', () => {
    const logs = [],
          {log} = console
    console.log = newLog
    gulp.start('spec:info')
    console.log = log
    logs.slice(-6).should.eql([
      '',
      '--- Static v0.7.0',
      `Static files from test${sep}fixtures are copied to tmp`,
      'Affected files:',
      'index.html',
      '',
    ])
    rump.reconfigure({paths: {source: {static: 'nonexistant'}}})
    logs.length = 0
    console.log = newLog
    gulp.start('spec:info')
    console.log = log
    logs.length.should.not.be.above(4)

    function newLog(...args) {
      logs.push(stripColor(args.join(' ')))
    }
  })

  describe('for building', () => {
    let original

    before(async() => {
      original = await readFile('test/fixtures/index.html')
      await new Promise(resolve => {
        gulp.task('postbuild', ['spec:watch'], resolve)
        gulp.start('postbuild')
      })
    })

    beforeEach(() => timeout(1000))

    afterEach(() => writeFile('test/fixtures/index.html', original))

    it('handles updates', async() => {
      bufferEqual(original, await readFile('tmp/index.html')).should.be.true()
      await writeFile('test/fixtures/index.html', '
New
')
      await timeout(1000)
      bufferEqual(original, await readFile('tmp/index.html')).should.be.false()
    })
  })
})
<|endoftext|>


<commit_before>/*
 *     (C) Copyright 2012 Universidad Politécnica de Madrid
 *
 *     This file is part of Wirecloud Platform.
 *
 *     Wirecloud Platform is free software: you can redistribute it and/or
 *     modify it under the terms of the GNU Affero General Public License as
 *     published by the Free Software Foundation, either version 3 of the
 *     License, or (at your option) any later version.
 *
 *     Wirecloud is distributed in the hope that it will be useful, but WITHOUT
 *     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 *     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public
 *     License for more details.
 *
 *     You should have received a copy of the GNU Affero General Public License
 *     along with Wirecloud Platform.  If not, see
 *     <http://www.gnu.org/licenses/>.
 *
 */

var OperatorMeta = function OperatorMeta(desc) {
    var vendor, name, version, display_name, description, inputs, outputs;

    // Vendor
    if (!('vendor' in desc) || desc.vendor.trim() === '') {
        throw new TypeError(gettext('missing operator vendor'));
    }
    vendor = desc.vendor.trim();
    Object.defineProperty(this, 'vendor', {value: vendor});

    // Name
    if (!('name' in desc) || desc.name.trim() === '') {
        throw new TypeError(gettext('missing operator name'));
    }
    name = desc.name.trim();
    Object.defineProperty(this, 'name', {value: name});

    // Version
    if (!('version' in desc) || desc.version.trim() === '') {
        throw new TypeError(gettext('missing operator version'));
    }
    version = desc.version.trim();
    Object.defineProperty(this, 'version', {value: version});

    // URI
    uri = desc.name.trim();
    Object.defineProperty(this, 'uri', {value: vendor + '/' + name + '/' + version});

    if (!('display_name' in desc) || desc.display_name.trim() === '') {
        display_name = name;
    } else {
        display_name = desc.display_name;
    }
    Object.defineProperty(this, 'display_name', {value: display_name});

    description = desc.description;
    if (description == null || description.trim() === '') {
        description = '';
    }
    Object.defineProperty(this, 'description', {value: description});

    inputs = desc.wiring.slots;
    if (inputs == null) {
        inputs = {};
    }
    Object.defineProperty(this, 'inputs', {value: inputs});

    outputs = desc.wiring.events;
    if (outputs == null) {
        outputs = {};
    }
    Object.defineProperty(this, 'outputs', {value: outputs});

    if (inputs.length === 0 && outputs.length === 0) {
        throw new TypeError();
    }
};

OperatorMeta.prototype.instanciate = function instanciate(id/*TODO*/, wiringEditor) {
    return new Operator(this, id /* TODO */, wiringEditor);
};

var Operator = function Operator(operator_meta, id, /* TODO */ wiringEditor) {
    var i, inputs, outputs, data_uri;

    Object.defineProperty(this, 'meta', {value: operator_meta});
    Object.defineProperty(this, 'name', {value: operator_meta.name});
    Object.defineProperty(this, 'display_name', {value: operator_meta.display_name});
    Object.defineProperty(this, 'id', {value: id});

    inputs = this.meta.inputs;
    this.inputs = {};
    for (i = 0; i < inputs.length; i++) {
        this.inputs[inputs[i].name] = new OperatorTargetEndpoint(this, inputs[i]);
    }

    outputs = this.meta.outputs;
    this.outputs = {};
    for (i = 0; i < outputs.length; i++) {
        this.outputs[outputs[i].name] = new OperatorSourceEndpoint(this, outputs[i]);
    }

    if (!wiringEditor) {
        this.element = document.createElement('object');
        data_uri = Wirecloud.URLs.OPERATOR_ENTRY.evaluate({vendor: operator_meta.vendor, name: operator_meta.name, version: operator_meta.version});
        this.element.setAttribute('data', data_uri);
        document.body.appendChild(this.element);
    }
};

Operator.prototype.sendEvent = function sendEvent(endpoint_name, data) {
    this.outputs[endpoint_name].propagate(data);
};

Operator.prototype.fullDisconnect = function fullDisconnect() {
    var i, connectables;

    connectables = this.inputs;
    for (i = 0; i < connectables.length; i++) {
        connectables[i].fullDisconnect();
    }

    connectables = this.outputs;
    for (i = 0; i < connectables.length; i++) {
        connectables[i].fullDisconnect();
    }
};

Operator.prototype.destroy = function destroy() {
    if (this.element.parentNode) {
        this.element.parentNode.removeChild(this.element);
    }
};

var OperatorTargetEndpoint = function OperatorTargetEndpoint(operator, meta) {
    Object.defineProperty(this, 'meta', {value: meta});
    Object.defineProperty(this, 'name', {value: meta.name});
    Object.defineProperty(this, 'friendcode', {value: meta.friendcode});
    Object.defineProperty(this, 'label', {value: meta.label});
    Object.defineProperty(this, 'description', {value: meta.description});
    Object.defineProperty(this, 'operator', {value: operator});

    this.connectable = this;
    wOut.call(this, this.meta.name, this.meta.type, this.meta.friendcode, this.operator.id + '_' + this.meta.name);
};
OperatorTargetEndpoint.prototype = new wOut();

OperatorTargetEndpoint.prototype.serialize = function serialize() {
    return {
        'type': 'ioperator',
        'id': this.operator.id,
        'endpoint': this.meta.name
    };
};

OperatorTargetEndpoint.prototype._is_target_slot = function _is_target_slot(list) {
    var i, target;

    if (list == null) {
        return true;
    }

    for (i = 0; i < list.length; i += 1) {
        target = list[i];
        if ((target.type === 'ioperator') && (target.id == this.operator.id) && (target.endpoint == this.meta.name)) {
            return true;
        }
    }
    return false;
};

OperatorTargetEndpoint.prototype.getFinalSlots = function getFinalSlots() {
    var action_label = this.meta.action_label, result;
    if (!action_label || action_label === '') {
        action_label = gettext('Use in %(slotName)s');
        action_label = interpolate(action_label, {slotName: this.meta.label}, true);
    }

    result = this.serialize();
    result.action_label = action_label;

    return [result];
};

OperatorTargetEndpoint.prototype._annotate = function _anotate(value, source, options) {
};

OperatorTargetEndpoint.prototype.propagate = function propagate(newValue, options) {
    if (!options || this._is_target_slot(options.targetSlots)) {
        this.meta.callback.call(this.operator, newValue);
    }
};

var OperatorSourceEndpoint = function OperatorSourceEndpoint(operator, meta) {
    Object.defineProperty(this, 'meta', {value: meta});
    Object.defineProperty(this, 'name', {value: meta.name});
    Object.defineProperty(this, 'friendcode', {value: meta.friendcode});
    Object.defineProperty(this, 'operator', {value: operator});
    Object.defineProperty(this, 'label', {value: meta.label});
    Object.defineProperty(this, 'description', {value: meta.description});
    Object.defineProperty(this, 'operator', {value: operator});

    this.connectable = this; // TODO
    wIn.call(this, this.meta.name, this.meta.type, this.friendcode, this.operator.id + '_' + this.meta.name);
};
OperatorSourceEndpoint.prototype = new wIn();

OperatorSourceEndpoint.prototype.serialize = function serialize() {
    return {
        'type': 'ioperator',
        'id': this.operator.id,
        'endpoint': this.meta.name
    };
};
<commit_msg>Pass operator ids through a hash in the operator url<commit_after>/*
 *     (C) Copyright 2012 Universidad Politécnica de Madrid
 *
 *     This file is part of Wirecloud Platform.
 *
 *     Wirecloud Platform is free software: you can redistribute it and/or
 *     modify it under the terms of the GNU Affero General Public License as
 *     published by the Free Software Foundation, either version 3 of the
 *     License, or (at your option) any later version.
 *
 *     Wirecloud is distributed in the hope that it will be useful, but WITHOUT
 *     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 *     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public
 *     License for more details.
 *
 *     You should have received a copy of the GNU Affero General Public License
 *     along with Wirecloud Platform.  If not, see
 *     <http://www.gnu.org/licenses/>.
 *
 */

var OperatorMeta = function OperatorMeta(desc) {
    var vendor, name, version, display_name, description, inputs, outputs;

    // Vendor
    if (!('vendor' in desc) || desc.vendor.trim() === '') {
        throw new TypeError(gettext('missing operator vendor'));
    }
    vendor = desc.vendor.trim();
    Object.defineProperty(this, 'vendor', {value: vendor});

    // Name
    if (!('name' in desc) || desc.name.trim() === '') {
        throw new TypeError(gettext('missing operator name'));
    }
    name = desc.name.trim();
    Object.defineProperty(this, 'name', {value: name});

    // Version
    if (!('version' in desc) || desc.version.trim() === '') {
        throw new TypeError(gettext('missing operator version'));
    }
    version = desc.version.trim();
    Object.defineProperty(this, 'version', {value: version});

    // URI
    uri = desc.name.trim();
    Object.defineProperty(this, 'uri', {value: vendor + '/' + name + '/' + version});

    if (!('display_name' in desc) || desc.display_name.trim() === '') {
        display_name = name;
    } else {
        display_name = desc.display_name;
    }
    Object.defineProperty(this, 'display_name', {value: display_name});

    description = desc.description;
    if (description == null || description.trim() === '') {
        description = '';
    }
    Object.defineProperty(this, 'description', {value: description});

    inputs = desc.wiring.slots;
    if (inputs == null) {
        inputs = {};
    }
    Object.defineProperty(this, 'inputs', {value: inputs});

    outputs = desc.wiring.events;
    if (outputs == null) {
        outputs = {};
    }
    Object.defineProperty(this, 'outputs', {value: outputs});

    if (inputs.length === 0 && outputs.length === 0) {
        throw new TypeError();
    }
};

OperatorMeta.prototype.instanciate = function instanciate(id/*TODO*/, wiringEditor) {
    return new Operator(this, id /* TODO */, wiringEditor);
};

var Operator = function Operator(operator_meta, id, /* TODO */ wiringEditor) {
    var i, inputs, outputs, data_uri;

    Object.defineProperty(this, 'meta', {value: operator_meta});
    Object.defineProperty(this, 'name', {value: operator_meta.name});
    Object.defineProperty(this, 'display_name', {value: operator_meta.display_name});
    Object.defineProperty(this, 'id', {value: id});

    inputs = this.meta.inputs;
    this.inputs = {};
    for (i = 0; i < inputs.length; i++) {
        this.inputs[inputs[i].name] = new OperatorTargetEndpoint(this, inputs[i]);
    }

    outputs = this.meta.outputs;
    this.outputs = {};
    for (i = 0; i < outputs.length; i++) {
        this.outputs[outputs[i].name] = new OperatorSourceEndpoint(this, outputs[i]);
    }

    if (!wiringEditor) {
        this.element = document.createElement('object');
        data_uri = Wirecloud.URLs.OPERATOR_ENTRY.evaluate({vendor: operator_meta.vendor, name: operator_meta.name, version: operator_meta.version}) + '#id=' + id;
        this.element.setAttribute('data', data_uri);
        document.body.appendChild(this.element);
    }
};

Operator.prototype.sendEvent = function sendEvent(endpoint_name, data) {
    this.outputs[endpoint_name].propagate(data);
};

Operator.prototype.fullDisconnect = function fullDisconnect() {
    var i, connectables;

    connectables = this.inputs;
    for (i = 0; i < connectables.length; i++) {
        connectables[i].fullDisconnect();
    }

    connectables = this.outputs;
    for (i = 0; i < connectables.length; i++) {
        connectables[i].fullDisconnect();
    }
};

Operator.prototype.destroy = function destroy() {
    if (this.element.parentNode) {
        this.element.parentNode.removeChild(this.element);
    }
};

var OperatorTargetEndpoint = function OperatorTargetEndpoint(operator, meta) {
    Object.defineProperty(this, 'meta', {value: meta});
    Object.defineProperty(this, 'name', {value: meta.name});
    Object.defineProperty(this, 'friendcode', {value: meta.friendcode});
    Object.defineProperty(this, 'label', {value: meta.label});
    Object.defineProperty(this, 'description', {value: meta.description});
    Object.defineProperty(this, 'operator', {value: operator});

    this.connectable = this;
    wOut.call(this, this.meta.name, this.meta.type, this.meta.friendcode, this.operator.id + '_' + this.meta.name);
};
OperatorTargetEndpoint.prototype = new wOut();

OperatorTargetEndpoint.prototype.serialize = function serialize() {
    return {
        'type': 'ioperator',
        'id': this.operator.id,
        'endpoint': this.meta.name
    };
};

OperatorTargetEndpoint.prototype._is_target_slot = function _is_target_slot(list) {
    var i, target;

    if (list == null) {
        return true;
    }

    for (i = 0; i < list.length; i += 1) {
        target = list[i];
        if ((target.type === 'ioperator') && (target.id == this.operator.id) && (target.endpoint == this.meta.name)) {
            return true;
        }
    }
    return false;
};

OperatorTargetEndpoint.prototype.getFinalSlots = function getFinalSlots() {
    var action_label = this.meta.action_label, result;
    if (!action_label || action_label === '') {
        action_label = gettext('Use in %(slotName)s');
        action_label = interpolate(action_label, {slotName: this.meta.label}, true);
    }

    result = this.serialize();
    result.action_label = action_label;

    return [result];
};

OperatorTargetEndpoint.prototype._annotate = function _anotate(value, source, options) {
};

OperatorTargetEndpoint.prototype.propagate = function propagate(newValue, options) {
    if (!options || this._is_target_slot(options.targetSlots)) {
        this.meta.callback.call(this.operator, newValue);
    }
};

var OperatorSourceEndpoint = function OperatorSourceEndpoint(operator, meta) {
    Object.defineProperty(this, 'meta', {value: meta});
    Object.defineProperty(this, 'name', {value: meta.name});
    Object.defineProperty(this, 'friendcode', {value: meta.friendcode});
    Object.defineProperty(this, 'operator', {value: operator});
    Object.defineProperty(this, 'label', {value: meta.label});
    Object.defineProperty(this, 'description', {value: meta.description});
    Object.defineProperty(this, 'operator', {value: operator});

    this.connectable = this; // TODO
    wIn.call(this, this.meta.name, this.meta.type, this.friendcode, this.operator.id + '_' + this.meta.name);
};
OperatorSourceEndpoint.prototype = new wIn();

OperatorSourceEndpoint.prototype.serialize = function serialize() {
    return {
        'type': 'ioperator',
        'id': this.operator.id,
        'endpoint': this.meta.name
    };
};
<|endoftext|>


<commit_before>(function(angular, undefined) {
'use strict';

// module: django.shop, TODO: move this into a summary JS file
var djangoShopModule = angular.module('django.shop.dialogs', ['djng.urls', 'djng.forms', 'django.shop.utils']);

// Shared controller for all forms, links and buttons using shop-dialog elements. It just adds
// an `upload` function to the scope, so that all forms can send their gathered data to the
// server. Since this controller does not make any presumption on how and where to proceed to,
// the caller has to set the controllers `deferred` to a `$q.deferred()` object.
djangoShopModule.controller('DialogController',
        ['$scope', '$rootScope', '$http', '$q', 'djangoUrl', 'djangoForm',
        function($scope, $rootScope, $http, $q, djangoUrl, djangoForm) {
	var uploadURL = djangoUrl.reverse('shop:checkout-upload');

	function getProperty(obj, prop) {
		var parts = prop.split('.'), part;
		for (part = parts.shift(); obj && part; part = parts.shift()) {
			obj = obj[part];
		}
		return obj;
	}

	this.uploadScope = function(scope, deferred) {
		$http.post(uploadURL, scope.data).success(function(response) {
			var hasErrors = false;
			if (deferred) {
				// only report errors, when the customer clicked onto a button using the
				// directive `shop-dialog-proceed`, but not on ordinary upload events.
				angular.forEach(response.errors, function(errors, key) {
					var errProp = getProperty(scope, key);
					hasErrors = djangoForm.setErrors(errProp, errors) || hasErrors;
				});
				if (hasErrors) {
					deferred.reject(response);
				} else {
					deferred.resolve(response);
				}
			}
			$rootScope.cart = response.cart;
			$rootScope.checkout_summary = response.checkout_summary;
		}).error(function(errors) {
			console.error("Unable to upload checkout forms:");
			console.log(errors);
		});
	};

	// This function is a noop returning a the promise of the given deferred object for further
	// processing. Its only purpose is to add a hook in case intermediate asynchronous operations
	// are required, as in the case of the external dialog form used by djangoshop-stripe.
	function prepare(deferred) {
		deferred.resolve();
		return deferred.promise;
	}

	$scope.prepare = $scope.prepare || prepare;
}]);

// Directive <form shop-dialog-form ...> (must be added as attribute to the <form> element)
// It is used to add an `upload()` method to the scope, so that `ng-change="upload()"`
// can be added to any input element. Use it to upload the models on the server.
djangoShopModule.directive('shopDialogForm', ['$q', '$timeout', function($q, $timeout) {
	return {
		restrict: 'A',
		controller: 'DialogController',
		link: function(scope, element, attrs, DialogController) {
			var ready = false;
			if (attrs.shopDialogForm) {
				// initialize with form data
				scope.$eval(attrs.shopDialogForm);
			}
			$timeout(function() {
				// form ran its first scope.$digest() cycle
				ready = true;
			});

			scope.upload = function() {
				if (ready) {
					DialogController.uploadScope(scope);
				}
			};

			scope.switchEntity = function(form_controller) {
				var deferred;
				if (ready) {
					deferred = $q.defer();
					DialogController.uploadScope(scope, deferred);
					deferred.promise.then(pristineEntity, pristineEntity);
				}

				function pristineEntity(response) {
					angular.extend(scope.data, response.data);
					scope.stepIsValid = response.data.$valid;
					form_controller.$setPristine();
				}
			};

			scope.removeEntity = function(form_controller, data_model) {
				var deferred = $q.defer();
				if (angular.isObject(scope.data[data_model])) {
					scope.data[data_model].remove_entity = true;
					DialogController.uploadScope(scope, deferred);
				}
				if (angular.isObject(form_controller['form_entities'])) {
					$q.when(deferred.promise).then(removeEntry, removeEntry);
				}

				function removeEntry(response) {
					var remove_entity_filter;
					if (angular.isObject(response.data[data_model]) && angular.isString(response.data[data_model].remove_entity_filter)) {
						remove_entity_filter = new Function(response.data[data_model].remove_entity_filter);
						form_controller['form_entities'] = remove_entity_filter.apply(null, form_controller['form_entities']);
					}
					scope.stepIsValid = response.data.$valid;
					angular.extend(scope.data, response.data);
					// skip one digest cycle so that the form can be updated without triggering a change event
					ready = false; $timeout(function() { ready = true; });
				}
			};
		}
	};
}]);

// Directive <ANY shop-dialog-proceed> to be added to button elements.
djangoShopModule.directive('shopDialogProceed', ['$window', '$http', '$q', 'djangoUrl',
                                         function($window, $http, $q, djangoUrl) {
	var purchaseURL = djangoUrl.reverse('shop:checkout-purchase');
	return {
		restrict: 'EA',
		controller: 'DialogController',
		link: function(scope, element, attrs, DialogController) {
			// add ng-click="proceed()" to button elements wishing to post the content of the
			// current scope. Returns a promise for further processing.
			scope.proceed = function() {
				var deferred = $q.defer();  // deferred for uploading scope
				scope.prepare($q.defer()).then(function() {
					DialogController.uploadScope(scope, deferred);
				});
				return deferred.promise;
			};

			// add ng-click="proceedWith(action)" to button elements wishing to
			// proceed after having posted the content of the current scope.
			scope.proceedWith = function(action) {
				scope.prepare($q.defer()).then(function() {
					var deferred = $q.defer();  // deferred for uploading scope
					DialogController.uploadScope(scope, deferred);
					performAction(deferred.promise, action);
				});
			};

			// Some actions, such as purchasing require a lot of time. This function
			// disables the button and replaces existing Glyphicons against a spinning wheel.
			function disableButton() {
				element.attr('disabled', 'disabled');
				angular.forEach(element.find('i'), function(span) {
					span = angular.element(span);
					if (span.hasClass('cascade-icon-left') || span.hasClass('cascade-icon-right')) {
						span.attr('deactivated-class', span.attr('class'));
						span.attr('class', 'glyphicon glyphicon-refresh glyphicon-refresh-animate');
					}
				});
			}

			function reenableButton() {
				element.removeAttr('disabled');
				angular.forEach(element.find('span'), function(span) {
					span = angular.element(span);
					if (span.attr('deactivated-class')) {
						span.attr('class', span.attr('deactivated-class'));
						span.removeAttr('deactivated-class');
					}
				});
			}

			function performAction(promise, action) {
				$q.when(promise).then(function() {
					console.log("Proceed to: " + action);
					if (action === 'RELOAD_PAGE') {
						$window.location.reload();
					} else if (action === 'PURCHASE_NOW') {
						disableButton();
						// Convert the cart into an order object.
						return $http.post(purchaseURL, scope.data);
					} else {
						// Proceed as usual and load another page
						$window.location.assign(action);
					}
				}).then(function(response) {
					if (response) {
						console.log(response);
						// evaluate expression to proceed on the PSP's server which itself might be a promise
						return eval(response.data.expression);
					}
				}).then(function() {
					console.log("Proceeded without any further request-response cycle.");
				}, function(errs) {
					if (errs) {
						console.error(errs);
					}
					reenableButton();
				});
			}
		}
	};
}]);

// Directive <TAG shop-form-validate="model-to-watch">
// It is used to override the validation of hidden form fragments.
// If model-to-watch is false, then input elements inside this DOM tree are not validated.
// This is useful, if a form fragment shall be validated only under certain conditions.
djangoShopModule.directive('shopFormValidate', function() {
	return {
		restrict: 'A',
		require: '^form',
		link: function(scope, element, attrs, formCtrl) {
			if (!attrs.shopFormValidate)
				return;
			scope.$watch(attrs.shopFormValidate, function() {
				var validateExpr = scope.$eval(attrs.shopFormValidate);
				angular.forEach(formCtrl, function(instance) {
					// iterate over form controller and move active parsers to inactive
					if (angular.isObject(instance) && instance.hasOwnProperty('$parsers')) {
						if (validateExpr) {
							if (angular.isArray(instance.$inactiveParsers)) {
								instance.$parsers = instance.$inactiveParsers;
							}
							instance.$inactiveParsers = [];
						} else {
							instance.$inactiveParsers = instance.$parsers;
							instance.$parsers = [];
							// reset all possible errors for this input element
							angular.forEach(instance.$error, function(val, key) {
								instance.$setValidity(key, true);
							});
						}
					}
				});
			});
		}
	};
});

})(window.angular);
<commit_msg>updated docstrings<commit_after>(function(angular, undefined) {
'use strict';

// module: django.shop, TODO: move this into a summary JS file
var djangoShopModule = angular.module('django.shop.dialogs', ['djng.urls', 'djng.forms', 'django.shop.utils']);

// Shared controller for all forms, links and buttons using shop-dialog elements. It just adds
// an `upload` function to the scope, so that all forms can send their gathered data to the
// server. Since this controller does not make any presumption on how and where to proceed to,
// the caller has to set the controllers `deferred` to a `$q.deferred()` object.
djangoShopModule.controller('DialogController',
        ['$scope', '$rootScope', '$http', '$q', 'djangoUrl', 'djangoForm',
        function($scope, $rootScope, $http, $q, djangoUrl, djangoForm) {
	var uploadURL = djangoUrl.reverse('shop:checkout-upload');

	function getProperty(obj, prop) {
		var parts = prop.split('.'), part;
		for (part = parts.shift(); obj && part; part = parts.shift()) {
			obj = obj[part];
		}
		return obj;
	}

	this.uploadScope = function(scope, deferred) {
		$http.post(uploadURL, scope.data).success(function(response) {
			var hasErrors = false;
			if (deferred) {
				// only report errors, when the customer clicked onto a button using the
				// directive `shop-dialog-proceed`, but not on ordinary upload events.
				angular.forEach(response.errors, function(errors, key) {
					var errProp = getProperty(scope, key);
					hasErrors = djangoForm.setErrors(errProp, errors) || hasErrors;
				});
				if (hasErrors) {
					deferred.reject(response);
				} else {
					deferred.resolve(response);
				}
			}
			$rootScope.cart = response.cart;
			$rootScope.checkout_summary = response.checkout_summary;
		}).error(function(errors) {
			console.error("Unable to upload checkout forms:");
			console.log(errors);
		});
	};

	// This function is a noop returning a the promise of the given deferred object for further
	// processing. Its only purpose is to add a hook in case intermediate asynchronous operations
	// are required, as in the case of the external dialog form used by djangoshop-stripe.
	function prepare(deferred) {
		deferred.resolve();
		return deferred.promise;
	}

	$scope.prepare = $scope.prepare || prepare;
}]);

// Directive <form shop-dialog-form ...> (must be added as attribute to the <form> element)
// It is used to add an `upload()` method to the scope, so that `ng-change="upload()"`
// can be added to any input element. Use it to upload the models on the server.
djangoShopModule.directive('shopDialogForm', ['$q', '$timeout', function($q, $timeout) {
	return {
		restrict: 'A',
		controller: 'DialogController',
		link: function(scope, element, attrs, DialogController) {
			var ready = false;
			if (attrs.shopDialogForm) {
				// initialize with form data
				scope.$eval(attrs.shopDialogForm);
			}
			$timeout(function() {
				// form ran its first scope.$digest() cycle
				ready = true;
			});

			scope.upload = function() {
				if (ready) {
					DialogController.uploadScope(scope);
				}
			};

			scope.switchEntity = function(form_controller) {
				var deferred;
				if (ready) {
					deferred = $q.defer();
					DialogController.uploadScope(scope, deferred);
					deferred.promise.then(pristineEntity, pristineEntity);
				}

				function pristineEntity(response) {
					angular.extend(scope.data, response.data);
					scope.stepIsValid = response.data.$valid;
					form_controller.$setPristine();
				}
			};

			scope.removeEntity = function(form_controller, data_model) {
				var deferred = $q.defer();
				if (angular.isObject(scope.data[data_model])) {
					scope.data[data_model].remove_entity = true;
					DialogController.uploadScope(scope, deferred);
				}
				if (angular.isObject(form_controller['form_entities'])) {
					$q.when(deferred.promise).then(removeEntry, removeEntry);
				}

				function removeEntry(response) {
					var remove_entity_filter;
					if (angular.isObject(response.data[data_model]) && angular.isString(response.data[data_model].remove_entity_filter)) {
						remove_entity_filter = new Function(response.data[data_model].remove_entity_filter);
						form_controller['form_entities'] = remove_entity_filter.apply(null, form_controller['form_entities']);
					}
					scope.stepIsValid = response.data.$valid;
					angular.extend(scope.data, response.data);
					// skip one digest cycle so that the form can be updated without triggering a change event
					ready = false; $timeout(function() { ready = true; });
				}
			};
		}
	};
}]);

// Directive <ANY shop-dialog-proceed> to be added to button elements.
djangoShopModule.directive('shopDialogProceed', ['$window', '$http', '$q', 'djangoUrl',
                                         function($window, $http, $q, djangoUrl) {
	var purchaseURL = djangoUrl.reverse('shop:checkout-purchase');
	return {
		restrict: 'EA',
		controller: 'DialogController',
		link: function(scope, element, attrs, DialogController) {
			// add ng-click="proceed()" to button elements wishing to post the content of the
			// current scope. Returns a promise for further processing.
			scope.proceed = function() {
				var deferred = $q.defer();  // deferred for uploading scope
				scope.prepare($q.defer()).then(function() {
					DialogController.uploadScope(scope, deferred);
				});
				return deferred.promise;
			};

			// add ng-click="proceedWith(action)" to button elements wishing to
			// proceed after having posted the content of the current scope.
			scope.proceedWith = function(action) {
				scope.prepare($q.defer()).then(function() {
					var deferred = $q.defer();  // deferred for uploading scope
					DialogController.uploadScope(scope, deferred);
					performAction(deferred.promise, action);
				});
			};

			// Some actions, such as purchasing require a lot of time. This function
			// disables the button and replaces existing Glyphicons against a spinning wheel.
			function disableButton() {
				element.attr('disabled', 'disabled');
				angular.forEach(element.find('i'), function(span) {
					span = angular.element(span);
					if (span.hasClass('cascade-icon-left') || span.hasClass('cascade-icon-right')) {
						span.attr('deactivated-class', span.attr('class'));
						span.attr('class', 'glyphicon glyphicon-refresh glyphicon-refresh-animate');
					}
				});
			}

			function reenableButton() {
				element.removeAttr('disabled');
				angular.forEach(element.find('span'), function(span) {
					span = angular.element(span);
					if (span.attr('deactivated-class')) {
						span.attr('class', span.attr('deactivated-class'));
						span.removeAttr('deactivated-class');
					}
				});
			}

			function performAction(promise, action) {
				$q.when(promise).then(function() {
					console.log("Proceed to: " + action);
					if (action === 'RELOAD_PAGE') {
						$window.location.reload();
					} else if (action === 'PURCHASE_NOW') {
						disableButton();
						// Convert the cart into an order object.
						return $http.post(purchaseURL, scope.data);
					} else {
						// Proceed as usual and load another page
						$window.location.assign(action);
					}
				}).then(function(response) {
					if (response) {
						console.log(response);
						// evaluate expression to proceed on the PSP's server which itself might be a promise
						return eval(response.data.expression);
					}
				}).then(function() {
					console.log("Proceeded without any further request-response cycle.");
				}, function(errs) {
					if (errs) {
						console.error(errs);
					}
					reenableButton();
				});
			}
		}
	};
}]);

// Directive <TAG shop-form-validate="model-to-watch">
// It is used to override the validation of form fragments, which can be hidden.
// If `model-to-watch` is false, then input elements inside this DOM tree are not validated.
// This is useful, if a form fragment shall be validated only under certain conditions.
djangoShopModule.directive('shopFormValidate', function() {
	return {
		restrict: 'A',
		require: '^form',
		link: function(scope, element, attrs, formCtrl) {
			if (!attrs.shopFormValidate)
				return;
			scope.$watch(attrs.shopFormValidate, function() {
				var validateExpr = scope.$eval(attrs.shopFormValidate);
				angular.forEach(formCtrl, function(instance) {
					// iterate over form controller and move active parsers to inactive
					if (angular.isObject(instance) && instance.hasOwnProperty('$parsers')) {
						if (validateExpr) {
							if (angular.isArray(instance.$inactiveParsers)) {
								instance.$parsers = instance.$inactiveParsers;
							}
							instance.$inactiveParsers = [];
						} else {
							instance.$inactiveParsers = instance.$parsers;
							instance.$parsers = [];
							// reset all possible errors for this input element
							angular.forEach(instance.$error, function(val, key) {
								instance.$setValidity(key, true);
							});
						}
					}
				});
			});
		}
	};
});

})(window.angular);
<|endoftext|>


<commit_before>/* eslint-env browser */
import React, { Component } from 'react';
import { connect } from 'react-redux';
import EnqueteRuntimeApp from './EnqueteRuntimeApp';
import * as Actions from '../actions';
import '../css/runtime.scss';

/** プレビューのためのコンテナ */
class EnquetePreviewApp extends Component {
  constructor(props) {
    super(props);
    this.state = {
      mode: 'pc',
    };
  }

  changeView(mode) {
    this.setState({ mode });
  }

  render() {
    const { restart } = this.props;
    const { mode } = this.state;

    if (mode === 'pc') {
      document.body.className = 'm3-enquete__user-agent-group--PC';
    } else {
      document.body.className = 'm3-enquete__user-agent-group--SP';
    }

    const cssLinks = ENV.RUNTIME_CSS_URL.split(/,/).map(url => <link type="text/css" rel="stylesheet" href={url} />);

    return (

        {cssLinks}

[プレビュー モード] 回答は保存されません

          <button onClick={() => restart()}>やり直す</button>
          <button onClick={() => window.close()}>閉じる</button>
          <button className="spMode pc" style={{ marginLeft: '50px' }} onClick={() => this.changeView('pc')}>PC表示</button>
          <button className="spMode sp" onClick={() => this.changeView('sp')}>スマホ表示</button>

        <EnqueteRuntimeApp noPostAnswer />

    );
  }
}

const stateToProps = state => ({
  state,
});
const actionsToProps = dispatch => ({
  restart: () => dispatch(Actions.restart()),
});

export default connect(
  stateToProps,
  actionsToProps,
)(EnquetePreviewApp);
<commit_msg>不要なsassのimport削除<commit_after>/* eslint-env browser */
import React, { Component } from 'react';
import { connect } from 'react-redux';
import EnqueteRuntimeApp from './EnqueteRuntimeApp';
import * as Actions from '../actions';

/** プレビューのためのコンテナ */
class EnquetePreviewApp extends Component {
  constructor(props) {
    super(props);
    this.state = {
      mode: 'pc',
    };
  }

  changeView(mode) {
    this.setState({ mode });
  }

  render() {
    const { restart } = this.props;
    const { mode } = this.state;

    if (mode === 'pc') {
      document.body.className = 'm3-enquete__user-agent-group--PC';
    } else {
      document.body.className = 'm3-enquete__user-agent-group--SP';
    }

    const cssLinks = ENV.RUNTIME_CSS_URL.split(/,/).map(url => <link type="text/css" rel="stylesheet" href={url} />);

    return (

        {cssLinks}

[プレビュー モード] 回答は保存されません

          <button onClick={() => restart()}>やり直す</button>
          <button onClick={() => window.close()}>閉じる</button>
          <button className="spMode pc" style={{ marginLeft: '50px' }} onClick={() => this.changeView('pc')}>PC表示</button>
          <button className="spMode sp" onClick={() => this.changeView('sp')}>スマホ表示</button>

        <EnqueteRuntimeApp noPostAnswer />

    );
  }
}

const stateToProps = state => ({
  state,
});
const actionsToProps = dispatch => ({
  restart: () => dispatch(Actions.restart()),
});

export default connect(
  stateToProps,
  actionsToProps,
)(EnquetePreviewApp);
<|endoftext|>


<commit_before>import { resolve, join } from 'path'
import { parse } from 'url'
import fs from 'mz/fs'
import http, { STATUS_CODES } from 'http'
import {
  renderToHTML,
  renderErrorToHTML,
  renderJSON,
  renderErrorJSON,
  sendHTML,
  serveStatic,
  serveStaticWithGzip
} from './render'
import Router from './router'
import HotReloader from './hot-reloader'
import { resolveFromList } from './resolve'
import getConfig from './config'
// We need to go up one more level since we are in the `dist` directory
import pkg from '../../package'

export default class Server {
  constructor ({ dir = '.', dev = false, staticMarkup = false, quiet = false } = {}) {
    this.dir = resolve(dir)
    this.dev = dev
    this.quiet = quiet
    this.renderOpts = { dir: this.dir, dev, staticMarkup }
    this.router = new Router()
    this.hotReloader = dev ? new HotReloader(this.dir, { quiet }) : null
    this.http = null
    this.config = getConfig(this.dir)

    this.defineRoutes()
  }

  getRequestHandler () {
    return (req, res, parsedUrl) => {
      if (!parsedUrl || parsedUrl.query === null) {
        parsedUrl = parse(req.url, true)
      }

      this.run(req, res, parsedUrl)
      .catch((err) => {
        if (!this.quiet) console.error(err)
        res.statusCode = 500
        res.end(STATUS_CODES[500])
      })
    }
  }

  async prepare () {
    if (this.hotReloader) {
      await this.hotReloader.start()
    }

    this.renderOpts.buildId = await this.readBuildId()
  }

  async close () {
    if (this.hotReloader) {
      await this.hotReloader.stop()
    }

    if (this.http) {
      await new Promise((resolve, reject) => {
        this.http.close((err) => {
          if (err) return reject(err)
          return resolve()
        })
      })
    }
  }

  defineRoutes () {
    const routes = {
      '/_next-prefetcher.js': async (req, res, params) => {
        const p = join(__dirname, '../client/next-prefetcher-bundle.js')
        await this.serveStatic(req, res, p)
      },

      '/_next/:buildId/main.js': async (req, res, params) => {
        this.handleBuildId(params.buildId, res)
        const p = join(this.dir, '.next/main.js')
        await this.serveStaticWithGzip(req, res, p)
      },

      '/_next/:buildId/commons.js': async (req, res, params) => {
        this.handleBuildId(params.buildId, res)
        const p = join(this.dir, '.next/commons.js')
        await this.serveStaticWithGzip(req, res, p)
      },

      '/_next/:buildId/pages/:path*': async (req, res, params) => {
        this.handleBuildId(params.buildId, res)
        const paths = params.path || ['index']
        const pathname = `/${paths.join('/')}`
        await this.renderJSON(req, res, pathname)
      },

      '/_next/:path+': async (req, res, params) => {
        const p = join(__dirname, '..', 'client', ...(params.path || []))
        await this.serveStatic(req, res, p)
      },

      '/static/:path+': async (req, res, params) => {
        const p = join(this.dir, 'static', ...(params.path || []))
        await this.serveStatic(req, res, p)
      },

      '/:path*': async (req, res, params, parsedUrl) => {
        const { pathname, query } = parsedUrl
        await this.render(req, res, pathname, query)
      }
    }

    for (const method of ['GET', 'HEAD']) {
      for (const p of Object.keys(routes)) {
        this.router.add(method, p, routes[p])
      }
    }
  }

  async start (port) {
    await this.prepare()
    this.http = http.createServer(this.getRequestHandler())
    await new Promise((resolve, reject) => {
      // This code catches EADDRINUSE error if the port is already in use
      this.http.on('error', reject)
      this.http.on('listening', () => resolve())
      this.http.listen(port)
    })
  }

  async run (req, res, parsedUrl) {
    if (this.hotReloader) {
      await this.hotReloader.run(req, res)
    }

    const fn = this.router.match(req, res, parsedUrl)
    if (fn) {
      await fn()
      return
    }

    if (req.method === 'GET' || req.method === 'HEAD') {
      await this.render404(req, res, parsedUrl)
    } else {
      res.statusCode = 501
      res.end(STATUS_CODES[501])
    }
  }

  async render (req, res, pathname, query) {
    if (this.config.poweredByHeader) {
      res.setHeader('X-Powered-By', `Next.js ${pkg.version}`)
    }
    const html = await this.renderToHTML(req, res, pathname, query)
    sendHTML(res, html, req.method)
  }

  async renderToHTML (req, res, pathname, query) {
    if (this.dev) {
      const compilationErr = this.getCompilationError(pathname)
      if (compilationErr) {
        res.statusCode = 500
        return this.renderErrorToHTML(compilationErr, req, res, pathname, query)
      }
    }

    try {
      return await renderToHTML(req, res, pathname, query, this.renderOpts)
    } catch (err) {
      if (err.code === 'ENOENT') {
        res.statusCode = 404
        return this.renderErrorToHTML(null, req, res, pathname, query)
      } else {
        if (!this.quiet) console.error(err)
        res.statusCode = 500
        return this.renderErrorToHTML(err, req, res, pathname, query)
      }
    }
  }

  async renderError (err, req, res, pathname, query) {
    const html = await this.renderErrorToHTML(err, req, res, pathname, query)
    sendHTML(res, html, req.method)
  }

  async renderErrorToHTML (err, req, res, pathname, query) {
    if (this.dev) {
      const compilationErr = this.getCompilationError('/_error')
      if (compilationErr) {
        res.statusCode = 500
        return renderErrorToHTML(compilationErr, req, res, pathname, query, this.renderOpts)
      }
    }

    try {
      return await renderErrorToHTML(err, req, res, pathname, query, this.renderOpts)
    } catch (err2) {
      if (this.dev) {
        if (!this.quiet) console.error(err2)
        res.statusCode = 500
        return renderErrorToHTML(err2, req, res, pathname, query, this.renderOpts)
      } else {
        throw err2
      }
    }
  }

  async render404 (req, res, parsedUrl = parse(req.url, true)) {
    const { pathname, query } = parsedUrl
    res.statusCode = 404
    this.renderError(null, req, res, pathname, query)
  }

  async renderJSON (req, res, page) {
    if (this.dev) {
      const compilationErr = this.getCompilationError(page)
      if (compilationErr) {
        return this.renderErrorJSON(compilationErr, req, res)
      }
    }

    try {
      await renderJSON(req, res, page, this.renderOpts)
    } catch (err) {
      if (err.code === 'ENOENT') {
        res.statusCode = 404
        return this.renderErrorJSON(null, req, res)
      } else {
        if (!this.quiet) console.error(err)
        res.statusCode = 500
        return this.renderErrorJSON(err, req, res)
      }
    }
  }

  async renderErrorJSON (err, req, res) {
    if (this.dev) {
      const compilationErr = this.getCompilationError('/_error')
      if (compilationErr) {
        res.statusCode = 500
        return renderErrorJSON(compilationErr, req, res, this.renderOpts)
      }
    }

    return renderErrorJSON(err, req, res, this.renderOpts)
  }

  async serveStaticWithGzip (req, res, path) {
    this._serveStatic(req, res, () => {
      return serveStaticWithGzip(req, res, path)
    })
  }

  serveStatic (req, res, path) {
    this._serveStatic(req, res, () => {
      return serveStatic(req, res, path)
    })
  }

  async _serveStatic (req, res, fn) {
    try {
      await fn()
    } catch (err) {
      if (err.code === 'ENOENT') {
        this.render404(req, res)
      } else {
        throw err
      }
    }
  }

  async readBuildId () {
    const buildIdPath = join(this.dir, '.next', 'BUILD_ID')
    try {
      const buildId = await fs.readFile(buildIdPath, 'utf8')
      return buildId.trim()
    } catch (err) {
      if (err.code === 'ENOENT') {
        return '-'
      } else {
        throw err
      }
    }
  }

  handleBuildId (buildId, res) {
    if (this.dev) return
    if (buildId !== this.renderOpts.buildId) {
      const errorMessage = 'Build id mismatch!' +
        'Seems like the server and the client version of files are not the same.'
      throw new Error(errorMessage)
    }

    res.setHeader('Cache-Control', 'max-age=365000000, immutable')
  }

  getCompilationError (page) {
    if (!this.hotReloader) return

    const errors = this.hotReloader.getCompilationErrors()
    if (!errors.size) return

    const id = join(this.dir, '.next', 'bundles', 'pages', page)
    const p = resolveFromList(id, errors.keys())
    if (p) return errors.get(p)[0]
  }
}
<commit_msg>Throw when parsedUrl is not provided (#1015)<commit_after>import { resolve, join } from 'path'
import { parse } from 'url'
import fs from 'mz/fs'
import http, { STATUS_CODES } from 'http'
import {
  renderToHTML,
  renderErrorToHTML,
  renderJSON,
  renderErrorJSON,
  sendHTML,
  serveStatic,
  serveStaticWithGzip
} from './render'
import Router from './router'
import HotReloader from './hot-reloader'
import { resolveFromList } from './resolve'
import getConfig from './config'
// We need to go up one more level since we are in the `dist` directory
import pkg from '../../package'

export default class Server {
  constructor ({ dir = '.', dev = false, staticMarkup = false, quiet = false } = {}) {
    this.dir = resolve(dir)
    this.dev = dev
    this.quiet = quiet
    this.renderOpts = { dir: this.dir, dev, staticMarkup }
    this.router = new Router()
    this.hotReloader = dev ? new HotReloader(this.dir, { quiet }) : null
    this.http = null
    this.config = getConfig(this.dir)

    this.defineRoutes()
  }

  getRequestHandler () {
    return (req, res, parsedUrl) => {
      if (!parsedUrl) {
        parsedUrl = parse(req.url, true)
      }

      if (!parsedUrl.query) {
        throw new Error('Please provide a parsed url to `handle` as third parameter. See https://github.com/zeit/next.js#custom-server-and-routing for an example.')
      }

      this.run(req, res, parsedUrl)
      .catch((err) => {
        if (!this.quiet) console.error(err)
        res.statusCode = 500
        res.end(STATUS_CODES[500])
      })
    }
  }

  async prepare () {
    if (this.hotReloader) {
      await this.hotReloader.start()
    }

    this.renderOpts.buildId = await this.readBuildId()
  }

  async close () {
    if (this.hotReloader) {
      await this.hotReloader.stop()
    }

    if (this.http) {
      await new Promise((resolve, reject) => {
        this.http.close((err) => {
          if (err) return reject(err)
          return resolve()
        })
      })
    }
  }

  defineRoutes () {
    const routes = {
      '/_next-prefetcher.js': async (req, res, params) => {
        const p = join(__dirname, '../client/next-prefetcher-bundle.js')
        await this.serveStatic(req, res, p)
      },

      '/_next/:buildId/main.js': async (req, res, params) => {
        this.handleBuildId(params.buildId, res)
        const p = join(this.dir, '.next/main.js')
        await this.serveStaticWithGzip(req, res, p)
      },

      '/_next/:buildId/commons.js': async (req, res, params) => {
        this.handleBuildId(params.buildId, res)
        const p = join(this.dir, '.next/commons.js')
        await this.serveStaticWithGzip(req, res, p)
      },

      '/_next/:buildId/pages/:path*': async (req, res, params) => {
        this.handleBuildId(params.buildId, res)
        const paths = params.path || ['index']
        const pathname = `/${paths.join('/')}`
        await this.renderJSON(req, res, pathname)
      },

      '/_next/:path+': async (req, res, params) => {
        const p = join(__dirname, '..', 'client', ...(params.path || []))
        await this.serveStatic(req, res, p)
      },

      '/static/:path+': async (req, res, params) => {
        const p = join(this.dir, 'static', ...(params.path || []))
        await this.serveStatic(req, res, p)
      },

      '/:path*': async (req, res, params, parsedUrl) => {
        const { pathname, query } = parsedUrl
        await this.render(req, res, pathname, query)
      }
    }

    for (const method of ['GET', 'HEAD']) {
      for (const p of Object.keys(routes)) {
        this.router.add(method, p, routes[p])
      }
    }
  }

  async start (port) {
    await this.prepare()
    this.http = http.createServer(this.getRequestHandler())
    await new Promise((resolve, reject) => {
      // This code catches EADDRINUSE error if the port is already in use
      this.http.on('error', reject)
      this.http.on('listening', () => resolve())
      this.http.listen(port)
    })
  }

  async run (req, res, parsedUrl) {
    if (this.hotReloader) {
      await this.hotReloader.run(req, res)
    }

    const fn = this.router.match(req, res, parsedUrl)
    if (fn) {
      await fn()
      return
    }

    if (req.method === 'GET' || req.method === 'HEAD') {
      await this.render404(req, res, parsedUrl)
    } else {
      res.statusCode = 501
      res.end(STATUS_CODES[501])
    }
  }

  async render (req, res, pathname, query) {
    if (this.config.poweredByHeader) {
      res.setHeader('X-Powered-By', `Next.js ${pkg.version}`)
    }
    const html = await this.renderToHTML(req, res, pathname, query)
    sendHTML(res, html, req.method)
  }

  async renderToHTML (req, res, pathname, query) {
    if (this.dev) {
      const compilationErr = this.getCompilationError(pathname)
      if (compilationErr) {
        res.statusCode = 500
        return this.renderErrorToHTML(compilationErr, req, res, pathname, query)
      }
    }

    try {
      return await renderToHTML(req, res, pathname, query, this.renderOpts)
    } catch (err) {
      if (err.code === 'ENOENT') {
        res.statusCode = 404
        return this.renderErrorToHTML(null, req, res, pathname, query)
      } else {
        if (!this.quiet) console.error(err)
        res.statusCode = 500
        return this.renderErrorToHTML(err, req, res, pathname, query)
      }
    }
  }

  async renderError (err, req, res, pathname, query) {
    const html = await this.renderErrorToHTML(err, req, res, pathname, query)
    sendHTML(res, html, req.method)
  }

  async renderErrorToHTML (err, req, res, pathname, query) {
    if (this.dev) {
      const compilationErr = this.getCompilationError('/_error')
      if (compilationErr) {
        res.statusCode = 500
        return renderErrorToHTML(compilationErr, req, res, pathname, query, this.renderOpts)
      }
    }

    try {
      return await renderErrorToHTML(err, req, res, pathname, query, this.renderOpts)
    } catch (err2) {
      if (this.dev) {
        if (!this.quiet) console.error(err2)
        res.statusCode = 500
        return renderErrorToHTML(err2, req, res, pathname, query, this.renderOpts)
      } else {
        throw err2
      }
    }
  }

  async render404 (req, res, parsedUrl = parse(req.url, true)) {
    const { pathname, query } = parsedUrl
    res.statusCode = 404
    this.renderError(null, req, res, pathname, query)
  }

  async renderJSON (req, res, page) {
    if (this.dev) {
      const compilationErr = this.getCompilationError(page)
      if (compilationErr) {
        return this.renderErrorJSON(compilationErr, req, res)
      }
    }

    try {
      await renderJSON(req, res, page, this.renderOpts)
    } catch (err) {
      if (err.code === 'ENOENT') {
        res.statusCode = 404
        return this.renderErrorJSON(null, req, res)
      } else {
        if (!this.quiet) console.error(err)
        res.statusCode = 500
        return this.renderErrorJSON(err, req, res)
      }
    }
  }

  async renderErrorJSON (err, req, res) {
    if (this.dev) {
      const compilationErr = this.getCompilationError('/_error')
      if (compilationErr) {
        res.statusCode = 500
        return renderErrorJSON(compilationErr, req, res, this.renderOpts)
      }
    }

    return renderErrorJSON(err, req, res, this.renderOpts)
  }

  async serveStaticWithGzip (req, res, path) {
    this._serveStatic(req, res, () => {
      return serveStaticWithGzip(req, res, path)
    })
  }

  serveStatic (req, res, path) {
    this._serveStatic(req, res, () => {
      return serveStatic(req, res, path)
    })
  }

  async _serveStatic (req, res, fn) {
    try {
      await fn()
    } catch (err) {
      if (err.code === 'ENOENT') {
        this.render404(req, res)
      } else {
        throw err
      }
    }
  }

  async readBuildId () {
    const buildIdPath = join(this.dir, '.next', 'BUILD_ID')
    try {
      const buildId = await fs.readFile(buildIdPath, 'utf8')
      return buildId.trim()
    } catch (err) {
      if (err.code === 'ENOENT') {
        return '-'
      } else {
        throw err
      }
    }
  }

  handleBuildId (buildId, res) {
    if (this.dev) return
    if (buildId !== this.renderOpts.buildId) {
      const errorMessage = 'Build id mismatch!' +
        'Seems like the server and the client version of files are not the same.'
      throw new Error(errorMessage)
    }

    res.setHeader('Cache-Control', 'max-age=365000000, immutable')
  }

  getCompilationError (page) {
    if (!this.hotReloader) return

    const errors = this.hotReloader.getCompilationErrors()
    if (!errors.size) return

    const id = join(this.dir, '.next', 'bundles', 'pages', page)
    const p = resolveFromList(id, errors.keys())
    if (p) return errors.get(p)[0]
  }
}
<|endoftext|>


<commit_before>var kafka = require('kafka-node'),
    murmur = require('murmurhash-js'),
    config = require('../config'),

    topics = require('../lib/topics.js'),

    client = new kafka.Client(config.kafka.zkConnect, config.kafka.clientId),
    producer = new kafka.HighLevelProducer(client),
    compression = config.kafka.compression || 0,
    seed = config.kafka.producerSeed,

    log = require('../logger.js'),
    logger = log.logger;

module.exports = function (app) {

    app.put('/topics/:topic', function (req, res) {
        logger.debug('put information to topic');

        producer.createTopics([req.params.topic],
            false,
            function (err, data) {
                if (err) {
                    logger.error({error: err, request: req, response: res});
                    return res.status(500).json({ error: err });
                }
                res.json({ message: data });
            });
    });

    app.post('/topics/:topic', function (req, res) {
        logger.trace('posting information to topic');

        if (!req.body || !req.body.records) {
            res.status(500).json({error : "The Records field is required"}).send();
        }

        var topic = req.params.topic;

        topics.partitions(topic, function (err, data) {
            logger.trace('loading partition data in topic controller');
            if (err) {
                logger.error({error: err, request: req, response: res});
                return res.status(500).json({ error: err });
            }

            logger.trace({data: req.body}, 'message body data');
            var numPartitions = data,
                messages = req.body.records.map(function (p) {
                    // ensure that the p.value is a string, else it will cause an kafka error
                    if (!!p.value) {
                        p.value = '';
                    } else if (typeof p.value !== 'string') {
                        p.value = JSON.parse(p.value);
                    }

                    var hasKey = p.key !== null && typeof p.key !== 'undefined',
                        hasPartition = p.partition !== null && typeof p.partition !== 'undefined',
                        result = {
                            topic: topic,
                            messages: hasKey ? new kafka.KeyedMessage(p.key, p.value) : p.value
                        };
                    if (hasKey) {
                        result.partition = murmur.murmur2(p.key, seed) % numPartitions;
                    }
                    else if (hasPartition) {
                        result.partition = p.partition;
                    }
                    return result;
                });

            logger.trace({data: data, messages: messages}, 'ready to send the data');
            producer.send(messages, function (err, data) {
                logger.trace({data: data}, 'data sent');
                if (err) {
                    logger.error({error: err, request: req, response: res});
                    return res.status(500).json({error: err});
                }

                var topicResult = data[topic];
                var results = [];
                for (var i in topicResult) {
                    results.push({ partition: i, offset: topicResult[i] });
                }
                res.json({ offsets: results });
            });
        });

    });

};
<commit_msg>fix the topic body parsing<commit_after>var kafka = require('kafka-node'),
    murmur = require('murmurhash-js'),
    config = require('../config'),

    topics = require('../lib/topics.js'),

    client = new kafka.Client(config.kafka.zkConnect, config.kafka.clientId),
    producer = new kafka.HighLevelProducer(client),
    compression = config.kafka.compression || 0,
    seed = config.kafka.producerSeed,

    log = require('../logger.js'),
    logger = log.logger;

module.exports = function (app) {

    app.put('/topics/:topic', function (req, res) {
        logger.debug('put information to topic');

        producer.createTopics([req.params.topic],
            false,
            function (err, data) {
                if (err) {
                    logger.error({error: err, request: req, response: res});
                    return res.status(500).json({ error: err });
                }
                res.json({ message: data });
            });
    });

    app.post('/topics/:topic', function (req, res) {
        logger.trace('posting information to topic');

        if (!req.body || !req.body.records) {
            res.status(500).json({error : "The Records field is required"}).send();
        }

        var topic = req.params.topic;

        topics.partitions(topic, function (err, data) {
            logger.trace('loading partition data in topic controller');
            if (err) {
                logger.error({error: err, request: req, response: res});
                return res.status(500).json({ error: err });
            }

            logger.trace({data: req.body}, 'message body data');
            var numPartitions = data,
                messages = req.body.records.map(function (p) {
                    // ensure that the p.value is a string, else it will cause an kafka error
                    if (!p.value) {
                        p.value = '';
                    } else if (typeof p.value !== 'string') {
                        p.value = JSON.parse(p.value);
                    }

                    var hasKey = p.key !== null && typeof p.key !== 'undefined',
                        hasPartition = p.partition !== null && typeof p.partition !== 'undefined',
                        result = {
                            topic: topic,
                            messages: hasKey ? new kafka.KeyedMessage(p.key, p.value) : p.value
                        };
                    if (hasKey) {
                        result.partition = murmur.murmur2(p.key, seed) % numPartitions;
                    }
                    else if (hasPartition) {
                        result.partition = p.partition;
                    }
                    return result;
                });

            logger.trace({data: data, messages: messages}, 'ready to send the data');
            producer.send(messages, function (err, data) {
                logger.trace({data: data}, 'data sent');
                if (err) {
                    logger.error({error: err, request: req, response: res});
                    return res.status(500).json({error: err});
                }

                var topicResult = data[topic];
                var results = [];
                for (var i in topicResult) {
                    results.push({ partition: i, offset: topicResult[i] });
                }
                res.json({ offsets: results });
            });
        });

    });

};
<|endoftext|>


<commit_before>// framework/init.js
// ------------------

// Record the footwork version as of this build.
fw.footworkVersion = 'FOOTWORK_VERSION';

// Expose any embedded dependencies
fw.embed = embedded;

fw.viewModel = {};
fw.dataModel = {};
fw.router = {};
fw.outlet = {};
fw.settings = {};

var runPostInit = [];
var internalComponents = [];
var entityDescriptors = [];
var entityMixins = [];

var entityClass = 'fw-entity';
var entityAnimateClass = 'fw-entity-animate';
var minimumAnimationDelay = 20;
var isEntityCtor;
var isEntity;
var isDataModel;
var isDataModelCtor;
var isRouter;
var activeOutlets = fw.observableArray();
var DefaultViewModel;

runPostInit.unshift(function() {
  DefaultViewModel = fw.viewModel.create({
    namespace: '_DefaultNamespace',
    autoIncrement: true,
    initialize: function(params) {
      if(isObject(params) && isObject(params.$viewModel)) {
        extend(this, params.$viewModel);
      }
    },
    sequenceAnimations: function() {
      return result(fw.settings, 'defaultAnimationSequence', 0);
    }
  });
});
<commit_msg>now exposing the current Deferred factory on fw.deferred<commit_after>// framework/init.js
// ------------------

// Record the footwork version as of this build.
fw.footworkVersion = 'FOOTWORK_VERSION';

// Expose any embedded dependencies
fw.embed = embedded;

// Directly expose the Deferred factory
fw.deferred = Deferred;

fw.viewModel = {};
fw.dataModel = {};
fw.router = {};
fw.outlet = {};
fw.settings = {};

var runPostInit = [];
var internalComponents = [];
var entityDescriptors = [];
var entityMixins = [];

var entityClass = 'fw-entity';
var entityAnimateClass = 'fw-entity-animate';
var minimumAnimationDelay = 20;
var isEntityCtor;
var isEntity;
var isDataModel;
var isDataModelCtor;
var isRouter;
var activeOutlets = fw.observableArray();
var DefaultViewModel;

runPostInit.unshift(function() {
  DefaultViewModel = fw.viewModel.create({
    namespace: '_DefaultNamespace',
    autoIncrement: true,
    initialize: function(params) {
      if(isObject(params) && isObject(params.$viewModel)) {
        extend(this, params.$viewModel);
      }
    },
    sequenceAnimations: function() {
      return result(fw.settings, 'defaultAnimationSequence', 0);
    }
  });
});
<|endoftext|>


<commit_before>"use strict";

describe("http", function () {

    it("knows config.httpPort", function () {
        assert("object" === typeof config && "number" === typeof config.httpPort);
    });

    describe("gpf.http", function () {

        var baseUrl;

        before(function () {
            baseUrl = "http://localhost:" + config.httpPort + "/echo/?";
        });

        it("allows the GET operation", function (done) {
            gpf.http.request({
                method: gpf.http.get,
                url: baseUrl + "status=200&content=Hello%20World"

            }).then(function (response) {
                assert(response.statusCode === 200);
                assert(response.responseText === "Hello World");
                done();
            }, done);
        });

        it("supports common shortcuts", function (done) {
            gpf.http.get(baseUrl + "status=200&content=Hello%20World").then(function (response) {
                assert(response.statusCode === 200);
                assert(response.responseText === "Hello World");
                done();
            }, done);
        });

    });

/*
    describe("gpf.http.mock", function () {

        it("mocks any request", function (done) {
            gpf.http.mock({
                method: gpf.http.get,
                url: /echo\?status=([0-9]+)/,
                response: function (request) {
                    return Promise.resolve({
                        textContent: ""
                    });
                }
            })
        });
    });
 */

});
<commit_msg>Code fixing<commit_after>"use strict";

describe("http", function () {

    it("knows config.httpPort", function () {
        assert("object" === typeof config && "number" === typeof config.httpPort);
    });

    describe("gpf.http", function () {

        var baseUrl;

        before(function () {
            baseUrl = "http://localhost:" + config.httpPort + "/echo/?";
        });

        it("allows the GET operation", function (done) {
            gpf.http.request({
                method: gpf.http.methods.get,
                url: baseUrl + "status=200&content=Hello%20World"

            }).then(function (response) {
                assert(response.status === 200);
                assert(response.responseText === "Hello World");
                done();
            }, done);
        });

        it("supports common shortcuts", function (done) {
            gpf.http.get(baseUrl + "status=200&content=Hello%20World").then(function (response) {
                assert(response.status === 200);
                assert(response.responseText === "Hello World");
                done();
            }, done);
        });

    });

/*
    describe("gpf.http.mock", function () {

        it("mocks any request", function (done) {
            gpf.http.mock({
                method: gpf.http.get,
                url: /echo\?status=([0-9]+)/,
                response: function (request) {
                    return Promise.resolve({
                        textContent: ""
                    });
                }
            })
        });
    });
 */

});
<|endoftext|>


<commit_before>import path from 'path';
import webpack from 'webpack';

const paths = {
  ASSETS: path.resolve(__dirname, './assets'),
  SRC: path.resolve(__dirname),
  COMPONENTS: path.resolve(__dirname, '../src'),
  DIST: path.resolve(__dirname, './build')
};

module.exports = {

  plugins: [
    new webpack.ContextReplacementPlugin(/moment[\/\\]locale$/, /de|fr|en/)
  ],

  module: {
    loaders: [
      {
        test: /\.jsx?$/,
        loader: 'babel',
        exclude: [ paths.ASSETS, /src\/.+\/examples/, paths.DIST ],
        include: [
          paths.COMPONENTS,
          paths.SRC,
          /rc-datepicker/,
          /react-input-children/,
          /react-autosize-textarea/,
          /react-cookie-banner/,
          /react-flexview/
        ]
      },
      {
        test: /\.png$|\.gif$/,
        loader: 'file?name=[path][name].[ext]'
      }
    ],
    preLoaders: [
      {
        test: /\.jsx?$/,
        loader: 'eslint',
        include: [ paths.SRC, paths.COMPONENTS ],
        exclude: paths.ASSETS
      }
    ]
  }

};
<commit_msg>Define StyleLintPlugin in webpack base config.<commit_after>import path from 'path';
import webpack from 'webpack';
import StyleLintPlugin from 'stylelint-webpack-plugin';

const paths = {
  ASSETS: path.resolve(__dirname, './assets'),
  SRC: path.resolve(__dirname),
  COMPONENTS: path.resolve(__dirname, '../src'),
  DIST: path.resolve(__dirname, './build')
};

module.exports = {

  plugins: [
    new webpack.ContextReplacementPlugin(/moment[\/\\]locale$/, /de|fr|en/),
    new StyleLintPlugin({
      files: '**/*.s?(a|c)ss',
      failOnError: false,
      syntax: 'scss'
    })
  ],

  module: {
    loaders: [
      {
        test: /\.jsx?$/,
        loader: 'babel',
        exclude: [ paths.ASSETS, /src\/.+\/examples/, paths.DIST ],
        include: [
          paths.COMPONENTS,
          paths.SRC,
          /rc-datepicker/,
          /react-input-children/,
          /react-autosize-textarea/,
          /react-cookie-banner/,
          /react-flexview/
        ]
      },
      {
        test: /\.png$|\.gif$/,
        loader: 'file?name=[path][name].[ext]'
      }
    ],
    preLoaders: [
      {
        test: /\.jsx?$/,
        loader: 'eslint',
        include: [ paths.SRC, paths.COMPONENTS ],
        exclude: paths.ASSETS
      }
    ]
  }

};
<|endoftext|>