fix: formatting touch ups and timeout adjustment

This commit is contained in:
talwat 2025-08-10 00:27:37 +02:00
parent 6f15f9226f
commit 3e0cbf9871
4 changed files with 43 additions and 10 deletions

1
Cargo.lock generated
View File

@ -1467,6 +1467,7 @@ dependencies = [
"libc",
"mpris-server",
"rand",
"regex",
"reqwest",
"rodio",
"scraper",

View File

@ -56,6 +56,7 @@ serde_json = { version = "1.0.142", optional = true }
scraper = { version = "0.21.0", optional = true }
html-escape = { version = "0.2.13", optional = true }
indicatif = { version = "0.18.0", optional = true }
regex = "1.11.1"
[target.'cfg(target_os = "linux")'.dependencies]
libc = "0.2.167"

View File

@ -42,7 +42,7 @@ pub mod mpris;
/// The time to wait in between errors.
/// TODO: Make this configurable.
const TIMEOUT: Duration = Duration::from_secs(5);
const TIMEOUT: Duration = Duration::from_secs(3);
/// Main struct responsible for queuing up & playing tracks.
// TODO: Consider refactoring [Player] from being stored in an [Arc], into containing many smaller [Arc]s.
@ -139,7 +139,7 @@ impl Player {
"/",
env!("CARGO_PKG_VERSION")
))
.timeout(TIMEOUT)
.timeout(TIMEOUT * 2)
.build()?;
let player = Self {

View File

@ -19,6 +19,7 @@ use std::{io::Cursor, path::Path, time::Duration};
use bytes::Bytes;
use inflector::Inflector as _;
use regex::Regex;
use rodio::{Decoder, Source as _};
use unicode_segmentation::UnicodeSegmentation;
use url::form_urlencoded;
@ -29,6 +30,7 @@ pub mod list;
pub use error::Error;
use crate::tracks::error::Context;
use lazy_static::lazy_static;
/// Just a shorthand for a decoded [Bytes].
pub type DecodedData = Decoder<Cursor<Bytes>>;
@ -95,6 +97,21 @@ pub struct Info {
pub duration: Option<Duration>,
}
lazy_static! {
static ref MASTER_PATTERNS: [Regex; 5] = [
// (master), (master v3), (kupla master), (kupla master2)
Regex::new(r"\s*\(.*?master(?:\s*v?\d+)?\)$").unwrap(),
// mstr or - mstr or (mstr) — now also matches "mstr v3", "mstr2", etc.
Regex::new(r"\s*[-(]?\s*mstr(?:\s*v?\d+)?\s*\)?$").unwrap(),
// - master, master at end without parentheses
Regex::new(r"\s*[-]?\s*master(?:\s*v?\d+)?$").unwrap(),
// kupla master1, kupla master v2 (without parentheses or separator)
Regex::new(r"\s+kupla\s+master(?:\s*v?\d+|\d+)?$").unwrap(),
// (kupla master) followed by trailing parenthetical numbers, e.g. "... (kupla master) (1)"
Regex::new(r"\s*\(.*?master(?:\s*v?\d+)?\)(?:\s*\(\d+\))+$").unwrap(),
];
}
impl Info {
/// Decodes a URL string into normal UTF-8.
fn decode_url(text: &str) -> String {
@ -106,17 +123,30 @@ impl Info {
}
/// Formats a name with [Inflector].
///
/// This will also strip the first few numbers that are
/// usually present on most lofi tracks.
/// usually present on most lofi tracks and do some other
/// formatting operations.
fn format_name(name: &str) -> eyre::Result<String, Error> {
let path = Path::new(name);
let stem = path
let name = path
.file_stem()
.and_then(|x| x.to_str())
.ok_or((name, error::Kind::InvalidName))?;
let formatted = Self::decode_url(stem)
.to_lowercase()
let name = Self::decode_url(name).to_lowercase();
let mut name = name
.replace("masster", "master")
.replace("(online-audio-converter.com)", ""); // Some of these names, man...
// Get rid of "master" suffix with a few regex patterns.
for regex in MASTER_PATTERNS.iter() {
name = regex.replace(&name, "").to_string();
}
let name = name
.trim_end_matches("13lufs")
.to_title_case()
// Inflector doesn't like contractions...
// Replaces a few very common ones.
@ -128,11 +158,12 @@ impl Info {
.replace(" Ll ", "'ll ")
.replace(" Re ", "'re ")
.replace(" M ", "'m ");
let name = name.trim();
// This is incremented for each digit in front of the song name.
let mut skip = 0;
for character in formatted.as_bytes() {
for character in name.as_bytes() {
if character.is_ascii_digit() {
skip += 1;
} else {
@ -141,12 +172,12 @@ impl Info {
}
// If the entire name of the track is a number, then just return it.
if skip == formatted.len() {
Ok(formatted)
if skip == name.len() {
Ok(name.to_string())
} else {
// We've already checked before that the bound is at an ASCII digit.
#[allow(clippy::string_slice)]
Ok(String::from(&formatted[skip..]))
Ok(String::from(&name[skip..]))
}
}