From ce1a48639fcd87204a4c770b8199c48ba26d0691 Mon Sep 17 00:00:00 2001 From: inorishio Date: Mon, 23 Mar 2026 13:43:30 +0100 Subject: [PATCH] Clean up --- .gitignore | 4 + Cargo.lock | 16 -- Cargo.toml | 18 -- Config/Config.qml | 18 -- Config/Pets.qml | 38 ---- General.qml | 38 ---- ideskpet | 379 ---------------------------------- src/bin/ideskpet.rs | 490 -------------------------------------------- src/main.rs | 186 ----------------- 9 files changed, 4 insertions(+), 1183 deletions(-) create mode 100644 .gitignore delete mode 100644 Cargo.lock delete mode 100644 Cargo.toml delete mode 100644 Config/Config.qml delete mode 100644 Config/Pets.qml delete mode 100644 General.qml delete mode 100644 ideskpet delete mode 100644 src/bin/ideskpet.rs delete mode 100644 src/main.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..959095c --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +# Generated by Cargo +# will have compiled files and executables +debug +target diff --git a/Cargo.lock b/Cargo.lock deleted file mode 100644 index fc9ef66..0000000 --- a/Cargo.lock +++ /dev/null @@ -1,16 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "ideskpet-installer" -version = "1.0.0" -dependencies = [ - "libc", -] - -[[package]] -name = "libc" -version = "0.2.183" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b646652bf6661599e1da8901b3b9522896f01e736bad5f723fe7a3a27f899d" diff --git a/Cargo.toml b/Cargo.toml deleted file mode 100644 index a1feaa1..0000000 --- a/Cargo.toml +++ /dev/null @@ -1,18 +0,0 @@ -[package] -name = "ideskpet-installer" -version = "1.0.0" -edition = "2021" -description = "Installer and CLI for I-DeskPet desktop pet application" -authors = ["InoriShio"] -license = "MIT" - -[[bin]] -name = "ideskpet-installer" -path = "src/main.rs" - -[[bin]] -name = "ideskpet" -path = "src/bin/ideskpet.rs" - -[target.'cfg(unix)'.dependencies] -libc = "0.2" diff --git a/Config/Config.qml b/Config/Config.qml deleted file mode 100644 index 8d0109f..0000000 --- a/Config/Config.qml +++ /dev/null @@ -1,18 +0,0 @@ - - FileView { - id: watcher - path: root.configPath - - watchChanges: true - - onFileChanged: reload() - - onAdapterUpdated: writeAdapter() - - JsonAdapter { - id: adapter - - property string gifFolder: Quickshell.shellDir + "/Gifs" - property real maxScaling: 1 - } - } diff --git a/Config/Pets.qml b/Config/Pets.qml deleted file mode 100644 index 7eb883b..0000000 --- a/Config/Pets.qml +++ /dev/null @@ -1,38 +0,0 @@ - - FileView { - id: watcher - path: configPath - - property string name: gifItem.fileBaseName + ".json" - property string configDir: Quickshell.env("HOME") + "/.config/I-DeskPet/" - property string configPath: configDir + name - - onLoaded: { - if ( gifSaved.zIndex === -1 ) gifSaved.zIndex = gifItem.index - gifItem.x = gifSaved.positionX - gifItem.y = gifSaved.positionY - gifItem.loaded = true - } - - onLoadFailed: { - gifSaved.zIndex = gifItem.index - writeAdapter() - gifItem.loaded = true - } - - watchChanges: true - - onFileChanged: reload() - - onAdapterUpdated: writeAdapter() - - JsonAdapter { - id: gifSaved - - property real scaling: 1 - property int positionX: 0 - property int positionY: 0 - property int zIndex: -1 - } - } - } diff --git a/General.qml b/General.qml deleted file mode 100644 index 2856121..0000000 --- a/General.qml +++ /dev/null @@ -1,38 +0,0 @@ - - FileView { - id: watcher - path: configPath - - property string name: gifItem.fileBaseName + ".json" - property string configDir: Quickshell.env("HOME") + "/.config/I-DeskPet/" - property string configPath: configDir + name - - onLoaded: { - if ( gifSaved.zIndex === -1 ) gifSaved.zIndex = gifItem.index - gifItem.x = gifSaved.positionX - gifItem.y = gifSaved.positionY - gifItem.loaded = true - } - - onLoadFailed: { - gifSaved.zIndex = gifItem.index - writeAdapter() - gifItem.loaded = true - } - - watchChanges: true - - onFileChanged: reload() - - onAdapterUpdated: writeAdapter() - - JsonAdapter { - id: gifSaved - - property real scaling: 1 - property int positionX: 0 - property int positionY: 0 - property int zIndex: -1 - } - } -} diff --git a/ideskpet b/ideskpet deleted file mode 100644 index 6be033e..0000000 --- a/ideskpet +++ /dev/null @@ -1,379 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -# ============================================================================= -# ideskpet - CLI tool for I-DeskPet Quickshell application -# ============================================================================= - -VERSION="1.0.0" -REPO_URL="https://github.com/InoriShio/I-DeskPet" -INSTALL_DIR="/etc/xdg/quickshell/I-DeskPet" -LOG_DIR="$HOME/.local/state/ideskpet" -LOG_FILE="$LOG_DIR/ideskpet.log" -APP_ID="I-DeskPet" - -# Colors -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -BLUE='\033[0;34m' -BOLD='\033[1m' -NC='\033[0m' - -# ============================================================================= -# Helper Functions -# ============================================================================= - -print_help() { - cat << EOF -${BOLD}ideskpet${NC} - CLI tool for I-DeskPet desktop pet application (v${VERSION}) - -${BOLD}USAGE:${NC} - ideskpet [OPTIONS] - -${BOLD}COMMANDS:${NC} - ${GREEN}start${NC} Start the I-DeskPet application - ${GREEN}stop${NC} Stop the running I-DeskPet instance - ${GREEN}restart${NC} Restart the I-DeskPet application - ${GREEN}log${NC} Show application logs - ${GREEN}update${NC} Update I-DeskPet from GitHub - -${BOLD}HYPRLAND SHORTCUTS:${NC} - ${BLUE}toggle-layer${NC} Toggle pet between overlay/bottom layer - ${BLUE}toggle-region${NC} Toggle click-through mode - ${BLUE}cycle-zindex${NC} Cycle z-index of hovered gif - -${BOLD}LOG OPTIONS:${NC} - ideskpet log Show last 50 lines of logs - ideskpet log -f Follow logs in real-time (Ctrl+C to exit) - ideskpet log -n Show last N lines of logs - -${BOLD}OTHER:${NC} - -h, --help Show this help message - -v, --version Show version - -${BOLD}CONFIGURATION:${NC} - User config: ~/.config/I-DeskPet/config.json - - Example config.json: - { - "gifFolder": "/home/user/Pictures/Pets", - "maxScaling": 1 - } - -${BOLD}HYPRLAND KEYBIND EXAMPLES:${NC} - bind = CTRL, mouse:274, global, I-DeskPet:toggle-Region - bind = SHIFT, mouse:274, global, I-DeskPet:toggle-Layer - bind = \$mainMod, Z, global, I-DeskPet:cycle-zIndex - -${BOLD}INSTALLATION:${NC} - sudo cp ideskpet /usr/bin/ideskpet - sudo chmod +x /usr/bin/ideskpet - -EOF -} - -print_version() { - echo "ideskpet v${VERSION}" -} - -info() { - echo -e "${GREEN}[INFO]${NC} $1" -} - -warn() { - echo -e "${YELLOW}[WARN]${NC} $1" -} - -error() { - echo -e "${RED}[ERROR]${NC} $1" >&2 -} - -is_running() { - pgrep -f "quickshell.*${APP_ID}" > /dev/null 2>&1 -} - -get_pid() { - pgrep -f "quickshell.*${APP_ID}" 2>/dev/null || true -} - -ensure_log_dir() { - if [[ ! -d "$LOG_DIR" ]]; then - mkdir -p "$LOG_DIR" - fi -} - -ensure_installed() { - if [[ ! -d "$INSTALL_DIR" ]]; then - warn "I-DeskPet is not installed at ${INSTALL_DIR}" - info "Cloning from ${REPO_URL}..." - - # Check if /etc/xdg/quickshell exists - if [[ ! -d "/etc/xdg/quickshell" ]]; then - info "Creating /etc/xdg/quickshell directory (requires sudo)..." - sudo mkdir -p /etc/xdg/quickshell - fi - - info "Cloning repository (requires sudo)..." - sudo git clone "$REPO_URL" "$INSTALL_DIR" - - if [[ $? -eq 0 ]]; then - info "Successfully installed I-DeskPet to ${INSTALL_DIR}" - else - error "Failed to clone repository" - exit 1 - fi - fi -} - -check_dependencies() { - local missing=() - - if ! command -v quickshell &> /dev/null; then - missing+=("quickshell") - fi - - if ! command -v hyprctl &> /dev/null; then - missing+=("hyprctl (hyprland)") - fi - - if ! command -v git &> /dev/null; then - missing+=("git") - fi - - if [[ ${#missing[@]} -gt 0 ]]; then - error "Missing dependencies: ${missing[*]}" - echo "Please install the missing packages and try again." - exit 1 - fi -} - -# ============================================================================= -# Command Implementations -# ============================================================================= - -cmd_start() { - check_dependencies - ensure_installed - ensure_log_dir - - if is_running; then - warn "I-DeskPet is already running (PID: $(get_pid))" - echo "Use 'ideskpet restart' to restart, or 'ideskpet stop' to stop." - exit 1 - fi - - info "Starting I-DeskPet..." - - # Start quickshell in background, redirect output to log file - nohup quickshell -p "$INSTALL_DIR" >> "$LOG_FILE" 2>&1 & - disown - - # Wait a moment and check if it started successfully - sleep 1 - - if is_running; then - info "I-DeskPet started successfully (PID: $(get_pid))" - echo "Use 'ideskpet log -f' to view logs" - else - error "Failed to start I-DeskPet" - echo "Check logs with 'ideskpet log' for details" - exit 1 - fi -} - -cmd_stop() { - if ! is_running; then - warn "I-DeskPet is not running" - exit 0 - fi - - local pid - pid=$(get_pid) - - info "Stopping I-DeskPet (PID: ${pid})..." - - # Try graceful shutdown first - kill "$pid" 2>/dev/null || true - - # Wait up to 5 seconds for graceful shutdown - local count=0 - while is_running && [[ $count -lt 10 ]]; do - sleep 0.5 - ((count++)) - done - - # Force kill if still running - if is_running; then - warn "Graceful shutdown failed, force killing..." - kill -9 "$pid" 2>/dev/null || true - sleep 0.5 - fi - - if is_running; then - error "Failed to stop I-DeskPet" - exit 1 - else - info "I-DeskPet stopped successfully" - fi -} - -cmd_restart() { - info "Restarting I-DeskPet..." - - if is_running; then - cmd_stop - fi - - sleep 0.5 - cmd_start -} - -cmd_log() { - ensure_log_dir - - if [[ ! -f "$LOG_FILE" ]]; then - warn "No log file found at ${LOG_FILE}" - echo "Start I-DeskPet first with 'ideskpet start'" - exit 1 - fi - - local follow=false - local lines=50 - - # Parse arguments - while [[ $# -gt 0 ]]; do - case "$1" in - -f|--follow) - follow=true - shift - ;; - -n|--lines) - if [[ -n "${2:-}" ]] && [[ "$2" =~ ^[0-9]+$ ]]; then - lines="$2" - shift 2 - else - error "Option -n requires a numeric argument" - exit 1 - fi - ;; - *) - error "Unknown log option: $1" - echo "Usage: ideskpet log [-f] [-n ]" - exit 1 - ;; - esac - done - - if [[ "$follow" == true ]]; then - info "Following logs (Ctrl+C to exit)..." - echo "---" - tail -n "$lines" -f "$LOG_FILE" - else - tail -n "$lines" "$LOG_FILE" - fi -} - -cmd_update() { - check_dependencies - - if [[ ! -d "$INSTALL_DIR" ]]; then - error "I-DeskPet is not installed at ${INSTALL_DIR}" - echo "Run 'ideskpet start' to install it first." - exit 1 - fi - - info "Updating I-DeskPet from GitHub..." - - cd "$INSTALL_DIR" - - # Check for local changes - if ! sudo git diff --quiet 2>/dev/null; then - warn "Local changes detected. They may be overwritten." - fi - - sudo git pull - - if [[ $? -eq 0 ]]; then - info "Update completed successfully" - - if is_running; then - echo "" - warn "I-DeskPet is currently running." - echo "Run 'ideskpet restart' to apply changes." - fi - else - error "Update failed" - exit 1 - fi -} - -cmd_shortcut() { - local shortcut="$1" - - if ! command -v hyprctl &> /dev/null; then - error "hyprctl not found. Are you running Hyprland?" - exit 1 - fi - - if ! is_running; then - warn "I-DeskPet is not running" - echo "Start it first with 'ideskpet start'" - exit 1 - fi - - info "Triggering shortcut: ${APP_ID}:${shortcut}" - hyprctl dispatch global "${APP_ID}:${shortcut}" -} - -# ============================================================================= -# Main Entry Point -# ============================================================================= - -main() { - local cmd="${1:-}" - - case "$cmd" in - start) - cmd_start - ;; - stop) - cmd_stop - ;; - restart) - cmd_restart - ;; - log) - shift - cmd_log "$@" - ;; - update) - cmd_update - ;; - toggle-layer) - cmd_shortcut "toggle-Layer" - ;; - toggle-region) - cmd_shortcut "toggle-Region" - ;; - cycle-zindex) - cmd_shortcut "cycle-zIndex" - ;; - -h|--help|help) - print_help - ;; - -v|--version|version) - print_version - ;; - "") - print_help - ;; - *) - error "Unknown command: ${cmd}" - echo "Run 'ideskpet --help' for usage information." - exit 1 - ;; - esac -} - -main "$@" diff --git a/src/bin/ideskpet.rs b/src/bin/ideskpet.rs deleted file mode 100644 index f4b199d..0000000 --- a/src/bin/ideskpet.rs +++ /dev/null @@ -1,490 +0,0 @@ -//! I-DeskPet CLI Tool -//! -//! A command-line interface for managing the I-DeskPet desktop pet application. -//! -//! Usage: -//! ideskpet [options] -//! -//! Commands: -//! start, stop, restart, log, update, toggle-layer, toggle-region, cycle-zindex - -#[cfg(unix)] -use std::env; -#[cfg(unix)] -use std::fs; -#[cfg(unix)] -use std::io::{BufRead, BufReader}; -#[cfg(unix)] -use std::path::PathBuf; -#[cfg(unix)] -use std::process::{Command, Stdio}; -#[cfg(unix)] -use std::thread; -#[cfg(unix)] -use std::time::Duration; - -#[cfg(unix)] -const VERSION: &str = "1.0.0"; -#[cfg(unix)] -const APP_ID: &str = "I-DeskPet"; -#[cfg(unix)] -const INSTALL_DIR: &str = "/etc/xdg/quickshell/I-DeskPet"; -#[cfg(unix)] -const REPO_URL: &str = "https://github.com/InoriShio/I-DeskPet"; - -// ANSI color codes -#[cfg(unix)] -const RED: &str = "\x1b[31m"; -#[cfg(unix)] -const GREEN: &str = "\x1b[32m"; -#[cfg(unix)] -const YELLOW: &str = "\x1b[33m"; -#[cfg(unix)] -const BLUE: &str = "\x1b[34m"; -#[cfg(unix)] -const BOLD: &str = "\x1b[1m"; -#[cfg(unix)] -const NC: &str = "\x1b[0m"; - -fn main() { - #[cfg(not(unix))] - { - eprintln!("\x1b[31m[ERROR]\x1b[0m ideskpet only works on Linux/Unix systems."); - std::process::exit(1); - } - - #[cfg(unix)] - { - let args: Vec = env::args().collect(); - run_cli(&args); - } -} - -#[cfg(unix)] -fn run_cli(args: &[String]) { - if args.len() < 2 { - print_help(); - return; - } - - let command = args[1].as_str(); - - match command { - "start" => cmd_start(), - "stop" => cmd_stop(), - "restart" => cmd_restart(), - "log" => cmd_log(&args[2..]), - "update" => cmd_update(), - "toggle-layer" => cmd_shortcut("toggle-Layer"), - "toggle-region" => cmd_shortcut("toggle-Region"), - "cycle-zindex" => cmd_shortcut("cycle-zIndex"), - "-h" | "--help" | "help" => print_help(), - "-v" | "--version" | "version" => println!("ideskpet v{VERSION}"), - _ => { - eprintln!("{RED}[ERROR]{NC} Unknown command: {command}"); - eprintln!("Run 'ideskpet --help' for usage information."); - std::process::exit(1); - } - } -} - -// ============================================================================= -// Helper Functions -// ============================================================================= - -#[cfg(unix)] -fn get_log_dir() -> PathBuf { - let home = env::var("HOME").unwrap_or_else(|_| "/tmp".to_string()); - PathBuf::from(home).join(".local/state/ideskpet") -} - -#[cfg(unix)] -fn get_log_file() -> PathBuf { - get_log_dir().join("ideskpet.log") -} - -#[cfg(unix)] -fn ensure_log_dir() { - let log_dir = get_log_dir(); - if !log_dir.exists() { - if let Err(e) = fs::create_dir_all(&log_dir) { - eprintln!("{YELLOW}[WARN]{NC} Failed to create log directory: {e}"); - } - } -} - -#[cfg(unix)] -fn is_running() -> bool { - get_pid().is_some() -} - -#[cfg(unix)] -fn get_pid() -> Option { - let output = Command::new("pgrep") - .args(["-f", &format!("quickshell.*{APP_ID}")]) - .output() - .ok()?; - - if output.status.success() { - let stdout = String::from_utf8_lossy(&output.stdout); - stdout.lines().next()?.trim().parse().ok() - } else { - None - } -} - -#[cfg(unix)] -fn check_dependency(name: &str) -> bool { - Command::new("which") - .arg(name) - .stdout(Stdio::null()) - .stderr(Stdio::null()) - .status() - .map(|s| s.success()) - .unwrap_or(false) -} - -#[cfg(unix)] -fn check_dependencies() -> bool { - let mut ok = true; - let deps = ["quickshell", "hyprctl", "git"]; - - for dep in deps { - if !check_dependency(dep) { - eprintln!("{RED}[ERROR]{NC} Missing dependency: {dep}"); - ok = false; - } - } - - if !ok { - eprintln!("\nPlease install the missing dependencies and try again."); - } - - ok -} - -// ============================================================================= -// Commands -// ============================================================================= - -#[cfg(unix)] -fn cmd_start() { - if !check_dependency("quickshell") { - eprintln!("{RED}[ERROR]{NC} quickshell is not installed"); - std::process::exit(1); - } - - if is_running() { - let pid = get_pid().unwrap(); - eprintln!("{YELLOW}[WARN]{NC} I-DeskPet is already running (PID: {pid})"); - eprintln!("Use 'ideskpet restart' to restart, or 'ideskpet stop' to stop."); - std::process::exit(1); - } - - // Check if install directory exists - if !std::path::Path::new(INSTALL_DIR).exists() { - eprintln!("{RED}[ERROR]{NC} I-DeskPet is not installed at {INSTALL_DIR}"); - eprintln!("Please run the installer first: cargo run"); - std::process::exit(1); - } - - ensure_log_dir(); - let log_file = get_log_file(); - - println!("{GREEN}[INFO]{NC} Starting I-DeskPet..."); - - // Open log file for appending - let log_handle = fs::OpenOptions::new() - .create(true) - .append(true) - .open(&log_file); - - let (stdout_file, stderr_file) = match log_handle { - Ok(f) => { - let f2 = f.try_clone().unwrap_or_else(|_| { - fs::OpenOptions::new() - .create(true) - .append(true) - .open(&log_file) - .unwrap() - }); - (Stdio::from(f), Stdio::from(f2)) - } - Err(e) => { - eprintln!("{YELLOW}[WARN]{NC} Could not open log file: {e}"); - (Stdio::null(), Stdio::null()) - } - }; - - // Spawn quickshell process - let result = Command::new("nohup") - .args(["quickshell", "-p", INSTALL_DIR]) - .stdout(stdout_file) - .stderr(stderr_file) - .stdin(Stdio::null()) - .spawn(); - - match result { - Ok(_child) => { - // Wait a moment to check if it started - thread::sleep(Duration::from_secs(1)); - - if is_running() { - let pid = get_pid().unwrap_or(0); - println!("{GREEN}[OK]{NC} I-DeskPet started successfully (PID: {pid})"); - println!("Use 'ideskpet log -f' to view logs"); - } else { - eprintln!("{RED}[ERROR]{NC} I-DeskPet failed to start"); - eprintln!("Check logs with 'ideskpet log' for details"); - std::process::exit(1); - } - } - Err(e) => { - eprintln!("{RED}[ERROR]{NC} Failed to start quickshell: {e}"); - std::process::exit(1); - } - } -} - -#[cfg(unix)] -fn cmd_stop() { - if !is_running() { - println!("{YELLOW}[WARN]{NC} I-DeskPet is not running"); - return; - } - - let pid = get_pid().unwrap(); - println!("{GREEN}[INFO]{NC} Stopping I-DeskPet (PID: {pid})..."); - - // Send SIGTERM - let _ = Command::new("kill").arg(pid.to_string()).status(); - - // Wait for graceful shutdown (up to 5 seconds) - for _ in 0..10 { - thread::sleep(Duration::from_millis(500)); - if !is_running() { - println!("{GREEN}[OK]{NC} I-DeskPet stopped successfully"); - return; - } - } - - // Force kill if still running - println!("{YELLOW}[WARN]{NC} Graceful shutdown failed, force killing..."); - let _ = Command::new("kill").args(["-9", &pid.to_string()]).status(); - - thread::sleep(Duration::from_millis(500)); - - if is_running() { - eprintln!("{RED}[ERROR]{NC} Failed to stop I-DeskPet"); - std::process::exit(1); - } else { - println!("{GREEN}[OK]{NC} I-DeskPet stopped successfully"); - } -} - -#[cfg(unix)] -fn cmd_restart() { - println!("{GREEN}[INFO]{NC} Restarting I-DeskPet..."); - - if is_running() { - cmd_stop(); - } - - thread::sleep(Duration::from_millis(500)); - cmd_start(); -} - -#[cfg(unix)] -fn cmd_log(args: &[String]) { - let log_file = get_log_file(); - - if !log_file.exists() { - eprintln!( - "{YELLOW}[WARN]{NC} No log file found at {}", - log_file.display() - ); - eprintln!("Start I-DeskPet first with 'ideskpet start'"); - std::process::exit(1); - } - - let mut follow = false; - let mut lines: u32 = 50; - - // Parse arguments - let mut i = 0; - while i < args.len() { - match args[i].as_str() { - "-f" | "--follow" => { - follow = true; - } - "-n" | "--lines" => { - if i + 1 < args.len() { - if let Ok(n) = args[i + 1].parse() { - lines = n; - i += 1; - } else { - eprintln!("{RED}[ERROR]{NC} Invalid number for -n option"); - std::process::exit(1); - } - } else { - eprintln!("{RED}[ERROR]{NC} -n option requires a number"); - std::process::exit(1); - } - } - _ => { - eprintln!("{RED}[ERROR]{NC} Unknown log option: {}", args[i]); - eprintln!("Usage: ideskpet log [-f] [-n ]"); - std::process::exit(1); - } - } - i += 1; - } - - if follow { - println!("{GREEN}[INFO]{NC} Following logs (Ctrl+C to exit)..."); - println!("---"); - - let status = Command::new("tail") - .args(["-n", &lines.to_string(), "-f", log_file.to_str().unwrap()]) - .status(); - - if let Err(e) = status { - eprintln!("{RED}[ERROR]{NC} Failed to tail log file: {e}"); - std::process::exit(1); - } - } else { - let status = Command::new("tail") - .args(["-n", &lines.to_string(), log_file.to_str().unwrap()]) - .status(); - - if let Err(e) = status { - eprintln!("{RED}[ERROR]{NC} Failed to read log file: {e}"); - std::process::exit(1); - } - } -} - -#[cfg(unix)] -fn cmd_update() { - if !check_dependency("git") { - eprintln!("{RED}[ERROR]{NC} git is not installed"); - std::process::exit(1); - } - - if !std::path::Path::new(INSTALL_DIR).exists() { - eprintln!("{RED}[ERROR]{NC} I-DeskPet is not installed at {INSTALL_DIR}"); - eprintln!("Please run the installer first: cargo run"); - std::process::exit(1); - } - - println!("{GREEN}[INFO]{NC} Updating I-DeskPet from GitHub..."); - - let status = Command::new("sudo") - .args(["git", "-C", INSTALL_DIR, "pull"]) - .status(); - - match status { - Ok(s) if s.success() => { - println!("{GREEN}[OK]{NC} Update completed successfully"); - - if is_running() { - println!(); - println!("{YELLOW}[WARN]{NC} I-DeskPet is currently running."); - println!("Run 'ideskpet restart' to apply changes."); - } - } - Ok(_) => { - eprintln!("{RED}[ERROR]{NC} Git pull failed"); - std::process::exit(1); - } - Err(e) => { - eprintln!("{RED}[ERROR]{NC} Failed to run git: {e}"); - std::process::exit(1); - } - } -} - -#[cfg(unix)] -fn cmd_shortcut(shortcut: &str) { - if !check_dependency("hyprctl") { - eprintln!("{RED}[ERROR]{NC} hyprctl not found. Are you running Hyprland?"); - std::process::exit(1); - } - - if !is_running() { - eprintln!("{YELLOW}[WARN]{NC} I-DeskPet is not running"); - eprintln!("Start it first with 'ideskpet start'"); - std::process::exit(1); - } - - let shortcut_full = format!("{APP_ID}:{shortcut}"); - println!("{GREEN}[INFO]{NC} Triggering shortcut: {shortcut_full}"); - - let status = Command::new("hyprctl") - .args(["dispatch", "global", &shortcut_full]) - .status(); - - match status { - Ok(s) if s.success() => { - println!("{GREEN}[OK]{NC} Shortcut triggered"); - } - Ok(_) => { - eprintln!("{RED}[ERROR]{NC} Failed to trigger shortcut"); - std::process::exit(1); - } - Err(e) => { - eprintln!("{RED}[ERROR]{NC} Failed to run hyprctl: {e}"); - std::process::exit(1); - } - } -} - -#[cfg(unix)] -fn print_help() { - println!( - "{BOLD}ideskpet{NC} - CLI tool for I-DeskPet desktop pet application (v{VERSION}) - -{BOLD}USAGE:{NC} - ideskpet [OPTIONS] - -{BOLD}COMMANDS:{NC} - {GREEN}start{NC} Start the I-DeskPet application - {GREEN}stop{NC} Stop the running I-DeskPet instance - {GREEN}restart{NC} Restart the I-DeskPet application - {GREEN}log{NC} Show application logs - {GREEN}update{NC} Update I-DeskPet from GitHub - -{BOLD}HYPRLAND SHORTCUTS:{NC} - {BLUE}toggle-layer{NC} Toggle pet between overlay/bottom layer - {BLUE}toggle-region{NC} Toggle click-through mode - {BLUE}cycle-zindex{NC} Cycle z-index of hovered gif - -{BOLD}LOG OPTIONS:{NC} - ideskpet log Show last 50 lines of logs - ideskpet log -f Follow logs in real-time (Ctrl+C to exit) - ideskpet log -n Show last N lines of logs - -{BOLD}OTHER:{NC} - -h, --help Show this help message - -v, --version Show version - -{BOLD}CONFIGURATION:{NC} - User config: ~/.config/I-DeskPet/config.json - - Example config.json: - {{ - \"gifFolder\": \"/home/user/Pictures/Pets\", - \"maxScaling\": 1 - }} - -{BOLD}HYPRLAND KEYBIND EXAMPLES:{NC} - bind = CTRL, mouse:274, global, I-DeskPet:toggle-Region - bind = SHIFT, mouse:274, global, I-DeskPet:toggle-Layer - bind = $mainMod, Z, global, I-DeskPet:cycle-zIndex - -{BOLD}OTHER KEYBINDS:{NC} - Double click Reset gif size to original - Scroll Scale the gif up or down -" - ); -} diff --git a/src/main.rs b/src/main.rs deleted file mode 100644 index 538d890..0000000 --- a/src/main.rs +++ /dev/null @@ -1,186 +0,0 @@ -//! I-DeskPet Installer -//! -//! This installer builds the ideskpet CLI binary, clones/updates the repo, -//! and installs everything to the appropriate system locations. -//! -//! Run with `cargo run` on your Arch Linux machine. - -#[cfg(unix)] -use std::path::Path; -#[cfg(unix)] -use std::process::{Command, ExitStatus}; - -#[cfg(unix)] -const REPO_URL: &str = "https://github.com/InoriShio/I-DeskPet"; -#[cfg(unix)] -const INSTALL_DIR: &str = "/etc/xdg/quickshell/I-DeskPet"; -#[cfg(unix)] -const BINARY_DEST: &str = "/usr/bin/ideskpet"; - -// ANSI color codes -#[cfg(unix)] -const RED: &str = "\x1b[31m"; -#[cfg(unix)] -const GREEN: &str = "\x1b[32m"; -#[cfg(unix)] -const YELLOW: &str = "\x1b[33m"; -#[cfg(unix)] -const BLUE: &str = "\x1b[34m"; -#[cfg(unix)] -const BOLD: &str = "\x1b[1m"; -#[cfg(unix)] -const NC: &str = "\x1b[0m"; - -fn main() { - #[cfg(not(unix))] - { - eprintln!("\x1b[31m[ERROR]\x1b[0m This installer only works on Linux/Unix systems."); - eprintln!("Please run this on your Arch Linux machine."); - std::process::exit(1); - } - - #[cfg(unix)] - run_installer(); -} - -#[cfg(unix)] -fn run_installer() { - println!("{BOLD}=== I-DeskPet Installer ==={NC}\n"); - - // Step 1: Build the ideskpet binary - if !build_binary() { - std::process::exit(1); - } - - // Step 2: Clone or update the repository - if !setup_repository() { - std::process::exit(1); - } - - // Step 3: Install the binary to /usr/bin - if !install_binary() { - std::process::exit(1); - } - - // Success! - println!("\n{GREEN}{BOLD}=== Installation Complete ==={NC}\n"); - print_usage(); -} - -#[cfg(unix)] -fn build_binary() -> bool { - println!("{BLUE}[1/3]{NC} Building ideskpet binary..."); - - let status = Command::new("cargo") - .args(["build", "--release", "--bin", "ideskpet"]) - .status(); - - match status { - Ok(s) if s.success() => { - println!("{GREEN}[OK]{NC} Binary built successfully\n"); - true - } - Ok(_) => { - eprintln!("{RED}[ERROR]{NC} Failed to build binary"); - false - } - Err(e) => { - eprintln!("{RED}[ERROR]{NC} Failed to run cargo: {e}"); - false - } - } -} - -#[cfg(unix)] -fn setup_repository() -> bool { - println!("{BLUE}[2/3]{NC} Setting up repository at {INSTALL_DIR}..."); - - let install_path = Path::new(INSTALL_DIR); - let parent_dir = install_path - .parent() - .unwrap_or(Path::new("/etc/xdg/quickshell")); - - // Check if parent directory exists, create if not - if !parent_dir.exists() { - println!(" Creating directory {parent_dir:?} (requires sudo)..."); - if !run_sudo(&["mkdir", "-p", parent_dir.to_str().unwrap()]) { - return false; - } - } - - if install_path.exists() { - // Repository exists, do git pull - println!(" Repository exists, updating with git pull..."); - if !run_sudo(&["git", "-C", INSTALL_DIR, "pull"]) { - eprintln!("{YELLOW}[WARN]{NC} Git pull failed, continuing anyway..."); - } else { - println!("{GREEN}[OK]{NC} Repository updated\n"); - } - } else { - // Clone the repository - println!(" Cloning from {REPO_URL}..."); - if !run_sudo(&["git", "clone", REPO_URL, INSTALL_DIR]) { - eprintln!("{RED}[ERROR]{NC} Failed to clone repository"); - return false; - } - println!("{GREEN}[OK]{NC} Repository cloned\n"); - } - - true -} - -#[cfg(unix)] -fn install_binary() -> bool { - println!("{BLUE}[3/3]{NC} Installing binary to {BINARY_DEST}..."); - - // Get the path to the built binary - let binary_src = "target/release/ideskpet"; - - if !Path::new(binary_src).exists() { - eprintln!("{RED}[ERROR]{NC} Built binary not found at {binary_src}"); - return false; - } - - // Copy binary to /usr/bin - println!(" Copying binary (requires sudo)..."); - if !run_sudo(&["cp", binary_src, BINARY_DEST]) { - eprintln!("{RED}[ERROR]{NC} Failed to copy binary"); - return false; - } - - // Set executable permissions - println!(" Setting executable permissions..."); - if !run_sudo(&["chmod", "+x", BINARY_DEST]) { - eprintln!("{RED}[ERROR]{NC} Failed to set permissions"); - return false; - } - - println!("{GREEN}[OK]{NC} Binary installed to {BINARY_DEST}"); - true -} - -#[cfg(unix)] -fn run_sudo(args: &[&str]) -> bool { - let status = Command::new("sudo").args(args).status(); - - matches!(status, Ok(s) if s.success()) -} - -#[cfg(unix)] -fn print_usage() { - println!("{BOLD}Usage:{NC}"); - println!(" ideskpet start Start the desktop pet"); - println!(" ideskpet stop Stop the desktop pet"); - println!(" ideskpet restart Restart the desktop pet"); - println!(" ideskpet log View last 50 lines of logs"); - println!(" ideskpet log -f Follow logs in real-time"); - println!(" ideskpet log -n View last N lines of logs"); - println!(" ideskpet update Update from GitHub"); - println!(" ideskpet toggle-layer Toggle overlay/bottom layer"); - println!(" ideskpet toggle-region Toggle click-through mode"); - println!(" ideskpet cycle-zindex Cycle z-index of hovered gif"); - println!(" ideskpet --help Show full help"); - println!(); - println!("{BOLD}Get started:{NC}"); - println!(" Run {GREEN}ideskpet start{NC} to launch your desktop pet!"); -}