sportdb-importers 1.1.0 → 1.1.1

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: 03d3875605ad42d0fd7876f036c2bbbe2dd8999d
4
- data.tar.gz: 92435a82e496ef1ca09a9e44395038a81c7b5b21
3
+ metadata.gz: 6a504f73f34a5e73bb311ee460402b068056d68d
4
+ data.tar.gz: b8680b47ec3c06958ac8f6718261873521314998
5
5
  SHA512:
6
- metadata.gz: ac4fea2f6fc7b2fc7d5d981e792977bd1bb44ae8de3bcd72bacae4583828f02f76a1785f9e91f7d68036e10b4743f1cd561e610b1e41612b058c634f5f1b1537
7
- data.tar.gz: 2ff8b5dc6f53994431cba566e2031834aa61fd2d6f668a8d4a61af177783791b4981946b58e587ddd2a199f8fa6469ce006925b607111529359503afc627479e
6
+ metadata.gz: 5c0ea550c7450f524d0314e55365b221841e95c6c5794681ec1b34c5d27cdb721bd0a4408b69ade5e751a76d88a0fddbcdc58bbe1644f5d644ae925311bdec3f
7
+ data.tar.gz: 358bdd2d3872ff3b80d9916293c9bf372f581ebaf2e0c14de370a80983bb74148acba97b6baa1b0072b59da796c1ba3849d5bc5279c519111a011a46f4fd007f
@@ -3,7 +3,8 @@ Manifest.txt
3
3
  README.md
4
4
  Rakefile
5
5
  lib/sportdb/importers.rb
6
- lib/sportdb/importers/import.rb
6
+ lib/sportdb/importers/event.rb
7
+ lib/sportdb/importers/match.rb
7
8
  lib/sportdb/importers/version.rb
8
9
  test/helper.rb
9
10
  test/test_club.rb
@@ -8,37 +8,20 @@ require 'sportdb/sync'
8
8
  ###
9
9
  # our own code
10
10
  require 'sportdb/importers/version' # let version always go first
11
- require 'sportdb/importers/import'
11
+ require 'sportdb/importers/event'
12
+ require 'sportdb/importers/match'
12
13
 
13
14
 
14
15
  module SportDb
15
16
  class Package
16
17
  ## (re)open class - note: adds more machinery; see sportdb-text for first/original/base definition
17
18
 
18
- def read_csv( start: nil ) ### todo/fix - rename to read_csv !!!!!!
19
+ def read_csv( start: nil )
19
20
  ## start - season e.g. 1993/94 to start (skip older seasons)
20
21
  ## note: assume package holds country/national (club) league
21
22
  # use for importing german bundesliga, english premier league, etc.
22
23
 
23
- match_by_season( format: 'csv', start: start ).each_with_index do |(season_key, entries),i|
24
- puts "season [#{i+1}] >#{season_key}<:"
25
-
26
- entries.each do |entry,j|
27
- ## note: assume datafile basename (without extension) is the league key
28
- ## e.g. eng.1, eng.3a, eng.3b, at.1, champs, world, etc.
29
- league_key = File.basename( entry.name, File.extname( entry.name ) ) ## get basename WITHOUT extension
30
-
31
- pp [entry.name, season_key, league_key]
32
-
33
- event = CsvEventImporter.parse( entry.read, league: league_key,
34
- season: season_key )
35
-
36
- puts "added #{event.name} - from source >#{entry.name}<"
37
- puts " #{event.teams.size} teams"
38
- puts " #{event.matches.size} matches"
39
- puts " #{event.rounds.size} rounds"
40
- end # each datafile
41
- end # each season
24
+ each_csv { |entry| SportDb.handle_csv( entry, start: start ) }
42
25
  end # method import
43
26
 
44
27
  end # class Package
@@ -50,25 +33,101 @@ end # class Package
50
33
  def self.read_csv( path )
51
34
  if File.directory?( path ) ## if directory assume "unzipped" package
52
35
  DirPackage.new( path ).read_csv
53
- elsif File.file?( path ) && File.extname( path ) == '.zip' ## check if file is a .zip (archive) file
36
+ elsif File.file?( path ) && File.extname( path ).downcase == '.zip' ## check if file is a .zip (archive) file
54
37
  ZipPackage.new( path ).read_csv
55
38
  else ## no package; assume single (standalone) datafile
56
39
  ## assume single (free-standing) file
40
+ handle_csv( path )
41
+ end
42
+ end
43
+
44
+ ##################
45
+ ### helper
46
+ ## move handle_csv somewhere else - why? why not?
47
+ def self.handle_csv( source, start: nil )
48
+ ## todo/fix: (re)use a more generic filter instead of start for start of season only
49
+
50
+ ## todo/fix: use a "generic" filter_season helper for easy reuse
51
+ ## filter_season( clause, season_key )
52
+ ## or better filter = SeasonFilter.new( clause )
53
+ ## filter.skip? filter.include? ( season_sason_key )?
54
+ ## fiteer.before?( season_key ) etc.
55
+ ## find some good method names!!!!
56
+ season_start = start ? Import::Season.new( start ) : nil
57
+
58
+ if source.is_a?( Datafile::DirPackage::Entry) ||
59
+ source.is_a?( Datafile::ZipPackage::Entry)
60
+ entry = source
61
+
62
+ basename = File.basename( entry.name, File.extname( entry.name ) ) ## get basename WITHOUT extension
63
+
64
+ ## check if basename is all numbers (and _-) e.g. 2020.csv or 20.csv etc.
65
+ ## if yes, assume "mixed" match datafiles (with many/mixed leagues)
66
+ if basename =~ /^[0-9_-]+$/
67
+ pp [entry.name, basename]
68
+
69
+ CsvMatchImporter.parse( entry.read )
70
+ else ## assume "classic" with season
71
+ league_key = basename
72
+
73
+ ## todo/fix: check if season_key is proper season - e.g. matches pattern !!!!
74
+ season_q = File.basename( File.dirname( entry.name ))
75
+ season = Import::Season.new( season_q ) ## normalize season
76
+ season_key = season.key
77
+
78
+ if season_start && season_start.start_year > season.start_year
79
+ ## skip if start season before this season
80
+ else
81
+ pp [entry.name, season_key, league_key]
82
+
83
+ event = CsvEventImporter.parse( entry.read, league: league_key,
84
+ season: season_key )
85
+
86
+ puts "added #{event.name} - from source >#{entry.name}<"
87
+ puts " #{event.teams.size} teams"
88
+ puts " #{event.matches.size} matches"
89
+ puts " #{event.rounds.size} rounds"
90
+ end
91
+ end
92
+ else ## assume (string) filepath for now - add more options later on!!!!
93
+ ## assume single (free-standing) file
94
+ path = source
57
95
  full_path = File.expand_path( path ) ## resolve/make path absolute
58
96
  ## 1) assume basename is the league key
59
97
  ## 2) assume last directory is the season key
60
- league_key = File.basename( full_path, File.extname( full_path ) ) ## get basename WITHOUT extension
61
- season_key = File.basename( File.dirname( full_path ) )
62
-
63
- event = CsvEventImporter.read( full_path, league: league_key,
64
- season: season_key )
65
98
 
66
- puts "added #{event.name} - from source >#{path}<"
67
- puts " #{event.teams.size} teams"
68
- puts " #{event.matches.size} matches"
69
- puts " #{event.rounds.size} rounds"
99
+ basename = File.basename( full_path, File.extname( full_path ) ) ## get basename WITHOUT extension
100
+ if basename =~ /^[0-9_-]+$/
101
+ pp [path, basename]
102
+ CsvMatchImporter.read( full_path )
103
+ else ## assume "classic" with season
104
+ ## 1) assume basename is the league key
105
+ ## 2) assume last directory is the season key
106
+ league_key = basename
107
+
108
+ season_q = File.basename( File.dirname( full_path ) )
109
+ season = Import::Season.new( season_q ) ## normalize season
110
+ season_key = season.key
111
+
112
+ if season_start && season_start.start_year > season.start_year
113
+ ## skip if start season before this season
114
+ else
115
+ ## todo/fix: check if season_key is proper season - e.g. matches pattern !!!!
116
+ pp [path, season_key, league_key]
117
+
118
+ event = CsvEventImporter.read( full_path, league: league_key,
119
+ season: season_key )
120
+
121
+ puts "added #{event.name} - from source >#{path}<"
122
+ puts " #{event.teams.size} teams"
123
+ puts " #{event.matches.size} matches"
124
+ puts " #{event.rounds.size} rounds"
125
+ end
126
+ end
70
127
  end
71
- end
128
+ end # method self.handle_csv
129
+
130
+
72
131
  end # module SportDb
73
132
 
74
133
 
@@ -1,6 +1,4 @@
1
1
 
2
- ## todo/fix: rename to CsvEventImporter or EventImporter !!! returns Event!!
3
- ## todo/fix/check: rename to CsvMatchReader and CsvMatchReader to CsvMatchParser - why? why not?
4
2
 
5
3
  module SportDb
6
4
  class CsvEventImporter
@@ -0,0 +1,96 @@
1
+
2
+
3
+ module SportDb
4
+ class CsvMatchImporter
5
+
6
+ def self.read( path, headers: nil )
7
+ txt = File.open( path, 'r:utf-8' ) {|f| f.read }
8
+ parse( txt, headers: headers )
9
+ end
10
+
11
+ def self.parse( txt, headers: nil )
12
+ new( txt, headers: headers ).parse
13
+ end
14
+
15
+
16
+ def initialize( txt, headers: nil )
17
+ @txt = txt
18
+ @headers = headers
19
+ end
20
+
21
+
22
+ def parse
23
+ ## todo/fix: add headers options (pass throughto CsvMatchReader)
24
+ ## add filters too why? why not?
25
+
26
+ ## todo/fix:
27
+ ## add normalize: false/mapping: false flag for NOT mapping club/team names
28
+ ## make normalize: false the default, anyways - why? why not?
29
+ opts = {}
30
+ opts[:headers] = @headers if @headers
31
+
32
+ matches = CsvMatchParser.parse( @txt, **opts )
33
+
34
+ matches.each do |match|
35
+ league = Import.catalog.leagues.find!( match.league )
36
+ # pp league
37
+
38
+ team1 = Import.catalog.teams.find_by!( name: match.team1, league: league )
39
+ team2 = Import.catalog.teams.find_by!( name: match.team2, league: league )
40
+
41
+ date = Date.strptime( match.date, '%Y-%m-%d' )
42
+ ## quick hack - for now always use 2019/20 style season
43
+ ## fix!!! - use league to find proper season e.g. 2019 or 2019/20 etc.
44
+
45
+ start_year = if date.month >= 7
46
+ date.year
47
+ else
48
+ date.year-1
49
+ end
50
+
51
+ ## note: for now always assume 2019/20 season
52
+ season = Import::Season.new( '%d/%d' % [start_year, (start_year+1)%100] )
53
+ # pp season
54
+
55
+
56
+ event_rec = Sync::Event.find_or_create_by( league: league,
57
+ season: season )
58
+
59
+ team1_rec = Sync::Team.find_or_create( team1 )
60
+ team2_rec = Sync::Team.find_or_create( team2 )
61
+
62
+ ## warn about duplicates?
63
+ ## note: for now only allow one (unique) match pair per team
64
+ match_recs = Model::Match.where( event_id: event_rec.id,
65
+ team1_id: team1_rec.id,
66
+ team2_id: team2_rec.id ).to_a
67
+ if match_recs.size > 0
68
+ puts "!! #{match_recs.size} duplicate match record(s) found:"
69
+ pp match_recs
70
+ exit 1
71
+ end
72
+
73
+ ## find last pos - check if it can be nil? yes, is nil if no records found
74
+ max_pos = Model::Match.where( event_id: event_rec.id ).maximum( 'pos' )
75
+ max_pos = max_pos ? max_pos+1 : 1
76
+
77
+ rec = Model::Match.create!(
78
+ event_id: event_rec.id,
79
+ team1_id: team1_rec.id,
80
+ team2_id: team2_rec.id,
81
+ ## round_id: round_rec.id, -- note: now optional
82
+ pos: max_pos,
83
+ date: date.to_date,
84
+ score1: match.score1,
85
+ score2: match.score2,
86
+ score1i: match.score1i,
87
+ score2i: match.score2i )
88
+
89
+ ## todo/fix:
90
+ ## check if event includes teams?
91
+ ## if not (auto-)add teams to event.teams !!!!!!!
92
+ end
93
+ end # method parse
94
+
95
+ end # class CsvEventImporter
96
+ end # module SportDb
@@ -7,7 +7,7 @@ module Importers
7
7
 
8
8
  MAJOR = 1 ## todo: namespace inside version or something - why? why not??
9
9
  MINOR = 1
10
- PATCH = 0
10
+ PATCH = 1
11
11
  VERSION = [MAJOR,MINOR,PATCH].join('.')
12
12
 
13
13
  def self.version
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sportdb-importers
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gerald Bauer
@@ -67,7 +67,8 @@ files:
67
67
  - README.md
68
68
  - Rakefile
69
69
  - lib/sportdb/importers.rb
70
- - lib/sportdb/importers/import.rb
70
+ - lib/sportdb/importers/event.rb
71
+ - lib/sportdb/importers/match.rb
71
72
  - lib/sportdb/importers/version.rb
72
73
  - test/helper.rb
73
74
  - test/test_club.rb