Skip to content

Commit cde89da

Browse files
authored
Add #daily_review client method and type (#14)
* Add #daily_review client method and type Ref: https://readwise.io/api_deets#:~:text=Daily%20Review%20LIST * fix: Add new review files
1 parent 4ce1275 commit cde89da

File tree

6 files changed

+163
-0
lines changed

6 files changed

+163
-0
lines changed

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,14 @@ updated_tag = client.update_highlight_tag(highlight: highlight, tag: added_tag)
5858

5959
# remove a tag from a highlight
6060
client.remove_highlight_tag(highlight: highlight, tag: added_tag)
61+
62+
# get daily review highlights
63+
daily_review = client.daily_review
64+
puts daily_review.id
65+
puts daily_review.url
66+
puts daily_review.completed?
67+
puts daily_review.highlights.size
68+
puts daily_review.highlights.first.text
6169
```
6270

6371
### Reader API (V3)

lib/readwise/client.rb

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
require_relative 'highlight'
55
require_relative 'tag'
66
require_relative 'document'
7+
require_relative 'review'
78

89
module Readwise
910
class Client
@@ -126,6 +127,13 @@ def get_book(book_id:)
126127
transform_book(res)
127128
end
128129

130+
def daily_review
131+
url = BASE_URL + 'review/'
132+
133+
res = get_readwise_request(url)
134+
transform_review(res)
135+
end
136+
129137
def export(updated_after: nil, book_ids: [])
130138
resp = export_page(updated_after: updated_after, book_ids: book_ids)
131139
next_page_cursor = resp[:next_page_cursor]
@@ -275,6 +283,17 @@ def transform_tag(res)
275283
)
276284
end
277285

286+
def transform_review(res)
287+
highlights = (res['highlights'] || []).map { |highlight| transform_highlight(highlight) }
288+
289+
Review.new(
290+
id: res['review_id'],
291+
url: res['review_url'],
292+
completed: res['review_completed'],
293+
highlights: highlights
294+
)
295+
end
296+
278297
def get_readwise_request(url)
279298
uri = URI.parse(url)
280299
req = Net::HTTP::Get.new(uri)

lib/readwise/review.rb

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
module Readwise
2+
Review = Struct.new(
3+
:id,
4+
:url,
5+
:completed,
6+
:highlights,
7+
keyword_init: true
8+
) do
9+
def completed?
10+
completed
11+
end
12+
13+
def serialize
14+
to_h.compact
15+
end
16+
end
17+
end

spec/fixtures/daily_review.json

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
{
2+
"review_id": 12345,
3+
"review_url": "https://readwise.io/review/12345",
4+
"review_completed": false,
5+
"highlights": [
6+
{
7+
"id": 123,
8+
"text": "This is the first highlight for daily review.",
9+
"book_id": 456,
10+
"url": "https://readwise.io/highlight/123",
11+
"highlighted_at": "2023-01-15T10:30:00.000Z",
12+
"created_at": "2023-01-15T10:30:00.000Z",
13+
"updated_at": "2023-01-15T10:30:00.000Z",
14+
"color": "yellow",
15+
"end_location": null,
16+
"external_id": null,
17+
"is_discard": false,
18+
"is_favorite": true,
19+
"location": 1,
20+
"location_type": "page",
21+
"note": null,
22+
"readwise_url": "https://readwise.io/highlight/123",
23+
"tags": []
24+
},
25+
{
26+
"id": 124,
27+
"text": "This is the second highlight for daily review.",
28+
"book_id": 457,
29+
"url": "https://readwise.io/highlight/124",
30+
"highlighted_at": "2023-01-16T14:20:00.000Z",
31+
"created_at": "2023-01-16T14:20:00.000Z",
32+
"updated_at": "2023-01-16T14:20:00.000Z",
33+
"color": "blue",
34+
"end_location": null,
35+
"external_id": null,
36+
"is_discard": false,
37+
"is_favorite": false,
38+
"location": 5,
39+
"location_type": "page",
40+
"note": "This is a note on the highlight",
41+
"readwise_url": "https://readwise.io/highlight/124",
42+
"tags": []
43+
}
44+
]
45+
}

spec/readwise/client_spec.rb

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
require 'readwise/client'
22
require 'readwise/highlight'
33
require 'readwise/document'
4+
require 'readwise/review'
45
require "rspec/file_fixtures"
56

67
RSpec.describe Readwise::Client do
@@ -101,6 +102,23 @@
101102
end
102103
end
103104

105+
context 'daily review' do
106+
let(:daily_review_response) { fixture('daily_review.json').from_json(false) }
107+
108+
it 'can retrieve daily review' do
109+
expect(subject).to receive(:get_readwise_request).and_return(daily_review_response)
110+
111+
review = subject.daily_review
112+
expect(review).to be_instance_of Readwise::Review
113+
expect(review.id).to eq(12345)
114+
expect(review.url).to eq('https://readwise.io/review/12345')
115+
expect(review.completed?).to be false
116+
expect(review.highlights).to be_an(Array)
117+
expect(review.highlights.size).to eq(2)
118+
expect(review.highlights.first).to be_instance_of Readwise::Highlight
119+
end
120+
end
121+
104122
context 'documents (V3 API)' do
105123
context 'creating a document' do
106124
let(:document_create_response) { fixture('document_create.json').from_json(false) }

spec/readwise/review_spec.rb

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
require 'readwise/review'
2+
require 'readwise/highlight'
3+
4+
RSpec.describe Readwise::Review do
5+
let(:review_data) do
6+
{
7+
id: 12345,
8+
url: 'https://readwise.io/review/12345',
9+
completed: false,
10+
highlights: []
11+
}
12+
end
13+
14+
subject { described_class.new(**review_data) }
15+
16+
describe '#completed?' do
17+
it 'returns false when completed is false' do
18+
expect(subject.completed?).to be false
19+
end
20+
21+
it 'returns true when completed is true' do
22+
review = described_class.new(**review_data.merge(completed: true))
23+
expect(review.completed?).to be true
24+
end
25+
end
26+
27+
describe '#serialize' do
28+
it 'returns a hash representation' do
29+
result = subject.serialize
30+
expect(result).to be_a(Hash)
31+
expect(result[:id]).to eq(12345)
32+
expect(result[:url]).to eq('https://readwise.io/review/12345')
33+
expect(result[:completed]).to be false
34+
end
35+
36+
it 'excludes nil values from serialization' do
37+
review = described_class.new(id: 123, url: 'https://example.com', completed: nil, highlights: [])
38+
result = review.serialize
39+
expect(result).not_to have_key(:completed)
40+
expect(result[:id]).to eq(123)
41+
end
42+
end
43+
44+
describe 'with highlights' do
45+
let(:highlight) { Readwise::Highlight.new(text: 'Sample highlight', highlight_id: '123', book_id: '456', tags: []) }
46+
let(:review_with_highlights) do
47+
described_class.new(**review_data.merge(highlights: [highlight]))
48+
end
49+
50+
it 'stores highlights properly' do
51+
expect(review_with_highlights.highlights).to be_an(Array)
52+
expect(review_with_highlights.highlights.size).to eq(1)
53+
expect(review_with_highlights.highlights.first).to be_instance_of Readwise::Highlight
54+
end
55+
end
56+
end

0 commit comments

Comments
 (0)