cinch 0.2.9 → 0.3.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.rdoc CHANGED
@@ -1,8 +1,7 @@
1
- = Cinch: The IRC Microframework
1
+ = Cinch: The IRC Bot Building Framework
2
2
 
3
3
  == Description
4
-
5
- Cinch is an IRC Microframework for quickly creating IRC bots
4
+ Cinch is an IRC Bot Building Framework for quickly creating IRC bots
6
5
  in Ruby with minimal effort.
7
6
  It provides a minimal interface based on plugins and rules. It's as simple as creating a
8
7
  plugin, defining a rule, and watching your profits flourish.
@@ -14,7 +13,6 @@ If you'd like to test your own Cinch experiments you can do so in the cinch IRC
14
13
  on {irc.freenode.org}[irc://irc.freenode.org/cinch]. Support is also welcome here.
15
14
 
16
15
  == Installation
17
- The latest version of Cinch is 0.2
18
16
 
19
17
  === RubyGems
20
18
  You can install the latest version of Cinch using RubyGems
@@ -25,7 +23,6 @@ Alternatively you can check out the latest code directly from Github
25
23
  git clone http://github.com/injekt/cinch.git
26
24
 
27
25
  == Example
28
-
29
26
  Your typical <em>Hello, World</em> application would go something like this:
30
27
 
31
28
  require 'cinch'
@@ -62,17 +59,18 @@ other Ruby script.
62
59
 
63
60
  ruby hello.rb
64
61
 
65
- Cinch also parses the command line for options, to save you having to configure options within your script.
62
+ Cinch also parses the command line for options, to save you having to configure
63
+ options within your script.
66
64
 
67
65
  ruby hello.rb -s irc.freenode.org -n Coolbot
68
- ruby hello.rb --channels foo,bar
66
+ ruby hello.rb -C foo,bar
69
67
 
70
- Doing a <b>ruby hello.rb -h</b> provides all possible command line options. When using the <em>--channels</em>
71
- option, the channel prefix is option, and if none is given the channel will be prefixed with a hash (#)
68
+ Doing a <b>ruby hello.rb -h</b> provides all possible command line options. When using the <em>-C</em>
69
+ or <em>--channels</em> option, the channel prefix is option, and if none is given the channel
70
+ will be prefixed with a hash (#)
72
71
  character
73
72
 
74
73
  == Plugins
75
-
76
74
  Plugins are invoked using the command prefix character (which by default is set to <b>!</b>). You can
77
75
  also tell Cinch to ignore any command prefix and instead use the bots username. This would provide
78
76
  a result similar to this:
@@ -172,8 +170,7 @@ before sending me a pull request. Alternatively paste the example and inform me
172
170
  channel or by email
173
171
 
174
172
  == Authors
175
- Just me at the moment, sad poor lonely me...
176
- * {Lee Jarvis}[http://blog.injekt.net]
173
+ * {Lee Jarvis}[http://injekt.net]
177
174
 
178
175
  == Notes
179
176
  * RDoc API documentation is available {here}[http://rdoc.injekt.net/cinch]
@@ -189,5 +186,4 @@ request once one patch has been submitted. Any contribution is welcome and appre
189
186
  == TODO
190
187
  * More specs
191
188
  * More documentation
192
- * More examples
193
189
 
data/Rakefile CHANGED
@@ -1,14 +1,19 @@
1
1
  require "rake"
2
2
  require "rake/clean"
3
3
  require "rake/gempackagetask"
4
- require "rake/rdoctask"
5
4
  require "spec/rake/spectask"
6
5
 
6
+ begin
7
+ require 'hanna/rdoctask'
8
+ rescue LoadError
9
+ require 'rake/rdoctask'
10
+ end
11
+
7
12
  require 'lib/cinch'
8
13
 
9
14
  NAME = 'cinch'
10
15
  VERSION = Cinch::VERSION
11
- TITLE = "Cinch: The IRC Microframework"
16
+ TITLE = "Cinch: The IRC Bot Building Framework"
12
17
  CLEAN.include ["*.gem", "rdoc"]
13
18
  RDOC_OPTS = [
14
19
  "-U", "--title", TITLE,
data/lib/cinch.rb CHANGED
@@ -9,7 +9,7 @@ require 'cinch/rules'
9
9
  require 'cinch/base'
10
10
 
11
11
  module Cinch
12
- VERSION = '0.2.9'
12
+ VERSION = '0.3.0'
13
13
 
14
14
  # Setup bot options and return a new Cinch::Base instance
15
15
  def self.setup(ops={}, &blk)
data/lib/cinch/base.rb CHANGED
@@ -1,8 +1,5 @@
1
1
  module Cinch
2
2
 
3
- # == Author
4
- # * Lee Jarvis - ljjarvis@gmail.com
5
- #
6
3
  # == Description
7
4
  # The base for an IRC connection
8
5
  # TODO: More documentation
@@ -17,6 +14,9 @@ module Cinch
17
14
  # bot.plugin "say :text" do |m|
18
15
  # m.reply m.args[:text]
19
16
  # end
17
+ #
18
+ # == Author
19
+ # * Lee Jarvis - ljjarvis@gmail.com
20
20
  class Base
21
21
 
22
22
  # A Hash holding rules and attributes
@@ -28,6 +28,12 @@ module Cinch
28
28
  # An OpenStruct holding all configuration options
29
29
  attr_reader :options
30
30
 
31
+ # Hash of custom rule patterns
32
+ attr_reader :custom_patterns
33
+
34
+ # Our IRC::Socket instance
35
+ attr_reader :irc
36
+
31
37
  # Default options hash
32
38
  DEFAULTS = {
33
39
  :port => 6667,
@@ -64,7 +70,14 @@ module Cinch
64
70
 
65
71
  @rules = Rules.new
66
72
  @listeners = {}
67
- @custom_patterns = {}
73
+
74
+ @custom_patterns = {
75
+ 'digit' => "(\\d+?)",
76
+ 'word' => "([a-zA-Z_]+?)",
77
+ 'string' => "(\\w+?)",
78
+ 'upper' => "([A-Z]+?)",
79
+ 'lower' => "([a-z]+?)",
80
+ }
68
81
 
69
82
  @irc = IRC::Socket.new(options[:server], options[:port])
70
83
  @parser = IRC::Parser.new
@@ -78,7 +91,7 @@ module Cinch
78
91
  end
79
92
 
80
93
  if @options.respond_to?(:channels)
81
- on(376) { @options.channels.each {|c| @irc.join(c) } }
94
+ on("004") { @options.channels.each {|c| @irc.join(c) } }
82
95
  end
83
96
  end
84
97
 
@@ -123,6 +136,7 @@ module Cinch
123
136
  @rules.add_rule(rule, keys, options, blk)
124
137
  end
125
138
  end
139
+ alias :rule :plugin
126
140
 
127
141
  # Add new listeners
128
142
  #
@@ -130,6 +144,11 @@ module Cinch
130
144
  # on(376) do |m|
131
145
  # m.join "#mychan"
132
146
  # end
147
+ #
148
+ # Note that when adding listeners for numberic IRC replies which
149
+ # begin with a 0 (digit), make sure you define the command as a
150
+ # String and not Integer. This is because 001.to_s == "1" so the
151
+ # command will not work as expected.
133
152
  def on(*commands, &blk)
134
153
  commands.map {|x| x.to_s.downcase.to_sym }.each do |cmd|
135
154
  if @listeners.key?(cmd)
@@ -153,28 +172,28 @@ module Cinch
153
172
  # * upper - matches [A-Z]+
154
173
  #
155
174
  # == Examples
156
- # For capturing individual words
175
+ # === Capturing individual words
157
176
  # bot.plugin("say :text-word")
158
177
  # * Does match !say foo
159
178
  # * Does not match !say foo bar baz
160
179
  #
161
- # For capturing digits
180
+ # === Capturing digits
162
181
  # bot.plugin("say :text-digit")
163
182
  # * Does match !say 3
164
183
  # * Does not match !say 3 4
165
184
  # * Does not match !say foo
166
185
  #
167
- # For both
186
+ # === Both digit and word
168
187
  # bot.plugin("say :n-digit :text-word")
169
188
  # * Does match !say 3 foo
170
189
  # * Does not match !say 3 foo bar
171
190
  #
172
- # For capturing until the end of the line
191
+ # === Capturing until the end of the line
173
192
  # bot.plugin("say :text")
174
193
  # * Does match !say foo
175
194
  # * Does match !say foo bar
176
195
  #
177
- # Or mix them all
196
+ # === Or mix them all
178
197
  # bot.plugin("say :n-digit :who-word :text")
179
198
  #
180
199
  # Using "!say 3 injekt some text here" would provide
@@ -193,22 +212,14 @@ module Cinch
193
212
  Regexp.escape(match)
194
213
  else
195
214
  k = $2
196
- if k =~ /\-(\w+)$/
215
+ if k =~ /\-\w+$/
197
216
  key, type = k.split('-')
198
217
  keys << key[1..-1]
199
-
200
- case type
201
- when 'digit'; "(\\d+?)"
202
- when 'word'; "([a-zA-Z_]+?)"
203
- when 'string'; "(\\w+?)"
204
- when 'upper'; "([A-Z]+?)"
205
- when 'lower'; "([a-z]+?)"
218
+
219
+ if @custom_patterns.include?(type)
220
+ @custom_patterns[type]
206
221
  else
207
- if @custom_patterns.include?(type)
208
- @custom_patterns[type]
209
- else
210
- "([^\x00\r\n]+?)"
211
- end
222
+ "([^\x00\r\n]+?)"
212
223
  end
213
224
  else
214
225
  keys << k[1..-1]
@@ -222,20 +233,19 @@ module Cinch
222
233
  # Add a custom 'type', for rule validation
223
234
  #
224
235
  # == Example
225
- # bot = Cinch.setup do
226
- # server 'irc.freenode.org'
227
- # port 6667
228
- # end
236
+ # bot = Cinch.setup do
237
+ # server 'irc.freenode.org'
238
+ # port 6667
239
+ # end
229
240
  #
230
- # bot.add_custom_pattern(:number, "[0-9]")
241
+ # bot.add_custom_pattern(:number, "[0-9]")
231
242
  #
232
- # bot.plugin("getnum :foo-number") do |m|
233
- # m.reply "Your number was: #{m.args[:foo]}"
234
- # end
243
+ # bot.plugin("getnum :foo-number") do |m|
244
+ # m.reply "Your number was: #{m.args[:foo]}"
245
+ # end
235
246
  def add_custom_pattern(name, pattern)
236
247
  @custom_patterns[name.to_s] = "(#{pattern.to_s})"
237
248
  end
238
- alias :add_custom_type :add_custom_pattern # backwards
239
249
  alias :add_pattern :add_custom_pattern
240
250
 
241
251
  # Run run run
data/lib/cinch/irc.rb CHANGED
@@ -8,9 +8,7 @@ require 'irc/message'
8
8
  require 'irc/socket'
9
9
 
10
10
  module Cinch
11
- # == Author
12
- # * Lee Jarvis - ljjarvis@gmail.com
13
- #
11
+
14
12
  # == Description
15
13
  # Cinch::IRC provides tools to interact with an IRC server, this
16
14
  # includes reading/writing/parsing and building a message response.
@@ -38,6 +36,8 @@ module Cinch
38
36
  # end
39
37
  # end
40
38
  #
39
+ # == Author
40
+ # * Lee Jarvis - ljjarvis@gmail.com
41
41
  module IRC
42
42
 
43
43
  end
@@ -1,18 +1,17 @@
1
1
  module Cinch
2
2
  module IRC
3
3
 
4
- # == Author
5
- # * Lee Jarvis - ljjarvis@gmail.com
6
- #
7
4
  # == Description
8
- # IRC::Message is a nicely encapsulated IRC message object. Used directly by
9
- # IRC::Parser#parse_servermessage and sent to every plugin defined. It does
10
- # not do any parsing of itself, that's all down to the parser
11
- #
12
- # == See
13
- # * Cinch::IRC::Parser#parse_servermessage
5
+ # IRC::Message provies a nicely encapsulated IRC message object. Used directly by
6
+ # IRC::Parser#parse and sent to any plugin or listener defined.
14
7
  #
15
8
  # TODO: Add more documentation
9
+ #
10
+ # == See Also
11
+ # * Cinch::IRC::Parser#parse
12
+ #
13
+ # == Author
14
+ # * Lee Jarvis - ljjarvis@gmail.com
16
15
  class Message
17
16
 
18
17
  # Message prefix
@@ -74,16 +73,21 @@ module Cinch
74
73
  @data.delete(var)
75
74
  end
76
75
 
76
+ # Alter an attribute
77
+ def alter(var, val)
78
+ if @data.key?(var)
79
+ @data[var] = val
80
+ end
81
+ end
82
+
77
83
  # Check if our message was sent privately
78
84
  def private?
79
85
  !@data[:channel]
80
86
  end
81
87
 
82
- # Add the nick/user/host attributes
83
- def apply_user(nick, user, host)
84
- @data[:nick] = nick
85
- @data[:user] = user
86
- @data[:host] = host
88
+ # Check if our message was sent publicly (in a channel)
89
+ def public?
90
+ !private?
87
91
  end
88
92
 
89
93
  # Reply to a channel or user, probably the most commonly used helper
@@ -1,9 +1,6 @@
1
1
  module Cinch
2
2
  module IRC
3
3
 
4
- # == Author
5
- # * Lee Jarvis - ljjarvis@gmail.com
6
- #
7
4
  # == Description
8
5
  # Parse incoming IRC lines and extract data, returning a nicely
9
6
  # encapsulated Cinch::IRC::Message
@@ -19,6 +16,9 @@ module Cinch
19
16
  # message.nick #=> foo
20
17
  # message.channel #=> #mychan
21
18
  # message.text #=> ding dong!
19
+ #
20
+ # == Author
21
+ # * Lee Jarvis - ljjarvis@gmail.com
22
22
  class Parser
23
23
 
24
24
  # A hash holding all of our patterns
@@ -79,7 +79,7 @@ module Cinch
79
79
 
80
80
  # Parse the incoming raw IRC string and return
81
81
  # a nicely formatted IRC::Message
82
- def parse_servermessage(raw)
82
+ def parse(raw)
83
83
  raise ArgumentError, raw unless raw && matches = raw.match(pattern(:message))
84
84
 
85
85
  prefix, command, parameters = matches.captures
@@ -90,17 +90,19 @@ module Cinch
90
90
  m = IRC::Message.new(raw, prefix, command, params)
91
91
 
92
92
  if prefix && userhost = parse_userhost(prefix)
93
- m.apply_user(*userhost)
93
+ nick, user, host = userhost
94
+ m.add(:nick, nick)
95
+ m.add(:user, user)
96
+ m.add(:host, host)
94
97
 
95
98
  unless m.params.empty?
96
- m[:recipient] = m.params.first
97
- m[:channel] = m[:recipient] if valid_channel?(m[:recipient])
99
+ m.add(:recipient, m.params.first)
100
+ m.add(:channel, m.recipient) if valid_channel?(m.recipient)
98
101
  end
99
102
  end
100
103
 
101
104
  m # Return our IRC::Message
102
105
  end
103
- alias :parse :parse_servermessage
104
106
 
105
107
  # Parse the prefix returned from the server
106
108
  # and return an Array of [nick, user, host] or
@@ -1,10 +1,8 @@
1
1
  module Cinch
2
2
  module IRC
3
- # == Author
4
- # * Lee Jarvis - ljjarvis@gmail.com
5
- #
3
+
6
4
  # == Description
7
- # This class has been directly take from the irc-socket library. Original documentation
5
+ # This class has been directly taken from the irc-socket library. Original documentation
8
6
  # for this class can be found {here}[http://rdoc.injekt.net/irc-socket].
9
7
  #
10
8
  # IRCSocket is an IRC wrapper around a TCPSocket. It implements all of the major
@@ -37,6 +35,9 @@ module Cinch
37
35
  #
38
36
  # puts irc.read
39
37
  # end
38
+ #
39
+ # == Author
40
+ # * Lee Jarvis - ljjarvis@gmail.com
40
41
  class Socket
41
42
 
42
43
  # The server our socket is connected to
@@ -166,7 +167,7 @@ module Cinch
166
167
 
167
168
  # Send JOIN command - Join a channel with given password
168
169
  def join(channel, password=nil)
169
- write("JOIN #{channel}")
170
+ write_optional("JOIN #{channel}", password)
170
171
  end
171
172
 
172
173
  # Send PART command
data/lib/cinch/rules.rb CHANGED
@@ -1,8 +1,5 @@
1
1
  module Cinch
2
2
 
3
- # == Author
4
- # * Lee Jarvis - ljjarvis@gmail.com
5
- #
6
3
  # == Description
7
4
  # Every rule defined through the Cinch::Base#plugin method becomes an instance
8
5
  # of this class. Each rule consists of keys used for named parameters, a hash
@@ -10,25 +7,28 @@ module Cinch
10
7
  #
11
8
  # When a rule matches an IRC message, all options with be checked, then all
12
9
  # callbacks will be invoked.
10
+ #
11
+ # == Author
12
+ # * Lee Jarvis - ljjarvis@gmail.com
13
13
  class Rule < Struct.new(:rule, :keys, :options, :callbacks)
14
14
  def initialize(rule, keys, options, callback)
15
15
  callbacks = [callback]
16
16
  super(rule, keys, options, callbacks)
17
17
  end
18
18
 
19
- # Execute all callbacks, passing an Cinch::IRC::Message to them
19
+ # Execute all callbacks, passing a Cinch::IRC::Message to them
20
20
  def execute(message)
21
21
  options.keys.each do |key|
22
22
  case key
23
23
  when :nick, :nicks
24
- return unless validate(options[:nick], message.nick)
24
+ return unless validate(options[:nick] || options[:nicks], message.nick)
25
25
  when :host, :hosts
26
- return unless validate(options[:host], message.host)
26
+ return unless validate(options[:host] || options[:hosts], message.host)
27
27
  when :user, :users
28
- return unless validate(options[:user], message.user)
28
+ return unless validate(options[:user] || options[:users], message.user)
29
29
  when :channel, :channels
30
30
  if message.channel
31
- return unless validate(options[:channel], message.channel)
31
+ return unless validate(options[:channel] || options[:channels], message.channel)
32
32
  end
33
33
  end
34
34
  end
@@ -43,7 +43,7 @@ module Cinch
43
43
  if option.is_a?(Array)
44
44
  return unless option.any?{|o| o == attr }
45
45
  else
46
- return unless options.to_s == attr
46
+ return unless option.to_s == attr
47
47
  end
48
48
  true
49
49
  end
@@ -54,9 +54,6 @@ module Cinch
54
54
  end
55
55
  end
56
56
 
57
- # == Author
58
- # * Lee Jarvis - ljjarvis@gmail.com
59
- #
60
57
  # == Description
61
58
  # This class provides an interface to manage rules. A rule should only ever be
62
59
  # added using the Rules#add_rule method and retrieved using the Rules#get_rule
@@ -87,6 +84,9 @@ module Cinch
87
84
  # rules.get_rule('foo')
88
85
  # rules.options = {:foo => 'bar'}
89
86
  # rules.options[:bar] = 'baz'
87
+ #
88
+ # == Author
89
+ # * Lee Jarvis - ljjarvis@gmail.com
90
90
  class Rules
91
91
  def initialize
92
92
  @rules = {}
data/spec/base_spec.rb CHANGED
@@ -20,9 +20,19 @@ describe "Cinch::Base" do
20
20
  @base.listeners.should include :"433"
21
21
  end
22
22
 
23
- it "should add a 376 listener, only if channels are set" do
24
- @base.listeners.should_not include :'376'
25
- @full.listeners.should include :'376'
23
+ it "should add a 004 listener, only if channels are set" do
24
+ @base.listeners.should_not include :'004'
25
+ @full.listeners.should include :'004'
26
+ end
27
+
28
+ it "should add a 433 nick taken listener" do
29
+ @base.listeners.should include :'433'
30
+ end
31
+
32
+ it "should add default custom_patterns" do
33
+ [:digit, :word, :string, :upper, :lower].each do |l|
34
+ @base.custom_patterns.should include l.to_s
35
+ end
26
36
  end
27
37
  end
28
38
 
@@ -56,7 +56,7 @@ describe "IRC::Parser" do
56
56
  end
57
57
  end
58
58
 
59
- describe "#parse_servermessage" do
59
+ describe "#parse" do
60
60
  it "should return an IRC::Message" do
61
61
  @parser.parse("foo :bar").should be_kind_of(Cinch::IRC::Message)
62
62
  end
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 2
8
- - 9
9
- version: 0.2.9
7
+ - 3
8
+ - 0
9
+ version: 0.3.0
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-05-07 00:00:00 +01:00
17
+ date: 2010-05-18 00:00:00 +01:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -31,7 +31,7 @@ dependencies:
31
31
  version: 1.3.0
32
32
  type: :development
33
33
  version_requirements: *id001
34
- description: An IRC Microframework
34
+ description: An IRC Bot Building Framework
35
35
  email: ljjarvis@gmail.com
36
36
  executables: []
37
37
 
@@ -77,7 +77,7 @@ post_install_message:
77
77
  rdoc_options:
78
78
  - --quiet
79
79
  - --title
80
- - "Cinch: The IRC Microframework"
80
+ - "Cinch: The IRC Bot Building Framework"
81
81
  - --main
82
82
  - README.rdoc
83
83
  require_paths:
@@ -104,6 +104,6 @@ rubyforge_project:
104
104
  rubygems_version: 1.3.6
105
105
  signing_key:
106
106
  specification_version: 3
107
- summary: An IRC Microframework
107
+ summary: An IRC Bot Building Framework
108
108
  test_files: []
109
109