fbtxt2json 0.1.0 → 0.2.1

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.
Files changed (6) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1 -1
  3. data/README.md +58 -3
  4. data/Rakefile +4 -2
  5. data/bin/fbtxt2json +153 -32
  6. metadata +20 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '0840ecd85960fd8947a270f5df38fd20bb865b9c6105c6dd16f684d89c30c7e4'
4
- data.tar.gz: 5a321670218d38604964438bf1ff4b36fceb6a322a4b92c2120ce22d8dd32292
3
+ metadata.gz: eda08bd194e92f91e52f319f99b158dd512ea80011b72bf75045cc08404ee1a9
4
+ data.tar.gz: 5c0046100b7d4f7d17d2217dca7ca0c782284cac0ad89f1d5ca422e8319548a4
5
5
  SHA512:
6
- metadata.gz: eb3fe0e7e9a32e9808bdad2b7c0a018be63a8712341444a00cc0392802476c057844216b591e562d0ab6912d1ac11142b5a6831307dd66a9f347c6e40afe434f
7
- data.tar.gz: fc9fd0cd07ab989aafc6ab1250e9da657d37be5901845c8c9b38faa7f6631c11abcd66c4e036f6898e5e98e96752c5d718fc2e2b08f18a1242ca12bcf095860a
6
+ metadata.gz: 7749effafe765758821fc38b7df011b782facf1a78fa80862c7c22e3d1bcfa0e3b7a5009c4e83bae730dc5c29949fb09c61ae3ffc69d9d171557ebd6b3d24b65
7
+ data.tar.gz: 19d8181d200b05948a6f78428201c48c96942495168e5d84812bd1df271269f90ea8f9a20e8e35cbc3f2f530e921b3042a09b19707c898669083919efeea7bfa
data/CHANGELOG.md CHANGED
@@ -1,4 +1,4 @@
1
- ### 0.1.0
1
+ ### 0.2.1
2
2
  ### 0.0.1 / 2024-09-28
3
3
 
4
4
  * Everything is new. First release.
data/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # fbtxt2json - convert football.txt match schedules & more to json
2
2
 
3
3
 
4
- * home :: [github.com/sportdb/sport.db](https://github.com/sportdb/sport.db)
5
- * bugs :: [github.com/sportdb/sport.db/issues](https://github.com/sportdb/sport.db/issues)
4
+ * home :: [github.com/sportdb/footty](https://github.com/sportdb/footty)
5
+ * bugs :: [github.com/sportdb/footty/issues](https://github.com/sportdb/footty/issues)
6
6
  * gem :: [rubygems.org/gems/fbtxt2json](https://rubygems.org/gems/fbtxt2json)
7
7
  * rdoc :: [rubydoc.info/gems/fbtxt2json](http://rubydoc.info/gems/fbtxt2json)
8
8
 
@@ -29,10 +29,16 @@ resulting in:
29
29
  ```
30
30
  Usage: fbtxt2json [options] PATH
31
31
  --verbose, --debug turn on verbose / debug output (default: false)
32
- -o, --output PATH output to file
32
+ -o, --output PATH output to file / dir
33
33
  ```
34
34
 
35
35
 
36
+ Note - the football.txt to .json converter works in two modes. (1) you can pass in one or more files to concat(enate) into one .json output or (2) you can pass in one or more directories to convert all files (automagically) one-by-one.
37
+
38
+
39
+
40
+ ### Concat(enate) one or more files into one .json output
41
+
36
42
  Let's try to convert the "Euro" European Championship 2024
37
43
  in the Football.TXT format (see [`euro/2024--germany/euro.txt`](https://github.com/openfootball/euro/blob/master/2024--germany/euro.txt)) to JSON:
38
44
 
@@ -114,6 +120,55 @@ to output into a file use the `-o/--output` option:
114
120
  $ fbtxt2json england/2024-25/1-premierleague.txt -o en.json
115
121
  ```
116
122
 
123
+
124
+ ### (Auto-)convert one or more directories
125
+
126
+ Let's try to convert the England directory (repo), that is, all datafiles
127
+ in the Football.TXT format (see [`/england`](https://github.com/openfootball/england)) to JSON:
128
+
129
+ ```
130
+ $ fbtxt2json england
131
+ ```
132
+
133
+ resulting in:
134
+
135
+ ```
136
+ england/
137
+ 2024-25/
138
+ 1-premierleague.json
139
+ 2-championship.json
140
+ 3-league1.json
141
+ 4-league2.json
142
+ 5-nationalleague.json
143
+ eflcup.json
144
+ facup.json
145
+ ...
146
+ ```
147
+
148
+ Note - by default all `.txt` file extensions get changed to `.json`.
149
+ To use a different output directory use the `-o/--output` option. Example:
150
+
151
+ ```
152
+ $ fbtxt2json england -o ./o
153
+ ```
154
+
155
+ resulting in:
156
+
157
+ ```
158
+ o/
159
+ 2024-25/
160
+ 1-premierleague.json
161
+ 2-championship.json
162
+ 3-league1.json
163
+ 4-league2.json
164
+ 5-nationalleague.json
165
+ eflcup.json
166
+ facup.json
167
+ ...
168
+ ...
169
+ ```
170
+
171
+
117
172
  That's it.
118
173
 
119
174
 
data/Rakefile CHANGED
@@ -2,12 +2,12 @@ require 'hoe'
2
2
 
3
3
 
4
4
  Hoe.spec 'fbtxt2json' do
5
- self.version = '0.1.0'
5
+ self.version = '0.2.1'
6
6
 
7
7
  self.summary = "fbtxt2json - convert football.txt match schedules & more to json"
8
8
  self.description = summary
9
9
 
10
- self.urls = { home: 'https://github.com/sportdb/sport.db' }
10
+ self.urls = { home: 'https://github.com/sportdb/footty' }
11
11
 
12
12
  self.author = 'Gerald Bauer'
13
13
  self.email = 'gerald.bauer@gmail.com'
@@ -20,6 +20,8 @@ Hoe.spec 'fbtxt2json' do
20
20
 
21
21
  self.extra_deps = [
22
22
  ['sportdb-quick', '>= 0.2.1'],
23
+ ### note - include fbtok gem for (shared) command-line helpers/machinery!!!
24
+ ['fbtok', '>= 0.3.3'],
23
25
  ]
24
26
 
25
27
  self.spec_extras = {
data/bin/fbtxt2json CHANGED
@@ -4,22 +4,33 @@
4
4
  ## ruby -I ./lib bin/fbtxt2json
5
5
 
6
6
 
7
+ #####
8
+ ## todo
9
+ ## add option for [no]-halt-on-error (default: false)
10
+ ## or use a different (shorter) name e.g. --resume?
11
+
12
+
13
+
7
14
  ## our own code
8
15
  require 'sportdb/quick'
9
16
 
17
+ require 'fbtok' ### check if requires sportdb/quick (no need to duplicate)
18
+
10
19
 
11
20
 
12
21
  require 'optparse'
13
22
 
14
23
 
15
24
 
16
- args = ARGV
17
- opts = { debug: false,
25
+ args = ARGV
26
+ opts = { debug: false,
18
27
  output: nil,
19
- }
28
+ summary: false,
29
+ seasons: [],
30
+ }
20
31
 
21
- parser = OptionParser.new do |parser|
22
- parser.banner = "Usage: #{$PROGRAM_NAME} [options] PATH"
32
+ parser = OptionParser.new do |parser|
33
+ parser.banner = "Usage: #{$PROGRAM_NAME} [options] PATH"
23
34
 
24
35
  ##
25
36
  ## check if git has a offline option?? (use same)
@@ -35,20 +46,35 @@ require 'optparse'
35
46
  end
36
47
 
37
48
  parser.on( "-o PATH", "--output PATH",
38
- "output to file" ) do |output|
49
+ "output to file / dir" ) do |output|
39
50
  opts[:output] = output
40
51
  end
52
+
53
+ parser.on( "--summary",
54
+ "(auto-)generate summary (index.html) page (default: #{opts[:summary]})" ) do |summary|
55
+ opts[:summary] = summary
56
+ end
57
+
58
+ parser.on( "--seasons SEASONS",
59
+ "turn on processing only seasons (default: #{!opts[:seasons].empty?}" ) do |seasons|
60
+ pp seasons
61
+ seasons = seasons.split( /[, ]/ )
62
+ seasons = seasons.map {|season| Season.parse(season) }
63
+ opts[:seasons] = seasons
64
+ end
41
65
  end
42
66
  parser.parse!( args )
43
67
 
68
+
44
69
  puts "OPTS:"
45
70
  p opts
46
71
  puts "ARGV:"
47
72
  p args
48
73
 
49
74
 
75
+
50
76
  paths = if args.empty?
51
- ['../../../openfootball/euro/2021--europe/euro.txt']
77
+ ['/sports/openfootball/euro/2021--europe/euro.txt']
52
78
  else
53
79
  args
54
80
  end
@@ -64,35 +90,130 @@ else
64
90
  end
65
91
 
66
92
 
67
- ## step 1 - concat(enate) all text files into one
68
- txt = String.new
69
- paths.each_with_index do |path,i|
70
- puts "==> reading [#{i+1}/#{paths.size}] >#{path}<..."
71
- txt += "\n\n" if i > 0
72
- txt += read_text( path )
93
+ ###
94
+ ## two modes - process directories or concat(enate)d files
95
+ ##
96
+ ## check if args is a directory
97
+ ##
98
+ dirs = 0
99
+ files = 0
100
+ paths.each do |path|
101
+ if Dir.exist?( path )
102
+ dirs += 1
103
+ elsif File.exist?( path )
104
+ files += 1
105
+ else ## not a file or dir repprt errr
106
+ raise ArgumentError, "file/dir does NOT exist - #{path}"
107
+ end
108
+ end
109
+
110
+ if dirs > 0 && files > 0
111
+ raise ArgumentError, "#{files} file(s), #{dirs} dir(s) - can only process dirs or files but NOT both; sorry"
112
+ end
113
+
114
+
115
+
116
+ def parse( txt,
117
+ summary: nil,
118
+ dump: false ) ### check - name parse_txt or txt_to_json or such - why? why not?
119
+ quick = SportDb::QuickMatchReader.new( txt )
120
+ matches = quick.parse
121
+ name = quick.league_name ## quick hack - get league+season via league_name
122
+
123
+ data = { 'name' => name,
124
+ 'matches' => matches.map {|match| match.as_json }}
125
+
126
+ if dump
127
+ pp data
128
+ puts
129
+ end
130
+ puts " #{matches.size} match(es)"
131
+
132
+ if quick.errors?
133
+ puts "!! #{quick.errors.size} parse error(s):"
134
+ pp quick.errors
135
+ exit 1
136
+ end
137
+
138
+
139
+ if summary
140
+ ## add stats to summary page
141
+ summary << "- #{name} | #{matches.size} match(es)\n"
142
+ end
143
+
144
+ data
73
145
  end
74
146
 
75
- ## step 2 - parse (matches) in the football.txt format
76
- quick = SportDb::QuickMatchReader.new( txt )
77
- matches = quick.parse
78
- name = quick.league_name ## quick hack - get league+season via league_name
79
-
80
- data = { 'name' => name,
81
- 'matches' => matches.map {|match| match.as_json }}
82
- pp data
83
- puts
84
- puts " #{matches.size} match(es)"
85
-
86
- if quick.errors?
87
- puts "!! #{quick.errors.size} parse error(s):"
88
- pp quick.errors
89
- exit 1
90
- end
91
147
 
92
- if opts[:output]
93
- puts "==> writing matches to #{opts[:output]}"
94
- write_json( opts[:output], data )
148
+ if files > 0
149
+ ## step 1 - concat(enate) all text files into one
150
+ txt = String.new
151
+ paths.each_with_index do |path,i|
152
+ puts "==> reading file [#{i+1}/#{paths.size}] >#{path}<..."
153
+ txt += "\n\n" if i > 0
154
+ txt += read_text( path )
155
+ end
156
+
157
+ ## step 2 - parse (matches) in the football.txt format
158
+ data = parse( txt, dump: true )
159
+
160
+ if opts[:output]
161
+ puts "==> writing matches to #{opts[:output]}"
162
+ write_json( opts[:output], data )
163
+ end
164
+ elsif dirs > 0
165
+
166
+ ## use a html pre(formatted) text
167
+ summary = String.new
168
+ summary << "<pre>\n"
169
+ summary << "run on #{Time.now.to_s}\n\n" ## add version and such - why? why not?
170
+
171
+ paths.each_with_index do |path,i|
172
+ puts "==> reading dir [#{i+1}/#{paths.size}] >#{path}<..."
173
+ summary << "==> [#{i+1}/#{paths.size}] dir #{path}\n"
174
+
175
+ ### todo/fix: add seasons filter upstream??
176
+ ##
177
+
178
+ datafiles = SportDb::Parser::Opts._find( path )
179
+ pp datafiles
180
+ puts " #{datafiles.size} datafile(s)"
181
+ summary << " #{datafiles.size} datafile(s)\n\n"
182
+
183
+ datafiles.each do |datafile|
184
+ txt = read_text( datafile )
185
+ data = parse( txt, summary: summary )
186
+
187
+ if opts[:output]
188
+ ### norm - File.expand_path !!!
189
+ ## note - use '.' to use (relative to) local directory !!!
190
+ reldir = File.expand_path(File.dirname( path )) ## keep last dir (in relative name)
191
+ relpath = datafile.sub( reldir+'/', '' )
192
+ dir = File.dirname( relpath )
193
+ ## puts " reldir = #{reldir}, datafile = #{datafile}"
194
+ ## puts " relpath = #{relpath}, dir = #{dir}"
195
+ basename = File.basename( relpath, File.extname(relpath))
196
+ outpath = "#{opts[:output]}/#{dir}/#{basename}.json"
197
+ else
198
+ dir = File.dirname( datafile )
199
+ basename = File.basename( datafile, File.extname(datafile) )
200
+ outpath = "#{dir}/#{basename}.json"
201
+ end
202
+ puts " writing matches to #{outpath}"
203
+ write_json( outpath, data )
95
204
  end
205
+ end
206
+
207
+ summary << "</pre>"
208
+ puts summary
209
+ if opts[:summary]
210
+ write_text( "#{opts[:output]}/index.html", summary )
211
+ end
212
+ else
213
+ ## do nothing; no args
214
+ end
215
+
216
+
96
217
 
97
218
 
98
219
  puts "bye"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fbtxt2json
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.1
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-30 00:00:00.000000000 Z
11
+ date: 2025-04-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sportdb-quick
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: 0.2.1
27
+ - !ruby/object:Gem::Dependency
28
+ name: fbtok
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 0.3.3
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 0.3.3
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: rdoc
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -50,14 +64,14 @@ dependencies:
50
64
  requirements:
51
65
  - - "~>"
52
66
  - !ruby/object:Gem::Version
53
- version: '4.1'
67
+ version: '4.2'
54
68
  type: :development
55
69
  prerelease: false
56
70
  version_requirements: !ruby/object:Gem::Requirement
57
71
  requirements:
58
72
  - - "~>"
59
73
  - !ruby/object:Gem::Version
60
- version: '4.1'
74
+ version: '4.2'
61
75
  description: fbtxt2json - convert football.txt match schedules & more to json
62
76
  email: gerald.bauer@gmail.com
63
77
  executables:
@@ -73,7 +87,7 @@ files:
73
87
  - README.md
74
88
  - Rakefile
75
89
  - bin/fbtxt2json
76
- homepage: https://github.com/sportdb/sport.db
90
+ homepage: https://github.com/sportdb/footty
77
91
  licenses:
78
92
  - Public Domain
79
93
  metadata: {}
@@ -94,7 +108,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
94
108
  - !ruby/object:Gem::Version
95
109
  version: '0'
96
110
  requirements: []
97
- rubygems_version: 3.4.10
111
+ rubygems_version: 3.5.22
98
112
  signing_key:
99
113
  specification_version: 4
100
114
  summary: fbtxt2json - convert football.txt match schedules & more to json