mecomp_daemon/services/
mod.rs

1use log::warn;
2use mecomp_storage::{
3    db::schemas::{
4        album::{Album, TABLE_NAME as ALBUM_TABLE_NAME},
5        artist::{Artist, TABLE_NAME as ARTIST_TABLE_NAME},
6        collection::{Collection, TABLE_NAME as COLLECTION_TABLE_NAME},
7        dynamic::{DynamicPlaylist, TABLE_NAME as DYNAMIC_PLAYLIST_TABLE_NAME},
8        playlist::{Playlist, TABLE_NAME as PLAYLIST_TABLE_NAME},
9        song::{Song, TABLE_NAME as SONG_TABLE_NAME},
10        Thing,
11    },
12    errors::{Error, StorageResult},
13};
14use one_or_many::OneOrMany;
15use surrealdb::{Connection, Surreal};
16
17pub mod library;
18#[cfg(feature = "analysis")]
19pub mod radio;
20
21/// Get the songs associated with every thing in the list.
22///
23/// This function will go through the list of things and get the songs associated with each thing.
24///
25/// It will then remove duplicates from the list of songs.
26///
27/// # Errors
28///
29/// This function will return an error if there is an issue reading the songs from the database.
30#[inline]
31pub async fn get_songs_from_things<C: Connection>(
32    db: &Surreal<C>,
33    things: &[Thing],
34) -> StorageResult<OneOrMany<Song>> {
35    // go through the list, and get songs for each thing (depending on what it is)
36    let mut songs: OneOrMany<Song> = OneOrMany::None;
37    for thing in things {
38        match thing.tb.as_str() {
39            ALBUM_TABLE_NAME => {
40                for song in Album::read_songs(db, thing.clone().into()).await? {
41                    songs.push(song);
42                }
43            }
44            ARTIST_TABLE_NAME => {
45                for song in Artist::read_songs(db, thing.clone().into()).await? {
46                    songs.push(song);
47                }
48            }
49            COLLECTION_TABLE_NAME => {
50                for song in Collection::read_songs(db, thing.clone().into()).await? {
51                    songs.push(song);
52                }
53            }
54            PLAYLIST_TABLE_NAME => {
55                for song in Playlist::read_songs(db, thing.clone().into()).await? {
56                    songs.push(song);
57                }
58            }
59            SONG_TABLE_NAME => songs.push(
60                Song::read(db, thing.clone().into())
61                    .await?
62                    .ok_or(Error::NotFound)?,
63            ),
64            DYNAMIC_PLAYLIST_TABLE_NAME => {
65                for song in DynamicPlaylist::run_query_by_id(db, thing.clone().into())
66                    .await?
67                    .unwrap_or_default()
68                {
69                    songs.push(song);
70                }
71            }
72            _ => {
73                warn!("Unknown thing type: {}", thing.tb);
74            }
75        }
76    }
77
78    // remove duplicates
79    songs.dedup_by_key(|song| song.id.clone());
80
81    Ok(songs)
82}