From b7038ffa9e8fa84ef993bf406fdb82c48cb8a760 Mon Sep 17 00:00:00 2001 From: Jesse Luehrs Date: Wed, 7 Nov 2018 01:08:42 -0500 Subject: process tracks chronologically this way, if we get interrupted partway through, continuing will do the right thing --- src/lastfm/api_types.rs | 2 ++ src/lastfm/mod.rs | 39 ++++++++++++++++++++++++++++++--------- 2 files changed, 32 insertions(+), 9 deletions(-) diff --git a/src/lastfm/api_types.rs b/src/lastfm/api_types.rs index 28b593a..30d7114 100644 --- a/src/lastfm/api_types.rs +++ b/src/lastfm/api_types.rs @@ -1,4 +1,5 @@ #![allow(non_camel_case_types)] +#![allow(non_snake_case)] #[derive(Deserialize)] pub struct track_artist { @@ -28,6 +29,7 @@ pub struct track { #[derive(Deserialize)] pub struct recent_tracks_recenttracks_attr { pub total: String, // no idea why this is a string + pub totalPages: String, } #[derive(Deserialize)] diff --git a/src/lastfm/mod.rs b/src/lastfm/mod.rs index a4ec8eb..cb0afaf 100644 --- a/src/lastfm/mod.rs +++ b/src/lastfm/mod.rs @@ -22,7 +22,7 @@ pub struct Track { pub struct Tracks<'a> { client: &'a LastFMClient, - page: u64, + page: Option, buf: Vec, from: Option, } @@ -31,14 +31,20 @@ impl<'a> Tracks<'a> { fn new(client: &LastFMClient, from: Option) -> Tracks { Tracks { client, - page: 0, + page: None, buf: vec![], from, } } fn get_next_page(&mut self) -> Result<()> { - self.page += 1; + if !self.page.is_some() { + self.page = Some(self.client.get_total_pages(self.from)?); + } + let page = self.page.unwrap(); + if page < 1 { + return Ok(()) + } let req = self.client.client .get(API_ROOT) @@ -47,7 +53,7 @@ impl<'a> Tracks<'a> { ("api_key", &self.client.api_key), ("user", &self.client.user), ("format", "json"), - ("page", &format!("{}", self.page)), + ("page", &format!("{}", page)), ("limit", "200"), ]); let req = if let Some(from) = self.from { @@ -72,6 +78,7 @@ impl<'a> Tracks<'a> { }) }) .collect::>>()?; + self.page = Some(page - 1); Ok(()) } else { @@ -104,6 +111,23 @@ impl LastFMClient { } pub fn track_count(&self, from: Option) -> Result { + let data = self.recent_tracks(from)?; + Ok(data.recenttracks.attr.total.parse()?) + } + + pub fn tracks(&self, from: Option) -> Tracks { + Tracks::new(&self, from) + } + + fn get_total_pages(&self, from: Option) -> Result { + let data = self.recent_tracks(from)?; + Ok(data.recenttracks.attr.totalPages.parse()?) + } + + fn recent_tracks( + &self, + from: Option, + ) -> Result { let req = self.client .get(API_ROOT) .query(&[ @@ -111,6 +135,7 @@ impl LastFMClient { ("api_key", &self.api_key), ("user", &self.user), ("format", "json"), + ("limit", "200"), ]); let req = if let Some(from) = from { req.query(&[("from", &format!("{}", from))]) @@ -123,14 +148,10 @@ impl LastFMClient { if res.status().is_success() { let data: api_types::recent_tracks = res.json()?; - Ok(data.recenttracks.attr.total.parse()?) + Ok(data) } else { Err(failure::err_msg(res.status().as_str().to_string())) } } - - pub fn tracks(&self, from: Option) -> Tracks { - Tracks::new(&self, from) - } } -- cgit v1.2.3