cakewalk 3.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 (99) hide show
  1. checksums.yaml +7 -0
  2. data/.yardopts +1 -0
  3. data/LICENSE +22 -0
  4. data/README.md +169 -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/cakewalk/ban.rb +50 -0
  41. data/lib/cakewalk/bot.rb +479 -0
  42. data/lib/cakewalk/cached_list.rb +19 -0
  43. data/lib/cakewalk/callback.rb +20 -0
  44. data/lib/cakewalk/channel.rb +463 -0
  45. data/lib/cakewalk/channel_list.rb +29 -0
  46. data/lib/cakewalk/configuration/bot.rb +48 -0
  47. data/lib/cakewalk/configuration/dcc.rb +16 -0
  48. data/lib/cakewalk/configuration/plugins.rb +41 -0
  49. data/lib/cakewalk/configuration/sasl.rb +19 -0
  50. data/lib/cakewalk/configuration/ssl.rb +19 -0
  51. data/lib/cakewalk/configuration/timeouts.rb +14 -0
  52. data/lib/cakewalk/configuration.rb +73 -0
  53. data/lib/cakewalk/constants.rb +533 -0
  54. data/lib/cakewalk/dcc/dccable_object.rb +37 -0
  55. data/lib/cakewalk/dcc/incoming/send.rb +147 -0
  56. data/lib/cakewalk/dcc/incoming.rb +1 -0
  57. data/lib/cakewalk/dcc/outgoing/send.rb +122 -0
  58. data/lib/cakewalk/dcc/outgoing.rb +1 -0
  59. data/lib/cakewalk/dcc.rb +12 -0
  60. data/lib/cakewalk/exceptions.rb +46 -0
  61. data/lib/cakewalk/formatting.rb +125 -0
  62. data/lib/cakewalk/handler.rb +118 -0
  63. data/lib/cakewalk/handler_list.rb +90 -0
  64. data/lib/cakewalk/helpers.rb +231 -0
  65. data/lib/cakewalk/irc.rb +913 -0
  66. data/lib/cakewalk/isupport.rb +98 -0
  67. data/lib/cakewalk/log_filter.rb +21 -0
  68. data/lib/cakewalk/logger/formatted_logger.rb +97 -0
  69. data/lib/cakewalk/logger/zcbot_logger.rb +22 -0
  70. data/lib/cakewalk/logger.rb +168 -0
  71. data/lib/cakewalk/logger_list.rb +85 -0
  72. data/lib/cakewalk/mask.rb +69 -0
  73. data/lib/cakewalk/message.rb +391 -0
  74. data/lib/cakewalk/message_queue.rb +107 -0
  75. data/lib/cakewalk/mode_parser.rb +76 -0
  76. data/lib/cakewalk/network.rb +89 -0
  77. data/lib/cakewalk/open_ended_queue.rb +26 -0
  78. data/lib/cakewalk/pattern.rb +65 -0
  79. data/lib/cakewalk/plugin.rb +515 -0
  80. data/lib/cakewalk/plugin_list.rb +38 -0
  81. data/lib/cakewalk/rubyext/float.rb +3 -0
  82. data/lib/cakewalk/rubyext/module.rb +26 -0
  83. data/lib/cakewalk/rubyext/string.rb +33 -0
  84. data/lib/cakewalk/sasl/dh_blowfish.rb +71 -0
  85. data/lib/cakewalk/sasl/diffie_hellman.rb +47 -0
  86. data/lib/cakewalk/sasl/mechanism.rb +6 -0
  87. data/lib/cakewalk/sasl/plain.rb +26 -0
  88. data/lib/cakewalk/sasl.rb +34 -0
  89. data/lib/cakewalk/syncable.rb +83 -0
  90. data/lib/cakewalk/target.rb +199 -0
  91. data/lib/cakewalk/timer.rb +145 -0
  92. data/lib/cakewalk/user.rb +488 -0
  93. data/lib/cakewalk/user_list.rb +87 -0
  94. data/lib/cakewalk/utilities/deprecation.rb +16 -0
  95. data/lib/cakewalk/utilities/encoding.rb +37 -0
  96. data/lib/cakewalk/utilities/kernel.rb +13 -0
  97. data/lib/cakewalk/version.rb +4 -0
  98. data/lib/cakewalk.rb +5 -0
  99. metadata +140 -0
@@ -0,0 +1,36 @@
1
+ require 'cakewalk'
2
+ require 'open-uri'
3
+ require 'nokogiri'
4
+ require 'cgi'
5
+
6
+ class Google
7
+ include Cakewalk::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 = Cakewalk::Bot.new do
28
+ configure do |c|
29
+ c.server = "irc.libera.chat"
30
+ c.nick = "MrCakewalk"
31
+ c.channels = ["#cakewalk-bots"]
32
+ c.plugins.plugins = [Google]
33
+ end
34
+ end
35
+
36
+ bot.start
@@ -0,0 +1,22 @@
1
+ require 'cakewalk'
2
+
3
+ class Hello
4
+ include Cakewalk::Plugin
5
+
6
+ match "hello"
7
+
8
+ def execute(m)
9
+ m.reply "Hello, #{m.user.nick}"
10
+ end
11
+ end
12
+
13
+ bot = Cakewalk::Bot.new do
14
+ configure do |c|
15
+ c.server = "irc.libera.chat"
16
+ c.channels = ["#cakewalk-bots"]
17
+ c.plugins.plugins = [Hello]
18
+ end
19
+ end
20
+
21
+ bot.start
22
+
@@ -0,0 +1,36 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'cakewalk'
3
+
4
+ class HooksDemo
5
+ include Cakewalk::Plugin
6
+
7
+ hook :pre, method: :generate_random_number
8
+ def generate_random_number(m)
9
+ # Hooks are called in the same thread as the handler and thus
10
+ # using thread local variables is possible.
11
+ Thread.current[:rand] = Kernel.rand
12
+ end
13
+
14
+ hook :post, method: :cheer
15
+ def cheer(m)
16
+ m.reply "Yay, I successfully ran a command…"
17
+ end
18
+
19
+ match "rand"
20
+ def execute(m)
21
+ m.reply "Random number: " + Thread.current[:rand].to_s
22
+ end
23
+ end
24
+
25
+ bot = Cakewalk::Bot.new do
26
+ configure do |c|
27
+ c.nick = "cakewalk_hooks"
28
+ c.server = "irc.libera.chat"
29
+ c.channels = ["#cakewalk-bots"]
30
+ c.verbose = true
31
+ c.plugins.plugins = [HooksDemo]
32
+ end
33
+ end
34
+
35
+
36
+ bot.start
@@ -0,0 +1,42 @@
1
+ require 'cakewalk'
2
+
3
+ class JoinPart
4
+ include Cakewalk::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 = Cakewalk::Bot.new do
34
+ configure do |c|
35
+ c.server = "irc.libera.chat"
36
+ c.nick = "CakewalkBot"
37
+ c.channels = ["#cakewalk-bots"]
38
+ c.plugins.plugins = [JoinPart]
39
+ end
40
+ end
41
+
42
+ bot.start
@@ -0,0 +1,35 @@
1
+ require 'cakewalk'
2
+
3
+ class DirectAddressing
4
+ include Cakewalk::Plugin
5
+
6
+ # Note: the lambda will be executed in the context it has been
7
+ # defined in, in this case the class DirectAddressing (and not an
8
+ # instance of said class).
9
+ #
10
+ # The reason we are using a lambda is that the bot's nick can change
11
+ # and the prefix has to be up to date.
12
+ set :prefix, lambda{ |m| Regexp.new("^" + Regexp.escape(m.bot.nick + ": " ))}
13
+
14
+ match "hello", method: :greet
15
+ def greet(m)
16
+ m.reply "Hello to you, too."
17
+ end
18
+
19
+ match "rename", method: :rename
20
+ def rename(m)
21
+ @bot.nick += "_"
22
+ end
23
+ end
24
+
25
+ bot = Cakewalk::Bot.new do
26
+ configure do |c|
27
+ c.nick = "cakewalk_lambda"
28
+ c.server = "irc.libera.chat"
29
+ c.channels = ["#cakewalk-bots"]
30
+ c.verbose = true
31
+ c.plugins.plugins = [DirectAddressing]
32
+ end
33
+ end
34
+
35
+ bot.start
@@ -0,0 +1,24 @@
1
+ require 'cakewalk'
2
+
3
+ class Nickchange
4
+ include Cakewalk::Plugin
5
+ listen_to :nick
6
+
7
+ def listen(m)
8
+ # This will send a PM to the user who changed their nick and inform
9
+ # them of their old nick.
10
+ m.reply "Your old nick was: #{m.user.last_nick}" ,true
11
+ end
12
+ end
13
+
14
+ bot = Cakewalk::Bot.new do
15
+ configure do |c|
16
+ c.nick = "cakewalk_nickchange"
17
+ c.server = "irc.libera.chat"
18
+ c.channels = ["#cakewalk-bots"]
19
+ c.verbose = true
20
+ c.plugins.plugins = [Nickchange]
21
+ end
22
+ end
23
+
24
+ bot.start
@@ -0,0 +1,22 @@
1
+ require 'cakewalk'
2
+
3
+ class Messenger
4
+ include Cakewalk::Plugin
5
+
6
+ match /msg (.+?) (.+)/
7
+ def execute(m, receiver, message)
8
+ User(receiver).send(message)
9
+ end
10
+ end
11
+
12
+ bot = Cakewalk::Bot.new do
13
+ configure do |c|
14
+ c.server = "irc.libera.chat"
15
+ c.nick = "CakewalkBot"
16
+ c.channels = ["#cakewalk-bots"]
17
+ c.plugins.plugins = [Messenger]
18
+ end
19
+ end
20
+
21
+ bot.start
22
+
@@ -0,0 +1,32 @@
1
+ require 'cakewalk'
2
+
3
+ class MultiCommands
4
+ include Cakewalk::Plugin
5
+ match /command1 (.+)/, method: :command1
6
+ match /command2 (.+)/, method: :command2
7
+ match /^command3 (.+)/, use_prefix: false
8
+
9
+ def command1(m, arg)
10
+ m.reply "command1, arg: #{arg}"
11
+ end
12
+
13
+ def command2(m, arg)
14
+ m.reply "command2, arg: #{arg}"
15
+ end
16
+
17
+ def execute(m, arg)
18
+ m.reply "command3, arg: #{arg}"
19
+ end
20
+ end
21
+
22
+ bot = Cakewalk::Bot.new do
23
+ configure do |c|
24
+ c.nick = "cakewalk_multi"
25
+ c.server = "irc.libera.chat"
26
+ c.channels = ["#cakewalk-bots"]
27
+ c.verbose = true
28
+ c.plugins.plugins = [MultiCommands]
29
+ end
30
+ end
31
+
32
+ bot.start
@@ -0,0 +1,37 @@
1
+ require 'cakewalk'
2
+
3
+ class RandomNumberGenerator
4
+ def initialize(bot)
5
+ @bot = bot
6
+ end
7
+
8
+ def start
9
+ while true
10
+ sleep 5 # pretend that we are waiting for some kind of entropy
11
+ @bot.handlers.dispatch(:random_number, nil, Kernel.rand)
12
+ end
13
+ end
14
+ end
15
+
16
+ class DoSomethingRandom
17
+ include Cakewalk::Plugin
18
+
19
+ listen_to :random_number
20
+ def listen(m, number)
21
+ Channel("#cakewalk-bots").send "I got a random number: #{number}"
22
+ end
23
+ end
24
+
25
+ bot = Cakewalk::Bot.new do
26
+ configure do |c|
27
+ c.nick = "cakewalk_events"
28
+ c.server = "irc.libera.chat"
29
+ c.channels = ["#cakewalk-bots"]
30
+ c.verbose = true
31
+ c.plugins.plugins = [DoSomethingRandom]
32
+ end
33
+ end
34
+
35
+
36
+ Thread.new { RandomNumberGenerator.new(bot).start }
37
+ bot.start
@@ -0,0 +1,45 @@
1
+ require 'cakewalk'
2
+
3
+ class Seen
4
+ class SeenStruct < Struct.new(:who, :where, :what, :time)
5
+ def to_s
6
+ "[#{time.asctime}] #{who} was seen in #{where} saying #{what}"
7
+ end
8
+ end
9
+
10
+ include Cakewalk::Plugin
11
+ listen_to :channel
12
+ match /seen (.+)/
13
+
14
+ def initialize(*args)
15
+ super
16
+ @users = {}
17
+ end
18
+
19
+ def listen(m)
20
+ @users[m.user.nick] = SeenStruct.new(m.user, m.channel, m.message, Time.now)
21
+ end
22
+
23
+ def execute(m, nick)
24
+ if nick == @bot.nick
25
+ m.reply "That's me!"
26
+ elsif nick == m.user.nick
27
+ m.reply "That's you!"
28
+ elsif @users.key?(nick)
29
+ m.reply @users[nick].to_s
30
+ else
31
+ m.reply "I haven't seen #{nick}"
32
+ end
33
+ end
34
+ end
35
+
36
+ bot = Cakewalk::Bot.new do
37
+ configure do |c|
38
+ c.server = 'irc.libera.chat'
39
+ c.channels = ["#cakewalk-bots"]
40
+ c.plugins.plugins = [Seen]
41
+ end
42
+ end
43
+
44
+ bot.start
45
+
@@ -0,0 +1,22 @@
1
+ require 'cakewalk'
2
+
3
+ class TimedPlugin
4
+ include Cakewalk::Plugin
5
+
6
+ timer 5, method: :timed
7
+ def timed
8
+ Channel("#cakewalk-bots").send "5 seconds have passed"
9
+ end
10
+ end
11
+
12
+ bot = Cakewalk::Bot.new do
13
+ configure do |c|
14
+ c.nick = "cakewalk_timer"
15
+ c.server = "irc.libera.chat"
16
+ c.channels = ["#cakewalk-bots"]
17
+ c.verbose = true
18
+ c.plugins.plugins = [TimedPlugin]
19
+ end
20
+ end
21
+
22
+ bot.start
@@ -0,0 +1,33 @@
1
+ require 'open-uri'
2
+ require 'cakewalk'
3
+
4
+ class TinyURL
5
+ include Cakewalk::Plugin
6
+
7
+ listen_to :channel
8
+
9
+ def shorten(url)
10
+ url = open("http://tinyurl.com/api-create.php?url=#{URI.escape(url)}").read
11
+ url == "Error" ? nil : url
12
+ rescue OpenURI::HTTPError
13
+ nil
14
+ end
15
+
16
+ def listen(m)
17
+ urls = URI.extract(m.message, "http")
18
+ short_urls = urls.map { |url| shorten(url) }.compact
19
+ unless short_urls.empty?
20
+ m.reply short_urls.join(", ")
21
+ end
22
+ end
23
+ end
24
+
25
+ bot = Cakewalk::Bot.new do
26
+ configure do |c|
27
+ c.server = "irc.libera.chat"
28
+ c.channels = ["#cakewalk-bots"]
29
+ c.plugins.plugins = [TinyURL]
30
+ end
31
+ end
32
+
33
+ bot.start
@@ -0,0 +1,50 @@
1
+ require "cakewalk/mask"
2
+ module Cakewalk
3
+ # This class represents channel bans.
4
+ class Ban
5
+ # @return [Mask] A {Mask} object for non-extended bans
6
+ # @return [String] A String object for extended bans (see {#extended})
7
+ attr_reader :mask
8
+
9
+ # The user who created the ban. Might be nil on networks that do
10
+ # not strictly follow the RFCs, for example IRCnet in some(?)
11
+ # cases.
12
+ #
13
+ # @return [User, nil] The user who created the ban
14
+ attr_reader :by
15
+
16
+ # @return [Time]
17
+ attr_reader :created_at
18
+
19
+ # @return [Boolean] whether this is an extended ban (as used by for example Freenode)
20
+ attr_reader :extended
21
+
22
+ # @param [String, Mask] mask The mask
23
+ # @param [User, nil] by The user who created the ban.
24
+ # @param [Time] at The time at which the ban was created
25
+ def initialize(mask, by, at)
26
+ @by, @created_at = by, at
27
+ if mask =~ /^[\$~]/
28
+ @extended = true
29
+ @mask = mask
30
+ else
31
+ @extended = false
32
+ @mask = Mask.from(mask)
33
+ end
34
+ end
35
+
36
+ # @return [Boolean] true if the ban matches `user`
37
+ # @raise [Exceptions::UnsupportedFeature] Cakewalk does not support
38
+ # Freenode's extended bans
39
+ def match(user)
40
+ raise UnsupportedFeature, "extended bans are not supported yet" if @extended
41
+ @mask =~ user
42
+ end
43
+ alias_method :=~, :match
44
+
45
+ # @return [String]
46
+ def to_s
47
+ @mask.to_s
48
+ end
49
+ end
50
+ end