Merge pull request #352 from Arthur-Milchior/correctCaseInRename
Ensure that even childless deck's name is considered independtly of the case
This commit is contained in:
commit
ea9e564b66
@ -135,9 +135,9 @@ class DeckManager:
|
|||||||
type = defaultDeck
|
type = defaultDeck
|
||||||
name = name.replace('"', '')
|
name = name.replace('"', '')
|
||||||
name = unicodedata.normalize("NFC", name)
|
name = unicodedata.normalize("NFC", name)
|
||||||
for id, g in list(self.decks.items()):
|
deck = self.byName(name)
|
||||||
if unicodedata.normalize("NFC", g['name'].lower()) == name.lower():
|
if deck:
|
||||||
return int(id)
|
return int(deck["id"])
|
||||||
if not create:
|
if not create:
|
||||||
return None
|
return None
|
||||||
g = copy.deepcopy(type)
|
g = copy.deepcopy(type)
|
||||||
@ -242,9 +242,9 @@ class DeckManager:
|
|||||||
return self.decks['1']
|
return self.decks['1']
|
||||||
|
|
||||||
def byName(self, name):
|
def byName(self, name):
|
||||||
"Get deck with NAME."
|
"""Get deck with NAME, ignoring cases."""
|
||||||
for m in list(self.decks.values()):
|
for m in list(self.decks.values()):
|
||||||
if m['name'] == name:
|
if self.equalName(m['name'], name):
|
||||||
return m
|
return m
|
||||||
|
|
||||||
def update(self, g):
|
def update(self, g):
|
||||||
@ -257,7 +257,7 @@ class DeckManager:
|
|||||||
def rename(self, g, newName):
|
def rename(self, g, newName):
|
||||||
"Rename deck prefix to NAME if not exists. Updates children."
|
"Rename deck prefix to NAME if not exists. Updates children."
|
||||||
# make sure target node doesn't already exist
|
# make sure target node doesn't already exist
|
||||||
if newName in self.allNames():
|
if self.byName(newName):
|
||||||
raise DeckRenameError(_("That deck already exists."))
|
raise DeckRenameError(_("That deck already exists."))
|
||||||
# make sure we're not nesting under a filtered deck
|
# make sure we're not nesting under a filtered deck
|
||||||
for p in self.parentsByName(newName):
|
for p in self.parentsByName(newName):
|
||||||
@ -454,7 +454,7 @@ class DeckManager:
|
|||||||
|
|
||||||
for deck in decks:
|
for deck in decks:
|
||||||
# two decks with the same name?
|
# two decks with the same name?
|
||||||
if deck['name'] in names:
|
if self.normalizeName(deck['name']) in names:
|
||||||
self.col.log("fix duplicate deck name", deck['name'])
|
self.col.log("fix duplicate deck name", deck['name'])
|
||||||
deck['name'] += "%d" % intTime(1000)
|
deck['name'] += "%d" % intTime(1000)
|
||||||
self.save(deck)
|
self.save(deck)
|
||||||
@ -468,12 +468,12 @@ class DeckManager:
|
|||||||
# immediate parent must exist
|
# immediate parent must exist
|
||||||
if "::" in deck['name']:
|
if "::" in deck['name']:
|
||||||
immediateParent = "::".join(deck['name'].split("::")[:-1])
|
immediateParent = "::".join(deck['name'].split("::")[:-1])
|
||||||
if immediateParent not in names:
|
if self.normalizeName(immediateParent) not in names:
|
||||||
self.col.log("fix deck with missing parent", deck['name'])
|
self.col.log("fix deck with missing parent", deck['name'])
|
||||||
self._ensureParents(deck['name'])
|
self._ensureParents(deck['name'])
|
||||||
names.add(immediateParent)
|
names.add(self.normalizeName(immediateParent))
|
||||||
|
|
||||||
names.add(deck['name'])
|
names.add(self.normalizeName(deck['name']))
|
||||||
|
|
||||||
def checkIntegrity(self):
|
def checkIntegrity(self):
|
||||||
self._recoverOrphans()
|
self._recoverOrphans()
|
||||||
@ -600,3 +600,11 @@ class DeckManager:
|
|||||||
|
|
||||||
def isDyn(self, did):
|
def isDyn(self, did):
|
||||||
return self.get(did)['dyn']
|
return self.get(did)['dyn']
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def normalizeName(name):
|
||||||
|
return unicodedata.normalize("NFC", name.lower())
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def equalName(name1, name2):
|
||||||
|
return DeckManager.normalizeName(name1) == DeckManager.normalizeName(name2)
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
# coding: utf-8
|
# coding: utf-8
|
||||||
|
|
||||||
|
from anki.errors import DeckRenameError
|
||||||
from tests.shared import assertException, getEmptyCol
|
from tests.shared import assertException, getEmptyCol
|
||||||
|
|
||||||
def test_basic():
|
def test_basic():
|
||||||
@ -87,6 +88,20 @@ def test_rename():
|
|||||||
d.decks.rename(d.decks.get(id), "yo")
|
d.decks.rename(d.decks.get(id), "yo")
|
||||||
for n in "yo", "yo::two", "yo::two::three":
|
for n in "yo", "yo::two", "yo::two::three":
|
||||||
assert n in d.decks.allNames()
|
assert n in d.decks.allNames()
|
||||||
|
# over filtered
|
||||||
|
filteredId = d.decks.newDyn("filtered")
|
||||||
|
filtered = d.decks.get(filteredId)
|
||||||
|
childId = d.decks.id("child")
|
||||||
|
child = d.decks.get(childId)
|
||||||
|
assertException(DeckRenameError, lambda: d.decks.rename(child, "filtered::child"))
|
||||||
|
assertException(DeckRenameError, lambda: d.decks.rename(child, "FILTERED::child"))
|
||||||
|
# changing case
|
||||||
|
parentId = d.decks.id("PARENT")
|
||||||
|
d.decks.id("PARENT::CHILD")
|
||||||
|
assertException(DeckRenameError, lambda: d.decks.rename(child, "PARENT::CHILD"))
|
||||||
|
assertException(DeckRenameError, lambda: d.decks.rename(child, "PARENT::child"))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def test_renameForDragAndDrop():
|
def test_renameForDragAndDrop():
|
||||||
d = getEmptyCol()
|
d = getEmptyCol()
|
||||||
@ -130,6 +145,27 @@ def test_renameForDragAndDrop():
|
|||||||
d.decks.renameForDragAndDrop(chinese_did, None)
|
d.decks.renameForDragAndDrop(chinese_did, None)
|
||||||
assert deckNames() == [ 'Chinese', 'Chinese::HSK', 'Languages' ]
|
assert deckNames() == [ 'Chinese', 'Chinese::HSK', 'Languages' ]
|
||||||
|
|
||||||
|
# can't drack a deck where sibling have same name
|
||||||
|
new_hsk_did = d.decks.id("HSK")
|
||||||
|
assertException(DeckRenameError, lambda: d.decks.renameForDragAndDrop(new_hsk_did, chinese_did))
|
||||||
|
d.decks.rem(new_hsk_did)
|
||||||
|
|
||||||
|
# can't drack a deck where sibling have same name different case
|
||||||
|
new_hsk_did = d.decks.id("hsk")
|
||||||
|
assertException(DeckRenameError, lambda: d.decks.renameForDragAndDrop(new_hsk_did, chinese_did))
|
||||||
|
d.decks.rem(new_hsk_did)
|
||||||
|
|
||||||
# '' is a convenient alias for the top level DID
|
# '' is a convenient alias for the top level DID
|
||||||
d.decks.renameForDragAndDrop(hsk_did, '')
|
d.decks.renameForDragAndDrop(hsk_did, '')
|
||||||
assert deckNames() == [ 'Chinese', 'HSK', 'Languages' ]
|
assert deckNames() == [ 'Chinese', 'HSK', 'Languages' ]
|
||||||
|
|
||||||
|
def test_check():
|
||||||
|
d = getEmptyCol()
|
||||||
|
|
||||||
|
foo_did = d.decks.id("foo")
|
||||||
|
FOO_did = d.decks.id("bar")
|
||||||
|
FOO = d.decks.byName("bar")
|
||||||
|
FOO["name"] = "FOO"
|
||||||
|
d.decks.save(FOO)
|
||||||
|
d.decks._checkDeckTree()
|
||||||
|
assert "foo" not in d.decks.allNames() or "FOO" not in d.decks.allNames()
|
||||||
|
Loading…
Reference in New Issue
Block a user