summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDouglas Barbosa Alexandre <dbalexandre@gmail.com>2017-04-11 22:33:54 -0300
committerDouglas Barbosa Alexandre <dbalexandre@gmail.com>2017-04-24 16:17:52 -0300
commitfc42f3dffa364a360c76ff2785813d74f42016c7 (patch)
tree1bf7e3a340e910756ddde22bd4b8bdb1b6429048 /lib
parent7030eb3286613be919e12daf95c43061b49aa5f5 (diff)
downloadgitlab-ce-fc42f3dffa364a360c76ff2785813d74f42016c7.tar.gz
Add basic client for the GitHub API
Diffstat (limited to 'lib')
-rw-r--r--lib/github/client.rb21
-rw-r--r--lib/github/collection.rb26
-rw-r--r--lib/github/issues.rb20
-rw-r--r--lib/github/labels.rb20
-rw-r--r--lib/github/milestones.rb20
-rw-r--r--lib/github/pull_requests.rb20
-rw-r--r--lib/github/rate_limit.rb41
-rw-r--r--lib/github/releases.rb20
-rw-r--r--lib/github/repositories.rb17
-rw-r--r--lib/github/response.rb22
-rw-r--r--lib/github/user.rb23
11 files changed, 250 insertions, 0 deletions
diff --git a/lib/github/client.rb b/lib/github/client.rb
new file mode 100644
index 00000000000..2511523bf6a
--- /dev/null
+++ b/lib/github/client.rb
@@ -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
diff --git a/lib/github/collection.rb b/lib/github/collection.rb
new file mode 100644
index 00000000000..bbca12a1c84
--- /dev/null
+++ b/lib/github/collection.rb
@@ -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
diff --git a/lib/github/issues.rb b/lib/github/issues.rb
new file mode 100644
index 00000000000..27843e1cdd8
--- /dev/null
+++ b/lib/github/issues.rb
@@ -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
diff --git a/lib/github/labels.rb b/lib/github/labels.rb
new file mode 100644
index 00000000000..0ea023888b3
--- /dev/null
+++ b/lib/github/labels.rb
@@ -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
diff --git a/lib/github/milestones.rb b/lib/github/milestones.rb
new file mode 100644
index 00000000000..d50278105db
--- /dev/null
+++ b/lib/github/milestones.rb
@@ -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
diff --git a/lib/github/pull_requests.rb b/lib/github/pull_requests.rb
new file mode 100644
index 00000000000..af04c90d454
--- /dev/null
+++ b/lib/github/pull_requests.rb
@@ -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
diff --git a/lib/github/rate_limit.rb b/lib/github/rate_limit.rb
new file mode 100644
index 00000000000..30b000f8a9a
--- /dev/null
+++ b/lib/github/rate_limit.rb
@@ -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
diff --git a/lib/github/releases.rb b/lib/github/releases.rb
new file mode 100644
index 00000000000..026ef4e6853
--- /dev/null
+++ b/lib/github/releases.rb
@@ -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
diff --git a/lib/github/repositories.rb b/lib/github/repositories.rb
new file mode 100644
index 00000000000..42342471102
--- /dev/null
+++ b/lib/github/repositories.rb
@@ -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
diff --git a/lib/github/response.rb b/lib/github/response.rb
new file mode 100644
index 00000000000..c34b69aa4ea
--- /dev/null
+++ b/lib/github/response.rb
@@ -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
diff --git a/lib/github/user.rb b/lib/github/user.rb
new file mode 100644
index 00000000000..19fe6230820
--- /dev/null
+++ b/lib/github/user.rb
@@ -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