Compare commits

...

1 Commits

Author SHA1 Message Date
dynco-nym 346c4f7910 Add latitude/longitude fields to Location 2024-11-29 18:51:00 +01:00
3 changed files with 54 additions and 15 deletions
Generated
+1 -1
View File
@@ -6061,7 +6061,7 @@ dependencies = [
[[package]]
name = "nym-node-status-api"
version = "1.0.0-rc.4"
version = "1.0.0-rc.4-fix"
dependencies = [
"anyhow",
"axum 0.7.7",
@@ -3,7 +3,7 @@
[package]
name = "nym-node-status-api"
version = "1.0.0-rc.4"
version = "1.0.0-rc.4-fix"
authors.workspace = true
repository.workspace = true
homepage.workspace = true
@@ -1,5 +1,5 @@
use cosmwasm_std::{Addr, Coin};
use serde::{Deserialize, Serialize};
use serde::{Deserialize, Deserializer, Serialize};
pub(crate) struct IpInfoClient {
client: reqwest::Client,
@@ -15,11 +15,7 @@ impl IpInfoClient {
}
pub(crate) async fn locate_ip(&self, ip: impl AsRef<str>) -> anyhow::Result<Location> {
let url = format!(
"https://ipinfo.io/{}/country?token={}",
ip.as_ref(),
&self.token
);
let url = format!("https://ipinfo.io/{}?token={}", ip.as_ref(), &self.token);
let response = self
.client
.get(url)
@@ -33,11 +29,12 @@ impl IpInfoClient {
}
anyhow::Error::from(err)
})?;
let response_text = response.text().await?.trim().to_string();
let raw_response = response.text().await?;
let response: LocationResponse =
serde_json::from_str(&raw_response).inspect_err(|e| tracing::error!("{e}"))?;
let location = response.into();
Ok(Location {
two_letter_iso_country_code: response_text,
})
Ok(location)
}
/// check DOESN'T consume bandwidth allowance
@@ -64,7 +61,7 @@ impl IpInfoClient {
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[derive(Debug, Clone, Serialize)]
pub(crate) struct NodeGeoData {
pub(crate) identity_key: String,
pub(crate) owner: Addr,
@@ -72,15 +69,57 @@ pub(crate) struct NodeGeoData {
pub(crate) location: Location,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[derive(Debug, Clone, Serialize)]
pub(crate) struct Location {
pub(crate) two_letter_iso_country_code: String,
#[serde(flatten)]
pub(crate) location: Coordinates,
}
impl From<LocationResponse> for Location {
fn from(value: LocationResponse) -> Self {
Self {
two_letter_iso_country_code: value.two_letter_iso_country_code,
location: value.loc,
}
}
}
#[derive(Debug, Clone, Deserialize)]
pub(crate) struct LocationResponse {
#[serde(rename = "country")]
pub(crate) two_letter_iso_country_code: String,
#[serde(deserialize_with = "deserialize_loc")]
pub(crate) loc: Coordinates,
}
fn deserialize_loc<'de, D>(deserializer: D) -> Result<Coordinates, D::Error>
where
D: Deserializer<'de>,
{
let loc_raw = String::deserialize(deserializer)?;
return match loc_raw.split_once(',') {
Some((lat, long)) => Ok(Coordinates {
latitude: lat.parse().map_err(|err| serde::de::Error::custom(err))?,
longitude: long.parse().map_err(|err| serde::de::Error::custom(err))?,
}),
None => Err(serde::de::Error::custom("coordinates")),
};
}
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
pub(crate) struct Coordinates {
pub(crate) latitude: f64,
pub(crate) longitude: f64,
}
impl Location {
pub(crate) fn empty() -> Self {
Self {
two_letter_iso_country_code: String::new(),
two_letter_iso_country_code: String::default(),
location: Coordinates {
..Default::default()
},
}
}
}