Moved preprocessor into main program

This commit is contained in:
Phiol Borman 2020-02-26 11:11:04 +01:00
parent 63e63655de
commit fda2b28162
8 changed files with 516 additions and 21 deletions

View File

@ -2280,13 +2280,31 @@
<span class="help-block">This will include details for other books by new authors found in wishlists or csv files,<br>
or when manually importing a book by a new author</span>
</div>
<fieldset>
<legend>External Programs</legend>
<div class="form-group">
<label for="imp_preprocess">PreProcessor program:</label>
<input type="text" id="imp_preprocess" name="imp_preprocess" value="${lazylibrarian.CONFIG['IMP_PREPROCESS']}" class="form-control">
<span class="help-block">Path to preprocessor to run before importing books into the library</span>
<label for="ext_preprocess">Additional PreProcessor program:</label>
<input type="text" id="ext_preprocess" name="ext_preprocess" value="${lazylibrarian.CONFIG['EXT_PREPROCESS']}" class="form-control">
<span class="help-block">Path to additional preprocessor to run before importing books into the library</span>
<input type="button" value="Test preprocessor" id="testpreprocessor" class="btn btn-default" />
</div>
<legend>Calibre</legend>
<div class="form-group">
<label for="ebook_convert">ebook-convert program:</label>
<input type="text" id="ebook_convert" name="ebook_convert" value="${lazylibrarian.CONFIG['EBOOK_CONVERT']}" class="form-control" placeholder="ebook-convert program">
<span class="help-block">Path to "ebook-convert" to convert book formats</span>
</div>
<div class="form-group">
<label for="ffmpeg">ffmpeg program:</label>
<input type="text" id="ffmpeg" name="ffmpeg" value="${lazylibrarian.CONFIG['FFMPEG']}" class="form-control" placeholder="ffmpeg program">
<span class="help-block">Path to "ffmpeg" to merge audiobook parts or add tags</span>
</div>
<div class="form-group">
<label for="git_program">git program:</label>
<input type="text" placeholder="git program" id="git_program" name="git_program" value="${lazylibrarian.CONFIG['GIT_PROGRAM']}" class="form-control">
<span class="help-block">Git program unless already in your path. Usually leave this blank</span>
</div>
</fieldset>
<legend>Calibre</legend>
<fieldset>
<div class="form-group">
<label for="imp_calibredb">Calibredb import program:</label>
@ -2645,11 +2663,6 @@
</div>
</fieldset>
<fieldset>
<div class="form-group">
<label for="git_program">git program:</label>
<input type="text" placeholder="git program" id="git_program" name="git_program" value="${lazylibrarian.CONFIG['GIT_PROGRAM']}" class="form-control">
<span class="help-block">Git program unless already in your path. Usually leave this blank</span>
</div>
%if lazylibrarian.CONFIG['MAG_TAB'] == True:
<div class="form-group">
<label for="imp_convert">Cover creation program:</label>
@ -2679,6 +2692,8 @@
Create opf files for magazines</label>
</div>
%endif
</fieldset>
<fieldset>
%if lazylibrarian.CONFIG['COMIC_TAB'] == True:
<div class="checkbox">
<%
@ -2811,6 +2826,96 @@
</div>
%endif
</fieldset>
<fieldset>
<legend>eBook Conversions</legend>
<div class="form-group">
<label for="ebook_wanted_formats">eBook wanted formats:</label>
<input type="text" id="ebook_wanted_formats" name="ebook_wanted_formats" value="${lazylibrarian.CONFIG['EBOOK_WANTED_FORMATS']}" class="form-control" placeholder="wanted formats">
</div>
<div class="checkbox">
<%
if lazylibrarian.CONFIG['KEEP_OPF'] == True:
checked = 'checked="checked"'
else:
checked = ''
%>
<label for="keep_opf" class="control-label">
<input type="checkbox" id="keep_opf" name="keep_opf" value="1" ${checked} />
Keep downloaded opf</label>
</div>
<div class="checkbox">
<%
if lazylibrarian.CONFIG['KEEP_JPG'] == True:
checked = 'checked="checked"'
else:
checked = ''
%>
<label for="keep_jpg" class="control-label">
<input type="checkbox" id="keep_jpg" name="keep_jpg" value="1" ${checked} />
Keep downloaded jpg</label>
</div>
<div class="checkbox">
<%
if lazylibrarian.CONFIG['DELETE_OTHER_FORMATS'] == True:
checked = 'checked="checked"'
else:
checked = ''
%>
<label for="delete_other_formats" class="control-label">
<input type="checkbox" id="delete_other_formats" name="delete_other_formats" value="1" ${checked} />
Delete unwanted filetypes</label>
</div>
<legend>AudioBook Conversions</legend>
<div class="form-group">
<label for="audio_options">ffmpeg options:</label>
<input type="text" id="audio_options" name="audio_options" value="${lazylibrarian.CONFIG['AUDIO_OPTIONS']}" class="form-control" placeholder="audio options">
</div>
<div class="checkbox">
<%
if lazylibrarian.CONFIG['CREATE_SINGLEAUDIO'] == True:
checked = 'checked="checked"'
else:
checked = ''
%>
<label for="create_singleaudio" class="control-label">
<input type="checkbox" id="create_singleaudio" name="create_singleaudio" value="1" ${checked} />
Merge audiobook parts into one file</label>
</div>
<div class="checkbox">
<%
if lazylibrarian.CONFIG['KEEP_SEPARATEAUDIO'] == True:
checked = 'checked="checked"'
else:
checked = ''
%>
<label for="keep_separateaudio" class="control-label">
<input type="checkbox" id="keep_separateaudio" name="keep_separateaudio" value="1" ${checked} />
Also keep separate parts</label>
</div>
<div class="checkbox">
<%
if lazylibrarian.CONFIG['WRITE_AUDIOTAGS'] == True:
checked = 'checked="checked"'
else:
checked = ''
%>
<label for="write_audiotags" class="control-label">
<input type="checkbox" id="write_audiotags" name="write_audiotags" value="1" ${checked} />
Write audio tags</label>
</div>
<legend>Magazine Conversions</legend>
<div class="checkbox">
<%
if lazylibrarian.CONFIG['SWAP_COVERPAGE'] == True:
checked = 'checked="checked"'
else:
checked = ''
%>
<label for="swap_coverpage" class="control-label">
<input type="checkbox" id="swap_coverpage" name="swap_coverpage" value="1" ${checked} />
Swap Coverpage</label>
</div>
</fieldset>
</div>
</div>
<br>
@ -3919,7 +4024,7 @@
<label for="datetype[${mag['Title']}]" class="input-group-addon">Date Style</label>
<input type="text" id="datetype[${mag['Title']}]" name="datetype[${mag['Title']}]" value="${mag['DateType']}" class="form-control" placeholder="auto">
<label for="coverpage[${mag['Title']}]" class="input-group-addon">Cover Page</label>
<input type="number" id="coverpage[${mag['Title']}]" name="coverpage[${mag['Title']}]" value="${mag['CoverPage']}" class="form-control" placeholder="1">
<input type="number" id="coverpage[${mag['Title']}]" name="coverpage[${mag['Title']}]" value="${mag['CoverPage']}" min=1 class="form-control" placeholder="1">
</div>
</div>
%endfor

View File

@ -1319,7 +1319,7 @@
});
$('#testpreprocessor').click(function () {
var prg = $.trim($("#imp_preprocessor").val());
var prg = $.trim($("#ext_preprocessor").val());
$.get("testPreProcessor", { 'prg': prg},
function (data) {
bootbox.dialog({

5
example_preprocessor.py → demo_preprocessor.py Executable file → Normal file
View File

@ -11,6 +11,11 @@
# Anything you print to stdout appears as debug messages in the log
# The exit code and messages get passed back to the "test" button
# Always exit zero on success, non-zero on fail
#
################################################################
# NOTE all of the features in the example preprocessor
# are already included in the main lazylibrarian program
################################################################
import os
import subprocess

View File

@ -210,7 +210,7 @@ CONFIG_NONDEFAULT = ['BOOKSTRAP_THEME', 'AUDIOBOOK_TYPE', 'AUDIO_DIR', 'AUDIO_TA
'AUTOADDMAG', 'AUTOADD_MAGONLY', 'TRANSMISSION_DIR', 'DELUGE_DIR', 'QBITTORRENT_DIR',
'BANNED_EXT', 'MAG_RENAME', 'LOGFILES', 'LOGSIZE', 'ISS_FORMAT', 'DATE_FORMAT',
'NO_ISBN', 'NO_SETS', 'NO_LANG', 'NO_PUBDATE', 'IMP_IGNORE', 'IMP_GOOGLEIMAGE', 'DELETE_CSV',
'BLACKLIST_FAILED', 'BLACKLIST_PROCESSED', 'WISHLIST_INTERVAL', 'IMP_PREPROCESS',
'BLACKLIST_FAILED', 'BLACKLIST_PROCESSED', 'WISHLIST_INTERVAL', 'EXT_PREPROCESS',
'OPDS_ENABLED', 'OPDS_AUTHENTICATION', 'OPDS_USERNAME', 'OPDS_PASSWORD', 'OPDS_METAINFO',
'OPDS_PAGE', 'DELAYSEARCH', 'SEED_WAIT', 'GR_AOWNED', 'GR_AWANTED', 'MAG_DELFOLDER',
'ADMIN_EMAIL', 'RSS_ENABLED', 'RSS_HOST', 'RSS_PODCAST', 'COMIC_TAB', 'COMIC_DEST_FOLDER',
@ -310,7 +310,7 @@ CONFIG_DEFINITIONS = {
'IMP_MAGCOVER': ('bool', 'General', 1),
'IMP_COMICCOVER': ('bool', 'General', 1),
'IMP_CONVERT': ('str', 'General', ''),
'IMP_PREPROCESS': ('str', 'General', ''),
'EXT_PREPROCESS': ('str', 'General', ''),
'GIT_PROGRAM': ('str', 'General', ''),
'CACHE_AGE': ('int', 'General', 30),
'TASK_AGE': ('int', 'General', 2),
@ -628,6 +628,17 @@ CONFIG_DEFINITIONS = {
'PREF_UNRARLIB': ('int', 'General', 1),
'USER_AGENT': ('str', 'General', ''),
'RATESTARS': ('bool', 'General', 1),
'EBOOK_WANTED_FORMATS': ('str', 'Preprocess', 'epub, mobi'),
'DELETE_OTHER_FORMATS': ('bool', 'Preprocess', 0),
'EBOOK_CONVERT': ('str', 'Preprocess', 'ebook-convert'),
'KEEP_OPF': ('bool', 'Preprocess', 1),
'KEEP_JPG': ('bool', 'Preprocess', 1),
'FFMPEG': ('str', 'Preprocess', 'ffmpeg'),
'AUDIO_OPTIONS': ('str', 'Preprocess', '-ab, 320k'),
'CREATE_SINGLEAUDIO': ('bool', 'Preprocess', 0),
'KEEP_SEPARATEAUDIO': ('bool', 'Preprocess', 0),
'WRITE_AUDIOTAGS': ('bool', 'Preprocess', 0),
'SWAP_COVERPAGE': ('bool', 'Preprocess', 0),
# 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36'),
}

View File

@ -109,8 +109,9 @@ def upgrade_needed():
# 57 Add Description to comics and Description/Contributors to comicissues
# 58 Ensure Link was added to comicissues (was missing for new installs in v57)
# 59 Added per provider seeders instead of global
# 60 Moved preprocessor into main program and disabled old preprocessor
db_current_version = 59
db_current_version = 60
if db_version < db_current_version:
return db_current_version
@ -1715,3 +1716,13 @@ def db_v59(myDB, upgradelog):
lazylibrarian.CONFIG['NUMBEROFSEEDERS'] = 0
lazylibrarian.config_write()
upgradelog.write("%s v59: complete\n" % time.ctime())
# noinspection PyUnusedLocal
def db_v60(myDB, upgradelog):
if lazylibrarian.CONFIG['IMP_PREPROCESSOR']:
lazylibrarian.UPDATE_MSG = '<b>The old example_preprocessor is deprecated</b>'
lazylibrarian.UPDATE_MSG += '<br>it\'s functions are now included in the main program'
lazylibrarian.UPDATE_MSG += '<br>See new config options in "processing" tab'
time.sleep(30)
upgradelog.write("%s v60: complete\n" % time.ctime())

View File

@ -55,6 +55,7 @@ from lazylibrarian.importer import addAuthorToDB, addAuthorNameToDB, update_tota
from lazylibrarian.librarysync import get_book_info, find_book_in_db, LibraryScan
from lazylibrarian.magazinescan import create_id
from lazylibrarian.images import createMagCover
from lazylibrarian.preprocessor import preprocess_ebook, preprocess_audio, preprocess_magazine
from lazylibrarian.notifiers import notify_download, custom_notify_download
try:
from deluge_client import DelugeRPCClient
@ -134,7 +135,7 @@ def importMag(source_file=None, title=None, issuenum=None):
tempdir = tempfile.mkdtemp()
_ = safe_copy(source_file, tempdir)
success, dest_file = processDestination(tempdir, dest_path, '', '',
global_name, title, "mag")
global_name, title, "magazine")
shutil.rmtree(tempdir, ignore_errors=True)
if not success:
logger.error("Unable to import %s: %s" % (source_file, dest_file))
@ -914,6 +915,7 @@ def processDir(reset=False, startdir=None, ignoreclient=False, downloadid=None):
else:
data = myDB.match('SELECT IssueDate from magazines WHERE Title=?', (book['BookID'],))
if data: # it's a magazine
book_type = 'magazine'
logger.debug('Processing magazine %s' % book['BookID'])
# AuxInfo was added for magazine release date, normally housed in 'magazines'
# but if multiple files are downloading, there will be an error in post-processing
@ -959,6 +961,7 @@ def processDir(reset=False, startdir=None, ignoreclient=False, downloadid=None):
data = None
if data: # it's a comic
book_type = 'comic'
logger.debug('Processing %s issue %s' % (data['Title'], issueid))
mostrecentissue = data['LatestIssue']
if PY2:
@ -2165,11 +2168,23 @@ def processDestination(pp_path=None, dest_path=None, authorname=None, bookname=N
return False, 'Unable to locate a valid filetype (%s) in %s, leaving for manual processing' % (
booktype, pp_path)
if booktype == 'ebook':
preprocess_ebook(pp_path)
elif booktype == 'audio':
preprocess_audio(pp_path, authorname, bookname)
elif booktype == 'magazine':
myDB = database.DBConnection()
res = myDB.match("SELECT CoverPage from magazines WHERE Title=?", (bookid,))
cover = 0
if res:
cover = check_int(res['CoverPage'], 0)
preprocess_magazine(pp_path, cover=cover)
# run custom pre-processing, for example remove unwanted formats
# or force format conversion before sending to calibre
if len(lazylibrarian.CONFIG['IMP_PREPROCESS']):
logger.debug("Running PreProcessor: %s %s %s %s" % (booktype, pp_path, authorname, bookname))
params = [lazylibrarian.CONFIG['IMP_PREPROCESS'], booktype, pp_path, authorname, bookname]
if len(lazylibrarian.CONFIG['EXT_PREPROCESS']):
logger.debug("Running external PreProcessor: %s %s %s %s" % (booktype, pp_path, authorname, bookname))
params = [lazylibrarian.CONFIG['EXT_PREPROCESS'], booktype, pp_path, authorname, bookname]
rc, res, err = runScript(params)
if rc:
return False, "Preprocessor returned %s: res[%s] err[%s]" % (rc, res, err)

View File

@ -0,0 +1,348 @@
# This file is part of Lazylibrarian.
# Lazylibrarian is free software':'you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# Lazylibrarian is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with Lazylibrarian. If not, see <http://www.gnu.org/licenses/>.
from __future__ import print_function
from __future__ import with_statement
import os
import subprocess
import lazylibrarian
from lazylibrarian import logger
from lazylibrarian.common import listdir, path_exists
from lazylibrarian.formatter import makeBytestr, check_int, getList
try:
from tinytag import TinyTag
except ImportError:
try:
from lib.tinytag import TinyTag
except ImportError:
TinyTag = None
try:
# noinspection PyProtectedMember
from PyPDF3 import PdfFileWriter, PdfFileReader
except ImportError:
try:
# noinspection PyProtectedMember
from lib.PyPDF3 import PdfFileWriter, PdfFileReader
except ImportError:
PdfFileWriter = None
PdfFileReader = None
def preprocess_ebook(bookfolder):
ebook_convert = lazylibrarian.CONFIG['ebook_convert']
if not path_exists(ebook_convert):
logger.error("%s not found" % ebook_convert)
return
logger.debug("Preprocess ebook %s" % bookfolder)
sourcefile = None
created = ''
for fname in listdir(bookfolder):
filename, extn = os.path.splitext(fname)
if extn.lower() == '.epub':
sourcefile = fname
break
elif extn.lower() in ['.mobi', '.azw3']:
sourcefile = fname
break
logger.debug("Wanted formats: %s" % lazylibrarian.CONFIG['ebook_wanted_formats'])
if not sourcefile:
logger.error("No suitable sourcefile found in %s" % bookfolder)
return
basename, source_extn = os.path.splitext(sourcefile)
wanted_formats = getList(lazylibrarian.CONFIG['ebook_wanted_formats'])
for ftype in wanted_formats:
if not path_exists(os.path.join(bookfolder, basename + '.' + ftype)):
logger.debug("No %s" % ftype)
params = [ebook_convert, os.path.join(bookfolder, sourcefile),
os.path.join(bookfolder, basename + '.' + ftype)]
if ftype == 'mobi':
params.extend(['--output-profile', 'kindle'])
try:
_ = subprocess.check_output(params, stderr=subprocess.STDOUT)
if created:
created += ' '
created += ftype
except Exception as e:
logger.error("%s" % e)
logger.error(repr(params))
return
else:
logger.debug("Found %s" % ftype)
if lazylibrarian.CONFIG['delete_other_formats']:
if lazylibrarian.CONFIG['keep_opf']:
wanted_formats.append('opf')
if lazylibrarian.CONFIG['keep_opf']:
wanted_formats.append('jpg')
for fname in listdir(bookfolder):
filename, extn = os.path.splitext(fname)
if not extn or extn.lstrip('.').lower() not in wanted_formats:
logger.debug("Deleting %s" % fname)
try:
os.remove(os.path.join(bookfolder, fname))
except OSError:
pass
if created:
logger.debug("Created %s from %s" % (created, source_extn))
else:
logger.debug("No extra ebook formats created")
def preprocess_audio(bookfolder, authorname, bookname):
if not lazylibrarian.CONFIG['create_singleaudio'] and not lazylibrarian.CONFIG['write_audiotags']:
return
ffmpeg = lazylibrarian.CONFIG['ffmpeg']
if not path_exists(ffmpeg):
logger.error("%s not found" % ffmpeg)
return
if not TinyTag:
logger.error("TinyTag not found")
return
logger.debug("Preprocess audio %s %s %s" % (bookfolder, authorname, bookname))
# this produces a single file audiobook
ffmpeg_params = ['-f', 'concat', '-safe', '0', '-i',
os.path.join(bookfolder, 'partslist.ll'), '-f', 'ffmetadata',
'-i', os.path.join(bookfolder, 'metadata.ll'), '-map_metadata', '1',
'-id3v2_version', '3']
cnt = 0
parts = []
total = 0
author = ''
book = ''
audio_file = ''
out_type = ''
for f in listdir(bookfolder):
extn = os.path.splitext(f)[1].lstrip('.')
if extn.lower() in getList(lazylibrarian.CONFIG['audiobook_type']):
cnt += 1
audio_file = f
try:
audio_path = os.path.join(bookfolder, f)
performer = ''
composer = ''
albumartist = ''
book = ''
track = 0
total = 0
if TinyTag.is_supported(audio_path):
id3r = TinyTag.get(audio_path)
performer = id3r.artist
composer = id3r.composer
albumartist = id3r.albumartist
book = id3r.album
track = id3r.track
total = id3r.track_total
track = check_int(track, 0)
total = check_int(total, 0)
if performer:
performer = performer.strip()
if composer:
composer = composer.strip()
if book:
book = book.strip()
if albumartist:
albumartist = albumartist.strip()
if composer: # if present, should be author
author = composer
elif performer: # author, or narrator if composer == author
author = performer
elif albumartist:
author = albumartist
if author and book:
parts.append([track, book, author, f])
if track == 1:
out_type = extn
except Exception as e:
logger.debug("tinytag %s %s" % (type(e).__name__, str(e)))
pass
logger.info("%s found %s audiofiles" % (book, cnt))
if cnt == 1 and not parts: # single file audiobook with no tags
parts = [[1, book, author, audio_file]]
if cnt != len(parts):
logger.error("%s: Incorrect number of parts (found %i from %i)" % (book, len(parts), cnt))
return
if total and total != cnt:
logger.error("%s: Reported %i parts, got %i" % (book, total, cnt))
return
if cnt == 1:
logger.info("Only one audio file found, nothing to merge")
return
# check all parts have the same author and title
if len(parts) > 1:
for part in parts:
if part[1] != book:
logger.error("%s: Inconsistent title: [%s][%s]" % (book, part[1], book))
return
if part[2] != author:
logger.error("%s: Inconsistent author: [%s][%s]" % (book, part[2], author))
return
# do we have any track info (value is 0 if not)
tokmatch = ''
if parts[0][0] == 0:
# try to extract part information from filename. Search for token style of part 1 in this order...
for token in [' 001.', ' 01.', ' 1.', ' 001 ', ' 01 ', ' 1 ', '01']:
if tokmatch:
break
for part in parts:
if token in part[3]:
tokmatch = token
break
if tokmatch: # we know the numbering style, get numbers for the other parts
cnt = 0
while cnt < len(parts):
cnt += 1
if tokmatch == ' 001.':
pattern = ' %s.' % str(cnt).zfill(3)
elif tokmatch == ' 01.':
pattern = ' %s.' % str(cnt).zfill(2)
elif tokmatch == ' 1.':
pattern = ' %s.' % str(cnt)
elif tokmatch == ' 001 ':
pattern = ' %s ' % str(cnt).zfill(3)
elif tokmatch == ' 01 ':
pattern = ' %s ' % str(cnt).zfill(2)
elif tokmatch == ' 1 ':
pattern = ' %s ' % str(cnt)
else:
pattern = '%s' % str(cnt).zfill(2)
# standardise numbering of the parts
for part in parts:
if pattern in part[3]:
part[0] = cnt
break
parts.sort(key=lambda x: x[0])
# check all parts are present
cnt = 0
while cnt < len(parts):
if parts[cnt][0] != cnt + 1:
logger.error("%s: No part %i found" % (book, cnt + 1))
return
cnt += 1
# if we get here, looks like we have all the parts
with open(os.path.join(bookfolder, 'partslist.ll'), 'wb') as f:
for part in parts:
f.write("file '%s'" % makeBytestr(part[3]))
if lazylibrarian.CONFIG['write_audiotags'] and authorname and bookname:
if tokmatch or (part[2] != authorname) or (part[1] != bookname):
extn = os.path.splitext(part[3])[1]
params = [ffmpeg, '-i', os.path.join(bookfolder, part[3]),
'-y', '-c:a', 'copy', '-metadata', "album=%s" % bookname,
'-metadata', "artist=%s" % authorname,
'-metadata', "track=%s" % part[0],
os.path.join(bookfolder, "tempaudio%s" % extn)]
try:
_ = subprocess.check_output(params, stderr=subprocess.STDOUT)
os.remove(os.path.join(bookfolder, part[3]))
os.rename(os.path.join(bookfolder, "tempaudio%s" % extn),
os.path.join(bookfolder, part[3]))
logger.debug("Metadata written to %s" % part[3])
except Exception as e:
logger.error(str(e))
return
if lazylibrarian.CONFIG['create_singleaudio']:
params = [ffmpeg, '-i', os.path.join(bookfolder, parts[0][3]),
'-f', 'ffmetadata', '-y', os.path.join(bookfolder, 'metadata.ll')]
try:
_ = subprocess.check_output(params, stderr=subprocess.STDOUT)
logger.debug("Metadata written to metadata.ll")
except Exception as e:
logger.error(str(e))
return
params = [ffmpeg]
params.extend(ffmpeg_params)
params.extend(getList(lazylibrarian.CONFIG['audio_options']))
params.append('-y')
if not out_type:
out_type = 'mp3'
outfile = "%s - %s.%s" % (author, book, out_type)
params.append(os.path.join(bookfolder, outfile))
try:
logger.debug("Processing %d files" % len(parts))
_ = subprocess.check_output(params, stderr=subprocess.STDOUT)
except Exception as e:
logger.error(str(e))
return
logger.info("%d files merged into %s" % (len(parts), outfile))
os.remove(os.path.join(bookfolder, 'partslist.ll'))
os.remove(os.path.join(bookfolder, 'metadata.ll'))
if not lazylibrarian.CONFIG['keep_separate_audio']:
logger.debug("Removing %d part files" % len(parts))
for part in parts:
os.remove(os.path.join(bookfolder, part[3]))
def preprocess_magazine(bookfolder, cover=0):
logger.debug("Preprocess magazine %s cover=%s" % (bookfolder, cover))
if cover < 2:
return
if not PdfFileWriter:
logger.error("PdfFileWriter not found")
return
try:
sourcefile = None
for fname in listdir(bookfolder):
filename, extn = os.path.splitext(fname)
if extn.lower() == '.pdf':
sourcefile = fname
break
if not sourcefile:
logger.error("No suitable sourcefile found in %s" % bookfolder)
return
cover -= 1 # zero based page count
fname = os.path.join(bookfolder, sourcefile)
output = PdfFileWriter()
f = open(fname, "rb")
input1 = PdfFileReader(f)
cnt = input1.getNumPages()
output.addPage(input1.getPage(cover))
p = 0
while p < cnt:
if p != cover:
output.addPage(input1.getPage(p))
p = p + 1
with open(fname + 'new', "wb") as outputStream:
output.write(outputStream)
logger.debug("%s has %d pages. Cover from page %d" % (fname, cnt, cover + 1))
f.close()
os.remove(fname)
os.rename(fname + 'new', fname)
except Exception as e:
logger.error(str(e))

View File

@ -5802,9 +5802,9 @@ class WebInterface(object):
threading.currentThread().name = "WEBSERVER"
cherrypy.response.headers['Cache-Control'] = "max-age=0,no-cache,no-store"
if 'prg' in kwargs and kwargs['prg']:
lazylibrarian.CONFIG['IMP_PREPROCESS'] = kwargs['prg']
if len(lazylibrarian.CONFIG['IMP_PREPROCESS']):
params = [lazylibrarian.CONFIG['IMP_PREPROCESS'], 'test', '']
lazylibrarian.CONFIG['EXT_PREPROCESS'] = kwargs['prg']
if len(lazylibrarian.CONFIG['EXT_PREPROCESS']):
params = [lazylibrarian.CONFIG['EXT_PREPROCESS'], 'test', '']
rc, res, err = runScript(params)
if rc:
return "Preprocessor returned %s: res[%s] err[%s]" % (rc, res, err)