cinch 0.2.6 → 0.2.9

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+
@@ -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
+
@@ -9,7 +9,7 @@ require 'cinch/rules'
9
9
  require 'cinch/base'
10
10
 
11
11
  module Cinch
12
- VERSION = '0.2.6'
12
+ VERSION = '0.2.9'
13
13
 
14
14
  # Setup bot options and return a new Cinch::Base instance
15
15
  def self.setup(ops={}, &blk)
@@ -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 possibly rules, which
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
- unless rule.options.key?(:prefix) || options.prefix == false
270
- unless rule.to_s[1..options.prefix.size] == options.prefix
271
- rule.to_s.insert(1, options.prefix)
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 message.text && mdata = message.text.rstrip.match(Regexp.new(rule.to_s))
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
-
@@ -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'
@@ -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
@@ -0,0 +1,2 @@
1
+ --colour
2
+ --format specdoc
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 2
8
- - 6
9
- version: 0.2.6
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-04-28 00:00:00 +01:00
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