1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
use anyhow::Result;
use num_format::ToFormattedString;

use crate::app::Fetch;
use crate::config::Config;
use crate::models::saved_scrobbles::SavedScrobbles;
use crate::{files, lastfm, utils};

pub async fn fetch(f: Fetch, config: Config) -> Result<()> {
    let username = match f.username {
        Some(username) => username,
        None => config.default_username,
    };

    println!("Fetching user profile `{}`...", &username);
    let user = lastfm::profile::fetch_profile(&username, &config.api_key).await?;

    println!("Username: {}", user.name);
    println!("Number of scrobbles: {}", user.play_count_formatted());

    let file_format = match f.file_format {
        Some(format) => format,
        None => "json".to_string(),
    };

    let mut saved_tracks = if !f.new_file {
        match files::load_from_file(&user.name, &file_format) {
            Ok(saved_scrobbles) => saved_scrobbles,
            Err(_) => {
                println!(
                    "Existing file for `{}` not found. Creating new file...",
                    &user.name
                );
                SavedScrobbles::default()
            }
        }
    } else {
        println!("Creating new file...");
        SavedScrobbles::default()
    };

    let page = match f.page {
        Some(page) => {
            if page <= 0 {
                1
            } else {
                page
            }
        }
        None => 1,
    };

    let limit = match f.limit {
        Some(limit) => {
            if limit <= 0 {
                50
            } else if limit > 200 {
                200
            } else {
                limit
            }
        }
        None => 200,
    };

    let from = match f.from {
        Some(from) => from,
        None => 0,
    };

    let to = match f.to {
        Some(to) => to,
        None => utils::get_current_unix_timestamp(),
    };

    let min_timestamp = if f.current_day {
        use chrono::prelude::*;

        Utc::now().date().and_hms(0, 0, 0).timestamp()
    } else if !saved_tracks.is_empty() {
        match saved_tracks.most_recent_scrobble() {
            Some(track) => track.timestamp_utc + 10,
            None => 0,
        }
    } else {
        from
    };

    let new_tracks = lastfm::recently_played::fetch_tracks(
        &user,
        &config.api_key,
        page,
        limit,
        min_timestamp,
        to,
    )
    .await?;

    if new_tracks.is_empty() {
        println!("No new tracks were retrieved from Last.fm");
        return Ok(());
    }

    let new_tracks_len = &new_tracks.len();
    let new_total = if !saved_tracks.is_empty() {
        match new_tracks_len {
            1 => println!("Saving one new track to existing file..."),
            _ => println!(
                "Saving {} new tracks to existing file...",
                new_tracks_len.to_formatted_string(&utils::get_locale())
            ),
        }
        files::append_to_file(&new_tracks, &mut saved_tracks, &user.name, &file_format)?
    } else {
        println!(
            "Saving {} tracks to file...",
            &new_tracks.len().to_formatted_string(&utils::get_locale())
        );
        files::save_to_file(&new_tracks, &user.name, &file_format)?
    };

    if new_total != user.play_count() && !f.current_day {
        println!(
            "{} scrobbles were saved to the file, when {} scrobbles were expected.",
            new_total.to_formatted_string(&utils::get_locale()),
            user.play_count().to_formatted_string(&utils::get_locale())
        );
        println!("Please consider creating a new file with the new file flag. `-n`");
    } else {
        match new_total {
            1 => println!("One scrobble saved"),
            _ => println!(
                "{} scrobbles saved.",
                new_total.to_formatted_string(&utils::get_locale())
            ),
        }
    }

    Ok(())
}