Editor: Do not allow creating multiple new files whose names differ only by case. Fixes #1664027 [error when renaming a similar filename in the files browser from the editor](https://bugs.launchpad.net/calibre/+bug/1664027)

This commit is contained in:
Kovid Goyal 2017-02-13 16:42:20 +05:30
parent 0489816b68
commit 3b8fc2066c

View File

@ -326,9 +326,9 @@ class Container(ContainerBase): # {{{
if '..' in name: if '..' in name:
raise ValueError('Names are not allowed to have .. in them') raise ValueError('Names are not allowed to have .. in them')
href = self.name_to_href(name, self.opf_name) href = self.name_to_href(name, self.opf_name)
if self.has_name(name) or self.manifest_has_name(name): if self.has_name_case_insensitive(name) or self.manifest_has_name(name):
if not modify_name_if_needed: if not modify_name_if_needed:
raise ValueError(('A file with the name %s already exists' % name) if self.has_name(name) else raise ValueError(('A file with the name %s already exists' % name) if self.has_name_case_insensitive(name) else
('An item with the href %s already exists in the manifest' % href)) ('An item with the href %s already exists in the manifest' % href))
base, ext = name.rpartition('.')[::2] base, ext = name.rpartition('.')[::2]
c = 0 c = 0
@ -336,7 +336,7 @@ class Container(ContainerBase): # {{{
c += 1 c += 1
q = '%s-%d.%s' % (base, c, ext) q = '%s-%d.%s' % (base, c, ext)
href = self.name_to_href(q, self.opf_name) href = self.name_to_href(q, self.opf_name)
if not self.has_name(q) and not self.manifest_has_name(q): if not self.has_name_case_insensitive(q) and not self.manifest_has_name(q):
name = q name = q
break break
path = self.name_to_abspath(name) path = self.name_to_abspath(name)
@ -508,6 +508,15 @@ class Container(ContainerBase): # {{{
''' Return True iff a file with the same canonical name as that specified exists. Unlike :meth:`exists` this method is always case-sensitive. ''' ''' Return True iff a file with the same canonical name as that specified exists. Unlike :meth:`exists` this method is always case-sensitive. '''
return name and name in self.name_path_map return name and name in self.name_path_map
def has_name_case_insensitive(self, name):
if not name:
return False
name = name.lower()
for q in self.name_path_map:
if q.lower() == name:
return True
return False
def relpath(self, path, base=None): def relpath(self, path, base=None):
'''Convert an absolute path (with os separators) to a path relative to '''Convert an absolute path (with os separators) to a path relative to
base (defaults to self.root). The relative path is *not* a name. Use base (defaults to self.root). The relative path is *not* a name. Use