bettery 0.0.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.
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