icu_tournament 1.2.3 → 1.2.4
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/README.rdoc +2 -2
- data/lib/icu_tournament/tournament_sp.rb +19 -18
- data/lib/icu_tournament/util.rb +45 -0
- data/lib/icu_tournament/version.rb +1 -1
- data/spec/federation_spec.rb +0 -1
- data/spec/util_spec.rb +112 -6
- metadata +13 -28
data/README.rdoc
CHANGED
|
@@ -9,8 +9,8 @@ For ruby 1.9.2 (version 1.1.2 was the last compatible with ruby 1.8.7).
|
|
|
9
9
|
|
|
10
10
|
gem install icu_tournament
|
|
11
11
|
|
|
12
|
-
For name canonicalisation, _icu_name_ is required
|
|
13
|
-
|
|
12
|
+
For name canonicalisation, the _icu_name_ gem is required and
|
|
13
|
+
for handling SwissPerfect files the _dbf_ and _rubyzip_ gems are needed.
|
|
14
14
|
|
|
15
15
|
== Usage
|
|
16
16
|
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
require 'inifile'
|
|
2
1
|
require 'dbf'
|
|
3
2
|
require 'zip/zipfilesystem'
|
|
4
3
|
require 'tempfile'
|
|
@@ -222,28 +221,30 @@ module ICU
|
|
|
222
221
|
|
|
223
222
|
def parse_ini(file)
|
|
224
223
|
begin
|
|
225
|
-
ini =
|
|
224
|
+
ini = ICU::Util.load_ini(file)
|
|
226
225
|
rescue
|
|
227
|
-
raise "
|
|
226
|
+
raise "non-existant INI file (#{file})"
|
|
228
227
|
end
|
|
229
|
-
raise "invalid INI file (no sections)" if ini.
|
|
228
|
+
raise "invalid INI file (no sections)" if ini.size == 0
|
|
230
229
|
%w(name arbiter rounds).each do |key|
|
|
231
|
-
val = (ini['Tournament Info'][key.capitalize] || '').squeeze(" ")
|
|
230
|
+
val = (ini['Tournament Info'][key.capitalize] || '').squeeze(" ")
|
|
232
231
|
@t.send("#{key}=", val) if val.size > 0
|
|
233
232
|
end
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
233
|
+
if ini['Standings'] && ini['Standings']['Tie Breaks']
|
|
234
|
+
@t.tie_breaks = ini['Standings']['Tie Breaks'].to_s.split(/,/).map do |tbid|
|
|
235
|
+
case tbid.to_i # tie break name in SwissPerfect
|
|
236
|
+
when 1217 then :buchholz # Buchholz
|
|
237
|
+
when 1218 then :harkness # Median Buchholz
|
|
238
|
+
when 1219 then :progressive # cumulative
|
|
239
|
+
when 1220 then :neustadtl # Berger
|
|
240
|
+
when 1221 then :ratings # rating sum
|
|
241
|
+
when 1222 then :wins # number of wins
|
|
242
|
+
when 1223 then nil # minor scores - not applicable
|
|
243
|
+
when 1226 then nil # Brightwell - not applicable
|
|
244
|
+
else nil
|
|
245
|
+
end
|
|
246
|
+
end.find_all { |tb| tb }
|
|
247
|
+
end
|
|
247
248
|
end
|
|
248
249
|
|
|
249
250
|
def parse_trn(file, arg={})
|
data/lib/icu_tournament/util.rb
CHANGED
|
@@ -21,6 +21,51 @@ module ICU
|
|
|
21
21
|
nil
|
|
22
22
|
end
|
|
23
23
|
end
|
|
24
|
+
|
|
25
|
+
# Decide if a string is valid UTF-8 or not, returning true or false.
|
|
26
|
+
def self.is_utf8(str)
|
|
27
|
+
dup = str.dup
|
|
28
|
+
dup.force_encoding("UTF-8")
|
|
29
|
+
dup.valid_encoding?
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Try to convert any string to UTF-8.
|
|
33
|
+
def self.to_utf8(str)
|
|
34
|
+
utf8 = is_utf8(str)
|
|
35
|
+
dup = str.dup
|
|
36
|
+
return dup.force_encoding("UTF-8") if utf8
|
|
37
|
+
dup.force_encoding("Windows-1252") if dup.encoding.name.match(/^(ASCII-8BIT|UTF-8)$/)
|
|
38
|
+
dup.encode("UTF-8")
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Read UTF data from a file.
|
|
42
|
+
def self.read_utf8(name)
|
|
43
|
+
File.open(name, "r:ASCII-8BIT") do |f|
|
|
44
|
+
data = f.read
|
|
45
|
+
to_utf8(data)
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Load an INI file and convert to a hash.
|
|
50
|
+
def self.load_ini(name)
|
|
51
|
+
text = read_utf8(name)
|
|
52
|
+
data = Hash.new
|
|
53
|
+
header = nil
|
|
54
|
+
text.split(/\n/).each do |line|
|
|
55
|
+
if line.match(/^\s*\[([^\]]+)\]\s*$/)
|
|
56
|
+
header = $1.strip
|
|
57
|
+
header = nil if header == ""
|
|
58
|
+
elsif header && line.match(/^([^=]+)=(.*)$/)
|
|
59
|
+
key = $1.strip
|
|
60
|
+
val = $2.strip
|
|
61
|
+
unless key == ""
|
|
62
|
+
data[header] ||= Hash.new
|
|
63
|
+
data[header][key] = val
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
data
|
|
68
|
+
end
|
|
24
69
|
end
|
|
25
70
|
|
|
26
71
|
#
|
data/spec/federation_spec.rb
CHANGED
data/spec/util_spec.rb
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
# encoding: UTF-8
|
|
1
2
|
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
|
2
3
|
|
|
3
4
|
module ICU
|
|
@@ -33,6 +34,111 @@ module ICU
|
|
|
33
34
|
Util.parsedate('16th June 1986').should == '1986-06-16'
|
|
34
35
|
end
|
|
35
36
|
end
|
|
37
|
+
|
|
38
|
+
context "#is_utf8" do
|
|
39
|
+
it "should recognise US-ASCII as a special case of UTF-8" do
|
|
40
|
+
Util.is_utf8("Resume".encode("US-ASCII")).should be_true
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
it "should recognise UTF-8" do
|
|
44
|
+
Util.is_utf8("Résumé").should be_true
|
|
45
|
+
Util.is_utf8("δog").should be_true
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
it "should recognize other encodings as not being UTF-8" do
|
|
49
|
+
Util.is_utf8("Résumé".encode("ISO-8859-1")).should be_false
|
|
50
|
+
Util.is_utf8("€50".encode("Windows-1252")).should be_false
|
|
51
|
+
Util.is_utf8("ひらがな".encode("Shift_JIS")).should be_false
|
|
52
|
+
Util.is_utf8("\xa3").should be_false
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
context "#to_utf8" do
|
|
57
|
+
it "should convert to UTF-8" do
|
|
58
|
+
Util.to_utf8("Resume").should == "Resume"
|
|
59
|
+
Util.to_utf8("Resume".force_encoding("US-ASCII")).encoding.name.should == "UTF-8"
|
|
60
|
+
Util.to_utf8("Résumé".encode("ISO-8859-1")).should == "Résumé"
|
|
61
|
+
Util.to_utf8("Résumé".encode("Windows-1252")).should == "Résumé"
|
|
62
|
+
Util.to_utf8("€50".encode("Windows-1252")).should == "€50"
|
|
63
|
+
Util.to_utf8("\xa350".force_encoding("ASCII-8BIT")).should == "£50"
|
|
64
|
+
Util.to_utf8("\xa350").should == "£50"
|
|
65
|
+
Util.to_utf8("ひらがな".encode("Shift_JIS")).should == "ひらがな"
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
context "#read_utf8" do
|
|
70
|
+
before(:all) do
|
|
71
|
+
@s = File.dirname(__FILE__) + '/samples/file'
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
it "should read ASCII" do
|
|
75
|
+
Util.read_utf8("#{@s}/ascii.txt").should == "Resume\nResume\n"
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
it "should read Latin-1" do
|
|
79
|
+
Util.read_utf8("#{@s}/latin1.txt").should == "Résumé\nRésumé\n"
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
it "should read Windows CP1252" do
|
|
83
|
+
Util.read_utf8("#{@s}/cp1252.txt").should == "€3\n£7\n¥1\n"
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
it "should read UTF-8" do
|
|
87
|
+
Util.read_utf8("#{@s}/utf8.txt").should == "ヒラガナ\nヒラガナ\n"
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
it "should thow an exception for a non-existant file" do
|
|
91
|
+
lambda { Util.read_utf8("#{@s}/no_such_file.txt") }.should raise_error
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
context "#load_ini" do
|
|
96
|
+
before(:all) do
|
|
97
|
+
@s = File.dirname(__FILE__) + '/samples/ini'
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
it "should read ASCII" do
|
|
101
|
+
data = Util.load_ini("#{@s}/ascii.ini")
|
|
102
|
+
data.should be_an_instance_of(Hash)
|
|
103
|
+
data["Pairing"]["UseRating"].should == "0"
|
|
104
|
+
data["NoKeys"] == nil
|
|
105
|
+
data["Tournament Info"]["Arbiter"].should == "Herbert Scarry"
|
|
106
|
+
data["Tournament Info"]["DrawSymbol"].should == "D"
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
it "should read Latin1" do
|
|
110
|
+
data = Util.load_ini("#{@s}/latin1.ini")
|
|
111
|
+
data.should be_an_instance_of(Hash)
|
|
112
|
+
data["Tournament Info"]["Arbiter"].should == "Gearóidín"
|
|
113
|
+
data["Tournament Info"]["DrawSymbol"].should == "½"
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
it "should read Windows-1252" do
|
|
117
|
+
data = Util.load_ini("#{@s}/cp1252.ini")
|
|
118
|
+
data.should be_an_instance_of(Hash)
|
|
119
|
+
data["Tournament Info"]["Entry Fee"].should == "€50"
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
it "should read UTF8" do
|
|
123
|
+
data = Util.load_ini("#{@s}/utf8.ini")
|
|
124
|
+
data.should be_an_instance_of(Hash)
|
|
125
|
+
data["Tournament Info"]["Entry Fee"].should == "€50"
|
|
126
|
+
data["Tournament Info"]["Arbiter"].should == "ヒラガナ"
|
|
127
|
+
data["Tournament Info"]["DrawSymbol"].should == "½"
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
it "should handle untidily formatted files" do
|
|
131
|
+
data = Util.load_ini("#{@s}/untidy.ini")
|
|
132
|
+
data.should be_an_instance_of(Hash)
|
|
133
|
+
data["Tournament Info"]["Entry Fee"].should == "€50"
|
|
134
|
+
data["Tournament Info"]["DrawSymbol"].should == "½"
|
|
135
|
+
data["Pairing"]["Use Rating"].should == "0"
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
it "should thow an exception for a non-existant file" do
|
|
139
|
+
lambda { Util.read_utf8("#{@s}/no_such_file.ini") }.should raise_error
|
|
140
|
+
end
|
|
141
|
+
end
|
|
36
142
|
end
|
|
37
143
|
|
|
38
144
|
describe Accessor do
|
|
@@ -117,7 +223,7 @@ module ICU
|
|
|
117
223
|
@obj.respond_to?(:hisint=).should be_true
|
|
118
224
|
end
|
|
119
225
|
end
|
|
120
|
-
|
|
226
|
+
|
|
121
227
|
context "#attr_integer_or_nil" do
|
|
122
228
|
before(:each) do
|
|
123
229
|
@class = Class.new
|
|
@@ -182,7 +288,7 @@ module ICU
|
|
|
182
288
|
@obj.respond_to?(:theirpos=).should be_true
|
|
183
289
|
end
|
|
184
290
|
end
|
|
185
|
-
|
|
291
|
+
|
|
186
292
|
context "#attr_positive_or_nil" do
|
|
187
293
|
before(:each) do
|
|
188
294
|
@class = Class.new
|
|
@@ -219,7 +325,7 @@ module ICU
|
|
|
219
325
|
@obj.respond_to?(:theirpon=).should be_true
|
|
220
326
|
end
|
|
221
327
|
end
|
|
222
|
-
|
|
328
|
+
|
|
223
329
|
context "#attr_date" do
|
|
224
330
|
before(:each) do
|
|
225
331
|
@class = Class.new
|
|
@@ -251,7 +357,7 @@ module ICU
|
|
|
251
357
|
@obj.respond_to?(:theirdate=).should be_true
|
|
252
358
|
end
|
|
253
359
|
end
|
|
254
|
-
|
|
360
|
+
|
|
255
361
|
context "#attr_date_or_nil" do
|
|
256
362
|
before(:each) do
|
|
257
363
|
@class = Class.new
|
|
@@ -283,7 +389,7 @@ module ICU
|
|
|
283
389
|
@obj.respond_to?(:theirdate=).should be_true
|
|
284
390
|
end
|
|
285
391
|
end
|
|
286
|
-
|
|
392
|
+
|
|
287
393
|
context "#attr_string" do
|
|
288
394
|
before(:each) do
|
|
289
395
|
@class = Class.new
|
|
@@ -317,7 +423,7 @@ module ICU
|
|
|
317
423
|
@obj.respond_to?(:theirstring).should be_true
|
|
318
424
|
end
|
|
319
425
|
end
|
|
320
|
-
|
|
426
|
+
|
|
321
427
|
context "#attr_string_or_nil" do
|
|
322
428
|
before(:each) do
|
|
323
429
|
@class = Class.new
|
metadata
CHANGED
|
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
|
5
5
|
segments:
|
|
6
6
|
- 1
|
|
7
7
|
- 2
|
|
8
|
-
-
|
|
9
|
-
version: 1.2.
|
|
8
|
+
- 4
|
|
9
|
+
version: 1.2.4
|
|
10
10
|
platform: ruby
|
|
11
11
|
authors:
|
|
12
12
|
- Mark Orr
|
|
@@ -14,28 +14,13 @@ autorequire:
|
|
|
14
14
|
bindir: bin
|
|
15
15
|
cert_chain: []
|
|
16
16
|
|
|
17
|
-
date: 2011-01-
|
|
17
|
+
date: 2011-01-14 00:00:00 +00:00
|
|
18
18
|
default_executable:
|
|
19
19
|
dependencies:
|
|
20
|
-
- !ruby/object:Gem::Dependency
|
|
21
|
-
name: inifile
|
|
22
|
-
prerelease: false
|
|
23
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
|
24
|
-
none: false
|
|
25
|
-
requirements:
|
|
26
|
-
- - ">="
|
|
27
|
-
- !ruby/object:Gem::Version
|
|
28
|
-
segments:
|
|
29
|
-
- 0
|
|
30
|
-
- 3
|
|
31
|
-
- 0
|
|
32
|
-
version: 0.3.0
|
|
33
|
-
type: :runtime
|
|
34
|
-
version_requirements: *id001
|
|
35
20
|
- !ruby/object:Gem::Dependency
|
|
36
21
|
name: dbf
|
|
37
22
|
prerelease: false
|
|
38
|
-
requirement: &
|
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
|
39
24
|
none: false
|
|
40
25
|
requirements:
|
|
41
26
|
- - ">="
|
|
@@ -46,11 +31,11 @@ dependencies:
|
|
|
46
31
|
- 5
|
|
47
32
|
version: 1.2.5
|
|
48
33
|
type: :runtime
|
|
49
|
-
version_requirements: *
|
|
34
|
+
version_requirements: *id001
|
|
50
35
|
- !ruby/object:Gem::Dependency
|
|
51
36
|
name: rubyzip
|
|
52
37
|
prerelease: false
|
|
53
|
-
requirement: &
|
|
38
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
|
54
39
|
none: false
|
|
55
40
|
requirements:
|
|
56
41
|
- - ">="
|
|
@@ -61,11 +46,11 @@ dependencies:
|
|
|
61
46
|
- 4
|
|
62
47
|
version: 0.9.4
|
|
63
48
|
type: :runtime
|
|
64
|
-
version_requirements: *
|
|
49
|
+
version_requirements: *id002
|
|
65
50
|
- !ruby/object:Gem::Dependency
|
|
66
51
|
name: icu_name
|
|
67
52
|
prerelease: false
|
|
68
|
-
requirement: &
|
|
53
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
|
69
54
|
none: false
|
|
70
55
|
requirements:
|
|
71
56
|
- - ">="
|
|
@@ -73,14 +58,14 @@ dependencies:
|
|
|
73
58
|
segments:
|
|
74
59
|
- 0
|
|
75
60
|
- 0
|
|
76
|
-
-
|
|
77
|
-
version: 0.0.
|
|
61
|
+
- 3
|
|
62
|
+
version: 0.0.3
|
|
78
63
|
type: :runtime
|
|
79
|
-
version_requirements: *
|
|
64
|
+
version_requirements: *id003
|
|
80
65
|
- !ruby/object:Gem::Dependency
|
|
81
66
|
name: rspec
|
|
82
67
|
prerelease: false
|
|
83
|
-
requirement: &
|
|
68
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
|
84
69
|
none: false
|
|
85
70
|
requirements:
|
|
86
71
|
- - ">="
|
|
@@ -91,7 +76,7 @@ dependencies:
|
|
|
91
76
|
- 0
|
|
92
77
|
version: 2.3.0
|
|
93
78
|
type: :development
|
|
94
|
-
version_requirements: *
|
|
79
|
+
version_requirements: *id004
|
|
95
80
|
description: Convert files of chess tournament data in different formats to ruby classes and vice-versa.
|
|
96
81
|
email: mark.j.l.orr@googlemail.com
|
|
97
82
|
executables: []
|