Xmotoctl

Aus C3D2
Version vom 22. Oktober 2006, 15:29 Uhr von Astro (Diskussion | Beiträge) (Usage: Dateinamen lügen)

Wechseln zu: Navigation, Suche


xmotoctl.rb

Dient dem Anzeigen und Validieren aller pending Highscores in einem Privaten Raum. Benötigt Ruby-MediaWiki.

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. ;-)

% 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

Source

#!/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