class GithubStats::User

User object

Attributes

last_updated[R]
name[R]
url[R]

Public Class Methods

new(params = {}) click to toggle source

Creates a new user object

# File lib/githubstats.rb, line 49
def initialize(params = {})
  params = { name: params } unless params.is_a? Hash
  @name = params[:name] || guess_user
  @url = (params[:url] || DEFAULT_URL) % @name
  @last_updated = nil
  enable_caching %i[streak longest_streak streaks]
end

Public Instance Methods

data(reload = false) click to toggle source

Lazy loader for data

# File lib/githubstats.rb, line 91
def data(reload = false)
  load_data if reload == true || @last_updated.nil?
  @data
end
inspect()
Alias for: to_s
longest_streak() click to toggle source

Set a custom longest_streak to account for the overriden streak

# File lib/githubstats.rb, line 83
def longest_streak
  return data.longest_streak if data.longest_streak.size < 364
  streak
end
respond_to_missing?(method, include_private = false) click to toggle source

Adjust respond_to? to properly respond with patched method_missing

Calls superclass method
# File lib/githubstats.rb, line 99
def respond_to_missing?(method, include_private = false)
  load_data if @last_updated.nil?
  super || @data.respond_to?(method, include_private)
end
streak() click to toggle source

Set a custom streaks value that takes into account GitHub, which makes available streak data for longer than a year

# File lib/githubstats.rb, line 69
def streak
  return [] if streaks.empty?
  streaks.last.last.date >= Date.today - 1 ? streaks.last : []
end
streaks() click to toggle source
# File lib/githubstats.rb, line 74
def streaks
  naive = data.streaks
  return naive if naive.last.nil? || naive.last.size < 364
  [real_streak]
end
to_s() click to toggle source

Print human-readable string about object

# File lib/githubstats.rb, line 60
def to_s
  "Contributions from #{@name}"
end
Also aliased as: inspect

Private Instance Methods

download(to_date = nil) click to toggle source

Downloads new data from Github

# File lib/githubstats.rb, line 143
def download(to_date = nil)
  resp = request(to_date)
  html = Nokogiri::HTML(resp)
  svg = html.css('table.ContributionCalendar-grid td[data-date]')
  svg.css('.ContributionCalendar-day').map do |x|
    x.attributes.values_at('data-date', 'data-level').map(&:value)
  end
end
guess_user(names = []) click to toggle source

Guesses the user’s name based on system environment

# File lib/githubstats.rb, line 109
def guess_user(names = [])
  names << Rugged::Config.global['github.user'] if USE_RUGGED
  names << ENV.fetch('USER', nil)
  names.find { |name| name } || (raise 'Failed to guess username')
end
load_data() click to toggle source

Creates a new Data object from downloaded data

# File lib/githubstats.rb, line 118
def load_data
  @data = GithubStats::Data.new download
  @last_updated = Time.now
end
method_missing(sym, *args, &block) click to toggle source
Calls superclass method
# File lib/githubstats.rb, line 163
def method_missing(sym, *args, &block)
  load_data if @last_updated.nil?
  return super unless @data.respond_to? sym
  define_singleton_method(sym) { |*a, &b| @data.send(sym, *a, &b) }
  send(sym, *args, &block)
end
real_streak() click to toggle source
# File lib/githubstats.rb, line 136
def real_streak
  @real_streak ||= real_streak_rewind(data.streaks.last)
end
real_streak_rewind(partial_streak) click to toggle source

Set a custom longest_streak that takes into account GitHub’s historical records

# File lib/githubstats.rb, line 127
def real_streak_rewind(partial_streak)
  new_data = download(partial_streak.first.date - 1)
  old_data = partial_streak.map(&:to_a)
  new_stats = GithubStats::Data.new(new_data + old_data)
  partial_streak = new_stats.streaks.last
  return partial_streak if partial_streak.first.date != new_stats.start_date
  real_streak_rewind partial_streak
end
request(to_date = nil) click to toggle source
# File lib/githubstats.rb, line 152
def request(to_date = nil)
  url = to_date ? @url + "?to=#{to_date.strftime('%Y-%m-%d')}" : @url
  # https://stackoverflow.com/a/5786863/6456163
  resp = Net::HTTP.get_response(URI(url))
  code = resp.code
  raise("Failed loading data from GitHub: #{url} #{code}") if code != '200'
  resp.body
rescue SocketError
  raise RuntimeError
end