A Pen by Hannu Hartikainen on CodePen.
Created
December 20, 2016 14:07
-
-
Save dancek/ac8e1eb309a994623a464668228e4ab7 to your computer and use it in GitHub Desktop.
Helmet search from Goodreads to-read shelf
This file contains hidden or 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
<h1>Helmet search from Goodreads to-read shelf</h1> | |
<p>Goodreads user id: <input id="user" /> <button onclick="refresh()">Go!</button></p> | |
<p>(note: you need to set profile visible to 'anyone' in <a href="https://www.goodreads.com/user/edit?tab=settings" target="_blank">Goodreads settings</a>)</p> | |
<hr/> | |
<table id="books"> | |
</table> | |
<pre id="debug"></pre> |
This file contains hidden or 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
function fetchGoodreadsShelf(id) { | |
const url = `https://webtask.it.auth0.com/api/run/wt-hannu-hartikainen-gmail-com-1/goodreads?id=${id}`; | |
return fetch(url) | |
.then(response => { | |
if (!response.ok) throw response; | |
return response.json() | |
}); | |
} | |
function getBookFromReview(review) { | |
const book = review.book; | |
console.log(book.title, book); // for debugging | |
const out = { | |
isbn13: book.isbn13, | |
title: book.title, | |
author: book.authors.author.name, // TODO: multiple authors | |
rating: book.average_rating, | |
url: book.link | |
} | |
return out; | |
} | |
function printDebug(data) { | |
document.getElementById('debug').innerText = JSON.stringify(data, null, 2); | |
return data; | |
} | |
function createTd(text, href) { | |
const td = document.createElement('td'); | |
const textNode = document.createTextNode(text); | |
var content; | |
if (href) { | |
content = document.createElement('a'); | |
content.setAttribute('href', href); | |
content.setAttribute('target', '_blank'); | |
content.appendChild(textNode); | |
} else { | |
content = textNode; | |
} | |
td.appendChild(content); | |
return td; | |
} | |
const SURNAME_RE = /(.*) ([^ ]*)/ | |
function surnameFirst(author) { | |
const [_, firstname, surname] = author.match(SURNAME_RE); | |
return `${surname}, ${firstname}`; | |
} | |
// strip goodreads additions like series name and number | |
function strippedTitle(title) { | |
return title.replace(/ *\(.*, #.*\)/, ''); | |
} | |
function authorSearchLink(book) { | |
return `http://luettelo.helmet.fi/search~S9*fin/?searchtype=a&searcharg=${surnameFirst(book.author)}`; | |
} | |
function titleSearchLink(book) { | |
return `http://luettelo.helmet.fi/search~S9*fin/?searchtype=t&searcharg=${strippedTitle(book.title)}`; | |
} | |
function createRowFromBook(book) { | |
const tr = document.createElement('tr'); | |
tr.appendChild(createTd(book.rating, book.url)) | |
tr.appendChild(createTd(book.author, authorSearchLink(book))); | |
tr.appendChild(createTd(book.title, titleSearchLink(book))); | |
return tr; | |
} | |
function insertRows(rows) { | |
const table = document.getElementById('books') | |
const docFrag = document.createDocumentFragment(); | |
rows.map(row => docFrag.appendChild(row)) | |
while(table.firstChild) { | |
table.removeChild(table.firstChild); | |
} | |
table.appendChild(docFrag); | |
} | |
function setMsg(msg) { | |
document.getElementById('books').innerHTML = `<tr><td>${msg}</td></tr>`; | |
} | |
function init() { | |
const id = localStorage.getItem('goodreadsUser') || '20719991'; | |
document.getElementById('user').value = id; | |
} | |
function refresh() { | |
const id = document.getElementById('user').value; | |
localStorage.setItem('goodreadsUser', id) | |
setMsg(`Fetching Goodreads to-read shelf for user ${id}...`); | |
fetchGoodreadsShelf(id) | |
.catch(() => setMsg("Couldn't fetch data from Goodreads!")) | |
.then(json => json.reviews.review) // the structure: wtf | |
.then(reviews => reviews.map(getBookFromReview)) | |
//.then(printDebug) | |
.then(books => books.map(createRowFromBook)) | |
.then(insertRows) | |
// TODO: handle processing errors | |
} | |
// run automatically | |
init(); | |
refresh(); | |
/* // webtask code: | |
var Request = require('request'); | |
var xml2js = require('[email protected]'); | |
var parser = new xml2js.Parser({ | |
explicitRoot: false, | |
explicitArray: false | |
}); | |
module.exports = function (ctx, done) { | |
var id = ctx.data.id || 20719991; | |
var options = { | |
url: `https://www.goodreads.com/review/list/${id}.xml?key=${ctx.secrets.GOODREADS_API_KEY}&v=2&shelf=to-read&per_page=200`, | |
time: true | |
}; | |
console.log('Requesting', options.url); | |
Request.get(options, function (err, res, body) { | |
parser.parseString(body, function(err_, json) { | |
delete json.Request.key; | |
done(err_, json); | |
}); | |
}); | |
}; | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment