diff --git a/src/bottles/mod.rs b/src/bottles/mod.rs new file mode 100644 index 0000000..fc511aa --- /dev/null +++ b/src/bottles/mod.rs @@ -0,0 +1,5 @@ +mod platform; +mod settings; + +pub use platform::*; +pub use settings::*; diff --git a/src/bottles/platform.rs b/src/bottles/platform.rs new file mode 100644 index 0000000..dccad5c --- /dev/null +++ b/src/bottles/platform.rs @@ -0,0 +1,136 @@ +use std::{error::Error, process::Command}; + +use eframe::epaint::ahash::HashMap; +use serde::{Deserialize, Serialize}; + +use crate::platform::Platform; + +use super::BottlesSettings; +use steam_shortcuts_util::{shortcut::ShortcutOwned, Shortcut}; + +#[derive(Debug, Deserialize, Serialize, Clone)] +pub struct BottlesPlatform { + pub settings: BottlesSettings, +} + +#[derive(Debug, Clone)] +pub struct BottlesApp { + pub name: String, + pub bottle: String, +} + +impl From for ShortcutOwned { + fn from(app: BottlesApp) -> Self { + // + let launch_parameter = format!( + "run --command=bottles-cli com.usebottles.bottles run -b \"{}\" -p \"{}\"", + app.bottle, app.name + ); + Shortcut::new("0", &app.name, "flatpak", "", "", "", &launch_parameter).to_owned() + } +} + +impl Platform> for BottlesPlatform { + fn enabled(&self) -> bool { + self.settings.enabled + } + + fn name(&self) -> &str { + "Bottles" + } + + fn get_shortcuts(&self) -> Result, Box> { + let mut res = vec![]; + let bottles = get_bottles(); + dbg!(&bottles); + for bottle in bottles { + for (_id,program) in bottle.external_programs { + res.push(BottlesApp{ + name:program.name, + bottle: bottle.name.clone() + }) + } + } + Ok(res) + } + + fn settings_valid(&self) -> crate::platform::SettingsValidity { + if let Ok(s) =self.get_shortcuts(){ + if !s.is_empty() { + return crate::platform::SettingsValidity::Valid; + } + } + crate::platform::SettingsValidity::Invalid { reason: String::from("Nothing found")} + } + + #[cfg(target_family = "unix")] + fn create_symlinks(&self) -> bool { + false + } + + fn needs_proton(&self, _input: &BottlesApp) -> bool { + false + } +} + +fn get_bottles() -> Vec { + let output_result = get_bottles_output(); + match output_result { + Ok(json) => { + let map : HashMap= serde_json::from_str(json.as_str()).unwrap_or_default(); + let mut res = vec![]; + for (_,value) in map{ + res.push(value); + } + res + }, + Err(_err) => vec![], + } +} + +fn get_bottles_output() -> Result> { + let output = { + #[cfg(not(feature = "flatpak"))] + { + let mut command = Command::new("flatpak"); + command + .arg("run") + .arg("--command=bottles-cli") + .arg("com.usebottles.bottles") + .arg("-j") + .arg("list") + .arg("bottles") + .output()? + } + #[cfg(feature = "flatpak")] + { + let mut command = Command::new("flatpak-spawn"); + command + .arg("--host") + .arg("flatpak") + .arg("run") + .arg("--command=bottles-cli") + .arg("com.usebottles.bottles") + .arg("-j") + .arg("list") + .arg("bottles") + .output()? + } + }; + Ok(String::from_utf8_lossy(&output.stdout).to_string()) +} + +#[derive(Deserialize,Debug)] +struct Bottle { + #[serde(alias = "Name")] + pub(crate) name: String, + #[serde(alias = "External_Programs")] + pub(crate) external_programs : HashMap, +} + +#[derive(Deserialize,Debug)] +struct Program { + #[serde(alias = "Name")] + pub(crate) name: String, +} + diff --git a/src/bottles/settings.rs b/src/bottles/settings.rs new file mode 100644 index 0000000..7fcb88c --- /dev/null +++ b/src/bottles/settings.rs @@ -0,0 +1,6 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Deserialize, Serialize, Clone)] +pub struct BottlesSettings { + pub enabled: bool, +} diff --git a/src/defaultconfig.toml b/src/defaultconfig.toml index c1669b7..fd9f725 100644 --- a/src/defaultconfig.toml +++ b/src/defaultconfig.toml @@ -43,10 +43,12 @@ default_launch_through_heroic = true [amazon] enabled = true - [flatpak] enabled = true +[bottles] +enabled = true + [steam] create_collections = false optimize_for_big_picture = false diff --git a/src/main.rs b/src/main.rs index 62459ee..4a60c77 100644 --- a/src/main.rs +++ b/src/main.rs @@ -17,6 +17,7 @@ mod steamgriddb; mod sync; mod ui; mod uplay; +mod bottles; fn main() { ensure_config_folder(); diff --git a/src/settings.rs b/src/settings.rs index 9ba22b3..9fbfb03 100644 --- a/src/settings.rs +++ b/src/settings.rs @@ -8,6 +8,9 @@ use crate::{ #[cfg(target_family = "unix")] use crate::heroic::HeroicSettings; +#[cfg(target_family = "unix")] +use crate::bottles::BottlesSettings; + use config::{Config, ConfigError, Environment, File}; use serde::{Deserialize, Serialize}; use std::env; @@ -30,6 +33,8 @@ pub struct Settings { pub heroic: HeroicSettings, pub amazon: AmazonSettings, pub flatpak: FlatpakSettings, + #[cfg(target_family = "unix")] + pub bottles: BottlesSettings, } impl Settings { diff --git a/src/sync/synchronization.rs b/src/sync/synchronization.rs index 1ff0f15..cbcfc31 100644 --- a/src/sync/synchronization.rs +++ b/src/sync/synchronization.rs @@ -224,6 +224,11 @@ pub fn get_platform_shortcuts(settings: &Settings) -> Vec<(String, Vec