cinch 0.2.6 → 0.2.9
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +32 -2
- data/Rakefile +0 -14
- data/examples/custom_prefix.rb +25 -0
- data/examples/google.rb +31 -0
- data/examples/urban_dict.rb +31 -0
- data/lib/cinch.rb +1 -1
- data/lib/cinch/base.rb +42 -20
- data/spec/base_spec.rb +4 -0
- data/spec/options_spec.rb +5 -0
- data/spec/spec.opts +2 -0
- metadata +7 -3
data/README.rdoc
CHANGED
@@ -10,6 +10,9 @@ plugin, defining a rule, and watching your profits flourish.
|
|
10
10
|
Cinch will do all of the hard work for you, so you can spend time creating cool plugins
|
11
11
|
and extensions to wow your internet peers.
|
12
12
|
|
13
|
+
If you'd like to test your own Cinch experiments you can do so in the cinch IRC channel
|
14
|
+
on {irc.freenode.org}[irc://irc.freenode.org/cinch]. Support is also welcome here.
|
15
|
+
|
13
16
|
== Installation
|
14
17
|
The latest version of Cinch is 0.2
|
15
18
|
|
@@ -105,6 +108,27 @@ This method also works for arrays, to only reply to a message sent in the foo an
|
|
105
108
|
m.reply "Hello"
|
106
109
|
end
|
107
110
|
|
111
|
+
You can also set a custom prefix for each individual plugin, this is a great method if you have
|
112
|
+
two commands which do slightly different things. You can seperate the commands depending on which
|
113
|
+
prefix the rule contains.
|
114
|
+
|
115
|
+
bot.plugin "foo", :prefix => '@' do |m|
|
116
|
+
m.reply "Doing foo.."
|
117
|
+
end
|
118
|
+
|
119
|
+
You can also prefix the rule with the bots nickname. Either pass the <b>:bot</b>, <b>:botnick</b> or
|
120
|
+
<b>bot.nick</b> values to the prefix option.
|
121
|
+
|
122
|
+
bot.plugin "foo", :prefix => :bot do |m|
|
123
|
+
m.reply "Doing foo.."
|
124
|
+
end
|
125
|
+
|
126
|
+
Assuming the username is cinch, this will respond to the following:
|
127
|
+
* cinch: foo
|
128
|
+
* cinch, foo
|
129
|
+
|
130
|
+
More examples of this can be found in the /examples directory
|
131
|
+
|
108
132
|
== Named Parameter Patterns
|
109
133
|
Since version 0.2, Cinch supports named parameter patterns. It means stuff like the this works:
|
110
134
|
|
@@ -141,20 +165,26 @@ Which would provide the following output on IRC:
|
|
141
165
|
|
142
166
|
Note though that although Cinch adds the capturing parenthesis for you, you must escape it yourself
|
143
167
|
|
168
|
+
== Examples
|
169
|
+
Check out the /examples directory for basic, yet fully functional out-of-the-box bots.
|
170
|
+
If you have any examples you'd like to add, please either fork the repo and push your example
|
171
|
+
before sending me a pull request. Alternatively paste the example and inform me in the IRC
|
172
|
+
channel or by email
|
173
|
+
|
144
174
|
== Authors
|
145
175
|
Just me at the moment, sad poor lonely me...
|
146
176
|
* {Lee Jarvis}[http://blog.injekt.net]
|
147
177
|
|
148
178
|
== Notes
|
149
|
-
|
150
179
|
* RDoc API documentation is available {here}[http://rdoc.injekt.net/cinch]
|
151
180
|
* Wiki is available {here}[https://github.com/injekt/cinch/wikis]
|
152
181
|
* Issue and feature tracking is available {here}[https://github.com/injekt/cinch/issues]
|
153
182
|
* Contribution in the form of bugfixes or feature requests is welcome and encouraged
|
154
183
|
|
184
|
+
== Contribute
|
155
185
|
If you'd like to contribute, fork the GitHub repository, make any changes, and send
|
156
186
|
{injekt}[http://github.com/injekt] a pull request. Collaborator access is available on
|
157
|
-
request once one patch has been submitted.
|
187
|
+
request once one patch has been submitted. Any contribution is welcome and appreciated
|
158
188
|
|
159
189
|
== TODO
|
160
190
|
* More specs
|
data/Rakefile
CHANGED
@@ -42,24 +42,10 @@ task :release => [:package] do
|
|
42
42
|
sh "gem push ./#{NAME}-#{VERSION}.gem"
|
43
43
|
end
|
44
44
|
|
45
|
-
desc "Upload rdoc to injekt.net"
|
46
|
-
task :upload => [:clean, :rdoc] do
|
47
|
-
sh("scp -r rdoc/* injekt@injekt.net:/var/www/injekt.net/rdoc/cinch")
|
48
|
-
end
|
49
|
-
|
50
45
|
desc "Run all specs"
|
51
46
|
Spec::Rake::SpecTask.new(:spec) do |t|
|
52
47
|
t.spec_files = Dir['spec/**/*_spec.rb']
|
53
48
|
end
|
54
49
|
|
55
|
-
namespace :spec do
|
56
|
-
desc "Print with specdoc formatting"
|
57
|
-
Spec::Rake::SpecTask.new(:doc) do |t|
|
58
|
-
t.spec_opts = ["--format", "specdoc"]
|
59
|
-
t.spec_files = Dir['spec/**/*_spec.rb']
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
|
64
50
|
task :default => [:clean, :spec]
|
65
51
|
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'cinch'
|
2
|
+
|
3
|
+
bot = Cinch.setup do
|
4
|
+
server "irc.freenode.org"
|
5
|
+
channels %w( #cinch )
|
6
|
+
end
|
7
|
+
|
8
|
+
bot.plugin "default" do |m|
|
9
|
+
m.reply "default prefix"
|
10
|
+
end
|
11
|
+
|
12
|
+
bot.plugin "custom", :prefix => '@' do |m|
|
13
|
+
m.reply "custom prefix"
|
14
|
+
end
|
15
|
+
|
16
|
+
bot.plugin "botnick", :prefix => :botnick do |m|
|
17
|
+
m.reply "botnick prefix"
|
18
|
+
end
|
19
|
+
|
20
|
+
bot.plugin "botnick2", :prefix => bot.nick do |m|
|
21
|
+
m.reply "another botnick prefix"
|
22
|
+
end
|
23
|
+
|
24
|
+
bot.run
|
25
|
+
|
data/examples/google.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'cinch'
|
2
|
+
require 'open-uri'
|
3
|
+
require 'nokogiri'
|
4
|
+
require 'cgi'
|
5
|
+
|
6
|
+
bot = Cinch.setup do
|
7
|
+
server "irc.freenode.net"
|
8
|
+
nick "MrCinch"
|
9
|
+
channels %w/ #cinch /
|
10
|
+
end
|
11
|
+
|
12
|
+
# Extremely basic method, grabs the first result returned by Google
|
13
|
+
# or "No results found" otherwise
|
14
|
+
def google(query)
|
15
|
+
url = "http://www.google.com/search?q=#{CGI.escape(query)}"
|
16
|
+
res = Nokogiri::HTML(open(url)).at("h3.r")
|
17
|
+
|
18
|
+
title = res.text
|
19
|
+
link = res.at('a')[:href]
|
20
|
+
desc = res.at("./following::div").children.first.text
|
21
|
+
rescue
|
22
|
+
"No results found"
|
23
|
+
else
|
24
|
+
CGI.unescape_html "#{title} - #{desc} (#{link})"
|
25
|
+
end
|
26
|
+
|
27
|
+
bot.plugin("google :query") do |m|
|
28
|
+
m.reply google(m.args[:query])
|
29
|
+
end
|
30
|
+
|
31
|
+
bot.run
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'cinch'
|
2
|
+
require 'open-uri'
|
3
|
+
require 'nokogiri'
|
4
|
+
require 'cgi'
|
5
|
+
|
6
|
+
# This bot connects to urban dictionary and returns the first result
|
7
|
+
# for a given query, replying with the result directly to the sender
|
8
|
+
|
9
|
+
bot = Cinch.setup do
|
10
|
+
server "irc.freenode.net"
|
11
|
+
nick "MrCinch"
|
12
|
+
channels %w/ #cinch /
|
13
|
+
end
|
14
|
+
|
15
|
+
# This method assumes everything will go ok, it's not the best method
|
16
|
+
# of doing this *by far* and is simply a helper method to show how it
|
17
|
+
# can be done.. it works!
|
18
|
+
def urban_dict(query)
|
19
|
+
url = "http://www.urbandictionary.com/define.php?term=#{CGI.escape(query)}"
|
20
|
+
CGI.unescape_html Nokogiri::HTML(open(url)).at("div.definition").text.gsub(/\s+/, ' ') rescue nil
|
21
|
+
end
|
22
|
+
|
23
|
+
bot.plugin("urban :query") do |m|
|
24
|
+
m.answer urban_dict(m.args[:query]) || "No results found"
|
25
|
+
end
|
26
|
+
|
27
|
+
bot.run
|
28
|
+
|
29
|
+
# injekt> !urban cinch
|
30
|
+
# MrCinch> injekt: describing an action that's extremely easy.
|
31
|
+
|
data/lib/cinch.rb
CHANGED
data/lib/cinch/base.rb
CHANGED
@@ -21,7 +21,7 @@ module Cinch
|
|
21
21
|
|
22
22
|
# A Hash holding rules and attributes
|
23
23
|
attr_reader :rules
|
24
|
-
|
24
|
+
|
25
25
|
# A Hash holding listeners and reply Procs
|
26
26
|
attr_reader :listeners
|
27
27
|
|
@@ -32,6 +32,7 @@ module Cinch
|
|
32
32
|
DEFAULTS = {
|
33
33
|
:port => 6667,
|
34
34
|
:nick => "Cinch",
|
35
|
+
:nick_suffix => '_',
|
35
36
|
:username => 'cinch',
|
36
37
|
:realname => "Cinch IRC Microframework",
|
37
38
|
:prefix => '!',
|
@@ -70,7 +71,12 @@ module Cinch
|
|
70
71
|
|
71
72
|
# Default listeners
|
72
73
|
on(:ping) {|m| @irc.pong(m.text) }
|
73
|
-
|
74
|
+
|
75
|
+
on(433) do |m|
|
76
|
+
@options.nick += @options.nick_suffix
|
77
|
+
@irc.nick @options.nick
|
78
|
+
end
|
79
|
+
|
74
80
|
if @options.respond_to?(:channels)
|
75
81
|
on(376) { @options.channels.each {|c| @irc.join(c) } }
|
76
82
|
end
|
@@ -87,8 +93,8 @@ module Cinch
|
|
87
93
|
op.on("-n nick") {|v| options[:nick] = v }
|
88
94
|
op.on("-c command_prefix") {|v| options[:prefix] = v }
|
89
95
|
op.on("-v", "--verbose", "Enable verbose mode") {|v| options[:verbose] = true }
|
90
|
-
op.on("-C", "--channels x,y,z", Array, "Autojoin channels") {|v|
|
91
|
-
options[:channels] = v.map {|c| %w(# + &).include?(c[0].chr) ? c : c.insert(0, '#') }
|
96
|
+
op.on("-C", "--channels x,y,z", Array, "Autojoin channels") {|v|
|
97
|
+
options[:channels] = v.map {|c| %w(# + &).include?(c[0].chr) ? c : c.insert(0, '#') }
|
92
98
|
}
|
93
99
|
end.parse(ARGV)
|
94
100
|
rescue OptionParser::MissingArgument => err
|
@@ -109,7 +115,7 @@ module Cinch
|
|
109
115
|
# end
|
110
116
|
def plugin(rule, options={}, &blk)
|
111
117
|
rule, keys = compile(rule)
|
112
|
-
|
118
|
+
|
113
119
|
if @rules.has_rule?(rule)
|
114
120
|
@rules.add_callback(rule, blk)
|
115
121
|
@rules.merge_options(rule, options)
|
@@ -117,7 +123,7 @@ module Cinch
|
|
117
123
|
@rules.add_rule(rule, keys, options, blk)
|
118
124
|
end
|
119
125
|
end
|
120
|
-
|
126
|
+
|
121
127
|
# Add new listeners
|
122
128
|
#
|
123
129
|
# == Example
|
@@ -135,7 +141,7 @@ module Cinch
|
|
135
141
|
end
|
136
142
|
|
137
143
|
# This method builds a regular expression from your rule
|
138
|
-
# and defines all named parameters, as well as dealing with
|
144
|
+
# and defines all named parameters, as well as dealing with
|
139
145
|
# patterns.
|
140
146
|
#
|
141
147
|
# So far 3 patterns are supported:
|
@@ -170,7 +176,7 @@ module Cinch
|
|
170
176
|
#
|
171
177
|
# Or mix them all
|
172
178
|
# bot.plugin("say :n-digit :who-word :text")
|
173
|
-
#
|
179
|
+
#
|
174
180
|
# Using "!say 3 injekt some text here" would provide
|
175
181
|
# the following attributes
|
176
182
|
# m.args[:n] => 3
|
@@ -190,7 +196,7 @@ module Cinch
|
|
190
196
|
if k =~ /\-(\w+)$/
|
191
197
|
key, type = k.split('-')
|
192
198
|
keys << key[1..-1]
|
193
|
-
|
199
|
+
|
194
200
|
case type
|
195
201
|
when 'digit'; "(\\d+?)"
|
196
202
|
when 'word'; "([a-zA-Z_]+?)"
|
@@ -204,7 +210,7 @@ module Cinch
|
|
204
210
|
"([^\x00\r\n]+?)"
|
205
211
|
end
|
206
212
|
end
|
207
|
-
else
|
213
|
+
else
|
208
214
|
keys << k[1..-1]
|
209
215
|
"([^\x00\r\n]+?)"
|
210
216
|
end
|
@@ -216,7 +222,7 @@ module Cinch
|
|
216
222
|
# Add a custom 'type', for rule validation
|
217
223
|
#
|
218
224
|
# == Example
|
219
|
-
# bot = Cinch.setup do
|
225
|
+
# bot = Cinch.setup do
|
220
226
|
# server 'irc.freenode.org'
|
221
227
|
# port 6667
|
222
228
|
# end
|
@@ -230,15 +236,15 @@ module Cinch
|
|
230
236
|
@custom_patterns[name.to_s] = "(#{pattern.to_s})"
|
231
237
|
end
|
232
238
|
alias :add_custom_type :add_custom_pattern # backwards
|
233
|
-
alias :add_pattern :add_custom_pattern
|
239
|
+
alias :add_pattern :add_custom_pattern
|
234
240
|
|
235
241
|
# Run run run
|
236
|
-
def run
|
242
|
+
def run
|
237
243
|
@irc.connect options.server, options.port
|
238
244
|
@irc.pass options.password if options.password
|
239
245
|
@irc.nick options.nick
|
240
246
|
@irc.user options.username, options.usermode, '*', options.realname
|
241
|
-
|
247
|
+
|
242
248
|
begin
|
243
249
|
process(@irc.read) while @irc.connected?
|
244
250
|
rescue Interrupt
|
@@ -255,24 +261,41 @@ module Cinch
|
|
255
261
|
message.irc = @irc
|
256
262
|
puts message if options.verbose
|
257
263
|
|
264
|
+
# runs on any symbol
|
265
|
+
@listeners[:any].each { |l| l.call(message) } if @listeners.key?(:any)
|
266
|
+
|
258
267
|
if @listeners.key?(message.symbol)
|
259
268
|
@listeners[message.symbol].each {|l| l.call(message) }
|
260
269
|
end
|
261
270
|
|
262
271
|
if [:privmsg].include?(message.symbol)
|
263
272
|
|
264
|
-
# At the moment we must traverse all
|
273
|
+
# At the moment we must traverse all possible rules, which
|
265
274
|
# could get clunky with a lot of rules. This is because each
|
266
275
|
# rule can be unique in what prefix it uses, in future some kind
|
267
276
|
# of loose checking should be put in place
|
268
277
|
rules.each do |rule|
|
269
|
-
|
270
|
-
|
271
|
-
|
278
|
+
pattern = rule.to_s
|
279
|
+
|
280
|
+
if options.prefix
|
281
|
+
if rule.options.key?(:prefix)
|
282
|
+
if [:bot, :botnick, options.nick].include? rule.options[:prefix]
|
283
|
+
prefix = options.nick + "[:,] "
|
284
|
+
else
|
285
|
+
prefix = rule.options[:prefix]
|
286
|
+
end
|
287
|
+
else
|
288
|
+
prefix = options.prefix
|
272
289
|
end
|
290
|
+
else
|
291
|
+
prefix = nil
|
273
292
|
end
|
274
293
|
|
275
|
-
if
|
294
|
+
if prefix && pattern[1..prefix.size] != prefix
|
295
|
+
pattern.insert(1, prefix)
|
296
|
+
end
|
297
|
+
|
298
|
+
if message.text && mdata = message.text.rstrip.match(Regexp.new(pattern))
|
276
299
|
unless rule.keys.empty? || mdata.captures.empty?
|
277
300
|
args = Hash[rule.keys.map {|k| k.to_sym}.zip(mdata.captures)]
|
278
301
|
message.args = args
|
@@ -306,4 +329,3 @@ module Cinch
|
|
306
329
|
end
|
307
330
|
end
|
308
331
|
end
|
309
|
-
|
data/spec/base_spec.rb
CHANGED
@@ -16,6 +16,10 @@ describe "Cinch::Base" do
|
|
16
16
|
@base.listeners.should include :ping
|
17
17
|
end
|
18
18
|
|
19
|
+
it "should add a default nick-taken listener" do
|
20
|
+
@base.listeners.should include :"433"
|
21
|
+
end
|
22
|
+
|
19
23
|
it "should add a 376 listener, only if channels are set" do
|
20
24
|
@base.listeners.should_not include :'376'
|
21
25
|
@full.listeners.should include :'376'
|
data/spec/options_spec.rb
CHANGED
@@ -27,7 +27,12 @@ describe "Cinch::Base options" do
|
|
27
27
|
defaults = {
|
28
28
|
:port => 6667,
|
29
29
|
:nick => 'Cinch',
|
30
|
+
:nick_suffix => '_',
|
31
|
+
:username => 'cinch',
|
32
|
+
:realname => 'Cinch IRC Microframework',
|
33
|
+
:usermode => 0,
|
30
34
|
:prefix => '!',
|
35
|
+
:password => nil,
|
31
36
|
}
|
32
37
|
|
33
38
|
base = @base.new
|
data/spec/spec.opts
ADDED
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 2
|
8
|
-
-
|
9
|
-
version: 0.2.
|
8
|
+
- 9
|
9
|
+
version: 0.2.9
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Lee 'injekt' Jarvis
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-
|
17
|
+
date: 2010-05-07 00:00:00 +01:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -43,6 +43,7 @@ files:
|
|
43
43
|
- README.rdoc
|
44
44
|
- Rakefile
|
45
45
|
- spec/base_spec.rb
|
46
|
+
- spec/spec.opts
|
46
47
|
- spec/irc/socket_spec.rb
|
47
48
|
- spec/irc/helper.rb
|
48
49
|
- spec/irc/message_spec.rb
|
@@ -57,10 +58,13 @@ files:
|
|
57
58
|
- lib/cinch/irc/parser.rb
|
58
59
|
- lib/cinch/rules.rb
|
59
60
|
- lib/cinch/irc.rb
|
61
|
+
- examples/google.rb
|
62
|
+
- examples/custom_prefix.rb
|
60
63
|
- examples/join_part.rb
|
61
64
|
- examples/msg.rb
|
62
65
|
- examples/memo.rb
|
63
66
|
- examples/custom_patterns.rb
|
67
|
+
- examples/urban_dict.rb
|
64
68
|
- examples/seen.rb
|
65
69
|
- examples/hello.rb
|
66
70
|
- examples/autovoice.rb
|