yt-support 0.1.0 → 0.1.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 320897c435303a2e12b6889a59b0258dd249b4ef
4
- data.tar.gz: d96402625a05ab1e621d98b94a6e7810253a0a92
3
+ metadata.gz: 52850660c93460a274efca68349e3b6a1cdaf53c
4
+ data.tar.gz: bd1b2f4d5a3e4c0005dfd2d15ad5b8508c49f33e
5
5
  SHA512:
6
- metadata.gz: a848182a029379a5c58640a1c7bdeae13f15fda93db35378ff1af40df4540bfa3089f089b09e9ae91dc6e2eb8422432b6376cd8ae76734f659984db36caa86c7
7
- data.tar.gz: c47d0461dac76678f894ccb80d6a34f63af935f5206a12a35b23f90b850291bbf5e263af46e482287ba69f0a468a8448fa80c71ddb3aa78cef326dd536435b4a
6
+ metadata.gz: 0b804979d3bd2d49ef3841e5a0c43f1d692d634b38ef348409396c642257062eaf9cb76db6f0aa107807f9736e532713be08fc4a509978295add768c0490bcf5
7
+ data.tar.gz: 612a312b478a97225a0b35508fd2f4f40f7e52745f6f1b8bc44c7d6e3e49ea3380d9ec9f2eb65b1d72b5531a73f0e39f719ef971d12235e9247d8f13635b9254
@@ -6,6 +6,10 @@ For more information about changelogs, check
6
6
  [Keep a Changelog](http://keepachangelog.com) and
7
7
  [Vandamme](http://tech-angels.github.io/vandamme).
8
8
 
9
+ ## 0.1.1 - 2017-03-29
10
+
11
+ * [FEATURE] Extracted Yt::HTTPRequest and Yt::HTTPError from Yt::Auth
12
+
9
13
  ## 0.1.0 - 2017-03-17
10
14
 
11
15
  * [FEATURE] Extracted Yt::Config and Yt::Configuration from Yt
data/README.md CHANGED
@@ -7,9 +7,9 @@ It is considered suitable for internal use only at this time.
7
7
  The **source code** is available on [GitHub](https://github.com/fullscreen/yt-support) and the **documentation** on [RubyDoc](http://www.rubydoc.info/gems/yt-support/frames).
8
8
 
9
9
  [![Build Status](http://img.shields.io/travis/Fullscreen/yt-support/master.svg)](https://travis-ci.org/Fullscreen/yt-support)
10
- [![Coverage Status](http://img.shields.io/coveralls/fullscreen/yt-support/master.svg)](https://coveralls.io/r/Fullscreen/yt-support)
11
- [![Dependency Status](http://img.shields.io/gemnasium/fullscreen/yt-support.svg)](https://gemnasium.com/Fullscreen/yt-support)
12
- [![Code Climate](http://img.shields.io/codeclimate/github/fullscreen/yt-support.svg)](https://codeclimate.com/github/Fullscreen/yt-support)
10
+ [![Coverage Status](http://img.shields.io/coveralls/Fullscreen/yt-support/master.svg)](https://coveralls.io/r/Fullscreen/yt-support)
11
+ [![Dependency Status](http://img.shields.io/gemnasium/Fullscreen/yt-support.svg)](https://gemnasium.com/Fullscreen/yt-support)
12
+ [![Code Climate](http://img.shields.io/codeclimate/github/Fullscreen/yt-support.svg)](https://codeclimate.com/github/Fullscreen/yt-support)
13
13
  [![Online docs](http://img.shields.io/badge/docs-✓-green.svg)](http://www.rubydoc.info/gems/yt-support/frames)
14
14
  [![Gem Version](http://img.shields.io/gem/v/yt-support.svg)](http://rubygems.org/gems/yt-support)
15
15
 
@@ -17,6 +17,8 @@ Yt::Support provides:
17
17
 
18
18
  * [Yt.configure](http://www.rubydoc.info/gems/yt-support/Yt/Config#configure-instance_method)
19
19
  * [Yt::Configuration](http://www.rubydoc.info/gems/yt-support/Yt/Configuration)
20
+ * [Yt::HTTPRequest](http://www.rubydoc.info/gems/yt-support/Yt/HTTPRequest)
21
+ * [Yt::HTTPError](http://www.rubydoc.info/gems/yt-support/Yt/HTTPError)
20
22
 
21
23
  How to contribute
22
24
  =================
@@ -0,0 +1,5 @@
1
+ module Yt
2
+ # A wrapper around StandardError.
3
+ class HTTPError < StandardError
4
+ end
5
+ end
@@ -0,0 +1,128 @@
1
+ require 'net/http'
2
+ require 'json'
3
+ require 'yt/http_error'
4
+
5
+ module Yt
6
+ # A wrapper around +Net::HTTP+ to send HTTP requests to any web API and
7
+ # return their result or raise an error if the result is unexpected.
8
+ # The basic way to use Request is by calling +run+ on an instance.
9
+ # @example List the most popular videos on YouTube.
10
+ # host = ''www.googleapis.com'
11
+ # path = '/youtube/v3/videos'
12
+ # params = {chart: 'mostPopular', key: ENV['API_KEY'], part: 'snippet'}
13
+ # response = Yt::Request.new(path: path, params: params).run
14
+ # response.body['items'].map{|video| video['snippet']['title']}
15
+ # @api private
16
+ class HTTPRequest
17
+ # Initializes a Request object.
18
+ # @param [Hash] options the options for the request.
19
+ # @option options [Symbol] :method (:get) The HTTP method to use.
20
+ # @option options [String] :host The host of the request URI.
21
+ # @option options [String] :path The path of the request URI.
22
+ # @option options [Hash] :params ({}) The params to use as the query
23
+ # component of the request URI, for instance the Hash +{a: 1, b: 2}+
24
+ # corresponds to the query parameters +"a=1&b=2"+.
25
+ # @option options [Hash] :headers ({}) The headers of the request.
26
+ # @option options [#size] :body The body of the request.
27
+ # @option options [Hash] :request_format (:json) The format of the
28
+ # requesty body. If a request body is passed, it will be parsed
29
+ # according to this format before sending it in the request.
30
+ # @option options [Proc] :error_message The block that will be invoked
31
+ # when a request fails.
32
+ def initialize(options = {})
33
+ @method = options.fetch :method, :get
34
+ @host = options.fetch :host, 'www.googleapis.com'
35
+ @path = options[:path]
36
+ @params = options.fetch :params, {}
37
+ @headers = options.fetch :headers, {}
38
+ @body = options[:body]
39
+ @request_format = options.fetch :request_format, :json
40
+ @error_message = options.fetch :error_message, ->(body) {"Error: #{body}"}
41
+ end
42
+
43
+ # Sends the request and returns the response with the body parsed from JSON.
44
+ # @return [Net::HTTPResponse] if the request succeeds.
45
+ # @raise [Yt::HTTPError] if the request fails.
46
+ def run
47
+ if response.is_a? Net::HTTPSuccess
48
+ response.tap do
49
+ parse_response!
50
+ end
51
+ else
52
+ raise Yt::HTTPError, error_message
53
+ end
54
+ end
55
+
56
+ private
57
+
58
+ # @return [URI::HTTPS] the (memoized) URI of the request.
59
+ def uri
60
+ attributes = {host: @host, path: @path, query: URI.encode_www_form(query)}
61
+ @uri ||= URI::HTTPS.build attributes
62
+ end
63
+
64
+ # Equivalent to @params.transform_keys{|key| key.to_s.camelize :lower}
65
+ def query
66
+ {}.tap do |camel_case_params|
67
+ @params.each_key do |key|
68
+ camel_case_params[camelize key] = @params[key]
69
+ end
70
+ end
71
+ end
72
+
73
+ def camelize(part)
74
+ part.to_s.gsub(/(?:_|(\/))([a-z\d]*)/i) { "#{$1}#{$2.capitalize}" }
75
+ end
76
+
77
+ # @return [Net::HTTPRequest] the full HTTP request object,
78
+ # inclusive of headers of request body.
79
+ def http_request
80
+ net_http_class = Object.const_get "Net::HTTP::#{@method.capitalize}"
81
+ @http_request ||= net_http_class.new(uri.request_uri).tap do |request|
82
+ set_request_body! request
83
+ set_request_headers! request
84
+ end
85
+ end
86
+
87
+ # Adds the request body to the request in the appropriate format.
88
+ # if the request body is a JSON Object, transform its keys into camel-case,
89
+ # since this is the common format for JSON APIs.
90
+ def set_request_body!(request)
91
+ if @body
92
+ request.set_form_data @body
93
+ end
94
+ end
95
+
96
+ # Adds the request headers to the request in the appropriate format.
97
+ # The User-Agent header is also set to recognize the request, and to
98
+ # tell the server that gzip compression can be used, since Net::HTTP
99
+ # supports it and automatically sets the Accept-Encoding header.
100
+ def set_request_headers!(request)
101
+ if @request_format == :json
102
+ request.initialize_http_header 'Content-Type' => 'application/json'
103
+ end
104
+ @headers.each do |name, value|
105
+ request.add_field name, value
106
+ end
107
+ end
108
+
109
+ # Run the request and memoize the response or the server error received.
110
+ def response
111
+ @response ||= Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
112
+ http.request http_request
113
+ end
114
+ end
115
+
116
+ # Replaces the body of the response with the parsed version of the body,
117
+ # according to the format specified in the HTTPRequest.
118
+ def parse_response!
119
+ if response.body
120
+ response.body = JSON response.body
121
+ end
122
+ end
123
+
124
+ def error_message
125
+ @error_message.call response.body
126
+ end
127
+ end
128
+ end
@@ -1 +1,2 @@
1
1
  require 'yt/config'
2
+ require 'yt/http_request'
@@ -2,6 +2,6 @@ module Yt
2
2
  # Provides common functionality to all Yt gems.
3
3
  module Support
4
4
  # current version of gem
5
- VERSION = '0.1.0'
5
+ VERSION = '0.1.1'
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: yt-support
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Claudio Baccigalupo
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2017-03-17 00:00:00.000000000 Z
12
+ date: 2017-03-29 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -117,6 +117,8 @@ files:
117
117
  - bin/setup
118
118
  - lib/yt/config.rb
119
119
  - lib/yt/configuration.rb
120
+ - lib/yt/http_error.rb
121
+ - lib/yt/http_request.rb
120
122
  - lib/yt/support.rb
121
123
  - lib/yt/support/version.rb
122
124
  - yt-support.gemspec