diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index f28b1c5..ab4c414 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -8,22 +8,13 @@
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
@@ -61,7 +52,7 @@
"RunOnceActivity.ShowReadmeOnStart": "true",
"RunOnceActivity.rust.reset.selective.auto.import": "true",
"git-widget-placeholder": "master",
- "last_opened_file_path": "/home/ward/RustroverProjects/pika-idk-manager/src",
+ "last_opened_file_path": "/home/ward/RustroverProjects/pika-idk-manager/src/lib",
"node.js.detected.package.eslint": "true",
"node.js.selected.package.eslint": "(autodetect)",
"nodejs_package_manager_path": "npm",
@@ -73,6 +64,7 @@
}]]>
+
@@ -146,7 +138,7 @@
-
+
diff --git a/src/bin/apt/apt_full_upgrade/main.rs b/src/bin/apt/apt_full_upgrade/main.rs
index e71fdf5..d80cecd 100644
--- a/src/bin/apt/apt_full_upgrade/main.rs
+++ b/src/bin/apt/apt_full_upgrade/main.rs
@@ -1 +1,66 @@
-fn main() {}
\ No newline at end of file
+use rust_apt::new_cache;
+use rust_apt::progress::{AcquireProgress, InstallProgress};
+use tokio::runtime::Runtime;
+use pika_unixsocket_tools::apt_update_progress_socket::AptUpdateProgressSocket;
+use pika_unixsocket_tools::apt_install_progress_socket::AptInstallProgressSocket;
+use pika_unixsocket_tools::pika_unixsocket_tools::*;
+
+fn main() {
+ let cache = new_cache!().unwrap();
+ let percent_socket_path = "/tmp/pika_apt_upgrade_percent.sock";
+ let status_socket_path = "/tmp/pika_apt_upgrade_status.sock";
+
+ let pkg = cache.get("neovim").unwrap();
+ let mut acquire_progress = AcquireProgress::new(AptUpdateProgressSocket::new(
+ percent_socket_path,
+ status_socket_path,
+ ));
+ let mut install_progress = InstallProgress::new(AptInstallProgressSocket::new(
+ percent_socket_path,
+ status_socket_path,
+ ));
+
+ pkg.mark_install(true, true);
+ pkg.protect();
+ cache.resolve(true).unwrap();
+
+ match cache.get_archives(&mut acquire_progress) {
+ Ok(_) => {
+ Runtime::new()
+ .unwrap()
+ .block_on(send_successful_to_socket(percent_socket_path));
+ Runtime::new()
+ .unwrap()
+ .block_on(send_successful_to_socket(status_socket_path));
+ }
+ Err(e) => {
+ Runtime::new()
+ .unwrap()
+ .block_on(send_failed_to_socket(percent_socket_path));
+ Runtime::new()
+ .unwrap()
+ .block_on(send_failed_to_socket(status_socket_path));
+ panic!("{}", e.to_string())
+ }
+ };
+
+ match cache.do_install(&mut install_progress) {
+ Ok(_) => {
+ Runtime::new()
+ .unwrap()
+ .block_on(send_successful_to_socket(percent_socket_path));
+ Runtime::new()
+ .unwrap()
+ .block_on(send_successful_to_socket(status_socket_path));
+ }
+ Err(e) => {
+ Runtime::new()
+ .unwrap()
+ .block_on(send_failed_to_socket(percent_socket_path));
+ Runtime::new()
+ .unwrap()
+ .block_on(send_failed_to_socket(status_socket_path));
+ panic!("{}", e.to_string())
+ }
+ };
+}
\ No newline at end of file
diff --git a/src/bin/gui/apt_update_page/mod.rs b/src/bin/gui/apt_update_page/mod.rs
index 6d94f4a..14c3f85 100644
--- a/src/bin/gui/apt_update_page/mod.rs
+++ b/src/bin/gui/apt_update_page/mod.rs
@@ -53,13 +53,13 @@ pub fn apt_update_page(
thread::spawn(move || {
Runtime::new()
.unwrap()
- .block_on(update_percent_socket_server(update_percent_sender));
+ .block_on(start_socket_server(update_percent_sender, "/tmp/pika_apt_update_percent.sock"));
});
thread::spawn(move || {
Runtime::new()
.unwrap()
- .block_on(update_status_socket_server(update_status_sender));
+ .block_on(start_socket_server(update_status_sender, "/tmp/pika_apt_update_status.sock"));
});
thread::spawn(move || {
@@ -387,92 +387,3 @@ fn set_all_apt_row_marks_to(parent_listbox: &impl IsA, value: bool) {
child_counter = next_child
}
}
-
-async fn update_percent_socket_server(buffer_sender: async_channel::Sender) {
- // Path to the Unix socket file
- let socket_path = "/tmp/pika_apt_update_percent.sock";
-
- // Remove the socket file if it already exists
- if Path::new(socket_path).exists() {
- fs::remove_file(socket_path).expect("Could not remove existing socket file");
- }
-
- // Bind the Unix listener to the socket path
- let listener = UnixListener::bind(socket_path).expect("Could not bind");
-
- println!("Server listening on {}", socket_path);
-
- // Loop to accept incoming connections
- loop {
- // Accept an incoming connection
- match listener.accept().await {
- Ok((stream, _)) => {
- // Handle the connection in a separate task
- task::spawn(handle_client(stream, buffer_sender.clone()));
- }
- Err(e) => {
- // Print error message if a connection fails
- eprintln!("Connection failed: {}", e);
- }
- }
- }
-}
-
-async fn update_status_socket_server(buffer_sender: async_channel::Sender) {
- // Path to the Unix socket file
- let socket_path = "/tmp/pika_apt_update_status.sock";
-
- // Remove the socket file if it already exists
- if Path::new(socket_path).exists() {
- fs::remove_file(socket_path).expect("Could not remove existing socket file");
- }
-
- // Bind the Unix listener to the socket path
- let listener = UnixListener::bind(socket_path).expect("Could not bind");
-
- println!("Server listening on {}", socket_path);
-
- // Loop to accept incoming connections
- loop {
- // Accept an incoming connection
- match listener.accept().await {
- Ok((stream, _)) => {
- // Handle the connection in a separate task
- task::spawn(handle_client(stream, buffer_sender.clone()));
- }
- Err(e) => {
- // Print error message if a connection fails
- eprintln!("Connection failed: {}", e);
- }
- }
- }
-}
-async fn get_upgradable_socket_server(buffer_sender: async_channel::Sender) {
- // Path to the Unix socket file
- let socket_path = "/tmp/pika_apt_get_upgradable.sock";
-
- // Remove the socket file if it already exists
- if Path::new(socket_path).exists() {
- fs::remove_file(socket_path).expect("Could not remove existing socket file");
- }
-
- // Bind the Unix listener to the socket path
- let listener = UnixListener::bind(socket_path).expect("Could not bind");
-
- println!("Server listening on {}", socket_path);
-
- // Loop to accept incoming connections
- loop {
- // Accept an incoming connection
- match listener.accept().await {
- Ok((stream, _)) => {
- // Handle the connection in a separate task
- task::spawn(handle_client(stream, buffer_sender.clone()));
- }
- Err(e) => {
- // Print error message if a connection fails
- eprintln!("Connection failed: {}", e);
- }
- }
- }
-}
diff --git a/src/bin/gui/apt_update_page/process.rs b/src/bin/gui/apt_update_page/process.rs
index a8ef5fe..abea871 100644
--- a/src/bin/gui/apt_update_page/process.rs
+++ b/src/bin/gui/apt_update_page/process.rs
@@ -5,8 +5,11 @@ use gtk::glib::*;
use gtk::*;
use pretty_bytes::converter::convert;
use serde_json::{Value};
-use std::{fs::*};
+use std::{fs::*, thread};
use std::path::Path;
+use std::process::Command;
+use tokio::runtime::Runtime;
+use pika_unixsocket_tools::pika_unixsocket_tools::start_socket_server;
struct AptChangesInfo {
package_count: u64,
@@ -174,7 +177,115 @@ fn apt_confirm_window(excluded_updates_vec: &Vec, window: adw::Applicati
std::fs::write(json_file_path, serde_json::to_string_pretty(&excluded_updates_values_json).unwrap()).expect("Failed to write to json file");
}
- apt_confirm_dialog.present();
+ //apt_confirm_dialog.present();
+ apt_full_upgrade_from_socket(window);
+}
+
+fn apt_full_upgrade_from_socket(window: adw::ApplicationWindow) {
+ let (upgrade_percent_sender, upgrade_percent_receiver) = async_channel::unbounded::();
+ let upgrade_percent_sender = upgrade_percent_sender.clone();
+ let (upgrade_status_sender, upgrade_status_receiver) = async_channel::unbounded::();
+ let upgrade_status_sender = upgrade_status_sender.clone();
+ let upgrade_status_sender_clone0 = upgrade_status_sender.clone();
+
+ thread::spawn(move || {
+ Runtime::new()
+ .unwrap()
+ .block_on(start_socket_server(upgrade_percent_sender, "/tmp/pika_apt_upgrade_percent.sock"));
+ });
+
+ thread::spawn(move || {
+ Runtime::new()
+ .unwrap()
+ .block_on(start_socket_server(upgrade_status_sender, "/tmp/pika_apt_upgrade_status.sock"));
+ });
+
+ thread::spawn(move || {
+ let apt_upgrade_command = Command::new("pkexec")
+ .args(["/home/ward/RustroverProjects/pika-idk-manager/target/debug/apt_full_upgrade"])
+ .status()
+ .unwrap();
+ match apt_upgrade_command.code().unwrap() {
+ 0 => {
+ upgrade_status_sender_clone0
+ .send_blocking("FN_OVERRIDE_SUCCESSFUL".to_owned())
+ .unwrap()
+ }
+ 53 => {}
+ _ => {
+ upgrade_status_sender_clone0
+ .send_blocking(t!("upgrade_status_error_perms").to_string())
+ .unwrap();
+ upgrade_status_sender_clone0
+ .send_blocking("FN_OVERRIDE_FAILED".to_owned())
+ .unwrap()
+ }
+ }
+ });
+
+ let apt_upgrade_dialog_child_box = gtk::Box::builder()
+ .orientation(Orientation::Vertical)
+ .build();
+
+ let apt_upgrade_dialog_progress_bar = gtk::ProgressBar::builder()
+ .show_text(true)
+ .hexpand(true)
+ .build();
+
+ let apt_upgrade_dialog_spinner = gtk::Spinner::builder()
+ .hexpand(true)
+ .valign(Align::Start)
+ .halign(Align::Center)
+ .spinning(true)
+ .height_request(128)
+ .width_request(128)
+ .build();
+
+ apt_upgrade_dialog_child_box.append(&apt_upgrade_dialog_spinner);
+ apt_upgrade_dialog_child_box.append(&apt_upgrade_dialog_progress_bar);
+
+ let apt_upgrade_dialog = adw::MessageDialog::builder()
+ .transient_for(&window)
+ .extra_child(&apt_upgrade_dialog_child_box)
+ .heading(t!("apt_upgrade_dialog_heading"))
+ .hide_on_close(true)
+ .width_request(500)
+ .build();
+
+ let upgrade_percent_server_context = MainContext::default();
+ // The main loop executes the asynchronous block
+ upgrade_percent_server_context.spawn_local(clone!(@weak apt_upgrade_dialog_progress_bar, @weak apt_upgrade_dialog => async move {
+ while let Ok(state) = upgrade_percent_receiver.recv().await {
+ match state.as_ref() {
+ "FN_OVERRIDE_SUCCESSFUL" => {}
+ _ => {
+ apt_upgrade_dialog_progress_bar.set_fraction(state.parse::().unwrap()/100.0)
+ }
+ }
+ }
+ }));
+
+ let upgrade_status_server_context = MainContext::default();
+ // The main loop executes the asynchronous block
+ upgrade_status_server_context.spawn_local(
+ clone!(@weak apt_upgrade_dialog, @weak apt_upgrade_dialog_child_box => async move {
+ while let Ok(state) = upgrade_status_receiver.recv().await {
+ match state.as_ref() {
+ "FN_OVERRIDE_SUCCESSFUL" => {
+ apt_upgrade_dialog.close();
+ }
+ "FN_OVERRIDE_FAILED" => {
+ apt_upgrade_dialog_child_box.set_visible(false);
+ apt_upgrade_dialog.set_title(Some(&t!("apt_upgrade_dialog_status_failed").to_string()));
+ apt_upgrade_dialog.set_response_enabled("apt_upgrade_dialog_ok", true);
+ }
+ _ => apt_upgrade_dialog.set_body(&state)
+ }
+ }
+ }),
+ );
+
+ apt_upgrade_dialog.present();
}
fn create_color_badge(
diff --git a/src/lib/apt_install_progress_socket/mod.rs b/src/lib/apt_install_progress_socket/mod.rs
new file mode 100644
index 0000000..999e51b
--- /dev/null
+++ b/src/lib/apt_install_progress_socket/mod.rs
@@ -0,0 +1,104 @@
+use crate::pika_unixsocket_tools::*;
+use rust_apt::progress::{DynAcquireProgress, DynInstallProgress};
+use rust_apt::raw::{AcqTextStatus, ItemDesc, PkgAcquire};
+use std::process::exit;
+use tokio::io::{AsyncWriteExt};
+use tokio::net::UnixStream;
+use tokio::runtime::Runtime;
+
+pub struct AptInstallProgressSocket<'a> {
+ pkgname: String,
+ steps_done: u64,
+ total_steps: u64,
+ action: String,
+ percent_socket_path: &'a str,
+ status_socket_path: &'a str,
+}
+
+impl<'a> AptInstallProgressSocket<'a> {
+ /// Returns a new default progress instance.
+ pub fn new(percent_socket_path: &'a str, status_socket_path: &'a str) -> Self {
+ let mut progress = Self {
+ pkgname: String::new(),
+ steps_done: 0,
+ total_steps: 0,
+ action: String::new(),
+ percent_socket_path: percent_socket_path,
+ status_socket_path: status_socket_path,
+ };
+ progress
+ }
+}
+
+impl<'a> DynInstallProgress for AptInstallProgressSocket<'a> {
+ fn status_changed(
+ &mut self,
+ pkgname: String,
+ steps_done: u64,
+ total_steps: u64,
+ action: String
+ ) {
+ let progress_percent: f32 =
+ (steps_done as f32 * 100.0) / total_steps as f32;
+ Runtime::new().unwrap().block_on(send_progress_percent(
+ progress_percent,
+ self.percent_socket_path,
+ ));
+ Runtime::new().unwrap().block_on(send_progress_status(
+ &action,
+ self.status_socket_path,
+ ));
+ }
+
+ fn error(
+ &mut self,
+ pkgname: String,
+ steps_done: u64,
+ total_steps: u64,
+ error: String
+ ) {
+ let message = format!(
+ "dpkg failure on {}: {}",
+ pkgname,
+ error
+ );
+ eprintln!("{}", &message);
+ Runtime::new()
+ .unwrap()
+ .block_on(send_progress_status(&message, self.status_socket_path));
+ Runtime::new()
+ .unwrap()
+ .block_on(send_failed_to_socket(self.percent_socket_path));
+ Runtime::new()
+ .unwrap()
+ .block_on(send_failed_to_socket(self.status_socket_path));
+ exit(53)
+ }
+}
+
+async fn send_progress_percent(progress_f32: f32, socket_path: &str) {
+ // Connect to the Unix socket
+ let mut stream = UnixStream::connect(socket_path)
+ .await
+ .expect("Could not connect to server");
+
+ let message = progress_f32.to_string();
+ // Send the message to the server
+ stream
+ .write_all(message.as_bytes())
+ .await
+ .expect("Failed to write to stream");
+}
+
+async fn send_progress_status(message: &str, socket_path: &str) {
+ // Connect to the Unix socket
+ let mut stream = UnixStream::connect(socket_path)
+ .await
+ .expect("Could not connect to server");
+
+ // Send the message to the server
+ stream
+ .write_all(message.as_bytes())
+ .await
+ .expect("Failed to write to stream");
+}
diff --git a/src/lib/lib.rs b/src/lib/lib.rs
index 22816ae..98c2e73 100644
--- a/src/lib/lib.rs
+++ b/src/lib/lib.rs
@@ -1,2 +1,3 @@
pub mod pika_unixsocket_tools;
+pub mod apt_install_progress_socket;
pub mod apt_update_progress_socket;
\ No newline at end of file
diff --git a/src/lib/pika_unixsocket_tools/mod.rs b/src/lib/pika_unixsocket_tools/mod.rs
index d8da124..ba37e9c 100644
--- a/src/lib/pika_unixsocket_tools/mod.rs
+++ b/src/lib/pika_unixsocket_tools/mod.rs
@@ -1,5 +1,8 @@
+use std::fs;
+use std::path::Path;
use tokio::io::{AsyncReadExt, AsyncWriteExt};
-use tokio::net::UnixStream;
+use tokio::net::{UnixListener, UnixStream};
+use tokio::task;
pub async fn send_successful_to_socket(socket_path: &str) {
// Connect to the Unix socket
@@ -50,3 +53,30 @@ pub async fn handle_client(mut stream: UnixStream, buffer_sender: async_channel:
}
}
}
+
+pub async fn start_socket_server(buffer_sender: async_channel::Sender, socket_path: &str) {
+ // Remove the socket file if it already exists
+ if Path::new(socket_path).exists() {
+ fs::remove_file(socket_path).expect("Could not remove existing socket file");
+ }
+
+ // Bind the Unix listener to the socket path
+ let listener = UnixListener::bind(socket_path).expect("Could not bind");
+
+ println!("Server listening on {}", socket_path);
+
+ // Loop to accept incoming connections
+ loop {
+ // Accept an incoming connection
+ match listener.accept().await {
+ Ok((stream, _)) => {
+ // Handle the connection in a separate task
+ task::spawn(handle_client(stream, buffer_sender.clone()));
+ }
+ Err(e) => {
+ // Print error message if a connection fails
+ eprintln!("Connection failed: {}", e);
+ }
+ }
+ }
+}
\ No newline at end of file