diff --git a/CHANGELOG.md b/CHANGELOG.md index 8ccc2f3..af06a05 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,32 +1,13 @@ # Changelog Tyto - Littérateur -- Repository: https://git.a-lec.org/echolib/tyto-litterateur -- Issues: https://git.a-lec.org/echolib/tyto-litterateur/-/issues -- Changelog: https://git.a-lec.org/echolib/tyto-litterateur/-/blob/master/CHANGELOG.md -- License: https://git.a-lec.org/echolib/tyto-litterateur/-/blob/master/LICENSE +- Repository: https://git.a-lec.org/echolib/tyto-litterateur +- Issues: https://git.a-lec.org/echolib/tyto-litterateur/-/issues +- Changelog: https://git.a-lec.org/echolib/tyto-litterateur/-/blob/master/CHANGELOG.md +- License: https://git.a-lec.org/echolib/tyto-litterateur/-/blob/master/LICENSE +- Documentation: https://tyto.echolib.re + +## [0.10.6] -## [0.10.2] -- Citer dans un texte > `[_` + `_]` -- Italique `` > `;_` + `_;` -- Italique `` > {_:_` + `_:` -## [0.10.1] -- Fix with try in check for static page -## [0.10.0] -- Add full static page option (--static) only with wip -- Add
markers: `<<`, `>>` -- Add new container
in footer -- Better status display for article -- fix lang setting -- fix for less warnings in HTML validity - -## [0.9.1] -- wip: tabulation when using `
` -- wip: inline quote markers `@_myquote_@` -- wip: inline italic marker `:_maybe_:` -- wip: fix data retreive in complete quote - -## [0.9.0] -- Last testings before final diff --git a/Makefile b/Makefile index 2482287..c6421da 100644 --- a/Makefile +++ b/Makefile @@ -1,12 +1,23 @@ #!/bin/bash +# +# Copyright (C) 2023-2024 Adrien Bourmault +# +# This file is part of tyto-litterateur. +# +# 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 +# (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 . -# file: Makefile - -# By neox - -# License: GNU AFFERO GENERAL PUBLIC LICENSE Version 3, 19 November 2007 - -default: debian/tyto.deb +default: tyto.deb ### MAKE DEB @@ -14,14 +25,14 @@ default: debian/tyto.deb .PHONY: clean -debian/tyto.deb: debian/debian-binary debian/control.tar.gz debian/data.tar.gz - ar -r debian/tyto.deb debian/debian-binary debian/control.tar.gz debian/data.tar.gz +tyto.deb: debian/debian-binary debian/control.tar.gz debian/data.tar.gz + cd debian && ar -r ../tyto.deb debian-binary control.tar.gz data.tar.gz debian/data.tar.gz: cd src && tar czvf ../debian/data.tar.gz usr var debian/control.tar.gz: - tar czvf debian/control.tar.gz debian/control #preinst postinst prerm postrm + cd debian && tar czvf control.tar.gz control #preinst postinst prerm postrm debian/debian-binary: echo 2.0 > debian/debian-binary @@ -29,4 +40,4 @@ debian/debian-binary: clean: -rm debian/*.tar.gz -rm debian/debian-binary - -rm debian/*.deb + -rm *.deb diff --git a/README.md b/README.md index c4660b0..006d560 100644 --- a/README.md +++ b/README.md @@ -1,220 +1,53 @@ # Tyto -Pour obtenir de l'aide, taper juste la commande tyto +- FR. Pour obtenir de l'aide, taper juste la commande tyto +- EN. To get help, just type tyto. +- - Doc is only in french yet, but Tyto is translated, also for your websites ## Répertoire de code du projet Tyto -TODO +https://git.a-lec.org/echolib/tyto-litterateur -## Comment définir les métas -``` -# Obligatoires uniques -# Ces marqueurs se configurent sur UNE ligne -title: Titre -about: Infos de l'article -author: Auteur -tags: mot-clé-1,mot 2, -date: YYYY-MM-DD (AAAA-MM-JJ) +## Documentation officielle +https://tyto.echolib.re (en cours de construction) -# L'image doit être configurée avec le même Nom -# dans les marqueurs multiples -# Utilise l'image précisée comme "avatar" dans les réseaux sociaux -snpic: Nom - - -# Optionnels multiples -# Ces marqueurs se configurent sur 3 lignes -link: Nom du lien - URL - Texte Alternatif - -image: Nom - URI - Texte Alternatif - -file: Nom du lien - URL - Texte Alternatif - -raw: Nom - URI - Texte Alternatif - -abbr: abbrev - Définition de abbrev - ABBR (forme à afficher dans l'artile (optionnel)) - -# Séparateur d'au moins 5 "-" pour définir la fin -# des métadonnées d'entête de l'article ----------- -``` - -## Comment écrire un article - -### Écrire des titres -``` -# Les titres HTML vont de 1 à 6. -# Utiliser #N, où N est entre 1 et 6. -# Si du contenu existe entre les titres, une
est ajoutée -# Astuce: on commence en général par #2 dans l'article le titre du site -# étant en #1 - -# Source -#2 Titre 1 -Contenu 1 - -#3 Titre 2 - -#4 Titre 3 -contenu 2 - -#5 Titre 4 -``` - -### Balise div -``` -<< CSS -(( -1er paragraphes dans une balise div class="CSS" -)) -(( -2e paragraphes dans une balise div class="CSS" -)) ->> -``` - -### Paragraphes -``` -(( CSS -Un paragraphe -)) -``` - -### Code Brut -``` -{{ CSS -def hello_world(): - print("Hello") -}} -``` - -### Listes ul/ol -``` --( CSS -= Liste ul -== Sous-liste ul -=== Sous-sous-liste ul -++++ Sous-sous-sous-liste ol -+++ Sous-sous-liste ol --) -``` - -### Ancres -``` -# Source de l'ancre cible. "id" est son identité --> id - -# 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 Nom identique pour les marqueurs `file:` et `link:` - - -### Gras, Strong, italique... -``` -*_très gras_* # -+_gras léger_+ # -;_en italique_; # -:_en italique_: # -~_texte barré_~ # -[_Citation rapide_] # -%_Classe personnalisée_% >>> -._Souligné_. # -{_Code_} # - -# Montrer comment écrire du code dans Tyto: -# Bypass avec \ devant {_ et _} -{_\{_Comme ça\_}_} - -``` - -### Abréviations -``` -# 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 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 web à l'image -_image:Nom c=CSS t=https://... w=320px h=240 # 240px -``` - -### Code brut depuis un fichier -``` -_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 -(( -Pfff, vraiment ! -)) -]] +## Créer un domaine ```` +mkdir -p MONDOMAIN +cd MONDOMAIN +tyto new domain URL +```` + +# Créer un article +https://tyto.echolib.re/%C3%A9crire/ ``` -# Source: citation basique -[[ -Une citation simple, et sans paragraphe -]] +cd articles/ +tyto new index +tyto edit index.tyto +``` + +# Vérifier, prévisualiser un article +``` +tyto check index.tyto +tyto wip index.tyto +``` + +# Les modules +https://tyto.echolib.re/usages/modules.html + +La barre latérale, le menu, le pied de page et les balises génériques metas +ne seront pas visible localement sans serveur nginx. + +Utiliser l'option --static avec la commande wip pour les voir. Attention, +utiliser la commande publish après avoir utilisé l'option --static sur wip +mettra en ligne la version statique de la page. Il faut donc avant la +commande publish, recommencer la commande wip sur un article sans l'option +--static pour utiliser l'include de nginx (comportement par défaut) + + +# Publier ! +``` +# La première fois, ou après mise à jour des modules ou des fichiers (logo, css...) +tyto publish template + +# Mettre dans le dossier "www" officiel +tyto publish index.tyto ``` diff --git a/debian/control b/debian/control index 77c6364..12fef31 100644 --- a/debian/control +++ b/debian/control @@ -1,5 +1,5 @@ Package: tyto -Version: 0.10.2 +Version: 1.0.0 Section: custom Priority: optional Architecture: all @@ -7,4 +7,4 @@ Essential: no Depends: nano,python3 Installed-Size: `du -ks .|cut -f 1` Maintainer: echolib -Description: Tyto - Litterateur is a libre project to create and manage multiple websites from articles files. Tyto uses its own syntax to convert your articles in HTML5 pages. Tyto works on a GNU/Linux system and needs minimal dependencies. +Description: Tyto - Litterateur is a libre project in FR/EN to create and manage multiple static websites from articles files. Tyto uses its own syntax to convert your articles in HTML5 pages. Tyto works on a GNU/Linux system and needs minimal dependencies. diff --git a/src/usr/bin/tyto b/src/usr/bin/tyto index e4e7998..f2198e5 100755 --- a/src/usr/bin/tyto +++ b/src/usr/bin/tyto @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Version: 0.10.2 +# Version: 1.0.0 # Tyto - Littérateur # # Copyright (C) 2023 Cyrille Louarn @@ -24,28 +24,28 @@ # File: /usr/bin/tyto #---------------------------------------------------------------------- -#------------ -# funny stats -#------------ -# scripts files: -# app lines: -# app comments: -# app functions: -# lines: -# functions: -# comments: -#---------------------------------------------------------------------- - -#********************************************************************** +#------------------------- +# Funny Stats Project +#------------------------- +# Project files : 20 +# Project lines : 7508 +# Project comments : 1153 +# Project functions: 109 +# Project program : 5652 +# +# file lines : 93 +# file comments : 33 +# file functions: 0 +# file program : 47 +#-------------------------- import sys sys.path.insert(0, '/var/lib/tyto/program') - #====================# # MAIN # # Treat Arguments # -#--------------------#------------------------------------------------- +#--------------------# import logs if not __name__ == "__main__": @@ -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, + "help" : infos.tyto, + "edit" : show.manage, + "edit-about" : show.manage, + "edit-db" : show.manage, + "edit-wip" : show.manage, + "edit-www" : show.manage, + "force-wip" : wip.manage, + "new" : new.manage, + "publish" : publish.manage, + "preview" : show.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, + "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..acf053b --- /dev/null +++ b/src/usr/share/bash-completion/completions/tyto @@ -0,0 +1,311 @@ +#!/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 +#---------------------------------------------------------------------- + +#------------------------- +# Funny Stats Project +#------------------------- +# file lines : 311 +# file comments : 45 +# file functions: 0 +# file program : 234 +#-------------------------- + + +#=================# +# 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 < id -(( -un long paragraphe -)) -(( ->_id:Retourner au point d'ancre_< -)) -``` - -### Retour à la ligne HTML -``` -| #
-``` - -### Lien vers URL -``` -Voir ce _Nom du lien # Ouverture même fenêtre -Voir ce _Nom du lien+ # ouverture nouvelle fenêtre -``` - -### Lien vers fichier -``` -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: - -### Gras, Strong, italique... -``` -*_très gras_* # -+_gras léger_+ # -/_en italique_/ # -[_en italique_] # -~_texte barré_~ # -{_Code_} # -:_Citation rapide_: # -%_Classe personnalisée_% >>> -._Souligné_. # - -``` - -### 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. -``` - -### Images -``` -# Chaque image doit être placée en début de ligne -# Placer dans un paragraphe pour chaque 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 -``` - -### Code Brut depuis un fichier -``` -_brut:NOM +# Mettre dans le dossier "www" officiel +tyto publish index.tyto ``` diff --git a/src/var/lib/tyto/help/styles.css b/src/var/lib/tyto/help/styles.css index 2dacdf7..8afea19 100644 --- a/src/var/lib/tyto/help/styles.css +++ b/src/var/lib/tyto/help/styles.css @@ -3,12 +3,23 @@ * DOMAIN MUST be changed by domain css set in configuration */ -/* + +/* include header to footer */ +div#site_container { +} + +/* Include article + sidebar */ +div#article_sidebar_container { +} + + +/*===================================================================== * Header */ header#header_page { } +/* Block */ div#site_logo { } @@ -18,6 +29,7 @@ a#site_logo_link { img#site_logo_image { } +/* Block */ div#site_infos { } @@ -31,7 +43,7 @@ p#site_about { } -/* +/*===================================================================== * navbar */ nav#site_menu { @@ -46,16 +58,18 @@ li.site_menu_item { a.site_menu_link { } -/* + +/*===================================================================== * article */ article#article_main { } -h1#main_title { -} -h2.title_2 { +/* article title */ +h2#main_title { } + +/* Writer titles*/ h3.title_3 { } h4.title_4 { @@ -65,9 +79,17 @@ h5.title_5 { h6.title_6 { } -/* Between every IF CONTENTS */ +/* Between every IF CONTENTS */ div.contents { } +div.contents_2 { +} +div.contents_3 { +} +div.contents_4 { +} +div.contents_5 { +} /* Default if not set in post */ p.DOMAIN { @@ -78,6 +100,12 @@ br.DOMAIN { a.link { } +a.link-file { +} + +/* When block quote with _cite:*/ +a.figc { +} a.anchor_link { } @@ -88,31 +116,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 { @@ -132,13 +161,19 @@ span#article_code { a#article_code_link { } -/* + +/* Sitemap */ +ul.sitemap { +} + + +/*===================================================================== * sidebar */ aside#sidebar { } -h1#sidebar_title { +h2#sidebar_title { } ul#sidebar_list { } @@ -146,13 +181,13 @@ li.sidebar_item { } a.sidebar_item_link { } -h2.sidebar_item_title { +h3.sidebar_item_title { } p.sidebar_item_about { } -/* +/*===================================================================== * footer */ footer#footer_page { @@ -165,7 +200,7 @@ div#footer_container { /* Block*/ div#footer_infos { } -h1#footer_site_title { +h2#footer_site_title { } p#footer_about { } @@ -187,5 +222,3 @@ p.footer_copyright { } p.footer_generator { } - - diff --git a/src/var/lib/tyto/tyto_domain.default b/src/var/lib/tyto/help/tyto_domain.default similarity index 75% rename from src/var/lib/tyto/tyto_domain.default rename to src/var/lib/tyto/help/tyto_domain.default index f6f48c2..6b2404d 100644 --- a/src/var/lib/tyto/tyto_domain.default +++ b/src/var/lib/tyto/help/tyto_domain.default @@ -3,9 +3,9 @@ directory = "" database = "" # Local user configuration -lang_sys = "SYS" +lang_sys = "" local_user = "" -lang_logs = "SYS" +lang_logs = "" articles_db_d = "" # Working directories @@ -19,7 +19,6 @@ navbar_f = "" sidebar_f = "" metas_f = "" footer_f = "" -footer_about_f = "" # Domain shortname = "" @@ -27,8 +26,8 @@ www_url = "" wip_url = "" # Servers directories -srv_root = "" -srv_domain = "" +srv_root = "/var/www/" +srv_domain = " srv_wip = "" srv_wip_tpl_d = "" srv_wip_images_d = "" @@ -38,36 +37,46 @@ srv_www_tpl_d = "" srv_www_images_d = "" srv_www_files_d = "" -# Servers files +# Servers files (wip) +wip_favicon_f = "" +wip_logo_f = "" +wip_css_f = "" wip_navbar_f = "" wip_sidebar_f = "" wip_metas_f = "" wip_footer_f = "" +wip_stats_f = "" + +# Servers files (www) +www_favicon_f = "" +www_logo_f = "" +www_css_f = "" www_navbar_f = "" www_sidebar_f = "" www_metas_f = "" www_footer_f = "" -wip_logo_f = "" -www_logo_f = "" +www_stats_f = "" www_rss_f = "" # Domain user's settings +favicon = "favicon.png" logo = "logo.png" +styles = "styles.css" rss = "rss.xml" rss_items = 100 title = "" date = "" about = "" -lang_site = "SYS" +lang_site = "" mail = "" tags = "" -license = "" +license = "gfdl-1.3" license_url = "" legal_url = "" terms_url = "" css = "tyto" sep = "-" -article_code = False +article_code = True relme = "" sidebar_title = "" sidebar_items = 6 diff --git a/src/var/lib/tyto/program/args.py b/src/var/lib/tyto/program/args.py index 656df18..69dafa1 100644 --- a/src/var/lib/tyto/program/args.py +++ b/src/var/lib/tyto/program/args.py @@ -23,120 +23,148 @@ # File: /var/lib/tyto/program/args.py #---------------------------------------------------------------------- -#------------ -# funny stats -#------------ -# lines: -# functions: -# comments: -#---------------------------------------------------------------------- +#------------------------- +# Funny Stats Project +#------------------------- +# file lines : 174 +# file comments : 29 +# file functions: 2 +# file program : 135 +#-------------------------- -#********************************************************************** import os, sys import infos +try: + action + target -# Arguments from command line -# tyto [action] [target] -#---------------------------- -actions = \ -( -'check', -'edit', -'edit-about', -'edit-db', -'edit-wip', -'edit-www', -'help', -'new', -'show', -'show-about', -'show-db', -'show-wip', -'show-www', -'status', -'wip', -'publish' -) +except: -option = \ -( -'--static', -) - -pass_actions = ('new') - -# Actions that needs to check for article's database -pass_db = \ -( -'check', -'edit', -'edit-db', -'edit-wip', -'edit-www', -'publish', -'show', -'show-about', -'show-db', -'show-wip', -'show-www', -'status', -'wip', -) - -pass_targets = \ -( -'added', -'again', -'updated', -'domain', -'footer', -'metas', -'navbar', -'sidebar', -'stats', -'template' -) - -pass_status = \ -( -'domain', -) - -multi_chk = ('added', 'again', 'updated') - -''' -action = '' -target = '' -option = '' -''' - - -# action -#------- -try: action = sys.argv[1] -except: action = '' - -# With no argument, show help -if not action: - infos.tyto(target) - sys.exit(0) - -# Unused argument [action] -if action in actions: act_err = False -else: act_err = True - - -# target -#------- -try: target = sys.argv[2] -except: target = '' - - -# option -try: option = sys.argv[3] -except: option = '' + # Arguments from command line + # tyto [action] [target] + #---------------------------- + actions = \ + ( + 'check', + 'edit', + 'edit-db', + 'edit-wip', + 'edit-www', + 'force-wip', + 'new', + 'preview', + 'publish', + 'quick-pub', + 'show', + 'show-db', + 'show-wip', + 'show-www', + 'status', + 'wip', + ) + + quicks = \ + ( + 'force-wip', + 'quick-pub', + ) + + options = \ + ( + '--static', + ) + + pass_actions = ('new') + + # Actions that needs to check for article's database + pass_db = \ + ( + 'check', + 'edit', + 'edit-db', + 'edit-wip', + 'edit-www', + 'force-wip', + 'publish', + 'preview', + 'quick-pub', + 'show', + 'show-about', + 'show-db', + 'show-wip', + 'show-www', + 'status', + 'wip', + ) + + pass_targets = \ + ( + 'added', + 'again', + 'updated', + 'domain', + 'footer', + 'metas', + 'navbar', + 'sidebar', + 'sitemap', + 'stats', + 'template' + ) + + pass_status = \ + ( + 'domain', + ) + + multi_chk = \ + ( + 'added', + 'again', + 'updated' + ) + + helps = \ + ( + 'domains', + 'version', + 'help' + ) + + + # action + #------- + try: action = sys.argv[1] + except: action = '' + + act_err = False + + # With no argument, show help + if not action: + infos.tyto('full') + sys.exit(0) + + elif action in helps: + infos.tyto(action) + + # Unused argument [action] + elif not action in actions: + act_err = True + + + # target + #------- + try: + target = sys.argv[2] + except: + infos.tyto('full') + sys.exit(0) + + # options + try: option = sys.argv[3] + except: option = '' # Set action and target for binary def set_action(): diff --git a/src/var/lib/tyto/program/check.py b/src/var/lib/tyto/program/check.py index 144d08b..bea51a9 100644 --- a/src/var/lib/tyto/program/check.py +++ b/src/var/lib/tyto/program/check.py @@ -24,21 +24,19 @@ # File: /var/lib/tyto/program/check.py #---------------------------------------------------------------------- -#------------ -# funny stats -#------------ -# lines: -# functions: -# comments: -#---------------------------------------------------------------------- +#------------------------- +# Funny Stats Project +#------------------------- +# file lines : 1146 +# file comments : 163 +# file functions: 25 +# file program : 873 +#-------------------------- -#********************************************************************** - -# Import needed libs import time, importlib, sys, os, re, datetime from datetime import datetime from time import gmtime, strftime -import args, dom, logs, status, db, form, tyto, langs, wip +import args, dom, logs, status, db, form, tyto, langs, wip, html domain_dir = post_err = multi_chk = False @@ -68,12 +66,13 @@ def manage(target): logs.out("1", db.uri_file, True) # Already check - elif db.exists and not db.old_chk: - 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 '%( - langs.site.check_a, langs.site.q - ), True) + elif db.exists: + db.show_title() + if not db.old_chk and not args.option == "--force": + logs.out("20", '%s > %s'%(db.date_chk, db.uri_file), False) + answer = form.asking(' ├ %s%s '%( + langs.site.check_a, langs.site.q + ), True) check_process(target) else: @@ -88,7 +87,7 @@ def manage(target): # Argument is a module name # # Check if modules files exists # #-------------------------------# -def check_module(target): +def check_module(target): if target == "domain": status.check(target) return @@ -100,8 +99,10 @@ def check_module(target): if not os.path.exists(t): logs.out("24", t, False) unused_f = True + if not unused_f: logs.out("28", "%s"%langs.log.all_ok, False) + except: logs.out("28", "%s + %s"%(args.action, target), True) @@ -121,6 +122,7 @@ def check_all(option): # Then Do a check, and return #----------------------------------------- if option == "added": + no_post = True for root, dirs, files in os.walk(dom.articles_d[:-1]): for file in files: if (file.endswith('.tyto')): @@ -131,9 +133,13 @@ def check_all(option): if os.path.exists(db_config): continue + no_post = False importlib.reload(db) check_process(args.target) print() + + if no_post: + logs.out("28", '%s'%langs.log.nonewpost, True) return # With [updated], Article must have changed @@ -166,15 +172,25 @@ def check_all(option): # Check articles process # #------------------------# def check_process(target): + global post_err + if not db.post: - logs.out("1", db.post, True) + logs.out("1", db.post, False) + post_err = True + return + + # Start checking processes + #------------------------- + # Convert file to string + # Also check for separator and empty article + file_to_string() + if post_err: + return global post_bottom, article_bottom global date_wip, hash_wip, date_www, hash_www, post_bottom - global post_err date_wip = hash_wip = date_www = hash_www = '' - post_err = False # Set values for wip and www from DB if db.exists: @@ -213,12 +229,6 @@ def check_process(target): http_www = "%s/%s"%(dom.www_url, srv_post_short_uri) http_wip = '%s/%s'%(dom.wip_url, srv_post_short_uri) - # Start checking processes - #------------------------- - # Convert file to string - # Also check for separator and empty article - file_to_string() - # Check for icodes, bcodes, quotes # check icodes marks on same line if_icodes_bcodes_quotes(post_bottom) @@ -229,10 +239,12 @@ 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')) if post_err: @@ -241,15 +253,22 @@ def check_process(target): return print(' │\n ├ [%s] > %s'%(title, db.uri_file)) + + # Check optional tags configuration check_opt_tags(post_header.rsplit('\n')) if post_err: if db.exists and tyto.exists(db.config): os.remove(db.config) return - - # Check for valid contents - check_content(post_bottom) + check_titles() # #1-5 (titles) + check_words_tags() # Strongs, italics... + check_blocks_tags() # Paragraphs, quotes... + check_anchors() # Anchors + check_contents_list() # Lists ul/ol contents + check_legacy_HTML() # Real HTML tags + check_tags_set() # Check _TAG:Name (_image:Name) + check_contents_writer() # Convinience # Remove db (if exists) on post error and return if post_err: @@ -269,14 +288,22 @@ def check_process(target): # Check if separator or exit # #---------------------------------# def file_to_string(): + global post_err global article, post_header, post_bottom global ln_header, ln_bottom, ln_article + post_err = False post_header = post_bottom = '' sep = content = False article = open(db.uri_file, 'r').read() for line in article.rsplit('\n'): + if line.startswith(logs.shebang): + print(' │') + logs.out("82", db.uri_file, False) + post_err = True + return + if line.startswith('-----'): if not sep: sep = True @@ -292,12 +319,17 @@ def file_to_string(): # Check if separator or exit if not sep: - logs.out("6", '"-----" > %s'%db.uri_file, True) + print(' │') + logs.out("6", '"-----" > %s'%db.uri_file, False) + post_err = True + return if not content: if db.exists and tyto.exists(db.config): os.remove(db.config) - logs.out("18", db.uri_file, True) + logs.out("18", db.uri_file, False) + post_err = True + return # +2 > (start at 0 + separator line) ln_article = len(article.splitlines()) + 1 @@ -313,11 +345,11 @@ def file_to_string(): def count_words(post_bottom): global post_words post_words = 0 + for line in post_bottom: if not line \ or line.startswith(tyto.nolinewords) \ - or line.startswith("#") and \ - not line.startswith(tyto.titles_tags): + or line.startswith("#") and not line.startswith(tyto.titles_user): continue post_words = post_words + len(line.strip().split(" ")) @@ -330,11 +362,11 @@ def count_words(post_bottom): #---------------------------------------------# def if_icodes_bcodes_quotes(post_bottom): global icode, quote, bcode, post_err - global post_titles, nbr_quotes, nbr_bcodes, nbr_ancs, post_comments + global nbr_quotes, nbr_bcodes, nbr_ancs, post_comments global post_images, post_raws, fcodes icode = quote = in_quote = bcode = in_bcode = in_bq = False - post_titles = nbr_quotes = nbr_bcodes = nbr_ancs = 0 + nbr_quotes = nbr_bcodes = nbr_ancs = 0 post_images = post_comments = post_raws = fcodes = 0 for ln, line in enumerate(post_bottom.rsplit('\n'), 1): @@ -363,10 +395,7 @@ def if_icodes_bcodes_quotes(post_bottom): if in_bq: continue - elif line.startswith(tyto.titles_tags): - post_titles += 1 - continue - elif line.startswith('#'): + elif line.startswith('#') and not line.startswith(tyto.titles_user): post_comments += 1 continue elif line.startswith(tyto.single_tags[1][0]): @@ -380,14 +409,14 @@ def if_icodes_bcodes_quotes(post_bottom): fcodes += 1 # icodes - elif tyto.words_tags[9][0] or tyto.words_tags[9][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[9][0]) - icode_m2 = line.count(tyto.words_tags[9][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[9][0], tyto.words_tags[9][1], + tyto.icode_tags[0], tyto.icode_tags[1], db.uri_file ), False ) @@ -402,23 +431,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(",")) @@ -428,8 +464,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 @@ -724,6 +758,22 @@ def check_snpic(name): def check_anchors(): global post_err + c_opened = c_closed = 0 + c_opened = post_bottom.count(tyto.anchor_tags[0]) + c_closed = post_bottom.count(tyto.anchor_tags[1]) + + if c_opened != c_closed: + logs.out("8", '%s "%s" + "%s" > %s'%( + tyto.anchor_tags[4], + tyto.anchor_tags[0], tyto.anchor_tags[1], + db.uri_file + ), False) + post_err = True + return + + globals()['post_%s'%tyto.anchor_tags[4]] = int(c_opened) + + # Anchor target if nbr_ancs > 0: # Create anchors names targets @@ -754,31 +804,51 @@ def check_anchors(): post_err = True return - # Check in anchor link has target one + # Check if anchor link has target one else: for ln, line in enumerate(post_bottom.rsplit('\n'), 1): + ln = ln + ln_header + 1 + # Anchor link - if tyto.words_tags[0][0] and tyto.words_tags[0][1] in line: + if tyto.anchor_tags[0] and tyto.anchor_tags[1] in line: anchors = re.findall(r">_(.*?)_<", line) for anchor in anchors: anchor_name = anchor.rsplit(':')[0].lstrip() if not anchor_name in anchors_names: logs.out("12", 'L=%s. anchor "%s" > %s'%( - ln + 1 + ln_header, anchor_name, db.uri_file + ln, anchor_name, db.uri_file ), False) post_err = True -#===========================# -# Check tags in post_bottom # -#---------------------------# -def check_content(post_bottom): - global post_err +#==========================# +# Check titles and content # +#--------------------------# +def check_titles(): + global post_err, post_titles + post_titles = 0 + + for ln, line in enumerate(post_bottom.rsplit('\n'), 1): + ln = ln + ln_header + 1 - # Check tags for words (strongs, italics...) - # Set stats for each one - #------------------------------------------- - for tag in tyto.words_tags: + if line.startswith(tyto.titles_user): + title_name = line[2: len(line)].lstrip() + if not title_name: + post_err = True + logs.out("84", 'L=%s > %s'%(ln, db.uri_file), False) + continue + + post_titles += 1 + + +#============================================# +# Check tags for words (strongs, italics...) # +# Set stats for each one # +#--------------------------------------------# +def check_words_tags(): + global post_err, post_bottom + + for tag in tyto.markers_tags: c_opened = c_closed = 0 c_opened = post_bottom.count(tag[0]) @@ -794,12 +864,16 @@ def check_content(post_bottom): post_err = True else: - globals()['post_%s'%tag[4]] = int(c_opened) + globals()['post_%s'%tag[4]] = int(c_opened) - # Check block tags paragraphs, qyotes...) - # Set stats for each one - #------------------------------------------- +#=========================================# +# Check block tags paragraphs, quotes...) # +# Set stats for each one # +#-----------------------------------------#- +def check_blocks_tags(): + global post_err + for tag in tyto.block_tags: c_opened = c_closed = 0 @@ -817,18 +891,18 @@ def check_content(post_bottom): globals()['post_%s'%tag[4]] = int(c_opened) - # Check if anchor has target - # Count anchors target - #--------------------------- - check_anchors() +#====================================# +# Lists: check if contents are valid # +#------------------------------------# +def check_contents_list(): + global post_err - - # Lists: check if contents are valid - #----------------------------------- if post_lists > 0: inlist = False for ln, line in enumerate(post_bottom.rsplit('\n'), 1): - if line.startswith(tyto.block_tags[3][0]): + ln = ln + ln_header + 1 + + if line.startswith(tyto.block_tags[3][0]): inlist = True continue elif line.startswith(tyto.block_tags[3][1]): @@ -839,16 +913,39 @@ def check_content(post_bottom): if inlist and not line or not line[0] in tyto.markers_lists: logs.out("3", 'L=%s. %s %s > %s'%( - ln + ln_header, + ln, tyto.block_tags[3][4], tyto.markers_lists, db.uri_file ), False) post_err = True - + + +#==================================# +# Legacy HTML Tags, check if aired # +#----------------------------------# +def check_legacy_HTML(): + global post_err - # Check for all match _TAGS:NAME from content in header - #------------------------------------------------------ + for tag in tyto.leg_html_tags: + leg1 = post_bottom.count(tag[0]) + leg2 = post_bottom.count(tag[1]) + + if leg1 != leg2: + logs.out("8", '"%s" + "%s" > %s'%( + tag[0], tag[1], db.uri_file + ), False) + post_err = True + + +#================================# +# Check for all match _TAGS:NAME # +# (from content in header) # +# _image:, _raw:... # +#--------------------------------# +def check_tags_set(): + global post_err + set_tags = () for ln, line in enumerate(post_bottom): for htag in tyto.head_tags: @@ -866,23 +963,13 @@ def check_content(post_bottom): if match: continue else: logs.out("12", "%s %s"%(htag, ptag_set), False) - post_err = True - + post_err = True - # Legacy HTML not paired error - for tag in tyto.leg_html_tags: - leg1 = post_bottom.count(tag[0]) - leg2 = post_bottom.count(tag[1]) - - if leg1 != leg2: - logs.out("8", '"%s" + "%s" > %s'%( - tag[0], tag[1], db.uri_file - ), False) - post_err = True - - # Template Tags (warning for not paired symbols) - #----------------------------------------------- +#================================================# +# Template Tags (warning for not paired symbols) # +#------------------------------------------------# +def check_contents_writer(): for tag in tyto.tpl_tags: tpl1 = post_bottom.count(tag[0]) tpl2 = post_bottom.count(tag[1]) @@ -910,7 +997,7 @@ def check_static_posts(): try: post_datas = open(srv_post, "r").read() if not re.findall( - tyto.tags_html_mods[dom.wip_metas_f], + html.tags_html_mods[dom.wip_metas_f], post_datas ): globals()[static] = "True" @@ -936,6 +1023,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 + \ @@ -943,20 +1031,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..f4f3e64 --- /dev/null +++ b/src/var/lib/tyto/program/creators.py @@ -0,0 +1,241 @@ +#!/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 Project +#------------------------- +# file lines : 241 +# file comments : 41 +# file functions: 3 +# file program : 182 +#-------------------------- + + +import os, importlib, datetime, subprocess +import args, dom, db, langs, tyto, check, wip, logs + + +#========================# +# Manage action [create] # +#------------------------# +def manage(target): + target = args.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 new 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' + \ + '|\n' + \ + '
\n' + \ + '|\n' + \ + '\n' + \ + '%s\n' + + tab = 8 + uri_dir_set = "" + + # Contents in article's Header + links = "" + + # Index of all links in article + index_l = '-( index\n= /' + + # All links in sitemap + contents = '-( sitemap\n= / ' + + # 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 + + # Take only .tyto files + for f in files: + if not f.endswith(".tyto"): + continue + + 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 + curr_dir = uri_dir.count("/") + root_dir = uri_dir.rsplit("/")[0] + ranc_dir = root_dir.replace(" ", "_") + + + try: prev_dir + except: prev_dir = curr_dir + + try: name_dir + except: name_dir = root_dir + + #print(":",prev_dir, name_dir, curr_dir, root_dir) + #print(": %s"%(uri_dir.rsplit("/")[int(curr_dir - 1)])) + #print(">", subdirs, uri_dir.rsplit("/")) + #print(":", prev_dir, curr_dir) + if name_dir != root_dir: + index_l = '%s\n= %s'%( + index_l, + ranc_dir, + root_dir + ) + contents = '%s\n%s [%s] '%( + contents, + int(curr_dir) * "=", + root_dir, + ranc_dir + ) + name_dir = root_dir + prev_dir = curr_dir + + if prev_dir != curr_dir: + sanc_dir = uri_dir.rsplit("/")[int(curr_dir - 1)].replace(" ", "_") + index_l = '%s\n%s %s'%( + index_l, + int(curr_dir) * "=", + sanc_dir, + uri_dir.rsplit("/")[int(curr_dir - 1)] + ) + contents = '%s\n%s [%s] '%( + contents, + int(curr_dir) * "=", + uri_dir.rsplit("/")[int(curr_dir - 1)], + sanc_dir + ) + prev_dir = curr_dir + + contents = "%s\n%s _%s"%( + contents, + int(curr_dir + 1) * '=', + db.title + ) + + # Ending markers + index_l = "%s\n-)"%index_l + contents = "%s\n-)"%contents + + # Fill new sitemap.tyto and create + sitemap_tyto = \ + sitemap_tyto%( + nbr_files, + links, + index_l, + contents + ) + sitemap_file = "%ssitemap.tyto"%dom.articles_d + tyto.set_file(sitemap_file, "New", sitemap_tyto) + + # Check and wip + print() + www = subprocess.run( + [ + '/usr/bin/tyto', + 'force-wip', + 'sitemap.tyto' + ], + ) diff --git a/src/var/lib/tyto/program/db.py b/src/var/lib/tyto/program/db.py index a488d9d..cce60ad 100644 --- a/src/var/lib/tyto/program/db.py +++ b/src/var/lib/tyto/program/db.py @@ -23,15 +23,15 @@ # File: /var/lib/tyto/program/db.py #---------------------------------------------------------------------- -#------------ -# funny stats -#------------ -# lines: -# functions: -# comments: -#---------------------------------------------------------------------- +#------------------------- +# Funny Stats Project +#------------------------- +# file lines : 206 +# file comments : 37 +# file functions: 1 +# file program : 152 +#-------------------------- -#********************************************************************** import os import args, logs, dom, form, tyto, check, publish @@ -79,62 +79,63 @@ if args.target \ # Check if database config is valid (contains values) if exists: values = \ - ( - 'post_id', - 'post_src', - 'post_wip', - 'static_wip', - 'post_www', - 'static_www', - 'direc_src', - 'short_src', - 'short_srv', - 'sub_uri', - 'http_wip', - 'http_www', - 'date_chk', - 'hash_chk', - 'date_wip', - 'hash_wip', - 'date_www', - 'hash_www', - 'title', - 'about', - 'author', - 'meta_tags', - 'date', - 'snpic', - 'uris', - 'uniq_anchors', - 'uniq_abbrs', - 'uniq_links', - 'uniq_images', - 'uniq_files', - 'uniq_raws', - 'comments', - 'tags', - 'words', - 'titles', - 'paragraphs', - 'links', - 'images', - 'anchors', - 'abbrs', - 'strongs', - 'bolds', - 'emphasis', - 'italics', - 'dels', - 'underlines', - 'cites', - 'customs', - 'icodes', - 'bcodes', - 'quotes', - 'lists', - 'files', - 'raws', - 'codes', + ( + 'post_id', + 'post_src', + 'post_wip', + 'static_wip', + 'post_www', + 'static_www', + 'direc_src', + 'short_src', + 'short_srv', + 'sub_uri', + 'http_wip', + 'http_www', + 'date_chk', + 'hash_chk', + 'date_wip', + 'hash_wip', + 'date_www', + 'hash_www', + 'title', + 'about', + 'author', + 'meta_tags', + 'date', + 'snpic', + 'sitemap', + 'uris', + 'uniq_anchors', + 'uniq_abbrs', + 'uniq_links', + 'uniq_images', + 'uniq_files', + 'uniq_raws', + 'comments', + 'tags', + 'words', + 'titles', + 'paragraphs', + 'links', + 'images', + 'anchors', + 'abbrs', + 'strongs', + 'bolds', + 'emphasis', + 'italics', + 'dels', + 'underlines', + 'cites', + 'customs', + 'icodes', + 'bcodes', + 'quotes', + 'lists', + 'files', + 'raws', + 'codes', ) # Set exist for wip and www files @@ -193,3 +194,13 @@ if args.target \ # Article is updated on both servers if hash_chk == hash_wip == hash_www: sync_srvs = True + + +#=========================# +# Show title and uri file # +#-------------------------# +def show_title(): + try: + print(' ├ "%s" > %s'%(title, uri_file)) + except: + return diff --git a/src/var/lib/tyto/program/dom.py b/src/var/lib/tyto/program/dom.py index df5182d..224a6ea 100644 --- a/src/var/lib/tyto/program/dom.py +++ b/src/var/lib/tyto/program/dom.py @@ -23,271 +23,291 @@ # File: /var/lib/tyto/program/dom.py #---------------------------------------------------------------------- -#------------ -# funny stats -#------------ -# lines: -# functions: -# comments: -#---------------------------------------------------------------------- +#------------------------- +# Funny Stats Project +#------------------------- +# file lines : 318 +# file comments : 31 +# file functions: 1 +# file program : 277 +#-------------------------- -#********************************************************************** import os, sys, importlib, langs import args -lib = 'tyto_domain' -exists = incomplete = active = ready = shortname = corrupt = False -local_user = articles_db_d = False -hole = False -# Set current directory try: - user_dir + ready + except: + + lib = 'tyto_domain' + exists = incomplete = active = ready = shortname = corrupt = False + local_user = articles_db_d = False + hole = False + + # Set current directory try: - user_dir = os.getcwd() + "/" + user_dir except: - hole = True - -# Settings for domain, check if db is not corrupted -dom_values = \ -( -'directory', -'database', -'local_user', -'lang_sys', -'lang_logs', -'articles_db_d', -'articles_d', -'files_d', -'images_d', -'modules_d', -'navbar_f', -'sidebar_f', -'metas_f', -'footer_f', -'footer_about_f', -'shortname', -'www_url', -'wip_url', -'srv_root', -'srv_domain', -'srv_wip', -'srv_wip_tpl_d', -'srv_wip_images_d', -'srv_wip_files_d', -'srv_www', -'srv_www_tpl_d', -'srv_www_images_d', -'srv_www_files_d', -'wip_css_f', -'wip_logo_f', -'wip_navbar_f', -'wip_sidebar_f', -'wip_metas_f', -'wip_footer_f', -'wip_stats_f', -'www_css_f', -'www_navbar_f', -'www_sidebar_f', -'www_metas_f', -'www_footer_f', -'www_stats_f', -'www_logo_f', -'www_rss_f', -'logo', -'styles', -'rss', -'rss_items', -'title', -'date', -'about', -'lang_site', -'mail', -'tags', -'license', -'license_url', -'legal_url', -'terms_url', -'css', -'sep', -'article_code', -'relme', -'sidebar_title', -'sidebar_items', -'activated' -) - -create_files = \ -( -'navbar_f', -'sidebar_f', -'metas_f', -'footer_f', -'footer_about_f' -) - -wip_html_mods = () -err_val = (()) # Make a list from values error -file_unu = (()) # Make a list for files to check -file_mod = (()) # male a list for modules files to create -dir_new = (()) # Make a list for directories created -dir_unu = (()) # Not created, unused - - -if not hole: - home_dir = os.path.expanduser('~') - - # Set configuration domain directory - root_dir = user_dir - if '/articles' in user_dir: - root_dir = user_dir.rsplit('/articles')[0] + "/" - - # Set configuration domain file - config = '%styto_domain.py'%root_dir - shortname = config - - # Set exists if configuration file - if os.path.exists(config): - exists = True try: - exec(open(config).read()) - try: - os.path.exists(articles_d) - if '/articles' in user_dir: - user_uri_dir = user_dir.rsplit(articles_d)[1] - else: - user_uri_dir = '' - os.chdir(articles_d) - except: corrupt = True + user_dir = os.getcwd() + "/" except: - corrupt = True - - if not args.target in args.pass_targets: - if args.target.startswith("articles/"): - args.target = args.target.rsplit("articles/")[1] - args.target = user_uri_dir + args.target + hole = True + + # Set current user name + try: + user + except: + try: + user = os.environ.get('USER') + except: + user = '' + + + # Settings for domain, check if db is not corrupted + dom_values = \ + ( + 'directory', + 'database', + 'local_user', + 'lang_sys', + 'lang_logs', + 'articles_db_d', + 'articles_d', + 'files_d', + 'images_d', + 'modules_d', + 'navbar_f', + 'sidebar_f', + 'metas_f', + 'footer_f', + 'shortname', + 'www_url', + 'wip_url', + 'srv_root', + 'srv_domain', + 'srv_wip', + 'srv_wip_tpl_d', + 'srv_wip_images_d', + 'srv_wip_files_d', + 'srv_www', + 'srv_www_tpl_d', + 'srv_www_images_d', + 'srv_www_files_d', + 'wip_favicon_f', + 'wip_css_f', + 'wip_logo_f', + 'wip_navbar_f', + 'wip_sidebar_f', + 'wip_metas_f', + 'wip_footer_f', + 'wip_stats_f', + 'www_navbar_f', + 'www_sidebar_f', + 'www_metas_f', + 'www_footer_f', + 'www_stats_f', + 'www_logo_f', + 'www_css_f', + 'www_rss_f', + 'www_favicon_f', + 'favicon', + 'logo', + 'styles', + 'rss', + 'rss_items', + 'title', + 'date', + 'about', + 'lang_site', + 'mail', + 'tags', + 'license', + 'license_url', + 'legal_url', + 'terms_url', + 'css', + 'sep', + 'article_code', + 'relme', + 'sidebar_title', + 'sidebar_items', + 'activated' + ) + + create_files = \ + ( + 'navbar_f', + 'sidebar_f', + 'metas_f', + 'footer_f', + ) + + wip_html_mods = () + err_val = (()) # Make a list from values error + + if not hole: + home_dir = os.path.expanduser('~') - # For logs: show uri if not shortname known - try: shortname - except: pass + # Set configuration domain directory + root_dir = user_dir + if '/articles' in user_dir: + root_dir = user_dir.rsplit('/articles')[0] + "/" + + # Set configuration domain file + config = '%styto_domain.py'%root_dir + shortname = config - try: active = activated - except: pass - - if not corrupt: - for value in dom_values: + # Set exists if configuration file + if os.path.exists(config): + exists = True + try: + exec(open(config).read()) try: - eval(str(value)) - value_set = True - except: - err_val = err_val + ((value),) - value_set = False - incomplete = True - active = False - - - if value.endswith('_d'): - if value_set: - if not os.path.exists(eval(str(value))): - try: - os.makedirs(eval(str(value)), exist_ok=True) - dir_new = dir_new + ((eval(str(value))),) - except: - dir_unu = dir_unu + ((eval(str(value))),) - - elif value.endswith('_f'): - if value_set: - if not os.path.exists(eval(str(value))): - if value in create_files: - file_mod = file_mod + ((value),) - else: - file_unu = file_unu + ((eval(str(value))),) - - - #==============================================# - # When an active and complete domain is needed # - #----------------------------------------------# - if exists and not incomplete and not corrupt: - wip_html_mods = \ - ( - eval(str('wip_navbar_f')), - eval(str('wip_sidebar_f')), - eval(str('wip_metas_f')), - eval(str('wip_footer_f')) - ) - if active: - ready = True - - metas = ( - eval(str('metas_f')), - eval(str('wip_metas_f')), - eval(str('www_metas_f')) - ) - navbars = ( - eval(str('navbar_f')), - eval(str('wip_navbar_f')), - eval(str('www_navbar_f')) - ) - sidebars = ( - eval(str('sidebar_f')), - eval(str('wip_sidebar_f')), - eval(str('www_sidebar_f')) - ) - footers = ( - eval(str('footer_f')), - eval(str('wip_footer_f')), - eval(str('www_footer_f')), - eval(str('footer_about_f')) - ) - - templates = ( - eval(str('wip_logo_f')), - eval(str('wip_css_f')), - eval(str('wip_navbar_f')), - eval(str('wip_sidebar_f')), - eval(str('wip_metas_f')), - eval(str('wip_footer_f')), - eval(str('wip_stats_f')), - eval(str('www_logo_f')), - eval(str('www_css_f')), - eval(str('www_navbar_f')), - eval(str('www_sidebar_f')), - eval(str('www_metas_f')), - eval(str('www_footer_f')), - eval(str('www_stats_f')), - eval(str('www_rss_f')), - ) - - modules = { - "metas" : metas, - "navbar" : navbars, - "sidebar" : sidebars, - "footer" : footers, - "template": templates, - } + os.path.exists(articles_d) + if '/articles' in user_dir: + user_uri_dir = user_dir.rsplit(articles_d)[1] + else: + user_uri_dir = '' + os.chdir(articles_d) + except: corrupt = True + except: + corrupt = True - templates_wip = { - eval(str('wip_logo_f')), - eval(str('wip_css_f')), - eval(str('wip_navbar_f')), - eval(str('wip_sidebar_f')), - eval(str('wip_metas_f')), - eval(str('wip_footer_f')), - eval(str('wip_stats_f')), - } + if not args.target in args.pass_targets: + if args.target.startswith("articles/"): + args.target = args.target.rsplit("articles/")[1] + args.target = user_uri_dir + args.target + + # For logs: show uri if not shortname known + try: shortname + except: pass + + try: active = activated + except: pass + + # Check set values configuration + if not corrupt: + for value in dom_values: + try: + eval(str(value)) + value_set = True + except: + err_val = err_val + ((value),) + value_set = False + incomplete = True + active = False - templates_www = { - eval(str('www_logo_f')), - eval(str('www_css_f')), - eval(str('www_navbar_f')), - eval(str('www_sidebar_f')), - eval(str('www_metas_f')), - eval(str('www_footer_f')), - eval(str('www_stats_f')), - eval(str('www_rss_f')) - } + + #==============================================# + # When an active and complete domain is needed # + #----------------------------------------------# + if exists and not incomplete and not corrupt: + if active: + ready = True + + wip_html_mods = \ + ( + eval(str('wip_navbar_f')), + eval(str('wip_sidebar_f')), + eval(str('wip_metas_f')), + eval(str('wip_footer_f')) + ) + www_html_mods = \ + ( + eval(str('www_navbar_f')), + eval(str('www_sidebar_f')), + eval(str('www_metas_f')), + eval(str('www_footer_f')) + ) + metas = \ + ( + eval(str('metas_f')), + eval(str('wip_metas_f')), + eval(str('www_metas_f')) + ) + navbars = \ + ( + eval(str('navbar_f')), + eval(str('wip_navbar_f')), + eval(str('www_navbar_f')) + ) + sidebars = \ + ( + eval(str('sidebar_f')), + eval(str('wip_sidebar_f')), + eval(str('www_sidebar_f')) + ) + footers = \ + ( + eval(str('footer_f')), + eval(str('wip_footer_f')), + eval(str('www_footer_f')), + ) + + templates = \ + ( + eval(str('wip_logo_f')), + eval(str('wip_favicon_f')), + eval(str('wip_css_f')), + eval(str('wip_navbar_f')), + eval(str('wip_sidebar_f')), + eval(str('wip_metas_f')), + eval(str('wip_footer_f')), + eval(str('wip_stats_f')), + eval(str('www_favicon_f')), + eval(str('www_logo_f')), + eval(str('www_css_f')), + eval(str('www_navbar_f')), + eval(str('www_sidebar_f')), + eval(str('www_metas_f')), + eval(str('www_footer_f')), + eval(str('www_stats_f')), + eval(str('www_rss_f')), + ) + + statistics = \ + ( + eval(str('wip_stats_f')), + eval(str('www_stats_f')), + ) + + modules = \ + { + "metas" : metas, + "navbar" : navbars, + "sidebar" : sidebars, + "footer" : footers, + "template": templates, + "stats" : statistics, + } + + templates_files_wip = \ + ( + eval(str('wip_favicon_f')), + eval(str('wip_logo_f')), + eval(str('wip_css_f')), + eval(str('wip_navbar_f')), + eval(str('wip_sidebar_f')), + eval(str('wip_metas_f')), + eval(str('wip_footer_f')), + eval(str('wip_stats_f')), + ) + + templates_files_www = \ + ( + eval(str('www_favicon_f')), + eval(str('www_logo_f')), + eval(str('www_css_f')), + eval(str('www_navbar_f')), + eval(str('www_sidebar_f')), + eval(str('www_metas_f')), + eval(str('www_footer_f')), + eval(str('www_stats_f')), + eval(str('www_rss_f')) + ) #====================================# # Check if domain is ready and ready # @@ -295,3 +315,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 b11665e..f72f529 100644 --- a/src/var/lib/tyto/program/form.py +++ b/src/var/lib/tyto/program/form.py @@ -25,36 +25,38 @@ # File: /var/lib/tyto/program/form.py #---------------------------------------------------------------------- -#------------ -# funny stats -#------------ -# lines: -# functions: -# comments: -#---------------------------------------------------------------------- +#------------------------- +# Funny Stats Project +#------------------------- +# file lines : 1092 +# file comments : 104 +# file functions: 7 +# file program : 872 +#-------------------------- -#********************************************************************** from datetime import datetime import os, sys, shutil, re, locale, importlib import logs, dom, tyto, html, show, langs -# locale translation directory -trans_dir = '/var/lib/tyto/translations' - -# Get default System language try: - lang_sys = locale.getdefaultlocale()[0].split('_')[0] - os.path.exists('%s/site_%s.py'%(trans_dir, lang_sys)) + lang_site except: - lang_sys = 'en' - -lang_site = lang_sys + # locale translation directory + trans_dir = '/var/lib/tyto/translations' + + # Get default System language + try: + lang_sys = locale.getdefaultlocale()[0].split('_')[0] + os.path.exists('%s/site_%s.py'%(trans_dir, lang_sys)) + except: + lang_sys = 'en' + + lang_site = lang_sys # Generic answer -answer_yes = ('y', 'Y', 'yes', 'Yes', 'YES', - 'o', 'O', 'oui', 'Oui', 'Oui' - ) +try: answer_yes +except: answer_yes = langs.answer_yes #=======================================# @@ -72,7 +74,11 @@ def asking(question, yes_no): logs.out("255", '', True) if yes_no: - if not answer in answer_yes: + go = False + for yes_names in answer_yes: + if answer.lower() in yes_names: + go = True + if not go: logs.out("255", '', True) else: @@ -207,7 +213,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 + \ @@ -244,7 +249,28 @@ def create_domain(target): ), False) if answer: logo = answer - if not logo: logo='logo.png' + + # Get css file name + #------------------ + try: css_file = dom.css_file + except: css_file = "styles.css" + + answer = asking(' ├ %s%s {%s} '%( + langs.site.form_css_f, langs.site.q, css_file + ), False) + + if answer: css_file = answer + + # Get favicon file name + #---------------------- + try: favicon_file = dom.favicon_file + except: favicon_file = "favicon.png" + + answer = asking(' ├ %s%s {%s} '%( + langs.site.form_fav_f, langs.site.q, favicon_file + ), False) + + if answer: favicon_file = answer # Set config's directories for servers @@ -256,7 +282,7 @@ def create_domain(target): srv_www_tpl = "%s/www/template/"%root_srv_dom set_f = \ - '# Servers directories\n' + \ + '\n# Servers directories\n' + \ 'srv_root = "%s/"\n'%srv + \ 'srv_domain = "%s/"\n'%root_srv_dom + \ 'srv_wip = "%s/wip/"\n'%root_srv_dom + \ @@ -269,8 +295,9 @@ def create_domain(target): 'srv_www_files_d = "%s/www/files/"\n'%root_srv_dom + \ '\n' + \ '# Servers files (wip)\n' + \ + 'wip_favicon_f = "%s%s"\n'%(srv_wip_tpl, favicon_file) + \ 'wip_logo_f = "%s%s"\n'%(srv_wip_tpl, logo) + \ - 'wip_css_f = "%sstyles.css"\n'%srv_wip_tpl + \ + 'wip_css_f = "%s%s"\n'%(srv_wip_tpl, css_file) + \ 'wip_navbar_f = "%snavbar.html"\n'%srv_wip_tpl + \ 'wip_sidebar_f = "%ssidebar.html"\n'%srv_wip_tpl + \ 'wip_metas_f = "%smetas.html"\n'%srv_wip_tpl + \ @@ -278,13 +305,14 @@ def create_domain(target): 'wip_stats_f = "%s"\n'%stats_wip_f + \ '\n' + \ '# Servers files (www)\n' + \ + 'www_favicon_f = "%s%s"\n'%(srv_www_tpl, favicon_file) + \ 'www_logo_f = "%s%s"\n'%(srv_www_tpl, logo) + \ - 'www_css_f = "%sstyles.css"\n'%srv_www_tpl + \ + 'www_css_f = "%s%s"\n'%(srv_www_tpl, css_file) + \ 'www_navbar_f = "%snavbar.html"\n'%srv_www_tpl + \ 'www_sidebar_f = "%ssidebar.html"\n'%srv_www_tpl + \ 'www_metas_f = "%smetas.html"\n'%srv_www_tpl + \ 'www_footer_f = "%sfooter.html"\n'%srv_www_tpl + \ - 'www_stats_f = "%s"'%stats_www_f + 'www_stats_f = "%s"\n'%stats_www_f tyto.set_file(dom.config, False, set_f) @@ -300,11 +328,13 @@ def create_domain(target): if answer: www_rss = answer - set_f = 'www_rss_f = "%s/www/%s"\n'%(root_srv_dom, rss) + \ - '\n# Domain user\'s settings\n' + \ - 'logo = "%s"\n'%logo + \ - 'styles = "styles.css"\n' + \ - 'rss = "%s"'%rss + set_f = \ + 'www_rss_f = "%s/www/%s"\n'%(root_srv_dom, rss) + \ + '\n# Domain user\'s settings\n' + \ + 'favicon = "%s"\n'%favicon_file + \ + 'logo = "%s"\n'%logo + \ + 'styles = "%s"\n'%css_file + \ + 'rss = "%s"\n'%rss tyto.set_file(dom.config, False, set_f) @@ -322,7 +352,7 @@ def create_domain(target): if not str(rss_items).isdigit() or not int(rss_items) > 1: rss_items = 100 - set_f = 'rss_items = %d'%int(rss_items) + set_f = 'rss_items = %d\n'%int(rss_items) tyto.set_file(dom.config, False, set_f) @@ -339,7 +369,7 @@ def create_domain(target): if not title: invalid = True else: title = tyto.convert_altname(title) - set_f = 'title = "%s"'%title + set_f = 'title = "%s"\n'%title tyto.set_file(dom.config, False, set_f) @@ -354,7 +384,7 @@ def create_domain(target): if answer: date = answer - set_f = 'date = "%s"'%date + set_f = 'date = "%s"\n'%date tyto.set_file(dom.config, False, set_f) @@ -371,7 +401,7 @@ def create_domain(target): if not about: invalid = True else: about = tyto.convert_altname(about) - set_f = 'about = "%s"'%about + set_f = 'about = "%s"\n'%about tyto.set_file(dom.config, False, set_f) @@ -391,7 +421,7 @@ def create_domain(target): if not tyto.exists('%s/site_%s.py'%(trans_dir, lang_site)): lang_site = 'en' - set_f = 'lang_site = "%s"'%lang_site + set_f = 'lang_site = "%s"\n'%lang_site tyto.set_file(dom.config, False, set_f) @@ -404,12 +434,13 @@ def create_domain(target): langs.site.form_mail, langs.site.q, mail ), False) - if answer: mail = answer - if not re.search('^\w+@\w+.\w+$', mail): + if answer: mail = answer + passplus = mail.replace('+', '').replace('-', '') + if not re.search('^\w+@\w+.\w+$', passplus): logs.out("3", mail, False) invalid = True - set_f = 'mail = "%s"'%mail + set_f = 'mail = "%s"\n'%mail tyto.set_file(dom.config, False, set_f) @@ -426,14 +457,14 @@ def create_domain(target): if not tags: invalid = True elif '"' in tags: tags = tags.replace('"', '') - set_f = 'tags = "%s"'%tags + set_f = 'tags = "%s"\n'%tags tyto.set_file(dom.config, False, set_f) # Get License domain #------------------- try: domlicense = dom.license - except: domlicense = 'CC BY-NC-SA 3.0' + except: domlicense = 'gfdl-1.3' answer = asking(' ├ %s%s {%s} '%( langs.site.form_lic, langs.site.q, domlicense @@ -442,14 +473,16 @@ def create_domain(target): if answer: domlicense = answer if '"' in domlicense: domlicense = domlicense.replace('"', '') - set_f = 'license = "%s"'%domlicense + set_f = 'license = "%s"\n'%domlicense tyto.set_file(dom.config, False, set_f) # Get License URL (optional) #--------------------------- try: licurl = dom.license_url - except: licurl = '' + except: + if domlicense == "gfdl-1.3": + licurl = "https://www.gnu.org/licenses/fdl-1.3.txt" answer = asking(' ├ %s [http(s)://...] %s%s {%s} '%( langs.site.form_opt, langs.site.form_licurl, @@ -462,7 +495,7 @@ def create_domain(target): logs.out("2", '"http(s)://%s"%s'%(licurl, langs.site.q), False) licurl = '' - set_f = 'license_url = "%s"'%licurl + set_f = 'license_url = "%s"\n'%licurl tyto.set_file(dom.config, False, set_f) @@ -482,7 +515,7 @@ def create_domain(target): logs.out("2", '"http(s)://%s"%s'%(legalurl, langs.site.q), False) legalurl = '' - set_f = 'legal_url = "%s"'%legalurl + set_f = 'legal_url = "%s"\n'%legalurl tyto.set_file(dom.config, False, set_f) @@ -502,7 +535,7 @@ def create_domain(target): logs.out("2", '"http(s)://%s"%s'%(termsurl, langs.site.q), False) termsurl = '' - set_f = 'terms_url = "%s"'%termsurl + set_f = 'terms_url = "%s"\n'%termsurl tyto.set_file(dom.config, False, set_f) @@ -520,7 +553,7 @@ def create_domain(target): logs.out("3", css, False) css = 'tyto' - set_f = 'css = "%s"'%css + set_f = 'css = "%s"\n'%css tyto.set_file(dom.config, False, set_f) @@ -538,27 +571,27 @@ def create_domain(target): logs.out("3", answer, False) sep = "-" - set_f = 'sep = "%s"'%sep + set_f = 'sep = "%s"\n'%sep tyto.set_file(dom.config, False, set_f) # Show article source ? #---------------------- try: - dom.article_code - article_code = "True" + if dom.article_code: article_code = "True" + else: article_code = "False" except: article_code = "False" - answer = (' ├ %s%s {%s} '%( - langs.site.form_pscode, langs.site.q, article_code + answer = asking(' ├ %s%s {%s} (Y|n) '%( + langs.site.form_pscode, langs.site.q, str(article_code) ), False) if answer: if answer in answer_yes: article_code = "True" else: article_code = "False" - set_f = 'article_code = %s'%article_code + set_f = 'article_code = %s\n'%article_code tyto.set_file(dom.config, False, set_f) @@ -578,7 +611,7 @@ def create_domain(target): logs.out("2", '"http(s)://%s"%s'%(relme, langs.site.q), False) relmel = '' - set_f = 'relme = "%s"'%relme + set_f = 'relme = "%s"\n'%relme tyto.set_file(dom.config, False, set_f) @@ -599,7 +632,7 @@ def create_domain(target): else: sdb_title = tyto.convert_altname(sdb_title) - set_f = 'sidebar_title = "%s"'%sdb_title + set_f = 'sidebar_title = "%s"\n'%sdb_title tyto.set_file(dom.config, False, set_f) @@ -617,7 +650,7 @@ def create_domain(target): if not str(sdb_items).isdigit() or not int(sdb_items) in range(1,17): sdb_items = 6 - set_f = 'sidebar_items = %d'%int(sdb_items) + set_f = 'sidebar_items = %d\n'%int(sdb_items) tyto.set_file(dom.config, False, set_f) @@ -650,13 +683,17 @@ def create_domain(target): # Activate Domain #---------------- tyto.set_file(dom.config, False, '\nactivated = True') - shutil.copy2(dom.config, config_bkp) - logs.out("32", config_bkp, False) - # RELoad config + # ReLoad config #-------------- importlib.reload(dom) + # Backup and create local user dir + if not os.makedirs(dom.articles_db_d, exist_ok=True): + logs.out("33", dom.articles_db_d, False) + shutil.copy2(dom.config, config_bkp) + logs.out("32", config_bkp, False) + # Create folders from configuration file #--------------------------------------- @@ -674,18 +711,18 @@ def create_domain(target): logs.out("37", folder, False) else: os.makedirs(folder, exist_ok=True) - logs.out("33", foloder, False) + logs.out("33", folder, False) print(' │') # Create in _configs/ modules files #---------------------------------- - create_metas('form') - create_navbar('form') - create_sidebar('form') - create_footer('form') - create_footer_about('form') + + html.create_user_metas('new') + html.create_navbar('new') + html.create_sidebar('new') + html.create_user_footer('new') print(langs.site.form_ready) @@ -700,16 +737,18 @@ def create_domain(target): #------------------------# def create_metas(option): if not dom.ready: dom.valid() - + + print(' │\n ├ %s'%langs.site.metas_inf) + if option != "new": return + # Create new default config file, or ask if exists if tyto.exists(dom.metas_f): - answer = asking(' ├ %s. %s%s '%( - langs.site.metas, langs.site.form_reset, - langs.site.q + answer = asking(' ├ %s%s '%( + langs.site.form_reset, langs.site.q ), False) if not answer in answer_yes: - if option == "form": return + if option == "new": return logs.out("255", '', True) # Set default content for @@ -766,10 +805,6 @@ def create_metas(option): '' tyto.set_file(dom.metas_f, 'New', metas_tags) - - # Create an empty html file in wip/www server if not exists - if not tyto.exists(dom.wip_metas_f): - html.create_user_metas('wip') #=============================# @@ -778,15 +813,17 @@ def create_metas(option): def create_navbar(option): if not dom.ready: dom.valid() + print(' │\n ├ %s'%langs.site.navbar_inf) + if option != "new": return + # Create new config file, or ask if exists if tyto.exists(dom.navbar_f): - answer = asking(' ├ %s. %s%s '%( - langs.site.navbar, langs.site.form_reset, - langs.site.q + answer = asking(' ├ %s%s '%( + langs.site.form_reset, langs.site.q ), False) if not answer in answer_yes: - if option == "form": return + if option == "new": return logs.out("255", '', True) @@ -827,9 +864,6 @@ def create_navbar(option): navbar_lang = navbar_lang%(tyto.Tyto, dom.navbar_f) tyto.set_file(dom.navbar_f, 'New', navbar_lang) - - # Create wip navbar file - html.create_navbar('wip') #==============================# @@ -838,19 +872,21 @@ def create_navbar(option): def create_sidebar(option): if not dom.ready: dom.valid() + print(' │\n ├ %s'%langs.site.sidebar_inf) + if option != "new": return + # Create an empty html file in wip/www server if not exists if not tyto.exists(dom.wip_sidebar_f): tyto.set_file(dom.wip_sidebar_f, 'new', '') # Create new config file, or ask if exists with option = 'reset' if tyto.exists(dom.sidebar_f): - answer = asking(' ├ %s. %s%s '%( - langs.site.sidebar, langs.site.form_reset, - langs.site.q + answer = asking(' ├ %s%s '%( + langs.site.form_reset, langs.site.q ), False) if not answer in answer_yes: - if option == "form": return + if option == "new": return logs.out("255", '', True) @@ -900,6 +936,9 @@ def create_sidebar(option): def create_footer(option): if not dom.ready: dom.valid() + print(' │\n ├ %s'%langs.site.footer_inf) + if option != "new": return + # Default footer contents #------------------------ Tytosrc = \ @@ -924,19 +963,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 = '/' @@ -999,15 +1027,15 @@ def create_footer(option): # Final HTML footer code footer = \ '%s\n'%footer_lang%(tyto.Tyto, dom.footer_f) + \ - '
\n' + \ + '
\n' + \ ' \n' + \ ' \n' + \ '' @@ -203,7 +218,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' + \ '' @@ -250,15 +265,15 @@ def create_html_time_meta(process): def create_user_metas(option): dom.valid() - if option == 'wip': target = dom.wip_metas_f + form.create_metas(option) + + if option in wip_opts: target = dom.wip_metas_f elif option in pub_opts: target = dom.www_metas_f if option == 'www' and tyto.exists(target): form.asking(' ├ %s. %s%s '%( langs.site.metas, langs.site.form_rep, langs.site.q ), True) - - print(' │\n ├ %s'%langs.site.metas_inf) # Create wip metas.html file according to option #----------------------------------------------- @@ -284,10 +299,12 @@ def create_user_metas(option): def create_navbar(option): dom.valid() + form.create_navbar(option) + if not tyto.exists(dom.navbar_f): logs.out("1", dom.navbar_f, True) - if option == 'wip': target = dom.wip_navbar_f + if option in wip_opts: target = dom.wip_navbar_f elif option in pub_opts: target = dom.www_navbar_f if option == 'www' and tyto.exists(target): @@ -296,14 +313,12 @@ def create_navbar(option): option, langs.site.q ), True) - print(' │\n ├ %s'%langs.site.navbar_inf) - # navbar has items navbar_items = False # Set first HTML line menu_html = \ - '%s
\n%s'%line + div_close = False + + # Has content after, open div + try: + post_bottom.rsplit('\n')[ln + 1] + div_open = True + except: + continue + + # New div + if div_open: + line = '%s\n
'%(line, hx) + div_close = True + + # Save new article with div and no empty lines + #--------------------------------------------- + if not article_tmp: article_tmp = line + else: article_tmp = "%s\n%s"%(article_tmp, line) - if indiv: - article_temp = '%s\n
'%article_temp + # Close last div (if any) + if div_close: + article_tmp = "%s\n
"%(article_tmp) - # Replace article with new contents - post_bottom = article_temp - + post_bottom = article_tmp + #==============================================# # Convert raw file to HTML with
 +  #
@@ -951,8 +1026,10 @@ def wip_fileraws(target):
   for i in range(1, db.uniq_raws + 1):
     raw      = 'db.raw_%s'%i
     raw_file = open('%s%s'%(dom.articles_d, eval(raw)[1])).read()
+    raw_alt = ""
     if eval(raw)[2]:
       raw_alt = ' # %s'%eval(raw)[2]
+    
     raw_inc  = ''%raw_alt
     
     for line in raw_file.rsplit('\n'):
diff --git a/src/var/lib/tyto/translations/logs_en.py b/src/var/lib/tyto/translations/logs_en.py
index 584b4d0..cd31411 100644
--- a/src/var/lib/tyto/translations/logs_en.py
+++ b/src/var/lib/tyto/translations/logs_en.py
@@ -11,44 +11,48 @@
 #**********************************************************************
 
 # Generic
-sidebar  = 'Sidebar'
-navbar   = 'Navbar'
-meta_t   = ' tag'
-time_t   = '