pub struct LastFmClient { /* private fields */ }Expand description
Main client for interacting with Last.fm’s web interface.
This client handles authentication, session management, and provides methods for browsing user libraries and editing scrobble data through web scraping.
§Examples
use lastfm_edit::{LastFmClient, Result};
#[tokio::main]
async fn main() -> Result<()> {
// Create client with any HTTP implementation
let http_client = http_client::native::NativeClient::new();
let mut client = LastFmClient::new(Box::new(http_client));
// Login to Last.fm
client.login("username", "password").await?;
// Check if authenticated
assert!(client.is_logged_in());
Ok(())
}Implementations§
Source§impl LastFmClient
impl LastFmClient
Sourcepub fn new(client: Box<dyn HttpClient>) -> Self
pub fn new(client: Box<dyn HttpClient>) -> Self
Create a new LastFmClient with the default Last.fm URL.
§Arguments
client- Any HTTP client implementation that implementsHttpClient
§Examples
use lastfm_edit::LastFmClient;
let http_client = http_client::native::NativeClient::new();
let client = LastFmClient::new(Box::new(http_client));Sourcepub fn with_base_url(client: Box<dyn HttpClient>, base_url: String) -> Self
pub fn with_base_url(client: Box<dyn HttpClient>, base_url: String) -> Self
Create a new LastFmClient with a custom base URL.
This is useful for testing or if Last.fm changes their domain.
§Arguments
client- Any HTTP client implementationbase_url- The base URL for Last.fm (e.g., “https://www.last.fm”)
Sourcepub fn with_rate_limit_patterns(
client: Box<dyn HttpClient>,
base_url: String,
rate_limit_patterns: Vec<String>,
) -> Self
pub fn with_rate_limit_patterns( client: Box<dyn HttpClient>, base_url: String, rate_limit_patterns: Vec<String>, ) -> Self
Create a new LastFmClient with custom rate limit detection patterns.
§Arguments
client- Any HTTP client implementationbase_url- The base URL for Last.fmrate_limit_patterns- Text patterns that indicate rate limiting in responses
Sourcepub async fn login(&mut self, username: &str, password: &str) -> Result<()>
pub async fn login(&mut self, username: &str, password: &str) -> Result<()>
Authenticate with Last.fm using username and password.
This method:
- Fetches the login page to extract CSRF tokens
- Submits the login form with credentials
- Validates the authentication by checking for session cookies
- Stores session data for subsequent requests
§Arguments
username- Last.fm username or emailpassword- Last.fm password
§Returns
Returns [Ok(())] on successful authentication, or LastFmError::Auth on failure.
§Examples
let mut client = LastFmClient::new(Box::new(http_client::native::NativeClient::new()));
client.login("username", "password").await?;
assert!(client.is_logged_in());Sourcepub fn username(&self) -> &str
pub fn username(&self) -> &str
Get the currently authenticated username.
Returns an empty string if not logged in.
Sourcepub fn is_logged_in(&self) -> bool
pub fn is_logged_in(&self) -> bool
Check if the client is currently authenticated.
Returns true if login was successful and session is active.
Sourcepub fn artist_tracks<'a>(&'a mut self, artist: &str) -> ArtistTracksIterator<'a>
pub fn artist_tracks<'a>(&'a mut self, artist: &str) -> ArtistTracksIterator<'a>
Create an iterator for browsing an artist’s tracks from the user’s library.
§Arguments
artist- The artist name to browse
§Returns
Returns an ArtistTracksIterator that implements AsyncPaginatedIterator.
§Examples
let mut client = LastFmClient::new(Box::new(http_client::native::NativeClient::new()));
// client.login(...).await?;
let mut tracks = client.artist_tracks("Radiohead");
while let Some(track) = tracks.next().await? {
println!("{} - {}", track.artist, track.name);
}Sourcepub fn artist_albums<'a>(&'a mut self, artist: &str) -> ArtistAlbumsIterator<'a>
pub fn artist_albums<'a>(&'a mut self, artist: &str) -> ArtistAlbumsIterator<'a>
Create an iterator for browsing an artist’s albums from the user’s library.
§Arguments
artist- The artist name to browse
§Returns
Returns an ArtistAlbumsIterator that implements AsyncPaginatedIterator.
Sourcepub fn recent_tracks<'a>(&'a mut self) -> RecentTracksIterator<'a>
pub fn recent_tracks<'a>(&'a mut self) -> RecentTracksIterator<'a>
Create an iterator for browsing the user’s recent tracks.
This provides access to the user’s recent listening history with timestamps, which is useful for finding tracks to edit.
§Returns
Returns a RecentTracksIterator that implements AsyncPaginatedIterator.
§Examples
let mut client = LastFmClient::new(Box::new(http_client::native::NativeClient::new()));
// client.login(...).await?;
let mut recent = client.recent_tracks();
while let Some(track) = recent.next().await? {
if let Some(timestamp) = track.timestamp {
println!("{} - {} (played at {})", track.artist, track.name, timestamp);
}
}Sourcepub async fn get_recent_scrobbles(&mut self, page: u32) -> Result<Vec<Track>>
pub async fn get_recent_scrobbles(&mut self, page: u32) -> Result<Vec<Track>>
Fetch recent scrobbles from the user’s listening history This gives us real scrobble data with timestamps for editing
Sourcepub async fn find_recent_scrobble_for_track(
&mut self,
track_name: &str,
artist_name: &str,
max_pages: u32,
) -> Result<Option<Track>>
pub async fn find_recent_scrobble_for_track( &mut self, track_name: &str, artist_name: &str, max_pages: u32, ) -> Result<Option<Track>>
Find the most recent scrobble for a specific track This searches through recent listening history to find real scrobble data
pub async fn edit_scrobble( &mut self, edit: &ScrobbleEdit, ) -> Result<EditResponse>
pub async fn edit_scrobble_with_retry( &mut self, edit: &ScrobbleEdit, max_retries: u32, ) -> Result<EditResponse>
Sourcepub async fn load_edit_form_values(
&mut self,
track_name: &str,
artist_name: &str,
) -> Result<ScrobbleEdit>
pub async fn load_edit_form_values( &mut self, track_name: &str, artist_name: &str, ) -> Result<ScrobbleEdit>
Load prepopulated form values for editing a specific track This extracts scrobble data directly from the track page forms
Sourcepub async fn get_album_tracks(
&mut self,
album_name: &str,
artist_name: &str,
) -> Result<Vec<Track>>
pub async fn get_album_tracks( &mut self, album_name: &str, artist_name: &str, ) -> Result<Vec<Track>>
Get tracks from a specific album page This makes a single request to the album page and extracts track data
Sourcepub async fn edit_album(
&mut self,
old_album_name: &str,
new_album_name: &str,
artist_name: &str,
) -> Result<EditResponse>
pub async fn edit_album( &mut self, old_album_name: &str, new_album_name: &str, artist_name: &str, ) -> Result<EditResponse>
Edit album metadata by updating scrobbles with new album name This edits ALL tracks from the album that are found in recent scrobbles
Sourcepub async fn edit_artist(
&mut self,
old_artist_name: &str,
new_artist_name: &str,
) -> Result<EditResponse>
pub async fn edit_artist( &mut self, old_artist_name: &str, new_artist_name: &str, ) -> Result<EditResponse>
Edit artist metadata by updating scrobbles with new artist name This edits ALL tracks from the artist that are found in recent scrobbles
Sourcepub async fn edit_artist_for_track(
&mut self,
track_name: &str,
old_artist_name: &str,
new_artist_name: &str,
) -> Result<EditResponse>
pub async fn edit_artist_for_track( &mut self, track_name: &str, old_artist_name: &str, new_artist_name: &str, ) -> Result<EditResponse>
Edit artist metadata for a specific track only This edits only the specified track if found in recent scrobbles
Sourcepub async fn edit_artist_for_album(
&mut self,
album_name: &str,
old_artist_name: &str,
new_artist_name: &str,
) -> Result<EditResponse>
pub async fn edit_artist_for_album( &mut self, album_name: &str, old_artist_name: &str, new_artist_name: &str, ) -> Result<EditResponse>
Edit artist metadata for all tracks in a specific album This edits ALL tracks from the specified album that are found in recent scrobbles
pub async fn get_artist_tracks_page( &mut self, artist: &str, page: u32, ) -> Result<TrackPage>
Sourcepub fn extract_tracks_from_document(
&self,
document: &Html,
artist: &str,
) -> Result<Vec<Track>>
pub fn extract_tracks_from_document( &self, document: &Html, artist: &str, ) -> Result<Vec<Track>>
Extract tracks from HTML document using multiple parsing strategies
pub fn parse_tracks_page( &self, document: &Html, page_number: u32, artist: &str, ) -> Result<TrackPage>
Sourcepub fn parse_recent_scrobbles(&self, document: &Html) -> Result<Vec<Track>>
pub fn parse_recent_scrobbles(&self, document: &Html) -> Result<Vec<Track>>
Parse recent scrobbles from the user’s library page This extracts real scrobble data with timestamps for editing
Sourcepub async fn get(&mut self, url: &str) -> Result<Response>
pub async fn get(&mut self, url: &str) -> Result<Response>
Make an HTTP GET request with authentication and retry logic