mirror of
https://github.com/ankitects/anki.git
synced 2025-09-24 16:56:36 -04:00
Expose apkg export/import on backend
This commit is contained in:
parent
16f8c980a6
commit
6b85b5900f
3 changed files with 66 additions and 4 deletions
|
@ -5,6 +5,9 @@ syntax = "proto3";
|
|||
|
||||
package anki.import_export;
|
||||
|
||||
import "anki/collection.proto";
|
||||
import "anki/decks.proto";
|
||||
import "anki/notes.proto";
|
||||
import "anki/generic.proto";
|
||||
|
||||
service ImportExportService {
|
||||
|
@ -12,6 +15,9 @@ service ImportExportService {
|
|||
returns (generic.Empty);
|
||||
rpc ExportCollectionPackage(ExportCollectionPackageRequest)
|
||||
returns (generic.Empty);
|
||||
rpc ImportAnkiPackage(ImportAnkiPackageRequest)
|
||||
returns (collection.OpChanges);
|
||||
rpc ExportAnkiPackage(ExportAnkiPackageRequest) returns (generic.Empty);
|
||||
}
|
||||
|
||||
message ImportCollectionPackageRequest {
|
||||
|
@ -26,6 +32,21 @@ message ExportCollectionPackageRequest {
|
|||
bool legacy = 3;
|
||||
}
|
||||
|
||||
message ImportAnkiPackageRequest {
|
||||
string package_path = 1;
|
||||
}
|
||||
|
||||
message ExportAnkiPackageRequest {
|
||||
string out_path = 1;
|
||||
bool with_scheduling = 2;
|
||||
bool with_media = 3;
|
||||
oneof selector {
|
||||
generic.Empty whole_collection = 4;
|
||||
decks.DeckId deck_id = 5;
|
||||
notes.NoteIds note_ids = 6;
|
||||
}
|
||||
}
|
||||
|
||||
message PackageMetadata {
|
||||
enum Version {
|
||||
VERSION_UNKNOWN = 0;
|
||||
|
|
|
@ -4,9 +4,10 @@
|
|||
use super::{progress::Progress, Backend};
|
||||
pub(super) use crate::backend_proto::importexport_service::Service as ImportExportService;
|
||||
use crate::{
|
||||
backend_proto::{self as pb},
|
||||
backend_proto::{self as pb, export_anki_package_request::Selector},
|
||||
import_export::{package::import_colpkg, ImportProgress},
|
||||
prelude::*,
|
||||
search::SearchNode,
|
||||
};
|
||||
|
||||
impl ImportExportService for Backend {
|
||||
|
@ -43,6 +44,38 @@ impl ImportExportService for Backend {
|
|||
)
|
||||
.map(Into::into)
|
||||
}
|
||||
|
||||
fn import_anki_package(&self, input: pb::ImportAnkiPackageRequest) -> Result<pb::OpChanges> {
|
||||
self.with_col(|col| col.import_apkg(&input.package_path, &mut self.import_progress_fn()))
|
||||
.map(Into::into)
|
||||
}
|
||||
|
||||
fn export_anki_package(&self, input: pb::ExportAnkiPackageRequest) -> Result<pb::Empty> {
|
||||
let selector = input
|
||||
.selector
|
||||
.ok_or_else(|| AnkiError::invalid_input("missing oneof"))?;
|
||||
self.with_col(|col| {
|
||||
col.export_apkg(
|
||||
&input.out_path,
|
||||
SearchNode::from_selector(selector),
|
||||
input.with_scheduling,
|
||||
input.with_media,
|
||||
None,
|
||||
self.export_progress_fn(),
|
||||
)
|
||||
})
|
||||
.map(Into::into)
|
||||
}
|
||||
}
|
||||
|
||||
impl SearchNode {
|
||||
fn from_selector(selector: Selector) -> Self {
|
||||
match selector {
|
||||
Selector::WholeCollection(_) => Self::WholeCollection,
|
||||
Selector::DeckId(did) => Self::from_deck_id(did, true),
|
||||
Selector::NoteIds(nids) => Self::from_note_ids(nids.note_ids),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Backend {
|
||||
|
|
|
@ -134,11 +134,11 @@ impl Default for SearchBuilder {
|
|||
}
|
||||
|
||||
impl SearchNode {
|
||||
pub fn from_deck_id(did: DeckId, with_children: bool) -> Self {
|
||||
pub fn from_deck_id(did: impl Into<DeckId>, with_children: bool) -> Self {
|
||||
if with_children {
|
||||
Self::DeckIdWithChildren(did)
|
||||
Self::DeckIdWithChildren(did.into())
|
||||
} else {
|
||||
Self::DeckIdWithoutChildren(did)
|
||||
Self::DeckIdWithoutChildren(did.into())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -166,6 +166,14 @@ impl SearchNode {
|
|||
name,
|
||||
)))
|
||||
}
|
||||
|
||||
pub fn from_note_ids<I: IntoIterator<Item = N>, N: Into<NoteId>>(ids: I) -> Self {
|
||||
Self::NoteIds(ids.into_iter().map(Into::into).join(","))
|
||||
}
|
||||
|
||||
pub fn from_card_ids<I: IntoIterator<Item = C>, C: Into<CardId>>(ids: I) -> Self {
|
||||
Self::CardIds(ids.into_iter().map(Into::into).join(","))
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Into<SearchNode>> From<T> for Node {
|
||||
|
|
Loading…
Reference in a new issue