diff --git a/cps/helper.py b/cps/helper.py index ed829c9e..9aa3d884 100644 --- a/cps/helper.py +++ b/cps/helper.py @@ -13,9 +13,10 @@ import unicodedata from io import BytesIO import worker import time - from flask import send_from_directory, make_response, redirect, abort from flask_babel import gettext as _ +from flask_login import current_user +from babel.dates import format_datetime import threading import shutil import requests @@ -73,10 +74,12 @@ def convert_book_format(book_id, calibrepath, old_book_format, new_book_format, # read settings and append converter task to queue if kindle_mail: settings = ub.get_mail_settings() - text = _(u"%(format)s: %(book)s", format=new_book_format, book=book.title) + settings['subject'] = _('Send to Kindle') # pretranslate Subject for e-mail + settings['body'] = _(u'This e-mail has been sent via Calibre-Web.') + # text = _(u"%(format)s: %(book)s", format=new_book_format, book=book.title) else: settings = dict() - text = _(u"%(format)s: %(book)s", format=new_book_format, book=book.title) + text = (u"%s -> %s: %s" % (old_book_format, new_book_format, book.title)) settings['old_book_format'] = old_book_format settings['new_book_format'] = new_book_format global_WorkerThread.add_convert(file_path, book.id, user_id, text, settings, kindle_mail) @@ -89,7 +92,8 @@ def convert_book_format(book_id, calibrepath, old_book_format, new_book_format, def send_test_mail(kindle_mail, user_name): global_WorkerThread.add_email(_(u'Calibre-Web test e-mail'),None, None, ub.get_mail_settings(), - kindle_mail, user_name, _(u"Test e-mail")) + kindle_mail, user_name, _(u"Test e-mail"), + _(u'This e-mail has been sent via Calibre-Web.')) return @@ -133,7 +137,7 @@ def send_mail(book_id, kindle_mail, calibrepath, user_id): if 'mobi' in formats: result = formats['mobi'] elif 'epub' in formats: - # returns None if sucess, otherwise errormessage + # returns None if success, otherwise errormessage return convert_book_format(book_id, calibrepath, u'epub', u'mobi', user_id, kindle_mail) elif 'pdf' in formats: result = formats['pdf'] # worker.get_attachment() @@ -591,32 +595,40 @@ def render_task_status(tasklist): renderedtasklist=list() for task in tasklist: - # localize the task status - if isinstance( task['status'], int ): - if task['status'] == worker.STAT_WAITING: - task['status'] = _('Waiting') - elif task['status'] == worker.STAT_FAIL: - task['status'] = _('Failed') - elif task['status'] == worker.STAT_STARTED: - task['status'] = _('Started') - elif task['status'] == worker.STAT_FINISH_SUCCESS: - task['status'] = _('Finished') - else: - task['status'] = _('Unknown Status') - - # localize the task type - if isinstance( task['taskType'], int ): - if task['taskType'] == worker.TASK_EMAIL: - task['taskMessage'] = _('EMAIL: ') + task['taskMessage'] - elif task['taskType'] == worker.TASK_CONVERT: - task['taskMessage'] = _('CONVERT: ') + task['taskMessage'] - elif task['taskType'] == worker.TASK_UPLOAD: - task['taskMessage'] = _('UPLOAD: ') + task['taskMessage'] - elif task['taskType'] == worker.TASK_CONVERT_ANY: - task['taskMessage'] = _('CONVERT: ') + task['taskMessage'] + if task['user'] == current_user.nickname or current_user.role_admin(): + if task['formStarttime']: + task['starttime'] = format_datetime(task['formStarttime'], format='short', locale=web.get_locale()) + task['formStarttime'] = "" else: - task['taskMessage'] = _('Unknown Task: ') + task['taskMessage'] + if 'starttime' not in task: + task['starttime'] = "" + + # localize the task status + if isinstance( task['stat'], int ): + if task['stat'] == worker.STAT_WAITING: + task['status'] = _(u'Waiting') + elif task['stat'] == worker.STAT_FAIL: + task['status'] = _(u'Failed') + elif task['stat'] == worker.STAT_STARTED: + task['status'] = _(u'Started') + elif task['stat'] == worker.STAT_FINISH_SUCCESS: + task['status'] = _(u'Finished') + else: + task['status'] = _(u'Unknown Status') + + # localize the task type + if isinstance( task['taskType'], int ): + if task['taskType'] == worker.TASK_EMAIL: + task['taskMessage'] = _(u'E-mail: ') + task['taskMess'] + elif task['taskType'] == worker.TASK_CONVERT: + task['taskMessage'] = _(u'Convert: ') + task['taskMess'] + elif task['taskType'] == worker.TASK_UPLOAD: + task['taskMessage'] = _(u'Upload: ') + task['taskMess'] + elif task['taskType'] == worker.TASK_CONVERT_ANY: + task['taskMessage'] = _(u'Convert: ') + task['taskMess'] + else: + task['taskMessage'] = _(u'Unknown Task: ') + task['taskMess'] - renderedtasklist.append(task) + renderedtasklist.append(task) return renderedtasklist diff --git a/cps/web.py b/cps/web.py index 9eaa7a12..e8a8b242 100644 --- a/cps/web.py +++ b/cps/web.py @@ -54,8 +54,9 @@ import tempfile from redirect import redirect_back import time import server -import copy +# import copy from reverseproxy import ReverseProxied + try: from googleapiclient.errors import HttpError except ImportError: @@ -116,44 +117,6 @@ EXTENSIONS_CONVERT = {'pdf', 'epub', 'mobi', 'azw3', 'docx', 'rtf', 'fb2', 'lit' # EXTENSIONS_READER = set(['txt', 'pdf', 'epub', 'zip', 'cbz', 'tar', 'cbt'] + (['rar','cbr'] if rar_support else [])) -'''class ReverseProxied(object): - """Wrap the application in this middleware and configure the - front-end server to add these headers, to let you quietly bind - this to a URL other than / and to an HTTP scheme that is - different than what is used locally. - - Code courtesy of: http://flask.pocoo.org/snippets/35/ - - In nginx: - location /myprefix { - proxy_pass http://127.0.0.1:8083; - proxy_set_header Host $host; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Scheme $scheme; - proxy_set_header X-Script-Name /myprefix; - } - """ - - def __init__(self, application): - self.app = application - - def __call__(self, environ, start_response): - script_name = environ.get('HTTP_X_SCRIPT_NAME', '') - if script_name: - environ['SCRIPT_NAME'] = script_name - path_info = environ.get('PATH_INFO', '') - if path_info and path_info.startswith(script_name): - environ['PATH_INFO'] = path_info[len(script_name):] - - scheme = environ.get('HTTP_X_SCHEME', '') - if scheme: - environ['wsgi.url_scheme'] = scheme - servr = environ.get('HTTP_X_FORWARDED_SERVER', '') - if servr: - environ['HTTP_HOST'] = servr - return self.app(environ, start_response)''' - - # Main code mimetypes.init() mimetypes.add_type('application/xhtml+xml', '.xhtml') @@ -897,14 +860,6 @@ def get_opds_download_link(book_id, book_format): except KeyError: headers["Content-Type"] = "application/octet-stream" return helper.do_download_file(book, book_format, data, headers) - #if config.config_use_google_drive: - # app.logger.info(time.time() - startTime) - # df = gdriveutils.getFileFromEbooksFolder(book.path, data.name + "." + book_format) - # return do_gdrive_download(df, headers) - #else: - # response = make_response(send_from_directory(os.path.join(config.config_calibre_dir, book.path), data.name + "." + book_format)) - # response.headers = headers - # return response @app.route("/ajax/book/") @@ -923,7 +878,7 @@ def get_metadata_calibre_companion(uuid): @login_required def get_email_status_json(): answer=list() - UIanswer = list() + # UIanswer = list() tasks=helper.global_WorkerThread.get_taskstatus() if not current_user.role_admin(): for task in tasks: @@ -945,10 +900,10 @@ def get_email_status_json(): task['starttime'] = "" answer = tasks - UIanswer = copy.deepcopy(answer) - UIanswer = helper.render_task_status(UIanswer) + # UIanswer = copy.deepcopy(answer) + answer = helper.render_task_status(answer) - js=json.dumps(UIanswer) + js=json.dumps(answer) response = make_response(js) response.headers["Content-Type"] = "application/json; charset=utf-8" return response @@ -1734,32 +1689,14 @@ def bookmark(book_id, book_format): def get_tasks_status(): # if current user admin, show all email, otherwise only own emails answer=list() - UIanswer=list() + # UIanswer=list() tasks=helper.global_WorkerThread.get_taskstatus() - if not current_user.role_admin(): - for task in tasks: - if task['user'] == current_user.nickname: - if task['formStarttime']: - task['starttime'] = format_datetime(task['formStarttime'], format='short', locale=get_locale()) - task['formStarttime'] = "" - else: - if 'starttime' not in task: - task['starttime'] = "" - answer.append(task) - else: - for task in tasks: - if task['formStarttime']: - task['starttime'] = format_datetime(task['formStarttime'], format='short', locale=get_locale()) - task['formStarttime'] = "" - else: - if 'starttime' not in task: - task['starttime'] = "" - answer = tasks + # answer = tasks - UIanswer = copy.deepcopy(answer) - UIanswer = helper.render_task_status(UIanswer) + # UIanswer = copy.deepcopy(answer) + answer = helper.render_task_status(tasks) # foreach row format row - return render_title_template('tasks.html', entries=UIanswer, title=_(u"Tasks")) + return render_title_template('tasks.html', entries=answer, title=_(u"Tasks")) @app.route("/admin") diff --git a/cps/worker.py b/cps/worker.py index de891916..23d6beb3 100644 --- a/cps/worker.py +++ b/cps/worker.py @@ -170,11 +170,11 @@ class WorkerThread(threading.Thread): if self.current != self.last: doLock.release() if self.queue[self.current]['taskType'] == TASK_EMAIL: - self.send_raw_email() + self._send_raw_email() if self.queue[self.current]['taskType'] == TASK_CONVERT: - self.convert_any_format() + self._convert_any_format() if self.queue[self.current]['taskType'] == TASK_CONVERT_ANY: - self.convert_any_format() + self._convert_any_format() # TASK_UPLOAD is handled implicitly self.current += 1 else: @@ -190,7 +190,7 @@ class WorkerThread(threading.Thread): else: return "0 %" - def delete_completed_tasks(self): + def _delete_completed_tasks(self): for index, task in reversed(list(enumerate(self.UIqueue))): if task['progress'] == "100 %": # delete tasks @@ -202,31 +202,30 @@ class WorkerThread(threading.Thread): def get_taskstatus(self): if self.current < len(self.queue): - if self.queue[self.current]['status'] == STAT_STARTED: + if self.UIqueue[self.current]['stat'] == STAT_STARTED: if self.queue[self.current]['taskType'] == TASK_EMAIL: self.UIqueue[self.current]['progress'] = self.get_send_status() self.UIqueue[self.current]['runtime'] = self._formatRuntime( datetime.now() - self.queue[self.current]['starttime']) return self.UIqueue - def convert_any_format(self): + def _convert_any_format(self): # convert book, and upload in case of google drive - self.queue[self.current]['status'] = STAT_STARTED - self.UIqueue[self.current]['status'] = STAT_STARTED + self.UIqueue[self.current]['stat'] = STAT_STARTED self.queue[self.current]['starttime'] = datetime.now() self.UIqueue[self.current]['formStarttime'] = self.queue[self.current]['starttime'] curr_task = self.queue[self.current]['taskType'] - filename = self.convert_ebook_format() + filename = self._convert_ebook_format() if filename: if web.ub.config.config_use_google_drive: gd.updateGdriveCalibreFromLocal() if curr_task == TASK_CONVERT: - self.add_email(_(u'Send to Kindle'), self.queue[self.current]['path'], filename, - self.queue[self.current]['settings'], self.queue[self.current]['kindle'], - self.UIqueue[self.current]['user'], _(u"%(book)s", book=self.queue[self.current]['title'])) + self.add_email(self.queue[self.current]['settings']['subject'], self.queue[self.current]['path'], + filename, self.queue[self.current]['settings'], self.queue[self.current]['kindle'], + self.UIqueue[self.current]['user'], self.queue[self.current]['title'], + self.queue[self.current]['settings']['body']) - - def convert_ebook_format(self): + def _convert_ebook_format(self): error_message = None file_path = self.queue[self.current]['file_path'] bookid = self.queue[self.current]['bookid'] @@ -244,11 +243,12 @@ class WorkerThread(threading.Thread): self._handleSuccess() return file_path + format_new_ext else: - web.app.logger.info("Book id %d - target format of %s does not existing. Moving forward with convert.", bookid, format_new_ext) + web.app.logger.info("Book id %d - target format of %s does not exist. Moving forward with convert.", bookid, format_new_ext) # check if converter-executable is existing if not os.path.exists(web.ub.config.config_converterpath): - self._handleError(_(u"Convertertool %(converter)s not found", converter=web.ub.config.config_converterpath)) + # ToDo Text is not translated + self._handleError(u"Convertertool %s not found" % web.ub.config.config_converterpath) return try: @@ -343,35 +343,34 @@ class WorkerThread(threading.Thread): addLock = threading.Lock() addLock.acquire() if self.last >= 20: - self.delete_completed_tasks() + self._delete_completed_tasks() # progress, runtime, and status = 0 self.id += 1 task = TASK_CONVERT_ANY if kindle_mail: task = TASK_CONVERT self.queue.append({'file_path':file_path, 'bookid':bookid, 'starttime': 0, 'kindle': kindle_mail, - 'status': STAT_WAITING, 'taskType': task, 'settings':settings}) - self.UIqueue.append({'user': user_name, 'formStarttime': '', 'progress': " 0 %", 'taskMessage': taskMessage, - 'runtime': '0 s', 'status': STAT_WAITING,'id': self.id, 'taskType': task } ) + 'taskType': task, 'settings':settings}) + self.UIqueue.append({'user': user_name, 'formStarttime': '', 'progress': " 0 %", 'taskMess': taskMessage, + 'runtime': '0 s', 'stat': STAT_WAITING,'id': self.id, 'taskType': task } ) self.last=len(self.queue) addLock.release() - def add_email(self, subject, filepath, attachment, settings, recipient, user_name, taskMessage, - text=_(u'This e-mail has been sent via Calibre-Web.')): + text): # if more than 20 entries in the list, clean the list addLock = threading.Lock() addLock.acquire() if self.last >= 20: - self.delete_completed_tasks() + self._delete_completed_tasks() # progress, runtime, and status = 0 self.id += 1 self.queue.append({'subject':subject, 'attachment':attachment, 'filepath':filepath, 'settings':settings, 'recipent':recipient, 'starttime': 0, - 'status': STAT_WAITING, 'taskType': TASK_EMAIL, 'text':text}) - self.UIqueue.append({'user': user_name, 'formStarttime': '', 'progress': " 0 %", 'taskMessage': taskMessage, - 'runtime': '0 s', 'status': STAT_WAITING,'id': self.id, 'taskType': TASK_EMAIL }) + 'taskType': TASK_EMAIL, 'text':text}) + self.UIqueue.append({'user': user_name, 'formStarttime': '', 'progress': " 0 %", 'taskMess': taskMessage, + 'runtime': '0 s', 'stat': STAT_WAITING,'id': self.id, 'taskType': TASK_EMAIL }) self.last=len(self.queue) addLock.release() @@ -380,22 +379,22 @@ class WorkerThread(threading.Thread): addLock = threading.Lock() addLock.acquire() if self.last >= 20: - self.delete_completed_tasks() + self._delete_completed_tasks() # progress=100%, runtime=0, and status finished self.id += 1 - self.queue.append({'starttime': datetime.now(), 'status': STAT_FINISH_SUCCESS, 'taskType': TASK_UPLOAD}) - self.UIqueue.append({'user': user_name, 'formStarttime': '', 'progress': "100 %", 'taskMessage': taskMessage, - 'runtime': '0 s', 'status': _('Finished'),'id': self.id, 'taskType': TASK_UPLOAD}) + self.queue.append({'starttime': datetime.now(), 'taskType': TASK_UPLOAD}) + self.UIqueue.append({'user': user_name, 'formStarttime': '', 'progress': "100 %", 'taskMess': taskMessage, + 'runtime': '0 s', 'stat': STAT_FINISH_SUCCESS,'id': self.id, 'taskType': TASK_UPLOAD}) self.UIqueue[self.current]['formStarttime'] = self.queue[self.current]['starttime'] self.last=len(self.queue) addLock.release() - def send_raw_email(self): + def _send_raw_email(self): self.queue[self.current]['starttime'] = datetime.now() self.UIqueue[self.current]['formStarttime'] = self.queue[self.current]['starttime'] - self.queue[self.current]['status'] = STAT_STARTED - self.UIqueue[self.current]['status'] = STAT_STARTED + # self.queue[self.current]['status'] = STAT_STARTED + self.UIqueue[self.current]['stat'] = STAT_STARTED obj=self.queue[self.current] # create MIME message msg = MIMEMultipart() @@ -452,7 +451,11 @@ class WorkerThread(threading.Thread): self._handleError(u'Error sending email: ' + e.message) return None except (smtplib.SMTPException) as e: - self._handleError(u'Error sending email: ' + e.smtp_error.replace("\n",'. ')) + if hasattr(e, "smtp_error"): + text = e.smtp_error.replace("\n",'. ') + else: + text = '' + self._handleError(u'Error sending email: ' + text) return None except (socket.error) as e: self._handleError(u'Error sending email: ' + e.strerror) @@ -472,16 +475,16 @@ class WorkerThread(threading.Thread): def _handleError(self, error_message): web.app.logger.error(error_message) - self.queue[self.current]['status'] = STAT_FAIL - self.UIqueue[self.current]['status'] = STAT_FAIL + # self.queue[self.current]['status'] = STAT_FAIL + self.UIqueue[self.current]['stat'] = STAT_FAIL self.UIqueue[self.current]['progress'] = "100 %" self.UIqueue[self.current]['runtime'] = self._formatRuntime( datetime.now() - self.queue[self.current]['starttime']) self.UIqueue[self.current]['message'] = error_message def _handleSuccess(self): - self.queue[self.current]['status'] = STAT_FINISH_SUCCESS - self.UIqueue[self.current]['status'] = STAT_FINISH_SUCCESS + # self.queue[self.current]['status'] = STAT_FINISH_SUCCESS + self.UIqueue[self.current]['stat'] = STAT_FINISH_SUCCESS self.UIqueue[self.current]['progress'] = "100 %" self.UIqueue[self.current]['runtime'] = self._formatRuntime( datetime.now() - self.queue[self.current]['starttime'])