readwise 0.4.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/FUNDING.yml +1 -1
- data/CHANGELOG.md +5 -0
- data/README.md +20 -1
- data/lib/readwise/book.rb +1 -0
- data/lib/readwise/client.rb +125 -22
- data/lib/readwise/highlight.rb +40 -0
- data/lib/readwise/tag.rb +5 -1
- data/lib/readwise/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2132de7e8f9fdbc395fc94872968cee73d333c67723b2e81a7554b61105e1469
|
4
|
+
data.tar.gz: 4aca80570f7ea3d6d7045cfe0f3fe75c64d578e4ea2de05697d98e747215d74a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 35498d0c04b98eab247b3bf78bdf66dc51294f0538273c9515d8122b737c494421a4425f241d25577d77ec55a2ce01455e02fb91281a72769c753a7d74e9690c
|
7
|
+
data.tar.gz: 751bfaf4334fcf74cd6f16b685108a8df095a84366b91c76e1978447d839f28ff7234c136f933bd37eb18f7e1b0e437a40e84e7b17a4c5e3641a6d0995519268
|
data/.github/FUNDING.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,11 @@
|
|
2
2
|
|
3
3
|
## [Unreleased]
|
4
4
|
|
5
|
+
## [0.5.0] - 2023-06-15
|
6
|
+
- Add methods to create/update highlights ([#8](https://github.com/joshbeckman/readwise-ruby/pull/12))
|
7
|
+
- Add methods to add/update/remove highlight tags
|
8
|
+
- Add method to get book
|
9
|
+
|
5
10
|
## [0.4.0] - 2023-03-19
|
6
11
|
|
7
12
|
- Add `get_highlight` client method ([#10](https://github.com/andjosh/readwise-ruby/pull/10) from [@ajistrying](https://github.com/ajistrying))
|
data/README.md
CHANGED
@@ -33,11 +33,30 @@ books = client.export(book_ids: ['123']) # export specific highlights
|
|
33
33
|
|
34
34
|
puts books.first.title # books are Readwise::Book structs
|
35
35
|
puts books.first.highlights.map(&:text) # highlights are Readwise::Highlight structs
|
36
|
+
|
37
|
+
# create a highlight
|
38
|
+
create = Readwise::HighlightCreate.new(text: 'foobar', author: 'Joan')
|
39
|
+
highlight = client.create_highlight(highlight: create)
|
40
|
+
|
41
|
+
# update a highlight
|
42
|
+
update = Readwise::HighlightUpdate.new(text: 'foobaz', color: 'yellow')
|
43
|
+
updated = client.update_highlight(highlight: highlight, update: update)
|
44
|
+
|
45
|
+
# add a tag to a highlight
|
46
|
+
tag = Readwise::Tag.new(name: 'foobar')
|
47
|
+
added_tag = client.add_highlight_tag(highlight: highlight, tag: tag)
|
48
|
+
|
49
|
+
# update a tag on a highlight
|
50
|
+
added_tag.name = 'bing'
|
51
|
+
updated_tag = client.update_highlight_tag(highlight: highlight, tag: added_tag)
|
52
|
+
|
53
|
+
# remove a tag from a highlight
|
54
|
+
client.remove_highlight_tag(highlight: highlight, tag: added_tag)
|
36
55
|
```
|
37
56
|
|
38
57
|
## Development
|
39
58
|
|
40
|
-
After checking out the repo, run `bin/setup` to install dependencies. Then, run `bundle exec
|
59
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `bundle exec rspec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
41
60
|
|
42
61
|
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
43
62
|
|
data/lib/readwise/book.rb
CHANGED
data/lib/readwise/client.rb
CHANGED
@@ -12,25 +12,81 @@ module Readwise
|
|
12
12
|
|
13
13
|
def initialize(token: nil)
|
14
14
|
raise ArgumentError unless token
|
15
|
+
|
15
16
|
@token = token.to_s
|
16
17
|
end
|
17
18
|
|
18
19
|
def create_highlight(highlight:)
|
19
|
-
create_highlights([highlight])
|
20
|
+
create_highlights(highlights: [highlight]).first
|
20
21
|
end
|
21
22
|
|
22
23
|
def create_highlights(highlights: [])
|
23
|
-
raise
|
24
|
+
raise ArgumentError unless highlights.all? { |item| item.is_a?(Readwise::HighlightCreate) }
|
25
|
+
return [] unless highlights.any?
|
26
|
+
|
27
|
+
url = BASE_URL + 'highlights/'
|
28
|
+
|
29
|
+
payload = { highlights: highlights.map(&:serialize) }
|
30
|
+
res = post_readwise_request(url, payload: payload)
|
31
|
+
|
32
|
+
modified_ids = res.map { |book| book['modified_highlights'] }.flatten
|
33
|
+
modified_ids.map { |id| get_highlight(highlight_id: id) }
|
24
34
|
end
|
25
35
|
|
26
36
|
def get_highlight(highlight_id:)
|
27
|
-
url = BASE_URL +
|
37
|
+
url = BASE_URL + "highlights/#{highlight_id}"
|
28
38
|
|
29
39
|
res = get_readwise_request(url)
|
30
40
|
|
31
41
|
transform_highlight(res)
|
32
42
|
end
|
33
43
|
|
44
|
+
def update_highlight(highlight:, update:)
|
45
|
+
raise ArgumentError unless update.is_a?(Readwise::HighlightUpdate)
|
46
|
+
|
47
|
+
url = BASE_URL + "highlights/#{highlight.highlight_id}"
|
48
|
+
|
49
|
+
res = patch_readwise_request(url, payload: update.serialize)
|
50
|
+
|
51
|
+
transform_highlight(res)
|
52
|
+
end
|
53
|
+
|
54
|
+
def remove_highlight_tag(highlight:, tag:)
|
55
|
+
url = BASE_URL + "highlights/#{highlight.highlight_id}/tags/#{tag.tag_id}"
|
56
|
+
|
57
|
+
delete_readwise_request(url)
|
58
|
+
end
|
59
|
+
|
60
|
+
def add_highlight_tag(highlight:, tag:)
|
61
|
+
raise ArgumentError unless tag.is_a?(Readwise::Tag)
|
62
|
+
|
63
|
+
url = BASE_URL + "highlights/#{highlight.highlight_id}/tags"
|
64
|
+
|
65
|
+
payload = tag.serialize.select { |k, v| k == :name }
|
66
|
+
res = post_readwise_request(url, payload: payload)
|
67
|
+
|
68
|
+
transform_tag(res)
|
69
|
+
end
|
70
|
+
|
71
|
+
def update_highlight_tag(highlight:, tag:)
|
72
|
+
raise ArgumentError unless tag.is_a?(Readwise::Tag)
|
73
|
+
|
74
|
+
url = BASE_URL + "highlights/#{highlight.highlight_id}/tags/#{tag.tag_id}"
|
75
|
+
|
76
|
+
payload = tag.serialize.select { |k, v| k == :name }
|
77
|
+
res = patch_readwise_request(url, payload: payload)
|
78
|
+
|
79
|
+
transform_tag(res)
|
80
|
+
end
|
81
|
+
|
82
|
+
def get_book(book_id:)
|
83
|
+
url = BASE_URL + "books/#{book_id}"
|
84
|
+
|
85
|
+
res = get_readwise_request(url)
|
86
|
+
|
87
|
+
transform_book(res)
|
88
|
+
end
|
89
|
+
|
34
90
|
def export(updated_after: nil, book_ids: [])
|
35
91
|
resp = export_page(updated_after: updated_after, book_ids: book_ids)
|
36
92
|
next_page_cursor = resp[:next_page_cursor]
|
@@ -48,22 +104,7 @@ module Readwise
|
|
48
104
|
def export_page(page_cursor: nil, updated_after: nil, book_ids: [])
|
49
105
|
parsed_body = get_export_page(page_cursor: page_cursor, updated_after: updated_after, book_ids: book_ids)
|
50
106
|
results = parsed_body.dig('results').map do |item|
|
51
|
-
|
52
|
-
asin: item['asin'],
|
53
|
-
author: item['author'],
|
54
|
-
book_id: item['user_book_id'].to_s,
|
55
|
-
category: item['category'],
|
56
|
-
cover_image_url: item['cover_image_url'],
|
57
|
-
note: item['document_note'],
|
58
|
-
readable_title: item['readable_title'],
|
59
|
-
readwise_url: item['readwise_url'],
|
60
|
-
source: item['source'],
|
61
|
-
source_url: item['source_url'],
|
62
|
-
tags: item['book_tags'].map { |tag| transform_tag(tag) },
|
63
|
-
title: item['title'],
|
64
|
-
unique_url: item['unique_url'],
|
65
|
-
highlights: item['highlights'].map { |highlight| transform_highlight(highlight) },
|
66
|
-
)
|
107
|
+
transform_book(item)
|
67
108
|
end
|
68
109
|
{
|
69
110
|
results: results,
|
@@ -82,6 +123,27 @@ module Readwise
|
|
82
123
|
|
83
124
|
end
|
84
125
|
|
126
|
+
def transform_book(res)
|
127
|
+
highlights = (res['highlights'] || []).map { |highlight| transform_highlight(highlight) }
|
128
|
+
Book.new(
|
129
|
+
asin: res['asin'],
|
130
|
+
author: res['author'],
|
131
|
+
book_id: res['user_book_id'].to_s,
|
132
|
+
category: res['category'],
|
133
|
+
cover_image_url: res['cover_image_url'],
|
134
|
+
note: res['document_note'],
|
135
|
+
readable_title: res['readable_title'],
|
136
|
+
readwise_url: res['readwise_url'] || res['highlights_url'],
|
137
|
+
source: res['source'],
|
138
|
+
source_url: res['source_url'],
|
139
|
+
tags: (res['book_tags'] || res['tags'] || []).map { |tag| transform_tag(tag) },
|
140
|
+
title: res['title'],
|
141
|
+
unique_url: res['unique_url'],
|
142
|
+
highlights: highlights,
|
143
|
+
num_highlights: res['num_highlights'] || highlights.size,
|
144
|
+
)
|
145
|
+
end
|
146
|
+
|
85
147
|
def transform_highlight(res)
|
86
148
|
Highlight.new(
|
87
149
|
book_id: res['book_id'].to_s,
|
@@ -118,10 +180,51 @@ module Readwise
|
|
118
180
|
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
|
119
181
|
http.request(req)
|
120
182
|
end
|
121
|
-
|
122
|
-
raise Error, '
|
123
|
-
|
183
|
+
|
184
|
+
raise Error, 'Get request failed' unless res.is_a?(Net::HTTPSuccess)
|
185
|
+
|
186
|
+
JSON.parse(res.body)
|
187
|
+
end
|
188
|
+
|
189
|
+
def patch_readwise_request(url, payload:)
|
190
|
+
uri = URI.parse(url)
|
191
|
+
req = Net::HTTP::Patch.new(uri)
|
192
|
+
req['Authorization'] = "Token #{@token}"
|
193
|
+
req['Content-Type'] = 'application/json'
|
194
|
+
req.body = payload.to_json
|
195
|
+
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
|
196
|
+
http.request(req)
|
197
|
+
end
|
198
|
+
|
199
|
+
raise Error, 'Patch request failed' unless res.is_a?(Net::HTTPSuccess)
|
200
|
+
|
201
|
+
JSON.parse(res.body)
|
202
|
+
end
|
203
|
+
|
204
|
+
def post_readwise_request(url, payload:)
|
205
|
+
uri = URI.parse(url)
|
206
|
+
req = Net::HTTP::Post.new(uri)
|
207
|
+
req['Authorization'] = "Token #{@token}"
|
208
|
+
req['Content-Type'] = 'application/json'
|
209
|
+
req.body = payload.to_json
|
210
|
+
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
|
211
|
+
http.request(req)
|
212
|
+
end
|
213
|
+
|
214
|
+
raise Error, 'Post request failed' unless res.is_a?(Net::HTTPSuccess)
|
215
|
+
|
124
216
|
JSON.parse(res.body)
|
125
217
|
end
|
218
|
+
|
219
|
+
def delete_readwise_request(url)
|
220
|
+
uri = URI.parse(url)
|
221
|
+
req = Net::HTTP::Delete.new(uri)
|
222
|
+
req['Authorization'] = "Token #{@token}"
|
223
|
+
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
|
224
|
+
http.request(req)
|
225
|
+
end
|
226
|
+
|
227
|
+
raise Error, 'Delete request failed' unless res.is_a?(Net::HTTPSuccess)
|
228
|
+
end
|
126
229
|
end
|
127
230
|
end
|
data/lib/readwise/highlight.rb
CHANGED
@@ -39,5 +39,45 @@ module Readwise
|
|
39
39
|
|
40
40
|
Time.parse(highlighted_at)
|
41
41
|
end
|
42
|
+
|
43
|
+
def serialize
|
44
|
+
to_h
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
HighlightCreate = Struct.new(
|
49
|
+
'ReadwiseHighlightCreate',
|
50
|
+
:author,
|
51
|
+
:category, # One of: books, articles, tweets or podcasts.
|
52
|
+
# (default: articles when source_url is provided, otherwise: books)
|
53
|
+
:highlight_url,
|
54
|
+
:highlighted_at,
|
55
|
+
:image_url,
|
56
|
+
:location,
|
57
|
+
:location_type, # One of: page, order or time_offset (default: order)
|
58
|
+
:note,
|
59
|
+
:source_type,
|
60
|
+
:source_url,
|
61
|
+
:text,
|
62
|
+
:title,
|
63
|
+
keyword_init: true
|
64
|
+
) do
|
65
|
+
def serialize
|
66
|
+
to_h.compact
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
HighlightUpdate = Struct.new(
|
71
|
+
'ReadwiseHighlightUpdate',
|
72
|
+
:color,
|
73
|
+
:location,
|
74
|
+
:note,
|
75
|
+
:text,
|
76
|
+
:url,
|
77
|
+
keyword_init: true
|
78
|
+
) do
|
79
|
+
def serialize
|
80
|
+
to_h.compact
|
81
|
+
end
|
42
82
|
end
|
43
83
|
end
|
data/lib/readwise/tag.rb
CHANGED
data/lib/readwise/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: readwise
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Josh Beckman
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-06-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -114,7 +114,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
114
114
|
- !ruby/object:Gem::Version
|
115
115
|
version: '0'
|
116
116
|
requirements: []
|
117
|
-
rubygems_version: 3.4.
|
117
|
+
rubygems_version: 3.4.14
|
118
118
|
signing_key:
|
119
119
|
specification_version: 4
|
120
120
|
summary: Readwise API client
|