anthonyw-dyno 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/MIT-LICENSE +19 -0
- data/README.markdown +14 -0
- data/Rakefile +44 -0
- data/VERSION.yml +4 -0
- data/lib/dyno.rb +18 -0
- data/lib/dyno/competitor.rb +19 -0
- data/lib/dyno/event.rb +16 -0
- data/lib/dyno/parsers/race07_parser.rb +133 -0
- data/spec/competitor_spec.rb +74 -0
- data/spec/event_spec.rb +59 -0
- data/spec/fixtures/race07/full.ini +131 -0
- data/spec/fixtures/race07/header_no_track.ini +11 -0
- data/spec/fixtures/race07/header_only.ini +12 -0
- data/spec/fixtures/race07/no_header_section.ini +6 -0
- data/spec/fixtures/race07/no_steam_id.ini +37 -0
- data/spec/fixtures/race07/readme.markdown +5 -0
- data/spec/fixtures/race07/single_driver.ini +37 -0
- data/spec/parsers/race07_parser_spec.rb +143 -0
- data/spec/spec_helper.rb +3 -0
- metadata +85 -0
data/MIT-LICENSE
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Copyright (c) 2008 Anthony Williams
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
5
|
+
in the Software without restriction, including without limitation the rights
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in all
|
11
|
+
copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
19
|
+
SOFTWARE.
|
data/README.markdown
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
dyno
|
2
|
+
====
|
3
|
+
|
4
|
+
A Ruby library for parsing sim-racing results files. Presently supports:
|
5
|
+
|
6
|
+
* Race 07 / GTR: Evolution
|
7
|
+
|
8
|
+
With support for the following in the near future:
|
9
|
+
|
10
|
+
* rFactor
|
11
|
+
* LFS
|
12
|
+
* Arca
|
13
|
+
|
14
|
+
... once I've got my hands on some sample results files.
|
data/Rakefile
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'spec/rake/spectask'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |s|
|
7
|
+
s.name = 'dyno'
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.has_rdoc = true
|
10
|
+
s.summary = 'A rubygem for parsing sim-racing results files.'
|
11
|
+
s.description = s.summary
|
12
|
+
s.author = 'Anthony Williams'
|
13
|
+
s.email = 'anthony@ninecraft.com'
|
14
|
+
s.homepage = 'http://github.com/anthonyw/dyno'
|
15
|
+
|
16
|
+
s.extra_rdoc_files = ['README.markdown', 'MIT-LICENSE']
|
17
|
+
|
18
|
+
# Dependencies.
|
19
|
+
s.add_dependency "iniparse", ">= 0.2.0"
|
20
|
+
|
21
|
+
s.files = %w(MIT-LICENSE README.markdown Rakefile VERSION.yml) +
|
22
|
+
Dir.glob("{lib,spec}/**/*")
|
23
|
+
end
|
24
|
+
rescue LoadError
|
25
|
+
puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
|
26
|
+
end
|
27
|
+
|
28
|
+
################################################################################
|
29
|
+
# rSpec & rcov
|
30
|
+
################################################################################
|
31
|
+
|
32
|
+
desc "Run all examples"
|
33
|
+
Spec::Rake::SpecTask.new('spec') do |t|
|
34
|
+
t.spec_files = FileList['spec/**/*.rb']
|
35
|
+
t.spec_opts = ['-c -f s']
|
36
|
+
end
|
37
|
+
|
38
|
+
desc "Run all examples with RCov"
|
39
|
+
Spec::Rake::SpecTask.new('spec:rcov') do |t|
|
40
|
+
t.spec_files = FileList['spec/**/*.rb']
|
41
|
+
t.spec_opts = ['-c -f s']
|
42
|
+
t.rcov = true
|
43
|
+
t.rcov_opts = ['--exclude', 'spec']
|
44
|
+
end
|
data/VERSION.yml
ADDED
data/lib/dyno.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'time'
|
3
|
+
|
4
|
+
module Dyno
|
5
|
+
# Base exception class.
|
6
|
+
class DynoError < StandardError; end
|
7
|
+
|
8
|
+
# Raised if an input source couldn't be parsed, or was missing something.
|
9
|
+
class MalformedInputError < DynoError; end
|
10
|
+
end
|
11
|
+
|
12
|
+
%w( competitor event ).each do |file|
|
13
|
+
require File.join( File.dirname(__FILE__), "dyno", file )
|
14
|
+
end
|
15
|
+
|
16
|
+
Dir["#{ File.dirname(__FILE__) }/dyno/parsers/*_parser.rb"].sort.each do |parser|
|
17
|
+
require parser
|
18
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Dyno
|
2
|
+
class Competitor
|
3
|
+
attr_accessor :name, :uid, :position, :vehicle, :laps, :race_time,
|
4
|
+
:best_lap, :lap_times
|
5
|
+
|
6
|
+
##
|
7
|
+
# @param [String] name The competitor's name.
|
8
|
+
# @param [Hash] properties Extra information about the competitor.
|
9
|
+
#
|
10
|
+
def initialize(name, properties = {})
|
11
|
+
@name = name
|
12
|
+
@lap_times = properties.fetch(:laps, [])
|
13
|
+
|
14
|
+
[:uid, :position, :vehicle, :laps, :race_time, :best_lap].each do |prop|
|
15
|
+
instance_variable_set "@#{prop}", properties[prop]
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/dyno/event.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
module Dyno
|
2
|
+
class Event
|
3
|
+
attr_accessor :time, :game, :game_version, :track, :competitors
|
4
|
+
|
5
|
+
##
|
6
|
+
# @param [Hash] properties Event information.
|
7
|
+
#
|
8
|
+
def initialize(properties = {})
|
9
|
+
@time = properties.fetch( :time, Time.now )
|
10
|
+
@track = properties[:track]
|
11
|
+
@game = properties[:game]
|
12
|
+
@game_version = properties[:game_version]
|
13
|
+
@competitors = properties.fetch( :competitors, [] )
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,133 @@
|
|
1
|
+
require 'iniparse'
|
2
|
+
|
3
|
+
module Dyno::Parsers
|
4
|
+
##
|
5
|
+
# Parses a Race 07 results file (which appears to be some variation of the
|
6
|
+
# ini format).
|
7
|
+
#
|
8
|
+
# TODO: Remove dependency on inifile and write our own ini parser so that:
|
9
|
+
# * we can extract individual lap information.
|
10
|
+
# * we don't have to have a results file on disk.
|
11
|
+
#
|
12
|
+
class Race07Parser
|
13
|
+
##
|
14
|
+
# Takes a file path and parses it.
|
15
|
+
#
|
16
|
+
# @param [String] filename The path to the results file.
|
17
|
+
#
|
18
|
+
def self.parse_file( filename )
|
19
|
+
parse( IniParse.open( filename ) )
|
20
|
+
end
|
21
|
+
|
22
|
+
##
|
23
|
+
# Takes an IniFile instance, parses the contents, and returns a
|
24
|
+
# Dyno::Event containing your results.
|
25
|
+
#
|
26
|
+
# @param [IniFile] results The results.
|
27
|
+
# @return [Dyno::Event]
|
28
|
+
#
|
29
|
+
def self.parse( results )
|
30
|
+
new( results ).parse
|
31
|
+
end
|
32
|
+
|
33
|
+
##
|
34
|
+
# Returns your parsed event and competitor information.
|
35
|
+
#
|
36
|
+
def parse
|
37
|
+
parse_event!
|
38
|
+
parse_competitors!
|
39
|
+
@event
|
40
|
+
end
|
41
|
+
|
42
|
+
#######
|
43
|
+
private
|
44
|
+
#######
|
45
|
+
|
46
|
+
##
|
47
|
+
# Takes an IniFile instance and parses the contents.
|
48
|
+
#
|
49
|
+
# @param [IniFile] results The results.
|
50
|
+
#
|
51
|
+
def initialize( results )
|
52
|
+
@raw = results
|
53
|
+
end
|
54
|
+
|
55
|
+
##
|
56
|
+
# Extracts the event information from the results.
|
57
|
+
#
|
58
|
+
def parse_event!
|
59
|
+
raise Dyno::MalformedInputError unless @raw.has_section?('Header')
|
60
|
+
|
61
|
+
@event = Dyno::Event.new( :game => 'Race 07' )
|
62
|
+
@event.time = Time.parse( @raw['Header']['TimeString'] )
|
63
|
+
@event.game_version = @raw['Header']['Version']
|
64
|
+
|
65
|
+
# Extract the track name from Race/Scene
|
66
|
+
if @raw.has_section?('Race') && @raw['Race']['Scene']
|
67
|
+
@event.track = @raw['Race']['Scene'].split( '\\' )[-2].gsub( /[_-]+/, ' ' )
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
##
|
72
|
+
# Extracts information about each of the competitors.
|
73
|
+
#
|
74
|
+
def parse_competitors!
|
75
|
+
finished_competitors = []
|
76
|
+
dnf_competitors = []
|
77
|
+
|
78
|
+
@raw.each do |section|
|
79
|
+
# Competitor sections are named SlotNNN.
|
80
|
+
next unless section.key =~ /Slot\d\d\d/
|
81
|
+
|
82
|
+
competitor = Dyno::Competitor.new(section['Driver'],
|
83
|
+
:vehicle => section['Vehicle'],
|
84
|
+
:laps => section['Laps'].to_i
|
85
|
+
)
|
86
|
+
|
87
|
+
# Some results files have a blank ID.
|
88
|
+
if section['SteamId'] && section['SteamId'].kind_of?(Numeric)
|
89
|
+
competitor.uid = section['SteamId']
|
90
|
+
end
|
91
|
+
|
92
|
+
# Sort out the competitors lap times.
|
93
|
+
competitor.best_lap = lap_time_to_float(section['BestLap'])
|
94
|
+
|
95
|
+
competitor.lap_times = section['Lap'].map do |lap|
|
96
|
+
lap = lap.gsub(/\((.*)\)/, '\1')
|
97
|
+
lap_time_to_float(lap.split(',').last.strip)
|
98
|
+
end
|
99
|
+
|
100
|
+
if section['RaceTime'] == 'DNF'
|
101
|
+
competitor.race_time = 'DNF'
|
102
|
+
dnf_competitors << competitor
|
103
|
+
else
|
104
|
+
time = section['RaceTime'].split( /:|\./ )
|
105
|
+
|
106
|
+
competitor.race_time = time[2].to_f + ( time[1].to_i * 60 ) +
|
107
|
+
( time[0].to_i * 60 * 60 ) + "0.#{time[3]}".to_f
|
108
|
+
|
109
|
+
finished_competitors << competitor
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
# Sort finished competitors by their race time, lowest (P1) first.
|
114
|
+
finished_competitors = finished_competitors.sort_by { |c| c.race_time }
|
115
|
+
|
116
|
+
# ... and DNF'ed competitors by how many laps they've done.
|
117
|
+
dnf_competitors = dnf_competitors.sort_by { |c| c.laps }.reverse!
|
118
|
+
|
119
|
+
# Finally let's assign their finishing positions.
|
120
|
+
competitors = finished_competitors + dnf_competitors
|
121
|
+
competitors.each_with_index { |c, i| c.position = i + 1 }
|
122
|
+
|
123
|
+
# All done!
|
124
|
+
@event.competitors = competitors
|
125
|
+
end
|
126
|
+
|
127
|
+
# Converts a lap time (in the format of M:SS:SSS) to a float.
|
128
|
+
def lap_time_to_float(time)
|
129
|
+
time = time.split( /:|\./ )
|
130
|
+
time[1].to_f + ( time[0].to_i * 60 ) + "0.#{time[2]}".to_f
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
describe Dyno::Competitor do
|
4
|
+
before(:all) do
|
5
|
+
@competitor = Dyno::Competitor.new("Jake Lucas")
|
6
|
+
end
|
7
|
+
|
8
|
+
it 'should have a +name+ accessor' do
|
9
|
+
@competitor.should respond_to(:name)
|
10
|
+
@competitor.should respond_to(:name=)
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'should have a +uid+ accessor' do
|
14
|
+
@competitor.should respond_to(:uid)
|
15
|
+
@competitor.should respond_to(:uid=)
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'should have a +position+ accessor' do
|
19
|
+
@competitor.should respond_to(:position)
|
20
|
+
@competitor.should respond_to(:position=)
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should have a +vehicle+ accessor' do
|
24
|
+
@competitor.should respond_to(:vehicle)
|
25
|
+
@competitor.should respond_to(:vehicle=)
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'should have a +laps+ accessor' do
|
29
|
+
@competitor.should respond_to(:laps)
|
30
|
+
@competitor.should respond_to(:laps=)
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'should have a +race_time+ accessor' do
|
34
|
+
@competitor.should respond_to(:race_time)
|
35
|
+
@competitor.should respond_to(:race_time=)
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'should have a +best_lap+ accessor' do
|
39
|
+
@competitor.should respond_to(:best_lap)
|
40
|
+
@competitor.should respond_to(:best_lap=)
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'should respond_to #dnf?' do
|
44
|
+
pending do
|
45
|
+
@competitor.should respond_to(:dnf)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# ----------
|
50
|
+
# initialize
|
51
|
+
|
52
|
+
it 'should use the given values when creating a Event' do
|
53
|
+
properties = {
|
54
|
+
:uid => 1337,
|
55
|
+
:position => 3,
|
56
|
+
:vehicle => "BMW 320si E90 2007",
|
57
|
+
:laps => 13,
|
58
|
+
:race_time => "0:21:31.183",
|
59
|
+
:best_lap => "1:37.960"
|
60
|
+
}
|
61
|
+
|
62
|
+
competitor = Dyno::Competitor.new("Jake Lucas", properties)
|
63
|
+
competitor.name.should == "Jake Lucas"
|
64
|
+
|
65
|
+
properties.each do |prop, value|
|
66
|
+
competitor.send(prop).should == value
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'should require that a name be supplied' do
|
71
|
+
lambda { Dyno::Competitor.new }.should raise_error(ArgumentError)
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
data/spec/event_spec.rb
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
describe Dyno::Event do
|
4
|
+
before(:all) do
|
5
|
+
@event = Dyno::Event.new
|
6
|
+
end
|
7
|
+
|
8
|
+
it 'should have a +time+ accessor' do
|
9
|
+
@event.should respond_to(:time)
|
10
|
+
@event.should respond_to(:time=)
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'should have a +track+ accessor' do
|
14
|
+
@event.should respond_to(:track)
|
15
|
+
@event.should respond_to(:track=)
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'should have a +game+ accessor' do
|
19
|
+
@event.should respond_to(:game)
|
20
|
+
@event.should respond_to(:game=)
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should have a +game_version+ accessor' do
|
24
|
+
@event.should respond_to(:game_version)
|
25
|
+
@event.should respond_to(:game_version=)
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'should have a +competitors+ accessor' do
|
29
|
+
@event.should respond_to(:competitors)
|
30
|
+
@event.should respond_to(:competitors=)
|
31
|
+
end
|
32
|
+
|
33
|
+
# -----------
|
34
|
+
# #initialize
|
35
|
+
|
36
|
+
it 'should use the given values when creating a Event' do
|
37
|
+
event = Dyno::Event.new(
|
38
|
+
:time => Time.now - 10,
|
39
|
+
:track => "Anderstorp 2007",
|
40
|
+
:game => "Event 07",
|
41
|
+
:game_version => "1.1.1.14",
|
42
|
+
:competitors => [1]
|
43
|
+
)
|
44
|
+
|
45
|
+
event.time.should be_close(Time.now - 10, 0.5)
|
46
|
+
event.track.should == "Anderstorp 2007"
|
47
|
+
event.game.should == "Event 07"
|
48
|
+
event.game_version.should == "1.1.1.14"
|
49
|
+
event.competitors.should == [1]
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'should set a default time if none is given' do
|
53
|
+
Dyno::Event.new.time.should be_close(Time.now, 1)
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'should default competitors to [] if none are given' do
|
57
|
+
Dyno::Event.new.competitors.should == []
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,131 @@
|
|
1
|
+
[Header]
|
2
|
+
Game=RACE 07
|
3
|
+
Version=1.1.1.14
|
4
|
+
TimeString=2008/09/13 23:26:32
|
5
|
+
Aids=0,0,0,0,0,1,1,0,0
|
6
|
+
|
7
|
+
[Race]
|
8
|
+
RaceMode=5
|
9
|
+
Scene=GameData\Locations\Anderstorp_2007\2007_ANDERSTORP.TRK
|
10
|
+
AIDB=GameData\Locations\Anderstorp_2007\2007_ANDERSTORP.AIW
|
11
|
+
Race Length=0.100
|
12
|
+
Track Length=4018.8376
|
13
|
+
|
14
|
+
[Slot010]
|
15
|
+
Driver=Mark Voss
|
16
|
+
SteamUser=mvoss
|
17
|
+
SteamId=1865369
|
18
|
+
Vehicle=Chevrolet Lacetti 2007
|
19
|
+
Team=TEMPLATE_TEAM
|
20
|
+
QualTime=1:37.839
|
21
|
+
Laps=13
|
22
|
+
Lap=(0, -1.000, 1:48.697)
|
23
|
+
Lap=(1, 89.397, 1:39.455)
|
24
|
+
Lap=(2, 198.095, 1:38.060)
|
25
|
+
Lap=(3, 297.550, 1:38.632)
|
26
|
+
Lap=(4, 395.610, 1:38.031)
|
27
|
+
Lap=(5, 494.242, 1:39.562)
|
28
|
+
Lap=(6, 592.273, 1:39.950)
|
29
|
+
Lap=(7, 691.835, 1:38.366)
|
30
|
+
Lap=(8, 791.785, 1:39.889)
|
31
|
+
Lap=(9, 890.151, 1:39.420)
|
32
|
+
Lap=(10, 990.040, 1:39.401)
|
33
|
+
Lap=(11, 1089.460, 1:39.506)
|
34
|
+
Lap=(12, 1188.862, 1:40.017)
|
35
|
+
LapDistanceTravelled=3857.750244
|
36
|
+
BestLap=1:38.031
|
37
|
+
RaceTime=0:21:38.988
|
38
|
+
|
39
|
+
[Slot016]
|
40
|
+
Driver=Corey Ball
|
41
|
+
SteamUser=cball
|
42
|
+
SteamId=889853
|
43
|
+
Vehicle=SEAT Leon 2007
|
44
|
+
Team=TEMPLATE_TEAM
|
45
|
+
QualTime=1:37.904
|
46
|
+
Laps=9
|
47
|
+
Lap=(0, -1.000, 1:51.434)
|
48
|
+
Lap=(1, 89.397, 1:39.427)
|
49
|
+
Lap=(2, 200.831, 1:38.394)
|
50
|
+
Lap=(3, 300.258, 1:40.239)
|
51
|
+
Lap=(4, 398.653, 1:38.172)
|
52
|
+
Lap=(5, 498.891, 1:38.427)
|
53
|
+
Lap=(6, 597.063, 1:39.271)
|
54
|
+
Lap=(7, 695.490, 1:39.922)
|
55
|
+
Lap=(8, 794.761, 1:40.305)
|
56
|
+
LapDistanceTravelled=532.898193
|
57
|
+
BestLap=1:38.172
|
58
|
+
RaceTime=DNF
|
59
|
+
Reason=0
|
60
|
+
|
61
|
+
[Slot013]
|
62
|
+
Driver=Gabriel Lloyd
|
63
|
+
SteamUser=glloyd
|
64
|
+
SteamId=635
|
65
|
+
Vehicle=Chevrolet Lacetti 2007
|
66
|
+
Team=TEMPLATE_TEAM
|
67
|
+
QualTime=1:36.607
|
68
|
+
Laps=13
|
69
|
+
Lap=(0, -1.000, 1:50.816)
|
70
|
+
Lap=(1, 89.397, 1:38.835)
|
71
|
+
Lap=(2, 200.213, 1:38.082)
|
72
|
+
Lap=(3, 299.048, 1:38.367)
|
73
|
+
Lap=(4, 397.131, 1:37.825)
|
74
|
+
Lap=(5, 495.497, 1:38.757)
|
75
|
+
Lap=(6, 593.322, 1:38.718)
|
76
|
+
Lap=(7, 692.080, 1:38.478)
|
77
|
+
Lap=(8, 790.797, 1:39.347)
|
78
|
+
Lap=(9, 889.275, 1:38.713)
|
79
|
+
Lap=(10, 988.622, 1:38.952)
|
80
|
+
Lap=(11, 1087.336, 1:39.285)
|
81
|
+
Lap=(12, 1186.288, 1:40.555)
|
82
|
+
LapDistanceTravelled=3898.517578
|
83
|
+
BestLap=1:37.825
|
84
|
+
RaceTime=0:21:36.730
|
85
|
+
|
86
|
+
[Slot018]
|
87
|
+
Driver=Reino Lintula
|
88
|
+
SteamUser=rlintula
|
89
|
+
SteamId=1816
|
90
|
+
Vehicle=SEAT Leon 2007
|
91
|
+
Team=TEMPLATE_TEAM
|
92
|
+
QualTime=1:39.602
|
93
|
+
Laps=7
|
94
|
+
Lap=(0, -1.000, 1:52.788)
|
95
|
+
Lap=(1, 112.593, 1:39.346)
|
96
|
+
Lap=(2, 225.381, 1:40.680)
|
97
|
+
Lap=(3, 324.727, 1:38.775)
|
98
|
+
Lap=(4, 425.407, 1:40.149)
|
99
|
+
Lap=(5, 524.182, 1:41.551)
|
100
|
+
Lap=(6, 624.331, 1:46.908)
|
101
|
+
LapDistanceTravelled=1333.551270
|
102
|
+
BestLap=1:38.775
|
103
|
+
RaceTime=DNF
|
104
|
+
Reason=0
|
105
|
+
|
106
|
+
[Slot002]
|
107
|
+
Driver=Jerry Lalich
|
108
|
+
SteamUser=jlalich
|
109
|
+
SteamId=236892
|
110
|
+
Vehicle=Chevrolet Lacetti 2007
|
111
|
+
Team=TEMPLATE_TEAM
|
112
|
+
QualTime=1:38.081
|
113
|
+
Laps=13
|
114
|
+
Lap=(0, -1.000, 1:48.530)
|
115
|
+
Lap=(1, 89.397, 1:39.213)
|
116
|
+
Lap=(2, 197.927, 1:37.933)
|
117
|
+
Lap=(3, 297.140, 1:37.717)
|
118
|
+
Lap=(4, 395.073, 1:38.500)
|
119
|
+
Lap=(5, 492.790, 1:38.641)
|
120
|
+
Lap=(6, 591.290, 1:39.810)
|
121
|
+
Lap=(7, 689.931, 1:39.177)
|
122
|
+
Lap=(8, 789.742, 1:40.122)
|
123
|
+
Lap=(9, 888.918, 1:38.928)
|
124
|
+
Lap=(10, 989.040, 1:39.238)
|
125
|
+
Lap=(11, 1087.968, 1:39.223)
|
126
|
+
Lap=(12, 1187.206, 1:39.888)
|
127
|
+
LapDistanceTravelled=3892.720215
|
128
|
+
BestLap=1:37.717
|
129
|
+
RaceTime=0:21:36.920
|
130
|
+
|
131
|
+
[END]
|
@@ -0,0 +1,12 @@
|
|
1
|
+
[Header]
|
2
|
+
Game=RACE 07
|
3
|
+
Version=1.1.1.14
|
4
|
+
TimeString=2008/09/13 23:00:50
|
5
|
+
Aids=0,0,0,0,0,1,1,0,0
|
6
|
+
|
7
|
+
[Race]
|
8
|
+
RaceMode=5
|
9
|
+
Scene=GameData\Locations\Anderstorp_2007\2007_ANDERSTORP.TRK
|
10
|
+
AIDB=GameData\Locations\Anderstorp_2007\2007_ANDERSTORP.AIW
|
11
|
+
Race Length=0.100
|
12
|
+
Track Length=4018.8376
|
@@ -0,0 +1,37 @@
|
|
1
|
+
[Header]
|
2
|
+
Game=RACE 07
|
3
|
+
Version=1.1.1.14
|
4
|
+
TimeString=2008/09/13 23:26:32
|
5
|
+
Aids=0,0,0,0,0,1,1,0,0
|
6
|
+
|
7
|
+
[Race]
|
8
|
+
RaceMode=5
|
9
|
+
Scene=GameData\Locations\Anderstorp_2007\2007_ANDERSTORP.TRK
|
10
|
+
AIDB=GameData\Locations\Anderstorp_2007\2007_ANDERSTORP.AIW
|
11
|
+
Race Length=0.100
|
12
|
+
Track Length=4018.8376
|
13
|
+
|
14
|
+
[Slot013]
|
15
|
+
Driver=Gabriel Lloyd
|
16
|
+
SteamUser=
|
17
|
+
SteamId=
|
18
|
+
Vehicle=Chevrolet Lacetti 2007
|
19
|
+
Team=TEMPLATE_TEAM
|
20
|
+
QualTime=1:36.607
|
21
|
+
Laps=13
|
22
|
+
Lap=(0, -1.000, 1:50.816)
|
23
|
+
Lap=(1, 89.397, 1:38.835)
|
24
|
+
Lap=(2, 200.213, 1:38.082)
|
25
|
+
Lap=(3, 299.048, 1:38.367)
|
26
|
+
Lap=(4, 397.131, 1:37.825)
|
27
|
+
Lap=(5, 495.497, 1:38.757)
|
28
|
+
Lap=(6, 593.322, 1:38.718)
|
29
|
+
Lap=(7, 692.080, 1:38.478)
|
30
|
+
Lap=(8, 790.797, 1:39.347)
|
31
|
+
Lap=(9, 889.275, 1:38.713)
|
32
|
+
Lap=(10, 988.622, 1:38.952)
|
33
|
+
Lap=(11, 1087.336, 1:39.285)
|
34
|
+
Lap=(12, 1186.288, 1:40.555)
|
35
|
+
LapDistanceTravelled=3898.517578
|
36
|
+
BestLap=1:37.825
|
37
|
+
RaceTime=0:21:36.730
|
@@ -0,0 +1,37 @@
|
|
1
|
+
[Header]
|
2
|
+
Game=RACE 07
|
3
|
+
Version=1.1.1.14
|
4
|
+
TimeString=2008/09/13 23:26:32
|
5
|
+
Aids=0,0,0,0,0,1,1,0,0
|
6
|
+
|
7
|
+
[Race]
|
8
|
+
RaceMode=5
|
9
|
+
Scene=GameData\Locations\Anderstorp_2007\2007_ANDERSTORP.TRK
|
10
|
+
AIDB=GameData\Locations\Anderstorp_2007\2007_ANDERSTORP.AIW
|
11
|
+
Race Length=0.100
|
12
|
+
Track Length=4018.8376
|
13
|
+
|
14
|
+
[Slot013]
|
15
|
+
Driver=Gabriel Lloyd
|
16
|
+
SteamUser=glloyd
|
17
|
+
SteamId=635
|
18
|
+
Vehicle=Chevrolet Lacetti 2007
|
19
|
+
Team=TEMPLATE_TEAM
|
20
|
+
QualTime=1:36.607
|
21
|
+
Laps=13
|
22
|
+
Lap=(0, -1.000, 1:50.816)
|
23
|
+
Lap=(1, 89.397, 1:38.835)
|
24
|
+
Lap=(2, 200.213, 1:38.082)
|
25
|
+
Lap=(3, 299.048, 1:38.367)
|
26
|
+
Lap=(4, 397.131, 1:37.825)
|
27
|
+
Lap=(5, 495.497, 1:38.757)
|
28
|
+
Lap=(6, 593.322, 1:38.718)
|
29
|
+
Lap=(7, 692.080, 1:38.478)
|
30
|
+
Lap=(8, 790.797, 1:39.347)
|
31
|
+
Lap=(9, 889.275, 1:38.713)
|
32
|
+
Lap=(10, 988.622, 1:38.952)
|
33
|
+
Lap=(11, 1087.336, 1:39.285)
|
34
|
+
Lap=(12, 1186.288, 1:40.555)
|
35
|
+
LapDistanceTravelled=3898.517578
|
36
|
+
BestLap=1:37.825
|
37
|
+
RaceTime=0:21:36.730
|
@@ -0,0 +1,143 @@
|
|
1
|
+
require File.join( File.dirname(__FILE__), '..', 'spec_helper' )
|
2
|
+
|
3
|
+
describe Dyno::Parsers::Race07Parser do
|
4
|
+
|
5
|
+
it 'should respond to .parse' do
|
6
|
+
Dyno::Parsers::Race07Parser.should respond_to(:parse)
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'should respond to .parse_file' do
|
10
|
+
Dyno::Parsers::Race07Parser.should respond_to(:parse_file)
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'should respond to #parse' do
|
14
|
+
Dyno::Parsers::Race07Parser.public_instance_methods.should include('parse')
|
15
|
+
end
|
16
|
+
|
17
|
+
# --------------
|
18
|
+
# Event parsing.
|
19
|
+
|
20
|
+
describe 'parse_event!' do
|
21
|
+
before(:all) do
|
22
|
+
@event = Dyno::Parsers::Race07Parser.parse_file(
|
23
|
+
'spec/fixtures/race07/header_only.ini'
|
24
|
+
)
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'should set the game' do
|
28
|
+
@event.game.should == 'Race 07'
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'should correctly set the game version' do
|
32
|
+
# 1.1.1.14
|
33
|
+
@event.game_version.should == '1.1.1.14'
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'should correctly set the event time' do
|
37
|
+
# 2008/09/13 23:00:50
|
38
|
+
@event.time.should == Time.local(2008, 9, 13, 23, 00, 50)
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'should correctly set the track' do
|
42
|
+
@event.track.should == 'Anderstorp 2007'
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'should not set the track if one could not be discerned' do
|
46
|
+
event = Dyno::Parsers::Race07Parser.parse_file(
|
47
|
+
'spec/fixtures/race07/header_no_track.ini'
|
48
|
+
)
|
49
|
+
|
50
|
+
event.track.should be_nil
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'should whine loudly if there is no "Header" section' do
|
54
|
+
lambda {
|
55
|
+
Dyno::Parsers::Race07Parser.parse_file(
|
56
|
+
'spec/fixtures/race07/no_header_section.ini'
|
57
|
+
)
|
58
|
+
}.should raise_error(Dyno::MalformedInputError)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# -------------------
|
63
|
+
# Competitor parsing.
|
64
|
+
|
65
|
+
describe 'parse_competitors!' do
|
66
|
+
before(:all) do
|
67
|
+
@event = Dyno::Parsers::Race07Parser.parse_file(
|
68
|
+
'spec/fixtures/race07/single_driver.ini'
|
69
|
+
)
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'should set the driver name correctly' do
|
73
|
+
@event.competitors.first.name.should == 'Gabriel Lloyd'
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'should set the vehicle correctly' do
|
77
|
+
@event.competitors.first.vehicle.should == 'Chevrolet Lacetti 2007'
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'should set the steam id (uid) correctly' do
|
81
|
+
@event.competitors.first.uid.should == 635
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'should not set the steam id if one is not present' do
|
85
|
+
event = Dyno::Parsers::Race07Parser.parse_file(
|
86
|
+
'spec/fixtures/race07/no_steam_id.ini'
|
87
|
+
)
|
88
|
+
|
89
|
+
event.competitors.first.uid.should be_nil
|
90
|
+
end
|
91
|
+
|
92
|
+
it 'should set the lap count correctly' do
|
93
|
+
@event.competitors.first.laps.should == 13
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'should convert the race time to a float' do
|
97
|
+
@event.competitors.first.race_time.should == 1296.73
|
98
|
+
end
|
99
|
+
|
100
|
+
it 'should convert the best lap time to a float' do
|
101
|
+
@event.competitors.first.best_lap.should == 97.825
|
102
|
+
end
|
103
|
+
|
104
|
+
it "should correctly set the competitors lap times" do
|
105
|
+
@event.competitors.first.lap_times.should == [
|
106
|
+
110.816, # Lap=(0, -1.000, 1:50.816)
|
107
|
+
98.835, # Lap=(1, 89.397, 1:38.835)
|
108
|
+
98.082, # Lap=(2, 200.213, 1:38.082)
|
109
|
+
98.367, # Lap=(3, 299.048, 1:38.367)
|
110
|
+
97.825, # Lap=(4, 397.131, 1:37.825)
|
111
|
+
98.757, # Lap=(5, 495.497, 1:38.757)
|
112
|
+
98.718, # Lap=(6, 593.322, 1:38.718)
|
113
|
+
98.478, # Lap=(7, 692.080, 1:38.478)
|
114
|
+
99.347, # Lap=(8, 790.797, 1:39.347)
|
115
|
+
98.713, # Lap=(9, 889.275, 1:38.713)
|
116
|
+
98.952, # Lap=(10, 988.622, 1:38.952)
|
117
|
+
99.285, # Lap=(11, 1087.336, 1:39.285)
|
118
|
+
100.555 # Lap=(12, 1186.288, 1:40.555)
|
119
|
+
]
|
120
|
+
end
|
121
|
+
|
122
|
+
it 'should correctly sort drivers by their finishing time, and assign their position' do
|
123
|
+
event = Dyno::Parsers::Race07Parser.parse_file(
|
124
|
+
'spec/fixtures/race07/full.ini'
|
125
|
+
)
|
126
|
+
|
127
|
+
event.competitors[0].name.should == 'Gabriel Lloyd'
|
128
|
+
event.competitors[0].position.should == 1
|
129
|
+
|
130
|
+
event.competitors[1].name.should == 'Jerry Lalich'
|
131
|
+
event.competitors[1].position.should == 2
|
132
|
+
|
133
|
+
event.competitors[2].name.should == 'Mark Voss'
|
134
|
+
event.competitors[2].position.should == 3
|
135
|
+
|
136
|
+
event.competitors[3].name.should == 'Corey Ball'
|
137
|
+
event.competitors[3].position.should == 4
|
138
|
+
|
139
|
+
event.competitors[4].name.should == 'Reino Lintula'
|
140
|
+
event.competitors[4].position.should == 5
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: anthonyw-dyno
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.3
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Anthony Williams
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-01-15 00:00:00 -08:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: iniparse
|
17
|
+
version_requirement:
|
18
|
+
version_requirements: !ruby/object:Gem::Requirement
|
19
|
+
requirements:
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 0.2.0
|
23
|
+
version:
|
24
|
+
description: A rubygem for parsing sim-racing results files.
|
25
|
+
email: anthony@ninecraft.com
|
26
|
+
executables: []
|
27
|
+
|
28
|
+
extensions: []
|
29
|
+
|
30
|
+
extra_rdoc_files:
|
31
|
+
- README.markdown
|
32
|
+
- MIT-LICENSE
|
33
|
+
files:
|
34
|
+
- MIT-LICENSE
|
35
|
+
- README.markdown
|
36
|
+
- Rakefile
|
37
|
+
- VERSION.yml
|
38
|
+
- lib/dyno
|
39
|
+
- lib/dyno/competitor.rb
|
40
|
+
- lib/dyno/event.rb
|
41
|
+
- lib/dyno/parsers
|
42
|
+
- lib/dyno/parsers/race07_parser.rb
|
43
|
+
- lib/dyno.rb
|
44
|
+
- spec/competitor_spec.rb
|
45
|
+
- spec/event_spec.rb
|
46
|
+
- spec/fixtures
|
47
|
+
- spec/fixtures/race07
|
48
|
+
- spec/fixtures/race07/full.ini
|
49
|
+
- spec/fixtures/race07/header_no_track.ini
|
50
|
+
- spec/fixtures/race07/header_only.ini
|
51
|
+
- spec/fixtures/race07/no_header_section.ini
|
52
|
+
- spec/fixtures/race07/no_steam_id.ini
|
53
|
+
- spec/fixtures/race07/readme.markdown
|
54
|
+
- spec/fixtures/race07/single_driver.ini
|
55
|
+
- spec/parsers
|
56
|
+
- spec/parsers/race07_parser_spec.rb
|
57
|
+
- spec/spec_helper.rb
|
58
|
+
has_rdoc: true
|
59
|
+
homepage: http://github.com/anthonyw/dyno
|
60
|
+
post_install_message:
|
61
|
+
rdoc_options: []
|
62
|
+
|
63
|
+
require_paths:
|
64
|
+
- lib
|
65
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: "0"
|
70
|
+
version:
|
71
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: "0"
|
76
|
+
version:
|
77
|
+
requirements: []
|
78
|
+
|
79
|
+
rubyforge_project:
|
80
|
+
rubygems_version: 1.2.0
|
81
|
+
signing_key:
|
82
|
+
specification_version: 2
|
83
|
+
summary: A rubygem for parsing sim-racing results files.
|
84
|
+
test_files: []
|
85
|
+
|