mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
More work on in-server conversion
This commit is contained in:
parent
04f82a64e0
commit
4dd9a58262
@ -320,3 +320,25 @@ OPTIONS = {
|
||||
},
|
||||
}
|
||||
OPTIONS['output']['txtz'] = OPTIONS['output']['txt']
|
||||
|
||||
|
||||
def options_for_input_fmt(fmt):
|
||||
from calibre.customize.ui import plugin_for_input_format
|
||||
fmt = fmt.lower()
|
||||
plugin = plugin_for_input_format(fmt)
|
||||
if plugin is None:
|
||||
return None, ()
|
||||
full_name = plugin.name.lower().replace(' ', '_')
|
||||
name = full_name.rpartition('_')[0]
|
||||
return full_name, OPTIONS['input'].get(name, ())
|
||||
|
||||
|
||||
def options_for_output_fmt(fmt):
|
||||
from calibre.customize.ui import plugin_for_output_format
|
||||
fmt = fmt.lower()
|
||||
plugin = plugin_for_output_format(fmt)
|
||||
if plugin is None:
|
||||
return None, ()
|
||||
full_name = plugin.name.lower().replace(' ', '_')
|
||||
name = full_name.rpartition('_')[0]
|
||||
return full_name, OPTIONS['output'].get(name, ())
|
||||
|
@ -137,23 +137,35 @@ def conversion_status(ctx, rd, job_id):
|
||||
|
||||
def get_conversion_options(input_fmt, output_fmt, book_id, db):
|
||||
from calibre.ebooks.conversion.plumber import create_dummy_plumber
|
||||
from calibre.ebooks.conversion.config import load_specifics, load_defaults, OPTIONS
|
||||
from calibre.ebooks.conversion.config import (
|
||||
load_specifics, load_defaults, OPTIONS, options_for_input_fmt, options_for_output_fmt)
|
||||
from calibre.customize.conversion import OptionRecommendation
|
||||
plumber = create_dummy_plumber(input_fmt, output_fmt)
|
||||
specifics = load_specifics(db, book_id)
|
||||
ans = {'options': {}, 'disabled': set()}
|
||||
for group_name, option_names in OPTIONS['pipe'].iteritems():
|
||||
if group_name == 'debug':
|
||||
continue
|
||||
|
||||
def merge_group(group_name, option_names):
|
||||
if not group_name or group_name == 'debug':
|
||||
return
|
||||
defs = load_defaults(group_name)
|
||||
defs.merge_recommendations(plumber.get_option, OptionRecommendation.LOW, option_names)
|
||||
specifics.merge_recommendations(plumber.get_option, OptionRecommendation.HIGH, option_names, only_existing=True)
|
||||
defs.merge_recommendations(plumber.get_option_by_name, OptionRecommendation.LOW, option_names)
|
||||
specifics.merge_recommendations(plumber.get_option_by_name, OptionRecommendation.HIGH, option_names, only_existing=True)
|
||||
for k in defs:
|
||||
if k in specifics:
|
||||
defs[k] = specifics[k]
|
||||
defs = defs.as_dict()
|
||||
ans['options'].update(defs['options'])
|
||||
ans['disabled'] |= defs['disabled']
|
||||
ans['disabled'] |= set(defs['disabled'])
|
||||
|
||||
for group_name, option_names in OPTIONS['pipe'].iteritems():
|
||||
merge_group(group_name, option_names)
|
||||
|
||||
group_name, option_names = options_for_input_fmt(input_fmt)
|
||||
merge_group(group_name, option_names)
|
||||
group_name, option_names = options_for_output_fmt(output_fmt)
|
||||
merge_group(group_name, option_names)
|
||||
|
||||
ans['disabled'] = tuple(ans['disabled'])
|
||||
return ans
|
||||
|
||||
|
||||
|
@ -11,11 +11,14 @@ from book_list.library_data import load_status, url_books_query
|
||||
from book_list.router import back, report_a_load_failure
|
||||
from book_list.top_bar import create_top_bar, set_title
|
||||
from book_list.ui import set_panel_handler
|
||||
from dom import add_extra_css, build_rule, clear, ensure_id
|
||||
from dom import add_extra_css, build_rule
|
||||
from utils import conditional_timeout, parse_url_params
|
||||
from widgets import create_button
|
||||
|
||||
CLASS_NAME = 'convert-book-panel'
|
||||
current_state = 'initializing'
|
||||
overall_container_id = None
|
||||
initializers = {}
|
||||
|
||||
add_extra_css(def():
|
||||
sel = '.' + CLASS_NAME + ' '
|
||||
@ -28,12 +31,18 @@ conversion_data = None
|
||||
conversion_data_load_status = {'loading':True, 'ok':False, 'error_html':None, 'current_fetch':None}
|
||||
|
||||
|
||||
def container_for_current_state():
|
||||
ans = document.getElementById(overall_container_id)
|
||||
if ans:
|
||||
return ans.querySelector(f'[data-state="{current_state}"]')
|
||||
|
||||
|
||||
def on_conversion_started(end_type, xhr, ev):
|
||||
pass
|
||||
|
||||
|
||||
def get_conversion_options(container):
|
||||
return conversion_data.conversion_options
|
||||
return conversion_data.conversion_options.options
|
||||
|
||||
|
||||
def start_conversion():
|
||||
@ -48,17 +57,13 @@ def start_conversion():
|
||||
ajax_send(f'/conversion/start/{conversion_data.book_id}', data, on_conversion_started, query=query)
|
||||
|
||||
|
||||
def create_convert_book(container):
|
||||
conversion_data.container_id = ensure_id(container)
|
||||
set_title(container.parentNode, _('Convert: {}').format(conversion_data.title))
|
||||
container.appendChild(E.div(class_='top'))
|
||||
def create_configuring_markup():
|
||||
ans = E.div(class_='top')
|
||||
|
||||
def generate_choice(name):
|
||||
formats = conversion_data[name]
|
||||
ans = E.select(name=name)
|
||||
for fmt in formats:
|
||||
ans.appendChild(E.option(fmt, value=fmt))
|
||||
return ans
|
||||
|
||||
tcell = 'display: table-cell; padding-top: 1em; padding-left: 1em'
|
||||
|
||||
start_conv = E.div(
|
||||
@ -79,7 +84,16 @@ def create_convert_book(container):
|
||||
create_button(_('Start conversion'), action=start_conversion)
|
||||
)
|
||||
)
|
||||
container.lastChild.appendChild(start_conv)
|
||||
ans.appendChild(start_conv)
|
||||
|
||||
def initialize(container):
|
||||
for name in 'input_formats', 'output_formats':
|
||||
sel = container.querySelector(f'select[name="{name}"]')
|
||||
formats = conversion_data[name]
|
||||
for fmt in formats:
|
||||
sel.appendChild(E.option(fmt, value=fmt))
|
||||
|
||||
return ans, initialize
|
||||
|
||||
|
||||
# Initialization {{{
|
||||
@ -121,28 +135,62 @@ def on_close(container_id):
|
||||
|
||||
|
||||
def check_for_data_loaded():
|
||||
nonlocal current_state
|
||||
container = this
|
||||
if load_status.loading or conversion_data_load_status.loading:
|
||||
conditional_timeout(container.id, 5, check_for_data_loaded)
|
||||
return
|
||||
container = container.lastChild
|
||||
clear(container)
|
||||
if not load_status.ok:
|
||||
report_load_failure(container)
|
||||
return
|
||||
if not conversion_data_load_status.ok:
|
||||
current_state = 'load-failure'
|
||||
report_load_failure(container_for_current_state())
|
||||
elif not conversion_data_load_status.ok:
|
||||
current_state = 'load-failure'
|
||||
report_a_load_failure(
|
||||
container, _('Failed to load conversion data from calibre, with error:'),
|
||||
container_for_current_state(),
|
||||
_('Failed to load conversion data from calibre, with error:'),
|
||||
conversion_data_load_status.error_html)
|
||||
return
|
||||
create_convert_book(container)
|
||||
else:
|
||||
set_title(container.parentNode, _('Convert: {}').format(conversion_data.title))
|
||||
current_state = 'configuring'
|
||||
apply_state_to_markup()
|
||||
|
||||
|
||||
def create_markup(container):
|
||||
container.appendChild(E.div(
|
||||
data_state='initializing', style='margin: 1ex 1em',
|
||||
E.div(_('Loading conversion data, please wait...'))
|
||||
))
|
||||
container.appendChild(E.div(
|
||||
data_state='load-failure', style='margin: 1ex 1em',
|
||||
))
|
||||
|
||||
ccm, init = create_configuring_markup()
|
||||
ccm.dataset.state = 'configuring'
|
||||
container.appendChild(ccm)
|
||||
initializers[ccm.dataset.state] = init
|
||||
|
||||
|
||||
def apply_state_to_markup():
|
||||
container = document.getElementById(overall_container_id)
|
||||
if container:
|
||||
for node in container.lastChild.childNodes:
|
||||
if node.dataset.state is current_state:
|
||||
node.style.display = 'block'
|
||||
if initializers[current_state]:
|
||||
initializers[current_state](node)
|
||||
else:
|
||||
node.style.display = 'none'
|
||||
|
||||
|
||||
def init(container_id):
|
||||
nonlocal overall_container_id
|
||||
container = document.getElementById(container_id)
|
||||
overall_container_id = container_id
|
||||
create_top_bar(container, title=_('Convert book'), action=on_close.bind(None, container_id), icon='close')
|
||||
container.appendChild(E.div(class_=CLASS_NAME))
|
||||
container.lastChild.appendChild(E.div(_('Loading conversion data, please wait...'), style='margin: 1ex 1em'))
|
||||
create_markup(container.lastChild)
|
||||
apply_state_to_markup()
|
||||
conditional_timeout(container_id, 5, check_for_data_loaded)
|
||||
q = parse_url_params()
|
||||
fetch_conversion_data(q.book_id)
|
||||
|
Loading…
x
Reference in New Issue
Block a user