rubot 0.0.3 → 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.
- data/README.rdoc +33 -0
- data/bin/rubot +43 -19
- data/bin/rubot~ +48 -0
- data/lib/core.rb +4 -4
- data/lib/core/command.rb +12 -4
- data/lib/core/dispatcher.rb +52 -50
- data/lib/core/runner.rb +2 -2
- data/lib/core/runner.rb~ +13 -0
- data/lib/extensions.rb +2 -5
- data/lib/generators/command.rb~ +5 -0
- data/lib/generators/command.template~ +5 -0
- data/lib/generators/commands.template +5 -0
- data/lib/generators/listener.template~ +7 -0
- data/lib/generators/listeners.template +7 -0
- data/lib/generators/runner.template~ +5 -0
- data/lib/generators/runners.template +7 -0
- data/lib/irc.rb +4 -4
- data/lib/irc/message.rb +1 -1
- data/lib/irc/server.rb +2 -2
- data/lib/irc/server.rb~ +162 -0
- data/lib/rubot.rb +3 -7
- data/lib/template.rb +42 -0
- data/lib/template.rb~ +52 -0
- data/lib/template/resources/config.yml +4 -4
- metadata +36 -31
- data/README +0 -1
- data/Rakefile +0 -12
- data/lib/extensions/kernel.rb +0 -6
data/README.rdoc
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
= rubot
|
2
|
+
A Ruby Bot framwork for IRC featuring reloadable commands and listeners.
|
3
|
+
|
4
|
+
== Installation
|
5
|
+
gem install rubot
|
6
|
+
|
7
|
+
== Usage
|
8
|
+
This gem installs an executable script to your gems directory.
|
9
|
+
|
10
|
+
To get help at any time,
|
11
|
+
rubot --help
|
12
|
+
|
13
|
+
===Initialization
|
14
|
+
To initialize a new project,
|
15
|
+
rubot --init <project_name>
|
16
|
+
|
17
|
+
This will create the <project_name> directory with the following structure:
|
18
|
+
* *commands* - Houses commands to be called by user. Includes several useful default commands
|
19
|
+
* *listeners* - Houses listeners that see every message not formatted as a command
|
20
|
+
* *resources* - Houses various resources, defaults with config.yml
|
21
|
+
* *runners* - Houses runners that are executed at startup
|
22
|
+
* *main.rb* - Sets up and launches rubot
|
23
|
+
|
24
|
+
After creating the project, modify resources/config.yml to meet your needs.
|
25
|
+
|
26
|
+
Run the bot with
|
27
|
+
ruby main.rb
|
28
|
+
|
29
|
+
===Generators
|
30
|
+
Rubot provides generators for commands, listeners, and runners.
|
31
|
+
rubot --command my_command
|
32
|
+
rubot --listener my_listener
|
33
|
+
rubot --runner my_runner
|
data/bin/rubot
CHANGED
@@ -1,24 +1,48 @@
|
|
1
|
-
|
2
|
-
require "fileutils"
|
1
|
+
#!/usr/bin/env ruby
|
3
2
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
end
|
3
|
+
require "optparse"
|
4
|
+
require "ostruct"
|
5
|
+
require "template"
|
8
6
|
|
9
|
-
|
10
|
-
|
11
|
-
|
7
|
+
options = OpenStruct.new
|
8
|
+
parser = OptionParser.new do |parser|
|
9
|
+
parser.banner = "Usage: #{__FILE__} <options>"
|
10
|
+
|
11
|
+
parser.separator ""
|
12
|
+
parser.separator "Initialization"
|
13
|
+
|
14
|
+
parser.on("-i", "--init ProjectName", "Initializes a new rubot project in the ProjectName directory") do |name|
|
15
|
+
init name
|
16
|
+
exit
|
17
|
+
end
|
18
|
+
|
19
|
+
parser.separator ""
|
20
|
+
parser.separator "Generators"
|
21
|
+
|
22
|
+
parser.on("-c", "--command Name", "Generates a new command named Name") do |name|
|
23
|
+
generate_command(name)
|
24
|
+
exit
|
25
|
+
end
|
26
|
+
|
27
|
+
parser.on("-l", "--listener Name", "Generates a new listener named Name") do |name|
|
28
|
+
generate_listener(name)
|
29
|
+
exit
|
30
|
+
end
|
31
|
+
|
32
|
+
parser.on("-r", "--runner Name", "Generates a new listener named Name") do |name|
|
33
|
+
generate_runner(name)
|
34
|
+
exit
|
35
|
+
end
|
36
|
+
|
37
|
+
parser.separator ""
|
38
|
+
parser.separator "Common options:"
|
39
|
+
|
40
|
+
parser.on_tail("-h", "--help", "Show this message") do
|
41
|
+
puts parser
|
42
|
+
exit
|
43
|
+
end
|
12
44
|
end
|
13
45
|
|
14
|
-
|
15
|
-
|
16
|
-
spec = Gem.searcher.find("rubot")
|
17
|
-
template_dir = File.join(spec.installation_path, "gems", spec.full_name, "lib", "template")
|
46
|
+
parser.parse!(ARGV)
|
47
|
+
puts parser
|
18
48
|
|
19
|
-
FileUtils.cp_r(template_dir, ARGV[0])
|
20
|
-
# for some reason gem doesn't include empty folders during the install
|
21
|
-
# this is to make sure these directories exist
|
22
|
-
%w{resources commands listeners runners}.each do |dir|
|
23
|
-
FileUtils.mkdir File.join(ARGV[0], dir) unless File.exist? File.join(ARGV[0], dir)
|
24
|
-
end
|
data/bin/rubot~
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "optparse"
|
4
|
+
require "ostruct"
|
5
|
+
require "template"
|
6
|
+
|
7
|
+
options = OpenStruct.new
|
8
|
+
parser = OptionParser.new do |parser|
|
9
|
+
parser.banner = "Usage: #{__FILE__} <options>"
|
10
|
+
|
11
|
+
parser.separator ""
|
12
|
+
parser.separator "Initialization"
|
13
|
+
|
14
|
+
parser.on("-i", "--init ProjectName", "Initializes a new rubot project in the ProjectName directory") do |name|
|
15
|
+
init name
|
16
|
+
exit
|
17
|
+
end
|
18
|
+
|
19
|
+
parser.separator ""
|
20
|
+
parser.separator "Generators"
|
21
|
+
|
22
|
+
parser.on("-c", "--command Name", "Generates a new command named Name") do |name|
|
23
|
+
generate_command(name)
|
24
|
+
exit
|
25
|
+
end
|
26
|
+
|
27
|
+
parser.on("-l", "--listener Name", "Generates a new listener named Name") do |listener|
|
28
|
+
generate_listener(name)
|
29
|
+
exit
|
30
|
+
end
|
31
|
+
|
32
|
+
parser.on("-r", "--runner Name", "Generates a new listener named Name") do |runner|
|
33
|
+
generate_runner(name)
|
34
|
+
exit
|
35
|
+
end
|
36
|
+
|
37
|
+
parser.separator ""
|
38
|
+
parser.separator "Common options:"
|
39
|
+
|
40
|
+
parser.on_tail("-h", "--help", "Show this message") do
|
41
|
+
puts parser
|
42
|
+
exit
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
parser.parse!(ARGV)
|
47
|
+
puts parser
|
48
|
+
|
data/lib/core.rb
CHANGED
data/lib/core/command.rb
CHANGED
@@ -4,14 +4,23 @@ require "optparse"
|
|
4
4
|
|
5
5
|
module Rubot
|
6
6
|
module Core
|
7
|
+
# Base class that handles the dirty work for IRC commands.
|
8
|
+
# All commands belong in the /commands directory and
|
9
|
+
# inherit this class.
|
10
|
+
#
|
11
|
+
# Since:: 0.0.1
|
7
12
|
class Command
|
8
|
-
attr_reader :protected
|
9
13
|
|
10
14
|
def initialize(dispatcher)
|
11
15
|
@dispatcher = dispatcher
|
12
16
|
end
|
13
17
|
|
14
18
|
def run(server, message)
|
19
|
+
if protected? && !message.authenticated
|
20
|
+
server.msg(message.destination, "unauthorized")
|
21
|
+
return
|
22
|
+
end
|
23
|
+
|
15
24
|
args = Shellwords.shellwords(message.body.gsub(/(')/n, "\\\\\'"))
|
16
25
|
options = parse(args)
|
17
26
|
|
@@ -25,7 +34,7 @@ module Rubot
|
|
25
34
|
end
|
26
35
|
end
|
27
36
|
|
28
|
-
def
|
37
|
+
def protected?
|
29
38
|
false
|
30
39
|
end
|
31
40
|
|
@@ -37,13 +46,12 @@ module Rubot
|
|
37
46
|
end
|
38
47
|
|
39
48
|
def self.acts_as_protected
|
40
|
-
define_method(:
|
49
|
+
define_method(:protected?) do
|
41
50
|
true
|
42
51
|
end
|
43
52
|
end
|
44
53
|
|
45
54
|
def self.aliases(*aliases)
|
46
|
-
raise ArgumentError, 'only symbols allowed' unless aliases.all? {|a| a.is_a? Symbol}
|
47
55
|
define_method(:aliases) do
|
48
56
|
aliases
|
49
57
|
end
|
data/lib/core/dispatcher.rb
CHANGED
@@ -2,84 +2,86 @@ require "thread"
|
|
2
2
|
|
3
3
|
module Rubot
|
4
4
|
module Core
|
5
|
+
# The middle man. The Dispatcher takes incomming messages
|
6
|
+
# from the server and determines the appropriate action to
|
7
|
+
# take, handing the messages off to commands or listeners.
|
8
|
+
#
|
9
|
+
# Since:: 0.0.1
|
5
10
|
class Dispatcher
|
6
|
-
|
7
11
|
attr_reader :commands, :listeners, :function_character, :config, :resource_lock
|
8
|
-
|
12
|
+
|
9
13
|
def initialize(config)
|
10
14
|
@config = config
|
11
15
|
@function_character = @config["function_character"]
|
12
|
-
|
13
|
-
@auth_list = config["auth_list"].split(
|
14
|
-
@auth_list ||= []
|
15
|
-
|
16
|
+
|
17
|
+
@auth_list = (config["auth_list"] || "").split(",")
|
16
18
|
@resource_lock = Mutex.new
|
19
|
+
|
17
20
|
reload
|
18
21
|
# runners are only run on server connection, so there's no need them to be in reload
|
19
22
|
load_dir "runners", @runners = {}
|
20
23
|
end
|
21
|
-
|
24
|
+
|
22
25
|
def connected(server)
|
23
26
|
run_runners(server)
|
24
27
|
end
|
25
|
-
|
28
|
+
|
26
29
|
def reload
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
30
|
+
load_dir "commands", @commands = {}
|
31
|
+
load_dir "listeners", @listeners = {}
|
32
|
+
end
|
33
|
+
|
31
34
|
def handle_message(server, message)
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
#if command is protected and user is not authenticated, return
|
42
|
-
if command.is_protected? && !@auth_list.include?(message.from)
|
43
|
-
server.msg(message.destination, "unauthorized")
|
44
|
-
return
|
45
|
-
end
|
46
|
-
|
47
|
-
command.run(server, message)
|
48
|
-
elsif message.from != server.nick
|
49
|
-
@listeners.each_value do |listener|
|
50
|
-
listener.execute(server, message)
|
35
|
+
if message.body =~ /^#{@function_character}([a-z_]+)( .+)?$/i
|
36
|
+
message.body = $2.nil? ? "" : $2.strip # remove the function name from the message
|
37
|
+
message.alias = $1.underscore.to_sym
|
38
|
+
|
39
|
+
command = command_from_message(message)
|
40
|
+
command.run(server, message) unless command.nil?
|
41
|
+
elsif message.from != server.nick
|
42
|
+
@listeners.each_value do |listener|
|
43
|
+
listener.execute(server, message)
|
51
44
|
end
|
52
45
|
end
|
53
46
|
end
|
54
|
-
|
47
|
+
|
48
|
+
def command_from_message(message)
|
49
|
+
command = @commands[message.alias]
|
50
|
+
message.authenticated = authenticated?(message.from) unless command.nil?
|
51
|
+
command
|
52
|
+
end
|
53
|
+
|
54
|
+
def authenticated?(nick)
|
55
|
+
@auth_list.include?(nick)
|
56
|
+
end
|
57
|
+
|
55
58
|
def add_auth(nick)
|
56
|
-
|
57
|
-
@auth_list.push nick
|
58
|
-
end
|
59
|
+
@auth_list << nick unless authenticated?(nick)
|
59
60
|
end
|
60
|
-
|
61
|
+
|
61
62
|
def remove_auth(nick)
|
62
63
|
@auth_list.delete nick
|
63
64
|
end
|
64
|
-
|
65
|
+
|
65
66
|
private
|
66
|
-
|
67
|
+
|
67
68
|
def run_runners(server)
|
68
|
-
@runners.each_value {|
|
69
|
+
@runners.each_value {|runner| runner.run(server)}
|
69
70
|
end
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
next unless set
|
76
|
-
|
77
|
-
name = File.basename(file, ".rb")
|
78
|
-
clazz = eval(name.camelize).new(self)
|
79
|
-
set[name.to_sym] = clazz
|
80
|
-
clazz.aliases.each{|a| set[a] = clazz} if clazz.respond_to? :aliases
|
71
|
+
|
72
|
+
def load_dir(dir, set)
|
73
|
+
Dir["#{dir}/*.rb"].each do |file|
|
74
|
+
load file
|
75
|
+
file_to_instance_hash(file, set)
|
81
76
|
end
|
82
77
|
end
|
78
|
+
|
79
|
+
def file_to_instance_hash(file, hash, ext = ".rb")
|
80
|
+
name = File.basename(file, ext)
|
81
|
+
clazz = eval(name.camelize).new(self)
|
82
|
+
hash[name.to_sym] = clazz
|
83
|
+
clazz.aliases.each{|aliaz| hash[aliaz] = clazz} if clazz.respond_to? :aliases
|
84
|
+
end
|
83
85
|
end
|
84
86
|
end
|
85
87
|
end
|
data/lib/core/runner.rb
CHANGED
data/lib/core/runner.rb~
ADDED
data/lib/extensions.rb
CHANGED
data/lib/irc.rb
CHANGED
data/lib/irc/message.rb
CHANGED
data/lib/irc/server.rb
CHANGED
@@ -4,7 +4,7 @@ module Rubot
|
|
4
4
|
module Irc
|
5
5
|
class Server
|
6
6
|
include Rubot::Irc::Constants
|
7
|
-
attr_reader :nick, :connected_at
|
7
|
+
attr_reader :nick, :connected_at, :channels
|
8
8
|
|
9
9
|
def initialize(dispatcher)
|
10
10
|
dispatcher.config["server"].each_pair do |key, value|
|
@@ -158,4 +158,4 @@ module Rubot
|
|
158
158
|
end
|
159
159
|
end
|
160
160
|
end
|
161
|
-
end
|
161
|
+
end
|
data/lib/irc/server.rb~
ADDED
@@ -0,0 +1,162 @@
|
|
1
|
+
require "socket"
|
2
|
+
|
3
|
+
module Rubot
|
4
|
+
module Irc
|
5
|
+
class Server
|
6
|
+
include Rubot::Irc::Constants
|
7
|
+
attr_reader :nick, :connected_at, :channels
|
8
|
+
|
9
|
+
def initialize(dispatcher)
|
10
|
+
dispatcher.config["server"].each_pair do |key, value|
|
11
|
+
instance_variable_set("@#{key}".to_sym, value)
|
12
|
+
end
|
13
|
+
@channels = @channels.split(",").collect(&:strip)
|
14
|
+
@dispatcher = dispatcher
|
15
|
+
|
16
|
+
@message_queue = MessageQueue.new(@message_delay)
|
17
|
+
|
18
|
+
@message_queue.message do |destination, message|
|
19
|
+
raw "PRIVMSG #{destination} :#{message}"
|
20
|
+
end
|
21
|
+
|
22
|
+
@message_queue.action do |destination, action|
|
23
|
+
raw "PRIVMSG #{destination} :\001ACTION #{action}\001"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def connect
|
28
|
+
return if @is_connected
|
29
|
+
|
30
|
+
@conn = TCPSocket.open(@host, @port, @vhost)
|
31
|
+
raw "USER #{@nick} #{@nick} #{@nick} :#{@real_name}"
|
32
|
+
change_nick @nick
|
33
|
+
join @channels
|
34
|
+
|
35
|
+
begin
|
36
|
+
main_loop()
|
37
|
+
rescue Interrupt
|
38
|
+
rescue Exception => detail
|
39
|
+
puts detail.message()
|
40
|
+
print detail.backtrace.join("\n")
|
41
|
+
retry
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def quit
|
46
|
+
raw "QUIT :#{@quit_message}"
|
47
|
+
@conn.close
|
48
|
+
end
|
49
|
+
|
50
|
+
def change_nick(new_nick)
|
51
|
+
raw "NICK #{new_nick}"
|
52
|
+
@nick = new_nick
|
53
|
+
end
|
54
|
+
|
55
|
+
def join(channels)
|
56
|
+
channels = channels.split(',') if channels.is_a? String
|
57
|
+
@channels.concat(channels).uniq!
|
58
|
+
bulk_command("JOIN %s", channels)
|
59
|
+
end
|
60
|
+
|
61
|
+
def part(channels)
|
62
|
+
channels = channels.split(',') if channels.is_a? String
|
63
|
+
@channels.reject! { |channel| channels.include?(channel) }
|
64
|
+
bulk_command("PART %s :#{@quit_message}", channels)
|
65
|
+
end
|
66
|
+
|
67
|
+
def msg(destination, message)
|
68
|
+
@message_queue.message(destination, message)
|
69
|
+
#message = message.to_s.split("\n") unless message.is_a? Array
|
70
|
+
#build_message_array(message).each do |l|
|
71
|
+
# raw "PRIVMSG #{destination} :#{l}"
|
72
|
+
#end
|
73
|
+
end
|
74
|
+
|
75
|
+
def action(destination, message)
|
76
|
+
@message_queue.action(destination, message)
|
77
|
+
#msg(destination, "\001ACTION #{message}\001")
|
78
|
+
end
|
79
|
+
|
80
|
+
def raw(message)
|
81
|
+
puts "--> #{message}"
|
82
|
+
@conn.puts "#{message}\n"
|
83
|
+
end
|
84
|
+
|
85
|
+
def names(channel)
|
86
|
+
raw "NAMES #{channel}"
|
87
|
+
@conn.gets.split(":")[2].split(" ")
|
88
|
+
end
|
89
|
+
|
90
|
+
private
|
91
|
+
|
92
|
+
def main_loop
|
93
|
+
while true
|
94
|
+
ready = select([@conn])
|
95
|
+
next unless ready
|
96
|
+
|
97
|
+
return if @conn.eof
|
98
|
+
s = @conn.gets
|
99
|
+
handle_server_input(s)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def handle_server_input(s)
|
104
|
+
puts s
|
105
|
+
|
106
|
+
case s.strip
|
107
|
+
when /^PING :(.+)$/i
|
108
|
+
raw "PONG :#{$1}"
|
109
|
+
when /^:([-.0-9a-z]+)\s([0-9]+)\s(.+)\s(.*)$/i
|
110
|
+
handle_meta($1, $2.to_i, $4)
|
111
|
+
when /^:(.+?)!(.+?)@(.+?)\sPRIVMSG\s(.+)\s:(.+)$/i
|
112
|
+
message = Rubot::Irc::Message.new($1, $4 == @nick ? $1 : $4, $5)
|
113
|
+
# TODO add ability to pass events other than privmsg to dispatcher. ie, nick changes, parts, joins, quits, bans, etc, etc
|
114
|
+
@dispatcher.handle_message(self, message)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
# performs the same command on each element in the given collection, separated by comma
|
119
|
+
def bulk_command(formatted_string, elements)
|
120
|
+
if elements.is_a? String
|
121
|
+
elements = elements.split(',')
|
122
|
+
end
|
123
|
+
|
124
|
+
elements.each do |e|
|
125
|
+
raw sprintf(formatted_string, e.to_s.strip)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
def handle_meta(server, code, message)
|
130
|
+
case code
|
131
|
+
when ERR_NICK_IN_USE
|
132
|
+
if @nick == @alt_nick
|
133
|
+
puts "all nicks used, don't know how to name myself."
|
134
|
+
quit
|
135
|
+
exit!
|
136
|
+
end
|
137
|
+
change_nick @alt_nick
|
138
|
+
join @channels
|
139
|
+
when WELLCOME
|
140
|
+
@dispatcher.connected(self)
|
141
|
+
@is_connected = true
|
142
|
+
@connected_at = Time.now
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
def string_to_irc_lines(str)
|
147
|
+
str.split(" ").inject([""]) do |arr, word|
|
148
|
+
arr.push("") if arr.last.size > MAX_MESSAGE_LENGTH
|
149
|
+
arr.last << "#{word} "
|
150
|
+
arr
|
151
|
+
end.map(&:strip)
|
152
|
+
end
|
153
|
+
|
154
|
+
def build_message_array(arr)
|
155
|
+
arr.each_with_index.map do |message, index|
|
156
|
+
message.size > MAX_MESSAGE_LENGTH ? string_to_irc_lines(message) : arr[index]
|
157
|
+
end.flatten
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
data/lib/rubot.rb
CHANGED
data/lib/template.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
require "fileutils"
|
2
|
+
require "extensions/string"
|
3
|
+
|
4
|
+
def init(name)
|
5
|
+
if Dir.exist? name
|
6
|
+
puts "directory '#{name}' already exists"
|
7
|
+
return
|
8
|
+
end
|
9
|
+
|
10
|
+
template_dir = File.join(File.dirname(__FILE__), "template")
|
11
|
+
|
12
|
+
FileUtils.cp_r(template_dir, name)
|
13
|
+
|
14
|
+
dir_structure = %w{resources commands listeners runners}
|
15
|
+
|
16
|
+
# for some reason gem doesn't include empty folders during the install.
|
17
|
+
# this is to make sure these directories exist
|
18
|
+
dir_structure.each do |dir|
|
19
|
+
FileUtils.mkdir File.join(name, dir) unless File.exist? File.join(name, dir)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def generate_command(name)
|
24
|
+
generate("commands", name)
|
25
|
+
end
|
26
|
+
|
27
|
+
def generate_listener(name)
|
28
|
+
generate("listeners", name)
|
29
|
+
end
|
30
|
+
|
31
|
+
def generate_runner(name)
|
32
|
+
generate("runners", name)
|
33
|
+
end
|
34
|
+
|
35
|
+
def generate(template, name)
|
36
|
+
filename = File.join(template, "#{name.underscore}.rb")
|
37
|
+
puts "file '#{filename}' already exists" and return if File.exist?(filename)
|
38
|
+
|
39
|
+
template_file = File.join(File.dirname(__FILE__), "generators", "#{template}.template")
|
40
|
+
source = IO.read(template_file).gsub(/--NAME--/, name.camelize)
|
41
|
+
File.open(filename, "w") {|file| file.write(source)}
|
42
|
+
end
|
data/lib/template.rb~
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
require "fileutils"
|
2
|
+
require "extensions/string"
|
3
|
+
|
4
|
+
def init(name)
|
5
|
+
if Dir.exist? name
|
6
|
+
puts "directory '#{name}' already exists"
|
7
|
+
return
|
8
|
+
end
|
9
|
+
|
10
|
+
template_dir = File.join(File.dirname(__FILE__), "template")
|
11
|
+
|
12
|
+
FileUtils.cp_r(template_dir, name)
|
13
|
+
|
14
|
+
dir_structure = %w{resources commands listeners runners}
|
15
|
+
|
16
|
+
# for some reason gem doesn't include empty folders during the install.
|
17
|
+
# this is to make sure these directories exist
|
18
|
+
dir_structure.each do |dir|
|
19
|
+
FileUtils.mkdir File.join(name, dir) unless File.exist? File.join(name, dir)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def generate_command(name)
|
24
|
+
#command = File.join("commands", "#{name.underscore}.rb")
|
25
|
+
#template_file = File.join(File.dirname(__FILE__), "generators", "command.template")
|
26
|
+
#source = IO.read(template_file).gsub(/--NAME--/, name.camelize)
|
27
|
+
#File.open(command, "w") {|file| file.write(source)}
|
28
|
+
generate("commands", name)
|
29
|
+
end
|
30
|
+
|
31
|
+
def generate_listener(name)
|
32
|
+
#template_file = File.join(File.dirname(__FILE__), "generators", "listener.template")
|
33
|
+
#command = IO.read(template_file).gsub(/--NAME--/, name.camelize)
|
34
|
+
#File.open("listeners/#{name.underscore}.rb", "w") {|file| file.write(command)}
|
35
|
+
generate("listeners", name)
|
36
|
+
end
|
37
|
+
|
38
|
+
def generate_runner(name)
|
39
|
+
#template_file = File.join(File.dirname(__FILE__), "generators", "runner.template")
|
40
|
+
#command = IO.read(template_file).gsub(/--NAME--/, name.camelize)
|
41
|
+
#File.open("runners/#{name.underscore}.rb", "w") {|file| file.write(command)}
|
42
|
+
generate("runners", name)
|
43
|
+
end
|
44
|
+
|
45
|
+
def generate(template, name)
|
46
|
+
filename = File.join(template, "#{name.underscore}.rb")
|
47
|
+
puts "file '#{filename}' already exists" and return if File.exist?(filename)
|
48
|
+
|
49
|
+
template_file = File.join(File.dirname(__FILE__), "generators", "#{template}.template")
|
50
|
+
source = IO.read(template_file).gsub(/--NAME--/, name.camelize)
|
51
|
+
File.open(filename, "w") {|file| file.write(source)}
|
52
|
+
end
|
@@ -2,10 +2,10 @@
|
|
2
2
|
server:
|
3
3
|
host: irc.freenode.net
|
4
4
|
port: 6667
|
5
|
-
nick:
|
6
|
-
alt_nick:
|
7
|
-
real_name:
|
8
|
-
channels:
|
5
|
+
nick: mybot
|
6
|
+
alt_nick: mybot_
|
7
|
+
real_name: rubot
|
8
|
+
channels: "#mychannel"
|
9
9
|
vhost: #leave blank if none
|
10
10
|
quit_message: powered by rubot
|
11
11
|
message_delay: 2 #in seconds
|
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
+
- 1
|
7
8
|
- 0
|
8
|
-
|
9
|
-
version: 0.0.3
|
9
|
+
version: 0.1.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Chris Thorn
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-03-
|
17
|
+
date: 2010-03-23 00:00:00 -08:00
|
18
18
|
default_executable:
|
19
19
|
dependencies: []
|
20
20
|
|
@@ -25,48 +25,53 @@ executables:
|
|
25
25
|
extensions: []
|
26
26
|
|
27
27
|
extra_rdoc_files:
|
28
|
-
- README
|
28
|
+
- README.rdoc
|
29
29
|
files:
|
30
30
|
- bin/rubot
|
31
|
-
-
|
32
|
-
- lib/core/dispatcher.rb
|
33
|
-
- lib/core/listener.rb
|
34
|
-
- lib/core/runner.rb
|
31
|
+
- bin/rubot~
|
35
32
|
- lib/core.rb
|
36
|
-
- lib/extensions/kernel.rb
|
37
|
-
- lib/extensions/object.rb
|
38
|
-
- lib/extensions/string.rb
|
39
|
-
- lib/extensions.rb
|
40
|
-
- lib/irc/constants.rb
|
41
33
|
- lib/irc/message.rb
|
42
|
-
- lib/irc/message_queue.rb
|
43
34
|
- lib/irc/server.rb
|
44
|
-
- lib/irc.rb
|
45
|
-
- lib/
|
46
|
-
- lib/
|
47
|
-
- lib/
|
48
|
-
- lib/
|
49
|
-
- lib/
|
50
|
-
- lib/
|
51
|
-
- lib/
|
35
|
+
- lib/irc/constants.rb
|
36
|
+
- lib/irc/message_queue.rb
|
37
|
+
- lib/irc/server.rb~
|
38
|
+
- lib/generators/command.rb~
|
39
|
+
- lib/generators/listener.template~
|
40
|
+
- lib/generators/listeners.template
|
41
|
+
- lib/generators/commands.template
|
42
|
+
- lib/generators/command.template~
|
43
|
+
- lib/generators/runner.template~
|
44
|
+
- lib/generators/runners.template
|
45
|
+
- lib/extensions/object.rb
|
46
|
+
- lib/extensions/string.rb
|
52
47
|
- lib/template/commands/reload.rb
|
48
|
+
- lib/template/commands/quit.rb
|
49
|
+
- lib/template/commands/part.rb
|
50
|
+
- lib/template/commands/msg.rb
|
53
51
|
- lib/template/commands/up_time.rb
|
52
|
+
- lib/template/commands/join.rb
|
53
|
+
- lib/template/commands/auth.rb
|
54
|
+
- lib/template/commands/help.rb
|
54
55
|
- lib/template/main.rb
|
55
56
|
- lib/template/resources/config.yml
|
56
|
-
-
|
57
|
-
-
|
57
|
+
- lib/core/dispatcher.rb
|
58
|
+
- lib/core/listener.rb
|
59
|
+
- lib/core/command.rb
|
60
|
+
- lib/core/runner.rb
|
61
|
+
- lib/core/runner.rb~
|
62
|
+
- lib/irc.rb
|
63
|
+
- lib/template.rb
|
64
|
+
- lib/extensions.rb
|
65
|
+
- lib/rubot.rb
|
66
|
+
- lib/template.rb~
|
67
|
+
- README.rdoc
|
58
68
|
has_rdoc: true
|
59
69
|
homepage: http://github.com/thorncp/rubot
|
60
70
|
licenses: []
|
61
71
|
|
62
72
|
post_install_message:
|
63
|
-
rdoc_options:
|
64
|
-
|
65
|
-
- --inline-source
|
66
|
-
- --title
|
67
|
-
- NiftyGenerators
|
68
|
-
- --main
|
69
|
-
- README.rdoc
|
73
|
+
rdoc_options: []
|
74
|
+
|
70
75
|
require_paths:
|
71
76
|
- lib
|
72
77
|
required_ruby_version: !ruby/object:Gem::Requirement
|
data/README
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
# todo Add documentation here
|
data/Rakefile
DELETED
@@ -1,12 +0,0 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require 'rake'
|
3
|
-
require 'echoe'
|
4
|
-
|
5
|
-
Echoe.new('rubot', '0.0.1') do |p|
|
6
|
-
p.description = "A Ruby Bot framwork for IRC"
|
7
|
-
p.url = "http://github.com/tombombadil/hello_world"
|
8
|
-
p.author = "Chris Thorn"
|
9
|
-
p.email = "thorncp @nospam@ gmail.com"
|
10
|
-
p.ignore_pattern = ["tmp/*", "script/*"]
|
11
|
-
p.development_dependencies = []
|
12
|
-
end
|