lastfm_edit/discovery/
album_tracks.rs1use super::common::filter_by_original_album_artist;
2use crate::{
3 AsyncDiscoveryIterator, AsyncPaginatedIterator, ExactScrobbleEdit, LastFmEditClientImpl,
4 Result, ScrobbleEdit,
5};
6use async_trait::async_trait;
7
8pub struct AlbumTracksDiscovery {
14 client: LastFmEditClientImpl,
15 edit: ScrobbleEdit,
16 album_name: String,
17 tracks_iterator: crate::AlbumTracksIterator,
18 current_track_results: Vec<ExactScrobbleEdit>,
19 current_track_index: usize,
20}
21
22impl AlbumTracksDiscovery {
23 pub fn new(client: LastFmEditClientImpl, edit: ScrobbleEdit, album_name: String) -> Self {
24 let tracks_iterator = crate::AlbumTracksIterator::new(
25 client.clone(),
26 album_name.clone(),
27 edit.artist_name_original.clone(),
28 );
29
30 Self {
31 client,
32 edit,
33 album_name,
34 tracks_iterator,
35 current_track_results: Vec::new(),
36 current_track_index: 0,
37 }
38 }
39}
40
41#[async_trait(?Send)]
42impl AsyncDiscoveryIterator<ExactScrobbleEdit> for AlbumTracksDiscovery {
43 async fn next(&mut self) -> Result<Option<ExactScrobbleEdit>> {
44 if self.current_track_index < self.current_track_results.len() {
46 let result = self.current_track_results[self.current_track_index].clone();
47 self.current_track_index += 1;
48 return Ok(Some(result));
49 }
50
51 while let Some(track) = self.tracks_iterator.next().await? {
53 let lookup_artist = if track.artist.is_empty() {
54 &self.edit.artist_name_original
55 } else {
56 &track.artist
57 };
58
59 log::debug!(
60 "Getting scrobble data for track '{}' from album '{}' by '{}'",
61 track.name,
62 self.album_name,
63 lookup_artist
64 );
65
66 match self
68 .client
69 .load_edit_form_values_internal(&track.name, lookup_artist)
70 .await
71 {
72 Ok(track_scrobbles) => {
73 let mut modified_edits = Vec::new();
75 for scrobble in track_scrobbles {
76 let mut modified_edit = scrobble.clone();
77 if let Some(new_track_name) = &self.edit.track_name {
78 modified_edit.track_name = new_track_name.clone();
79 }
80 if let Some(new_album_name) = &self.edit.album_name {
81 modified_edit.album_name = new_album_name.clone();
82 }
83 modified_edit.artist_name = self.edit.artist_name.clone();
84 if let Some(new_album_artist_name) = &self.edit.album_artist_name {
85 modified_edit.album_artist_name = new_album_artist_name.clone();
86 }
87 modified_edit.edit_all = self.edit.edit_all;
88 modified_edits.push(modified_edit);
89 }
90
91 let filtered_edits =
92 filter_by_original_album_artist(modified_edits, &self.edit);
93
94 if !filtered_edits.is_empty() {
95 self.current_track_results = filtered_edits;
97 self.current_track_index = 1; return Ok(Some(self.current_track_results[0].clone()));
99 }
100 }
101 Err(e) => {
102 log::debug!(
103 "Failed to get scrobble data for track '{}': {}",
104 track.name,
105 e
106 );
107 }
109 }
110 }
111
112 Ok(None)
114 }
115}