github-api-client 0.3.3 → 0.4.0.pre

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. data/.gitignore +4 -0
  2. data/.rspec +1 -0
  3. data/Gemfile +1 -15
  4. data/Gemfile.lock +23 -25
  5. data/NEWS +18 -0
  6. data/Rakefile +38 -0
  7. data/TODO +6 -0
  8. data/bin/api-browser.rb +12 -17
  9. data/bin/github-api-client +33 -0
  10. data/db/migrate/001_migrate_everything.rb +18 -0
  11. data/features/user_api.feature +88 -0
  12. data/github-api-client.gemspec +41 -0
  13. data/lib/github-api-client.rb +31 -9
  14. data/lib/github-api-client/browser.rb +11 -8
  15. data/lib/github-api-client/config.rb +0 -5
  16. data/lib/github-api-client/fetchers.rb +11 -0
  17. data/lib/github-api-client/fetchers/repo.rb +32 -0
  18. data/lib/github-api-client/fetchers/user.rb +49 -0
  19. data/lib/github-api-client/helpers.rb +15 -0
  20. data/lib/github-api-client/resource.rb +72 -0
  21. data/lib/github-api-client/resources/repo.rb +13 -0
  22. data/lib/github-api-client/resources/user.rb +10 -0
  23. data/lib/github-api-client/strategies/ask.rb +14 -0
  24. data/lib/github-api-client/strategies/local.rb +14 -0
  25. data/lib/github-api-client/strategies/remote.rb +14 -0
  26. data/lib/github-api-client/strategy.rb +15 -0
  27. data/lib/github-api-client/version.rb +10 -0
  28. data/new_design +4 -0
  29. metadata +62 -68
  30. data/VERSION +0 -1
  31. data/db/migrate/001_create_users.rb +0 -21
  32. data/db/migrate/002_create_user_followings.rb +0 -12
  33. data/db/migrate/003_create_repos.rb +0 -32
  34. data/db/migrate/004_create_repo_watchings.rb +0 -12
  35. data/db/migrate/005_create_organizations.rb +0 -15
  36. data/db/migrate/006_create_organizations_members.rb +0 -12
  37. data/lib/github-api-client/organization.rb +0 -64
  38. data/lib/github-api-client/repo.rb +0 -99
  39. data/lib/github-api-client/user.rb +0 -186
data/VERSION DELETED
@@ -1 +0,0 @@
1
- 0.3.3
@@ -1,21 +0,0 @@
1
- class CreateUsers < ActiveRecord::Migration
2
- def self.up
3
- create_table :users do |t|
4
- %w(login token type name company location blog email language permission).each do |attr|
5
- t.string attr
6
- end
7
-
8
- %w(gravatar_id score record).each do |attr|
9
- t.integer attr
10
- end
11
-
12
- %w(created_at pushed).each do |attr|
13
- t.datetime attr
14
- end
15
- end
16
- end
17
-
18
- def self.down
19
- drop_table :users
20
- end
21
- end
@@ -1,12 +0,0 @@
1
- class CreateUserFollowings < ActiveRecord::Migration
2
- def self.up
3
- create_table :user_followings, :id => false do |t|
4
- t.references :follower
5
- t.references :following
6
- end
7
- end
8
-
9
- def self.down
10
- drop_table :user_followings
11
- end
12
- end
@@ -1,32 +0,0 @@
1
- class CreateRepos < ActiveRecord::Migration
2
- def self.up
3
- create_table :repos do |t|
4
- %w(name description url language integrate_branch homepage source).each do |attr|
5
- t.string attr
6
- end
7
-
8
- %w(parent).each do |attr|
9
- t.references attr
10
- end
11
-
12
- t.references :owner, :polymorphic => true
13
-
14
- # TODO: organization temporarily a string, only when there's no organization model
15
- %w(size score).each do |attr|
16
- t.integer attr
17
- end
18
-
19
- %w(has_downloads b_fork deleted locked has_wiki private open_issues has_issues).each do |attr|
20
- t.boolean attr
21
- end
22
-
23
- %w(created_at pushed_at).each do |attr|
24
- t.datetime attr
25
- end
26
- end
27
- end
28
-
29
- def self.down
30
- drop_table :repos
31
- end
32
- end
@@ -1,12 +0,0 @@
1
- class CreateRepoWatchings < ActiveRecord::Migration
2
- def self.up
3
- create_table :repo_watchings, :id => false do |t|
4
- t.references :watcher
5
- t.references :repo
6
- end
7
- end
8
-
9
- def self.down
10
- drop_table :repo_watchings
11
- end
12
- end
@@ -1,15 +0,0 @@
1
- class CreateOrganizations < ActiveRecord::Migration
2
- def self.up
3
- create_table :organizations do |t|
4
- %w(name company location blog type login email gravatar_id billing_email permission).each do |attr|
5
- t.string attr
6
- end
7
-
8
- t.timestamps
9
- end
10
- end
11
-
12
- def self.down
13
- drop_table :organizations
14
- end
15
- end
@@ -1,12 +0,0 @@
1
- class CreateOrganizationsMembers < ActiveRecord::Migration
2
- def self.up
3
- create_table :organizations_members, :id => false do |t|
4
- t.references :user
5
- t.references :organization
6
- end
7
- end
8
-
9
- def self.down
10
- drop_table :organizations_member
11
- end
12
- end
@@ -1,64 +0,0 @@
1
- module GitHub
2
- class Organization < ActiveRecord::Base
3
- has_and_belongs_to_many :members, :class_name => 'GitHub::User', :join_table => 'organizations_members'
4
- has_many :repositories, :class_name => 'GitHub::Repo', :as => :owner
5
-
6
- def get
7
- self.update_attributes(
8
- GitHub::Base.parse_attributes(:org_get,
9
- YAML::load(
10
- GitHub::Browser.get("/organizations/#{self.login}"))['organization']))
11
- self
12
- end
13
-
14
- def self.get(login)
15
- o = GitHub::Organization.find_by_login(login)
16
- o ||= GitHub::Organization.new(:login => login).get
17
- end
18
-
19
- def fetch(*things)
20
- things.each do |thing|
21
- case thing
22
- when :self then get
23
- when :members then get_members
24
- when :repositories then get_repositories
25
- end
26
- end
27
- self
28
- end
29
-
30
- private
31
- def get_members
32
- members = YAML::load(GitHub::Browser.get "/organizations/#{login}/public_members")['users']
33
- puts "Fetching members for #{"organization".color(:magenta).bright} #{self.login.dup.color(:green).bright}"
34
- i, count = 0, members.count.to_s.color(:green).bright
35
- self.transaction do
36
- members.each do |user|
37
- i += 1
38
- u = GitHub::User.find_or_create_by_login(user['login'])
39
- self.association(:members).find_or_create u
40
- print "\r#{i.to_s.color(:yellow).bright}/#{count}"
41
- end
42
- end
43
- puts nil
44
- self
45
- end
46
-
47
- def get_repositories
48
- repos = YAML::load(GitHub::Browser.get "/organizations/#{login}/public_repositories")['repositories']
49
- puts "Fetching repositories for #{"organization".color(:magenta).bright} #{self.login.dup.color(:green).bright}"
50
- i, count = 0, repos.count.to_s.color(:green).bright
51
- self.transaction do
52
- repos.each do |repo|
53
- i += 1
54
- r = GitHub::Repo.find_by_url(repo[:url])
55
- r ||= GitHub::Repo.create(GitHub::Base.parse_attributes :org_repo_index, repo)
56
- print "\r#{i.to_s.color(:yellow).bright}/#{count}"
57
- end
58
- end
59
- puts nil
60
- self
61
- end
62
-
63
- end
64
- end
@@ -1,99 +0,0 @@
1
- module GitHub
2
- class Repo < ActiveRecord::Base
3
- belongs_to :owner, :polymorphic => true
4
- belongs_to :parent, :class_name => 'GitHub::Repo'
5
- has_and_belongs_to_many :watchers, :class_name => 'GitHub::User', :join_table => 'repo_watchings', :foreign_key => 'repo_id', :association_foreign_key => 'watcher_id'
6
-
7
- def get
8
- parser = case self.owner_type
9
- when 'GitHub::User'
10
- :repo_get
11
- when 'GitHub::Organization'
12
- :org_repo_get
13
- end
14
- self.update_attributes GitHub::Base.parse_attributes(parser,
15
- YAML::load(
16
- GitHub::Browser.get("/repos/show/#{self.permalink}"))['repository'])
17
- self
18
- end
19
-
20
- def self.get(information, o_type = :user)
21
- #FIXME: permalink column must be present, comparing url's is surely not the most efficient way for the db
22
- conditions = {:name => information.split('/').last}
23
- if o_type == :user
24
- conditions.merge! :owner_id => GitHub::User.find_or_create_by_login(information.split('/').first).id, :owner_type => 'GitHub::User'
25
- else
26
- conditions.merge! :owner_id => GitHub::Organization.find_or_create_by_login(information.split('/').first).id, :owner_type => 'GitHub::Organization'
27
- end
28
- if r = GitHub::Repo.where(conditions).first
29
- r.get
30
- else
31
- r = GitHub::Repo.new(conditions).get
32
- p r.parent
33
- r
34
- end
35
- end
36
-
37
- def fetch(*things)
38
- things.each do |thing|
39
- case thing
40
- when :self then get
41
- when :watchers then get_watchers
42
- end
43
- end
44
- self
45
- end
46
-
47
- private
48
- def get_watchers
49
- watchers = YAML::load(GitHub::Browser.get("/repos/show/#{self.permalink}/watchers"))['watchers']
50
- puts "Fetching watchers for #{"repo".color(:blue).bright} #{self.permalink.dup.color(:green).bright}"
51
- i, count = 0, watchers.count.to_s.color(:green).bright
52
- self.transaction do
53
- watchers.each do |watcher|
54
- i += 1
55
- attr = {:login => watcher}
56
- self.association(:watchers).find_or_create(GitHub::User.find_or_create_by_login(attr))
57
- print "\r#{i.to_s.color(:blue).bright}/#{count}"
58
- end
59
- end
60
- puts nil
61
- self
62
- end
63
-
64
- public
65
- def owner_login=(user)
66
- if user
67
- self.owner = GitHub::User.find_or_create_by_login(user)
68
- end
69
- end
70
-
71
- def organization_login=(organization)
72
- if organization
73
- self.owner = Organization.find_or_create_by_login(organization)
74
- end
75
- end
76
-
77
- def parent=(permalink)
78
- #FIXME: parent repo does not allow organization to be owner ATM
79
- owner = GitHub::User.find_or_create_by_login permalink.split('/').first
80
- name = permalink.split('/').last
81
- repo = GitHub::Repo.where(:owner_id => owner.id, :owner_type => 'GitHub::Repo', :name => name).first
82
- repo ||= GitHub::Repo.create(:owner => owner, :name => name)
83
- self.parent_id = repo.id
84
- end
85
-
86
- def permalink
87
- "#{owner.login}/#{name}"
88
- end
89
-
90
- # For future, when sql will be find_or_create_by_permalink
91
- def permalink=(anything)
92
- @permalink = permalink
93
- end
94
-
95
- def fork?
96
- b_fork
97
- end
98
- end
99
- end
@@ -1,186 +0,0 @@
1
- module GitHub
2
- # Basic model, stores retrieved user and his associations
3
- class User < ActiveRecord::Base
4
- has_and_belongs_to_many :followers, :foreign_key => 'follower_id', :association_foreign_key => 'following_id', :join_table => 'user_followings', :class_name => 'User'
5
- has_and_belongs_to_many :followings, :foreign_key => 'following_id', :association_foreign_key => 'follower_id', :join_table => 'user_followings', :class_name => 'User'
6
- has_many :repos, :class_name => 'GitHub::Repo', :as => :owner
7
-
8
- # FIXME: Does GitHub allow a user to have multiple organizations?
9
- has_and_belongs_to_many :organizations, :join_table => 'organizations_members'
10
-
11
- # Fetches info about current_user from GitHub
12
- # GitHub::User.new.build(:login => 'asd', :token => 'token').get #=> GitHub::User
13
- # @return [GitHub::User] Chainable self object after syncing attributes with GitHub
14
- def get
15
- self.update_attributes(
16
- GitHub::Base.parse_attributes(:user_get,
17
- YAML::load(
18
- GitHub::Browser.get("/user/show/#{self.login}"))['user']))
19
- self
20
- end
21
-
22
- # Static function, that gets information about GitHub::User by login.
23
- # === Examples
24
- # GitHub::User.get('defunkt') #=> GitHub::User
25
- # @param [String] login GitHub user login to fetch
26
- # @return [GitHub::User] Newly created, in local database user synced with github
27
- def self.get(login)
28
- if u = GitHub::User.find_by_login(login)
29
- u.get
30
- else
31
- u = GitHub::User.new(:login => login).fetch(:self)
32
- end
33
- end
34
-
35
- # Searches for users in GitHub database
36
- # @param [String] login GitHub user login to search
37
- # @return [Array<GitHub::User>] All users that matched login
38
- def self.search(login)
39
- users = []
40
- YAML::load(GitHub::Browser.get("/user/search/#{login}"))['users'].each do |user|
41
- users << GitHub::User.find_or_create_by_login(GitHub::Base.parse_attributes(:user_search, user))
42
- end
43
- users
44
- end
45
-
46
- # Experimental function, requests POST transmission to custom path of GitHub API
47
- # @param [Array] route Route splitted like: ['users', 'search', 'chacon']
48
- # @param [Hash] options Options to pass with the request
49
- # @option [Hash] options 'values[email]' => 'test@api.com'
50
- def set(route = [], options = {})
51
- return GitHub::Browser.post "/#{route.join('/')}", options.merge(self.auth_info)
52
- end
53
-
54
- # End-user way to fetch information
55
- # @param [Array<Symbol>] things Things to fetch for GitHub::User
56
- # @option things [Symbol] :self Sync with GitHub Database
57
- # @option things [Symbol] :followers Map followers from GitHub Database
58
- # @option things [Symbol] :followings Map user's followings from GitHub
59
- # @return [GitHub::User] Chainable, updated User
60
- # @see GitHub::User#get
61
- # @see GitHub::User#get_followers
62
- def fetch(*things)
63
- things.each do |thing|
64
- case thing
65
- when :self then get
66
- when :followers then get_followers
67
- when :followings then get_followings
68
- when :organizations then get_organizations
69
- when :repos then get_repos
70
- end
71
- end
72
- self
73
- end
74
-
75
- # Executes when you got a real object
76
- # @see GitHub::User#fetch
77
- # @return GitHub::User Chainable after mapping followers association
78
- private
79
- def get_followers
80
- users = YAML::load(GitHub::Browser.get "/user/show/#{login}/followers")['users'] || []
81
- puts "Fetching followers for #{"user".color(:yellow).bright} #{self.login.dup.color(:green).bright}"
82
- i, count = 0, users.count.to_s.color(:green).bright
83
- self.transaction do
84
- users.each do |user|
85
- i += 1
86
- u = GitHub::User.find_or_create_by_login(user)
87
- self.association(:followers).find_or_create u
88
- print "\r#{i.to_s.color(:yellow).bright}/#{count}"
89
- end
90
- end
91
- puts nil
92
- self
93
- end
94
-
95
- def get_followings
96
- users = YAML::load(GitHub::Browser.get "/user/show/#{login}/following")['users'] || []
97
- puts "Fetching followings for #{"user".color(:yellow).bright} #{self.login.dup.color(:green).bright}"
98
- i, count = 0, users.count.to_s.color(:green).bright
99
- self.transaction do
100
- users.each do |user|
101
- i += 1
102
- u = GitHub::User.find_or_create_by_login(user)
103
- self.association(:followings).find_or_create u
104
- print "\r#{i.to_s.color(:yellow).bright}/#{count}"
105
- end
106
- end
107
- puts nil
108
- self
109
- end
110
-
111
- def get_organizations
112
- organizations = YAML::load(GitHub::Browser.get "/user/show/#{login}/organizations")['organizations'] || []
113
- puts "Fetching organizations for #{"user".color(:yellow).bright} #{self.login.dup.color(:green).bright}"
114
- i, count = 0, organizations.count.to_s.color(:green).bright
115
- self.transaction do
116
- organizations.each do |org|
117
- i += 1
118
- u = GitHub::Organization.find_or_create_by_login(org['login'])
119
- self.association(:organizations).find_or_create u
120
- print "\r#{i.to_s.color(:yellow).bright}/#{count}"
121
- end
122
- end
123
- puts nil
124
- self
125
- end
126
-
127
- # Executes when you got a real object
128
- # @see GitHub::User#fetch
129
- # @return GitHub::User Chainable after mapping followers association
130
- def get_repos
131
- repos = YAML::load(GitHub::Browser.get "/repos/show/#{login}")['repositories'] || []
132
- puts "Fetching repositories for #{"user".color(:yellow).bright} #{self.login.dup.color(:green).bright}"
133
- i, count = 0, repos.count.to_s.color(:green).bright
134
- self.transaction do
135
- repos.each do |repo|
136
- i += 1
137
- u = GitHub::User.find_or_create_by_login(repo[:owner])
138
- r = GitHub::Repo.where(:owner_id => u.id, :name => repo[:name]).first
139
- r ||= GitHub::Repo.create(:owner => u, :name => repo[:name])
140
- print "\r#{i.to_s.color(:yellow).bright}/#{count}"
141
- end
142
- end
143
- puts nil
144
- self
145
- end
146
-
147
- public
148
- # Returns an array with logins of GitHub::User followers
149
- # @param [String] login GitHub login of which followers will be mapped
150
- # @return [Array<GitHub::User>] Followers
151
- # @deprecated It should not support such way, there should be objects!
152
- def self.get_followers(login)
153
- users = YAML::load(GitHub::Browser.get "/user/show/#{login}/followers")['users']
154
-
155
- # Loading each user (not effective with 688 followers like schacon has)
156
- objects = []
157
- i = 1
158
- users.each do |user|
159
- puts "#{users.length.to_s} / #{i.to_s} - Fetching followers"
160
- i = i + 1
161
- u = GitHub::User.find_or_create_by_login(user)
162
- objects << u
163
- end
164
- return objects
165
- end
166
-
167
- # Collects information from authenticated user.
168
- # Used by post requests to authenticate
169
- # @return [Hash] Collected from GitHub::User options for HTTP POST request authentication
170
- def auth_info
171
- {:login => self.login, :token => self.token}
172
- end
173
-
174
- # Experimental, sets information about GitHub::User or returns authenticated :self
175
- # @param [String] login Login to which post request will be sent
176
- # @param [Hash] options Options to include to a post request
177
- # @option options [Hash] email 'values[email]' => 'test@api.com' - Sets user email to test@api.com if authenticated
178
- # @return [String] Request retrieved data
179
- def post(login, options = {})
180
- if [:self, :me].include? login
181
- login = self.login
182
- end
183
- return GitHub::Browser.post "/user/show/#{login}", options.merge(self.auth_info)
184
- end
185
- end
186
- end