This commit is contained in:
Paul Zinselmeyer 2023-05-01 20:56:21 +02:00
commit 40060daaf5
Signed by: pfzetto
GPG key ID: 4EEF46A5B276E648
6 changed files with 1982 additions and 0 deletions

2
.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
/target
.env

42
.gitlab-ci.yml Normal file
View file

@ -0,0 +1,42 @@
variables:
DOCKER_TLS_CERTDIR: ""
DOCKER_HOST: tcp://docker:2375
services:
- name: docker:dind
entrypoint: ["dockerd-entrypoint.sh", "--tls=false"]
stages:
- build
# - test
- pack
cargo-build:
stage: build
image: rust:slim
variables:
CARGO_HOME: $CI_PROJECT_DIR/.cargo
before_script:
script:
- cargo build --release
cache:
key: $CI_COMMIT_REF_SLUG
paths:
- target/
- .cargo/registry/index/
- .cargo/registry/cache/
artifacts:
paths:
- target/release/bin
docker:
stage: pack
image: docker:latest
only:
- master
script:
- docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
- docker build --network host -t $CI_REGISTRY_IMAGE/master . -f Dockerfile
- docker push $CI_REGISTRY_IMAGE/master
dependencies:
- cargo-build

1859
Cargo.lock generated Normal file

File diff suppressed because it is too large Load diff

14
Cargo.toml Normal file
View file

@ -0,0 +1,14 @@
[package]
name = "stromsensor_mailer"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
dotenvy = "0.15.7"
sqlx = { version = "0.6", features = ["runtime-tokio-rustls", "mysql", "chrono", "decimal"], default-features=false }
lettre = { version="0.10.4", features=["smtp-transport", "pool", "rustls-tls", "hostname", "builder"], default-features=false }
tokio = { version = "1.28.0", features = ["full"] }
chrono = "0.4.24"
rust_decimal = "1.29.1"

5
Dockerfile Normal file
View file

@ -0,0 +1,5 @@
FROM debian:stable-slim as final
WORKDIR /app
COPY ./target/release/bin ./bin
CMD ["/app/bin"]

60
src/main.rs Normal file
View file

@ -0,0 +1,60 @@
use std::env;
use chrono::{Local, NaiveDateTime};
use lettre::{
message::header::ContentType, transport::smtp::authentication::Credentials, Message,
SmtpTransport, Transport,
};
use rust_decimal::{prelude::ToPrimitive, Decimal};
use sqlx::{Connection, MySqlConnection, Row};
#[tokio::main]
async fn main() {
dotenvy::dotenv().ok();
let mut connection = MySqlConnection::connect(
&env::var("DATABASE_URL").expect("DATABASE_URL environment variable"),
)
.await
.unwrap();
let email_host = env::var("EMAIL_HOST").expect("EMAIL_HOST env var");
let email_user = env::var("EMAIL_USER").expect("EMAIL_USER env var");
let email_pass = env::var("EMAIL_PASS").expect("EMAIL_PASS env var");
let email_name = env::var("EMAIL_NAME").expect("EMAIL_NAME env var");
let email_to = env::var("EMAIL_TO").expect("EMAIL_TO env var");
let row =
sqlx::query("SELECT timestamp, value FROM counter_value ORDER BY timestamp DESC LIMIT 1")
.fetch_one(&mut connection)
.await
.unwrap();
let timestamp: NaiveDateTime = row.get("timestamp");
let value: Decimal = row.get("value");
let now = Local::now();
let mut email =
Message::builder().from(format!("{email_name} <{email_user}>").parse().unwrap());
for to in email_to.split(',') {
email = email.to(to.parse().unwrap());
}
let email = email
.subject(format!("Zählerstand vom {}", now.format("%d.%m.%Y")))
.header(ContentType::TEXT_PLAIN)
.body(format!(
"Zählerstand: {:.3} kWh\nStand: {} UTC",
(value.to_u128().unwrap() as f64) / 1000.0,
timestamp.format("%d.%m.%Y %H:%m"),
))
.unwrap();
let creds = Credentials::new(email_user, email_pass);
SmtpTransport::relay(&email_host)
.unwrap()
.credentials(creds)
.build()
.send(&email)
.unwrap();
}