wip
This commit is contained in:
commit
adda135743
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
target
|
||||
result
|
3339
Cargo.lock
generated
Normal file
3339
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
16
Cargo.toml
Normal file
16
Cargo.toml
Normal file
@ -0,0 +1,16 @@
|
||||
[package]
|
||||
name = "alert-me"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
clap = { version = "4.5.4", features = ["derive"] }
|
||||
config = "0.14.0"
|
||||
reqwest = { version = "0.12.4", features = ["json", "rustls-tls"], default-features = false }
|
||||
rumqttc = "0.24.0"
|
||||
sea-orm = { version = "0.12", features = [ "sqlx-postgres", "runtime-tokio-rustls", "macros" ] }
|
||||
serde = "1.0.199"
|
||||
serde_json = "1.0.116"
|
||||
tokio = { version = "1.37.0", features = ["full"] }
|
||||
tracing = "0.1.40"
|
||||
tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
|
145
flake.lock
Normal file
145
flake.lock
Normal file
@ -0,0 +1,145 @@
|
||||
{
|
||||
"nodes": {
|
||||
"fenix": {
|
||||
"inputs": {
|
||||
"nixpkgs": "nixpkgs",
|
||||
"rust-analyzer-src": "rust-analyzer-src"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1714199028,
|
||||
"narHash": "sha256-QO3Yv3UfJRfhZE1wsHOartg+k8/Kf1BiDyfl8eEpqcE=",
|
||||
"owner": "nix-community",
|
||||
"repo": "fenix",
|
||||
"rev": "055f6db376eaf544d84aa55bd5a7c70634af41ba",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-community",
|
||||
"repo": "fenix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-utils": {
|
||||
"inputs": {
|
||||
"systems": "systems"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1710146030,
|
||||
"narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"naersk": {
|
||||
"inputs": {
|
||||
"nixpkgs": "nixpkgs_2"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1713520724,
|
||||
"narHash": "sha256-CO8MmVDmqZX2FovL75pu5BvwhW+Vugc7Q6ze7Hj8heI=",
|
||||
"owner": "nix-community",
|
||||
"repo": "naersk",
|
||||
"rev": "c5037590290c6c7dae2e42e7da1e247e54ed2d49",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-community",
|
||||
"repo": "naersk",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1714076141,
|
||||
"narHash": "sha256-Drmja/f5MRHZCskS6mvzFqxEaZMeciScCTFxWVLqWEY=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "7bb2ccd8cdc44c91edba16c48d2c8f331fb3d856",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nixos",
|
||||
"ref": "nixos-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs_2": {
|
||||
"locked": {
|
||||
"lastModified": 0,
|
||||
"narHash": "sha256-Drmja/f5MRHZCskS6mvzFqxEaZMeciScCTFxWVLqWEY=",
|
||||
"path": "/nix/store/370qy3d3wg9zhbn5a3dcv6k1q1iigfh4-source",
|
||||
"type": "path"
|
||||
},
|
||||
"original": {
|
||||
"id": "nixpkgs",
|
||||
"type": "indirect"
|
||||
}
|
||||
},
|
||||
"nixpkgs_3": {
|
||||
"locked": {
|
||||
"lastModified": 1714076141,
|
||||
"narHash": "sha256-Drmja/f5MRHZCskS6mvzFqxEaZMeciScCTFxWVLqWEY=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "7bb2ccd8cdc44c91edba16c48d2c8f331fb3d856",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"fenix": "fenix",
|
||||
"flake-utils": "flake-utils",
|
||||
"naersk": "naersk",
|
||||
"nixpkgs": "nixpkgs_3"
|
||||
}
|
||||
},
|
||||
"rust-analyzer-src": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1714150666,
|
||||
"narHash": "sha256-S8AsTyJvT6Q3pRFeo8QepWF/husnJh61cOhRt18Xmyc=",
|
||||
"owner": "rust-lang",
|
||||
"repo": "rust-analyzer",
|
||||
"rev": "1ed7e2de05ee76f6ae83cc9c72eb0b33ad6903f2",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "rust-lang",
|
||||
"ref": "nightly",
|
||||
"repo": "rust-analyzer",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"systems": {
|
||||
"locked": {
|
||||
"lastModified": 1681028828,
|
||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"type": "github"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
148
flake.nix
Normal file
148
flake.nix
Normal file
@ -0,0 +1,148 @@
|
||||
{
|
||||
description = "alert-me project";
|
||||
inputs = {
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||
flake-utils.url = "github:numtide/flake-utils";
|
||||
naersk.url = "github:nix-community/naersk";
|
||||
fenix.url = "github:nix-community/fenix";
|
||||
};
|
||||
|
||||
outputs =
|
||||
{
|
||||
self,
|
||||
nixpkgs,
|
||||
naersk,
|
||||
fenix,
|
||||
flake-utils,
|
||||
...
|
||||
}:
|
||||
let
|
||||
buildTargets = {
|
||||
"x86_64-linux" = {
|
||||
crossSystemConfig = "x86_64-unknown-linux-musl";
|
||||
rustTarget = "x86_64-unknown-linux-musl";
|
||||
};
|
||||
|
||||
"i686-linux" = {
|
||||
crossSystemConfig = "i686-unknown-linux-musl";
|
||||
rustTarget = "i686-unknown-linux-musl";
|
||||
};
|
||||
|
||||
"aarch64-linux" = {
|
||||
crossSystemConfig = "aarch64-unknown-linux-musl";
|
||||
rustTarget = "aarch64-unknown-linux-musl";
|
||||
};
|
||||
|
||||
"armv6l-linux" = {
|
||||
crossSystemConfig = "armv6l-unknown-linux-musleabihf";
|
||||
rustTarget = "arm-unknown-linux-musleabihf";
|
||||
};
|
||||
};
|
||||
|
||||
eachSystem =
|
||||
supportedSystems: callback:
|
||||
builtins.foldl' (overall: system: overall // { ${system} = callback system; }) { } supportedSystems;
|
||||
|
||||
eachCrossSystem =
|
||||
supportedSystems: callback:
|
||||
eachSystem supportedSystems (
|
||||
buildSystem:
|
||||
builtins.foldl' (
|
||||
inner: targetSystem: inner // { "cross-${targetSystem}" = callback buildSystem targetSystem; }
|
||||
) { default = callback buildSystem buildSystem; } supportedSystems
|
||||
);
|
||||
|
||||
mkPkgs =
|
||||
buildSystem: targetSystem:
|
||||
import nixpkgs (
|
||||
{
|
||||
system = buildSystem;
|
||||
}
|
||||
// (
|
||||
if targetSystem == null then
|
||||
{ }
|
||||
else
|
||||
{ crossSystem.config = buildTargets.${targetSystem}.crossSystemConfig; }
|
||||
)
|
||||
);
|
||||
in
|
||||
flake-utils.lib.eachDefaultSystem (
|
||||
system:
|
||||
let
|
||||
pkgs = import nixpkgs { inherit system; };
|
||||
rust = fenix.packages.${system}.stable;
|
||||
in
|
||||
with pkgs;
|
||||
{
|
||||
devShells.default = mkShell {
|
||||
buildInputs = [
|
||||
mosquitto
|
||||
rust.toolchain
|
||||
rust-analyzer
|
||||
sea-orm-cli
|
||||
];
|
||||
};
|
||||
}
|
||||
)
|
||||
// {
|
||||
packages = eachCrossSystem (builtins.attrNames buildTargets) (
|
||||
buildSystem: targetSystem:
|
||||
let
|
||||
pkgs = mkPkgs buildSystem null;
|
||||
pkgsCross = mkPkgs buildSystem targetSystem;
|
||||
rustTarget = buildTargets.${targetSystem}.rustTarget;
|
||||
|
||||
fenixPkgs = fenix.packages.${buildSystem};
|
||||
|
||||
mkToolchain = fenixPkgs: fenixPkgs.stable;
|
||||
|
||||
toolchain = fenixPkgs.combine [
|
||||
(mkToolchain fenixPkgs).rustc
|
||||
(mkToolchain fenixPkgs).cargo
|
||||
(mkToolchain fenixPkgs.targets.${rustTarget}).rust-std
|
||||
];
|
||||
|
||||
buildPackageAttrs =
|
||||
if builtins.hasAttr "makeBuildPackageAttrs" buildTargets.${targetSystem} then
|
||||
buildTargets.${targetSystem}.makeBuildPackageAttrs pkgsCross
|
||||
else
|
||||
{ };
|
||||
|
||||
naersk-lib = pkgs.callPackage naersk {
|
||||
cargo = toolchain;
|
||||
rustc = toolchain;
|
||||
};
|
||||
in
|
||||
naersk-lib.buildPackage (
|
||||
buildPackageAttrs
|
||||
// rec {
|
||||
src = ./.;
|
||||
strictDeps = true;
|
||||
doCheck = false;
|
||||
|
||||
OPENSSL_STATIC = "1";
|
||||
OPENSSL_LIB_DIR = "${pkgsCross.pkgsStatic.openssl.out}/lib";
|
||||
OPENSSL_INCLUDE_DIR = "${pkgsCross.pkgsStatic.openssl.dev}/include";
|
||||
|
||||
# Required because ring crate is special. This also seems to have
|
||||
# fixed some issues with the x86_64-windows cross-compile :shrug:
|
||||
TARGET_CC = "${pkgsCross.stdenv.cc}/bin/${pkgsCross.stdenv.cc.targetPrefix}cc";
|
||||
|
||||
CARGO_BUILD_TARGET = rustTarget;
|
||||
CARGO_BUILD_RUSTFLAGS = [
|
||||
"-C"
|
||||
"target-feature=+crt-static"
|
||||
|
||||
# -latomic is required to build openssl-sys for armv6l-linux, but
|
||||
# it doesn't seem to hurt any other builds.
|
||||
# "-C"
|
||||
# "link-args=-static -latomic"
|
||||
|
||||
"-C"
|
||||
"linker=${TARGET_CC}"
|
||||
];
|
||||
}
|
||||
)
|
||||
);
|
||||
};
|
||||
}
|
21
migration/Cargo.toml
Normal file
21
migration/Cargo.toml
Normal file
@ -0,0 +1,21 @@
|
||||
[package]
|
||||
name = "migration"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
publish = false
|
||||
|
||||
[lib]
|
||||
name = "migration"
|
||||
path = "src/lib.rs"
|
||||
|
||||
[dependencies]
|
||||
async-std = { version = "1", features = ["attributes", "tokio1"] }
|
||||
|
||||
[dependencies.sea-orm-migration]
|
||||
version = "0.12.0"
|
||||
features = [
|
||||
# Enable at least one `ASYNC_RUNTIME` and `DATABASE_DRIVER` feature if you want to run migration via CLI.
|
||||
# View the list of supported features at https://www.sea-ql.org/SeaORM/docs/install-and-config/database-and-async-runtime.
|
||||
# e.g.
|
||||
"runtime-tokio-rustls", "sqlx-postgres",
|
||||
]
|
41
migration/README.md
Normal file
41
migration/README.md
Normal file
@ -0,0 +1,41 @@
|
||||
# Running Migrator CLI
|
||||
|
||||
- Generate a new migration file
|
||||
```sh
|
||||
cargo run -- generate MIGRATION_NAME
|
||||
```
|
||||
- Apply all pending migrations
|
||||
```sh
|
||||
cargo run
|
||||
```
|
||||
```sh
|
||||
cargo run -- up
|
||||
```
|
||||
- Apply first 10 pending migrations
|
||||
```sh
|
||||
cargo run -- up -n 10
|
||||
```
|
||||
- Rollback last applied migrations
|
||||
```sh
|
||||
cargo run -- down
|
||||
```
|
||||
- Rollback last 10 applied migrations
|
||||
```sh
|
||||
cargo run -- down -n 10
|
||||
```
|
||||
- Drop all tables from the database, then reapply all migrations
|
||||
```sh
|
||||
cargo run -- fresh
|
||||
```
|
||||
- Rollback all applied migrations, then reapply all migrations
|
||||
```sh
|
||||
cargo run -- refresh
|
||||
```
|
||||
- Rollback all applied migrations
|
||||
```sh
|
||||
cargo run -- reset
|
||||
```
|
||||
- Check the status of all migrations
|
||||
```sh
|
||||
cargo run -- status
|
||||
```
|
12
migration/src/lib.rs
Normal file
12
migration/src/lib.rs
Normal file
@ -0,0 +1,12 @@
|
||||
pub use sea_orm_migration::prelude::*;
|
||||
|
||||
mod m20220101_000001_create_table;
|
||||
|
||||
pub struct Migrator;
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl MigratorTrait for Migrator {
|
||||
fn migrations() -> Vec<Box<dyn MigrationTrait>> {
|
||||
vec![Box::new(m20220101_000001_create_table::Migration)]
|
||||
}
|
||||
}
|
47
migration/src/m20220101_000001_create_table.rs
Normal file
47
migration/src/m20220101_000001_create_table.rs
Normal file
@ -0,0 +1,47 @@
|
||||
use sea_orm_migration::prelude::*;
|
||||
|
||||
#[derive(DeriveMigrationName)]
|
||||
pub struct Migration;
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl MigrationTrait for Migration {
|
||||
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
// Replace the sample below with your own migration scripts
|
||||
todo!();
|
||||
|
||||
manager
|
||||
.create_table(
|
||||
Table::create()
|
||||
.table(Post::Table)
|
||||
.if_not_exists()
|
||||
.col(
|
||||
ColumnDef::new(Post::Id)
|
||||
.integer()
|
||||
.not_null()
|
||||
.auto_increment()
|
||||
.primary_key(),
|
||||
)
|
||||
.col(ColumnDef::new(Post::Title).string().not_null())
|
||||
.col(ColumnDef::new(Post::Text).string().not_null())
|
||||
.to_owned(),
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
// Replace the sample below with your own migration scripts
|
||||
todo!();
|
||||
|
||||
manager
|
||||
.drop_table(Table::drop().table(Post::Table).to_owned())
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(DeriveIden)]
|
||||
enum Post {
|
||||
Table,
|
||||
Id,
|
||||
Title,
|
||||
Text,
|
||||
}
|
6
migration/src/main.rs
Normal file
6
migration/src/main.rs
Normal file
@ -0,0 +1,6 @@
|
||||
use sea_orm_migration::prelude::*;
|
||||
|
||||
#[async_std::main]
|
||||
async fn main() {
|
||||
cli::run_cli(migration::Migrator).await;
|
||||
}
|
37
src/json/alert.rs
Normal file
37
src/json/alert.rs
Normal file
@ -0,0 +1,37 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use super::{
|
||||
area::Area, contact::Contact, description::Description, image::Image,
|
||||
image_description::ImageDescription, image_title::ImageTitle, link::Link, text::Text,
|
||||
title::Title,
|
||||
};
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Alert {
|
||||
pub identifier: String,
|
||||
pub gtrans_origin: Option<String>,
|
||||
pub sent: String,
|
||||
pub title: Title,
|
||||
pub description: Description,
|
||||
pub nation_wide: bool,
|
||||
pub banner: bool,
|
||||
pub instructions: Vec<Text>,
|
||||
pub sender: String,
|
||||
pub publisher_name: Option<String>,
|
||||
pub link: Option<String>,
|
||||
pub links: Vec<Link>,
|
||||
pub contact: Contact,
|
||||
pub event: String,
|
||||
pub all_clear: bool,
|
||||
pub severity: String,
|
||||
pub test_alert: bool,
|
||||
pub technical_test_alert: bool,
|
||||
pub publish_date: String,
|
||||
pub areas: Vec<Area>,
|
||||
pub images: Vec<Image>,
|
||||
pub image_titles: Vec<ImageTitle>,
|
||||
pub image_descriptions: Vec<ImageDescription>,
|
||||
pub event_icon_path: String,
|
||||
pub reference: String,
|
||||
}
|
10
src/json/alerts.rs
Normal file
10
src/json/alerts.rs
Normal file
@ -0,0 +1,10 @@
|
||||
use super::alert::Alert;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Alerts {
|
||||
pub heartbeat_age_in_millis: u64,
|
||||
pub render_time: String,
|
||||
pub alerts: Vec<Alert>,
|
||||
}
|
13
src/json/area.rs
Normal file
13
src/json/area.rs
Normal file
@ -0,0 +1,13 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use super::{circle::Circle, description::Description, polygon::Polygon, region::Region};
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Area {
|
||||
pub description: Description,
|
||||
pub region_type: String,
|
||||
pub polygons: Vec<Polygon>,
|
||||
pub circles: Vec<Circle>,
|
||||
pub regions: Vec<Region>,
|
||||
}
|
10
src/json/circle.rs
Normal file
10
src/json/circle.rs
Normal file
@ -0,0 +1,10 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use super::coordinate::Coordinate;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Circle {
|
||||
pub center_position: Coordinate,
|
||||
pub radius: String,
|
||||
}
|
8
src/json/contact.rs
Normal file
8
src/json/contact.rs
Normal file
@ -0,0 +1,8 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Contact {
|
||||
pub contact: String,
|
||||
pub contact_origin: Option<String>,
|
||||
}
|
10
src/json/coordinate.rs
Normal file
10
src/json/coordinate.rs
Normal file
@ -0,0 +1,10 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Coordinate {
|
||||
#[serde(rename = "0")]
|
||||
pub zero: String,
|
||||
#[serde(rename = "1")]
|
||||
pub one: String,
|
||||
}
|
8
src/json/description.rs
Normal file
8
src/json/description.rs
Normal file
@ -0,0 +1,8 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Description {
|
||||
pub description: String,
|
||||
pub description_gtrans_origin: Option<String>,
|
||||
}
|
10
src/json/image.rs
Normal file
10
src/json/image.rs
Normal file
@ -0,0 +1,10 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Image {
|
||||
pub uri: String,
|
||||
pub digest: String,
|
||||
pub index: u64,
|
||||
pub size: String,
|
||||
}
|
11
src/json/image_description.rs
Normal file
11
src/json/image_description.rs
Normal file
@ -0,0 +1,11 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use super::description::Description;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct ImageDescription {
|
||||
pub index: u64,
|
||||
#[serde(flatten)]
|
||||
pub description: Description,
|
||||
}
|
12
src/json/image_title.rs
Normal file
12
src/json/image_title.rs
Normal file
@ -0,0 +1,12 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use super::title::Title;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct ImageTitle {
|
||||
pub index: u64,
|
||||
#[serde(flatten)]
|
||||
pub title: Title,
|
||||
pub alt_text: String,
|
||||
}
|
8
src/json/link.rs
Normal file
8
src/json/link.rs
Normal file
@ -0,0 +1,8 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Link {
|
||||
pub href: String,
|
||||
pub text: String,
|
||||
}
|
9
src/json/polygon.rs
Normal file
9
src/json/polygon.rs
Normal file
@ -0,0 +1,9 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use super::coordinate::Coordinate;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Polygon {
|
||||
pub coordinates: Vec<Coordinate>,
|
||||
}
|
7
src/json/region.rs
Normal file
7
src/json/region.rs
Normal file
@ -0,0 +1,7 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Region {
|
||||
pub region: String,
|
||||
}
|
8
src/json/text.rs
Normal file
8
src/json/text.rs
Normal file
@ -0,0 +1,8 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Text {
|
||||
pub text: String,
|
||||
pub text_origin: Option<String>,
|
||||
}
|
8
src/json/title.rs
Normal file
8
src/json/title.rs
Normal file
@ -0,0 +1,8 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Title {
|
||||
pub title: String,
|
||||
pub title_gtrans_origin: Option<String>,
|
||||
}
|
14
src/logging.rs
Normal file
14
src/logging.rs
Normal file
@ -0,0 +1,14 @@
|
||||
use tracing::debug;
|
||||
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
|
||||
|
||||
pub(crate) fn setup(bin_name: &str) {
|
||||
let default_config = format!("{}=info,tower_http=info", bin_name);
|
||||
tracing_subscriber::registry()
|
||||
.with(
|
||||
tracing_subscriber::EnvFilter::try_from_default_env()
|
||||
.unwrap_or_else(|_| default_config.into()),
|
||||
)
|
||||
.with(tracing_subscriber::fmt::layer().with_target(true))
|
||||
.init();
|
||||
debug!("tracing/logging is setup");
|
||||
}
|
42
src/main.rs
Normal file
42
src/main.rs
Normal file
@ -0,0 +1,42 @@
|
||||
use std::time::Duration;
|
||||
|
||||
use tokio::time;
|
||||
use tracing::debug;
|
||||
|
||||
use crate::json::alerts::Alerts;
|
||||
|
||||
mod json {
|
||||
pub mod alert;
|
||||
pub mod alerts;
|
||||
pub mod area;
|
||||
pub mod circle;
|
||||
pub mod contact;
|
||||
pub mod coordinate;
|
||||
pub mod description;
|
||||
pub mod image;
|
||||
pub mod image_description;
|
||||
pub mod image_title;
|
||||
pub mod link;
|
||||
pub mod polygon;
|
||||
pub mod region;
|
||||
pub mod text;
|
||||
pub mod title;
|
||||
}
|
||||
mod logging;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
logging::setup("alert-me");
|
||||
|
||||
let mut interval = time::interval(Duration::from_secs(5));
|
||||
|
||||
loop {
|
||||
interval.tick().await;
|
||||
let resp = reqwest::get("https://www.alert.swiss/content/alertswiss-internet/en/home/_jcr_content/polyalert.alertswiss_alerts.actual.json")
|
||||
.await
|
||||
.unwrap()
|
||||
.json::<Alerts>()
|
||||
.await.unwrap();
|
||||
debug!("{resp:#?}");
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user