mod_spox 0.1.0.1 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +36 -0
- data/INSTALL +2 -2
- data/README +0 -1
- data/bin/mod_spox +51 -12
- data/data/mod_spox/extras/AOLSpeak.rb +5 -18
- data/data/mod_spox/extras/AutoKick.rb +44 -23
- data/data/mod_spox/extras/AutoMode.rb +2 -5
- data/data/mod_spox/extras/AutoRejoin.rb +21 -0
- data/data/mod_spox/extras/Bouncer.rb +10 -10
- data/data/mod_spox/extras/Bytes.rb +12 -0
- data/data/mod_spox/extras/Confess.rb +131 -52
- data/data/mod_spox/extras/DCC.rb +189 -0
- data/data/mod_spox/extras/DevWatch.rb +32 -33
- data/data/mod_spox/extras/FloodKicker.rb +129 -0
- data/data/mod_spox/extras/GoogleIt.rb +13 -0
- data/data/mod_spox/extras/Headers.rb +31 -4
- data/data/mod_spox/extras/Karma.rb +103 -49
- data/data/mod_spox/extras/Logger.rb +45 -30
- data/data/mod_spox/extras/LolSpeak.rb +1 -1
- data/data/mod_spox/extras/NickServ.rb +83 -0
- data/data/mod_spox/extras/PhpCli.rb +12 -15
- data/data/mod_spox/extras/PhpFuncLookup.rb +57 -25
- data/data/mod_spox/extras/Quotes.rb +5 -4
- data/data/mod_spox/extras/RegexTracker.rb +160 -0
- data/data/mod_spox/extras/Roulette.rb +22 -23
- data/data/mod_spox/extras/Search.rb +3 -2
- data/data/mod_spox/extras/Slashdot.rb +35 -0
- data/data/mod_spox/extras/Topten.rb +5 -5
- data/data/mod_spox/extras/TracTicket.rb +68 -0
- data/data/mod_spox/extras/Translate.rb +69 -30
- data/data/mod_spox/extras/Twitter.rb +372 -0
- data/data/mod_spox/extras/UrbanDictionary.rb +21 -12
- data/data/mod_spox/extras/Weather.rb +1 -1
- data/data/mod_spox/plugins/Authenticator.rb +63 -30
- data/data/mod_spox/plugins/Banner.rb +164 -151
- data/data/mod_spox/plugins/Helper.rb +18 -7
- data/data/mod_spox/plugins/PluginLoader.rb +46 -22
- data/data/mod_spox/plugins/PoolConfig.rb +52 -0
- data/data/mod_spox/plugins/Quitter.rb +1 -1
- data/data/mod_spox/plugins/Status.rb +28 -0
- data/lib/mod_spox/Action.rb +20 -3
- data/lib/mod_spox/BaseConfig.rb +1 -0
- data/lib/mod_spox/Bot.rb +98 -75
- data/lib/mod_spox/BotConfig.rb +14 -6
- data/lib/mod_spox/ConfigurationWizard.rb +94 -105
- data/lib/mod_spox/Database.rb +33 -13
- data/lib/mod_spox/Helpers.rb +67 -38
- data/lib/mod_spox/Loader.rb +25 -5
- data/lib/mod_spox/Logger.rb +20 -62
- data/lib/mod_spox/MessageFactory.rb +34 -25
- data/lib/mod_spox/Monitors.rb +5 -0
- data/lib/mod_spox/Pipeline.rb +40 -51
- data/lib/mod_spox/Plugin.rb +40 -9
- data/lib/mod_spox/PluginManager.rb +46 -38
- data/lib/mod_spox/Pool.rb +129 -143
- data/lib/mod_spox/Socket.rb +41 -50
- data/lib/mod_spox/Sockets.rb +211 -0
- data/lib/mod_spox/Timer.rb +86 -69
- data/lib/mod_spox/handlers/BadNick.rb +1 -1
- data/lib/mod_spox/handlers/Created.rb +1 -1
- data/lib/mod_spox/handlers/Handler.rb +9 -0
- data/lib/mod_spox/handlers/Invite.rb +1 -1
- data/lib/mod_spox/handlers/Join.rb +2 -2
- data/lib/mod_spox/handlers/Kick.rb +1 -1
- data/lib/mod_spox/handlers/LuserChannels.rb +1 -1
- data/lib/mod_spox/handlers/LuserOp.rb +1 -1
- data/lib/mod_spox/handlers/LuserUnknown.rb +1 -1
- data/lib/mod_spox/handlers/Mode.rb +2 -2
- data/lib/mod_spox/handlers/MyInfo.rb +1 -1
- data/lib/mod_spox/handlers/Names.rb +1 -1
- data/lib/mod_spox/handlers/Nick.rb +20 -3
- data/lib/mod_spox/handlers/NickInUse.rb +3 -3
- data/lib/mod_spox/handlers/Notice.rb +5 -15
- data/lib/mod_spox/handlers/Part.rb +1 -1
- data/lib/mod_spox/handlers/Ping.rb +1 -1
- data/lib/mod_spox/handlers/Pong.rb +1 -1
- data/lib/mod_spox/handlers/Privmsg.rb +2 -2
- data/lib/mod_spox/handlers/Quit.rb +1 -1
- data/lib/mod_spox/handlers/Topic.rb +2 -1
- data/lib/mod_spox/handlers/Welcome.rb +3 -3
- data/lib/mod_spox/handlers/Who.rb +9 -7
- data/lib/mod_spox/handlers/Whois.rb +29 -16
- data/lib/mod_spox/handlers/YourHost.rb +1 -1
- data/lib/mod_spox/messages/incoming/Privmsg.rb +38 -19
- data/lib/mod_spox/messages/internal/DCCListener.rb +12 -0
- data/lib/mod_spox/messages/internal/DCCRequest.rb +12 -0
- data/lib/mod_spox/messages/internal/DCCSocket.rb +19 -0
- data/lib/mod_spox/messages/internal/StatusRequest.rb +2 -1
- data/lib/mod_spox/messages/outgoing/Privmsg.rb +21 -5
- data/lib/mod_spox/migrations/001_initialize_models.rb +115 -0
- data/lib/mod_spox/models/Auth.rb +24 -16
- data/lib/mod_spox/models/AuthGroup.rb +4 -3
- data/lib/mod_spox/models/Channel.rb +20 -12
- data/lib/mod_spox/models/ChannelMode.rb +2 -2
- data/lib/mod_spox/models/Config.rb +11 -3
- data/lib/mod_spox/models/Group.rb +6 -1
- data/lib/mod_spox/models/Nick.rb +93 -33
- data/lib/mod_spox/models/NickChannel.rb +8 -6
- data/lib/mod_spox/models/NickGroup.rb +16 -0
- data/lib/mod_spox/models/NickMode.rb +3 -3
- data/lib/mod_spox/models/Server.rb +6 -2
- data/lib/mod_spox/models/Setting.rb +12 -6
- data/lib/mod_spox/models/Signature.rb +7 -13
- data/lib/mod_spox/models/Trigger.rb +1 -1
- metadata +125 -100
@@ -0,0 +1,83 @@
|
|
1
|
+
class NickServ < ModSpox::Plugin
|
2
|
+
|
3
|
+
#TODO: Add support for things like RECOVERY and GHOST
|
4
|
+
|
5
|
+
def initialize(pipeline)
|
6
|
+
super
|
7
|
+
admin = Models::Group.find_or_create(:name => 'admin')
|
8
|
+
add_sig(:sig => 'nickserv address( \S+)?', :method => :set_address, :group => admin,
|
9
|
+
:desc => 'Set/view address to send nickserv info to', :params => [:address])
|
10
|
+
add_sig(:sig => 'nickserv combo (\S+) (\S+)', :method => :set_combo, :group => admin,
|
11
|
+
:desc => 'Set nick/pass combo', :params => [:nick, :password], :req => 'private')
|
12
|
+
add_sig(:sig => 'nickserv show', :method => :output_info, :group => admin,
|
13
|
+
:desc => 'Show nickserv info', :req => 'private')
|
14
|
+
add_sig(:sig => 'nickserv send', :method => :send_combo, :group => admin,
|
15
|
+
:desc => 'Send nickserv info')
|
16
|
+
@nickserv = Models::Setting.find_or_create(:name => 'nickserv').value
|
17
|
+
unless(@nickserv.is_a?(Hash) && @nickserv.has_key?(:address) && @nickserv.has_key?(:combos))
|
18
|
+
@nickserv = {:address => nil, :combos => {}}
|
19
|
+
end
|
20
|
+
@pipeline.hook(self, :send_nickserv, :Incoming_Welcome)
|
21
|
+
end
|
22
|
+
|
23
|
+
# @nickserv = {:address => 'nickserv@blah', :combos => {'nick' => 'pass'}}
|
24
|
+
|
25
|
+
def set_address(message, params)
|
26
|
+
if(params[:address])
|
27
|
+
params[:address].strip!
|
28
|
+
@nickserv[:address] = params[:address]
|
29
|
+
save_info
|
30
|
+
reply message.replyto, "Nickserv address updated to: #{params[:address]}"
|
31
|
+
else
|
32
|
+
unless(@nickserv[:address].nil?)
|
33
|
+
reply message.replyto, "Nickserv address set to: #{@nickserv[:address]}"
|
34
|
+
else
|
35
|
+
reply message.replyto, "\2Error:\2 Nickserv address has not been set"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def set_combo(message, params)
|
41
|
+
@nickserv[:combos][params[:nick].to_sym] = params[:password]
|
42
|
+
save_info
|
43
|
+
reply message.replyto, "Nickserv password saved for nick: \2#{params[:nick]}\2"
|
44
|
+
end
|
45
|
+
|
46
|
+
def output_info(message, params)
|
47
|
+
output = ["\2Nickserv information dump:\2"]
|
48
|
+
output << "Address used to send identification: #{@nickserv[:address].nil? ? 'unset' : @nickserv[:address]}"
|
49
|
+
@nickserv[:combos].each_pair{|k,v| output << "#{k} -> #{v}"}
|
50
|
+
reply message.replyto, output
|
51
|
+
end
|
52
|
+
|
53
|
+
def send_combo(message, params)
|
54
|
+
output = 'Identification sent to nickserv'
|
55
|
+
begin
|
56
|
+
identify
|
57
|
+
rescue Object => boom
|
58
|
+
output = boom.to_s
|
59
|
+
ensure
|
60
|
+
reply message.replyto, output
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def send_nickserv(m)
|
65
|
+
identify
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
|
70
|
+
def save_info
|
71
|
+
s = Models::Setting.filter(:name => 'nickserv').first.update(:value => @nickserv)
|
72
|
+
end
|
73
|
+
|
74
|
+
def identify
|
75
|
+
raise Exceptions::BotException.new('No address set for nickserv') if @nickserv[:address].nil?
|
76
|
+
if(@nickserv[:combos].has_key?(me.nick.to_sym))
|
77
|
+
@pipeline << Messages::Outgoing::Privmsg.new(@nickserv[:address], "IDENTIFY #{@nickserv[:combos][me.nick.to_sym]}")
|
78
|
+
else
|
79
|
+
raise Exceptions::BotException.new("No nickserv password available for: #{me.nick.nick}")
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
@@ -9,7 +9,7 @@ class PhpCli < ModSpox::Plugin
|
|
9
9
|
@path = Config[:plugin_directory] + '/phpcli'
|
10
10
|
@botini = @path + '/bot.ini'
|
11
11
|
unless(File.directory?(@path))
|
12
|
-
FileUtils.mkdir_p(@path)
|
12
|
+
FileUtils.mkdir_p(@path)
|
13
13
|
end
|
14
14
|
result = Helpers.safe_exec('which php')
|
15
15
|
raise NoInterpreter.new if result.empty?
|
@@ -18,21 +18,16 @@ class PhpCli < ModSpox::Plugin
|
|
18
18
|
ini.write($ini)
|
19
19
|
ini.close
|
20
20
|
end
|
21
|
-
php = Group.find_or_create(:name => '
|
21
|
+
php = Group.find_or_create(:name => 'php')
|
22
22
|
admin = Group.filter(:name => 'admin').first
|
23
23
|
Signature.find_or_create(:signature => 'php (on|off)', :plugin => name, :method => 'set_channel', :group_id => admin.pk,
|
24
24
|
:description => 'Add or remove channel from allowing PHP command').params = [:action]
|
25
25
|
Signature.find_or_create(:signature => 'php (?!on|off)(.+)', :plugin => name, :method => 'execute_php', :group_id => php.pk,
|
26
26
|
:description => 'Execute PHP code').params = [:code]
|
27
|
-
@channels = Setting.
|
28
|
-
|
29
|
-
Logger.log("WE ARE NIL PEOPLE")
|
30
|
-
@channels = []
|
31
|
-
else
|
32
|
-
@channels = @channels.value
|
33
|
-
end
|
27
|
+
@channels = Setting.filter(:name => 'phpcli').first
|
28
|
+
@channels = @channels.nil? ? [] : @channels.value
|
34
29
|
end
|
35
|
-
|
30
|
+
|
36
31
|
def set_channel(message, params)
|
37
32
|
return unless message.is_public?
|
38
33
|
if(params[:action] == 'on')
|
@@ -55,7 +50,7 @@ class PhpCli < ModSpox::Plugin
|
|
55
50
|
end
|
56
51
|
end
|
57
52
|
end
|
58
|
-
|
53
|
+
|
59
54
|
def execute_php(message, params)
|
60
55
|
return unless @channels.include?(message.target.pk)
|
61
56
|
filepath = @path + "/#{rand(99999)}.bot.php"
|
@@ -83,12 +78,14 @@ class PhpCli < ModSpox::Plugin
|
|
83
78
|
reply message.replyto, "Result: "+output
|
84
79
|
end
|
85
80
|
File.delete(filepath)
|
86
|
-
rescue
|
87
|
-
reply message.replyto, "\2Error:\2 Timeout reached
|
81
|
+
rescue Timeout::Error => boom
|
82
|
+
reply message.replyto, "\2Error:\2 Timeout reached: #{boom}"
|
83
|
+
rescue Object => boom
|
84
|
+
reply message.replyto, "\2Error:\2 Script execution terminated. (#{boom})"
|
88
85
|
File.delete(filepath)
|
89
86
|
end
|
90
87
|
end
|
91
|
-
|
88
|
+
|
92
89
|
class NoInterpreter < Exceptions::BotException
|
93
90
|
end
|
94
91
|
|
@@ -115,7 +112,7 @@ safe_mode_exec_dir = /tmp/mod_spox/php
|
|
115
112
|
safe_mode_allowed_env_vars = PHP_
|
116
113
|
safe_mode_protected_env_vars = LD_LIBRARY_PATH
|
117
114
|
open_basedir = /tmp/mod_spox
|
118
|
-
disable_functions = fscanf fputs chown chmod copy delete fflush file flock ftell glob link fseek lstat move_uploaded_file rename realpath set_file_buffer touch fprintf chgrp fgetss readfile dio_close dio_fnctl dio_open dio_read dio_seek dio_stat dio_tcsetattr dio_truncate dio_write chdir chroot dir closedir getcwd opendir readdir rewinddir scandir posix_kill posix_access posix_ctermid posix_get_last_error posix_getcwd posix_getegid posix_geteuid posix_getgid posix_getgrgid posix_getgrnam posix_getgroups posix_getlogin posix_getpgid posix_getpgrp posix_getpid posix_getppid posix_getpwnam posix_getpwuid posix_getwuid posix_getrlimit posix_getsid posix_getuid posix_isatty posix_mkfifo posix_mknod posix_setegid posix_setgid posix_setpgid posix_setsid posix_setuid posix_strerror posix_times posix_ttyname posix_uname expect_expectl expect_popen sleep time_sleep_until usleep pfsockopen fsockopen openlog debugger_on proc_open pclose popen fsockopen fread set_time_limit ini_set ini_alter ini_restore exec system passthru proc_close proc_nice proc_open proc_terminiate shell_exec sleep usleep pcntl_fork pcntl_exec pcntl_alarm pcntl_getpriority pcntl_setpriority pcntl_waitpid pcntl_wexitstatus pcntl_wifexited pcntl_wifsignaled pcntl_wifstopped pcntl_wstopsig pcntl_wtermsig readline_add_history readline_callback_handler_install readline_callback_handler_remove readline_callback_read_char readline_clear_history readline_completion_function readline_info readline_list_history readline_on_new_line readline_read_history readline_redisplay readline_write_history readline dl set_include_path set_magic_quotes_runtime file_put_contents fwrite fputs copy fputcsv tmpfile symlink tempnam mysql_connect unlink putenv ftp_connect socket_create socket_create socket_close socket_accept socket_bind socket_close socket_connect socket_create_listen socket_create_pair socket_get_option socket_listen socket_read socket_recv socket_select socket_send socket_sendto shmop_close shmop_open shmop_delete shmop_read shmop_size shmop_write msg_get_queue msg_receive msg_remove_queue msg_send msg_set_queue msg_stat_queue msg_acquire sem_aquire sem_release sem_get sem_remove mail time_nanosleep usleep
|
115
|
+
disable_functions = fscanf fputs chown chmod copy delete fflush file flock ftell glob link fseek lstat move_uploaded_file rename realpath set_file_buffer touch fprintf chgrp fgetss readfile dio_close dio_fnctl dio_open dio_read dio_seek dio_stat dio_tcsetattr dio_truncate dio_write chdir chroot dir closedir getcwd opendir readdir rewinddir scandir posix_kill posix_access posix_ctermid posix_get_last_error posix_getcwd posix_getegid posix_geteuid posix_getgid posix_getgrgid posix_getgrnam posix_getgroups posix_getlogin posix_getpgid posix_getpgrp posix_getpid posix_getppid posix_getpwnam posix_getpwuid posix_getwuid posix_getrlimit posix_getsid posix_getuid posix_isatty posix_mkfifo posix_mknod posix_setegid posix_setgid posix_setpgid posix_setsid posix_setuid posix_strerror posix_times posix_ttyname posix_uname expect_expectl expect_popen sleep time_sleep_until usleep pfsockopen fsockopen openlog debugger_on proc_open pclose popen fsockopen fread set_time_limit ini_set ini_alter ini_restore exec system passthru proc_close proc_nice proc_open proc_terminiate shell_exec sleep usleep pcntl_fork pcntl_exec pcntl_alarm pcntl_getpriority pcntl_setpriority pcntl_waitpid pcntl_wexitstatus pcntl_wifexited pcntl_wifsignaled pcntl_wifstopped pcntl_wstopsig pcntl_wtermsig readline_add_history readline_callback_handler_install readline_callback_handler_remove readline_callback_read_char readline_clear_history readline_completion_function readline_info readline_list_history readline_on_new_line readline_read_history readline_redisplay readline_write_history readline dl set_include_path set_magic_quotes_runtime file_put_contents fwrite fputs copy fputcsv tmpfile symlink tempnam mysql_connect unlink putenv ftp_connect socket_create socket_create socket_close socket_accept socket_bind socket_close socket_connect socket_create_listen socket_create_pair socket_get_option socket_listen socket_read socket_recv socket_select socket_send socket_sendto shmop_close shmop_open shmop_delete shmop_read shmop_size shmop_write msg_get_queue msg_receive msg_remove_queue msg_send msg_set_queue msg_stat_queue msg_acquire sem_aquire sem_release sem_get sem_remove mail time_nanosleep usleep include include_once require require_once ftp_alloc ftp_cdup ftp_chdir ftp_chmod ftp_close ftp_connect ftp_delete ftp_exec ftp_fget ftp_fput ftp_get ftp_get_option ftp_login ftp_mdtm ftp_mkdir ftp_nb_continue ftp_nb_fget ftp_nb_fput ftp_nb_get ftp_nb_put
|
119
116
|
disable_classes = dir
|
120
117
|
expose_php = On
|
121
118
|
max_execution_time = 10
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'cgi'
|
2
|
+
require 'open-uri'
|
2
3
|
|
3
4
|
# Inspired from an old plugin for the original mod_spox
|
4
5
|
# Original development: spox & Ryan "pizza_milkshake" Flynn
|
@@ -79,12 +80,14 @@ class PhpFuncLookup < ModSpox::Plugin
|
|
79
80
|
|
80
81
|
def phpfunc(m, params)
|
81
82
|
name = params[:name].downcase
|
82
|
-
Logger.
|
83
|
+
Logger.info "phpfunc name=#{name}"
|
83
84
|
if name =~ /^\S+$/ && name =~ /\*/
|
84
85
|
parse_wildcard(m, name)
|
85
86
|
elsif name =~ /^\$/
|
86
|
-
parse_predefined(m, name)
|
87
|
-
elsif name =~ /^\S+$/ && filename =
|
87
|
+
parse_predefined(m, name)
|
88
|
+
elsif name =~ /^\S+$/ && filename = find_control_file(name)
|
89
|
+
parse_control(m, name, filename)
|
90
|
+
elsif name =~ /^\S+$/ && filename = find_function_file(name)
|
88
91
|
parse_function(m, name, filename)
|
89
92
|
elsif @ops.has_key?(name)
|
90
93
|
parse_operator(m, name)
|
@@ -93,7 +96,7 @@ class PhpFuncLookup < ModSpox::Plugin
|
|
93
96
|
|
94
97
|
def fetch(m, params)
|
95
98
|
reply m.replyto, "Fetching PHP manual (This could take a few minutes)"
|
96
|
-
fetch_manual
|
99
|
+
fetch_manual(m)
|
97
100
|
end
|
98
101
|
|
99
102
|
def listen(m)
|
@@ -147,26 +150,27 @@ class PhpFuncLookup < ModSpox::Plugin
|
|
147
150
|
|
148
151
|
private
|
149
152
|
|
150
|
-
def
|
153
|
+
def find_function_file(name)
|
151
154
|
Dir.new(@manual).each do |filename|
|
152
155
|
return filename if filename.downcase == "function.#{name.gsub(/(_|->)/, '-').downcase}.html"
|
153
156
|
end
|
154
157
|
return nil
|
155
158
|
end
|
159
|
+
|
160
|
+
def find_control_file(name)
|
161
|
+
Dir.new(@manual).each do |filename|
|
162
|
+
return filename if filename.downcase == "control-structures.#{name}.html"
|
163
|
+
end
|
164
|
+
return nil
|
165
|
+
end
|
156
166
|
|
157
167
|
def fetch_manual(message=nil, params=nil)
|
158
168
|
Thread.new do
|
159
|
-
|
160
|
-
|
161
|
-
connection = Net::HTTP.new("us.php.net", 80)
|
162
|
-
File.open("#{@path}/manual.tar.gz", 'w'){ |manual|
|
163
|
-
connection.get('/distributions/manual/php_manual_en.tar.gz', nil){ |line|
|
164
|
-
manual.write(line)
|
165
|
-
}
|
166
|
-
}
|
169
|
+
Logger.info 'Fetching PHP manual from http://us.php.net'
|
170
|
+
open("#{@path}/manual.tar.gz", 'w').write(open('http://us.php.net/distributions/manual/php_manual_en.tar.gz').read)
|
167
171
|
Dir.chdir(@path)
|
168
172
|
Helpers.safe_exec("tar -xzf #{@path}/manual.tar.gz", 60)
|
169
|
-
Logger.
|
173
|
+
Logger.info "PHP manual fetching complete."
|
170
174
|
reply message.replyto, "PHP manual fetch is now complete" unless message.nil?
|
171
175
|
end
|
172
176
|
end
|
@@ -200,9 +204,9 @@ class PhpFuncLookup < ModSpox::Plugin
|
|
200
204
|
|
201
205
|
def parse_wildcard(m, name)
|
202
206
|
matches = []
|
203
|
-
pattern = name.gsub(/\*/, '.*?')
|
207
|
+
pattern = name.gsub(/\*/, '.*?').gsub(/_/, '-')
|
204
208
|
Dir.open(@manual).each do |file|
|
205
|
-
if(file =~ /^(
|
209
|
+
if(file =~ /^(function\.#{pattern})\.html/)
|
206
210
|
match = $1
|
207
211
|
if(match =~ /^function\.(.+?)\-/)
|
208
212
|
if(@classlist.include?($1.downcase))
|
@@ -211,11 +215,9 @@ class PhpFuncLookup < ModSpox::Plugin
|
|
211
215
|
else
|
212
216
|
match.gsub!(/[-]/, '_')
|
213
217
|
end
|
214
|
-
match.gsub!(/^function\./, '')
|
215
|
-
else
|
216
|
-
match = nil
|
217
218
|
end
|
218
|
-
|
219
|
+
match.gsub!(/^function\./, '')
|
220
|
+
matches << match unless match.empty?
|
219
221
|
end
|
220
222
|
end
|
221
223
|
matches.sort!
|
@@ -223,6 +225,7 @@ class PhpFuncLookup < ModSpox::Plugin
|
|
223
225
|
if(matches.empty?)
|
224
226
|
output = "\2Error:\2 No matches found"
|
225
227
|
else
|
228
|
+
output << "Matches against term: \2#{name}:\2"
|
226
229
|
output << matches.values_at(0..19).join(', ')
|
227
230
|
end
|
228
231
|
reply m.replyto, output
|
@@ -233,7 +236,7 @@ class PhpFuncLookup < ModSpox::Plugin
|
|
233
236
|
page.gsub!(/[\r\n]/, '')
|
234
237
|
versions = page =~ /<p class="verinfo">(.+?)<\/p>/i ? $1 : '(UNKNOWN)'
|
235
238
|
proto = page =~ /<div class="methodsynopsis dc-description">(.+?)<\/div>/i ? $1 : name
|
236
|
-
desc = page =~ /<p class="
|
239
|
+
desc = page =~ /<p class="(para rdfs-comment|simpara)">(.+?)<\/p>/i ? $2.strip : '(UNKNOWN)'
|
237
240
|
versions = CGI::unescapeHTML(versions)
|
238
241
|
proto = CGI::unescapeHTML(proto.gsub(/<.+?>/, ' ').gsub(/[\s]+/, ' '))
|
239
242
|
desc = CGI::unescapeHTML(desc.gsub(/<.+?>/, ' ').gsub(/[\s]+/, ' '))
|
@@ -245,13 +248,42 @@ class PhpFuncLookup < ModSpox::Plugin
|
|
245
248
|
end
|
246
249
|
|
247
250
|
def parse_operator(m, name)
|
248
|
-
Logger.
|
251
|
+
Logger.info "parse_operator name=#{name}"
|
249
252
|
name.downcase!
|
250
253
|
type, title, ejemplo = @ops[name]
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
+
if(title.is_a?(Array))
|
255
|
+
output = ["\2#{name}\2 is the \2#{title.join("\2 or \2")}\2 operator"]
|
256
|
+
if(ejemplo.is_a?(Array))
|
257
|
+
(0..(ejemplo.size - 1)).each do |i|
|
258
|
+
output << "\2Example (#{type[i]}):\2 #{ejemplo[i]}"
|
259
|
+
end
|
260
|
+
elsif(!ejemplo.nil?)
|
261
|
+
output << "\2Example (#{type}):\2 #{ejemplo}"
|
262
|
+
end
|
263
|
+
type.each do |t|
|
264
|
+
output << "http://php.net/manual/en/language.operators.#{t}.php"
|
265
|
+
end
|
266
|
+
else
|
267
|
+
output = ["\2#{name}\2 is the \2#{title}\2 operator"]
|
268
|
+
output << "\2Example usage:\2 #{ejemplo}" unless ejemplo.nil? || ejemplo.empty?
|
269
|
+
output << "http://php.net/manual/en/language.operators.#{type}.php"
|
254
270
|
end
|
271
|
+
reply m.replyto, output
|
272
|
+
end
|
273
|
+
|
274
|
+
def parse_control(m, name, filename)
|
275
|
+
page = File.open("#{@manual}/#{filename}", 'r').readlines.join('')
|
276
|
+
page.gsub!(/[\r\n]/, '')
|
277
|
+
con = page =~ /<h2 class="title"><i>([^<]+)</ ? $1 : '(UNKNOWN)'
|
278
|
+
par = page =~ /^.+?<p class="para">(.+?)<div/ ? $1.strip : '(UNKNOWN)'
|
279
|
+
Logger.info("Match: #{par}")
|
280
|
+
par = par.gsub(/<.+?>/, ' ').gsub(/\s{2,}/, ' ')
|
281
|
+
par.gsub!(/\.[^\.]+:$/, '.')
|
282
|
+
#par.slice!(0..199) if par.size > 200
|
283
|
+
output = ["\2Control structure: #{con}\2"]
|
284
|
+
output << par
|
285
|
+
output << "http://www.php.net/manual/en/#{filename.gsub(/\.html$/, '.php')}"
|
286
|
+
reply m.replyto, output
|
255
287
|
end
|
256
288
|
|
257
289
|
def populate_classes
|
@@ -23,15 +23,16 @@ class Quotes < ModSpox::Plugin
|
|
23
23
|
if(params[:term] =~ /^\d+$/)
|
24
24
|
quote = Quote[params[:term].to_i]
|
25
25
|
else
|
26
|
-
|
26
|
+
ids = Quote.filter(:quote => Regexp.new(params[:term], Regexp::IGNORECASE)).map(:id)
|
27
|
+
quote = Quote[ids[rand(ids.size)].to_i]
|
27
28
|
reg = true
|
28
29
|
end
|
29
30
|
else
|
30
31
|
ids = Quote.select(:id).map(:id)
|
31
|
-
quote = Quote[ids[rand(ids.size
|
32
|
+
quote = Quote[ids[rand(ids.size)].to_i]
|
32
33
|
end
|
33
34
|
if(quote)
|
34
|
-
reply message.replyto, "\2[\2#{quote.pk}\2|\2#{quote.added.year}/#{sprintf('%02d', quote.added.month)}/#{sprintf('%02d', quote.added.day)}\2]:\2 #{reg ? quote.quote.gsub(/(#{params[:term]})
|
35
|
+
reply message.replyto, "\2[\2#{quote.pk}\2|\2#{quote.added.year}/#{sprintf('%02d', quote.added.month)}/#{sprintf('%02d', quote.added.day)}\2]:\2 #{reg ? quote.quote.gsub(/(#{params[:term]})/i, "\2\\1\2") : quote.quote}"
|
35
36
|
else
|
36
37
|
reply message.replyto, "\2Error:\2 Failed to find quote"
|
37
38
|
end
|
@@ -46,7 +47,7 @@ class Quotes < ModSpox::Plugin
|
|
46
47
|
end
|
47
48
|
|
48
49
|
def searchquote(message, params)
|
49
|
-
result = Quote.filter(:quote => Regexp.new(params[:term]))
|
50
|
+
result = Quote.filter(:quote => Regexp.new(params[:term], Regexp::IGNORECASE))
|
50
51
|
if(result.size > 0)
|
51
52
|
ids = result.map(:id)
|
52
53
|
ids.sort!
|
@@ -0,0 +1,160 @@
|
|
1
|
+
class RegexTracker < ModSpox::Plugin
|
2
|
+
|
3
|
+
include Models
|
4
|
+
def initialize(pipeline)
|
5
|
+
super
|
6
|
+
track = Group.find_or_create(:name => 'track')
|
7
|
+
add_sig(:sig => 'track info (\d+)', :method => :score, :desc => 'Show info on regex tracking',
|
8
|
+
:params => [:id])
|
9
|
+
add_sig(:sig => 'track list(\s\S+)?', :method => :list, :desc => 'List currently tracked regex', :params => [:channel])
|
10
|
+
add_sig(:sig => 'track add (.+)', :method => :add, :desc => 'Add new regex for tracking',
|
11
|
+
:params => [:regex], :group => track)
|
12
|
+
add_sig(:sig => 'track remove (\d+)', :method => :remove, :desc => 'Remove regex from tracking',
|
13
|
+
:params => [:id], :group => track)
|
14
|
+
add_sig(:sig => 'track modify (\d+) (.+)', :method => :modify, :desc => 'Modify regex',
|
15
|
+
:params => [:id, :regex], :group => track)
|
16
|
+
@pipeline.hook(self, :check, :Incoming_Privmsg)
|
17
|
+
TrackInfo.create_table unless TrackInfo.table_exists?
|
18
|
+
@cache = {}
|
19
|
+
build_cache
|
20
|
+
end
|
21
|
+
|
22
|
+
def check(message)
|
23
|
+
return unless @cache.has_key?(message.target.pk.to_i)
|
24
|
+
time = Time.now
|
25
|
+
@cache[message.target.pk.to_i].each do |t|
|
26
|
+
if(message.message =~ /#{t[:regex]}/)
|
27
|
+
ti = TrackInfo[t[:id]]
|
28
|
+
if(ti.last_score.year != time.year || ti.last_score.yday != time.yday)
|
29
|
+
ti.score_today = 0
|
30
|
+
end
|
31
|
+
ti.last_score = Time.now
|
32
|
+
ti.score_today += 1
|
33
|
+
ti.score_total += 1
|
34
|
+
ti.save
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def list(message, params)
|
40
|
+
output = ''
|
41
|
+
begin
|
42
|
+
raise 'No channel given for list' if message.is_private? && !params[:channel]
|
43
|
+
channel = params[:channel] ? Helpers.find_model(params[:channel].strip, false) : message.target
|
44
|
+
if(TrackInfo.filter(:channel_id => channel.pk).count > 0)
|
45
|
+
output = []
|
46
|
+
output << "\2Currently tracked regexs in #{channel.name}"
|
47
|
+
TrackInfo.filter(:channel_id => channel.pk).each do |t|
|
48
|
+
output << "\2ID:\2 #{t.pk} --- \2REGEX:\2 #{t.regex}"
|
49
|
+
end
|
50
|
+
else
|
51
|
+
output = 'Error: Nothing is currently being tracked'
|
52
|
+
end
|
53
|
+
rescue Object => boom
|
54
|
+
output = "Error: #{boom}"
|
55
|
+
ensure
|
56
|
+
reply message.replyto, output
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def add(message, params)
|
61
|
+
output = ''
|
62
|
+
begin
|
63
|
+
r = Regexp.new(params[:regex])
|
64
|
+
t = TrackInfo.new
|
65
|
+
t.regex = params[:regex]
|
66
|
+
t.channel = message.target
|
67
|
+
t.last_score = Time.now
|
68
|
+
t.save
|
69
|
+
build_cache
|
70
|
+
output = "New regex has been added for tracking (ID: #{t.pk})"
|
71
|
+
rescue Object => boom
|
72
|
+
output = "Failed to save regex: #{boom}"
|
73
|
+
ensure
|
74
|
+
reply message.replyto, output
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def remove(message, params)
|
79
|
+
id = params[:id].to_i
|
80
|
+
tis = TrackInfo.filter(:id => id)
|
81
|
+
if(tis.count > 0)
|
82
|
+
tis.destroy
|
83
|
+
build_cache
|
84
|
+
reply message.replyto, "Regex has been removed (ID: #{id})"
|
85
|
+
else
|
86
|
+
reply message.replyto, "Failed to find regex being tracked with ID: #{id}"
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def modify(message, params)
|
91
|
+
id = params[:id].to_i
|
92
|
+
tis = TrackInfo.filter(:id => id)
|
93
|
+
output = ''
|
94
|
+
begin
|
95
|
+
r = Regexp.new(params[:regex])
|
96
|
+
if(tis.count > 0)
|
97
|
+
t = tis.first
|
98
|
+
t.regex = params[:regex]
|
99
|
+
t.save
|
100
|
+
build_cache
|
101
|
+
output = "Regex has been update (ID: #{t.pk})"
|
102
|
+
else
|
103
|
+
output = "Failed to locate tracking regex (ID: #{id})"
|
104
|
+
end
|
105
|
+
rescue Object => boom
|
106
|
+
output = "Failed to save regex. #{boom}"
|
107
|
+
ensure
|
108
|
+
reply message.replyto, output
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def score(message, params)
|
113
|
+
id = params[:id].to_i
|
114
|
+
t = TrackInfo.filter(:id => id).first
|
115
|
+
if(t)
|
116
|
+
reply message.replyto, "\2(#{id})\2: Regex: #{t.regex}, Today: #{t.score_today}, Total: #{t.score_total}, Last occurance: #{t.last_score}"
|
117
|
+
else
|
118
|
+
reply message.replyto, "Failed to find tracking regex with ID: #{id}"
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
def build_cache
|
123
|
+
@cache = {}
|
124
|
+
TrackInfo.all.each do |t|
|
125
|
+
@cache[t.channel_id.to_i] = [] unless @cache.has_key?(t.channel_id.to_i)
|
126
|
+
@cache[t.channel_id.to_i] << {:id => t.pk, :regex => t.regex}
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
class TrackInfo < Sequel::Model
|
131
|
+
set_schema do
|
132
|
+
primary_key :id, :null => false
|
133
|
+
varchar :regex, :null => false
|
134
|
+
integer :score_total, :null => false, :default => 0
|
135
|
+
integer :score_today, :null => false, :default => 0
|
136
|
+
timestamp :last_score, :null => false
|
137
|
+
foreign_key :channel_id, :table => :channels, :null => false
|
138
|
+
index [:regex, :channel_id], :unique => true
|
139
|
+
end
|
140
|
+
|
141
|
+
def channel
|
142
|
+
Channel[channel_id]
|
143
|
+
end
|
144
|
+
|
145
|
+
def channel=(chan)
|
146
|
+
raise Exceptions::InvalidType.new('Channel model was expected') unless chan.is_a?(Models::Channel)
|
147
|
+
values[:channel_id] = chan.pk
|
148
|
+
end
|
149
|
+
|
150
|
+
def regex=(r)
|
151
|
+
r = [Marshal.dump(r)].pack('m')
|
152
|
+
super(r)
|
153
|
+
end
|
154
|
+
|
155
|
+
def regex
|
156
|
+
values[:regex] ? Marshal.load(values[:regex].unpack('m')[0]) : nil
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
end
|