fbtok 0.4.0 → 0.4.2

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: d2f0738b7fe70aa6b73cb62e99c6319fe782be09aca0f73f7891a037b98ba020
4
- data.tar.gz: b801c24152bac941a766f1340409e3a32aeefb69a217bff94f7f86953749d2b1
3
+ metadata.gz: 0bd9a1ff623cc7049c87db9b8344799d9ee49294bf1cd8f2a48cd57886fd0b89
4
+ data.tar.gz: 35acfef6ccd67319d218e8dd849e3772042d8190afe786f73ba98fa19ca2418b
5
5
  SHA512:
6
- metadata.gz: 406113d724520254adf88aedbe49a6a11ea46aaeaebe85666f2a7a78ea1712936508db4b27bdda928436551d64f52503bc7c9cf98aef464af3cb200917ff324d
7
- data.tar.gz: 9e5d237e6d3344b5c4ffb005d5d0c32d40003933ed99594d5e7a6480b6779254f92a15bfde8c4cc6b8b67feb39f4e40e8489d8cae009708eccccbf13b05fdc6b
6
+ metadata.gz: 20054a913668ac69f58bc17ebbc4bdc6de6528639f64a52b60925e87129f05fbd9bfe4a87c9ea8be55bf0d5010280e0fdf2f56b8b1b892b9f4744d99aa66239b
7
+ data.tar.gz: c7980b69a62273c6fffd4c7025ccb086a96070ee8dff51248fab1ddf08ef2625de467e646c4496570f163519d88985e06698c1452e639419c629521320bc26c5
data/CHANGELOG.md CHANGED
@@ -1,4 +1,4 @@
1
- ### 0.4.0
1
+ ### 0.4.2
2
2
  ### 0.0.1 / 2025-01-02
3
3
 
4
4
  * Everything is new. First release.
data/Manifest.txt CHANGED
@@ -3,8 +3,13 @@ Manifest.txt
3
3
  README.md
4
4
  Rakefile
5
5
  bin/fbquick
6
+ bin/fbquik
6
7
  bin/fbtok
7
8
  bin/fbtree
8
9
  bin/fbx
9
10
  lib/fbtok.rb
11
+ lib/fbtok/fbquick.rb
12
+ lib/fbtok/fbtok.rb
13
+ lib/fbtok/fbtree.rb
14
+ lib/fbtok/fbx.rb
10
15
  lib/fbtok/pathspec.rb
data/README.md CHANGED
@@ -25,23 +25,25 @@ $ gem install fbtok
25
25
  - depends on sportdb-parser
26
26
 
27
27
  get help
28
+
28
29
  ```
29
30
  $ fbtok -h
30
31
  $ fbtree -h
31
32
  ```
32
33
 
33
34
  run on single / individual (data)files
34
- ````
35
+
36
+ ```
35
37
  $ fbtok england/2025-26/1-permierleague.txt
36
38
  $ fbtok worldcup/min/2022.txt
37
39
 
38
40
  $ fbtree england/2025-26/1-permierleague.txt
39
41
  $ fbtree worldcup/min/2022.txt
40
-
41
42
  ```
42
43
 
43
44
  or on directories (auto-collecting all datafiles)
44
45
 
46
+ ```
45
47
  $ fbtok england
46
48
  $ fbtok worldcup
47
49
 
@@ -50,31 +52,32 @@ $ fbtree worldcup
50
52
  ```
51
53
 
52
54
 
53
-
54
- ### fbquick & fbx - use quick match reader & dump match schedule
55
+ ### fbquick/fbquik & fbx - use quick match reader & dump match schedule
55
56
 
56
57
  - depends on sportdb-quick (& sportdb-parser)
57
58
 
58
59
  get help
60
+
59
61
  ```
60
- $ fbquick -h
62
+ $ fbquik -h
61
63
  $ fbx -h
62
64
  ```
63
65
 
64
66
  run on single / individual (data)files
65
- ````
66
- $ fbquick england/2025-26/1-permierleague.txt
67
- $ fbquick worldcup/min/2022.txt
67
+
68
+ ```
69
+ $ fbquik england/2025-26/1-permierleague.txt
70
+ $ fbquik worldcup/min/2022.txt
68
71
 
69
72
  $ fbx england/2025-26/1-permierleague.txt
70
73
  $ fbx worldcup/min/2022.txt
71
-
72
74
  ```
73
75
 
74
76
  or on directories (auto-collecting all datafiles)
75
77
 
76
- $ fbquick england
77
- $ fbquick worldcup
78
+ ```
79
+ $ fbquik england
80
+ $ fbquik worldcup
78
81
  ```
79
82
 
80
83
  note: `fbx` only works with single / individual (data)files
@@ -82,8 +85,6 @@ note: `fbx` only works with single / individual (data)files
82
85
 
83
86
 
84
87
 
85
-
86
-
87
88
  ## Questions? Comments?
88
89
 
89
90
  Yes, you can. More than welcome.
data/Rakefile CHANGED
@@ -2,7 +2,7 @@ require 'hoe'
2
2
 
3
3
 
4
4
  Hoe.spec 'fbtok' do
5
- self.version = '0.4.0'
5
+ self.version = '0.4.2'
6
6
 
7
7
  self.summary = "fbtok - football.txt lint tools incl. tokenizer, parser & more"
8
8
  self.description = summary
data/bin/fbquick CHANGED
@@ -7,130 +7,16 @@
7
7
  ## -or-
8
8
  ## $ ruby -I ../parser/lib -I ../quick/lib -I ./lib bin/fbquick
9
9
 
10
- ##
11
- ## todo/fix - add (shortcut) alias fbquik,fbqk - why? why not?
12
10
 
11
+ ## quick hack
12
+ ## if available always use latest (local) source version
13
+ $LOAD_PATH.unshift( '/sports/sportdb/sport.db.v2/parser/lib' )
14
+ $LOAD_PATH.unshift( '/sports/sportdb/sport.db.v2/quick/lib' )
13
15
 
14
- ## our own code
15
- require 'fbtok'
16
-
17
-
18
-
19
-
20
- args = ARGV
21
- opts = { debug: false,
22
- file: nil,
23
- }
24
-
25
- parser = OptionParser.new do |parser|
26
- parser.banner = "Usage: #{$PROGRAM_NAME} [options]"
27
-
28
- ##
29
- ## check if git has a offline option?? (use same)
30
- ## check for other tools - why? why not?
31
- # parser.on( "-q", "--quiet",
32
- # "less debug output/messages - default is (#{!opts[:debug]})" ) do |debug|
33
- # opts[:debug] = false
34
- # end
35
- parser.on( "--verbose", "--debug",
36
- "turn on verbose / debug output (default: #{opts[:debug]})" ) do |debug|
37
- opts[:debug] = true
38
- end
39
-
40
- parser.on( "-f FILE", "--file FILE",
41
- "read datafiles (pathspecs) via .csv file") do |file|
42
- opts[:file] = file
43
- end
44
-
45
-
46
- end
47
- parser.parse!( args )
48
-
49
-
50
-
51
- if opts[:debug]
52
- puts "OPTS:"
53
- p opts
54
- puts "ARGV:"
55
- p args
56
-
57
- SportDb::QuickMatchReader.debug = true
58
- SportDb::MatchParser.debug = true
59
- else
60
- SportDb::QuickMatchReader.debug = false
61
- SportDb::MatchParser.debug = false
62
- LogUtils::Logger.root.level = :info
63
- end
64
-
65
-
66
- ## todo/check - use packs or projects or such
67
- ## instead of specs - why? why not?
68
- specs = if opts[:file]
69
- read_pathspecs( opts[:file] )
70
- else
71
- args = ['/sports/openfootball/euro/2021--europe/euro.txt',
72
- '/sports/openfootball/euro/2024--germany/euro.txt'] if args.empty?
73
16
 
74
- build_pathspecs( args )
75
- end
76
-
77
- pp specs
78
-
79
-
80
-
81
- specs.each_with_index do |rec,i|
82
- datafiles = rec['datafiles']
83
- errors = []
84
-
85
- datafiles.each_with_index do |path,j|
86
- puts "==> [#{i+1}/#{specs.size}, #{j+1}/#{datafiles.size}] reading >#{path}<..."
87
- txt = read_text( path )
88
- quick = SportDb::QuickMatchReader.new( txt )
89
- matches = quick.parse
90
-
91
- if quick.errors?
92
- puts "!! #{quick.errors.size} error(s):"
93
- pp quick.errors
94
-
95
- quick.errors.each do |err|
96
- errors << [ path, *err ] # note: use splat (*) to add extra values (starting with msg)
97
- end
98
- end
99
- puts " #{matches.size} match(es)"
100
- end
101
-
102
- if errors.size > 0
103
- puts
104
- puts "!! #{errors.size} PARSE ERRORS in #{datafiles.size} datafile(s)"
105
- pp errors
106
- else
107
- puts
108
- puts " OK - no parse errors in #{datafiles.size} datafile(s)"
109
- end
110
-
111
- ## add errors to rec via rec['errors'] to allow
112
- ## for further processing/reporting
113
- rec['errors'] = errors
114
- end
115
-
116
-
117
-
118
- ###
119
- ## generate a report if --file option used
120
- if opts[:file]
121
- buf = SportDb::PathspecReport.new(
122
- specs,
123
- title: 'fbquick summary report' ).build
124
-
125
- puts
126
- puts "SUMMARY:"
127
- puts buf
128
-
129
- # maybe write out in the future?
130
- # basedir = File.dirname( opts[:file] )
131
- # basename = File.basename( opts[:file], File.extname( opts[:file] ))
132
- end
133
17
 
18
+ ## our own code
19
+ require 'fbtok'
134
20
 
135
21
 
136
- puts "bye"
22
+ Fbquick.main
data/bin/fbquik ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ ## tip: to test run:
4
+ ## $ ruby -I ./lib bin/fbquik
5
+
6
+ ## quick hack
7
+ ## if available always use latest (local) source version
8
+ $LOAD_PATH.unshift( '/sports/sportdb/sport.db.v2/parser/lib' )
9
+ $LOAD_PATH.unshift( '/sports/sportdb/sport.db.v2/quick/lib' )
10
+
11
+
12
+ ## our own code
13
+ require 'fbtok'
14
+
15
+
16
+ Fbquick.main
data/bin/fbtok CHANGED
@@ -3,125 +3,12 @@
3
3
  ## tip: to test run:
4
4
  ## $ ruby -I ./lib bin/fbtok
5
5
 
6
- require 'fbtok'
7
-
8
- args = ARGV
9
-
10
-
11
- opts = {
12
- debug: true,
13
- warn: false,
14
- file: nil,
15
- }
16
-
17
- parser = OptionParser.new do |parser|
18
- parser.banner = "Usage: #{$PROGRAM_NAME} [options] PATH"
19
-
20
-
21
- parser.on( "-q", "--quiet",
22
- "less debug output/messages (default: #{!opts[:debug]})" ) do |debug|
23
- opts[:debug] = false
24
- end
25
- parser.on( "--verbose", "--debug",
26
- "turn on verbose / debug output (default: #{opts[:debug]})" ) do |debug|
27
- opts[:debug] = true
28
- end
29
- parser.on( "-w", "--warn",
30
- "turn warnings into errors (default: #{opts[:warn]})" ) do |warn|
31
- opts[:warn] = true
32
- end
33
-
34
-
35
- parser.on( "-f FILE", "--file FILE",
36
- "read datafiles (pathspecs) via .csv file") do |file|
37
- opts[:file] = file
38
- ## note: for batch (massive) processing auto-set debug (verbose output) to false (as default)
39
- opts[:debug] = false
40
- end
41
- end
42
- parser.parse!( args )
43
-
44
-
45
-
46
- if opts[:debug]
47
- puts "OPTS:"
48
- p opts
49
- puts "ARGV:"
50
- p args
51
- end
52
-
53
-
54
- # SportDb::Parser::Linter.debug = opts[:debug]
55
- # SportDb::Parser::Linter.warn = opts[:warn]
56
-
57
-
58
-
59
- ## todo/check - use packs or projects or such
60
- ## instead of specs - why? why not?
61
- specs = if opts[:file]
62
- read_pathspecs( opts[:file] )
63
- else
64
- args = ['/sports/openfootball/euro/2021--europe/euro.txt',
65
- '/sports/openfootball/euro/2024--germany/euro.txt'] if args.empty?
6
+ ## quick hack
7
+ ## if available always use latest (local) source version
8
+ $LOAD_PATH.unshift( '/sports/sportdb/sport.db.v2/parser/lib' )
66
9
 
67
- build_pathspecs( args )
68
- end
69
10
 
11
+ require 'fbtok'
70
12
 
71
- pp specs
72
-
73
-
74
-
75
- specs.each_with_index do |rec,i|
76
- datafiles = rec['datafiles']
77
-
78
- errors = []
79
-
80
- datafiles.each_with_index do |path,j|
81
- puts "==> [#{i+1}/#{specs.size}, #{j+1}/#{datafiles.size}] reading >#{path}<..."
82
-
83
- txt = read_text( path )
84
- lexer = SportDb::Lexer.new( txt, debug: opts[:debug] )
85
- tokens, more_errors = lexer.tokenize_with_errors
86
-
87
- ####
88
- ## todo - report error on empty file (no tokens!!!)
89
-
90
- puts " #{tokens.size} token(s)"
91
-
92
- errors += more_errors if more_errors.size > 0
93
- end
94
-
95
- if errors.size > 0
96
- puts
97
- pp errors
98
- puts
99
- puts "!! #{errors.size} tokenize error(s) in #{datafiles.size} datafiles(s)"
100
- else
101
- puts
102
- puts "OK no tokenize errors found in #{datafiles.size} datafile(s)"
103
- end
104
-
105
- ## add errors to rec via rec['errors'] to allow
106
- ## for further processing/reporting
107
- rec['errors'] = errors
108
- end
109
-
110
-
111
- ###
112
- ## generate a report if --file option used
113
- if opts[:file]
114
- buf = SportDb::PathspecReport.new(
115
- specs,
116
- title: 'fbtok summary report' ).build
117
-
118
- puts
119
- puts "SUMMARY:"
120
- puts buf
121
-
122
- # maybe write out in the future?
123
- # basedir = File.dirname( opts[:file] )
124
- # basename = File.basename( opts[:file], File.extname( opts[:file] ))
125
- end
126
13
 
127
- puts "bye"
14
+ Fbtok.main
data/bin/fbtree CHANGED
@@ -3,140 +3,11 @@
3
3
  ## tip: to test run:
4
4
  ## $ ruby -I ./lib bin/fbtree
5
5
 
6
- require 'fbtok'
7
-
8
- args = ARGV
9
-
10
-
11
- opts = {
12
- debug: true,
13
- warn: false,
14
- file: nil,
15
- }
16
-
17
- parser = OptionParser.new do |parser|
18
- parser.banner = "Usage: #{$PROGRAM_NAME} [options] PATH"
19
-
20
-
21
- parser.on( "-q", "--quiet",
22
- "less debug output/messages (default: #{!opts[:debug]})" ) do |debug|
23
- opts[:debug] = false
24
- end
25
- parser.on( "--verbose", "--debug",
26
- "turn on verbose / debug output (default: #{opts[:debug]})" ) do |debug|
27
- opts[:debug] = true
28
- end
29
- parser.on( "-w", "--warn",
30
- "turn warnings into errors (default: #{opts[:warn]})" ) do |warn|
31
- opts[:warn] = true
32
- end
33
-
34
-
35
- parser.on( "-f FILE", "--file FILE",
36
- "read datafiles (pathspecs) via .csv file") do |file|
37
- opts[:file] = file
38
- ## note: for batch (massive) processing auto-set debug (verbose output) to false (as default)
39
- opts[:debug] = false
40
- end
41
-
42
- end
43
- parser.parse!( args )
44
-
45
-
46
- if opts[:debug]
47
- puts "OPTS:"
48
- p opts
49
- puts "ARGV:"
50
- p args
51
- end
52
-
53
-
54
- # SportDb::Parser::Linter.debug = opts[:debug]
55
- # SportDb::Parser::Linter.warn = opts[:warn]
56
-
57
-
58
-
59
-
60
- ## todo/check - use packs or projects or such
61
- ## instead of specs - why? why not?
62
- specs = if opts[:file]
63
- read_pathspecs( opts[:file] )
64
- else
65
- args = ['/sports/openfootball/euro/2021--europe/euro.txt',
66
- '/sports/openfootball/euro/2024--germany/euro.txt'] if args.empty?
67
-
68
- build_pathspecs( args )
69
- end
70
-
71
6
 
7
+ ## quick hack
8
+ ## if available always use latest (local) source version
9
+ $LOAD_PATH.unshift( '/sports/sportdb/sport.db.v2/parser/lib' )
72
10
 
73
- def dump_tree_stats( tree )
74
- stats = Hash.new(0) ## track counts only for now
75
- tree.each do |node|
76
- stats[ node.class ] += 1
77
- end
78
-
79
- match_count = stats[ RaccMatchParser::MatchLine ]
80
- goal_count = stats[ RaccMatchParser::GoalLine ]
81
- lineup_count = stats[ RaccMatchParser::LineupLine ]
82
-
83
- puts " #{match_count} MatchLine(s)" if match_count > 0
84
- puts " #{goal_count} GoalLine(s)" if goal_count > 0
85
- puts " #{lineup_count} LineupLine(s)" if lineup_count > 0
86
- end
87
-
88
-
89
-
90
-
91
-
92
- specs.each_with_index do |rec,i|
93
- datafiles = rec['datafiles']
94
-
95
- errors = []
96
-
97
- datafiles.each_with_index do |path,j|
98
- puts "==> [#{i+1}/#{specs.size}, #{j+1}/#{datafiles.size}] reading >#{path}<..."
99
-
100
- txt = read_text( path )
101
- parser = RaccMatchParser.new( txt, debug: opts[:debug] )
102
- tree = parser.parse
103
-
104
- dump_tree_stats( tree )
105
-
106
- errors += parser.errors if parser.errors?
107
- end
108
-
109
- if errors.size > 0
110
- puts
111
- pp errors
112
- puts
113
- puts "!! #{errors.size} parse error(s) in #{datafiles.size} datafiles(s)"
114
- else
115
- puts
116
- puts "OK no parse errors found in #{datafiles.size} datafile(s)"
117
- end
118
-
119
- ## add errors to rec via rec['errors'] to allow
120
- ## for further processing/reporting
121
- rec['errors'] = errors
122
- end
123
-
124
-
125
- ###
126
- ## generate a report if --file option used
127
- if opts[:file]
128
-
129
- buf = SportDb::PathspecReport.new(
130
- specs,
131
- title: 'fbtree summary report' ).build
132
-
133
- puts
134
- puts "SUMMARY:"
135
- puts buf
136
-
137
- # maybe write out in the future?
138
- # basedir = File.dirname( opts[:file] )
139
- # basename = File.basename( opts[:file], File.extname( opts[:file] ))
140
- end
11
+ require 'fbtok'
141
12
 
142
- puts "bye"
13
+ Fbtree.main
data/bin/fbx CHANGED
@@ -1,110 +1,18 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  ## tip: to test run:
4
- ## $ ruby -I ./lib -I ../parser/lib bin/fbx
4
+ ## $ ruby -I ./lib bin/fbx
5
5
 
6
- ##
7
- ## todo/fix - use for testing
8
- # reads textfile and dumps results in json
9
- #
10
- # check - keep fbx name or find a differnt name - why? why not?
11
6
 
7
+ ## quick hack
8
+ ## if available always use latest (local) source version
9
+ $LOAD_PATH.unshift( '/sports/sportdb/sport.db.v2/parser/lib' )
10
+ $LOAD_PATH.unshift( '/sports/sportdb/sport.db.v2/quick/lib' )
12
11
 
13
- ## our own code
14
- require 'fbtok'
15
-
16
-
17
- ##
18
- ## read textfile
19
- ## and dump match parse results
20
- ##
21
- ## fbt ../openfootball/.../euro.txt
22
-
23
-
24
-
25
-
26
- args = ARGV
27
- opts = { debug: false,
28
- outline: false }
29
-
30
- parser = OptionParser.new do |parser|
31
- parser.banner = "Usage: #{$PROGRAM_NAME} [options]"
32
-
33
- ##
34
- ## check if git has a offline option?? (use same)
35
- ## check for other tools - why? why not?
36
-
37
-
38
- parser.on( "--verbose", "--debug",
39
- "turn on verbose / debug output (default: #{opts[:debug]})" ) do |debug|
40
- opts[:debug] = debug
41
- end
42
-
43
- # parser.on( "--outline",
44
- # "turn on outline (only) output (default: #{opts[:outline]})" ) do |outline|
45
- # opts[:outline] = outline
46
- # end
47
- end
48
- parser.parse!( args )
49
-
50
-
51
- if opts[:debug]
52
- puts "OPTS:"
53
- p opts
54
- puts "ARGV:"
55
- p args
56
12
 
57
- SportDb::MatchParser.debug = true
58
- else
59
- SportDb::MatchParser.debug = false
60
- LogUtils::Logger.root.level = :info
61
- end
62
13
 
14
+ ## our own code
15
+ require 'fbtok'
63
16
 
64
- args = [
65
- '../../../openfootball/euro/2021--europe/euro.txt',
66
- '../../../openfootball/euro/2024--germany/euro.txt',
67
- ] if args.empty?
68
-
69
- pp args
70
-
71
-
72
- paths = args
73
-
74
-
75
- ## errors = []
76
-
77
-
78
- paths.each_with_index do |path,i|
79
- puts "==> [#{i+1}/#{paths.size}] reading >#{path}<..."
80
-
81
- txt = read_text( path )
82
-
83
- parser = SportDb::MatchParser.new( txt, start: nil )
84
-
85
- auto_conf_teams, matches, rounds, groups = parser.parse
86
-
87
- puts ">>> #{auto_conf_teams.size} teams:"
88
- pp auto_conf_teams
89
- puts ">>> #{matches.size} matches:"
90
- pp matches[0,2] ## print first two matches
91
- puts "..."
92
- puts ">>> #{rounds.size} rounds:"
93
- pp rounds
94
- puts ">>> #{groups.size} groups:"
95
- pp groups
96
- end # each paths
97
-
98
- =begin
99
- if errors.size > 0
100
- puts
101
- pp errors
102
- puts
103
- puts "!! #{errors.size} parse error(s) in #{paths.size} datafiles(s)"
104
- else
105
- puts
106
- puts "OK no parse errors found in #{paths.size} datafile(s)"
107
- end
108
- =end
109
17
 
110
- puts "bye"
18
+ Fbx.main
@@ -0,0 +1,123 @@
1
+
2
+ module Fbquick
3
+
4
+
5
+ def self.main( args=ARGV )
6
+
7
+ opts = { debug: false,
8
+ file: nil,
9
+ }
10
+
11
+ parser = OptionParser.new do |parser|
12
+ parser.banner = "Usage: #{$PROGRAM_NAME} [options] DATAFILE or DIR"
13
+
14
+ ##
15
+ ## check if git has a offline option?? (use same)
16
+ ## check for other tools - why? why not?
17
+ # parser.on( "-q", "--quiet",
18
+ # "less debug output/messages - default is (#{!opts[:debug]})" ) do |debug|
19
+ # opts[:debug] = false
20
+ # end
21
+ parser.on( "--verbose", "--debug",
22
+ "turn on verbose / debug output (default: #{opts[:debug]})" ) do |debug|
23
+ opts[:debug] = true
24
+ end
25
+
26
+ parser.on( "-f FILE", "--file FILE",
27
+ "read datafiles (pathspecs) via .csv file") do |file|
28
+ opts[:file] = file
29
+ end
30
+
31
+
32
+ end
33
+ parser.parse!( args )
34
+
35
+
36
+
37
+ if opts[:debug]
38
+ puts "OPTS:"
39
+ p opts
40
+ puts "ARGV:"
41
+ p args
42
+
43
+ SportDb::QuickMatchReader.debug = true
44
+ SportDb::MatchParser.debug = true
45
+ else
46
+ SportDb::QuickMatchReader.debug = false
47
+ SportDb::MatchParser.debug = false
48
+ LogUtils::Logger.root.level = :info
49
+ end
50
+
51
+
52
+ ## todo/check - use packs or projects or such
53
+ ## instead of specs - why? why not?
54
+ specs = if opts[:file]
55
+ read_pathspecs( opts[:file] )
56
+ else
57
+ args = ['/sports/openfootball/euro/2021--europe/euro.txt',
58
+ '/sports/openfootball/euro/2024--germany/euro.txt'] if args.empty?
59
+
60
+ build_pathspecs( args )
61
+ end
62
+
63
+ pp specs
64
+
65
+
66
+
67
+ specs.each_with_index do |rec,i|
68
+ datafiles = rec['datafiles']
69
+ errors = []
70
+
71
+ datafiles.each_with_index do |path,j|
72
+ puts "==> [#{i+1}/#{specs.size}, #{j+1}/#{datafiles.size}] reading >#{path}<..."
73
+ txt = read_text( path )
74
+ quick = SportDb::QuickMatchReader.new( txt )
75
+ matches = quick.parse
76
+
77
+ if quick.errors?
78
+ puts "!! #{quick.errors.size} error(s):"
79
+ pp quick.errors
80
+
81
+ quick.errors.each do |err|
82
+ errors << [ path, *err ] # note: use splat (*) to add extra values (starting with msg)
83
+ end
84
+ end
85
+ puts " #{matches.size} match(es)"
86
+ end
87
+
88
+ if errors.size > 0
89
+ puts
90
+ puts "!! #{errors.size} PARSE ERRORS in #{datafiles.size} datafile(s)"
91
+ pp errors
92
+ else
93
+ puts
94
+ puts " OK - no parse errors in #{datafiles.size} datafile(s)"
95
+ end
96
+
97
+ ## add errors to rec via rec['errors'] to allow
98
+ ## for further processing/reporting
99
+ rec['errors'] = errors
100
+ end
101
+
102
+
103
+
104
+ ###
105
+ ## generate a report if --file option used
106
+ if opts[:file]
107
+ buf = SportDb::PathspecReport.new(
108
+ specs,
109
+ title: 'fbquick summary report' ).build
110
+
111
+ puts
112
+ puts "SUMMARY:"
113
+ puts buf
114
+
115
+ # maybe write out in the future?
116
+ # basedir = File.dirname( opts[:file] )
117
+ # basename = File.basename( opts[:file], File.extname( opts[:file] ))
118
+ end
119
+
120
+ puts "bye"
121
+ end
122
+
123
+ end # module Fbquick
@@ -0,0 +1,127 @@
1
+
2
+ module Fbtok
3
+
4
+
5
+ def self.main( args=ARGV )
6
+
7
+ opts = {
8
+ debug: true,
9
+ warn: false,
10
+ file: nil,
11
+ }
12
+
13
+
14
+ parser = OptionParser.new do |parser|
15
+ parser.banner = "Usage: #{$PROGRAM_NAME} [options] DATAFILE or DIR"
16
+
17
+
18
+ parser.on( "-q", "--quiet",
19
+ "less debug output/messages (default: #{!opts[:debug]})" ) do |debug|
20
+ opts[:debug] = false
21
+ end
22
+ parser.on( "--verbose", "--debug",
23
+ "turn on verbose / debug output (default: #{opts[:debug]})" ) do |debug|
24
+ opts[:debug] = true
25
+ end
26
+ parser.on( "-w", "--warn",
27
+ "turn warnings into errors (default: #{opts[:warn]})" ) do |warn|
28
+ opts[:warn] = true
29
+ end
30
+
31
+
32
+ parser.on( "-f FILE", "--file FILE",
33
+ "read datafiles (pathspecs) via .csv file") do |file|
34
+ opts[:file] = file
35
+ ## note: for batch (massive) processing auto-set debug (verbose output) to false (as default)
36
+ opts[:debug] = false
37
+ end
38
+ end
39
+ parser.parse!( args )
40
+
41
+
42
+
43
+ if opts[:debug]
44
+ puts "OPTS:"
45
+ p opts
46
+ puts "ARGV:"
47
+ p args
48
+ end
49
+
50
+
51
+ # SportDb::Parser::Linter.debug = opts[:debug]
52
+ # SportDb::Parser::Linter.warn = opts[:warn]
53
+
54
+
55
+
56
+ ## todo/check - use packs or projects or such
57
+ ## instead of specs - why? why not?
58
+ specs = if opts[:file]
59
+ read_pathspecs( opts[:file] )
60
+ else
61
+ args = ['/sports/openfootball/euro/2021--europe/euro.txt',
62
+ '/sports/openfootball/euro/2024--germany/euro.txt'] if args.empty?
63
+
64
+ build_pathspecs( args )
65
+ end
66
+
67
+
68
+ pp specs
69
+
70
+
71
+
72
+ specs.each_with_index do |rec,i|
73
+ datafiles = rec['datafiles']
74
+
75
+ errors = []
76
+
77
+ datafiles.each_with_index do |path,j|
78
+ puts "==> [#{i+1}/#{specs.size}, #{j+1}/#{datafiles.size}] reading >#{path}<..."
79
+
80
+ txt = read_text( path )
81
+ lexer = SportDb::Lexer.new( txt, debug: opts[:debug] )
82
+ tokens, more_errors = lexer.tokenize_with_errors
83
+
84
+ ####
85
+ ## todo - report error on empty file (no tokens!!!)
86
+
87
+ puts " #{tokens.size} token(s)"
88
+
89
+ errors += more_errors if more_errors.size > 0
90
+ end
91
+
92
+ if errors.size > 0
93
+ puts
94
+ pp errors
95
+ puts
96
+ puts "!! #{errors.size} tokenize error(s) in #{datafiles.size} datafiles(s)"
97
+ else
98
+ puts
99
+ puts "OK no tokenize errors found in #{datafiles.size} datafile(s)"
100
+ end
101
+
102
+ ## add errors to rec via rec['errors'] to allow
103
+ ## for further processing/reporting
104
+ rec['errors'] = errors
105
+ end
106
+
107
+
108
+ ###
109
+ ## generate a report if --file option used
110
+ if opts[:file]
111
+ buf = SportDb::PathspecReport.new(
112
+ specs,
113
+ title: 'fbtok summary report' ).build
114
+
115
+ puts
116
+ puts "SUMMARY:"
117
+ puts buf
118
+
119
+ # maybe write out in the future?
120
+ # basedir = File.dirname( opts[:file] )
121
+ # basename = File.basename( opts[:file], File.extname( opts[:file] ))
122
+ end
123
+
124
+ puts "bye"
125
+
126
+ end # self.main
127
+ end # module Fbtok
@@ -0,0 +1,141 @@
1
+
2
+ module Fbtree
3
+
4
+ def self.main( args=ARGV )
5
+
6
+
7
+ opts = {
8
+ debug: true,
9
+ warn: false,
10
+ file: nil,
11
+ }
12
+
13
+ parser = OptionParser.new do |parser|
14
+ parser.banner = "Usage: #{$PROGRAM_NAME} [options] DATAFILE or DIR"
15
+
16
+
17
+ parser.on( "-q", "--quiet",
18
+ "less debug output/messages (default: #{!opts[:debug]})" ) do |debug|
19
+ opts[:debug] = false
20
+ end
21
+ parser.on( "--verbose", "--debug",
22
+ "turn on verbose / debug output (default: #{opts[:debug]})" ) do |debug|
23
+ opts[:debug] = true
24
+ end
25
+ parser.on( "-w", "--warn",
26
+ "turn warnings into errors (default: #{opts[:warn]})" ) do |warn|
27
+ opts[:warn] = true
28
+ end
29
+
30
+
31
+ parser.on( "-f FILE", "--file FILE",
32
+ "read datafiles (pathspecs) via .csv file") do |file|
33
+ opts[:file] = file
34
+ ## note: for batch (massive) processing auto-set debug (verbose output) to false (as default)
35
+ opts[:debug] = false
36
+ end
37
+
38
+ end
39
+ parser.parse!( args )
40
+
41
+
42
+ if opts[:debug]
43
+ puts "OPTS:"
44
+ p opts
45
+ puts "ARGV:"
46
+ p args
47
+ end
48
+
49
+
50
+ # SportDb::Parser::Linter.debug = opts[:debug]
51
+ # SportDb::Parser::Linter.warn = opts[:warn]
52
+
53
+
54
+
55
+
56
+ ## todo/check - use packs or projects or such
57
+ ## instead of specs - why? why not?
58
+ specs = if opts[:file]
59
+ read_pathspecs( opts[:file] )
60
+ else
61
+ args = ['/sports/openfootball/euro/2021--europe/euro.txt',
62
+ '/sports/openfootball/euro/2024--germany/euro.txt'] if args.empty?
63
+
64
+ build_pathspecs( args )
65
+ end
66
+
67
+
68
+
69
+
70
+ specs.each_with_index do |rec,i|
71
+ datafiles = rec['datafiles']
72
+
73
+ errors = []
74
+
75
+ datafiles.each_with_index do |path,j|
76
+ puts "==> [#{i+1}/#{specs.size}, #{j+1}/#{datafiles.size}] reading >#{path}<..."
77
+
78
+ txt = read_text( path )
79
+ parser = RaccMatchParser.new( txt, debug: opts[:debug] )
80
+ tree = parser.parse
81
+
82
+ dump_tree_stats( tree )
83
+
84
+ errors += parser.errors if parser.errors?
85
+ end
86
+
87
+
88
+ if errors.size > 0
89
+ puts
90
+ pp errors
91
+ puts
92
+ puts "!! #{errors.size} parse error(s) in #{datafiles.size} datafiles(s)"
93
+ else
94
+ puts
95
+ puts "OK no parse errors found in #{datafiles.size} datafile(s)"
96
+ end
97
+
98
+ ## add errors to rec via rec['errors'] to allow
99
+ ## for further processing/reporting
100
+ rec['errors'] = errors
101
+ end
102
+
103
+
104
+ ###
105
+ ## generate a report if --file option used
106
+ if opts[:file]
107
+
108
+ buf = SportDb::PathspecReport.new(
109
+ specs,
110
+ title: 'fbtree summary report' ).build
111
+
112
+ puts
113
+ puts "SUMMARY:"
114
+ puts buf
115
+
116
+ # maybe write out in the future?
117
+ # basedir = File.dirname( opts[:file] )
118
+ # basename = File.basename( opts[:file], File.extname( opts[:file] ))
119
+ end
120
+
121
+ puts "bye"
122
+ end
123
+
124
+
125
+ def self.dump_tree_stats( tree )
126
+ stats = Hash.new(0) ## track counts only for now
127
+ tree.each do |node|
128
+ stats[ node.class ] += 1
129
+ end
130
+
131
+ match_count = stats[ RaccMatchParser::MatchLine ]
132
+ goal_count = stats[ RaccMatchParser::GoalLine ]
133
+ lineup_count = stats[ RaccMatchParser::LineupLine ]
134
+
135
+ puts " #{match_count} MatchLine(s)" if match_count > 0
136
+ puts " #{goal_count} GoalLine(s)" if goal_count > 0
137
+ puts " #{lineup_count} LineupLine(s)" if lineup_count > 0
138
+ end
139
+
140
+
141
+ end # module Fbtree
data/lib/fbtok/fbx.rb ADDED
@@ -0,0 +1,107 @@
1
+ ##
2
+ ## todo/fix - use for testing
3
+ # reads textfile and dumps results in json
4
+ #
5
+ # check - keep fbx name or find a differnt name - why? why not?
6
+
7
+ ##
8
+ ## read textfile
9
+ ## and dump match parse results
10
+ ##
11
+ ## fbt ../openfootball/.../euro.txt
12
+
13
+
14
+
15
+ module Fbx
16
+
17
+ def self.main( args=ARGV )
18
+
19
+ opts = { debug: false,
20
+ outline: false }
21
+
22
+ parser = OptionParser.new do |parser|
23
+ parser.banner = "Usage: #{$PROGRAM_NAME} [options] DATAFILE"
24
+
25
+ ##
26
+ ## check if git has a offline option?? (use same)
27
+ ## check for other tools - why? why not?
28
+
29
+
30
+ parser.on( "--verbose", "--debug",
31
+ "turn on verbose / debug output (default: #{opts[:debug]})" ) do |debug|
32
+ opts[:debug] = debug
33
+ end
34
+
35
+ # parser.on( "--outline",
36
+ # "turn on outline (only) output (default: #{opts[:outline]})" ) do |outline|
37
+ # opts[:outline] = outline
38
+ # end
39
+ end
40
+ parser.parse!( args )
41
+
42
+
43
+ if opts[:debug]
44
+ puts "OPTS:"
45
+ p opts
46
+ puts "ARGV:"
47
+ p args
48
+
49
+ SportDb::MatchParser.debug = true
50
+ else
51
+ SportDb::MatchParser.debug = false
52
+ LogUtils::Logger.root.level = :info
53
+ end
54
+
55
+
56
+ args = [
57
+ '../../../openfootball/euro/2021--europe/euro.txt',
58
+ '../../../openfootball/euro/2024--germany/euro.txt',
59
+ ] if args.empty?
60
+
61
+ pp args
62
+
63
+
64
+
65
+ ## errors = []
66
+
67
+
68
+ paths = args
69
+
70
+ paths.each_with_index do |path,i|
71
+ puts "==> [#{i+1}/#{paths.size}] reading >#{path}<..."
72
+
73
+ txt = read_text( path )
74
+
75
+ ##
76
+ ## note - use start: nil => requires that first date incl. a year!!!
77
+ parser = SportDb::MatchParser.new( txt, start: nil )
78
+
79
+ auto_conf_teams, matches, rounds, groups = parser.parse
80
+
81
+ puts ">>> #{auto_conf_teams.size} teams:"
82
+ pp auto_conf_teams
83
+ puts ">>> #{matches.size} matches:"
84
+ pp matches[0,2] ## print first two matches
85
+ puts "..."
86
+ puts ">>> #{rounds.size} rounds:"
87
+ pp rounds
88
+ puts ">>> #{groups.size} groups:"
89
+ pp groups
90
+ end # each paths
91
+
92
+ =begin
93
+ if errors.size > 0
94
+ puts
95
+ pp errors
96
+ puts
97
+ puts "!! #{errors.size} parse error(s) in #{paths.size} datafiles(s)"
98
+ else
99
+ puts
100
+ puts "OK no parse errors found in #{paths.size} datafile(s)"
101
+ end
102
+ =end
103
+
104
+ puts "bye"
105
+
106
+ end # self.main
107
+ end # module Fbx
@@ -20,6 +20,9 @@ class Pathspec
20
20
  ## BUT NOT as first character!!! (e.g. exclude .confg.txt !!!)
21
21
  ## e.g. 2024-25/at.1.txt
22
22
  ## change to at_1 or uefa_cl or such - why? why not?
23
+ ##
24
+ ## note - support case-insensitive flag (e.g. 2025-26/namur/2_Prov_A.txt)
25
+
23
26
  MATCH_RE = %r{
24
27
  ## "classic" variant i) with season folder
25
28
  ## e.g. /1930/cup.txt
@@ -30,6 +33,13 @@ class Pathspec
30
33
  (?: --[a-z0-9_-]+
31
34
  )?
32
35
  /
36
+
37
+ ### note - allow optional directories
38
+ (?:
39
+ [a-z0-9][a-z0-9_-]*
40
+ /
41
+ )*
42
+
33
43
  [a-z0-9][a-z0-9._-]* \.txt ## e.g /1-premierleague.txt
34
44
  $
35
45
  )
@@ -46,7 +56,7 @@ class Pathspec
46
56
  \.txt
47
57
  $
48
58
  )
49
- }x
59
+ }xi
50
60
 
51
61
  ### add support for matchdatafile with season NOT in directory
52
62
  ## but starting filename e.g. 2024_friendlies.txt or 2024-25_bundesliga.txt
@@ -58,6 +68,12 @@ end
58
68
 
59
69
 
60
70
  ## todo/check - rename to glob or expand or such - why? why not?
71
+
72
+ ##
73
+ ## todo - add a strict: true|false or all: true|false or such option
74
+ ## that will use generic **/*.txt and only use ignore filter!!!
75
+
76
+
61
77
  def self._find( path, seasons: nil )
62
78
  ## check - rename dir
63
79
  ## use root_dir or work_dir or cd or such - why? why not?
@@ -95,6 +111,8 @@ def self._find( path, seasons: nil )
95
111
  next if seasons && seasons.size > 0 &&
96
112
  !seasons.include?( Season.parse( m[:season] ))
97
113
 
114
+
115
+ #########
98
116
  ### exclude squad
99
117
  ## and .v2 or .v2603
100
118
  ##
@@ -107,6 +125,12 @@ def self._find( path, seasons: nil )
107
125
  next if /squad/i.match( basename )
108
126
  next if /\.v[0-9][0-9_]*/i.match( basename )
109
127
 
128
+ #####
129
+ ### exclude dirs w/ squad or wiki
130
+ dirname = File.dirname( candidate )
131
+
132
+ next if /squad|wiki/i.match( dirname )
133
+
110
134
 
111
135
  datafiles << candidate
112
136
  end
data/lib/fbtok.rb CHANGED
@@ -4,3 +4,9 @@ require 'sportdb/quick'
4
4
 
5
5
  ## our own code
6
6
  require_relative 'fbtok/pathspec'
7
+
8
+
9
+ require_relative 'fbtok/fbtok'
10
+ require_relative 'fbtok/fbtree'
11
+ require_relative 'fbtok/fbquick'
12
+ require_relative 'fbtok/fbx'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fbtok
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.4.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gerald Bauer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-05-26 00:00:00.000000000 Z
11
+ date: 2026-05-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sportdb-parser
@@ -76,6 +76,7 @@ description: fbtok - football.txt lint tools incl. tokenizer, parser & more
76
76
  email: gerald.bauer@gmail.com
77
77
  executables:
78
78
  - fbquick
79
+ - fbquik
79
80
  - fbtok
80
81
  - fbtree
81
82
  - fbx
@@ -90,10 +91,15 @@ files:
90
91
  - README.md
91
92
  - Rakefile
92
93
  - bin/fbquick
94
+ - bin/fbquik
93
95
  - bin/fbtok
94
96
  - bin/fbtree
95
97
  - bin/fbx
96
98
  - lib/fbtok.rb
99
+ - lib/fbtok/fbquick.rb
100
+ - lib/fbtok/fbtok.rb
101
+ - lib/fbtok/fbtree.rb
102
+ - lib/fbtok/fbx.rb
97
103
  - lib/fbtok/pathspec.rb
98
104
  homepage: https://github.com/sportdb/footty
99
105
  licenses: