soar_core/package/formats/
appimage.rs1use std::{fs, path::Path};
2
3use squishy::{appimage::AppImage, EntryKind};
4
5use crate::{
6 constants::PNG_MAGIC_BYTES, database::models::PackageExt, error::ErrorContext,
7 utils::calc_magic_bytes, SoarResult,
8};
9
10use super::common::{symlink_desktop, symlink_icon};
11
12pub async fn integrate_appimage<P: AsRef<Path>, T: PackageExt>(
13 install_dir: P,
14 file_path: P,
15 package: &T,
16 has_icon: bool,
17 has_desktop: bool,
18) -> SoarResult<()> {
19 if has_icon && has_desktop {
20 return Ok(());
21 }
22
23 let install_dir = install_dir.as_ref();
24 let pkg_name = package.pkg_name();
25 let appimage = AppImage::new(None, &file_path, None)?;
26 let squashfs = &appimage.squashfs;
27
28 if !has_icon {
29 if let Some(entry) = appimage.find_icon() {
30 if let EntryKind::File(basic_file) = entry.kind {
31 let dest = format!("{}/{}.DirIcon", install_dir.display(), pkg_name);
32 let _ = squashfs.write_file(basic_file, &dest);
33
34 let magic_bytes = calc_magic_bytes(&dest, 8)?;
35 let ext = if magic_bytes == PNG_MAGIC_BYTES {
36 "png"
37 } else {
38 "svg"
39 };
40 let final_path = format!("{}/{}.{ext}", install_dir.display(), pkg_name);
41 fs::rename(&dest, &final_path)
42 .with_context(|| format!("renaming from {dest} to {final_path}"))?;
43
44 symlink_icon(final_path)?;
45 }
46 }
47 }
48
49 if !has_desktop {
50 if let Some(entry) = appimage.find_desktop() {
51 if let EntryKind::File(basic_file) = entry.kind {
52 let dest = format!("{}/{}.desktop", install_dir.display(), pkg_name);
53 let _ = squashfs.write_file(basic_file, &dest);
54 symlink_desktop(dest, package)?;
55 }
56 }
57 }
58
59 if let Some(entry) = appimage.find_appstream() {
60 if let EntryKind::File(basic_file) = entry.kind {
61 let file_name = if entry
62 .path
63 .file_name()
64 .unwrap()
65 .to_string_lossy()
66 .contains("appdata")
67 {
68 "appdata"
69 } else {
70 "metainfo"
71 };
72 let dest = format!("{}/{}.{file_name}.xml", install_dir.display(), pkg_name);
73 let _ = squashfs.write_file(basic_file, &dest);
74 }
75 }
76 Ok(())
77}