mirror of
https://github.com/ankitects/anki.git
synced 2025-09-18 22:12:21 -04:00
nest progress messages and remove Python wrapper class
The progress messages are only really intended to be consumed by Anki. If consumption by add-ons was expected, we'd be better off keeping the wrapper, as the API for oneofs in Python is quite awkward to use.
This commit is contained in:
parent
f434cff36f
commit
c23b01978d
7 changed files with 58 additions and 112 deletions
|
@ -4,7 +4,6 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import copy
|
import copy
|
||||||
import enum
|
|
||||||
import os
|
import os
|
||||||
import pprint
|
import pprint
|
||||||
import re
|
import re
|
||||||
|
@ -12,7 +11,6 @@ import sys
|
||||||
import time
|
import time
|
||||||
import traceback
|
import traceback
|
||||||
import weakref
|
import weakref
|
||||||
from dataclasses import dataclass
|
|
||||||
from typing import Any, List, Optional, Sequence, Tuple, Union
|
from typing import Any, List, Optional, Sequence, Tuple, Union
|
||||||
|
|
||||||
import anki._backend.backend_pb2 as _pb
|
import anki._backend.backend_pb2 as _pb
|
||||||
|
@ -46,10 +44,7 @@ from anki.utils import (
|
||||||
|
|
||||||
# public exports
|
# public exports
|
||||||
SearchTerm = _pb.SearchTerm
|
SearchTerm = _pb.SearchTerm
|
||||||
MediaSyncProgress = _pb.MediaSyncProgress
|
Progress = _pb.Progress
|
||||||
FullSyncProgress = _pb.FullSyncProgress
|
|
||||||
NormalSyncProgress = _pb.NormalSyncProgress
|
|
||||||
DatabaseCheckProgress = _pb.DatabaseCheckProgress
|
|
||||||
Config = _pb.Config
|
Config = _pb.Config
|
||||||
EmptyCardsReport = _pb.EmptyCardsReport
|
EmptyCardsReport = _pb.EmptyCardsReport
|
||||||
NoteWithEmptyCards = _pb.NoteWithEmptyCards
|
NoteWithEmptyCards = _pb.NoteWithEmptyCards
|
||||||
|
@ -125,7 +120,7 @@ class Collection:
|
||||||
##########################################################################
|
##########################################################################
|
||||||
|
|
||||||
def latest_progress(self) -> Progress:
|
def latest_progress(self) -> Progress:
|
||||||
return Progress.from_proto(self._backend.latest_progress())
|
return self._backend.latest_progress()
|
||||||
|
|
||||||
# Scheduler
|
# Scheduler
|
||||||
##########################################################################
|
##########################################################################
|
||||||
|
@ -874,42 +869,5 @@ table.review-log {{ {revlog_style} }}
|
||||||
self._backend.set_preferences(prefs)
|
self._backend.set_preferences(prefs)
|
||||||
|
|
||||||
|
|
||||||
class ProgressKind(enum.Enum):
|
|
||||||
NoProgress = 0
|
|
||||||
MediaSync = 1
|
|
||||||
MediaCheck = 2
|
|
||||||
FullSync = 3
|
|
||||||
NormalSync = 4
|
|
||||||
DatabaseCheck = 5
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class Progress:
|
|
||||||
kind: ProgressKind
|
|
||||||
val: Union[
|
|
||||||
MediaSyncProgress,
|
|
||||||
FullSyncProgress,
|
|
||||||
NormalSyncProgress,
|
|
||||||
DatabaseCheckProgress,
|
|
||||||
str,
|
|
||||||
]
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def from_proto(proto: _pb.Progress) -> Progress:
|
|
||||||
kind = proto.WhichOneof("value")
|
|
||||||
if kind == "media_sync":
|
|
||||||
return Progress(kind=ProgressKind.MediaSync, val=proto.media_sync)
|
|
||||||
elif kind == "media_check":
|
|
||||||
return Progress(kind=ProgressKind.MediaCheck, val=proto.media_check)
|
|
||||||
elif kind == "full_sync":
|
|
||||||
return Progress(kind=ProgressKind.FullSync, val=proto.full_sync)
|
|
||||||
elif kind == "normal_sync":
|
|
||||||
return Progress(kind=ProgressKind.NormalSync, val=proto.normal_sync)
|
|
||||||
elif kind == "database_check":
|
|
||||||
return Progress(kind=ProgressKind.DatabaseCheck, val=proto.database_check)
|
|
||||||
else:
|
|
||||||
return Progress(kind=ProgressKind.NoProgress, val="")
|
|
||||||
|
|
||||||
|
|
||||||
# legacy name
|
# legacy name
|
||||||
_Collection = Collection
|
_Collection = Collection
|
||||||
|
|
|
@ -6,22 +6,20 @@ from __future__ import annotations
|
||||||
from concurrent.futures import Future
|
from concurrent.futures import Future
|
||||||
|
|
||||||
import aqt
|
import aqt
|
||||||
from anki.collection import DatabaseCheckProgress, ProgressKind
|
|
||||||
from aqt.qt import *
|
from aqt.qt import *
|
||||||
from aqt.utils import showText, tooltip
|
from aqt.utils import showText, tooltip
|
||||||
|
|
||||||
|
|
||||||
def on_progress(mw: aqt.main.AnkiQt) -> None:
|
def on_progress(mw: aqt.main.AnkiQt) -> None:
|
||||||
progress = mw.col.latest_progress()
|
progress = mw.col.latest_progress()
|
||||||
if progress.kind != ProgressKind.DatabaseCheck:
|
if not progress.HasField("database_check"):
|
||||||
return
|
return
|
||||||
|
dbprogress = progress.database_check
|
||||||
assert isinstance(progress.val, DatabaseCheckProgress)
|
|
||||||
mw.progress.update(
|
mw.progress.update(
|
||||||
process=False,
|
process=False,
|
||||||
label=progress.val.stage,
|
label=dbprogress.stage,
|
||||||
value=progress.val.stage_current,
|
value=dbprogress.stage_current,
|
||||||
max=progress.val.stage_total,
|
max=dbprogress.stage_total,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ from concurrent.futures import Future
|
||||||
from typing import Iterable, List, Optional, Sequence, TypeVar
|
from typing import Iterable, List, Optional, Sequence, TypeVar
|
||||||
|
|
||||||
import aqt
|
import aqt
|
||||||
from anki.collection import ProgressKind, SearchTerm
|
from anki.collection import SearchTerm
|
||||||
from anki.errors import Interrupted
|
from anki.errors import Interrupted
|
||||||
from anki.lang import TR
|
from anki.lang import TR
|
||||||
from anki.media import CheckMediaOut
|
from anki.media import CheckMediaOut
|
||||||
|
@ -62,11 +62,9 @@ class MediaChecker:
|
||||||
|
|
||||||
def _on_progress(self) -> None:
|
def _on_progress(self) -> None:
|
||||||
progress = self.mw.col.latest_progress()
|
progress = self.mw.col.latest_progress()
|
||||||
if progress.kind != ProgressKind.MediaCheck:
|
if not progress.HasField("media_check"):
|
||||||
return
|
return
|
||||||
|
label = progress.media_check
|
||||||
assert isinstance(progress.val, str)
|
|
||||||
val = progress.val
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if self.progress_dialog.wantCancel:
|
if self.progress_dialog.wantCancel:
|
||||||
|
@ -75,7 +73,7 @@ class MediaChecker:
|
||||||
# dialog may not be active
|
# dialog may not be active
|
||||||
pass
|
pass
|
||||||
|
|
||||||
self.mw.taskman.run_on_main(lambda: self.mw.progress.update(val))
|
self.mw.taskman.run_on_main(lambda: self.mw.progress.update(label=label))
|
||||||
|
|
||||||
def _check(self) -> CheckMediaOut:
|
def _check(self) -> CheckMediaOut:
|
||||||
"Run the check on a background thread."
|
"Run the check on a background thread."
|
||||||
|
|
|
@ -9,7 +9,7 @@ from dataclasses import dataclass
|
||||||
from typing import Any, Callable, List, Optional, Union
|
from typing import Any, Callable, List, Optional, Union
|
||||||
|
|
||||||
import aqt
|
import aqt
|
||||||
from anki.collection import MediaSyncProgress, ProgressKind
|
from anki.collection import Progress
|
||||||
from anki.errors import Interrupted, NetworkError
|
from anki.errors import Interrupted, NetworkError
|
||||||
from anki.lang import TR
|
from anki.lang import TR
|
||||||
from anki.types import assert_exhaustive
|
from anki.types import assert_exhaustive
|
||||||
|
@ -18,7 +18,7 @@ from aqt import gui_hooks
|
||||||
from aqt.qt import QDialog, QDialogButtonBox, QPushButton, QTextCursor, QTimer, qconnect
|
from aqt.qt import QDialog, QDialogButtonBox, QPushButton, QTextCursor, QTimer, qconnect
|
||||||
from aqt.utils import disable_help_button, showWarning, tr
|
from aqt.utils import disable_help_button, showWarning, tr
|
||||||
|
|
||||||
LogEntry = Union[MediaSyncProgress, str]
|
LogEntry = Union[Progress.MediaSync, str]
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
|
@ -37,11 +37,10 @@ class MediaSyncer:
|
||||||
|
|
||||||
def _on_progress(self) -> None:
|
def _on_progress(self) -> None:
|
||||||
progress = self.mw.col.latest_progress()
|
progress = self.mw.col.latest_progress()
|
||||||
if progress.kind != ProgressKind.MediaSync:
|
if not progress.HasField("media_sync"):
|
||||||
return
|
return
|
||||||
|
sync_progress = progress.media_sync
|
||||||
assert isinstance(progress.val, MediaSyncProgress)
|
self._log_and_notify(sync_progress)
|
||||||
self._log_and_notify(progress.val)
|
|
||||||
|
|
||||||
def start(self) -> None:
|
def start(self) -> None:
|
||||||
"Start media syncing in the background, if it's not already running."
|
"Start media syncing in the background, if it's not already running."
|
||||||
|
@ -202,13 +201,13 @@ class MediaSyncDialog(QDialog):
|
||||||
def _entry_to_text(self, entry: LogEntryWithTime) -> str:
|
def _entry_to_text(self, entry: LogEntryWithTime) -> str:
|
||||||
if isinstance(entry.entry, str):
|
if isinstance(entry.entry, str):
|
||||||
txt = entry.entry
|
txt = entry.entry
|
||||||
elif isinstance(entry.entry, MediaSyncProgress):
|
elif isinstance(entry.entry, Progress.MediaSync):
|
||||||
txt = self._logentry_to_text(entry.entry)
|
txt = self._logentry_to_text(entry.entry)
|
||||||
else:
|
else:
|
||||||
assert_exhaustive(entry.entry)
|
assert_exhaustive(entry.entry)
|
||||||
return self._time_and_text(entry.time, txt)
|
return self._time_and_text(entry.time, txt)
|
||||||
|
|
||||||
def _logentry_to_text(self, e: MediaSyncProgress) -> str:
|
def _logentry_to_text(self, e: Progress.MediaSync) -> str:
|
||||||
return f"{e.added}, {e.removed}, {e.checked}"
|
return f"{e.added}, {e.removed}, {e.checked}"
|
||||||
|
|
||||||
def _on_log_entry(self, entry: LogEntryWithTime) -> None:
|
def _on_log_entry(self, entry: LogEntryWithTime) -> None:
|
||||||
|
|
|
@ -9,7 +9,6 @@ from concurrent.futures import Future
|
||||||
from typing import Callable, Tuple
|
from typing import Callable, Tuple
|
||||||
|
|
||||||
import aqt
|
import aqt
|
||||||
from anki.collection import FullSyncProgress, NormalSyncProgress, ProgressKind
|
|
||||||
from anki.errors import Interrupted, SyncError
|
from anki.errors import Interrupted, SyncError
|
||||||
from anki.lang import TR, without_unicode_isolation
|
from anki.lang import TR, without_unicode_isolation
|
||||||
from anki.sync import SyncOutput, SyncStatus
|
from anki.sync import SyncOutput, SyncStatus
|
||||||
|
@ -73,15 +72,15 @@ def handle_sync_error(mw: aqt.main.AnkiQt, err: Exception) -> None:
|
||||||
|
|
||||||
def on_normal_sync_timer(mw: aqt.main.AnkiQt) -> None:
|
def on_normal_sync_timer(mw: aqt.main.AnkiQt) -> None:
|
||||||
progress = mw.col.latest_progress()
|
progress = mw.col.latest_progress()
|
||||||
if progress.kind != ProgressKind.NormalSync:
|
if not progress.HasField("normal_sync"):
|
||||||
return
|
return
|
||||||
|
sync_progress = progress.normal_sync
|
||||||
|
|
||||||
assert isinstance(progress.val, NormalSyncProgress)
|
|
||||||
mw.progress.update(
|
mw.progress.update(
|
||||||
label=f"{progress.val.added}\n{progress.val.removed}",
|
label=f"{sync_progress.added}\n{sync_progress.removed}",
|
||||||
process=False,
|
process=False,
|
||||||
)
|
)
|
||||||
mw.progress.set_title(progress.val.stage)
|
mw.progress.set_title(sync_progress.stage)
|
||||||
|
|
||||||
if mw.progress.want_cancel():
|
if mw.progress.want_cancel():
|
||||||
mw.col.abort_sync()
|
mw.col.abort_sync()
|
||||||
|
@ -153,17 +152,17 @@ def confirm_full_download(mw: aqt.main.AnkiQt, on_done: Callable[[], None]) -> N
|
||||||
|
|
||||||
def on_full_sync_timer(mw: aqt.main.AnkiQt) -> None:
|
def on_full_sync_timer(mw: aqt.main.AnkiQt) -> None:
|
||||||
progress = mw.col.latest_progress()
|
progress = mw.col.latest_progress()
|
||||||
if progress.kind != ProgressKind.FullSync:
|
if not progress.HasField("full_sync"):
|
||||||
return
|
return
|
||||||
|
sync_progress = progress.full_sync
|
||||||
|
|
||||||
assert isinstance(progress.val, FullSyncProgress)
|
if sync_progress.transferred == sync_progress.total:
|
||||||
if progress.val.transferred == progress.val.total:
|
|
||||||
label = tr(TR.SYNC_CHECKING)
|
label = tr(TR.SYNC_CHECKING)
|
||||||
else:
|
else:
|
||||||
label = None
|
label = None
|
||||||
mw.progress.update(
|
mw.progress.update(
|
||||||
value=progress.val.transferred,
|
value=sync_progress.transferred,
|
||||||
max=progress.val.total,
|
max=sync_progress.total,
|
||||||
process=False,
|
process=False,
|
||||||
label=label,
|
label=label,
|
||||||
)
|
)
|
||||||
|
|
|
@ -535,42 +535,36 @@ message SyncError {
|
||||||
///////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////
|
||||||
|
|
||||||
message Progress {
|
message Progress {
|
||||||
oneof value {
|
message MediaSync {
|
||||||
Empty none = 1;
|
|
||||||
MediaSyncProgress media_sync = 2;
|
|
||||||
string media_check = 3;
|
|
||||||
FullSyncProgress full_sync = 4;
|
|
||||||
NormalSyncProgress normal_sync = 5;
|
|
||||||
DatabaseCheckProgress database_check = 6;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
message MediaSyncProgress {
|
|
||||||
string checked = 1;
|
string checked = 1;
|
||||||
string added = 2;
|
string added = 2;
|
||||||
string removed = 3;
|
string removed = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
message FullSyncProgress {
|
message FullSync {
|
||||||
uint32 transferred = 1;
|
uint32 transferred = 1;
|
||||||
uint32 total = 2;
|
uint32 total = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
message MediaSyncUploadProgress {
|
message NormalSync {
|
||||||
uint32 files = 1;
|
|
||||||
uint32 deletions = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
message NormalSyncProgress {
|
|
||||||
string stage = 1;
|
string stage = 1;
|
||||||
string added = 2;
|
string added = 2;
|
||||||
string removed = 3;
|
string removed = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
message DatabaseCheckProgress {
|
message DatabaseCheck {
|
||||||
string stage = 1;
|
string stage = 1;
|
||||||
uint32 stage_total = 2;
|
uint32 stage_total = 2;
|
||||||
uint32 stage_current = 3;
|
uint32 stage_current = 3;
|
||||||
|
}
|
||||||
|
oneof value {
|
||||||
|
Empty none = 1;
|
||||||
|
MediaSync media_sync = 2;
|
||||||
|
string media_check = 3;
|
||||||
|
FullSync full_sync = 4;
|
||||||
|
NormalSync normal_sync = 5;
|
||||||
|
DatabaseCheck database_check = 6;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Messages
|
// Messages
|
||||||
|
|
|
@ -1898,7 +1898,7 @@ fn progress_to_proto(progress: Option<Progress>, i18n: &I18n) -> pb::Progress {
|
||||||
let s = i18n.trn(TR::MediaCheckChecked, tr_args!["count"=>n]);
|
let s = i18n.trn(TR::MediaCheckChecked, tr_args!["count"=>n]);
|
||||||
pb::progress::Value::MediaCheck(s)
|
pb::progress::Value::MediaCheck(s)
|
||||||
}
|
}
|
||||||
Progress::FullSync(p) => pb::progress::Value::FullSync(pb::FullSyncProgress {
|
Progress::FullSync(p) => pb::progress::Value::FullSync(pb::progress::FullSync {
|
||||||
transferred: p.transferred_bytes as u32,
|
transferred: p.transferred_bytes as u32,
|
||||||
total: p.total_bytes as u32,
|
total: p.total_bytes as u32,
|
||||||
}),
|
}),
|
||||||
|
@ -1919,7 +1919,7 @@ fn progress_to_proto(progress: Option<Progress>, i18n: &I18n) -> pb::Progress {
|
||||||
tr_args![
|
tr_args![
|
||||||
"up"=>p.local_remove, "down"=>p.remote_remove],
|
"up"=>p.local_remove, "down"=>p.remote_remove],
|
||||||
);
|
);
|
||||||
pb::progress::Value::NormalSync(pb::NormalSyncProgress {
|
pb::progress::Value::NormalSync(pb::progress::NormalSync {
|
||||||
stage,
|
stage,
|
||||||
added,
|
added,
|
||||||
removed,
|
removed,
|
||||||
|
@ -1940,7 +1940,7 @@ fn progress_to_proto(progress: Option<Progress>, i18n: &I18n) -> pb::Progress {
|
||||||
DatabaseCheckProgress::History => i18n.tr(TR::DatabaseCheckCheckingHistory),
|
DatabaseCheckProgress::History => i18n.tr(TR::DatabaseCheckCheckingHistory),
|
||||||
}
|
}
|
||||||
.to_string();
|
.to_string();
|
||||||
pb::progress::Value::DatabaseCheck(pb::DatabaseCheckProgress {
|
pb::progress::Value::DatabaseCheck(pb::progress::DatabaseCheck {
|
||||||
stage,
|
stage,
|
||||||
stage_current,
|
stage_current,
|
||||||
stage_total,
|
stage_total,
|
||||||
|
@ -1955,8 +1955,8 @@ fn progress_to_proto(progress: Option<Progress>, i18n: &I18n) -> pb::Progress {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn media_sync_progress(p: MediaSyncProgress, i18n: &I18n) -> pb::MediaSyncProgress {
|
fn media_sync_progress(p: MediaSyncProgress, i18n: &I18n) -> pb::progress::MediaSync {
|
||||||
pb::MediaSyncProgress {
|
pb::progress::MediaSync {
|
||||||
checked: i18n.trn(TR::SyncMediaCheckedCount, tr_args!["count"=>p.checked]),
|
checked: i18n.trn(TR::SyncMediaCheckedCount, tr_args!["count"=>p.checked]),
|
||||||
added: i18n.trn(
|
added: i18n.trn(
|
||||||
TR::SyncMediaAddedCount,
|
TR::SyncMediaAddedCount,
|
||||||
|
|
Loading…
Reference in a new issue