diff --git a/src/calibre/devices/kindle/driver.py b/src/calibre/devices/kindle/driver.py index 9cd41ce557..24f6220e47 100644 --- a/src/calibre/devices/kindle/driver.py +++ b/src/calibre/devices/kindle/driver.py @@ -267,6 +267,7 @@ class KINDLE(USBMS): def add_annotation_to_library(self, db, db_id, annotation): from calibre.ebooks.metadata import MetaInformation + from calibre.ebooks.BeautifulSoup import prettify bm = annotation ignore_tags = {'Catalog', 'Clippings'} @@ -289,9 +290,9 @@ class KINDLE(USBMS): hrTag['class'] = 'annotations_divider' user_notes_soup.insert(0, hrTag) - mi.comments += unicode_type(user_notes_soup.prettify()) + mi.comments += prettify(user_notes_soup) else: - mi.comments = unicode_type(user_notes_soup.prettify()) + mi.comments = prettify(user_notes_soup) # Update library comments db.set_comment(db_id, mi.comments) diff --git a/src/calibre/devices/kobo/driver.py b/src/calibre/devices/kobo/driver.py index a051d2951e..c9f9f295ac 100644 --- a/src/calibre/devices/kobo/driver.py +++ b/src/calibre/devices/kobo/driver.py @@ -1299,6 +1299,7 @@ class KOBO(USBMS): return ka_soup def add_annotation_to_library(self, db, db_id, annotation): + from calibre.ebooks.BeautifulSoup import prettify bm = annotation ignore_tags = {'Catalog', 'Clippings'} @@ -1321,9 +1322,9 @@ class KOBO(USBMS): hrTag['class'] = 'annotations_divider' user_notes_soup.insert(0, hrTag) - mi.comments += unicode_type(user_notes_soup.prettify()) + mi.comments += prettify(user_notes_soup) else: - mi.comments = unicode_type(user_notes_soup.prettify()) + mi.comments = prettify(user_notes_soup) # Update library comments db.set_comment(db_id, mi.comments) diff --git a/src/calibre/ebooks/BeautifulSoup.py b/src/calibre/ebooks/BeautifulSoup.py index b0913ba2cf..24e2dd4526 100644 --- a/src/calibre/ebooks/BeautifulSoup.py +++ b/src/calibre/ebooks/BeautifulSoup.py @@ -26,6 +26,13 @@ def parse_html(markup): return parse(markup, return_root=False) +def prettify(soup): + ans = soup.prettify() + if isinstance(ans, bytes): + ans = ans.decode('utf-8') + return ans + + def BeautifulSoup(markup='', *a, **kw): return parse_html(markup) diff --git a/src/calibre/library/catalogs/epub_mobi_builder.py b/src/calibre/library/catalogs/epub_mobi_builder.py index 3aa4e2d149..1a795810fc 100644 --- a/src/calibre/library/catalogs/epub_mobi_builder.py +++ b/src/calibre/library/catalogs/epub_mobi_builder.py @@ -13,7 +13,7 @@ from calibre import ( from calibre.constants import isosx, cache_dir from calibre.customize.conversion import DummyReporter from calibre.customize.ui import output_profiles -from calibre.ebooks.BeautifulSoup import BeautifulSoup, BeautifulStoneSoup, NavigableString +from calibre.ebooks.BeautifulSoup import BeautifulSoup, BeautifulStoneSoup, NavigableString, prettify from calibre.ebooks.chardet import substitute_entites from calibre.ebooks.metadata import author_to_author_sort from calibre.library.catalogs import AuthorSortMismatchException, EmptyCatalogException, \ @@ -1621,9 +1621,8 @@ class CatalogBuilder(object): # Write the generated file to content_dir outfile_spec = "%s/ByAlphaAuthor.html" % (self.content_dir) - outfile = open(outfile_spec, 'w') - outfile.write(soup.prettify()) - outfile.close() + with open(outfile_spec, 'wb') as outfile: + outfile.write(prettify(soup).encode('utf-8')) self.html_filelist_1.append("content/ByAlphaAuthor.html") def generate_html_by_date_added(self): @@ -1885,9 +1884,8 @@ class CatalogBuilder(object): # Write the generated file to content_dir outfile_spec = "%s/ByDateAdded.html" % (self.content_dir) - outfile = open(outfile_spec, 'w') - outfile.write(soup.prettify()) - outfile.close() + with open(outfile_spec, 'wb') as outfile: + outfile.write(prettify(soup).encode('utf-8')) self.html_filelist_2.append("content/ByDateAdded.html") def generate_html_by_date_read(self): @@ -2062,9 +2060,8 @@ class CatalogBuilder(object): # Write the generated file to content_dir outfile_spec = "%s/ByDateRead.html" % (self.content_dir) - outfile = open(outfile_spec, 'w') - outfile.write(soup.prettify()) - outfile.close() + with open(outfile_spec, 'wb') as outfile: + outfile.write(prettify(soup).encode('utf-8')) self.html_filelist_2.append("content/ByDateRead.html") def generate_html_by_genres(self): @@ -2309,9 +2306,8 @@ class CatalogBuilder(object): dtc += 1 # Write the generated file to content_dir - outfile = open(outfile, 'w') - outfile.write(soup.prettify()) - outfile.close() + with open(outfile, 'wb') as outfile: + outfile.write(prettify(soup).encode('utf-8')) if len(books) > 1: titles_spanned = [(books[0]['author'], books[0]['title']), (books[-1]['author'], books[-1]['title'])] @@ -2469,9 +2465,8 @@ class CatalogBuilder(object): # Write the generated file to content_dir outfile_spec = "%s/BySeries.html" % (self.content_dir) - outfile = open(outfile_spec, 'w') - outfile.write(soup.prettify()) - outfile.close() + with open(outfile_spec, 'wb') as outfile: + outfile.write(prettify(soup).encode('utf-8')) self.html_filelist_1.append("content/BySeries.html") def generate_html_by_title(self): @@ -2624,9 +2619,8 @@ class CatalogBuilder(object): # Write the volume to content_dir outfile_spec = "%s/ByAlphaTitle.html" % (self.content_dir) - outfile = open(outfile_spec, 'w') - outfile.write(soup.prettify()) - outfile.close() + with open(outfile_spec, 'wb') as outfile: + outfile.write(prettify(soup).encode('utf-8')) self.html_filelist_1.append("content/ByAlphaTitle.html") def generate_html_description_header(self, book): @@ -2845,9 +2839,8 @@ class CatalogBuilder(object): soup = self.generate_html_description_header(title) # Write the book entry to content_dir - outfile = open("%s/book_%d.html" % (self.content_dir, int(title['id'])), 'w') - outfile.write(soup.prettify()) - outfile.close() + with open("%s/book_%d.html" % (self.content_dir, int(title['id'])), 'wb') as outfile: + outfile.write(prettify(soup).encode('utf-8')) def generate_html_empty_header(self, title): """ Return a boilerplate HTML header.