dialers 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +10 -0
- data/.rbenv-vars-example +4 -0
- data/.rspec +5 -0
- data/.rubocop.yml +89 -0
- data/.travis.yml +4 -0
- data/Gemfile +4 -0
- data/Guardfile +16 -0
- data/LICENSE.txt +21 -0
- data/NOTES.md +60 -0
- data/README.md +143 -0
- data/Rakefile +1 -0
- data/bin/_guard-core +16 -0
- data/bin/console +7 -0
- data/bin/guard +16 -0
- data/bin/rspec +16 -0
- data/bin/setup +7 -0
- data/dialers.gemspec +37 -0
- data/examples/github/api.rb +19 -0
- data/examples/github/api_caller.rb +27 -0
- data/examples/github/usage.rb +12 -0
- data/examples/twitter/api.rb +27 -0
- data/examples/twitter/api_caller.rb +43 -0
- data/examples/twitter/usage.rb +16 -0
- data/lib/dialers.rb +13 -0
- data/lib/dialers/assign_attributes.rb +20 -0
- data/lib/dialers/caller.rb +128 -0
- data/lib/dialers/errors.rb +77 -0
- data/lib/dialers/request_options.rb +5 -0
- data/lib/dialers/short_circuit.rb +18 -0
- data/lib/dialers/short_circuits_collection.rb +27 -0
- data/lib/dialers/status.rb +82 -0
- data/lib/dialers/transformable.rb +84 -0
- data/lib/dialers/version.rb +3 -0
- data/lib/dialers/wrapper.rb +34 -0
- metadata +260 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 3978ac1bde74537904eb9303ca9110fb6d602527
|
4
|
+
data.tar.gz: d3d1ab7abdddaee79b6f3fd6c81b2969d886c412
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 27e135965acf52401317d38637ec87e08d82fd1afdd825f497cd9e0c63c64572566a00aa29929975167fca8eaba0cdf7081b4399ce5d30a8f5c46e45d4900f60
|
7
|
+
data.tar.gz: 97446946876217282580984376a6fa36d71c09e31999fa0ffd18ed061021e948d490e0de54563ff78b98b12a9f229f0f884fe1068a7938165535422dbd6f662c
|
data/.gitignore
ADDED
data/.rbenv-vars-example
ADDED
data/.rspec
ADDED
data/.rubocop.yml
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
AllCops:
|
2
|
+
Exclude:
|
3
|
+
- bin/**/*
|
4
|
+
- tmp/**/*
|
5
|
+
|
6
|
+
Documentation:
|
7
|
+
Enabled: false
|
8
|
+
|
9
|
+
Style/StringLiterals:
|
10
|
+
EnforcedStyle: double_quotes
|
11
|
+
|
12
|
+
Style/HashSyntax:
|
13
|
+
EnforcedStyle: ruby19
|
14
|
+
UseHashRocketsWithSymbolValues: true
|
15
|
+
|
16
|
+
Style/ClassAndModuleChildren:
|
17
|
+
Enabled: false
|
18
|
+
|
19
|
+
Style/AccessorMethodName:
|
20
|
+
Enabled: false
|
21
|
+
|
22
|
+
Style/GuardClause:
|
23
|
+
Enabled: false
|
24
|
+
|
25
|
+
Style/IfUnlessModifier:
|
26
|
+
Enabled: false
|
27
|
+
|
28
|
+
Style/NegatedIf:
|
29
|
+
Enabled: false
|
30
|
+
|
31
|
+
Style/AlignParameters:
|
32
|
+
EnforcedStyle: with_fixed_indentation
|
33
|
+
|
34
|
+
Style/Lambda:
|
35
|
+
Enabled: false
|
36
|
+
|
37
|
+
Style/BracesAroundHashParameters:
|
38
|
+
Enabled: false
|
39
|
+
|
40
|
+
Style/PredicateName:
|
41
|
+
NamePrefixBlacklist: []
|
42
|
+
|
43
|
+
Style/ClassAndModuleCamelCase:
|
44
|
+
Enabled: false
|
45
|
+
|
46
|
+
Style/GlobalVars:
|
47
|
+
Enabled: false
|
48
|
+
|
49
|
+
Style/WordArray:
|
50
|
+
Enabled: false
|
51
|
+
|
52
|
+
Style/AsciiComments:
|
53
|
+
Enabled: false
|
54
|
+
|
55
|
+
Style/MultilineBlockChain:
|
56
|
+
Enabled: false
|
57
|
+
|
58
|
+
Style/EachWithObject:
|
59
|
+
Enabled: false
|
60
|
+
|
61
|
+
Style/MultilineBlockLayout:
|
62
|
+
Enabled: false
|
63
|
+
|
64
|
+
Style/SpaceAroundBlockParameters:
|
65
|
+
Enabled: false
|
66
|
+
|
67
|
+
Style/BlockComments:
|
68
|
+
Enabled: false
|
69
|
+
|
70
|
+
Style/ModuleFunction:
|
71
|
+
Enabled: false
|
72
|
+
|
73
|
+
Style/RaiseArgs:
|
74
|
+
EnforcedStyle: compact
|
75
|
+
|
76
|
+
Lint/AmbiguousOperator:
|
77
|
+
Enabled: false
|
78
|
+
|
79
|
+
Lint/EndAlignment:
|
80
|
+
AlignWith: "variable"
|
81
|
+
|
82
|
+
Metrics/LineLength:
|
83
|
+
Max: 100
|
84
|
+
|
85
|
+
Metrics/AbcSize:
|
86
|
+
Enabled: False
|
87
|
+
|
88
|
+
Metrics/ClassLength:
|
89
|
+
Max: 100
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/Guardfile
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
guard :rspec, cmd: "bin/rspec" do
|
2
|
+
require "guard/rspec/dsl"
|
3
|
+
dsl = Guard::RSpec::Dsl.new(self)
|
4
|
+
|
5
|
+
# Feel free to open issues for suggestions and improvements
|
6
|
+
|
7
|
+
# RSpec files
|
8
|
+
rspec = dsl.rspec
|
9
|
+
watch(rspec.spec_helper) { rspec.spec_dir }
|
10
|
+
watch(rspec.spec_support) { rspec.spec_dir }
|
11
|
+
watch(rspec.spec_files)
|
12
|
+
|
13
|
+
# Ruby files
|
14
|
+
ruby = dsl.ruby
|
15
|
+
dsl.watch_spec_files_for(ruby.lib_files)
|
16
|
+
end
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2015 juliogarciag
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/NOTES.md
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
1. Example with Twitter
|
2
|
+
|
3
|
+
```ruby
|
4
|
+
# This example requires the gem simple_oauth
|
5
|
+
module Twitter
|
6
|
+
class ApiCaller < Dialers::Caller
|
7
|
+
BASE_URL = "https://api.twitter.com/1.1/"
|
8
|
+
CONSUMER_KEY = ENV["TWITTER_CONSUMER_KEY"]
|
9
|
+
CONSUMER_SECRET = ENV["TWITTER_CONSUMER_SECRET"]
|
10
|
+
TOKEN = ENV["TWITTER_TOKEN"]
|
11
|
+
TOKEN_SECRET= ENV["TWITTER_TOKEN_SECRET"]
|
12
|
+
|
13
|
+
setup_api(url: BASE_URL) do |faraday|
|
14
|
+
faraday.request :json
|
15
|
+
faraday.request :oauth,
|
16
|
+
consumer_key: CONSUMER_KEY,
|
17
|
+
consumer_secret: CONSUMER_SECRET,
|
18
|
+
token: TOKEN,
|
19
|
+
token_secret: TOKEN_SECRET
|
20
|
+
faraday.response :json
|
21
|
+
faraday.adapter :net_http
|
22
|
+
end
|
23
|
+
|
24
|
+
short_circuits.add(
|
25
|
+
if: -> (response) { Dialers::Status.new(response.status).server_error? },
|
26
|
+
do: -> (response) { fail Dialers::ServerError.new(response) }
|
27
|
+
)
|
28
|
+
|
29
|
+
short_circuits.push(
|
30
|
+
if: -> (response) { Dialers::Status.new(response.status).is?(401) },
|
31
|
+
do: -> (response) { fail Dialers::UnauthorizedError.new(response) }
|
32
|
+
)
|
33
|
+
|
34
|
+
short_circuits.add(
|
35
|
+
if: -> { |response| Dialers::Status.new(response.status).is?(404) },
|
36
|
+
do: -> { |response| fail Dialers::NotFoundError.new(response) }
|
37
|
+
)
|
38
|
+
end
|
39
|
+
|
40
|
+
class Tweet
|
41
|
+
attr_accessor :created_at, :text
|
42
|
+
end
|
43
|
+
|
44
|
+
class User
|
45
|
+
attr_accessor :screen_name, :profile_image_url
|
46
|
+
end
|
47
|
+
|
48
|
+
class Api < Dialers::Wrapper
|
49
|
+
api_caller { ApiCaller.new }
|
50
|
+
|
51
|
+
def get_user_timeline
|
52
|
+
api_caller.get("statuses/user_timeline.json").transform_to_many(Tweet)
|
53
|
+
end
|
54
|
+
|
55
|
+
def get_user
|
56
|
+
api_caller.get("account/verify_credentials.json").transform_to_one(User)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
```
|
data/README.md
ADDED
@@ -0,0 +1,143 @@
|
|
1
|
+
# Dialers
|
2
|
+
|
3
|
+
Dialers is a gem that allows to easily create wrappers over external HTTP apis using [Faraday](https://github.com/lostisland/faraday).
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem "dialers"
|
11
|
+
```
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Additionally, if you want to use a Faraday adapter different from the default one (`net_http`, based on the built-in ruby library), you have to install the gem for that. For example, to use [patron](https://github.com/toland/patron) you have to add `gem "patron"` to your Gemfile. For simplicity, this readme will use the default `net_http` adapter.
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
We will use the Github API public part as a example. First, you need at least two classes: one to keep your api methods and another one to keep the api connection configuration. Let's start with this:
|
22
|
+
|
23
|
+
```ruby
|
24
|
+
module Github
|
25
|
+
class Api < Dialers::ApiWrapper
|
26
|
+
end
|
27
|
+
|
28
|
+
class ApiCaller < Dialers::Caller
|
29
|
+
end
|
30
|
+
end
|
31
|
+
```
|
32
|
+
|
33
|
+
Now, let's configure our github api. It's important to note that this configuration is the same that Faraday uses (indeed, it's passed to Faraday as it is):
|
34
|
+
|
35
|
+
```ruby
|
36
|
+
module Github
|
37
|
+
class ApiCaller < Dialers::Caller
|
38
|
+
TIMEOUT_IN_SECONDS = 5
|
39
|
+
GITHUB_API_URL = "https://api.github.com"
|
40
|
+
|
41
|
+
setup_api(url: GITHUB_API_URL) do |faraday|
|
42
|
+
faraday.request :json
|
43
|
+
faraday.request :request_headers, accept: "application/vnd.github.v3+json"
|
44
|
+
faraday.response :json
|
45
|
+
faraday.adapter :net_http
|
46
|
+
faraday.options.timeout = TIMEOUT_IN_SECONDS
|
47
|
+
faraday.options.open_timeout = TIMEOUT_IN_SECONDS
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
```
|
52
|
+
|
53
|
+
If you want to know more about how to configure Faraday to some different and more complex use cases, please check the [examples directory](examples/). Now that the configuration is over, let's plug the caller into the wrapper to be able to create some methods.
|
54
|
+
|
55
|
+
```ruby
|
56
|
+
module Github
|
57
|
+
class Api < Dialers::ApiWrapper
|
58
|
+
api_caller { Github::ApiCaller }
|
59
|
+
|
60
|
+
def user_repos(username)
|
61
|
+
api_caller.get("users/#{username}/repos").as_received
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
```
|
66
|
+
|
67
|
+
Let's try this:
|
68
|
+
|
69
|
+
```ruby
|
70
|
+
github = Github::Api.new
|
71
|
+
github.user_repos("rails")
|
72
|
+
# => [ { ... }] # An enormous array of hashes
|
73
|
+
```
|
74
|
+
|
75
|
+
Now, this sucks for us because we don't have any kind of schema nor classes here. Let's add something to organize this response:
|
76
|
+
|
77
|
+
```ruby
|
78
|
+
module Github
|
79
|
+
class Repository
|
80
|
+
attr_accessor :id, :name, :description, :language
|
81
|
+
end
|
82
|
+
|
83
|
+
class Api < Dialers::ApiWrapper
|
84
|
+
api_caller { Github::ApiCaller }
|
85
|
+
|
86
|
+
def user_repos(username)
|
87
|
+
api_caller.get("users/#{username}/repos").transform_to_many(Github::Repository)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
```
|
92
|
+
|
93
|
+
Using `transform_to_many` we mapped the response body to many `Github::Repository` objects. Let's try now:
|
94
|
+
|
95
|
+
```ruby
|
96
|
+
github = Github::Api.new
|
97
|
+
repositories = github.user_repos("rails")
|
98
|
+
repositories.first.name # maybe Rails
|
99
|
+
```
|
100
|
+
|
101
|
+
You can use `post`, `put`, `patch`, `options`, `get` and `head` on the callers. You can use `transform_to_one` to make just one object and you can pass a hash to decide which object to instantiate depending on the response's status. For more info, you can check out [the caller's documentation](http://www.rubydoc.info/github/platanus/dialers/master/Dialers/Caller).
|
102
|
+
|
103
|
+
## Some Rails Nice Things
|
104
|
+
|
105
|
+
***NOTE: This a thing we want to make. It's not done yet but we want it to be this way***
|
106
|
+
|
107
|
+
In Rails, you can use the next command to generate a dialer wrapper:
|
108
|
+
|
109
|
+
```bash
|
110
|
+
$ rails g dialers:api anexternalservice
|
111
|
+
```
|
112
|
+
|
113
|
+
This will generate the following structure:
|
114
|
+
|
115
|
+
```
|
116
|
+
dialers/
|
117
|
+
anexternalservice/
|
118
|
+
api.rb
|
119
|
+
api_caller.rb
|
120
|
+
```
|
121
|
+
|
122
|
+
Everything else is the same. This is just a proposal for a organization friendly to Rails. But, if you want, you can use any class organization you want.
|
123
|
+
|
124
|
+
## Development
|
125
|
+
|
126
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake false` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
127
|
+
|
128
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
129
|
+
|
130
|
+
To run the examples in the examples directory you have to setup some environment variables as defined in `.rbenv-vars-example` and run the examples like this:
|
131
|
+
|
132
|
+
```
|
133
|
+
$ ruby -Ilib examples/github/usage.rb
|
134
|
+
```
|
135
|
+
|
136
|
+
## Contributing
|
137
|
+
|
138
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/platanus/dialers.
|
139
|
+
|
140
|
+
|
141
|
+
## License
|
142
|
+
|
143
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/bin/_guard-core
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# This file was generated by Bundler.
|
4
|
+
#
|
5
|
+
# The application '_guard-core' is installed as part of a gem, and
|
6
|
+
# this file is here to facilitate running it.
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'pathname'
|
10
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
|
11
|
+
Pathname.new(__FILE__).realpath)
|
12
|
+
|
13
|
+
require 'rubygems'
|
14
|
+
require 'bundler/setup'
|
15
|
+
|
16
|
+
load Gem.bin_path('guard', '_guard-core')
|
data/bin/console
ADDED
data/bin/guard
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# This file was generated by Bundler.
|
4
|
+
#
|
5
|
+
# The application 'guard' is installed as part of a gem, and
|
6
|
+
# this file is here to facilitate running it.
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'pathname'
|
10
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
|
11
|
+
Pathname.new(__FILE__).realpath)
|
12
|
+
|
13
|
+
require 'rubygems'
|
14
|
+
require 'bundler/setup'
|
15
|
+
|
16
|
+
load Gem.bin_path('guard', 'guard')
|
data/bin/rspec
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# This file was generated by Bundler.
|
4
|
+
#
|
5
|
+
# The application 'rspec' is installed as part of a gem, and
|
6
|
+
# this file is here to facilitate running it.
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'pathname'
|
10
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
|
11
|
+
Pathname.new(__FILE__).realpath)
|
12
|
+
|
13
|
+
require 'rubygems'
|
14
|
+
require 'bundler/setup'
|
15
|
+
|
16
|
+
load Gem.bin_path('rspec-core', 'rspec')
|