Skip to content

Instantly share code, notes, and snippets.

@slackorama
Created January 8, 2019 00:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save slackorama/1170ba8f060fe96fbdc49ca5cdc2db0b to your computer and use it in GitHub Desktop.
Save slackorama/1170ba8f060fe96fbdc49ca5cdc2db0b to your computer and use it in GitHub Desktop.
get your read shelf from good reads and output an org table.
#!/usr/bin/env python
"""Grab the books from the current year from goodreads and emit an org mode table.
"""
from __future__ import print_function
import datetime
from email.utils import parsedate
import sys
import time
from xml.dom import minidom
import requests
def get_crap(obj, tag):
"""Grab the firstChild of the first elements with the given tag."""
elements = obj.getElementsByTagName(tag)
child = None
if len(elements) >= 1:
child = elements[0].firstChild
return child
def get_year(review):
"Get the year from the `read_at` node."
read_at = get_crap(review, 'read_at')
if read_at is None:
return "???"
read_at = read_at.data
read_at = datetime.datetime.fromtimestamp(time.mktime(parsedate(read_at)))
return str(read_at.year)
def main(args):
"uh..main"
goodreads_key = args[1]
more_pages = True
page = 1
while more_pages:
# URL =
url = 'https://www.goodreads.com/review/list'
params = {
'key': goodreads_key,
'v': 2,
'format': 'xml',
'id': 1519786,
'per_page': 200,
'shelf': 'read',
'page': page}
req = requests.get(url, params=params)
if req.status_code != 200:
print('Bad request!')
sys.exit(1)
xmldoc = minidom.parseString(req.content)
reviews = xmldoc.getElementsByTagName('reviews')[0]
end = reviews.getAttribute('end')
total = reviews.getAttribute('total')
if end == total:
# this is the last page
more_pages = False
else:
page = page+1
for review in reviews.getElementsByTagName('review'):
authors = review.getElementsByTagName('authors')
print_data = {
'year': get_year(review),
'title': get_crap(review, 'title').data.encode('UTF-8'),
'link': get_crap(review, 'link').data,
'rating': get_crap(review, 'rating').data.encode('UTF-8')
}
if len(authors) == 1:
print_data['author'] = get_crap(authors[0], 'name').data.encode('utf-8')
else:
print_data['author'] = 'Multiple Authors'
print('|{year}|[[{link}][{title}]] by {author} ({rating} stars)|'.format(**print_data))
if __name__ == '__main__':
main(sys.argv)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment