cinch 0.3.5 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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
+