tlaw 0.0.1 → 0.0.2

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: 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