Module: Timeprice::Sources
- Defined in:
- lib/timeprice/sources.rb
Overview
Enumerate bundled data sources with license/attribution and the actual coverage range derived from data/ at runtime.
Constant Summary collapse
- ATTRIBUTIONS =
Static license & attribution metadata. Coverage is computed dynamically.
[ { id: "us_cpi", kind: "cpi", country: "US", name: "U.S. Bureau of Labor Statistics — CPI-U (series CUUR0000SA0)", license: "U.S. Government work — public domain", license_url: "https://www.bls.gov/bls/linksite.htm", attribution: "Data: U.S. Bureau of Labor Statistics", }, { id: "uk_cpi", kind: "cpi", country: "UK", name: "UK Office for National Statistics — CPI all-items (series D7BT)", license: "Open Government Licence v3.0", license_url: "https://www.nationalarchives.gov.uk/doc/open-government-licence/version/3/", attribution: "Contains public sector information licensed under the Open Government Licence v3.0", }, { id: "eu_hicp", kind: "cpi", country: "EU", name: "Eurostat — HICP prc_hicp_midx (Euro area, all items)", license: "Eurostat reuse policy (free reuse with attribution)", license_url: "https://ec.europa.eu/eurostat/about-us/policies/copyright", attribution: "Source: Eurostat", }, { id: "jp_cpi", kind: "cpi", country: "JP", name: "World Bank — FP.CPI.TOTL (annual, JP fallback)", license: "CC BY 4.0", license_url: "https://datacatalog.worldbank.org/public-licenses#cc-by", attribution: "Source: World Bank, FP.CPI.TOTL", }, { id: "vn_cpi", kind: "cpi", country: "VN", name: "World Bank — FP.CPI.TOTL (annual)", license: "CC BY 4.0", license_url: "https://datacatalog.worldbank.org/public-licenses#cc-by", attribution: "Source: World Bank, FP.CPI.TOTL", }, { id: "fx_ecb", kind: "fx", country: nil, name: "European Central Bank reference rates (via Frankfurter)", license: "ECB reference rates — free reuse", license_url: "https://www.ecb.europa.eu/services/disclaimer/html/index.en.html", attribution: "FX data: European Central Bank reference rates via Frankfurter", }, { id: "fx_vnd", kind: "fx", country: "VN", name: "World Bank — PA.NUS.FCRF (VND annual average, broadcast daily)", license: "CC BY 4.0", license_url: "https://datacatalog.worldbank.org/public-licenses#cc-by", attribution: "VND FX: World Bank, PA.NUS.FCRF", }, ].freeze
Class Method Summary collapse
- .coverage_for(src) ⇒ Object
- .cpi_coverage(country) ⇒ Object
- .fx_coverage(id) ⇒ Object
-
.list ⇒ Array<Hash>
Returns an array of hashes with :id, :kind, :name, :license, :license_url, :attribution, :coverage (string like “1990-01 to 2026-03 (monthly+annual)”).
Class Method Details
.coverage_for(src) ⇒ Object
85 86 87 88 89 90 91 92 93 |
# File 'lib/timeprice/sources.rb', line 85 def coverage_for(src) case src[:kind] when "cpi" then cpi_coverage(src[:country]) when "fx" then fx_coverage(src[:id]) else "n/a" end rescue StandardError => e "(coverage unavailable: #{e.})" end |
.cpi_coverage(country) ⇒ Object
95 96 97 98 99 100 101 102 103 |
# File 'lib/timeprice/sources.rb', line 95 def cpi_coverage(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 |
.fx_coverage(id) ⇒ Object
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
# File 'lib/timeprice/sources.rb', line 105 def fx_coverage(id) root = File.join(DataLoader.data_root, "fx", "usd") years = Dir[File.join(root, "*.json")].map { |f| File.basename(f, ".json").to_i }.sort return "no data" if years.empty? case id when "fx_vnd" # VND broadcast-from-annual covers earlier years too. with_vnd = years.select do |y| d = JSON.parse(File.read(File.join(root, "#{y}.json"))) d["rates"].any? { |_, v| v.key?("VND") } end return "no VND data" if with_vnd.empty? "USD↔VND #{with_vnd.first}..#{with_vnd.last}" else # ECB pairs (EUR/GBP/JPY) start 1999 ecb_years = years.select do |y| d = JSON.parse(File.read(File.join(root, "#{y}.json"))) d["rates"].any? { |_, v| v.keys.intersect?(%w[EUR GBP JPY]) } end return "no ECB data" if ecb_years.empty? "USD↔EUR/GBP/JPY daily #{ecb_years.first}..#{ecb_years.last}" end end |
.list ⇒ Array<Hash>
Returns an array of hashes with :id, :kind, :name, :license, :license_url, :attribution, :coverage (string like “1990-01 to 2026-03 (monthly+annual)”).
81 82 83 |
# File 'lib/timeprice/sources.rb', line 81 def list ATTRIBUTIONS.map { |s| s.merge(coverage: coverage_for(s)) } end |