diff --git a/SECURITY.md b/SECURITY.md index a7113785..bbaad7c4 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -27,3 +27,6 @@ To receive fixes for security vulnerabilities it is required to always upgrade t | V 0.6.14|Cross-Site Scripting vulnerability on typeahead inputs. Thanks to @notdodo|| +## Staement regarding Log4j (CVE-2021-44228 and related) + +Calibre-web is not affected by bugs related to Log4j. Calibre-Web is a python program, therefore not using Java, and not using the Java logging feature log4j. diff --git a/cps/admin.py b/cps/admin.py index 2c32431f..04d9138f 100644 --- a/cps/admin.py +++ b/cps/admin.py @@ -590,6 +590,8 @@ def load_dialogtexts(element_id): texts["main"] = _('Are you sure you want to change shelf sync behavior for the selected user(s)?') elif element_id == "db_submit": texts["main"] = _('Are you sure you want to change Calibre library location?') + elif element_id == "btnfullsync": + texts["main"] = _("Are you sure you want delete Calibre-Web's sync database to force a full sync with your Kobo Reader?") return json.dumps(texts) @@ -889,10 +891,18 @@ def list_restriction(res_type, user_id): else: json_dumps = "" js = json.dumps(json_dumps) - response = make_response(js) #.replace("'", '"') + response = make_response(js) response.headers["Content-Type"] = "application/json; charset=utf-8" return response +@admi.route("/ajax/fullsync") +@login_required +def ajax_fullsync(): + count = ub.session.query(ub.KoboSyncedBooks).filter(current_user.id == ub.KoboSyncedBooks.user_id).delete() + message = _("{} sync entries deleted").format(count) + ub.session_commit(message) + return Response(json.dumps([{"type": "success", "message": message}]), mimetype='application/json') + @admi.route("/ajax/pathchooser/") @login_required @@ -1189,13 +1199,13 @@ def _db_configuration_update_helper(): # if db changed -> delete shelfs, delete download books, delete read books, kobo sync... ub.session.query(ub.Downloads).delete() ub.session.query(ub.ArchivedBook).delete() - ub.session.query(ub.ArchivedBook).delete() ub.session.query(ub.ReadBook).delete() ub.session.query(ub.BookShelf).delete() ub.session.query(ub.Bookmark).delete() ub.session.query(ub.KoboReadingState).delete() ub.session.query(ub.KoboStatistics).delete() ub.session.query(ub.KoboSyncedBooks).delete() + ub.session_commit() _config_string(to_save, "config_calibre_dir") calibre_db.update_config(config) if not os.access(os.path.join(config.config_calibre_dir, "metadata.db"), os.W_OK): diff --git a/cps/editbooks.py b/cps/editbooks.py index 448a52bd..8bbe8208 100644 --- a/cps/editbooks.py +++ b/cps/editbooks.py @@ -241,14 +241,14 @@ def modify_identifiers(input_identifiers, db_identifiers, db_session): @editbook.route("/ajax/delete/") @login_required def delete_book_from_details(book_id): - return Response(delete_book(book_id, "", True), mimetype='application/json') + return Response(delete_book_from_table(book_id, "", True), mimetype='application/json') @editbook.route("/delete/", defaults={'book_format': ""}) @editbook.route("/delete//") @login_required def delete_book_ajax(book_id, book_format): - return delete_book(book_id, book_format, False) + return delete_book_from_table(book_id, book_format, False) def delete_whole_book(book_id, book): @@ -318,7 +318,7 @@ def render_delete_book_result(book_format, jsonResponse, warning, book_id): return redirect(url_for('web.index')) -def delete_book(book_id, book_format, jsonResponse): +def delete_book_from_table(book_id, book_format, jsonResponse): warning = {} if current_user.role_delete_books(): book = calibre_db.get_book(book_id) @@ -1295,7 +1295,7 @@ def merge_list_book(): element.format, element.uncompressed_size, to_name)) - delete_book(from_book.id,"", True) + delete_book_from_table(from_book.id,"", True) return json.dumps({'success': True}) return "" diff --git a/cps/helper.py b/cps/helper.py index d611b5e9..21dab9a3 100644 --- a/cps/helper.py +++ b/cps/helper.py @@ -233,7 +233,7 @@ def get_valid_filename(value, replace_whitespace=True): value = value[:-1]+u'_' value = value.replace("/", "_").replace(":", "_").strip('\0') if use_unidecode: - if not config.config_unicode_filename: + if config.config_unicode_filename: value = (unidecode.unidecode(value)) else: value = value.replace(u'§', u'SS') diff --git a/cps/iso_language_names.py b/cps/iso_language_names.py index 697b7e22..c6267ffd 100644 --- a/cps/iso_language_names.py +++ b/cps/iso_language_names.py @@ -51,11 +51,11 @@ LANGUAGE_NAMES = { "bel": "běloruština", "bem": "bemba (Zambie)", "ben": "bengálština", - "berinomo": "bit", "bho": "bhódžpurština", "bik": "bikolština", "bin": "bini", "bis": "bislamština", + "bit": "berinomo", "bla": "siksika", "bod": "tibetština", "bos": "bosenština", @@ -164,6 +164,7 @@ LANGUAGE_NAMES = { "hil": "hiligayonština", "hin": "hindština", "hit": "chetitština", + "hmj": "Ge", "hmn": "hmongština", "hmo": "hiri motu", "hrv": "chorvatština", @@ -474,11 +475,11 @@ LANGUAGE_NAMES = { "bel": "Weißrussisch", "bem": "Bemba (Sambia)", "ben": "Bengalisch", - "berinomo": "Bit", "bho": "Bhojpuri", "bik": "Bikol", "bin": "Bini", "bis": "Bislama", + "bit": "Berinomo", "bla": "Blackfoot", "bod": "Tibetisch", "bos": "Bosnisch", @@ -587,6 +588,7 @@ LANGUAGE_NAMES = { "hil": "Hiligaynon", "hin": "Hindi", "hit": "Hethitisch", + "hmj": "Ge", "hmn": "Miao-Sprachen", "hmo": "Hiri-Motu", "hrv": "Kroatisch", @@ -896,12 +898,12 @@ LANGUAGE_NAMES = { "bel": "Λευκωρωσικά", "bem": "Bemba (Zambia)", "ben": "Μπενγκάλι", + "bit": "Berinomo", "bho": "Bhojpuri", "bik": "Bikol", "byn": "Bilin", "bin": "Bini", "bis": "Bislama", - "berinomo": "Bit", "zbl": "Blissymbols", "bos": "Βοσνιακά", "bra": "Braj", @@ -971,6 +973,7 @@ LANGUAGE_NAMES = { "lug": "Ganda", "gay": "Gayo", "gba": "Gbaya (Central African Republic)", + "hmj": "Ge", "gez": "Geez", "kat": "Γεωργιανά", "deu": "Γερμανικά", @@ -1275,11 +1278,11 @@ LANGUAGE_NAMES = { "bel": "Bielorruso", "bem": "Bemba (Zambia)", "ben": "Bengalí", - "berinomo": "Bit", "bho": "Bopurí", "bik": "Bicolano", "bin": "Bini", "bis": "Bislama", + "bit": "Berinomo", "bla": "Siksiká", "bod": "Tibetano", "bos": "Bosnio", @@ -1388,6 +1391,7 @@ LANGUAGE_NAMES = { "hil": "Hiligainón", "hin": "Hindi", "hit": "Hitita", + "hmj": "Ge", "hmn": "Hmong", "hmo": "Hiri motu", "hrv": "Croata", @@ -1698,11 +1702,11 @@ LANGUAGE_NAMES = { "bel": "valkovenäjä", "bem": "Bemba (Zambia)", "ben": "bengali", - "berinomo": "Bit", "bho": "bhojpuri", "bik": "bikol", "bin": "bini", "bis": "bislama", + "bit": "Berinomo", "bla": "mustajalka (siksika)", "bod": "tiibetti", "bos": "bosnia", @@ -1811,6 +1815,7 @@ LANGUAGE_NAMES = { "hil": "hiligaynon", "hin": "hindi", "hit": "heetti", + "hmj": "Ge", "hmn": "hmong", "hmo": "hiri-motu", "hrv": "kroatia", @@ -2121,11 +2126,11 @@ LANGUAGE_NAMES = { "bel": "biélorusse", "bem": "bemba (Zambie)", "ben": "bengali", - "berinomo": "bit", "bho": "bhojpuri", "bik": "bikol", "bin": "bini", "bis": "bislama", + "bit": "berinomo", "bla": "pied-noir", "bod": "tibétain", "bos": "bosniaque", @@ -2234,6 +2239,7 @@ LANGUAGE_NAMES = { "hil": "hiligaynon", "hin": "hindi", "hit": "hittite", + "hmj": "ge", "hmn": "hmong", "hmo": "hiri Motu", "hrv": "croate", @@ -2544,11 +2550,11 @@ LANGUAGE_NAMES = { "bel": "belarusz", "bem": "Bemba (Zambia)", "ben": "bengáli", - "berinomo": "Bit", "bho": "bhodzspuri", "bik": "bikol", "bin": "bini", "bis": "biszlama", + "bit": "Berinomo", "bla": "szikszika", "bod": "tibeti", "bos": "bosnyák", @@ -2657,6 +2663,7 @@ LANGUAGE_NAMES = { "hil": "hiligajnon", "hin": "hindi", "hit": "hettita", + "hmj": "Ge", "hmn": "hmong", "hmo": "hiri motu", "hrv": "horvát", @@ -2967,11 +2974,11 @@ LANGUAGE_NAMES = { "bel": "Bielorusso", "bem": "Bemba (Zambia)", "ben": "Bengalese", - "berinomo": "Bit", "bho": "Bhojpuri", "bik": "bicol", "bin": "Bini", "bis": "bislama", + "bit": "Berinomo", "bla": "Siksika", "bod": "Tibetano", "bos": "Bosniaco", @@ -3080,6 +3087,7 @@ LANGUAGE_NAMES = { "hil": "Hiligayna", "hin": "Hindi", "hit": "hittite", + "hmj": "Ge", "hmn": "Hmong", "hmo": "Hiri motu", "hrv": "Croato", @@ -3390,11 +3398,11 @@ LANGUAGE_NAMES = { "bel": "白ロシア語", "bem": "Bemba (Zambia)", "ben": "ベンガル語", - "berinomo": "Bit", "bho": "ボージプリー語", "bik": "ビコル語", "bin": "ビニ語", "bis": "ビスラマ語", + "bit": "Berinomo", "bla": "ブラックフット語", "bod": "チベット語", "bos": "ボスニア語", @@ -3503,6 +3511,7 @@ LANGUAGE_NAMES = { "hil": "ヒリジャノン語", "hin": "ヒンディー語", "hit": "ヒッタイト語", + "hmj": "Ge", "hmn": "フモング語", "hmo": "ヒリモトゥ語", "hrv": "クロアチア語", @@ -3813,11 +3822,11 @@ LANGUAGE_NAMES = { "bel": "Belarusian", "bem": "Bemba (Zambia)", "ben": "Bengali", - "berinomo": "Bit", "bho": "Bhojpuri", "bik": "Bikol", "bin": "Bini", "bis": "Bislama", + "bit": "Berinomo", "bla": "Siksika", "bod": "Tibetan", "bos": "Bosnian", @@ -3926,6 +3935,7 @@ LANGUAGE_NAMES = { "hil": "Hiligaynon", "hin": "Hindi", "hit": "Hittite", + "hmj": "Ge", "hmn": "Hmong", "hmo": "Hiri Motu", "hrv": "Croatian", @@ -4236,11 +4246,11 @@ LANGUAGE_NAMES = { "bel": "Wit-Russisch; Belarussisch", "bem": "Bemba (Zambia)", "ben": "Bengaals", - "berinomo": "Bit", "bho": "Bhojpuri", "bik": "Bikol", "bin": "Bini; Edo", "bis": "Bislama", + "bit": "Berinomo", "bla": "Siksika", "bod": "Tibetaans", "bos": "Bosnisch", @@ -4349,6 +4359,7 @@ LANGUAGE_NAMES = { "hil": "Hiligainoons", "hin": "Hindi", "hit": "Hittitisch", + "hmj": "Ge", "hmn": "Hmong", "hmo": "Hiri Motu", "hrv": "Kroatisch", @@ -4659,11 +4670,11 @@ LANGUAGE_NAMES = { "bel": "białoruski", "bem": "bemba (Zambia)", "ben": "bengalski", - "berinomo": "Bit", "bho": "bhodźpuri", "bik": "bikol", "bin": "edo", "bis": "bislama", + "bit": "Berinomo", "bla": "siksika", "bod": "tybetański", "bos": "bośniacki", @@ -4772,6 +4783,7 @@ LANGUAGE_NAMES = { "hil": "hiligajnon", "hin": "hindi", "hit": "hetycki", + "hmj": "Ge", "hmn": "hmong", "hmo": "hiri motu", "hrv": "chorwacki", @@ -5081,12 +5093,12 @@ LANGUAGE_NAMES = { "bel": "Belarusian", "bem": "Bemba (Zambia)", "ben": "Bengali", + "bit": "Berinomo", "bho": "Bhojpuri", "bik": "Bikol", "byn": "Bilin", "bin": "Bini", "bis": "Bislama", - "berinomo": "Bit", "zbl": "Blissymbols", "bos": "Bosnian", "bra": "Braj", @@ -5156,6 +5168,7 @@ LANGUAGE_NAMES = { "lug": "Ganda", "gay": "Gayo", "gba": "Gbaya (Central African Republic)", + "hmj": "Ge", "gez": "Geez", "kat": "Georgiano", "deu": "Alemão", @@ -5458,11 +5471,11 @@ LANGUAGE_NAMES = { "bel": "Белорусский", "bem": "Бемба (Замбия)", "ben": "Бенгальский", - "berinomo": "Bit", "bho": "Бходжпури", "bik": "Бикольский", "bin": "Бини", "bis": "Бислама", + "bit": "Berinomo", "bla": "Сиксика", "bod": "Тибетский", "bos": "Боснийский", @@ -5571,6 +5584,7 @@ LANGUAGE_NAMES = { "hil": "Хилигайнон", "hin": "Хинди", "hit": "Хиттит", + "hmj": "Ge", "hmn": "Хмонг", "hmo": "Хири Моту", "hrv": "Хорватский", @@ -5881,11 +5895,11 @@ LANGUAGE_NAMES = { "bel": "Vitryska", "bem": "Bemba (Zambia)", "ben": "Bengaliska", - "berinomo": "Bit", "bho": "Bhojpuri", "bik": "Bikol", "bin": "Edo (bini)", "bis": "Bislama", + "bit": "Berinomo", "bla": "Siksika (svartfotindianernas språk)", "bod": "Tibetanska", "bos": "Bosniska", @@ -5994,6 +6008,7 @@ LANGUAGE_NAMES = { "hil": "Hiligaynon", "hin": "Hindi", "hit": "Hettitiska språk", + "hmj": "Ge", "hmn": "Hmong", "hmo": "Hiri Motu", "hrv": "Kroatiska", @@ -6303,12 +6318,12 @@ LANGUAGE_NAMES = { "bel": "Beyaz Rusça", "bem": "Bemba (Zambia)", "ben": "Bengalce", + "bit": "Berinomo", "bho": "Bhojpuri (Hindistan)", "bik": "Bikol (Filipinler)", "byn": "Bilin", "bin": "Bini (Afrika)", "bis": "Bislama (Vanuatu; Kuzey Pasifik)", - "berinomo": "Bit", "zbl": "Blis Sembolleri", "bos": "Boşnakça", "bra": "Braj (Hindistan)", @@ -6378,6 +6393,7 @@ LANGUAGE_NAMES = { "lug": "Ganda Dili", "gay": "Gayo (Sumatra)", "gba": "Gbaya (Orta Afrika Cumhuriyeti)", + "hmj": "Ge", "gez": "Geez (Etiyopya)", "kat": "Gürcüce", "deu": "Almanca", @@ -6680,11 +6696,11 @@ LANGUAGE_NAMES = { "bel": "білоруська", "bem": "бемба (Замбія)", "ben": "бенгальська", - "berinomo": "біт", "bho": "бходжпурі", "bik": "бікольська", "bin": "біні", "bis": "біслама", + "bit": "беріномо", "bla": "сісіка", "bod": "тибетська", "bos": "боснійська", @@ -6793,6 +6809,7 @@ LANGUAGE_NAMES = { "hil": "хілігайнон", "hin": "хінді", "hit": "хетська", + "hmj": "ге", "hmn": "хмонг", "hmo": "хірімоту", "hrv": "хорватська", @@ -7103,11 +7120,11 @@ LANGUAGE_NAMES = { "bel": "白俄罗斯语", "bem": "本巴语(赞比亚)", "ben": "孟加拉语", - "berinomo": "布兴话", "bho": "博杰普尔语", "bik": "比科尔语", "bin": "比尼语", "bis": "比斯拉马语", + "bit": "Berinomo", "bla": "西克西卡语", "bod": "藏语", "bos": "波斯尼亚语", @@ -7216,6 +7233,7 @@ LANGUAGE_NAMES = { "hil": "希利盖农语", "hin": "印地语", "hit": "赫梯语", + "hmj": "亻革家语、重安江苗语", "hmn": "苗语", "hmo": "希里莫图语", "hrv": "克罗地亚语", @@ -7525,12 +7543,12 @@ LANGUAGE_NAMES = { "bel": "白俄羅斯文", "bem": "Bemba (Zambia)", "ben": "Bengali", + "bit": "Berinomo", "bho": "Bhojpuri", "bik": "Bikol", "byn": "Bilin", "bin": "Bini", "bis": "Bislama", - "berinomo": "Bit", "zbl": "布利斯符號", "bos": "Bosnian", "bra": "Braj", @@ -7600,6 +7618,7 @@ LANGUAGE_NAMES = { "lug": "Ganda", "gay": "Gayo", "gba": "Gbaya (Central African Republic)", + "hmj": "Ge", "gez": "Geez", "kat": "Georgian", "deu": "德文", @@ -8016,6 +8035,7 @@ LANGUAGE_NAMES = { "hil": "Hiligaynon", "hin": "Hindi", "hit": "Hittite", + "hmj": "Ge", "hmn": "Hmong", "hmo": "Hiri Motu", "hrv": "Croatian", diff --git a/cps/kobo.py b/cps/kobo.py index 1bcf3f8d..ef9a9476 100644 --- a/cps/kobo.py +++ b/cps/kobo.py @@ -146,9 +146,16 @@ def HandleSyncRequest(): if not current_app.wsgi_app.is_proxied: log.debug('Kobo: Received unproxied request, changed request port to external server port') - new_books_last_modified = sync_token.books_last_modified - new_books_last_created = sync_token.books_last_created + # if no books synced don't respect sync_token + if not ub.session.query(ub.KoboSyncedBooks).filter(ub.KoboSyncedBooks.user_id == current_user.id).count(): + sync_token.books_last_modified = datetime.datetime.min + sync_token.books_last_created = datetime.datetime.min + sync_token.reading_state_last_modified = datetime.datetime.min + + new_books_last_modified = sync_token.books_last_modified # needed for sync selected shelfs only + new_books_last_created = sync_token.books_last_created # needed to distinguish between new and changed entitlement new_reading_state_last_modified = sync_token.reading_state_last_modified + new_archived_last_modified = datetime.datetime.min sync_results = [] @@ -209,7 +216,7 @@ def HandleSyncRequest(): books = calibre_db.session.execute(changed_entries.limit(SYNC_ITEM_LIMIT)) else: books = changed_entries.limit(SYNC_ITEM_LIMIT) - log.debug("Books to Sync: {}".format(books.count())) + log.debug("Books to Sync: {}".format(len(books.all()))) for book in books: formats = [data.format for data in book.Books.data] if not 'KEPUB' in formats and config.config_kepubifypath and 'EPUB' in formats: @@ -306,7 +313,9 @@ def HandleSyncRequest(): sync_shelves(sync_token, sync_results, only_kobo_shelves) - sync_token.books_last_created = new_books_last_created + # update last created timestamp to distinguish between new and changed entitlements + if not cont_sync: + sync_token.books_last_created = new_books_last_created sync_token.books_last_modified = new_books_last_modified sync_token.archive_last_modified = new_archived_last_modified sync_token.reading_state_last_modified = new_reading_state_last_modified diff --git a/cps/services/worker.py b/cps/services/worker.py index 5952c705..076c9104 100644 --- a/cps/services/worker.py +++ b/cps/services/worker.py @@ -85,7 +85,7 @@ class WorkerThread(threading.Thread): def add(cls, user, task): ins = cls.getInstance() ins.num += 1 - log.debug("Add Task for user: {}: {}".format(user, task)) + log.debug("Add Task for user: {} - {}".format(user, task)) ins.queue.put(QueuedTask( num=ins.num, user=user, diff --git a/cps/static/css/style.css b/cps/static/css/style.css index bf2257e6..6e6b0eae 100644 --- a/cps/static/css/style.css +++ b/cps/static/css/style.css @@ -429,7 +429,7 @@ div.log { } #detailcover { cursor:zoom-in; } -#detailcover:-webkit-full-screen { cursor:zoom-out; } -#detailcover:-moz-full-screen { cursor:zoom-out; } -#detailcover:-ms-fullscreen { cursor:zoom-out; } -#detailcover:fullscreen { cursor:zoom-out; } +#detailcover:-webkit-full-screen { cursor:zoom-out; border: 0; } +#detailcover:-moz-full-screen { cursor:zoom-out; border: 0; } +#detailcover:-ms-fullscreen { cursor:zoom-out; border: 0; } +#detailcover:fullscreen { cursor:zoom-out; border: 0; } diff --git a/cps/static/js/libs/tinymce/langs/zh_Hans_CN.js b/cps/static/js/libs/tinymce/langs/zh_Hans_CN.js index 2a784f57..981c9090 100644 --- a/cps/static/js/libs/tinymce/langs/zh_Hans_CN.js +++ b/cps/static/js/libs/tinymce/langs/zh_Hans_CN.js @@ -1,4 +1,4 @@ -tinymce.addI18n('zh_CN',{ +tinymce.addI18n('zh_Hans_CN',{ "Redo": "\u91cd\u505a", "Undo": "\u64a4\u9500", "Cut": "\u526a\u5207", diff --git a/cps/static/js/libs/tinymce/langs/zh_Hant_TW.js b/cps/static/js/libs/tinymce/langs/zh_Hant_TW.js index 1987486c..f6e7e248 100644 --- a/cps/static/js/libs/tinymce/langs/zh_Hant_TW.js +++ b/cps/static/js/libs/tinymce/langs/zh_Hant_TW.js @@ -1,4 +1,4 @@ -tinymce.addI18n('zh_TW',{ +tinymce.addI18n('zh_Hant_TW',{ "Redo": "\u91cd\u505a", "Undo": "\u64a4\u92b7", "Cut": "\u526a\u4e0b", @@ -416,4 +416,4 @@ tinymce.addI18n('zh_TW',{ "Spellcheck": "\u62fc\u5b57\u6aa2\u67e5", "Caption": "\u8868\u683c\u6a19\u984c", "Insert template": "\u63d2\u5165\u6a23\u7248" -}); \ No newline at end of file +}); diff --git a/cps/static/js/main.js b/cps/static/js/main.js index cf6fbe0d..585d2296 100644 --- a/cps/static/js/main.js +++ b/cps/static/js/main.js @@ -517,6 +517,7 @@ $(function() { .on("hidden.bs.modal", function() { $(this).find(".modal-body").html("..."); $("#config_delete_kobo_token").show(); + $("#kobo_full_sync").show(); }); $("#config_delete_kobo_token").click(function() { @@ -530,6 +531,7 @@ $(function() { url: getPath() + "/kobo_auth/deleteauthtoken/" + value, }); $("#config_delete_kobo_token").hide(); + $("#kobo_full_sync").hide(); } ); }); @@ -563,6 +565,33 @@ $(function() { } ); }); + + $("#kobo_full_sync").click(function() { + confirmDialog( + "btnfullsync", + "GeneralDeleteModal", + $(this).data('value'), + function(value){ + path = getPath() + "/ajax/fullsync" + $.ajax({ + method:"get", + url: path, + timeout: 900, + success:function(data) { + data.forEach(function(item) { + if (!jQuery.isEmptyObject(item)) { + $( ".navbar" ).after( '
' + + '
'+item.message+'
' + + '
'); + } + }); + } + }); + } + ); + }); + + $("#user_submit").click(function() { this.closest("form").submit(); }); diff --git a/cps/static/js/reading/epub.js b/cps/static/js/reading/epub.js index edafa82c..7942bfbd 100644 --- a/cps/static/js/reading/epub.js +++ b/cps/static/js/reading/epub.js @@ -61,11 +61,14 @@ var reader; this.removeBookmark(bookmark); }.bind(this)); } + + var csrftoken = $("input[name='csrf_token']").val(); // Save to database $.ajax(calibre.bookmarkUrl, { method: "post", - data: { bookmark: location || "" } + data: { bookmark: location || "" }, + headers: { "X-CSRFToken": csrftoken } }).fail(function (xhr, status, error) { alert(error); }); diff --git a/cps/tasks/convert.py b/cps/tasks/convert.py index ada53005..59ad6909 100644 --- a/cps/tasks/convert.py +++ b/cps/tasks/convert.py @@ -217,13 +217,16 @@ class TaskConvert(CalibreTask): quotes.append(quotes_index) quotes_index += 1 - p = process_open(command, quotes) + p = process_open(command, quotes, newlines=False) except OSError as e: return 1, _(u"Ebook-converter failed: %(error)s", error=e) while p.poll() is None: nextline = p.stdout.readline() - log.debug(nextline.strip('\r\n')) + if isinstance(nextline, bytes): + nextline = nextline.decode('utf-8', errors="ignore").strip('\r\n') + if nextline: + log.debug(nextline) # parse progress string from calibre-converter progress = re.search(r"(\d+)%\s.*", nextline) if progress: @@ -236,11 +239,15 @@ class TaskConvert(CalibreTask): calibre_traceback = p.stderr.readlines() error_message = "" for ele in calibre_traceback: - log.debug(ele.strip('\n')) + ele = ele.decode('utf-8', errors="ignore").strip('\n') + log.debug(ele) if not ele.startswith('Traceback') and not ele.startswith(' File'): - error_message = _("Calibre failed with error: %(error)s", error=ele.strip('\n')) + error_message = _("Calibre failed with error: %(error)s", error=ele) return check, error_message @property def name(self): return "Convert" + + def __str__(self): + return "Convert {} {}".format(self.bookid, self.kindle_mail) diff --git a/cps/tasks/mail.py b/cps/tasks/mail.py index 2e95ee98..05b2175f 100644 --- a/cps/tasks/mail.py +++ b/cps/tasks/mail.py @@ -267,4 +267,4 @@ class TaskEmail(CalibreTask): return "E-mail" def __str__(self): - return "{}, {}".format(self.name, self.subject) + return "E-mail {}, {}".format(self.name, self.subject) diff --git a/cps/tasks/upload.py b/cps/tasks/upload.py index 6a341cdd..2a667c28 100644 --- a/cps/tasks/upload.py +++ b/cps/tasks/upload.py @@ -32,3 +32,6 @@ class TaskUpload(CalibreTask): @property def name(self): return "Upload" + + def __str__(self): + return "Upload {}".format(self.message) diff --git a/cps/templates/read.html b/cps/templates/read.html index 3d2566e0..1766eb1b 100644 --- a/cps/templates/read.html +++ b/cps/templates/read.html @@ -17,6 +17,7 @@