inoreader-api 0.9.0

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: aa0262c517e47bef19e82c90cefa27fb432ac3b5
4
+ data.tar.gz: 0e97fe585a014d3660b0d22ed595194dc1961892
5
+ SHA512:
6
+ metadata.gz: 1de9738b02e45a77ea0384b4db4d98668b80e66310379f3cf40885385891d6855912e0e2fd4a0bfcd11b00fcbbea7e7496ee4cc30772df37f0ff879217e57c7a
7
+ data.tar.gz: 399baebe15d15b8a06dc3f7f4deabf1007ef5060d21a5270c800456b9b3c53470835e851099f4a5113d4947d354e863bce6ac77b197a6f63ac684f3b23abf1d2
@@ -0,0 +1,20 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ .idea
19
+
20
+ spec/real_request_spec.rb
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in inoreader-api.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 kyohei8
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,239 @@
1
+ # Simple api client of [InoReader](http://inoreader.com/)
2
+
3
+ This gem is Simple api client of [InoReader](http://inoreader.com/)
4
+
5
+ InoReader official API is [here](http://wiki.inoreader.com/doku.php?id=api)
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ gem 'inoreader-api'
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install inoreader-api
20
+
21
+ ## Usage
22
+
23
+ ### Initialize
24
+
25
+ #### Initialize with Login
26
+
27
+ ```ruby
28
+ require 'inoreader-api'
29
+
30
+ inoreader = InoreaderApi::Api.new(:username => 'username', :password => 'password')
31
+ inoreader.auth_token # => 'G2UlCa...Fx'
32
+ ```
33
+
34
+ #### Initialize with Token
35
+
36
+ ```ruby
37
+ require 'inoreader-api'
38
+
39
+ inoreader = InoreaderApi::Api.new(:auth_token => 'yourtoken')
40
+ inoreader.auth_token # => yourtoken
41
+ ```
42
+
43
+ ### Token
44
+
45
+ ```ruby
46
+ inoreader.token # => yourtoken
47
+ ```
48
+
49
+ ### User info
50
+
51
+ ```ruby
52
+ user = inoreader.user_info
53
+ user.userId # => '1005921515'
54
+ user.userName # => 'Jacket'
55
+ ```
56
+
57
+ ### Get unread counters
58
+
59
+ ```ruby
60
+ unread = inoreader.unread_counters
61
+ unread.max # => 1000
62
+ ```
63
+
64
+ ### List of user subscriptions
65
+
66
+ ```ruby
67
+ inoreader.user_subscription
68
+ ```
69
+
70
+ ### List of user tags and folders
71
+
72
+ ```ruby
73
+ inoreader.user_tags_folders
74
+ ```
75
+
76
+ ### Stream
77
+
78
+ #### feed items
79
+
80
+ For additional parameter about any of the request, see the http://wiki.inoreader.com/doku.php?id=api#stream_contents
81
+
82
+ ``` ruby
83
+ # retrieve all feed item
84
+ inoreader.items
85
+ # => #<Hashie::Mash continuation="bHe_p00GLz2u" description="" direction="ltr"...
86
+
87
+ # with parameter
88
+ inoreader.items('feed/http://feeds.test.com/',{
89
+ :n => 10,
90
+ :r => 'o',
91
+ :ot => '1389756192',
92
+ :xt => 'user/-/state/com.google/read',
93
+ :it => 'user/-/state/com.google/read',
94
+ :c => 'Beg3ah6v3'
95
+ })
96
+ ```
97
+
98
+ #### item ids
99
+
100
+ ```ruby
101
+ # retrieve all item ids
102
+ inoreader.item_ids
103
+ # => #<Hashie::Mash continuation="eCpdOmg58fOF" itemRefs=[...
104
+
105
+ # with parameter
106
+ inoreader.item_ids('feed/http://feeds.test.com/',{
107
+ :n => 10,
108
+ :r => 'o',
109
+ :ot => '1389756192',
110
+ :xt => 'user/-/state/com.google/read',
111
+ :it => 'user/-/state/com.google/read',
112
+ :c => 'Beg3ah6v3'
113
+ })
114
+ ```
115
+
116
+ ### Tags
117
+
118
+ #### Rename tag
119
+
120
+ ```ruby
121
+ inoreader.rename_tag('oldtag','newtag') # => 'OK'
122
+ ```
123
+
124
+ #### Delete tag
125
+
126
+ ```ruby
127
+ inoreader.disable_tag('tagname') # => 'OK'
128
+ ```
129
+
130
+ #### Add tag
131
+
132
+ ```ruby
133
+ inoreader.add_tag('1719158580', 'user/-/state/com.google/read') # => 'OK'
134
+ # or
135
+ inoreader.add_tag('tag:google.com,2005:reader/item/000000006678359d', 'user/-/state/com.google/read') # => 'OK'
136
+ ```
137
+
138
+ #### Remove tag
139
+
140
+ ```ruby
141
+ inoreader.remove_tag('1719158580', 'user/-/state/com.google/read') # => 'OK'
142
+ # or
143
+ inoreader.remove_tag('tag:google.com,2005:reader/item/000000006678359d', 'user/-/state/com.google/read') # => 'OK'
144
+ ```
145
+
146
+ ### Mark all as read
147
+
148
+ ```ruby
149
+ # specify label
150
+ inoreader.mark_all_as_read(1373407120123456, 'user/-/label/Google') # => 'OK'
151
+
152
+ # or feed
153
+ inoreader.mark_all_as_read(1373407120123456, 'feed/http://feeds.test.com/') # => 'OK'
154
+ ```
155
+
156
+ ### Subscription
157
+
158
+ #### Add subscription (feed)
159
+
160
+ ```ruby
161
+ inoreader.add_subscription('http://newfeeditem.com/')
162
+ # => #<Hashie::Mash numResults=1 query="http://newfeeditem.com/" streamId="feed/http://rss.newfeeditem.com/feeds">
163
+ ```
164
+
165
+ #### Rename subscription
166
+
167
+ ```ruby
168
+ inoreader.rename_subscription('feed/http://rss.newfeeditem.com/feeds', 'new title') # => 'OK'
169
+ ```
170
+
171
+ #### Add folder
172
+
173
+ ```ruby
174
+ inoreader.add_folder_subscription('feed/http://rss.newfeeditem.com/feeds', 'folderName') # => 'OK'
175
+ ```
176
+
177
+ #### Remove folder
178
+
179
+ ```ruby
180
+ inoreader.remove_folder_subscription('feed/http://rss.newfeeditem.com/feeds', 'folderName') # => 'OK'
181
+ ```
182
+
183
+ #### unsubscribe
184
+
185
+ ```ruby
186
+ inoreader.unsubscribe('feed/http://rss.newfeeditem.com/feeds') # => 'OK'
187
+ ```
188
+
189
+ #### subscribe
190
+
191
+ ```ruby
192
+ inoreader.subscribe('feed/http://rss.newfeeditem.com/feeds') # => 'OK'
193
+ # with folder
194
+ inoreader.subscribe('feed/http://rss.newfeeditem.com/feeds', 'newFolder') # => 'OK'
195
+ ```
196
+
197
+ ### Preferences list
198
+
199
+ ```ruby
200
+ inoreader.preferences_list
201
+ # => #<Hashie::Mash prefs=[#<Hashie::Mash id="lhn-prefs" value="{\"subscriptions\":{\"ssa\":\"false\"}}">]>
202
+ ```
203
+
204
+
205
+ ### Stream preferences list
206
+
207
+ ```ruby
208
+ inoreader.stream_preferences_list
209
+ # => #<Hashie::Mash streamprefs=#<Hashie::Mash...
210
+ ```
211
+
212
+ ### Set subscription ordering
213
+
214
+ ```ruby
215
+ inoreader.set_subscription_ordering('user/-/state/com.google/root', '00A3AAB000B9C8F9')# => 'OK'
216
+ ```
217
+
218
+ ## httparty mode
219
+ If you attach the `:return_httparty_response => true` when the initiarize, you can return the response of httparty.
220
+
221
+ [httparty(github)](https://github.com/jnunemaker/httparty)
222
+
223
+ ```ruby
224
+ inoreader = InoreaderApi::Api.new(
225
+ :auth_token => 'token',
226
+ :return_httparty_response => true
227
+ )
228
+
229
+ inoreader.item_ids
230
+ # <HTTParty::Response:0x7fe10416dd60 parsed_response={"items"=>[], "itemRefs"=>[{"id"=>"1719385305", "directStreamIds"=>[], ...
231
+ ```
232
+
233
+ ## Contributing
234
+
235
+ 1. Fork it
236
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
237
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
238
+ 4. Push to the branch (`git push origin my-new-feature`)
239
+ 5. Create new Pull Request
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,30 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'inoreader/api/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "inoreader-api"
8
+ spec.version = Inoreader::Api::VERSION
9
+ spec.authors = ["kyohei8"]
10
+ spec.email = ["tsukuda.kyouhei@gmail.com"]
11
+ spec.description = %q{InoReader Ruby Client}
12
+ spec.summary = %q{InoReader Ruby Client}
13
+ spec.homepage = ""
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_runtime_dependency 'httparty'
22
+ spec.add_runtime_dependency 'multi_json'
23
+ spec.add_runtime_dependency 'hashie'
24
+ spec.add_development_dependency 'bundler', '~> 1.3'
25
+ spec.add_development_dependency 'rake'
26
+ spec.add_development_dependency 'webmock'
27
+ spec.add_development_dependency 'rspec'
28
+ spec.add_development_dependency 'simplecov'
29
+
30
+ end
@@ -0,0 +1 @@
1
+ require(File.join(File.dirname(__FILE__), "inoreader", "api"))
@@ -0,0 +1,8 @@
1
+ # coding: utf-8
2
+
3
+ require 'inoreader/api/app'
4
+ require 'inoreader/api/helper'
5
+
6
+ module InoreaderApi
7
+ class InoreaderApiError < StandardError; end
8
+ end
@@ -0,0 +1,228 @@
1
+ # coding: utf-8
2
+ require 'json'
3
+
4
+ module InoreaderApi
5
+ class Api
6
+ # set auth toke or username/password
7
+ # @param [Hash] options
8
+ # @option auth_token [String] auth token
9
+ # @option username [String] username
10
+ # @option password [String] password
11
+ # @option return_httparty_response [Boolean]
12
+ # @return [String] auth token
13
+ def initialize(options={})
14
+ # set default
15
+ options = {
16
+ :return_httparty_response => false
17
+ }.merge(options)
18
+ @auth_token = options.delete(:auth_token)
19
+ if !@auth_token && options.has_key?(:username) && options.has_key?(:password)
20
+ username = options.delete(:username)
21
+ password = options.delete(:password)
22
+ res = login(username, password)
23
+ @auth_token = res
24
+ end
25
+
26
+ InoreaderApi::Helper.return_httparty_response = options[:return_httparty_response]
27
+ end
28
+
29
+ # return to auth token
30
+ def auth_token
31
+ @auth_token
32
+ end
33
+
34
+ # get user info
35
+ # @return [String] json string "{"userId":"XXXXXXXXX", "userName":"user_name", ...}"
36
+ def user_info
37
+ Helper.request '/reader/api/0/user-info', {:query => {:T => @auth_token}}
38
+ end
39
+
40
+ # get token
41
+ # @return [String] token. ex."aFP4xIm2Ow...."
42
+ def token
43
+ Helper.request '/reader/api/0/token', {:query => {:T => @auth_token}}
44
+ end
45
+
46
+ # OPML Import
47
+ def import
48
+ # todo
49
+ end
50
+
51
+ # get unread counters
52
+ def unread_counters
53
+ Helper.request '/reader/api/0/unread-count?output=json', {:query => {:T => @auth_token}}
54
+ end
55
+
56
+ # get user subscriptions
57
+ def user_subscription
58
+ Helper.request '/reader/api/0/subscription/list', {:query => {:T => @auth_token}}
59
+ end
60
+
61
+ # get user tags/folders
62
+ def user_tags_folders
63
+ Helper.request '/reader/api/0/tag/list', {:query => {:T => @auth_token}}
64
+ end
65
+
66
+ # stream
67
+ # output format : json only
68
+ # @param [String] path request path
69
+ # @param [String] feed id of subscription
70
+ # @param [Hash] params request Parameters
71
+ # @option params [Number] :n Number of items. (default 20, max 1000)
72
+ # @option params [String] :r Order. (default is newest first. 'o' is oldest first)
73
+ # @option params [String] :ot Start time (unix timestamp. ex.1389756192)
74
+ # @option params [String] :xt Exclude Target. (ex. 'user/-/state/com.google/read')
75
+ # @option params [String] :it Include Target. ('user/-/state/com.google/read(,starred,like)')
76
+ # @option params [String] :c Continuation.
77
+ def stream(path, feed='', params={})
78
+ query = {:query => params.merge!(:T => @auth_token, :output => 'json')}
79
+ feed_name = feed.empty? ? '' : ('/' + feed)
80
+ Helper.request "#{path}#{feed_name}", query
81
+ end
82
+
83
+ # get user items
84
+ # @see InoreaderApi::Api#stream
85
+ def items(feed='', params={})
86
+ stream '/reader/atom', feed, params
87
+ end
88
+
89
+ # get user item ids
90
+ # @see InoreaderApi::Api#stream
91
+ def item_ids(feed='', params={})
92
+ stream '/reader/api/0/stream/items/ids', feed, params
93
+ end
94
+
95
+ ## tag ##
96
+
97
+ # rename tag
98
+ # @param source source tag
99
+ # @param dest dest tag
100
+ def rename_tag(source, dest)
101
+ Helper.request '/reader/api/0/rename-tag', {:query => {:T => @auth_token, s: source, dest: dest}}, :post
102
+ end
103
+
104
+ # delete(disable) tag
105
+ def disable_tag(tag_name)
106
+ Helper.request '/reader/api/0/disable-tag', {:query => {:T => @auth_token, s: tag_name}}, :post
107
+ end
108
+
109
+ # add tag
110
+ # @param [String] items Item IDs(short or long)
111
+ # @param [String] add_tag use SpecialTag or custom tag
112
+ def add_tag(items, add_tag=nil)
113
+ Helper.request '/reader/api/0/edit-tag', {:query => {:T => @auth_token, :i => items, :a => add_tag}}, :post
114
+ end
115
+
116
+ # remove tag
117
+ # @param [Array] items Item IDs(short or long)
118
+ # @param [String] remove_tag SpecialTag or custom tag
119
+ def remove_tag(items, remove_tag)
120
+ Helper.request '/reader/api/0/edit-tag', {:query => {:T => @auth_token, :i => items, :r => remove_tag}}, :post
121
+ end
122
+
123
+ # mark all as read. mark as read, older than ts.
124
+ # @param [String] ts microseconds.
125
+ # @param [String] s Stream.
126
+ def mark_all_as_read(ts, s)
127
+ Helper.request '/reader/api/0/mark-all-as-read', {:query => {:T => @auth_token, :ts => ts, :s => s}}, :post
128
+ end
129
+
130
+ # add Subscription
131
+ # @param [String] url specify the URL to add.
132
+ def add_subscription(url)
133
+ Helper.request '/reader/api/0/subscription/quickadd', {:query => {:T => @auth_token, quickadd: url}}, :post
134
+ end
135
+
136
+ # edit subscription
137
+ # @param [String] ac action ('edit' or 'subscribe' or 'unsubscribe')
138
+ # @param [String] s stream id(feed/feed_url)
139
+ # @param [String] t subscription title. Omit this parameter to keep the title unchanged
140
+ # @param [String] a add subscription to folder/tag.
141
+ # @param [String] r remove subscription from folder/tag.
142
+ def edit_subscription(ac, s, t=nil, a=nil, r=nil)
143
+ query = {:T => @auth_token, :ac => ac, :s => s}
144
+ query[:t] = t unless t.nil?
145
+ query[:a] = a unless a.nil?
146
+ query[:r] = r unless r.nil?
147
+ Helper.request '/reader/api/0/subscription/edit', {:query => query}, :post
148
+ end
149
+
150
+ # rename subscription title
151
+ # @param [String] s stream id(feed/feed_url)
152
+ # @param [String] t subscription new title.
153
+ def rename_subscription(s, t)
154
+ edit_subscription :edit, s, t
155
+ end
156
+
157
+ # add folder to subscription
158
+ # @param [String] s stream id(feed/feed_url)
159
+ # @param [String] a add subscription to folder
160
+ def add_folder_subscription(s, a)
161
+ edit_subscription :edit, s, nil, a
162
+ end
163
+
164
+ # remove folder to subscription
165
+ # @param [String] s stream id(feed/feed_url)
166
+ # @param [String] r remove subscription to folder
167
+ def remove_folder_subscription(s, r)
168
+ edit_subscription :edit, s, nil, nil, r
169
+ end
170
+
171
+ # unsubscribe
172
+ # @param [String] s stream id(feed/feed_url)
173
+ def unsubscribe(s)
174
+ edit_subscription :unsubscribe, s
175
+ end
176
+
177
+ # subscribe (=add Subscription)
178
+ # @param [String] s stream id(feed/feed_url)
179
+ # @param [String] a folder name
180
+ def subscribe(s, a)
181
+ edit_subscription :subscribe, s, nil, a
182
+ end
183
+
184
+ # preference list:current subscriptions sorting.
185
+ def preferences_list
186
+ Helper.request '/reader/api/0/preference/list', {:query => {:T => @auth_token}}
187
+ end
188
+
189
+ # Stream preferences list
190
+ def stream_preferences_list
191
+ Helper.request '/reader/api/0/preference/stream/list', {:query => {:T => @auth_token}}
192
+ end
193
+
194
+ # @param [String] s stream id. root or folder name
195
+ # @param [String] k key
196
+ # @param [String] v value
197
+ def set_stream_preferences(s, k, v)
198
+ query = {:query => {:T => @auth_token, :s => s, :k => k, :v => v}}
199
+ Helper.request '/reader/api/0/preference/stream/set', query, :post
200
+ end
201
+
202
+ # Set stream preferences. now is “subscription-ordering” only :P
203
+ # @param [String] s stream id. 'root' or folder name
204
+ # @param [String] v sorting value
205
+ def set_subscription_ordering(s, v)
206
+ set_stream_preferences(s, 'subscription-ordering', v)
207
+ end
208
+
209
+ private
210
+ # Authenticate, to return authToken
211
+ # @param un username or Email
212
+ # @param pw Password
213
+ # @return Hash
214
+ # if success
215
+ # {
216
+ # :auth_token => xxxxxxxx
217
+ # }
218
+ #
219
+ def login(un, pw)
220
+ response_body = Helper.auth_request un, pw
221
+ auth_token = Hash[*response_body.split.collect { |i| i.split('=') }.flatten]['Auth']
222
+ raise InoreaderApi::InoreaderApiError.new 'Bad Authentication' if auth_token.nil?
223
+ auth_token
224
+ rescue => e
225
+ raise InoreaderApi::InoreaderApiError.new e.message if auth_token.nil?
226
+ end
227
+ end
228
+ end