Add commas

This commit is contained in:
Joey Hines 2026-04-02 21:20:31 -06:00
parent 628b68316a
commit dc4389de4c
Signed by: joeyahines
GPG Key ID: E99D8FB14855100E

240
src/discord/space.rs Normal file
View File

@ -0,0 +1,240 @@
use crate::discord::Context;
use crate::error::Error;
use poise::serenity_prelude::MessageBuilder;
use rust_dsn_parser::prelude::*;
use std::collections::HashMap;
use std::time::{SystemTime, UNIX_EPOCH};
use structopt::lazy_static::lazy_static;
use thousands::Separable;
lazy_static! {
static ref NAME_MAP: HashMap<String, &'static str> = vec![
("ace", "Advanced Composition Explorer"),
("apm1", "Astrobotic Peregrine 1 Mission"),
("agm1", "Astrobotic Griffin Lander"),
("argo", "ArgoMoon"),
("atot", "Advanced Tracking and Observational Techniques"),
("bepi", "BepiColombo"),
("bios", "BioSentinel"),
("caps", "CAPSTONE"),
("cas", "Cassini"),
("cass", "Testing"),
("ch1", "Chandrayaan"),
("ch2", "Chandrayaan-2"),
("ch2l", "Chandrayaan-2 Lander"),
("ch2o", "Chandrayaan-2 Orbiter"),
("ch3", "Chandrayaan-3"),
("cgo", "Carruthers Geocorona Observatory"),
("chdr", "Chandra"),
("clu1", "Cluster 1"),
("clu2", "Cluster 2"),
("clu3", "Cluster 3"),
("clu4", "Cluster 4"),
("cue3", "CU Earth Escape Explorer"),
("cusp", "CubeSat for Solar Particles"),
("dart", "Double Asteroid Redirection Test"),
("dawn", "Dawn"),
("dif", "Deep Impact"),
("dsco", "Deep Space Climate Observatory (DSCOVR)"),
("dsn", "Testing"),
("egs", "EVN and Global Services"),
("em1", "Human Space Flight: Artemis I"),
("em2", "Human Space Flight: Artemis II"),
("em3", "Human Space Flight: Artemis III"),
("emm", "Emirates Mars Mission (Hope)"),
("em-1", "Exploration Mission-1"),
("em-2", "Exploration Mission-2"),
("em-3", "Exploration Mission-3"),
("em-4", "Exploration Mission-4"),
("em-5", "Exploration Mission-5"),
("em-6", "Exploration Mission-6"),
("em-7", "Exploration Mission-7"),
("em-8", "Exploration Mission-8"),
("em-9", "Exploration Mission-9"),
("em-10", "Exploration Mission-10"),
("equl", "EQUULEUS"),
("escb", "ESCAPADE Blue"),
("escg", "ESCAPADE Gold"),
("eurc", "Europa Clipper"),
("eus", "Exploration Upper Stage"),
("gaia", "Gaia"),
("gbra", "Ground Based Radio Astronomy"),
("go10", "GOES 10"),
("go11", "GOES 11"),
("go12", "GOES 12"),
("go13", "GOES 13"),
("go14", "GOES 14"),
("go15", "GOES 15"),
("go16", "GOES 16"),
("go17", "GOES 17"),
("grla", "GRAIL A"),
("grlb", "GRAIL B"),
("gssr", "Goldstone Solar System Radar"),
("gtl", "Geotail"),
("gvrt", "Goldstone Apple Valley Radio Telescope"),
("hcra", "Host Country Radio Astronomy"),
("hmap", "LunaH-Map"),
("hst", "Hubble Space Telescope"),
("hyb2", "Hayabusa-2"),
("ice", "ISEE-3 Reboot"),
("icps", "Interim Cryogenic Propulsion Stage"),
("imag", "IMAGE"),
("imap", "IMAP"),
("intg", "INTEGRAL"),
("jno", "Juno"),
("jnsa", "Janus A"),
("jnsb", "Janus B"),
("jwst", "James Webb Space Telescope"),
("kepl", "Kepler"),
("kplo", "Korea Pathfinder Lunar Orbiter"),
("lade", "LADEE"),
("ltb", "Lunar Trailblazer"),
("lcro", "LCROSS"),
("lfl", "Lunar Flashlight"),
("lici", "LICIACube"),
("lro", "Lunar Reconnaissance Orbiter"),
("lnd1", "Lunar Node 1"),
("ltst", "Interim Cryogenic Propulsion Stage"),
("lucy", "Lucy"),
("lunah-map", "Lunar Hydrogen MAPper"),
("m01o", "Mars Odyssey"),
("m01s", "Mars Odyssey"),
("m20", "Mars 2020 (Perseverance)"),
("map", "WMAP"),
("mcoa", "MarCO A"),
("mcob", "MarCO B"),
("mer1", "Opportunity"),
("mer2", "Spirit"),
("mex", "Mars Express"),
("mgs", "Mars Global Surveyor"),
("mlic", "Lunar IceCube"),
("mms1", "MMS 1"),
("mms2", "MMS 2"),
("mms3", "MMS 3"),
("mms4", "MMS 4"),
("mom", "Mars Orbiter Mission"),
("mro", "Mars Reconnaissance Orbiter"),
("mros", "Mars Reconnaissance Orbiter"),
("msgr", "MESSENGER"),
("msl", "Mars Science Laboratory (Curiosity)"),
("musc", "Hayabusa"),
("mvn", "MAVEN"),
("neas", "Near Earth Asteroid Scout"),
("nhpc", "New Horizons"),
("no15", "NOAA 15"),
("no16", "NOAA 16"),
("no17", "NOAA 17"),
("no18", "NOAA 18"),
("nsyt", "InSight"),
("olin", "SWARM-EX"),
("omot", "OMOTENASHI"),
("orx", "OSIRIS-REx"),
("phx", "Phoenix"),
("plc", "Akatsuki"),
("polr", "POLAR"),
("psyc", "Psyche"),
("rd1", "Red Dragon 1"),
("rfc", "Reference Frame Calibration"),
("rose", "Rosetta"),
("rp", "Resource Prospector"),
("rsp", "ExoMars Rover and Surface Platform"),
("rsts", "Resource System Time Sharing"),
("sdu", "Stardust"),
("sele", "Kaguya"),
("sgp", "Space Geodesy Program"),
("slim", "Smart Lander for Investigating Moon"),
("soho", "SOHO"),
("spil", "Beresheet"),
("spp", "Parker Solar Probe"),
("sta", "STEREO A"),
("stab", "STEREO B"),
("stb", "STEREO B"),
("stf", "Spitzer Space Telescope"),
("swfo", "Space Weather Follow On-Lagrange 1"),
("td10", "TDRS 10"),
("td11", "TDRS 11"),
("td12", "TDRS 12"),
("td13", "TDRS 13"),
("tdr1", "TDRS 1"),
("tdr3", "TDRS 3"),
("tdr4", "TDRS 4"),
("tdr5", "TDRS 5"),
("tdr6", "TDRS 6"),
("tdr7", "TDRS 7"),
("tdr8", "TDRS 8"),
("tdr9", "TDRS 9"),
("terr", "TERRA"),
("tess", "Transiting Exoplanet Survey Satellite"),
("tgo", "Trace Gas Orbiter"),
("thb", "THEMIS B"),
("thc", "THEMIS C"),
("tm", "Team Miles"),
("tmm", "Team Miles"),
("ulys", "Ulysses"),
("vex", "Venus Express"),
("vgr1", "Voyager 1"),
("vgr2", "Voyager 2"),
("vlbi", "V.L.B. Interferometry"),
("wind", "WIND"),
("xmm", "X-ray Multi-Mirror Mission (XMM-Newton)")
]
.into_iter()
.map(|(name, fren_name)| (name.to_string(), fren_name))
.collect();
}
/// Check status of the NASA DSN
#[poise::command(prefix_command, category = "Space")]
pub async fn dsn(ctx: Context<'_>) -> Result<(), Error> {
let mut params = HashMap::new();
let timestamp = (SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_millis()
/ 5000) as u64;
params.insert("r", timestamp);
let client = reqwest::Client::new();
let resp = client
.get("https://eyes.nasa.gov/dsn/data/dsn.xml")
.query(&params)
.send()
.await?
.text()
.await?;
let mut msg_builder = MessageBuilder::new();
msg_builder.push_line("# NASA Deep Space Network Status");
let dsn_stat = DsnResponse::from_xml_string(&resp).unwrap();
for station in &dsn_stat.stations {
msg_builder.push_bold_line(format!("{}:", station.friendly_name));
for dish in &station.dishes {
if let Some(target) = dish.target.first() {
let name = NAME_MAP
.get(&target.name.to_lowercase())
.map(|s| s.to_string())
.unwrap_or(target.name.to_string());
let dish_line = format!(
"* 📡 **{}** => 🛰️ **{}** ({} km away, Round Trip Time: {}s)",
dish.name,
name,
target.upleg_range.separate_with_commas(),
target.rtlt.separate_with_commas()
);
msg_builder.push_line(dish_line);
}
}
}
ctx.reply(msg_builder.build()).await?;
Ok(())
}