Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
transitive-bullshit committed Oct 7, 2024
1 parent 7f01515 commit c26dde2
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 29 deletions.
47 changes: 41 additions & 6 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,41 @@ It works by logging into your [Kindle web reader](https://read.amazon.com) accou

The accuracy has been very close to perfect in my testing, with the only discrepancies being occasional whitespace issues.

<table>
<tbody>
<tr>
<td>
<img src="./examples/B0819W19WD/kindle-reader-library-example.jpg" alt="Kindle web reader library" width="640">
</td>
</tr>
<tr>
<td>
<img src="./examples/B0819W19WD/kindle-reader-page-example.png" alt="Kindle web reader page" width="640">
</td>
</tr>
<tr>
<td>
<img src="./examples/B0819W19WD/pages/0000-0001.png" alt="First page of Revelation Space by Alastair Reynolds" width="640">
</td>
</tr>
<tr>
<td>
**Mantell Sector, North Nekhebet, Resurgam, Delta Pavonis system, 2551**

There was a razorstorm coming in.

Sylveste stood on the edge of the excavation and wondered if any of his labours would survive the night. The archaeological dig was an array of deep square shafts separated by baulks of sheer-sided soil: the classical Wheeler box-grid. The shafts went down tens of metres, walled by transparent cofferdams spun from hyperdiamond. A million years of stratified geological history pressed against the sheets. But it would take only one good dustfall—one good razorstorm—to fill the shafts almost to the surface.

“Confirmation, sir,” said one of his team, emerging from the crouched form of the first crawler. The man’s voice was muffled behind his breather mask. “Cuvier’s just issued a severe weather advisory for the whole North

</td>
</tr>

</tbody>
</table>

---

<p align="center">
<img alt="Kindle web reader page" src="./examples/B0819W19WD/kindle-reader-page-example.png" width="45%">
&nbsp; &nbsp;&nbsp; &nbsp;
Expand Down Expand Up @@ -154,12 +189,12 @@ The other downside is that the **LLM costs add up to a few dollars per book usin
Here's an [example](./examples/B0819W19WD) using the first page of the scifi book [Revelation Space](https://www.amazon.com/gp/product/B0819W19WD?ref_=dbs_m_mng_rwt_calw_tkin_0&storeType=ebooks) by [Alastair Reynolds](https://www.goodreads.com/author/show/51204.Alastair_Reynolds):

<table>
<tbody>
<tr>
<td align="center">
<img src="./examples/B0819W19WD/pages/0000-0001.png" alt="First page of Revelation Space by Alastair Reynolds" width="640">
</td>
</tr>
<tbody>
<tr>
<td>
<img src="./examples/B0819W19WD/pages/0000-0001.png" alt="First page of Revelation Space by Alastair Reynolds" width="640">
</td>
</tr>
</tbody>
</table>

Expand Down
48 changes: 25 additions & 23 deletions src/extract-kindle-book.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,30 +66,32 @@ async function main() {
let meta: any

page.on('response', async (response) => {
const status = response.status()
if (status !== 200) return

const url = new URL(response.url())
if (
url.hostname === 'read.amazon.com' &&
url.pathname === '/service/mobile/reader/startReading' &&
url.searchParams.get('asin')?.toLowerCase() === asin.toLowerCase()
) {
const body: any = await response.json()
delete body.karamelToken
delete body.metadataUrl
delete body.YJFormatVersion
info = body
} else if (url.pathname.endsWith('YJmetadata.jsonp')) {
const body = await response.text()
const metadata = parseJsonpResponse<any>(body)
if (metadata.asin !== asin) return
delete metadata.cpr
if (Array.isArray(metadata.authorsList)) {
metadata.authorsList = normalizeAuthors(metadata.authorsList)
try {
const status = response.status()
if (status !== 200) return

const url = new URL(response.url())
if (
url.hostname === 'read.amazon.com' &&
url.pathname === '/service/mobile/reader/startReading' &&
url.searchParams.get('asin')?.toLowerCase() === asin.toLowerCase()
) {
const body: any = await response.json()
delete body.karamelToken
delete body.metadataUrl
delete body.YJFormatVersion
info = body
} else if (url.pathname.endsWith('YJmetadata.jsonp')) {
const body = await response.text()
const metadata = parseJsonpResponse<any>(body)
if (metadata.asin !== asin) return
delete metadata.cpr
if (Array.isArray(metadata.authorsList)) {
metadata.authorsList = normalizeAuthors(metadata.authorsList)
}
meta = metadata
}
meta = metadata
}
} catch {}
})

await Promise.any([
Expand Down

0 comments on commit c26dde2

Please sign in to comment.