The plugin linked in the OP appears to not be compatible with Python 3. With Python 2 having effectively been EOL'd this year, a version that is compatible with Python 3 would be useful.
Here's my attempt at such a conversion:
https://home.alfter.us/s/aQcprygAZLSpd2B
I've bumped the version number to 1.4.2, set the minimum Calibre version to 4.0, and kept running the converter against an ePub until it ran without errors. These are my changes:
Code:
diff -ur "Modify ePub.py2/common_utils.py" "Modify ePub.py3/common_utils.py"
--- "Modify ePub.py2/common_utils.py" 2015-01-11 10:33:06.000000000 -0800
+++ "Modify ePub.py3/common_utils.py" 2020-08-15 12:49:43.422848052 -0700
@@ -438,7 +438,7 @@
def populate_combo(self, selected_key):
self.clear()
selected_idx = idx = -1
- for key, value in self.values.iteritems():
+ for key, value in self.values.items():
idx = idx + 1
self.addItem(value)
if key == selected_key:
@@ -446,7 +446,7 @@
self.setCurrentIndex(selected_idx)
def selected_key(self):
- for key, value in self.values.iteritems():
+ for key, value in self.values.items():
if value == unicode(self.currentText()).strip():
return key
diff -ur "Modify ePub.py2/container.py" "Modify ePub.py3/container.py"
--- "Modify ePub.py2/container.py" 2020-03-03 18:40:15.000000000 -0800
+++ "Modify ePub.py3/container.py" 2020-08-15 13:31:05.561700105 -0700
@@ -11,8 +11,8 @@
from lxml import etree
from lxml.etree import XMLSyntaxError
-from urlparse import urldefrag, urlparse, urlunparse
-from urllib import unquote as urlunquote
+from urllib.parse import urldefrag, urlparse, urlunparse
+from urllib.parse import unquote as urlunquote
from calibre import guess_type, prepare_string_for_xml
from calibre.ebooks.chardet import xml_to_unicode
@@ -170,11 +170,11 @@
if not base and rel_to_opf:
base = self.opf_dir
if not base:
- return urllib.quote(name)
+ return urllib.parse.quote(name)
href = posixpath.relpath(name, base)
if href == '.':
href = ''
- return urllib.quote(href)
+ return urllib.parse.quote(href)
def abshref(self, href, base_name):
"""Convert the URL provided in :param:`href` from a reference
@@ -303,7 +303,7 @@
"""Automatically decode :param:`data` into a `unicode` object."""
def fix_data(d):
return d.replace('\r\n', '\n').replace('\r', '\n')
- if isinstance(data, unicode):
+ if isinstance(data, str):
return fix_data(data)
bom_enc = None
if data[:4] in ('\0\0\xfe\xff', '\xff\xfe\0\0'):
@@ -682,7 +682,7 @@
self.dirtied.clear()
with ZipFile(path, 'w', compression=ZIP_DEFLATED) as zf:
# Write mimetype
- zf.writestr('mimetype', bytes(guess_type('a.epub')[0]),
+ zf.writestr('mimetype', bytes(guess_type('a.epub')[0], "utf-8"),
compression=ZIP_STORED)
# Write everything else
exclude_files = ['.DS_Store','mimetype']
@@ -863,7 +863,7 @@
data = self.get_parsed_etree(html_name)
body = XPath('//h:body')(data)
if body:
- text = etree.tostring(body[0], method='text', encoding=unicode)
+ text = etree.tostring(body[0]).decode()
else:
text = ''
text = re.sub(r'\s+', '', text)
diff -ur "Modify ePub.py2/covers.py" "Modify ePub.py3/covers.py"
--- "Modify ePub.py2/covers.py" 2012-07-03 09:11:08.000000000 -0700
+++ "Modify ePub.py3/covers.py" 2020-08-15 13:28:40.400708757 -0700
@@ -8,7 +8,8 @@
__docformat__ = 'restructuredtext en'
import posixpath, os
-from urllib import unquote
+from urllib.parse import unquote
+from functools import cmp_to_key
from calibre import fit_image
from calibre.utils.magick.draw import Image
@@ -229,7 +230,7 @@
self.container.delete_from_guide(reference)
# Sort by the largest size
- covers.sort(cmp=lambda x,y:cmp(x[1], y[1]), reverse=True)
+ covers.sort(key=cmp_to_key(lambda x,y:cmp(x[1], y[1])), reverse=True)
if covers:
reference = covers[0][0]
href = reference.get('href')
@@ -367,7 +368,7 @@
tp = templ%unquote(rel_cover_href)
with open(titlepage_path, 'wb') as f:
- f.write(tp)
+ f.write(bytes(tp, "utf-8"))
titlepage_name = os.path.relpath(titlepage_path, self.container.root).replace(os.sep, '/')
return titlepage_name
diff -ur "Modify ePub.py2/css.py" "Modify ePub.py3/css.py"
--- "Modify ePub.py2/css.py" 2013-09-01 00:59:38.000000000 -0700
+++ "Modify ePub.py3/css.py" 2020-08-15 12:49:43.423848052 -0700
@@ -27,7 +27,7 @@
from calibre.ebooks.conversion.config import load_defaults
ps = load_defaults('look_and_feel')
# Only interested in the extra_css out of settings
- prefs_css = dict((k,v) for k,v in ps.iteritems() if k == 'extra_css')
+ prefs_css = dict((k,v) for k,v in ps.items() if k == 'extra_css')
return prefs_css.get('extra_css', '')
def rewrite_css(self):
diff -ur "Modify ePub.py2/dialogs.py" "Modify ePub.py3/dialogs.py"
--- "Modify ePub.py2/dialogs.py" 2019-10-17 03:14:00.000000000 -0700
+++ "Modify ePub.py3/dialogs.py" 2020-08-15 12:49:43.424848051 -0700
@@ -195,7 +195,7 @@
def _save_clicked(self):
self._set_options()
- cfg.plugin_prefs[cfg.STORE_SAVED_SETTINGS] = [k for k,v in self.options.iteritems() if v]
+ cfg.plugin_prefs[cfg.STORE_SAVED_SETTINGS] = [k for k,v in self.options.items() if v]
def _restore_clicked(self):
self._select_none_clicked()
diff -ur "Modify ePub.py2/__init__.py" "Modify ePub.py3/__init__.py"
--- "Modify ePub.py2/__init__.py" 2020-03-12 16:08:36.000000000 -0700
+++ "Modify ePub.py3/__init__.py" 2020-08-15 12:45:15.147864042 -0700
@@ -24,8 +24,8 @@
description = 'Apply cleanup tasks and updates to an ePub without doing a conversion'
supported_platforms = ['windows', 'osx', 'linux']
author = 'Grant Drake, with additions by Robert L. Hood and Leigh Parry'
- version = (1, 4, 1)
- minimum_calibre_version = (0, 8, 53)
+ version = (1, 4, 2)
+ minimum_calibre_version = (4, 0, 0)
#: This field defines the GUI plugin class that contains all the code
#: that actually does something. Its format is module_path:class_name
diff -ur "Modify ePub.py2/margins.py" "Modify ePub.py3/margins.py"
--- "Modify ePub.py2/margins.py" 2012-12-09 16:25:16.000000000 -0800
+++ "Modify ePub.py3/margins.py" 2020-08-15 12:49:43.424848051 -0700
@@ -33,7 +33,7 @@
from calibre.ebooks.conversion.config import load_defaults
ps = load_defaults('page_setup')
# Only interested in the margins out of page setup settings
- prefs_margins = dict((k,v) for k,v in ps.iteritems() if k.startswith('margin_'))
+ prefs_margins = dict((k,v) for k,v in ps.items() if k.startswith('margin_'))
if 'margin_top' not in prefs_margins:
# The user has never changed their page setup defaults to save settings
prefs_margins = calibre_default_margins
@@ -41,7 +41,7 @@
def _prefs_to_css_properties(self, user_margins):
css_margins = ''
- for pref, value in user_margins.iteritems():
+ for pref, value in user_margins.items():
# Negative margins mean we don't want the attribute written
if value >= 0.0:
property_name = re.sub('_', '-', pref)
@@ -86,7 +86,7 @@
# If we got to here, then we found "some" margins in the style that are
# either identical or a subset of our preferred margins
- for pref, pref_value in self.user_margins.iteritems():
+ for pref, pref_value in self.user_margins.items():
if pref_value < 0.0: # The user does not want this margin defined
if pref in doc_defined_margins: # Currently is defined, so remove it
return True
diff -ur "Modify ePub.py2/modify.py" "Modify ePub.py3/modify.py"
--- "Modify ePub.py2/modify.py" 2020-03-03 18:38:14.000000000 -0800
+++ "Modify ePub.py3/modify.py" 2020-08-15 12:49:43.425848051 -0700
@@ -918,7 +918,7 @@
else:
prefs_margins = default_margins
- for s, v in prefs_margins.iteritems():
+ for s, v in prefs_margins.items():
setattr(self.opts, s, v)
def get_epub_output_options():
@@ -935,7 +935,7 @@
else:
prefs_options = default_values
- for s, v in prefs_options.iteritems():
+ for s, v in prefs_options.items():
setattr(self.opts, s, v)
self.opts = OptionValues()