gazette 0.1.2 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +23 -21
- data/VERSION +1 -1
- data/gazette.gemspec +6 -2
- data/lib/gazette.rb +3 -1
- data/lib/gazette/response.rb +0 -32
- data/lib/gazette/response/error.rb +18 -0
- data/lib/gazette/response/success.rb +32 -0
- data/spec/response/error_spec.rb +11 -0
- data/spec/response/success_spec.rb +6 -2
- metadata +7 -3
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Gazette
|
2
2
|
|
3
|
-
Gazette is a Ruby gem to interact with the [Instapaper API](http://www.instapaper.com/api). It
|
3
|
+
Gazette is a Ruby gem to interact with the [Instapaper API](http://www.instapaper.com/api). It implements all API features, including authentication and adding URLs to read later. Gazette operates over HTTP and HTTPS, and uses (Instapaper-preferred) HTTP basic authentication.
|
4
4
|
|
5
5
|
* [Github](http://github.com/Fluxx/gazette) - Browse source code, README, etc.
|
6
6
|
* [Yardoc](http://rubydoc.info/github/Fluxx/gazette/master/frames) - Documentation.
|
@@ -16,45 +16,47 @@ At your favorite shell:
|
|
16
16
|
|
17
17
|
## Usage
|
18
18
|
|
19
|
-
All interaction with the Instapaper API is done with an instance of `Gazette::Client
|
19
|
+
All interaction with the Instapaper API is done with an instance of `Gazette::Client`. The constructor requires one argument: the user's Instapaper email or username. The second argument is an optional hash, which can contain a `:password => "user_pass"` to pass the user's password, and/or `:https => true` if you would like to communicate with the Instapaper API over HTTPS.
|
20
20
|
|
21
21
|
@client = Gazette::Client.new("user@eample.com", :password => "seeecrets")
|
22
|
-
=> #<Gazette::Client:0x101f41cb0 @password=nil, @https=false, @username="user@eample.com", @options={}>
|
23
22
|
|
24
23
|
By default Gazette communicates with the Instapaper API over good 'ol HTTP. You are strongly encouraged to use HTTPS if at all possible.
|
25
24
|
|
26
|
-
|
27
25
|
### Authentication
|
28
26
|
|
29
|
-
With a client in hand, you can call `@client.authenticate` to authenticate the user's credentials. Per the API documentation, authentication is totally optional. It may be useful if you want to verify the credentials provided by a user, but is not a required step before adding URLs.
|
27
|
+
With a `@client` in hand, you can call `@client.authenticate` to authenticate the user's credentials. Per the API documentation, authentication is a totally optional. It may be useful if you want to verify the credentials provided by a user, but is not a required step before adding URLs.
|
30
28
|
|
31
29
|
>> @client.authenticate
|
32
|
-
=> #<Gazette::Response::Success:0x101f37260 @instapaper_title=nil, @content_location=nil>
|
33
|
-
|
34
|
-
### Responses
|
35
|
-
|
36
|
-
All valid responses to the Instapaper API return a `Gazette::Response::Success` object. All invalid response *raise* one of the following exceptions:
|
37
|
-
|
38
|
-
* `Gazette::Response::InvalidCredentials` - Invalid user credentials.
|
39
|
-
* `Gazette::Response::ServerError` - API encountered an error. Please try again later.
|
40
|
-
* `Gazette::Response::UnknownError` - Some other unknown error. File a bug...maybe.
|
41
|
-
|
42
|
-
Thus, for proper error checking, please `rescue` any/all of the above exceptions.
|
43
30
|
|
44
31
|
### Adding URLs
|
45
32
|
|
46
|
-
To add URLs to the client's Instapaper account, call `@client.add(
|
33
|
+
To add URLs to the client's Instapaper account, call `@client.add(url_string)`:
|
47
34
|
|
48
35
|
>> @client.add("http://patmaddox.com/blog/2010/5/9/a-response-to-unit-and-functional-tests-are-as-useful-as-100.html", :title => "How do you write 100% correct code?", :selection => "How do you guarantee an application's correctness?")
|
49
|
-
=> #<Gazette::Response::Success:0x101f17a00 @instapaper_title="\"How do you write 100% correct code?\"", @content_location="http://patmaddox.com/blog/2010/5/9/a-response-to-unit-and-functional-tests-are-as-useful-as-100.html">
|
50
36
|
|
51
|
-
The `#add` method
|
37
|
+
The `#add` method's first parameter, a string of the URL you want to add, is required. The 2nd parameter is an optional hash, which can contain any of the following. See the [Instapaper API documentation](http://www.instapaper.com/api) for details:
|
52
38
|
|
53
39
|
* `:title => "string"`
|
54
40
|
* `:selection => "string"`
|
55
|
-
* `:redirect => :close` which attempts to close the window after a short delay.
|
56
|
-
* `:jsonp => "string"`
|
41
|
+
* `:redirect => :close` - Response body contains HTML which displays a "Saved!" message with and attempts to close the browser window after a short delay.
|
42
|
+
* `:jsonp => "string"` - Response body contains JSON response with the specified callback function.
|
43
|
+
|
44
|
+
### Responses
|
45
|
+
|
46
|
+
If a successful API call was made, Gazette returns an instance of `Gazette::Response::Success`. Responses have the following instance methods to retrieve
|
47
|
+
values returned by the Instapaper API:
|
48
|
+
|
49
|
+
* `#content_location` Saved URL of the newly created item.
|
50
|
+
* `#instapaper_title` Saved title of the newly created item.
|
51
|
+
* `#body` Body of the response from the API request. Useful when the `:redirect` or `:jsonp` option is used in a `@client.add` call (see above).
|
52
|
+
|
53
|
+
Invalid responses from the API cause Gazette to *raise* a new exception. All exceptions are subclasses of `Gazette::Response::Error`:
|
54
|
+
|
55
|
+
* `Gazette::Response::InvalidCredentials` - Invalid user credentials.
|
56
|
+
* `Gazette::Response::ServerError` - API encountered an error. Please try again later.
|
57
|
+
* `Gazette::Response::UnknownError` - Some other unknown error. File a bug...maybe.
|
57
58
|
|
59
|
+
Thus, for proper error checking, please `rescue Gazette::Response::Error` and/or the other specific exceptions.
|
58
60
|
|
59
61
|
## Note on Patches/Pull Requests
|
60
62
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.2.0
|
data/gazette.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{gazette}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.2.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Jeff Pollard"]
|
12
|
-
s.date = %q{2010-
|
12
|
+
s.date = %q{2010-12-03}
|
13
13
|
s.description = %q{Simple Ruby wrapper gem to interact with the Instapaper API. Supports authenticate and add API methods, as well as https, jsonp and all other features of the API.}
|
14
14
|
s.email = %q{jeff.pollard@gmail.com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -29,9 +29,12 @@ Gem::Specification.new do |s|
|
|
29
29
|
"lib/gazette/api.rb",
|
30
30
|
"lib/gazette/client.rb",
|
31
31
|
"lib/gazette/response.rb",
|
32
|
+
"lib/gazette/response/error.rb",
|
33
|
+
"lib/gazette/response/success.rb",
|
32
34
|
"spec/client/add_spec.rb",
|
33
35
|
"spec/client/authenticate_spec.rb",
|
34
36
|
"spec/client/client_spec.rb",
|
37
|
+
"spec/response/error_spec.rb",
|
35
38
|
"spec/response/success_spec.rb",
|
36
39
|
"spec/spec.opts",
|
37
40
|
"spec/spec_helper.rb",
|
@@ -46,6 +49,7 @@ Gem::Specification.new do |s|
|
|
46
49
|
"spec/client/add_spec.rb",
|
47
50
|
"spec/client/authenticate_spec.rb",
|
48
51
|
"spec/client/client_spec.rb",
|
52
|
+
"spec/response/error_spec.rb",
|
49
53
|
"spec/response/success_spec.rb",
|
50
54
|
"spec/spec_helper.rb"
|
51
55
|
]
|
data/lib/gazette.rb
CHANGED
data/lib/gazette/response.rb
CHANGED
@@ -2,38 +2,6 @@ module Gazette
|
|
2
2
|
# Container class for response from the Instapaper API.
|
3
3
|
# @author Jeff Pollard
|
4
4
|
class Response
|
5
|
-
# Successful response from the Instapaper API
|
6
|
-
# @author Jeff Pollard
|
7
|
-
class Success < Response
|
8
|
-
|
9
|
-
# Final saved URL of the content returned from the Instapaper API.
|
10
|
-
attr_reader :content_location
|
11
|
-
|
12
|
-
# Saved title of the content returned from the Instapaper API.
|
13
|
-
attr_reader :instapaper_title
|
14
|
-
|
15
|
-
# Create a new Success object out of a net/http response.
|
16
|
-
def initialize(response)
|
17
|
-
unless response.is_a?(Net::HTTPResponse)
|
18
|
-
# Require a net/http response object
|
19
|
-
raise ArgumentError.new("Argument must be a Net::HTTPResponse object")
|
20
|
-
end
|
21
|
-
|
22
|
-
# Build our ivars from the headers
|
23
|
-
@content_location = response.header['Content-Location']
|
24
|
-
@instapaper_title = response.header['X-Instapaper-Title']
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
# Response raised of the Instapaper returned a response indicating invalid user
|
29
|
-
# credentials.
|
30
|
-
class InvalidCredentials < Exception; end
|
31
|
-
|
32
|
-
# Retponse raised if the Instapaper returned a server error (500).
|
33
|
-
class ServerError < Exception; end
|
34
|
-
|
35
|
-
# Response returned if there was some other type of unknown error.
|
36
|
-
class UnknownError < Exception; end
|
37
5
|
|
38
6
|
end
|
39
7
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Gazette
|
2
|
+
class Response
|
3
|
+
|
4
|
+
# Superclass for all Gazette::Errors
|
5
|
+
class Error < Exception; end
|
6
|
+
|
7
|
+
# Response raised of the Instapaper returned a response indicating invalid user
|
8
|
+
# credentials.
|
9
|
+
class InvalidCredentials < Error; end
|
10
|
+
|
11
|
+
# Retponse raised if the Instapaper returned a server error (500).
|
12
|
+
class ServerError < Error; end
|
13
|
+
|
14
|
+
# Response returned if there was some other type of unknown error.
|
15
|
+
class UnknownError < Error; end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Gazette
|
2
|
+
class Response
|
3
|
+
|
4
|
+
# Successful response from the Instapaper API
|
5
|
+
# @author Jeff Pollard
|
6
|
+
class Success < Response
|
7
|
+
|
8
|
+
# Final saved URL of the content returned from the Instapaper API.
|
9
|
+
attr_reader :content_location
|
10
|
+
|
11
|
+
# Saved title of the content returned from the Instapaper API.
|
12
|
+
attr_reader :instapaper_title
|
13
|
+
|
14
|
+
# The body returned by the Instapaper API
|
15
|
+
attr_reader :body
|
16
|
+
|
17
|
+
# Create a new Success object out of a net/http response.
|
18
|
+
def initialize(response)
|
19
|
+
unless response.is_a?(Net::HTTPResponse)
|
20
|
+
# Require a net/http response object
|
21
|
+
raise ArgumentError.new("Argument must be a Net::HTTPResponse object")
|
22
|
+
end
|
23
|
+
|
24
|
+
# Build our ivars from the response and headers
|
25
|
+
@body = response.body
|
26
|
+
@content_location = response.header['Content-Location']
|
27
|
+
@instapaper_title = response.header['X-Instapaper-Title']
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
describe Gazette::Response::Error do
|
4
|
+
|
5
|
+
it "is the superclass of InvalidCredentials, ServerError and UnknownError errors" do
|
6
|
+
Gazette::Response::InvalidCredentials.superclass.should == Gazette::Response::Error
|
7
|
+
Gazette::Response::ServerError.superclass.should == Gazette::Response::Error
|
8
|
+
Gazette::Response::UnknownError.superclass.should == Gazette::Response::Error
|
9
|
+
end
|
10
|
+
|
11
|
+
end
|
@@ -2,7 +2,7 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
|
2
2
|
|
3
3
|
describe Gazette::Response::Success do
|
4
4
|
before(:each) do
|
5
|
-
@response = mock("response", :is_a? => true, :header => {})
|
5
|
+
@response = mock("response", :is_a? => true, :header => {}, :body => "200")
|
6
6
|
end
|
7
7
|
|
8
8
|
it "raises an argument error unless the first argument is a Net::HTTPResponse object" do
|
@@ -20,6 +20,10 @@ describe Gazette::Response::Success do
|
|
20
20
|
Gazette::Response::Success.new(@response).instapaper_title.should be_nil
|
21
21
|
end
|
22
22
|
|
23
|
+
it "has an body attribute" do
|
24
|
+
Gazette::Response::Success.new(@response).body.should == "200"
|
25
|
+
end
|
26
|
+
|
23
27
|
it "sets content_location if the 'Content-Location' header is present" do
|
24
28
|
@response.stub!(:header).and_return({'Content-Location' => 'http://www.example.com/'})
|
25
29
|
Gazette::Response::Success.new(@response).content_location.should == 'http://www.example.com/'
|
@@ -29,5 +33,5 @@ describe Gazette::Response::Success do
|
|
29
33
|
@response.stub!(:header).and_return({'X-Instapaper-Title' => 'nonse'})
|
30
34
|
Gazette::Response::Success.new(@response).instapaper_title.should == 'nonse'
|
31
35
|
end
|
32
|
-
|
36
|
+
|
33
37
|
end
|
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
-
- 1
|
8
7
|
- 2
|
9
|
-
|
8
|
+
- 0
|
9
|
+
version: 0.2.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Jeff Pollard
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-
|
17
|
+
date: 2010-12-03 00:00:00 -08:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -65,9 +65,12 @@ files:
|
|
65
65
|
- lib/gazette/api.rb
|
66
66
|
- lib/gazette/client.rb
|
67
67
|
- lib/gazette/response.rb
|
68
|
+
- lib/gazette/response/error.rb
|
69
|
+
- lib/gazette/response/success.rb
|
68
70
|
- spec/client/add_spec.rb
|
69
71
|
- spec/client/authenticate_spec.rb
|
70
72
|
- spec/client/client_spec.rb
|
73
|
+
- spec/response/error_spec.rb
|
71
74
|
- spec/response/success_spec.rb
|
72
75
|
- spec/spec.opts
|
73
76
|
- spec/spec_helper.rb
|
@@ -106,5 +109,6 @@ test_files:
|
|
106
109
|
- spec/client/add_spec.rb
|
107
110
|
- spec/client/authenticate_spec.rb
|
108
111
|
- spec/client/client_spec.rb
|
112
|
+
- spec/response/error_spec.rb
|
109
113
|
- spec/response/success_spec.rb
|
110
114
|
- spec/spec_helper.rb
|