sportdb-writers 0.4.2 → 0.4.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8617a863daaeb1b9d99c74068d58e762086ba329a423dee7effce66659b28e33
4
- data.tar.gz: 920417fb198af92e662102d356cfae8edb038fdeb9f7659d6538b942ed6f2835
3
+ metadata.gz: b08a4a77a08af12a0f8c7b9873c5115b8b8135e13e3b7d878ab246567a8ffa32
4
+ data.tar.gz: a6e9f8f3b0933667f2fa4cf5eb7903c4410ead48e3647dfb903e261bb3f164be
5
5
  SHA512:
6
- metadata.gz: 1e179dfaa2ad55f64f690308a83af8a0861056050faa7e1d0e5645d7098c54f090ffdc24a8dea30d903ce4b72c2860a3a3741b8f954ee9f343a4f27d62df8297
7
- data.tar.gz: 00340a7bfb452dbf504e15346f6ecdd63757853dd2144a868bc77e4742b4f8f6efe1c98c982c6a449caaf20d5cd4883bdc99317e949caa80f72e245fef62b5c0
6
+ metadata.gz: 1ebb1e1a90a196a992fef5eebf43baea0e613f559d73db25d8bd8812da67fe31bb4f286b767e7423c80f00d25d1c3f745972946448eaab8a3239e9f53a8d78fc
7
+ data.tar.gz: 02342a063aef2f2604567a70a76e4caf48e49b555ab1b09fb7da996b6812547c17d684a053b3164f9b797de44e4c2a2c490a66b7865983d8d63fb78eda3294a8
data/CHANGELOG.md CHANGED
@@ -1,4 +1,4 @@
1
- ### 0.4.2
1
+ ### 0.4.3
2
2
  ### 0.0.1 / 2020-11-15
3
3
 
4
4
  * Everything is new. First release.
data/Manifest.txt CHANGED
@@ -5,4 +5,5 @@ Rakefile
5
5
  lib/sportdb/writers.rb
6
6
  lib/sportdb/writers/goals.rb
7
7
  lib/sportdb/writers/txt_writer.rb
8
+ lib/sportdb/writers/txt_writer_v2.rb
8
9
  lib/sportdb/writers/version.rb
@@ -11,31 +11,40 @@ class TxtMatchWriter
11
11
  'Viertelfinale' => 'Quarterfinals',
12
12
  'Halbfinale' => 'Semifinals',
13
13
  'Finale' => 'Final',
14
- }
15
-
16
14
 
17
- ## note: build returns buf - an (in-memory) string buf(fer)
18
- def self.build( matches, rounds: true )
19
- ## note: make sure rounds is a bool, that is, true or false (do NOT pass in strings etc.)
20
- raise ArgumentError, "rounds flag - bool expected; got: #{rounds.inspect}" unless rounds.is_a?( TrueClass ) || rounds.is_a?( FalseClass )
15
+ 'Gruppe A' => 'Group A',
16
+ 'Gruppe B' => 'Group B',
17
+ 'Gruppe C' => 'Group C',
18
+ 'Gruppe D' => 'Group D',
19
+ 'Gruppe E' => 'Group E',
20
+ 'Gruppe F' => 'Group F',
21
+ }
21
22
 
22
23
 
24
+ ## helper - to calculate match stats e.g.
25
+ ## how many stages, start and end dates, etc.
26
+ def self._calc_stats( matches )
23
27
  ### check for stages & stats
24
- stats = { 'stage' => Hash.new(0),
25
- 'date' => { 'start_date' => nil,
26
- 'end_date' => nil, },
27
- 'teams' => Hash.new(0),
28
- }
29
-
30
- ## add matches played stats too??
28
+ stats = { 'stage' => Hash.new(0),
29
+ 'date' => { 'start_date' => nil,
30
+ 'end_date' => nil, },
31
+ 'teams' => Hash.new(0),
32
+ 'matches' => 0,
33
+ 'use_stages' => false,
34
+ }
35
+
36
+ ## add matches played stats too??
37
+ ## for now only simply count used
38
+ stats['matches'] = matches.size
31
39
 
32
40
  matches.each do |match|
33
41
  stage = match.stage
34
42
  stage = 'Regular Season' if stage.nil? || stage.empty?
35
43
  stats['stage'][ stage ] += 1
36
44
 
45
+ ## note - date for now optional (not required)!!!!
46
+ ## only teams for match
37
47
  if match.date
38
-
39
48
  ## todo/fix - norm date (parse as Date)
40
49
  ## check format etc.
41
50
  date = if match.date.is_a?( String )
@@ -48,52 +57,74 @@ def self.build( matches, rounds: true )
48
57
 
49
58
  stats['date']['start_date'] = date if date < stats['date']['start_date']
50
59
  stats['date']['end_date'] = date if date > stats['date']['end_date']
51
- end
60
+ end
52
61
 
53
62
  [match.team1, match.team2].each do |team|
54
63
  stats['teams'][ team ] += 1 if team && !['N.N.'].include?( team )
55
64
  end
56
65
  end
66
+
67
+ ## add & update use_stage flag
68
+ stats['use_stages'] = if stats['stage'].size >= 2 ||
69
+ (stats['stage'].size == 1 &&
70
+ stats['stage'].keys[0] != 'Regular Season')
71
+ true
72
+ else
73
+ false
74
+ end
75
+ stats
76
+ end
57
77
 
58
- use_stages = if stats['stage'].size >= 2 ||
59
- (stats['stage'].size == 1 &&
60
- stats['stage'].keys[0] != 'Regular Season')
61
- true
62
- else
63
- false
64
- end
65
-
66
-
67
- ### add comment header
68
- buf = String.new
69
- # e.g. 13 April 25 September 2024
70
- # or 16 August 2024 – 25 May 2025
71
- ## note - date is optional!!
72
- if stats['date']['start_date']
73
- buf << "# Date "
74
- start_date = stats['date']['start_date']
75
- end_date = stats['date']['end_date']
76
- if start_date.year != end_date.year
77
- buf << "#{start_date.strftime('%a %b/%-d %Y')} - #{end_date.strftime('%a %b/%-d %Y')}"
78
- else
79
- buf << "#{start_date.strftime('%a %b/%-d')} - #{end_date.strftime('%a %b/%-d %Y')}"
80
- end
81
- buf << " (#{end_date.jd-start_date.jd}d)" ## add days
82
- buf << "\n"
83
- end
78
+ def self._build_stats( stats )
79
+ ### add comment header
80
+ buf = String.new
81
+ # e.g. 13 April – 25 September 2024
82
+ # or 16 August 2024 – 25 May 2025
83
+ ## note - date is optional!!
84
+ if stats['date']['start_date']
85
+ buf << "# Date "
86
+ start_date = stats['date']['start_date']
87
+ end_date = stats['date']['end_date']
88
+ if start_date.year != end_date.year
89
+ buf << "#{start_date.strftime('%a %b/%-d %Y')} - #{end_date.strftime('%a %b/%-d %Y')}"
90
+ else
91
+ buf << "#{start_date.strftime('%a %b/%-d')} - #{end_date.strftime('%a %b/%-d %Y')}"
92
+ end
93
+ buf << " (#{end_date.jd-start_date.jd}d)" ## add days
94
+ buf << "\n"
95
+ end
96
+
97
+ buf << "# Teams #{stats['teams'].size}\n"
98
+ buf << "# Matches #{stats['matches']}\n"
99
+
100
+ if stats['use_stages']
101
+ buf << "# Stages "
102
+ stages = stats['stage'].map { |name,count| "#{name} (#{count})" }.join( ' ' )
103
+ buf << stages
104
+ buf << "\n"
105
+ end
106
+
107
+ buf
108
+ end
84
109
 
85
- buf << "# Teams #{stats['teams'].size}\n"
86
- buf << "# Matches #{matches.size}\n"
87
110
 
88
- if use_stages
89
- buf << "# Stages "
90
- stages = stats['stage'].map { |name,count| "#{name} (#{count})" }.join( ' ' )
91
- buf << stages
92
- buf << "\n"
93
- end
94
- buf << "\n\n"
111
+ ## note: build returns buf - an (in-memory) string buf(fer)
112
+ def self.build( matches, rounds: true )
113
+ ## note: make sure rounds is a bool, that is, true or false (do NOT pass in strings etc.)
114
+ raise ArgumentError, "rounds flag - bool expected; got: #{rounds.inspect}" unless rounds.is_a?( TrueClass ) || rounds.is_a?( FalseClass )
115
+
116
+
117
+ ### calc stats and check for stages
118
+ stats = _calc_stats( matches )
119
+
120
+ buf = String.new
121
+
122
+ ### add comment header
123
+ buf << _build_stats( stats )
124
+ buf << "\n\n"
95
125
 
96
126
 
127
+ use_stages = stats['use_stages' ]
97
128
  if use_stages
98
129
  ## split matches by stage
99
130
  matches_by_stage = {}
@@ -0,0 +1,188 @@
1
+ module SportDb
2
+ class TxtMatchWriter
3
+
4
+
5
+
6
+ ## note: build returns buf - an (in-memory) string buf(fer)
7
+ def self.build_v2( matches, rounds: true )
8
+ ## note: make sure rounds is a bool, that is, true or false (do NOT pass in strings etc.)
9
+ raise ArgumentError, "rounds flag - bool expected; got: #{rounds.inspect}" unless rounds.is_a?( TrueClass ) || rounds.is_a?( FalseClass )
10
+
11
+
12
+ ### check for stages & stats
13
+ stats = _calc_stats( matches )
14
+
15
+
16
+ buf = String.new
17
+
18
+ ### add comment header
19
+ buf << _build_stats( stats )
20
+ buf << "\n\n"
21
+
22
+ buf << _build_batch_v2( matches, rounds: rounds )
23
+
24
+ buf
25
+ end
26
+
27
+
28
+ def self._build_batch_v2( matches, rounds: true )
29
+ ## note: make sure rounds is a bool, that is, true or false (do NOT pass in strings etc.)
30
+ raise ArgumentError, "rounds flag - bool expected; got: #{rounds.inspect}" unless rounds.is_a?( TrueClass ) || rounds.is_a?( FalseClass )
31
+
32
+ last_round = nil
33
+ last_year = nil
34
+ last_date = nil
35
+ last_time = nil
36
+
37
+
38
+ buf = String.new
39
+
40
+
41
+ matches.each_with_index do |match,i|
42
+
43
+ ## note: make rounds optional (set rounds flag to false to turn off)
44
+ if rounds
45
+ ## build round string
46
+ round = if match.round.is_a?( Integer ) ||
47
+ match.round =~ /^[0-9]+$/ ## all numbers/digits
48
+ ## default "class format
49
+ ## e.g. Runde 1, Spieltag 1, Matchday 1, Week 1
50
+ "Matchday #{match.round}"
51
+ else ## use as is from match
52
+ ## note: for now assume english names
53
+ if match.round.nil?
54
+ ## warn
55
+ puts "!! ERROR - match with round nil?"
56
+ pp match
57
+ exit 1
58
+ end
59
+ (ROUND_TRANSLATIONS[match.round] || match.round)
60
+ end
61
+
62
+ ## if stage present - (auto-)add upfront
63
+ round = "#{match.stage}, #{round}" if match.stage
64
+
65
+
66
+ if round != last_round
67
+ buf << (i == 0 ? "\n" : "\n\n") ## start with single empty line
68
+ buf << "» #{round}\n"
69
+
70
+ ## note - reset last_date & last_time on every new round header
71
+ last_date = nil
72
+ last_time = nil
73
+ last_round = round
74
+ end
75
+ end
76
+
77
+
78
+ date = if match.date.is_a?( String )
79
+ Date.strptime( match.date, '%Y-%m-%d' )
80
+ else ## assume it's already a date (object) or nil!!!!
81
+ match.date
82
+ end
83
+
84
+ time = if match.time.is_a?( String )
85
+ Time.strptime( match.time, '%H:%M')
86
+ else ## assume it's already a time (object) or nil
87
+ match.time
88
+ end
89
+
90
+
91
+ ## note - date might be NIL!!!!!
92
+ date_yyyymmdd = date ? date.strftime( '%Y-%m-%d' ) : nil
93
+
94
+ ## note: time is OPTIONAL for now
95
+ ## note: use 17.00 and NOT 17:00 for now
96
+ time_hhmm = time ? time.strftime( '%H.%M' ) : nil
97
+
98
+
99
+ if date_yyyymmdd
100
+ if date_yyyymmdd != last_date
101
+ ## note: add an extra leading blank line (if no round headings printed)
102
+ buf << "\n" unless rounds
103
+
104
+ buf << " "
105
+ ## note: only add year if different for last date header
106
+ buf << if (date ? date.year : nil) != last_year
107
+ "#{date.strftime( '%a %b/%-d %Y' )}"
108
+ else
109
+ "#{date.strftime( '%a %b/%-d' )}"
110
+ end
111
+ buf << "\n"
112
+ last_time = nil
113
+ end
114
+ end
115
+
116
+
117
+ ## allow strings and structs for team names
118
+ team1 = match.team1.is_a?( String ) ? match.team1 : match.team1.name
119
+ team2 = match.team2.is_a?( String ) ? match.team2 : match.team2.name
120
+
121
+
122
+ line = String.new
123
+ line << ' '
124
+
125
+ if time
126
+ if last_time != time_hhmm
127
+ line << " %5s" % time_hhmm
128
+ else
129
+ line << (' ' *7)
130
+ end
131
+ line << ' '
132
+ else
133
+ line << (' ' *9)
134
+ end
135
+
136
+ line << "%-23s" % team1 ## note: use %-s for left-align
137
+ line << " v "
138
+ line << "%-23s" % team2
139
+
140
+ ## note - only print if score is available
141
+ ## returns - for not available for now!!!!
142
+ score = match.score.to_s( lang: 'en' )
143
+ if score != '-'
144
+ ## note: separate by at least two spaces for now
145
+ line << " #{score} "
146
+ end
147
+
148
+ if match.status
149
+ line << ' '
150
+ case match.status
151
+ when Status::CANCELLED
152
+ line << '[cancelled]'
153
+ when Status::AWARDED
154
+ line << '[awarded]'
155
+ when Status::ABANDONED
156
+ line << '[abandoned]'
157
+ when Status::REPLAY
158
+ line << '[replay]'
159
+ when Status::POSTPONED
160
+ line << '[postponed]'
161
+ ## was -- note: add NOTHING for postponed for now
162
+ else
163
+ puts "!! WARN - unknown match status >#{match.status}<:"
164
+ pp match
165
+ line << "[#{match.status.downcase}]" ## print "literal" downcased for now
166
+ end
167
+ end
168
+
169
+ ## add match line
170
+ buf << line.rstrip ## remove possible right trailing spaces before adding
171
+ buf << "\n"
172
+
173
+ if match.goals
174
+ buf << ' ' # 4 space indent
175
+ buf << ' ' if time # 7 (5+2) space indent (for hour e.g. 17.30)
176
+ buf << "[#{build_goals(match.goals)}]"
177
+ buf << "\n"
178
+ end
179
+
180
+ last_year = date ? date.year : nil
181
+ last_date = date_yyyymmdd
182
+ last_time = time_hhmm
183
+ end
184
+ buf
185
+ end
186
+
187
+ end # class TxtMatchWriter
188
+ end # module SportDb
@@ -4,7 +4,7 @@ module Module
4
4
  module Writers
5
5
  MAJOR = 0 ## todo: namespace inside version or something - why? why not??
6
6
  MINOR = 4
7
- PATCH = 2
7
+ PATCH = 3
8
8
  VERSION = [MAJOR,MINOR,PATCH].join('.')
9
9
 
10
10
  def self.version
@@ -28,6 +28,7 @@ end # module Writer
28
28
  require_relative 'writers/version'
29
29
  require_relative 'writers/goals'
30
30
  require_relative 'writers/txt_writer'
31
+ require_relative 'writers/txt_writer_v2'
31
32
 
32
33
 
33
34
 
@@ -42,10 +43,26 @@ class TxtMatchWriter
42
43
 
43
44
  puts "==> writing to >#{path}<..."
44
45
  File.open( path, 'w:utf-8' ) do |f|
45
- f.write( "= #{name}\n" )
46
+ f.write( "= #{name}\n\n" )
46
47
  f.write( buf )
47
48
  end
48
49
  end # method self.write
50
+
51
+ def self.write_v2( path, matches, name:, rounds: true)
52
+
53
+ buf = build_v2( matches, rounds: rounds )
54
+
55
+ ## for convenience - make sure parent folders/directories exist
56
+ FileUtils.mkdir_p( File.dirname( path) ) unless Dir.exist?( File.dirname( path ))
57
+
58
+ puts "==> writing to >#{path}<..."
59
+ File.open( path, 'w:utf-8' ) do |f|
60
+ f.write( "= #{name}\n\n" )
61
+ f.write( buf )
62
+ end
63
+ end # method self.write_v2
64
+
65
+
49
66
  end # class TxtMatchWriter
50
67
  end # module SportDb
51
68
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sportdb-writers
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.2
4
+ version: 0.4.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gerald Bauer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-12-30 00:00:00.000000000 Z
11
+ date: 2025-03-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sportdb-structs
@@ -75,6 +75,7 @@ files:
75
75
  - lib/sportdb/writers.rb
76
76
  - lib/sportdb/writers/goals.rb
77
77
  - lib/sportdb/writers/txt_writer.rb
78
+ - lib/sportdb/writers/txt_writer_v2.rb
78
79
  - lib/sportdb/writers/version.rb
79
80
  homepage: https://github.com/sportdb/sport.db
80
81
  licenses: