Skip to content

Commit d98c2df

Browse files
Add: 辞書周りのエンドポイントを追加
1 parent f760287 commit d98c2df

File tree

2 files changed

+113
-2
lines changed

2 files changed

+113
-2
lines changed

src/main.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use crate::icon_manager::ICON_MANAGER;
1313
use anyhow::Result;
1414
use axum::{
1515
response::{IntoResponse, Redirect},
16-
routing::{get, post},
16+
routing::{delete, get, post, put},
1717
Router,
1818
};
1919
use clap::Parser;
@@ -55,6 +55,18 @@ async fn main() -> Result<()> {
5555
"/import_user_dict",
5656
post(routes::user_dict::import_user_dict),
5757
)
58+
.route(
59+
"/user_dict_word",
60+
post(routes::user_dict::post_user_dict_word),
61+
)
62+
.route(
63+
"/user_dict_word/:word_uuid",
64+
delete(routes::user_dict::delete_user_dict_word),
65+
)
66+
.route(
67+
"/user_dict_word/:word_uuid",
68+
put(routes::user_dict::put_user_dict_word),
69+
)
5870
.route("/audio_query", post(routes::audio_query::post_audio_query))
5971
.route(
6072
"/accent_phrases",

src/routes/user_dict.rs

Lines changed: 100 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use crate::routes::audio_query::OPEN_JTALK;
22
use crate::voicevox::user_dict::{UserDict, UserDictWord, UserDictWordType};
33

4+
use axum::extract::{Path, Query};
45
use axum::response::Json;
56
use once_cell::sync::Lazy;
67
use serde::{Deserialize, Serialize};
@@ -36,9 +37,18 @@ pub struct VvUserDictWord {
3637
mora_count: usize,
3738
surface: String,
3839
pronunciation: String,
40+
#[serde(skip_deserializing)]
3941
part_of_speech_detail_1: String,
4042
}
4143

44+
#[derive(Debug, Serialize, Deserialize)]
45+
pub struct VvUserDictWordParam {
46+
priority: u32,
47+
accent_type: usize,
48+
surface: String,
49+
pronunciation: String,
50+
}
51+
4252
impl From<VvUserDictWord> for UserDictWord {
4353
fn from(word: VvUserDictWord) -> UserDictWord {
4454
UserDictWord::new(
@@ -51,6 +61,7 @@ impl From<VvUserDictWord> for UserDictWord {
5161
"動詞" => UserDictWordType::Verb,
5262
"形容詞" => UserDictWordType::Adjective,
5363
"語尾" => UserDictWordType::Suffix,
64+
"" => UserDictWordType::ProperNoun,
5465
_ => {
5566
warn!("Unknown word type: {}", &word.part_of_speech_detail_1);
5667
UserDictWordType::CommonNoun
@@ -82,6 +93,19 @@ impl From<UserDictWord> for VvUserDictWord {
8293
}
8394
}
8495

96+
impl From<VvUserDictWordParam> for UserDictWord {
97+
fn from(word: VvUserDictWordParam) -> UserDictWord {
98+
UserDictWord::new(
99+
&word.surface[..],
100+
word.pronunciation,
101+
word.accent_type,
102+
UserDictWordType::CommonNoun,
103+
word.priority,
104+
)
105+
.unwrap()
106+
}
107+
}
108+
85109
pub async fn get_user_dict() -> Json<HashMap<String, VvUserDictWord>> {
86110
let user_dict = USER_DICT.lock().await;
87111

@@ -110,9 +134,84 @@ pub async fn import_user_dict(Json(payload): Json<HashMap<String, VvUserDictWord
110134
.load(temp_file.to_str().unwrap())
111135
.map_err(|e| Error::DictionaryOperationFailed(e.into()))?;
112136

113-
user_dict.save(&USER_DICT_PATH).unwrap();
137+
user_dict
138+
.save(&USER_DICT_PATH)
139+
.map_err(|e| Error::DictionaryOperationFailed(e.into()))?;
114140

115141
OPEN_JTALK.lock().await.use_user_dict(&user_dict).unwrap();
116142

117143
Ok(())
118144
}
145+
146+
pub async fn post_user_dict_word(Query(param): Query<VvUserDictWordParam>) -> Result<String> {
147+
let mut user_dict = USER_DICT.lock().await;
148+
149+
let word: UserDictWord = param.into();
150+
151+
let word_uuid = user_dict
152+
.add_word(word)
153+
.map_err(|e| Error::DictionaryOperationFailed(e.into()))?;
154+
155+
user_dict
156+
.save(&USER_DICT_PATH)
157+
.map_err(|e| Error::DictionaryOperationFailed(e.into()))?;
158+
159+
OPEN_JTALK
160+
.lock()
161+
.await
162+
.use_user_dict(&user_dict)
163+
.map_err(|e| Error::DictionaryOperationFailed(e.into()))?;
164+
165+
Ok(word_uuid.hyphenated().to_string())
166+
}
167+
168+
pub async fn delete_user_dict_word(Path(word_uuid): Path<String>) -> Result<()> {
169+
let mut user_dict = USER_DICT.lock().await;
170+
171+
let word_uuid = uuid::Uuid::parse_str(&word_uuid)
172+
.map_err(|e| Error::DictionaryOperationFailed(e.into()))?;
173+
174+
user_dict
175+
.remove_word(word_uuid)
176+
.map_err(|e| Error::DictionaryOperationFailed(e.into()))?;
177+
178+
user_dict
179+
.save(&USER_DICT_PATH)
180+
.map_err(|e| Error::DictionaryOperationFailed(e.into()))?;
181+
182+
OPEN_JTALK
183+
.lock()
184+
.await
185+
.use_user_dict(&user_dict)
186+
.map_err(|e| Error::DictionaryOperationFailed(e.into()))?;
187+
188+
Ok(())
189+
}
190+
191+
pub async fn put_user_dict_word(
192+
Path(word_uuid): Path<String>,
193+
Query(payload): Query<VvUserDictWordParam>,
194+
) -> Result<()> {
195+
let mut user_dict = USER_DICT.lock().await;
196+
197+
let word_uuid = uuid::Uuid::parse_str(&word_uuid)
198+
.map_err(|e| Error::DictionaryOperationFailed(e.into()))?;
199+
200+
let word: UserDictWord = payload.into();
201+
202+
user_dict
203+
.update_word(word_uuid, word)
204+
.map_err(|e| Error::DictionaryOperationFailed(e.into()))?;
205+
206+
user_dict
207+
.save(&USER_DICT_PATH)
208+
.map_err(|e| Error::DictionaryOperationFailed(e.into()))?;
209+
210+
OPEN_JTALK
211+
.lock()
212+
.await
213+
.use_user_dict(&user_dict)
214+
.map_err(|e| Error::DictionaryOperationFailed(e.into()))?;
215+
216+
Ok(())
217+
}

0 commit comments

Comments
 (0)