// Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html syntax = "proto3"; option java_multiple_files = true; package anki.stats; import "anki/generic.proto"; import "anki/cards.proto"; service StatsService { rpc CardStats(cards.CardId) returns (CardStatsResponse); rpc GetReviewLogs(cards.CardId) returns (ReviewLogs); rpc Graphs(GraphsRequest) returns (GraphsResponse); rpc GetGraphPreferences(generic.Empty) returns (GraphPreferences); rpc SetGraphPreferences(GraphPreferences) returns (generic.Empty); } // Implicitly includes any of the above methods that are not listed in the // backend service. service BackendStatsService {} message ReviewLogs { repeated CardStatsResponse.StatsRevlogEntry entries = 1; } message CardStatsResponse { message StatsRevlogEntry { int64 time = 1; RevlogEntry.ReviewKind review_kind = 2; uint32 button_chosen = 3; // seconds uint32 interval = 4; // per mill uint32 ease = 5; float taken_secs = 6; optional cards.FsrsMemoryState memory_state = 7; } repeated StatsRevlogEntry revlog = 1; int64 card_id = 2; int64 note_id = 3; string deck = 4; // Unix timestamps int64 added = 5; optional int64 first_review = 6; optional int64 latest_review = 7; optional int64 due_date = 8; optional int32 due_position = 9; // days uint32 interval = 10; // per mill uint32 ease = 11; uint32 reviews = 12; uint32 lapses = 13; float average_secs = 14; float total_secs = 15; string card_type = 16; string notetype = 17; optional cards.FsrsMemoryState memory_state = 18; // not set if due date/state not available optional float fsrs_retrievability = 19; string custom_data = 20; string preset = 21; optional string original_deck = 22; optional float desired_retention = 23; } message GraphsRequest { string search = 1; uint32 days = 2; } message GraphsResponse { message Added { map added = 1; } message Intervals { map intervals = 1; } message Eases { map eases = 1; float average = 2; } message Retrievability { map retrievability = 1; float average = 2; float sum_by_card = 3; float sum_by_note = 4; } message FutureDue { map future_due = 1; bool have_backlog = 2; uint32 daily_load = 3; } message Today { uint32 answer_count = 1; uint32 answer_millis = 2; uint32 correct_count = 3; uint32 mature_correct = 4; uint32 mature_count = 5; uint32 learn_count = 6; uint32 review_count = 7; uint32 relearn_count = 8; uint32 early_review_count = 9; } // each bucket is a 24 element vec message Hours { message Hour { uint32 total = 1; uint32 correct = 2; } repeated Hour one_month = 1; repeated Hour three_months = 2; repeated Hour one_year = 3; repeated Hour all_time = 4; } message ReviewCountsAndTimes { message Reviews { uint32 learn = 1; uint32 relearn = 2; uint32 young = 3; uint32 mature = 4; uint32 filtered = 5; } map count = 1; map time = 2; } // 4 element vecs for buttons 1-4 message Buttons { message ButtonCounts { repeated uint32 learning = 1; repeated uint32 young = 2; repeated uint32 mature = 3; } ButtonCounts one_month = 1; ButtonCounts three_months = 2; ButtonCounts one_year = 3; ButtonCounts all_time = 4; } message CardCounts { message Counts { uint32 newCards = 1; uint32 learn = 2; uint32 relearn = 3; uint32 young = 4; uint32 mature = 5; uint32 suspended = 6; uint32 buried = 7; } // Buried/suspended cards are included in counts; suspended/buried counts // are 0. Counts including_inactive = 1; // Buried/suspended cards are counted separately. Counts excluding_inactive = 2; } message TrueRetentionStats { message TrueRetention { uint32 young_passed = 1; uint32 young_failed = 2; uint32 mature_passed = 3; uint32 mature_failed = 4; } TrueRetention today = 1; TrueRetention yesterday = 2; TrueRetention week = 3; TrueRetention month = 4; TrueRetention year = 5; TrueRetention all_time = 6; } Buttons buttons = 1; CardCounts card_counts = 2; Hours hours = 3; Today today = 4; Eases eases = 5; Eases difficulty = 11; Intervals intervals = 6; FutureDue future_due = 7; Added added = 8; ReviewCountsAndTimes reviews = 9; uint32 rollover_hour = 10; Retrievability retrievability = 12; bool fsrs = 13; Intervals stability = 14; TrueRetentionStats true_retention = 15; } 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; FILTERED = 3; MANUAL = 4; RESCHEDULED = 5; } 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 CardEntry { int64 id = 1; int64 note_id = 2; int64 deck_id = 3; } message DeckEntry { int64 id = 1; int64 parent_id = 2; int64 preset_id = 3; } message Dataset { repeated RevlogEntry revlogs = 1; repeated CardEntry cards = 2; repeated DeckEntry decks = 3; int64 next_day_at = 4; }