Skip to content

Instantly share code, notes, and snippets.

@soapdog
Created May 13, 2021 17:18
Show Gist options
  • Save soapdog/c94fab2cc41dab6666ffa2ce07ca77af to your computer and use it in GitHub Desktop.
Save soapdog/c94fab2cc41dab6666ffa2ce07ca77af to your computer and use it in GitHub Desktop.
A script to get TBR from The StoryGraph
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
-- pass a string, list, record or number, and either a path to save the result to, or missing value to have it returned as text
-- from: https://forum.latenightsw.com/t/applescript-record-to-json/668/2
on convertASToJSON:someASThing saveTo:posixPath
--convert to JSON data
set {theData, theError} to current application's NSJSONSerialization's dataWithJSONObject:someASThing options:0 |error|:(reference)
if theData is missing value then error (theError's localizedDescription() as text) number -10000
if posixPath is missing value then -- return string
-- convert data to a UTF8 string
set someString to current application's NSString's alloc()'s initWithData:theData encoding:(current application's NSUTF8StringEncoding)
return someString as text
else
-- write data to file
set theResult to theData's writeToFile:posixPath atomically:true
return theResult as boolean -- returns false if save failed
end if
end convertASToJSON:saveTo:
on page_down()
tell application "System Events" to tell process "Safari"
set frontmost to true
tell window 1
key code 119
end tell
end tell
end page_down
on get_tbr_count()
tell application "Safari"
activate
make new document with properties {URL:"https://app.thestorygraph.com/to-read/andregarzia"}
delay 2
repeat 5 times
my page_down()
delay 2
end repeat
delay 2
set paneCount to do JavaScript "panes = document.querySelectorAll('.book-pane').length" in document 1 -- fill data
log "total books in tbr: " & paneCount
return paneCount
end tell
end get_tbr_count
on get_current_isbn(bookId)
tell application "Safari"
activate
make new document with properties {URL:"https://app.thestorygraph.com/books/" & bookId & "/editions"}
delay 3
try
set isbn to do JavaScript "isbn = document.evaluate(\"//span[text()='ISBN:']\", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue.parentElement.innerText.replace('ISBN: ','')" in document 1
close document 1
return isbn
on error
close document 1
return false
end try
end tell
end get_current_isbn
on write_tbr_html(tbr)
log "Writing tbr.html.pmd"
set the_file to "/Users/me/site/tbr.poly.pmd"
try
log "opening file"
set dataStream to open for access the_file with write permission
set eof of dataStream to 0
write ("#lang pollen" & linefeed & linefeed) to dataStream starting at eof as «class utf8»
write ("◊(define-meta title " & quote & "TBR List" & quote & ")" & linefeed & linefeed) to dataStream starting at eof as «class utf8»
write (("_Generated on " & (current date) as string) & "_" & linefeed & linefeed) to dataStream as «class utf8»
repeat with book in tbr
write ("### [" & the title of book & "](https://app.thestorygraph.com/books/" & the storygraphBookId of book & ")" & linefeed) to dataStream as «class utf8»
write ("* **Author:** [" & the author of book & "](https://app.thestorygraph.com/authors/" & the storygraphAuthorId of book & ")" & linefeed) to dataStream as «class utf8»
if the series of book is not missing value then
write ("* **Series:** " & the series of book & linefeed) to dataStream as «class utf8»
end if
if the isbn of book is not "None" then
write ("* **ISBN:** " & the isbn of book & linefeed) to dataStream as «class utf8»
end if
if the owned of book is true then
write ("* **😻 YOU ALREADY HAVE THIS BOOK 📚**" & linefeed) to dataStream as «class utf8»
end if
write linefeed to dataStream as «class utf8»
log "- tbr " & the title of book
end repeat
close access dataStream
on error errmsg number num
log errmsg
try
close access file the_file
end try
end try
end write_tbr_html
tell application "Safari"
activate
set tbrCount to my get_tbr_count()
set tbr to {}
repeat with x from 1 to tbrCount
set mySeries to do JavaScript "series = document.querySelector(':nth-child(" & x & " of .book-pane) div.book-title-author-and-series > p > a').innerText" in document 1
set myTitle to do JavaScript "title = document.querySelector(':nth-child(" & x & " of .book-pane) div.book-title-author-and-series > h3 > a').innerText" in document 1
set myBookId to do JavaScript "bookid = document.querySelector(':nth-child(" & x & " of .book-pane)').getAttribute('data-book-id')" in document 1
set myAuthorId to do JavaScript "authorId = document.querySelector(':nth-child(" & x & " of .book-pane)').getAttribute('data-author-ids').substring(0,36)" in document 1
set myOwnedLocation to do JavaScript "bookOwned = document.querySelector(':nth-child(" & x & " of .book-pane)').innerText.indexOf('Mark as owned')" in document 1
if myOwnedLocation is -1 then
set myOwned to true
else
set myOwned to false
end if
set myISBN to my get_current_isbn(myBookId)
log myTitle
try
set myAuthor to do JavaScript "author = document.querySelector(':nth-child(" & x & " of .book-pane) div.book-title-author-and-series > :nth-child(2 of p)').innerText" in document 1
copy {title:myTitle, series:mySeries, author:myAuthor, storygraphBookId:myBookId, storygraphAuthorId:myAuthorId, isbn:myISBN, owned:myOwned} to end of tbr
on error errmsg number num
copy {title:myTitle, author:mySeries, series:missing value, storygraphBookId:myBookId, storygraphAuthorId:myAuthorId, isbn:myISBN, owned:myOwned} to end of tbr
end try
end repeat
my convertASToJSON:tbr saveTo:("/Users/me/site/tbr.json")
my write_tbr_html(tbr)
log "Ended"
display notification "TBR Ready"
close document 1
end tell
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment