Skip to content

Commit

Permalink
feat: export API keys to secrets
Browse files Browse the repository at this point in the history
  • Loading branch information
RouHim committed Jun 5, 2022
1 parent c74b929 commit a9aa02c
Show file tree
Hide file tree
Showing 9 changed files with 81 additions and 82 deletions.
3 changes: 2 additions & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
cache
target
!target/x86_64-unknown-linux-musl/release/this-week-in-past
!target/release/this-week-in-past
!target/release/this-week-in-past
test.sh
3 changes: 3 additions & 0 deletions .github/workflows/build-image.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ jobs:
test:
name: Run application tests
runs-on: ubuntu-latest
env:
BIGDATA_CLOUD_API_KEY: ${{ secrets.BIGDATA_CLOUD_API_KEY }}
OPEN_WEATHER_MAP_API_KEY: ${{ secrets.OPEN_WEATHER_MAP_API_KEY }}
steps:
- name: Checkout code
uses: actions/checkout@v3
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/target
.idea
cache
test.sh
16 changes: 0 additions & 16 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 13 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,16 @@ docker run -p 8080:8080 \

All configuration is done via environment parameter:

| Name | Description | Default value |
|--------------------------|---------------------------------------------------------|---------------|
| RESOURCE_PATHS | Paths to the resources to load (comma separated) | |
| CACHE_DIR | Path to the caching to load, needs to read/write rights | |
| SLIDESHOW_INTERVAL | Interval of the slideshow in milliseconds | 10000 |
| WEATHER_ENABLED | Indicates if weather should be shown in the slideshow | true |
| LOCATION_NAME | Weather location | Berlin |
| LANGUAGE | Weather language | en |
| HOME_ASSISTANT_BASE_URL | Home assistant base url | |
| HOME_ASSISTANT_ENTITY_ID | Home assistant entity id to load the weather from | |
| HOME_ASSISTANT_API_TOKEN | Home assistant api access token | |
| Name | Description | Default value |
|--------------------------|------------------------------------------------------------------------------------|---------------|
| RESOURCE_PATHS | Paths to the resources to load (comma separated) | |
| CACHE_DIR | Path to the caching to load, needs to read/write rights | |
| SLIDESHOW_INTERVAL | Interval of the slideshow in milliseconds | 10000 |
| WEATHER_ENABLED | Indicates if weather should be shown in the slideshow | true |
| BIGDATA_CLOUD_API_KEY | To resolve geo coordinates to city name. Obtain here: https://www.bigdatacloud.com | |
| OPEN_WEATHER_MAP_API_KEY | To receive weather live data. Obtain here: https://openweathermap.org/api | |
| LOCATION_NAME | Weather location | Berlin |
| LANGUAGE | Weather language | en |
| HOME_ASSISTANT_BASE_URL | Home assistant base url | |
| HOME_ASSISTANT_ENTITY_ID | Home assistant entity id to load the weather from | |
| HOME_ASSISTANT_API_TOKEN | Home assistant api access token | |
49 changes: 49 additions & 0 deletions src/geo_location.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
use std::collections::HashMap;
use std::env;
use std::fmt::{Display, Formatter};

use lazy_static::lazy_static;
use regex::{Captures, Regex};
use serde::{Deserialize, Serialize};
use serde_json::Value;

/// Struct representing a geo location
#[derive(Serialize, Deserialize, Debug, Copy, Clone, PartialEq)]
Expand Down Expand Up @@ -114,3 +117,49 @@ pub fn from_degrees_minutes_seconds(latitude: String, longitude: String) -> Opti
None
}
}

/// Returns the city name for the specified geo location
/// The city name is resolved from the geo location using the bigdatacloud api
pub async fn resolve_city_name(geo_location: GeoLocation) -> Option<String> {
if env::var("BIGDATA_CLOUD_API_KEY").is_err() {
return None;
}

let response = reqwest::get(format!(
"https://api.bigdatacloud.net/data/reverse-geocode?latitude={}&longitude={}&localityLanguage=de&key={}",
geo_location.latitude,
geo_location.longitude,
env::var("BIGDATA_CLOUD_API_KEY").unwrap(),
)).await;

if response.is_err() {
return None;
}

let response_json =
response.unwrap().text().await.ok().and_then(|json_string| {
serde_json::from_str::<HashMap<String, Value>>(&json_string).ok()
});

let mut city_name = response_json
.as_ref()
.and_then(|json_data| get_string_value("city", json_data))
.filter(|city_name| !city_name.trim().is_empty());

if city_name.is_none() {
city_name = response_json
.as_ref()
.and_then(|json_data| get_string_value("locality", json_data))
.filter(|city_name| !city_name.trim().is_empty());
}

city_name
}

/// Returns the string value for the specified key of an hash map
fn get_string_value(field_name: &str, json_data: &HashMap<String, Value>) -> Option<String> {
json_data
.get(field_name)
.and_then(|field_value| field_value.as_str())
.map(|field_string_value| field_string_value.to_string())
}
48 changes: 2 additions & 46 deletions src/resource_processor.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
use std::collections::HashMap;
use std::env;

use evmap::ReadHandle;
use rand::prelude::SliceRandom;
use rand::Rng;
use rayon::iter::{IntoParallelRefIterator, ParallelIterator};
use serde_json::Value;

use crate::geo_location::GeoLocation;
use crate::geo_location;
use crate::resource_reader::RemoteResource;

pub fn md5(string: &str) -> String {
Expand Down Expand Up @@ -58,7 +56,7 @@ pub async fn build_display_value(resource: RemoteResource) -> String {

// Append city name
if let Some(resource_location) = resource.location {
let city_name = resolve_city_name(resource_location).await;
let city_name = geo_location::resolve_city_name(resource_location).await;

if let Some(city_name) = city_name {
display_value.push_str(", ");
Expand All @@ -69,48 +67,6 @@ pub async fn build_display_value(resource: RemoteResource) -> String {
display_value.trim().to_string()
}

/// Returns the city name for the specified geo location
/// The city name is resolved from the geo location using the bigdatacloud api
pub async fn resolve_city_name(geo_location: GeoLocation) -> Option<String> {
let response = reqwest::get(format!(
"https://api.bigdatacloud.net/data/reverse-geocode?latitude={}&longitude={}&localityLanguage=de&key={}",
geo_location.latitude,
geo_location.longitude,
"6b8aad17eba7449d9d93c533359b0384",
)).await;

if response.is_err() {
return None;
}

let response_json =
response.unwrap().text().await.ok().and_then(|json_string| {
serde_json::from_str::<HashMap<String, Value>>(&json_string).ok()
});

let mut city_name = response_json
.as_ref()
.and_then(|json_data| get_string_value("city", json_data))
.filter(|city_name| !city_name.trim().is_empty());

if city_name.is_none() {
city_name = response_json
.as_ref()
.and_then(|json_data| get_string_value("locality", json_data))
.filter(|city_name| !city_name.trim().is_empty());
}

city_name
}

/// Returns the string value for the specified key of an hash map
fn get_string_value(field_name: &str, json_data: &HashMap<String, Value>) -> Option<String> {
json_data
.get(field_name)
.and_then(|field_value| field_value.as_str())
.map(|field_string_value| field_string_value.to_string())
}

/// Selects a random entry from the specified resource provider
/// The id of the resource is returned
pub fn random_entry(kv_reader: &ReadHandle<String, String>) -> Option<String> {
Expand Down
10 changes: 5 additions & 5 deletions src/resource_processor_test.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use assertor::*;

use crate::geo_location::GeoLocation;
use crate::resource_processor;
use crate::{geo_location, resource_processor};

#[actix_rt::test]
async fn resolve_koblenz() {
Expand All @@ -12,7 +12,7 @@ async fn resolve_koblenz() {
};

// WHEN resolving the city name
let city_name = resource_processor::resolve_city_name(geo_location).await;
let city_name = geo_location::resolve_city_name(geo_location).await;

// THEN the resolved city name should be Koblenz
assert_that!(city_name).is_equal_to(Some("Koblenz".to_string()));
Expand All @@ -27,7 +27,7 @@ async fn resolve_amsterdam() {
};

// WHEN resolving the city name
let city_name = resource_processor::resolve_city_name(geo_location).await;
let city_name = geo_location::resolve_city_name(geo_location).await;

// THEN the resolved city name should be Amsterdam
assert_that!(city_name).is_equal_to(Some("Amsterdam".to_string()));
Expand All @@ -42,7 +42,7 @@ async fn resolve_kottenheim() {
};

// WHEN resolving the city name
let city_name = resource_processor::resolve_city_name(geo_location).await;
let city_name = geo_location::resolve_city_name(geo_location).await;

// THEN the resolved city name should be Kottenheim
assert_that!(city_name).is_equal_to(Some("Kottenheim".to_string()));
Expand All @@ -57,7 +57,7 @@ async fn resolve_invalid_data() {
};

// WHEN resolving the city name
let city_name = resource_processor::resolve_city_name(geo_location).await;
let city_name = geo_location::resolve_city_name(geo_location).await;

// THEN the resolved city name should be None
assert_that!(city_name).is_equal_to(None);
Expand Down
9 changes: 6 additions & 3 deletions src/weather_processor.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
use std::env;

const OPEN_WEATHER_MAP_API_KEY: &str = "4021b60be2b322c8cfc749a6503bb553";

/// Returns the current weather data provided by OpenWeatherMap
/// The data is selected by the configured location
/// Returns None if the data could not be retrieved or the weather json data
pub async fn get_current_weather() -> Option<String> {
if env::var("OPEN_WEATHER_MAP_API_KEY").is_err() {
return None;
}

let api_key: String = env::var("OPEN_WEATHER_MAP_API_KEY").unwrap();
let city: String = env::var("LOCATION_NAME").unwrap_or_else(|_| "Berlin".to_string());
let units: String = env::var("UNITS").unwrap_or_else(|_| "metric".to_string());
let language: String = env::var("LANGUAGE").unwrap_or_else(|_| "en".to_string());

let response = reqwest::get(format!(
"https://api.openweathermap.org/data/2.5/weather?q={city}&appid={OPEN_WEATHER_MAP_API_KEY}&units={units}&lang={language}"
"https://api.openweathermap.org/data/2.5/weather?q={city}&appid={api_key}&units={units}&lang={language}"
)).await;

if response.is_ok() {
Expand Down

0 comments on commit a9aa02c

Please sign in to comment.