Skip to content

Commit

Permalink
cleaned up mess in main.rs and added settings wrapper
Browse files Browse the repository at this point in the history
  • Loading branch information
0PandaDEV committed Apr 12, 2024
1 parent 6de099a commit afb32d7
Show file tree
Hide file tree
Showing 10 changed files with 281 additions and 142 deletions.
2 changes: 1 addition & 1 deletion lib/Download.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
export default class Download {
static async downloadVideoAsMp3(url: string, name: string): Promise<void> {
try {
await window.__TAURI__.core.invoke("download_wrapper", {
await window.__TAURI__.core.invoke("download", {
url,
name,
});
Expand Down
2 changes: 1 addition & 1 deletion lib/Player.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { readSongs } from './Config';
import { readSongs } from './Songs';

class Player {
private static instance: Player;
Expand Down
45 changes: 45 additions & 0 deletions lib/Settings.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
interface EQSettings {
[key: string]: string;
}

class Settings {
static async readSettings(): Promise<Map<string, string>> {
try {
const settings: { [key: string]: string } = await window.__TAURI__.invoke('read_settings');
return new Map(Object.entries(settings));
} catch (error) {
console.error('Error reading settings:', error);
throw error;
}
}

static async readEQSettings(): Promise<Map<string, string>> {
try {
const eqSettings: { [key: string]: string } = await window.__TAURI__.invoke('read_eq_settings');
return new Map(Object.entries(eqSettings));
} catch (error) {
console.error('Error reading EQ settings:', error);
throw error;
}
}

static async writeEQSettings(eqSettings: EQSettings): Promise<void> {
try {
await window.__TAURI__.invoke('write_eq_settings', { eqSettings });
} catch (error) {
console.error('Error writing EQ settings:', error);
throw error;
}
}

static async updateUserSetting(key: string, value: string): Promise<void> {
try {
await window.__TAURI__.invoke('update_user_setting', { key, value });
} catch (error) {
console.error('Error updating user setting:', error);
throw error;
}
}
}

export default Settings;
File renamed without changes.
2 changes: 1 addition & 1 deletion pages/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@

<script setup>
import { onMounted, ref } from "vue";
import { readSongs } from "~/lib/Config.ts";
import { readSongs } from "~/lib/Songs.ts";
import Player from "~/lib/Player.ts";
const songs = ref([]);
Expand Down
115 changes: 56 additions & 59 deletions src-tauri/src/config.rs
Original file line number Diff line number Diff line change
@@ -1,66 +1,40 @@
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::fs::{self, File};
use std::io::Error;
use std::io::Error as IoError; // Renamed for clarity
use std::path::PathBuf;
use std::collections::HashMap;
use tauri::Error as TauriError; // Import Tauri's Error type

#[derive(Serialize, Deserialize)]
struct Song {
id: String,
title: String,
artist: String,
length: u32,
cover: String,
date_added: String,
}

#[derive(Serialize, Deserialize)]
pub struct SongsConfig {
songs: HashMap<String, Song>,
pub struct UserSettings {
settings: HashMap<String, String>,
}

impl SongsConfig {
fn new() -> Self {
SongsConfig {
songs: HashMap::new(),
impl UserSettings {
pub fn new() -> Self {
UserSettings {
settings: HashMap::new(),
}
}

fn load(path: &PathBuf) -> Result<Self, Error> {
pub fn load(path: &PathBuf) -> Result<Self, IoError> {
let file = File::open(path)?;
let config = serde_json::from_reader(file)?;
Ok(config)
}

fn save(&self, path: &PathBuf) -> Result<(), Error> {
pub fn save(&self, path: &PathBuf) -> Result<(), IoError> {
let file = File::create(path)?;
serde_json::to_writer_pretty(file, &self)?;
Ok(())
}

fn add_song(
&mut self,
id: String,
title: String,
artist: String,
length: u32,
cover: String,
date_added: String,
) {
let song_id = id.clone(); // Clone `id` before moving it
let song = Song {
id, // `id` is moved here
title,
artist,
length,
cover,
date_added,
};
self.songs.insert(song_id, song); // Use `song_id` here
pub fn update_setting(&mut self, key: String, value: String) {
self.settings.insert(key, value);
}
}

pub fn get_config_path() -> PathBuf {
pub fn get_settings_path() -> PathBuf {
let mut path = PathBuf::new();
match std::env::consts::OS {
"macos" | "linux" => {
Expand All @@ -73,35 +47,58 @@ pub fn get_config_path() -> PathBuf {
}
_ => {}
}
path.push("songs.json");
path.push("settings.json");
path
}

pub fn write_song(
id: String,
title: String,
artist: String,
length: u32,
cover: String,
date_added: String,
) -> Result<(), Error> {
let path = get_config_path();
#[tauri::command]
pub fn update_user_setting(key: String, value: String) -> Result<(), TauriError> {
let path = get_settings_path();
if !path.exists() {
fs::create_dir_all(path.parent().unwrap())?;
File::create(&path)?;
SongsConfig::new().save(&path)?;
UserSettings::new().save(&path)?;
}
let mut config = SongsConfig::load(&path)?;
config.add_song(id, title, artist, length, cover, date_added);
config.save(&path)
let mut settings = UserSettings::load(&path)?;
settings.update_setting(key, value);
settings.save(&path).map_err(TauriError::from)
}

pub fn read_songs() -> Result<SongsConfig, Error> {
let path = get_config_path();
#[tauri::command]
pub fn read_settings() -> Result<HashMap<String, String>, TauriError> {
let path = get_settings_path();
if !path.exists() {
return Err(TauriError::from(IoError::new(std::io::ErrorKind::NotFound, "Settings file not found")));
}
let settings = UserSettings::load(&path)?;
Ok(settings.settings)
}

#[tauri::command]
pub fn read_eq_settings() -> Result<HashMap<String, String>, TauriError> {
let path = get_settings_path();
if !path.exists() {
return Err(TauriError::from(IoError::new(std::io::ErrorKind::NotFound, "Settings file not found")));
}
let settings = UserSettings::load(&path)?;
if let Some(eq_settings) = settings.settings.get("eq") {
let eq: HashMap<String, String> = serde_json::from_str(eq_settings).map_err(|_| TauriError::from(IoError::new(std::io::ErrorKind::InvalidData, "Failed to parse EQ settings")))?;
Ok(eq)
} else {
Err(TauriError::from(IoError::new(std::io::ErrorKind::NotFound, "EQ settings not found")))
}
}

#[tauri::command]
pub fn write_eq_settings(eq_settings: HashMap<String, String>) -> Result<(), TauriError> {
let path = get_settings_path();
if !path.exists() {
fs::create_dir_all(path.parent().unwrap())?;
File::create(&path)?;
SongsConfig::new().save(&path)?;
UserSettings::new().save(&path)?;
}
SongsConfig::load(&path)
}
let mut settings = UserSettings::load(&path)?;
let eq_settings_str = serde_json::to_string(&eq_settings).map_err(TauriError::from)?;
settings.update_setting("eq".to_string(), eq_settings_str);
settings.save(&path).map_err(TauriError::from)
}
36 changes: 18 additions & 18 deletions src-tauri/src/downloader.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
use crate::config;
use anyhow::{anyhow, Result};
use crate::songs;
use anyhow::anyhow;
use chrono::Local;
use image::{self, ImageFormat};
use reqwest::Client;
use serde::Deserialize;
use std::fs::{self, File};
use std::path::PathBuf;
use rusty_ytdl::Video;
use tauri::Error as TauriError;

#[derive(Debug, Deserialize)]
struct ApiResponse {
Expand All @@ -26,9 +27,8 @@ struct ApiItem {
}

#[tauri::command]
pub async fn download(url: String, name: String) -> Result<()> {

let video = Video::new(url.clone()).map_err(|e| anyhow!(e.to_string()))?;
pub async fn download(url: String, name: String) -> Result<(), TauriError> {
let video = Video::new(url.clone()).map_err(|e| TauriError::from(anyhow!(e.to_string())))?;

let client = Client::new();

Expand All @@ -45,26 +45,26 @@ pub async fn download(url: String, name: String) -> Result<()> {
_ => {}
}
if !base_path.exists() {
fs::create_dir_all(&base_path)?;
fs::create_dir_all(&base_path).map_err(|e| TauriError::from(anyhow!(e.to_string())))?;
}

let mut path = base_path.clone();
path.push("Songs");
if !path.exists() {
fs::create_dir_all(&path)?;
fs::create_dir_all(&path).map_err(|e| TauriError::from(anyhow!(e.to_string())))?;
}
path.push(&name);

video.download(&path).await.map_err(|e| anyhow!(e.to_string()))?;
video.download(&path).await.map_err(|e| TauriError::from(anyhow!(e.to_string())))?;

let api_url = format!(
"https://wireway.ch/api/musicAPI/search/?q={}",
url.trim_start_matches(
"https://youtube.com/watch?v="
)
);
let resp_body = reqwest::get(&api_url).await?.text().await?;
let api_response: ApiResponse = serde_json::from_str(&resp_body)?;
let resp_body = reqwest::get(&api_url).await.map_err(|e| TauriError::from(anyhow!(e.to_string())))?.text().await.map_err(|e| TauriError::from(anyhow!(e.to_string())))?;
let api_response: ApiResponse = serde_json::from_str(&resp_body).map_err(|e| TauriError::from(anyhow!(e.to_string())))?;

let mut cover_path = String::new();

Expand All @@ -88,31 +88,31 @@ pub async fn download(url: String, name: String) -> Result<()> {
let date_added = Local::now().format("%Y-%m-%d %H:%M:%S").to_string();

if !cover.is_empty() {
let response = client.get(&cover).send().await?;
let response = client.get(&cover).send().await.map_err(|e| TauriError::from(anyhow!(e.to_string())))?;
if response.status().is_success() {
let body = response.bytes().await?;
let image = image::load_from_memory(&body)?;
let body = response.bytes().await.map_err(|e| TauriError::from(anyhow!(e.to_string())))?;
let image = image::load_from_memory(&body).map_err(|e| TauriError::from(anyhow!(e.to_string())))?;
let covers_path = base_path.join("Covers");
if !covers_path.exists() {
fs::create_dir_all(&covers_path)?;
fs::create_dir_all(&covers_path).map_err(|e| TauriError::from(anyhow!(e.to_string())))?;
}
let cover_file_name = format!("{}.png", video_id);
let cover_file_path = covers_path.join(&cover_file_name);
let mut file = File::create(&cover_file_path)?;
image.write_to(&mut file, ImageFormat::Png)?;
let mut file = File::create(&cover_file_path).map_err(|e| TauriError::from(anyhow!(e.to_string())))?;
image.write_to(&mut file, ImageFormat::Png).map_err(|e| TauriError::from(anyhow!(e.to_string())))?;
cover_path = format!("/Covers/{}", cover_file_name);
}
}

config::write_song(
songs::write_song(
video_id.to_string(),
title,
artist,
length,
cover_path,
date_added,
)
.map_err(|e| anyhow!(e.to_string()))?;
.map_err(|e| TauriError::from(anyhow!(e.to_string())))?;
}

println!("Downloaded and tagged: {}", path.display());
Expand Down
Loading

0 comments on commit afb32d7

Please sign in to comment.