Replace freedesktop_entry_parser with cosmic-mime-apps
This commit is contained in:
parent
3baaf4b452
commit
f0e41d701c
1 changed files with 45 additions and 91 deletions
136
src/mime_app.rs
136
src/mime_app.rs
|
|
@ -8,7 +8,6 @@ pub use mime_guess::Mime;
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
use std::{
|
use std::{
|
||||||
cmp::Ordering,
|
cmp::Ordering,
|
||||||
env,
|
|
||||||
ffi::OsStr,
|
ffi::OsStr,
|
||||||
fs, io,
|
fs, io,
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
|
|
@ -280,107 +279,62 @@ impl MimeAppCache {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let desktops: Vec<String> = env::var("XDG_CURRENT_DESKTOP")
|
let mut list = cosmic_mime_apps::List::default();
|
||||||
.unwrap_or_default()
|
|
||||||
.split(':')
|
|
||||||
.map(str::to_ascii_lowercase)
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
// Load mimeapps.list files
|
let paths = cosmic_mime_apps::list_paths();
|
||||||
// https://specifications.freedesktop.org/mime-apps-spec/mime-apps-spec-latest.html
|
list.load_from_paths(&paths);
|
||||||
//TODO: ensure correct lookup order
|
|
||||||
let mut mimeapps_paths = Vec::new();
|
|
||||||
let xdg_dirs = xdg::BaseDirectories::new();
|
|
||||||
|
|
||||||
mimeapps_paths.extend(xdg_dirs.find_data_files("applications/mimeapps.list"));
|
for (mime, filenames) in list
|
||||||
|
.added_associations
|
||||||
for desktop in desktops.iter().rev() {
|
.iter()
|
||||||
mimeapps_paths
|
.chain(list.default_apps.iter())
|
||||||
.extend(xdg_dirs.find_data_files(format!("applications/{desktop}-mimeapps.list")));
|
{
|
||||||
}
|
for filename in filenames {
|
||||||
|
log::trace!("add {mime}={filename}");
|
||||||
mimeapps_paths.extend(xdg_dirs.find_config_files("mimeapps.list"));
|
let apps = self
|
||||||
|
.cache
|
||||||
for desktop in desktops.iter().rev() {
|
.entry(mime.clone())
|
||||||
mimeapps_paths.extend(xdg_dirs.find_config_files(format!("{desktop}-mimeapps.list")));
|
.or_insert_with(|| Vec::with_capacity(1));
|
||||||
}
|
if !apps.iter().any(|x| filename_eq(&x.path, filename)) {
|
||||||
|
if let Some(app) = all_apps.iter().find(|&x| filename_eq(&x.path, filename)) {
|
||||||
//TODO: handle directory specific behavior
|
apps.push(MimeApp::from(app));
|
||||||
for path in mimeapps_paths {
|
} else {
|
||||||
let entry = match freedesktop_entry_parser::parse_entry(&path) {
|
log::info!(
|
||||||
Ok(ok) => ok,
|
"failed to add association for {mime:?}: application {filename:?} not found"
|
||||||
Err(err) => {
|
);
|
||||||
log::warn!("failed to parse {}: {}", path.display(), err);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
for attr in entry
|
|
||||||
.section("Added Associations")
|
|
||||||
.attrs()
|
|
||||||
.chain(entry.section("Default Applications").attrs())
|
|
||||||
{
|
|
||||||
if let Ok(mime) = attr.name.parse::<Mime>() {
|
|
||||||
if let Some(filenames) = attr.value {
|
|
||||||
for filename in filenames.split_terminator(';') {
|
|
||||||
log::trace!("add {mime}={filename}");
|
|
||||||
let apps = self
|
|
||||||
.cache
|
|
||||||
.entry(mime.clone())
|
|
||||||
.or_insert_with(|| Vec::with_capacity(1));
|
|
||||||
if !apps.iter().any(|x| filename_eq(&x.path, filename)) {
|
|
||||||
if let Some(app) =
|
|
||||||
all_apps.iter().find(|&x| filename_eq(&x.path, filename))
|
|
||||||
{
|
|
||||||
apps.push(MimeApp::from(app));
|
|
||||||
} else {
|
|
||||||
log::info!(
|
|
||||||
"failed to add association for {mime:?}: application {filename:?} not found"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for attr in entry.section("Removed Associations").attrs() {
|
for (mime, filenames) in list.removed_associations.iter() {
|
||||||
if let Ok(mime) = attr.name.parse::<Mime>() {
|
for filename in filenames {
|
||||||
if let Some(filenames) = attr.value {
|
log::trace!("remove {mime}={filename}");
|
||||||
for filename in filenames.split_terminator(';') {
|
if let Some(apps) = self.cache.get_mut(&mime) {
|
||||||
log::trace!("remove {mime}={filename}");
|
apps.retain(|x| !filename_eq(&x.path, filename));
|
||||||
if let Some(apps) = self.cache.get_mut(&mime) {
|
|
||||||
apps.retain(|x| !filename_eq(&x.path, filename));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for attr in entry.section("Default Applications").attrs() {
|
for (mime, filenames) in list.default_apps.iter() {
|
||||||
if let Ok(mime) = attr.name.parse::<Mime>() {
|
for filename in filenames {
|
||||||
if let Some(filenames) = attr.value {
|
log::trace!("default {mime}={filename}");
|
||||||
for filename in filenames.split_terminator(';') {
|
if let Some(apps) = self.cache.get_mut(&mime) {
|
||||||
log::trace!("default {mime}={filename}");
|
let mut found = false;
|
||||||
if let Some(apps) = self.cache.get_mut(&mime) {
|
for app in apps.iter_mut() {
|
||||||
let mut found = false;
|
if filename_eq(&app.path, filename) {
|
||||||
for app in apps.iter_mut() {
|
app.is_default = true;
|
||||||
if filename_eq(&app.path, filename) {
|
found = true;
|
||||||
app.is_default = true;
|
} else {
|
||||||
found = true;
|
app.is_default = false;
|
||||||
} else {
|
|
||||||
app.is_default = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if found {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
log::debug!(
|
|
||||||
"failed to set default for {mime:?}: application {filename:?} not found"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if found {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
log::debug!(
|
||||||
|
"failed to set default for {mime:?}: application {filename:?} not found"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue