# # I addded all my books to 'owned books' with the Quick Add. # Since none of those books were on an actual shelf I could not export them. # This script will move _all_ owned books to a shelf. # # Use goodreads-oauth-example.py to get an oauth token for your application. # Fill in the consumer and token strings. # Be sure to set target_list to the list you want to move _all_ your owned books onto. # from string import Template import oauth2 as oauth import urlparse import urllib import time import xml.dom.minidom import sys, getopt # If you get 'Title Messed Up By Unicode Error' messages try # export PYTHONIOENCODING=utf-8 target_list = 'own' consumer = oauth.Consumer(key='Your-GoodReads-Key', secret='Your-GoodReads-Secret') token = oauth.Token('oauth token key', 'oauth token secret') client = oauth.Client(consumer, token) url = 'http://www.goodreads.com' ############################# # # who are we? # def getUserId(): response, content = client.request('%s/api/auth_user' % url,'GET') if response['status'] != '200': raise Exception('Cannot fetch resource: %s' % response['status']) # else: # print 'User loaded.' userxml = xml.dom.minidom.parseString(content) user_id = userxml.getElementsByTagName('user')[0].attributes['id'].value return str(user_id) ############################# # # fetch xml for a page of owned books # def getOwnedBooks(page): owned_template = Template('${base}/owned_books/user?format=xml&id=${user_id}&page=${page}&per_page=100') body = urllib.urlencode({}) headers = {'content-type': 'application/x-www-form-urlencoded'} request_url = owned_template.substitute(base=url, user_id=user_id, page=page) response, content = client.request(request_url, 'GET', body, headers) if response['status'] != '200': raise Exception('Failure status: %s for page ' % response['status'] + page) # else: # print 'Page loaded!' return content ############################# # # grab id and title from a node # def getBookInfo(book): book_id = book.getElementsByTagName('id')[0].firstChild.nodeValue book_title = book.getElementsByTagName('title')[0].firstChild.nodeValue return book_id, book_title ############################# # # ask api to add a book to a shelf # def addBookToList(book_id, shelf_name): body = urllib.urlencode({'name': shelf_name, 'book_id': book_id}) headers = {'content-type': 'application/x-www-form-urlencoded'} response, content = client.request('%s/shelf/add_to_shelf.xml' % url,'POST', body, headers) if response['status'] != '201': raise Exception('Failure status: %s' % response['status']) # else: # print 'Book added!' return True ############################# # # loop over each page of owned books # loop over each book # add book to list # user_id = getUserId() print 'User id is: ' + user_id current_page = 0 total_books = 0 while True: current_page = current_page + 1 content = getOwnedBooks(current_page) xmldoc = xml.dom.minidom.parseString(content) page_books = 0 for book in xmldoc.getElementsByTagName('book'): book_id , book_title = getBookInfo(book) try: print 'Book %10s : %s' % (str(book_id), book_title) except UnicodeEncodeError: print 'Book %10s : %s' % (str(book_id), 'Title Messed Up By Unicode Error') page_books += 1 total_books += 1 addBookToList(book_id, target_list) time.sleep(1) print 'Found ' + str(page_books) + ' books on page ' + str(current_page) + ' (total = ' + str(total_books) + ')' time.sleep(1) if (page_books == 0): break; ############################# # # so much fun # print 'Found ' + str(total_books) print 'Done.' ## END ##