View Single Post
Old 12-11-2022, 09:53 AM   #6
chaley
Grand Sorcerer
chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.
 
Posts: 12,476
Karma: 8025702
Join Date: Jan 2010
Location: Notts, England
Device: Kobo Libra 2
Here are two solutions, one in GPM and one in Python.
Code:
program: 
	new_ids = '';
	found_isbn = '';

# first search for an isbn. Remove it from the list if found.
	for id in $identifiers:
		if '^isbn:' in id then
			found_isbn = '1'
		else
# Can't use list operations because ids can contain commas
			new_ids = new_ids & (if new_ids then ', ' fi) & id
  		fi
	rof;

# If we found an isbn try to convert it and then add it back into the identifiers list
	if found_isbn then
		isbn = isbn10_to_13();
		newisbn = strcat('isbn:', isbn);
		new_ids & (if new_ids then ', ' fi) & newisbn
	else
		$identifiers
	fi
Here is a solution in Python. This will be much faster but probably harder for you to understand what it does. It doesn't use the stored template, instead including the conversion functions directly.
Code:
python:
def evaluate(book, context):
	new_ids = {}
	# Copy the identifiers dict, replacing isbns with the converted value
	for k,v in book.identifiers.items():
		new_ids[k] = convert_isbn(v) if k == 'isbn' else v
	# Rebuild the identifiers string from the new identifiers dict
	return ', '.join([k + ':' + v for k,v in new_ids.items()])
		
def convert_isbn(isbn):
	if len(isbn) != 10:
		# This isn't an isbn 10. Return it as it is.
		return isbn
	prefix = '978' + isbn[:-1]
	check = check_digit_13(prefix)
	return prefix + check

def check_digit_13(isbn):
	sum = 0
	for i in range(len(isbn)):
		c = int(isbn[i])
		if i % 2: w = 3
		else: w = 1
		sum += w * c
	r = 10 - (sum % 10)
	if r == 10: return '0'
	else: return str(r)
chaley is offline   Reply With Quote