Create favorite model, add endpoint for retrieving favorites

This commit is contained in:
Reimar 2024-08-15 11:02:40 +02:00
parent e57174ccda
commit d88db4a284
Signed by: Reimar
GPG Key ID: 93549FA07F0AE268
4 changed files with 50 additions and 2 deletions

View File

@ -1135,6 +1135,7 @@ dependencies = [
"hmac", "hmac",
"refinery", "refinery",
"rusqlite", "rusqlite",
"serde",
"serde_json", "serde_json",
"sha2", "sha2",
] ]

View File

@ -7,6 +7,7 @@ edition = "2021"
base64 = "0.22.1" base64 = "0.22.1"
sha2 = "0.10.8" sha2 = "0.10.8"
hmac = "0.12.1" hmac = "0.12.1"
serde = "1.0.207"
serde_json = "1.0.124" serde_json = "1.0.124"
actix-web = "4" actix-web = "4"
actix-utils = "3.0.1" actix-utils = "3.0.1"

View File

@ -1,8 +1,10 @@
mod auth; mod auth;
mod models;
use actix_web::{get, Responder, HttpResponse, HttpServer, App, web}; use actix_web::{get, Responder, HttpResponse, HttpServer, App, web};
use std::sync::{Mutex, Arc}; use std::sync::{Mutex, MutexGuard, Arc};
use crate::auth::AuthorizedUser; use auth::AuthorizedUser;
use models::Favorite;
mod embedded { mod embedded {
use refinery::embed_migrations; use refinery::embed_migrations;
@ -29,6 +31,26 @@ async fn authorized(auth: AuthorizedUser) -> impl Responder {
HttpResponse::Ok().body(format!("Authorized as {} ({})", auth.username, auth.user_id)) HttpResponse::Ok().body(format!("Authorized as {} ({})", auth.username, auth.user_id))
} }
#[get("/favorites")]
async fn favorites(auth: AuthorizedUser, data: web::Data<AppData>) -> impl Responder {
let db = data.database.lock().unwrap();
match get_favorites(db, auth.user_id) {
Some(favorites) => HttpResponse::Ok().json(favorites),
None => HttpResponse::InternalServerError().finish(),
}
}
fn get_favorites(db: MutexGuard<'_, rusqlite::Connection>, user_id: String) -> Option<Vec<Favorite>> {
Some(
db.prepare("SELECT * FROM favorites WHERE user_id = :user_id").ok()?
.query_map(&[(":user_id", &user_id)], |row| Favorite::from_row(row))
.ok()?
.map(|fav| fav.unwrap())
.collect()
)
}
#[actix_web::main] #[actix_web::main]
async fn main() -> std::io::Result<()> { async fn main() -> std::io::Result<()> {
let _ = dotenvy::dotenv(); let _ = dotenvy::dotenv();
@ -58,6 +80,7 @@ async fn main() -> std::io::Result<()> {
})) }))
.service(healthcheck) .service(healthcheck)
.service(authorized) .service(authorized)
.service(favorites)
}) })
.bind(("0.0.0.0", port))? .bind(("0.0.0.0", port))?
.run() .run()

View File

@ -0,0 +1,23 @@
use std::string::String;
use serde::Serialize;
use rusqlite::{Row, Error};
#[derive(Serialize)]
pub struct Favorite {
pub id: usize,
pub user_id: String,
pub lat: f64,
pub lng: f64,
}
impl Favorite {
pub fn from_row(row: &Row) -> Result<Self, Error> {
Ok(Favorite {
id: row.get("id")?,
user_id: row.get("user_id")?,
lat: row.get("lat")?,
lng: row.get("lng")?,
})
}
}