diff --git a/cps/editbooks.py b/cps/editbooks.py index 2c375c72..0a6410b1 100644 --- a/cps/editbooks.py +++ b/cps/editbooks.py @@ -162,7 +162,7 @@ def upload(): return make_response(jsonify(resp)) else: resp = {"location": url_for('web.show_book', book_id=book_id)} - return make_response(jsonify(resp)) + return Response(json.dumps(resp), mimetype='application/json') except (OperationalError, IntegrityError, StaleDataError) as e: calibre_db.session.rollback() log.error_or_exception("Database error: {}".format(e)) @@ -398,6 +398,7 @@ def get_sorted_entry(field, bookid): return make_response(jsonify(authors=" & ".join([a.name for a in calibre_db.order_authors([book])]))) return "" + @editbook.route("/ajax/simulatemerge", methods=['POST']) @user_login_required @edit_required @@ -462,6 +463,7 @@ def read_selected_books(): return json.dumps({'success': True}) return "" + @editbook.route("/ajax/mergebooks", methods=['POST']) @user_login_required @edit_required @@ -772,8 +774,9 @@ def prepare_authors(authr, calibre_path, gdrive=False): all_new_name = helper.get_valid_filename(one_book.title, chars=42) + ' - ' \ + helper.get_valid_filename(renamed_author.name, chars=42) # change location in database to new author/title path - helper.rename_all_files_on_change(one_book, new_path, new_path, all_new_name, gdrive) - + error = helper.rename_all_files_on_change(one_book, new_path, new_path, all_new_name, gdrive) + if error: + flash(error) return input_authors diff --git a/cps/helper.py b/cps/helper.py index fb8b3547..6d584454 100644 --- a/cps/helper.py +++ b/cps/helper.py @@ -394,10 +394,16 @@ def delete_book_file(book, calibrepath, book_format=None): def rename_all_files_on_change(one_book, new_path, old_path, all_new_name, gdrive=False): for file_format in one_book.data: if not gdrive: - if not os.path.exists(new_path): - os.makedirs(new_path) - shutil.move(os.path.join(old_path, file_format.name + '.' + file_format.format.lower()), - os.path.join(new_path, all_new_name + '.' + file_format.format.lower())) + try: + if not os.path.exists(new_path): + os.makedirs(new_path) + shutil.move(os.path.join(old_path, file_format.name + '.' + file_format.format.lower()), + os.path.join(new_path, all_new_name + '.' + file_format.format.lower())) + except PermissionError as ex: + log.error("Moving book-id %s folder %s failed: %s", one_book.id, new_path, ex) + return _("Moving book path of Book %(book_id)s to: '%(src)s' failed with error: %(error)s", + book_id=one_book.id, src=new_path, error=str(ex)) + else: g_file = gd.getFileFromEbooksFolder(old_path, file_format.name + '.' + file_format.format.lower()) @@ -410,6 +416,7 @@ def rename_all_files_on_change(one_book, new_path, old_path, all_new_name, gdriv # change name in Database file_format.name = all_new_name + return False def rename_author_path(first_author, old_author_dir, renamed_author, calibre_path="", gdrive=False): @@ -468,7 +475,7 @@ def update_dir_structure_file(book_id, calibre_path, original_filepath, new_auth all_new_name = get_valid_filename(local_book.title, chars=42) + ' - ' \ + get_valid_filename(new_author, chars=42) # Book folder already moved, only files need to be renamed - rename_all_files_on_change(local_book, new_path, new_path, all_new_name) + error |= rename_all_files_on_change(local_book, new_path, new_path, all_new_name) if error: return error @@ -511,11 +518,11 @@ def update_dir_structure_gdrive(book_id, first_author): book.path = new_authordir + '/' + book.path.split('/')[1] gd.updateDatabaseOnEdit(g_file['id'], book.path) else: - return _('File %(file)s not found on Google Drive', file=authordir) # file not found''' + return _('File %(file)s not found on Google Drive', file=authordir) # file not found if titledir != new_titledir or authordir != new_authordir : all_new_name = get_valid_filename(book.title, chars=42) + ' - ' \ + get_valid_filename(new_authordir, chars=42) - rename_all_files_on_change(book, book.path, book.path, all_new_name, gdrive=True) # todo: Move filenames on gdrive + return rename_all_files_on_change(book, book.path, book.path, all_new_name, gdrive=True) # todo: Move filenames on gdrive return False @@ -558,26 +565,6 @@ def move_files_on_change(calibre_path, new_author_dir, new_titledir, localbook, return False -def rename_files_on_change(first_author, - renamed_author, - local_book, - original_filepath="", - path="", - calibre_path="", - gdrive=False): - # Rename all files from old names to new names - #try: - #clean_author_database(renamed_author, calibre_path, gdrive=gdrive) - #if first_author and first_author not in renamed_author: - # clean_author_database([first_author], calibre_path, local_book, gdrive) - #if not gdrive and not renamed_author and not original_filepath and len(os.listdir(os.path.dirname(path))) == 0: - # shutil.rmtree(os.path.dirname(path)) - #except (OSError, FileNotFoundError) as ex: - # log.error_or_exception("Error in rename file in path {}".format(ex)) - # return _("Error in rename file in path: {}".format(str(ex))) - return False - - def delete_book_gdrive(book, book_format): error = None if book_format: @@ -972,8 +959,9 @@ def do_download_file(book, book_format, client, data, headers): # ToDo Check headers parameter for element in headers: response.headers[element[0]] = element[1] - log.info('Downloading file: \'%s\' by %s - %s', format(os.path.join(filename, book_name + "." + book_format)), + log.info('Downloading file: \'%s\' by %s', format(os.path.join(filename, book_name + "." + book_format)), current_user.name, request.headers.get('X-Forwarded-For', request.remote_addr)) + log.info('Downloading file: {}'.format(os.path.join(filename, book_name + "." + book_format))) return response diff --git a/test/Calibre-Web TestSummary_Linux.html b/test/Calibre-Web TestSummary_Linux.html index 1dce233b..dad550db 100644 --- a/test/Calibre-Web TestSummary_Linux.html +++ b/test/Calibre-Web TestSummary_Linux.html @@ -37,20 +37,20 @@
-

Start Time: 2024-12-13 18:37:11

+

Start Time: 2024-12-15 07:24:54

-

Stop Time: 2024-12-14 01:56:41

+

Stop Time: 2024-12-15 14:36:53

-

Duration: 6h 13 min

+

Duration: 6h 5 min

@@ -234,11 +234,11 @@ - + TestBackupMetadata 21 - 21 - 0 + 20 + 1 0 0 @@ -419,11 +419,31 @@ - +
TestBackupMetadata - test_backup_change_custom_text
- PASS + +
+ FAIL +
+ + + + @@ -1844,12 +1864,12 @@ - + TestEditBooksList 19 - 19 - 0 - 0 + 5 + 5 + 9 0 Detail @@ -1858,11 +1878,31 @@ - +
TestEditBooksList - test_booklist_xss
- PASS + +
+ ERROR +
+ + + + @@ -1876,110 +1916,386 @@ - +
TestEditBooksList - test_bookslist_edit_categories
- PASS + +
+ ERROR +
+ + + + - +
TestEditBooksList - test_bookslist_edit_comment
- PASS + +
+ FAIL +
+ + + + - +
TestEditBooksList - test_bookslist_edit_cust_category
- PASS + +
+ ERROR +
+ + + + - +
TestEditBooksList - test_bookslist_edit_cust_comment
- PASS + +
+ FAIL +
+ + + + - +
TestEditBooksList - test_bookslist_edit_cust_enum
- PASS + +
+ ERROR +
+ + + + - +
TestEditBooksList - test_bookslist_edit_cust_float
- PASS + +
+ FAIL +
+ + + + - +
TestEditBooksList - test_bookslist_edit_cust_int
- PASS + +
+ ERROR +
+ + + + - +
TestEditBooksList - test_bookslist_edit_cust_ratings
- PASS + +
+ ERROR +
+ + + + - +
TestEditBooksList - test_bookslist_edit_cust_text
- PASS + +
+ FAIL +
+ + + + - +
TestEditBooksList - test_bookslist_edit_languages
- PASS + +
+ ERROR +
+ + + + - +
TestEditBooksList - test_bookslist_edit_publisher
- PASS + +
+ ERROR +
+ + + + - +
TestEditBooksList - test_bookslist_edit_series
- PASS + +
+ ERROR +
+ + + + @@ -2020,11 +2336,33 @@ - +
TestEditBooksList - test_search_books_list
- PASS + +
+ FAIL +
+ + + + @@ -3539,6 +3877,56 @@ AssertionError: 0.02499824076612272 not less than or equal to 0.02 + + _FailedTest + 1 + 0 + 0 + 1 + 0 + + Detail + + + + + + + +
_FailedTest - test_mass_edit_books_list
+ + +
+ ERROR +
+ + + + + + + + + TestMergeBooksList 2 @@ -3547,13 +3935,13 @@ AssertionError: 0.02499824076612272 not less than or equal to 0.02 0 0 - Detail + Detail - +
TestMergeBooksList - test_book_merge
@@ -3562,7 +3950,7 @@ AssertionError: 0.02499824076612272 not less than or equal to 0.02 - +
TestMergeBooksList - test_delete_book
@@ -3580,13 +3968,13 @@ AssertionError: 0.02499824076612272 not less than or equal to 0.02 0 0 - Detail + Detail - +
TestOAuthLogin - test_oauth_about
@@ -3595,7 +3983,7 @@ AssertionError: 0.02499824076612272 not less than or equal to 0.02 - +
TestOAuthLogin - test_visible_oauth
@@ -3613,13 +4001,13 @@ AssertionError: 0.02499824076612272 not less than or equal to 0.02 0 0 - Detail + Detail - +
TestOPDSFeed - test_access_right_guest
@@ -3628,7 +4016,7 @@ AssertionError: 0.02499824076612272 not less than or equal to 0.02 - +
TestOPDSFeed - test_access_right_user
@@ -3637,7 +4025,7 @@ AssertionError: 0.02499824076612272 not less than or equal to 0.02 - +
TestOPDSFeed - test_opds
@@ -3646,7 +4034,7 @@ AssertionError: 0.02499824076612272 not less than or equal to 0.02 - +
TestOPDSFeed - test_opds_author
@@ -3655,7 +4043,7 @@ AssertionError: 0.02499824076612272 not less than or equal to 0.02 - +
TestOPDSFeed - test_opds_books
@@ -3664,7 +4052,7 @@ AssertionError: 0.02499824076612272 not less than or equal to 0.02 - +
TestOPDSFeed - test_opds_calibre_companion
@@ -3673,7 +4061,7 @@ AssertionError: 0.02499824076612272 not less than or equal to 0.02 - +
TestOPDSFeed - test_opds_colon_password
@@ -3682,7 +4070,7 @@ AssertionError: 0.02499824076612272 not less than or equal to 0.02 - +
TestOPDSFeed - test_opds_cover
@@ -3691,7 +4079,7 @@ AssertionError: 0.02499824076612272 not less than or equal to 0.02 - +
TestOPDSFeed - test_opds_download_book
@@ -3700,7 +4088,7 @@ AssertionError: 0.02499824076612272 not less than or equal to 0.02 - +
TestOPDSFeed - test_opds_formats
@@ -3709,7 +4097,7 @@ AssertionError: 0.02499824076612272 not less than or equal to 0.02 - +
TestOPDSFeed - test_opds_guest_user
@@ -3718,7 +4106,7 @@ AssertionError: 0.02499824076612272 not less than or equal to 0.02 - +
TestOPDSFeed - test_opds_hot
@@ -3727,7 +4115,7 @@ AssertionError: 0.02499824076612272 not less than or equal to 0.02 - +
TestOPDSFeed - test_opds_language
@@ -3736,7 +4124,7 @@ AssertionError: 0.02499824076612272 not less than or equal to 0.02 - +
TestOPDSFeed - test_opds_non_admin
@@ -3745,7 +4133,7 @@ AssertionError: 0.02499824076612272 not less than or equal to 0.02 - +
TestOPDSFeed - test_opds_publisher
@@ -3754,7 +4142,7 @@ AssertionError: 0.02499824076612272 not less than or equal to 0.02 - +
TestOPDSFeed - test_opds_random
@@ -3763,7 +4151,7 @@ AssertionError: 0.02499824076612272 not less than or equal to 0.02 - +
TestOPDSFeed - test_opds_ratings
@@ -3772,7 +4160,7 @@ AssertionError: 0.02499824076612272 not less than or equal to 0.02 - +
TestOPDSFeed - test_opds_read_unread
@@ -3781,7 +4169,7 @@ AssertionError: 0.02499824076612272 not less than or equal to 0.02 - +
TestOPDSFeed - test_opds_search
@@ -3790,7 +4178,7 @@ AssertionError: 0.02499824076612272 not less than or equal to 0.02 - +
TestOPDSFeed - test_opds_series
@@ -3799,7 +4187,7 @@ AssertionError: 0.02499824076612272 not less than or equal to 0.02 - +
TestOPDSFeed - test_opds_shelf_access
@@ -3808,7 +4196,7 @@ AssertionError: 0.02499824076612272 not less than or equal to 0.02 - +
TestOPDSFeed - test_opds_stats
@@ -3817,7 +4205,7 @@ AssertionError: 0.02499824076612272 not less than or equal to 0.02 - +
TestOPDSFeed - test_opds_tags
@@ -3826,7 +4214,7 @@ AssertionError: 0.02499824076612272 not less than or equal to 0.02 - +
TestOPDSFeed - test_opds_top_rated
@@ -3835,7 +4223,7 @@ AssertionError: 0.02499824076612272 not less than or equal to 0.02 - +
TestOPDSFeed - test_opds_unicode_user
@@ -3844,7 +4232,7 @@ AssertionError: 0.02499824076612272 not less than or equal to 0.02 - +
TestOPDSFeed - test_recently_added
@@ -3862,13 +4250,13 @@ AssertionError: 0.02499824076612272 not less than or equal to 0.02 0 0 - Detail + Detail - +
TestUploadPDF - test_upload_invalid_pdf
@@ -3886,13 +4274,13 @@ AssertionError: 0.02499824076612272 not less than or equal to 0.02 0 0 - Detail + Detail - +
TestPipInstall - test_command_start
@@ -3901,7 +4289,7 @@ AssertionError: 0.02499824076612272 not less than or equal to 0.02 - +
TestPipInstall - test_foldername_database_location
@@ -3910,7 +4298,7 @@ AssertionError: 0.02499824076612272 not less than or equal to 0.02 - +
TestPipInstall - test_module_start
@@ -3920,21 +4308,21 @@ AssertionError: 0.02499824076612272 not less than or equal to 0.02 - + TestReader - 8 + 9 7 0 - 0 + 1 1 - Detail + Detail - +
TestReader - test_cb7_reader
@@ -3943,7 +4331,7 @@ AssertionError: 0.02499824076612272 not less than or equal to 0.02 - +
TestReader - test_comic_MACOS_files
@@ -3952,7 +4340,7 @@ AssertionError: 0.02499824076612272 not less than or equal to 0.02 - +
TestReader - test_comic_reader
@@ -3961,7 +4349,7 @@ AssertionError: 0.02499824076612272 not less than or equal to 0.02 - +
TestReader - test_epub_reader
@@ -3970,7 +4358,44 @@ AssertionError: 0.02499824076612272 not less than or equal to 0.02 - + + +
TestReader - test_kepub_reader
+ + +
+ ERROR +
+ + + + + + + + +
TestReader - test_pdf_reader
@@ -3979,7 +4404,7 @@ AssertionError: 0.02499824076612272 not less than or equal to 0.02 - +
TestReader - test_single_file_comic
@@ -3988,7 +4413,7 @@ AssertionError: 0.02499824076612272 not less than or equal to 0.02 - +
TestReader - test_sound_listener
@@ -3997,7 +4422,7 @@ AssertionError: 0.02499824076612272 not less than or equal to 0.02 - +
TestReader - test_txt_reader
@@ -4015,13 +4440,13 @@ AssertionError: 0.02499824076612272 not less than or equal to 0.02 0 0 - Detail + Detail - +
TestReadOnlyDatabase - test_readonly_path
@@ -4039,13 +4464,13 @@ AssertionError: 0.02499824076612272 not less than or equal to 0.02 0 0 - Detail + Detail - +
TestRegister - test_forgot_password
@@ -4054,7 +4479,7 @@ AssertionError: 0.02499824076612272 not less than or equal to 0.02 - +
TestRegister - test_illegal_email
@@ -4063,7 +4488,7 @@ AssertionError: 0.02499824076612272 not less than or equal to 0.02 - +
TestRegister - test_limit_domain
@@ -4072,7 +4497,7 @@ AssertionError: 0.02499824076612272 not less than or equal to 0.02 - +
TestRegister - test_register_no_server
@@ -4081,7 +4506,7 @@ AssertionError: 0.02499824076612272 not less than or equal to 0.02 - +
TestRegister - test_registering_only_email
@@ -4090,7 +4515,7 @@ AssertionError: 0.02499824076612272 not less than or equal to 0.02 - +
TestRegister - test_registering_user
@@ -4099,7 +4524,7 @@ AssertionError: 0.02499824076612272 not less than or equal to 0.02 - +
TestRegister - test_registering_user_fail
@@ -4108,7 +4533,7 @@ AssertionError: 0.02499824076612272 not less than or equal to 0.02 - +
TestRegister - test_user_change_password
@@ -4126,13 +4551,13 @@ AssertionError: 0.02499824076612272 not less than or equal to 0.02 0 0 - Detail + Detail - +
TestReverseProxy - test_logout
@@ -4141,7 +4566,7 @@ AssertionError: 0.02499824076612272 not less than or equal to 0.02 - +
TestReverseProxy - test_move_page
@@ -4150,7 +4575,7 @@ AssertionError: 0.02499824076612272 not less than or equal to 0.02 - +
TestReverseProxy - test_next
@@ -4159,7 +4584,7 @@ AssertionError: 0.02499824076612272 not less than or equal to 0.02 - +
TestReverseProxy - test_reverse_about
@@ -4177,13 +4602,13 @@ AssertionError: 0.02499824076612272 not less than or equal to 0.02 0 1 - Detail + Detail - +
TestShelf - test_access_shelf
@@ -4192,7 +4617,7 @@ AssertionError: 0.02499824076612272 not less than or equal to 0.02 - +
TestShelf - test_add_shelf_from_search
@@ -4201,7 +4626,7 @@ AssertionError: 0.02499824076612272 not less than or equal to 0.02 - +
TestShelf - test_adv_search_shelf
@@ -4210,7 +4635,7 @@ AssertionError: 0.02499824076612272 not less than or equal to 0.02 - +
TestShelf - test_arrange_shelf
@@ -4219,7 +4644,7 @@ AssertionError: 0.02499824076612272 not less than or equal to 0.02 - +
TestShelf - test_create_public_shelf
@@ -4228,7 +4653,7 @@ AssertionError: 0.02499824076612272 not less than or equal to 0.02 - +
TestShelf - test_create_public_shelf_no_permission
@@ -4237,7 +4662,7 @@ AssertionError: 0.02499824076612272 not less than or equal to 0.02 - +
TestShelf - test_delete_book_of_shelf
@@ -4246,7 +4671,7 @@ AssertionError: 0.02499824076612272 not less than or equal to 0.02 - +
TestShelf - test_private_shelf
@@ -4255,7 +4680,7 @@ AssertionError: 0.02499824076612272 not less than or equal to 0.02 - +
TestShelf - test_public_private_shelf
@@ -4264,7 +4689,7 @@ AssertionError: 0.02499824076612272 not less than or equal to 0.02 - +
TestShelf - test_public_shelf
@@ -4273,7 +4698,7 @@ AssertionError: 0.02499824076612272 not less than or equal to 0.02 - +
TestShelf - test_rename_shelf
@@ -4282,7 +4707,7 @@ AssertionError: 0.02499824076612272 not less than or equal to 0.02 - +
TestShelf - test_shelf_action_non_shelf_edit_role
@@ -4291,7 +4716,7 @@ AssertionError: 0.02499824076612272 not less than or equal to 0.02 - +
TestShelf - test_shelf_anonymous
@@ -4300,19 +4725,19 @@ AssertionError: 0.02499824076612272 not less than or equal to 0.02 - +
TestShelf - test_shelf_database_change
- SKIP + SKIP
-