diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..656e823 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,64 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "lldb", + "request": "launch", + "name": "Debug unit tests in library 'cheezenotes'", + "cargo": { + "args": [ + "test", + "--no-run", + "--lib", + "--package=cheezenotes" + ], + "filter": { + "name": "cheezenotes", + "kind": "lib" + } + }, + "args": [], + "cwd": "${workspaceFolder}" + }, + { + "type": "lldb", + "request": "launch", + "name": "Debug executable 'cheezenotes'", + "cargo": { + "args": [ + "build", + "--bin=cheezenotes", + "--package=cheezenotes" + ], + "filter": { + "name": "cheezenotes", + "kind": "bin" + } + }, + "args": [], + "cwd": "${workspaceFolder}" + }, + { + "type": "lldb", + "request": "launch", + "name": "Debug unit tests in executable 'cheezenotes'", + "cargo": { + "args": [ + "test", + "--no-run", + "--bin=cheezenotes", + "--package=cheezenotes" + ], + "filter": { + "name": "cheezenotes", + "kind": "bin" + } + }, + "args": [], + "cwd": "${workspaceFolder}" + } + ] +} \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 8cbb0b7..4530c42 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -143,6 +143,23 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "actix-session" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43da8b818ae1f11049a4d218975345fe8e56ce5a5f92c11f972abcff5ff80e87" +dependencies = [ + "actix-service", + "actix-utils", + "actix-web", + "anyhow", + "async-trait", + "derive_more", + "serde", + "serde_json", + "tracing", +] + [[package]] name = "actix-utils" version = "3.0.1" @@ -212,6 +229,41 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +[[package]] +name = "aead" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c192eb8f11fc081b0fe4259ba5af04217d4e0faddd02417310a927911abd7c8" +dependencies = [ + "crypto-common", + "generic-array", +] + +[[package]] +name = "aes" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "433cfd6710c9986c576a25ca913c39d66a6474107b406f34f91d4a8923395241" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + +[[package]] +name = "aes-gcm" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82e1366e0c69c9f927b1fa5ce2c7bf9eafc8f9268c0b9800729e8b267612447c" +dependencies = [ + "aead", + "aes", + "cipher", + "ctr", + "ghash", + "subtle", +] + [[package]] name = "ahash" version = "0.7.6" @@ -256,6 +308,12 @@ dependencies = [ "libc", ] +[[package]] +name = "anyhow" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "224afbd727c3d6e4b90103ece64b8d1b67fbb1973b1046c2281eed3f3803f800" + [[package]] name = "askama" version = "0.11.1" @@ -338,6 +396,12 @@ version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" +[[package]] +name = "base64" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ea22880d78093b0cbe17c89f64a7d457941e65759157ec6cb31a31d652b05e5" + [[package]] name = "base64" version = "0.21.0" @@ -440,6 +504,7 @@ name = "cheezenotes" version = "0.2.0" dependencies = [ "actix-files", + "actix-session", "actix-web", "askama", "askama_actix", @@ -447,6 +512,8 @@ dependencies = [ "git2", "lazy_static", "mongodb", + "r2d2", + "r2d2_sqlite", "regex", "rusqlite", "serde", @@ -468,6 +535,16 @@ dependencies = [ "winapi", ] +[[package]] +name = "cipher" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1873270f8f7942c191139cb8a40fd228da6c3fd2fc376d7e92d47aa14aeb59e" +dependencies = [ + "crypto-common", + "inout", +] + [[package]] name = "clap" version = "4.1.4" @@ -527,7 +604,14 @@ version = "0.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e859cd57d0710d9e06c381b550c06e76992472a8c6d527aecd2fc673dcc231fb" dependencies = [ + "aes-gcm", + "base64 0.20.0", + "hkdf", + "hmac", "percent-encoding", + "rand", + "sha2", + "subtle", "time 0.3.17", "version_check", ] @@ -563,9 +647,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ "generic-array", + "rand_core", "typenum", ] +[[package]] +name = "ctr" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" +dependencies = [ + "cipher", +] + [[package]] name = "cxx" version = "1.0.91" @@ -857,6 +951,16 @@ dependencies = [ "wasi 0.11.0+wasi-snapshot-preview1", ] +[[package]] +name = "ghash" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d930750de5717d2dd0b8c0d42c076c0e884c81a73e6cab859bbd2339c71e3e40" +dependencies = [ + "opaque-debug", + "polyval", +] + [[package]] name = "git2" version = "0.16.1" @@ -930,6 +1034,15 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +[[package]] +name = "hkdf" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "791a029f6b9fc27657f6f188ec6e5e43f6911f6f878e0dc5501396e09809d437" +dependencies = [ + "hmac", +] + [[package]] name = "hmac" version = "0.12.1" @@ -1046,6 +1159,15 @@ dependencies = [ "hashbrown", ] +[[package]] +name = "inout" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" +dependencies = [ + "generic-array", +] + [[package]] name = "io-lifetimes" version = "1.0.5" @@ -1407,6 +1529,12 @@ version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66" +[[package]] +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" + [[package]] name = "openssl-probe" version = "0.1.5" @@ -1504,6 +1632,18 @@ version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" +[[package]] +name = "polyval" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ef234e08c11dfcb2e56f79fd70f6f2eb7f025c0ce2333e82f4f0518ecad30c6" +dependencies = [ + "cfg-if", + "cpufeatures", + "opaque-debug", + "universal-hash", +] + [[package]] name = "ppv-lite86" version = "0.2.17" @@ -1558,6 +1698,27 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "r2d2" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51de85fb3fb6524929c8a2eb85e6b6d363de4e8c48f9e2c2eac4944abc181c93" +dependencies = [ + "log", + "parking_lot", + "scheduled-thread-pool", +] + +[[package]] +name = "r2d2_sqlite" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4f5d0337e99cd5cacd91ffc326c6cc9d8078def459df560c4f9bf9ba4a51034" +dependencies = [ + "r2d2", + "rusqlite", +] + [[package]] name = "rand" version = "0.8.5" @@ -1722,6 +1883,15 @@ version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7b4b9743ed687d4b4bcedf9ff5eaa7398495ae14e61cba0a295704edbc7decde" +[[package]] +name = "scheduled-thread-pool" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "977a7519bff143a44f842fd07e80ad1329295bd71686457f18e496736f4bf9bf" +dependencies = [ + "parking_lot", +] + [[package]] name = "scopeguard" version = "1.1.0" @@ -2218,6 +2388,16 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" +[[package]] +name = "universal-hash" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d3160b73c9a19f7e2939a2fdad446c57c1bbbbf4d919d3213ff1267a580d8b5" +dependencies = [ + "crypto-common", + "subtle", +] + [[package]] name = "untrusted" version = "0.7.1" diff --git a/Cargo.toml b/Cargo.toml index cc38a69..fc5bc06 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,6 +11,7 @@ clap = { version = "4.0.18", features = ["derive"] } actix-web = "4" actix-files = "0.6.2" +actix-session = { version = "0.7.2", features = ["cookie-session"] } askama = { version = "0.11.1", features = ["with-actix-web"] } askama_actix = "0.13.0" @@ -21,6 +22,8 @@ git2 = "0.16.0" regex = "1" +r2d2 = "0.8" +r2d2_sqlite = "0.21.0" rusqlite = {version = "0.28.0", features=["bundled"]} lazy_static = "1.4.0" diff --git a/db/db copy.sqlite3 b/db/db copy.sqlite3 new file mode 100644 index 0000000..a531d5d Binary files /dev/null and b/db/db copy.sqlite3 differ diff --git a/db/db.sql b/db/db.sql new file mode 100644 index 0000000..13c5378 --- /dev/null +++ b/db/db.sql @@ -0,0 +1,5 @@ +create table pages ( + page_name text primary key, + page_text text, + active boolean default true not null +); \ No newline at end of file diff --git a/db/db.sqlite3 b/db/db.sqlite3 new file mode 100644 index 0000000..d4757bc Binary files /dev/null and b/db/db.sqlite3 differ diff --git a/pages/BPCE-SI-Notes.md b/pages/BPCE-SI-Notes.md index 9d9efd2..5bd4a74 100644 --- a/pages/BPCE-SI-Notes.md +++ b/pages/BPCE-SI-Notes.md @@ -1,12 +1,14 @@ [Notes](notes) # Notes (BPCE-SI) ## A faire +- tiers-v2/corporateInformation -> identifiantLEI -> QrD5B3, QrD5F3, QrD17CIB00 +- Gce.SirenSiretNonDistrib : **proxy-dc.sec.bpce-it.fr** +- Récupération des bilans dans les différents clients (évolution bilans). - Voir les versions de .Net qu'on peut installer sur les serveurs batch PMM. - Millesime 2022 liasse 2033 valeur 111 sur page A à renommer 111A - Sujet Anaïs : Immatriculation avec données manquantes en base de données : 11315 509234258 - Modifier tâche de migration GIT avec les applis à migrer durant le sprint - Voir Jean-Charles Bezard pour les grands clients nationnaux en fonction du grappage -- INC00100347 - Voir avec Julien la NDS semaine du 20/01/2023 - Regarder si on peut appareiller fichier index et xml dans SurveillanceSiren. - Batch pour récupérer les siren confidentiels : tout le stock ou les mises à jour selon paramètre d'exécution. @@ -25,11 +27,12 @@ * [Forbearance](forbearance) * [SPT](SPT) * [Millésime 2022](millesime2022) +## Fonctionnel +- [Campagne Elocal]() ## Listes - [Contacts](contacts-bpce-si) - [Clients](clients-bpce-si) ## Suivi Anaïs -- [Feedback 27/01/2023](anais-feedback-27-01-2023)## Suivi Anaïs - [Feedback 27/01/2023](anais-feedback-27-01-2023) ## Bidouille - [bidouille]() \ No newline at end of file diff --git a/pages/Campagne Elocal.md b/pages/Campagne Elocal.md new file mode 100644 index 0000000..9a3c67e --- /dev/null +++ b/pages/Campagne Elocal.md @@ -0,0 +1,14 @@ +[retour](BPCE-SI-Notes) +# CampagnesElocal +## Calendrier2023 +|||campagne 1|campagne 2|campagne 3|campagne 4| +|Batchs concernés|FI_SPT|:X:|:X:|::|::| +||SOCIO|X|X|X|?| +||RETRO_SP|X||X|?| +||BILAN_SEM|?|?|X|?| +||SOCIO_EPCI (auto)|X|X|X|?| +|Périodes|Livraison INPUTS||||| +||UTI||||| +||QPA||||| +||MEP|Février|Avril|Septembre|Nov.-Déc.| +|Terminé|Date|06/02/2023|||| \ No newline at end of file diff --git a/pages/bidouille.md b/pages/bidouille.md index 14234cf..8a32f5b 100644 --- a/pages/bidouille.md +++ b/pages/bidouille.md @@ -1,13 +1,2 @@ [retour](BPCE-SI-Notes) -[](\\Prdgce7v2115\d\gcedoc\referentielproduction\clients\csctrmif\csctrmif\Documents) -[](\\Prdgce7v2116\d\gcedoc\referentielproduction\clients\csctrmif\csctrmif\Documents) -[](\\Prdgce7v2117\d\gcedoc\referentielproduction\clients\csctrmif\csctrmif\Documents) -[](\\Prdgce7v2118\d\gcedoc\referentielproduction\clients\csctrmif\csctrmif\Documents) -[](\\Prdgce7v2119\d\gcedoc\referentielproduction\clients\csctrmif\csctrmif\Documents) -[](\\Prdgce7v2120\d\gcedoc\referentielproduction\clients\csctrmif\csctrmif\Documents) -[](\\Prdgce7v2121\d\gcedoc\referentielproduction\clients\csctrmif\csctrmif\Documents) -[](\\Prdgce7v2122\d\gcedoc\referentielproduction\clients\csctrmif\csctrmif\Documents) -[](\\Prdgce7v2123\d\gcedoc\referentielproduction\clients\csctrmif\csctrmif\Documents) -[](\\Prdgce7v2124\d\gcedoc\referentielproduction\clients\csctrmif\csctrmif\Documents) -[](\\Prdgce7v2125\d\gcedoc\referentielproduction\clients\csctrmif\csctrmif\Documents) -[](\\Prdgce7v2126\d\gcedoc\referentielproduction\clients\csctrmif\csctrmif\Documents) +# Bidouille \ No newline at end of file diff --git a/pages/dbtest.md b/pages/dbtest.md new file mode 100644 index 0000000..e92b696 --- /dev/null +++ b/pages/dbtest.md @@ -0,0 +1 @@ +# test DB \ No newline at end of file diff --git a/pages/enveloppes.md b/pages/enveloppes.md index dcd1497..567279f 100644 --- a/pages/enveloppes.md +++ b/pages/enveloppes.md @@ -52,5 +52,5 @@ ## 10 - resumé après modification * Ajouter une zone de saisie pour permettre au conseiller de saisir la phrase (pour la synthèse) ## 11 - Synthèse (pdf) -* Grise la ligne enveloppe (gris plus clair) +* Griser la ligne enveloppe (gris plus clair) * ligne dessous, CTO numéro de compte, si nouveau : "à souscrire" \ No newline at end of file diff --git a/pages/forbearance.md b/pages/forbearance.md index 819e72a..a9aed7a 100644 --- a/pages/forbearance.md +++ b/pages/forbearance.md @@ -3,3 +3,4 @@ Rechercher les valeurs possible des états et statut. fait. * GECOCH : P34249 * Clarity : 031984-02 +* synthesecorporateserv/rechercheBilan **->** voir si on a les données Elocal suffisantes (validé etc.) diff --git a/pages/notes.md b/pages/notes.md index 7b680d2..6a84aec 100644 --- a/pages/notes.md +++ b/pages/notes.md @@ -2,6 +2,8 @@ # Notes ## BPCE-SI - [Notes](BPCE-SI-Notes) +## Cheeze Notes +- exemple [r2d2 + rusqlite](https://github.com/actix/examples/blob/master/databases/sqlite/src/main.rs) ## Rust *  [Idées](perso-idees) *  [Crates](perso-crates) @@ -15,4 +17,5 @@ ## Avec les enfants - [Bricolages]() - [mini-golf]() -- [Livres](livres enfants) \ No newline at end of file +- [Livres](livres enfants) +- lapin de race feu noir \ No newline at end of file diff --git a/pages/test.md b/pages/test.md index 4d17437..6c7b8e3 100644 --- a/pages/test.md +++ b/pages/test.md @@ -1,3 +1,4 @@ [Accueil](accueil) # Test pour développement CheezeNotes -test de gras au milieu d'un texte \ No newline at end of file +test de gras au milieu d'un texte +[!](/static/cs.png) Salut les filles ! \ No newline at end of file diff --git a/src/commons.rs b/src/commons.rs index 08937c9..da976af 100644 --- a/src/commons.rs +++ b/src/commons.rs @@ -1,4 +1,6 @@ use clap::Parser; +use r2d2::Pool; +use r2d2_sqlite::SqliteConnectionManager; #[derive(Parser)] pub struct Arguments { @@ -26,7 +28,5 @@ impl Arguments { pub struct AppData { pub name: String, pub root: String, - pub db_url: String, - pub db_user: String, - pub db_password: String, + pub pool: Pool, } diff --git a/src/database.rs b/src/database.rs deleted file mode 100644 index 39fd9a6..0000000 --- a/src/database.rs +++ /dev/null @@ -1,12 +0,0 @@ -use rusqlite::{params, Connection, Result}; - -pub struct DatabaseConnection { - connection_string: String, - connection: Option, -} - -pub fn new(connection_string: String) -> DatabaseConnection { - let mut con = DatabaseConnection{ connection_string: connection_string.to_owned(), connection: None}; - con.connection = Some(Connection::open(connection_string).unwrap()); - con -} diff --git a/src/db.rs b/src/db.rs new file mode 100644 index 0000000..1dddb91 --- /dev/null +++ b/src/db.rs @@ -0,0 +1,51 @@ +use actix_web::{error, web, Error}; +use serde::{Deserialize, Serialize}; + +pub type Pool = r2d2::Pool; +pub type Connection = r2d2::PooledConnection; + +#[derive(Debug, Serialize, Deserialize)] +pub struct Page { + pub page_name: String, + pub page_text: String, +} + +pub async fn get_page_by_name(pool: &Pool, pagename: String) -> Result, Error> { + let pool = pool.clone(); + + let conn = web::block(move || pool.get()) + .await? + .map_err(error::ErrorInternalServerError)?; + + web::block(move || { + let mut stmt = conn + .prepare("SELECT page_name, page_text from pages WHERE active=true and page_name=?")?; + + stmt.query_map([pagename], |row| { + Ok(Page { + page_name: row.get(0)?, + page_text: row.get(1)?, + }) + }) + .and_then(Iterator::collect) + }) + .await? + .map_err(error::ErrorInternalServerError) +} + +pub async fn update_page(pool: &Pool, page_name: String, page_text: String) -> Result { + let pool = pool.clone(); + + let conn = web::block(move || pool.get()) + .await? + .map_err(error::ErrorInternalServerError)?; + + web::block(move || { + let mut stmt = conn + .prepare("insert or replace into pages (page_name, page_text, active) values (?, ?, true)")?; + stmt.execute([page_name, page_text, ]) + }) + .await? + .map_err(error::ErrorInternalServerError) +} + diff --git a/src/lib.rs b/src/lib.rs index 2c7a8f3..da8829f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,4 @@ pub mod page; pub mod index; pub mod commons; -pub mod database; \ No newline at end of file +pub mod db; \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 2cb7592..bbaf1ee 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,9 @@ use actix_web::{web, App, HttpServer}; use actix_files; +use r2d2::Pool; +use r2d2_sqlite::{self, SqliteConnectionManager}; + use cheezenotes::commons::{Arguments, AppData}; use cheezenotes::{ page, index }; @@ -13,12 +16,13 @@ async fn main() -> std::io::Result<()> { let port = args.port; let root = args.root; + let manager = SqliteConnectionManager::file("db/db.sqlite3"); + let pool = Pool::new(manager).unwrap(); + let appdata = AppData { name: String::from("CheezeNotes"), root, - db_url: String::from(""), - db_user: String::from(""), - db_password: String::from(""), + pool: pool.clone(), }; HttpServer::new(move || { @@ -27,7 +31,6 @@ async fn main() -> std::io::Result<()> { .service(index::index) .service(page::page) .service(page::save_page) - //.service(page::page_link) .service(actix_files::Files::new("/static", "./static")) .service(actix_files::Files::new("/static/modules", "./static/modules")) }) diff --git a/src/page.rs b/src/page.rs index 8f04485..505199c 100644 --- a/src/page.rs +++ b/src/page.rs @@ -1,15 +1,15 @@ +use actix_web::http::header::ContentType; +use actix_web::{get, put, Responder}; use actix_web::{web, HttpResponse}; -use actix_web::{Responder, get, put}; +use serde::Deserialize; use std::fs; -use std::io::Write; -//use regex::Regex; use askama_actix::Template; use askama_actix::TemplateToResponse; use crate::commons::AppData; -//use crate::database::DatabaseConnection; +use crate::db; #[derive(Template)] #[template(path = "page.html")] @@ -20,60 +20,77 @@ pub struct PageTemplate { pub init: String, } +#[derive(Debug, Deserialize)] +struct QueryParams { + pub data: Option, +} + +async fn get_data(data: & web::Data, pagename: String) -> String { + let fut_page_datas = db::get_page_by_name(&data.pool, pagename.to_owned()); + let page_datas = fut_page_datas.await.unwrap(); + let md; + match page_datas.first() { + None => { + let filename = String::from("pages/") + pagename.as_str() + ".md"; + md = match fs::read_to_string(filename) { + Ok(txt) => { + db::update_page(&data.pool, pagename.to_owned(), txt.to_owned()) + .await + .unwrap(); + txt + } + Err(_) => String::from("# ") + pagename.replace("_", " ").as_str(), + }; + } + Some(dat) => md = (*dat.page_text).to_string(), + } + md +} + #[get("/page/{page}")] -async fn page(path: web::Path<(String,)>, data: web::Data) -> impl Responder { +async fn page( + path: web::Path<(String,)>, + data: web::Data, + params: web::Query, +) -> impl Responder { let pagename = &path.0; - let name = data.name.to_owned() + " " + pagename.as_str(); + + let md = get_data(&data, pagename.to_owned()).await; + + match ¶ms.data { + Some(_) => { + return HttpResponse::Ok() + .content_type(ContentType::plaintext()) + .body(md) + } + None => {} + } + + let name = data.name.to_owned() + " - " + pagename.as_str(); let root = data.root.to_owned(); - let filename = String::from("pages/") + pagename.as_str() + ".md"; - let md = match fs::read_to_string(filename) { - Ok(txt) => txt, - Err(_) => String::from("# Nouvelle page"), - }; - let init = String::from("init();"); - PageTemplate { name, root, md, init }.to_response() + //let init = String::from("init();"); + let init = format!("init();"); + PageTemplate { + name, + root, + md, + init, + } + .to_response() } #[put("/page/{page}")] -async fn save_page(body: String, path: web::Path<(String,)>) -> impl Responder { +async fn save_page( + body: String, + path: web::Path<(String,)>, + data: web::Data, +) -> impl Responder { let pagename = &path.0; - /*if pagename == "index" { + if pagename == "index" { return HttpResponse::Ok(); - }*/ - let filename = String::from("pages/") + pagename.as_str() + ".md"; - let mut file = match fs::File::create(&filename) { - Ok(f) => f, - Err(_) => return HttpResponse::Unauthorized(), - }; - match file.write_all(body.as_bytes()) { - Ok(_) => HttpResponse::Ok(), - Err(_) => HttpResponse::Unauthorized(), } + db::update_page(&data.pool, pagename.to_owned(), body) + .await + .unwrap(); + HttpResponse::Ok() } - -/*#[get("/page/{oldpage}/{page}")] -async fn page_link(path: web::Path<(String, String,)>, data: web::Data) -> impl Responder { - let pagename = &path.1; - let name = data.name.to_owned() + " " + pagename.as_str(); - let filename = String::from("pages/") + pagename.as_str() + ".md"; - let md = match fs::read_to_string(filename) { - Ok(txt) => txt, - Err(_) => String::from("# Nouvelle page"), - }; - let init = format!("init('{}')", pagename); - PageTemplate { name, md, init }.to_response() -}*/ - -/*fn normalize_pagename(pagename: String) -> Result { - let pagename = pagename.trim(); - - let space_re = Regex::new(r"[-\s]").unwrap(); - let pagename = &*space_re.replace_all(pagename, "_"); - - let re = Regex::new(r"").unwrap(); - if re.is_match(pagename) { - Ok(pagename.to_owned()) - } else { - Err(()) - } -}*/ \ No newline at end of file diff --git a/static/cheezenotes.css b/static/cheezenotes.css index c688075..1f0cacc 100644 --- a/static/cheezenotes.css +++ b/static/cheezenotes.css @@ -7,21 +7,11 @@ url(/static/MaterialIconsOutlined-Regular.otf) format('woff'); } -html { - font-family: system-ui; - font-size: 12pt; -} - -body { - margin: 0; - background-color: #f6f6f6; -} - .material-icons { font-family: 'Material Icons'; font-weight: normal; font-style: normal; - font-size: 20px; /* Preferred icon size */ + font-size: 22px; /* Preferred icon size */ display: inline-block; line-height: 1; text-transform: none; @@ -35,26 +25,71 @@ body { font-feature-settings: 'liga'; } +html { + font-family: system-ui; + font-size: 12pt; +} + +body { + margin: 0; + background-color: #dddddd; +} + +div#content { + position: absolute; + margin: 0; + padding: 0; + top: 0; + left: 0; + bottom: 0; + right: 0; + overflow: auto; +} + +div #margindiv { + max-width: 1200px; + margin-left: auto; + margin-right: auto; + top: 0; + bottom: 0; +} + +div#cheezenotes { + position: static; + margin: 0; + margin-top: 0; + margin-bottom: 3rem; + padding-top: 1rem; + padding-left: 3rem; + padding-right: 3rem; + padding-bottom: 1rem; + background-color: #ffffff; + min-height: 100%; + overflow-x: auto; +} + div#buttons { + position: sticky; white-space: nowrap; + overflow-x: auto; box-sizing: border-box; - padding: .2rem; - position: fixed; - background-color: #dddde5; + padding-top: .2rem; + padding-bottom: .2rem; + background-color: #dddddd; top: 0; left: 0; right: 0; margin-left: auto; margin-right: auto; - max-width: 1200; + max-width: 1200px; } div#buttons button.button { color: #444444; padding: 0; margin: 0; - height: 1.8rem; - width: 1.8rem; + height: 2.6rem; + width: 2.6rem; background-color: #eeeeee; border: 1px solid #cccccc; border-right: none; @@ -68,14 +103,15 @@ div#buttons button.separator { color: #bbbbbb; border: none; border-left: 1px solid #cccccc; - height: 1.8rem; + height: 2.6rem; margin: 0; padding: 0; } div#buttons button.text { + line-height: 1; color: #444444; - font-size: 16px; + font-size: 18px; vertical-align: bottom; } div#buttons button.text:disabled { @@ -108,7 +144,7 @@ div#buttons #lockButtonLabel { div.ta { margin-left: auto; margin-right: auto; - max-width: 1200; + max-width: 1200px; } textarea#ta { @@ -122,21 +158,6 @@ textarea#ta { background-color: #cceeff; } -div#cheezenotes { - margin-top: 2rem; - margin-left: auto; - margin-right: auto; - max-width: 1200; - padding-top: 1rem; - padding-left: 3rem; - padding-right: 3rem; - padding-bottom: 1rem; - margin-bottom: 3rem; - background-color: #ffffff; - min-height: 90%; - overflow-x: auto; -} - /*div#cheezenotes div.cheezenotes_line {*/ /* Pour firefox : white-space: pre; */ /*}*/ @@ -314,6 +335,7 @@ div#cheezenotes:focus div.cheezenotes_line span.token { div#cheezenotes div.body { margin-top: 0.5rem; + line-height: 1; margin-bottom: 0.5rem; } div#cheezenotes span.mono { diff --git a/static/cs.png b/static/cs.png new file mode 100644 index 0000000..adae08f Binary files /dev/null and b/static/cs.png differ diff --git a/static/modules/cheezenotes.js b/static/modules/cheezenotes.js index 9210c4a..3778801 100644 --- a/static/modules/cheezenotes.js +++ b/static/modules/cheezenotes.js @@ -118,15 +118,10 @@ function onsave(e) { let saveButton = document.getElementById('saveButton'); saveButton.disabled = true; let text = save(document.getElementById('ta'), document.getElementById('cheezenotes')); - var xhttp = new XMLHttpRequest(); - xhttp.onreadystatechange = function () { - if (this.readyState == 4 && this.status != 200) { - saveButton.disabled = false; - alert(xhttp.responseText); - } - } - xhttp.open("PUT", document.location.href, true); - xhttp.send(text); + fetch(document.location.href, { method: "PUT", body: text }).catch((error) => { + saveButton.disabled = false; + alert(error); + }) } function onload(e) { @@ -154,8 +149,10 @@ function onedit(e) { let prevline = line.previousSibling; if (prevline != null && prevline.innerText == '\n') { - prevline.className = 'cheezenotes_line'; - prevline.classList.add('body'); + /*prevline.className = 'cheezenotes_line'; + prevline.classList.add('body');*/ + let newline = formatLine(prevline.innerText); + prevline.parentNode.replaceChild(newline, prevline); } let newline = formatLine(line.innerText); @@ -336,11 +333,33 @@ function onfocus() { enableFormatButtons(); } -function init(pagename = null) { +function onpopstate(e) { + let top = 0; + let left = 0; + if (e.state.top) { + top = e.state.top; + } + if (e.state.left) { + left = e.state.left; + } + fetch(document.location.href + "?data=").then((response) => { + let ta = document.getElementById('ta'); + response.text().then((data) => { + ta.value = data; + load(document.getElementById('ta'), document.getElementById('cheezenotes')); + let content = document.getElementById('content'); + content.scrollTop = top; + content.scrollLeft = left; + }); + }).catch((error) => { alert(error); }); +} + +function init() { let cheezenotes = document.getElementById('cheezenotes'); dpwidth(cheezenotes); + window.addEventListener('popstate', onpopstate); cheezenotes.addEventListener('input', onedit); cheezenotes.addEventListener('keyup', onkeyup); cheezenotes.addEventListener('keypress', onkeypress); @@ -364,7 +383,7 @@ function init(pagename = null) { addButton('h1Button', 'H1', onh1button); addButton('h2Button', 'H2', onh2button); addButton('h3Button', 'H3', onh3button); - lastButton(addButton('bqButton', ':format_quote', onbqbutton)); + addButton('bqButton', ':format_quote', onbqbutton); addSeparator(); addOnOffButton('editModeButton', ':edit_note', ':visibility', function (e) { @@ -378,6 +397,13 @@ function init(pagename = null) { disableFormatButtons(); + /*if (pagename != null) { + fetch(pagename + "?data=").then((response) => { + let ta = document.getElementById('ta'); + response.text().then((data) => { ta.value = data; onload(); }); + }).catch((error) => { alert(error); }); + }*/ + onload(); } diff --git a/static/modules/md.js b/static/modules/md.js index 8baa3b3..203d130 100644 --- a/static/modules/md.js +++ b/static/modules/md.js @@ -32,7 +32,7 @@ function appendData(div, data) { newline = formatLine(lineBegin + lines[0]); line.parentNode.replaceChild(newline, line); let prevline = newline; - for(let i=1; i { alert(error); }); } return false; } else { @@ -106,7 +120,7 @@ function onlinkout(e) { let cheezenotes = document.getElementById('cheezenotes'); if (cheezenotes.contentEditable == 'false') { cheezenotes.contentEditable = true; - } + } } function formatLine(line) { @@ -205,7 +219,7 @@ function formatLine(line) { if (elem.getElementsByClassName('tablerow').length > 0) { if (elem.childNodes[0].childNodes.length > 0) { let child = elem.childNodes[0].childNodes[0]; - while(child != null) { + while (child != null) { if (child.nodeType == 3) { let newchild = document.createElement('span'); newchild.innerText = child.nodeValue; @@ -219,7 +233,7 @@ function formatLine(line) { elem.classList.add('tablerow'); } let links = elem.getElementsByClassName('link'); - for (let i=0; i`' + mono + '`' + line.substring(matches[i]+2, line.length); + line = line.substring(0, matches[i]) + '`' + mono + '`' + line.substring(matches[i] + 2, line.length); } return line; } @@ -471,7 +485,7 @@ function removeLink(line) { if (listLink == null) { return [line, null]; } - + line = line.replace(/(\[([^\]]*?)\]\(([^\)]*?)\))/g, "[]()"); return [line, listLink.reverse()]; } @@ -492,13 +506,14 @@ function addLink(line, listLink) { cpt++; } matches = matches.reverse(); - for(let i=0; i[!$2]($3)'); line = line.replace(/(\[([^\]]+?)\]\(([^\)]+?)\))/ig, '[$2]($3)'); line = line.replace(/(\[([^\]]+?)\]\(\))/ig, '[$2]()'); line = line.replace(/(\[\]\(([^\)]+?)\))/ig, '[]($2)'); diff --git a/templates/page.html b/templates/page.html index aec8917..618ccc3 100644 --- a/templates/page.html +++ b/templates/page.html @@ -1,30 +1,31 @@ - - - - - - - - - {{name}} - - - - -
- + + + + + + + + + + {{name}} + + + + + +
+
+
+
+
-
-
- - - +
+ + + + \ No newline at end of file