From 1a69431a81b2f389705f8e0f55ebd19d7d1ab573 Mon Sep 17 00:00:00 2001 From: Justas Brazauskas Date: Sat, 17 Jan 2015 18:41:27 +0200 Subject: [PATCH 1/9] Added pluralization --- main.js | 7 +++++-- package.json | 1 + 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/main.js b/main.js index f1231f7..fca3b30 100644 --- a/main.js +++ b/main.js @@ -1,6 +1,7 @@ var Slack = require('slack-node'); var async = require('async'); var GitHubApi = require("github"); +var pluralize = require('pluralize'); var CronJob = require('cron').CronJob; var format = require('util').format; var q = require('q'); @@ -10,13 +11,15 @@ var githubApiToken = process.env.GITHUB_API_TOKEN; var channel = process.env.SLACK_CHANNEL || "#general"; var slackIcon = process.env.SLACK_ICON || "http://4.bp.blogspot.com/-9TT2oDIQ00k/TqVViEko4HI/AAAAAAAAADU/svUOHDxP6UM/s1600/T-rex-hates-push-ups.jpg"; var slackUsername = process.env.SLACK_USERNAME || "Swolebot"; -var messageTemplate = "@channel: %s pushups!"; +var messageTemplate = "@channel: %s %s!"; var ratio = process.env.RATIO || 2; var hours = (typeof process.env.HOURS !== 'undefined') ? process.env.HOURS.split(',') : [11, 14, 17]; var timezone = process.env.TIMEZONE || "America/New_York"; var runInWeekends = (process.env.WEEKENDS) || false; var repos; +var exercise = 'pushup'; + if (process.env.REPOS) { repos = process.env.REPOS.split(','); } else { @@ -130,7 +133,7 @@ function run() { amount += num; }); amount = amount * ratio; - return postMessage(format(messageTemplate, amount)); + return postMessage(format(messageTemplate, amount, pluralize(exercise, amount))); }).then(function () { console.log("Done!"); }).catch(function (err) { diff --git a/package.json b/package.json index d563148..3104dbb 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "async": "^0.9.0", "cron": "^1.0.5", "github": "^0.2.3", + "pluralize": "^1.1.1", "q": "^1.1.2", "slack-node": "0.0.93", "time": "^0.11.0" From 632ae0d690e9e45e26eb719d7913dab44c1dfc6d Mon Sep 17 00:00:00 2001 From: Justas Brazauskas Date: Sun, 18 Jan 2015 00:10:21 +0200 Subject: [PATCH 2/9] Just some updates. Just a bit. Nothing fancy --- main.js | 166 ++++++++++++++++++++++++++++++++++++++++++++++++--- package.json | 1 + 2 files changed, 158 insertions(+), 9 deletions(-) diff --git a/main.js b/main.js index fca3b30..ab7e737 100644 --- a/main.js +++ b/main.js @@ -2,6 +2,7 @@ var Slack = require('slack-node'); var async = require('async'); var GitHubApi = require("github"); var pluralize = require('pluralize'); +var moment = require('moment'); var CronJob = require('cron').CronJob; var format = require('util').format; var q = require('q'); @@ -11,14 +12,57 @@ var githubApiToken = process.env.GITHUB_API_TOKEN; var channel = process.env.SLACK_CHANNEL || "#general"; var slackIcon = process.env.SLACK_ICON || "http://4.bp.blogspot.com/-9TT2oDIQ00k/TqVViEko4HI/AAAAAAAAADU/svUOHDxP6UM/s1600/T-rex-hates-push-ups.jpg"; var slackUsername = process.env.SLACK_USERNAME || "Swolebot"; -var messageTemplate = "@channel: %s %s!"; -var ratio = process.env.RATIO || 2; +var messageTemplate = "@channel: %s! %s"; +var ratio = process.env.RATIO || 1; var hours = (typeof process.env.HOURS !== 'undefined') ? process.env.HOURS.split(',') : [11, 14, 17]; var timezone = process.env.TIMEZONE || "America/New_York"; var runInWeekends = (process.env.WEEKENDS) || false; -var repos; +var repos, exercises; -var exercise = 'pushup'; +var funMessages = [ + 'Keep Pumping!', + ucFirst(slackUsername) + ' :heart: you.', + 'Karma++.', + 'Just a few to go.', + 'Muscles++', + 'Sweat away those pounds.', + 'Do you like me?', + '`undefined is not a function`.', + 'Abort, Retry, Fail?', + 'Kernel Panic', + ':heart::cat2:?', + ':clap::clap', + 'Go play some :basketball:', + 'With :love: from :moon:', + 'Make some :tea: today.', + getRandSlackUserName.bind(undefined, '%s did those faster than you did.'), + getRandSlackUserName.bind(undefined, '%s dont you cheat on me.'), + getRandSlackUserName.bind(undefined, '%s does double this time.'), + getRandSlackUserName.bind(undefined, 'Exept %s. They are free this time.'), + getRandSlackUserName.bind(undefined, '%s does not like jumping.'), + getRandSlackUserName.bind(undefined, '%s, did you just leveled up?.'), + getRandSlackUserName.bind(undefined, '%s did those faster than you did.') +]; + +if (process.env.EXERCISES) { + var tmp = process.env.EXERCISES.split(','); + var good = {}; + if (process.env.EXERCISES.indexOf(':') > -1) { + exercises = {}; + tmp.forEach(function (section) { + var items = section.split(':'); + exercises[items[0]] = parseFloat(items[1]); + }); + } else { + exercises = tmp; + } +} else { + exercises = { + situp: 1, + pushup: 1.5, + jump: 2 + }; +} if (process.env.REPOS) { repos = process.env.REPOS.split(','); @@ -38,6 +82,50 @@ github.authenticate({ token: githubApiToken }); +function getRandSlackUserName(msg) { + return getChannelID(channel).then(function (id) { + return q.ninvoke(slack, 'api', "channels.info", { + channel: id + }); + }).then(function (resp) { + var user = resp.channel.members[rand(resp.channel.members.length, 0) - 1]; + return q.ninvoke(slack, 'api', "users.info", { + user: user + }); + }).then(function (user) { + var name; + user = user.user; + if (user.real_name) { + name = user.real_name; + } else { + name = '@' + user.name; + } + if (msg) { + return format(msg, name); + } + return name; + }); +} + +function getChannelID(name) { + if (name.indexOf('#') !== 0) { + return q.when(name); + } + return q.ninvoke(slack, 'api', "channels.list").then(function (resp) { + var id = ''; + resp.channels.forEach(function (channel) { + if (channel.name === name.substr(1)) { + id = channel.id; + } + }); + return id; + }); +} + +function ucFirst(str) { + return str.substr(0, 1).toUpperCase() + str.substr(1); +} + function postMessage(message, callback) { return q.ninvoke(slack, 'api', "chat.postMessage", { channel: channel, @@ -82,7 +170,14 @@ function getPRs(user, repo, callback) { state: 'open', per_page: 100 }).then(function (data) { - return data.length; + var num = data.length; + var now = new Date().getTime(); + data.forEach(function (pr) { + if (moment(pr.created_at).add(5, 'days').format('x') < now) { + num++; + } + }); + return num; }); } @@ -105,20 +200,67 @@ function getRepos() { }); } +function rand(upTo, min) { + if (min === undefined) { + min = 1; + } + return Math.ceil((Math.random() * Math.ceil(upTo)) + Math.ceil(min)); +} + +function compileExercise(amount) { + var rands = {}, left = amount, messages = [], collection; + if (Array.isArray(exercises)) { + collection = exercises; + } else { + collection = Object.keys(exercises); + } + collection.forEach(function (name, i) { + if (i === collection.length - 1) { + rands[name] = left; + return; + } + var rnd = rand(amount / Math.pow(collection.length, 2), amount / ((collection.length - 1) * 2)); + left -= rnd; + rands[name] = rnd; + }); + Object.keys(rands).forEach(function (name) { + var amount = rands[name]; + if (exercises[name]) { + amount = Math.floor(amount * exercises[name]); + } + if (amount >= 1) { + messages.push(pluralize(name, amount, true)); + } + }); + + return messages.join(', '); +} + +function getFunMessage() { + var rnd = rand(funMessages.length - 1, 0); + var msg = funMessages[rnd]; + if (typeof msg !== 'function') { + return msg; + } + return msg(); +} + function run() { console.log('Started!'); getRepos().then(function (data) { - var arr = []; + var arr = [], exclude = []; data.forEach(function (items) { if (Array.isArray(items)) { arr = arr.concat(items); + } else if (items.indexOf('!') === 0){ + exclude.push(items.substr(1)); } else { arr.push(items); } }); // We want to make sure, that we will make no more pushups than we 'want' return arr.filter(function(item, pos) { - return arr.indexOf(item) === pos && arr.lastIndexOf(item) === pos; + return arr.indexOf(item) === pos && arr.lastIndexOf(item) === pos && exclude.indexOf(item) === -1; }); }).then(function (arr) { return q.ninvoke(async, 'map', arr, function (data, callback) { @@ -132,8 +274,12 @@ function run() { data.forEach(function (num) { amount += num; }); - amount = amount * ratio; - return postMessage(format(messageTemplate, amount, pluralize(exercise, amount))); + if (!ratio && Array.isArray(exercises)) { + amount = amount * ratio; + } + return [compileExercise(amount), getFunMessage()]; + }).spread(function(exercises, message) { + return postMessage(format(messageTemplate, exercises, (exercises.length > 0) ? message : '')); }).then(function () { console.log("Done!"); }).catch(function (err) { @@ -150,3 +296,5 @@ hours.forEach(function (hour) { timeZone: timezone }); }); + +run(); diff --git a/package.json b/package.json index 3104dbb..b996993 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "async": "^0.9.0", "cron": "^1.0.5", "github": "^0.2.3", + "moment": "^2.9.0", "pluralize": "^1.1.1", "q": "^1.1.2", "slack-node": "0.0.93", From 5eabf934842065da2bf072f009b8db4b612462ad Mon Sep 17 00:00:00 2001 From: Justas Brazauskas Date: Sun, 18 Jan 2015 00:11:27 +0200 Subject: [PATCH 3/9] Removed debug stuff --- main.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/main.js b/main.js index ab7e737..57242c9 100644 --- a/main.js +++ b/main.js @@ -296,5 +296,3 @@ hours.forEach(function (hour) { timeZone: timezone }); }); - -run(); From 90a791a2eaf1e5b70b3ccbc731c0d83e606a71ff Mon Sep 17 00:00:00 2001 From: Justas Brazauskas Date: Mon, 19 Jan 2015 21:02:22 +0200 Subject: [PATCH 4/9] Fix incorrect emoji --- main.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.js b/main.js index 57242c9..f61d2e9 100644 --- a/main.js +++ b/main.js @@ -33,7 +33,7 @@ var funMessages = [ ':heart::cat2:?', ':clap::clap', 'Go play some :basketball:', - 'With :love: from :moon:', + 'With :heart: from :moon:', 'Make some :tea: today.', getRandSlackUserName.bind(undefined, '%s did those faster than you did.'), getRandSlackUserName.bind(undefined, '%s dont you cheat on me.'), From 0653bb9251533f4d4daabb1c7f39c751448da2ee Mon Sep 17 00:00:00 2001 From: Justas Brazauskas Date: Tue, 20 Jan 2015 15:55:29 +0200 Subject: [PATCH 5/9] Added nicer message --- main.js | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/main.js b/main.js index f61d2e9..ca828b5 100644 --- a/main.js +++ b/main.js @@ -12,7 +12,7 @@ var githubApiToken = process.env.GITHUB_API_TOKEN; var channel = process.env.SLACK_CHANNEL || "#general"; var slackIcon = process.env.SLACK_ICON || "http://4.bp.blogspot.com/-9TT2oDIQ00k/TqVViEko4HI/AAAAAAAAADU/svUOHDxP6UM/s1600/T-rex-hates-push-ups.jpg"; var slackUsername = process.env.SLACK_USERNAME || "Swolebot"; -var messageTemplate = "@channel: %s! %s"; +var messageTemplate = "@channel: %s Open Pull Requests (%s old). %s! %s"; var ratio = process.env.RATIO || 1; var hours = (typeof process.env.HOURS !== 'undefined') ? process.env.HOURS.split(',') : [11, 14, 17]; var timezone = process.env.TIMEZONE || "America/New_York"; @@ -170,14 +170,19 @@ function getPRs(user, repo, callback) { state: 'open', per_page: 100 }).then(function (data) { - var num = data.length; + var toReturn = { + prs: data.length, + old: 0, + num: data.length + }; var now = new Date().getTime(); data.forEach(function (pr) { if (moment(pr.created_at).add(5, 'days').format('x') < now) { - num++; + toReturn.num++; + toReturn.old++; } }); - return num; + return toReturn; }); } @@ -265,21 +270,23 @@ function run() { }).then(function (arr) { return q.ninvoke(async, 'map', arr, function (data, callback) { var str = data.split('/'); - getPRs(str[0], str[1]).then(function (nums) { - callback(null, nums); + getPRs(str[0], str[1]).then(function (data) { + callback(null, data); }); }); }).then(function (data) { - var amount = 0; - data.forEach(function (num) { - amount += num; + var amount = 0, prs = 0, old = 0; + data.forEach(function (repo) { + amount += repo.num; + prs += repo.prs; + old += repo.old; }); if (!ratio && Array.isArray(exercises)) { amount = amount * ratio; } - return [compileExercise(amount), getFunMessage()]; - }).spread(function(exercises, message) { - return postMessage(format(messageTemplate, exercises, (exercises.length > 0) ? message : '')); + return [prs, old, compileExercise(amount), getFunMessage()]; + }).spread(function(prs, old, exercises, message) { + return postMessage(format(messageTemplate, prs, old, exercises, (exercises.length > 0) ? message : '')); }).then(function () { console.log("Done!"); }).catch(function (err) { @@ -296,3 +303,5 @@ hours.forEach(function (hour) { timeZone: timezone }); }); + +run(); From f0616a3573740251105d421bda10dd98191c87d2 Mon Sep 17 00:00:00 2001 From: Justas Brazauskas Date: Tue, 20 Jan 2015 15:56:57 +0200 Subject: [PATCH 6/9] Do not run instantly --- main.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/main.js b/main.js index ca828b5..d08949b 100644 --- a/main.js +++ b/main.js @@ -303,5 +303,3 @@ hours.forEach(function (hour) { timeZone: timezone }); }); - -run(); From f871353a18335a141829c053dc84ea4dc2404b48 Mon Sep 17 00:00:00 2001 From: Justas Brazauskas Date: Mon, 2 Feb 2015 10:11:16 +0200 Subject: [PATCH 7/9] Fixed typo --- main.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.js b/main.js index d08949b..8d98568 100644 --- a/main.js +++ b/main.js @@ -31,7 +31,7 @@ var funMessages = [ 'Abort, Retry, Fail?', 'Kernel Panic', ':heart::cat2:?', - ':clap::clap', + ':clap::clap:', 'Go play some :basketball:', 'With :heart: from :moon:', 'Make some :tea: today.', From a8c1b36d970384c22e5f94db7f30c81aa8b85452 Mon Sep 17 00:00:00 2001 From: Justas Brazauskas Date: Mon, 2 Feb 2015 10:38:16 +0200 Subject: [PATCH 8/9] Added random quotes --- main.js | 48 ++++++++++++++++++------------------------------ package.json | 1 + 2 files changed, 19 insertions(+), 30 deletions(-) diff --git a/main.js b/main.js index 8d98568..829a77c 100644 --- a/main.js +++ b/main.js @@ -5,6 +5,7 @@ var pluralize = require('pluralize'); var moment = require('moment'); var CronJob = require('cron').CronJob; var format = require('util').format; +var restler = require('restler'); var q = require('q'); var apiToken = process.env.SLACK_API_TOKEN; @@ -20,28 +21,7 @@ var runInWeekends = (process.env.WEEKENDS) || false; var repos, exercises; var funMessages = [ - 'Keep Pumping!', - ucFirst(slackUsername) + ' :heart: you.', - 'Karma++.', - 'Just a few to go.', - 'Muscles++', - 'Sweat away those pounds.', - 'Do you like me?', - '`undefined is not a function`.', - 'Abort, Retry, Fail?', - 'Kernel Panic', - ':heart::cat2:?', - ':clap::clap:', - 'Go play some :basketball:', - 'With :heart: from :moon:', - 'Make some :tea: today.', - getRandSlackUserName.bind(undefined, '%s did those faster than you did.'), - getRandSlackUserName.bind(undefined, '%s dont you cheat on me.'), - getRandSlackUserName.bind(undefined, '%s does double this time.'), - getRandSlackUserName.bind(undefined, 'Exept %s. They are free this time.'), - getRandSlackUserName.bind(undefined, '%s does not like jumping.'), - getRandSlackUserName.bind(undefined, '%s, did you just leveled up?.'), - getRandSlackUserName.bind(undefined, '%s did those faster than you did.') + getRandQuote ]; if (process.env.EXERCISES) { @@ -92,14 +72,8 @@ function getRandSlackUserName(msg) { return q.ninvoke(slack, 'api', "users.info", { user: user }); - }).then(function (user) { - var name; - user = user.user; - if (user.real_name) { - name = user.real_name; - } else { - name = '@' + user.name; - } + }).then(function (resp) { + var name = '@' + resp.user.name; if (msg) { return format(msg, name); } @@ -107,6 +81,20 @@ function getRandSlackUserName(msg) { }); } +function getRandQuote() { + var def = q.defer(); + restler.get('http://www.iheartquotes.com/api/v1/random', { + query: { + source: 'esr+humorix_misc+humorix_stories+joel_on_software+macintosh+math+mav_flame+osp_rules+paul_graham+prog_style+subversion', + format: 'json', + max_lines: 5 + } + }).on('complete', def.resolve); + return def.promise.then(function (data) { + return '\n\n\n' + data.quote; + }); +} + function getChannelID(name) { if (name.indexOf('#') !== 0) { return q.when(name); diff --git a/package.json b/package.json index b996993..0c45e28 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "moment": "^2.9.0", "pluralize": "^1.1.1", "q": "^1.1.2", + "restler": "^3.2.2", "slack-node": "0.0.93", "time": "^0.11.0" } From a9eadcda77d66bc6e8cf0456a86f5a5016347c34 Mon Sep 17 00:00:00 2001 From: Justas Brazauskas Date: Fri, 17 Apr 2015 09:45:18 +0300 Subject: [PATCH 9/9] Added a way to disable quotes --- main.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/main.js b/main.js index 829a77c..d01156f 100644 --- a/main.js +++ b/main.js @@ -17,6 +17,7 @@ var messageTemplate = "@channel: %s Open Pull Requests (%s old). %s! %s"; var ratio = process.env.RATIO || 1; var hours = (typeof process.env.HOURS !== 'undefined') ? process.env.HOURS.split(',') : [11, 14, 17]; var timezone = process.env.TIMEZONE || "America/New_York"; +var quotesEnabled = process.env.QUOTES === 'true' ? true : false; var runInWeekends = (process.env.WEEKENDS) || false; var repos, exercises; @@ -272,7 +273,7 @@ function run() { if (!ratio && Array.isArray(exercises)) { amount = amount * ratio; } - return [prs, old, compileExercise(amount), getFunMessage()]; + return [prs, old, compileExercise(amount), (quotesEnabled ? getFunMessage() : '')]; }).spread(function(prs, old, exercises, message) { return postMessage(format(messageTemplate, prs, old, exercises, (exercises.length > 0) ? message : '')); }).then(function () {