Rewrite application in rust
This commit is contained in:
parent
74f43ff919
commit
9b4938b6af
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/target
|
1016
Cargo.lock
generated
Normal file
1016
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
22
Cargo.toml
Normal file
22
Cargo.toml
Normal file
@ -0,0 +1,22 @@
|
||||
[package]
|
||||
name = "pacman-update-notify"
|
||||
version = "0.1.0-dev0"
|
||||
edition = "2021"
|
||||
publish = false
|
||||
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1.0"
|
||||
zbus = "3.2"
|
||||
zvariant = "3.7"
|
||||
argh = "0.1"
|
||||
|
||||
[dependencies.tokio]
|
||||
version = "1"
|
||||
features = ["rt-multi-thread", "sync", "process", "time", "macros"]
|
||||
|
||||
|
||||
[profile.release]
|
||||
lto = "fat"
|
||||
opt-level = 3
|
||||
strip = "debuginfo"
|
8
Gemfile
8
Gemfile
@ -1,8 +0,0 @@
|
||||
source 'https://rubygems.org'
|
||||
|
||||
# to access the notification service
|
||||
gem 'ruby-dbus'
|
||||
|
||||
group :development do
|
||||
gem 'pry'
|
||||
end
|
10
README.md
10
README.md
@ -1,11 +1,9 @@
|
||||
# Pacman Update Notifier
|
||||
Simple update notification script for pacman.
|
||||
|
||||
Simple update notifier for pacman.
|
||||
|
||||
Uses DBus to send update notifications.
|
||||
|
||||
## Setup
|
||||
Clone this repositiory.
|
||||
## Installation
|
||||
|
||||
Run `bundle install` inside the clone directory.
|
||||
|
||||
Then run `bundle exec ruby ./pacman-update-notify.rb`.
|
||||
Run `cargo install https://gitea.valeth.me/valeth/pacman-update-notify`.
|
||||
|
@ -1,49 +0,0 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
require "dbus"
|
||||
require "logger"
|
||||
|
||||
Thread.abort_on_exception = true
|
||||
|
||||
interval = ARGV.fetch(0) { 3600 }
|
||||
last_check = 0
|
||||
update_queue = Queue.new
|
||||
threads = []
|
||||
@dbus = DBus.session_bus["org.freedesktop.Notifications"]["/org/freedesktop/Notifications"]["org.freedesktop.Notifications"]
|
||||
@log = Logger.new(STDOUT)
|
||||
@log.formatter = proc do |severity, datetime, _progname, message|
|
||||
"[#{severity}] #{datetime} #{message}\n"
|
||||
end
|
||||
|
||||
def notify(updates)
|
||||
message = "#{updates} updates available"
|
||||
@log.info { message }
|
||||
@dbus.Notify("pacman", 0, "package-x-generic", "Pacman", message, [], [], 3000)
|
||||
end
|
||||
|
||||
threads << Thread.new do
|
||||
@log.info { "Checking every #{interval} seconds" }
|
||||
loop do
|
||||
@log.info { "Checking for updates..." }
|
||||
update_queue << `pacman -Qqu`.split("\n").size
|
||||
sleep(interval.to_i)
|
||||
end
|
||||
end
|
||||
|
||||
threads.last.name = "UpdateCheck"
|
||||
|
||||
threads << Thread.new do
|
||||
loop do
|
||||
updates = update_queue.deq
|
||||
if updates != last_check
|
||||
last_check = updates
|
||||
notify(updates) unless updates.zero?
|
||||
else
|
||||
@log.info { "No new updates available" }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
threads.last.name = "UpdateNotify"
|
||||
|
||||
threads.each(&:join)
|
103
src/main.rs
Normal file
103
src/main.rs
Normal file
@ -0,0 +1,103 @@
|
||||
#![allow(clippy::too_many_arguments)]
|
||||
|
||||
use std::{collections::HashMap, time::Duration};
|
||||
|
||||
use anyhow::Result;
|
||||
use tokio::{
|
||||
process::Command,
|
||||
sync::mpsc::{self, Receiver, Sender},
|
||||
};
|
||||
use zbus::Connection;
|
||||
use zvariant::Value;
|
||||
|
||||
type VariantMap<'a> = HashMap<&'a str, &'a Value<'a>>;
|
||||
|
||||
#[zbus::dbus_proxy]
|
||||
trait Notifications {
|
||||
async fn notify(
|
||||
&self,
|
||||
app_name: &str,
|
||||
replaces_id: u32,
|
||||
app_icon: &str,
|
||||
summary: &str,
|
||||
body: &str,
|
||||
actions: &[&str],
|
||||
hints: VariantMap<'_>,
|
||||
timeout: i32,
|
||||
) -> zbus::Result<u32>;
|
||||
}
|
||||
|
||||
#[derive(argh::FromArgs)]
|
||||
/// Simple pacman update notifier
|
||||
struct Args {
|
||||
/// the update check interval in seconds
|
||||
#[argh(option, short = 'i')]
|
||||
interval: u64,
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<()> {
|
||||
let args: Args = argh::from_env();
|
||||
let interval = Duration::from_secs(args.interval);
|
||||
|
||||
let (tx, rx) = mpsc::channel(1);
|
||||
|
||||
tokio::spawn(async move {
|
||||
update_check(tx, interval)
|
||||
.await
|
||||
.map_err(|e| eprintln!("{}", e))
|
||||
});
|
||||
|
||||
if let Err(err) = notifier(rx).await {
|
||||
eprintln!("{}", err)
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn update_check(tx: Sender<u64>, interval: Duration) -> Result<()> {
|
||||
let mut interval = tokio::time::interval(interval);
|
||||
|
||||
loop {
|
||||
interval.tick().await;
|
||||
|
||||
let cmd = Command::new("pacman").arg("-Qqu").output();
|
||||
let output = cmd.await?;
|
||||
let stdout = String::from_utf8(output.stdout)?;
|
||||
|
||||
let pkg_count = stdout.split('\n').count() as u64;
|
||||
|
||||
tx.send(pkg_count).await?;
|
||||
}
|
||||
}
|
||||
|
||||
async fn notifier(mut rx: Receiver<u64>) -> Result<()> {
|
||||
let conn = Connection::session().await?;
|
||||
let proxy = NotificationsProxy::new(&conn).await?;
|
||||
|
||||
let mut last_check = 0;
|
||||
|
||||
while let Some(pkg_count) = rx.recv().await {
|
||||
if pkg_count == 0 || pkg_count == last_check {
|
||||
continue;
|
||||
}
|
||||
|
||||
last_check = pkg_count;
|
||||
let message = format!("{} updates available", pkg_count);
|
||||
|
||||
proxy
|
||||
.notify(
|
||||
"pacman",
|
||||
0,
|
||||
"package-x-generic",
|
||||
"Pacman",
|
||||
message.as_ref(),
|
||||
&[],
|
||||
VariantMap::new(),
|
||||
3000,
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
Loading…
Reference in New Issue
Block a user