Add basic client for the GitHub API
This commit is contained in:
parent
7030eb3286
commit
fc42f3dffa
11 changed files with 250 additions and 0 deletions
21
lib/github/client.rb
Normal file
21
lib/github/client.rb
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
module Github
|
||||||
|
class Client
|
||||||
|
attr_reader :connection
|
||||||
|
|
||||||
|
def initialize(token)
|
||||||
|
@connection = Faraday.new(url: 'https://api.github.com') do |faraday|
|
||||||
|
faraday.adapter :net_http_persistent
|
||||||
|
faraday.response :json, content_type: /\bjson$/
|
||||||
|
faraday.authorization 'token', token
|
||||||
|
faraday.response :logger
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def get(url, query = {})
|
||||||
|
rate_limit = RateLimit.new(connection)
|
||||||
|
sleep rate_limit.reset_in if rate_limit.exceed?
|
||||||
|
|
||||||
|
Github::Response.new(connection.get(url, query))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
26
lib/github/collection.rb
Normal file
26
lib/github/collection.rb
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
module Github
|
||||||
|
class Collection
|
||||||
|
def initialize(url)
|
||||||
|
@url = url
|
||||||
|
end
|
||||||
|
|
||||||
|
def fetch(query = {})
|
||||||
|
return [] if @url.blank?
|
||||||
|
|
||||||
|
Enumerator.new do |yielder|
|
||||||
|
loop do
|
||||||
|
response = client.get(@url, query)
|
||||||
|
response.body.each { |item| yielder << item }
|
||||||
|
raise StopIteration unless response.rels.key?(:next)
|
||||||
|
@url = response.rels[:next]
|
||||||
|
end
|
||||||
|
end.lazy
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def client
|
||||||
|
@client ||= Github::Client.new
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
20
lib/github/issues.rb
Normal file
20
lib/github/issues.rb
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
module Github
|
||||||
|
class Issues
|
||||||
|
attr_reader :owner, :repo
|
||||||
|
|
||||||
|
def initialize(owner, repo)
|
||||||
|
@owner = owner
|
||||||
|
@repo = repo
|
||||||
|
end
|
||||||
|
|
||||||
|
def fetch
|
||||||
|
Collection.new(issues_url).fetch(state: :all, sort: :created, direction: :asc, per_page: 10)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def issues_url
|
||||||
|
"/repos/#{owner}/#{repo}/issues"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
20
lib/github/labels.rb
Normal file
20
lib/github/labels.rb
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
module Github
|
||||||
|
class Labels
|
||||||
|
attr_reader :owner, :repo
|
||||||
|
|
||||||
|
def initialize(owner, repo)
|
||||||
|
@owner = owner
|
||||||
|
@repo = repo
|
||||||
|
end
|
||||||
|
|
||||||
|
def fetch
|
||||||
|
Collection.new(labels_url).fetch
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def labels_url
|
||||||
|
"/repos/#{owner}/#{repo}/labels"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
20
lib/github/milestones.rb
Normal file
20
lib/github/milestones.rb
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
module Github
|
||||||
|
class Milestones
|
||||||
|
attr_reader :owner, :repo
|
||||||
|
|
||||||
|
def initialize(owner, repo)
|
||||||
|
@owner = owner
|
||||||
|
@repo = repo
|
||||||
|
end
|
||||||
|
|
||||||
|
def fetch
|
||||||
|
Collection.new(milestones_url).fetch
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def milestones_url
|
||||||
|
"/repos/#{owner}/#{repo}/milestones"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
20
lib/github/pull_requests.rb
Normal file
20
lib/github/pull_requests.rb
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
module Github
|
||||||
|
class PullRequests
|
||||||
|
attr_reader :owner, :repo
|
||||||
|
|
||||||
|
def initialize(owner, repo)
|
||||||
|
@owner = owner
|
||||||
|
@repo = repo
|
||||||
|
end
|
||||||
|
|
||||||
|
def fetch
|
||||||
|
Collection.new(pull_requests_url).fetch(state: :all, sort: :created, direction: :asc)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def pull_requests_url
|
||||||
|
"/repos/#{owner}/#{repo}/pulls"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
41
lib/github/rate_limit.rb
Normal file
41
lib/github/rate_limit.rb
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
module Github
|
||||||
|
class RateLimit
|
||||||
|
SAFE_REMAINING_REQUESTS = 100.freeze
|
||||||
|
SAFE_RESET_TIME = 500.freeze
|
||||||
|
|
||||||
|
attr_reader :connection
|
||||||
|
|
||||||
|
def initialize(connection)
|
||||||
|
@connection = connection
|
||||||
|
end
|
||||||
|
|
||||||
|
def exceed?
|
||||||
|
return false unless enabled?
|
||||||
|
|
||||||
|
remaining <= SAFE_REMAINING_REQUESTS
|
||||||
|
end
|
||||||
|
|
||||||
|
def remaining
|
||||||
|
@remaining ||= response.body.dig('rate', 'remaining').to_i
|
||||||
|
end
|
||||||
|
|
||||||
|
def reset_in
|
||||||
|
@reset ||= response.body.dig('rate', 'reset').to_i
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def rate_limit_url
|
||||||
|
'/rate_limit'
|
||||||
|
end
|
||||||
|
|
||||||
|
def response
|
||||||
|
@response ||= connection.get(rate_limit_url)
|
||||||
|
end
|
||||||
|
|
||||||
|
# GitHub Rate Limit API returns 404 when the rate limit is disabled
|
||||||
|
def enabled?
|
||||||
|
response.status != 404
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
20
lib/github/releases.rb
Normal file
20
lib/github/releases.rb
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
module Github
|
||||||
|
class Releases
|
||||||
|
attr_reader :owner, :repo
|
||||||
|
|
||||||
|
def initialize(owner, repo)
|
||||||
|
@owner = owner
|
||||||
|
@repo = repo
|
||||||
|
end
|
||||||
|
|
||||||
|
def fetch
|
||||||
|
Collection.new(releases_url).fetch
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def releases_url
|
||||||
|
"/repos/#{owner}/#{repo}/releases"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
17
lib/github/repositories.rb
Normal file
17
lib/github/repositories.rb
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
module Github
|
||||||
|
class Repositories
|
||||||
|
def initialize(username)
|
||||||
|
@username = username
|
||||||
|
end
|
||||||
|
|
||||||
|
def fetch
|
||||||
|
Collection.new(repos_url).fetch
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def repos_url
|
||||||
|
'/user/repos'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
22
lib/github/response.rb
Normal file
22
lib/github/response.rb
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
module Github
|
||||||
|
class Response
|
||||||
|
attr_reader :raw, :headers, :body, :status
|
||||||
|
|
||||||
|
def initialize(response)
|
||||||
|
@raw = response
|
||||||
|
@headers = response.headers
|
||||||
|
@body = response.body
|
||||||
|
@status = response.status
|
||||||
|
end
|
||||||
|
|
||||||
|
def rels
|
||||||
|
links = headers['Link'].to_s.split(', ').map do |link|
|
||||||
|
href, name = link.match(/<(.*?)>; rel="(\w+)"/).captures
|
||||||
|
|
||||||
|
[name.to_sym, href]
|
||||||
|
end
|
||||||
|
|
||||||
|
Hash[*links.flatten]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
23
lib/github/user.rb
Normal file
23
lib/github/user.rb
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
module Github
|
||||||
|
class User
|
||||||
|
attr_reader :username
|
||||||
|
|
||||||
|
def initialize(username)
|
||||||
|
@username = username
|
||||||
|
end
|
||||||
|
|
||||||
|
def get
|
||||||
|
client.get(user_url).body
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def client
|
||||||
|
@client ||= Github::Client.new
|
||||||
|
end
|
||||||
|
|
||||||
|
def user_url
|
||||||
|
"/users/#{username}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in a new issue