Compare commits
10 Commits
Author | SHA1 | Date | |
---|---|---|---|
3062313b10 | |||
ce53d54e8f | |||
b217a98ead | |||
5df09d8440 | |||
b0c880ef09 | |||
a72875733b | |||
f957923b47 | |||
827566b4f2 | |||
2e8f24386f | |||
c32069cfab |
2
.env.sample
Normal file
2
.env.sample
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
ACCUWHEATHER_API_ID=########
|
||||||
|
PATH_TO_CITIES="/share/cities.json"
|
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
**/.env
|
||||||
|
**/target/
|
||||||
|
**/*.lock
|
||||||
|
cities.json
|
11
Dockerfile
Normal file
11
Dockerfile
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
FROM rust AS build
|
||||||
|
WORKDIR /code
|
||||||
|
COPY ./code .
|
||||||
|
RUN cargo install --path .
|
||||||
|
|
||||||
|
FROM debian:buster-slim
|
||||||
|
COPY --from=build /usr/local/cargo/bin/clima /usr/local/bin/clima
|
||||||
|
RUN apt-get update && apt-get install -y libssl-dev && rm -rf /var/lib/apt/lists/*
|
||||||
|
ENV ACCUWHEATHER_API_ID "1"
|
||||||
|
ENV PATH_TO_CITIES "/share/cities.json"
|
||||||
|
CMD [ "sh", "-c", "/usr/local/bin/clima $ACCUWHEATHER_API_ID $PATH_TO_CITIES" ]
|
14
README.md
14
README.md
@ -1,5 +1,17 @@
|
|||||||
# Call
|
# Call
|
||||||
|
|
||||||
```
|
```
|
||||||
app ACCUWHEATHER_API_ID PATH_TO_CITIES.txt
|
docker compose up
|
||||||
|
```
|
||||||
|
|
||||||
|
# Compile / Build
|
||||||
|
|
||||||
|
```
|
||||||
|
docker compose build
|
||||||
|
```
|
||||||
|
|
||||||
|
# Rebuild
|
||||||
|
|
||||||
|
```
|
||||||
|
docker compose down --rmi all; docker compose build
|
||||||
```
|
```
|
||||||
|
58
code/src/lib.rs
Normal file
58
code/src/lib.rs
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
use std::fs::File;
|
||||||
|
pub mod model;
|
||||||
|
use crate::model::{Country, Weather};
|
||||||
|
|
||||||
|
// Get all the city and countrie data outside of the program
|
||||||
|
pub fn get_list(path:String) -> Vec<Country> {
|
||||||
|
let file = File::open(path).expect("El archivo debería permitir la lectura.");
|
||||||
|
let json: Vec<Country> = serde_json::from_reader(file).expect("Pensá un poquito... capaz que no colocaste la ruta correctamente o peñarol peñarol.");
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is the call to the api.
|
||||||
|
pub async fn call_api(code:&String, api_key:&String) -> Result<Weather, reqwest::Error> {
|
||||||
|
let url = format!(
|
||||||
|
"http://dataservice.accuweather.com/forecasts/v1/daily/1day/{}?apikey={}&language=es-ES&metric=true",
|
||||||
|
code,
|
||||||
|
api_key);
|
||||||
|
|
||||||
|
let data = reqwest::get(url)
|
||||||
|
.await?
|
||||||
|
.json::<Weather>()
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
Ok(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn convert_icon(icon: i32) -> String {
|
||||||
|
|
||||||
|
let final_icon = match icon {
|
||||||
|
1..=5 => ":soleado:",
|
||||||
|
6 => ":casi_todo_soleado:",
|
||||||
|
7..=8 => ":nube:",
|
||||||
|
35..=38 => ":nube:",
|
||||||
|
11 => ":nube:",
|
||||||
|
22 => ":nube:",
|
||||||
|
12 => ":nube_de_lluvia:",
|
||||||
|
13..=14 => ":sol_tras_nubes_lluvia:",
|
||||||
|
19 => ":nube_de_nieve:",
|
||||||
|
15 => ":nube_de_truenos_y_lluvia:",
|
||||||
|
20..=21 => ":sol_con_nubes:",
|
||||||
|
23 => ":sol_con_nubes:",
|
||||||
|
24 => ":cubito_de_hielo:",
|
||||||
|
18 => ":nube_de_lluvia:",
|
||||||
|
25 => ":nube_de_lluvia:",
|
||||||
|
39..=40 => ":nube_de_lluvia:",
|
||||||
|
16..=17 => ":nube_de_truenos_y_lluvia:",
|
||||||
|
41..=42 => ":nube_de_truenos_y_lluvia:",
|
||||||
|
26 => ":nube_de_nieve:",
|
||||||
|
29 => ":nube_de_nieve:",
|
||||||
|
30 => ":cara_con_calor:",
|
||||||
|
31 => ":cara_con_frio:",
|
||||||
|
32 => ":guión:",
|
||||||
|
33..=34 => ":luna_llena_con_cara:",
|
||||||
|
_=>""
|
||||||
|
};
|
||||||
|
|
||||||
|
return final_icon.to_string();
|
||||||
|
}
|
36
code/src/main.rs
Normal file
36
code/src/main.rs
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
use std::env;
|
||||||
|
use std::string::String;
|
||||||
|
|
||||||
|
use clima::{get_list, call_api, convert_icon};
|
||||||
|
use clima::model::Country;
|
||||||
|
|
||||||
|
#[tokio::main]
|
||||||
|
async fn main() {
|
||||||
|
let args: Vec<String> = env::args().collect();
|
||||||
|
|
||||||
|
let key = &args[1];
|
||||||
|
let path = &args[2];
|
||||||
|
|
||||||
|
let countries: Vec<Country> = get_list(path.to_string());
|
||||||
|
|
||||||
|
for country in countries {
|
||||||
|
println!("{} {}", country.name, country.flag);
|
||||||
|
for city in country.cities {
|
||||||
|
println!("{}", city.name);
|
||||||
|
if let Ok(w) = call_api(&city.code, &key).await {
|
||||||
|
println!("{}", w.headline.text);
|
||||||
|
println!("Máxima: {} | Mínima:{}",w.daily_forecasts[0].temperature.maximum.value, w.daily_forecasts[0].temperature.minimum.value);
|
||||||
|
println!("Día {} ({}) | Noche {} ({})",
|
||||||
|
convert_icon(w.daily_forecasts[0].day.icon),
|
||||||
|
w.daily_forecasts[0].day.icon_phrase,
|
||||||
|
convert_icon(w.daily_forecasts[0].night.icon),
|
||||||
|
w.daily_forecasts[0].night.icon_phrase,
|
||||||
|
);
|
||||||
|
println!("Más información: {}", w.daily_forecasts[0].link);
|
||||||
|
println!("***************************");
|
||||||
|
} else {
|
||||||
|
println!("Tan cerca... pero tan lejos. Algo en las estructuras está mal. Quizá nunca debiste ponerte a estudiar RUST. Cagón!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
7
code/src/model/city.rs
Normal file
7
code/src/model/city.rs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
use serde::{Serialize, Deserialize};
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct City {
|
||||||
|
pub name : String,
|
||||||
|
pub code: String
|
||||||
|
}
|
10
code/src/model/country.rs
Normal file
10
code/src/model/country.rs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
use serde::{Serialize, Deserialize};
|
||||||
|
use std::string::String;
|
||||||
|
use super::City;
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct Country {
|
||||||
|
pub name : String,
|
||||||
|
pub flag: String,
|
||||||
|
pub cities: Vec<City>
|
||||||
|
}
|
17
code/src/model/daily_forecasts.rs
Normal file
17
code/src/model/daily_forecasts.rs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
use serde::{Serialize, Deserialize};
|
||||||
|
use std::string::String;
|
||||||
|
use super::{Day, Temperature};
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct DailyForecasts {
|
||||||
|
#[serde(rename = "Date")]
|
||||||
|
pub date: String,
|
||||||
|
#[serde(rename = "Day")]
|
||||||
|
pub day: Day,
|
||||||
|
#[serde(rename = "Night")]
|
||||||
|
pub night: Day,
|
||||||
|
#[serde(rename = "Temperature")]
|
||||||
|
pub temperature : Temperature,
|
||||||
|
#[serde(rename = "Link")]
|
||||||
|
pub link: String
|
||||||
|
}
|
10
code/src/model/day.rs
Normal file
10
code/src/model/day.rs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
use serde::{Serialize, Deserialize};
|
||||||
|
use std::string::String;
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct Day {
|
||||||
|
#[serde(rename = "Icon")]
|
||||||
|
pub icon: i32,
|
||||||
|
#[serde(rename = "IconPhrase")]
|
||||||
|
pub icon_phrase : String
|
||||||
|
}
|
8
code/src/model/headline.rs
Normal file
8
code/src/model/headline.rs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
use serde::{Serialize, Deserialize};
|
||||||
|
use std::string::String;
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct Headline {
|
||||||
|
#[serde(rename = "Text")]
|
||||||
|
pub text: String
|
||||||
|
}
|
21
code/src/model/mod.rs
Normal file
21
code/src/model/mod.rs
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
mod city;
|
||||||
|
pub use city::City;
|
||||||
|
mod country;
|
||||||
|
pub use country::Country;
|
||||||
|
|
||||||
|
mod temperature_value;
|
||||||
|
pub use temperature_value::TemperatureValue;
|
||||||
|
|
||||||
|
mod temperature;
|
||||||
|
pub use temperature::Temperature;
|
||||||
|
mod day;
|
||||||
|
pub use day::Day;
|
||||||
|
|
||||||
|
mod daily_forecasts;
|
||||||
|
pub use daily_forecasts::DailyForecasts;
|
||||||
|
|
||||||
|
mod headline;
|
||||||
|
pub use headline::Headline;
|
||||||
|
|
||||||
|
mod weather;
|
||||||
|
pub use weather::Weather;
|
10
code/src/model/temperature.rs
Normal file
10
code/src/model/temperature.rs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
use serde::{Serialize, Deserialize};
|
||||||
|
use super::TemperatureValue;
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct Temperature {
|
||||||
|
#[serde(rename = "Minimum")]
|
||||||
|
pub minimum: TemperatureValue,
|
||||||
|
#[serde(rename = "Maximum")]
|
||||||
|
pub maximum: TemperatureValue
|
||||||
|
}
|
12
code/src/model/temperature_value.rs
Normal file
12
code/src/model/temperature_value.rs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
use serde::{Serialize, Deserialize};
|
||||||
|
use std::string::String;
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct TemperatureValue {
|
||||||
|
#[serde(rename = "Value")]
|
||||||
|
pub value: f32,
|
||||||
|
#[serde(rename = "Unit")]
|
||||||
|
pub unit: String,
|
||||||
|
#[serde(rename = "UnitType")]
|
||||||
|
pub unit_type: u32,
|
||||||
|
}
|
10
code/src/model/weather.rs
Normal file
10
code/src/model/weather.rs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
use serde::{Serialize, Deserialize};
|
||||||
|
use super::{Headline, DailyForecasts};
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct Weather {
|
||||||
|
#[serde(rename = "Headline")]
|
||||||
|
pub headline: Headline,
|
||||||
|
#[serde(rename = "DailyForecasts")]
|
||||||
|
pub daily_forecasts: Vec<DailyForecasts>,
|
||||||
|
}
|
10
docker-compose.yml
Normal file
10
docker-compose.yml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
version: '3'
|
||||||
|
|
||||||
|
services:
|
||||||
|
app:
|
||||||
|
image: rust
|
||||||
|
build: .
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
|
volumes:
|
||||||
|
- ./cities.json:/share/cities.json
|
Reference in New Issue
Block a user