backup added
This commit is contained in:
parent
cda66aa56b
commit
dc86209ddb
|
|
@ -370,6 +370,7 @@ dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
"tokio-stream",
|
||||||
"vrd 0.0.7",
|
"vrd 0.0.7",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -1702,6 +1703,17 @@ dependencies = [
|
||||||
"tokio",
|
"tokio",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio-stream"
|
||||||
|
version = "0.1.15"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af"
|
||||||
|
dependencies = [
|
||||||
|
"futures-core",
|
||||||
|
"pin-project-lite",
|
||||||
|
"tokio",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio-util"
|
name = "tokio-util"
|
||||||
version = "0.7.11"
|
version = "0.7.11"
|
||||||
|
|
|
||||||
|
|
@ -15,4 +15,5 @@ pyo3 = { version = "0.21.2", features = ["auto-initialize"]}
|
||||||
serde = "1.0.203"
|
serde = "1.0.203"
|
||||||
serde_json = "1.0.117"
|
serde_json = "1.0.117"
|
||||||
tokio = "1.38.0"
|
tokio = "1.38.0"
|
||||||
|
tokio-stream = "0.1.15"
|
||||||
vrd = "0.0.7"
|
vrd = "0.0.7"
|
||||||
|
|
|
||||||
|
|
@ -4,10 +4,11 @@ use anyhow::Result;
|
||||||
use axum::{
|
use axum::{
|
||||||
body::Body, response::{IntoResponse, Response}, routing::{get, post}, Json, Router
|
body::Body, response::{IntoResponse, Response}, routing::{get, post}, Json, Router
|
||||||
};
|
};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
use crate::ApiResult;
|
use crate::ApiResult;
|
||||||
use db::{get_users, User};
|
use db::{get_database, get_users, LogEntry, Mole, User};
|
||||||
use http::{header::HeaderMap, StatusCode};
|
use http::{header::HeaderMap, StatusCode};
|
||||||
use mongodb::bson::{doc, oid::ObjectId};
|
use mongodb::bson::{doc, oid::ObjectId, to_document, Document};
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
|
|
||||||
pub fn router() -> Router {
|
pub fn router() -> Router {
|
||||||
|
|
@ -39,6 +40,11 @@ pub async fn auth(api: &str) -> Result<Option<User>> {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
struct BackupData {
|
||||||
|
moles: Vec<Mole>,
|
||||||
|
logs: Vec<LogEntry>,
|
||||||
|
}
|
||||||
|
|
||||||
async fn get_sign_in(Json(body): Json<User>) -> ApiResult {
|
async fn get_sign_in(Json(body): Json<User>) -> ApiResult {
|
||||||
let db = get_users().await?;
|
let db = get_users().await?;
|
||||||
|
|
@ -79,8 +85,8 @@ async fn post_sign_in(Json(body): Json<User>) -> ApiResult {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
match db.find_one(query.clone(), None).await? {
|
match db.count_documents(query.clone(), None).await? {
|
||||||
Some(_user) => {
|
count if count != 0 => {
|
||||||
db.update_one(query, update, None).await?;
|
db.update_one(query, update, None).await?;
|
||||||
|
|
||||||
Ok(Response::builder()
|
Ok(Response::builder()
|
||||||
|
|
@ -89,7 +95,7 @@ async fn post_sign_in(Json(body): Json<User>) -> ApiResult {
|
||||||
"_api_key": api.to_string()
|
"_api_key": api.to_string()
|
||||||
})).into_response().into_body())?)
|
})).into_response().into_body())?)
|
||||||
},
|
},
|
||||||
None => {
|
_ => {
|
||||||
Ok(Response::builder()
|
Ok(Response::builder()
|
||||||
.status(StatusCode::UNAUTHORIZED)
|
.status(StatusCode::UNAUTHORIZED)
|
||||||
.body(Body::from("Username or password is incorrect"))?)
|
.body(Body::from("Username or password is incorrect"))?)
|
||||||
|
|
@ -110,13 +116,13 @@ async fn post_sign_up(Json(body): Json<User>) -> ApiResult {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
match db.find_one(query, None).await? {
|
match db.count_documents(query, None).await? {
|
||||||
Some(_user) => {
|
count if count != 0 => {
|
||||||
Ok(Response::builder()
|
Ok(Response::builder()
|
||||||
.status(StatusCode::NOT_ACCEPTABLE)
|
.status(StatusCode::NOT_ACCEPTABLE)
|
||||||
.body(Body::from("Username is already taken"))?)
|
.body(Body::from("Username is already taken"))?)
|
||||||
},
|
},
|
||||||
None => {
|
_ => {
|
||||||
db.insert_one(body, None).await?;
|
db.insert_one(body, None).await?;
|
||||||
|
|
||||||
Ok(Response::builder()
|
Ok(Response::builder()
|
||||||
|
|
@ -154,6 +160,51 @@ async fn post_sign_out(headers: HeaderMap) -> ApiResult {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub async fn post_backup() {} //TODO: Backup
|
async fn get_restore() {
|
||||||
|
//TODO: Restore
|
||||||
|
//find all moles that match user_id
|
||||||
|
//find all logs that match mole_ids
|
||||||
|
//Return as Json
|
||||||
|
|
||||||
pub async fn get_restore() {} //TODO: restore
|
}
|
||||||
|
|
||||||
|
async fn post_backup(headers: HeaderMap, Json(user_data): Json<BackupData>) -> ApiResult {
|
||||||
|
let api = headers["api_key"].to_str()?;
|
||||||
|
|
||||||
|
match auth(api).await? {
|
||||||
|
Some(_user) => {
|
||||||
|
let _ = backup_docs_if_new(user_data.moles, "moles").await;
|
||||||
|
let _ = backup_docs_if_new(user_data.logs, "logs").await;
|
||||||
|
|
||||||
|
Ok(Response::builder()
|
||||||
|
.status(StatusCode::CREATED)
|
||||||
|
.body(Body::from("Account backup successful"))?)
|
||||||
|
},
|
||||||
|
None => Ok(Response::builder()
|
||||||
|
.status(StatusCode::UNAUTHORIZED)
|
||||||
|
.body(Body::from("API Key is incorrect"))?),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn backup_docs_if_new<T: serde::Serialize>(docs: Vec<T>, collection: &'static str) -> Result<()> {
|
||||||
|
let _ = docs.iter()
|
||||||
|
.map(|doc| to_document(doc).unwrap())
|
||||||
|
.map(|doc| {
|
||||||
|
tokio::spawn(async move {
|
||||||
|
let _ = insert_if_new(doc, collection).await;
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn insert_if_new(doc: Document, collection: &str) -> Result<()> {
|
||||||
|
let db = get_database().await?.collection(collection);
|
||||||
|
|
||||||
|
match db.count_documents(doc.clone(), None).await? {
|
||||||
|
0 => Some(db.insert_one(doc, None)),
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,7 @@
|
||||||
|
pub mod locations;
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
use locations::Location;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use mongodb::{
|
use mongodb::{
|
||||||
bson::{doc, oid::ObjectId, DateTime},
|
bson::{doc, oid::ObjectId, DateTime},
|
||||||
|
|
@ -24,55 +27,13 @@ pub async fn get_users() -> Result<Collection<User>> {
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
pub struct Mole {
|
pub struct Mole {
|
||||||
#[serde(rename = "_id", skip_serializing_if = "Option::is_none")]
|
#[serde(rename = "_id", skip_serializing_if = "Option::is_none")]
|
||||||
id: Option<ObjectId>,
|
pub id: Option<ObjectId>,
|
||||||
#[serde(rename="_user_id")]
|
#[serde(rename="_user_id")]
|
||||||
user_id: ObjectId,
|
pub user_id: ObjectId,
|
||||||
#[serde(rename="_image_path", skip_serializing_if = "Option::is_none")]
|
#[serde(rename="_image_path", skip_serializing_if = "Option::is_none")]
|
||||||
image_path: Option<String>,
|
pub image_path: Option<String>,
|
||||||
location: Location,
|
pub location: Location,
|
||||||
}
|
}
|
||||||
impl Mole {
|
|
||||||
pub fn new(user_id: ObjectId, location: Location) -> Self {
|
|
||||||
let id = None;
|
|
||||||
let image_path = None;
|
|
||||||
|
|
||||||
Self {
|
|
||||||
id,
|
|
||||||
user_id,
|
|
||||||
image_path,
|
|
||||||
location,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn with_image(user_id: ObjectId, location: Location, image_path: String) -> Self {
|
|
||||||
let id = None;
|
|
||||||
let image_path = Some(image_path);
|
|
||||||
|
|
||||||
Self {
|
|
||||||
id,
|
|
||||||
user_id,
|
|
||||||
image_path,
|
|
||||||
location
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
|
||||||
pub enum Location {
|
|
||||||
FrontLocation(FrontLocation),
|
|
||||||
LeftSideLocation(LeftSideLocation),
|
|
||||||
RightSideLocation(RightSideLocation),
|
|
||||||
BackLocation(BackLocation),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
|
||||||
pub enum FrontLocation {} //TODO: Add front locations
|
|
||||||
#[derive(Serialize, Deserialize)]
|
|
||||||
pub enum LeftSideLocation {} //TODO: Add left side locations
|
|
||||||
#[derive(Serialize, Deserialize)]
|
|
||||||
pub enum RightSideLocation {} //TODO: Add right side locations
|
|
||||||
#[derive(Serialize, Deserialize)]
|
|
||||||
pub enum BackLocation {} //TODO: Add back locations
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
pub struct LogEntry {
|
pub struct LogEntry {
|
||||||
|
|
@ -84,19 +45,6 @@ pub struct LogEntry {
|
||||||
#[serde(rename = "_mole_id")]
|
#[serde(rename = "_mole_id")]
|
||||||
pub mole_id: ObjectId
|
pub mole_id: ObjectId
|
||||||
}
|
}
|
||||||
impl LogEntry {
|
|
||||||
pub fn new(contents: String, mole_id: ObjectId) -> Self {
|
|
||||||
let id = None;
|
|
||||||
let date_created: DateTime = chrono::Utc::now().into();
|
|
||||||
|
|
||||||
Self {
|
|
||||||
id,
|
|
||||||
date_created,
|
|
||||||
contents,
|
|
||||||
mole_id,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Serialize, Deserialize)]
|
#[derive(Clone, Serialize, Deserialize)]
|
||||||
pub struct User {
|
pub struct User {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,94 @@
|
||||||
|
use serde::{Serialize, Deserialize};
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
pub enum Location {
|
||||||
|
FrontLocation(FrontLocation),
|
||||||
|
LeftSideLocation(SideLocation),
|
||||||
|
RightSideLocation(SideLocation),
|
||||||
|
BackLocation(BackLocation),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
pub enum FrontLocation {
|
||||||
|
Forehead,
|
||||||
|
Nose,
|
||||||
|
LeftEye,
|
||||||
|
RightEye,
|
||||||
|
Lips,
|
||||||
|
Chin,
|
||||||
|
Neck,
|
||||||
|
LeftCollar,
|
||||||
|
RightCollar,
|
||||||
|
LeftBreast,
|
||||||
|
RightBreast,
|
||||||
|
Stomach,
|
||||||
|
Genitals,
|
||||||
|
LeftShoulder,
|
||||||
|
RightShoulder,
|
||||||
|
LeftUpperArm,
|
||||||
|
RightUpperArm,
|
||||||
|
LeftInnerElbow,
|
||||||
|
RightInnerElbow,
|
||||||
|
LeftLowerArm,
|
||||||
|
RightLowerArm,
|
||||||
|
LeftWrist,
|
||||||
|
RightWrist,
|
||||||
|
LeftPalm,
|
||||||
|
RightPalm,
|
||||||
|
LeftThigh,
|
||||||
|
RightThigh,
|
||||||
|
LeftKnee,
|
||||||
|
RightKnee,
|
||||||
|
LeftShin,
|
||||||
|
RightShin,
|
||||||
|
LeftAnkle,
|
||||||
|
RightAnkle,
|
||||||
|
LeftFoot,
|
||||||
|
RightFoot,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
pub enum SideLocation {
|
||||||
|
Head,
|
||||||
|
Ear,
|
||||||
|
Cheek,
|
||||||
|
Neck,
|
||||||
|
Shoulder,
|
||||||
|
UpperArm,
|
||||||
|
Elbow,
|
||||||
|
LowerArm,
|
||||||
|
Wrist,
|
||||||
|
Hand,
|
||||||
|
UpperTorso,
|
||||||
|
LowerTorso,
|
||||||
|
Hip,
|
||||||
|
UpperLeg,
|
||||||
|
Knee,
|
||||||
|
LowerLeg,
|
||||||
|
Ankle,
|
||||||
|
Foot,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
pub enum BackLocation {
|
||||||
|
Head,
|
||||||
|
Neck,
|
||||||
|
LeftShoulder,
|
||||||
|
RightShoulder,
|
||||||
|
UpperBack,
|
||||||
|
LowerBack,
|
||||||
|
LeftButtock,
|
||||||
|
RightButtock,
|
||||||
|
LeftHamstring,
|
||||||
|
RightHamstring,
|
||||||
|
LeftKneePit,
|
||||||
|
RightKneePit,
|
||||||
|
LeftCalf,
|
||||||
|
RightCalf,
|
||||||
|
LeftAnkle,
|
||||||
|
RightAnkle,
|
||||||
|
LeftHeel,
|
||||||
|
RightHeel,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -14,7 +14,7 @@ pub async fn run() -> Result<()> {
|
||||||
|
|
||||||
let app = router();
|
let app = router();
|
||||||
let port = std::env::var("API_PORT")?;
|
let port = std::env::var("API_PORT")?;
|
||||||
let listener = tokio::net::TcpListener::bind(format!("127.0.0.1:{port}")).await.unwrap();
|
let listener = tokio::net::TcpListener::bind(format!("0.0.0.0:{port}")).await.unwrap();
|
||||||
axum::serve(listener, app).await.unwrap();
|
axum::serve(listener, app).await.unwrap();
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,4 +28,4 @@ def predict(model_bytes, image_bytes):
|
||||||
model = process_model_bytes(model_bytes)
|
model = process_model_bytes(model_bytes)
|
||||||
result = model.predict(image)
|
result = model.predict(image)
|
||||||
|
|
||||||
return result[0], result[1]
|
return result[0][0], result[0][1]
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue