Compare commits

...

19 Commits

Author SHA1 Message Date
Paul van Tilburg a289bd9ef0
Bump the version to 0.2.5
Check Details
Lints Details
Test Suite Details
2023-03-24 13:10:22 +01:00
Paul van Tilburg 122f98a92d
Update the changelog 2023-03-24 13:09:53 +01:00
Paul van Tilburg 1426405943
Bump dependencies on cached and chrono-tz 2023-03-24 13:05:42 +01:00
Paul van Tilburg 34be96d187
Update to Rocket 0.5.0-rc.3 2023-03-24 13:04:56 +01:00
Paul van Tilburg bc140a9d1e
Remove unnecessary debug statement
Check Details
Lints Details
Test Suite Details
2023-03-23 16:57:30 +01:00
Paul van Tilburg 39c224eb90
Cargo update; fixes RUSTSEC-2023-0018 2023-03-23 16:56:48 +01:00
Paul van Tilburg b517448fd7
Speed up workflow by using sparce Cargo index for crates.io
Check Details
Lints Details
Test Suite Details
2023-03-21 11:50:00 +01:00
Paul van Tilburg 3de66dbd41
Add Gitea Actions (CI) workflow for cargo
Check Details
Lints Details
Test Suite Details
2023-03-21 11:16:48 +01:00
Paul van Tilburg 6a04fc958f
Fix float comparison in tests 2023-03-21 11:15:32 +01:00
Paul van Tilburg c8b951ab7e
Fix clippy issue 2023-03-21 11:05:03 +01:00
Paul van Tilburg 32ec6b516c
Cargo update
This fixes build issues with the `geo-types` crate versio 0.7.7.
Also replace use of now deprecated functions/methods.
2023-01-31 14:02:46 +01:00
Paul van Tilburg a6301fa678 Fix markdownlint issues 2022-10-23 10:50:05 +02:00
Paul van Tilburg f00537d5f3
Add more lints; fix issues 2022-10-17 20:02:54 +02:00
Paul van Tilburg c8970fa3bb
Cargo update 2022-10-17 19:53:01 +02:00
Paul van Tilburg aee3409f4a Bump dependency on cached to 0.38.0
This fixes the unused `*_prime_cache` compile warnings.
2022-08-12 09:46:17 +02:00
Paul van Tilburg dbdd7bef0f Cargo update 2022-08-12 09:44:15 +02:00
Paul van Tilburg d749233b24 Merge uses 2022-08-12 09:44:08 +02:00
Paul van Tilburg abb6657212
Cargo update 2022-07-17 13:25:22 +02:00
Paul van Tilburg 8b03f2162b
Bump dependency on geocoding to 0.4.0
This finally removes the duplicate dependency tree on older versions of
crates we're already using (chrono, request, etc.).
2022-07-17 13:25:22 +02:00
9 changed files with 922 additions and 1129 deletions

View File

@ -0,0 +1,82 @@
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

@ -7,6 +7,25 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
## [0.2.5]
### Added
* Add Gitea Actions workflow for cargo
### Changed
* Updated dependencies on `cached`, `chrono-tz` and `geocoding`
### Fixed
* Fix float comparison in tests
* Fix clippy issues
### Security
* Update dependencies ([RUSTSEC-2023-0018](https://rustsec.org/advisories/RUSTSEC-2023-0018.html))
## [0.2.4] - 2022-07-05
### Added
@ -69,7 +88,8 @@ 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.4...HEAD
[Unreleased]: https://git.luon.net/paul/sinoptik/compare/v0.2.5...HEAD
[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
[0.2.2]: https://git.luon.net/paul/sinoptik/compare/v0.2.1...v0.2.2

1866
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.4"
version = "0.2.5"
authors = [
"Admar Schoonen <admar@luon.net",
"Paul van Tilburg <paul@luon.net>"
@ -12,14 +12,14 @@ repository = "https://git.luon.net/paul/sinoptik"
license = "MIT"
[dependencies]
cached = { version = "0.34.0", features = ["async"] }
cached = { version = "0.42.0", features = ["async"] }
chrono = "0.4.19"
chrono-tz = "0.6.1"
chrono-tz = "0.8.1"
csv = "1.1.6"
geocoding = "0.3.1"
geocoding = "0.4.0"
image = "0.24.1"
reqwest = { version = "0.11.9", features = ["json"] }
rocket = { version = "0.5.0-rc.2", features = ["json"] }
rocket = { version = "0.5.0-rc.3", features = ["json"] }
thiserror = "1.0.31"
[dev-dependencies]

View File

@ -67,7 +67,6 @@ GET /forecast?address=Stationsplein,Utrecht&metrics[]=all
or directly by using its geocoded position:
```http
GET /forecast?lat=52.0902&lon=5.1114&metrics[]=all
```
@ -75,8 +74,8 @@ GET /forecast?lat=52.0902&lon=5.1114&metrics[]=all
### Metrics
When querying, the metrics need to be selected. It can be one of: `AQI`, `NO2`,
`O3`, `PAQI`, `PM10`, `pollen`, `precipitation` or `UVI`. If you use metric `all`, or
`all` is part of the selected metrics, all metrics will be retrieved.
`O3`, `PAQI`, `PM10`, `pollen`, `precipitation` or `UVI`. If you use metric
`all`, or `all` is part of the selected metrics, all metrics will be retrieved.
Note that the parameter "array" notation as well as the repeated parameter
notation are supported. For example:
@ -86,7 +85,7 @@ GET /forecast?address=Stationsplein,Utrecht&metrics=AQI&metrics=pollen
GET /forecast?address=Stationsplein,Utrecht&metrics=all
```
### Response
### Forecast responses
The response of the API is a JSON object that contains three fixed fields:
@ -160,8 +159,8 @@ selecting the maximum value for each hour:
#### Errors
If geocoding of an address is requested but fails, a not found error is returned (HTTP 404).
with the following body (this will change in the future):
If geocoding of an address is requested but fails, a not found error is
returned (HTTP 404). with the following body (this will change in the future):
```json
{
@ -173,10 +172,10 @@ with the following body (this will change in the future):
}
```
If for any specific metric an error occurs, the list with forecast items will be absent.
However, the `errors` field will contain the error message for each failed metric.
For example, say Buienradar is down and precipitation forecast items can not be
retrieved:
If for any specific metric an error occurs, the list with forecast items will
be absent. However, the `errors` field will contain the error message for each
failed metric. For example, say Buienradar is down and precipitation forecast
items can not be retrieved:
```json
{
@ -210,7 +209,7 @@ or directly by using its geocoded position:
GET /map?lat=52.0902&lon=5.1114&metric=pollen
```
### Response
### Map responses
The response is a PNG image with a crosshair drawn on the map. If geocoding of
an address fails or if the position is out of bounds of the map, nothing is

View File

@ -1,9 +1,17 @@
#![doc = include_str!("../README.md")]
#![warn(
clippy::all,
missing_copy_implementations,
missing_debug_implementations,
rust_2018_idioms,
rustdoc::broken_intra_doc_links
rustdoc::broken_intra_doc_links,
trivial_casts,
trivial_numeric_casts,
renamed_and_removed_lints,
unsafe_code,
unstable_features,
unused_import_braces,
unused_qualifications
)]
#![deny(missing_docs)]
@ -60,7 +68,7 @@ pub(crate) enum Error {
UnsupportedMetric(Metric),
}
impl<'r, 'o: 'r> rocket::response::Responder<'r, 'o> for Error {
impl<'r, 'o: 'r> Responder<'r, 'o> for Error {
fn respond_to(self, _request: &'r Request<'_>) -> rocket::response::Result<'o> {
eprintln!("💥 Encountered error during request: {}", self);
@ -155,7 +163,7 @@ fn rocket(maps_handle: MapsHandle) -> Rocket<Build> {
.attach(AdHoc::on_liftoff("Maps refresher", |_| {
Box::pin(async move {
// We don't care about the join handle nor error results?
let _ = rocket::tokio::spawn(maps_refresher);
let _refresher = rocket::tokio::spawn(maps_refresher);
})
}))
}
@ -205,8 +213,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_f64_near!(json["lat"].as_f64().unwrap(), 51.4392648);
assert_f64_near!(json["lon"].as_f64().unwrap(), 5.478633);
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_matches!(json["time"], JsonValue::Number(_));
assert_matches!(json.get("AQI"), None);
assert_matches!(json.get("NO2"), None);
@ -223,8 +231,8 @@ mod tests {
.dispatch();
assert_eq!(response.status(), Status::Ok);
let json = response.into_json::<JsonValue>().expect("Not valid JSON");
assert_f64_near!(json["lat"].as_f64().unwrap(), 51.4392648);
assert_f64_near!(json["lon"].as_f64().unwrap(), 5.478633);
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_matches!(json["time"], JsonValue::Number(_));
assert_matches!(json.get("AQI"), Some(JsonValue::Array(_)));
assert_matches!(json.get("NO2"), Some(JsonValue::Array(_)));

View File

@ -1,9 +1,17 @@
#![doc = include_str!("../README.md")]
#![warn(
clippy::all,
missing_copy_implementations,
missing_debug_implementations,
rust_2018_idioms,
rustdoc::broken_intra_doc_links
rustdoc::broken_intra_doc_links,
trivial_casts,
trivial_numeric_casts,
renamed_and_removed_lints,
unsafe_code,
unstable_features,
unused_import_braces,
unused_qualifications
)]
#![deny(missing_docs)]

View File

@ -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 = time + chrono::Duration::seconds(interval as i64);
time += chrono::Duration::seconds(interval);
offset += width;
}

View File

@ -4,9 +4,8 @@
//! and <https://www.buienradar.nl/overbuienradar/gratis-weerdata>.
use cached::proc_macro::cached;
use chrono::offset::TimeZone;
use chrono::serde::ts_seconds;
use chrono::{DateTime, Datelike, Duration, NaiveTime, ParseError, Utc};
use chrono::{DateTime, Datelike, Duration, NaiveTime, ParseError, TimeZone, Utc};
use chrono_tz::Europe;
use csv::ReaderBuilder;
use reqwest::Url;
@ -66,10 +65,10 @@ impl TryFrom<Row> for Item {
/// time zone.
fn parse_time(t: &str) -> Result<DateTime<Utc>, ParseError> {
// First, get the current date in the Europe/Amsterdam time zone.
let today = Utc::now().with_timezone(&Europe::Amsterdam).date();
let today = Utc::now().with_timezone(&Europe::Amsterdam).date_naive();
// Then, parse the time and interpret it relative to "today".
let ntime = NaiveTime::parse_from_str(t, "%H:%M")?;
let ndtime = today.naive_local().and_time(ntime);
let ndtime = today.and_time(ntime);
// Finally, interpret the naive date/time in the Europe/Amsterdam time zone and convert it to
// the UTC time zone.
let ldtime = Europe::Amsterdam.from_local_datetime(&ndtime).unwrap();
@ -98,8 +97,9 @@ fn fix_items_day_boundary(items: Vec<Item>) -> Vec<Item> {
let now = Utc::now().with_timezone(&Europe::Amsterdam);
// Use noon on the same day as "now" as a comparison moment.
let noon = Europe::Amsterdam
.ymd(now.year(), now.month(), now.day())
.and_hms(12, 0, 0);
.with_ymd_and_hms(now.year(), now.month(), now.day(), 12, 0, 0)
.single()
.expect("Invalid date: input date is invalid or not unambiguous");
if now < noon {
// It is still before noon, so bump timestamps after noon a day back.
@ -107,7 +107,7 @@ fn fix_items_day_boundary(items: Vec<Item>) -> Vec<Item> {
.into_iter()
.map(|mut item| {
if item.time > noon {
item.time = item.time - Duration::days(1)
item.time -= Duration::days(1)
}
item
})
@ -118,7 +118,7 @@ fn fix_items_day_boundary(items: Vec<Item>) -> Vec<Item> {
.into_iter()
.map(|mut item| {
if item.time < noon {
item.time = item.time + Duration::days(1)
item.time += Duration::days(1)
}
item
})