feat: extend scrape command options

This commit is contained in:
talwat 2024-09-25 23:54:55 +02:00
parent 2102564d04
commit 233b552343
4 changed files with 32 additions and 11 deletions

View File

@ -15,8 +15,16 @@ struct Args {
#[derive(Subcommand)]
enum Commands {
/// Scrapes the lofi girl website file server for mp3 files.
Scrape,
/// Scrapes the lofi girl website file server for files.
Scrape {
/// The file extention to search for, defaults to mp3.
#[clap(long, short, default_value = "mp3")]
extention: String,
/// Whether to include the full HTTP URL or just the distinguishing part.
#[clap(long, short)]
include_full: bool,
},
/// Starts the player.
Play,
}
@ -26,7 +34,10 @@ async fn main() -> eyre::Result<()> {
let cli = Args::parse();
match cli.command {
Commands::Scrape => scrape::scrape().await,
Commands::Scrape {
extention,
include_full,
} => scrape::scrape(extention, include_full).await,
Commands::Play => play::play().await,
}
}

View File

@ -2,7 +2,7 @@ use std::{collections::VecDeque, sync::Arc};
use arc_swap::ArcSwapOption;
use reqwest::Client;
use rodio::{Decoder, OutputStream, OutputStreamHandle, Sink};
use rodio::{OutputStream, OutputStreamHandle, Sink};
use tokio::{
select,
sync::{

View File

@ -3,12 +3,13 @@ use std::sync::LazyLock;
use futures::{stream::FuturesUnordered, StreamExt};
use scraper::{Html, Selector};
const BASE_URL: &'static str = "https://lofigirl.com/wp-content/uploads/";
static SELECTOR: LazyLock<Selector> =
LazyLock::new(|| Selector::parse("html > body > pre > a").unwrap());
async fn parse(path: &str) -> eyre::Result<Vec<String>> {
let response =
reqwest::get(format!("https://lofigirl.com/wp-content/uploads/{}", path)).await?;
let response = reqwest::get(format!("{}{}", BASE_URL, path)).await?;
let document = response.text().await?;
let html = Html::parse_document(&document);
@ -23,7 +24,9 @@ async fn parse(path: &str) -> eyre::Result<Vec<String>> {
///
/// It's a bit hacky, and basically works by checking all of the years, then months, and then all of the files.
/// This is done as a way to avoid recursion, since async rust really hates recursive functions.
async fn scan() -> eyre::Result<Vec<String>> {
async fn scan(extention: &str, include_full: bool) -> eyre::Result<Vec<String>> {
let extention = &format!(".{}", extention);
let items = parse("").await?;
let years: Vec<u32> = items
@ -48,8 +51,12 @@ async fn scan() -> eyre::Result<Vec<String>> {
let items = items
.into_iter()
.filter_map(|x| {
if x.ends_with(".mp3") {
if x.ends_with(extention) {
if include_full {
Some(format!("{BASE_URL}{path}{x}"))
} else {
Some(format!("{path}{x}"))
}
} else {
None
}
@ -69,8 +76,8 @@ async fn scan() -> eyre::Result<Vec<String>> {
eyre::Result::Ok(files)
}
pub async fn scrape() -> eyre::Result<()> {
let files = scan().await?;
pub async fn scrape(extention: String, include_full: bool) -> eyre::Result<()> {
let files = scan(&extention, include_full).await?;
for file in files {
println!("{}", file);
}

View File

@ -38,12 +38,15 @@ impl TrackInfo {
}
}
/// The main track struct, which includes the actual decoded file
/// as well as some basic information about it.
pub struct Track {
pub info: TrackInfo,
pub data: Data,
}
impl Track {
/// Fetches, downloads, and decodes a random track from the tracklist.
pub async fn random(client: &Client) -> eyre::Result<Self> {
let name = random().await?;
let data = download(&name, client).await?;