<commit_before>var assert = require('chai').assert;

var primitives = {'string': true, 'JSON': true, 'experiment': true};
function isPrimitive(type) {
  return primitives[type] == true || isTypeVar(type);
}

var typeVarID = 0;

function newTypeVar() {
  return "'" + (typeVarID++);
}

function isTypeVar(type) {
  return type[0] == "'";
}

function isList(type) {
  return type[0] == '[' && type[type.length - 1] == ']';
}

function delist(type) {
  assert.isTrue(isList(type));
  return type.slice(1, type.length - 1);
}

function isTuple(type) {
  return /\(([^,].*),([^,].*)\)/.exec(type) !== null;
}

function leftType(type) {
  assert.isTrue(isTuple(type));
  return /\(([^,].*),([^,].*)\)/.exec(type)[1];
}

function rightType(type) {
  assert.isTrue(isTuple(type));
  return /\(([^,].*),([^,].*)\)/.exec(type)[2];
}

function substitute(type, coersion) {
  assert.isTrue(isPrimitive(type) && isTypeVar(type), type + ' is a primitive type var');
  var subs = {};
  subs.value = coersion[type];
  subs.coersion = {};
  for (key in coersion) {
    if (key == type)
      continue;
    subs.coersion[key] = coersion[key];
  }
  return subs;
}

// TODO complete this, deal with multiple type vars if they ever arise.
function coerce(left, right, coersion) {
  // 'a -> 'a, string -> string, JSON -> JSON, etc.
  if (left == right)
    return coersion;

  if (isList(left) && isList(right)) {
    return coerce(delist(left), delist(right), coersion);
  }

  if (isTuple(left) && isTuple(right)) {
    var leftCoerce = coerce(leftType(left), leftType(right), coersion);
    var rightCoerce = coerce(rightType(left), rightType(right), coersion);
    if (leftCoerce == undefined || rightCoerce == undefined)
      return undefined;
    for (key in rightCoerce)
      leftCoerce[key] = rightCoerce[key];
    return leftCoerce;
  }

  assert.equal(isPrimitive(left), true, left + ' is a primitive type');
  assert.equal(isPrimitive(right), true, right + ' is a primitive type');

  // 'a -> 'b

  if (isTypeVar(left) && isTypeVar(right)) {
    var result = left;
    while (isTypeVar(result) && coersion[result] !== undefined)
      result = coersion[result];
    left = result;
  }

  // 'a -> string
  if (isTypeVar(left)) {
    var subs = substitute(left, coersion);
    if (subs.value == right)
      return subs.coersion;
  }

  // string -> 'a
  if (isTypeVar(right)) {
    coersion[right] = left;
    return coersion;
  }

  return undefined;
}

module.exports.newTypeVar = newTypeVar;
module.exports.coerce = coerce;
<commit_msg>Replace assert with type check failure.<commit_after>var assert = require('chai').assert;

var primitives = {'string': true, 'JSON': true, 'experiment': true};
function isPrimitive(type) {
  return primitives[type] == true || isTypeVar(type);
}

var typeVarID = 0;

function newTypeVar() {
  return "'" + (typeVarID++);
}

function isTypeVar(type) {
  return type[0] == "'";
}

function isList(type) {
  return type[0] == '[' && type[type.length - 1] == ']';
}

function delist(type) {
  assert.isTrue(isList(type));
  return type.slice(1, type.length - 1);
}

function isTuple(type) {
  return /\(([^,].*),([^,].*)\)/.exec(type) !== null;
}

function leftType(type) {
  assert.isTrue(isTuple(type));
  return /\(([^,].*),([^,].*)\)/.exec(type)[1];
}

function rightType(type) {
  assert.isTrue(isTuple(type));
  return /\(([^,].*),([^,].*)\)/.exec(type)[2];
}

function substitute(type, coersion) {
  assert.isTrue(isPrimitive(type) && isTypeVar(type), type + ' is a primitive type var');
  var subs = {};
  subs.value = coersion[type];
  subs.coersion = {};
  for (key in coersion) {
    if (key == type)
      continue;
    subs.coersion[key] = coersion[key];
  }
  return subs;
}

// TODO complete this, deal with multiple type vars if they ever arise.
function coerce(left, right, coersion) {
  // 'a -> 'a, string -> string, JSON -> JSON, etc.
  if (left == right)
    return coersion;

  if (isList(left) && isList(right)) {
    return coerce(delist(left), delist(right), coersion);
  }

  if (isTuple(left) && isTuple(right)) {
    var leftCoerce = coerce(leftType(left), leftType(right), coersion);
    var rightCoerce = coerce(rightType(left), rightType(right), coersion);
    if (leftCoerce == undefined || rightCoerce == undefined)
      return undefined;
    for (key in rightCoerce)
      leftCoerce[key] = rightCoerce[key];
    return leftCoerce;
  }

  if (!isPrimitive(left) || !isPrimitive(right))
    return undefined;

  assert.equal(isPrimitive(left), true, left + ' is a primitive type');
  assert.equal(isPrimitive(right), true, right + ' is a primitive type');

  // 'a -> 'b

  if (isTypeVar(left) && isTypeVar(right)) {
    var result = left;
    while (isTypeVar(result) && coersion[result] !== undefined)
      result = coersion[result];
    left = result;
  }

  // 'a -> string
  if (isTypeVar(left)) {
    var subs = substitute(left, coersion);
    if (subs.value == right)
      return subs.coersion;
    if (subs.value == undefined) {
      coersion[left] = right;
      return coersion;
    }
  }

  // string -> 'a
  if (isTypeVar(right)) {
    coersion[right] = left;
    return coersion;
  }

  return undefined;
}

module.exports.newTypeVar = newTypeVar;
module.exports.coerce = coerce;
<|endoftext|>


<commit_before>// The MIT License (MIT)

// Copyright (c) 2014 Glass Umbrella. Created by Eddie Lee.

// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

(function($) {
    $.fn.gutruncate = function(options) {
        var defaults = {
            minLength: 150,
            tolerance: 80,
            readMoreText: "more",
            readLessText: "less",
            ellipsisText: "…",
            blockLevelMore: true,
            reapply: false,
            togglePosition: "bottom",
            externalToggle: null
        };

        var options = $.extend(defaults, options);

        var _showContent = function($element) {
            var moreLink = $(".gutruncate-more-link", $element);
            var moreContent = $(".gutruncate-more", $element);
            var ellipsis = $(".gutruncate-ellipsis", $element);

            if(options.externalToggle) {
                $(options.externalToggle).addClass("gutruncate_open");
                $(options.externalToggle).removeClass("gutruncate_closed");
            }

            $element.addClass("gutruncate_open");
            $element.removeClass("gutruncate_closed");
            moreContent.css("display", "inline");
            moreLink.text(options.readLessText);
            ellipsis.css("display", "none");
        };

        var _truncateContent = function($element) {
            var moreLink = $(".gutruncate-more-link", $element);
            var moreContent = $(".gutruncate-more", $element);
            var ellipsis = $(".gutruncate-ellipsis", $element);

            if(options.externalToggle) {
                $(options.externalToggle).removeClass("gutruncate_open");
                $(options.externalToggle).addClass("gutruncate_closed");
            }

            $element.removeClass("gutruncate_open");
            $element.addClass("gutruncate_closed");
            moreContent.css("display", "none");
            moreLink.text(options.readMoreText);
            ellipsis.css("display", "inline");
        };

        var _toggleContent = function(evt) {
            $element = $(evt.target).closest(".gutruncate");

            if ($element.hasClass("gutruncate_closed")) {
                _showContent($element);
            } else {
                _truncateContent($element);
            }
            return false;
        };

        return this.each(function(index, element) {

            $element = $(element);

            //Don't reapply
            if ($element.hasClass("gutruncate") && !options.reapply) {
                return true;
            }

            var body = $element.html().trim();

            //Don't apply if isnt long enough
            if (body.length <= options.minLength + options.tolerance) {
                return true;
            }

            //Don't apply if is all one word
            var splitLocation = body.indexOf(" ", options.minLength);
            if (splitLocation === -1) {
                return true;
            }

            //If can't find a safe place to split within tolerance - split at exact length
            if (splitLocation > (options.minLength + options.tolerance)) {
                splitLocation = options.minLength;
            }

            //Split text
            var visibleSection = body.substring(0, splitLocation);
            var hiddenSection = body.substring(splitLocation);

            //Update DOM
            $element.html(
                visibleSection
                + ""
                + options.ellipsisText
                + ""

                + ""
                + hiddenSection
                + ""
            );

            if (!options.externalToggle) {
                //Add toggle link
                var toggle = (options.blockLevelMore ? "
" : " ")
                    + ""
                    + options.readMoreText
                    + ""
                    + (options.blockLevelMore ? "
" : "");

                if(options.togglePosition === "bottom") {
                    $element.append(toggle);
                } else if(options.togglePosition === "top") {
                    $element.prepend(toggle);
                }

                //Add click handler
                $(".gutruncate-more-link", $element).click(_toggleContent);
            } else if (!$element.hasClass("gutruncate")) {
                //Huck-up external toggle
                var target = this;
                $(options.externalToggle).click(function() {
                    _toggleContent({
                        target: target
                    });
                });
            }

            //Start off truncated
            _truncateContent($element);

            //Finished
            $element.addClass("gutruncate");
        });
    };

    if (ko !== undefined && ko.bindingHandlers !== undefined) {
        var _gutruncate = function(element, valueAccessor) {
            var binding = ko.unwrap(valueAccessor());
            var options = {};
            var text = "";

            if (binding === null) {
                binding = "";
            }

            if (typeof binding === "string") {
                text = binding;
            } else {
                text = ko.unwrap(binding.text);
                if (binding.options) {
                    options = ko.unwrap(binding.options);
                }
            }

            options.reapply = true; //Needs to rerun when changed
            $(element).html(htmlEncode(text));
            $(element).gutruncate(options);
        };

        ko.bindingHandlers.gutruncate = {
            init: _gutruncate,
            update: _gutruncate
        };
    }

    function htmlEncode(value) {
        return $('
').text(value).html();
    }
})(jQuery);<commit_msg>Added amd support<commit_after>// The MIT License (MIT)

// Copyright (c) 2014 Glass Umbrella. Created by Eddie Lee.

// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

;
(function(factory) {
    if (typeof define === 'function' && define.amd) {
        define(['jquery', 'knockout'], factory);
    } else {
        factory(jQuery, ko);
    }
}(function($, ko) {
    $.fn.gutruncate = function(options) {
        var defaults = {
            minLength: 150,
            tolerance: 80,
            readMoreText: "more",
            readLessText: "less",
            ellipsisText: "…",
            blockLevelMore: true,
            reapply: false,
            togglePosition: "bottom",
            externalToggle: null
        };

        var options = $.extend(defaults, options);

        var _showContent = function($element) {
            var moreLink = $(".gutruncate-more-link", $element);
            var moreContent = $(".gutruncate-more", $element);
            var ellipsis = $(".gutruncate-ellipsis", $element);

            if (options.externalToggle) {
                $(options.externalToggle).addClass("gutruncate_open");
                $(options.externalToggle).removeClass("gutruncate_closed");
            }

            $element.addClass("gutruncate_open");
            $element.removeClass("gutruncate_closed");
            moreContent.css("display", "inline");
            moreLink.text(options.readLessText);
            ellipsis.css("display", "none");
        };

        var _truncateContent = function($element) {
            var moreLink = $(".gutruncate-more-link", $element);
            var moreContent = $(".gutruncate-more", $element);
            var ellipsis = $(".gutruncate-ellipsis", $element);

            if (options.externalToggle) {
                $(options.externalToggle).removeClass("gutruncate_open");
                $(options.externalToggle).addClass("gutruncate_closed");
            }

            $element.removeClass("gutruncate_open");
            $element.addClass("gutruncate_closed");
            moreContent.css("display", "none");
            moreLink.text(options.readMoreText);
            ellipsis.css("display", "inline");
        };

        var _toggleContent = function(evt) {
            $element = $(evt.target).closest(".gutruncate");

            if ($element.hasClass("gutruncate_closed")) {
                _showContent($element);
            } else {
                _truncateContent($element);
            }
            return false;
        };

        return this.each(function(index, element) {

            $element = $(element);

            //Don't reapply
            if ($element.hasClass("gutruncate") && !options.reapply) {
                return true;
            }

            var body = $element.html().trim();

            //Don't apply if isnt long enough
            if (body.length <= options.minLength + options.tolerance) {
                return true;
            }

//Don't apply if is all one word
            var splitLocation = body.indexOf(" ", options.minLength);
            if (splitLocation === -1) {
                return true;
            }

            //If can't find a safe place to split within tolerance - split at exact length
            if (splitLocation > (options.minLength + options.tolerance)) {
                splitLocation = options.minLength;
            }

            //Split text
            var visibleSection = body.substring(0, splitLocation);
            var hiddenSection = body.substring(splitLocation);

            //Update DOM
            $element.html(
                visibleSection
                + ""
                + options.ellipsisText
                + ""
                + ""
                + hiddenSection
                + ""
            );

            if (!options.externalToggle) {
                //Add toggle link
                var toggle = (options.blockLevelMore ? "
" : " ")
                    + ""
                    + options.readMoreText
                    + ""
                    + (options.blockLevelMore ? "
" : "");

                if (options.togglePosition === "bottom") {
                    $element.append(toggle);
                } else if (options.togglePosition === "top") {
                    $element.prepend(toggle);
                }

                //Add click handler
                $(".gutruncate-more-link", $element).click(_toggleContent);
            } else if (!$element.hasClass("gutruncate")) {
                //Huck-up external toggle
                var target = this;
                $(options.externalToggle).click(function() {
                    _toggleContent({
                        target: target
                    });
                });
            }

            //Start off truncated
            _truncateContent($element);

            //Finished
            $element.addClass("gutruncate");
        });
    };

    if (ko !== undefined && ko.bindingHandlers !== undefined) {
        var _gutruncate = function(element, valueAccessor) {
            var binding = ko.unwrap(valueAccessor());
            var options = {};
            var text = "";

            if (binding === null) {
                binding = "";
            }

            if (typeof binding === "string") {
                text = binding;
            } else {
                text = ko.unwrap(binding.text);
                if (binding.options) {
                    options = ko.unwrap(binding.options);
                }
            }

            options.reapply = true; //Needs to rerun when changed
            $(element).html(htmlEncode(text));
            $(element).gutruncate(options);
        };

        ko.bindingHandlers.gutruncate = {
            init: _gutruncate,
            update: _gutruncate
        };
    }

    function htmlEncode(value) {
        return $('
').text(value).html();
    }
}));<|endoftext|>


<commit_before>'use strict';

const _ = require('lodash');
const Promise = require('bluebird');
const eventmesh = require('../../data-access-layer/eventmesh');
const CONST = require('../../common/constants');
const errors = require('../../common/errors');
const logger = require('../../common/logger');
const config = require('../../common/config');
const utils = require('../../common/utils');
const DirectorService = require('./DirectorService');
const ServiceInstanceNotFound = errors.ServiceInstanceNotFound;
const AssertionError = errors.AssertionError;
const Conflict = errors.Conflict;

class BoshTaskPoller {
  static start() {
    function poller(object, intervalId) {
      const resourceDetails = eventmesh.apiServerClient.parseResourceDetailsFromSelfLink(object.metadata.selfLink);
      // If no lockedByPoller annotation then set annotation  with time
      // Else check timestamp if more than specific time than start polling and change lockedByPoller Ip
      return eventmesh.apiServerClient.getResource({
          resourceGroup: resourceDetails.resourceGroup,
          resourceType: resourceDetails.resourceType,
          resourceId: object.metadata.name,
        })
        .then(resourceBody => {
          const options = resourceBody.spec.options;
          const pollerAnnotation = resourceBody.metadata.annotations.lockedByTaskPoller;
          logger.debug(`pollerAnnotation is ${pollerAnnotation} current time is: ${new Date()}`);
          return Promise.try(() => {
            // If task is not picked by poller which has the lock on task for CONST.DIRECTOR_RESOURCE_POLLER_INTERVAL + DIRECTOR_RESOURCE_POLLER_RELAXATION_TIME then try to acquire lock
            if (pollerAnnotation && (JSON.parse(pollerAnnotation).ip !== config.broker_ip) && (new Date() - new Date(JSON.parse(pollerAnnotation).lockTime) < (CONST.DIRECTOR_RESOURCE_POLLER_INTERVAL + CONST.DIRECTOR_RESOURCE_POLLER_RELAXATION_TIME))) { // cahnge this to 5000
              logger.debug(`Process with ip ${JSON.parse(pollerAnnotation).ip} is already polling for task`);
            } else {
              const patchBody = _.cloneDeep(resourceBody);
              const metadata = patchBody.metadata;
              const currentAnnotations = metadata.annotations;
              const patchAnnotations = currentAnnotations ? currentAnnotations : {};
              patchAnnotations.lockedByTaskPoller = JSON.stringify({
                lockTime: new Date(),
                ip: config.broker_ip
              });
              metadata.annotations = patchAnnotations;
              // Handle conflict also
              return eventmesh.apiServerClient.updateResource({
                  resourceGroup: resourceDetails.resourceGroup,
                  resourceType: resourceDetails.resourceType,
                  resourceId: metadata.name,
                  metadata: metadata
                })
                .tap((updatedResource) => logger.debug(`Successfully acquired bosh task poller lock for request with options: ${JSON.stringify(options)}\n` +
                  `Updated resource with poller annotations is: `, updatedResource))
                .then(() => {
                  if (_.includes([CONST.APISERVER.RESOURCE_STATE.SUCCEEDED, CONST.APISERVER.RESOURCE_STATE.FAILED], resourceBody.status.state)) {
                    BoshTaskPoller.clearPoller(metadata.name, intervalId);
                  } else {
                    return DirectorService.createDirectorService(metadata.name, options)
                      .then(boshService => boshService.lastOperation(resourceBody.status.response))
                      .tap(lastOperationValue => logger.debug('last operation value is ', lastOperationValue))
                      .then(lastOperationValue => Promise.all([eventmesh.apiServerClient.updateResource({
                        resourceGroup: CONST.APISERVER.RESOURCE_GROUPS.DEPLOYMENT,
                        resourceType: CONST.APISERVER.RESOURCE_TYPES.DIRECTOR,
                        resourceId: metadata.name,
                        status: {
                          lastOperation: lastOperationValue,
                          state: lastOperationValue.resourceState
                        }
                      }), Promise.try(() => {
                        if (_.includes([CONST.APISERVER.RESOURCE_STATE.SUCCEEDED, CONST.APISERVER.RESOURCE_STATE.FAILED], lastOperationValue.resourceState)) {
                          // cancel the poller and clear the array
                          BoshTaskPoller.clearPoller(metadata.name, intervalId);
                        }
                      })]))
                      .catch(ServiceInstanceNotFound, err => {
                        logger.error(`Error occured while getting last operation`, err);
                        BoshTaskPoller.clearPoller(metadata.name, intervalId);
                        if (resourceBody.status.response.type === 'delete') {
                          return eventmesh.apiServerClient.deleteResource({
                            resourceGroup: CONST.APISERVER.RESOURCE_GROUPS.DEPLOYMENT,
                            resourceType: CONST.APISERVER.RESOURCE_TYPES.DIRECTOR,
                            resourceId: metadata.name
                          });
                        } else {
                          return eventmesh.apiServerClient.updateResource({
                            resourceGroup: CONST.APISERVER.RESOURCE_GROUPS.DEPLOYMENT,
                            resourceType: CONST.APISERVER.RESOURCE_TYPES.DIRECTOR,
                            resourceId: metadata.name,
                            status: {
                              lastOperation: {
                                state: CONST.APISERVER.RESOURCE_STATE.FAILED,
                                description: CONST.SERVICE_BROKER_ERR_MSG
                              },
                              state: CONST.APISERVER.RESOURCE_STATE.FAILED,
                              error: utils.buildErrorJson(err)
                            }
                          });
                        }
                      })
                      .catch(AssertionError, err => {
                        logger.error(`Error occured while getting last operation`, err);
                        BoshTaskPoller.clearPoller(metadata.name, intervalId);
                        return eventmesh.apiServerClient.updateResource({
                          resourceGroup: CONST.APISERVER.RESOURCE_GROUPS.DEPLOYMENT,
                          resourceType: CONST.APISERVER.RESOURCE_TYPES.DIRECTOR,
                          resourceId: metadata.name,
                          status: {
                            lastOperation: {
                              state: CONST.APISERVER.RESOURCE_STATE.FAILED,
                              description: CONST.SERVICE_BROKER_ERR_MSG
                            },
                            state: CONST.APISERVER.RESOURCE_STATE.FAILED,
                            error: utils.buildErrorJson(err)
                          }
                        });
                      });
                  }
                })
                .catch(Conflict, () => {
                  logger.debug(`Not able to acquire bosh task poller processing lock, Request is probably picked by other worker`);
                });
            }
          });
        })
        .catch(err => {
          logger.error(`Error occured while polling for last operation, clearing bosh task poller interval now`, err);
          BoshTaskPoller.clearPoller(object.metadata.name, intervalId);
        });
    }

    function startPoller(event) {
      logger.debug('Received Director Event: ', event);
      if (event.type === CONST.API_SERVER.WATCH_EVENT.ADDED || event.type === CONST.API_SERVER.WATCH_EVENT.MODIFIED) {
        logger.debug('starting bosh task poller for deployment ', event.object.metadata.name);
        BoshTaskPoller.clearPoller(event.object.metadata.name, BoshTaskPoller.pollers[event.object.metadata.name]);
        // Poller time should be little less than watch refresh interval as
        const intervalId = setInterval(() => poller(event.object, intervalId), CONST.DIRECTOR_RESOURCE_POLLER_INTERVAL);
        BoshTaskPoller.pollers[event.object.metadata.name] = intervalId;
      }
    }
    const queryString = `state in (${CONST.APISERVER.RESOURCE_STATE.IN_PROGRESS})`;
    return eventmesh.apiServerClient.registerWatcher(CONST.APISERVER.RESOURCE_GROUPS.DEPLOYMENT, CONST.APISERVER.RESOURCE_TYPES.DIRECTOR, startPoller, queryString)
      .then(stream => {
        logger.debug(`Successfully set watcher on director resources for task polling with query string:`, queryString);
        return Promise
          .delay(CONST.APISERVER.POLLER_WATCHER_REFRESH_INTERVAL)
          .then(() => {
            logger.debug(`Refreshing stream after ${CONST.APISERVER.POLLER_WATCHER_REFRESH_INTERVAL}`);
            stream.abort();
            return this.start();
          });
      })
      .catch(err => {
        logger.error(`Error occured in registering watch for bosh task poller:`, err);
        return Promise
          .delay(CONST.APISERVER.WATCHER_ERROR_DELAY)
          .then(() => {
            logger.debug(`Refreshing stream after ${CONST.APISERVER.WATCHER_ERROR_DELAY}`);
            return this.start();
          });
      });
  }

  static clearPoller(resourceId, intervalId) {
    logger.debug(`Clearing bosh task poller interval for deployment`, resourceId);
    if (intervalId) {
      clearInterval(intervalId);
    }
    _.unset(BoshTaskPoller.pollers, resourceId);
  }
}

BoshTaskPoller.pollers = [];
module.exports = BoshTaskPoller;<commit_msg>Fix bosh task poller<commit_after>'use strict';

const _ = require('lodash');
const Promise = require('bluebird');
const eventmesh = require('../../data-access-layer/eventmesh');
const CONST = require('../../common/constants');
const errors = require('../../common/errors');
const logger = require('../../common/logger');
const config = require('../../common/config');
const utils = require('../../common/utils');
const DirectorService = require('./DirectorService');
const ServiceInstanceNotFound = errors.ServiceInstanceNotFound;
const AssertionError = errors.AssertionError;
const Conflict = errors.Conflict;

class BoshTaskPoller {
  static start() {
    function poller(object, intervalId) {
      const resourceDetails = eventmesh.apiServerClient.parseResourceDetailsFromSelfLink(object.metadata.selfLink);
      // If no lockedByPoller annotation then set annotation  with time
      // Else check timestamp if more than specific time than start polling and change lockedByPoller Ip
      return eventmesh.apiServerClient.getResource({
          resourceGroup: resourceDetails.resourceGroup,
          resourceType: resourceDetails.resourceType,
          resourceId: object.metadata.name,
        })
        .then(resourceBody => {
          const options = resourceBody.spec.options;
          const pollerAnnotation = resourceBody.metadata.annotations.lockedByTaskPoller;
          logger.debug(`pollerAnnotation is ${pollerAnnotation} current time is: ${new Date()}`);
          return Promise.try(() => {
            // If task is not picked by poller which has the lock on task for CONST.DIRECTOR_RESOURCE_POLLER_INTERVAL + DIRECTOR_RESOURCE_POLLER_RELAXATION_TIME then try to acquire lock
            if (pollerAnnotation && (JSON.parse(pollerAnnotation).ip !== config.broker_ip) && (new Date() - new Date(JSON.parse(pollerAnnotation).lockTime) < (CONST.DIRECTOR_RESOURCE_POLLER_INTERVAL + CONST.DIRECTOR_RESOURCE_POLLER_RELAXATION_TIME))) { // cahnge this to 5000
              logger.debug(`Process with ip ${JSON.parse(pollerAnnotation).ip} is already polling for task`);
            } else {
              const patchBody = _.cloneDeep(resourceBody);
              const metadata = patchBody.metadata;
              const currentAnnotations = metadata.annotations;
              const patchAnnotations = currentAnnotations ? currentAnnotations : {};
              patchAnnotations.lockedByTaskPoller = JSON.stringify({
                lockTime: new Date(),
                ip: config.broker_ip
              });
              metadata.annotations = patchAnnotations;
              // Handle conflict also
              return eventmesh.apiServerClient.updateResource({
                  resourceGroup: resourceDetails.resourceGroup,
                  resourceType: resourceDetails.resourceType,
                  resourceId: metadata.name,
                  metadata: metadata
                })
                .tap((updatedResource) => logger.debug(`Successfully acquired bosh task poller lock for request with options: ${JSON.stringify(options)}\n` +
                  `Updated resource with poller annotations is: `, updatedResource))
                .then(() => {
                  if (_.includes([CONST.APISERVER.RESOURCE_STATE.SUCCEEDED, CONST.APISERVER.RESOURCE_STATE.FAILED], resourceBody.status.state)) {
                    BoshTaskPoller.clearPoller(metadata.name, intervalId);
                  } else {
                    return DirectorService.createDirectorService(metadata.name, options)
                      .then(boshService => boshService.lastOperation(resourceBody.status.response))
                      .tap(lastOperationValue => logger.debug('last operation value is ', lastOperationValue))
                      .then(lastOperationValue => Promise.all([eventmesh.apiServerClient.updateResource({
                        resourceGroup: CONST.APISERVER.RESOURCE_GROUPS.DEPLOYMENT,
                        resourceType: CONST.APISERVER.RESOURCE_TYPES.DIRECTOR,
                        resourceId: metadata.name,
                        status: {
                          lastOperation: lastOperationValue,
                          state: lastOperationValue.resourceState
                        }
                      }), Promise.try(() => {
                        if (_.includes([CONST.APISERVER.RESOURCE_STATE.SUCCEEDED, CONST.APISERVER.RESOURCE_STATE.FAILED], lastOperationValue.resourceState)) {
                          // cancel the poller and clear the array
                          BoshTaskPoller.clearPoller(metadata.name, intervalId);
                        }
                      })]))
                      .catch(ServiceInstanceNotFound, err => {
                        logger.error(`Error occured while getting last operation`, err);
                        BoshTaskPoller.clearPoller(metadata.name, intervalId);
                        if (resourceBody.status.response.type === 'delete') {
                          return eventmesh.apiServerClient.deleteResource({
                            resourceGroup: CONST.APISERVER.RESOURCE_GROUPS.DEPLOYMENT,
                            resourceType: CONST.APISERVER.RESOURCE_TYPES.DIRECTOR,
                            resourceId: metadata.name
                          });
                        } else {
                          return eventmesh.apiServerClient.updateResource({
                            resourceGroup: CONST.APISERVER.RESOURCE_GROUPS.DEPLOYMENT,
                            resourceType: CONST.APISERVER.RESOURCE_TYPES.DIRECTOR,
                            resourceId: metadata.name,
                            status: {
                              lastOperation: {
                                state: CONST.APISERVER.RESOURCE_STATE.FAILED,
                                description: CONST.SERVICE_BROKER_ERR_MSG
                              },
                              state: CONST.APISERVER.RESOURCE_STATE.FAILED,
                              error: utils.buildErrorJson(err)
                            }
                          });
                        }
                      })
                      .catch(AssertionError, err => {
                        logger.error(`Error occured while getting last operation for instance ${object.metadata.name}`, err);
                        BoshTaskPoller.clearPoller(metadata.name, intervalId);
                        return eventmesh.apiServerClient.updateResource({
                          resourceGroup: CONST.APISERVER.RESOURCE_GROUPS.DEPLOYMENT,
                          resourceType: CONST.APISERVER.RESOURCE_TYPES.DIRECTOR,
                          resourceId: metadata.name,
                          status: {
                            lastOperation: {
                              state: CONST.APISERVER.RESOURCE_STATE.FAILED,
                              description: CONST.SERVICE_BROKER_ERR_MSG
                            },
                            state: CONST.APISERVER.RESOURCE_STATE.FAILED,
                            error: utils.buildErrorJson(err)
                          }
                        });
                      });
                  }
                })
                .catch(Conflict, () => {
                  logger.debug(`Not able to acquire bosh task poller processing lock for instance ${object.metadata.name}, Request is probably picked by other worker`);
                });
            }
          });
        })
        .catch(err => {
          logger.error(`Error occured while polling for last operation for instance ${object.metadata.name}, clearing bosh task poller interval now`, err);
          BoshTaskPoller.clearPoller(object.metadata.name, intervalId);
        });
    }

    function startPoller(event) {
      logger.debug('Received Director Event: ', event);
      if ((event.type === CONST.API_SERVER.WATCH_EVENT.ADDED || event.type === CONST.API_SERVER.WATCH_EVENT.MODIFIED) && !BoshTaskPoller.pollers[event.object.metadata.name]) {
        logger.debug('starting bosh task poller for deployment ', event.object.metadata.name);
        // Poller time should be little less than watch refresh interval as
        const intervalId = setInterval(() => poller(event.object, intervalId), CONST.DIRECTOR_RESOURCE_POLLER_INTERVAL);
        BoshTaskPoller.pollers[event.object.metadata.name] = intervalId;
      }
    }
    const queryString = `state in (${CONST.APISERVER.RESOURCE_STATE.IN_PROGRESS})`;
    return eventmesh.apiServerClient.registerWatcher(CONST.APISERVER.RESOURCE_GROUPS.DEPLOYMENT, CONST.APISERVER.RESOURCE_TYPES.DIRECTOR, startPoller, queryString)
      .then(stream => {
        logger.debug(`Successfully set watcher on director resources for task polling with query string:`, queryString);
        return Promise
          .delay(CONST.APISERVER.POLLER_WATCHER_REFRESH_INTERVAL)
          .then(() => {
            logger.debug(`Refreshing stream after ${CONST.APISERVER.POLLER_WATCHER_REFRESH_INTERVAL}`);
            stream.abort();
            return this.start();
          });
      })
      .catch(err => {
        logger.error(`Error occured in registering watch for bosh task poller:`, err);
        return Promise
          .delay(CONST.APISERVER.WATCHER_ERROR_DELAY)
          .then(() => {
            logger.debug(`Refreshing stream after ${CONST.APISERVER.WATCHER_ERROR_DELAY}`);
            return this.start();
          });
      });
  }

  static clearPoller(resourceId, intervalId) {
    logger.debug(`Clearing bosh task poller interval for deployment`, resourceId);
    if (intervalId) {
      clearInterval(intervalId);
    }
    _.unset(BoshTaskPoller.pollers, resourceId);
  }
}

BoshTaskPoller.pollers = [];
module.exports = BoshTaskPoller;<|endoftext|>


<commit_before>/*
LightCycles

v0.1 K Ellis 19/12/2014

Inspired by the Sinclair ZX Spectrum classic by PSS from 1983 of the same name.
This is an experiment in HTML5's Canvas and Javascript.
*/

(function () {
  "use strict";

  //Initialise the 'global' variables
  var lc = {},
    canvas = document.getElementById('canvas'),
    context = canvas.getContext('2d');

  canvas.width = window.innerWidth;
  canvas.height = window.innerHeight;

  function initialiseGame(numberOfPlayers) {
    var iy, ix;

    lc.pixelSize = (Math.floor(canvas.width / 320) < Math.floor(canvas.height / 200)) ? Math.floor(canvas.width / 320) : Math.floor(canvas.height / 200);

    //Set player start position and directions.
    lc.player1 = {
      xPos: 289,
      yPos: 110,
      dir: 0,
      crashed: false
    };
    lc.player2 = {
      xPos: 30,
      yPos: 100,
      dir: 1,
      crashed: false
    };

    lc.inGame = true;
    lc.players = (numberOfPlayers);
    lc.endMessage = 'Welcome to LightCycles';

    //Clear the drawing area
    context.clearRect(0, 0, canvas.width, canvas.height);

    //(re)set the game array ready for the start of the game.
    lc.gameGrid = []; //320 x 200 grid
    lc.gameDrawn = []; //320 x 200 grid
    for (ix = 0; ix < 320; ix += 1) {
      for (iy = 0; iy < 200; iy += 1) {
        lc.gameGrid[ix * 320 + iy] = 0;
        lc.gameDrawn[ix * 320 + iy] = 0;
        if (iy === 0 || iy === 199) {
          //Replace top/bottom edge with a wall
          lc.gameGrid[ix * 320 + iy] = 1;
        }
        if (ix === 0 || ix === 319) {
          //Replace left/right edge with a wall
          lc.gameGrid[ix * 320 + iy] = 1;
        }
      }
    }
  }

  function drawGameGrid() {
    var iy, ix,
      xOffset, yOffset,
      block, drawn;

    xOffset = (canvas.width - (320 * lc.pixelSize)) / 2;
    yOffset = (canvas.height - (200 * lc.pixelSize)) / 2;

    for (ix = 0; ix < 320; ix += 1) {
      for (iy = 0; iy < 200; iy += 1) {

        //Check gameGrid against drawnGrid, so we only draw the deltas and don't
        //waste cyclers drawing stuff that is already on screen.
        block = lc.gameGrid[ix * 320 + iy];
        drawn = lc.gameDrawn[ix * 320 + iy];
        if (block !== drawn) {
          //Draw pixel grid

          switch (block) {
          case 1: //borders
            context.fillStyle = '#00e2ff';
            break;
          case 2: //Player 1 (red)
            context.fillStyle = '#ff0000';
            break;
          case 3: //player 2 (green)
            context.fillStyle = '#00ff00';
            break;
          default:
            context.fillStyle = '#000000';
            break;
          }

          //Draw a pre-defined wall
          //context.fillStyle = '#'+Math.floor(Math.random()*16777215).toString(16);
          context.fillRect((ix * lc.pixelSize) + xOffset, (iy * lc.pixelSize) + yOffset, lc.pixelSize, lc.pixelSize);
          lc.gameDrawn[ix * 320 + iy] = block;
        } //end draw pixel grid
      }
    }
  }

  function updatePlayerPositions() {

    if (lc.players === 1) {
      //if single player game, we'll update player 2 here.
      //The computer logic is simple, in that it aways turns the same way, unless
      //that way is blocked. I should add some randomness here!
      switch (lc.player2.dir) {
      case 0:
        if (lc.gameGrid[((lc.player2.xPos - 1) * 320) + lc.player2.yPos] !== 0) {
          if (lc.gameGrid[(lc.player2.xPos * 320) + (lc.player2.yPos - 1)] === 0) {
            lc.player2.dir = 2;
          } else {
            lc.player2.dir = 3;
          }
        }
        break;
      case 1:
        if (lc.gameGrid[((lc.player2.xPos + 1) * 320) + lc.player2.yPos] !== 0) {
          if (lc.gameGrid[(lc.player2.xPos * 320) + (lc.player2.yPos + 1)] === 0) {
            lc.player2.dir = 3;
          } else {
            lc.player2.dir = 2;
          }
        }
        break;
      case 2:
        if (lc.gameGrid[(lc.player2.xPos * 320) + (lc.player2.yPos - 1)] !== 0) {
          if (lc.gameGrid[((lc.player2.xPos - 1) * 320) + lc.player2.yPos] !== 0) {
            lc.player2.dir = 1;
          } else {
            lc.player2.dir = 0;
          }
        }
        break;
      case 3:
        if (lc.gameGrid[(lc.player2.xPos * 320) + (lc.player2.yPos + 1)] !== 0) {
          if (lc.gameGrid[((lc.player2.xPos + 1) * 320) + lc.player2.yPos] !== 0) {
            lc.player2.dir = 0;
          } else {
            lc.player2.dir = 1;
          }
        }
        break;
      }
    }

    //Player 1
    switch (lc.player1.dir) {
    case 0: //left
      lc.player1.xPos -= 1;
      break;
    case 1: //left
      lc.player1.xPos += 1;
      break;
    case 2: //up
      lc.player1.yPos -= 1;
      break;
    case 3: //down
      lc.player1.yPos += 1;
      break;
    }
    if (lc.gameGrid[(lc.player1.xPos * 320) + lc.player1.yPos] === 0) {
      lc.gameGrid[(lc.player1.xPos * 320) + lc.player1.yPos] = 2;
    } else {
      lc.player1.crashed = true;
    }

    //Player 2
    switch (lc.player2.dir) {
    case 0: //left
      lc.player2.xPos -= 1;
      break;
    case 1: //left
      lc.player2.xPos += 1;
      break;
    case 2: //up
      lc.player2.yPos -= 1;
      break;
    case 3: //down
      lc.player2.yPos += 1;
      break;
    }
    if (lc.gameGrid[(lc.player2.xPos * 320) + lc.player2.yPos] === 0) {
      lc.gameGrid[(lc.player2.xPos * 320) + lc.player2.yPos] = 3;
    } else {
      lc.player2.crashed = true;
    }
  }

  function checkForPlayerCrash() {
    //Someone has crashed, so what's the score alfy?
    if ((lc.player1.crashed === true && lc.player2.crashed === true) || ((lc.player1.xPos === lc.player2.xPos) && (lc.player1.yPos === lc.player2.yPos))) {
      //it's a draw!
      lc.inGame = false;
      return "Both players have crashed! It's a draw!";
    }

    if (lc.player1.crashed === true) {
      //Player 1
      lc.inGame = false;
      return "Red has crashed. Green Wins!";
    }

    if (lc.player2.crashed === true) {
      //Player 2
      lc.inGame = false;
      return "Green has crashed. Red Wins!";
    }
    return;
  }

  function drawGameOverScreen(text) {
    context.font = lc.pixelSize * 15 + "px Arial";
    context.textAlign = 'center';
    context.fillStyle = '#ffeb00';
    context.fillText(text, canvas.width / 2, (canvas.height / 2) - (lc.pixelSize * 30));
    context.font = lc.pixelSize * 10 + "px Arial";
    context.fillStyle = '#d4c406';
    context.fillText("Press 1 for 1 player (Computer Plays Green), or 2 for 2 players", canvas.width / 2, (canvas.height / 2) + (lc.pixelSize * 40));
    context.fillStyle = '#7ee8f5';
    context.fillText("Green Player: Q, A, Z and X. Red Player: O, P, N and M", canvas.width / 2, (canvas.height / 2) + (lc.pixelSize * 70));
  }

  window.addEventListener("keydown", function (event) {
    switch (event.keyCode) {

    case 78:
      //Key: N - Player 1 Left
      if (lc.player1.dir !== 1) {
        lc.player1.dir = 0;
      }
      break;
    case 77:
      //Key: M - Player 1 Right
      if (lc.player1.dir !== 0) {
        lc.player1.dir = 1;
      }
      break;
    case 80:
      //Key: P - Player 1 Up
      if (lc.player1.dir !== 3) {
        lc.player1.dir = 2;
      }
      break;
    case 76:
      //Key: L - Player 1 Down
      if (lc.player1.dir !== 2) {
        lc.player1.dir = 3;
      }
      break;

    case 49:
      //1 player game selected
      if (lc.inGame === false) {
        initialiseGame(1);
      }
      break;
    case 50:
      //2 player game selected
      if (lc.inGame === false) {
        initialiseGame(2);
      }
      break;
    }

    if (lc.players === 2) {
      //Keyboard controls player 2 (green) only in 2 player mode)
      switch (event.keyCode) {
      case 90:
        //Key: Z - Player 2 Left
        if (lc.player2.dir !== 1) {
          lc.player2.dir = 0;
        }
        break;
      case 88:
        //Key: X - Player 2 Right
        if (lc.player2.dir !== 0) {
          lc.player2.dir = 1;
        }
        break;
      case 81:
        //Key: Q - Player 2 Up
        if (lc.player2.dir !== 3) {
          lc.player2.dir = 2;
        }
        break;
      case 65:
        //Key: A - Player 2 Down
        if (lc.player2.dir !== 2) {
          lc.player2.dir = 3;
        }
        break;
      }
    }

  }, false);

  function draw() {
    setTimeout(function () {
      window.requestAnimationFrame(draw);

      if (lc.inGame === true) {
        updatePlayerPositions();
        lc.endMessage = checkForPlayerCrash();
        drawGameGrid();
      } else {
        drawGameOverScreen(lc.endMessage);
        //waitForGameRestart
      }

    }, 25); // 25ms is 40fps (1000/40)
  }

  //First time in, so force game over and wait for user to start game.
  initialiseGame(0);
  lc.inGame = false;
  draw();

}());<commit_msg>Change starting pos of green player to same line as red<commit_after>/*
LightCycles

v0.1 K Ellis 19/12/2014

Inspired by the Sinclair ZX Spectrum classic by PSS from 1983 of the same name.
This is an experiment in HTML5's Canvas and Javascript.
*/

(function () {
  "use strict";

  //Initialise the 'global' variables
  var lc = {},
    canvas = document.getElementById('canvas'),
    context = canvas.getContext('2d');

  canvas.width = window.innerWidth;
  canvas.height = window.innerHeight;

  function initialiseGame(numberOfPlayers) {
    var iy, ix;

    lc.pixelSize = (Math.floor(canvas.width / 320) < Math.floor(canvas.height / 200)) ? Math.floor(canvas.width / 320) : Math.floor(canvas.height / 200);

    //Set player start position and directions.
    lc.player1 = {
      xPos: 289,
      yPos: 100,
      dir: 0,
      crashed: false
    };
    lc.player2 = {
      xPos: 30,
      yPos: 100,
      dir: 1,
      crashed: false
    };

    lc.inGame = true;
    lc.players = (numberOfPlayers);
    lc.endMessage = 'Welcome to LightCycles';

    //Clear the drawing area
    context.clearRect(0, 0, canvas.width, canvas.height);

    //(re)set the game array ready for the start of the game.
    lc.gameGrid = []; //320 x 200 grid
    lc.gameDrawn = []; //320 x 200 grid
    for (ix = 0; ix < 320; ix += 1) {
      for (iy = 0; iy < 200; iy += 1) {
        lc.gameGrid[ix * 320 + iy] = 0;
        lc.gameDrawn[ix * 320 + iy] = 0;
        if (iy === 0 || iy === 199) {
          //Replace top/bottom edge with a wall
          lc.gameGrid[ix * 320 + iy] = 1;
        }
        if (ix === 0 || ix === 319) {
          //Replace left/right edge with a wall
          lc.gameGrid[ix * 320 + iy] = 1;
        }
      }
    }
  }

  function drawGameGrid() {
    var iy, ix,
      xOffset, yOffset,
      block, drawn;

    xOffset = (canvas.width - (320 * lc.pixelSize)) / 2;
    yOffset = (canvas.height - (200 * lc.pixelSize)) / 2;

    for (ix = 0; ix < 320; ix += 1) {
      for (iy = 0; iy < 200; iy += 1) {

        //Check gameGrid against drawnGrid, so we only draw the deltas and don't
        //waste cyclers drawing stuff that is already on screen.
        block = lc.gameGrid[ix * 320 + iy];
        drawn = lc.gameDrawn[ix * 320 + iy];
        if (block !== drawn) {
          //Draw pixel grid

          switch (block) {
          case 1: //borders
            context.fillStyle = '#00e2ff';
            break;
          case 2: //Player 1 (red)
            context.fillStyle = '#ff0000';
            break;
          case 3: //player 2 (green)
            context.fillStyle = '#00ff00';
            break;
          default:
            context.fillStyle = '#000000';
            break;
          }

          //Draw a pre-defined wall
          //context.fillStyle = '#'+Math.floor(Math.random()*16777215).toString(16);
          context.fillRect((ix * lc.pixelSize) + xOffset, (iy * lc.pixelSize) + yOffset, lc.pixelSize, lc.pixelSize);
          lc.gameDrawn[ix * 320 + iy] = block;
        } //end draw pixel grid
      }
    }
  }

  function updatePlayerPositions() {

    if (lc.players === 1) {
      //if single player game, we'll update player 2 here.
      //The computer logic is simple, in that it aways turns the same way, unless
      //that way is blocked. I should add some randomness here!
      switch (lc.player2.dir) {
      case 0:
        if (lc.gameGrid[((lc.player2.xPos - 1) * 320) + lc.player2.yPos] !== 0) {
          if (lc.gameGrid[(lc.player2.xPos * 320) + (lc.player2.yPos - 1)] === 0) {
            lc.player2.dir = 2;
          } else {
            lc.player2.dir = 3;
          }
        }
        break;
      case 1:
        if (lc.gameGrid[((lc.player2.xPos + 1) * 320) + lc.player2.yPos] !== 0) {
          if (lc.gameGrid[(lc.player2.xPos * 320) + (lc.player2.yPos + 1)] === 0) {
            lc.player2.dir = 3;
          } else {
            lc.player2.dir = 2;
          }
        }
        break;
      case 2:
        if (lc.gameGrid[(lc.player2.xPos * 320) + (lc.player2.yPos - 1)] !== 0) {
          if (lc.gameGrid[((lc.player2.xPos - 1) * 320) + lc.player2.yPos] !== 0) {
            lc.player2.dir = 1;
          } else {
            lc.player2.dir = 0;
          }
        }
        break;
      case 3:
        if (lc.gameGrid[(lc.player2.xPos * 320) + (lc.player2.yPos + 1)] !== 0) {
          if (lc.gameGrid[((lc.player2.xPos + 1) * 320) + lc.player2.yPos] !== 0) {
            lc.player2.dir = 0;
          } else {
            lc.player2.dir = 1;
          }
        }
        break;
      }
    }

    //Player 1
    switch (lc.player1.dir) {
    case 0: //left
      lc.player1.xPos -= 1;
      break;
    case 1: //left
      lc.player1.xPos += 1;
      break;
    case 2: //up
      lc.player1.yPos -= 1;
      break;
    case 3: //down
      lc.player1.yPos += 1;
      break;
    }
    if (lc.gameGrid[(lc.player1.xPos * 320) + lc.player1.yPos] === 0) {
      lc.gameGrid[(lc.player1.xPos * 320) + lc.player1.yPos] = 2;
    } else {
      lc.player1.crashed = true;
    }

    //Player 2
    switch (lc.player2.dir) {
    case 0: //left
      lc.player2.xPos -= 1;
      break;
    case 1: //left
      lc.player2.xPos += 1;
      break;
    case 2: //up
      lc.player2.yPos -= 1;
      break;
    case 3: //down
      lc.player2.yPos += 1;
      break;
    }
    if (lc.gameGrid[(lc.player2.xPos * 320) + lc.player2.yPos] === 0) {
      lc.gameGrid[(lc.player2.xPos * 320) + lc.player2.yPos] = 3;
    } else {
      lc.player2.crashed = true;
    }
  }

  function checkForPlayerCrash() {
    //Someone has crashed, so what's the score alfy?
    if ((lc.player1.crashed === true && lc.player2.crashed === true) || ((lc.player1.xPos === lc.player2.xPos) && (lc.player1.yPos === lc.player2.yPos))) {
      //it's a draw!
      lc.inGame = false;
      return "Both players have crashed! It's a draw!";
    }

    if (lc.player1.crashed === true) {
      //Player 1
      lc.inGame = false;
      return "Red has crashed. Green Wins!";
    }

    if (lc.player2.crashed === true) {
      //Player 2
      lc.inGame = false;
      return "Green has crashed. Red Wins!";
    }
    return;
  }

  function drawGameOverScreen(text) {
    context.font = lc.pixelSize * 15 + "px Arial";
    context.textAlign = 'center';
    context.fillStyle = '#ffeb00';
    context.fillText(text, canvas.width / 2, (canvas.height / 2) - (lc.pixelSize * 30));
    context.font = lc.pixelSize * 10 + "px Arial";
    context.fillStyle = '#d4c406';
    context.fillText("Press 1 for 1 player (Computer Plays Green), or 2 for 2 players", canvas.width / 2, (canvas.height / 2) + (lc.pixelSize * 40));
    context.fillStyle = '#7ee8f5';
    context.fillText("Green Player: Q, A, Z and X. Red Player: O, P, N and M", canvas.width / 2, (canvas.height / 2) + (lc.pixelSize * 70));
  }

  window.addEventListener("keydown", function (event) {
    switch (event.keyCode) {

    case 78:
      //Key: N - Player 1 Left
      if (lc.player1.dir !== 1) {
        lc.player1.dir = 0;
      }
      break;
    case 77:
      //Key: M - Player 1 Right
      if (lc.player1.dir !== 0) {
        lc.player1.dir = 1;
      }
      break;
    case 80:
      //Key: P - Player 1 Up
      if (lc.player1.dir !== 3) {
        lc.player1.dir = 2;
      }
      break;
    case 76:
      //Key: L - Player 1 Down
      if (lc.player1.dir !== 2) {
        lc.player1.dir = 3;
      }
      break;

    case 49:
      //1 player game selected
      if (lc.inGame === false) {
        initialiseGame(1);
      }
      break;
    case 50:
      //2 player game selected
      if (lc.inGame === false) {
        initialiseGame(2);
      }
      break;
    }

    if (lc.players === 2) {
      //Keyboard controls player 2 (green) only in 2 player mode)
      switch (event.keyCode) {
      case 90:
        //Key: Z - Player 2 Left
        if (lc.player2.dir !== 1) {
          lc.player2.dir = 0;
        }
        break;
      case 88:
        //Key: X - Player 2 Right
        if (lc.player2.dir !== 0) {
          lc.player2.dir = 1;
        }
        break;
      case 81:
        //Key: Q - Player 2 Up
        if (lc.player2.dir !== 3) {
          lc.player2.dir = 2;
        }
        break;
      case 65:
        //Key: A - Player 2 Down
        if (lc.player2.dir !== 2) {
          lc.player2.dir = 3;
        }
        break;
      }
    }

  }, false);

  function draw() {
    setTimeout(function () {
      window.requestAnimationFrame(draw);

      if (lc.inGame === true) {
        updatePlayerPositions();
        lc.endMessage = checkForPlayerCrash();
        drawGameGrid();
      } else {
        drawGameOverScreen(lc.endMessage);
        //waitForGameRestart
      }

    }, 25); // 25ms is 40fps (1000/40)
  }

  //First time in, so force game over and wait for user to start game.
  initialiseGame(0);
  lc.inGame = false;
  draw();

}());<|endoftext|>


<commit_before>const webpack = require('webpack');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const entry = {app: './app'};
const jsRule = {
  test: /\.js$/,
  loader: 'babel-loader',
  exclude: [/node_modules/],
  query: {
    presets: ['react', 'es2015', 'stage-0']
  }
};
const isProd = process.env.NODE_ENV === 'production'; // eslint-disable-line
const config = isProd
  ? {
      entry,

      output: {
        path: './',
        filename: 'bundle.js'
      },

      resolve: {
        alias: {
          // 'index':path.join(__dirname,'..', 'src', 'index.js'),
          // 'theme':path.join(__dirname,'..', 'src', 'theme.js')
        }
      },

      module: {
        rules: [
          jsRule,
          {
            test: /\.scss$/,
            loader: ExtractTextPlugin.extract({
              fallbackLoader: 'style-loader',
              loader: ['css-loader', 'sass-loader']
            })
          }
        ]
      },

      plugins: [
        new ExtractTextPlugin('bundle.css'),
        new webpack.optimize.UglifyJsPlugin({compress: {warnings: false}})
      ]
    }
  : {
      entry,

      devtool: 'source-maps',

      module: {
        rules: [
          jsRule,
          {
            test: /\.(sass|scss)$/,
            use: ['style-loader', 'css-loader', 'sass-loader']
          }
        ]
      }
    };

module.exports = config;
<commit_msg>fix webpack windows build issue(#940) (#1144)<commit_after>const webpack = require('webpack');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const path = require('path');
const entry = {app: './app'};
const jsRule = {
  test: /\.js$/,
  loader: 'babel-loader',
  exclude: [/node_modules/],
  query: {
    presets: ['react', 'es2015', 'stage-0']
  }
};
const isProd = process.env.NODE_ENV === 'production'; // eslint-disable-line
const config = isProd
  ? {
      entry,

      output: {
        path: './',
        filename: 'bundle.js'
      },

      resolve: {
        alias: {
          // 'index':path.join(__dirname,'..', 'src', 'index.js'),
          // 'theme':path.join(__dirname,'..', 'src', 'theme.js')
        }
      },

      module: {
        rules: [
          jsRule,
          {
            test: /\.scss$/,
            loader: ExtractTextPlugin.extract({
              fallbackLoader: 'style-loader',
              loader: ['css-loader', 'sass-loader']
            })
          }
        ]
      },

      plugins: [
        new ExtractTextPlugin('bundle.css'),
        new webpack.optimize.UglifyJsPlugin({compress: {warnings: false}})
      ]
    }
  : {
      entry,

      devtool: 'source-maps',

      module: {
        rules: [
          jsRule,
          {
            test: /\.(sass|scss)$/,
            use: ['style-loader', 'css-loader', 'sass-loader']
          }
        ]
      },

      resolve: {
        modules: ['node_modules', path.join(__dirname,'..', 'src')]
      },

    };

module.exports = config;
<|endoftext|>


<commit_before>//========================================================================
//                          Libraries
//========================================================================

var express = require('express')
var publicRouter = express.Router()
var privateRouter = express.Router()
var adminRouter = express.Router()
var mapdb = require('../../models/map')
var query = require('../../helper/query-helper')
var validator = require('validator')
var async = require('async')
var ObjectId = require('mongoose').Types.ObjectId
var logger = require('../../config/logger').mainLogger
var fs = require('fs')
var async = require('async')

privateRouter.get('/', function (req, res) {
  var populate
  if (req.query['populate'] !== undefined) {
    populate = req.query['populate']
  }
  if (populate !== undefined && populate) {
    query.doFindResultSortQuery(req, res, null, {path: 'tiles', populate: {path: 'tileType'}}, mapdb.map)
  } else {
    query.doFindResultSortQuery(req, res, null, null, mapdb.map)
  }
})

adminRouter.get('/tiletypes', function (req, res) {
  query.doFindResultSortQuery(req, res, null, null, mapdb.tileType)
})

privateRouter.get('/:mapid', function (req, res, next) {
  var id = req.params.mapid

  if (!ObjectId.isValid(id)) {
    return next()
  }

  var populate
  if (req.query['populate'] !== undefined) {
    populate = req.query['populate']
  }
  if (populate !== undefined && populate) {
    query.doIdQuery(req, res, id, "", mapdb.map, {path: 'tiles', populate: {path: 'tileType'}})
  } else {
    query.doIdQuery(req, res, id, "", mapdb.map)
  }
})

adminRouter.post('/createmap', function (req, res) {
  var map = req.body
  var tiles = []
  for (var i in map.tiles.length) {
    var tile = map.tiles[i]

    if (isNan(i)) {
      var coords = i.split(',')
      tile.x = coords[0]
      tile.y = coords[1]
      tile.z = coords[2]
    }

    var tileTypeId = typeof tile.tileType === 'object' ? tile.tileType._id : tile.tileType
    tiles.push({
      x        : tile.x,
      y        : tile.y,
      z        : tile.z,
      tileType : tileTypeId,
      rot      : tile.rot,
      items    : {
        obstacles : tile.items.obstacles,
        speedbumps: tile.items.speedbumps
      },
      levelUp  : tile.levelUp,
      levelDown: tile.levelDown
    })
  }

  var newMap = new mapdb.map({
    name  : map.name,
    height: map.height,
    width : map.width,
    length: map.length,
    tiles : tiles,
    startTile : {
      x : map.startTile.x,
      y : map.startTile.y,
      z : map.startTile.z
    },
    numberOfDropTiles : map.numberOfDropTiles
  })

  newMap.save(function (err, data) {
    if (err) {
      res.status(400).send({msg: "Error saving map"})
    } else {
      res.status(201).send({msg: "New map has been saved", id: data._id})
    }
  })
})

publicRouter.all('*', function (req, res, next) {
  next()
})
privateRouter.all('*', function (req, res, next) {
  next()
})

module.exports.public = publicRouter
module.exports.private = privateRouter
module.exports.admin = adminRouter
<commit_msg>Fixed bugs saving map<commit_after>//========================================================================
//                          Libraries
//========================================================================

var express = require('express')
var publicRouter = express.Router()
var privateRouter = express.Router()
var adminRouter = express.Router()
var mapdb = require('../../models/map')
var query = require('../../helper/query-helper')
var validator = require('validator')
var async = require('async')
var ObjectId = require('mongoose').Types.ObjectId
var logger = require('../../config/logger').mainLogger
var fs = require('fs')
var async = require('async')

privateRouter.get('/', function (req, res) {
  var populate
  if (req.query['populate'] !== undefined) {
    populate = req.query['populate']
  }
  if (populate !== undefined && populate) {
    query.doFindResultSortQuery(req, res, null, {path: 'tiles', populate: {path: 'tileType'}}, mapdb.map)
  } else {
    query.doFindResultSortQuery(req, res, null, null, mapdb.map)
  }
})

adminRouter.get('/tiletypes', function (req, res) {
  query.doFindResultSortQuery(req, res, null, null, mapdb.tileType)
})

privateRouter.get('/:mapid', function (req, res, next) {
  var id = req.params.mapid

  if (!ObjectId.isValid(id)) {
    return next()
  }

  var populate
  if (req.query['populate'] !== undefined) {
    populate = req.query['populate']
  }
  if (populate !== undefined && populate) {
    query.doIdQuery(req, res, id, "", mapdb.map, {path: 'tiles', populate: {path: 'tileType'}})
  } else {
    query.doIdQuery(req, res, id, "", mapdb.map)
  }
})

adminRouter.get('/:mapid/update', function (req, res, next) {
  var id = req.params.mapid

  if (!ObjectId.isValid(id)) {
    return next()
  }

})

adminRouter.post('/createmap', function (req, res) {
  var map = req.body

  logger.debug(map)

  var tiles = []
  for (var i in map.tiles) {
    var tile = map.tiles[i]

    if (isNaN(i)) {
      var coords = i.split(',')
      tile.x = coords[0]
      tile.y = coords[1]
      tile.z = coords[2]
    }

    logger.debug(tile)

    var tileTypeId = typeof tile.tileType === 'object' ? tile.tileType._id : tile.tileType
    tiles.push({
      x        : tile.x,
      y        : tile.y,
      z        : tile.z,
      tileType : tileTypeId,
      rot      : tile.rot,
      items    : {
        obstacles : tile.items.obstacles,
        speedbumps: tile.items.speedbumps
      },
      levelUp  : tile.levelUp,
      levelDown: tile.levelDown
    })
  }

  var newMap = new mapdb.map({
    name  : map.name,
    height: map.height,
    width : map.width,
    length: map.length,
    tiles : tiles,
    startTile : {
      x : map.startTile.x,
      y : map.startTile.y,
      z : map.startTile.z
    },
    numberOfDropTiles : map.numberOfDropTiles
  })

  newMap.save(function (err, data) {
    if (err) {
      res.status(400).send({msg: "Error saving map"})
    } else {
      res.status(201).send({msg: "New map has been saved", id: data._id})
    }
  })
})

publicRouter.all('*', function (req, res, next) {
  next()
})
privateRouter.all('*', function (req, res, next) {
  next()
})

module.exports.public = publicRouter
module.exports.private = privateRouter
module.exports.admin = adminRouter
<|endoftext|>


<commit_before>var mongo = require('mongodb');

var Server = mongo.Server,
    Db = mongo.Db,
    BSON = mongo.BSONPure;
	ObjectID = mongo.ObjectID;

// DATA OBJECT
var	produtogrupo = require('./data/produtogrupo');
	produto = require('./data/produto');
	garcom = require('./data/garcom');
	mesa = require('./data/mesa');
	consumomesa = require('./data/consumomesa');

var stringConexao = "ds033069.mongolab.com";
var portaConexao = 33069;

var server = new Server(stringConexao, portaConexao, {auto_reconnect: true});
db = new Db('heroku_app22498672', server, {safe: true});

db.open(function(err, db) {
	console.log("opening connection...");

	if(err) { return console.log("erro aqui -> " + err); }

	console.log("Connected to 'ArquitetaWeb MocksApi' database");

	if (stringConexao == "localhost") {
		console.log("MONGO Authorized");
		db.collection('mesas', {safe:true}, function(err, collection) {
			if (err) {
				console.log(err);
				console.log("The 'mesas' collection doesn't exist. Creating data...");
				populateMesa();
			}
		});
	} else {
		db.authenticate("arquitetaweb", "arqw3b", {}, function(err,success){
			if (err) {
				console.warn("MONGO ERROR: unauthorized "+ err.message);
			} else {
				console.log("MONGO Authorized");
				verifyTables();
			}
		});
	}
});

exports.clear = function(req, res) {
	console.log('Schedule');
	db.collection('mesas', function(err, collection) {
		collection.update({}, {$set: { Situacao: "1" }}, {safe:true, multi:true}, function(err, result) {
			if (err) {
				console.log('Error updating mesa: ' + err);
				res.send({'error':'An error has occurred'});
			} else {
				db.collection('consumomesa', function(err, collection) {
					collection.drop(function(err, result) {
						if (err) {
							console.log('Error drop mesa: ' + err);
							res.send({'error':'An error has occurred'});
						} else {
							console.log('' + result + ' document(s) updated');
							res.send({'sucess':'document(s) updated, sucess!'});
						}
					});
				});
			}
		});
	});
};

exports.recriar = function(req, res) {
	dropTables();
	verifyTables();
	res.send({'sucess':'recreate datatables sucess!'});
};

exports.findById = function(req, res) {
	var id = req.param("id");
	console.log('Retrieving mesa: ' + id);
	db.collection('mesas', function(err, collection) {
		collection.findOne({'Id': parseInt(id)}, function(err, item) {
			res.send("Item ---> " + item.Id);
			console.log('Item ---> ' + item.NumeroMesa);
			console.log('err ---> ' + err);
		});
	});
};

exports.findRaiz = function(req, res) {
    res.send([{name:'Mock'}, {name:'Mock2'}, {name:'Mock3'}]);
};

exports.atualizarmesa = function(req, res) {
	var id = req.param("id");
	var situacao = req.param("situacao");
	console.log('Updating mesa: ' + id + ' for situation ' + situacao);
	db.collection('mesas', function(err, collection) {
		collection.update({ Id: parseInt(id) }, {$set: { Situacao: situacao }}, {safe:true}, function(err, result) {
			if (err) {
				console.log('Error updating mesa: ' + err);
				res.send({'error':'An error has occurred'});
			} else {
				console.log('' + result + ' document(s) updated');
				res.send(result);
			}
		});
	});
};

exports.addconsumomesa = function(req, res) {
	var consumoObject = req.body;
	var idmesa = req.param("MesaId");
	var consumoStr =  JSON.stringify(consumoObject);
	console.log('Consumo: ' +consumoStr);
	console.log('MesaId: ' +idmesa);
	console.log('MesaId2: ' +consumoObject[0]);
	console.log('MesaId3: ' +consumoObject[0].MesaId);
	db.collection('consumomesa', function(err, collection) {
		if (consumoStr == "{}") {
			res.status(500);
			url = req.url;
			console.log('Error insert consumomesa: object invalid retry');
			res.send({'error': 'Invalid object.'});
			return;
		}

		if (err) {
			console.log('Error insert consumomesa: ' + err);
			res.send({'error': 'An error has occurred'});
		} else {
			collection.insert(consumoObject, function (err, inserted) {
				if (err) {
					console.log('Error insert consumomesa: ' + err);
					res.send({'error': 'An error has occurred'});
				} else {
					db.collection('mesas', function(err, collection) {
						collection.update({ Id: parseInt(idmesa) }, {$set: { Situacao: '2' }}, {safe:true}, function(err, result) {
							if (err) {
								console.log('Error updating mesa: ' + err);
								res.send({'error':'An error has occurred'});
							} else {
								var sucess = 'affected: ' + result + ' :: idmesa: '+ idmesa + ((result > 0) ? ' - sucess' : ' - error. opss...!');
								console.log(sucess);
								res.send(sucess);
							}
						});
					});
					console.log('Sucess inserted consumomesa: ' + inserted);
					res.send(inserted);
				}
			});
		}
	});
};

exports.getfecharconta = function(req, res) {
	var idmesa = req.param("idmesa");
	console.log('Retrieving fechar mesa: ' + idmesa);
	db.collection('consumomesa', function(err, collection) {
		collection.remove({'MesaId': parseInt(idmesa)}, function(err, items) {
			if (err) {
				console.log('Error fechar mesa: ' + err);
				res.send({'error':'An error has occurred'});
			} else {
				db.collection('mesas', function(err, collection) {
					collection.update({ Id: parseInt(idmesa) }, {$set: { Situacao: '3' }}, {safe:true}, function(err, result) {
						if (err) {
							console.log('Error updating mesa: ' + err);
							res.send({'error':'An error has occurred'});
						} else {
							var sucess = 'affected: ' + result + ' :: idmesa: '+ idmesa + ((result > 0) ? ' - sucess' : ' - error. opss...!');
							console.log(sucess);
							res.send(sucess);
						}
					});
				});
			}
		});
	});
};

exports.getconsumorecente = function(req, res) {
	var idmesa = req.param("idmesa");
	var qtdeRegistros = req.param("qtde");
	console.log('Retrieving consumo mesa: ' + idmesa);
	console.log('Retrieving consumo qtde: ' + qtdeRegistros);
	db.collection('consumomesa', function(err, collection) {
		collection.find({'MesaId': parseInt(idmesa)}).sort({DataHoraPedido: -1}).limit(parseInt(qtdeRegistros)).toArray(function(err, items) {
			res.send(items);
		});
	});
};

exports.getconsumomesa = function(req, res) {
	var idmesa = req.param("idmesa");
	console.log('Retrieving consumo mesa: ' + idmesa);
	db.collection('consumomesa', function(err, collection) {
		collection.find({'MesaId': parseInt(idmesa)}).toArray(function(err, items) {
			res.send(items);
		});
	});
};

exports.mesas = function(req, res) {
	db.collection('mesas', function(err, collection) {
		collection.find().toArray(function(err, items) {
			res.send(items);
		});
	});
};

exports.garcom = function(req, res) {
	db.collection('garcom', function(err, collection) {
		collection.find().toArray(function(err, items) {
			res.send(items);
		});
	});
};

exports.produtogrupo = function(req, res) {
	db.collection('produtogrupo', function(err, collection) {
		collection.find().toArray(function(err, items) {
			res.send(items);
		});
	});
};

exports.produto = function(req, res) {
	db.collection('produto', function(err, collection) {
		collection.find().toArray(function(err, items) {
			res.send(items);
		});
	});
};

dropTables = function() {
	db.collection('mesas').drop();
	db.collection('garcom').drop();
	db.collection('produtogrupo').drop();
	db.collection('produto').drop();
	db.collection('consumomesa').drop();
}

verifyTables = function() {
	db.collection('mesas', {safe:true}, function(err, collection) {
		if (err) {
			console.log(err);
			console.log("The 'mesas' collection doesn't exist. Creating data...");
			populateMesa();
		}
	});

	db.collection('garcom', {safe:true}, function(err, collection) {
		if (err) {
			console.log(err);
			console.log("The 'garcom' collection doesn't exist. Creating data...");
			populateGarcom();
		}
	});

	db.collection('produtogrupo', {safe:true}, function(err, collection) {
		if (err) {
			console.log(err);
			console.log("The 'produtogrupo' collection doesn't exist. Creating data...");
			populateProdutoGrupo();
		}
	});

	db.collection('produto', {safe:true}, function(err, collection) {
		if (err) {
			console.log(err);
			console.log("The 'produto' collection doesn't exist. Creating data...");
			populateProduto();
		}
	});

	db.collection('consumomesa', {safe:true}, function(err, collection) {
		if (err) {
			console.log(err);
			console.log("The 'consumo mesa' collection doesn't exist. Creating data...");
			populateConsumoMesa();
		}
	});
};

populateMesa = function() {
	console.log("populando mesas");

    db.collection('mesas', function(err, collection) {
		console.log("inserindo mesas");
        collection.insert(mesa.data(), {safe:true}, function(err, result) {});
    });
};

populateGarcom = function() {
	console.log("populando garcom");

	db.collection('garcom', function(err, collection) {
		console.log("inserindo garcom");
		collection.insert(garcom.data(), {safe:true}, function(err, result) {});
    });
};

populateProdutoGrupo = function() {
	console.log("populando produtogrupo");

	db.collection('produtogrupo', function(err, collection) {
		console.log("inserindo produtogrupo");
		collection.insert(produtogrupo.data(), {safe:true}, function(err, result) {});
    });
};

populateProduto = function() {
	console.log("populando produto");

	db.collection('produto', function(err, collection) {
		console.log("inserindo produto");
		collection.insert(produto.data(), {safe:true}, function(err, result) {});
    });
};

populateConsumoMesa = function() {
	console.log("populando consumomesa");

	db.collection('consumomesa', function(err, collection) {
		console.log("inserindo consumomesa");
		collection.insert(consumomesa.data(), {safe:true}, function(err, result) {});
    });
};<commit_msg>#200320141551<commit_after>var mongo = require('mongodb');

var Server = mongo.Server,
    Db = mongo.Db,
    BSON = mongo.BSONPure;
	ObjectID = mongo.ObjectID;

// DATA OBJECT
var	produtogrupo = require('./data/produtogrupo');
	produto = require('./data/produto');
	garcom = require('./data/garcom');
	mesa = require('./data/mesa');
	consumomesa = require('./data/consumomesa');

var stringConexao = "ds033069.mongolab.com";
var portaConexao = 33069;

var server = new Server(stringConexao, portaConexao, {auto_reconnect: true});
db = new Db('heroku_app22498672', server, {safe: true});

db.open(function(err, db) {
	console.log("opening connection...");

	if(err) { return console.log("erro aqui -> " + err); }

	console.log("Connected to 'ArquitetaWeb MocksApi' database");

	if (stringConexao == "localhost") {
		console.log("MONGO Authorized");
		db.collection('mesas', {safe:true}, function(err, collection) {
			if (err) {
				console.log(err);
				console.log("The 'mesas' collection doesn't exist. Creating data...");
				populateMesa();
			}
		});
	} else {
		db.authenticate("arquitetaweb", "arqw3b", {}, function(err,success){
			if (err) {
				console.warn("MONGO ERROR: unauthorized "+ err.message);
			} else {
				console.log("MONGO Authorized");
				verifyTables();
			}
		});
	}
});

exports.clear = function(req, res) {
	console.log('Schedule');
	db.collection('mesas', function(err, collection) {
		collection.update({}, {$set: { Situacao: "1" }}, {safe:true, multi:true}, function(err, result) {
			if (err) {
				console.log('Error updating mesa: ' + err);
				res.send({'error':'An error has occurred'});
			} else {
				db.collection('consumomesa', function(err, collection) {
					collection.drop(function(err, result) {
						if (err) {
							console.log('Error drop mesa: ' + err);
							res.send({'error':'An error has occurred'});
						} else {
							console.log('' + result + ' document(s) updated');
							res.send({'sucess':'document(s) updated, sucess!'});
						}
					});
				});
			}
		});
	});
};

exports.recriar = function(req, res) {
	dropTables();
	verifyTables();
	res.send({'sucess':'recreate datatables sucess!'});
};

exports.findById = function(req, res) {
	var id = req.param("id");
	console.log('Retrieving mesa: ' + id);
	db.collection('mesas', function(err, collection) {
		collection.findOne({'Id': parseInt(id)}, function(err, item) {
			res.send("Item ---> " + item.Id);
			console.log('Item ---> ' + item.NumeroMesa);
			console.log('err ---> ' + err);
		});
	});
};

exports.findRaiz = function(req, res) {
    res.send([{name:'Mock'}, {name:'Mock2'}, {name:'Mock3'}]);
};

exports.atualizarmesa = function(req, res) {
	var id = req.param("id");
	var situacao = req.param("situacao");
	console.log('Updating mesa: ' + id + ' for situation ' + situacao);
	db.collection('mesas', function(err, collection) {
		collection.update({ Id: parseInt(id) }, {$set: { Situacao: situacao }}, {safe:true}, function(err, result) {
			if (err) {
				console.log('Error updating mesa: ' + err);
				res.send({'error':'An error has occurred'});
			} else {
				console.log('' + result + ' document(s) updated');
				res.send(result);
			}
		});
	});
};

exports.addconsumomesa = function(req, res) {
	var consumoObject = req.body;
	var consumoStr =  JSON.stringify(consumoObject);
	console.log('Consumo: ' +consumoStr);
	console.log('MesaId: ' +consumoObject[0].MesaId);
	db.collection('consumomesa', function(err, collection) {
		if (consumoStr == "{}") {
			res.status(500);
			url = req.url;
			console.log('Error insert consumomesa: object invalid retry');
			res.send({'error': 'Invalid object.'});
			return;
		}

		if (err) {
			console.log('Error insert consumomesa: ' + err);
			res.send({'error': 'An error has occurred'});
		} else {
			collection.insert(consumoObject, function (err, inserted) {
				if (err) {
					console.log('Error insert consumomesa: ' + err);
					res.send({'error': 'An error has occurred'});
				} else {
					var idmesa = consumoObject[0].MesaId;
					db.collection('mesas', function(err, collection) {
						collection.update({ Id: parseInt(idmesa) }, {$set: { Situacao: '2' }}, {safe:true}, function(err, result) {
							if (err) {
								console.log('Error updating mesa: ' + err);
								res.send({'error':'An error has occurred'});
							} else {
								var sucess = 'affected: ' + result + ' :: idmesa: '+ idmesa + ((result > 0) ? ' - sucess' : ' - error. opss...!');
								console.log(sucess);
								res.send(sucess);
							}
						});
					});
					console.log('Sucess inserted consumomesa: ' + inserted);
					res.send(inserted);
				}
			});
		}
	});
};

exports.getfecharconta = function(req, res) {
	var idmesa = req.param("idmesa");
	console.log('Retrieving fechar mesa: ' + idmesa);
	db.collection('consumomesa', function(err, collection) {
		collection.remove({'MesaId': parseInt(idmesa)}, function(err, items) {
			if (err) {
				console.log('Error fechar mesa: ' + err);
				res.send({'error':'An error has occurred'});
			} else {
				db.collection('mesas', function(err, collection) {
					collection.update({ Id: parseInt(idmesa) }, {$set: { Situacao: '3' }}, {safe:true}, function(err, result) {
						if (err) {
							console.log('Error updating mesa: ' + err);
							res.send({'error':'An error has occurred'});
						} else {
							var sucess = 'affected: ' + result + ' :: idmesa: '+ idmesa + ((result > 0) ? ' - sucess' : ' - error. opss...!');
							console.log(sucess);
							res.send(sucess);
						}
					});
				});
			}
		});
	});
};

exports.getconsumorecente = function(req, res) {
	var idmesa = req.param("idmesa");
	var qtdeRegistros = req.param("qtde");
	console.log('Retrieving consumo mesa: ' + idmesa);
	console.log('Retrieving consumo qtde: ' + qtdeRegistros);
	db.collection('consumomesa', function(err, collection) {
		collection.find({'MesaId': parseInt(idmesa)}).sort({DataHoraPedido: -1}).limit(parseInt(qtdeRegistros)).toArray(function(err, items) {
			res.send(items);
		});
	});
};

exports.getconsumomesa = function(req, res) {
	var idmesa = req.param("idmesa");
	console.log('Retrieving consumo mesa: ' + idmesa);
	db.collection('consumomesa', function(err, collection) {
		collection.find({'MesaId': parseInt(idmesa)}).toArray(function(err, items) {
			res.send(items);
		});
	});
};

exports.mesas = function(req, res) {
	db.collection('mesas', function(err, collection) {
		collection.find().toArray(function(err, items) {
			res.send(items);
		});
	});
};

exports.garcom = function(req, res) {
	db.collection('garcom', function(err, collection) {
		collection.find().toArray(function(err, items) {
			res.send(items);
		});
	});
};

exports.produtogrupo = function(req, res) {
	db.collection('produtogrupo', function(err, collection) {
		collection.find().toArray(function(err, items) {
			res.send(items);
		});
	});
};

exports.produto = function(req, res) {
	db.collection('produto', function(err, collection) {
		collection.find().toArray(function(err, items) {
			res.send(items);
		});
	});
};

dropTables = function() {
	db.collection('mesas').drop();
	db.collection('garcom').drop();
	db.collection('produtogrupo').drop();
	db.collection('produto').drop();
	db.collection('consumomesa').drop();
}

verifyTables = function() {
	db.collection('mesas', {safe:true}, function(err, collection) {
		if (err) {
			console.log(err);
			console.log("The 'mesas' collection doesn't exist. Creating data...");
			populateMesa();
		}
	});

	db.collection('garcom', {safe:true}, function(err, collection) {
		if (err) {
			console.log(err);
			console.log("The 'garcom' collection doesn't exist. Creating data...");
			populateGarcom();
		}
	});

	db.collection('produtogrupo', {safe:true}, function(err, collection) {
		if (err) {
			console.log(err);
			console.log("The 'produtogrupo' collection doesn't exist. Creating data...");
			populateProdutoGrupo();
		}
	});

	db.collection('produto', {safe:true}, function(err, collection) {
		if (err) {
			console.log(err);
			console.log("The 'produto' collection doesn't exist. Creating data...");
			populateProduto();
		}
	});

	db.collection('consumomesa', {safe:true}, function(err, collection) {
		if (err) {
			console.log(err);
			console.log("The 'consumo mesa' collection doesn't exist. Creating data...");
			populateConsumoMesa();
		}
	});
};

populateMesa = function() {
	console.log("populando mesas");

    db.collection('mesas', function(err, collection) {
		console.log("inserindo mesas");
        collection.insert(mesa.data(), {safe:true}, function(err, result) {});
    });
};

populateGarcom = function() {
	console.log("populando garcom");

	db.collection('garcom', function(err, collection) {
		console.log("inserindo garcom");
		collection.insert(garcom.data(), {safe:true}, function(err, result) {});
    });
};

populateProdutoGrupo = function() {
	console.log("populando produtogrupo");

	db.collection('produtogrupo', function(err, collection) {
		console.log("inserindo produtogrupo");
		collection.insert(produtogrupo.data(), {safe:true}, function(err, result) {});
    });
};

populateProduto = function() {
	console.log("populando produto");

	db.collection('produto', function(err, collection) {
		console.log("inserindo produto");
		collection.insert(produto.data(), {safe:true}, function(err, result) {});
    });
};

populateConsumoMesa = function() {
	console.log("populando consumomesa");

	db.collection('consumomesa', function(err, collection) {
		console.log("inserindo consumomesa");
		collection.insert(consumomesa.data(), {safe:true}, function(err, result) {});
    });
};<|endoftext|>