From 26a8ac1425e6c892f7686589e29bb4142c0338da Mon Sep 17 00:00:00 2001 From: Ozzie Isaacs Date: Sat, 5 Feb 2022 09:06:14 +0100 Subject: [PATCH] Mass rename author before last stage --- cps/editbooks.py | 24 ++++--- cps/gdriveutils.py | 46 +++---------- cps/helper.py | 136 +++++++++++++++++++++----------------- optional-requirements.txt | 2 +- 4 files changed, 103 insertions(+), 105 deletions(-) diff --git a/cps/editbooks.py b/cps/editbooks.py index 21561766..16e29535 100755 --- a/cps/editbooks.py +++ b/cps/editbooks.py @@ -82,7 +82,6 @@ def search_objects_remove(db_book_object, db_type, input_elements): type_elements = c_elements.name for inp_element in input_elements: if inp_element.lower() == type_elements.lower(): - # if inp_element == type_elements: found = True break # if the element was not found in the new list, add it to remove list @@ -132,7 +131,6 @@ def add_objects(db_book_object, db_object, db_session, db_type, add_elements): # check if a element with that name exists db_element = db_session.query(db_object).filter(db_filter == add_element).first() # if no element is found add it - # if new_element is None: if db_type == 'author': new_element = db_object(add_element, helper.get_sorted_author(add_element.replace('|', ',')), "") elif db_type == 'series': @@ -1067,12 +1065,22 @@ def upload(): book_id = db_book.id title = db_book.title # ToDo this currently doesn't work -> integrate in update_dir_structure_gdrive - error = helper.update_dir_structure_file(book_id, - config.config_calibre_dir, - input_authors[0], - meta.file_path, - title_dir + meta.extension.lower(), - renamed_author=renamed_authors) + if config.config_use_google_drive: + file_name = helper.get_valid_filename(title, chars=42) + \ + ' - ' + helper.get_valid_filename(input_authors[0], chars=42) +\ + meta.extension.lower() + + gdrive_path = os.path.join(helper.get_valid_filename(input_authors[0], chars=96), + title_dir + " (" + str(book_id) + ")", + file_name) + gdriveutils.uploadFileToEbooksFolder(gdrive_path.replace("\\", "/"), meta.file_path) + else: + error = helper.update_dir_structure(book_id, + config.config_calibre_dir, + input_authors[0], + meta.file_path, + title_dir + meta.extension.lower(), + renamed_author=renamed_authors) move_coverfile(meta, db_book) diff --git a/cps/gdriveutils.py b/cps/gdriveutils.py index de3fbb64..eae175a0 100644 --- a/cps/gdriveutils.py +++ b/cps/gdriveutils.py @@ -35,10 +35,10 @@ except ImportError: from sqlalchemy.exc import OperationalError, InvalidRequestError from sqlalchemy.sql.expression import text -try: - from six import __version__ as six_version -except ImportError: - six_version = "not installed" +#try: +# from six import __version__ as six_version +#except ImportError: +# six_version = "not installed" try: from httplib2 import __version__ as httplib2_version except ImportError: @@ -355,30 +355,6 @@ def downloadFile(path, filename, output): f = getFileFromEbooksFolder(path, filename) f.GetContentFile(output) -'''def renameGdriveFolderRemote(origin_file, target_folder): - drive = getDrive(Gdrive.Instance().drive) - previous_parents = ",".join([parent["id"] for parent in origin_file.get('parents')]) - children = drive.auth.service.children().list(folderId=previous_parents).execute() - gFileTargetDir = getFileFromEbooksFolder(None, target_folder) - if not gFileTargetDir or gFileTargetDir['title'] != target_folder: - # Folder is not existing, rename folder - drive.auth.service.files().patch(fileId=origin_file['id'], - body={'title': target_folder}, - fields='title').execute() - # gFileTargetDir = drive.CreateFile( - # {'title': target_folder, 'parents': [{"kind": "drive#fileLink", 'id': getEbooksFolderId()}], - # "mimeType": "application/vnd.google-apps.folder"}) - # gFileTargetDir.Upload() - else: - # Move the file to the new folder - drive.auth.service.files().update(fileId=origin_file['id'], - addParents=gFileTargetDir['id'], - removeParents=previous_parents, - fields='id, parents').execute() - # if previous_parents has no children anymore, delete original fileparent - if len(children['items']) == 1: - deleteDatabaseEntry(previous_parents) - drive.auth.service.files().delete(fileId=previous_parents).execute()''' def moveGdriveFolderRemote(origin_file, target_folder): drive = getDrive(Gdrive.Instance().drive) @@ -454,24 +430,24 @@ def uploadFileToEbooksFolder(destFile, f): splitDir = destFile.split('/') for i, x in enumerate(splitDir): if i == len(splitDir)-1: - existingFiles = drive.ListFile({'q': "title = '%s' and '%s' in parents and trashed = false" % + existing_Files = drive.ListFile({'q': "title = '%s' and '%s' in parents and trashed = false" % (x.replace("'", r"\'"), parent['id'])}).GetList() - if len(existingFiles) > 0: - driveFile = existingFiles[0] + if len(existing_Files) > 0: + driveFile = existing_Files[0] else: driveFile = drive.CreateFile({'title': x, 'parents': [{"kind": "drive#fileLink", 'id': parent['id']}], }) driveFile.SetContentFile(f) driveFile.Upload() else: - existingFolder = drive.ListFile({'q': "title = '%s' and '%s' in parents and trashed = false" % + existing_Folder = drive.ListFile({'q': "title = '%s' and '%s' in parents and trashed = false" % (x.replace("'", r"\'"), parent['id'])}).GetList() - if len(existingFolder) == 0: + if len(existing_Folder) == 0: parent = drive.CreateFile({'title': x, 'parents': [{"kind": "drive#fileLink", 'id': parent['id']}], "mimeType": "application/vnd.google-apps.folder"}) parent.Upload() else: - parent = existingFolder[0] + parent = existing_Folder[0] def watchChange(drive, channel_id, channel_type, channel_address, @@ -713,5 +689,5 @@ def get_error_text(client_secrets=None): def get_versions(): - return {'six': six_version, + return { # 'six': six_version, 'httplib2': httplib2_version} diff --git a/cps/helper.py b/cps/helper.py index 26cca79c..ac538665 100644 --- a/cps/helper.py +++ b/cps/helper.py @@ -369,13 +369,13 @@ def clean_author_database(renamed_author, calibrepath, local_book=None, gdrive=N # Moves files in file storage during author/title rename, or from temp dir to file storage -def update_dir_structure_file(book_id, calibrepath, first_author, orignal_filepath, db_filename, renamed_author): +def update_dir_structure_file(book_id, calibre_path, first_author, original_filepath, db_filename, renamed_author): # get book database entry from id, if original path overwrite source with original_filepath localbook = calibre_db.get_book(book_id) - if orignal_filepath: - path = orignal_filepath + if original_filepath: + path = original_filepath else: - path = os.path.join(calibrepath, localbook.path) + path = os.path.join(calibre_path, localbook.path) # Create (current) authordir and titledir from database authordir = localbook.path.split('/')[0] @@ -389,10 +389,10 @@ def update_dir_structure_file(book_id, calibrepath, first_author, orignal_filepa new_author = calibre_db.session.query(db.Authors).filter(db.Authors.name == r).first() old_author_dir = get_valid_filename(r, chars=96) new_author_rename_dir = get_valid_filename(new_author.name, chars=96) - if os.path.isdir(os.path.join(calibrepath, old_author_dir)): + if os.path.isdir(os.path.join(calibre_path, old_author_dir)): try: - old_author_path = os.path.join(calibrepath, old_author_dir) - new_author_path = os.path.join(calibrepath, new_author_rename_dir) + old_author_path = os.path.join(calibre_path, old_author_dir) + new_author_path = os.path.join(calibre_path, new_author_rename_dir) shutil.move(os.path.normcase(old_author_path), os.path.normcase(new_author_path)) except (OSError) as ex: log.error("Rename author from: %s to %s: %s", old_author_path, new_author_path, ex) @@ -400,48 +400,72 @@ def update_dir_structure_file(book_id, calibrepath, first_author, orignal_filepa return _("Rename author from: '%(src)s' to '%(dest)s' failed with error: %(error)s", src=old_author_path, dest=new_author_path, error=str(ex)) if first_author.lower() in [r.lower() for r in renamed_author]: - if os.path.isdir(os.path.join(calibrepath, new_authordir)): - path = os.path.join(calibrepath, new_authordir, titledir) + if os.path.isdir(os.path.join(calibre_path, new_authordir)): + path = os.path.join(calibre_path, new_authordir, titledir) else: new_authordir = get_valid_filename(localbook.authors[0].name, chars=96) new_titledir = get_valid_filename(localbook.title, chars=96) + " (" + str(book_id) + ")" - if titledir != new_titledir or authordir != new_authordir or orignal_filepath: - new_path = os.path.join(calibrepath, new_authordir, new_titledir) - new_name = get_valid_filename(localbook.title, chars=96) + ' - ' + new_authordir - try: - if orignal_filepath: - if not os.path.isdir(new_path): - os.makedirs(new_path) - shutil.move(os.path.normcase(orignal_filepath), os.path.normcase(os.path.join(new_path, db_filename))) - log.debug("Moving title: %s to %s/%s", orignal_filepath, new_path, new_name) - else: - # Check new path is not valid path - if not os.path.exists(new_path): - # move original path to new path - log.debug("Moving title: %s to %s", path, new_path) - shutil.move(os.path.normcase(path), os.path.normcase(new_path)) - else: # path is valid copy only files to new location (merge) - log.info("Moving title: %s into existing: %s", path, new_path) - # Take all files and subfolder from old path (strange command) - for dir_name, __, file_list in os.walk(path): - for file in file_list: - shutil.move(os.path.normcase(os.path.join(dir_name, file)), - os.path.normcase(os.path.join(new_path + dir_name[len(path):], file))) - # change location in database to new author/title path - localbook.path = os.path.join(new_authordir, new_titledir).replace('\\','/') - except (OSError) as ex: - log.error("Rename title from: %s to %s: %s", path, new_path, ex) - log.debug(ex, exc_info=True) - return _("Rename title from: '%(src)s' to '%(dest)s' failed with error: %(error)s", - src=path, dest=new_path, error=str(ex)) + if titledir != new_titledir or authordir != new_authordir or original_filepath: + error = move_files_on_change(calibre_path, + new_authordir, + new_titledir, + localbook, + db_filename, + original_filepath, + path) + if error: + return error # Rename all files from old names to new names + return rename_files_on_change(first_author, renamed_author, localbook, original_filepath, path, calibre_path) + + +def move_files_on_change(calibre_path, new_authordir, new_titledir, localbook, db_filename, original_filepath, path): + new_path = os.path.join(calibre_path, new_authordir, new_titledir) + new_name = get_valid_filename(localbook.title, chars=96) + ' - ' + new_authordir try: - clean_author_database(renamed_author, calibrepath) + if original_filepath: + if not os.path.isdir(new_path): + os.makedirs(new_path) + shutil.move(os.path.normcase(original_filepath), os.path.normcase(os.path.join(new_path, db_filename))) + log.debug("Moving title: %s to %s/%s", original_filepath, new_path, new_name) + else: + # Check new path is not valid path + if not os.path.exists(new_path): + # move original path to new path + log.debug("Moving title: %s to %s", path, new_path) + shutil.move(os.path.normcase(path), os.path.normcase(new_path)) + else: # path is valid copy only files to new location (merge) + log.info("Moving title: %s into existing: %s", path, new_path) + # Take all files and subfolder from old path (strange command) + for dir_name, __, file_list in os.walk(path): + for file in file_list: + shutil.move(os.path.normcase(os.path.join(dir_name, file)), + os.path.normcase(os.path.join(new_path + dir_name[len(path):], file))) + # change location in database to new author/title path + localbook.path = os.path.join(new_authordir, new_titledir).replace('\\','/') + except OSError as ex: + log.error("Rename title from: %s to %s: %s", path, new_path, ex) + log.debug(ex, exc_info=True) + return _("Rename title from: '%(src)s' to '%(dest)s' failed with error: %(error)s", + src=path, dest=new_path, error=str(ex)) + return False + + +def rename_files_on_change(first_author, + renamed_author, + localbook, + orignal_filepath="", + path="", + calibre_path="", + gdrive=False): + # Rename all files from old names to new names + try: + clean_author_database(renamed_author, calibre_path, gdrive) if first_author and first_author not in renamed_author: - clean_author_database([first_author], calibrepath, localbook) - if not renamed_author and not orignal_filepath and len(os.listdir(os.path.dirname(path))) == 0: + clean_author_database([first_author], calibre_path, localbook, gdrive) + if not gdrive and not renamed_author and not orignal_filepath and len(os.listdir(os.path.dirname(path))) == 0: shutil.rmtree(os.path.dirname(path)) except (OSError, FileNotFoundError) as ex: log.error("Error in rename file in path %s", ex) @@ -449,6 +473,7 @@ def update_dir_structure_file(book_id, calibrepath, first_author, orignal_filepa return _("Error in rename file in path: %(error)s", error=str(ex)) return False + def update_dir_structure_gdrive(book_id, first_author, renamed_author): error = False book = calibre_db.get_book(book_id) @@ -457,16 +482,12 @@ def update_dir_structure_gdrive(book_id, first_author, renamed_author): if first_author: new_authordir = get_valid_filename(first_author, chars=96) for r in renamed_author: - # Todo: Rename all authors on gdrive new_author = calibre_db.session.query(db.Authors).filter(db.Authors.name == r).first() old_author_dir = get_valid_filename(r, chars=96) new_author_rename_dir = get_valid_filename(new_author.name, chars=96) gFile = gd.getFileFromEbooksFolder(None, old_author_dir) if gFile: gd.moveGdriveFolderRemote(gFile, new_author_rename_dir) - # author is always co-author and has is never author, no folder is okay - #else: - # error = _(u'File %(file)s not found on Google Drive', file=authordir) # file not found else: new_authordir = get_valid_filename(book.authors[0].name, chars=96) @@ -476,8 +497,7 @@ def update_dir_structure_gdrive(book_id, first_author, renamed_author): if titledir != new_titledir: gFile = gd.getFileFromEbooksFolder(os.path.dirname(book.path), titledir) if gFile: - gFile['title'] = new_titledir - gFile.Upload() + gd.moveGdriveFileRemote(gFile, new_titledir) book.path = book.path.split('/')[0] + u'/' + new_titledir gd.updateDatabaseOnEdit(gFile['id'], book.path) # only child folder affected else: @@ -494,15 +514,9 @@ def update_dir_structure_gdrive(book_id, first_author, renamed_author): # change location in database to new author/title path book.path = os.path.join(new_authordir, new_titledir).replace('\\', '/') - - # Rename all files from old names to new names - clean_author_database(renamed_author, "", gdrive=True) - if first_author not in renamed_author: - clean_author_database([first_author], "", book, gdrive=True) - + error |= rename_files_on_change(first_author, renamed_author, book, gdrive=True) return error - def delete_book_gdrive(book, book_format): error = None if book_format: @@ -582,19 +596,19 @@ def valid_email(email): def update_dir_structure(book_id, - calibrepath, - first_author=None, - orignal_filepath=None, - db_filename=None, - renamed_author=None): + calibre_path, + first_author=None, # change author of book to this author + original_filepath=None, + db_filename=None, + renamed_author=None): renamed_author = renamed_author or [] if config.config_use_google_drive: return update_dir_structure_gdrive(book_id, first_author, renamed_author) else: return update_dir_structure_file(book_id, - calibrepath, + calibre_path, first_author, - orignal_filepath, + original_filepath, db_filename, renamed_author) diff --git a/optional-requirements.txt b/optional-requirements.txt index 5de006fe..2370bc7e 100644 --- a/optional-requirements.txt +++ b/optional-requirements.txt @@ -10,7 +10,7 @@ pyasn1>=0.1.9,<0.5.0 PyDrive2>=1.3.1,<1.11.0 PyYAML>=3.12 rsa>=3.4.2,<4.9.0 -six>=1.10.0,<1.17.0 +# six>=1.10.0,<1.17.0 # Gmail google-auth-oauthlib>=0.4.3,<0.5.0