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
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