Module: Timeprice::Sources::Coverage
- Defined in:
- lib/timeprice/sources/coverage.rb
Overview
Computes coverage strings for bundled data sources at runtime. All filesystem reads happen here so the Sources attribution registry stays a pure data table.
Class Method Summary collapse
- .cpi(country) ⇒ Object
- .ecb_summary(years) ⇒ Object
- .for(src) ⇒ String
- .fx(id) ⇒ Object
- .fx_root ⇒ Object
- .fx_years ⇒ Object
- .vnd_summary(years) ⇒ Object
- .year_has_currency?(year, codes) ⇒ Boolean
Class Method Details
.cpi(country) ⇒ Object
26 27 28 29 30 31 32 33 34 |
# File 'lib/timeprice/sources/coverage.rb', line 26 def cpi(country) data = DataLoader.load_cpi(country) monthly = (data["monthly"] || {}).keys.sort annual = (data["annual"] || {}).keys.sort parts = [] parts << "monthly #{monthly.first}..#{monthly.last} (#{monthly.size})" unless monthly.empty? parts << "annual #{annual.first}..#{annual.last} (#{annual.size})" unless annual.empty? parts.join(", ") end |
.ecb_summary(years) ⇒ Object
54 55 56 57 58 59 |
# File 'lib/timeprice/sources/coverage.rb', line 54 def ecb_summary(years) ecb_years = years.select { |y| year_has_currency?(y, %w[EUR GBP JPY]) } return "no ECB data" if ecb_years.empty? "USD↔EUR/GBP/JPY daily #{ecb_years.first}..#{ecb_years.last}" end |
.for(src) ⇒ String
16 17 18 19 20 21 22 23 24 |
# File 'lib/timeprice/sources/coverage.rb', line 16 def for(src) case src[:kind] when "cpi" then cpi(src[:country]) when "fx" then fx(src[:id]) else "n/a" end rescue StandardError => e "(coverage unavailable: #{e.})" end |
.fx(id) ⇒ Object
36 37 38 39 40 41 |
# File 'lib/timeprice/sources/coverage.rb', line 36 def fx(id) years = fx_years return "no data" if years.empty? id == "fx_vnd" ? vnd_summary(years) : ecb_summary(years) end |
.fx_root ⇒ Object
66 67 68 |
# File 'lib/timeprice/sources/coverage.rb', line 66 def fx_root File.join(DataLoader.data_root, "fx", "usd") end |
.fx_years ⇒ Object
43 44 45 |
# File 'lib/timeprice/sources/coverage.rb', line 43 def fx_years Dir[File.join(fx_root, "*.json")].map { |f| File.basename(f, ".json").to_i }.sort end |
.vnd_summary(years) ⇒ Object
47 48 49 50 51 52 |
# File 'lib/timeprice/sources/coverage.rb', line 47 def vnd_summary(years) with_vnd = years.select { |y| year_has_currency?(y, %w[VND]) } return "no VND data" if with_vnd.empty? "USD↔VND #{with_vnd.first}..#{with_vnd.last}" end |
.year_has_currency?(year, codes) ⇒ Boolean
61 62 63 64 |
# File 'lib/timeprice/sources/coverage.rb', line 61 def year_has_currency?(year, codes) rates = JSON.parse(File.read(File.join(fx_root, "#{year}.json")))["rates"] rates.any? { |_, v| v.keys.intersect?(codes) } end |