Skip to content

Commit 4dad4a5

Browse files
committed
core: make action calls UI-agnostic
1 parent 13ecd13 commit 4dad4a5

File tree

10 files changed

+248
-172
lines changed

10 files changed

+248
-172
lines changed

src/actions.rs

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::pages::{Action, DialogMessage, MessageType};
1+
use crate::ui::{Action, DialogMessage, MessageType, RunCmdCallback};
22
use crate::{fl, kwin_dbus, utils, PacmanWrapper};
33

44
use std::path::Path;
@@ -139,29 +139,29 @@ pub fn remove_dblock(dialog_tx: Sender<DialogMessage>) {
139139
}
140140
}
141141

142-
pub fn update_system() {
142+
pub fn update_system(callback: RunCmdCallback) {
143143
let (cmd, escalate) = match utils::get_pacman_wrapper() {
144144
PacmanWrapper::Aura => ("aura -Syu && aura -Akaxu", false),
145145
_ => ("pacman -Syu", true),
146146
};
147-
let _ = utils::run_cmd_terminal(String::from(cmd), escalate);
147+
let _ = utils::run_cmd_terminal(callback, String::from(cmd), escalate);
148148
}
149149

150-
pub fn clear_pkgcache() {
150+
pub fn clear_pkgcache(callback: RunCmdCallback) {
151151
let (cmd, escalate) = match utils::get_pacman_wrapper() {
152152
PacmanWrapper::Pak => ("pak -Sc", false),
153153
PacmanWrapper::Yay => ("yay -Sc", false),
154154
PacmanWrapper::Paru => ("paru -Sc", false),
155155
_ => ("pacman -Sc", true),
156156
};
157-
let _ = utils::run_cmd_terminal(String::from(cmd), escalate);
157+
let _ = utils::run_cmd_terminal(callback, String::from(cmd), escalate);
158158
}
159159

160-
pub fn reinstall_packages() {
161-
let _ = utils::run_cmd_terminal(String::from("pacman -S $(pacman -Qnq)"), true);
160+
pub fn reinstall_packages(callback: RunCmdCallback) {
161+
let _ = utils::run_cmd_terminal(callback, String::from("pacman -S $(pacman -Qnq)"), true);
162162
}
163163

164-
pub fn remove_orphans(dialog_tx: Sender<DialogMessage>) {
164+
pub fn remove_orphans(callback: RunCmdCallback, dialog_tx: Sender<DialogMessage>) {
165165
// check if you have orphans packages.
166166
let mut orphan_pkgs = Exec::cmd("/sbin/pacman")
167167
.arg("-Qtdq")
@@ -183,21 +183,22 @@ pub fn remove_orphans(dialog_tx: Sender<DialogMessage>) {
183183
.expect("Couldn't send data to channel");
184184
return;
185185
}
186-
let _ = utils::run_cmd_terminal(format!("pacman -Rns {orphan_pkgs}"), true);
186+
let _ = utils::run_cmd_terminal(callback, format!("pacman -Rns {orphan_pkgs}"), true);
187187
}
188188

189-
pub fn reset_keyring() {
189+
pub fn reset_keyring(callback: RunCmdCallback) {
190190
let key_reset = r#"
191191
rm -rf /etc/pacman.d/gnupg/ && \
192192
pacman-key --init && pacman-key --populate && \
193193
pacman-key --recv-keys F3B607488DB35A47 --keyserver keyserver.ubuntu.com && \
194194
pacman-key --lsign-key F3B607488DB35A47
195195
"#;
196196

197-
let _ = utils::run_cmd_terminal(key_reset.into(), true);
197+
let _ = utils::run_cmd_terminal(callback, key_reset.into(), true);
198198
}
199199

200200
pub fn install_needed_packages(
201+
callback: RunCmdCallback,
201202
package_names: &[&str],
202203
dialog_msg: String,
203204
dialog_action: Action,
@@ -223,34 +224,37 @@ pub fn install_needed_packages(
223224

224225
// install overwise
225226
let packages = packages_to_install.join(" ");
226-
let _ = utils::run_cmd_terminal(format!("pacman -S {packages}"), true);
227+
let _ = utils::run_cmd_terminal(callback, format!("pacman -S {packages}"), true);
227228
}
228229

229-
pub fn rankmirrors() {
230-
let _ = utils::run_cmd_terminal(String::from("cachyos-rate-mirrors"), true);
230+
pub fn rankmirrors(callback: RunCmdCallback) {
231+
let _ = utils::run_cmd_terminal(callback, String::from("cachyos-rate-mirrors"), true);
231232
}
232233

233-
pub fn install_gaming(dialog_tx: Sender<DialogMessage>) {
234+
pub fn install_gaming(callback: RunCmdCallback, dialog_tx: Sender<DialogMessage>) {
234235
const ALPM_PACKAGE_NAMES: [&str; 2] = ["cachyos-gaming-meta", "cachyos-gaming-applications"];
235236
install_needed_packages(
237+
callback,
236238
&ALPM_PACKAGE_NAMES,
237239
fl!("gaming-package-installed"),
238240
Action::InstallGaming,
239241
dialog_tx,
240242
);
241243
}
242244

243-
pub fn install_snapper(dialog_tx: Sender<DialogMessage>) {
245+
pub fn install_snapper(callback: RunCmdCallback, dialog_tx: Sender<DialogMessage>) {
244246
install_needed_packages(
247+
callback,
245248
&["cachyos-snapper-support"],
246249
fl!("snapper-package-installed"),
247250
Action::InstallSnapper,
248251
dialog_tx,
249252
);
250253
}
251254

252-
pub fn install_spoofdpi(dialog_tx: Sender<DialogMessage>) {
255+
pub fn install_spoofdpi(callback: RunCmdCallback, dialog_tx: Sender<DialogMessage>) {
253256
install_needed_packages(
257+
callback,
254258
&["spoofdpi"],
255259
fl!("spoof-dpi-package-installed"),
256260
Action::InstallSpoofDpi,

src/dns.rs

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
use phf::phf_ordered_map;
2+
3+
pub static G_DNS_SERVERS: phf::OrderedMap<&'static str, (&'static str, &'static str)> = phf_ordered_map! {
4+
"AdGuard" => ("94.140.14.14,94.140.15.15", "2a10:50c0::ad1:ff,2a10:50c0::ad2:ff"),
5+
"AdGuard Family Protection" => ("94.140.14.15,94.140.15.16", "2a10:50c0::bad1:ff,2a10:50c0::bad2:ff"),
6+
"Cloudflare" => ("1.1.1.1,1.0.0.1", "2606:4700:4700::1111,2606:4700:4700::1001"),
7+
"Cloudflare Malware blocking" => ("1.1.1.2,1.0.0.2", "2606:4700:4700::1112,2606:4700:4700::1002"),
8+
"Cloudflare Malware and adult content blocking" => ("1.1.1.3,1.0.0.3", "2606:4700:4700::1113,2606:4700:4700::1003"),
9+
"Cisco Umbrella(OpenDNS)" => ("208.67.222.222,208.67.220.220", "2620:119:35::35,2620:119:53::53"),
10+
"DNS.Watch" => ("84.200.69.80,84.200.70.40", "2001:1608:10:25::1c04:b12f,2001:1608:10:25::9249:d69b"),
11+
"GCore" => ("95.85.95.85,2.56.220.2", "2a03:90c0:999d::1,2a03:90c0:9992::1"),
12+
"Google" => ("8.8.8.8,8.8.4.4", "2001:4860:4860::8888,2001:4860:4860::8844"),
13+
"Quad9" => ("9.9.9.9,149.112.112.112", "2620:fe::fe,2620:fe::9"),
14+
"Yandex" => ("77.88.8.8,77.88.8.1", "2a02:6b8::feed:0ff,2a02:6b8:0:1::feed:0ff"),
15+
"Yandex Malware blocking" => ("77.88.8.88,77.88.8.2", "2a02:6b8::feed:bad,2a02:6b8:0:1::feed:bad"),
16+
"Yandex Malware and adult content blocking" => ("77.88.8.7,77.88.8.3", "2a02:6b8::feed:a11,2a02:6b8:0:1::feed:a11"),
17+
"阿里云公共DNS (AliDNS)" => ("223.5.5.5,223.6.6.6", "2400:3200::1,2400:3200:baba::1"),
18+
"腾讯云 DNSPod (Tencent)" => ("119.29.29.29,119.28.28.28", "2402:4e00::,2402:4e00:1::")
19+
};
20+
21+
#[derive(Debug)]
22+
pub enum DnsAction {
23+
/// Set a DNS provider for a network connection
24+
Set {
25+
/// Network connection name (use 'list-connections' to see available)
26+
connection: String,
27+
28+
/// DNS provider to use (use 'list-servers' to see available)
29+
server: DnsServer,
30+
},
31+
/// Reset DNS settings for a network connection to automatic (DHCP)
32+
Reset {
33+
/// Network connection name to reset
34+
connection: String,
35+
},
36+
/// List available network connections managed by NetworkManager
37+
ListConnections,
38+
/// List available third-party DNS providers
39+
ListServers,
40+
}
41+
42+
#[derive(Debug, Clone, Copy)]
43+
pub enum DnsServer {
44+
AdGuard,
45+
AdGuardFamily,
46+
Cloudflare,
47+
CloudflareMalware,
48+
CloudflareMalwareAdult,
49+
OpenDns,
50+
DnsWatch,
51+
GCore,
52+
Google,
53+
Quad9,
54+
Yandex,
55+
YandexMalware,
56+
YandexMalwareAdult,
57+
AliDns,
58+
Tencent,
59+
}
60+
61+
// TODO(vnepogodin): use these mapping instead of phf::map
62+
impl DnsServer {
63+
pub fn as_str(&self) -> &'static str {
64+
match self {
65+
DnsServer::AdGuard => "AdGuard",
66+
DnsServer::AdGuardFamily => "AdGuard Family Protection",
67+
DnsServer::Cloudflare => "Cloudflare",
68+
DnsServer::CloudflareMalware => "Cloudflare Malware blocking",
69+
DnsServer::CloudflareMalwareAdult => "Cloudflare Malware and adult content blocking",
70+
DnsServer::OpenDns => "Cisco Umbrella(OpenDNS)",
71+
DnsServer::DnsWatch => "DNS.Watch",
72+
DnsServer::GCore => "GCore",
73+
DnsServer::Google => "Google",
74+
DnsServer::Quad9 => "Quad9",
75+
DnsServer::Yandex => "Yandex",
76+
DnsServer::YandexMalware => "Yandex Malware blocking",
77+
DnsServer::YandexMalwareAdult => "Yandex Malware and adult content blocking",
78+
DnsServer::AliDns => "阿里云公共DNS (AliDNS)",
79+
DnsServer::Tencent => "腾讯云 DNSPod (Tencent)",
80+
}
81+
}
82+
}

src/gui.rs

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
use crate::ui::{MessageType, UI};
2+
use gtk::prelude::*;
3+
4+
pub struct GUI {
5+
window: gtk::Window,
6+
}
7+
8+
impl GUI {
9+
pub fn new(window: gtk::Window) -> Self {
10+
GUI { window }
11+
}
12+
}
13+
14+
impl UI for GUI {
15+
fn show_message(&self, message_type: MessageType, message: &str, title: String) {
16+
let dialog_msg_type = match message_type {
17+
MessageType::Info => gtk::MessageType::Info,
18+
MessageType::Warning => gtk::MessageType::Warning,
19+
MessageType::Error => gtk::MessageType::Error,
20+
};
21+
22+
let dialog = gtk::MessageDialog::builder()
23+
.transient_for(&self.window)
24+
.message_type(dialog_msg_type)
25+
.text(message)
26+
.title(title)
27+
.modal(true)
28+
.buttons(gtk::ButtonsType::Ok)
29+
.build();
30+
dialog.connect_response(|dialog, _| dialog.close());
31+
32+
dialog.show();
33+
// block until user responds
34+
dialog.run();
35+
// we are required to close/hide manually according to the docs
36+
dialog.close();
37+
}
38+
}
39+
40+
pub fn run_command(command: &str, escalate: bool) -> bool {
41+
let cmd_formated = format!("{command}; read -p 'Press enter to exit'");
42+
let mut args: Vec<&str> = vec![];
43+
if escalate {
44+
args.extend_from_slice(&["-s", "pkexec /usr/share/cachyos-hello/scripts/rootshell.sh"]);
45+
}
46+
args.push(cmd_formated.as_str());
47+
48+
let exit_status = subprocess::Exec::cmd("/usr/share/cachyos-hello/scripts/terminal-helper")
49+
.args(args.as_slice())
50+
.stdout(subprocess::Redirection::Pipe)
51+
.join()
52+
.unwrap();
53+
exit_status.success()
54+
}

src/installer.rs

Lines changed: 12 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
use crate::pages::MessageType;
1+
use crate::gui::GUI;
2+
use crate::ui::{MessageType, UI};
23
use crate::{check_regular_file, fl, utils, G_HELLO_WINDOW};
34

45
use std::fs;
@@ -19,31 +20,21 @@ struct Versions {
1920
handheld_iso_version: String,
2021
}
2122

22-
fn outdated_version_check(window: &gtk::Window, message: String) -> bool {
23+
fn outdated_version_check(ui: &GUI, message: String) -> bool {
2324
let edition_tag: String =
2425
fs::read_to_string("/etc/edition-tag").unwrap_or("desktop".into()).trim().into();
2526
let version_tag: String =
2627
fs::read_to_string("/etc/version-tag").unwrap_or("testing".into()).trim().into();
2728

2829
if version_tag.contains("testing") {
29-
utils::show_simple_dialog(
30-
window,
31-
MessageType::Warning,
32-
&fl!("testing-iso-warning"),
33-
message.clone(),
34-
);
30+
ui.show_message(MessageType::Warning, &fl!("testing-iso-warning"), message.clone());
3531
return true;
3632
}
3733

3834
let response = reqwest::blocking::get("https://cachyos.org/versions.json");
3935

4036
if response.is_err() {
41-
utils::show_simple_dialog(
42-
window,
43-
MessageType::Warning,
44-
&fl!("offline-error"),
45-
message.clone(),
46-
);
37+
ui.show_message(MessageType::Warning, &fl!("offline-error"), message.clone());
4738
return false;
4839
}
4940

@@ -58,17 +49,12 @@ fn outdated_version_check(window: &gtk::Window, message: String) -> bool {
5849
.to_owned();
5950

6051
if version_tag != latest_version {
61-
utils::show_simple_dialog(
62-
window,
63-
MessageType::Warning,
64-
&fl!("outdated-version-warning"),
65-
message.clone(),
66-
);
52+
ui.show_message(MessageType::Warning, &fl!("outdated-version-warning"), message.clone());
6753
}
6854
true
6955
}
7056

71-
fn edition_compat_check(window: &gtk::Window, message: String) -> bool {
57+
fn edition_compat_check(ui: &GUI, message: String) -> bool {
7258
let edition_tag = fs::read_to_string("/etc/edition-tag").unwrap_or("desktop".to_string());
7359

7460
if edition_tag == "handheld" {
@@ -84,19 +70,14 @@ fn edition_compat_check(window: &gtk::Window, message: String) -> bool {
8470

8571
if available_profiles.iter().any(|profile| handheld_profile_names.contains(&&profile.name))
8672
{
87-
utils::show_simple_dialog(
88-
window,
89-
MessageType::Warning,
90-
&fl!("unsupported-hw-warning"),
91-
message.clone(),
92-
);
73+
ui.show_message(MessageType::Warning, &fl!("unsupported-hw-warning"), message.clone());
9374
return true;
9475
}
9576
}
9677
true
9778
}
9879

99-
fn connectivity_check(window: &gtk::Window, message: String) -> bool {
80+
fn connectivity_check(ui: &GUI, message: String) -> bool {
10081
// First try HTTP check to cachyos.org
10182
let http_status = match reqwest::blocking::get("https://cachyos.org") {
10283
Ok(resp) => resp.status().is_success() || resp.status().is_server_error(),
@@ -127,7 +108,7 @@ fn connectivity_check(window: &gtk::Window, message: String) -> bool {
127108
}
128109

129110
// All connectivity checks failed
130-
utils::show_simple_dialog(window, MessageType::Error, &fl!("offline-error"), message);
111+
ui.show_message(MessageType::Error, &fl!("offline-error"), message);
131112
false
132113
}
133114

@@ -140,8 +121,9 @@ pub fn launch_installer(message: String) {
140121
let install_btn: gtk::Button = builder.object("install").unwrap();
141122
install_btn.set_sensitive(false);
142123

124+
let ui_comp = crate::gui::GUI::new(window_ref.clone());
143125
let checks = [connectivity_check, edition_compat_check, outdated_version_check];
144-
if !checks.iter().all(|x| x(window_ref, message.clone())) {
126+
if !checks.iter().all(|x| x(&ui_comp, message.clone())) {
145127
// if any check failed, return
146128
info!("Some ISO check failed!");
147129
install_btn.set_sensitive(true);

src/main.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,17 @@
33

44
mod actions;
55
mod config;
6+
mod dns;
67
mod embed_data;
78
mod gresource;
9+
mod gui;
810
mod installer;
911
mod kwin_dbus;
1012
mod localization;
1113
mod logger;
1214
mod pages;
1315
mod systemd_units;
16+
mod ui;
1417
mod utils;
1518
mod window;
1619

0 commit comments

Comments
 (0)