isaac 0.2.2 → 0.2.5
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.rdoc +7 -14
- data/isaac.gemspec +3 -2
- data/lib/isaac.rb +116 -75
- metadata +6 -4
data/README.rdoc
CHANGED
@@ -45,6 +45,13 @@ If you want to match private messages use the +on :private+ event:
|
|
45
45
|
msg nick, "Login successful!"
|
46
46
|
end
|
47
47
|
|
48
|
+
You can also pass the RegExp captures as block arguments:
|
49
|
+
|
50
|
+
on :channel, /catch this: (.*) and this: (.*)/ do |first, last|
|
51
|
+
# `first` will contain the first regexp capture,
|
52
|
+
# `last` the second.
|
53
|
+
end
|
54
|
+
|
48
55
|
=== Defining helpers
|
49
56
|
Helpers should not be defined in the top level, but instead using the +helpers+-constructor:
|
50
57
|
|
@@ -67,20 +74,6 @@ Errors, as specified by RFC 1459, can be reacted upon as well. If you e.g. try t
|
|
67
74
|
|
68
75
|
Available variables: +nick+ and +channel+.
|
69
76
|
|
70
|
-
=== Send commands from outside an event (not implemented in Shaft atm)
|
71
|
-
You might want to send messages, join channels etc. without it strictly being the result of an on()-event, e.g. send a message every time a RSS feed is updated or whatever. You can use +Isaac.execute+ for that, and all your normal commands, +msg+, +join+, +topic+ etc. will be available:
|
72
|
-
|
73
|
-
class K
|
74
|
-
def smoke(brand)
|
75
|
-
Isaac.execute { msg "harryjr", "you should smoke #{brand} cigarettes" }
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
on :connect do
|
80
|
-
k = K.new
|
81
|
-
k.smoke("Lucky Strike")
|
82
|
-
end
|
83
|
-
|
84
77
|
== Contribute
|
85
78
|
The source is hosted at GitHub: http://github.com/ichverstehe/isaac
|
86
79
|
|
data/isaac.gemspec
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = "isaac"
|
3
|
-
s.version = "0.2.
|
4
|
-
s.date = "2009-
|
3
|
+
s.version = "0.2.5"
|
4
|
+
s.date = "2009-04-25"
|
5
5
|
s.summary = "The smallish DSL for writing IRC bots"
|
6
6
|
s.email = "harry@vangberg.name"
|
7
7
|
s.homepage = "http://github.com/ichverstehe/isaac"
|
@@ -16,3 +16,4 @@ Gem::Specification.new do |s|
|
|
16
16
|
s.rdoc_options = ["--main", "README.rdoc"]
|
17
17
|
s.extra_rdoc_files = ["LICENSE", "README.rdoc"]
|
18
18
|
end
|
19
|
+
|
data/lib/isaac.rb
CHANGED
@@ -20,53 +20,29 @@ module Isaac
|
|
20
20
|
instance_eval(&b) if block_given?
|
21
21
|
end
|
22
22
|
|
23
|
-
def
|
24
|
-
|
25
|
-
puts "Connecting to #{@config.server}:#{@config.port}"
|
26
|
-
@irc = IRC.new(self, @config)
|
27
|
-
@irc.connect
|
28
|
-
puts "========================================="
|
23
|
+
def configure(&b)
|
24
|
+
b.call(@config)
|
29
25
|
end
|
30
26
|
|
31
|
-
def on(event, match=//, &
|
27
|
+
def on(event, match=//, &block)
|
32
28
|
match = match.to_s if match.is_a? Integer
|
33
|
-
(@events[event] ||= []) << [Regexp.new(match),
|
29
|
+
(@events[event] ||= []) << [Regexp.new(match), block]
|
34
30
|
end
|
35
31
|
|
36
32
|
def helpers(&b)
|
37
|
-
instance_eval
|
38
|
-
end
|
39
|
-
|
40
|
-
def configure(&b)
|
41
|
-
b.call(@config)
|
42
|
-
end
|
43
|
-
|
44
|
-
def dispatch(event, env={})
|
45
|
-
self.nick, self.userhost, self.channel, self.error =
|
46
|
-
env[:nick], env[:userhost], env[:channel], env[:error]
|
47
|
-
self.message = env[:message] || ""
|
48
|
-
|
49
|
-
event = @events[event] && @events[event].detect do |regexp,_|
|
50
|
-
message.match(regexp)
|
51
|
-
end
|
52
|
-
|
53
|
-
if event
|
54
|
-
regexp, block = *event
|
55
|
-
self.match = message.match(regexp).captures
|
56
|
-
catch(:halt) { instance_eval(&block) }
|
57
|
-
end
|
33
|
+
instance_eval(&b)
|
58
34
|
end
|
59
35
|
|
60
36
|
def halt
|
61
37
|
throw :halt
|
62
38
|
end
|
63
39
|
|
64
|
-
def raw(
|
65
|
-
@irc.message(
|
40
|
+
def raw(command)
|
41
|
+
@irc.message(command)
|
66
42
|
end
|
67
43
|
|
68
|
-
def msg(recipient,
|
69
|
-
raw("PRIVMSG #{recipient} :#{
|
44
|
+
def msg(recipient, text)
|
45
|
+
raw("PRIVMSG #{recipient} :#{text}")
|
70
46
|
end
|
71
47
|
|
72
48
|
def join(*channels)
|
@@ -80,6 +56,44 @@ module Isaac
|
|
80
56
|
def topic(channel, text)
|
81
57
|
raw("TOPIC #{channel} :#{text}")
|
82
58
|
end
|
59
|
+
|
60
|
+
def start
|
61
|
+
puts "Connecting to #{@config.server}:#{@config.port}" unless @config.environment == :test
|
62
|
+
@irc = IRC.new(self, @config)
|
63
|
+
@irc.connect
|
64
|
+
end
|
65
|
+
|
66
|
+
def dispatch(event, env={})
|
67
|
+
self.nick, self.userhost, self.channel, self.error =
|
68
|
+
env[:nick], env[:userhost], env[:channel], env[:error]
|
69
|
+
self.message = env[:message] || ""
|
70
|
+
|
71
|
+
if handler = find(event, message)
|
72
|
+
regexp, block = *handler
|
73
|
+
self.match = message.match(regexp).captures
|
74
|
+
invoke block
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
private
|
79
|
+
def find(type, message)
|
80
|
+
if events = @events[type]
|
81
|
+
events.detect {|regexp,_| message.match(regexp)}
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def invoke(block)
|
86
|
+
mc = class << self; self; end
|
87
|
+
mc.send :define_method, :__isaac_event_handler, &block
|
88
|
+
|
89
|
+
bargs = case block.arity <=> 0
|
90
|
+
when -1; match
|
91
|
+
when 0; []
|
92
|
+
when 1; match[0..block.arity-1]
|
93
|
+
end
|
94
|
+
|
95
|
+
catch(:halt) { __isaac_event_handler(*bargs) }
|
96
|
+
end
|
83
97
|
end
|
84
98
|
|
85
99
|
class IRC
|
@@ -87,56 +101,44 @@ module Isaac
|
|
87
101
|
@bot, @config = bot, config
|
88
102
|
@transfered = 0
|
89
103
|
@registration = []
|
90
|
-
@lock = false
|
91
|
-
@queue = []
|
92
104
|
end
|
93
105
|
|
94
106
|
def connect
|
95
107
|
@socket = TCPSocket.open(@config.server, @config.port)
|
96
|
-
|
108
|
+
@queue = Queue.new(@socket, @bot.config.server)
|
109
|
+
message "PASS #{@config.password}" if @config.password
|
97
110
|
message "NICK #{@config.nick}"
|
98
111
|
message "USER #{@config.nick} 0 * :#{@config.realname}"
|
99
|
-
@lock
|
112
|
+
@queue.lock
|
100
113
|
|
101
|
-
|
102
|
-
|
103
|
-
Thread.start {
|
104
|
-
while line = @socket.gets
|
105
|
-
parse line
|
106
|
-
end
|
107
|
-
}
|
108
|
-
else
|
109
|
-
while line = @socket.gets
|
110
|
-
parse line
|
111
|
-
end
|
114
|
+
while line = @socket.gets
|
115
|
+
parse line
|
112
116
|
end
|
113
117
|
end
|
114
118
|
|
115
119
|
def parse(input)
|
116
120
|
puts "<< #{input}" if @bot.config.verbose
|
117
|
-
case input
|
118
|
-
when
|
119
|
-
@registration << $
|
121
|
+
case input.chomp
|
122
|
+
when /(^:\S+ )?00([1-4])/
|
123
|
+
@registration << $2.to_i
|
120
124
|
if registered?
|
121
|
-
@
|
125
|
+
@queue.unlock
|
122
126
|
@bot.dispatch(:connect)
|
123
|
-
continue_queue
|
124
127
|
end
|
125
|
-
when
|
126
|
-
message "NOTICE #{$
|
128
|
+
when /(^:(\S+)!\S+ )?PRIVMSG \S+ :?\001VERSION\001/
|
129
|
+
message "NOTICE #{$2} :\001VERSION #{@bot.config.version}\001"
|
127
130
|
when /^PING (\S+)/
|
128
|
-
@
|
131
|
+
@queue.unlock
|
129
132
|
message "PONG #{$1}"
|
130
|
-
when
|
131
|
-
env = { :nick => $
|
133
|
+
when /(^:(\S+)!(\S+) )?PRIVMSG (\S+) :?(.*)/
|
134
|
+
env = { :nick => $2, :userhost => $3, :channel => $4, :message => $5 }
|
132
135
|
type = env[:channel].match(/^#/) ? :channel : :private
|
133
136
|
@bot.dispatch(type, env)
|
134
|
-
when
|
135
|
-
env = {:error => $
|
137
|
+
when /(^:\S+ )?([4-5]\d\d) \S+ (\S+)/
|
138
|
+
env = {:error => $2.to_i, :message => $2, :nick => $3, :channel => $3}
|
136
139
|
@bot.dispatch(:error, env)
|
137
|
-
when
|
138
|
-
@
|
139
|
-
continue_queue
|
140
|
+
when /(^:\S+ )?PONG/
|
141
|
+
@queue.unlock
|
140
142
|
end
|
141
143
|
end
|
142
144
|
|
@@ -146,21 +148,60 @@ module Isaac
|
|
146
148
|
|
147
149
|
def message(msg)
|
148
150
|
@queue << msg
|
149
|
-
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
class Queue
|
155
|
+
def initialize(socket, server)
|
156
|
+
# We need server for pinging us out of an excess flood
|
157
|
+
@socket, @server = socket, server
|
158
|
+
@queue, @lock, @transfered = [], false, 0
|
159
|
+
end
|
160
|
+
|
161
|
+
def lock
|
162
|
+
@lock = true
|
163
|
+
end
|
164
|
+
|
165
|
+
def unlock
|
166
|
+
@lock, @transfered = false, 0
|
167
|
+
invoke
|
168
|
+
end
|
169
|
+
|
170
|
+
def <<(message)
|
171
|
+
@queue << message
|
172
|
+
invoke
|
173
|
+
end
|
174
|
+
|
175
|
+
private
|
176
|
+
def message_to_send?
|
177
|
+
!@lock && !@queue.empty?
|
178
|
+
end
|
179
|
+
|
180
|
+
def transfered_after_next_send
|
181
|
+
@transfered + @queue.first.size + 2 # the 2 is for \r\n
|
182
|
+
end
|
183
|
+
|
184
|
+
def exceed_limit?
|
185
|
+
transfered_after_next_send > 1472
|
186
|
+
end
|
187
|
+
|
188
|
+
def lock_and_ping
|
189
|
+
lock
|
190
|
+
@socket.print "PING :#{@server}\r\n"
|
191
|
+
end
|
192
|
+
|
193
|
+
def next_message
|
194
|
+
@queue.shift.to_s.chomp + "\r\n"
|
150
195
|
end
|
151
196
|
|
152
|
-
def
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
@socket.puts msg
|
157
|
-
puts ">> #{msg}" if @bot.config.verbose
|
158
|
-
@transfered += msg.size + 1
|
197
|
+
def invoke
|
198
|
+
while message_to_send?
|
199
|
+
if exceed_limit?
|
200
|
+
lock_and_ping; break
|
159
201
|
else
|
160
|
-
@
|
161
|
-
@
|
162
|
-
|
163
|
-
break
|
202
|
+
@transfered = transfered_after_next_send
|
203
|
+
@socket.print next_message
|
204
|
+
# puts ">> #{msg}" if @bot.config.verbose
|
164
205
|
end
|
165
206
|
end
|
166
207
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: isaac
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Harry Vangberg
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-04-25 00:00:00 +02:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -29,6 +29,8 @@ files:
|
|
29
29
|
- lib/isaac.rb
|
30
30
|
has_rdoc: true
|
31
31
|
homepage: http://github.com/ichverstehe/isaac
|
32
|
+
licenses: []
|
33
|
+
|
32
34
|
post_install_message:
|
33
35
|
rdoc_options:
|
34
36
|
- --main
|
@@ -50,9 +52,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
50
52
|
requirements: []
|
51
53
|
|
52
54
|
rubyforge_project: isaac
|
53
|
-
rubygems_version: 1.3.
|
55
|
+
rubygems_version: 1.3.3
|
54
56
|
signing_key:
|
55
|
-
specification_version:
|
57
|
+
specification_version: 3
|
56
58
|
summary: The smallish DSL for writing IRC bots
|
57
59
|
test_files: []
|
58
60
|
|