Save to disk: Do not limit the total path length to 240 characters on non-Windows platforms. Fixes #2038238 [file and folder names garbled if too long in "save to disk".](https://bugs.launchpad.net/calibre/+bug/2038238)

This commit is contained in:
Kovid Goyal 2023-10-04 13:46:15 +05:30
parent 1daa020a4f
commit 2a6158e05e
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
3 changed files with 9 additions and 7 deletions

View File

@ -1707,7 +1707,7 @@ class DB:
# Ensure that the file has the same case as dest # Ensure that the file has the same case as dest
try: try:
os.rename(path, dest) os.rename(path, dest)
except: except OSError:
pass # Nothing too catastrophic happened, the cases mismatch, that's all pass # Nothing too catastrophic happened, the cases mismatch, that's all
else: else:
if use_hardlink: if use_hardlink:
@ -1716,7 +1716,7 @@ class DB:
return True return True
except: except:
pass pass
with open(path, 'rb') as f, open(dest, 'wb') as d: with open(path, 'rb') as f, open(make_long_path_useable(dest), 'wb') as d:
shutil.copyfileobj(f, d) shutil.copyfileobj(f, d)
return True return True

View File

@ -10,7 +10,7 @@ import re
import traceback import traceback
from calibre import prints, sanitize_file_name, strftime from calibre import prints, sanitize_file_name, strftime
from calibre.constants import DEBUG, preferred_encoding from calibre.constants import DEBUG, iswindows, preferred_encoding
from calibre.db.errors import NoSuchFormat from calibre.db.errors import NoSuchFormat
from calibre.db.lazy import FormatsList from calibre.db.lazy import FormatsList
from calibre.ebooks.metadata import fmt_sidx, title_sort from calibre.ebooks.metadata import fmt_sidx, title_sort
@ -342,13 +342,13 @@ def do_save_book_to_disk(db, book_id, mi, plugboards,
cdata = db.cover(book_id) cdata = db.cover(book_id)
if cdata: if cdata:
cpath = base_path + '.jpg' cpath = base_path + '.jpg'
with open(cpath, 'wb') as f: with open(make_long_path_useable(cpath), 'wb') as f:
f.write(cdata) f.write(cdata)
mi.cover = base_name+'.jpg' mi.cover = base_name+'.jpg'
if opts.write_opf: if opts.write_opf:
from calibre.ebooks.metadata.opf2 import metadata_to_opf from calibre.ebooks.metadata.opf2 import metadata_to_opf
opf = metadata_to_opf(mi) opf = metadata_to_opf(mi)
with open(base_path+'.opf', 'wb') as f: with open(make_long_path_useable(base_path+'.opf'), 'wb') as f:
f.write(opf) f.write(opf)
finally: finally:
mi.cover, mi.pubdate, mi.timestamp = originals mi.cover, mi.pubdate, mi.timestamp = originals
@ -372,7 +372,7 @@ def do_save_book_to_disk(db, book_id, mi, plugboards,
except NoSuchFormat: except NoSuchFormat:
continue continue
if opts.update_metadata: if opts.update_metadata:
with open(fmt_path, 'r+b') as stream: with open(make_long_path_useable(fmt_path), 'r+b') as stream:
update_metadata(mi, fmt, stream, plugboards, cdata) update_metadata(mi, fmt, stream, plugboards, cdata)
return not formats_written, book_id, mi.title return not formats_written, book_id, mi.title
@ -384,7 +384,8 @@ def sanitize_args(root, opts):
root = os.path.abspath(root) root = os.path.abspath(root)
opts.template = preprocess_template(opts.template) opts.template = preprocess_template(opts.template)
length = 240 length = 255 if iswindows else 1024
length -= 15
length -= len(root) length -= len(root)
if length < 5: if length < 5:
raise ValueError('%r is too long.'%root) raise ValueError('%r is too long.'%root)

View File

@ -442,6 +442,7 @@ class WindowsAtomicFolderMove:
def hardlink_file(src, dest): def hardlink_file(src, dest):
src, dest = make_long_path_useable(src), make_long_path_useable(dest)
if iswindows: if iswindows:
windows_hardlink(src, dest) windows_hardlink(src, dest)
return return