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
|
||||
|
||||
from calibre.utils.config import config_dir
|
||||
from calibre.utils.config import config_dir, prefs, tweaks
|
||||
from calibre.utils.lock import ExclusiveFile
|
||||
from calibre import sanitize_file_name
|
||||
from calibre.customize.conversion import OptionRecommendation
|
||||
from calibre.customize.ui import available_output_formats
|
||||
|
||||
|
||||
config_dir = os.path.join(config_dir, 'conversion')
|
||||
@ -114,3 +115,78 @@ class GuiRecommendations(dict):
|
||||
self.disabled_options.add(name)
|
||||
elif opt.level > level or name not in self:
|
||||
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 calibre.gui2.convert.single import (Config, sort_formats_by_preference,
|
||||
GroupModel, gprefs, get_output_formats)
|
||||
from calibre.gui2.convert.single import Config, GroupModel, gprefs
|
||||
from calibre.gui2.convert.look_and_feel import LookAndFeelWidget
|
||||
from calibre.gui2.convert.heuristics import HeuristicsWidget
|
||||
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 import GuiRecommendations
|
||||
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.logging import Log
|
||||
|
||||
|
@ -11,8 +11,8 @@ import cPickle, shutil
|
||||
from PyQt5.Qt import QAbstractListModel, Qt, QFont, QModelIndex, QDialog, QCoreApplication, QSize
|
||||
|
||||
from calibre.gui2 import gprefs
|
||||
from calibre.ebooks.conversion.config import (GuiRecommendations, save_specifics,
|
||||
load_specifics)
|
||||
from calibre.ebooks.conversion.config import (
|
||||
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.metadata import MetadataWidget
|
||||
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.ebooks.conversion.plumber import (Plumber,
|
||||
supported_input_formats, ARCHIVE_FMTS)
|
||||
from calibre.ebooks.conversion.plumber import (Plumber, ARCHIVE_FMTS)
|
||||
from calibre.ebooks.conversion.config import delete_specifics
|
||||
from calibre.customize.ui import available_output_formats
|
||||
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
|
||||
|
||||
|
||||
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):
|
||||
|
||||
def __init__(self, widgets):
|
||||
@ -92,49 +56,6 @@ class GroupModel(QAbstractListModel):
|
||||
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):
|
||||
'''
|
||||
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.gui2 import warning_dialog, question_dialog
|
||||
from calibre.gui2.convert.single import NoSupportedInputFormats
|
||||
from calibre.gui2.convert.single import Config as SingleConfig, \
|
||||
get_input_format_for_book
|
||||
from calibre.gui2.convert.single import Config as SingleConfig
|
||||
from calibre.gui2.convert.bulk import BulkConfig
|
||||
from calibre.gui2.convert.metadata import create_opf_file, create_cover_file
|
||||
from calibre.customize.conversion import OptionRecommendation
|
||||
from calibre.utils.config import prefs
|
||||
from calibre.ebooks.conversion.config import GuiRecommendations, \
|
||||
load_defaults, load_specifics, save_specifics
|
||||
from calibre.ebooks.conversion.config import (
|
||||
GuiRecommendations, load_defaults, load_specifics, save_specifics,
|
||||
get_input_format_for_book, NoSupportedInputFormats)
|
||||
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 len(bad) == 1 and not bad[0][1]:
|
||||
title = db.title(bad[0][0], True)
|
||||
warning_dialog(parent, _('Could not convert'), '<p>'+
|
||||
_('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 '
|
||||
'them, that is most likely because you moved the book\'s '
|
||||
'files around outside of calibre. You will need to find those files '
|
||||
'and re-add them to calibre.')%title, show=True)
|
||||
warning_dialog(parent, _('Could not convert'), '<p>'+ _(
|
||||
'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 '
|
||||
'them, that is most likely because you moved the book\'s '
|
||||
'files around outside of calibre. You will need to find those files '
|
||||
'and re-add them to calibre.')%title, show=True)
|
||||
else:
|
||||
res = []
|
||||
for id, available_formats in bad:
|
||||
|
Loading…
x
Reference in New Issue
Block a user