rustfm_scraper/app/
fetch.rs1use anyhow::Result;
2use num_format::ToFormattedString;
3
4use crate::app::Fetch;
5use crate::config::Config;
6use crate::models::saved_scrobbles::SavedScrobbles;
7use crate::{files, lastfm, utils};
8
9pub async fn fetch(f: Fetch, config: Config) -> Result<()> {
10 let username = match f.username {
11 Some(username) => username,
12 None => config.default_username,
13 };
14
15 println!("Fetching user profile `{}`...", &username);
16 let user = lastfm::profile::fetch_profile(&username, &config.api_key).await?;
17
18 println!("Username: {}", user.name);
19 println!("Number of scrobbles: {}", user.play_count_formatted());
20
21 let file_format = match f.file_format {
22 Some(format) => format,
23 None => "json".to_string(),
24 };
25
26 let mut saved_tracks = if !f.new_file {
27 match files::load_from_file(&user.name, &file_format) {
28 Ok(saved_scrobbles) => saved_scrobbles,
29 Err(_) => {
30 println!(
31 "Existing file for `{}` not found. Creating new file...",
32 &user.name
33 );
34 SavedScrobbles::default()
35 }
36 }
37 } else {
38 println!("Creating new file...");
39 SavedScrobbles::default()
40 };
41
42 let page = match f.page {
43 Some(page) => {
44 if page <= 0 {
45 1
46 } else {
47 page
48 }
49 }
50 None => 1,
51 };
52
53 let limit = match f.limit {
54 Some(limit) => {
55 if limit <= 0 {
56 50
57 } else if limit > 1000 {
58 1000
59 } else {
60 limit
61 }
62 }
63 None => 1000,
64 };
65
66 let from = match f.from {
67 Some(from) => from,
68 None => 0,
69 };
70
71 let to = match f.to {
72 Some(to) => to,
73 None => utils::get_current_unix_timestamp(),
74 };
75
76 let min_timestamp = if f.current_day {
77 use chrono::prelude::*;
78
79 Utc::now().date().and_hms(0, 0, 0).timestamp()
80 } else if !saved_tracks.is_empty() {
81 match saved_tracks.most_recent_scrobble() {
82 Some(track) => track.timestamp_utc + 10,
83 None => 0,
84 }
85 } else {
86 from
87 };
88
89 let new_tracks = lastfm::recently_played::fetch_tracks(
90 &user,
91 &config.api_key,
92 page,
93 limit,
94 min_timestamp,
95 to,
96 )
97 .await?;
98
99 if new_tracks.is_empty() {
100 println!("No new tracks were retrieved from Last.fm");
101 return Ok(());
102 }
103
104 let new_tracks_len = &new_tracks.len();
105 let new_total = if !saved_tracks.is_empty() {
106 match new_tracks_len {
107 1 => println!("Saving one new track to existing file..."),
108 _ => println!(
109 "Saving {} new tracks to existing file...",
110 new_tracks_len.to_formatted_string(&utils::get_locale())
111 ),
112 }
113 files::append_to_file(&new_tracks, &mut saved_tracks, &user.name, &file_format)?
114 } else {
115 println!(
116 "Saving {} tracks to file...",
117 &new_tracks.len().to_formatted_string(&utils::get_locale())
118 );
119 files::save_to_file(&new_tracks, &user.name, &file_format)?
120 };
121
122 if new_total != user.play_count() && !f.current_day {
123 println!(
124 "{} scrobbles were saved to the file, when {} scrobbles were expected.",
125 new_total.to_formatted_string(&utils::get_locale()),
126 user.play_count().to_formatted_string(&utils::get_locale())
127 );
128 println!("Please consider creating a new file with the new file flag. `-n`");
129 } else {
130 match new_total {
131 1 => println!("One scrobble saved"),
132 _ => println!(
133 "{} scrobbles saved.",
134 new_total.to_formatted_string(&utils::get_locale())
135 ),
136 }
137 }
138
139 Ok(())
140}