Builds a basic api with rocket.rs, updates index.html
This commit is contained in:
14
Cargo.toml
14
Cargo.toml
@@ -1,9 +1,7 @@
|
||||
[package]
|
||||
name = "CookAssistant"
|
||||
version = "0.1.0"
|
||||
authors = ["artus <artus@landoftheunicorn.hd.free.fr>"]
|
||||
edition = "2018"
|
||||
[workspace]
|
||||
|
||||
[dependencies]
|
||||
cookbook = { path = "cookbook/" }
|
||||
planner = { path = "planner/" }
|
||||
members = [
|
||||
"cookbook",
|
||||
"planner",
|
||||
"web",
|
||||
]
|
||||
|
||||
Binary file not shown.
@@ -10,7 +10,6 @@ mod importer;
|
||||
use diesel::prelude::*;
|
||||
use dotenv::dotenv;
|
||||
use std::env;
|
||||
use crate::models::{Recipe, NewRecipe};
|
||||
|
||||
pub fn establish_connection() -> SqliteConnection {
|
||||
dotenv().ok();
|
||||
@@ -21,10 +20,11 @@ pub fn establish_connection() -> SqliteConnection {
|
||||
}
|
||||
|
||||
pub mod recipes {
|
||||
use crate::models::{Recipe, NewRecipe};
|
||||
use crate::models::{Recipe};
|
||||
use super::{SqliteConnection, schema};
|
||||
use super::diesel::prelude::*;
|
||||
|
||||
/// Loads all recipes from database
|
||||
pub fn load_all(conn: &SqliteConnection) -> Vec<Recipe> {
|
||||
use self::schema::recipes::dsl::*;
|
||||
recipes.load::<Recipe>(conn)
|
||||
|
||||
@@ -5,7 +5,6 @@ use super::diesel::prelude::*;
|
||||
pub mod fields {
|
||||
use diesel::{
|
||||
backend::Backend,
|
||||
sqlite::Sqlite,
|
||||
sql_types::*,
|
||||
deserialize::{self, FromSql},
|
||||
serialize::{self, Output, ToSql},
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
fn main() {
|
||||
println!("Hello, world!");
|
||||
}
|
||||
17
web/Cargo.toml
Normal file
17
web/Cargo.toml
Normal file
@@ -0,0 +1,17 @@
|
||||
[package]
|
||||
name = "web"
|
||||
version = "0.1.0"
|
||||
authors = ["artus40 <artus@landoftheunicorn.ovh>"]
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
rocket = "0.4.0"
|
||||
cookbook = { path = "../cookbook/" }
|
||||
serde = "1.0"
|
||||
serde_derive = "1.0"
|
||||
|
||||
|
||||
[dependencies.rocket_contrib]
|
||||
version = "0.4.0"
|
||||
default-features = false
|
||||
features = ["json", "diesel_sqlite_pool"]
|
||||
2
web/Rocket.toml
Normal file
2
web/Rocket.toml
Normal file
@@ -0,0 +1,2 @@
|
||||
[global.databases]
|
||||
cookbook_db = { url = "../cookbook/db.sqlite3" }
|
||||
@@ -11,7 +11,8 @@
|
||||
<section v-if="active_view > -1">
|
||||
<button @click="setActiveView(-1)">X close</button>
|
||||
<h4>{{ items[active_view].title }}</h4>
|
||||
<p>{{ categories[items[active_view].category].name }}</p>
|
||||
<h6>{{ categories[items[active_view].category].name }}</h6>
|
||||
<p><strong>{{ items[active_view].ingredients }}</strong></p>
|
||||
</section>
|
||||
<!-- Category List View -->
|
||||
<section v-else>
|
||||
@@ -36,27 +37,33 @@
|
||||
|
||||
var app = new Vue({
|
||||
el: '#app',
|
||||
data: {
|
||||
data () {
|
||||
return {
|
||||
categories: [
|
||||
{id: 0, name: "Petit-déjeuner"},
|
||||
{id: 1, name: "Plat principal"},
|
||||
{id: 2, name: "Dessert"}
|
||||
{id: 1, name: "Entrée"},
|
||||
{id: 2, name: "Plat principal"},
|
||||
{id: 3, name: "Dessert"}
|
||||
],
|
||||
active_category: -1,
|
||||
active_view: -1,
|
||||
items: [
|
||||
{id: 0, title: "Raclette", category: 1},
|
||||
{id: 1, title: "Tartiflette", category: 1},
|
||||
{id: 2, title: "Pancakes", category: 0},
|
||||
{id: 3, title: "Crêpes", category: 2}
|
||||
],
|
||||
items: []
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
setActiveCategory: function(id) {
|
||||
this.active_category = id;
|
||||
},
|
||||
setActiveView: function(id) {
|
||||
this.active_view = id;
|
||||
this.active_view = id - 1;
|
||||
},
|
||||
fetchRecipesList: function() {
|
||||
fetch("/api/list")
|
||||
.then((res) => res.json())
|
||||
.then((data) => this.items = data)
|
||||
.catch(function(err) {
|
||||
console.error(err);
|
||||
});
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@@ -65,6 +72,9 @@
|
||||
rec => rec.category == this.active_category
|
||||
);
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.fetchRecipesList()
|
||||
}
|
||||
});
|
||||
</script>
|
||||
65
web/src/main.rs
Normal file
65
web/src/main.rs
Normal file
@@ -0,0 +1,65 @@
|
||||
#![feature(proc_macro_hygiene, decl_macro)]
|
||||
|
||||
#[macro_use] extern crate rocket;
|
||||
#[macro_use] extern crate rocket_contrib;
|
||||
#[macro_use] extern crate serde_derive;
|
||||
|
||||
extern crate cookbook;
|
||||
|
||||
use std::path::Path;
|
||||
use rocket::response::{NamedFile, status::NotFound};
|
||||
|
||||
#[get("/")]
|
||||
fn index() -> Result<NamedFile, NotFound<String>> {
|
||||
NamedFile::open(&Path::new("./html/index.html"))
|
||||
.map_err(|_| NotFound(format!("Server error : index not found")))
|
||||
}
|
||||
|
||||
mod api {
|
||||
use cookbook::*;
|
||||
use rocket_contrib::{
|
||||
json::Json,
|
||||
databases::diesel,
|
||||
};
|
||||
|
||||
#[database("cookbook_db")]
|
||||
pub struct CookbookDbConn(diesel::SqliteConnection);
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct Recipe {
|
||||
id: i32,
|
||||
title: String,
|
||||
category: i16,
|
||||
ingredients: String,
|
||||
preparation: String,
|
||||
}
|
||||
|
||||
impl Recipe {
|
||||
fn from(rec: models::Recipe) -> Recipe {
|
||||
Recipe {
|
||||
id: rec.id,
|
||||
title: rec.title,
|
||||
category: rec.category as i16,
|
||||
ingredients: rec.ingredients,
|
||||
preparation: rec.preparation,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[get("/list")]
|
||||
pub fn recipes_list(conn: CookbookDbConn) -> Json<Vec<Recipe>> {
|
||||
Json(
|
||||
recipes::load_all(&conn)
|
||||
.into_iter()
|
||||
.map(|r| Recipe::from(r))
|
||||
.collect()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
rocket::ignite()
|
||||
.attach(api::CookbookDbConn::fairing())
|
||||
.mount("/", routes![index])
|
||||
.mount("/api", routes![api::recipes_list]).launch();
|
||||
}
|
||||
Reference in New Issue
Block a user