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
use regex::Regex;
use reqwest::header::{HeaderMap, HeaderValue, AUTHORIZATION, CONTENT_TYPE};
use reqwest::StatusCode;
use serde::Serialize;
use std::error::Error;

mod constants;

#[derive(Serialize, Default)]
pub struct Submission {
    pub listen_type: ListenType,
    pub payload: Vec<Payload>,
}

#[derive(Serialize, PartialEq)]
pub enum ListenType {
    #[serde(rename(serialize = "single"))]
    Single,
    #[serde(rename(serialize = "playing_now"))]
    PlayingNow,
    #[serde(rename(serialize = "import"))]
    Import,
}

impl Default for ListenType {
    fn default() -> Self {
        ListenType::Single
    }
}

#[derive(Serialize, Default)]
pub struct Payload {
    pub listened_at: u64,
    pub track_metadata: TrackMetadata,
}

#[derive(Serialize, Default)]
pub struct TrackMetadata {
    pub artist_name: &'static str,
    pub track_name: &'static str,
    pub release_name: &'static str,
}

pub fn submit_import(user_uuid: &str, sub: Submission) -> Result<StatusCode, Box<dyn Error>> {
    if sub.listen_type == ListenType::Import {
        let mut headers = HeaderMap::new();
        let mut auth = String::from("Token ");
        auth.push_str(user_uuid);
        headers.insert(AUTHORIZATION, HeaderValue::from_str(auth.as_str()).unwrap());
        headers.insert(CONTENT_TYPE, HeaderValue::from_static("application/json"));
        let j = serde_json::to_string(&sub).unwrap();
        let res = reqwest::Client::new()
            .post((constants::API_ROOT_URL.to_string() + "/1/submit-listens").as_str())
            .headers(headers)
            .body(j)
            .send()
            .unwrap();
        return Ok(res.status());
    } else {
        return Err("error".into());
    }
}

pub fn submit_playing_now(user_uuid: &str, sub: Submission) -> Result<StatusCode, Box<dyn Error>> {
    if sub.listen_type == ListenType::PlayingNow && sub.payload.len() == 1 {
        let mut headers = HeaderMap::new();
        let mut auth = String::from("Token ");
        auth.push_str(user_uuid);
        headers.insert(AUTHORIZATION, HeaderValue::from_str(auth.as_str()).unwrap());
        headers.insert(CONTENT_TYPE, HeaderValue::from_static("application/json"));
        let j = serde_json::to_string(&sub).unwrap();
        let re = Regex::new(r#""listened_at":\d+,"#).unwrap();
        let result = re.replace_all(j.as_str(), "");
        let res = reqwest::Client::new()
            .post((constants::API_ROOT_URL.to_string() + "/1/submit-listens").as_str())
            .headers(headers)
            .body(format!("{}", result))
            .send()
            .unwrap();
        return Ok(res.status());
    } else {
        return Err("error".into());
    }
}

pub fn submit_single(user_uuid: &str, sub: Submission) -> Result<StatusCode, Box<dyn Error>> {
    if sub.listen_type == ListenType::Single
        && sub.payload.len() == 1
        && sub.payload.first().unwrap().listened_at != 0
    {
        let mut headers = HeaderMap::new();
        let mut auth = String::from("Token ");
        auth.push_str(user_uuid);
        headers.insert(AUTHORIZATION, HeaderValue::from_str(auth.as_str()).unwrap());
        headers.insert(CONTENT_TYPE, HeaderValue::from_static("application/json"));
        let j = serde_json::to_string(&sub).unwrap();
        let res = reqwest::Client::new()
            .post((constants::API_ROOT_URL.to_string() + "/1/submit-listens").as_str())
            .headers(headers)
            .body(j)
            .send()
            .unwrap();
        return Ok(res.status());
    } else {
        return Err("error".into());
    }
}

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {
        assert_eq!(2 + 2, 4);
    }
}