1
0
Fork 0
mirror of https://github.com/Zedfrigg/ironbar.git synced 2025-04-20 11:54:23 +02:00
ironbar/src/desktop_file.rs

74 lines
2.1 KiB
Rust
Raw Normal View History

2022-08-14 14:30:13 +01:00
use std::collections::HashMap;
use std::fs::File;
use std::io;
use std::io::BufRead;
use std::path::PathBuf;
use walkdir::WalkDir;
/// Gets directories that should contain `.desktop` files
/// and exist on the filesystem.
fn find_application_dirs() -> Vec<PathBuf> {
let mut dirs = vec![PathBuf::from("/usr/share/applications")];
let user_dir = dirs::data_local_dir();
if let Some(mut user_dir) = user_dir {
user_dir.push("applications");
dirs.push(user_dir);
}
dirs.into_iter().filter(|dir| dir.exists()).collect()
}
/// Attempts to locate a `.desktop` file for an app id
/// (or app class).
///
/// A simple case-insensitive check is performed on filename == `app_id`.
pub fn find_desktop_file(app_id: &str) -> Option<PathBuf> {
let dirs = find_application_dirs();
for dir in dirs {
let mut walker = WalkDir::new(dir).max_depth(5).into_iter();
let entry = walker.find(|entry| {
entry.as_ref().map_or(false, |entry| {
2022-08-14 14:30:13 +01:00
let file_name = entry.file_name().to_string_lossy().to_lowercase();
let test_name = format!("{}.desktop", app_id.to_lowercase());
file_name == test_name
})
2022-08-14 14:30:13 +01:00
});
if let Some(Ok(entry)) = entry {
let path = entry.path().to_owned();
return Some(path);
}
}
None
}
/// Parses a desktop file into a flat hashmap of keys/values.
fn parse_desktop_file(path: PathBuf) -> io::Result<HashMap<String, String>> {
let file = File::open(path)?;
let lines = io::BufReader::new(file).lines();
let mut map = HashMap::new();
for line in lines.flatten() {
if let Some((key, value)) = line.split_once('=') {
2022-08-14 14:30:13 +01:00
map.insert(key.to_string(), value.to_string());
}
}
Ok(map)
}
/// Attempts to get the icon name from the app's `.desktop` file.
pub fn get_desktop_icon_name(app_id: &str) -> Option<String> {
find_desktop_file(app_id).and_then(|file| {
let map = parse_desktop_file(file);
map.map_or(None, |map| {
map.get("Icon").map(std::string::ToString::to_string)
})
})
2022-08-14 14:30:13 +01:00
}