From 77741977a1cafae88c12e21dc30fc483deb302f8 Mon Sep 17 00:00:00 2001 From: Arthur Milchior Date: Mon, 6 Apr 2020 22:45:30 +0200 Subject: [PATCH 1/8] make _path static --- pylib/anki/decks.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pylib/anki/decks.py b/pylib/anki/decks.py index 4e980a5d7..0fb778f61 100644 --- a/pylib/anki/decks.py +++ b/pylib/anki/decks.py @@ -291,7 +291,8 @@ class DeckManager: ancestorPath = self._path(ancestorDeckName) return ancestorPath == self._path(descendantDeckName)[0 : len(ancestorPath)] - def _path(self, name: str) -> Any: + @staticmethod + def _path(name: str) -> Any: return name.split("::") def _basename(self, name: str) -> Any: From 5d55c4cda26028c2905ed6a4027942717ea0ef33 Mon Sep 17 00:00:00 2001 From: Arthur Milchior Date: Mon, 6 Apr 2020 22:23:31 +0200 Subject: [PATCH 2/8] Sort decks according to their paths Currently it's sorted alphabetically. Because of this, "A::B" appears between "A9" and "AA" in list of decks. --- pylib/anki/decks.py | 9 ++++++--- qt/aqt/studydeck.py | 6 +++++- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/pylib/anki/decks.py b/pylib/anki/decks.py index 0fb778f61..8bceb7346 100644 --- a/pylib/anki/decks.py +++ b/pylib/anki/decks.py @@ -5,7 +5,6 @@ from __future__ import annotations import copy import json -import operator import unicodedata from typing import Any, Dict, List, Optional, Set, Tuple, Union @@ -298,6 +297,10 @@ class DeckManager: def _basename(self, name: str) -> Any: return self._path(name)[-1] + @classmethod + def key(cls, deck: Dict[str, Any]) -> List[str]: + return cls._path(deck["name"]) + def _ensureParents(self, name: str) -> Any: "Ensure parents exist, and return name with case matching parents." s = "" @@ -455,7 +458,7 @@ class DeckManager: def _checkDeckTree(self) -> None: decks = self.col.decks.all() - decks.sort(key=operator.itemgetter("name")) + decks.sort(key=self.key) names: Set[str] = set() for deck in decks: @@ -571,7 +574,7 @@ class DeckManager: childMap = {} # go through all decks, sorted by name - for deck in sorted(self.all(), key=operator.itemgetter("name")): + for deck in sorted(self.all(), key=self.key): node: Dict[int, Any] = {} childMap[deck["id"]] = node diff --git a/qt/aqt/studydeck.py b/qt/aqt/studydeck.py index 1a024b7c4..00538a880 100644 --- a/qt/aqt/studydeck.py +++ b/qt/aqt/studydeck.py @@ -3,6 +3,7 @@ # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html import aqt +from anki.decks import DeckManager from anki.lang import _ from aqt import gui_hooks from aqt.qt import * @@ -51,7 +52,10 @@ class StudyDeck(QDialog): if title: self.setWindowTitle(title) if not names: - names = sorted(self.mw.col.decks.allNames(dyn=dyn, force_default=False)) + names = sorted( + self.mw.col.decks.allNames(dyn=dyn, force_default=False), + key=DeckManager._path, + ) self.nameFunc = None self.origNames = names else: From 266c2022b574431ba3a517fa248f8758de752b04 Mon Sep 17 00:00:00 2001 From: Arthur Milchior Date: Mon, 6 Apr 2020 22:16:49 +0200 Subject: [PATCH 3/8] uses _path where possible --- pylib/anki/decks.py | 12 ++++++------ pylib/anki/importing/anki2.py | 5 +++-- pylib/anki/sched.py | 3 ++- pylib/anki/schedv2.py | 5 +++-- pylib/anki/template.py | 3 ++- qt/aqt/browser.py | 3 ++- 6 files changed, 18 insertions(+), 13 deletions(-) diff --git a/pylib/anki/decks.py b/pylib/anki/decks.py index 8bceb7346..263906b41 100644 --- a/pylib/anki/decks.py +++ b/pylib/anki/decks.py @@ -126,7 +126,7 @@ class DeckManager: # child of an existing deck then it needs to be renamed deck = self.get(did) if "::" in deck["name"]: - base = deck["name"].split("::")[-1] + base = self._path(deck["name"])[-1] suffix = "" while True: # find an unused name @@ -469,14 +469,14 @@ class DeckManager: self.save(deck) # ensure no sections are blank - if not all(deck["name"].split("::")): + if not all(self._path(deck["name"])): self.col.log("fix deck with missing sections", deck["name"]) deck["name"] = "recovered%d" % intTime(1000) self.save(deck) # immediate parent must exist if "::" in deck["name"]: - immediateParent = "::".join(deck["name"].split("::")[:-1]) + immediateParent = "::".join(self._path(deck["name"])[:-1]) if immediateParent not in names: self.col.log("fix deck with missing parent", deck["name"]) self._ensureParents(deck["name"]) @@ -579,7 +579,7 @@ class DeckManager: childMap[deck["id"]] = node # add note to immediate parent - parts = deck["name"].split("::") + parts = self._path(deck["name"]) if len(parts) > 1: immediateParent = "::".join(parts[:-1]) pid = nameMap[immediateParent]["id"] @@ -591,7 +591,7 @@ class DeckManager: "All parents of did." # get parent and grandparent names parents: List[str] = [] - for part in self.get(did)["name"].split("::")[:-1]: + for part in self._path(self.get(did)["name"])[:-1]: if not parents: parents.append(part) else: @@ -609,7 +609,7 @@ class DeckManager: "All existing parents of name" if "::" not in name: return [] - names = name.split("::")[:-1] + names = self._path(name)[:-1] head = [] parents = [] diff --git a/pylib/anki/importing/anki2.py b/pylib/anki/importing/anki2.py index a43e0b13f..33a92fd58 100644 --- a/pylib/anki/importing/anki2.py +++ b/pylib/anki/importing/anki2.py @@ -7,6 +7,7 @@ from typing import Any, Dict, List, Optional, Tuple from anki.collection import _Collection from anki.consts import * +from anki.decks import DeckManager from anki.importing.base import Importer from anki.lang import _ from anki.storage import Collection @@ -257,13 +258,13 @@ class Anki2Importer(Importer): name = g["name"] # if there's a prefix, replace the top level deck if self.deckPrefix: - tmpname = "::".join(name.split("::")[1:]) + tmpname = "::".join(DeckManager._path(name)[1:]) name = self.deckPrefix if tmpname: name += "::" + tmpname # manually create any parents so we can pull in descriptions head = "" - for parent in name.split("::")[:-1]: + for parent in DeckManager._path(name)[:-1]: if head: head += "::" head += parent diff --git a/pylib/anki/sched.py b/pylib/anki/sched.py index 1e187e38d..3d79e1b69 100644 --- a/pylib/anki/sched.py +++ b/pylib/anki/sched.py @@ -14,6 +14,7 @@ import anki from anki import hooks from anki.cards import Card from anki.consts import * +from anki.decks import DeckManager from anki.schedv2 import Scheduler as V2 from anki.utils import ids2str, intTime @@ -153,7 +154,7 @@ class Scheduler(V2): data = [] def parent(name): - parts = name.split("::") + parts = DeckManager._path(name) if len(parts) < 2: return None parts = parts[:-1] diff --git a/pylib/anki/schedv2.py b/pylib/anki/schedv2.py index 75ab8b5d0..f787142b0 100644 --- a/pylib/anki/schedv2.py +++ b/pylib/anki/schedv2.py @@ -16,6 +16,7 @@ import anki # pylint: disable=unused-import from anki import hooks from anki.cards import Card from anki.consts import * +from anki.decks import DeckManager from anki.lang import _ from anki.rsbackend import FormatTimeSpanContext, SchedTimingToday from anki.utils import ids2str, intTime @@ -240,7 +241,7 @@ order by due""" data = [] def parent(name): - parts = name.split("::") + parts = DeckManager._path(name) if len(parts) < 2: return None parts = parts[:-1] @@ -279,7 +280,7 @@ order by due""" def _groupChildren(self, grps: List[List[Any]]) -> Any: # first, split the group names into components for g in grps: - g[0] = g[0].split("::") + g[0] = DeckManager._path(g[0]) # and sort based on those components grps.sort(key=itemgetter(0)) # then run main function diff --git a/pylib/anki/template.py b/pylib/anki/template.py index 97fde6699..06e198844 100644 --- a/pylib/anki/template.py +++ b/pylib/anki/template.py @@ -34,6 +34,7 @@ from typing import Any, Dict, List, Optional, Tuple import anki from anki import hooks from anki.cards import Card +from anki.decks import DeckManager from anki.models import NoteType from anki.notes import Note from anki.rsbackend import TemplateReplacementList @@ -153,7 +154,7 @@ def fields_for_rendering( fields["Tags"] = note.stringTags().strip() fields["Type"] = card.note_type()["name"] fields["Deck"] = col.decks.name(card.odid or card.did) - fields["Subdeck"] = fields["Deck"].split("::")[-1] + fields["Subdeck"] = DeckManager._path(fields["Deck"])[-1] fields["Card"] = card.template()["name"] flag = card.userFlag() fields["CardFlag"] = flag and f"flag{flag}" or "" diff --git a/qt/aqt/browser.py b/qt/aqt/browser.py index d68c2078a..2dbb60aeb 100644 --- a/qt/aqt/browser.py +++ b/qt/aqt/browser.py @@ -20,6 +20,7 @@ from anki import hooks from anki.cards import Card from anki.collection import _Collection from anki.consts import * +from anki.decks import DeckManager from anki.lang import _, ngettext from anki.models import NoteType from anki.notes import Note @@ -1302,7 +1303,7 @@ QTableView {{ gridline-color: {grid} }} def addDecks(parent, decks): for head, did, rev, lrn, new, children in decks: name = self.mw.col.decks.get(did)["name"] - shortname = name.split("::")[-1] + shortname = DeckManager._path(name)[-1] if children: subm = parent.addMenu(shortname) subm.addItem(_("Filter"), self._filterFunc("deck", name)) From 69a9425cd0e28ac2a60a982e88b9a16f02a3516b Mon Sep 17 00:00:00 2001 From: Arthur Milchior Date: Mon, 6 Apr 2020 23:02:28 +0200 Subject: [PATCH 4/8] replace _path by path (because it's not private here) --- pylib/anki/decks.py | 30 ++++++++++++++++-------------- pylib/anki/importing/anki2.py | 4 ++-- pylib/anki/sched.py | 2 +- pylib/anki/schedv2.py | 4 ++-- pylib/anki/template.py | 2 +- qt/aqt/browser.py | 2 +- 6 files changed, 23 insertions(+), 21 deletions(-) diff --git a/pylib/anki/decks.py b/pylib/anki/decks.py index 263906b41..24052084e 100644 --- a/pylib/anki/decks.py +++ b/pylib/anki/decks.py @@ -126,7 +126,7 @@ class DeckManager: # child of an existing deck then it needs to be renamed deck = self.get(did) if "::" in deck["name"]: - base = self._path(deck["name"])[-1] + base = self.path(deck["name"])[-1] suffix = "" while True: # find an unused name @@ -260,7 +260,7 @@ class DeckManager: ontoDeckName = self.get(ontoDeckDid)["name"] if ontoDeckDid is None or ontoDeckDid == "": - if len(self._path(draggedDeckName)) > 1: + if len(self.path(draggedDeckName)) > 1: self.rename(draggedDeck, self._basename(draggedDeckName)) elif self._canDragAndDrop(draggedDeckName, ontoDeckName): draggedDeck = self.get(draggedDeckDid) @@ -282,29 +282,31 @@ class DeckManager: return True def _isParent(self, parentDeckName: str, childDeckName: str) -> Any: - return self._path(childDeckName) == self._path(parentDeckName) + [ + return self.path(childDeckName) == self.path(parentDeckName) + [ self._basename(childDeckName) ] def _isAncestor(self, ancestorDeckName: str, descendantDeckName: str) -> Any: - ancestorPath = self._path(ancestorDeckName) - return ancestorPath == self._path(descendantDeckName)[0 : len(ancestorPath)] + ancestorPath = self.path(ancestorDeckName) + return ancestorPath == self.path(descendantDeckName)[0 : len(ancestorPath)] @staticmethod - def _path(name: str) -> Any: + def path(name: str) -> Any: return name.split("::") + _path = path + def _basename(self, name: str) -> Any: - return self._path(name)[-1] + return self.path(name)[-1] @classmethod def key(cls, deck: Dict[str, Any]) -> List[str]: - return cls._path(deck["name"]) + return cls.path(deck["name"]) def _ensureParents(self, name: str) -> Any: "Ensure parents exist, and return name with case matching parents." s = "" - path = self._path(name) + path = self.path(name) if len(path) < 2: return name for p in path[:-1]: @@ -469,14 +471,14 @@ class DeckManager: self.save(deck) # ensure no sections are blank - if not all(self._path(deck["name"])): + if not all(self.path(deck["name"])): self.col.log("fix deck with missing sections", deck["name"]) deck["name"] = "recovered%d" % intTime(1000) self.save(deck) # immediate parent must exist if "::" in deck["name"]: - immediateParent = "::".join(self._path(deck["name"])[:-1]) + immediateParent = "::".join(self.path(deck["name"])[:-1]) if immediateParent not in names: self.col.log("fix deck with missing parent", deck["name"]) self._ensureParents(deck["name"]) @@ -579,7 +581,7 @@ class DeckManager: childMap[deck["id"]] = node # add note to immediate parent - parts = self._path(deck["name"]) + parts = self.path(deck["name"]) if len(parts) > 1: immediateParent = "::".join(parts[:-1]) pid = nameMap[immediateParent]["id"] @@ -591,7 +593,7 @@ class DeckManager: "All parents of did." # get parent and grandparent names parents: List[str] = [] - for part in self._path(self.get(did)["name"])[:-1]: + for part in self.path(self.get(did)["name"])[:-1]: if not parents: parents.append(part) else: @@ -609,7 +611,7 @@ class DeckManager: "All existing parents of name" if "::" not in name: return [] - names = self._path(name)[:-1] + names = self.path(name)[:-1] head = [] parents = [] diff --git a/pylib/anki/importing/anki2.py b/pylib/anki/importing/anki2.py index 33a92fd58..3ab83098a 100644 --- a/pylib/anki/importing/anki2.py +++ b/pylib/anki/importing/anki2.py @@ -258,13 +258,13 @@ class Anki2Importer(Importer): name = g["name"] # if there's a prefix, replace the top level deck if self.deckPrefix: - tmpname = "::".join(DeckManager._path(name)[1:]) + tmpname = "::".join(DeckManager.path(name)[1:]) name = self.deckPrefix if tmpname: name += "::" + tmpname # manually create any parents so we can pull in descriptions head = "" - for parent in DeckManager._path(name)[:-1]: + for parent in DeckManager.path(name)[:-1]: if head: head += "::" head += parent diff --git a/pylib/anki/sched.py b/pylib/anki/sched.py index 3d79e1b69..272b0bf9c 100644 --- a/pylib/anki/sched.py +++ b/pylib/anki/sched.py @@ -154,7 +154,7 @@ class Scheduler(V2): data = [] def parent(name): - parts = DeckManager._path(name) + parts = DeckManager.path(name) if len(parts) < 2: return None parts = parts[:-1] diff --git a/pylib/anki/schedv2.py b/pylib/anki/schedv2.py index f787142b0..e437a4d4a 100644 --- a/pylib/anki/schedv2.py +++ b/pylib/anki/schedv2.py @@ -241,7 +241,7 @@ order by due""" data = [] def parent(name): - parts = DeckManager._path(name) + parts = DeckManager.path(name) if len(parts) < 2: return None parts = parts[:-1] @@ -280,7 +280,7 @@ order by due""" def _groupChildren(self, grps: List[List[Any]]) -> Any: # first, split the group names into components for g in grps: - g[0] = DeckManager._path(g[0]) + g[0] = DeckManager.path(g[0]) # and sort based on those components grps.sort(key=itemgetter(0)) # then run main function diff --git a/pylib/anki/template.py b/pylib/anki/template.py index 06e198844..5ed110441 100644 --- a/pylib/anki/template.py +++ b/pylib/anki/template.py @@ -154,7 +154,7 @@ def fields_for_rendering( fields["Tags"] = note.stringTags().strip() fields["Type"] = card.note_type()["name"] fields["Deck"] = col.decks.name(card.odid or card.did) - fields["Subdeck"] = DeckManager._path(fields["Deck"])[-1] + fields["Subdeck"] = DeckManager.path(fields["Deck"])[-1] fields["Card"] = card.template()["name"] flag = card.userFlag() fields["CardFlag"] = flag and f"flag{flag}" or "" diff --git a/qt/aqt/browser.py b/qt/aqt/browser.py index 2dbb60aeb..1b487bb07 100644 --- a/qt/aqt/browser.py +++ b/qt/aqt/browser.py @@ -1303,7 +1303,7 @@ QTableView {{ gridline-color: {grid} }} def addDecks(parent, decks): for head, did, rev, lrn, new, children in decks: name = self.mw.col.decks.get(did)["name"] - shortname = DeckManager._path(name)[-1] + shortname = DeckManager.path(name)[-1] if children: subm = parent.addMenu(shortname) subm.addItem(_("Filter"), self._filterFunc("deck", name)) From 5315b717c0359d6a0d7d6649ba4b574fcb5213bb Mon Sep 17 00:00:00 2001 From: Arthur Milchior Date: Mon, 6 Apr 2020 22:20:51 +0200 Subject: [PATCH 5/8] _basename used where possible --- pylib/anki/decks.py | 7 ++++--- pylib/anki/template.py | 2 +- qt/aqt/browser.py | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/pylib/anki/decks.py b/pylib/anki/decks.py index 24052084e..a62fb83cd 100644 --- a/pylib/anki/decks.py +++ b/pylib/anki/decks.py @@ -126,7 +126,7 @@ class DeckManager: # child of an existing deck then it needs to be renamed deck = self.get(did) if "::" in deck["name"]: - base = self.path(deck["name"])[-1] + base = self._basename(deck["name"]) suffix = "" while True: # find an unused name @@ -296,8 +296,9 @@ class DeckManager: _path = path - def _basename(self, name: str) -> Any: - return self.path(name)[-1] + @classmethod + def _basename(cls, name: str) -> Any: + return cls.path(name)[-1] @classmethod def key(cls, deck: Dict[str, Any]) -> List[str]: diff --git a/pylib/anki/template.py b/pylib/anki/template.py index 5ed110441..d98a1c2f8 100644 --- a/pylib/anki/template.py +++ b/pylib/anki/template.py @@ -154,7 +154,7 @@ def fields_for_rendering( fields["Tags"] = note.stringTags().strip() fields["Type"] = card.note_type()["name"] fields["Deck"] = col.decks.name(card.odid or card.did) - fields["Subdeck"] = DeckManager.path(fields["Deck"])[-1] + fields["Subdeck"] = DeckManager._basename(fields["Deck"]) fields["Card"] = card.template()["name"] flag = card.userFlag() fields["CardFlag"] = flag and f"flag{flag}" or "" diff --git a/qt/aqt/browser.py b/qt/aqt/browser.py index 1b487bb07..80b414c25 100644 --- a/qt/aqt/browser.py +++ b/qt/aqt/browser.py @@ -1303,7 +1303,7 @@ QTableView {{ gridline-color: {grid} }} def addDecks(parent, decks): for head, did, rev, lrn, new, children in decks: name = self.mw.col.decks.get(did)["name"] - shortname = DeckManager.path(name)[-1] + shortname = DeckManager._basename(name) if children: subm = parent.addMenu(shortname) subm.addItem(_("Filter"), self._filterFunc("deck", name)) From bda2935de16ac2da786a1c8bc2fb39cb86ff6e1f Mon Sep 17 00:00:00 2001 From: Arthur Milchior Date: Mon, 6 Apr 2020 23:05:27 +0200 Subject: [PATCH 6/8] _basename to basename, since it's not private in use --- pylib/anki/decks.py | 12 +++++++----- pylib/anki/template.py | 2 +- qt/aqt/browser.py | 2 +- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/pylib/anki/decks.py b/pylib/anki/decks.py index a62fb83cd..f76f1cb56 100644 --- a/pylib/anki/decks.py +++ b/pylib/anki/decks.py @@ -126,7 +126,7 @@ class DeckManager: # child of an existing deck then it needs to be renamed deck = self.get(did) if "::" in deck["name"]: - base = self._basename(deck["name"]) + base = self.basename(deck["name"]) suffix = "" while True: # find an unused name @@ -261,14 +261,14 @@ class DeckManager: if ontoDeckDid is None or ontoDeckDid == "": if len(self.path(draggedDeckName)) > 1: - self.rename(draggedDeck, self._basename(draggedDeckName)) + self.rename(draggedDeck, self.basename(draggedDeckName)) elif self._canDragAndDrop(draggedDeckName, ontoDeckName): draggedDeck = self.get(draggedDeckDid) draggedDeckName = draggedDeck["name"] ontoDeckName = self.get(ontoDeckDid)["name"] assert ontoDeckName.strip() self.rename( - draggedDeck, ontoDeckName + "::" + self._basename(draggedDeckName) + draggedDeck, ontoDeckName + "::" + self.basename(draggedDeckName) ) def _canDragAndDrop(self, draggedDeckName: str, ontoDeckName: str) -> bool: @@ -283,7 +283,7 @@ class DeckManager: def _isParent(self, parentDeckName: str, childDeckName: str) -> Any: return self.path(childDeckName) == self.path(parentDeckName) + [ - self._basename(childDeckName) + self.basename(childDeckName) ] def _isAncestor(self, ancestorDeckName: str, descendantDeckName: str) -> Any: @@ -297,9 +297,11 @@ class DeckManager: _path = path @classmethod - def _basename(cls, name: str) -> Any: + def basename(cls, name: str) -> Any: return cls.path(name)[-1] + _basename = basename + @classmethod def key(cls, deck: Dict[str, Any]) -> List[str]: return cls.path(deck["name"]) diff --git a/pylib/anki/template.py b/pylib/anki/template.py index d98a1c2f8..5b14d33f0 100644 --- a/pylib/anki/template.py +++ b/pylib/anki/template.py @@ -154,7 +154,7 @@ def fields_for_rendering( fields["Tags"] = note.stringTags().strip() fields["Type"] = card.note_type()["name"] fields["Deck"] = col.decks.name(card.odid or card.did) - fields["Subdeck"] = DeckManager._basename(fields["Deck"]) + fields["Subdeck"] = DeckManager.basename(fields["Deck"]) fields["Card"] = card.template()["name"] flag = card.userFlag() fields["CardFlag"] = flag and f"flag{flag}" or "" diff --git a/qt/aqt/browser.py b/qt/aqt/browser.py index 80b414c25..b107e2a08 100644 --- a/qt/aqt/browser.py +++ b/qt/aqt/browser.py @@ -1303,7 +1303,7 @@ QTableView {{ gridline-color: {grid} }} def addDecks(parent, decks): for head, did, rev, lrn, new, children in decks: name = self.mw.col.decks.get(did)["name"] - shortname = DeckManager._basename(name) + shortname = DeckManager.basename(name) if children: subm = parent.addMenu(shortname) subm.addItem(_("Filter"), self._filterFunc("deck", name)) From 285e9280cf571086a41168d527e1e58855944590 Mon Sep 17 00:00:00 2001 From: Arthur Milchior Date: Mon, 6 Apr 2020 22:55:28 +0200 Subject: [PATCH 7/8] immediate_parent_path --- pylib/anki/decks.py | 16 ++++++++++------ pylib/anki/importing/anki2.py | 2 +- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/pylib/anki/decks.py b/pylib/anki/decks.py index f76f1cb56..12724803a 100644 --- a/pylib/anki/decks.py +++ b/pylib/anki/decks.py @@ -302,6 +302,10 @@ class DeckManager: _basename = basename + @classmethod + def immediate_parent_path(cls, name: str) -> Any: + return cls._path(name)[:-1] + @classmethod def key(cls, deck: Dict[str, Any]) -> List[str]: return cls.path(deck["name"]) @@ -481,7 +485,7 @@ class DeckManager: # immediate parent must exist if "::" in deck["name"]: - immediateParent = "::".join(self.path(deck["name"])[:-1]) + immediateParent = "::".join(self.immediate_parent_path(deck["name"])) if immediateParent not in names: self.col.log("fix deck with missing parent", deck["name"]) self._ensureParents(deck["name"]) @@ -584,9 +588,9 @@ class DeckManager: childMap[deck["id"]] = node # add note to immediate parent - parts = self.path(deck["name"]) - if len(parts) > 1: - immediateParent = "::".join(parts[:-1]) + immediate_parent_path = self.immediate_parent_path(deck["name"]) + if immediate_parent_path: + immediateParent = "::".join(immediate_parent_path) pid = nameMap[immediateParent]["id"] childMap[pid][deck["id"]] = node @@ -596,7 +600,7 @@ class DeckManager: "All parents of did." # get parent and grandparent names parents: List[str] = [] - for part in self.path(self.get(did)["name"])[:-1]: + for part in self.immediate_parent_path(self.get(did)["name"]): if not parents: parents.append(part) else: @@ -614,7 +618,7 @@ class DeckManager: "All existing parents of name" if "::" not in name: return [] - names = self.path(name)[:-1] + names = self.immediate_parent_path(name) head = [] parents = [] diff --git a/pylib/anki/importing/anki2.py b/pylib/anki/importing/anki2.py index 3ab83098a..296b3b2c9 100644 --- a/pylib/anki/importing/anki2.py +++ b/pylib/anki/importing/anki2.py @@ -264,7 +264,7 @@ class Anki2Importer(Importer): name += "::" + tmpname # manually create any parents so we can pull in descriptions head = "" - for parent in DeckManager.path(name)[:-1]: + for parent in DeckManager.immediate_parent_path(name): if head: head += "::" head += parent From 64bb71e5bdea657605e7ffc600f636ecd24f7609 Mon Sep 17 00:00:00 2001 From: Arthur Milchior Date: Mon, 6 Apr 2020 23:00:54 +0200 Subject: [PATCH 8/8] immediate_parent --- pylib/anki/decks.py | 13 +++++++++---- pylib/anki/sched.py | 11 ++--------- pylib/anki/schedv2.py | 11 ++--------- 3 files changed, 13 insertions(+), 22 deletions(-) diff --git a/pylib/anki/decks.py b/pylib/anki/decks.py index 12724803a..755bc3ed6 100644 --- a/pylib/anki/decks.py +++ b/pylib/anki/decks.py @@ -306,6 +306,12 @@ class DeckManager: def immediate_parent_path(cls, name: str) -> Any: return cls._path(name)[:-1] + @classmethod + def immediate_parent(cls, name: str) -> Any: + pp = cls.immediate_parent_path(name) + if pp: + return "::".join(pp) + @classmethod def key(cls, deck: Dict[str, Any]) -> List[str]: return cls.path(deck["name"]) @@ -485,7 +491,7 @@ class DeckManager: # immediate parent must exist if "::" in deck["name"]: - immediateParent = "::".join(self.immediate_parent_path(deck["name"])) + immediateParent = self.immediate_parent(deck["name"]) if immediateParent not in names: self.col.log("fix deck with missing parent", deck["name"]) self._ensureParents(deck["name"]) @@ -588,9 +594,8 @@ class DeckManager: childMap[deck["id"]] = node # add note to immediate parent - immediate_parent_path = self.immediate_parent_path(deck["name"]) - if immediate_parent_path: - immediateParent = "::".join(immediate_parent_path) + immediateParent = self.immediate_parent(deck["name"]) + if immediateParent is not None: pid = nameMap[immediateParent]["id"] childMap[pid][deck["id"]] = node diff --git a/pylib/anki/sched.py b/pylib/anki/sched.py index 272b0bf9c..997227b38 100644 --- a/pylib/anki/sched.py +++ b/pylib/anki/sched.py @@ -153,18 +153,11 @@ class Scheduler(V2): lims: Dict[str, List[int]] = {} data = [] - def parent(name): - parts = DeckManager.path(name) - if len(parts) < 2: - return None - parts = parts[:-1] - return "::".join(parts) - for deck in decks: - p = parent(deck["name"]) + p = DeckManager.immediate_parent(deck["name"]) # new nlim = self._deckNewLimitSingle(deck) - if p: + if p is not None: nlim = min(nlim, lims[p][0]) new = self._newForDeck(deck["id"], nlim) # learning diff --git a/pylib/anki/schedv2.py b/pylib/anki/schedv2.py index e437a4d4a..b4ba43c56 100644 --- a/pylib/anki/schedv2.py +++ b/pylib/anki/schedv2.py @@ -240,19 +240,12 @@ order by due""" lims: Dict[str, List[int]] = {} data = [] - def parent(name): - parts = DeckManager.path(name) - if len(parts) < 2: - return None - parts = parts[:-1] - return "::".join(parts) - childMap = self.col.decks.childMap() for deck in decks: - p = parent(deck["name"]) + p = DeckManager.immediate_parent(deck["name"]) # new nlim = self._deckNewLimitSingle(deck) - if p: + if p is not None: nlim = min(nlim, lims[p][0]) new = self._newForDeck(deck["id"], nlim) # learning