Compare commits

...
2 Commits
Author SHA1 Message Date
polv 079fdd512c try spawn blocking 2026-03-22 21:46:47 +07:00
polv 413376d3f3 remove zipSource 2026-03-22 15:15:26 +07:00
7 changed files with 45 additions and 50 deletions

No files matched your search

+3
View File
@@ -6,3 +6,6 @@ resolver = "3"
lto = true lto = true
codegen-units = 1 codegen-units = 1
strip = true strip = true
# debug = true # keep symbols
# lto = false # disable LTO
# opt-level = 1 # reduce but don't maximize optimization
+1
View File
@@ -10,6 +10,7 @@
"build:desktop": "tauri build", "build:desktop": "tauri build",
"build:android": "tauri android build", "build:android": "tauri android build",
"install:android": "adb install -r src-tauri/gen/android/app/build/outputs/apk/universal/release/app-universal-release.apk", "install:android": "adb install -r src-tauri/gen/android/app/build/outputs/apk/universal/release/app-universal-release.apk",
"run:android": "tauri android run",
"build:android:debug": "tauri android build --debug", "build:android:debug": "tauri android build --debug",
"install:android:debug": "adb install -r src-tauri/gen/android/app/build/outputs/apk/universal/debug/app-universal-debug.apk", "install:android:debug": "adb install -r src-tauri/gen/android/app/build/outputs/apk/universal/debug/app-universal-debug.apk",
"run:desktop": ".\\target\\release\\cjdic2.exe", "run:desktop": ".\\target\\release\\cjdic2.exe",
+1 -1
View File
@@ -16,7 +16,7 @@ mod yomitan;
pub use yomitan::YomitanRow; pub use yomitan::YomitanRow;
mod yomitan_writer; mod yomitan_writer;
pub use yomitan_writer::{YomitanProgress, YomitanWriter, YomitanZipImportResult, ZipSource}; pub use yomitan_writer::{YomitanProgress, YomitanWriter, YomitanZipImportResult};
use crate::{CJDicError, tokenizer::Tokenizer}; use crate::{CJDicError, tokenizer::Tokenizer};
+6 -23
View File
@@ -4,11 +4,10 @@ use rusqlite::{Connection, OptionalExtension, Result, Transaction, params};
use serde::Serialize; use serde::Serialize;
use serde_json::Value; use serde_json::Value;
use std::{ use std::{
borrow::Cow,
collections::HashMap, collections::HashMap,
env::current_dir, env::current_dir,
fs::{File, create_dir_all}, fs::{File, create_dir_all},
io::{self, Cursor, Read}, io::{self, Read},
path::{Path, PathBuf}, path::{Path, PathBuf},
}; };
use zip::ZipArchive; use zip::ZipArchive;
@@ -30,21 +29,6 @@ pub(super) fn normalize_term(s: &str) -> String {
.collect() .collect()
} }
pub trait ZipSource {
fn file_name(&self) -> &str;
fn bytes(&self) -> std::io::Result<Cow<'_, [u8]>>;
}
impl ZipSource for PathBuf {
fn file_name(&self) -> &str {
Path::file_name(self).and_then(|n| n.to_str()).unwrap_or("")
}
fn bytes(&self) -> std::io::Result<Cow<'_, [u8]>> {
std::fs::read(self).map(Cow::Owned)
}
}
#[derive(Serialize, Debug, Clone)] #[derive(Serialize, Debug, Clone)]
pub struct YomitanProgress { pub struct YomitanProgress {
pub message: String, pub message: String,
@@ -446,24 +430,23 @@ impl YomitanWriter {
Ok(()) Ok(())
} }
pub fn import_dictionary_zip_file<Z, Callback>( pub fn import_dictionary_zip_file<Callback>(
&mut self, &mut self,
zip_file: &Z, zip_file: &PathBuf,
asset_dir: &PathBuf, asset_dir: &PathBuf,
lang: &str, lang: &str,
progress_callback: Callback, progress_callback: Callback,
) -> anyhow::Result<YomitanZipImportResult, CJDicError> ) -> anyhow::Result<YomitanZipImportResult, CJDicError>
where where
Z: ZipSource,
Callback: Fn(YomitanProgress), Callback: Fn(YomitanProgress),
{ {
let bundle_name = zip_file.file_name(); let bundle_name = zip_file.file_name().and_then(|n| n.to_str()).unwrap_or("");
let _timer = Timer::new(format!("Importing {}", bundle_name)); let _timer = Timer::new(format!("Importing {}", bundle_name));
self.conn.execute_batch("PRAGMA foreign_keys = off")?; self.conn.execute_batch("PRAGMA foreign_keys = off")?;
let cursor = Cursor::new(zip_file.bytes()?); let file = File::open(&zip_file)?;
let mut archive = ZipArchive::new(cursor)?; let mut archive = ZipArchive::new(file)?;
let mut asset_count = 0; let mut asset_count = 0;
+1 -1
View File
@@ -7,7 +7,7 @@ mod service;
mod tokenizer; mod tokenizer;
mod util; mod util;
pub use db::{YomitanProgress, YomitanRow, YomitanZipImportResult, ZipSource}; pub use db::{YomitanProgress, YomitanRow, YomitanZipImportResult};
pub use error::CJDicError; pub use error::CJDicError;
pub use service::{AppService, SqlParam, YomitanDictEntry}; pub use service::{AppService, SqlParam, YomitanDictEntry};
pub use tokenizer::TokenizeSegment; pub use tokenizer::TokenizeSegment;
+8 -9
View File
@@ -7,7 +7,7 @@ use rusqlite::{Connection, params_from_iter};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::{ use crate::{
Timer, ZipSource, Timer,
db::{ db::{
DBFILE, Database, DbChild, YomitanProgress, YomitanRow, YomitanWriter, DBFILE, Database, DbChild, YomitanProgress, YomitanRow, YomitanWriter,
YomitanZipImportResult, YomitanZipImportResult,
@@ -40,6 +40,7 @@ pub enum SqlParam {
Bool(bool), Bool(bool),
} }
#[derive(Clone)]
pub struct AppService { pub struct AppService {
db: Database, db: Database,
tokenizer: Tokenizer, tokenizer: Tokenizer,
@@ -163,24 +164,23 @@ impl AppService {
Ok(out) Ok(out)
} }
pub fn load_yomitan_zip_dir<Z, LoadCallback, ImportCallback>( pub fn load_yomitan_zip_dir<LoadCallback, ImportCallback>(
&self, &self,
zip_dir: Vec<Z>, zip_dir: Vec<PathBuf>,
asset_dir: &PathBuf, asset_dir: &PathBuf,
lang: &str, lang: &str,
load_callback: LoadCallback, load_callback: LoadCallback,
import_callback: ImportCallback, import_callback: ImportCallback,
) -> Result<LoadYomitanZipDirResult, CJDicError> ) -> Result<LoadYomitanZipDirResult, CJDicError>
where where
Z: ZipSource,
LoadCallback: Fn(LoadYomitanZipDirResult), LoadCallback: Fn(LoadYomitanZipDirResult),
ImportCallback: Fn(YomitanProgress), ImportCallback: Fn(YomitanProgress),
{ {
let mut dir_zip_map: HashMap<String, &Z> = HashMap::new(); let mut dir_zip_map: HashMap<String, &PathBuf> = HashMap::new();
let mut zip_dir_ord: HashMap<String, usize> = HashMap::new(); let mut zip_dir_ord: HashMap<String, usize> = HashMap::new();
for (i, entry) in zip_dir.iter().enumerate() { for (i, entry) in zip_dir.iter().enumerate() {
let filename = entry.file_name(); let filename = entry.file_name().and_then(|n| n.to_str()).unwrap_or("");
dir_zip_map.insert(filename.to_string(), entry); dir_zip_map.insert(filename.to_string(), entry);
zip_dir_ord.insert(filename.to_string(), i); zip_dir_ord.insert(filename.to_string(), i);
} }
@@ -276,15 +276,14 @@ impl AppService {
}) })
} }
pub fn import_yomitan_zip_file<Z, Callback>( pub fn import_yomitan_zip_file<Callback>(
writer: &mut YomitanWriter, // Reuse existing connection writer: &mut YomitanWriter, // Reuse existing connection
zip_file: &Z, zip_file: &PathBuf,
asset_dir: &PathBuf, asset_dir: &PathBuf,
lang: &str, lang: &str,
progress_callback: Callback, progress_callback: Callback,
) -> Result<YomitanZipImportResult, CJDicError> ) -> Result<YomitanZipImportResult, CJDicError>
where where
Z: ZipSource,
Callback: Fn(YomitanProgress), Callback: Fn(YomitanProgress),
{ {
Ok(writer.import_dictionary_zip_file(zip_file, asset_dir, lang, progress_callback)?) Ok(writer.import_dictionary_zip_file(zip_file, asset_dir, lang, progress_callback)?)
+25 -16
View File
@@ -59,26 +59,35 @@ pub async fn init_yomitan(
.map(|d| data_dir.join(&d.filepath)) .map(|d| data_dir.join(&d.filepath))
.collect(); .collect();
let update_count = Cell::new(0usize); let state = state.inner().clone();
let app_clone = app.clone();
state.load_yomitan_zip_dir( let update_count = tokio::task::spawn_blocking(move || {
zip_files, let update_count = Cell::new(0usize);
&yomitan_assets,
lang.as_str(),
|r| {
update_count.set(update_count.get() + r.new_dicts.len() + r.to_be_removed_dicts.len());
app.emit("load-yomitan-dir", r).unwrap();
},
|r| {
update_count.set(update_count.get() + 1);
app.emit("yomitan-import-progress", r).unwrap();
},
)?;
if update_count.get() > 0 { state.load_yomitan_zip_dir(
zip_files,
&yomitan_assets,
lang.as_str(),
|r| {
update_count
.set(update_count.get() + r.new_dicts.len() + r.to_be_removed_dicts.len());
app.emit("load-yomitan-dir", r).unwrap();
},
|r| {
update_count.set(update_count.get() + 1);
app.emit("yomitan-import-progress", r).unwrap();
},
)?;
Ok::<usize, CJDicError>(update_count.get())
})
.await
.map_err(|e| CJDicError::Error(e.to_string()))??;
if update_count > 0 {
println!("Request app restart?",); println!("Request app restart?",);
// Request app restart anyway // Request app restart anyway
app.request_restart(); app_clone.request_restart();
} }
Ok(()) Ok(())