sportdb-quick 0.0.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.
- checksums.yaml +7 -0
- data/CHANGELOG.md +3 -0
- data/Manifest.txt +13 -0
- data/README.md +5 -0
- data/Rakefile +32 -0
- data/bin/fbt +121 -0
- data/lib/sportdb/quick/linter.rb +149 -0
- data/lib/sportdb/quick/match_parser.rb +735 -0
- data/lib/sportdb/quick/opts.rb +70 -0
- data/lib/sportdb/quick/outline_reader.rb +97 -0
- data/lib/sportdb/quick/quick_league_outline_reader.rb +85 -0
- data/lib/sportdb/quick/quick_match_reader.rb +95 -0
- data/lib/sportdb/quick/version.rb +24 -0
- data/lib/sportdb/quick.rb +31 -0
- metadata +137 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: f2ce8e81bd6aece43872ba2718123dd2b34d6f52807ab8260a2e91f01a8c28ed
|
4
|
+
data.tar.gz: c91175dabbac6e590198df83151ee36d9a9daa853b77f0eedfa229f9db55edd0
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 53f5ca14405552fe662d35e6b1d1672afce956f27cc40801265a9f9d44a4d622b320a00a5ba935a04bae0453872ecb0da27b21927b184a87ed2755973eef118b
|
7
|
+
data.tar.gz: a688b66358bf16ec13ccbb90b5e29eaf483ca3e69f64ca4816f7210038383ea002660fa62a8ac971e9764903490757c9a84864bf57075794d8e0a337970a55b4
|
data/CHANGELOG.md
ADDED
data/Manifest.txt
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
CHANGELOG.md
|
2
|
+
Manifest.txt
|
3
|
+
README.md
|
4
|
+
Rakefile
|
5
|
+
bin/fbt
|
6
|
+
lib/sportdb/quick.rb
|
7
|
+
lib/sportdb/quick/linter.rb
|
8
|
+
lib/sportdb/quick/match_parser.rb
|
9
|
+
lib/sportdb/quick/opts.rb
|
10
|
+
lib/sportdb/quick/outline_reader.rb
|
11
|
+
lib/sportdb/quick/quick_league_outline_reader.rb
|
12
|
+
lib/sportdb/quick/quick_match_reader.rb
|
13
|
+
lib/sportdb/quick/version.rb
|
data/README.md
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'hoe'
|
2
|
+
require './lib/sportdb/quick/version.rb'
|
3
|
+
|
4
|
+
|
5
|
+
Hoe.spec 'sportdb-quick' do
|
6
|
+
|
7
|
+
self.version = SportDb::Module::Quick::VERSION
|
8
|
+
|
9
|
+
self.summary = "sportdb-quick - football.txt (quick) match parsers and more"
|
10
|
+
self.description = summary
|
11
|
+
|
12
|
+
self.urls = { home: 'https://github.com/sportdb/sport.db' }
|
13
|
+
|
14
|
+
self.author = 'Gerald Bauer'
|
15
|
+
self.email = 'gerald.bauer@gmail.com'
|
16
|
+
|
17
|
+
# switch extension to .markdown for gihub formatting
|
18
|
+
self.readme_file = 'README.md'
|
19
|
+
self.history_file = 'CHANGELOG.md'
|
20
|
+
|
21
|
+
self.licenses = ['Public Domain']
|
22
|
+
|
23
|
+
self.extra_deps = [
|
24
|
+
['sportdb-parser', '>= 0.2.2'],
|
25
|
+
['sportdb-structs', '>= 0.4.0'],
|
26
|
+
['logutils', '>= 0.6.1'],
|
27
|
+
]
|
28
|
+
|
29
|
+
self.spec_extras = {
|
30
|
+
required_ruby_version: '>= 3.1.0'
|
31
|
+
}
|
32
|
+
end
|
data/bin/fbt
ADDED
@@ -0,0 +1,121 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
## tip: to test run:
|
4
|
+
## ruby -I ./lib bin/fbt
|
5
|
+
## -or-
|
6
|
+
## ruby -I ../parser/lib -I ./lib bin/fbt
|
7
|
+
## -or-
|
8
|
+
## ruby -I ../parser/lib -I ../sportdb-structs/lib -I ./lib bin/fbt
|
9
|
+
|
10
|
+
|
11
|
+
## our own code
|
12
|
+
require 'sportdb/quick'
|
13
|
+
|
14
|
+
|
15
|
+
|
16
|
+
require 'optparse'
|
17
|
+
|
18
|
+
##
|
19
|
+
## read textfile
|
20
|
+
## and dump tokens
|
21
|
+
##
|
22
|
+
## fbt ../openfootball/.../euro.txt
|
23
|
+
|
24
|
+
|
25
|
+
|
26
|
+
|
27
|
+
args = ARGV
|
28
|
+
opts = { debug: false,
|
29
|
+
metal: false,
|
30
|
+
quick: false }
|
31
|
+
|
32
|
+
parser = OptionParser.new do |parser|
|
33
|
+
parser.banner = "Usage: #{$PROGRAM_NAME} [options]"
|
34
|
+
|
35
|
+
##
|
36
|
+
## check if git has a offline option?? (use same)
|
37
|
+
## check for other tools - why? why not?
|
38
|
+
|
39
|
+
|
40
|
+
parser.on( "--verbose", "--debug",
|
41
|
+
"turn on verbose / debug output (default: #{opts[:debug]})" ) do |debug|
|
42
|
+
opts[:debug] = debug
|
43
|
+
end
|
44
|
+
|
45
|
+
parser.on( "--metal",
|
46
|
+
"turn off typed parse tree; show to the metal tokens"+
|
47
|
+
" (default: #{opts[:metal]})" ) do |metal|
|
48
|
+
opts[:metal] = metal
|
49
|
+
end
|
50
|
+
|
51
|
+
parser.on( "--quick",
|
52
|
+
"use quick match reader; output matches in json"+
|
53
|
+
" (default: #{opts[:quick]})" ) do |quick|
|
54
|
+
opts[:quick] = quick
|
55
|
+
end
|
56
|
+
end
|
57
|
+
parser.parse!( args )
|
58
|
+
|
59
|
+
puts "OPTS:"
|
60
|
+
p opts
|
61
|
+
puts "ARGV:"
|
62
|
+
p args
|
63
|
+
|
64
|
+
|
65
|
+
|
66
|
+
|
67
|
+
|
68
|
+
paths = if args.empty?
|
69
|
+
[
|
70
|
+
'../../../openfootball/euro/2021--europe/euro.txt',
|
71
|
+
'../../../openfootball/euro/2024--germany/euro.txt',
|
72
|
+
]
|
73
|
+
else
|
74
|
+
## check for directories
|
75
|
+
## and auto-expand
|
76
|
+
|
77
|
+
SportDb::Quick::Opts.expand_args( args )
|
78
|
+
end
|
79
|
+
|
80
|
+
|
81
|
+
if opts[:quick]
|
82
|
+
|
83
|
+
paths.each_with_index do |path,i|
|
84
|
+
puts "==> [#{i+1}/#{paths.size}] reading >#{path}<..."
|
85
|
+
|
86
|
+
matches = SportDb::QuickMatchReader.read( path )
|
87
|
+
## pp matches
|
88
|
+
## try json for matches
|
89
|
+
data = matches.map {|match| match.as_json }
|
90
|
+
pp data
|
91
|
+
puts
|
92
|
+
puts " #{data.size} match(es)"
|
93
|
+
end
|
94
|
+
else
|
95
|
+
SportDb::Quick::Linter.debug = true if opts[:debug]
|
96
|
+
|
97
|
+
linter = SportDb::Quick::Linter.new
|
98
|
+
|
99
|
+
errors = []
|
100
|
+
|
101
|
+
paths.each_with_index do |path,i|
|
102
|
+
puts "==> [#{i+1}/#{paths.size}] reading >#{path}<..."
|
103
|
+
linter.read( path, parse: !opts[:metal] )
|
104
|
+
|
105
|
+
errors += linter.errors if linter.errors?
|
106
|
+
end
|
107
|
+
|
108
|
+
if errors.size > 0
|
109
|
+
puts
|
110
|
+
pp errors
|
111
|
+
puts
|
112
|
+
puts "!! #{errors.size} parse error(s) in #{paths.size} datafiles(s)"
|
113
|
+
else
|
114
|
+
puts
|
115
|
+
puts "OK no parse errors found in #{paths.size} datafile(s)"
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
|
120
|
+
puts "bye"
|
121
|
+
|
@@ -0,0 +1,149 @@
|
|
1
|
+
|
2
|
+
module SportDb
|
3
|
+
module Quick
|
4
|
+
|
5
|
+
###
|
6
|
+
## note - Linter for now nested inside Parser - keep? why? why not?
|
7
|
+
class Linter
|
8
|
+
|
9
|
+
def self.debug=(value) @@debug = value; end
|
10
|
+
def self.debug?() @@debug ||= false; end ## note: default is FALSE
|
11
|
+
def debug?() self.class.debug?; end
|
12
|
+
|
13
|
+
|
14
|
+
|
15
|
+
attr_reader :errors
|
16
|
+
|
17
|
+
def initialize
|
18
|
+
@errors = []
|
19
|
+
@parser = Parser.new ## use own parser instance (not shared) - why? why not?
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
def errors?() @errors.size > 0; end
|
24
|
+
|
25
|
+
|
26
|
+
|
27
|
+
## note: colon (:) MUST be followed by one (or more) spaces
|
28
|
+
## make sure mon feb 12 18:10 will not match
|
29
|
+
## allow 1. FC Köln etc.
|
30
|
+
## Mainz 05:
|
31
|
+
## limit to 30 chars max
|
32
|
+
## only allow chars incl. intl buut (NOT ()[]/;)
|
33
|
+
##
|
34
|
+
## Group A:
|
35
|
+
## Group B: - remove colon
|
36
|
+
## or lookup first
|
37
|
+
|
38
|
+
ATTRIB_RE = %r{^
|
39
|
+
[ ]*? # slurp leading spaces
|
40
|
+
(?<key>[^:|\]\[()\/; -]
|
41
|
+
[^:|\]\[()\/;]{0,30}
|
42
|
+
)
|
43
|
+
[ ]*? # slurp trailing spaces
|
44
|
+
:[ ]+
|
45
|
+
(?<value>.+)
|
46
|
+
[ ]*? # slurp trailing spaces
|
47
|
+
$
|
48
|
+
}ix
|
49
|
+
|
50
|
+
|
51
|
+
#########
|
52
|
+
## parse - false (default) - tokenize (only)
|
53
|
+
## - true - tokenize & parse
|
54
|
+
def read( path, parse: false )
|
55
|
+
## note: every (new) read call - resets errors list to empty
|
56
|
+
@errors = []
|
57
|
+
|
58
|
+
nodes = OutlineReader.read( path )
|
59
|
+
|
60
|
+
## process nodes
|
61
|
+
h1 = nil
|
62
|
+
orphans = 0 ## track paragraphs's with no heading
|
63
|
+
|
64
|
+
attrib_found = false
|
65
|
+
|
66
|
+
|
67
|
+
nodes.each do |node|
|
68
|
+
type = node[0]
|
69
|
+
|
70
|
+
if type == :h1
|
71
|
+
h1 = node[1] ## get heading text
|
72
|
+
puts
|
73
|
+
puts " = Heading 1 >#{node[1]}<"
|
74
|
+
elsif type == :p
|
75
|
+
|
76
|
+
if h1.nil?
|
77
|
+
orphans += 1 ## only warn once
|
78
|
+
puts "!! WARN - no heading for #{orphans} text paragraph(s); skipping parse"
|
79
|
+
next
|
80
|
+
end
|
81
|
+
|
82
|
+
lines = node[1]
|
83
|
+
|
84
|
+
tree = []
|
85
|
+
lines.each_with_index do |line,i|
|
86
|
+
|
87
|
+
if debug?
|
88
|
+
puts
|
89
|
+
puts "line >#{line}<"
|
90
|
+
end
|
91
|
+
|
92
|
+
|
93
|
+
## skip new (experimental attrib syntax)
|
94
|
+
if attrib_found == false &&
|
95
|
+
ATTRIB_RE.match?( line )
|
96
|
+
## note: check attrib regex AFTER group def e.g.:
|
97
|
+
## Group A:
|
98
|
+
## Group B: etc.
|
99
|
+
## todo/fix - change Group A: to Group A etc.
|
100
|
+
## Group B: to Group B
|
101
|
+
attrib_found = true
|
102
|
+
## logger.debug "skipping key/value line - >#{line}<"
|
103
|
+
next
|
104
|
+
end
|
105
|
+
|
106
|
+
if attrib_found
|
107
|
+
## check if line ends with dot
|
108
|
+
## if not slurp up lines to the next do!!!
|
109
|
+
## logger.debug "skipping key/value line - >#{line}<"
|
110
|
+
attrib_found = false if line.end_with?( '.' )
|
111
|
+
# logger.debug "skipping key/value line (cont.) - >#{line}<"
|
112
|
+
next
|
113
|
+
end
|
114
|
+
|
115
|
+
t, error_messages = if parse
|
116
|
+
@parser.parse_with_errors( line )
|
117
|
+
else
|
118
|
+
@parser.tokenize_with_errors( line )
|
119
|
+
end
|
120
|
+
|
121
|
+
|
122
|
+
if error_messages.size > 0
|
123
|
+
## add to "global" error list
|
124
|
+
## make a triplet tuple (file / msg / line text)
|
125
|
+
error_messages.each do |msg|
|
126
|
+
@errors << [ path,
|
127
|
+
msg,
|
128
|
+
line
|
129
|
+
]
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
pp t if debug?
|
134
|
+
|
135
|
+
tree << t
|
136
|
+
end
|
137
|
+
|
138
|
+
## pp tree
|
139
|
+
else
|
140
|
+
pp node
|
141
|
+
raise ArgumentError, "unsupported (node) type >#{type}<"
|
142
|
+
end
|
143
|
+
end # each node
|
144
|
+
end # read
|
145
|
+
end # class Linter
|
146
|
+
|
147
|
+
|
148
|
+
end # module Quick
|
149
|
+
end # module SportDb
|