fix: use file storage as primary for credentials (more reliable in dev)

This commit is contained in:
vicrodh committed 2026-01-09 19:53:02 -06:00
1 parent 087fbbd567
commit 97951b2189
2 files changed
+34 -83

No files matched your search

+23 -52
View File
@@ -32,6 +32,10 @@ pub async fn share_track_songlink(
let isrc = isrc.unwrap_or_default().trim().to_string();
let url = url.unwrap_or_default().trim().to_string();
if let Some(songlink) = resolve_songlink_from_itunes(&isrc, track_id, &state).await {
return Ok(songlink);
}
if !isrc.is_empty() {
log::info!("Command: share_track_songlink ISRC={}", isrc);
match state.songlink.get_by_isrc(&isrc).await {
@@ -46,46 +50,30 @@ pub async fn share_track_songlink(
}
if url.is_empty() {
if let Some(track_id) = track_id {
if let Some(itunes_url) = resolve_itunes_url(track_id, &isrc, &state).await {
return match state.songlink.get_by_url(&itunes_url, ContentType::Track).await {
Ok(result) => Ok(result),
Err(err) => {
log::warn!("iTunes URL lookup failed: {}", err);
if let Some(fallback) = songlink_from_itunes_url(&itunes_url) {
return Ok(fallback);
}
Err(err.to_string())
}
};
}
}
return Err(ShareError::MissingIdentifier.to_string());
}
log::info!("Command: share_track_songlink URL={}", url);
match state.songlink.get_by_url(&url, ContentType::Track).await {
Ok(result) => Ok(result),
Err(err) => {
log::warn!("URL lookup failed: {}", err);
if let Some(track_id) = track_id {
if let Some(itunes_url) = resolve_itunes_url(track_id, &isrc, &state).await {
return match state.songlink.get_by_url(&itunes_url, ContentType::Track).await {
Ok(result) => Ok(result),
Err(itunes_err) => {
log::warn!("iTunes URL lookup failed: {}", itunes_err);
if let Some(fallback) = songlink_from_itunes_url(&itunes_url) {
return Ok(fallback);
}
Err(itunes_err.to_string())
}
};
}
}
Err(err.to_string())
}
state
.songlink
.get_by_url(&url, ContentType::Track)
.await
.map_err(|e| e.to_string())
}
async fn resolve_songlink_from_itunes(
isrc: &str,
track_id: Option<u64>,
state: &State<'_, AppState>,
) -> Option<SongLinkResponse> {
if let Some(url) = lookup_itunes_by_isrc(isrc).await {
return songlink_from_itunes_url(&url);
}
let track_id = track_id?;
let (title, artist) = fetch_track_metadata(track_id, state).await?;
let url = search_itunes_by_term(&title, &artist).await?;
songlink_from_itunes_url(&url)
}
fn songlink_from_itunes_url(itunes_url: &str) -> Option<SongLinkResponse> {
@@ -115,23 +103,6 @@ fn extract_itunes_track_id(itunes_url: &str) -> Option<String> {
None
}
async fn resolve_itunes_url(
track_id: u64,
isrc: &str,
state: &State<'_, AppState>,
) -> Option<String> {
if let Some(url) = lookup_itunes_by_isrc(isrc).await {
return Some(url);
}
let (title, artist) = match fetch_track_metadata(track_id, state).await {
Some(meta) => meta,
None => return None,
};
search_itunes_by_term(&title, &artist).await
}
async fn fetch_track_metadata(
track_id: u64,
state: &State<'_, AppState>,
+11 -31
View File
@@ -106,7 +106,7 @@ fn has_fallback_credentials() -> bool {
get_fallback_path().map(|p| p.exists()).unwrap_or(false)
}
/// Save Qobuz credentials - tries keyring first, then fallback
/// Save Qobuz credentials - saves to both file (primary) and keyring (secondary)
pub fn save_qobuz_credentials(email: &str, password: &str) -> Result<(), String> {
log::info!("Attempting to save credentials for: {}", email);
@@ -115,40 +115,20 @@ pub fn save_qobuz_credentials(email: &str, password: &str) -> Result<(), String>
password: password.to_string(),
};
// Try keyring first
match Entry::new(SERVICE_NAME, QOBUZ_CREDENTIALS_KEY) {
Ok(entry) => {
let json = serde_json::to_string(&credentials)
.map_err(|e| format!("Failed to serialize credentials: {}", e))?;
// Always save to file first (more reliable, especially in dev)
save_to_fallback(&credentials)?;
match entry.set_password(&json) {
Ok(()) => {
log::info!("Qobuz credentials saved to system keyring");
// Verify the save worked by reading it back
match entry.get_password() {
Ok(_) => {
log::info!("Verified: credentials readable from keyring");
return Ok(());
}
Err(e) => {
log::error!("Keyring save appeared to succeed but verification failed: {}", e);
log::warn!("Falling back to file storage...");
}
}
}
Err(e) => {
log::warn!("Keyring save failed ({}), trying fallback...", e);
}
}
}
Err(e) => {
log::warn!("Keyring not available ({}), using fallback...", e);
// Also try keyring as secondary (nice to have for desktop integration)
if let Ok(entry) = Entry::new(SERVICE_NAME, QOBUZ_CREDENTIALS_KEY) {
let json = serde_json::to_string(&credentials).unwrap_or_default();
if let Err(e) = entry.set_password(&json) {
log::debug!("Keyring save failed (not critical): {}", e);
} else {
log::debug!("Also saved to keyring");
}
}
// Fallback to file
save_to_fallback(&credentials)
Ok(())
}
/// Load Qobuz credentials - tries keyring first, then fallback