mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Sync to pluginize
This commit is contained in:
commit
00f24eaf5d
@ -30,7 +30,7 @@ def _config():
|
|||||||
c.add_opt('filetype_mapping', default={}, help=_('Mapping for filetype plugins'))
|
c.add_opt('filetype_mapping', default={}, help=_('Mapping for filetype plugins'))
|
||||||
c.add_opt('plugin_customization', default={}, help=_('Local plugin customization'))
|
c.add_opt('plugin_customization', default={}, help=_('Local plugin customization'))
|
||||||
c.add_opt('disabled_plugins', default=set([]), help=_('Disabled plugins'))
|
c.add_opt('disabled_plugins', default=set([]), help=_('Disabled plugins'))
|
||||||
|
|
||||||
return ConfigProxy(c)
|
return ConfigProxy(c)
|
||||||
|
|
||||||
config = _config()
|
config = _config()
|
||||||
@ -45,7 +45,7 @@ class PluginNotFound(ValueError):
|
|||||||
def load_plugin(path_to_zip_file):
|
def load_plugin(path_to_zip_file):
|
||||||
'''
|
'''
|
||||||
Load plugin from zip file or raise InvalidPlugin error
|
Load plugin from zip file or raise InvalidPlugin error
|
||||||
|
|
||||||
:return: A :class:`Plugin` instance.
|
:return: A :class:`Plugin` instance.
|
||||||
'''
|
'''
|
||||||
print 'Loading plugin from', path_to_zip_file
|
print 'Loading plugin from', path_to_zip_file
|
||||||
@ -61,9 +61,9 @@ def load_plugin(path_to_zip_file):
|
|||||||
if x.minimum_calibre_version > version or \
|
if x.minimum_calibre_version > version or \
|
||||||
platform not in x.supported_platforms:
|
platform not in x.supported_platforms:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
return x
|
return x
|
||||||
|
|
||||||
raise InvalidPlugin(_('No valid plugin found in ')+path_to_zip_file)
|
raise InvalidPlugin(_('No valid plugin found in ')+path_to_zip_file)
|
||||||
|
|
||||||
_initialized_plugins = []
|
_initialized_plugins = []
|
||||||
@ -122,8 +122,8 @@ def reread_metadata_plugins():
|
|||||||
for ft in plugin.file_types:
|
for ft in plugin.file_types:
|
||||||
if not _metadata_writers.has_key(ft):
|
if not _metadata_writers.has_key(ft):
|
||||||
_metadata_writers[ft] = []
|
_metadata_writers[ft] = []
|
||||||
_metadata_writers[ft].append(plugin)
|
_metadata_writers[ft].append(plugin)
|
||||||
|
|
||||||
def metadata_readers():
|
def metadata_readers():
|
||||||
ans = set([])
|
ans = set([])
|
||||||
for plugins in _metadata_readers.values():
|
for plugins in _metadata_readers.values():
|
||||||
@ -136,8 +136,8 @@ def metadata_writers():
|
|||||||
for plugins in _metadata_writers.values():
|
for plugins in _metadata_writers.values():
|
||||||
for plugin in plugins:
|
for plugin in plugins:
|
||||||
ans.add(plugin)
|
ans.add(plugin)
|
||||||
return ans
|
return ans
|
||||||
|
|
||||||
def get_file_type_metadata(stream, ftype):
|
def get_file_type_metadata(stream, ftype):
|
||||||
mi = MetaInformation(None, None)
|
mi = MetaInformation(None, None)
|
||||||
ftype = ftype.lower().strip()
|
ftype = ftype.lower().strip()
|
||||||
@ -163,21 +163,21 @@ def set_file_type_metadata(stream, mi, ftype):
|
|||||||
plugin.set_metadata(stream, mi, ftype.lower().strip())
|
plugin.set_metadata(stream, mi, ftype.lower().strip())
|
||||||
break
|
break
|
||||||
except:
|
except:
|
||||||
print 'Failed to set metadata for', repr(getattr(mi, 'title', ''))
|
print 'Failed to set metadata for', repr(getattr(mi, 'title', ''))
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
|
|
||||||
|
|
||||||
def _run_filetype_plugins(path_to_file, ft=None, occasion='preprocess'):
|
def _run_filetype_plugins(path_to_file, ft=None, occasion='preprocess'):
|
||||||
occasion = {'import':_on_import, 'preprocess':_on_preprocess,
|
occasion = {'import':_on_import, 'preprocess':_on_preprocess,
|
||||||
'postprocess':_on_postprocess}[occasion]
|
'postprocess':_on_postprocess}[occasion]
|
||||||
customization = config['plugin_customization']
|
customization = config['plugin_customization']
|
||||||
if ft is None:
|
if ft is None:
|
||||||
ft = os.path.splitext(path_to_file)[-1].lower().replace('.', '')
|
ft = os.path.splitext(path_to_file)[-1].lower().replace('.', '')
|
||||||
nfp = path_to_file
|
nfp = path_to_file
|
||||||
for plugin in occasion.get(ft, []):
|
for plugin in occasion.get(ft, []):
|
||||||
if is_disabled(plugin):
|
if is_disabled(plugin):
|
||||||
continue
|
continue
|
||||||
plugin.site_customization = customization.get(plugin.name, '')
|
plugin.site_customization = customization.get(plugin.name, '')
|
||||||
with plugin:
|
with plugin:
|
||||||
try:
|
try:
|
||||||
nfp = plugin.run(path_to_file)
|
nfp = plugin.run(path_to_file)
|
||||||
@ -190,13 +190,13 @@ def _run_filetype_plugins(path_to_file, ft=None, occasion='preprocess'):
|
|||||||
nfp = path_to_file
|
nfp = path_to_file
|
||||||
return nfp
|
return nfp
|
||||||
|
|
||||||
run_plugins_on_import = functools.partial(_run_filetype_plugins,
|
run_plugins_on_import = functools.partial(_run_filetype_plugins,
|
||||||
occasion='import')
|
occasion='import')
|
||||||
run_plugins_on_preprocess = functools.partial(_run_filetype_plugins,
|
run_plugins_on_preprocess = functools.partial(_run_filetype_plugins,
|
||||||
occasion='preprocess')
|
occasion='preprocess')
|
||||||
run_plugins_on_postprocess = functools.partial(_run_filetype_plugins,
|
run_plugins_on_postprocess = functools.partial(_run_filetype_plugins,
|
||||||
occasion='postprocess')
|
occasion='postprocess')
|
||||||
|
|
||||||
|
|
||||||
def initialize_plugin(plugin, path_to_zip_file):
|
def initialize_plugin(plugin, path_to_zip_file):
|
||||||
try:
|
try:
|
||||||
@ -206,7 +206,7 @@ def initialize_plugin(plugin, path_to_zip_file):
|
|||||||
tb = traceback.format_exc()
|
tb = traceback.format_exc()
|
||||||
raise InvalidPlugin((_('Initialization of plugin %s failed with traceback:')
|
raise InvalidPlugin((_('Initialization of plugin %s failed with traceback:')
|
||||||
%tb) + '\n'+tb)
|
%tb) + '\n'+tb)
|
||||||
|
|
||||||
|
|
||||||
def add_plugin(path_to_zip_file):
|
def add_plugin(path_to_zip_file):
|
||||||
make_config_dir()
|
make_config_dir()
|
||||||
@ -248,18 +248,18 @@ def input_format_plugins():
|
|||||||
for plugin in _initialized_plugins:
|
for plugin in _initialized_plugins:
|
||||||
if isinstance(plugin, InputFormatPlugin):
|
if isinstance(plugin, InputFormatPlugin):
|
||||||
yield plugin
|
yield plugin
|
||||||
|
|
||||||
def plugin_for_input_format(fmt):
|
def plugin_for_input_format(fmt):
|
||||||
for plugin in input_format_plugins():
|
for plugin in input_format_plugins():
|
||||||
if fmt.lower() in plugin.file_types:
|
if fmt.lower() in plugin.file_types:
|
||||||
return plugin
|
return plugin
|
||||||
|
|
||||||
def available_input_formats():
|
def available_input_formats():
|
||||||
formats = []
|
formats = set([])
|
||||||
for plugin in input_format_plugins():
|
for plugin in input_format_plugins():
|
||||||
if not is_disabled(plugin):
|
if not is_disabled(plugin):
|
||||||
for format in plugin.file_types:
|
for format in plugin.file_types:
|
||||||
formats.append(format)
|
formats.add(format)
|
||||||
return formats
|
return formats
|
||||||
|
|
||||||
def output_format_plugins():
|
def output_format_plugins():
|
||||||
@ -273,10 +273,10 @@ def plugin_for_output_format(fmt):
|
|||||||
return plugin
|
return plugin
|
||||||
|
|
||||||
def available_output_formats():
|
def available_output_formats():
|
||||||
formats = []
|
formats = set([])
|
||||||
for plugin in output_format_plugins():
|
for plugin in output_format_plugins():
|
||||||
if not is_disabled(plugin):
|
if not is_disabled(plugin):
|
||||||
formats.append(plugin.file_type)
|
formats.add(plugin.file_type)
|
||||||
return formats
|
return formats
|
||||||
|
|
||||||
def disable_plugin(plugin_or_name):
|
def disable_plugin(plugin_or_name):
|
||||||
@ -309,21 +309,21 @@ def initialize_plugins():
|
|||||||
except:
|
except:
|
||||||
print 'Failed to initialize plugin...'
|
print 'Failed to initialize plugin...'
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
_initialized_plugins.sort(cmp=lambda x,y:cmp(x.priority, y.priority), reverse=True)
|
_initialized_plugins.sort(cmp=lambda x,y:cmp(x.priority, y.priority), reverse=True)
|
||||||
reread_filetype_plugins()
|
reread_filetype_plugins()
|
||||||
reread_metadata_plugins()
|
reread_metadata_plugins()
|
||||||
|
|
||||||
initialize_plugins()
|
initialize_plugins()
|
||||||
|
|
||||||
def option_parser():
|
def option_parser():
|
||||||
parser = OptionParser(usage=_('''\
|
parser = OptionParser(usage=_('''\
|
||||||
%prog options
|
%prog options
|
||||||
|
|
||||||
Customize calibre by loading external plugins.
|
Customize calibre by loading external plugins.
|
||||||
'''))
|
'''))
|
||||||
parser.add_option('-a', '--add-plugin', default=None,
|
parser.add_option('-a', '--add-plugin', default=None,
|
||||||
help=_('Add a plugin by specifying the path to the zip file containing it.'))
|
help=_('Add a plugin by specifying the path to the zip file containing it.'))
|
||||||
parser.add_option('-r', '--remove-plugin', default=None,
|
parser.add_option('-r', '--remove-plugin', default=None,
|
||||||
help=_('Remove a custom plugin by name. Has no effect on builtin plugins'))
|
help=_('Remove a custom plugin by name. Has no effect on builtin plugins'))
|
||||||
parser.add_option('--customize-plugin', default=None,
|
parser.add_option('--customize-plugin', default=None,
|
||||||
help=_('Customize plugin. Specify name of plugin and customization string separated by a comma.'))
|
help=_('Customize plugin. Specify name of plugin and customization string separated by a comma.'))
|
||||||
@ -377,16 +377,16 @@ def main(args=sys.argv):
|
|||||||
print
|
print
|
||||||
for plugin in initialized_plugins():
|
for plugin in initialized_plugins():
|
||||||
print fmt%(
|
print fmt%(
|
||||||
plugin.type, plugin.name,
|
plugin.type, plugin.name,
|
||||||
plugin.version, is_disabled(plugin),
|
plugin.version, is_disabled(plugin),
|
||||||
plugin_customization(plugin)
|
plugin_customization(plugin)
|
||||||
)
|
)
|
||||||
print '\t', plugin.description
|
print '\t', plugin.description
|
||||||
if plugin.is_customizable():
|
if plugin.is_customizable():
|
||||||
print '\t', plugin.customization_help()
|
print '\t', plugin.customization_help()
|
||||||
print
|
print
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
sys.exit(main())
|
sys.exit(main())
|
||||||
|
@ -179,10 +179,13 @@ OptionRecommendation(name='language',
|
|||||||
raise ValueError('Input file must have an extension')
|
raise ValueError('Input file must have an extension')
|
||||||
input_fmt = input_fmt[1:].lower()
|
input_fmt = input_fmt[1:].lower()
|
||||||
|
|
||||||
output_fmt = os.path.splitext(output)[1]
|
if os.path.exists(output) and os.path.isdir(output):
|
||||||
if not output_fmt:
|
output_fmt = 'oeb'
|
||||||
output_fmt = '.oeb'
|
else:
|
||||||
output_fmt = output_fmt[1:].lower()
|
output_fmt = os.path.splitext(output)[1]
|
||||||
|
if not output_fmt:
|
||||||
|
output_fmt = '.oeb'
|
||||||
|
output_fmt = output_fmt[1:].lower()
|
||||||
|
|
||||||
self.input_plugin = plugin_for_input_format(input_fmt)
|
self.input_plugin = plugin_for_input_format(input_fmt)
|
||||||
self.output_plugin = plugin_for_output_format(output_fmt)
|
self.output_plugin = plugin_for_output_format(output_fmt)
|
||||||
|
@ -5,20 +5,20 @@ __copyright__ = '2008 Kovid Goyal <kovid at kovidgoyal.net>'
|
|||||||
Iterate over the HTML files in an ebook. Useful for writing viewers.
|
Iterate over the HTML files in an ebook. Useful for writing viewers.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
import re, os, math, copy
|
import re, os, math
|
||||||
from cStringIO import StringIO
|
from cStringIO import StringIO
|
||||||
|
|
||||||
from PyQt4.Qt import QFontDatabase
|
from PyQt4.Qt import QFontDatabase
|
||||||
|
|
||||||
from calibre.ebooks.epub.from_any import MAP
|
from calibre.customize.ui import available_input_formats
|
||||||
from calibre.ebooks.epub.from_html import TITLEPAGE
|
from calibre.ebooks.epub.from_html import TITLEPAGE
|
||||||
from calibre.ebooks.epub import config
|
from calibre.ebooks.metadata.opf2 import OPF, OPFCreator
|
||||||
from calibre.ebooks.metadata.opf2 import OPF
|
|
||||||
from calibre.ptempfile import TemporaryDirectory
|
from calibre.ptempfile import TemporaryDirectory
|
||||||
from calibre.ebooks.chardet import xml_to_unicode
|
from calibre.ebooks.chardet import xml_to_unicode
|
||||||
from calibre.ebooks.html_old import create_dir
|
|
||||||
from calibre.utils.zipfile import safe_replace, ZipFile
|
from calibre.utils.zipfile import safe_replace, ZipFile
|
||||||
from calibre.utils.config import DynamicConfig
|
from calibre.utils.config import DynamicConfig
|
||||||
|
from calibre.utils.logging import Log
|
||||||
|
from calibre import CurrentDir
|
||||||
|
|
||||||
def character_count(html):
|
def character_count(html):
|
||||||
'''
|
'''
|
||||||
@ -50,11 +50,28 @@ class SpineItem(unicode):
|
|||||||
obj.max_page = -1
|
obj.max_page = -1
|
||||||
return obj
|
return obj
|
||||||
|
|
||||||
def html2opf(path, tdir, opts):
|
class FakeOpts(object):
|
||||||
opts = copy.copy(opts)
|
verbose = 0
|
||||||
opts.output = tdir
|
breadth_first = False
|
||||||
create_dir(path, opts)
|
max_levels = 5
|
||||||
return os.path.join(tdir, 'metadata.opf')
|
input_encoding = None
|
||||||
|
|
||||||
|
def html2opf(path, tdir, log):
|
||||||
|
from calibre.ebooks.html.input import get_filelist
|
||||||
|
from calibre.ebooks.metadata.meta import get_metadata
|
||||||
|
with CurrentDir(tdir):
|
||||||
|
fl = get_filelist(path, tdir, FakeOpts(), log)
|
||||||
|
mi = get_metadata(open(path, 'rb'), 'html')
|
||||||
|
mi = OPFCreator(os.getcwdu(), mi)
|
||||||
|
mi.guide = None
|
||||||
|
entries = [(f.path, 'application/xhtml+xml') for f in fl]
|
||||||
|
mi.create_manifest(entries)
|
||||||
|
mi.create_spine([f.path for f in fl])
|
||||||
|
|
||||||
|
mi.render(open('metadata.opf', 'wb'))
|
||||||
|
opfpath = os.path.abspath('metadata.opf')
|
||||||
|
|
||||||
|
return opfpath
|
||||||
|
|
||||||
def opf2opf(path, tdir, opts):
|
def opf2opf(path, tdir, opts):
|
||||||
return path
|
return path
|
||||||
@ -62,24 +79,22 @@ def opf2opf(path, tdir, opts):
|
|||||||
def is_supported(path):
|
def is_supported(path):
|
||||||
ext = os.path.splitext(path)[1].replace('.', '').lower()
|
ext = os.path.splitext(path)[1].replace('.', '').lower()
|
||||||
ext = re.sub(r'(x{0,1})htm(l{0,1})', 'html', ext)
|
ext = re.sub(r'(x{0,1})htm(l{0,1})', 'html', ext)
|
||||||
return ext in list(MAP.keys())+['html', 'opf']
|
return ext in available_input_formats()
|
||||||
|
|
||||||
class EbookIterator(object):
|
class EbookIterator(object):
|
||||||
|
|
||||||
CHARACTERS_PER_PAGE = 1000
|
CHARACTERS_PER_PAGE = 1000
|
||||||
|
|
||||||
def __init__(self, pathtoebook):
|
def __init__(self, pathtoebook, log=None):
|
||||||
|
self.log = log
|
||||||
|
if log is None:
|
||||||
|
self.log = Log()
|
||||||
pathtoebook = pathtoebook.strip()
|
pathtoebook = pathtoebook.strip()
|
||||||
self.pathtoebook = os.path.abspath(pathtoebook)
|
self.pathtoebook = os.path.abspath(pathtoebook)
|
||||||
self.config = DynamicConfig(name='iterator')
|
self.config = DynamicConfig(name='iterator')
|
||||||
ext = os.path.splitext(pathtoebook)[1].replace('.', '').lower()
|
ext = os.path.splitext(pathtoebook)[1].replace('.', '').lower()
|
||||||
ext = re.sub(r'(x{0,1})htm(l{0,1})', 'html', ext)
|
ext = re.sub(r'(x{0,1})htm(l{0,1})', 'html', ext)
|
||||||
map = dict(MAP)
|
self.ebook_ext = ext
|
||||||
map['html'] = html2opf
|
|
||||||
map['opf'] = opf2opf
|
|
||||||
if ext not in map.keys():
|
|
||||||
raise UnsupportedFormatError(ext)
|
|
||||||
self.to_opf = map[ext]
|
|
||||||
|
|
||||||
def search(self, text, index):
|
def search(self, text, index):
|
||||||
text = text.lower()
|
text = text.lower()
|
||||||
@ -115,14 +130,24 @@ class EbookIterator(object):
|
|||||||
def __enter__(self):
|
def __enter__(self):
|
||||||
self._tdir = TemporaryDirectory('_ebook_iter')
|
self._tdir = TemporaryDirectory('_ebook_iter')
|
||||||
self.base = self._tdir.__enter__()
|
self.base = self._tdir.__enter__()
|
||||||
opts = config('').parse()
|
if self.ebook_ext == 'opf':
|
||||||
self.pathtoopf = self.to_opf(self.pathtoebook, self.base, opts)
|
self.pathtoopf = self.pathtoebook
|
||||||
|
elif self.ebook_ext == 'html':
|
||||||
|
self.pathtoopf = html2opf(self.pathtoebook, self.base, self.log)
|
||||||
|
else:
|
||||||
|
from calibre.ebooks.conversion.plumber import Plumber
|
||||||
|
plumber = Plumber(self.pathtoebook, self.base, self.log)
|
||||||
|
plumber.setup_options()
|
||||||
|
self.pathtoopf = plumber.input_plugin(open(plumber.input, 'rb'),
|
||||||
|
plumber.opts, plumber.input_fmt, self.log,
|
||||||
|
{}, self.base)
|
||||||
|
|
||||||
|
|
||||||
self.opf = OPF(self.pathtoopf, os.path.dirname(self.pathtoopf))
|
self.opf = OPF(self.pathtoopf, os.path.dirname(self.pathtoopf))
|
||||||
self.spine = [SpineItem(i.path) for i in self.opf.spine]
|
self.spine = [SpineItem(i.path) for i in self.opf.spine]
|
||||||
|
|
||||||
cover = self.opf.cover
|
cover = self.opf.cover
|
||||||
if os.path.splitext(self.pathtoebook)[1].lower() in \
|
if self.ebook_ext in ('lit', 'mobi', 'prc', 'opf') and cover:
|
||||||
('.lit', '.mobi', '.prc') and cover:
|
|
||||||
cfile = os.path.join(os.path.dirname(self.spine[0]), 'calibre_ei_cover.html')
|
cfile = os.path.join(os.path.dirname(self.spine[0]), 'calibre_ei_cover.html')
|
||||||
open(cfile, 'wb').write(TITLEPAGE%cover)
|
open(cfile, 'wb').write(TITLEPAGE%cover)
|
||||||
self.spine[0:0] = [SpineItem(cfile)]
|
self.spine[0:0] = [SpineItem(cfile)]
|
||||||
@ -131,7 +156,6 @@ class EbookIterator(object):
|
|||||||
self.opf.path_to_html_toc not in self.spine:
|
self.opf.path_to_html_toc not in self.spine:
|
||||||
self.spine.append(SpineItem(self.opf.path_to_html_toc))
|
self.spine.append(SpineItem(self.opf.path_to_html_toc))
|
||||||
|
|
||||||
|
|
||||||
sizes = [i.character_count for i in self.spine]
|
sizes = [i.character_count for i in self.spine]
|
||||||
self.pages = [math.ceil(i/float(self.CHARACTERS_PER_PAGE)) for i in sizes]
|
self.pages = [math.ceil(i/float(self.CHARACTERS_PER_PAGE)) for i in sizes]
|
||||||
for p, s in zip(self.pages, self.spine):
|
for p, s in zip(self.pages, self.spine):
|
@ -17,14 +17,14 @@ from calibre.gui2.viewer.bookmarkmanager import BookmarkManager
|
|||||||
from calibre.gui2.main_window import MainWindow
|
from calibre.gui2.main_window import MainWindow
|
||||||
from calibre.gui2 import Application, ORG_NAME, APP_UID, choose_files, \
|
from calibre.gui2 import Application, ORG_NAME, APP_UID, choose_files, \
|
||||||
info_dialog, error_dialog
|
info_dialog, error_dialog
|
||||||
from calibre.ebooks.epub.iterator import EbookIterator
|
from calibre.ebooks.oeb.iterator import EbookIterator
|
||||||
from calibre.ebooks.epub.from_any import SOURCE_FORMATS
|
|
||||||
from calibre.ebooks import DRMError
|
from calibre.ebooks import DRMError
|
||||||
from calibre.gui2.dialogs.conversion_error import ConversionErrorDialog
|
from calibre.gui2.dialogs.conversion_error import ConversionErrorDialog
|
||||||
from calibre.constants import islinux
|
from calibre.constants import islinux
|
||||||
from calibre.utils.config import Config, StringConfig
|
from calibre.utils.config import Config, StringConfig
|
||||||
from calibre.gui2.library import SearchBox
|
from calibre.gui2.library import SearchBox
|
||||||
from calibre.ebooks.metadata import MetaInformation
|
from calibre.ebooks.metadata import MetaInformation
|
||||||
|
from calibre.customize.ui import available_input_formats
|
||||||
|
|
||||||
class TOCItem(QStandardItem):
|
class TOCItem(QStandardItem):
|
||||||
|
|
||||||
@ -362,7 +362,8 @@ class EbookViewer(MainWindow, Ui_EbookViewer):
|
|||||||
def open_ebook(self, checked):
|
def open_ebook(self, checked):
|
||||||
files = choose_files(self, 'ebook viewer open dialog',
|
files = choose_files(self, 'ebook viewer open dialog',
|
||||||
_('Choose ebook'),
|
_('Choose ebook'),
|
||||||
[(_('Ebooks'), SOURCE_FORMATS)], all_files=False,
|
[(_('Ebooks'), available_input_formats())],
|
||||||
|
all_files=False,
|
||||||
select_only_single_file=True)
|
select_only_single_file=True)
|
||||||
if files:
|
if files:
|
||||||
self.load_ebook(files[0])
|
self.load_ebook(files[0])
|
||||||
|
@ -445,6 +445,8 @@ class BasicNewsRecipe(object):
|
|||||||
:param progress_reporter: A Callable that takes two arguments: progress (a number between 0 and 1) and a string message. The message should be optional.
|
:param progress_reporter: A Callable that takes two arguments: progress (a number between 0 and 1) and a string message. The message should be optional.
|
||||||
'''
|
'''
|
||||||
self.log = Log()
|
self.log = Log()
|
||||||
|
if options.verbose:
|
||||||
|
self.log.filter_level = self.log.DEBUG
|
||||||
if not isinstance(self.title, unicode):
|
if not isinstance(self.title, unicode):
|
||||||
self.title = unicode(self.title, 'utf-8', 'replace')
|
self.title = unicode(self.title, 'utf-8', 'replace')
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user