177 lines
4.8 KiB
Plaintext
177 lines
4.8 KiB
Plaintext
{{Project Info|
|
|
About=Dient dem Anzeigen und Validieren aller pending Highscores in einem Privaten Raum. Benötigt [[Ruby-MediaWiki]].|
|
|
Lang=Ruby|
|
|
Source=https://wiki.c3d2.de/Xmotoctl#Source
|
|
}}
|
|
|
|
[[Category:Ruby]]
|
|
=xmotoctl.rb=
|
|
|
|
==Usage==
|
|
Für Replay 11154 wurde vorher ein schnelleres Replay im selben Level validiert, weshalb man dieses nicht mehr validieren kann. xmotoctl.rb kann dies ohne Hilfe eines neuronalen Netzes erkennen. ;-)
|
|
<pre style="clear:right">% ruby xmotoctl.rb 31 Astro *********************** validateall
|
|
Performing POST request
|
|
Performing GET request
|
|
Id | Level | Driver | Time |Current Best Time|Current Best Driver| Date |Somersaults|Replay|
|
|
-----+-----------------+-----------+-------+-----------------+-------------------+---------------+-----------+------+------
|
|
11251|Corea1 |Waldmeister|0:23:03|0:24:04 |Sven |22 october 2006|0 | |
|
|
11154|Joshua.wad: Round|Astro |0:18:18|0:06:35 |Waldmeister |21 october 2006|4 | |
|
|
Validating 11251...
|
|
Validating 11154...
|
|
Error: No validate action available
|
|
</pre>
|
|
==Source==
|
|
<pre>#!/usr/bin/env ruby
|
|
$: << 'ruby-mediawiki/lib/'
|
|
require 'mediawiki/minibrowser'
|
|
require 'htree'
|
|
require 'rexml/document'
|
|
class REXML::Element
|
|
def first_element(s)
|
|
each_element(s) { |e| return e }
|
|
nil
|
|
end
|
|
end
|
|
class HTTPDocument
|
|
def initialize(url, browser=MediaWiki::MiniBrowser.new(URI::parse(url)))
|
|
@url = url
|
|
@browser = browser
|
|
end
|
|
def perform_request
|
|
puts "Performing GET request"
|
|
@body = @browser.get_content(@url)
|
|
end
|
|
def body
|
|
perform_request unless @body
|
|
@body
|
|
end
|
|
def html
|
|
@html = HTree(body).to_rexml unless @html
|
|
@html
|
|
end
|
|
end
|
|
class HTTPPostDocument < HTTPDocument
|
|
def initialize(url, params)
|
|
@params = params
|
|
super(url)
|
|
end
|
|
def perform_request
|
|
puts "Performing POST request"
|
|
@body = @browser.post_content(@url, @params)
|
|
end
|
|
end
|
|
class Login < HTTPPostDocument
|
|
def initialize(id, username, password)
|
|
super("http://xmoto.free.fr/index.php", {:page=>:rooms, :action=>:change, :id_room=>id, :login=>username, :password=>password})
|
|
error = nil
|
|
html.each_element('//div[@class=\'message_erreur\']') { |div|
|
|
error = div.text
|
|
}
|
|
raise error if error
|
|
end
|
|
def highscoresvalidation
|
|
HighscoresValidation.new(@browser)
|
|
end
|
|
end
|
|
class HighscoresValidation < HTTPDocument
|
|
def initialize(browser)
|
|
super("http://xmoto.free.fr/index.php?page=highscoresvalidation", browser)
|
|
end
|
|
def table
|
|
html.first_element('//table[@class=\'admin_data\']')
|
|
end
|
|
def get_columns
|
|
res = []
|
|
table.each_element('tr[1]/th') { |th|
|
|
res << th.text
|
|
}
|
|
res
|
|
end
|
|
def columns
|
|
@columns = get_columns unless @columns
|
|
@columns
|
|
end
|
|
def get_highscores
|
|
res = []
|
|
table.each_element('tr[starts-with(@class, \'admin_data_line\')]') { |tr|
|
|
i = 0
|
|
row = {}
|
|
tr.each_element('td[@class=\'admin_data_multiple\']') { |td|
|
|
row[columns[i]] = td.text.strip if td.text
|
|
i += 1
|
|
}
|
|
res << row
|
|
}
|
|
res
|
|
end
|
|
def highscores
|
|
@highscores = get_highscores unless @highscores
|
|
@highscores
|
|
end
|
|
def dump_highscores
|
|
column_widths = {}
|
|
columns.each do |column|
|
|
width = column.size
|
|
highscores.each { |h|
|
|
width = h[column].size if (h[column]||'').size > width
|
|
}
|
|
column_widths[column] = width
|
|
end
|
|
puts columns.collect { |c|
|
|
c.center(column_widths[c])
|
|
}.join('|')
|
|
puts columns.collect { |c|
|
|
'-' * column_widths[c]
|
|
}.join('+')
|
|
highscores.each do |h|
|
|
puts columns.collect { |c|
|
|
value = h[c] || ''
|
|
value.ljust(column_widths[c])
|
|
}.join('|')
|
|
end
|
|
end
|
|
def highscore_actions(id)
|
|
res = nil
|
|
# TODO: Replace contains()
|
|
table.each_element('tr[starts-with(@class, \'admin_data_line\') and contains(td[1], '+id+')]') { |tr|
|
|
res = {}
|
|
tr.each_element('td[@class=\'admin_data_multiple\']/ul[@class=\'admin_submenu_actions\']/li/a') { |a|
|
|
res[a.attributes['title']] = a.attributes['href']
|
|
}
|
|
}
|
|
res
|
|
end
|
|
def validate(id)
|
|
actions = highscore_actions(id)
|
|
if actions['validate']
|
|
@browser.get_content('/' + actions['validate'])
|
|
else
|
|
raise 'No validate action available'
|
|
end
|
|
end
|
|
end
|
|
if ARGV.size < 3
|
|
puts "Usage: #{$0} <room id> <username> <password> [validateall]"
|
|
exit!
|
|
end
|
|
room_id, username, password = ARGV.shift, ARGV.shift, ARGV.shift
|
|
l = Login.new(room_id, username, password)
|
|
h = l.highscoresvalidation
|
|
h.dump_highscores
|
|
if ARGV.first == 'validateall'
|
|
h.highscores.each { |h1|
|
|
id = h1['Id']
|
|
puts "Validating #{id}..."
|
|
begin
|
|
h.validate(id)
|
|
rescue Exception => e
|
|
puts "Error: #{e}"
|
|
end
|
|
}
|
|
end
|
|
</pre>
|
|
|
|
|
|
|
|
{{Rübÿ Spëëd Mëtäl Cödïng}}
|