mirror of
https://github.com/ankitects/anki.git
synced 2025-11-07 05:07:10 -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;
|
||||
}
|
||||
|
||||
message NestedOpChanges {
|
||||
OpChangesOnly changes = 1;
|
||||
}
|
||||
|
||||
message OpChangesWithCount {
|
||||
OpChanges changes = 1;
|
||||
uint32 count = 2;
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ Preferences = config_pb2.Preferences
|
|||
UndoStatus = collection_pb2.UndoStatus
|
||||
OpChanges = collection_pb2.OpChanges
|
||||
OpChangesOnly = collection_pb2.OpChangesOnly
|
||||
NestedOpChanges = collection_pb2.NestedOpChanges
|
||||
OpChangesWithCount = collection_pb2.OpChangesWithCount
|
||||
OpChangesWithId = collection_pb2.OpChangesWithId
|
||||
OpChangesAfterUndo = collection_pb2.OpChangesAfterUndo
|
||||
|
|
|
|||
|
|
@ -30,7 +30,13 @@ import aqt
|
|||
import aqt.main
|
||||
import aqt.operations
|
||||
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.scheduler.v3 import SchedulingStatesWithContext, SetSchedulingStatesRequest
|
||||
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)
|
||||
op_changes_type = int(request.headers.get("Anki-Op-Changes", "0"))
|
||||
if op_changes_type:
|
||||
response: OpChanges | OpChangesOnly
|
||||
if op_changes_type == 1:
|
||||
response = OpChanges()
|
||||
else:
|
||||
response = OpChangesOnly()
|
||||
response.ParseFromString(output)
|
||||
op_message_types = (OpChanges, OpChangesOnly, NestedOpChanges)
|
||||
try:
|
||||
response = op_message_types[op_changes_type - 1]()
|
||||
response.ParseFromString(output)
|
||||
changes: Any = response
|
||||
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:
|
||||
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)
|
||||
|
||||
|
|
|
|||
|
|
@ -101,6 +101,7 @@ enum OpChangesType {
|
|||
None = 0,
|
||||
OpChanges = 1,
|
||||
OpChangesOnly = 2,
|
||||
NestedOpChanges = 3,
|
||||
}
|
||||
|
||||
struct MethodDetails {
|
||||
|
|
@ -117,7 +118,8 @@ impl MethodDetails {
|
|||
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 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 {
|
||||
method_name: name,
|
||||
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 root {
|
||||
OpChangesType::OpChanges
|
||||
} else {
|
||||
OpChangesType::OpChangesOnly
|
||||
match level {
|
||||
0 => OpChangesType::None,
|
||||
1 => OpChangesType::OpChanges,
|
||||
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) {
|
||||
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 {
|
||||
OpChangesType::None
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue