Class: SportDb::TxtMatchWriter
- Inherits:
-
Object
- Object
- SportDb::TxtMatchWriter
- Defined in:
- lib/sportdb/writers.rb,
lib/sportdb/writers/build.rb,
lib/sportdb/writers/rounds.rb,
lib/sportdb/writers/build_stats.rb
Constant Summary collapse
- ROUND_TRANSLATIONS =
translate from lang x (german, etc) to english
{ # de/german '1. Runde' => 'Round 1', '2. Runde' => 'Round 2', 'Achtelfinale' => 'Round of 16', 'Viertelfinale' => 'Quarterfinals', 'Halbfinale' => 'Semifinals', 'Finale' => 'Final', 'Gruppe A' => 'Group A', 'Gruppe B' => 'Group B', 'Gruppe C' => 'Group C', 'Gruppe D' => 'Group D', 'Gruppe E' => 'Group E', 'Gruppe F' => 'Group F', }
Class Method Summary collapse
- ._build_batch(matches, rounds: true) ⇒ Object
- ._build_stats(stats) ⇒ Object
-
._calc_stats(matches) ⇒ Object
helper - to calculate match stats e.g.
-
.build(matches, rounds: true) ⇒ Object
note: build returns buf - an (in-memory) string buf(fer).
- .build_v2 ⇒ Object
-
.write(path, matches, name:, rounds: true) ⇒ Object
(also: write_v2)
fix - change name: to title: !!!! fix: remove rounds: true|false - make it works without rounds without flag!!!!!.
Class Method Details
._build_batch(matches, rounds: true) ⇒ Object
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 |
# File 'lib/sportdb/writers/build.rb', line 28 def self._build_batch( matches, rounds: true ) ## note: make sure rounds is a bool, that is, true or false (do NOT pass in strings etc.) raise ArgumentError, "rounds flag - bool expected; got: #{rounds.inspect}" unless rounds.is_a?( TrueClass ) || rounds.is_a?( FalseClass ) last_round = nil last_year = nil last_date = nil last_time = nil buf = String.new matches.each_with_index do |match,i| ## note: make rounds optional (set rounds flag to false to turn off) if rounds ## build round string round = if match.round if match.round.is_a?( Integer ) || match.round =~ /^[0-9]+$/ ## all numbers/digits ## default "class format ## e.g. Runde 1, Spieltag 1, Matchday 1, Week 1 "Matchday #{match.round}" else ## use as is from match ## note: for now assume english names (ROUND_TRANSLATIONS[match.round] || match.round) end else nil end if match.stage if ['Regular', 'Regular stage'].include?(match.stage) ## skip stage else ## note - only stage present is possible ## if stage present - (auto-)add upfront round = round ? "#{match.stage}, #{round}" : "#{match.stage}" end end if round.nil? puts "!! ERROR - match with round nil (no round and no stage)" pp match exit 1 end if round != last_round buf << (i == 0 ? "\n" : "\n\n") ## start with single empty line buf << "▪ #{round}\n" ## note - reset last_date & last_time on every new round header ## kind of starting "new scope" (no date/time inheritance) last_date = nil last_time = nil last_round = round end end date = if match.date.is_a?( String ) Date.strptime( match.date, '%Y-%m-%d' ) else ## assume it's already a date (object) or nil!!!! match.date end ### ## fix - fix - fix ## ruby has no TIME type/class ## Time.strptime will include date (plus timezone etc.) e.g.!!! ## 12:00 => 2026-05-25 12:00:00 +0200 ## do NOT use object; keep time as a string!!!! time = if match.time.is_a?( String ) Time.strptime( match.time, '%H:%M') else ## assume it's already a time (object) or nil match.time end ## note - date might be NIL!!!!! date_yyyymmdd = date ? date.strftime( '%Y-%m-%d' ) : nil ## note: time is OPTIONAL for now ## note: use 17:00 always as time format (do NOT use 17.00!!!) time_hhmm = time ? time.strftime( '%H:%M' ) : nil if date_yyyymmdd if date_yyyymmdd != last_date ## note: add an extra leading blank line (if no round headings printed) buf << "\n" unless rounds buf << " " ## note: only add year if different for last date header buf << if (date ? date.year : nil) != last_year "#{date.strftime( '%a %b %-d %Y' )}" else "#{date.strftime( '%a %b %-d' )}" end buf << "\n" last_time = nil end end ## allow strings and structs for team names team1 = match.team1.is_a?( String ) ? match.team1 : match.team1.name team2 = match.team2.is_a?( String ) ? match.team2 : match.team2.name line = String.new line << ' ' if time if last_time != time_hhmm line << " %5s" % time_hhmm else line << (' ' *7) end line << ' ' else line << (' ' *9) end line << "%-23s" % team1 ## note: use %-s for left-align line << " v " line << "%-23s" % team2 ## note - only print if score is available ## returns - for not available for now!!!! score = match.score.to_s( lang: 'en' ) if score != '-' ## note: separate by at least two spaces for now line << " #{score} " end if match.status line << ' ' case match.status when Status::CANCELLED line << '[cancelled]' when Status::AWARDED line << '[awarded]' when Status::ABANDONED line << '[abandoned]' when Status::REPLAY line << '[replay]' when Status::POSTPONED line << '[postponed]' ## was -- note: add NOTHING for postponed for now else puts "!! ERROR - unknown match status >#{match.status}<:" pp match line << "[#{match.status.downcase}]" ## print "literal" downcased for now exit 1 end end ## add match line buf << line.rstrip ## remove possible right trailing spaces before adding buf << "\n" if match.goals buf << ' ' # 4 space indent buf << ' ' if time # 7 (5+2) space indent (for hour e.g. 17.30) buf << "(#{build_goals(match.goals)})" buf << "\n" end last_year = date ? date.year : nil last_date = date_yyyymmdd last_time = time_hhmm end buf end |
._build_stats(stats) ⇒ Object
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
# File 'lib/sportdb/writers/build_stats.rb', line 60 def self._build_stats( stats ) ### add comment header buf = String.new # e.g. 13 April – 25 September 2024 # or 16 August 2024 – 25 May 2025 ## note - date is optional!! if stats['date']['start_date'] buf << "# Date " start_date = stats['date']['start_date'] end_date = stats['date']['end_date'] if start_date.year != end_date.year buf << "#{start_date.strftime('%a %b %-d %Y')} - #{end_date.strftime('%a %b %-d %Y')}" else buf << "#{start_date.strftime('%a %b %-d')} - #{end_date.strftime('%a %b %-d %Y')}" end buf << " (#{end_date.jd-start_date.jd}d)" ## add days buf << "\n" end buf << "# Teams #{stats['teams'].size}\n" buf << "# Matches #{stats['matches']}\n" if stats['use_stages'] buf << "# Stages " stages = stats['stage'].map { |name,count| "#{name} (#{count})" }.join( ' ' ) buf << stages buf << "\n" end buf end |
._calc_stats(matches) ⇒ Object
helper - to calculate match stats e.g.
how many stages, start and end dates, etc.
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/sportdb/writers/build_stats.rb', line 8 def self._calc_stats( matches ) ### check for stages & stats stats = { 'stage' => Hash.new(0), 'date' => { 'start_date' => nil, 'end_date' => nil, }, 'teams' => Hash.new(0), 'matches' => 0, 'use_stages' => false, } ## add matches played stats too?? ## for now only simply count used stats['matches'] = matches.size matches.each do |match| stage = match.stage stage = 'Regular Season' if stage.nil? || stage.empty? stats['stage'][ stage ] += 1 ## note - date for now optional (not required)!!!! ## only teams for match if match.date ## todo/fix - norm date (parse as Date) ## check format etc. date = if match.date.is_a?( String ) Date.strptime( match.date, '%Y-%m-%d' ) else ## assume it's already a date (object) match.date end stats['date']['start_date'] ||= date stats['date']['end_date'] ||= date stats['date']['start_date'] = date if date < stats['date']['start_date'] stats['date']['end_date'] = date if date > stats['date']['end_date'] end [match.team1, match.team2].each do |team| stats['teams'][ team ] += 1 if team && !['N.N.'].include?( team ) end end ## add & update use_stage flag stats['use_stages'] = if stats['stage'].size >= 2 || (stats['stage'].size == 1 && stats['stage'].keys[0] != 'Regular Season') true else false end stats end |
.build(matches, rounds: true) ⇒ Object
note: build returns buf - an (in-memory) string buf(fer)
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
# File 'lib/sportdb/writers/build.rb', line 7 def self.build( matches, rounds: true ) ## note: make sure rounds is a bool, that is, true or false (do NOT pass in strings etc.) raise ArgumentError, "rounds flag - bool expected; got: #{rounds.inspect}" unless rounds.is_a?( TrueClass ) || rounds.is_a?( FalseClass ) ### check for stages & stats stats = _calc_stats( matches ) buf = String.new ### add comment header buf << _build_stats( stats ) buf << "\n\n" buf << _build_batch( matches, rounds: rounds ) buf end |
.build_v2 ⇒ Object
63 |
# File 'lib/sportdb/writers.rb', line 63 alias_method :build_v2, :build |
.write(path, matches, name:, rounds: true) ⇒ Object Also known as: write_v2
fix - change name: to title: !!!!
fix: remove rounds: true|false - make it works without rounds without flag!!!!!
48 49 50 51 52 53 54 55 56 |
# File 'lib/sportdb/writers.rb', line 48 def self.write( path, matches, name:, rounds: true) buf = build( matches, rounds: rounds ) puts "==> writing to >#{path}<..." txt = "= #{name}\n\n" + buf write_text( path, txt ) end |