Reverted xdg.rs

This commit is contained in:
Nicola Guerrera
2023-05-14 19:31:16 +02:00
parent 7ac6133aa9
commit ac3961e713
2 changed files with 4 additions and 213 deletions

View File

@@ -44,9 +44,6 @@ fn model_from_icon(parent: &Spatial, icon: &Icon) -> Result<Model> {
&ResourceID::new_namespaced("protostar", "hexagon/hexagon"), &ResourceID::new_namespaced("protostar", "hexagon/hexagon"),
)?; )?;
let model_part = model.model_part("hexagon/hexagon").unwrap(); let model_part = model.model_part("hexagon/hexagon").unwrap();
model_part
.set_material_parameter("color", MaterialParameter::Color([0.0, 1.0, 1.0, 1.0]))?;
model_part.set_material_parameter(
model model
.model_part("Hex")? .model_part("Hex")?
.set_material_parameter("color", MaterialParameter::Color([0.0, 1.0, 1.0, 1.0]))?; .set_material_parameter("color", MaterialParameter::Color([0.0, 1.0, 1.0, 1.0]))?;
@@ -113,7 +110,7 @@ impl ProtoStar {
None => {} None => {}
} }
Self::new_raw(
pub fn create_from_desktop_file( pub fn create_from_desktop_file(
parent: &Spatial, parent: &Spatial,
position: impl Into<Vector3<f32>>, position: impl Into<Vector3<f32>>,
@@ -129,7 +126,8 @@ impl ProtoStar {
desktop_file.name.as_deref(), desktop_file.name.as_deref(),
icon, icon,
desktop_file.command.ok_or_else(|| eyre!("No command"))?, desktop_file.command.ok_or_else(|| eyre!("No command"))?,
) );
} }
pub fn new_raw( pub fn new_raw(
parent: &Spatial, parent: &Spatial,

View File

@@ -2,9 +2,6 @@ use color_eyre::eyre::Result;
use lazy_static::lazy_static; use lazy_static::lazy_static;
use linicon; use linicon;
use regex::Regex; use regex::Regex;
use lazy_static::lazy_static;
use linicon;
use regex::Regex;
use resvg::render; use resvg::render;
use resvg::tiny_skia::{Pixmap, Transform}; use resvg::tiny_skia::{Pixmap, Transform};
use resvg::usvg::{FitTo, Tree}; use resvg::usvg::{FitTo, Tree};
@@ -12,21 +9,14 @@ use serde::{Deserialize, Serialize};
use serde_json; use serde_json;
use serde_with::serde_as; use serde_with::serde_as;
use std::collections::HashMap; use std::collections::HashMap;
use serde::{Deserialize, Serialize};
use serde_json;
use serde_with::serde_as;
use std::collections::HashMap;
use std::ffi::OsString; use std::ffi::OsString;
use std::fs::create_dir_all; use std::fs::create_dir_all;
use std::fs::File; use std::fs::File;
use std::fs::File;
use std::io::{BufRead, BufReader, ErrorKind}; use std::io::{BufRead, BufReader, ErrorKind};
use std::io::{Read, Write}; use std::io::{Read, Write};
use std::io::{Read, Write};
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::str::FromStr; use std::str::FromStr;
use std::sync::Mutex; use std::sync::Mutex;
use std::sync::Mutex;
use std::{env, fs}; use std::{env, fs};
use walkdir::WalkDir; use walkdir::WalkDir;
@@ -67,69 +57,19 @@ impl ImageCache {
} }
} }
lazy_static! {
static ref IMAGE_CACHE: Mutex<ImageCache> = Mutex::new(ImageCache::new(
get_image_cache_dir().join("imagechache.map")
));
}
#[serde_as]
#[derive(Deserialize, Serialize)]
struct ImageCache {
path: PathBuf,
#[serde_as(as = "Vec<(_, _)>")]
pub map: HashMap<String, PathBuf>,
}
impl ImageCache {
fn new(path: PathBuf) -> Self {
if let Ok(mut file) = File::open(&path) {
let mut buf = vec![];
if file.read_to_end(&mut buf).is_ok() {
if let Ok(cache) = serde_json::from_slice(&buf[..]) {
return cache;
}
}
}
//There was no file, or the file failed to load, create a new World.
ImageCache {
path,
map: HashMap::new(),
}
}
fn insert(&mut self, k: String, v: PathBuf) {
self.map.insert(k, v);
}
fn save(&self) {
let mut f = File::create(&self.path).unwrap();
let buf = serde_json::to_vec(&self).unwrap();
f.write_all(&buf[..]).unwrap();
}
}
lazy_static! { lazy_static! {
static ref IMAGE_CACHE: Mutex<ImageCache> = Mutex::new(ImageCache::new( static ref IMAGE_CACHE: Mutex<ImageCache> = Mutex::new(ImageCache::new(
get_image_cache_dir().join("imagechache.map") get_image_cache_dir().join("imagechache.map")
)); ));
} }
fn get_data_dirs() -> Vec<PathBuf> {
let xdg_data_dirs_str = std::env::var("XDG_DATA_DIRS").unwrap_or_default();
fn get_data_dirs() -> Vec<PathBuf> { fn get_data_dirs() -> Vec<PathBuf> {
let xdg_data_dirs_str = std::env::var("XDG_DATA_DIRS").unwrap_or_default(); let xdg_data_dirs_str = std::env::var("XDG_DATA_DIRS").unwrap_or_default();
let xdg_data_dirs = xdg_data_dirs_str
let xdg_data_dirs = xdg_data_dirs_str let xdg_data_dirs = xdg_data_dirs_str
.split(":") .split(":")
.filter_map(|dir| PathBuf::from_str(dir).ok()); .filter_map(|dir| PathBuf::from_str(dir).ok());
.filter_map(|dir| PathBuf::from_str(dir).ok());
let data_home = dirs::home_dir()
.unwrap_or(PathBuf::from_str("/usr/share/").expect(
"No XDG_DATA_DIR set, no HOME directory found and no /usr/share direcotry found",
))
let data_home = dirs::home_dir() let data_home = dirs::home_dir()
.unwrap_or(PathBuf::from_str("/usr/share/").expect( .unwrap_or(PathBuf::from_str("/usr/share/").expect(
"No XDG_DATA_DIR set, no HOME directory found and no /usr/share direcotry found", "No XDG_DATA_DIR set, no HOME directory found and no /usr/share direcotry found",
@@ -150,30 +90,12 @@ fn get_app_dirs() -> Vec<PathBuf> {
.filter(|dir| dir.exists() && dir.is_dir()) .filter(|dir| dir.exists() && dir.is_dir())
.collect() .collect()
} }
.join("share");
xdg_data_dirs
.chain([data_home].into_iter())
.filter(|dir| dir.exists() && dir.is_dir())
.collect()
}
fn get_app_dirs() -> Vec<PathBuf> {
get_data_dirs()
.into_iter()
.map(|dir| dir.join("applications"))
.filter(|dir| dir.exists() && dir.is_dir())
.collect()
}
pub fn get_desktop_files() -> Vec<PathBuf> {
pub fn get_desktop_files() -> Vec<PathBuf> { pub fn get_desktop_files() -> Vec<PathBuf> {
let desktop_extension = OsString::from_str("desktop").unwrap(); let desktop_extension = OsString::from_str("desktop").unwrap();
// Get the list of directories to search // Get the list of directories to search
let app_dirs = get_app_dirs(); let app_dirs = get_app_dirs();
let app_dirs = get_app_dirs();
app_dirs app_dirs
.into_iter()
.into_iter() .into_iter()
.flat_map(|dir| { .flat_map(|dir| {
// Follow symlinks and recursively search directories // Follow symlinks and recursively search directories
@@ -218,10 +140,6 @@ pub fn parse_desktop_file(path: PathBuf) -> Result<DesktopFile, String> {
let mut no_display = false; let mut no_display = false;
let mut desktop_entry_found = false; let mut desktop_entry_found = false;
let re = Regex::new(r"^\[([^\]]*)\]$").unwrap();
let mut no_display = false;
let mut desktop_entry_found = false;
let re = Regex::new(r"^\[([^\]]*)\]$").unwrap(); let re = Regex::new(r"^\[([^\]]*)\]$").unwrap();
// Loop through each line of the file // Loop through each line of the file
@@ -241,14 +159,6 @@ pub fn parse_desktop_file(path: PathBuf) -> Result<DesktopFile, String> {
desktop_entry_found = entry.as_str().contains("Desktop Entry"); desktop_entry_found = entry.as_str().contains("Desktop Entry");
} }
if !desktop_entry_found {
continue;
}
if let Some(captures) = re.captures(&line) {
let entry = captures.get(1).unwrap();
desktop_entry_found = entry.as_str().contains("Desktop Entry");
}
if !desktop_entry_found { if !desktop_entry_found {
continue; continue;
} }
@@ -277,12 +187,6 @@ pub fn parse_desktop_file(path: PathBuf) -> Result<DesktopFile, String> {
_ => false, _ => false,
} }
} }
"NoDisplay" => {
no_display = match value {
"true" => true,
_ => false,
}
}
_ => (), // Ignore unknown keys _ => (), // Ignore unknown keys
} }
} }
@@ -295,7 +199,6 @@ pub fn parse_desktop_file(path: PathBuf) -> Result<DesktopFile, String> {
categories, categories,
icon, icon,
no_display, no_display,
no_display,
}) })
} }
@@ -328,7 +231,6 @@ pub struct DesktopFile {
pub categories: Vec<String>, pub categories: Vec<String>,
pub icon: Option<String>, pub icon: Option<String>,
pub no_display: bool, pub no_display: bool,
pub no_display: bool,
} }
impl DesktopFile { impl DesktopFile {
pub fn get_raw_icons(&self) -> Vec<Icon> { pub fn get_raw_icons(&self) -> Vec<Icon> {
@@ -341,13 +243,6 @@ impl DesktopFile {
} }
} }
if let Some(cache_icon_path) = IMAGE_CACHE.lock().unwrap().map.get(icon_name) {
if cache_icon_path.exists() {
if let Some(icon) = Icon::from_path(cache_icon_path.to_owned(), 128) {
return vec![icon];
}
}
}
if let Some(cache_icon_path) = IMAGE_CACHE.lock().unwrap().map.get(icon_name) { if let Some(cache_icon_path) = IMAGE_CACHE.lock().unwrap().map.get(icon_name) {
if cache_icon_path.exists() { if cache_icon_path.exists() {
if let Some(icon) = Icon::from_path(cache_icon_path.to_owned(), 128) { if let Some(icon) = Icon::from_path(cache_icon_path.to_owned(), 128) {
@@ -356,9 +251,6 @@ impl DesktopFile {
} }
} }
let mut icons_iter = linicon::lookup_icon(icon_name)
.use_fallback_themes(false)
.peekable();
let mut icons_iter = linicon::lookup_icon(icon_name) let mut icons_iter = linicon::lookup_icon(icon_name)
.use_fallback_themes(false) .use_fallback_themes(false)
.peekable(); .peekable();
@@ -367,10 +259,6 @@ impl DesktopFile {
//dbg!("No icons found in current theme"); //dbg!("No icons found in current theme");
icons_iter = linicon::lookup_icon(icon_name).peekable(); icons_iter = linicon::lookup_icon(icon_name).peekable();
} }
if icons_iter.peek().is_none() {
//dbg!("No icons found in current theme");
icons_iter = linicon::lookup_icon(icon_name).peekable();
}
let sized_png: Vec<Icon> = icons_iter let sized_png: Vec<Icon> = icons_iter
.filter_map(|i| i.ok()) .filter_map(|i| i.ok())
@@ -378,20 +266,9 @@ impl DesktopFile {
.map(|i| Icon::from_path(i.path, i.max_size - 2).unwrap()) .map(|i| Icon::from_path(i.path, i.max_size - 2).unwrap())
.collect(); .collect();
sized_png sized_png
let sized_png: Vec<Icon> = icons_iter
.filter_map(|i| i.ok())
.filter(|i| i.icon_type != linicon::IconType::XMP) //TODO: support XMP
.map(|i| Icon::from_path(i.path, i.max_size - 2).unwrap())
.collect();
sized_png
} }
} }
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct Icon {
pub icon_type: IconType,
pub path: PathBuf,
pub size: u16,
#[derive(Debug, PartialEq, Eq, Clone)] #[derive(Debug, PartialEq, Eq, Clone)]
pub struct Icon { pub struct Icon {
pub icon_type: IconType, pub icon_type: IconType,
@@ -399,26 +276,6 @@ pub struct Icon {
pub size: u16, pub size: u16,
} }
#[derive(Debug, PartialEq, Eq, Clone)]
pub enum IconType {
Png,
Svg,
Gltf,
}
impl Icon {
pub fn from_path(path: PathBuf, size: u16) -> Option<Icon> {
let icon_type = match path.extension().and_then(|ext| ext.to_str()) {
Some("png") => IconType::Png,
Some("svg") => IconType::Svg,
Some("glb") | Some("gltf") => IconType::Gltf,
_ => return None,
};
return Some(Icon {
icon_type,
path,
size,
});
#[derive(Debug, PartialEq, Eq, Clone)] #[derive(Debug, PartialEq, Eq, Clone)]
pub enum IconType { pub enum IconType {
Png, Png,
@@ -440,33 +297,6 @@ impl Icon {
}); });
} }
pub fn cached_process(self, size: u16) -> Result<Icon, std::io::Error> {
if !IMAGE_CACHE.lock().unwrap().map.contains_key(
&self
.path
.with_extension("")
.file_name()
.unwrap()
.to_str()
.unwrap()
.to_owned(),
) {
dbg!("Saving value in the DB");
IMAGE_CACHE.lock().unwrap().insert(
self.path
.with_extension("")
.file_name()
.unwrap()
.to_str()
.unwrap()
.to_owned(),
self.path.clone(),
);
IMAGE_CACHE.lock().unwrap().save();
}
match self.icon_type {
IconType::Svg => Ok(Icon::from_path(get_png_from_svg(self.path, size)?, size).unwrap()),
_ => Ok(self),
pub fn cached_process(self, size: u16) -> Result<Icon, std::io::Error> { pub fn cached_process(self, size: u16) -> Result<Icon, std::io::Error> {
if !IMAGE_CACHE.lock().unwrap().map.contains_key( if !IMAGE_CACHE.lock().unwrap().map.contains_key(
&self &self
@@ -508,11 +338,10 @@ fn test_get_icon_path() {
categories: vec![], categories: vec![],
icon: Some("krita".into()), icon: Some("krita".into()),
no_display: false, no_display: false,
no_display: false,
}; };
// Call the get_icon_path() function with a size argument and store the result // Call the get_icon_path() function with a size argument and store the result
let icon_paths = desktop_file.get_raw_icons(128); let icon_paths = desktop_file.get_raw_icons();
dbg!(&icon_paths); dbg!(&icon_paths);
// Assert that the get_icon_path() function returns the expected result // Assert that the get_icon_path() function returns the expected result
@@ -523,26 +352,8 @@ fn test_get_icon_path() {
) )
.unwrap() .unwrap()
)); ));
assert!(icon_paths.contains(
&Icon::from_path(
PathBuf::from("/usr/share/icons/hicolor/32x32/apps/krita.png"),
32
)
.unwrap()
));
} }
pub fn get_image_cache_dir() -> PathBuf {
let cache_dir;
if let Ok(xdg_cache_home) = std::env::var("XDG_CACHE_HOME") {
cache_dir =
PathBuf::from_str(&xdg_cache_home).unwrap_or(dirs::home_dir().unwrap().join(".cache"))
} else {
cache_dir = dirs::home_dir().unwrap().join(".cache");
}
let image_cache_dir = cache_dir.join("protostar_icon_cache");
create_dir_all(&image_cache_dir).expect("Could not create image cache directory");
return image_cache_dir;
pub fn get_image_cache_dir() -> PathBuf { pub fn get_image_cache_dir() -> PathBuf {
let cache_dir; let cache_dir;
if let Ok(xdg_cache_home) = std::env::var("XDG_CACHE_HOME") { if let Ok(xdg_cache_home) = std::env::var("XDG_CACHE_HOME") {
@@ -556,7 +367,6 @@ pub fn get_image_cache_dir() -> PathBuf {
return image_cache_dir; return image_cache_dir;
} }
pub fn get_png_from_svg(svg_path: impl AsRef<Path>, size: u16) -> Result<PathBuf, std::io::Error> {
pub fn get_png_from_svg(svg_path: impl AsRef<Path>, size: u16) -> Result<PathBuf, std::io::Error> { pub fn get_png_from_svg(svg_path: impl AsRef<Path>, size: u16) -> Result<PathBuf, std::io::Error> {
let svg_path = fs::canonicalize(svg_path)?; let svg_path = fs::canonicalize(svg_path)?;
let svg_data = fs::read(svg_path.as_path())?; let svg_data = fs::read(svg_path.as_path())?;
@@ -573,26 +383,10 @@ pub fn get_png_from_svg(svg_path: impl AsRef<Path>, size: u16) -> Result<PathBuf
return Ok(png_path); return Ok(png_path);
} }
let mut pixmap = Pixmap::new(size.into(), size.into()).unwrap();
let svg_data = fs::read(svg_path.as_path())?;
let tree = Tree::from_data(svg_data.as_slice(), &resvg::usvg::Options::default())
.map_err(|_| ErrorKind::InvalidData)?;
let png_path = get_image_cache_dir().join(format!(
"{}-{}.png",
svg_path.file_name().unwrap().to_str().unwrap(),
svg_data.len()
));
if png_path.exists() {
return Ok(png_path);
}
let mut pixmap = Pixmap::new(size.into(), size.into()).unwrap(); let mut pixmap = Pixmap::new(size.into(), size.into()).unwrap();
render( render(
&tree, &tree,
FitTo::Width(size.into()), FitTo::Width(size.into()),
FitTo::Width(size.into()),
Transform::identity(), Transform::identity(),
pixmap.as_mut(), pixmap.as_mut(),
); );
@@ -617,7 +411,6 @@ fn test_render_svg_to_png() {
// Call the function with the test input and output paths and a size of 200 // Call the function with the test input and output paths and a size of 200
let png_path = get_png_from_svg(&svg_path, 200).unwrap(); let png_path = get_png_from_svg(&svg_path, 200).unwrap();
let png_path = get_png_from_svg(&svg_path, 200).unwrap();
dbg!(&png_path); dbg!(&png_path);
// Check that the output file exists // Check that the output file exists