news: headlines about the artists you follow, anchored to the artist
No per-artist music news API exists — every product that does this aggregates and filters, so this does too. Google News RSS is the source: free, keyless, no pagination, and no contract at all, which is why it gets the most conservative pacer in the file (4 requests per 10 seconds) and a 6-hour cache on disk as well as in memory. Nothing user-facing waits on it; the home page asks after it is already drawn. The query is the QUOTED artist name plus the word "music", and the quoting is the whole design. Measured 2026-08-04 against the real feed: a bare ambiguous name returned 0 of 10 relevant items — searching "Girls" gives Indigo Girls, The Deli Girls and a school production of Mean Girls — while the same name with a corroborating token returned 8 of 8, and an unambiguous one 10 of 10. That is the identity-anchor rule the rest of the app already lives by, applied to a provider that only speaks in names: never trust the name alone. The parser is deliberately not an XML library. One provider, four flat tags inside <item> blocks, exactly the judgment the Bing scrape made. What it does handle is what Google actually emits: entity-encoded titles including numeric forms, a " - Publication" suffix on every headline (stripped when the tail matches the <source> tag, so the title reads as a headline rather than a citation), and RFC 2822 pubDates converted to unix seconds by a hand-rolled civil-date conversion — nothing else in the workspace needs a date crate for one field. Freshness and relevance stay OUT of here. The 45-day window and the review filter are display policy and belong to the surface that shows them; this returns what the feed said, newest first, capped at a dozen.
This commit is contained in:
1 parent
50afa6a6a9
commit
8ef730848a
3 files changed
+245
No files matched your search
@@ -4204,6 +4204,25 @@ pub async fn unfollow_artist(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// ---- home ----
|
||||
|
||||
/// Headlines for the home page's news panel, one paced Google News query per
|
||||
/// followed artist. Serial on purpose: the pacer inside `artist_news` is the
|
||||
/// budget, and nothing user-blocking waits on this call — the frontend
|
||||
/// requests it after the page is already up.
|
||||
#[tauri::command]
|
||||
pub async fn home_artist_news(
|
||||
state: State<'_, LibraryState>,
|
||||
artists: Vec<String>,
|
||||
) -> Result<std::collections::HashMap<String, Vec<metadata::ArtistNewsItem>>, String> {
|
||||
let mut out = std::collections::HashMap::new();
|
||||
for name in artists {
|
||||
let items = state.metadata.artist_news(&name).await;
|
||||
out.insert(name, items);
|
||||
}
|
||||
Ok(out)
|
||||
}
|
||||
|
||||
// ---- playlists ----
|
||||
|
||||
fn now_secs() -> i64 {
|
||||
|
||||
@@ -89,6 +89,7 @@ pub fn run() {
|
||||
commands::followed_artists,
|
||||
commands::follow_artist,
|
||||
commands::unfollow_artist,
|
||||
commands::home_artist_news,
|
||||
commands::list_playlists,
|
||||
commands::create_playlist,
|
||||
commands::delete_playlist,
|
||||
|
||||
Reference in new issue
Block a user