sportdb-readers 0.2.3 → 0.3.0

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
  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