Xmotoctl

Aus C3D2
Version vom 25. November 2006, 21:58 Uhr von Astro (Diskussion | Beiträge) (Mit Project Info)

Wechseln zu: Navigation, Suche


Xmotoctl
Dient dem Anzeigen und Validieren aller pending Highscores in einem Privaten Raum. Benötigt Ruby-MediaWiki.
Home: https://wiki.c3d2.de/Xmotoctl
Meta
Sprachen:Ruby
Plattformen:Beliebig
Links

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

% 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


Speed metal coding 64x64.jpg
Rübÿ Spëëd Mëtäl Cödïng
Coders: Astro | Conny | Sven
Projects: CacaANSICam | Date Determinator | DVB-Scraping | Filmnächte-Scraping | GeeKal | Gruntmaster | Harvester | Hirn | Irb | Jargon-File | Ruby-MediaWiki | Miniwebserver | Momomoto | Pentabarf | Podcast-fetching | Ruby | Ruby-Geekend | Ruby und Ruby on Rails | Sedusa | VDS-Badges | Xmotoctl | Youtube-Scraping