butler 1.8.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +4 -0
- data/GPL.txt +340 -0
- data/LICENSE.txt +52 -0
- data/README +37 -0
- data/Rakefile +334 -0
- data/bin/botcontrol +230 -0
- data/data/butler/config_template.yaml +4 -0
- data/data/butler/dialogs/backup.rb +19 -0
- data/data/butler/dialogs/botcontrol.rb +4 -0
- data/data/butler/dialogs/config.rb +1 -0
- data/data/butler/dialogs/create.rb +53 -0
- data/data/butler/dialogs/delete.rb +3 -0
- data/data/butler/dialogs/en/backup.yaml +6 -0
- data/data/butler/dialogs/en/botcontrol.yaml +5 -0
- data/data/butler/dialogs/en/create.yaml +11 -0
- data/data/butler/dialogs/en/delete.yaml +2 -0
- data/data/butler/dialogs/en/help.yaml +17 -0
- data/data/butler/dialogs/en/info.yaml +13 -0
- data/data/butler/dialogs/en/list.yaml +4 -0
- data/data/butler/dialogs/en/notyetimplemented.yaml +2 -0
- data/data/butler/dialogs/en/rename.yaml +3 -0
- data/data/butler/dialogs/en/start.yaml +3 -0
- data/data/butler/dialogs/en/sync_plugins.yaml +3 -0
- data/data/butler/dialogs/en/uninstall.yaml +5 -0
- data/data/butler/dialogs/en/unknown_command.yaml +2 -0
- data/data/butler/dialogs/help.rb +11 -0
- data/data/butler/dialogs/info.rb +27 -0
- data/data/butler/dialogs/interactive.rb +1 -0
- data/data/butler/dialogs/list.rb +10 -0
- data/data/butler/dialogs/notyetimplemented.rb +1 -0
- data/data/butler/dialogs/rename.rb +4 -0
- data/data/butler/dialogs/selectbot.rb +2 -0
- data/data/butler/dialogs/start.rb +5 -0
- data/data/butler/dialogs/sync_plugins.rb +30 -0
- data/data/butler/dialogs/uninstall.rb +17 -0
- data/data/butler/dialogs/unknown_command.rb +1 -0
- data/data/butler/plugins/core/logout.rb +41 -0
- data/data/butler/plugins/core/plugins.rb +134 -0
- data/data/butler/plugins/core/privilege.rb +103 -0
- data/data/butler/plugins/core/user.rb +166 -0
- data/data/butler/plugins/dev/eval.rb +64 -0
- data/data/butler/plugins/dev/nometa.rb +14 -0
- data/data/butler/plugins/dev/onhandlers.rb +93 -0
- data/data/butler/plugins/dev/raw.rb +36 -0
- data/data/butler/plugins/dev/rawlog.rb +77 -0
- data/data/butler/plugins/games/eightball.rb +54 -0
- data/data/butler/plugins/games/mastermind.rb +174 -0
- data/data/butler/plugins/irc/action.rb +36 -0
- data/data/butler/plugins/irc/join.rb +38 -0
- data/data/butler/plugins/irc/notice.rb +36 -0
- data/data/butler/plugins/irc/part.rb +38 -0
- data/data/butler/plugins/irc/privmsg.rb +36 -0
- data/data/butler/plugins/irc/quit.rb +36 -0
- data/data/butler/plugins/operator/deop.rb +41 -0
- data/data/butler/plugins/operator/devoice.rb +41 -0
- data/data/butler/plugins/operator/limit.rb +47 -0
- data/data/butler/plugins/operator/op.rb +41 -0
- data/data/butler/plugins/operator/voice.rb +41 -0
- data/data/butler/plugins/public/help.rb +69 -0
- data/data/butler/plugins/public/login.rb +72 -0
- data/data/butler/plugins/public/usage.rb +49 -0
- data/data/butler/plugins/service/clones.rb +56 -0
- data/data/butler/plugins/service/define.rb +47 -0
- data/data/butler/plugins/service/log.rb +183 -0
- data/data/butler/plugins/service/svn.rb +91 -0
- data/data/butler/plugins/util/cycle.rb +98 -0
- data/data/butler/plugins/util/load.rb +41 -0
- data/data/butler/plugins/util/pong.rb +29 -0
- data/data/butler/strings/random/acknowledge.en.yaml +5 -0
- data/data/butler/strings/random/gratitude.en.yaml +3 -0
- data/data/butler/strings/random/hello.en.yaml +4 -0
- data/data/butler/strings/random/ignorance.en.yaml +7 -0
- data/data/butler/strings/random/ignorance_about.en.yaml +3 -0
- data/data/butler/strings/random/insult.en.yaml +3 -0
- data/data/butler/strings/random/rejection.en.yaml +12 -0
- data/data/man/botcontrol.1 +17 -0
- data/lib/access.rb +187 -0
- data/lib/access/admin.rb +16 -0
- data/lib/access/privilege.rb +122 -0
- data/lib/access/role.rb +102 -0
- data/lib/access/savable.rb +18 -0
- data/lib/access/user.rb +180 -0
- data/lib/access/yamlbase.rb +126 -0
- data/lib/butler.rb +188 -0
- data/lib/butler/bot.rb +247 -0
- data/lib/butler/control.rb +93 -0
- data/lib/butler/dialog.rb +64 -0
- data/lib/butler/initialvalues.rb +40 -0
- data/lib/butler/irc/channel.rb +135 -0
- data/lib/butler/irc/channels.rb +96 -0
- data/lib/butler/irc/client.rb +351 -0
- data/lib/butler/irc/hostmask.rb +53 -0
- data/lib/butler/irc/message.rb +184 -0
- data/lib/butler/irc/parser.rb +125 -0
- data/lib/butler/irc/parser/commands.rb +83 -0
- data/lib/butler/irc/parser/generic.rb +343 -0
- data/lib/butler/irc/socket.rb +378 -0
- data/lib/butler/irc/string.rb +186 -0
- data/lib/butler/irc/topic.rb +15 -0
- data/lib/butler/irc/user.rb +265 -0
- data/lib/butler/irc/users.rb +112 -0
- data/lib/butler/plugin.rb +249 -0
- data/lib/butler/plugin/configproxy.rb +35 -0
- data/lib/butler/plugin/mapper.rb +85 -0
- data/lib/butler/plugin/matcher.rb +55 -0
- data/lib/butler/plugin/onhandlers.rb +70 -0
- data/lib/butler/plugin/trigger.rb +58 -0
- data/lib/butler/plugins.rb +147 -0
- data/lib/butler/version.rb +17 -0
- data/lib/cloptions.rb +217 -0
- data/lib/cloptions/adapters.rb +24 -0
- data/lib/cloptions/switch.rb +132 -0
- data/lib/configuration.rb +223 -0
- data/lib/dialogline.rb +296 -0
- data/lib/dialogline/localizations.rb +24 -0
- data/lib/durations.rb +57 -0
- data/lib/event.rb +295 -0
- data/lib/event/at.rb +64 -0
- data/lib/event/every.rb +56 -0
- data/lib/event/timed.rb +112 -0
- data/lib/installer.rb +75 -0
- data/lib/iterator.rb +34 -0
- data/lib/log.rb +68 -0
- data/lib/log/comfort.rb +85 -0
- data/lib/log/converter.rb +23 -0
- data/lib/log/entry.rb +152 -0
- data/lib/log/fakeio.rb +55 -0
- data/lib/log/file.rb +54 -0
- data/lib/log/filereader.rb +81 -0
- data/lib/log/forward.rb +49 -0
- data/lib/log/methods.rb +39 -0
- data/lib/log/nolog.rb +18 -0
- data/lib/log/splitter.rb +26 -0
- data/lib/ostructfixed.rb +26 -0
- data/lib/ruby/array/columnize.rb +38 -0
- data/lib/ruby/dir/mktree.rb +28 -0
- data/lib/ruby/enumerable/join.rb +13 -0
- data/lib/ruby/exception/detailed.rb +24 -0
- data/lib/ruby/file/append.rb +11 -0
- data/lib/ruby/file/write.rb +11 -0
- data/lib/ruby/hash/zip.rb +15 -0
- data/lib/ruby/kernel/bench.rb +15 -0
- data/lib/ruby/kernel/daemonize.rb +42 -0
- data/lib/ruby/kernel/non_verbose.rb +17 -0
- data/lib/ruby/kernel/safe_fork.rb +18 -0
- data/lib/ruby/range/stepped.rb +11 -0
- data/lib/ruby/string/arguments.rb +72 -0
- data/lib/ruby/string/chunks.rb +15 -0
- data/lib/ruby/string/post_arguments.rb +44 -0
- data/lib/ruby/string/unescaped.rb +17 -0
- data/lib/scheduler.rb +164 -0
- data/lib/scriptfile.rb +101 -0
- data/lib/templater.rb +86 -0
- data/test/cloptions.rb +134 -0
- data/test/cv.rb +28 -0
- data/test/irc/client.rb +85 -0
- data/test/irc/client_login.txt +53 -0
- data/test/irc/client_subscribe.txt +8 -0
- data/test/irc/message.rb +30 -0
- data/test/irc/messages.txt +64 -0
- data/test/irc/parser.rb +13 -0
- data/test/irc/profile_parser.rb +12 -0
- data/test/irc/users.rb +28 -0
- metadata +256 -0
@@ -0,0 +1,72 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright 2007 by Stefan Rusterholz.
|
3
|
+
# All rights reserved.
|
4
|
+
# See LICENSE.txt for permissions.
|
5
|
+
#++
|
6
|
+
|
7
|
+
|
8
|
+
|
9
|
+
#extend OnHandlers
|
10
|
+
trigger "login"
|
11
|
+
|
12
|
+
# FIXME, requires working OnHandlers
|
13
|
+
# FIXME, requires Butler::IRC::Message#answer to work with :JOIN
|
14
|
+
def on_join
|
15
|
+
if @message.from.user[0,1] == "i" then
|
16
|
+
# check nick->user mappings
|
17
|
+
if user = plugin.config["nickmap"][@message.from.nick] then
|
18
|
+
@message.from.
|
19
|
+
answer(:success)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# FIXME, log events
|
25
|
+
# FIXME, accept plain login, using IDENT_CAPAB
|
26
|
+
def on_trigger
|
27
|
+
return answer(usage) unless [3].include?(@message.arguments.length)
|
28
|
+
|
29
|
+
if access = @butler.access.login(*@message.arguments[1,2]) then
|
30
|
+
@message.from.access = access
|
31
|
+
answer(:success)
|
32
|
+
if @message.public? then
|
33
|
+
@message.from.access.credentials = nil
|
34
|
+
answer(:public_success)
|
35
|
+
end
|
36
|
+
else
|
37
|
+
answer(:failure)
|
38
|
+
answer(:public_failure) if @message.public?
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
__END__
|
43
|
+
---
|
44
|
+
:revision:
|
45
|
+
:plugin: 1
|
46
|
+
:summary:
|
47
|
+
en: Authenticate to the bot
|
48
|
+
:about:
|
49
|
+
:mail: "apeiros@gmx.net"
|
50
|
+
:version: "1.0.0"
|
51
|
+
:author: "Stefan Rusterholz"
|
52
|
+
:strings:
|
53
|
+
:success:
|
54
|
+
en: You are now authenticated.
|
55
|
+
:failure:
|
56
|
+
en: Could not authenticate you.
|
57
|
+
:public_success:
|
58
|
+
en: |
|
59
|
+
You authenticated yourself in public. Your password has been deleted.
|
60
|
+
Please set a new one immediatly using 'access password ![c(blue)]password![o]'
|
61
|
+
:public_failure:
|
62
|
+
en: |
|
63
|
+
You tried to authenticate yourself in public. Be aware that a public login will result in a reset password.
|
64
|
+
If this was similar to your real password, then please login and set a new one immediatly using 'access password ![(blue)]password![r]'
|
65
|
+
:usage:
|
66
|
+
en: |
|
67
|
+
![b]login![o] ![c(blue)]username password![o]
|
68
|
+
:help:
|
69
|
+
en:
|
70
|
+
"": |
|
71
|
+
Using 'login ![c(blue)]username password![o]' you can Authenticate to the bot.
|
72
|
+
Be aware that the bot will delete your password if you authenticate in public as a protection measure.
|
@@ -0,0 +1,49 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright 2007 by Stefan Rusterholz.
|
3
|
+
# All rights reserved.
|
4
|
+
# See LICENSE.txt for permissions.
|
5
|
+
#++
|
6
|
+
|
7
|
+
|
8
|
+
|
9
|
+
trigger "usage"
|
10
|
+
|
11
|
+
def on_trigger
|
12
|
+
if @message.arguments.length != 2 then
|
13
|
+
answer(usage)
|
14
|
+
elsif plugin = @butler.plugins.identify(@message.arguments[1]) then
|
15
|
+
answer(@butler.plugins[plugin].plugin_usage(@message))
|
16
|
+
else
|
17
|
+
answer(:no_plugin, :name => @message.arguments[1])
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
__END__
|
22
|
+
---
|
23
|
+
:revision:
|
24
|
+
:plugin: 1
|
25
|
+
:summary:
|
26
|
+
en: Give information about elementary usage of a plugin
|
27
|
+
:about:
|
28
|
+
:mail: "apeiros@gmx.net"
|
29
|
+
:version: "1.0.0"
|
30
|
+
:author: "Stefan Rusterholz"
|
31
|
+
:strings:
|
32
|
+
:no_plugin:
|
33
|
+
en: |
|
34
|
+
No plugin named <%= name %> loaded.
|
35
|
+
:usage:
|
36
|
+
en: |
|
37
|
+
![b]usage![o] <![c(green)]plugin![o]>
|
38
|
+
:help:
|
39
|
+
en:
|
40
|
+
"": |
|
41
|
+
Usage provides you with elementary information on how to use a plugin-command.
|
42
|
+
If you need more information, use the help command.
|
43
|
+
"keyword": |
|
44
|
+
Arguments in green and embraced by <angle brackets> are keyword arguments.
|
45
|
+
Keyword arguments require a specific format.
|
46
|
+
"keyword nick": |
|
47
|
+
A <nick> argument must be a valid (not necessary online) IRC nickname.
|
48
|
+
"keyword channel": |
|
49
|
+
A <channel> argument must be a valid (not necessary existing) IRC channelname.
|
@@ -0,0 +1,56 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright 2007 by Stefan Rusterholz.
|
3
|
+
# All rights reserved.
|
4
|
+
# See LICENSE.txt for permissions.
|
5
|
+
#++
|
6
|
+
|
7
|
+
|
8
|
+
|
9
|
+
trigger "clones"
|
10
|
+
|
11
|
+
def on_trigger
|
12
|
+
strong = @message.arguments.last != "weak"
|
13
|
+
if (@message.arguments.length == 2 && @message.arguments[1].valid_channelname?) then
|
14
|
+
all_clones = @butler.channels[message.arguments[1]].clones(strong)
|
15
|
+
answer(:clones_in_channel, :channel => message.arguments[1], :count => all_clones.length)
|
16
|
+
answer_clones(all_clones)
|
17
|
+
else
|
18
|
+
all_clones = @butler.users.clones(strong)
|
19
|
+
answer(:all_clones, :count => all_clones.length)
|
20
|
+
answer_clones(all_clones)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def answer_clones(all_clones)
|
25
|
+
all_clones.each { |common, clones|
|
26
|
+
answer(:clonelist, :common => common, :clones => clones)
|
27
|
+
}
|
28
|
+
end
|
29
|
+
|
30
|
+
__END__
|
31
|
+
---
|
32
|
+
:revision:
|
33
|
+
:plugin: 1
|
34
|
+
:summary:
|
35
|
+
en: Let butler send a notice to a user or channel
|
36
|
+
:about:
|
37
|
+
:mail: "apeiros@gmx.net"
|
38
|
+
:version: "1.0.0"
|
39
|
+
:author: "Stefan Rusterholz"
|
40
|
+
:strings:
|
41
|
+
:clones_in_channel:
|
42
|
+
en: |
|
43
|
+
Clones in channel <%= channel %> (<%= count %>):
|
44
|
+
:all_clones:
|
45
|
+
en: |
|
46
|
+
All clones (<%= count %>):
|
47
|
+
:clonelist:
|
48
|
+
en: |
|
49
|
+
<%= common %>: <%= clones.map { |u| "#{u.nick}" }.join(", ") %>
|
50
|
+
:usage:
|
51
|
+
en: |
|
52
|
+
![b]notice![o] (![c(green)]nick![o] | ![c(green)]channel![o])
|
53
|
+
:help:
|
54
|
+
en:
|
55
|
+
"": |
|
56
|
+
Let butler send a notice to a user or channel.
|
@@ -0,0 +1,47 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright 2007 by Stefan Rusterholz.
|
3
|
+
# All rights reserved.
|
4
|
+
# See LICENSE.txt for permissions.
|
5
|
+
#++
|
6
|
+
|
7
|
+
|
8
|
+
|
9
|
+
require 'open-uri'
|
10
|
+
require 'hpricot'
|
11
|
+
require 'cgi'
|
12
|
+
|
13
|
+
Query = "http://www.google.com/search?client=butler&rls=%s&q=define:+%s&ie=UTF-8&oe=UTF-8"
|
14
|
+
|
15
|
+
trigger "define"
|
16
|
+
|
17
|
+
def on_trigger
|
18
|
+
word = @message.post_arguments[1]
|
19
|
+
doc = Hpricot(open(Query%[@message.language, CGI.escape(word)]))
|
20
|
+
see_also = (doc/"//div[@id='res']/font[1]/p/a")[5..-1].map { |e| e.inner_text }
|
21
|
+
found = (doc/"//div[@id='res']/ul/font/li").find { |e| (e/"//a").inner_text.include?("wikipedia.org") }
|
22
|
+
if found then
|
23
|
+
answer(found.inner_text.sub(%r{\w+\.wikipedia\.org/wiki/.*?$}, ''))
|
24
|
+
else
|
25
|
+
answer(:not_found, :search_string => word)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
__END__
|
30
|
+
---
|
31
|
+
:revision:
|
32
|
+
:plugin: 1
|
33
|
+
:configuration: 1
|
34
|
+
:summary:
|
35
|
+
en: "Use googles define: to find the definition of words."
|
36
|
+
:about:
|
37
|
+
:mail: "apeiros@gmx.net"
|
38
|
+
:version: "1.0.0"
|
39
|
+
:author: "Stefan Rusterholz"
|
40
|
+
:usage:
|
41
|
+
en: "![b]define![o] *search_string"
|
42
|
+
:help:
|
43
|
+
en:
|
44
|
+
"": "Use googles define: to find the definition of words."
|
45
|
+
:strings:
|
46
|
+
:not_found:
|
47
|
+
en: No search result for '<%= search_string %>'.
|
@@ -0,0 +1,183 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright 2007 by Stefan Rusterholz.
|
3
|
+
# All rights reserved.
|
4
|
+
# See LICENSE.txt for permissions.
|
5
|
+
#++
|
6
|
+
|
7
|
+
|
8
|
+
|
9
|
+
require 'sequel/sqlite'
|
10
|
+
|
11
|
+
class <<self
|
12
|
+
attr_reader :log_db
|
13
|
+
attr_reader :log_table
|
14
|
+
end
|
15
|
+
|
16
|
+
@log_db = Sequel.sqlite @butler.path.log+'/log.sqlite'
|
17
|
+
|
18
|
+
configuration(
|
19
|
+
"channels" => []
|
20
|
+
)
|
21
|
+
@log_db.create_table(:log) {
|
22
|
+
primary_key :oid, :integer
|
23
|
+
int :time
|
24
|
+
str :channel, :size => 255
|
25
|
+
str :nick, :size => 48
|
26
|
+
int :type
|
27
|
+
text :text
|
28
|
+
} unless @log_db.table_exists?(:log)
|
29
|
+
@log_table = @log_db[:log]
|
30
|
+
|
31
|
+
MessageTypes = [:PRIVMSG, :NOTICE, :JOIN, :PART, :QUIT, :KICK, :KILL]
|
32
|
+
|
33
|
+
trigger "log"
|
34
|
+
|
35
|
+
def on_trigger
|
36
|
+
case @message.arguments[1]
|
37
|
+
when "list"
|
38
|
+
answer(:list, :channels => plugin.config["channels"])
|
39
|
+
when "on"
|
40
|
+
plugin.config["channels"] |= message.arguments[2..-1]
|
41
|
+
answer(:activated, :channels => message.arguments[2..-1])
|
42
|
+
when "off"
|
43
|
+
plugin.config["channels"] -= message.arguments[2..-1]
|
44
|
+
answer(:deactivated, :channels => message.arguments[2..-1])
|
45
|
+
when "search"
|
46
|
+
text, channel, from = @message.text.match(/search (.*)(?: in channel (#\w+))?(?: from (\w+))?$/).captures
|
47
|
+
text = "%#{text}%" if text
|
48
|
+
filtered = plugin.log_table #.filter { :type == 0 || :type == 1 }
|
49
|
+
filtered = filtered.filter { :nick == from } if from
|
50
|
+
filtered = filtered.filter { :nick == channel } if channel
|
51
|
+
filtered = filtered.filter { :text =~ text } if text
|
52
|
+
count = filtered.count
|
53
|
+
if count.zero? then
|
54
|
+
answer(:no_match)
|
55
|
+
else
|
56
|
+
upper = [5,count].min
|
57
|
+
answer("Found (1-#{upper} of #{count}):")
|
58
|
+
filtered.order(:time.DESC).first(5).each_with_index { |row, index|
|
59
|
+
answer(
|
60
|
+
"#{index+1}: " \
|
61
|
+
"[#{Time.at(row[:time]).strftime('%Y-%m-%d %H:%M')}, " \
|
62
|
+
"#{row[:from]} in #{row[:channel]}] " \
|
63
|
+
"#{row[:text]}"
|
64
|
+
)
|
65
|
+
}
|
66
|
+
end
|
67
|
+
when "dump"
|
68
|
+
n = @message.arguments[2].to_i
|
69
|
+
n = 5 if n.zero?
|
70
|
+
data = plugin.log_table.order(:time.DESC).first(n)
|
71
|
+
answer("Dump(#{data.length}):")
|
72
|
+
data.each_with_index { |row, index|
|
73
|
+
answer(
|
74
|
+
"#{index+1}: " \
|
75
|
+
"[#{Time.at(row[:time]).strftime('%Y-%m-%d %H:%M')}, " \
|
76
|
+
"#{row[:from]} in #{row[:channel]}] " \
|
77
|
+
"#{row[:text]}"
|
78
|
+
)
|
79
|
+
}
|
80
|
+
else
|
81
|
+
answer(usage)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
subscribe(:PRIVMSG, -10, nil, MessageTypes.index(:PRIVMSG)) { |listener, message, type|
|
86
|
+
next unless @config["channels"].include?(message.channel.to_str)
|
87
|
+
@log_table << {
|
88
|
+
:time => Time.now.to_i,
|
89
|
+
:channel => message.channel.to_str,
|
90
|
+
:nick => message.from.nick,
|
91
|
+
:type => type,
|
92
|
+
:text => message.text
|
93
|
+
}
|
94
|
+
}
|
95
|
+
subscribe(:NOTICE, -10, nil, MessageTypes.index(:NOTICE)) { |listener, message, type|
|
96
|
+
next unless @config["channels"].include?(message.channel.to_str)
|
97
|
+
@log_table << {
|
98
|
+
:time => Time.now.to_i,
|
99
|
+
:channel => message.channel.to_str,
|
100
|
+
:nick => message.from.nick,
|
101
|
+
:type => type,
|
102
|
+
:text => message.text
|
103
|
+
}
|
104
|
+
}
|
105
|
+
subscribe(:JOIN, -10, nil, MessageTypes.index(:JOIN)) { |listener, message, type|
|
106
|
+
next unless @config["channels"].include?(message.channel.to_str)
|
107
|
+
@log_table << {
|
108
|
+
:time => Time.now.to_i,
|
109
|
+
:channel => message.channel.to_str,
|
110
|
+
:nick => message.from.nick,
|
111
|
+
:type => type,
|
112
|
+
:text => nil
|
113
|
+
}
|
114
|
+
}
|
115
|
+
subscribe(:PART, -10, nil, MessageTypes.index(:PART)) { |listener, message, type|
|
116
|
+
next unless @config["channels"].include?(message.channel.to_str)
|
117
|
+
@log_table << {
|
118
|
+
:time => Time.now.to_i,
|
119
|
+
:channel => message.channel.to_str,
|
120
|
+
:nick => message.from.nick,
|
121
|
+
:type => type,
|
122
|
+
:text => message.text
|
123
|
+
}
|
124
|
+
}
|
125
|
+
subscribe(:QUIT, -10, nil, MessageTypes.index(:QUIT)) { |listener, message, type|
|
126
|
+
next unless @config["channels"].include?(message.channel.to_str)
|
127
|
+
@log_table << {
|
128
|
+
:time => Time.now.to_i,
|
129
|
+
:channel => message.channel.to_str,
|
130
|
+
:nick => message.from.nick,
|
131
|
+
:type => type,
|
132
|
+
:text => message.text
|
133
|
+
}
|
134
|
+
}
|
135
|
+
subscribe(:KICK, -10, nil, MessageTypes.index(:KICK)) { |listener, message, type|
|
136
|
+
next unless @config["channels"].include?(message.channel.to_str)
|
137
|
+
@log_table << {
|
138
|
+
:time => Time.now.to_i,
|
139
|
+
:channel => message.channel.to_str,
|
140
|
+
:nick => message.from.nick,
|
141
|
+
:type => type,
|
142
|
+
:text => message.text
|
143
|
+
}
|
144
|
+
}
|
145
|
+
subscribe(:KILL, -10, nil, MessageTypes.index(:KILL)) { |listener, message, type|
|
146
|
+
next unless @config["channels"].include?(message.channel.to_str)
|
147
|
+
@log_table << {
|
148
|
+
:time => Time.now.to_i,
|
149
|
+
:channel => message.channel.to_str,
|
150
|
+
:nick => message.from.nick,
|
151
|
+
:type => type,
|
152
|
+
:text => message.text
|
153
|
+
}
|
154
|
+
}
|
155
|
+
|
156
|
+
__END__
|
157
|
+
---
|
158
|
+
:revision:
|
159
|
+
:plugin: 1
|
160
|
+
:configuration: 1
|
161
|
+
:summary:
|
162
|
+
en: Log channel messages
|
163
|
+
:about:
|
164
|
+
:mail: "apeiros@gmx.net"
|
165
|
+
:version: "1.0.0"
|
166
|
+
:author: "Stefan Rusterholz"
|
167
|
+
:usage:
|
168
|
+
en: "![b]log![o] 'list'"
|
169
|
+
:help:
|
170
|
+
en:
|
171
|
+
"": Log channel messages.
|
172
|
+
:strings:
|
173
|
+
:no_match:
|
174
|
+
en: "No match found."
|
175
|
+
:list:
|
176
|
+
en: |
|
177
|
+
Logging is active for: <%= channels.join(', ') %>.
|
178
|
+
:activated:
|
179
|
+
en: |
|
180
|
+
Logging activated in: <%= channels.join(', ') %>.
|
181
|
+
:deactivated:
|
182
|
+
en: |
|
183
|
+
Logging deactivated in: <%= channels.join(', ') %>.
|
@@ -0,0 +1,91 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright 2007 by Stefan Rusterholz.
|
3
|
+
# All rights reserved.
|
4
|
+
# See LICENSE.txt for permissions.
|
5
|
+
#++
|
6
|
+
|
7
|
+
|
8
|
+
|
9
|
+
require 'open-uri'
|
10
|
+
require 'hpricot'
|
11
|
+
require 'cgi'
|
12
|
+
|
13
|
+
configuration(
|
14
|
+
"frequency" => 900,
|
15
|
+
"repositories" => {}
|
16
|
+
)
|
17
|
+
|
18
|
+
def self.current_revision(repo)
|
19
|
+
(Hpricot.XML(`svn info --xml #{repo}`)/"info/entry").first.attributes["revision"].to_i
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.changes(repo, from, to=nil)
|
23
|
+
range = to ? "#{from}:#{to}" : from.to_s
|
24
|
+
doc = Hpricot.XML(`svn log -r #{range} --xml #{repo}`)
|
25
|
+
(doc/"log/logentry").map { |entry|
|
26
|
+
"#{(entry/'author').inner_text}, " \
|
27
|
+
"r#{entry.attributes['revision']}: " \
|
28
|
+
"#{(entry/'msg').inner_text.gsub("\n", ' ')}"
|
29
|
+
}
|
30
|
+
end
|
31
|
+
|
32
|
+
every(@config["frequency"]) do
|
33
|
+
repositories = @config["repositories"]
|
34
|
+
repositories.each { |repo, data|
|
35
|
+
cr, lr = current_revision(repo), data[:revision]
|
36
|
+
if cr > lr then
|
37
|
+
data[:revision] = cr
|
38
|
+
@config["repositories"] = repositories
|
39
|
+
changed = changes(repo, lr+1, cr).join("\n")
|
40
|
+
@butler.irc.privmsg(changed, *data[:channels])
|
41
|
+
end
|
42
|
+
}
|
43
|
+
end
|
44
|
+
|
45
|
+
trigger "svn"
|
46
|
+
|
47
|
+
def on_trigger
|
48
|
+
repos = plugin.config["repositories"]
|
49
|
+
case arguments(1)
|
50
|
+
when "add"
|
51
|
+
repo = @message.arguments[2]
|
52
|
+
repos[repo] = {
|
53
|
+
:revision => plugin.current_revision(repo),
|
54
|
+
:channels => @message.arguments[3..-1]
|
55
|
+
}
|
56
|
+
plugin.config["repositories"] = repos
|
57
|
+
answer(:added, :repository => repo)
|
58
|
+
|
59
|
+
when "remove"
|
60
|
+
repo = @message.arguments[2]
|
61
|
+
repos.delete(repo)
|
62
|
+
plugin.config["repositories"] = repos
|
63
|
+
answer(:removed, :repository => repo)
|
64
|
+
|
65
|
+
else
|
66
|
+
answer(usage)
|
67
|
+
end
|
68
|
+
#
|
69
|
+
end
|
70
|
+
|
71
|
+
__END__
|
72
|
+
---
|
73
|
+
:revision:
|
74
|
+
:plugin: 1
|
75
|
+
:configuration: 1
|
76
|
+
:summary:
|
77
|
+
en: "Poll repositories for changes and publicate them."
|
78
|
+
:about:
|
79
|
+
:mail: "apeiros@gmx.net"
|
80
|
+
:version: "1.0.0"
|
81
|
+
:author: "Stefan Rusterholz"
|
82
|
+
:usage:
|
83
|
+
en: "![b]svn![o] 'add' repository channel ..."
|
84
|
+
:help:
|
85
|
+
en:
|
86
|
+
"": "Poll repositories for changes and publicate them."
|
87
|
+
:strings:
|
88
|
+
:added:
|
89
|
+
en: Added repository <%= repository %>.
|
90
|
+
:removed:
|
91
|
+
en: Added repository <%= repository %>.
|