2022-08-16 09:05:18 +01:00
|
|
|
use crate::args::CLIArgs;
|
|
|
|
use crate::args::GenHTMLCommandArgs;
|
|
|
|
use crate::types::File;
|
2023-01-08 10:24:44 +00:00
|
|
|
use crate::utils::formats::get_format_handler;
|
2022-10-22 21:01:36 +01:00
|
|
|
use crate::utils::scan_for_music;
|
2022-10-22 14:16:02 +01:00
|
|
|
use std::cmp::Ordering;
|
2022-08-16 09:05:18 +01:00
|
|
|
use std::io::Write;
|
|
|
|
|
|
|
|
use html_escape::encode_text;
|
|
|
|
|
|
|
|
fn table_for_files(files: Vec<File>, includes_path: bool) -> String {
|
|
|
|
let mut html_content = String::new();
|
|
|
|
let mut path_head = String::new();
|
|
|
|
if includes_path {
|
|
|
|
path_head.push_str("<th>Path</th>")
|
|
|
|
}
|
|
|
|
|
|
|
|
html_content.push_str(
|
|
|
|
format!(
|
|
|
|
"
|
|
|
|
<table class=\"pure-table pure-table-horizontal\">
|
|
|
|
<thead>
|
|
|
|
<tr>
|
|
|
|
{}
|
|
|
|
<th>Title</th>
|
|
|
|
<th>Artist</th>
|
|
|
|
<th>Format</th>
|
|
|
|
</tr>
|
|
|
|
</thead>
|
|
|
|
<tbody>
|
|
|
|
",
|
|
|
|
path_head
|
|
|
|
)
|
|
|
|
.as_str(),
|
|
|
|
);
|
|
|
|
|
|
|
|
let mut is_odd = true;
|
|
|
|
for file in files.iter() {
|
|
|
|
let td_class = match is_odd {
|
|
|
|
true => "pure-table-odd",
|
|
|
|
false => "pure-table-even",
|
|
|
|
};
|
|
|
|
|
2023-01-08 10:24:44 +00:00
|
|
|
let data_title = encode_text(&file.info.tags.title);
|
|
|
|
let data_artist = encode_text(&file.info.tags.artist);
|
2022-08-16 09:05:18 +01:00
|
|
|
let data_extension = encode_text(&file.extension);
|
|
|
|
|
|
|
|
let mut path_data = String::new();
|
|
|
|
if includes_path {
|
2022-10-22 14:16:02 +01:00
|
|
|
let file_directory = file.path_from_source.to_string_lossy().to_string();
|
|
|
|
|
|
|
|
path_data.push_str(format!("<td>{}</td>", encode_text(&file_directory)).as_str());
|
2022-08-16 09:05:18 +01:00
|
|
|
}
|
|
|
|
html_content.push_str(
|
|
|
|
format!(
|
|
|
|
"
|
|
|
|
<tr class=\"{}\">
|
|
|
|
{}
|
|
|
|
<td>{}</td>
|
|
|
|
<td>{}</td>
|
|
|
|
<td>{}</td>
|
|
|
|
</tr>
|
|
|
|
",
|
|
|
|
td_class, path_data, data_title, data_artist, data_extension
|
|
|
|
)
|
|
|
|
.as_str(),
|
|
|
|
);
|
|
|
|
is_odd = !is_odd;
|
|
|
|
}
|
|
|
|
|
|
|
|
html_content.push_str(
|
|
|
|
"
|
|
|
|
</tbody>
|
|
|
|
</table>
|
|
|
|
",
|
|
|
|
);
|
2022-10-22 14:16:02 +01:00
|
|
|
|
|
|
|
html_content
|
2022-08-16 09:05:18 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn genhtml_command(
|
|
|
|
_args: &CLIArgs,
|
|
|
|
genhtml_args: &GenHTMLCommandArgs,
|
|
|
|
) -> Result<(), Box<dyn std::error::Error>> {
|
|
|
|
println!("Scanning For Music");
|
|
|
|
let mut files = scan_for_music(&genhtml_args.source)?;
|
|
|
|
|
2023-01-08 10:24:44 +00:00
|
|
|
println!("Analysing Files");
|
2022-08-16 09:05:18 +01:00
|
|
|
for file in files.iter_mut() {
|
2023-01-08 10:24:44 +00:00
|
|
|
println!("Analysing: {:?}", file.join_path_from_source());
|
2022-08-16 09:05:18 +01:00
|
|
|
|
2023-01-08 10:24:44 +00:00
|
|
|
let handler = get_format_handler(file)?;
|
|
|
|
|
|
|
|
file.info = handler.get_audio_file_info(false)?;
|
2022-08-16 09:05:18 +01:00
|
|
|
}
|
|
|
|
|
2022-10-22 14:16:02 +01:00
|
|
|
files.sort_by(|a, b| -> Ordering {
|
2022-08-16 09:05:18 +01:00
|
|
|
if a.path_from_source != b.path_from_source {
|
|
|
|
return a.path_from_source.cmp(&b.path_from_source);
|
|
|
|
}
|
2023-01-08 10:24:44 +00:00
|
|
|
|
|
|
|
let a_tags = &a.info.tags;
|
|
|
|
let b_tags = &b.info.tags;
|
|
|
|
|
|
|
|
if a_tags.title != b_tags.title {
|
|
|
|
return a_tags.title.cmp(&b_tags.title);
|
2022-08-16 09:05:18 +01:00
|
|
|
}
|
2022-10-22 21:01:36 +01:00
|
|
|
|
2023-01-08 10:24:44 +00:00
|
|
|
a_tags.artist.cmp(&b_tags.artist)
|
2022-08-16 09:05:18 +01:00
|
|
|
});
|
|
|
|
|
|
|
|
let mut html_content = String::new();
|
|
|
|
html_content.push_str(
|
|
|
|
format!(
|
|
|
|
"
|
|
|
|
<!DOCTYPE HTML>
|
|
|
|
<html>
|
|
|
|
<head>
|
|
|
|
<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">
|
|
|
|
<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">
|
|
|
|
<link rel=\"stylesheet\" href=\"https://unpkg.com/purecss@2.0.6/build/pure-min.css\">
|
|
|
|
<title>{}</title>
|
|
|
|
<meta property=\"og:title\" content=\"{}\" />
|
|
|
|
<meta property=\"og:description\" content=\"{}\" />
|
|
|
|
</head>
|
|
|
|
<body>
|
|
|
|
",
|
|
|
|
encode_text(&genhtml_args.title),
|
|
|
|
encode_text(&genhtml_args.title),
|
|
|
|
encode_text(&genhtml_args.description)
|
|
|
|
)
|
|
|
|
.as_str(),
|
|
|
|
);
|
|
|
|
|
|
|
|
html_content.push_str(&table_for_files(files, true));
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
Err(e) => {
|
|
|
|
panic!("Could not create HTML file: {}", e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-10-22 14:16:02 +01:00
|
|
|
Ok(())
|
2022-08-16 09:05:18 +01:00
|
|
|
}
|