mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Refactor code to get conversion formats to make it re-useable
This commit is contained in:
parent
91dcd80f8c
commit
27c79db06a
@ -8,10 +8,11 @@ __docformat__ = 'restructuredtext en'
|
|||||||
|
|
||||||
import os, ast, json
|
import os, ast, json
|
||||||
|
|
||||||
from calibre.utils.config import config_dir
|
from calibre.utils.config import config_dir, prefs, tweaks
|
||||||
from calibre.utils.lock import ExclusiveFile
|
from calibre.utils.lock import ExclusiveFile
|
||||||
from calibre import sanitize_file_name
|
from calibre import sanitize_file_name
|
||||||
from calibre.customize.conversion import OptionRecommendation
|
from calibre.customize.conversion import OptionRecommendation
|
||||||
|
from calibre.customize.ui import available_output_formats
|
||||||
|
|
||||||
|
|
||||||
config_dir = os.path.join(config_dir, 'conversion')
|
config_dir = os.path.join(config_dir, 'conversion')
|
||||||
@ -114,3 +115,78 @@ class GuiRecommendations(dict):
|
|||||||
self.disabled_options.add(name)
|
self.disabled_options.add(name)
|
||||||
elif opt.level > level or name not in self:
|
elif opt.level > level or name not in self:
|
||||||
self[name] = opt.recommended_value
|
self[name] = opt.recommended_value
|
||||||
|
|
||||||
|
|
||||||
|
def get_available_formats_for_book(db, book_id):
|
||||||
|
available_formats = db.new_api.formats(book_id)
|
||||||
|
return {x.lower() for x in available_formats}
|
||||||
|
|
||||||
|
|
||||||
|
class NoSupportedInputFormats(Exception):
|
||||||
|
|
||||||
|
def __init__(self, available_formats):
|
||||||
|
Exception.__init__(self)
|
||||||
|
self.available_formats = available_formats
|
||||||
|
|
||||||
|
|
||||||
|
def get_supported_input_formats_for_book(db, book_id):
|
||||||
|
from calibre.ebooks.conversion.plumber import supported_input_formats
|
||||||
|
available_formats = get_available_formats_for_book(db, book_id)
|
||||||
|
input_formats = {x.lower() for x in supported_input_formats()}
|
||||||
|
input_formats = sorted(available_formats.intersection(input_formats))
|
||||||
|
if not input_formats:
|
||||||
|
raise NoSupportedInputFormats(tuple(x for x in available_formats if x))
|
||||||
|
return input_formats
|
||||||
|
|
||||||
|
|
||||||
|
def get_preferred_input_format_for_book(db, book_id):
|
||||||
|
recs = load_specifics(db, book_id)
|
||||||
|
if recs:
|
||||||
|
return recs.get('gui_preferred_input_format', None)
|
||||||
|
|
||||||
|
|
||||||
|
def sort_formats_by_preference(formats, prefs):
|
||||||
|
uprefs = [x.upper() for x in prefs]
|
||||||
|
|
||||||
|
def key(x):
|
||||||
|
try:
|
||||||
|
return uprefs.index(x.upper())
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
return len(prefs)
|
||||||
|
return sorted(formats, key=key)
|
||||||
|
|
||||||
|
|
||||||
|
def get_input_format_for_book(db, book_id, pref=None):
|
||||||
|
'''
|
||||||
|
Return (preferred input format, list of available formats) for the book
|
||||||
|
identified by book_id. Raises an error if the book has no input formats.
|
||||||
|
|
||||||
|
:param pref: If None, the format used as input for the last conversion, if
|
||||||
|
any, on this book is used. If not None, should be a lowercase format like
|
||||||
|
'epub' or 'mobi'. If you do not want the last converted format to be used,
|
||||||
|
set pref=False.
|
||||||
|
'''
|
||||||
|
if pref is None:
|
||||||
|
pref = get_preferred_input_format_for_book(db, book_id)
|
||||||
|
if hasattr(pref, 'lower'):
|
||||||
|
pref = pref.lower()
|
||||||
|
input_formats = get_supported_input_formats_for_book(db, book_id)
|
||||||
|
input_format = pref if pref in input_formats else \
|
||||||
|
sort_formats_by_preference(input_formats, prefs['input_format_order'])[0]
|
||||||
|
return input_format, input_formats
|
||||||
|
|
||||||
|
|
||||||
|
def get_output_formats(preferred_output_format):
|
||||||
|
all_formats = {x.upper() for x in available_output_formats()}
|
||||||
|
all_formats.discard('OEB')
|
||||||
|
pfo = preferred_output_format.upper() if preferred_output_format else ''
|
||||||
|
restrict = tweaks['restrict_output_formats']
|
||||||
|
if restrict:
|
||||||
|
fmts = [x.upper() for x in restrict]
|
||||||
|
if pfo and pfo not in fmts and pfo in all_formats:
|
||||||
|
fmts.append(pfo)
|
||||||
|
else:
|
||||||
|
fmts = list(sorted(all_formats,
|
||||||
|
key=lambda x:{'EPUB':'!A', 'MOBI':'!B'}.get(x.upper(), x)))
|
||||||
|
return fmts
|
||||||
|
@ -8,8 +8,7 @@ import shutil
|
|||||||
|
|
||||||
from PyQt5.Qt import QModelIndex, QDialog
|
from PyQt5.Qt import QModelIndex, QDialog
|
||||||
|
|
||||||
from calibre.gui2.convert.single import (Config, sort_formats_by_preference,
|
from calibre.gui2.convert.single import Config, GroupModel, gprefs
|
||||||
GroupModel, gprefs, get_output_formats)
|
|
||||||
from calibre.gui2.convert.look_and_feel import LookAndFeelWidget
|
from calibre.gui2.convert.look_and_feel import LookAndFeelWidget
|
||||||
from calibre.gui2.convert.heuristics import HeuristicsWidget
|
from calibre.gui2.convert.heuristics import HeuristicsWidget
|
||||||
from calibre.gui2.convert.search_and_replace import SearchAndReplaceWidget
|
from calibre.gui2.convert.search_and_replace import SearchAndReplaceWidget
|
||||||
@ -18,6 +17,7 @@ from calibre.gui2.convert.structure_detection import StructureDetectionWidget
|
|||||||
from calibre.gui2.convert.toc import TOCWidget
|
from calibre.gui2.convert.toc import TOCWidget
|
||||||
from calibre.gui2.convert import GuiRecommendations
|
from calibre.gui2.convert import GuiRecommendations
|
||||||
from calibre.ebooks.conversion.plumber import Plumber
|
from calibre.ebooks.conversion.plumber import Plumber
|
||||||
|
from calibre.ebooks.conversion.config import sort_formats_by_preference, get_output_formats
|
||||||
from calibre.utils.config import prefs
|
from calibre.utils.config import prefs
|
||||||
from calibre.utils.logging import Log
|
from calibre.utils.logging import Log
|
||||||
|
|
||||||
|
@ -11,8 +11,8 @@ import cPickle, shutil
|
|||||||
from PyQt5.Qt import QAbstractListModel, Qt, QFont, QModelIndex, QDialog, QCoreApplication, QSize
|
from PyQt5.Qt import QAbstractListModel, Qt, QFont, QModelIndex, QDialog, QCoreApplication, QSize
|
||||||
|
|
||||||
from calibre.gui2 import gprefs
|
from calibre.gui2 import gprefs
|
||||||
from calibre.ebooks.conversion.config import (GuiRecommendations, save_specifics,
|
from calibre.ebooks.conversion.config import (
|
||||||
load_specifics)
|
GuiRecommendations, save_specifics, sort_formats_by_preference, get_input_format_for_book, get_output_formats)
|
||||||
from calibre.gui2.convert.single_ui import Ui_Dialog
|
from calibre.gui2.convert.single_ui import Ui_Dialog
|
||||||
from calibre.gui2.convert.metadata import MetadataWidget
|
from calibre.gui2.convert.metadata import MetadataWidget
|
||||||
from calibre.gui2.convert.look_and_feel import LookAndFeelWidget
|
from calibre.gui2.convert.look_and_feel import LookAndFeelWidget
|
||||||
@ -24,49 +24,13 @@ from calibre.gui2.convert.toc import TOCWidget
|
|||||||
from calibre.gui2.convert.debug import DebugWidget
|
from calibre.gui2.convert.debug import DebugWidget
|
||||||
|
|
||||||
|
|
||||||
from calibre.ebooks.conversion.plumber import (Plumber,
|
from calibre.ebooks.conversion.plumber import (Plumber, ARCHIVE_FMTS)
|
||||||
supported_input_formats, ARCHIVE_FMTS)
|
|
||||||
from calibre.ebooks.conversion.config import delete_specifics
|
from calibre.ebooks.conversion.config import delete_specifics
|
||||||
from calibre.customize.ui import available_output_formats
|
|
||||||
from calibre.customize.conversion import OptionRecommendation
|
from calibre.customize.conversion import OptionRecommendation
|
||||||
from calibre.utils.config import prefs, tweaks
|
from calibre.utils.config import prefs
|
||||||
from calibre.utils.logging import Log
|
from calibre.utils.logging import Log
|
||||||
|
|
||||||
|
|
||||||
class NoSupportedInputFormats(Exception):
|
|
||||||
|
|
||||||
def __init__(self, available_formats):
|
|
||||||
Exception.__init__(self)
|
|
||||||
self.available_formats = available_formats
|
|
||||||
|
|
||||||
|
|
||||||
def sort_formats_by_preference(formats, prefs):
|
|
||||||
uprefs = [x.upper() for x in prefs]
|
|
||||||
|
|
||||||
def key(x):
|
|
||||||
try:
|
|
||||||
return uprefs.index(x.upper())
|
|
||||||
except ValueError:
|
|
||||||
pass
|
|
||||||
return len(prefs)
|
|
||||||
return sorted(formats, key=key)
|
|
||||||
|
|
||||||
|
|
||||||
def get_output_formats(preferred_output_format):
|
|
||||||
all_formats = {x.upper() for x in available_output_formats()}
|
|
||||||
all_formats.discard('OEB')
|
|
||||||
pfo = preferred_output_format.upper() if preferred_output_format else ''
|
|
||||||
restrict = tweaks['restrict_output_formats']
|
|
||||||
if restrict:
|
|
||||||
fmts = [x.upper() for x in restrict]
|
|
||||||
if pfo and pfo not in fmts and pfo in all_formats:
|
|
||||||
fmts.append(pfo)
|
|
||||||
else:
|
|
||||||
fmts = list(sorted(all_formats,
|
|
||||||
key=lambda x:{'EPUB':'!A', 'MOBI':'!B'}.get(x.upper(), x)))
|
|
||||||
return fmts
|
|
||||||
|
|
||||||
|
|
||||||
class GroupModel(QAbstractListModel):
|
class GroupModel(QAbstractListModel):
|
||||||
|
|
||||||
def __init__(self, widgets):
|
def __init__(self, widgets):
|
||||||
@ -92,49 +56,6 @@ class GroupModel(QAbstractListModel):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def get_preferred_input_format_for_book(db, book_id):
|
|
||||||
recs = load_specifics(db, book_id)
|
|
||||||
if recs:
|
|
||||||
return recs.get('gui_preferred_input_format', None)
|
|
||||||
|
|
||||||
|
|
||||||
def get_available_formats_for_book(db, book_id):
|
|
||||||
available_formats = db.formats(book_id, index_is_id=True)
|
|
||||||
if not available_formats:
|
|
||||||
available_formats = ''
|
|
||||||
return set([x.lower() for x in
|
|
||||||
available_formats.split(',')])
|
|
||||||
|
|
||||||
|
|
||||||
def get_supported_input_formats_for_book(db, book_id):
|
|
||||||
available_formats = get_available_formats_for_book(db, book_id)
|
|
||||||
input_formats = set([x.lower() for x in supported_input_formats()])
|
|
||||||
input_formats = sorted(available_formats.intersection(input_formats))
|
|
||||||
if not input_formats:
|
|
||||||
raise NoSupportedInputFormats(tuple(x for x in available_formats if x))
|
|
||||||
return input_formats
|
|
||||||
|
|
||||||
|
|
||||||
def get_input_format_for_book(db, book_id, pref):
|
|
||||||
'''
|
|
||||||
Return (preferred input format, list of available formats) for the book
|
|
||||||
identified by book_id. Raises an error if the book has no input formats.
|
|
||||||
|
|
||||||
:param pref: If None, the format used as input for the last conversion, if
|
|
||||||
any, on this book is used. If not None, should be a lowercase format like
|
|
||||||
'epub' or 'mobi'. If you do not want the last converted format to be used,
|
|
||||||
set pref=False.
|
|
||||||
'''
|
|
||||||
if pref is None:
|
|
||||||
pref = get_preferred_input_format_for_book(db, book_id)
|
|
||||||
if hasattr(pref, 'lower'):
|
|
||||||
pref = pref.lower()
|
|
||||||
input_formats = get_supported_input_formats_for_book(db, book_id)
|
|
||||||
input_format = pref if pref in input_formats else \
|
|
||||||
sort_formats_by_preference(input_formats, prefs['input_format_order'])[0]
|
|
||||||
return input_format, input_formats
|
|
||||||
|
|
||||||
|
|
||||||
class Config(QDialog, Ui_Dialog):
|
class Config(QDialog, Ui_Dialog):
|
||||||
'''
|
'''
|
||||||
Configuration dialog for single book conversion. If accepted, has the
|
Configuration dialog for single book conversion. If accepted, has the
|
||||||
|
@ -13,15 +13,14 @@ from PyQt5.Qt import QDialog, QProgressDialog, QTimer
|
|||||||
|
|
||||||
from calibre.ptempfile import PersistentTemporaryFile
|
from calibre.ptempfile import PersistentTemporaryFile
|
||||||
from calibre.gui2 import warning_dialog, question_dialog
|
from calibre.gui2 import warning_dialog, question_dialog
|
||||||
from calibre.gui2.convert.single import NoSupportedInputFormats
|
from calibre.gui2.convert.single import Config as SingleConfig
|
||||||
from calibre.gui2.convert.single import Config as SingleConfig, \
|
|
||||||
get_input_format_for_book
|
|
||||||
from calibre.gui2.convert.bulk import BulkConfig
|
from calibre.gui2.convert.bulk import BulkConfig
|
||||||
from calibre.gui2.convert.metadata import create_opf_file, create_cover_file
|
from calibre.gui2.convert.metadata import create_opf_file, create_cover_file
|
||||||
from calibre.customize.conversion import OptionRecommendation
|
from calibre.customize.conversion import OptionRecommendation
|
||||||
from calibre.utils.config import prefs
|
from calibre.utils.config import prefs
|
||||||
from calibre.ebooks.conversion.config import GuiRecommendations, \
|
from calibre.ebooks.conversion.config import (
|
||||||
load_defaults, load_specifics, save_specifics
|
GuiRecommendations, load_defaults, load_specifics, save_specifics,
|
||||||
|
get_input_format_for_book, NoSupportedInputFormats)
|
||||||
from calibre.gui2.convert import bulk_defaults_for_input_format
|
from calibre.gui2.convert import bulk_defaults_for_input_format
|
||||||
|
|
||||||
|
|
||||||
@ -100,12 +99,12 @@ def convert_single_ebook(parent, db, book_ids, auto_conversion=False, # {{{
|
|||||||
if bad and show_no_format_warning:
|
if bad and show_no_format_warning:
|
||||||
if len(bad) == 1 and not bad[0][1]:
|
if len(bad) == 1 and not bad[0][1]:
|
||||||
title = db.title(bad[0][0], True)
|
title = db.title(bad[0][0], True)
|
||||||
warning_dialog(parent, _('Could not convert'), '<p>'+
|
warning_dialog(parent, _('Could not convert'), '<p>'+ _(
|
||||||
_('Could not convert <b>%s</b> as it has no e-book files. If you '
|
'Could not convert <b>%s</b> as it has no e-book files. If you '
|
||||||
'think it should have files, but calibre is not finding '
|
'think it should have files, but calibre is not finding '
|
||||||
'them, that is most likely because you moved the book\'s '
|
'them, that is most likely because you moved the book\'s '
|
||||||
'files around outside of calibre. You will need to find those files '
|
'files around outside of calibre. You will need to find those files '
|
||||||
'and re-add them to calibre.')%title, show=True)
|
'and re-add them to calibre.')%title, show=True)
|
||||||
else:
|
else:
|
||||||
res = []
|
res = []
|
||||||
for id, available_formats in bad:
|
for id, available_formats in bad:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user