|
|
@ -42,6 +42,7 @@ STAT_FINISH_SUCCESS = 3
|
|
|
|
TASK_EMAIL = 1
|
|
|
|
TASK_EMAIL = 1
|
|
|
|
TASK_CONVERT = 2
|
|
|
|
TASK_CONVERT = 2
|
|
|
|
TASK_UPLOAD = 3
|
|
|
|
TASK_UPLOAD = 3
|
|
|
|
|
|
|
|
TASK_CONVERT_ANY = 4
|
|
|
|
|
|
|
|
|
|
|
|
RET_FAIL = 0
|
|
|
|
RET_FAIL = 0
|
|
|
|
RET_SUCCESS = 1
|
|
|
|
RET_SUCCESS = 1
|
|
|
@ -171,7 +172,9 @@ class WorkerThread(threading.Thread):
|
|
|
|
if self.queue[self.current]['typ'] == TASK_EMAIL:
|
|
|
|
if self.queue[self.current]['typ'] == TASK_EMAIL:
|
|
|
|
self.send_raw_email()
|
|
|
|
self.send_raw_email()
|
|
|
|
if self.queue[self.current]['typ'] == TASK_CONVERT:
|
|
|
|
if self.queue[self.current]['typ'] == TASK_CONVERT:
|
|
|
|
self.convert_mobi()
|
|
|
|
self.convert_any_format()
|
|
|
|
|
|
|
|
if self.queue[self.current]['typ'] == TASK_CONVERT_ANY:
|
|
|
|
|
|
|
|
self.convert_any_format()
|
|
|
|
# TASK_UPLOAD is handled implicitly
|
|
|
|
# TASK_UPLOAD is handled implicitly
|
|
|
|
self.current += 1
|
|
|
|
self.current += 1
|
|
|
|
else:
|
|
|
|
else:
|
|
|
@ -200,61 +203,75 @@ class WorkerThread(threading.Thread):
|
|
|
|
def get_taskstatus(self):
|
|
|
|
def get_taskstatus(self):
|
|
|
|
if self.current < len(self.queue):
|
|
|
|
if self.current < len(self.queue):
|
|
|
|
if self.queue[self.current]['status'] == STAT_STARTED:
|
|
|
|
if self.queue[self.current]['status'] == STAT_STARTED:
|
|
|
|
if not self.queue[self.current]['typ'] == TASK_CONVERT:
|
|
|
|
if self.queue[self.current]['typ'] == TASK_EMAIL:
|
|
|
|
self.UIqueue[self.current]['progress'] = self.get_send_status()
|
|
|
|
self.UIqueue[self.current]['progress'] = self.get_send_status()
|
|
|
|
self.UIqueue[self.current]['runtime'] = self._formatRuntime(
|
|
|
|
self.UIqueue[self.current]['runtime'] = self._formatRuntime(
|
|
|
|
datetime.now() - self.queue[self.current]['starttime'])
|
|
|
|
datetime.now() - self.queue[self.current]['starttime'])
|
|
|
|
return self.UIqueue
|
|
|
|
return self.UIqueue
|
|
|
|
|
|
|
|
|
|
|
|
def convert_mobi(self):
|
|
|
|
def convert_any_format(self):
|
|
|
|
# convert book, and upload in case of google drive
|
|
|
|
# convert book, and upload in case of google drive
|
|
|
|
self.queue[self.current]['status'] = STAT_STARTED
|
|
|
|
self.queue[self.current]['status'] = STAT_STARTED
|
|
|
|
self.UIqueue[self.current]['status'] = _('Started')
|
|
|
|
self.UIqueue[self.current]['status'] = _('Started')
|
|
|
|
self.queue[self.current]['starttime'] = datetime.now()
|
|
|
|
self.queue[self.current]['starttime'] = datetime.now()
|
|
|
|
self.UIqueue[self.current]['formStarttime'] = self.queue[self.current]['starttime']
|
|
|
|
self.UIqueue[self.current]['formStarttime'] = self.queue[self.current]['starttime']
|
|
|
|
filename=self.convert()
|
|
|
|
curr_task = self.queue[self.current]['typ']
|
|
|
|
|
|
|
|
filename = self.convert_ebook_format()
|
|
|
|
|
|
|
|
if filename:
|
|
|
|
if web.ub.config.config_use_google_drive:
|
|
|
|
if web.ub.config.config_use_google_drive:
|
|
|
|
gd.updateGdriveCalibreFromLocal()
|
|
|
|
gd.updateGdriveCalibreFromLocal()
|
|
|
|
if(filename):
|
|
|
|
if curr_task == TASK_CONVERT:
|
|
|
|
self.add_email(_(u'Send to Kindle'), self.queue[self.current]['path'], filename,
|
|
|
|
self.add_email(_(u'Send to Kindle'), self.queue[self.current]['path'], filename,
|
|
|
|
self.queue[self.current]['settings'], self.queue[self.current]['kindle'],
|
|
|
|
self.queue[self.current]['settings'], self.queue[self.current]['kindle'],
|
|
|
|
self.UIqueue[self.current]['user'], _(u"E-mail: %s" % self.queue[self.current]['title']))
|
|
|
|
self.UIqueue[self.current]['user'], _(u"E-mail: %s" % self.queue[self.current]['title']))
|
|
|
|
|
|
|
|
|
|
|
|
def convert(self):
|
|
|
|
|
|
|
|
|
|
|
|
def convert_ebook_format(self):
|
|
|
|
error_message = None
|
|
|
|
error_message = None
|
|
|
|
file_path = self.queue[self.current]['file_path']
|
|
|
|
file_path = self.queue[self.current]['file_path']
|
|
|
|
bookid = self.queue[self.current]['bookid']
|
|
|
|
bookid = self.queue[self.current]['bookid']
|
|
|
|
# check if converter-excecutable is existing
|
|
|
|
format_old_ext = u'.' + self.queue[self.current]['settings']['old_book_format'].lower()
|
|
|
|
|
|
|
|
format_new_ext = u'.' + self.queue[self.current]['settings']['new_book_format'].lower()
|
|
|
|
|
|
|
|
# check if converter-executable is existing
|
|
|
|
if not os.path.exists(web.ub.config.config_converterpath):
|
|
|
|
if not os.path.exists(web.ub.config.config_converterpath):
|
|
|
|
self._handleError(_(u"Convertertool %(converter)s not found", converter=web.ub.config.config_converterpath))
|
|
|
|
self._handleError(_(u"Convertertool %(converter)s not found", converter=web.ub.config.config_converterpath))
|
|
|
|
return
|
|
|
|
return
|
|
|
|
try:
|
|
|
|
try:
|
|
|
|
# check which converter to use kindlegen is "1"
|
|
|
|
# check which converter to use kindlegen is "1"
|
|
|
|
|
|
|
|
if format_old_ext == '.epub' and format_new_ext == '.mobi':
|
|
|
|
if web.ub.config.config_ebookconverter == 1:
|
|
|
|
if web.ub.config.config_ebookconverter == 1:
|
|
|
|
command = [web.ub.config.config_converterpath, u'"' + file_path + u'.epub"']
|
|
|
|
if os.name == 'nt':
|
|
|
|
|
|
|
|
command = web.ub.config.config_converterpath + u' "' + file_path + u'.epub"'
|
|
|
|
|
|
|
|
if sys.version_info < (3, 0):
|
|
|
|
|
|
|
|
command = command.encode(sys.getfilesystemencoding())
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
|
|
|
|
command = [web.ub.config.config_converterpath, file_path + u'.epub']
|
|
|
|
|
|
|
|
if sys.version_info < (3, 0):
|
|
|
|
|
|
|
|
command = [x.encode(sys.getfilesystemencoding()) for x in command]
|
|
|
|
|
|
|
|
if web.ub.config.config_ebookconverter == 2:
|
|
|
|
# Linux py2.7 encode as list without quotes no empty element for parameters
|
|
|
|
# Linux py2.7 encode as list without quotes no empty element for parameters
|
|
|
|
# linux py3.x no encode and as list without quotes no empty element for parameters
|
|
|
|
# linux py3.x no encode and as list without quotes no empty element for parameters
|
|
|
|
# windows py2.7 encode as string with qoutes empty element for parameters is okay
|
|
|
|
# windows py2.7 encode as string with quotes empty element for parameters is okay
|
|
|
|
# windows py 3.x no encode and as string with qoutes empty element for parameters is okay
|
|
|
|
# windows py 3.x no encode and as string with quotes empty element for parameters is okay
|
|
|
|
# seperate handling for windows and linux
|
|
|
|
# separate handling for windows and linux
|
|
|
|
if os.name == 'nt':
|
|
|
|
if os.name == 'nt':
|
|
|
|
command = web.ub.config.config_converterpath + u' "' + file_path + u'.epub" "' + \
|
|
|
|
command = web.ub.config.config_converterpath + u' "' + file_path + format_old_ext + u'" "' + \
|
|
|
|
file_path + u'.mobi" ' + web.ub.config.config_calibre
|
|
|
|
file_path + format_new_ext + u'" ' + web.ub.config.config_calibre
|
|
|
|
if sys.version_info < (3, 0):
|
|
|
|
if sys.version_info < (3, 0):
|
|
|
|
command = command.encode(sys.getfilesystemencoding())
|
|
|
|
command = command.encode(sys.getfilesystemencoding())
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
command = [web.ub.config.config_converterpath, (file_path + u'.epub'),
|
|
|
|
command = [web.ub.config.config_converterpath, (file_path + format_old_ext),
|
|
|
|
(file_path + u'.mobi')]
|
|
|
|
(file_path + format_new_ext)]
|
|
|
|
if web.ub.config.config_calibre:
|
|
|
|
if web.ub.config.config_calibre:
|
|
|
|
command.append(web.ub.config.config_calibre)
|
|
|
|
command.append(web.ub.config.config_calibre)
|
|
|
|
if sys.version_info < (3, 0):
|
|
|
|
if sys.version_info < (3, 0):
|
|
|
|
command = [ x.encode(sys.getfilesystemencoding()) for x in command ]
|
|
|
|
command = [x.encode(sys.getfilesystemencoding()) for x in command]
|
|
|
|
|
|
|
|
|
|
|
|
p = subprocess.Popen(command, stdout=subprocess.PIPE, universal_newlines=True)
|
|
|
|
p = subprocess.Popen(command, stdout=subprocess.PIPE, universal_newlines=True)
|
|
|
|
except OSError as e:
|
|
|
|
except OSError as e:
|
|
|
|
self._handleError(_(u"Ebook-converter failed: %s" % e))
|
|
|
|
self._handleError(_(u"Ebook-converter failed: %s" % e))
|
|
|
|
return
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
if web.ub.config.config_ebookconverter == 1:
|
|
|
|
if web.ub.config.config_ebookconverter == 1:
|
|
|
|
nextline = p.communicate()[0]
|
|
|
|
nextline = p.communicate()[0]
|
|
|
|
# Format of error message (kindlegen translates its output texts):
|
|
|
|
# Format of error message (kindlegen translates its output texts):
|
|
|
@ -265,7 +282,6 @@ class WorkerThread(threading.Thread):
|
|
|
|
error_message = _(u"Kindlegen failed with Error %(error)s. Message: %(message)s",
|
|
|
|
error_message = _(u"Kindlegen failed with Error %(error)s. Message: %(message)s",
|
|
|
|
error=conv_error.group(1), message=conv_error.group(2).strip())
|
|
|
|
error=conv_error.group(1), message=conv_error.group(2).strip())
|
|
|
|
web.app.logger.debug("convert_kindlegen: " + nextline)
|
|
|
|
web.app.logger.debug("convert_kindlegen: " + nextline)
|
|
|
|
|
|
|
|
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
while p.poll() is None:
|
|
|
|
while p.poll() is None:
|
|
|
|
nextline = p.stdout.readline()
|
|
|
|
nextline = p.stdout.readline()
|
|
|
@ -277,30 +293,31 @@ class WorkerThread(threading.Thread):
|
|
|
|
if progress:
|
|
|
|
if progress:
|
|
|
|
self.UIqueue[self.current]['progress'] = progress.group(1) + ' %'
|
|
|
|
self.UIqueue[self.current]['progress'] = progress.group(1) + ' %'
|
|
|
|
|
|
|
|
|
|
|
|
#process returncode
|
|
|
|
# process returncode
|
|
|
|
check = p.returncode
|
|
|
|
check = p.returncode
|
|
|
|
|
|
|
|
|
|
|
|
# kindlegen returncodes
|
|
|
|
# kindlegen returncodes
|
|
|
|
# 0 = Info(prcgen):I1036: Mobi file built successfully
|
|
|
|
# 0 = Info(prcgen):I1036: Mobi file built successfully
|
|
|
|
# 1 = Info(prcgen):I1037: Mobi file built with WARNINGS!
|
|
|
|
# 1 = Info(prcgen):I1037: Mobi file built with WARNINGS!
|
|
|
|
# 2 = Info(prcgen):I1038: MOBI file could not be generated because of errors!
|
|
|
|
# 2 = Info(prcgen):I1038: MOBI file could not be generated because of errors!
|
|
|
|
if ( check < 2 and web.ub.config.config_ebookconverter == 1) or \
|
|
|
|
if (check < 2 and web.ub.config.config_ebookconverter == 1) or \
|
|
|
|
(check == 0 and web.ub.config.config_ebookconverter == 2):
|
|
|
|
(check == 0 and web.ub.config.config_ebookconverter == 2):
|
|
|
|
cur_book = web.db.session.query(web.db.Books).filter(web.db.Books.id == bookid).first()
|
|
|
|
cur_book = web.db.session.query(web.db.Books).filter(web.db.Books.id == bookid).first()
|
|
|
|
new_format = web.db.Data(name=cur_book.data[0].name,book_format="MOBI",
|
|
|
|
new_format = web.db.Data(name=cur_book.data[0].name,
|
|
|
|
book=bookid,uncompressed_size=os.path.getsize(file_path + ".mobi"))
|
|
|
|
book_format=self.queue[self.current]['settings']['new_book_format'],
|
|
|
|
|
|
|
|
book=bookid, uncompressed_size=os.path.getsize(file_path + format_new_ext))
|
|
|
|
cur_book.data.append(new_format)
|
|
|
|
cur_book.data.append(new_format)
|
|
|
|
web.db.session.commit()
|
|
|
|
web.db.session.commit()
|
|
|
|
self.queue[self.current]['path'] = cur_book.path
|
|
|
|
self.queue[self.current]['path'] = cur_book.path
|
|
|
|
self.queue[self.current]['title'] = cur_book.title
|
|
|
|
self.queue[self.current]['title'] = cur_book.title
|
|
|
|
if web.ub.config.config_use_google_drive:
|
|
|
|
if web.ub.config.config_use_google_drive:
|
|
|
|
os.remove(file_path + u".epub")
|
|
|
|
os.remove(file_path + format_old_ext)
|
|
|
|
self.queue[self.current]['status'] = STAT_FINISH_SUCCESS
|
|
|
|
self.queue[self.current]['status'] = STAT_FINISH_SUCCESS
|
|
|
|
self.UIqueue[self.current]['status'] = _('Finished')
|
|
|
|
self.UIqueue[self.current]['status'] = _('Finished')
|
|
|
|
self.UIqueue[self.current]['progress'] = "100 %"
|
|
|
|
self.UIqueue[self.current]['progress'] = "100 %"
|
|
|
|
self.UIqueue[self.current]['runtime'] = self._formatRuntime(
|
|
|
|
self.UIqueue[self.current]['runtime'] = self._formatRuntime(
|
|
|
|
datetime.now() - self.queue[self.current]['starttime'])
|
|
|
|
datetime.now() - self.queue[self.current]['starttime'])
|
|
|
|
return file_path + ".mobi"
|
|
|
|
return file_path + format_new_ext
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
web.app.logger.info("ebook converter failed with error while converting book")
|
|
|
|
web.app.logger.info("ebook converter failed with error while converting book")
|
|
|
|
if not error_message:
|
|
|
|
if not error_message:
|
|
|
@ -309,18 +326,20 @@ class WorkerThread(threading.Thread):
|
|
|
|
return
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def add_convert(self, file_path, bookid, user_name, typ, settings, kindle_mail):
|
|
|
|
def add_convert(self, file_path, bookid, user_name, typ, settings, kindle_mail=None):
|
|
|
|
addLock = threading.Lock()
|
|
|
|
addLock = threading.Lock()
|
|
|
|
addLock.acquire()
|
|
|
|
addLock.acquire()
|
|
|
|
if self.last >= 20:
|
|
|
|
if self.last >= 20:
|
|
|
|
self.delete_completed_tasks()
|
|
|
|
self.delete_completed_tasks()
|
|
|
|
# progress, runtime, and status = 0
|
|
|
|
# progress, runtime, and status = 0
|
|
|
|
self.id += 1
|
|
|
|
self.id += 1
|
|
|
|
self.queue.append({'file_path':file_path, 'bookid':bookid, 'starttime': 0, 'kindle':kindle_mail,
|
|
|
|
task = TASK_CONVERT_ANY
|
|
|
|
'status': STAT_WAITING, 'typ': TASK_CONVERT, 'settings':settings})
|
|
|
|
if kindle_mail:
|
|
|
|
|
|
|
|
task = TASK_CONVERT
|
|
|
|
|
|
|
|
self.queue.append({'file_path':file_path, 'bookid':bookid, 'starttime': 0, 'kindle': kindle_mail,
|
|
|
|
|
|
|
|
'status': STAT_WAITING, 'typ': task, 'settings':settings})
|
|
|
|
self.UIqueue.append({'user': user_name, 'formStarttime': '', 'progress': " 0 %", 'type': typ,
|
|
|
|
self.UIqueue.append({'user': user_name, 'formStarttime': '', 'progress': " 0 %", 'type': typ,
|
|
|
|
'runtime': '0 s', 'status': _('Waiting'),'id': self.id } )
|
|
|
|
'runtime': '0 s', 'status': _('Waiting'),'id': self.id } )
|
|
|
|
self.id += 1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self.last=len(self.queue)
|
|
|
|
self.last=len(self.queue)
|
|
|
|
addLock.release()
|
|
|
|
addLock.release()
|
|
|
@ -334,12 +353,12 @@ class WorkerThread(threading.Thread):
|
|
|
|
if self.last >= 20:
|
|
|
|
if self.last >= 20:
|
|
|
|
self.delete_completed_tasks()
|
|
|
|
self.delete_completed_tasks()
|
|
|
|
# progress, runtime, and status = 0
|
|
|
|
# progress, runtime, and status = 0
|
|
|
|
|
|
|
|
self.id += 1
|
|
|
|
self.queue.append({'subject':subject, 'attachment':attachment, 'filepath':filepath,
|
|
|
|
self.queue.append({'subject':subject, 'attachment':attachment, 'filepath':filepath,
|
|
|
|
'settings':settings, 'recipent':recipient, 'starttime': 0,
|
|
|
|
'settings':settings, 'recipent':recipient, 'starttime': 0,
|
|
|
|
'status': STAT_WAITING, 'typ': TASK_EMAIL, 'text':text})
|
|
|
|
'status': STAT_WAITING, 'typ': TASK_EMAIL, 'text':text})
|
|
|
|
self.UIqueue.append({'user': user_name, 'formStarttime': '', 'progress': " 0 %", 'type': typ,
|
|
|
|
self.UIqueue.append({'user': user_name, 'formStarttime': '', 'progress': " 0 %", 'type': typ,
|
|
|
|
'runtime': '0 s', 'status': _('Waiting'),'id': self.id })
|
|
|
|
'runtime': '0 s', 'status': _('Waiting'),'id': self.id })
|
|
|
|
self.id += 1
|
|
|
|
|
|
|
|
self.last=len(self.queue)
|
|
|
|
self.last=len(self.queue)
|
|
|
|
addLock.release()
|
|
|
|
addLock.release()
|
|
|
|
|
|
|
|
|
|
|
@ -350,11 +369,11 @@ class WorkerThread(threading.Thread):
|
|
|
|
if self.last >= 20:
|
|
|
|
if self.last >= 20:
|
|
|
|
self.delete_completed_tasks()
|
|
|
|
self.delete_completed_tasks()
|
|
|
|
# progress=100%, runtime=0, and status finished
|
|
|
|
# progress=100%, runtime=0, and status finished
|
|
|
|
|
|
|
|
self.id += 1
|
|
|
|
self.queue.append({'starttime': datetime.now(), 'status': STAT_FINISH_SUCCESS, 'typ': TASK_UPLOAD})
|
|
|
|
self.queue.append({'starttime': datetime.now(), 'status': STAT_FINISH_SUCCESS, 'typ': TASK_UPLOAD})
|
|
|
|
self.UIqueue.append({'user': user_name, 'formStarttime': '', 'progress': "100 %", 'type': typ,
|
|
|
|
self.UIqueue.append({'user': user_name, 'formStarttime': '', 'progress': "100 %", 'type': typ,
|
|
|
|
'runtime': '0 s', 'status': _('Finished'),'id': self.id })
|
|
|
|
'runtime': '0 s', 'status': _('Finished'),'id': self.id })
|
|
|
|
self.UIqueue[self.current]['formStarttime'] = self.queue[self.current]['starttime']
|
|
|
|
self.UIqueue[self.current]['formStarttime'] = self.queue[self.current]['starttime']
|
|
|
|
self.id += 1
|
|
|
|
|
|
|
|
self.last=len(self.queue)
|
|
|
|
self.last=len(self.queue)
|
|
|
|
addLock.release()
|
|
|
|
addLock.release()
|
|
|
|
|
|
|
|
|
|
|
|