From 0c3cc9026ba687de1943760d8c4b15190153090b Mon Sep 17 00:00:00 2001 From: Eric Kidd Date: Sat, 4 May 2024 09:52:37 -0400 Subject: [PATCH] substudy: Give better errors earlier for Anki export (fixes #57) --- substudy/src/export/anki/connect.rs | 14 ++++++++++++++ substudy/src/export/anki/mod.rs | 27 ++++++++++++++++++++------- 2 files changed, 34 insertions(+), 7 deletions(-) diff --git a/substudy/src/export/anki/connect.rs b/substudy/src/export/anki/connect.rs index 1f569dd0..a0435167 100644 --- a/substudy/src/export/anki/connect.rs +++ b/substudy/src/export/anki/connect.rs @@ -131,6 +131,20 @@ impl AnkiRequestParams for VersionRequest { } } +/// Get all deck names. +#[derive(Debug, Serialize)] +#[serde(rename_all = "camelCase")] +pub(crate) struct DeckNamesRequest; + +impl AnkiRequestParams for DeckNamesRequest { + const ACTION: &'static str = "deckNames"; + type Response = Vec; + + fn omit_params(&self) -> bool { + true + } +} + /// Get all model names. #[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] diff --git a/substudy/src/export/anki/mod.rs b/substudy/src/export/anki/mod.rs index 58ae2c46..74e7170d 100644 --- a/substudy/src/export/anki/mod.rs +++ b/substudy/src/export/anki/mod.rs @@ -12,8 +12,8 @@ use crate::{ export::{ anki::connect::{ AddNotesRequest, AnkiConnect, CanAddNotesWithErrorDetailRequest, - ModelNamesRequest, Note, NoteOptions, StoreMediaFileRequest, - VersionRequest, + DeckNamesRequest, ModelNamesRequest, Note, NoteOptions, + StoreMediaFileRequest, VersionRequest, }, Exporter, }, @@ -175,17 +175,30 @@ pub async fn export_anki( exporter: &mut Exporter, options: AnkiExportOptions, ) -> Result<()> { - let exporting = export_anki_helper(exporter, options.skip_duplicates)?; - exporter.finish_exports(ui).await?; - let model = &models::AUDIO_MODEL; - // Make sure we can talk to Anki-Connect. let client = AnkiConnect::new(); let version = client.request(VersionRequest).await.context( - "Could not connect to Anki (Anki not running, Anki-Connect plugin not installed, or blocked by local firewall?)", + "Could not connect to AnkiConnect (see `substudy export anki --help` for troubleshooting)", )?; debug!("Anki-Connect version: {}", version); + // Make sure our deck exists. + let deck_names = client + .request(DeckNamesRequest) + .await + .context("error fetching deck names from Anki-Connect")?; + if !deck_names.iter().any(|n| n == &options.deck) { + return Err(anyhow!( + "deck not found: {:?} (please create it in Anki first)", + options.deck + )); + } + + // Export our notes and media (to a temporary directory). + let exporting = export_anki_helper(exporter, options.skip_duplicates)?; + exporter.finish_exports(ui).await?; + let model = &models::AUDIO_MODEL; + // Make sure our model exists. let model_names = client .request(ModelNamesRequest)