cricinfo 0.0.1 → 0.0.2
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/History.txt +5 -0
- data/Manifest.txt +1 -0
- data/README.rdoc +5 -1
- data/bin/cricinfo +28 -0
- data/lib/cricinfo.rb +11 -1
- data/lib/cricinfo/game.rb +16 -9
- data/lib/cricinfo/innings.rb +2 -1
- data/lib/cricinfo/scores.rb +55 -24
- data/spec/cricinfo_scores_spec.rb +50 -10
- metadata +28 -9
data/History.txt
CHANGED
data/Manifest.txt
CHANGED
data/README.rdoc
CHANGED
@@ -13,7 +13,11 @@ An interface to cricinfo.com game data (current games only).
|
|
13
13
|
== SYNOPSIS:
|
14
14
|
|
15
15
|
c = CricInfo::Scores.new
|
16
|
-
c.games.each { |
|
16
|
+
c.games.each { |game| puts game.summary }
|
17
|
+
|
18
|
+
game = c.games.first
|
19
|
+
puts game.inns1.runs
|
20
|
+
puts game.inns1.wickets
|
17
21
|
|
18
22
|
== INSTALL:
|
19
23
|
|
data/bin/cricinfo
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
$:.unshift File.dirname(__FILE__) + '/../lib'
|
4
|
+
require 'cricinfo'
|
5
|
+
|
6
|
+
def error(message)
|
7
|
+
puts "ERROR: #{message}"
|
8
|
+
end
|
9
|
+
|
10
|
+
def usage(exit = true)
|
11
|
+
puts "usage: cricinfo <command>"
|
12
|
+
exit 1 if exit
|
13
|
+
end
|
14
|
+
|
15
|
+
begin
|
16
|
+
command = ARGV[0]
|
17
|
+
usage unless command
|
18
|
+
|
19
|
+
case command
|
20
|
+
when 'list'
|
21
|
+
c = CricInfo::Scores.new
|
22
|
+
c.games.each { |game| puts game.summary }
|
23
|
+
else
|
24
|
+
error("unrecognised command #{command}")
|
25
|
+
usage
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
data/lib/cricinfo.rb
CHANGED
@@ -8,6 +8,16 @@ require 'cricinfo/game'
|
|
8
8
|
require 'cricinfo/scores'
|
9
9
|
|
10
10
|
module CricInfo
|
11
|
-
VERSION = '0.0.
|
11
|
+
VERSION = '0.0.2'
|
12
12
|
end
|
13
13
|
|
14
|
+
# array monkey patch
|
15
|
+
# http://snippets.dzone.com/posts/show/3332
|
16
|
+
class Array
|
17
|
+
def permutations
|
18
|
+
return [self] if size < 2
|
19
|
+
perm = []
|
20
|
+
each { |e| (self - [e]).permutations.each { |p| perm << ([e] + p) } }
|
21
|
+
perm
|
22
|
+
end
|
23
|
+
end
|
data/lib/cricinfo/game.rb
CHANGED
@@ -13,15 +13,25 @@ module CricInfo
|
|
13
13
|
|
14
14
|
include GameTypes
|
15
15
|
|
16
|
-
|
17
|
-
|
16
|
+
attr_accessor :start_time, :name, :type, :innings
|
17
|
+
# team1 is the team batting first (first innings)
|
18
|
+
attr_accessor :team1, :team2
|
18
19
|
|
19
20
|
def initialize
|
20
|
-
@
|
21
|
-
@inns2 = Innings.new
|
21
|
+
@innings = []
|
22
22
|
@type = GAMETYPE_ODI # assume ODI by default
|
23
23
|
end
|
24
24
|
|
25
|
+
def inns1; @innings[0]; end
|
26
|
+
def inns2; @innings[1]; end
|
27
|
+
def inns3; @innings[2]; end
|
28
|
+
def inns4; @innings[3]; end
|
29
|
+
|
30
|
+
def add_innings
|
31
|
+
@innings.push(Innings.new)
|
32
|
+
@innings[-1]
|
33
|
+
end
|
34
|
+
|
25
35
|
def type_string
|
26
36
|
gtype = ["Unknown game type", "Test match", "ODI", "T20"]
|
27
37
|
type >= 0 && type <= GAMETYPE_T20 ? gtype[type] : gtype[0]
|
@@ -30,11 +40,8 @@ module CricInfo
|
|
30
40
|
# returns a string summarising the game data
|
31
41
|
def summary
|
32
42
|
out = ''
|
33
|
-
out += "%s: %s v %s (%s)\n" % [name,
|
34
|
-
|
35
|
-
out += inns1.summary if inns1.summary
|
36
|
-
out += inns2.summary if inns2.summary
|
37
|
-
end
|
43
|
+
out += "%s: %s v %s (%s)\n" % [name, team1, team2, type_string]
|
44
|
+
out += innings.collect { |i| i.summary }.join
|
38
45
|
out
|
39
46
|
end
|
40
47
|
|
data/lib/cricinfo/innings.rb
CHANGED
@@ -7,7 +7,8 @@ module CricInfo
|
|
7
7
|
# returns a string summarising the innings data
|
8
8
|
def summary
|
9
9
|
return '' unless overs || runs # overs can be blank if innings over
|
10
|
-
out = "%s %d
|
10
|
+
out = "%s %d" % [team, runs]
|
11
|
+
out += "/%d" % [wickets] if wickets
|
11
12
|
out += " declared" if declared
|
12
13
|
out += " (%s ov)" % [overs] if overs
|
13
14
|
out += "\n"
|
data/lib/cricinfo/scores.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
|
1
2
|
module CricInfo
|
2
3
|
class Scores
|
3
4
|
include CricInfo::GameTypes
|
@@ -6,10 +7,11 @@ module CricInfo
|
|
6
7
|
SCORES_PATH = "/s/2497/Scores"
|
7
8
|
|
8
9
|
# match name, team1, team2, inningsdata, start_time
|
9
|
-
RE_MATCH = /matchId
|
10
|
+
RE_MATCH = /matchId=.*?">(.+?):\s*(\w+)\s+v\s+(\w+)<\/a>.*?<\/tr>(.*?)<\/tr>(.*?Start time (.*?)\s*<\/b>)?/
|
10
11
|
|
11
|
-
# team1/2,
|
12
|
-
|
12
|
+
# team1/2, i1runs, i1wickets, i1decl, i2wickets, i2decl, overs
|
13
|
+
# (overs optional)
|
14
|
+
RE_INNINGS = /<b>\s*(\w+)\s*<\/b>\s*<b>\s*(\d+)(?:\/(\d+))?(d)?(?:\s*&\s*(\d+)\/(\d+)(d)?)?\s*(?:\(([\d\.]+))?/
|
13
15
|
|
14
16
|
# start_time (e.g. Start time 09:30 GMT)
|
15
17
|
RE_START = /<b>\s*Start\s+time\s+(.*?)\s*<\/b>/
|
@@ -32,33 +34,28 @@ module CricInfo
|
|
32
34
|
|
33
35
|
game = Game.new
|
34
36
|
game.name = match_name
|
35
|
-
inns_count = 0
|
36
37
|
game.type = GAMETYPE_TEST if match_name.match(/Test/)
|
37
|
-
game.
|
38
|
-
game.
|
38
|
+
game.team1 = team1
|
39
|
+
game.team2 = team2
|
39
40
|
game.start_time = start ? Time.parse(start) : nil
|
40
41
|
|
41
42
|
# parse innings data
|
42
|
-
idata.scan(RE_INNINGS) do |
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
game.inns2.team = tmp
|
52
|
-
end
|
53
|
-
|
54
|
-
game.type = GAMETYPE_TEST if overs.to_f > Game::OVERS_ODI
|
55
|
-
|
56
|
-
inns.runs = runs.to_i
|
57
|
-
inns.wickets = wickets.to_i
|
58
|
-
inns.overs = overs
|
59
|
-
inns.declared = declared ? true : false
|
43
|
+
idata.scan(RE_INNINGS) do |data|
|
44
|
+
team, i1runs, i1wickets, i1decl, i2runs, i2wickets, i2decl, overs = *data
|
45
|
+
game.type = GAMETYPE_TEST if overs && overs.to_f > Game::OVERS_ODI
|
46
|
+
inns1 = add_innings(game, team, i1runs, i1wickets, i1decl)
|
47
|
+
inns2 = add_innings(game, team, i2runs, i2wickets, i2decl)
|
48
|
+
|
49
|
+
# overs given applies to the last innings
|
50
|
+
inns = inns2 ? inns2 : inns1
|
51
|
+
inns.overs = overs ? overs : nil
|
60
52
|
end
|
61
53
|
|
54
|
+
# rorder innings: attempt to guess innings order.
|
55
|
+
# find first valid permutation of innings order.
|
56
|
+
list = game.innings.permutations.detect { |i| valid_innings_order(i) }
|
57
|
+
game.innings = list if list
|
58
|
+
|
62
59
|
@games.push(game)
|
63
60
|
end
|
64
61
|
|
@@ -66,6 +63,40 @@ module CricInfo
|
|
66
63
|
|
67
64
|
private
|
68
65
|
|
66
|
+
# return true if the order of the list of innings is valid.
|
67
|
+
def valid_innings_order(list)
|
68
|
+
return true if list.length <= 1
|
69
|
+
|
70
|
+
# any innings with overs attached must be the last innings.
|
71
|
+
over_inns = list.detect { |i| i.overs }
|
72
|
+
return false if over_inns && over_inns != list[-1]
|
73
|
+
|
74
|
+
# the first and second innings must be different teams.
|
75
|
+
return false if list[0].team == list[1].team
|
76
|
+
|
77
|
+
# - a team can only bat twice in a row if it is following on.
|
78
|
+
# -- (a team can only follow on if it is > 200 runs behind)
|
79
|
+
(1...list.length).each do |i|
|
80
|
+
if list[i].team == list[i - 1].team
|
81
|
+
# team batted twice
|
82
|
+
return false unless list[i - 2].runs > list[i - 1].runs + 200
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
return true # innings order is valid
|
87
|
+
end
|
88
|
+
|
89
|
+
def add_innings(game, team, runs, wickets, decl)
|
90
|
+
return unless runs
|
91
|
+
|
92
|
+
inns = game.add_innings
|
93
|
+
inns.team = team
|
94
|
+
inns.runs = runs.to_i
|
95
|
+
inns.wickets = wickets ? wickets.to_i : 10
|
96
|
+
inns.declared = decl ? true : false
|
97
|
+
inns
|
98
|
+
end
|
99
|
+
|
69
100
|
def self.fetch_score_data
|
70
101
|
Net::HTTP.get(SCORES_HOST, SCORES_PATH) || ''
|
71
102
|
end
|
@@ -6,7 +6,7 @@ describe CricInfo::Scores do
|
|
6
6
|
FIXTURE_PATH = File.dirname(__FILE__) + '/fixtures'
|
7
7
|
|
8
8
|
# Scores1.html
|
9
|
-
it "should initialize and parse score data" do
|
9
|
+
it "should initialize and parse score data 1" do
|
10
10
|
CricInfo::Scores.should_receive(:fetch_score_data).and_return(fixture(1))
|
11
11
|
c = CricInfo::Scores.new
|
12
12
|
c.should_not be_nil
|
@@ -15,15 +15,15 @@ describe CricInfo::Scores do
|
|
15
15
|
game = c.games[0]
|
16
16
|
game.name.should == "5th ODI"
|
17
17
|
game.type.should == GAMETYPE_ODI
|
18
|
-
game.
|
19
|
-
game.
|
18
|
+
game.team1.should == "NZ"
|
19
|
+
game.team2.should == "AUS"
|
20
20
|
game.inns1.runs.should == 219
|
21
21
|
game.inns1.wickets.should == 8
|
22
22
|
game.inns1.overs.should == "46.4"
|
23
23
|
end
|
24
24
|
|
25
25
|
# Scores4.html
|
26
|
-
it "should initialize and parse score data" do
|
26
|
+
it "should initialize and parse score data 4" do
|
27
27
|
CricInfo::Scores.should_receive(:fetch_score_data).and_return(fixture(4))
|
28
28
|
c = CricInfo::Scores.new
|
29
29
|
c.should_not be_nil
|
@@ -32,8 +32,8 @@ describe CricInfo::Scores do
|
|
32
32
|
game = c.games[1]
|
33
33
|
game.name.should == "5th ODI"
|
34
34
|
game.type.should == GAMETYPE_ODI
|
35
|
-
game.
|
36
|
-
game.
|
35
|
+
game.team1.should == "NZ"
|
36
|
+
game.team2.should == "AUS"
|
37
37
|
game.inns1.runs.should == 241
|
38
38
|
game.inns1.wickets.should == 9
|
39
39
|
game.inns2.runs.should == 129
|
@@ -41,24 +41,64 @@ describe CricInfo::Scores do
|
|
41
41
|
game.inns2.overs.should == "33.3"
|
42
42
|
|
43
43
|
game = c.games[0] # not started
|
44
|
-
game.
|
45
|
-
game.
|
44
|
+
game.team1.should == "MUMB"
|
45
|
+
game.team2.should == "RTHAN"
|
46
46
|
game.start_time.should == Time.parse("09:30 GMT")
|
47
47
|
end
|
48
48
|
|
49
49
|
# Scores5.html
|
50
|
-
it "should initialize and parse score data" do
|
50
|
+
it "should initialize and parse score data 5" do
|
51
51
|
CricInfo::Scores.should_receive(:fetch_score_data).and_return(fixture(5))
|
52
52
|
c = CricInfo::Scores.new
|
53
53
|
c.should_not be_nil
|
54
54
|
|
55
55
|
c.games.length.should == 1
|
56
56
|
game = c.games[0] # BAN v ENG
|
57
|
-
game.
|
57
|
+
game.team1.should == "BAN"
|
58
|
+
game.team2.should == "ENG"
|
59
|
+
game.inns1.team.should == "ENG" # note: order different to game team names
|
58
60
|
game.inns2.team.should == "BAN"
|
59
61
|
game.inns1.declared.should == true
|
60
62
|
end
|
61
63
|
|
64
|
+
# Scores6.html
|
65
|
+
# 3 innings
|
66
|
+
it "should initialize and parse score data 6" do
|
67
|
+
CricInfo::Scores.should_receive(:fetch_score_data).and_return(fixture(6))
|
68
|
+
c = CricInfo::Scores.new
|
69
|
+
c.should_not be_nil
|
70
|
+
|
71
|
+
c.games.length.should == 2
|
72
|
+
game = c.games[1] # BAN v ENG
|
73
|
+
game.innings.length.should == 3
|
74
|
+
|
75
|
+
game.inns1.team.should == "ENG"
|
76
|
+
game.inns2.team.should == "BAN"
|
77
|
+
game.inns3.team.should == "ENG"
|
78
|
+
end
|
79
|
+
|
80
|
+
# Scores7.html (doctored from Scores6.html)
|
81
|
+
# 4 innings
|
82
|
+
it "should initialize and parse score data 7" do
|
83
|
+
CricInfo::Scores.should_receive(:fetch_score_data).and_return(fixture(7))
|
84
|
+
c = CricInfo::Scores.new
|
85
|
+
c.should_not be_nil
|
86
|
+
|
87
|
+
c.games.length.should == 2
|
88
|
+
game = c.games[1] # BAN v ENG
|
89
|
+
game.innings.length.should == 4
|
90
|
+
|
91
|
+
game.inns1.team.should == "ENG"
|
92
|
+
game.inns1.runs.should == 599
|
93
|
+
game.inns1.wickets.should == 6
|
94
|
+
game.inns1.declared.should == true
|
95
|
+
game.inns2.team.should == "BAN"
|
96
|
+
game.inns2.runs.should == 296
|
97
|
+
game.inns2.wickets.should == 10
|
98
|
+
game.inns3.team.should == "ENG"
|
99
|
+
game.inns4.team.should == "BAN"
|
100
|
+
end
|
101
|
+
|
62
102
|
private
|
63
103
|
|
64
104
|
def fixture(number)
|
metadata
CHANGED
@@ -1,7 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cricinfo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
hash: 27
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 2
|
10
|
+
version: 0.0.2
|
5
11
|
platform: ruby
|
6
12
|
authors:
|
7
13
|
- Andrew S Williams
|
@@ -9,19 +15,25 @@ autorequire:
|
|
9
15
|
bindir: bin
|
10
16
|
cert_chain: []
|
11
17
|
|
12
|
-
date: 2010-
|
18
|
+
date: 2010-07-14 00:00:00 +09:30
|
13
19
|
default_executable:
|
14
20
|
dependencies:
|
15
21
|
- !ruby/object:Gem::Dependency
|
16
22
|
name: hoe
|
17
|
-
|
18
|
-
|
19
|
-
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
20
26
|
requirements:
|
21
27
|
- - ">="
|
22
28
|
- !ruby/object:Gem::Version
|
29
|
+
hash: 5
|
30
|
+
segments:
|
31
|
+
- 2
|
32
|
+
- 3
|
33
|
+
- 3
|
23
34
|
version: 2.3.3
|
24
|
-
|
35
|
+
type: :development
|
36
|
+
version_requirements: *id001
|
25
37
|
description: An interface to cricinfo.com game data (current games only).
|
26
38
|
email:
|
27
39
|
- sobakasu@gmail.com
|
@@ -37,6 +49,7 @@ files:
|
|
37
49
|
- ./Manifest.txt
|
38
50
|
- ./README.rdoc
|
39
51
|
- ./Rakefile
|
52
|
+
- ./bin/cricinfo
|
40
53
|
- ./lib/cricinfo/game.rb
|
41
54
|
- ./lib/cricinfo/innings.rb
|
42
55
|
- ./lib/cricinfo/scores.rb
|
@@ -63,21 +76,27 @@ rdoc_options:
|
|
63
76
|
require_paths:
|
64
77
|
- lib
|
65
78
|
required_ruby_version: !ruby/object:Gem::Requirement
|
79
|
+
none: false
|
66
80
|
requirements:
|
67
81
|
- - ">="
|
68
82
|
- !ruby/object:Gem::Version
|
83
|
+
hash: 3
|
84
|
+
segments:
|
85
|
+
- 0
|
69
86
|
version: "0"
|
70
|
-
version:
|
71
87
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
88
|
+
none: false
|
72
89
|
requirements:
|
73
90
|
- - ">="
|
74
91
|
- !ruby/object:Gem::Version
|
92
|
+
hash: 3
|
93
|
+
segments:
|
94
|
+
- 0
|
75
95
|
version: "0"
|
76
|
-
version:
|
77
96
|
requirements: []
|
78
97
|
|
79
98
|
rubyforge_project: cricinfo
|
80
|
-
rubygems_version: 1.3.
|
99
|
+
rubygems_version: 1.3.7
|
81
100
|
signing_key:
|
82
101
|
specification_version: 3
|
83
102
|
summary: An interface to cricinfo.com game data (current games only).
|