Compare commits

...

41 Commits
v0.2.5 ... main

Author SHA1 Message Date
Paul van Tilburg 88c59cdb1f
Bump the version to 0.2.11
Check, lint and test using Cargo / Check, lint and test (push) Successful in 4m18s Details
Release / Release (push) Successful in 1m3s Details
Release / Release Rust crate (push) Successful in 3m1s Details
Release / Release Debian package (push) Successful in 5m12s Details
2024-02-27 16:07:22 +01:00
Paul van Tilburg cad766b520
Update the changelog 2024-02-27 16:07:19 +01:00
Paul van Tilburg e62699c102
Tweak/fix tests; reduce required accuracy for geocoded coordinates
Also somebody seems to have slightly moved Eindhoven.
2024-02-27 16:06:56 +01:00
Paul van Tilburg f32f67dbf4
Fix clippy issue 2024-02-27 16:00:57 +01:00
Paul van Tilburg d1e43a7aa7
Cargo update; fixes several security advisories
Fixes RUSTSEC-2024-0003 and RUSTSEC-2023-0072.
2024-02-27 15:59:44 +01:00
Paul van Tilburg c2450267e0
Bump the version to 0.2.10
Check, lint and test using Cargo / Check, lint and test (push) Successful in 5m42s Details
Release / Release (push) Successful in 1m35s Details
Release / Release Rust crate (push) Successful in 4m10s Details
Release / Release Debian package (push) Successful in 6m3s Details
2023-11-03 10:41:56 +01:00
Paul van Tilburg 087ecf00f1
Update the changelog 2023-11-03 10:40:43 +01:00
Paul van Tilburg f8ea25c516
Bump the dependency on cached to 0.46.0 2023-11-03 10:39:49 +01:00
Paul van Tilburg f830d34464
Cargo update; fixes RUSTSEC-2020-0071 and RUSTSEC-2023-0044
Fix the tests for small changes in Rocket 0.5-rc.4.
Also fix the usage of a deprecate method.
2023-11-03 10:39:47 +01:00
Paul van Tilburg ff10cc19e8
Correct Debian package file pattern
Check, lint and test using Cargo / Check, lint and test (push) Successful in 5m34s Details
2023-08-25 21:23:11 +02:00
Paul van Tilburg 1211fea46a
Bump the version to 0.2.9
Check, lint and test using Cargo / Check, lint and test (push) Successful in 6m10s Details
Release / Release (push) Successful in 1m47s Details
Release / Release Rust crate (push) Successful in 4m28s Details
Release / Release Debian package (push) Failing after 6m22s Details
2023-08-25 20:48:46 +02:00
Paul van Tilburg 182521aab7
Update the changelog 2023-08-25 20:48:17 +02:00
Paul van Tilburg dadf5d3147
Fix clippy issue
Check, lint and test using Cargo / Check, lint and test (push) Successful in 6m9s Details
2023-08-25 20:24:19 +02:00
Paul van Tilburg 4b506541f3
Build and release a Debian package in a separate job
Check, lint and test using Cargo / Check, lint and test (push) Failing after 3m34s Details
Release it to the package repository instead of attaching to the release.
Also add the relevant part of the changelog as release notes to the
release and fix some schema-related issues.
2023-08-25 20:15:39 +02:00
Paul van Tilburg 47e28a7098
Cargo update 2023-08-25 20:06:56 +02:00
Paul van Tilburg 07e0701106
Bump the version to 0.2.8
Check, lint and test using Cargo / Check, lint and test (push) Successful in 12m45s Details
Release / Release (push) Successful in 12m16s Details
Release / Release crate (push) Successful in 10m0s Details
2023-06-04 12:13:46 +02:00
Paul van Tilburg 91d5500c86
Update the changelog 2023-06-04 12:13:19 +02:00
Paul van Tilburg 9b3c11ee76
Cargo update 2023-06-04 12:12:54 +02:00
Paul van Tilburg 27e1ac726c
Bump dependency on cached to 0.44.0 2023-06-04 12:12:54 +02:00
Paul van Tilburg 3047cf74c2
No longer configure using a sparse Cargo index for crates.io
This is the default since Rust 1.70.
2023-06-04 12:02:35 +02:00
Paul van Tilburg 44474aa545
Tweak README
Check, lint and test using Cargo / Check, lint and test (push) Successful in 5m44s Details
2023-05-29 16:38:42 +02:00
Paul van Tilburg 50b0e94839
Properly attribute the PAQI metric
Check, lint and test using Cargo / Check, lint and test (push) Successful in 5m45s Details
2023-05-29 16:37:16 +02:00
Paul van Tilburg 1010311403
Don't provide the map for the PAQI metric (it is pollen only) 2023-05-29 16:36:02 +02:00
Paul van Tilburg d16699636b Merge pull request 'Print the version on lift off and add version endpoint' (#30) from 29-print-version-add-endpoint into main
Check, lint and test using Cargo / Check, lint and test (push) Successful in 5m52s Details
Reviewed-on: #30
2023-05-29 16:14:56 +02:00
Paul van Tilburg 38fb28c248 Add a /version API endpoint
Check, lint and test using Cargo / Check, lint and test (pull_request) Successful in 6m5s Details
Check, lint and test using Cargo / Check, lint and test (push) Has been cancelled Details
* Introduce the `VersionInfo` struct, build from the vergen environment
  variables
* Add the `version` handler to construct and return the version info
* Update the README
2023-05-29 15:48:36 +02:00
Paul van Tilburg 7c2b012e95 Print the version on lift off 2023-05-29 15:48:36 +02:00
Paul van Tilburg ab6001f072 Use the vergen crate to generate version information
* Add depend on the `vergen` crate (only use the `build`, `git` and
  `gitcl` features)
* Add the build script `build.rs` to setup the environment variables
  from the build system
2023-05-29 15:48:36 +02:00
Paul van Tilburg 9742331f6d
Annote the map key colors in the comments
Check, lint and test using Cargo / Check, lint and test (push) Successful in 5m42s Details
2023-05-26 20:44:24 +02:00
Paul van Tilburg 9bb9d248a8
Bump the version to 0.2.7
Check, lint and test using Cargo / Check, lint and test (push) Successful in 5m39s Details
Release / Release (push) Successful in 7m29s Details
Release / Release crate (push) Successful in 4m8s Details
2023-05-26 20:17:31 +02:00
Paul van Tilburg 37788fac1c
Update the changelog
Also add missing release dates!
2023-05-26 20:16:24 +02:00
Paul van Tilburg 112875e7ac
Use the personal Cargo token
Use this instead of the (missing) repository's secret.
2023-05-26 20:05:52 +02:00
Paul van Tilburg 1c71ca79ef
Switch back to the original Buienradar color scheme (refs: #27)
Check, lint and test using Cargo / Check, lint and test (push) Successful in 6m29s Details
This reverts commit a52313ffb7.
2023-05-26 19:43:37 +02:00
Paul van Tilburg afca20c96f
Bump the version to 0.2.6
Check, lint and test using Cargo / Check, lint and test (push) Successful in 5m35s Details
Release / Release (push) Successful in 8m17s Details
Release / Release crate (push) Failing after 4m12s Details
2023-05-24 22:17:59 +02:00
Paul van Tilburg 2d34eee49a
Update the changelog 2023-05-24 22:17:31 +02:00
Paul van Tilburg a52313ffb7
Switch to new Buienradar color scheme (closes: #27)
Check, lint and test using Cargo / Check, lint and test (push) Successful in 6m13s Details
2023-05-24 22:13:13 +02:00
Admar Schoonen f39a3a33ee
Set sampling area to 31x31 (closes: #26)
Check, lint and test using Cargo / Check, lint and test (push) Successful in 6m16s Details
2023-05-24 19:20:24 +02:00
Paul van Tilburg a59b4eefe1
Improve error description/comment 2023-05-24 19:16:04 +02:00
Paul van Tilburg 1aad3e2eb6
Nomatim seems to geocode Eindhoven differently now
Check, lint and test using Cargo / Check, lint and test (push) Successful in 5m32s Details
2023-05-22 20:50:46 +02:00
Paul van Tilburg 929508a9cc
Add a full release workflow
Check, lint and test using Cargo / Check, lint and test (push) Failing after 5m32s Details
2023-05-22 20:09:45 +02:00
Paul van Tilburg 23e4f731a0
Tweak step name 2023-05-22 20:08:36 +02:00
Paul van Tilburg d84440304a
Simplify Gitea Actions check, lint and test workflow
Check, lint and test using Cargo / Check, lint and test (push) Successful in 6m20s Details
2023-04-25 16:38:59 +02:00
12 changed files with 1150 additions and 791 deletions

View File

@ -1,82 +0,0 @@
name: "Check, Test and Lint Using Cargo"
on:
- push
- pull_request
- workflow_dispatch
jobs:
check:
name: Check
runs-on: debian-latest
steps:
- name: Checkout sources
uses: actions/checkout@v3
- name: Install stable toolchain
uses: https://github.com/actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
override: true
- name: Use sparse Cargo index for crates.io
run: echo -e '[registries.crates-io]\nprotocol = "sparse"' >> /root/.cargo/config.toml
- name: Run cargo check
uses: https://github.com/actions-rs/cargo@v1
with:
command: check
test:
name: Test Suite
runs-on: debian-latest
steps:
- name: Checkout sources
uses: actions/checkout@v3
- name: Install stable toolchain
uses: https://github.com/actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
override: true
- name: Use sparse Cargo index for crates.io
run: echo -e '[registries.crates-io]\nprotocol = "sparse"' >> /root/.cargo/config.toml
- name: Run cargo test
uses: https://github.com/actions-rs/cargo@v1
with:
command: test
args: --all-features
lints:
name: Lints
runs-on: debian-latest
steps:
- name: Checkout sources
uses: actions/checkout@v3
- name: Install stable toolchain
uses: https://github.com/actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
override: true
components: rustfmt, clippy
- name: Use sparse Cargo index for crates.io
run: echo -e '[registries.crates-io]\nprotocol = "sparse"' >> /root/.cargo/config.toml
- name: Run cargo fmt
uses: https://github.com/actions-rs/cargo@v1
with:
command: fmt
args: --all -- --check
- name: Run cargo clippy
uses: https://github.com/actions-rs/cargo@v1
with:
command: clippy
args: -- -D warnings

View File

@ -0,0 +1,45 @@
name: "Check, lint and test using Cargo"
on:
- pull_request
- push
- workflow_dispatch
jobs:
check_lint:
name: Check, lint and test
runs-on: debian-latest
steps:
- name: Checkout sources
uses: actions/checkout@v3
- name: Install Rust stable toolchain
uses: https://github.com/actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
override: true
components: rustfmt, clippy
- name: Run cargo check
uses: https://github.com/actions-rs/cargo@v1
with:
command: check
- name: Run cargo clippy
uses: https://github.com/actions-rs/cargo@v1
with:
command: clippy
args: -- -D warnings
- name: Run cargo fmt
uses: https://github.com/actions-rs/cargo@v1
with:
command: fmt
args: --all -- --check
- name: Run cargo test
uses: https://github.com/actions-rs/cargo@v1
with:
command: test
args: --all-features

View File

@ -0,0 +1,112 @@
name: "Release"
on:
push:
tags:
- "v*"
jobs:
release:
name: "Release"
runs-on: debian-latest
steps:
- name: Checkout sources
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Determine the version of the release
run: |
VERSION=${GITHUB_REF_NAME#v}
echo "Releasing version: $VERSION"
echo "VERSION=$VERSION" >> $GITHUB_ENV
- name: Get the release notes from the changelog
run: |
EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64)
RELEASE_NOTES=$(sed -n -e "/^## \[$VERSION\]/,/^## \[/{//"'!'"p;}" CHANGELOG.md | sed -e '1d;$d')
echo "Release notes:"
echo
echo "$RELEASE_NOTES"
echo "RELEASE_NOTES<<$EOF" >> "$GITHUB_ENV"
echo "$RELEASE_NOTES" >> "$GITHUB_ENV"
echo "$EOF" >> "$GITHUB_ENV"
- name: Install Go
uses: actions/setup-go@v4
with:
go-version: '>=1.20.1'
- name: Release to Gitea
uses: actions/release-action@main
with:
# This is available by default.
api_key: '${{ secrets.RELEASE_TOKEN }}'
files: FIXME
title: 'Release ${{ env.VERSION }}'
body: '${{ env.RELEASE_NOTES }}'
release-crate:
name: "Release Rust crate"
runs-on: debian-latest
steps:
- name: Checkout sources
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Install Rust stable toolchain
uses: https://github.com/actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
override: true
- name: Use sparse Cargo index for crates.io
run: echo -e '[registries.crates-io]\nprotocol = "sparse"' >> /root/.cargo/config.toml
- name: Register the Gitea crate registry with Cargo
run: echo -e '[registries.luon]\nindex = "https://git.luon.net/paul/_cargo-index.git"' >> /root/.cargo/config.toml
- name: Run cargo publish
uses: https://github.com/actions-rs/cargo@v1
env:
# This needs to be provided for the repository; no login necessary as a result.
CARGO_REGISTRIES_LUON_TOKEN: '${{ secrets.CARGO_TOKEN }}'
with:
command: publish
args: --registry luon
release-deb:
name: "Release Debian package"
runs-on: debian-latest
steps:
- name: Checkout sources
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Install Rust stable toolchain
uses: https://github.com/actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
override: true
- name: Install cargo-deb
uses: https://github.com/brndnmtthws/rust-action-cargo-binstall@v1
with:
packages: cargo-deb
- name: Run cargo-deb
uses: https://github.com/actions-rs/cargo@v1
with:
command: deb
- name: Publish Debian package
env:
DEB_REPO_TOKEN: '${{ secrets.DEB_REPO_TOKEN }}'
run: |
curl --config <(printf "user=%s:%s" paul "${DEB_REPO_TOKEN}") \
--upload-file target/debian/sinoptik*.deb \
https://git.luon.net/api/packages/paul/debian/pool/bookworm/main/upload

View File

@ -7,7 +7,91 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
## [0.2.5]
## [0.2.11] - 2024-02-27
### Security
* Updated dependencies, fixes security advisories:
* [RUSTSEC-2024-0003](https://rustsec.org/advisories/RUSTSEC-2024-0003)
* [RUSTSEC-2023-0072](https://rustsec.org/advisories/RUSTSEC-2024-0072)
### Fixed
* Fix clippy issue
* Tweak/fix tests; reduce required accuracy for geocoded coordinates
## [0.2.10] - 2023-11-03
### Security
* Update dependencies
([RUSTSEC-2020-0071](https://rustsec.org/advisories/RUSTSEC-2020-0071.html),
[RUSTSEC-2023-0044](https://rustsec.org/advisories/RUSTSEC-2023-0044.html))
### Changed
* Switch to Rocket 0.5 RC4
* Update dependency on `cached`
### Fixed
* Fix clippy issues
## [0.2.9] - 2023-08-25
### Changed
* Update release Gitea Actions workflow; add seperate job to release Debian
package to the new repository
### Security
* Update dependencies ([RUSTSEC-2023-0044](https://rustsec.org/advisories/RUSTSEC-2023-0044))
## [0.2.8] - 2023-06-05
### Added
* Print the version on lift off (#30)
* Add a `/version` endpoint to the API (#30)
### Changed
* Update dependency on `cached`
### Fixed
* Properly attribute the PAQI metric in its description(s)
### Removed
* No longer provide a map for the PAQI metric; the map used is only for pollen
## [0.2.7] - 2023-05-26
### Fixed
* Switch back to the original Buienradar color scheme/maps key (#27)
* Fix the token used to publish the crate to the Cargo package index
## [0.2.6] - 2023-05-24
### Added
* Add full release Gitea Actions workflow
### Changed
* Simplify Gitea Actions check, lint and test workflow
* Improve no known map colors found error description
### Fixed
* Update coordinates of Eindhoven in tests (Nomatim changed its geocoding)
* Increase sampling area to 31×31 pixels (#26)
* Switch to new Buienradar color scheme/maps key (#27)
## [0.2.5] - 2023-03-24
### Added
@ -88,7 +172,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
Initial release.
[Unreleased]: https://git.luon.net/paul/sinoptik/compare/v0.2.5...HEAD
[Unreleased]: https://git.luon.net/paul/sinoptik/compare/v0.2.11...HEAD
[0.2.11]: https://git.luon.net/paul/sinoptik/compare/v0.2.10...v0.2.11
[0.2.10]: https://git.luon.net/paul/sinoptik/compare/v0.2.9...v0.2.10
[0.2.9]: https://git.luon.net/paul/sinoptik/compare/v0.2.8...v0.2.9
[0.2.8]: https://git.luon.net/paul/sinoptik/compare/v0.2.7...v0.2.8
[0.2.7]: https://git.luon.net/paul/sinoptik/compare/v0.2.6...v0.2.7
[0.2.6]: https://git.luon.net/paul/sinoptik/compare/v0.2.5...v0.2.6
[0.2.5]: https://git.luon.net/paul/sinoptik/compare/v0.2.4...v0.2.5
[0.2.4]: https://git.luon.net/paul/sinoptik/compare/v0.2.3...v0.2.4
[0.2.3]: https://git.luon.net/paul/sinoptik/compare/v0.2.2...v0.2.3

1446
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
[package]
name = "sinoptik"
version = "0.2.5"
version = "0.2.11"
authors = [
"Admar Schoonen <admar@luon.net",
"Paul van Tilburg <paul@luon.net>"
@ -12,7 +12,7 @@ repository = "https://git.luon.net/paul/sinoptik"
license = "MIT"
[dependencies]
cached = { version = "0.42.0", features = ["async"] }
cached = { version = "0.46.0", features = ["async"] }
chrono = "0.4.19"
chrono-tz = "0.8.1"
csv = "1.1.6"
@ -22,6 +22,9 @@ reqwest = { version = "0.11.9", features = ["json"] }
rocket = { version = "0.5.0-rc.3", features = ["json"] }
thiserror = "1.0.31"
[build-dependencies]
vergen = { version = "8.2.1", default-features = false, features = ["build", "git", "gitcl"] }
[dev-dependencies]
assert_float_eq = "1.1.3"
assert_matches = "1.5.0"
@ -42,7 +45,8 @@ Currently supported metrics are:
* O concentration (per hour, from Luchtmeetnet)
* Particulate matter (PM10) concentration (per hour, from Luchtmeetnet)
* Pollen (per hour, from Buienradar)
* Pollen/air quality index (per hour, from Buienradar)
* Pollen/air quality index (per hour, combined from Buienradar and
Luchtmeetnet)
* Precipitation (per 5 minutes, from Buienradar)
* UV index (per day, from Buienradar)

View File

@ -11,7 +11,8 @@ Currently supported metrics are:
* O₃ concentration (per hour, from [Luchtmeetnet])
* Particulate matter (PM10) concentration (per hour, from [Luchtmeetnet])
* Pollen (per hour, from [Buienradar])
* Pollen/air quality index (per hour, from [Buienradar])
* Pollen/air quality index (per hour, combined from [Buienradar] and
[Luchtmeetnet])
* Precipitation (per 5 minutes, from [Buienradar])
* UV index (per day, from [Buienradar])
@ -216,6 +217,31 @@ an address fails or if the position is out of bounds of the map, nothing is
returned (HTTP 404). If the maps cannot/have not been downloaded or cached yet,
a service unavailable error is returned (HTTP 503).
## Version API endpoint
The `/version` API endpoint provides information of the current version and
build of the service. This can be used to check if it needs to be updated.
Again, there is no path and no query parameters, just:
```http
GET /version
```
### Version responses
The response uses the JSON format and typically looks like this:
```json
{
"version": "0.2.7",
"timestamp": "2023-05-29T13:34:34.701323159Z",
"git_sha": "bb5962d",
"git_timestamp": "2023-05-29T15:32:17.000000000+02:00"
}
```
(Build and git information in example output may be out of date.)
## License
Sinoptik is licensed under the MIT license (see the `LICENSE` file or

9
build.rs Normal file
View File

@ -0,0 +1,9 @@
use std::error::Error;
use vergen::EmitBuilder;
fn main() -> Result<(), Box<dyn Error>> {
// Generate the `cargo:` instructions to fill the appropriate environment variables.
EmitBuilder::builder().all_build().all_git().emit()?;
Ok(())
}

View File

@ -21,6 +21,7 @@ use rocket::fairing::AdHoc;
use rocket::http::Status;
use rocket::response::Responder;
use rocket::serde::json::Json;
use rocket::serde::Serialize;
use rocket::{get, routes, Build, Request, Rocket, State};
use self::forecast::{forecast, Forecast, Metric};
@ -84,13 +85,41 @@ impl<'r, 'o: 'r> Responder<'r, 'o> for Error {
}
}
/// Result type that defaults to [`Error`] as the default error type.
pub(crate) type Result<T, E = Error> = std::result::Result<T, E>;
#[derive(Responder)]
#[response(content_type = "image/png")]
struct PngImageData(Vec<u8>);
/// Result type that defaults to [`Error`] as the default error type.
pub(crate) type Result<T, E = Error> = std::result::Result<T, E>;
/// The version information as JSON response.
#[derive(Debug, Serialize)]
#[serde(crate = "rocket::serde")]
struct VersionInfo {
/// The version of the build.
version: String,
/// The timestamp of the build.
timestamp: String,
/// The (most recent) git SHA used for the build.
git_sha: String,
/// The timestamp of the last git commit used for the build.
git_timestamp: String,
}
impl VersionInfo {
/// Retrieves the version information from the environment variables.
fn new() -> Self {
Self {
version: String::from(env!("CARGO_PKG_VERSION")),
timestamp: String::from(env!("VERGEN_BUILD_TIMESTAMP")),
git_sha: String::from(&env!("VERGEN_GIT_SHA")[0..7]),
git_timestamp: String::from(env!("VERGEN_GIT_COMMIT_TIMESTAMP")),
}
}
}
/// Handler for retrieving the forecast for an address.
#[get("/forecast?<address>&<metrics>")]
async fn forecast_address(
@ -150,6 +179,12 @@ async fn map_geo(
image_data.map(PngImageData)
}
/// Returns the version information.
#[get("/version", format = "application/json")]
async fn version() -> Result<Json<VersionInfo>> {
Ok(Json(VersionInfo::new()))
}
/// Sets up Rocket.
fn rocket(maps_handle: MapsHandle) -> Rocket<Build> {
let maps_refresher = maps::run(Arc::clone(&maps_handle));
@ -157,7 +192,13 @@ fn rocket(maps_handle: MapsHandle) -> Rocket<Build> {
rocket::build()
.mount(
"/",
routes![forecast_address, forecast_geo, map_address, map_geo],
routes![
forecast_address,
forecast_geo,
map_address,
map_geo,
version
],
)
.manage(maps_handle)
.attach(AdHoc::on_liftoff("Maps refresher", |_| {
@ -166,6 +207,15 @@ fn rocket(maps_handle: MapsHandle) -> Rocket<Build> {
let _refresher = rocket::tokio::spawn(maps_refresher);
})
}))
.attach(AdHoc::on_liftoff("Version", |_| {
Box::pin(async move {
let name = env!("CARGO_PKG_NAME");
let version = env!("CARGO_PKG_VERSION");
let git_sha = &env!("VERGEN_GIT_SHA")[0..7];
println!("🌁 Started {name} v{version} (git @{git_sha})");
})
}))
}
/// Sets up Rocket and the maps cache refresher task.
@ -213,8 +263,8 @@ mod tests {
let response = client.get("/forecast?address=eindhoven").dispatch();
assert_eq!(response.status(), Status::Ok);
let json = response.into_json::<JsonValue>().expect("Not valid JSON");
assert_float_absolute_eq!(json["lat"].as_f64().unwrap(), 51.44855695, 1e-8);
assert_float_absolute_eq!(json["lon"].as_f64().unwrap(), 5.45012252, 1e-8);
assert_float_absolute_eq!(json["lat"].as_f64().unwrap(), 51.448557, 1e-5);
assert_float_absolute_eq!(json["lon"].as_f64().unwrap(), 5.450123, 1e-5);
assert_matches!(json["time"], JsonValue::Number(_));
assert_matches!(json.get("AQI"), None);
assert_matches!(json.get("NO2"), None);
@ -231,8 +281,8 @@ mod tests {
.dispatch();
assert_eq!(response.status(), Status::Ok);
let json = response.into_json::<JsonValue>().expect("Not valid JSON");
assert_float_absolute_eq!(json["lat"].as_f64().unwrap(), 51.44855695, 1e-8);
assert_float_absolute_eq!(json["lon"].as_f64().unwrap(), 5.45012252, 1e-8);
assert_float_absolute_eq!(json["lat"].as_f64().unwrap(), 51.448557, 1e-5);
assert_float_absolute_eq!(json["lon"].as_f64().unwrap(), 5.450123, 1e-5);
assert_matches!(json["time"], JsonValue::Number(_));
assert_matches!(json.get("AQI"), Some(JsonValue::Array(_)));
assert_matches!(json.get("NO2"), Some(JsonValue::Array(_)));
@ -316,7 +366,7 @@ mod tests {
// No metric selected, don't know which map to show?
let response = client.get("/map?address=eindhoven").dispatch();
assert_eq!(response.status(), Status::NotFound);
assert_eq!(response.status(), Status::UnprocessableEntity);
}
#[test]
@ -325,10 +375,6 @@ mod tests {
let maps_handle_clone = Arc::clone(&maps_handle);
let client = Client::tracked(rocket(maps_handle)).expect("Not a valid Rocket instance");
// No metric passed, don't know which map to show?
let response = client.get("/map?lat=51.4&lon=5.5").dispatch();
assert_eq!(response.status(), Status::NotFound);
// No maps available yet.
let response = client.get("/map?lat=51.4&lon=5.5&metric=pollen").dispatch();
assert_eq!(response.status(), Status::ServiceUnavailable);
@ -345,8 +391,12 @@ mod tests {
assert_eq!(response.status(), Status::Ok);
assert_eq!(response.content_type(), Some(ContentType::PNG));
// ... but not if it is out of bounds.
let response = client.get("/map?lat=0.0&lon=0.0&metric=pollen").dispatch();
assert_eq!(response.status(), Status::NotFound);
// No metric passed, don't know which map to show?
let response = client.get("/map?lat=51.4&lon=5.5").dispatch();
assert_eq!(response.status(), Status::NotFound);
assert_eq!(response.status(), Status::UnprocessableEntity);
}
}

View File

@ -8,7 +8,7 @@ use std::f64::consts::PI;
use std::sync::{Arc, Mutex};
use chrono::serde::ts_seconds;
use chrono::{DateTime, Duration, NaiveDateTime, Utc};
use chrono::{DateTime, Duration, NaiveDateTime, TimeZone, Utc};
use image::{
DynamicImage, GenericImage, GenericImageView, ImageError, ImageFormat, Pixel, Rgb, Rgba,
};
@ -47,8 +47,8 @@ pub(crate) enum Error {
#[error("Failed to join a task: {0}")]
Join(#[from] rocket::tokio::task::JoinError),
/// Found no known (map key) colors in samples.
#[error("Found not known colors in samples")]
/// Did not find any known (map key) colors in samples.
#[error("Did not find any known colors in samples")]
NoKnownColorsInSamples,
/// No maps found (yet).
@ -78,22 +78,22 @@ type MapKeyHistogram = HashMap<Rgb<u8>, u32>;
/// Note that the actual score starts from 1, not 0 as per this array.
#[rustfmt::skip]
const MAP_KEY: [[u8; 3]; 10] = [
[0x49, 0xDA, 0x21],
[0x30, 0xD2, 0x00],
[0xFF, 0xF8, 0x8B],
[0xFF, 0xF6, 0x42],
[0xFD, 0xBB, 0x31],
[0xFD, 0x8E, 0x24],
[0xFC, 0x10, 0x3E],
[0x97, 0x0A, 0x33],
[0xA6, 0x6D, 0xBC],
[0xB3, 0x30, 0xA1],
[0x49, 0xDA, 0x21], // #49DA21
[0x30, 0xD2, 0x00], // #30D200
[0xFF, 0xF8, 0x8B], // #FFF88B
[0xFF, 0xF6, 0x42], // #FFF642
[0xFD, 0xBB, 0x31], // #FDBB31
[0xFD, 0x8E, 0x24], // #FD8E24
[0xFC, 0x10, 0x3E], // #FC103E
[0x97, 0x0A, 0x33], // #970A33
[0xA6, 0x6D, 0xBC], // #A66DBC
[0xB3, 0x30, 0xA1], // #B330A1
];
/// The Buienradar map sample size.
///
/// Determiess the number of pixels in width/height that is samples around the sampling coordinate.
const MAP_SAMPLE_SIZE: [u32; 2] = [11, 11];
/// Determines the number of pixels in width/height that is sampled around the sampling coordinate.
const MAP_SAMPLE_SIZE: [u32; 2] = [31, 31];
/// The interval between map refreshes (in seconds).
const REFRESH_INTERVAL: tokio::time::Duration = tokio::time::Duration::from_secs(60);
@ -449,7 +449,7 @@ async fn retrieve_image(url: Url) -> Result<RetrievedMaps> {
.ok_or_else(|| Error::InvalidImagePath(path.to_owned()))?;
let timestamp = NaiveDateTime::parse_from_str(timestamp_str, "%Y%m%d%H%M")?;
DateTime::<Utc>::from_utc(timestamp, Utc)
Utc.from_utc_datetime(&timestamp)
};
let bytes = response.bytes().await?;
@ -567,7 +567,6 @@ pub(crate) async fn mark_map(
tokio::task::spawn_blocking(move || {
let maps = maps_handle.lock().expect("Maps handle lock was poisoned");
let image = match metric {
Metric::PAQI => maps.pollen_mark(position),
Metric::Pollen => maps.pollen_mark(position),
Metric::UVI => maps.uvi_mark(position),
_ => return Err(crate::Error::UnsupportedMetric(metric)),

View File

@ -109,7 +109,7 @@ pub(crate) async fn resolve_address(address: String) -> Result<Position> {
let points: Vec<Point<f64>> = osm.forward(&address)?;
points
.get(0)
.first()
.ok_or(Error::NoPositionFound)
.map(Position::from)
})

View File

@ -108,7 +108,7 @@ fn merge(
// value.
let items = pollen_samples
.into_iter()
.zip(aqi_items.into_iter())
.zip(aqi_items)
.map(|(pollen_sample, aqi_item)| {
let time = pollen_sample.time;
let value = (pollen_sample.score as f32).max(aqi_item.value);