corrections diverses

pull/25/head
Nicolas Sanchez 3 years ago
parent c3f404534a
commit abc51ad87c

2
Cargo.lock generated

@ -518,6 +518,7 @@ dependencies = [
"rusqlite", "rusqlite",
"serde", "serde",
"serde_json", "serde_json",
"uuid 1.3.0",
] ]
[[package]] [[package]]
@ -2431,6 +2432,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1674845326ee10d37ca60470760d4288a6f80f304007d92e5c53bab78c9cfd79" checksum = "1674845326ee10d37ca60470760d4288a6f80f304007d92e5c53bab78c9cfd79"
dependencies = [ dependencies = [
"getrandom", "getrandom",
"rand",
"serde", "serde",
] ]

@ -9,6 +9,8 @@ edition = "2021"
clap = { version = "4.0.18", features = ["derive"] } clap = { version = "4.0.18", features = ["derive"] }
uuid = {version = "1.3.0", features=["v4", "fast-rng"]}
actix-web = "4" actix-web = "4"
actix-files = "0.6.2" actix-files = "0.6.2"
actix-session = { version = "0.7.2", features = ["cookie-session"] } actix-session = { version = "0.7.2", features = ["cookie-session"] }

@ -4,4 +4,8 @@ create table pages (
page_text text, page_text text,
active boolean default true not null, active boolean default true not null,
primary key (domain, page_name) primary key (domain, page_name)
);
create table pages_histo (
); );

Binary file not shown.

@ -29,7 +29,7 @@ impl Arguments {
#[derive(Clone)] #[derive(Clone)]
pub struct AppData { pub struct AppData {
pub name: String, pub app_name: String,
pub root: String, pub base_url: String,
pub pool: Pool<SqliteConnectionManager>, pub db_pool: Pool<SqliteConnectionManager>,
} }

@ -1,9 +1,16 @@
use actix_web::{error, web, Error}; use actix_web::{error, web, Error};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use uuid::Uuid;
pub type Pool = r2d2::Pool<r2d2_sqlite::SqliteConnectionManager>; pub type Pool = r2d2::Pool<r2d2_sqlite::SqliteConnectionManager>;
pub type Connection = r2d2::PooledConnection<r2d2_sqlite::SqliteConnectionManager>; pub type Connection = r2d2::PooledConnection<r2d2_sqlite::SqliteConnectionManager>;
#[allow(unused)]
fn uuid4() -> String {
let id = Uuid::new_v4();
id.to_string()
}
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
pub struct Page { pub struct Page {
pub domain: String, pub domain: String,
@ -11,7 +18,38 @@ pub struct Page {
pub page_text: String, pub page_text: String,
} }
pub async fn get_page_by_name(pool: &Pool, domain: String, pagename: String) -> Result<Vec<Page>, Error> { pub struct Domain {
pub domain: String,
pub domain_name: String,
}
pub async fn get_domains(pool: &Pool) -> Result<Vec<Domain>, 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<Vec<Page>, Error> {
let pool = pool.clone(); let pool = pool.clone();
let conn = web::block(move || pool.get()) let conn = web::block(move || pool.get())
@ -35,7 +73,12 @@ pub async fn get_page_by_name(pool: &Pool, domain: String, pagename: String) ->
.map_err(error::ErrorInternalServerError) .map_err(error::ErrorInternalServerError)
} }
pub async fn update_page(pool: &Pool, domain: String, page_name: String, page_text: String) -> Result<usize, Error> { pub async fn update_page(
pool: &Pool,
domain: String,
page_name: String,
page_text: String,
) -> Result<usize, Error> {
let pool = pool.clone(); let pool = pool.clone();
let conn = web::block(move || pool.get()) let conn = web::block(move || pool.get())

@ -5,17 +5,23 @@ use askama_actix::Template;
use askama_actix::TemplateToResponse; use askama_actix::TemplateToResponse;
use crate::commons::AppData; use crate::commons::AppData;
use crate::db;
use crate::db::Domain;
#[derive(Template)] #[derive(Template)]
#[template(path = "index.html")] #[template(path = "index.html")]
pub struct PageTemplate { pub struct PageTemplate {
pub name: String, pub app_name: String,
pub root: String, pub base_url: String,
pub domains: Vec<Domain>,
} }
#[get("/")] #[get("/")]
async fn index(data: web::Data<AppData>) -> impl Responder { async fn index(data: web::Data<AppData>) -> impl Responder {
let name = data.name.to_owned(); let app_name = data.app_name.to_owned();
let root = data.root.to_owned(); let base_url = data.base_url.to_owned();
PageTemplate { name, root }.to_response()
let domains = db::get_domains(&data.db_pool).await.unwrap();
PageTemplate { app_name, base_url, domains }.to_response()
} }

@ -14,16 +14,16 @@ async fn main() -> std::io::Result<()> {
let ip = args.ip; let ip = args.ip;
let port = args.port; let port = args.port;
let root = args.root; let base_url = args.root;
let db = args.db; let db = args.db;
let manager = SqliteConnectionManager::file(db); let manager = SqliteConnectionManager::file(db);
let pool = Pool::new(manager).unwrap(); let pool = Pool::new(manager).unwrap();
let appdata = AppData { let appdata = AppData {
name: String::from("CheezeNotes"), app_name: String::from("CheezeNotes"),
root, base_url,
pool: pool.clone(), db_pool: pool.clone(),
}; };
HttpServer::new(move || { HttpServer::new(move || {

@ -1,4 +1,5 @@
use actix_web::http::header::ContentType; use actix_web::http::header::ContentType;
use actix_web::web::Query;
use actix_web::{get, put, Responder}; use actix_web::{get, put, Responder};
use actix_web::{web, HttpResponse}; use actix_web::{web, HttpResponse};
use serde::Deserialize; use serde::Deserialize;
@ -12,36 +13,49 @@ use crate::db;
#[derive(Template)] #[derive(Template)]
#[template(path = "page.html")] #[template(path = "page.html")]
pub struct PageTemplate { pub struct PageTemplate {
pub name: String, pub app_name: String,
pub root: String, pub base_url: String,
pub md: String, pub md: String,
pub init: String, pub init: String,
} }
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[allow(non_snake_case)]
struct QueryParams { struct QueryParams {
pub data: Option<String>, pub data: Option<String>,
pub fromDomain: Option<String>,
pub fromPage: Option<String>,
} }
async fn get_data(data: & web::Data<AppData>, domain: String, page_name: String) -> String { fn new_page_text(page_name: String, domain_from: &Option<String>, page_from: &Option<String>) -> String {
let fut_page_datas = db::get_page_by_name(&data.pool, domain.to_owned(), page_name.to_owned()); let mut retour = String::from("");
if let Some(domain_f) = domain_from {
if let Some(page_f) = page_from {
retour = format!("[retour](/{}/{})\n", domain_f, page_f);
}
}
retour + "# " + page_name.replace("_", " ").as_str()
}
async fn get_data(data: &web::Data<AppData>, domain: String, page_name: String, params: &Query<QueryParams>) -> 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 page_datas = fut_page_datas.await.unwrap();
match page_datas.first() { match page_datas.first() {
None => String::from("# ") + page_name.replace("_", " ").as_str(), None => new_page_text(page_name, &params.fromDomain, &params.fromPage),
Some(dat) => (*dat.page_text).to_string(), Some(dat) => (*dat.page_text).to_string(),
} }
} }
#[get("/{domain}/{page}")] #[get("/{domain}/{page}")]
async fn page( async fn page(
path: web::Path<(String, String,)>, path: web::Path<(String, String)>,
data: web::Data<AppData>, data: web::Data<AppData>,
params: web::Query<QueryParams>, params: web::Query<QueryParams>,
) -> impl Responder { ) -> impl Responder {
let domain = &path.0; let domain = &path.0;
let page_name = &path.1; let page_name = &path.1;
let md = get_data(&data, domain.to_owned(), page_name.to_owned()).await; let md = get_data(&data, domain.to_owned(), page_name.to_owned(), &params).await;
match &params.data { match &params.data {
Some(_) => { Some(_) => {
@ -52,13 +66,13 @@ async fn page(
None => {} None => {}
} }
let name = data.name.to_owned() + " - " + page_name.as_str(); let app_name = data.app_name.to_owned() + " - " + page_name.as_str();
let root = data.root.to_owned(); let base_url = data.base_url.to_owned();
//let init = String::from("init();"); //let init = String::from("init();");
let init = format!("init();"); let init = format!("init({:?}, {:?});", domain, page_name);
PageTemplate { PageTemplate {
name, app_name,
root, base_url,
md, md,
init, init,
} }
@ -76,7 +90,7 @@ async fn save_page(
if pagename == "index" { if pagename == "index" {
return HttpResponse::Ok(); return HttpResponse::Ok();
} }
db::update_page(&data.pool, domain.to_owned(), pagename.to_owned(), body) db::update_page(&data.db_pool, domain.to_owned(), pagename.to_owned(), body)
.await .await
.unwrap(); .unwrap();
HttpResponse::Ok() HttpResponse::Ok()

@ -35,6 +35,11 @@ body {
background-color: #dddddd; background-color: #dddddd;
} }
p.domain {
padding-left: 2rem;
font-size: 2rem;
}
div#content { div#content {
position: absolute; position: absolute;
margin: 0; margin: 0;
@ -47,9 +52,11 @@ div#content {
} }
div#margindiv { div#margindiv {
max-width: 1200px; /*max-width: 1600px;
margin-left: auto; margin-left: auto;
margin-right: auto; margin-right: auto;*/
margin-left: .5rem;
margin-right: .5rem;
top: 0; top: 0;
bottom: 0; bottom: 0;
} }
@ -60,8 +67,8 @@ div#cheezenotes {
margin-top: 0; margin-top: 0;
margin-bottom: 3rem; margin-bottom: 3rem;
padding-top: 1rem; padding-top: 1rem;
padding-left: 3rem; padding-left: 1rem;
padding-right: 3rem; padding-right: 1rem;
padding-bottom: 1rem; padding-bottom: 1rem;
background-color: #ffffff; background-color: #ffffff;
min-height: 100%; min-height: 100%;
@ -79,9 +86,11 @@ div#buttons {
top: 0; top: 0;
left: 0; left: 0;
right: 0; right: 0;
/*margin-left: .5rem;
margin-right: .5rem;
margin-left: auto; margin-left: auto;
margin-right: auto; margin-right: auto;
max-width: 1200px; max-width: 1600px;*/
} }
div#buttons button.button { div#buttons button.button {
@ -142,9 +151,11 @@ div#buttons #lockButtonLabel {
} }
div.ta { div.ta {
margin-left: auto; margin-left: .5rem;
margin-right: .5rem;
/*margin-left: auto;
margin-right: auto; margin-right: auto;
max-width: 1200px; max-width: 1600px;*/
} }
textarea#ta { textarea#ta {
@ -171,6 +182,10 @@ div#cheezenotes:focus {
outline: none; outline: none;
} }
div#cheezenotes input.checkbox {
vertical-align: bottom;
}
div#cheezenotes div.line { div#cheezenotes div.line {
border-bottom: 1px solid #dddddd; border-bottom: 1px solid #dddddd;
padding-top: 0rem; padding-top: 0rem;

@ -356,8 +356,10 @@ function onpopstate(e) {
}).catch((error) => { alert(error); }); }).catch((error) => { alert(error); });
} }
function init() { function init(domain, page) {
let cheezenotes = document.getElementById('cheezenotes'); let cheezenotes = document.getElementById('cheezenotes');
window.domain = domain;
window.page = page;
dpwidth(cheezenotes); dpwidth(cheezenotes);

@ -104,7 +104,7 @@ function onlink(e) {
if (link.host !== document.location.host) { if (link.host !== document.location.host) {
open(link.href); open(link.href);
} else { } else {
fetch(link.href + "?data=").then((response) => { fetch(link.href + '?data=&fromDomain=' + window.domain + '&fromPage=' + window.page).then((response) => {
let ta = document.getElementById('ta'); let ta = document.getElementById('ta');
response.text().then((data) => { response.text().then((data) => {
let content = document.getElementById('content'); let content = document.getElementById('content');
@ -114,6 +114,15 @@ function onlink(e) {
window.history.pushState({}, "", link.href); window.history.pushState({}, "", link.href);
document.title = 'CheezeNotes - ' + link.getAttribute('data-href'); document.title = 'CheezeNotes - ' + link.getAttribute('data-href');
ta.value = data; ta.value = data;
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); load(document.getElementById('ta'), cheezenotes);
/*let editModeButton = document.getElementById('editModeButton'); /*let editModeButton = document.getElementById('editModeButton');
@ -198,6 +207,14 @@ function formatLine(line) {
token = /^(\s*>(\s|$))/i; token = /^(\s*>(\s|$))/i;
elem.classList.add('bq1'); elem.classList.add('bq1');
elem.classList.add('bq'); 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, '<input class="checkbox" type="checkbox"' + checked + '><span class="token">$1</span></input>')
elem.classList.add('checkbox');
} else { } else {
elem.classList.add('body'); elem.classList.add('body');
} }
@ -534,12 +551,37 @@ function addLink(line, listLink) {
return line; return line;
} }
function formatLink(line) { /*function formatLink(link) {
line = line.replace(/(\[!([^\]]*?)\]\(([^\)]+?)\))/ig, '<span class="token">[!</span><img style="vertical-align: top; max-height: 1rem;" class="image" src="$3">$2</img><span class="token">]($3)</span>'); link = link.replace(/(\[!([^\]]*?)\]\(([^\)]+?)\))/i, '<span class="token">[!</span><img style="vertical-align: top; max-height: 1rem;" class="image" src="$3">$2</img><span class="token">]($3)</span>');
line = line.replace(/(\[([^\]]+?)\]\(([^\)]+?)\))/ig, '<span class="token">[</span><a class="link" data-href="$3" href="$3">$2</a><span class="token">]($3)</span>'); link = link.replace(/(\[([^\]]+?)\]\(([^\)]+?)\))/i, '<span class="token">[</span><a class="link" data-href="$3" href="$3">$2</a><span class="token">]($3)</span>');
line = line.replace(/(\[([^\]]+?)\]\(\))/ig, '<span class="token">[</span><a class="link" data-href="$2" href="$2">$2</a><span class="token">]()</span>'); link = link.replace(/(\[([^\]]+?)\]\(\))/i, '<span class="token">[</span><a class="link" data-href="$2" href="$2">$2</a><span class="token">]()</span>');
line = line.replace(/(\[\]\(([^\)]+?)\))/ig, '<span class="token">[](</span><a class="link" data-href="$2" href="$2">$2</a><span class="token">)</span>'); link = link.replace(/(\[\]\(([^\)]+?)\))/i, '<span class="token">[](</span><a class="link" data-href="$2" href="$2">$2</a><span class="token">)</span>');
return line; 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 '<span class="token">[](</span><a class="link" data-href="' + href + '" href="' + href + '">' + url + '</a><span class="token">)</span>';
} else {
if (libelle.startsWith('!')) {
return '<span class="token">[' + libelle + '</span><img style="vertical-align: top; max-height: 1rem;" class="image" src="' + href + '" title="' + libelle.substring(1) + '" /><span class="token">](' + url + ')</span>';
} else {
return '<span class="token">[</span><a class="link" data-href="' + href + '" href="' + href + '">' + libelle + '</a><span class="token">](' + url + ')</span>';
}
}
} }
function addBold(line) { function addBold(line) {

@ -7,10 +7,13 @@
<meta name="apple-mobile-web-app-capable" content="yes"> <meta name="apple-mobile-web-app-capable" content="yes">
<meta name="mobile-web-app-capable" content="yes"> <meta name="mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black"> <meta name="apple-mobile-web-app-status-bar-style" content="black">
<title>{{name}}</title> <title>{{app_name}}</title>
<link rel="stylesheet" href="{{ root|safe }}static/cheezenotes.css"> <link rel="stylesheet" href="{{ base_url|safe }}static/cheezenotes.css">
</head> </head>
<body> <body>
<h1></h1> <h1>{{app_name}}</h1>
{% for domain in domains %}
<p class="domain"><a href="{{ base_url|safe }}{{ domain.domain }}">{{ domain.domain_name }}</a></p>
{% endfor %}
</body> </body>
</html> </html>

@ -9,9 +9,9 @@
<meta name="apple-mobile-web-app-capable" content="yes"> <meta name="apple-mobile-web-app-capable" content="yes">
<meta name="mobile-web-app-capable" content="yes"> <meta name="mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black"> <meta name="apple-mobile-web-app-status-bar-style" content="black">
<title>{{name}}</title> <title>{{app_name}}</title>
<link rel="stylesheet" href="{{ root|safe }}static/cheezenotes.css"> <link rel="stylesheet" href="{{ base_url|safe }}static/cheezenotes.css">
<script type="module" src="{{ root|safe }}static/modules/cheezenotes.js"></script> <script type="module" src="{{ base_url|safe }}static/modules/cheezenotes.js"></script>
</head> </head>
<body> <body>
@ -23,7 +23,7 @@
</div> </div>
</div> </div>
<script type="module"> <script type="module">
import { init } from '{{ root|safe }}static/modules/cheezenotes.js'; import { init } from '{{ base_url|safe }}static/modules/cheezenotes.js';
{{ init|safe }} {{ init|safe }}
</script> </script>
</body> </body>

Loading…
Cancel
Save