mirror of
https://github.com/patarapolw/cjdic2.git
synced 2026-11-09 17:39:35 +00:00
make starting from zero work on Android + Windows
This commit is contained in:
1 parent
653eacf8d4
commit
a00efbf505
10 files changed
+166
-44
No files matched your search
Generated
+1
@@ -645,6 +645,7 @@ dependencies = [
|
|||||||
"tauri-plugin-opener",
|
"tauri-plugin-opener",
|
||||||
"tokio",
|
"tokio",
|
||||||
"zip",
|
"zip",
|
||||||
|
"zstd",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|||||||
+5
-4
@@ -4,9 +4,9 @@
|
|||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev:desktop": "tauri dev",
|
"dev:desktop": "cross-env RUST_BACKTRACE=1 tauri dev",
|
||||||
"dev:mobile": "tauri dev -c src-tauri/tauri.mobile.conf.json",
|
"dev:mobile": "cross-env RUST_BACKTRACE=1 tauri dev -c src-tauri/tauri.mobile.conf.json",
|
||||||
"dev:android": "tauri android dev",
|
"dev:android": "cross-env RUST_BACKTRACE=1 tauri android dev",
|
||||||
"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",
|
||||||
@@ -17,6 +17,7 @@
|
|||||||
"tauri": "tauri"
|
"tauri": "tauri"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@tauri-apps/cli": "^2"
|
"@tauri-apps/cli": "^2",
|
||||||
|
"cross-env": "^10.1.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Generated
+62
@@ -11,6 +11,9 @@ importers:
|
|||||||
'@tauri-apps/cli':
|
'@tauri-apps/cli':
|
||||||
specifier: ^2
|
specifier: ^2
|
||||||
version: 2.10.0
|
version: 2.10.0
|
||||||
|
cross-env:
|
||||||
|
specifier: ^10.1.0
|
||||||
|
version: 10.1.0
|
||||||
|
|
||||||
js-server:
|
js-server:
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -256,6 +259,9 @@ packages:
|
|||||||
'@emotion/weak-memoize@0.4.0':
|
'@emotion/weak-memoize@0.4.0':
|
||||||
resolution: {integrity: sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==}
|
resolution: {integrity: sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==}
|
||||||
|
|
||||||
|
'@epic-web/invariant@1.0.0':
|
||||||
|
resolution: {integrity: sha512-lrTPqgvfFQtR/eY/qkIzp98OGdNJu0m5ji3q/nJI8v3SXkRKEnWiOxMmbvcSoAIzv/cGiuvRy57k4suKQSAdwA==}
|
||||||
|
|
||||||
'@esbuild/aix-ppc64@0.27.3':
|
'@esbuild/aix-ppc64@0.27.3':
|
||||||
resolution: {integrity: sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==}
|
resolution: {integrity: sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
@@ -1100,6 +1106,15 @@ packages:
|
|||||||
resolution: {integrity: sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==}
|
resolution: {integrity: sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
|
|
||||||
|
cross-env@10.1.0:
|
||||||
|
resolution: {integrity: sha512-GsYosgnACZTADcmEyJctkJIoqAhHjttw7RsFrVoJNXbsWWqaq6Ym+7kZjq6mS45O0jij6vtiReppKQEtqWy6Dw==}
|
||||||
|
engines: {node: '>=20'}
|
||||||
|
hasBin: true
|
||||||
|
|
||||||
|
cross-spawn@7.0.6:
|
||||||
|
resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
|
||||||
|
engines: {node: '>= 8'}
|
||||||
|
|
||||||
csstype@3.2.3:
|
csstype@3.2.3:
|
||||||
resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==}
|
resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==}
|
||||||
|
|
||||||
@@ -1238,6 +1253,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==}
|
resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
|
isexe@2.0.0:
|
||||||
|
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
|
||||||
|
|
||||||
js-tokens@4.0.0:
|
js-tokens@4.0.0:
|
||||||
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
|
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
|
||||||
|
|
||||||
@@ -1349,6 +1367,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==}
|
resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
|
|
||||||
|
path-key@3.1.1:
|
||||||
|
resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
|
||||||
|
engines: {node: '>=8'}
|
||||||
|
|
||||||
path-parse@1.0.7:
|
path-parse@1.0.7:
|
||||||
resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
|
resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
|
||||||
|
|
||||||
@@ -1488,6 +1510,14 @@ packages:
|
|||||||
setprototypeof@1.2.0:
|
setprototypeof@1.2.0:
|
||||||
resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==}
|
resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==}
|
||||||
|
|
||||||
|
shebang-command@2.0.0:
|
||||||
|
resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
|
||||||
|
engines: {node: '>=8'}
|
||||||
|
|
||||||
|
shebang-regex@3.0.0:
|
||||||
|
resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
|
||||||
|
engines: {node: '>=8'}
|
||||||
|
|
||||||
sonic-boom@4.2.1:
|
sonic-boom@4.2.1:
|
||||||
resolution: {integrity: sha512-w6AxtubXa2wTXAUsZMMWERrsIRAdrK0Sc+FUytWvYAhBJLyuI4llrMIC1DtlNSdI99EI86KZum2MMq3EAZlF9Q==}
|
resolution: {integrity: sha512-w6AxtubXa2wTXAUsZMMWERrsIRAdrK0Sc+FUytWvYAhBJLyuI4llrMIC1DtlNSdI99EI86KZum2MMq3EAZlF9Q==}
|
||||||
|
|
||||||
@@ -1614,6 +1644,11 @@ packages:
|
|||||||
resolution: {integrity: sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==}
|
resolution: {integrity: sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
|
|
||||||
|
which@2.0.2:
|
||||||
|
resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
|
||||||
|
engines: {node: '>= 8'}
|
||||||
|
hasBin: true
|
||||||
|
|
||||||
ws@8.19.0:
|
ws@8.19.0:
|
||||||
resolution: {integrity: sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==}
|
resolution: {integrity: sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==}
|
||||||
engines: {node: '>=10.0.0'}
|
engines: {node: '>=10.0.0'}
|
||||||
@@ -1918,6 +1953,8 @@ snapshots:
|
|||||||
|
|
||||||
'@emotion/weak-memoize@0.4.0': {}
|
'@emotion/weak-memoize@0.4.0': {}
|
||||||
|
|
||||||
|
'@epic-web/invariant@1.0.0': {}
|
||||||
|
|
||||||
'@esbuild/aix-ppc64@0.27.3':
|
'@esbuild/aix-ppc64@0.27.3':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
@@ -2970,6 +3007,17 @@ snapshots:
|
|||||||
path-type: 4.0.0
|
path-type: 4.0.0
|
||||||
yaml: 1.10.2
|
yaml: 1.10.2
|
||||||
|
|
||||||
|
cross-env@10.1.0:
|
||||||
|
dependencies:
|
||||||
|
'@epic-web/invariant': 1.0.0
|
||||||
|
cross-spawn: 7.0.6
|
||||||
|
|
||||||
|
cross-spawn@7.0.6:
|
||||||
|
dependencies:
|
||||||
|
path-key: 3.1.1
|
||||||
|
shebang-command: 2.0.0
|
||||||
|
which: 2.0.2
|
||||||
|
|
||||||
csstype@3.2.3: {}
|
csstype@3.2.3: {}
|
||||||
|
|
||||||
debug@4.4.3:
|
debug@4.4.3:
|
||||||
@@ -3128,6 +3176,8 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
hasown: 2.0.2
|
hasown: 2.0.2
|
||||||
|
|
||||||
|
isexe@2.0.0: {}
|
||||||
|
|
||||||
js-tokens@4.0.0: {}
|
js-tokens@4.0.0: {}
|
||||||
|
|
||||||
jsesc@3.1.0: {}
|
jsesc@3.1.0: {}
|
||||||
@@ -3201,6 +3251,8 @@ snapshots:
|
|||||||
json-parse-even-better-errors: 2.3.1
|
json-parse-even-better-errors: 2.3.1
|
||||||
lines-and-columns: 1.2.4
|
lines-and-columns: 1.2.4
|
||||||
|
|
||||||
|
path-key@3.1.1: {}
|
||||||
|
|
||||||
path-parse@1.0.7: {}
|
path-parse@1.0.7: {}
|
||||||
|
|
||||||
path-scurry@2.0.2:
|
path-scurry@2.0.2:
|
||||||
@@ -3340,6 +3392,12 @@ snapshots:
|
|||||||
|
|
||||||
setprototypeof@1.2.0: {}
|
setprototypeof@1.2.0: {}
|
||||||
|
|
||||||
|
shebang-command@2.0.0:
|
||||||
|
dependencies:
|
||||||
|
shebang-regex: 3.0.0
|
||||||
|
|
||||||
|
shebang-regex@3.0.0: {}
|
||||||
|
|
||||||
sonic-boom@4.2.1:
|
sonic-boom@4.2.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
atomic-sleep: 1.0.0
|
atomic-sleep: 1.0.0
|
||||||
@@ -3420,6 +3478,10 @@ snapshots:
|
|||||||
tr46: 5.1.1
|
tr46: 5.1.1
|
||||||
webidl-conversions: 7.0.0
|
webidl-conversions: 7.0.0
|
||||||
|
|
||||||
|
which@2.0.2:
|
||||||
|
dependencies:
|
||||||
|
isexe: 2.0.0
|
||||||
|
|
||||||
ws@8.19.0: {}
|
ws@8.19.0: {}
|
||||||
|
|
||||||
yallist@3.1.1: {}
|
yallist@3.1.1: {}
|
||||||
|
|||||||
@@ -51,10 +51,11 @@ impl<'a> SearchDatabase<'a> {
|
|||||||
self.conn.execute_batch(&format!(
|
self.conn.execute_batch(&format!(
|
||||||
"
|
"
|
||||||
DELETE FROM {0}.terms;
|
DELETE FROM {0}.terms;
|
||||||
DELETE FROM {0}.terms_ft;
|
DROP TABLE {0}.terms_ft;
|
||||||
",
|
",
|
||||||
DBSCHEMA[DbChild::Search]
|
DBSCHEMA[DbChild::Search]
|
||||||
))?;
|
))?;
|
||||||
|
self.create_schema()?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
use blake3::hash;
|
use blake3::hash;
|
||||||
|
use enum_map::EnumMap;
|
||||||
use rusqlite::{Connection, OptionalExtension, Result, Transaction, params};
|
use rusqlite::{Connection, OptionalExtension, Result, Transaction, params};
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
@@ -61,6 +62,7 @@ pub struct YomitanZipImportResult {
|
|||||||
pub struct YomitanWriter {
|
pub struct YomitanWriter {
|
||||||
dir: PathBuf,
|
dir: PathBuf,
|
||||||
conn: Connection,
|
conn: Connection,
|
||||||
|
is_db_attached: EnumMap<DbChild, bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl YomitanWriter {
|
impl YomitanWriter {
|
||||||
@@ -78,7 +80,15 @@ impl YomitanWriter {
|
|||||||
",
|
",
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
Ok(Self { dir, conn })
|
Ok(Self {
|
||||||
|
dir,
|
||||||
|
conn,
|
||||||
|
is_db_attached: enum_map! {
|
||||||
|
DbChild::YomitanGlossary => false,
|
||||||
|
DbChild::Search => false,
|
||||||
|
_ => true
|
||||||
|
},
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_schema(
|
pub fn create_schema(
|
||||||
@@ -172,8 +182,8 @@ impl YomitanWriter {
|
|||||||
)?;
|
)?;
|
||||||
|
|
||||||
self.create_materialized_views()?;
|
self.create_materialized_views()?;
|
||||||
self.attach_db(DbChild::YomitanGlossary)?;
|
self.ensure_db_attached(DbChild::YomitanGlossary)?;
|
||||||
self.attach_db(DbChild::Search)?;
|
self.ensure_db_attached(DbChild::Search)?;
|
||||||
|
|
||||||
let schema_version = "2026-03-08";
|
let schema_version = "2026-03-08";
|
||||||
let current_schema_version = {
|
let current_schema_version = {
|
||||||
@@ -334,7 +344,11 @@ impl YomitanWriter {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn attach_db(&mut self, db_child: DbChild) -> Result<(), CJDicError> {
|
fn ensure_db_attached(&mut self, db_child: DbChild) -> Result<(), CJDicError> {
|
||||||
|
if self.is_db_attached[db_child] {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
let dir = self.dir.clone();
|
let dir = self.dir.clone();
|
||||||
let path = if self.dir.is_absolute() {
|
let path = if self.dir.is_absolute() {
|
||||||
dir
|
dir
|
||||||
@@ -371,6 +385,8 @@ impl YomitanWriter {
|
|||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.is_db_attached[db_child] = true;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -506,7 +522,7 @@ impl YomitanWriter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.attach_db(DbChild::YomitanGlossary)?;
|
self.ensure_db_attached(DbChild::YomitanGlossary)?;
|
||||||
|
|
||||||
{
|
{
|
||||||
let tx = self.conn.transaction()?;
|
let tx = self.conn.transaction()?;
|
||||||
@@ -793,12 +809,30 @@ impl YomitanWriter {
|
|||||||
tokenizer: Tokenizer,
|
tokenizer: Tokenizer,
|
||||||
progress_callback: impl Fn(YomitanProgress),
|
progress_callback: impl Fn(YomitanProgress),
|
||||||
) -> Result<(), CJDicError> {
|
) -> Result<(), CJDicError> {
|
||||||
|
self.ensure_db_attached(DbChild::Search)?;
|
||||||
|
|
||||||
let mut search_db = SearchDatabase::new(&mut self.conn);
|
let mut search_db = SearchDatabase::new(&mut self.conn);
|
||||||
|
search_db.create_schema()?;
|
||||||
search_db.reset_db()?;
|
search_db.reset_db()?;
|
||||||
search_db.regenerate_yomitan("main", tokenizer.clone(), &progress_callback)?;
|
search_db.regenerate_yomitan("main", tokenizer.clone(), &progress_callback)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn check_search_db(&mut self) -> Result<bool, CJDicError> {
|
||||||
|
self.ensure_db_attached(DbChild::Search)?;
|
||||||
|
|
||||||
|
let is_filled = self.conn.query_row(
|
||||||
|
"
|
||||||
|
SELECT
|
||||||
|
(SELECT COALESCE(MAX(id), 0) FROM search.terms) >=
|
||||||
|
(SELECT COALESCE(MAX(id), 0) FROM terms)
|
||||||
|
",
|
||||||
|
[],
|
||||||
|
|r| r.get::<_, bool>(0),
|
||||||
|
)?;
|
||||||
|
Ok(is_filled)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn intern(
|
fn intern(
|
||||||
|
|||||||
+19
-9
@@ -1,4 +1,5 @@
|
|||||||
use std::{
|
use std::{
|
||||||
|
backtrace::Backtrace,
|
||||||
string::FromUtf8Error,
|
string::FromUtf8Error,
|
||||||
sync::{MutexGuard, PoisonError},
|
sync::{MutexGuard, PoisonError},
|
||||||
};
|
};
|
||||||
@@ -51,63 +52,72 @@ pub enum CJDicError {
|
|||||||
|
|
||||||
impl From<rusqlite::Error> for CJDicError {
|
impl From<rusqlite::Error> for CJDicError {
|
||||||
fn from(e: rusqlite::Error) -> Self {
|
fn from(e: rusqlite::Error) -> Self {
|
||||||
eprintln!("{e:#}");
|
let bt = Backtrace::capture();
|
||||||
|
eprintln!("{e:#}\n{bt}");
|
||||||
CJDicError::Database(e.to_string())
|
CJDicError::Database(e.to_string())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<serde_json::Error> for CJDicError {
|
impl From<serde_json::Error> for CJDicError {
|
||||||
fn from(e: serde_json::Error) -> Self {
|
fn from(e: serde_json::Error) -> Self {
|
||||||
eprintln!("{e:#}");
|
let bt = Backtrace::capture();
|
||||||
|
eprintln!("{e:#}\n{bt}");
|
||||||
CJDicError::Serialization(e.to_string())
|
CJDicError::Serialization(e.to_string())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<anyhow::Error> for CJDicError {
|
impl From<anyhow::Error> for CJDicError {
|
||||||
fn from(e: anyhow::Error) -> Self {
|
fn from(e: anyhow::Error) -> Self {
|
||||||
eprintln!("{e:#}");
|
let bt = Backtrace::capture();
|
||||||
|
eprintln!("{e:#}\n{bt}");
|
||||||
CJDicError::AnyhowError(e.to_string())
|
CJDicError::AnyhowError(e.to_string())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<std::io::Error> for CJDicError {
|
impl From<std::io::Error> for CJDicError {
|
||||||
fn from(e: std::io::Error) -> Self {
|
fn from(e: std::io::Error) -> Self {
|
||||||
eprintln!("{e:#}");
|
let bt = Backtrace::capture();
|
||||||
|
eprintln!("{e:#}\n{bt}");
|
||||||
CJDicError::IOError(e.to_string())
|
CJDicError::IOError(e.to_string())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<ZipError> for CJDicError {
|
impl From<ZipError> for CJDicError {
|
||||||
fn from(e: ZipError) -> Self {
|
fn from(e: ZipError) -> Self {
|
||||||
eprintln!("{e:#}");
|
let bt = Backtrace::capture();
|
||||||
|
eprintln!("{e:#}\n{bt}");
|
||||||
CJDicError::ZipError(e.to_string())
|
CJDicError::ZipError(e.to_string())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<VibratoError> for CJDicError {
|
impl From<VibratoError> for CJDicError {
|
||||||
fn from(e: VibratoError) -> Self {
|
fn from(e: VibratoError) -> Self {
|
||||||
eprintln!("{e:#}");
|
let bt = Backtrace::capture();
|
||||||
|
eprintln!("{e:#}\n{bt}");
|
||||||
CJDicError::VibratoError(e.to_string())
|
CJDicError::VibratoError(e.to_string())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<FromUtf8Error> for CJDicError {
|
impl From<FromUtf8Error> for CJDicError {
|
||||||
fn from(e: FromUtf8Error) -> Self {
|
fn from(e: FromUtf8Error) -> Self {
|
||||||
eprintln!("{e:#}");
|
let bt = Backtrace::capture();
|
||||||
|
eprintln!("{e:#}\n{bt}");
|
||||||
CJDicError::FromUtf8Error(e.to_string())
|
CJDicError::FromUtf8Error(e.to_string())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<PoisonError<MutexGuard<'_, Connection>>> for CJDicError {
|
impl From<PoisonError<MutexGuard<'_, Connection>>> for CJDicError {
|
||||||
fn from(e: PoisonError<MutexGuard<'_, Connection>>) -> Self {
|
fn from(e: PoisonError<MutexGuard<'_, Connection>>) -> Self {
|
||||||
eprintln!("{e:#}");
|
let bt = Backtrace::capture();
|
||||||
|
eprintln!("{e:#}\n{bt}");
|
||||||
CJDicError::ConnectionMutexGuardError(e.to_string())
|
CJDicError::ConnectionMutexGuardError(e.to_string())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<PoisonError<MutexGuard<'_, Tokenizer>>> for CJDicError {
|
impl From<PoisonError<MutexGuard<'_, Tokenizer>>> for CJDicError {
|
||||||
fn from(e: PoisonError<MutexGuard<'_, Tokenizer>>) -> Self {
|
fn from(e: PoisonError<MutexGuard<'_, Tokenizer>>) -> Self {
|
||||||
eprintln!("{e:#}");
|
let bt = Backtrace::capture();
|
||||||
|
eprintln!("{e:#}\n{bt}");
|
||||||
CJDicError::TokenizerMutexGuardError(e.to_string())
|
CJDicError::TokenizerMutexGuardError(e.to_string())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+13
-4
@@ -40,10 +40,10 @@ pub struct AppService {
|
|||||||
impl AppService {
|
impl AppService {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
db_dir: impl AsRef<Path>,
|
db_dir: impl AsRef<Path>,
|
||||||
vibrato_dict: impl AsRef<Path>,
|
vibrato_dic: impl AsRef<Path>,
|
||||||
) -> Result<Self, CJDicError> {
|
) -> Result<Self, CJDicError> {
|
||||||
let db = Database::new(db_dir)?;
|
let db = Database::new(db_dir)?;
|
||||||
let tokenizer = Tokenizer::new(vibrato_dict)?;
|
let tokenizer = Tokenizer::new(vibrato_dic)?;
|
||||||
Ok(Self { db, tokenizer })
|
Ok(Self { db, tokenizer })
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,6 +174,10 @@ impl AppService {
|
|||||||
to_be_removed_dicts.push(z.to_string());
|
to_be_removed_dicts.push(z.to_string());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
for z in dir_zip_map.keys() {
|
||||||
|
new_dicts.push(z.to_string());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Import ordering
|
// Import ordering
|
||||||
@@ -202,14 +206,19 @@ impl AppService {
|
|||||||
|
|
||||||
{
|
{
|
||||||
let mut writer = YomitanWriter::new(self.db.dir.clone())?;
|
let mut writer = YomitanWriter::new(self.db.dir.clone())?;
|
||||||
|
|
||||||
for z in new_dicts.clone().iter() {
|
for z in new_dicts.clone().iter() {
|
||||||
if let Some(zip_file) = dir_zip_map.get(z) {
|
if let Some(zip_file) = dir_zip_map.get(z) {
|
||||||
Self::import_yomitan_zip_file(&mut writer, *zip_file, lang, &import_callback)?;
|
Self::import_yomitan_zip_file(&mut writer, *zip_file, lang, &import_callback)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
writer.make_search_db(self.tokenizer.clone(), &import_callback)?;
|
{
|
||||||
|
let mut writer = YomitanWriter::new(self.db.dir.clone())?;
|
||||||
|
|
||||||
|
if new_dicts.len() + to_be_removed_dicts.len() > 0 || !writer.check_search_db()? {
|
||||||
|
writer.make_search_db(self.tokenizer.clone(), &import_callback)?;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(LoadYomitanZipDirResult {
|
Ok(LoadYomitanZipDirResult {
|
||||||
|
|||||||
@@ -26,9 +26,8 @@ pub struct Tokenizer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Tokenizer {
|
impl Tokenizer {
|
||||||
pub fn new(vibrato_dict: impl AsRef<Path>) -> Result<Self, CJDicError> {
|
pub fn new(vibrato_dic: impl AsRef<Path>) -> Result<Self, CJDicError> {
|
||||||
let file = BufReader::new(File::open(vibrato_dict)?);
|
let reader = BufReader::new(File::open(vibrato_dic)?);
|
||||||
let reader = zstd::Decoder::new(file)?;
|
|
||||||
let dictionary = vibrato_rkyv::Dictionary::read(reader)?;
|
let dictionary = vibrato_rkyv::Dictionary::read(reader)?;
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
ja_tokenizer: vibrato_rkyv::Tokenizer::new(dictionary),
|
ja_tokenizer: vibrato_rkyv::Tokenizer::new(dictionary),
|
||||||
|
|||||||
@@ -29,3 +29,4 @@ serde = "1.0.228"
|
|||||||
zip = "8.1.0"
|
zip = "8.1.0"
|
||||||
tokio = { version = "1.50.0", features = ["io-util"] }
|
tokio = { version = "1.50.0", features = ["io-util"] }
|
||||||
tauri-plugin-clipboard-manager = "2"
|
tauri-plugin-clipboard-manager = "2"
|
||||||
|
zstd = "0.13.3"
|
||||||
+22
-18
@@ -15,35 +15,39 @@ pub fn run() {
|
|||||||
.plugin(tauri_plugin_opener::init())
|
.plugin(tauri_plugin_opener::init())
|
||||||
.plugin(tauri_plugin_clipboard_manager::init())
|
.plugin(tauri_plugin_clipboard_manager::init())
|
||||||
.setup(|app| {
|
.setup(|app| {
|
||||||
let app_dir = app.path().app_config_dir()?;
|
let config_dir = app.path().app_config_dir()?;
|
||||||
create_dir_all(&app_dir)?;
|
create_dir_all(&config_dir)?;
|
||||||
|
|
||||||
let dict_path = {
|
let data_dir = app.path().app_data_dir()?;
|
||||||
// Resolve the resource path (returns asset://localhost/ URI on Android)
|
create_dir_all(&data_dir.join("yomitan/ja"))?;
|
||||||
let resource_path = app.path().resolve(
|
|
||||||
|
let cache_dir = app.path().app_cache_dir()?;
|
||||||
|
let vibrato_dic_dir = cache_dir.join("vibrato");
|
||||||
|
create_dir_all(&vibrato_dic_dir)?;
|
||||||
|
|
||||||
|
println!("{:?}", vibrato_dic_dir);
|
||||||
|
|
||||||
|
let vibrato_dic_path = vibrato_dic_dir.join("system.dic");
|
||||||
|
if !vibrato_dic_path.exists() {
|
||||||
|
let zst_path = app.path().resolve(
|
||||||
"resources/mecab-ipadic/system.dic.zst",
|
"resources/mecab-ipadic/system.dic.zst",
|
||||||
tauri::path::BaseDirectory::Resource,
|
tauri::path::BaseDirectory::Resource,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
// Use Tauri's fs abstraction — works on both Android and desktop
|
// Use Tauri's fs abstraction — works on both Android and desktop
|
||||||
let bytes = app.fs().read(&resource_path)?;
|
let bytes = app.fs().read(&zst_path)?;
|
||||||
|
|
||||||
// Write to app's cache dir, which IS a real writable filesystem path on Android
|
let mut decoder = zstd::Decoder::new(bytes.as_slice())?;
|
||||||
let cache_dir = app.path().app_cache_dir()?.join("vibrato");
|
let mut out = fs::File::create(&vibrato_dic_path)?;
|
||||||
create_dir_all(&cache_dir)?;
|
std::io::copy(&mut decoder, &mut out)?;
|
||||||
let dict_path = cache_dir.join("system.dic.zst");
|
}
|
||||||
fs::write(&dict_path, &bytes)?;
|
|
||||||
|
|
||||||
dict_path
|
println!("{:?}", vibrato_dic_path);
|
||||||
};
|
|
||||||
|
|
||||||
// db_path is app_dir;
|
// db_path is at config_dir;
|
||||||
let service = AppService::new(&app_dir, &dict_path)?;
|
let service = AppService::new(&config_dir, &vibrato_dic_path)?;
|
||||||
app.manage(service);
|
app.manage(service);
|
||||||
|
|
||||||
let app_data_dir = app.path().app_data_dir()?;
|
|
||||||
create_dir_all(&app_data_dir.join("yomitan/ja"))?;
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
.invoke_handler(tauri::generate_handler![
|
.invoke_handler(tauri::generate_handler![
|
||||||
|
|||||||
Reference in new issue
Block a user