Guess not attachments on oclug list so it is here.
On Friday 17 April 2009 3:11:16 pm Bruce Harding wrote:
>
> No not to much of a hurry. Right all images prior to mid-2008 are named
> with there 10 digit ISBN.
>
> I found this attached script as well.
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
#
# isbn.py
#
# Code for messing with ISBN numbers
# Especially stuff for converting between ISBN-10 and ISBN-13
#
# Copyright (C) 2007 Darren J Wilkinson
# 2008 Osvaldo Santana Neto <osantana [ at ] gmail [ dot ] com>
#
# Free GPL code
# Last updated: 14/8/2007
"""
Code for messing with ISBN numbers. Stuff for validating ISBN-10 and
ISBN-13 numbers, computing check digits and converting from one format
to the other.
This code doesn't know anything about proper hyphenation of ISBNs. Nor does
it know anything about the real "validity" of ISBNs - it just validates on
the basis of the check-digit.
Some examples::
>>> valid("3-79081-945-X")
True
>>> valid("1-58488-540-8")
True
>>> valid("1-58488-540-5")
False
>>> valid("978-1@#$5848ZZZYYY8-540-5")
True
>>> check("1-58488-540")
'8'
>>> check("3-79081-945")
'X'
>>> check("978-158488-540")
'5'
>>> valid_isbn13("978-158488-540-5")
True
>>> valid_isbn10("978-158488-540-5")
False
>>> strip("978-1ZYUI58488-540-5")
'9781584885405'
>>> convert("1-58488-540-8")
'9781584885405'
>>> convert("978-158488-540-5")
'1584885408'
>>> convert("1-8758488-540-8")
Traceback (most recent call last):
...
ValueError: Invalid ISBN
>>> to_isbn13("1-58488-540-8")
'9781584885405'
>>> to_isbn13("978-158488-540-5")
'9781584885405'
>>> to_isbn10("978-158488-540-5")
'1584885408'
>>> to_isbn10("1584885408")
'1584885408'
>>> format("1584885408", "")
'1584885408'
>>> format("1584885408", "-")
'1-58488-540-8'
>>> format("1584885408", " ")
'1 58488 540 8'
>>> format("9781584885405")
'9781584885405'
>>> format("9781584885405", "-")
'978-158488-540-5'
>>> format("97815ASDQWE!@#84885405", "-")
'978-158488-540-5'
>>> format("9781584883ASDF@#$l5405", "-")
'9781584883ASDF@#$l5405'
>>> url("amazon", "978-158488-540-5")
'http://www.amazon.com/o/ASIN/1584885408'
The code is very simple pure python code in a single source file. Please
read the source code file (isbn.py) for further information about how
it works.
Please send bug reports, bug fixes, etc. to:
darrenjwilkinson [ at ] btinternet [ dot ] com
Free GPL code, Copyright (C) 2007 Darren J Wilkinson
http://www.staff.ncl.ac.uk/d.j.wilkinson/
Or, if you are using the isbn.py utility version send your bug reports, fixes,
etc. to:
Osvaldo Santana Neto <osantana [ at ] gmail [ dot ] com>
http://www.pythonologia.org/
"""
import sys
(OK,
INVALID,
ERROR,
) = range(3)
def strip(isbn):
"""Strip whitespace, hyphens, etc. from an ISBN number and return the
result."""
return filter(lambda x: str.isdigit(x) or x.upper() == "X", isbn)
def convert(isbn):
"""Convert an ISBN-10 to ISBN-13 or vice-versa."""
short = strip(isbn)
if not valid(short):
raise ValueError("Invalid ISBN")
if len(short) == 10:
stem = "978" + short[:-1]
return stem + check(stem)
else:
if short.startswith("978"):
stem = short[3:-1]
return stem + check(stem)
else:
raise ValueError("ISBN not convertible")
def valid(isbn):
"""Check the validity of an ISBN. Works for either ISBN-10 or ISBN-13."""
short = strip(isbn)
if len(short) == 10:
return valid_isbn10(short)
if len(short) == 13:
return valid_isbn13(short)
return False
def check(stem):
"""Compute the check digit for the stem of an ISBN. Works with either the
first 9 digits of an ISBN-10 or the first 12 digits of an ISBN-13."""
short = strip(stem)
if len(short) == 9:
return check_isbn10(short)
if len(short) == 12:
return check_isbn13(short)
return False
def check_isbn10(stem):
"""Computes the ISBN-10 check digit based on the first 9 digits of a
stripped ISBN-10 number."""
check = 11 - sum( (x+2) * int(y) for x,y in enumerate(reversed(stem)) ) %
11
if check == 10:
return "X"
elif check == 11:
return "0"
return str(check)
def valid_isbn10(isbn):
"""Checks the validity of an ISBN-10 number."""
short = strip(isbn)
if len(short) != 10:
return False
digits = [ (10 if x.upper() == "X" else int(x)) for x in short ]
return (sum( (x+1)*y for x,y in enumerate(reversed(digits)) ) % 11) == 0
def check_isbn13(stem):
"""Compute the ISBN-13 check digit based on the first 12 digits of a
stripped ISBN-13 number. """
check = 10 - sum( (x%2*2+1) * int(y) for x,y in enumerate(stem) ) % 10
if check == 10:
return "0"
return str(check)
def valid_isbn13(isbn):
"""Checks the validity of an ISBN-13 number."""
short = strip(isbn)
if len(short) != 13:
return False
digits = [ (10 if x.upper() == "X" else int(x)) for x in short ]
return (sum( (x%2*2+1) * y for x,y in enumerate(digits) ) % 10) == 0
def to_isbn10(isbn):
"""Converts supplied ISBN (either ISBN-10 or ISBN-13) to a stripped
ISBN-10."""
if not valid(isbn):
raise ValueError("Invalid ISBN")
if valid_isbn10(isbn):
return strip(isbn)
else:
return convert(isbn)
def to_isbn13(isbn):
"""Converts supplied ISBN (either ISBN-10 or ISBN-13) to a stripped
ISBN-13."""
if not valid(isbn):
raise ValueError("Invalid ISBN")
if valid_isbn13(isbn):
return strip(isbn)
else:
return convert(isbn)
def url(type_, isbn):
"""Returns a URL for a book, corresponding to the "type" and the "isbn"
provided. This function is likely to go out-of-date quickly, and is
provided mainly as an example of a potential use-case for the module.
Currently allowed types are "google-books" (the default if the type is not
recognised), "amazon", "amazon-uk", "blackwells"."""
short = to_isbn10(isbn)
providers = {
'amazon': 'http://www.amazon.com/o/ASIN/%s',
'amazon-uk': 'http://www.amazon.co.uk/o/ASIN/%s',
'blackwells': 'http://bookshop.blackwell.co.uk/jsp/welcome.jsp?action=search&type=isbn&term=%s',
}
return providers.get(type_, "http://books.google.com/books?vid=%s") %
(short,)
def format(isbn, sep=""):
s = strip(isbn)
if len(s) == 10:
return s[0] + sep + s[1:6] + sep + s[6:9] + sep + s[9]
if len(s) == 13:
return s[0:3] + sep + s[3:9] + sep + s[9:12] + sep + s[12]
return isbn
def main():
from optparse import OptionParser
usage = """usage: %prog [options] ISBN
If ISBN arg is an ISBN-13:
--isbn13 will check the ISBN number (and return an error code with the
result)
--isbn10 will convert the ISBN-13 to ISBN-10
If ISBN arg is an ISBN-10:
--isbn10 will check the ISBN number (and return an error code with the
result)
--isbn13 will convert the ISBN-10 to ISBN-13
"""
parser = OptionParser(usage=usage)
parser.add_option("-3", "--isbn13", action="store_true", dest="isbn13",
default=True,
help="check or convert a ISBN-13 value (default)")
parser.add_option("-0", "--isbn10", action="store_false", dest="isbn13",
help="check or convert a ISBN-10 value")
parser.add_option("-s", "--separator", dest="separator", metavar="SEP",
default="",
help="select a ISBN separator character. (default: '%default')")
parser.add_option("-q", "--quiet", action="store_false", dest="verbose",
default=True,
help="quiet (no output)")
parser.add_option("-t", "--test", action="store_true", dest="test",
help="test internal functions (useful for developers).")
(options, args) = parser.parse_args()
if options.test:
import doctest
doctest.testmod()
sys.exit(0)
if not args:
parser.error("incorrect number of arguments.")
verbose = options.verbose
separator = options.separator
isbn = strip(args[0])
if len(isbn) == 13:
valid_func = valid_isbn13
only_check = options.isbn13
elif len(isbn) == 10:
valid_func = valid_isbn10
only_check = not options.isbn13
else: # invalid input
if verbose:
print "INVALID: %s" % (isbn,)
return INVALID
if only_check: # check it
if valid_func(isbn): # OK!
if verbose:
print format(isbn, separator)
return OK
else: # NOT OK!
if verbose:
print "INVALID: %s" % (isbn,)
return INVALID
else: # convert it
try:
n_isbn = convert(isbn)
except ValueError: # CANNOT CONVERT!
if verbose:
print "INVALID: %s" % (isbn,)
return INVALID
if verbose: # CONVERT!
print format(n_isbn, separator)
return OK
if __name__=='__main__':
sys.exit(main())
# vim:ts=4:sw=4:et:si:ai:sm
--
Bruce Harding, Member: IEEE, SPIE, IACR
Manager,
Computer Books for Less
210 Bank St.
Ottawa ON K2P 1W2
Phone: 613-233-7357
Fax: 613-233-6823