Make clippy happy, add tokio monitoring

This commit is contained in:
DaXcess
2023-01-27 14:11:54 +00:00
parent 4897e943dd
commit 4253c9f1bb
27 changed files with 493 additions and 150 deletions
+4 -8
View File
@@ -42,9 +42,7 @@ impl Sink for StdoutSink {
self
.output
.take()
.ok_or(SinkError::NotConnected(
"StdoutSink is not connected".to_string(),
))?
.ok_or_else(|| SinkError::NotConnected("StdoutSink is not connected".to_string()))?
.flush()
.map_err(|why| SinkError::OnWrite(why.to_string()))?;
@@ -62,9 +60,9 @@ impl Sink for StdoutSink {
48000,
2,
samplerate::ConverterType::Linear,
&samples_f32,
samples_f32,
)
.unwrap();
.expect("to succeed");
let samples_i16 =
&converter.f64_to_s16(&resampled.iter().map(|v| *v as f64).collect::<Vec<f64>>());
@@ -81,9 +79,7 @@ impl SinkAsBytes for StdoutSink {
self
.output
.as_deref_mut()
.ok_or(SinkError::NotConnected(
"StdoutSink is not connected".to_string(),
))?
.ok_or_else(|| SinkError::NotConnected("StdoutSink is not connected".to_string()))?
.write_all(data)
.map_err(|why| SinkError::OnWrite(why.to_string()))?;
+2 -2
View File
@@ -19,14 +19,14 @@ pub fn run(ctx: Context, command: ApplicationCommandInteraction) -> CommandOutpu
EmbedBuilder::new()
.title("Spoticord Help")
.icon_url("https://spoticord.com/logo-standard.webp")
.description(format!("**Welcome to Spoticord**
.description("**Welcome to Spoticord**
It seems you have requested some help. Not to worry, we can help you out.\n
**Not sure how the bot works?**
**[Click here](https://spoticord.com/#how-to)** for a quick overview about how to set up Spoticord and how to use it.\n
**Which commands are there?**
You can find all **[the commands](https://spoticord.com/#commands)** on the website. You may also just type `/` in Discord and see which commands are available there.\n
**Need more help?**
If you still need some help, whether you are having issues with the bot or you just want to give us some feedback, you can join our **[Discord server](https://discord.gg/wRCyhVqBZ5)**."))
If you still need some help, whether you are having issues with the bot or you just want to give us some feedback, you can join our **[Discord server](https://discord.gg/wRCyhVqBZ5)**.".to_string())
.status(Status::Info)
.build(),
false,
+9 -8
View File
@@ -17,9 +17,13 @@ pub const NAME: &str = "link";
pub fn run(ctx: Context, command: ApplicationCommandInteraction) -> CommandOutput {
Box::pin(async move {
let data = ctx.data.read().await;
let database = data.get::<Database>().unwrap();
let database = data.get::<Database>().expect("to contain a value");
if let Ok(_) = database.get_user_account(command.user.id.to_string()).await {
if database
.get_user_account(command.user.id.to_string())
.await
.is_ok()
{
respond_message(
&ctx,
&command,
@@ -35,7 +39,7 @@ pub fn run(ctx: Context, command: ApplicationCommandInteraction) -> CommandOutpu
}
if let Ok(request) = database.get_user_request(command.user.id.to_string()).await {
let base = std::env::var("SPOTICORD_ACCOUNTS_URL").unwrap();
let base = std::env::var("SPOTICORD_ACCOUNTS_URL").expect("to be present");
let link = format!("{}/spotify/{}", base, request.token);
respond_message(
@@ -102,7 +106,7 @@ pub fn run(ctx: Context, command: ApplicationCommandInteraction) -> CommandOutpu
.await
{
Ok(request) => {
let base = std::env::var("SPOTICORD_ACCOUNTS_URL").unwrap();
let base = std::env::var("SPOTICORD_ACCOUNTS_URL").expect("to be present");
let link = format!("{}/spotify/{}", base, request.token);
respond_message(
@@ -121,9 +125,8 @@ pub fn run(ctx: Context, command: ApplicationCommandInteraction) -> CommandOutpu
true,
)
.await;
return;
}
Err(why) => {
error!("Error creating user request: {:?}", why);
@@ -137,8 +140,6 @@ pub fn run(ctx: Context, command: ApplicationCommandInteraction) -> CommandOutpu
true,
)
.await;
return;
}
};
})
+2 -2
View File
@@ -22,7 +22,7 @@ pub const NAME: &str = "rename";
pub fn run(ctx: Context, command: ApplicationCommandInteraction) -> CommandOutput {
Box::pin(async move {
let data = ctx.data.read().await;
let database = data.get::<Database>().unwrap();
let database = data.get::<Database>().expect("to contain a value");
// Check if user exists, if not, create them
if let Err(why) = database.get_user(command.user.id.to_string()).await {
@@ -65,7 +65,7 @@ pub fn run(ctx: Context, command: ApplicationCommandInteraction) -> CommandOutpu
let device_name = match command.data.options.get(0) {
Some(option) => match option.value {
Some(ref value) => value.as_str().unwrap().to_string(),
Some(ref value) => value.as_str().expect("to be a string").to_string(),
None => {
respond_message(
&ctx,
+2 -2
View File
@@ -17,8 +17,8 @@ pub const NAME: &str = "unlink";
pub fn run(ctx: Context, command: ApplicationCommandInteraction) -> CommandOutput {
Box::pin(async move {
let data = ctx.data.read().await;
let database = data.get::<Database>().unwrap();
let session_manager = data.get::<SessionManager>().unwrap();
let database = data.get::<Database>().expect("to contain a value");
let session_manager = data.get::<SessionManager>().expect("to contain a value");
// Disconnect session if user has any
if let Some(session) = session_manager.find(command.user.id).await {
+1 -1
View File
@@ -170,7 +170,7 @@ impl CommandManager {
cmds: &HashMap<String, CommandInfo>,
mut commands: &'a mut CreateApplicationCommands,
) -> &'a mut CreateApplicationCommands {
for (_, command_info) in cmds {
for command_info in cmds.values() {
commands = commands.create_application_command(|command| (command_info.register)(command));
}
+15 -11
View File
@@ -15,7 +15,10 @@ pub const NAME: &str = "join";
pub fn run(ctx: Context, command: ApplicationCommandInteraction) -> CommandOutput {
Box::pin(async move {
let guild = ctx.cache.guild(command.guild_id.unwrap()).unwrap();
let guild = ctx
.cache
.guild(command.guild_id.expect("to contain a value"))
.expect("to be present");
// Get the voice channel id of the calling user
let channel_id = match guild
@@ -81,8 +84,7 @@ pub fn run(ctx: Context, command: ApplicationCommandInteraction) -> CommandOutpu
}
};
if let Ok(permissions) =
channel.permissions_for_user(&ctx.cache, &ctx.cache.current_user_id())
if let Ok(permissions) = channel.permissions_for_user(&ctx.cache, ctx.cache.current_user_id())
{
if !permissions.view_channel() || !permissions.connect() || !permissions.speak() {
respond_message(
@@ -142,8 +144,7 @@ pub fn run(ctx: Context, command: ApplicationCommandInteraction) -> CommandOutpu
}
};
if let Ok(permissions) =
channel.permissions_for_user(&ctx.cache, &ctx.cache.current_user_id())
if let Ok(permissions) = channel.permissions_for_user(&ctx.cache, ctx.cache.current_user_id())
{
if !permissions.view_channel() || !permissions.send_messages() || !permissions.embed_links()
{
@@ -167,7 +168,10 @@ pub fn run(ctx: Context, command: ApplicationCommandInteraction) -> CommandOutpu
}
let data = ctx.data.read().await;
let session_manager = data.get::<SessionManager>().unwrap().clone();
let session_manager = data
.get::<SessionManager>()
.expect("to contain a value")
.clone();
// Check if another session is already active in this server
let mut session_opt = session_manager.get_session(guild.id).await;
@@ -206,7 +210,7 @@ pub fn run(ctx: Context, command: ApplicationCommandInteraction) -> CommandOutpu
.description(
format!(
"You are already playing music in another server ({}).\nStop playing in that server first before joining this one.",
ctx.cache.guild(session.guild_id().await).unwrap().name
ctx.cache.guild(session.guild_id().await).expect("to be present").name
)).status(Status::Error).build(),
true,
)
@@ -230,7 +234,7 @@ pub fn run(ctx: Context, command: ApplicationCommandInteraction) -> CommandOutpu
if let Some(session) = session_opt.as_mut() {
if let Err(why) = session.update_owner(&ctx, command.user.id).await {
// Need to link first
if let SessionCreateError::NoSpotifyError = why {
if let SessionCreateError::NoSpotify = why {
update_message(
&ctx,
&command,
@@ -243,7 +247,7 @@ pub fn run(ctx: Context, command: ApplicationCommandInteraction) -> CommandOutpu
.await;
return;
} else if let SessionCreateError::NoLongerSpotifyError = why {
} else if let SessionCreateError::SpotifyExpired = why {
update_message(
&ctx,
&command,
@@ -284,7 +288,7 @@ pub fn run(ctx: Context, command: ApplicationCommandInteraction) -> CommandOutpu
.await
{
// Need to link first
if let SessionCreateError::NoSpotifyError = why {
if let SessionCreateError::NoSpotify = why {
update_message(
&ctx,
&command,
@@ -297,7 +301,7 @@ pub fn run(ctx: Context, command: ApplicationCommandInteraction) -> CommandOutpu
.await;
return;
} else if let SessionCreateError::NoLongerSpotifyError = why {
} else if let SessionCreateError::SpotifyExpired = why {
update_message(
&ctx,
&command,
+8 -2
View File
@@ -15,9 +15,15 @@ pub const NAME: &str = "leave";
pub fn run(ctx: Context, command: ApplicationCommandInteraction) -> CommandOutput {
Box::pin(async move {
let data = ctx.data.read().await;
let session_manager = data.get::<SessionManager>().unwrap().clone();
let session_manager = data
.get::<SessionManager>()
.expect("to contain a value")
.clone();
let session = match session_manager.get_session(command.guild_id.unwrap()).await {
let session = match session_manager
.get_session(command.guild_id.expect("to contain a value"))
.await
{
Some(session) => session,
None => {
respond_message(
+16 -8
View File
@@ -37,9 +37,15 @@ pub fn run(ctx: Context, command: ApplicationCommandInteraction) -> CommandOutpu
};
let data = ctx.data.read().await;
let session_manager = data.get::<SessionManager>().unwrap().clone();
let session_manager = data
.get::<SessionManager>()
.expect("to contain a value")
.clone();
let session = match session_manager.get_session(command.guild_id.unwrap()).await {
let session = match session_manager
.get_session(command.guild_id.expect("to contain a value"))
.await
{
Some(session) => session,
None => {
not_playing.await;
@@ -86,8 +92,8 @@ pub fn run(ctx: Context, command: ApplicationCommandInteraction) -> CommandOutpu
// Create title
let title = format!(
"{} - {}",
pbi.get_artists().unwrap(),
pbi.get_name().unwrap()
pbi.get_artists().expect("to contain a value"),
pbi.get_name().expect("to contain a value")
);
// Create description
@@ -100,9 +106,9 @@ pub fn run(ctx: Context, command: ApplicationCommandInteraction) -> CommandOutpu
for i in 0..20 {
if i == spot {
description.push_str("🔵");
description.push('🔵');
} else {
description.push_str("▬");
description.push('▬');
}
}
@@ -141,7 +147,7 @@ pub fn run(ctx: Context, command: ApplicationCommandInteraction) -> CommandOutpu
};
// Get the thumbnail image
let thumbnail = pbi.get_thumbnail_url().unwrap();
let thumbnail = pbi.get_thumbnail_url().expect("to contain a value");
if let Err(why) = command
.create_interaction_response(&ctx.http, |response| {
@@ -159,7 +165,9 @@ pub fn run(ctx: Context, command: ApplicationCommandInteraction) -> CommandOutpu
.url(format!(
"https://open.spotify.com/{}/{}",
audio_type,
spotify_id.to_base62().unwrap()
spotify_id
.to_base62()
.expect("to be able to convert to base62")
))
.description(description)
.footer(|footer| footer.text(&owner.name).icon_url(owner.face()))
+1 -1
View File
@@ -22,7 +22,7 @@ pub fn run(ctx: Context, command: ApplicationCommandInteraction) -> CommandOutpu
.interaction_response_data(|message| message.content("Pong!"))
})
.await
.unwrap();
.ok();
})
}
+2 -2
View File
@@ -15,7 +15,7 @@ pub const NAME: &str = "token";
pub fn run(ctx: Context, command: ApplicationCommandInteraction) -> CommandOutput {
Box::pin(async move {
let data = ctx.data.read().await;
let db = data.get::<Database>().unwrap();
let db = data.get::<Database>().expect("to contain a value");
let token = db.get_access_token(command.user.id.to_string()).await;
@@ -31,7 +31,7 @@ pub fn run(ctx: Context, command: ApplicationCommandInteraction) -> CommandOutpu
.interaction_response_data(|message| message.content(content).ephemeral(true))
})
.await
.unwrap();
.ok();
})
}
+2 -2
View File
@@ -19,7 +19,7 @@ impl EventHandler for Handler {
// READY event, emitted when the bot/shard starts up
async fn ready(&self, ctx: Context, ready: Ready) {
let data = ctx.data.read().await;
let command_manager = data.get::<CommandManager>().unwrap();
let command_manager = data.get::<CommandManager>().expect("to contain a value");
debug!("Ready received, logged in as {}", ready.user.name);
@@ -78,7 +78,7 @@ impl EventHandler for Handler {
);
let data = ctx.data.read().await;
let command_manager = data.get::<CommandManager>().unwrap();
let command_manager = data.get::<CommandManager>().expect("to contain a value");
command_manager.execute_command(&ctx, command).await;
}
+2 -2
View File
@@ -320,7 +320,7 @@ impl Database {
) -> Result<(), DatabaseError> {
let device_name: String = name.into();
if device_name.len() > 16 || device_name.len() < 1 {
if device_name.len() > 16 || device_name.is_empty() {
return Err(DatabaseError::InvalidInputBody(
"Invalid device name length".into(),
));
@@ -345,7 +345,7 @@ impl Database {
StatusCode::OK | StatusCode::CREATED | StatusCode::ACCEPTED | StatusCode::NO_CONTENT => {
Ok(())
}
status => return Err(DatabaseError::InvalidStatusCode(status)),
status => Err(DatabaseError::InvalidStatusCode(status)),
}
}
}
+2 -2
View File
@@ -58,12 +58,12 @@ impl Client {
self
.tx
.lock()
.unwrap()
.expect("to be able to lock")
.send(packet)
.map_err(IpcError::Bincode)
}
pub fn try_recv(&self) -> Result<IpcPacket, TryRecvError> {
self.rx.lock().unwrap().try_recv()
self.rx.lock().expect("to be able to lock").try_recv()
}
}
+16 -12
View File
@@ -26,6 +26,8 @@ mod utils;
#[tokio::main]
async fn main() {
console_subscriber::init();
if std::env::var("RUST_LOG").is_err() {
#[cfg(debug_assertions)]
{
@@ -42,18 +44,16 @@ async fn main() {
let args: Vec<String> = env::args().collect();
if args.len() > 2 {
if &args[1] == "--player" {
// Woah! We're running in player mode!
if args.len() > 2 && &args[1] == "--player" {
// Woah! We're running in player mode!
debug!("Starting Spoticord player");
debug!("Starting Spoticord player");
player::main().await;
player::main().await;
debug!("Player exited, shutting down");
debug!("Player exited, shutting down");
return;
}
return;
}
info!("It's a good day");
@@ -62,7 +62,10 @@ async fn main() {
let result = dotenv();
if let Ok(path) = result {
debug!("Loaded environment file: {}", path.to_str().unwrap());
debug!(
"Loaded environment file: {}",
path.to_str().expect("to get the string")
);
} else {
warn!("No .env file found, expecting all necessary environment variables");
}
@@ -83,7 +86,7 @@ async fn main() {
.framework(StandardFramework::new())
.register_songbird()
.await
.unwrap();
.expect("to create a client");
{
let mut data = client.data.write().await;
@@ -98,7 +101,8 @@ async fn main() {
#[cfg(unix)]
let mut term: Option<Box<dyn Any + Send>> = Some(Box::new(
tokio::signal::unix::signal(SignalKind::terminate()).unwrap(),
tokio::signal::unix::signal(SignalKind::terminate())
.expect("to be able to create the signal stream"),
));
#[cfg(not(unix))]
@@ -145,7 +149,7 @@ async fn main() {
#[cfg(unix)]
match term {
Some(ref mut term) => {
let term = term.downcast_mut::<tokio::signal::unix::Signal>().unwrap();
let term = term.downcast_mut::<tokio::signal::unix::Signal>().expect("to be able to downcast");
term.recv().await
}
+15 -13
View File
@@ -43,7 +43,9 @@ impl SpoticordPlayer {
let token = token.into();
// Get the username (required for librespot)
let username = utils::spotify::get_username(&token).await.unwrap();
let username = utils::spotify::get_username(&token)
.await
.expect("to get the username");
let session_config = SessionConfig::default();
let player_config = PlayerConfig {
@@ -68,7 +70,7 @@ impl SpoticordPlayer {
self
.client
.send(IpcPacket::ConnectError(why.to_string()))
.unwrap();
.ok();
return;
}
};
@@ -77,7 +79,7 @@ impl SpoticordPlayer {
self.session = Some(session.clone());
// Volume mixer
let mixer = (mixer::find(Some("softvol")).unwrap())(MixerConfig {
let mixer = (mixer::find(Some("softvol")).expect("to exist"))(MixerConfig {
volume_ctrl: librespot::playback::config::VolumeCtrl::Linear,
..MixerConfig::default()
});
@@ -138,13 +140,13 @@ impl SpoticordPlayer {
.send(IpcPacket::ConnectError(
"Switch to Spoticord device timed out".to_string(),
))
.unwrap();
.ok();
break;
}
}
Err(why) => {
error!("Failed to set device: {}", why);
ipc.send(IpcPacket::ConnectError(why.to_string())).unwrap();
ipc.send(IpcPacket::ConnectError(why.to_string())).ok();
break;
}
}
@@ -167,7 +169,7 @@ impl SpoticordPlayer {
duration_ms,
} => {
if let Err(why) = ipc.send(IpcPacket::Playing(
track_id.to_uri().unwrap(),
track_id.to_uri().expect("to not fail"),
position_ms,
duration_ms,
)) {
@@ -182,7 +184,7 @@ impl SpoticordPlayer {
duration_ms,
} => {
if let Err(why) = ipc.send(IpcPacket::Paused(
track_id.to_uri().unwrap(),
track_id.to_uri().expect("to not fail"),
position_ms,
duration_ms,
)) {
@@ -194,7 +196,9 @@ impl SpoticordPlayer {
old_track_id: _,
new_track_id,
} => {
if let Err(why) = ipc.send(IpcPacket::TrackChange(new_track_id.to_uri().unwrap())) {
if let Err(why) = ipc.send(IpcPacket::TrackChange(
new_track_id.to_uri().expect("to not fail"),
)) {
error!("Failed to send track change packet: {}", why);
}
}
@@ -247,11 +251,9 @@ pub async fn main() {
tokio::time::sleep(Duration::from_millis(25)).await;
continue;
} else if let TryRecvError::IpcError(why) = &why {
if let IpcError::Disconnected = why {
debug!("IPC connection closed, goodbye");
break;
}
} else if let TryRecvError::IpcError(IpcError::Disconnected) = &why {
debug!("IPC connection closed, goodbye");
break;
}
error!("Failed to receive message: {}", why);
+4 -4
View File
@@ -11,13 +11,13 @@ use super::SpoticordSession;
#[derive(Debug, Error)]
pub enum SessionCreateError {
#[error("This session has no owner assigned")]
NoOwnerError,
NoOwner,
#[error("The user has not linked their Spotify account")]
NoSpotifyError,
NoSpotify,
#[error("The application no longer has access to the user's Spotify account")]
NoLongerSpotifyError,
SpotifyExpired,
#[error("An error has occured while communicating with the database")]
DatabaseError,
@@ -99,7 +99,7 @@ impl InnerSessionManager {
pub fn find(&self, owner_id: UserId) -> Option<SpoticordSession> {
let guild_id = self.owner_map.get(&owner_id)?;
self.sessions.get(&guild_id).cloned()
self.sessions.get(guild_id).cloned()
}
/// Get the amount of sessions
+43 -38
View File
@@ -70,10 +70,13 @@ impl SpoticordSession {
) -> Result<SpoticordSession, SessionCreateError> {
// Get the Spotify token of the owner
let data = ctx.data.read().await;
let session_manager = data.get::<SessionManager>().unwrap().clone();
let session_manager = data
.get::<SessionManager>()
.expect("to contain a value")
.clone();
// Join the voice channel
let songbird = songbird::get(ctx).await.unwrap().clone();
let songbird = songbird::get(ctx).await.expect("to be present").clone();
let (call, result) = songbird.join(guild_id, channel_id).await;
@@ -83,7 +86,7 @@ impl SpoticordSession {
}
let inner = InnerSpoticordSession {
owner: Some(owner_id.clone()),
owner: Some(owner_id),
guild_id,
channel_id,
text_channel_id,
@@ -124,7 +127,10 @@ impl SpoticordSession {
) -> Result<(), SessionCreateError> {
// Get the Spotify token of the owner
let data = ctx.data.read().await;
let session_manager = data.get::<SessionManager>().unwrap().clone();
let session_manager = data
.get::<SessionManager>()
.expect("to contain a value")
.clone();
{
let mut inner = self.0.write().await;
@@ -144,22 +150,22 @@ impl SpoticordSession {
}
async fn create_player(&mut self, ctx: &Context) -> Result<(), SessionCreateError> {
let owner_id = match self.owner().await.clone() {
let owner_id = match self.owner().await {
Some(owner_id) => owner_id,
None => return Err(SessionCreateError::NoOwnerError),
None => return Err(SessionCreateError::NoOwner),
};
let data = ctx.data.read().await;
let database = data.get::<Database>().unwrap();
let database = data.get::<Database>().expect("to contain a value");
let token = match database.get_access_token(owner_id.to_string()).await {
Ok(token) => token,
Err(why) => {
if let DatabaseError::InvalidStatusCode(code) = why {
if code == 404 {
return Err(SessionCreateError::NoSpotifyError);
return Err(SessionCreateError::NoSpotify);
} else if code == 400 {
return Err(SessionCreateError::NoLongerSpotifyError);
return Err(SessionCreateError::SpotifyExpired);
}
}
@@ -185,24 +191,25 @@ impl SpoticordSession {
};
// Spawn player process
let child = match Command::new(std::env::current_exe().unwrap())
.args([
"--player",
&tx_name,
&rx_name,
"--debug-guild-id",
&self.guild_id().await.to_string(),
])
.stdout(Stdio::piped())
.stderr(Stdio::inherit())
.spawn()
{
Ok(child) => child,
Err(why) => {
error!("Failed to start player process: {:?}", why);
return Err(SessionCreateError::ForkError);
}
};
let child =
match Command::new(std::env::current_exe().expect("to know the current executable path"))
.args([
"--player",
&tx_name,
&rx_name,
"--debug-guild-id",
&self.guild_id().await.to_string(),
])
.stdout(Stdio::piped())
.stderr(Stdio::inherit())
.spawn()
{
Ok(child) => child,
Err(why) => {
error!("Failed to start player process: {:?}", why);
return Err(SessionCreateError::ForkError);
}
};
// Establish bi-directional IPC channel
let client = match server.accept() {
@@ -256,11 +263,9 @@ impl SpoticordSession {
tokio::time::sleep(Duration::from_millis(25)).await;
continue;
} else if let TryRecvError::IpcError(why) = &why {
if let IpcError::Disconnected = why {
trace!("IPC connection closed, exiting IPC handler");
break;
}
} else if let TryRecvError::IpcError(IpcError::Disconnected) = &why {
trace!("IPC connection closed, exiting IPC handler");
break;
}
error!("Failed to receive IPC message: {:?}", why);
@@ -310,7 +315,7 @@ impl SpoticordSession {
// A new track has been set by the player
IpcPacket::TrackChange(track) => {
// Convert to SpotifyId
let track_id = SpotifyId::from_uri(&track).unwrap();
let track_id = SpotifyId::from_uri(&track).expect("to be a valid uri");
let instance = instance.clone();
let ctx = ctx.clone();
@@ -329,7 +334,7 @@ impl SpoticordSession {
// The player has started playing a track
IpcPacket::Playing(track, position_ms, duration_ms) => {
// Convert to SpotifyId
let track_id = SpotifyId::from_uri(&track).unwrap();
let track_id = SpotifyId::from_uri(&track).expect("to be a valid uri");
let was_none = instance
.update_playback(duration_ms, position_ms, true)
@@ -350,7 +355,7 @@ impl SpoticordSession {
instance.start_disconnect_timer().await;
// Convert to SpotifyId
let track_id = SpotifyId::from_uri(&track).unwrap();
let track_id = SpotifyId::from_uri(&track).expect("to be a valid uri");
let was_none = instance
.update_playback(duration_ms, position_ms, false)
@@ -415,7 +420,7 @@ impl SpoticordSession {
let pbi = self.playback_info().await;
if let Some(pbi) = pbi {
pbi.spotify_id.is_none() || pbi.spotify_id.unwrap() != spotify_id
pbi.spotify_id.is_none() || pbi.spotify_id != Some(spotify_id)
} else {
false
}
@@ -426,7 +431,7 @@ impl SpoticordSession {
}
let data = ctx.data.read().await;
let database = data.get::<Database>().unwrap();
let database = data.get::<Database>().expect("to contain a value");
let token = match database.get_access_token(&owner_id.to_string()).await {
Ok(token) => token,
@@ -549,7 +554,7 @@ impl SpoticordSession {
inner
.playback_info
.as_mut()
.unwrap()
.expect("to contain a value")
.update_pos_dur(position_ms, duration_ms, playing);
};
+7 -8
View File
@@ -66,10 +66,8 @@ impl PlaybackInfo {
pub fn get_name(&self) -> Option<String> {
if let Some(track) = &self.track {
Some(track.name.clone())
} else if let Some(episode) = &self.episode {
Some(episode.name.clone())
} else {
None
self.episode.as_ref().map(|episode| episode.name.clone())
}
}
@@ -84,10 +82,11 @@ impl PlaybackInfo {
.collect::<Vec<String>>()
.join(", "),
)
} else if let Some(episode) = &self.episode {
Some(episode.show.name.clone())
} else {
None
self
.episode
.as_ref()
.map(|episode| episode.show.name.clone())
}
}
@@ -97,12 +96,12 @@ impl PlaybackInfo {
let mut images = track.album.images.clone();
images.sort_by(|a, b| b.width.cmp(&a.width));
Some(images.get(0).unwrap().url.clone())
images.get(0).as_ref().map(|image| image.url.clone())
} else if let Some(episode) = &self.episode {
let mut images = episode.show.images.clone();
images.sort_by(|a, b| b.width.cmp(&a.width));
Some(images.get(0).unwrap().url.clone())
images.get(0).as_ref().map(|image| image.url.clone())
} else {
None
}
+5 -5
View File
@@ -7,11 +7,11 @@ pub fn escape(text: impl Into<String>) -> String {
let text: String = text.into();
text
.replace("\\", "\\\\")
.replace("*", "\\*")
.replace("_", "\\_")
.replace("~", "\\~")
.replace("`", "\\`")
.replace('\\', "\\\\")
.replace('*', "\\*")
.replace('_', "\\_")
.replace('~', "\\~")
.replace('`', "\\`")
}
pub async fn get_user(ctx: &Context, id: UserId) -> Option<User> {
+3 -3
View File
@@ -65,10 +65,10 @@ impl EmbedBuilder {
}
}
pub fn make_embed_message<'a>(
embed: &'a mut CreateEmbed,
pub fn make_embed_message(
embed: &'_ mut CreateEmbed,
options: EmbedMessageOptions,
) -> &'a mut CreateEmbed {
) -> &'_ mut CreateEmbed {
let status = options.status.unwrap_or(Status::None);
embed.author(|author| {
+4 -4
View File
@@ -23,15 +23,15 @@ pub fn time_to_str(time: u32) -> String {
let min = 60;
if time / hour >= 1 {
return format!(
format!(
"{}h{}m{}s",
time / hour,
(time % hour) / min,
(time % hour) % min
);
)
} else if time / min >= 1 {
return format!("{}m{}s", time / min, time % min);
format!("{}m{}s", time / min, time % min)
} else {
return format!("{}s", time);
format!("{}s", time)
}
}
+4 -7
View File
@@ -69,13 +69,10 @@ pub async fn get_username(token: impl Into<String>) -> Result<String, String> {
if response.status() != 200 {
error!("Failed to get username: {}", response.status());
return Err(
format!(
"Failed to get track info: Invalid status code: {}",
response.status()
)
.into(),
);
return Err(format!(
"Failed to get track info: Invalid status code: {}",
response.status()
));
}
let body: Value = match response.json().await {