Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge branch 'master' into fogbugz

Conflicts:
	package.json
  • Loading branch information...
commit 4b478a63bc1c9bbec639c83a59da9914eb13fa07 2 parents 15d2f7f + f694233
@atmos atmos authored
View
13 package.json
@@ -1,12 +1,12 @@
{
"name": "hubot-scripts",
- "version": "1.1.0",
- "author": "GitHub Inc.",
+ "version": "1.1.2",
+ "author": "hubot",
"keywords": "hubot plugin scripts campfire bot robot",
"description": "Allows you to open in to a variety of scripts",
"licenses": [{
"type": "MIT",
- "url": "http://github.com/github/hubt-scripts/raw/master/LICENSE"
+ "url": "http://github.com/github/hubot-scripts/raw/master/LICENSE"
}],
"repository" : {
@@ -15,9 +15,12 @@
},
"dependencies": {
- "hubot": ">= 1.0.4",
+ "hubot": ">= 1.1.2",
"redis": "0.6.7",
- "xml2js": "0.1.x"
+ "jsdom": "==0.2.0",
+ "xml2js": "0.1.x",
+ "soupselect": "0.2.0",
+ "htmlparser": "1.7.x"
},
"directories": {
View
24 src/scripts/dnsimple.coffee
@@ -0,0 +1,24 @@
+# Domain availability via DNSimple, requires you set
+# DNSIMPLE_USERNAME & DNSIMPLE_PASSWORD environment variables
+#
+# check domain <domainname> - returns whether a domain is available
+#
+
+module.exports = (robot) ->
+ robot.hear /check domain (.*)/i, (msg) ->
+ domain = escape(msg.match[1])
+ user = process.env.DNSIMPLE_USERNAME
+ pass = process.env.DNSIMPLE_PASSWORD
+ auth = 'Basic ' + new Buffer(user + ':' + pass).toString('base64');
+ msg.http("https://dnsimple.com/domains/#{domain}/check")
+ .headers(Authorization: auth, Accept: 'application/json')
+ .get() (err, res, body) ->
+ switch res.statusCode
+ when 200
+ msg.send "Sorry, #{domain} is not available."
+ when 404
+ msg.send "Cybersquat that shit!"
+ when 401
+ msg.send "You need to authenticate by setting the DNSIMPLE_USERNAME & DNSIMPLE_PASSWORD environment variables"
+ else
+ msg.send "Unable to process your request and we're not sure why :("
View
33 src/scripts/eight-ball.coffee
@@ -0,0 +1,33 @@
+# The Magic Eight ball
+#
+# eightball <query> - Ask the magic eight ball a question
+#
+
+ball = [
+ "It is certain",
+ "It is decidedly so",
+ "Without a doubt",
+ "Yes – definitely",
+ "You may rely on it",
+ "As I see it, yes",
+ "Most likely",
+ "Outlook good",
+ "Signs point to yes",
+ "Yes",
+ "Reply hazy, try again",
+ "Ask again later",
+ "Better not tell you now",
+ "Cannot predict now",
+ "Concentrate and ask again",
+ "Don't count on it",
+ "My reply is no",
+ "My sources say no",
+ "Outlook not so good",
+ "Very doubtful",
+]
+
+module.exports = (robot) ->
+ robot.respond /(eightball|8ball)(.*)/i, (msg) ->
+ msg.send msg.random ball
+
+
View
19 src/scripts/gemwhois.coffee
@@ -0,0 +1,19 @@
+# Whois for gems, because gem names are like domains in the 90's
+#
+# gem whois <gemname> - returns gem details if it exists
+#
+
+module.exports = (robot) ->
+ robot.respond /gem whois (.*)/i, (msg) ->
+ gemname = escape(msg.match[1])
+ msg.http("http://rubygems.org/api/v1/gems/#{gemname}.json")
+ .get() (err, res, body) ->
+ try
+ json = JSON.parse(body)
+ msg.send " gem name: #{json.name}\n
+ owners: #{json.authors}\n
+ info: #{json.info}\n
+ version: #{json.version}\n
+ downloads: #{json.downloads}\n"
+ catch err
+ msg.send "Gem not found. It will be mine. Oh yes. It will be mine. *sinister laugh*"
View
9 src/scripts/giftv.coffee
@@ -0,0 +1,9 @@
+# Return random animated GIFs from giftv.
+#
+# giftv me - Returns a random animated GIF.
+module.exports = (robot) ->
+ robot.respond /giftv( me)?$/i, (msg) ->
+ msg
+ .http('http://www.gif.tv/gifs/get.php')
+ .get() (err, res, body) ->
+ msg.send 'http://www.gif.tv/gifs/' + body + '.gif' || 'Could not compute.'
View
27 src/scripts/github-issues.coffee
@@ -0,0 +1,27 @@
+# Show open issues from a Github repository.
+#
+# You need to set the following variables:
+# HUBOT_GITHUB_TOKEN ="<oauth token>"
+# HUBOT_GITHUB_USER ="<user name>"
+#
+# HUBOT_GITHUB_USER is optional, but if you set it, you can ask `show me issues
+# for hubot` instead of `show me issues for github/hubot`.
+#
+# show me issues for <user/repo> -- Shows open issues for that project.
+module.exports = (robot) ->
+ robot.respond /show\s+(me\s+)?issues\s+(for\s+)?(.*)/i, (msg)->
+ oauth_token = process.env.HUBOT_GITHUB_TOKEN
+ repo = msg.match[3].toLowerCase()
+ repo = "#{process.env.HUBOT_GITHUB_USER}/#{repo}" unless ~repo.indexOf("/")
+ msg.http("https://api.github.com/repos/#{repo}/issues")
+ .headers(Authorization: "token #{oauth_token}", Accept: "application/json")
+ .query(state: "open", sort: "created")
+ .get() (err, res, body) ->
+ if err
+ msg.send "GitHub says: #{err}"
+ return
+ issues = JSON.parse(body)
+ for issue in issues
+ labels = ("##{label.name}" for label in issue.labels)
+ msg.send "[#{issue.number}] #{issue.title} #{labels.join(" ")}"
+
View
8 src/scripts/hideyakids.coffee
@@ -0,0 +1,8 @@
+# Antoine Dodson's greatest hits... errr... only hit
+#
+# hide ya kids - Hide `em!
+#
+
+module.exports = (robot) ->
+ robot.hear /hide ya kids/i, (msg) ->
+ msg.send "http://www.youtube.com/watch?v=hMtZfW2z9dw"
View
14 src/scripts/likeaboss.coffee
@@ -0,0 +1,14 @@
+# LIKE A BOSS
+#
+
+images = [
+ "http://s3.amazonaws.com/kym-assets/photos/images/original/000/114/151/14185212UtNF3Va6.gif?1302832919",
+ "http://s3.amazonaws.com/kym-assets/photos/images/newsfeed/000/110/885/boss.jpg",
+ "http://verydemotivational.files.wordpress.com/2011/06/demotivational-posters-like-a-boss.jpg",
+ "http://assets.head-fi.org/b/b3/b3ba6b88_funny-facebook-fails-like-a-boss3.jpg",
+ "http://img.anongallery.org/img/6/0/like-a-boss.jpg",
+ ]
+
+module.exports = (robot) ->
+ robot.hear /like a boss/i, (msg) ->
+ msg.send msg.random images
View
16 src/scripts/lolz.coffee
@@ -0,0 +1,16 @@
+# lulz - BRING THE LOLZ from bukk.it
+
+Select = require("soupselect").select
+HtmlParser = require "htmlparser"
+
+module.exports = (robot) ->
+ robot.respond /.*l[ou]lz/i, (msg) ->
+ msg.http("http://bukk.it")
+ .get() (err, res, body) ->
+ handler = new HtmlParser.DefaultHandler()
+ parser = new HtmlParser.Parser handler
+
+ parser.parseComplete body
+
+ results = ("http://bukk.it/#{link.attribs.href}" for link in Select handler.dom, "td a")
+ msg.send msg.random results
View
67 src/scripts/meme_generator.coffee
@@ -0,0 +1,67 @@
+# Integrates with memegenerator.net
+#
+# Y U NO <text> - Generates the Y U NO GUY with the bottom caption
+# of <text>
+#
+# I don't always <something>
+# but when I do <text> - Generates The Most Interesting man in the World
+#
+# <text> ORLY? - Generates the ORLY? owl with the top caption of <text>
+#
+# <text> (SUCCESS|NAILED IT) - Generates success kid with the top caption of <text>
+#
+
+module.exports = (robot) ->
+ robot.respond /Y U NO (.+)/i, (msg) ->
+ caption = msg.match[1] || ""
+
+ memeGenerator msg, 2, 166088, "Y U NO", caption, (url) ->
+ msg.send url
+
+ robot.respond /(I DON'?T ALWAYS .*) (BUT WHEN I DO .*)/i, (msg) ->
+ memeGenerator msg, 74, 2485, msg.match[1], msg.match[2], (url) ->
+ msg.send url
+
+ robot.respond /(.*)(O\s?RLY\??.*)/i, (msg) ->
+ memeGenerator msg, 920, 117049, msg.match[1], msg.match[2], (url) ->
+ msg.send url
+
+ robot.respond /(.*)(SUCCESS|NAILED IT.*)/i, (msg) ->
+ memeGenerator msg, 121, 1031, msg.match[1], msg.match[2], (url) ->
+ msg.send url
+
+ robot.respond /(.*) (ALL the .*)/, (msg) ->
+ memeGenerator msg, 6013, 1121885, msg.match[1], msg.match[2], (url) ->
+ msg.send url
+
+memeGenerator = (msg, generatorID, imageID, text0, text1, callback) ->
+ username = process.env.HUBOT_MEMEGEN_USERNAME
+ password = process.env.HUBOT_MEMEGEN_PASSWORD
+
+ unless username
+ msg.send "MemeGenerator username isn't set. Sign up at http://memegenerator.net"
+ msg.send "Then set the HUBOT_MEMEGEN_USERNAME environment variable"
+ return
+
+ unless password
+ msg.send "MemeGenerator password isn't set. Sign up at http://memegenerator.net"
+ msg.send "Then set the HUBOT_MEMEGEN_PASSWORD environment variable"
+ return
+
+ msg.http('http://version1.api.memegenerator.net/Instance_Create')
+ .query
+ username: username,
+ password: password,
+ languageCode: 'en',
+ generatorID: generatorID,
+ imageID: imageID,
+ text0: text0,
+ text1: text1
+ .get() (err, res, body) ->
+ result = JSON.parse(body)['result']
+ instanceURL = result['instanceUrl']
+ img = "http://memegenerator.net" + result['instanceImageUrl']
+
+ msg.http(instanceURL).get() (err, res, body) ->
+ # Need to hit instanceURL so that image gets generated
+ callback img
View
17 src/scripts/polite.coffee
@@ -0,0 +1,17 @@
+# Polite.
+#
+# Say thanks to your robot.
+
+responses = [
+ "You're welcome",
+ "No problem",
+ "Anytime",
+ "That's what I'm here for!",
+ "You are more than welcome",
+ "You don't have to thank me, I'm your loyal servant",
+ "Don't mention it."
+]
+
+module.exports = (robot) ->
+ robot.respond /(thanks|thank you|cheers|nice one)/i, (msg) ->
+ msg.send msg.random responses
View
2  src/scripts/redis-brain.coffee
@@ -22,7 +22,7 @@ module.exports = (robot) ->
robot.brain.mergeData JSON.parse(reply.toString())
robot.brain.on 'save', (data) ->
- client.set 'hubot:storage', data
+ client.set 'hubot:storage', JSON.stringify data
robot.brain.on 'close', ->
client.quit()
View
26 src/scripts/redis_brain.coffee
@@ -1,26 +0,0 @@
-# sets up hooks to persist the brain into redis.
-module.exports = (robot) ->
- info = Url.parse process.env.REDISTOGO_URL || 'redis://localhost:6379'
- client = Redis.createClient(info.port, info.hostname)
-
- if info.auth
- client.auth info.auth.split(":")[1]
-
- client.on "error", (err) ->
- console.log "Error #{err}"
-
- client.on "connect", ->
- console.log "Successfully connected to Redis"
-
- client.get "hubot:storage", (err, reply) ->
- if err
- throw err
- else if reply
- robot.brain.mergeData JSON.parse(reply.toString())
-
- robot.brain.on 'save', (data) ->
- client.set 'hubot:storage', data
-
- robot.brain.on 'close', ->
- client.quit()
-
View
30 src/scripts/spotify.coffee
@@ -0,0 +1,30 @@
+# Metadata lookup for spotify links
+#
+# <spotify link> - returns info about the link (track, artist, etc.)
+#
+
+module.exports = (robot) ->
+ robot.hear spotify.link, (msg) ->
+ msg.http(spotify.uri msg.match[0]).get() (err, res, body) ->
+ if res.statusCode is 200
+ data = JSON.parse(body)
+ msg.send spotify[data.info.type](data)
+
+spotify =
+ link: /// (
+ ?: http://open.spotify.com/(track|album|artist)/
+ | spotify:(track|album|artist):
+ ) \S+ ///
+
+ uri: (link) -> "http://ws.spotify.com/lookup/1/.json?uri=#{link}"
+
+ track: (data) ->
+ track = "#{data.track.artists[0].name} - #{data.track.name}"
+ album = "(#{data.track.album.name}) (#{data.track.album.released})"
+ "Track: #{track} #{album}"
+
+ album: (data) ->
+ "Album: #{data.album.artist} - #{data.album.name} (#{data.album.released})"
+
+ artist: (data) ->
+ "Artist: #{data.artist.name}"
View
33 src/scripts/teamcity.coffee
@@ -0,0 +1,33 @@
+# Show status of 3 most recent builds.
+#
+# You need to set the following variables:
+# HUBOT_TEAMCITY_USERNAME = <user name>
+# HUBOT_TEAMCITY_PASSWORD = <password>
+# HUBOT_TEAMCITY_HOSTNAME = <host : port>
+#
+# show me builds -- Show status of currently running builds
+module.exports = (robot) ->
+ robot.respond /show (me )?builds/i, (msg) ->
+ username = process.env.HUBOT_TEAMCITY_USERNAME
+ password = process.env.HUBOT_TEAMCITY_PASSWORD
+ hostname = process.env.HUBOT_TEAMCITY_HOSTNAME
+ msg.http("http://#{hostname}/app/rest/builds")
+ .query(locator: ["running:any", "count:3"].join(","))
+ .headers(Authorization: "Basic #{new Buffer("#{username}:#{password}").toString("base64")}", Accept: "application/json")
+ .get() (err, res, body) ->
+ if err
+ msg.send "Team city says: #{err}"
+ return
+ # Sort by build number.
+ builds = JSON.parse(body).build.sort((a, b)-> parseInt(b.number) - parseInt(a.number))
+ for build in builds
+ if build.running
+ started = Date.parse(build.startDate.replace(/(\d{4})(\d{2})(\d{2})T(\d{2})(\d{2})(\d{2})([+\-]\d{4})/, "$1-$2-$3T$4:$5:$6$7"))
+ elapsed = (Date.now() - started) / 1000
+ seconds = "" + Math.floor(elapsed % 60)
+ seconds = "0#{seconds}" if seconds.length < 2
+ msg.send "#{build.number}, #{build.percentageComplete}% complete, #{Math.floor(elapsed / 60)}:#{seconds} minutes"
+ else if build.status is "SUCCESS"
+ msg.send "#{build.number} is full of win"
+ else if build.status is "FAILUED"
+ msg.send "#{build.number} is #fail"
View
59 src/scripts/weather.coffee
@@ -0,0 +1,59 @@
+# Get some weather action!
+#
+# weather <city> - Get the weather for a location
+# forecast <city> - Get the forecast for a location
+JsDom = require 'jsdom'
+
+module.exports = (robot) ->
+ robot.respond /forecast(?: me)?\s(.*)/, (msg) ->
+ query msg, (body, err) ->
+ return msg.send err if err
+
+ strings = []
+ for element in body.getElementsByTagName('forecast_conditions')
+ day = element.getElementsByTagName('day_of_week')[0].getAttribute('data');
+ low = element.getElementsByTagName('low')[0].getAttribute('data');
+ high = element.getElementsByTagName('high')[0].getAttribute('data');
+ condition = element.getElementsByTagName('condition')[0].getAttribute('data');
+ strings.push "#{day} #{condition} high of: #{convertTemp(high)} low of: #{convertTemp(low)}"
+
+ msg.send strings.join "\n"
+
+ robot.respond /weather(?: me)?\s(.*)/, (msg) ->
+ query msg, (body, err) ->
+ return msg.send err if err
+
+ city = body.getElementsByTagName('city')[0];
+ return msg.send 'No city -> no weather.' if not city or not city.getAttribute
+
+ strings = []
+ strings.push "Weather for #{city.getAttribute('data')}"
+ currentCondition = body.getElementsByTagName('current_conditions')[0];
+ conditions = currentCondition.getElementsByTagName('condition')[0];
+ temp = currentCondition.getElementsByTagName('temp_c')[0];
+ humidity = currentCondition.getElementsByTagName('humidity')[0];
+
+ strings.push("Current conditions: #{conditions.getAttribute('data')} " +
+ "#{temp.getAttribute('data')}ºc")
+
+ strings.push humidity.getAttribute('data')
+ msg.send strings.join "\n"
+
+ getDom = (xml) ->
+ body = JsDom.jsdom(xml)
+ throw Error('No xml') if body.getElementsByTagName('weather')[0].childNodes.length == 0
+ body
+
+ convertTemp = (faren) ->
+ ((5 / 9) * (faren - 32)).toFixed 0
+
+ query = (msg, cb) ->
+ location = msg.match[1]
+ msg.http('http://www.google.com/ig/api')
+ .query(weather: location)
+ .get() (err, res, body) ->
+ try
+ body = getDom body
+ catch err
+ err = 'Could not fetch weather data :('
+ cb(body, err)
Please sign in to comment.
Something went wrong with that request. Please try again.