cinch 0.2.6 → 0.2.9
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 +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
|