sportdb-writers 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7e6c426324cdb4d759fd741cc287435dc10a16f7aabbaf699295132c0f38a6e1
4
- data.tar.gz: 70b7dc48369a7b822cd2b800dcb9dc05f1188cf18559bb43a5654d3fd63dc304
3
+ metadata.gz: 3483a7e2f321970a2e970ba30e272127892013b61c63be66431a318d32b52c3f
4
+ data.tar.gz: 4d213ad75e6973aa6ef95bee7fb39a62bca69cd3261fc18e2bfcfc9a6b913b87
5
5
  SHA512:
6
- metadata.gz: 9f78877c0169b086b0e3b8d0e5357b0b24a729a12f294a5344d7797ffe6f7be29eb0d4ed7557181429c07b959c4ddce7528bbdeb272e7e8da4396a5d037c17f0
7
- data.tar.gz: 24502014e49eb97679ab177b893f44a375f796185155da9ee4a5e7d705d5d3e43e171b14a6c494ef3cb3087961f769fc09aa646e4e48a50cc6b426d961839789
6
+ metadata.gz: b7b00a033d247555ca57acc503c88de73111605738998a9e5b3ea4e53f0353b08df19cfa1f9d5c84a5ad22b5528ddb632ba927b4f0b53fb5493f5391732d3d13
7
+ data.tar.gz: 23cec6ae8fa9b9ca04cf2242c86f8310de76a191b5a66bc4f2cab09aff7ea5c3e0a0d312bfe582dd2150d344302bdabab592c9b1944385bd75ae86de2367d207
data/CHANGELOG.md CHANGED
@@ -1,4 +1,4 @@
1
- ### 0.1.2
1
+ ### 0.2.0
2
2
 
3
3
  ### 0.0.1 / 2020-11-15
4
4
 
data/Manifest.txt CHANGED
@@ -8,9 +8,11 @@ config/leagues_america.csv
8
8
  config/leagues_europe.csv
9
9
  config/leagues_world.csv
10
10
  config/openfootball.csv
11
+ lib/sportdb/fbgen/github.rb
12
+ lib/sportdb/fbgen/github_config.rb
13
+ lib/sportdb/fbgen/main.rb
14
+ lib/sportdb/fbtxt/main.rb
11
15
  lib/sportdb/writers.rb
12
- lib/sportdb/writers/github.rb
13
- lib/sportdb/writers/github_config.rb
14
16
  lib/sportdb/writers/goals.rb
15
17
  lib/sportdb/writers/league_config.rb
16
18
  lib/sportdb/writers/txt_writer.rb
data/bin/fbgen CHANGED
@@ -6,178 +6,8 @@
6
6
 
7
7
  require 'sportdb/writers'
8
8
 
9
- require 'optparse'
10
9
 
11
-
12
-
13
- args=ARGV
14
-
15
-
16
- opts = {
17
- source_path: [],
18
- push: false,
19
- dry: false, ## dry run (no write)
20
- debug: true,
21
- }
22
-
23
-
24
-
25
- parser = OptionParser.new do |parser|
26
- parser.banner = "Usage: #{$PROGRAM_NAME} [options] [args]"
27
-
28
- parser.on( "-p", "--push",
29
- "fast forward sync and commit & push changes to git repo - default is (#{opts[:push]})" ) do |push|
30
- opts[:push] = push
31
- end
32
- parser.on( "--dry",
33
- "dry run; do NOT write - default is (#{opts[:dry]})" ) do |dry|
34
- opts[:dry] = dry
35
- end
36
- parser.on( "-q", "--quiet",
37
- "less debug output/messages - default is (#{!opts[:debug]})" ) do |debug|
38
- opts[:debug] = !debug
39
- end
40
- end
41
- parser.parse!( args )
42
-
43
-
44
-
45
- if opts[:source_path].empty? &&
46
- File.exist?( '/sports/cache.api.fbdat') &&
47
- File.exist?( '/sports/cache.wfb' )
48
- opts[:source_path] << '/sports/cache.api.fbdat'
49
- opts[:source_path] << '/sports/cache.wfb'
50
- end
51
-
52
-
53
- puts "OPTS:"
54
- p opts
55
- puts "ARGV:"
56
- p args
57
-
58
-
59
- ### split args in datasets with leagues and seasons
60
- datasets = []
61
-
62
-
63
- args.each do |arg|
64
- if arg =~ %r{^[0-9/-]+$} ## season
65
- if datasets.empty?
66
- puts "!! ERROR - league required before season arg; sorry"
67
- exit 1
68
- end
69
-
70
- season = Season.parse( arg ) ## check season
71
- datasets[-1][1] << season
72
- else ## assume league key
73
- key = arg.downcase
74
- league_info = Writer::LEAGUES[ key ]
75
-
76
- if league_info.nil?
77
- puts "!! ERROR - no league found for >#{key}<; sorry"
78
- exit 1
79
- end
80
-
81
- datasets << [key, []]
82
- end
83
- end
84
-
85
- pp datasets
86
-
87
-
88
-
89
- def find_file( filename, path: )
90
- path.each do |src_dir|
91
- path = "#{src_dir}/#{filename}"
92
- return path if File.exist?( path )
93
- end
94
-
95
- ## fix - raise file not found error!!!
96
- nil ## not found - raise filenot found error - why? why not?
97
- end
98
-
99
-
100
- source_path = opts[:source_path]
101
- source_path = ['.'] if source_path.empty? ## use ./ as default
102
-
103
-
104
- root_dir = if opts[:push]
105
- SportDb::GitHubSync.root # e.g. "/sports"
106
- else
107
- './o'
108
- end
109
-
110
-
111
- puts " (output) root_dir: >#{root_dir}<"
112
-
113
-
114
- sync = if opts[:push]
115
- repos = SportDb::GitHubSync.find_repos( datasets )
116
- puts " #{repos.size} repo(s):"
117
- pp repos
118
- SportDb::GitHubSync.new( repos )
119
- else
120
- nil
121
- end
122
- puts " sync:"
123
- pp sync
124
-
125
- sync.git_fast_forward_if_clean if sync
126
-
127
-
128
-
129
- datasets.each do |league_key, seasons|
130
- seasons = [ Season('2024/25') ] if seasons.empty?
131
-
132
- puts "==> gen #{league_key} - #{seasons.size} seasons(s)..."
133
-
134
- league_info = Writer::LEAGUES[ league_key ]
135
- pp league_info
136
-
137
- seasons.each do |season|
138
- ### get matches
139
-
140
- filename = "#{season.to_path}/#{league_key}.csv"
141
- path = find_file( filename, path: source_path )
142
-
143
- if path.nil?
144
- puts "!! no source found for #{filename}; sorry"
145
- exit 1
146
- end
147
-
148
- puts " ---> reading matches in #{path} ..."
149
- matches = SportDb::CsvMatchParser.read( path )
150
- puts " #{matches.size} matches"
151
-
152
- ## build
153
- txt = SportDb::TxtMatchWriter.build( matches )
154
- puts txt if opts[:debug]
155
-
156
- league_name = league_info[ :name ] # e.g. Brasileiro Série A
157
- basename = league_info[ :basename] #.e.g 1-seriea
158
-
159
- league_name = league_name.call( season ) if league_name.is_a?( Proc ) ## is proc/func - name depends on season
160
- basename = basename.call( season ) if basename.is_a?( Proc ) ## is proc/func - name depends on season
161
-
162
- buf = String.new
163
- buf << "= #{league_name} #{season}\n\n"
164
- buf << txt
165
-
166
- repo = SportDb::GitHubSync::REPOS[ league_key ]
167
- repo_path = "#{repo['owner']}/#{repo['name']}"
168
- repo_path << "/#{repo['path']}" if repo['path'] ## note: do NOT forget to add optional extra path!!!
169
-
170
- outpath = "#{root_dir}/#{repo_path}/#{season.to_path}/#{basename}.txt"
171
- if opts[:dry]
172
- puts " (dry) writing to >#{outpath}<..."
173
- else
174
- write_text( outpath, buf )
175
- end
176
- end
177
- end
178
-
179
-
180
- sync.git_push_if_changes if sync
10
+ Fbgen.main( ARGV )
181
11
 
182
12
 
183
13
  puts "bye"
data/bin/fbtxt CHANGED
@@ -9,44 +9,9 @@
9
9
 
10
10
  require 'sportdb/writers'
11
11
 
12
- require 'optparse'
13
12
 
13
+ Fbtxt.main( ARGV )
14
14
 
15
15
 
16
- args=ARGV
17
-
18
-
19
- opts = {
20
- }
21
-
22
- parser = OptionParser.new do |parser|
23
- parser.banner = "Usage: #{$PROGRAM_NAME} [options]"
24
- end
25
- parser.parse!( args )
26
-
27
- puts "OPTS:"
28
- p opts
29
- puts "ARGV:"
30
- p args
31
-
32
-
33
- matches = []
34
-
35
- ## step 1 - get all matches via csv
36
- args.each do |arg|
37
- path = arg
38
- puts "==> reading matches in #{path} ..."
39
- more_matches = SportDb::CsvMatchParser.read( path )
40
- matches += more_matches
41
- end
42
-
43
- puts "#{matches.size} matches"
44
- puts
45
-
46
-
47
- txt = SportDb::TxtMatchWriter.build( matches )
48
- puts txt
49
- puts
50
-
51
16
  puts "bye"
52
17
 
@@ -7,10 +7,17 @@ at.3.o, Österr. Regionalliga Ost, 3-regionalliga-ost,,,
7
7
  at.cup, ÖFB Cup, cup,,,
8
8
 
9
9
 
10
- de.1, Deutsche Bundesliga, 1-bundesliga,,,
11
- de.2, Deutsche 2. Bundesliga, 2-bundesliga2,,,
12
- de.3, Deutsche 3. Liga, 3-liga3,,,
13
- de.cup, DFB Pokal, cup,,,
10
+ de.1, Deutsche Bundesliga, 1-bundesliga,,,
11
+ de.2, Deutsche 2. Bundesliga, 2-bundesliga2,,,
12
+ de.3, Deutsche 3. Liga, 3-liga3,,,
13
+ de.4.bayern, Deutsche Regionalliga Bayern, 4-regionalliga-bayern,,,
14
+ de.4.n, Deutsche Regionalliga Nord, 4-regionalliga-nord,,,
15
+ de.4.no, Deutsche Regionalliga Nordost, 4-regionalliga-nordost,,,
16
+ de.4.w, Deutsche Regionalliga West, 4-regionalliga-west,,,
17
+ de.4.sw, Deutsche Regionalliga Südwest, 4-regionalliga-suedwest,,,
18
+ de.cup, DFB Pokal, cup,,,
19
+
20
+
14
21
 
15
22
  it.1, Italian Serie A, 1-seriea,,,
16
23
  it.2, Italian Serie B, 2-serieb,,,
@@ -45,6 +52,8 @@ pt.2, Portuguese Segunda Liga, 2-segundaliga,,,
45
52
 
46
53
  ch.1, Swiss Super League, 1-superleague,,,
47
54
  ch.2, Swiss Challenge League, 2-challengeleague,,,
55
+ ch.cup, Swiss Cup, cup,,,
56
+
48
57
 
49
58
  tr.1, Turkish Süper Lig, 1-superlig,,,
50
59
  tr.2, Turkish 1. Lig, 2-lig1,,,
@@ -1,5 +1,5 @@
1
1
 
2
- module SportDb
2
+ module Fbgen
3
3
 
4
4
  ###
5
5
  ## todo/fix:
@@ -80,4 +80,4 @@ def _git_fast_forward_if_clean( pathspec )
80
80
  end
81
81
  end
82
82
  end # class GitHub
83
- end # module SportDb
83
+ end # module Fbgen
@@ -1,5 +1,5 @@
1
1
 
2
- module SportDb
2
+ module Fbgen
3
3
  class GitHubConfig
4
4
 
5
5
  ## map leagues to repo+path
@@ -91,7 +91,7 @@ def find_repo( key )
91
91
  end
92
92
 
93
93
  end # class GitHubConfig
94
- end # module SportDb
94
+ end # module Fbgen
95
95
 
96
96
 
97
97
 
@@ -0,0 +1,211 @@
1
+
2
+ module Fbgen
3
+ def self.main( args=ARGV )
4
+
5
+ opts = {
6
+ source_path: [],
7
+ push: false,
8
+ dry: false, ## dry run (no write)
9
+ debug: true,
10
+ file: nil,
11
+ }
12
+
13
+ parser = OptionParser.new do |parser|
14
+ parser.banner = "Usage: #{$PROGRAM_NAME} [options] [args]"
15
+
16
+ parser.on( "-p", "--push",
17
+ "fast forward sync and commit & push changes to git repo - default is (#{opts[:push]})" ) do |push|
18
+ opts[:push] = push
19
+ end
20
+ parser.on( "--dry",
21
+ "dry run; do NOT write - default is (#{opts[:dry]})" ) do |dry|
22
+ opts[:dry] = dry
23
+ end
24
+ parser.on( "-q", "--quiet",
25
+ "less debug output/messages - default is (#{!opts[:debug]})" ) do |debug|
26
+ opts[:debug] = !debug
27
+ end
28
+
29
+ parser.on( "-f FILE", "--file FILE",
30
+ "read leagues via .csv file") do |file|
31
+ opts[:file] = file
32
+ end
33
+ end
34
+ parser.parse!( args )
35
+
36
+
37
+
38
+ if opts[:source_path].empty? &&
39
+ File.exist?( '/sports/cache.api.fbdat') &&
40
+ File.exist?( '/sports/cache.wfb' )
41
+ opts[:source_path] << '/sports/cache.api.fbdat'
42
+ opts[:source_path] << '/sports/cache.wfb'
43
+ end
44
+
45
+
46
+ puts "OPTS:"
47
+ p opts
48
+ puts "ARGV:"
49
+ p args
50
+
51
+ datasets = if opts[:file]
52
+ read_datasets( opts[:file] )
53
+ else
54
+ parse_datasets( args )
55
+ end
56
+
57
+ puts "datasets:"
58
+ pp datasets
59
+
60
+
61
+ source_path = opts[:source_path]
62
+ source_path = ['.'] if source_path.empty? ## use ./ as default
63
+
64
+ root_dir = if opts[:push]
65
+ GitHubSync.root # e.g. "/sports"
66
+ else
67
+ './o'
68
+ end
69
+
70
+ puts " (output) root_dir: >#{root_dir}<"
71
+
72
+ sync = if opts[:push]
73
+ repos = GitHubSync.find_repos( datasets )
74
+ puts " #{repos.size} repo(s):"
75
+ pp repos
76
+ GitHubSync.new( repos )
77
+ else
78
+ nil
79
+ end
80
+ puts " sync:"
81
+ pp sync
82
+
83
+ sync.git_fast_forward_if_clean if sync
84
+
85
+
86
+
87
+ datasets.each do |league_key, seasons|
88
+ seasons = [ Season('2024/25') ] if seasons.empty?
89
+
90
+ puts "==> gen #{league_key} - #{seasons.size} seasons(s)..."
91
+
92
+ league_info = Writer::LEAGUES[ league_key ]
93
+ pp league_info
94
+
95
+ seasons.each do |season|
96
+ ### get matches
97
+
98
+ filename = "#{season.to_path}/#{league_key}.csv"
99
+ path = find_file( filename, path: source_path )
100
+
101
+ if path.nil?
102
+ puts "!! no source found for #{filename}; sorry"
103
+ exit 1
104
+ end
105
+
106
+ puts " ---> reading matches in #{path} ..."
107
+ matches = SportDb::CsvMatchParser.read( path )
108
+ puts " #{matches.size} matches"
109
+
110
+ ## build
111
+ txt = SportDb::TxtMatchWriter.build( matches )
112
+ puts txt if opts[:debug]
113
+
114
+ league_name = league_info[ :name ] # e.g. Brasileiro Série A
115
+ basename = league_info[ :basename] #.e.g 1-seriea
116
+
117
+ league_name = league_name.call( season ) if league_name.is_a?( Proc ) ## is proc/func - name depends on season
118
+ basename = basename.call( season ) if basename.is_a?( Proc ) ## is proc/func - name depends on season
119
+
120
+ buf = String.new
121
+ buf << "= #{league_name} #{season}\n\n"
122
+ buf << txt
123
+
124
+ repo = GitHubSync::REPOS[ league_key ]
125
+ repo_path = "#{repo['owner']}/#{repo['name']}"
126
+ repo_path << "/#{repo['path']}" if repo['path'] ## note: do NOT forget to add optional extra path!!!
127
+
128
+ outpath = "#{root_dir}/#{repo_path}/#{season.to_path}/#{basename}.txt"
129
+ if opts[:dry]
130
+ puts " (dry) writing to >#{outpath}<..."
131
+ else
132
+ write_text( outpath, buf )
133
+ end
134
+ end
135
+ end
136
+
137
+ sync.git_push_if_changes if sync
138
+
139
+ end # method self.main
140
+
141
+
142
+
143
+ def self.parse_datasets( args )
144
+ ### split args in datasets with leagues and seasons
145
+ datasets = []
146
+ args.each do |arg|
147
+ if arg =~ %r{^[0-9/-]+$} ## season
148
+ if datasets.empty?
149
+ puts "!! ERROR - league required before season arg; sorry"
150
+ exit 1
151
+ end
152
+
153
+ season = Season.parse( arg ) ## check season
154
+ datasets[-1][1] << season
155
+ else ## assume league key
156
+ key = arg.downcase
157
+ league_info = Writer::LEAGUES[ key ]
158
+
159
+ if league_info.nil?
160
+ puts "!! ERROR - no league found for >#{key}<; sorry"
161
+ exit 1
162
+ end
163
+
164
+ datasets << [key, []]
165
+ end
166
+ end
167
+ datasets
168
+ end
169
+
170
+
171
+ def self.read_datasets( path )
172
+ ### split args in datasets with leagues and seasons
173
+ datasets = []
174
+ recs = read_csv( path )
175
+ recs.each do |rec|
176
+ league_code = rec['league']
177
+ key = league_code.downcase
178
+ league_info = Writer::LEAGUES[ key ]
179
+
180
+ if league_info.nil?
181
+ puts "!! ERROR - no league found for >#{key}<; sorry"
182
+ exit 1
183
+ end
184
+
185
+ datasets << [key, []]
186
+
187
+ seasons_str = rec['seasons']
188
+ seasons = seasons_str.split( /[ ]+/ )
189
+
190
+ seasons.each do |season_str|
191
+ season = Season.parse( season_str ) ## check season
192
+ datasets[-1][1] << season
193
+ end
194
+ end
195
+ datasets
196
+ end
197
+
198
+
199
+ def self.find_file( filename, path: )
200
+ path.each do |src_dir|
201
+ path = "#{src_dir}/#{filename}"
202
+ return path if File.exist?( path )
203
+ end
204
+
205
+ ## fix - raise file not found error!!!
206
+ nil ## not found - raise filenot found error - why? why not?
207
+ end
208
+
209
+
210
+
211
+ end # module Fbgen
@@ -0,0 +1,37 @@
1
+
2
+ module Fbtxt
3
+ def self.main( args=ARGV )
4
+
5
+
6
+ opts = {
7
+ }
8
+
9
+ parser = OptionParser.new do |parser|
10
+ parser.banner = "Usage: #{$PROGRAM_NAME} [options]"
11
+ end
12
+ parser.parse!( args )
13
+
14
+ puts "OPTS:"
15
+ p opts
16
+ puts "ARGV:"
17
+ p args
18
+
19
+
20
+ matches = []
21
+
22
+ ## step 1 - get all matches via csv
23
+ args.each do |arg|
24
+ path = arg
25
+ puts "==> reading matches in #{path} ..."
26
+ more_matches = SportDb::CsvMatchParser.read( path )
27
+ matches += more_matches
28
+ end
29
+
30
+ puts "#{matches.size} matches"
31
+ puts
32
+
33
+ txt = SportDb::TxtMatchWriter.build( matches )
34
+ puts txt
35
+ puts
36
+ end
37
+ end # module Fbtxt
@@ -19,12 +19,116 @@ def self.build( matches, rounds: true )
19
19
  ## note: make sure rounds is a bool, that is, true or false (do NOT pass in strings etc.)
20
20
  raise ArgumentError, "rounds flag - bool expected; got: #{rounds.inspect}" unless rounds.is_a?( TrueClass ) || rounds.is_a?( FalseClass )
21
21
 
22
- ## note: for now always english
22
+
23
+ ### 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??
31
+
32
+ matches.each do |match|
33
+ stage = match.stage
34
+ stage = 'Regular Season' if stage.nil? || stage.empty?
35
+ stats['stage'][ stage ] += 1
36
+
37
+ if match.date
38
+
39
+ ## todo/fix - norm date (parse as Date)
40
+ ## check format etc.
41
+ date = if match.date.is_a?( String )
42
+ Date.strptime( match.date, '%Y-%m-%d' )
43
+ else ## assume it's already a date (object)
44
+ match.date
45
+ end
46
+ stats['date']['start_date'] ||= date
47
+ stats['date']['end_date'] ||= date
48
+
49
+ stats['date']['start_date'] = date if date < stats['date']['start_date']
50
+ stats['date']['end_date'] = date if date > stats['date']['end_date']
51
+ end
52
+
53
+ [match.team1, match.team2].each do |team|
54
+ stats['teams'][ team ] += 1 if team && !['N.N.'].include?( team )
55
+ end
56
+ end
57
+
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
+ buf << "# Date "
72
+ start_date = stats['date']['start_date']
73
+ end_date = stats['date']['end_date']
74
+ if start_date.year != end_date.year
75
+ buf << "#{start_date.strftime('%a %b/%-d %Y')} - #{end_date.strftime('%a %b/%-d %Y')}"
76
+ else
77
+ buf << "#{start_date.strftime('%a %b/%-d')} - #{end_date.strftime('%a %b/%-d %Y')}"
78
+ end
79
+ buf << " (#{end_date.jd-start_date.jd}d)" ## add days
80
+ buf << "\n"
81
+
82
+ buf << "# Teams #{stats['teams'].size}\n"
83
+ buf << "# Matches #{matches.size}\n"
84
+
85
+ if use_stages
86
+ buf << "# Stages "
87
+ stages = stats['stage'].map { |name,count| "#{name} (#{count})" }.join( ' ' )
88
+ buf << stages
89
+ buf << "\n"
90
+ end
91
+ buf << "\n\n"
92
+
93
+
94
+ if use_stages
95
+ ## split matches by stage
96
+ matches_by_stage = {}
97
+ matches.each do |match|
98
+ stage = match.stage || ''
99
+ matches_by_stage[stage] ||= []
100
+ matches_by_stage[stage] << match
101
+ end
102
+
103
+ ## todo/fix
104
+ ## note - empty stage must go first!!!!
105
+ matches_by_stage.each_with_index do |(name, matches),i|
106
+ buf << "\n" if i != 0 # add extra new line (if not first stage)
107
+ if name.empty?
108
+ buf << "# Regular Season\n" ## empty stage
109
+ else
110
+ buf << "== #{name}\n"
111
+ end
112
+ buf += _build_batch( matches, rounds: rounds )
113
+ buf << "\n" if i+1 != matches_by_stage.size
114
+ end
115
+ buf
116
+ else
117
+ buf += _build_batch( matches, rounds: rounds )
118
+ buf
119
+ end
120
+ end
121
+
122
+
123
+ def self._build_batch( matches, rounds: true )
124
+ ## note: make sure rounds is a bool, that is, true or false (do NOT pass in strings etc.)
125
+ raise ArgumentError, "rounds flag - bool expected; got: #{rounds.inspect}" unless rounds.is_a?( TrueClass ) || rounds.is_a?( FalseClass )
126
+
127
+ ## note: for now always english
23
128
  round = 'Matchday'
24
129
  format_date = ->(date) { date.strftime( '%a %b/%-d' ) }
25
130
  format_score = ->(match) { match.score.to_s( lang: 'en' ) }
26
131
  round_translations = ROUND_TRANSLATIONS
27
-
28
132
 
29
133
  buf = String.new
30
134
 
@@ -33,12 +137,12 @@ def self.build( matches, rounds: true )
33
137
  last_time = nil
34
138
 
35
139
 
36
- matches.each do |match|
140
+ matches.each_with_index do |match,i|
37
141
 
38
142
  ## note: make rounds optional (set rounds flag to false to turn off)
39
143
  if rounds
40
144
  if match.round != last_round
41
- buf << "\n\n"
145
+ buf << (i == 0 ? "\n" : "\n\n") ## start with single empty line
42
146
  if match.round.is_a?( Integer ) ||
43
147
  match.round =~ /^[0-9]+$/ ## all numbers/digits
44
148
  ## default "class format
@@ -3,8 +3,8 @@ module SportDb
3
3
  module Module
4
4
  module Writers
5
5
  MAJOR = 0 ## todo: namespace inside version or something - why? why not??
6
- MINOR = 1
7
- PATCH = 2
6
+ MINOR = 2
7
+ PATCH = 0
8
8
  VERSION = [MAJOR,MINOR,PATCH].join('.')
9
9
 
10
10
  def self.version
@@ -2,6 +2,9 @@
2
2
  require 'sportdb/quick'
3
3
 
4
4
 
5
+ require 'optparse' ## command-line processing; check if included updstream?
6
+
7
+
5
8
 
6
9
  module Writer
7
10
  class Configuration
@@ -45,16 +48,21 @@ module Writer
45
48
  end # module Writer
46
49
 
47
50
 
51
+ ###
52
+ # fbtxt tool
53
+ require_relative 'fbtxt/main'
54
+
55
+
48
56
 
49
57
  ########################
50
58
  # push & pull github scripts
51
59
  require 'gitti' ## note - requires git machinery
52
60
 
53
- require_relative 'writers/github_config'
54
- require_relative 'writers/github' ## github helpers/update machinery
61
+ require_relative 'fbgen/github_config'
62
+ require_relative 'fbgen/github' ## github helpers/update machinery
55
63
 
56
64
 
57
- module SportDb
65
+ module Fbgen
58
66
  class GitHubSync
59
67
  REPOS = GitHubConfig.new
60
68
  recs = read_csv( "#{SportDb::Module::Writers.root}/config/openfootball.csv" )
@@ -88,9 +96,10 @@ def self.find_repos( datasets )
88
96
  repos.uniq ## note: remove duplicates (e.g. europe or world or such)
89
97
  end
90
98
  end # class GitHubSync
91
- end # module SportDb
99
+ end # module Fbgen
92
100
 
93
101
 
102
+ require_relative 'fbgen/main'
94
103
 
95
104
 
96
105
 
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.1.2
4
+ version: 0.2.0
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-09-07 00:00:00.000000000 Z
11
+ date: 2024-09-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sportdb-quick
@@ -94,9 +94,11 @@ files:
94
94
  - config/leagues_europe.csv
95
95
  - config/leagues_world.csv
96
96
  - config/openfootball.csv
97
+ - lib/sportdb/fbgen/github.rb
98
+ - lib/sportdb/fbgen/github_config.rb
99
+ - lib/sportdb/fbgen/main.rb
100
+ - lib/sportdb/fbtxt/main.rb
97
101
  - lib/sportdb/writers.rb
98
- - lib/sportdb/writers/github.rb
99
- - lib/sportdb/writers/github_config.rb
100
102
  - lib/sportdb/writers/goals.rb
101
103
  - lib/sportdb/writers/league_config.rb
102
104
  - lib/sportdb/writers/txt_writer.rb