Compare commits

...

20 Commits
v0.2.9 ... main

Author SHA1 Message Date
Paul van Tilburg ba1b27fd66
Bump the version to 0.2.12
Check, lint and test using Cargo / Check, lint and test (push) Failing after 9m37s Details
Release / Release Rust crate (push) Successful in 4m37s Details
Release / Release Debian package (push) Has been cancelled Details
Release / Release (push) Has been cancelled Details
2024-05-09 12:29:47 +02:00
Paul van Tilburg 94c29cad71
Update the changelog 2024-05-09 12:28:47 +02:00
Paul van Tilburg 8e5a1ef305
Bump dependency on reqwest to 0.12.4 2024-05-09 12:25:46 +02:00
Paul van Tilburg 6c39cac26e
Bump dependency on image to 0.25.1
Also only enable the `png` feature and update a deprecated output format
definition.
2024-05-09 12:24:44 +02:00
Paul van Tilburg f1ee03d96c
Bump dependency on chrono-tz to 0.9.0 2024-05-09 12:24:41 +02:00
Paul van Tilburg 98f60cba89
Bump dependency on cached to 0.51.3 2024-05-09 12:24:39 +02:00
Paul van Tilburg 45ee951601
Cargo update; fixes RUSTSEC-2024-0019 and RUSTSEC-2024-0332 2024-05-09 12:12:58 +02:00
Paul van Tilburg f4e7c82b53
Fix test; remove maps load/maps test race
Check, lint and test using Cargo / Check, lint and test (push) Successful in 4m39s Details
Introduce the Rocket core that can be used to test the API without
background processes interfering with the test setup.
2024-05-09 12:04:00 +02:00
Paul van Tilburg a29d7f3535
Fix test; reduce require accurancy for coordinates
There are currently two entries for the city of Eindhoven in the
Nomanitim geoecoding database. Reduced acccuracy still is enough to
check that the API works properly.
2024-05-09 12:03:48 +02:00
Paul van Tilburg c86f001fee
Fix clippy issues
Check, lint and test using Cargo / Check, lint and test (push) Failing after 5m23s Details
2024-05-03 14:34:46 +02:00
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
7 changed files with 872 additions and 733 deletions

View File

@ -108,5 +108,5 @@ jobs:
DEB_REPO_TOKEN: '${{ secrets.DEB_REPO_TOKEN }}'
run: |
curl --config <(printf "user=%s:%s" paul "${DEB_REPO_TOKEN}") \
--upload-file target/debian/sandbox*.deb \
--upload-file target/debian/sinoptik*.deb \
https://git.luon.net/api/packages/paul/debian/pool/bookworm/main/upload

View File

@ -7,6 +7,53 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
## [0.2.12] - 2024-05-09
### Security
* Updated dependencies, fixes security advisiories:
* [RUSTSEC-2024-0019](https://rustsec.org/advisories/RUSTSEC-2024-0019)
* [RUSTSEC-2024-0332](https://rustsec.org/advisories/RUSTSEC-2024-0332)
### Changed
* Update dependency on `cached`, `chrono-tz`, `image` and `reqwest`
### Fixed
* Fix tests; reduce required accuracy for geocoded coordinates again and
don't run background map updates during tests
## [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
@ -142,7 +189,10 @@ 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.9...HEAD
[Unreleased]: https://git.luon.net/paul/sinoptik/compare/v0.2.12...HEAD
[0.2.12]: https://git.luon.net/paul/sinoptik/compare/v0.2.11...v0.2.12
[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

1482
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.9"
version = "0.2.12"
authors = [
"Admar Schoonen <admar@luon.net",
"Paul van Tilburg <paul@luon.net>"
@ -12,13 +12,13 @@ repository = "https://git.luon.net/paul/sinoptik"
license = "MIT"
[dependencies]
cached = { version = "0.44.0", features = ["async"] }
cached = { version = "0.51.3", features = ["async"] }
chrono = "0.4.19"
chrono-tz = "0.8.1"
chrono-tz = "0.9.0"
csv = "1.1.6"
geocoding = "0.4.0"
image = "0.24.1"
reqwest = { version = "0.11.9", features = ["json"] }
image = { version = "0.25.1", default-features = false, features = ["png"]}
reqwest = { version = "0.12.4", features = ["json"] }
rocket = { version = "0.5.0-rc.3", features = ["json"] }
thiserror = "1.0.31"

View File

@ -54,11 +54,11 @@ pub(crate) enum Error {
/// Failed to merge AQI & pollen items.
#[error("Failed to merge AQI & pollen items: {0}")]
Merge(#[from] self::providers::combined::MergeError),
Merge(#[from] providers::combined::MergeError),
/// Failed to retrieve or sample the maps.
#[error("Failed to retrieve or sample the maps: {0}")]
Maps(#[from] self::maps::Error),
Maps(#[from] maps::Error),
/// No geocoded position could be found.
#[error("No geocoded position could be found")]
@ -185,10 +185,8 @@ 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));
/// Sets up Rocket without fairings.
fn rocket_core(maps_handle: MapsHandle) -> Rocket<Build> {
rocket::build()
.mount(
"/",
@ -201,6 +199,14 @@ fn rocket(maps_handle: MapsHandle) -> Rocket<Build> {
],
)
.manage(maps_handle)
}
/// Sets up Rocket.
fn rocket(maps_handle: MapsHandle) -> Rocket<Build> {
let rocket = rocket_core(Arc::clone(&maps_handle));
let maps_refresher = maps::run(maps_handle);
rocket
.attach(AdHoc::on_liftoff("Maps refresher", |_| {
Box::pin(async move {
// We don't care about the join handle nor error results?
@ -263,8 +269,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.4392648, 1e-8);
assert_float_absolute_eq!(json["lon"].as_f64().unwrap(), 5.478633, 1e-8);
assert_float_absolute_eq!(json["lat"].as_f64().unwrap(), 51.448557, 1e-1);
assert_float_absolute_eq!(json["lon"].as_f64().unwrap(), 5.450123, 1e-1);
assert_matches!(json["time"], JsonValue::Number(_));
assert_matches!(json.get("AQI"), None);
assert_matches!(json.get("NO2"), None);
@ -281,8 +287,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.4392648, 1e-8);
assert_float_absolute_eq!(json["lon"].as_f64().unwrap(), 5.478633, 1e-8);
assert_float_absolute_eq!(json["lat"].as_f64().unwrap(), 51.448557, 1e-1);
assert_float_absolute_eq!(json["lon"].as_f64().unwrap(), 5.450123, 1e-1);
assert_matches!(json["time"], JsonValue::Number(_));
assert_matches!(json.get("AQI"), Some(JsonValue::Array(_)));
assert_matches!(json.get("NO2"), Some(JsonValue::Array(_)));
@ -338,7 +344,8 @@ mod tests {
fn map_address() {
let maps_handle = Arc::new(Mutex::new(Maps::new()));
let maps_handle_clone = Arc::clone(&maps_handle);
let client = Client::tracked(rocket(maps_handle)).expect("Not a valid Rocket instance");
let client =
Client::tracked(rocket_core(maps_handle)).expect("Not a valid Rocket instance");
// No maps available yet.
let response = client
@ -366,18 +373,15 @@ 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]
fn map_geo() {
let maps_handle = Arc::new(Mutex::new(Maps::new()));
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);
let client =
Client::tracked(rocket_core(maps_handle)).expect("Not a valid Rocket instance");
// No maps available yet.
let response = client.get("/map?lat=51.4&lon=5.5&metric=pollen").dispatch();
@ -395,8 +399,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,
};
@ -45,7 +45,7 @@ pub(crate) enum Error {
/// Failed to join a task.
#[error("Failed to join a task: {0}")]
Join(#[from] rocket::tokio::task::JoinError),
Join(#[from] tokio::task::JoinError),
/// Did not find any known (map key) colors in samples.
#[error("Did not find any known colors in samples")]
@ -393,7 +393,7 @@ fn sample<I: GenericImageView<Pixel = Rgba<u8>>>(
.expect("Maximum color is always a map key color") as u8;
samples.push(Sample { time, score });
time += chrono::Duration::seconds(interval);
time += Duration::seconds(interval);
offset += width;
}
@ -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?;
@ -575,10 +575,7 @@ pub(crate) async fn mark_map(
// Encode the image as PNG image data.
let mut image_data = Cursor::new(Vec::new());
match image.write_to(
&mut image_data,
image::ImageOutputFormat::from(image::ImageFormat::Png),
) {
match image.write_to(&mut image_data, ImageFormat::Png) {
Ok(()) => Ok(image_data.into_inner()),
Err(err) => Err(crate::Error::from(Error::from(err))),
}

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)
})