<commit_before>var _ = require("underscore")._;

module.exports = ArgParser;

// for nomnom.parseArgs()
var argParser = ArgParser();
for(var i in argParser) {
  if(typeof argParser[i] == "function")
    ArgParser[i] = argParser[i];
}

function ArgParser() {

  function opt(arg) {
    // get the specified opt for this parsed arg
    var match = Opt({});
    parser.specs.forEach(function(opt) {
      if(opt.matches(arg))
        match = opt;
    });
    return match;
  };

  function setOption(options, arg, value) {
    var option = opt(arg);
    if(option.callback) {
      var message = option.callback(value);
      if(typeof message == "string") {
        parser.print(message);
      }
    }
    var name = option.name || arg;

    if (option.type != "string") {
       try { // try to infer type by JSON parsing the string
         value = JSON.parse(value)
       } catch(e) {}
    }

    if (option.choices && option.choices.indexOf(value) == -1) {
       parser.print(name + " must be one of: " + option.choices.join(", "));
    }

    if(option.list) {
      if(!options[name])
        options[name] = [value];
      else
        options[name].push(value);
    }
    else
      options[name] = value;
  };

  var parser = {
    commands : {},
    specs: {},

    command : function(name) {
      var command = parser.commands[name] = {
        name: name,
        specs: {}
      };

      // facilitates command('name').opts().callback().help()
      var chain = {
        opts : function(specs) {
          command.specs = specs;
          return chain;
        },
        callback : function(callback) {
          command.callback = callback;
          return chain;
        },
        help : function(help) {
          command.help = help;
          return chain;
        },
        usage : function(usage) {
          command.usageString = usage;
          return chain;
        }
      };
      return chain;
    },

    globalOpts : function(specs) {
      parser.globalSpecs = specs;
      return parser;
    },

    opts : function(specs) {
      parser.specs = specs;
      return parser;
    },

    callback : function(fallbackCb) {
      parser.fallbackCb = fallbackCb;
      return parser;
    },

    usage : function(usageString) {
      parser.usageString = usageString;
      return parser;
    },

    printFunc : function(print) {
      parser.print = print;
      return parser;
    },

    scriptName : function(script) {
      parser.script = script;
      return parser;
    },

    help : function(helpString) {
      parser.helpString = helpString;
      return parser;
    },

    parseArgs : function(argv, parserOpts) {
      var printHelp = true;
      if(argv && (!argv.length || typeof argv[0] != "string")) {
        // using old API
        parserOpts = parserOpts || {};
        parser.specs = argv;
        parser.script = parserOpts.script;
        parser.print = parserOpts.printFunc;
        printHelp = parserOpts.printHelp;
        if(printHelp === undefined)
          printHelp = true;
        argv = parserOpts.argv;
      }
      parser.print = parser.print || function(str) {
        require("sys").puts(str);
        process.exit(0);
      };
      parser.helpString = parser.helpString || "";
      parser.script = parser.script || process.argv[0] + " "
            + require('path').basename(process.argv[1]);

      parser.specs = parser.specs || {};
      var argv = argv || process.argv.slice(2);

      var commandName;
      if(JSON.stringify(parser.commands) != "{}") {
        if(argv.length && Arg(argv[0]).isValue)
          commandName = argv[0];

        if(!commandName) {
          // no command but command expected e.g. 'git -h'
          parser.specs.command = {
            position: 0,
            help: 'one of: ' + _(parser.commands).keys().join(", ")
          }
          _(parser.specs).extend(parser.globalSpecs);
        }
        else {
          // command specified e.g. 'git add -p'
          var command = parser.commands[commandName];
          if(!command)
            parser.print(parser.script + ": no such command '" + commandName + "'");
          parser.specs = _(command.specs).extend(parser.globalSpecs);
          parser.script += " " + command.name;
          if(command.help)
            parser.helpString = command.help;
        }
      }

      if(parser.specs.length === undefined) {
        // specs is a hash not an array
        parser.specs = _(parser.specs).map(function(opt, name) {
          opt.name = name;
          return opt;
        });
      }
      parser.specs = parser.specs.map(function(opt) {
        return Opt(opt);
      });

      if(printHelp && (argv.indexOf("--help") != -1
           || argv.indexOf("-h") != -1))
        parser.print(parser.getUsage(command));

      var options = {};
      args = argv.map(function(arg) {
        return Arg(arg);
      }).concat(Arg());
      var positionals = [];

      /* parse the args */
      args.reduce(function(arg, val) {
        /* word */
        if(arg.isValue) {
          positionals.push(arg.value);
        }
        /* -c */
        else if(arg.chars) {
          var lastChar = arg.chars.pop();

          /* -cfv */
          (arg.chars).forEach(function(ch) {
            setOption(options, ch, true);
          });

          /* -c 3 */
          if(val.isValue && opt(lastChar).expectsValue) {
            setOption(options, lastChar, val.value);
            return Arg(); // skip next turn - swallow arg
          }
          else {
            setOption(options, lastChar, true);
          }
        }
        /* --config=tests.json or --debug */
        else if(arg.full) {
          var value = arg.value;
          /* --debug */
          if(value === undefined) {
            /* --config test */
            if(val.isValue && opt(arg.full).expectsValue) {
               setOption(options, arg.full, val.value);
               return Arg();
            }
            else {
              value = true;
            }
          }
          setOption(options, arg.full, value);
        }
        return val;
      });

      positionals.forEach(function(pos, index) {
        setOption(options, index, pos);
      });

      options._ = positionals;

      parser.specs.forEach(function(opt) {
        if(typeof options[opt.name] == "undefined")
          options[opt.name] = opt.default;
      });

      // exit if required arg isn't present
      parser.specs.forEach(function(opt) {
        if(opt.required && options[opt.name] === undefined)
          parser.print(opt.name + " argument is required\n\n" + parser.getUsage(command));
      });

      if(command && command.callback)
        command.callback(options);
      else if(parser.fallbackCb)
        parser.fallbackCb(options);

      return options;
    },

    getUsage : function(command) {
      if(command && command.usageString)
        return command.usageString;
      if(parser.usageString)
        return parser.usageString;

      // todo: use a template
      var str = "usage: " + parser.script;

      var positionals = _(parser.specs).select(function(opt) {
        return opt.position != undefined;
      })
      positionals = _(positionals).sortBy(function(opt) {
        return opt.position;
      });
      var options = _(parser.specs).select(function(opt) {
        return opt.position === undefined;
      });

      // assume there are no gaps in the specified pos. args
      positionals.forEach(function(pos) {
        str += " ";
        var posStr = pos.string;
        if(!posStr) {
          posStr = "<" + (pos.name || "arg" + pos.position) + ">";
          if(pos.list)
            posStr += "...";
        }
        str += posStr;
      });
      if(options.length || positionals.length)
        str += " [options]\n\n";

      function spaces(length) {
        var spaces = "";
        for(var i = 0; i < length; i++)
          spaces += " ";
        return spaces;
      }
      var longest = positionals.reduce(function(max, pos) {
          return pos.name.length > max ? pos.name.length : max;
      }, 0);
      positionals.forEach(function(pos) {
        var posStr = pos.string || pos.name;
        str += posStr + spaces(longest - posStr.length) + "     "
               + (pos.help || "") + "\n";
      });
      if(positionals.length && options.length)
        str += "\n";

      if(options.length)
        str += "options:\n";

      var longest = options.reduce(function(max, opt) {
        return opt.string.length > max && !opt.hidden ? opt.string.length : max;
      }, 0);
      options.forEach(function(opt) {
        if(!opt.hidden)
          str += "   " + opt.string + spaces(longest - opt.string.length)
                 + "   " + (opt.help || "") + "\n";
      });
      return str + "\n" + (parser.helpString || "") + "\n";
    }
  }

  return parser;
};

/* an opt is what's specified by the user in opts hash */
Opt = function(opt) {
  var strings = (opt.string || "").split(","),
      abbr, full, metavar;
  for (var i = 0; i < strings.length; i++) {
    var string = strings[i].trim(),
        matches;
    if (matches = string.match(/^\-([^-])(?:\s+(.*))?$/)) {
      abbr = matches[1];
      metavar = matches[2];
    }
    else if(matches = string.match(/^\-\-(.+?)(?:[=\s]+(.+))?$/)) {
      full = matches[1];
      metavar = metavar || matches[2];
    }
  }

  matches = matches || [];
  var abbr = opt.abbr || abbr,   // e.g. v from -v
      full = opt.full || full, // e.g. verbose from --verbose
      metavar = opt.metavar || metavar;  // e.g. PATH from '--config=PATH'
      expectsValue = opt.expectsValue || metavar || opt.default;

  var string;
  if(opt.string) {
    string = opt.string;
  }
  else if (opt.position === undefined) {
    string= "";
    if(abbr) {
      string += "-" + abbr;
      if(metavar)
        string += " " + metavar
      string += ", ";
    }
    string += "--" + (full || opt.name);
    if(metavar)
      string += " " + metavar;
  }

  opt = _(opt).extend({
    name: opt.name || full || abbr,
    string: string,
    abbr: abbr,
    full: full,
    metavar: metavar,
    matches: function(arg) {
      return opt.full == arg || opt.abbr == arg || opt.position == arg
        || opt.name == arg || (opt.list && arg >= opt.position);
    },
    expectsValue: expectsValue
  });
  return opt;
}

/* an arg is an item that's actually parsed from the command line
   e.g. "-l", "log.txt", or "--logfile=log.txt" */
Arg = function(str) {
  var abbrRegex = /^\-(\w+?)$/,
      fullRegex = /^\-\-(no\-)?(.+?)(?:=(.+))?$/,
      valRegex = /^[^\-].*/;

  var charMatch = abbrRegex.exec(str),
      chars = charMatch && charMatch[1].split("");

  var fullMatch = fullRegex.exec(str),
      full = fullMatch && fullMatch[2];

  var isValue = str !== undefined && (str === "" || valRegex.test(str)),
      value;
  if(isValue)
    value = str;
  else if(full)
    value = fullMatch[1] ? false : fullMatch[3];

  return {
    str: str,
    chars: chars,
    full: full,
    value: value,
    isValue: isValue
  }
}<commit_msg>Fail if a value is expected, but none set<commit_after>var _ = require("underscore")._;

module.exports = ArgParser;

// for nomnom.parseArgs()
var argParser = ArgParser();
for(var i in argParser) {
  if(typeof argParser[i] == "function")
    ArgParser[i] = argParser[i];
}

function ArgParser() {

  function opt(arg) {
    // get the specified opt for this parsed arg
    var match = Opt({});
    parser.specs.forEach(function(opt) {
      if(opt.matches(arg))
        match = opt;
    });
    return match;
  };

  function setOption(options, arg, value) {
    var option = opt(arg);
    if(option.callback) {
      var message = option.callback(value);
      if(typeof message == "string") {
        parser.print(message);
      }
    }
    var name = option.name || arg;

    if (option.type != "string") {
       try { // try to infer type by JSON parsing the string
         value = JSON.parse(value)
       } catch(e) {}
    }

    if (option.choices && option.choices.indexOf(value) == -1) {
       parser.print(name + " must be one of: " + option.choices.join(", "));
    }

    if(option.list) {
      if(!options[name])
        options[name] = [value];
      else
        options[name].push(value);
    }
    else
      options[name] = value;
  };

  var parser = {
    commands : {},
    specs: {},

    command : function(name) {
      var command = parser.commands[name] = {
        name: name,
        specs: {}
      };

      // facilitates command('name').opts().callback().help()
      var chain = {
        opts : function(specs) {
          command.specs = specs;
          return chain;
        },
        callback : function(callback) {
          command.callback = callback;
          return chain;
        },
        help : function(help) {
          command.help = help;
          return chain;
        },
        usage : function(usage) {
          command.usageString = usage;
          return chain;
        }
      };
      return chain;
    },

    globalOpts : function(specs) {
      parser.globalSpecs = specs;
      return parser;
    },

    opts : function(specs) {
      parser.specs = specs;
      return parser;
    },

    callback : function(fallbackCb) {
      parser.fallbackCb = fallbackCb;
      return parser;
    },

    usage : function(usageString) {
      parser.usageString = usageString;
      return parser;
    },

    printFunc : function(print) {
      parser.print = print;
      return parser;
    },

    scriptName : function(script) {
      parser.script = script;
      return parser;
    },

    help : function(helpString) {
      parser.helpString = helpString;
      return parser;
    },

    parseArgs : function(argv, parserOpts) {
      var printHelp = true;
      if(argv && (!argv.length || typeof argv[0] != "string")) {
        // using old API
        parserOpts = parserOpts || {};
        parser.specs = argv;
        parser.script = parserOpts.script;
        parser.print = parserOpts.printFunc;
        printHelp = parserOpts.printHelp;
        if(printHelp === undefined)
          printHelp = true;
        argv = parserOpts.argv;
      }
      parser.print = parser.print || function(str) {
        require("sys").puts(str);
        process.exit(0);
      };
      parser.helpString = parser.helpString || "";
      parser.script = parser.script || process.argv[0] + " "
            + require('path').basename(process.argv[1]);

      parser.specs = parser.specs || {};
      var argv = argv || process.argv.slice(2);

      var commandName;
      if(JSON.stringify(parser.commands) != "{}") {
        if(argv.length && Arg(argv[0]).isValue)
          commandName = argv[0];

        if(!commandName) {
          // no command but command expected e.g. 'git -h'
          parser.specs.command = {
            position: 0,
            help: 'one of: ' + _(parser.commands).keys().join(", ")
          }
          _(parser.specs).extend(parser.globalSpecs);
        }
        else {
          // command specified e.g. 'git add -p'
          var command = parser.commands[commandName];
          if(!command)
            parser.print(parser.script + ": no such command '" + commandName + "'");
          parser.specs = _(command.specs).extend(parser.globalSpecs);
          parser.script += " " + command.name;
          if(command.help)
            parser.helpString = command.help;
        }
      }

      if(parser.specs.length === undefined) {
        // specs is a hash not an array
        parser.specs = _(parser.specs).map(function(opt, name) {
          opt.name = name;
          return opt;
        });
      }
      parser.specs = parser.specs.map(function(opt) {
        return Opt(opt);
      });

      if(printHelp && (argv.indexOf("--help") != -1
           || argv.indexOf("-h") != -1))
        parser.print(parser.getUsage(command));

      var options = {};
      args = argv.map(function(arg) {
        return Arg(arg);
      }).concat(Arg());
      var positionals = [];

      /* parse the args */
      args.reduce(function(arg, val) {
        /* word */
        if(arg.isValue) {
          positionals.push(arg.value);
        }
        /* -c */
        else if(arg.chars) {
          var lastChar = arg.chars.pop();

          /* -cfv */
          (arg.chars).forEach(function(ch) {
            setOption(options, ch, true);
          });

          /* -c 3 */
          if(val.isValue && opt(lastChar).expectsValue) {
            setOption(options, lastChar, val.value);
            return Arg(); // skip next turn - swallow arg
          }
          else if(opt(lastChar).expectsValue && val.value === undefined) {
            parser.print(opt(lastChar).name + " expects a value\n\n" + parser.getUsage(command));
          }
          else {
            setOption(options, lastChar, true);
          }
        }
        /* --config=tests.json or --debug */
        else if(arg.full) {
          var value = arg.value;
          /* --debug */
          if(value === undefined) {
            /* --config test */
            if(val.isValue && opt(arg.full).expectsValue) {
              setOption(options, arg.full, val.value);
              return Arg();
            }
            else if(opt(arg.full).expectsValue && val.value === undefined) {
              parser.print(opt(arg.full).name + " expects a value\n\n" + parser.getUsage(command));
            }
            else {
              value = true;
            }
          }
          setOption(options, arg.full, value);
        }
        return val;
      });

      positionals.forEach(function(pos, index) {
        setOption(options, index, pos);
      });

      options._ = positionals;

      parser.specs.forEach(function(opt) {
        if(typeof options[opt.name] == "undefined")
          options[opt.name] = opt.default;
      });

      // exit if required arg isn't present
      parser.specs.forEach(function(opt) {
        if(opt.required && options[opt.name] === undefined)
          parser.print(opt.name + " argument is required\n\n" + parser.getUsage(command));
      });

      if(command && command.callback)
        command.callback(options);
      else if(parser.fallbackCb)
        parser.fallbackCb(options);

      return options;
    },

    getUsage : function(command) {
      if(command && command.usageString)
        return command.usageString;
      if(parser.usageString)
        return parser.usageString;

      // todo: use a template
      var str = "usage: " + parser.script;

      var positionals = _(parser.specs).select(function(opt) {
        return opt.position != undefined;
      })
      positionals = _(positionals).sortBy(function(opt) {
        return opt.position;
      });
      var options = _(parser.specs).select(function(opt) {
        return opt.position === undefined;
      });

      // assume there are no gaps in the specified pos. args
      positionals.forEach(function(pos) {
        str += " ";
        var posStr = pos.string;
        if(!posStr) {
          posStr = "<" + (pos.name || "arg" + pos.position) + ">";
          if(pos.list)
            posStr += "...";
        }
        str += posStr;
      });
      if(options.length || positionals.length)
        str += " [options]\n\n";

      function spaces(length) {
        var spaces = "";
        for(var i = 0; i < length; i++)
          spaces += " ";
        return spaces;
      }
      var longest = positionals.reduce(function(max, pos) {
          return pos.name.length > max ? pos.name.length : max;
      }, 0);
      positionals.forEach(function(pos) {
        var posStr = pos.string || pos.name;
        str += posStr + spaces(longest - posStr.length) + "     "
               + (pos.help || "") + "\n";
      });
      if(positionals.length && options.length)
        str += "\n";

      if(options.length)
        str += "options:\n";

      var longest = options.reduce(function(max, opt) {
        return opt.string.length > max && !opt.hidden ? opt.string.length : max;
      }, 0);
      options.forEach(function(opt) {
        if(!opt.hidden)
          str += "   " + opt.string + spaces(longest - opt.string.length)
                 + "   " + (opt.help || "") + "\n";
      });
      return str + "\n" + (parser.helpString || "") + "\n";
    }
  }

  return parser;
};

/* an opt is what's specified by the user in opts hash */
Opt = function(opt) {
  var strings = (opt.string || "").split(","),
      abbr, full, metavar;
  for (var i = 0; i < strings.length; i++) {
    var string = strings[i].trim(),
        matches;
    if (matches = string.match(/^\-([^-])(?:\s+(.*))?$/)) {
      abbr = matches[1];
      metavar = matches[2];
    }
    else if(matches = string.match(/^\-\-(.+?)(?:[=\s]+(.+))?$/)) {
      full = matches[1];
      metavar = metavar || matches[2];
    }
  }

  matches = matches || [];
  var abbr = opt.abbr || abbr,   // e.g. v from -v
      full = opt.full || full, // e.g. verbose from --verbose
      metavar = opt.metavar || metavar;  // e.g. PATH from '--config=PATH'
      expectsValue = opt.expectsValue || metavar || opt.default;

  var string;
  if(opt.string) {
    string = opt.string;
  }
  else if (opt.position === undefined) {
    string= "";
    if(abbr) {
      string += "-" + abbr;
      if(metavar)
        string += " " + metavar
      string += ", ";
    }
    string += "--" + (full || opt.name);
    if(metavar)
      string += " " + metavar;
  }

  opt = _(opt).extend({
    name: opt.name || full || abbr,
    string: string,
    abbr: abbr,
    full: full,
    metavar: metavar,
    matches: function(arg) {
      return opt.full == arg || opt.abbr == arg || opt.position == arg
        || opt.name == arg || (opt.list && arg >= opt.position);
    },
    expectsValue: expectsValue
  });
  return opt;
}

/* an arg is an item that's actually parsed from the command line
   e.g. "-l", "log.txt", or "--logfile=log.txt" */
Arg = function(str) {
  var abbrRegex = /^\-(\w+?)$/,
      fullRegex = /^\-\-(no\-)?(.+?)(?:=(.+))?$/,
      valRegex = /^[^\-].*/;

  var charMatch = abbrRegex.exec(str),
      chars = charMatch && charMatch[1].split("");

  var fullMatch = fullRegex.exec(str),
      full = fullMatch && fullMatch[2];

  var isValue = str !== undefined && (str === "" || valRegex.test(str)),
      value;
  if(isValue)
    value = str;
  else if(full)
    value = fullMatch[1] ? false : fullMatch[3];

  return {
    str: str,
    chars: chars,
    full: full,
    value: value,
    isValue: isValue
  }
}
<|endoftext|>


<commit_before>'use strict';

const dbConnector = require('./databaseConnector');
const dbDefaults = require('./config/dbPopDefaults');
const logger = require('./logger.js');
const appConfig = require('./config/appConfig');

const messageSort = function(a, b) {
  if (a.time < b.time) {
    return -1;
  } else if (a.time > b.time) {
    return 1;
  }

  return 0;
};

function getUserById(socketId, callback) {
  dbConnector.getUserById(socketId, function(err, user) {
    callback(err, user);
  });
}

function getCommand(commandName, callback) {
  dbConnector.getCommand(commandName, function(err, command) {
    callback(err, command);
  });
}

function userAllowedCommand(socketId, commandName, callback) {
  let isAllowed = false;
  const callbackFunc = function(err, user) {
    if (err) {
      callback(err);
    } else {
      getCommand(commandName, function(cmdErr, command) {
        if (cmdErr) {
          callback(cmdErr);
        } else {
          const userLevel = user ? user.accessLevel : 0;
          const commandLevel = command.accessLevel;

          if (userLevel >= commandLevel) {
            isAllowed = true;
          }
        }

        callback(cmdErr, isAllowed, user);
      });
    }
  };

  getUserById(socketId, callbackFunc);
}

/**
 *
 * @param {array} rooms History from these rooms will retrieved
 * @param {int} lines Amount of lines returned for each room
 * @param {boolean} missedMsgs If true, only messages that the user missed since last login are sent
 * @param {date} lastOnline Last time user was online. Used to determine which missed messages to send
 * @param {function} callback Callback
 * @returns {undefined} Returns undefined
 */
function getHistory(rooms, lines, missedMsgs, lastOnline, callback) {
  dbConnector.getHistoryFromRooms(rooms, function(err, history) {
    const historyMessages = [];

    if (err || history === null) {
      logger.sendErrorMsg(logger.ErrorCodes.db, 'Failed to get history', err);
    } else {
      const maxLines = lines === null || isNaN(lines) ? appConfig.historyLines : lines;

      for (let i = 0; i < history.length; i++) {
        const currentHistory = history[i];

        if (currentHistory.messages.length > 0) {
          const messages = currentHistory.messages.slice(-maxLines);
          const messageLength = messages.length - 1;

          for (let j = messageLength; j !== 0; j--) {
            const message = messages[j];

            /*
             * Pushes all the messages from the room OR only the messages that the user hasn't already seen
             */
            if (!missedMsgs || (message !== undefined && lastOnline <= message.time)) {
              message.roomName = currentHistory.roomName;
              historyMessages.push(message);
            }
          }
        }
      }

      // Above loop pushes in everything in the reverse order.
      historyMessages.reverse();
      historyMessages.sort(messageSort);
    }

    callback(err, historyMessages);
  });
}

/**
 *
 * @param {object} newRoom Room name to create
 * @param {object} user User who added the room
 * @param {function} callback Callback
 * @returns {undefined} Returns undefined
 */
function createRoom(newRoom, user, callback) {
  newRoom.roomName = newRoom.roomName.toLowerCase();

  dbConnector.createRoom(newRoom, null, function(err, room) {
    if (err || room === null) {
      logger.sendErrorMsg(logger.ErrorCodes.db, 'Failed to create room for user ' + user.userName, err);
      callback(err);
    } else {
      dbConnector.addRoomToUser(user.userName, room.roomName, function(roomErr) {
        if (roomErr) {
          logger.sendErrorMsg(logger.ErrorCodes.db, 'Failed to add user ' + user.userName + ' to its room', roomErr);
        }

        callback(roomErr, room.roomName);
      });
    }
  });
}

function updateUserSocketId(socketId, userName, callback) {
  dbConnector.updateUserSocketId(userName, socketId, function(err, user) {
    if (err) {
      logger.sendErrorMsg(logger.ErrorCodes.db, 'Failed to update Id', err);
    }

    callback(err, user);
  });
}

function joinRooms(rooms, socket, device) {
  const allRooms = rooms;

  allRooms.push(dbDefaults.rooms.important.roomName);
  allRooms.push(dbDefaults.rooms.broadcast.roomName);

  if (device) {
    allRooms.push(device + dbDefaults.device);
  }

  for (let i = 0; i < allRooms.length; i++) {
    const room = allRooms[i];

    socket.join(room);
  }
}

exports.userAllowedCommand = userAllowedCommand;
exports.getHistory = getHistory;
exports.createRoom = createRoom;
exports.updateUserSocketId = updateUserSocketId;
exports.joinRooms = joinRooms;
<commit_msg>Maxlines in history is on all history, not per room<commit_after>'use strict';

const dbConnector = require('./databaseConnector');
const dbDefaults = require('./config/dbPopDefaults');
const logger = require('./logger.js');
const appConfig = require('./config/appConfig');

const messageSort = function(a, b) {
  if (a.time < b.time) {
    return -1;
  } else if (a.time > b.time) {
    return 1;
  }

  return 0;
};

function getUserById(socketId, callback) {
  dbConnector.getUserById(socketId, function(err, user) {
    callback(err, user);
  });
}

function getCommand(commandName, callback) {
  dbConnector.getCommand(commandName, function(err, command) {
    callback(err, command);
  });
}

function userAllowedCommand(socketId, commandName, callback) {
  let isAllowed = false;
  const callbackFunc = function(err, user) {
    if (err) {
      callback(err);
    } else {
      getCommand(commandName, function(cmdErr, command) {
        if (cmdErr) {
          callback(cmdErr);
        } else {
          const userLevel = user ? user.accessLevel : 0;
          const commandLevel = command.accessLevel;

          if (userLevel >= commandLevel) {
            isAllowed = true;
          }
        }

        callback(cmdErr, isAllowed, user);
      });
    }
  };

  getUserById(socketId, callbackFunc);
}

/**
 *
 * @param {array} rooms History from these rooms will retrieved
 * @param {int} lines Amount of lines returned for each room
 * @param {boolean} missedMsgs If true, only messages that the user missed since last login are sent
 * @param {date} lastOnline Last time user was online. Used to determine which missed messages to send
 * @param {function} callback Callback
 * @returns {undefined} Returns undefined
 */
function getHistory(rooms, lines, missedMsgs, lastOnline, callback) {
  dbConnector.getHistoryFromRooms(rooms, function(err, history) {
    const historyMessages = [];

    if (err || history === null) {
      logger.sendErrorMsg(logger.ErrorCodes.db, 'Failed to get history', err);
    } else {
      const maxLines = lines === null || isNaN(lines) ? appConfig.historyLines : lines;

      for (let i = 0; i < history.length; i++) {
        historyMessages = historyMessages.concat(history[i].messages);
      }

      historyMessages.sort(messageSort);
      historyMessages = historyMessages.slice(-maxLines);

      if (missedMsgs) {
        for (let i = historyMessages.length - 1; 0 < i; i--) {
          const message = historyMessages[i];

          if (lastOnline > message.time) {
            historyMessages = historyMessages.slice(i + 1);

            break;
          }
        }
      }
    }

    callback(err, historyMessages);
  });
}

/**
 *
 * @param {object} newRoom Room name to create
 * @param {object} user User who added the room
 * @param {function} callback Callback
 * @returns {undefined} Returns undefined
 */
function createRoom(newRoom, user, callback) {
  newRoom.roomName = newRoom.roomName.toLowerCase();

  dbConnector.createRoom(newRoom, null, function(err, room) {
    if (err || room === null) {
      logger.sendErrorMsg(logger.ErrorCodes.db, 'Failed to create room for user ' + user.userName, err);
      callback(err);
    } else {
      dbConnector.addRoomToUser(user.userName, room.roomName, function(roomErr) {
        if (roomErr) {
          logger.sendErrorMsg(logger.ErrorCodes.db, 'Failed to add user ' + user.userName + ' to its room', roomErr);
        }

        callback(roomErr, room.roomName);
      });
    }
  });
}

function updateUserSocketId(socketId, userName, callback) {
  dbConnector.updateUserSocketId(userName, socketId, function(err, user) {
    if (err) {
      logger.sendErrorMsg(logger.ErrorCodes.db, 'Failed to update Id', err);
    }

    callback(err, user);
  });
}

function joinRooms(rooms, socket, device) {
  const allRooms = rooms;

  allRooms.push(dbDefaults.rooms.important.roomName);
  allRooms.push(dbDefaults.rooms.broadcast.roomName);

  if (device) {
    allRooms.push(device + dbDefaults.device);
  }

  for (let i = 0; i < allRooms.length; i++) {
    const room = allRooms[i];

    socket.join(room);
  }
}

exports.userAllowedCommand = userAllowedCommand;
exports.getHistory = getHistory;
exports.createRoom = createRoom;
exports.updateUserSocketId = updateUserSocketId;
exports.joinRooms = joinRooms;
<|endoftext|>


<commit_before>const fs = require("fs");
var jsonfile = require('jsonfile')
var Discord = require("discord.js");
var bot = new Discord.Client();

bot.on("message", msg => {
  // Set the prefix
  let prefix = "!";
  // Exit and stop if it's not there
  if(!msg.content.startsWith(prefix)) return;
  // Exit if any bot
  if(msg.author.bot) return;

  if (msg.content.startsWith(prefix + "ping")) {
    msg.channel.sendMessage("pong!");
  }

  else if (msg.content.startsWith(prefix + "foo")) {
    msg.channel.sendMessage("bar!");
  }

});

// ===========================================================
// ПРОСТЫЕ ОТВЕТЫ

bot.on('message', function(message) {

      if (((message.content.indexOf('расскажи') > -1) || (message.content.indexOf('напомни') > -1)) && ((message.content.indexOf('про') > -1) || (message.content.indexOf('правил') > -1)) &&(message.content.indexOf('игр') > -1) && (message.author.username != "Нормаль")){
           message.channel.sendMessage("Всё просто. Как образованная крыса, которая не смогла найти работу по специальности, я сижу на палубе ровно, грустно вздыхаю и подсчитываю все ваши сообщения. За каждые 100 сообщений вы получите от меня уровень и памятную дырку в моем платочке. Меня всегда можно спросить о прогрессе, если вдруг кого-то это будет волновать ~~(8:>");
      }

      if (((message.content.indexOf('отвали') > -1)
            ||(message.content.indexOf('заткнись') > -1)
            ||(message.content.indexOf('убейся') > -1)
            ||(message.content.indexOf('заткнись') > -1)
            ) && (message.author.username != "Нормаль")){
           message.channel.sendMessage("фу, как грубо! Не надо так! >:[");
      }

});

bot.on('message', function(message) {
    if(message.author.bot) return;
    var msg = message.content.toLowerCase();

    for (var i = 0; i < brain.counters.length; i++) {
            var counter = brain.counters[i];
            var regex = counter.ask;
            regex = counter.ask.replace("*", "(.*)");
            //console.log(regex,' -> ', msg.match(regex));
            //console.log(msg.match(regex) != null);
            if (msg.match(regex) && counter.ask != "")
            {
                var k = getRandomInt(0,counter.responses.length);
                var response = counter.responses[k];
                console.dir(counter.ask);
                console.log(regex);
                console.dir(response);
                message.channel.sendMessage(response.answer);
                return;
            }
        }

});

// ===========================================================
// КАНАЛ ДЛЯ ОБУЧЕНИЯ
//let brain = JSON.parse(fs.readFileSync('ratBrain', 'utf8'));
var ratBrain = 'ratBrain.json'
var brain = jsonfile.readFileSync(ratBrain);

bot.on("message", message => {
    if(message.author.bot) return;
    if (message.channel.name == 'traintherat' || message.channel.name == 'trum_s_krysoj' ){
        console.log("обучаюсь!");

        if (message.content == "покажи мозг")
        {
            var test = JSON.stringify(brain);
            test = test.replace(new RegExp('"ask":"","responses":[(.*)]', 'i'), '\n');
            test = test.replace(new RegExp('{', 'g'), '\n');
            test = test.replace(new RegExp('}', 'g'), '\n');

            message.channel.sendMessage('```'+test+'```');
            return;
        }
        var text = message.content.toLowerCase();
        console.log('try to teach: ', text);
        try {
                JSON.parse(message.content, (key, value) => {
                    for (var i = 0; i < brain.counters.length; i++) {
                        var counter = brain.counters[i];
                        if (counter.ask == key)
                        {
                            console.log('here it is!');
                            for (var j = 0; j < counter.responses.length; j++) {
                                var answer = counter.responses[j];
                                if (answer.answer == value)
                                {
                                    return;
                                }
                            }
                            counter.responses.push({"num":counter.responses.length, "answer":value});
                            fs.writeFile(ratBrain, JSON.stringify(brain), console.error);
                            message.channel.sendMessage('вроде запомнила');
                            return;
                        }
                    }
                    brain.counters.push({"ask":key, "responses":[{"num":1,"answer":value}]});
                    fs.writeFile(ratBrain, JSON.stringify(brain), console.error);
                    message.channel.sendMessage('вроде запомнила');
                });
        }
        catch (e) {
            console.log('ERROR',e);
            if (e != null)
        //the json is not ok
            message.channel.sendMessage('это я не буду запоминать ><');
        }

    }
});

// ===========================================================
// ПРИВЕТСТВИЕ
bot.on("guildMemberAdd", (member) => {
    console.log(`Новый пират "${member.user.username}" пожаловал на "${member.guild.name}"` );
    member.guild.defaultChannel.sendMessage(`Хэй, команда, у нас тут новенький! Приветствуйте "${member.user.username}"`);
});

// ===========================================================
// ИГРА

let points = JSON.parse(fs.readFileSync('points.json', 'utf8'));
console.log(points);
const prefix = "+";
const prefix_g = "~";

bot.on("message", message => {
  if(message.content.startsWith(prefix)) return;
  if(message.author.bot) return;

  let userData = points[message.author.id];
  if(!userData) {
      userData = {points: 0, level: 0};
      points[message.author.id] = userData;
    }
    console.log('UD: ',userData);
  userData.points++;

  let curLevel = Math.floor(userData.points/100); //(0.1 * Math.sqrt(userData.points));
  if(curLevel > userData.level) {
    // Level up!
    userData.level = curLevel;
    message.reply(`апнул **${curLevel}** уровень!`);
    var i = getRandomInt(1,5);
    if (i == 1)
        message.channel.sendMessage("*машет платочком*");
        else if (i == 2)
            message.channel.sendMessage("*утирает слёзы счастья*");
        else if (i == 3)
            message.channel.sendMessage("*дырявит платочек*");
        else if (i == 4)
            message.channel.sendMessage("*скромно уползает*");
  }

  if ((
       (message.content.indexOf('уровень') > -1)
       ||(message.content.indexOf('лвл') > -1)
       ||(message.content.indexOf('левел') > -1)
  ) && (message.author.username != "Нормаль")
  || message.content.startsWith(prefix_g + "level")){
      message.reply(`У тебя сейчас ${userData.level} уровень и ${userData.points} очков.`);
    var i = getRandomInt(1,5);
    if (i == 1)
        message.channel.sendMessage("*недовольно уползает*");
        else if (i == 2)
            message.channel.sendMessage("*сердито уползает*");
        else if (i == 3)
            message.channel.sendMessage("*уползает кряхтя*");
        else if (i == 4)
            message.channel.sendMessage("*бубнит что-то себе под нос и скрывается между бочками с ромом*");
  }

  fs.writeFile('./points', JSON.stringify(points), console.error);
});

// ============================================================
// ============================================================
// ============================================================
// ============================================================
// ============================================================
bot.on('error', e => { console.error(e); });

bot.on("ready", () => {
    console.log(`Ready to server in ${bot.channels.size} channels on ${bot.guilds.size} servers, for a total of ${bot.users.size} users.`);
});

bot.on('message', function(message) {
        if (message.channel.isPrivate) {
                console.log('PM: \t', message.author.username, ':\t' ,message.content);
        } else {
                console.log('MSG: \t', ':\t',message.channel.name, '\t->\t', message.author.username, ':\t',message.content);
        }
});

bot.login("MjYxNTE4ODQwMjY4MDYyNzIw.Cz2GEQ._wEEjADIcFPCHJ1A98ZVoxuyHvk");

// ============================================================
// ============================================================
// ============================================================
// ============================================================
// ============================================================

function getRandomInt(min, max) {
  return Math.floor(Math.random() * (max - min)) + min;
}
<commit_msg>added server starting<commit_after>const fs = require("fs");
var jsonfile = require('jsonfile')
var Discord = require("discord.js");
var bot = new Discord.Client();

var http = require('http');

http.createServer(function (request, response) {
  console.log('Creating server...');
}).listen(5000);

console.log('Server running at http://127.0.0.1:5000/');

bot.on("message", msg => {
  // Set the prefix
  let prefix = "!";
  // Exit and stop if it's not there
  if(!msg.content.startsWith(prefix)) return;
  // Exit if any bot
  if(msg.author.bot) return;

  if (msg.content.startsWith(prefix + "ping")) {
    msg.channel.sendMessage("pong!");
  }

  else if (msg.content.startsWith(prefix + "foo")) {
    msg.channel.sendMessage("bar!");
  }

});

// ===========================================================
// ПРОСТЫЕ ОТВЕТЫ

bot.on('message', function(message) {

      if (((message.content.indexOf('расскажи') > -1) || (message.content.indexOf('напомни') > -1)) && ((message.content.indexOf('про') > -1) || (message.content.indexOf('правил') > -1)) &&(message.content.indexOf('игр') > -1) && (message.author.username != "Нормаль")){
           message.channel.sendMessage("Всё просто. Как образованная крыса, которая не смогла найти работу по специальности, я сижу на палубе ровно, грустно вздыхаю и подсчитываю все ваши сообщения. За каждые 100 сообщений вы получите от меня уровень и памятную дырку в моем платочке. Меня всегда можно спросить о прогрессе, если вдруг кого-то это будет волновать ~~(8:>");
      }

      if (((message.content.indexOf('отвали') > -1)
            ||(message.content.indexOf('заткнись') > -1)
            ||(message.content.indexOf('убейся') > -1)
            ||(message.content.indexOf('заткнись') > -1)
            ) && (message.author.username != "Нормаль")){
           message.channel.sendMessage("фу, как грубо! Не надо так! >:[");
      }

});

bot.on('message', function(message) {
    if(message.author.bot) return;
    var msg = message.content.toLowerCase();

    for (var i = 0; i < brain.counters.length; i++) {
            var counter = brain.counters[i];
            var regex = counter.ask;
            regex = counter.ask.replace("*", "(.*)");
            //console.log(regex,' -> ', msg.match(regex));
            //console.log(msg.match(regex) != null);
            if (msg.match(regex) && counter.ask != "")
            {
                var k = getRandomInt(0,counter.responses.length);
                var response = counter.responses[k];
                console.dir(counter.ask);
                console.log(regex);
                console.dir(response);
                message.channel.sendMessage(response.answer);
                return;
            }
        }

});

// ===========================================================
// КАНАЛ ДЛЯ ОБУЧЕНИЯ
//let brain = JSON.parse(fs.readFileSync('ratBrain', 'utf8'));
var ratBrain = 'ratBrain.json'
var brain = jsonfile.readFileSync(ratBrain);

bot.on("message", message => {
    if(message.author.bot) return;
    if (message.channel.name == 'traintherat' || message.channel.name == 'trum_s_krysoj' ){
        console.log("обучаюсь!");

        if (message.content == "покажи мозг")
        {
            var test = JSON.stringify(brain);
            test = test.replace(new RegExp('"ask":"","responses":[(.*)]', 'i'), '\n');
            test = test.replace(new RegExp('{', 'g'), '\n');
            test = test.replace(new RegExp('}', 'g'), '\n');

            message.channel.sendMessage('```'+test+'```');
            return;
        }
        var text = message.content.toLowerCase();
        console.log('try to teach: ', text);
        try {
                JSON.parse(message.content, (key, value) => {
                    for (var i = 0; i < brain.counters.length; i++) {
                        var counter = brain.counters[i];
                        if (counter.ask == key)
                        {
                            console.log('here it is!');
                            for (var j = 0; j < counter.responses.length; j++) {
                                var answer = counter.responses[j];
                                if (answer.answer == value)
                                {
                                    return;
                                }
                            }
                            counter.responses.push({"num":counter.responses.length, "answer":value});
                            fs.writeFile(ratBrain, JSON.stringify(brain), console.error);
                            message.channel.sendMessage('вроде запомнила');
                            return;
                        }
                    }
                    brain.counters.push({"ask":key, "responses":[{"num":1,"answer":value}]});
                    fs.writeFile(ratBrain, JSON.stringify(brain), console.error);
                    message.channel.sendMessage('вроде запомнила');
                });
        }
        catch (e) {
            console.log('ERROR',e);
            if (e != null)
        //the json is not ok
            message.channel.sendMessage('это я не буду запоминать ><');
        }

    }
});

// ===========================================================
// ПРИВЕТСТВИЕ
bot.on("guildMemberAdd", (member) => {
    console.log(`Новый пират "${member.user.username}" пожаловал на "${member.guild.name}"` );
    member.guild.defaultChannel.sendMessage(`Хэй, команда, у нас тут новенький! Приветствуйте "${member.user.username}"`);
});

// ===========================================================
// ИГРА

let points = JSON.parse(fs.readFileSync('points.json', 'utf8'));
console.log(points);
const prefix = "+";
const prefix_g = "~";

bot.on("message", message => {
  if(message.content.startsWith(prefix)) return;
  if(message.author.bot) return;

  let userData = points[message.author.id];
  if(!userData) {
      userData = {points: 0, level: 0};
      points[message.author.id] = userData;
    }
    console.log('UD: ',userData);
  userData.points++;

  let curLevel = Math.floor(userData.points/100); //(0.1 * Math.sqrt(userData.points));
  if(curLevel > userData.level) {
    // Level up!
    userData.level = curLevel;
    message.reply(`апнул **${curLevel}** уровень!`);
    var i = getRandomInt(1,5);
    if (i == 1)
        message.channel.sendMessage("*машет платочком*");
        else if (i == 2)
            message.channel.sendMessage("*утирает слёзы счастья*");
        else if (i == 3)
            message.channel.sendMessage("*дырявит платочек*");
        else if (i == 4)
            message.channel.sendMessage("*скромно уползает*");
  }

  if ((
       (message.content.indexOf('уровень') > -1)
       ||(message.content.indexOf('лвл') > -1)
       ||(message.content.indexOf('левел') > -1)
  ) && (message.author.username != "Нормаль")
  || message.content.startsWith(prefix_g + "level")){
      message.reply(`У тебя сейчас ${userData.level} уровень и ${userData.points} очков.`);
    var i = getRandomInt(1,5);
    if (i == 1)
        message.channel.sendMessage("*недовольно уползает*");
        else if (i == 2)
            message.channel.sendMessage("*сердито уползает*");
        else if (i == 3)
            message.channel.sendMessage("*уползает кряхтя*");
        else if (i == 4)
            message.channel.sendMessage("*бубнит что-то себе под нос и скрывается между бочками с ромом*");
  }

  fs.writeFile('./points', JSON.stringify(points), console.error);
});

// ============================================================
// ============================================================
// ============================================================
// ============================================================
// ============================================================
bot.on('error', e => { console.error(e); });

bot.on("ready", () => {
    console.log(`Ready to server in ${bot.channels.size} channels on ${bot.guilds.size} servers, for a total of ${bot.users.size} users.`);
});

bot.on('message', function(message) {
        if (message.channel.isPrivate) {
                console.log('PM: \t', message.author.username, ':\t' ,message.content);
        } else {
                console.log('MSG: \t', ':\t',message.channel.name, '\t->\t', message.author.username, ':\t',message.content);
        }
});

bot.login("MjYxNTE4ODQwMjY4MDYyNzIw.Cz2GEQ._wEEjADIcFPCHJ1A98ZVoxuyHvk");

// ============================================================
// ============================================================
// ============================================================
// ============================================================
// ============================================================

function getRandomInt(min, max) {
  return Math.floor(Math.random() * (max - min)) + min;
}
<|endoftext|>


<commit_before>const fs = require('fs');
const path = require('path');
const config = require('./config');
const moment = require('moment');
const spawn = require('child_process').spawn;
const Promise = require('bluebird');
const AWS = require('aws-sdk');
AWS.config.loadFromPath(path.join(__dirname,'aws-creds.json'));
const s3 = new AWS.S3();

function Picture(){

  this.filepath;
  this.keyname;
  this.url;

  this.getUrl = function(expires){
    expires = expires ? expires : 60;
    var params = {Bucket: config.aws_s3_bucket, Key: this.keyname, Expires: expires};
    this.url = s3.getSignedUrl('getObject', params);
  	return this.url;
  }
}

var captureProc = null;
function takePicture() {
  return new Promise(function(resolve){

    if(captureProc != null) {
      captureProc.kill();
      captureProc = null;
	  }

    var date = moment.utc();
    var datestr = date.format('YYYYMMDDHHmmss');
    var filename = datestr+".jpg";
    var filepath = path.join(config.capture_dir, filename);
    var keyname = date.format("YYYY/MM/DD/") + filename;
    var args = ["-awb", "auto", "-ex", "auto", "-w", config.capture_width, "-h", config.capture_height, "-vf", "-o", filepath];

    console.info(keyname + "\tcapture started")
    captureProc = spawn('raspistill', args);
    console.info(keyname + "\tcapture complete")

    var picture = new Picture();
    picture.filepath = filepath;
    picture.keyname = keyname;

    captureProc.on('close', function(code){
      resolve(picture);
	  });
  });
}

function uploadPicture(picture) {
  return new Promise(function(resolve, reject){
    fs.readFile(picture.filepath, function(err, data) {
      if(err) throw err;

      var s3bucket = new AWS.S3({params: {Bucket: config.aws_s3_bucket }});
      var params = {
        Key: picture.keyname,
        Body: data
      };

      console.info(picture.keyname + "\tupload started");
      s3bucket.upload(params, function (err, data) {
        if (err) {
        	reject(err);
        } else {
          console.info(picture.keyname + "\tupload complete");
          resolve(picture);
        }
      });
	  });
  });
}

function deleteFile(picture) {
  return new Promise(function(resolve, reject){
    fs.unlink(picture.filepath, function(err){
      if (err) throw err;
      console.info(picture.keyname + "\tdeleted local file\t" + picture.filepath);
      resolve(picture);
    });
  });
}

function capture(){
  takePicture()
    .then(uploadPicture)
    .then(deleteFile)
    .then(function(picture){
      console.info(picture.keyname + "\turl created\t" + picture.getUrl(60));
    });
}

var interval;
var pid_path = path.join(__dirname,'pilapse.pid');

function start(){
  fs.readFile(pid_path, function(err, data){
    if (!err) {

      throw new Error('Process '+ data +' already running from '+pid_path);

    } else {

      var pid = String(process.pid);
      fs.writeFile(pid_path, pid, function(err) {
        if (err) throw err;
      });

      console.info("process\tstarting timelapse\t" + config.capture_frequency + " seconds");

      capture(); // take picture on start
      interval = setInterval(function(){
        capture();
      }, config.capture_frequency * 1000)

    }
  });
}

function stop(){

  fs.unlink(pid_path, function(err){
    if (err) throw err;
  });

  if(interval) clearInterval(interval);
  console.info("process\thalting timelapse");
}

// MAIN :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

start();
process.on('SIGTERM', stop);
process.on('SIGINT', stop);
<commit_msg>Fun with comments<commit_after>const fs = require('fs');
const path = require('path');
const config = require('./config');
const moment = require('moment');
const spawn = require('child_process').spawn;
const Promise = require('bluebird');
const AWS = require('aws-sdk');
AWS.config.loadFromPath(path.join(__dirname,'aws-creds.json'));
const s3 = new AWS.S3();

function Picture(){

  this.filepath;
  this.keyname;
  this.url;

  this.getUrl = function(expires){
    expires = expires ? expires : 60;
    var params = {Bucket: config.aws_s3_bucket, Key: this.keyname, Expires: expires};
    this.url = s3.getSignedUrl('getObject', params);
  	return this.url;
  }
}

var captureProc = null;
function takePicture() {
  return new Promise(function(resolve){

    if(captureProc != null) {
      captureProc.kill();
      captureProc = null;
	  }

    var date = moment.utc();
    var datestr = date.format('YYYYMMDDHHmmss');
    var filename = datestr+".jpg";
    var filepath = path.join(config.capture_dir, filename);
    var keyname = date.format("YYYY/MM/DD/") + filename;
    var args = ["-awb", "auto", "-ex", "auto", "-w", config.capture_width, "-h", config.capture_height, "-vf", "-o", filepath];

    console.info(keyname + "\tcapture started")
    captureProc = spawn('raspistill', args);
    console.info(keyname + "\tcapture complete")

    var picture = new Picture();
    picture.filepath = filepath;
    picture.keyname = keyname;

    captureProc.on('close', function(code){
      resolve(picture);
	  });
  });
}

function uploadPicture(picture) {
  return new Promise(function(resolve, reject){
    fs.readFile(picture.filepath, function(err, data) {
      if(err) throw err;

      var s3bucket = new AWS.S3({params: {Bucket: config.aws_s3_bucket }});
      var params = {
        Key: picture.keyname,
        Body: data
      };

      console.info(picture.keyname + "\tupload started");
      s3bucket.upload(params, function (err, data) {
        if (err) {
        	reject(err);
        } else {
          console.info(picture.keyname + "\tupload complete");
          resolve(picture);
        }
      });
	  });
  });
}

function deleteFile(picture) {
  return new Promise(function(resolve, reject){
    fs.unlink(picture.filepath, function(err){
      if (err) throw err;
      console.info(picture.keyname + "\tdeleted local file\t" + picture.filepath);
      resolve(picture);
    });
  });
}

function capture(){
  takePicture()
    .then(uploadPicture)
    .then(deleteFile)
    .then(function(picture){
      console.info(picture.keyname + "\turl created\t" + picture.getUrl(60));
    });
}

var interval;
var pid_path = path.join(__dirname,'pilapse.pid');

function start(){
  fs.readFile(pid_path, function(err, data){
    if (!err) {

      throw new Error('Process '+ data +' already running from '+pid_path);

    } else {

      var pid = String(process.pid);
      fs.writeFile(pid_path, pid, function(err) {
        if (err) throw err;
      });

      console.info("process\tstarting timelapse\t" + config.capture_frequency + " seconds");

      capture(); // take picture on start
      interval = setInterval(function(){
        capture();
      }, config.capture_frequency * 1000)

    }
  });
}

function stop(){

  fs.unlink(pid_path, function(err){
    if (err) throw err;
  });

  if(interval) clearInterval(interval);
  console.info("process\thalting timelapse");
}

// MAIN :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

// Let's get this party started, right?

start();
process.on('SIGTERM', stop);
process.on('SIGINT', stop);
<|endoftext|>


<commit_before>function Mancala() {
  // public constants
  this.BOARD = [ 2, 2, 2, 2 ];

  // public variables
  this.board = JSON.parse(JSON.stringify(this.BOARD));

  // private variables
  var half = Math.ceil(this.board.length / 2);

  // private functions
  this.divider = function() {
    var div = "-----".split(""),
        len = (half - 1) * 4 + 5;

    while(div.length < len) {
      div.push("-");
    }

    return div.join("");
  };

  this.topHalf = function() {
    var div = "|".split("");

    for (var i = 0; i < half; i++) {
      div.push(" ");
      div.push(this.board[i]);
      div.push(" |");
    }

    return div.join("");
  };

  this.bottomHalf = function() {
    var div = "|".split(""),
        len = this.board.length;

    for (var i = len - 1; i >= half; i--) {
      div.push(" ");
      div.push(this.board[i]);
      div.push(" |");
    }

    return div.join("");
  };

  this.firstInt = function(args) {
    var index = args[0];

    function isInt(value) {
      return !isNaN(value) && (function (x) { return (x | 0) === x; }) (parseFloat(value));
    }

    if (!isInt(index)) {
      console.error("error: invalid input");
      this.exit();
    }

    return index;
  };

  this.over = function() {
    var empties,
        i,
        len = this.board.length;

    for (empties = 0, i = 0; i < half; i++) {
      if (this.board[i] === 0) {
        empties++;
      }
    }
    if (empties === half) { console.log("game over"); return true; }

    for (empties = 0, i = half; i < len; i++) {
      if (this.board[i] === 0) {
        empties++;
      }
    }
    if (empties === half) { console.log("game over"); return true; }

    return false;
  };

  this.countermove = function() {
    var move = -1,
        len = this.board.length,
        utility = -1 * 2 * len;

    for (var i = half; i < len; i++) {
      if (this.board[i] !== 0 && (move === -1 || this.utility(i) > utility)) {
        move = i;
      }
    }

    this.distribute(move);
    return true;
  };

  this.distribute = function(index) {
    var marbles = this.board[index],
        len = this.board.length;

    this.board[index] = 0;
    while (marbles > 0) {
      this.board[(++index) % len]++;
      marbles--;
    }
  };

  this.utility = function(move) {
    var simulate = JSON.parse(JSON.stringify(this.board)),
        utility = 0,
        len = this.board.length;

    this.distribute([move]);

    for (utility = 0, i = half; i < len; i++) {
      utility += this.board[i];
    }

    this.board = JSON.parse(JSON.stringify(simulate));

    return utility;
  };
}

// public functions
Mancala.prototype.play = function(input) {
  var map = {
    all: function() { this.all("my"); }.bind(this),
    move: function() { this.move(args); }.bind(this),
    print: function() { this.print(); }.bind(this),
    reset: function() { this.reset(); }.bind(this),
    exit: function() { this.exit(); }.bind(this)
  };

  var args = input.split(" ");
  command = args.shift();

  if (map.hasOwnProperty(command)) {
    map[command](args);
  } else {
    console.error("error: invalid input");
  }
};

Mancala.prototype.all = function(player) {
  var simulate = JSON.parse(JSON.stringify(this.board)),
      half = Math.ceil(simulate.length / 2),
      empties = 0,
      moves = [];

  for (var i = 0; i < half; i++) {
    if (player === "their") { _i = i + half; } else { _i = i; }
    if (simulate[_i] !== 0) {
      moves.push(_i);
    }
  }

  var len = moves.length;
  for (var j = 0; j < moves.length; j++) {
    console.log("Testing " + player + " move. (" + moves[j] + ")");
    this.move([moves[j]]);
    this.print();

    if (this.over()) {
      continue;
    } else {
      return (this.all(player === "their" ? "my" : "their"));
    }
  }
};

Mancala.prototype.reset = function() {
  this.board = JSON.parse(JSON.stringify(this.BOARD));
};

Mancala.prototype.move = function(args) {
  var index = this.firstInt(args),
      len = this.board.length;

  if (this.board[index] === 0 || index >= len) {
    console.error("error: invalid move");
    return false;
  }

  this.distribute(index);

  if (this.over()) {
    this.print();
    this.exit();
  }

  this.print();

  console.log("opponents move");
  this.countermove();
  return true;
};

Mancala.prototype.print = function() {
  console.log(this.divider());
  console.log(this.topHalf());
  console.log(this.divider());
  console.log(this.bottomHalf());
  console.log(this.divider());
};

Mancala.prototype.exit = function() {
  process.exit(0);
};

module.exports = Mancala;
<commit_msg>Use distribute in place of move. Constrain moves to your side.<commit_after>function Mancala() {
  // public constants
  this.BOARD = [ 2, 2, 2, 2 ];

  // public variables
  this.board = JSON.parse(JSON.stringify(this.BOARD));

  // private variables
  var half = Math.ceil(this.board.length / 2);

  // private functions
  this.divider = function() {
    var div = "-----".split(""),
        len = (half - 1) * 4 + 5;

    while(div.length < len) {
      div.push("-");
    }

    return div.join("");
  };

  this.topHalf = function() {
    var div = "|".split("");

    for (var i = 0; i < half; i++) {
      div.push(" ");
      div.push(this.board[i]);
      div.push(" |");
    }

    return div.join("");
  };

  this.bottomHalf = function() {
    var div = "|".split(""),
        len = this.board.length;

    for (var i = len - 1; i >= half; i--) {
      div.push(" ");
      div.push(this.board[i]);
      div.push(" |");
    }

    return div.join("");
  };

  this.firstInt = function(args) {
    var index = args[0];

    function isInt(value) {
      return !isNaN(value) && (function (x) { return (x | 0) === x; }) (parseFloat(value));
    }

    if (!isInt(index)) {
      console.error("error: invalid input");
      this.exit();
    }

    return index;
  };

  this.over = function() {
    var empties,
        i,
        len = this.board.length;

    for (empties = 0, i = 0; i < half; i++) {
      if (this.board[i] === 0) {
        empties++;
      }
    }
    if (empties === half) { console.log("game over"); return true; }

    for (empties = 0, i = half; i < len; i++) {
      if (this.board[i] === 0) {
        empties++;
      }
    }
    if (empties === half) { console.log("game over"); return true; }

    return false;
  };

  this.countermove = function() {
    var move = -1,
        len = this.board.length,
        utility = -1 * 2 * len;

    for (var i = half; i < len; i++) {
      if (this.board[i] !== 0 && (move === -1 || this.utility(i) > utility)) {
        move = i;
      }
    }

    this.distribute(move);
    return true;
  };

  this.distribute = function(index) {
    var marbles = this.board[index],
        len = this.board.length;

    this.board[index] = 0;
    while (marbles > 0) {
      this.board[(++index) % len]++;
      marbles--;
    }
  };

  this.utility = function(move) {
    var simulate = JSON.parse(JSON.stringify(this.board)),
        utility = 0,
        len = this.board.length;

    this.distribute([move]);

    for (utility = 0, i = half; i < len; i++) {
      utility += this.board[i];
    }

    this.board = JSON.parse(JSON.stringify(simulate));

    return utility;
  };
}

// public functions
Mancala.prototype.play = function(input) {
  var map = {
    all: function() { this.all("my"); }.bind(this),
    move: function() { this.move(args); }.bind(this),
    print: function() { this.print(); }.bind(this),
    reset: function() { this.reset(); }.bind(this),
    exit: function() { this.exit(); }.bind(this)
  };

  var args = input.split(" ");
  command = args.shift();

  if (map.hasOwnProperty(command)) {
    map[command](args);
  } else {
    console.error("error: invalid input");
  }
};

Mancala.prototype.all = function(player) {
  var simulate = JSON.parse(JSON.stringify(this.board)),
      half = Math.ceil(simulate.length / 2),
      empties = 0,
      moves = [];

  for (var i = 0; i < half; i++) {
    if (player === "their") { _i = i + half; } else { _i = i; }
    if (simulate[_i] !== 0) {
      moves.push(_i);
    }
  }

  var len = moves.length;
  for (var j = 0; j < moves.length; j++) {
    console.log("Testing " + player + " move. (" + moves[j] + ")");
    this.distribute(moves[j]);
    this.print();

    if (this.over()) {
      continue;
    } else {
      return (this.all(player === "their" ? "my" : "their"));
    }
  }
};

Mancala.prototype.reset = function() {
  this.board = JSON.parse(JSON.stringify(this.BOARD));
};

Mancala.prototype.move = function(args) {
  var index = this.firstInt(args),
      len = this.board.length,
      half = Math.ceil(this.board.length / 2);

  if (this.board[index] === 0 || index >= half) {
    console.error("error: invalid move");
    return false;
  }

  this.distribute(index);

  if (this.over()) {
    this.print();
    this.exit();
  }

  this.print();

  console.log("opponents move");
  this.countermove();
  return true;
};

Mancala.prototype.print = function() {
  console.log(this.divider());
  console.log(this.topHalf());
  console.log(this.divider());
  console.log(this.bottomHalf());
  console.log(this.divider());
};

Mancala.prototype.exit = function() {
  process.exit(0);
};

module.exports = Mancala;
<|endoftext|>


<commit_before>/**
 * Tw2RenderTarget
 * @property {Tw2TextureRes} texture
 * @property {WebglFrameBuffer} _frameBuffer
 * @property {WebglRenderBuffer} _renderBuffer
 * @property {number} width - width of the resulting texture
 * @property {number} height - height of the resulting texture
 * @property {boolean} hasDepth - Controls whether depth is considered when creating the webgl buffers
 * @constructor
 */
function Tw2RenderTarget()
{
    this.texture = null;
    this._frameBuffer = null;
    this._renderBuffer = null;
    this.width = null;
    this.height = null;
    this.hasDepth = null;
}

/**
 * Destroys the render target's webgl buffers and textures
 * @prototype
 */
Tw2RenderTarget.prototype.Destroy = function()
{
    if (this.texture)
    {
        device.gl.deleteTexture(this.texture.texture);
        this.texture = null;
    }
    if (this._renderBuffer)
    {
        device.gl.deleteRenderbuffer(this._renderBuffer);
        this._renderBuffer = null;
    }
    if (this._frameBuffer)
    {
        device.gl.deleteFramebuffer(this._frameBuffer);
        this._frameBuffer = null;
    }
};

/**
 * Creates the render target
 * @param {number} width
 * @param {number} height
 * @param {boolean} hasDepth
 * @prototype
 */
Tw2RenderTarget.prototype.Create = function(width, height, hasDepth)
{
    this.Destroy();
    this.texture = new Tw2TextureRes();
    this.texture.Attach(device.gl.createTexture());

    this._frameBuffer = device.gl.createFramebuffer();
    device.gl.bindFramebuffer(device.gl.FRAMEBUFFER, this._frameBuffer);

    device.gl.bindTexture(device.gl.TEXTURE_2D, this.texture.texture);
    device.gl.texImage2D(device.gl.TEXTURE_2D, 0, device.gl.RGBA, width, height, 0, device.gl.RGBA, device.gl.UNSIGNED_BYTE, null);
    device.gl.texParameteri(device.gl.TEXTURE_2D, device.gl.TEXTURE_MAG_FILTER, device.gl.LINEAR);
    device.gl.texParameteri(device.gl.TEXTURE_2D, device.gl.TEXTURE_MIN_FILTER, device.gl.LINEAR);
    device.gl.bindTexture(device.gl.TEXTURE_2D, null);

    this._renderBuffer = null;
    if (hasDepth)
    {
        this._renderBuffer = device.gl.createRenderbuffer();
        device.gl.bindRenderbuffer(device.gl.RENDERBUFFER, this._renderBuffer);
        device.gl.renderbufferStorage(device.gl.RENDERBUFFER, device.gl.DEPTH_COMPONENT16, width, height);
    }

    device.gl.framebufferTexture2D(device.gl.FRAMEBUFFER, device.gl.COLOR_ATTACHMENT0, device.gl.TEXTURE_2D, this.texture.texture, 0);
    if (hasDepth)
    {
        device.gl.framebufferRenderbuffer(device.gl.FRAMEBUFFER, device.gl.DEPTH_ATTACHMENT, device.gl.RENDERBUFFER, this._renderBuffer);
    }
    device.gl.bindRenderbuffer(device.gl.RENDERBUFFER, null);
    device.gl.bindFramebuffer(device.gl.FRAMEBUFFER, null);

    this.width = width;
    this.height = height;
    this.hasDepth = hasDepth;
};

/**
 * Sets the render target as the current frame buffer
 * @prototype
 */
Tw2RenderTarget.prototype.Set = function()
{
    device.gl.bindFramebuffer(device.gl.FRAMEBUFFER, this._frameBuffer);
    device.gl.viewport(0, 0, this.width, this.height);
};

/**
 * Unsets the render target as the current frame buffer
 * @prototype
 */
Tw2RenderTarget.prototype.Unset = function()
{
    device.gl.bindFramebuffer(device.gl.FRAMEBUFFER, null);
    device.gl.viewport(0, 0, device.viewportWidth, device.viewportHeight);
};
<commit_msg>Minor update to Tw2RenderTarget<commit_after>/**
 * Tw2RenderTarget
 * @property {Tw2TextureRes} texture
 * @property {WebglFrameBuffer} _frameBuffer
 * @property {WebglRenderBuffer} _renderBuffer
 * @property {number} width - width of the resulting texture
 * @property {number} height - height of the resulting texture
 * @property {boolean} hasDepth - Controls whether depth is considered when creating the webgl buffers
 * @constructor
 */
function Tw2RenderTarget()
{
    this.texture = null;
    this._frameBuffer = null;
    this._renderBuffer = null;
    this.width = null;
    this.height = null;
    this.hasDepth = null;
}

/**
 * Destroys the render target's webgl buffers and textures
 * @prototype
 */
Tw2RenderTarget.prototype.Destroy = function()
{
    if (this.texture)
    {
        device.gl.deleteTexture(this.texture.texture);
        this.texture = null;
    }
    if (this._renderBuffer)
    {
        device.gl.deleteRenderbuffer(this._renderBuffer);
        this._renderBuffer = null;
    }
    if (this._frameBuffer)
    {
        device.gl.deleteFramebuffer(this._frameBuffer);
        this._frameBuffer = null;
    }
};

/**
 * Creates the render target's texture
 * @param {number} width     - The resulting texture's width
 * @param {number} height    - The resulting texture's height
 * @param {boolean} hasDepth - Optional flag to enable a depth buffer
 * @prototype
 */
Tw2RenderTarget.prototype.Create = function(width, height, hasDepth)
{
    this.Destroy();
    this.texture = new Tw2TextureRes();
    this.texture.Attach(device.gl.createTexture());

    this._frameBuffer = device.gl.createFramebuffer();
    device.gl.bindFramebuffer(device.gl.FRAMEBUFFER, this._frameBuffer);

    device.gl.bindTexture(device.gl.TEXTURE_2D, this.texture.texture);
    device.gl.texImage2D(device.gl.TEXTURE_2D, 0, device.gl.RGBA, width, height, 0, device.gl.RGBA, device.gl.UNSIGNED_BYTE, null);
    device.gl.texParameteri(device.gl.TEXTURE_2D, device.gl.TEXTURE_MAG_FILTER, device.gl.LINEAR);
    device.gl.texParameteri(device.gl.TEXTURE_2D, device.gl.TEXTURE_MIN_FILTER, device.gl.LINEAR);
    device.gl.bindTexture(device.gl.TEXTURE_2D, null);

    this._renderBuffer = null;

    if (hasDepth)
    {
        this._renderBuffer = device.gl.createRenderbuffer();
        device.gl.bindRenderbuffer(device.gl.RENDERBUFFER, this._renderBuffer);
        device.gl.renderbufferStorage(device.gl.RENDERBUFFER, device.gl.DEPTH_COMPONENT16, width, height);
    }

    device.gl.framebufferTexture2D(device.gl.FRAMEBUFFER, device.gl.COLOR_ATTACHMENT0, device.gl.TEXTURE_2D, this.texture.texture, 0);

    if (hasDepth)
    {
        device.gl.framebufferRenderbuffer(device.gl.FRAMEBUFFER, device.gl.DEPTH_ATTACHMENT, device.gl.RENDERBUFFER, this._renderBuffer);
    }

    device.gl.bindRenderbuffer(device.gl.RENDERBUFFER, null);
    device.gl.bindFramebuffer(device.gl.FRAMEBUFFER, null);

    this.texture.width = this.width = width;
    this.texture.height = this.height = height;
    this.hasDepth = hasDepth;
};

/**
 * Sets the render target as the current frame buffer
 * @prototype
 */
Tw2RenderTarget.prototype.Set = function()
{
    device.gl.bindFramebuffer(device.gl.FRAMEBUFFER, this._frameBuffer);
    device.gl.viewport(0, 0, this.width, this.height);
};

/**
 * Unsets the render target as the current frame buffer
 * @prototype
 */
Tw2RenderTarget.prototype.Unset = function()
{
    device.gl.bindFramebuffer(device.gl.FRAMEBUFFER, null);
    device.gl.viewport(0, 0, device.viewportWidth, device.viewportHeight);
};
<|endoftext|>


<commit_before>/*
 * Author: Alex Gibson
 * https://github.com/alexgibson/notify.js
 * License: MIT license
 */

(function(global, factory) {
    'use strict';

    if (typeof define === 'function' && define.amd) {
        // AMD environment
        define(function() {
            return factory(global, global.document);
        });
    } else if (typeof module !== 'undefined' && module.exports) {
        // CommonJS environment
        module.exports = factory(global, global.document);
    } else {
        // Browser environment
        global.Notify = factory(global, global.document);
    }
} (typeof window !== 'undefined' ? window : this, function (w, d) {
    'use strict';

    function isFunction(item) {
        return typeof item === 'function';
    }

    function Notify(title, options) {

        if (typeof title !== 'string') {
            throw new Error('Notify(): first arg (title) must be a string.');
        }

        this.title = title;

        this.options = {
            icon: '',
            body: '',
            tag: '',
            lang: 'en',
            notifyShow: null,
            notifyClose: null,
            notifyClick: null,
            notifyError: null,
            timeout: null
        };

        this.permission = null;

        //User defined options for notification content
        if (typeof options === 'object') {

            for (var i in options) {
                if (options.hasOwnProperty(i)) {
                    this.options[i] = options[i];
                }
            }

            //callback when notification is displayed
            if (isFunction(this.options.notifyShow)) {
                this.onShowCallback = this.options.notifyShow;
            }

            //callback when notification is closed
            if (isFunction(this.options.notifyClose)) {
                this.onCloseCallback = this.options.notifyClose;
            }

            //callback when notification is clicked
            if (isFunction(this.options.notifyClick)) {
                this.onClickCallback = this.options.notifyClick;
            }

            //callback when notification throws error
            if (isFunction(this.options.notifyError)) {
                this.onErrorCallback = this.options.notifyError;
            }
        }
    }

    // returns true if the browser supports Web Notifications
    // https://developers.google.com/web/updates/2015/05/Notifying-you-of-notificiation-changes
    // @param {perm} for test purposes only
    Notify.isSupported = function(perm) {
        if (!window.Notification || !Notification.requestPermission) {
            return false;
        }

        if (perm === 'granted' || Notification.permission === 'granted') {
            throw new Error('You must only call this before calling Notification.requestPermission(), otherwise this feature detect would trigger an actual notification!');
        }

        try {
            new Notification('');
        } catch (e) {
            if (e.name === 'TypeError') {
                return false;
            }
        }
        return true;
    };

    // true if the permission is not granted
    Notify.needsPermission = (Notification.permission === 'granted') ? false : true;

    // asks the user for permission to display notifications.  Then calls the callback functions is supplied.
    Notify.requestPermission = function(onPermissionGrantedCallback, onPermissionDeniedCallback) {
        w.Notification.requestPermission(function(perm) {
            switch (perm) {
                case 'granted':
                    Notify.needsPermission = false;
                    if (isFunction(onPermissionGrantedCallback)) {
                        onPermissionGrantedCallback();
                    }
                    break;
                case 'denied':
                    Notify.needsPermission = true;
                    if (isFunction(onPermissionDeniedCallback)) {
                        onPermissionDeniedCallback();
                    }
                    break;
            }
        });
    };

    Notify.prototype.show = function() {
        this.myNotify = new Notification(this.title, {
            'body': this.options.body,
            'tag' : this.options.tag,
            'icon' : this.options.icon,
            'lang' : this.options.lang
        });

        if (this.options.timeout && !isNaN(this.options.timeout)) {
            setTimeout(this.close.bind(this), this.options.timeout * 1000);
        }

        this.myNotify.addEventListener('show', this, false);
        this.myNotify.addEventListener('error', this, false);
        this.myNotify.addEventListener('close', this, false);
        this.myNotify.addEventListener('click', this, false);
    };

    Notify.prototype.onShowNotification = function(e) {
        if (this.onShowCallback) {
            this.onShowCallback(e);
        }
    };

    Notify.prototype.onCloseNotification = function(e) {
        if (this.onCloseCallback) {
            this.onCloseCallback(e);
        }
        this.destroy();
    };

    Notify.prototype.onClickNotification = function(e) {
        if (this.onClickCallback) {
            this.onClickCallback(e);
        }
    };

    Notify.prototype.onErrorNotification = function(e) {
        if (this.onErrorCallback) {
            this.onErrorCallback(e);
        }
        this.destroy();
    };

    Notify.prototype.destroy = function() {
        this.myNotify.removeEventListener('show', this, false);
        this.myNotify.removeEventListener('error', this, false);
        this.myNotify.removeEventListener('close', this, false);
        this.myNotify.removeEventListener('click', this, false);
    };

    Notify.prototype.close = function() {
        this.myNotify.close();
    };

    Notify.prototype.handleEvent = function(e) {
        switch (e.type) {
        case 'show':
            this.onShowNotification(e);
            break;
        case 'close':
            this.onCloseNotification(e);
            break;
        case 'click':
            this.onClickNotification(e);
            break;
        case 'error':
            this.onErrorNotification(e);
            break;
        }
    };

    return Notify;
}));
<commit_msg>Fix for evaluation error on missing variable and undefined property of window<commit_after>/*
 * Author: Alex Gibson
 * https://github.com/alexgibson/notify.js
 * License: MIT license
 */

(function(global, factory) {
    'use strict';

    if (typeof define === 'function' && define.amd) {
        // AMD environment
        define(function() {
            return factory(global, global.document);
        });
    } else if (typeof module !== 'undefined' && module.exports) {
        // CommonJS environment
        module.exports = factory(global, global.document);
    } else {
        // Browser environment
        global.Notify = factory(global, global.document);
    }
} (typeof window !== 'undefined' ? window : this, function (w, d) {
    'use strict';

    var N = w.Notification;

    function isFunction(item) {
        return typeof item === 'function';
    }

    function Notify(title, options) {

        if (typeof title !== 'string') {
            throw new Error('Notify(): first arg (title) must be a string.');
        }

        this.title = title;

        this.options = {
            icon: '',
            body: '',
            tag: '',
            lang: 'en',
            notifyShow: null,
            notifyClose: null,
            notifyClick: null,
            notifyError: null,
            timeout: null
        };

        this.permission = null;

        //User defined options for notification content
        if (typeof options === 'object') {

            for (var i in options) {
                if (options.hasOwnProperty(i)) {
                    this.options[i] = options[i];
                }
            }

            //callback when notification is displayed
            if (isFunction(this.options.notifyShow)) {
                this.onShowCallback = this.options.notifyShow;
            }

            //callback when notification is closed
            if (isFunction(this.options.notifyClose)) {
                this.onCloseCallback = this.options.notifyClose;
            }

            //callback when notification is clicked
            if (isFunction(this.options.notifyClick)) {
                this.onClickCallback = this.options.notifyClick;
            }

            //callback when notification throws error
            if (isFunction(this.options.notifyError)) {
                this.onErrorCallback = this.options.notifyError;
            }
        }
    }

    // returns true if the browser supports Web Notifications
    // https://developers.google.com/web/updates/2015/05/Notifying-you-of-notificiation-changes
    // @param {perm} for test purposes only
    Notify.isSupported = function(perm) {
        if (!N || !N.requestPermission) {
            return false;
        }

        if (perm === 'granted' || N.permission === 'granted') {
            throw new Error('You must only call this before calling Notification.requestPermission(), otherwise this feature detect would trigger an actual notification!');
        }

        try {
            new N('');
        } catch (e) {
            if (e.name === 'TypeError') {
                return false;
            }
        }
        return true;
    };

    // true if the permission is not granted
    Notify.needsPermission = (N.permission && N.permission === 'granted') ? false : true;

    // asks the user for permission to display notifications.  Then calls the callback functions is supplied.
    Notify.requestPermission = function(onPermissionGrantedCallback, onPermissionDeniedCallback) {
        N.requestPermission(function(perm) {
            switch (perm) {
                case 'granted':
                    Notify.needsPermission = false;
                    if (isFunction(onPermissionGrantedCallback)) {
                        onPermissionGrantedCallback();
                    }
                    break;
                case 'denied':
                    Notify.needsPermission = true;
                    if (isFunction(onPermissionDeniedCallback)) {
                        onPermissionDeniedCallback();
                    }
                    break;
            }
        });
    };

    Notify.prototype.show = function() {
        this.myNotify = new N(this.title, {
            'body': this.options.body,
            'tag' : this.options.tag,
            'icon' : this.options.icon,
            'lang' : this.options.lang
        });

        if (this.options.timeout && !isNaN(this.options.timeout)) {
            setTimeout(this.close.bind(this), this.options.timeout * 1000);
        }

        this.myNotify.addEventListener('show', this, false);
        this.myNotify.addEventListener('error', this, false);
        this.myNotify.addEventListener('close', this, false);
        this.myNotify.addEventListener('click', this, false);
    };

    Notify.prototype.onShowNotification = function(e) {
        if (this.onShowCallback) {
            this.onShowCallback(e);
        }
    };

    Notify.prototype.onCloseNotification = function(e) {
        if (this.onCloseCallback) {
            this.onCloseCallback(e);
        }
        this.destroy();
    };

    Notify.prototype.onClickNotification = function(e) {
        if (this.onClickCallback) {
            this.onClickCallback(e);
        }
    };

    Notify.prototype.onErrorNotification = function(e) {
        if (this.onErrorCallback) {
            this.onErrorCallback(e);
        }
        this.destroy();
    };

    Notify.prototype.destroy = function() {
        this.myNotify.removeEventListener('show', this, false);
        this.myNotify.removeEventListener('error', this, false);
        this.myNotify.removeEventListener('close', this, false);
        this.myNotify.removeEventListener('click', this, false);
    };

    Notify.prototype.close = function() {
        this.myNotify.close();
    };

    Notify.prototype.handleEvent = function(e) {
        switch (e.type) {
        case 'show':
            this.onShowNotification(e);
            break;
        case 'close':
            this.onCloseNotification(e);
            break;
        case 'click':
            this.onClickNotification(e);
            break;
        case 'error':
            this.onErrorNotification(e);
            break;
        }
    };

    return Notify;
}));
<|endoftext|>


<commit_before>
import React, { PropTypes } from 'react';
import Add from '../../components/Add';
import MessageFormContents from './MessageFormContents';
import MessagePreview from './MessagePreview';

const MessageAdd = (props) => {
  const { location: { query } } = props;
  return (
    <Add category="messages" FormContents={MessageFormContents}
      Preview={MessagePreview} showable={true} title="Add Message"
      default={{ libraryId: query.libraryId }} />
  );
};

MessageAdd.propTypes = {
  location: PropTypes.shape({
    query: PropTypes.shape({
      libraryId: PropTypes.string,
    }),
  }).isRequired,
};

export default MessageAdd;
<commit_msg>Fixed an issue with MessageAdd.<commit_after>
import React, { PropTypes } from 'react';
import Add from '../../components/Add';
import { searchToObject } from '../../utils/Params';
import MessageFormContents from './MessageFormContents';
import MessagePreview from './MessagePreview';

const MessageAdd = (props) => {
  const { location } = props;
  const query = searchToObject(location.search);
  return (
    <Add category="messages" FormContents={MessageFormContents}
      Preview={MessagePreview} showable={true} title="Add Message"
      default={{ libraryId: query.libraryId }} />
  );
};

MessageAdd.propTypes = {
  location: PropTypes.object.isRequired,
};

export default MessageAdd;
<|endoftext|>


<commit_before>// app.controller("UsersLoginCtrl", [$scope, $rootScope, AUTH_EVENTS, AuthService, function () {
//   $scope.credentials = {
//     username: "",
//     password: "",
//   };

//   $scope.login = function (credentials) {
//     AuthService.login(credentials).then(function (user) {
//       $rootScope.$broadcast(AUTH_EVENTS.loginSuccess);
//       $scope.setCurrentUser(user);
//     }, function () {
//       $rootScope.$broadcast(AUTH_EVENTS.loginFailed);
//     });
//   };

// }]);
app.controller("UsersLoginCtrl", function ($scope, $http, $routeParams) {
  $scope.credentials = {
    user_id: "",
    password: ""
  };

  console.log("DO SOME ");
  $scope.usersLogin = function (){
    console.log('trying to usersLogin');
    // Janky place to store user info & auth
    $scope.session = {}
    $http.post('api/users/login', {
      user_id: $scope.credentials.user_id
    }).
    success(function(data){
      console.log('able to usersLogin')
      $scope.session.user = data
      $scope.session.display = ("Hi, " + data.name)
      console.log($scope.session.user)
    }).
    error(function(data){
      console.log('unable to usersLogin')
      $scope.session.display = "no such user :("
    });
  };
  // $scope.message = "hilo"
  // $scope.login = function (credentials) {
  //   AuthService.login(credentials).then(function (user) {
  //     // $rootScope.$broadcast(AUTH_EVENTS.loginSuccess);
  //     $scope.setCurrentUser(user);
  //   }, function () {
  //     // $rootScope.$broadcast(AUTH_EVENTS.loginFailed);
  //   });
  // };

});
<commit_msg>added password authentication (no salt / encryption yet tho) for login -- still need to make users login by their username / email<commit_after>// app.controller("UsersLoginCtrl", [$scope, $rootScope, AUTH_EVENTS, AuthService, function () {
//   $scope.credentials = {
//     username: "",
//     password: "",
//   };

//   $scope.login = function (credentials) {
//     AuthService.login(credentials).then(function (user) {
//       $rootScope.$broadcast(AUTH_EVENTS.loginSuccess);
//       $scope.setCurrentUser(user);
//     }, function () {
//       $rootScope.$broadcast(AUTH_EVENTS.loginFailed);
//     });
//   };

// }]);
app.controller("UsersLoginCtrl", function ($scope, $http, $routeParams) {
  $scope.credentials = {
    user_id: "",
    password: ""
  };

  console.log("DO SOME ");
  $scope.usersLogin = function (){
    console.log('trying to usersLogin');
    // Janky place to store user info & auth
    $scope.session = {}

    // Submit credentials to database
    $http.post('api/users/login', {
      user_id: $scope.credentials.user_id,
      password: $scope.credentials.password
    }).
    success(function(data){
      console.log('able to usersLogin')
      $scope.session.user = data
      $scope.session.display = ("Hi, " + data.name)
      console.log($scope.session.user)
    }).
    error(function(data){
      console.log('unable to usersLogin')
      $scope.session.display = "something went wrong :("
    });
  };
  // $scope.message = "hilo"
  // $scope.login = function (credentials) {
  //   AuthService.login(credentials).then(function (user) {
  //     // $rootScope.$broadcast(AUTH_EVENTS.loginSuccess);
  //     $scope.setCurrentUser(user);
  //   }, function () {
  //     // $rootScope.$broadcast(AUTH_EVENTS.loginFailed);
  //   });
  // };

});
<|endoftext|>