From 38fa9ce206e8f1e59c111a11543e76bc7dc9d9cc Mon Sep 17 00:00:00 2001 From: OzzieIsaacs Date: Fri, 19 May 2017 20:36:58 +0200 Subject: [PATCH 01/11] At deleting a book, the book is also deleted from all Shelfs, Download list and read list (#192) --- cps/web.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/cps/web.py b/cps/web.py index cd9d9386..2f4b1525 100755 --- a/cps/web.py +++ b/cps/web.py @@ -1290,6 +1290,12 @@ def delete_book(book_id): if current_user.role_delete_books(): book = db.session.query(db.Books).filter(db.Books.id == book_id).first() if book: + # delete book from Shelfs, Downloads, Read list + ub.session.query(ub.BookShelf).filter(ub.BookShelf.book_id == book_id).delete() + ub.session.query(ub.ReadBook).filter(ub.ReadBook.book_id == book_id).delete() + ub.session.query(ub.Downloads).filter(ub.Downloads.book_id == book_id).delete() + ub.session.commit() + if config.config_use_google_drive: helper.delete_book_gdrive(book) # ToDo really delete file else: From 5f4d8398950c5b51ad2da3d8ca17c9ec1e454d4a Mon Sep 17 00:00:00 2001 From: OzzieIsaacs Date: Fri, 19 May 2017 21:30:39 +0200 Subject: [PATCH 02/11] Better output messages for failed kindlegen conversions (fix #191) --- cps/helper.py | 43 ++++++++++++++++++++++++++++--------------- 1 file changed, 28 insertions(+), 15 deletions(-) diff --git a/cps/helper.py b/cps/helper.py index eccbcd23..2d5dfa7e 100755 --- a/cps/helper.py +++ b/cps/helper.py @@ -52,6 +52,9 @@ except Exception as e: global_task = None updater_thread = None +RET_SUCCESS = 1 +RET_FAIL = 0 + def update_download(book_id, user_id): check = ub.session.query(ub.Downloads).filter(ub.Downloads.user_id == user_id).filter(ub.Downloads.book_id == book_id).first() @@ -63,6 +66,7 @@ def update_download(book_id, user_id): def make_mobi(book_id, calibrepath): + error_message = None vendorpath = os.path.join(os.path.normpath(os.path.dirname(os.path.realpath(__file__)) + os.sep + "../vendor" + os.sep)) if sys.platform == "win32": @@ -70,13 +74,15 @@ def make_mobi(book_id, calibrepath): else: kindlegen = (os.path.join(vendorpath, u"kindlegen")).encode(sys.getfilesystemencoding()) if not os.path.exists(kindlegen): - app.logger.error("make_mobi: kindlegen binary not found in: %s" % kindlegen) - return None + error_message = _(u"kindlegen binary %(kindlepath)s not found", kindlepath=kindlegen) + app.logger.error("make_mobi: " + error_message) + return error_message, RET_FAIL book = db.session.query(db.Books).filter(db.Books.id == book_id).first() data = db.session.query(db.Data).filter(db.Data.book == book.id).filter(db.Data.format == 'EPUB').first() if not data: - app.logger.error("make_mobi: epub format not found for book id: %d" % book_id) - return None + error_message = _(u"epub format not found for book id: %(book)d", book=book_id) + app.logger.error("make_mobi: " + error_message) + return error_message, RET_FAIL file_path = os.path.join(calibrepath, book.path, data.name) if os.path.exists(file_path + u".epub"): @@ -88,6 +94,15 @@ def make_mobi(book_id, calibrepath): if nextline == '' and p.poll() is not None: break if nextline != "\r\n": + # Format of error message (kindlegen translates its output texts): + # Error(prcgen):E23006: Language not recognized in metadata.The dc:Language field is mandatory.Aborting. + conv_error=re.search(".*\(.*\):(E\d+):\s(.*)",nextline) + # If error occoures, log in every case + if conv_error: + error_message = _(u"Kindlegen failed with Error %(error)s. Message: %(message)s", + error=conv_error.group(1), message=conv_error.group(2).decode('utf-8')) + app.logger.info("make_mobi: " + error_message) + app.logger.info(nextline.strip('\r\n')) app.logger.debug(nextline.strip('\r\n')) check = p.returncode @@ -99,13 +114,13 @@ def make_mobi(book_id, calibrepath): uncompressed_size=os.path.getsize(file_path + ".mobi") )) db.session.commit() - return file_path + ".mobi" + return file_path + ".mobi", RET_SUCCESS else: app.logger.error("make_mobi: kindlegen failed with error while converting book") - return None + return error_message, RET_FAIL else: - app.logger.error("make_mobie: epub not found: %s.epub" % file_path) - return None + app.logger.error("make_mobi: epub not found: %s.epub" % file_path) + return None, RET_FAIL class StderrLogger(object): @@ -204,13 +219,11 @@ def send_mail(book_id, kindle_mail, calibrepath): if 'mobi' in formats: msg.attach(get_attachment(formats['mobi'])) elif 'epub' in formats: - filepath = make_mobi(book.id, calibrepath) - if filepath is not None: - msg.attach(get_attachment(filepath)) - elif filepath is None: - return _("Could not convert epub to mobi") - elif 'pdf' in formats: - msg.attach(get_attachment(formats['pdf'])) + data, resultCode = make_mobi(book.id, calibrepath) + if resultCode == RET_SUCCESS: + msg.attach(get_attachment(data)) + else: + return data #_("Could not convert epub to mobi") elif 'pdf' in formats: msg.attach(get_attachment(formats['pdf'])) else: From 26f314d3710dcf6c625101c76d9c4689447fc0f6 Mon Sep 17 00:00:00 2001 From: nanu-c Date: Mon, 22 May 2017 22:54:53 +0200 Subject: [PATCH 03/11] support int custom fields --- cps/db.py | 11 +++++++++-- cps/templates/book_edit.html | 19 ++++++++++++------- cps/web.py | 16 ++++++++++++++++ 3 files changed, 37 insertions(+), 9 deletions(-) diff --git a/cps/db.py b/cps/db.py index 704789b6..1e418593 100755 --- a/cps/db.py +++ b/cps/db.py @@ -11,7 +11,7 @@ from ub import config import ub session = None -cc_exceptions = ['datetime', 'int', 'comments', 'float', 'composite', 'series'] +cc_exceptions = ['datetime', 'comments', 'float', 'composite', 'series'] cc_classes = None engine = None @@ -335,11 +335,18 @@ def setup_db(): primary_key=True) ) cc_ids.append([row.id, row.datatype]) + import sys + print >>sys.stderr,row.datatype if row.datatype == 'bool': ccdict = {'__tablename__': 'custom_column_' + str(row.id), 'id': Column(Integer, primary_key=True), 'book': Column(Integer, ForeignKey('books.id')), 'value': Column(Boolean)} + elif row.datatype == 'int': + ccdict = {'__tablename__': 'custom_column_' + str(row.id), + 'id': Column(Integer, primary_key=True), + 'book': Column(Integer, ForeignKey('books.id')), + 'value': Column(Integer)} else: ccdict = {'__tablename__': 'custom_column_' + str(row.id), 'id': Column(Integer, primary_key=True), @@ -347,7 +354,7 @@ def setup_db(): cc_classes[row.id] = type('Custom_Column_' + str(row.id), (Base,), ccdict) for cc_id in cc_ids: - if cc_id[1] == 'bool': + if (cc_id[1] == 'bool') or (cc_id[1] == 'int'): setattr(Books, 'custom_column_' + str(cc_id[0]), relationship(cc_classes[cc_id[0]], primaryjoin=( Books.id == cc_classes[cc_id[0]].book), diff --git a/cps/templates/book_edit.html b/cps/templates/book_edit.html index 5b44ac07..a24f74b5 100644 --- a/cps/templates/book_edit.html +++ b/cps/templates/book_edit.html @@ -51,12 +51,12 @@ - +
- + {% if cc|length > 0 %} {% for c in cc %}
@@ -68,6 +68,11 @@ {% endif %} + + {% if c.datatype == 'int' %} + + {% endif %} + {% if c.datatype in ['text', 'series'] and not c.is_multiple %} 0 %} @@ -80,12 +85,12 @@ {% if book['custom_column_' ~ c.id]|length > 0 %} value="{% for column in book['custom_column_' ~ c.id] %}{{ column.value.strip() }}{% if not loop.last %}, {% endif %}{% endfor %}"{% endif %}> {% endif %} - + {% if c.datatype == 'enumeration' %} {{_('view book after edit')}} diff --git a/cps/web.py b/cps/web.py index 2f4b1525..e13ecca0 100755 --- a/cps/web.py +++ b/cps/web.py @@ -2589,6 +2589,22 @@ def edit_book(book_id): cc_class = db.cc_classes[c.id] new_cc = cc_class(value=to_save[cc_string], book=book_id) db.session.add(new_cc) + elif c.datatype == 'int': + if to_save[cc_string] == 'None': + to_save[cc_string] = None + if to_save[cc_string] != cc_db_value: + if cc_db_value is not None: + if to_save[cc_string] is not None: + setattr(getattr(book, cc_string)[0], 'value', to_save[cc_string]) + else: + del_cc = getattr(book, cc_string)[0] + getattr(book, cc_string).remove(del_cc) + db.session.delete(del_cc) + else: + cc_class = db.cc_classes[c.id] + new_cc = cc_class(value=to_save[cc_string], book=book_id) + db.session.add(new_cc) + else: if c.datatype == 'rating': to_save[cc_string] = str(int(float(to_save[cc_string]) * 2)) From 3acf80c42b234230e49a26ecc52cd8ea2ea70e0e Mon Sep 17 00:00:00 2001 From: nanu-c Date: Mon, 22 May 2017 23:06:55 +0200 Subject: [PATCH 04/11] remove debuggingtool --- cps/db.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/cps/db.py b/cps/db.py index 1e418593..f79a1206 100755 --- a/cps/db.py +++ b/cps/db.py @@ -335,8 +335,6 @@ def setup_db(): primary_key=True) ) cc_ids.append([row.id, row.datatype]) - import sys - print >>sys.stderr,row.datatype if row.datatype == 'bool': ccdict = {'__tablename__': 'custom_column_' + str(row.id), 'id': Column(Integer, primary_key=True), From 1366b36c32fe721c4336b0b0e4685870f97e03bd Mon Sep 17 00:00:00 2001 From: OzzieIsaacs Date: Thu, 25 May 2017 08:20:19 +0200 Subject: [PATCH 05/11] Added integer-field to supported custom colums --- cps/templates/book_edit.html | 2 +- cps/web.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cps/templates/book_edit.html b/cps/templates/book_edit.html index a24f74b5..6651ce22 100644 --- a/cps/templates/book_edit.html +++ b/cps/templates/book_edit.html @@ -70,7 +70,7 @@ {% endif %} {% if c.datatype == 'int' %} - + {% endif %} {% if c.datatype in ['text', 'series'] and not c.is_multiple %} diff --git a/cps/web.py b/cps/web.py index e13ecca0..6f5dd8f9 100755 --- a/cps/web.py +++ b/cps/web.py @@ -1313,7 +1313,7 @@ def delete_book(book_id): cc_string = "custom_column_" + str(c.id) if not c.is_multiple: if len(getattr(book, cc_string)) > 0: - if c.datatype == 'bool': + if c.datatype == 'bool' or c.datatype == 'integer': del_cc = getattr(book, cc_string)[0] getattr(book, cc_string).remove(del_cc) db.session.delete(del_cc) From 7ab8a5877be62e0dc3c8ed87f82fdabccc5660bb Mon Sep 17 00:00:00 2001 From: OzzieIsaacs Date: Thu, 25 May 2017 08:46:33 +0200 Subject: [PATCH 06/11] read PDF/TXT without temporary files (#197) --- cps/templates/readpdf.html | 2 +- cps/templates/readtxt.html | 2 +- cps/web.py | 32 ++++++++++++++++++++------------ 3 files changed, 22 insertions(+), 14 deletions(-) diff --git a/cps/templates/readpdf.html b/cps/templates/readpdf.html index a7a79dbb..68b19d6e 100644 --- a/cps/templates/readpdf.html +++ b/cps/templates/readpdf.html @@ -48,7 +48,7 @@ See https://github.com/adobe-type-tools/cmap-resources