eds: still not able to resolve sometimes, some AI generated attempts at solving
This commit is contained in:
@@ -5,7 +5,6 @@ use once_cell::sync::OnceCell;
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
use std::thread;
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct EDSContactResolverBackend;
|
pub struct EDSContactResolverBackend;
|
||||||
@@ -39,16 +38,40 @@ impl AddressBookHandle {
|
|||||||
/// Obtain the global address-book handle, initialising it on the first call.
|
/// Obtain the global address-book handle, initialising it on the first call.
|
||||||
static ADDRESS_BOOK_HANDLE: OnceCell<Mutex<AddressBookHandle>> = OnceCell::new();
|
static ADDRESS_BOOK_HANDLE: OnceCell<Mutex<AddressBookHandle>> = OnceCell::new();
|
||||||
|
|
||||||
fn get_address_book_handle() -> Option<&'static Mutex<AddressBookHandle>> {
|
/// Check whether a given well-known name currently has an owner on the bus.
|
||||||
ADDRESS_BOOK_HANDLE
|
fn name_has_owner(conn: &Connection, name: &str) -> bool {
|
||||||
|
let proxy = conn.with_proxy("org.freedesktop.DBus", "/org/freedesktop/DBus", Duration::from_secs(2));
|
||||||
|
let result: Result<(bool,), _> = proxy.method_call("org.freedesktop.DBus", "NameHasOwner", (name.to_string(),));
|
||||||
|
result.map(|(b,)| b).unwrap_or(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a fresh handle, ensuring the cached one is still valid. If the backend owning the
|
||||||
|
/// address-book disappeared, the cache is cleared and we try to create a new handle.
|
||||||
|
fn obtain_handle() -> Option<std::sync::MutexGuard<'static, AddressBookHandle>> {
|
||||||
|
// Initialize cell if necessary.
|
||||||
|
let cell = ADDRESS_BOOK_HANDLE
|
||||||
.get_or_try_init(|| AddressBookHandle::new().map(Mutex::new))
|
.get_or_try_init(|| AddressBookHandle::new().map(Mutex::new))
|
||||||
.map_err(|e| {
|
.ok()?;
|
||||||
log::debug!(
|
|
||||||
"EDS resolver: failed to initialise address book handle: {}",
|
// Validate existing handle.
|
||||||
e
|
{
|
||||||
);
|
let mut guard = cell.lock().ok()?;
|
||||||
})
|
if !name_has_owner(&guard.connection, &guard.bus_name) {
|
||||||
.ok()
|
// Try to refresh the handle in-place.
|
||||||
|
match AddressBookHandle::new() {
|
||||||
|
Ok(new_h) => {
|
||||||
|
*guard = new_h;
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
log::debug!("EDS resolver: failed to refresh address book handle: {}", e);
|
||||||
|
// keep the stale handle but report failure
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Return guard after ensuring validity.
|
||||||
|
return Some(guard);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Helper that returns a blocking D-Bus session connection. Creating the
|
/// Helper that returns a blocking D-Bus session connection. Creating the
|
||||||
@@ -144,22 +167,35 @@ fn open_address_book(
|
|||||||
Ok((object_path, bus_name))
|
Ok((object_path, bus_name))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Ensure that the backend for the given address-book proxy is opened.
|
||||||
|
/// Evolution-Data-Server returns "Backend is not opened yet" until someone
|
||||||
|
/// calls the `Open` method once per process. We ignore any error here
|
||||||
|
/// because the backend might already be open.
|
||||||
|
fn ensure_address_book_open(proxy: &dbus::blocking::Proxy<&Connection>) {
|
||||||
|
let _: Result<(), _> = proxy.method_call(
|
||||||
|
"org.gnome.evolution.dataserver.AddressBook",
|
||||||
|
"Open",
|
||||||
|
(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
impl ContactResolverBackend for EDSContactResolverBackend {
|
impl ContactResolverBackend for EDSContactResolverBackend {
|
||||||
type ContactID = String;
|
type ContactID = String;
|
||||||
|
|
||||||
fn resolve_contact_id(&self, address: &str) -> Option<Self::ContactID> {
|
fn resolve_contact_id(&self, address: &str) -> Option<Self::ContactID> {
|
||||||
let handle_mutex = match get_address_book_handle() {
|
let handle = match obtain_handle() {
|
||||||
Some(h) => h,
|
Some(h) => h,
|
||||||
None => return None,
|
None => return None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let handle = handle_mutex.lock().unwrap();
|
|
||||||
let address_book_proxy = handle.connection.with_proxy(
|
let address_book_proxy = handle.connection.with_proxy(
|
||||||
&handle.bus_name,
|
&handle.bus_name,
|
||||||
&handle.object_path,
|
&handle.object_path,
|
||||||
Duration::from_secs(60),
|
Duration::from_secs(60),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
ensure_address_book_open(&address_book_proxy);
|
||||||
|
|
||||||
let filter = if address.contains('@') {
|
let filter = if address.contains('@') {
|
||||||
format!("(is \"email\" \"{}\")", address)
|
format!("(is \"email\" \"{}\")", address)
|
||||||
} else {
|
} else {
|
||||||
@@ -207,18 +243,19 @@ impl ContactResolverBackend for EDSContactResolverBackend {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_contact_display_name(&self, contact_id: &Self::ContactID) -> Option<String> {
|
fn get_contact_display_name(&self, contact_id: &Self::ContactID) -> Option<String> {
|
||||||
let handle_mutex = match get_address_book_handle() {
|
let handle = match obtain_handle() {
|
||||||
Some(h) => h,
|
Some(h) => h,
|
||||||
None => return None,
|
None => return None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let handle = handle_mutex.lock().unwrap();
|
|
||||||
let address_book_proxy = handle.connection.with_proxy(
|
let address_book_proxy = handle.connection.with_proxy(
|
||||||
&handle.bus_name,
|
&handle.bus_name,
|
||||||
&handle.object_path,
|
&handle.object_path,
|
||||||
Duration::from_secs(60),
|
Duration::from_secs(60),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
ensure_address_book_open(&address_book_proxy);
|
||||||
|
|
||||||
let vcard_result: Result<(String,), _> = address_book_proxy.method_call(
|
let vcard_result: Result<(String,), _> = address_book_proxy.method_call(
|
||||||
"org.gnome.evolution.dataserver.AddressBook",
|
"org.gnome.evolution.dataserver.AddressBook",
|
||||||
"GetContact",
|
"GetContact",
|
||||||
|
|||||||
Reference in New Issue
Block a user