Created
December 23, 2021 10:51
-
-
Save fallaciousreasoning/7b67c929ac36f37f3b17bd5d66c1f90a to your computer and use it in GitHub Desktop.
A script which adds a button to Goodreads for setting the Read date to the shevled date.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name Goodreads Set ReadDate | |
// @namespace Violentmonkey Scripts | |
// @match https://www.goodreads.com/review/list/* | |
// @grant none | |
// @version 1.0 | |
// @author - | |
// @description 20/12/2021, 12:05:54 pm | |
// ==/UserScript== | |
const shelfName = 'read'; | |
const reviewIdRegex = /reviewEditor.summon\(this, (\d+),.*reading_session_id: "(.*?)"/ | |
const csrfToken = document.querySelector('#reviewEditForm input[name="authenticity_token"]').value; | |
const setReadDate = async (reviewId, sessionId, date) => { | |
const response = await fetch(`https://www.goodreads.com/review/update/${reviewId}`, { | |
method: 'POST', | |
credentals: 'include', | |
headers: { | |
'X-CSRF-Token': csrfToken | |
}, | |
body: new URLSearchParams({ | |
'_reading_session_id':sessionId, | |
'review[read_at(1i)]':date.getFullYear(), | |
'review[read_at(2i)]':date.getMonth() +1, | |
'review[read_at(3i)]': date.getDate(), | |
'view':'table', | |
'shelf':'read', | |
'format':'json' | |
}) | |
}); | |
} | |
const getReviewId = (dateReadColumn) => { | |
const editLink = dateReadColumn.querySelector('a.floatingBoxLink.smallText'); | |
const editClick = editLink.getAttribute('onclick'); | |
const match = reviewIdRegex.exec(editClick); | |
if (!match) { | |
console.log(`Failed to extract reviewId from ${editClick}`); | |
return; | |
} | |
return { | |
reviewId: match[1], | |
sessionId: match[2], | |
}; | |
} | |
const updateDateText = (dateReadEl, date) => { | |
const greyText =dateReadEl.querySelector('.greyText'); | |
greyText?.remove(); | |
let dateText = dateReadEl.querySelector('.date_read_value'); | |
if (!dateText) { | |
dateText = document.createElement('span'); | |
dateText.setAttribute('class', 'date_read_value'); | |
dateReadEl.prepend(dateText); | |
} | |
dateText.innerText = date.toLocaleString('en-us',{month:'short', day: 'numeric', year:'numeric'}); | |
} | |
const makeLinkButton = (dateReadEl, { reviewId, sessionId }, date) => { | |
const link = document.createElement('a'); | |
link.href = '#'; | |
link.setAttribute('class', 'floatingBoxLink smallText'); | |
link.innerText = `[use shelved]`; | |
link.addEventListener('click', async e => { | |
e.preventDefault(); | |
console.log(`Setting read date for ${reviewId} to ${date}`); | |
await setReadDate(reviewId, sessionId, date); | |
console.log('Done!'); | |
updateDateText(dateReadEl, date); | |
}); | |
return link; | |
} | |
setTimeout(() => { | |
const books = document.querySelectorAll('.bookalike.review'); | |
for (const book of books) { | |
const dateRead = book.querySelector('.field.date_read .editable_date'); | |
const reviewId = getReviewId(dateRead); | |
if (!reviewId) continue; | |
const dateAdded = book.querySelector('.field.date_added')?.innerText; | |
if (!dateAdded) continue; | |
const date = new Date(dateAdded); | |
const setDateButton = makeLinkButton(dateRead, reviewId, date); | |
dateRead.appendChild(setDateButton); | |
} | |
}, 1000); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment