Files
gdown/src-tauri/src/lib.rs

138 lines
3.9 KiB
Rust
Raw Normal View History

mod engine;
use serde::{Deserialize, Serialize};
use std::fs;
use std::io::Write;
use std::path::PathBuf;
use tauri::Manager;
use engine::{
aria2_add_torrent, aria2_add_uri, aria2_change_global_option, aria2_get_task_detail,
aria2_list_tasks, aria2_pause_all, aria2_pause_task, aria2_remove_task,
aria2_remove_task_record, aria2_resume_all, aria2_resume_task, detect_aria2_binary,
engine_start, engine_status, engine_stop,
load_torrent_file,
open_path_in_file_manager, stop_engine_for_exit, EngineState,
};
#[tauri::command]
async fn focus_main_window(app: tauri::AppHandle) -> Result<(), String> {
let window = app
.get_webview_window("main")
.ok_or_else(|| "메인 창을 찾을 수 없습니다.".to_string())?;
window
.show()
.map_err(|error| format!("창 표시 실패: {error}"))?;
window
.unminimize()
.map_err(|error| format!("창 복원 실패: {error}"))?;
window
.set_focus()
.map_err(|error| format!("창 포커스 실패: {error}"))?;
Ok(())
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
struct ExternalAddRequest {
url: String,
out: Option<String>,
dir: Option<String>,
referer: Option<String>,
user_agent: Option<String>,
authorization: Option<String>,
cookie: Option<String>,
proxy: Option<String>,
split: Option<u32>,
}
fn external_add_queue_path() -> Result<PathBuf, String> {
let home = std::env::var("HOME").map_err(|err| format!("HOME 경로 확인 실패: {err}"))?;
Ok(PathBuf::from(home).join(".gdown").join("external_add_queue.jsonl"))
}
#[tauri::command]
fn take_external_add_requests() -> Result<Vec<ExternalAddRequest>, String> {
let path = external_add_queue_path()?;
let parent = path
.parent()
.ok_or_else(|| "큐 디렉터리 경로를 계산할 수 없습니다.".to_string())?;
fs::create_dir_all(parent).map_err(|err| format!("큐 디렉터리 생성 실패: {err}"))?;
if !path.exists() {
return Ok(Vec::new());
}
let content = fs::read_to_string(&path).map_err(|err| format!("큐 읽기 실패: {err}"))?;
let mut requests: Vec<ExternalAddRequest> = Vec::new();
for line in content.lines() {
let trimmed = line.trim();
if trimmed.is_empty() {
continue;
}
if let Ok(item) = serde_json::from_str::<ExternalAddRequest>(trimmed) {
requests.push(item);
}
}
let mut file = fs::OpenOptions::new()
.write(true)
.truncate(true)
.open(&path)
.map_err(|err| format!("큐 초기화 실패: {err}"))?;
file
.write_all(b"")
.map_err(|err| format!("큐 파일 쓰기 실패: {err}"))?;
Ok(requests)
}
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
tauri::Builder::default()
.manage(EngineState::default())
.plugin(tauri_plugin_dialog::init())
.plugin(tauri_plugin_deep_link::init())
.on_window_event(|window, event| {
if let tauri::WindowEvent::CloseRequested { .. } = event {
if window.label() == "main" {
let state = window.state::<EngineState>();
stop_engine_for_exit(&state);
}
}
})
.setup(|app| {
if cfg!(debug_assertions) {
app.handle().plugin(
tauri_plugin_log::Builder::default()
.level(log::LevelFilter::Info)
.build(),
)?;
}
Ok(())
})
.invoke_handler(tauri::generate_handler![
engine_start,
engine_stop,
engine_status,
detect_aria2_binary,
aria2_add_torrent,
aria2_add_uri,
aria2_change_global_option,
aria2_get_task_detail,
aria2_list_tasks,
aria2_pause_task,
aria2_resume_task,
aria2_remove_task,
aria2_remove_task_record,
aria2_pause_all,
aria2_resume_all,
load_torrent_file,
open_path_in_file_manager,
focus_main_window,
take_external_add_requests
])
.run(tauri::generate_context!())
.expect("error while running tauri application");
}