this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 325 lines 12 kB view raw
1use chrono::{DateTime, FixedOffset}; 2use jacquard::{CowStr, smol_str::ToSmolStr, types::string::Datetime}; 3 4#[derive(Debug, Default)] 5pub struct Artist { 6 pub artist_name: String, 7 pub artist_mb_id: Option<String>, 8} 9 10#[derive(Debug, Default)] 11pub struct Play { 12 pub track_name: String, 13 pub track_mb_id: Option<String>, 14 pub recording_mb_id: Option<String>, 15 pub duration: Option<i64>, 16 pub artist_names: Option<Vec<String>>, 17 pub artist_mb_ids: Option<Vec<String>>, 18 pub artists: Option<Vec<Artist>>, 19 pub release_name: Option<String>, 20 pub release_mb_id: Option<String>, 21 pub isrc: Option<String>, 22 pub origin_url: Option<String>, 23 pub music_service_base_domain: Option<String>, 24 pub submission_client_agent: Option<String>, 25 pub played_time: Option<DateTime<FixedOffset>>, 26 pub track_discriminant: Option<String>, 27 pub release_discriminant: Option<String>, 28} 29 30#[derive(Debug, Default)] 31pub struct PlayView { 32 pub track_name: String, 33 pub track_mb_id: Option<String>, 34 pub recording_mb_id: Option<String>, 35 pub duration: Option<i64>, 36 pub artists: Vec<Artist>, 37 pub release_name: Option<String>, 38 pub release_mb_id: Option<String>, 39 pub isrc: Option<String>, 40 pub origin_url: Option<String>, 41 pub music_service_base_domain: Option<String>, 42 pub submission_client_agent: Option<String>, 43 pub played_time: Option<DateTime<FixedOffset>>, 44} 45 46#[derive(Debug, Default)] 47pub struct Status { 48 pub time: DateTime<FixedOffset>, 49 pub expiry: Option<DateTime<FixedOffset>>, 50 pub item: PlayView, 51} 52 53impl From<jacquard_api::fm_teal::alpha::feed::Artist<'_>> for Artist { 54 fn from(value: jacquard_api::fm_teal::alpha::feed::Artist) -> Self { 55 Self { 56 artist_name: value.artist_name.to_string(), 57 artist_mb_id: value.artist_mb_id.map(|s| s.to_string()), 58 } 59 } 60} 61 62impl From<Artist> for jacquard_api::fm_teal::alpha::feed::Artist<'static> { 63 fn from(value: Artist) -> Self { 64 Self { 65 artist_name: CowStr::Owned(value.artist_name.to_smolstr()), 66 artist_mb_id: value.artist_mb_id.map(|s| CowStr::Owned(s.to_smolstr())), 67 extra_data: None, 68 } 69 } 70} 71 72impl From<jacquard_api::fm_teal::alpha::feed::play::Play<'_>> for Play { 73 fn from(value: jacquard_api::fm_teal::alpha::feed::play::Play<'_>) -> Self { 74 Self { 75 track_name: value.track_name.to_string(), 76 track_mb_id: value.track_mb_id.map(|s| s.to_string()), 77 recording_mb_id: value.recording_mb_id.map(|s| s.to_string()), 78 duration: value.duration, 79 artist_names: value 80 .artist_names 81 .map(|v| v.iter().map(|a| a.to_string()).collect()), 82 artist_mb_ids: value 83 .artist_mb_ids 84 .map(|v| v.iter().map(|a| a.to_string()).collect()), 85 artists: value 86 .artists 87 .map(|v| v.iter().map(|a| a.clone().into()).collect()), 88 release_name: value.release_name.map(|s| s.to_string()), 89 release_mb_id: value.release_mb_id.map(|s| s.to_string()), 90 isrc: value.isrc.map(|s| s.to_string()), 91 origin_url: value.origin_url.map(|s| s.to_string()), 92 music_service_base_domain: value.music_service_base_domain.map(|s| s.to_string()), 93 submission_client_agent: value.submission_client_agent.map(|s| s.to_string()), 94 played_time: value.played_time.map(|dt| *dt.as_ref()), 95 track_discriminant: value.track_discriminant.map(|s| s.to_string()), 96 release_discriminant: value.release_discriminant.map(|s| s.to_string()), 97 } 98 } 99} 100 101impl From<Play> for jacquard_api::fm_teal::alpha::feed::play::Play<'static> { 102 fn from(val: Play) -> Self { 103 jacquard_api::fm_teal::alpha::feed::play::Play { 104 track_name: CowStr::Owned(val.track_name.to_smolstr()), 105 track_mb_id: val.track_mb_id.map(|s| CowStr::Owned(s.to_smolstr())), 106 recording_mb_id: val.recording_mb_id.map(|s| CowStr::Owned(s.to_smolstr())), 107 duration: val.duration, 108 artist_names: val 109 .artist_names 110 .map(|v| v.iter().map(|s| CowStr::Owned(s.to_smolstr())).collect()), 111 artist_mb_ids: val 112 .artist_mb_ids 113 .map(|v| v.iter().map(|s| CowStr::Owned(s.to_smolstr())).collect()), 114 artists: val 115 .artists 116 .map(|v| v.into_iter().map(|a| a.into()).collect()), 117 release_name: val.release_name.map(|s| CowStr::Owned(s.to_smolstr())), 118 release_mb_id: val.release_mb_id.map(|s| CowStr::Owned(s.to_smolstr())), 119 isrc: val.isrc.map(|s| CowStr::Owned(s.to_smolstr())), 120 origin_url: val.origin_url.map(|s| CowStr::Owned(s.to_smolstr())), 121 music_service_base_domain: val 122 .music_service_base_domain 123 .map(|s| CowStr::Owned(s.to_smolstr())), 124 submission_client_agent: val 125 .submission_client_agent 126 .map(|s| CowStr::Owned(s.to_smolstr())), 127 played_time: val.played_time.map(Datetime::new), 128 track_discriminant: val 129 .track_discriminant 130 .map(|s| CowStr::Owned(s.to_smolstr())), 131 release_discriminant: val 132 .release_discriminant 133 .map(|s| CowStr::Owned(s.to_smolstr())), 134 extra_data: None, 135 } 136 } 137} 138 139impl From<jacquard_api::fm_teal::alpha::feed::PlayView<'_>> for PlayView { 140 fn from(value: jacquard_api::fm_teal::alpha::feed::PlayView<'_>) -> Self { 141 Self { 142 track_name: value.track_name.to_string(), 143 track_mb_id: value.track_mb_id.map(|s| s.to_string()), 144 recording_mb_id: value.recording_mb_id.map(|s| s.to_string()), 145 duration: value.duration, 146 artists: value.artists.iter().map(|a| a.clone().into()).collect(), 147 release_name: value.release_name.map(|s| s.to_string()), 148 release_mb_id: value.release_mb_id.map(|s| s.to_string()), 149 isrc: value.isrc.map(|s| s.to_string()), 150 origin_url: value.origin_url.map(|s| s.to_string()), 151 music_service_base_domain: value.music_service_base_domain.map(|s| s.to_string()), 152 submission_client_agent: value.submission_client_agent.map(|s| s.to_string()), 153 played_time: value.played_time.map(|dt| *dt.as_ref()), 154 } 155 } 156} 157 158impl From<PlayView> for jacquard_api::fm_teal::alpha::feed::PlayView<'static> { 159 fn from(val: PlayView) -> Self { 160 jacquard_api::fm_teal::alpha::feed::PlayView { 161 track_name: CowStr::Owned(val.track_name.to_smolstr()), 162 track_mb_id: val.track_mb_id.map(|s| CowStr::Owned(s.to_smolstr())), 163 recording_mb_id: val.recording_mb_id.map(|s| CowStr::Owned(s.to_smolstr())), 164 duration: val.duration, 165 artists: val.artists.into_iter().map(|a| a.into()).collect(), 166 release_name: val.release_name.map(|s| CowStr::Owned(s.to_smolstr())), 167 release_mb_id: val.release_mb_id.map(|s| CowStr::Owned(s.to_smolstr())), 168 isrc: val.isrc.map(|s| CowStr::Owned(s.to_smolstr())), 169 origin_url: val.origin_url.map(|s| CowStr::Owned(s.to_smolstr())), 170 music_service_base_domain: val 171 .music_service_base_domain 172 .map(|s| CowStr::Owned(s.to_smolstr())), 173 submission_client_agent: val 174 .submission_client_agent 175 .map(|s| CowStr::Owned(s.to_smolstr())), 176 played_time: val.played_time.map(Datetime::new), 177 extra_data: None, 178 } 179 } 180} 181 182impl From<jacquard_api::fm_teal::alpha::actor::status::Status<'_>> for Status { 183 fn from(value: jacquard_api::fm_teal::alpha::actor::status::Status<'_>) -> Self { 184 Self { 185 time: *value.time.as_ref(), 186 expiry: value.expiry.map(|dt| *dt.as_ref()), 187 item: value.item.into(), 188 } 189 } 190} 191 192impl From<Status> for jacquard_api::fm_teal::alpha::actor::status::Status<'static> { 193 fn from(val: Status) -> Self { 194 jacquard_api::fm_teal::alpha::actor::status::Status { 195 time: Datetime::new(val.time), 196 expiry: val.expiry.map(Datetime::new), 197 item: val.item.into(), 198 extra_data: None, 199 } 200 } 201} 202 203impl Status { 204 pub fn display(&self, raw: bool, full: bool) { 205 // if both track name and artists are blank, probably nothing's playing 206 if self.item.track_name.is_empty() && self.item.artists.is_empty() && !raw { 207 println!("nothing playing right now"); 208 return; 209 } 210 211 println!("track: {}", self.item.track_name); 212 213 if let Some(track_id) = &self.item.track_mb_id 214 && full 215 { 216 println!("track id: {}", track_id); 217 } 218 219 if let Some(recording_id) = &self.item.recording_mb_id 220 && full 221 { 222 println!("recording id: {}", recording_id); 223 } 224 225 if !self.item.artists.is_empty() || raw { 226 print!("artists: "); 227 228 for i in 0..self.item.artists.len() { 229 print!("{}", self.item.artists[i].artist_name); 230 231 if let Some(artist_id) = &self.item.artists[i].artist_mb_id 232 && full 233 { 234 print!(" [{}]", artist_id); 235 } 236 237 if i != self.item.artists.len() - 1 { 238 print!(", "); 239 } 240 } 241 242 println!(); 243 } 244 245 if let Some(release) = &self.item.release_name { 246 println!("release: {}", release); 247 } 248 249 if let Some(release_id) = &self.item.release_mb_id 250 && full 251 { 252 println!("release id: {}", release_id); 253 } 254 255 if let Some(isrc) = &self.item.isrc 256 && full 257 { 258 println!("isrc: {}", isrc); 259 } 260 261 if let Some(played_time) = &self.item.played_time { 262 if raw { 263 println!("played: {}", played_time.format("%Y-%m-%d %H:%M:%S %:z")); 264 } else { 265 let local_dt = played_time.with_timezone(&chrono::Local); 266 println!("played: {}", local_dt.format("%Y-%m-%d %H:%M:%S")); 267 } 268 } 269 270 if let Some(duration) = self.item.duration { 271 if raw { 272 println!("duration: {}", duration); 273 } else { 274 let hours = duration / 3600; 275 let minutes = (duration - (hours * 3600)) / 60; 276 let seconds = duration - (minutes * 60); 277 278 let mut duration_str = "".to_string(); 279 if hours > 0 { 280 duration_str = format!("{:02}:", hours); 281 } 282 if minutes > 0 || hours > 0 { 283 duration_str = format!("{}{:02}:", duration_str, minutes); 284 } 285 if seconds > 0 || minutes > 0 || hours > 0 { 286 duration_str = format!("{}{:02}", duration_str, seconds); 287 } 288 289 println!("duration: {}", duration_str); 290 } 291 } 292 293 if let Some(service) = &self.item.music_service_base_domain 294 && full 295 { 296 println!("service: {}", service); 297 } 298 299 if let Some(client) = &self.item.submission_client_agent 300 && full 301 { 302 println!("client: {}", client); 303 } 304 305 if full { 306 if raw { 307 println!("time: {}", self.time.format("%Y-%m-%d %H:%M:%S %:z")); 308 } else { 309 let local_dt = self.time.with_timezone(&chrono::Local); 310 println!("time: {}", local_dt.format("%Y-%m-%d %H:%M:%S")); 311 } 312 } 313 314 if let Some(expiry) = &self.expiry 315 && full 316 { 317 if raw { 318 println!("expiry: {}", expiry.format("%Y-%m-%d %H:%M:%S %:z")); 319 } else { 320 let local_dt = expiry.with_timezone(&chrono::Local); 321 println!("expiry: {}", local_dt.format("%Y-%m-%d %H:%M:%S")); 322 } 323 } 324 } 325}