cinch 0.3.5 → 1.0.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.
Files changed (82) hide show
  1. data/LICENSE +20 -0
  2. data/README.md +192 -0
  3. data/Rakefile +53 -43
  4. data/examples/basic/autovoice.rb +32 -0
  5. data/examples/basic/google.rb +35 -0
  6. data/examples/basic/hello.rb +15 -0
  7. data/examples/basic/join_part.rb +38 -0
  8. data/examples/basic/memo.rb +39 -0
  9. data/examples/basic/msg.rb +16 -0
  10. data/examples/basic/seen.rb +36 -0
  11. data/examples/basic/urban_dict.rb +35 -0
  12. data/examples/basic/url_shorten.rb +35 -0
  13. data/examples/plugins/autovoice.rb +40 -0
  14. data/examples/plugins/custom_prefix.rb +23 -0
  15. data/examples/plugins/google.rb +37 -0
  16. data/examples/plugins/hello.rb +22 -0
  17. data/examples/plugins/join_part.rb +42 -0
  18. data/examples/plugins/memo.rb +50 -0
  19. data/examples/plugins/msg.rb +22 -0
  20. data/examples/plugins/multiple_matches.rb +41 -0
  21. data/examples/plugins/seen.rb +45 -0
  22. data/examples/plugins/urban_dict.rb +30 -0
  23. data/examples/plugins/url_shorten.rb +32 -0
  24. data/lib/cinch.rb +7 -20
  25. data/lib/cinch/ban.rb +41 -0
  26. data/lib/cinch/bot.rb +479 -0
  27. data/lib/cinch/callback.rb +11 -0
  28. data/lib/cinch/channel.rb +419 -0
  29. data/lib/cinch/constants.rb +369 -0
  30. data/lib/cinch/exceptions.rb +25 -0
  31. data/lib/cinch/helpers.rb +21 -0
  32. data/lib/cinch/irc.rb +344 -38
  33. data/lib/cinch/isupport.rb +96 -0
  34. data/lib/cinch/logger/formatted_logger.rb +80 -0
  35. data/lib/cinch/logger/logger.rb +44 -0
  36. data/lib/cinch/logger/null_logger.rb +18 -0
  37. data/lib/cinch/mask.rb +46 -0
  38. data/lib/cinch/message.rb +183 -0
  39. data/lib/cinch/message_queue.rb +62 -0
  40. data/lib/cinch/plugin.rb +205 -0
  41. data/lib/cinch/rubyext/infinity.rb +1 -0
  42. data/lib/cinch/rubyext/module.rb +18 -0
  43. data/lib/cinch/rubyext/queue.rb +19 -0
  44. data/lib/cinch/rubyext/string.rb +24 -0
  45. data/lib/cinch/syncable.rb +55 -0
  46. data/lib/cinch/user.rb +325 -0
  47. data/spec/bot_spec.rb +5 -0
  48. data/spec/channel_spec.rb +5 -0
  49. data/spec/cinch_spec.rb +5 -0
  50. data/spec/irc_spec.rb +5 -0
  51. data/spec/message_spec.rb +5 -0
  52. data/spec/plugin_spec.rb +5 -0
  53. data/spec/{helper.rb → spec_helper.rb} +0 -0
  54. data/spec/user_spec.rb +5 -0
  55. metadata +69 -51
  56. data/README.rdoc +0 -195
  57. data/examples/autovoice.rb +0 -32
  58. data/examples/custom_patterns.rb +0 -19
  59. data/examples/custom_prefix.rb +0 -25
  60. data/examples/google.rb +0 -31
  61. data/examples/hello.rb +0 -13
  62. data/examples/join_part.rb +0 -26
  63. data/examples/memo.rb +0 -40
  64. data/examples/msg.rb +0 -14
  65. data/examples/named-param-types.rb +0 -19
  66. data/examples/seen.rb +0 -41
  67. data/examples/urban_dict.rb +0 -31
  68. data/examples/url_shorten.rb +0 -34
  69. data/lib/cinch/base.rb +0 -368
  70. data/lib/cinch/irc/message.rb +0 -135
  71. data/lib/cinch/irc/parser.rb +0 -141
  72. data/lib/cinch/irc/socket.rb +0 -329
  73. data/lib/cinch/names.rb +0 -54
  74. data/lib/cinch/rules.rb +0 -171
  75. data/spec/base_spec.rb +0 -94
  76. data/spec/irc/helper.rb +0 -8
  77. data/spec/irc/message_spec.rb +0 -61
  78. data/spec/irc/parser_spec.rb +0 -103
  79. data/spec/irc/socket_spec.rb +0 -90
  80. data/spec/names_spec.rb +0 -393
  81. data/spec/options_spec.rb +0 -45
  82. data/spec/rules_spec.rb +0 -109
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 Lee Jarvis, Dominik Honnef
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,192 @@
1
+ Cinch - An IRC Bot Building Framework
2
+ =====================================
3
+
4
+ Description
5
+ -----------
6
+
7
+ Cinch is an IRC Bot Building Framework for quickly creating IRC bots in
8
+ Ruby with minimal effort. It provides a simple interface based on plugins and
9
+ rules. It's as easy as creating a plugin, defining a rule, and watching your
10
+ profits flourish.
11
+
12
+ Cinch will do all of the hard work for you, so you can spend time creating cool
13
+ plugins and extensions to wow your internet peers.
14
+
15
+ If you'd like to test your own Cinch experiments you can do so in the
16
+ \#cinch-bots IRC channel on
17
+ [irc.freenode.org](irc://irc.freenode.org/cinch-bots). For general
18
+ support, join [#cinch](irc://irc.freenode.org/cinch).
19
+
20
+ This original document can be found [here](http://doc.injekt.net/cinch).
21
+
22
+ Installation
23
+ ------------
24
+
25
+ ### RubyGems
26
+
27
+ You can install the latest Cinch gem using RubyGems
28
+
29
+ gem install cinch
30
+
31
+ ### GitHub
32
+
33
+ Alternatively you can check out the latest code directly from Github
34
+
35
+ git clone http://github.com/injekt/cinch.git
36
+
37
+ Example
38
+ -------
39
+
40
+ Your typical Hello, World application in Cinch would go something like this:
41
+
42
+ require 'cinch'
43
+
44
+ bot = Cinch::Bot.new do
45
+ configure do |c|
46
+ c.server = "irc.freenode.org"
47
+ c.channels = ["#cinch-bots"]
48
+ end
49
+
50
+ on :message, "hello" do |m|
51
+ m.reply "Hello, #{m.user.nick}"
52
+ end
53
+ end
54
+
55
+ bot.start
56
+
57
+ More examples can be found in the `examples` directory.
58
+
59
+ Features
60
+ --------
61
+
62
+ ### Documentation
63
+
64
+ Cinch provides a documented API, which is online for your viewing pleasure [here](http://doc.injekt.net/cinch).
65
+
66
+ ### Object Oriented
67
+
68
+ Many IRC bots (and there are, so **many**) are great, but we see so little of them take
69
+ advantage of the awesome Object Oriented Interface which most Ruby programmers will have
70
+ become accustomed to and grown to love.
71
+
72
+ Well, Cinch uses this functionality to it's advantage. Rather than having to pass around
73
+ a reference to a channel or a user, to another method, which then passes it to
74
+ another method (by which time you're confused about what's going on) -- Cinch provides
75
+ an OOP interface for even the simpliest of tasks, making your code simple and easy
76
+ to comprehend.
77
+
78
+ ### Threaded
79
+
80
+ Unlike a lot of popular IRC frameworks, Cinch is threaded. But wait, don't let that
81
+ scare you. It's totally easy to grasp.
82
+
83
+ Each of Cinch's plugins and handlers are executed in their own personal thread. This
84
+ means the main thread can stay focused on what it does best, providing non-blocking
85
+ reading and writing to an IRC server. This will prevent your bot from locking up
86
+ when one of your plugins starts doing some intense operations. Damn that's handy.
87
+
88
+ ### Key/Value Store
89
+
90
+ We have listened to your requests and implemented a bot-wide key/value store. You can
91
+ now store data and use it across your handlers. Here's an example:
92
+
93
+ configure do |c|
94
+ store[:friends] = []
95
+ end
96
+
97
+ on :message, /^add friend (.+)$/ do |m, friend|
98
+ store[:friends] << friend
99
+ end
100
+
101
+ on :message /^get friends$/ do |m|
102
+ m.reply "Your friends are: #{store[:friends].join(', ')}"
103
+ end
104
+
105
+ Neat, right?
106
+
107
+ ### Plugins
108
+
109
+ That's right folks, Cinch provides a modular based plugin system. This is a feature
110
+ many people have bugged us about for a long time. It's finally here, and it's
111
+ as awesome as you had hoped!
112
+
113
+ This system allows you to create feature packed plugins without interfering with
114
+ any of the Cinch internals. Everything in your plugin is self contained, meaning
115
+ you can share your favorite plugins among your friends and release a ton of
116
+ your own plugins for others to use
117
+
118
+ Want to see the same Hello, World application in plugin form? Sure you do!
119
+
120
+ require 'cinch'
121
+
122
+ class Hello
123
+ include Cinch::Plugin
124
+
125
+ match "hello"
126
+
127
+ def execute(m)
128
+ m.reply "Hello, #{m.user.nick}"
129
+ end
130
+ end
131
+
132
+ bot = Cinch::Bot.new do
133
+ configure do |c|
134
+ c.server = "irc.freenode.org"
135
+ c.channels = ["#cinch-bots"]
136
+ c.plugins.plugins = [Hello]
137
+ end
138
+ end
139
+
140
+ bot.start
141
+
142
+ More information can be found in the {Cinch::Plugin} documentation.
143
+
144
+ ### Numeric Replies
145
+
146
+ Do you know what IRC code 401 represents? How about 376? or perhaps 502?
147
+ Sure you don't (and if you do, you're as geeky as us!). Cinch doesn't expect you
148
+ to store the entire IRC RFC code set in your head, and rightfully so!
149
+
150
+ That's exactly why Cinch has a ton of constants representing these numbers
151
+ so you don't have to remember them. We're so nice.
152
+
153
+ ### Pretty Output
154
+
155
+ Ever get fed up of watching those boring, frankly unreadable lines
156
+ flicker down your terminal screen whilst your bot is online? Help is
157
+ at hand! By default, Cinch will colorize all text it sends to a
158
+ terminal, meaning you get some pretty damn awesome readable coloured
159
+ text. Cinch also provides a way for your plugins to log custom
160
+ messages:
161
+
162
+ on :message, /hello/ do |m|
163
+ bot.logger.debug "Someone said hello"
164
+ end
165
+
166
+ Authors
167
+ -------
168
+
169
+ * [Lee Jarvis](http://injekt.net)
170
+ * [Dominik Honnef](http://fork-bomb.org)
171
+
172
+ Contribute
173
+ ----------
174
+
175
+ Love Cinch? Love Ruby? Love helping? Of course you do! If you feel like Cinch
176
+ is missing that awesome jaw-dropping feature and you want to be the one to
177
+ make this magic happen, you can!
178
+
179
+ Please note that although we very much appreciate all of your efforts, Cinch
180
+ will not accept patches in aid of Ruby 1.8 compatibility. We have no intention
181
+ of supporting Ruby versions below 1.9.1.
182
+
183
+ Fork the project, implement your awesome feature in it's own branch, and send
184
+ a pull request to one of the Cinch collaborators. We'll be more than happy
185
+ to check it out.
186
+
187
+ Just remember, no specs, no cookies!
188
+
189
+ ### Contributors
190
+ - darix &lt;darix [at] nordisch.org&gt; (wrote the message splitting algorithm)
191
+ - robgleeson (thanks for testing, contributing a lot of ideas,
192
+ discussing design decisions etc)
data/Rakefile CHANGED
@@ -1,56 +1,66 @@
1
- require "rake"
2
- require "rake/clean"
3
- require "rake/gempackagetask"
4
- require "spec/rake/spectask"
5
-
6
- begin
7
- require 'hanna/rdoctask'
8
- rescue LoadError
9
- require 'rake/rdoctask'
10
- end
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'rake/clean'
11
4
 
12
- require 'lib/cinch'
13
-
14
- NAME = 'cinch'
15
- VERSION = Cinch::VERSION
16
- TITLE = "Cinch: The IRC Bot Building Framework"
17
- CLEAN.include ["*.gem", "rdoc"]
18
- RDOC_OPTS = [
19
- "-U", "--title", TITLE,
20
- "--op", "rdoc",
21
- "--main", "README.rdoc"
22
- ]
23
-
24
- Rake::RDocTask.new do |rdoc|
25
- rdoc.rdoc_dir = "rdoc"
26
- rdoc.options += RDOC_OPTS
27
- rdoc.rdoc_files.add %w(README.rdoc lib/**/*.rb)
28
- end
5
+ $LOAD_PATH.unshift('lib') unless $LOAD_PATH.include?('lib')
6
+ require 'cinch'
29
7
 
30
- desc "Package"
31
- task :package => [:clean] do |p|
32
- sh "gem build #{NAME}.gemspec"
8
+ CLEAN.include ["doc"]
9
+
10
+ require 'spec/rake/spectask'
11
+ Spec::Rake::SpecTask.new(:spec) do |spec|
12
+ spec.libs << 'lib' << 'spec'
13
+ spec.spec_files = FileList['spec/**/*_spec.rb']
33
14
  end
34
15
 
35
- desc "Install gem"
36
- task :install => [:package] do
37
- sh "sudo gem install ./#{NAME}-#{VERSION} --local"
16
+ require 'yard'
17
+ YARD::Rake::YardocTask.new do |t|
18
+ t.files = ['lib/**/*.rb', 'README.md']
19
+ t.options = [
20
+ '-m', 'markdown',
21
+ '--hide-void-return',
22
+ '--quiet',
23
+ '--title', "Cinch #{Cinch::VERSION} Documentation",
24
+ '--main', 'README.md',
25
+ ]
38
26
  end
39
27
 
40
- desc "Uninstall gem"
41
- task :uninstall => [:clean] do
42
- sh "sudo gem uninstall #{NAME}"
28
+ namespace :gem do
29
+ desc "Build gem"
30
+ task :build => ["rake:clean"] do
31
+ sh("gem build cinch.gemspec")
32
+ end
33
+
34
+ desc "Uninstall gem (not root)"
35
+ task :uninstall do
36
+ sh("gem uninstall cinch -v #{Cinch::VERSION}")
37
+ end
38
+
39
+ desc "Release to rubygems"
40
+ task :release => [:build] do
41
+ sh("gem push ./cinch-#{Cinch::VERSION}.gem")
42
+ end
43
+
44
+ desc "Install gem (not root)"
45
+ task :install => :build do
46
+ sh("gem install ./cinch-#{Cinch::VERSION} --local")
47
+ end
43
48
  end
44
49
 
45
- desc "Upload gem to gemcutter"
46
- task :release => [:package] do
47
- sh "gem push ./#{NAME}-#{VERSION}.gem"
50
+ namespace :doc do
51
+ desc "Upload documentation"
52
+ task :push => [:yard] do
53
+ # XXX rename once merge is complete
54
+ sh("scp -r doc injekt:injekt.net/doc/cinch-merge")
55
+ end
48
56
  end
49
57
 
50
- desc "Run all specs"
51
- Spec::Rake::SpecTask.new(:spec) do |t|
52
- t.spec_files = Dir['spec/**/*_spec.rb']
58
+ task :version do
59
+ puts "Cinch version #{Cinch::VERSION}"
53
60
  end
54
61
 
55
- task :default => [:clean, :spec]
62
+ desc "Install gem (not root)"
63
+ task :install => "gem:install"
64
+
65
+ task :default => :spec
56
66
 
@@ -0,0 +1,32 @@
1
+ require 'cinch'
2
+
3
+ # Give this bot ops in a channel and it'll auto voice
4
+ # visitors
5
+ #
6
+ # Enable with !autovoice on
7
+ # Disable with !autovoice off
8
+
9
+ bot = Cinch::Bot.new do
10
+ configure do |c|
11
+ c.nick = "cinch_autovoice"
12
+ c.server = "irc.freenode.org"
13
+ c.verbose = true
14
+ c.channels = ["#cinch-bots"]
15
+
16
+ @autovoice = true
17
+ end
18
+
19
+ on :join do |m|
20
+ unless m.user.nick == bot.nick # We shouldn't attempt to voice ourselves
21
+ m.channel.voice(m.user) if @autovoice
22
+ end
23
+ end
24
+
25
+ on :channel, /^!autovoice (on|off)/ do |m, option|
26
+ @autovoice = option == "on"
27
+
28
+ m.reply "Autovoice is now #{@autovoice ? 'enabled' : 'disabled'}"
29
+ end
30
+ end
31
+
32
+ bot.start
@@ -0,0 +1,35 @@
1
+ require 'cinch'
2
+ require 'open-uri'
3
+ require 'nokogiri'
4
+ require 'cgi'
5
+
6
+ bot = Cinch::Bot.new do
7
+ configure do |c|
8
+ c.server = "irc.freenode.net"
9
+ c.nick = "MrCinch"
10
+ c.channels = ["#cinch-bots"]
11
+ end
12
+
13
+ helpers do
14
+ # Extremely basic method, grabs the first result returned by Google
15
+ # or "No results found" otherwise
16
+ def google(query)
17
+ url = "http://www.google.com/search?q=#{CGI.escape(query)}"
18
+ res = Nokogiri::HTML(open(url)).at("h3.r")
19
+
20
+ title = res.text
21
+ link = res.at('a')[:href]
22
+ desc = res.at("./following::div").children.first.text
23
+ rescue
24
+ "No results found"
25
+ else
26
+ CGI.unescape_html "#{title} - #{desc} (#{link})"
27
+ end
28
+ end
29
+
30
+ on :message, /^!google (.+)/ do |m, query|
31
+ m.reply google(query)
32
+ end
33
+ end
34
+
35
+ bot.start
@@ -0,0 +1,15 @@
1
+ require 'cinch'
2
+
3
+ bot = Cinch::Bot.new do
4
+ configure do |c|
5
+ c.server = "irc.freenode.org"
6
+ c.channels = ["#cinch-bots"]
7
+ end
8
+
9
+ on :message, "hello" do |m|
10
+ m.reply "Hello, #{m.user.nick}"
11
+ end
12
+ end
13
+
14
+ bot.start
15
+
@@ -0,0 +1,38 @@
1
+ require 'cinch'
2
+
3
+ bot = Cinch::Bot.new do
4
+ configure do |c|
5
+ c.server = "irc.freenode.org"
6
+ c.nick = "CinchBot"
7
+ c.channels = ["#cinch-bots"]
8
+
9
+ # Who should be able to access these plugins
10
+ @admin = "injekt"
11
+ end
12
+
13
+ on :connect do
14
+ bot.join "#cinch"
15
+ end
16
+
17
+ helpers do
18
+ def is_admin?(user)
19
+ true if user.nick == @admin
20
+ end
21
+ end
22
+
23
+ on :message, /^!join (.+)/ do |m, channel|
24
+ bot.join(channel) if is_admin?(m.user)
25
+ end
26
+
27
+ on :message, /^!part(?: (.+))?/ do |m, channel|
28
+ # Part current channel if none is given
29
+ channel = channel || m.channel
30
+
31
+ if channel
32
+ bot.part(channel) if is_admin?(m.user)
33
+ end
34
+ end
35
+ end
36
+
37
+ bot.start
38
+