lib/ossert/fetch/bestgems.rb
# frozen_string_literal: true
module Ossert
module Fetch
class BestgemsBase
def self.process_page(page = nil)
doc = Nokogiri::HTML(open("http://bestgems.org/#{endpoint}#{page ? "?page=#{page}" : ''}"))
doc.css('table').xpath('//tr//td').each_slice(4) do |rank, downloads, name, _|
rank = rank.text.delete(',').to_i
downloads = downloads.text.delete(',').to_i
yield(rank, downloads, name.text)
end
end
end
class BestgemsDailyStat < BestgemsBase
def self.endpoint
:daily
end
end
class BestgemsTotalStat < BestgemsBase
def self.endpoint
:total
end
end
class Bestgems
attr_reader :client, :project
extend Forwardable
def_delegators :project, :agility, :community, :meta
def initialize(project)
@client = SimpleClient.new('http://bestgems.org/api/v1/')
@project = project
end
def total_downloads
client.get("gems/#{project.rubygems_alias}/total_downloads.json")
end
def daily_downloads
client.get("gems/#{project.rubygems_alias}/daily_downloads.json")
end
def total_ranking
client.get("gems/#{project.rubygems_alias}/total_ranking.json")
end
def daily_ranking
client.get("gems/#{project.rubygems_alias}/daily_ranking.json")
end
def process
process_total_downloads
process_daily_downloads
process_delta_downloads
end
def process_total_downloads
@downloads_till_now = nil
total_downloads.each do |total|
@downloads_till_now ||= total
quarter_downloads = community.quarters[total[:date]]
quarter_downloads.total_downloads = [
quarter_downloads.total_downloads.to_i,
total[:total_downloads]
].max
end
community.total.total_downloads = @downloads_till_now[:total_downloads]
end
def process_daily_downloads
daily_downloads.each do |daily|
downloads_saved = community.quarters[daily[:date]].delta_downloads.to_i
community.quarters[daily[:date]].delta_downloads = downloads_saved + daily[:daily_downloads].to_i
end
end
def process_delta_downloads
prev_downloads_delta = 0
community.quarters.each_sorted do |start_date, stat|
prev_downloads_delta = stat.delta_downloads.to_i - prev_downloads_delta
community.quarters[start_date].download_divergence = divergence(
prev_downloads_delta, @downloads_till_now[:total_downloads]
)
end
end
private
def divergence(delta, total)
(delta.to_f / total * 100.0).round(2)
end
end
end
end