UI of upgrades
This commit is contained in:
parent
b9fe70b6d7
commit
c8fe55422b
@ -9,9 +9,6 @@
|
|||||||
<component name="ChangeListManager">
|
<component name="ChangeListManager">
|
||||||
<list default="true" id="df2ca9e1-e07d-43f4-bc68-0a6113fc1fa2" name="Changes" comment="">
|
<list default="true" id="df2ca9e1-e07d-43f4-bc68-0a6113fc1fa2" name="Changes" comment="">
|
||||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/Cargo.lock" beforeDir="false" afterPath="$PROJECT_DIR$/Cargo.lock" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/Cargo.toml" beforeDir="false" afterPath="$PROJECT_DIR$/Cargo.toml" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/locales/en_US.json" beforeDir="false" afterPath="$PROJECT_DIR$/locales/en_US.json" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/src/bin/gui/apt_update_page/mod.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/bin/gui/apt_update_page/mod.rs" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/src/bin/gui/apt_update_page/mod.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/bin/gui/apt_update_page/mod.rs" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/src/bin/gui/apt_update_page/process.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/bin/gui/apt_update_page/process.rs" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/src/bin/gui/apt_update_page/process.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/bin/gui/apt_update_page/process.rs" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/src/lib/pika_unixsocket_tools/mod.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/lib/pika_unixsocket_tools/mod.rs" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/src/lib/pika_unixsocket_tools/mod.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/lib/pika_unixsocket_tools/mod.rs" afterDir="false" />
|
||||||
@ -45,25 +42,26 @@
|
|||||||
<option name="hideEmptyMiddlePackages" value="true" />
|
<option name="hideEmptyMiddlePackages" value="true" />
|
||||||
<option name="showLibraryContents" value="true" />
|
<option name="showLibraryContents" value="true" />
|
||||||
</component>
|
</component>
|
||||||
<component name="PropertiesComponent">{
|
<component name="PropertiesComponent"><![CDATA[{
|
||||||
"keyToString": {
|
"keyToString": {
|
||||||
"ASKED_ADD_EXTERNAL_FILES": "true",
|
"ASKED_ADD_EXTERNAL_FILES": "true",
|
||||||
"Cargo.Run apt_update.executor": "Run",
|
"Cargo.Build all.executor": "Run",
|
||||||
"Cargo.Run pikman-update-manager.executor": "Run",
|
"Cargo.Run apt_update.executor": "Run",
|
||||||
"Cargo.Test pikman-update-manager.executor": "Run",
|
"Cargo.Run pikman-update-manager.executor": "Run",
|
||||||
"RunOnceActivity.ShowReadmeOnStart": "true",
|
"Cargo.Test pikman-update-manager.executor": "Run",
|
||||||
"RunOnceActivity.rust.reset.selective.auto.import": "true",
|
"RunOnceActivity.ShowReadmeOnStart": "true",
|
||||||
"git-widget-placeholder": "master",
|
"RunOnceActivity.rust.reset.selective.auto.import": "true",
|
||||||
"last_opened_file_path": "/home/ward/RustroverProjects/pikman-update-manager/src/lib",
|
"git-widget-placeholder": "main",
|
||||||
"node.js.detected.package.eslint": "true",
|
"last_opened_file_path": "/home/ward/RustroverProjects/pikman-update-manager",
|
||||||
"node.js.selected.package.eslint": "(autodetect)",
|
"node.js.detected.package.eslint": "true",
|
||||||
"nodejs_package_manager_path": "npm",
|
"node.js.selected.package.eslint": "(autodetect)",
|
||||||
"org.rust.cargo.project.model.PROJECT_DISCOVERY": "true",
|
"nodejs_package_manager_path": "npm",
|
||||||
"org.rust.cargo.project.model.impl.CargoExternalSystemProjectAware.subscribe.first.balloon": "",
|
"org.rust.cargo.project.model.PROJECT_DISCOVERY": "true",
|
||||||
"org.rust.disableDetachedFileInspection/home/ward/RustroverProjects/pikman-update-manager/src/apt_update_progress_socket/lib.rs": "true",
|
"org.rust.cargo.project.model.impl.CargoExternalSystemProjectAware.subscribe.first.balloon": "",
|
||||||
"org.rust.first.attach.projects": "true"
|
"org.rust.disableDetachedFileInspection/home/ward/RustroverProjects/pikman-update-manager/src/apt_update_progress_socket/lib.rs": "true",
|
||||||
|
"org.rust.first.attach.projects": "true"
|
||||||
}
|
}
|
||||||
}</component>
|
}]]></component>
|
||||||
<component name="RecentsManager">
|
<component name="RecentsManager">
|
||||||
<key name="CopyFile.RECENT_KEYS">
|
<key name="CopyFile.RECENT_KEYS">
|
||||||
<recent name="$PROJECT_DIR$/src/lib" />
|
<recent name="$PROJECT_DIR$/src/lib" />
|
||||||
@ -164,6 +162,7 @@
|
|||||||
<workItem from="1720594302708" duration="52000" />
|
<workItem from="1720594302708" duration="52000" />
|
||||||
<workItem from="1720597532937" duration="7050000" />
|
<workItem from="1720597532937" duration="7050000" />
|
||||||
<workItem from="1720648284536" duration="9271000" />
|
<workItem from="1720648284536" duration="9271000" />
|
||||||
|
<workItem from="1720657757166" duration="5474000" />
|
||||||
</task>
|
</task>
|
||||||
<servers />
|
<servers />
|
||||||
</component>
|
</component>
|
||||||
|
@ -61,7 +61,7 @@ pub fn apt_update_page(
|
|||||||
Runtime::new().unwrap().block_on(start_socket_server(
|
Runtime::new().unwrap().block_on(start_socket_server(
|
||||||
update_status_sender,
|
update_status_sender,
|
||||||
"/tmp/pika_apt_update_status.sock",
|
"/tmp/pika_apt_update_status.sock",
|
||||||
"/var/log/pika-apt-update.log"
|
"/tmp/pika-apt-update.log"
|
||||||
));
|
));
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -206,8 +206,8 @@ pub fn apt_update_page(
|
|||||||
update_button.add_css_class("destructive-action");
|
update_button.add_css_class("destructive-action");
|
||||||
|
|
||||||
update_button.connect_clicked(
|
update_button.connect_clicked(
|
||||||
clone!(@weak window, @strong excluded_updates_vec => move |_| {
|
clone!(@weak window, @weak retry_signal_action, @strong excluded_updates_vec => move |_| {
|
||||||
process::apt_process_update(&excluded_updates_vec.borrow(), window);
|
process::apt_process_update(&excluded_updates_vec.borrow(), window, &retry_signal_action);
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -274,6 +274,7 @@ pub fn apt_update_page(
|
|||||||
"FN_OVERRIDE_SUCCESSFUL" => {}
|
"FN_OVERRIDE_SUCCESSFUL" => {}
|
||||||
"FN_OVERRIDE_FAILED" => {
|
"FN_OVERRIDE_FAILED" => {
|
||||||
apt_update_dialog_child_box.set_visible(false);
|
apt_update_dialog_child_box.set_visible(false);
|
||||||
|
apt_update_dialog.set_extra_child(Some(>k::Image::builder().pixel_size(128).icon_name("dialog-error-symbolic").halign(Align::Center).build()));
|
||||||
apt_update_dialog.set_title(Some(&t!("apt_update_dialog_status_failed").to_string()));
|
apt_update_dialog.set_title(Some(&t!("apt_update_dialog_status_failed").to_string()));
|
||||||
apt_update_dialog.set_response_enabled("apt_update_dialog_retry", true);
|
apt_update_dialog.set_response_enabled("apt_update_dialog_retry", true);
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ use serde_json::Value;
|
|||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
use std::{fs::*, thread};
|
use std::{fs::*, thread};
|
||||||
|
use adw::gio::SimpleAction;
|
||||||
use tokio::runtime::Runtime;
|
use tokio::runtime::Runtime;
|
||||||
|
|
||||||
struct AptChangesInfo {
|
struct AptChangesInfo {
|
||||||
@ -52,7 +53,7 @@ impl AptChangesInfo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn apt_process_update(excluded_updates_vec: &Vec<String>, window: adw::ApplicationWindow) {
|
pub fn apt_process_update(excluded_updates_vec: &Vec<String>, window: adw::ApplicationWindow, retry_signal_action: &SimpleAction,) {
|
||||||
let excluded_updates_alert_dialog = adw::MessageDialog::builder()
|
let excluded_updates_alert_dialog = adw::MessageDialog::builder()
|
||||||
.transient_for(&window)
|
.transient_for(&window)
|
||||||
.heading(t!("excluded_updates_alert_dialog_heading"))
|
.heading(t!("excluded_updates_alert_dialog_heading"))
|
||||||
@ -80,8 +81,8 @@ pub fn apt_process_update(excluded_updates_vec: &Vec<String>, window: adw::Appli
|
|||||||
gio::SimpleAction::new("excluded_updates_alert_dialog_action", None);
|
gio::SimpleAction::new("excluded_updates_alert_dialog_action", None);
|
||||||
|
|
||||||
excluded_updates_alert_dialog_action.connect_activate(
|
excluded_updates_alert_dialog_action.connect_activate(
|
||||||
clone!(@weak window, @strong excluded_updates_vec => move |_, _| {
|
clone!(@weak window, @weak retry_signal_action, @strong excluded_updates_vec => move |_, _| {
|
||||||
apt_confirm_window(&excluded_updates_vec, window)
|
apt_confirm_window(&excluded_updates_vec, window, &retry_signal_action)
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -96,7 +97,7 @@ pub fn apt_process_update(excluded_updates_vec: &Vec<String>, window: adw::Appli
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn apt_confirm_window(excluded_updates_vec: &Vec<String>, window: adw::ApplicationWindow) {
|
fn apt_confirm_window(excluded_updates_vec: &Vec<String>, window: adw::ApplicationWindow, retry_signal_action: &SimpleAction,) {
|
||||||
// Emulate Apt Full Upgrade to get transaction info
|
// Emulate Apt Full Upgrade to get transaction info
|
||||||
let mut apt_changes_struct = AptChangesInfo {
|
let mut apt_changes_struct = AptChangesInfo {
|
||||||
package_count_upgrade: 0,
|
package_count_upgrade: 0,
|
||||||
@ -274,20 +275,25 @@ fn apt_confirm_window(excluded_updates_vec: &Vec<String>, window: adw::Applicati
|
|||||||
.expect("Failed to write to json file");
|
.expect("Failed to write to json file");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let retry_signal_action0 = retry_signal_action.clone();
|
||||||
|
|
||||||
apt_confirm_dialog.choose(None::<&gio::Cancellable>, move |choice| {
|
apt_confirm_dialog.choose(None::<&gio::Cancellable>, move |choice| {
|
||||||
if choice == "apt_confirm_dialog_confirm" {
|
if choice == "apt_confirm_dialog_confirm" {
|
||||||
apt_full_upgrade_from_socket(window);
|
apt_full_upgrade_from_socket(window, &retry_signal_action0);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn apt_full_upgrade_from_socket(window: adw::ApplicationWindow) {
|
fn apt_full_upgrade_from_socket(window: adw::ApplicationWindow, retry_signal_action: &SimpleAction) {
|
||||||
let (upgrade_percent_sender, upgrade_percent_receiver) = async_channel::unbounded::<String>();
|
let (upgrade_percent_sender, upgrade_percent_receiver) = async_channel::unbounded::<String>();
|
||||||
let upgrade_percent_sender = upgrade_percent_sender.clone();
|
let upgrade_percent_sender = upgrade_percent_sender.clone();
|
||||||
let (upgrade_status_sender, upgrade_status_receiver) = async_channel::unbounded::<String>();
|
let (upgrade_status_sender, upgrade_status_receiver) = async_channel::unbounded::<String>();
|
||||||
let upgrade_status_sender = upgrade_status_sender.clone();
|
let upgrade_status_sender = upgrade_status_sender.clone();
|
||||||
let upgrade_status_sender_clone0 = upgrade_status_sender.clone();
|
let upgrade_status_sender_clone0 = upgrade_status_sender.clone();
|
||||||
|
|
||||||
|
let log_file_path = format!("/tmp/pika-apt-upgrade_{}.log", chrono::offset::Local::now().format("%Y-%m-%d_%H:%M"));
|
||||||
|
let log_file_path_clone0 = log_file_path.clone();
|
||||||
|
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
Runtime::new().unwrap().block_on(start_socket_server_no_log(
|
Runtime::new().unwrap().block_on(start_socket_server_no_log(
|
||||||
upgrade_percent_sender,
|
upgrade_percent_sender,
|
||||||
@ -299,7 +305,7 @@ fn apt_full_upgrade_from_socket(window: adw::ApplicationWindow) {
|
|||||||
Runtime::new().unwrap().block_on(start_socket_server(
|
Runtime::new().unwrap().block_on(start_socket_server(
|
||||||
upgrade_status_sender,
|
upgrade_status_sender,
|
||||||
"/tmp/pika_apt_upgrade_status.sock",
|
"/tmp/pika_apt_upgrade_status.sock",
|
||||||
"/var/log/pika-apt-upgrade.log"
|
&log_file_path
|
||||||
));
|
));
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -353,6 +359,35 @@ fn apt_full_upgrade_from_socket(window: adw::ApplicationWindow) {
|
|||||||
.width_request(500)
|
.width_request(500)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
apt_upgrade_dialog.add_response(
|
||||||
|
"apt_upgrade_dialog_ok",
|
||||||
|
&t!("apt_upgrade_dialog_ok_label").to_string(),
|
||||||
|
);
|
||||||
|
|
||||||
|
let apt_upgrade_dialog_child_box_done = gtk::Box::builder()
|
||||||
|
.orientation(Orientation::Vertical)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let apt_upgrade_log_image = gtk::Image::builder()
|
||||||
|
.pixel_size(128)
|
||||||
|
.halign(Align::Center)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let apt_upgrade_log_button = gtk::Button::builder()
|
||||||
|
.label(t!("apt_upgrade_dialog_open_log_file_label"))
|
||||||
|
.halign(Align::Center)
|
||||||
|
.margin_start(15)
|
||||||
|
.margin_end(15)
|
||||||
|
.margin_top(15)
|
||||||
|
.margin_bottom(15)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
apt_upgrade_dialog_child_box_done.append(&apt_upgrade_log_image);
|
||||||
|
apt_upgrade_dialog_child_box_done.append(&apt_upgrade_log_button);
|
||||||
|
|
||||||
|
apt_upgrade_dialog.set_response_enabled("apt_upgrade_dialog_ok", false);
|
||||||
|
apt_upgrade_dialog.set_close_response("apt_upgrade_dialog_ok");
|
||||||
|
|
||||||
let upgrade_percent_server_context = MainContext::default();
|
let upgrade_percent_server_context = MainContext::default();
|
||||||
// The main loop executes the asynchronous block
|
// 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 {
|
upgrade_percent_server_context.spawn_local(clone!(@weak apt_upgrade_dialog_progress_bar, @weak apt_upgrade_dialog => async move {
|
||||||
@ -369,16 +404,23 @@ fn apt_full_upgrade_from_socket(window: adw::ApplicationWindow) {
|
|||||||
let upgrade_status_server_context = MainContext::default();
|
let upgrade_status_server_context = MainContext::default();
|
||||||
// The main loop executes the asynchronous block
|
// The main loop executes the asynchronous block
|
||||||
upgrade_status_server_context.spawn_local(
|
upgrade_status_server_context.spawn_local(
|
||||||
clone!(@weak apt_upgrade_dialog, @weak apt_upgrade_dialog_child_box => async move {
|
clone!(@weak apt_upgrade_dialog, @weak apt_upgrade_dialog_child_box, @strong apt_upgrade_dialog_child_box_done, @strong apt_upgrade_log_image => async move {
|
||||||
while let Ok(state) = upgrade_status_receiver.recv().await {
|
while let Ok(state) = upgrade_status_receiver.recv().await {
|
||||||
match state.as_ref() {
|
match state.as_ref() {
|
||||||
"FN_OVERRIDE_SUCCESSFUL" => {
|
"FN_OVERRIDE_SUCCESSFUL" => {
|
||||||
apt_upgrade_dialog.close();
|
apt_upgrade_dialog_child_box.set_visible(false);
|
||||||
|
apt_upgrade_log_image.set_icon_name(Some("face-cool-symbolic"));
|
||||||
|
apt_upgrade_dialog.set_extra_child(Some(&apt_upgrade_dialog_child_box_done));
|
||||||
|
apt_upgrade_dialog.set_title(Some(&t!("apt_upgrade_dialog_status_successful").to_string()));
|
||||||
|
apt_upgrade_dialog.set_response_enabled("apt_upgrade_dialog_ok", true);
|
||||||
}
|
}
|
||||||
"FN_OVERRIDE_FAILED" => {
|
"FN_OVERRIDE_FAILED" => {
|
||||||
apt_upgrade_dialog_child_box.set_visible(false);
|
apt_upgrade_dialog_child_box.set_visible(false);
|
||||||
|
apt_upgrade_log_image.set_icon_name(Some("dialog-error-symbolic"));
|
||||||
|
apt_upgrade_dialog.set_extra_child(Some(&apt_upgrade_dialog_child_box_done));
|
||||||
apt_upgrade_dialog.set_title(Some(&t!("apt_upgrade_dialog_status_failed").to_string()));
|
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_response_enabled("apt_upgrade_dialog_ok", true);
|
||||||
|
apt_upgrade_dialog.set_response_enabled("apt_upgrade_dialog_open_log_file", true);
|
||||||
}
|
}
|
||||||
_ => apt_upgrade_dialog.set_body(&state)
|
_ => apt_upgrade_dialog.set_body(&state)
|
||||||
}
|
}
|
||||||
@ -386,7 +428,20 @@ fn apt_full_upgrade_from_socket(window: adw::ApplicationWindow) {
|
|||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
apt_upgrade_dialog.present();
|
let retry_signal_action0 = retry_signal_action.clone();
|
||||||
|
|
||||||
|
apt_upgrade_log_button.connect_clicked( move |_| {
|
||||||
|
let _ = std::process::Command::new("xdg-open").arg(log_file_path_clone0.to_owned()).spawn();
|
||||||
|
});
|
||||||
|
|
||||||
|
apt_upgrade_dialog.choose(None::<&gio::Cancellable>, move |choice| {
|
||||||
|
match choice.as_str() {
|
||||||
|
"apt_upgrade_dialog_ok" => {
|
||||||
|
retry_signal_action0.activate(None);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_color_badge(
|
fn create_color_badge(
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
use std::fs;
|
use std::fs;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use rust_i18n::t;
|
|
||||||
use tokio::io::{AsyncReadExt, AsyncWriteExt};
|
use tokio::io::{AsyncReadExt, AsyncWriteExt};
|
||||||
use tokio::net::{UnixListener, UnixStream};
|
use tokio::net::{UnixListener, UnixStream};
|
||||||
use tokio::task;
|
use tokio::task;
|
||||||
use chrono;
|
use chrono;
|
||||||
|
use std::fs::OpenOptions;
|
||||||
|
use std::io::Write;
|
||||||
|
|
||||||
pub async fn send_successful_to_socket(socket_path: &str) {
|
pub async fn send_successful_to_socket(socket_path: &str) {
|
||||||
// Connect to the Unix socket
|
// Connect to the Unix socket
|
||||||
@ -41,15 +42,11 @@ pub async fn handle_client(mut stream: UnixStream, buffer_sender: async_channel:
|
|||||||
// Buffer to store incoming data
|
// Buffer to store incoming data
|
||||||
let mut buffer = [0; 1024];
|
let mut buffer = [0; 1024];
|
||||||
|
|
||||||
let mut enable_log = true;
|
if !Path::new(&log_file_path).exists() {
|
||||||
|
match std::fs::File::create(&log_file_path) {
|
||||||
// Remove existing log file if exists
|
|
||||||
if Path::new(&log_file_path).exists() {
|
|
||||||
match std::fs::remove_file(&log_file_path) {
|
|
||||||
Ok(_) => {}
|
Ok(_) => {}
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
enable_log = false;
|
eprintln!("Warning: {} file couldn't be created", log_file_path);
|
||||||
eprintln!("Warning: {} file couldn't be deleted, logging disabled", log_file_path);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -58,12 +55,20 @@ pub async fn handle_client(mut stream: UnixStream, buffer_sender: async_channel:
|
|||||||
match stream.read(&mut buffer).await {
|
match stream.read(&mut buffer).await {
|
||||||
Ok(size) => {
|
Ok(size) => {
|
||||||
let message = String::from_utf8_lossy(&buffer[..size]).to_string();
|
let message = String::from_utf8_lossy(&buffer[..size]).to_string();
|
||||||
// Write to log file
|
|
||||||
|
|
||||||
// Send to async buffer sender
|
// Send to async buffer sender
|
||||||
buffer_sender
|
buffer_sender
|
||||||
.send_blocking(message)
|
.send_blocking(message.clone())
|
||||||
.expect("Buffer channel closed")
|
.expect("Buffer channel closed");
|
||||||
|
// Write to log file
|
||||||
|
let mut log_file = OpenOptions::new()
|
||||||
|
.write(true)
|
||||||
|
.append(true)
|
||||||
|
.open(&log_file_path)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
if let Err(e) = writeln!(log_file, "[{}] {}", chrono::offset::Local::now().format("%Y/%m/%d_%H:%M"), message) {
|
||||||
|
eprintln!("Couldn't write to file: {}", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
// Print error message if reading fails
|
// Print error message if reading fails
|
||||||
|
Loading…
Reference in New Issue
Block a user