// Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html syntax = "proto3"; package BackendProto; // Generic containers /////////////////////////////////////////////////////////// message Empty {} message OptionalInt32 { sint32 val = 1; } message OptionalUInt32 { uint32 val = 1; } message Int32 { sint32 val = 1; } message UInt32 { uint32 val = 1; } message Int64 { int64 val = 1; } message String { string val = 1; } message Json { bytes json = 1; } message Bool { bool val = 1; } message StringList { repeated string vals = 1; } message OpChangesWithCount { uint32 count = 1; OpChanges changes = 2; } message OpChangesWithId { int64 id = 1; OpChanges changes = 2; } // IDs used in RPC calls /////////////////////////////////////////////////////////// message NotetypeId { int64 ntid = 1; } message NoteId { int64 nid = 1; } message CardId { int64 cid = 1; } message CardIds { repeated int64 cids = 1; } message DeckId { int64 did = 1; } message DeckIds { repeated int64 dids = 1; } message DeckConfigId { int64 dcid = 1; } // Backend methods /////////////////////////////////////////////////////////// /// while the protobuf descriptors expose the order services are defined in, /// that information is not available in prost, so we define an enum to make /// sure all clients agree on the service index enum ServiceIndex { SERVICE_INDEX_SCHEDULING = 0; SERVICE_INDEX_DECKS = 1; SERVICE_INDEX_NOTES = 2; SERVICE_INDEX_SYNC = 3; SERVICE_INDEX_NOTETYPES = 4; SERVICE_INDEX_CONFIG = 5; SERVICE_INDEX_CARD_RENDERING = 6; SERVICE_INDEX_DECK_CONFIG = 7; SERVICE_INDEX_TAGS = 8; SERVICE_INDEX_SEARCH = 9; SERVICE_INDEX_STATS = 10; SERVICE_INDEX_MEDIA = 11; SERVICE_INDEX_I18N = 12; SERVICE_INDEX_COLLECTION = 13; SERVICE_INDEX_CARDS = 14; } service SchedulingService { rpc SchedTimingToday(Empty) returns (SchedTimingTodayOut); rpc StudiedToday(Empty) returns (String); rpc StudiedTodayMessage(StudiedTodayMessageIn) returns (String); rpc UpdateStats(UpdateStatsIn) returns (Empty); rpc ExtendLimits(ExtendLimitsIn) returns (Empty); rpc CountsForDeckToday(DeckId) returns (CountsForDeckTodayOut); rpc CongratsInfo(Empty) returns (CongratsInfoOut); rpc RestoreBuriedAndSuspendedCards(CardIds) returns (OpChanges); rpc UnburyDeck(UnburyDeckIn) returns (OpChanges); rpc BuryOrSuspendCards(BuryOrSuspendCardsIn) returns (OpChangesWithCount); rpc EmptyFilteredDeck(DeckId) returns (OpChanges); rpc RebuildFilteredDeck(DeckId) returns (OpChangesWithCount); rpc ScheduleCardsAsNew(ScheduleCardsAsNewIn) returns (OpChanges); rpc SetDueDate(SetDueDateIn) returns (OpChanges); rpc SortCards(SortCardsIn) returns (OpChangesWithCount); rpc SortDeck(SortDeckIn) returns (OpChangesWithCount); rpc GetNextCardStates(CardId) returns (NextCardStates); rpc DescribeNextStates(NextCardStates) returns (StringList); rpc StateIsLeech(SchedulingState) returns (Bool); rpc AnswerCard(CardAnswer) returns (OpChanges); rpc UpgradeScheduler(Empty) returns (Empty); rpc GetQueuedCards(GetQueuedCardsIn) returns (GetQueuedCardsOut); } service DecksService { rpc AddDeckLegacy(Json) returns (OpChangesWithId); rpc AddOrUpdateDeckLegacy(AddOrUpdateDeckLegacyIn) returns (DeckId); rpc DeckTree(DeckTreeIn) returns (DeckTreeNode); rpc DeckTreeLegacy(Empty) returns (Json); rpc GetAllDecksLegacy(Empty) returns (Json); rpc GetDeckIdByName(String) returns (DeckId); rpc GetDeck(DeckId) returns (Deck); rpc UpdateDeck(Deck) returns (OpChanges); rpc SetDeckCollapsed(SetDeckCollapsedIn) returns (OpChanges); rpc GetDeckLegacy(DeckId) returns (Json); rpc GetDeckNames(GetDeckNamesIn) returns (DeckNames); rpc NewDeckLegacy(Bool) returns (Json); rpc RemoveDecks(DeckIds) returns (OpChangesWithCount); rpc ReparentDecks(ReparentDecksIn) returns (OpChangesWithCount); rpc RenameDeck(RenameDeckIn) returns (OpChanges); rpc GetOrCreateFilteredDeck(DeckId) returns (FilteredDeckForUpdate); rpc AddOrUpdateFilteredDeck(FilteredDeckForUpdate) returns (OpChangesWithId); rpc FilteredDeckOrderLabels(Empty) returns (StringList); rpc SetCurrentDeck(DeckId) returns (OpChanges); rpc GetCurrentDeck(Empty) returns (Deck); } service NotesService { rpc NewNote(NotetypeId) returns (Note); rpc AddNote(AddNoteIn) returns (AddNoteOut); rpc DefaultsForAdding(DefaultsForAddingIn) returns (DeckAndNotetype); rpc DefaultDeckForNotetype(NotetypeId) returns (DeckId); rpc UpdateNote(UpdateNoteIn) returns (OpChanges); rpc GetNote(NoteId) returns (Note); rpc RemoveNotes(RemoveNotesIn) returns (OpChangesWithCount); rpc ClozeNumbersInNote(Note) returns (ClozeNumbersInNoteOut); rpc AfterNoteUpdates(AfterNoteUpdatesIn) returns (OpChangesWithCount); rpc FieldNamesForNotes(FieldNamesForNotesIn) returns (FieldNamesForNotesOut); rpc NoteIsDuplicateOrEmpty(Note) returns (NoteIsDuplicateOrEmptyOut); rpc CardsOfNote(NoteId) returns (CardIds); } service SyncService { rpc SyncMedia(SyncAuth) returns (Empty); rpc AbortSync(Empty) returns (Empty); rpc AbortMediaSync(Empty) returns (Empty); rpc BeforeUpload(Empty) returns (Empty); rpc SyncLogin(SyncLoginIn) returns (SyncAuth); rpc SyncStatus(SyncAuth) returns (SyncStatusOut); rpc SyncCollection(SyncAuth) returns (SyncCollectionOut); rpc FullUpload(SyncAuth) returns (Empty); rpc FullDownload(SyncAuth) returns (Empty); rpc SyncServerMethod(SyncServerMethodIn) returns (Json); } service ConfigService { rpc GetConfigJson(String) returns (Json); rpc SetConfigJson(SetConfigJsonIn) returns (Empty); rpc RemoveConfig(String) returns (Empty); rpc GetAllConfig(Empty) returns (Json); rpc GetConfigBool(Config.Bool) returns (Bool); rpc SetConfigBool(SetConfigBoolIn) returns (Empty); rpc GetConfigString(Config.String) returns (String); rpc SetConfigString(SetConfigStringIn) returns (Empty); rpc GetPreferences(Empty) returns (Preferences); rpc SetPreferences(Preferences) returns (OpChanges); } service NotetypesService { rpc AddNotetype(Notetype) returns (OpChangesWithId); rpc UpdateNotetype(Notetype) returns (OpChanges); rpc AddNotetypeLegacy(Json) returns (OpChangesWithId); rpc UpdateNotetypeLegacy(Json) returns (OpChanges); rpc AddOrUpdateNotetype(AddOrUpdateNotetypeIn) returns (NotetypeId); rpc GetStockNotetypeLegacy(StockNotetype) returns (Json); rpc GetNotetype(NotetypeId) returns (Notetype); rpc GetNotetypeLegacy(NotetypeId) returns (Json); rpc GetNotetypeNames(Empty) returns (NotetypeNames); rpc GetNotetypeNamesAndCounts(Empty) returns (NotetypeUseCounts); rpc GetNotetypeIdByName(String) returns (NotetypeId); rpc RemoveNotetype(NotetypeId) returns (OpChanges); } service CardRenderingService { rpc ExtractAVTags(ExtractAVTagsIn) returns (ExtractAVTagsOut); rpc ExtractLatex(ExtractLatexIn) returns (ExtractLatexOut); rpc GetEmptyCards(Empty) returns (EmptyCardsReport); rpc RenderExistingCard(RenderExistingCardIn) returns (RenderCardOut); rpc RenderUncommittedCard(RenderUncommittedCardIn) returns (RenderCardOut); rpc StripAVTags(String) returns (String); rpc RenderMarkdown(RenderMarkdownIn) returns (String); } service DeckConfigService { rpc AddOrUpdateDeckConfigLegacy(AddOrUpdateDeckConfigLegacyIn) returns (DeckConfigId); rpc GetDeckConfig(DeckConfigId) returns (DeckConfig); rpc AllDeckConfigLegacy(Empty) returns (Json); rpc GetDeckConfigLegacy(DeckConfigId) returns (Json); rpc NewDeckConfigLegacy(Empty) returns (Json); rpc RemoveDeckConfig(DeckConfigId) returns (Empty); rpc GetDeckConfigsForUpdate(DeckId) returns (DeckConfigsForUpdate); rpc UpdateDeckConfigs(UpdateDeckConfigsIn) returns (OpChanges); } service TagsService { rpc ClearUnusedTags(Empty) returns (OpChangesWithCount); rpc AllTags(Empty) returns (StringList); rpc RemoveTags(String) returns (OpChangesWithCount); rpc SetTagCollapsed(SetTagCollapsedIn) returns (OpChanges); rpc TagTree(Empty) returns (TagTreeNode); rpc ReparentTags(ReparentTagsIn) returns (OpChangesWithCount); rpc RenameTags(RenameTagsIn) returns (OpChangesWithCount); rpc AddNoteTags(NoteIdsAndTagsIn) returns (OpChangesWithCount); rpc RemoveNoteTags(NoteIdsAndTagsIn) returns (OpChangesWithCount); rpc FindAndReplaceTag(FindAndReplaceTagIn) returns (OpChangesWithCount); } service SearchService { rpc BuildSearchString(SearchNode) returns (String); rpc SearchCards(SearchIn) returns (SearchOut); rpc SearchNotes(SearchIn) returns (SearchOut); rpc JoinSearchNodes(JoinSearchNodesIn) returns (String); rpc ReplaceSearchNode(ReplaceSearchNodeIn) returns (String); rpc FindAndReplace(FindAndReplaceIn) returns (OpChangesWithCount); rpc AllBrowserColumns(Empty) returns (BrowserColumns); rpc BrowserRowForId(Int64) returns (BrowserRow); rpc SetActiveBrowserColumns(StringList) returns (Empty); } service StatsService { rpc CardStats(CardId) returns (String); rpc Graphs(GraphsIn) returns (GraphsOut); rpc GetGraphPreferences(Empty) returns (GraphPreferences); rpc SetGraphPreferences(GraphPreferences) returns (Empty); } service MediaService { rpc CheckMedia(Empty) returns (CheckMediaOut); rpc TrashMediaFiles(TrashMediaFilesIn) returns (Empty); rpc AddMediaFile(AddMediaFileIn) returns (String); rpc EmptyTrash(Empty) returns (Empty); rpc RestoreTrash(Empty) returns (Empty); } service I18nService { rpc TranslateString(TranslateStringIn) returns (String); rpc FormatTimespan(FormatTimespanIn) returns (String); rpc I18nResources(I18nResourcesIn) returns (Json); } service CollectionService { rpc OpenCollection(OpenCollectionIn) returns (Empty); rpc CloseCollection(CloseCollectionIn) returns (Empty); rpc CheckDatabase(Empty) returns (CheckDatabaseOut); rpc GetUndoStatus(Empty) returns (UndoStatus); rpc Undo(Empty) returns (OpChangesAfterUndo); rpc Redo(Empty) returns (OpChangesAfterUndo); rpc AddCustomUndoEntry(String) returns (UInt32); rpc MergeUndoEntries(UInt32) returns (OpChanges); rpc LatestProgress(Empty) returns (Progress); rpc SetWantsAbort(Empty) returns (Empty); } service CardsService { rpc GetCard(CardId) returns (Card); rpc UpdateCard(UpdateCardIn) returns (OpChanges); rpc RemoveCards(RemoveCardsIn) returns (Empty); rpc SetDeck(SetDeckIn) returns (OpChanges); rpc SetFlag(SetFlagIn) returns (OpChanges); } // Protobuf stored in .anki2 files // These should be moved to a separate file in the future /////////////////////////////////////////////////////////// message DeckConfig { message Config { enum NewCardFetchOrder { NEW_CARD_FETCH_ORDER_DUE = 0; NEW_CARD_FETCH_ORDER_RANDOM = 1; } enum NewCardSortOrder { NEW_CARD_SORT_ORDER_TEMPLATE_THEN_DUE = 0; NEW_CARD_SORT_ORDER_TEMPLATE_THEN_RANDOM = 1; NEW_CARD_SORT_ORDER_DUE = 2; NEW_CARD_SORT_ORDER_RANDOM = 3; } enum ReviewCardOrder { REVIEW_CARD_ORDER_DAY_THEN_RANDOM = 0; REVIEW_CARD_ORDER_INTERVALS_ASCENDING = 1; REVIEW_CARD_ORDER_INTERVALS_DESCENDING = 2; // REVIEW_CARD_ORDER_RELATIVE_OVERDUE = 3; } enum ReviewMix { REVIEW_MIX_MIX_WITH_REVIEWS = 0; REVIEW_MIX_AFTER_REVIEWS = 1; REVIEW_MIX_BEFORE_REVIEWS = 2; } enum LeechAction { LEECH_ACTION_SUSPEND = 0; LEECH_ACTION_TAG_ONLY = 1; } repeated float learn_steps = 1; repeated float relearn_steps = 2; reserved 3 to 8; uint32 new_per_day = 9; uint32 reviews_per_day = 10; uint32 new_per_day_minimum = 29; float initial_ease = 11; float easy_multiplier = 12; float hard_multiplier = 13; float lapse_multiplier = 14; float interval_multiplier = 15; uint32 maximum_review_interval = 16; uint32 minimum_lapse_interval = 17; uint32 graduating_interval_good = 18; uint32 graduating_interval_easy = 19; NewCardFetchOrder new_card_fetch_order = 20; NewCardSortOrder new_card_sort_order = 32; ReviewCardOrder review_order = 33; ReviewMix new_mix = 30; ReviewMix interday_learning_mix = 31; LeechAction leech_action = 21; uint32 leech_threshold = 22; bool disable_autoplay = 23; uint32 cap_answer_time_to_secs = 24; bool show_timer = 25; bool skip_question_when_replaying_answer = 26; bool bury_new = 27; bool bury_reviews = 28; bytes other = 255; } int64 id = 1; string name = 2; int64 mtime_secs = 3; int32 usn = 4; Config config = 5; } message Deck { message Common { bool study_collapsed = 1; bool browser_collapsed = 2; uint32 last_day_studied = 3; int32 new_studied = 4; int32 review_studied = 5; int32 milliseconds_studied = 7; // previously set in the v1 scheduler, // but not currently used for anything int32 learning_studied = 6; reserved 8 to 13; bytes other = 255; } message Normal { int64 config_id = 1; uint32 extend_new = 2; uint32 extend_review = 3; string description = 4; bool markdown_description = 5; reserved 6 to 11; } message Filtered { message SearchTerm { enum Order { OLDEST_REVIEWED_FIRST = 0; RANDOM = 1; INTERVALS_ASCENDING = 2; INTERVALS_DESCENDING = 3; LAPSES = 4; ADDED = 5; DUE = 6; REVERSE_ADDED = 7; DUE_PRIORITY = 8; } string search = 1; uint32 limit = 2; Order order = 3; } bool reschedule = 1; repeated SearchTerm search_terms = 2; // v1 scheduler only repeated float delays = 3; // v2 scheduler only uint32 preview_delay = 4; } // a container to store the deck specifics in the DB // as a tagged enum message KindContainer { oneof kind { Normal normal = 1; Filtered filtered = 2; } } int64 id = 1; string name = 2; int64 mtime_secs = 3; int32 usn = 4; Common common = 5; // the specifics are inlined here when sending data to clients, // as otherwise an extra level of indirection would be required oneof kind { Normal normal = 6; Filtered filtered = 7; } } message Notetype { message Config { enum Kind { KIND_NORMAL = 0; KIND_CLOZE = 1; } message CardRequirement { enum Kind { KIND_NONE = 0; KIND_ANY = 1; KIND_ALL = 2; } uint32 card_ord = 1; Kind kind = 2; repeated uint32 field_ords = 3; } Kind kind = 1; uint32 sort_field_idx = 2; string css = 3; /// This is now stored separately; retrieve with DefaultsForAdding() int64 target_deck_id_unused = 4; string latex_pre = 5; string latex_post = 6; bool latex_svg = 7; repeated CardRequirement reqs = 8; bytes other = 255; } message Field { message Config { bool sticky = 1; bool rtl = 2; string font_name = 3; uint32 font_size = 4; bytes other = 255; } OptionalUInt32 ord = 1; string name = 2; Config config = 5; } message Template { message Config { string q_format = 1; string a_format = 2; string q_format_browser = 3; string a_format_browser = 4; int64 target_deck_id = 5; string browser_font_name = 6; uint32 browser_font_size = 7; bytes other = 255; } OptionalUInt32 ord = 1; string name = 2; int64 mtime_secs = 3; sint32 usn = 4; Config config = 5; } int64 id = 1; string name = 2; int64 mtime_secs = 3; sint32 usn = 4; Config config = 7; repeated Field fields = 8; repeated Template templates = 9; } // Database objects /////////////////////////////////////////////////////////// message Note { int64 id = 1; string guid = 2; int64 notetype_id = 3; uint32 mtime_secs = 4; int32 usn = 5; repeated string tags = 6; repeated string fields = 7; } message Card { int64 id = 1; int64 note_id = 2; int64 deck_id = 3; uint32 template_idx = 4; int64 mtime_secs = 5; sint32 usn = 6; uint32 ctype = 7; sint32 queue = 8; sint32 due = 9; uint32 interval = 10; uint32 ease_factor = 11; uint32 reps = 12; uint32 lapses = 13; uint32 remaining_steps = 14; sint32 original_due = 15; int64 original_deck_id = 16; uint32 flags = 17; string data = 18; } // Backend /////////////////////////////////////////////////////////// message BackendInit { repeated string preferred_langs = 1; string locale_folder_path = 2; bool server = 3; } message I18nBackendInit { repeated string preferred_langs = 4; string locale_folder_path = 5; } // Errors /////////////////////////////////////////////////////////// message BackendError { enum Kind { INVALID_INPUT = 0; UNDO_EMPTY = 1; INTERRUPTED = 2; TEMPLATE_PARSE = 3; IO_ERROR = 4; DB_ERROR = 5; NETWORK_ERROR = 6; SYNC_AUTH_ERROR = 7; SYNC_OTHER_ERROR = 8; JSON_ERROR = 9; PROTO_ERROR = 10; NOT_FOUND_ERROR = 11; EXISTS = 12; FILTERED_DECK_ERROR = 13; SEARCH_ERROR = 14; } // localized error description suitable for displaying to the user string localized = 1; // the error subtype Kind kind = 2; } // Progress /////////////////////////////////////////////////////////// message Progress { message MediaSync { string checked = 1; string added = 2; string removed = 3; } message FullSync { uint32 transferred = 1; uint32 total = 2; } message NormalSync { string stage = 1; string added = 2; string removed = 3; } message DatabaseCheck { string stage = 1; uint32 stage_total = 2; 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 /////////////////////////////////////////////////////////// message SchedTimingTodayOut { uint32 days_elapsed = 1; int64 next_day_at = 2; } message DeckTreeIn { // if non-zero, counts for the provided timestamp will be included int64 now = 1; int64 top_deck_id = 2; } message DeckTreeNode { int64 deck_id = 1; string name = 2; repeated DeckTreeNode children = 3; uint32 level = 4; bool collapsed = 5; uint32 review_count = 6; uint32 learn_count = 7; uint32 new_count = 8; bool filtered = 16; } message RenderExistingCardIn { int64 card_id = 1; bool browser = 2; } message RenderUncommittedCardIn { Note note = 1; uint32 card_ord = 2; bytes template = 3; bool fill_empty = 4; } message RenderCardOut { repeated RenderedTemplateNode question_nodes = 1; repeated RenderedTemplateNode answer_nodes = 2; } message RenderedTemplateNode { oneof value { string text = 1; RenderedTemplateReplacement replacement = 2; } } message RenderedTemplateReplacement { string field_name = 1; string current_text = 2; repeated string filters = 3; } message ExtractAVTagsIn { string text = 1; bool question_side = 2; } message ExtractAVTagsOut { string text = 1; repeated AVTag av_tags = 2; } message AVTag { oneof value { string sound_or_video = 1; TTSTag tts = 2; } } message TTSTag { string field_text = 1; string lang = 2; repeated string voices = 3; float speed = 4; repeated string other_args = 5; } message ExtractLatexIn { string text = 1; bool svg = 2; bool expand_clozes = 3; } message ExtractLatexOut { string text = 1; repeated ExtractedLatex latex = 2; } message ExtractedLatex { string filename = 1; string latex_body = 2; } message AddMediaFileIn { string desired_name = 1; bytes data = 2; } message CheckMediaOut { repeated string unused = 1; repeated string missing = 2; string report = 3; bool have_trash = 4; } message TrashMediaFilesIn { repeated string fnames = 1; } message TranslateStringIn { uint32 module_index = 1; uint32 message_index = 2; map args = 3; } message TranslateArgValue { oneof value { string str = 1; double number = 2; } } message FormatTimespanIn { enum Context { PRECISE = 0; ANSWER_BUTTONS = 1; INTERVALS = 2; } float seconds = 1; Context context = 2; } message I18nResourcesIn { repeated string modules = 1; } message StudiedTodayMessageIn { uint32 cards = 1; double seconds = 2; } message CongratsLearnMessageIn { float next_due = 1; uint32 remaining = 2; } message OpenCollectionIn { string collection_path = 1; string media_folder_path = 2; string media_db_path = 3; string log_path = 4; } message SearchIn { string search = 1; SortOrder order = 2; } message SearchOut { repeated int64 ids = 1; } message SortOrder { message Builtin { string column = 1; bool reverse = 2; } oneof value { 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; } 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 JoinSearchNodesIn { SearchNode.Group.Joiner joiner = 1; SearchNode existing_node = 2; SearchNode additional_node = 3; } message ReplaceSearchNodeIn { SearchNode existing_node = 1; SearchNode replacement_node = 2; } message CloseCollectionIn { bool downgrade_to_schema11 = 1; } message AddOrUpdateDeckConfigLegacyIn { bytes config = 1; bool preserve_usn_and_mtime = 2; } message DeckConfigsForUpdate { message ConfigWithExtra { DeckConfig config = 1; uint32 use_count = 2; } message CurrentDeck { string name = 1; int64 config_id = 2; repeated int64 parent_config_ids = 3; } repeated ConfigWithExtra all_config = 1; CurrentDeck current_deck = 2; DeckConfig defaults = 3; bool schema_modified = 4; bool v3_scheduler = 5; } message UpdateDeckConfigsIn { int64 target_deck_id = 1; /// Unchanged, non-selected configs can be omitted. Deck will /// be set to whichever entry comes last. repeated DeckConfig configs = 2; repeated int64 removed_config_ids = 3; bool apply_to_children = 4; } message SetTagCollapsedIn { string name = 1; bool collapsed = 2; } message SetDeckCollapsedIn { enum Scope { REVIEWER = 0; BROWSER = 1; } int64 deck_id = 1; bool collapsed = 2; Scope scope = 3; } message GetChangedTagsOut { repeated string tags = 1; } message TagTreeNode { string name = 1; repeated TagTreeNode children = 2; uint32 level = 3; bool collapsed = 4; } message ReparentTagsIn { repeated string tags = 1; string new_parent = 2; } message RenameTagsIn { string current_prefix = 1; string new_prefix = 2; } message SetConfigJsonIn { string key = 1; bytes value_json = 2; } message StockNotetype { enum Kind { BASIC = 0; BASIC_AND_REVERSED = 1; BASIC_OPTIONAL_REVERSED = 2; BASIC_TYPING = 3; CLOZE = 4; } Kind kind = 1; } message NotetypeNames { repeated NotetypeNameId entries = 1; } message NotetypeUseCounts { repeated NotetypeNameIdUseCount entries = 1; } message NotetypeNameId { int64 id = 1; string name = 2; } message NotetypeNameIdUseCount { int64 id = 1; string name = 2; uint32 use_count = 3; } message AddOrUpdateNotetypeIn { bytes json = 1; bool preserve_usn_and_mtime = 2; } message AddNoteIn { Note note = 1; int64 deck_id = 2; } message AddNoteOut { int64 note_id = 1; OpChanges changes = 2; } message UpdateNoteIn { Note note = 1; bool skip_undo_entry = 2; } message UpdateCardIn { Card card = 1; bool skip_undo_entry = 2; } message EmptyCardsReport { message NoteWithEmptyCards { int64 note_id = 1; repeated int64 card_ids = 2; bool will_delete_note = 3; } string report = 1; repeated NoteWithEmptyCards notes = 2; } message DeckNames { repeated DeckNameId entries = 1; } message DeckNameId { int64 id = 1; string name = 2; } message AddOrUpdateDeckLegacyIn { bytes deck = 1; bool preserve_usn_and_mtime = 2; } message FieldNamesForNotesIn { repeated int64 nids = 1; } message FieldNamesForNotesOut { repeated string fields = 1; } message FindAndReplaceIn { 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; } repeated Cell cells = 1; Color color = 2; string font_name = 3; uint32 font_size = 4; } message AfterNoteUpdatesIn { repeated int64 nids = 1; bool mark_notes_modified = 2; bool generate_cards = 3; } message NoteIdsAndTagsIn { repeated int64 note_ids = 1; string tags = 2; } message FindAndReplaceTagIn { repeated int64 note_ids = 1; string search = 2; string replacement = 3; bool regex = 4; bool match_case = 5; } message CheckDatabaseOut { repeated string problems = 1; } 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; } Scheduling scheduling = 1; Reviewing reviewing = 2; Editing editing = 3; } message ClozeNumbersInNoteOut { repeated uint32 numbers = 1; } message GetDeckNamesIn { bool skip_empty_default = 1; // if unset, implies skip_empty_default bool include_filtered = 2; } message ReparentDecksIn { repeated int64 deck_ids = 1; int64 new_parent = 2; } message NoteIsDuplicateOrEmptyOut { enum State { NORMAL = 0; EMPTY = 1; DUPLICATE = 2; } State state = 1; } message SyncLoginIn { string username = 1; string password = 2; } message SyncStatusOut { enum Required { NO_CHANGES = 0; NORMAL_SYNC = 1; FULL_SYNC = 2; } Required required = 1; } message SyncCollectionOut { 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 SyncServerMethodIn { 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 RemoveNotesIn { repeated int64 note_ids = 1; repeated int64 card_ids = 2; } message RemoveCardsIn { repeated int64 card_ids = 1; } message UpdateStatsIn { int64 deck_id = 1; int32 new_delta = 2; int32 review_delta = 4; int32 millisecond_delta = 5; } message ExtendLimitsIn { int64 deck_id = 1; int32 new_delta = 2; int32 review_delta = 3; } message CountsForDeckTodayOut { int32 new = 1; int32 review = 2; } message GraphsIn { string search = 1; uint32 days = 2; } message GraphsOut { repeated Card cards = 1; repeated RevlogEntry revlog = 2; uint32 days_elapsed = 3; // Based on rollover hour uint32 next_day_at_secs = 4; uint32 scheduler_version = 5; /// Seconds to add to UTC timestamps to get local time. int32 local_offset_secs = 7; } message GraphPreferences { enum Weekday { SUNDAY = 0; MONDAY = 1; FRIDAY = 5; SATURDAY = 6; } Weekday calendar_first_day_of_week = 1; bool card_counts_separate_inactive = 2; bool browser_links_supported = 3; bool future_due_show_backlog = 4; } message RevlogEntry { enum ReviewKind { LEARNING = 0; REVIEW = 1; RELEARNING = 2; EARLY_REVIEW = 3; MANUAL = 4; } int64 id = 1; int64 cid = 2; int32 usn = 3; uint32 button_chosen = 4; int32 interval = 5; int32 last_interval = 6; uint32 ease_factor = 7; uint32 taken_millis = 8; ReviewKind review_kind = 9; } message CongratsInfoOut { 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 UnburyDeckIn { enum Mode { ALL = 0; SCHED_ONLY = 1; USER_ONLY = 2; } int64 deck_id = 1; Mode mode = 2; } message BuryOrSuspendCardsIn { enum Mode { SUSPEND = 0; BURY_SCHED = 1; BURY_USER = 2; } repeated int64 card_ids = 1; repeated int64 note_ids = 2; Mode mode = 3; } message ScheduleCardsAsNewIn { repeated int64 card_ids = 1; bool log = 2; } message SetDueDateIn { repeated int64 card_ids = 1; string days = 2; Config.String config_key = 3; } message SortCardsIn { repeated int64 card_ids = 1; uint32 starting_from = 2; uint32 step_size = 3; bool randomize = 4; bool shift_existing = 5; } message SortDeckIn { int64 deck_id = 1; bool randomize = 2; } message SetDeckIn { repeated int64 card_ids = 1; int64 deck_id = 2; } message Config { message Bool { enum Key { BROWSER_TABLE_SHOW_NOTES_MODE = 0; BROWSER_SORT_BACKWARDS = 1; BROWSER_NOTE_SORT_BACKWARDS = 2; 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; } Key key = 1; } } message SetConfigBoolIn { Config.Bool.Key key = 1; bool value = 2; } message SetConfigStringIn { Config.String.Key key = 1; string value = 2; } message RenderMarkdownIn { string markdown = 1; 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 GetQueuedCardsIn { uint32 fetch_limit = 1; bool intraday_learning_only = 2; } message QueuedCards { enum Queue { NEW = 0; LEARNING = 1; REVIEW = 2; } message QueuedCard { 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 GetQueuedCardsOut { oneof value { QueuedCards queued_cards = 1; CongratsInfoOut congrats_info = 2; } } message OpChanges { bool card = 1; bool note = 2; bool deck = 3; bool tag = 4; bool notetype = 5; bool config = 6; bool deck_config = 11; bool browser_table = 7; bool browser_sidebar = 8; bool editor = 9; bool reviewer = 10; } message UndoStatus { string undo = 1; string redo = 2; uint32 last_step = 3; } message OpChangesAfterUndo { OpChanges changes = 1; string operation = 2; int64 reverted_to_timestamp = 3; UndoStatus new_status = 4; uint32 counter = 5; } message DefaultsForAddingIn { int64 home_deck_of_current_review_card = 1; } message DeckAndNotetype { int64 deck_id = 1; int64 notetype_id = 2; } message RenameDeckIn { int64 deck_id = 1; string new_name = 2; } message FilteredDeckForUpdate { int64 id = 1; string name = 2; Deck.Filtered config = 3; } message SetFlagIn { repeated int64 card_ids = 1; uint32 flag = 2; }