cinch 1.0.2 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +25 -44
- data/examples/basic/autovoice.rb +1 -1
- data/examples/basic/join_part.rb +0 -4
- data/examples/plugins/autovoice.rb +2 -5
- data/examples/plugins/google.rb +1 -2
- data/examples/plugins/hooks.rb +36 -0
- data/examples/plugins/lambdas.rb +35 -0
- data/examples/plugins/last_nick.rb +24 -0
- data/examples/plugins/multiple_matches.rb +1 -10
- data/examples/plugins/own_events.rb +37 -0
- data/examples/plugins/timer.rb +22 -0
- data/examples/plugins/url_shorten.rb +1 -1
- data/lib/cinch.rb +50 -1
- data/lib/cinch/ban.rb +5 -2
- data/lib/cinch/bot.rb +360 -193
- data/lib/cinch/cache_manager.rb +15 -0
- data/lib/cinch/callback.rb +6 -0
- data/lib/cinch/channel.rb +150 -96
- data/lib/cinch/channel_manager.rb +26 -0
- data/lib/cinch/constants.rb +6 -4
- data/lib/cinch/exceptions.rb +9 -0
- data/lib/cinch/irc.rb +197 -82
- data/lib/cinch/logger/formatted_logger.rb +8 -8
- data/lib/cinch/logger/zcbot_logger.rb +37 -0
- data/lib/cinch/mask.rb +17 -3
- data/lib/cinch/message.rb +14 -7
- data/lib/cinch/message_queue.rb +8 -4
- data/lib/cinch/mode_parser.rb +56 -0
- data/lib/cinch/pattern.rb +45 -0
- data/lib/cinch/plugin.rb +129 -34
- data/lib/cinch/rubyext/string.rb +4 -4
- data/lib/cinch/syncable.rb +8 -0
- data/lib/cinch/user.rb +68 -13
- data/lib/cinch/user_manager.rb +60 -0
- metadata +17 -35
- data/Rakefile +0 -66
- data/lib/cinch/PLANNED +0 -4
- data/spec/bot_spec.rb +0 -5
- data/spec/channel_spec.rb +0 -5
- data/spec/cinch_spec.rb +0 -5
- data/spec/irc_spec.rb +0 -5
- data/spec/message_spec.rb +0 -5
- data/spec/plugin_spec.rb +0 -5
- data/spec/spec.opts +0 -2
- data/spec/spec_helper.rb +0 -8
- data/spec/user_spec.rb +0 -5
@@ -27,15 +27,14 @@ module Cinch
|
|
27
27
|
# (see Logger::Logger#log)
|
28
28
|
def log(messages, kind = :generic)
|
29
29
|
@mutex.synchronize do
|
30
|
-
messages = [messages].flatten.map {|s| s.chomp}
|
31
|
-
|
32
|
-
|
33
|
-
messages.each do |message|
|
30
|
+
messages = [messages].flatten.map {|s| s.to_s.chomp}
|
31
|
+
messages.each do |msg|
|
32
|
+
message = Time.now.strftime("[%Y/%m/%d %H:%M:%S.%L] ")
|
34
33
|
if kind == :debug
|
35
34
|
prefix = colorize("!! ", :yellow)
|
36
|
-
message
|
35
|
+
message << prefix + msg
|
37
36
|
else
|
38
|
-
pre, msg =
|
37
|
+
pre, msg = msg.split(" :", 2)
|
39
38
|
pre_parts = pre.split(" ")
|
40
39
|
|
41
40
|
if kind == :incoming
|
@@ -53,10 +52,10 @@ module Cinch
|
|
53
52
|
pre_parts[0] = colorize(pre_parts[0], :bold)
|
54
53
|
end
|
55
54
|
|
56
|
-
message
|
55
|
+
message << prefix + pre_parts.join(" ")
|
57
56
|
message << colorize(" :#{msg}", :yellow) if msg
|
58
57
|
end
|
59
|
-
@output.puts message.encode
|
58
|
+
@output.puts message.encode("locale", {:invalid => :replace, :undef => :replace})
|
60
59
|
end
|
61
60
|
end
|
62
61
|
end
|
@@ -66,6 +65,7 @@ module Cinch
|
|
66
65
|
# @param [Array<Symbol>] codes array of colors to apply
|
67
66
|
# @return [String] colorized string
|
68
67
|
def colorize(text, *codes)
|
68
|
+
return text unless @output.tty?
|
69
69
|
COLORS.values_at(*codes).join + text + COLORS[:reset]
|
70
70
|
end
|
71
71
|
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require "cinch/logger/logger"
|
2
|
+
module Cinch
|
3
|
+
module Logger
|
4
|
+
# This logger logs all incoming messages in the format of zcbot.
|
5
|
+
# All other debug output (outgoing messages, exceptions, ...) will
|
6
|
+
# silently be dropped. The sole purpose of this logger is to
|
7
|
+
# produce logs parseable by pisg (with the zcbot formatter) to
|
8
|
+
# create channel statistics..
|
9
|
+
class ZcbotLogger < Cinch::Logger::Logger
|
10
|
+
# @param [IO] output An IO to log to.
|
11
|
+
def initialize(output = STDERR)
|
12
|
+
@output = output
|
13
|
+
@mutex = Mutex.new
|
14
|
+
end
|
15
|
+
|
16
|
+
# (see Logger::Logger#debug)
|
17
|
+
def debug(messages)
|
18
|
+
end
|
19
|
+
|
20
|
+
# (see Logger::Logger#log)
|
21
|
+
def log(messages, kind = :generic)
|
22
|
+
return if kind != :incoming
|
23
|
+
|
24
|
+
@mutex.synchronize do
|
25
|
+
messages = [messages].flatten.map {|s| s.to_s.chomp}
|
26
|
+
messages.each do |msg|
|
27
|
+
@output.puts Time.now.strftime("%m/%d/%Y %H:%M:%S ") + msg.encode("locale", {:invalid => :replace, :undef => :replace})
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# (see Logger::Logger#log_exception)
|
33
|
+
def log_exception(e)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/lib/cinch/mask.rb
CHANGED
@@ -11,13 +11,27 @@ module Cinch
|
|
11
11
|
def initialize(mask)
|
12
12
|
@mask = mask
|
13
13
|
@nick, @user, @host = mask.match(/(.+)!(.+)@(.+)/)[1..-1]
|
14
|
-
@regexp = Regexp.new(Regexp.escape(mask).gsub("\\*", ".*"))
|
14
|
+
@regexp = Regexp.new("^" + Regexp.escape(mask).gsub("\\*", ".*") + "$")
|
15
15
|
end
|
16
16
|
|
17
|
+
# @return [Boolean]
|
18
|
+
def ==(other)
|
19
|
+
other.respond_to?(:mask) && other.mask == @mask
|
20
|
+
end
|
21
|
+
|
22
|
+
# @return [Boolean]
|
23
|
+
def eql?(other)
|
24
|
+
other.is_a?(self.class) && self == other
|
25
|
+
end
|
26
|
+
|
27
|
+
def hash
|
28
|
+
@mask.hash
|
29
|
+
end
|
30
|
+
|
31
|
+
# @param [User] user
|
17
32
|
# @return [Boolean]
|
18
33
|
def match(user)
|
19
|
-
mask
|
20
|
-
return mask =~ @regexp
|
34
|
+
return user.mask =~ @regexp
|
21
35
|
|
22
36
|
# TODO support CIDR (freenode)
|
23
37
|
end
|
data/lib/cinch/message.rb
CHANGED
@@ -10,7 +10,8 @@ module Cinch
|
|
10
10
|
# @return [Array<String>]
|
11
11
|
attr_accessor :params
|
12
12
|
attr_reader :events
|
13
|
-
|
13
|
+
# @return [Bot]
|
14
|
+
attr_reader :bot
|
14
15
|
def initialize(msg, bot)
|
15
16
|
@raw = msg
|
16
17
|
@bot = bot
|
@@ -50,7 +51,7 @@ module Cinch
|
|
50
51
|
host = @prefix[/@(\S+)$/, 1]
|
51
52
|
|
52
53
|
return nil if nick.nil?
|
53
|
-
@user ||=
|
54
|
+
@user ||= @bot.user_manager.find_ensured(user, nick, host)
|
54
55
|
end
|
55
56
|
|
56
57
|
# @return [String, nil]
|
@@ -91,14 +92,14 @@ module Cinch
|
|
91
92
|
@channel ||= begin
|
92
93
|
case command
|
93
94
|
when "INVITE", RPL_CHANNELMODEIS.to_s, RPL_BANLIST.to_s
|
94
|
-
|
95
|
+
@bot.channel_manager.find_ensured(params[1])
|
95
96
|
when RPL_NAMEREPLY.to_s
|
96
|
-
|
97
|
+
@bot.channel_manager.find_ensured(params[2])
|
97
98
|
else
|
98
99
|
if params.first.start_with?("#")
|
99
|
-
|
100
|
+
@bot.channel_manager.find_ensured(params.first)
|
100
101
|
elsif numeric_reply? and params[1].start_with?("#")
|
101
|
-
|
102
|
+
@bot.channel_manager.find_ensured(params[1])
|
102
103
|
end
|
103
104
|
end
|
104
105
|
end
|
@@ -121,6 +122,7 @@ module Cinch
|
|
121
122
|
$1
|
122
123
|
end
|
123
124
|
|
125
|
+
# @return [Array<String>, nil]
|
124
126
|
def ctcp_args
|
125
127
|
return unless ctcp?
|
126
128
|
ctcp_message.split(" ")[1..-1]
|
@@ -172,7 +174,12 @@ module Cinch
|
|
172
174
|
# @return [void]
|
173
175
|
def ctcp_reply(answer)
|
174
176
|
return unless ctcp?
|
175
|
-
|
177
|
+
user.notice "\001#{ctcp_command} #{answer}\001"
|
178
|
+
end
|
179
|
+
|
180
|
+
# @return [String]
|
181
|
+
def to_s
|
182
|
+
"#<Cinch::Message @raw=#{raw.chomp.inspect} @params=#{@params.inspect} channel=#{channel.inspect} user=#{user.inspect}>"
|
176
183
|
end
|
177
184
|
|
178
185
|
private
|
data/lib/cinch/message_queue.rb
CHANGED
@@ -51,11 +51,15 @@ module Cinch
|
|
51
51
|
|
52
52
|
message = @queue.pop.to_s.chomp
|
53
53
|
|
54
|
-
|
55
|
-
|
54
|
+
begin
|
55
|
+
@socket.writeline Cinch.encode_outgoing(message, @bot.config.encoding) + "\r\n"
|
56
|
+
@log << Time.now
|
57
|
+
@bot.logger.log(message, :outgoing) if @bot.config.verbose
|
56
58
|
|
57
|
-
|
58
|
-
|
59
|
+
@time_since_last_send = Time.now
|
60
|
+
rescue IOError
|
61
|
+
@bot.debug "Could not send message (connectivity problems): #{message}"
|
62
|
+
end
|
59
63
|
end
|
60
64
|
end
|
61
65
|
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module Cinch
|
2
|
+
# @api private
|
3
|
+
module ModeParser
|
4
|
+
def self.parse_modes(modes, params, param_modes = {})
|
5
|
+
if modes.size == 0
|
6
|
+
raise InvalidModeString, 'Empty mode string'
|
7
|
+
end
|
8
|
+
|
9
|
+
if modes[0] !~ /[+-]/
|
10
|
+
raise InvalidModeString, "Malformed modes string: %s" % modes
|
11
|
+
end
|
12
|
+
|
13
|
+
changes = []
|
14
|
+
|
15
|
+
direction = nil
|
16
|
+
count = -1
|
17
|
+
|
18
|
+
modes.each_char do |ch|
|
19
|
+
if ch =~ /[+-]/
|
20
|
+
if count == 0
|
21
|
+
raise InvalidModeString, 'Empty mode sequence: %s' % modes
|
22
|
+
end
|
23
|
+
|
24
|
+
direction = case ch
|
25
|
+
when "+"
|
26
|
+
:add
|
27
|
+
when "-"
|
28
|
+
:remove
|
29
|
+
end
|
30
|
+
count = 0
|
31
|
+
else
|
32
|
+
param = nil
|
33
|
+
if param_modes[direction].include?(ch)
|
34
|
+
if params.size > 0
|
35
|
+
param = params.shift
|
36
|
+
else
|
37
|
+
raise InvalidModeString, 'Not enough parameters: %s' % ch.inspect
|
38
|
+
end
|
39
|
+
end
|
40
|
+
changes << [direction, ch, param]
|
41
|
+
count += 1
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
if params.size > 0
|
46
|
+
raise InvalidModeString, 'Too many parameters: %s %s' % [modes, params].inspect
|
47
|
+
end
|
48
|
+
|
49
|
+
if count == 0
|
50
|
+
raise InvalidModeString, 'Empty mode sequence: %r' % modes
|
51
|
+
end
|
52
|
+
|
53
|
+
return changes
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
module Cinch
|
3
|
+
# @api private
|
4
|
+
class Pattern
|
5
|
+
# @param [String, Regexp, NilClass, Proc, #to_s] obj The object to
|
6
|
+
# convert to a regexp
|
7
|
+
# @return [Regexp, nil]
|
8
|
+
def self.obj_to_r(obj)
|
9
|
+
case obj
|
10
|
+
when Regexp, NilClass
|
11
|
+
return obj
|
12
|
+
else
|
13
|
+
return Regexp.new(Regexp.escape(obj.to_s))
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.resolve_proc(obj, msg = nil)
|
18
|
+
if obj.is_a?(Proc)
|
19
|
+
return resolve_proc(obj.call(msg), msg)
|
20
|
+
else
|
21
|
+
return obj
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
attr_reader :prefix
|
26
|
+
attr_reader :suffix
|
27
|
+
attr_reader :pattern
|
28
|
+
def initialize(prefix, pattern, suffix)
|
29
|
+
@prefix, @pattern, @suffix = prefix, pattern, suffix
|
30
|
+
end
|
31
|
+
|
32
|
+
def to_r(msg = nil)
|
33
|
+
prefix = Pattern.obj_to_r(Pattern.resolve_proc(@prefix, msg))
|
34
|
+
suffix = Pattern.obj_to_r(Pattern.resolve_proc(@suffix, msg))
|
35
|
+
pattern = Pattern.resolve_proc(@pattern, msg)
|
36
|
+
|
37
|
+
case pattern
|
38
|
+
when Regexp, NilClass
|
39
|
+
/#{prefix}#{pattern}#{suffix}/
|
40
|
+
else
|
41
|
+
/^#{prefix}#{Pattern.obj_to_r(pattern)}#{suffix}$/
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/lib/cinch/plugin.rb
CHANGED
@@ -3,8 +3,14 @@ module Cinch
|
|
3
3
|
include Helpers
|
4
4
|
|
5
5
|
module ClassMethods
|
6
|
-
|
6
|
+
# @api private
|
7
|
+
Match = Struct.new(:pattern, :use_prefix, :use_suffix, :method)
|
8
|
+
# @api private
|
7
9
|
Listener = Struct.new(:event, :method)
|
10
|
+
# @api private
|
11
|
+
Timer = Struct.new(:interval, :method, :threaded, :registered)
|
12
|
+
# @api private
|
13
|
+
Hook = Struct.new(:type, :for, :method)
|
8
14
|
|
9
15
|
# Set a match pattern.
|
10
16
|
#
|
@@ -15,9 +21,9 @@ module Cinch
|
|
15
21
|
# pattern.
|
16
22
|
# @return [void]
|
17
23
|
def match(pattern, options = {})
|
18
|
-
options = {:use_prefix => true, :method => :execute}.merge(options)
|
19
|
-
@
|
20
|
-
@
|
24
|
+
options = {:use_prefix => true, :use_suffix => true, :method => :execute}.merge(options)
|
25
|
+
@__cinch_matches ||= []
|
26
|
+
@__cinch_matches << Match.new(pattern, options[:use_prefix], options[:use_suffix], options[:method])
|
21
27
|
end
|
22
28
|
|
23
29
|
# Events to listen to.
|
@@ -53,8 +59,8 @@ module Cinch
|
|
53
59
|
(@__cinch_ctcps ||= []) << command.to_s.upcase
|
54
60
|
end
|
55
61
|
|
56
|
-
# Define a help message which will be returned on "
|
57
|
-
#
|
62
|
+
# Define a help message which will be returned on "<prefix>help
|
63
|
+
# <pluginname>".
|
58
64
|
#
|
59
65
|
# @param [String] message
|
60
66
|
# @return [void]
|
@@ -66,10 +72,22 @@ module Cinch
|
|
66
72
|
#
|
67
73
|
# @param [String] prefix
|
68
74
|
# @return [void]
|
69
|
-
def prefix(prefix)
|
70
|
-
|
75
|
+
def prefix(prefix = nil, &block)
|
76
|
+
raise ArgumentError if prefix.nil? && block.nil?
|
77
|
+
@__cinch_prefix = prefix || block
|
71
78
|
end
|
72
79
|
|
80
|
+
# Set the plugin suffix.
|
81
|
+
#
|
82
|
+
# @param [String] suffix
|
83
|
+
# @return [void]
|
84
|
+
def suffix(suffix = nil, &block)
|
85
|
+
raise ArgumentError if suffix.nil? && block.nil?
|
86
|
+
@__cinch_suffix = suffix || block
|
87
|
+
end
|
88
|
+
|
89
|
+
|
90
|
+
|
73
91
|
# Set which kind of messages to react on (i.e. call {#execute})
|
74
92
|
#
|
75
93
|
# @param [Symbol<:message, :channel, :private>] target React to all,
|
@@ -87,12 +105,63 @@ module Cinch
|
|
87
105
|
@__cinch_name = name
|
88
106
|
end
|
89
107
|
|
108
|
+
# @example
|
109
|
+
# timer 5, method: :some_method
|
110
|
+
# def some_method
|
111
|
+
# Channel("#cinch-bots").send(Time.now.to_s)
|
112
|
+
# end
|
113
|
+
# @param [Number] interval Interval in seconds
|
114
|
+
# @option options [Symbol] :method (:timer) Method to call
|
115
|
+
# @option options [Boolean] :threaded (true) Call method in a thread?
|
116
|
+
# @return [void]
|
117
|
+
def timer(interval, options = {})
|
118
|
+
options = {:method => :timer, :threaded => true}.merge(options)
|
119
|
+
@__cinch_timers ||= []
|
120
|
+
@__cinch_timers << Timer.new(interval, options[:method], options[:threaded], false)
|
121
|
+
end
|
122
|
+
|
123
|
+
# Defines a hook which will be run before or after a handler is
|
124
|
+
# executed, depending on the value of `type`.
|
125
|
+
#
|
126
|
+
# @param [Symbol<:pre, :post>] type Run the hook before or after
|
127
|
+
# a handler?
|
128
|
+
# @option options [Array<:match, :listen_to, :ctcp>] :for ([:match, :listen_to, :ctcp])
|
129
|
+
# Which kinds of events to run the hook for.
|
130
|
+
# @option options [Symbol] :method (true) The method to execute.
|
131
|
+
# @return [void]
|
132
|
+
def hook(type, options = {})
|
133
|
+
options = {:for => [:match, :listen_to, :ctcp], :method => :hook}.merge(options)
|
134
|
+
__hooks(type) << Hook.new(type, options[:for], options[:method])
|
135
|
+
end
|
136
|
+
|
90
137
|
# @return [String]
|
91
138
|
# @api private
|
92
139
|
def __plugin_name
|
93
140
|
@__cinch_name || self.name.split("::").last.downcase
|
94
141
|
end
|
95
142
|
|
143
|
+
# @return [Hash]
|
144
|
+
# @api private
|
145
|
+
def __hooks(type = nil, events = nil)
|
146
|
+
@__cinch_hooks ||= Hash.new{|h,k| h[k] = []}
|
147
|
+
|
148
|
+
if type.nil?
|
149
|
+
hooks = @__cinch_hooks
|
150
|
+
else
|
151
|
+
hooks = @__cinch_hooks[type]
|
152
|
+
end
|
153
|
+
|
154
|
+
if events.nil?
|
155
|
+
return hooks
|
156
|
+
else
|
157
|
+
events = [*events]
|
158
|
+
if hooks.is_a?(Hash)
|
159
|
+
hooks = hooks.map { |k, v| v }
|
160
|
+
end
|
161
|
+
return hooks.select { |hook| (events & hook.for).size > 0 }
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
96
165
|
# @return [void]
|
97
166
|
# @api private
|
98
167
|
def __register_with_bot(bot, instance)
|
@@ -100,36 +169,30 @@ module Cinch
|
|
100
169
|
|
101
170
|
(@__cinch_listeners || []).each do |listener|
|
102
171
|
bot.debug "[plugin] #{plugin_name}: Registering listener for type `#{listener.event}`"
|
103
|
-
bot.on(listener.event, [], instance) do |message, plugin|
|
104
|
-
|
172
|
+
bot.on(listener.event, [], instance) do |message, plugin, *args|
|
173
|
+
if plugin.respond_to?(listener.method)
|
174
|
+
plugin.class.__hooks(:pre, :listen_to).each {|hook| plugin.__send__(hook.method, message)}
|
175
|
+
plugin.__send__(listener.method, message, *args)
|
176
|
+
plugin.class.__hooks(:post, :listen_to).each {|hook| plugin.__send__(hook.method, message)}
|
177
|
+
end
|
105
178
|
end
|
106
179
|
end
|
107
180
|
|
108
|
-
if (@
|
109
|
-
@
|
181
|
+
if (@__cinch_matches ||= []).empty?
|
182
|
+
@__cinch_matches << Match.new(plugin_name, true, true, :execute)
|
110
183
|
end
|
111
184
|
|
112
185
|
prefix = @__cinch_prefix || bot.config.plugins.prefix
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
if pattern.use_prefix && prefix
|
120
|
-
case pattern.pattern
|
121
|
-
when Regexp
|
122
|
-
pattern_to_register = /^#{prefix}#{pattern.pattern}/
|
123
|
-
when String
|
124
|
-
pattern_to_register = prefix + pattern.pattern
|
125
|
-
end
|
126
|
-
else
|
127
|
-
pattern_to_register = pattern.pattern
|
128
|
-
end
|
186
|
+
suffix = @__cinch_suffix || bot.config.plugins.suffix
|
187
|
+
|
188
|
+
@__cinch_matches.each do |pattern|
|
189
|
+
_prefix = pattern.use_prefix ? prefix : nil
|
190
|
+
_suffix = pattern.use_suffix ? suffix : nil
|
129
191
|
|
192
|
+
pattern_to_register = Pattern.new(_prefix, pattern.pattern, _suffix)
|
130
193
|
react_on = @__cinch_react_on || :message
|
131
194
|
|
132
|
-
bot.debug "[plugin] #{plugin_name}: Registering executor with pattern `#{pattern_to_register}`, reacting on `#{react_on}`"
|
195
|
+
bot.debug "[plugin] #{plugin_name}: Registering executor with pattern `#{pattern_to_register.inspect}`, reacting on `#{react_on}`"
|
133
196
|
|
134
197
|
bot.on(react_on, pattern_to_register, instance, pattern) do |message, plugin, pattern, *args|
|
135
198
|
if plugin.respond_to?(pattern.method)
|
@@ -140,7 +203,9 @@ module Cinch
|
|
140
203
|
elsif arity == 0
|
141
204
|
args = []
|
142
205
|
end
|
206
|
+
plugin.class.__hooks(:pre, :match).each {|hook| plugin.__send__(hook.method, message)}
|
143
207
|
method.call(message, *args)
|
208
|
+
plugin.class.__hooks(:post, :match).each {|hook| plugin.__send__(hook.method, message)}
|
144
209
|
end
|
145
210
|
end
|
146
211
|
end
|
@@ -148,13 +213,46 @@ module Cinch
|
|
148
213
|
(@__cinch_ctcps || []).each do |ctcp|
|
149
214
|
bot.debug "[plugin] #{plugin_name}: Registering CTCP `#{ctcp}`"
|
150
215
|
bot.on(:ctcp, ctcp, instance, ctcp) do |message, plugin, ctcp, *args|
|
216
|
+
plugin.class.__hooks(:pre, :ctcp).each {|hook| plugin.__send__(hook.method, message)}
|
151
217
|
plugin.__send__("ctcp_#{ctcp.downcase}", message, *args)
|
218
|
+
plugin.class.__hooks(:post, :ctcp).each {|hook| plugin.__send__(hook.method, message)}
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
(@__cinch_timers || []).each do |timer|
|
223
|
+
bot.debug "[plugin] #{__plugin_name}: Registering timer with interval `#{timer.interval}` for method `#{timer.method}`"
|
224
|
+
bot.on :connect do
|
225
|
+
next if timer.registered
|
226
|
+
timer.registered = true
|
227
|
+
Thread.new do
|
228
|
+
bot.debug "registering timer..."
|
229
|
+
loop do
|
230
|
+
sleep timer.interval
|
231
|
+
if instance.respond_to?(timer.method)
|
232
|
+
l = lambda {
|
233
|
+
begin
|
234
|
+
instance.__send__(timer.method)
|
235
|
+
rescue => e
|
236
|
+
bot.logger.log_exception(e)
|
237
|
+
end
|
238
|
+
}
|
239
|
+
|
240
|
+
if timer.threaded
|
241
|
+
Thread.new do
|
242
|
+
l.call
|
243
|
+
end
|
244
|
+
else
|
245
|
+
l.call
|
246
|
+
end
|
247
|
+
end
|
248
|
+
end
|
249
|
+
end
|
152
250
|
end
|
153
251
|
end
|
154
252
|
|
155
253
|
if @__cinch_help_message
|
156
254
|
bot.debug "[plugin] #{plugin_name}: Registering help message"
|
157
|
-
bot.on(:message,
|
255
|
+
bot.on(:message, "#{prefix}help #{plugin_name}", @__cinch_help_message) do |message, help_message|
|
158
256
|
message.reply(help_message)
|
159
257
|
end
|
160
258
|
end
|
@@ -169,10 +267,7 @@ module Cinch
|
|
169
267
|
self.class.__register_with_bot(bot, self)
|
170
268
|
end
|
171
269
|
|
172
|
-
#
|
173
|
-
# @yield
|
174
|
-
# @return (see Bot#synchronize)
|
175
|
-
# @see Bot#synchronize
|
270
|
+
# (see Bot#synchronize)
|
176
271
|
def synchronize(*args, &block)
|
177
272
|
@bot.synchronize(*args, &block)
|
178
273
|
end
|