rbot 0.9.9 → 0.9.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/AUTHORS +8 -0
- data/ChangeLog +51 -0
- data/INSTALL +4 -0
- data/README +1 -0
- data/REQUIREMENTS +11 -0
- data/TODO +2 -0
- data/bin/rbot +21 -2
- data/data/rbot/languages/german.lang +4 -1
- data/data/rbot/languages/russian.lang +75 -0
- data/data/rbot/plugins/autoop.rb +42 -51
- data/data/rbot/plugins/bans.rb +205 -0
- data/data/rbot/plugins/bash.rb +56 -0
- data/data/rbot/plugins/chucknorris.rb +74 -0
- data/data/rbot/plugins/chucknorris.yml.gz +0 -0
- data/data/rbot/plugins/deepthoughts.rb +95 -0
- data/data/rbot/plugins/demauro.rb +95 -0
- data/data/rbot/plugins/digg.rb +51 -0
- data/data/rbot/plugins/figlet.rb +24 -0
- data/data/rbot/plugins/forecast.rb +133 -0
- data/data/rbot/plugins/freshmeat.rb +13 -7
- data/data/rbot/plugins/google.rb +2 -0
- data/data/rbot/plugins/grouphug.rb +36 -0
- data/data/rbot/plugins/imdb.rb +92 -0
- data/data/rbot/plugins/insult.rb +8 -1
- data/data/rbot/plugins/iplookup.rb +227 -0
- data/data/rbot/plugins/karma.rb +2 -2
- data/data/rbot/plugins/keywords.rb +470 -0
- data/data/rbot/plugins/lart.rb +132 -146
- data/data/rbot/plugins/lastfm.rb +25 -0
- data/data/rbot/plugins/markov.rb +204 -0
- data/data/rbot/plugins/math.rb +5 -1
- data/data/rbot/plugins/nickserv.rb +71 -11
- data/data/rbot/plugins/opme.rb +19 -19
- data/data/rbot/plugins/quakeauth.rb +2 -2
- data/data/rbot/plugins/quotes.rb +40 -25
- data/data/rbot/plugins/remind.rb +1 -1
- data/data/rbot/plugins/rot13.rb +2 -2
- data/data/rbot/plugins/roulette.rb +49 -15
- data/data/rbot/plugins/rss.rb +585 -0
- data/data/rbot/plugins/rubyurl.rb +39 -0
- data/data/rbot/plugins/seen.rb +2 -1
- data/data/rbot/plugins/slashdot.rb +5 -5
- data/data/rbot/plugins/spell.rb +5 -0
- data/data/rbot/plugins/theyfightcrime.rb +121 -0
- data/data/rbot/plugins/threat.rb +55 -0
- data/data/rbot/plugins/tinyurl.rb +39 -0
- data/data/rbot/plugins/topic.rb +204 -0
- data/data/rbot/plugins/urban.rb +71 -0
- data/data/rbot/plugins/url.rb +399 -4
- data/data/rbot/plugins/wow.rb +123 -0
- data/data/rbot/plugins/wserver.rb +1 -1
- data/data/rbot/templates/levels.rbot +2 -0
- data/lib/rbot/auth.rb +207 -96
- data/lib/rbot/channel.rb +5 -5
- data/lib/rbot/config.rb +125 -24
- data/lib/rbot/dbhash.rb +87 -21
- data/lib/rbot/httputil.rb +181 -13
- data/lib/rbot/ircbot.rb +525 -179
- data/lib/rbot/ircsocket.rb +330 -54
- data/lib/rbot/message.rb +66 -23
- data/lib/rbot/messagemapper.rb +25 -17
- data/lib/rbot/plugins.rb +244 -115
- data/lib/rbot/post-clean.rb +1 -0
- data/lib/rbot/{post-install.rb → post-config.rb} +1 -1
- data/lib/rbot/rbotconfig.rb +29 -14
- data/lib/rbot/registry.rb +111 -72
- data/lib/rbot/rfc2812.rb +208 -197
- data/lib/rbot/timer.rb +4 -0
- data/lib/rbot/utils.rb +2 -2
- metadata +127 -104
- data/data/rbot/plugins/rss.rb.disabled +0 -414
- data/lib/rbot/keywords.rb +0 -433
@@ -0,0 +1,39 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require "shorturl"
|
3
|
+
|
4
|
+
class RubyURL < Plugin
|
5
|
+
|
6
|
+
# return a help string when the bot is asked for help on this plugin
|
7
|
+
def help(plugin, topic="")
|
8
|
+
return "rubyurl <your long url>"
|
9
|
+
end
|
10
|
+
|
11
|
+
# reply to a private message that we've registered for
|
12
|
+
def privmsg(m)
|
13
|
+
|
14
|
+
# m.params contains the rest of the message, m.plugin contains the first
|
15
|
+
# word (useful because it's possible to register for multiple commands)
|
16
|
+
unless(m.params)
|
17
|
+
m.reply "incorrect usage. " + help(m.plugin)
|
18
|
+
end
|
19
|
+
|
20
|
+
# TODO: might want to add a check here to validate the url
|
21
|
+
# if they call 'rubyurl help' backwards, don't return a lame link
|
22
|
+
|
23
|
+
if (m.params == "help")
|
24
|
+
m.reply "Try again. Correct usage is: " + help(m.plugin)
|
25
|
+
return false
|
26
|
+
end
|
27
|
+
|
28
|
+
# call the ShortURL library with the value of the url
|
29
|
+
url = ShortURL.shorten(m.params)
|
30
|
+
|
31
|
+
|
32
|
+
m.reply "Your RubyURL: #{url}"
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# create an instance of the RubyURL class and register it as a plugin
|
38
|
+
rubyurl = RubyURL.new
|
39
|
+
rubyurl.register("rubyurl")
|
data/data/rbot/plugins/seen.rb
CHANGED
@@ -21,6 +21,7 @@ class SeenPlugin < Plugin
|
|
21
21
|
end
|
22
22
|
|
23
23
|
def listen(m)
|
24
|
+
return if m.sourcenick.nil?
|
24
25
|
# keep database up to date with who last said what
|
25
26
|
if m.kind_of?(PrivMessage)
|
26
27
|
return if m.private?
|
@@ -78,7 +79,7 @@ class SeenPlugin < Plugin
|
|
78
79
|
when "JOIN"
|
79
80
|
ret += "joining #{saw.where}"
|
80
81
|
when "QUIT"
|
81
|
-
ret += "
|
82
|
+
ret += "quitting IRC (#{saw.message})"
|
82
83
|
when "TOPIC"
|
83
84
|
ret += "changing the topic of #{saw.where} to #{saw.message}"
|
84
85
|
end
|
@@ -21,11 +21,11 @@ class SlashdotPlugin < Plugin
|
|
21
21
|
m.reply "search for #{search} failed"
|
22
22
|
return
|
23
23
|
end
|
24
|
-
|
24
|
+
debug xml.inspect
|
25
25
|
begin
|
26
26
|
doc = Document.new xml
|
27
27
|
rescue REXML::ParseException => e
|
28
|
-
|
28
|
+
warning e.inspect
|
29
29
|
m.reply "couldn't parse output XML: #{e.class}"
|
30
30
|
return
|
31
31
|
end
|
@@ -33,7 +33,7 @@ class SlashdotPlugin < Plugin
|
|
33
33
|
m.reply "search for #{search} failed"
|
34
34
|
return
|
35
35
|
end
|
36
|
-
|
36
|
+
debug doc.inspect
|
37
37
|
max = 8 if max > 8
|
38
38
|
done = 0
|
39
39
|
doc.elements.each("*/item") {|e|
|
@@ -50,9 +50,9 @@ class SlashdotPlugin < Plugin
|
|
50
50
|
end
|
51
51
|
|
52
52
|
def slashdot(m, params)
|
53
|
-
|
53
|
+
debug params.inspect
|
54
54
|
max = params[:limit].to_i
|
55
|
-
|
55
|
+
debug "max is #{max}"
|
56
56
|
xml = @bot.httputil.get(URI.parse("http://slashdot.org/slashdot.xml"))
|
57
57
|
unless xml
|
58
58
|
m.reply "slashdot news parse failed"
|
data/data/rbot/plugins/spell.rb
CHANGED
@@ -14,18 +14,23 @@ class SpellPlugin < Plugin
|
|
14
14
|
p.each_line {|l|
|
15
15
|
if(l =~ /^\*/)
|
16
16
|
m.reply "#{m.params} may be spelled correctly"
|
17
|
+
p.close
|
17
18
|
return
|
18
19
|
elsif(l =~ /^\s*&.*: (.*)$/)
|
19
20
|
m.reply "#{m.params}: #$1"
|
21
|
+
p.close
|
20
22
|
return
|
21
23
|
elsif(l =~ /^\s*\+ (.*)$/)
|
22
24
|
m.reply "#{m.params} is presumably derived from " + $1.downcase
|
25
|
+
p.close
|
23
26
|
return
|
24
27
|
elsif(l =~ /^\s*#/)
|
25
28
|
m.reply "#{m.params}: no suggestions"
|
29
|
+
p.close
|
26
30
|
return
|
27
31
|
end
|
28
32
|
}
|
33
|
+
p.close
|
29
34
|
else
|
30
35
|
m.reply "couldn't exec ispell :("
|
31
36
|
return
|
@@ -0,0 +1,121 @@
|
|
1
|
+
HE = [
|
2
|
+
|
3
|
+
['a superhumanly strong','an underprivileged','a globe-trotting','an impetuous','a shy','a suave','a notorious','a one-legged','an all-American','a short-sighted','an otherworldly','a hate-fuelled','a scrappy','an unconventional','a jaded','a leather-clad','a fiendish','a Nobel prize-winning','a suicidal','a maverick','a bookish','an old-fashioned','a witless','a lounge-singing','a war-weary','a scarfaced','a gun-slinging','an obese','a time-tossed','a benighted','an uncontrollable','an immortal','an oversexed','a world-famous','an ungodly','a fast talking','a deeply religious','a lonely','a sword-wielding','a genetically engineered'],
|
4
|
+
|
5
|
+
['white trash','zombie','shark-wrestling','playboy','guitar-strumming','Jewish',
|
6
|
+
'sweet-toothed','bohemian','crooked','chivalrous','moralistic','amnesiac','devious','drug-addicted',
|
7
|
+
'voodoo','Catholic','overambitious','coffee-fuelled','pirate','misogynist','skateboarding',
|
8
|
+
'arachnophobic','Amish','small-town','Republican','one-eyed','gay','guerilla','vegetarian',
|
9
|
+
'dishevelled','alcoholic','flyboy','ninja','albino','hunchbacked','neurotic','umbrella-wielding',
|
10
|
+
'native American','soccer-playing','day-dreaming'],
|
11
|
+
|
12
|
+
['grifter','stage actor','paramedic','gentleman spy','jungle king','hairdresser',
|
13
|
+
'photographer','ex-con','vagrant','filmmaker','werewolf','senator','romance novelist','shaman','cop',
|
14
|
+
'rock star','farmboy','cat burglar','cowboy','cyborg','inventor','assassin','boxer','dog-catcher',
|
15
|
+
'master criminal','gangster','firefighter','househusband','dwarf','librarian','paranormal investigator',
|
16
|
+
'Green Beret','waffle chef','vampire hunter','messiah','astronaut','sorceror','card sharp','matador',
|
17
|
+
'barbarian'],
|
18
|
+
|
19
|
+
['with a robot buddy named Sparky.','whom everyone believes is mad.','gone bad.',
|
20
|
+
'with a mysterious suitcase handcuffed to his arm.','living undercover at Ringling Bros. Circus.',
|
21
|
+
'searching for his wife''s true killer.','who dotes on his loving old ma.','looking for ''the Big One.''',
|
22
|
+
'who knows the secret of the alien invasion.','on the edge.','on a mission from God.','with a secret.',
|
23
|
+
'in drag.','plagued by the memory of his family''s brutal murder.','looking for a cure to the poison coursing through his veins.',
|
24
|
+
'moving from town to town, helping folk in trouble.',
|
25
|
+
'who must take medication to keep him sane.','who hangs with the wrong crowd.',
|
26
|
+
'possessed of the uncanny powers of an insect.','with a winning smile and a way with the ladies.',
|
27
|
+
'fleeing from a secret government programme.','from the ''hood.','haunted by an iconic dead American confidante.',
|
28
|
+
'with a passion for fast cars.','trapped in a world he never made.','in a wheelchair.',
|
29
|
+
'on the hunt for the last specimen of a great and near-mythical creature.','on the run.',
|
30
|
+
'for the 21st century.','who hides his scarred face behind a mask.','on the wrong side of the law.',
|
31
|
+
'with no name.','from the Mississippi delta.','with acid for blood.','with nothing left to lose.',
|
32
|
+
'haunted by memories of ''Nam.','on a search for his missing sister.','on his last day in the job.',
|
33
|
+
'from a doomed world.','who believes he can never love again.']
|
34
|
+
|
35
|
+
]
|
36
|
+
|
37
|
+
SHE = [
|
38
|
+
|
39
|
+
['a radical','a green-fingered','a tortured','a time-travelling','a vivacious',
|
40
|
+
'a scantily clad','a mistrustful','a violent','a transdimensional','a strong-willed','a ditzy','a man-hating',
|
41
|
+
'a high-kicking','a blind','an elegant','a supernatural','a foxy','a bloodthirsty','a cynical','a beautiful',
|
42
|
+
'a plucky','a sarcastic','a psychotic','a hard-bitten','a manipulative','an orphaned','a cosmopolitan',
|
43
|
+
'a chain-smoking','a cold-hearted','a warm-hearted','a sharp-shooting','an enchanted','a wealthy','a pregnant',
|
44
|
+
'a mentally unstable','a virginal','a brilliant','a disco-crazy','a provocative','an artistic'],
|
45
|
+
|
46
|
+
['tempestuous', 'Buddhist', 'foul-mouthed', 'nymphomaniac', 'green-skinned', 'impetuous', 'African-American','punk','hypochondriac','junkie','blonde','goth','insomniac','gypsy','mutant','renegade', 'tomboy','French-Canadian','motormouth','belly-dancing','communist','hip-hop','thirtysomething',
|
47
|
+
'cigar-chomping','extravagent','out-of-work','Bolivian','mute','cat-loving','snooty','wisecracking',
|
48
|
+
'red-headed','winged','kleptomaniac','antique-collecting','psychic','gold-digging','bisexual','paranoid',
|
49
|
+
'streetsmart'],
|
50
|
+
|
51
|
+
['archaeologist','pearl diver','mechanic','detective','hooker','femme fatale',
|
52
|
+
'former first lady','barmaid','fairy princess','magician''s assistant','schoolgirl','college professor',
|
53
|
+
'angel','bounty hunter','opera singer','cab driver','soap star','doctor','politician','lawyer','nun',
|
54
|
+
'snake charmer','journalist','bodyguard','vampire','stripper','Valkyrie','wrestler','mermaid','single mother',
|
55
|
+
'safe cracker','traffic cop','research scientist','queen of the dead','Hell''s Angel','museum curator',
|
56
|
+
'advertising executive','widow','mercenary','socialite'],
|
57
|
+
|
58
|
+
['on her way to prison for a murder she didn''t commit.','trying to make a difference in a man''s world.',
|
59
|
+
'with the soul of a mighty warrior.','looking for love in all the wrong places.','with an MBA from Harvard.',
|
60
|
+
'who hides her beauty behind a pair of thick-framed spectacles.','with the power to see death.',
|
61
|
+
'descended from a line of powerful witches.','from a family of eight older brothers.','with a flame-thrower.',
|
62
|
+
'with her own daytime radio talk show.','living on borrowed time.','who can talk to animals.',
|
63
|
+
'prone to fits of savage, blood-crazed rage.','who don''t take no shit from nobody.','with a knack for trouble.',
|
64
|
+
'who believes she is the reincarnation of an ancient Egyptian queen.','fleeing from a Satanic cult.',
|
65
|
+
'on the trail of a serial killer.','with a birthmark shaped like Liberty''s torch.',
|
66
|
+
'in the witness protection scheme.','from out of town.','from aristocratic European stock.',
|
67
|
+
'living homeless in New York''s sewers.','with only herself to blame.','from beyond the grave',
|
68
|
+
'married to the Mob.','from the wrong side of the tracks.','from a secret island of warrior women.',
|
69
|
+
'from Mars.','with someone else''s memories.','from a different time and place.','operating on the wrong side of the law.',
|
70
|
+
'who inherited a spooky stately manor from her late maiden aunt.','who dreams of becoming Elvis.',
|
71
|
+
'with a song in her heart and a spring in her step.','in the wrong place at the wrong time.',
|
72
|
+
'with an incredible destiny.','with the power to bend men''s minds.','with an evil twin sister.']
|
73
|
+
|
74
|
+
]
|
75
|
+
|
76
|
+
TITLE = [
|
77
|
+
|
78
|
+
['FATAL', 'PRIMAL', 'BASIC', 'LETHAL',
|
79
|
+
'FINAL', 'CLEAR', 'DIRTY', 'RED', 'FOREIGN', 'PRIMARY', 'EXECUTIVE',
|
80
|
+
'BLOOD', 'HARD', 'STEEL', 'TERMINAL', 'HOT', 'COLD', 'TOTAL', 'PROGNOSIS:',
|
81
|
+
'BURNING', 'FAST', 'PAINFUL', 'MISSION:', 'DEADLY', 'PARTIAL',
|
82
|
+
'RAGING', 'CORDIAL'],
|
83
|
+
|
84
|
+
['DECISION', 'INCISION', 'CONCLUSION',
|
85
|
+
'CONCUSSION', 'HEAT', 'FIRE', 'RECOIL', 'INSTINCT', 'DESIRE', 'WEAPON',
|
86
|
+
'BADGE', 'DEED', 'JUSTICE', 'HEAT', 'VENGEANCE', 'RECESSION', 'COMBUSTION',
|
87
|
+
'JUDGEMENT', 'WARNING', 'AWAKENING', 'JURISDICTION', 'BASIS', 'FINDINGS',
|
88
|
+
'INJECTION', 'REJECTION', 'REMISSION', 'DIGESTION', 'IDENTITY',
|
89
|
+
'DISPERSION'],
|
90
|
+
|
91
|
+
['II','III','IV','V','VI','VII','VIII','IX','X','XI','XII','XIII','XIV','XV','XVI','XVII','XVIII','XIX']
|
92
|
+
|
93
|
+
]
|
94
|
+
|
95
|
+
class TheyFightCrime < Plugin
|
96
|
+
def help(plugin, topic="")
|
97
|
+
"movieplot => generate a random movie scenario. movietitle => generate a random movie title."
|
98
|
+
end
|
99
|
+
|
100
|
+
def get_random_things(thing_array)
|
101
|
+
thing_array.map { |things| things[rand(things.length)] }
|
102
|
+
end
|
103
|
+
|
104
|
+
def do_movieplot(m, params)
|
105
|
+
he_things = get_random_things(HE)
|
106
|
+
she_things = get_random_things(SHE)
|
107
|
+
m.reply "Summary: He's #{he_things.join " "} She's #{she_things.join " "} They fight crime."
|
108
|
+
end
|
109
|
+
|
110
|
+
def do_movietitle(m, params)
|
111
|
+
title_things = get_random_things(TITLE)
|
112
|
+
m.reply "Title: #{title_things.join " "}"
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
plugin = TheyFightCrime.new
|
117
|
+
plugin.map 'movieplot', :action => 'do_movieplot'
|
118
|
+
plugin.map 'movietitle', :action => 'do_movietitle'
|
119
|
+
|
120
|
+
|
121
|
+
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# Security threat level plugin for rbot
|
2
|
+
# by Robin Kearney (robin@riviera.org.uk)
|
3
|
+
#
|
4
|
+
# inspired by elliots fascination with the us
|
5
|
+
# threat level.
|
6
|
+
#
|
7
|
+
# again a dirty hack but it works, just...
|
8
|
+
#
|
9
|
+
|
10
|
+
require 'uri/common'
|
11
|
+
|
12
|
+
class ThreatPlugin < Plugin
|
13
|
+
|
14
|
+
def help(plugin, topic="")
|
15
|
+
"threat => prints out the current threat level as reported by http://www.dhs.gov/"
|
16
|
+
end
|
17
|
+
|
18
|
+
def privmsg(m)
|
19
|
+
color = ""
|
20
|
+
red = "\x0304" # severe
|
21
|
+
orange = "\x0307" # high
|
22
|
+
yellow = "\x0308" # elevated
|
23
|
+
blue = "\x0312" # guarded
|
24
|
+
green = "\x0303" # low
|
25
|
+
black = "\x0301" # default
|
26
|
+
|
27
|
+
page = @bot.httputil.get URI.parse("http://www.dhs.gov/dhspublic/")
|
28
|
+
if page =~ / <img.*dhs\/images\/dhs-advisory-(.*).gif.*/
|
29
|
+
state = $1
|
30
|
+
end
|
31
|
+
case state
|
32
|
+
when "severe"
|
33
|
+
color = red
|
34
|
+
when "high"
|
35
|
+
color = orange
|
36
|
+
when "elevated"
|
37
|
+
color = yellow
|
38
|
+
when "guarded"
|
39
|
+
color = blue
|
40
|
+
when "low"
|
41
|
+
color = green
|
42
|
+
else
|
43
|
+
color = black
|
44
|
+
end
|
45
|
+
|
46
|
+
m.reply color + "Today " + m.sourcenick + " the threat level is " + state.capitalize
|
47
|
+
|
48
|
+
return
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
plugin = ThreatPlugin.new
|
53
|
+
plugin.register("threat")
|
54
|
+
|
55
|
+
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require "shorturl"
|
3
|
+
|
4
|
+
class TinyURL < Plugin
|
5
|
+
include WWW
|
6
|
+
|
7
|
+
# return a help string when the bot is asked for help on this plugin
|
8
|
+
def help(plugin, topic="")
|
9
|
+
return "tinyurl <your long url>"
|
10
|
+
end
|
11
|
+
|
12
|
+
# reply to a private message that we've registered for
|
13
|
+
def privmsg(m)
|
14
|
+
|
15
|
+
# m.params contains the rest of the message, m.plugin contains the first
|
16
|
+
# word (useful because it's possible to register for multiple commands)
|
17
|
+
unless(m.params)
|
18
|
+
m.reply "incorrect usage. " + help(m.plugin)
|
19
|
+
end
|
20
|
+
|
21
|
+
# TODO: might want to add a check here to validate the url
|
22
|
+
# if they call 'rubyurl help' backwards, don't return a lame link
|
23
|
+
|
24
|
+
if (m.params == "help")
|
25
|
+
m.reply "Try again. Correct usage is: " + help(m.plugin)
|
26
|
+
return false
|
27
|
+
end
|
28
|
+
|
29
|
+
# call the ShortURL library with the value of the url
|
30
|
+
url = ShortURL.shorten(m.params, :tinyurl)
|
31
|
+
|
32
|
+
m.reply "tinyurl: #{url}"
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# create an instance of the RubyURL class and register it as a plugin
|
38
|
+
tinyurl = TinyURL.new
|
39
|
+
tinyurl.register("tinyurl")
|
@@ -0,0 +1,204 @@
|
|
1
|
+
# Author: Giuseppe "Oblomov" Bilotta <giuseppe.bilotta@gmail.com>
|
2
|
+
# Add a bunch of topic manipulation features
|
3
|
+
|
4
|
+
class TopicPlugin < Plugin
|
5
|
+
def initialize
|
6
|
+
super
|
7
|
+
@separator = "|" # default separator
|
8
|
+
end
|
9
|
+
|
10
|
+
def help(plugin, topic="")
|
11
|
+
case plugin
|
12
|
+
when "topic"
|
13
|
+
case topic
|
14
|
+
when "add"
|
15
|
+
return "topic add <text> => add <text> at the end the topic"
|
16
|
+
when "prepend"
|
17
|
+
return "topic prepend <text> => add <text> at the beginning of the topic"
|
18
|
+
when "addat"
|
19
|
+
return "topic addat <num> <text> => add <text> at position <num> of the topic"
|
20
|
+
when "del", "delete"
|
21
|
+
return "topic del <num> => remove section <num> from the topic"
|
22
|
+
when "replace"
|
23
|
+
return "topic replace <num> <text> => Replaces section <num> with <text>"
|
24
|
+
when "sep", "separator"
|
25
|
+
return "topic sep(arator) [<text>] => get or set the topic section separator"
|
26
|
+
when "learn"
|
27
|
+
return "topic learn => remembers the topic for later"
|
28
|
+
when "restore"
|
29
|
+
return "topic restore => resets the topic to the latest remembered one"
|
30
|
+
when "clear"
|
31
|
+
return "topic clear => clears the topic"
|
32
|
+
when "set"
|
33
|
+
return "topic set <text> => sets the topic to <text>"
|
34
|
+
else
|
35
|
+
return "topic add(at)|prepend|del(ete)|replace|sep(arator)|learn|restore|clear|set: " + \
|
36
|
+
"manipulate the topic of the current channel; use topic <#channel> <command> " + \
|
37
|
+
"for private addressing"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def handletopic(m, param)
|
43
|
+
return unless m.kind_of?(PrivMessage)
|
44
|
+
if m.public?
|
45
|
+
ch = m.channel.downcase
|
46
|
+
else
|
47
|
+
ch = param[:channel].downcase
|
48
|
+
end
|
49
|
+
cmd = param[:command]
|
50
|
+
txt = param[:text].join(" ")
|
51
|
+
|
52
|
+
unless @bot.channels.has_key?(ch)
|
53
|
+
m.reply "I am not in channel #{ch}"
|
54
|
+
return
|
55
|
+
end
|
56
|
+
|
57
|
+
case cmd
|
58
|
+
when /^a(dd|ppend)$/
|
59
|
+
topicappend(m, ch, txt)
|
60
|
+
when 'prepend'
|
61
|
+
topicprepend(m, ch, txt)
|
62
|
+
when 'addat'
|
63
|
+
if txt =~ /\s*(-?\d+)\s+(.*)\s*/
|
64
|
+
num = $1.to_i - 1
|
65
|
+
num += 1 if num < 0
|
66
|
+
txt = $2
|
67
|
+
topicaddat(m, ch, num, txt)
|
68
|
+
end
|
69
|
+
when /^del(ete)?$/
|
70
|
+
if txt =~ /\s*(-?\d+)\s*/
|
71
|
+
num=$1.to_i - 1
|
72
|
+
num += 1 if num < 0
|
73
|
+
topicdel(m, ch, num)
|
74
|
+
end
|
75
|
+
when 'set'
|
76
|
+
topicset(m, ch, txt)
|
77
|
+
when 'clear'
|
78
|
+
topicset(m, ch, '')
|
79
|
+
when /^sep(arator)?$/
|
80
|
+
topicsep(m, ch, txt)
|
81
|
+
when 'learn'
|
82
|
+
learntopic(m, ch)
|
83
|
+
when 'replace'
|
84
|
+
if txt =~ /\s*(-?\d+)\s+(.*)\s*/
|
85
|
+
num = $1.to_i - 1
|
86
|
+
num += 1 if num < 0
|
87
|
+
txt = $2
|
88
|
+
replacetopic(m, ch, num, txt)
|
89
|
+
end
|
90
|
+
when 'restore'
|
91
|
+
restoretopic(m, ch)
|
92
|
+
else
|
93
|
+
m.reply 'unknown command'
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def topicsep(m, ch, txt)
|
98
|
+
if txt
|
99
|
+
sep = txt.strip
|
100
|
+
if sep != ""
|
101
|
+
setsep(ch, sep)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
m.reply "Topic separator set to #{getsep(ch)}"
|
105
|
+
end
|
106
|
+
|
107
|
+
def setsep(ch, sep)
|
108
|
+
if @registry.has_key?(ch)
|
109
|
+
data = @registry[ch]
|
110
|
+
else
|
111
|
+
data = Hash.new
|
112
|
+
end
|
113
|
+
|
114
|
+
oldsep = getsep(ch)
|
115
|
+
topic = @bot.channels[ch].topic.to_s
|
116
|
+
topicarray = topic.split(/\s+#{Regexp.escape(oldsep)}\s*/)
|
117
|
+
|
118
|
+
if sep != oldsep and topicarray.length > 0
|
119
|
+
newtopic = topicarray.join(" #{sep} ")
|
120
|
+
@bot.topic ch, newtopic
|
121
|
+
end
|
122
|
+
|
123
|
+
data[:separator] = sep
|
124
|
+
@registry[ch] = data
|
125
|
+
end
|
126
|
+
|
127
|
+
def getsep(ch)
|
128
|
+
if @registry.has_key?(ch)
|
129
|
+
if @registry[ch].has_key?(:separator)
|
130
|
+
return @registry[ch][:separator]
|
131
|
+
end
|
132
|
+
end
|
133
|
+
return @separator
|
134
|
+
end
|
135
|
+
|
136
|
+
def topicaddat(m, channel, num, txt)
|
137
|
+
sep = getsep(channel)
|
138
|
+
topic = @bot.channels[channel].topic.to_s
|
139
|
+
topicarray = topic.split(/\s+#{Regexp.escape(sep)}\s*/)
|
140
|
+
topicarray.insert(num, txt)
|
141
|
+
newtopic = topicarray.join(" #{sep} ")
|
142
|
+
@bot.topic channel, newtopic
|
143
|
+
end
|
144
|
+
|
145
|
+
def topicappend(m, ch, txt)
|
146
|
+
topicaddat(m, ch, -1, txt)
|
147
|
+
end
|
148
|
+
|
149
|
+
def topicprepend(m, ch, txt)
|
150
|
+
topicaddat(m, ch, 0, txt)
|
151
|
+
end
|
152
|
+
|
153
|
+
def topicdel(m, channel, num)
|
154
|
+
sep = getsep(channel)
|
155
|
+
topic = @bot.channels[channel].topic.to_s
|
156
|
+
topicarray = topic.split(/\s+#{Regexp.escape(sep)}\s*/)
|
157
|
+
topicarray.delete_at(num)
|
158
|
+
newtopic = topicarray.join(" #{sep} ")
|
159
|
+
@bot.topic channel, newtopic
|
160
|
+
end
|
161
|
+
|
162
|
+
def learntopic(m, channel)
|
163
|
+
return if !@bot.auth.allow?("learntopic", m.source, m.replyto)
|
164
|
+
topic = @bot.channels[channel].topic.to_s
|
165
|
+
if @registry.has_key?(channel)
|
166
|
+
data = @registry[channel]
|
167
|
+
else
|
168
|
+
data = Hash.new
|
169
|
+
end
|
170
|
+
data[:topic] = topic
|
171
|
+
@registry[channel] = data
|
172
|
+
m.okay
|
173
|
+
end
|
174
|
+
|
175
|
+
def replacetopic(m, channel, num, txt)
|
176
|
+
return if !@bot.auth.allow?("topic", m.source, m.replyto)
|
177
|
+
sep = getsep(channel)
|
178
|
+
topic = @bot.channels[channel].topic.to_s
|
179
|
+
topicarray = topic.split(/\s+#{Regexp.escape(sep)}\s*/)
|
180
|
+
topicarray[num] = txt
|
181
|
+
newtopic = topicarray.join(" #{sep} ")
|
182
|
+
@bot.topic channel, newtopic
|
183
|
+
end
|
184
|
+
|
185
|
+
def restoretopic(m, channel)
|
186
|
+
return if !@bot.auth.allow?("restoretopic", m.source, m.replyto)
|
187
|
+
if @registry.has_key?(channel) && @registry[channel].has_key?(:topic)
|
188
|
+
topic = @registry[channel][:topic]
|
189
|
+
@bot.topic channel, topic
|
190
|
+
else
|
191
|
+
m.reply "I don't remember any topic for this channel"
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
def topicset(m, channel, text)
|
196
|
+
return if !@bot.auth.allow?("topic", m.source, m.replyto)
|
197
|
+
@bot.topic channel, text
|
198
|
+
end
|
199
|
+
|
200
|
+
end
|
201
|
+
plugin = TopicPlugin.new
|
202
|
+
plugin.map 'topic :command *text', :action => 'handletopic', :public => true, :private => false
|
203
|
+
plugin.map 'topic :channel :command *text', :action => 'handletopic', :public => false, :private => true
|
204
|
+
|