diff --git a/cps/editbooks.py b/cps/editbooks.py index d8e16e4c..dd506fa6 100644 --- a/cps/editbooks.py +++ b/cps/editbooks.py @@ -26,6 +26,7 @@ from datetime import datetime import json from shutil import copyfile from uuid import uuid4 +from markupsafe import escape try: from lxml.html.clean import clean_html except ImportError: @@ -468,7 +469,7 @@ def edit_book_comments(comments, book): comments = clean_html(comments) if len(book.comments): if book.comments[0].text != comments: - book.comments[0].text = clean_html(comments) + book.comments[0].text = comments modif_date = True else: if comments: @@ -663,9 +664,9 @@ def upload_single_file(request, book, book_id): return redirect(url_for('web.show_book', book_id=book.id)) # Queue uploader info - uploadText=_(u"File format %(ext)s added to %(book)s", ext=file_ext.upper(), book=book.title) - WorkerThread.add(current_user.name, TaskUpload( - "" + uploadText + "")) + link = '{}'.format(url_for('web.show_book', book_id=book.id), escape(book.title)) + uploadText=_(u"File format %(ext)s added to %(book)s", ext=file_ext.upper(), book=link) + WorkerThread.add(current_user.name, TaskUpload(uploadText)) return uploader.process( saved_filename, *os.path.splitext(requested_file.filename), @@ -1038,9 +1039,9 @@ def upload(): gdriveutils.updateGdriveCalibreFromLocal() if error: flash(error, category="error") - uploadText=_(u"File %(file)s uploaded", file=title) - WorkerThread.add(current_user.name, TaskUpload( - "" + uploadText + "")) + link = '{}'.format(url_for('web.show_book', book_id=book_id), escape(title)) + uploadText = _(u"File %(file)s uploaded", file=link) + WorkerThread.add(current_user.name, TaskUpload(uploadText)) if len(request.files.getlist("btn-upload")) < 2: if current_user.role_edit() or current_user.role_admin(): diff --git a/cps/helper.py b/cps/helper.py index 860b5bf1..a78b7c21 100644 --- a/cps/helper.py +++ b/cps/helper.py @@ -98,10 +98,10 @@ def convert_book_format(book_id, calibrepath, old_book_format, new_book_format, settings['body'] = _(u'This e-mail has been sent via Calibre-Web.') else: settings = dict() - link = '{}"'.format(url_for('web.show_book', book_id=book.id), escape(book.title)) # prevent xss + link = '{}'.format(url_for('web.show_book', book_id=book.id), escape(book.title)) # prevent xss txt = u"{} -> {}: {}".format( - old_book_format, - new_book_format, + old_book_format.upper(), + new_book_format.upper(), link) settings['old_book_format'] = old_book_format settings['new_book_format'] = new_book_format @@ -216,9 +216,11 @@ def send_mail(book_id, book_format, convert, kindle_mail, calibrepath, user_id): for entry in iter(book.data): if entry.format.upper() == book_format.upper(): converted_file_name = entry.name + '.' + book_format.lower() + link = '{}'.format(url_for('web.show_book', book_id=book_id), escape(book.title)) + EmailText = _(u"%(book)s send to Kindle", book=link) WorkerThread.add(user_id, TaskEmail(_(u"Send to Kindle"), book.path, converted_file_name, config.get_mail_settings(), kindle_mail, - _(u"E-mail: %(book)s", book=book.title), _(u'This e-mail has been sent via Calibre-Web.'))) + EmailText, _(u'This e-mail has been sent via Calibre-Web.'))) return return _(u"The requested file could not be read. Maybe wrong permissions?") diff --git a/cps/services/gmail.py b/cps/services/gmail.py index 9380121a..baada1f8 100644 --- a/cps/services/gmail.py +++ b/cps/services/gmail.py @@ -61,7 +61,7 @@ def get_user_info(credentials): return user_info.get('email', "") def send_messsage(token, msg): - log.debug("Start sending email via Gmail") + log.debug("Start sending e-mail via Gmail") creds = Credentials( token=token['token'], refresh_token=token['refresh_token'], @@ -80,4 +80,4 @@ def send_messsage(token, msg): body = {'raw': raw} (service.users().messages().send(userId='me', body=body).execute()) - log.debug("Email send successfully via Gmail") + log.debug("E-mail send successfully via Gmail") diff --git a/cps/static/js/table.js b/cps/static/js/table.js index b2a95bc9..a55ec5d1 100644 --- a/cps/static/js/table.js +++ b/cps/static/js/table.js @@ -36,10 +36,10 @@ $(function() { async: true, timeout: 900, success: function (data) { - $('#table').bootstrapTable("load", data); + $('#tasktable').bootstrapTable("load", data); } }); - }, 2000); + }, 1000); } $("#books-table").on("check.bs.table check-all.bs.table uncheck.bs.table uncheck-all.bs.table", diff --git a/cps/tasks/convert.py b/cps/tasks/convert.py index 2e2a51d8..56cc7076 100644 --- a/cps/tasks/convert.py +++ b/cps/tasks/convert.py @@ -5,6 +5,7 @@ import re from glob import glob from shutil import copyfile +from markupsafe import escape from sqlalchemy.exc import SQLAlchemyError @@ -13,6 +14,7 @@ from cps import db from cps import logger, config from cps.subproc_wrapper import process_open from flask_babel import gettext as _ +from flask import url_for from cps.tasks.mail import TaskEmail from cps import gdriveutils @@ -24,6 +26,7 @@ class TaskConvert(CalibreTask): super(TaskConvert, self).__init__(taskMessage) self.file_path = file_path self.bookid = bookid + self.title = "" self.settings = settings self.kindle_mail = kindle_mail self.user = user @@ -35,6 +38,7 @@ class TaskConvert(CalibreTask): if config.config_use_google_drive: worker_db = db.CalibreDB(expire_on_commit=False) cur_book = worker_db.get_book(self.bookid) + self.title = cur_book.title data = worker_db.get_book_format(self.bookid, self.settings['old_book_format']) df = gdriveutils.getFileFromEbooksFolder(cur_book.path, data.name + "." + self.settings['old_book_format'].lower()) @@ -66,12 +70,13 @@ class TaskConvert(CalibreTask): # if we're sending to kindle after converting, create a one-off task and run it immediately # todo: figure out how to incorporate this into the progress try: + EmailText = _(u"%(book)s send to Kindle", book=escape(self.title)) worker_thread.add(self.user, TaskEmail(self.settings['subject'], self.results["path"], filename, self.settings, self.kindle_mail, - self.settings['subject'], + EmailText, self.settings['body'], internal=True) ) @@ -93,8 +98,9 @@ class TaskConvert(CalibreTask): local_db.get_book_format(self.bookid, self.settings['new_book_format']): log.info("Book id %d already converted to %s", book_id, format_new_ext) cur_book = local_db.get_book(book_id) + self.title = cur_book.title self.results['path'] = file_path - self.results['title'] = cur_book.title + self.results['title'] = self.title self._handleSuccess() local_db.session.close() return os.path.basename(file_path + format_new_ext) @@ -130,7 +136,8 @@ class TaskConvert(CalibreTask): local_db.session.close() return self.results['path'] = cur_book.path - self.results['title'] = cur_book.title + self.title = cur_book.title + self.results['title'] = self.title if not config.config_use_google_drive: self._handleSuccess() return os.path.basename(file_path + format_new_ext) diff --git a/cps/tasks/mail.py b/cps/tasks/mail.py index f19231ec..292114d5 100644 --- a/cps/tasks/mail.py +++ b/cps/tasks/mail.py @@ -143,7 +143,7 @@ class TaskEmail(CalibreTask): self.send_gmail_email(msg) except MemoryError as e: log.debug_or_exception(e) - self._handleError(u'MemoryError sending email: {}'.format(str(e))) + self._handleError(u'MemoryError sending e-mail: {}'.format(str(e))) except (smtplib.SMTPException, smtplib.SMTPAuthenticationError) as e: log.debug_or_exception(e) if hasattr(e, "smtp_error"): @@ -154,13 +154,13 @@ class TaskEmail(CalibreTask): text = '\n'.join(e.args) else: text = '' - self._handleError(u'Smtplib Error sending email: {}'.format(text)) + self._handleError(u'Smtplib Error sending e-mail: {}'.format(text)) except socket.error as e: log.debug_or_exception(e) - self._handleError(u'Socket Error sending email: {}'.format(e.strerror)) + self._handleError(u'Socket Error sending e-mail: {}'.format(e.strerror)) except Exception as ex: log.debug_or_exception(ex) - self._handleError(u'Error sending email: {}'.format(ex)) + self._handleError(u'Error sending e-mail: {}'.format(ex)) def send_standard_email(self, msg): @@ -173,7 +173,7 @@ class TaskEmail(CalibreTask): org_smtpstderr = smtplib.stderr smtplib.stderr = logger.StderrLogger('worker.smtp') - log.debug("Start sending email") + log.debug("Start sending e-mail") if use_ssl == 2: self.asyncSMTP = EmailSSL(self.settings["mail_server"], self.settings["mail_port"], timeout=timeout) @@ -196,7 +196,7 @@ class TaskEmail(CalibreTask): self.asyncSMTP.sendmail(self.settings["mail_from"], self.recipent, fp.getvalue()) self.asyncSMTP.quit() self._handleSuccess() - log.debug("Email send successfully") + log.debug("E-mail send successfully") if sys.version_info < (3, 0): smtplib.stderr = org_smtpstderr @@ -258,7 +258,7 @@ class TaskEmail(CalibreTask): @property def name(self): - return "Email" + return "E-mail" def __str__(self): return "{}, {}".format(self.name, self.subject) diff --git a/test/Calibre-Web TestSummary_Linux.html b/test/Calibre-Web TestSummary_Linux.html index 101769f7..5175c380 100644 --- a/test/Calibre-Web TestSummary_Linux.html +++ b/test/Calibre-Web TestSummary_Linux.html @@ -37,20 +37,20 @@
Start Time: 2021-07-30 11:44:06
+Start Time: 2021-08-27 20:45:00
Stop Time: 2021-07-30 15:14:26
+Stop Time: 2021-08-28 00:16:11
Duration: 2h 45 min
+Duration: 2h 48 min
Traceback (most recent call last): + File "/home/ozzie/Development/calibre-web-test/test/test_ebook_convert.py", line 202, in test_convert_email + self.assertEqual(ret[-2]['result'], 'Finished') +IndexError: list index out of range+
Traceback (most recent call last): + File "/home/ozzie/Development/calibre-web-test/test/test_ebook_convert.py", line 249, in test_convert_failed_and_email + self.assertEqual(ret[-1]['result'], 'Failed') +IndexError: list index out of range+
Traceback (most recent call last): + File "/home/ozzie/Development/calibre-web-test/test/test_ebook_convert.py", line 337, in test_convert_only + self.assertEqual(ret_orig[-6]['result'], 'Finished') +IndexError: list index out of range+
Traceback (most recent call last): + File "/home/ozzie/Development/calibre-web-test/test/test_ebook_convert.py", line 164, in test_convert_parameter + self.assertEqual(1, task_len) +AssertionError: 1 != 0+
Traceback (most recent call last): + File "/home/ozzie/Development/calibre-web-test/test/test_ebook_convert.py", line 141, in test_convert_wrong_excecutable + self.assertEqual(2, task_len) +AssertionError: 2 != 0+
Traceback (most recent call last): + File "/home/ozzie/Development/calibre-web-test/test/test_ebook_convert.py", line 457, in test_email_failed + self.assertEqual(ret[-1]['result'], 'Failed') +IndexError: list index out of range+
Traceback (most recent call last): + File "/home/ozzie/Development/calibre-web-test/test/test_ebook_convert.py", line 416, in test_email_only + self.assertEqual(ret[-1]['result'], 'Finished') +IndexError: list index out of range+
Traceback (most recent call last): + File "/home/ozzie/Development/calibre-web-test/test/test_ebook_convert.py", line 500, in test_ssl_smtp_setup_error + self.assertEqual(ret[-1]['result'], 'Failed') +IndexError: list index out of range+
Traceback (most recent call last): + File "/home/ozzie/Development/calibre-web-test/test/test_ebook_convert.py", line 480, in test_starttls_smtp_setup_error + self.assertEqual(ret[-1]['result'], 'Failed') +IndexError: list index out of range+
Traceback (most recent call last): + File "/home/ozzie/Development/calibre-web-test/test/test_ebook_convert_gdrive.py", line 193, in test_convert_email + self.assertTrue("Email" in ret[-1]['task']) +IndexError: list index out of range+
Traceback (most recent call last): + File "/home/ozzie/Development/calibre-web-test/test/test_ebook_convert_gdrive.py", line 234, in test_convert_failed_and_email + self.assertEqual(ret[-1]['result'], 'Failed') +IndexError: list index out of range+
Traceback (most recent call last): + File "/home/ozzie/Development/calibre-web-test/test/test_ebook_convert_gdrive.py", line 324, in test_convert_only + self.assertEqual(ret[-6]['result'], 'Finished') +IndexError: list index out of range+
Traceback (most recent call last): + File "/home/ozzie/Development/calibre-web-test/test/test_ebook_convert_gdrive.py", line 157, in test_convert_parameter + self.assertEqual(task_len, 1) +AssertionError: 0 != 1+
Traceback (most recent call last): + File "/home/ozzie/Development/calibre-web-test/test/test_ebook_convert_gdrive.py", line 430, in test_email_failed + self.assertEqual(ret[-1]['result'], 'Failed') +IndexError: list index out of range+
Traceback (most recent call last): + File "/home/ozzie/Development/calibre-web-test/test/test_ebook_convert_gdrive.py", line 389, in test_email_only + self.assertEqual(ret[-1]['result'], 'Finished') +IndexError: list index out of range+
Traceback (most recent call last): + File "/home/ozzie/Development/calibre-web-test/test/test_ebook_convert_kepubify.py", line 126, in test_convert_only + self.assertEqual(ret[-1]['result'], 'Finished') +IndexError: list index out of range+
Traceback (most recent call last): + File "/home/ozzie/Development/calibre-web-test/test/test_ebook_convert_kepubify_gdrive.py", line 174, in test_convert_only + self.assertEqual(ret[-1]['result'], 'Finished') +IndexError: list index out of range+
Traceback (most recent call last): + File "/home/ozzie/Development/calibre-web-test/venv/lib/python3.8/site-packages/selenium/webdriver/remote/switch_to.py", line 82, in frame + frame_reference = self._driver.find_element(By.ID, frame_reference) + File "/home/ozzie/Development/calibre-web-test/venv/lib/python3.8/site-packages/selenium/webdriver/remote/webdriver.py", line 976, in find_element + return self.execute(Command.FIND_ELEMENT, { + File "/home/ozzie/Development/calibre-web-test/venv/lib/python3.8/site-packages/selenium/webdriver/remote/webdriver.py", line 321, in execute + self.error_handler.check_response(response) + File "/home/ozzie/Development/calibre-web-test/venv/lib/python3.8/site-packages/selenium/webdriver/remote/errorhandler.py", line 242, in check_response + raise exception_class(message, screen, stacktrace) +selenium.common.exceptions.NoSuchElementException: Message: Unable to locate element: [id="description_ifr"] -+During handling of the above exception, another exception occurred: + +Traceback (most recent call last): + File "/home/ozzie/Development/calibre-web-test/venv/lib/python3.8/site-packages/selenium/webdriver/remote/switch_to.py", line 85, in frame + frame_reference = self._driver.find_element(By.NAME, frame_reference) + File "/home/ozzie/Development/calibre-web-test/venv/lib/python3.8/site-packages/selenium/webdriver/remote/webdriver.py", line 976, in find_element + return self.execute(Command.FIND_ELEMENT, { + File "/home/ozzie/Development/calibre-web-test/venv/lib/python3.8/site-packages/selenium/webdriver/remote/webdriver.py", line 321, in execute + self.error_handler.check_response(response) + File "/home/ozzie/Development/calibre-web-test/venv/lib/python3.8/site-packages/selenium/webdriver/remote/errorhandler.py", line 242, in check_response + raise exception_class(message, screen, stacktrace) +selenium.common.exceptions.NoSuchElementException: Message: Unable to locate element: [name="description_ifr"] + + +During handling of the above exception, another exception occurred: + +Traceback (most recent call last): + File "/home/ozzie/Development/calibre-web-test/test/test_edit_additional_books.py", line 673, in test_xss_comment_edit + self.edit_book(1, content={'description': ''}) + File "/home/ozzie/Development/calibre-web-test/test/helper_ui.py", line 1608, in edit_book + cls.driver.switch_to.frame("description_ifr") + File "/home/ozzie/Development/calibre-web-test/venv/lib/python3.8/site-packages/selenium/webdriver/remote/switch_to.py", line 87, in frame + raise NoSuchFrameException(frame_reference) +selenium.common.exceptions.NoSuchFrameException: Message: description_ifr + + + + + + + + + ++ + + + + ++ +TestEditAdditionalBooks - test_xss_custom_comment_edit++ ++ ERROR ++ +++ + +++ +Traceback (most recent call last): + File "/home/ozzie/Development/calibre-web-test/test/test_edit_additional_books.py", line 687, in test_xss_custom_comment_edit + self.edit_book(1, custom_content={'Custom Comment 人物': ''}) + File "/home/ozzie/Development/calibre-web-test/test/helper_ui.py", line 1634, in edit_book + submit.click() +AttributeError: 'bool' object has no attribute 'click'+TestEditBooks 35 -34 -0 +33 +1 0 1 @@ -859,11 +1291,32 @@ - + @@ -1270,11 +1723,11 @@ - - TestEditBooks - test_edit_commentsPASS ++ + FAIL ++ +++ + +++ +Traceback (most recent call last): + File "/home/ozzie/Development/calibre-web-test/test/test_edit_books.py", line 428, in test_edit_comments + self.assertEqual('', values['comment']) +AssertionError: '' != 'bogomirä 人物' ++ bogomirä 人物++ TestEditBooksOnGdrive 20 -20 -0 +19 +1 0 0 @@ -1311,11 +1764,32 @@ - + @@ -1465,12 +1939,12 @@ - - TestEditBooksOnGdrive - test_edit_commentsPASS ++ + FAIL ++ +++ + +++ +Traceback (most recent call last): + File "/home/ozzie/Development/calibre-web-test/test/test_edit_ebooks_gdrive.py", line 639, in test_edit_comments + self.assertEqual('', values['comment']) +AssertionError: '' != 'bogomirä 人物' ++ bogomirä 人物++ TestSTARTTLS 3 -3 -0 +1 0 +2 0 Detail @@ -1479,20 +1953,60 @@ - + - - TestSTARTTLS - test_STARTTLSPASS ++ + ERROR ++ +++ + +++ +Traceback (most recent call last): + File "/home/ozzie/Development/calibre-web-test/test/test_email_STARTTLS.py", line 79, in test_STARTTLS + self.assertEqual(ret[-1]['result'], 'Finished') +IndexError: list index out of range++ @@ -1507,12 +2021,12 @@ - - TestSTARTTLS - test_STARTTLS_SSL_setup_errorPASS ++ + ERROR ++ +++ + +++ +Traceback (most recent call last): + File "/home/ozzie/Development/calibre-web-test/test/test_email_STARTTLS.py", line 100, in test_STARTTLS_SSL_setup_error + self.assertEqual(ret[-1]['result'], 'Failed') +IndexError: list index out of range++ TestSSL 6 -6 -0 +1 0 +5 0 Detail @@ -1521,20 +2035,60 @@ - + - - TestSSL - test_SSL_None_setup_errorPASS ++ + ERROR ++ +++ + +++ +Traceback (most recent call last): + File "/home/ozzie/Development/calibre-web-test/test/test_email_ssl.py", line 122, in test_SSL_None_setup_error + self.assertEqual('Failed', ret[-1]['result']) +IndexError: list index out of range++ @@ -1548,29 +2102,159 @@ - - TestSSL - test_SSL_STARTTLS_setup_errorPASS ++ + ERROR ++ +++ + +++ +Traceback (most recent call last): + File "/home/ozzie/Development/calibre-web-test/test/test_email_ssl.py", line 101, in test_SSL_STARTTLS_setup_error + self.assertEqual(ret[-1]['result'], 'Failed') +IndexError: list index out of range++ - - TestSSL - test_SSL_non_admin_userPASS ++ + ERROR ++ +++ + +++ +Traceback (most recent call last): + File "/home/ozzie/Development/calibre-web-test/test/test_email_ssl.py", line 195, in test_SSL_non_admin_user + self.assertEqual(ret[-1]['result'], 'Finished') +IndexError: list index out of range++ - - TestSSL - test_SSL_onlyPASS ++ + ERROR ++ +++ + +++ +Traceback (most recent call last): + File "/home/ozzie/Development/calibre-web-test/test/test_email_ssl.py", line 64, in test_SSL_only + self.setup_server(False, {'mail_use_ssl': 'SSL/TLS'}) + File "/home/ozzie/Development/calibre-web-test/test/helper_ui.py", line 674, in setup_server + select = Select(cls.driver.find_element_by_id(key)) + File "/home/ozzie/Development/calibre-web-test/venv/lib/python3.8/site-packages/selenium/webdriver/remote/webdriver.py", line 360, in find_element_by_id + return self.find_element(by=By.ID, value=id_) + File "/home/ozzie/Development/calibre-web-test/venv/lib/python3.8/site-packages/selenium/webdriver/remote/webdriver.py", line 976, in find_element + return self.execute(Command.FIND_ELEMENT, { + File "/home/ozzie/Development/calibre-web-test/venv/lib/python3.8/site-packages/selenium/webdriver/remote/webdriver.py", line 321, in execute + self.error_handler.check_response(response) + File "/home/ozzie/Development/calibre-web-test/venv/lib/python3.8/site-packages/selenium/webdriver/remote/errorhandler.py", line 242, in check_response + raise exception_class(message, screen, stacktrace) +selenium.common.exceptions.NoSuchElementException: Message: Unable to locate element: [id="mail_use_ssl"]++ + + + + + - TestSSL - test_email_limitPASS ++ ++ ERROR ++ +++ + +++ +Traceback (most recent call last): + File "/home/ozzie/Development/calibre-web-test/test/test_email_ssl.py", line 135, in test_email_limit + self.fill_basic_config({'config_uploading': 1}) + File "/home/ozzie/Development/calibre-web-test/test/helper_ui.py", line 342, in fill_basic_config + cls._fill_basic_config(elements) + File "/home/ozzie/Development/calibre-web-test/test/helper_ui.py", line 252, in _fill_basic_config + WebDriverWait(cls.driver, 5).until(EC.presence_of_element_located((By.ID, "config_port"))) + File "/home/ozzie/Development/calibre-web-test/venv/lib/python3.8/site-packages/selenium/webdriver/support/wait.py", line 80, in until + raise TimeoutException(message, screen, stacktrace) +selenium.common.exceptions.TimeoutException: Message:++ + + + +_ErrorHolder +1 +0 +0 +1 +0 ++ Detail + ++ @@ -1584,13 +2268,13 @@+ +tearDownClass (test_email_ssl)++ + ERROR ++ +++ + +++ +Traceback (most recent call last): + File "/home/ozzie/Development/calibre-web-test/test/test_email_ssl.py", line 52, in tearDownClass + cls.stop_calibre_web() + File "/home/ozzie/Development/calibre-web-test/test/helper_ui.py", line 430, in stop_calibre_web + cls.driver.find_element_by_id('admin_stop').click() + File "/home/ozzie/Development/calibre-web-test/venv/lib/python3.8/site-packages/selenium/webdriver/remote/webdriver.py", line 360, in find_element_by_id + return self.find_element(by=By.ID, value=id_) + File "/home/ozzie/Development/calibre-web-test/venv/lib/python3.8/site-packages/selenium/webdriver/remote/webdriver.py", line 976, in find_element + return self.execute(Command.FIND_ELEMENT, { + File "/home/ozzie/Development/calibre-web-test/venv/lib/python3.8/site-packages/selenium/webdriver/remote/webdriver.py", line 321, in execute + self.error_handler.check_response(response) + File "/home/ozzie/Development/calibre-web-test/venv/lib/python3.8/site-packages/selenium/webdriver/remote/errorhandler.py", line 242, in check_response + raise exception_class(message, screen, stacktrace) +selenium.common.exceptions.NoSuchElementException: Message: Unable to locate element: [id="admin_stop"]+0 0 - Detail + Detail