mirror of
https://github.com/talwat/lowfi
synced 2025-08-15 14:04:04 +00:00
fix: formatting touch ups and timeout adjustment
This commit is contained in:
parent
6f15f9226f
commit
3e0cbf9871
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -1467,6 +1467,7 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
"mpris-server",
|
"mpris-server",
|
||||||
"rand",
|
"rand",
|
||||||
|
"regex",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"rodio",
|
"rodio",
|
||||||
"scraper",
|
"scraper",
|
||||||
|
@ -56,6 +56,7 @@ serde_json = { version = "1.0.142", optional = true }
|
|||||||
scraper = { version = "0.21.0", optional = true }
|
scraper = { version = "0.21.0", optional = true }
|
||||||
html-escape = { version = "0.2.13", optional = true }
|
html-escape = { version = "0.2.13", optional = true }
|
||||||
indicatif = { version = "0.18.0", optional = true }
|
indicatif = { version = "0.18.0", optional = true }
|
||||||
|
regex = "1.11.1"
|
||||||
|
|
||||||
[target.'cfg(target_os = "linux")'.dependencies]
|
[target.'cfg(target_os = "linux")'.dependencies]
|
||||||
libc = "0.2.167"
|
libc = "0.2.167"
|
||||||
|
@ -42,7 +42,7 @@ pub mod mpris;
|
|||||||
|
|
||||||
/// The time to wait in between errors.
|
/// The time to wait in between errors.
|
||||||
/// TODO: Make this configurable.
|
/// 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.
|
/// Main struct responsible for queuing up & playing tracks.
|
||||||
// TODO: Consider refactoring [Player] from being stored in an [Arc], into containing many smaller [Arc]s.
|
// 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")
|
env!("CARGO_PKG_VERSION")
|
||||||
))
|
))
|
||||||
.timeout(TIMEOUT)
|
.timeout(TIMEOUT * 2)
|
||||||
.build()?;
|
.build()?;
|
||||||
|
|
||||||
let player = Self {
|
let player = Self {
|
||||||
|
@ -19,6 +19,7 @@ use std::{io::Cursor, path::Path, time::Duration};
|
|||||||
|
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use inflector::Inflector as _;
|
use inflector::Inflector as _;
|
||||||
|
use regex::Regex;
|
||||||
use rodio::{Decoder, Source as _};
|
use rodio::{Decoder, Source as _};
|
||||||
use unicode_segmentation::UnicodeSegmentation;
|
use unicode_segmentation::UnicodeSegmentation;
|
||||||
use url::form_urlencoded;
|
use url::form_urlencoded;
|
||||||
@ -29,6 +30,7 @@ pub mod list;
|
|||||||
pub use error::Error;
|
pub use error::Error;
|
||||||
|
|
||||||
use crate::tracks::error::Context;
|
use crate::tracks::error::Context;
|
||||||
|
use lazy_static::lazy_static;
|
||||||
|
|
||||||
/// Just a shorthand for a decoded [Bytes].
|
/// Just a shorthand for a decoded [Bytes].
|
||||||
pub type DecodedData = Decoder<Cursor<Bytes>>;
|
pub type DecodedData = Decoder<Cursor<Bytes>>;
|
||||||
@ -95,6 +97,21 @@ pub struct Info {
|
|||||||
pub duration: Option<Duration>,
|
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 {
|
impl Info {
|
||||||
/// Decodes a URL string into normal UTF-8.
|
/// Decodes a URL string into normal UTF-8.
|
||||||
fn decode_url(text: &str) -> String {
|
fn decode_url(text: &str) -> String {
|
||||||
@ -106,17 +123,30 @@ impl Info {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Formats a name with [Inflector].
|
/// Formats a name with [Inflector].
|
||||||
|
///
|
||||||
/// This will also strip the first few numbers that are
|
/// 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> {
|
fn format_name(name: &str) -> eyre::Result<String, Error> {
|
||||||
let path = Path::new(name);
|
let path = Path::new(name);
|
||||||
|
|
||||||
let stem = path
|
let name = path
|
||||||
.file_stem()
|
.file_stem()
|
||||||
.and_then(|x| x.to_str())
|
.and_then(|x| x.to_str())
|
||||||
.ok_or((name, error::Kind::InvalidName))?;
|
.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()
|
.to_title_case()
|
||||||
// Inflector doesn't like contractions...
|
// Inflector doesn't like contractions...
|
||||||
// Replaces a few very common ones.
|
// Replaces a few very common ones.
|
||||||
@ -128,11 +158,12 @@ impl Info {
|
|||||||
.replace(" Ll ", "'ll ")
|
.replace(" Ll ", "'ll ")
|
||||||
.replace(" Re ", "'re ")
|
.replace(" Re ", "'re ")
|
||||||
.replace(" M ", "'m ");
|
.replace(" M ", "'m ");
|
||||||
|
let name = name.trim();
|
||||||
|
|
||||||
// This is incremented for each digit in front of the song name.
|
// This is incremented for each digit in front of the song name.
|
||||||
let mut skip = 0;
|
let mut skip = 0;
|
||||||
|
|
||||||
for character in formatted.as_bytes() {
|
for character in name.as_bytes() {
|
||||||
if character.is_ascii_digit() {
|
if character.is_ascii_digit() {
|
||||||
skip += 1;
|
skip += 1;
|
||||||
} else {
|
} else {
|
||||||
@ -141,12 +172,12 @@ impl Info {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If the entire name of the track is a number, then just return it.
|
// If the entire name of the track is a number, then just return it.
|
||||||
if skip == formatted.len() {
|
if skip == name.len() {
|
||||||
Ok(formatted)
|
Ok(name.to_string())
|
||||||
} else {
|
} else {
|
||||||
// We've already checked before that the bound is at an ASCII digit.
|
// We've already checked before that the bound is at an ASCII digit.
|
||||||
#[allow(clippy::string_slice)]
|
#[allow(clippy::string_slice)]
|
||||||
Ok(String::from(&formatted[skip..]))
|
Ok(String::from(&name[skip..]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user