rubot 0.0.3 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|