Skip to content

Commit

Permalink
add /radio_sur command
Browse files Browse the repository at this point in the history
  • Loading branch information
jelni committed Jul 4, 2024
1 parent 14effa1 commit 3d8798d
Show file tree
Hide file tree
Showing 8 changed files with 203 additions and 127 deletions.
1 change: 1 addition & 0 deletions src/apis.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub mod azuracast;
pub mod cobalt;
pub mod craiyon;
pub mod different_dimension_me;
Expand Down
155 changes: 155 additions & 0 deletions src/apis/azuracast.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
use serde::Deserialize;

use crate::commands::CommandError;
use crate::utilities::api_utils::DetectServerError;
use crate::utilities::message_entities::{Entity, ToEntity, ToEntityOwned};
use crate::utilities::text_utils;

#[derive(Deserialize)]
pub struct PlayerState {
pub station: Station,
pub live: Live,
pub now_playing: Option<CurrentSong>,
pub playing_next: Option<StationQueue>,
pub listeners: Listeners,
}

#[derive(Deserialize)]
pub struct Station {
pub id: u32,
pub name: String,
pub public_player_url: String,
}

#[derive(Deserialize)]
pub struct Listeners {
pub total: u32,
pub unique: u32,
}

#[derive(Deserialize)]
pub struct Live {
pub is_live: bool,
pub streamer_name: String,
}

#[derive(Deserialize)]
pub struct CurrentSong {
pub song: Song,
pub duration: u32,
pub elapsed: u32,
}

#[derive(Deserialize)]
pub struct StationQueue {
pub song: Song,
}

#[derive(Deserialize)]
pub struct Song {
pub title: String,
pub artist: String,
pub album: String,
}

impl PlayerState {
pub fn format_entities(self, compact: bool) -> Vec<Entity<'static>> {
let mut entities = Vec::new();

if self.live.is_live {
entities.extend([
"DJ ".text(),
self.live.streamer_name.bold_owned(),
" NA BEACIE!!!".text(),
]);
} else {
entities.extend([
self.station.name.text_url_owned(self.station.public_player_url),
" mówi:".text(),
]);
}

if let Some(now_playing) = self.now_playing {
entities.push("\n".text());
entities.extend(format_song(now_playing.song));
entities.extend([
"\n".text(),
text_utils::progress_bar(now_playing.elapsed, now_playing.duration).code_owned(),
" ".text(),
text_utils::format_duration(now_playing.elapsed.into()).text_owned(),
" / ".text(),
text_utils::format_duration(now_playing.duration.into()).text_owned(),
]);
}

if !compact {
if let Some(playing_next) = self.playing_next {
entities.push("\n\nNastępnie:\n".text());
entities.extend(format_song(playing_next.song));
}
}

if !compact || self.listeners.total > 0 {
if !compact {
entities.push("\n".text());
}

entities.extend(["\nSłucha: ".text(), self.listeners.total.to_string().text_owned()]);

if self.listeners.total != self.listeners.unique {
entities.extend([
"(tak naprawdę ".text(),
self.listeners.unique.to_string().text_owned(),
")".text(),
]);
}
}

entities
}
}

pub async fn now_playing(
http_client: reqwest::Client,
domain: &str,
) -> Result<Vec<PlayerState>, CommandError> {
let now_playing = http_client
.get(format!("https://{domain}/api/nowplaying"))
.send()
.await?
.server_error()?
.json()
.await?;

Ok(now_playing)
}

pub async fn station_now_playing(
http_client: reqwest::Client,
domain: &str,
station_id: u32,
) -> Result<PlayerState, CommandError> {
let now_playing = http_client
.get(format!("https://{domain}/api/nowplaying/{station_id}"))
.send()
.await?
.server_error()?
.json()
.await?;

Ok(now_playing)
}

fn format_song(song: Song) -> Vec<Entity<'static>> {
let mut entities = vec![song.title.bold_owned()];

if !song.artist.is_empty() {
entities.extend(["\n".text(), song.artist.text_owned()]);
}

if !song.album.is_empty() {
entities.extend([" • ".text(), song.album.text_owned()]);
}

entities
}
61 changes: 0 additions & 61 deletions src/apis/poligon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,64 +19,3 @@ pub async fn startit_joke(http_client: reqwest::Client) -> Result<String, Comman

Ok(joke.joke)
}

#[derive(Deserialize)]
pub struct PlayerState {
pub station: Station,
pub live: Live,
pub now_playing: Option<CurrentSong>,
pub playing_next: Option<StationQueue>,
pub listeners: Listeners,
}

#[derive(Deserialize)]
pub struct Station {
pub name: String,
pub public_player_url: String,
}

#[derive(Deserialize)]
pub struct Listeners {
pub total: u32,
pub unique: u32,
}

#[derive(Deserialize)]
pub struct Live {
pub is_live: bool,
pub streamer_name: String,
}

#[derive(Deserialize)]
pub struct CurrentSong {
pub song: Song,
pub duration: u32,
pub elapsed: u32,
}

#[derive(Deserialize)]
pub struct StationQueue {
pub song: Song,
}

#[derive(Deserialize)]
pub struct Song {
pub title: String,
pub artist: String,
pub album: String,
}

pub async fn now_playing(
http_client: reqwest::Client,
station_id: u32,
) -> Result<PlayerState, CommandError> {
let now_playing = http_client
.get(format!("https://radio.poligon.lgbt/api/nowplaying/{station_id}"))
.send()
.await?
.server_error()?
.json::<PlayerState>()
.await?;

Ok(now_playing)
}
1 change: 1 addition & 0 deletions src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ pub mod mevo;
pub mod moveit_joke;
pub mod ping;
pub mod radio_poligon;
pub mod radio_sur;
pub mod screenshot;
pub mod sex;
pub mod stablehorde;
Expand Down
77 changes: 11 additions & 66 deletions src/commands/radio_poligon.rs
Original file line number Diff line number Diff line change
@@ -1,84 +1,29 @@
use async_trait::async_trait;

use super::{CommandResult, CommandTrait};
use crate::apis::poligon::{self, Song};
use crate::apis::azuracast;
use crate::utilities::command_context::CommandContext;
use crate::utilities::message_entities::{self, Entity, ToEntity, ToEntityOwned};
use crate::utilities::text_utils::{self};
use crate::utilities::message_entities;

pub struct RadioPoligon;

#[async_trait]
impl CommandTrait for RadioPoligon {
fn command_names(&self) -> &[&str] {
&["radio_poligon", "radio", "poligon"]
&["radio_poligon", "poligon"]
}

async fn execute(&self, ctx: &CommandContext, _: String) -> CommandResult {
let now_playing = poligon::now_playing(ctx.bot_state.http_client.clone(), 1).await?;
let mut entities = Vec::new();
let station = azuracast::station_now_playing(
ctx.bot_state.http_client.clone(),
"radio.poligon.lgbt",
1,
)
.await?;

if now_playing.live.is_live {
entities.extend([
"DJ ".text(),
now_playing.live.streamer_name.bold(),
" NA BEACIE!!!".text(),
"\n".text(),
]);
} else {
entities.extend([
now_playing.station.name.text_url(now_playing.station.public_player_url),
" mówi:".text(),
"\n".text(),
]);
}

if let Some(now_playing) = now_playing.now_playing {
entities.extend(format_song(now_playing.song));
entities.extend([
"\n".text(),
text_utils::progress_bar(now_playing.elapsed, now_playing.duration).code_owned(),
" ".text(),
text_utils::format_duration(now_playing.elapsed.into()).text_owned(),
" / ".text(),
text_utils::format_duration(now_playing.duration.into()).text_owned(),
"\n".text(),
]);
}

if let Some(playing_next) = now_playing.playing_next {
entities.push("\nNastępnie:\n".text());
entities.extend(format_song(playing_next.song));
entities.push("\n".text());
}

entities
.extend(["\nSłucha: ".text(), now_playing.listeners.total.to_string().text_owned()]);

if now_playing.listeners.total != now_playing.listeners.unique {
entities.extend([
"(tak naprawdę ".text(),
now_playing.listeners.unique.to_string().text_owned(),
")".text(),
]);
}

ctx.reply_formatted_text(message_entities::formatted_text(entities)).await?;
ctx.reply_formatted_text(message_entities::formatted_text(station.format_entities(false)))
.await?;

Ok(())
}
}

fn format_song(song: Song) -> Vec<Entity<'static>> {
let mut entities = vec![song.title.bold_owned()];

if !song.artist.is_empty() {
entities.extend(["\n".text(), song.artist.text_owned()]);
}

if !song.album.is_empty() {
entities.extend([" • ".text(), song.album.text_owned()]);
}

entities
}
33 changes: 33 additions & 0 deletions src/commands/radio_sur.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
use async_trait::async_trait;

use super::{CommandResult, CommandTrait};
use crate::apis::azuracast;
use crate::utilities::command_context::CommandContext;
use crate::utilities::message_entities::{self, ToEntity};

pub struct RadioSur;

#[async_trait]
impl CommandTrait for RadioSur {
fn command_names(&self) -> &[&str] {
&["radio_sur", "sur"]
}

async fn execute(&self, ctx: &CommandContext, _: String) -> CommandResult {
let mut stations =
azuracast::now_playing(ctx.bot_state.http_client.clone(), "stream.surradio.live")
.await?;

stations.sort_unstable_by_key(|station| station.station.id);

let entities = stations
.into_iter()
.map(|station| station.format_entities(true))
.collect::<Vec<_>>()
.join(&"\n\n".text());

ctx.reply_formatted_text(message_entities::formatted_text(entities)).await?;

Ok(())
}
}
1 change: 1 addition & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ async fn main() {
bot.add_command(commands::cobalt_download::CobaltDownload::auto());
bot.add_command(commands::cobalt_download::CobaltDownload::audio());
bot.add_command(commands::charinfo::CharInfo);
bot.add_command(commands::radio_sur::RadioSur);
bot.add_command(commands::radio_poligon::RadioPoligon);
bot.add_command(commands::autocomplete::Autocomplete);
bot.add_command(commands::mevo::Mevo);
Expand Down
1 change: 1 addition & 0 deletions src/utilities/message_entities.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ impl Utf16Len for str {
}
}

#[derive(Clone)]
pub enum Entity<'a> {
Text(Cow<'a, str>),
Bold(Vec<Entity<'a>>),
Expand Down

0 comments on commit 3d8798d

Please sign in to comment.