Overhaul refactor. Still things in progress
This commit is contained in:
@@ -2,15 +2,15 @@ use std::str::FromStr;
|
||||
use futures_util::stream::StreamExt as _;
|
||||
|
||||
use crate::{
|
||||
airports::{QueryAirport, QueryFilters, QueryOrderField, QueryOrderBy, Airport, AirportCategory},
|
||||
db::{Response, Metadata},
|
||||
airports::{Airport, AirportCategory},
|
||||
db::Paged,
|
||||
auth::{Auth, verify_role},
|
||||
};
|
||||
use actix_multipart::Multipart;
|
||||
use actix_web::{delete, get, post, put, web, HttpResponse, HttpRequest, ResponseError};
|
||||
use log::{error, warn};
|
||||
use postgis_diesel::types::{Polygon, Point};
|
||||
use serde::{Serialize, Deserialize};
|
||||
use crate::airports::UpdateAirport;
|
||||
use crate::users::ADMIN_ROLE;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
struct AirportsQuery {
|
||||
@@ -27,7 +27,7 @@ struct AirportsQuery {
|
||||
|
||||
#[post("/import")]
|
||||
async fn import_airports(mut payload: Multipart, auth: Auth) -> HttpResponse {
|
||||
if let Err(err) = verify_role(&auth, "admin") {
|
||||
if let Err(err) = verify_role(&auth, ADMIN_ROLE) {
|
||||
return ResponseError::error_response(&err);
|
||||
};
|
||||
|
||||
@@ -43,7 +43,7 @@ async fn import_airports(mut payload: Multipart, auth: Auth) -> HttpResponse {
|
||||
let data = match chunk {
|
||||
Ok(data) => data,
|
||||
Err(err) => {
|
||||
error!("Failed to get chunk: {}", err);
|
||||
log::error!("Failed to get chunk: {}", err);
|
||||
return ResponseError::error_response(&err);
|
||||
}
|
||||
};
|
||||
@@ -54,14 +54,12 @@ async fn import_airports(mut payload: Multipart, auth: Auth) -> HttpResponse {
|
||||
let airports: Vec<Airport> = match serde_json::from_slice(&bytes) {
|
||||
Ok(a) => a,
|
||||
Err(err) => {
|
||||
error!("Failed to parse JSON: {}", err);
|
||||
log::error!("Failed to parse JSON: {}", err);
|
||||
return ResponseError::error_response(&err);
|
||||
}
|
||||
};
|
||||
|
||||
// Convert Vec<Airport> to Vec<QueryAirport> and insert into database
|
||||
let query_airports: Vec<QueryAirport> = airports.into_iter().map(|a| a.into()).collect();
|
||||
match QueryAirport::insert_all(query_airports) {
|
||||
match Airport::insert_all(airports).await {
|
||||
Ok(_) => {}
|
||||
Err(err) => return ResponseError::error_response(&err),
|
||||
};
|
||||
@@ -71,220 +69,83 @@ async fn import_airports(mut payload: Multipart, auth: Auth) -> HttpResponse {
|
||||
|
||||
#[get("")]
|
||||
async fn get_airports(req: HttpRequest) -> HttpResponse {
|
||||
let params = web::Query::<AirportsQuery>::from_query(req.query_string()).unwrap();
|
||||
let mut filters = QueryFilters::default();
|
||||
filters.icaos = match ¶ms.icaos {
|
||||
Some(i) => Some(i.split(",").map(|s| s.to_string()).collect()),
|
||||
None => None,
|
||||
};
|
||||
filters.name = params.name.clone();
|
||||
filters.categories = match ¶ms.categories {
|
||||
Some(c) => Some(
|
||||
c.split(",")
|
||||
.map(|s| AirportCategory::from_str(s).unwrap())
|
||||
.collect(),
|
||||
),
|
||||
None => None,
|
||||
};
|
||||
filters.bounds = match ¶ms.bounds {
|
||||
Some(b) => {
|
||||
let bounds: Vec<&str> = b.split(",").collect();
|
||||
if bounds.len() != 4 {
|
||||
warn!("Expected 4 bounds, received {}: {}", bounds.len(), b);
|
||||
return HttpResponse::UnprocessableEntity().body(format!(
|
||||
"Received {}; expected NE_LAT,NE_LON,SW_LAT,SW_LON",
|
||||
b
|
||||
));
|
||||
}
|
||||
let ne_lat = match bounds[0].parse::<f64>() {
|
||||
Ok(b) => b,
|
||||
Err(err) => {
|
||||
warn!("{}", err);
|
||||
return HttpResponse::UnprocessableEntity().body(format!("{}", err));
|
||||
}
|
||||
};
|
||||
let ne_lon = match bounds[1].parse::<f64>() {
|
||||
Ok(b) => b,
|
||||
Err(err) => {
|
||||
warn!("{}", err);
|
||||
return HttpResponse::UnprocessableEntity().body(format!("{}", err));
|
||||
}
|
||||
};
|
||||
let sw_lat = match bounds[2].parse::<f64>() {
|
||||
Ok(b) => b,
|
||||
Err(err) => {
|
||||
warn!("{}", err);
|
||||
return HttpResponse::UnprocessableEntity().body(format!("{}", err));
|
||||
}
|
||||
};
|
||||
let sw_lon = match bounds[3].parse::<f64>() {
|
||||
Ok(b) => b,
|
||||
Err(err) => {
|
||||
warn!("{}", err);
|
||||
return HttpResponse::UnprocessableEntity().body(format!("{}", err));
|
||||
}
|
||||
};
|
||||
let mut polygon: Polygon<Point> = Polygon::new(Some(4326));
|
||||
polygon.add_point(Point {
|
||||
x: sw_lon,
|
||||
y: sw_lat,
|
||||
srid: Some(4326),
|
||||
});
|
||||
polygon.add_point(Point {
|
||||
x: ne_lon,
|
||||
y: sw_lat,
|
||||
srid: Some(4326),
|
||||
});
|
||||
polygon.add_point(Point {
|
||||
x: ne_lon,
|
||||
y: ne_lat,
|
||||
srid: Some(4326),
|
||||
});
|
||||
polygon.add_point(Point {
|
||||
x: sw_lon,
|
||||
y: ne_lat,
|
||||
srid: Some(4326),
|
||||
});
|
||||
polygon.add_point(Point {
|
||||
x: sw_lon,
|
||||
y: sw_lat,
|
||||
srid: Some(4326),
|
||||
});
|
||||
Some(polygon)
|
||||
}
|
||||
None => None,
|
||||
};
|
||||
|
||||
filters.order_by = match ¶ms.order_by {
|
||||
Some(o) => Some(QueryOrderBy::from_str(&o).unwrap()),
|
||||
None => None,
|
||||
};
|
||||
filters.order_field = match ¶ms.order_field {
|
||||
Some(o) => Some(QueryOrderField::from_str(&o).unwrap()),
|
||||
None => None,
|
||||
};
|
||||
filters.has_metar = match ¶ms.has_metar {
|
||||
Some(h) => Some(h.parse::<bool>().unwrap()),
|
||||
None => None,
|
||||
};
|
||||
|
||||
let limit = match params.limit {
|
||||
Some(l) => l,
|
||||
None => 100,
|
||||
};
|
||||
let page = match params.page {
|
||||
Some(p) => p,
|
||||
None => 1,
|
||||
};
|
||||
let total = match QueryAirport::get_count(&filters) {
|
||||
Ok(t) => t,
|
||||
Err(_) => 0,
|
||||
};
|
||||
|
||||
match web::block(move || QueryAirport::get_all(&filters, limit, page))
|
||||
.await
|
||||
.unwrap()
|
||||
{
|
||||
Ok(a) => {
|
||||
// Convert Vec<QueryAirport> to Vec<Airport>
|
||||
let mut airports: Vec<Airport> = vec![];
|
||||
for airport in a {
|
||||
airports.push(airport.into());
|
||||
}
|
||||
HttpResponse::Ok().json(Response {
|
||||
data: airports,
|
||||
meta: Some(Metadata { page, limit, total }),
|
||||
})
|
||||
}
|
||||
match Airport::select_all().await {
|
||||
Ok(airports) => HttpResponse::Ok().json(airports),
|
||||
Err(err) => {
|
||||
error!("{}", err);
|
||||
err.to_http_response()
|
||||
log::error!("{}", err);
|
||||
ResponseError::error_response(&err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[get("/{icao}")]
|
||||
async fn get_airport(icao: web::Path<String>) -> HttpResponse {
|
||||
match QueryAirport::get(&icao.into_inner()) {
|
||||
Ok(a) => {
|
||||
let airport: Airport = a.into();
|
||||
HttpResponse::Ok().json(airport)
|
||||
}
|
||||
Err(err) => {
|
||||
error!("{}", err);
|
||||
err.to_http_response()
|
||||
}
|
||||
match Airport::select(&icao.into_inner()).await {
|
||||
Some(airport) => HttpResponse::Ok().json(airport),
|
||||
None => HttpResponse::NotFound().finish(),
|
||||
}
|
||||
}
|
||||
|
||||
#[post("")]
|
||||
async fn create_airport(airport: web::Json<Airport>, auth: Auth) -> HttpResponse {
|
||||
let _ = match verify_role(&auth, "admin") {
|
||||
async fn insert_airport(airport: web::Json<Airport>, auth: Auth) -> HttpResponse {
|
||||
let _ = match verify_role(&auth, ADMIN_ROLE) {
|
||||
Ok(_) => {}
|
||||
Err(err) => return ResponseError::error_response(&err),
|
||||
};
|
||||
let query_airport: QueryAirport = airport.into_inner().into();
|
||||
match QueryAirport::insert(query_airport) {
|
||||
Ok(a) => {
|
||||
let airport: Airport = a.into();
|
||||
HttpResponse::Ok().json(airport)
|
||||
}
|
||||
match airport.insert().await {
|
||||
Ok(a) => HttpResponse::Ok().json(a),
|
||||
Err(err) => {
|
||||
error!("{}", err);
|
||||
err.to_http_response()
|
||||
log::error!("{}", err);
|
||||
ResponseError::error_response(&err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[put("/{icao}")]
|
||||
async fn update_airport(
|
||||
_icao: web::Path<String>,
|
||||
airport: web::Json<Airport>,
|
||||
icao: web::Path<String>,
|
||||
airport: web::Json<UpdateAirport>,
|
||||
auth: Auth,
|
||||
) -> HttpResponse {
|
||||
let _ = match verify_role(&auth, "admin") {
|
||||
let _ = match verify_role(&auth, ADMIN_ROLE) {
|
||||
Ok(_) => {}
|
||||
Err(err) => return ResponseError::error_response(&err),
|
||||
};
|
||||
let query_airport: QueryAirport = airport.into_inner().into();
|
||||
match QueryAirport::update(query_airport) {
|
||||
Ok(a) => {
|
||||
let airport: Airport = a.into();
|
||||
HttpResponse::Ok().json(airport)
|
||||
}
|
||||
match Airport::update(&icao.into_inner(), &airport.into_inner()).await {
|
||||
Ok(a) => HttpResponse::Ok().json(a),
|
||||
Err(err) => {
|
||||
error!("{}", err);
|
||||
err.to_http_response()
|
||||
log::error!("{}", err);
|
||||
ResponseError::error_response(&err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[delete("")]
|
||||
async fn delete_airports(auth: Auth) -> HttpResponse {
|
||||
let _ = match verify_role(&auth, "admin") {
|
||||
let _ = match verify_role(&auth, ADMIN_ROLE) {
|
||||
Ok(_) => {}
|
||||
Err(err) => return ResponseError::error_response(&err),
|
||||
};
|
||||
match QueryAirport::delete(None) {
|
||||
match Airport::delete_all().await {
|
||||
Ok(_) => HttpResponse::NoContent().finish(),
|
||||
Err(err) => {
|
||||
error!("{}", err);
|
||||
err.to_http_response()
|
||||
log::error!("{}", err);
|
||||
ResponseError::error_response(&err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[delete("/{icao}")]
|
||||
async fn delete_airport(icao: web::Path<String>, auth: Auth) -> HttpResponse {
|
||||
let _ = match verify_role(&auth, "admin") {
|
||||
let _ = match verify_role(&auth, ADMIN_ROLE) {
|
||||
Ok(_) => {}
|
||||
Err(err) => return ResponseError::error_response(&err),
|
||||
};
|
||||
match QueryAirport::delete(Some(icao.into_inner())) {
|
||||
match Airport::delete(&icao.into_inner()).await {
|
||||
Ok(_) => HttpResponse::NoContent().finish(),
|
||||
Err(err) => {
|
||||
error!("{}", err);
|
||||
err.to_http_response()
|
||||
log::error!("{}", err);
|
||||
ResponseError::error_response(&err)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -295,7 +156,7 @@ pub fn init_routes(config: &mut web::ServiceConfig) {
|
||||
.service(import_airports)
|
||||
.service(get_airports)
|
||||
.service(get_airport)
|
||||
.service(create_airport)
|
||||
.service(insert_airport)
|
||||
.service(update_airport)
|
||||
.service(delete_airports)
|
||||
.service(delete_airport),
|
||||
|
||||
Reference in New Issue
Block a user