Top Level Namespace
Defined Under Namespace
Modules: Fifadat Classes: Fifa
Instance Method Summary collapse
- #_deep_stringify_keys(obj) ⇒ Object
-
#banner ⇒ Object
say hello.
-
#cocos ⇒ Object
check if incl webclient already?.
- #fetch_json(url, path = nil, headers: nil) ⇒ Object
- #fetch_json_if(url, outpath, force: false) ⇒ Object
- #prepare(name:, season:, outdir: '.', force: false) ⇒ Object
- #prepare_reports(name:, season:, outdir: '.', force: false) ⇒ Object
- #read_json_v2(path) ⇒ Object
- #write_json_v2(path, data) ⇒ Object
Instance Method Details
#_deep_stringify_keys(obj) ⇒ Object
45 46 47 48 49 50 51 52 53 54 55 |
# File 'lib/fifadat/json.rb', line 45 def _deep_stringify_keys(obj) case obj when Hash obj.transform_keys(&:to_s) .transform_values { |v| _deep_stringify_keys(v) } when Array obj.map { |v| _deep_stringify_keys(v) } else obj end end |
#banner ⇒ Object
say hello
26 |
# File 'lib/fifadat.rb', line 26 puts Fifadat. |
#cocos ⇒ Object
check if incl webclient already?
6 |
# File 'lib/fifadat.rb', line 6 require 'cocos' |
#fetch_json(url, path = nil, headers: nil) ⇒ Object
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
# File 'lib/fifadat/json.rb', line 75 def fetch_json( url, path=nil, headers: nil ) res = if headers Webclient.get( url, headers: headers ) else Webclient.get( url ) end if res.status.ok? data = res.json ## pp data puts "OK - fetching #{url}" write_json_v2( path, data ) if path data else puts " #{url}" puts "!! ERROR #{res.status.code} #{res.status.message}" exit 1 end end |
#fetch_json_if(url, outpath, force: false) ⇒ Object
100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
# File 'lib/fifadat/json.rb', line 100 def fetch_json_if( url, outpath, force: false ) delay_in_secs = 1 ## 1 sec if force == false && File.exist?( outpath ) puts "CACHE HIT - #{outpath}" return nil end data = fetch_json( url, outpath ) puts " sleeping #{delay_in_secs} sec(s)..." sleep( delay_in_secs ) data end |
#prepare(name:, season:, outdir: '.', force: false) ⇒ Object
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
# File 'lib/fifadat/prepare.rb', line 7 def prepare( name:, season:, outdir: '.', force: false ) ### ### rename name to slug or such ## e.g. worldcup, clubworldcup, interconticup or such expected!!! season = Season(season) idComp = Fifa._idComp_by!( name: name ) idSeason = Fifa._idSeason_by!( name: name, season: season ) fetch_json_if( Fifa::Metal.matches_url( idSeason: idSeason ), "#{outdir}/#{name}/#{season.to_path}_matches.json", force: force ) fetch_json_if( Fifa::Metal.stages_url( idSeason: idSeason ), "#{outdir}/#{name}/misc/#{season.to_path}_stages.json", force: force ) fetch_json_if( Fifa::Metal.squads_url( idCompetition: idComp, idSeason: idSeason ), "#{outdir}/#{name}/misc/#{season.to_path}_squads.json", force: force ) end |
#prepare_reports(name:, season:, outdir: '.', force: false) ⇒ Object
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
# File 'lib/fifadat/prepare.rb', line 36 def prepare_reports( name:, season:, outdir: '.', force: false ) ## download match reports (via live/football) season = Season(season) data = read_json( "#{outdir}/#{name}/#{season.to_path}_matches.json" ) matches = data['Results'] puts " #{matches.size} match(es) in season #{season}" matches.each_with_index do |m, i| idCompetition = m['IdCompetition'] idSeason = m['IdSeason'] idStage = m['IdStage'] idMatch = m['IdMatch'] stageName = desc( m['StageName'] ) ## note - skip if teams not yet know ## e.g. Home & Away is null ## e.g. "Home": null, ## "Away": null, ## todo/fix - check for MatchStatus and ResultType too ## e.g. MatchStatus = 1 -- future ## ResultType = 0 -- not played yet if m['Home'].nil? || m['Away'].nil? puts "[#{i+1}/#{matches.size}] ?? ??, #{stageName} (SKIPPED - TO BE DONE)" next end dateTime = parse_date( m['Date'] ) ## utc localDateTime = parse_date( m['LocalDate'] ) ## pp m['Home'] teamName1 = desc( m['Home']['TeamName'] ) teamCode1 = m['Home']['Abbreviation'] ## pp m['Away'] teamName2 = desc( m['Away']['TeamName'] ) teamCode2 = m['Away']['Abbreviation'] puts "[#{i+1}/#{matches.size}] #{teamName1} #{teamName2}, #{stageName}, #{localDateTime}" outpath = "#{outdir}/#{name}/matches/#{season.to_path}/#{localDateTime.strftime('%Y-%m-%d')}_#{teamCode1}-#{teamCode2}__#{idMatch}.json" url = Fifa::Metal.live_url( idCompetition: idCompetition, idSeason: idSeason, idStage: idStage, idMatch: idMatch ) fetch_json_if( url, outpath, force: force ) ### ## add timeline (only) if score incl. penalty shoot-out resultType = m['ResultType'] if resultType == 2 ## (aet??) win on pens ## download timeline outpath = "#{outdir}/#{name}/timelines/#{season.to_path}/#{localDateTime.strftime('%Y-%m-%d')}_#{teamCode1}-#{teamCode2}__#{idMatch}.json" url = Fifa::Metal.timeline_url( idCompetition: idCompetition, idSeason: idSeason, idStage: idStage, idMatch: idMatch ) fetch_json_if( url, outpath, force: force ) end end end |
#read_json_v2(path) ⇒ Object
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
# File 'lib/fifadat/json.rb', line 2 def read_json_v2( path ) txt = read_text( path ) ## \u00A0 - non-breaking space txt = txt.gsub( /[\u00A0]/, ' ' ) ## (auto-)remove ™ (e.g. FIFA World Cup™) txt = txt.gsub( '™', '' ) ## check for non-breaking space ## fix-fix-fix add unicode normalize!! txt = txt.unicode_normalize(:nfc) ## !! ASSERT FAILED - official name alpha expected; got "Luís Carlos Mateus Filipe" ## Luís Carlos Mateus Filipe ## "Luís Carlos ## Luís Carlos Mateus Filipe # [{"Locale": "en-gb", "Description": "Luís Carlos Mateus Filipe"}], ## !! ASSERT FAILED - official name alpha expected; ## got >Luís Carlos Mateus Filipe< ## => L (76) | u (117) | í (237) | (173) | s (115) | (32) | C (67) | a (97) | r (114) | l (108) | o (111) | s (115) | (32) | M (77) | a (97) | t (116) | e (101) | u (117) | s (115) | (32) | F (70) | i (105) | l (108) | i (105) | p (112) | e (101) | ## You have run straight into a textbook encoding double-decode bug. ## The actual issue is even more interesting than it looks: ## Character 173 (0xAD) shouldn't even be there. ## It only exists in your text because a clean UTF-8 string ## was forced through a bad translation process, ## ripping the letter í completely in half. ## # Clean the string by removing character 173 ## encoding error in pt/2025-26_matches.json ## double check upstream source txt = txt.gsub(/\u{AD}/, '') ### # Or using delete ## txt = txt.delete("\u{AD}") parse_json( txt ) end |
#write_json_v2(path, data) ⇒ Object
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/fifadat/json.rb', line 57 def write_json_v2( path, data ) ## note - always stringify keys for now ## e.g. { name: "" } => { "name": "" } data = _deep_stringify_keys( data ) ## hack - use pretty_inspect for json pretty print txtjson = data.pretty_inspect txtjson = txtjson.gsub( '=>', ': ' ) txtjson = txtjson.gsub( /\bnil\b/, 'null' ) ## double check for syntax errors json = JSON.parse( txtjson ) write_text( path, txtjson ) end |