From 7d44eb781e2d0ca57bb8d4a139e4a3af5cf554d0 Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Mon, 1 May 2023 18:35:55 +0200 Subject: [PATCH] [0.10.5] - sitemap, bash-autocompletion... --- debian/control | 2 +- src/usr/bin/tyto | 40 +-- .../share/bash-completion/completions/tyto | 282 ++++++++++++++++++ src/var/lib/tyto/help/CHANGELOG.md | 26 +- src/var/lib/tyto/help/README.md | 177 +++++++---- src/var/lib/tyto/help/styles.css | 54 ++-- src/var/lib/tyto/program/args.py | 18 +- src/var/lib/tyto/program/check.py | 47 +-- src/var/lib/tyto/program/creators.py | 185 ++++++++++++ src/var/lib/tyto/program/db.py | 1 + src/var/lib/tyto/program/dom.py | 4 +- src/var/lib/tyto/program/form.py | 51 +--- src/var/lib/tyto/program/html.py | 4 +- src/var/lib/tyto/program/new.py | 5 +- src/var/lib/tyto/program/publish.py | 26 +- src/var/lib/tyto/program/show.py | 10 - src/var/lib/tyto/program/tyto.py | 239 +++++++++++---- src/var/lib/tyto/program/wip.py | 23 +- src/var/lib/tyto/translations/site_en.py | 33 +- src/var/lib/tyto/translations/site_fr.py | 37 +-- 20 files changed, 964 insertions(+), 300 deletions(-) create mode 100755 src/usr/share/bash-completion/completions/tyto create mode 100644 src/var/lib/tyto/program/creators.py diff --git a/debian/control b/debian/control index 0987457..8ab667a 100644 --- a/debian/control +++ b/debian/control @@ -1,5 +1,5 @@ Package: tyto -Version: 0.10.4 +Version: 0.10.5 Section: custom Priority: optional Architecture: all diff --git a/src/usr/bin/tyto b/src/usr/bin/tyto index f5781b3..e8dd46f 100755 --- a/src/usr/bin/tyto +++ b/src/usr/bin/tyto @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Version: 0.10.4 +# Version: 0.10.5 # Tyto - Littérateur # # Copyright (C) 2023 Cyrille Louarn @@ -62,25 +62,27 @@ status.domain() # Command start argument -import check, form, html, new, publish, show, wip, infos +import check, form, html, new, publish, show, wip, infos, creators actions = { - 'check' : check.manage, - 'help' : infos.tyto, - 'edit' : show.manage, - 'edit-about' : show.manage, - 'edit-db' : show.manage, - 'edit-wip' : show.manage, - 'edit-www' : show.manage, - 'new' : new.manage, - 'publish' : publish.manage_publish, - 'show' : show.manage, - 'show-about' : show.manage, - 'show-db' : show.manage, - 'show-wip' : show.manage, - 'show-www' : show.manage, - 'status' : status.check, - 'template' : publish.manage_publish, - 'wip' : wip.manage, + "check" : check.manage, + "create" : creators.manage, + "help" : infos.tyto, + "edit" : show.manage, + "edit-about" : show.manage, + "edit-db" : show.manage, + "edit-wip" : show.manage, + "edit-www" : show.manage, + "new" : new.manage, + "publish" : publish.manage, + "quick-pub" : publish.manage, + "show" : show.manage, + "show-about" : show.manage, + "show-db" : show.manage, + "show-wip" : show.manage, + "show-www" : show.manage, + "status" : status.check, + "template" : publish.manage, + "wip" : wip.manage, } diff --git a/src/usr/share/bash-completion/completions/tyto b/src/usr/share/bash-completion/completions/tyto new file mode 100755 index 0000000..abe8e36 --- /dev/null +++ b/src/usr/share/bash-completion/completions/tyto @@ -0,0 +1,282 @@ +#!/bin/bash +# Tyto - Littérateur +# +# Copyright (C) 2023 Cyrille Louarn +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License +# as published by the Free Software Foundation, either version 3 of the +# License, or of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +#---------------------------------------------------------------------- +# XMPP: echolib (im@echolib.re) +# +# Description: Autocompletion commands +# File: /usr/share/bash-completion/completions/tyto +#---------------------------------------------------------------------- + + +#=====================================================================# +# Actions section # +#=====================================================================# + +# Actions: argument 1 # +#---------------------# +_tyto_actions() { +cat </dev/null +} + +# Targets with quick-pub +#----------------------- +_tyto_targets_qp() { +find . -type f -name "*.tyto" -printf '%P\n' 2>/dev/null +} + + +# Targets with edit +#------------------ +_tyto_targets_edits() { +cat </dev/null +} + +# Targets with edit +#------------------ +_tyto_targets_shows() { +cat </dev/null +} + +# Targets: argument 2 (all + .tyto files) +#---------------------------------------- +_tyto_targets() { +cat </dev/null +} + +# Targets: only with action "new" +#-------------------------------- +_tyto_targets_new() { +cat < est ajoutée + +# Source #1 Titre 1 -(( -Un paragraphe -)) +Contenu 1 #2 Titre 2 + +#3 Titre 3 +contenu 2 + +#4 Titre 4 +``` + +### Balise div +``` +<< CSS +(( +1er paragraphes dans une balise div class="CSS" +)) +(( +2e paragraphes dans une balise div class="CSS" +)) +>> ``` ### Paragraphes @@ -74,94 +127,114 @@ def hello_world(): -) ``` -### Citations -``` -[[ CSS -_cite: autheur -_lang: langue -_link: lien -_year: année ou date YYYY-MM-DD -_book: référence -(( -Citation placée dans un paragraphe -)) -]] - -[[ CSS -Citation simple sans référence -]] -``` - ### Ancres ``` +# Source de l'ancre cible. "id" est son identité -> id -(( -un long paragraphe -)) -(( ->_id:Retourner au point d'ancre_< -)) + +# Source de l'ancre d'appel +# Définir l'identité cible et le texte du lien +>_id:Retourner au point d'ancre id_< + ``` ### Retour à la ligne HTML ``` -| #
+# Source +| + +# HTML +
``` ### Lien vers URL ``` +# Placer "_" devant le Nom du lien Voir ce _Nom du lien # Ouverture même fenêtre Voir ce _Nom du lien+ # ouverture nouvelle fenêtre ``` ### Lien vers fichier ``` +# Placer "__" devant le Nom du lien Voir ce __Nom du lien # Ouverture même fenêtre Voir ce __Nom du lien+ # ouverture nouvelle fenêtre ``` Note: -Vous pouvez avoir un NAME identique pour file: et link: +Vous pouvez avoir un Nom identique pour les marqueurs `file:` et `link:` + ### Gras, Strong, italique... ``` *_très gras_* # +_gras léger_+ # -/_en italique_/ # -[_en italique_] # +;_en italique_; # +:_en italique_: # ~_texte barré_~ # -{_Code_} # -:_Citation rapide_: # +[_Citation rapide_] # %_Classe personnalisée_% >>> -._Souligné_. # +._Souligné_. # +{_Code_} # + +# Montrer comment écrire du code dans Tyto: +# Bypass avec \ devant {_ et _} (idem pour les marqueurs précédents) +{_\{_Comme ça\_}_} ``` ### Abréviations ``` -# ! NOM sera remplacé par "nom" dans la page si défini en entête -# sinon, NOM sera conservé -# Toujours écrire en majuscule les ABBR dans l'article brut -# nom -Avec ce NOM. +# abbrev sera remplacé par "ABBR" dans la page si défini en entête +# sinon, abbrev sera conservé +# - Toujours écrire dans l'article : +# - entre parenthèses ET majuscules les "(ABBREV)" + + +Avec cette (ABBREV). +# HTML: ABBR ``` ### Images ``` # Chaque image doit être placée en début de ligne -# Placer dans un paragraphe pour chaque ou après "|", +# Placer dans un paragraphe pour chacune ou après "|", # sinon, affichage les une à côté des autres # ! Si pas d'unité pour w= et h= : défaut "px" + _image:Nom _image:Nom c=CSS _image:Nom c=css w=1080 _image:Nom w=640em h=480em _image:Nom t=+ # Rend l'image interne cliquable -_image:Nom t=https://...# Donne un lien à l'image -_image:Nom c=CSS t=https://... w=320px h=240 +_image:Nom t=https://...# Donne un lien web à l'image +_image:Nom c=CSS t=https://... w=320px h=240 # 240px ``` -### Code Brut depuis un fichier +### Code brut depuis un fichier ``` -_brut:NOM +_raw:Nom +``` + +### Citations +Possibilité dans toute citation d'utiliser les marqueurs +optionnels `_xxx:`. Pour la date, utilisez le FORMAT INTERNATIONAL +``` +# Source: citation complète +[[ CSS_TEST +_cite: echolib +_date: 2022-12-28 (format AAAA ou AAAA-MM ou AAAA-MM-JJ) +_lang: fr +_link: https://tyto.echolib.re +_book: Référence +(( +Une belle citation complète +)) +]] +```` +``` +# Source: citation basique +[[ +Une citation simple, et sans paragraphe +]] ``` diff --git a/src/var/lib/tyto/help/styles.css b/src/var/lib/tyto/help/styles.css index d57c8a9..504555e 100644 --- a/src/var/lib/tyto/help/styles.css +++ b/src/var/lib/tyto/help/styles.css @@ -3,12 +3,13 @@ * DOMAIN MUST be changed by domain css set in configuration */ -/* +/*===================================================================== * Header */ header#header_page { } +/* Block */ div#site_logo { } @@ -18,6 +19,7 @@ a#site_logo_link { img#site_logo_image { } +/* Block */ div#site_infos { } @@ -31,7 +33,7 @@ p#site_about { } -/* +/*===================================================================== * navbar */ nav#site_menu { @@ -46,7 +48,8 @@ li.site_menu_item { a.site_menu_link { } -/* + +/*===================================================================== * article */ article#article_main { @@ -69,14 +72,14 @@ h6.title_6 { /* Between every IF CONTENTS */ div.contents { } +div.contents_2 { +} div.contents_3 { } div.contents_4 { } div.contents_5 { } -div.contents_6 { -} /* Default if not set in post */ p.DOMAIN { @@ -90,6 +93,10 @@ a.link { a.link-file { } +/* When block quote with _cite:*/ +a.figc { +} + a.anchor_link { } @@ -99,31 +106,32 @@ abbr.DOMAIN { img.DOMAIN_image { } -code.icode { -} - ul.DOMAIN { } -li.DOMAIN +li.DOMAIN { +} -strong.strong { +/* Words tags*/ +code.icode { } -b.bold { +strong.DOMAIN { } -em.em{ +b.DOMAIN { } -i.italic { +em.DOMAIN{ } -del.del { +i.DOMAIN { } -u.underline { +del.DOMAIN { } -cite.cite { +u.DOMAIN { +} +cite.DOMAIN { } span.custom { } -/* Block_code */ +/* Block-code */ code.DOMAIN { } pre.bcode { @@ -143,7 +151,13 @@ span#article_code { a#article_code_link { } -/* + +/* Sitemap */ +ul.sitemap { +} + + +/*===================================================================== * sidebar */ @@ -163,7 +177,7 @@ p.sidebar_item_about { } -/* +/*===================================================================== * footer */ footer#footer_page { @@ -198,5 +212,3 @@ p.footer_copyright { } p.footer_generator { } - - diff --git a/src/var/lib/tyto/program/args.py b/src/var/lib/tyto/program/args.py index c5ba5aa..d540f33 100644 --- a/src/var/lib/tyto/program/args.py +++ b/src/var/lib/tyto/program/args.py @@ -43,14 +43,14 @@ import infos actions = \ ( 'check', + 'create', 'edit', - 'edit-about', 'edit-db', 'edit-wip', 'edit-www', + 'quick-pub', 'new', 'show', - 'show-about', 'show-db', 'show-wip', 'show-www', @@ -59,9 +59,10 @@ actions = \ 'publish' ) -option = \ +options = \ ( '--static', + '--force', ) pass_actions = ('new') @@ -75,6 +76,7 @@ pass_db = \ 'edit-wip', 'edit-www', 'publish', + 'quick-pub', 'show', 'show-about', 'show-db', @@ -94,6 +96,7 @@ pass_targets = \ 'metas', 'navbar', 'sidebar', + 'sitemap', 'stats', 'template' ) @@ -123,6 +126,8 @@ helps = \ try: action = sys.argv[1] except: action = '' +act_err = False + # With no argument, show help if not action: infos.tyto('full') @@ -132,10 +137,7 @@ elif action in helps: infos.tyto(action) # Unused argument [action] -elif action in actions: - act_err = False - -else: +elif not action in actions: act_err = True @@ -147,7 +149,7 @@ except: infos.tyto('full') sys.exit(0) -# option +# options try: option = sys.argv[3] except: option = '' diff --git a/src/var/lib/tyto/program/check.py b/src/var/lib/tyto/program/check.py index ba68741..e5c4cf2 100644 --- a/src/var/lib/tyto/program/check.py +++ b/src/var/lib/tyto/program/check.py @@ -68,7 +68,9 @@ def manage(target): logs.out("1", db.uri_file, True) # Already check - elif db.exists and not db.old_chk: + elif db.exists \ + and not db.old_chk \ + and not args.option == "--force": print(' ├ [%s] > %s'%(db.title, db.uri_file)) logs.out("20", '%s > %s'%(db.date_chk, db.uri_file), False) answer = form.asking(' ├ %s%s '%( @@ -235,10 +237,11 @@ def check_process(target): post_bottom = tyto.protect_article # Protect inline-codes - if icode: - tyto.protect_icodes(post_bottom) - post_bottom = tyto.protect_article + if icode: post_bottom = tyto.protect_icodes(post_bottom) + # Replace escaped markers + post_bottom = tyto.protect_escaped(post_bottom, False) + # Check header tags configurations check_needed_tags(post_header.rsplit('\n')) @@ -294,6 +297,7 @@ def file_to_string(): for line in article.rsplit('\n'): if line.startswith(logs.shebang): + print(' │') logs.out("82", db.uri_file, False) post_err = True return @@ -313,6 +317,7 @@ def file_to_string(): # Check if separator or exit if not sep: + print(' │') logs.out("6", '"-----" > %s'%db.uri_file, False) post_err = True return @@ -402,14 +407,14 @@ def if_icodes_bcodes_quotes(post_bottom): fcodes += 1 # icodes - elif tyto.words_tags[8][0] or tyto.words_tags[8][1] in line: + elif tyto.icode_tags[0] in line or tyto.icode_tags[1] in line: icode_m1 = icode_m2 = 0 - icode_m1 = line.count(tyto.words_tags[8][0]) - icode_m2 = line.count(tyto.words_tags[8][1]) + icode_m1 = line.count(tyto.icode_tags[0]) + icode_m2 = line.count(tyto.icode_tags[1]) if icode_m1 != icode_m2: logs.out("8", 'L=%s. icode "%s" + "%s" > %s'%( ln + 1 + ln_header, - tyto.words_tags[8][0], tyto.words_tags[8][1], + tyto.icode_tags[0], tyto.icode_tags[1], db.uri_file ), False ) @@ -424,23 +429,30 @@ def if_icodes_bcodes_quotes(post_bottom): #-----------------------------------------# def check_needed_tags(post_header): global post_err - global title, author, about, tags, date + global title, author, about, tags, date, sitemap global stat_tags title = author = about = tags = '' + sitemap = "True" date = () stat_tags = 0 # Check post header for each needed tags for tag in tyto.needed_header_tags: for ln, line in enumerate(post_header, 1): + # Sitemap : set to False if #NoSitemap + if line.startswith("# NoSitemap"): + sitemap = "False" + # Break if already set - if globals()[tag]: break + if globals()[tag]: + break # Set data from tag if line.startswith('%s:'%tag): globals()[tag] = line.rsplit('%s:'%tag)[1].lstrip() globals()[tag] = tyto.convert_altname(globals()[tag]) + # Stat for "tags:" if tag == 'tags': stat_tags = len(globals()[tag].strip().split(",")) @@ -450,8 +462,6 @@ def check_needed_tags(post_header): if not globals()[tag]: logs.out("38", '%s:'%tag, False) post_err = True - - # Check date format # Set french format in post DB @@ -1006,6 +1016,7 @@ def create_database(): 'meta_tags = "%s"\n'%tags + \ 'date = "%s"\n'%date_tr + \ 'snpic = "%s"\n'%snpic_url + \ + 'sitemap = %s\n'%sitemap + \ '\n# Post Configurations\n' + \ 'post_id = "%s"\n'%db.uri_id + \ 'post_src = "%s"\n'%db.uri_file + \ @@ -1013,20 +1024,20 @@ def create_database(): 'short_src = "%s"\n'%src_post_short_uri + \ 'short_srv = "%s"\n'%srv_post_short_uri + \ 'sub_uri = "%s"\n'%sub_uri + \ - 'date_chk = "%s"\n'%tyto.nowdate() + \ - 'hash_chk = "%s"\n'%db.hash_post + \ + 'date_chk = "%s"\n'%tyto.nowdate() + \ + 'hash_chk = "%s"\n'%db.hash_post + \ '\n# wip configuration\n' + \ 'post_wip = "%s"\n'%srv_post_wip_uri + \ 'http_wip = "%s"\n'%http_wip + \ 'static_wip = %s\n'%wip_static + \ - 'date_wip = "%s"\n'%date_wip + \ - 'hash_wip = "%s"\n'%hash_wip + \ + 'date_wip = "%s"\n'%date_wip + \ + 'hash_wip = "%s"\n'%hash_wip + \ '\n# www configuration\n' + \ 'post_www = "%s"\n'%srv_post_www_uri + \ 'http_www = "%s"\n'%http_www + \ 'static_www = %s\n'%www_static + \ - 'date_www = "%s"\n'%date_www + \ - 'hash_www = "%s"\n'%hash_www + \ + 'date_www = "%s"\n'%date_www + \ + 'hash_www = "%s"\n'%hash_www + \ '\n# Used files\n' + \ 'uris = %s'%str(files_post) diff --git a/src/var/lib/tyto/program/creators.py b/src/var/lib/tyto/program/creators.py new file mode 100644 index 0000000..903dc4f --- /dev/null +++ b/src/var/lib/tyto/program/creators.py @@ -0,0 +1,185 @@ +#!/usr/bin/env python3 +# Tyto - Littérateur +# +# Copyright (C) 2023 Cyrille Louarn +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License +# as published by the Free Software Foundation, either version 3 of the +# License, or of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +#---------------------------------------------------------------------- +# XMPP: echolib (im@echolib.re) +# +# Description: Manage 'creators' argument. +# Create articles +# File: /var/lib/tyto/program/creators.py +#---------------------------------------------------------------------- + +#------------ +# funny stats +#------------ +# lines: +# functions: +# comments: +#---------------------------------------------------------------------- + +#********************************************************************** + +import os, importlib, datetime, subprocess +import args, dom, db, langs, tyto, check, wip, logs + + +#========================# +# Manage action [create] # +#------------------------# +def manage(target): + + creators = { + "sitemap" : create_sitemap, + } + + try: + creators[target](target) + except: + logs.out("28", "%s + %s"%(args.action, args.target), True) + + + +#=====================# +# Set and return date # +#---------------------# +def nowdate(): + now = datetime.datetime.now() + return(now.strftime('%Y-%m-%d')) + + +#============================# +# Create sitemap.tyto file # +# Then check it, and wip it # +# ! sitemap is the "www" one # +# seen in 'wip' server # +#----------------------------# +def create_sitemap(target): + dom.valid() + + # Define sitemap.tyto + sitemap_tyto = \ + '# %s Tyto - Littérateur [tyto create sitemap]\n'%langs.site.sitemap_gen + \ + '# NoSitemap\n' + \ + 'title: %s (%s %s)\n'%(langs.site.sitemap_t, '%s', langs.site.links) + \ + 'about: %s Tyto - Littérateur\n'%langs.site.sitemap_gen + \ + 'author: Tyto\n' + \ + 'tags: sitemap\n' + \ + 'date: %s\n'%nowdate() + \ + '\n' + \ + '%s\n' + \ + '-----\n' + \ + '\n' + \ + '%s\n' + \ + '-)' + + print(sitemap_tyto) + + tab = 8 + uri_dir_set = "" + links = "" + contents = "#1 /\n-( sitemap" + + # Not real articles folder + forbid_dir = ( + dom.files_d, + dom.images_d, + dom.modules_d + ) + + # Get all .tyto files from domain + nbr_files = 0 + for r, dirs, files in os.walk(os.getcwd()): + if r.startswith(forbid_dir): + continue + + for f in files: + if f.endswith(".tyto"): + try: + uri_file = r.rsplit(dom.articles_d)[1] + uri_file = os.path.join(uri_file,f) + except: + uri_file = f + + uri_dir = uri_file.rsplit(f)[0] + if not uri_dir: + uri_dir = "~/" + + # Try to load Article Database + args.action = "check" + args.target = uri_file + importlib.reload(db) + if not db.exists: + continue + else: + try: + db.hash_www + db.sitemap + if not db.sitemap: + continue + except: + continue + + # Count + nbr_files += 1 + + # create defined link + if not links: + links = \ + "link: %s\n%s%s\n%s%s\n"%( + db.title, tab * " ", db.short_srv, tab * " ", db.about + ) + else: + links = \ + "%s\nlink: %s\n%s%s\n%s%s\n"%( + links, + db.title, tab * " ", + db.short_srv, tab * " ", db.about + ) + + + # Create list link line + if not uri_dir.startswith(uri_dir_set): + root_dir = uri_dir.rsplit("/")[0] + contents = "%s\n-)\n\n#1 %s\n-( sitemap"%(contents, root_dir) + uri_dir_set = uri_dir.rsplit("/")[0] + + uls = uri_dir.count("/") + contents = \ + "%s\n%s [%s] _%s (%s)"%( + contents, + uls * "=", db.date, db.title, db.author + ) + + sitemap_tyto = \ + sitemap_tyto%( + nbr_files, + links, + contents + ) + sitemap_file = "%ssitemap.tyto"%dom.articles_d + tyto.set_file(sitemap_file, "New", sitemap_tyto) + + # Check and wip + www = subprocess.run( + [ + '/usr/bin/tyto', + 'wip', + 'sitemap.tyto', + '--force' + ], + ) diff --git a/src/var/lib/tyto/program/db.py b/src/var/lib/tyto/program/db.py index a488d9d..c50f3f9 100644 --- a/src/var/lib/tyto/program/db.py +++ b/src/var/lib/tyto/program/db.py @@ -104,6 +104,7 @@ if args.target \ 'meta_tags', 'date', 'snpic', + 'sitemap', 'uris', 'uniq_anchors', 'uniq_abbrs', diff --git a/src/var/lib/tyto/program/dom.py b/src/var/lib/tyto/program/dom.py index 976a8dd..e0c32c7 100644 --- a/src/var/lib/tyto/program/dom.py +++ b/src/var/lib/tyto/program/dom.py @@ -77,7 +77,6 @@ dom_values = \ 'sidebar_f', 'metas_f', 'footer_f', - 'footer_about_f', 'shortname', 'www_url', 'wip_url', @@ -138,7 +137,6 @@ create_files = \ 'sidebar_f', 'metas_f', 'footer_f', - 'footer_about_f' ) wip_html_mods = () @@ -241,7 +239,6 @@ if not hole: eval(str('footer_f')), eval(str('wip_footer_f')), eval(str('www_footer_f')), - eval(str('footer_about_f')) ) templates = \ @@ -312,3 +309,4 @@ if not hole: def valid(): if incomplete: sys.exit(41) elif not active: sys.exit(42) + elif not ready: sys.exit(41) diff --git a/src/var/lib/tyto/program/form.py b/src/var/lib/tyto/program/form.py index 51a487c..013a40d 100644 --- a/src/var/lib/tyto/program/form.py +++ b/src/var/lib/tyto/program/form.py @@ -207,7 +207,6 @@ def create_domain(target): 'sidebar_f = "%styto.sidebar"\n'%modules_dir + \ 'metas_f = "%styto.metas.html"\n'%modules_dir + \ 'footer_f = "%styto.footer.html"\n'%modules_dir + \ - 'footer_about_f = "%s"\n'%footer_about_f + \ '\n# Domain\n' + \ 'shortname = "%s"\n'%shortname + \ 'www_url = "%s"\n'%www_url + \ @@ -679,7 +678,7 @@ def create_domain(target): #---------------- tyto.set_file(dom.config, False, '\nactivated = True') - # RELoad config + # ReLoad config #-------------- importlib.reload(dom) @@ -718,15 +717,6 @@ def create_domain(target): html.create_navbar('new') html.create_sidebar('new') html.create_user_footer('new') - create_footer_about('new') - - ''' - create_metas('form') - create_navbar('form') - create_sidebar('form') - create_footer('form') - create_footer_about('form') - ''' print(langs.site.form_ready) @@ -941,7 +931,6 @@ def create_footer(option): if not dom.ready: dom.valid() print(' │\n ├ %s'%langs.site.footer_inf) - create_footer_about(option) if option != "new": return # Default footer contents @@ -968,19 +957,8 @@ def create_footer(option): '%stitle="%s"\n'%(9 * ' ', langs.site.go_home) + \ '%sclass="footer_title_link">%s'%(9 * ' ', dom.title) - # Insert content of footer_about_f or default if not exists - footer_about = '' - if tyto.exists(dom.footer_about_f): - footer_custom = open(dom.footer_about_f).read() - for line in footer_custom.rsplit('\n'): - if not line or line.startswith('#'): - continue - - line = '%s%s'%(6 * ' ', line) - if footer_about: footer_about = '%s\n%s'%(footer_about, line) - else: footer_about = line - else: - footer_about = "

%s

"%dom.about + # Insert content of fabout domain + footer_about = "

%s

"%dom.about # License URL. Set to homepage if unknown if not dom.license_url: dom.license_url = '/' @@ -1106,26 +1084,3 @@ def create_footer(option): tyto.set_file(dom.footer_f, 'New', footer) - -# Generic HTML list in footer -""" - ' \n' -""" - - -#========================================# -# Create custom about section for footer # -#----------------------------------------# -def create_footer_about(option): - if not tyto.exists(dom.footer_about_f): - set_f = '%s\n'%langs.site.footer_about_doc%(tyto.Tyto, - dom.footer_about_f - ) + \ - ''%dom.about - - tyto.set_file(dom.footer_about_f, 'New', set_f) - diff --git a/src/var/lib/tyto/program/html.py b/src/var/lib/tyto/program/html.py index 5cb21e1..927fd2b 100644 --- a/src/var/lib/tyto/program/html.py +++ b/src/var/lib/tyto/program/html.py @@ -213,7 +213,7 @@ def create_html_time_meta(process): importlib.reload(db) global time_html_pub, meta_pub, date_raw - + if process == 'wip': try: date_raw = db.date_wip #
\n'%( db.title, langs.site.w_published, date_pub, time_pub, - date_pub + db.date ) + \ ' \n' + \ '' diff --git a/src/var/lib/tyto/program/new.py b/src/var/lib/tyto/program/new.py index 9b9c352..f50ead2 100644 --- a/src/var/lib/tyto/program/new.py +++ b/src/var/lib/tyto/program/new.py @@ -68,8 +68,9 @@ def manage(target): if args.target.endswith(".tyto"): args.target = args.target.replace(".tyto", '') - u = unidecode(args.target, "utf-8") - args.target = unidecode(u) + # In case needed (todo later) + # u = unidecode(args.target, "utf-8") + # args.target = unidecode(u) filepost = "%s%s.tyto"%(dom.articles_d, args.target) if tyto.exists(filepost): diff --git a/src/var/lib/tyto/program/publish.py b/src/var/lib/tyto/program/publish.py index d475ed1..179022c 100644 --- a/src/var/lib/tyto/program/publish.py +++ b/src/var/lib/tyto/program/publish.py @@ -35,20 +35,37 @@ import os, sys, shutil, importlib from pathlib import Path -import logs, args, dom, db, wip, html, tyto, form, stats, rss, langs +import logs, args, dom, db, wip, html, tyto, form, stats, rss, langs, check #==============================# # Manage action, get post db # # check if publish can be done # #------------------------------# -def manage_publish(target): +def manage(target): dom.valid() - + + # Specific QUICK processes: check > wip > publish + if args.action == "quick-pub": + try: + db.uri_file + except: + logs.out("28", "%s + %s"%(args.action, args.target), True) + + print(" ! Quick Publish") + check.check_process(target) + importlib.reload(db) + wip.wip_article(db.uri_file) + importlib.reload(db) + check_to_publish('one') + publish_article() + rss.create_feed() + return + # Target is footer, sidebar, navbar, metas # template: create/copy template/ files # all: publish all wip article #----------------------------------------- - if target in args.pass_targets: + elif target in args.pass_targets: do = { 'updated' : publish_all, 'again' : publish_all, @@ -64,6 +81,7 @@ def manage_publish(target): do[target]('www') return + # Database must exists... if not target: logs.out("5", '', True) if not db.post: logs.out("1", db.uri_file, True) diff --git a/src/var/lib/tyto/program/show.py b/src/var/lib/tyto/program/show.py index d870612..8c5ba8a 100644 --- a/src/var/lib/tyto/program/show.py +++ b/src/var/lib/tyto/program/show.py @@ -108,8 +108,6 @@ def manage(target): "post" : 'src', "show-db" : 'db', "edit-db" : 'db', - "show-about" : 'about', - "edit-about" : 'about', "show-wip" : 'wip', "edit-wip" : 'wip', "show-www" : 'www', @@ -136,14 +134,6 @@ def manage(target): "sidebar" : dom.sidebar_f, "post" : post_db }, - 'about' : { - "domain" : dom.config, - "footer" : dom.footer_about_f, - "metas" : dom.metas_f, - "navbar" : dom.navbar_f, - "sidebar" : dom.sidebar_f, - "post" : post_db - }, 'wip' : { "domain" : dom.config, "footer" : dom.wip_footer_f, diff --git a/src/var/lib/tyto/program/tyto.py b/src/var/lib/tyto/program/tyto.py index e6945da..5d23f87 100644 --- a/src/var/lib/tyto/program/tyto.py +++ b/src/var/lib/tyto/program/tyto.py @@ -106,37 +106,37 @@ headers = \ words_tags = [ ( '*_', '_*', - '', '', + ''%dom.css, '', 'strongs' ), ( '+_', '_+', - '', '', + ''%dom.css, '', 'bolds' ), ( ';_', '_;', - '', '', + ''%dom.css, '', 'emphasis' ), ( ':_', '_:', - '', '', + ''%dom.css, '', 'italics' ), ( '~_', '_~', - '', '', + ''%dom.css, '', 'dels' ), ( - '._', '_.', '', + '._', '_.', ''%dom.css, '', 'underlines' ), ( '[_', '_]', - '', '', + ''%dom.css, '', 'cites' ), ( @@ -144,12 +144,93 @@ words_tags = [ '', '', 'customs' ), +] + + +icode_tags = \ ( '{_', '_}', '', '', - 'codes' - ), -] + 'icodes', + '\\{_', '\\_}' + ) +strong_tags = \ + ( + '*_', '_*', + ''%dom.css, '', + 'strongs', + '\\*_', '\\_*', + '-S1-', '-S2-' + ) +bold_tags = \ + ( + '+_', '_+', + ''%dom.css, '', + 'bolds', + '\\+_', '\\_+', + '-B1-', '-B2-' + ) +em_tags = \ + ( + ';_', '_;', + ''%dom.css, '', + 'emphasis', + '\\;_', '\\_;', + '-EM1-', '-EM2-' + ) +i_tags = \ + ( + ':_', '_:', + ''%dom.css, '', + 'italics', + '\\:_', '\\_:', + '-I1-', '-I2-' + ) +u_tags = \ + ( + '._', '_.', ''%dom.css, + '', + 'underlines', + '\\._', '\\_.', + '-U1-', '-U2-' + ) +del_tags = \ + ( + '~_', '_~', + ''%dom.css, '', + 'dels', + '\\~_', '\\_~', + '-DE1-', '-DE2-' + ) +cite_tags = \ + ( + '[_', '_]', + ''%dom.css, '', + 'cites', + '\\[_', '\\_]', + '-CI1-', '-CI2-' + ) +custom1_tags = \ + ( + '%_', '_%', + '', '', + 'customs', + '\\%_', '\\_%', + '-CU1-', '-CU2-' + ) + + +markers_tags = \ + [ + strong_tags, + bold_tags, + em_tags, + i_tags, + u_tags, + del_tags, + cite_tags, + custom1_tags, + ] # At begining line, create block contents block_tags = [ @@ -280,6 +361,48 @@ date: %s nbr_icodes = 0 +#==============================# +# Replace escaped markers # +# check: with "" # +# wip: with altternate # +# (recover when wip done) # +#------------------------------# +def protect_escaped(post_bottom, reverse): + for m1, m2, h1, h2, n, e1, e2, r1, r2 in markers_tags: + + # In check mode, No need to keep escaped markers + if args.action == "check": + r1 = r2 = '' + + if reverse: + post_bottom = post_bottom.replace(r1, m1) + post_bottom = post_bottom.replace(r2, m2) + else: + post_bottom = post_bottom.replace(e1, r1) + post_bottom = post_bottom.replace(e2, r2) + + return post_bottom + + +# -- tests +def find_between( s, first, last ): + try: + start = s.index( first ) + len( first ) + end = s.index( last, start ) + return s[start:end] + except ValueError: + return "" + +def find_between_r( s, first, last ): + try: + start = s.rindex( first ) + len( first ) + end = s.rindex( last, start ) + return s[start:end] + except ValueError: + return "" +# -- tests + + #=======# # TOOLS # #=======#-------------------------------------------------------------- @@ -478,56 +601,70 @@ def protect_bcodes_quotes(process, post_bottom): if close_quote: quote = b64_quote = '' -#=======================# -# Protec iCodes # -# Used in check and wip # -#-----------------------~ +#=======================================# +# Protec iCodes # +# Used in check and wip # +# Methode: iterate (c)haracter in lines # +# check: remove icdoe # +# wip: convert to b64 # +#---------------------------------------# def protect_icodes(post_bottom): - global protect_article global nbr_icodes - protect_article = post_bottom - in_icode = False - src_code = rep_code = '' - # Get only lines that contains code + in_icode = ok_icode = go_icode = False for ln, line in enumerate(post_bottom.rsplit('\n')): - if not words_tags[8][0] in line: continue - - # Iterate (c)haracter in line + if not "{_" in line or not "_}" in line: + continue + + code = "" for i, c in enumerate(line): - c_b = c_bb = c_a = "" - if c == '_': - c_b = line[i-1] # before - c_bb = line[i-2] # before, before - c_a = line[i+1] # after - - # incode if - if c_b == '{' and not c_bb == '\\': - in_icode = True - nbr_icodes += 1 - code = words_tags[8][2] + if c == "_": + try: + if line[i-1] == "{" and line[i-2] != "\\": + in_icode = True + ok_icode = False + go_icode = True + elif line[i+1] == "}" and line[i-2] != "\\": + in_icode = False + ok_icode = True + go_icode = False + except: continue - - # No more in code if - if c_a == '}' and not c_b == '\\': - in_icode = False - src_code = convert_altname(src_code) - code = '%s%s%s'%(code, src_code, words_tags[8][3]) - b64_code = b64('Encode', code, 'I64.', '.I64') - rep_code = "%s%s%s"%( - words_tags[8][0], rep_code, words_tags[8][1] - ) - protect_article = protect_article.replace(rep_code, b64_code) - - src_code = rep_code = b64_code = '' + + if go_icode : + go_icode = False continue - - # Construct original replacement code and source code + if in_icode: - rep_code = '%s%s'%(rep_code, c) - if c == '\\': continue - src_code = '%s%s'%(src_code, c) + ok_icode = False + code = "%s%s"%(code, c) + + # End icode + if ok_icode: + nbr_icodes += 1 + tyto_code = "%s%s%s"%(icode_tags[0], code, icode_tags[1]) + + if args.action == "check": + post_bottom = \ + post_bottom = post_bottom.replace(tyto_code , '') + + elif args.action == "wip": + code = convert_altname(code) + html_code = "%s%s%s"%( + icode_tags[2], code, icode_tags[3]) + b64_code = b64('Encode', html_code, 'I64.', '.I64') + post_bottom = post_bottom.replace(tyto_code, b64_code) + + + # Reset for next + code = tyto_code = html_code = b64_code = "" + ok_icode = False + + post_bottom = post_bottom.replace("\\%s"%icode_tags[0], icode_tags[0]) + post_bottom = post_bottom.replace("\\%s"%icode_tags[1], icode_tags[1]) + + return post_bottom #=====================================# diff --git a/src/var/lib/tyto/program/wip.py b/src/var/lib/tyto/program/wip.py index 93a961b..21cc0b4 100644 --- a/src/var/lib/tyto/program/wip.py +++ b/src/var/lib/tyto/program/wip.py @@ -38,7 +38,7 @@ import os, re, sys, locale, shutil, importlib, time from pathlib import Path -import args, logs, langs, dom, db, tyto, html, form, stats +import args, logs, langs, dom, db, tyto, html, form, stats, check #=========================================# @@ -49,11 +49,20 @@ def manage(target): global post_db, hash_post, target_all - # wip_article(db.post_src) ; return # Force wip without checking - if not target: logs.out("5", '[target]', True) + # option --force to check and wip processes + if args.option == '--force': + if args.target in args.pass_targets: + logs.out("28", "%s + %s"%(args.target, args.option), True) + + check.manage(target) + #importlib.reload(db) + wip_article(target) + return + + # Modules and multi-articles elif target in args.pass_targets: do = { 'updated' : wip_all, @@ -156,9 +165,10 @@ def wip_article(target): # Protect inline-codes if db.icodes > 0: - tyto.protect_icodes(post_bottom) - post_bottom = tyto.protect_article + post_bottom = tyto.protect_icodes(post_bottom) + # Replace escaped markers + post_bottom = tyto.protect_escaped(post_bottom, False) # Convert contents from modules wip_clean_lines() # Remove comments and empty lines @@ -170,6 +180,9 @@ def wip_article(target): wip_titles() # Convert #N, remove empty line, add divs wip_lists() # convert ul/ol lists wip_quotes() # Quotes. Decode base64 Q64 and convert to HTML + + # Replace escaped markers + post_bottom = tyto.protect_escaped(post_bottom, True) wip_icodes() # inline_codes. Decode base64 icode and replace wip_filecode(target) # Read file and convert to HTML wip_bcodes() # Block-codes. Decode B64 and convert to HTML diff --git a/src/var/lib/tyto/translations/site_en.py b/src/var/lib/tyto/translations/site_en.py index 82f1d0f..0a24eab 100644 --- a/src/var/lib/tyto/translations/site_en.py +++ b/src/var/lib/tyto/translations/site_en.py @@ -20,6 +20,7 @@ # Generic article = "Article" +links = "links" sidebar = 'Sidebar' navbar = 'Navbar' metas = 'Metas Tags' @@ -88,7 +89,9 @@ rss_c = "Create ATOM/RSS feed" # Other uptpl = "Update directory" stats_f = "Articles: %s (%s words)" -reg_domains = 'Registred domains' +reg_domains = "Registred domains" +sitemap_gen = "Sitemap generated by" +sitemap_t = "Sitemap" # Form #---------------------------------------------------------------------- @@ -237,19 +240,6 @@ footer_doc = \ '# - Do NOT copy to template directory' '# %s\n'%(20 * "-") -footer_about_doc = \ -'# For %s\n' + \ -'# Type text/HTML file\n' + \ -'# Description Used when a footer is generated\n' + \ -'# Content inserted in "about" section\n' + \ -'# File %s\n' + \ -'# How Put any HTML code\n' + \ -'# Notes - Lines are ignored if:\n' + \ -'# - empty\n' + \ -'# - begin with "#"\n' + \ -'# - Do NOT copy to template directory\n' + \ -'# %s\n'%(20 * "-") - # Help with Tyto commands args_helps = """\n# New domain : - Create directory and go in @@ -261,13 +251,12 @@ args_helps = """\n# New domain : - (css, logo...) files go in "wip/template/" # Usage: tyto [action] [target] - # Actions - - [action] > withour [target] + # [action] > withour [target] version : Show installed version domains : Show installed domains help : Show commands help - - [action] > According to [target] + # [action] > According to [target] # Edit a file edit : Source file, configuration module edit-about: [footer] Edit description section in footer @@ -292,9 +281,9 @@ args_helps = """\n# New domain : check : Check the validity of a tyto format file wip : Create article HTML page in server 'wip' publish : Create article HTML page in server 'www' + quick-pub : Do check, wip, publish ([file] only) - # Targets - - [target] > According to [action] + # [target] > According to [action] # Multiple articles updated : Update articles (already checked) again : Force all articles (already checked) @@ -316,7 +305,11 @@ args_helps = """\n# New domain : metas : , configuration file navbar : Navbar configuration file sidebar : Sidebar configuration file - stats : Stats file (server 'wip' er 'www')""" + stats : Stats file (server 'wip' er 'www') + + # [option] : + --static : Créer une page HTML entièrement statique + --force : Avec [wip], vérifier l'article et créer la page HTML""" ex_helps = """# Examples : # Check article (according to sub-folder) diff --git a/src/var/lib/tyto/translations/site_fr.py b/src/var/lib/tyto/translations/site_fr.py index 49b1e49..c2c1e3d 100644 --- a/src/var/lib/tyto/translations/site_fr.py +++ b/src/var/lib/tyto/translations/site_fr.py @@ -20,6 +20,7 @@ # Generic article = "Article" +links = "liens" sidebar = 'Barre Latérale' navbar = 'Barre de menu' metas = 'Balises Metas' @@ -88,7 +89,9 @@ rss_c = "Créer le flux ATOM/RSS" # Autre uptpl = "Mettre à jour le dossier" stats_f = "Articles : %s (%s mots)" -reg_domains = 'Domaines enregistrés' +reg_domains = "Domaines enregistrés" +sitemap_gen = "Plan du site (sitemap) généré par" +sitemap_t = "Plan du site" # Formulaire #---------------------------------------------------------------------- @@ -237,19 +240,6 @@ footer_doc = \ '# - Ne PAS copier ce fichier dans le dossier template\n' + \ '# %s\n'%(20 * "-") -footer_about_doc = \ -'# Pour %s\n' + \ -'# Type Fichier text/HTML\n' + \ -'# Description Utilisé lors de la génération du pied de page\n' + \ -'# Contenu inséré dans la section "about"\n' + \ -'# Fichier %s\n' + \ -'# Comment Insérer du code HTML\n' + \ -'# Notes - Les lignes sont ignorées si :\n' + \ -'# - vides\n' + \ -'# - commencent par "#"\n' + \ -'# - Ne PAS copier ce fichier dans le dossier template\n' + \ -'# %s\n'%(20 * "-") - # Help with Tyto commands args_helps = """\n# Nouveau domaine : - Créer un dossier et aller dedans @@ -261,17 +251,14 @@ args_helps = """\n# Nouveau domaine : - Les fichier (css, logo...) vont dans le dossier serveur "wip/template/" # Usage: tyto [action] [target] - # Les actions - - [action] > Sans [target] + # [action] > Sans [target] version : Montre la version installée domains : Montre les domains installés help : Montre l'aide des commandes - - [action] > Selon l'argument [target] + # [action] > Selon l'argument [target] # Modifier un ficher edit : Fichier source, module de configuration - edit-about: [footer] Modifier la section description du pied de page - sinon comme l'action [edit-db] edit-db : Modifier une base de données/fichier de configuration edit-wip : Modifier un fichier dans le serveur 'wip' edit_www : Modifier un fichier dans le serveur 'www' @@ -283,8 +270,6 @@ args_helps = """\n# Nouveau domaine : # Afficher un fichier (avec numéros de ligne) show : Fichier source, module de configuration - show-about: [footer] Afficher la section description du pied de page - sinon comme l'action [show-db] show-db : Afficher une base de données/fichier de configuration show-wip : Afficher un fichier dans le serveur 'wip' show-www : Afficher un fichier dans le serveur 'www' @@ -293,9 +278,9 @@ args_helps = """\n# Nouveau domaine : check : Vérifier la validité d'un article au format tyto wip : Créer une page HTML de l'article dans le serveur 'wip' publish : Créer une page HTML de l'article dans le serveur 'www' + quick-pub : Faire check, wip, publish ([file] seulement) - # Les cibles - - [target] > Selon l'action [action] + # [target] > Selon l'action [action] # Traitement en masse updated : Mise à jour des articles modifiés (déjà vérifiés) again : Forcer TOUS les articles déjà vérifiés @@ -317,7 +302,11 @@ args_helps = """\n# Nouveau domaine : metas : Fichier de configuration des balises HTML , navbar : Fichier de configuration du menu de navigation sidebar : Fichier de configuration de la barre latérale - stats : Fichier de statistiques (serveur 'wip' ou 'www')""" + stats : Fichier de statistiques (serveur 'wip' ou 'www') + + # [option] + --static : Créer une page HTML entièrement statique + --force : Avec [wip], vérifier l'article et créer la page HTML""" ex_helps = """# Exemples : # Vérifier l'article dans le sous dossier (suivant l'emplacement)