kippt 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.
- data/.gitignore +17 -0
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +165 -0
- data/Rakefile +10 -0
- data/kippt.gemspec +24 -0
- data/lib/kippt.rb +8 -0
- data/lib/kippt/account.rb +10 -0
- data/lib/kippt/client.rb +33 -0
- data/lib/kippt/clip.rb +29 -0
- data/lib/kippt/clip_collection.rb +10 -0
- data/lib/kippt/clips.rb +63 -0
- data/lib/kippt/collection.rb +46 -0
- data/lib/kippt/collection_resource.rb +35 -0
- data/lib/kippt/connection.rb +52 -0
- data/lib/kippt/list.rb +14 -0
- data/lib/kippt/list_collection.rb +10 -0
- data/lib/kippt/lists.rb +24 -0
- data/lib/kippt/version.rb +3 -0
- data/spec/fixtures/clip.json +1 -0
- data/spec/fixtures/clips.json +1 -0
- data/spec/fixtures/list.json +1 -0
- data/spec/fixtures/lists.json +1 -0
- data/spec/kippt/account_spec.rb +28 -0
- data/spec/kippt/client_spec.rb +17 -0
- data/spec/kippt/clip_collection_spec.rb +10 -0
- data/spec/kippt/clip_spec.rb +52 -0
- data/spec/kippt/clips_spec.rb +144 -0
- data/spec/kippt/list_collection_spec.rb +9 -0
- data/spec/kippt/lists_spec.rb +57 -0
- data/spec/spec_helper.rb +40 -0
- metadata +170 -0
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Vesa Vänskä
|
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,165 @@
|
|
1
|
+
# Kippt
|
2
|
+
|
3
|
+
Kippt is a gem that provides a client library for using Kippt.com API.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem "kippt"
|
11
|
+
```
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
```sh
|
16
|
+
$ bundle
|
17
|
+
```
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
|
21
|
+
```sh
|
22
|
+
$ gem install kippt
|
23
|
+
```
|
24
|
+
|
25
|
+
## Usage
|
26
|
+
|
27
|
+
### Authentication
|
28
|
+
|
29
|
+
To be able to use the API you need to authenticated. There's two ways to authenticate:
|
30
|
+
|
31
|
+
#### With login credentials
|
32
|
+
|
33
|
+
```ruby
|
34
|
+
client = Kippt::Client.new(username: "vesan", password: "s3cr3t")
|
35
|
+
# Methods called on `client` will use the passed credentials
|
36
|
+
```
|
37
|
+
|
38
|
+
#### With token
|
39
|
+
|
40
|
+
```ruby
|
41
|
+
client = Kippt::Client.new(username: "vesan", token: "2544d6bfddf5893ec8617")
|
42
|
+
# Methods called on `client` will use the passed credentials
|
43
|
+
```
|
44
|
+
|
45
|
+
### Account
|
46
|
+
|
47
|
+
```ruby
|
48
|
+
client = Kippt::Client.new(username: "vesan", token: "2544d6bfddf5893ec8617")
|
49
|
+
account = client.account
|
50
|
+
account.username #=> "vesan"
|
51
|
+
account.token #=> "2544d6bfddf5893ec8617"
|
52
|
+
```
|
53
|
+
|
54
|
+
### Resources
|
55
|
+
|
56
|
+
Currently this client library is read-only! Ability to create and edit
|
57
|
+
resources will be added soon.
|
58
|
+
|
59
|
+
#### Lists
|
60
|
+
|
61
|
+
Get all the lists:
|
62
|
+
|
63
|
+
```ruby
|
64
|
+
client = Kippt::Client.new(username: "vesan", token: "2544d6bfddf5893ec8617")
|
65
|
+
lists = client.lists # Returns Kippt::ListCollection
|
66
|
+
```
|
67
|
+
|
68
|
+
Get single list:
|
69
|
+
|
70
|
+
```ruby
|
71
|
+
client = Kippt::Client.new(username: "vesan", token: "2544d6bfddf5893ec8617")
|
72
|
+
list_id = 10
|
73
|
+
list = client.lists[list_id] # Returns Kippt::ListItem
|
74
|
+
```
|
75
|
+
|
76
|
+
#### Clips
|
77
|
+
|
78
|
+
```ruby
|
79
|
+
client = Kippt::Client.new(username: "vesan", token: "2544d6bfddf5893ec8617")
|
80
|
+
clips = client.clips # Returns Kippt::ClipCollection
|
81
|
+
```
|
82
|
+
|
83
|
+
### Pagination
|
84
|
+
|
85
|
+
Lists and clips are paginated:
|
86
|
+
|
87
|
+
```ruby
|
88
|
+
client = Kippt::Client.new(username: "vesan", token: "2544d6bfddf5893ec8617")
|
89
|
+
clips = client.clips.all
|
90
|
+
|
91
|
+
clips.total_count
|
92
|
+
clips.offset
|
93
|
+
clips.limit
|
94
|
+
```
|
95
|
+
|
96
|
+
You can get next and previous set of results:
|
97
|
+
|
98
|
+
```ruby
|
99
|
+
clips.next_page? #=> true
|
100
|
+
clips.next_page # Returns new Kippt::ClipCollection
|
101
|
+
clips.prev_page? #=> true
|
102
|
+
clips.prev_page # Returns new Kippt::ClipCollection
|
103
|
+
```
|
104
|
+
|
105
|
+
There's also `#previous\_page?` and `#previous\_page`.
|
106
|
+
|
107
|
+
Limit and offset can be controlled manually:
|
108
|
+
|
109
|
+
```ruby
|
110
|
+
client.clips.all(limit: 25, offset: 50)
|
111
|
+
```
|
112
|
+
|
113
|
+
### Search
|
114
|
+
|
115
|
+
Clips can be searched:
|
116
|
+
|
117
|
+
```ruby
|
118
|
+
client.clips.search("kippt") #=> Returns Kippt::ClipCollection
|
119
|
+
```
|
120
|
+
|
121
|
+
Other available options are `is\_starred: true` and `list: [list-id]` like:
|
122
|
+
|
123
|
+
```ruby
|
124
|
+
client.clips.search(q: "kippt", list: 5, is_starred: true)
|
125
|
+
```
|
126
|
+
|
127
|
+
### Creating, updating and deleting resources
|
128
|
+
|
129
|
+
**NOT IMPLEMENTED YET**
|
130
|
+
|
131
|
+
```ruby
|
132
|
+
clip = client.clips.build
|
133
|
+
clip.url = "http://github.com"
|
134
|
+
clip.save #=> Returns boolean
|
135
|
+
```
|
136
|
+
|
137
|
+
If you are missing required fields `#save` will return `false` and you can use
|
138
|
+
`#errors` to get the error messages returned by the API.
|
139
|
+
|
140
|
+
```ruby
|
141
|
+
clip = client.clips.build
|
142
|
+
clip.save #=> false
|
143
|
+
clip.errors #=> ["No url."]
|
144
|
+
```
|
145
|
+
|
146
|
+
Deleting clips is done with `#destroy`:
|
147
|
+
|
148
|
+
```ruby
|
149
|
+
clip_id = 1001
|
150
|
+
clip = client.clips[clip_id]
|
151
|
+
clip.destroy #=> true
|
152
|
+
```
|
153
|
+
|
154
|
+
## Contributing
|
155
|
+
|
156
|
+
1. Fork it
|
157
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
158
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
159
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
160
|
+
5. Create new Pull Request
|
161
|
+
|
162
|
+
## TODO
|
163
|
+
|
164
|
+
* Ability to create, update and delete resources
|
165
|
+
* Add user agent string
|
data/Rakefile
ADDED
data/kippt.gemspec
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/kippt/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Vesa Vänskä"]
|
6
|
+
gem.email = ["vesa@vesavanska.com"]
|
7
|
+
gem.description = %q{Client library for using Kippt.com API}
|
8
|
+
gem.summary = %q{Client library for using Kippt.com API}
|
9
|
+
gem.homepage = ""
|
10
|
+
|
11
|
+
gem.files = `git ls-files`.split($\)
|
12
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
13
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
14
|
+
gem.name = "kippt"
|
15
|
+
gem.require_paths = ["lib"]
|
16
|
+
gem.version = Kippt::VERSION
|
17
|
+
|
18
|
+
gem.add_dependency "faraday", "~> 0.7.6"
|
19
|
+
gem.add_dependency "faraday_middleware", "~> 0.8.7"
|
20
|
+
gem.add_dependency "yajl-ruby", "~> 1.1.0"
|
21
|
+
|
22
|
+
gem.add_development_dependency "rspec", "~> 2.9.0"
|
23
|
+
gem.add_development_dependency "webmock", "~> 1.8.6"
|
24
|
+
end
|
data/lib/kippt.rb
ADDED
data/lib/kippt/client.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
require "kippt/connection"
|
2
|
+
require "kippt/account"
|
3
|
+
require "kippt/clips"
|
4
|
+
require "kippt/lists"
|
5
|
+
|
6
|
+
class Kippt::Client
|
7
|
+
include Kippt::Connection
|
8
|
+
|
9
|
+
attr_reader :username, :token, :password
|
10
|
+
|
11
|
+
def initialize(options = {})
|
12
|
+
@username = options.fetch(:username) { raise ArgumentError.new("username is required") }
|
13
|
+
|
14
|
+
@password = options.fetch(:password) { nil }
|
15
|
+
@token = options.fetch(:token) { nil }
|
16
|
+
|
17
|
+
if @password.nil? && @token.nil?
|
18
|
+
raise ArgumentError.new("password or token is required")
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def account
|
23
|
+
Kippt::Account.new(get("account").body)
|
24
|
+
end
|
25
|
+
|
26
|
+
def lists
|
27
|
+
Kippt::Lists.new(self)
|
28
|
+
end
|
29
|
+
|
30
|
+
def clips
|
31
|
+
Kippt::Clips.new(self)
|
32
|
+
end
|
33
|
+
end
|
data/lib/kippt/clip.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require "ostruct"
|
2
|
+
|
3
|
+
class Kippt::Clip
|
4
|
+
extend Forwardable
|
5
|
+
|
6
|
+
attr_reader :attributes, :errors
|
7
|
+
|
8
|
+
def_delegators :attributes, :url_domain, :updated, :is_starred, :title,
|
9
|
+
:url, :notes, :created, :list, :id, :resource_uri,
|
10
|
+
:is_starred=, :title=, :url=, :notes=, :list=
|
11
|
+
|
12
|
+
def initialize(attributes = {}, collection_resource = nil)
|
13
|
+
@attributes = OpenStruct.new(attributes)
|
14
|
+
@errors = []
|
15
|
+
@collection_resource = collection_resource
|
16
|
+
end
|
17
|
+
|
18
|
+
def destroy
|
19
|
+
@collection_resource.destroy_resource(self)
|
20
|
+
end
|
21
|
+
|
22
|
+
def save
|
23
|
+
response = @collection_resource.save_object(self)
|
24
|
+
if response[:error_message]
|
25
|
+
errors << response[:error_message]
|
26
|
+
end
|
27
|
+
response[:success]
|
28
|
+
end
|
29
|
+
end
|
data/lib/kippt/clips.rb
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
require "kippt/connection"
|
2
|
+
require "kippt/collection_resource"
|
3
|
+
require "kippt/clip_collection"
|
4
|
+
require "kippt/clip"
|
5
|
+
|
6
|
+
class Kippt::Clips
|
7
|
+
include Kippt::CollectionResource
|
8
|
+
|
9
|
+
def initialize(client)
|
10
|
+
@client = client
|
11
|
+
end
|
12
|
+
|
13
|
+
def object_class
|
14
|
+
Kippt::Clip
|
15
|
+
end
|
16
|
+
|
17
|
+
def collection_class
|
18
|
+
Kippt::ClipCollection
|
19
|
+
end
|
20
|
+
|
21
|
+
def base_uri
|
22
|
+
"clips"
|
23
|
+
end
|
24
|
+
|
25
|
+
def search(parameters)
|
26
|
+
# TODO: Validate parameters
|
27
|
+
if parameters.is_a?(String)
|
28
|
+
Kippt::ClipCollection.new(
|
29
|
+
@client.get("search/clips", {:q => parameters}).body,
|
30
|
+
self)
|
31
|
+
else
|
32
|
+
Kippt::ClipCollection.new(
|
33
|
+
@client.get("search/clips", parameters).body,
|
34
|
+
self)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def save_object(object)
|
39
|
+
if object.id
|
40
|
+
response = @client.put("clips/#{object.id}", writable_parameters_from(object))
|
41
|
+
else
|
42
|
+
response = @client.post("clips", writable_parameters_from(object))
|
43
|
+
end
|
44
|
+
|
45
|
+
save_response = {success: response.success?}
|
46
|
+
if response.body["message"]
|
47
|
+
save_response[:error_message] = response.body["message"]
|
48
|
+
end
|
49
|
+
save_response
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def writable_parameters_from(clip)
|
55
|
+
[:url, :title, :list, :notes, :is_starred].
|
56
|
+
inject({}) do |parameters, attribute_name|
|
57
|
+
unless clip.send(attribute_name).nil?
|
58
|
+
parameters[attribute_name] = clip.send(attribute_name)
|
59
|
+
end
|
60
|
+
parameters
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module Kippt::Collection
|
2
|
+
attr_reader :total_count, :limit, :offset
|
3
|
+
|
4
|
+
def initialize(data, collection_resource = nil)
|
5
|
+
meta = data.fetch("meta")
|
6
|
+
@limit = meta.fetch("limit")
|
7
|
+
@offset = meta.fetch("offset")
|
8
|
+
@next = meta.fetch("next") { nil }
|
9
|
+
@prev = meta.fetch("prev") { nil }
|
10
|
+
@total_count = meta.fetch("total_count")
|
11
|
+
|
12
|
+
@collection_resource = collection_resource
|
13
|
+
|
14
|
+
@object_data = data.fetch("objects")
|
15
|
+
end
|
16
|
+
|
17
|
+
def objects
|
18
|
+
@objects ||= @object_data.map {|data| object_class.new(data, @collection_resource) }
|
19
|
+
end
|
20
|
+
|
21
|
+
def [](index)
|
22
|
+
objects[index]
|
23
|
+
end
|
24
|
+
|
25
|
+
def each(&block)
|
26
|
+
objects.each(&block)
|
27
|
+
end
|
28
|
+
|
29
|
+
def next_page?
|
30
|
+
@next
|
31
|
+
end
|
32
|
+
|
33
|
+
def next_page
|
34
|
+
# TODO: Raise error if there is no page
|
35
|
+
@collection_resource.collection_from_url(@next)
|
36
|
+
end
|
37
|
+
|
38
|
+
def prev_page?
|
39
|
+
@prev
|
40
|
+
end
|
41
|
+
|
42
|
+
def prev_page
|
43
|
+
# TODO: Raise error if there is no page
|
44
|
+
@collection_resource.collection_from_url(@prev)
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Kippt::CollectionResource
|
2
|
+
def all(options = {})
|
3
|
+
validate_collection_options(options)
|
4
|
+
|
5
|
+
collection_class.new(@client.get(base_uri, options).body, self)
|
6
|
+
end
|
7
|
+
|
8
|
+
def build
|
9
|
+
object_class.new({}, self)
|
10
|
+
end
|
11
|
+
|
12
|
+
def [](resource_id)
|
13
|
+
object_class.new(@client.get("#{base_uri}/#{resource_id}").body)
|
14
|
+
end
|
15
|
+
|
16
|
+
def collection_from_url(url)
|
17
|
+
collection_class.new(@client.get(url).body, self)
|
18
|
+
end
|
19
|
+
|
20
|
+
def destroy_resource(resource)
|
21
|
+
if resource.id
|
22
|
+
@client.delete("#{base_uri}/#{resource.id}").success?
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def validate_collection_options(options)
|
29
|
+
options.each do |key, _|
|
30
|
+
unless [:limit, :offset].include?(key)
|
31
|
+
raise ArgumentError.new("Unrecognized argument: #{key}")
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Kippt::Connection
|
2
|
+
def get(url, options = {})
|
3
|
+
request(:get, url, options)
|
4
|
+
end
|
5
|
+
|
6
|
+
def post(url, options = {})
|
7
|
+
request(:post, url, options)
|
8
|
+
end
|
9
|
+
|
10
|
+
def put(url, options = {})
|
11
|
+
request(:put, url, options)
|
12
|
+
end
|
13
|
+
|
14
|
+
def delete(url, options = {})
|
15
|
+
request(:delete, url, options)
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def connection
|
21
|
+
@connection ||= Faraday.new("https://kippt.com/api") do |builder|
|
22
|
+
builder.use Faraday::Request::JSON
|
23
|
+
builder.use FaradayMiddleware::ParseJson
|
24
|
+
# builder.use Faraday::Response::Logger
|
25
|
+
builder.adapter Faraday.default_adapter
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def request(method, url, options)
|
30
|
+
response = connection.send(method) do |req|
|
31
|
+
if @password
|
32
|
+
connection.basic_auth(@username, @password)
|
33
|
+
else
|
34
|
+
req.headers["X-Kippt-Username"] = @username
|
35
|
+
req.headers["X-Kippt-API-Token"] = @token
|
36
|
+
end
|
37
|
+
|
38
|
+
if method == :get
|
39
|
+
req.url url, options
|
40
|
+
else
|
41
|
+
req.url url
|
42
|
+
req.body = options
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
if response.status == 401
|
47
|
+
raise Kippt::APIError.new(response.body["message"])
|
48
|
+
end
|
49
|
+
|
50
|
+
response
|
51
|
+
end
|
52
|
+
end
|
data/lib/kippt/list.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require "ostruct"
|
2
|
+
|
3
|
+
class Kippt::List
|
4
|
+
extend Forwardable
|
5
|
+
|
6
|
+
attr_reader :attributes
|
7
|
+
|
8
|
+
def_delegators :attributes, :rss_url, :updated, :title,
|
9
|
+
:created, :slug, :id, :resource_uri
|
10
|
+
|
11
|
+
def initialize(attributes)
|
12
|
+
@attributes = OpenStruct.new(attributes)
|
13
|
+
end
|
14
|
+
end
|
data/lib/kippt/lists.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require "kippt/connection"
|
2
|
+
require "kippt/collection_resource"
|
3
|
+
require "kippt/list_collection"
|
4
|
+
require "kippt/list"
|
5
|
+
|
6
|
+
class Kippt::Lists
|
7
|
+
include Kippt::CollectionResource
|
8
|
+
|
9
|
+
def initialize(client)
|
10
|
+
@client = client
|
11
|
+
end
|
12
|
+
|
13
|
+
def object_class
|
14
|
+
Kippt::List
|
15
|
+
end
|
16
|
+
|
17
|
+
def collection_class
|
18
|
+
Kippt::ListCollection
|
19
|
+
end
|
20
|
+
|
21
|
+
def base_uri
|
22
|
+
"lists"
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
{"url_domain": "karrisaarinen.com", "updated": "1335090586", "is_starred": false, "title": "Karri Saarinen", "url": "http://karrisaarinen.com/", "notes": "My favorite designer-bro.", "created": "1335090567", "list": "/api/lists/44525/", "id": 1589450, "resource_uri": "/api/clips/1589450/"}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"meta": {"next": null, "total_count": 1, "previous": null, "limit": 20, "offset": 0}, "objects": [{"url_domain": "karrisaarinen.com", "updated": "1335090586", "is_starred": false, "title": "Karri Saarinen", "url": "http://karrisaarinen.com/", "notes": "Cool site, bro", "created": "1335090567", "list": "/api/lists/44525/", "id": 1589450, "resource_uri": "/api/clips/1589450/"}]}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"rss_url": "https://kippt.com/feed/vesan/0VLW0SSjVBRJ1oQEpe9OmSf1q2Q6lvq/inspiration", "updated": "1335090586", "title": "Inspiration", "created": "1335090037", "slug": "inspiration", "id": 10, "resource_uri": "/api/lists/10/"}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"meta": {"next": null, "total_count": 4, "previous": null, "limit": 20, "offset": 0}, "objects": [{"rss_url": "https://kippt.com/feed/vesan/0VLW0SSjVBRJ1oQEpe9OmSf1q2Q6lvq/inspiration", "updated": "1335090586", "title": "Inspiration", "created": "1335090037", "slug": "inspiration", "id": 10, "resource_uri": "/api/lists/10/"}, {"rss_url": "https://kippt.com/feed/vesan/0VLW0SSjVBRJ1oQEpe9OmSf1q2Q6lvq/moikka-vesa", "updated": "1319441679", "title": "Moikka Vesa!", "created": "1319435972", "slug": "moikka-vesa", "id": 134, "resource_uri": "/api/lists/134/"}, {"rss_url": "https://kippt.com/feed/vesan/0VLW0SSjVBRJ1oQEpe9OmSf1q2Q6lvq/read-later", "updated": "1319434196", "title": "Read Later", "created": "1319434196", "slug": "read-later", "id": 133, "resource_uri": "/api/lists/133/"}, {"rss_url": "https://kippt.com/feed/vesan/0VLW0SSjVBRJ1oQEpe9OmSf1q2Q6lvq/inbox", "updated": "1319434196", "title": "Inbox", "created": "1319434196", "slug": "inbox", "id": 132, "resource_uri": "/api/lists/132/"}]}
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "kippt/account"
|
3
|
+
|
4
|
+
describe Kippt::Account do
|
5
|
+
describe "#token" do
|
6
|
+
subject { Kippt::Account.new("api_token" => "12345") }
|
7
|
+
|
8
|
+
it "gets set" do
|
9
|
+
subject.token.should eq "12345"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "#api_token" do
|
14
|
+
subject { Kippt::Account.new("api_token" => "12345") }
|
15
|
+
|
16
|
+
it "is aliased to token" do
|
17
|
+
subject.api_token.should eq "12345"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "#username" do
|
22
|
+
subject { Kippt::Account.new("username" => "bob") }
|
23
|
+
|
24
|
+
it "gets set" do
|
25
|
+
subject.username.should eq "bob"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "kippt/client"
|
3
|
+
|
4
|
+
describe Kippt::Client do
|
5
|
+
describe "#initialize" do
|
6
|
+
context "when there is no username" do
|
7
|
+
it "raises error"
|
8
|
+
end
|
9
|
+
|
10
|
+
context "when there is no password or token" do
|
11
|
+
it "raises error"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "#lists" do
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "crack/json"
|
3
|
+
require "kippt/clip_collection"
|
4
|
+
|
5
|
+
describe Kippt::ClipCollection do
|
6
|
+
let(:data) { Crack::JSON.parse(fixture("clips.json").read) }
|
7
|
+
subject { Kippt::ClipCollection.new(data) }
|
8
|
+
|
9
|
+
it_behaves_like "collection"
|
10
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "crack/json"
|
3
|
+
require "kippt/clip_collection"
|
4
|
+
|
5
|
+
describe Kippt::ClipCollection do
|
6
|
+
let(:data) { Crack::JSON.parse(fixture("clip.json").read) }
|
7
|
+
subject { Kippt::Clip.new(data) }
|
8
|
+
|
9
|
+
describe "attribute accessors" do
|
10
|
+
it "delegates to attributes" do
|
11
|
+
[:url_domain, :updated, :is_starred,
|
12
|
+
:title, :url, :notes, :created, :list, :id,
|
13
|
+
:resource_uri].each do |attribute_name|
|
14
|
+
subject.send(attribute_name).should eq data[attribute_name.to_s]
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "#save" do
|
20
|
+
let(:collection_resource) { Kippt::Client.new(valid_user_credentials).clips }
|
21
|
+
subject { Kippt::Clip.new({}, collection_resource) }
|
22
|
+
|
23
|
+
context "with valid parameters" do
|
24
|
+
it "sends POST request to server" do
|
25
|
+
collection_resource.should_receive(:save_object).with(subject).and_return({})
|
26
|
+
subject.url = "http://kiskolabs.com"
|
27
|
+
subject.save
|
28
|
+
end
|
29
|
+
|
30
|
+
it "returns true" do
|
31
|
+
collection_resource.stub(:save_object).and_return(
|
32
|
+
{success: true})
|
33
|
+
subject.save.should be_true
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
context "with invalid parameters" do
|
38
|
+
before do
|
39
|
+
collection_resource.stub(:save_object).and_return({success: false, error_message: "No url."})
|
40
|
+
end
|
41
|
+
|
42
|
+
it "sets an error messages" do
|
43
|
+
subject.save
|
44
|
+
subject.errors.should eq ["No url."]
|
45
|
+
end
|
46
|
+
|
47
|
+
it "returns false" do
|
48
|
+
subject.save.should be_false
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,144 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "kippt/clips"
|
3
|
+
|
4
|
+
describe Kippt::Clips do
|
5
|
+
describe "#all" do
|
6
|
+
subject { Kippt::Client.new(valid_user_credentials).clips }
|
7
|
+
|
8
|
+
it "returns ClipCollection" do
|
9
|
+
stub_get("/clips").
|
10
|
+
to_return(:status => 200, :body => fixture("clips.json"))
|
11
|
+
clips = subject.all
|
12
|
+
clips.is_a? Kippt::ClipCollection
|
13
|
+
end
|
14
|
+
|
15
|
+
it "accepts limit and offset options" do
|
16
|
+
stub_get("/clips?limit=10&offset=100").
|
17
|
+
to_return(:status => 200, :body => fixture("clips.json"))
|
18
|
+
clips = subject.all(:limit => 10, :offset => 100)
|
19
|
+
end
|
20
|
+
|
21
|
+
context "when passed unrecognized arguments" do
|
22
|
+
it "raises error" do
|
23
|
+
lambda {
|
24
|
+
subject.all(:foobar => true)
|
25
|
+
}.should raise_error(
|
26
|
+
ArgumentError, "Unrecognized argument: foobar")
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "#[]" do
|
32
|
+
subject { Kippt::Client.new(valid_user_credentials).clips }
|
33
|
+
|
34
|
+
it "fetches single list" do
|
35
|
+
stub_get("/clips/10").
|
36
|
+
to_return(:status => 200, :body => fixture("list.json"))
|
37
|
+
subject[10].id.should eq 10
|
38
|
+
end
|
39
|
+
|
40
|
+
it "returns Kippt::Clip" do
|
41
|
+
stub_get("/clips/10").
|
42
|
+
to_return(:status => 200, :body => fixture("list.json"))
|
43
|
+
subject[10].should be_a(Kippt::Clip)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe "#build" do
|
48
|
+
subject { Kippt::Client.new(valid_user_credentials).clips }
|
49
|
+
|
50
|
+
it "returns Kippt::Clip" do
|
51
|
+
subject.build.should be_a(Kippt::Clip)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe "#search" do
|
56
|
+
subject { Kippt::Client.new(valid_user_credentials).clips }
|
57
|
+
|
58
|
+
describe "parameters" do
|
59
|
+
it "accepts String" do
|
60
|
+
stub_get("/search/clips?q=bunny").
|
61
|
+
to_return(:status => 200, :body => fixture("clips.json"))
|
62
|
+
subject.search("bunny")
|
63
|
+
end
|
64
|
+
|
65
|
+
it "accepts Hash" do
|
66
|
+
stub_get("/search/clips?q=bunny&list=4&is_starred=true").
|
67
|
+
to_return(:status => 200, :body => fixture("clips.json"))
|
68
|
+
subject.search(:q => "bunny", :list => 4, :is_starred => true)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
it "returns ClipCollection" do
|
73
|
+
stub_get("/search/clips?q=bunny").
|
74
|
+
to_return(:status => 200, :body => fixture("clips.json"))
|
75
|
+
clips = subject.search("bunny")
|
76
|
+
clips.is_a? Kippt::ClipCollection
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
describe "#save_object" do
|
81
|
+
subject { Kippt::Client.new(valid_user_credentials).clips }
|
82
|
+
|
83
|
+
context "successful request" do
|
84
|
+
it "returns hash with success boolean" do
|
85
|
+
stub_request(:post, "https://kippt.com/api/clips").
|
86
|
+
with(:body => "{\"url\":\"http://kiskolabs.com\"}").
|
87
|
+
to_return(:status => 200, :body => "{}", :headers => {})
|
88
|
+
|
89
|
+
clip = Kippt::Clip.new(:url => "http://kiskolabs.com")
|
90
|
+
response = subject.save_object(clip)
|
91
|
+
response[:success].should be_true
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
context "unsuccessful request" do
|
96
|
+
it "returns hash with success boolean and error message" do
|
97
|
+
stub_request(:post, "https://kippt.com/api/clips").
|
98
|
+
with(:body => "{\"url\":\"http://kiskolabs.com\"}").
|
99
|
+
to_return(:status => 400, :body => "{\"message\": \"No good.\"}", :headers => {})
|
100
|
+
|
101
|
+
clip = Kippt::Clip.new(:url => "http://kiskolabs.com")
|
102
|
+
response = subject.save_object(clip)
|
103
|
+
response[:success].should be_false
|
104
|
+
response[:error_message].should eq "No good."
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
context "when object doesn't have an id" do
|
109
|
+
it "POSTs new resource to the API" do
|
110
|
+
stub_request(:post, "https://kippt.com/api/clips").
|
111
|
+
with(:body => "{\"url\":\"http://kiskolabs.com\"}").
|
112
|
+
to_return(:status => 200, :body => "{}", :headers => {})
|
113
|
+
|
114
|
+
clip = Kippt::Clip.new(:url => "http://kiskolabs.com")
|
115
|
+
subject.save_object(clip)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
context "when object has an id" do
|
120
|
+
it "PUTs new version of the resource to the API" do
|
121
|
+
stub_request(:put, "https://kippt.com/api/clips/22").
|
122
|
+
with(:body => "{\"url\":\"http://kiskolabs.com\"}").
|
123
|
+
to_return(:status => 200, :body => "{}", :headers => {})
|
124
|
+
|
125
|
+
clip = Kippt::Clip.new(:id => 22, :url => "http://kiskolabs.com")
|
126
|
+
subject.save_object(clip)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
describe "#destroy_resource" do
|
132
|
+
subject { Kippt::Client.new(valid_user_credentials).clips }
|
133
|
+
|
134
|
+
context "successful request" do
|
135
|
+
it "returns boolean" do
|
136
|
+
stub_request(:delete, "https://kippt.com/api/clips/100").
|
137
|
+
to_return(:status => 200, :headers => {})
|
138
|
+
|
139
|
+
clip = Kippt::Clip.new(id: 100)
|
140
|
+
subject.destroy_resource(clip).should be_true
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "kippt/lists"
|
3
|
+
|
4
|
+
describe Kippt::Lists do
|
5
|
+
describe "#all" do
|
6
|
+
subject { Kippt::Client.new(valid_user_credentials).lists }
|
7
|
+
|
8
|
+
it "returns ListCollection" do
|
9
|
+
stub_get("/lists").
|
10
|
+
to_return(:status => 200, :body => fixture("lists.json"))
|
11
|
+
lists = subject.all
|
12
|
+
lists.is_a? Kippt::ListCollection
|
13
|
+
end
|
14
|
+
|
15
|
+
it "accepts limit and offset options" do
|
16
|
+
stub_get("/lists?limit=10&offset=100").
|
17
|
+
to_return(:status => 200, :body => fixture("lists.json"))
|
18
|
+
lists = subject.all(:limit => 10, :offset => 100)
|
19
|
+
end
|
20
|
+
|
21
|
+
context "when passed unrecognized arguments" do
|
22
|
+
it "raises error" do
|
23
|
+
lambda {
|
24
|
+
subject.all(:foobar => true)
|
25
|
+
}.should raise_error(
|
26
|
+
ArgumentError, "Unrecognized argument: foobar")
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "#[]" do
|
32
|
+
subject { Kippt::Client.new(valid_user_credentials).lists }
|
33
|
+
|
34
|
+
it "fetches single list" do
|
35
|
+
stub_get("/lists/10").
|
36
|
+
to_return(:status => 200, :body => fixture("list.json"))
|
37
|
+
subject[10].id.should eq 10
|
38
|
+
end
|
39
|
+
|
40
|
+
it "returns Kippt::List" do
|
41
|
+
stub_get("/lists/10").
|
42
|
+
to_return(:status => 200, :body => fixture("list.json"))
|
43
|
+
subject[10].should be_a(Kippt::List)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe "#collection_from_url" do
|
48
|
+
subject { Kippt::Client.new(valid_user_credentials).lists }
|
49
|
+
|
50
|
+
it "returns a new ListCollection" do
|
51
|
+
stub_get("/lists/?limit=20&offset=20").
|
52
|
+
to_return(:status => 200, :body => fixture("lists.json"))
|
53
|
+
list = subject.collection_from_url("/api/lists/?limit=20&offset=20")
|
54
|
+
list.should be_a(Kippt::ListCollection)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
require "kippt"
|
2
|
+
require "rspec"
|
3
|
+
require "webmock/rspec"
|
4
|
+
|
5
|
+
def stub_get(url)
|
6
|
+
stub_request(:get, kippt_url(url))
|
7
|
+
end
|
8
|
+
|
9
|
+
def kippt_url(url)
|
10
|
+
"https://kippt.com/api#{url}"
|
11
|
+
end
|
12
|
+
|
13
|
+
def valid_user_credentials
|
14
|
+
{:username => "bob", :token => "bobstoken"}
|
15
|
+
end
|
16
|
+
|
17
|
+
def fixture(file)
|
18
|
+
fixture_path = File.expand_path("../fixtures", __FILE__)
|
19
|
+
File.new(fixture_path + '/' + file)
|
20
|
+
end
|
21
|
+
|
22
|
+
shared_examples_for "collection" do
|
23
|
+
describe "#total_count" do
|
24
|
+
it "returns total count of lists" do
|
25
|
+
subject.total_count.should eq data["meta"]["total_count"]
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe "#offset" do
|
30
|
+
it "returns offset of the results" do
|
31
|
+
subject.offset.should eq 0
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe "#limit" do
|
36
|
+
it "returns limit of the results" do
|
37
|
+
subject.limit.should eq 20
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
metadata
ADDED
@@ -0,0 +1,170 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: kippt
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Vesa Vänskä
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-04-29 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: faraday
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 0.7.6
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 0.7.6
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: faraday_middleware
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: 0.8.7
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 0.8.7
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: yajl-ruby
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ~>
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 1.1.0
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 1.1.0
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: rspec
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ~>
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: 2.9.0
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ~>
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: 2.9.0
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: webmock
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ~>
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: 1.8.6
|
86
|
+
type: :development
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ~>
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: 1.8.6
|
94
|
+
description: Client library for using Kippt.com API
|
95
|
+
email:
|
96
|
+
- vesa@vesavanska.com
|
97
|
+
executables: []
|
98
|
+
extensions: []
|
99
|
+
extra_rdoc_files: []
|
100
|
+
files:
|
101
|
+
- .gitignore
|
102
|
+
- .rspec
|
103
|
+
- Gemfile
|
104
|
+
- LICENSE
|
105
|
+
- README.md
|
106
|
+
- Rakefile
|
107
|
+
- kippt.gemspec
|
108
|
+
- lib/kippt.rb
|
109
|
+
- lib/kippt/account.rb
|
110
|
+
- lib/kippt/client.rb
|
111
|
+
- lib/kippt/clip.rb
|
112
|
+
- lib/kippt/clip_collection.rb
|
113
|
+
- lib/kippt/clips.rb
|
114
|
+
- lib/kippt/collection.rb
|
115
|
+
- lib/kippt/collection_resource.rb
|
116
|
+
- lib/kippt/connection.rb
|
117
|
+
- lib/kippt/list.rb
|
118
|
+
- lib/kippt/list_collection.rb
|
119
|
+
- lib/kippt/lists.rb
|
120
|
+
- lib/kippt/version.rb
|
121
|
+
- spec/fixtures/clip.json
|
122
|
+
- spec/fixtures/clips.json
|
123
|
+
- spec/fixtures/list.json
|
124
|
+
- spec/fixtures/lists.json
|
125
|
+
- spec/kippt/account_spec.rb
|
126
|
+
- spec/kippt/client_spec.rb
|
127
|
+
- spec/kippt/clip_collection_spec.rb
|
128
|
+
- spec/kippt/clip_spec.rb
|
129
|
+
- spec/kippt/clips_spec.rb
|
130
|
+
- spec/kippt/list_collection_spec.rb
|
131
|
+
- spec/kippt/lists_spec.rb
|
132
|
+
- spec/spec_helper.rb
|
133
|
+
homepage: ''
|
134
|
+
licenses: []
|
135
|
+
post_install_message:
|
136
|
+
rdoc_options: []
|
137
|
+
require_paths:
|
138
|
+
- lib
|
139
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
140
|
+
none: false
|
141
|
+
requirements:
|
142
|
+
- - ! '>='
|
143
|
+
- !ruby/object:Gem::Version
|
144
|
+
version: '0'
|
145
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
146
|
+
none: false
|
147
|
+
requirements:
|
148
|
+
- - ! '>='
|
149
|
+
- !ruby/object:Gem::Version
|
150
|
+
version: '0'
|
151
|
+
requirements: []
|
152
|
+
rubyforge_project:
|
153
|
+
rubygems_version: 1.8.21
|
154
|
+
signing_key:
|
155
|
+
specification_version: 3
|
156
|
+
summary: Client library for using Kippt.com API
|
157
|
+
test_files:
|
158
|
+
- spec/fixtures/clip.json
|
159
|
+
- spec/fixtures/clips.json
|
160
|
+
- spec/fixtures/list.json
|
161
|
+
- spec/fixtures/lists.json
|
162
|
+
- spec/kippt/account_spec.rb
|
163
|
+
- spec/kippt/client_spec.rb
|
164
|
+
- spec/kippt/clip_collection_spec.rb
|
165
|
+
- spec/kippt/clip_spec.rb
|
166
|
+
- spec/kippt/clips_spec.rb
|
167
|
+
- spec/kippt/list_collection_spec.rb
|
168
|
+
- spec/kippt/lists_spec.rb
|
169
|
+
- spec/spec_helper.rb
|
170
|
+
has_rdoc:
|