use crate::dictionary::app_data_dir; use std::io; use tokio::fs::{File, OpenOptions}; use tokio::io::{AsyncReadExt, AsyncWriteExt}; use zstd::{DEFAULT_COMPRESSION_LEVEL, Decoder, Encoder}; // const API_URL: &str = "http://127.0.0.1:8089/"; const API_URL: &str = "https://learning.micialware.ru/"; pub async fn send_data(id: String) { let path = app_data_dir(); let db_file = path.join("data.db"); let data = tokio::fs::read(db_file).await.unwrap(); let data = compress(data); let api_url = API_URL.to_string(); let id_url = format!("{api_url}upload/stream/{id}"); let client = reqwest::Client::new(); let new_version = client .post(&id_url) .body(data) .send() .await .unwrap() .text() .await .unwrap(); set_local_version(new_version.parse::().unwrap()).await; } fn compress(data: Vec) -> Vec { let mut encoder = Encoder::new(Vec::new(), DEFAULT_COMPRESSION_LEVEL).unwrap(); io::copy(&mut &data[..], &mut encoder).unwrap(); encoder.finish().unwrap() } pub async fn load_data(id: String, temp: bool) { let api_url = API_URL.to_string(); let id_url = format!("{api_url}download/{id}"); let client = reqwest::Client::new(); let data = client .get(&id_url) .send() .await .unwrap() .bytes() .await .unwrap() .to_vec(); let data = decompress(data); let path = app_data_dir(); let file_name = if temp { "data.db.tmp" } else { "data.db" }; let db_file = path.join(file_name); tokio::fs::write(db_file, data).await.unwrap(); let version_url = format!("{API_URL}{id}/version"); let version = client .get(&version_url) .send() .await .unwrap() .text() .await .unwrap(); set_local_version(version.parse::().unwrap()).await; } pub fn decompress(data: Vec) -> Vec { let mut decoder = Decoder::new(&data[..]).unwrap(); let mut decompressed = Vec::new(); let res = io::copy(&mut decoder, &mut decompressed); if let Err(e) = res { println!("{}", e); } decompressed } pub async fn first_sync() -> String { let id_url = API_URL.to_string() + "generate"; let client = reqwest::Client::new(); let id = client .get(&id_url) .send() .await .unwrap() .text() .await .unwrap(); println!("id: {}", id); id } pub async fn get_web_version(key: &str) -> Result { let id_url = format!("{API_URL}{key}/version"); let client = reqwest::Client::new(); let version = client.get(&id_url).send().await?.text().await?; println!("version: {}", version); Ok(version.parse::().unwrap_or_default()) } pub async fn get_local_version() -> u32 { let file = app_data_dir().join("data.meta"); if file.exists() { let mut data = String::new(); File::open(file.clone()) .await .unwrap() .read_to_string(&mut data) .await .unwrap(); return data.parse::().unwrap(); } let mut file = OpenOptions::new() .write(true) .create(true) .truncate(true) .open(file) .await .unwrap(); file.write_all("0".as_bytes()).await.unwrap(); 0 } pub async fn set_local_version(version: u32) { let file_path = app_data_dir().join("data.meta"); let mut file = OpenOptions::new() .write(true) .create(true) .truncate(true) .open(file_path) .await .unwrap(); file.write_all(version.to_string().as_bytes()) .await .unwrap(); }