👷 add dns servers page
This commit is contained in:
parent
7601d14d08
commit
61b7c65da2
|
@ -175,6 +175,7 @@ dependencies = [
|
|||
"i18n-embed-fl",
|
||||
"once_cell",
|
||||
"pacmanconf",
|
||||
"phf",
|
||||
"reqwest",
|
||||
"rust-embed",
|
||||
"serde",
|
||||
|
@ -1273,6 +1274,48 @@ version = "2.3.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94"
|
||||
|
||||
[[package]]
|
||||
name = "phf"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc"
|
||||
dependencies = [
|
||||
"phf_macros",
|
||||
"phf_shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf_generator"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0"
|
||||
dependencies = [
|
||||
"phf_shared",
|
||||
"rand",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf_macros"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b"
|
||||
dependencies = [
|
||||
"phf_generator",
|
||||
"phf_shared",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.36",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf_shared"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b"
|
||||
dependencies = [
|
||||
"siphasher",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-lite"
|
||||
version = "0.2.13"
|
||||
|
@ -1343,6 +1386,21 @@ dependencies = [
|
|||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
||||
dependencies = [
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.3.5"
|
||||
|
@ -1615,6 +1673,12 @@ dependencies = [
|
|||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "siphasher"
|
||||
version = "0.3.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d"
|
||||
|
||||
[[package]]
|
||||
name = "slab"
|
||||
version = "0.4.9"
|
||||
|
|
|
@ -24,6 +24,7 @@ serde = { version = "1", default-features = false }
|
|||
serde_json = "1"
|
||||
reqwest = { version = "0.11", features = ["blocking"] }
|
||||
unic-langid = "0.9"
|
||||
phf = { version = "0.11", features = ["macros"], default-features = false }
|
||||
|
||||
[profile.release]
|
||||
strip = "symbols"
|
||||
|
|
|
@ -11,6 +11,17 @@ lock-doesnt-exist = Pacman db lock does not exist!
|
|||
orphans-not-found = No orphan packages found!
|
||||
package-not-installed = Package '{$package_name}' has not been installed!
|
||||
|
||||
# Dns Connections page
|
||||
dns-settings = DNS Settings
|
||||
select-connections = Select Connections:
|
||||
select-dns-server = Select DNS server:
|
||||
apply = Apply
|
||||
reset = Reset
|
||||
dns-server-changed = DNS server was successfully changed!
|
||||
dns-server-failed = Failed to set DNS server!
|
||||
dns-server-reset = DNS server has been reset!
|
||||
dns-server-reset-failed = Failed to reset DNS server!
|
||||
|
||||
# Tweaks page (tweaks)
|
||||
tweak-enabled-title = {$tweak} enabled
|
||||
|
||||
|
@ -22,6 +33,7 @@ update-system-title = System update
|
|||
remove-orphans-title = Remove orphans
|
||||
clear-pkgcache-title = Clear package cache
|
||||
rankmirrors-title = Rank mirrors
|
||||
dnsserver-title = Change DNS server
|
||||
|
||||
# Main Page (buttons)
|
||||
button-about-tooltip = About
|
||||
|
|
|
@ -343,6 +343,7 @@ fn build_ui(application: >k::Application) {
|
|||
}
|
||||
pages::create_appbrowser_page(&builder);
|
||||
pages::create_tweaks_page(&builder);
|
||||
pages::create_dnsconnections_page(&builder);
|
||||
|
||||
// Show the UI
|
||||
main_window.show();
|
||||
|
|
262
src/pages.rs
262
src/pages.rs
|
@ -5,6 +5,7 @@ use crate::{fl, utils};
|
|||
use glib::translate::FromGlib;
|
||||
use gtk::{glib, Builder};
|
||||
use once_cell::sync::Lazy;
|
||||
use phf::phf_ordered_map;
|
||||
use std::fmt::Write as _;
|
||||
use std::path::Path;
|
||||
use std::sync::Mutex;
|
||||
|
@ -17,6 +18,18 @@ use subprocess::{Exec, Redirection};
|
|||
static G_LOCAL_UNITS: Lazy<Mutex<SystemdUnits>> = Lazy::new(|| Mutex::new(SystemdUnits::new()));
|
||||
static G_GLOBAL_UNITS: Lazy<Mutex<SystemdUnits>> = Lazy::new(|| Mutex::new(SystemdUnits::new()));
|
||||
|
||||
static G_DNS_SERVERS: phf::OrderedMap<&'static str, &'static str> = phf_ordered_map! {
|
||||
"Adguard" => "94.140.14.14",
|
||||
"Adguard Family Protection" => "94.140.14.15",
|
||||
"Cloudflare" => "1.1.1.1",
|
||||
"Cloudflare Malware and adult content blocking" => "1.1.1.3",
|
||||
"DNS.Watch" => "84.200.69.80",
|
||||
"Cisco Umbrella(OpenDNS)" => "208.67.222.222,208.67.220.220",
|
||||
"Quad9" => "9.9.9.9",
|
||||
"Google" => "8.8.8.8,8.8.4.4",
|
||||
"Yandex" => "77.88.8.8,77.88.8.1",
|
||||
};
|
||||
|
||||
struct DialogMessage {
|
||||
pub msg: String,
|
||||
pub msg_type: gtk::MessageType,
|
||||
|
@ -26,6 +39,7 @@ struct DialogMessage {
|
|||
enum Action {
|
||||
RemoveLock,
|
||||
RemoveOrphans,
|
||||
SetDnsServer,
|
||||
}
|
||||
|
||||
fn update_translation_apps_section(section_box: >k::Box) {
|
||||
|
@ -104,11 +118,24 @@ pub fn update_translations(builder: &Builder) {
|
|||
}
|
||||
}
|
||||
|
||||
fn create_fixes_section() -> gtk::Box {
|
||||
fn get_nm_connections() -> Vec<String> {
|
||||
let connections = Exec::cmd("/sbin/nmcli")
|
||||
.args(&["-t", "-f", "NAME", "connection", "show"])
|
||||
.stdout(Redirection::Pipe)
|
||||
.capture()
|
||||
.unwrap()
|
||||
.stdout_str();
|
||||
|
||||
// get list of connections separated by newline
|
||||
connections.split('\n').filter(|x| !x.is_empty()).map(String::from).collect::<Vec<_>>()
|
||||
}
|
||||
|
||||
fn create_fixes_section(builder: &Builder) -> gtk::Box {
|
||||
let topbox = gtk::Box::new(gtk::Orientation::Vertical, 2);
|
||||
let button_box_f = gtk::Box::new(gtk::Orientation::Horizontal, 10);
|
||||
let button_box_s = gtk::Box::new(gtk::Orientation::Horizontal, 10);
|
||||
let button_box_t = gtk::Box::new(gtk::Orientation::Horizontal, 10);
|
||||
let button_box_frth = gtk::Box::new(gtk::Orientation::Horizontal, 10);
|
||||
let label = gtk::Label::new(None);
|
||||
label.set_line_wrap(true);
|
||||
label.set_justify(gtk::Justification::Center);
|
||||
|
@ -121,6 +148,7 @@ fn create_fixes_section() -> gtk::Box {
|
|||
let remove_orphans_btn = gtk::Button::with_label(&fl!("remove-orphans-title"));
|
||||
let clear_pkgcache_btn = gtk::Button::with_label(&fl!("clear-pkgcache-title"));
|
||||
let rankmirrors_btn = gtk::Button::with_label(&fl!("rankmirrors-title"));
|
||||
let dnsserver_btn = gtk::Button::with_label(&fl!("dnsserver-title"));
|
||||
|
||||
{
|
||||
removelock_btn.set_widget_name("remove-lock-title");
|
||||
|
@ -130,6 +158,7 @@ fn create_fixes_section() -> gtk::Box {
|
|||
remove_orphans_btn.set_widget_name("remove-orphans-title");
|
||||
clear_pkgcache_btn.set_widget_name("clear-pkgcache-title");
|
||||
rankmirrors_btn.set_widget_name("rankmirrors-title");
|
||||
dnsserver_btn.set_widget_name("dnsserver-title");
|
||||
}
|
||||
|
||||
// Create context channel.
|
||||
|
@ -210,6 +239,11 @@ fn create_fixes_section() -> gtk::Box {
|
|||
let _ = utils::run_cmd_terminal(String::from("cachyos-rate-mirrors"), true);
|
||||
});
|
||||
});
|
||||
dnsserver_btn.connect_clicked(glib::clone!(@weak builder => move |_| {
|
||||
let name = "dnsConnectionsBrowser";
|
||||
let stack: gtk::Stack = builder.object("stack").unwrap();
|
||||
stack.set_visible_child_name(&format!("{name}page"));
|
||||
}));
|
||||
|
||||
// Setup receiver.
|
||||
let removelock_btn_clone = removelock_btn.clone();
|
||||
|
@ -218,6 +252,7 @@ fn create_fixes_section() -> gtk::Box {
|
|||
let widget_obj = match msg.action {
|
||||
Action::RemoveLock => &removelock_btn_clone,
|
||||
Action::RemoveOrphans => &remove_orphans_btn_clone,
|
||||
_ => panic!("Unexpected action!!"),
|
||||
};
|
||||
let widget_window =
|
||||
utils::get_window_from_widget(widget_obj).expect("Failed to retrieve window");
|
||||
|
@ -241,9 +276,12 @@ fn create_fixes_section() -> gtk::Box {
|
|||
button_box_s.pack_start(&clear_pkgcache_btn, true, true, 2);
|
||||
button_box_s.pack_end(&remove_orphans_btn, true, true, 2);
|
||||
button_box_t.pack_end(&rankmirrors_btn, true, true, 2);
|
||||
button_box_frth.pack_end(&dnsserver_btn, true, true, 2);
|
||||
button_box_f.set_halign(gtk::Align::Fill);
|
||||
button_box_s.set_halign(gtk::Align::Fill);
|
||||
button_box_t.set_halign(gtk::Align::Fill);
|
||||
button_box_frth.set_halign(gtk::Align::Fill);
|
||||
topbox.pack_end(&button_box_frth, true, true, 5);
|
||||
topbox.pack_end(&button_box_t, true, true, 5);
|
||||
topbox.pack_end(&button_box_s, true, true, 5);
|
||||
topbox.pack_end(&button_box_f, true, true, 5);
|
||||
|
@ -369,6 +407,184 @@ fn create_apps_section() -> Option<gtk::Box> {
|
|||
}
|
||||
}
|
||||
|
||||
fn create_connections_section() -> gtk::Box {
|
||||
let topbox = gtk::Box::new(gtk::Orientation::Vertical, 2);
|
||||
let connection_box = gtk::Box::new(gtk::Orientation::Horizontal, 2);
|
||||
let dnsservers_box = gtk::Box::new(gtk::Orientation::Horizontal, 2);
|
||||
let button_box = gtk::Box::new(gtk::Orientation::Horizontal, 2);
|
||||
let label = gtk::Label::new(None);
|
||||
label.set_line_wrap(true);
|
||||
label.set_justify(gtk::Justification::Center);
|
||||
label.set_text(&fl!("dns-settings"));
|
||||
|
||||
let connections_label = gtk::Label::new(None);
|
||||
connections_label.set_justify(gtk::Justification::Left);
|
||||
connections_label.set_text(&fl!("select-connections"));
|
||||
let servers_label = gtk::Label::new(None);
|
||||
servers_label.set_justify(gtk::Justification::Left);
|
||||
servers_label.set_text(&fl!("select-dns-server"));
|
||||
let apply_btn = gtk::Button::with_label(&fl!("apply"));
|
||||
let reset_btn = gtk::Button::with_label(&fl!("reset"));
|
||||
|
||||
let combo_conn = {
|
||||
let store = gtk::ListStore::new(&[String::static_type()]);
|
||||
let nm_connections = get_nm_connections();
|
||||
for nm_connection in nm_connections.iter() {
|
||||
store.set(&store.append(), &[(0, nm_connection)]);
|
||||
}
|
||||
utils::create_combo_with_model(&store)
|
||||
};
|
||||
let combo_servers = {
|
||||
let store = gtk::ListStore::new(&[String::static_type()]);
|
||||
for dns_server in G_DNS_SERVERS.keys().into_iter() {
|
||||
store.set(&store.append(), &[(0, dns_server)]);
|
||||
}
|
||||
utils::create_combo_with_model(&store)
|
||||
};
|
||||
combo_servers.set_active(Some(2));
|
||||
|
||||
combo_conn.set_widget_name("connections_combo");
|
||||
combo_servers.set_widget_name("servers_combo");
|
||||
|
||||
// Create context channel.
|
||||
let (dialog_tx, dialog_rx) = glib::MainContext::channel(glib::Priority::default());
|
||||
|
||||
// Connect signals.
|
||||
let dialog_tx_clone = dialog_tx.clone();
|
||||
let combo_conn_clone = combo_conn.clone();
|
||||
let combo_serv_clone = combo_servers.clone();
|
||||
apply_btn.connect_clicked(move |_| {
|
||||
let dialog_tx_clone = dialog_tx_clone.clone();
|
||||
let conn_name = {
|
||||
if let Some(tree_iter) = combo_conn_clone.active_iter() {
|
||||
let model = combo_conn_clone.model().unwrap();
|
||||
let group_gobj = model.value(&tree_iter, 0);
|
||||
let group = group_gobj.get::<&str>().unwrap();
|
||||
String::from(group)
|
||||
} else {
|
||||
"".into()
|
||||
}
|
||||
};
|
||||
let server_name = {
|
||||
if let Some(tree_iter) = combo_serv_clone.active_iter() {
|
||||
let model = combo_serv_clone.model().unwrap();
|
||||
let group_gobj = model.value(&tree_iter, 0);
|
||||
let group = group_gobj.get::<&str>().unwrap();
|
||||
String::from(group)
|
||||
} else {
|
||||
"".into()
|
||||
}
|
||||
};
|
||||
let server_addr = G_DNS_SERVERS.get(&server_name).unwrap();
|
||||
std::thread::spawn(move || {
|
||||
println!("conn_name := {conn_name:?}; server_addr := {server_addr:?}");
|
||||
let status_code = Exec::cmd("/sbin/pkexec")
|
||||
.arg("bash")
|
||||
.arg("-c")
|
||||
.arg(format!(
|
||||
"nmcli con mod '{conn_name}' ipv4.dns '{server_addr}' && systemctl restart \
|
||||
NetworkManager"
|
||||
))
|
||||
.join()
|
||||
.unwrap();
|
||||
if status_code.success() {
|
||||
dialog_tx_clone
|
||||
.send(DialogMessage {
|
||||
msg: fl!("dns-server-changed"),
|
||||
msg_type: gtk::MessageType::Info,
|
||||
action: Action::SetDnsServer,
|
||||
})
|
||||
.expect("Couldn't send data to channel");
|
||||
} else {
|
||||
dialog_tx_clone
|
||||
.send(DialogMessage {
|
||||
msg: fl!("dns-server-failed"),
|
||||
msg_type: gtk::MessageType::Error,
|
||||
action: Action::SetDnsServer,
|
||||
})
|
||||
.expect("Couldn't send data to channel");
|
||||
}
|
||||
});
|
||||
});
|
||||
let dialog_tx_clone = dialog_tx.clone();
|
||||
let combo_conn_clone = combo_conn.clone();
|
||||
reset_btn.connect_clicked(move |_| {
|
||||
let dialog_tx_clone = dialog_tx_clone.clone();
|
||||
let conn_name = {
|
||||
if let Some(tree_iter) = combo_conn_clone.active_iter() {
|
||||
let model = combo_conn_clone.model().unwrap();
|
||||
let group_gobj = model.value(&tree_iter, 0);
|
||||
let group = group_gobj.get::<&str>().unwrap();
|
||||
String::from(group)
|
||||
} else {
|
||||
"".into()
|
||||
}
|
||||
};
|
||||
std::thread::spawn(move || {
|
||||
let status_code = Exec::cmd("/sbin/pkexec")
|
||||
.arg("bash")
|
||||
.arg("-c")
|
||||
.arg(format!(
|
||||
"nmcli con mod '{conn_name}' ipv4.dns '' && systemctl restart NetworkManager"
|
||||
))
|
||||
.join()
|
||||
.unwrap();
|
||||
if status_code.success() {
|
||||
dialog_tx_clone
|
||||
.send(DialogMessage {
|
||||
msg: fl!("dns-server-reset"),
|
||||
msg_type: gtk::MessageType::Info,
|
||||
action: Action::SetDnsServer,
|
||||
})
|
||||
.expect("Couldn't send data to channel");
|
||||
} else {
|
||||
dialog_tx_clone
|
||||
.send(DialogMessage {
|
||||
msg: fl!("dns-server-reset-failed"),
|
||||
msg_type: gtk::MessageType::Error,
|
||||
action: Action::SetDnsServer,
|
||||
})
|
||||
.expect("Couldn't send data to channel");
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Setup receiver
|
||||
let apply_btn_clone = apply_btn.clone();
|
||||
dialog_rx.attach(None, move |msg| {
|
||||
let widget_obj = &apply_btn_clone;
|
||||
let widget_window =
|
||||
utils::get_window_from_widget(widget_obj).expect("Failed to retrieve window");
|
||||
|
||||
let dialog = gtk::MessageDialog::builder()
|
||||
.transient_for(&widget_window)
|
||||
.message_type(msg.msg_type)
|
||||
.text(msg.msg)
|
||||
.title(msg.msg_type.to_string())
|
||||
.modal(true)
|
||||
.build();
|
||||
dialog.show();
|
||||
glib::ControlFlow::Continue
|
||||
});
|
||||
|
||||
topbox.pack_start(&label, true, false, 1);
|
||||
connection_box.pack_start(&connections_label, true, true, 2);
|
||||
connection_box.pack_end(&combo_conn, true, true, 2);
|
||||
dnsservers_box.pack_start(&servers_label, true, true, 2);
|
||||
dnsservers_box.pack_end(&combo_servers, true, true, 2);
|
||||
button_box.pack_start(&reset_btn, true, true, 2);
|
||||
button_box.pack_end(&apply_btn, true, true, 2);
|
||||
connection_box.set_halign(gtk::Align::Fill);
|
||||
dnsservers_box.set_halign(gtk::Align::Fill);
|
||||
button_box.set_halign(gtk::Align::Fill);
|
||||
topbox.pack_start(&connection_box, true, true, 5);
|
||||
topbox.pack_start(&dnsservers_box, true, true, 5);
|
||||
topbox.pack_start(&button_box, true, true, 5);
|
||||
|
||||
topbox.set_hexpand(true);
|
||||
topbox
|
||||
}
|
||||
|
||||
fn load_enabled_units() {
|
||||
G_LOCAL_UNITS.lock().unwrap().loaded_units.clear();
|
||||
G_LOCAL_UNITS.lock().unwrap().enabled_units.clear();
|
||||
|
@ -433,7 +649,7 @@ pub fn create_tweaks_page(builder: &Builder) {
|
|||
}));
|
||||
|
||||
let options_section_box = create_options_section();
|
||||
let fixes_section_box = create_fixes_section();
|
||||
let fixes_section_box = create_fixes_section(builder);
|
||||
let apps_section_box_opt = create_apps_section();
|
||||
|
||||
let child_name = "tweaksBrowserpage";
|
||||
|
@ -472,6 +688,48 @@ pub fn create_tweaks_page(builder: &Builder) {
|
|||
stack.add_named(&viewport, child_name);
|
||||
}
|
||||
|
||||
pub fn create_dnsconnections_page(builder: &Builder) {
|
||||
let viewport = gtk::Viewport::new(gtk::Adjustment::NONE, gtk::Adjustment::NONE);
|
||||
let image = gtk::Image::from_icon_name(Some("go-previous"), gtk::IconSize::Button);
|
||||
let back_btn = gtk::Button::new();
|
||||
back_btn.set_image(Some(&image));
|
||||
back_btn.set_widget_name("tweaksBrowser");
|
||||
|
||||
back_btn.connect_clicked(glib::clone!(@weak builder => move |button| {
|
||||
let name = button.widget_name();
|
||||
let stack: gtk::Stack = builder.object("stack").unwrap();
|
||||
stack.set_visible_child_name(&format!("{name}page"));
|
||||
}));
|
||||
|
||||
let connections_section_box = create_connections_section();
|
||||
|
||||
let child_name = "dnsConnectionsBrowserpage";
|
||||
connections_section_box.set_widget_name(&format!("{child_name}_connections"));
|
||||
|
||||
let grid = gtk::Grid::new();
|
||||
grid.set_hexpand(true);
|
||||
grid.set_margin_start(10);
|
||||
grid.set_margin_end(10);
|
||||
grid.set_margin_top(5);
|
||||
grid.set_margin_bottom(5);
|
||||
grid.attach(&back_btn, 0, 1, 1, 1);
|
||||
let box_collection_s = gtk::Box::new(gtk::Orientation::Vertical, 5);
|
||||
let box_collection = gtk::Box::new(gtk::Orientation::Vertical, 5);
|
||||
box_collection.set_widget_name(child_name);
|
||||
|
||||
box_collection.pack_start(&connections_section_box, false, false, 10);
|
||||
|
||||
box_collection.set_valign(gtk::Align::Center);
|
||||
box_collection.set_halign(gtk::Align::Center);
|
||||
box_collection_s.pack_start(&grid, false, false, 0);
|
||||
box_collection_s.pack_start(&box_collection, false, false, 10);
|
||||
viewport.add(&box_collection_s);
|
||||
viewport.show_all();
|
||||
|
||||
let stack: gtk::Stack = builder.object("stack").unwrap();
|
||||
stack.add_named(&viewport, child_name);
|
||||
}
|
||||
|
||||
pub fn create_appbrowser_page(builder: &Builder) {
|
||||
let install: gtk::Button = builder.object("appBrowser").unwrap();
|
||||
install.set_visible(true);
|
||||
|
|
Loading…
Reference in New Issue