Sutto-marvin 0.1.20081115 → 0.1.20081120
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.textile +70 -50
- data/VERSION.yml +1 -1
- data/bin/marvin +10 -6
- data/config/connections.yml.sample +5 -0
- data/config/settings.yml.sample +2 -7
- data/config/setup.rb +1 -0
- data/handlers/debug_handler.rb +5 -0
- data/handlers/hello_world.rb +1 -1
- data/lib/marvin.rb +1 -0
- data/lib/marvin/abstract_client.rb +79 -42
- data/lib/marvin/abstract_parser.rb +14 -2
- data/lib/marvin/base.rb +44 -6
- data/lib/marvin/dispatchable.rb +9 -4
- data/lib/marvin/drb_handler.rb +7 -2
- data/lib/marvin/exceptions.rb +3 -0
- data/lib/marvin/irc.rb +1 -1
- data/lib/marvin/irc/client.rb +31 -7
- data/lib/marvin/irc/event.rb +9 -4
- data/lib/marvin/irc/replies.rb +154 -0
- data/lib/marvin/loader.rb +1 -0
- data/lib/marvin/logger.rb +66 -3
- data/lib/marvin/options.rb +33 -0
- data/lib/marvin/parsers.rb +3 -0
- data/lib/marvin/parsers/command.rb +73 -0
- data/lib/marvin/parsers/prefixes.rb +8 -0
- data/lib/marvin/parsers/prefixes/host_mask.rb +30 -0
- data/lib/marvin/parsers/prefixes/server.rb +24 -0
- data/lib/marvin/parsers/ragel_parser.rb +713 -0
- data/lib/marvin/parsers/ragel_parser.rl +144 -0
- data/lib/marvin/parsers/regexp_parser.rb +0 -3
- data/lib/marvin/parsers/simple_parser.rb +20 -81
- data/lib/marvin/settings.rb +8 -8
- data/lib/marvin/util.rb +2 -2
- data/script/{run → client} +0 -0
- data/script/daemon-runner +1 -1
- data/script/install +3 -0
- data/test/parser_comparison.rb +36 -0
- data/test/parser_test.rb +20 -0
- data/test/test_helper.rb +10 -0
- metadata +19 -9
- data/lib/marvin/irc/socket_client.rb +0 -69
- data/lib/marvin/parsers/simple_parser/default_events.rb +0 -37
- data/lib/marvin/parsers/simple_parser/event_extensions.rb +0 -14
- data/lib/marvin/parsers/simple_parser/prefixes.rb +0 -34
@@ -0,0 +1,144 @@
|
|
1
|
+
# Ragel Parser comes from the Arrbot Guys -
|
2
|
+
# Kudos to Halogrium and Epitron.
|
3
|
+
|
4
|
+
%%{
|
5
|
+
machine irc;
|
6
|
+
|
7
|
+
action prefix_servername_start {
|
8
|
+
server = Marvin::Parsers::Prefixes::Server.new
|
9
|
+
}
|
10
|
+
|
11
|
+
action prefix_servername {
|
12
|
+
server.name << fc
|
13
|
+
}
|
14
|
+
|
15
|
+
action prefix_servername_finish {
|
16
|
+
command.prefix = server
|
17
|
+
}
|
18
|
+
|
19
|
+
action prefix_hostmask_start {
|
20
|
+
hostmask = Marvin::Parsers::Prefixes::HostMask.new
|
21
|
+
}
|
22
|
+
|
23
|
+
action hostmask_nickname {
|
24
|
+
hostmask.nickname << fc
|
25
|
+
}
|
26
|
+
|
27
|
+
action hostmask_user {
|
28
|
+
hostmask.user << fc
|
29
|
+
}
|
30
|
+
|
31
|
+
action hostmask_host {
|
32
|
+
hostmask.host << fc
|
33
|
+
}
|
34
|
+
|
35
|
+
action prefix_hostmask_finish {
|
36
|
+
command.prefix = hostmask
|
37
|
+
}
|
38
|
+
|
39
|
+
action message_code_start {
|
40
|
+
code = ""
|
41
|
+
}
|
42
|
+
|
43
|
+
action message_code {
|
44
|
+
code << fc
|
45
|
+
}
|
46
|
+
|
47
|
+
action message_code_finish {
|
48
|
+
command.code = code
|
49
|
+
}
|
50
|
+
|
51
|
+
action params_start {
|
52
|
+
params_1 = []
|
53
|
+
params_2 = []
|
54
|
+
}
|
55
|
+
|
56
|
+
action params {
|
57
|
+
}
|
58
|
+
|
59
|
+
action params_1_start {
|
60
|
+
params_1 << ""
|
61
|
+
}
|
62
|
+
|
63
|
+
action params_2_start {
|
64
|
+
params_2 << ""
|
65
|
+
}
|
66
|
+
|
67
|
+
action params_1 {
|
68
|
+
params_1.last << fc
|
69
|
+
}
|
70
|
+
|
71
|
+
action params_2 {
|
72
|
+
params_2.last << fc
|
73
|
+
}
|
74
|
+
|
75
|
+
action params_1_finish {
|
76
|
+
command.params = params_1
|
77
|
+
}
|
78
|
+
|
79
|
+
action params_2_finish {
|
80
|
+
command.params = params_2
|
81
|
+
}
|
82
|
+
|
83
|
+
SPACE = " ";
|
84
|
+
special = "[" | "\\" | "]" | "^" | "_" | "`" | "{" | "|" | "}" | "+";
|
85
|
+
nospcrlfcl = extend - ( 0 | SPACE | '\r' | '\n' | ':' );
|
86
|
+
crlf = "\r\n";
|
87
|
+
shortname = ( alnum ( alnum | "-" )* alnum* ) | "*";
|
88
|
+
multihostname = shortname ( ( "." | "/" ) shortname )*;
|
89
|
+
singlehostname = shortname ( "." | "/" );
|
90
|
+
hostname = multihostname | singlehostname;
|
91
|
+
servername = hostname;
|
92
|
+
nickname = ( alpha | special ) ( alnum | special | "-" ){,15};
|
93
|
+
user = (extend - ( 0 | "\n" | "\r" | SPACE | "@" ))+;
|
94
|
+
ip4addr = digit{1,3} "." digit{1,3} "." digit{1,3} "." digit{1,3};
|
95
|
+
ip6addr = ( xdigit+ ( ":" xdigit+ ){7} ) | ( "0:0:0:0:0:" ( "0" | "FFFF"i ) ":" ip4addr );
|
96
|
+
hostaddr = ip4addr | ip6addr;
|
97
|
+
host = hostname | hostaddr;
|
98
|
+
hostmask = nickname $ hostmask_nickname ( ( "!" user $ hostmask_user )? "@" host $ hostmask_host )?;
|
99
|
+
prefix = ( servername $ prefix_servername > prefix_servername_start % prefix_servername_finish ) | ( hostmask > prefix_hostmask_start % prefix_hostmask_finish );
|
100
|
+
code = alpha+ | digit{3};
|
101
|
+
middle = nospcrlfcl ( ":" | nospcrlfcl )*;
|
102
|
+
trailing = ( ":" | " " | nospcrlfcl )*;
|
103
|
+
params_1 = ( SPACE middle $ params_1 > params_1_start ){,14} ( SPACE ":" trailing $ params_1 > params_1_start )?;
|
104
|
+
params_2 = ( SPACE middle $ params_2 > params_2_start ){14} ( SPACE ":"? trailing $ params_2 > params_2_start )?;
|
105
|
+
params = ( params_1 % params_1_finish | params_2 % params_2_finish ) $ params > params_start;
|
106
|
+
message = ( ":" prefix SPACE )? ( code $ message_code > message_code_start % message_code_finish ) params? crlf;
|
107
|
+
|
108
|
+
main := message;
|
109
|
+
|
110
|
+
}%%
|
111
|
+
|
112
|
+
module Marvin
|
113
|
+
module Parsers
|
114
|
+
class RagelParser < Marvin::AbstractParser
|
115
|
+
|
116
|
+
%% write data;
|
117
|
+
|
118
|
+
private
|
119
|
+
|
120
|
+
def self.parse!(line)
|
121
|
+
data = "#{line.strip}\r\n"
|
122
|
+
|
123
|
+
p = 0;
|
124
|
+
pe = data.length
|
125
|
+
cs = 0
|
126
|
+
|
127
|
+
hostmask = nil
|
128
|
+
server = nil
|
129
|
+
code = nil
|
130
|
+
command = Marvin::Parsers::Command.new(data)
|
131
|
+
|
132
|
+
%% write init;
|
133
|
+
%% write exec;
|
134
|
+
|
135
|
+
if cs >= irc_first_final
|
136
|
+
command
|
137
|
+
else
|
138
|
+
raise UnparseableMessage, "Failed to parse the message: #{input.inspect}"
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
@@ -81,9 +81,6 @@ module Marvin
|
|
81
81
|
register_event :quit, /^\:(.+)\!\~?(.+)\@(.+) QUIT :?(.+?)$/i,
|
82
82
|
:nick, :ident, :host, :message
|
83
83
|
|
84
|
-
register_event :nick_taken, /^\:(\S+) 433 \* (\w+) :(.+)$/,
|
85
|
-
:server, :target, :message
|
86
|
-
|
87
84
|
register_event :ping, /^\:(.+)\!\~?(.+)\@(.+) PING (.*)$/,
|
88
85
|
:nick, :ident, :host, :data
|
89
86
|
|
@@ -1,101 +1,40 @@
|
|
1
|
-
require File.dirname(__FILE__) / "simple_parser/prefixes"
|
2
|
-
require File.dirname(__FILE__) / "simple_parser/event_extensions"
|
3
|
-
require File.dirname(__FILE__) / "simple_parser/default_events"
|
4
|
-
|
5
1
|
module Marvin
|
6
2
|
module Parsers
|
7
3
|
class SimpleParser < Marvin::AbstractParser
|
8
4
|
|
9
|
-
cattr_accessor :events
|
10
|
-
self.events ||= {}
|
11
|
-
|
12
|
-
attr_accessor :arguments, :prefix, :current_line, :parts, :event
|
13
|
-
|
14
|
-
def initialize(line)
|
15
|
-
self.current_line = line
|
16
|
-
parse!
|
17
|
-
end
|
18
|
-
|
19
|
-
def to_event
|
20
|
-
if self.event.blank?
|
21
|
-
parse!
|
22
|
-
return nil
|
23
|
-
else
|
24
|
-
return self.event
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
5
|
private
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
6
|
+
|
7
|
+
# Parses an incoming message by using string
|
8
|
+
# Manipulation.
|
9
|
+
def self.parse!(line)
|
33
10
|
if line[0] == ?:
|
34
11
|
prefix_text, line = line.split(" ", 2)
|
35
12
|
else
|
36
13
|
prefix_text = nil
|
37
14
|
end
|
38
|
-
|
39
|
-
|
15
|
+
command = Marvin::Parsers::Command.new(line + "\r\n")
|
16
|
+
command.prefix = self.extract_prefix(prefix_text)
|
40
17
|
head, tail = line.split(":", 2)
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
self.parts.unshift(command.to_s) # Reappend the command
|
47
|
-
process_event self.events[:numeric]
|
48
|
-
elsif self.events.has_key? command
|
49
|
-
# Registered Command
|
50
|
-
process_event self.events[command]
|
51
|
-
else
|
52
|
-
# Unknown Command
|
53
|
-
self.event = nil
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
def process_event(prototype, skip_mutation = false)
|
58
|
-
self.event = prototype.dup
|
59
|
-
self.event.prefix = self.prefix
|
60
|
-
self.event.raw_arguments = self.parts
|
61
|
-
mutate_event! unless skip_mutation
|
18
|
+
parts = head.split(" ")
|
19
|
+
command.code = parts.shift
|
20
|
+
parts << tail unless tail.nil?
|
21
|
+
command.params = parts
|
22
|
+
return command
|
62
23
|
end
|
63
24
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
else
|
73
|
-
message = message[1..-2]
|
74
|
-
new_event = :ctcp
|
75
|
-
end
|
76
|
-
self.parts = [message]
|
77
|
-
process_event self.events[new_event], true
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
def extract_prefix!(text)
|
82
|
-
return if text.blank?
|
83
|
-
full_prefix = text[1..-1]
|
84
|
-
prefix = full_prefix
|
85
|
-
# Ugly regexp for nick!ident@host format
|
86
|
-
# Officially this should be less-terse, but hey
|
87
|
-
# it's a simple parser.
|
88
|
-
if full_prefix =~ /^([^@!]+)\!\~?([^@]+)@(.*)$/
|
89
|
-
prefix = UserPrefix.new($1, $2, $3)
|
25
|
+
# From a given string, attempts to get the correct
|
26
|
+
# type of prefix (be it a HostMask or a Server name).
|
27
|
+
def self.extract_prefix(prefix_text)
|
28
|
+
return if prefix_text.blank?
|
29
|
+
prefix_text = prefix_text[1..-1] # Remove the leading :
|
30
|
+
# I think I just vomitted in my mouth a little...
|
31
|
+
if prefix_text =~ /^([A-Za-z0-9\-\[\]\\\`\^\{\}]+)(\!\~?([^@]+))?(@(.*))?$/
|
32
|
+
prefix = Prefixes::HostMask.new($1, $3, $5)
|
90
33
|
else
|
91
|
-
|
92
|
-
prefix = ServerNamePrefix.new(prefix.strip)
|
34
|
+
prefix = Prefixes::Server.new(prefix_text.strip)
|
93
35
|
end
|
94
|
-
self.prefix = prefix
|
95
36
|
return prefix
|
96
37
|
end
|
97
|
-
|
98
|
-
include DefaultEvents
|
99
38
|
end
|
100
39
|
end
|
101
40
|
end
|
data/lib/marvin/settings.rb
CHANGED
@@ -1,9 +1,14 @@
|
|
1
1
|
require 'yaml'
|
2
|
+
require 'eventmachine'
|
2
3
|
|
3
4
|
module Marvin
|
4
5
|
class Settings
|
5
6
|
|
6
|
-
cattr_accessor :environment, :configuration, :is_setup, :default_client,
|
7
|
+
cattr_accessor :environment, :configuration, :is_setup, :default_client,
|
8
|
+
:handler_folder, :default_parser, :log_level, :verbose
|
9
|
+
|
10
|
+
self.verbose = false
|
11
|
+
self.log_level = :info
|
7
12
|
|
8
13
|
class << self
|
9
14
|
|
@@ -23,13 +28,8 @@ module Marvin
|
|
23
28
|
def setup!(options = {})
|
24
29
|
self.environment ||= "development"
|
25
30
|
self.configuration = {}
|
26
|
-
self.default_client ||=
|
27
|
-
|
28
|
-
Marvin::IRC::Client
|
29
|
-
rescue LoadError
|
30
|
-
Marvin::IRC::SocketClient
|
31
|
-
end
|
32
|
-
self.default_parser ||= Marvin::Parsers::RegexpParser
|
31
|
+
self.default_client ||= Marvin::IRC::Client
|
32
|
+
self.default_parser ||= Marvin::Parsers::SimpleParser
|
33
33
|
loaded_yaml = YAML.load_file(root / "config/settings.yml")
|
34
34
|
loaded_options = loaded_yaml["default"].
|
35
35
|
merge(loaded_yaml[self.environment]).
|
data/lib/marvin/util.rb
CHANGED
@@ -10,9 +10,9 @@ module Marvin
|
|
10
10
|
alias chan channel_name
|
11
11
|
|
12
12
|
def arguments(input)
|
13
|
-
prefix,
|
13
|
+
prefix, ending = input.split(":", 2)
|
14
14
|
prefix = prefix.split(" ")
|
15
|
-
prefix << ending.
|
15
|
+
prefix << ending unless ending.blank?
|
16
16
|
return prefix
|
17
17
|
end
|
18
18
|
|
data/script/{run → client}
RENAMED
File without changes
|
data/script/daemon-runner
CHANGED
data/script/install
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'benchmark'
|
2
|
+
require File.join(File.dirname(__FILE__),'../lib/marvin')
|
3
|
+
|
4
|
+
LINES = [
|
5
|
+
":irc.darth.vpn.spork.in 366 testbot #testing :End of NAMES list",
|
6
|
+
":Helsinki.FI.EU.Undernet.org PONG Helsinki.FI.EU.Undernet.org :Helsinki.FI.EU.Undernet.org",
|
7
|
+
":testnick USER guest tolmoon tolsun :Ronnie Reagan",
|
8
|
+
"LIST #twilight_zone,#42",
|
9
|
+
":WiZ LINKS *.bu.edu *.edu",
|
10
|
+
":Angel PRIVMSG Wiz :Hello are you receiving this message ?",
|
11
|
+
":RelayBot!n=MarvinBo@203.161.81.201.static.amnet.net.au JOIN :#relayrelay",
|
12
|
+
":SuttoL!n=SuttoL@li6-47.members.linode.com PRIVMSG #relayrelay :testing...",
|
13
|
+
":wolfe.freenode.net 004 MarvinBot3000 wolfe.freenode.net hyperion-1.0.2b aAbBcCdDeEfFGhHiIjkKlLmMnNopPQrRsStTuUvVwWxXyYzZ01234569*@ bcdefFhiIklmnoPqstv"
|
14
|
+
]
|
15
|
+
PARSERS = [Marvin::Parsers::RagelParser, Marvin::Parsers::SimpleParser, Marvin::Parsers::RegexpParser]
|
16
|
+
|
17
|
+
LINES.each do |line|
|
18
|
+
|
19
|
+
puts "Processing: #{line}"
|
20
|
+
puts ""
|
21
|
+
cmd = []
|
22
|
+
|
23
|
+
PARSERS.each do |p|
|
24
|
+
parser = p.new(line)
|
25
|
+
ev = parser.to_event
|
26
|
+
puts "Parser: #{p.name}"
|
27
|
+
if ev.nil?
|
28
|
+
puts "Unknown Event"
|
29
|
+
else
|
30
|
+
puts ev.to_hash.inspect
|
31
|
+
end
|
32
|
+
puts ""
|
33
|
+
end
|
34
|
+
puts ""
|
35
|
+
|
36
|
+
end
|
data/test/parser_test.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
class ParserTest < Test::Unit::TestCase
|
2
|
+
@@parser = nil
|
3
|
+
def self.parser_is(p)
|
4
|
+
@@parser = p
|
5
|
+
end
|
6
|
+
|
7
|
+
context "When parsing a PONG" do
|
8
|
+
end
|
9
|
+
|
10
|
+
context "When parsing a PING" do
|
11
|
+
end
|
12
|
+
|
13
|
+
context "When parsing a PRIVMSG" do
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
["Regexp", "Simple"].each do |parser_name|
|
19
|
+
eval("class #{parser_name}ParserTest < ParserTest; parser_is #{parser_is}Parser; end")
|
20
|
+
end
|
data/test/test_helper.rb
ADDED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: Sutto-marvin
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.20081120
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Darcy Laycock
|
@@ -9,8 +9,8 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-11-
|
13
|
-
default_executable:
|
12
|
+
date: 2008-11-22 00:00:00 -08:00
|
13
|
+
default_executable: marvin
|
14
14
|
dependencies: []
|
15
15
|
|
16
16
|
description: Marvin is a Ruby IRC library / framework for ultimate awesomeness and with an evented design.
|
@@ -42,33 +42,43 @@ files:
|
|
42
42
|
- lib/marvin/irc/base_server.rb
|
43
43
|
- lib/marvin/irc/client.rb
|
44
44
|
- lib/marvin/irc/event.rb
|
45
|
-
- lib/marvin/irc/
|
45
|
+
- lib/marvin/irc/replies.rb
|
46
46
|
- lib/marvin/irc.rb
|
47
47
|
- lib/marvin/loader.rb
|
48
48
|
- lib/marvin/logger.rb
|
49
49
|
- lib/marvin/middle_man.rb
|
50
|
+
- lib/marvin/options.rb
|
50
51
|
- lib/marvin/parsers
|
52
|
+
- lib/marvin/parsers/command.rb
|
53
|
+
- lib/marvin/parsers/prefixes
|
54
|
+
- lib/marvin/parsers/prefixes/host_mask.rb
|
55
|
+
- lib/marvin/parsers/prefixes/server.rb
|
56
|
+
- lib/marvin/parsers/prefixes.rb
|
57
|
+
- lib/marvin/parsers/ragel_parser.rb
|
58
|
+
- lib/marvin/parsers/ragel_parser.rl
|
51
59
|
- lib/marvin/parsers/regexp_parser.rb
|
52
|
-
- lib/marvin/parsers/simple_parser
|
53
|
-
- lib/marvin/parsers/simple_parser/default_events.rb
|
54
|
-
- lib/marvin/parsers/simple_parser/event_extensions.rb
|
55
|
-
- lib/marvin/parsers/simple_parser/prefixes.rb
|
56
60
|
- lib/marvin/parsers/simple_parser.rb
|
57
61
|
- lib/marvin/parsers.rb
|
58
62
|
- lib/marvin/settings.rb
|
59
63
|
- lib/marvin/test_client.rb
|
60
64
|
- lib/marvin/util.rb
|
61
65
|
- lib/marvin.rb
|
66
|
+
- test/parser_comparison.rb
|
67
|
+
- test/parser_test.rb
|
68
|
+
- test/test_helper.rb
|
62
69
|
- spec/marvin
|
63
70
|
- spec/marvin/abstract_client_test.rb
|
64
71
|
- spec/spec_helper.rb
|
72
|
+
- script/client
|
65
73
|
- script/daemon-runner
|
66
|
-
- script/
|
74
|
+
- script/install
|
75
|
+
- handlers/debug_handler.rb
|
67
76
|
- handlers/hello_world.rb
|
68
77
|
- handlers/logging_handler.rb
|
69
78
|
- handlers/tweet_tweet.rb
|
70
79
|
- config/setup.rb
|
71
80
|
- config/settings.yml.sample
|
81
|
+
- config/connections.yml.sample
|
72
82
|
has_rdoc: false
|
73
83
|
homepage: http://blog.ninjahideout.com/
|
74
84
|
post_install_message:
|