155 lines
4.2 KiB
Rust
155 lines
4.2 KiB
Rust
use crate::helpers::db;
|
|
use crate::schema::{playlists, playlists_tracks};
|
|
use chrono::NaiveDateTime;
|
|
use diesel::{prelude::*, result::Error};
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
use super::artists_tracks::{ArtistTracks, TrackArtist};
|
|
use super::{playlists_tracks::PlaylistTracks, tracks::Tracks, users::Users};
|
|
|
|
#[derive(Debug, Deserialize, Serialize)]
|
|
pub struct PlaylistCreator {
|
|
pub id: String,
|
|
pub name: String,
|
|
}
|
|
|
|
#[derive(
|
|
AsChangeset, Debug, Deserialize, Identifiable, Queryable, Selectable, Serialize, PartialEq,
|
|
)]
|
|
#[diesel(table_name = playlists)]
|
|
pub struct Playlists {
|
|
pub id: String,
|
|
pub name: String,
|
|
pub public: bool,
|
|
|
|
pub playlist_type: String,
|
|
|
|
pub creator_id: String,
|
|
pub parent_id: Option<String>,
|
|
|
|
pub created_at: Option<NaiveDateTime>,
|
|
pub updated_at: Option<NaiveDateTime>,
|
|
}
|
|
|
|
#[derive(Debug, Deserialize, Insertable)]
|
|
#[diesel(table_name = playlists)]
|
|
pub struct NewPlaylist {
|
|
pub name: String,
|
|
pub public: bool,
|
|
// pub playlist_type: String,
|
|
pub creator_id: String,
|
|
}
|
|
|
|
impl Playlists {
|
|
pub fn find(id: &str) -> Result<Self, Error> {
|
|
let conn = &mut db::connection()?;
|
|
let playlist = playlists::table.filter(playlists::id.eq(id)).first(conn)?;
|
|
Ok(playlist)
|
|
}
|
|
|
|
pub fn create(playlist: NewPlaylist) -> Result<Self, Error> {
|
|
let conn = &mut db::connection()?;
|
|
let playlist = diesel::insert_into(playlists::table)
|
|
.values(playlist)
|
|
.get_result(conn)?;
|
|
Ok(playlist)
|
|
}
|
|
|
|
pub fn find_for_user(user_id: &str, filter_public: bool) -> Result<Vec<Playlists>, Error> {
|
|
let conn = &mut db::connection()?;
|
|
|
|
let mut playlists = playlists::table
|
|
.distinct()
|
|
.select(Playlists::as_select())
|
|
.order((playlists::playlist_type.desc(), playlists::parent_id.desc()))
|
|
.filter(playlists::creator_id.eq(user_id))
|
|
.into_boxed();
|
|
|
|
if filter_public {
|
|
playlists = playlists.filter(
|
|
playlists::public
|
|
.eq(true)
|
|
.and(playlists::playlist_type.ne("folder")),
|
|
);
|
|
}
|
|
|
|
let playlists = playlists.get_results(conn)?;
|
|
Ok(playlists)
|
|
}
|
|
|
|
pub fn get_tracks(&self) -> Result<Vec<PlaylistTrack>, Error> {
|
|
let tracks: Vec<PlaylistTrack> = PlaylistTracks::get_tracks(self)?;
|
|
|
|
Ok(tracks)
|
|
}
|
|
|
|
pub fn get_creator(&self) -> Result<Users, Error> {
|
|
let creator = Users::find(&self.creator_id)?;
|
|
Ok(creator)
|
|
}
|
|
|
|
pub fn get_data(&self, tracks: &[PlaylistTrack]) -> (usize, usize) {
|
|
if tracks.is_empty() {
|
|
return (0, 0);
|
|
}
|
|
|
|
let duration = tracks
|
|
.iter()
|
|
.map(|track| track.duration_ms)
|
|
.reduce(|a, b| a + b)
|
|
.unwrap() as usize;
|
|
|
|
(duration, tracks.len())
|
|
}
|
|
|
|
pub fn can_see(&self, creator: Option<Users>) -> bool {
|
|
self.public || creator.map_or(false, |user| user.id == self.creator_id)
|
|
}
|
|
}
|
|
|
|
// // Folder
|
|
// struct Folder {
|
|
// id: String,
|
|
// name: String,
|
|
// playlists: Vec<Playlists>,
|
|
// }
|
|
|
|
// impl Folder {
|
|
// pub fn get_playlists(&self) -> Result<Vec<Playlists>, Error> {
|
|
// let playlists = playlists::table
|
|
// }
|
|
// }
|
|
|
|
#[derive(Deserialize, Serialize)]
|
|
pub struct PlaylistTrack {
|
|
pub id: String,
|
|
pub title: String,
|
|
pub duration_ms: i32,
|
|
|
|
pub artists: Vec<TrackArtist>,
|
|
pub added_at: NaiveDateTime,
|
|
pub spotify_id: Option<String>,
|
|
pub tidal_id: Option<String>,
|
|
}
|
|
|
|
impl From<Tracks> for PlaylistTrack {
|
|
fn from(track: Tracks) -> Self {
|
|
let artists = ArtistTracks::get_artists(&track).unwrap();
|
|
|
|
let added_at = playlists_tracks::table
|
|
.filter(playlists_tracks::track_id.eq(&track.id))
|
|
.select(playlists_tracks::added_at)
|
|
.first::<NaiveDateTime>(&mut db::connection().unwrap())
|
|
.unwrap();
|
|
|
|
PlaylistTrack {
|
|
id: track.id,
|
|
title: track.title,
|
|
duration_ms: track.duration_ms,
|
|
artists,
|
|
added_at,
|
|
spotify_id: track.spotify_id,
|
|
tidal_id: track.tidal_id,
|
|
}
|
|
}
|
|
}
|