Skip to content

Commit

Permalink
feat: Separate dirs for different lifetimes
Browse files Browse the repository at this point in the history
  • Loading branch information
ryanabx committed Apr 27, 2024
1 parent 08d2b30 commit 640cd7b
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 41 deletions.
2 changes: 1 addition & 1 deletion profile.d/desktop-entry-daemon.sh
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# set XDG_DATA_DIRS to include desktop-entry-daemon installations
export XDG_DATA_DIRS
XDG_DATA_DIRS="$XDG_DATA_DIRS:$HOME/.cache/desktop-entry-daemon/:$XDG_RUNTIME_DIR/desktop-entry-daemon/"
XDG_DATA_DIRS="$XDG_DATA_DIRS:$HOME/.cache/desktop-entry-daemon/:$XDG_RUNTIME_DIR/desktop-entry-daemon/session/:$XDG_RUNTIME_DIR/desktop-entry-daemon/proc/"
87 changes: 64 additions & 23 deletions src/entry_management.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,9 @@ impl Lifetime {
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct EntryManager {
pub cache: EntryCache,
pub temp_entry_dir: PathBuf,
pub temp_icon_dir: PathBuf,
pub persistent_entry_dir: PathBuf,
pub persistent_icon_dir: PathBuf,
pub proc_dir: PathBuf,
pub session_dir: PathBuf,
pub persistent_dir: PathBuf,
pub config_file: PathBuf,
pub change_handlers: HashSet<u32>,
}
Expand All @@ -101,6 +100,12 @@ pub struct EntryCache {
pub icons: HashMap<Lifetime, Vec<IconHandle>>,
}

#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub enum ResourceType {
DesktopEntry,
Icon,
}

pub enum ConfigError {
IO(std::io::Error),
Parse(SpannedError),
Expand All @@ -127,13 +132,17 @@ impl EntryCache {
}

impl EntryManager {
pub fn new(tmp_dir: PathBuf, persistent_dir: PathBuf, config_file: PathBuf) -> Self {
pub fn new(
proc_dir: PathBuf,
session_dir: PathBuf,
persistent_dir: PathBuf,
config_file: PathBuf,
) -> Self {
let mut manager = Self {
cache: EntryCache::new(&config_file).unwrap_or_default(),
temp_entry_dir: tmp_dir.join(Path::new("applications")),
temp_icon_dir: tmp_dir.join(Path::new("icons")),
persistent_entry_dir: persistent_dir.join(Path::new("applications")),
persistent_icon_dir: persistent_dir.join(Path::new("icons")),
proc_dir,
session_dir,
persistent_dir,
config_file,
change_handlers: HashSet::new(),
};
Expand All @@ -145,6 +154,28 @@ impl EntryManager {
}
manager
}
pub fn directory_for_lifetime(
&self,
lifetime: Lifetime,
resource_type: ResourceType,
) -> PathBuf {
match (lifetime, resource_type) {
(Lifetime::Process(_), ResourceType::DesktopEntry) => {
self.proc_dir.join(Path::new("applications"))
}
(Lifetime::Process(_), ResourceType::Icon) => self.proc_dir.join(Path::new("icons")),
(Lifetime::Session(_), ResourceType::DesktopEntry) => {
self.session_dir.join(Path::new("applications"))
}
(Lifetime::Session(_), ResourceType::Icon) => self.session_dir.join(Path::new("icons")),
(Lifetime::Persistent(_), ResourceType::DesktopEntry) => {
self.persistent_dir.join(Path::new("applications"))
}
(Lifetime::Persistent(_), ResourceType::Icon) => {
self.persistent_dir.join(Path::new("icons"))
}
}
}
/// responsible for registering a desktop `entry` with a given `lifetime`. saves file as
/// `appid`.desktop, and can be referred to with the specified appid
pub fn register_entry(
Expand All @@ -156,7 +187,7 @@ impl EntryManager {
// validate entry
let entry = validate_desktop_entry(entry, appid)?;
let desktop_file_path = self
.temp_entry_dir
.directory_for_lifetime(lifetime.clone(), ResourceType::DesktopEntry)
.as_path()
.join(format!("{}.desktop", appid));
if desktop_file_path.exists() {
Expand Down Expand Up @@ -196,10 +227,10 @@ impl EntryManager {
.decode()
{
// image sent as bytes
self.icon_as_bytes(&img, icon_name)?
self.icon_as_bytes(&img, icon_name, lifetime.clone())?
} else if let Ok(text_data) = String::from_utf8(icon_data.into()) {
// image sent as svg
self.icon_as_svg(text_data, icon_name)?
self.icon_as_svg(text_data, icon_name, lifetime.clone())?
} else {
return Err(EntryManagerError::IconValidation(
IconValidationError::NoTypeFound,
Expand All @@ -225,6 +256,7 @@ impl EntryManager {
&self,
img: &DynamicImage,
icon_name: &str,
lifetime: Lifetime,
) -> Result<PathBuf, EntryManagerError> {
log::info!("{} is a valid image as bytes", icon_name);
if img.width() != img.height() {
Expand All @@ -239,12 +271,14 @@ impl EntryManager {
} else {
img.to_owned()
};
let icon_path = self.temp_icon_dir.join(Path::new(&format!(
"hicolor/{}x{}/apps/{}.png",
img.width(),
img.height(),
icon_name
)));
let icon_path = self
.directory_for_lifetime(lifetime, ResourceType::Icon)
.join(Path::new(&format!(
"hicolor/{}x{}/apps/{}.png",
img.width(),
img.height(),
icon_name
)));
let _ = create_dir_all(icon_path.parent().unwrap());
if icon_path.exists() {
return Err(EntryManagerError::PathCollision(icon_path));
Expand All @@ -253,13 +287,20 @@ impl EntryManager {
Ok(icon_path)
}

fn icon_as_svg(&self, svg_text: String, icon_name: &str) -> Result<PathBuf, EntryManagerError> {
fn icon_as_svg(
&self,
svg_text: String,
icon_name: &str,
lifetime: Lifetime,
) -> Result<PathBuf, EntryManagerError> {
// check for valid svg
svg::read(&svg_text)?;
let icon_path = self.temp_icon_dir.join(Path::new(&format!(
"hicolor/scalable/apps/{}.svg",
icon_name
)));
let icon_path = self
.directory_for_lifetime(lifetime, ResourceType::Icon)
.join(Path::new(&format!(
"hicolor/scalable/apps/{}.svg",
icon_name
)));
let _ = create_dir_all(icon_path.parent().unwrap());
if icon_path.exists() {
return Err(EntryManagerError::PathCollision(icon_path));
Expand Down
5 changes: 3 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@ mod tools;
#[async_std::main]
async fn main() -> ZbusResult<()> {
env_logger::init();
let (tmp_dir, persistent_dir, config_file) = get_dirs();
let (proc_dir, session_dir, persistent_dir, config_file) = get_dirs();
let manager = Arc::new(Mutex::new(EntryManager::new(
tmp_dir,
proc_dir,
session_dir,
persistent_dir,
config_file,
)));
Expand Down
47 changes: 32 additions & 15 deletions src/tools.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,22 +36,37 @@ fn app_exists(id: &str) -> bool {
false
}

pub fn get_dirs() -> (PathBuf, PathBuf, PathBuf) {
pub fn get_dirs() -> (PathBuf, PathBuf, PathBuf, PathBuf) {
let home_str = env::var("HOME").unwrap();
let runtime_dir_str = env::var("RUNTIME_DIRECTORY").unwrap_or(format!(
"/run/user/{}/desktop-entry-daemon/",
let proc_dir_str = env::var("RUNTIME_DIRECTORY").unwrap_or(format!(
"/run/user/{}/desktop-entry-daemon/proc/",
env::var("UID").unwrap_or("1000".to_string())
));
let tmp_dir = Path::new(&runtime_dir_str);
if !tmp_dir.exists() {
let proc_dir = Path::new(&proc_dir_str);
if !proc_dir.exists() {
log::warn!(
"tmp_dir {} does not exist! creating directory...",
tmp_dir.to_str().unwrap()
"proc_dir {} does not exist! creating directory...",
proc_dir.to_str().unwrap()
);
fs::create_dir(tmp_dir).unwrap();
fs::create_dir(proc_dir).unwrap();
}
let _ = fs::create_dir(tmp_dir.join(Path::new("applications")));
let _ = fs::create_dir(tmp_dir.join(Path::new("icons")));
let _ = fs::create_dir(proc_dir.join(Path::new("applications")));
let _ = fs::create_dir(proc_dir.join(Path::new("icons")));

let session_dir_str = env::var("RUNTIME_DIRECTORY").unwrap_or(format!(
"/run/user/{}/desktop-entry-daemon/session/",
env::var("UID").unwrap_or("1000".to_string())
));
let session_dir = Path::new(&session_dir_str);
if !session_dir.exists() {
log::warn!(
"session_dir {} does not exist! creating directory...",
session_dir.to_str().unwrap()
);
fs::create_dir(session_dir).unwrap();
}
let _ = fs::create_dir(session_dir.join(Path::new("applications")));
let _ = fs::create_dir(session_dir.join(Path::new("icons")));

let persistent_dir_str = format!("{}/.cache/desktop-entry-daemon/", home_str);
let persistent_dir = Path::new(&persistent_dir_str);
Expand All @@ -62,20 +77,22 @@ pub fn get_dirs() -> (PathBuf, PathBuf, PathBuf) {
);
fs::create_dir(persistent_dir).unwrap();
}
let _ = fs::create_dir(tmp_dir.join(Path::new("applications")));
let _ = fs::create_dir(tmp_dir.join(Path::new("icons")));
let _ = fs::create_dir(proc_dir.join(Path::new("applications")));
let _ = fs::create_dir(proc_dir.join(Path::new("icons")));

let config_file_str = format!("{}/.config/desktop-entry-daemon/cache.ron", home_str);
let config_file = Path::new(&config_file_str);
let _ = fs::create_dir(config_file.parent().unwrap());
log::debug!(
"tmp_dir: {:?} | persistent_dir: {:?} | config_file: {:?}",
tmp_dir,
"proc_dir: {:?} | session_dir: {:?} | persistent_dir: {:?} | config_file: {:?}",
proc_dir,
session_dir,
persistent_dir,
config_file,
);
(
tmp_dir.to_owned(),
proc_dir.to_owned(),
session_dir.to_owned(),
persistent_dir.to_owned(),
config_file.to_owned(),
)
Expand Down

0 comments on commit 640cd7b

Please sign in to comment.