module ChartsLookup
Constants
- CHART_DATE_PATTERN
- MAX_ENTRIES
Public Instance Methods
Source
# File lib/charts_lookup.rb, line 80 def error_report(message) { error: true, report: ChartsReport.error(message) } end
Source
# File lib/charts_lookup.rb, line 60 def lookup(country_query, fetch:, limit: MAX_ENTRIES) resolved = ChartsCountry.resolve(country_query) return error_report(resolved[:error]) if resolved[:error] html = fetch.call(ChartsCountry.weekly_url(resolved[:code])) parsed = parse_page(html, limit: limit) entries = parsed[:entries] return error_report("No chart data found for #{resolved[:name]}.") if entries.empty? name = parsed[:country_name] || resolved[:name] report = ChartsReport.build( country_name: name, chart_date: parsed[:chart_date], entries: entries ) { report: report, entries: entries } rescue StandardError error_report("Could not fetch Spotify charts — try again shortly.") end
Source
# File lib/charts_lookup.rb, line 36 def parse_chart_date(doc) title = doc.at("span.pagetitle")&.text.to_s match = title.match(/ - (\d{4}\/\d{2}\/\d{2})/) date = match ? match[1].strip : nil date if date&.match?(CHART_DATE_PATTERN) end
Source
# File lib/charts_lookup.rb, line 30 def parse_country_name(doc) title = doc.at("span.pagetitle")&.text.to_s match = title.match(/Spotify Weekly Chart - (.+?) - /) match ? match[1].strip : nil end
Source
# File lib/charts_lookup.rb, line 43 def parse_entries(doc, limit: MAX_ENTRIES) rows = doc.css("table#spotifyweekly tbody tr") rows.filter_map do |row| cells = row.css("td") next if cells.length < 3 position = cells[0].text.to_s.strip.to_i next unless position.positive? change = cells[1].text.to_s.strip label = cells[2].at("div")&.text.to_s.gsub(/\s+/, " ").strip next if label.empty? { position: position, change: change, label: label } end.first(limit) end
Source
# File lib/charts_lookup.rb, line 19 def parse_page(html, limit: MAX_ENTRIES) doc = Nokogiri.HTML(html.to_s) country_name = parse_country_name(doc) chart_date = parse_chart_date(doc) entries = parse_entries(doc, limit: limit) { country_name: country_name, chart_date: chart_date, entries: entries } rescue StandardError { country_name: nil, chart_date: nil, entries: [] } end