mirror of
https://github.com/ankitects/anki.git
synced 2025-12-23 20:02:58 -05:00
Handle deeply nested OpChanges
Messages such as AddNotesResponse were not handled correctly.
This commit is contained in:
parent
74c727e82c
commit
7dc2d29136
4 changed files with 41 additions and 15 deletions
|
|
@ -78,6 +78,10 @@ message OpChangesOnly {
|
||||||
collection.OpChanges changes = 1;
|
collection.OpChanges changes = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message NestedOpChanges {
|
||||||
|
OpChangesOnly changes = 1;
|
||||||
|
}
|
||||||
|
|
||||||
message OpChangesWithCount {
|
message OpChangesWithCount {
|
||||||
OpChanges changes = 1;
|
OpChanges changes = 1;
|
||||||
uint32 count = 2;
|
uint32 count = 2;
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@ Preferences = config_pb2.Preferences
|
||||||
UndoStatus = collection_pb2.UndoStatus
|
UndoStatus = collection_pb2.UndoStatus
|
||||||
OpChanges = collection_pb2.OpChanges
|
OpChanges = collection_pb2.OpChanges
|
||||||
OpChangesOnly = collection_pb2.OpChangesOnly
|
OpChangesOnly = collection_pb2.OpChangesOnly
|
||||||
|
NestedOpChanges = collection_pb2.NestedOpChanges
|
||||||
OpChangesWithCount = collection_pb2.OpChangesWithCount
|
OpChangesWithCount = collection_pb2.OpChangesWithCount
|
||||||
OpChangesWithId = collection_pb2.OpChangesWithId
|
OpChangesWithId = collection_pb2.OpChangesWithId
|
||||||
OpChangesAfterUndo = collection_pb2.OpChangesAfterUndo
|
OpChangesAfterUndo = collection_pb2.OpChangesAfterUndo
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,13 @@ import aqt
|
||||||
import aqt.main
|
import aqt.main
|
||||||
import aqt.operations
|
import aqt.operations
|
||||||
from anki import frontend_pb2, generic_pb2, hooks
|
from anki import frontend_pb2, generic_pb2, hooks
|
||||||
from anki.collection import OpChanges, OpChangesOnly, Progress, SearchNode
|
from anki.collection import (
|
||||||
|
NestedOpChanges,
|
||||||
|
OpChanges,
|
||||||
|
OpChangesOnly,
|
||||||
|
Progress,
|
||||||
|
SearchNode,
|
||||||
|
)
|
||||||
from anki.decks import UpdateDeckConfigs
|
from anki.decks import UpdateDeckConfigs
|
||||||
from anki.scheduler.v3 import SchedulingStatesWithContext, SetSchedulingStatesRequest
|
from anki.scheduler.v3 import SchedulingStatesWithContext, SetSchedulingStatesRequest
|
||||||
from anki.utils import dev_mode, from_json_bytes, to_json_bytes
|
from anki.utils import dev_mode, from_json_bytes, to_json_bytes
|
||||||
|
|
@ -1001,16 +1007,19 @@ def raw_backend_request(endpoint: str) -> Callable[[], bytes]:
|
||||||
output = getattr(aqt.mw.col._backend, f"{endpoint}_raw")(request.data)
|
output = getattr(aqt.mw.col._backend, f"{endpoint}_raw")(request.data)
|
||||||
op_changes_type = int(request.headers.get("Anki-Op-Changes", "0"))
|
op_changes_type = int(request.headers.get("Anki-Op-Changes", "0"))
|
||||||
if op_changes_type:
|
if op_changes_type:
|
||||||
response: OpChanges | OpChangesOnly
|
op_message_types = (OpChanges, OpChangesOnly, NestedOpChanges)
|
||||||
if op_changes_type == 1:
|
try:
|
||||||
response = OpChanges()
|
response = op_message_types[op_changes_type - 1]()
|
||||||
else:
|
response.ParseFromString(output)
|
||||||
response = OpChangesOnly()
|
changes: Any = response
|
||||||
response.ParseFromString(output)
|
for _ in range(op_changes_type - 1):
|
||||||
|
changes = changes.changes
|
||||||
|
except IndexError:
|
||||||
|
raise ValueError(f"unhandled op changes level: {op_changes_type}")
|
||||||
|
|
||||||
def handle_on_main() -> None:
|
def handle_on_main() -> None:
|
||||||
handler = aqt.mw.app.activeWindow()
|
handler = aqt.mw.app.activeWindow()
|
||||||
on_op_finished(aqt.mw, response, handler)
|
on_op_finished(aqt.mw, changes, handler)
|
||||||
|
|
||||||
aqt.mw.taskman.run_on_main(handle_on_main)
|
aqt.mw.taskman.run_on_main(handle_on_main)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -101,6 +101,7 @@ enum OpChangesType {
|
||||||
None = 0,
|
None = 0,
|
||||||
OpChanges = 1,
|
OpChanges = 1,
|
||||||
OpChangesOnly = 2,
|
OpChangesOnly = 2,
|
||||||
|
NestedOpChanges = 3,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct MethodDetails {
|
struct MethodDetails {
|
||||||
|
|
@ -117,7 +118,8 @@ impl MethodDetails {
|
||||||
let input_type = full_name_to_imported_reference(method.proto.input().full_name());
|
let input_type = full_name_to_imported_reference(method.proto.input().full_name());
|
||||||
let output_type = full_name_to_imported_reference(method.proto.output().full_name());
|
let output_type = full_name_to_imported_reference(method.proto.output().full_name());
|
||||||
let comments = method.comments.clone();
|
let comments = method.comments.clone();
|
||||||
let op_changes_type = get_op_changes_type(&method.proto.output(), true);
|
let op_changes_type =
|
||||||
|
get_op_changes_type(&method.proto.output(), &method.proto.output(), 1);
|
||||||
Self {
|
Self {
|
||||||
method_name: name,
|
method_name: name,
|
||||||
input_type,
|
input_type,
|
||||||
|
|
@ -128,16 +130,26 @@ impl MethodDetails {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_op_changes_type(message: &MessageDescriptor, root: bool) -> OpChangesType {
|
fn get_op_changes_type(
|
||||||
|
root_message: &MessageDescriptor,
|
||||||
|
message: &MessageDescriptor,
|
||||||
|
level: u8,
|
||||||
|
) -> OpChangesType {
|
||||||
if message.full_name() == "anki.collection.OpChanges" {
|
if message.full_name() == "anki.collection.OpChanges" {
|
||||||
if root {
|
match level {
|
||||||
OpChangesType::OpChanges
|
0 => OpChangesType::None,
|
||||||
} else {
|
1 => OpChangesType::OpChanges,
|
||||||
OpChangesType::OpChangesOnly
|
2 => OpChangesType::OpChangesOnly,
|
||||||
|
3 => OpChangesType::NestedOpChanges,
|
||||||
|
_ => panic!(
|
||||||
|
"unhandled op changes level for message {}: {}",
|
||||||
|
root_message.full_name(),
|
||||||
|
level
|
||||||
|
),
|
||||||
}
|
}
|
||||||
} else if let Some(field) = message.get_field(1) {
|
} else if let Some(field) = message.get_field(1) {
|
||||||
if let Some(field_message) = field.kind().as_message() {
|
if let Some(field_message) = field.kind().as_message() {
|
||||||
get_op_changes_type(field_message, false)
|
get_op_changes_type(root_message, field_message, level + 1)
|
||||||
} else {
|
} else {
|
||||||
OpChangesType::None
|
OpChangesType::None
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue