librmo 0.4.4

A library to manage media files and play them
Documentation
use crate::error::CustomError;
use config::Config;
use sea_orm::{Database, EnumIter};
use sea_orm_migration::prelude::*;
use serde::{Deserialize, Serialize};
use std::env;
use std::fs;

#[derive(Iden, EnumIter)]
pub enum ReportType {
    #[iden = "ALBUM"]
    NoAlbum,
    #[iden = "ALBUMART"]
    NoAlbumArt,
    #[iden = "ALBUMARTSAVED"]
    NoAlbumArtSaved,
    #[iden = "ALBUMID"]
    NoAlbumId,
    #[iden = "ALBUMARTIST"]
    NoAlbumArtist,
    #[iden = "ALBUMARTISTID"]
    NoAlbumArtistId,
    #[iden = "TRACKTITLE"]
    NoTrackTitle,
    #[iden = "TRACKNUM"]
    NoTrackNum,
    #[iden = "TRACKRELEASEID"]
    NoTrackReleaseId,
    #[iden = "TRACKRELEASEGROUPID"]
    NoTrackReleaseGroupId,
    #[iden = "TRACKRECORDINGID"]
    NoTrackRecordingId,
    #[iden = "NOTAGS"]
    NoTag,
    #[iden = "NOYEAR"]
    NoYear,
    #[iden = "DURATION"]
    Duration,
}

const APP_DIR: &str = "librmo";

#[derive(Serialize, Deserialize, Debug)]
pub struct Settings {
    pub database_url: String,
    pub cache_dir: String,
    pub config_dir: String,
    pub album_art_dir: String,
    pub album_art_group_dir: String,
}
#[allow(dead_code)]
pub async fn get_cache_dir() -> Result<String, CustomError> {
    let config = read_config().expect("Failed to set up application settings");
    let settings = config.try_deserialize::<Settings>().unwrap();
    Ok(settings.cache_dir)
}

pub fn init() -> Result<Config, CustomError> {
    fs::create_dir_all(build_config_dir())?;
    fs::create_dir_all(build_cache_dir())?;
    fs::create_dir_all(build_album_art_dir())?;
    fs::create_dir_all(build_full_album_art_dir())?;
    fs::create_dir_all(build_album_art_group_dir())?;
    fs::create_dir_all(build_full_album_art_group_dir())?;
    read_config()
}

pub fn read_config() -> Result<Config, CustomError> {
    let default_settings = Settings {
        database_url: build_database_url(),
        cache_dir: build_cache_dir(),
        config_dir: build_config_dir(),
        album_art_dir: build_album_art_dir(),
        album_art_group_dir: build_album_art_group_dir(),
    };
    Ok(Config::builder()
        .set_default("database_url", default_settings.database_url)?
        .set_default("cache_dir", default_settings.cache_dir)?
        .set_default("config_dir", default_settings.config_dir)?
        .set_default("album_art_dir", default_settings.album_art_dir)?
        .set_default("album_art_group_dir", default_settings.album_art_group_dir)?
        .build()?)
}

pub async fn get_db_connection() -> Result<sea_orm::prelude::DatabaseConnection, CustomError> {
    let config = read_config()?;
    let settings = config.try_deserialize::<Settings>()?;
    let db = Database::connect(settings.database_url).await?;
    Ok(db)
}

pub fn get_db_url() -> Result<String, CustomError> {
    Ok(build_database_url())
}

pub struct AlbumArtDirs {
    pub album_art: String,
    pub album_art_full: String,
    pub album_art_group: String,
    pub album_art_group_full: String,
}

pub fn get_album_art_dirs() -> AlbumArtDirs {
    AlbumArtDirs {
        album_art: build_album_art_dir(),
        album_art_full: build_full_album_art_dir(),
        album_art_group: build_album_art_group_dir(),
        album_art_group_full: build_full_album_art_group_dir(),
    }
}

pub struct AlbumArtFiles {
    pub album_art: Vec<String>,
    pub album_art_full: Vec<String>,
    pub album_art_group: Vec<String>,
    pub album_art_group_full: Vec<String>,
}

pub fn get_album_art_files() -> AlbumArtFiles {
    AlbumArtFiles {
        album_art: fs::read_dir(build_album_art_dir())
            .unwrap()
            .filter(|p| p.as_ref().unwrap().path().is_file())
            .map(|f| f.unwrap().path().display().to_string())
            .collect(),
        album_art_full: fs::read_dir(build_full_album_art_dir())
            .unwrap()
            .filter(|p| p.as_ref().unwrap().path().is_file())
            .map(|f| f.unwrap().path().display().to_string())
            .collect(),
        album_art_group: fs::read_dir(build_album_art_group_dir())
            .unwrap()
            .filter(|p| p.as_ref().unwrap().path().is_file())
            .map(|f| f.unwrap().path().display().to_string())
            .collect(),
        album_art_group_full: fs::read_dir(build_full_album_art_group_dir())
            .unwrap()
            .filter(|p| p.as_ref().unwrap().path().is_file())
            .map(|f| f.unwrap().path().display().to_string())
            .collect(),
    }
}

fn build_database_url() -> String {
    format!("sqlite:{}/media.db", build_config_dir())
}

fn build_config_dir() -> String {
    let key = "LIBRMO_DB_DIR";
    let val = env::var(key);
    return match val {
        Ok(x) => x,
        Err(_) => format!(
            "{}/{}",
            dirs::config_dir()
                .unwrap_or_else(|| ".config".into())
                .to_str()
                .unwrap(),
            APP_DIR
        ),
    };
}

fn build_album_art_dir() -> String {
    format!("{}/album_art", build_cache_dir(),)
}
fn build_full_album_art_dir() -> String {
    format!("{}/album_art_full", build_cache_dir(),)
}
fn build_album_art_group_dir() -> String {
    format!("{}/album_art_group", build_cache_dir(),)
}
fn build_full_album_art_group_dir() -> String {
    format!("{}/album_art_group_full", build_cache_dir(),)
}
fn build_cache_dir() -> String {
    format!(
        "{}/{}",
        dirs::cache_dir()
            .unwrap_or_else(|| ".cache".into())
            .to_str()
            .unwrap(),
        APP_DIR
    )
}