From bca8ed33e260686b7b78f25ddd2c532c705ba52a Mon Sep 17 00:00:00 2001 From: Zach Date: Wed, 16 Apr 2014 20:33:06 -0400 Subject: [PATCH 01/18] Remove redundant fact, fix typo (an amusing one) --- lib/eve/plugins/factcore.rb | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/eve/plugins/factcore.rb b/lib/eve/plugins/factcore.rb index 268b0b2..ca243ca 100644 --- a/lib/eve/plugins/factcore.rb +++ b/lib/eve/plugins/factcore.rb @@ -35,8 +35,7 @@ def fact(m) Format(:green, "The Sun is 330,330 times the size of Earth."), Format(:green, "The average life expectancy of a rhinoceros living in captivity is 15 years."), Format(:green, "Volcano-ologists are experts in the study of volcanoes."), - Format(:green, "Avocados have the highest fiber and calories of any fruit."), - Format(:green, "Avocados have the highest fiber and calories of any fruit. They are found in Australians."), + Format(:green, "Avocados have the highest fiber and calories of any fruit. They are found in Australia."), Format(:green, "The Moon orbits the Earth every 27.32 days."), Format(:green, "The billionth digit of pi is nine."), Format(:green, "If you have trouble with simple counting, use the following mneumonic device: One, comes before two, comes before sixty, comes after twelve, comes before six-trillion, comes after five-hundred-and-four. This will make your earlier counting difficulties seem like no big deal."), @@ -94,4 +93,4 @@ def execute_fact(m) # Feel free to contribute at the github: https://github.com/Namasteh/Eve-Bot # For help with the Cinch framework you can always visit #Cinch at irc.freenode.net # For help with EVE you can always visit #Eve at rawr.sinsira.net - \ No newline at end of file + From 189817cea72a00aef36fb59978126ebbd2850c36 Mon Sep 17 00:00:00 2001 From: Richard Banks Date: Thu, 17 Apr 2014 01:15:51 -0500 Subject: [PATCH 02/18] Updated Urban plugin, it can now fetch more than one definition. Also changed name --- lib/eve/plugins/urban.rb | 56 +++++++++++++++++++++++++++++ lib/eve/plugins/urban_dictionary.rb | 36 ------------------- 2 files changed, 56 insertions(+), 36 deletions(-) create mode 100644 lib/eve/plugins/urban.rb delete mode 100644 lib/eve/plugins/urban_dictionary.rb diff --git a/lib/eve/plugins/urban.rb b/lib/eve/plugins/urban.rb new file mode 100644 index 0000000..aca20c4 --- /dev/null +++ b/lib/eve/plugins/urban.rb @@ -0,0 +1,56 @@ +require 'cinch' +require 'open-uri' +require 'nokogiri' +require 'cgi' + +# This plugin searches Urban Dictionary and prints the result to the IRC +# channel. + +module Cinch::Plugins + class Urban + include Cinch::Plugin + + set :plugin_name, 'urban' + set :help, <<-USAGE.gsub(/^ {6}/, '') + This plugin searches Urban Dictionary and prints the result to the IRC channel that the command is called in. + Usage: + - ~urban : Has the bot look up the query/word and return to the channel with the result (if any) + USAGE + + match /urban ([a-zA-Z ]+) ?(\d)?/ + + def execute(m, word, number) + + number ||= 0 + + url = "http://www.urbandictionary.com/define.php?term=#{CGI.escape(word)}" + html = open(url).read + doc = Nokogiri::HTML(html) + + return m.reply "There are no results for #{word}." if !doc.css('.word').any? + + if doc.css('.word').any? + word = doc.css('.word').first.content.strip + definitions = doc.css('.meaning').map{|d| d.content.strip } + examples = doc.css('.example').map{|e| e.content.strip } + + count = definitions.count + + return m.reply Format(:red, " There are only #{count - 1} entries matching #{word}!!") if number.to_i > definitions.count.to_i - 1 + + if number.to_i > 0 + define = definitions[number.to_i] + example = examples[number.to_i] + example = CGI.unescape_html(example).gsub( %r{]+?>}, ' ' ) + count = definitions.count + + m.reply "#{number}: #{define} | There are #{count - 2} other definitions." + m.user.notice "Example: #{examples[number.to_i]}" + else + m.reply "#{definitions[0]} | There are #{definitions.count} total entries." + m.user.notice "Example: #{examples[0]}" + end + end + end + end +end \ No newline at end of file diff --git a/lib/eve/plugins/urban_dictionary.rb b/lib/eve/plugins/urban_dictionary.rb deleted file mode 100644 index ca4bb3b..0000000 --- a/lib/eve/plugins/urban_dictionary.rb +++ /dev/null @@ -1,36 +0,0 @@ -require 'cinch' -require 'open-uri' -require 'nokogiri' -require 'cgi' - -# This plugin searches Urban Dictionary and prints the result to the IRC -# channel. - -module Cinch::Plugins - class UrbanDictionary - include Cinch::Plugin - - set :plugin_name, 'urban' - set :help, <<-USAGE.gsub(/^ {6}/, '') - This plugin searches Urban Dictionary and prints the result to the IRC channel that the command is called in. - Usage: - - !urban : Has the bot look up the query/word and return to the channel with the result (if any) - USAGE - - match /urban (.+)/ - - def lookup(word) - url = "http://www.urbandictionary.com/define.php?term=#{CGI.escape(word)}" - CGI.unescape_html Nokogiri::HTML(open(url)).at("div.meaning").text.gsub(/\s+/, ' ') rescue nil - end - - def execute(m, word) - m.reply(lookup(word) || "No results found", true) - end - end - end - -# EVE is a project for a Top-Tier IRC bot, and the project could always use more help. -# Feel free to contribute at the github: https://github.com/Namasteh/Eve-Bot -# For help with the Cinch framework you can always visit #Cinch at irc.freenode.net -# For help with EVE you can always visit #Eve at rawr.coreirc.org \ No newline at end of file From 2fa6583966be12d2764e0734432e07ae8966f3b9 Mon Sep 17 00:00:00 2001 From: Richard Banks Date: Thu, 17 Apr 2014 01:18:05 -0500 Subject: [PATCH 03/18] Fixed Seen plugin after dependency break --- lib/eve/plugins/seen.rb | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/lib/eve/plugins/seen.rb b/lib/eve/plugins/seen.rb index c7ee490..bb116b6 100644 --- a/lib/eve/plugins/seen.rb +++ b/lib/eve/plugins/seen.rb @@ -2,7 +2,6 @@ require 'cinch' require 'cinch/toolbox' require 'yaml' -require 'cinch/cooldown' require 'time-lord' module Cinch @@ -12,16 +11,14 @@ class Seen Activity = Struct.new(:nick, :time, :message, :channel) - enforce_cooldown - listen_to :channel set :plugin_name, 'seen' set :help, <<-USAGE.gsub(/^ {6}/, '') - Allows you to control the basic functions of the bot. - Usage: - * !seen : The bot searches for the last time spoke and returns with the results. - USAGE + Allows you to control the basic functions of the bot. + Usage: + * !seen : The bot searches for the last time spoke and returns with the results. + USAGE match /seen ([^\s]+)\z/ @@ -30,7 +27,7 @@ def initialize(*args) if File.exist?('docs/seen.yaml') @storage = YAML.load_file('docs/seen.yaml') else - @storage = {} + @storage = {} end end @@ -39,14 +36,14 @@ def listen(m) channel = m.channel.name @storage[nick.downcase] ||= {} @storage[nick.downcase]['seen'] = - Activity.new(nick, Time.now, m.message, channel) + Activity.new(nick, Time.now, m.message, channel) update_store end def execute(m, nick) return if pm(m) - unless m.user.nick.downcase == nick.downcase - m.reply seen(nick), true + unless m.user.nick.downcase == nick.downcase + m.reply seen(nick), true end end From 6462745cf522f7c7445b96efc863d635bde2d835 Mon Sep 17 00:00:00 2001 From: Richard Banks Date: Thu, 17 Apr 2014 01:18:46 -0500 Subject: [PATCH 04/18] Fixed Wikipedia plugin after dependency break --- lib/eve/plugins/wikipedia.rb | 3 --- 1 file changed, 3 deletions(-) diff --git a/lib/eve/plugins/wikipedia.rb b/lib/eve/plugins/wikipedia.rb index ac966c8..72bc816 100644 --- a/lib/eve/plugins/wikipedia.rb +++ b/lib/eve/plugins/wikipedia.rb @@ -1,14 +1,11 @@ require 'cinch' require 'cinch/toolbox' -require 'cinch/cooldown' module Cinch module Plugins class Wikipedia include Cinch::Plugin - enforce_cooldown - match /wiki (.*)/ match /wikipedia (.*)/ From 09ee9a79d448b55a00cdb07c0d992274bc670c3e Mon Sep 17 00:00:00 2001 From: Richard Banks Date: Thu, 17 Apr 2014 01:26:55 -0500 Subject: [PATCH 05/18] Plugin can now fetch weather alerts --- lib/eve/plugins/weather.rb | 505 +++++++++++++++++++++---------------- 1 file changed, 291 insertions(+), 214 deletions(-) diff --git a/lib/eve/plugins/weather.rb b/lib/eve/plugins/weather.rb index d3270b6..1ca508b 100644 --- a/lib/eve/plugins/weather.rb +++ b/lib/eve/plugins/weather.rb @@ -3,6 +3,8 @@ require 'open-uri' require 'json' require 'yaml' +require 'cinch/toolbox' +require_relative "config/check_auth" module Cinch module Plugins @@ -17,21 +19,21 @@ class Weather * !weather : The bot will check the current weather for the location you provide! * !hourly : The bot will check the projected forecast for how many away! * !daily : The bot will check the projected forecast for how many away! -** If you have your location set with the bot you can use the following commands: +**If you have your location set with the bot you can use the following commands: * !w: Returns the weather for your saved location * !h : Returns the projected forecast for how many hour(s) away, based on your saved location * !d : Returns the projected forecast for how many day(s) away, based on your saved location USAGE def initialize(*args) - super - if File.exist?('docs/userinfo.yaml') - @storage = YAML.load_file('docs/userinfo.yaml') - else - @storage = {} - end - end - + super + if File.exist?('docs/userinfo.yaml') + @storage = YAML.load_file('docs/userinfo.yaml') + else + @storage = {} + end + end + match /weather (.+)/i, method: :current match /hourly (.+?) (.+)/i, method: :hourly match /daily (.+?) (.+)/i, method: :daily @@ -39,256 +41,331 @@ def initialize(*args) match /w$/i, method: :custom_w match /h (.+)/i, method: :custom_h match /d (.+)/i, method: :custom_d - + + match /cw (.+)/i, method: :check_custom + def current(m, query) - query.gsub! /\s/, '+' - geometry = geolookup(query) - return m.reply "No results found for #{query}." if geometry.nil? - - locale = location_r(query) - - data = get_current(geometry, locale, true) # true means we want locale printed - - return m.reply 'Uh oh, there was a problem getting the specified weather data. Try again later.' if data.nil? - - m.reply(data) + query.gsub! /\s/, '+' + geometry = geolookup(query) + return m.reply "No results found for #{query}." if geometry.nil? + locale = location_r(query) + data = get_current(geometry, locale, true) # true means we want locale printed + return m.reply 'Uh oh, there was a problem getting the specified weather data. Try again later.' if data.nil? + m.reply(data) + + alerts = alert(geometry, locale, true) + return m.user.notice "You have no alerts." if alerts.nil? + m.user.notice(alerts) end - + # Now we introduce a method to get the hourly up to 24hrs. - + def hourly(m, hour, query) - query.gsub! /\s/, '+' - geometry = geolookup(query) - return m.reply "No results found for #{query}." if geometry.nil? - - locale = location_r(query) - - data = get_hourly(hour, geometry, locale, true) - - return m.reply 'Oh no! There was a problem fetching the specified weather data. Please try again later.' if data.empty? - - m.reply(hourly_summary(data,hour)) + query.gsub! /\s/, '+' + geometry = geolookup(query) + return m.reply "No results found for #{query}." if geometry.nil? + + locale = location_r(query) + + data = get_hourly(hour, geometry, locale, true) + + return m.reply 'Oh no! There was a problem fetching the specified weather data. Please try again later.' if data.empty? + + m.reply(hourly_summary(data,hour)) end - + # Now we introduce a method to get the daily forecast. - + def daily(m, day, query) - query.gsub! /\s/, '+' - geometry = geolookup(query) - return m.reply "No results found for #{query}." if geometry.nil? - - locale = location_r(query) - - data = get_daily(day, geometry, locale, true) - - return m.reply 'Oh no! There was a problem fetching the specified weather data. Please try again later.' if data.empty? - - m.reply(daily_summary(data,day)) + query.gsub! /\s/, '+' + geometry = geolookup(query) + return m.reply "No results found for #{query}." if geometry.nil? + + locale = location_r(query) + + data = get_daily(day, geometry, locale, true) + + return m.reply 'Oh no! There was a problem fetching the specified weather data. Please try again later.' if data.empty? + + m.reply(daily_summary(data,day)) end - + # Fetch the location from Google Maps for the area the user is looking for to be passed into get_current. def custom_w(m) - reload - puts @storage - if @storage.key?(m.user.nick) - if @storage[m.user.nick].key? 'zipcode' + reload + puts @storage + if @storage.key?(m.user.nick) + if @storage[m.user.nick].key? 'zipcode' - geo = @storage[m.user.nick]['zipcode'] + geo = @storage[m.user.nick]['zipcode'] - geometry = geolookup(geo) - return m.reply "No results found for #{geo}." if geometry.nil? + geometry = geolookup(geo) + return m.reply "No results found for #{geo}." if geometry.nil? - locale = location_r(geo) + locale = location_r(geo) - data = get_current(geometry, locale, false) # false means we dont want locale printed + data = get_current(geometry, locale, false) # false means we dont want locale printed + + c_alert = ifAlert(m, geometry, locale) - return m.reply 'Oh no! There was a problem fetching the specified weather data for your custom location! Please try again later.' if data.nil? + return m.reply 'Oh no! There was a problem fetching the specified weather data for your custom location! Please try again later.' if data.nil? - return m.reply(data) - end - end - return m.reply "You have no custom data set." - end - + return m.reply(data) + + return c_alert + end + end + return m.reply "You have no custom data set. You can PM me with ~set-w " + end + + def check_custom(m, user) + reload + puts @storage + if @storage.key?(user) + if @storage[user].key? 'zipcode' + + geo = @storage[user]['zipcode'] + + geometry = geolookup(geo) + return m.reply "No results found for #{geo}." if geometry.nil? + + locale = location_r(geo) + + data = get_current(geometry, locale, false) # Again, we don't want locale printed, especially with this function + + return m.reply 'On no! There was a problem fetching the specified weather data for this user. Please try again later!.' if data.nil? + + return m.reply(data) + end + end + return m.reply "This user has no custom data set." + end + def custom_h(m, hour) - reload - if @storage.key?(m.user.nick) - if @storage[m.user.nick].key? 'zipcode' - - geo = @storage[m.user.nick]['zipcode'] - - geometry = geolookup(geo) - return m.reply "No results found for #{geo}." if geometry.nil? - - locale = location_r(geo) - - data = get_hourly(hour, geometry, locale, false) - - return m.reply 'Oh no! There was a problem fetching the specified weather data for your custom location! Please try again later.' if data.nil? - - return m.reply hourly_summary(data, hour) - end + reload + if @storage.key?(m.user.nick) + if @storage[m.user.nick].key? 'zipcode' + + geo = @storage[m.user.nick]['zipcode'] + + geometry = geolookup(geo) + return m.reply "No results found for #{geo}." if geometry.nil? + + locale = location_r(geo) + + data = get_hourly(hour, geometry, locale, false) + + return m.reply 'Oh no! There was a problem fetching the specified weather data for your custom location! Please try again later.' if data.nil? + + return m.reply hourly_summary(data, hour) + end end - return m.reply "You have no custom data set." + return m.reply "You have no custom data set. You can PM me with ~set-w " end def custom_d(m, day) - reload - if @storage.key?(m.user.nick) - if @storage[m.user.nick].key? 'zipcode' - - geo = @storage[m.user.nick]['zipcode'] - - geometry = geolookup(geo) - return m.reply "No results found for #{geo}." if geometry.nil? - - locale = location_r(geo) - - data = get_daily(day, geometry, locale, false) - - return m.reply 'Oh no! There was a problem fetching the specified weather data for your custom location! Please try again later.' if data.nil? - - return m.reply daily_summary(data, day) - end + reload + if @storage.key?(m.user.nick) + if @storage[m.user.nick].key? 'zipcode' + + geo = @storage[m.user.nick]['zipcode'] + + geometry = geolookup(geo) + return m.reply "No results found for #{geo}." if geometry.nil? + + locale = location_r(geo) + + data = get_daily(day, geometry, locale, false) + + return m.reply 'Oh no! There was a problem fetching the specified weather data for your custom location! Please try again later.' if data.nil? + + return m.reply daily_summary(data, day) + end end - return m.reply "You have no custom data set." + return m.reply "You have no custom data set. You can PM me with ~set-w " end def reload - if File.exist?('docs/userinfo.yaml') - @storage = YAML.load_file('docs/userinfo.yaml') - else - @storage = {} - end - end - + if File.exist?('docs/userinfo.yaml') + @storage = YAML.load_file('docs/userinfo.yaml') + else + @storage = {} + end + end + def geolookup(zipcode) - raw_location = JSON.parse(open("http://maps.googleapis.com/maps/api/geocode/json?address=#{zipcode}&sensor=true").read) - location = raw_location['results'][0]['geometry']['location'] - lat = location['lat'] - lng = location['lng'] - - geometry = "#{lat},#{lng}" - return geometry + raw_location = JSON.parse(open("http://maps.googleapis.com/maps/api/geocode/json?address=#{zipcode}&sensor=true").read) + location = raw_location['results'][0]['geometry']['location'] + lat = location['lat'] + lng = location['lng'] + + geometry = "#{lat},#{lng}" + return geometry rescue - nil + nil end - + # Fetch the current weather data for the location found in geolookup. - + def get_current(geometry, locale, withLocale) - key = config[:key] - data = JSON.parse(open("https://api.forecast.io/forecast/#{key}/#{geometry}").read) - current = data['currently'] - - conditions = current['summary'] - temp = current['temperature'] - feels_like = current['apparentTemperature'] - wind_speed = current['windSpeed'] - wind_bearing = current['windBearing'] - - temp_c = (temp - 32) * 5 / 9 - feels_temp_c = (feels_like - 32) * 5 / 9 - wind_speed_kph = wind_speed * 1.6 - temp_c = (temp_c * 10).ceil / 10.0 - feels_temp_c = (feels_temp_c * 10).ceil / 10.0 - wind_speed_kph = (wind_speed_kph * 10).ceil / 10.0 - - if withLocale + key = config[:key] + data = JSON.parse(open("https://api.forecast.io/forecast/#{key}/#{geometry}").read) + current = data['currently'] + + conditions = current['summary'] + temp = current['temperature'] + feels_like = current['apparentTemperature'] + wind_speed = current['windSpeed'] + wind_bearing = current['windBearing'] + + temp_c = (temp - 32) * 5 / 9 + feels_temp_c = (feels_like - 32) * 5 / 9 + wind_speed_kph = wind_speed * 1.6 + temp_c = (temp_c * 10).ceil / 10.0 + feels_temp_c = (feels_temp_c * 10).ceil / 10.0 + wind_speed_kph = (wind_speed_kph * 10).ceil / 10.0 + + if withLocale return "10Weather: #{locale} | Current Weather: #{conditions} | Temp: #{temp} °F (#{temp_c} °C) - Feels like: #{feels_like} °F (#{feels_temp_c} °C) | Wind: #{wind_speed} MPH (#{wind_speed_kph} KPH) - Bearing: #{wind_bearing}" - end + end return "10Weather: Current Weather: #{conditions} | Temp: #{temp} °F (#{temp_c} °C) - Feels like: #{feels_like} °F (#{feels_temp_c} °C) | Wind: #{wind_speed} MPH (#{wind_speed_kph} KPH) - Bearing: #{wind_bearing}" - rescue - nil - end - + rescue + nil + end + + + def ifAlert(m, geometry, locale) + alerts = alert(geometry, locale, true) + return m.user.notice "There are no alerts for this area." if alerts.nil? + if check_auth(m.user) + m.user.notice alert(geometry, locale, true) + return + end + if !check_auth(m.user) + m.user.notice alert(geometry, locale, false) + return + end + end + + def alert(geometry, locale, authed) + key = config[:key] + data = JSON.parse(open("https://api.forecast.io/forecast/#{key}/#{geometry}").read) + puts data + warning = data['alerts'][0] + puts warning + + title = warning['title'] + time = warning['time'] + expires = warning['expires'] + content = warning['description'] + url = warning['uri'] + + time = Time.at(time.to_i) + expires = Time.at(expires.to_i) + + content.gsub! /\n/, ' ' + + content = content[0..200] + + url = Cinch::Toolbox.shorten(url) + + if authed + return "WEATHER ALERT || #{title}: #{content}... [Read More: #{url}] || Time: #{time} - Expires: #{expires}" + end + + return "4THERE IS A WEATHER ALERT IN THIS AREA, PLEASE AUTH WITH NICKSERV AND TRIGGER AGAIN TO READ." + rescue + nil + end + + # Now we are going to fetch the hourly data. - + def get_hourly(hour, geometry, locale, withLocale) - key = config[:key] - logo = "10Hourly Fore4cast:" - data = JSON.parse(open("https://api.forecast.io/forecast/#{key}/#{geometry}").read) - raw_hourly = data['hourly']['data'] - hourly = [] - for i in raw_hourly - sum = i['summary'] - temp = i['temperature'] - feels_temp = i['apparentTemperature'] - wind = i['windSpeed'] - bear = i['windBearing'] + key = config[:key] + logo = "10Hourly Fore4cast:" + data = JSON.parse(open("https://api.forecast.io/forecast/#{key}/#{geometry}").read) + raw_hourly = data['hourly']['data'] + hourly = [] + for i in raw_hourly + sum = i['summary'] + temp = i['temperature'] + feels_temp = i['apparentTemperature'] + wind = i['windSpeed'] + bear = i['windBearing'] - temp_c = (temp - 32) * 5 / 9 - feels_temp_c = (feels_temp - 32) * 5 / 9 - wind_speed_kph = wind * 1.6 - temp_c = (temp_c * 10).ceil / 10.0 - feels_temp_c = (feels_temp_c * 10).ceil / 10.0 - wind_speed_kph = (wind_speed_kph * 10).ceil / 10.0 - - if withLocale - hourly.push(("%s - #{locale}: Forecast Predicted in #{hour} hour(s): %s | Temp: [ %s °F (%s °C) | Will feel like: %s °F (%s °C) ] | Wind: [ Speed: %s MPH (%s KPH) | Bearing: %s ]" % [logo, sum, temp, temp_c, feels_temp, feels_temp_c, wind, wind_speed_kph, bear])) - else - hourly.push(("%s - Forecast Predicted in #{hour} hour(s): %s | Temp: [ %s °F (%s °C) | Will feel like: %s °F (%s °C) ] | Wind: [ Speed: %s MPH (%s KPH) | Bearing: %s ]" % [logo, sum, temp, temp_c, feels_temp, feels_temp_c, wind, wind_speed_kph, bear])) - end - end - return hourly - end - + temp_c = (temp - 32) * 5 / 9 + feels_temp_c = (feels_temp - 32) * 5 / 9 + wind_speed_kph = wind * 1.6 + temp_c = (temp_c * 10).ceil / 10.0 + feels_temp_c = (feels_temp_c * 10).ceil / 10.0 + wind_speed_kph = (wind_speed_kph * 10).ceil / 10.0 + + if withLocale + hourly.push(("%s - #{locale}: Forecast Predicted in #{hour} hour(s): %s | Temp: [ %s °F (%s °C) | Will feel like: %s °F (%s °C) ] | Wind: [ Speed: %s MPH (%s KPH) | Bearing: %s ]" % [logo, sum, temp, temp_c, feels_temp, feels_temp_c, wind, wind_speed_kph, bear])) + else + hourly.push(("%s - Forecast Predicted in #{hour} hour(s): %s | Temp: [ %s °F (%s °C) | Will feel like: %s °F (%s °C) ] | Wind: [ Speed: %s MPH (%s KPH) | Bearing: %s ]" % [logo, sum, temp, temp_c, feels_temp, feels_temp_c, wind, wind_speed_kph, bear])) + end + end + return hourly + end + def hourly_summary(data, hour) - return data[hour.to_i - 1] + return data[hour.to_i - 1] end - + # Now we are going to fetch the daily data. - + def get_daily(day, geometry, locale, withLocale) - key = config[:key] - logo = "10Daily Fore4cast:" - data = JSON.parse(open("https://api.forecast.io/forecast/#{key}/#{geometry}").read) - raw_daily = data['daily']['data'] - daily = [] - for i in raw_daily - sum = i['summary'] - min = i['temperatureMin'] - max = i['temperatureMax'] - appmin = i['apparentTemperatureMin'] - appmax = i['apparentTemperatureMax'] - wind = i['windSpeed'] - bear = i['windBearing'] - - # We're going to convert it to metric as well, because IRC. - - temp_c_max = (max - 32) * 5 / 9 - temp_c_min = (min - 32) * 5 / 9 - feels_temp_c_min = (appmin - 32) * 5 / 9 - feels_temp_c_max = (appmax - 32) * 5 / 9 - wind_speed_kph = wind * 1.6 - temp_c_max = (temp_c_max * 10).ceil / 10.0 - temp_c_min = (temp_c_min * 10).ceil / 10.0 - feels_temp_c_min = (feels_temp_c_min * 10).ceil / 10.0 - feels_temp_c_max = (feels_temp_c_max * 10).ceil / 10.0 - wind_speed_kph = (wind_speed_kph * 10).ceil / 10.0 - - if withLocale - daily.push(("%s - #{locale}: Forecast Predicted in #{day} day(s): %s | Temp: [ 10Low: %s °F (10#{temp_c_min} °C) | 4High: %s °F (4#{temp_c_max} °C) ] - Will Feel Like: [ 10Low: %s °F (10#{feels_temp_c_min} °C) | 4High: %s °F (4#{feels_temp_c_max} °C) ] | Wind: [ Speed: %s MPH (#{wind_speed_kph} KPH) | Bearing: %s ]" % [logo, sum, min, max, appmin, appmax, wind, bear])) - else - daily.push(("%s - Forecast Predicted in #{day} day(s): %s | Temp: [ 10Low: %s °F (10#{temp_c_min} °C) | 4High: %s °F (4#{temp_c_max} °C) ] - Will Feel Like: [ 10Low: %s °F (10#{feels_temp_c_min} °C) | 4High: %s °F (4#{feels_temp_c_max} °C) ] | Wind: [ Speed: %s MPH (#{wind_speed_kph} KPH) | Bearing: %s ]" % [logo, sum, min, max, appmin, appmax, wind, bear])) - end - end - return daily - end - + key = config[:key] + logo = "10Daily Fore4cast:" + data = JSON.parse(open("https://api.forecast.io/forecast/#{key}/#{geometry}").read) + raw_daily = data['daily']['data'] + daily = [] + for i in raw_daily + sum = i['summary'] + min = i['temperatureMin'] + max = i['temperatureMax'] + appmin = i['apparentTemperatureMin'] + appmax = i['apparentTemperatureMax'] + wind = i['windSpeed'] + bear = i['windBearing'] + + # We're going to convert it to metric as well, because IRC. + + temp_c_max = (max - 32) * 5 / 9 + temp_c_min = (min - 32) * 5 / 9 + feels_temp_c_min = (appmin - 32) * 5 / 9 + feels_temp_c_max = (appmax - 32) * 5 / 9 + wind_speed_kph = wind * 1.6 + temp_c_max = (temp_c_max * 10).ceil / 10.0 + temp_c_min = (temp_c_min * 10).ceil / 10.0 + feels_temp_c_min = (feels_temp_c_min * 10).ceil / 10.0 + feels_temp_c_max = (feels_temp_c_max * 10).ceil / 10.0 + wind_speed_kph = (wind_speed_kph * 10).ceil / 10.0 + + if withLocale + daily.push(("%s - #{locale}: Forecast Predicted in #{day} day(s): %s | Temp: [ 10Low: %s °F (10#{temp_c_min} °C) | 4High: %s °F (4#{temp_c_max} °C) ] - Will Feel Like: [ 10Low: %s °F (10#{feels_temp_c_min} °C) | 4High: %s °F (4#{feels_temp_c_max} °C) ] | Wind: [ Speed: %s MPH (#{wind_speed_kph} KPH) | Bearing: %s ]" % [logo, sum, min, max, appmin, appmax, wind, bear])) + else + daily.push(("%s - Forecast Predicted in #{day} day(s): %s | Temp: [ 10Low: %s °F (10#{temp_c_min} °C) | 4High: %s °F (4#{temp_c_max} °C) ] - Will Feel Like: [ 10Low: %s °F (10#{feels_temp_c_min} °C) | 4High: %s °F (4#{feels_temp_c_max} °C) ] | Wind: [ Speed: %s MPH (#{wind_speed_kph} KPH) | Bearing: %s ]" % [logo, sum, min, max, appmin, appmax, wind, bear])) + end + end + return daily + end + def daily_summary(data, day) - return data[day.to_i - 1] + return data[day.to_i - 1] end - + # We're gonna fetch the location data again so we can pass it into the results. Primitive, but it works. - + def location_r(location) - raw_locale = JSON.parse(open("http://maps.googleapis.com/maps/api/geocode/json?address=#{location}&sensor=true").read) - locale_data = raw_locale['results'][0]['formatted_address'] - - locale = "#{locale_data}" + raw_locale = JSON.parse(open("http://maps.googleapis.com/maps/api/geocode/json?address=#{location}&sensor=true").read) + locale_data = raw_locale['results'][0]['formatted_address'] + + locale = "#{locale_data}" end end end From 5038870293fb3e70573e19a3c46a92e1a52d59bf Mon Sep 17 00:00:00 2001 From: Richard Banks Date: Thu, 17 Apr 2014 01:27:58 -0500 Subject: [PATCH 06/18] Changed to accommdate authname check --- lib/eve/plugins/user_info.rb | 403 ++++++++++++++++++----------------- 1 file changed, 202 insertions(+), 201 deletions(-) diff --git a/lib/eve/plugins/user_info.rb b/lib/eve/plugins/user_info.rb index 0db90c8..32e7405 100644 --- a/lib/eve/plugins/user_info.rb +++ b/lib/eve/plugins/user_info.rb @@ -1,202 +1,203 @@ -require 'cinch' -require 'yaml' -require_relative "config/check_master" - -module Cinch - module Plugins - class UserInfo - include Cinch::Plugin - include Cinch::Helpers - - set :plugin_name, 'userinfo' - set :help, <<-USAGE.gsub(/^ {6}/, '') - Save certain data to the bot for convienence and sometimes privacy - Usage: - * !set-w : Save your location to the bot for future use in calling weather. - * !set-greeting : Save a custom greeting for the bot to use when you enter the channel. - * !set-twitter : Save your Twitter handle to the bot for use with the Twitter plugin! (use ~@ to call your own Twitter information!) - * !set-birthday : Save your birthday to the bot for special surprises! - There are delete commands as well: - * !del-w: Delete your location data from the bot. - * !del-greeting: Deletes your custom greeting from the bot. - * !del-twitter: Deletes your Twitter handle from the bot. - * !del-birthday: Deletes your birthday from the bot. - USAGE - - def initialize(*args) - super - if File.exist?('docs/userinfo.yaml') - @storage = YAML.load_file('docs/userinfo.yaml') - else - @storage = {} - end - end - - match /set-w (.+)/, method: :set_w - - match /set-twitter (.+)/, method: :set_twitter - - match /set-greeting (.+)/, method: :set_greeting - - match /set-rgreeting (.+?) (.+)/, method: :set_rgreeting - - match /set-birthday ((\d{4})-(0[1-9]|1[012]|[1-9])-([12]\d|3[01]|[1-9]|0[1-9]))/, method: :set_birthday - - match /set-gender (male|female)/, method: :set_gender - - - match /del-w/, method: :del_w - - match /del-twitter/, method: :del_twitter - - match /del-greeting/, method: :del_greeting - - match /del-birthday/, method: :del_birthday - - match /del-data/, method: :del_data - - match /rdel-data (.+)/, method: :rdel_data - - - def set_w(m, zc) - zc.gsub! /\s/, '+' - @storage[m.user.nick] ||= {} - @storage[m.user.nick]['zipcode'] = zc - m.reply "Updated your weather location to #{zc}!" - update_store - rescue - m.reply Format(:red, "Error: #{$!}") - end - - def del_w(m) - if @storage.key?(m.user.nick) - if @storage[m.user.nick].key? 'zipcode' - w = @storage[m.user.nick] - w.delete('zipcode') - update_store - m.reply "Successfully deleted your location data!" - return; - end - m.reply "You have no location data set!" - end - end - - def set_twitter(m, handle) - @storage[m.user.nick] ||= {} - @storage[m.user.nick]['twitter'] = handle - m.reply "Updated your Twitter handle to #{handle}!" - update_store - rescue - m.reply Format(:red, "Error: #{$!}") - end - - def del_twitter(m) - if @storage.key?(m.user.nick) - if @storage[m.user.nick].key? 'twitter' - t = @storage[m.user.nick] - t.delete('twitter') - update_store - m.reply "Successfully deleted your Twitter handle!" - return; - end - m.reply "You have no Twitter handle set!" - end - end - - def set_greeting(m, greeting) - @storage[m.user.nick] ||= {} - @storage[m.user.nick]['greeting'] = greeting - m.reply "Updated your custom greeting to \"#{greeting}\"!" - update_store - rescue - m.reply Format(:red, "Error: #{$!}") - end - - def del_greeting(m) - if @storage.key?(m.user.nick) - if @storage[m.user.nick].key? 'greeting' - g = @storage[m.user.nick] - g.delete('greeting') - update_store - m.reply "Successfully deleted your custom greeting!" - return; - end - m.reply "You have no custom greeting set!" - end - end - - def set_rgreeting(m, user, greeting) - return unless check_master(m.user) - @storage[user] ||= {} - @storage[user]['greeting'] = greeting - m.reply "Updated #{user}'s greeting to \"#{greeting}\"." - update_store - rescue - m.reply Format(:red, "Error: #{$!}") - end - - def set_birthday(m, birthday) - @storage[m.user.nick] ||= {} - @storage[m.user.nick]['birthday'] = birthday - m.reply "Updated your birthday to \"#{birthday}\"." - update_store - rescue - m.reply Format(:red, "Error: #{$!}") - end - - def del_birthday(m) - if @storage.key?(m.user.nick) - if @storage[m.user.nick].key? 'birthday' - b = @storage[m.user.nick] - b.delete('birthday') - update_store - m.reply "Successfully deleted your birthday data!" - return; - end - m.reply "You have no birthday data set!" - end - end - - def del_data(m) - if @storage.key?(m.user.nick) - @storage.delete m.user.nick - update_store - m.reply "All of your custom data has been deleted!" - return; - end - m.reply "You have no custom data set!" - end - - def rdel_data(m, user) - unless check_user(m.user) - m.reply Format(:red, "You are not authorized to use that command!") - return; - end - if @storage.key?(user) - @storage.delete user - update_store - m.reply "All of #{user}'s data has been deleted!" - else - m.reply "#{user} has no custom data set!" - end - end - - def set_gender(m, gender) - @storage[m.user.nick] ||= {} - @storage[m.user.nick]['gender'] = gender - update_store - m.reply "Updated your gender to #{gender}!" - rescue - m.reply Format(:red, "Error: #{$!}") - end - - def update_store - synchronize(:update) do - File.open('docs/userinfo.yaml', 'w') do |fh| - YAML.dump(@storage, fh) - end - end -end -end -end +require 'cinch' +require 'yaml' +require_relative "config/check_master" + +module Cinch + module Plugins + class UserInfo + include Cinch::Plugin + include Cinch::Helpers + + set :plugin_name, 'userinfo' + set :help, <<-USAGE.gsub(/^ {6}/, '') + Save certain data to the bot for convienence and sometimes privacy + Usage: + * ~set-w : Save your location to the bot for future use in calling weather. + * ~set-greeting : Save a custom greeting for the bot to use when you enter the channel. + * ~set-twitter : Save your Twitter handle to the bot for use with the Twitter plugin! (use ~@ to call your own Twitter information!) + * ~set-birthday : Save your birthday to the bot for special surprises! + There are delete commands as well: + * ~del-w: Delete your location data from the bot. + * ~del-greeting: Deletes your custom greeting from the bot. + * ~del-twitter: Deletes your Twitter handle from the bot. + * ~del-birthday: Deletes your birthday from the bot. + USAGE + + def initialize(*args) + super + if File.exist?('docs/userinfo.yaml') + @storage = YAML.load_file('docs/userinfo.yaml') + else + @storage = {} + end + end + + match /set-w (.+)/, method: :set_w + + match /set-twitter (.+)/, method: :set_twitter + + match /set-greeting (.+)/, method: :set_greeting + + match /set-rgreeting (.+?) (.+)/, method: :set_rgreeting + + match /set-birthday ((\d{4})-(0[1-9]|1[012]|[1-9])-([12]\d|3[01]|[1-9]|0[1-9]))/, method: :set_birthday + + match /set-gender (male|female)/, method: :set_gender + + + match /del-w/, method: :del_w + + match /del-twitter/, method: :del_twitter + + match /del-greeting/, method: :del_greeting + + match /del-birthday/, method: :del_birthday + + match /del-data/, method: :del_data + + match /rdel-data (.+)/, method: :rdel_data + + + def set_w(m, zc) + zc.gsub! /\s/, '+' + @storage[User(m.user).nick] ||= {} + @storage[m.user.nick]['zipcode'] = zc + @storage[m.user.nick]['auth'] = User(m.user).authname + m.reply "Updated your weather location to #{zc}!" + update_store + rescue + m.reply Format(:red, "Error: #{$!}") + end + + def del_w(m) + if @storage.key?(m.user.nick) + if @storage[m.user.nick].key? 'zipcode' + w = @storage[m.user.nick] + w.delete('zipcode') + update_store + m.reply "Successfully deleted your location data!" + return; + end + m.reply "You have no location data set!" + end + end + + def set_twitter(m, handle) + @storage[m.user.nick] ||= {} + @storage[m.user.nick]['twitter'] = handle + m.reply "Updated your Twitter handle to #{handle}!" + update_store + rescue + m.reply Format(:red, "Error: #{$!}") + end + + def del_twitter(m) + if @storage.key?(m.user.nick) + if @storage[m.user.nick].key? 'twitter' + t = @storage[m.user.nick] + t.delete('twitter') + update_store + m.reply "Successfully deleted your Twitter handle!" + return; + end + m.reply "You have no Twitter handle set!" + end + end + + def set_greeting(m, greeting) + @storage[m.user.nick] ||= {} + @storage[m.user.nick]['greeting'] = greeting + m.reply "Updated your custom greeting to \"#{greeting}\"!" + update_store + rescue + m.reply Format(:red, "Error: #{$!}") + end + + def del_greeting(m) + if @storage.key?(m.user.nick) + if @storage[m.user.nick].key? 'greeting' + g = @storage[m.user.nick] + g.delete('greeting') + update_store + m.reply "Successfully deleted your custom greeting!" + return; + end + m.reply "You have no custom greeting set!" + end + end + + def set_rgreeting(m, user, greeting) + return unless check_master(m.user) + @storage[user] ||= {} + @storage[user]['greeting'] = greeting + m.reply "Updated #{user}'s greeting to \"#{greeting}\"." + update_store + rescue + m.reply Format(:red, "Error: #{$!}") + end + + def set_birthday(m, birthday) + @storage[m.user.nick] ||= {} + @storage[m.user.nick]['birthday'] = birthday + m.reply "Updated your birthday to \"#{birthday}\"." + update_store + rescue + m.reply Format(:red, "Error: #{$!}") + end + + def del_birthday(m) + if @storage.key?(m.user.nick) + if @storage[m.user.nick].key? 'birthday' + b = @storage[m.user.nick] + b.delete('birthday') + update_store + m.reply "Successfully deleted your birthday data!" + return; + end + m.reply "You have no birthday data set!" + end + end + + def del_data(m) + if @storage.key?(m.user.nick) + @storage.delete m.user.nick + update_store + m.reply "All of your custom data has been deleted!" + return; + end + m.reply "You have no custom data set!" + end + + def rdel_data(m, user) + unless check_user(m.user) + m.reply Format(:red, "You are not authorized to use that command!") + return; + end + if @storage.key?(user) + @storage.delete user + update_store + m.reply "All of #{user}'s data has been deleted!" + else + m.reply "#{user} has no custom data set!" + end + end + + def set_gender(m, gender) + @storage[m.user.nick] ||= {} + @storage[m.user.nick]['gender'] = gender + update_store + m.reply "Updated your gender to #{gender}!" + rescue + m.reply Format(:red, "Error: #{$!}") + end + + def update_store + synchronize(:update) do + File.open('docs/userinfo.yaml', 'w') do |fh| + YAML.dump(@storage, fh) + end + end +end +end +end end \ No newline at end of file From 906e3739bc769e95a6ac8cf71c916f0adac0414e Mon Sep 17 00:00:00 2001 From: Richard Banks Date: Thu, 17 Apr 2014 01:28:54 -0500 Subject: [PATCH 07/18] Added Dictionary plugin --- lib/eve/plugins/dictionary.rb | 126 ++++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 lib/eve/plugins/dictionary.rb diff --git a/lib/eve/plugins/dictionary.rb b/lib/eve/plugins/dictionary.rb new file mode 100644 index 0000000..80c13f3 --- /dev/null +++ b/lib/eve/plugins/dictionary.rb @@ -0,0 +1,126 @@ +require 'cinch' +require 'ostruct' +require 'open-uri' +require 'json' +require 'cgi' + +module Cinch + module Plugins + class Dictionary + include Cinch::Plugin + + set :plugin_name, 'dictionary' + set :help, <<-USAGE.gsub(/^ {6}/, '') + This plugin searches for definitions. + Usage: + * ~define : Fetches and returns the definition for the given word. + USAGE + + match /define (.+)/i, method: :define + + def define(m, query) + data = fetch_definition(m, query) + return m.reply Format(:red, "I'm sorry but I couldn't find the definition of #{query}.") if data.empty? + definition(m, data) + end + + def fetch_definition(m, word) + data = JSON.parse(open("http://api.wordnik.com:80/v4/word.json/#{word}/definitions?limit=2&includeRelated=true&sourceDictionaries=wiktionary&useCanonical=true&includeTags=false&api_key=86454404519fadebdb90e06ef9a04381b87e620884ad40abd").read) + results = [] + + data.each{|i| results.push("%s: (%s) - %s" % [i['word'], i['partOfSpeech'], i['text']])} + + return results + end + + + def definition(m, data) + data[0..1].each{|i| m.reply i} + end + + match /synonym (.+)/i, method: :synonym + + def synonym(m, word) + data = fetch_synonyms(m, word) + list = data.join(", ") + return m.reply Format(:red, "There are no thesaurus results for #{word}") if data.empty? + m.reply "Here are some synonyms for #{word}: #{list}" + end + + def fetch_synonyms(m, word) + data = JSON.parse(open("http://api.wordnik.com:80/v4/word.json/#{word}/relatedWords?useCanonical=false&relationshipTypes=synonym&limitPerRelationshipType=10&api_key=86454404519fadebdb90e06ef9a04381b87e620884ad40abd").read) + list = [] + + for i in data + synonym = i['words'] + + list.push("%s" % [synonym]) + end + return list + end + + match /equivalent (.+)/i, method: :equivalent + + def equivalent(m, word) + data = fetch_equals(m, word) + list = data.join(", ") + return m.reply Format(:red, "There are no equal results for #{word}") if data.empty? + m.reply "Here are some equivalents for #{word}: #{list}" + end + + def fetch_equals(m, word) + data = JSON.parse(open("http://api.wordnik.com:80/v4/word.json/#{word}/relatedWords?useCanonical=true&relationshipTypes=equivalent&limitPerRelationshipType=10&api_key=86454404519fadebdb90e06ef9a04381b87e620884ad40abd").read) + list = [] + + for i in data + equivalent = i['words'] + + list.push("%s" % [equivalent]) + end + return list + end + + match /variants (.+)/i, method: :variants + + def variants(m, word) + data = fetch_variants(m, word) + list = data.join(", ") + return m.reply Format(:red, "There are no variant results for #{word}") if data.empty? + m.reply "Here are some variants of #{word}: #{list}" + end + + def fetch_variants(m, word) + data = JSON.parse(open("http://api.wordnik.com:80/v4/word.json/#{word}/relatedWords?useCanonical=true&relationshipTypes=variant&limitPerRelationshipType=10&api_key=86454404519fadebdb90e06ef9a04381b87e620884ad40abd").read) + list = [] + + for i in data + variants = i['words'] + + list.push("%s" % [variants]) + end + return list + end + + match /rhyme (.+)/i, method: :rhyme + + def rhyme(m, word) + data = fetch_rhymes(m, word) + list = data.join(", ") + return m.reply Format(:red, "There are no rhyming results for #{word}") if data.empty? + m.reply "Here are some words that rhyme with #{word}: #{list}" + end + + def fetch_rhymes(m, word) + data = JSON.parse(open("http://api.wordnik.com:80/v4/word.json/#{word}/relatedWords?useCanonical=true&relationshipTypes=rhyme&limitPerRelationshipType=20&api_key=86454404519fadebdb90e06ef9a04381b87e620884ad40abd").read) + list = [] + + for i in data + rhymes = i['words'] + + list.push("%s" % [rhymes]) + end + return list + end + end + end + end \ No newline at end of file From 46574c8e66c9190445f73d8b42d49671831d77ad Mon Sep 17 00:00:00 2001 From: Richard Banks Date: Thu, 17 Apr 2014 01:30:10 -0500 Subject: [PATCH 08/18] Added helpers for the news plugin --- lib/eve/plugins/helpers/category_helper.rb | 168 +++++++++++++++++++++ lib/eve/plugins/helpers/defcon_tools.rb | 21 +++ 2 files changed, 189 insertions(+) create mode 100644 lib/eve/plugins/helpers/category_helper.rb create mode 100644 lib/eve/plugins/helpers/defcon_tools.rb diff --git a/lib/eve/plugins/helpers/category_helper.rb b/lib/eve/plugins/helpers/category_helper.rb new file mode 100644 index 0000000..a9982eb --- /dev/null +++ b/lib/eve/plugins/helpers/category_helper.rb @@ -0,0 +1,168 @@ +require 'json' +require 'open-uri' +require 'ostruct' +require 'cinch/toolbox' + +module Cinch + module Helpers + + def categories + c_data = JSON.parse(open("http://api.feedzilla.com/v1/categories.json").read) + c_list = [] + + for i in c_data + c_title = i['english_category_name'] + c_id = i['category_id'] + + c_list.push("%s [ %s ]" % [c_title, c_id]) + end + return c_list + end + + def sub_categories(id) + sc_data = JSON.parse(open("http://api.feedzilla.com/v1/categories/#{id}/subcategories.json").read) + sc_list = [] + + for i in sc_data + sc_title = i['display_subcategory_name'] + sc_id = i['subcategory_id'] + + sc_list.push("%s [ %s ]" % [sc_title, sc_id]) + end + return sc_list + end + + def execute_c_search(id, terms) + search_c_data = JSON.parse(open("http://api.feedzilla.com/v1/categories/#{id}/articles/search.json?q=#{terms}&count=4").read) + s_c_data = search_c_data['articles'] + search_c_list = [] + + for i in s_c_data + article_source = i['source'] + article_title = i['title'] + article_summary = i['summary'] + article_url = i['url'] + + url = article_url + url = Cinch::Toolbox.shorten(url) + + url = /"shorturl": "(.+)"/.match(url)[1] + + summary = article_summary[0..200] + + summary_s = summary.gsub! /\n/, ' ' + + search_c_list.push("%s | Title \"%s\" | Summary: %s [ %s ]" % [article_source, article_title, summary, url]) + end + return search_c_list + end + + def execute_sc_search(id, sc_id, terms) + search_sc_data = JSON.parse(open("http://api.feedzilla.com/v1/categories/#{id}/subcategories/#{sc_id}/articles/search.json?q=#{terms}&count=4").read) + s_sc_data = search_sc_data['articles'] + search_sc_list = [] + + for i in s_sc_data + article_source = i['source'] + article_title = i['title'] + article_summary = i['summary'] + article_url = i['url'] + + url = article_url + url = Cinch::Toolbox.shorten(url) + + url = /"shorturl": "(.+)"/.match(url)[1] + + summary = article_summary[0..200] + + summary_s = summary.gsub! /\n/, ' ' + + search_sc_list.push("%s | Title \"%s\" | Summary: %s [ %s ]" % [article_source, article_title, summary_s, url]) + end + return search_sc_list + end + + def fetch_news + news_data = JSON.parse(open("http://api.feedzilla.com/v1/categories/26/articles.json?&count=4").read) + news_articles = news_data['articles'] + news_list = [] + + for i in news_articles + article_source = i['source'] + article_title = i['title'] + article_summary = i['summary'] + article_url = i['url'] + + puts article_url + + url = article_url + url = Cinch::Toolbox.shorten(url) + + url = /"shorturl": "(.+)"/.match(url)[1] + + puts url.class + + summary = article_summary[0..200] + + summary_s = summary.gsub! /\n/, ' ' + + news_list.push("%s | Title \"%s\" | Summary: %s [ #{url} ]" % [article_source, article_title, summary_s]) + end + return news_list + end + + def c_top_news(id) + c_news_data = JSON.parse(open("http://api.feedzilla.com/v1/categories/#{id}/articles.json?&count=4").read) + c_news_articles = c_news_data['articles'] + c_news_list = [] + + for i in c_news_articles + article_source = i['source'] + article_title = i['title'] + article_summary = i['summary'] + article_url = i['url'] + + + url = article_url + url = Cinch::Toolbox.shorten(url) + + url = /"shorturl": "(.+)"/.match(url)[1] + + summary = article_summary[0..200] + + summary_s = summary.gsub! /\n/, ' ' + + c_news_list.push("%s | Title \"%s\" | Summary: %s [ #{url} ]" % [article_source, article_title, summary_s]) + end + return c_news_list + end + + def sc_top_news(id, sc_id) + sc_news_data = JSON.parse(open("http://api.feedzilla.com/v1/categories/#{id}/subcategories/#{sc_id}/articles.json?&count=4").read) + sc_news_articles = sc_news_data['articles'] + sc_news_list = [] + + for i in sc_news_articles + article_source = i['source'] + article_title = i['title'] + article_summary = i['summary'] + article_url = i['url'] + + + url = article_url + url = Cinch::Toolbox.shorten(url) + + url = /"shorturl": "(.+)"/.match(url)[1] + + summary = article_summary[0..200] + + summary_s = summary.gsub! /\n/, ' ' + + sc_news_list.push("%s | Title \"%s\" | Summary: %s [ #{url} ]" % [article_source, article_title, summary_s]) + end + return sc_news_list + end + + end + end + \ No newline at end of file diff --git a/lib/eve/plugins/helpers/defcon_tools.rb b/lib/eve/plugins/helpers/defcon_tools.rb new file mode 100644 index 0000000..7a9bc1f --- /dev/null +++ b/lib/eve/plugins/helpers/defcon_tools.rb @@ -0,0 +1,21 @@ +require 'cinch' + +module Cinch + module Helpers + + def d_limit(m, chan, option) + if option == "on" + @limit = option == "on" + count = Channel(chan).users.count.to_i + count = count + 2 + User("ChanServ").send("set #{chan} MLOCK +ntsl #{count}") + return + end + if option == "off" + @limit = option == "off" + User("ChanServ").send("set #{chan} MLOCK +nt-sl") + return + end + end + end +end \ No newline at end of file From 9ae71b3bbddcbfcb611c52acb0dd4ebe534b89a0 Mon Sep 17 00:00:00 2001 From: Richard Banks Date: Thu, 17 Apr 2014 01:32:46 -0500 Subject: [PATCH 09/18] Added authname checker for the Weather plugin --- lib/eve/plugins/config/check_auth.rb | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 lib/eve/plugins/config/check_auth.rb diff --git a/lib/eve/plugins/config/check_auth.rb b/lib/eve/plugins/config/check_auth.rb new file mode 100644 index 0000000..922d32b --- /dev/null +++ b/lib/eve/plugins/config/check_auth.rb @@ -0,0 +1,27 @@ +require 'cinch' +require 'yaml' + +module Cinch + module Helpers + + def check_auth(user) + reload + user.refresh + + return false unless !user.authname.nil? + + if ((@storage.key?(user.nick)) && (@storage[user.nick].key? 'auth')) + auth = @storage[user.nick]['auth'] + return auth == user.authname + end + end + + def reload + if File.exist?('docs/userinfo.yaml') + @storage = YAML.load_file('docs/userinfo.yaml') + else + @storage = {} + end + end + end +end \ No newline at end of file From 37b52721b3ba71d0a47b81b7e2226db59208210b Mon Sep 17 00:00:00 2001 From: Richard Banks Date: Thu, 17 Apr 2014 01:33:10 -0500 Subject: [PATCH 10/18] Added News plugin using the FeedZilla API --- lib/eve/plugins/news.rb | 97 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 lib/eve/plugins/news.rb diff --git a/lib/eve/plugins/news.rb b/lib/eve/plugins/news.rb new file mode 100644 index 0000000..7b04ff3 --- /dev/null +++ b/lib/eve/plugins/news.rb @@ -0,0 +1,97 @@ +# @author Richard Banks + +# Feel free to join us in #Lobby on irc://rawr.sinsira.net where you can test this gem and get help! + +require 'cinch' +require 'ostruct' +require 'open-uri' +require 'json' +require 'cgi' +require 'cinch/toolbox' +require_relative "helpers/category_helper.rb" + +module Cinch + module Plugins + class News + include Cinch::Plugin + + set :plugin_name, 'news' + set :help, <<-USAGE.gsub(/^ {6}/, '') + This plugin is a comprehensive news aggregator and contacts several sources for articles. + Enable/Disable Usage: + * ~n-categories: This command returns all the categories that you can choose from in a PM. + * ~n-subcategories : This command returns all the subcategories of the specified category and their useable ID. + * ~news: This command retrieves the top three articles from the Top Stories subcategory of the Top News category. + * ~news : This command retrieves the top three articles from the specified category. + * ~news : This command retrieves the top three articles from the specified subcategory of the specified category. + * ~s-category : This command searches the specified category for your query. + USAGE + + match /n-categories/, method: :list_categories + + match /n-subcategories (.+)/, method: :list_subs + + match /news$/, method: :top_news + + match /news (.+)$/, method: :c_topnews + + match /news (.+?) (.+)/, method: :sc_topnews + + match /s-category (.+?) (.+)/, method: :search_category + + match /s-subcategory (.+?) (.+?) (.+)/, method: :search_subcategory + + def list_categories(m) + cat_list = categories + ca_list = cat_list.join(", ") + m.user.notice "#{ca_list}" + end + + def list_subs(m, c_id) + sc_list = sub_categories(c_id) + s_list = sc_list.join(", ") + m.user.notice "#{s_list}" + end + + + def search_category(m, id, terms) + terms.gsub! /\s/, '+' + search_list = execute_c_search(id, terms) + search_list[0..2].each{|i| m.reply i} + rescue OpenURI::HTTPError + m.reply "Error: #{$!}" + end + + def search_subcategory(m, id, sc_id, terms) + terms.gsub! /\s/, '+' + sc_search_list = execute_sc_search(id, sc_id, terms) + sc_search_list[0..2].each{|i| m.reply i} + rescue OpenURI::HTTPError + m.reply "Error #{$!}" + end + + def top_news(m) + news = fetch_news + news[0..2].each{|i| m.reply i} + rescue OpenURI::HTTPError + m.reply "Error #{$!}" + end + + def c_topnews(m, id) + c_news = c_top_news(id) + c_news[0..2].each{|i| m.reply i} + rescue OpenURI::HTTPError + m.reply "Error #{$!}" + end + + def sc_topnews(m, id, sc_id) + sc_news = sc_top_news(id, sc_id) + sc_news[0..2].each{|i| m.reply i} + rescue OpenURI::HTTPError + m.reply "Error #{$!}" + end + + + end + end +end \ No newline at end of file From c92f9a1ab3cdee3440a1d87aae8b2c083bf4579b Mon Sep 17 00:00:00 2001 From: Richard Banks Date: Thu, 17 Apr 2014 01:33:31 -0500 Subject: [PATCH 11/18] Updated README.md --- README.md | 52 ++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 40 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 97bb878..107928c 100644 --- a/README.md +++ b/README.md @@ -12,50 +12,66 @@ Eve and several of it's plugins have some dependencies. The first of which are v ###-Section A: Installing Ruby, RVM, and RubyGems- 1.) The first thing we need to do is make sure that your package manager is up to date: -sudo apt-get update + +> sudo apt-get update 2.) If you don't have curl you need to install it now: -sudo apt-get install curl + +> sudo apt-get install curl 3.) Now you need to install RVM: -\curl -L https://get.rvm.io | bash -s stable + +> \curl -L https://get.rvm.io | bash -s stable 4.) Now you need to load RVM: -source ~/.rvm/scripts/rvm + +> source ~/.rvm/scripts/rvm 5.) Now you need to install RVM's dependencies: -rvm requirements + + rvm requirements 6.) Now you need to install Ruby: -rvm install ruby + + rvm install ruby 7.) Now you need to tell the system what version to use as default: -rvm use ruby -default + + rvm use ruby -default 8.) Now you need to install RubyGems: -rvm rubygems current + + rvm rubygems current Excellent. Now you are done installing RVM, Ruby, and RubyGems! ###-Section B: Installing the Framework- 1.) This is really easy: -gem install cinch + + gem install cinch ###-Section C: Installing Plugin Dependencies- As of now there are only two dependencies needed for the plugins. 1.) If you want to have Eve do anything that has to do with web fetching you must install the Nokogiri gem: -gem install nokogiri + + gem install nokogiri 2.) If you want to have Eve fetch tweets from any twitter account you need to install the Twitter gem: -gem install cinch-twitter + + gem install cinch-twitter + +3.) Most of Eve's plugins rely on JSON: + + gem install json ###-Section D: Getting Eve- Now you just need to get Eve from the repo: -git clone https://github.com/Namasteh/Eve-Bot.git + + git clone https://github.com/Namasteh/Eve-Bot.git ###-Section E: Configuring Eve- @@ -70,3 +86,15 @@ Next you need to make sure the plugins you want loaded are in the c.plugins.plug Next are your Twitter options, you need to put your API keys in this section or the Twitter plugin will not work! In c.password you need to put Eve's NickServ pass so she can identify upon connecting. + +###-Section F: Adding Yourself As Master- + +When you run Eve, you will need the bot to recognize you as master, and you must add yourself as a master to the bot's userinfo.yaml file in order for any of the userinfo dependent plugins to work. + +So open docs/userinfo.yaml and place the following inside, save, and close + + --- + yourircnick: + auth: yourauthname + master: true + From 4aec2235feb7fba0841782065884d0f4bcccc3aa Mon Sep 17 00:00:00 2001 From: Richard Banks Date: Thu, 17 Apr 2014 01:33:55 -0500 Subject: [PATCH 12/18] Updated Eve.rb to reflect new changes --- Eve.rb | 66 ++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 36 insertions(+), 30 deletions(-) diff --git a/Eve.rb b/Eve.rb index e84c8f8..9d0b5a5 100644 --- a/Eve.rb +++ b/Eve.rb @@ -1,6 +1,6 @@ require 'cinch' require 'redis' -require_relative "lib/eve/plugins/urban_dictionary" +require_relative "lib/eve/plugins/urban" require_relative "lib/eve/plugins/help" require_relative "lib/eve/plugins/seen" require_relative "lib/eve/plugins/greeting" @@ -29,6 +29,9 @@ require_relative "lib/eve/plugins/isitup" require_relative "lib/eve/plugins/relationship_handler" require_relative "lib/eve/plugins/admin_handler" +require_relative "lib/eve/plugins/four_chan" +require_relative "lib/eve/plugins/dictionary" +require_relative "lib/eve/plugins/news" # You should have something in the block below as it will have Eve report @@ -53,34 +56,37 @@ c.user = "Eve" c.realname = "Eve 5.0" c.plugins.plugins = [Cinch::Plugins::PluginManagement, - Cinch::Plugins::UrbanDictionary, - Cinch::Plugins::Help, - Cinch::Plugins::Seen, - Cinch::Plugins::Greeting, - Cinch::Plugins::Eightball, - Cinch::Plugins::Decide, - Cinch::Plugins::Memo, - Cinch::Plugins::AIRespond, - Cinch::Plugins::ControlPanel, - Cinch::Plugins::ChanopCP, - Cinch::Plugins::PrivateCP, - Cinch::Plugins::PrivChanCP, - Cinch::Plugins::FactCore, - Cinch::Plugins::ActAI, - Cinch::Plugins::UrlScraper, - Cinch::Plugins::Twitter, - Cinch::Plugins::TwitterStatus, - Cinch::Plugins::ValentineBoxx, - Cinch::Plugins::Wikipedia, - Cinch::Plugins::Weather, - Cinch::Plugins::Google, - Cinch::Plugins::YouTube, - Cinch::Plugins::Math, - Cinch::Plugins::Bitcoin, - Cinch::Plugins::UserInfo, - Cinch::Plugins::Isitup, - Cinch::Plugins::RelationshipHandler, - Cinch::Plugins::AdminHandler]; + Cinch::Plugins::Urban, + Cinch::Plugins::Help, + Cinch::Plugins::Seen, + Cinch::Plugins::Greeting, + Cinch::Plugins::Eightball, + Cinch::Plugins::Decide, + Cinch::Plugins::Memo, + Cinch::Plugins::AIRespond, + Cinch::Plugins::ControlPanel, + Cinch::Plugins::ChanopCP, + Cinch::Plugins::PrivateCP, + Cinch::Plugins::PrivChanCP, + Cinch::Plugins::FactCore, + Cinch::Plugins::ActAI, + Cinch::Plugins::UrlScraper, + Cinch::Plugins::Twitter, + Cinch::Plugins::TwitterStatus, + Cinch::Plugins::ValentineBoxx, + Cinch::Plugins::Wikipedia, + Cinch::Plugins::Weather, + Cinch::Plugins::Google, + Cinch::Plugins::YouTube, + Cinch::Plugins::Math, + Cinch::Plugins::Bitcoin, + Cinch::Plugins::UserInfo, + Cinch::Plugins::Isitup, + Cinch::Plugins::RelationshipHandler, + Cinch::Plugins::AdminHandler, + Cinch::Plugins::FourChan, + Cinch::Plugins::Dictionary, + Cinch::Plugins::News]; #c.plugins.options[Cinch::Plugins::UrlScraper] = { enabled_channels: ["#foo", "#bar" "#channel"] } #c.plugins.options[Cinch::Plugins::Greeting] = { enabled_channels: ["#foo", "#bar" "#channel"] } #c.plugins.options[Cinch::Plugins::TwitterStatus] = { @@ -98,7 +104,7 @@ #} #} c.plugins.options[Cinch::Plugins::Weather] = { key: 'foo' } - c.password = "nspass" + c.password = "nspass" end end From 417754371fbc32c64a242468a2355c187ae628c1 Mon Sep 17 00:00:00 2001 From: Richard Banks Date: Thu, 17 Apr 2014 01:45:36 -0500 Subject: [PATCH 13/18] Changed version --- Eve.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Eve.rb b/Eve.rb index 9d0b5a5..844a8f3 100644 --- a/Eve.rb +++ b/Eve.rb @@ -54,7 +54,7 @@ c.channels = ["#Eve"] c.nick = "Eve" c.user = "Eve" - c.realname = "Eve 5.0" + c.realname = "Eve 6.0" c.plugins.plugins = [Cinch::Plugins::PluginManagement, Cinch::Plugins::Urban, Cinch::Plugins::Help, From df39ecb5ae37f3554befae146a6d373f820f388c Mon Sep 17 00:00:00 2001 From: Richard Banks Date: Thu, 17 Apr 2014 02:35:37 -0500 Subject: [PATCH 14/18] Updated to reflect change in AI plugin --- Eve.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Eve.rb b/Eve.rb index 844a8f3..a3ce54e 100644 --- a/Eve.rb +++ b/Eve.rb @@ -63,7 +63,7 @@ Cinch::Plugins::Eightball, Cinch::Plugins::Decide, Cinch::Plugins::Memo, - Cinch::Plugins::AIRespond, + Cinch::Plugins::Ai, Cinch::Plugins::ControlPanel, Cinch::Plugins::ChanopCP, Cinch::Plugins::PrivateCP, From a2f9d6e677de347f371c768ab7cc909e2899f76d Mon Sep 17 00:00:00 2001 From: Richard Banks Date: Thu, 17 Apr 2014 02:36:27 -0500 Subject: [PATCH 15/18] Updated plugin to cover all currencies and provide exchange rate for specific amount --- lib/eve/plugins/bitcoin.rb | 98 +++++++++++++++++++++++++++----------- 1 file changed, 71 insertions(+), 27 deletions(-) diff --git a/lib/eve/plugins/bitcoin.rb b/lib/eve/plugins/bitcoin.rb index f72c718..6e7e524 100644 --- a/lib/eve/plugins/bitcoin.rb +++ b/lib/eve/plugins/bitcoin.rb @@ -1,27 +1,71 @@ -require 'cinch' -require 'ostruct' -require 'open-uri' -require 'json' - -module Cinch - module Plugins - class Bitcoin - include Cinch::Plugin - - set :plugin_name, 'bitcoin' - set :help, <<-USAGE.gsub(/^ {6}/, '') - Just a seen plugin! - Usage: - * !btcv: Returns the latest value of 1 (one) Bitcoin in USD - USAGE - - match /btcv/ - - def execute(m) - data = JSON.parse(open("http://blockchain.info/ticker").read) - value = data['USD']['15m'] - m.reply "Current value of 1 BTC in USD is: #{value}", true - end - end - end -end \ No newline at end of file +require 'cinch' +require 'ostruct' +require 'open-uri' +require 'json' + +module Cinch + module Plugins + class Bitcoin + include Cinch::Plugin + + set :plugin_name, 'bitcoin' + set :help, <<-USAGE.gsub(/^ {6}/, '') + Bitcoin plugin that fetches results from Blockchain.info! + Usage: + * !btcv : Returns the latest value of 1 (one) Bitcoin in + * !btc : Returns the value of in . + USAGE + + match /btcv (\w{3})/ + + def execute(m, currency) + data = JSON.parse(open("http://blockchain.info/ticker").read) + + coins = ['USD', 'CNY', 'JPY', 'SGD', 'HKD', 'CAD', 'NZD', 'AUD', 'CLP', 'GBP', 'HKK', 'SEK', 'ISK', 'CHF', 'BRL', 'EUR', 'RUB', 'PLN', 'THB', 'KRW', 'TWD'] + + currency = currency.upcase + + if !coins.include?(currency) + m.reply "That currency isn't in my database!" + m.user.notice "You can use: #{coins}" + return + end + + value = data[currency]['15m'] + value = value.round(2).to_f + value = value.to_s.reverse.gsub(/(\d{3})(?=\d)/, '\\1,').reverse + + symbol = data[currency]['symbol'] + + m.reply "Current value of 1 BTC in #{currency} is: #{symbol}#{value}", true + end + + match /btc (\w{3}) (.+)/, method: :conversion + + def conversion(m, currency, btc) + data = JSON.parse(open("http://blockchain.info/ticker").read) + + coins = ['USD', 'CNY', 'JPY', 'SGD', 'HKD', 'CAD', 'NZD', 'AUD', 'CLP', 'GBP', 'HKK', 'SEK', 'ISK', 'CHF', 'BRL', 'EUR', 'RUB', 'PLN', 'THB', 'KRW', 'TWD'] + + currency = currency.upcase + + if !coins.include?(currency) + m.reply "That currency isn't in my database!" + m.user.notice "You can use: #{coins}" + return + end + value = data[currency]['15m'] + value = value.round(2).to_f + + symbol = data[currency]['symbol'] + + btc = btc.to_f + + conv = (btc * value).round(2) + conv = conv.to_s.reverse.gsub(/(\d{3})(?=\d)/, '\\1,').reverse + + m.reply "The value of #{btc}BTC is #{symbol}#{conv}.", true + end + end + end + end \ No newline at end of file From d15d2e4a15a11de99397690ff1c62a5a2475c18c Mon Sep 17 00:00:00 2001 From: Richard Banks Date: Thu, 17 Apr 2014 02:36:59 -0500 Subject: [PATCH 16/18] Updated plugin to reflect changes to plugins --- lib/eve/plugins/help.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/eve/plugins/help.rb b/lib/eve/plugins/help.rb index acdb461..bee3cf7 100644 --- a/lib/eve/plugins/help.rb +++ b/lib/eve/plugins/help.rb @@ -19,12 +19,12 @@ def execute(m) unless check_master(m.user) m.user.send Format(:green, "Hello, #{m.user.nick}") m.user.send Format(:green, "You can get further information on a plugin by typing !help IN A PM. Don't do it in a channel!!") - m.user.send Format(:orange, "memo, seen, urban, eightball, decider, factcore, weather, twitter, valentineboxx, wikipedia, google, youtube, 4chan, math, isitup, bitcoin, userinfo") + m.user.send Format(:orange, "memo, seen, urban, eightball, decider, factcore, weather, twitter, valentineboxx, wikipedia, google, youtube, 4chan, math, isitup, bitcoin, userinfo, news") return; end m.user.send Format(:green, "Hello, #{m.user.nick}") m.user.send Format(:green, "You can get further information on a plugin by typing !help IN A PM. Don't do it in a channel!!") - m.user.send Format(:orange, "memo, seen, urban, eightball, decider, factcore, weather, twitter, valentineboxx, wikipedia, google, youtube, 4chan, math, isitup, bitcoin, userinfo") + m.user.send Format(:orange, "memo, seen, urban, eightball, decider, factcore, weather, twitter, valentineboxx, wikipedia, google, youtube, 4chan, math, isitup, bitcoin, userinfo, news") m.user.send Format(:red, "The following plugins are only available to operators of the bot! USE WITH CAUTION!! USE OF EVERY ONE OF THESE PLUGINS IS REPORTED!!!") m.user.send Format(:red, "channelcp, controlpanel, privatecp, privchancp, urlscraper, pluginmanagement, adminhandler, relationshiphandler") end From 0ec2c16e799ef939a3a49355023e4d8dd4d0cbcc Mon Sep 17 00:00:00 2001 From: Richard Banks Date: Thu, 17 Apr 2014 10:53:46 -0500 Subject: [PATCH 17/18] Delete factcore.rb Redundant, left over file from old release --- lib/eve/plugins/factcore.rb | 96 ------------------------------------- 1 file changed, 96 deletions(-) delete mode 100644 lib/eve/plugins/factcore.rb diff --git a/lib/eve/plugins/factcore.rb b/lib/eve/plugins/factcore.rb deleted file mode 100644 index ca243ca..0000000 --- a/lib/eve/plugins/factcore.rb +++ /dev/null @@ -1,96 +0,0 @@ -require 'cinch' - -module Cinch::Plugins - class FactCore - include Cinch::Plugin - - set :prefix, /^~/ - set :plugin_name, 'factcore' - set :help, <<-USAGE.gsub(/^ {6}/, '') - Gives a funny, and sometimes true fact - Usage: - - ~fact: This will cause me to return with a funny (and sometimes true) fact! - USAGE - - def fact(m) - [ - Format(:green, "Fact: Space does not exist."), - Format(:green, "The square root of rope is string."), - Format(:green, "While the submarine is vastly superior to the boat in every way, over 97% of people still use boats for aquatic transportation."), - Format(:green, "Cellular phones will not give you cancer. Only hepatitis."), - Format(:green, "Pants were invented in the 16th century to avoid Poseidon's wrath. It was believed that the sight of naked sailors angered the sea god."), - Format(:green, "The atomic weight of Germanium is 72.64."), - Format(:green, "89% of magic tricks are not magic. Technically, they are sorcery."), - Format(:green, "An ostrich's eye is bigger than its brain."), - Format(:green, "In Greek myth, the craftsman Daedalus invented human flight so a group of Minotaurs would stop teasing him about it."), - Format(:green, "Humans can survive underwater, but not for very long."), - Format(:green, "Raseph, the Semetic god of war and plague, had a gazelle growing out of his forehead."), - Format(:green, "The plural of Surgeon General is Surgeons General. The past tense of Surgeons General is Surgeonsed General."), - Format(:green, "Polymerase I polypeptide A is a human gene."), - Format(:green, "Rats cannot throw up."), - Format(:green, "Iguanas can stay underwater for 28.7 minutes."), - Format(:green, "Human tapeworms can grow up to 22.9 meters."), - Format(:green, "The Schrodinger's cat paradox outlines a situation in which a cat in a box must be considered, for all intents and purposes, simultaneously alive and dead. Schrodinger created this paradox as a justification for killing cats."), - Format(:green, "Every square inch of the human body has 32 million bacteria on it."), - Format(:green, "The Sun is 330,330 times the size of Earth."), - Format(:green, "The average life expectancy of a rhinoceros living in captivity is 15 years."), - Format(:green, "Volcano-ologists are experts in the study of volcanoes."), - Format(:green, "Avocados have the highest fiber and calories of any fruit. They are found in Australia."), - Format(:green, "The Moon orbits the Earth every 27.32 days."), - Format(:green, "The billionth digit of pi is nine."), - Format(:green, "If you have trouble with simple counting, use the following mneumonic device: One, comes before two, comes before sixty, comes after twelve, comes before six-trillion, comes after five-hundred-and-four. This will make your earlier counting difficulties seem like no big deal."), - Format(:green, "A gallon of water weighs 8.34 pounds."), - Format(:green, "Hot water freezes quicker than cold water."), - Format(:green, "Honey does not spoil."), - Format(:green, "The average adult human body contains half a pound of salt."), - Format(:green, "A nanosecond lasts one-billionth of a second."), - Format(:green, "According to Norse legend, thunder god Thor's chariot was pulled across the sky by two goats."), - Format(:green, "China produces the world's second largest crop of soybeans."), - Format(:green, "Tungsten has the highest melting point of any metal, at 3,410 degrees Celsius."), - Format(:green, "Gently cleaning the tongue twice a day is the most effective way to fight bad breath."), - Format(:green, "Roman toothpaste was made with urine. Urine is an ingredient in toothpaste continued to be used up until the 18th century."), - Format(:green, "The Tariff Act of 1789, established to protect domestic manufacture, was the second statute ever enacted by the United States government."), - Format(:green, "The value of Pi is the ratio of any circle's circumference to its diameter in Euclidean space."), - Format(:green, "The Mexican-American War ended in 1838 with the signing of the Treaty of Guadelupe Hidalgo."), - Format(:green, "In 1879, Sandford Fleming first produced the adoption of worldwide standardized time zones at the Royal Canadian Institute."), - Format(:green, "Marie Curie invented the theory of radioactivity, the treatment of radioactivity, and dying of radioactivity."), - Format(:green, "At the end of The Seagull by Anton Chekhov, Konstantin kills himself."), - Format(:green, "Contrary to popular belief, the Eskimo does not have 100 different words for snow. They do, however, have 234 words for fudge."), - Format(:green, "In Victorian England, a commoner was not allowed to look directly at the Queen, due to a belief at the time that the poor had the ability to steal thoughts. Science now believes that less than 4% of poor people are able to do this."), - Format(:green, "In 1862, Abraham Lincoln signed the Emancipation Proclamation, freeing the slaves. Like everything he did, Lincoln freed the slaves while sleepwalking, and later had no memory of the event."), - Format(:green, "In 1948, at the request of a dying boy, baseball legend Babe Ruth at 75 hot dogs, then died of hot dog poisoning."), - Format(:green, "William Shakespeare did not exist. His plays were masterminded in 1589 by Francis Bacon, who used a Ouiji board to enslave playwriting ghosts."), - Format(:green, "It is incorrectly noted that Thomas Edison invented push-ups in 1878. Nikolai Tesla had in fact patented the activity three years earlier, under the name Tesla-cize."), - Format(:green, "Whales are twice as intelligent and three times as delicious as humans."), - Format(:green, "The automobile brake was not invented until 1895. Before this, someone had to be in the car at all times, driving in circles until passengers returned from their errands."), - Format(:green, "Edmund Hilary, the first person to climb Mt. Everest, did so accidentally, while chasing a bird."), - Format(:green, "Diamonds are made when coal is put under intense pressure. Diamonds put under intense pressure become foam pellets, commonly used today as packing material."), - Format(:green, "The most poisonous fish in the world is the orange ruffy. Everything on its body is made of a deadly poison. The ruffy's eyes are composed of a less harmful deadly poison."), - Format(:green, "The occupation of court jester was invented accidentally, when a vassal's epilepsy was mistaken for capering."), - Format(:green, "Halley's Comet can be viewed orbiting Earth every seventy-six years. For the other seventy-five, it retreats to the heart of the Sun, where it hibernates undisturbed."), - Format(:green, "The first commercial air flight took place in 1914. Everyone involved screamed the entire way."), - Format(:green, "In Greek myth, Prometheus stole fire from the gods and gave it to humankind. The jewellery he kept for himself."), - Format(:green, "The first person to prove that cow's milk is drinkable was very, very thirsty."), - Format(:green, "Before the Wright Brothers invented the airplane, anyone wanting to fly anywhere was required to eat 200 pounds of helium."), - Format(:green, "Before the invention of scrambled eggs in 1912, the typical breakfast was either whole eggs still in the shell, or scrambled rocks."), - Format(:green, "During the Great Depression, the Tennessee Valley Authority outlawed pet rabbits, forcing many to hot glue-gun long ears onto their pet mice."), - Format(:green, "At some point in their lives 1 in 6 children will be abducted by the Dutch."), - Format(:green, "According to most advanced algorithms, the world's best name is Craig."), - Format(:green, "To make a photocopier, simply photocopy a mirror."), - Format(:green, "Dreams are the subconscious mind's way of reminding people to go to school naked and have their teeth fall out.") - ].sample - end - - match /fact/, method: :execute_fact - - def execute_fact(m) - m.reply fact(m) - end - end -end - -# EVE is a project for a Top-Tier IRC bot, and the project could always use more help. -# Feel free to contribute at the github: https://github.com/Namasteh/Eve-Bot -# For help with the Cinch framework you can always visit #Cinch at irc.freenode.net -# For help with EVE you can always visit #Eve at rawr.sinsira.net - From f39e8389918e88a2b72067907e342785e8efff45 Mon Sep 17 00:00:00 2001 From: Richard Banks Date: Thu, 17 Apr 2014 10:59:53 -0500 Subject: [PATCH 18/18] Update fact_core.rb Applied typo fix from KernelPone to current factcore plugin --- lib/eve/plugins/fact_core.rb | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/lib/eve/plugins/fact_core.rb b/lib/eve/plugins/fact_core.rb index d94e4d2..ca243ca 100644 --- a/lib/eve/plugins/fact_core.rb +++ b/lib/eve/plugins/fact_core.rb @@ -4,11 +4,12 @@ module Cinch::Plugins class FactCore include Cinch::Plugin + set :prefix, /^~/ set :plugin_name, 'factcore' set :help, <<-USAGE.gsub(/^ {6}/, '') Gives a funny, and sometimes true fact Usage: - - !fact: This will cause me to return with a funny (and sometimes true) fact! + - ~fact: This will cause me to return with a funny (and sometimes true) fact! USAGE def fact(m) @@ -34,8 +35,7 @@ def fact(m) Format(:green, "The Sun is 330,330 times the size of Earth."), Format(:green, "The average life expectancy of a rhinoceros living in captivity is 15 years."), Format(:green, "Volcano-ologists are experts in the study of volcanoes."), - Format(:green, "Avocados have the highest fiber and calories of any fruit."), - Format(:green, "Avocados have the highest fiber and calories of any fruit. They are found in Australians."), + Format(:green, "Avocados have the highest fiber and calories of any fruit. They are found in Australia."), Format(:green, "The Moon orbits the Earth every 27.32 days."), Format(:green, "The billionth digit of pi is nine."), Format(:green, "If you have trouble with simple counting, use the following mneumonic device: One, comes before two, comes before sixty, comes after twelve, comes before six-trillion, comes after five-hundred-and-four. This will make your earlier counting difficulties seem like no big deal."), @@ -88,5 +88,9 @@ def execute_fact(m) end end end + +# EVE is a project for a Top-Tier IRC bot, and the project could always use more help. +# Feel free to contribute at the github: https://github.com/Namasteh/Eve-Bot +# For help with the Cinch framework you can always visit #Cinch at irc.freenode.net +# For help with EVE you can always visit #Eve at rawr.sinsira.net - \ No newline at end of file