sportdb-readers 0.2.3 → 0.3.0
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 +4 -4
- data/Manifest.txt +1 -0
- data/lib/sportdb/readers.rb +37 -20
- data/lib/sportdb/readers/datafile.rb +116 -0
- data/lib/sportdb/readers/version.rb +2 -2
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6d2044ec2c7a67046c429f4f52fa78a02d64f42b
|
4
|
+
data.tar.gz: 4e4e0102a368e5f9b53d8d40681470017fbc8579
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bf9db195f63e40f376a5bf9a63a7c73c79a6fcaf8dc42bbcc2fd6e18813ec275ccdab4ba5209ff52adba42b98ca7c211e2b172ac844fe2c721c349ceaf3685d7
|
7
|
+
data.tar.gz: afe05f74d798eb1a0ea04d0d2ed207f858f1d3135a7bfd27eeefadbc55dc8afd8d7eb290dd2652f01394f4a9af335bbc83a7b7f715467e681b2618a86b8c3fca
|
data/Manifest.txt
CHANGED
data/lib/sportdb/readers.rb
CHANGED
@@ -1,5 +1,8 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
+
require 'zip' ## todo/check: if zip is alreay included in a required module?
|
4
|
+
|
5
|
+
|
3
6
|
|
4
7
|
require 'sportdb/config'
|
5
8
|
require 'sportdb/models' ## add sql database support
|
@@ -15,6 +18,7 @@ require 'sportdb/readers/conf_linter'
|
|
15
18
|
require 'sportdb/readers/match_parser'
|
16
19
|
require 'sportdb/readers/match_reader'
|
17
20
|
require 'sportdb/readers/match_linter'
|
21
|
+
require 'sportdb/readers/datafile'
|
18
22
|
|
19
23
|
|
20
24
|
|
@@ -22,42 +26,55 @@ require 'sportdb/readers/match_linter'
|
|
22
26
|
## add convenience shortcut helpers
|
23
27
|
module SportDb
|
24
28
|
|
25
|
-
|
29
|
+
## note: sync is dry run (for lint checking)
|
30
|
+
def self.read_conf( path, season: nil, sync: true )
|
26
31
|
sync ? ConfReaderV2.read( path, season: season )
|
27
32
|
: ConfLinter.read( path, season: season )
|
28
33
|
end
|
29
34
|
|
30
|
-
### todo: add alias read_matches - why? why not?
|
31
|
-
def self.read_match( path, sync: true, season: nil ) ## note: sync is dry run (for lint checking)
|
35
|
+
def self.read_match( path, season: nil, sync: true ) ### todo/check: add alias read_matches - why? why not?
|
32
36
|
sync ? MatchReaderV2.read( path, season: season )
|
33
37
|
: MatchLinter.read( path, season: season )
|
34
38
|
end
|
35
39
|
|
36
|
-
def self.lint_conf( path, season: nil ) read_conf( path, sync: false, season: season ); end
|
37
|
-
def self.lint_match( path, season: nil ) read_match( path, sync: false, season: season ); end
|
38
40
|
|
41
|
+
def self.parse_conf( txt, season: nil, sync: true )
|
42
|
+
sync ? ConfReaderV2.parse( txt, season: season )
|
43
|
+
: ConfLinter.parse( txt, season: season )
|
44
|
+
end
|
39
45
|
|
40
|
-
def self.
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
datafiles = Datafile.find( path, %r{/\d{4}-\d{2} ## season folder e.g. /2019-20
|
45
|
-
/[a-z0-9_-]+\.txt$ ## txt e.g /1-premierleague.txt
|
46
|
-
}x )
|
46
|
+
def self.parse_match( txt, season: nil, sync: true ) ### todo/check: add alias read_matches - why? why not?
|
47
|
+
sync ? MatchReaderV2.parse( txt, season: season )
|
48
|
+
: MatchLinter.parse( txt, season: season )
|
49
|
+
end
|
47
50
|
|
48
|
-
|
49
|
-
|
51
|
+
|
52
|
+
def self.read( path, season: nil, sync: true )
|
53
|
+
pack = if File.directory?( path ) ## if directory assume "unzipped" package
|
54
|
+
Datafile::DirPackage.new( path )
|
55
|
+
elsif Datafile.match_zip( path ) ## check if file is a .zip (archive) file
|
56
|
+
Datafile::ZipPackage.new( path )
|
57
|
+
else ## no package; assume single (standalone) datafile
|
58
|
+
nil
|
59
|
+
end
|
60
|
+
|
61
|
+
if pack
|
62
|
+
pack.read_conf( season: season, sync: sync )
|
63
|
+
pack.read_match( season: season, sync: sync )
|
50
64
|
else
|
51
|
-
## check if datafile matches conf(iguration) naming (e.g. .conf.txt)
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
read_match( path, sync: sync, season: season )
|
65
|
+
if Datafile.match_conf( path ) ## check if datafile matches conf(iguration) naming (e.g. .conf.txt)
|
66
|
+
read_conf( path, season: season, sync: sync )
|
67
|
+
else ## assume "regular" match datafile
|
68
|
+
read_match( path, season: season, sync: sync )
|
56
69
|
end
|
57
70
|
end
|
58
71
|
end # method read
|
59
72
|
|
60
|
-
|
73
|
+
|
74
|
+
## (more) convenience helpers for lint(ing)
|
75
|
+
def self.lint( path, season: nil ) read( path, season: season, sync: false ); end
|
76
|
+
def self.lint_conf( path, season: nil ) read_conf( path, season: season, sync: false ); end
|
77
|
+
def self.lint_match( path, season: nil ) read_match( path, season: season, sync: false ); end
|
61
78
|
|
62
79
|
end # module SportDb
|
63
80
|
|
@@ -0,0 +1,116 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
module Datafile
|
4
|
+
|
5
|
+
|
6
|
+
## todo/fix: move regex patterns upstream to datafile in sportdb-formats!!
|
7
|
+
|
8
|
+
CONF_RE = %r{ /\.conf\.txt$
|
9
|
+
}x
|
10
|
+
|
11
|
+
MATCH_RE = %r{ /\d{4}-\d{2} ## season folder e.g. /2019-20
|
12
|
+
/[a-z0-9_-]+\.txt$ ## txt e.g /1-premierleague.txt
|
13
|
+
}x
|
14
|
+
|
15
|
+
ZIP_RE = %r{ \.zip$
|
16
|
+
}x
|
17
|
+
def self.match_zip( path, pattern: ZIP_RE ) pattern.match( path ); end
|
18
|
+
|
19
|
+
|
20
|
+
|
21
|
+
class PackageBase
|
22
|
+
|
23
|
+
## note: "abstract" methods - each and read required in derived class !!!!
|
24
|
+
|
25
|
+
def each_conf( &blk ) each( pattern: CONF_RE, &blk ); end
|
26
|
+
def each_match( &blk ) each( pattern: MATCH_RE, &blk ); end
|
27
|
+
|
28
|
+
def read_conf( season:, sync: )
|
29
|
+
read( pattern: CONF_RE ) do |name,txt|
|
30
|
+
SportDb.parse_conf( season: season, sync: sync )
|
31
|
+
end
|
32
|
+
end
|
33
|
+
def read_match( season:, sync: )
|
34
|
+
read( pattern: MATCH_RE ) do |name, txt|
|
35
|
+
SportDb.parse_match( season: season, sync: sync )
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end # class PackageBase
|
39
|
+
|
40
|
+
|
41
|
+
|
42
|
+
class DirPackage < PackageBase ## todo/check: find a better name e.g. UnzippedPackage, FilesystemPackage, etc. - why? why not?
|
43
|
+
|
44
|
+
def initialize( path )
|
45
|
+
@path = path ## rename to root_path or base_path or somehting - why? why not?
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
def each_file( pattern: ) ## todo/check: rename to glob or something - why? why not?
|
50
|
+
## note: incl. files starting with dot (.)) as candidates (normally excluded with just *)
|
51
|
+
Dir.glob( "#{@path}/**/{*,.*}.txt" ).each do |path|
|
52
|
+
## todo/fix: (auto) skip and check for directories
|
53
|
+
if pattern.match( path )
|
54
|
+
yield( path)
|
55
|
+
else
|
56
|
+
## puts " skipping >#{path}<"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
|
62
|
+
Entry = Struct.new( :name )
|
63
|
+
|
64
|
+
def each( pattern: ) ## todo/check: rename to each_entry - why? why not?
|
65
|
+
each_file( pattern: pattern ) do |path|
|
66
|
+
## fix: split path like a "virtual" zip like entry
|
67
|
+
yield( Entry.new( path ) )
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def read( pattern: )
|
72
|
+
each_file( pattern: pattern ) do |path|
|
73
|
+
txt = File.open( path, 'r:utf-8').read
|
74
|
+
yield( path, txt ) ## only pass along txt - why? why not? or pass along entry and not just entry.name?
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end # class DirPackage
|
78
|
+
|
79
|
+
|
80
|
+
|
81
|
+
## helper wrapper for datafiles in zips
|
82
|
+
class ZipPackage < PackageBase
|
83
|
+
def initialize( path )
|
84
|
+
@path = path
|
85
|
+
end
|
86
|
+
|
87
|
+
|
88
|
+
def each( pattern: )
|
89
|
+
Zip::File.open( @path ) do |zipfile|
|
90
|
+
zipfile.each do |entry|
|
91
|
+
if entry.directory?
|
92
|
+
next ## skip
|
93
|
+
elsif entry.file?
|
94
|
+
if pattern.match( entry.name )
|
95
|
+
yield( entry )
|
96
|
+
else
|
97
|
+
## puts " skipping >#{entry.name}<"
|
98
|
+
end
|
99
|
+
else
|
100
|
+
puts "** !! ERROR !! #{entry.name} is unknown zip file type, sorry"
|
101
|
+
exit 1
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def read( pattern: )
|
108
|
+
each( pattern: pattern ) do |entry|
|
109
|
+
txt = entry.get_input_stream.read
|
110
|
+
## puts "** encoding: #{txt.encoding}" #=> encoding: ASCII-8BIT
|
111
|
+
txt = txt.force_encoding( Encoding::UTF_8 )
|
112
|
+
yield( "#{@path}!/#{entry.name}", txt ) ## only pass along txt - why? why not? or pass along entry and not just entry.name?
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end # class ZipPackage
|
116
|
+
end # module Datafile
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sportdb-readers
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.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: 2019-11-
|
11
|
+
date: 2019-11-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sportdb-config
|
@@ -97,6 +97,7 @@ files:
|
|
97
97
|
- lib/sportdb/readers.rb
|
98
98
|
- lib/sportdb/readers/conf_linter.rb
|
99
99
|
- lib/sportdb/readers/conf_reader.rb
|
100
|
+
- lib/sportdb/readers/datafile.rb
|
100
101
|
- lib/sportdb/readers/league_outline_reader.rb
|
101
102
|
- lib/sportdb/readers/match_linter.rb
|
102
103
|
- lib/sportdb/readers/match_parser.rb
|