Skip to content

Commit

Permalink
Loop to selection list when pressing q while playing (#23)
Browse files Browse the repository at this point in the history
* Loop to selection list when pressing q while playing

* Cache station list loaded from internet

* Allow disabling the station cache with a flag

* Fix typo in informational message
  • Loading branch information
hannesbraun authored Aug 12, 2023
1 parent 801dc16 commit d61b80f
Show file tree
Hide file tree
Showing 7 changed files with 167 additions and 117 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
authors = ["Marcos Gutiérrez Alonso <margual56@gmail.com>"]
description = "A simple radio cli for listening to your favourite streams from the console"
name = "radio-cli"
version = "2.2.1"
version = "2.3.0"
edition = "2021"
homepage = "https://github.com/margual56/radio-cli"
repository = "https://github.com/margual56/radio-cli"
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ The license is GPLv2
Don't be surprised if these are not implemented in the end hehe (if there is no interest in the project, certainly not)

- [x] ~Audio (mpv) controls when not in verbose mode~
- [ ] Loop to selection list when pressing `q` while playing
- [x] Loop to selection list when pressing `q` while playing
- [x] ~Some kind of online updating of the list of stations~ _(kind of)_
- [x] ~Code optimizations/beautification~
- [x] ~Search international online radios~
Expand Down
59 changes: 35 additions & 24 deletions src/lib/browser.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
use std::error::Error;
use std::rc::Rc;

use crate::{station::Station, Config};
use inquire::{error::InquireError, Autocomplete, Text};
use radiobrowser::{blocking::RadioBrowserAPI, ApiCountry, ApiStation, StationOrder};

pub type StationCache = Rc<Vec<ApiStation>>;

#[derive(Debug, Clone)]
pub struct Stations {
stations: Vec<ApiStation>,
stations: StationCache,
}

impl Autocomplete for Stations {
Expand Down Expand Up @@ -39,39 +42,47 @@ impl Autocomplete for Stations {

pub struct Browser {
api: RadioBrowserAPI,
config: Config,
stations: Vec<ApiStation>,
config: Rc<Config>,
stations: StationCache,
}

impl Browser {
pub fn new(config: Config) -> Result<Browser, Box<dyn Error>> {
pub fn new(
config: Rc<Config>,
cached_stations: Option<StationCache>,
) -> Result<(Browser, StationCache), Box<dyn Error>> {
let api = match RadioBrowserAPI::new() {
Ok(r) => r,
Err(e) => return Err(e),
};

let stations = if let Some(code) = &config.country_code {
match api
.get_stations()
.countrycode(code)
.order(StationOrder::Clickcount)
.send()
{
Ok(s) => s,
Err(_e) => Vec::new(),
}
} else {
match api.get_stations().order(StationOrder::Clickcount).send() {
Ok(s) => s,
Err(_e) => Vec::new(),
}
};
let stations = cached_stations.unwrap_or_else(|| {
Rc::new(if let Some(code) = &config.country_code {
match api
.get_stations()
.countrycode(code)
.order(StationOrder::Clickcount)
.send()
{
Ok(s) => s,
Err(_e) => Vec::new(),
}
} else {
match api.get_stations().order(StationOrder::Clickcount).send() {
Ok(s) => s,
Err(_e) => Vec::new(),
}
})
});

Ok(Browser {
api,
config,
Ok((
Browser {
api,
config,
stations: stations.clone(),
},
stations,
})
))
}

pub fn get_countries() -> Result<Vec<ApiCountry>, Box<dyn Error>> {
Expand Down
7 changes: 7 additions & 0 deletions src/lib/cli_args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,13 @@ pub struct Cli {
)]
pub list_countries: bool,

/// Flag: --no-station-cache: Don't cache the station list loaded from the internet.
#[clap(
long = "no-station-cache",
help = "Don't cache the station list loaded from the internet."
)]
pub no_station_cache: bool,

/// Show extra info
#[clap(flatten)]
pub verbose: clap_verbosity_flag::Verbosity,
Expand Down
44 changes: 1 addition & 43 deletions src/lib/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,13 @@ use crate::station::Station;
use crate::version::Version;

use colored::*;
use inquire::{error::InquireError, Select};
use serde::de::{Deserializer, Error as SeError, Visitor};
use serde::Deserialize;
use std::fmt::{Formatter, Result as ResultFmt};
use std::fs::File;
use std::io::{Read, Write};
use std::path::PathBuf;

use crate::browser::Browser;

const _CONFIG_URL: &str = "https://raw.githubusercontent.com/margual56/radio-cli/main/config.json";

#[derive(Deserialize, Debug, Clone)]
Expand Down Expand Up @@ -134,7 +131,7 @@ impl Config {
}
}

pub fn get_url_for(self, station_name: &str) -> Option<String> {
pub fn get_url_for(&self, station_name: &str) -> Option<String> {
for s in self.data.iter() {
if s.station.eq(station_name) {
return Some(s.url.clone());
Expand All @@ -153,45 +150,6 @@ impl Config {

stations
}

/// Prompts the user to select a station.
/// Returns a station and if the station was taken from the internet.
pub fn prompt(self) -> Result<(Station, bool), InquireError> {
let max_lines: usize = match self.max_lines {
Some(x) => x,
None => Select::<Station>::DEFAULT_PAGE_SIZE,
};

let res = Select::new(&"Select a station to play:".bold(), self.data.clone())
.with_page_size(max_lines)
.prompt();

let internet: bool;
let station: Station = match res {
Ok(s) => {
if s.station.eq("Other") {
internet = true;
let result = Browser::new(self);

let brow = match result {
Ok(b) => b,
Err(_e) => return Err(InquireError::OperationInterrupted),
};

match brow.prompt() {
Ok(r) => r,
Err(e) => return Err(e),
}
} else {
internet = false;
s
}
}
Err(e) => return Err(e),
};

Ok((station, internet))
}
}

fn deserialize_version<'de, D>(deserializer: D) -> Result<Version, D::Error>
Expand Down
Loading

0 comments on commit d61b80f

Please sign in to comment.