code tidying
This commit is contained in:
parent
253db1cbd5
commit
8f03cf4f17
|
@ -13,7 +13,7 @@ pub fn new_taglib_file(
|
|||
filepath: String,
|
||||
taglib_type: Option<TagLibFileType>,
|
||||
) -> Result<TagLibFile, TagLibError> {
|
||||
let filename_c = CString::new(filepath.clone()).unwrap();
|
||||
let filename_c = CString::new(filepath).unwrap();
|
||||
let filename_c_ptr = filename_c.as_ptr();
|
||||
|
||||
let file = unsafe {
|
||||
|
@ -70,10 +70,11 @@ impl TagLibFile {
|
|||
impl File for TagLibFile {
|
||||
fn save(&mut self) -> Result<(), TagLibError> {
|
||||
let result = unsafe { bindings::wrap_taglib_file_save(self.ctx) };
|
||||
return match result {
|
||||
|
||||
match result {
|
||||
true => Ok(()),
|
||||
false => Err(TagLibError::SaveError),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -12,9 +12,9 @@ impl TagLibOggTag {
|
|||
let value = unsafe { bindings::wrap_taglib_opustag_get_field(self.ctx, key.as_ptr()) };
|
||||
|
||||
if value.is_null() {
|
||||
return None;
|
||||
None
|
||||
} else {
|
||||
return c_str_to_str(value);
|
||||
c_str_to_str(value)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,8 @@ pub struct TagLibTag {
|
|||
impl Tag for TagLibTag {
|
||||
fn title(&self) -> Option<String> {
|
||||
let title_ref = unsafe { bindings::wrap_taglib_tag_title(self.ctx) };
|
||||
return c_str_to_str(title_ref);
|
||||
|
||||
c_str_to_str(title_ref)
|
||||
}
|
||||
fn set_title(&mut self, title: String) {
|
||||
let title = CString::new(title).unwrap();
|
||||
|
@ -18,7 +19,8 @@ impl Tag for TagLibTag {
|
|||
}
|
||||
fn artist(&self) -> Option<String> {
|
||||
let artist_ref = unsafe { bindings::wrap_taglib_tag_artist(self.ctx) };
|
||||
return c_str_to_str(artist_ref);
|
||||
|
||||
c_str_to_str(artist_ref)
|
||||
}
|
||||
fn set_artist(&mut self, artist: String) {
|
||||
let artist = CString::new(artist).unwrap();
|
||||
|
|
10
src/args.rs
10
src/args.rs
|
@ -4,10 +4,10 @@ use clap::{Args, Parser, Subcommand};
|
|||
#[clap()]
|
||||
pub struct CLIArgs {
|
||||
#[clap(subcommand)]
|
||||
pub command: Option<Commands>,
|
||||
pub command: Commands,
|
||||
}
|
||||
|
||||
#[derive(Debug, Subcommand)]
|
||||
#[derive(Debug, Clone, Subcommand)]
|
||||
pub enum Commands {
|
||||
Process(ProcessCommandArgs),
|
||||
Genhtml(GenHTMLCommandArgs),
|
||||
|
@ -17,7 +17,7 @@ pub enum Commands {
|
|||
GetTags(GetTagsCommandArgs),
|
||||
}
|
||||
|
||||
#[derive(Debug, Args)]
|
||||
#[derive(Debug, Clone, Args)]
|
||||
pub struct ProcessCommandArgs {
|
||||
pub source: String,
|
||||
#[clap(long)]
|
||||
|
@ -30,7 +30,7 @@ pub struct ProcessCommandArgs {
|
|||
pub replaygain_threads: Option<u32>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Args)]
|
||||
#[derive(Debug, Clone, Args)]
|
||||
pub struct GenHTMLCommandArgs {
|
||||
pub source: String,
|
||||
pub dest: String,
|
||||
|
@ -42,7 +42,7 @@ pub struct GenHTMLCommandArgs {
|
|||
pub link_base: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Args)]
|
||||
#[derive(Debug, Clone, Args)]
|
||||
pub struct TranscodeCommandArgs {
|
||||
pub source: String,
|
||||
pub dest: String,
|
||||
|
|
|
@ -23,7 +23,7 @@ use crate::{
|
|||
};
|
||||
|
||||
pub fn copy_command(
|
||||
_args: &CLIArgs,
|
||||
_args: CLIArgs,
|
||||
copy_args: &CopyCommandArgs,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
if copy_args.transcode_config.is_none() && copy_args.transcode_preset.is_none() {
|
||||
|
@ -56,6 +56,7 @@ pub fn copy_command(
|
|||
|
||||
for file in files.iter() {
|
||||
let filename = file.join_filename();
|
||||
|
||||
if let Entry::Vacant(entry) = seen.entry(filename.clone()) {
|
||||
entry.insert(true);
|
||||
} else {
|
||||
|
@ -82,7 +83,7 @@ pub fn copy_command(
|
|||
for directory in directories.iter() {
|
||||
fs::create_dir_all(
|
||||
PathBuf::from_str(copy_args.dest.as_str())
|
||||
.unwrap()
|
||||
.expect("invalid destination")
|
||||
.join(directory),
|
||||
)?;
|
||||
}
|
||||
|
@ -107,14 +108,15 @@ pub fn copy_command(
|
|||
fn copy_file(file: &File, copy_args: &CopyCommandArgs) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let from_path = file.join_path_to();
|
||||
|
||||
let to_path_dest = PathBuf::from_str(copy_args.dest.as_str()).unwrap();
|
||||
let to_path_dest = PathBuf::from_str(copy_args.dest.as_str()).expect("invalid destination");
|
||||
let to_path = match copy_args.single_directory {
|
||||
true => to_path_dest.join(file.join_filename()),
|
||||
false => to_path_dest
|
||||
.join(file.path_from_source.clone())
|
||||
.join(file.join_filename()),
|
||||
};
|
||||
let to_path_string = to_path.as_os_str().to_str().unwrap().to_string();
|
||||
|
||||
let to_path_string = to_path.to_string_lossy();
|
||||
|
||||
if !copy_args.no_skip_existing && to_path.exists() {
|
||||
println!(
|
||||
|
@ -148,7 +150,7 @@ fn copy_files(
|
|||
fn transcode_file(
|
||||
file: &File,
|
||||
copy_args: &CopyCommandArgs,
|
||||
config: TranscodeConfig,
|
||||
config: &TranscodeConfig,
|
||||
is_threaded: bool,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let new_filename_full: String = match config.file_extension.clone() {
|
||||
|
@ -158,14 +160,15 @@ fn transcode_file(
|
|||
}
|
||||
};
|
||||
|
||||
let to_path_dest = PathBuf::from_str(copy_args.dest.as_str()).unwrap();
|
||||
let to_path_dest = PathBuf::from_str(copy_args.dest.as_str()).expect("invalid destination");
|
||||
let to_path = match copy_args.single_directory {
|
||||
true => to_path_dest.join(new_filename_full),
|
||||
false => to_path_dest
|
||||
.join(file.path_from_source.clone())
|
||||
.join(new_filename_full),
|
||||
};
|
||||
let to_path_string = to_path.as_os_str().to_str().unwrap().to_string();
|
||||
|
||||
let to_path_string = to_path.to_string_lossy();
|
||||
|
||||
if !file.extra_files.is_empty() {
|
||||
for extra_file in file.extra_files.iter() {
|
||||
|
@ -178,11 +181,14 @@ fn transcode_file(
|
|||
"Skipping transcode for {} as file already exists",
|
||||
to_path_string
|
||||
);
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
println!("Transcoding {}", to_path_string);
|
||||
transcode(file.to_owned(), to_path_string.clone(), config, None)?;
|
||||
|
||||
transcode(file.to_owned(), to_path_string.to_string(), config, None)?;
|
||||
|
||||
if is_threaded {
|
||||
println!("Finished Transcoding {}", to_path_string);
|
||||
}
|
||||
|
@ -198,41 +204,38 @@ fn transcode_files(
|
|||
copy_args.transcode_preset.as_ref(),
|
||||
copy_args.transcode_config.as_ref(),
|
||||
)
|
||||
.unwrap();
|
||||
.expect("transcode config error");
|
||||
|
||||
if copy_args.threads.is_some() && copy_args.threads.unwrap() > 1 {
|
||||
let threads = copy_args.threads.unwrap_or(1);
|
||||
|
||||
if threads > 1 {
|
||||
let files_copy = files.to_vec();
|
||||
|
||||
let jobs: Arc<Mutex<Vec<File>>> = Arc::new(Mutex::new(files_copy));
|
||||
let copy_args_arc = Arc::new(copy_args);
|
||||
let transcode_config_arc = Arc::new(transcode_config);
|
||||
|
||||
let copy_args = Arc::new(copy_args);
|
||||
let transcode_config = Arc::new(transcode_config);
|
||||
|
||||
scope(|s| {
|
||||
for _ in 0..copy_args.threads.unwrap() {
|
||||
for _ in 0..threads {
|
||||
s.spawn(|| loop {
|
||||
let mut jobs = jobs.lock().unwrap();
|
||||
let job = jobs.pop();
|
||||
if job.is_none() {
|
||||
break;
|
||||
}
|
||||
let job = job.unwrap().clone();
|
||||
drop(jobs);
|
||||
|
||||
let result = transcode_file(
|
||||
&job,
|
||||
©_args_arc,
|
||||
transcode_config_arc.as_ref().clone(),
|
||||
true,
|
||||
);
|
||||
if result.is_err() {
|
||||
panic!("Error Transcoding: {}", result.unwrap_err())
|
||||
let job = jobs.pop();
|
||||
if let Some(job) = job {
|
||||
let result = transcode_file(&job, ©_args, &transcode_config, true);
|
||||
if let Err(err) = result {
|
||||
panic!("Error Transcoding: {}", err)
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
for file in files.iter() {
|
||||
transcode_file(file, copy_args, transcode_config.clone(), false)?;
|
||||
transcode_file(file, copy_args, &transcode_config, false)?;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -10,8 +10,9 @@ use std::io::Write;
|
|||
use html_escape::encode_text;
|
||||
use urlencoding::encode as url_encode;
|
||||
|
||||
fn table_for_files(files: Vec<File>, includes_path: bool, link_base: Option<String>) -> String {
|
||||
fn table_for_files(files: Vec<File>, includes_path: bool, link_base: &Option<String>) -> String {
|
||||
let mut html_content = String::new();
|
||||
|
||||
let mut path_head = String::new();
|
||||
if includes_path {
|
||||
path_head.push_str("<th>Path</th>")
|
||||
|
@ -51,6 +52,7 @@ fn table_for_files(files: Vec<File>, includes_path: bool, link_base: Option<Stri
|
|||
|
||||
let data_title = encode_text(&file.info.tags.title);
|
||||
let data_artist = encode_text(&file.info.tags.artist);
|
||||
|
||||
let format = if let Some(format) = &file.info.format {
|
||||
format.to_string()
|
||||
} else {
|
||||
|
@ -67,17 +69,24 @@ fn table_for_files(files: Vec<File>, includes_path: bool, link_base: Option<Stri
|
|||
}
|
||||
|
||||
let mut url_data = String::new();
|
||||
if link_base.is_some() {
|
||||
if let Some(link_base) = &link_base {
|
||||
let mut url = String::new();
|
||||
let link_base_str = link_base.as_ref().unwrap().clone();
|
||||
url.push_str(link_base_str.as_str());
|
||||
|
||||
url.push_str(link_base.as_str());
|
||||
url.push('/');
|
||||
|
||||
let file_path = file.join_path_from_source();
|
||||
let file_path: Vec<&OsStr> = file_path.iter().collect();
|
||||
|
||||
for i in 0..(file_path.len()) {
|
||||
let file_path_element = file_path.get(i).unwrap();
|
||||
|
||||
url.push_str(
|
||||
url_encode(file_path.get(i).unwrap().to_str().unwrap())
|
||||
url_encode(
|
||||
file_path_element
|
||||
.to_str()
|
||||
.expect("invalid character in filename"),
|
||||
)
|
||||
.to_string()
|
||||
.as_str(),
|
||||
);
|
||||
|
@ -118,7 +127,7 @@ fn table_for_files(files: Vec<File>, includes_path: bool, link_base: Option<Stri
|
|||
}
|
||||
|
||||
pub fn genhtml_command(
|
||||
_args: &CLIArgs,
|
||||
_args: CLIArgs,
|
||||
genhtml_args: &GenHTMLCommandArgs,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
println!("Scanning For Music");
|
||||
|
@ -171,20 +180,18 @@ pub fn genhtml_command(
|
|||
.as_str(),
|
||||
);
|
||||
|
||||
html_content.push_str(&table_for_files(
|
||||
files,
|
||||
true,
|
||||
genhtml_args.link_base.clone(),
|
||||
));
|
||||
html_content.push_str(&table_for_files(files, true, &genhtml_args.link_base));
|
||||
html_content.push_str("</body></html>");
|
||||
|
||||
let file_path = std::path::PathBuf::from(genhtml_args.dest.as_str()).join("index.html");
|
||||
let html_index_file = std::fs::File::create(file_path);
|
||||
|
||||
|
||||
match html_index_file {
|
||||
Ok(mut file) => match file.write_all(html_content.as_bytes()) {
|
||||
Ok(_) => {}
|
||||
Err(e) => {
|
||||
panic!("Could not write html file: {}", e);
|
||||
panic!("Could not write HTML file: {}", e);
|
||||
}
|
||||
},
|
||||
Err(e) => {
|
||||
|
|
|
@ -22,7 +22,7 @@ fn from_main_tags(tags: &crate::types::Tags) -> Tags {
|
|||
}
|
||||
|
||||
pub fn get_tags_command(
|
||||
_args: &CLIArgs,
|
||||
_args: CLIArgs,
|
||||
get_tags_args: &GetTagsCommandArgs,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let mut files: Vec<File> = Vec::new();
|
||||
|
|
|
@ -10,7 +10,7 @@ use crate::utils::formats::get_format_handler;
|
|||
use crate::utils::replaygain::analyze_replaygain;
|
||||
use crate::utils::scan_for_music;
|
||||
|
||||
fn rename_file(_args: &CLIArgs, process_args: &ProcessCommandArgs, file: &mut File) {
|
||||
fn rename_file(process_args: &ProcessCommandArgs, file: &mut File) {
|
||||
let title = &file.info.tags.title;
|
||||
let artist = &file.info.tags.artist;
|
||||
|
||||
|
@ -136,7 +136,7 @@ pub fn add_replaygain_tags(file: &File, force: bool) -> Result<(), Box<dyn std::
|
|||
}
|
||||
|
||||
pub fn process_command(
|
||||
args: &CLIArgs,
|
||||
_args: CLIArgs,
|
||||
process_args: &ProcessCommandArgs,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
println!("Scanning For Music");
|
||||
|
@ -153,40 +153,40 @@ pub fn process_command(
|
|||
|
||||
println!("Renaming Files");
|
||||
for file in files.iter_mut() {
|
||||
rename_file(args, process_args, file);
|
||||
rename_file(process_args, file);
|
||||
}
|
||||
|
||||
if !process_args.skip_replaygain && !process_args.dry_run {
|
||||
println!("Adding ReplayGain Tags to Files");
|
||||
|
||||
if process_args.replaygain_threads.is_some() && process_args.replaygain_threads.unwrap() > 1
|
||||
{
|
||||
let files_copy = files.to_vec();
|
||||
let threads = process_args.replaygain_threads.unwrap_or(0);
|
||||
|
||||
let jobs: Arc<Mutex<Vec<File>>> = Arc::new(Mutex::new(files_copy));
|
||||
|
||||
scope(|s| {
|
||||
for _ in 0..process_args.replaygain_threads.unwrap() {
|
||||
s.spawn(|| loop {
|
||||
let mut jobs = jobs.lock().unwrap();
|
||||
let job = jobs.pop();
|
||||
if job.is_none() {
|
||||
break;
|
||||
}
|
||||
let job = job.unwrap().clone();
|
||||
drop(jobs);
|
||||
|
||||
let result = add_replaygain_tags(&job, process_args.force_replaygain);
|
||||
if result.is_err() {
|
||||
panic!("Error doing replaygain: {}", result.unwrap_err())
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
if threads <= 1 {
|
||||
for file in files.iter_mut() {
|
||||
add_replaygain_tags(file, process_args.force_replaygain)?;
|
||||
}
|
||||
|
||||
return Ok(());
|
||||
} else {
|
||||
let jobs: Arc<Mutex<Vec<File>>> = Arc::new(Mutex::new(files));
|
||||
|
||||
scope(|s| {
|
||||
for _ in 0..threads {
|
||||
s.spawn(|| loop {
|
||||
let mut jobs = jobs.lock().unwrap();
|
||||
|
||||
let job = jobs.pop();
|
||||
if let Some(job) = job {
|
||||
let result = add_replaygain_tags(&job, process_args.force_replaygain);
|
||||
if let Err(err) = result {
|
||||
panic!("Error doing replaygain: {}", err)
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ use crate::types::File;
|
|||
use crate::utils::formats::get_format_handler;
|
||||
|
||||
pub fn set_tags_command(
|
||||
_args: &CLIArgs,
|
||||
_args: CLIArgs,
|
||||
add_tags_args: &SetTagsCommandArgs,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let mut files: Vec<File> = Vec::new();
|
||||
|
|
|
@ -11,13 +11,9 @@ use crate::utils::transcoder::presets::transcode_preset_or_config;
|
|||
use crate::utils::transcoder::transcode;
|
||||
|
||||
pub fn transcode_command(
|
||||
_args: &CLIArgs,
|
||||
_args: CLIArgs,
|
||||
transcode_args: &TranscodeCommandArgs,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
if transcode_args.transcode_config.is_none() && transcode_args.transcode_preset.is_none() {
|
||||
panic!("Please provide Transcode Preset/Config");
|
||||
}
|
||||
|
||||
if let Some(preset) = &transcode_args.transcode_preset {
|
||||
if preset == "list" {
|
||||
print_presets();
|
||||
|
@ -25,19 +21,15 @@ pub fn transcode_command(
|
|||
}
|
||||
}
|
||||
|
||||
println!("Transcoding");
|
||||
let input_file = File::from_path("".to_string(), PathBuf::from(&transcode_args.source));
|
||||
let output_file = File::from_path("".to_string(), PathBuf::from(&transcode_args.dest));
|
||||
|
||||
let transcode_config = transcode_preset_or_config(
|
||||
transcode_args.transcode_preset.as_ref(),
|
||||
transcode_args.transcode_config.as_ref(),
|
||||
);
|
||||
).expect("transcode config error");
|
||||
|
||||
if transcode_config.is_err() {
|
||||
panic!("Please provide Transcode Preset/Config");
|
||||
}
|
||||
let transcode_config = transcode_config.unwrap();
|
||||
println!("Transcoding");
|
||||
|
||||
let input_file = File::from_path("".to_string(), PathBuf::from(&transcode_args.source));
|
||||
let output_file = File::from_path("".to_string(), PathBuf::from(&transcode_args.dest));
|
||||
|
||||
if !transcode_args.ignore_extension {
|
||||
if let Some(ref file_extension) = transcode_config.file_extension {
|
||||
|
@ -69,7 +61,7 @@ pub fn transcode_command(
|
|||
transcode(
|
||||
input_file,
|
||||
transcode_args.dest.clone(),
|
||||
transcode_config,
|
||||
&transcode_config,
|
||||
Some(tx),
|
||||
)?;
|
||||
child.join().expect("oops! the child thread panicked");
|
||||
|
|
45
src/main.rs
45
src/main.rs
|
@ -17,29 +17,26 @@ use commands::transcode::transcode_command;
|
|||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let cli = CLIArgs::parse();
|
||||
|
||||
match cli.command.as_ref() {
|
||||
Some(Commands::Process(process_args)) => {
|
||||
process_command(&cli, process_args)?;
|
||||
}
|
||||
Some(Commands::Genhtml(genhtml_args)) => {
|
||||
genhtml_command(&cli, genhtml_args)?;
|
||||
}
|
||||
Some(Commands::Transcode(transcode_args)) => {
|
||||
transcode_command(&cli, transcode_args)?;
|
||||
}
|
||||
Some(Commands::Copy(copy_args)) => {
|
||||
copy_command(&cli, copy_args)?;
|
||||
}
|
||||
Some(Commands::SetTags(set_tags_args)) => {
|
||||
set_tags_command(&cli, set_tags_args)?;
|
||||
}
|
||||
Some(Commands::GetTags(get_tags_args)) => {
|
||||
get_tags_command(&cli, get_tags_args)?;
|
||||
}
|
||||
None => {
|
||||
panic!("please provide a subcommand");
|
||||
}
|
||||
}
|
||||
let command = cli.command.to_owned();
|
||||
|
||||
Ok(())
|
||||
match command {
|
||||
Commands::Process(process_args) => {
|
||||
return process_command(cli, &process_args);
|
||||
}
|
||||
Commands::Genhtml(genhtml_args) => {
|
||||
return genhtml_command(cli, &genhtml_args);
|
||||
}
|
||||
Commands::Transcode(transcode_args) => {
|
||||
return transcode_command(cli, &transcode_args);
|
||||
}
|
||||
Commands::Copy(copy_args) => {
|
||||
return copy_command(cli, ©_args);
|
||||
}
|
||||
Commands::SetTags(set_tags_args) => {
|
||||
return set_tags_command(cli, &set_tags_args);
|
||||
}
|
||||
Commands::GetTags(get_tags_args) => {
|
||||
return get_tags_command(cli, &get_tags_args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
16
src/types.rs
16
src/types.rs
|
@ -72,22 +72,24 @@ pub struct File {
|
|||
impl File {
|
||||
pub fn from_path(source_dir: String, full_path: PathBuf) -> File {
|
||||
let full_file_path = PathBuf::from(&source_dir).join(full_path);
|
||||
let filename = full_file_path
|
||||
|
||||
let filename_without_extension = full_file_path
|
||||
.file_stem()
|
||||
.unwrap()
|
||||
.to_str()
|
||||
.unwrap()
|
||||
.expect("filename invalid")
|
||||
.to_string_lossy()
|
||||
.to_string();
|
||||
|
||||
let extension = full_file_path.extension();
|
||||
|
||||
let extension = if let Some(extension) = extension {
|
||||
extension.to_str().unwrap().to_string()
|
||||
extension.to_string_lossy().to_string()
|
||||
} else {
|
||||
"".to_string()
|
||||
};
|
||||
|
||||
let path_from_src = full_file_path.strip_prefix(&source_dir).unwrap();
|
||||
let path_from_src = full_file_path
|
||||
.strip_prefix(&source_dir)
|
||||
.expect("couldn't get path relative to source");
|
||||
|
||||
let mut folder_path_from_src = path_from_src.to_path_buf();
|
||||
folder_path_from_src.pop();
|
||||
|
@ -95,7 +97,7 @@ impl File {
|
|||
let path_to = PathBuf::from(&source_dir).join(&folder_path_from_src);
|
||||
|
||||
File {
|
||||
filename,
|
||||
filename: filename_without_extension,
|
||||
extension,
|
||||
path_from_source: folder_path_from_src,
|
||||
path_to,
|
||||
|
|
|
@ -5,16 +5,16 @@ const MAPPINGS_DATA: &str = include_str!("mappings.json");
|
|||
|
||||
lazy_static! {
|
||||
static ref MAPPINGS: HashMap<char, String> = {
|
||||
let data: HashMap<String, String> = serde_json::from_str(MAPPINGS_DATA).unwrap();
|
||||
let data: HashMap<String, String> =
|
||||
serde_json::from_str(MAPPINGS_DATA).expect("mapping data invalid");
|
||||
|
||||
let mut replacement_map: HashMap<char, String> = HashMap::new();
|
||||
for (chr, repl) in &data {
|
||||
match chr.parse::<u32>() {
|
||||
Ok(n) => {
|
||||
let b = char::from_u32(n);
|
||||
if b.is_some() {
|
||||
replacement_map.insert(b.unwrap(), repl.to_string());
|
||||
}
|
||||
let b = char::from_u32(n).expect("invalid char in string");
|
||||
|
||||
replacement_map.insert(b, repl.to_string());
|
||||
}
|
||||
Err(e) => {
|
||||
panic!(
|
||||
|
@ -41,14 +41,9 @@ pub fn reduce_to_ascii(input: String) -> String {
|
|||
continue;
|
||||
}
|
||||
|
||||
match MAPPINGS.get(&c) {
|
||||
Some(replacement) => {
|
||||
if let Some(replacement) = MAPPINGS.get(&c) {
|
||||
output.push_str(replacement);
|
||||
}
|
||||
None => {
|
||||
output.push_str("");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
output
|
||||
|
|
|
@ -43,6 +43,7 @@ impl ToString for FileFormat {
|
|||
|
||||
pub fn detect_ogg_subformat(path: &Path) -> Result<FileFormat, FormatDetectionError> {
|
||||
let file = File::open(path);
|
||||
|
||||
if let Err(_error) = file {
|
||||
return Err(FormatDetectionError::FileReadError);
|
||||
}
|
||||
|
|
|
@ -98,12 +98,12 @@ impl AudioContainerFormat for FLACAudioFormat {
|
|||
&mut self,
|
||||
allow_missing_tags: bool,
|
||||
) -> Result<AudioFileInfo, BoxedError> {
|
||||
return Ok(AudioFileInfo {
|
||||
Ok(AudioFileInfo {
|
||||
tags: self.get_tags(allow_missing_tags)?,
|
||||
contains_replaygain: self.contains_replaygain_tags(),
|
||||
supports_replaygain: self.supports_replaygain(),
|
||||
format: Some(FileFormat::FLAC),
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -165,6 +165,13 @@ impl AudioContainerFormat for GenericFFMpegAudioFormat {
|
|||
}
|
||||
|
||||
fn save_changes(&mut self) -> Result<(), BoxedError> {
|
||||
if self.changes.title.is_none()
|
||||
&& self.changes.artist.is_none()
|
||||
&& self.changes.replaygain_data.is_none()
|
||||
{
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let mut args: Vec<String> = Vec::new();
|
||||
|
||||
let tempdir = tempfile::tempdir()?;
|
||||
|
@ -179,15 +186,18 @@ impl AudioContainerFormat for GenericFFMpegAudioFormat {
|
|||
|
||||
args.extend(vec!["-c".to_string(), "copy".to_string()]);
|
||||
|
||||
if let Some(title) = self.changes.title.clone() {
|
||||
if let Some(title) = &self.changes.title {
|
||||
args.extend(vec![
|
||||
"-metadata".to_string(),
|
||||
format!("title=\"{}\"", title),
|
||||
format!("title=\"{}\"", title.as_str()),
|
||||
])
|
||||
}
|
||||
|
||||
if let Some(artist) = self.changes.artist.clone() {
|
||||
args.extend(vec!["-metadata".to_string(), format!("artist={}", artist)])
|
||||
if let Some(artist) = &self.changes.artist {
|
||||
args.extend(vec![
|
||||
"-metadata".to_string(),
|
||||
format!("artist={}", artist.as_str()),
|
||||
])
|
||||
}
|
||||
|
||||
args.push(temp_file.to_string_lossy().to_string());
|
||||
|
@ -205,12 +215,12 @@ impl AudioContainerFormat for GenericFFMpegAudioFormat {
|
|||
&mut self,
|
||||
allow_missing_tags: bool,
|
||||
) -> Result<AudioFileInfo, BoxedError> {
|
||||
return Ok(AudioFileInfo {
|
||||
Ok(AudioFileInfo {
|
||||
tags: self.get_tags(allow_missing_tags)?,
|
||||
contains_replaygain: self.contains_replaygain_tags(),
|
||||
supports_replaygain: self.supports_replaygain(),
|
||||
format: Some(self.format_type),
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -134,12 +134,12 @@ impl AudioContainerFormat for TaglibAudioFormat {
|
|||
&mut self,
|
||||
allow_missing_tags: bool,
|
||||
) -> Result<AudioFileInfo, BoxedError> {
|
||||
return Ok(AudioFileInfo {
|
||||
Ok(AudioFileInfo {
|
||||
tags: self.get_tags(allow_missing_tags)?,
|
||||
contains_replaygain: self.contains_replaygain_tags(),
|
||||
supports_replaygain: self.supports_replaygain(),
|
||||
format: self.file_format,
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -115,12 +115,12 @@ impl AudioContainerFormat for ID3AudioFormat {
|
|||
&mut self,
|
||||
allow_missing_tags: bool,
|
||||
) -> Result<AudioFileInfo, BoxedError> {
|
||||
return Ok(AudioFileInfo {
|
||||
Ok(AudioFileInfo {
|
||||
tags: self.get_tags(allow_missing_tags)?,
|
||||
supports_replaygain: self.supports_replaygain(),
|
||||
format: Some(FileFormat::MP3),
|
||||
contains_replaygain: self.contains_replaygain_tags(),
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -84,6 +84,7 @@ pub fn get_format_handler(file: &File) -> Result<Box<dyn AudioContainerFormat>,
|
|||
|
||||
fn is_supported_extension(file_path: &Path) -> bool {
|
||||
let ext = file_path.extension();
|
||||
|
||||
if ext.is_none() {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ pub fn find_extra_files(
|
|||
pub fn scan_for_music(src_dir: &String) -> Result<Vec<File>, Box<dyn std::error::Error>> {
|
||||
let mut files: Vec<File> = Vec::new();
|
||||
|
||||
for entry in WalkDir::new(&src_dir) {
|
||||
for entry in WalkDir::new(src_dir) {
|
||||
let entry = entry.unwrap();
|
||||
let entry_path = entry.into_path();
|
||||
if entry_path.is_dir() {
|
||||
|
|
|
@ -84,8 +84,7 @@ pub fn progress_monitor(
|
|||
let mut watcher = RecommendedWatcher::new(
|
||||
tx,
|
||||
notify::Config::default().with_poll_interval(Duration::from_millis(100)),
|
||||
)
|
||||
.expect("could not watch for ffmpeg log progress status");
|
||||
).expect("could not watch for ffmpeg log progress status");
|
||||
|
||||
watcher
|
||||
.watch(&file_path, RecursiveMode::NonRecursive)
|
||||
|
|
|
@ -8,7 +8,7 @@ use super::{progress_monitor, types::TranscodeConfig};
|
|||
pub fn transcode(
|
||||
file: File,
|
||||
dest: String,
|
||||
config: TranscodeConfig,
|
||||
config: &TranscodeConfig,
|
||||
progress_sender: Option<Sender<String>>,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let mut command_args: Vec<String> = Vec::new();
|
||||
|
@ -19,28 +19,28 @@ pub fn transcode(
|
|||
file.join_path_to().to_string_lossy().to_string(),
|
||||
]);
|
||||
|
||||
if let Some(encoder) = config.encoder {
|
||||
command_args.extend(vec!["-c:a".to_string(), encoder]);
|
||||
if let Some(encoder) = &config.encoder {
|
||||
command_args.extend(vec!["-c:a".to_string(), encoder.to_string()]);
|
||||
}
|
||||
|
||||
if let Some(container) = config.container {
|
||||
command_args.extend(vec!["-f".to_string(), container]);
|
||||
if let Some(container) = &config.container {
|
||||
command_args.extend(vec!["-f".to_string(), container.to_string()]);
|
||||
}
|
||||
|
||||
if let Some(sample_rate) = config.sample_rate {
|
||||
command_args.extend(vec!["-ar".to_string(), sample_rate]);
|
||||
if let Some(sample_rate) = &config.sample_rate {
|
||||
command_args.extend(vec!["-ar".to_string(), sample_rate.to_string()]);
|
||||
}
|
||||
|
||||
if let Some(channels) = config.channels {
|
||||
command_args.extend(vec!["-ac".to_string(), channels]);
|
||||
if let Some(channels) = &config.channels {
|
||||
command_args.extend(vec!["-ac".to_string(), channels.to_string()]);
|
||||
}
|
||||
|
||||
if let Some(quality) = config.quality {
|
||||
command_args.extend(vec!["-q:a".to_string(), quality]);
|
||||
if let Some(quality) = &config.quality {
|
||||
command_args.extend(vec!["-q:a".to_string(), quality.to_string()]);
|
||||
}
|
||||
|
||||
if let Some(bitrate) = config.bitrate {
|
||||
command_args.extend(vec!["-b:a".to_string(), bitrate]);
|
||||
if let Some(bitrate) = &config.bitrate {
|
||||
command_args.extend(vec!["-b:a".to_string(), bitrate.to_string()]);
|
||||
}
|
||||
|
||||
command_args.push(dest);
|
||||
|
@ -48,9 +48,9 @@ pub fn transcode(
|
|||
let mut progress_thread: Option<JoinHandle<()>> = None;
|
||||
let mut progress_file: Option<String> = None;
|
||||
|
||||
if progress_sender.is_some() {
|
||||
let sender = progress_sender.as_ref().unwrap();
|
||||
if let Some(sender) = &progress_sender {
|
||||
let result = progress_monitor(file.join_path_to(), sender);
|
||||
|
||||
if let Ok(result) = result {
|
||||
progress_thread = Some(result.1);
|
||||
progress_file = Some(result.0.clone());
|
||||
|
|
Loading…
Reference in a new issue