mirror of
https://github.com/talwat/lowfi
synced 2024-12-27 11:41:54 +00:00
feat: extend scrape command options
This commit is contained in:
parent
2102564d04
commit
233b552343
17
src/main.rs
17
src/main.rs
@ -15,8 +15,16 @@ struct Args {
|
|||||||
|
|
||||||
#[derive(Subcommand)]
|
#[derive(Subcommand)]
|
||||||
enum Commands {
|
enum Commands {
|
||||||
/// Scrapes the lofi girl website file server for mp3 files.
|
/// Scrapes the lofi girl website file server for files.
|
||||||
Scrape,
|
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.
|
/// Starts the player.
|
||||||
Play,
|
Play,
|
||||||
}
|
}
|
||||||
@ -26,7 +34,10 @@ async fn main() -> eyre::Result<()> {
|
|||||||
let cli = Args::parse();
|
let cli = Args::parse();
|
||||||
|
|
||||||
match cli.command {
|
match cli.command {
|
||||||
Commands::Scrape => scrape::scrape().await,
|
Commands::Scrape {
|
||||||
|
extention,
|
||||||
|
include_full,
|
||||||
|
} => scrape::scrape(extention, include_full).await,
|
||||||
Commands::Play => play::play().await,
|
Commands::Play => play::play().await,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ use std::{collections::VecDeque, sync::Arc};
|
|||||||
|
|
||||||
use arc_swap::ArcSwapOption;
|
use arc_swap::ArcSwapOption;
|
||||||
use reqwest::Client;
|
use reqwest::Client;
|
||||||
use rodio::{Decoder, OutputStream, OutputStreamHandle, Sink};
|
use rodio::{OutputStream, OutputStreamHandle, Sink};
|
||||||
use tokio::{
|
use tokio::{
|
||||||
select,
|
select,
|
||||||
sync::{
|
sync::{
|
||||||
|
@ -3,12 +3,13 @@ use std::sync::LazyLock;
|
|||||||
use futures::{stream::FuturesUnordered, StreamExt};
|
use futures::{stream::FuturesUnordered, StreamExt};
|
||||||
use scraper::{Html, Selector};
|
use scraper::{Html, Selector};
|
||||||
|
|
||||||
|
const BASE_URL: &'static str = "https://lofigirl.com/wp-content/uploads/";
|
||||||
|
|
||||||
static SELECTOR: LazyLock<Selector> =
|
static SELECTOR: LazyLock<Selector> =
|
||||||
LazyLock::new(|| Selector::parse("html > body > pre > a").unwrap());
|
LazyLock::new(|| Selector::parse("html > body > pre > a").unwrap());
|
||||||
|
|
||||||
async fn parse(path: &str) -> eyre::Result<Vec<String>> {
|
async fn parse(path: &str) -> eyre::Result<Vec<String>> {
|
||||||
let response =
|
let response = reqwest::get(format!("{}{}", BASE_URL, path)).await?;
|
||||||
reqwest::get(format!("https://lofigirl.com/wp-content/uploads/{}", path)).await?;
|
|
||||||
let document = response.text().await?;
|
let document = response.text().await?;
|
||||||
|
|
||||||
let html = Html::parse_document(&document);
|
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.
|
/// 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.
|
/// 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 items = parse("").await?;
|
||||||
|
|
||||||
let years: Vec<u32> = items
|
let years: Vec<u32> = items
|
||||||
@ -48,8 +51,12 @@ async fn scan() -> eyre::Result<Vec<String>> {
|
|||||||
let items = items
|
let items = items
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter_map(|x| {
|
.filter_map(|x| {
|
||||||
if x.ends_with(".mp3") {
|
if x.ends_with(extention) {
|
||||||
Some(format!("{path}{x}"))
|
if include_full {
|
||||||
|
Some(format!("{BASE_URL}{path}{x}"))
|
||||||
|
} else {
|
||||||
|
Some(format!("{path}{x}"))
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
@ -69,8 +76,8 @@ async fn scan() -> eyre::Result<Vec<String>> {
|
|||||||
eyre::Result::Ok(files)
|
eyre::Result::Ok(files)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn scrape() -> eyre::Result<()> {
|
pub async fn scrape(extention: String, include_full: bool) -> eyre::Result<()> {
|
||||||
let files = scan().await?;
|
let files = scan(&extention, include_full).await?;
|
||||||
for file in files {
|
for file in files {
|
||||||
println!("{}", file);
|
println!("{}", 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 struct Track {
|
||||||
pub info: TrackInfo,
|
pub info: TrackInfo,
|
||||||
pub data: Data,
|
pub data: Data,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Track {
|
impl Track {
|
||||||
|
/// Fetches, downloads, and decodes a random track from the tracklist.
|
||||||
pub async fn random(client: &Client) -> eyre::Result<Self> {
|
pub async fn random(client: &Client) -> eyre::Result<Self> {
|
||||||
let name = random().await?;
|
let name = random().await?;
|
||||||
let data = download(&name, client).await?;
|
let data = download(&name, client).await?;
|
||||||
|
Loading…
Reference in New Issue
Block a user