github_api2 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (127) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +770 -0
  3. data/LICENSE.txt +20 -0
  4. data/README.md +741 -0
  5. data/lib/github_api2/api/actions.rb +60 -0
  6. data/lib/github_api2/api/arguments.rb +253 -0
  7. data/lib/github_api2/api/config/property.rb +30 -0
  8. data/lib/github_api2/api/config/property_set.rb +120 -0
  9. data/lib/github_api2/api/config.rb +105 -0
  10. data/lib/github_api2/api/factory.rb +33 -0
  11. data/lib/github_api2/api.rb +398 -0
  12. data/lib/github_api2/authorization.rb +75 -0
  13. data/lib/github_api2/client/activity/events.rb +233 -0
  14. data/lib/github_api2/client/activity/feeds.rb +50 -0
  15. data/lib/github_api2/client/activity/notifications.rb +181 -0
  16. data/lib/github_api2/client/activity/starring.rb +130 -0
  17. data/lib/github_api2/client/activity/watching.rb +176 -0
  18. data/lib/github_api2/client/activity.rb +31 -0
  19. data/lib/github_api2/client/authorizations/app.rb +98 -0
  20. data/lib/github_api2/client/authorizations.rb +142 -0
  21. data/lib/github_api2/client/emojis.rb +19 -0
  22. data/lib/github_api2/client/gists/comments.rb +100 -0
  23. data/lib/github_api2/client/gists.rb +289 -0
  24. data/lib/github_api2/client/git_data/blobs.rb +51 -0
  25. data/lib/github_api2/client/git_data/commits.rb +101 -0
  26. data/lib/github_api2/client/git_data/references.rb +150 -0
  27. data/lib/github_api2/client/git_data/tags.rb +95 -0
  28. data/lib/github_api2/client/git_data/trees.rb +113 -0
  29. data/lib/github_api2/client/git_data.rb +31 -0
  30. data/lib/github_api2/client/gitignore.rb +57 -0
  31. data/lib/github_api2/client/issues/assignees.rb +77 -0
  32. data/lib/github_api2/client/issues/comments.rb +146 -0
  33. data/lib/github_api2/client/issues/events.rb +50 -0
  34. data/lib/github_api2/client/issues/labels.rb +189 -0
  35. data/lib/github_api2/client/issues/milestones.rb +146 -0
  36. data/lib/github_api2/client/issues.rb +248 -0
  37. data/lib/github_api2/client/markdown.rb +62 -0
  38. data/lib/github_api2/client/meta.rb +19 -0
  39. data/lib/github_api2/client/orgs/hooks.rb +182 -0
  40. data/lib/github_api2/client/orgs/members.rb +142 -0
  41. data/lib/github_api2/client/orgs/memberships.rb +131 -0
  42. data/lib/github_api2/client/orgs/projects.rb +57 -0
  43. data/lib/github_api2/client/orgs/teams.rb +407 -0
  44. data/lib/github_api2/client/orgs.rb +127 -0
  45. data/lib/github_api2/client/projects/cards.rb +158 -0
  46. data/lib/github_api2/client/projects/columns.rb +146 -0
  47. data/lib/github_api2/client/projects.rb +83 -0
  48. data/lib/github_api2/client/pull_requests/comments.rb +140 -0
  49. data/lib/github_api2/client/pull_requests/reviews.rb +158 -0
  50. data/lib/github_api2/client/pull_requests.rb +195 -0
  51. data/lib/github_api2/client/repos/branches/protections.rb +75 -0
  52. data/lib/github_api2/client/repos/branches.rb +48 -0
  53. data/lib/github_api2/client/repos/collaborators.rb +84 -0
  54. data/lib/github_api2/client/repos/comments.rb +125 -0
  55. data/lib/github_api2/client/repos/commits.rb +80 -0
  56. data/lib/github_api2/client/repos/contents.rb +263 -0
  57. data/lib/github_api2/client/repos/deployments.rb +138 -0
  58. data/lib/github_api2/client/repos/downloads.rb +62 -0
  59. data/lib/github_api2/client/repos/forks.rb +50 -0
  60. data/lib/github_api2/client/repos/hooks.rb +214 -0
  61. data/lib/github_api2/client/repos/invitations.rb +41 -0
  62. data/lib/github_api2/client/repos/keys.rb +104 -0
  63. data/lib/github_api2/client/repos/merging.rb +47 -0
  64. data/lib/github_api2/client/repos/pages.rb +48 -0
  65. data/lib/github_api2/client/repos/projects.rb +62 -0
  66. data/lib/github_api2/client/repos/pub_sub_hubbub.rb +133 -0
  67. data/lib/github_api2/client/repos/releases/assets.rb +136 -0
  68. data/lib/github_api2/client/repos/releases/tags.rb +24 -0
  69. data/lib/github_api2/client/repos/releases.rb +189 -0
  70. data/lib/github_api2/client/repos/statistics.rb +89 -0
  71. data/lib/github_api2/client/repos/statuses.rb +91 -0
  72. data/lib/github_api2/client/repos.rb +473 -0
  73. data/lib/github_api2/client/say.rb +25 -0
  74. data/lib/github_api2/client/scopes.rb +46 -0
  75. data/lib/github_api2/client/search/legacy.rb +111 -0
  76. data/lib/github_api2/client/search.rb +133 -0
  77. data/lib/github_api2/client/users/emails.rb +65 -0
  78. data/lib/github_api2/client/users/followers.rb +115 -0
  79. data/lib/github_api2/client/users/keys.rb +104 -0
  80. data/lib/github_api2/client/users.rb +117 -0
  81. data/lib/github_api2/client.rb +77 -0
  82. data/lib/github_api2/configuration.rb +70 -0
  83. data/lib/github_api2/connection.rb +82 -0
  84. data/lib/github_api2/constants.rb +61 -0
  85. data/lib/github_api2/core_ext/array.rb +25 -0
  86. data/lib/github_api2/core_ext/hash.rb +91 -0
  87. data/lib/github_api2/deprecation.rb +39 -0
  88. data/lib/github_api2/error/client_error.rb +89 -0
  89. data/lib/github_api2/error/service_error.rb +223 -0
  90. data/lib/github_api2/error.rb +32 -0
  91. data/lib/github_api2/ext/faraday.rb +40 -0
  92. data/lib/github_api2/mash.rb +7 -0
  93. data/lib/github_api2/middleware.rb +37 -0
  94. data/lib/github_api2/mime_type.rb +33 -0
  95. data/lib/github_api2/normalizer.rb +23 -0
  96. data/lib/github_api2/null_encoder.rb +25 -0
  97. data/lib/github_api2/page_iterator.rb +138 -0
  98. data/lib/github_api2/page_links.rb +63 -0
  99. data/lib/github_api2/paged_request.rb +42 -0
  100. data/lib/github_api2/pagination.rb +115 -0
  101. data/lib/github_api2/parameter_filter.rb +35 -0
  102. data/lib/github_api2/params_hash.rb +115 -0
  103. data/lib/github_api2/rate_limit.rb +25 -0
  104. data/lib/github_api2/request/basic_auth.rb +36 -0
  105. data/lib/github_api2/request/jsonize.rb +54 -0
  106. data/lib/github_api2/request/oauth2.rb +45 -0
  107. data/lib/github_api2/request/verbs.rb +63 -0
  108. data/lib/github_api2/request.rb +84 -0
  109. data/lib/github_api2/response/atom_parser.rb +22 -0
  110. data/lib/github_api2/response/follow_redirects.rb +140 -0
  111. data/lib/github_api2/response/header.rb +87 -0
  112. data/lib/github_api2/response/jsonize.rb +28 -0
  113. data/lib/github_api2/response/mashify.rb +24 -0
  114. data/lib/github_api2/response/raise_error.rb +22 -0
  115. data/lib/github_api2/response/xmlize.rb +28 -0
  116. data/lib/github_api2/response.rb +48 -0
  117. data/lib/github_api2/response_wrapper.rb +161 -0
  118. data/lib/github_api2/ssl_certs/cacerts.pem +2183 -0
  119. data/lib/github_api2/utils/url.rb +63 -0
  120. data/lib/github_api2/validations/format.rb +26 -0
  121. data/lib/github_api2/validations/presence.rb +32 -0
  122. data/lib/github_api2/validations/required.rb +21 -0
  123. data/lib/github_api2/validations/token.rb +41 -0
  124. data/lib/github_api2/validations.rb +22 -0
  125. data/lib/github_api2/version.rb +5 -0
  126. data/lib/github_api2.rb +92 -0
  127. metadata +363 -0
@@ -0,0 +1,37 @@
1
+ # encoding: utf-8
2
+
3
+ require_relative 'response'
4
+ require_relative 'response/mashify'
5
+ require_relative 'response/jsonize'
6
+ require_relative 'response/atom_parser'
7
+ require_relative 'response/raise_error'
8
+ require_relative 'response/header'
9
+ require_relative 'response/follow_redirects'
10
+
11
+ module Github
12
+ class Middleware
13
+ def self.default(options = {})
14
+ api = options[:api]
15
+ proc do |builder|
16
+ builder.use Github::Request::Jsonize
17
+ builder.use Faraday::Request::Multipart
18
+ builder.use Faraday::Request::UrlEncoded
19
+ builder.use Github::Request::OAuth2, api.oauth_token if api.oauth_token?
20
+ builder.use Github::Request::BasicAuth, api.authentication if api.basic_authed?
21
+
22
+ builder.use Github::Response::FollowRedirects if api.follow_redirects
23
+ builder.use Faraday::Response::Logger if ENV['DEBUG']
24
+ unless options[:raw]
25
+ builder.use Github::Response::Mashify
26
+ builder.use Github::Response::Jsonize
27
+ builder.use Github::Response::AtomParser
28
+ end
29
+ if api.stack
30
+ api.stack.call(builder)
31
+ end
32
+ builder.use Github::Response::RaiseError
33
+ builder.adapter options[:adapter]
34
+ end
35
+ end
36
+ end # Middleware
37
+ end # Github
@@ -0,0 +1,33 @@
1
+ # encoding: utf-8
2
+
3
+ module Github
4
+ module MimeType
5
+
6
+ MEDIA_LOOKUP = {
7
+ 'json' => 'json',
8
+ 'blob' => 'raw',
9
+ 'raw' => 'raw+json',
10
+ 'text' => 'text+json',
11
+ 'html' => 'html+json',
12
+ 'full' => 'full+json'
13
+ }
14
+
15
+ # Parse media type param
16
+ #
17
+ def parse(media)
18
+ version = 'v3'
19
+ media.sub!(/^[.]*|[.]*$/,"")
20
+ media = media.include?('+') ? media.split('+')[0] : media
21
+ version, media = media.split('.') if media.include?('.')
22
+ media_type = lookup_media(media)
23
+ "application/vnd.github.#{version}.#{media_type}"
24
+ end
25
+
26
+ def lookup_media(name)
27
+ MEDIA_LOOKUP.fetch(name) do
28
+ raise ArgumentError, "Provided Media Type #{name} is not valid"
29
+ end
30
+ end
31
+
32
+ end # MimeType
33
+ end # Github
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+ # encoding: utf-8
3
+
4
+ module Github
5
+ # Normalize client-supplied parameter keys.
6
+ module Normalizer
7
+ # Turns any keys from nested hashes including nested arrays into strings
8
+ def normalize!(params)
9
+ case params
10
+ when Hash
11
+ params.keys.each do |k|
12
+ params[k.to_s] = params.delete(k)
13
+ normalize!(params[k.to_s])
14
+ end
15
+ when Array
16
+ params.map! do |el|
17
+ normalize!(el)
18
+ end
19
+ end
20
+ params
21
+ end
22
+ end # Normalizer
23
+ end # Github
@@ -0,0 +1,25 @@
1
+ # encoding: utf-8
2
+
3
+ require 'faraday'
4
+
5
+ module Github
6
+
7
+ # Skip encoding of the key nested parameters
8
+ module NullParamsEncoder
9
+ if defined?(Faraday::NestedParamsEncoder)
10
+ class << self
11
+ Faraday::NestedParamsEncoder.singleton_methods do |m|
12
+ define_method m, ::Faraday::NestedParamsEncoder.method(m).to_proc
13
+ end
14
+ end
15
+ end
16
+
17
+ def self.escape(s)
18
+ s.to_s
19
+ end
20
+
21
+ def self.unescape(s)
22
+ s.to_s
23
+ end
24
+ end # NullEncoder
25
+ end # Github
@@ -0,0 +1,138 @@
1
+ # encoding: utf-8
2
+
3
+ require 'uri'
4
+
5
+ require_relative 'constants'
6
+ require_relative 'paged_request'
7
+ require_relative 'utils/url'
8
+
9
+ module Github
10
+ # A class responsible for requesting resources through page links
11
+ #
12
+ # @api private
13
+ class PageIterator
14
+ include Github::Constants
15
+ include Github::Utils::Url
16
+ include Github::PagedRequest
17
+
18
+ # Setup attribute accesor for all the link types
19
+ ATTRIBUTES = [META_FIRST, META_NEXT, META_PREV, META_LAST]
20
+
21
+ DEFAULT_SHA = 'master'
22
+
23
+ ATTRIBUTES.each do |attr|
24
+ attr_accessor :"#{attr}_page_uri", :"#{attr}_page"
25
+ end
26
+
27
+ attr_reader :current_api
28
+
29
+ def initialize(links, current_api)
30
+ @links = links
31
+ @current_api = current_api
32
+ update_page_links(@links)
33
+ end
34
+
35
+ def next?
36
+ next_page == 0 || !next_page_uri.nil?
37
+ end
38
+
39
+ def count
40
+ parse_query(URI(last_page_uri).query)['page'] if last_page_uri
41
+ end
42
+
43
+ # Perform http get request for the first resource
44
+ #
45
+ def first
46
+ perform_request(first_page_uri) if first_page_uri
47
+ end
48
+
49
+ # Perform http get request for the next resource
50
+ #
51
+ def next
52
+ perform_request(next_page_uri) if next?
53
+ end
54
+
55
+ # Perform http get request for the previous resource
56
+ #
57
+ def prev
58
+ perform_request(prev_page_uri) if prev_page_uri
59
+ end
60
+
61
+ # Perform http get request for the last resource
62
+ #
63
+ def last
64
+ perform_request(last_page_uri) if last_page_uri
65
+ end
66
+
67
+ # Returns the result for a specific page.
68
+ #
69
+ def get_page(page_number)
70
+ # Find URI that we can work with, if we cannot get the first or the
71
+ # last page URI then there is only one page.
72
+ page_uri = first_page_uri || last_page_uri
73
+ return nil unless page_uri
74
+
75
+ perform_request(page_uri, page_number)
76
+ end
77
+
78
+ private
79
+
80
+ def perform_request(page_uri_path, page_number = nil)
81
+ page_uri = URI(page_uri_path)
82
+ params = parse_query(page_uri.query)
83
+
84
+ if page_number
85
+ params['page'] = page_number
86
+ elsif next_page < 1
87
+ sha = sha(params)
88
+ params['sha'] = sha if sha
89
+ else
90
+ params['page'] = parse_page_number(page_uri_path)
91
+ end
92
+ params['per_page'] = parse_per_page_number(page_uri_path)
93
+
94
+ response = page_request(page_uri.path, params)
95
+ update_page_links response.links
96
+ response
97
+ end
98
+
99
+ def sha(params)
100
+ return params['last_sha'] if params.keys.include?('last_sha')
101
+ return DEFAULT_SHA if params.keys.include?('sha')
102
+ end
103
+
104
+ def parse_per_page_number(uri) # :nodoc:
105
+ parse_page_params(uri, PARAM_PER_PAGE)
106
+ end
107
+
108
+ def parse_page_number(uri) # :nodoc:
109
+ parse_page_params(uri, PARAM_PAGE)
110
+ end
111
+
112
+ # Extracts query string parameter for given name
113
+ def parse_page_params(uri, attr) # :nodoc:
114
+ return -1 if uri.nil? || uri.empty?
115
+ parsed = nil
116
+ begin
117
+ parsed = URI.parse(uri)
118
+ rescue URI::Error
119
+ return -1
120
+ end
121
+ param = parse_query_for_param(parsed.query, attr)
122
+ return -1 if param.nil? || param.empty?
123
+ begin
124
+ return param.to_i
125
+ rescue ArgumentError
126
+ return -1
127
+ end
128
+ end
129
+
130
+ # Wholesale update of all link attributes
131
+ def update_page_links(links) # :nodoc:
132
+ ATTRIBUTES.each do |attr|
133
+ send(:"#{attr}_page_uri=", links.send(:"#{attr}"))
134
+ send(:"#{attr}_page=", parse_page_number(links.send(:"#{attr}")))
135
+ end
136
+ end
137
+ end # PageIterator
138
+ end # Github
@@ -0,0 +1,63 @@
1
+ # encoding: utf-8
2
+
3
+ require_relative 'constants'
4
+
5
+ module Github
6
+ # Determines the links in the current response link header to be used
7
+ # to find the links to other pages of request responses. These will
8
+ # only be present if the result set size exceeds the per page limit.
9
+ #
10
+ # @api private
11
+ class PageLinks
12
+ include Github::Constants
13
+
14
+ DELIM_LINKS = ','.freeze # :nodoc:
15
+
16
+ # Hold the extracted values for URI from the Link header
17
+ # for the first, last, next and previous page.
18
+ attr_accessor :first, :last, :next, :prev
19
+
20
+ LINK_REGEX = /<([^>]+)>; rel=\"([^\"]+)\"/
21
+
22
+ # Parses links from executed request
23
+ #
24
+ # @param [Hash] response_headers
25
+ #
26
+ # @api private
27
+ def initialize(response_headers)
28
+ link_header = response_headers[HEADER_LINK]
29
+ if link_header && link_header =~ /(next|first|last|prev)/
30
+ extract_links(link_header)
31
+ else
32
+ # When on the first page
33
+ self.next = response_headers[HEADER_NEXT]
34
+ self.last = response_headers[HEADER_LAST]
35
+ end
36
+ end
37
+
38
+ private
39
+
40
+ def extract_links(link_header)
41
+ link_header.split(DELIM_LINKS).each do |link|
42
+ LINK_REGEX.match(link.strip) do |match|
43
+ url_part, meta_part = match[1], match[2]
44
+ next if !url_part || !meta_part
45
+ assign_url_part(meta_part, url_part)
46
+ end
47
+ end
48
+ end
49
+
50
+ def assign_url_part(meta_part, url_part)
51
+ case meta_part
52
+ when META_FIRST
53
+ self.first = url_part
54
+ when META_LAST
55
+ self.last = url_part
56
+ when META_NEXT
57
+ self.next = url_part
58
+ when META_PREV
59
+ self.prev = url_part
60
+ end
61
+ end
62
+ end # PageLinks
63
+ end # Github
@@ -0,0 +1,42 @@
1
+ # encoding: utf-8
2
+
3
+ require_relative 'constants'
4
+
5
+ module Github
6
+
7
+ # A module that adds http get request to response pagination
8
+ module PagedRequest
9
+ include Github::Constants
10
+
11
+ FIRST_PAGE = 1 # Default request page if none provided
12
+
13
+ PER_PAGE = 30 # Default number of items as specified by API
14
+
15
+ NOT_FOUND = -1 # Either page or per_page parameter not present
16
+
17
+ # Check if current api instance has default per_page param set,
18
+ # otherwise use global default.
19
+ #
20
+ def default_page_size
21
+ current_api.per_page ? current_api.per_page : PER_PAGE
22
+ end
23
+
24
+ def default_page
25
+ current_api.page ? current_api.page : FIRST_PAGE
26
+ end
27
+
28
+ # Perform http get request with pagination parameters
29
+ #
30
+ def page_request(path, params={})
31
+ if params[PARAM_PER_PAGE] == NOT_FOUND
32
+ params[PARAM_PER_PAGE] = default_page_size
33
+ end
34
+ if params[PARAM_PAGE] && params[PARAM_PAGE] == NOT_FOUND
35
+ params[PARAM_PAGE] = default_page
36
+ end
37
+
38
+ current_api.get_request(path, ParamsHash.new(params))
39
+ end
40
+
41
+ end # PagedRequest
42
+ end # Github
@@ -0,0 +1,115 @@
1
+ # encoding: utf-8
2
+
3
+ require_relative 'constants'
4
+ require_relative 'page_links'
5
+ require_relative 'page_iterator'
6
+
7
+ module Github
8
+ # A module that decorates response with pagination helpers
9
+ module Pagination
10
+ include Github::Constants
11
+
12
+ # Return page links
13
+ def links
14
+ @links = Github::PageLinks.new(env[:response_headers])
15
+ end
16
+
17
+ # Retrieve number of total pages base on current :per_page parameter
18
+ def count_pages
19
+ page_iterator.count.to_i
20
+ end
21
+
22
+ # Iterate over results set pages by automatically calling `next_page`
23
+ # until all pages are exhausted. Caution needs to be exercised when
24
+ # using this feature - 100 pages iteration will perform 100 API calls.
25
+ # By default this is off. You can set it on the client, individual API
26
+ # instances or just per given request.
27
+ #
28
+ def auto_paginate(auto=false)
29
+ if (current_api.auto_pagination? || auto) && self.body.is_a?(Array)
30
+ resources_bodies = []
31
+ each_page { |resource| resources_bodies += resource.body }
32
+ self.body = resources_bodies
33
+ end
34
+ self
35
+ end
36
+
37
+ # Iterator like each for response pages. If there are no pages to
38
+ # iterate over this method will return current page.
39
+ def each_page
40
+ yield self
41
+ while page_iterator.next?
42
+ yield next_page
43
+ end
44
+ end
45
+
46
+ # Retrieves the result of the first page. Returns <tt>nil</tt> if there is
47
+ # no first page - either because you are already on the first page
48
+ # or there are no pages at all in the result.
49
+ def first_page
50
+ first_request = page_iterator.first
51
+ self.instance_eval { @env = first_request.env } if first_request
52
+ first_request
53
+ end
54
+
55
+ # Retrieves the result of the next page. Returns <tt>nil</tt> if there is
56
+ # no next page or no pages at all.
57
+ def next_page
58
+ next_request = page_iterator.next
59
+ self.instance_eval { @env = next_request.env } if next_request
60
+ next_request
61
+ end
62
+
63
+ # Retrieves the result of the previous page. Returns <tt>nil</tt> if there is
64
+ # no previous page or no pages at all.
65
+ def prev_page
66
+ prev_request = page_iterator.prev
67
+ self.instance_eval { @env = prev_request.env } if prev_request
68
+ prev_request
69
+ end
70
+ alias :previous_page :prev_page
71
+
72
+ # Retrieves the result of the last page. Returns <tt>nil</tt> if there is
73
+ # no last page - either because you are already on the last page,
74
+ # there is only one page or there are no pages at all in the result.
75
+ def last_page
76
+ last_request = page_iterator.last
77
+ self.instance_eval { @env = last_request.env } if last_request
78
+ last_request
79
+ end
80
+
81
+ # Retrieves a specific result for a page given page number.
82
+ # The <tt>page_number</tt> parameter is not validate, hitting a page
83
+ # that does not exist will return Github API error. Consequently, if
84
+ # there is only one page, this method returns nil
85
+ def page(page_number)
86
+ request = page_iterator.get_page(page_number)
87
+ self.instance_eval { @env = request.env } if request
88
+ request
89
+ end
90
+
91
+ # Returns <tt>true</tt> if there is another page in the result set,
92
+ # otherwise <tt>false</tt>
93
+ def has_next_page?
94
+ page_iterator.next?
95
+ end
96
+
97
+ # Handle pagination params when they are not passed directly
98
+ #
99
+ def self.per_page_as_param(per_page_config)
100
+ params = {}
101
+ if (per_page_config != Github::Configuration.property_set[:per_page])
102
+ params[:per_page] = per_page_config unless per_page_config.nil?
103
+ end
104
+ params
105
+ end
106
+
107
+ private
108
+
109
+ # Internally used page iterator
110
+ def page_iterator # :nodoc:
111
+ @page_iterator = Github::PageIterator.new(links, current_api)
112
+ end
113
+
114
+ end # Pagination
115
+ end # Github
@@ -0,0 +1,35 @@
1
+ # encoding: utf-8
2
+
3
+ require_relative 'params_hash'
4
+ require_relative 'validations'
5
+
6
+ module Github
7
+ # Allows you to specify parameters keys which will be preserved
8
+ # in parameters hash and its subhashes. Any keys from the nested
9
+ # hash that do not match will be removed.
10
+ module ParameterFilter
11
+
12
+ # Removes any keys from nested hashes that don't match predefiend keys
13
+ #
14
+ def filter!(keys, params, options={:recursive => true}) # :nodoc:
15
+ case params
16
+ when Hash, ParamsHash
17
+ params.keys.each do |k, v|
18
+ unless (keys.include?(k) or Github::Validations::VALID_API_KEYS.include?(k))
19
+ params.delete(k)
20
+ else
21
+ filter!(keys, params[k]) if options[:recursive]
22
+ end
23
+ end
24
+ when Array
25
+ params.map! do |el|
26
+ filter!(keys, el) if options[:recursive]
27
+ end
28
+ else
29
+ params
30
+ end
31
+ return params
32
+ end
33
+
34
+ end # Filter
35
+ end # Github
@@ -0,0 +1,115 @@
1
+ # encoding: utf-8
2
+
3
+ require 'delegate'
4
+ require 'base64'
5
+
6
+ require_relative 'normalizer'
7
+ require_relative 'mime_type'
8
+
9
+ module Github
10
+ # Class responsible for holding request parameters
11
+ class ParamsHash < DelegateClass(Hash)
12
+ include Normalizer
13
+ include MimeType
14
+
15
+ REQUEST_PARAMS = [:accept, :media, :data, :raw, :headers]
16
+
17
+ def initialize(hash)
18
+ super(normalize!(Hash[hash]))
19
+ end
20
+
21
+ # Create empty hash
22
+ #
23
+ # @api public
24
+ def self.empty
25
+ new({})
26
+ end
27
+
28
+ # Extract and parse media type param
29
+ #
30
+ # [.version].param[+json]
31
+ #
32
+ # @api public
33
+ def media
34
+ parse(delete('media'))
35
+ end
36
+
37
+ # Get accept header
38
+ #
39
+ # @api public
40
+ def accept
41
+ if key?('accept') then self['accept']
42
+ elsif key?('media') then media
43
+ else nil
44
+ end
45
+ end
46
+
47
+ # Extract request data from parameters
48
+ #
49
+ # @api public
50
+ def data
51
+ if key?('data') && !self['data'].nil?
52
+ self['data']
53
+ else
54
+ request_params
55
+ end
56
+ end
57
+
58
+ def encoder
59
+ if key?('encoder') && self['encoder']
60
+ self['encoder']
61
+ else
62
+ {}
63
+ end
64
+ end
65
+
66
+ # Configuration options from request
67
+ #
68
+ # @return [Hash]
69
+ #
70
+ # @api public
71
+ def options
72
+ opts = fetch('options', {})
73
+ headers = fetch('headers', {})
74
+ if value = accept
75
+ headers[:accept] = value
76
+ end
77
+ opts[:raw] = key?('raw') ? self['raw'] : false
78
+ opts[:headers] = headers unless headers.empty?
79
+ opts
80
+ end
81
+
82
+ # Update hash with default parameters for non existing keys
83
+ #
84
+ def merge_default(defaults)
85
+ if defaults && !defaults.empty?
86
+ defaults.each do |key, value|
87
+ self[key] = value unless self.key?(key)
88
+ end
89
+ end
90
+ self
91
+ end
92
+
93
+ # Base64 encode string removing newline characters
94
+ #
95
+ # @api public
96
+ def strict_encode64(key)
97
+ value = self[key]
98
+ encoded = if Base64.respond_to?(:strict_encode64)
99
+ Base64.strict_encode64(value)
100
+ else
101
+ [value].pack('m0')
102
+ end
103
+ self[key] = encoded.delete("\n\r")
104
+ end
105
+
106
+ # Filter out request params
107
+ #
108
+ # @api public
109
+ def request_params
110
+ to_hash.select do |key, value|
111
+ !REQUEST_PARAMS.include?(key.to_sym)
112
+ end
113
+ end
114
+ end # ParamsHash
115
+ end # Github
@@ -0,0 +1,25 @@
1
+ # encoding: utf-8
2
+
3
+ module Github
4
+ module RateLimit
5
+
6
+ def ratelimit(*args)
7
+ arguments(args)
8
+
9
+ get_request("/rate_limit", arguments.params).rate.limit
10
+ end
11
+
12
+ def ratelimit_remaining(*args)
13
+ arguments(args)
14
+
15
+ get_request("/rate_limit", arguments.params).rate.remaining
16
+ end
17
+
18
+ def ratelimit_reset(*args)
19
+ arguments(args)
20
+
21
+ get_request("/rate_limit", arguments.params).rate.reset
22
+ end
23
+
24
+ end # RateLimit
25
+ end # Github
@@ -0,0 +1,36 @@
1
+ # encoding: utf-8
2
+
3
+ require 'faraday'
4
+ require 'base64'
5
+
6
+ module Github
7
+ class Request
8
+ class BasicAuth < Faraday::Middleware
9
+ # dependency 'base64'
10
+
11
+ # @api private
12
+ def initialize(app, *args)
13
+ @app = app
14
+ @auth = nil
15
+ options = args.extract_options!
16
+
17
+ if options.key?(:login) && !options[:login].nil?
18
+ credentials = "#{options[:login]}:#{options[:password]}"
19
+ @auth = Base64.encode64(credentials)
20
+ @auth.gsub!("\n", "")
21
+ end
22
+ end
23
+
24
+ # Update request headers
25
+ #
26
+ # @api private
27
+ def call(env)
28
+ if @auth
29
+ env[:request_headers].merge!('Authorization' => "Basic #{@auth}")
30
+ end
31
+
32
+ @app.call(env)
33
+ end
34
+ end # BasicAuth
35
+ end # Request
36
+ end # Github