gardesk/garnotify / e51733b

Browse files

garnotifyctl: add CLI with subcommands

Authored by mfwolffe <wolffemf@dukes.jmu.edu>
SHA
e51733b76a09185ff9116988be2911759e833f56
Parents
a6161fe
Tree
f0d9e1f

1 changed file

StatusFile+-
A garnotifyctl/src/main.rs 105 0
garnotifyctl/src/main.rsadded
@@ -0,0 +1,105 @@
1
+//! garnotifyctl - Control utility for garnotify daemon
2
+
3
+use anyhow::Result;
4
+use clap::{Parser, Subcommand};
5
+
6
+mod ipc;
7
+
8
+/// garnotifyctl - Control utility for garnotify
9
+#[derive(Parser)]
10
+#[command(name = "garnotifyctl")]
11
+#[command(about = "Control utility for garnotify daemon", long_about = None)]
12
+struct Cli {
13
+    #[command(subcommand)]
14
+    command: Commands,
15
+}
16
+
17
+#[derive(Subcommand)]
18
+enum Commands {
19
+    /// Close a notification by ID
20
+    Close {
21
+        /// Notification ID to close (omit to close most recent)
22
+        id: Option<u32>,
23
+    },
24
+    /// Close all notifications
25
+    CloseAll,
26
+    /// Pop and redisplay the most recent notification from history
27
+    HistoryPop,
28
+    /// Clear notification history
29
+    HistoryClear,
30
+    /// Set Do Not Disturb mode
31
+    SetPaused {
32
+        /// Enable or disable DND ("true" or "false")
33
+        #[arg(value_parser = ["true", "false"])]
34
+        paused: String,
35
+        /// Pause level: 0=show all, 1=critical only, 2=show none
36
+        #[arg(short, long, default_value = "2")]
37
+        level: u8,
38
+    },
39
+    /// Check if Do Not Disturb is enabled
40
+    IsPaused,
41
+    /// Get count of active notifications
42
+    Count,
43
+    /// List active notifications
44
+    List {
45
+        /// Output as JSON
46
+        #[arg(short, long)]
47
+        json: bool,
48
+    },
49
+    /// Enable a rule by name
50
+    RuleEnable {
51
+        /// Rule name to enable
52
+        name: String,
53
+    },
54
+    /// Disable a rule by name
55
+    RuleDisable {
56
+        /// Rule name to disable
57
+        name: String,
58
+    },
59
+    /// Reload configuration
60
+    Reload,
61
+    /// Get daemon status
62
+    Status,
63
+    /// Stop the daemon
64
+    Quit,
65
+}
66
+
67
+fn main() -> Result<()> {
68
+    let cli = Cli::parse();
69
+
70
+    let response = match cli.command {
71
+        Commands::Close { id } => ipc::send_command(&ipc::Command::Close { id })?,
72
+        Commands::CloseAll => ipc::send_command(&ipc::Command::CloseAll)?,
73
+        Commands::HistoryPop => ipc::send_command(&ipc::Command::HistoryPop)?,
74
+        Commands::HistoryClear => ipc::send_command(&ipc::Command::HistoryClear)?,
75
+        Commands::SetPaused { paused, level } => {
76
+            let paused = paused == "true";
77
+            ipc::send_command(&ipc::Command::SetPaused { paused, level })?
78
+        }
79
+        Commands::IsPaused => ipc::send_command(&ipc::Command::IsPaused)?,
80
+        Commands::Count => ipc::send_command(&ipc::Command::Count)?,
81
+        Commands::List { json: _ } => ipc::send_command(&ipc::Command::List)?,
82
+        Commands::RuleEnable { name } => ipc::send_command(&ipc::Command::RuleEnable { name })?,
83
+        Commands::RuleDisable { name } => ipc::send_command(&ipc::Command::RuleDisable { name })?,
84
+        Commands::Reload => ipc::send_command(&ipc::Command::Reload)?,
85
+        Commands::Status => ipc::send_command(&ipc::Command::Status)?,
86
+        Commands::Quit => ipc::send_command(&ipc::Command::Quit)?,
87
+    };
88
+
89
+    if response.success {
90
+        if let Some(ref msg) = response.message {
91
+            println!("{}", msg);
92
+        }
93
+        if let Some(ref data) = response.data {
94
+            println!("{}", serde_json::to_string_pretty(data)?);
95
+        }
96
+        if response.message.is_none() && response.data.is_none() {
97
+            println!("OK");
98
+        }
99
+    } else {
100
+        eprintln!("Error: {}", response.message.as_deref().unwrap_or("Unknown error"));
101
+        std::process::exit(1);
102
+    }
103
+
104
+    Ok(())
105
+}