mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
In-server conversion basically works, phew!
Now to create the UI for conversion settings.
This commit is contained in:
parent
256c509238
commit
72fbe75bec
@ -20,7 +20,7 @@ from calibre.customize.ui import run_plugins_on_import, run_plugins_on_postimpor
|
|||||||
from calibre.db import SPOOL_SIZE, _get_next_series_num_for_list
|
from calibre.db import SPOOL_SIZE, _get_next_series_num_for_list
|
||||||
from calibre.db.categories import get_categories
|
from calibre.db.categories import get_categories
|
||||||
from calibre.db.locking import create_locks, DowngradeLockError, SafeReadLock
|
from calibre.db.locking import create_locks, DowngradeLockError, SafeReadLock
|
||||||
from calibre.db.errors import NoSuchFormat
|
from calibre.db.errors import NoSuchFormat, NoSuchBook
|
||||||
from calibre.db.fields import create_field, IDENTITY, InvalidLinkTable
|
from calibre.db.fields import create_field, IDENTITY, InvalidLinkTable
|
||||||
from calibre.db.search import Search
|
from calibre.db.search import Search
|
||||||
from calibre.db.tables import VirtualTable
|
from calibre.db.tables import VirtualTable
|
||||||
@ -1340,10 +1340,9 @@ class Cache(object):
|
|||||||
user_mi = mi.get_all_user_metadata(make_copy=False)
|
user_mi = mi.get_all_user_metadata(make_copy=False)
|
||||||
fm = self.field_metadata
|
fm = self.field_metadata
|
||||||
for key in user_mi.iterkeys():
|
for key in user_mi.iterkeys():
|
||||||
if (key in fm and
|
if (key in fm and user_mi[key]['datatype'] == fm[key]['datatype'] and (
|
||||||
user_mi[key]['datatype'] == fm[key]['datatype'] and
|
user_mi[key]['datatype'] != 'text' or (
|
||||||
(user_mi[key]['datatype'] != 'text' or
|
user_mi[key]['is_multiple'] == fm[key]['is_multiple']))):
|
||||||
user_mi[key]['is_multiple'] == fm[key]['is_multiple'])):
|
|
||||||
val = mi.get(key, None)
|
val = mi.get(key, None)
|
||||||
if force_changes or val is not None:
|
if force_changes or val is not None:
|
||||||
protected_set_field(key, val)
|
protected_set_field(key, val)
|
||||||
@ -1397,6 +1396,8 @@ class Cache(object):
|
|||||||
fmt = check_ebook_format(stream_or_path, fmt)
|
fmt = check_ebook_format(stream_or_path, fmt)
|
||||||
|
|
||||||
with self.write_lock:
|
with self.write_lock:
|
||||||
|
if not self._has_id(book_id):
|
||||||
|
raise NoSuchBook(book_id)
|
||||||
fmt = (fmt or '').upper()
|
fmt = (fmt or '').upper()
|
||||||
self.format_metadata_cache[book_id].pop(fmt, None)
|
self.format_metadata_cache[book_id].pop(fmt, None)
|
||||||
try:
|
try:
|
||||||
|
@ -11,3 +11,9 @@ __docformat__ = 'restructuredtext en'
|
|||||||
class NoSuchFormat(ValueError):
|
class NoSuchFormat(ValueError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class NoSuchBook(KeyError):
|
||||||
|
|
||||||
|
def __init__(self, book_id):
|
||||||
|
KeyError.__init__(self, 'No book with id: {} in database'.format(book_id))
|
||||||
|
self.book_id = book_id
|
||||||
|
@ -9,6 +9,7 @@ import shutil
|
|||||||
import tempfile
|
import tempfile
|
||||||
from threading import Lock
|
from threading import Lock
|
||||||
|
|
||||||
|
from calibre.db.errors import NoSuchBook
|
||||||
from calibre.srv.changes import formats_added
|
from calibre.srv.changes import formats_added
|
||||||
from calibre.srv.errors import BookNotFound, HTTPNotFound
|
from calibre.srv.errors import BookNotFound, HTTPNotFound
|
||||||
from calibre.srv.routes import endpoint, json
|
from calibre.srv.routes import endpoint, json
|
||||||
@ -25,7 +26,7 @@ class JobStatus(object):
|
|||||||
|
|
||||||
def __init__(self, job_id, book_id, tdir, library_id, pathtoebook, conversion_data):
|
def __init__(self, job_id, book_id, tdir, library_id, pathtoebook, conversion_data):
|
||||||
self.job_id = job_id
|
self.job_id = job_id
|
||||||
self.log = ''
|
self.log = self.traceback = ''
|
||||||
self.book_id = book_id
|
self.book_id = book_id
|
||||||
self.output_path = os.path.join(
|
self.output_path = os.path.join(
|
||||||
tdir, 'output.' + conversion_data['output_fmt'].lower())
|
tdir, 'output.' + conversion_data['output_fmt'].lower())
|
||||||
@ -34,9 +35,11 @@ class JobStatus(object):
|
|||||||
self.conversion_data = conversion_data
|
self.conversion_data = conversion_data
|
||||||
self.running = self.ok = True
|
self.running = self.ok = True
|
||||||
self.last_check_at = monotonic()
|
self.last_check_at = monotonic()
|
||||||
|
self.was_aborted = False
|
||||||
|
|
||||||
def cleanup(self):
|
def cleanup(self):
|
||||||
safe_delete_tree(self.tdir)
|
safe_delete_tree(self.tdir)
|
||||||
|
self.log = self.traceback = ''
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def current_status(self):
|
def current_status(self):
|
||||||
@ -106,7 +109,7 @@ def convert_book(path_to_ebook, opf_path, cover_path, output_fmt, recs):
|
|||||||
os.chdir(os.path.dirname(path_to_ebook))
|
os.chdir(os.path.dirname(path_to_ebook))
|
||||||
status_file = share_open('status', 'wb')
|
status_file = share_open('status', 'wb')
|
||||||
|
|
||||||
def notification(percent, msg):
|
def notification(percent, msg=''):
|
||||||
status_file.write('{}:{}|||\n'.format(percent, msg).encode('utf-8'))
|
status_file.write('{}:{}|||\n'.format(percent, msg).encode('utf-8'))
|
||||||
status_file.flush()
|
status_file.flush()
|
||||||
|
|
||||||
@ -129,11 +132,11 @@ def queue_job(ctx, rd, library_id, db, fmt, book_id, conversion_data):
|
|||||||
fd, pathtocover = tempfile.mkstemp(prefix='', suffix=('.jpg'), dir=tdir)
|
fd, pathtocover = tempfile.mkstemp(prefix='', suffix=('.jpg'), dir=tdir)
|
||||||
with os.fdopen(fd, 'wb') as f:
|
with os.fdopen(fd, 'wb') as f:
|
||||||
cover_copied = db.copy_cover_to(book_id, f)
|
cover_copied = db.copy_cover_to(book_id, f)
|
||||||
cover_path = f.name if cover_copied else None
|
cover_path = pathtocover if cover_copied else None
|
||||||
mi = db.get_metadata(book_id)
|
mi = db.get_metadata(book_id)
|
||||||
mi.application_id = mi.uuid
|
mi.application_id = mi.uuid
|
||||||
raw = metadata_to_opf(mi)
|
raw = metadata_to_opf(mi)
|
||||||
fd, pathtocover = tempfile.mkstemp(prefix='', suffix=('.opf'), dir=tdir)
|
fd, opf_path = tempfile.mkstemp(prefix='', suffix=('.opf'), dir=tdir)
|
||||||
with os.fdopen(fd, 'wb') as metadata_file:
|
with os.fdopen(fd, 'wb') as metadata_file:
|
||||||
metadata_file.write(raw)
|
metadata_file.write(raw)
|
||||||
|
|
||||||
@ -146,7 +149,7 @@ def queue_job(ctx, rd, library_id, db, fmt, book_id, conversion_data):
|
|||||||
job_id = ctx.start_job(
|
job_id = ctx.start_job(
|
||||||
'Convert book %s (%s)' % (book_id, fmt), 'calibre.srv.convert',
|
'Convert book %s (%s)' % (book_id, fmt), 'calibre.srv.convert',
|
||||||
'convert_book', args=(
|
'convert_book', args=(
|
||||||
pathtoebook, metadata_file.name, cover_path, conversion_data['output_fmt'], recs),
|
pathtoebook, opf_path, cover_path, conversion_data['output_fmt'], recs),
|
||||||
job_done_callback=job_done
|
job_done_callback=job_done
|
||||||
)
|
)
|
||||||
expire_old_jobs()
|
expire_old_jobs()
|
||||||
@ -181,19 +184,20 @@ def conversion_status(ctx, rd, job_id):
|
|||||||
del conversion_jobs[job_id]
|
del conversion_jobs[job_id]
|
||||||
|
|
||||||
try:
|
try:
|
||||||
ans = {'running': False, 'ok': job_status.ok, 'was_aborted': job_status.was_aborted,
|
ans = {'running': False, 'ok': job_status.ok, 'was_aborted':
|
||||||
'traceback': job_status.traceback, 'log': job_status.log}
|
job_status.was_aborted, 'traceback': job_status.traceback,
|
||||||
|
'log': job_status.log}
|
||||||
if job_status.ok:
|
if job_status.ok:
|
||||||
db, library_id = get_library_data(ctx, rd)[:2]
|
db, library_id = get_library_data(ctx, rd)[:2]
|
||||||
if library_id != job_status.library_id:
|
if library_id != job_status.library_id:
|
||||||
raise HTTPNotFound('job library_id does not match')
|
raise HTTPNotFound('job library_id does not match')
|
||||||
with db.safe_read_lock:
|
fmt = job_status.output_path.rpartition('.')[-1]
|
||||||
if not db.has_id(job_status.book_id):
|
try:
|
||||||
raise HTTPNotFound(
|
|
||||||
'book_id {} not found in library'.format(job_status.book_id))
|
|
||||||
fmt = job_status.output_path.rpartition('.')[-1]
|
|
||||||
db.add_format(job_status.book_id, fmt, job_status.output_path)
|
db.add_format(job_status.book_id, fmt, job_status.output_path)
|
||||||
formats_added({job_status.book_id: (fmt,)})
|
except NoSuchBook:
|
||||||
|
raise HTTPNotFound(
|
||||||
|
'book_id {} not found in library'.format(job_status.book_id))
|
||||||
|
formats_added({job_status.book_id: (fmt,)})
|
||||||
ans['size'] = os.path.getsize(job_status.output_path)
|
ans['size'] = os.path.getsize(job_status.output_path)
|
||||||
ans['fmt'] = fmt
|
ans['fmt'] = fmt
|
||||||
return ans
|
return ans
|
||||||
|
@ -66,7 +66,7 @@ def report_conversion_ajax_failure(xhr):
|
|||||||
nonlocal current_state
|
nonlocal current_state
|
||||||
current_state = 'configuring'
|
current_state = 'configuring'
|
||||||
apply_state_to_markup()
|
apply_state_to_markup()
|
||||||
error_dialog(_('Failed to start conversion'), _(
|
error_dialog(_('Failed to convert'), _(
|
||||||
'Could not convert {}. Click "Show details" for more'
|
'Could not convert {}. Click "Show details" for more'
|
||||||
' information').format(conversion_data.title),
|
' information').format(conversion_data.title),
|
||||||
xhr.error_html
|
xhr.error_html
|
||||||
@ -104,14 +104,15 @@ def on_conversion_status(end_type, xhr, ev):
|
|||||||
if response.running:
|
if response.running:
|
||||||
c = container_for_current_state()
|
c = container_for_current_state()
|
||||||
c.querySelector('progress').value = response.percent
|
c.querySelector('progress').value = response.percent
|
||||||
c.querySelector('.progress-msg').textContent = response.msg
|
if response.msg:
|
||||||
|
c.querySelector('.progress-msg').textContent = response.msg
|
||||||
check_for_conversion_status()
|
check_for_conversion_status()
|
||||||
else:
|
else:
|
||||||
if response.ok:
|
if response.ok:
|
||||||
current_state = 'converted'
|
|
||||||
apply_state_to_markup()
|
|
||||||
conversion_data.fmt = response.fmt
|
conversion_data.fmt = response.fmt
|
||||||
conversion_data.size = response.size
|
conversion_data.size = response.size
|
||||||
|
current_state = 'converted'
|
||||||
|
apply_state_to_markup()
|
||||||
else:
|
else:
|
||||||
show_failure(response)
|
show_failure(response)
|
||||||
else:
|
else:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user