readwise 0.4.0 → 0.5.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 766eb82d68f06591b6e05211877532619182404c3aa29c24720de5cd1788ad0a
4
- data.tar.gz: 70b4affa8b2e46271fb1d690e00328be10e1fcbb5fd6a3d5ae08135947818671
3
+ metadata.gz: 2132de7e8f9fdbc395fc94872968cee73d333c67723b2e81a7554b61105e1469
4
+ data.tar.gz: 4aca80570f7ea3d6d7045cfe0f3fe75c64d578e4ea2de05697d98e747215d74a
5
5
  SHA512:
6
- metadata.gz: f6b8cda492331d61352a83bc01732fee2d30191419b226327334daf4c00338afe6876bfb5b806318506bc42a5706f826225a2c917dcaf17a0172d9c12cc3cd08
7
- data.tar.gz: 7b2e849cc2bff772ebe84c7b93cb0b7bdf9c506c9bce80a79754554590a537717c39882f6b04faa8e43105b5eac20598fd89f1a39002746d8212557a4bdaf42d
6
+ metadata.gz: 35498d0c04b98eab247b3bf78bdf66dc51294f0538273c9515d8122b737c494421a4425f241d25577d77ec55a2ce01455e02fb91281a72769c753a7d74e9690c
7
+ data.tar.gz: 751bfaf4334fcf74cd6f16b685108a8df095a84366b91c76e1978447d839f28ff7234c136f933bd37eb18f7e1b0e437a40e84e7b17a4c5e3641a6d0995519268
data/.github/FUNDING.yml CHANGED
@@ -1,3 +1,3 @@
1
1
  # These are supported funding model platforms
2
2
 
3
- github: andjosh
3
+ github: joshbeckman
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 rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
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
@@ -10,6 +10,7 @@ module Readwise
10
10
  :cover_image_url,
11
11
  :highlights,
12
12
  :note,
13
+ :num_highlights,
13
14
  :readable_title,
14
15
  :readwise_url,
15
16
  :source,
@@ -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 NotImplementedError
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 + 'highlights/' + highlight_id
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
- Book.new(
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, 'Export request failed' unless res.is_a?(Net::HTTPSuccess)
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
@@ -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
@@ -4,5 +4,9 @@ module Readwise
4
4
  :tag_id,
5
5
  :name,
6
6
  keyword_init: true
7
- )
7
+ ) do
8
+ def serialize
9
+ to_h
10
+ end
11
+ end
8
12
  end
@@ -1,3 +1,3 @@
1
1
  module Readwise
2
- VERSION = "0.4.0"
2
+ VERSION = "0.5.0"
3
3
  end
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.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-03-19 00:00:00.000000000 Z
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.7
117
+ rubygems_version: 3.4.14
118
118
  signing_key:
119
119
  specification_version: 4
120
120
  summary: Readwise API client