github-api-client 0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/github_api.rb +28 -0
- data/lib/github_api/base.rb +80 -0
- data/lib/github_api/browser.rb +25 -0
- data/lib/github_api/user.rb +93 -0
- metadata +66 -0
data/lib/github_api.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
$LOAD_PATH << './github_api' << './lib/github_api'
|
3
|
+
|
4
|
+
require 'net/http'
|
5
|
+
require 'uri'
|
6
|
+
require 'yaml'
|
7
|
+
require 'singleton'
|
8
|
+
require 'active_record'
|
9
|
+
|
10
|
+
ActiveRecord::Base.establish_connection :adapter => 'sqlite3', :database => 'ruby.db'
|
11
|
+
|
12
|
+
require 'base'
|
13
|
+
require 'user'
|
14
|
+
require 'browser'
|
15
|
+
require 'rainbow'
|
16
|
+
|
17
|
+
|
18
|
+
begin
|
19
|
+
unless $user = GitHub::User.where(YAML::load_file('config/secrets.yml')['user']).first
|
20
|
+
$user = GitHub::User.create(YAML::load_file('config/secrets.yml')['user'])
|
21
|
+
end rescue puts "Run rake db:migrate task and restart application"
|
22
|
+
|
23
|
+
rescue Errno::ENOENT
|
24
|
+
puts "Could not load config/secrets.yml, have you defined it?"
|
25
|
+
end
|
26
|
+
|
27
|
+
module GitHub #:nodoc:
|
28
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
module GitHub
|
2
|
+
# Basic functionality inherited later
|
3
|
+
class Base
|
4
|
+
# Sends key= value signals at object, that inherits it
|
5
|
+
def build(options = {})
|
6
|
+
options.each_pair do |k, v|
|
7
|
+
self.send "#{k.to_sym}=", v
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
# Synchronizes every information from local database with GitHub
|
12
|
+
# == VERY DANGEROUS AND EVIL
|
13
|
+
# Recursively gets all* GitHub Users, takes years to fetch
|
14
|
+
# * - all that have at least one follower
|
15
|
+
def self.sync
|
16
|
+
puts "Synchronizing local database with GitHub"
|
17
|
+
users = GitHub::User.all
|
18
|
+
count = users.count
|
19
|
+
i = 1
|
20
|
+
users.each do |user|
|
21
|
+
puts "#{count.to_s} / #{i.to_s} - Updating records"
|
22
|
+
i = i + 1
|
23
|
+
# Disabled because of its length
|
24
|
+
#user.get
|
25
|
+
#user.get_followers
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# Converts pitfalls from GitHub API differences into normal data
|
30
|
+
def self.parse_attributes(attributes)
|
31
|
+
#p attributes
|
32
|
+
{:name => :login, :username => :login, :fullname => :name, :followers => :followers_count, :repos => :public_repo_count, :created => :nil}.each do |k, v|
|
33
|
+
unless v == :nil
|
34
|
+
attributes[v] = attributes[k.to_s]
|
35
|
+
end
|
36
|
+
attributes.delete k.to_s
|
37
|
+
end
|
38
|
+
attributes
|
39
|
+
end
|
40
|
+
|
41
|
+
def to_ary #:nodoc:
|
42
|
+
return self.attributes
|
43
|
+
end
|
44
|
+
|
45
|
+
def method_missing(method, *args, &block) #:nodoc:
|
46
|
+
puts "Missing #{method}"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# Singleton class, that is used globally
|
51
|
+
class Helper
|
52
|
+
include Singleton
|
53
|
+
|
54
|
+
# Recognizing objects retrieved from GitHub, creating new and assigning parameters
|
55
|
+
# from YAML
|
56
|
+
# === Objects
|
57
|
+
# * GitHub::User - recognition by key 'user'
|
58
|
+
# More to be added soon
|
59
|
+
def self.build_from_yaml(yaml)
|
60
|
+
yaml = YAML::load yaml
|
61
|
+
object = case
|
62
|
+
when yaml.has_key?('user') then [GitHub::User, 'user']
|
63
|
+
when yaml.has_key?('users') then [[GitHub::User], 'users']
|
64
|
+
end
|
65
|
+
if object.first.class == Array
|
66
|
+
objects = []
|
67
|
+
yaml[object[1]].each do |single_yaml|
|
68
|
+
o = object.first.first.new
|
69
|
+
o.build single_yaml
|
70
|
+
objects << o
|
71
|
+
end
|
72
|
+
objects
|
73
|
+
else
|
74
|
+
object[0] = object.first.new
|
75
|
+
object.first.build yaml[object[1]]
|
76
|
+
object.first
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module GitHub
|
2
|
+
# Handles low-level HTTP requests
|
3
|
+
class Browser
|
4
|
+
include Singleton
|
5
|
+
|
6
|
+
# Returnes root uri for GitHub API
|
7
|
+
def self.base_uri
|
8
|
+
"http://github.com/api/v2/yaml"
|
9
|
+
end
|
10
|
+
|
11
|
+
# Runs HTTP GET request at given uri
|
12
|
+
def self.get(uri)
|
13
|
+
uri = uri.gsub(" ","+")
|
14
|
+
puts "Requesting #{URI.parse(self.base_uri + uri)}"
|
15
|
+
Net::HTTP.get URI.parse(self.base_uri + uri)
|
16
|
+
end
|
17
|
+
|
18
|
+
# Runs HTTP POST requests with options such as GitHub::User.auth_info
|
19
|
+
def self.post(uri, options = {})
|
20
|
+
uri = uri.gsub(" ","+")
|
21
|
+
puts "Requesting #{URI.parse(self.base_uri + uri)} with options: #{options}"
|
22
|
+
Net::HTTP.post_form URI.parse(self.base_uri + uri), options
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,93 @@
|
|
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 => 'followings', :class_name => 'User'
|
5
|
+
has_and_belongs_to_many :following, :foreign_key => 'following_id', :association_foreign_key => 'follower_id', :join_table => 'followings', :class_name => 'User'
|
6
|
+
|
7
|
+
# Fetches info about current_user from GitHub
|
8
|
+
# GitHub::User.new.build(:login => 'asd', :token => 'token').get #=> GitHub::User
|
9
|
+
def get
|
10
|
+
self.update_attributes YAML::load(GitHub::Browser.get("/user/show/#{self.login}"))['user']
|
11
|
+
self
|
12
|
+
end
|
13
|
+
|
14
|
+
# Static function, that gets information about GitHub::User by login.
|
15
|
+
# === Examples
|
16
|
+
# GitHub::User.get('defunkt') #=> GitHub::User
|
17
|
+
def self.get(login)
|
18
|
+
return GitHub::User.find_or_create_by_login YAML::load(GitHub::Browser.get("/user/show/#{login}"))['user']
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.search(login)
|
22
|
+
users = []
|
23
|
+
YAML::load(GitHub::Browser.get("/user/search/#{login}"))['users'].each do |user|
|
24
|
+
users << GitHub::User.find_or_create_by_login(GitHub::Base.parse_attributes(user))
|
25
|
+
end
|
26
|
+
users
|
27
|
+
end
|
28
|
+
|
29
|
+
def set(route = [], options = {}) #:nodoc:
|
30
|
+
return GitHub::Browser.post "/#{route.join('/')}", options.merge(self.auth_info)
|
31
|
+
end
|
32
|
+
|
33
|
+
# End-user way to fetch information
|
34
|
+
def fetch(*things)
|
35
|
+
things.each do |thing|
|
36
|
+
case thing
|
37
|
+
when :self then get
|
38
|
+
when :followers then get_followers
|
39
|
+
end
|
40
|
+
end
|
41
|
+
self
|
42
|
+
end
|
43
|
+
|
44
|
+
# Executes when you got a real object
|
45
|
+
private
|
46
|
+
def get_followers
|
47
|
+
users = YAML::load(GitHub::Browser.get "/user/show/#{login}/followers")['users']
|
48
|
+
|
49
|
+
ids = []
|
50
|
+
i = 1
|
51
|
+
users.each do |user|
|
52
|
+
puts "#{users.length.to_s} / #{i.to_s} - Fetching followers"
|
53
|
+
i = i + 1
|
54
|
+
u = GitHub::User.find_or_create_by_login(user)
|
55
|
+
ids << u.id
|
56
|
+
end
|
57
|
+
|
58
|
+
self.follower_ids = ids
|
59
|
+
self
|
60
|
+
end
|
61
|
+
|
62
|
+
# Returns an array with logins of GitHub::User followers
|
63
|
+
public
|
64
|
+
def self.get_followers(login)
|
65
|
+
users = YAML::load(GitHub::Browser.get "/user/show/#{login}/followers")['users']
|
66
|
+
|
67
|
+
# Loading each user (not effective with 688 followers like schacon has)
|
68
|
+
objects = []
|
69
|
+
i = 1
|
70
|
+
users.each do |user|
|
71
|
+
puts "#{users.length.to_s} / #{i.to_s} - Fetching followers"
|
72
|
+
i = i + 1
|
73
|
+
u = GitHub::User.find_or_create_by_login(user)
|
74
|
+
objects << u
|
75
|
+
end
|
76
|
+
return objects
|
77
|
+
end
|
78
|
+
|
79
|
+
# Collects information from authenticated user.
|
80
|
+
# Used by post requests to authenticate
|
81
|
+
def auth_info
|
82
|
+
{:login => self.login, :token => self.token}
|
83
|
+
end
|
84
|
+
|
85
|
+
# Experimental, sets information about GitHub::User or returns authenticated :self
|
86
|
+
def post(login, options = {})
|
87
|
+
if [:self, :me].include? login
|
88
|
+
login = self.login
|
89
|
+
end
|
90
|
+
return GitHub::Browser.post "/user/show/#{login}", options.merge(self.auth_info)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
metadata
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: github-api-client
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 1
|
8
|
+
version: "0.1"
|
9
|
+
platform: ruby
|
10
|
+
authors:
|
11
|
+
- "Jakub Oko\xC5\x84ski"
|
12
|
+
autorequire:
|
13
|
+
bindir: bin
|
14
|
+
cert_chain: []
|
15
|
+
|
16
|
+
date: 2010-11-28 00:00:00 +01:00
|
17
|
+
default_executable:
|
18
|
+
dependencies: []
|
19
|
+
|
20
|
+
description: Library for easy GitHub API browsing
|
21
|
+
email: kuba@okonski.org
|
22
|
+
executables: []
|
23
|
+
|
24
|
+
extensions: []
|
25
|
+
|
26
|
+
extra_rdoc_files: []
|
27
|
+
|
28
|
+
files:
|
29
|
+
- lib/github_api.rb
|
30
|
+
- lib/github_api/base.rb
|
31
|
+
- lib/github_api/browser.rb
|
32
|
+
- lib/github_api/user.rb
|
33
|
+
has_rdoc: true
|
34
|
+
homepage: http://github.com/farnoy/github-api-client
|
35
|
+
licenses: []
|
36
|
+
|
37
|
+
post_install_message:
|
38
|
+
rdoc_options: []
|
39
|
+
|
40
|
+
require_paths:
|
41
|
+
- lib
|
42
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
43
|
+
none: false
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
segments:
|
48
|
+
- 0
|
49
|
+
version: "0"
|
50
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
51
|
+
none: false
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
segments:
|
56
|
+
- 0
|
57
|
+
version: "0"
|
58
|
+
requirements: []
|
59
|
+
|
60
|
+
rubyforge_project:
|
61
|
+
rubygems_version: 1.3.7
|
62
|
+
signing_key:
|
63
|
+
specification_version: 3
|
64
|
+
summary: Library for easy GitHub API browsing
|
65
|
+
test_files: []
|
66
|
+
|