cinch 1.0.2 → 1.1.0
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/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
|