1#[cfg(feature = "experimental")]
2mod transcription;
3
4#[cfg(feature = "config")]
5pub mod config;
6
7use std::{
8 fmt,
9 fs::{self},
10 io,
11 path::{Path, PathBuf},
12};
13
14#[derive(Debug)]
15pub enum Error {
16 IoError(io::Error),
17 ExtensionError,
18 FailedCreateRenamedFolder(io::Error),
19 NoParent,
20}
21impl fmt::Display for Error {
22 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
23 match self {
24 Error::IoError(error) => writeln!(f, "{}", error),
25 Error::ExtensionError => writeln!(f, "extension error"),
26 Error::FailedCreateRenamedFolder(e) => writeln!(f, "failed create renamed folder{}", e),
27 Error::NoParent => writeln!(f, "no parent"),
28 }
29 }
30}
31
32#[derive(Debug)]
33struct PathSet {
34 audio_path: PathBuf,
35 changed_audio_path: Option<PathBuf>,
36 line: String,
37}
38impl PathSet {
39 fn new<P: AsRef<Path>, S: AsRef<str>>(audio_path: P, line: S) -> Self {
41 Self {
42 audio_path: audio_path.as_ref().to_path_buf(),
43 changed_audio_path: None,
44 line: line.as_ref().to_string(),
45 }
46 }
47}
48impl fmt::Display for PathSet {
49 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
50 writeln!(f, "Audio: {}", self.audio_path.display())?;
51 writeln!(f, "Line: {}", self.line)?;
52 Ok(())
53 }
54}
55
56pub struct ListForCheck(Vec<(Option<String>, Option<String>)>);
57
58impl ListForCheck {
59 fn new() -> Self {
60 Self(Vec::<(Option<String>, Option<String>)>::new())
61 }
62}
63
64impl fmt::Display for ListForCheck {
65 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
66 for (old, new) in &self.0 {
67 let oldd = &old
68 .as_ref()
69 .unwrap_or(&"None".to_string())
70 .chars()
71 .take(20)
72 .collect::<String>();
73
74 writeln!(
75 f,
76 "* {:width$} ---> {}",
77 oldd,
78 new.as_ref().unwrap_or(&"None".to_string()),
79 width = 20
80 )?;
81 }
82 Ok(())
83 }
84}
85
86#[derive(Debug)]
87pub struct PathSets {
88 work_dir: PathBuf,
89 list: Vec<PathSet>,
90 audio_extension: String,
91 }
93impl fmt::Display for PathSets {
94 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
95 for i in &self.list {
96 writeln!(f, "{}", i)?;
97 }
98 Ok(())
99 }
100}
101impl PathSets {
102 pub fn new<P: AsRef<Path>, S: AsRef<str>>(
108 dir: P,
109 audio_extension: S,
110 line_extension: S,
111 ) -> Result<Self, Error> {
112 let filtered_path_list =
113 get_file_list(&dir, audio_extension.as_ref(), line_extension.as_ref())?;
114
115 let tmp_list = build_path_sets(
116 filtered_path_list,
117 audio_extension.as_ref(),
118 line_extension.as_ref(),
119 )?;
120
121 let mut new = PathSets {
122 work_dir: dir.as_ref().to_path_buf(),
123 list: tmp_list,
124 audio_extension: audio_extension.as_ref().to_string(),
125 };
126 new.ready_rename();
127 Ok(new)
128 }
129
130 #[cfg(feature = "experimental")]
132 pub fn new_transcription<P: AsRef<Path>, S: AsRef<str>>(
133 dir: P,
134 audio_extension: S,
135 line_extension: S,
136 ) -> Result<Self, Error> {
137 let filtered_path_list =
138 get_file_list(&dir, audio_extension.as_ref(), line_extension.as_ref())?;
139
140 let path_set_list = filtered_path_list
141 .iter()
142 .filter(|f| f.extension().unwrap().to_str() == Some(audio_extension.as_ref()))
143 .map(|audio_path| {
144 let line = transcription::transcription("model_path", audio_path, Some("ja"));
145 PathSet::new(audio_path, line)
146 })
147 .collect();
148
149 let mut new = PathSets {
150 work_dir: dir.as_ref().to_path_buf(),
151 list: path_set_list,
152 audio_extension: audio_extension.as_ref().to_string(),
153 };
154 new.ready_rename();
155 Ok(new)
156 }
157
158 fn ready_rename(&mut self) {
160 for i in &mut self.list {
161 i.changed_audio_path = Some(
163 self.work_dir
164 .join("renamed")
165 .join(&i.line)
166 .with_extension(&self.audio_extension),
167 );
168 }
169 }
170
171 pub fn check(&self) -> Result<ListForCheck, Error> {
173 let mut list_for_check = ListForCheck::new();
174 for i in &self.list {
175 list_for_check.0.push((
176 i.audio_path
177 .file_name()
178 .map(|f| f.to_string_lossy().to_string()),
179 i.changed_audio_path
180 .as_ref()
181 .and_then(|f| f.file_name().map(|f| f.to_string_lossy().to_string())),
182 ));
183 }
184 Ok(list_for_check)
185 }
186
187 pub fn rename(&mut self) -> Result<(), Error> {
189 create_renamed_folder(&self.work_dir)?;
190 for i in &mut self.list {
191 let changed_audio = match i.changed_audio_path.as_ref() {
192 Some(v) => v,
193 None => continue,
194 };
195 if fs::rename(&i.audio_path, changed_audio).is_err() {
196 i.changed_audio_path = None
197 };
198 }
199 Ok(())
200 }
201}
202
203fn get_file_list<P: AsRef<Path>>(
206 dir: P,
207 audio_ext: &str,
208 line_ext: &str,
209) -> Result<Vec<PathBuf>, Error> {
210 Ok(fs::read_dir(&dir)
211 .map_err(Error::IoError)?
212 .filter_map(|entry| entry.ok())
213 .map(|ok_entry| ok_entry.path())
214 .filter(|entry| {
215 entry
216 .extension()
217 .is_some_and(|ext| ext == audio_ext || ext == line_ext)
218 })
219 .collect())
220}
221
222fn create_renamed_folder<P: AsRef<Path>>(dir: P) -> Result<(), Error> {
223 fs::create_dir(dir.as_ref().join("renamed")).map_err(Error::FailedCreateRenamedFolder)?;
224 Ok(())
225}
226
227fn build_path_sets(
229 list: Vec<PathBuf>,
230 audio_ext: &str,
231 line_ext: &str,
232) -> Result<Vec<PathSet>, Error> {
233 let mut tmp_list = Vec::<PathSet>::new();
234 let mut empty_count = 0;
235
236 for path in list {
237 if match path.extension() {
238 Some(v) => v,
239 None => continue,
240 } == audio_ext
241 {
242 let text_path = path.with_extension(line_ext);
244
245 let mut empty = false;
246
247 let line = if text_path.exists() {
248 let tmp = fs::read_to_string(text_path)
249 .map_err(Error::IoError)?
250 .chars()
251 .take(20)
252 .collect::<String>()
253 .trim()
254 .to_string();
255 if tmp.is_empty() {
256 empty = true;
258 format!("empty_{}", empty_count)
259 } else {
260 tmp
262 }
263 } else {
264 empty = true;
266 format!("empty_{}", empty_count)
267 };
268
269 if empty {
270 empty_count += 1;
271 }
272
273 let new_set = PathSet::new(path, line);
274 tmp_list.push(new_set);
275 }
276 }
277 Ok(tmp_list)
278}
279
280#[cfg(test)]
281mod tests {
282 use super::*;
283 use std::{env, process};
284
285 #[test]
286 fn ready_foo() {
287 ready();
288 let a = env::current_dir().unwrap().join("assets_for_test/assets");
289 create_renamed_folder(a).unwrap();
290 }
291
292 fn ready() -> bool {
294 let p = env::current_dir().unwrap().to_path_buf();
295 let windows_path = p.join("ready_test_files.ps1");
296 let unix_path = p.join("ready_test_files.sh");
297
298 if cfg!(target_os = "windows") {
299 process::Command::new("powershell")
300 .args([
301 "-ExecutionPolicy",
302 "Bypass",
303 "-NoExit",
304 "-File",
305 windows_path.to_str().unwrap(),
306 ])
307 .status()
308 .unwrap()
309 .success()
310 } else {
311 process::Command::new("sh")
312 .args([unix_path.to_str().unwrap()])
313 .status()
314 .unwrap()
315 .success()
316 }
317 }
318
319 #[test]
320 fn ready_function() {
321 ready();
322 println!(
323 "{:?}",
324 get_file_list(
325 env::current_dir()
326 .unwrap()
327 .join("assets_for_test")
328 .join("assets"),
329 "wav",
330 "txt"
331 )
332 .unwrap()
333 );
334 }
335
336 #[test]
337 fn list_assets() {
338 ready();
339 let cud = env::current_dir()
340 .unwrap()
341 .join("assets_for_test")
342 .join("assets");
343 let a = PathSets::new(&cud, "wav", "txt").unwrap();
344 for i in a.list {
345 println!("{:?}", i);
346 }
347 }
348
349 #[test]
350 fn test_check() {
351 ready();
352 let cud = env::current_dir()
353 .unwrap()
354 .join("assets_for_test")
355 .join("assets");
356 let a = PathSets::new(&cud, "wav", "txt").unwrap().check().unwrap();
357 println!("{}", a);
358 }
359
360 #[test]
361 fn test_rename() {
362 ready();
363 let cud = env::current_dir()
364 .unwrap()
365 .join("assets_for_test")
366 .join("assets");
367 PathSets::new(&cud, "wav", "txt").unwrap().rename().unwrap();
368 for i in fs::read_dir(cud.join("renamed")).unwrap() {
369 println!("{:?}", i);
370 }
371 }
372
373 #[test]
374 fn test_init_rename_prep() {
375 ready();
376 let cud = env::current_dir()
377 .unwrap()
378 .join("assets_for_test")
379 .join("assets");
380 let mut b = PathSets::new(&cud, "wav", "txt").unwrap();
381 b.ready_rename();
382 println!("{:?}", b.list);
383 }
384}