mod_spox 0.2.0 → 0.3.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/CHANGELOG +31 -1
- data/LICENSE +674 -0
- data/README.rdoc +73 -0
- data/bin/mod_spox +28 -28
- data/data/mod_spox/extras/AOLSpeak.rb +2 -3
- data/data/mod_spox/extras/AutoKick.rb +10 -23
- data/data/mod_spox/extras/AutoMode.rb +12 -23
- data/data/mod_spox/extras/Bash.rb +55 -0
- data/data/mod_spox/extras/Bouncer.rb +85 -57
- data/data/mod_spox/extras/Bullshit.rb +1 -1
- data/data/mod_spox/extras/Bytes.rb +1 -2
- data/data/mod_spox/extras/Confess.rb +27 -29
- data/data/mod_spox/extras/DCC.rb +11 -20
- data/data/mod_spox/extras/DevWatch.rb +21 -23
- data/data/mod_spox/extras/DownForEveryoneOrJustMe.rb +47 -0
- data/data/mod_spox/extras/EightBall.rb +1 -1
- data/data/mod_spox/extras/FML.rb +35 -0
- data/data/mod_spox/extras/Headers.rb +31 -50
- data/data/mod_spox/extras/Karma.rb +81 -29
- data/data/mod_spox/extras/Logger.rb +2 -2
- data/data/mod_spox/extras/LolSpeak.rb +1 -2
- data/data/mod_spox/extras/PhpCli.rb +138 -8
- data/data/mod_spox/extras/PhpFuncLookup.rb +20 -23
- data/data/mod_spox/extras/Pinger.rb +1 -1
- data/data/mod_spox/extras/Quotes.rb +8 -10
- data/data/mod_spox/extras/RegexTracker.rb +2 -4
- data/data/mod_spox/extras/Roulette.rb +20 -27
- data/data/mod_spox/extras/RubyCli.rb +93 -0
- data/data/mod_spox/extras/Search.rb +17 -3
- data/data/mod_spox/extras/Seen.rb +150 -0
- data/data/mod_spox/extras/SlashdotHeadlineGenerator.rb +500 -0
- data/data/mod_spox/extras/Talk.rb +2 -4
- data/data/mod_spox/extras/Topten.rb +10 -12
- data/data/mod_spox/extras/TracTicket.rb +3 -5
- data/data/mod_spox/extras/Translate.rb +20 -22
- data/data/mod_spox/extras/Twitter.rb +118 -33
- data/data/mod_spox/extras/UrbanDictionary.rb +8 -17
- data/data/mod_spox/extras/Weather.rb +1 -2
- data/data/mod_spox/plugins/Authenticator.rb +93 -98
- data/data/mod_spox/plugins/Banner.rb +26 -56
- data/data/mod_spox/plugins/Helper.rb +5 -6
- data/data/mod_spox/plugins/Initializer.rb +4 -14
- data/data/mod_spox/plugins/Joiner.rb +1 -1
- data/data/mod_spox/plugins/Nicker.rb +13 -0
- data/data/mod_spox/plugins/Parter.rb +2 -2
- data/data/mod_spox/plugins/Permissions.rb +60 -0
- data/data/mod_spox/plugins/PluginLoader.rb +7 -12
- data/data/mod_spox/plugins/Ponger.rb +51 -0
- data/data/mod_spox/plugins/Quitter.rb +1 -2
- data/data/mod_spox/plugins/Servers.rb +57 -0
- data/data/mod_spox/plugins/Status.rb +3 -2
- data/data/mod_spox/plugins/Triggers.rb +9 -9
- data/lib/mod_spox/Bot.rb +109 -33
- data/lib/mod_spox/BotConfig.rb +2 -2
- data/lib/mod_spox/ConfigurationWizard.rb +12 -12
- data/lib/mod_spox/Database.rb +1 -4
- data/lib/mod_spox/Exceptions.rb +26 -0
- data/lib/mod_spox/Helpers.rb +29 -68
- data/lib/mod_spox/Loader.rb +23 -24
- data/lib/mod_spox/Logger.rb +19 -17
- data/lib/mod_spox/MessageFactory.rb +50 -24
- data/lib/mod_spox/Pipeline.rb +21 -7
- data/lib/mod_spox/Plugin.rb +27 -3
- data/lib/mod_spox/PluginManager.rb +28 -15
- data/lib/mod_spox/PriorityQueue.rb +69 -0
- data/lib/mod_spox/Socket.rb +93 -51
- data/lib/mod_spox/Sockets.rb +76 -63
- data/lib/mod_spox/Timer.rb +21 -141
- data/lib/mod_spox/Version.rb +14 -0
- data/lib/mod_spox/handlers/BadNick.rb +1 -1
- data/lib/mod_spox/handlers/Bounce.rb +5 -5
- data/lib/mod_spox/handlers/Created.rb +13 -5
- data/lib/mod_spox/handlers/Handler.rb +12 -3
- data/lib/mod_spox/handlers/Invite.rb +14 -8
- data/lib/mod_spox/handlers/Join.rb +24 -20
- data/lib/mod_spox/handlers/Kick.rb +22 -13
- data/lib/mod_spox/handlers/Mode.rb +42 -36
- data/lib/mod_spox/handlers/Motd.rb +4 -0
- data/lib/mod_spox/handlers/Names.rb +66 -39
- data/lib/mod_spox/handlers/Nick.rb +20 -14
- data/lib/mod_spox/handlers/Part.rb +25 -8
- data/lib/mod_spox/handlers/Ping.rb +11 -5
- data/lib/mod_spox/handlers/Pong.rb +9 -5
- data/lib/mod_spox/handlers/Privmsg.rb +25 -17
- data/lib/mod_spox/handlers/Quit.rb +13 -8
- data/lib/mod_spox/handlers/Topic.rb +4 -0
- data/lib/mod_spox/handlers/Welcome.rb +16 -24
- data/lib/mod_spox/handlers/Who.rb +64 -48
- data/lib/mod_spox/handlers/Whois.rb +92 -60
- data/lib/mod_spox/messages/incoming/Nick.rb +2 -2
- data/lib/mod_spox/messages/incoming/Privmsg.rb +1 -1
- data/lib/mod_spox/messages/incoming/Whois.rb +1 -0
- data/lib/mod_spox/messages/internal/EstablishConnection.rb +1 -1
- data/lib/mod_spox/messages/internal/PluginsReady.rb +10 -0
- data/lib/mod_spox/messages/internal/QueueSocket.rb +8 -0
- data/lib/mod_spox/messages/internal/Reconnect.rb +8 -0
- data/lib/mod_spox/messages/internal/UnqueueSocket.rb +8 -0
- data/lib/mod_spox/migrations/002_persistent_sigs.rb +14 -0
- data/lib/mod_spox/migrations/003_auth_restructure.rb +31 -0
- data/lib/mod_spox/migrations/004_mode_index_fix.rb +18 -0
- data/lib/mod_spox/migrations/005_nick_mode_nopark.rb +18 -0
- data/lib/mod_spox/models/Auth.rb +16 -46
- data/lib/mod_spox/models/AuthMask.rb +13 -0
- data/lib/mod_spox/models/Channel.rb +46 -27
- data/lib/mod_spox/models/Config.rb +10 -19
- data/lib/mod_spox/models/Group.rb +20 -8
- data/lib/mod_spox/models/Models.rb +1 -1
- data/lib/mod_spox/models/Nick.rb +105 -113
- data/lib/mod_spox/models/NickMode.rb +23 -9
- data/lib/mod_spox/models/Server.rb +12 -1
- data/lib/mod_spox/models/Setting.rb +12 -16
- data/lib/mod_spox/models/Signature.rb +28 -8
- data/tests/BotHolder.rb +24 -0
- data/tests/handlers/tc_BadNick.rb +21 -0
- data/tests/handlers/tc_Created.rb +24 -0
- data/tests/handlers/tc_Invite.rb +50 -0
- data/tests/handlers/tc_Join.rb +33 -0
- data/tests/handlers/tc_Kick.rb +32 -0
- data/tests/handlers/tc_Mode.rb +85 -0
- data/tests/handlers/tc_Names.rb +35 -0
- data/tests/handlers/tc_Nick.rb +55 -0
- data/tests/handlers/tc_Part.rb +44 -0
- data/tests/handlers/tc_Ping.rb +40 -0
- data/tests/handlers/tc_Pong.rb +28 -0
- data/tests/handlers/tc_Privmsg.rb +85 -0
- data/tests/handlers/tc_Quit.rb +40 -0
- data/tests/handlers/tc_Who.rb +50 -0
- data/tests/handlers/tc_Whois.rb +61 -0
- data/tests/models/tc_Auth.rb +34 -0
- data/tests/models/tc_Channel.rb +52 -0
- data/tests/models/tc_Config.rb +19 -0
- data/tests/models/tc_Nick.rb +142 -0
- data/tests/models/tc_NickMode.rb +40 -0
- data/tests/models/tc_Setting.rb +21 -0
- data/tests/models/tc_Signature.rb +14 -0
- data/tests/run_tests.rb +4 -0
- metadata +284 -212
- data/README +0 -36
- data/lib/mod_spox/Cache.rb +0 -57
- data/lib/mod_spox/Monitors.rb +0 -84
- data/lib/mod_spox/Pool.rb +0 -164
- data/lib/mod_spox/models/AuthGroup.rb +0 -16
- data/lib/mod_spox/models/ChannelMode.rb +0 -14
- data/lib/mod_spox/models/NickChannel.rb +0 -45
- data/lib/mod_spox/models/NickGroup.rb +0 -16
data/lib/mod_spox/BotConfig.rb
CHANGED
|
@@ -20,11 +20,11 @@ module ModSpox
|
|
|
20
20
|
# :userconfigpath => path to the user configuration file
|
|
21
21
|
def BotConfig.populate(createdir=true)
|
|
22
22
|
gemname, gem = Gem.source_index.find{|name, spec|
|
|
23
|
-
spec.name == 'mod_spox' && spec.version.version =
|
|
23
|
+
spec.name == 'mod_spox' && spec.version.version = ModSpox.botversion
|
|
24
24
|
}
|
|
25
25
|
if(gem)
|
|
26
26
|
p = gem.full_gem_path
|
|
27
|
-
up =
|
|
27
|
+
up = ModSpox.mod_spox_path.nil? ? Etc.getpwnam(Etc.getlogin).dir : ModSpox.mod_spox.path
|
|
28
28
|
@@config = {:basepath => p,
|
|
29
29
|
:libpath => "#{p}/lib/mod_spox",
|
|
30
30
|
:datapath => "#{p}/data/mod_spox",
|
|
@@ -44,7 +44,7 @@ module ModSpox
|
|
|
44
44
|
config[:memcache] = get_input('Use memcache (EXPERIMENTAL): ', '(yes|no)', 'no')
|
|
45
45
|
valid_connection = false
|
|
46
46
|
until valid_connection do
|
|
47
|
-
config[:db_adapter] = get_input('Database type (pgsql): ', '(pgsql)', '
|
|
47
|
+
config[:db_adapter] = get_input('Database type (pgsql|sqlite|mysql): ', '(pgsql|sqlite|mysql)', 'sqlite')
|
|
48
48
|
unless(config[:db_adapter] == 'sqlite')
|
|
49
49
|
config[:db_username] = get_input('Database username: ', '.+', 'mod_spox')
|
|
50
50
|
config[:db_password] = get_input('Database password: ', '.*', nil)
|
|
@@ -63,8 +63,7 @@ module ModSpox
|
|
|
63
63
|
rescue Object => boom
|
|
64
64
|
puts 'Failed'
|
|
65
65
|
puts 'Error: Unexpected error encountered.'
|
|
66
|
-
puts "Info: #{boom
|
|
67
|
-
exit 1
|
|
66
|
+
puts "Info: #{boom}"
|
|
68
67
|
ensure
|
|
69
68
|
$stdout.flush
|
|
70
69
|
end
|
|
@@ -76,7 +75,7 @@ module ModSpox
|
|
|
76
75
|
puts 'mod_spox is now configured and ready for use'
|
|
77
76
|
rescue Object => boom
|
|
78
77
|
puts 'Failed'
|
|
79
|
-
puts "Error: #{boom}
|
|
78
|
+
puts "Error: #{boom}"
|
|
80
79
|
puts 'Please try running the configuration again'
|
|
81
80
|
end
|
|
82
81
|
end
|
|
@@ -89,11 +88,11 @@ module ModSpox
|
|
|
89
88
|
|
|
90
89
|
def test_connection(type, username=nil, password=nil, host=nil, name=nil)
|
|
91
90
|
case type
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
91
|
+
when 'mysql'
|
|
92
|
+
c = Sequel.mysql(name, :user => username, :password => password, :host => host)
|
|
93
|
+
c.test_connection
|
|
95
94
|
when 'pgsql'
|
|
96
|
-
c = Sequel.connect("#{
|
|
95
|
+
c = Sequel.connect("#{ModSpox.jdbc ? 'jdbc:' : ''}postgres://#{username}:#{password}@#{host}/#{name}")
|
|
97
96
|
c.test_connection
|
|
98
97
|
when 'sqlite'
|
|
99
98
|
return true
|
|
@@ -107,7 +106,7 @@ module ModSpox
|
|
|
107
106
|
config[key] = value if key.to_s =~ /^(db|memcache)/
|
|
108
107
|
end
|
|
109
108
|
config.write_configuration
|
|
110
|
-
initialize_bot
|
|
109
|
+
ModSpox.initialize_bot
|
|
111
110
|
require 'mod_spox/models/Models'
|
|
112
111
|
require 'mod_spox/Helpers'
|
|
113
112
|
Sequel::Migrator.apply(Database.db, BotConfig[:libpath] + '/migrations')
|
|
@@ -121,11 +120,12 @@ module ModSpox
|
|
|
121
120
|
s = Models::Server.find_or_create(:host => uconfig[:irc_server], :port => uconfig[:irc_port])
|
|
122
121
|
n = Models::Nick.find_or_create(:nick => uconfig[:admin_nick])
|
|
123
122
|
a = Models::Auth.find_or_create(:nick_id => n.pk)
|
|
124
|
-
|
|
123
|
+
g = Models::Group.find_or_create(:name => 'admin')
|
|
124
|
+
a.add_group(g)
|
|
125
125
|
a.password = uconfig[:admin_password]
|
|
126
126
|
a.save
|
|
127
127
|
t = Models::Trigger.find_or_create(:trigger => uconfig[:trigger])
|
|
128
|
-
t.
|
|
128
|
+
t.active = true
|
|
129
129
|
t.save
|
|
130
130
|
end
|
|
131
131
|
|
|
@@ -177,4 +177,4 @@ module ModSpox
|
|
|
177
177
|
|
|
178
178
|
end
|
|
179
179
|
|
|
180
|
-
end
|
|
180
|
+
end
|
data/lib/mod_spox/Database.rb
CHANGED
|
@@ -30,10 +30,7 @@ module ModSpox
|
|
|
30
30
|
end
|
|
31
31
|
|
|
32
32
|
def Database.reset_connections
|
|
33
|
-
|
|
34
|
-
Database.db.pool.allocated.each_pair do |thread, connection|
|
|
35
|
-
thread.kill
|
|
36
|
-
end
|
|
33
|
+
@@db.disconnect
|
|
37
34
|
end
|
|
38
35
|
|
|
39
36
|
def Database.reconnect
|
data/lib/mod_spox/Exceptions.rb
CHANGED
|
@@ -30,6 +30,32 @@ module ModSpox
|
|
|
30
30
|
|
|
31
31
|
class TimerInUse < BotException
|
|
32
32
|
end
|
|
33
|
+
|
|
34
|
+
class EmptyQueue < BotException
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
class Disconnected < BotException
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
class NotInChannel < BotException
|
|
41
|
+
attr_reader :channel
|
|
42
|
+
def initialize(channel)
|
|
43
|
+
@channel = channel
|
|
44
|
+
end
|
|
45
|
+
def to_s
|
|
46
|
+
"Bot is not currently in channel: #{@channel}"
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
class QuietChannel < BotException
|
|
51
|
+
attr_reader :channel
|
|
52
|
+
def initialize(channel)
|
|
53
|
+
@channel = channel
|
|
54
|
+
end
|
|
55
|
+
def to_s
|
|
56
|
+
"Bot is not allowed to speak in channel: #{@channel}"
|
|
57
|
+
end
|
|
58
|
+
end
|
|
33
59
|
|
|
34
60
|
end
|
|
35
61
|
end
|
data/lib/mod_spox/Helpers.rb
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
'mod_spox/models/Nick',
|
|
4
4
|
'mod_spox/models/Channel',
|
|
5
5
|
'mod_spox/models/Server',
|
|
6
|
-
'mod_spox/
|
|
6
|
+
'mod_spox/models/Models',
|
|
7
7
|
'mod_spox/Logger'].each{|f|require f}
|
|
8
8
|
|
|
9
9
|
module ModSpox
|
|
@@ -33,20 +33,20 @@ module ModSpox
|
|
|
33
33
|
# Converts bytes into easy human readable form
|
|
34
34
|
# O(1) version by Ryan "pizza_milkshake" Flynn
|
|
35
35
|
Suff = [
|
|
36
|
-
"", #
|
|
37
|
-
"Kilo", #
|
|
38
|
-
"Mega", #
|
|
39
|
-
"Giga", #
|
|
40
|
-
"Tera", #
|
|
41
|
-
"Peta", #
|
|
42
|
-
"Exa", #
|
|
43
|
-
"Zetta", #
|
|
44
|
-
"Yotta" #
|
|
36
|
+
"", # 1024^0
|
|
37
|
+
"Kilo", # 1024^1
|
|
38
|
+
"Mega", # 1024^2
|
|
39
|
+
"Giga", # 1024^3
|
|
40
|
+
"Tera", # 1024^4
|
|
41
|
+
"Peta", # 1024^5
|
|
42
|
+
"Exa", # 1024^6
|
|
43
|
+
"Zetta", # 1024^7
|
|
44
|
+
"Yotta" # 1024^8
|
|
45
45
|
]
|
|
46
46
|
def Helpers.format_size(bytes)
|
|
47
|
-
mag = (Math.log(bytes) / Math.log(
|
|
47
|
+
mag = (Math.log(bytes) / Math.log(1024)).floor
|
|
48
48
|
mag = [ Suff.length - 1, mag ].min
|
|
49
|
-
val = bytes.to_f / (
|
|
49
|
+
val = bytes.to_f / (1024 ** mag)
|
|
50
50
|
"%7.3f %sbyte%s" % [ val, Suff[mag], val == 1 ? "" : "s" ]
|
|
51
51
|
end
|
|
52
52
|
|
|
@@ -87,68 +87,29 @@ module ModSpox
|
|
|
87
87
|
# or channel name. If the string given does not match the required
|
|
88
88
|
# pattern for a channel or nick, the string is returned.
|
|
89
89
|
def Helpers.find_model(string, create=true)
|
|
90
|
-
|
|
90
|
+
result = nil
|
|
91
91
|
if(string =~ /^[A-Za-z\|\\\{\}\[\]\^\`~\_\-]+[A-Za-z0-9\|\\\{\}\[\]\^\`~\_\-]*$/)
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
Logger.warn("Nick returned from cache invalid. Expecting #{string} but got #{nick.nick}")
|
|
98
|
-
nick = nil
|
|
99
|
-
end
|
|
100
|
-
rescue Object => boom
|
|
101
|
-
Logger.info("Failed to grab cached nick: #{boom}")
|
|
102
|
-
end
|
|
103
|
-
end
|
|
104
|
-
unless(nick)
|
|
105
|
-
begin
|
|
106
|
-
nick = Models::Nick.locate(string, create)
|
|
107
|
-
if(nick.nil?)
|
|
108
|
-
Database.reconnect
|
|
109
|
-
return string
|
|
110
|
-
end
|
|
111
|
-
rescue Object => boom
|
|
112
|
-
Logger.warn("Caught an error. Assuming the database barfed: #{boom}")
|
|
113
|
-
Database.reconnect
|
|
114
|
-
end
|
|
115
|
-
@@nick_cache[string.downcase.to_sym] = nick.pk if nick.is_a?(Models::Nick)
|
|
116
|
-
Logger.info('Nick was retrieved from database')
|
|
117
|
-
end
|
|
118
|
-
return nick
|
|
119
|
-
elsif(string =~ /^[&#+!]/)
|
|
120
|
-
if(@@channel_cache.has_key?(string.downcase.to_sym))
|
|
121
|
-
begin
|
|
122
|
-
channel = Models::Channel[@@channel_cache[string.downcase.to_sym]]
|
|
123
|
-
if(string.downcase != channel.name.downcase)
|
|
124
|
-
Logger.warn("Channel returned from cache invalid. Expecting #{string} but got #{channel.name}")
|
|
125
|
-
channel = nil
|
|
126
|
-
end
|
|
127
|
-
rescue Object => boom
|
|
128
|
-
Logger.info("Failed to grab cached channel: #{boom}")
|
|
129
|
-
end
|
|
130
|
-
end
|
|
131
|
-
unless(channel)
|
|
132
|
-
channel = Models::Channel.locate(string, create)
|
|
133
|
-
if(channel.nil?)
|
|
134
|
-
Database.reconnect
|
|
135
|
-
return string
|
|
136
|
-
end
|
|
137
|
-
@@channel_cache[string.downcase.to_sym] = channel.pk if channel.is_a?(Models::Channel)
|
|
138
|
-
Logger.info('Channel was retrieved from database')
|
|
139
|
-
end
|
|
140
|
-
return channel
|
|
141
|
-
elsif(model = Models::Server.filter(:host => string, :connected => true).first)
|
|
142
|
-
return model
|
|
92
|
+
result = Models::Nick.find_or_create(:nick => string.downcase)
|
|
93
|
+
elsif(['&', '#', '+', '!'].include?(string[0]))
|
|
94
|
+
result = Models::Channel.find_or_create(:name => string.downcase)
|
|
95
|
+
elsif(Models::Server.filter(:host => string, :connected => true).count > 0)
|
|
96
|
+
result = Models::Server.filter(:host => string, :connected => true).first
|
|
143
97
|
else
|
|
144
98
|
Logger.warn("Failed to match string to model: #{string} -> No match")
|
|
145
|
-
return string
|
|
146
99
|
end
|
|
100
|
+
return result
|
|
147
101
|
end
|
|
148
102
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
103
|
+
# string:: string to convert
|
|
104
|
+
# Converts HTML entities found in a string
|
|
105
|
+
def Helpers.convert_entities(string)
|
|
106
|
+
begin
|
|
107
|
+
require 'htmlentities'
|
|
108
|
+
@@coder = HTMLEntities.new unless Helpers.class_variable_defined?(:@@coder)
|
|
109
|
+
return @@coder.decode(string)
|
|
110
|
+
rescue Object
|
|
111
|
+
return string
|
|
112
|
+
end
|
|
152
113
|
end
|
|
153
114
|
end
|
|
154
115
|
end
|
data/lib/mod_spox/Loader.rb
CHANGED
|
@@ -7,13 +7,13 @@
|
|
|
7
7
|
module ModSpox
|
|
8
8
|
|
|
9
9
|
# Loads all files needed by the bot
|
|
10
|
-
def initialize_bot
|
|
11
|
-
setup_adapter
|
|
10
|
+
def self.initialize_bot(db=nil)
|
|
11
|
+
setup_adapter(db)
|
|
12
12
|
check_upgrade
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
# Setup the DataMapper adapter
|
|
16
|
-
def setup_adapter
|
|
16
|
+
def self.setup_adapter(db=nil)
|
|
17
17
|
memcache = false
|
|
18
18
|
config = BaseConfig.new(BotConfig[:userconfigpath])
|
|
19
19
|
if(config[:memcache] == 'on')
|
|
@@ -26,36 +26,35 @@ module ModSpox
|
|
|
26
26
|
# do nothing #
|
|
27
27
|
end
|
|
28
28
|
end
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
29
|
+
unless(db.nil?)
|
|
30
|
+
Database.db = db
|
|
31
|
+
else
|
|
32
|
+
case config[:db_adapter]
|
|
33
|
+
when 'mysql'
|
|
34
|
+
Database.db = Sequel.mysql(config[:db_database], :user => config[:db_username],
|
|
35
|
+
:password => config[:db_password], :host => config[:db_host], :max_connections => 20)
|
|
36
|
+
Database.type = :mysql
|
|
37
|
+
when 'pgsql'
|
|
38
|
+
Database.db = Sequel.connect("#{ModSpox.jdbc ? 'jdbc:' : ''}postgres://#{config[:db_username]}:#{config[:db_password]}@#{config[:db_host]}/#{config[:db_database]}")
|
|
39
|
+
Database.type = :pgsql
|
|
40
|
+
when 'sqlite'
|
|
41
|
+
Database.db = Sequel.sqlite("#{BotConfig[:userpath]}/mod_spox.db", :pool_timeout => 20, :timeout => 5000)
|
|
42
|
+
Database.type = :sqlite
|
|
43
|
+
end
|
|
40
44
|
end
|
|
41
45
|
end
|
|
42
46
|
|
|
43
47
|
# check if the bot has been upgraded
|
|
44
|
-
def check_upgrade
|
|
48
|
+
def self.check_upgrade
|
|
49
|
+
Sequel::Migrator.apply(Database.db, BotConfig[:libpath] + '/migrations')
|
|
45
50
|
config = BaseConfig.new(BotConfig[:userconfigpath])
|
|
46
51
|
config[:plugin_upgrade] = 'no'
|
|
47
52
|
begin
|
|
48
|
-
|
|
53
|
+
config[:plugin_upgrade] = 'yes' if config[:last_version] != ModSpox.botversion
|
|
49
54
|
rescue Exceptions::UnknownKey => boom
|
|
50
|
-
|
|
55
|
+
config[:plugin_upgrade] = 'yes'
|
|
51
56
|
end
|
|
52
|
-
config[:last_version] =
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
# perform upgrade tasks
|
|
56
|
-
def do_upgrade(config)
|
|
57
|
-
Sequel::Migrator.apply(Database.db, BotConfig[:libpath] + '/migrations')
|
|
58
|
-
config[:plugin_upgrade] = 'yes'
|
|
57
|
+
config[:last_version] = ModSpox.botversion
|
|
59
58
|
end
|
|
60
59
|
|
|
61
60
|
end
|
data/lib/mod_spox/Logger.rb
CHANGED
|
@@ -3,32 +3,34 @@ module ModSpox
|
|
|
3
3
|
|
|
4
4
|
class Logger
|
|
5
5
|
|
|
6
|
-
def Logger.initialize(
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
levels = {:info => Object::Logger::INFO, :warn => Object::Logger::WARN, :fatal => Object::Logger::FATAL}
|
|
11
|
-
@@log = Object::Logger.new(output)
|
|
12
|
-
@@log.level = levels.has_key?(level) ? levels[level] : Object::Logger::WARN
|
|
13
|
-
end
|
|
6
|
+
def Logger.initialize(logger, level)
|
|
7
|
+
l = {:info => ::Logger::INFO, :error => ::Logger::ERROR, :warn => ::Logger::WARN, :fatal => ::Logger::FATAL}
|
|
8
|
+
@@log = logger.is_a?(::Logger) ? logger : nil
|
|
9
|
+
@@log.level = l[level]
|
|
14
10
|
end
|
|
15
11
|
|
|
16
12
|
def Logger.warn(s)
|
|
17
|
-
|
|
18
|
-
Pool << lambda{@@log.warn(s)}
|
|
19
|
-
end
|
|
13
|
+
@@log.warn(s) if Logger.log?
|
|
20
14
|
end
|
|
21
15
|
|
|
22
16
|
def Logger.info(s)
|
|
23
|
-
|
|
24
|
-
Pool << lambda{@@log.info(s)}
|
|
25
|
-
end
|
|
17
|
+
@@log.info(s) if Logger.log?
|
|
26
18
|
end
|
|
27
19
|
|
|
28
20
|
def Logger.fatal(s)
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
21
|
+
@@log.fatal(s) if Logger.log?
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def Logger.error(s)
|
|
25
|
+
@@log.error(s) if Logger.log?
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def Logger.log?
|
|
29
|
+
Logger.class_variable_defined?(:@@log)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def Logger.raw
|
|
33
|
+
Logger.log? ? @@log : nil
|
|
32
34
|
end
|
|
33
35
|
|
|
34
36
|
end
|
|
@@ -1,18 +1,21 @@
|
|
|
1
1
|
['mod_spox/handlers/Handler',
|
|
2
2
|
'mod_spox/Logger',
|
|
3
|
-
'mod_spox/Pipeline'
|
|
4
|
-
'mod_spox/Pool'].each{|f|require f}
|
|
3
|
+
'mod_spox/Pipeline'].each{|f|require f}
|
|
5
4
|
|
|
6
5
|
module ModSpox
|
|
7
6
|
|
|
8
7
|
class MessageFactory
|
|
9
8
|
|
|
9
|
+
# access to handlers. (only really needed for testing)
|
|
10
|
+
attr_reader :handlers
|
|
11
|
+
|
|
10
12
|
# pipeline:: Message pipeline
|
|
11
13
|
# Create a new MessageFactory
|
|
12
|
-
def initialize(pipeline)
|
|
14
|
+
def initialize(pipeline, pool)
|
|
13
15
|
@pipeline = pipeline
|
|
16
|
+
@pool = pool
|
|
17
|
+
@sync_pool = ActionPool::Pool.new(1, 1, nil, 2, Logger.raw)
|
|
14
18
|
@handlers = Hash.new
|
|
15
|
-
@lock = Mutex.new
|
|
16
19
|
build_handlers
|
|
17
20
|
@sync = [RPL_MOTDSTART, RPL_MOTD, RPL_ENDOFMOTD, RPL_WHOREPLY, RPL_ENDOFWHO,
|
|
18
21
|
RPL_NAMREPLY, RPL_ENDOFNAMES, RPL_WHOISUSER, RPL_WHOISSERVER, RPL_WHOISOPERATOR,
|
|
@@ -24,7 +27,28 @@ module ModSpox
|
|
|
24
27
|
# be processed thus there is now wait for processing to be
|
|
25
28
|
# completed.
|
|
26
29
|
def <<(string)
|
|
27
|
-
|
|
30
|
+
@pool.process{ parse_message(string) }
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# s:: string from server
|
|
34
|
+
# determine type of message from server
|
|
35
|
+
def find_key(s)
|
|
36
|
+
s = s.dup
|
|
37
|
+
begin
|
|
38
|
+
key = nil
|
|
39
|
+
if(s[0].chr == ':')
|
|
40
|
+
s.slice!(0..s.index(' '))
|
|
41
|
+
key = s.slice!(0..s.index(' ')-1)
|
|
42
|
+
else
|
|
43
|
+
key = s.slice(0..s.index(' ')-1)
|
|
44
|
+
end
|
|
45
|
+
key.strip!
|
|
46
|
+
key = key.to_sym if key.to_i == 0
|
|
47
|
+
return key
|
|
48
|
+
rescue Object
|
|
49
|
+
Logger.info("Failed to find key for message: #{s}")
|
|
50
|
+
raise Exceptions::UnknownKey.new
|
|
51
|
+
end
|
|
28
52
|
end
|
|
29
53
|
|
|
30
54
|
private
|
|
@@ -55,29 +79,31 @@ module ModSpox
|
|
|
55
79
|
def parse_message(message)
|
|
56
80
|
Logger.info("Processing message: #{message}")
|
|
57
81
|
begin
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
if(@
|
|
62
|
-
Logger.info("Message of type #{key}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
else
|
|
72
|
-
Pool << lambda do
|
|
73
|
-
message = @handlers[key].process(message)
|
|
74
|
-
@pipeline << message unless message.nil?
|
|
75
|
-
end
|
|
82
|
+
key = find_key(message)
|
|
83
|
+
if(@handlers.has_key?(key))
|
|
84
|
+
Logger.info("Message of type #{key} is now being handled by #{@handlers[key]}")
|
|
85
|
+
if(@sync.include?(key))
|
|
86
|
+
Logger.info("Message of type #{key} requires synchronized processing")
|
|
87
|
+
@sync_pool.process do
|
|
88
|
+
message = @handlers[key].process(message)
|
|
89
|
+
@pipeline << message unless message.nil?
|
|
90
|
+
end
|
|
91
|
+
else
|
|
92
|
+
@pool.process do
|
|
93
|
+
message = @handlers[key].process(message)
|
|
94
|
+
@pipeline << message unless message.nil?
|
|
76
95
|
end
|
|
77
96
|
end
|
|
97
|
+
else
|
|
98
|
+
Logger.error("No handler was found to process message of type: #{key} Message: #{message}")
|
|
78
99
|
end
|
|
79
100
|
rescue Object => boom
|
|
80
|
-
|
|
101
|
+
if(boom.class.to_s == 'SQLite3::BusyException' || boom.class.to_s == 'PGError')
|
|
102
|
+
Database.reset_connections
|
|
103
|
+
retry
|
|
104
|
+
else
|
|
105
|
+
Logger.warn("Failed to parse message from server: #{boom}\n#{boom.backtrace.join("\n")}")
|
|
106
|
+
end
|
|
81
107
|
end
|
|
82
108
|
end
|
|
83
109
|
|