Rewrite application in rust

This commit is contained in:
Patrick Auernig 2022-10-06 16:24:01 +02:00
parent 74f43ff919
commit 9b4938b6af
7 changed files with 1146 additions and 63 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/target

1016
Cargo.lock generated Normal file

File diff suppressed because it is too large Load Diff

22
Cargo.toml Normal file
View 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"

View File

@ -1,8 +0,0 @@
source 'https://rubygems.org'
# to access the notification service
gem 'ruby-dbus'
group :development do
gem 'pry'
end

View File

@ -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`.

View File

@ -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
View 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(())
}