bettery 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (34) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +22 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +3 -0
  5. data/.yardopts +5 -0
  6. data/Gemfile +19 -0
  7. data/LICENSE.txt +22 -0
  8. data/README.md +38 -0
  9. data/Rakefile +6 -0
  10. data/bettery.gemspec +26 -0
  11. data/lib/bettery.rb +28 -0
  12. data/lib/bettery/client.rb +170 -0
  13. data/lib/bettery/client/projects.rb +45 -0
  14. data/lib/bettery/configurable.rb +41 -0
  15. data/lib/bettery/default.rb +92 -0
  16. data/lib/bettery/error.rb +115 -0
  17. data/lib/bettery/project.rb +45 -0
  18. data/lib/bettery/response/raise_error.rb +21 -0
  19. data/lib/bettery/version.rb +3 -0
  20. data/spec/bettery/client/projects_spec.rb +38 -0
  21. data/spec/bettery/client_spec.rb +307 -0
  22. data/spec/bettery/project_spec.rb +51 -0
  23. data/spec/bettery_spec.rb +51 -0
  24. data/spec/cassettes/Bettery_Client/_get/handles_query_params.json +1 -0
  25. data/spec/cassettes/Bettery_Client/_head/handles_query_params.json +1 -0
  26. data/spec/cassettes/Bettery_Client/_last_response/caches_the_last_agent_response.json +1 -0
  27. data/spec/cassettes/Bettery_Client_Projects/_project/returns_the_matching_project.json +1 -0
  28. data/spec/cassettes/Bettery_Client_Projects/_project_/returns_false_if_the_project_doesn_t_exist.json +1 -0
  29. data/spec/cassettes/Bettery_Client_Projects/_project_/returns_true_if_the_project_exists.json +1 -0
  30. data/spec/cassettes/Bettery_Client_Projects/_projects/returns_projects_on_betterplace.json +1 -0
  31. data/spec/spec_helper.rb +84 -0
  32. data/yard/default/fulldoc/html/css/common.css +3 -0
  33. data/yard/default/layout/html/setup.rb +17 -0
  34. metadata +117 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 75102720ef2fe05113049f2116c176b00cd6e985
4
+ data.tar.gz: 958b545b5c80a17962994ab0a19898b2eabbc4df
5
+ SHA512:
6
+ metadata.gz: 2b295918c558ec7645c891118894b40c13a0129142410ad941596e847bc55c8e6f136235c3b6ac0aa97dfd466feb20eabe6a13ebe314d2075ca4949af42893ec
7
+ data.tar.gz: db6bf57dbd99e2b318615e11ab8ad04897f286bcabb53db6e7ac631ca4132d4696f2cc318c544682dbad9dc9046a2f883e8e9f7a2a7168c1feca23153a99fa77
@@ -0,0 +1,22 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *.bundle
19
+ *.so
20
+ *.o
21
+ *.a
22
+ mkmf.log
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
@@ -0,0 +1,3 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1.2
@@ -0,0 +1,5 @@
1
+ --no-private
2
+ --title=""
3
+ --markup=markdown
4
+ --template-path=./yard
5
+ --exclude lib/bettery/response
data/Gemfile ADDED
@@ -0,0 +1,19 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'rake'
4
+
5
+ group :development do
6
+ gem 'pry'
7
+ gem 'yard'
8
+ end
9
+
10
+ group :test do
11
+ gem 'rspec', '~> 3.0.0'
12
+ gem 'coveralls', require: false
13
+ gem 'simplecov', require: false
14
+ gem 'vcr', '~> 2.9.2'
15
+ gem 'webmock', '~> 1.9'
16
+ end
17
+
18
+ # Specify your gem's dependencies in bettery.gemspec
19
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Duilio Ruggiero
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,38 @@
1
+ # Bettery
2
+
3
+ [![Build Status](https://travis-ci.org/sinetris/bettery.svg?branch=master)](https://travis-ci.org/sinetris/bettery)
4
+ [![Coverage Status](https://img.shields.io/coveralls/sinetris/bettery.svg)](https://coveralls.io/r/sinetris/bettery?branch=master)
5
+ [![Dependency Status](https://gemnasium.com/sinetris/bettery.svg)](https://gemnasium.com/sinetris/bettery)
6
+
7
+ Ruby toolkit for working with the [Betterplace API][betterplace_api].
8
+
9
+ ## Installation
10
+
11
+ Add this line to your application's Gemfile:
12
+
13
+ ```ruby
14
+ gem 'bettery', github: 'sinetris/bettery'
15
+ ```
16
+
17
+ And then execute:
18
+
19
+ $ bundle
20
+
21
+ ## Usage
22
+
23
+ ```ruby
24
+ projects = Bettery.projects
25
+ projects.fields => #<Set: {:total_entries, :offset, :total_pages, :current_page, :per_page, :data}>
26
+ projects.total_entries #=> 11149
27
+ projects.data.first.title #=> "Mit der DKMS im Kampf gegen Blutkrebs!"
28
+ ```
29
+
30
+ ## Contributing
31
+
32
+ 1. Fork it ( https://github.com/sinetris/bettery/fork )
33
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
34
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
35
+ 4. Push to the branch (`git push origin my-new-feature`)
36
+ 5. Create a new Pull Request
37
+
38
+ [betterplace_api]: https://github.com/betterplace/betterplace_apidocs
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task default: :spec
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'bettery/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "bettery"
8
+ spec.version = Bettery::VERSION
9
+ spec.authors = ["Duilio Ruggiero"]
10
+ spec.email = ["duilio.ruggiero@gmail.com"]
11
+ spec.summary = %q{Betterplace API wrapper in Ruby.}
12
+ spec.description = %q{Ruby toolkit for working with the Betterplace API.}
13
+ spec.homepage = "https://github.com/sinetris/bettery"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.required_ruby_version = "~> 2.0"
22
+
23
+ spec.add_development_dependency "bundler", "~> 1.6"
24
+
25
+ spec.add_runtime_dependency 'sawyer', '~> 0.5'
26
+ end
@@ -0,0 +1,28 @@
1
+ require 'bettery/client'
2
+ require 'bettery/default'
3
+
4
+ # Ruby toolkit for the Betterplace API
5
+ module Bettery
6
+ class << self
7
+ include Bettery::Configurable
8
+
9
+ # API client based on configured options {Configurable}
10
+ #
11
+ # @return [Bettery::Client] API wrapper
12
+ def client
13
+ unless defined?(@client) && @client.same_options?(options)
14
+ @client = Bettery::Client.new(options)
15
+ end
16
+ @client
17
+ end
18
+
19
+ private
20
+
21
+ def method_missing(method_name, *args, &block)
22
+ return super unless client.respond_to?(method_name)
23
+ client.send(method_name, *args, &block)
24
+ end
25
+ end
26
+ end
27
+
28
+ Bettery.setup
@@ -0,0 +1,170 @@
1
+ require 'sawyer'
2
+ require 'bettery/configurable'
3
+ require 'bettery/project'
4
+ require 'bettery/client/projects'
5
+
6
+ module Bettery
7
+
8
+ # Client for the Betterplace API
9
+ #
10
+ # @see https://developer.betterplace.org
11
+ class Client
12
+ include Bettery::Configurable
13
+ include Bettery::Client::Projects
14
+
15
+ # Header keys that can be passed in options hash to {#get},{#head}
16
+ CONVENIENCE_HEADERS = Set.new([:accept, :content_type])
17
+
18
+ # Current API version
19
+ API_VERSION = "api_v4"
20
+
21
+ def initialize(options = {})
22
+ # Use options passed in, but fall back to module defaults
23
+ Bettery::Configurable.keys.each do |key|
24
+ instance_variable_set(:"@#{key}", options[key] || Bettery.instance_variable_get(:"@#{key}"))
25
+ end
26
+ end
27
+
28
+ # Compares client options to a Hash of requested options
29
+ #
30
+ # @param opts [Hash] Options to compare with current client options
31
+ # @return [Boolean]
32
+ def same_options?(opts)
33
+ opts.hash == options.hash
34
+ end
35
+
36
+ # API endpoint
37
+ # @return [String]
38
+ def api_endpoint
39
+ File.join(api_base_endpoint, locale, API_VERSION)
40
+ end
41
+
42
+ # Make a HTTP GET request
43
+ #
44
+ # @param url [String] The path, relative to {#api_endpoint}
45
+ # @param options [Hash] Query and header params for request
46
+ # @return [Sawyer::Resource]
47
+ def get(url, options = {})
48
+ request :get, url, parse_query_and_convenience_headers(options)
49
+ end
50
+
51
+ # Make a HTTP POST request
52
+ #
53
+ # @param url [String] The path, relative to {#api_endpoint}
54
+ # @param options [Hash] Body and header params for request
55
+ # @return [Sawyer::Resource]
56
+ def post(url, options = {})
57
+ request :post, url, options
58
+ end
59
+
60
+ # Make a HTTP PUT request
61
+ #
62
+ # @param url [String] The path, relative to {#api_endpoint}
63
+ # @param options [Hash] Body and header params for request
64
+ # @return [Sawyer::Resource]
65
+ def put(url, options = {})
66
+ request :put, url, options
67
+ end
68
+
69
+ # Make a HTTP PATCH request
70
+ #
71
+ # @param url [String] The path, relative to {#api_endpoint}
72
+ # @param options [Hash] Body and header params for request
73
+ # @return [Sawyer::Resource]
74
+ def patch(url, options = {})
75
+ request :patch, url, options
76
+ end
77
+
78
+ # Make a HTTP DELETE request
79
+ #
80
+ # @param url [String] The path, relative to {#api_endpoint}
81
+ # @param options [Hash] Query and header params for request
82
+ # @return [Sawyer::Resource]
83
+ def delete(url, options = {})
84
+ request :delete, url, options
85
+ end
86
+
87
+ # Make a HTTP HEAD request
88
+ #
89
+ # @param url [String] The path, relative to {#api_endpoint}
90
+ # @param options [Hash] Query and header params for request
91
+ # @return [Sawyer::Resource]
92
+ def head(url, options = {})
93
+ request :head, url, parse_query_and_convenience_headers(options)
94
+ end
95
+
96
+ # Hypermedia agent for the Betterplace API
97
+ #
98
+ # @return [Sawyer::Agent]
99
+ def agent
100
+ @agent ||= Sawyer::Agent.new(api_endpoint, sawyer_options) do |http|
101
+ http.headers[:accept] = default_media_type
102
+ http.headers[:user_agent] = user_agent
103
+ end
104
+ end
105
+
106
+ # Response for last HTTP request
107
+ #
108
+ # @return [Sawyer::Response]
109
+ def last_response
110
+ @last_response if defined? @last_response
111
+ end
112
+
113
+ private
114
+
115
+ def request(method, path, data, options = {})
116
+ if data.is_a?(Hash)
117
+ options[:query] = data.delete(:query) || {}
118
+ options[:headers] = data.delete(:headers) || {}
119
+ if accept = data.delete(:accept)
120
+ options[:headers][:accept] = accept
121
+ end
122
+ end
123
+
124
+ @last_response = response = agent.call(method, URI::Parser.new.escape(path.to_s), data, options)
125
+ response.data
126
+ end
127
+
128
+ # Executes the request, checking if it was successful
129
+ #
130
+ # @return [Boolean] True on success, false otherwise
131
+ def boolean_from_response(method, path, options = {})
132
+ request(method, path, options)
133
+ @last_response.status == 204
134
+ rescue Bettery::NotFound
135
+ false
136
+ end
137
+
138
+ def paginate(url, options = {}, &block)
139
+ opts = parse_query_and_convenience_headers(options.dup)
140
+ request(:get, url, opts)
141
+ end
142
+
143
+ def sawyer_options
144
+ opts = {
145
+ links_parser:Sawyer::LinkParsers::Simple.new
146
+ }
147
+ conn_opts = @connection_options
148
+ conn_opts[:builder] = @middleware if @middleware
149
+ conn_opts[:proxy] = @proxy if @proxy
150
+ opts[:faraday] = Faraday.new(conn_opts)
151
+
152
+ opts
153
+ end
154
+
155
+ def parse_query_and_convenience_headers(options)
156
+ headers = options.fetch(:headers, {})
157
+ CONVENIENCE_HEADERS.each do |h|
158
+ if header = options.delete(h)
159
+ headers[h] = header
160
+ end
161
+ end
162
+ query = options.delete(:query)
163
+ opts = {query: options}
164
+ opts[:query].merge!(query) if query && query.is_a?(Hash)
165
+ opts[:headers] = headers unless headers.empty?
166
+
167
+ opts
168
+ end
169
+ end
170
+ end
@@ -0,0 +1,45 @@
1
+ module Bettery
2
+ class Client
3
+
4
+ # Methods for the Projects API
5
+ #
6
+ # @see https://github.com/betterplace/betterplace_apidocs
7
+ module Projects
8
+
9
+ # Check if a project exists
10
+ #
11
+ # @see https://github.com/betterplace/betterplace_apidocs
12
+ # @param project [Integer, String, Hash, Project] A Betterplace project
13
+ # @return true if a project exists, false otherwise
14
+ def project?(project, options = {})
15
+ !!project(project, options)
16
+ rescue Bettery::NotFound
17
+ false
18
+ end
19
+
20
+ # Get a single project
21
+ #
22
+ # @see https://github.com/betterplace/betterplace_apidocs
23
+ # @param project [Integer, String, Hash, Project] A Betterplace project
24
+ # @return [Sawyer::Resource] Project information
25
+ def project(project, options = {})
26
+ get Bettery::Project.path(project), options
27
+ end
28
+
29
+ # List all projects
30
+ #
31
+ # This provides a dump of every project, in the order that they were
32
+ # created.
33
+ #
34
+ # @see https://github.com/betterplace/betterplace_apidocs
35
+ #
36
+ # @param options [Hash] Optional options
37
+ # @option options [Integer] :since The integer ID of the last Project
38
+ # that you’ve seen.
39
+ # @return [Sawyer::Resource] List of projects.
40
+ def projects(options = {})
41
+ get 'projects.json', options
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,41 @@
1
+ module Bettery
2
+ module Configurable
3
+ attr_accessor :api_base_endpoint, :connection_options, :default_media_type,
4
+ :locale, :middleware, :per_page, :proxy, :user_agent
5
+
6
+ class << self
7
+ def keys
8
+ @keys ||= [
9
+ :api_base_endpoint,
10
+ :connection_options,
11
+ :default_media_type,
12
+ :locale,
13
+ :middleware,
14
+ :per_page,
15
+ :proxy,
16
+ :user_agent
17
+ ]
18
+ end
19
+ end
20
+
21
+ # Set configuration options using a block
22
+ def configure
23
+ yield self
24
+ end
25
+
26
+ # Reset configuration options to default values
27
+ def reset!
28
+ Bettery::Configurable.keys.each do |key|
29
+ instance_variable_set(:"@#{key}", Bettery::Default.options[key])
30
+ end
31
+ self
32
+ end
33
+ alias setup reset!
34
+
35
+ private
36
+
37
+ def options
38
+ Hash[Bettery::Configurable.keys.map{|key| [key, instance_variable_get(:"@#{key}")]}]
39
+ end
40
+ end
41
+ end