grinch 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (99) hide show
  1. checksums.yaml +7 -0
  2. data/.yardopts +1 -0
  3. data/LICENSE +22 -0
  4. data/README.md +180 -0
  5. data/docs/bot_options.md +454 -0
  6. data/docs/changes.md +541 -0
  7. data/docs/common_mistakes.md +60 -0
  8. data/docs/common_tasks.md +57 -0
  9. data/docs/encodings.md +69 -0
  10. data/docs/events.md +273 -0
  11. data/docs/getting_started.md +184 -0
  12. data/docs/logging.md +90 -0
  13. data/docs/migrating.md +267 -0
  14. data/docs/plugins.md +4 -0
  15. data/docs/readme.md +20 -0
  16. data/examples/basic/autovoice.rb +32 -0
  17. data/examples/basic/google.rb +35 -0
  18. data/examples/basic/hello.rb +15 -0
  19. data/examples/basic/join_part.rb +34 -0
  20. data/examples/basic/memo.rb +39 -0
  21. data/examples/basic/msg.rb +16 -0
  22. data/examples/basic/seen.rb +36 -0
  23. data/examples/basic/urban_dict.rb +35 -0
  24. data/examples/basic/url_shorten.rb +35 -0
  25. data/examples/plugins/autovoice.rb +37 -0
  26. data/examples/plugins/custom_prefix.rb +23 -0
  27. data/examples/plugins/dice_roll.rb +38 -0
  28. data/examples/plugins/google.rb +36 -0
  29. data/examples/plugins/hello.rb +22 -0
  30. data/examples/plugins/hooks.rb +36 -0
  31. data/examples/plugins/join_part.rb +42 -0
  32. data/examples/plugins/lambdas.rb +35 -0
  33. data/examples/plugins/last_nick.rb +24 -0
  34. data/examples/plugins/msg.rb +22 -0
  35. data/examples/plugins/multiple_matches.rb +32 -0
  36. data/examples/plugins/own_events.rb +37 -0
  37. data/examples/plugins/seen.rb +45 -0
  38. data/examples/plugins/timer.rb +22 -0
  39. data/examples/plugins/url_shorten.rb +33 -0
  40. data/lib/cinch.rb +5 -0
  41. data/lib/cinch/ban.rb +50 -0
  42. data/lib/cinch/bot.rb +479 -0
  43. data/lib/cinch/cached_list.rb +19 -0
  44. data/lib/cinch/callback.rb +20 -0
  45. data/lib/cinch/channel.rb +463 -0
  46. data/lib/cinch/channel_list.rb +29 -0
  47. data/lib/cinch/configuration.rb +73 -0
  48. data/lib/cinch/configuration/bot.rb +48 -0
  49. data/lib/cinch/configuration/dcc.rb +16 -0
  50. data/lib/cinch/configuration/plugins.rb +41 -0
  51. data/lib/cinch/configuration/sasl.rb +19 -0
  52. data/lib/cinch/configuration/ssl.rb +19 -0
  53. data/lib/cinch/configuration/timeouts.rb +14 -0
  54. data/lib/cinch/constants.rb +533 -0
  55. data/lib/cinch/dcc.rb +12 -0
  56. data/lib/cinch/dcc/dccable_object.rb +37 -0
  57. data/lib/cinch/dcc/incoming.rb +1 -0
  58. data/lib/cinch/dcc/incoming/send.rb +147 -0
  59. data/lib/cinch/dcc/outgoing.rb +1 -0
  60. data/lib/cinch/dcc/outgoing/send.rb +122 -0
  61. data/lib/cinch/exceptions.rb +46 -0
  62. data/lib/cinch/formatting.rb +125 -0
  63. data/lib/cinch/handler.rb +118 -0
  64. data/lib/cinch/handler_list.rb +90 -0
  65. data/lib/cinch/helpers.rb +231 -0
  66. data/lib/cinch/irc.rb +924 -0
  67. data/lib/cinch/isupport.rb +98 -0
  68. data/lib/cinch/log_filter.rb +21 -0
  69. data/lib/cinch/logger.rb +168 -0
  70. data/lib/cinch/logger/formatted_logger.rb +97 -0
  71. data/lib/cinch/logger/zcbot_logger.rb +22 -0
  72. data/lib/cinch/logger_list.rb +85 -0
  73. data/lib/cinch/mask.rb +69 -0
  74. data/lib/cinch/message.rb +392 -0
  75. data/lib/cinch/message_queue.rb +107 -0
  76. data/lib/cinch/mode_parser.rb +76 -0
  77. data/lib/cinch/network.rb +104 -0
  78. data/lib/cinch/open_ended_queue.rb +26 -0
  79. data/lib/cinch/pattern.rb +65 -0
  80. data/lib/cinch/plugin.rb +515 -0
  81. data/lib/cinch/plugin_list.rb +38 -0
  82. data/lib/cinch/rubyext/float.rb +3 -0
  83. data/lib/cinch/rubyext/module.rb +26 -0
  84. data/lib/cinch/rubyext/string.rb +33 -0
  85. data/lib/cinch/sasl.rb +34 -0
  86. data/lib/cinch/sasl/dh_blowfish.rb +71 -0
  87. data/lib/cinch/sasl/diffie_hellman.rb +47 -0
  88. data/lib/cinch/sasl/mechanism.rb +6 -0
  89. data/lib/cinch/sasl/plain.rb +26 -0
  90. data/lib/cinch/syncable.rb +83 -0
  91. data/lib/cinch/target.rb +199 -0
  92. data/lib/cinch/timer.rb +145 -0
  93. data/lib/cinch/user.rb +488 -0
  94. data/lib/cinch/user_list.rb +87 -0
  95. data/lib/cinch/utilities/deprecation.rb +16 -0
  96. data/lib/cinch/utilities/encoding.rb +37 -0
  97. data/lib/cinch/utilities/kernel.rb +13 -0
  98. data/lib/cinch/version.rb +4 -0
  99. metadata +140 -0
data/docs/plugins.md ADDED
@@ -0,0 +1,4 @@
1
+ # @title Plugins
2
+ # @markup kramdown
3
+
4
+ Content will follow soon…
data/docs/readme.md ADDED
@@ -0,0 +1,20 @@
1
+ # @title README
2
+ # @markup kramdown
3
+
4
+
5
+ - {file:docs/changes.md Changelog}
6
+ - {file:docs/migrating.md Migration guides}
7
+
8
+ # Important documents
9
+
10
+ The following is a list of important documents to read.
11
+
12
+ - {file:docs/bot_options.md Bot options}
13
+ - {file:docs/common_tasks.md Common Tasks}
14
+ - {file:docs/common_mistakes.md Common mistakes}
15
+ - {Cinch::DCC DCC}
16
+ - {file:docs/encodings.md Encodings}
17
+ - {file:docs/logging.md Logging}
18
+ - {Cinch::SASL SASL}
19
+ - {Cinch::Formatting Formatting messages}
20
+ - {file:docs/events.md Events}
@@ -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
+ # It starts out disabled.
10
+
11
+ bot = Cinch::Bot.new do
12
+ configure do |c|
13
+ c.nick = "cinch_autovoice"
14
+ c.server = "irc.freenode.org"
15
+ c.verbose = true
16
+ c.channels = ["#cinch-bots"]
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.parse(open(url).read).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,34 @@
1
+ require 'cinch'
2
+
3
+ # Who should be able to access these plugins
4
+ $admin = "injekt"
5
+
6
+ bot = Cinch::Bot.new do
7
+ configure do |c|
8
+ c.server = "irc.freenode.org"
9
+ c.nick = "CinchBot"
10
+ c.channels = ["#cinch-bots"]
11
+ end
12
+
13
+ helpers do
14
+ def is_admin?(user)
15
+ true if user.nick == $admin
16
+ end
17
+ end
18
+
19
+ on :message, /^!join (.+)/ do |m, channel|
20
+ bot.join(channel) if is_admin?(m.user)
21
+ end
22
+
23
+ on :message, /^!part(?: (.+))?/ do |m, channel|
24
+ # Part current channel if none is given
25
+ channel = channel || m.channel
26
+
27
+ if channel
28
+ bot.part(channel) if is_admin?(m.user)
29
+ end
30
+ end
31
+ end
32
+
33
+ bot.start
34
+
@@ -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
+ $memos = {}
12
+
13
+ bot = Cinch::Bot.new do
14
+ configure do |c|
15
+ c.server = "irc.freenode.org"
16
+ c.channels = ["#cinch-bots"]
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
+ $users = {}
10
+
11
+ bot = Cinch::Bot.new do
12
+ configure do |c|
13
+ c.server = 'irc.freenode.org'
14
+ c.channels = ["#cinch-bots"]
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)).css("div.meaning").first.text.gsub(/\s+/, ' ').strip 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,37 @@
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.channels = ["#cinch-bots"]
32
+ c.verbose = true
33
+ c.plugins.plugins = [Autovoice]
34
+ end
35
+ end
36
+
37
+ bot.start
@@ -0,0 +1,23 @@
1
+ require 'cinch'
2
+
3
+ class SomeCommand
4
+ include Cinch::Plugin
5
+
6
+ set :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,38 @@
1
+ require 'cinch'
2
+
3
+ class DiceRoll
4
+ include Cinch::Plugin
5
+
6
+ # [[<repeats>#]<rolls>]d<sides>[<+/-><offset>]
7
+ match(/roll (?:(?:(\d+)#)?(\d+))?d(\d+)(?:([+-])(\d+))?/)
8
+ def execute(m, repeats, rolls, sides, offset_op, offset)
9
+ repeats = repeats.to_i
10
+ repeats = 1 if repeats < 1
11
+ rolls = rolls.to_i
12
+ rolls = 1 if rolls < 1
13
+
14
+ total = 0
15
+
16
+ repeats.times do
17
+ rolls.times do
18
+ score = rand(sides.to_i) + 1
19
+ if offset_op
20
+ score = score.send(offset_op, offset.to_i)
21
+ end
22
+ total += score
23
+ end
24
+ end
25
+
26
+ m.reply "Your dice roll was: #{total}", true
27
+ end
28
+ end
29
+
30
+ bot = Cinch::Bot.new do
31
+ configure do |c|
32
+ c.server = 'irc.freenode.org'
33
+ c.channels = ['#cinch-bots']
34
+ c.plugins.plugins = [DiceRoll]
35
+ end
36
+ end
37
+
38
+ bot.start
@@ -0,0 +1,36 @@
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.parse(open(url).read).at("h3.r")
13
+
14
+ title = res.text
15
+ link = res.at('a')[:href]
16
+ desc = res.at("./following::div").children.first.text
17
+ CGI.unescape_html "#{title} - #{desc} (#{link})"
18
+ rescue
19
+ "No results found"
20
+ end
21
+
22
+ def execute(m, query)
23
+ m.reply(search(query))
24
+ end
25
+ end
26
+
27
+ bot = Cinch::Bot.new do
28
+ configure do |c|
29
+ c.server = "irc.freenode.net"
30
+ c.nick = "MrCinch"
31
+ c.channels = ["#cinch-bots"]
32
+ c.plugins.plugins = [Google]
33
+ end
34
+ end
35
+
36
+ bot.start