instapaper 0.3.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.md +1 -1
  3. data/README.md +66 -37
  4. data/instapaper.gemspec +21 -30
  5. data/lib/instapaper/{client/account.rb → api/accounts.rb} +5 -5
  6. data/lib/instapaper/api/bookmarks.rb +77 -0
  7. data/lib/instapaper/{client/folder.rb → api/folders.rb} +12 -11
  8. data/lib/instapaper/api/highlights.rb +33 -0
  9. data/lib/instapaper/api/oauth.rb +18 -0
  10. data/lib/instapaper/api.rb +15 -0
  11. data/lib/instapaper/bookmark.rb +21 -0
  12. data/lib/instapaper/bookmark_list.rb +20 -0
  13. data/lib/instapaper/client.rb +43 -29
  14. data/lib/instapaper/credentials.rb +12 -0
  15. data/lib/instapaper/error.rb +115 -0
  16. data/lib/instapaper/folder.rb +17 -0
  17. data/lib/instapaper/highlight.rb +16 -0
  18. data/lib/instapaper/http/headers.rb +45 -0
  19. data/lib/instapaper/http/qline_parser.rb +9 -0
  20. data/lib/instapaper/http/request.rb +41 -0
  21. data/lib/instapaper/http/response.rb +65 -0
  22. data/lib/instapaper/http/utils.rb +70 -0
  23. data/lib/instapaper/user.rb +14 -0
  24. data/lib/instapaper/version.rb +1 -1
  25. data/lib/instapaper.rb +0 -25
  26. metadata +70 -211
  27. data/.gemtest +0 -0
  28. data/.gitignore +0 -11
  29. data/.rspec +0 -3
  30. data/.travis.yml +0 -8
  31. data/.yardopts +0 -3
  32. data/Gemfile +0 -7
  33. data/Rakefile +0 -13
  34. data/lib/faraday/response/raise_http_1xxx.rb +0 -65
  35. data/lib/instapaper/authentication.rb +0 -32
  36. data/lib/instapaper/client/bookmark.rb +0 -81
  37. data/lib/instapaper/client/user.rb +0 -19
  38. data/lib/instapaper/configuration.rb +0 -88
  39. data/lib/instapaper/connection.rb +0 -35
  40. data/lib/instapaper/request.rb +0 -22
  41. data/spec/faraday/response_spec.rb +0 -22
  42. data/spec/fixtures/access_token.qline +0 -1
  43. data/spec/fixtures/bookmarks_add.json +0 -1
  44. data/spec/fixtures/bookmarks_archive.json +0 -1
  45. data/spec/fixtures/bookmarks_get_text.txt +0 -299
  46. data/spec/fixtures/bookmarks_list.json +0 -5
  47. data/spec/fixtures/bookmarks_move.json +0 -1
  48. data/spec/fixtures/bookmarks_star.json +0 -1
  49. data/spec/fixtures/bookmarks_unarchive.json +0 -1
  50. data/spec/fixtures/bookmarks_unstar.json +0 -1
  51. data/spec/fixtures/bookmarks_update_read_progress.json +0 -1
  52. data/spec/fixtures/folders_add.json +0 -1
  53. data/spec/fixtures/folders_delete.json +0 -1
  54. data/spec/fixtures/folders_list.json +0 -1
  55. data/spec/fixtures/folders_set_order.json +0 -1
  56. data/spec/fixtures/invalid_credentials.qline +0 -1
  57. data/spec/fixtures/verify_credentials.json +0 -1
  58. data/spec/instapaper/client/account_spec.rb +0 -27
  59. data/spec/instapaper/client/bookmark_spec.rb +0 -234
  60. data/spec/instapaper/client/folder_spec.rb +0 -89
  61. data/spec/instapaper/client/user_spec.rb +0 -36
  62. data/spec/instapaper/client_spec.rb +0 -65
  63. data/spec/instapaper_spec.rb +0 -85
  64. data/spec/spec_helper.rb +0 -52
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: f676a4a48c703e736cfd38eb18782f59695b96a90f161dceef13ebdc3c2a59cb
4
+ data.tar.gz: 7578b717fbc477c7b1607ad66fbf71474c9ab74d6feaf2732cf01e91372499cd
5
+ SHA512:
6
+ metadata.gz: b0bb55c79906debe49a45b95413ede8d85de5bb6f583d7a51b9ff3fda0795f0e4342eee24da19ddd24360d989c251c3946bd58b473d4256011c480ccaa3b632e
7
+ data.tar.gz: 540559d498d6a4d8dcddbfa1f48ee8f19ab7bcb4df03fd3331cccb96c8642f3cfc28bcfa1fe604f5bcbefce2be3ccc054ca7998d656b9b85e63794b96b9f9c30
data/LICENSE.md CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2011 Steve Agalloco
1
+ Copyright (c) 2015 Steve Agalloco
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -1,6 +1,15 @@
1
1
  # Instapaper
2
2
 
3
- Instapaper is a ruby wrapper for interacting with [Instapaper's Full Developer API](http://www.instapaper.com/api/full). Note that access to the Full API is restricted to Instapaper subscribers only.
3
+ [![Gem Version](http://img.shields.io/gem/v/instapaper.svg)][gem]
4
+ [![Build Status](http://img.shields.io/travis/stve/instapaper.svg)][travis]
5
+ [![Code Climate](https://img.shields.io/codeclimate/maintainability/stve/instapaper.svg)][codeclimate]
6
+
7
+ [gem]: https://rubygems.org/gems/instapaper
8
+ [travis]: https://travis-ci.org/stve/instapaper
9
+ [codeclimate]: https://codeclimate.com/github/stve/instapaper
10
+
11
+
12
+ Instapaper is a ruby wrapper for interacting with [Instapaper's Full API](https://www.instapaper.com/api/full). Note that access to the Full API is restricted to Instapaper subscribers only.
4
13
 
5
14
  ## Installation
6
15
 
@@ -8,16 +17,28 @@ Instapaper is a ruby wrapper for interacting with [Instapaper's Full Developer A
8
17
 
9
18
  ## Usage
10
19
 
11
- Instapaper offers full support for all methods exposed through the Full API. Note that Instapaer does not support the request-token/authorize workflow. To obtain an access token, use the `access_token` method.
20
+ This library offers full support for all methods exposed through Instapaper's Full API. Note that Instapaper's API does not support the request-token/authorize workflow. To obtain an access token, use the `access_token` method.
21
+
22
+ ## Changes in 1.0.0
23
+
24
+ If you've used earlier versions of this library, a lot has changed in version `1.x`. While not a total rewrite, I've changed a number of things based on my experience writing API libraries:
25
+
26
+ * swapped out Faraday for http.rb
27
+ * responses now return custom classes instead of Hashie::Rash objects
28
+ * most API methods are more clear as to their behavior (i.e., `#star_bookmark` instead of just `#star`)
29
+ * module-based configuration and invocation has been removed, you'll now need to instantiate an `Instapaper::Client` instead (see usage below)
30
+ * Improved error handling
31
+ * Updates for version 1.1 of Instapaper's API
32
+ * Support for Highlights API
12
33
 
13
34
  ## Configuration
14
35
 
15
36
  ```ruby
16
- Instapaper.configure do |config|
17
- config.consumer_key = YOUR_CONSUMER_KEY
18
- config.consumer_secret = YOUR_CONSUMER_SECRET
19
- config.oauth_token = YOUR_OAUTH_TOKEN
20
- config.oauth_token_secret = YOUR_OAUTH_TOKEN_SECRET
37
+ client = Instapaper::Client.new do |client|
38
+ client.consumer_key = YOUR_CONSUMER_KEY
39
+ client.consumer_secret = YOUR_CONSUMER_SECRET
40
+ client.oauth_token = YOUR_OAUTH_TOKEN
41
+ client.oauth_token_secret = YOUR_OAUTH_TOKEN_SECRET
21
42
  end
22
43
  ```
23
44
 
@@ -26,13 +47,13 @@ end
26
47
  To obtain an access token via xAuth:
27
48
 
28
49
  ```ruby
29
- Instapaper.access_token(username, password)
50
+ client.access_token(username, password)
30
51
  ```
31
52
 
32
53
  You can also verify credentials once you have received tokens:
33
54
 
34
55
  ```ruby
35
- Instapaper.verify_credentials
56
+ client.verify_credentials
36
57
  ```
37
58
 
38
59
  ## Bookmark Operations
@@ -40,51 +61,56 @@ Instapaper.verify_credentials
40
61
  Retrieve a list of bookmarks:
41
62
 
42
63
  ```ruby
43
- Instapaper.bookmarks
64
+ client.bookmarks
44
65
  ```
45
66
 
46
67
  Add a new bookmark:
47
68
 
48
69
  ```ruby
49
- Instapaper.add_bookmark('http://someurl.com', :title => 'This is the title', :description => 'This is the description')
70
+ bookmark = {
71
+ title: 'This is the title',
72
+ description: 'This is the description',
73
+ }
74
+
75
+ client.add_bookmark('http://someurl.com', bookmark)
50
76
  ```
51
77
 
52
78
  Remove a bookmark:
53
79
 
54
80
  ```ruby
55
- Instapaper.delete_bookmark(bookmark_id)
81
+ client.delete_bookmark(bookmark_id)
56
82
  ```
57
83
 
58
84
  Update read progress:
59
85
 
60
86
  ```ruby
61
- Instapaper.update_read_progress(bookmark_id, 0.5)
87
+ client.update_read_progress(bookmark_id, 0.5)
62
88
  ```
63
89
 
64
90
  Star/Un-star a bookmark:
65
91
 
66
92
  ```ruby
67
- Instapaper.star(bookmark_id)
68
- Instapaper.unstar(bookmark_id)
93
+ client.star_bookmark(bookmark_id)
94
+ client.unstar_bookmark(bookmark_id)
69
95
  ```
70
96
 
71
97
  Archive/Un-archive a bookmark:
72
98
 
73
99
  ```ruby
74
- Instapaper.archive(bookmark_id)
75
- Instapaper.unarchive(bookmark_id)
100
+ client.archive_bookmark(bookmark_id)
101
+ client.unarchive_bookmark(bookmark_id)
76
102
  ```
77
103
 
78
104
  Move a bookmark to a folder:
79
105
 
80
106
  ```ruby
81
- Instapaper.move(bookmark_id, folder_id)
107
+ client.move_bookmark(bookmark_id, folder_id)
82
108
  ```
83
109
 
84
110
  Obtain the text of a bookmark:
85
111
 
86
112
  ```ruby
87
- Instapaper.text(bookmark_id)
113
+ client.get_text(bookmark_id)
88
114
  ```
89
115
 
90
116
  ## Folder Operations
@@ -93,48 +119,51 @@ Instapaper.text(bookmark_id)
93
119
  To obtain the list of folders:
94
120
 
95
121
  ```ruby
96
- Instapaper.folders
122
+ client.folders
97
123
  ```
98
124
 
99
125
  You can add by passing a name:
100
126
 
101
127
  ```ruby
102
- Instapaper.add_folder('eventmachine')
128
+ client.add_folder('eventmachine')
103
129
  ```
104
130
 
105
131
  And remove folders by referencing a folder by it's id.
106
132
 
107
133
  ```ruby
108
- Instapaper.delete_folder(folder_id)
134
+ client.delete_folder(folder_id)
109
135
  ```
110
136
 
111
137
  Lastly, the folders can be reordered:
112
138
 
113
139
  ```ruby
114
- Instapaper.set_order(['folder_id1:2','folder_id2:1'])
140
+ client.set_order(['folder_id1:2','folder_id2:1'])
115
141
  ```
116
142
 
117
- ## Restrictions
143
+ ## Highlights Operations
118
144
 
119
- Users without an Instapaper Subscription may only invoke the following calls:
145
+ Obtain highlights for a bookmark:
120
146
 
121
147
  ```ruby
122
- Instapaper.access_token
123
- Instapaper.verify_credentials
124
- Instapaper.add_bookmark
125
- Instapaper.folders
148
+ client.highlights(bookmark_id)
126
149
  ```
127
150
 
128
- ## <a name="build"></a>Build Status
129
- [![Build Status](https://secure.travis-ci.org/spagalloco/instapaper.png?branch=master)][travis]
151
+ Add a highlight for a bookmark:
130
152
 
131
- [travis]: http://travis-ci.org/spagalloco/instapaper
153
+ ```ruby
154
+ highlight = {
155
+ text: 'And so we beat on, boats against the current, borne back ceaselessly into the past.',
156
+ position: 20,
157
+ }
132
158
 
133
- ## <a name="dependencies"></a>Dependency Status
134
- [![Dependency Status](https://gemnasium.com/spagalloco/instapaper.png?travis)][gemnasium]
159
+ client.add_highlight(bookmark_id, highlight)
160
+ ```
135
161
 
136
- [gemnasium]: https://gemnasium.com/spagalloco/instapaper
162
+ Remove a highlight:
137
163
 
164
+ ```ruby
165
+ client.delete_highlight(highlight_id)
166
+ ```
138
167
 
139
168
  ## Documentation
140
169
 
@@ -146,10 +175,10 @@ Instapaper.folders
146
175
  * Make your feature addition or bug fix.
147
176
  * Add tests for it. This is important so I don't break it in a
148
177
  future version unintentionally.
149
- * Commit, do not mess with rakefile, version, or history.
178
+ * Commit, do not mess with Rakefile, gem version, or history.
150
179
  (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
151
180
  * Send me a pull request. Bonus points for topic branches.
152
181
 
153
182
  ## Copyright
154
183
 
155
- Copyright (c) 2011 Steve Agalloco. See [LICENSE](https://github.com/spagalloco/instapaper/blob/master/LICENSE.md) for details.
184
+ Copyright (c) 2015 Steve Agalloco. See [LICENSE](https://github.com/stve/instapaper/blob/master/LICENSE.md) for details.
data/instapaper.gemspec CHANGED
@@ -1,32 +1,23 @@
1
- # -*- encoding: utf-8 -*-
2
- $:.push File.expand_path("../lib", __FILE__)
3
- require "instapaper/version"
1
+ lib = File.expand_path('lib', __dir__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require 'instapaper/version'
4
4
 
5
- Gem::Specification.new do |gem|
6
- gem.name = "instapaper"
7
- gem.version = Instapaper::VERSION
8
-
9
- gem.author = "Steve Agalloco"
10
- gem.email = "steve.agalloco@gmail.com"
11
- gem.homepage = "https://github.com/spagalloco/instapaper"
12
- gem.summary = %q{Ruby Instapaper Client}
13
- gem.description = %q{Ruby Instapaper Client}
14
-
15
- gem.add_development_dependency('rake', '~> 0.9')
16
- gem.add_development_dependency('rdiscount', '~> 1.6')
17
- gem.add_development_dependency('rspec', '~> 2.7')
18
- gem.add_development_dependency('simplecov', '~> 0.5')
19
- gem.add_development_dependency('yard', '~> 0.7')
20
- gem.add_development_dependency('json', '>= 0')
21
- gem.add_development_dependency('webmock', '~> 1.7')
22
-
23
- gem.add_runtime_dependency('faraday_middleware', '~> 0.7')
24
- gem.add_runtime_dependency('multi_json', '~> 1')
25
- gem.add_runtime_dependency('rash', '~> 0.3')
26
- gem.add_runtime_dependency('simple_oauth', '~> 0.1')
27
-
28
- gem.files = `git ls-files`.split("\n")
29
- gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
30
- gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
31
- gem.require_paths = ["lib"]
5
+ Gem::Specification.new do |spec|
6
+ spec.add_dependency 'addressable', '~> 2.3'
7
+ spec.add_dependency 'http', '>= 2', '< 6'
8
+ spec.add_dependency 'multi_json', '~> 1'
9
+ spec.add_dependency 'simple_oauth', '~> 0.3'
10
+ spec.add_dependency 'virtus', '~> 1'
11
+ spec.add_development_dependency 'bundler'
12
+ spec.author = 'Steve Agalloco'
13
+ spec.description = "Ruby Client for Instapaper's Full API"
14
+ spec.email = 'steve.agalloco@gmail.com'
15
+ spec.files = %w[LICENSE.md README.md instapaper.gemspec] + Dir['lib/**/*.rb']
16
+ spec.homepage = 'https://github.com/stve/instapaper'
17
+ spec.licenses = %w[MIT]
18
+ spec.name = 'instapaper'
19
+ spec.require_paths = %w[lib]
20
+ spec.required_ruby_version = '>= 2.0.0'
21
+ spec.summary = 'Ruby Instapaper Client'
22
+ spec.version = Instapaper::VERSION
32
23
  end
@@ -1,13 +1,13 @@
1
+ require 'instapaper/user'
2
+
1
3
  module Instapaper
2
- class Client
4
+ module API
3
5
  # Defines methods related to accounts
4
- module Account
5
-
6
+ module Accounts
6
7
  # Returns the currently logged in user.
7
8
  def verify_credentials
8
- post('account/verify_credentials')
9
+ perform_post_with_object('/api/1.1/account/verify_credentials', {}, Instapaper::User)
9
10
  end
10
-
11
11
  end
12
12
  end
13
13
  end
@@ -0,0 +1,77 @@
1
+ require 'instapaper/bookmark'
2
+ require 'instapaper/bookmark_list'
3
+
4
+ module Instapaper
5
+ module API
6
+ # Defines methods related to bookmarks
7
+ module Bookmarks
8
+ # Lists the user's unread bookmarks, and can also synchronize reading positions.
9
+ # @option limit: Optional. A number between 1 and 500, default 25.
10
+ # @option folder_id: Optional. Possible values are unread (default), starred, archive, or a folder_id value from /api/1.1/folders/list.
11
+ # @option have: Optional. A concatenation of bookmark_id values that the client already has from the specified folder. See below.
12
+ # @option highlights: Optional. A '-' delimited list of highlight IDs that the client already has from the specified bookmarks.
13
+ def bookmarks(options = {})
14
+ perform_post_with_object('/api/1.1/bookmarks/list', options, Instapaper::BookmarkList)
15
+ end
16
+
17
+ # Updates the user's reading progress on a single article.
18
+ # @param bookmark_id [String] The id of the bookmark to update.
19
+ # @param progress [Float] The user's progress, as a floating-point number between 0.0 and 1.0, defined as the top edge of the user's current viewport, expressed as a percentage of the article's total length.
20
+ # @param progress_timestamp [Integer] The Unix timestamp value of the time that the progress was recorded.
21
+ def update_read_progress(bookmark_id, progress, progress_timestamp = Time.now)
22
+ perform_post_with_object('/api/1.1/bookmarks/update_read_progress', {bookmark_id: bookmark_id, progress: progress, progress_timestamp: progress_timestamp.to_i}, Instapaper::Bookmark)
23
+ end
24
+
25
+ # Adds a new unread bookmark to the user's account.
26
+ # @param url [String] The url of the bookmark.
27
+ def add_bookmark(url, options = {})
28
+ perform_post_with_object('/api/1.1/bookmarks/add', options.merge(url: url), Instapaper::Bookmark)
29
+ end
30
+
31
+ # Permanently deletes the specified bookmark.
32
+ # This is NOT the same as Archive. Please be clear to users if you're going to do this.
33
+ # @param bookmark_id [String] The id of the bookmark.
34
+ def delete_bookmark(bookmark_id)
35
+ perform_post_with_objects('/api/1.1/bookmarks/delete', {bookmark_id: bookmark_id}, Array)
36
+ end
37
+
38
+ # Stars the specified bookmark.
39
+ # @param bookmark_id [String] The id of the bookmark.
40
+ def star_bookmark(bookmark_id)
41
+ perform_post_with_object('/api/1.1/bookmarks/star', {bookmark_id: bookmark_id}, Instapaper::Bookmark)
42
+ end
43
+
44
+ # Un-stars the specified bookmark.
45
+ # @param bookmark_id [String] The id of the bookmark.
46
+ def unstar_bookmark(bookmark_id)
47
+ perform_post_with_object('/api/1.1/bookmarks/unstar', {bookmark_id: bookmark_id}, Instapaper::Bookmark)
48
+ end
49
+
50
+ # Moves the specified bookmark to the Archive.
51
+ # @param bookmark_id [String] The id of the bookmark.
52
+ def archive_bookmark(bookmark_id)
53
+ perform_post_with_object('/api/1.1/bookmarks/archive', {bookmark_id: bookmark_id}, Instapaper::Bookmark)
54
+ end
55
+
56
+ # Moves the specified bookmark to the top of the Unread folder.
57
+ # @param bookmark_id [String] The id of the bookmark.
58
+ def unarchive_bookmark(bookmark_id)
59
+ perform_post_with_object('/api/1.1/bookmarks/unarchive', {bookmark_id: bookmark_id}, Instapaper::Bookmark)
60
+ end
61
+
62
+ # Moves the specified bookmark to a user-created folder.
63
+ # @param bookmark_id [String] The id of the bookmark.
64
+ # @param folder_id [String] The id of the folder to move the bookmark to.
65
+ def move_bookmark(bookmark_id, folder_id)
66
+ perform_post_with_object('/api/1.1/bookmarks/move', {bookmark_id: bookmark_id, folder_id: folder_id}, Instapaper::Bookmark)
67
+ end
68
+
69
+ # Returns the specified bookmark's processed text-view HTML, which is
70
+ # always text/html encoded as UTF-8.
71
+ # @param bookmark_id [String] The id of the bookmark.
72
+ def get_text(bookmark_id)
73
+ perform_post_with_unparsed_response('/api/1.1/bookmarks/get_text', bookmark_id: bookmark_id)
74
+ end
75
+ end
76
+ end
77
+ end
@@ -1,34 +1,35 @@
1
+ require 'instapaper/folder'
2
+
1
3
  module Instapaper
2
- class Client
4
+ module API
3
5
  # Defines methods related to folders
4
- module Folder
5
-
6
- # List the account’s user-created folders.
6
+ module Folders
7
+ # List the account's user-created folders.
7
8
  # @note This only includes organizational folders and does not include RSS-feed folders or starred-subscription folders
8
9
  def folders
9
- post('folders/list')
10
+ perform_post_with_objects('/api/1.1/folders/list', {}, Instapaper::Folder)
10
11
  end
11
12
 
12
13
  # Creates an organizational folder.
13
14
  # @param title [String] The title of the folder to create
14
15
  def add_folder(title)
15
- post('folders/add', :title => title)
16
+ perform_post_with_object('/api/1.1/folders/add', {title: title}, Instapaper::Folder)
16
17
  end
17
18
 
18
19
  # Deletes the folder and moves any articles in it to the Archive.
19
20
  # @param folder_id [String] The id of the folder.
20
21
  def delete_folder(folder_id)
21
- post('folders/delete', :folder_id => folder_id)
22
+ perform_post_with_unparsed_response('/api/1.1/folders/delete', folder_id: folder_id)
23
+ true
22
24
  end
23
25
 
24
- # Re-orders a users folders.
26
+ # Re-orders a user's folders.
25
27
  # @param order [Array] An array of folder_id:position pairs joined by commas.
26
28
  # @example Ordering folder_ids 100, 200, and 300
27
29
  # Instapaper.set_order(['100:1','200:2','300:3'])
28
- def set_order(order=[])
29
- post('folders/set_order', :order => order.join(','))
30
+ def set_order(order = []) # rubocop:disable Naming/AccessorMethodName
31
+ perform_post_with_objects('/api/1.1/folders/set_order', {order: order.join(',')}, Instapaper::Folder)
30
32
  end
31
-
32
33
  end
33
34
  end
34
35
  end
@@ -0,0 +1,33 @@
1
+ require 'instapaper/highlight'
2
+
3
+ module Instapaper
4
+ module API
5
+ # Defines methods related to highlights
6
+ module Highlights
7
+ # List highlights for a bookmark
8
+ # @param bookmark_id [String, Integer]
9
+ def highlights(bookmark_id)
10
+ perform_get_with_objects("/api/1.1/bookmarks/#{bookmark_id}/highlights", {}, Instapaper::Highlight)
11
+ end
12
+
13
+ # Create a new highlight
14
+ # @note Non-subscribers are limited to 5 highlights per month.
15
+ # @param bookmark_id [String, Integer]
16
+ # @param options [Hash]
17
+ # @option options [String] :text The text for the highlight (HTML tags in text parameter should be unescaped.)
18
+ # @option options [String, Integer] :posiiton The 0-indexed position of text in the content. Defaults to 0.
19
+ # @return [Instapaper::Highlight]
20
+ def add_highlight(bookmark_id, options = {})
21
+ perform_post_with_object("/api/1.1/bookmarks/#{bookmark_id}/highlight", options, Instapaper::Highlight)
22
+ end
23
+
24
+ # Delete a highlight
25
+ # @param highlight_id [String, Integer]
26
+ # @return [Boolean]
27
+ def delete_highlight(highlight_id, options = {})
28
+ perform_post_with_unparsed_response("/api/1.1/highlights/#{highlight_id}/delete", options)
29
+ true
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,18 @@
1
+ require 'instapaper/credentials'
2
+ require 'instapaper/http/qline_parser'
3
+
4
+ module Instapaper
5
+ module API
6
+ # Defines methods related to OAuth
7
+ module OAuth
8
+ # Gets an OAuth access token for a user.
9
+ def access_token(username, password)
10
+ response = perform_post_with_unparsed_response('/api/1.1/oauth/access_token', x_auth_username: username, x_auth_password: password, x_auth_mode: 'client_auth')
11
+ parsed_response = QLineParser.parse(response)
12
+ raise Instapaper::Error::OAuthError, parsed_response['error'] if parsed_response.key?('error')
13
+
14
+ Instapaper::Credentials.new(parsed_response)
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,15 @@
1
+ require 'instapaper/api/accounts'
2
+ require 'instapaper/api/bookmarks'
3
+ require 'instapaper/api/folders'
4
+ require 'instapaper/api/highlights'
5
+ require 'instapaper/api/oauth'
6
+
7
+ module Instapaper
8
+ module API
9
+ include Instapaper::API::Accounts
10
+ include Instapaper::API::Bookmarks
11
+ include Instapaper::API::Folders
12
+ include Instapaper::API::Highlights
13
+ include Instapaper::API::OAuth
14
+ end
15
+ end
@@ -0,0 +1,21 @@
1
+ require 'virtus'
2
+
3
+ module Instapaper
4
+ class Bookmark
5
+ include Virtus.value_object
6
+
7
+ values do
8
+ attribute :instapaper_hash, String
9
+ attribute :description, String
10
+ attribute :bookmark_id, Integer
11
+ attribute :private_source, String
12
+ attribute :title, String
13
+ attribute :url, String
14
+ attribute :progress_timestamp, DateTime
15
+ attribute :time, DateTime
16
+ attribute :progress, String
17
+ attribute :starred, String
18
+ attribute :type, String
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,20 @@
1
+ require 'instapaper/bookmark'
2
+ require 'instapaper/highlight'
3
+ require 'instapaper/user'
4
+
5
+ module Instapaper
6
+ class BookmarkList
7
+ include Virtus.value_object
8
+
9
+ values do
10
+ attribute :user, Instapaper::User
11
+ attribute :bookmarks, Array[Instapaper::Bookmark]
12
+ attribute :highlights, Array[Instapaper::Highlight]
13
+ attribute :delete_ids, Array[Integer]
14
+ end
15
+
16
+ def each(&block)
17
+ bookmarks.each(&block)
18
+ end
19
+ end
20
+ end
@@ -1,43 +1,57 @@
1
- require 'instapaper/connection'
2
- require 'instapaper/request'
3
- require 'instapaper/authentication'
1
+ require 'instapaper/api'
2
+ require 'instapaper/http/utils'
3
+ require 'instapaper/version'
4
4
 
5
5
  module Instapaper
6
6
  # Wrapper for the Instapaper REST API
7
7
  class Client
8
- # @private
9
- attr_accessor *Configuration::VALID_OPTIONS_KEYS
8
+ include Instapaper::API
9
+ include Instapaper::HTTP::Utils
10
10
 
11
- alias :api_endpoint :endpoint
12
- alias :api_version :version
11
+ attr_accessor :oauth_token, :oauth_token_secret, :consumer_key, :consumer_secret, :proxy
12
+ attr_writer :user_agent
13
13
 
14
- # Creates a new API
15
- def initialize(options={})
16
- options = Instapaper.options.merge(options)
17
- Configuration::VALID_OPTIONS_KEYS.each do |key|
18
- send("#{key}=", options[key])
19
- end
14
+ # Initializes a new Client object
15
+ #
16
+ # @param options [Hash]
17
+ # @return [Instapaper::Client]
18
+ def initialize(options = {})
19
+ @oauth_token = options[:oauth_token]
20
+ @oauth_token_secret = options[:oauth_token_secret]
21
+ @consumer_key = options[:consumer_key]
22
+ @consumer_secret = options[:consumer_secret]
23
+ @proxy = options[:proxy]
24
+ yield(self) if block_given?
20
25
  end
21
26
 
22
- def endpoint_with_prefix
23
- api_endpoint + path_prefix
27
+ # @return [String]
28
+ def user_agent
29
+ @user_agent ||= "InstapaperRubyGem/#{Instapaper::VERSION}"
24
30
  end
25
31
 
26
- include Connection
27
- include Request
28
- include Authentication
32
+ # Authentication hash
33
+ #
34
+ # @return [Hash]
35
+ def credentials
36
+ {
37
+ consumer_key: @consumer_key,
38
+ consumer_secret: @consumer_secret,
39
+ oauth_token: @oauth_token,
40
+ oauth_token_secret: @oauth_token_secret,
41
+ }
42
+ end
29
43
 
30
- # Require client method modules after initializing the Client class in
31
- # order to avoid a superclass mismatch error, allowing those modules to be
32
- # Client-namespaced.
33
- require 'instapaper/client/account'
34
- require 'instapaper/client/user'
35
- require 'instapaper/client/bookmark'
36
- require 'instapaper/client/folder'
44
+ # @return [Hash]
45
+ def consumer_credentials
46
+ {
47
+ consumer_key: @consumer_key,
48
+ consumer_secret: @consumer_secret,
49
+ }
50
+ end
37
51
 
38
- include Instapaper::Client::Account
39
- include Instapaper::Client::User
40
- include Instapaper::Client::Bookmark
41
- include Instapaper::Client::Folder
52
+ # @return [Boolean]
53
+ def credentials?
54
+ credentials.values.all?
55
+ end
42
56
  end
43
57
  end
@@ -0,0 +1,12 @@
1
+ require 'virtus'
2
+
3
+ module Instapaper
4
+ class Credentials
5
+ include Virtus.value_object
6
+
7
+ values do
8
+ attribute :oauth_token, String
9
+ attribute :oauth_token_secret, String
10
+ end
11
+ end
12
+ end