mirror of
https://github.com/ankitects/anki.git
synced 2025-09-21 23:42:23 -04:00
split out sync, search, scheduler & config
This commit is contained in:
parent
9e0a295ab9
commit
35b059ecdb
29 changed files with 675 additions and 617 deletions
|
@ -7,7 +7,6 @@ package anki.backend;
|
||||||
|
|
||||||
import "anki/generic.proto";
|
import "anki/generic.proto";
|
||||||
import "anki/cards.proto";
|
import "anki/cards.proto";
|
||||||
import "anki/decks.proto";
|
|
||||||
import "anki/collection.proto";
|
import "anki/collection.proto";
|
||||||
import "anki/notes.proto";
|
import "anki/notes.proto";
|
||||||
import "anki/notetypes.proto";
|
import "anki/notetypes.proto";
|
||||||
|
@ -19,12 +18,12 @@ import "anki/notetypes.proto";
|
||||||
/// that information is not available in prost, so we define an enum to make
|
/// that information is not available in prost, so we define an enum to make
|
||||||
/// sure all clients agree on the service index
|
/// sure all clients agree on the service index
|
||||||
enum ServiceIndex {
|
enum ServiceIndex {
|
||||||
SERVICE_INDEX_SCHEDULING = 0;
|
SERVICE_INDEX_SCHEDULER = 0;
|
||||||
SERVICE_INDEX_DECKS = 1;
|
SERVICE_INDEX_DECKS = 1;
|
||||||
SERVICE_INDEX_NOTES = 2;
|
SERVICE_INDEX_NOTES = 2;
|
||||||
SERVICE_INDEX_SYNC = 3;
|
SERVICE_INDEX_SYNC = 3;
|
||||||
SERVICE_INDEX_NOTETYPES = 4;
|
SERVICE_INDEX_NOTETYPES = 4;
|
||||||
SERVICE_INDEX_CONFIG = 5;
|
SERVICE_INDEX_CONFIGS = 5;
|
||||||
SERVICE_INDEX_CARD_RENDERING = 6;
|
SERVICE_INDEX_CARD_RENDERING = 6;
|
||||||
SERVICE_INDEX_DECK_CONFIG = 7;
|
SERVICE_INDEX_DECK_CONFIG = 7;
|
||||||
SERVICE_INDEX_TAGS = 8;
|
SERVICE_INDEX_TAGS = 8;
|
||||||
|
@ -36,61 +35,6 @@ enum ServiceIndex {
|
||||||
SERVICE_INDEX_CARDS = 14;
|
SERVICE_INDEX_CARDS = 14;
|
||||||
}
|
}
|
||||||
|
|
||||||
service SchedulingService {
|
|
||||||
rpc SchedTimingToday(generic.Empty) returns (SchedTimingTodayResponse);
|
|
||||||
rpc StudiedToday(generic.Empty) returns (generic.String);
|
|
||||||
rpc StudiedTodayMessage(StudiedTodayMessageRequest) returns (generic.String);
|
|
||||||
rpc UpdateStats(UpdateStatsRequest) returns (generic.Empty);
|
|
||||||
rpc ExtendLimits(ExtendLimitsRequest) returns (generic.Empty);
|
|
||||||
rpc CountsForDeckToday(decks.DeckId) returns (CountsForDeckTodayResponse);
|
|
||||||
rpc CongratsInfo(generic.Empty) returns (CongratsInfoResponse);
|
|
||||||
rpc RestoreBuriedAndSuspendedCards(cards.CardIds)
|
|
||||||
returns (collection.OpChanges);
|
|
||||||
rpc UnburyDeck(UnburyDeckRequest) returns (collection.OpChanges);
|
|
||||||
rpc BuryOrSuspendCards(BuryOrSuspendCardsRequest)
|
|
||||||
returns (collection.OpChangesWithCount);
|
|
||||||
rpc EmptyFilteredDeck(decks.DeckId) returns (collection.OpChanges);
|
|
||||||
rpc RebuildFilteredDeck(decks.DeckId) returns (collection.OpChangesWithCount);
|
|
||||||
rpc ScheduleCardsAsNew(ScheduleCardsAsNewRequest)
|
|
||||||
returns (collection.OpChanges);
|
|
||||||
rpc SetDueDate(SetDueDateRequest) returns (collection.OpChanges);
|
|
||||||
rpc SortCards(SortCardsRequest) returns (collection.OpChangesWithCount);
|
|
||||||
rpc SortDeck(SortDeckRequest) returns (collection.OpChangesWithCount);
|
|
||||||
rpc GetNextCardStates(cards.CardId) returns (NextCardStates);
|
|
||||||
rpc DescribeNextStates(NextCardStates) returns (generic.StringList);
|
|
||||||
rpc StateIsLeech(SchedulingState) returns (generic.Bool);
|
|
||||||
rpc AnswerCard(CardAnswer) returns (collection.OpChanges);
|
|
||||||
rpc UpgradeScheduler(generic.Empty) returns (generic.Empty);
|
|
||||||
rpc GetQueuedCards(GetQueuedCardsRequest) returns (QueuedCards);
|
|
||||||
}
|
|
||||||
|
|
||||||
service SyncService {
|
|
||||||
rpc SyncMedia(SyncAuth) returns (generic.Empty);
|
|
||||||
rpc AbortSync(generic.Empty) returns (generic.Empty);
|
|
||||||
rpc AbortMediaSync(generic.Empty) returns (generic.Empty);
|
|
||||||
rpc BeforeUpload(generic.Empty) returns (generic.Empty);
|
|
||||||
rpc SyncLogin(SyncLoginRequest) returns (SyncAuth);
|
|
||||||
rpc SyncStatus(SyncAuth) returns (SyncStatusResponse);
|
|
||||||
rpc SyncCollection(SyncAuth) returns (SyncCollectionResponse);
|
|
||||||
rpc FullUpload(SyncAuth) returns (generic.Empty);
|
|
||||||
rpc FullDownload(SyncAuth) returns (generic.Empty);
|
|
||||||
rpc SyncServerMethod(SyncServerMethodRequest) returns (generic.Json);
|
|
||||||
}
|
|
||||||
|
|
||||||
service ConfigService {
|
|
||||||
rpc GetConfigJson(generic.String) returns (generic.Json);
|
|
||||||
rpc SetConfigJson(SetConfigJsonRequest) returns (collection.OpChanges);
|
|
||||||
rpc SetConfigJsonNoUndo(SetConfigJsonRequest) returns (generic.Empty);
|
|
||||||
rpc RemoveConfig(generic.String) returns (collection.OpChanges);
|
|
||||||
rpc GetAllConfig(generic.Empty) returns (generic.Json);
|
|
||||||
rpc GetConfigBool(Config.Bool) returns (generic.Bool);
|
|
||||||
rpc SetConfigBool(SetConfigBoolRequest) returns (collection.OpChanges);
|
|
||||||
rpc GetConfigString(Config.String) returns (generic.String);
|
|
||||||
rpc SetConfigString(SetConfigStringRequest) returns (collection.OpChanges);
|
|
||||||
rpc GetPreferences(generic.Empty) returns (Preferences);
|
|
||||||
rpc SetPreferences(Preferences) returns (collection.OpChanges);
|
|
||||||
}
|
|
||||||
|
|
||||||
service CardRenderingService {
|
service CardRenderingService {
|
||||||
rpc ExtractAVTags(ExtractAVTagsRequest) returns (ExtractAVTagsResponse);
|
rpc ExtractAVTags(ExtractAVTagsRequest) returns (ExtractAVTagsResponse);
|
||||||
rpc ExtractLatex(ExtractLatexRequest) returns (ExtractLatexResponse);
|
rpc ExtractLatex(ExtractLatexRequest) returns (ExtractLatexResponse);
|
||||||
|
@ -121,19 +65,6 @@ service TagsService {
|
||||||
returns (collection.OpChangesWithCount);
|
returns (collection.OpChangesWithCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
service SearchService {
|
|
||||||
rpc BuildSearchString(SearchNode) returns (generic.String);
|
|
||||||
rpc SearchCards(SearchRequest) returns (SearchResponse);
|
|
||||||
rpc SearchNotes(SearchRequest) returns (SearchResponse);
|
|
||||||
rpc JoinSearchNodes(JoinSearchNodesRequest) returns (generic.String);
|
|
||||||
rpc ReplaceSearchNode(ReplaceSearchNodeRequest) returns (generic.String);
|
|
||||||
rpc FindAndReplace(FindAndReplaceRequest)
|
|
||||||
returns (collection.OpChangesWithCount);
|
|
||||||
rpc AllBrowserColumns(generic.Empty) returns (BrowserColumns);
|
|
||||||
rpc BrowserRowForId(generic.Int64) returns (BrowserRow);
|
|
||||||
rpc SetActiveBrowserColumns(generic.StringList) returns (generic.Empty);
|
|
||||||
}
|
|
||||||
|
|
||||||
service StatsService {
|
service StatsService {
|
||||||
rpc CardStats(cards.CardId) returns (generic.String);
|
rpc CardStats(cards.CardId) returns (generic.String);
|
||||||
rpc Graphs(GraphsRequest) returns (GraphsResponse);
|
rpc Graphs(GraphsRequest) returns (GraphsResponse);
|
||||||
|
@ -194,11 +125,6 @@ message BackendError {
|
||||||
// Messages
|
// Messages
|
||||||
///////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////
|
||||||
|
|
||||||
message SchedTimingTodayResponse {
|
|
||||||
uint32 days_elapsed = 1;
|
|
||||||
int64 next_day_at = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
message RenderExistingCardRequest {
|
message RenderExistingCardRequest {
|
||||||
int64 card_id = 1;
|
int64 card_id = 1;
|
||||||
bool browser = 2;
|
bool browser = 2;
|
||||||
|
@ -295,118 +221,11 @@ message TrashMediaFilesRequest {
|
||||||
repeated string fnames = 1;
|
repeated string fnames = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
message StudiedTodayMessageRequest {
|
|
||||||
uint32 cards = 1;
|
|
||||||
double seconds = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
message CongratsLearnMessageRequest {
|
message CongratsLearnMessageRequest {
|
||||||
float next_due = 1;
|
float next_due = 1;
|
||||||
uint32 remaining = 2;
|
uint32 remaining = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
message SearchRequest {
|
|
||||||
string search = 1;
|
|
||||||
SortOrder order = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
message SearchResponse {
|
|
||||||
repeated int64 ids = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
message SortOrder {
|
|
||||||
message Builtin {
|
|
||||||
string column = 1;
|
|
||||||
bool reverse = 2;
|
|
||||||
}
|
|
||||||
oneof value {
|
|
||||||
generic.Empty none = 1;
|
|
||||||
string custom = 2;
|
|
||||||
Builtin builtin = 3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
message SearchNode {
|
|
||||||
message Dupe {
|
|
||||||
int64 notetype_id = 1;
|
|
||||||
string first_field = 2;
|
|
||||||
}
|
|
||||||
enum Flag {
|
|
||||||
FLAG_NONE = 0;
|
|
||||||
FLAG_ANY = 1;
|
|
||||||
FLAG_RED = 2;
|
|
||||||
FLAG_ORANGE = 3;
|
|
||||||
FLAG_GREEN = 4;
|
|
||||||
FLAG_BLUE = 5;
|
|
||||||
FLAG_PINK = 6;
|
|
||||||
FLAG_TURQUOISE = 7;
|
|
||||||
FLAG_PURPLE = 8;
|
|
||||||
}
|
|
||||||
enum Rating {
|
|
||||||
RATING_ANY = 0;
|
|
||||||
RATING_AGAIN = 1;
|
|
||||||
RATING_HARD = 2;
|
|
||||||
RATING_GOOD = 3;
|
|
||||||
RATING_EASY = 4;
|
|
||||||
RATING_BY_RESCHEDULE = 5;
|
|
||||||
}
|
|
||||||
message Rated {
|
|
||||||
uint32 days = 1;
|
|
||||||
Rating rating = 2;
|
|
||||||
}
|
|
||||||
enum CardState {
|
|
||||||
CARD_STATE_NEW = 0;
|
|
||||||
CARD_STATE_LEARN = 1;
|
|
||||||
CARD_STATE_REVIEW = 2;
|
|
||||||
CARD_STATE_DUE = 3;
|
|
||||||
CARD_STATE_SUSPENDED = 4;
|
|
||||||
CARD_STATE_BURIED = 5;
|
|
||||||
}
|
|
||||||
message IdList {
|
|
||||||
repeated int64 ids = 1;
|
|
||||||
}
|
|
||||||
message Group {
|
|
||||||
enum Joiner {
|
|
||||||
AND = 0;
|
|
||||||
OR = 1;
|
|
||||||
}
|
|
||||||
repeated SearchNode nodes = 1;
|
|
||||||
Joiner joiner = 2;
|
|
||||||
}
|
|
||||||
oneof filter {
|
|
||||||
Group group = 1;
|
|
||||||
SearchNode negated = 2;
|
|
||||||
string parsable_text = 3;
|
|
||||||
uint32 template = 4;
|
|
||||||
int64 nid = 5;
|
|
||||||
Dupe dupe = 6;
|
|
||||||
string field_name = 7;
|
|
||||||
Rated rated = 8;
|
|
||||||
uint32 added_in_days = 9;
|
|
||||||
int32 due_in_days = 10;
|
|
||||||
Flag flag = 11;
|
|
||||||
CardState card_state = 12;
|
|
||||||
IdList nids = 13;
|
|
||||||
uint32 edited_in_days = 14;
|
|
||||||
string deck = 15;
|
|
||||||
int32 due_on_day = 16;
|
|
||||||
string tag = 17;
|
|
||||||
string note = 18;
|
|
||||||
uint32 introduced_in_days = 19;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
message JoinSearchNodesRequest {
|
|
||||||
SearchNode.Group.Joiner joiner = 1;
|
|
||||||
SearchNode existing_node = 2;
|
|
||||||
SearchNode additional_node = 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
message ReplaceSearchNodeRequest {
|
|
||||||
SearchNode existing_node = 1;
|
|
||||||
SearchNode replacement_node = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
message SetTagCollapsedRequest {
|
message SetTagCollapsedRequest {
|
||||||
string name = 1;
|
string name = 1;
|
||||||
bool collapsed = 2;
|
bool collapsed = 2;
|
||||||
|
@ -433,12 +252,6 @@ message RenameTagsRequest {
|
||||||
string new_prefix = 2;
|
string new_prefix = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
message SetConfigJsonRequest {
|
|
||||||
string key = 1;
|
|
||||||
bytes value_json = 2;
|
|
||||||
bool undoable = 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
message EmptyCardsReport {
|
message EmptyCardsReport {
|
||||||
message NoteWithEmptyCards {
|
message NoteWithEmptyCards {
|
||||||
int64 note_id = 1;
|
int64 note_id = 1;
|
||||||
|
@ -449,59 +262,6 @@ message EmptyCardsReport {
|
||||||
repeated NoteWithEmptyCards notes = 2;
|
repeated NoteWithEmptyCards notes = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
message FindAndReplaceRequest {
|
|
||||||
repeated int64 nids = 1;
|
|
||||||
string search = 2;
|
|
||||||
string replacement = 3;
|
|
||||||
bool regex = 4;
|
|
||||||
bool match_case = 5;
|
|
||||||
string field_name = 6;
|
|
||||||
}
|
|
||||||
|
|
||||||
message BrowserColumns {
|
|
||||||
enum Sorting {
|
|
||||||
SORTING_NONE = 0;
|
|
||||||
SORTING_NORMAL = 1;
|
|
||||||
SORTING_REVERSED = 2;
|
|
||||||
}
|
|
||||||
enum Alignment {
|
|
||||||
ALIGNMENT_START = 0;
|
|
||||||
ALIGNMENT_CENTER = 1;
|
|
||||||
}
|
|
||||||
message Column {
|
|
||||||
string key = 1;
|
|
||||||
string cards_mode_label = 2;
|
|
||||||
string notes_mode_label = 3;
|
|
||||||
Sorting sorting = 4;
|
|
||||||
bool uses_cell_font = 5;
|
|
||||||
Alignment alignment = 6;
|
|
||||||
}
|
|
||||||
repeated Column columns = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
message BrowserRow {
|
|
||||||
message Cell {
|
|
||||||
string text = 1;
|
|
||||||
bool is_rtl = 2;
|
|
||||||
}
|
|
||||||
enum Color {
|
|
||||||
COLOR_DEFAULT = 0;
|
|
||||||
COLOR_MARKED = 1;
|
|
||||||
COLOR_SUSPENDED = 2;
|
|
||||||
COLOR_FLAG_RED = 3;
|
|
||||||
COLOR_FLAG_ORANGE = 4;
|
|
||||||
COLOR_FLAG_GREEN = 5;
|
|
||||||
COLOR_FLAG_BLUE = 6;
|
|
||||||
COLOR_FLAG_PINK = 7;
|
|
||||||
COLOR_FLAG_TURQUOISE = 8;
|
|
||||||
COLOR_FLAG_PURPLE = 9;
|
|
||||||
}
|
|
||||||
repeated Cell cells = 1;
|
|
||||||
Color color = 2;
|
|
||||||
string font_name = 3;
|
|
||||||
uint32 font_size = 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
message NoteIdsAndTagsRequest {
|
message NoteIdsAndTagsRequest {
|
||||||
repeated int64 note_ids = 1;
|
repeated int64 note_ids = 1;
|
||||||
string tags = 2;
|
string tags = 2;
|
||||||
|
@ -515,117 +275,6 @@ message FindAndReplaceTagRequest {
|
||||||
bool match_case = 5;
|
bool match_case = 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
message Preferences {
|
|
||||||
message Scheduling {
|
|
||||||
enum NewReviewMix {
|
|
||||||
DISTRIBUTE = 0;
|
|
||||||
REVIEWS_FIRST = 1;
|
|
||||||
NEW_FIRST = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
// read only; 1-3
|
|
||||||
uint32 scheduler_version = 1;
|
|
||||||
|
|
||||||
uint32 rollover = 2;
|
|
||||||
uint32 learn_ahead_secs = 3;
|
|
||||||
NewReviewMix new_review_mix = 4;
|
|
||||||
|
|
||||||
// v2 only
|
|
||||||
bool new_timezone = 5;
|
|
||||||
bool day_learn_first = 6;
|
|
||||||
}
|
|
||||||
message Reviewing {
|
|
||||||
bool hide_audio_play_buttons = 1;
|
|
||||||
bool interrupt_audio_when_answering = 2;
|
|
||||||
bool show_remaining_due_counts = 3;
|
|
||||||
bool show_intervals_on_buttons = 4;
|
|
||||||
uint32 time_limit_secs = 5;
|
|
||||||
}
|
|
||||||
message Editing {
|
|
||||||
bool adding_defaults_to_current_deck = 1;
|
|
||||||
bool paste_images_as_png = 2;
|
|
||||||
bool paste_strips_formatting = 3;
|
|
||||||
string default_search_text = 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
Scheduling scheduling = 1;
|
|
||||||
Reviewing reviewing = 2;
|
|
||||||
Editing editing = 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
message SyncLoginRequest {
|
|
||||||
string username = 1;
|
|
||||||
string password = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
message SyncStatusResponse {
|
|
||||||
enum Required {
|
|
||||||
NO_CHANGES = 0;
|
|
||||||
NORMAL_SYNC = 1;
|
|
||||||
FULL_SYNC = 2;
|
|
||||||
}
|
|
||||||
Required required = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
message SyncCollectionResponse {
|
|
||||||
enum ChangesRequired {
|
|
||||||
NO_CHANGES = 0;
|
|
||||||
NORMAL_SYNC = 1;
|
|
||||||
FULL_SYNC = 2;
|
|
||||||
// local collection has no cards; upload not an option
|
|
||||||
FULL_DOWNLOAD = 3;
|
|
||||||
// remote collection has no cards; download not an option
|
|
||||||
FULL_UPLOAD = 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32 host_number = 1;
|
|
||||||
string server_message = 2;
|
|
||||||
ChangesRequired required = 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
message SyncAuth {
|
|
||||||
string hkey = 1;
|
|
||||||
uint32 host_number = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
message SyncServerMethodRequest {
|
|
||||||
enum Method {
|
|
||||||
HOST_KEY = 0;
|
|
||||||
META = 1;
|
|
||||||
START = 2;
|
|
||||||
APPLY_GRAVES = 3;
|
|
||||||
APPLY_CHANGES = 4;
|
|
||||||
CHUNK = 5;
|
|
||||||
APPLY_CHUNK = 6;
|
|
||||||
SANITY_CHECK = 7;
|
|
||||||
FINISH = 8;
|
|
||||||
ABORT = 9;
|
|
||||||
// caller must reopen after these two are called
|
|
||||||
FULL_UPLOAD = 10;
|
|
||||||
FULL_DOWNLOAD = 11;
|
|
||||||
}
|
|
||||||
Method method = 1;
|
|
||||||
bytes data = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
message UpdateStatsRequest {
|
|
||||||
int64 deck_id = 1;
|
|
||||||
int32 new_delta = 2;
|
|
||||||
int32 review_delta = 4;
|
|
||||||
int32 millisecond_delta = 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
message ExtendLimitsRequest {
|
|
||||||
int64 deck_id = 1;
|
|
||||||
int32 new_delta = 2;
|
|
||||||
int32 review_delta = 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
message CountsForDeckTodayResponse {
|
|
||||||
int32 new = 1;
|
|
||||||
int32 review = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
message GraphsRequest {
|
message GraphsRequest {
|
||||||
string search = 1;
|
string search = 1;
|
||||||
uint32 days = 2;
|
uint32 days = 2;
|
||||||
|
@ -673,205 +322,7 @@ message RevlogEntry {
|
||||||
uint32 taken_millis = 8;
|
uint32 taken_millis = 8;
|
||||||
ReviewKind review_kind = 9;
|
ReviewKind review_kind = 9;
|
||||||
}
|
}
|
||||||
|
|
||||||
message CongratsInfoResponse {
|
|
||||||
uint32 learn_remaining = 1;
|
|
||||||
uint32 secs_until_next_learn = 2;
|
|
||||||
bool review_remaining = 3;
|
|
||||||
bool new_remaining = 4;
|
|
||||||
bool have_sched_buried = 5;
|
|
||||||
bool have_user_buried = 6;
|
|
||||||
bool is_filtered_deck = 7;
|
|
||||||
bool bridge_commands_supported = 8;
|
|
||||||
string deck_description = 9;
|
|
||||||
}
|
|
||||||
|
|
||||||
message UnburyDeckRequest {
|
|
||||||
enum Mode {
|
|
||||||
ALL = 0;
|
|
||||||
SCHED_ONLY = 1;
|
|
||||||
USER_ONLY = 2;
|
|
||||||
}
|
|
||||||
int64 deck_id = 1;
|
|
||||||
Mode mode = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
message BuryOrSuspendCardsRequest {
|
|
||||||
enum Mode {
|
|
||||||
SUSPEND = 0;
|
|
||||||
BURY_SCHED = 1;
|
|
||||||
BURY_USER = 2;
|
|
||||||
}
|
|
||||||
repeated int64 card_ids = 1;
|
|
||||||
repeated int64 note_ids = 2;
|
|
||||||
Mode mode = 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
message ScheduleCardsAsNewRequest {
|
|
||||||
repeated int64 card_ids = 1;
|
|
||||||
bool log = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
message SetDueDateRequest {
|
|
||||||
repeated int64 card_ids = 1;
|
|
||||||
string days = 2;
|
|
||||||
Config.String config_key = 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
message SortCardsRequest {
|
|
||||||
repeated int64 card_ids = 1;
|
|
||||||
uint32 starting_from = 2;
|
|
||||||
uint32 step_size = 3;
|
|
||||||
bool randomize = 4;
|
|
||||||
bool shift_existing = 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
message SortDeckRequest {
|
|
||||||
int64 deck_id = 1;
|
|
||||||
bool randomize = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
message Config {
|
|
||||||
message Bool {
|
|
||||||
enum Key {
|
|
||||||
BROWSER_TABLE_SHOW_NOTES_MODE = 0;
|
|
||||||
PREVIEW_BOTH_SIDES = 3;
|
|
||||||
COLLAPSE_TAGS = 4;
|
|
||||||
COLLAPSE_NOTETYPES = 5;
|
|
||||||
COLLAPSE_DECKS = 6;
|
|
||||||
COLLAPSE_SAVED_SEARCHES = 7;
|
|
||||||
COLLAPSE_TODAY = 8;
|
|
||||||
COLLAPSE_CARD_STATE = 9;
|
|
||||||
COLLAPSE_FLAGS = 10;
|
|
||||||
SCHED_2021 = 11;
|
|
||||||
ADDING_DEFAULTS_TO_CURRENT_DECK = 12;
|
|
||||||
HIDE_AUDIO_PLAY_BUTTONS = 13;
|
|
||||||
INTERRUPT_AUDIO_WHEN_ANSWERING = 14;
|
|
||||||
PASTE_IMAGES_AS_PNG = 15;
|
|
||||||
PASTE_STRIPS_FORMATTING = 16;
|
|
||||||
NORMALIZE_NOTE_TEXT = 17;
|
|
||||||
}
|
|
||||||
Key key = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
message String {
|
|
||||||
enum Key {
|
|
||||||
SET_DUE_BROWSER = 0;
|
|
||||||
SET_DUE_REVIEWER = 1;
|
|
||||||
DEFAULT_SEARCH_TEXT = 2;
|
|
||||||
CARD_STATE_CUSTOMIZER = 3;
|
|
||||||
}
|
|
||||||
Key key = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
message SetConfigBoolRequest {
|
|
||||||
Config.Bool.Key key = 1;
|
|
||||||
bool value = 2;
|
|
||||||
bool undoable = 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
message SetConfigStringRequest {
|
|
||||||
Config.String.Key key = 1;
|
|
||||||
string value = 2;
|
|
||||||
bool undoable = 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
message RenderMarkdownRequest {
|
message RenderMarkdownRequest {
|
||||||
string markdown = 1;
|
string markdown = 1;
|
||||||
bool sanitize = 2;
|
bool sanitize = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
message SchedulingState {
|
|
||||||
message New {
|
|
||||||
uint32 position = 1;
|
|
||||||
}
|
|
||||||
message Learning {
|
|
||||||
uint32 remaining_steps = 1;
|
|
||||||
uint32 scheduled_secs = 2;
|
|
||||||
}
|
|
||||||
message Review {
|
|
||||||
uint32 scheduled_days = 1;
|
|
||||||
uint32 elapsed_days = 2;
|
|
||||||
float ease_factor = 3;
|
|
||||||
uint32 lapses = 4;
|
|
||||||
bool leeched = 5;
|
|
||||||
}
|
|
||||||
message Relearning {
|
|
||||||
Review review = 1;
|
|
||||||
Learning learning = 2;
|
|
||||||
}
|
|
||||||
message Normal {
|
|
||||||
oneof value {
|
|
||||||
New new = 1;
|
|
||||||
Learning learning = 2;
|
|
||||||
Review review = 3;
|
|
||||||
Relearning relearning = 4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
message Preview {
|
|
||||||
uint32 scheduled_secs = 1;
|
|
||||||
bool finished = 2;
|
|
||||||
}
|
|
||||||
message ReschedulingFilter {
|
|
||||||
Normal original_state = 1;
|
|
||||||
}
|
|
||||||
message Filtered {
|
|
||||||
oneof value {
|
|
||||||
Preview preview = 1;
|
|
||||||
ReschedulingFilter rescheduling = 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
oneof value {
|
|
||||||
Normal normal = 1;
|
|
||||||
Filtered filtered = 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
message NextCardStates {
|
|
||||||
SchedulingState current = 1;
|
|
||||||
SchedulingState again = 2;
|
|
||||||
SchedulingState hard = 3;
|
|
||||||
SchedulingState good = 4;
|
|
||||||
SchedulingState easy = 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
message CardAnswer {
|
|
||||||
enum Rating {
|
|
||||||
AGAIN = 0;
|
|
||||||
HARD = 1;
|
|
||||||
GOOD = 2;
|
|
||||||
EASY = 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
int64 card_id = 1;
|
|
||||||
SchedulingState current_state = 2;
|
|
||||||
SchedulingState new_state = 3;
|
|
||||||
Rating rating = 4;
|
|
||||||
int64 answered_at_millis = 5;
|
|
||||||
uint32 milliseconds_taken = 6;
|
|
||||||
}
|
|
||||||
|
|
||||||
message GetQueuedCardsRequest {
|
|
||||||
uint32 fetch_limit = 1;
|
|
||||||
bool intraday_learning_only = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
message QueuedCards {
|
|
||||||
enum Queue {
|
|
||||||
NEW = 0;
|
|
||||||
LEARNING = 1;
|
|
||||||
REVIEW = 2;
|
|
||||||
}
|
|
||||||
message QueuedCard {
|
|
||||||
cards.Card card = 1;
|
|
||||||
Queue queue = 2;
|
|
||||||
NextCardStates next_states = 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
repeated QueuedCard cards = 1;
|
|
||||||
uint32 new_count = 2;
|
|
||||||
uint32 learning_count = 3;
|
|
||||||
uint32 review_count = 4;
|
|
||||||
}
|
|
||||||
|
|
113
proto/anki/configs.proto
Normal file
113
proto/anki/configs.proto
Normal file
|
@ -0,0 +1,113 @@
|
||||||
|
// Copyright: Ankitects Pty Ltd and contributors
|
||||||
|
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
|
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package anki.configs;
|
||||||
|
|
||||||
|
import "anki/generic.proto";
|
||||||
|
import "anki/collection.proto";
|
||||||
|
|
||||||
|
service ConfigsService {
|
||||||
|
rpc GetConfigJson(generic.String) returns (generic.Json);
|
||||||
|
rpc SetConfigJson(SetConfigJsonRequest) returns (collection.OpChanges);
|
||||||
|
rpc SetConfigJsonNoUndo(SetConfigJsonRequest) returns (generic.Empty);
|
||||||
|
rpc RemoveConfig(generic.String) returns (collection.OpChanges);
|
||||||
|
rpc GetAllConfig(generic.Empty) returns (generic.Json);
|
||||||
|
rpc GetConfigBool(Config.Bool) returns (generic.Bool);
|
||||||
|
rpc SetConfigBool(SetConfigBoolRequest) returns (collection.OpChanges);
|
||||||
|
rpc GetConfigString(Config.String) returns (generic.String);
|
||||||
|
rpc SetConfigString(SetConfigStringRequest) returns (collection.OpChanges);
|
||||||
|
rpc GetPreferences(generic.Empty) returns (Preferences);
|
||||||
|
rpc SetPreferences(Preferences) returns (collection.OpChanges);
|
||||||
|
}
|
||||||
|
|
||||||
|
message Config {
|
||||||
|
message Bool {
|
||||||
|
enum Key {
|
||||||
|
BROWSER_TABLE_SHOW_NOTES_MODE = 0;
|
||||||
|
PREVIEW_BOTH_SIDES = 3;
|
||||||
|
COLLAPSE_TAGS = 4;
|
||||||
|
COLLAPSE_NOTETYPES = 5;
|
||||||
|
COLLAPSE_DECKS = 6;
|
||||||
|
COLLAPSE_SAVED_SEARCHES = 7;
|
||||||
|
COLLAPSE_TODAY = 8;
|
||||||
|
COLLAPSE_CARD_STATE = 9;
|
||||||
|
COLLAPSE_FLAGS = 10;
|
||||||
|
SCHED_2021 = 11;
|
||||||
|
ADDING_DEFAULTS_TO_CURRENT_DECK = 12;
|
||||||
|
HIDE_AUDIO_PLAY_BUTTONS = 13;
|
||||||
|
INTERRUPT_AUDIO_WHEN_ANSWERING = 14;
|
||||||
|
PASTE_IMAGES_AS_PNG = 15;
|
||||||
|
PASTE_STRIPS_FORMATTING = 16;
|
||||||
|
NORMALIZE_NOTE_TEXT = 17;
|
||||||
|
}
|
||||||
|
Key key = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message String {
|
||||||
|
enum Key {
|
||||||
|
SET_DUE_BROWSER = 0;
|
||||||
|
SET_DUE_REVIEWER = 1;
|
||||||
|
DEFAULT_SEARCH_TEXT = 2;
|
||||||
|
CARD_STATE_CUSTOMIZER = 3;
|
||||||
|
}
|
||||||
|
Key key = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
message SetConfigBoolRequest {
|
||||||
|
Config.Bool.Key key = 1;
|
||||||
|
bool value = 2;
|
||||||
|
bool undoable = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message SetConfigStringRequest {
|
||||||
|
Config.String.Key key = 1;
|
||||||
|
string value = 2;
|
||||||
|
bool undoable = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message SetConfigJsonRequest {
|
||||||
|
string key = 1;
|
||||||
|
bytes value_json = 2;
|
||||||
|
bool undoable = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Preferences {
|
||||||
|
message Scheduling {
|
||||||
|
enum NewReviewMix {
|
||||||
|
DISTRIBUTE = 0;
|
||||||
|
REVIEWS_FIRST = 1;
|
||||||
|
NEW_FIRST = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// read only; 1-3
|
||||||
|
uint32 scheduler_version = 1;
|
||||||
|
|
||||||
|
uint32 rollover = 2;
|
||||||
|
uint32 learn_ahead_secs = 3;
|
||||||
|
NewReviewMix new_review_mix = 4;
|
||||||
|
|
||||||
|
// v2 only
|
||||||
|
bool new_timezone = 5;
|
||||||
|
bool day_learn_first = 6;
|
||||||
|
}
|
||||||
|
message Reviewing {
|
||||||
|
bool hide_audio_play_buttons = 1;
|
||||||
|
bool interrupt_audio_when_answering = 2;
|
||||||
|
bool show_remaining_due_counts = 3;
|
||||||
|
bool show_intervals_on_buttons = 4;
|
||||||
|
uint32 time_limit_secs = 5;
|
||||||
|
}
|
||||||
|
message Editing {
|
||||||
|
bool adding_defaults_to_current_deck = 1;
|
||||||
|
bool paste_images_as_png = 2;
|
||||||
|
bool paste_strips_formatting = 3;
|
||||||
|
string default_search_text = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
Scheduling scheduling = 1;
|
||||||
|
Reviewing reviewing = 2;
|
||||||
|
Editing editing = 3;
|
||||||
|
}
|
219
proto/anki/scheduler.proto
Normal file
219
proto/anki/scheduler.proto
Normal file
|
@ -0,0 +1,219 @@
|
||||||
|
// Copyright: Ankitects Pty Ltd and contributors
|
||||||
|
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
|
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package anki.scheduler;
|
||||||
|
|
||||||
|
import "anki/generic.proto";
|
||||||
|
import "anki/cards.proto";
|
||||||
|
import "anki/decks.proto";
|
||||||
|
import "anki/collection.proto";
|
||||||
|
import "anki/configs.proto";
|
||||||
|
|
||||||
|
service SchedulerService {
|
||||||
|
rpc GetQueuedCards(GetQueuedCardsRequest) returns (QueuedCards);
|
||||||
|
rpc AnswerCard(CardAnswer) returns (collection.OpChanges);
|
||||||
|
rpc SchedTimingToday(generic.Empty) returns (SchedTimingTodayResponse);
|
||||||
|
rpc StudiedToday(generic.Empty) returns (generic.String);
|
||||||
|
rpc StudiedTodayMessage(StudiedTodayMessageRequest) returns (generic.String);
|
||||||
|
rpc UpdateStats(UpdateStatsRequest) returns (generic.Empty);
|
||||||
|
rpc ExtendLimits(ExtendLimitsRequest) returns (generic.Empty);
|
||||||
|
rpc CountsForDeckToday(decks.DeckId) returns (CountsForDeckTodayResponse);
|
||||||
|
rpc CongratsInfo(generic.Empty) returns (CongratsInfoResponse);
|
||||||
|
rpc RestoreBuriedAndSuspendedCards(cards.CardIds)
|
||||||
|
returns (collection.OpChanges);
|
||||||
|
rpc UnburyDeck(UnburyDeckRequest) returns (collection.OpChanges);
|
||||||
|
rpc BuryOrSuspendCards(BuryOrSuspendCardsRequest)
|
||||||
|
returns (collection.OpChangesWithCount);
|
||||||
|
rpc EmptyFilteredDeck(decks.DeckId) returns (collection.OpChanges);
|
||||||
|
rpc RebuildFilteredDeck(decks.DeckId) returns (collection.OpChangesWithCount);
|
||||||
|
rpc ScheduleCardsAsNew(ScheduleCardsAsNewRequest)
|
||||||
|
returns (collection.OpChanges);
|
||||||
|
rpc SetDueDate(SetDueDateRequest) returns (collection.OpChanges);
|
||||||
|
rpc SortCards(SortCardsRequest) returns (collection.OpChangesWithCount);
|
||||||
|
rpc SortDeck(SortDeckRequest) returns (collection.OpChangesWithCount);
|
||||||
|
rpc GetNextCardStates(cards.CardId) returns (NextCardStates);
|
||||||
|
rpc DescribeNextStates(NextCardStates) returns (generic.StringList);
|
||||||
|
rpc StateIsLeech(SchedulingState) returns (generic.Bool);
|
||||||
|
rpc UpgradeScheduler(generic.Empty) returns (generic.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
message SchedulingState {
|
||||||
|
message New {
|
||||||
|
uint32 position = 1;
|
||||||
|
}
|
||||||
|
message Learning {
|
||||||
|
uint32 remaining_steps = 1;
|
||||||
|
uint32 scheduled_secs = 2;
|
||||||
|
}
|
||||||
|
message Review {
|
||||||
|
uint32 scheduled_days = 1;
|
||||||
|
uint32 elapsed_days = 2;
|
||||||
|
float ease_factor = 3;
|
||||||
|
uint32 lapses = 4;
|
||||||
|
bool leeched = 5;
|
||||||
|
}
|
||||||
|
message Relearning {
|
||||||
|
Review review = 1;
|
||||||
|
Learning learning = 2;
|
||||||
|
}
|
||||||
|
message Normal {
|
||||||
|
oneof value {
|
||||||
|
New new = 1;
|
||||||
|
Learning learning = 2;
|
||||||
|
Review review = 3;
|
||||||
|
Relearning relearning = 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
message Preview {
|
||||||
|
uint32 scheduled_secs = 1;
|
||||||
|
bool finished = 2;
|
||||||
|
}
|
||||||
|
message ReschedulingFilter {
|
||||||
|
Normal original_state = 1;
|
||||||
|
}
|
||||||
|
message Filtered {
|
||||||
|
oneof value {
|
||||||
|
Preview preview = 1;
|
||||||
|
ReschedulingFilter rescheduling = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
oneof value {
|
||||||
|
Normal normal = 1;
|
||||||
|
Filtered filtered = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
message QueuedCards {
|
||||||
|
enum Queue {
|
||||||
|
NEW = 0;
|
||||||
|
LEARNING = 1;
|
||||||
|
REVIEW = 2;
|
||||||
|
}
|
||||||
|
message QueuedCard {
|
||||||
|
cards.Card card = 1;
|
||||||
|
Queue queue = 2;
|
||||||
|
NextCardStates next_states = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
repeated QueuedCard cards = 1;
|
||||||
|
uint32 new_count = 2;
|
||||||
|
uint32 learning_count = 3;
|
||||||
|
uint32 review_count = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
message GetQueuedCardsRequest {
|
||||||
|
uint32 fetch_limit = 1;
|
||||||
|
bool intraday_learning_only = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message SchedTimingTodayResponse {
|
||||||
|
uint32 days_elapsed = 1;
|
||||||
|
int64 next_day_at = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message StudiedTodayMessageRequest {
|
||||||
|
uint32 cards = 1;
|
||||||
|
double seconds = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message UpdateStatsRequest {
|
||||||
|
int64 deck_id = 1;
|
||||||
|
int32 new_delta = 2;
|
||||||
|
int32 review_delta = 4;
|
||||||
|
int32 millisecond_delta = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ExtendLimitsRequest {
|
||||||
|
int64 deck_id = 1;
|
||||||
|
int32 new_delta = 2;
|
||||||
|
int32 review_delta = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message CountsForDeckTodayResponse {
|
||||||
|
int32 new = 1;
|
||||||
|
int32 review = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message CongratsInfoResponse {
|
||||||
|
uint32 learn_remaining = 1;
|
||||||
|
uint32 secs_until_next_learn = 2;
|
||||||
|
bool review_remaining = 3;
|
||||||
|
bool new_remaining = 4;
|
||||||
|
bool have_sched_buried = 5;
|
||||||
|
bool have_user_buried = 6;
|
||||||
|
bool is_filtered_deck = 7;
|
||||||
|
bool bridge_commands_supported = 8;
|
||||||
|
string deck_description = 9;
|
||||||
|
}
|
||||||
|
|
||||||
|
message UnburyDeckRequest {
|
||||||
|
enum Mode {
|
||||||
|
ALL = 0;
|
||||||
|
SCHED_ONLY = 1;
|
||||||
|
USER_ONLY = 2;
|
||||||
|
}
|
||||||
|
int64 deck_id = 1;
|
||||||
|
Mode mode = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message BuryOrSuspendCardsRequest {
|
||||||
|
enum Mode {
|
||||||
|
SUSPEND = 0;
|
||||||
|
BURY_SCHED = 1;
|
||||||
|
BURY_USER = 2;
|
||||||
|
}
|
||||||
|
repeated int64 card_ids = 1;
|
||||||
|
repeated int64 note_ids = 2;
|
||||||
|
Mode mode = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ScheduleCardsAsNewRequest {
|
||||||
|
repeated int64 card_ids = 1;
|
||||||
|
bool log = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message SetDueDateRequest {
|
||||||
|
repeated int64 card_ids = 1;
|
||||||
|
string days = 2;
|
||||||
|
configs.Config.String config_key = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message SortCardsRequest {
|
||||||
|
repeated int64 card_ids = 1;
|
||||||
|
uint32 starting_from = 2;
|
||||||
|
uint32 step_size = 3;
|
||||||
|
bool randomize = 4;
|
||||||
|
bool shift_existing = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
message SortDeckRequest {
|
||||||
|
int64 deck_id = 1;
|
||||||
|
bool randomize = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message NextCardStates {
|
||||||
|
SchedulingState current = 1;
|
||||||
|
SchedulingState again = 2;
|
||||||
|
SchedulingState hard = 3;
|
||||||
|
SchedulingState good = 4;
|
||||||
|
SchedulingState easy = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
message CardAnswer {
|
||||||
|
enum Rating {
|
||||||
|
AGAIN = 0;
|
||||||
|
HARD = 1;
|
||||||
|
GOOD = 2;
|
||||||
|
EASY = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
int64 card_id = 1;
|
||||||
|
SchedulingState current_state = 2;
|
||||||
|
SchedulingState new_state = 3;
|
||||||
|
Rating rating = 4;
|
||||||
|
int64 answered_at_millis = 5;
|
||||||
|
uint32 milliseconds_taken = 6;
|
||||||
|
}
|
177
proto/anki/search.proto
Normal file
177
proto/anki/search.proto
Normal file
|
@ -0,0 +1,177 @@
|
||||||
|
// Copyright: Ankitects Pty Ltd and contributors
|
||||||
|
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
|
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package anki.search;
|
||||||
|
|
||||||
|
import "anki/generic.proto";
|
||||||
|
import "anki/collection.proto";
|
||||||
|
|
||||||
|
service SearchService {
|
||||||
|
rpc BuildSearchString(SearchNode) returns (generic.String);
|
||||||
|
rpc SearchCards(SearchRequest) returns (SearchResponse);
|
||||||
|
rpc SearchNotes(SearchRequest) returns (SearchResponse);
|
||||||
|
rpc JoinSearchNodes(JoinSearchNodesRequest) returns (generic.String);
|
||||||
|
rpc ReplaceSearchNode(ReplaceSearchNodeRequest) returns (generic.String);
|
||||||
|
rpc FindAndReplace(FindAndReplaceRequest)
|
||||||
|
returns (collection.OpChangesWithCount);
|
||||||
|
rpc AllBrowserColumns(generic.Empty) returns (BrowserColumns);
|
||||||
|
rpc BrowserRowForId(generic.Int64) returns (BrowserRow);
|
||||||
|
rpc SetActiveBrowserColumns(generic.StringList) returns (generic.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
message SearchNode {
|
||||||
|
message Dupe {
|
||||||
|
int64 notetype_id = 1;
|
||||||
|
string first_field = 2;
|
||||||
|
}
|
||||||
|
enum Flag {
|
||||||
|
FLAG_NONE = 0;
|
||||||
|
FLAG_ANY = 1;
|
||||||
|
FLAG_RED = 2;
|
||||||
|
FLAG_ORANGE = 3;
|
||||||
|
FLAG_GREEN = 4;
|
||||||
|
FLAG_BLUE = 5;
|
||||||
|
FLAG_PINK = 6;
|
||||||
|
FLAG_TURQUOISE = 7;
|
||||||
|
FLAG_PURPLE = 8;
|
||||||
|
}
|
||||||
|
enum Rating {
|
||||||
|
RATING_ANY = 0;
|
||||||
|
RATING_AGAIN = 1;
|
||||||
|
RATING_HARD = 2;
|
||||||
|
RATING_GOOD = 3;
|
||||||
|
RATING_EASY = 4;
|
||||||
|
RATING_BY_RESCHEDULE = 5;
|
||||||
|
}
|
||||||
|
message Rated {
|
||||||
|
uint32 days = 1;
|
||||||
|
Rating rating = 2;
|
||||||
|
}
|
||||||
|
enum CardState {
|
||||||
|
CARD_STATE_NEW = 0;
|
||||||
|
CARD_STATE_LEARN = 1;
|
||||||
|
CARD_STATE_REVIEW = 2;
|
||||||
|
CARD_STATE_DUE = 3;
|
||||||
|
CARD_STATE_SUSPENDED = 4;
|
||||||
|
CARD_STATE_BURIED = 5;
|
||||||
|
}
|
||||||
|
message IdList {
|
||||||
|
repeated int64 ids = 1;
|
||||||
|
}
|
||||||
|
message Group {
|
||||||
|
enum Joiner {
|
||||||
|
AND = 0;
|
||||||
|
OR = 1;
|
||||||
|
}
|
||||||
|
repeated SearchNode nodes = 1;
|
||||||
|
Joiner joiner = 2;
|
||||||
|
}
|
||||||
|
oneof filter {
|
||||||
|
Group group = 1;
|
||||||
|
SearchNode negated = 2;
|
||||||
|
string parsable_text = 3;
|
||||||
|
uint32 template = 4;
|
||||||
|
int64 nid = 5;
|
||||||
|
Dupe dupe = 6;
|
||||||
|
string field_name = 7;
|
||||||
|
Rated rated = 8;
|
||||||
|
uint32 added_in_days = 9;
|
||||||
|
int32 due_in_days = 10;
|
||||||
|
Flag flag = 11;
|
||||||
|
CardState card_state = 12;
|
||||||
|
IdList nids = 13;
|
||||||
|
uint32 edited_in_days = 14;
|
||||||
|
string deck = 15;
|
||||||
|
int32 due_on_day = 16;
|
||||||
|
string tag = 17;
|
||||||
|
string note = 18;
|
||||||
|
uint32 introduced_in_days = 19;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
message SearchRequest {
|
||||||
|
string search = 1;
|
||||||
|
SortOrder order = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message SearchResponse {
|
||||||
|
repeated int64 ids = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message SortOrder {
|
||||||
|
message Builtin {
|
||||||
|
string column = 1;
|
||||||
|
bool reverse = 2;
|
||||||
|
}
|
||||||
|
oneof value {
|
||||||
|
generic.Empty none = 1;
|
||||||
|
string custom = 2;
|
||||||
|
Builtin builtin = 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
message JoinSearchNodesRequest {
|
||||||
|
SearchNode.Group.Joiner joiner = 1;
|
||||||
|
SearchNode existing_node = 2;
|
||||||
|
SearchNode additional_node = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ReplaceSearchNodeRequest {
|
||||||
|
SearchNode existing_node = 1;
|
||||||
|
SearchNode replacement_node = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message FindAndReplaceRequest {
|
||||||
|
repeated int64 nids = 1;
|
||||||
|
string search = 2;
|
||||||
|
string replacement = 3;
|
||||||
|
bool regex = 4;
|
||||||
|
bool match_case = 5;
|
||||||
|
string field_name = 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
message BrowserColumns {
|
||||||
|
enum Sorting {
|
||||||
|
SORTING_NONE = 0;
|
||||||
|
SORTING_NORMAL = 1;
|
||||||
|
SORTING_REVERSED = 2;
|
||||||
|
}
|
||||||
|
enum Alignment {
|
||||||
|
ALIGNMENT_START = 0;
|
||||||
|
ALIGNMENT_CENTER = 1;
|
||||||
|
}
|
||||||
|
message Column {
|
||||||
|
string key = 1;
|
||||||
|
string cards_mode_label = 2;
|
||||||
|
string notes_mode_label = 3;
|
||||||
|
Sorting sorting = 4;
|
||||||
|
bool uses_cell_font = 5;
|
||||||
|
Alignment alignment = 6;
|
||||||
|
}
|
||||||
|
repeated Column columns = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message BrowserRow {
|
||||||
|
message Cell {
|
||||||
|
string text = 1;
|
||||||
|
bool is_rtl = 2;
|
||||||
|
}
|
||||||
|
enum Color {
|
||||||
|
COLOR_DEFAULT = 0;
|
||||||
|
COLOR_MARKED = 1;
|
||||||
|
COLOR_SUSPENDED = 2;
|
||||||
|
COLOR_FLAG_RED = 3;
|
||||||
|
COLOR_FLAG_ORANGE = 4;
|
||||||
|
COLOR_FLAG_GREEN = 5;
|
||||||
|
COLOR_FLAG_BLUE = 6;
|
||||||
|
COLOR_FLAG_PINK = 7;
|
||||||
|
COLOR_FLAG_TURQUOISE = 8;
|
||||||
|
COLOR_FLAG_PURPLE = 9;
|
||||||
|
}
|
||||||
|
repeated Cell cells = 1;
|
||||||
|
Color color = 2;
|
||||||
|
string font_name = 3;
|
||||||
|
uint32 font_size = 4;
|
||||||
|
}
|
76
proto/anki/sync.proto
Normal file
76
proto/anki/sync.proto
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
// Copyright: Ankitects Pty Ltd and contributors
|
||||||
|
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
|
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package anki.sync;
|
||||||
|
|
||||||
|
import "anki/generic.proto";
|
||||||
|
|
||||||
|
service SyncService {
|
||||||
|
rpc SyncMedia(SyncAuth) returns (generic.Empty);
|
||||||
|
rpc AbortSync(generic.Empty) returns (generic.Empty);
|
||||||
|
rpc AbortMediaSync(generic.Empty) returns (generic.Empty);
|
||||||
|
rpc BeforeUpload(generic.Empty) returns (generic.Empty);
|
||||||
|
rpc SyncLogin(SyncLoginRequest) returns (SyncAuth);
|
||||||
|
rpc SyncStatus(SyncAuth) returns (SyncStatusResponse);
|
||||||
|
rpc SyncCollection(SyncAuth) returns (SyncCollectionResponse);
|
||||||
|
rpc FullUpload(SyncAuth) returns (generic.Empty);
|
||||||
|
rpc FullDownload(SyncAuth) returns (generic.Empty);
|
||||||
|
rpc SyncServerMethod(SyncServerMethodRequest) returns (generic.Json);
|
||||||
|
}
|
||||||
|
|
||||||
|
message SyncAuth {
|
||||||
|
string hkey = 1;
|
||||||
|
uint32 host_number = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message SyncLoginRequest {
|
||||||
|
string username = 1;
|
||||||
|
string password = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message SyncStatusResponse {
|
||||||
|
enum Required {
|
||||||
|
NO_CHANGES = 0;
|
||||||
|
NORMAL_SYNC = 1;
|
||||||
|
FULL_SYNC = 2;
|
||||||
|
}
|
||||||
|
Required required = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message SyncCollectionResponse {
|
||||||
|
enum ChangesRequired {
|
||||||
|
NO_CHANGES = 0;
|
||||||
|
NORMAL_SYNC = 1;
|
||||||
|
FULL_SYNC = 2;
|
||||||
|
// local collection has no cards; upload not an option
|
||||||
|
FULL_DOWNLOAD = 3;
|
||||||
|
// remote collection has no cards; download not an option
|
||||||
|
FULL_UPLOAD = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 host_number = 1;
|
||||||
|
string server_message = 2;
|
||||||
|
ChangesRequired required = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message SyncServerMethodRequest {
|
||||||
|
enum Method {
|
||||||
|
HOST_KEY = 0;
|
||||||
|
META = 1;
|
||||||
|
START = 2;
|
||||||
|
APPLY_GRAVES = 3;
|
||||||
|
APPLY_CHANGES = 4;
|
||||||
|
CHUNK = 5;
|
||||||
|
APPLY_CHUNK = 6;
|
||||||
|
SANITY_CHECK = 7;
|
||||||
|
FINISH = 8;
|
||||||
|
ABORT = 9;
|
||||||
|
// caller must reopen after these two are called
|
||||||
|
FULL_UPLOAD = 10;
|
||||||
|
FULL_DOWNLOAD = 11;
|
||||||
|
}
|
||||||
|
Method method = 1;
|
||||||
|
bytes data = 2;
|
||||||
|
}
|
|
@ -16,6 +16,10 @@ import anki.decks_pb2
|
||||||
import anki.deckconfig_pb2
|
import anki.deckconfig_pb2
|
||||||
import anki.notes_pb2
|
import anki.notes_pb2
|
||||||
import anki.notetypes_pb2
|
import anki.notetypes_pb2
|
||||||
|
import anki.scheduler_pb2
|
||||||
|
import anki.sync_pb2
|
||||||
|
import anki.configs_pb2
|
||||||
|
import anki.search_pb2
|
||||||
|
|
||||||
import stringcase
|
import stringcase
|
||||||
|
|
||||||
|
@ -179,6 +183,10 @@ service_modules = dict(
|
||||||
DECKS=anki.decks_pb2,
|
DECKS=anki.decks_pb2,
|
||||||
DECK_CONFIG=anki.deckconfig_pb2,
|
DECK_CONFIG=anki.deckconfig_pb2,
|
||||||
NOTETYPES=anki.notetypes_pb2,
|
NOTETYPES=anki.notetypes_pb2,
|
||||||
|
SCHEDULER=anki.scheduler_pb2,
|
||||||
|
SYNC=anki.sync_pb2,
|
||||||
|
CONFIGS=anki.configs_pb2,
|
||||||
|
SEARCH=anki.search_pb2,
|
||||||
)
|
)
|
||||||
|
|
||||||
for service in anki.backend_pb2.ServiceIndex.DESCRIPTOR.values:
|
for service in anki.backend_pb2.ServiceIndex.DESCRIPTOR.values:
|
||||||
|
|
|
@ -8,22 +8,22 @@ from __future__ import annotations
|
||||||
from typing import Any, Generator, List, Literal, Optional, Sequence, Tuple, Union, cast
|
from typing import Any, Generator, List, Literal, Optional, Sequence, Tuple, Union, cast
|
||||||
|
|
||||||
import anki.backend_pb2 as _pb
|
import anki.backend_pb2 as _pb
|
||||||
from anki import collection_pb2
|
from anki import collection_pb2, configs_pb2, generic_pb2, search_pb2
|
||||||
from anki._legacy import DeprecatedNamesMixin, deprecated
|
from anki._legacy import DeprecatedNamesMixin, deprecated
|
||||||
|
|
||||||
# protobuf we publicly export - listed first to avoid circular imports
|
# protobuf we publicly export - listed first to avoid circular imports
|
||||||
SearchNode = _pb.SearchNode
|
SearchNode = search_pb2.SearchNode
|
||||||
Progress = collection_pb2.Progress
|
Progress = collection_pb2.Progress
|
||||||
EmptyCardsReport = _pb.EmptyCardsReport
|
EmptyCardsReport = _pb.EmptyCardsReport
|
||||||
GraphPreferences = _pb.GraphPreferences
|
GraphPreferences = _pb.GraphPreferences
|
||||||
Preferences = _pb.Preferences
|
Preferences = configs_pb2.Preferences
|
||||||
UndoStatus = collection_pb2.UndoStatus
|
UndoStatus = collection_pb2.UndoStatus
|
||||||
OpChanges = collection_pb2.OpChanges
|
OpChanges = collection_pb2.OpChanges
|
||||||
OpChangesWithCount = collection_pb2.OpChangesWithCount
|
OpChangesWithCount = collection_pb2.OpChangesWithCount
|
||||||
OpChangesWithId = collection_pb2.OpChangesWithId
|
OpChangesWithId = collection_pb2.OpChangesWithId
|
||||||
OpChangesAfterUndo = collection_pb2.OpChangesAfterUndo
|
OpChangesAfterUndo = collection_pb2.OpChangesAfterUndo
|
||||||
BrowserRow = _pb.BrowserRow
|
BrowserRow = search_pb2.BrowserRow
|
||||||
BrowserColumns = _pb.BrowserColumns
|
BrowserColumns = search_pb2.BrowserColumns
|
||||||
|
|
||||||
import copy
|
import copy
|
||||||
import os
|
import os
|
||||||
|
@ -34,7 +34,7 @@ import weakref
|
||||||
from dataclasses import dataclass, field
|
from dataclasses import dataclass, field
|
||||||
|
|
||||||
import anki.latex
|
import anki.latex
|
||||||
from anki import generic_pb2, hooks
|
from anki import hooks
|
||||||
from anki._backend import RustBackend, Translations
|
from anki._backend import RustBackend, Translations
|
||||||
from anki.browser import BrowserConfig, BrowserDefaults
|
from anki.browser import BrowserConfig, BrowserDefaults
|
||||||
from anki.cards import Card, CardId
|
from anki.cards import Card, CardId
|
||||||
|
@ -486,12 +486,12 @@ class Collection(DeprecatedNamesMixin):
|
||||||
order: Union[bool, str, BrowserColumns.Column],
|
order: Union[bool, str, BrowserColumns.Column],
|
||||||
reverse: bool,
|
reverse: bool,
|
||||||
finding_notes: bool,
|
finding_notes: bool,
|
||||||
) -> _pb.SortOrder:
|
) -> search_pb2.SortOrder:
|
||||||
if isinstance(order, str):
|
if isinstance(order, str):
|
||||||
return _pb.SortOrder(custom=order)
|
return search_pb2.SortOrder(custom=order)
|
||||||
if isinstance(order, bool):
|
if isinstance(order, bool):
|
||||||
if order is False:
|
if order is False:
|
||||||
return _pb.SortOrder(none=generic_pb2.Empty())
|
return search_pb2.SortOrder(none=generic_pb2.Empty())
|
||||||
# order=True: set args to sort column and reverse from config
|
# order=True: set args to sort column and reverse from config
|
||||||
sort_key = BrowserConfig.sort_column_key(finding_notes)
|
sort_key = BrowserConfig.sort_column_key(finding_notes)
|
||||||
order = self.get_browser_column(self.get_config(sort_key))
|
order = self.get_browser_column(self.get_config(sort_key))
|
||||||
|
@ -499,13 +499,15 @@ class Collection(DeprecatedNamesMixin):
|
||||||
reverse = self.get_config(reverse_key)
|
reverse = self.get_config(reverse_key)
|
||||||
if isinstance(order, BrowserColumns.Column):
|
if isinstance(order, BrowserColumns.Column):
|
||||||
if order.sorting != BrowserColumns.SORTING_NONE:
|
if order.sorting != BrowserColumns.SORTING_NONE:
|
||||||
return _pb.SortOrder(
|
return search_pb2.SortOrder(
|
||||||
builtin=_pb.SortOrder.Builtin(column=order.key, reverse=reverse)
|
builtin=search_pb2.SortOrder.Builtin(
|
||||||
|
column=order.key, reverse=reverse
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
# eg, user is ordering on an add-on field with the add-on not installed
|
# eg, user is ordering on an add-on field with the add-on not installed
|
||||||
print(f"{order} is not a valid sort order.")
|
print(f"{order} is not a valid sort order.")
|
||||||
return _pb.SortOrder(none=generic_pb2.Empty())
|
return search_pb2.SortOrder(none=generic_pb2.Empty())
|
||||||
|
|
||||||
def find_and_replace(
|
def find_and_replace(
|
||||||
self,
|
self,
|
||||||
|
|
|
@ -25,12 +25,12 @@ from typing import Any
|
||||||
from weakref import ref
|
from weakref import ref
|
||||||
|
|
||||||
import anki
|
import anki
|
||||||
from anki import backend_pb2 as _pb
|
from anki import configs_pb2
|
||||||
from anki.collection import OpChanges
|
from anki.collection import OpChanges
|
||||||
from anki.errors import NotFoundError
|
from anki.errors import NotFoundError
|
||||||
from anki.utils import from_json_bytes, to_json_bytes
|
from anki.utils import from_json_bytes, to_json_bytes
|
||||||
|
|
||||||
Config = _pb.Config
|
Config = configs_pb2.Config
|
||||||
|
|
||||||
|
|
||||||
class ConfigManager:
|
class ConfigManager:
|
||||||
|
|
1
pylib/anki/configs_pb2.pyi
Symbolic link
1
pylib/anki/configs_pb2.pyi
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../../bazel-bin/pylib/anki/configs_pb2.pyi
|
1
pylib/anki/deckconfig_pb2.pyi
Symbolic link
1
pylib/anki/deckconfig_pb2.pyi
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../../bazel-bin/pylib/anki/deckconfig_pb2.pyi
|
1
pylib/anki/decks_pb2.pyi
Symbolic link
1
pylib/anki/decks_pb2.pyi
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../../bazel-bin/pylib/anki/decks_pb2.pyi
|
1
pylib/anki/notes_pb2.pyi
Symbolic link
1
pylib/anki/notes_pb2.pyi
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../../bazel-bin/pylib/anki/notes_pb2.pyi
|
1
pylib/anki/notetypes_pb2.pyi
Symbolic link
1
pylib/anki/notetypes_pb2.pyi
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../../bazel-bin/pylib/anki/notetypes_pb2.pyi
|
|
@ -4,12 +4,15 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import anki
|
import anki
|
||||||
import anki.backend_pb2 as _pb
|
from anki import decks_pb2, scheduler_pb2
|
||||||
from anki import decks_pb2
|
|
||||||
from anki.collection import OpChanges, OpChangesWithCount, OpChangesWithId
|
from anki.collection import OpChanges, OpChangesWithCount, OpChangesWithId
|
||||||
from anki.config import Config
|
from anki.config import Config
|
||||||
|
|
||||||
SchedTimingToday = _pb.SchedTimingTodayResponse
|
SchedTimingToday = scheduler_pb2.SchedTimingTodayResponse
|
||||||
|
CongratsInfo = scheduler_pb2.CongratsInfoResponse
|
||||||
|
UnburyDeck = scheduler_pb2.UnburyDeckRequest
|
||||||
|
BuryOrSuspend = scheduler_pb2.BuryOrSuspendCardsRequest
|
||||||
|
FilteredDeckForUpdate = decks_pb2.FilteredDeckForUpdate
|
||||||
|
|
||||||
|
|
||||||
from typing import List, Optional, Sequence
|
from typing import List, Optional, Sequence
|
||||||
|
@ -20,11 +23,6 @@ from anki.decks import DeckConfigDict, DeckId, DeckTreeNode
|
||||||
from anki.notes import NoteId
|
from anki.notes import NoteId
|
||||||
from anki.utils import ids2str, intTime
|
from anki.utils import ids2str, intTime
|
||||||
|
|
||||||
CongratsInfo = _pb.CongratsInfoResponse
|
|
||||||
UnburyDeck = _pb.UnburyDeckRequest
|
|
||||||
BuryOrSuspend = _pb.BuryOrSuspendCardsRequest
|
|
||||||
FilteredDeckForUpdate = decks_pb2.FilteredDeckForUpdate
|
|
||||||
|
|
||||||
|
|
||||||
class SchedulerBase:
|
class SchedulerBase:
|
||||||
"Actions shared between schedulers."
|
"Actions shared between schedulers."
|
||||||
|
|
|
@ -11,8 +11,7 @@ from heapq import *
|
||||||
from typing import Any, Callable, Dict, List, Optional, Tuple, Union
|
from typing import Any, Callable, Dict, List, Optional, Tuple, Union
|
||||||
|
|
||||||
import anki # pylint: disable=unused-import
|
import anki # pylint: disable=unused-import
|
||||||
import anki.backend_pb2 as _pb
|
from anki import hooks, scheduler_pb2
|
||||||
from anki import hooks
|
|
||||||
from anki.cards import Card, CardId
|
from anki.cards import Card, CardId
|
||||||
from anki.consts import *
|
from anki.consts import *
|
||||||
from anki.decks import DeckConfigDict, DeckDict, DeckId
|
from anki.decks import DeckConfigDict, DeckDict, DeckId
|
||||||
|
@ -20,8 +19,8 @@ from anki.lang import FormatTimeSpan
|
||||||
from anki.scheduler.legacy import SchedulerBaseWithLegacy
|
from anki.scheduler.legacy import SchedulerBaseWithLegacy
|
||||||
from anki.utils import ids2str, intTime
|
from anki.utils import ids2str, intTime
|
||||||
|
|
||||||
CountsForDeckToday = _pb.CountsForDeckTodayResponse
|
CountsForDeckToday = scheduler_pb2.CountsForDeckTodayResponse
|
||||||
SchedTimingToday = _pb.SchedTimingTodayResponse
|
SchedTimingToday = scheduler_pb2.SchedTimingTodayResponse
|
||||||
|
|
||||||
# legacy type alias
|
# legacy type alias
|
||||||
QueueConfig = Dict[str, Any]
|
QueueConfig = Dict[str, Any]
|
||||||
|
|
|
@ -14,7 +14,7 @@ from __future__ import annotations
|
||||||
|
|
||||||
from typing import List, Literal, Sequence, Tuple
|
from typing import List, Literal, Sequence, Tuple
|
||||||
|
|
||||||
import anki.backend_pb2 as _pb
|
from anki import scheduler_pb2
|
||||||
from anki.cards import Card
|
from anki.cards import Card
|
||||||
from anki.collection import OpChanges
|
from anki.collection import OpChanges
|
||||||
from anki.consts import *
|
from anki.consts import *
|
||||||
|
@ -24,10 +24,10 @@ from anki.scheduler.legacy import SchedulerBaseWithLegacy
|
||||||
from anki.types import assert_exhaustive
|
from anki.types import assert_exhaustive
|
||||||
from anki.utils import intTime
|
from anki.utils import intTime
|
||||||
|
|
||||||
QueuedCards = _pb.QueuedCards
|
QueuedCards = scheduler_pb2.QueuedCards
|
||||||
SchedulingState = _pb.SchedulingState
|
SchedulingState = scheduler_pb2.SchedulingState
|
||||||
NextStates = _pb.NextCardStates
|
NextStates = scheduler_pb2.NextCardStates
|
||||||
CardAnswer = _pb.CardAnswer
|
CardAnswer = scheduler_pb2.CardAnswer
|
||||||
|
|
||||||
|
|
||||||
class Scheduler(SchedulerBaseWithLegacy):
|
class Scheduler(SchedulerBaseWithLegacy):
|
||||||
|
@ -171,7 +171,7 @@ class Scheduler(SchedulerBaseWithLegacy):
|
||||||
##########################################################################
|
##########################################################################
|
||||||
# fixme: move these into tests_schedv2 in the future
|
# fixme: move these into tests_schedv2 in the future
|
||||||
|
|
||||||
def _interval_for_state(self, state: _pb.SchedulingState) -> int:
|
def _interval_for_state(self, state: scheduler_pb2.SchedulingState) -> int:
|
||||||
kind = state.WhichOneof("value")
|
kind = state.WhichOneof("value")
|
||||||
if kind == "normal":
|
if kind == "normal":
|
||||||
return self._interval_for_normal_state(state.normal)
|
return self._interval_for_normal_state(state.normal)
|
||||||
|
@ -181,7 +181,9 @@ class Scheduler(SchedulerBaseWithLegacy):
|
||||||
assert_exhaustive(kind)
|
assert_exhaustive(kind)
|
||||||
return 0 # unreachable
|
return 0 # unreachable
|
||||||
|
|
||||||
def _interval_for_normal_state(self, normal: _pb.SchedulingState.Normal) -> int:
|
def _interval_for_normal_state(
|
||||||
|
self, normal: scheduler_pb2.SchedulingState.Normal
|
||||||
|
) -> int:
|
||||||
kind = normal.WhichOneof("value")
|
kind = normal.WhichOneof("value")
|
||||||
if kind == "new":
|
if kind == "new":
|
||||||
return 0
|
return 0
|
||||||
|
@ -196,7 +198,7 @@ class Scheduler(SchedulerBaseWithLegacy):
|
||||||
return 0 # unreachable
|
return 0 # unreachable
|
||||||
|
|
||||||
def _interval_for_filtered_state(
|
def _interval_for_filtered_state(
|
||||||
self, filtered: _pb.SchedulingState.Filtered
|
self, filtered: scheduler_pb2.SchedulingState.Filtered
|
||||||
) -> int:
|
) -> int:
|
||||||
kind = filtered.WhichOneof("value")
|
kind = filtered.WhichOneof("value")
|
||||||
if kind == "preview":
|
if kind == "preview":
|
||||||
|
|
1
pylib/anki/scheduler_pb2.pyi
Symbolic link
1
pylib/anki/scheduler_pb2.pyi
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../../bazel-bin/pylib/anki/scheduler_pb2.pyi
|
1
pylib/anki/search_pb2.pyi
Symbolic link
1
pylib/anki/search_pb2.pyi
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../../bazel-bin/pylib/anki/search_pb2.pyi
|
|
@ -1,12 +1,12 @@
|
||||||
# Copyright: Ankitects Pty Ltd and contributors
|
# Copyright: Ankitects Pty Ltd and contributors
|
||||||
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
|
|
||||||
import anki.backend_pb2 as _pb
|
from anki import sync_pb2
|
||||||
|
|
||||||
# public exports
|
# public exports
|
||||||
SyncAuth = _pb.SyncAuth
|
SyncAuth = sync_pb2.SyncAuth
|
||||||
SyncOutput = _pb.SyncCollectionResponse
|
SyncOutput = sync_pb2.SyncCollectionResponse
|
||||||
SyncStatus = _pb.SyncStatusResponse
|
SyncStatus = sync_pb2.SyncStatusResponse
|
||||||
|
|
||||||
|
|
||||||
# Legacy attributes some add-ons may be using
|
# Legacy attributes some add-ons may be using
|
||||||
|
|
1
pylib/anki/sync_pb2.pyi
Symbolic link
1
pylib/anki/sync_pb2.pyi
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../../bazel-bin/pylib/anki/sync_pb2.pyi
|
|
@ -27,7 +27,7 @@ except ImportError as e:
|
||||||
from flask import Response
|
from flask import Response
|
||||||
|
|
||||||
from anki import Collection
|
from anki import Collection
|
||||||
from anki.backend_pb2 import SyncServerMethodRequest
|
from anki.sync_pb2 import SyncServerMethodRequest
|
||||||
|
|
||||||
Method = SyncServerMethodRequest.Method # pylint: disable=no-member
|
Method = SyncServerMethodRequest.Method # pylint: disable=no-member
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
|
|
||||||
use super::Backend;
|
use super::Backend;
|
||||||
pub(super) use crate::backend_proto::config_service::Service as ConfigService;
|
pub(super) use crate::backend_proto::configs_service::Service as ConfigsService;
|
||||||
use crate::{
|
use crate::{
|
||||||
backend_proto as pb,
|
backend_proto as pb,
|
||||||
backend_proto::config::{bool::Key as BoolKeyProto, string::Key as StringKeyProto},
|
backend_proto::config::{bool::Key as BoolKeyProto, string::Key as StringKeyProto},
|
||||||
|
@ -52,7 +52,7 @@ impl From<pb::config::String> for StringKey {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ConfigService for Backend {
|
impl ConfigsService for Backend {
|
||||||
fn get_config_json(&self, input: pb::String) -> Result<pb::Json> {
|
fn get_config_json(&self, input: pb::String) -> Result<pb::Json> {
|
||||||
self.with_col(|col| {
|
self.with_col(|col| {
|
||||||
let val: Option<Value> = col.get_config_optional(input.val.as_str());
|
let val: Option<Value> = col.get_config_optional(input.val.as_str());
|
||||||
|
|
|
@ -40,7 +40,7 @@ use self::{
|
||||||
card::CardsService,
|
card::CardsService,
|
||||||
cardrendering::CardRenderingService,
|
cardrendering::CardRenderingService,
|
||||||
collection::CollectionService,
|
collection::CollectionService,
|
||||||
config::ConfigService,
|
config::ConfigsService,
|
||||||
deckconfig::DeckConfigService,
|
deckconfig::DeckConfigService,
|
||||||
decks::DecksService,
|
decks::DecksService,
|
||||||
i18n::I18nService,
|
i18n::I18nService,
|
||||||
|
@ -48,7 +48,7 @@ use self::{
|
||||||
notes::NotesService,
|
notes::NotesService,
|
||||||
notetypes::NotetypesService,
|
notetypes::NotetypesService,
|
||||||
progress::ProgressState,
|
progress::ProgressState,
|
||||||
scheduler::SchedulingService,
|
scheduler::SchedulerService,
|
||||||
search::SearchService,
|
search::SearchService,
|
||||||
stats::StatsService,
|
stats::StatsService,
|
||||||
sync::{SyncService, SyncState},
|
sync::{SyncService, SyncState},
|
||||||
|
@ -117,11 +117,11 @@ impl Backend {
|
||||||
pb::ServiceIndex::from_i32(service as i32)
|
pb::ServiceIndex::from_i32(service as i32)
|
||||||
.ok_or_else(|| AnkiError::invalid_input("invalid service"))
|
.ok_or_else(|| AnkiError::invalid_input("invalid service"))
|
||||||
.and_then(|service| match service {
|
.and_then(|service| match service {
|
||||||
pb::ServiceIndex::Scheduling => SchedulingService::run_method(self, method, input),
|
pb::ServiceIndex::Scheduler => SchedulerService::run_method(self, method, input),
|
||||||
pb::ServiceIndex::Decks => DecksService::run_method(self, method, input),
|
pb::ServiceIndex::Decks => DecksService::run_method(self, method, input),
|
||||||
pb::ServiceIndex::Notes => NotesService::run_method(self, method, input),
|
pb::ServiceIndex::Notes => NotesService::run_method(self, method, input),
|
||||||
pb::ServiceIndex::Notetypes => NotetypesService::run_method(self, method, input),
|
pb::ServiceIndex::Notetypes => NotetypesService::run_method(self, method, input),
|
||||||
pb::ServiceIndex::Config => ConfigService::run_method(self, method, input),
|
pb::ServiceIndex::Configs => ConfigsService::run_method(self, method, input),
|
||||||
pb::ServiceIndex::Sync => SyncService::run_method(self, method, input),
|
pb::ServiceIndex::Sync => SyncService::run_method(self, method, input),
|
||||||
pb::ServiceIndex::Tags => TagsService::run_method(self, method, input),
|
pb::ServiceIndex::Tags => TagsService::run_method(self, method, input),
|
||||||
pb::ServiceIndex::DeckConfig => DeckConfigService::run_method(self, method, input),
|
pb::ServiceIndex::DeckConfig => DeckConfigService::run_method(self, method, input),
|
||||||
|
|
|
@ -5,7 +5,7 @@ mod answering;
|
||||||
mod states;
|
mod states;
|
||||||
|
|
||||||
use super::Backend;
|
use super::Backend;
|
||||||
pub(super) use crate::backend_proto::scheduling_service::Service as SchedulingService;
|
pub(super) use crate::backend_proto::scheduler_service::Service as SchedulerService;
|
||||||
use crate::{
|
use crate::{
|
||||||
backend_proto::{self as pb},
|
backend_proto::{self as pb},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
|
@ -16,7 +16,7 @@ use crate::{
|
||||||
stats::studied_today,
|
stats::studied_today,
|
||||||
};
|
};
|
||||||
|
|
||||||
impl SchedulingService for Backend {
|
impl SchedulerService for Backend {
|
||||||
/// This behaves like _updateCutoff() in older code - it also unburies at the start of
|
/// This behaves like _updateCutoff() in older code - it also unburies at the start of
|
||||||
/// a new day.
|
/// a new day.
|
||||||
fn sched_timing_today(&self, _input: pb::Empty) -> Result<pb::SchedTimingTodayResponse> {
|
fn sched_timing_today(&self, _input: pb::Empty) -> Result<pb::SchedTimingTodayResponse> {
|
||||||
|
|
|
@ -14,11 +14,15 @@ macro_rules! protobuf {
|
||||||
}
|
}
|
||||||
|
|
||||||
protobuf!(backend);
|
protobuf!(backend);
|
||||||
|
protobuf!(cards);
|
||||||
|
protobuf!(collection);
|
||||||
|
protobuf!(configs);
|
||||||
|
protobuf!(deckconfig);
|
||||||
|
protobuf!(decks);
|
||||||
|
protobuf!(generic);
|
||||||
|
protobuf!(i18n);
|
||||||
protobuf!(notes);
|
protobuf!(notes);
|
||||||
protobuf!(notetypes);
|
protobuf!(notetypes);
|
||||||
protobuf!(decks);
|
protobuf!(scheduler);
|
||||||
protobuf!(deckconfig);
|
protobuf!(search);
|
||||||
protobuf!(i18n);
|
protobuf!(sync);
|
||||||
protobuf!(cards);
|
|
||||||
protobuf!(generic);
|
|
||||||
protobuf!(collection);
|
|
||||||
|
|
|
@ -3,11 +3,11 @@ Copyright: Ankitects Pty Ltd and contributors
|
||||||
License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { Backend } from "lib/proto";
|
import type { Scheduler } from "lib/proto";
|
||||||
import { buildNextLearnMsg } from "./lib";
|
import { buildNextLearnMsg } from "./lib";
|
||||||
import { bridgeLink } from "lib/bridgecommand";
|
import { bridgeLink } from "lib/bridgecommand";
|
||||||
|
|
||||||
export let info: Backend.CongratsInfoResponse;
|
export let info: Scheduler.CongratsInfoResponse;
|
||||||
import * as tr from "lib/i18n";
|
import * as tr from "lib/i18n";
|
||||||
|
|
||||||
const congrats = tr.schedulingCongratulationsFinished();
|
const congrats = tr.schedulingCongratulationsFinished();
|
||||||
|
|
|
@ -1,19 +1,19 @@
|
||||||
// Copyright: Ankitects Pty Ltd and contributors
|
// Copyright: Ankitects Pty Ltd and contributors
|
||||||
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
|
|
||||||
import { Backend } from "lib/proto";
|
import { Scheduler } from "lib/proto";
|
||||||
import { postRequest } from "lib/postrequest";
|
import { postRequest } from "lib/postrequest";
|
||||||
import { naturalUnit, unitAmount, unitName } from "lib/time";
|
import { naturalUnit, unitAmount, unitName } from "lib/time";
|
||||||
|
|
||||||
import * as tr from "lib/i18n";
|
import * as tr from "lib/i18n";
|
||||||
|
|
||||||
export async function getCongratsInfo(): Promise<Backend.CongratsInfoResponse> {
|
export async function getCongratsInfo(): Promise<Scheduler.CongratsInfoResponse> {
|
||||||
return Backend.CongratsInfoResponse.decode(
|
return Scheduler.CongratsInfoResponse.decode(
|
||||||
await postRequest("/_anki/congratsInfo", "")
|
await postRequest("/_anki/congratsInfo", "")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function buildNextLearnMsg(info: Backend.CongratsInfoResponse): string {
|
export function buildNextLearnMsg(info: Scheduler.CongratsInfoResponse): string {
|
||||||
const secsUntil = info.secsUntilNextLearn;
|
const secsUntil = info.secsUntilNextLearn;
|
||||||
// next learning card not due (/ until tomorrow)?
|
// next learning card not due (/ until tomorrow)?
|
||||||
if (secsUntil == 0 || secsUntil > 86_400) {
|
if (secsUntil == 0 || secsUntil > 86_400) {
|
||||||
|
|
|
@ -6,4 +6,5 @@ import Backend = anki.backend;
|
||||||
import Cards = anki.cards;
|
import Cards = anki.cards;
|
||||||
import DeckConfig = anki.deckconfig;
|
import DeckConfig = anki.deckconfig;
|
||||||
import Notetypes = anki.notetypes;
|
import Notetypes = anki.notetypes;
|
||||||
export { Backend, Cards, DeckConfig, Notetypes };
|
import Scheduler = anki.scheduler;
|
||||||
|
export { Backend, Cards, DeckConfig, Notetypes, Scheduler };
|
||||||
|
|
|
@ -1,26 +1,26 @@
|
||||||
// Copyright: Ankitects Pty Ltd and contributors
|
// Copyright: Ankitects Pty Ltd and contributors
|
||||||
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
|
|
||||||
import { Backend } from "lib/proto";
|
import { Scheduler } from "lib/proto";
|
||||||
import { postRequest } from "lib/postrequest";
|
import { postRequest } from "lib/postrequest";
|
||||||
|
|
||||||
async function getNextStates(): Promise<Backend.NextCardStates> {
|
async function getNextStates(): Promise<Scheduler.NextCardStates> {
|
||||||
return Backend.NextCardStates.decode(
|
return Scheduler.NextCardStates.decode(
|
||||||
await postRequest("/_anki/nextCardStates", "")
|
await postRequest("/_anki/nextCardStates", "")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function setNextStates(
|
async function setNextStates(
|
||||||
key: string,
|
key: string,
|
||||||
states: Backend.NextCardStates
|
states: Scheduler.NextCardStates
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const data: Uint8Array = Backend.NextCardStates.encode(states).finish();
|
const data: Uint8Array = Scheduler.NextCardStates.encode(states).finish();
|
||||||
await postRequest("/_anki/setNextCardStates", data, { key });
|
await postRequest("/_anki/setNextCardStates", data, { key });
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function mutateNextCardStates(
|
export async function mutateNextCardStates(
|
||||||
key: string,
|
key: string,
|
||||||
mutator: (states: Backend.NextCardStates) => void
|
mutator: (states: Scheduler.NextCardStates) => void
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const states = await getNextStates();
|
const states = await getNextStates();
|
||||||
mutator(states);
|
mutator(states);
|
||||||
|
|
Loading…
Reference in a new issue