tlaw 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6d841ff577a627eeecb9897b2cf4a20778eef17c
4
- data.tar.gz: f52b898df817a0982b98d05000dc71f1e35cabb4
3
+ metadata.gz: 37f3ec860edbe2fac8ea3e85b3e0d2d75392ee15
4
+ data.tar.gz: b11a83253074b9dfb89c650bd46b155359f4b3f9
5
5
  SHA512:
6
- metadata.gz: bbcbe2d3adbb328867b018d5664e2027191be9c47763ce8295bad2391a0ba9011af89fa073d920d016dc0f0ddf7f9c3fe60e1436458a88596658a6de93f6d28f
7
- data.tar.gz: 63e85a71614104dff15bde2f9e188a16c8e72aadf3c037eeae06699e7ec9af612be73a2d5c1250fabccc31f8f1d159aa8f6ae1297cea13a04910c51868deb586
6
+ metadata.gz: e2ad59fcbebd0f0302dbda95365c6c46f15baf8b9333a0bd78c7720540f62785909d6fb3baa07581dd1a504a70527ec047713150c79239ffdcc7566bfa2ba2a1
7
+ data.tar.gz: e4cddec1d3e1074001a71dfd6a3858c7afdc57e11f5129ce35fd99d91d8635102b381c4f33b56edd53a974393c792bbbe1f357cd992b484877c0a84c39348039
@@ -0,0 +1,7 @@
1
+ # This configuration was generated by
2
+ # `rubocop --auto-gen-config`
3
+ # on 2017-07-29 18:05:32 +0300 using RuboCop version 0.49.1.
4
+ # The point is for the user to remove these configuration records
5
+ # one by one as the offenses are removed from the code base.
6
+ # Note that changes in the inspected code, or installation of new
7
+ # versions of RuboCop, may require this file to be generated again.
@@ -0,0 +1,11 @@
1
+ # The Last API Wrapper Changelog
2
+
3
+ # 0.0.2 (2017-07-31)
4
+
5
+ * Codebase modernized and rubocopped;
6
+ * Support for redirects;
7
+ * Support for pattern-based (regexp) postprocessors.
8
+
9
+ # 0.0.1 (2016-09-19)
10
+
11
+ Initial release.
data/README.md CHANGED
@@ -74,49 +74,51 @@ which produces solid, fast and reliable wrappers.
74
74
 
75
75
  ```ruby
76
76
  class Example < TLAW::API
77
- base 'http://api.example.com'
77
+ define do
78
+ base 'http://api.example.com'
78
79
 
79
- param :api_key, required: true # this would be necessary for API instance creation
80
- # So, the API instance would be e = Example.new(api_key: '123')
81
- # ...and parameter ?api_key=123 would be added to any request
80
+ param :api_key, required: true # this would be necessary for API instance creation
81
+ # So, the API instance would be e = Example.new(api_key: '123')
82
+ # ...and parameter ?api_key=123 would be added to any request
82
83
 
83
- endpoint :foo # The simplest endpoint, will query "http://api.example.com/foo"
84
- # And then you just do e.foo and obtain result
84
+ endpoint :foo # The simplest endpoint, will query "http://api.example.com/foo"
85
+ # And then you just do e.foo and obtain result
85
86
 
86
- endpoint :bar, '/baz.json' # Path to query rewritten, will query "http://api.example.com/baz.json"
87
- # Method is still e.bar, though.
87
+ endpoint :bar, '/baz.json' # Path to query rewritten, will query "http://api.example.com/baz.json"
88
+ # Method is still e.bar, though.
88
89
 
89
- # Now, for params definition:
90
- endpont :movie do
91
- param :id
92
- end
93
- # Method call would be movie(id: '123')
94
- # Generated URL would be "http://api.example.com/movie?id=123"
95
-
96
- # When param is part of the path, you can use RFC 6570
97
- # URL template standard:
98
- endpoint :movie, '/movies/{id}'
99
- # That would generate method which is called like movie('123')
100
- # ...and call to "http://api.example.com/movies/123"
101
-
102
- # Now, we can stack endpoints in namespaces
103
- namespace :foo do # adds /foo to path
104
- namespace :bar, '/baz' do # optional path parameter works
105
- endpoint :blah # URL for call would be "http://api.example.com/foo/baz/blah"
106
- # And method call would be like e.foo.bar.blah(parameters)
90
+ # Now, for params definition:
91
+ endpont :movie do
92
+ param :id
93
+ end
94
+ # Method call would be movie(id: '123')
95
+ # Generated URL would be "http://api.example.com/movie?id=123"
96
+
97
+ # When param is part of the path, you can use RFC 6570
98
+ # URL template standard:
99
+ endpoint :movie, '/movies/{id}'
100
+ # That would generate method which is called like movie('123')
101
+ # ...and call to "http://api.example.com/movies/123"
102
+
103
+ # Now, we can stack endpoints in namespaces
104
+ namespace :foo do # adds /foo to path
105
+ namespace :bar, '/baz' do # optional path parameter works
106
+ endpoint :blah # URL for call would be "http://api.example.com/foo/baz/blah"
107
+ # And method call would be like e.foo.bar.blah(parameters)
108
+ end
109
+
110
+ # URL normalization works, so you can stack in namespaces even
111
+ # things not related to them in source API, "redesigning" API on
112
+ # the fly.
113
+ endpoint :books, '/../books.json' # Real URL would be "http://api.example.com/books"
114
+ # Yet method call is still namespaced like e.foo.books
107
115
  end
108
116
 
109
- # URL normalization works, so you can stack in namespaces even
110
- # things not related to them in source API, "redesigning" API on
111
- # the fly.
112
- endpoint :books, '/../books.json' # Real URL would be "http://api.example.com/books"
113
- # Yet method call is still namespaced like e.foo.books
114
- end
115
-
116
- # Namespaces can have their own input parameters
117
- namespace :foo, '/foo/{id}' do
118
- endpoint :bar # URL would be "http://api.example.com/foo/123/bar
119
- # method call would be e.foo(123).bar
117
+ # Namespaces can have their own input parameters
118
+ namespace :foo, '/foo/{id}' do
119
+ endpoint :bar # URL would be "http://api.example.com/foo/123/bar
120
+ # method call would be e.foo(123).bar
121
+ end
120
122
  end
121
123
 
122
124
  # ...and everything works in all possible and useful ways, just check
@@ -149,9 +151,9 @@ Source API responds like:
149
151
  "meta": {
150
152
  "code": "OK",
151
153
  },
152
- "weahter": {
154
+ "weather": {
153
155
  "temp": 10,
154
- "precipation": 138
156
+ "precipitation": 138
155
157
  },
156
158
  "location": {
157
159
  "lat": 123,
@@ -167,8 +169,8 @@ this way:
167
169
  ```json
168
170
  {
169
171
  "meta.code": "OK",
170
- "weahter.temp": 10,
171
- "weahter.precipation": 138,
172
+ "weather.temp": 10,
173
+ "weather.precipitation": 138,
172
174
  "location.lat": 123,
173
175
  "location.lon": 456
174
176
  ...
@@ -58,6 +58,48 @@ weather = TLAW::Examples::ForecastIO
58
58
  .new(api_key: ENV['FORECAST_IO'], units: :si)
59
59
 
60
60
  res = weather.forecast(40.7127, -74.0059, extended_hourly: true)
61
+ pp res
62
+ # {"latitude"=>40.7127,
63
+ # "longitude"=>-74.0059,
64
+ # "timezone"=>"America/New_York",
65
+ # "offset"=>-5,
66
+ # "currently.time"=>2017-02-23 19:06:50 +0200,
67
+ # "currently.summary"=>"Overcast",
68
+ # "currently.icon"=>"cloudy",
69
+ # "currently.nearestStormDistance"=>362,
70
+ # "currently.nearestStormBearing"=>179,
71
+ # "currently.precipIntensity"=>0,
72
+ # "currently.precipProbability"=>0,
73
+ # "currently.temperature"=>12.57,
74
+ # "currently.apparentTemperature"=>12.57,
75
+ # "currently.dewPoint"=>10.42,
76
+ # "currently.humidity"=>0.87,
77
+ # "currently.windSpeed"=>2.03,
78
+ # "currently.windBearing"=>188,
79
+ # "currently.visibility"=>9.69,
80
+ # "currently.cloudCover"=>0.95,
81
+ # "currently.pressure"=>1012.11,
82
+ # "currently.ozone"=>330.56,
83
+ # "minutely.summary"=>"Overcast for the hour.",
84
+ # "minutely.icon"=>"cloudy",
85
+ # "minutely.data"=>
86
+ # #<TLAW::DataTable[time, precipIntensity, precipProbability] x 61>,
87
+ # "hourly.summary"=>"Light rain starting this evening.",
88
+ # "hourly.icon"=>"rain",
89
+ # "hourly.data"=>
90
+ # #<TLAW::DataTable[time, summary, icon, precipIntensity, precipProbability, temperature, apparentTemperature, dewPoint, humidity, windSpeed, windBearing, visibility, cloudCover, pressure, ozone, precipType] x 169>,
91
+ # "daily.summary"=>
92
+ # "Light rain throughout the week, with temperatures falling to 12°C on Thursday.",
93
+ # "daily.icon"=>"rain",
94
+ # "daily.data"=>
95
+ # #<TLAW::DataTable[time, summary, icon, sunriseTime, sunsetTime, moonPhase, precipIntensity, precipIntensityMax, precipIntensityMaxTime, precipProbability, precipType, temperatureMin, temperatureMinTime, temperatureMax, temperatureMaxTime, apparentTemperatureMin, apparentTemperatureMinTime, apparentTemperatureMax, apparentTemperatureMaxTime, dewPoint, humidity, windSpeed, windBearing, visibility, cloudCover, pressure, ozone] x 8>,
96
+ # "flags.sources"=> ["darksky", "lamp", "gfs", "cmc", "nam", "rap", "rtma", "sref", "fnmoc", "isd", "madis", "nearest-precip", "nwspa"],
97
+ # "flags.darksky-stations"=>["KDIX", "KOKX"],
98
+ # "flags.lamp-stations"=> ["KBLM", "KCDW", "KEWR", "KFRG", "KHPN", "KJFK", "KLGA", "KMMU", "KNYC", "KSMQ", "KTEB"],
99
+ # "flags.isd-stations"=> ["725020-14734", "725025-94741", "725030-14732", "725033-94728", "725060-99999", "744860-94789", "744976-99999", "997271-99999", "997272-99999", "997743-99999", "999999-14732", "999999-14734", "999999-14786", "999999-94706", "999999-94728", "999999-94741"],
100
+ # "flags.madis-stations"=> ["AU015", "BATN6", "C1099", "C9714", "D0486", "D3216", "D5729", "D9152", "E0405", "E1296", "E2876", "KLGA", "KNYC", "KTEB", "NJ12", "ROBN4"],
101
+ # "flags.units"=>"si"}
102
+
61
103
  pp res['minutely.data'].first
62
104
  # {"time"=>2016-09-12 21:20:00 +0300,
63
105
  # "precipIntensity"=>0,
@@ -0,0 +1,87 @@
1
+ require 'pp'
2
+
3
+ $:.unshift 'lib'
4
+ require 'tlaw'
5
+
6
+
7
+ module TLAW
8
+ module Examples
9
+ class Giphy < TLAW::API
10
+ define do
11
+ desc %Q{
12
+ Wrapper for [Giphy](https://giphy.com/) GIF hosting service API.
13
+ }
14
+
15
+ docs 'https://developers.giphy.com/docs/'
16
+
17
+ base 'http://api.giphy.com/v1'
18
+
19
+ param :api_key, required: true,
20
+ desc: %Q{For development, create it at your [dashboard](https://developers.giphy.com/dashboard/?create=true).
21
+ Note that you'll need to request different key for production use.}
22
+ param :lang,
23
+ desc: %Q{2-letter ISO 639-1 language code.
24
+ [Full list of supported languages](https://developers.giphy.com/docs/)}
25
+
26
+ %i[gifs stickers].each do |ns|
27
+ namespace ns do
28
+ if ns == :gifs
29
+ desc 'Fetch GIPHY GIFs.'
30
+ else
31
+ desc 'Fetch GIPHY stickers (GIFs with transparent background).'
32
+ end
33
+
34
+ endpoint :search do
35
+ desc 'Search all GIFs by word or phrase.'
36
+
37
+ param :query, field: :q, keyword: false, required: true, desc: 'Search string'
38
+ param :limit, :to_i, desc: 'Max number of results to return'
39
+ param :offset, :to_i, desc: 'Results offset'
40
+ param :rating, enum: %w[y g pg pg-13 r unrated nsfw], desc: 'Parental advisory rating'
41
+ end
42
+
43
+ endpoint :trending do
44
+ desc 'Fetch GIFs currently trending online. Hand curated by the GIPHY editorial team.'
45
+
46
+ param :limit, :to_i, desc: 'Max number of results to return'
47
+ param :rating, enum: %w[y g pg pg-13 r unrated nsfw], desc: 'Parental advisory rating'
48
+ end
49
+
50
+ endpoint :translate do
51
+ desc 'Translates phrase to GIFs "vocabulary".'
52
+
53
+ param :phrase, field: :s, keyword: false, required: true, desc: 'Phrase to translate'
54
+
55
+ post_process(/\.(size|mp4_size|webp_size|width|height|frames)/, &:to_i)
56
+ end
57
+
58
+ endpoint :random do
59
+ desc 'Returns a random GIF, optionally limited by tag.'
60
+
61
+ param :tag
62
+ param :rating, desc: 'Parental advisory rating'
63
+ end
64
+
65
+ post_process_items('data') do
66
+ post_process(/\.(size|mp4_size|webp_size|width|height|frames)/, &:to_i)
67
+ end
68
+ end
69
+ end
70
+
71
+ namespace :gifs do
72
+ endpoint :[], '/{id}' do
73
+ desc 'One GIF by unique id.'
74
+
75
+ param :id, required: true
76
+ end
77
+
78
+ endpoint :multiple, '/?ids={ids}' do
79
+ desc 'Sevaral GIFs by unique ids.'
80
+
81
+ param :ids, :to_a, required: true
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,106 @@
1
+ #!/usr/bin/env ruby
2
+ require_relative 'demo_base'
3
+ require_relative 'giphy'
4
+
5
+ giphy = TLAW::Examples::Giphy.new(api_key: ENV['GIPHY'])
6
+
7
+ pp giphy.gifs.search('tardis')
8
+ # => {"data"=>
9
+ # #<TLAW::DataTable[type, id, slug, url, bitly_gif_url, bitly_url, embed_url, username, source, rating, content_url, source_tld, source_post_url, is_indexable, import_datetime, trending_datetime, images.fixed_height_still.url, images.fixed_height_still.width, images.fixed_height_still.height, images.original_still.url, images.original_still.width, images.original_still.height, images.fixed_width.url, images.fixed_width.width, images.fixed_width.height, images.fixed_width.size, images.fixed_width.mp4, images.fixed_width.mp4_size, images.fixed_width.webp, images.fixed_width.webp_size, images.fixed_height_small_still.url, images.fixed_height_small_still.width, images.fixed_height_small_still.height, images.fixed_height_downsampled.url, images.fixed_height_downsampled.width, images.fixed_height_downsampled.height, images.fixed_height_downsampled.size, images.fixed_height_downsampled.webp, images.fixed_height_downsampled.webp_size, images.preview.width, images.preview.height, images.preview.mp4, images.preview.mp4_size, images.fixed_height_small.url, images.fixed_height_small.width, images.fixed_height_small.height, images.fixed_height_small.size, images.fixed_height_small.mp4, images.fixed_height_small.mp4_size, images.fixed_height_small.webp, images.fixed_height_small.webp_size, images.downsized_still.url, images.downsized_still.width, images.downsized_still.height, images.downsized_still.size, images.downsized.url, images.downsized.width, images.downsized.height, images.downsized.size, images.downsized_large.url, images.downsized_large.width, images.downsized_large.height, images.downsized_large.size, images.fixed_width_small_still.url, images.fixed_width_small_still.width, images.fixed_width_small_still.height, images.preview_webp.url, images.preview_webp.width, images.preview_webp.height, images.preview_webp.size, images.fixed_width_still.url, images.fixed_width_still.width, images.fixed_width_still.height, images.fixed_width_small.url, images.fixed_width_small.width, images.fixed_width_small.height, images.fixed_width_small.size, images.fixed_width_small.mp4, images.fixed_width_small.mp4_size, images.fixed_width_small.webp, images.fixed_width_small.webp_size, images.downsized_small.width, images.downsized_small.height, images.downsized_small.mp4, images.downsized_small.mp4_size, images.fixed_width_downsampled.url, images.fixed_width_downsampled.width, images.fixed_width_downsampled.height, images.fixed_width_downsampled.size, images.fixed_width_downsampled.webp, images.fixed_width_downsampled.webp_size, images.downsized_medium.url, images.downsized_medium.width, images.downsized_medium.height, images.downsized_medium.size, images.original.url, images.original.width, images.original.height, images.original.size, images.original.frames, images.original.mp4, images.original.mp4_size, images.original.webp, images.original.webp_size, images.fixed_height.url, images.fixed_height.width, images.fixed_height.height, images.fixed_height.size, images.fixed_height.mp4, images.fixed_height.mp4_size, images.fixed_height.webp, images.fixed_height.webp_size, images.looping.mp4, images.looping.mp4_size, images.original_mp4.width, images.original_mp4.height, images.original_mp4.mp4, images.original_mp4.mp4_size, images.preview_gif.url, images.preview_gif.width, images.preview_gif.height, images.preview_gif.size, user.avatar_url, user.banner_url, user.profile_url, user.username, user.display_name, user.twitter, images.fixed_height_still.size, images.original_still.size, images.fixed_height_small_still.size, images.fixed_width_small_still.size, images.fixed_width_still.size, images.original.hash, images.hd.width, images.hd.height, images.hd.mp4, images.hd.mp4_size, images.480w_still.url, images.480w_still.width, images.480w_still.height, images.480w_still.size] x 25>,
10
+ # "pagination.total_count"=>1559,
11
+ # "pagination.count"=>25,
12
+ # "pagination.offset"=>0,
13
+ # "meta.status"=>200,
14
+ # "meta.msg"=>"OK",
15
+ # "meta.response_id"=>"597d9b7b6b56594f3259f254"}
16
+ #
17
+
18
+ pp giphy.gifs.search('tardis')['data'].first
19
+ # =>
20
+ # {"type"=>"gif",
21
+ # "id"=>"yp2qzMjcEQVB6",
22
+ # "slug"=>"tardis-doctor-who-deer-yp2qzMjcEQVB6",
23
+ # "url"=>"https://giphy.com/gifs/tardis-doctor-who-deer-yp2qzMjcEQVB6",
24
+ # "bitly_gif_url"=>"http://gph.is/XN3l6K",
25
+ # "bitly_url"=>"http://gph.is/XN3l6K",
26
+ # "embed_url"=>"https://giphy.com/embed/yp2qzMjcEQVB6",
27
+ # "username"=>"",
28
+ # "source"=>"http://doctorwhogifs.tumblr.com/post/38804044036",
29
+ # "rating"=>"y",
30
+ # "content_url"=>"",
31
+ # "source_tld"=>"doctorwhogifs.tumblr.com",
32
+ # "source_post_url"=>"http://doctorwhogifs.tumblr.com/post/38804044036",
33
+ # "is_indexable"=>0,
34
+ # "import_datetime"=>"2013-03-21 05:57:22",
35
+ # "trending_datetime"=>"1970-01-01 00:00:00",
36
+ # "images.fixed_height_still.url"=>
37
+ # "https://media0.giphy.com/media/yp2qzMjcEQVB6/200_s.gif",
38
+ # "images.fixed_height_still.width"=>346,
39
+ # "images.fixed_height_still.height"=>200,
40
+ # "images.original_still.url"=>
41
+ # "https://media2.giphy.com/media/yp2qzMjcEQVB6/giphy_s.gif",
42
+ # "images.original_still.width"=>360,
43
+ # "images.original_still.height"=>208,
44
+ # "images.fixed_width.url"=>
45
+ # "https://media1.giphy.com/media/yp2qzMjcEQVB6/200w.gif",
46
+ # "images.fixed_width.width"=>200,
47
+ # "images.fixed_width.height"=>116,
48
+ # "images.fixed_width.size"=>37396,
49
+ # "images.fixed_width.mp4"=>
50
+ # "https://media2.giphy.com/media/yp2qzMjcEQVB6/200w.mp4",
51
+ # "images.fixed_width.mp4_size"=>13349,
52
+ # "images.fixed_width.webp"=>
53
+ # "https://media2.giphy.com/media/yp2qzMjcEQVB6/200w.webp",
54
+ # "images.fixed_width.webp_size"=>61238,
55
+ # ...and so on, there are several types of images
56
+
57
+ # Inspectability:
58
+
59
+ TLAW::Examples::Giphy
60
+ # => #<TLAW::Examples::Giphy: call-sequence: TLAW::Examples::Giphy.new(api_key:, lang: nil); namespaces: gifs, stickers; docs: .describe>
61
+
62
+ giphy
63
+ # => #<TLAW::Examples::Giphy.new(api_key: nil, lang: nil) namespaces: gifs, stickers; docs: .describe>
64
+
65
+ giphy.describe
66
+ # => TLAW::Examples::Giphy.new(api_key: nil, lang: nil)
67
+ # Wrapper for [Giphy](https://giphy.com/) GIF hosting service API.
68
+ #
69
+ # Docs: https://developers.giphy.com/docs/
70
+ #
71
+ # @param api_key For development, create it at your [dashboard](https://developers.giphy.com/dashboard/?create=true).
72
+ # Note that you'll need to request different key for production use.
73
+ # @param lang 2-letter ISO 639-1 language code.
74
+ # [Full list of supported languages](https://developers.giphy.com/docs/)
75
+ #
76
+ # Namespaces:
77
+ #
78
+ # .gifs()
79
+ # Fetch GIPHY GIFs.
80
+ #
81
+ # .stickers()
82
+ # Fetch GIPHY stickers (GIFs with transparent background).
83
+
84
+ giphy.namespaces[:gifs].describe
85
+ # => .gifs()
86
+ # Fetch GIPHY GIFs.
87
+ #
88
+ # Endpoints:
89
+ #
90
+ # .search(query, limit: nil, offset: nil, rating: nil)
91
+ # Search all GIFs by word or phrase.
92
+ #
93
+ # .trending(limit: nil, rating: nil)
94
+ # Fetch GIFs currently trending online. Hand curated by the GIPHY editorial team.
95
+ #
96
+ # .translate(phrase)
97
+ # Translates phrase to GIFs "vocabulary".
98
+ #
99
+ # .random(tag: nil, rating: nil)
100
+ # Returns a random GIF, optionally limited by tag.
101
+ #
102
+ # .[](id)
103
+ # One GIF by unique id.
104
+ #
105
+ # .multiple(ids)
106
+ # Sevaral GIFs by unique ids.
@@ -1,6 +1,7 @@
1
1
  require 'open-uri'
2
2
  require 'json'
3
- require 'addressable'
3
+ require 'addressable/uri'
4
+ require 'addressable/template'
4
5
 
5
6
  # Let no one know! But they in Ruby committee just too long to add
6
7
  # something like this to the language.
@@ -30,7 +30,7 @@ module TLAW
30
30
  end
31
31
 
32
32
  def self.from_rows(column_names, rows)
33
- new rows.map { |r| column_names.zip(r).to_h }
33
+ new(rows.map { |r| column_names.zip(r).to_h })
34
34
  end
35
35
 
36
36
  # Creates DataTable from array of hashes.
@@ -1,4 +1,5 @@
1
1
  require 'faraday'
2
+ require 'faraday_middleware'
2
3
  require 'addressable/template'
3
4
  require 'crack'
4
5
 
@@ -77,7 +78,10 @@ module TLAW
77
78
  def initialize(**parent_params)
78
79
  super
79
80
 
80
- @client = Faraday.new
81
+ @client = Faraday.new do |faraday|
82
+ faraday.use FaradayMiddleware::FollowRedirects
83
+ faraday.adapter Faraday.default_adapter
84
+ end
81
85
  @url_template = self.class.construct_template
82
86
  end
83
87
 
@@ -111,6 +115,7 @@ module TLAW
111
115
  end
112
116
 
113
117
  def guard_errors!(response)
118
+ # TODO: follow redirects
114
119
  return response if (200...400).cover?(response.status)
115
120
 
116
121
  body = JSON.parse(response.body) rescue nil
@@ -23,15 +23,16 @@ module TLAW
23
23
  end
24
24
 
25
25
  def call(hash)
26
- return hash unless hash.is_a?(Hash) && hash.key?(@key)
27
-
28
- hash.merge(@key => @block.call(hash[@key]))
26
+ return hash unless hash.is_a?(Hash)
27
+ hash.keys.grep(@key).inject(hash) do |res, k|
28
+ res.merge(k => @block.call(hash[k]))
29
+ end
29
30
  end
30
31
  end
31
32
 
32
33
  class Replace < Base
33
34
  def call(hash)
34
- hash.derp(&@block)
35
+ @block.call(hash)
35
36
  end
36
37
  end
37
38
 
@@ -42,10 +43,11 @@ module TLAW
42
43
  end
43
44
 
44
45
  def call(hash)
45
- return hash unless hash.key?(@key)
46
- return hash unless hash[@key].is_a?(Array)
47
-
48
- hash.merge(@key => hash[@key].map(&@item_processor))
46
+ return hash unless hash.is_a?(Hash)
47
+ hash.keys.grep(@key).inject(hash) do |res, k|
48
+ next res unless hash[k].is_a?(Array)
49
+ res.merge(k => hash[k].map(&@item_processor))
50
+ end
49
51
  end
50
52
  end
51
53
 
@@ -1,7 +1,7 @@
1
1
  module TLAW
2
2
  MAJOR = 0
3
3
  MINOR = 0
4
- PATCH = 1
4
+ PATCH = 2
5
5
 
6
6
  VERSION = [MAJOR, MINOR, PATCH].join('.')
7
7
  end
@@ -29,6 +29,7 @@ Gem::Specification.new do |s|
29
29
  s.required_ruby_version = '>= 2.1.0'
30
30
 
31
31
  s.add_runtime_dependency 'faraday'
32
+ s.add_runtime_dependency 'faraday_middleware'
32
33
  s.add_runtime_dependency 'addressable'
33
34
  s.add_runtime_dependency 'crack'
34
35
 
@@ -38,6 +39,7 @@ Gem::Specification.new do |s|
38
39
 
39
40
  # Testing
40
41
  s.add_development_dependency 'rubocop', '>= 0.40'
42
+ s.add_development_dependency 'rubocop-rspec'
41
43
  s.add_development_dependency 'rspec', '>= 3.5'
42
44
  s.add_development_dependency 'rspec-its', '~> 1'
43
45
  s.add_development_dependency 'simplecov', '~> 0.9'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tlaw
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Victor Shepelev
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-09-19 00:00:00.000000000 Z
11
+ date: 2017-07-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: faraday_middleware
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: addressable
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -94,6 +108,20 @@ dependencies:
94
108
  - - ">="
95
109
  - !ruby/object:Gem::Version
96
110
  version: '0.40'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rubocop-rspec
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
97
125
  - !ruby/object:Gem::Dependency
98
126
  name: rspec
99
127
  requirement: !ruby/object:Gem::Requirement
@@ -206,20 +234,23 @@ dependencies:
206
234
  - - ">="
207
235
  - !ruby/object:Gem::Version
208
236
  version: '0'
209
- description: |2
210
- And here would be description.
237
+ description: " And here would be description.\n"
211
238
  email: zverok.offline@gmail.com
212
239
  executables: []
213
240
  extensions: []
214
241
  extra_rdoc_files: []
215
242
  files:
216
243
  - ".codeclimate.yml"
244
+ - ".rubocop_todo.yml"
217
245
  - ".yardopts"
246
+ - CHANGELOG.md
218
247
  - LICENSE.txt
219
248
  - README.md
220
249
  - examples/demo_base.rb
221
250
  - examples/forecast_io.rb
222
251
  - examples/forecast_io_demo.rb
252
+ - examples/giphy.rb
253
+ - examples/giphy_demo.rb
223
254
  - examples/open_weather_map.rb
224
255
  - examples/open_weather_map_demo.rb
225
256
  - examples/tmdb_demo.rb
@@ -258,7 +289,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
258
289
  version: '0'
259
290
  requirements: []
260
291
  rubyforge_project:
261
- rubygems_version: 2.4.8
292
+ rubygems_version: 2.6.10
262
293
  signing_key:
263
294
  specification_version: 4
264
295
  summary: Here would be summary