Merge pull request #1040 from RumovZ/deck-name-err
Catch deck rename errors and localise warnings
This commit is contained in:
commit
5564fd9e13
@ -1,3 +1,4 @@
|
|||||||
errors-invalid-input-empty = Invalid input.
|
errors-invalid-input-empty = Invalid input.
|
||||||
errors-invalid-input-details = Invalid input: { $details }
|
errors-invalid-input-details = Invalid input: { $details }
|
||||||
errors-parse-number-fail = A number was invalid or out of range.
|
errors-parse-number-fail = A number was invalid or out of range.
|
||||||
|
errors-filtered-parent-deck = Invalid deck name: Filtered decks cannot be parent decks.
|
||||||
|
@ -12,7 +12,7 @@ from typing import Any, Dict, Iterable, List, Optional, Sequence, Tuple, Union
|
|||||||
import anki # pylint: disable=unused-import
|
import anki # pylint: disable=unused-import
|
||||||
import anki._backend.backend_pb2 as _pb
|
import anki._backend.backend_pb2 as _pb
|
||||||
from anki.consts import *
|
from anki.consts import *
|
||||||
from anki.errors import DeckIsFilteredError, DeckRenameError, NotFoundError
|
from anki.errors import NotFoundError
|
||||||
from anki.utils import from_json_bytes, ids2str, intTime, to_json_bytes
|
from anki.utils import from_json_bytes, ids2str, intTime, to_json_bytes
|
||||||
|
|
||||||
# public exports
|
# public exports
|
||||||
@ -246,12 +246,9 @@ class DeckManager:
|
|||||||
|
|
||||||
def update(self, g: Deck, preserve_usn: bool = True) -> None:
|
def update(self, g: Deck, preserve_usn: bool = True) -> None:
|
||||||
"Add or update an existing deck. Used for syncing and merging."
|
"Add or update an existing deck. Used for syncing and merging."
|
||||||
try:
|
g["id"] = self.col._backend.add_or_update_deck_legacy(
|
||||||
g["id"] = self.col._backend.add_or_update_deck_legacy(
|
deck=to_json_bytes(g), preserve_usn_and_mtime=preserve_usn
|
||||||
deck=to_json_bytes(g), preserve_usn_and_mtime=preserve_usn
|
)
|
||||||
)
|
|
||||||
except DeckIsFilteredError as exc:
|
|
||||||
raise DeckRenameError("deck was filtered") from exc
|
|
||||||
|
|
||||||
def rename(self, g: Deck, newName: str) -> None:
|
def rename(self, g: Deck, newName: str) -> None:
|
||||||
"Rename deck prefix to NAME if not exists. Updates children."
|
"Rename deck prefix to NAME if not exists. Updates children."
|
||||||
|
@ -47,7 +47,15 @@ class ExistsError(Exception):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class DeckIsFilteredError(Exception):
|
class DeckRenameError(Exception):
|
||||||
|
"""Legacy error, use DeckIsFilteredError instead."""
|
||||||
|
|
||||||
|
def __init__(self, description: str, *args: object) -> None:
|
||||||
|
super().__init__(description, *args)
|
||||||
|
self.description = description
|
||||||
|
|
||||||
|
|
||||||
|
class DeckIsFilteredError(StringError, DeckRenameError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
@ -78,7 +86,7 @@ def backend_exception_to_pylib(err: _pb.BackendError) -> Exception:
|
|||||||
elif val == "exists":
|
elif val == "exists":
|
||||||
return ExistsError()
|
return ExistsError()
|
||||||
elif val == "deck_is_filtered":
|
elif val == "deck_is_filtered":
|
||||||
return DeckIsFilteredError()
|
return DeckIsFilteredError(err.localized)
|
||||||
elif val == "proto_error":
|
elif val == "proto_error":
|
||||||
return StringError(err.localized)
|
return StringError(err.localized)
|
||||||
else:
|
else:
|
||||||
@ -95,12 +103,3 @@ class AnkiError(Exception):
|
|||||||
|
|
||||||
def __str__(self) -> str:
|
def __str__(self) -> str:
|
||||||
return self.type
|
return self.type
|
||||||
|
|
||||||
|
|
||||||
class DeckRenameError(Exception):
|
|
||||||
def __init__(self, description: str) -> None:
|
|
||||||
super().__init__()
|
|
||||||
self.description = description
|
|
||||||
|
|
||||||
def __str__(self) -> str:
|
|
||||||
return f"Couldn't rename deck: {self.description}"
|
|
||||||
|
@ -9,7 +9,7 @@ from typing import Any
|
|||||||
|
|
||||||
import aqt
|
import aqt
|
||||||
from anki.decks import DeckTreeNode
|
from anki.decks import DeckTreeNode
|
||||||
from anki.errors import DeckRenameError
|
from anki.errors import DeckIsFilteredError
|
||||||
from anki.utils import intTime
|
from anki.utils import intTime
|
||||||
from aqt import AnkiQt, gui_hooks
|
from aqt import AnkiQt, gui_hooks
|
||||||
from aqt.qt import *
|
from aqt.qt import *
|
||||||
@ -88,11 +88,7 @@ class DeckBrowser:
|
|||||||
elif cmd == "import":
|
elif cmd == "import":
|
||||||
self.mw.onImport()
|
self.mw.onImport()
|
||||||
elif cmd == "create":
|
elif cmd == "create":
|
||||||
deck = getOnlyText(tr(TR.DECKS_NAME_FOR_DECK))
|
self._on_create()
|
||||||
if deck:
|
|
||||||
self.mw.col.decks.id(deck)
|
|
||||||
gui_hooks.sidebar_should_refresh_decks()
|
|
||||||
self.refresh()
|
|
||||||
elif cmd == "drag":
|
elif cmd == "drag":
|
||||||
source, target = arg.split(",")
|
source, target = arg.split(",")
|
||||||
self._handle_drag_and_drop(int(source), int(target or 0))
|
self._handle_drag_and_drop(int(source), int(target or 0))
|
||||||
@ -272,8 +268,8 @@ class DeckBrowser:
|
|||||||
try:
|
try:
|
||||||
self.mw.col.decks.rename(deck, newName)
|
self.mw.col.decks.rename(deck, newName)
|
||||||
gui_hooks.sidebar_should_refresh_decks()
|
gui_hooks.sidebar_should_refresh_decks()
|
||||||
except DeckRenameError as e:
|
except DeckIsFilteredError as err:
|
||||||
showWarning(e.description)
|
showWarning(str(err))
|
||||||
return
|
return
|
||||||
self.show()
|
self.show()
|
||||||
|
|
||||||
@ -352,6 +348,17 @@ class DeckBrowser:
|
|||||||
def _onShared(self) -> None:
|
def _onShared(self) -> None:
|
||||||
openLink(f"{aqt.appShared}decks/")
|
openLink(f"{aqt.appShared}decks/")
|
||||||
|
|
||||||
|
def _on_create(self) -> None:
|
||||||
|
deck = getOnlyText(tr(TR.DECKS_NAME_FOR_DECK))
|
||||||
|
if deck:
|
||||||
|
try:
|
||||||
|
self.mw.col.decks.id(deck)
|
||||||
|
except DeckIsFilteredError as err:
|
||||||
|
showWarning(str(err))
|
||||||
|
return
|
||||||
|
gui_hooks.sidebar_should_refresh_decks()
|
||||||
|
self.refresh()
|
||||||
|
|
||||||
######################################################################
|
######################################################################
|
||||||
|
|
||||||
def _v1_upgrade_message(self) -> str:
|
def _v1_upgrade_message(self) -> str:
|
||||||
|
@ -4,8 +4,8 @@ from typing import Callable, List, Optional, Tuple
|
|||||||
|
|
||||||
import aqt
|
import aqt
|
||||||
from anki.collection import SearchNode
|
from anki.collection import SearchNode
|
||||||
from anki.decks import Deck, DeckRenameError
|
from anki.decks import Deck
|
||||||
from anki.errors import InvalidInput
|
from anki.errors import DeckIsFilteredError, InvalidInput
|
||||||
from anki.lang import without_unicode_isolation
|
from anki.lang import without_unicode_isolation
|
||||||
from aqt import AnkiQt, colors, gui_hooks
|
from aqt import AnkiQt, colors, gui_hooks
|
||||||
from aqt.qt import *
|
from aqt.qt import *
|
||||||
@ -301,8 +301,8 @@ class DeckConf(QDialog):
|
|||||||
self.saveConf()
|
self.saveConf()
|
||||||
except InvalidInput as err:
|
except InvalidInput as err:
|
||||||
show_invalid_search_error(err)
|
show_invalid_search_error(err)
|
||||||
except DeckRenameError as err:
|
except DeckIsFilteredError as err:
|
||||||
showWarning(err.description)
|
showWarning(str(err))
|
||||||
else:
|
else:
|
||||||
if not self.col.sched.rebuild_filtered_deck(self.deck["id"]):
|
if not self.col.sched.rebuild_filtered_deck(self.deck["id"]):
|
||||||
if askUser(tr(TR.DECKS_THE_PROVIDED_SEARCH_DID_NOT_MATCH)):
|
if askUser(tr(TR.DECKS_THE_PROVIDED_SEARCH_DID_NOT_MATCH)):
|
||||||
|
@ -10,7 +10,7 @@ from typing import Any, Dict, Iterable, List, Optional, Sequence, Tuple, cast
|
|||||||
import aqt
|
import aqt
|
||||||
from anki.collection import Config, SearchNode
|
from anki.collection import Config, SearchNode
|
||||||
from anki.decks import DeckTreeNode
|
from anki.decks import DeckTreeNode
|
||||||
from anki.errors import DeckRenameError, InvalidInput
|
from anki.errors import DeckIsFilteredError, InvalidInput
|
||||||
from anki.tags import TagTreeNode
|
from anki.tags import TagTreeNode
|
||||||
from anki.types import assert_exhaustive
|
from anki.types import assert_exhaustive
|
||||||
from aqt import colors, gui_hooks
|
from aqt import colors, gui_hooks
|
||||||
@ -988,8 +988,8 @@ class SidebarTreeView(QTreeView):
|
|||||||
self.mw.checkpoint(tr(TR.ACTIONS_RENAME_DECK))
|
self.mw.checkpoint(tr(TR.ACTIONS_RENAME_DECK))
|
||||||
try:
|
try:
|
||||||
self.mw.col.decks.rename(deck, new_name)
|
self.mw.col.decks.rename(deck, new_name)
|
||||||
except DeckRenameError as e:
|
except DeckIsFilteredError as err:
|
||||||
showWarning(e.description)
|
showWarning(str(err))
|
||||||
return
|
return
|
||||||
self.refresh()
|
self.refresh()
|
||||||
self.mw.deckBrowser.refresh()
|
self.mw.deckBrowser.refresh()
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
from typing import List, Optional
|
from typing import List, Optional
|
||||||
|
|
||||||
import aqt
|
import aqt
|
||||||
|
from anki.errors import DeckIsFilteredError
|
||||||
from aqt import gui_hooks
|
from aqt import gui_hooks
|
||||||
from aqt.qt import *
|
from aqt.qt import *
|
||||||
from aqt.utils import (
|
from aqt.utils import (
|
||||||
@ -17,6 +18,7 @@ from aqt.utils import (
|
|||||||
saveGeom,
|
saveGeom,
|
||||||
shortcut,
|
shortcut,
|
||||||
showInfo,
|
showInfo,
|
||||||
|
showWarning,
|
||||||
tr,
|
tr,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -162,7 +164,11 @@ class StudyDeck(QDialog):
|
|||||||
n = getOnlyText(tr(TR.DECKS_NEW_DECK_NAME), default=default)
|
n = getOnlyText(tr(TR.DECKS_NEW_DECK_NAME), default=default)
|
||||||
n = n.strip()
|
n = n.strip()
|
||||||
if n:
|
if n:
|
||||||
did = self.mw.col.decks.id(n)
|
try:
|
||||||
|
did = self.mw.col.decks.id(n)
|
||||||
|
except DeckIsFilteredError as err:
|
||||||
|
showWarning(str(err))
|
||||||
|
return
|
||||||
# deck name may not be the same as user input. ex: ", ::
|
# deck name may not be the same as user input. ex: ", ::
|
||||||
self.name = self.mw.col.decks.name(did)
|
self.name = self.mw.col.decks.name(did)
|
||||||
# make sure we clean up reset hook when manually exiting
|
# make sure we clean up reset hook when manually exiting
|
||||||
|
@ -208,6 +208,7 @@ impl AnkiError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
AnkiError::ParseNumError => i18n.tr(TR::ErrorsParseNumberFail).into(),
|
AnkiError::ParseNumError => i18n.tr(TR::ErrorsParseNumberFail).into(),
|
||||||
|
AnkiError::DeckIsFiltered => i18n.tr(TR::ErrorsFilteredParentDeck).into(),
|
||||||
_ => format!("{:?}", self),
|
_ => format!("{:?}", self),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user