diff --git a/Cargo.toml b/Cargo.toml index 780a0c0..84b4deb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,9 +1,7 @@ -[package] -name = "CookAssistant" -version = "0.1.0" -authors = ["artus "] -edition = "2018" +[workspace] -[dependencies] -cookbook = { path = "cookbook/" } -planner = { path = "planner/" } +members = [ + "cookbook", + "planner", + "web", +] diff --git a/cookbook/db.sqlite3 b/cookbook/db.sqlite3 index bc86f98..6d8c137 100644 Binary files a/cookbook/db.sqlite3 and b/cookbook/db.sqlite3 differ diff --git a/cookbook/src/lib.rs b/cookbook/src/lib.rs index 755c3e2..8f688d0 100644 --- a/cookbook/src/lib.rs +++ b/cookbook/src/lib.rs @@ -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 { use self::schema::recipes::dsl::*; recipes.load::(conn) diff --git a/cookbook/src/models.rs b/cookbook/src/models.rs index a430bb1..0dcd5ea 100644 --- a/cookbook/src/models.rs +++ b/cookbook/src/models.rs @@ -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}, diff --git a/src/main.rs b/src/main.rs deleted file mode 100644 index e7a11a9..0000000 --- a/src/main.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn main() { - println!("Hello, world!"); -} diff --git a/web/Cargo.toml b/web/Cargo.toml new file mode 100644 index 0000000..0c073d9 --- /dev/null +++ b/web/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "web" +version = "0.1.0" +authors = ["artus40 "] +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"] diff --git a/web/Rocket.toml b/web/Rocket.toml new file mode 100644 index 0000000..a29d328 --- /dev/null +++ b/web/Rocket.toml @@ -0,0 +1,2 @@ +[global.databases] +cookbook_db = { url = "../cookbook/db.sqlite3" } diff --git a/web/index.html b/web/html/index.html similarity index 64% rename from web/index.html rename to web/html/index.html index 38c9350..fd3019c 100644 --- a/web/index.html +++ b/web/html/index.html @@ -11,7 +11,8 @@

{{ items[active_view].title }}

-

{{ categories[items[active_view].category].name }}

+
{{ categories[items[active_view].category].name }}
+

{{ items[active_view].ingredients }}

@@ -36,27 +37,33 @@ var app = new Vue({ el: '#app', - data: { - categories: [ - {id: 0, name: "Petit-déjeuner"}, - {id: 1, name: "Plat principal"}, - {id: 2, 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} - ], + data () { + return { + categories: [ + {id: 0, name: "Petit-déjeuner"}, + {id: 1, name: "Entrée"}, + {id: 2, name: "Plat principal"}, + {id: 3, name: "Dessert"} + ], + active_category: -1, + active_view: -1, + 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() } }); diff --git a/web/src/main.rs b/web/src/main.rs new file mode 100644 index 0000000..8811870 --- /dev/null +++ b/web/src/main.rs @@ -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::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> { + 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(); +}