class GithubApi

This class is a basic GitHub API client library. The only function that is exposed publically, get_all_pages, will auto-paginate when needed and if not needeed will just return the hash payload. Most failures that could happen while calling an API are also handled here.

Public Class Methods

new(token = nil) click to toggle source
# File lib/org_lang_stats/github_api.rb, line 17
def initialize(token = nil)
    @token = token
end

Public Instance Methods

abort_max_retries() click to toggle source
# File lib/org_lang_stats/github_api.rb, line 80
def abort_max_retries
    abort 'Max retries limit reached! Run in --debug mode for more info'
end
auth_string() click to toggle source
# File lib/org_lang_stats/github_api.rb, line 21
def auth_string
    "Basic #{Base64.strict_encode64(':' + @token)}" if @token
end
get_all_pages(url:, params: {}, all_pages: []) click to toggle source
# File lib/org_lang_stats/github_api.rb, line 25
def get_all_pages(url:, params: {}, all_pages: [])

    response = get_page(url, params)
    logger.debug "Url:#{url} returned succesfully!"

    resp_body = JSON.parse(response)

    return resp_body if resp_body.is_a?(Hash)
    all_pages += resp_body

    begin
        next_url = get_next_url(response)
        return get_all_pages(url: next_url, params: params, all_pages: all_pages)
    rescue NoMethodError
        # Ends the recursion
        return all_pages
    end
end
get_next_url(response) click to toggle source
# File lib/org_lang_stats/github_api.rb, line 61
def get_next_url(response)
    response.headers[:link].split(',')
                           .select { |link| link.include? 'rel="next"' }.first
                           .split(';').first[/<(.+)>/, 1]
end
get_page(url, params = {}) click to toggle source
# File lib/org_lang_stats/github_api.rb, line 44
def get_page(url, params = {})
    begin
        tries ||= MAX_RETRIES
        RestClient.get(url, params: DEFAULT_PARAMS.merge(params), Authorization: auth_string)
    # Soft error codes
    rescue RestClient::Forbidden, RestClient::Exceptions::OpenTimeout, Errno::ECONNRESET, SocketError => ex

        rate_lim_reached(ex) if ex.class.name == 'RestClient::Forbidden'
        sleep_with_msg(ex)
        retry unless (tries -= 1).zero?
        abort_max_retries
    # Hard error codes
    rescue RestClient::NotFound
        abort "Url #{url} not found!"
    end
end
rate_lim_reached(ex) click to toggle source
# File lib/org_lang_stats/github_api.rb, line 73
def rate_lim_reached(ex)
    reset_in = ex.response.headers[:x_ratelimit_reset].to_i - Time.now.to_i
    logger.debug "Rate limit reached! Limits will be reset in #{reset_in / 60} minutes"
    logger.debug "Sleeping until then...Refresh your IP and rerun if you don't want to wait!"
    sleep reset_in
end
sleep_with_msg(ex) click to toggle source
# File lib/org_lang_stats/github_api.rb, line 67
def sleep_with_msg(ex)
    logger.debug "An error of type #{ex.class} happened, message is #{ex.message}"
    logger.debug "Request will be retried in #{DEFAULT_SLEEP} seconds\n"
    sleep DEFAULT_SLEEP
end