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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7a80a58bb3ddb33bdba8040a926546b548ba5436
4
- data.tar.gz: 608847551d5a437ab847e91aa79ea82626d010cf
3
+ metadata.gz: 6d2044ec2c7a67046c429f4f52fa78a02d64f42b
4
+ data.tar.gz: 4e4e0102a368e5f9b53d8d40681470017fbc8579
5
5
  SHA512:
6
- metadata.gz: fc388f76b6b1ec3ca85ea4bea73ace80f13af88ef05eb7601b04176aeca742c35e828ee1fa6d5ca674d6a71789007f5b785185e8b241db4ee14e89218ff624ca
7
- data.tar.gz: aa7ed9979898a56656f16d9093687b3d4c7a1590add76d4d5a866966e5bd2169e545fabcbc0fdc11f7c79b2ac8677667c9ca52d7a57e0dfb23963becbaa2d71f
6
+ metadata.gz: bf9db195f63e40f376a5bf9a63a7c73c79a6fcaf8dc42bbcc2fd6e18813ec275ccdab4ba5209ff52adba42b98ca7c211e2b172ac844fe2c721c349ceaf3685d7
7
+ data.tar.gz: afe05f74d798eb1a0ea04d0d2ed207f858f1d3135a7bfd27eeefadbc55dc8afd8d7eb290dd2652f01394f4a9af335bbc83a7b7f715467e681b2618a86b8c3fca
data/Manifest.txt CHANGED
@@ -5,6 +5,7 @@ Rakefile
5
5
  lib/sportdb/readers.rb
6
6
  lib/sportdb/readers/conf_linter.rb
7
7
  lib/sportdb/readers/conf_reader.rb
8
+ lib/sportdb/readers/datafile.rb
8
9
  lib/sportdb/readers/league_outline_reader.rb
9
10
  lib/sportdb/readers/match_linter.rb
10
11
  lib/sportdb/readers/match_parser.rb
@@ -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
- def self.read_conf( path, sync: true, season: nil ) ## note: sync is dry run (for lint checking)
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.read( path, sync: true, season: nil )
41
- ## step 1: collect all datafiles
42
- if File.directory?( path ) ## if directory read complete package
43
- datafiles_conf = Datafile.find_conf( path )
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
- datafiles_conf.each { |datafile| read_conf( datafile, sync: sync, season: season ) }
49
- datafiles.each { |datafile| read_match( datafile, sync: sync, season: season ) }
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
- if Datafile.match_conf( path )
53
- read_conf( path, sync: sync, season: season )
54
- else ## assume "regular" match datafile
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
- def self.lint( path, season: nil ) read( path, sync: false, season: season ); end
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
@@ -5,8 +5,8 @@ module SportDb
5
5
  module Readers
6
6
 
7
7
  MAJOR = 0 ## todo: namespace inside version or something - why? why not??
8
- MINOR = 2
9
- PATCH = 3
8
+ MINOR = 3
9
+ PATCH = 0
10
10
  VERSION = [MAJOR,MINOR,PATCH].join('.')
11
11
 
12
12
  def self.version
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.2.3
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-14 00:00:00.000000000 Z
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