zetabot 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +4 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +281 -0
- data/LICENSE.txt +21 -0
- data/README.md +41 -0
- data/Rakefile +6 -0
- data/Zeta.gemspec +74 -0
- data/bin/console +14 -0
- data/bin/setup +13 -0
- data/bin/zeta +9 -0
- data/bin/zeta-setup +13 -0
- data/lib/Zeta.rb +13 -0
- data/lib/Zeta/access.rb +84 -0
- data/lib/Zeta/admin.rb +10 -0
- data/lib/Zeta/admin/autojoin.rb +25 -0
- data/lib/Zeta/admin/bot.rb +43 -0
- data/lib/Zeta/admin/channels.rb +36 -0
- data/lib/Zeta/admin/eval.rb +43 -0
- data/lib/Zeta/admin/fifo.rb +45 -0
- data/lib/Zeta/admin/ignore.rb +112 -0
- data/lib/Zeta/admin/oper.rb +50 -0
- data/lib/Zeta/admin/plugins.rb +109 -0
- data/lib/Zeta/admin/users.rb +5 -0
- data/lib/Zeta/blacklist.rb +25 -0
- data/lib/Zeta/cache.rb +0 -0
- data/lib/Zeta/cinch.rb +35 -0
- data/lib/Zeta/config.rb +42 -0
- data/lib/Zeta/gems.rb +0 -0
- data/lib/Zeta/locale.rb +4 -0
- data/lib/Zeta/log.rb +2 -0
- data/lib/Zeta/models.rb +5 -0
- data/lib/Zeta/models/channel.rb +3 -0
- data/lib/Zeta/models/plugin.rb +3 -0
- data/lib/Zeta/models/user.rb +3 -0
- data/lib/Zeta/plugins.rb +27 -0
- data/lib/Zeta/plugins/attack.rb +61 -0
- data/lib/Zeta/plugins/botinfo.rb +83 -0
- data/lib/Zeta/plugins/darkscience.rb +215 -0
- data/lib/Zeta/plugins/dbz.rb +31 -0
- data/lib/Zeta/plugins/dcc.rb +25 -0
- data/lib/Zeta/plugins/dnsbl.rb +36 -0
- data/lib/Zeta/plugins/echo.rb +15 -0
- data/lib/Zeta/plugins/eightball.rb +53 -0
- data/lib/Zeta/plugins/fml.rb +35 -0
- data/lib/Zeta/plugins/fnord.rb +329 -0
- data/lib/Zeta/plugins/gem.rb +0 -0
- data/lib/Zeta/plugins/gif.rb +73 -0
- data/lib/Zeta/plugins/help.rb +32 -0
- data/lib/Zeta/plugins/libsecure.rb +34 -0
- data/lib/Zeta/plugins/macros.rb +124 -0
- data/lib/Zeta/plugins/movie.rb +67 -0
- data/lib/Zeta/plugins/pdfinfo.rb +69 -0
- data/lib/Zeta/plugins/rainbow.rb +65 -0
- data/lib/Zeta/plugins/russian_roulette.rb +90 -0
- data/lib/Zeta/plugins/seen.rb +77 -0
- data/lib/Zeta/plugins/silly.rb +183 -0
- data/lib/Zeta/plugins/snooper.rb +146 -0
- data/lib/Zeta/plugins/urban.rb +60 -0
- data/lib/Zeta/plugins/weather.rb +203 -0
- data/lib/Zeta/plugins/whois.rb +25 -0
- data/lib/Zeta/plugins/wiki.rb +75 -0
- data/lib/Zeta/plugins/wolfram.rb +46 -0
- data/lib/Zeta/tasks/db.rb +0 -0
- data/lib/Zeta/version.rb +3 -0
- data/lib/generators/config/config.rb +0 -0
- data/lib/generators/plugin/new_plugin.rb +0 -0
- data/locale/en/8ball.yml +0 -0
- data/locale/en/attack.yml +148 -0
- data/locale/en/dbz.yml +10 -0
- data/locale/en/ircop.yml +5 -0
- data/locale/en/macros.yml +98 -0
- data/locale/en/meme.yml +27 -0
- metadata +636 -0
@@ -0,0 +1,90 @@
|
|
1
|
+
module Plugins
|
2
|
+
class RussianRoulette
|
3
|
+
include Cinch::Plugin
|
4
|
+
include Cinch::Helpers
|
5
|
+
enable_acl
|
6
|
+
|
7
|
+
set plugin_name: "Russian Roulette",
|
8
|
+
help: "In Soviet Russia, boolet shoots YOU!\nUsage: ?rr <nick>",
|
9
|
+
react_on: :channel
|
10
|
+
|
11
|
+
attr_reader :games
|
12
|
+
|
13
|
+
PHRASES = [
|
14
|
+
"\"BANG\" You're dead! ... Just kidding comrade... for now.",
|
15
|
+
"\"...BLAMMO!\" (hangfires are a bitch, aren't they?)",
|
16
|
+
"Are you scared yet, comrade?",
|
17
|
+
"Are you pissing your pants yet?",
|
18
|
+
"You are lucky, comrade. At least for now.",
|
19
|
+
"The chamber was as empty as your head.",
|
20
|
+
"Damn. And I thought that it had bullet too.",
|
21
|
+
"Lucky you, comrade.",
|
22
|
+
"Must be your lucky day, comrade.",
|
23
|
+
"\"BLAM!\" you can't play russian roulette with a tokarev, comrade.",
|
24
|
+
"... Looks like you get to live another day... or 5 second.",
|
25
|
+
"... Bad primer."
|
26
|
+
]
|
27
|
+
|
28
|
+
def initialize(*args)
|
29
|
+
super
|
30
|
+
@games = []
|
31
|
+
end
|
32
|
+
|
33
|
+
match /rr(?: (.+))?/, method: :russian
|
34
|
+
|
35
|
+
def russian(m, nick)
|
36
|
+
#return m.reply "I am sorry comrade, but I do not have pistol on me." unless check_user(m.channel, @bot)
|
37
|
+
return m.user.notice "Sorry comrade, but there is already game going on." if @games.include?(m.channel.name)
|
38
|
+
|
39
|
+
# player setup
|
40
|
+
player = User(nick) || m.user
|
41
|
+
player = m.user if player == @bot
|
42
|
+
# be nice, don't force the game on the starter unless the user actually exists in the channel.
|
43
|
+
return m.reply "I am terribly sorry %s, but I don't know %s." % [m.user.nick, player.nick] unless m.channel.users.include?(player)
|
44
|
+
|
45
|
+
# start game
|
46
|
+
@games << m.channel.name
|
47
|
+
|
48
|
+
turns, round_location = Array.new(2) { |i| Random.new.rand(1..6) }
|
49
|
+
m.channel.action "starts a %d-turn game of Russian Roulette with %s." % [turns, player.nick]
|
50
|
+
|
51
|
+
phrases = PHRASES.dup.shuffle
|
52
|
+
|
53
|
+
sleep 5
|
54
|
+
|
55
|
+
turns.times do |chamber|
|
56
|
+
return end_game(m.channel, true) unless m.channel.users.include?(player)
|
57
|
+
if round_location == chamber.succ
|
58
|
+
m.reply "*click*"
|
59
|
+
sleep 5
|
60
|
+
m.channel.kick(player, "*BLAM*")
|
61
|
+
m.reply "*BLAM*"
|
62
|
+
m.channel.action "watches %s's brain splatter across the wall." % player.nick
|
63
|
+
break
|
64
|
+
else
|
65
|
+
phrase = phrases.pop
|
66
|
+
m.reply "*click* %s" % phrase
|
67
|
+
end
|
68
|
+
sleep 5
|
69
|
+
end
|
70
|
+
|
71
|
+
m.reply "Looks like you get to live another day." if turns < round_location
|
72
|
+
sleep 1 if turns < round_location
|
73
|
+
end_game(m.channel)
|
74
|
+
end
|
75
|
+
|
76
|
+
private
|
77
|
+
|
78
|
+
def end_game(channel, premature=false)
|
79
|
+
@games.delete channel.name
|
80
|
+
channel.msg "Oh vell, it vas fun vhile it lasted." if premature
|
81
|
+
sleep 1
|
82
|
+
channel.action "holsters the pistol."
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
|
88
|
+
# AutoLoad
|
89
|
+
Bot.config.plugins.plugins.push Plugins::RussianRoulette
|
90
|
+
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'action_view'
|
2
|
+
module Plugins
|
3
|
+
class Seen
|
4
|
+
class SeenStruct < Struct.new(:who, :where, :what, :time)
|
5
|
+
include ActionView::Helpers::DateHelper
|
6
|
+
def to_s
|
7
|
+
# "[#{time.asctime}] #{who} was seen in #{where} last saying #{what}"
|
8
|
+
time_ago = time_ago_in_words(Time.at(time))
|
9
|
+
"[ \x1F#{where.to_s.upcase}\x0F ] \x0304#{who}\x0F: \"\x0303#{what[0..300]}\x0F\" \x02#{time_ago}\x0F ago"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
include Cinch::Plugin
|
14
|
+
include Cinch::Helpers
|
15
|
+
|
16
|
+
enable_acl(:nobody)
|
17
|
+
|
18
|
+
listen_to :channel
|
19
|
+
match /seen (.+)/
|
20
|
+
match /sync/, method: :sync
|
21
|
+
|
22
|
+
def initialize(*args)
|
23
|
+
super
|
24
|
+
@users = load_seen
|
25
|
+
end
|
26
|
+
|
27
|
+
def finalize
|
28
|
+
save_seen()
|
29
|
+
end
|
30
|
+
|
31
|
+
def listen(m)
|
32
|
+
@users[m.user.nick] = SeenStruct.new(m.user, m.channel, m.message, Time.now)
|
33
|
+
end
|
34
|
+
|
35
|
+
def execute(m, nick)
|
36
|
+
nick.rstrip!
|
37
|
+
if nick == @bot.nick
|
38
|
+
m.reply 'You are a Stupid human!'
|
39
|
+
elsif nick == m.user.nick
|
40
|
+
m.reply "Unfortunately, I see an idiot by the name of #{m.user.nick}"
|
41
|
+
elsif @users.key?(nick)
|
42
|
+
m.reply @users[nick].to_s
|
43
|
+
else
|
44
|
+
m.reply "I haven't seen #{nick}"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def sync(m)
|
49
|
+
save_seen()
|
50
|
+
end
|
51
|
+
|
52
|
+
def save_seen
|
53
|
+
File.open(File.join(Dir.home, '.zeta', 'cache', 'seen.rb'), 'w+') do |file|
|
54
|
+
Marshal.dump(@users, file)
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
def load_seen
|
60
|
+
if File.exists?(File.join(Dir.home, '.zeta', 'cache', 'seen.rb'))
|
61
|
+
File.open(File.join(Dir.home, '.zeta', 'cache', 'seen.rb')) do |file|
|
62
|
+
return Marshal.load(file)
|
63
|
+
end
|
64
|
+
else
|
65
|
+
return Hash.new
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def clear_seen
|
70
|
+
@users = {}
|
71
|
+
File.delete(File.join(Dir.home, '.zeta', 'cache', 'seen.rb'))
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
# AutoLoad
|
77
|
+
Bot.config.plugins.plugins.push Plugins::Seen
|
@@ -0,0 +1,183 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require 'active_support/time'
|
4
|
+
require 'active_support/core_ext/string'
|
5
|
+
require 'active_support/core_ext/object/blank'
|
6
|
+
require 'chronic_duration'
|
7
|
+
require 'date'
|
8
|
+
|
9
|
+
|
10
|
+
module Plugins
|
11
|
+
class Silly
|
12
|
+
include Cinch::Plugin
|
13
|
+
include Cinch::Helpers
|
14
|
+
enable_acl
|
15
|
+
|
16
|
+
set(
|
17
|
+
plugin_name: "Silly",
|
18
|
+
help: "You know, silly stuff.",
|
19
|
+
)
|
20
|
+
|
21
|
+
_seconds_in_a_day = 86400
|
22
|
+
|
23
|
+
attr_reader :pokers
|
24
|
+
|
25
|
+
def initialize *args
|
26
|
+
super
|
27
|
+
@pokers = {}
|
28
|
+
end
|
29
|
+
|
30
|
+
match /^pokes (.+)$/, react_on: :action, method: :listen_poke, use_prefix: false
|
31
|
+
|
32
|
+
def listen_poke(m, thebot)
|
33
|
+
|
34
|
+
if User(thebot) == @bot
|
35
|
+
@pokers[m.user] = 0 if !@pokers.include?(m.user)
|
36
|
+
@pokers[m.user] += 1
|
37
|
+
case @pokers[m.user]
|
38
|
+
when 1..3
|
39
|
+
m.reply "Do NOT poke the bot!"
|
40
|
+
when 4
|
41
|
+
m.reply "I said, do NOT poke the bot!"
|
42
|
+
when 5
|
43
|
+
msg = ["WHAT ARE YOU, AN IDIOT? I SAID DO NOT POKE ME!!", "THIS! IS! SPARTA!!"].sample
|
44
|
+
m.channel.kick m.user, ["WHAT ARE YOU, AN IDIOT? I SAID DO NOT POKE ME!!", "THIS! IS! SPARTA!!"].sample
|
45
|
+
@pokers.delete(m.user)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
match /\b(dumb|stupid)\b.+\bbots*\b/i, method: :execute_botinsult, use_prefix: false
|
51
|
+
|
52
|
+
def execute_botinsult(m)
|
53
|
+
|
54
|
+
m.reply ["Stupid human!", "Dumb human!", "Stupid meatbag.", "Silly human, your insults cannot harm me!", "get rekt", "u fkn w0t m8"].sample
|
55
|
+
end
|
56
|
+
|
57
|
+
def tzparser(tz)
|
58
|
+
prefix = (tz[0] !~ /(\+|-)/ ? "+" : "")
|
59
|
+
suffix = (tz =~ /^(?:\+|-)?(\d{1,2})$/ ? ":00" : "")
|
60
|
+
regexp = /^(\+|-)?(\d{1,2})(?::(\d{1,2}))?$/
|
61
|
+
if tz =~ regexp
|
62
|
+
prefix + tz.gsub(regexp) { |match| (!!$1 ? $1 : "") + $2.rjust(2, "0") + (!!$3 ? ":"+$3.rjust(2, "0") : "") } + suffix
|
63
|
+
else
|
64
|
+
raise ArgumentError, "A valid timezone was not supplied."
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
match "halloween", method: :halloween
|
69
|
+
match "halloweve", method: :halloween
|
70
|
+
match /halloween (\S+)/, method: :halloween
|
71
|
+
|
72
|
+
def halloween(m, tz = nil)
|
73
|
+
tz ||= "-00:00"
|
74
|
+
tz = tzparser(tz)
|
75
|
+
begin
|
76
|
+
today = Time.now.localtime(tz)
|
77
|
+
hw = Time.new(today.year, 10, 31, 0, 0, 0, tz)
|
78
|
+
hw = hw.next_year if hw.to_date.past?
|
79
|
+
message = if hw.to_date == today.to_date
|
80
|
+
"THIS IS HALLOWEEN!"
|
81
|
+
else
|
82
|
+
"There's #{ChronicDuration.output(hw.to_i - today.to_i, format: :long)} until Hallow's Eve!"
|
83
|
+
end
|
84
|
+
rescue ArgumentError => ae
|
85
|
+
message = ae.message
|
86
|
+
ensure
|
87
|
+
m.reply message, true
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
match "xmas", method: :xmas
|
92
|
+
match /xmas (\S+)/, method: :xmas
|
93
|
+
|
94
|
+
def xmas(m, tz = nil)
|
95
|
+
tz ||= "-00:00"
|
96
|
+
tz = tzparser(tz)
|
97
|
+
begin
|
98
|
+
today = Time.now.localtime(tz)
|
99
|
+
xmas = Time.new(today.year, 12, 25, 0, 0, 0, tz)
|
100
|
+
xmas = xmas.next_year if xmas.to_date.past?
|
101
|
+
message = if xmas.to_date == today.to_date
|
102
|
+
"Merry Christmas!"
|
103
|
+
else
|
104
|
+
"There's #{ChronicDuration.output(xmas.to_i - today.to_i, format: :long)} until Christmas!"
|
105
|
+
end
|
106
|
+
rescue ArgumentError => ae
|
107
|
+
message = ae.message
|
108
|
+
ensure
|
109
|
+
m.reply message, true
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
match "newyear", method: :newyear
|
114
|
+
match /newyear (\S+)/, method: :newyear
|
115
|
+
|
116
|
+
def newyear(m, tz = nil)
|
117
|
+
tz ||= "-00:00"
|
118
|
+
tz = tzparser(tz)
|
119
|
+
begin
|
120
|
+
today = Time.now.localtime(tz)
|
121
|
+
nyear = Time.new(today.year.succ, 1, 1, 0, 0, 0, tz)
|
122
|
+
#nyear = nyear.next_year if nyear.to_date.past?
|
123
|
+
message = if nyear.to_date == today.to_date
|
124
|
+
"Happy New Year #{today.year}!"
|
125
|
+
else
|
126
|
+
"There's #{ChronicDuration.output(nyear.to_i - today.to_i, format: :long)} until #{nyear.year}!"
|
127
|
+
end
|
128
|
+
rescue ArgumentError => ae
|
129
|
+
message = ae.message
|
130
|
+
ensure
|
131
|
+
m.reply message, true
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
match "tz", method: :tz
|
136
|
+
match /tz (\S+)/, method: :tz
|
137
|
+
|
138
|
+
def tz(m, tz = nil)
|
139
|
+
tz ||= "-00:00"
|
140
|
+
tz = tzparser(tz)
|
141
|
+
begin
|
142
|
+
today = Time.now.localtime(tz)
|
143
|
+
message = today.to_s
|
144
|
+
rescue ArgumentError => ae
|
145
|
+
message = ae.message
|
146
|
+
ensure
|
147
|
+
m.reply message, true
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
match "mayan", method: :mayan
|
152
|
+
|
153
|
+
def mayan(m)
|
154
|
+
msd = (Date.today.jd - Date.new(1, 1, 1).jd) + 1137142
|
155
|
+
lc = {
|
156
|
+
baktun: (msd - (msd % 144000)) / 144000,
|
157
|
+
katun: ((msd - (msd % 7200)) / 7200) % 20,
|
158
|
+
tun: ((msd - (msd % 360)) / 360) % 20,
|
159
|
+
uinal: ((msd - (msd % 20)) / 20) % 18,
|
160
|
+
kin: (msd % 20)
|
161
|
+
}
|
162
|
+
|
163
|
+
m.reply '%<baktun>s.%<katun>s.%<tun>s.%<uinal>s.%<kin>s' % lc
|
164
|
+
end
|
165
|
+
|
166
|
+
match /heavymetalize (.+)/, method: :heavymetalize
|
167
|
+
|
168
|
+
def heavymetalize(m, s)
|
169
|
+
m.reply s.tr('AEIOUaeiouyYWwXx', 'ÄËÏÖÜäëïöüÿŸẄẅẌẍ')
|
170
|
+
end
|
171
|
+
|
172
|
+
match /\bfeature\b.+\brequest\b/i, method: :execute_userproblem, use_prefix: false
|
173
|
+
|
174
|
+
def execute_userproblem(m)
|
175
|
+
m.reply ["user error.", "working as intended", "Status: WONTFIX", "PEBKAC issue", "ID:10T Error"].sample
|
176
|
+
end
|
177
|
+
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
|
182
|
+
# AutoLoad
|
183
|
+
Bot.config.plugins.plugins.push Plugins::Silly
|
@@ -0,0 +1,146 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
# == Author
|
3
|
+
# Marvin Gülker (Quintus)
|
4
|
+
#
|
5
|
+
# == Modification author
|
6
|
+
# Liothen
|
7
|
+
#
|
8
|
+
# == License
|
9
|
+
# A named-pipe plugin for Cinch.
|
10
|
+
# Copyright © 2012 Marvin Gülker
|
11
|
+
#
|
12
|
+
# This program is free software: you can redistribute it and/or modify
|
13
|
+
# it under the terms of the GNU Lesser General Public License as published by
|
14
|
+
# the Free Software Foundation, either version 3 of the License, or
|
15
|
+
# (at your option) any later version.
|
16
|
+
#
|
17
|
+
# This program is distributed in the hope that it will be useful,
|
18
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
19
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
20
|
+
# GNU Lesser General Public License for more details.
|
21
|
+
#
|
22
|
+
# You should have received a copy of the GNU Lesser General Public License
|
23
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
24
|
+
|
25
|
+
# Plugin for inspecting links pasted into channels.
|
26
|
+
require 'video_info'
|
27
|
+
require 'mechanize'
|
28
|
+
require 'action_view'
|
29
|
+
|
30
|
+
module Plugins
|
31
|
+
class Snooper
|
32
|
+
include Cinch::Plugin
|
33
|
+
include Cinch::Helpers
|
34
|
+
include ActionView::Helpers::DateHelper
|
35
|
+
|
36
|
+
enable_acl(:nobody)
|
37
|
+
|
38
|
+
# Default list of URL regexps to ignore.
|
39
|
+
# DEFAULT_BLACKLIST = [/\.png$/i, /\.jpe?g$/i, /\.bmp$/i, /\.gif$/i, /\.pdf$/i].freeze
|
40
|
+
|
41
|
+
set :help, <<-HELP
|
42
|
+
http[s]://...
|
43
|
+
I’ll fire a GET request at any link I encounter, parse the HTML
|
44
|
+
meta tags, and paste the result back into the channel.
|
45
|
+
HELP
|
46
|
+
|
47
|
+
match %r{\b((https?:\/\/)?(([0-9a-zA-Z_!~*'().&=+$%-]+:)?[0-9a-zA-Z_!~*'().&=+$%-]+\@)?(([0-9]{1,3}\.){3}[0-9]{1,3}|([0-9a-zA-Z_!~*'()-]+\.)*([0-9a-zA-Z][0-9a-zA-Z-]{0,61})?[0-9a-zA-Z]\.[a-zA-Z]{2,6})(:[0-9]{1,4})?((\/[0-9a-zA-Z_!~*'().;?:\@&=+$,%#-]+)*\/?))}i,
|
48
|
+
use_prefix: false,
|
49
|
+
react_on: :channel
|
50
|
+
|
51
|
+
def execute(msg, url)
|
52
|
+
url = "http://#{url}" unless url=~/^https?:\/\//
|
53
|
+
url = URI.encode(url)
|
54
|
+
|
55
|
+
# Ignore items on blacklist
|
56
|
+
# blacklist = DEFAULT_BLACKLIST.dup
|
57
|
+
# blacklist.concat(config[:blacklist]) if config[:blacklist]
|
58
|
+
# return if blacklist.any?{|entry| url =~ entry}
|
59
|
+
|
60
|
+
# Log
|
61
|
+
# debug "URL matched: #{url}"
|
62
|
+
|
63
|
+
# Parse URI
|
64
|
+
p = URI(url)
|
65
|
+
|
66
|
+
# API key lookup
|
67
|
+
VideoInfo.provider_api_keys = { youtube: Config.secrets[:google] }
|
68
|
+
|
69
|
+
# Parse out specific websites
|
70
|
+
if p.host == 'youtube.com' || p.host == 'www.youtube.com' || p.host == 'youtu.be'
|
71
|
+
match_youtube(msg, url)
|
72
|
+
elsif p.host == 'i.imgur.com' || p.host == 'imgur.com'
|
73
|
+
match_imgur(msg, url)
|
74
|
+
else
|
75
|
+
match_other(msg,url)
|
76
|
+
end
|
77
|
+
|
78
|
+
rescue => e
|
79
|
+
error "#{e.class.name}: #{e.message}"
|
80
|
+
error "[404] #{msg.user} - #{url}"
|
81
|
+
end
|
82
|
+
|
83
|
+
private
|
84
|
+
def match_youtube(msg, url)
|
85
|
+
if Config.secrets[:google]
|
86
|
+
video = VideoInfo.new(url)
|
87
|
+
msg.reply "#{Format(:red, 'YouTube ')}∴ #{video.title} ( #{Format(:green, Time.at(video.duration).strftime("%H:%M:%S"))} )"
|
88
|
+
else
|
89
|
+
match_other(msg, url)
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
|
94
|
+
def match_github(msg, url)
|
95
|
+
# TODO parse github url
|
96
|
+
end
|
97
|
+
|
98
|
+
def match_imgur(msg, url)
|
99
|
+
id = url.to_s.match(%r{(?:https?://i?\.?imgur.com/)(?:.*\/)?([A-Za-z0-9]+)(?:\.jpg|png|gif|gifv)?}i)
|
100
|
+
return match_other(msg, url) unless id
|
101
|
+
|
102
|
+
# Query Data
|
103
|
+
data = JSON.parse(
|
104
|
+
RestClient.get("https://api.imgur.com/3/image/#{id[1]}", { Authorization: "Client-ID #{Config.secrets[:imgur_id]}" })
|
105
|
+
)
|
106
|
+
return 'Unable to query imgur' unless defined?(data)
|
107
|
+
i = Hashie::Mash.new(data)
|
108
|
+
|
109
|
+
# SET Not Safe For Work
|
110
|
+
if i.data.nsfw
|
111
|
+
nsf = "[#{Format(:red, 'NSFW')}]"
|
112
|
+
else
|
113
|
+
nsf = "[#{Format(:green, 'SAFE')}]"
|
114
|
+
end
|
115
|
+
|
116
|
+
# Trigger reply message
|
117
|
+
msg.reply("#{Format(:purple, 'IMGUR')} #{nsf} ∴ [#{Format(:yellow, i.data.type)}] #{i.data.width}x#{i.data.height} "\
|
118
|
+
"∴ Views: #{ i.data.views.to_s} ∴ #{i.data.title ? i.data.title[0..100] : 'No Title'} "\
|
119
|
+
"∴ Posted #{time_ago_in_words(Time.at(i.data.datetime))} ago")
|
120
|
+
end
|
121
|
+
|
122
|
+
def match_other(msg,url)
|
123
|
+
begin
|
124
|
+
html = Mechanize.start { |m| Nokogiri::HTML(m.get(url).content, nil, 'utf-8') }
|
125
|
+
if node = html.at_xpath("html/head/title")
|
126
|
+
msg.reply("‡ #{node.text.lstrip.gsub(/\r|\n|\n\r/, ' ')[0..300]}")
|
127
|
+
end
|
128
|
+
|
129
|
+
if node = html.at_xpath('html/head/meta[@name="description"]')
|
130
|
+
msg.reply("» #{node[:content].lines.first(3).join.gsub(/\r|\n|\n\r/, ' ')[0..300]}")
|
131
|
+
end
|
132
|
+
|
133
|
+
info "[200] #{msg.user} - #{url}"
|
134
|
+
rescue => e
|
135
|
+
error e
|
136
|
+
error "[404] #{msg.user} - #{url}"
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
|
144
|
+
# AutoLoad
|
145
|
+
Bot.config.plugins.plugins.push Plugins::Snooper
|
146
|
+
|