Źródło BOINC Stats Parser'a

Publikuję tutaj źródło swojego programu - BSP 1.5, sczytującego dane do statystyk teamów w projektach BOINC. Program obejmuję licencją GPL wer.2. Do jego uruchomienia potrzebny jest interpreter języka Ruby (download: źródła dla Linuksa, One-Click Installer dla Windowsa). Wynikiem działania programu jest plik *.csv (do otwierania w arkuszach kalkulacyjnych, ";" jest separatorem kolumn), o strukturze:

struktura pliku wynikowego

pobrano o 12:34:56
Projekt1
TC;12345,67
Nazwa;TC;RAC
Użytkownik1;2222,22;222,22
Użytkownik2;1111,11;111,11
(...)

Projekt2
(...)

ustawienia


przykładowy adres: http://boinc.bakerlab.org/rosetta/team_display.php?teamid=1359

Program w przedstawionej postaci jest ustawiony do zbierania danych teamu InfoPC.pl. Postaram się teraz wyjaśnić, jak zmusić go do zbierania danych innych teamów, posługując się podanym wyżej adresem ze statystykami teamu InfoPC.pl w projekcie Rosetta. Obszarem naszych działań będzie sekcja module Ustawienia, przy czym nie będą nas interesować stałe zaczynające się od REG_. Jak widać, zajmiemy się więc stałymi PROJEKT, ADRES i TEAM_NR. Dwie ostatnie to tablice asocjacyjne. PROJEKT natomiast, jest tablicą z ich kluczami (skleja odpowiednie pola obydwu tablic asocjacyjnych). Jak widać tablica ADRES zawiera adresy stron poszczególnych projektów - czyli czerwoną część naszego adresu przykładowego. Część zielona nas nie interesuje, ponieważ we wszystkich projektach jest taka sama. Natomiast niebieski numer teamu podajemy w TEAM_NR. Tablica PROJEKT zawiera projekty (i ich kolejność), z których dane będziemy pobierać. Bardzo ważne jest, aby nazwy w PROJEKT, odpowiadały kluczom w tablicach asocjacyjnych. Same pozycje w tablicy PROJEKT, to tylko nazwy. Możemy tam podać np. seti1 i seti2, w TEAM_NR podać dla nich odpowiednie numery teamów, a w ADRES zdublować adresy - w ten sposób możemy zbierać statystyki kilku teamów, w ramach jednego projektu.

źródło BSP

#!/usr/bin/ruby
require "net/http"
require "uri"

czas = Time.new

module Ustawienia
   PROJEKT = ["seti", "predictor", "rosetta", "einstein", "climate"]
   ADRES = {"seti"=>"setiathome.berkeley.edu", "predictor"=>"predictor.scripps.edu", "rosetta"=>"boinc.bakerlab.org/rosetta", "einstein"=>"einstein.phys.uwm.edu", "climate"=>"climateapps2.oucs.ox.ac.uk/cpdnboinc"}
   TEAM_NR = {"seti"=>14, "predictor"=>610, "rosetta"=>1359, "einstein"=>4639, "climate"=>3897}
   REG_NAZWA = Regexp.new /\s<a href=show_user.php\?userid=[^>]+>([^<]+)/
   REG_STATS = Regexp.new /<td align=center>([0-9.,]+)<\/td>/
   REG_TEAMTC = Regexp.new /Total credit<\/td><td class=fieldvalue>([0-9.,]+)<\/td><\/tr>/
   REG_SPEC = Regexp.new /&[^ ;]+;/
end

class Array
   def ustaw_przecinek
      str = self.to_s
      str.delete! ","
      str.gsub! /\./, ","
   end
end

class Wpis
   attr_accessor :nazwa, :tc, :rac
   def initialize imie
      @nazwa = imie.to_s.gsub(Ustawienia::REG_SPEC, "")
      @tc
      @rac
   end
end

class Tabela
   attr_reader :tab, :team_tc
   def initialize
      @tab = Array.new
      @team_tc
   end
   def parsuj proj
      puts "Pobieram dane z projektu #{proj.capitalize}..."
      i = 0; p = 0
      while @tab[i-1] != nil or @team_tc == nil
         dane = Net::HTTP.get(URI.parse("http://#{Ustawienia::ADRES[proj]}/team_display.php?teamid=#{Ustawienia::TEAM_NR[proj]}&offset=#{i}"))
         if @team_tc == nil then @team_tc = (dane.scan Ustawienia::REG_TEAMTC).ustaw_przecinek end
         dane.scan Ustawienia::REG_NAZWA do |imie| @tab.push(Wpis.new(imie)) end
         j = i
         dane.scan Ustawienia::REG_STATS do |liczba|
            if p%2 == 0 then @tab[j].tc = liczba.ustaw_przecinek else
               @tab[j].rac = liczba.ustaw_przecinek
               j+=1
            end
            p+=1
         end
         i+=20
      end
      @tab
   end
end

puts "BOINC Stats Parser 1.5 by Sadi\nhttp://sadi.ovh.org/arty/bsp.php"
csv = File.new(czas.strftime("%d-%m-%Y.csv"), "w")
csv << "pobrano o " << czas.strftime("%H:%M:%S") << "\n"
Ustawienia::PROJEKT.each do |projekt|
   dane = Tabela.new
   dane.parsuj projekt
   csv << projekt.capitalize << "\nTC;" << dane.team_tc << "\nNazwa;TC;RAC\n"
   dane.tab.each do |osoba| csv << osoba.nazwa << ";" << osoba.tc << ";" << osoba.rac << "\n" end
   csv << "\n"
end
csv.close

czas = (Time.new - czas).to_s
puts "Ukonczono w #{czas.scan(/\d+\.\d{1,2}/)} sekund"

Niniejszy artykuł jest dostępny na licencji Creative Commons Uznanie autorstwa - Użycie niekomercyjne - Na tych samych warunkach 2.5 Polska. Źródło programu BSP objęte jest licencją GNU GPL wer.2.


<< Powrót

Komentarze:

Wszystkie przedstawione tutaj opinie należą do ich autorów i twórca strony nie ponosi żadnej odpowiedzialności za ich treść.


Imię/Ksywka (wymagane):

Strona WWW:

Wpisz tekst z obrazka (wymagane):

kod

Treść (wymagane):


W polu "Strona WWW" wpisywanie członu "http://" nie jest konieczne. Tagi (X)HTML wpisane w treści nie będą działać jako element strony, zamiast tego pojawią się w samym komentarzu. Komentarze obraźliwe, nie na temat lub niezgodne z prawem będą w miarę możliwości usuwane.

skiny: grey-tea green | light sky blue | carrot orange
some rights reserved | kanał informacyjny | admin | valid XHTML 1.0 | valid CSS | valid Atom 1.0