diff --git a/Cargo.lock b/Cargo.lock index 4530c42..97d66c0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -518,6 +518,7 @@ dependencies = [ "rusqlite", "serde", "serde_json", + "uuid 1.3.0", ] [[package]] @@ -2431,6 +2432,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1674845326ee10d37ca60470760d4288a6f80f304007d92e5c53bab78c9cfd79" dependencies = [ "getrandom", + "rand", "serde", ] diff --git a/Cargo.toml b/Cargo.toml index fc5bc06..5ab8a72 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,6 +9,8 @@ edition = "2021" clap = { version = "4.0.18", features = ["derive"] } +uuid = {version = "1.3.0", features=["v4", "fast-rng"]} + actix-web = "4" actix-files = "0.6.2" actix-session = { version = "0.7.2", features = ["cookie-session"] } diff --git a/db/db copy.sqlite3 b/db/db-sauve.sqlite3 similarity index 79% rename from db/db copy.sqlite3 rename to db/db-sauve.sqlite3 index a531d5d..2280fcd 100644 Binary files a/db/db copy.sqlite3 and b/db/db-sauve.sqlite3 differ diff --git a/db/db.sql b/db/db.sql index 13c5378..b5a5f3e 100644 --- a/db/db.sql +++ b/db/db.sql @@ -1,5 +1,11 @@ create table pages ( - page_name text primary key, + domain text, + page_name text, page_text text, - active boolean default true not null + active boolean default true not null, + primary key (domain, page_name) +); + +create table pages_histo ( + ); \ No newline at end of file diff --git a/db/db.sqlite3 b/db/db.sqlite3 index d4757bc..92f3030 100644 Binary files a/db/db.sqlite3 and b/db/db.sqlite3 differ diff --git a/pages/formation_ROA.md b/pages/formation_ROA.md new file mode 100644 index 0000000..567ec2a --- /dev/null +++ b/pages/formation_ROA.md @@ -0,0 +1,54 @@ +[retour](/BPCE-SI/BPCE-SI-Notes) +# formation ROA Devops et MCO +_le 16/03/2023_ +**formateur :** Jean-Marc Meunier +**Code projet (clarity) :** PR002611 +**Support :** +- [Documentation Myway ROA](https://confluence.f.bbg/display/MWROA/Documentation+Myway+ROA) +- [Modernisation PIC Myway ROA](https://confluence.f.bbg/display/MWROA/02-Modernisation+PIC+Myway+ROA) +## Objectif +**Devops :** Migrer les ressources ROA sur la nouvelle version de la plateforme. +- passage vers java 8 +- passer de tfs vers bitbucket +- changement d'installeur (XLR) +- changement de Jenkins +**MCO :** Maintenance en Condition Opérationnelle +## Ce qui change +- Jave 7 -> Java 8 +- JBOSS 6.4 -> 7 +- TFS -> Bitbucket +- Pack-it, install-it -> XLD, XLR +- Nexus -> Artifactory +- Sonar 7 -> Sonar 8, Checkmarx +## Pré-requis +### git +- `it config --global --list` +- **install git :** pulse SIT-PKG001 +- **config git :** user.name, user.email, désactiver la certification SSL +### Bitbucket +Créer un jeton bitbucket (nomprénom) en écriture du projjet et du dépôt (le password sera le jeton généré). **Ne pas perdre le jeton impossible de le consulter _a posteriori_** +- **nommage projet :** [CODE CIA]-[Techno(MYWAYROA)]-[CODE APPLICATION ARIS]-[DOMAINE-ARIS] +- **nommage ressource :** [BLOC APPLICATIF ARIS]-[API]-V[VERSION MAJEURE] +-- Chercher dans ls TFS dans le pom.xml ou dans Aris +Pour une création de dépôt, faire une demande +### Artifactory +[Artifcatory](https://artifactory.mycloud.intrabpce.fr/ui/) +- Créer également un jeton (consultable par la suite). +- `C:\Users\S0006310\.m2\settings.xml` dans server mettre le username et le jeton (password). +- Modifier les url pour la toolbox +### Configuration nouveau projet +- Créer le projet dans mycloud. +- Prévenir via un ticket **SIT-MYWAY004**. +- Prévenir la production applicative. +- Prévenir l'équipe XLR pour créer le template ou modifier le template existant. +- Configuration JBOSS +- Configuration Jenkins +## Migration d'une ressource +- Télécharger le zip de l'outil [GitTfs-0.31.0.zip](https://confluence.f.bbg/download/attachments/1258063573/GitTfs-0.31.0.zip?version=1&modificationDate=1613397108000&api=v2) +- paramétrer le PATH vers le répertoire d'install +- `git-tfs clone [source_TFS] [répertoire local git]` + +- récupérer l'outil sur artifactory pour la migration JBOSS [](https://artifactory.f.bbg/artifactory/CEH62-maven-releases/fr/itce/sie/myway/uld-ressource-migration) et copier le fichier *with-ressource* +- `call "D:\otoolbox-sie\Java\jdk1.8.0_151\bin\java.exe" -jar ".\uld-ressource-migration-x.y.z-jar-with-resources.jar" run -projectInput "D:\otoolbox-local\sources\CEF42-MYWAYROA-PTMYWAY-OUTINFR\PTMYWAYZ-OUTILSSIE-V2"` +- aller voir le fichier `outilssie-v3.csv` pour les logs +-- si pb, consulter la [migration manuelle](https://confluence.f.bbg/display/MWROA/02-Migration+manuelle) \ No newline at end of file diff --git a/src/commons.rs b/src/commons.rs index da976af..6e86091 100644 --- a/src/commons.rs +++ b/src/commons.rs @@ -13,6 +13,9 @@ pub struct Arguments { /// root of the url ending and starting with / #[arg(short, long, default_value_t = String::from("/"))] pub root: String, + /// sqlite database path + #[arg(short, long, default_value_t = String::from("db/db.sqlite3"))] + pub db: String, } impl Arguments { @@ -26,7 +29,7 @@ impl Arguments { #[derive(Clone)] pub struct AppData { - pub name: String, - pub root: String, - pub pool: Pool, + pub app_name: String, + pub base_url: String, + pub db_pool: Pool, } diff --git a/src/db.rs b/src/db.rs index 1dddb91..e1c6a2c 100644 --- a/src/db.rs +++ b/src/db.rs @@ -1,16 +1,55 @@ use actix_web::{error, web, Error}; use serde::{Deserialize, Serialize}; +use uuid::Uuid; pub type Pool = r2d2::Pool; pub type Connection = r2d2::PooledConnection; +#[allow(unused)] +fn uuid4() -> String { + let id = Uuid::new_v4(); + id.to_string() +} + #[derive(Debug, Serialize, Deserialize)] pub struct Page { + pub domain: String, pub page_name: String, pub page_text: String, } -pub async fn get_page_by_name(pool: &Pool, pagename: String) -> Result, Error> { +pub struct Domain { + pub domain: String, + pub domain_name: String, +} + +pub async fn get_domains(pool: &Pool) -> 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 distinct domain, REPLACE(domain, '_', ' ') from pages WHERE active=true order by domain")?; + + stmt.query_map([], |row| { + Ok(Domain { + domain: row.get(0)?, + domain_name: row.get(1)?, + }) + }) + .and_then(Iterator::collect) + }) + .await? + .map_err(error::ErrorInternalServerError) +} + +pub async fn get_page_by_name( + pool: &Pool, + domain: String, + pagename: String, +) -> Result, Error> { let pool = pool.clone(); let conn = web::block(move || pool.get()) @@ -19,12 +58,13 @@ pub async fn get_page_by_name(pool: &Pool, pagename: String) -> Result web::block(move || { let mut stmt = conn - .prepare("SELECT page_name, page_text from pages WHERE active=true and page_name=?")?; + .prepare("SELECT domain, page_name, page_text from pages WHERE active=true and domain=? and page_name=?")?; - stmt.query_map([pagename], |row| { + stmt.query_map([domain, pagename], |row| { Ok(Page { - page_name: row.get(0)?, - page_text: row.get(1)?, + domain: row.get(0)?, + page_name: row.get(1)?, + page_text: row.get(2)?, }) }) .and_then(Iterator::collect) @@ -33,7 +73,12 @@ pub async fn get_page_by_name(pool: &Pool, pagename: String) -> Result .map_err(error::ErrorInternalServerError) } -pub async fn update_page(pool: &Pool, page_name: String, page_text: String) -> Result { +pub async fn update_page( + pool: &Pool, + domain: String, + page_name: String, + page_text: String, +) -> Result { let pool = pool.clone(); let conn = web::block(move || pool.get()) @@ -42,10 +87,9 @@ pub async fn update_page(pool: &Pool, page_name: String, page_text: String) -> R 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, ]) + .prepare("insert or replace into pages (domain, page_name, page_text, active) values (?, ?, ?, true)")?; + stmt.execute([domain, page_name, page_text, ]) }) .await? .map_err(error::ErrorInternalServerError) } - diff --git a/src/index.rs b/src/index.rs index cd073d7..c52fff5 100644 --- a/src/index.rs +++ b/src/index.rs @@ -5,17 +5,23 @@ use askama_actix::Template; use askama_actix::TemplateToResponse; use crate::commons::AppData; +use crate::db; +use crate::db::Domain; #[derive(Template)] #[template(path = "index.html")] pub struct PageTemplate { - pub name: String, - pub root: String, + pub app_name: String, + pub base_url: String, + pub domains: Vec, } #[get("/")] async fn index(data: web::Data) -> impl Responder { - let name = data.name.to_owned(); - let root = data.root.to_owned(); - PageTemplate { name, root }.to_response() + let app_name = data.app_name.to_owned(); + let base_url = data.base_url.to_owned(); + + let domains = db::get_domains(&data.db_pool).await.unwrap(); + + PageTemplate { app_name, base_url, domains }.to_response() } \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index bbaf1ee..9a14f11 100644 --- a/src/main.rs +++ b/src/main.rs @@ -14,25 +14,26 @@ async fn main() -> std::io::Result<()> { let ip = args.ip; let port = args.port; - let root = args.root; + let base_url = args.root; + let db = args.db; - let manager = SqliteConnectionManager::file("db/db.sqlite3"); + let manager = SqliteConnectionManager::file(db); let pool = Pool::new(manager).unwrap(); let appdata = AppData { - name: String::from("CheezeNotes"), - root, - pool: pool.clone(), + app_name: String::from("CheezeNotes"), + base_url, + db_pool: pool.clone(), }; HttpServer::new(move || { App::new() .app_data(web::Data::new(appdata.to_owned())) .service(index::index) - .service(page::page) - .service(page::save_page) .service(actix_files::Files::new("/static", "./static")) .service(actix_files::Files::new("/static/modules", "./static/modules")) + .service(page::page) + .service(page::save_page) }) .bind((ip, port))? .run() diff --git a/src/page.rs b/src/page.rs index 505199c..24b4107 100644 --- a/src/page.rs +++ b/src/page.rs @@ -1,10 +1,9 @@ use actix_web::http::header::ContentType; +use actix_web::web::Query; use actix_web::{get, put, Responder}; use actix_web::{web, HttpResponse}; use serde::Deserialize; -use std::fs; - use askama_actix::Template; use askama_actix::TemplateToResponse; @@ -14,48 +13,57 @@ use crate::db; #[derive(Template)] #[template(path = "page.html")] pub struct PageTemplate { - pub name: String, - pub root: String, + pub app_name: String, + pub base_url: String, pub md: String, pub init: String, } #[derive(Debug, Deserialize)] +#[allow(non_snake_case)] struct QueryParams { pub data: Option, + pub fromDomain: Option, + pub fromPage: 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()); +fn new_page_text( + page_name: String, + domain_from: &Option, + page_from: &Option, +) -> String { + let mut retour = String::from(""); + if let (Some(domain_f), Some(page_f)) = (domain_from, page_from) { + retour = format!("[retour](/{}/{})\n", domain_f, page_f); + } + retour + "# " + page_name.replace("_", " ").as_str() +} + +async fn get_data( + data: &web::Data, + domain: String, + page_name: String, + params: &Query, +) -> String { + let fut_page_datas = + db::get_page_by_name(&data.db_pool, domain.to_owned(), page_name.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(), + None => new_page_text(page_name, ¶ms.fromDomain, ¶ms.fromPage), + Some(dat) => (*dat.page_text).to_string(), } - md } -#[get("/page/{page}")] +#[get("/{domain}/{page}")] async fn page( - path: web::Path<(String,)>, + path: web::Path<(String, String)>, data: web::Data, params: web::Query, ) -> impl Responder { - let pagename = &path.0; + let domain = &path.0; + let page_name = &path.1; - let md = get_data(&data, pagename.to_owned()).await; + let md = get_data(&data, domain.to_owned(), page_name.to_owned(), ¶ms).await; match ¶ms.data { Some(_) => { @@ -66,30 +74,31 @@ async fn page( None => {} } - let name = data.name.to_owned() + " - " + pagename.as_str(); - let root = data.root.to_owned(); + let app_name = data.app_name.to_owned() + " - " + page_name.as_str(); + let base_url = data.base_url.to_owned(); //let init = String::from("init();"); - let init = format!("init();"); + let init = format!("init({:?}, {:?});", domain, page_name); PageTemplate { - name, - root, + app_name, + base_url, md, init, } .to_response() } -#[put("/page/{page}")] +#[put("/{domain}/{page}")] async fn save_page( body: String, - path: web::Path<(String,)>, + path: web::Path<(String, String)>, data: web::Data, ) -> impl Responder { - let pagename = &path.0; + let domain = &path.0; + let pagename = &path.1; if pagename == "index" { return HttpResponse::Ok(); } - db::update_page(&data.pool, pagename.to_owned(), body) + db::update_page(&data.db_pool, domain.to_owned(), pagename.to_owned(), body) .await .unwrap(); HttpResponse::Ok() diff --git a/static/cheezenotes.css b/static/cheezenotes.css index 1f0cacc..1ec4f7f 100644 --- a/static/cheezenotes.css +++ b/static/cheezenotes.css @@ -35,6 +35,11 @@ body { background-color: #dddddd; } +p.domain { + padding-left: 2rem; + font-size: 2rem; +} + div#content { position: absolute; margin: 0; @@ -46,10 +51,12 @@ div#content { overflow: auto; } -div #margindiv { - max-width: 1200px; +div#margindiv { + /*max-width: 1600px; margin-left: auto; - margin-right: auto; + margin-right: auto;*/ + margin-left: .5rem; + margin-right: .5rem; top: 0; bottom: 0; } @@ -60,8 +67,8 @@ div#cheezenotes { margin-top: 0; margin-bottom: 3rem; padding-top: 1rem; - padding-left: 3rem; - padding-right: 3rem; + padding-left: 1rem; + padding-right: 1rem; padding-bottom: 1rem; background-color: #ffffff; min-height: 100%; @@ -79,9 +86,11 @@ div#buttons { top: 0; left: 0; right: 0; + /*margin-left: .5rem; + margin-right: .5rem; margin-left: auto; margin-right: auto; - max-width: 1200px; + max-width: 1600px;*/ } div#buttons button.button { @@ -142,14 +151,16 @@ div#buttons #lockButtonLabel { } div.ta { - margin-left: auto; + margin-left: .5rem; + margin-right: .5rem; + /*margin-left: auto; margin-right: auto; - max-width: 1200px; + max-width: 1600px;*/ } textarea#ta { position: relative; - top: 3rem; + top: 0; display: none; width: 100%; height: 15rem; @@ -171,6 +182,10 @@ div#cheezenotes:focus { outline: none; } +div#cheezenotes input.checkbox { + vertical-align: bottom; +} + div#cheezenotes div.line { border-bottom: 1px solid #dddddd; padding-top: 0rem; @@ -321,16 +336,17 @@ div#cheezenotes div.lasttablerow span.tablerow { div#cheezenotes div.cheezenotes_line span.token { font-weight: 1; - color: #1353b3; + color: transparent; overflow: hidden; -} - -div#cheezenotes div.cheezenotes_line span.token { font-size: 0; + vertical-align: baseline; + /*transition-property: font-size, color; + transition-duration: .2s;*/ } div#cheezenotes:focus div.cheezenotes_line span.token { - font-size: 95%; + color: #1353b3; + font-size: 90%; } div#cheezenotes div.body { diff --git a/static/modules/caret.js b/static/modules/caret.js index 6bab702..2cd6146 100644 --- a/static/modules/caret.js +++ b/static/modules/caret.js @@ -1,3 +1,18 @@ +function insertAtLineStart(txtBefore) { + let ret = saveSelection(); + let line = ret[0]; + let txt = line.innerText; + if (txt == '\n') { + txt = ""; + } + line.innerHTML = txtBefore + txt; + let span = document.createElement('span'); + span.innerHTML = txtBefore; + ret[1] = ret[1] + span.innerText.length;; + ret[3] = ret[3] + span.innerText.length;; + loadSelection(ret); +} + function insertTextAtCaret(txtBefore, txtAfter = '') { let ret = saveSelection(); let line = ret[0]; @@ -190,4 +205,4 @@ function setEndPositionInText(obj, position) { return 0; } -export { saveSelection, loadSelection, insertTextAtCaret }; \ No newline at end of file +export { saveSelection, loadSelection, insertTextAtCaret, insertAtLineStart }; \ No newline at end of file diff --git a/static/modules/cheezenotes.js b/static/modules/cheezenotes.js index 3778801..b81f16f 100644 --- a/static/modules/cheezenotes.js +++ b/static/modules/cheezenotes.js @@ -1,13 +1,13 @@ -import { saveSelection, loadSelection, insertTextAtCaret } from './caret.js'; +import { saveSelection, loadSelection, insertTextAtCaret, insertAtLineStart } from './caret.js'; import { formatLine, load, save, formatTable, redrawTables, appendData, dpwidth } from './md.js'; const showtokens = [ { fontSize: 0 }, - { fontSize: '95%' } + { fontSize: '90%' } ]; const hidetokens = [ - { fontSize: '95%' }, + { fontSize: '90%' }, { fontSize: 0 } ]; @@ -21,14 +21,14 @@ function timeoutSave() { function showTokens() { let tokens = document.getElementsByClassName('token'); for (let i = 0; i < tokens.length; i++) { - tokens[i].animate(showtokens, { duration: 200, iterations: 1 }); + tokens[i].animate(showtokens, { duration: 50, iterations: 1 }); } } function hideTokens() { let tokens = document.getElementsByClassName('token'); for (let i = 0; i < tokens.length; i++) { - tokens[i].animate(hidetokens, { duration: 200, iterations: 1 }); + tokens[i].animate(hidetokens, { duration: 50, iterations: 1 }); } } @@ -82,7 +82,12 @@ function onh1button(e) { e.preventDefault(); let cheezenotes = document.getElementById('cheezenotes'); cheezenotes.focus(); - insertTextAtCaret('#', ''); + let sel = saveSelection(); + if (sel[0].classList.contains('h')) { + return false; + } else { + insertAtLineStart('# '); + } onedit(e); return false; } @@ -91,7 +96,12 @@ function onh2button(e) { e.preventDefault(); let cheezenotes = document.getElementById('cheezenotes'); cheezenotes.focus(); - insertTextAtCaret('##', ''); + let sel = saveSelection(); + if (sel[0].classList.contains('h')) { + return false; + } else { + insertAtLineStart('## '); + } onedit(e); return false; } @@ -100,7 +110,12 @@ function onh3button(e) { e.preventDefault(); let cheezenotes = document.getElementById('cheezenotes'); cheezenotes.focus(); - insertTextAtCaret('###', ''); + let sel = saveSelection(); + if (sel[0].classList.contains('h')) { + return false; + } else { + insertAtLineStart('### '); + } onedit(e); return false; } @@ -215,19 +230,6 @@ function oncopy(e) { //alert(e.clipboardData.getData('text/plain')); } -function onlockbutton(e) { - let lockButton = document.getElementById('lockButton'); - let lockButtonLabel = document.getElementById('lockButtonLabel'); - let cheezenotes = document.getElementById('cheezenotes'); - if (lockButton.checked) { - cheezenotes.contentEditable = false; - lockButtonLabel.innerText = 'visibility'; - } else { - cheezenotes.contentEditable = true; - lockButtonLabel.innerText = 'visibility_off'; - } -} - function ondrag(e) { // alert('drag'); } @@ -327,7 +329,7 @@ function onblur(e) { disableFormatButtons(); } -function onfocus() { +function onfocus(e) { redrawTables(cheezenotes, dpwidth()); showTokens(); enableFormatButtons(); @@ -354,8 +356,10 @@ function onpopstate(e) { }).catch((error) => { alert(error); }); } -function init() { +function init(domain, page) { let cheezenotes = document.getElementById('cheezenotes'); + window.domain = domain; + window.page = page; dpwidth(cheezenotes); diff --git a/static/modules/md.js b/static/modules/md.js index 203d130..f7b5529 100644 --- a/static/modules/md.js +++ b/static/modules/md.js @@ -1,5 +1,15 @@ import { saveSelection, loadSelection } from "./caret.js"; +function setEditable() { + let editModeButton = document.getElementById('editModeButton'); + let cheezenotes = document.getElementById('cheezenotes'); + if (editModeButton.classList.contains('buttonoff')) { + cheezenotes.contentEditable = false; + } else { + cheezenotes.contentEditable = true; + } +} + function load(textarea, div) { div.innerHTML = ''; let lines = textarea.value.split('\n'); @@ -89,22 +99,37 @@ function onlink(e) { let cheezenotes = document.getElementById('cheezenotes'); if (cheezenotes.contentEditable == 'false') { e.preventDefault(); - cheezenotes.contentEditable = true; + setEditable(); let link = e.currentTarget; if (link.host !== document.location.host) { open(link.href); } else { - //open(link.href, '_self'); - fetch(link.href + "?data=").then((response) => { + fetch(link.href + '?data=&fromDomain=' + window.domain + '&fromPage=' + window.page).then((response) => { let ta = document.getElementById('ta'); response.text().then((data) => { let content = document.getElementById('content'); let left = content.scrollLeft; let top = content.scrollTop; - window.history.replaceState({top: top, left: left}, ""); + window.history.replaceState({ top: top, left: left }, ""); window.history.pushState({}, "", link.href); + document.title = 'CheezeNotes - ' + link.getAttribute('data-href'); ta.value = data; - load(document.getElementById('ta'), document.getElementById('cheezenotes')); + let url = link.getAttribute('data-href').split('/'); + let page = url[0]; + let domain = window.domain; + if (url.length == 3) { + domain = url[1]; + page = url[2]; + } + window.domain = domain; + window.page = page; + load(document.getElementById('ta'), cheezenotes); + + /*let editModeButton = document.getElementById('editModeButton'); + if (editModeButton.classList.contains('buttonoff')) { + let cheezenotes = document.getElementById('cheezenotes'); + cheezenotes.contentEditable = false; + }*/ content.scrollTop = 0; content.scrollLeft = 0; }); @@ -119,7 +144,7 @@ function onlink(e) { function onlinkout(e) { let cheezenotes = document.getElementById('cheezenotes'); if (cheezenotes.contentEditable == 'false') { - cheezenotes.contentEditable = true; + setEditable(); } } @@ -149,21 +174,27 @@ function formatLine(line) { } else if (line.match(/^\s*######(\s|$)/i)) { token = /^(\s*######(\s|$))/i; elem.classList.add('h6'); + elem.classList.add('h'); } else if (line.match(/^\s*#####(\s|$)/i)) { token = /^(\s*#####(\s|$))/i; elem.classList.add('h5'); + elem.classList.add('h'); } else if (line.match(/^\s*####(\s|$)/i)) { token = /^(\s*####(\s|$))/i; elem.classList.add('h4'); + elem.classList.add('h'); } else if (line.match(/^\s*###(\s|$)/i)) { token = /^(\s*###(\s|$))/i; elem.classList.add('h3'); + elem.classList.add('h'); } else if (line.match(/^\s*##(\s|$)/)) { token = /^(\s*##(\s|$))/i; elem.classList.add('h2'); + elem.classList.add('h'); } else if (line.match(/^\s*#(\s|$)/i)) { token = /^(\s*#(\s|$))/i; elem.classList.add('h1'); + elem.classList.add('h'); } else if (line.match(/^\s*>\s*>\s*>(\s|$)/i)) { token = /^(\s*>\s*>\s*>(\s|$))/i; elem.classList.add('bq3'); @@ -176,6 +207,14 @@ function formatLine(line) { token = /^(\s*>(\s|$))/i; elem.classList.add('bq1'); elem.classList.add('bq'); + } else if (line.match(/^\s*\[[xXvV]?\]\s+/i)) { + //token = /^(\s*\[[xXvV]?\]\s+)/i; + let checked = ''; + if (line.match(/^\s*\[[xXvV]\]\s+/i)) { + checked = ' checked="checked"'; + } + line = line.replace(/^(\s*\[[xXvV]?\]\s+)/i, '$1') + elem.classList.add('checkbox'); } else { elem.classList.add('body'); } @@ -512,12 +551,37 @@ function addLink(line, listLink) { return line; } -function formatLink(line) { - line = line.replace(/(\[!([^\]]*?)\]\(([^\)]+?)\))/ig, '[!$2]($3)'); - line = line.replace(/(\[([^\]]+?)\]\(([^\)]+?)\))/ig, '[$2]($3)'); - line = line.replace(/(\[([^\]]+?)\]\(\))/ig, '[$2]()'); - line = line.replace(/(\[\]\(([^\)]+?)\))/ig, '[]($2)'); - return line; +/*function formatLink(link) { + link = link.replace(/(\[!([^\]]*?)\]\(([^\)]+?)\))/i, '[!$2]($3)'); + link = link.replace(/(\[([^\]]+?)\]\(([^\)]+?)\))/i, '[$2]($3)'); + link = link.replace(/(\[([^\]]+?)\]\(\))/i, '[$2]()'); + link = link.replace(/(\[\]\(([^\)]+?)\))/i, '[]($2)'); + return link; +}*/ + +function formatLink(link) { + let matches = link.match(/\[(.*)\]\((.*)\)/); + let libelle = matches[1]; + let url = matches[2]; + if (url == '' && libelle == '') { + return link; + } + let href = url; + if (href == '') { + href = libelle; + } + if (href.match(/^[^\:\/]+\/.*$/)) { + href = '/' + href; + } + if (libelle == '') { + return '[](' + url + ')'; + } else { + if (libelle.startsWith('!')) { + return '[' + libelle + '](' + url + ')'; + } else { + return '[' + libelle + '](' + url + ')'; + } + } } function addBold(line) { diff --git a/templates/index.html b/templates/index.html index de55b3f..c2448ee 100644 --- a/templates/index.html +++ b/templates/index.html @@ -7,10 +7,13 @@ - {{name}} - + {{app_name}} + -

+

{{app_name}}

+ {% for domain in domains %} +

{{ domain.domain_name }}

+ {% endfor %} diff --git a/templates/page.html b/templates/page.html index 618ccc3..57d124e 100644 --- a/templates/page.html +++ b/templates/page.html @@ -9,9 +9,9 @@ - {{name}} - - + {{app_name}} + + @@ -23,7 +23,7 @@