(draft) metadata embedding when sending to device

This commit is contained in:
Thore Schillmann 2022-07-22 08:58:28 +00:00
parent 4913673e8f
commit 9bcbe523d7
4 changed files with 49 additions and 3 deletions

View File

@ -154,7 +154,7 @@ EXTENSIONS_UPLOAD = {'txt', 'pdf', 'epub', 'kepub', 'mobi', 'azw', 'azw3', 'cbr'
_extension = "" _extension = ""
if sys.platform == "win32": if sys.platform == "win32":
_extension = ".exe" _extension = ".exe"
SUPPORTED_CALIBRE_BINARIES = {binary:binary + _extension for binary in ["ebook-convert", "calibredb"]} SUPPORTED_CALIBRE_BINARIES = {binary:binary + _extension for binary in ["ebook-convert", "calibredb", "ebook-meta"]}
def has_flag(value, bit_flag): def has_flag(value, bit_flag):

View File

@ -54,7 +54,7 @@ from .tasks.convert import TaskConvert
from . import logger, config, db, ub, fs from . import logger, config, db, ub, fs
from . import gdriveutils as gd from . import gdriveutils as gd
from .constants import STATIC_DIR as _STATIC_DIR, CACHE_TYPE_THUMBNAILS, THUMBNAIL_TYPE_COVER, THUMBNAIL_TYPE_SERIES, SUPPORTED_CALIBRE_BINARIES from .constants import STATIC_DIR as _STATIC_DIR, CACHE_TYPE_THUMBNAILS, THUMBNAIL_TYPE_COVER, THUMBNAIL_TYPE_SERIES, SUPPORTED_CALIBRE_BINARIES
from .subproc_wrapper import process_wait from .subproc_wrapper import process_wait, process_open
from .services.worker import WorkerThread from .services.worker import WorkerThread
from .tasks.mail import TaskEmail from .tasks.mail import TaskEmail
from .tasks.thumbnail import TaskClearCoverThumbnailCache, TaskGenerateCoverThumbnails from .tasks.thumbnail import TaskClearCoverThumbnailCache, TaskGenerateCoverThumbnails
@ -213,6 +213,17 @@ def send_mail(book_id, book_format, convert, kindle_mail, calibrepath, user_id):
# returns None if success, otherwise errormessage # returns None if success, otherwise errormessage
return convert_book_format(book_id, calibrepath, u'azw3', book_format.lower(), user_id, kindle_mail) return convert_book_format(book_id, calibrepath, u'azw3', book_format.lower(), user_id, kindle_mail)
# ToDo: Delete when OPF creation has been implemented
if config.config_binariesdir:
quotes = [3, 5]
calibredb_binarypath = os.path.join(config.config_binariesdir, SUPPORTED_CALIBRE_BINARIES["calibredb"])
opf_command = [calibredb_binarypath, 'show_metadata', '--as-opf', str(book_id), '--with-library', config.config_calibre_dir]
p = process_open(opf_command, quotes)
p.wait()
path_opf = os.path.join(config.config_calibre_dir, book.path, "metadata.opf")
with open(path_opf, 'w') as fd:
shutil.copyfileobj(p.stdout, fd)
for entry in iter(book.data): for entry in iter(book.data):
if entry.format.upper() == book_format.upper(): if entry.format.upper() == book_format.upper():
converted_file_name = entry.name + '.' + book_format.lower() converted_file_name = entry.name + '.' + book_format.lower()

View File

@ -93,6 +93,16 @@ class TaskConvert(CalibreTask):
# todo: figure out how to incorporate this into the progress # todo: figure out how to incorporate this into the progress
try: try:
EmailText = N_(u"%(book)s send to Kindle", book=escape(self.title)) EmailText = N_(u"%(book)s send to Kindle", book=escape(self.title))
# ToDo: Delete when OPF creation has been implemented
if config.config_binariesdir:
quotes = [3, 5]
calibredb_binarypath = os.path.join(config.config_binariesdir, SUPPORTED_CALIBRE_BINARIES["calibredb"])
opf_command = [calibredb_binarypath, 'show_metadata', '--as-opf', str(self.book_id), '--with-library', config.config_calibre_dir]
p = process_open(opf_command, quotes)
p.wait()
path_opf = os.path.join(config.config_calibre_dir, cur_book.path, "metadata.opf")
with open(path_opf, 'w') as fd:
copyfileobj(p.stdout, fd)
worker_thread.add(self.user, TaskEmail(self.settings['subject'], worker_thread.add(self.user, TaskEmail(self.settings['subject'],
self.results["path"], self.results["path"],
filename, filename,

View File

@ -20,6 +20,7 @@ import os
import smtplib import smtplib
import threading import threading
import socket import socket
from shutil import copy
import mimetypes import mimetypes
from io import StringIO from io import StringIO
@ -32,6 +33,8 @@ from email.utils import formatdate
from cps.services.worker import CalibreTask from cps.services.worker import CalibreTask
from cps.services import gmail from cps.services import gmail
from cps import logger, config from cps import logger, config
from cps.subproc_wrapper import process_open
from cps.constants import SUPPORTED_CALIBRE_BINARIES
from cps import gdriveutils from cps import gdriveutils
import uuid import uuid
@ -245,15 +248,23 @@ class TaskEmail(CalibreTask):
df.GetContentFile(datafile) df.GetContentFile(datafile)
else: else:
return None return None
if config.config_binariesdir:
datafile = cls._embed_metadata(calibre_path, book_path, filename, datafile)
os.remove(os.path.join(calibre_path, book_path, filename))
file_ = open(datafile, 'rb') file_ = open(datafile, 'rb')
data = file_.read() data = file_.read()
file_.close() file_.close()
os.remove(datafile) os.remove(datafile)
else: else:
datafile = os.path.join(calibre_path, book_path, filename)
try: try:
file_ = open(os.path.join(calibre_path, book_path, filename), 'rb') if config.config_binariesdir:
datafile = cls._embed_metadata(calibre_path, book_path, filename, datafile)
file_ = open(datafile, 'rb')
data = file_.read() data = file_.read()
file_.close() file_.close()
if config.config_binariesdir:
os.remove(datafile)
except IOError as e: except IOError as e:
log.error_or_exception(e, stacklevel=3) log.error_or_exception(e, stacklevel=3)
log.error(u'The requested file could not be read. Maybe wrong permissions?') log.error(u'The requested file could not be read. Maybe wrong permissions?')
@ -270,3 +281,17 @@ class TaskEmail(CalibreTask):
def __str__(self): def __str__(self):
return "E-mail {}, {}".format(self.name, self.subject) return "E-mail {}, {}".format(self.name, self.subject)
def _embed_metadata(self, calibre_path, book_path, filename, datafile):
datafile_tmp = os.path.join(calibre_path, book_path, "tmp_" + filename)
path_opf = os.path.join(calibre_path, book_path, "metadata.opf")
copy(datafile, datafile_tmp)
calibredb_binarypath = os.path.join(config.config_binariesdir, SUPPORTED_CALIBRE_BINARIES["ebook-meta"])
opf_command = [calibredb_binarypath, datafile_tmp, "--from-opf", path_opf]
p = process_open(opf_command)
_, err = p.communicate()
if err:
# ToDo: Improve error handling
log.error('Metadata embedder encountered an error: %s', err)
return datafile_tmp