Improve web UI
This commit is contained in:
@@ -137,28 +137,29 @@ fn extract_tags(
|
||||
cover: &mut Option<(Vec<u8>, String)>,
|
||||
) {
|
||||
for tag in tags {
|
||||
let value = fix_encoding(tag.value.to_string());
|
||||
if let Some(key) = tag.std_key {
|
||||
match key {
|
||||
StandardTagKey::TrackTitle => {
|
||||
*title = Some(tag.value.to_string());
|
||||
*title = Some(value);
|
||||
}
|
||||
StandardTagKey::Artist | StandardTagKey::Performer => {
|
||||
if artist.is_none() {
|
||||
*artist = Some(tag.value.to_string());
|
||||
*artist = Some(value);
|
||||
}
|
||||
}
|
||||
StandardTagKey::Album => {
|
||||
*album = Some(tag.value.to_string());
|
||||
*album = Some(value);
|
||||
}
|
||||
StandardTagKey::TrackNumber => {
|
||||
if track.is_none() {
|
||||
*track = tag.value.to_string().parse().ok();
|
||||
*track = value.parse().ok();
|
||||
}
|
||||
}
|
||||
StandardTagKey::Date | StandardTagKey::OriginalDate => {
|
||||
if year.is_none() {
|
||||
// Parse first 4 characters as year
|
||||
*year = tag.value.to_string()[..4.min(tag.value.to_string().len())].parse().ok();
|
||||
*year = value[..4.min(value.len())].parse().ok();
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
@@ -173,3 +174,31 @@ fn extract_tags(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Heuristic to fix mojibake (CP1251 bytes interpreted as Latin-1/Windows-1252)
|
||||
fn fix_encoding(s: String) -> String {
|
||||
// If it's already a valid UTF-8 string that doesn't look like mojibake, return it.
|
||||
// Mojibake looks like characters from Latin-1 Supplement (0xC0-0xFF)
|
||||
// where they should be Cyrillic.
|
||||
|
||||
let bytes: Vec<u8> = s.chars().map(|c| c as u32).filter(|&c| c <= 255).map(|c| c as u8).collect();
|
||||
|
||||
// If the length is different, it means there were characters > 255, so it's not simple Latin-1 mojibake.
|
||||
if bytes.len() != s.chars().count() {
|
||||
return s;
|
||||
}
|
||||
|
||||
// Check if it's likely CP1251. Russian characters in CP1251 are 0xC0-0xFF.
|
||||
// In Latin-1 these are characters like À-ÿ.
|
||||
let has_mojibake = bytes.iter().any(|&b| b >= 0xC0);
|
||||
if !has_mojibake {
|
||||
return s;
|
||||
}
|
||||
|
||||
let (decoded, _, errors) = encoding_rs::WINDOWS_1251.decode(&bytes);
|
||||
if errors {
|
||||
return s;
|
||||
}
|
||||
|
||||
decoded.into_owned()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user