diff --git a/src/calibre/ebooks/metadata/__init__.py b/src/calibre/ebooks/metadata/__init__.py index ab9858b5ff..246ba0db73 100644 --- a/src/calibre/ebooks/metadata/__init__.py +++ b/src/calibre/ebooks/metadata/__init__.py @@ -386,3 +386,36 @@ class MetaInformation(object): def __nonzero__(self): return bool(self.title or self.author or self.comments or self.tags) + +def check_isbn10(isbn): + try: + digits = map(int, isbn[:9]) + products = [(i+1)*digits[i] for i in range(9)] + check = sum(products)%11 + if (check == 10 and isbn[9] == 'X') or check == int(isbn[9]): + return isbn + except: + pass + return None + +def check_isbn13(isbn): + try: + digits = map(int, isbn[:12]) + products = [(1 if i%2 ==0 else 3)*digits[i] for i in range(12)] + check = 10 - (sum(products)%10) + if check == 10: + check = 0 + if str(check) == isbn[12]: + return isbn + except: + pass + return None + +def check_isbn(isbn): + isbn = re.sub(r'[^0-9X]', '', isbn).upper() + if len(isbn) == 10: + return check_isbn10(isbn) + if len(isbn) == 13: + return check_isbn13(isbn) + return None + diff --git a/src/calibre/gui2/dialogs/metadata_single.py b/src/calibre/gui2/dialogs/metadata_single.py index 20a3d2a480..435c0b40cd 100644 --- a/src/calibre/gui2/dialogs/metadata_single.py +++ b/src/calibre/gui2/dialogs/metadata_single.py @@ -23,7 +23,8 @@ from calibre.gui2.dialogs.fetch_metadata import FetchMetadata from calibre.gui2.dialogs.tag_editor import TagEditor from calibre.gui2.widgets import ProgressIndicator from calibre.ebooks import BOOK_EXTENSIONS -from calibre.ebooks.metadata import authors_to_sort_string, string_to_authors, authors_to_string +from calibre.ebooks.metadata import authors_to_sort_string, string_to_authors, \ + authors_to_string, check_isbn from calibre.ebooks.metadata.library_thing import cover_from_isbn from calibre import islinux from calibre.ebooks.metadata.meta import get_metadata @@ -336,6 +337,7 @@ class MetadataSingleDialog(ResizableDialog, Ui_MetadataSingleDialog): isbn = db.isbn(self.id, index_is_id=True) if not isbn: isbn = '' + self.isbn.textChanged.connect(self.validate_isbn) self.isbn.setText(isbn) aus = self.db.author_sort(row) self.author_sort.setText(aus if aus else '') @@ -394,6 +396,20 @@ class MetadataSingleDialog(ResizableDialog, Ui_MetadataSingleDialog): self.cover.setPixmap(pm) self.cover_data = cover + def validate_isbn(self, isbn): + isbn = unicode(isbn).strip() + if not isbn: + self.isbn.setStyleSheet('QLineEdit { background-color: rgba(0,255,0,0%) }') + self.isbn.setToolTip(_('This ISBN number is valid')) + return + + if check_isbn(isbn): + self.isbn.setStyleSheet('QLineEdit { background-color: rgba(0,255,0,20%) }') + self.isbn.setToolTip(_('This ISBN number is valid')) + else: + self.isbn.setStyleSheet('QLineEdit { background-color: rgba(255,0,0,20%) }') + self.isbn.setToolTip(_('This ISBN number is invalid')) + def show_format(self, item, *args): fmt = item.ext self.emit(SIGNAL('view_format(PyQt_PyObject)'), fmt)