sportdb-parser 0.3.1 → 0.3.3

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: 3721d30a9ec1145f59d6bc84bb9a6cf81330fdafa00314decc2c165f2c6b92c1
4
- data.tar.gz: a50b917e0bc5db3ac21cb4ead5507233cbd91f4b6f3b52668ef74ba8c6db6140
3
+ metadata.gz: 8c4d7c1c55b5122f11fc1fdd863e2b8a5cc929b9ae9c57bcc0322400516ab4b8
4
+ data.tar.gz: f5fcae93a1010e1d74fd4f453cb6a201f8f6e11de1ad0d0c9a572c9bb00bd540
5
5
  SHA512:
6
- metadata.gz: 3e286842bcb5c163d841d414a15d4cbd91359324b88106603e22ebbec19b4cb8ffff3119d92a5c9e302e6aeabbc8a7ba74975efebee11ba275ce1d49f0286c1f
7
- data.tar.gz: f237aedda025eb35bb08b31345941a3f1f073cbf8c3495c1afcf6e45de73f067e47a8a4c55981d5881079a5ca45a04af427908f379555208c98851c5d4751aa1
6
+ metadata.gz: 93cb2dc95acf74b1a26088afe3162f0f87a25e949d3f81cd6408c35ec9c42d7309a7c5f59a4c29870146b72e77ed6d5bc3e14c754abf2925b1564b55cafe0ac3
7
+ data.tar.gz: 6de22cc1e40f8e423786cef7386ae890533a627b6877f6f17c73d47e6956b2de181c6f3d357a731be4476781c363abaab0de9b21c83a4f88f8b058f8a3a7d005
data/CHANGELOG.md CHANGED
@@ -1,4 +1,4 @@
1
- ### 0.3.1
1
+ ### 0.3.3
2
2
 
3
3
  ### 0.0.1 / 2024-07-12
4
4
 
data/Manifest.txt CHANGED
@@ -4,8 +4,10 @@ README.md
4
4
  Rakefile
5
5
  bin/fbtok
6
6
  lib/sportdb/parser.rb
7
+ lib/sportdb/parser/fbtok/main.rb
7
8
  lib/sportdb/parser/lang.rb
8
9
  lib/sportdb/parser/linter.rb
10
+ lib/sportdb/parser/opts.rb
9
11
  lib/sportdb/parser/outline_reader.rb
10
12
  lib/sportdb/parser/parser.rb
11
13
  lib/sportdb/parser/token-date.rb
data/bin/fbtok CHANGED
@@ -6,61 +6,7 @@
6
6
  require 'sportdb/parser'
7
7
 
8
8
 
9
- require 'optparse' ## check - already auto-required in cocos? keep? why? why not?
10
-
11
-
12
- args=ARGV
13
-
14
-
15
- opts = {
16
- debug: true,
17
- metal: false,
18
- }
19
-
20
- parser = OptionParser.new do |parser|
21
- parser.banner = "Usage: #{$PROGRAM_NAME} [options]"
22
-
23
- parser.on( "--verbose", "--debug",
24
- "turn on verbose / debug output (default: #{opts[:debug]})" ) do |debug|
25
- opts[:debug] = true
26
- end
27
-
28
- parser.on( "--metal",
29
- "turn off typed parse tree; show to the metal tokens"+
30
- " (default: #{opts[:metal]})" ) do |metal|
31
- opts[:metal] = true
32
- end
33
- end
34
- parser.parse!( args )
35
-
36
- puts "OPTS:"
37
- p opts
38
- puts "ARGV:"
39
- p args
40
-
41
-
42
- SportDb::Parser::Linter.debug = true if opts[:debug]
43
-
44
- linter = SportDb::Parser::Linter.new
45
- errors = []
46
-
47
- paths = args
48
- paths.each_with_index do |path,i|
49
- puts "==> [#{i+1}/#{paths.size}] reading >#{path}<..."
50
- linter.read( path, parse: !opts[:metal] )
51
-
52
- errors += linter.errors if linter.errors?
53
- end
54
-
55
- if errors.size > 0
56
- puts
57
- pp errors
58
- puts
59
- puts "!! #{errors.size} parse error(s) in #{paths.size} datafiles(s)"
60
- else
61
- puts
62
- puts "OK no parse errors found in #{paths.size} datafile(s)"
63
- end
9
+ Fbtok.main( ARGV )
64
10
 
65
11
 
66
12
  puts "bye"
@@ -0,0 +1,139 @@
1
+
2
+ module Fbtok
3
+ def self.main( args=ARGV )
4
+
5
+ opts = {
6
+ debug: true,
7
+ metal: false,
8
+ file: nil,
9
+ }
10
+
11
+ parser = OptionParser.new do |parser|
12
+ parser.banner = "Usage: #{$PROGRAM_NAME} [options]"
13
+
14
+
15
+ parser.on( "-q", "--quiet",
16
+ "less debug output/messages - default is (#{!opts[:debug]})" ) do |debug|
17
+ opts[:debug] = false
18
+ end
19
+ # parser.on( "--verbose", "--debug",
20
+ # "turn on verbose / debug output (default: #{opts[:debug]})" ) do |debug|
21
+ # opts[:debug] = true
22
+ # end
23
+
24
+ parser.on( "--metal",
25
+ "turn off typed parse tree; show to the metal tokens"+
26
+ " (default: #{opts[:metal]})" ) do |metal|
27
+ opts[:metal] = true
28
+ end
29
+
30
+ parser.on( "-f FILE", "--file FILE",
31
+ "read datafiles (pathspecs) via .csv file") do |file|
32
+ opts[:file] = file
33
+ end
34
+ end
35
+ parser.parse!( args )
36
+
37
+ puts "OPTS:"
38
+ p opts
39
+ puts "ARGV:"
40
+ p args
41
+
42
+
43
+ ## todo/check - use packs or projects or such
44
+ ## instead of specs - why? why not?
45
+ specs = []
46
+ if opts[:file]
47
+ recs = read_csv( opts[:file] )
48
+ pp recs
49
+ ## note - make pathspecs relative to passed in file arg!!!
50
+ basedir = File.dirname( opts[:file] )
51
+ recs.each do |rec|
52
+ paths = SportDb::Parser::Opts.find( rec['path'], dir: basedir )
53
+ specs << [paths, rec]
54
+ end
55
+ else
56
+ paths = if args.empty?
57
+ [
58
+ '../../../openfootball/euro/2021--europe/euro.txt',
59
+ '../../../openfootball/euro/2024--germany/euro.txt',
60
+ ]
61
+ else
62
+ ## check for directories
63
+ ## and auto-expand
64
+ SportDb::Parser::Opts.expand_args( args )
65
+ end
66
+ specs << [paths, {}]
67
+ end
68
+
69
+
70
+ SportDb::Parser::Linter.debug = true if opts[:debug]
71
+
72
+ linter = SportDb::Parser::Linter.new
73
+
74
+
75
+ specs.each_with_index do |(paths, rec),i|
76
+ errors = []
77
+
78
+ paths.each_with_index do |path,j|
79
+ puts "==> [#{j+1}/#{paths.size}] reading >#{path}<..."
80
+ linter.read( path, parse: !opts[:metal] )
81
+
82
+ errors += linter.errors if linter.errors?
83
+ end
84
+
85
+ if errors.size > 0
86
+ puts
87
+ pp errors
88
+ puts
89
+ puts "!! #{errors.size} parse error(s) in #{paths.size} datafiles(s)"
90
+ else
91
+ puts
92
+ puts "OK no parse errors found in #{paths.size} datafile(s)"
93
+ end
94
+
95
+ ## add errors to rec via rec['errors'] to allow
96
+ ## for further processing/reporting
97
+ rec['errors'] = errors
98
+ end
99
+
100
+
101
+ ###
102
+ ## generate a report if --file option used
103
+ if opts[:file]
104
+
105
+ buf = String.new
106
+
107
+ buf << "# fbtok summary report - #{specs.size} dataset(s)\n\n"
108
+
109
+ specs.each_with_index do |(paths, rec),i|
110
+ errors = rec['errors']
111
+
112
+ if errors.size > 0
113
+ buf << "!! #{errors.size} ERROR(S) "
114
+ else
115
+ buf << " OK "
116
+ end
117
+ buf << "%-20s" % rec['path']
118
+ buf << " - #{paths.size} datafile(s)"
119
+ buf << "\n"
120
+
121
+ if errors.size > 0
122
+ buf << errors.pretty_inspect
123
+ buf << "\n"
124
+ end
125
+ end
126
+
127
+ puts
128
+ puts "SUMMARY:"
129
+ puts buf
130
+
131
+ # maybe write out in the future?
132
+ # basedir = File.dirname( opts[:file] )
133
+ # basename = File.basename( opts[:file], File.extname( opts[:file] ))
134
+ end
135
+
136
+
137
+
138
+ end # method self.main
139
+ end # module Fbtok
@@ -26,11 +26,13 @@ end
26
26
 
27
27
 
28
28
  ROUND_RE = %r{^(
29
-
30
29
  ## add special case for group play-off rounds!
31
30
  ## group 2 play-off (e.g. worldcup 1954, 1958)
32
- (?: Group [ ] [a-z0-9]+ [ ]
33
- Play-?offs?
31
+ ##
32
+ ### note - allow Group ("stand-alone") as "generic" round for now
33
+ ## BUT do NOT allow Group 1, Group 2, Group A, Group B, etc.
34
+ (?: Group [ ] [A-Z0-9]+ [ ] Play-?offs? |
35
+ Group
34
36
  )
35
37
  |
36
38
  # round - note - requiers number e.g. round 1,2, etc.
@@ -44,29 +46,30 @@ ROUND_RE = %r{^(
44
46
  )
45
47
  |
46
48
  ## starting with qual(ification)
47
- ## Qual. Round 1 / Qual. Round 2 / Qual. Round 3
48
- (?: Qual \. [ ]
49
- Round
50
- [ ] [1-9][0-9]*
51
- )
49
+ ## Qual. Round 1 / Qual. Round 2 / Qual. Round 3
50
+ ## or
51
+ ## Playoff Round 1
52
+ ## Play-in Round 1
53
+ (?: (?: Qual \. |
54
+ Play-?off |
55
+ Play-?in
56
+ )
57
+ [ ] Round [ ] [1-9][0-9]* )
52
58
  |
53
59
  ## 1. Round / 2. Round / 3. Round / etc.
54
- ## Play-off Round
55
60
  ## First Round
61
+ ## Play-off Round
56
62
  ## Final Round (e.g. Worldcup 1950)
57
63
  (?:
58
64
  (?: [1-9][0-9]* \. |
59
- Play-?off |
60
65
  1st | First |
61
66
  2nd | Second |
67
+ Play-?off |
62
68
  Final
63
69
  )
64
70
  [ ] Round
65
71
  )
66
72
  |
67
- ## Playoff Round 1
68
- (?: Play-?off [ ] Round [ ] [1-9][0-9]* )
69
- |
70
73
  ## starting with preliminary
71
74
  # e.g. Preliminary round
72
75
  (?: Preliminary [ ]
@@ -135,6 +138,11 @@ ROUND_RE = %r{^(
135
138
  )
136
139
  [ ] Replays?
137
140
  )
141
+ |
142
+ ## more
143
+ (?:
144
+ Reclassification
145
+ )
138
146
  )$}ix
139
147
 
140
148
 
@@ -0,0 +1,78 @@
1
+
2
+ module SportDb
3
+ class Parser
4
+
5
+
6
+ ###
7
+ ## note - Opts Helpers for now nested inside Parser - keep here? why? why not?
8
+ class Opts
9
+
10
+ SEASON_RE = %r{ (?:
11
+ \d{4}-\d{2}
12
+ | \d{4}(--[a-z0-9_-]+)?
13
+ )
14
+ }x
15
+ SEASON = SEASON_RE.source ## "inline" helper for embedding in other regexes - keep? why? why not?
16
+
17
+
18
+ ## note: if pattern includes directory add here
19
+ ## (otherwise move to more "generic" datafile) - why? why not?
20
+ MATCH_RE = %r{ (?: ^|/ ) # beginning (^) or beginning of path (/)
21
+ #{SEASON}
22
+ /[a-z0-9_-]+\.txt$ ## txt e.g /1-premierleague.txt
23
+ }x
24
+
25
+
26
+ def self.find( path, dir: nil )
27
+ ## check - rename dir
28
+ ## use root_dir or work_dir or cd or such - why? why not?
29
+
30
+ datafiles = []
31
+
32
+ ## note: normalize path - use File.expand_path ??
33
+ ## change all backslash to slash for now
34
+ ## path = path.gsub( "\\", '/' )
35
+ path = if dir
36
+ File.expand_path( path, File.expand_path( dir ))
37
+ else
38
+ File.expand_path( path )
39
+ end
40
+
41
+ ## check all txt files
42
+ ## note: incl. files starting with dot (.)) as candidates
43
+ ## (normally excluded with just *)
44
+ candidates = Dir.glob( "#{path}/**/{*,.*}.txt" )
45
+ ## pp candidates
46
+ candidates.each do |candidate|
47
+ datafiles << candidate if MATCH_RE.match( candidate )
48
+ end
49
+
50
+ ## pp datafiles
51
+ datafiles
52
+ end
53
+
54
+
55
+ def self.expand_args( args )
56
+ paths = []
57
+
58
+ args.each do |arg|
59
+ ## check if directory
60
+ if Dir.exist?( arg )
61
+ datafiles = find( arg )
62
+ puts
63
+ puts " found #{datafiles.size} match txt datafiles in #{arg}"
64
+ pp datafiles
65
+ paths += datafiles
66
+ else
67
+ ## assume it's a file
68
+ paths << arg
69
+ end
70
+ end
71
+
72
+ paths
73
+ end
74
+ end # class Opts
75
+
76
+
77
+ end # class Parser
78
+ end # module SportDb
@@ -4,7 +4,7 @@ module SportDb
4
4
  module Parser
5
5
  MAJOR = 0 ## todo: namespace inside version or something - why? why not??
6
6
  MINOR = 3
7
- PATCH = 1
7
+ PATCH = 3
8
8
  VERSION = [MAJOR,MINOR,PATCH].join('.')
9
9
 
10
10
  def self.version
@@ -3,6 +3,10 @@ require 'cocos'
3
3
  require 'season/formats' # e.g. Season() support machinery
4
4
 
5
5
 
6
+ ## more stdlibs
7
+ require 'optparse' ## check - already auto-required in cocos? keep? why? why not?
8
+
9
+
6
10
 
7
11
  ####
8
12
  # try a (simple) tokenizer/parser with regex
@@ -28,7 +32,12 @@ require_relative 'parser/parser'
28
32
  ## todo/check - move outline reader upstream to cocos - why? why not?
29
33
  ## use read_outline(), parse_outline() - why? why not?
30
34
  require_relative 'parser/outline_reader'
35
+
36
+
37
+ require_relative 'parser/opts'
31
38
  require_relative 'parser/linter'
39
+ require_relative 'parser/fbtok/main'
40
+
32
41
 
33
42
  ###
34
43
  # make parser api (easily) available - why? why not?
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sportdb-parser
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.3.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-09-18 00:00:00.000000000 Z
11
+ date: 2024-09-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: cocos
@@ -88,8 +88,10 @@ files:
88
88
  - Rakefile
89
89
  - bin/fbtok
90
90
  - lib/sportdb/parser.rb
91
+ - lib/sportdb/parser/fbtok/main.rb
91
92
  - lib/sportdb/parser/lang.rb
92
93
  - lib/sportdb/parser/linter.rb
94
+ - lib/sportdb/parser/opts.rb
93
95
  - lib/sportdb/parser/outline_reader.rb
94
96
  - lib/sportdb/parser/parser.rb
95
97
  - lib/sportdb/parser/token-date.rb