added core edition googlebooks lookup and test, plus the start of a load_books management command

pull/1/head
Ed Summers 2011-09-07 05:34:03 -04:00
parent ded6c1719f
commit 19d73f8bf8
7 changed files with 194 additions and 69 deletions

View File

@ -1,51 +0,0 @@
"""
A simplistic module for looking up books via varioius web service APIs.
"""
import json
import requests
def openlibrary_book(isbn):
response = requests.get("http://openlibrary.org/api/books?",
params={"bibkeys": "ISBN:%s" % isbn,
"format": "json",
"jscmd": "data"})
if response.status_code != 200:
raise LookupFailure("failed to look up %s at OpenLibrary" % isbn)
hits = json.loads(response.content).values()
if len(hits) == 1:
return hits[0]
return None
def googlebooks_book(isbn):
response = requests.get('https://www.googleapis.com/books/v1/volumes',
params={'q': "isbn:%s" % isbn})
if response.status_code != 200:
raise LookupFailure("failed to look up %s at GoogleBooks" % isbn)
books = json.loads(response.content)
if books['totalItems'] == 1:
return books['items'][0]
return None
class LookupFailure(Exception):
pass
if __name__ == "__main__":
# list of books from Amanda
isbns = [
"0811216993", "0811216713", "1564780880", "0156709902",
"0803260970", "0231145365", "0745647863", "0393302318",
"1590171101", "015602909X", "0156576813", "0156982900",
"0156189798", "0553380834", "0375706682", "055380491X",
"0553378589", "0684831074", "0761148574", "1563053381",
"0520256093", "0679442707", "0375754741",
]
for isbn in isbns:
b = googlebooks_book(isbn)
google_id = b['id'] if b != None else ""
title = b['volumeInfo']['title']
b = openlibrary_book(isbn)
openlibrary_id = b['key'] if b != None else ""
print "\t".join([isbn, title, google_id, openlibrary_id])

101
core/books.py Executable file
View File

@ -0,0 +1,101 @@
from django.conf import settings
import json
import logging
import requests
def get_edition(isbn):
# lookup the isbn at googlebooks
results = googlebooks_search("isbn:%s" % isbn)
if results['totalItems'] == 0:
return None
elif results['totalItems'] > 1:
return LookupFailure("multiple results for isbn %s" % isbn)
# get the edition detail from google
google_id = results['items'][0]['id']
i = googlebooks_volume(google_id)
# normalize some of the googlebooks data
edition = {
'title': i['volumeInfo']['title'],
'authors': i['volumeInfo']['authors'],
'description': i['volumeInfo']['description'],
'categories': i['volumeInfo']['categories'],
'language': i['volumeInfo']['language'],
'publisher': i['volumeInfo']['publisher'],
'publication_date': i['volumeInfo']['publishedDate'],
'page_count': i['volumeInfo']['pageCount'],
'google_books_id': i['id'],
'cover_image_url': i['volumeInfo']['imageLinks']['thumbnail'],
'isbn_10': [],
'isbn_13': []
}
for identifier in i['volumeInfo'].get('industryIdentifiers', []):
if identifier['type'] == 'ISBN_10':
edition['isbn_10'].append(identifier['identifier'])
elif identifier['type'] == 'ISBN_13':
edition['isbn_13'].append(identifier['identifier'])
return edition
def get_work(isbn):
return {'title': 'Neuromancer'}
def googlebooks_search(q):
params = {"q": q, "key": settings.GOOGLE_BOOKS_API_KEY}
url = 'https://www.googleapis.com/books/v1/volumes'
return _get_json(url, params)
def googlebooks_volume(google_books_id):
params = {"key": settings.GOOGLE_BOOKS_API_KEY}
url = "https://www.googleapis.com/books/v1/volumes/%s" % google_books_id
return _get_json(url, params)
def _get_json(url, params):
response = requests.get(url, params=params)
if response.status_code == 200:
return json.loads(response.content)
else:
logging.error("unexpected HTTP response: %s" % response)
raise LookupFailure("GET failed: url=%s and params=%s" % (url, params))
class LookupFailure(Exception):
pass
if __name__ == "__main__":
# list of books from Amanda
isbns = [
# amanda's first list
"0811216993", "0811216713", "1564780880", "0156709902",
"0803260970", "0231145365", "0745647863", "0393302318",
"1590171101", "015602909X", "0156576813", "0156982900",
"0156189798", "0553380834", "0375706682", "055380491X",
"0553378589", "0684831074", "0761148574", "1563053381",
"0520256093", "0679442707", "0375754741",
# amanda's second list
"0547773986", "0719595800", "1582432104", "0156372088",
"0139391401", "0300022867", "0300084587", "0691063184",
"0691004765", "0940242753", "0671240773", "0060852240",
"0307270807", "0520047834", "0471609978", "0030839939",
"0465027822", "0465028381", "0716760355", "1597261076",
"1559638583", "0393014886", "0452011752", "0151400563",
"0812536363", "0441007465", "0441569595", "0441012035",
"0393311198", "0525200150", "0375704078", "0773723749",
"0760759146", "0441478123", "0553383043", "006076029X",
"0802714544", "0743442539", "0743431677",
]
for isbn in isbns:
print get_edition(isbn)

View File

View File

View File

@ -0,0 +1,12 @@
from django.core.management.base import BaseCommand
from regluit.core import books
class Command(BaseCommand):
help = "load books based on a text file of ISBNs"
args = "<filename>"
def handle(self, filename, **options):
for isbn in open(filename):
isbn = isbn.strip()
print books.get_edition(isbn)

View File

@ -1,23 +1,24 @@
"""
This file demonstrates two different styles of tests (one doctest and one
unittest). These will both pass when you run "manage.py test".
Replace these with more appropriate tests for your application.
"""
from django.test import TestCase
class SimpleTest(TestCase):
def test_basic_addition(self):
"""
Tests that 1 + 1 always equals 2.
"""
self.failUnlessEqual(1 + 1, 2)
from regluit.core import books
__test__ = {"doctest": """
Another way to test that 1 + 1 is equal to 2.
class TestBooks(TestCase):
>>> 1 + 1 == 2
True
"""}
def test_get_edition(self):
edition = books.get_edition(isbn='0441012035')
self.assertEqual(edition['title'], 'Neuromancer')
self.assertEqual(edition['publication_date'], '2004')
self.assertEqual(edition['publisher'], 'Ace Books')
self.assertEqual(edition['page_count'], 371)
self.assertEqual(edition['authors'], ['William Gibson'])
self.assertEqual(edition['isbn_10'], ['0441012035'])
self.assertEqual(edition['isbn_13'], ['9780441012039'])
self.assertEqual(edition['google_books_id'], '2NyiPwAACAAJ')
self.assertTrue('Fiction / Science Fiction / General' in edition['categories'])
self.assertTrue('The future blazed into existence with each deliberate word' in edition['description'])
self.assertEqual(edition['cover_image_url'], 'http://bks3.books.google.com/books?id=2NyiPwAACAAJ&printsec=frontcover&img=1&zoom=1&source=gbs_api')
def test_get_work(self):
work = books.get_work(isbn='0441012035')
self.assertEqual(work['title'], 'Neuromancer')

View File

@ -0,0 +1,62 @@
0811216993
0811216713
1564780880
0156709902
0803260970
0231145365
0745647863
0393302318
1590171101
015602909X
0156576813
0156982900
0156189798
0553380834
0375706682
055380491X
0553378589
0684831074
0761148574
1563053381
0520256093
0679442707
0375754741
0547773986
0719595800
1582432104
0156372088
0139391401
0300022867
0300084587
0691063184
0691004765
0940242753
0671240773
0060852240
0307270807
0520047834
0471609978
0030839939
0465027822
0465028381
0716760355
1597261076
1559638583
0393014886
0452011752
0151400563
0812536363
0441007465
0441569595
0441012035
0393311198
0525200150
0375704078
0773723749
0760759146
0441478123
0553383043
006076029X
0802714544
0743442539
0743431677