teamsnap_rb 0.0.3
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 +7 -0
- data/.gitignore +25 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +45 -0
- data/LICENSE +22 -0
- data/README.md +33 -0
- data/Rakefile +1 -0
- data/lib/teamsnap_rb.rb +23 -0
- data/lib/teamsnap_rb/client.rb +7 -0
- data/lib/teamsnap_rb/collection.rb +157 -0
- data/lib/teamsnap_rb/config.rb +13 -0
- data/lib/teamsnap_rb/exceptions.rb +3 -0
- data/lib/teamsnap_rb/item.rb +124 -0
- data/lib/teamsnap_rb/link.rb +24 -0
- data/lib/teamsnap_rb/links_proxy.rb +40 -0
- data/lib/teamsnap_rb/models/event.rb +4 -0
- data/lib/teamsnap_rb/models/user.rb +5 -0
- data/lib/teamsnap_rb/queries_proxy.rb +68 -0
- data/lib/teamsnap_rb/request_builder.rb +65 -0
- data/lib/teamsnap_rb/template.rb +37 -0
- data/lib/teamsnap_rb/version.rb +3 -0
- data/spec/collection_spec.rb +5 -0
- data/spec/item_spec.rb +5 -0
- data/spec/link_spec.rb +5 -0
- data/spec/spec_helper.rb +7 -0
- data/teamsnap_rb.gemspec +28 -0
- metadata +157 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: f8e3a81870fca373ca78814eb787dc449411386c
|
4
|
+
data.tar.gz: bffdeb4698ebee554f61812b2bb3143cddd0d872
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 8f99fae21aae3d939637393a7c812166ad351d7803f3c39674bcb89bade42c594995051329429a2b56df476800ab02bd262bdcf94015b76667b6b86ae737299e
|
7
|
+
data.tar.gz: d5379f5481cb14b940d222efa1c7d89ea667e1e16a7f7e008eaf3cc467d71592aa35c6f4b89b7ea4bfc2adc029ac4885ae02e0091cd06f04bc72947c75ff9e18
|
data/.gitignore
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
*.rbc
|
2
|
+
*.sassc
|
3
|
+
.sass-cache
|
4
|
+
capybara-*.html
|
5
|
+
.rspec
|
6
|
+
.rvmrc
|
7
|
+
/.bundle
|
8
|
+
/vendor/bundle
|
9
|
+
/log/*
|
10
|
+
/tmp/*
|
11
|
+
/db/*.sqlite3
|
12
|
+
/public/system/*
|
13
|
+
/coverage/
|
14
|
+
/spec/tmp/*
|
15
|
+
**.orig
|
16
|
+
rerun.txt
|
17
|
+
pickle-email-*.html
|
18
|
+
.project
|
19
|
+
config/initializers/secret_token.rb
|
20
|
+
config/*.yml
|
21
|
+
.ruby-version
|
22
|
+
.rbenv-version
|
23
|
+
/bin/stubs
|
24
|
+
/bin
|
25
|
+
/pkg
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
teamsnap_rb (0.0.3)
|
5
|
+
conglomerate (~> 0.8.0)
|
6
|
+
faraday (~> 0.9.0)
|
7
|
+
|
8
|
+
GEM
|
9
|
+
remote: https://rubygems.org/
|
10
|
+
specs:
|
11
|
+
coderay (1.1.0)
|
12
|
+
conglomerate (0.8.1)
|
13
|
+
diff-lcs (1.2.5)
|
14
|
+
faraday (0.9.0)
|
15
|
+
multipart-post (>= 1.2, < 3)
|
16
|
+
method_source (0.8.2)
|
17
|
+
multipart-post (2.0.0)
|
18
|
+
pry (0.9.12.4)
|
19
|
+
coderay (~> 1.0)
|
20
|
+
method_source (~> 0.8)
|
21
|
+
slop (~> 3.4)
|
22
|
+
rake (10.1.1)
|
23
|
+
rspec (3.0.0)
|
24
|
+
rspec-core (~> 3.0.0)
|
25
|
+
rspec-expectations (~> 3.0.0)
|
26
|
+
rspec-mocks (~> 3.0.0)
|
27
|
+
rspec-core (3.0.3)
|
28
|
+
rspec-support (~> 3.0.0)
|
29
|
+
rspec-expectations (3.0.3)
|
30
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
31
|
+
rspec-support (~> 3.0.0)
|
32
|
+
rspec-mocks (3.0.3)
|
33
|
+
rspec-support (~> 3.0.0)
|
34
|
+
rspec-support (3.0.3)
|
35
|
+
slop (3.4.7)
|
36
|
+
|
37
|
+
PLATFORMS
|
38
|
+
ruby
|
39
|
+
|
40
|
+
DEPENDENCIES
|
41
|
+
bundler (~> 1.5)
|
42
|
+
pry
|
43
|
+
rake
|
44
|
+
rspec (>= 3.0.0)
|
45
|
+
teamsnap_rb!
|
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 TeamSnap
|
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.
|
data/README.md
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# EARLY ACCESS
|
2
|
+
|
3
|
+
Please be aware there may be bugs, gremlins, and horrible issues; and you could be eaten by a grue. We are not responsible for any loss of life or limb (especially if you are eaten by a grue).
|
4
|
+
|
5
|
+
# TeamsnapRb
|
6
|
+
|
7
|
+
TeamsnapRb is a convenient wrapper around the faraday and the conglomerate gem that helps you talk to TeamSnap's APIv3.
|
8
|
+
|
9
|
+
## Installation
|
10
|
+
|
11
|
+
Add this line to your application's Gemfile:
|
12
|
+
|
13
|
+
gem 'teamsnap_rb'
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
|
17
|
+
$ bundle
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
|
21
|
+
$ gem install teamsnap_rb
|
22
|
+
|
23
|
+
## Usage
|
24
|
+
|
25
|
+
Needs to be updated; coming soon.
|
26
|
+
|
27
|
+
## Contributing
|
28
|
+
|
29
|
+
1. Fork it ( http://github.com/teamsnap/teamsnap_rb/fork )
|
30
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
31
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
32
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
33
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/lib/teamsnap_rb.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require "conglomerate"
|
2
|
+
require "json"
|
3
|
+
require "faraday"
|
4
|
+
require "securerandom"
|
5
|
+
|
6
|
+
require "teamsnap_rb/version"
|
7
|
+
require "teamsnap_rb/exceptions"
|
8
|
+
|
9
|
+
require "teamsnap_rb/config"
|
10
|
+
require "teamsnap_rb/request_builder"
|
11
|
+
require "teamsnap_rb/link"
|
12
|
+
require "teamsnap_rb/links_proxy"
|
13
|
+
require "teamsnap_rb/queries_proxy"
|
14
|
+
require "teamsnap_rb/item"
|
15
|
+
require "teamsnap_rb/template"
|
16
|
+
require "teamsnap_rb/models/event"
|
17
|
+
|
18
|
+
require "teamsnap_rb/collection"
|
19
|
+
require "teamsnap_rb/client"
|
20
|
+
|
21
|
+
module TeamsnapRb
|
22
|
+
|
23
|
+
end
|
@@ -0,0 +1,157 @@
|
|
1
|
+
module TeamsnapRb
|
2
|
+
class Collection
|
3
|
+
include Enumerable
|
4
|
+
|
5
|
+
attr_reader :errors
|
6
|
+
|
7
|
+
TYPE_TO_CLASS = {
|
8
|
+
"Event" => Event
|
9
|
+
}
|
10
|
+
|
11
|
+
def initialize(url, query_parameters, config, request: nil)
|
12
|
+
self.config = config
|
13
|
+
data = request || get(url, query_parameters)
|
14
|
+
self.errors = []
|
15
|
+
self.url = data.env["url"]
|
16
|
+
body = data.body
|
17
|
+
|
18
|
+
if data.success?
|
19
|
+
deserializer = Conglomerate::TreeDeserializer.new(JSON.parse(body))
|
20
|
+
self.collection_json = deserializer.deserialize
|
21
|
+
self.items = collection_json.items.map do |item|
|
22
|
+
type_name = item.data.find do |datum|
|
23
|
+
datum.name == "type"
|
24
|
+
end.value
|
25
|
+
|
26
|
+
klass = TYPE_TO_CLASS[type_name] || Item
|
27
|
+
klass.new(item, config)
|
28
|
+
end
|
29
|
+
|
30
|
+
if collection_json.error
|
31
|
+
errors << collection_json.error.message
|
32
|
+
end
|
33
|
+
else
|
34
|
+
errors << data.status.to_s
|
35
|
+
end
|
36
|
+
|
37
|
+
handle_error(errors)
|
38
|
+
end
|
39
|
+
|
40
|
+
def [](index)
|
41
|
+
items[index]
|
42
|
+
end
|
43
|
+
|
44
|
+
def each
|
45
|
+
items.each do |item|
|
46
|
+
yield item
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def where(attribute_hash)
|
51
|
+
CollectionWhereProxy.new(items).where(attribute_hash)
|
52
|
+
end
|
53
|
+
|
54
|
+
def href
|
55
|
+
collection_json.href
|
56
|
+
end
|
57
|
+
|
58
|
+
def method_missing(method, *args)
|
59
|
+
if links.respond_to?(method)
|
60
|
+
links.send(method)
|
61
|
+
elsif queries.respond_to?(method)
|
62
|
+
queries.send(method, *args)
|
63
|
+
else
|
64
|
+
super
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def respond_to?(method)
|
69
|
+
links.respond_to?(method) || queries.respond_to?(method)
|
70
|
+
end
|
71
|
+
|
72
|
+
def collection
|
73
|
+
@collection ||= Collection.new(href, {}, config)
|
74
|
+
end
|
75
|
+
|
76
|
+
def this
|
77
|
+
@this ||= Collection.new(this_href, {}, config)
|
78
|
+
end
|
79
|
+
|
80
|
+
def links
|
81
|
+
@links ||= LinksProxy.new(collection_json.links, config)
|
82
|
+
end
|
83
|
+
|
84
|
+
def queries
|
85
|
+
@queries ||= QueriesProxy.new(collection_json.queries, config)
|
86
|
+
end
|
87
|
+
|
88
|
+
def template
|
89
|
+
@template ||= TemplateProxy.new(collection_json.template, config, href)
|
90
|
+
end
|
91
|
+
|
92
|
+
def error
|
93
|
+
errors
|
94
|
+
end
|
95
|
+
|
96
|
+
def error?
|
97
|
+
errors.count > 0
|
98
|
+
end
|
99
|
+
|
100
|
+
private
|
101
|
+
|
102
|
+
attr_accessor :collection_json, :config, :items, :url
|
103
|
+
attr_writer :errors
|
104
|
+
|
105
|
+
def get(url, query_parameters = {})
|
106
|
+
RequestBuilder.new(config, url).connection.get do |conn|
|
107
|
+
query_parameters.each do |key, value|
|
108
|
+
conn.params[key] = value
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def this_href
|
114
|
+
collection_json.links.find { |l| l.rel == "self" }.href
|
115
|
+
end
|
116
|
+
|
117
|
+
def handle_error(errors)
|
118
|
+
if errors.include?("401")
|
119
|
+
raise HttpError, "401 Unauthorized for #{url}"
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
class CollectionWhereProxy
|
124
|
+
include Enumerable
|
125
|
+
|
126
|
+
def initialize(items)
|
127
|
+
self.items = items
|
128
|
+
end
|
129
|
+
|
130
|
+
def [](index)
|
131
|
+
items[index]
|
132
|
+
end
|
133
|
+
|
134
|
+
def each
|
135
|
+
items.each do |item|
|
136
|
+
yield item
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
def where(attribute_hash)
|
141
|
+
CollectionWhereProxy.new(find_all do |item|
|
142
|
+
attribute_hash.keys.all? do |key|
|
143
|
+
if item.respond_to?(key)
|
144
|
+
attribute_hash[key] == item.send(key)
|
145
|
+
else
|
146
|
+
false
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end)
|
150
|
+
end
|
151
|
+
|
152
|
+
private
|
153
|
+
|
154
|
+
attr_accessor :items
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module TeamsnapRb
|
2
|
+
class Config
|
3
|
+
attr_accessor :access_token, :client_id, :client_secret, :request_middleware, :response_middleware
|
4
|
+
|
5
|
+
def initialize(access_token: nil, client_id: nil, client_secret: nil)
|
6
|
+
self.access_token = access_token
|
7
|
+
self.client_secret = client_secret
|
8
|
+
self.client_id = client_id
|
9
|
+
self.response_middleware = []
|
10
|
+
self.request_middleware = []
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,124 @@
|
|
1
|
+
module TeamsnapRb
|
2
|
+
class Item
|
3
|
+
class << self
|
4
|
+
attr_accessor :templates
|
5
|
+
end
|
6
|
+
@templates = {}
|
7
|
+
|
8
|
+
def initialize(item, config)
|
9
|
+
self.config = config
|
10
|
+
self.item = item
|
11
|
+
end
|
12
|
+
|
13
|
+
def with(attrs)
|
14
|
+
attrs = Hash[attrs.map{ |k, v| [k.to_s, v] }]
|
15
|
+
dirtied_attrs = attrs.keys
|
16
|
+
attrs = attributes.merge(attrs)
|
17
|
+
|
18
|
+
new_data = attrs.inject([]) do |arr, (key, value)|
|
19
|
+
arr << Conglomerate::Datum.new(:name => key, :value => value)
|
20
|
+
end
|
21
|
+
|
22
|
+
item = Conglomerate::Item.new(
|
23
|
+
:href => href,
|
24
|
+
:data => new_data
|
25
|
+
)
|
26
|
+
|
27
|
+
Item.new(item, config).tap do |it|
|
28
|
+
it.send(:dirty, dirtied_attrs)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def save
|
33
|
+
attrs_to_update = dirty_attributes.inject({}) do |h, attr|
|
34
|
+
h.tap do |hash|
|
35
|
+
hash[attr] = attributes[attr]
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
request = RequestBuilder.new(config, href).connection.patch do |conn|
|
40
|
+
conn.body = template.build(attrs_to_update).to_json
|
41
|
+
conn.headers["Content-Type"] = "application/json"
|
42
|
+
end
|
43
|
+
|
44
|
+
Collection.new(nil, nil, config, :request => request)
|
45
|
+
end
|
46
|
+
|
47
|
+
def attributes
|
48
|
+
@attributes ||= data.inject({}) do |h, datum|
|
49
|
+
h.tap do |hash|
|
50
|
+
hash[datum.name] = datum.value
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def href
|
56
|
+
item.href
|
57
|
+
end
|
58
|
+
|
59
|
+
def method_missing(method, *args)
|
60
|
+
if datum = item.data.find { |d| d.name == method.to_s }
|
61
|
+
unless instance_variable_get("@#{method}_datum")
|
62
|
+
instance_variable_set("@#{method}_datum", datum.value)
|
63
|
+
end
|
64
|
+
|
65
|
+
instance_variable_get("@#{method}_datum")
|
66
|
+
elsif links.respond_to?(method)
|
67
|
+
links.send(method)
|
68
|
+
else
|
69
|
+
super
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def respond_to?(method)
|
74
|
+
if item.data.find { |d| d.name == method.to_s }
|
75
|
+
true
|
76
|
+
else
|
77
|
+
links.respond_to?(method)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def data
|
82
|
+
item.data
|
83
|
+
end
|
84
|
+
|
85
|
+
def template
|
86
|
+
self.class.templates[type] ||= fetch_template
|
87
|
+
end
|
88
|
+
|
89
|
+
def delete
|
90
|
+
response = delete_href(href)
|
91
|
+
if response.status == 204
|
92
|
+
true
|
93
|
+
else
|
94
|
+
raise FailedToDelete
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def this
|
99
|
+
@this ||= Collection.new(href, {}, config)
|
100
|
+
end
|
101
|
+
|
102
|
+
def links
|
103
|
+
@links ||= LinksProxy.new(item.links, config)
|
104
|
+
end
|
105
|
+
|
106
|
+
private
|
107
|
+
|
108
|
+
def delete_href(href)
|
109
|
+
RequestBuilder.new(config, href).connection.delete
|
110
|
+
end
|
111
|
+
|
112
|
+
def dirty(attrs)
|
113
|
+
self.dirty_attributes = attrs
|
114
|
+
end
|
115
|
+
|
116
|
+
def fetch_template
|
117
|
+
this.template
|
118
|
+
end
|
119
|
+
|
120
|
+
attr_accessor :item, :config, :dirty_attributes
|
121
|
+
end
|
122
|
+
|
123
|
+
class FailedToDelete < StandardError;end;
|
124
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module TeamsnapRb
|
2
|
+
class Link
|
3
|
+
def initialize(link, config)
|
4
|
+
self.config = config
|
5
|
+
self.link = link
|
6
|
+
end
|
7
|
+
|
8
|
+
def follow
|
9
|
+
@collection ||= Collection.new(href, {}, config)
|
10
|
+
end
|
11
|
+
|
12
|
+
def rel
|
13
|
+
link.rel
|
14
|
+
end
|
15
|
+
|
16
|
+
def href
|
17
|
+
link.href
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
attr_accessor :config, :link
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module TeamsnapRb
|
2
|
+
class LinksProxy
|
3
|
+
include Enumerable
|
4
|
+
|
5
|
+
def initialize(links, config)
|
6
|
+
self.config = config
|
7
|
+
self.links = links.inject({}) do |h, link|
|
8
|
+
h.tap do |hash|
|
9
|
+
hash[link.rel.to_sym] = Link.new(link, config)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def method_missing(method, *args)
|
15
|
+
if link = links[method.to_sym]
|
16
|
+
link.follow
|
17
|
+
else
|
18
|
+
super
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def respond_to?(method)
|
23
|
+
links.include?(method.to_sym) || super
|
24
|
+
end
|
25
|
+
|
26
|
+
def each
|
27
|
+
links.values.each do |link|
|
28
|
+
yield link
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def rels
|
33
|
+
links.keys
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
attr_accessor :links, :config
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module TeamsnapRb
|
2
|
+
class QueriesProxy
|
3
|
+
include Enumerable
|
4
|
+
|
5
|
+
def initialize(queries, config)
|
6
|
+
self.config = config
|
7
|
+
self.queries = queries.inject({}) do |h, query|
|
8
|
+
h.tap do |hash|
|
9
|
+
hash[query.rel.to_sym] = Query.new(query.href, query.data, config)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def method_missing(method, *args)
|
15
|
+
if query = queries[method.to_sym]
|
16
|
+
query.get(*args)
|
17
|
+
else
|
18
|
+
super
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def respond_to?(method)
|
23
|
+
queries.include?(method.to_sym) || super
|
24
|
+
end
|
25
|
+
|
26
|
+
def each
|
27
|
+
queries.values.each do |query|
|
28
|
+
yield query
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def rels
|
33
|
+
queries.keys
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
attr_accessor :queries, :config
|
39
|
+
end
|
40
|
+
|
41
|
+
class Query
|
42
|
+
MissingQueryParameter = Class.new(StandardError)
|
43
|
+
|
44
|
+
def initialize(url, data, config)
|
45
|
+
self.url = url
|
46
|
+
self.data = data
|
47
|
+
self.config = config
|
48
|
+
end
|
49
|
+
|
50
|
+
def get(query_parameters={})
|
51
|
+
possible_params = data.map(&:name).map(&:to_sym)
|
52
|
+
query_parameters.reject! { |key, value| !possible_params.include?(key) }
|
53
|
+
|
54
|
+
if query_parameters.empty?
|
55
|
+
raise(
|
56
|
+
MissingQueryParameter,
|
57
|
+
"You must provide at least one of the following parameters: #{possible_params}"
|
58
|
+
)
|
59
|
+
end
|
60
|
+
|
61
|
+
Collection.new(url, query_parameters, config)
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
attr_accessor :url, :data, :config
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require "openssl"
|
2
|
+
|
3
|
+
module TeamsnapRb
|
4
|
+
class RequestBuilder
|
5
|
+
attr_reader :connection
|
6
|
+
|
7
|
+
def initialize(config, url)
|
8
|
+
self.config = config
|
9
|
+
self.connection = Faraday::Connection.new(:url => url) do |faraday|
|
10
|
+
config.request_middleware.each do |m|
|
11
|
+
faraday.request(m)
|
12
|
+
end
|
13
|
+
|
14
|
+
config.response_middleware.each do |m|
|
15
|
+
faraday.response(m)
|
16
|
+
end
|
17
|
+
|
18
|
+
faraday.request :teamsnap_config_middleware, config
|
19
|
+
faraday.adapter Faraday.default_adapter
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
attr_accessor :config
|
26
|
+
attr_writer :connection
|
27
|
+
end
|
28
|
+
|
29
|
+
class TeamsnapAuthMiddleware < Faraday::Middleware
|
30
|
+
def initialize(app, *args, &block)
|
31
|
+
self.config = args[0]
|
32
|
+
super(app)
|
33
|
+
end
|
34
|
+
|
35
|
+
def call(env)
|
36
|
+
if config.access_token
|
37
|
+
env.request_headers["X-Teamsnap-Access-Token"] = config.access_token
|
38
|
+
elsif config.client_id && config.client_secret
|
39
|
+
query_params = Hash[URI.decode_www_form(env.url.query || "")]
|
40
|
+
query_params.merge!({
|
41
|
+
hmac_client_id: config.client_id,
|
42
|
+
hmac_nonce: SecureRandom.uuid,
|
43
|
+
hmac_timestamp: Time.now.to_i
|
44
|
+
})
|
45
|
+
env.url.query = URI.encode_www_form(query_params)
|
46
|
+
|
47
|
+
message = "/?" + env.url.query.to_s + (env.body || "")
|
48
|
+
digest = OpenSSL::Digest.new('sha256')
|
49
|
+
message_hash = digest.hexdigest(message)
|
50
|
+
|
51
|
+
env.request_headers["X-Teamsnap-Hmac"] = OpenSSL::HMAC.hexdigest(digest, config.client_secret, message_hash)
|
52
|
+
end
|
53
|
+
|
54
|
+
@app.call(env)
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
attr_accessor :config
|
60
|
+
end
|
61
|
+
|
62
|
+
Faraday::Request.register_middleware(
|
63
|
+
:teamsnap_config_middleware => lambda { TeamsnapAuthMiddleware }
|
64
|
+
)
|
65
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module TeamsnapRb
|
2
|
+
class TemplateProxy
|
3
|
+
def initialize(template, config, url)
|
4
|
+
self.config = config
|
5
|
+
self.template = template
|
6
|
+
self.url = url
|
7
|
+
end
|
8
|
+
|
9
|
+
def build(attrs={})
|
10
|
+
@data = template.build(attrs)
|
11
|
+
end
|
12
|
+
|
13
|
+
def push(attrs={})
|
14
|
+
build(attrs)
|
15
|
+
publish
|
16
|
+
end
|
17
|
+
|
18
|
+
def data
|
19
|
+
template.data
|
20
|
+
end
|
21
|
+
|
22
|
+
def publish
|
23
|
+
post(url, @data) if @data
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
attr_accessor :template, :config, :url
|
29
|
+
|
30
|
+
def post(url, query_parameters = {})
|
31
|
+
RequestBuilder.new(config, url).connection.post do |conn|
|
32
|
+
conn.body = @data.to_json
|
33
|
+
conn.headers['Content-Type'] = 'application/json'
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/spec/item_spec.rb
ADDED
data/spec/link_spec.rb
ADDED
data/spec/spec_helper.rb
ADDED
data/teamsnap_rb.gemspec
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'teamsnap_rb/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "teamsnap_rb"
|
8
|
+
spec.version = TeamsnapRb::VERSION
|
9
|
+
spec.authors = ["Party Chicken"]
|
10
|
+
spec.email = ["api@teamsnap.com"]
|
11
|
+
spec.summary = %q{A gem interact with TeamSnap's API}
|
12
|
+
spec.description = %q{}
|
13
|
+
spec.homepage = "http://www.teamsnap.com/api"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
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.add_development_dependency "bundler", "~> 1.5"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
spec.add_development_dependency "pry"
|
24
|
+
spec.add_development_dependency "rspec", ">= 3.0.0"
|
25
|
+
|
26
|
+
spec.add_dependency "faraday", "~> 0.9.0"
|
27
|
+
spec.add_dependency "conglomerate", "~> 0.8.0"
|
28
|
+
end
|
metadata
ADDED
@@ -0,0 +1,157 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: teamsnap_rb
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.3
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Party Chicken
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-09-25 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.5'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.5'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: pry
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 3.0.0
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 3.0.0
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: faraday
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 0.9.0
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 0.9.0
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: conglomerate
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 0.8.0
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 0.8.0
|
97
|
+
description: ''
|
98
|
+
email:
|
99
|
+
- api@teamsnap.com
|
100
|
+
executables: []
|
101
|
+
extensions: []
|
102
|
+
extra_rdoc_files: []
|
103
|
+
files:
|
104
|
+
- ".gitignore"
|
105
|
+
- Gemfile
|
106
|
+
- Gemfile.lock
|
107
|
+
- LICENSE
|
108
|
+
- README.md
|
109
|
+
- Rakefile
|
110
|
+
- lib/teamsnap_rb.rb
|
111
|
+
- lib/teamsnap_rb/client.rb
|
112
|
+
- lib/teamsnap_rb/collection.rb
|
113
|
+
- lib/teamsnap_rb/config.rb
|
114
|
+
- lib/teamsnap_rb/exceptions.rb
|
115
|
+
- lib/teamsnap_rb/item.rb
|
116
|
+
- lib/teamsnap_rb/link.rb
|
117
|
+
- lib/teamsnap_rb/links_proxy.rb
|
118
|
+
- lib/teamsnap_rb/models/event.rb
|
119
|
+
- lib/teamsnap_rb/models/user.rb
|
120
|
+
- lib/teamsnap_rb/queries_proxy.rb
|
121
|
+
- lib/teamsnap_rb/request_builder.rb
|
122
|
+
- lib/teamsnap_rb/template.rb
|
123
|
+
- lib/teamsnap_rb/version.rb
|
124
|
+
- spec/collection_spec.rb
|
125
|
+
- spec/item_spec.rb
|
126
|
+
- spec/link_spec.rb
|
127
|
+
- spec/spec_helper.rb
|
128
|
+
- teamsnap_rb.gemspec
|
129
|
+
homepage: http://www.teamsnap.com/api
|
130
|
+
licenses:
|
131
|
+
- MIT
|
132
|
+
metadata: {}
|
133
|
+
post_install_message:
|
134
|
+
rdoc_options: []
|
135
|
+
require_paths:
|
136
|
+
- lib
|
137
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
138
|
+
requirements:
|
139
|
+
- - ">="
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
version: '0'
|
142
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
143
|
+
requirements:
|
144
|
+
- - ">="
|
145
|
+
- !ruby/object:Gem::Version
|
146
|
+
version: '0'
|
147
|
+
requirements: []
|
148
|
+
rubyforge_project:
|
149
|
+
rubygems_version: 2.2.2
|
150
|
+
signing_key:
|
151
|
+
specification_version: 4
|
152
|
+
summary: A gem interact with TeamSnap's API
|
153
|
+
test_files:
|
154
|
+
- spec/collection_spec.rb
|
155
|
+
- spec/item_spec.rb
|
156
|
+
- spec/link_spec.rb
|
157
|
+
- spec/spec_helper.rb
|