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
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'cinch'
4
+
5
+ class Memo < Struct.new(:nick, :channel, :text, :time)
6
+ def to_s
7
+ "[#{time.asctime}] <#{channel}/#{nick}> #{text}"
8
+ end
9
+ end
10
+
11
+ bot = Cinch::Bot.new do
12
+ configure do |c|
13
+ c.server = "irc.freenode.org"
14
+ c.channels = ["#cinch-bots"]
15
+
16
+ @memos = {}
17
+ end
18
+
19
+ on :message do |m|
20
+ if @memos.has_key?(m.user.nick)
21
+ m.user.send @memos.delete(m.user.nick).to_s
22
+ end
23
+ end
24
+
25
+ on :message, /^!memo (.+?) (.+)/ do |m, nick, message|
26
+ if @memos.key?(nick)
27
+ m.reply "There's already a memo for #{nick}. You can only store one right now"
28
+ elsif nick == m.user.nick
29
+ m.reply "You can't leave memos for yourself.."
30
+ elsif nick == bot.nick
31
+ m.reply "You can't leave memos for me.."
32
+ else
33
+ @memos[nick] = Memo.new(m.user.nick, m.channel, message, Time.now)
34
+ m.reply "Added memo for #{nick}"
35
+ end
36
+ end
37
+ end
38
+
39
+ bot.start
@@ -0,0 +1,16 @@
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
+ end
9
+
10
+ on :message, /^!msg (.+?) (.+)/ do |m, who, text|
11
+ User(who).send text
12
+ end
13
+ end
14
+
15
+ bot.start
16
+
@@ -0,0 +1,36 @@
1
+ require 'cinch'
2
+
3
+ class Seen < Struct.new(:who, :where, :what, :time)
4
+ def to_s
5
+ "[#{time.asctime}] #{who} was seen in #{where} saying #{what}"
6
+ end
7
+ end
8
+
9
+ bot = Cinch::Bot.new do
10
+ configure do |c|
11
+ c.server = 'irc.freenode.org'
12
+ c.channels = ["#cinch-bots"]
13
+
14
+ @users = {}
15
+ end
16
+
17
+ # Only log channel messages
18
+ on :channel do |m|
19
+ @users[m.user.nick] = Seen.new(m.user.nick, m.channel, m.message, Time.new)
20
+ end
21
+
22
+ on :channel, /^!seen (.+)/ do |m, nick|
23
+ if nick == bot.nick
24
+ m.reply "That's me!"
25
+ elsif nick == m.user.nick
26
+ m.reply "That's you!"
27
+ elsif @users.key?(nick)
28
+ m.reply @users[nick].to_s
29
+ else
30
+ m.reply "I haven't seen #{nick}"
31
+ end
32
+ end
33
+ end
34
+
35
+ bot.start
36
+
@@ -0,0 +1,35 @@
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::Bot.new do
10
+ configure do |c|
11
+ c.server = "irc.freenode.net"
12
+ c.nick = "MrCinch"
13
+ c.channels = ["#cinch-bots"]
14
+ end
15
+
16
+ helpers do
17
+ # This method assumes everything will go ok, it's not the best method
18
+ # of doing this *by far* and is simply a helper method to show how it
19
+ # can be done.. it works!
20
+ def urban_dict(query)
21
+ url = "http://www.urbandictionary.com/define.php?term=#{CGI.escape(query)}"
22
+ CGI.unescape_html Nokogiri::HTML(open(url)).at("div.definition").text.gsub(/\s+/, ' ') rescue nil
23
+ end
24
+ end
25
+
26
+ on :message, /^!urban (.+)/ do |m, term|
27
+ m.reply(urban_dict(term) || "No results found", true)
28
+ end
29
+ end
30
+
31
+ bot.start
32
+
33
+ # injekt> !urban cinch
34
+ # MrCinch> injekt: describing an action that's extremely easy.
35
+
@@ -0,0 +1,35 @@
1
+ require 'open-uri'
2
+ require 'cinch'
3
+
4
+ # Automatically shorten URL's found in messages
5
+ # Using the tinyURL API
6
+
7
+ bot = Cinch::Bot.new do
8
+ configure do |c|
9
+ c.server = "irc.freenode.org"
10
+ c.channels = ["#cinch-bots"]
11
+ end
12
+
13
+ helpers do
14
+ def shorten(url)
15
+ url = open("http://tinyurl.com/api-create.php?url=#{URI.escape(url)}").read
16
+ url == "Error" ? nil : url
17
+ rescue OpenURI::HTTPError
18
+ nil
19
+ end
20
+ end
21
+
22
+ on :channel do |m|
23
+ urls = URI.extract(m.message, "http")
24
+
25
+ unless urls.empty?
26
+ short_urls = urls.map {|url| shorten(url) }.compact
27
+
28
+ unless short_urls.empty?
29
+ m.reply short_urls.join(", ")
30
+ end
31
+ end
32
+ end
33
+ end
34
+
35
+ bot.start
@@ -0,0 +1,40 @@
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
+ class Autovoice
10
+ include Cinch::Plugin
11
+ listen_to :join
12
+ match /autovoice (on|off)/
13
+
14
+ def listen(m)
15
+ unless m.user.nick == bot.nick
16
+ m.channel.voice(m.user) if @autovoice
17
+ end
18
+ end
19
+
20
+ def execute(m, option)
21
+ @autovoice = option == "on"
22
+
23
+ m.reply "Autovoice is now #{@autovoice ? 'enabled' : 'disabled'}"
24
+ end
25
+ end
26
+
27
+ bot = Cinch::Bot.new do
28
+ configure do |c|
29
+ c.nick = "cinch_autovoice"
30
+ c.server = "irc.freenode.org"
31
+ c.verbose = true
32
+ c.plugins.plugins = [Autovoice]
33
+ end
34
+
35
+ on :connect do
36
+ bot.join "#cinch"
37
+ end
38
+ end
39
+
40
+ bot.start
@@ -0,0 +1,23 @@
1
+ require 'cinch'
2
+
3
+ class SomeCommand
4
+ include Cinch::Plugin
5
+
6
+ prefix "~"
7
+ match "somecommand"
8
+
9
+ def execute(m)
10
+ m.reply "Successful"
11
+ end
12
+ end
13
+
14
+ bot = Cinch::Bot.new do
15
+ configure do |c|
16
+ c.server = "irc.freenode.org"
17
+ c.channels = ["#cinch-bots"]
18
+ c.plugins.plugins = [SomeCommand]
19
+ end
20
+ end
21
+
22
+ bot.start
23
+
@@ -0,0 +1,37 @@
1
+ require 'cinch'
2
+ require 'open-uri'
3
+ require 'nokogiri'
4
+ require 'cgi'
5
+
6
+ class Google
7
+ include Cinch::Plugin
8
+ match /google (.+)/
9
+
10
+ def search(query)
11
+ url = "http://www.google.com/search?q=#{CGI.escape(query)}"
12
+ res = Nokogiri::HTML(open(url)).at("h3.r")
13
+
14
+ title = res.text
15
+ link = res.at('a')[:href]
16
+ desc = res.at("./following::div").children.first.text
17
+ rescue
18
+ "No results found"
19
+ else
20
+ CGI.unescape_html "#{title} - #{desc} (#{link})"
21
+ end
22
+
23
+ def execute(m, query)
24
+ m.reply(search(query))
25
+ end
26
+ end
27
+
28
+ bot = Cinch::Bot.new do
29
+ configure do |c|
30
+ c.server = "irc.freenode.net"
31
+ c.nick = "MrCinch"
32
+ c.channels = ["#cinch-bots"]
33
+ c.plugins.plugins = [Google]
34
+ end
35
+ end
36
+
37
+ bot.start
@@ -0,0 +1,22 @@
1
+ require 'cinch'
2
+
3
+ class Hello
4
+ include Cinch::Plugin
5
+
6
+ match "hello"
7
+
8
+ def execute(m)
9
+ m.reply "Hello, #{m.user.nick}"
10
+ end
11
+ end
12
+
13
+ bot = Cinch::Bot.new do
14
+ configure do |c|
15
+ c.server = "irc.freenode.org"
16
+ c.channels = ["#cinch-bots"]
17
+ c.plugins.plugins = [Hello]
18
+ end
19
+ end
20
+
21
+ bot.start
22
+
@@ -0,0 +1,42 @@
1
+ require 'cinch'
2
+
3
+ class JoinPart
4
+ include Cinch::Plugin
5
+
6
+ match /join (.+)/, method: :join
7
+ match /part(?: (.+))?/, method: :part
8
+
9
+ def initialize(*args)
10
+ super
11
+
12
+ @admins = ["injekt", "DominikH"]
13
+ end
14
+
15
+ def check_user(user)
16
+ user.refresh # be sure to refresh the data, or someone could steal
17
+ # the nick
18
+ @admins.include?(user.authname)
19
+ end
20
+
21
+ def join(m, channel)
22
+ return unless check_user(m.user)
23
+ Channel(channel).join
24
+ end
25
+
26
+ def part(m, channel)
27
+ return unless check_user(m.user)
28
+ channel ||= m.channel
29
+ Channel(channel).part if channel
30
+ end
31
+ end
32
+
33
+ bot = Cinch::Bot.new do
34
+ configure do |c|
35
+ c.server = "irc.freenode.org"
36
+ c.nick = "CinchBot"
37
+ c.channels = ["#cinch-bots"]
38
+ c.plugins.plugins = [JoinPart]
39
+ end
40
+ end
41
+
42
+ bot.start
@@ -0,0 +1,50 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'cinch'
4
+
5
+ class Memo
6
+ class MemoStruct < Struct.new(:nick, :channel, :text, :time)
7
+ def to_s
8
+ "[#{time.asctime}] <#{channel}/#{nick}> #{text}"
9
+ end
10
+ end
11
+
12
+ include Cinch::Plugin
13
+
14
+ listen_to :message
15
+ match /memo (.+?) (.+)/
16
+
17
+ def initialize(*args)
18
+ super
19
+ @memos = {}
20
+ end
21
+
22
+ def listen(m)
23
+ if @memos.has_key?(m.user.nick)
24
+ m.user.send @memos.delete(m.user.nick).to_s
25
+ end
26
+ end
27
+
28
+ def execute(m, nick, message)
29
+ if @memos.key?(nick)
30
+ m.reply "There's already a memo for #{nick}. You can only store one right now"
31
+ elsif nick == m.user.nick
32
+ m.reply "You can't leave memos for yourself.."
33
+ elsif nick == bot.nick
34
+ m.reply "You can't leave memos for me.."
35
+ else
36
+ @memos[nick] = MemoStruct.new(m.user.nick, m.channel, message, Time.now)
37
+ m.reply "Added memo for #{nick}"
38
+ end
39
+ end
40
+ end
41
+
42
+ bot = Cinch::Bot.new do
43
+ configure do |c|
44
+ c.server = "irc.freenode.org"
45
+ c.channels = ["#cinch-bots"]
46
+ c.plugins.plugins = [Memo]
47
+ end
48
+ end
49
+
50
+ bot.start
@@ -0,0 +1,22 @@
1
+ require 'cinch'
2
+
3
+ class Messenger
4
+ include Cinch::Plugin
5
+
6
+ match /msg (.+?) (.+)/
7
+ def execute(m, receiver, message)
8
+ User(receiver).send(message)
9
+ end
10
+ end
11
+
12
+ bot = Cinch::Bot.new do
13
+ configure do |c|
14
+ c.server = "irc.freenode.org"
15
+ c.nick = "CinchBot"
16
+ c.channels = ["#cinch-bots"]
17
+ c.plugins.plugins = [Messenger]
18
+ end
19
+ end
20
+
21
+ bot.start
22
+
@@ -0,0 +1,41 @@
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
+ class MultiCommands
10
+ include Cinch::Plugin
11
+ match /command1 (.+)/, method: :command1
12
+ match /command2 (.+)/, method: :command2
13
+ match /^command3 (.+)/, use_prefix: false
14
+
15
+ def command1(m, arg)
16
+ m.reply "command1, arg: #{arg}"
17
+ end
18
+
19
+ def command2(m, arg)
20
+ m.reply "command2, arg: #{arg}"
21
+ end
22
+
23
+ def execute(m, arg)
24
+ m.reply "command3, arg: #{arg}"
25
+ end
26
+ end
27
+
28
+ bot = Cinch::Bot.new do
29
+ configure do |c|
30
+ c.nick = "cinch_multi"
31
+ c.server = "irc.freenode.org"
32
+ c.verbose = true
33
+ c.plugins.plugins = [MultiCommands]
34
+ end
35
+
36
+ on :connect do
37
+ bot.join "#dominikh"
38
+ end
39
+ end
40
+
41
+ bot.start