mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
newdb: Shorten filenames correctly
Ensure that the total path length is <= PATH_LIMIT * 4 and that no component is longer than PATH_LIMIT on unix.
This commit is contained in:
parent
7cf205f0c7
commit
ff8ecb1d56
@ -1056,25 +1056,31 @@ class DB(object):
|
||||
'''
|
||||
Construct the directory name for this book based on its metadata.
|
||||
'''
|
||||
author = ascii_filename(author
|
||||
)[:self.PATH_LIMIT].decode('ascii', 'replace')
|
||||
title = ascii_filename(title
|
||||
)[:self.PATH_LIMIT].decode('ascii', 'replace')
|
||||
book_id = ' (%d)' % book_id
|
||||
l = self.PATH_LIMIT - (len(book_id) // 2) - 2
|
||||
author = ascii_filename(author)[:l].decode('ascii', 'replace')
|
||||
title = ascii_filename(title)[:l].decode('ascii', 'replace')
|
||||
while author[-1] in (' ', '.'):
|
||||
author = author[:-1]
|
||||
if not author:
|
||||
author = ascii_filename(_('Unknown')).decode(
|
||||
'ascii', 'replace')
|
||||
return '%s/%s (%d)'%(author, title, book_id)
|
||||
return '%s/%s%s' % (author, title, book_id)
|
||||
|
||||
def construct_file_name(self, book_id, title, author):
|
||||
def construct_file_name(self, book_id, title, author, extlen):
|
||||
'''
|
||||
Construct the file name for this book based on its metadata.
|
||||
'''
|
||||
author = ascii_filename(author
|
||||
)[:self.PATH_LIMIT].decode('ascii', 'replace')
|
||||
title = ascii_filename(title
|
||||
)[:self.PATH_LIMIT].decode('ascii', 'replace')
|
||||
extlen = max(extlen, 14) # 14 accounts for ORIGINAL_EPUB
|
||||
# The PATH_LIMIT on windows already takes into account the doubling
|
||||
# (it is used to enforce the total path length limit, individual path
|
||||
# components can be much longer than the total path length would allow on
|
||||
# windows).
|
||||
l = (self.PATH_LIMIT - (extlen // 2) - 2) if iswindows else ((self.PATH_LIMIT - extlen - 2) // 2)
|
||||
if l < 5:
|
||||
raise ValueError('Extension length too long: %d' % extlen)
|
||||
author = ascii_filename(author)[:l].decode('ascii', 'replace')
|
||||
title = ascii_filename(title)[:l].decode('ascii', 'replace')
|
||||
name = title + ' - ' + author
|
||||
while name.endswith('.'):
|
||||
name = name[:-1]
|
||||
@ -1331,9 +1337,9 @@ class DB(object):
|
||||
wam.close_handles()
|
||||
|
||||
def add_format(self, book_id, fmt, stream, title, author, path):
|
||||
fname = self.construct_file_name(book_id, title, author)
|
||||
path = os.path.join(self.library_path, path)
|
||||
fmt = ('.' + fmt.lower()) if fmt else ''
|
||||
fname = self.construct_file_name(book_id, title, author, len(fmt))
|
||||
path = os.path.join(self.library_path, path)
|
||||
dest = os.path.join(path, fname + fmt)
|
||||
if not os.path.exists(path):
|
||||
os.makedirs(path)
|
||||
@ -1352,7 +1358,11 @@ class DB(object):
|
||||
path = self.construct_path_name(book_id, title, author)
|
||||
current_path = path_field.for_book(book_id, default_value='')
|
||||
formats = formats_field.for_book(book_id, default_value=())
|
||||
fname = self.construct_file_name(book_id, title, author)
|
||||
try:
|
||||
extlen = max(len(fmt) for fmt in formats) + 1
|
||||
except ValueError:
|
||||
extlen = 10
|
||||
fname = self.construct_file_name(book_id, title, author, extlen)
|
||||
# Check if the metadata used to construct paths has changed
|
||||
changed = False
|
||||
for fmt in formats:
|
||||
|
@ -97,3 +97,12 @@ class FilesystemTest(BaseTest):
|
||||
self.assertEqual(all_ids, cache.all_book_ids())
|
||||
cache.backend.close()
|
||||
|
||||
def test_long_filenames(self):
|
||||
' Test long file names '
|
||||
cache = self.init_cache()
|
||||
cache.set_field('title', {1:'a'*10000})
|
||||
self.assertLessEqual(len(cache.field_for('path', 1)), cache.backend.PATH_LIMIT * 2)
|
||||
cache.set_field('authors', {1:'b'*10000})
|
||||
self.assertLessEqual(len(cache.field_for('path', 1)), cache.backend.PATH_LIMIT * 2)
|
||||
fpath = cache.format_abspath(1, cache.formats(1)[0])
|
||||
self.assertLessEqual(len(fpath), len(cache.backend.library_path) + cache.backend.PATH_LIMIT * 4)
|
||||
|
Loading…
x
Reference in New Issue
Block a user