Files
jap_learn/src/data_provider/import.rs
T

108 lines
3.6 KiB
Rust
Raw Normal View History

2026-09-09 12:12:44 +03:00
use std::collections::BTreeMap;
2026-08-25 12:04:07 +03:00
use crate::helpers::into_result;
use crate::notification::NotificationData;
2026-08-25 12:04:07 +03:00
use crate::notification::NotificationData::IncorrectAnkiFile;
2026-08-23 22:48:00 +03:00
use log::info;
2026-08-14 23:52:48 +03:00
use rusqlite::Connection;
2026-08-14 11:17:22 +03:00
use serde_json::Value;
#[derive(Clone)]
pub struct ImportData(pub(crate) Vec<ImportGroup>);
2026-08-14 11:17:22 +03:00
#[derive(Clone, Debug)]
pub struct ImportGroup {
pub id: u64,
pub name: String,
pub fields: Vec<String>,
pub length: u64,
2026-09-09 12:12:44 +03:00
pub mapping: BTreeMap<String, String>,
2026-08-15 21:32:24 +03:00
pub imported: bool,
2026-08-14 11:17:22 +03:00
}
#[derive(Clone)]
pub struct ImportNote {
pub tags: String,
pub fields: Vec<String>,
2026-08-14 11:17:22 +03:00
}
pub fn load_groups(connection: &Connection) -> Result<ImportData, NotificationData> {
2026-08-14 11:17:22 +03:00
let json_models: String = connection
.query_one("select models from col", (), |row| row.get(0))
2026-08-24 23:42:58 +03:00
.map_err(|_| IncorrectAnkiFile)?;
2026-08-25 12:04:07 +03:00
let raw: Value = serde_json::from_str(json_models.as_str()).map_err(|_| IncorrectAnkiFile)?;
let sets = raw.as_object();
if let Some(sets) = sets {
let mut total_data = ImportData(vec![]);
2026-08-14 11:17:22 +03:00
let mut count_stmt = connection
.prepare("select mid, count(id) from notes group by mid")
2026-08-24 23:42:58 +03:00
.map_err(|_| IncorrectAnkiFile)?;
let counts = count_stmt
.query_map([], |row| Ok((row.get(0)?, row.get(1)?)))
2026-08-24 23:42:58 +03:00
.map_err(|_| IncorrectAnkiFile)?
2026-08-24 23:10:23 +03:00
.filter_map(|x| x.ok())
.collect::<Vec<(i64, i64)>>();
for (_, collection) in sets {
2026-09-09 10:53:03 +03:00
let fields_property = collection.get("flds");
if let Some(fields_property) = fields_property {
2026-08-25 12:04:07 +03:00
let fields = into_result(fields_property.as_array(), IncorrectAnkiFile)?
.iter()
.filter_map(|x| x.get("name"))
.map(|x| x.as_str().unwrap().to_string())
.collect();
let id = collection.get("id");
2026-08-25 12:04:07 +03:00
if id.is_none() || id.unwrap().as_u64().is_none() {
2026-08-24 23:42:58 +03:00
return Err(IncorrectAnkiFile);
}
let id = id.unwrap().as_u64().unwrap();
let name = collection.get("name");
2026-08-24 23:10:23 +03:00
if name.is_none() || name.unwrap().as_str().is_none() {
2026-08-24 23:42:58 +03:00
return Err(IncorrectAnkiFile);
}
let name = name.unwrap().as_str().unwrap().to_string();
2026-08-23 22:48:00 +03:00
let mut group = ImportGroup {
id,
name,
fields,
mapping: Default::default(),
length: 0,
imported: false,
};
if let Some((_, count)) = counts.iter().find(|(id, _)| *id == group.id as i64) {
group.length = *count as u64
}
2026-08-23 22:48:00 +03:00
info!("{:?}", group);
total_data.0.push(group);
2026-08-20 18:53:13 +03:00
}
}
2026-08-25 12:04:07 +03:00
return Ok(total_data);
2026-08-14 11:17:22 +03:00
}
2026-08-24 23:42:58 +03:00
Err(IncorrectAnkiFile)
2026-08-14 11:17:22 +03:00
}
2026-08-25 12:04:07 +03:00
pub fn get_words_of_group(
connection: &Connection,
group_id: u64,
) -> Result<Vec<ImportNote>, NotificationData> {
let mut count_stmt = connection
.prepare("select tags, flds from notes where mid == ?1;")
2026-08-24 23:42:58 +03:00
.map_err(|_| IncorrectAnkiFile)?;
Ok(count_stmt
2026-08-15 21:32:24 +03:00
.query_map((group_id as i64,), |row| {
Ok(ImportNote {
tags: row.get(0)?,
fields: row
.get::<usize, String>(1)?
.split('')
.map(|x| x.to_string())
.collect(),
})
})
2026-08-24 23:42:58 +03:00
.map_err(|_| IncorrectAnkiFile)?
2026-08-24 23:10:23 +03:00
.filter_map(|x| x.ok())
.collect::<Vec<ImportNote>>())
}