lpkg/src/mirrors.rs

68 lines
2 KiB
Rust
Raw Normal View History

2025-09-30 16:51:03 +02:00
use console::Style;
2025-09-30 17:08:26 +02:00
use reqwest::blocking::Client;
use scraper::{Html, Selector};
2025-09-30 16:51:03 +02:00
use std::io::{self, Write};
2025-09-30 20:38:13 +02:00
pub fn fetch_mirrors() -> Result<Vec<String>, Box<dyn std::error::Error>> {
let client = Client::new();
let res = client
.get("https://www.linuxfromscratch.org/lfs/mirrors.html#files")
.send()?
.text()?;
let document = Html::parse_document(&res);
let selector = Selector::parse("a[href^='http']").unwrap();
let mirrors = document
.select(&selector)
.filter_map(|element| {
let href = element.value().attr("href")?;
// Basic filtering to get potential mirror URLs
if href.contains("ftp.gnu.org") || href.contains("mirror") {
Some(href.to_string())
} else {
None
}
})
.collect();
Ok(mirrors)
}
2025-09-30 16:51:03 +02:00
pub fn choose_package_mirror() -> Option<String> {
2025-09-30 17:08:26 +02:00
let mirrors = match fetch_mirrors() {
Ok(mirrors) => mirrors,
Err(e) => {
println!("Failed to fetch mirrors: {}", e);
// Fallback to a default list if fetching fails
2025-09-30 17:12:09 +02:00
vec![
"ftp.fau.de".to_string(),
"mirror.kernel.org".to_string(),
"mirror.example.org".to_string(),
]
2025-09-30 17:08:26 +02:00
}
};
2025-09-30 16:51:03 +02:00
println!("Optional: choose a mirror for GNU source packages (replace ftp.gnu.org):");
for (i, mirror) in mirrors.iter().enumerate() {
println!(" [{}] {}", i + 1, mirror);
}
print!("Enter number or press Enter for default: ");
io::stdout().flush().unwrap();
let mut input = String::new();
io::stdin().read_line(&mut input).unwrap();
let input = input.trim();
if input.is_empty() {
None
} else {
let choice = input.parse::<usize>().unwrap_or(1);
let chosen = mirrors.get(choice.saturating_sub(1)).unwrap_or(&mirrors[0]);
println!(
"Using package mirror: {}",
Style::new().green().apply_to(chosen)
);
Some(chosen.to_string())
}
}