<commit_before>// Implements miscellaneous functions on the bot object.

var utils = require("./utils");
var https = require("https");
var model = require("./model");

function initMisc() {
  this.fileGet = fileGet;
  this.fileLink = fileLink;
  this.fileStream = fileStream;
  this.fileLoad = fileLoad;
  this.getChat = getChat;
  this.getProfilePhotos = getProfilePhotos;
  this.kickMember = kickMember;
  this.unbanMember = unbanMember;
  this.leaveChat = leaveChat;
  this.getChatAdministrators = getChatAdministrators;
  this.getChatMembersCount = getChatMembersCount;
  this.getChatMember = getChatMember;
  this.linkGame = linkGame;
  this.setGameScore = setGameScore;
  this.getGameHighScores = getGameHighScores;
  this.link = link;
  this.linkGroup = linkGroup;
  this.formatCommand = formatCommand;
}

// File download

function fileGet(file, cb) {
  // Undocumented feature: sometimes the file_path property may be
  // given to you without having to call getFile [again].
  if (file instanceof model.File && file.path) return cb(null, file);

  this.callMethod("getFile", {file_id: model.resolveFile(file)}, function (err, result) {
    if (err) return cb(err);
    cb(null, new model.File().parse(result, this.options));
  }.bind(this));
}

function fileLink(path) {
  if (path instanceof model.File) path = path.path;
  return "https://api.telegram.org/file/bot" + this.authToken + "/" + path;
}

function fileStream(file, cb) {
  this.fileGet(file, function (err, info, link) {
    if (err) return cb(err);
    https.get(this.fileLink(info), function (res) {
      cb(null, res);
    }).on("error", cb);
  }.bind(this));
}

function fileLoad(file, cb) {
  this.fileStream(file, function (err, stream) {
    if (err) return cb(err);
    var chunks = [];
    stream.on("error", cb);
    stream.on("readable", function () {
      var chunk = stream.read();
      if (chunk) chunks.push(chunk);
    });
    stream.on("end", function () {
      cb(null, Buffer.concat(chunks));
    });
  }.bind(this));
}

// Chat management

function getChat(chat, cb) { //TODO: propagate options
  if (utils.isStr(chat)) {
    if (chat[0] !== "@") chat = "@" + chat;
  } else {
    chat = model.resolveChat(chat);
  }
  this.callMethod("getChat", {chat_id: chat}, function (err, result) {
    if (err) return cb(err);
    cb(null, new model.Chat().parse(result, this.options));
  }.bind(this));
}

function getProfilePhotos(user, range, cb) {
  if (arguments.length === 2) cb = range, range = null;

  var parameters = {user_id: model.resolveChat(user)};
  if (range) {
    utils.checkArr(range);
    if (range[1] < 1 || range[1] > 100) throw new Error("Invalid photo range");
    parameters.offset = utils.checkInt(range[0]);
    parameters.limit = utils.checkInt(range[1]);
  }
  this.callMethod("getUserProfilePhotos", parameters, function (err, result) {
    if (err) return cb(err);

    utils.checkObj(result);

    var photos = utils.checkArr(result.photos);
    delete result.photos;
    photos = photos.map(function (photo) {
      return model.parsePhoto.call({}, photo, this.options);
    }.bind(this));

    photos.total = utils.checkInt(result.total_count);
    delete result.total_count;

    utils.verifyEmpty(result, this.options);
    cb(null, photos);
  }.bind(this));
}

function kickMember(chat, user, cb) {
  this.callMethod("kickChatMember", {chat_id: model.resolveChat(chat), user_id: model.resolveChat(user)}, function (err, result) {
    if (err) return cb(err);
    if (result !== true) return cb(new Error("Expected true, found " + result));
    cb();
  }.bind(this));
}

function unbanMember(chat, user, cb) {
  this.callMethod("unbanChatMember", {chat_id: model.resolveChat(chat), user_id: model.resolveChat(user)}, function (err, result) {
    if (err) return cb(err);
    if (result !== true) return cb(new Error("Expected true, found " + result));
    cb();
  }.bind(this));
}

function leaveChat(chat, cb) {
  this.callMethod("leaveChat", {chat_id: model.resolveChat(chat)}, function (err, result) {
    if (err) return cb(err);
    if (result !== true) return cb(new Error("Expected true, found " + result));
    cb();
  }.bind(this));
}

function getChatAdministrators(chat, cb) {
  this.callMethod("getChatAdministrators", {chat_id: model.resolveChat(chat)}, function (err, result) {
    if (err) return cb(err);
    var members = utils.checkArr(result).map(function (member) {
      return new model.ChatMember().parse(member, this.options);
    }.bind(this));
    cb(null, members);
  }.bind(this));
}

function getChatMembersCount(chat, cb) {
  this.callMethod("getChatMembersCount", {chat_id: model.resolveChat(chat)}, function (err, result) {
    if (err) return cb(err);
    cb(null, utils.checkInt(result));
  }.bind(this));
}

function getChatMember(chat, user, cb) {
  this.callMethod("getChatMember", {chat_id: model.resolveChat(chat), user_id: model.resolveChat(user)}, function (err, result) {
    if (err) return cb(err);
    cb(null, new model.ChatMember().parse(result, this.options));
  }.bind(this));
}

// Gaming

function linkGame(gameShortName) {
  return this.link({ game: gameShortName });
}

function setGameScore(user, score, options, cb) {
  var parameters = {
    user_id: model.resolveChat(user),
    score: utils.checkInt(score),
    disable_edit_message: options.disableEditMessage,
    force: options.force,
  };
  if (options.chat)
    parameters.chat_id = model.resolveChat(options.chat);
  if (options.message) {
    if (utils.isStr(options.message))
      parameters.inline_message_id = options.message;
    else
      parameters.message_id = model.resolveMessage(options.message);
  }
  this.callMethod("setGameScore", parameters, function (err, result) {
    if (err) return cb(err);
    if (parameters.message_id) result = new model.Message().parse(result, this.options);
    cb(null, result);
  }.bind(this));
}

function getGameHighScores(user, options, cb) {
  var parameters = {
    user_id: model.resolveChat(user),
  };
  if (options.chat)
    parameters.chat_id = model.resolveChat(options.chat);
  if (options.message) {
    if (utils.isStr(options.message))
      parameters.inline_message_id = options.message;
    else
      parameters.message_id = model.resolveMessage(options.message);
  }
  this.callMethod("getGameHighScores", parameters, function (err, result) {
    if (err) return cb(err);
    result = utils.checkArr(result).map(function (highScore) {
      return new model.GameHighScore().parse(highScore);
    });
    cb(null, result);
  }.bind(this));
}

// Other

function _link(options) {
  if (!this.get("username")) throw new Error("Username still not available");
  var link = "https://" + (options.old ? "telegram.me" : "t.me") + "/" + this.get("username");
  if (options.payload !== undefined) {
    if (!/^[A-Za-z0-9_-]+$/.test(options.payload))
      throw new Error("Payload contains invalid characters");
    link += "?start" + (options.group ? "group" : "") + "=" + options.payload;
  } else if (options.game !== undefined) {
    if (!/^[a-zA-Z0-9_]{3,30}$/.test(options.game))
      throw new Error("Game short name contains invalid characters");
    link += "?game=" + options.game;
  }
  return link;
}

function link(options, group) {
  if (utils.isStr(options)) options = { payload: options };
  if (!options) options = {};
  if (group) options.group = group;
  return _link.call(this, options);
}

function linkGroup(options) {
  return this.link(options, true);
}

function formatCommand(username, command, args) {
  if (username === true) {
    if (!this.get("username")) throw new Error("Username still not available");
    username = this.get("username");
  }
  if (!(args instanceof Array))
    args = [].slice.call(arguments, 2);
  if (username) username = username.toString();

  return model.formatCommand(username, command, args);
}

exports.initMisc = initMisc;
<commit_msg>misc: Add until parameter to kickMember<commit_after>// Implements miscellaneous functions on the bot object.

var utils = require("./utils");
var https = require("https");
var model = require("./model");

function initMisc() {
  this.fileGet = fileGet;
  this.fileLink = fileLink;
  this.fileStream = fileStream;
  this.fileLoad = fileLoad;
  this.getChat = getChat;
  this.getProfilePhotos = getProfilePhotos;
  this.kickMember = kickMember;
  this.unbanMember = unbanMember;
  this.leaveChat = leaveChat;
  this.getChatAdministrators = getChatAdministrators;
  this.getChatMembersCount = getChatMembersCount;
  this.getChatMember = getChatMember;
  this.linkGame = linkGame;
  this.setGameScore = setGameScore;
  this.getGameHighScores = getGameHighScores;
  this.link = link;
  this.linkGroup = linkGroup;
  this.formatCommand = formatCommand;
}

// File download

function fileGet(file, cb) {
  // Undocumented feature: sometimes the file_path property may be
  // given to you without having to call getFile [again].
  if (file instanceof model.File && file.path) return cb(null, file);

  this.callMethod("getFile", {file_id: model.resolveFile(file)}, function (err, result) {
    if (err) return cb(err);
    cb(null, new model.File().parse(result, this.options));
  }.bind(this));
}

function fileLink(path) {
  if (path instanceof model.File) path = path.path;
  return "https://api.telegram.org/file/bot" + this.authToken + "/" + path;
}

function fileStream(file, cb) {
  this.fileGet(file, function (err, info, link) {
    if (err) return cb(err);
    https.get(this.fileLink(info), function (res) {
      cb(null, res);
    }).on("error", cb);
  }.bind(this));
}

function fileLoad(file, cb) {
  this.fileStream(file, function (err, stream) {
    if (err) return cb(err);
    var chunks = [];
    stream.on("error", cb);
    stream.on("readable", function () {
      var chunk = stream.read();
      if (chunk) chunks.push(chunk);
    });
    stream.on("end", function () {
      cb(null, Buffer.concat(chunks));
    });
  }.bind(this));
}

// Chat management

function getChat(chat, cb) { //TODO: propagate options
  if (utils.isStr(chat)) {
    if (chat[0] !== "@") chat = "@" + chat;
  } else {
    chat = model.resolveChat(chat);
  }
  this.callMethod("getChat", {chat_id: chat}, function (err, result) {
    if (err) return cb(err);
    cb(null, new model.Chat().parse(result, this.options));
  }.bind(this));
}

function getProfilePhotos(user, range, cb) {
  if (arguments.length === 2) cb = range, range = null;

  var parameters = {user_id: model.resolveChat(user)};
  if (range) {
    utils.checkArr(range);
    if (range[1] < 1 || range[1] > 100) throw new Error("Invalid photo range");
    parameters.offset = utils.checkInt(range[0]);
    parameters.limit = utils.checkInt(range[1]);
  }
  this.callMethod("getUserProfilePhotos", parameters, function (err, result) {
    if (err) return cb(err);

    utils.checkObj(result);

    var photos = utils.checkArr(result.photos);
    delete result.photos;
    photos = photos.map(function (photo) {
      return model.parsePhoto.call({}, photo, this.options);
    }.bind(this));

    photos.total = utils.checkInt(result.total_count);
    delete result.total_count;

    utils.verifyEmpty(result, this.options);
    cb(null, photos);
  }.bind(this));
}

function kickMember(chat, user, until, cb) {
  if (arguments.length < 4) {
    cb = until;
    until = undefined;
  }

  if (utils.isNum(until))
    until = new Date(Date.now() + until * 1000);

  if (until !== undefined) {
    if (until instanceof Date)
      until = until.getTime() / 1000;
    else
      throw new Error("'until' isn't a valid Date");
  }

  this.callMethod("kickChatMember", {
    chat_id: model.resolveChat(chat),
    user_id: model.resolveChat(user),
    until_date: until,
  }, function (err, result) {
    if (err) return cb(err);
    if (result !== true) return cb(new Error("Expected true, found " + result));
    cb();
  }.bind(this));
}

function unbanMember(chat, user, cb) {
  this.callMethod("unbanChatMember", {chat_id: model.resolveChat(chat), user_id: model.resolveChat(user)}, function (err, result) {
    if (err) return cb(err);
    if (result !== true) return cb(new Error("Expected true, found " + result));
    cb();
  }.bind(this));
}

function leaveChat(chat, cb) {
  this.callMethod("leaveChat", {chat_id: model.resolveChat(chat)}, function (err, result) {
    if (err) return cb(err);
    if (result !== true) return cb(new Error("Expected true, found " + result));
    cb();
  }.bind(this));
}

function getChatAdministrators(chat, cb) {
  this.callMethod("getChatAdministrators", {chat_id: model.resolveChat(chat)}, function (err, result) {
    if (err) return cb(err);
    var members = utils.checkArr(result).map(function (member) {
      return new model.ChatMember().parse(member, this.options);
    }.bind(this));
    cb(null, members);
  }.bind(this));
}

function getChatMembersCount(chat, cb) {
  this.callMethod("getChatMembersCount", {chat_id: model.resolveChat(chat)}, function (err, result) {
    if (err) return cb(err);
    cb(null, utils.checkInt(result));
  }.bind(this));
}

function getChatMember(chat, user, cb) {
  this.callMethod("getChatMember", {chat_id: model.resolveChat(chat), user_id: model.resolveChat(user)}, function (err, result) {
    if (err) return cb(err);
    cb(null, new model.ChatMember().parse(result, this.options));
  }.bind(this));
}

// Gaming

function linkGame(gameShortName) {
  return this.link({ game: gameShortName });
}

function setGameScore(user, score, options, cb) {
  var parameters = {
    user_id: model.resolveChat(user),
    score: utils.checkInt(score),
    disable_edit_message: options.disableEditMessage,
    force: options.force,
  };
  if (options.chat)
    parameters.chat_id = model.resolveChat(options.chat);
  if (options.message) {
    if (utils.isStr(options.message))
      parameters.inline_message_id = options.message;
    else
      parameters.message_id = model.resolveMessage(options.message);
  }
  this.callMethod("setGameScore", parameters, function (err, result) {
    if (err) return cb(err);
    if (parameters.message_id) result = new model.Message().parse(result, this.options);
    cb(null, result);
  }.bind(this));
}

function getGameHighScores(user, options, cb) {
  var parameters = {
    user_id: model.resolveChat(user),
  };
  if (options.chat)
    parameters.chat_id = model.resolveChat(options.chat);
  if (options.message) {
    if (utils.isStr(options.message))
      parameters.inline_message_id = options.message;
    else
      parameters.message_id = model.resolveMessage(options.message);
  }
  this.callMethod("getGameHighScores", parameters, function (err, result) {
    if (err) return cb(err);
    result = utils.checkArr(result).map(function (highScore) {
      return new model.GameHighScore().parse(highScore);
    });
    cb(null, result);
  }.bind(this));
}

// Other

function _link(options) {
  if (!this.get("username")) throw new Error("Username still not available");
  var link = "https://" + (options.old ? "telegram.me" : "t.me") + "/" + this.get("username");
  if (options.payload !== undefined) {
    if (!/^[A-Za-z0-9_-]+$/.test(options.payload))
      throw new Error("Payload contains invalid characters");
    link += "?start" + (options.group ? "group" : "") + "=" + options.payload;
  } else if (options.game !== undefined) {
    if (!/^[a-zA-Z0-9_]{3,30}$/.test(options.game))
      throw new Error("Game short name contains invalid characters");
    link += "?game=" + options.game;
  }
  return link;
}

function link(options, group) {
  if (utils.isStr(options)) options = { payload: options };
  if (!options) options = {};
  if (group) options.group = group;
  return _link.call(this, options);
}

function linkGroup(options) {
  return this.link(options, true);
}

function formatCommand(username, command, args) {
  if (username === true) {
    if (!this.get("username")) throw new Error("Username still not available");
    username = this.get("username");
  }
  if (!(args instanceof Array))
    args = [].slice.call(arguments, 2);
  if (username) username = username.toString();

  return model.formatCommand(username, command, args);
}

exports.initMisc = initMisc;
<|endoftext|>


<commit_before>/*
 * Notes :
 * need to figure out if there is a way to continously check if
 * the alarms sets off.
 */

/**
 * Welcome to Pebble.js!
 * Test
 * This is where you write your app.
 */

// Calls in required stuff
var UI = require('ui');
var Vibe = require('ui/vibe');
var Settings = require('settings');
var Accel = require('ui/accel');
var date = new Date();
//var Vector2 = require('vector2');

// initialize
Accel.init();

var hours = [];
for (var i = 0; i < 24; i++) {
    hours.push(i + 1);
}
var minutes = [];
for (var i = 0; i < 60; i++) {
    minutes.push(i + 1);
}

var hourItems = createTimeItems(hours);
var minutesItems = createTimeItems(minutes);

var minuteChange = new UI.Menu({
    section : [{
        items : minutesItems
    }];

    minuteChange.on('select', function(e) {
        minuteChange.hide();
    });
});

var hourChange = new UI.Menu({
    section : [{
        items : hourItems
    }];

    timeChange.on('select', function(e) {
        hourChange.hide();
        minuteChange.show();
    });
});

var alarms = Settings.data('alarms') || [];
var createAlarmItems = function(alarms) {
    var items = [];
    items.push({
        title: "Add New Alarm"
    });
    console.log("alarm length : " + alarms.length);
    if (alarms.length > 0) {
        for (var i = 0; i < alarms.length; i++) {
            items.push({
                title: alarms[i].time,
                subtitle: alarms[i].enabled
            });
            console.log(i);
        }
    }
    console.log("Created item list");
    return items;
};

var createTimeItems = function(time) {
    var items = [];
    for (var i = 0; i < time.length; i++) {
        items.push({
            title : time[i]
        });
    }
    return items;
};

var detectTimeLoop = function() {
    date = new Date();
	for (var i = 0; i < alarms.length; i++) {

		//console.log("alarm " + alarms[i].hour + "h " + alarms[i].minute + "m");
		//console.log("actual " + date.getHours() + "h  " + date.getMinutes() + "m");

		// break if no longer valid alarm(s)
		if ( !alarms[i].hour || !alarms[i].minute ) { break; }

		if ( alarms[i].enabled && alarms[i].allowVib && alarms[i].hour == date.getHours() && alarms[i].minute == date.getMinutes() ) {

			Vibe.vibrate('long');
			console.log(i + ": I vibrated");

            if ( date.getSeconds() === 0 ) {
				var card = new UI.Card();
				card.title('Alarm');
				card.subtitle('Is going off!');
				card.body('Press \'select\' to turn it off.');
				card.show();

				card.on('click', 'select', function() {
					console.log('Alarm');
					alarms[i].allowVib = false;
					card.hide();
				});

				card.on('accelTap', function(e) {
					console.log('Alarm');
					alarms[i].allowVib = false;
					card.hide();
				});
			}
		} else {
			// else if not going off, make sure to allow vib for next time!
			if ( !alarms[i].allowVib ) {
				alarms[i].allowVib = true;
			}
		}
    }

	setTimeout(function() {
		detectTimeLoop();
	}, 1000);
};

detectTimeLoop();

/*
	Formats time from the 24-hour clock to 12-hour
*/
var formatTime = function( h, m ) {
	var hour = ( h % 12 !== 0 ? h % 12 : 12 );
    var minute = m < 10 ? "0" + m : m;
	return hour + ":" + minute + " " + ( ( h < 12 ) ? "AM" : "PM" );
};

// Sets up the alarms
var alarmItems = createAlarmItems(alarms);

/*
// Creates a loop to make an array of hours
var createHourItems = function() {
  var items = [];
  for (var i = 0; i hideurs.length; i++) {
    items.push({
      title: hours[i]
    });
  }
  return items;
};
*/

/*
var main = new UI.Menu({
   sections:[{
     items: createItems()
  }]
});

main.show();
*/

// The Splashscreen
var splashScreen = new UI.Card({
    title: 'Alarm',
    icon: 'images/menu_icon.png',
    subtitle: 'Welcome to Our App',
    body: 'This is the splash page'
    //banner (future plans)
});

// Makes a menu with New Alarms
var main = new UI.Menu({
    sections: [{
        items: alarmItems
        /*
            [{
            title: 'Add New Alarm',
            subtitle: 'New Alarm'
        }, {
            // Dr. Seuss
            title: 'One Alarm'
        }, {
            title: 'Two Alarm'
        }, {
            title: 'Red Alarm'
        }, {
            title: 'Blue Alarm'
        }]
        */
        //, createAlarmItems(alarms)
    }]
});

// Shows the spashscreen and goes to the menu after 400 ms
splashScreen.show();
setTimeout(function() {
    splashScreen.hide();
    main.show();
}, 800);

var createAlarm = function(callback) {

	date = new Date();

    alarms.push({
        time: formatTime( date.getHours(), date.getMinutes() + 2 ),
        hour: date.getHours(),
        minute: date.getMinutes() + 2,
        enabled: true,
		allowVib: true
    });
    console.log("hour : " + date.getHours());
    console.log("minute : " + date.getMinutes());
    console.log("time : " + formatTime( date.getHours(), date.getMinutes() ));
    callback();
};

main.on('select', function(e) {
    console.log(e.sectionIndex);
    // If it is on the "New Alarm Option"
    if (e.itemIndex === 0) {
        // Has a random card as a placeholder
        var card = new UI.Card();
        card.title('A Card');
        card.subtitle('Is a Window');
        card.body('The simplest window type in Pebble.js.');
        card.show();

        // When click the middle button it makes an alarm
        card.on('click', 'select', function() {
            createAlarm(function() {
                alarmItems = createAlarmItems(alarms);
                console.log('Items done');
                console.log(alarmItems);
                card.hide();
                main.section(0, section = {
                    items: alarmItems
                });
                console.log("success");
                hourChange.show();
            });
        });
    } else {
        // Otherwise the user selects an alarm
        // Creates the Menu for Alarm Options
        var alarmOptions = new UI.Menu({
            sections : [{
                items: [{
                    title: 'Disable'
                }, {
                    title: 'Edit'
                }, {
                    title: 'Delete'
                }]
            }]
        });
        alarmOptions.show();

        alarmOptions.on('select', function(e) {
            switch(e.itemIndex) {
                case 0:
                    // Disable or Enable the Alarm
                    if (e.item.enabled) {
                        e.item.enabled = false;
                    } else {
                        e.item.enabled = true;
                    }
                    break;
                case 1:
                    // Edit the time of the alarm
                    break;
                case 2:
                    // Deletes the alarm
                    alarms.splice(e.itemIndex - 2, 1);
                    console.log("deleted at : " + e.itemIndex - 2);
                    break;
                default:
                    console.log("error");
                    break;
            }
            // Update the alarms and gets rid of the option menu
            console.log('before : ' + alarmItems);
            alarmItems = createAlarmItems(alarms);
            alarmOptions.hide();
            main.section(0, section = {
                items: alarmItems
            });
            //console.log('updated alarms');
            console.log('after : ' + alarmItems);
        });
    }
    // Choose an option to chnage alarm
});

<commit_msg>commented out time related stuff<commit_after>/*
 * Notes :
 * need to figure out if there is a way to continously check if
 * the alarms sets off.
 */

/**
 * Welcome to Pebble.js!
 * Test
 * This is where you write your app.
 */

// Calls in required stuff
var UI = require('ui');
var Vibe = require('ui/vibe');
var Settings = require('settings');
var Accel = require('ui/accel');
var date = new Date();
//var Vector2 = require('vector2');

// initialize
Accel.init();

var hours = [];
for (var i = 0; i < 24; i++) {
    hours.push(i + 1);
}
var minutes = [];
for (var i = 0; i < 60; i++) {
    minutes.push(i + 1);
}

/*
var hourItems = createTimeItems(hours);
var minutesItems = createTimeItems(minutes);

var minuteChange = new UI.Menu({
    section : [{
        items : minutesItems
    }];

    minuteChange.on('select', function(e) {
        minuteChange.hide();
    });
});

var hourChange = new UI.Menu({
    section : [{
        items : hourItems
    }];

    timeChange.on('select', function(e) {
        hourChange.hide();
        minuteChange.show();
    });
});
*/

var alarms = Settings.data('alarms') || [];
var createAlarmItems = function(alarms) {
    var items = [];
    items.push({
        title: "Add New Alarm"
    });
    console.log("alarm length : " + alarms.length);
    if (alarms.length > 0) {
        for (var i = 0; i < alarms.length; i++) {
            items.push({
                title: alarms[i].time,
                subtitle: alarms[i].enabled
            });
            console.log(i);
        }
    }
    console.log("Created item list");
    return items;
};

var createTimeItems = function(time) {
    var items = [];
    for (var i = 0; i < time.length; i++) {
        items.push({
            title : time[i]
        });
    }
    return items;
};

var detectTimeLoop = function() {
    date = new Date();
	for (var i = 0; i < alarms.length; i++) {

		//console.log("alarm " + alarms[i].hour + "h " + alarms[i].minute + "m");
		//console.log("actual " + date.getHours() + "h  " + date.getMinutes() + "m");

		// break if no longer valid alarm(s)
		if ( !alarms[i].hour || !alarms[i].minute ) { break; }

		if ( alarms[i].enabled && alarms[i].allowVib && alarms[i].hour == date.getHours() && alarms[i].minute == date.getMinutes() ) {

			Vibe.vibrate('long');
			console.log(i + ": I vibrated");

            if ( date.getSeconds() === 0 ) {
				var card = new UI.Card();
				card.title('Alarm');
				card.subtitle('Is going off!');
				card.body('Press \'select\' to turn it off.');
				card.show();

				card.on('click', 'select', function() {
					console.log('Alarm');
					alarms[i].allowVib = false;
					card.hide();
				});

				card.on('accelTap', function(e) {
					console.log('Alarm');
					alarms[i].allowVib = false;
					card.hide();
				});
			}
		} else {
			// else if not going off, make sure to allow vib for next time!
			if ( !alarms[i].allowVib ) {
				alarms[i].allowVib = true;
			}
		}
    }

	setTimeout(function() {
		detectTimeLoop();
	}, 1000);
};

detectTimeLoop();

/*
	Formats time from the 24-hour clock to 12-hour
*/
var formatTime = function( h, m ) {
	var hour = ( h % 12 !== 0 ? h % 12 : 12 );
    var minute = m < 10 ? "0" + m : m;
	return hour + ":" + minute + " " + ( ( h < 12 ) ? "AM" : "PM" );
};

// Sets up the alarms
var alarmItems = createAlarmItems(alarms);

/*
// Creates a loop to make an array of hours
var createHourItems = function() {
  var items = [];
  for (var i = 0; i hideurs.length; i++) {
    items.push({
      title: hours[i]
    });
  }
  return items;
};
*/

/*
var main = new UI.Menu({
   sections:[{
     items: createItems()
  }]
});

main.show();
*/

// The Splashscreen
var splashScreen = new UI.Card({
    title: 'Alarm',
    icon: 'images/menu_icon.png',
    subtitle: 'Welcome to Our App',
    body: 'This is the splash page'
    //banner (future plans)
});

// Makes a menu with New Alarms
var main = new UI.Menu({
    sections: [{
        items: alarmItems
        /*
            [{
            title: 'Add New Alarm',
            subtitle: 'New Alarm'
        }, {
            // Dr. Seuss
            title: 'One Alarm'
        }, {
            title: 'Two Alarm'
        }, {
            title: 'Red Alarm'
        }, {
            title: 'Blue Alarm'
        }]
        */
        //, createAlarmItems(alarms)
    }]
});

// Shows the spashscreen and goes to the menu after 400 ms
splashScreen.show();
setTimeout(function() {
    splashScreen.hide();
    main.show();
}, 800);

var createAlarm = function(callback) {

	date = new Date();

    alarms.push({
        time: formatTime( date.getHours(), date.getMinutes() + 2 ),
        hour: date.getHours(),
        minute: date.getMinutes() + 2,
        enabled: true,
		allowVib: true
    });
    console.log("hour : " + date.getHours());
    console.log("minute : " + date.getMinutes());
    console.log("time : " + formatTime( date.getHours(), date.getMinutes() ));
    callback();
};

main.on('select', function(e) {
    console.log(e.sectionIndex);
    // If it is on the "New Alarm Option"
    if (e.itemIndex === 0) {
        // Has a random card as a placeholder
        var card = new UI.Card();
        card.title('A Card');
        card.subtitle('Is a Window');
        card.body('The simplest window type in Pebble.js.');
        card.show();

        // When click the middle button it makes an alarm
        card.on('click', 'select', function() {
            createAlarm(function() {
                alarmItems = createAlarmItems(alarms);
                console.log('Items done');
                console.log(alarmItems);
                card.hide();
                main.section(0, section = {
                    items: alarmItems
                });
                console.log("success");
                //hourChange.show();
            });
        });
    } else {
        // Otherwise the user selects an alarm
        // Creates the Menu for Alarm Options
        var alarmOptions = new UI.Menu({
            sections : [{
                items: [{
                    title: 'Disable'
                }, {
                    title: 'Edit'
                }, {
                    title: 'Delete'
                }]
            }]
        });
        alarmOptions.show();

        alarmOptions.on('select', function(e) {
            switch(e.itemIndex) {
                case 0:
                    // Disable or Enable the Alarm
                    if (e.item.enabled) {
                        e.item.enabled = false;
                    } else {
                        e.item.enabled = true;
                    }
                    break;
                case 1:
                    // Edit the time of the alarm
                    break;
                case 2:
                    // Deletes the alarm
                    alarms.splice(e.itemIndex - 2, 1);
                    console.log("deleted at : " + e.itemIndex - 2);
                    break;
                default:
                    console.log("error");
                    break;
            }
            // Update the alarms and gets rid of the option menu
            console.log('before : ' + alarmItems);
            alarmItems = createAlarmItems(alarms);
            alarmOptions.hide();
            main.section(0, section = {
                items: alarmItems
            });
            //console.log('updated alarms');
            console.log('after : ' + alarmItems);
        });
    }
    // Choose an option to chnage alarm
});

<|endoftext|>


<commit_before>/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

var App = require('app');

App.ReassignMasterWizardStep4Controller = App.HighAvailabilityProgressPageController.extend({

  isReassign: true,

  commands: ['stopServices', 'createHostComponents', 'putHostComponentsInMaintenanceMode', 'reconfigure', 'installHostComponents', 'startZooKeeperServers', 'startNameNode', 'deleteHostComponents', 'startServices'],

  clusterDeployState: 'REASSIGN_MASTER_INSTALLING',

  multiTaskCounter: 0,

  hostComponents: [],

  loadStep: function () {
    if (this.get('content.reassign.component_name') === 'NAMENODE' && !App.HostComponent.find().someProperty('componentName', 'SECONDARY_NAMENODE')) {
      this.set('hostComponents', ['NAMENODE', 'ZKFC']);
    } else {
      this.set('hostComponents', [this.get('content.reassign.component_name')]);
    }
    this.set('serviceName', [this.get('content.reassign.service_id')]);
    this._super();
  },

  initializeTasks: function () {
    var commands = this.get('commands');
    var currentStep = App.router.get('reassignMasterController.currentStep');
    var hostComponentsNames = '';

    this.get('hostComponents').forEach(function (comp, index) {
      hostComponentsNames += index ? '+' : '';
      hostComponentsNames += comp === 'ZKFC' ? comp : App.format.role(comp);
    }, this);

    for (var i = 0; i < commands.length; i++) {
      var TaskLabel = i === 3 ? this.get('serviceName') : hostComponentsNames; //For Reconfigure task, show serviceName
      var title = Em.I18n.t('services.reassign.step4.task' + i + '.title').format(TaskLabel);
      this.get('tasks').pushObject(Ember.Object.create({
        title: title,
        status: 'PENDING',
        id: i,
        command: commands[i],
        showRetry: false,
        showRollback: false,
        name: title,
        displayName: title,
        progress: 0,
        isRunning: false,
        hosts: []
      }));
    }

    if (this.get('content.hasManualSteps')) {
      if (this.get('content.reassign.component_name') === 'NAMENODE' && !App.HostComponent.find().someProperty('componentName', 'SECONDARY_NAMENODE')) {
        // Only for reassign NameNode with HA enabled
        this.get('tasks').splice(7, 2);
      } else {
        this.get('tasks').splice(5, 4);
      }
    } else {
      this.get('tasks').splice(5, 2);
    }
  },

  hideRollbackButton: function () {
    var failedTask = this.get('tasks').findProperty('showRollback');
    if (failedTask) {
      failedTask.set('showRollback', false)
    }
  }.observes('tasks.@each.showRollback'),

  onComponentsTasksSuccess: function () {
    this.set('multiTaskCounter', this.get('multiTaskCounter') + 1);
    if (this.get('multiTaskCounter') >= this.get('hostComponents').length) {
      this.onTaskCompleted();
    }
  },

  stopServices: function () {
    App.ajax.send({
      name: 'reassign.stop_services',
      sender: this,
      success: 'startPolling',
      error: 'onTaskError'
    });
  },

  createHostComponents: function () {
    this.set('multiTaskCounter', 0);
    var hostComponents = this.get('hostComponents');
    var hostName = this.get('content.reassignHosts.target');
    for (var i = 0; i < hostComponents.length; i++) {
      this.createComponent(hostComponents[i], hostName);
    }
  },

  onCreateComponent: function () {
    this.onComponentsTasksSuccess();
  },

  putHostComponentsInMaintenanceMode: function () {
    this.set('multiTaskCounter', 0);
    var hostComponents = this.get('hostComponents');
    var hostName = this.get('content.reassignHosts.source');
    for (var i = 0; i < hostComponents.length; i++) {
      App.ajax.send({
        name: 'reassign.maintenance_mode',
        sender: this,
        data: {
          hostName: hostName,
          componentName: hostComponents[i]
        },
        success: 'onComponentsTasksSuccess',
        error: 'onTaskError'
      });
    }
  },

  installHostComponents: function () {
    this.set('multiTaskCounter', 0);
    var hostComponents = this.get('hostComponents');
    var hostName = this.get('content.reassignHosts.target');
    for (var i = 0; i < hostComponents.length; i++) {
      this.installComponent(hostComponents[i], hostName, hostComponents.length);
    }
  },

  reconfigure: function () {
    this.loadConfigsTags();
  },

  loadConfigsTags: function () {
    App.ajax.send({
      name: 'config.tags',
      sender: this,
      success: 'onLoadConfigsTags',
      error: 'onTaskError'
    });
  },

  onLoadConfigsTags: function (data) {
    var componentName = this.get('content.reassign.component_name');
    var urlParams = [];
    switch (componentName) {
      case 'NAMENODE':
        urlParams.push('(type=hdfs-site&tag=' + data.Clusters.desired_configs['hdfs-site'].tag + ')');
        urlParams.push('(type=core-site&tag=' + data.Clusters.desired_configs['core-site'].tag + ')');
        if (App.Service.find().someProperty('serviceName', 'HBASE')) {
          urlParams.push('(type=hbase-site&tag=' + data.Clusters.desired_configs['hbase-site'].tag + ')');
        }
        break;
      case 'SECONDARY_NAMENODE':
        urlParams.push('(type=hdfs-site&tag=' + data.Clusters.desired_configs['hdfs-site'].tag + ')');
        urlParams.push('(type=core-site&tag=' + data.Clusters.desired_configs['core-site'].tag + ')');
        break;
      case 'JOBTRACKER':
        urlParams.push('(type=mapred-site&tag=' + data.Clusters.desired_configs['mapred-site'].tag + ')');
        break;
      case 'RESOURCEMANAGER':
        urlParams.push('(type=yarn-site&tag=' + data.Clusters.desired_configs['yarn-site'].tag + ')');
        break;
    }
    App.ajax.send({
      name: 'reassign.load_configs',
      sender: this,
      data: {
        urlParams: urlParams.join('|')
      },
      success: 'onLoadConfigs',
      error: 'onTaskError'
    });
  },

  configsSitesCount: null,

  configsSitesNumber: null,

  onLoadConfigs: function (data) {
    var isHadoop2Stack = App.get('isHadoop2Stack');
    var securityEnabled = this.get('content.securityEnabled');
    var componentName = this.get('content.reassign.component_name');
    var targetHostName = this.get('content.reassignHosts.target');
    var sourceHostName = this.get('content.reassignHosts.source');
    var configs = {};
    var componentDir = '';
    var secureConfigs = [];
    this.set('configsSitesNumber', data.items.length);
    this.set('configsSitesCount', 0);
    data.items.forEach(function (item) {
      configs[item.type] = item.properties;
    }, this);
    switch (componentName) {
      case 'NAMENODE':
        if (isHadoop2Stack) {
          if (!App.HostComponent.find().someProperty('componentName', 'SECONDARY_NAMENODE')) {
            var nameServices = configs['hdfs-site']['dfs.nameservices'];
            if (configs['hdfs-site']['dfs.namenode.http-address.' + nameServices + '.nn1'] === sourceHostName + ':50070') {
              configs['hdfs-site']['dfs.namenode.http-address.' + nameServices + '.nn1'] = targetHostName + ':50070';
              configs['hdfs-site']['dfs.namenode.rpc-address.' + nameServices + '.nn1'] = targetHostName + ':8020';
            } else {
              configs['hdfs-site']['dfs.namenode.http-address.' + nameServices + '.nn2'] = targetHostName + ':50070';
              configs['hdfs-site']['dfs.namenode.rpc-address.' + nameServices + '.nn2'] = targetHostName + ':8020';
            }
          } else {
            configs['hdfs-site']['dfs.namenode.http-address'] = targetHostName + ':50070';
            configs['hdfs-site']['dfs.namenode.https-address'] = targetHostName + ':50470';
            configs['core-site']['fs.defaultFS'] = 'hdfs://' + targetHostName + ':8020';
          }
          componentDir = configs['hdfs-site']['dfs.namenode.name.dir'];
        } else {
          componentDir = configs['hdfs-site']['dfs.name.dir'];
          configs['hdfs-site']['dfs.http.address'] = targetHostName + ':50070';
          configs['hdfs-site']['dfs.https.address'] = targetHostName + ':50470';
          configs['core-site']['fs.default.name'] = 'hdfs://' + targetHostName + ':8020';
        }
        if (App.Service.find().someProperty('serviceName', 'HBASE')) {
          configs['hbase-site']['hbase.rootdir'] = configs['hbase-site']['hbase.rootdir'].replace(/\/\/[^\/]*/, '//' + targetHostName);
        }
        if (securityEnabled) {
          secureConfigs.push({keytab: configs['hdfs-site']['dfs.namenode.keytab.file'], principal: configs['hdfs-site']['dfs.namenode.kerberos.principal']});
          secureConfigs.push({keytab: configs['hdfs-site']['dfs.web.authentication.kerberos.keytab'], principal: configs['hdfs-site']['dfs.web.authentication.kerberos.principal']});
        }
        break;
      case 'SECONDARY_NAMENODE':
        if (isHadoop2Stack) {
          componentDir = configs['hdfs-site']['dfs.namenode.checkpoint.dir'];
          configs['hdfs-site']['dfs.namenode.secondary.http-address'] = targetHostName + ':50090';
        } else {
          componentDir = configs['core-site']['fs.checkpoint.dir'];
          configs['hdfs-site']['dfs.secondary.http.address'] = targetHostName + ':50090';
        }
        if (securityEnabled) {
          secureConfigs.push({keytab: configs['hdfs-site']['dfs.secondary.namenode.keytab.file'], principal: configs['hdfs-site']['dfs.secondary.namenode.kerberos.principal']});
          secureConfigs.push({keytab: configs['hdfs-site']['dfs.web.authentication.kerberos.keytab'], principal: configs['hdfs-site']['dfs.web.authentication.kerberos.principal']});
        }
        break;
      case 'JOBTRACKER':
        configs['mapred-site']['mapreduce.history.server.http.address'] = targetHostName + ':51111';
        configs['mapred-site']['mapred.job.tracker.http.address'] = targetHostName + ':50030';
        configs['mapred-site']['mapred.job.tracker'] = targetHostName + ':50300';
        if (securityEnabled) {
          secureConfigs.push({keytab: configs['mapred-site']['mapreduce.jobtracker.keytab.file'], principal: configs['mapred-site']['mapreduce.jobtracker.kerberos.principal']});
        }
        break;
      case 'RESOURCEMANAGER':
        configs['yarn-site']['yarn.resourcemanager.address'] = targetHostName + ':8050';
        configs['yarn-site']['yarn.resourcemanager.admin.address'] = targetHostName + ':8141';
        configs['yarn-site']['yarn.resourcemanager.resource-tracker.address'] = targetHostName + ':8025';
        configs['yarn-site']['yarn.resourcemanager.scheduler.address'] = targetHostName + ':8030';
        configs['yarn-site']['yarn.resourcemanager.webapp.address'] = targetHostName + ':8088';
        configs['yarn-site']['yarn.resourcemanager.hostname'] = targetHostName;
        if (securityEnabled) {
          secureConfigs.push({keytab: configs['yarn-site']['yarn.resourcemanager.keytab'], principal: configs['yarn-site']['yarn.resourcemanager.principal']});
          secureConfigs.push({keytab: configs['yarn-site']['yarn.resourcemanager.webapp.spnego-keytab-file'], principal: configs['yarn-site']['yarn.resourcemanager.webapp.spnego-principal']});
        }

        break;
    }
    if (componentDir || secureConfigs.length) {
      App.router.get(this.get('content.controllerName')).saveComponentDir(componentDir);
      App.router.get(this.get('content.controllerName')).saveSecureConfigs(secureConfigs);
      App.clusterStatus.setClusterStatus({
        clusterName: this.get('content.cluster.name'),
        clusterState: this.get('clusterDeployState'),
        wizardControllerName: this.get('content.controllerName'),
        localdb: App.db.data
      });
    }
    for (var site in configs) {
      if (!configs.hasOwnProperty(site)) continue;
      App.ajax.send({
        name: 'reassign.save_configs',
        sender: this,
        data: {
          siteName: site,
          properties: configs[site]
        },
        success: 'onSaveConfigs',
        error: 'onTaskError'
      });
    }
  },

  onSaveConfigs: function () {
    this.set('configsSitesCount', this.get('configsSitesCount') + 1);
    if (this.get('configsSitesCount') === this.get('configsSitesNumber')) {
      this.onTaskCompleted();
    }
  },

  startZooKeeperServers: function () {
    var hostNames = this.get('content.masterComponentHosts').filterProperty('component', 'ZOOKEEPER_SERVER').mapProperty('hostName');
    this.startComponent('ZOOKEEPER_SERVER', hostNames);
  },

  startNameNode: function () {
    var hostName = this.get('content.masterComponentHosts').filterProperty('component', 'NAMENODE').mapProperty('hostName').without(this.get('content.reassignHosts.target'));
    this.startComponent('NAMENODE', hostName);
  },

  startServices: function () {
    App.ajax.send({
      name: 'reassign.start_services',
      sender: this,
      success: 'startPolling',
      error: 'onTaskError'
    });
  },

  deleteHostComponents: function () {
    this.set('multiTaskCounter', 0);
    var hostComponents = this.get('hostComponents');
    var hostName = this.get('content.reassignHosts.source');
    for (var i = 0; i < hostComponents.length; i++) {
      App.ajax.send({
        name: 'reassign.remove_component',
        sender: this,
        data: {
          hostName: hostName,
          componentName: hostComponents[i]
        },
        success: 'onComponentsTasksSuccess',
        error: 'onDeleteHostComponentsError'
      });
    }
  },

  onDeleteHostComponentsError: function (error) {
    if (error.responseText.indexOf('org.apache.ambari.server.controller.spi.NoSuchResourceException') !== -1) {
      this.onComponentsTasksSuccess();
    } else {
      this.onTaskError();
    }
  },

  done: function () {
    if (!this.get('isSubmitDisabled')) {
      this.removeObserver('tasks.@each.status', this, 'onTaskStatusChange');
      if (this.get('content.hasManualSteps')) {
        App.router.send('next');
      } else {
        App.router.send('complete');
      }
    }
  }
});
<commit_msg>AMBARI-3735. Reassign Master: moving the NameNode while NameNode HA is enabled breaks HBase. (onechiporenko)<commit_after>/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

var App = require('app');

App.ReassignMasterWizardStep4Controller = App.HighAvailabilityProgressPageController.extend({

  isReassign: true,

  commands: ['stopServices', 'createHostComponents', 'putHostComponentsInMaintenanceMode', 'reconfigure', 'installHostComponents', 'startZooKeeperServers', 'startNameNode', 'deleteHostComponents', 'startServices'],

  clusterDeployState: 'REASSIGN_MASTER_INSTALLING',

  multiTaskCounter: 0,

  hostComponents: [],

  loadStep: function () {
    if (this.get('content.reassign.component_name') === 'NAMENODE' && !App.HostComponent.find().someProperty('componentName', 'SECONDARY_NAMENODE')) {
      this.set('hostComponents', ['NAMENODE', 'ZKFC']);
    } else {
      this.set('hostComponents', [this.get('content.reassign.component_name')]);
    }
    this.set('serviceName', [this.get('content.reassign.service_id')]);
    this._super();
  },

  initializeTasks: function () {
    var commands = this.get('commands');
    var currentStep = App.router.get('reassignMasterController.currentStep');
    var hostComponentsNames = '';

    this.get('hostComponents').forEach(function (comp, index) {
      hostComponentsNames += index ? '+' : '';
      hostComponentsNames += comp === 'ZKFC' ? comp : App.format.role(comp);
    }, this);

    for (var i = 0; i < commands.length; i++) {
      var TaskLabel = i === 3 ? this.get('serviceName') : hostComponentsNames; //For Reconfigure task, show serviceName
      var title = Em.I18n.t('services.reassign.step4.task' + i + '.title').format(TaskLabel);
      this.get('tasks').pushObject(Ember.Object.create({
        title: title,
        status: 'PENDING',
        id: i,
        command: commands[i],
        showRetry: false,
        showRollback: false,
        name: title,
        displayName: title,
        progress: 0,
        isRunning: false,
        hosts: []
      }));
    }

    if (this.get('content.hasManualSteps')) {
      if (this.get('content.reassign.component_name') === 'NAMENODE' && !App.HostComponent.find().someProperty('componentName', 'SECONDARY_NAMENODE')) {
        // Only for reassign NameNode with HA enabled
        this.get('tasks').splice(7, 2);
      } else {
        this.get('tasks').splice(5, 4);
      }
    } else {
      this.get('tasks').splice(5, 2);
    }
  },

  hideRollbackButton: function () {
    var failedTask = this.get('tasks').findProperty('showRollback');
    if (failedTask) {
      failedTask.set('showRollback', false)
    }
  }.observes('tasks.@each.showRollback'),

  onComponentsTasksSuccess: function () {
    this.set('multiTaskCounter', this.get('multiTaskCounter') + 1);
    if (this.get('multiTaskCounter') >= this.get('hostComponents').length) {
      this.onTaskCompleted();
    }
  },

  stopServices: function () {
    App.ajax.send({
      name: 'reassign.stop_services',
      sender: this,
      success: 'startPolling',
      error: 'onTaskError'
    });
  },

  createHostComponents: function () {
    this.set('multiTaskCounter', 0);
    var hostComponents = this.get('hostComponents');
    var hostName = this.get('content.reassignHosts.target');
    for (var i = 0; i < hostComponents.length; i++) {
      this.createComponent(hostComponents[i], hostName);
    }
  },

  onCreateComponent: function () {
    this.onComponentsTasksSuccess();
  },

  putHostComponentsInMaintenanceMode: function () {
    this.set('multiTaskCounter', 0);
    var hostComponents = this.get('hostComponents');
    var hostName = this.get('content.reassignHosts.source');
    for (var i = 0; i < hostComponents.length; i++) {
      App.ajax.send({
        name: 'reassign.maintenance_mode',
        sender: this,
        data: {
          hostName: hostName,
          componentName: hostComponents[i]
        },
        success: 'onComponentsTasksSuccess',
        error: 'onTaskError'
      });
    }
  },

  installHostComponents: function () {
    this.set('multiTaskCounter', 0);
    var hostComponents = this.get('hostComponents');
    var hostName = this.get('content.reassignHosts.target');
    for (var i = 0; i < hostComponents.length; i++) {
      this.installComponent(hostComponents[i], hostName, hostComponents.length);
    }
  },

  reconfigure: function () {
    this.loadConfigsTags();
  },

  loadConfigsTags: function () {
    App.ajax.send({
      name: 'config.tags',
      sender: this,
      success: 'onLoadConfigsTags',
      error: 'onTaskError'
    });
  },

  onLoadConfigsTags: function (data) {
    var componentName = this.get('content.reassign.component_name');
    var urlParams = [];
    switch (componentName) {
      case 'NAMENODE':
        urlParams.push('(type=hdfs-site&tag=' + data.Clusters.desired_configs['hdfs-site'].tag + ')');
        urlParams.push('(type=core-site&tag=' + data.Clusters.desired_configs['core-site'].tag + ')');
        if (App.Service.find().someProperty('serviceName', 'HBASE')) {
          urlParams.push('(type=hbase-site&tag=' + data.Clusters.desired_configs['hbase-site'].tag + ')');
        }
        break;
      case 'SECONDARY_NAMENODE':
        urlParams.push('(type=hdfs-site&tag=' + data.Clusters.desired_configs['hdfs-site'].tag + ')');
        urlParams.push('(type=core-site&tag=' + data.Clusters.desired_configs['core-site'].tag + ')');
        break;
      case 'JOBTRACKER':
        urlParams.push('(type=mapred-site&tag=' + data.Clusters.desired_configs['mapred-site'].tag + ')');
        break;
      case 'RESOURCEMANAGER':
        urlParams.push('(type=yarn-site&tag=' + data.Clusters.desired_configs['yarn-site'].tag + ')');
        break;
    }
    App.ajax.send({
      name: 'reassign.load_configs',
      sender: this,
      data: {
        urlParams: urlParams.join('|')
      },
      success: 'onLoadConfigs',
      error: 'onTaskError'
    });
  },

  configsSitesCount: null,

  configsSitesNumber: null,

  onLoadConfigs: function (data) {
    var isHadoop2Stack = App.get('isHadoop2Stack');
    var securityEnabled = this.get('content.securityEnabled');
    var componentName = this.get('content.reassign.component_name');
    var targetHostName = this.get('content.reassignHosts.target');
    var sourceHostName = this.get('content.reassignHosts.source');
    var configs = {};
    var componentDir = '';
    var secureConfigs = [];
    this.set('configsSitesNumber', data.items.length);
    this.set('configsSitesCount', 0);
    data.items.forEach(function (item) {
      configs[item.type] = item.properties;
    }, this);
    switch (componentName) {
      case 'NAMENODE':
        if (isHadoop2Stack) {
          if (!App.HostComponent.find().someProperty('componentName', 'SECONDARY_NAMENODE')) {
            var nameServices = configs['hdfs-site']['dfs.nameservices'];
            if (configs['hdfs-site']['dfs.namenode.http-address.' + nameServices + '.nn1'] === sourceHostName + ':50070') {
              configs['hdfs-site']['dfs.namenode.http-address.' + nameServices + '.nn1'] = targetHostName + ':50070';
              configs['hdfs-site']['dfs.namenode.https-address.' + nameServices + '.nn1'] = targetHostName + ':50470';
              configs['hdfs-site']['dfs.namenode.rpc-address.' + nameServices + '.nn1'] = targetHostName + ':8020';
            } else {
              configs['hdfs-site']['dfs.namenode.http-address.' + nameServices + '.nn2'] = targetHostName + ':50070';
              configs['hdfs-site']['dfs.namenode.https-address.' + nameServices + '.nn2'] = targetHostName + ':50470';
              configs['hdfs-site']['dfs.namenode.rpc-address.' + nameServices + '.nn2'] = targetHostName + ':8020';
            }
          } else {
            configs['hdfs-site']['dfs.namenode.http-address'] = targetHostName + ':50070';
            configs['hdfs-site']['dfs.namenode.https-address'] = targetHostName + ':50470';
            configs['core-site']['fs.defaultFS'] = 'hdfs://' + targetHostName + ':8020';
          }
          componentDir = configs['hdfs-site']['dfs.namenode.name.dir'];
        } else {
          componentDir = configs['hdfs-site']['dfs.name.dir'];
          configs['hdfs-site']['dfs.http.address'] = targetHostName + ':50070';
          configs['hdfs-site']['dfs.https.address'] = targetHostName + ':50470';
          configs['core-site']['fs.default.name'] = 'hdfs://' + targetHostName + ':8020';
        }
        if (App.HostComponent.find().someProperty('componentName', 'SECONDARY_NAMENODE')) {
          if (App.Service.find().someProperty('serviceName', 'HBASE')) {
            configs['hbase-site']['hbase.rootdir'] = configs['hbase-site']['hbase.rootdir'].replace(/\/\/[^\/]*/, '//' + targetHostName);
          }
        }
        if (securityEnabled) {
          secureConfigs.push({keytab: configs['hdfs-site']['dfs.namenode.keytab.file'], principal: configs['hdfs-site']['dfs.namenode.kerberos.principal']});
          secureConfigs.push({keytab: configs['hdfs-site']['dfs.web.authentication.kerberos.keytab'], principal: configs['hdfs-site']['dfs.web.authentication.kerberos.principal']});
        }
        break;
      case 'SECONDARY_NAMENODE':
        if (isHadoop2Stack) {
          componentDir = configs['hdfs-site']['dfs.namenode.checkpoint.dir'];
          configs['hdfs-site']['dfs.namenode.secondary.http-address'] = targetHostName + ':50090';
        } else {
          componentDir = configs['core-site']['fs.checkpoint.dir'];
          configs['hdfs-site']['dfs.secondary.http.address'] = targetHostName + ':50090';
        }
        if (securityEnabled) {
          secureConfigs.push({keytab: configs['hdfs-site']['dfs.secondary.namenode.keytab.file'], principal: configs['hdfs-site']['dfs.secondary.namenode.kerberos.principal']});
          secureConfigs.push({keytab: configs['hdfs-site']['dfs.web.authentication.kerberos.keytab'], principal: configs['hdfs-site']['dfs.web.authentication.kerberos.principal']});
        }
        break;
      case 'JOBTRACKER':
        configs['mapred-site']['mapreduce.history.server.http.address'] = targetHostName + ':51111';
        configs['mapred-site']['mapred.job.tracker.http.address'] = targetHostName + ':50030';
        configs['mapred-site']['mapred.job.tracker'] = targetHostName + ':50300';
        if (securityEnabled) {
          secureConfigs.push({keytab: configs['mapred-site']['mapreduce.jobtracker.keytab.file'], principal: configs['mapred-site']['mapreduce.jobtracker.kerberos.principal']});
        }
        break;
      case 'RESOURCEMANAGER':
        configs['yarn-site']['yarn.resourcemanager.address'] = targetHostName + ':8050';
        configs['yarn-site']['yarn.resourcemanager.admin.address'] = targetHostName + ':8141';
        configs['yarn-site']['yarn.resourcemanager.resource-tracker.address'] = targetHostName + ':8025';
        configs['yarn-site']['yarn.resourcemanager.scheduler.address'] = targetHostName + ':8030';
        configs['yarn-site']['yarn.resourcemanager.webapp.address'] = targetHostName + ':8088';
        configs['yarn-site']['yarn.resourcemanager.hostname'] = targetHostName;
        if (securityEnabled) {
          secureConfigs.push({keytab: configs['yarn-site']['yarn.resourcemanager.keytab'], principal: configs['yarn-site']['yarn.resourcemanager.principal']});
          secureConfigs.push({keytab: configs['yarn-site']['yarn.resourcemanager.webapp.spnego-keytab-file'], principal: configs['yarn-site']['yarn.resourcemanager.webapp.spnego-principal']});
        }

        break;
    }
    if (componentDir || secureConfigs.length) {
      App.router.get(this.get('content.controllerName')).saveComponentDir(componentDir);
      App.router.get(this.get('content.controllerName')).saveSecureConfigs(secureConfigs);
      App.clusterStatus.setClusterStatus({
        clusterName: this.get('content.cluster.name'),
        clusterState: this.get('clusterDeployState'),
        wizardControllerName: this.get('content.controllerName'),
        localdb: App.db.data
      });
    }
    for (var site in configs) {
      if (!configs.hasOwnProperty(site)) continue;
      App.ajax.send({
        name: 'reassign.save_configs',
        sender: this,
        data: {
          siteName: site,
          properties: configs[site]
        },
        success: 'onSaveConfigs',
        error: 'onTaskError'
      });
    }
  },

  onSaveConfigs: function () {
    this.set('configsSitesCount', this.get('configsSitesCount') + 1);
    if (this.get('configsSitesCount') === this.get('configsSitesNumber')) {
      this.onTaskCompleted();
    }
  },

  startZooKeeperServers: function () {
    var hostNames = this.get('content.masterComponentHosts').filterProperty('component', 'ZOOKEEPER_SERVER').mapProperty('hostName');
    this.startComponent('ZOOKEEPER_SERVER', hostNames);
  },

  startNameNode: function () {
    var hostName = this.get('content.masterComponentHosts').filterProperty('component', 'NAMENODE').mapProperty('hostName').without(this.get('content.reassignHosts.target'));
    this.startComponent('NAMENODE', hostName);
  },

  startServices: function () {
    App.ajax.send({
      name: 'reassign.start_services',
      sender: this,
      success: 'startPolling',
      error: 'onTaskError'
    });
  },

  deleteHostComponents: function () {
    this.set('multiTaskCounter', 0);
    var hostComponents = this.get('hostComponents');
    var hostName = this.get('content.reassignHosts.source');
    for (var i = 0; i < hostComponents.length; i++) {
      App.ajax.send({
        name: 'reassign.remove_component',
        sender: this,
        data: {
          hostName: hostName,
          componentName: hostComponents[i]
        },
        success: 'onComponentsTasksSuccess',
        error: 'onDeleteHostComponentsError'
      });
    }
  },

  onDeleteHostComponentsError: function (error) {
    if (error.responseText.indexOf('org.apache.ambari.server.controller.spi.NoSuchResourceException') !== -1) {
      this.onComponentsTasksSuccess();
    } else {
      this.onTaskError();
    }
  },

  done: function () {
    if (!this.get('isSubmitDisabled')) {
      this.removeObserver('tasks.@each.status', this, 'onTaskStatusChange');
      if (this.get('content.hasManualSteps')) {
        App.router.send('next');
      } else {
        App.router.send('complete');
      }
    }
  }
});
<|endoftext|>


<commit_before>import {app, ipcMain, shell, BrowserWindow, nativeImage} from 'electron';
import EventEmitter from 'events';

import contextMenu from 'browser/menus/context';
import platform from 'common/utils/platform';
import prefs from 'browser/utils/prefs';

class IpcListenersManager extends EventEmitter {

  constructor (notifManager, trayManager, mainWindowManager) {
    super();
    this.notifManager = notifManager;
    this.trayManager = trayManager;
    this.mainWindowManager = mainWindowManager;
  }

  /**
   * Bind events to local methods.
   */
  set () {
    ipcMain.on('notif-count', ::this.onNotifCount);
    ipcMain.on('context-menu', ::this.onContextMenu);
    ipcMain.on('close-window', ::this.onCloseWindow);
    ipcMain.on('open-url', ::this.onOpenUrl);
  }

  /**
   * Called when the 'notif-count' event is received.
   */
  onNotifCount (event, count, badgeDataUrl) {
    log('on renderer notif-count', count, !!badgeDataUrl || null);
    this.notifManager.unreadCount = count;

    // Set icon badge
    if (prefs.get('show-notifications-badge')) {
      if (platform.isWindows) {
        if (count) {
          const image = nativeImage.createFromDataUrl(badgeDataUrl);
          this.mainWindowManager.window.setOverlayIcon(image, count);
        } else {
          this.mainWindowManager.window.setOverlayIcon(null, '');
        }
      } else {
        app.setBadgeCount(parseInt(count, 10) || 0);
      }
    }

    // Update tray
    this.trayManager.unreadCountUpdated(count);

    // Update window title
    this.mainWindowManager.suffixWindowTitle(count ? ' (' + count + ')' : '');
  }

  /**
   * Called when the 'context-menu' event is received.
   */
  onContextMenu (event, options) {
    try {
      options = JSON.parse(options);
      const menu = contextMenu.create(options, this.mainWindowManager.window);
      if (menu) {
        log('opening context menu');
        setTimeout(() => {
          menu.popup(this.mainWindowManager.window);
        }, 50);
      }
    } catch (err) {
      logError(err);
    }
  }

  /**
   * Called when the 'close-window' event is received.
   */
  onCloseWindow () {
    this.mainWindowManager.window.close();
  }

  /**
   * Called when the 'open-url' event is received.
   */
  onOpenUrl (event, url, options) {
    if (prefs.get('links-in-browser')) {
      log('on renderer open-url, externally', url);
      shell.openExternal(url);
    } else {
      log('on renderer open-url, new window', url);
      const newWindow = new BrowserWindow(options);
      newWindow.loadURL(url);
    }
  }

}

export default IpcListenersManager;
<commit_msg>Fix createFromDataURL again<commit_after>import {app, ipcMain, shell, BrowserWindow, nativeImage} from 'electron';
import EventEmitter from 'events';

import contextMenu from 'browser/menus/context';
import platform from 'common/utils/platform';
import prefs from 'browser/utils/prefs';

class IpcListenersManager extends EventEmitter {

  constructor (notifManager, trayManager, mainWindowManager) {
    super();
    this.notifManager = notifManager;
    this.trayManager = trayManager;
    this.mainWindowManager = mainWindowManager;
  }

  /**
   * Bind events to local methods.
   */
  set () {
    ipcMain.on('notif-count', ::this.onNotifCount);
    ipcMain.on('context-menu', ::this.onContextMenu);
    ipcMain.on('close-window', ::this.onCloseWindow);
    ipcMain.on('open-url', ::this.onOpenUrl);
  }

  /**
   * Called when the 'notif-count' event is received.
   */
  onNotifCount (event, count, badgeDataUrl) {
    log('on renderer notif-count', count, !!badgeDataUrl || null);
    this.notifManager.unreadCount = count;

    // Set icon badge
    if (prefs.get('show-notifications-badge')) {
      if (platform.isWindows) {
        if (count) {
          const image = nativeImage.createFromDataURL(badgeDataUrl);
          this.mainWindowManager.window.setOverlayIcon(image, count);
        } else {
          this.mainWindowManager.window.setOverlayIcon(null, '');
        }
      } else {
        app.setBadgeCount(parseInt(count, 10) || 0);
      }
    }

    // Update tray
    this.trayManager.unreadCountUpdated(count);

    // Update window title
    this.mainWindowManager.suffixWindowTitle(count ? ' (' + count + ')' : '');
  }

  /**
   * Called when the 'context-menu' event is received.
   */
  onContextMenu (event, options) {
    try {
      options = JSON.parse(options);
      const menu = contextMenu.create(options, this.mainWindowManager.window);
      if (menu) {
        log('opening context menu');
        setTimeout(() => {
          menu.popup(this.mainWindowManager.window);
        }, 50);
      }
    } catch (err) {
      logError(err);
    }
  }

  /**
   * Called when the 'close-window' event is received.
   */
  onCloseWindow () {
    this.mainWindowManager.window.close();
  }

  /**
   * Called when the 'open-url' event is received.
   */
  onOpenUrl (event, url, options) {
    if (prefs.get('links-in-browser')) {
      log('on renderer open-url, externally', url);
      shell.openExternal(url);
    } else {
      log('on renderer open-url, new window', url);
      const newWindow = new BrowserWindow(options);
      newWindow.loadURL(url);
    }
  }

}

export default IpcListenersManager;
<|endoftext|>


<commit_before>/**
 * @name Application
 * @description Minify all images of a given dir by using the TinyPNG API.
 * @see {@link https://github.com/tinify/tinify-nodejs} for TinyPNG client information.
 * @author Patrick Ferreira <paatrickferreira@gmail.com>
 */

const { logger } = require('./helpers/logger');
const fileSystemHelper = require('./helpers/file');
const { green, yellow } = require('colors');
const tinify = require('tinify');

/**
 * Gets the number of already minified images of based on the set API key.
 *
 * @returns {string} Total of compressed images.
 */
const getCompressionCount = async () => tinify.compressionCount;

/**
 * Minifies a given image, logging the result afterwrads.
 *
 * @param {string} file
 * @returns {boolean}
 */
const minifyFile = async (image) => {
  try {
    const oldSize = await fileSystemHelper.getFileSize(image);
    await tinify.fromFile(image).toFile(image);
    const optimizedSize = await fileSystemHelper.getFileSize(image);

    logger.info(`Minified image ${image}. From: ${yellow(oldSize)} to ${green(optimizedSize)}`);

    return image;
  } catch (err) {
    throw new Error(`${err.message}: ${image}`);
  }
};

/**
 * Main function. Validates if a given dir has images, clones it,
 * gets all its images and finally minify all of them, putting the results
 * in the cloned dir. That way the original dir stays intact.
 *
 * @param {string} dir
 */
const run = async (dir) => {
  logger.info('[Started]');

  await fileSystemHelper.checkIfDirHasImages(dir);

  logger.info('Cloning directory');
  const optimizedDir = await fileSystemHelper.cloneDir(dir);

  logger.info('Cleaning cloned directory');
  await fileSystemHelper.deleteNonImageFiles(optimizedDir);

  const images = await fileSystemHelper.getImagesFromDir(optimizedDir);
  const minifiedImages = await Promise.all(images.map(minifyFile));

  logger.info(`Total of minified images: ${green(minifiedImages.length)}`);
  logger.info('[Finished]');
};

/**
 * Sets and validates a Tinify API key. Throws an error if key is not valid.
 *
 * @param {string} apiKey
 */
const setAndValidateApiKey = async (apiKey) => {
  tinify.key = apiKey;

  await tinify.validate();
};

module.exports = {
  getCompressionCount,
  run,
  setAndValidateApiKey,
};
<commit_msg>Refactor file helper name on app<commit_after>/**
 * @name Application
 * @description Minify all images of a given dir by using the TinyPNG API.
 * @see {@link https://github.com/tinify/tinify-nodejs} for TinyPNG client information.
 * @author Patrick Ferreira <paatrickferreira@gmail.com>
 */

const { logger } = require('./helpers/logger');
const fileSystem = require('./helpers/file');
const { green, yellow } = require('colors');
const tinify = require('tinify');

/**
 * Gets the number of already minified images of based on the set API key.
 *
 * @returns {string} Total of compressed images.
 */
const getCompressionCount = async () => tinify.compressionCount;

/**
 * Minifies a given image, logging the result afterwrads.
 *
 * @param {string} file
 * @returns {boolean}
 */
const minifyFile = async (image) => {
  try {
    const oldSize = await fileSystem.getFileSize(image);
    await tinify.fromFile(image).toFile(image);
    const optimizedSize = await fileSystem.getFileSize(image);

    logger.info(`Minified image ${image}. From: ${yellow(oldSize)} to ${green(optimizedSize)}`);

    return image;
  } catch (err) {
    throw new Error(`${err.message}: ${image}`);
  }
};

/**
 * Main function. Validates if a given dir has images, clones it,
 * gets all its images and finally minify all of them, putting the results
 * in the cloned dir. That way the original dir stays intact.
 *
 * @param {string} dir
 */
const run = async (dir) => {
  logger.info('[Started]');

  await fileSystem.checkIfDirHasImages(dir);

  logger.info('Cloning directory');
  const optimizedDir = await fileSystem.cloneDir(dir);

  logger.info('Cleaning cloned directory');
  await fileSystem.deleteNonImageFiles(optimizedDir);

  const images = await fileSystem.getImagesFromDir(optimizedDir);
  const minifiedImages = await Promise.all(images.map(minifyFile));

  logger.info(`Total of minified images: ${green(minifiedImages.length)}`);
  logger.info('[Finished]');
};

/**
 * Sets and validates a Tinify API key. Throws an error if key is not valid.
 *
 * @param {string} apiKey
 */
const setAndValidateApiKey = async (apiKey) => {
  tinify.key = apiKey;

  await tinify.validate();
};

module.exports = {
  getCompressionCount,
  run,
  setAndValidateApiKey,
};
<|endoftext|>


<commit_before>/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

var App = require('app');

App.HiveInteractiveCheck = Em.Mixin.create({
  enableHiveInteractive: false,

  loadHiveConfigs: function() {
    App.ajax.send({
      name: 'service.serviceConfigVersions.get.current',
      sender: this,
      data: {
        serviceNames: ['HIVE']
      },
      success: 'onLoadHiveConfigs'
    });
  },

  onLoadHiveConfigs: function (data) {
    this.set('enableHiveInteractive', data.items[0].configurations.findProperty('type', 'hive-interactive-env').properties['enable_hive_interactive'] === 'true');
  }
});<commit_msg>AMBARI-25228 add a second HiveServer2Interactive Button Missing in Ambari UI is there is config group for Hive Service (asnaik) (#2907)<commit_after>/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

var App = require('app');

App.HiveInteractiveCheck = Em.Mixin.create({
  enableHiveInteractive: false,

  loadHiveConfigs: function() {
    App.ajax.send({
      name: 'service.serviceConfigVersions.get.current',
      sender: this,
      data: {
        serviceNames: ['HIVE']
      },
      success: 'onLoadHiveConfigs'
    });
  },

  onLoadHiveConfigs: function (data) {
    var enableHiveInteractive = false;
    data.items.forEach(function(item) {
        var hiveInteractive = item.configurations.findProperty('type', 'hive-interactive-env');
        if(hiveInteractive) {
          enableHiveInteractive = hiveInteractive.properties['enable_hive_interactive'] === 'true';
        }
      });
    this.set('enableHiveInteractive',enableHiveInteractive);
  }
});<|endoftext|>


<commit_before>const TelegramHelper = require('../../../helper/TelegramHelper');
const StringHelper = require('../../../helper/StringHelper');
const config = require('config');
module.exports = (() => {

  function webHook(request, response) {
    const {token, user_name, text} = request.body;

    if(StringHelper.isNullOrEmptyString(token) ||
        StringHelper.isNullOrEmptyString(user_name) ||
        StringHelper.isNullOrEmptyString(text)) {
      return response.status(400).json({success: false,
        error: {text: 'Wrong json supplied'}});
    }

    if(token !== config.get('slack_webhook_token')) {
      return response.status(400).json({success: false,
        error: {text: 'Wrong webhook token'}});
    }

    if(user_name !== 'kadsebot') {
      TelegramHelper.sendMessage(config.get('telegram_chat_id'), `${user_name}: ${text}`);
    }
    response.end();
  }
  return {
    webHook
  };
})();
<commit_msg>fix constant echoing<commit_after>const TelegramHelper = require('../../../helper/TelegramHelper');
const StringHelper = require('../../../helper/StringHelper');
const config = require('config');
module.exports = (() => {

  function webHook(request, response) {
    const {token, user_name, text} = request.body;

    if(StringHelper.isNullOrEmptyString(token) ||
        StringHelper.isNullOrEmptyString(user_name) ||
        StringHelper.isNullOrEmptyString(text)) {
      return response.status(400).json({success: false,
        error: {text: 'Wrong json supplied'}});
    }

    if(token !== config.get('slack_webhook_token')) {
      return response.status(400).json({success: false,
        error: {text: 'Wrong webhook token'}});
    }

    if(user_name !== 'slackbot') {
      TelegramHelper.sendMessage(config.get('telegram_chat_id'), `${user_name}: ${text}`);
    }
    response.end();
  }
  return {
    webHook
  };
})();
<|endoftext|>