balotelli 0.1.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.
- checksums.yaml +7 -0
- data/.codeclimate.yml +4 -0
- data/.gitignore +4 -0
- data/.travis.yml +7 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +13 -0
- data/README.md +1 -0
- data/Rakefile +7 -0
- data/balotelli.gemspec +24 -0
- data/lib/balotelli/balotelli_helper.rb +15 -0
- data/lib/balotelli/base.rb +155 -0
- data/lib/balotelli/config.rb +15 -0
- data/lib/balotelli/core/irc.rb +62 -0
- data/lib/balotelli/core/irc_logger.rb +94 -0
- data/lib/balotelli/core/join.rb +13 -0
- data/lib/balotelli/core/kick.rb +19 -0
- data/lib/balotelli/core/priv_msg.rb +18 -0
- data/lib/balotelli/core/router.rb +48 -0
- data/lib/balotelli/core/utils.rb +19 -0
- data/lib/balotelli/module/base.rb +27 -0
- data/lib/balotelli/version.rb +3 -0
- data/lib/balotelli.rb +6 -0
- data/test/lib/balotelli/balotelli_helper_test.rb +21 -0
- data/test/lib/balotelli/base_test.rb +60 -0
- data/test/lib/balotelli/config_test.rb +12 -0
- data/test/lib/balotelli/core/irc_test.rb +26 -0
- data/test/lib/balotelli/core/router_test.rb +32 -0
- data/test/test_helper.rb +11 -0
- metadata +119 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 027c995c67a45827bb5fb5731af28403436b9f5e
|
4
|
+
data.tar.gz: 53c56b031e08f5ce6c2dbd263483b7abc69b5878
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 4e351562adaa6329654db9a343873a0ec729681c798139bfe3bf85eec150986fcc4444103efe71099159b62c01690195dde6477a78bf25bed5332909df6406d0
|
7
|
+
data.tar.gz: 748bc1811d9fee418dd31c965e4180bed4d0da28dfd1df7c986fc8adc0529d91697f0802021c675cb74820409f45b73911bea3f0152162943bbf69119653a4a0
|
data/.codeclimate.yml
ADDED
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
data/README.md
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
# Balotelli [](https://travis-ci.org/mhib/balotelli)
|
data/Rakefile
ADDED
data/balotelli.gemspec
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
lib = File.expand_path('../lib', __FILE__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
require 'balotelli/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "balotelli"
|
7
|
+
spec.version = Balotelli::VERSION
|
8
|
+
spec.authors = ["Marcin Henryk Bartkowiak"]
|
9
|
+
spec.email = ["mhbartkowiak@gmail.com"]
|
10
|
+
spec.summary = "Simple IRC bot framework"
|
11
|
+
spec.description = ""
|
12
|
+
spec.homepage = "https://github.com/mhib/balotelli"
|
13
|
+
spec.license = "MIT"
|
14
|
+
|
15
|
+
spec.files = `git ls-files -z`.split("\x0")
|
16
|
+
spec.files.reject! { |file| file.include? 'examples/' }
|
17
|
+
#spec.executables = ['path']
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler"
|
22
|
+
spec.add_development_dependency "rake", '~> 10.4.2'
|
23
|
+
spec.add_development_dependency "minitest", '~> 5.8.0'
|
24
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'balotelli/base'
|
2
|
+
|
3
|
+
def Balotelli(server, name, pass, channels, log = false)
|
4
|
+
Class.new(Balotelli::Base) do
|
5
|
+
Balotelli::Module.constants.each do |c|
|
6
|
+
if c != :Base && (m = Balotelli::Module.const_get(c)).is_a?(Module)
|
7
|
+
register(m)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
include Balotelli::Core::IrcLogger.new('.', 'logs.log', channels) if log
|
11
|
+
end.tap do |c|
|
12
|
+
c.configure(*Balotelli::Config.build(server, name, pass))
|
13
|
+
c.connect { channels.each(&method(:join)) }
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,155 @@
|
|
1
|
+
require 'balotelli/core/irc'
|
2
|
+
require 'balotelli/core/router'
|
3
|
+
require 'balotelli/core/priv_msg'
|
4
|
+
require 'balotelli/core/join'
|
5
|
+
require 'balotelli/core/kick'
|
6
|
+
require 'balotelli/core/irc_logger'
|
7
|
+
require 'balotelli/core/utils'
|
8
|
+
require 'balotelli/config'
|
9
|
+
|
10
|
+
module Balotelli
|
11
|
+
class Base
|
12
|
+
def initialize(str, route, block, message, command)
|
13
|
+
@str = str
|
14
|
+
@message = message
|
15
|
+
@block = block
|
16
|
+
@route = route
|
17
|
+
@command = command
|
18
|
+
@matchdata = @command.match(@route)
|
19
|
+
end
|
20
|
+
|
21
|
+
def execute
|
22
|
+
instance_exec(@message, @matchdata, &@block)
|
23
|
+
end
|
24
|
+
private :execute
|
25
|
+
|
26
|
+
def out(message_string, destination = nil)
|
27
|
+
self.class.privmsg((destination || @message.responder), message_string)
|
28
|
+
end
|
29
|
+
|
30
|
+
def kick(params)
|
31
|
+
Core::Kick.new(params, self.class).execute!
|
32
|
+
end
|
33
|
+
|
34
|
+
def get_user_list(channel)
|
35
|
+
self.class.instance_variable_set(:@to_process, :user_list)
|
36
|
+
self.class.names(channel)
|
37
|
+
sleep 0.05 while __TO_PROCESS__
|
38
|
+
__CACHE__[:user_list][channel]
|
39
|
+
end
|
40
|
+
|
41
|
+
def method_missing(method, *args, **params, &block)
|
42
|
+
if method =~ /__([[[:upper:]]_]+)__/
|
43
|
+
self.class.instance_variable_get("@#{$1}".downcase)
|
44
|
+
else
|
45
|
+
super
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
class << self
|
50
|
+
include Balotelli::Core::IRC
|
51
|
+
include Balotelli::Core::Router
|
52
|
+
|
53
|
+
def setup
|
54
|
+
setup_router
|
55
|
+
|
56
|
+
@modules = {}
|
57
|
+
@cache = Hash.new { |hash, key| hash[key] = {} }
|
58
|
+
end
|
59
|
+
|
60
|
+
def inherited(subclass)
|
61
|
+
super
|
62
|
+
|
63
|
+
subclass.setup
|
64
|
+
end
|
65
|
+
|
66
|
+
def register(mod, namespace = nil)
|
67
|
+
if namespace
|
68
|
+
mod.instance_variable_set(:@commands_namespace, namespace.intern)
|
69
|
+
mod.instance_exec(namespace) do |n|
|
70
|
+
define_method(:commands_namespace) { n.intern }
|
71
|
+
end
|
72
|
+
end
|
73
|
+
@modules[mod.commands_namespace] ||= mod
|
74
|
+
@cache[:modules] = Hash[@modules.map { |k, v| [k.to_s, v] }]
|
75
|
+
end
|
76
|
+
|
77
|
+
def register_special(mod)
|
78
|
+
@routes.merge!(mod.instance_variable_get(:@routes))
|
79
|
+
end
|
80
|
+
|
81
|
+
def mod_match(str, priv = false)
|
82
|
+
if str =~ /\A[^a-zA-Z0-9\s]?(\S+) ?(.*)/
|
83
|
+
if (mod = @cache[:modules][$1.downcase])
|
84
|
+
mod.match($2, priv)
|
85
|
+
end
|
86
|
+
elsif str == :join
|
87
|
+
match = nil
|
88
|
+
@modules.each do |_, m|
|
89
|
+
if (match = m.match(:join))
|
90
|
+
break(match)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
match
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def run
|
98
|
+
@to_process = false
|
99
|
+
while (str = sgets)
|
100
|
+
process(str)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
private
|
105
|
+
|
106
|
+
def process(str)
|
107
|
+
if str =~ /\APING (.*)\z/
|
108
|
+
pong $1
|
109
|
+
elsif @on_connect && str =~ /End of \/MOTD command/i
|
110
|
+
instance_eval(&remove_instance_variable(:@on_connect))
|
111
|
+
elsif !(str =~ /(JOIN\s|PRIVMSG\s)/)
|
112
|
+
process_table(str)
|
113
|
+
else
|
114
|
+
Thread.new { process_message(str) }
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def process_message(str)
|
119
|
+
if str =~ Core::Utils::PRIV_MSG_REGEX
|
120
|
+
metadata = { user: $1, channel: $2, message: $3 }
|
121
|
+
priv = !($2 =~ /#.+/)
|
122
|
+
if (match = match(metadata[:message], priv)) ||
|
123
|
+
(match = mod_match(metadata[:message], priv))
|
124
|
+
new_response(str, match, metadata, Core::PrivMsg, priv)
|
125
|
+
end
|
126
|
+
elsif str =~ Core::Utils::JOIN_REGEX
|
127
|
+
metadata = { user: $1, channel: $2 }
|
128
|
+
if (match = match(:join)) || (match = mod_match(:join))
|
129
|
+
new_response(str, match, metadata, Core::Join)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
def new_response(str, match, metadata, klass, priv = nil)
|
135
|
+
route, block, mod, command = match.flatten
|
136
|
+
responder = klass.new(*[metadata, priv].compact)
|
137
|
+
new(str, route, block, responder, command).tap do |response|
|
138
|
+
response.extend(mod) if mod.class.to_s == 'Module'
|
139
|
+
end.send(:execute)
|
140
|
+
end
|
141
|
+
|
142
|
+
def process_table(string)
|
143
|
+
if @to_process && string =~ (regex = Core::Utils.table_regex(@nick))
|
144
|
+
metadata = { channel: $2, message: $3 }
|
145
|
+
users = @cache[@to_process][metadata[:channel]] = metadata[:message]
|
146
|
+
until (str = sgets) =~ /End of \/NAME/i
|
147
|
+
users << " #{str.match(regex).captures.first}"
|
148
|
+
end
|
149
|
+
@cache[@to_process][metadata[:channel]] = users.split(' ')
|
150
|
+
@to_process = false
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Balotelli
|
2
|
+
module Config
|
3
|
+
FREENODE = ['chat.freenode.net', 6667]
|
4
|
+
QUAKENET = ['irc.quakenet.org', 6667]
|
5
|
+
RIZON = ['irc.rizon.net', 6667]
|
6
|
+
PIRC = ['irc.pirc.pl', 6667]
|
7
|
+
MOZNET = ['irc.mozilla.org', 6667]
|
8
|
+
|
9
|
+
module_function
|
10
|
+
|
11
|
+
def build(server, name = ('balotelli%03d' % rand(1000)), pass = nil)
|
12
|
+
const_get(server.upcase).dup.push(name, pass)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'socket'
|
2
|
+
|
3
|
+
module Balotelli
|
4
|
+
module Core
|
5
|
+
module IRC
|
6
|
+
def configure(host, port, nick, pass = nil)
|
7
|
+
@host = host
|
8
|
+
@port = port
|
9
|
+
@nick = nick
|
10
|
+
@pass = pass
|
11
|
+
|
12
|
+
@socket = nil
|
13
|
+
@mutex = Mutex.new
|
14
|
+
end
|
15
|
+
|
16
|
+
def connect(&block)
|
17
|
+
@socket = TCPSocket.new(@host, @port)
|
18
|
+
|
19
|
+
sputs("PASS #{@pass}") if @pass
|
20
|
+
sputs("NICK #{@nick}")
|
21
|
+
sputs("USER #{@nick} 0 * :#{@nick}")
|
22
|
+
|
23
|
+
if block_given?
|
24
|
+
instance_variable_set(:@on_connect, block)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def sgets
|
29
|
+
str = @socket.gets
|
30
|
+
str.chomp! unless str.nil?
|
31
|
+
|
32
|
+
puts '<< ' + str.inspect
|
33
|
+
|
34
|
+
str
|
35
|
+
end
|
36
|
+
|
37
|
+
def sputs(str)
|
38
|
+
@mutex.synchronize do
|
39
|
+
puts '>> ' + str.inspect
|
40
|
+
|
41
|
+
@socket.puts(str)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def pong(message)
|
46
|
+
sputs("PONG #{message}")
|
47
|
+
end
|
48
|
+
|
49
|
+
def join(channel, password = nil)
|
50
|
+
sputs("JOIN #{channel} #{password}")
|
51
|
+
end
|
52
|
+
|
53
|
+
def privmsg(channel, message)
|
54
|
+
sputs("PRIVMSG #{channel} :#{message}")
|
55
|
+
end
|
56
|
+
|
57
|
+
def names(channel)
|
58
|
+
sputs("NAMES #{channel}")
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
require 'logger'
|
2
|
+
require 'fileutils'
|
3
|
+
require 'set'
|
4
|
+
module Balotelli
|
5
|
+
module Core
|
6
|
+
class IrcLogger < Module
|
7
|
+
LOG_FORMAT = proc do |_severity, datetime, _progname, msg|
|
8
|
+
"#{datetime.utc}: #{msg}\n"
|
9
|
+
end
|
10
|
+
|
11
|
+
attr_reader :log_file, :dir, :channels, :channels_logs
|
12
|
+
|
13
|
+
def initialize(dir = '', log_name = 'logs.log', channels = [])
|
14
|
+
@dir = dir
|
15
|
+
check_dir
|
16
|
+
@log_file = new_logger(log_name)
|
17
|
+
@channels = Set.new channels
|
18
|
+
@channels_logs = @channels.each_with_object({}) do |c, o|
|
19
|
+
o[c] = new_logger(channel_log_file(c))
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def included(des)
|
24
|
+
super
|
25
|
+
|
26
|
+
define_log_method
|
27
|
+
|
28
|
+
des.instance_variable_set(:@log_file, log_file)
|
29
|
+
des.instance_variable_set(:@logger, self)
|
30
|
+
|
31
|
+
class << des
|
32
|
+
alias_method :orig_sputs, :sputs
|
33
|
+
private :orig_sputs
|
34
|
+
|
35
|
+
def sputs(str)
|
36
|
+
orig_sputs(str)
|
37
|
+
to_log = ">>#{str.inspect}\n"
|
38
|
+
@log_file.info(to_log)
|
39
|
+
if str =~ /\A:?\S+ (#\S+) .*/
|
40
|
+
@logger.channel_log($1.downcase, to_log)
|
41
|
+
end
|
42
|
+
str
|
43
|
+
end
|
44
|
+
|
45
|
+
alias_method :orig_sgets, :sgets
|
46
|
+
private :orig_sgets
|
47
|
+
|
48
|
+
def sgets
|
49
|
+
str = orig_sgets
|
50
|
+
to_log = "<<#{str.inspect}\n"
|
51
|
+
@log_file.info(to_log)
|
52
|
+
if str =~ /\A:?\S+ \S+ (#\S+) .*/
|
53
|
+
@logger.channel_log($1.downcase, to_log)
|
54
|
+
end
|
55
|
+
str
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def channel_log(channel, to_log)
|
61
|
+
if (logger = @channels_logs[channel])
|
62
|
+
logger.info to_log
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
def define_log_method
|
69
|
+
define_method :log do |str|
|
70
|
+
log_string = "LOG: #{str.inspect}\n"
|
71
|
+
__LOG_FILE__.info log_string
|
72
|
+
puts log_string
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def channel_log_file(channel)
|
77
|
+
"#{channel.tr('#', '')}_logs.log"
|
78
|
+
end
|
79
|
+
|
80
|
+
def new_logger(file_name)
|
81
|
+
Logger.new(File.join(dir, file_name), 0, 1.0 / 0)
|
82
|
+
.tap do |l|
|
83
|
+
l.formatter = LOG_FORMAT
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def check_dir
|
88
|
+
unless File.file?(dir)
|
89
|
+
FileUtils.mkdir_p(dir)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Balotelli
|
2
|
+
module Core
|
3
|
+
class Join
|
4
|
+
attr_reader :user, :channel, :user_nick, :responder
|
5
|
+
def initialize(metadata)
|
6
|
+
@user = metadata[:user]
|
7
|
+
@user_nick = Core::Utils.nick_from_user(@user)
|
8
|
+
@channel = metadata[:channel]
|
9
|
+
@responder = @channel
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Balotelli
|
2
|
+
module Core
|
3
|
+
class Kick
|
4
|
+
attr_reader :who, :channel, :reason
|
5
|
+
def initialize(data, klass)
|
6
|
+
@who = data[:who]
|
7
|
+
@channel = data[:channel]
|
8
|
+
@reason = data[:reason].tr(' ', ' ') # space to nbsp
|
9
|
+
@klass = klass
|
10
|
+
end
|
11
|
+
|
12
|
+
def execute!
|
13
|
+
@klass.sputs("KICK #{channel} #{who} #{reason}")
|
14
|
+
end
|
15
|
+
|
16
|
+
alias_method :execute, :execute!
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Balotelli
|
2
|
+
module Core
|
3
|
+
class PrivMsg
|
4
|
+
attr_reader :user, :channel, :content, :user_nick, :responder
|
5
|
+
def initialize(metadata, privacy = false)
|
6
|
+
@user = metadata[:user]
|
7
|
+
@user_nick = @user.match(/\A(\S+)!.*/)[1]
|
8
|
+
@channel = metadata[:channel]
|
9
|
+
@content = metadata[:message]
|
10
|
+
if privacy
|
11
|
+
@responder = @user_nick
|
12
|
+
else
|
13
|
+
@responder = @channel
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Balotelli
|
2
|
+
module Core
|
3
|
+
module Router
|
4
|
+
def setup_router
|
5
|
+
@routes = {}
|
6
|
+
end
|
7
|
+
|
8
|
+
def on(route, option = {}, &block)
|
9
|
+
fail 'no block given' if block.nil?
|
10
|
+
|
11
|
+
if !option.key?(:private) || route == :join
|
12
|
+
option[:private] = false
|
13
|
+
end
|
14
|
+
|
15
|
+
if option[:private] == :both
|
16
|
+
on(route, option.clone.tap { |o| o[:private] = true }, &block)
|
17
|
+
on(route, option.clone.tap { |o| o[:private] = false }, &block)
|
18
|
+
return
|
19
|
+
end
|
20
|
+
|
21
|
+
@routes[route] ||= {}
|
22
|
+
|
23
|
+
if @routes[route][option[:private]] && !option[:force]
|
24
|
+
fail "Route #{route.inspect}, private: #{option[:private]} already exists"
|
25
|
+
end
|
26
|
+
|
27
|
+
@routes[route][option[:private]] = [block, self]
|
28
|
+
end
|
29
|
+
|
30
|
+
def match?(str, route)
|
31
|
+
case route
|
32
|
+
when Regexp
|
33
|
+
str =~ route
|
34
|
+
when String
|
35
|
+
str == route
|
36
|
+
when Symbol
|
37
|
+
str == route
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def match(str, priv = false)
|
42
|
+
if m = @routes.detect { |k, v| match?(str, k) && v[priv] }
|
43
|
+
[m[0], m[1][priv], str]
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Balotelli
|
2
|
+
module Core
|
3
|
+
module Utils
|
4
|
+
NICK_REGEX = /\A(\S+)!.*/.freeze
|
5
|
+
PRIV_MSG_REGEX = /\A:?(\S+) PRIVMSG (\S+) :?(.*)/.freeze
|
6
|
+
JOIN_REGEX = /\A:?(\S+) JOIN (\S+)/.freeze
|
7
|
+
|
8
|
+
module_function
|
9
|
+
|
10
|
+
def nick_from_user(str)
|
11
|
+
str.match(NICK_REGEX)[1]
|
12
|
+
end
|
13
|
+
|
14
|
+
def table_regex(nick)
|
15
|
+
/\A:?(\S+) \d+ #{nick} \S (#\S+) :?(.*)/.freeze
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'balotelli/core/router'
|
2
|
+
|
3
|
+
module Balotelli
|
4
|
+
module Module
|
5
|
+
module Base
|
6
|
+
include Balotelli::Core::Router
|
7
|
+
|
8
|
+
def setup
|
9
|
+
setup_router
|
10
|
+
end
|
11
|
+
|
12
|
+
class << self
|
13
|
+
def extended(mod)
|
14
|
+
super
|
15
|
+
|
16
|
+
mod.setup
|
17
|
+
|
18
|
+
mod.instance_eval do
|
19
|
+
def commands_namespace
|
20
|
+
@commands_namespace ||= name[/[^:]+$/].downcase.intern
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/lib/balotelli.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
module Balotelli::Module::Asdf
|
3
|
+
extend Balotelli::Module::Base
|
4
|
+
end
|
5
|
+
module Balotelli::Module::Qwerty
|
6
|
+
extend Balotelli::Module::Base
|
7
|
+
end
|
8
|
+
class BalotelliHelperTest < Minitest::Test
|
9
|
+
def setup
|
10
|
+
@bot = Balotelli(:freenode, "test", nil, nil)
|
11
|
+
end
|
12
|
+
def test_that_it_creates_balotelli_class
|
13
|
+
assert(Balotelli::Base == @bot.superclass)
|
14
|
+
assert(@bot.instance_variable_get(:@nick) == "test")
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_that_it_includes_modules
|
18
|
+
assert @bot.instance_variable_get(:@modules)[:qwerty] == Balotelli::Module::Qwerty
|
19
|
+
assert @bot.instance_variable_get(:@modules)[:asdf] == Balotelli::Module::Asdf
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class TestBot < Balotelli::Base
|
4
|
+
end
|
5
|
+
|
6
|
+
module Balotelli::Module::Asdf
|
7
|
+
extend Balotelli::Module::Base
|
8
|
+
|
9
|
+
on %r{yes}i do
|
10
|
+
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
module Balotelli::Module::Xyz
|
15
|
+
extend Balotelli::Module::Base
|
16
|
+
|
17
|
+
on %r{si}i do
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
module Balotelli::Module::SpecialOne
|
23
|
+
extend Balotelli::Module::Base
|
24
|
+
on "asdfg" do
|
25
|
+
puts "n"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class BaseTest < Minitest::Test
|
30
|
+
def test_it_sets_up
|
31
|
+
assert TestBot.instance_variable_get(:@routes)
|
32
|
+
assert TestBot.instance_variable_get(:@modules)
|
33
|
+
assert TestBot.instance_variable_get(:@cache)
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_it_responds_to_run
|
37
|
+
assert TestBot.respond_to?(:run)
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_it_registes_module
|
41
|
+
TestBot.register(Balotelli::Module::Asdf)
|
42
|
+
assert Balotelli::Module::Asdf.commands_namespace == :asdf
|
43
|
+
assert TestBot.instance_variable_get(:@modules)[:asdf] == Balotelli::Module::Asdf
|
44
|
+
TestBot.register(Balotelli::Module::Xyz, "hoh")
|
45
|
+
assert Balotelli::Module::Xyz.commands_namespace == :hoh
|
46
|
+
assert TestBot.instance_variable_get(:@modules)[:hoh] == Balotelli::Module::Xyz
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_it_registers_special
|
50
|
+
TestBot.register_special(Balotelli::Module::SpecialOne)
|
51
|
+
assert TestBot.match("asdfg")
|
52
|
+
end
|
53
|
+
|
54
|
+
#def test_it_matches_module_routes
|
55
|
+
#TestBot.register(Balotelli::Module::Asdf)
|
56
|
+
#assert_equal TestBot.mod_match("asdf Yes, sir")[0], /yes/i
|
57
|
+
#TestBot.register(Balotelli::Module::Xyz, "hoh")
|
58
|
+
#assert_equal TestBot.mod_match("!hoh Si si")[0], /si/i
|
59
|
+
#end
|
60
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class Bot
|
4
|
+
include Balotelli::Core::IRC
|
5
|
+
|
6
|
+
def initialize(*args)
|
7
|
+
configure(*args)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
class IRCTest < Minitest::Test
|
12
|
+
def setup
|
13
|
+
@bot = Bot.new(*Balotelli::Config.build(:freenode, "test"))
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_it_responds_to_required_messages
|
17
|
+
assert @bot.respond_to?(:connect)
|
18
|
+
assert @bot.respond_to?(:sgets)
|
19
|
+
assert @bot.respond_to?(:sputs)
|
20
|
+
assert @bot.respond_to?(:pong)
|
21
|
+
assert @bot.respond_to?(:join)
|
22
|
+
assert @bot.respond_to?(:privmsg)
|
23
|
+
assert @bot.respond_to?(:names)
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class ToRoute
|
4
|
+
include Balotelli::Core::Router
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
setup_router
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
class RouterTest < Minitest::Test
|
12
|
+
def setup
|
13
|
+
@route = ToRoute.new
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_it_has_routes
|
17
|
+
assert @route.instance_variable_get(:@routes)
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_it_mathes_routes
|
21
|
+
lam = -> { puts 'kk' }
|
22
|
+
@route.on %r{ono}i, private: true, &lam
|
23
|
+
assert @route.match('onOmatopeja', true) == [%r{ono}i, [lam, @route], 'onOmatopeja']
|
24
|
+
refute @route.match('onOmatopeja', false)
|
25
|
+
@route.on 'asdf', &lam
|
26
|
+
assert @route.match('asdf')
|
27
|
+
refute @route.match('asdf', true)
|
28
|
+
@route.on %r{hi}i, private: :both, &lam
|
29
|
+
assert @route.match('Hi')
|
30
|
+
assert @route.match('hI', true)
|
31
|
+
end
|
32
|
+
end
|
data/test/test_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,119 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: balotelli
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Marcin Henryk Bartkowiak
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-09-12 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 10.4.2
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 10.4.2
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: minitest
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 5.8.0
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 5.8.0
|
55
|
+
description: ''
|
56
|
+
email:
|
57
|
+
- mhbartkowiak@gmail.com
|
58
|
+
executables: []
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- ".codeclimate.yml"
|
63
|
+
- ".gitignore"
|
64
|
+
- ".travis.yml"
|
65
|
+
- Gemfile
|
66
|
+
- Gemfile.lock
|
67
|
+
- README.md
|
68
|
+
- Rakefile
|
69
|
+
- balotelli.gemspec
|
70
|
+
- lib/balotelli.rb
|
71
|
+
- lib/balotelli/balotelli_helper.rb
|
72
|
+
- lib/balotelli/base.rb
|
73
|
+
- lib/balotelli/config.rb
|
74
|
+
- lib/balotelli/core/irc.rb
|
75
|
+
- lib/balotelli/core/irc_logger.rb
|
76
|
+
- lib/balotelli/core/join.rb
|
77
|
+
- lib/balotelli/core/kick.rb
|
78
|
+
- lib/balotelli/core/priv_msg.rb
|
79
|
+
- lib/balotelli/core/router.rb
|
80
|
+
- lib/balotelli/core/utils.rb
|
81
|
+
- lib/balotelli/module/base.rb
|
82
|
+
- lib/balotelli/version.rb
|
83
|
+
- test/lib/balotelli/balotelli_helper_test.rb
|
84
|
+
- test/lib/balotelli/base_test.rb
|
85
|
+
- test/lib/balotelli/config_test.rb
|
86
|
+
- test/lib/balotelli/core/irc_test.rb
|
87
|
+
- test/lib/balotelli/core/router_test.rb
|
88
|
+
- test/test_helper.rb
|
89
|
+
homepage: https://github.com/mhib/balotelli
|
90
|
+
licenses:
|
91
|
+
- MIT
|
92
|
+
metadata: {}
|
93
|
+
post_install_message:
|
94
|
+
rdoc_options: []
|
95
|
+
require_paths:
|
96
|
+
- lib
|
97
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
98
|
+
requirements:
|
99
|
+
- - ">="
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
103
|
+
requirements:
|
104
|
+
- - ">="
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
version: '0'
|
107
|
+
requirements: []
|
108
|
+
rubyforge_project:
|
109
|
+
rubygems_version: 2.4.8
|
110
|
+
signing_key:
|
111
|
+
specification_version: 4
|
112
|
+
summary: Simple IRC bot framework
|
113
|
+
test_files:
|
114
|
+
- test/lib/balotelli/balotelli_helper_test.rb
|
115
|
+
- test/lib/balotelli/base_test.rb
|
116
|
+
- test/lib/balotelli/config_test.rb
|
117
|
+
- test/lib/balotelli/core/irc_test.rb
|
118
|
+
- test/lib/balotelli/core/router_test.rb
|
119
|
+
- test/test_helper.rb
|