githu3 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +179 -0
- data/bin/githu3 +7 -0
- data/lib/faraday/response/parse_json.rb +22 -0
- data/lib/githu3/cache/disk.rb +43 -0
- data/lib/githu3/cache/redis.rb +35 -0
- data/lib/githu3/cache.rb +8 -0
- data/lib/githu3/cli.rb +25 -0
- data/lib/githu3/client.rb +46 -30
- data/lib/githu3/comment.rb +15 -0
- data/lib/githu3/commit.rb +13 -0
- data/lib/githu3/connection.rb +47 -0
- data/lib/githu3/core_ext/hash.rb +18 -0
- data/lib/githu3/download.rb +4 -0
- data/lib/githu3/event.rb +6 -0
- data/lib/githu3/git_commit.rb +5 -0
- data/lib/githu3/issue.rb +10 -1
- data/lib/githu3/org.rb +1 -1
- data/lib/githu3/pull.rb +9 -0
- data/lib/githu3/ref.rb +9 -0
- data/lib/githu3/relations.rb +22 -2
- data/lib/githu3/repo.rb +14 -4
- data/lib/githu3/resource.rb +19 -4
- data/lib/githu3/resource_collection.rb +26 -9
- data/lib/githu3/store.rb +2 -2
- data/lib/githu3/team.rb +4 -0
- data/lib/githu3/tree.rb +4 -0
- data/lib/githu3/user.rb +5 -0
- data/lib/githu3/version.rb +1 -1
- data/lib/githu3.rb +23 -1
- metadata +94 -119
- data/.autotest +0 -3
- data/.document +0 -5
- data/.gitignore +0 -22
- data/.rspec +0 -4
- data/.travis.yml +0 -6
- data/Gemfile +0 -16
- data/Rakefile +0 -16
- data/githu3.gemspec +0 -34
- data/spec/fixtures/all_repos.json +0 -54
- data/spec/fixtures/error.json +0 -1
- data/spec/fixtures/issues/comments.json +0 -41
- data/spec/fixtures/issues/event.json +0 -12
- data/spec/fixtures/issues/events.json +0 -14
- data/spec/fixtures/me.json +0 -31
- data/spec/fixtures/orgs/github.json +0 -18
- data/spec/fixtures/orgs/rails.json +0 -18
- data/spec/fixtures/orgs.json +0 -14
- data/spec/fixtures/public_repos.json +0 -132
- data/spec/fixtures/repos/branches.json +0 -23
- data/spec/fixtures/repos/contributors.json +0 -58
- data/spec/fixtures/repos/faraday.json +0 -31
- data/spec/fixtures/repos/issue.json +0 -53
- data/spec/fixtures/repos/issues.json +0 -55
- data/spec/fixtures/repos/label.json +0 -5
- data/spec/fixtures/repos/labels.json +0 -7
- data/spec/fixtures/repos/milestone.json +0 -17
- data/spec/fixtures/repos/milestones.json +0 -19
- data/spec/fixtures/repos/tags.json +0 -164
- data/spec/fixtures/repos/teams.json +0 -17
- data/spec/fixtures/teams/1.json +0 -8
- data/spec/fixtures/teams/members.json +0 -8
- data/spec/fixtures/teams/repos.json +0 -28
- data/spec/fixtures/users/followers.json +0 -80
- data/spec/fixtures/users/following.json +0 -182
- data/spec/fixtures/users/orgs.json +0 -8
- data/spec/fixtures/users/repos.json +0 -132
- data/spec/fixtures/users/sbellity.json +0 -20
- data/spec/githu3/client_spec.rb +0 -66
- data/spec/githu3/error_spec.rb +0 -0
- data/spec/githu3/issue_spec.rb +0 -54
- data/spec/githu3/org_spec.rb +0 -79
- data/spec/githu3/repo_spec.rb +0 -100
- data/spec/githu3/resource_collection_spec.rb +0 -64
- data/spec/githu3/team_spec.rb +0 -47
- data/spec/githu3/user_spec.rb +0 -47
- data/spec/githu3_spec.rb +0 -7
- data/spec/helper.rb +0 -21
data/README.md
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# githu3 [![Build Status](http://travis-ci.org/sbellity/githu3.png)](http://travis-ci.org/sbellity/githu3)
|
2
2
|
|
3
|
+
githu3 is a ruby wrapper for github's v3 api.
|
4
|
+
|
3
5
|
|
4
6
|
## Installation
|
5
7
|
|
@@ -7,7 +9,184 @@
|
|
7
9
|
|
8
10
|
## Usage
|
9
11
|
|
12
|
+
### Authentication
|
13
|
+
|
14
|
+
There are two ways to authenticate
|
15
|
+
|
16
|
+
Basic Authentication:
|
17
|
+
|
18
|
+
client = Githu3::Client.new('username', 'password')
|
19
|
+
|
20
|
+
OAuth2 Token (send in a header):
|
21
|
+
|
22
|
+
client = Githu3::Client.new('myawesomelyverylongoauth2token')
|
23
|
+
|
24
|
+
Or you can use the lib as an un-authenticated client to access only public Github resources...
|
10
25
|
|
26
|
+
client = Githu3::Client.new
|
27
|
+
|
28
|
+
### Getting the basics
|
29
|
+
|
30
|
+
The Githu3::Client instance can directly access github's top-level resources : orgs, repos, teams and users
|
31
|
+
|
32
|
+
to get them :
|
33
|
+
|
34
|
+
c = Githu3::Client.new
|
35
|
+
|
36
|
+
# Org
|
37
|
+
rails_org = c.org 'rails' # -> 'rails' organization wrapped in a Gihu3::Org object
|
38
|
+
|
39
|
+
# Repo
|
40
|
+
rails_repo = c.repo 'rails/rails' # -> That's Rails !
|
41
|
+
|
42
|
+
# User
|
43
|
+
sbellity = c.user 'sbellity' # -> That's me !
|
44
|
+
|
45
|
+
# Team
|
46
|
+
a_team = c.team 123 # -> well... team number '123' if you have access to it
|
47
|
+
|
48
|
+
|
49
|
+
### Getting your stuff
|
50
|
+
|
51
|
+
When authenticated, your Githu3::Client instance can give you direct access to your top-level stuff...
|
52
|
+
|
53
|
+
me = Githu3::Client.new 'myawesomelyverylongoauth2token'
|
54
|
+
|
55
|
+
# Orgs
|
56
|
+
# returns a paginable Githu3::ResourceCollection stuffed with YOUR organizations
|
57
|
+
# more on this Githu3::ResourceCollection thing later...
|
58
|
+
my_orgs = me.orgs
|
59
|
+
|
60
|
+
# Repos
|
61
|
+
my_repos = me.repos
|
62
|
+
|
63
|
+
# Me
|
64
|
+
me = me.me # -> well, you get the point...
|
65
|
+
|
66
|
+
# Followers
|
67
|
+
me.following # -> returns a list a the Githu3::User, that you follow
|
68
|
+
me.followers # -> returns a list a the Githu3::User, that follow you
|
69
|
+
me.following?("rails") # -> true if you follow 'rails', false otherwise
|
70
|
+
|
71
|
+
|
72
|
+
### Getting deeper inside the API with Githu3::Resource Objects
|
73
|
+
|
74
|
+
All the calls to the API either return Githu3::Resource objects (ex. Githu3::User, Githu3::Repo, Githu3::Org...) et Githu3::ResourceCollection objects that wrap... Githu3::Resource objects
|
75
|
+
|
76
|
+
#### Attributes
|
77
|
+
|
78
|
+
All the member attributes are accessible directly via their names. If you try to access an attribute that does not exist... you'll get `nil`
|
79
|
+
|
80
|
+
Examples:
|
81
|
+
|
82
|
+
c = Githu3::Client.new
|
83
|
+
|
84
|
+
rails_org = c.org 'rails'
|
85
|
+
rails_org.login # -> 'rails'
|
86
|
+
rails_org.html_url # -> 'https://github.com/rails'
|
87
|
+
rails_org.public_repos # -> 44
|
88
|
+
rails_org.foo # -> nil
|
89
|
+
|
90
|
+
|
91
|
+
#### Relations
|
92
|
+
|
93
|
+
Relations between the Resources follow the nesting of the Github's REST Api. For example, you can get the list of an org's repos directly from the Githu3::Org object.
|
94
|
+
|
95
|
+
c = Githu3::Client.new
|
96
|
+
rails_org = c.org "rails"
|
97
|
+
rails_org.repos # -> the list of rails' repos
|
98
|
+
|
99
|
+
You can even do this !
|
100
|
+
|
101
|
+
rails_org.repos.first.issues # -> latest issues from rails' first repo
|
102
|
+
|
103
|
+
|
104
|
+
#### Embedding
|
105
|
+
|
106
|
+
Github often embeds objects inside others. For example, rails Repo has an owner object, that is a Githu3::User object... which let you do this:
|
107
|
+
|
108
|
+
rails_repo = c.repo "rails/rails"
|
109
|
+
rails_repo.owner # -> rails org wrapped in a Githu3::User object
|
110
|
+
|
111
|
+
|
112
|
+
|
113
|
+
### Getting lots of stuff with Githu3::ResourceCollection Objects
|
114
|
+
|
115
|
+
#### Acts as Enumerable
|
116
|
+
|
117
|
+
Most results from the Api calls are collections of stuff. Those collections are wrapped in Githu3::ResourceCollection objects that primarily act as Arrays. Meaning that you can safely call the usual `length`, `first`, `last`, `each`, `map`, `select`... an so on... on them.
|
118
|
+
|
119
|
+
#### Pagination
|
120
|
+
|
121
|
+
_Warning !... this Pagination api is very alpha-ish... and very susceptible to change_
|
122
|
+
|
123
|
+
In fact, Github's api generally returns [paginated results](http://developer.github.com/v3/#pagination). Github::ResourceCollection have a pagination api built right in, that lets you do those kinds of stuff :
|
124
|
+
|
125
|
+
rails_repo = c.repo "rails/rails"
|
126
|
+
rails_issues = rails_repo.issues(:per_page => 10, :page => 4) # -> :per_page defaults to 30, :page defaults to 1
|
127
|
+
|
128
|
+
rails_issues.current_page # -> 4
|
129
|
+
rails_issues.length # -> 10
|
130
|
+
|
131
|
+
next_issues = rails_issues.fetch_next # -> next_issues is a plain Array here...
|
132
|
+
# new records are added to your original collection
|
133
|
+
rails_issues.current_page # -> 5
|
134
|
+
rails_issues.length # -> 20
|
135
|
+
|
136
|
+
|
137
|
+
#### Filtering & Sorting
|
138
|
+
|
139
|
+
Github Api provides filter options for most collection calls. To use a filter on your Githu3::ResourceCollection object, you can do
|
140
|
+
|
141
|
+
repo = c.repo "sbellity/githu3"
|
142
|
+
open_issues = repo.issues :state => "open"
|
143
|
+
bugs = repo.issues :tag => "bug"
|
144
|
+
my_issues = repo.issues :assignee => "sbellity"
|
145
|
+
|
146
|
+
# You can also combine and sort them
|
147
|
+
my_open_bugs = repo.issues :assignee => "sbellity",
|
148
|
+
:tag => "bug",
|
149
|
+
:state => "open",
|
150
|
+
:sort => "updated",
|
151
|
+
:direction => "desc"
|
152
|
+
|
153
|
+
|
154
|
+
|
155
|
+
### Rate limiting
|
156
|
+
|
157
|
+
Your app may generate a LOT of requests to Github's API... By default, you are rate-limitted to 5000 requests per day. You can check anytime the status of your allowance via the method "rate_limit" on your Githu3::Client instance.
|
158
|
+
|
159
|
+
c = Githu3::Client.new
|
160
|
+
...
|
161
|
+
c.rate_limit # -> {:limit=>"5000", :remaining=>"4969"}
|
162
|
+
|
163
|
+
|
164
|
+
### Caching results
|
165
|
+
|
166
|
+
Githu3 provides a very basic cache mechanism to avoid making duplicate requests too often. Basically what it does is just record HTTP request results in a store with an expiration timeout and attempts to retrieve the results back from this store before hitting Github's servers. The different clients private data... should be safe, the request headers (that contain auth info) are used to generate the hash. 2 stores are provided by default : Redis and Disk.
|
167
|
+
|
168
|
+
To use them (these are the default options):
|
169
|
+
|
170
|
+
disk_cached_client = Githu3::Client.new('myawesomelyverylongoauth2token', :cache => :disk, :cache_options => {
|
171
|
+
:path => "/tmp/githu3",
|
172
|
+
:namespace => "cache", # or "myawesomelyverylongoauth2token" if you are paranoid...
|
173
|
+
:expiration => 120 # in seconds
|
174
|
+
})
|
175
|
+
|
176
|
+
redis_cached_client = Githu3::Client.new('myawesomelyverylongoauth2token', :cache => :redis, :cache_options => {
|
177
|
+
:host => "localhost", # defaults to localhost
|
178
|
+
:port => 6379 # defaults to 6379
|
179
|
+
:namespace => "githu3", # or "githu3:myawesomelyverylongoauth2token" if you are paranoid...
|
180
|
+
:expiration => 120 # in seconds
|
181
|
+
})
|
182
|
+
|
183
|
+
|
184
|
+
## Limitations / Known issues
|
185
|
+
|
186
|
+
* The current version (0.1.x branch) only supports read (GET) operations on Github... support for CREATE / UPDATE operations should show up in the the 0.2.x branch.
|
187
|
+
* Github's api is still in beta, so this lib could break anytime if they change something, stay tuned for new versions and please report any issue on the project issue tracker.
|
188
|
+
* Some calls (ex. `c.repo('rails/rails').issues` -> 2 HTTP GET) make unnecessary calls to github, we will try to find a way to avoid this overhead in a future version.
|
189
|
+
* This lib is VERY young, please be kind and help me improve it
|
11
190
|
|
12
191
|
|
13
192
|
## Contributing to githu3
|
data/bin/githu3
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
|
3
|
+
module Faraday
|
4
|
+
class Response::ParseJson < Response::Middleware
|
5
|
+
dependency 'multi_json'
|
6
|
+
|
7
|
+
def parse(body)
|
8
|
+
case body
|
9
|
+
when nil
|
10
|
+
nil
|
11
|
+
when ''
|
12
|
+
nil
|
13
|
+
when 'true'
|
14
|
+
true
|
15
|
+
when 'false'
|
16
|
+
false
|
17
|
+
else
|
18
|
+
::MultiJson.decode(body)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
module Githu3
|
4
|
+
module Cache
|
5
|
+
class Disk
|
6
|
+
attr_reader :config, :store
|
7
|
+
|
8
|
+
DEFAULTS = {
|
9
|
+
:path => '/tmp/githu3',
|
10
|
+
:namespace => 'cache',
|
11
|
+
:expire => 120
|
12
|
+
} unless defined?(DEFAULTS)
|
13
|
+
|
14
|
+
def initialize opts={}
|
15
|
+
@config = DEFAULTS.merge(opts || {})
|
16
|
+
@path = ::File.expand_path(::File.join(@config[:path], @config[:namespace]))
|
17
|
+
FileUtils.mkdir_p @path
|
18
|
+
end
|
19
|
+
|
20
|
+
def get k
|
21
|
+
val = nil
|
22
|
+
file_path = ::File.join(@path, k)
|
23
|
+
if ::File.exists?(file_path)
|
24
|
+
if (Time.now - ::File.atime(file_path)) < @config[:expire]
|
25
|
+
val = Marshal.load(::File.read(file_path))
|
26
|
+
else
|
27
|
+
FileUtils.rm(file_path)
|
28
|
+
end
|
29
|
+
else
|
30
|
+
end
|
31
|
+
val
|
32
|
+
end
|
33
|
+
|
34
|
+
def set k, val, opts={}
|
35
|
+
file_path = ::File.join(@path, k)
|
36
|
+
f = open(file_path, 'wb')
|
37
|
+
f.write(Marshal.dump(val))
|
38
|
+
f.close
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'redis'
|
2
|
+
require 'redis/namespace'
|
3
|
+
|
4
|
+
module Githu3
|
5
|
+
module Cache
|
6
|
+
class Redis
|
7
|
+
attr_reader :config, :store
|
8
|
+
|
9
|
+
DEFAULTS = {
|
10
|
+
:host => 'localhost',
|
11
|
+
:port => 6379,
|
12
|
+
:namespace => :githu3,
|
13
|
+
:expire => 120
|
14
|
+
} unless defined?(DEFAULTS)
|
15
|
+
|
16
|
+
def initialize opts={}
|
17
|
+
@config = DEFAULTS.merge(opts || {})
|
18
|
+
redis = ::Redis.new :host => @config[:host], :port => @config[:port]
|
19
|
+
@store = ::Redis::Namespace.new(@config[:namespace].to_sym, :redis => redis)
|
20
|
+
end
|
21
|
+
|
22
|
+
def get k
|
23
|
+
val = @store[k.to_s]
|
24
|
+
val = Marshal.load val unless val.nil?
|
25
|
+
val
|
26
|
+
end
|
27
|
+
|
28
|
+
def set k, val, opts={}
|
29
|
+
@store[k.to_s] = Marshal.dump(val)
|
30
|
+
@store.expire k.to_s, (opts[:expire] || @config[:expire]).to_i
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/lib/githu3/cache.rb
ADDED
data/lib/githu3/cli.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'githu3'
|
3
|
+
require 'thor'
|
4
|
+
require 'yaml'
|
5
|
+
|
6
|
+
module Githu3
|
7
|
+
|
8
|
+
class CLI < Thor
|
9
|
+
|
10
|
+
desc "issues", "get the latest issues from a repo"
|
11
|
+
def issues repo_name
|
12
|
+
client = Githu3::Client.new
|
13
|
+
begin
|
14
|
+
repo = client.repo(repo_name)
|
15
|
+
repo.issues.map do |issue|
|
16
|
+
puts [issue.number.to_s.ljust(5), issue.assignee.to_s.ljust(25), issue.title.to_s].join("\t|\t")
|
17
|
+
end
|
18
|
+
rescue => err
|
19
|
+
puts "Error: #{err.class.name}"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
data/lib/githu3/client.rb
CHANGED
@@ -1,48 +1,46 @@
|
|
1
1
|
require 'faraday'
|
2
|
-
require 'faraday_middleware'
|
3
2
|
require 'faraday/response/raise_githu3_error'
|
3
|
+
require 'faraday/response/parse_json'
|
4
4
|
require 'uri'
|
5
|
+
require 'forwardable'
|
5
6
|
require 'active_support/core_ext/hash'
|
6
7
|
|
7
8
|
module Githu3
|
8
9
|
|
9
10
|
class Client
|
10
11
|
|
12
|
+
extend Forwardable
|
13
|
+
|
11
14
|
BaseUrl = "https://api.github.com"
|
12
15
|
|
13
|
-
|
16
|
+
def_delegator :conn, :rate_limit
|
17
|
+
|
18
|
+
attr_reader :conn, :auth
|
14
19
|
|
15
|
-
def initialize(
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
@conn
|
20
|
+
def initialize(*args)
|
21
|
+
opts = args.extract_options!
|
22
|
+
@conn = Githu3::Connection.new opts do |c|
|
23
|
+
case args.length
|
24
|
+
when 1
|
25
|
+
@auth = :token
|
26
|
+
c.headers["Authorization"] = "token #{args.first}"
|
27
|
+
when 2
|
28
|
+
@auth = :basic
|
29
|
+
c.basic_auth(*args)
|
30
|
+
end
|
31
|
+
end
|
28
32
|
end
|
29
|
-
|
33
|
+
|
34
|
+
def authenticated?
|
35
|
+
!!@auth
|
36
|
+
end
|
37
|
+
|
30
38
|
def get *args
|
31
39
|
opts = args.extract_options!
|
32
40
|
uri = URI.parse(args.shift)
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
end
|
37
|
-
args.unshift uri.path
|
38
|
-
res = @conn.get(*args) do |req|
|
39
|
-
req.params = uri_params
|
40
|
-
if opts[:params].is_a?(Hash)
|
41
|
-
opts[:params].each { |k,v| req.params[k.to_s] = v.to_s }
|
42
|
-
end
|
43
|
-
end
|
44
|
-
@rate_limit[:limit] = res.headers["x-ratelimit-limit"]
|
45
|
-
@rate_limit[:remaining] = res.headers["x-ratelimit-remaining"]
|
41
|
+
uri.query = (opts[:params] || {}).stringify_keys.merge(Hash.from_url_params(uri.query || "")).to_url_params
|
42
|
+
|
43
|
+
res = @conn.get(uri, opts[:headers])
|
46
44
|
res
|
47
45
|
end
|
48
46
|
|
@@ -56,33 +54,51 @@ module Githu3
|
|
56
54
|
# My stuf...
|
57
55
|
|
58
56
|
def me
|
57
|
+
require_auth
|
59
58
|
Githu3::User.new "/user", self
|
60
59
|
end
|
61
60
|
|
62
61
|
def orgs params={}
|
62
|
+
require_auth
|
63
63
|
Githu3::ResourceCollection.new(self, Githu3::Org, "/user/orgs", params)
|
64
64
|
end
|
65
65
|
|
66
66
|
def repos params={}
|
67
|
+
require_auth
|
67
68
|
Githu3::ResourceCollection.new(self, Githu3::Repo, "/user/repos", params)
|
68
69
|
end
|
69
70
|
|
71
|
+
def teams
|
72
|
+
require_auth
|
73
|
+
Githu3::ResourceCollection.new(self, Githu3::Team, "/user/teams")
|
74
|
+
end
|
75
|
+
|
70
76
|
def followers params={}
|
77
|
+
require_auth
|
71
78
|
Githu3::ResourceCollection.new(self, Githu3::User, "/user/followers", params)
|
72
79
|
end
|
73
80
|
|
74
81
|
def following params={}
|
82
|
+
require_auth
|
75
83
|
Githu3::ResourceCollection.new(self, Githu3::User, "/user/following", params)
|
76
84
|
end
|
77
85
|
|
78
86
|
def following?(other_user)
|
87
|
+
require_auth
|
79
88
|
begin
|
80
89
|
get("/user/following/#{other_user}").status == 204
|
81
90
|
rescue Githu3::NotFound
|
82
91
|
false
|
83
92
|
end
|
84
93
|
end
|
85
|
-
|
94
|
+
|
95
|
+
protected
|
96
|
+
|
97
|
+
def require_auth
|
98
|
+
raise Githu3::Unauthorized, "You must me logged in to use this method" unless authenticated?
|
99
|
+
yield if block_given?
|
100
|
+
end
|
101
|
+
|
86
102
|
end
|
87
103
|
|
88
104
|
end
|
data/lib/githu3/comment.rb
CHANGED
@@ -1,5 +1,20 @@
|
|
1
1
|
module Githu3
|
2
2
|
class Comment < Githu3::Resource
|
3
3
|
|
4
|
+
embeds_one :user
|
5
|
+
|
6
|
+
def _type
|
7
|
+
m = url.match(/(issues|gists|pulls)\/comments\/[0-9]+$/)
|
8
|
+
if m.nil? || m[1].nil?
|
9
|
+
"commitcomment"
|
10
|
+
else
|
11
|
+
"#{m[1].singularize}comment"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def _mime_type mt
|
16
|
+
"application/vnd.github-#{_type}.#{mt}+json"
|
17
|
+
end
|
18
|
+
|
4
19
|
end
|
5
20
|
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Githu3
|
2
|
+
class Commit < Githu3::Resource
|
3
|
+
|
4
|
+
embeds_one :committer, :class_name => :user
|
5
|
+
embeds_one :author, :class_name => :user
|
6
|
+
embeds_one :commit, :class_name => :git_commit
|
7
|
+
|
8
|
+
def message
|
9
|
+
_attributes.message || commit.message rescue nil
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'digest/sha1'
|
2
|
+
|
3
|
+
module Githu3
|
4
|
+
|
5
|
+
class Connection
|
6
|
+
|
7
|
+
attr_reader :rate_limit, :cache, :conn
|
8
|
+
|
9
|
+
|
10
|
+
|
11
|
+
def initialize opts={}
|
12
|
+
@conn = Faraday.new({ :url => Githu3::Client::BaseUrl })
|
13
|
+
|
14
|
+
@conn.adapter opts[:adapter] if opts[:adapter]
|
15
|
+
@conn.use Faraday::Response::ParseJson
|
16
|
+
@conn.use Faraday::Response::RaiseGithu3Error
|
17
|
+
|
18
|
+
if opts[:cache]
|
19
|
+
cache_klass = Githu3::Cache.const_get(opts[:cache].to_s.camelize)
|
20
|
+
@cache = cache_klass.new(opts[:cache_config])
|
21
|
+
end
|
22
|
+
|
23
|
+
yield @conn if block_given?
|
24
|
+
|
25
|
+
@rate_limit = {}
|
26
|
+
end
|
27
|
+
|
28
|
+
def get url, headers={}, opts={}
|
29
|
+
use_cache = !@cache.nil? && !opts[:bypass_cache]
|
30
|
+
if use_cache
|
31
|
+
ref = Digest::SHA1.hexdigest [url, headers.to_s].join("")
|
32
|
+
res = @cache.get ref
|
33
|
+
return res unless res.nil?
|
34
|
+
end
|
35
|
+
res = @conn.get(url, headers)
|
36
|
+
if use_cache
|
37
|
+
@cache.set(ref, res) if res.status < 400
|
38
|
+
else
|
39
|
+
@rate_limit[:limit] = res.headers["x-ratelimit-limit"]
|
40
|
+
@rate_limit[:remaining] = res.headers["x-ratelimit-remaining"]
|
41
|
+
end
|
42
|
+
res
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class Hash
|
2
|
+
def to_url_params
|
3
|
+
elements = []
|
4
|
+
keys.size.times do |i|
|
5
|
+
elements << "#{keys[i]}=#{values[i]}"
|
6
|
+
end
|
7
|
+
elements.join('&')
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.from_url_params(url_params="")
|
11
|
+
result = {}
|
12
|
+
url_params.split('&').each do |element|
|
13
|
+
element = element.split('=')
|
14
|
+
result[element[0]] = element[1]
|
15
|
+
end
|
16
|
+
result
|
17
|
+
end
|
18
|
+
end
|
data/lib/githu3/event.rb
CHANGED
data/lib/githu3/issue.rb
CHANGED
@@ -3,7 +3,16 @@ module Githu3
|
|
3
3
|
|
4
4
|
has_many :events
|
5
5
|
has_many :comments
|
6
|
-
has_many :labels
|
7
6
|
|
7
|
+
# members
|
8
|
+
embeds_many :labels
|
9
|
+
embeds_one :user
|
10
|
+
embeds_one :milestone
|
11
|
+
embeds_one :assignee, :class_name => :user
|
12
|
+
|
13
|
+
def _mime_type mt
|
14
|
+
"application/vnd.github-issue.#{mt}+json"
|
15
|
+
end
|
16
|
+
|
8
17
|
end
|
9
18
|
end
|
data/lib/githu3/org.rb
CHANGED
data/lib/githu3/pull.rb
ADDED
data/lib/githu3/ref.rb
ADDED
data/lib/githu3/relations.rb
CHANGED
@@ -1,6 +1,26 @@
|
|
1
1
|
module Githu3
|
2
2
|
|
3
3
|
module Relations
|
4
|
+
|
5
|
+
def embeds_one m, opts={}
|
6
|
+
opts[:class_name] ||= m.to_s
|
7
|
+
define_method(m) do
|
8
|
+
klass = Githu3.const_get(opts[:class_name].to_s.camelize)
|
9
|
+
data = self._attributes.send(m)
|
10
|
+
klass.new(data, @client) unless data.nil?
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def embeds_many m, opts={}
|
15
|
+
opts[:class_name] ||= m.to_s.singularize
|
16
|
+
define_method(m) do
|
17
|
+
klass = Githu3.const_get(opts[:class_name].to_s.camelize)
|
18
|
+
data = self._attributes.send(m)
|
19
|
+
data.map { |o| klass.new(o, @client) } unless data.nil?
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
|
4
24
|
def has_many m, opts={}
|
5
25
|
opts[:class_name] ||= m.to_s.singularize
|
6
26
|
define_method(m) do |*args|
|
@@ -8,9 +28,9 @@ module Githu3
|
|
8
28
|
klass = Githu3.const_get(opts[:class_name].to_s.camelize)
|
9
29
|
_resource_path = [opts[:nested_in], m].compact.join("/")
|
10
30
|
if args.length == 1
|
11
|
-
klass.new([
|
31
|
+
klass.new([_path, _resource_path, args.first].join("/"), @client)
|
12
32
|
else
|
13
|
-
Githu3::ResourceCollection.new(@client, klass, [
|
33
|
+
Githu3::ResourceCollection.new(@client, klass, [_path, _resource_path].join("/"), params)
|
14
34
|
end
|
15
35
|
end
|
16
36
|
end
|