From 066e89b6840bd17a14760ce0024c06c94186af9b Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Wed, 16 Nov 2022 16:09:26 +0100 Subject: [PATCH 001/247] Check inside list for +, =, ' ' --- src/var/lib/tyto/program/check.py | 31 +++++++++++++++---- src/var/lib/tyto/program/log.py | 2 +- src/var/lib/tyto/program/wip.py | 51 +++++++++++++++++++++++++++++-- 3 files changed, 75 insertions(+), 9 deletions(-) diff --git a/src/var/lib/tyto/program/check.py b/src/var/lib/tyto/program/check.py index 2bf064f..586c4bd 100644 --- a/src/var/lib/tyto/program/check.py +++ b/src/var/lib/tyto/program/check.py @@ -233,6 +233,9 @@ def check_article(post_uri,Force): # Check links (anchors) check_links_anchors(article) + # Check titles/comments in article + check_lists_contents(article.rsplit('\n')) + # Check other markers check_article_markers(article) @@ -378,10 +381,6 @@ def check_post_header(headers): if_mandat_marker('date:', date) if date: check_date(date) - - #------------------------------ - # Check valid Opitonal markers - #------------------------------ #===================# @@ -912,7 +911,6 @@ def check_links_anchors(article): #for ln, line in enumerate(article.rsplit('\n'), 1): anchors_link = re.findall(r'\>_(.*?)_\<', article) for anchor in anchors_link: - print('> Anchor found: %s'%(anchor)) anchor_id = anchor.rsplit(':',1)[0] if not re.search(r'\>\> %s'%anchor_id, article): msg_log = 'Unused anchor ID ">> %s" from link "%s"'%( @@ -920,8 +918,29 @@ def check_links_anchors(article): ) log.append_f(post_logs,msg_log,1) Post_Err = True - Post_Err = True +#====================================# +# Check inside list for only + and = # +# Multilines for one marker list # +# MUST have at leat one space (\s) # +#------------------------------------# +def check_lists_contents(article): + global Post_Err + + inlist = False + + for line in article: + + if re.match(markers_reg[3][0], line): + inlist = True + continue + elif re.match(markers_reg[3][1], line): + inlist = False + + if inlist and not re.match(r'^\+|^\=|\s', line): + msg_log = 'Content list not "+" or "=": %s'%line + log.append_f(post_logs,msg_log,1) + Post_Err = True #====================================# # Create Database file for this Post # diff --git a/src/var/lib/tyto/program/log.py b/src/var/lib/tyto/program/log.py index 2712169..cd92783 100644 --- a/src/var/lib/tyto/program/log.py +++ b/src/var/lib/tyto/program/log.py @@ -69,7 +69,7 @@ def nowdate(): # Append line to specific log file # #----------------------------------# def append_f(f,line,n): - smiley = [':)',':(\033[1;31m','\033[1;33m:|'] + smiley = [':D',':<\033[1;31m','\033[1;33m:|'] now = nowdate() # Open file to append line diff --git a/src/var/lib/tyto/program/wip.py b/src/var/lib/tyto/program/wip.py index e342e83..4220b50 100644 --- a/src/var/lib/tyto/program/wip.py +++ b/src/var/lib/tyto/program/wip.py @@ -70,6 +70,9 @@ def manage_wip(file_post, Force): # All is good, converting... #--------------------------- + # Source DB variables + post_db = exec(open(check.curr_post_db).read(),globals()) + # Send to log msg_log = 'Wip > Article: %s. logs: %s'%( check.post_uri, check.post_logs @@ -91,11 +94,15 @@ def manage_wip(file_post, Force): wip_begin_markers(wip_html.rsplit('\n')) wip_titles( wip_html.rsplit('\n')) wip_words_markers(wip_html) + wip_anchors( wip_html) + + # After all, convert protected contents + wip_links( wip_html) wip_quotes( wip_html.rsplit('\n')) print('> Article HTML:') print(wip_html) - + #============================# # HTML CONVERTERS # @@ -114,7 +121,7 @@ def wip_begin_markers(wip_lines): # Set marker (regex to find), HTML, Need CSS marks_html = [ ['^\|$|^\|\s' , '
' , True ], - ['^>>\s' , '' , True ], + ['^>>\s' , '' , True ], [r'^\($|\(\s' , '

' , True ], ['^\)$|^\)\s' , '

' , False], ['^\[\[$|^\[\[\s' , '_(.*?)_\<', article) + + for anchor in anchors_link: + anchor_id = anchor.rsplit(':',1)[0] + anchor_name = anchor.rsplit(':',1)[1] + article = article.replace('>_%s_<'%anchor, + anchor_fmt%(anchor_id, anchor_name) + ) + wip_html = article + +# +# Convert links +# +def wip_links(article): + global wip_html + + link_fmt = '%s' + all_vars = set(globals()) + + for var in all_vars: + if var.startswith('link_'): + link = globals()[var] + article = article.replace('_%s'%link[0], + link_fmt%( + domain.domain_css, link[1], + link[2], link[0] + ) + ) + + wip_html = article + #======================================# # Words Markers (strongs, emphasis...) # #--------------------------------------# From 191329a69c40463f03fe76368ea55e4013edb30b Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Thu, 17 Nov 2022 14:20:59 +0100 Subject: [PATCH 002/247] check: abbr + markers (if new line is new marker) --- src/var/lib/tyto/program/check.py | 150 +++++++++++++++++++++++++----- 1 file changed, 126 insertions(+), 24 deletions(-) diff --git a/src/var/lib/tyto/program/check.py b/src/var/lib/tyto/program/check.py index 586c4bd..b67f75a 100644 --- a/src/var/lib/tyto/program/check.py +++ b/src/var/lib/tyto/program/check.py @@ -35,6 +35,12 @@ markers_reg = [ [ r'^\[\[$|^\[\[\s', r'^\]\]$', 'brut codes' ], [ r'^-\($|^-\(\s' , r'^-\)$' , 'lists' ] ] +markers_opt = ( + 'image:', + 'file:', + 'link:', + 'abbr:' + ) #=======# # Tools # @@ -169,7 +175,7 @@ def manage_check(file_post, Force): #==========================# # Pre-processing post file # #--------------------------# -def check_article(post_uri,Force): +def check_article(post_uri, Force): global article # Check needed directories. Create if not exist create_domain_dirs('db') @@ -318,13 +324,14 @@ def post_to_strings(post_uri): #------------------------------------# def check_post_header(headers): global Post_Err - global stats_links_uniq, stats_files_uniq, stats_images_uniq + global stats_links_uniq, stats_files_uniq, stats_images_uniq, stats_abbrs_uniq global stats_links_p, stats_files_p, stats_images_p global stats_links + # Mandatory markers global title, about, author, tags, date # Set Stats - stats_links_uniq = stats_files_uniq = stats_images_uniq = 0 + stats_links_uniq = stats_files_uniq = stats_images_uniq = stats_abbrs_uniq = 0 stats_links = stats_links_p = stats_files_p = stats_images_p = 0 # Set Mandatory marker. 0:True/False 1:ln 2: Content @@ -343,13 +350,13 @@ def check_post_header(headers): #----------------------- if line.startswith('title:'): title = (True,ln,line.split('title:')[1].lstrip()) - if line.startswith('about:'): + elif line.startswith('about:'): about = (True,ln,line.split('about:')[1].lstrip()) - if line.startswith('author:'): + elif line.startswith('author:'): author = (True,ln,line.split('author:')[1].lstrip()) - if line.startswith('tags:'): + elif line.startswith('tags:'): tags = (True,ln,line.split('tags:')[1].lstrip()) - if line.startswith('date:'): + elif line.startswith('date:'): date = (True,ln,line.split('date:')[1].lstrip()) #---------------------- @@ -361,15 +368,21 @@ def check_post_header(headers): stats_links_uniq += 1 check_links(line, ln, stats_links_uniq) # files: - if line.startswith('file:'): + elif line.startswith('file:'): # Create variable array stats_files_uniq += 1 check_files(line, ln, stats_files_uniq) # images: - if line.startswith('image:'): + elif line.startswith('image:'): # Create variable array stats_images_uniq += 1 check_images(line, ln, stats_images_uniq) + # ABBR + elif line.startswith('abbr:'): + # Create variable array + stats_abbrs_uniq += 1 + check_abbrs(line, ln, stats_abbrs_uniq) + #------------------------------- # Check valid Mandatory markers @@ -460,20 +473,20 @@ def if_option_marker(marker, m_in): if not m_in[2]: msg_log = 'Line %s. Unused URL for marker "%s"'%( - m_in[0]+1, marker + m_in[0], marker ) log.append_f(post_logs,msg_log,1) Post_Err = True if not m_in[3]: msg_log = 'Line %s. Unused Alt-Text for marker "%s"'%( - m_in[0]+2, marker + m_in[0]+1, marker ) log.append_f(post_logs,msg_log,1) Post_Err = True #=================================# -# Check every marker "links:" # +# Check every marker "link:" # # For line, from loop header file # # Also, create Stats # #---------------------------------# @@ -486,6 +499,14 @@ def check_links(line, ln, stats_links_uniq): link_url = headers.rsplit('\n')[ln].lstrip() link_alt = headers.rsplit('\n')[ln+1].lstrip() + # Check 2nd line + check_new_marker(link_url) + if new_marker: link_url = '' + + # Check 3rd line + check_new_marker(link_alt) + if new_marker: link_alt = '' + link = ( ln, link_name, @@ -517,7 +538,7 @@ def check_links(line, ln, stats_links_uniq): stats_links_p = stats_counter(link_page) #=================================# -# Check every marker "files:" # +# Check every marker "file:" # # For line, from loop header file # # Also, create Stats # #---------------------------------# @@ -530,7 +551,15 @@ def check_files(line, ln, stats_files_uniq): file_name = line.split('file:')[1].lstrip() file_uri = headers.rsplit('\n')[ln].lstrip() file_alt = headers.rsplit('\n')[ln+1].lstrip() - + + # Check 2nd line + check_new_marker(file_uri) + if new_marker: file_uri = '' + + # Check 3rd line + check_new_marker(file_alt) + if new_marker: file_alt = '' + file = ( ln, file_name, @@ -595,7 +624,7 @@ def check_files(line, ln, stats_files_uniq): stats_files_p = stats_counter(file_page) #=================================# -# Check every marker "images:" # +# Check every marker "image:" # # For line, from loop header file # # Also, create Stats # #---------------------------------# @@ -608,13 +637,21 @@ def check_images(line, ln, stats_images_uniq): image_name = line.split('image:')[1].lstrip() image_uri = headers.rsplit('\n')[ln].lstrip() image_alt = headers.rsplit('\n')[ln+1].lstrip() - + + # Check 2nd line + check_new_marker(image_uri) + if new_marker: image_uri = '' + + # Check 3rd line + check_new_marker(image_alt) + if new_marker: image_alt = '' + image = ( - ln, - image_name, - image_uri, - image_alt - ) + ln, + image_name, + image_uri, + image_alt + ) # Set/Check values to check in header globals()[image_nbr] = image @@ -672,6 +709,64 @@ def check_images(line, ln, stats_images_uniq): # Stats: count occurence stats_images_p = stats_counter(image_page) +#=================================# +# Check every marker "abbr:" # +# For line, from loop header file # +# Also, create Stats # +#---------------------------------# +def check_abbrs(line, ln, stats_abbrs_uniq): + global Post_Err + global stats_abbrs_p + + # Create variable array + abbr_name = line.split('abbr:')[1].lstrip() + abbr_alt = headers.rsplit('\n')[ln].lstrip() + abbr_rep = headers.rsplit('\n')[ln+1].lstrip() + + # Set/Check values to check in header + if not abbr_name: + msg_log = 'Line %s. Unused NAME for marker "abbr:"'%ln + log.append_f(post_logs,msg_log,1) + Post_Err = True + elif abbr_name.isupper() is False: + msg_log = 'Line %s. NAME not in CAPITAL for marker "abbr:"'%ln + log.append_f(post_logs,msg_log,1) + Post_Err = True + + # Check 2rd line + check_new_marker(abbr_alt) + if new_marker: abbr_name = '' + # Set/Check values to check in header + if not abbr_alt: + msg_log = 'Line %s. Unused alt-text for marker "abbr:"'%ln + 1 + log.append_f(post_logs,msg_log,1) + Post_Err = True + + # Check 3rd line + check_new_marker(abbr_rep) + if new_marker or not abbr_rep: abbr_rep = abbr_name + + abbr_nbr = 'abbr_%s'%stats_abbrs_uniq + abbr = ( + abbr_name, + abbr_alt, + abbr_rep + ) + globals()[abbr_nbr] = abbr + +#============================# +# Check marker's 3rd line # +# if new marker, or empty # +# for every optional markers # +#----------------------------# +def check_new_marker(line3): + global new_marker + + new_marker = False + + for marker in markers_opt: + if line3.startswith(marker): + new_marker = True #=================# # ARTICLE CONTENT # @@ -988,24 +1083,30 @@ def create_DB(post_db): domain.append_f(post_db, line_conf) # Optional headers to Post conf - # Add every links: array found to DB, one per line + # Add every "link:" array found to DB, one per line if stats_links_uniq > 0: for n in range(1,stats_links_uniq+1): m = 'link_%s'%n domain.append_f(post_db,'%s = %s'%(m,globals()[m])) - # Add every files: array found to DB, one per line + # Add every "file:" array found to DB, one per line if stats_files_uniq > 0: for n in range(1,stats_files_uniq+1): m = 'file_%s'%n domain.append_f(post_db,'%s = %s'%(m,globals()[m])) - # Add every images: array found to DB, one per line + # Add every "image:" array found to DB, one per line if stats_images_uniq > 0: for n in range(1,stats_images_uniq+1): m = 'image_%s'%n domain.append_f(post_db,'%s = %s'%(m,globals()[m])) + # Add every "abbr:" array found to DB, one per line + if stats_abbrs_uniq > 0: + for n in range(1,stats_abbrs_uniq+1): + m = 'abbr_%s'%n + domain.append_f(post_db,'%s = %s'%(m,globals()[m])) + # Statistics Post conf lines_conf = '' lines_conf = ( @@ -1013,6 +1114,7 @@ def create_DB(post_db): 'links_u = %d'%stats_links_uniq, 'files_u = %d'%stats_files_uniq, 'images_u = %d'%stats_images_uniq, + 'abbrs_u = %d'%stats_abbrs_uniq, '\n# Statistics (Wordings)', 'strongs = %d'%m_stats[0], 'bolds = %d'%m_stats[2], From b66769a20ad8ffdbc6d581cabb6605a244097268 Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Thu, 17 Nov 2022 14:38:20 +0100 Subject: [PATCH 003/247] check: abbr (match term in article + stats) --- src/var/lib/tyto/help/CHANGELOG.md | 16 ++ src/var/lib/tyto/help/FR_Installation.md | 21 +++ src/var/lib/tyto/help/README.md | 180 +++++++++++++++++++++++ src/var/lib/tyto/program/check.py | 15 +- 4 files changed, 230 insertions(+), 2 deletions(-) create mode 100644 src/var/lib/tyto/help/CHANGELOG.md create mode 100644 src/var/lib/tyto/help/FR_Installation.md create mode 100644 src/var/lib/tyto/help/README.md diff --git a/src/var/lib/tyto/help/CHANGELOG.md b/src/var/lib/tyto/help/CHANGELOG.md new file mode 100644 index 0000000..75c6ac6 --- /dev/null +++ b/src/var/lib/tyto/help/CHANGELOG.md @@ -0,0 +1,16 @@ +# Changelog + +Tyto - Littérateur +- Repository: https://git.a-lec.org/echolib/tyto +- Issues: https://git.a-lec.org/echolib/tyto/-/issues +- Changelog: https://git.a-lec.org/echolib/tyto/-/blob/main/CHANGELOG.md +- License: https://git.a-lec.org/echolib/tyto/-/blob/main/LICENSE + +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 static pages. Tyto works on a GNU/Linux system +and needs minimal dependancies. +- python3 rsync nano gawk curl + +## [0.9.0] First Commit version (pre-final) + diff --git a/src/var/lib/tyto/help/FR_Installation.md b/src/var/lib/tyto/help/FR_Installation.md new file mode 100644 index 0000000..f508aec --- /dev/null +++ b/src/var/lib/tyto/help/FR_Installation.md @@ -0,0 +1,21 @@ +# Installation manuelle + +Si vous utilisez Debian, il est plus que recommandé de procéder à +l'installation par le paquet .deb + +## Préparer les dossiers +```` +sudo mkdir -p /var/lib/tyto /etc/tyto /var/log/tyto +sudo touch /usr/local/bin/tyto +sudo chown -R USER:GROUP /var/lib/tyto /etc/tyto /var/log/tyto +sudo chown USER:GROUP /usr/local/bin/tyto +sudo chmod +x /usr/local/bin/tyto + +git clone https://git.a-lec.org/echolib/tyto +rsync -a folders'repo/ to /folders/ + +# Créer votre dossier pour le serveur web +# On utilise en général /var/www/ +# Celui-ci sera à renseigner lors de la création d'un domaine dans Tyto +sudo mkdir -p /var/www/ +```` diff --git a/src/var/lib/tyto/help/README.md b/src/var/lib/tyto/help/README.md new file mode 100644 index 0000000..9f49fa4 --- /dev/null +++ b/src/var/lib/tyto/help/README.md @@ -0,0 +1,180 @@ +# STL: Statique Littérateur +STL est une évolution du projet GSL. STL permet de créer un ou plusieurs +sites web/blogs statiques, en fonction de leur nom de domaine. + +Tout comme GSL, STL reprend une grande partie de l'écriture nouvelle de +vos articles, en apportant quelques évolutions. Les articles sont donc +au format .stl. + + +# Fonctionnement de STL ; le dossier de base +Contrairement à GSL, vos articles et les pages de votre site web sont +situés dans le même dossier de base. Pour obtenir ce dossier de base, +et configurer votre domaine, vous devez d'abord vous placer dans le +dossier de votre choix, puis lancer la commande de configuration. + +``` +cd MON-DOSSIER-PREFERE +stl domain new + +# Vous pouvez également pré-remplir votre domaine en fonction de l'URL +stl domain new https://mon-site.xyz +``` + +Dans ce dossier de base (MON-DOSSIER-PREFERE), après la configuration de +votre domaine, vous trouverez de nouveaux dossiers : +- articles/ +- - images/ +- - files/ + +Les sous-dossiers images/ et files/ sont proposés afin de faciliter la +réutilisation d'images et de fichiers (PDF, ou autres) déjà présents +dans un autre article. Lors de la synchronisation, il seront copiés à la +racine wip de votre serveur. Le but : faire en sorte que le +navigateur n'ait pas à recharger un même fichier depuis une URL +différente - ce qui plomberait la rapidité d'affichage de la page et +l'intérêt d'un site statique. L'utilisation de cette fonction dans vos +articles est simple ; voir la documentation expliquant comment écrire un +article dans le dossier help. + +Dans le dossier du serveur (/var/www est un exemple), vous trouverez +les dossiers suivants : +- /var/www/DOMAIN/wip/ +- - template (logos, styles.css, sidebar.html, footer.html, metas.html...) +- - images +- - files +- /var/www/DOMAIN/www/ (non créé pour une installation locale) +- - template/ +- - images +- - files + + +## Installation (server, ou local) +Il est possible d'utiliser STL de 2 manières différentes. Lors de la +configuation d'un nouveau domaine, vous devrez choisir entre une +installation faite sur un serveur distant, et une installation faite +en local (sur votre PC). Vous pouvez bien sûr choisir une installation +de type "server" sur votre PC, si celui-ci sert de serveur web. + +Concernant la décoration du site (styles.css, logos), les fichiers +devront être placés dans le dossier serveur /wip/template/ (créé par STL +lors de l'ajout d'un domaine). + + +### Installation "server" +À choisir si votre PC sert de serveur web, ou si vous avez installé STL +sur votre serveur distant. + +Lorsque vous installez STL, sur votre serveur distant, vous pouvez gérer +pour un même nom de domaine, votre site sur 2 adresses URL différentes. +La version WIP, permet de prévisualiser les modifications apportées à +vos pages (sans modifier celles sur WWW) avant de les valider sur votre +site officiel. + +Lorsque votre site prévisualisé sur WIP vous plaît, vous pouvez alors +synchroniser le dossier WIP sur WWW grâce à la commande : + +``` +# Pour publier un article précis +stl publish (ARTICLE) + +# Pour publier tous les articles dans WIP +stl publish all +``` + +Note : cette commande crée automatiquement le flux RSS dans WIP avant +de tous synchroniser sur WWW. + + +### Installation "local" +À choisir si vous voulez utiliser STL sur votre PC, et synchroniser +vous-même le dossier WIP sur votre serveur distant. Inutile donc, +d'installer STL sur le serveur distant. + +Lors d'une utilisation locale, STL ne crée pas le dossier WWW, et ne +synchronise donc pas le dossier WIP vers WWW. C'est à vous de le faire +(via ssh, par exemple). + +Vous devrez lorsque votre site vous plaît localement lancer la création +du flux RSS - avant de synchroniser votre site local sur votre serveur +distant - avec la commande : + +``` +stl rss +``` + + +# Utilisation de STL +Afin de gérer vos articles, vous devez vous placer dans MON-DOSSIER-PREFERE. +L'autocomplétion est activée et personnalisée pour vous aider à trouver +(ARTICLE.stl). + + +## Créer votre arborescence +Dans MON-DOSSIER-PREFERE, vous trouverez le dossier "articles". Celui-ci +sert de base à votre domain.xyz sur votre serveur. C'est dans ce dossier +"articles", que vous pouvez créer vos articles et vos sous-dossiers. +Il est à noter que le nom de l'article est important, puisque STL +l'utilisera en le transformant en .html. Il est donc recommandé - mais +pas obligatoire - de nommer vos articles index.stl, pour obtenir une page +index.html. Si vous voulez créer une page 404, nommez votre article 404.stl +à la racine du dossier "articles". + + +## Convertir votre article en HTML +Placez vous dans MON-DOSSIER-PREFERE. + +Avant de pouvoir convertir votre article, STL dispose d'un système de +vérification de la syntaxe STL. Si des erreurs sont trouvées, un système +de logs vous aidera à corriger ces erreurs. + +``` +# N'oubliez pas d'utiliser l'autocomplétion +stl check (ARTICLE.stl) +``` + +Vous pouvez maintenant le convertir en HTML dans le dossier wip + +``` +stl wip (ARTICLE.stl) +``` + + +## Utiliser la sidebar +C'est la seule partie du site qui est semi-statique. STL fait appel à +nginx, qui va se charger de traduire la balise HTML ``, +et afficher le rendu du fichier sidebar.html + +Chaque article, une fois convertit avec l'argument wip peut être placé +dans la sidebar à la position désirée, entre 1 et la valeur maximum +décidée, lors de la configuration du domaine. + +``` +stl sidebar add 1 (ARTICLE.stl) +``` + +Vous pouvez également décider de placer un article ausitôt convertit +avec l'argument wip sidebar=POSITON + +``` +stl wip sidebar=2 (ARTICLE.stl) +``` + +## Documentation de STL +Les fichiers de documentations sont dans le dossier help. +Le README est accessible depuis la ligne de commande, comme les arguments +utilisables. + +``` +stl help +stl readme +``` + + +## Dépendances +STL est écrit en bash, et a besoin des utilitaires +- gawk +- rsync +- nano +- curl + diff --git a/src/var/lib/tyto/program/check.py b/src/var/lib/tyto/program/check.py index b67f75a..1f185b3 100644 --- a/src/var/lib/tyto/program/check.py +++ b/src/var/lib/tyto/program/check.py @@ -325,14 +325,14 @@ def post_to_strings(post_uri): def check_post_header(headers): global Post_Err global stats_links_uniq, stats_files_uniq, stats_images_uniq, stats_abbrs_uniq - global stats_links_p, stats_files_p, stats_images_p + global stats_links_p, stats_files_p, stats_images_p, stats_abbrs_p global stats_links # Mandatory markers global title, about, author, tags, date # Set Stats stats_links_uniq = stats_files_uniq = stats_images_uniq = stats_abbrs_uniq = 0 - stats_links = stats_links_p = stats_files_p = stats_images_p = 0 + stats_links = stats_links_p = stats_files_p = stats_images_p = stats_abbrs_p = 0 # Set Mandatory marker. 0:True/False 1:ln 2: Content title = about = author = tags = date = ('','','') @@ -746,6 +746,16 @@ def check_abbrs(line, ln, stats_abbrs_uniq): check_new_marker(abbr_rep) if new_marker or not abbr_rep: abbr_rep = abbr_name + # Check NAME in article + if not abbr_name in article: + msg_log = 'Unused "%s" for marker "abbr:" in article"'%abbr_name + log.append_f(post_logs,msg_log,1) + Post_Err = True + return(1) + + # Statistics for all ABBR in article + stats_abbrs_p = stats_abbrs_p + stats_counter(abbr_name) + abbr_nbr = 'abbr_%s'%stats_abbrs_uniq abbr = ( abbr_name, @@ -1130,6 +1140,7 @@ def create_DB(post_db): 'links_p = %d'%stats_links_p, 'files_p = %d'%stats_files_p, 'images_p = %d'%stats_images_p, + 'abbrs_p = %d'%stats_abbrs_p, '\n# Statistics (Templates)', 'titles = %d'%stats_titles, 'anchors = %d'%stats_anchors, From 42bd5a40d81b0139d5cc9fd507026abae72707fe Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Fri, 18 Nov 2022 11:09:45 +0100 Subject: [PATCH 004/247] wip: ABBRs converted to base64 --- src/var/lib/tyto/program/check.py | 2 +- src/var/lib/tyto/program/wip.py | 45 ++++++++++++++++++++++--------- 2 files changed, 33 insertions(+), 14 deletions(-) diff --git a/src/var/lib/tyto/program/check.py b/src/var/lib/tyto/program/check.py index 1f185b3..c4e1f0c 100644 --- a/src/var/lib/tyto/program/check.py +++ b/src/var/lib/tyto/program/check.py @@ -1115,7 +1115,7 @@ def create_DB(post_db): if stats_abbrs_uniq > 0: for n in range(1,stats_abbrs_uniq+1): m = 'abbr_%s'%n - domain.append_f(post_db,'%s = %s'%(m,globals()[m])) + domain.append_f(post_db,'%s = %s'%(m,globals()[m])) # Statistics Post conf lines_conf = '' diff --git a/src/var/lib/tyto/program/wip.py b/src/var/lib/tyto/program/wip.py index 4220b50..38eec70 100644 --- a/src/var/lib/tyto/program/wip.py +++ b/src/var/lib/tyto/program/wip.py @@ -95,6 +95,7 @@ def manage_wip(file_post, Force): wip_titles( wip_html.rsplit('\n')) wip_words_markers(wip_html) wip_anchors( wip_html) + wip_abbrs( wip_html) # After all, convert protected contents wip_links( wip_html) @@ -234,6 +235,25 @@ def wip_links(article): wip_html = article +# +# +# +def wip_abbrs(article): + global wip_html + + abbr_fmt = '%s' + all_vars = set(globals()) + + for var in all_vars: + if var.startswith('abbr_'): + abbr = globals()[var] + abbr_b64 = abbr_fmt%(domain.domain_css, abbr[1], abbr[2]) + convert_to_b64(abbr_b64) + print('B64 for %s :> %s'%(abbr[1], b64_content)) + article = article.replace(abbr[0], b64_content) + + wip_html = article + #======================================# # Words Markers (strongs, emphasis...) # #--------------------------------------# @@ -356,11 +376,13 @@ def convert_quote(bQuote): # main quote content else: - if quote_html: quote_html = '%s\n%s'%(quote_html, line) - else : quote_html = line + if quote_html: quote_html = '%s\n%s'%(quote_html, line) + else : quote_html = line if not cite : author_show = 'NC' - if year and book: author_show = '%s%s%s'%(author_show, book_show, year_show) + if year and book: author_show = '%s%s%s'%( + author_show, book_show, year_show + ) if cite or link: author_show = '%s%s'%(cite, author_show) @@ -393,17 +415,16 @@ def convert_quote(bQuote): ) else: if year: quote_html = ''%( - year, blockquote - ) - else: quote_html = blockquote - - #print('> Quote_HTML:\n', quote_html) + year, blockquote + ) + else : quote_html = blockquote + #=================================# # Return datas in quote from line # #---------------------------------# def quote_data(line): - return line.split(' ',1)[1].lstrip() + return line.split(' ', 1)[1].lstrip() #=========================# @@ -437,10 +458,8 @@ def convert_bcodes(article, fm, lm, css): ) continue - if bCode: - bCode_lines = '%s%s\n'%(bCode_lines, line) - else: - article_temp = '%s%s\n'%(article_temp, line) + if bCode: bCode_lines = '%s%s\n'%(bCode_lines, line) + else : article_temp = '%s%s\n'%(article_temp, line) #====================================# # Protect bCodes contents to base64 # From fc47d177e26d2d6ee13ef88d14e045400e11fa30 Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Fri, 18 Nov 2022 15:46:32 +0100 Subject: [PATCH 005/247] wip: links are converted to base64 --- src/var/lib/tyto/program/check.py | 23 +++++++--------- src/var/lib/tyto/program/wip.py | 45 ++++++++++++++++--------------- 2 files changed, 33 insertions(+), 35 deletions(-) diff --git a/src/var/lib/tyto/program/check.py b/src/var/lib/tyto/program/check.py index c4e1f0c..e4c4901 100644 --- a/src/var/lib/tyto/program/check.py +++ b/src/var/lib/tyto/program/check.py @@ -218,15 +218,15 @@ def check_article(post_uri, Force): check_post_header(headers.rsplit('\n')) # Protect bCodes, keep markers for stats, before checking other markers - wip.convert_bcodes(article.rsplit('\n'), - '[[', ']]', - domain.domain_css) + wip.convert_bcodes(article.rsplit('\n'), + '[[', ']]', + domain.domain_css) article = wip.article_temp # Protect quotes, keep markers for stats, before checking other markers wip.convert_bcodes(article.rsplit('\n'), - '((', '))', - domain.domain_css) + '((', '))', + domain.domain_css) article = wip.article_temp # Protect iCodes, keep markers for stats @@ -304,13 +304,8 @@ def post_to_strings(post_uri): post = True continue - # In post content - if post: - article = '%s\n%s'%(article,line) - - # In post header - else: - headers = '%s\n%s'%(headers,line) + if post: article = '%s\n%s'%(article,line) # In post content + else: headers = '%s\n%s'%(headers,line) # In post header # Get number lines in headers, min line separator headers_ln = len(headers.split("\n")) - 1 @@ -601,7 +596,7 @@ def check_files(line, ln, stats_files_uniq): else: file_uri = '/%s'%(file_uri) - # Current or curstom URI + # Current or custom URI else: usr_file = '%s%s'%(domain.domain_articles,file_uri) if not os.path.exists(usr_file): @@ -687,7 +682,7 @@ def check_images(line, ln, stats_images_uniq): else: image_uri = '/%s'%(image_uri) - # Current or curstom URI + # Current or custom URI else: usr_file = '%s%s'%(domain.domain_articles,image_uri) if not os.path.exists(usr_file): diff --git a/src/var/lib/tyto/program/wip.py b/src/var/lib/tyto/program/wip.py index 38eec70..c2ce9a5 100644 --- a/src/var/lib/tyto/program/wip.py +++ b/src/var/lib/tyto/program/wip.py @@ -197,8 +197,9 @@ def wip_titles(wip_lines): #================================================# -# Create Anchors (links) # +# Create Anchors (links) and convert to HTML # # Target anchors are done with wip_begin_markers # +# Each are converted to Base64 # #------------------------------------------------# def wip_anchors(article): global wip_html @@ -209,14 +210,16 @@ def wip_anchors(article): for anchor in anchors_link: anchor_id = anchor.rsplit(':',1)[0] anchor_name = anchor.rsplit(':',1)[1] - article = article.replace('>_%s_<'%anchor, - anchor_fmt%(anchor_id, anchor_name) - ) - wip_html = article + anchor_b64 = anchor_fmt%(anchor_id, anchor_name) + convert_to_b64(anchor_b64) + article = article.replace('>_%s_<'%anchor, b64_content) + + wip_html = article -# -# Convert links -# +#==============================# +# Convert links to HTML # +# Each are converted to Base64 # +#------------------------------# def wip_links(article): global wip_html @@ -225,19 +228,20 @@ def wip_links(article): for var in all_vars: if var.startswith('link_'): - link = globals()[var] - article = article.replace('_%s'%link[0], - link_fmt%( - domain.domain_css, link[1], - link[2], link[0] - ) - ) + link = globals()[var] + link_b64 = link_fmt%(domain.domain_css, link[1], + link[2], link[0] + ) + convert_to_b64(link_b64) + article = article.replace('_%s'%link[0], b64_content) wip_html = article -# -# -# +#===========================================# +# Convert abbrs to HTML # +# each found are converted to Base64 # +# (avoid mismatch HTML if same word inside) # +#-------------------------------------------# def wip_abbrs(article): global wip_html @@ -246,11 +250,10 @@ def wip_abbrs(article): for var in all_vars: if var.startswith('abbr_'): - abbr = globals()[var] + abbr = globals()[var] abbr_b64 = abbr_fmt%(domain.domain_css, abbr[1], abbr[2]) convert_to_b64(abbr_b64) - print('B64 for %s :> %s'%(abbr[1], b64_content)) - article = article.replace(abbr[0], b64_content) + article = article.replace(abbr[0], b64_content) wip_html = article From 623540a92ac23712d61a62a1246333b91027cbdf Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Fri, 18 Nov 2022 15:52:02 +0100 Subject: [PATCH 006/247] wip: links are converted to base64 --- src/var/lib/tyto/program/wip.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/var/lib/tyto/program/wip.py b/src/var/lib/tyto/program/wip.py index c2ce9a5..0b956eb 100644 --- a/src/var/lib/tyto/program/wip.py +++ b/src/var/lib/tyto/program/wip.py @@ -135,7 +135,7 @@ def wip_begin_markers(wip_lines): # Find if line hase marker and remplace for marker in marks_html: if re.match(marker[0], line): - if marker[2]: # Hass CSS + if marker[2]: # Has CSS get_css(line) line = line.replace(line, marker[1]%css_set) else: From 413b6d291210870d04feb00f8cf1d4392f53ffb7 Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Fri, 18 Nov 2022 16:36:46 +0100 Subject: [PATCH 007/247] check: stats for links in article ; need more investigating for others --- src/var/lib/tyto/program/check.py | 3 ++- src/var/lib/tyto/program/wip.py | 12 ++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/var/lib/tyto/program/check.py b/src/var/lib/tyto/program/check.py index e4c4901..db6a651 100644 --- a/src/var/lib/tyto/program/check.py +++ b/src/var/lib/tyto/program/check.py @@ -520,6 +520,7 @@ def check_links(line, ln, stats_links_uniq): log.append_f(post_logs,msg_log,1) Post_Err = True + if Post_Err: return # Set final marker_N link = ( @@ -530,7 +531,7 @@ def check_links(line, ln, stats_links_uniq): globals()[link_nbr] = link # Stats: count occurence - stats_links_p = stats_counter(link_page) + stats_links_p = stats_links_p + stats_counter(link_page) #=================================# # Check every marker "file:" # diff --git a/src/var/lib/tyto/program/wip.py b/src/var/lib/tyto/program/wip.py index 0b956eb..51a4507 100644 --- a/src/var/lib/tyto/program/wip.py +++ b/src/var/lib/tyto/program/wip.py @@ -94,12 +94,12 @@ def manage_wip(file_post, Force): wip_begin_markers(wip_html.rsplit('\n')) wip_titles( wip_html.rsplit('\n')) wip_words_markers(wip_html) - wip_anchors( wip_html) - wip_abbrs( wip_html) + if anchors > 0: wip_anchors( wip_html) + if abbrs_u > 0: wip_abbrs( wip_html) # After all, convert protected contents - wip_links( wip_html) - wip_quotes( wip_html.rsplit('\n')) + if links_u > 0: wip_links( wip_html) + if quotes > 0: wip_quotes( wip_html.rsplit('\n')) print('> Article HTML:') print(wip_html) @@ -132,7 +132,7 @@ def wip_begin_markers(wip_lines): for line in wip_lines: if len(line) == 0: continue - # Find if line hase marker and remplace + # Find if line has marker and remplace for marker in marks_html: if re.match(marker[0], line): if marker[2]: # Has CSS @@ -220,7 +220,7 @@ def wip_anchors(article): # Convert links to HTML # # Each are converted to Base64 # #------------------------------# -def wip_links(article): +def wip_links(article): global wip_html link_fmt = '%s' From 06794ea31a0578de2dc4bf91e78080f908f780f7 Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Sat, 19 Nov 2022 12:32:48 +0100 Subject: [PATCH 008/247] wip: Protect some HTML markers to base64 in article --- src/var/lib/tyto/program/wip.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/var/lib/tyto/program/wip.py b/src/var/lib/tyto/program/wip.py index 51a4507..972c3d3 100644 --- a/src/var/lib/tyto/program/wip.py +++ b/src/var/lib/tyto/program/wip.py @@ -113,7 +113,8 @@ def manage_wip(file_post, Force): # New line: | # # Anchors: >> # # Paragraphs: ( =

# -# bCodes: (( = # +# bCodes: [[ = # +# Convert to HTML >> base64 # #----------------------------# def wip_begin_markers(wip_lines): global wip_html @@ -121,7 +122,7 @@ def wip_begin_markers(wip_lines): wip_tmp = '' # Set marker (regex to find), HTML, Need CSS marks_html = [ - ['^\|$|^\|\s' , '
' , True ], + ['^\|$|^\|\s' , '
' , True ], ['^>>\s' , '' , True ], [r'^\($|\(\s' , '

' , True ], ['^\)$|^\)\s' , '

' , False], @@ -140,7 +141,8 @@ def wip_begin_markers(wip_lines): line = line.replace(line, marker[1]%css_set) else: line = line.replace(line, marker[1]) - + convert_to_b64(line) + line = b64_content wip_tmp = '%s%s\n'%(wip_tmp, line) wip_html = wip_tmp From a0a425afb209bd143d3a4152224afa26e59704f9 Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Sat, 19 Nov 2022 15:42:09 +0100 Subject: [PATCH 009/247] wip: end of process, convert all b64 --- src/var/lib/tyto/program/wip.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/var/lib/tyto/program/wip.py b/src/var/lib/tyto/program/wip.py index 972c3d3..d394f6b 100644 --- a/src/var/lib/tyto/program/wip.py +++ b/src/var/lib/tyto/program/wip.py @@ -101,6 +101,9 @@ def manage_wip(file_post, Force): if links_u > 0: wip_links( wip_html) if quotes > 0: wip_quotes( wip_html.rsplit('\n')) + # Get Legacy contents from base64 markers + convert_all_b64(wip_html.rsplit('\n')) + print('> Article HTML:') print(wip_html) @@ -504,6 +507,25 @@ def convert_icodes(article, css): ) +#=======================================# +# Convert all base64 to legacy contents # +#---------------------------------------# +def convert_all_b64(wip_lines): + global wip_html + + wip_tmp = '' + + for line in wip_lines: + b64s = re.findall(r'B64\|(.*?)\|B64', line) + for b64 in b64s: + convert_from_b64(b64) + line = line.replace('B64|%s|B64'%b64, src_content) + if wip_tmp: wip_tmp = wip_tmp + line + '\n' + else : wip_tmp = line + '\n' + + wip_html = wip_tmp + + #=======# # TOOLS # #=======#-------------------------------------------------------------- From 1ed0b860825fd7639546ee11c7c3fda655849b52 Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Sat, 19 Nov 2022 16:56:08 +0100 Subject: [PATCH 010/247] wip: bcodes are converted with pre + span(s) --- src/var/lib/tyto/program/wip.py | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/var/lib/tyto/program/wip.py b/src/var/lib/tyto/program/wip.py index d394f6b..cb485bc 100644 --- a/src/var/lib/tyto/program/wip.py +++ b/src/var/lib/tyto/program/wip.py @@ -129,8 +129,8 @@ def wip_begin_markers(wip_lines): ['^>>\s' , '' , True ], [r'^\($|\(\s' , '

' , True ], ['^\)$|^\)\s' , '

' , False], - ['^\[\[$|^\[\[\s' , '' , False] + ['^\[\[$|^\[\[\s' , '
'          , False]
                ]
 
   for line in wip_lines:
@@ -448,26 +448,34 @@ def convert_bcodes(article, fm, lm, css):
   article_temp = ''
   bCode        = False
   bCode_lines  = ''
+  bCode_ln     = 0
   
   for line in article:    
     if line.startswith(fm):
       bCode        = True
-      article_temp = '%s%s\n'%(article_temp, line)
+      article_temp = '%s\n%s'%(article_temp, line)
       continue
     
     if line.startswith(lm):
       bCode    = False
       
-      #print(bCode_lines)
+      print(bCode_lines)
       convert_to_b64(bCode_lines)
       bCode_lines  = ''
-      article_temp = '%s%s\n%s\n'%(
+      article_temp = '%s\n%s\n%s'%(
                       article_temp, b64_content, line
                       )
       continue
   
-    if bCode: bCode_lines  = '%s%s\n'%(bCode_lines, line)
-    else    : article_temp = '%s%s\n'%(article_temp, line)
+    if bCode:
+      bCode_ln += 1
+      line = '  %s%s'%(
+              bCode_ln, line
+              )
+      if bCode_lines: bCode_lines = '%s\n%s'%(bCode_lines, line)
+      else          : bCode_lines = line
+    else:
+      article_temp = '%s\n%s'%(article_temp, line)
 
 #====================================#
 # Protect bCodes contents to base64  #

From dcce2983c2cf261e14e251253ed990fb8a2e1079 Mon Sep 17 00:00:00 2001
From: Cyrille L 
Date: Sat, 19 Nov 2022 17:06:06 +0100
Subject: [PATCH 011/247] check: new markers can be comments

---
 src/var/lib/tyto/program/check.py | 2 +-
 src/var/lib/tyto/program/wip.py   | 1 -
 2 files changed, 1 insertion(+), 2 deletions(-)

diff --git a/src/var/lib/tyto/program/check.py b/src/var/lib/tyto/program/check.py
index db6a651..ee899e0 100644
--- a/src/var/lib/tyto/program/check.py
+++ b/src/var/lib/tyto/program/check.py
@@ -771,7 +771,7 @@ def check_new_marker(line3):
   new_marker = False
   
   for marker in markers_opt:
-    if line3.startswith(marker):
+    if line3.startswith(marker) or line3.startswith('#'):
       new_marker = True
 
 #=================#
diff --git a/src/var/lib/tyto/program/wip.py b/src/var/lib/tyto/program/wip.py
index cb485bc..5a059b7 100644
--- a/src/var/lib/tyto/program/wip.py
+++ b/src/var/lib/tyto/program/wip.py
@@ -459,7 +459,6 @@ def convert_bcodes(article, fm, lm, css):
     if line.startswith(lm):
       bCode    = False
       
-      print(bCode_lines)
       convert_to_b64(bCode_lines)
       bCode_lines  = ''
       article_temp = '%s\n%s\n%s'%(

From c841c6321854abfa53a07ffe30571ade8192edd9 Mon Sep 17 00:00:00 2001
From: Cyrille L 
Date: Sat, 19 Nov 2022 18:02:47 +0100
Subject: [PATCH 012/247] wip: in-dev for HTML tabulations from final result

---
 src/var/lib/tyto/program/wip.py | 37 +++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/src/var/lib/tyto/program/wip.py b/src/var/lib/tyto/program/wip.py
index 5a059b7..9085cfa 100644
--- a/src/var/lib/tyto/program/wip.py
+++ b/src/var/lib/tyto/program/wip.py
@@ -106,6 +106,9 @@ def manage_wip(file_post, Force):
   
   print('> Article HTML:')
   print(wip_html)
+  
+  tab_article(wip_html.rsplit('\n'))
+  
 
 
 #============================#
@@ -575,3 +578,37 @@ def convert_from_b64(post_content):
   base64_bytes     = base64.b64decode(content_bytes)
   src_content      = base64_bytes.decode("utf8")
 
+
+#=======================#
+# Tabulations formating #
+#-----------------------#
+def tab_article(article):
+  global wip_html
+  
+  wip_tmp = ''
+  tab = 0
+  
+  for line in article:
+    if len(line) == 0: continue
+
+    print(line)
+    if line.startswith('
Date: Sat, 19 Nov 2022 18:05:49 +0100
Subject: [PATCH 013/247] wip: in-dev for HTML tabulations from final result

---
 src/var/lib/tyto/program/wip.py | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/src/var/lib/tyto/program/wip.py b/src/var/lib/tyto/program/wip.py
index 9085cfa..dafd287 100644
--- a/src/var/lib/tyto/program/wip.py
+++ b/src/var/lib/tyto/program/wip.py
@@ -591,7 +591,6 @@ def tab_article(article):
   for line in article:
     if len(line) == 0: continue
 
-    print(line)
     if line.startswith('
Date: Sat, 19 Nov 2022 18:10:52 +0100
Subject: [PATCH 014/247] wip: in-dev for HTML tabulations from final result

---
 src/var/lib/tyto/program/wip.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/var/lib/tyto/program/wip.py b/src/var/lib/tyto/program/wip.py
index dafd287..a9e7f14 100644
--- a/src/var/lib/tyto/program/wip.py
+++ b/src/var/lib/tyto/program/wip.py
@@ -471,7 +471,7 @@ def convert_bcodes(article, fm, lm, css):
   
     if bCode:
       bCode_ln += 1
-      line = '  %s%s'%(
+      line = '%s%s'%(
               bCode_ln, line
               )
       if bCode_lines: bCode_lines = '%s\n%s'%(bCode_lines, line)

From a3ab6c62b0e63e999c6963397e41c91f6661cbfe Mon Sep 17 00:00:00 2001
From: Cyrille L 
Date: Sun, 20 Nov 2022 16:58:55 +0100
Subject: [PATCH 015/247] check+wip: file links

---
 src/var/lib/tyto/program/check.py | 16 +++++++-------
 src/var/lib/tyto/program/wip.py   | 35 ++++++++++++++++++++++++++++---
 2 files changed, 41 insertions(+), 10 deletions(-)

diff --git a/src/var/lib/tyto/program/check.py b/src/var/lib/tyto/program/check.py
index ee899e0..a696173 100644
--- a/src/var/lib/tyto/program/check.py
+++ b/src/var/lib/tyto/program/check.py
@@ -194,7 +194,9 @@ def check_article(post_uri, Force):
   #------------------   
   # In check process: no values (kept from db, if exists)
   global hash_wip, hash_www, time_wip, time_www
+  
   hash_wip = time_wip = hash_www = time_www = ''
+  
   if db_exist:
     # backup hash_wip/www values
     hash_wip = post_wip[0];time_wip = post_wip[1]
@@ -569,7 +571,7 @@ def check_files(line, ln, stats_files_uniq):
   
   # Check NAME in article
   file_page = '__%s'%file_name
-  if not file_page in article.rsplit('\n'):
+  if not file_page in article:
     msg_log = 'Unused "%s" for marker "file:" in article"'%file_page
     log.append_f(post_logs,msg_log,1)
     Post_Err = True
@@ -578,10 +580,10 @@ def check_files(line, ln, stats_files_uniq):
   # In Generic folder /files/
   if file_uri.startswith('@'):
     file_uri = file_uri.replace('@','')
-    gen_file = '%s%s'%(domain.domain_files,file_uri)
+    gen_file = '%s%s'%(domain.domain_files, file_uri)
     if not os.path.exists(gen_file):
       msg_log = 'Unused file for marker "file:" in %s'%gen_file
-      log.append_f(post_logs,msg_log,1)
+      log.append_f(post_logs, msg_log, 1)
       Post_Err = True
     else:
       file_uri = '/files/%s'%file_uri
@@ -589,7 +591,7 @@ def check_files(line, ln, stats_files_uniq):
   # From Root articles (www/ in web)
   elif file_uri.startswith('/'):
     file_uri = file_uri[1:len(file_uri)] # No need first / to check
-    usr_file = '%s%s'%(domain.domain_articles,file_uri)
+    usr_file = '%s%s'%(domain.domain_articles, file_uri)
     if not os.path.exists(usr_file):
       msg_log = 'Unused file for marker "file:" in %s'%usr_file
       log.append_f(post_logs,msg_log,1)
@@ -599,10 +601,10 @@ def check_files(line, ln, stats_files_uniq):
   
   # Current or custom URI
   else:
-    usr_file = '%s%s'%(domain.domain_articles,file_uri)
+    usr_file = '%s%s'%(domain.domain_articles, file_uri)
     if not os.path.exists(usr_file):
       msg_log = 'Unused file for marker "file:" in %s'%usr_file
-      log.append_f(post_logs,msg_log,1)
+      log.append_f(post_logs, msg_log, 1)
       Post_Err = True
 
   if Post_Err: return
@@ -806,7 +808,7 @@ def check_article_markers(article):
     # Markers at begining line
     #-------------------------    
     # Paragraphs: ( and )
-    if re.match(markers_reg[0][0], line):   stats_p  += 1
+    if   re.match(markers_reg[0][0], line): stats_p  += 1
     elif re.match(markers_reg[0][1], line): stats_pe += 1
 
     # Lists: (- and -) ; count items with = and + at begining
diff --git a/src/var/lib/tyto/program/wip.py b/src/var/lib/tyto/program/wip.py
index a9e7f14..bfbd6e9 100644
--- a/src/var/lib/tyto/program/wip.py
+++ b/src/var/lib/tyto/program/wip.py
@@ -94,6 +94,7 @@ def manage_wip(file_post, Force):
   wip_begin_markers(wip_html.rsplit('\n'))
   wip_titles(       wip_html.rsplit('\n'))
   wip_words_markers(wip_html)
+  wip_files_links(wip_html)
   if anchors > 0: wip_anchors( wip_html)
   if abbrs_u > 0: wip_abbrs(   wip_html)
   
@@ -107,6 +108,7 @@ def manage_wip(file_post, Force):
   print('> Article HTML:')
   print(wip_html)
   
+  print('> Article with Tabs:')
   tab_article(wip_html.rsplit('\n'))
   
 
@@ -438,8 +440,33 @@ def quote_data(line):
   return line.split(' ', 1)[1].lstrip()
 
 
+#
+# Convert files_links
+#
+def wip_files_links(article):
+  global wip_html
+  
+  flink_fmt = '%s'
+  all_vars = set(globals())
+  
+  for var in all_vars:
+    if var.startswith('file_'):
+      flink     = globals()[var]
+      flink_b64 = flink_fmt%(domain.domain_css,
+                             flink[2],
+                             flink[1],
+                             flink[0]
+                            )
+      convert_to_b64(flink_b64)
+      article  = article.replace('__%s'%flink[0], b64_content)
+  
+  wip_html = article
+
+
 #=========================#
 # Done when command check #
+# - convert_bcodes()      #
+# - convert_icodes()      #
 #=========================#
 #====================================#
 # Protect bCodes contents to base64  #
@@ -480,7 +507,7 @@ def convert_bcodes(article, fm, lm, css):
       article_temp = '%s\n%s'%(article_temp, line)
 
 #====================================#
-# Protect bCodes contents to base64  #
+# Protect iCodes contents to base64  #
 # fm: First marker ; lm: last marker #
 #-----------------------------------=#
 def convert_icodes(article, css):
@@ -594,7 +621,8 @@ def tab_article(article):
     if line.startswith('
Date: Mon, 21 Nov 2022 14:03:27 +0100
Subject: [PATCH 016/247] wip: images

---
 src/var/lib/tyto/program/check.py |  20 +++---
 src/var/lib/tyto/program/wip.py   | 108 +++++++++++++++++++++++++++---
 2 files changed, 108 insertions(+), 20 deletions(-)

diff --git a/src/var/lib/tyto/program/check.py b/src/var/lib/tyto/program/check.py
index a696173..4c126c9 100644
--- a/src/var/lib/tyto/program/check.py
+++ b/src/var/lib/tyto/program/check.py
@@ -597,7 +597,7 @@ def check_files(line, ln, stats_files_uniq):
       log.append_f(post_logs,msg_log,1)
       Post_Err = True
     else:
-      file_uri = '/%s'%(file_uri)
+      file_uri = '/%s'%file_uri
   
   # Current or custom URI
   else:
@@ -632,7 +632,7 @@ def check_images(line, ln, stats_images_uniq):
   
   # Create variable array
   image_nbr  = 'image_%s'%stats_images_uniq
-  image_name = line.split('image:')[1].lstrip()
+  image_name = line.split('image:')[1].lstrip().rsplit(' ')[0]
   image_uri  = headers.rsplit('\n')[ln].lstrip()
   image_alt  = headers.rsplit('\n')[ln+1].lstrip()
 
@@ -657,19 +657,19 @@ def check_images(line, ln, stats_images_uniq):
   
   # Check value in article
   image_page = '_image:%s'%image_name
-  if not image_page in article.rsplit('\n'):
+  if not image_page in article:
     msg_log = 'Unused "%s" for marker "image:" in article"'%image_page
-    log.append_f(post_logs,msg_log,1)
+    log.append_f(post_logs, msg_log, 1)
     Post_Err = True
   
   # Check URI value (exists and where)
   # Set HTML value in DB
   if image_uri.startswith('@'):
     image_uri = image_uri.replace('@','')
-    gen_image = '%s%s'%(domain.domain_images,image_uri)
+    gen_image = '%s%s'%(domain.domain_images, image_uri)
     if not os.path.exists(gen_image):
       msg_log = 'Unused file for marker "imagee:" in %s'%gen_image
-      log.append_f(post_logs,msg_log,1)
+      log.append_f(post_logs, msg_log, 1)
       Post_Err = True
     else:
       image_uri = '/images/%s'%image_uri
@@ -677,20 +677,20 @@ def check_images(line, ln, stats_images_uniq):
   # From Root articles (www/ in web)
   elif image_uri.startswith('/'):
     image_uri = image_uri[1:len(image_uri)] # No need first / to check
-    usr_file = '%s%s'%(domain.domain_articles,image_uri)
+    usr_file = '%s%s'%(domain.domain_articles, image_uri)
     if not os.path.exists(usr_file):
       msg_log = 'Unused file for marker "image:" in %s'%usr_file
-      log.append_f(post_logs,msg_log,1)
+      log.append_f(post_logs, msg_log, 1)
       Post_Err = True
     else:
-      image_uri = '/%s'%(image_uri)
+      image_uri = '/%s'%image_uri
   
   # Current or custom URI
   else:
     usr_file = '%s%s'%(domain.domain_articles,image_uri)
     if not os.path.exists(usr_file):
       msg_log = 'Unused file for marker "file:" in %s'%usr_file
-      log.append_f(post_logs,msg_log,1)
+      log.append_f(post_logs, msg_log, 1)
       Post_Err = True
 
   if Post_Err: return
diff --git a/src/var/lib/tyto/program/wip.py b/src/var/lib/tyto/program/wip.py
index bfbd6e9..9c82352 100644
--- a/src/var/lib/tyto/program/wip.py
+++ b/src/var/lib/tyto/program/wip.py
@@ -94,13 +94,15 @@ def manage_wip(file_post, Force):
   wip_begin_markers(wip_html.rsplit('\n'))
   wip_titles(       wip_html.rsplit('\n'))
   wip_words_markers(wip_html)
-  wip_files_links(wip_html)
-  if anchors > 0: wip_anchors( wip_html)
-  if abbrs_u > 0: wip_abbrs(   wip_html)
+  
+  if files_u  > 0: wip_files_links(wip_html)
+  if images_u > 0: wip_images(     wip_html)
+  if anchors  > 0: wip_anchors(    wip_html)
+  if abbrs_u  > 0: wip_abbrs(      wip_html)
   
   # After all, convert protected contents
-  if links_u > 0: wip_links(   wip_html)
-  if quotes  > 0: wip_quotes(  wip_html.rsplit('\n'))
+  if links_u > 0: wip_links(       wip_html)
+  if quotes  > 0: wip_quotes(      wip_html.rsplit('\n'))
   
   # Get Legacy contents from base64 markers
   convert_all_b64(wip_html.rsplit('\n'))
@@ -108,8 +110,8 @@ def manage_wip(file_post, Force):
   print('> Article HTML:')
   print(wip_html)
   
-  print('> Article with Tabs:')
-  tab_article(wip_html.rsplit('\n'))
+  #print('> Article with Tabs:')
+  #tab_article(wip_html.rsplit('\n'))
   
 
 
@@ -440,9 +442,10 @@ def quote_data(line):
   return line.split(' ', 1)[1].lstrip()
 
 
-#
-# Convert files_links
-#
+#=========================#
+# Convert files_links     #
+# from header "file: xxx" #     #
+#-------------------------#
 def wip_files_links(article):
   global wip_html
   
@@ -463,6 +466,91 @@ def wip_files_links(article):
   wip_html = article
 
 
+#==========================#
+# Convert images           #
+# from header "image: xxx" #
+# Get parameters from line #     #
+#--------------------------#
+def wip_images(article):
+  global wip_html
+  
+  wip_html = ''
+  image_fmt = '%s'
+  img_style = '%s' # %(wh_style) style="..." if width and/or height
+  
+  all_vars = set(globals())
+  
+  for var in all_vars:
+    if var.startswith('image_'):
+      image     = globals()[var]
+      
+      # Search in article lines for _image:
+      for line in article.rsplit('\n'):
+        if not line.startswith('_image:'):
+          if wip_html: wip_html = '%s\n%s'%(wip_html, line)
+          else       : wip_html = line
+          
+        elif line.startswith('_image:%s'%image[0]):
+          width = height = set_css = target = ''
+          image_html = ''
+          wh_style  = '' # width and/or height parameters
+          
+          # Get parameters and set values for this marker
+          image_params = (line.rsplit(' '))
+          for param in image_params:
+            # CSS
+            if param.startswith('c='):
+              set_css = param.rsplit('=')[1]
+            
+            # Width
+            elif param.startswith('w='):
+              width = param.rsplit('=')[1]
+              if not width: width = ''
+              elif width.isdigit():
+                width = 'width:%spx;'%width
+              else:
+                wspl  = re.match(r"([0-9]+)([a-z]+)",width,re.I).groups()
+                width = 'width:%s;'%width
+            
+            # Height
+            elif param.startswith('h='):
+              height = param.rsplit('=')[1]
+              if not height: height = ''
+              elif height.isdigit():
+                height = 'height:%spx;'%height
+              else:
+                hspl  = re.match(r"([0-9]+)([a-z]+)",height,re.I).groups()
+                height = 'height:%s;'%height
+              
+            # Target
+            elif param.startswith('t='):
+              target = param.rsplit('=')[1]
+              if not target: target = image[1]
+          
+          # Check values and construct HTML
+          if not set_css: set_css = domain.domain_css
+          if width and height: wh_style = 'style="%s%s" '%(width,height)
+          elif width         : wh_style = 'style="%s" '%width
+          elif height        : wh_style = 'style="%s" '%height
+          
+          image_html = image_fmt%(set_css,
+                                  image[2], image[2],
+                                  img_style%wh_style,
+                                  image[1]
+                                 )
+          
+          # Create Target link if t=
+          if target:
+            line = '%s'%(
+                    set_css, target, image_html)
+            
+          else:
+            line = image_html
+          
+          if wip_html: wip_html = '%s\n%s'%(wip_html, line)
+          else       : wip_html = line
+  
+
 #=========================#
 # Done when command check #
 # - convert_bcodes()      #

From cc039f4555e388e77dc60b2d11ddf7d1e0c32a64 Mon Sep 17 00:00:00 2001
From: Cyrille L 
Date: Mon, 21 Nov 2022 14:18:15 +0100
Subject: [PATCH 017/247] wip: images ; split from regex var

---
 src/var/lib/tyto/program/wip.py | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/src/var/lib/tyto/program/wip.py b/src/var/lib/tyto/program/wip.py
index 9c82352..729864f 100644
--- a/src/var/lib/tyto/program/wip.py
+++ b/src/var/lib/tyto/program/wip.py
@@ -444,7 +444,7 @@ def quote_data(line):
 
 #=========================#
 # Convert files_links     #
-# from header "file: xxx" #     #
+# from header "file: xxx" #
 #-------------------------#
 def wip_files_links(article):
   global wip_html
@@ -469,11 +469,12 @@ def wip_files_links(article):
 #==========================#
 # Convert images           #
 # from header "image: xxx" #
-# Get parameters from line #     #
+# Get parameters from line #
 #--------------------------#
 def wip_images(article):
   global wip_html
   
+  regex_dw = r"([0-9]+)([a-z]+)"
   wip_html = ''
   image_fmt = '%s'
   img_style = '%s' # %(wh_style) style="..." if width and/or height
@@ -509,7 +510,7 @@ def wip_images(article):
               elif width.isdigit():
                 width = 'width:%spx;'%width
               else:
-                wspl  = re.match(r"([0-9]+)([a-z]+)",width,re.I).groups()
+                wspl  = re.match(regex_dw, width, re.I).groups()
                 width = 'width:%s;'%width
             
             # Height
@@ -519,7 +520,7 @@ def wip_images(article):
               elif height.isdigit():
                 height = 'height:%spx;'%height
               else:
-                hspl  = re.match(r"([0-9]+)([a-z]+)",height,re.I).groups()
+                hspl  = re.match(regex_dw, height, re.I).groups()
                 height = 'height:%s;'%height
               
             # Target
@@ -542,11 +543,12 @@ def wip_images(article):
           # Create Target link if t=
           if target:
             line = '%s'%(
-                    set_css, target, image_html)
-            
+                    set_css, target, image_html
+                    )
           else:
             line = image_html
           
+          # Replace line
           if wip_html: wip_html = '%s\n%s'%(wip_html, line)
           else       : wip_html = line
   

From ceec24105c0b105d01a6a4b19123e00beb397c31 Mon Sep 17 00:00:00 2001
From: Cyrille L 
Date: Mon, 21 Nov 2022 15:58:47 +0100
Subject: [PATCH 018/247] check: image in post + titles ; wip: fix empty lines
 in bCodes converter

---
 src/var/lib/tyto/program/check.py | 97 ++++++++++++++++++-------------
 src/var/lib/tyto/program/wip.py   |  6 +-
 2 files changed, 59 insertions(+), 44 deletions(-)

diff --git a/src/var/lib/tyto/program/check.py b/src/var/lib/tyto/program/check.py
index 4c126c9..cd49666 100644
--- a/src/var/lib/tyto/program/check.py
+++ b/src/var/lib/tyto/program/check.py
@@ -153,11 +153,10 @@ def create_domain_dirs(path_type):
 def get_filesum(path,src):
   from hashlib import blake2b
   file_sum = blake2b(digest_size=4)
-  if src:
-    file_sum.update(open(path, 'rb').read())
-  else:
-    file_sum.update(path.encode())
-  return file_sum.hexdigest()
+  
+  if src: file_sum.update(open(path, 'rb').read())
+  else  : file_sum.update(path.encode())
+  return  file_sum.hexdigest()
 
 
 #=========================#
@@ -169,13 +168,13 @@ def manage_check(file_post, Force):
   post_IDs(file_post)
   
   # Start checking Post, then exit if errors found in
-  check_article(post_uri, Force) 
+  process_article(post_uri, Force) 
 
 
 #==========================#
 # Pre-processing post file #
 #--------------------------#
-def check_article(post_uri, Force):
+def process_article(post_uri, Force):
   global article
   # Check needed directories. Create if not exist
   create_domain_dirs('db')
@@ -201,10 +200,11 @@ def check_article(post_uri, Force):
     # backup hash_wip/www values
     hash_wip = post_wip[0];time_wip = post_wip[1]
     hash_www = post_www[0];time_www = post_www[1]
+    
     # Compare chk Hashes.
     # Pass if Force, and not same
     if hash_chk == post_chk[0] and not Force:
-      print(':) Check was already done, on',post_chk[1])
+      print(':) Check was already done, on', post_chk[1])
       sys.exit(0)
 
   # Processing
@@ -218,6 +218,8 @@ def check_article(post_uri, Force):
   
   # Check markers in headers
   check_post_header(headers.rsplit('\n'))
+  if Post_Err: sys.exit(1)
+  
   
   # Protect bCodes, keep markers for stats, before checking other markers
   wip.convert_bcodes(article.rsplit('\n'),
@@ -249,9 +251,7 @@ def check_article(post_uri, Force):
   
   # Error in article 
   #---------------------
-  if Post_Err:
-    print(':( Invalid article. Needs corrections')
-    sys.exit(1)
+  if Post_Err: sys.exit(1)
   
   # No Domain registred yet
   #-------------------------
@@ -297,8 +297,8 @@ def post_to_strings(post_uri):
   # Split post in 2 strings for Headers and Article
   global headers, article, post_lines, headers_ln
   
-  post_lines = file_string.rsplit('\n')
   headers = article = ''
+  post_lines = file_string.rsplit('\n')
   post = False
   
   for line in post_lines:
@@ -320,20 +320,23 @@ def post_to_strings(post_uri):
 # Loop into headers to check markers #
 #------------------------------------#
 def check_post_header(headers):
-  global Post_Err
-  global stats_links_uniq, stats_files_uniq, stats_images_uniq, stats_abbrs_uniq
-  global stats_links_p, stats_files_p, stats_images_p, stats_abbrs_p
-  global stats_links
   # Mandatory markers
   global title, about, author, tags, date
 
-  # Set Stats
-  stats_links_uniq = stats_files_uniq = stats_images_uniq = stats_abbrs_uniq = 0
-  stats_links = stats_links_p = stats_files_p = stats_images_p = stats_abbrs_p = 0
-  
   # Set Mandatory marker.               0:True/False 1:ln 2: Content
   title  = about = author = tags = date = ('','','')
   
+  # Set Stats
+  global stats_links_uniq,  stats_links, stats_links_p
+  global stats_files_uniq,  stats_files_p
+  global stats_images_uniq, stats_images_p
+  global stats_abbrs_uniq,  stats_abbrs_p
+  
+  stats_links_uniq  = stats_links    = stats_links_p = 0
+  stats_files_uniq  = stats_files_p  = 0
+  stats_images_uniq = stats_images_p = 0
+  stats_abbrs_uniq  = stats_abbrs_p  = 0
+  
   # Set Optional markers. 0:ln 1:Name 2:URL 3:Alt
   link = file = image = ('','','','')
   
@@ -799,8 +802,8 @@ def check_article_markers(article):
   #------------------------
   for ln, line in enumerate(article.rsplit('\n'), 1):
     
-    # Do not check if in precode: [[ and ]]
-    if re.match(markers_reg[2][0], line):   precode = True
+    # Do not check line if in precode: [[ and ]]
+    if   re.match(markers_reg[2][0], line): precode = True
     elif re.match(markers_reg[2][1], line): precode = False
     if precode: continue
 
@@ -833,15 +836,15 @@ def check_article_markers(article):
     elif re.match(markers_reg[1][1], line): stats_qe     += 1
     
     # Check if referenced in header for markers
-    for marker_p in '_image:', '_code:', '_brut:':
-      if re.match(r'^%s'%marker_p, line):
-        m_name = line.split(':')[1][0]
-        marker_h = marker_p[1:len(marker_p)]
-        if not re.findall(r'%s\s+%s'%(marker_h, m_name), headers):
+    for marker in '_image:', '_code:', '_brut:':
+      if re.match(r'^%s'%marker, line):
+        m_name = line.split(':')[1].split(' ')[0]
+        marker_h = marker[1:len(marker)]
+        if not re.findall(r'\b%s\s+%s\b'%(marker_h, m_name), headers):
           msg_log = 'Line %s. Unused marker "%s %s" in header'%(
                      ln+headers_ln, marker_h, m_name
                      )
-          log.append_f(post_logs,msg_log,1)
+          log.append_f(post_logs, msg_log, 1)
           Post_Err = True
 
   #------------------------------
@@ -962,7 +965,7 @@ def check_article_titles(article):
   #------------------------
   for ln, line in enumerate(article, 1):
     
-    # Do not check if in precode: [[ and ]]
+    # Do not check line if in precode: [[ and ]]
     if re.match(markers_reg[2][0], line):
       precode = True
       stats_bcodes += 1
@@ -977,22 +980,33 @@ def check_article_titles(article):
       title = line.split(' ', 1)
       ht = line[1]
       
+      # Check title marker #[1-6]
       if ht == ' ' or ht == '#':
         stats_comments += 1
         continue
       
-      if ht.isnumeric() and not int(ht) in range(1,7):
-        msg_log = 'Line %s. Mismatch title number "%s" (1-6)'%(
-                   ln + headers_ln, ht)
-        log.append_f(post_logs,msg_log,1)
-        Post_Err = True
-        continue
+      # Title number not in range
+      elif ht.isdigit():
+        if not int(ht) in range(1,7):
+          msg_log = 'Line %s. Mismatch title number "%s" (1-6)'%(
+                     ln + headers_ln, ht)
+          log.append_f(post_logs,msg_log,1)
+          Post_Err = True
+          continue
+      
+      # Not a digit in marker title
+      else:
+          msg_log = 'Line %s. Mismatch title number "%s" (1-6)'%(
+                     ln + headers_ln, ht)
+          log.append_f(post_logs,msg_log,1)
+          Post_Err = True
+          continue
+      
+      # Check description's title
       try:
         title[1]
-        if title[1] ==  ' ' or title[1] == '':
-          Title_Err = True
-        else:
-          stats_titles += 1
+        if not title[1] or title[1] == ' ': Title_Err     = True
+        else                              : stats_titles += 1
       except:
         Title_Err = True
       
@@ -1010,8 +1024,7 @@ def check_article_titles(article):
 #---------------------------#
 def check_links_anchors(article):
   global Post_Err
- 
-  #for ln, line in enumerate(article.rsplit('\n'), 1):
+
   anchors_link = re.findall(r'\>_(.*?)_\<', article)
   for anchor in anchors_link:
     anchor_id = anchor.rsplit(':',1)[0]
@@ -1042,7 +1055,7 @@ def check_lists_contents(article):
     
     if inlist and not re.match(r'^\+|^\=|\s', line):
         msg_log = 'Content list not "+" or "=": %s'%line
-        log.append_f(post_logs,msg_log,1)
+        log.append_f(post_logs, msg_log, 1)
         Post_Err = True
 
 #====================================#
diff --git a/src/var/lib/tyto/program/wip.py b/src/var/lib/tyto/program/wip.py
index 729864f..c7dd5d7 100644
--- a/src/var/lib/tyto/program/wip.py
+++ b/src/var/lib/tyto/program/wip.py
@@ -573,7 +573,8 @@ def convert_bcodes(article, fm, lm, css):
   for line in article:    
     if line.startswith(fm):
       bCode        = True
-      article_temp = '%s\n%s'%(article_temp, line)
+      if article_temp: article_temp = '%s\n%s'%(article_temp, line)
+      else           : article_temp = line
       continue
     
     if line.startswith(lm):
@@ -594,7 +595,8 @@ def convert_bcodes(article, fm, lm, css):
       if bCode_lines: bCode_lines = '%s\n%s'%(bCode_lines, line)
       else          : bCode_lines = line
     else:
-      article_temp = '%s\n%s'%(article_temp, line)
+      if article_temp: article_temp = '%s\n%s'%(article_temp, line)
+      else           : article_temp = line
 
 #====================================#
 # Protect iCodes contents to base64  #

From 0ee4994d3f3108e5be9e71b27502fa529bbc910c Mon Sep 17 00:00:00 2001
From: Cyrille L 
Date: Mon, 21 Nov 2022 16:07:03 +0100
Subject: [PATCH 019/247] fix smileys in stdout

---
 src/var/lib/tyto/program/check.py  |  7 +++----
 src/var/lib/tyto/program/domain.py | 16 +++++++---------
 2 files changed, 10 insertions(+), 13 deletions(-)

diff --git a/src/var/lib/tyto/program/check.py b/src/var/lib/tyto/program/check.py
index cd49666..a25321e 100644
--- a/src/var/lib/tyto/program/check.py
+++ b/src/var/lib/tyto/program/check.py
@@ -68,7 +68,7 @@ def post_IDs(file_post):
   # From argument file_post
   # Set WEB link prefix. Count / in uri
   global weburi
-  slash = 0
+  slash  = 0
   weburi = ''
   
   for s in file_post:
@@ -262,8 +262,7 @@ def process_article(post_uri, Force):
 
   # No Error...
   #------------ 
-  # Temp post file for this article to use with wip action
-  # Set
+  # Create (file).wip for this article to use with wip argument
   global post_tmp
   post_tmp  = '%s%s.wip'%(domain.domain_db, curr_post_ID)
   
@@ -279,7 +278,7 @@ def process_article(post_uri, Force):
   
   # Create DB
   create_DB(curr_post_db)
-  print(':) Article is Ok and ready to "tyto wip"')
+  print(':D Article is Ok and ready to "tyto wip"')
 
 #=========================================#
 # Put file in strings => headers, article #
diff --git a/src/var/lib/tyto/program/domain.py b/src/var/lib/tyto/program/domain.py
index b5a0aed..3d0016b 100644
--- a/src/var/lib/tyto/program/domain.py
+++ b/src/var/lib/tyto/program/domain.py
@@ -62,24 +62,22 @@ except:
 
 domains_db = open(tyto_domains,'r').read()
 
-# Get user domain configuration file #
+# Get user domain configuration file
 # If exists, set to True, and exec
 try: # os.path.exists(conf_domain):
   exec(open(conf_domain).read())
   datas_domain = open(conf_domain, "r").read()
-  if domain_active:
-    print(':) Activated domain: "%s"'%domain_name)
-  else:
-    print(':/ Not activated domain in',conf_domain)
+  if domain_active: print(':D Activated domain: "%s"'%domain_name)
+  else            : print(':/ Not activated domain in',conf_domain)
 except:
-  print(':( Unused domain file:', conf_domain)
+  print(':< Unused domain file:', conf_domain)
 
 #=======#
 # Tools #
 #=======#--------------------------------------------------------------
-#============================#
-# Append new value to a file #
-#----------------------------#
+#===========================#
+# Append new line to a file #
+#---------------------------#
 def append_f(f,line_val):
   file = open(f, "a")
   file.write('%s\n'%line_val)

From f4fbb825db035baa86f1f040ce923e6f57648145 Mon Sep 17 00:00:00 2001
From: Cyrille L 
Date: Mon, 21 Nov 2022 17:06:46 +0100
Subject: [PATCH 020/247] domain: fix smileys

---
 src/var/lib/tyto/program/domain.py | 62 ++++++++++++------------------
 1 file changed, 24 insertions(+), 38 deletions(-)

diff --git a/src/var/lib/tyto/program/domain.py b/src/var/lib/tyto/program/domain.py
index 3d0016b..6a0ecf2 100644
--- a/src/var/lib/tyto/program/domain.py
+++ b/src/var/lib/tyto/program/domain.py
@@ -90,7 +90,7 @@ def append_f(f,line_val):
 #--------------------------------------#
 def exiting(process,out,msg):
   msgs = [
-          '\n:) All done !',
+          '\n:D All done !',
           '\n:/ Maybe next time...',
           '%s'%msg
          ]
@@ -133,9 +133,9 @@ def manage_domain(Domain, Opt):
       # Compare before and after domain conf file
       new_conf_ID = check.get_filesum(domain_conf,True)
       if not old_conf_ID == new_conf_ID:
-        exiting('root',2,':) Updated domain configuration file.')
+        exiting('root',2,':D Updated domain configuration file.')
       else:
-        exiting('root',2,':) Unchanged domain configuration file.')
+        exiting('root',2,':D Unchanged domain configuration file.')
     else:
       sys.exit(0)
 
@@ -222,10 +222,8 @@ def domain_input_confirn(set_domain):
 def domain_input():
   global domain_name
   set_domain = input(' ├ Enter Domain Name: ')
-  if not set_domain:
-    exiting('root',1,'')
-  else:
-    domain_name = set_domain
+  if not set_domain: exiting('root', 1, '')
+  else             : domain_name = set_domain
 
 #====================#
 # Domain FORM        #
@@ -274,7 +272,7 @@ def domain_form():
     srv = set_srv[:-1]
   
   if not os.path.exists(srv):
-    exiting('form',2,'\n:( Unsed directory "%s"'%srv)
+    exiting('form',2,'\n:< Unsed directory "%s"'%srv)
   
   # Settings for server
   srv_domain       = '%s/%s/'%(srv,domain_name)
@@ -330,7 +328,7 @@ def domain_form():
   set_sep = input(' ├ Website pages separator (%s) ? '%sep_titles)
   if set_sep:
     if len(set_sep) > 2:
-      exiting('form',2,'\n:( Seperator is 2 characters max')
+      exiting('form', 2, '\n:< Seperator is 2 characters max')
     sep_titles = set_sep
   
   append_f(temp_domain,'sep_titles       = "%s"'%sep_titles)
@@ -345,12 +343,9 @@ def domain_form():
     domain_about = show_about = ''
     
   set_about = input(' ├ Domain description (%s) ? '%show_about)
-  if not set_about and not domain_about:
-    exiting('form',1,'')
-  if set_about:
-    domain_about = set_about
-  if '"' in domain_about:
-    domain_about = domain_about.replace('"','\\"')
+  if not set_about and not domain_about: exiting('form',1,'')
+  if set_about: domain_about = set_about
+  if '"' in domain_about: domain_about = domain_about.replace('"','\\"')
   
   append_f(temp_domain,'domain_about     = "%s"'%domain_about)
   
@@ -367,7 +362,7 @@ def domain_form():
   set_lang = input(' ├ Website HTML lang (%s) ? '%domain_lang)
   if set_lang:
     if len(set_lang) > 3:
-      exiting('form',2,'\n:( HTML Lang is 3 characters max')
+      exiting('form',2,'\n:< HTML Lang is 3 characters max')
     domain_lang = set_lang
   
   append_f(temp_domain,'domain_lang      = "%s"'%domain_lang)
@@ -399,14 +394,13 @@ def domain_form():
     domain_mail = show_mail = ''
 
   set_mail = input(' ├ Contact admin mail (%s) ? '%show_mail)
-  if not set_mail and not domain_mail:
-    exiting('form',1,'')
+  if not set_mail and not domain_mail: exiting('form', 1, '')
   if set_mail:
     if not '@' and not '.' in set_mail:
-      exiting('form',2,'\n:( Invalid mail format (x@x.x)')
+      exiting('form', 2, '\n:< Invalid mail format (x@x.x)')
     domain_mail = set_mail
   elif not domain_mail:
-    exiting('form',2,'\n:( Mail is required.')
+    exiting('form', 2, '\n:< Mail is required.')
     
   append_f(temp_domain,'domain_mail      = "%s"'%domain_mail)
 
@@ -420,10 +414,8 @@ def domain_form():
     domain_tags = show_tags = ''
 
   set_tags = input(' ├ Domain Tags [x,y] (%s) ? '%show_tags)
-  if not set_tags and not domain_tags:
-    exiting('form',1,'')
-  if set_tags:
-    domain_tags = set_tags
+  if not set_tags and not domain_tags: exiting('form', 1, '')
+  if set_tags: domain_tags = set_tags
 
   append_f(temp_domain,'domain_tags      = "%s"'%domain_tags)
 
@@ -437,8 +429,7 @@ def domain_form():
     domain_license = show_license = 'CC BY-NC-SA'
   
   set_license = input(' ├ Website copyright (%s) ? '%show_license)
-  if set_license:
-    domain_license = set_license
+  if set_license: domain_license = set_license
   if '"' in domain_license:
     domain_license = domain_license.replace('"','\\"')
 
@@ -451,14 +442,11 @@ def domain_form():
     sidebar_title
     show_st = sidebar_title[:14] + '...'
   except:
-    if 'fr' in domain_lang:
-      sidebar_title = show_st = "À l'affiche !"
-    else:
-      sidebar_title = show_st = "Featured !"
+    if 'fr' in domain_lang: sidebar_title = show_st = "À l'affiche !"
+    else                  : sidebar_title = show_st = "Featured !"
 
   set_st = input(' ├ Sidebar title (%s) ? '%show_st)
-  if set_st:
-    sidebar_title = set_st
+  if set_st: sidebar_title = set_st
   if '"' in sidebar_title:
     sidebar_title = sidebar_title.replace('"','\\"')
 
@@ -473,7 +461,7 @@ def domain_form():
   set_si = input(' ├ Sidebar max items [1-16] (%s) ? '%sidebar_items)
   if set_si and set_si.isdigit():
     if set_si in range(1,16):
-      exiting('form',2,'\n:( Items number: 1-16')
+      exiting('form',2,'\n:< Items number: 1-16')
     sidebar_items = set_si
   
   # Domain LOGO (optional)
@@ -486,8 +474,7 @@ def domain_form():
     domain_logo = show_logo = ''
 
   set_logo = input(' ├ Optional. Logo filename (%s) ? '%show_logo)
-  if set_logo:
-    domain_logo = set_logo
+  if set_logo: domain_logo = set_logo
   append_f(temp_domain,'domain_logo      = "%s"'%domain_logo)
   
   # External URL profile (optional)
@@ -500,8 +487,7 @@ def domain_form():
     domain_exturl = show_e = ''
   
   set_e = input(' └ Optionnal. URL to a social network (%s) ? '%show_e)
-  if set_e:
-    domain_exturl = set_e
+  if set_e: domain_exturl = set_e
   
   append_f(temp_domain,'domain_exturl    = "%s"'%domain_exturl)
 
@@ -533,6 +519,6 @@ def create_domain():
   check.create_domain_dirs('all')
   
   # Will rename temp_domain conf to legacy domain conf file
-  exiting('form',2,'\n:) Activated domain: "%s"'%domain_name)
+  exiting('form',2,'\n:D Activated domain: "%s"'%domain_name)
 
 

From 17e3fdd342a937806cb190b31e20e24131cfcde6 Mon Sep 17 00:00:00 2001
From: Cyrille L 
Date: Mon, 21 Nov 2022 17:13:02 +0100
Subject: [PATCH 021/247] litle misc

---
 src/var/lib/tyto/program/check.py | 15 +++++++--------
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/src/var/lib/tyto/program/check.py b/src/var/lib/tyto/program/check.py
index a25321e..f1ec067 100644
--- a/src/var/lib/tyto/program/check.py
+++ b/src/var/lib/tyto/program/check.py
@@ -52,7 +52,7 @@ markers_opt = (
 def post_IDs(file_post):
   # Check if argument's file (.tyto) or exit
   if not file_post:
-    print(':( Unused argument file')
+    print(':< Unused argument file')
     sys.exit(1)
   
   # Set HTML file from file_post
@@ -62,7 +62,7 @@ def post_IDs(file_post):
   global post_uri
   post_uri = '%s%s'%(domain.domain_articles, file_post)
   if not os.path.exists(post_uri):
-    print(':( Unused file: %s'%post_uri)
+    print(':< Unused file: %s'%post_uri)
     sys.exit(1)
   
   # From argument file_post
@@ -142,7 +142,7 @@ def create_domain_dirs(path_type):
   
   # Check/Create needed directories (only for 'check' process)
   if 'db' in path_type:
-    os.makedirs(domain.domain_db, exist_ok=True)
+    os.makedirs(domain.domain_db,   exist_ok=True)
     os.makedirs(domain.domain_logs, exist_ok=True)
     
 #=======================#
@@ -187,7 +187,7 @@ def process_article(post_uri, Force):
     file.close()
     msg_log = 'Log > Create logs file for %s in %s\n'%(
                post_uri, post_logs)
-    log.append_f(post_logs,msg_log,0)
+    log.append_f(post_logs, msg_log, 0)
   
   # Article Database
   #------------------   
@@ -204,7 +204,7 @@ def process_article(post_uri, Force):
     # Compare chk Hashes.
     # Pass if Force, and not same
     if hash_chk == post_chk[0] and not Force:
-      print(':) Check was already done, on', post_chk[1])
+      print(':D Check was already done, on', post_chk[1])
       sys.exit(0)
 
   # Processing
@@ -220,7 +220,6 @@ def process_article(post_uri, Force):
   check_post_header(headers.rsplit('\n'))
   if Post_Err: sys.exit(1)
   
-  
   # Protect bCodes, keep markers for stats, before checking other markers
   wip.convert_bcodes(article.rsplit('\n'),
                     '[[', ']]',
@@ -406,13 +405,13 @@ def if_mandat_marker(marker, m_in):
   
   if not m_in[0]:
     msg_log = 'Unused needed marker "%s"'%marker
-    log.append_f(post_logs,msg_log,1)
+    log.append_f(post_logs, msg_log, 1)
     Post_Err = True
   elif not m_in[2]:
     msg_log = 'Line %s. Undefined marker "%s"'%(
                m_in[1], marker
                )
-    log.append_f(post_logs,msg_log,1)
+    log.append_f(post_logs, msg_log, 1)
 
 #================================#
 # Check Date format and validity #

From 6f3de302ee19ff3f80ef9cd7587cb3e9615e5bcc Mon Sep 17 00:00:00 2001
From: Cyrille L 
Date: Tue, 22 Nov 2022 12:21:55 +0100
Subject: [PATCH 022/247] check: added "brut:" marker

---
 src/var/lib/tyto/program/check.py | 133 +++++++++++++++++++++++++-----
 1 file changed, 114 insertions(+), 19 deletions(-)

diff --git a/src/var/lib/tyto/program/check.py b/src/var/lib/tyto/program/check.py
index f1ec067..07f6101 100644
--- a/src/var/lib/tyto/program/check.py
+++ b/src/var/lib/tyto/program/check.py
@@ -329,14 +329,16 @@ def check_post_header(headers):
   global stats_files_uniq,  stats_files_p
   global stats_images_uniq, stats_images_p
   global stats_abbrs_uniq,  stats_abbrs_p
+  global stats_bruts_uniq,  stats_bruts_p
   
   stats_links_uniq  = stats_links    = stats_links_p = 0
   stats_files_uniq  = stats_files_p  = 0
   stats_images_uniq = stats_images_p = 0
   stats_abbrs_uniq  = stats_abbrs_p  = 0
+  stats_bruts_uniq  = stats_bruts_p  = 0
   
   # Set Optional markers. 0:ln 1:Name 2:URL 3:Alt
-  link = file = image = ('','','','')
+  link = file = image = brut = ('','','','')
   
   #-----------------------
   # Loop in headers string
@@ -360,26 +362,26 @@ def check_post_header(headers):
     #----------------------
     # Set optional markers
     #----------------------
-    # links:
+    # link:
     if line.startswith('link:'):
-      # Create variable array
       stats_links_uniq += 1
       check_links(line, ln, stats_links_uniq)
-    # files:
+    # file:
     elif line.startswith('file:'):
-      # Create variable array
       stats_files_uniq += 1
       check_files(line, ln, stats_files_uniq)
-    # images:
+    # image:
     elif line.startswith('image:'):
-      # Create variable array
       stats_images_uniq += 1
       check_images(line, ln, stats_images_uniq)
-    # ABBR
+    # abbr:
     elif line.startswith('abbr:'):
-      # Create variable array
       stats_abbrs_uniq += 1
       check_abbrs(line, ln, stats_abbrs_uniq)
+    # brut:
+    elif line.startswith('brut:'):
+      stats_bruts_uniq += 1
+      check_bruts(line, ln, stats_bruts_uniq)
       
 
   #-------------------------------
@@ -390,8 +392,7 @@ def check_post_header(headers):
   if_mandat_marker('author:', author)
   if_mandat_marker('tags:', tags)
   if_mandat_marker('date:', date)
-  if date:
-    check_date(date)
+  if date: check_date(date)
 
 
 #===================#
@@ -435,7 +436,7 @@ def check_date(date):
     
   # Create date_check (epoch) from article's Date + now TIME
   if not Post_Err:
-    fmt_check = '%Y-%m-%d %H:%M:%S'
+    fmt_check  = '%Y-%m-%d %H:%M:%S'
     time_check = strftime("%H:%M:%S", gmtime())
     date_check = date[2] + ' ' + time_check 
     date_check = time.mktime(time.strptime(date_check,fmt_check))
@@ -595,7 +596,7 @@ def check_files(line, ln, stats_files_uniq):
     usr_file = '%s%s'%(domain.domain_articles, file_uri)
     if not os.path.exists(usr_file):
       msg_log = 'Unused file for marker "file:" in %s'%usr_file
-      log.append_f(post_logs,msg_log,1)
+      log.append_f(post_logs, msg_log, 1)
       Post_Err = True
     else:
       file_uri = '/%s'%file_uri
@@ -622,6 +623,92 @@ def check_files(line, ln, stats_files_uniq):
   # Stats: count occurence
   stats_files_p = stats_counter(file_page)
 
+#=================================#
+# Check every marker "brut:"      #
+# For line, from loop header file #
+# Also, create Stats              #
+#---------------------------------#
+def check_bruts(line, ln, stats_files_uniq):
+  global Post_Err
+  global stats_bruts_p
+  
+  # Create variable array
+  brut_nbr  = 'brut_%s'%stats_bruts_uniq
+  brut_name = line.split('brut:')[1].lstrip().rsplit(' ')[0]
+  brut_uri  = headers.rsplit('\n')[ln].lstrip()
+  brut_alt  = headers.rsplit('\n')[ln+1].lstrip()
+
+  # Check 2nd line
+  check_new_marker(brut_uri)
+  if new_marker: brut_uri = ''
+
+  # Check 3rd line
+  check_new_marker(brut_alt)
+  if new_marker: brut_alt = ''
+
+  brut = (
+          ln,
+          brut_name,
+          brut_uri,
+          brut_alt
+         )
+  
+  # Set/Check values to check in header
+  globals()[brut_nbr] = brut
+  if_option_marker('brut:', globals()[brut_nbr])
+
+  # Check value in article
+  brut_page = '_brut:%s'%brut_name
+  if not brut_page in article:
+    msg_log = 'Unused "%s" for marker "brut:" in article"'%brut_page
+    log.append_f(post_logs, msg_log, 1)
+    Post_Err = True
+
+  # Check URI value (exists and where)
+  # In Generic folder /files/
+  if brut_uri.startswith('@'):
+    brut_uri = brut_uri.replace('@','')
+    gen_file = '%s%s'%(domain.domain_files, brut_uri)
+    if not os.path.exists(gen_file):
+      msg_log = 'Unused file for marker "brut:" in %s'%gen_file
+      log.append_f(post_logs, msg_log, 1)
+      Post_Err = True
+    else:
+      brut_uri = '/files/%s'%brut_uri
+
+  # From Root articles (www/ in web)
+  elif brut_uri.startswith('/'):
+    brut_uri = brut_uri[1:len(brut_uri)] # No need first / to check
+    usr_file = '%s%s'%(domain.domain_articles, brut_uri)
+    if not os.path.exists(usr_file):
+      msg_log = 'Unused file for marker "brut:" in %s'%usr_file
+      log.append_f(post_logs, msg_log, 1)
+      Post_Err = True
+    else:
+      brut_uri = '/%s'%brut_uri
+
+  # Current or custom URI
+  else:
+    usr_file = '%s%s'%(domain.domain_articles, brut_uri)
+    if not os.path.exists(usr_file):
+      msg_log = 'Unused file for marker "brut:" in %s'%usr_file
+      log.append_f(post_logs, msg_log, 1)
+      Post_Err = True
+
+  if Post_Err: return
+  #--------------------
+  # Set final marker_N
+  #--------------------
+  brut = (
+          '%s'%brut_name,
+          brut_uri,
+          brut_alt
+         )
+  globals()[brut_nbr] = brut
+  
+  # Stats: count occurence
+  stats_bruts_p = stats_counter(brut_page)
+
 #=================================#
 # Check every marker "image:"     #
 # For line, from loop header file #
@@ -1110,21 +1197,27 @@ def create_DB(post_db):
   
   # Add every "file:" array found to DB, one per line
   if stats_files_uniq > 0:
-    for n in range(1,stats_files_uniq+1):
+    for n in range(1, stats_files_uniq+1):
       m = 'file_%s'%n
-      domain.append_f(post_db,'%s  = %s'%(m,globals()[m]))
+      domain.append_f(post_db, '%s  = %s'%(m,globals()[m]))
 
   # Add every "image:" array found to DB, one per line
   if stats_images_uniq > 0:
-    for n in range(1,stats_images_uniq+1):
+    for n in range(1, stats_images_uniq+1):
       m = 'image_%s'%n
-      domain.append_f(post_db,'%s = %s'%(m,globals()[m]))
+      domain.append_f(post_db, '%s = %s'%(m,globals()[m]))
+
+  # Add every "image:" array found to DB, one per line
+  if stats_bruts_uniq > 0:
+    for n in range(1, stats_bruts_uniq+1):
+      m = 'brut_%s'%n
+      domain.append_f(post_db, '%s  = %s'%(m,globals()[m]))
 
   # Add every "abbr:" array found to DB, one per line
   if stats_abbrs_uniq > 0:
-    for n in range(1,stats_abbrs_uniq+1):
+    for n in range(1, stats_abbrs_uniq+1):
       m = 'abbr_%s'%n
-      domain.append_f(post_db,'%s  = %s'%(m,globals()[m]))
+      domain.append_f(post_db, '%s  = %s'%(m,globals()[m]))
 
   # Statistics Post conf
   lines_conf = ''
@@ -1133,6 +1226,7 @@ def create_DB(post_db):
                 'links_u    = %d'%stats_links_uniq,
                 'files_u    = %d'%stats_files_uniq,
                 'images_u   = %d'%stats_images_uniq,
+                'bruts_u    = %d'%stats_bruts_uniq,
                 'abbrs_u    = %d'%stats_abbrs_uniq,
                 '\n# Statistics (Wordings)',
                 'strongs    = %d'%m_stats[0],
@@ -1149,6 +1243,7 @@ def create_DB(post_db):
                 'links_p    = %d'%stats_links_p,
                 'files_p    = %d'%stats_files_p,
                 'images_p   = %d'%stats_images_p,
+                'bruts_p    = %d'%stats_bruts_p,
                 'abbrs_p    = %d'%stats_abbrs_p,
                 '\n# Statistics (Templates)',
                 'titles     = %d'%stats_titles,

From d24600f1eb2a0f995619bbd4c65627e9c37a0eac Mon Sep 17 00:00:00 2001
From: Cyrille L 
Date: Tue, 22 Nov 2022 14:59:12 +0100
Subject: [PATCH 023/247] wip: added "_brut:" converter

---
 src/var/lib/tyto/program/wip.py | 65 +++++++++++++++++++++++++++++----
 1 file changed, 58 insertions(+), 7 deletions(-)

diff --git a/src/var/lib/tyto/program/wip.py b/src/var/lib/tyto/program/wip.py
index c7dd5d7..908caa4 100644
--- a/src/var/lib/tyto/program/wip.py
+++ b/src/var/lib/tyto/program/wip.py
@@ -104,14 +104,17 @@ def manage_wip(file_post, Force):
   if links_u > 0: wip_links(       wip_html)
   if quotes  > 0: wip_quotes(      wip_html.rsplit('\n'))
   
+  # brut files
+  if bruts_u > 0: wip_bruts(      wip_html.rsplit('\n')) 
+  
   # Get Legacy contents from base64 markers
   convert_all_b64(wip_html.rsplit('\n'))
   
-  print('> Article HTML:')
-  print(wip_html)
+  #print('> Article HTML:')
+  #print(wip_html)
   
-  #print('> Article with Tabs:')
-  #tab_article(wip_html.rsplit('\n'))
+  print('> Article with Tabs:')
+  tab_article(wip_html.rsplit('\n'))
   
 
 
@@ -553,6 +556,55 @@ def wip_images(article):
           else       : wip_html = line
   
 
+#=============================================#
+# Convert line _brut: to pre HTML, like bCode #
+#---------------------------------------------#
+def wip_bruts(article):
+  global wip_html
+  
+  wip_html = ''
+  
+  all_vars = set(globals())
+  
+  for var in all_vars:
+    if var.startswith('brut_'):
+      brut     = globals()[var]
+
+
+      # Search in article lines for _image:
+      for line in article:
+        if not line.startswith('_brut:'):
+          if wip_html: wip_html = '%s\n%s'%(wip_html, line)
+          else       : wip_html = line
+        
+        elif line.startswith('_brut:%s'%brut[0]):
+          # Open target file
+          brut_file  = ''
+          brut_html  = '' # brut file contents
+          brut_uri   = brut[1][1:len(brut[1])] # No need first "/"
+          brut_file  = '%s%s'%(domain.domain_articles, brut_uri)
+          brut_datas = open(brut_file, 'r').read()
+          
+          # Convert each lines to HTML, add to string
+          for ln, bline in enumerate(brut_datas.rsplit('\n'), 1):
+            brut_line_html = '%s'%ln + \
+                             '%s'%bline
+            if brut_html: brut_html = '%s\n%s'%(brut_html,brut_line_html)
+            else        : brut_html = brut_line_html
+          
+          # Get CSS, if exists, before creating last brut_html
+          get_css(line)
+          
+          # Add first and last HTML tags to string
+          brut_html = '
\n'%(
+                       css_set, brut[2]) + \
+                      '%s\n
'%brut_html + + # Replace line + if wip_html: wip_html = '%s\n%s'%(wip_html, brut_html) + else : wip_html = brut_html + + #=========================# # Done when command check # # - convert_bcodes() # @@ -589,9 +641,8 @@ def convert_bcodes(article, fm, lm, css): if bCode: bCode_ln += 1 - line = '%s%s'%( - bCode_ln, line - ) + line = '%s'%bCode_ln + \ + '%s'%line if bCode_lines: bCode_lines = '%s\n%s'%(bCode_lines, line) else : bCode_lines = line else: From 7945f5473f7ee02f456b6d428ebd4c29a5364677 Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Tue, 22 Nov 2022 16:04:45 +0100 Subject: [PATCH 024/247] html: in very ealy dev --- src/var/lib/tyto/program/html.py | 48 ++++++++++++++++++++++++++++++++ src/var/lib/tyto/program/wip.py | 7 +++-- 2 files changed, 52 insertions(+), 3 deletions(-) create mode 100644 src/var/lib/tyto/program/html.py diff --git a/src/var/lib/tyto/program/html.py b/src/var/lib/tyto/program/html.py new file mode 100644 index 0000000..1db253a --- /dev/null +++ b/src/var/lib/tyto/program/html.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python3 +# Name: Tyto - Littérateur +# Type: Global functions for HTML page +# Description: Create final HTML Page +# file: html.py +# Folder: /var/lib/tyto/programs/ +# By echolib (XMPP: im@echolib.re) +# License: GNU AFFERO GENERAL PUBLIC LICENSE Version 3, 19 November 2007 + +#------------ +# funny stats +#------------ +# lines: +# functions: +# comments: +#---------------------------------------------------------------------- + +#********************************************************************** +import check, log, domain + +def html_main_page(): + # Source DB variables + post_db = exec(open(check.curr_post_db).read(),globals()) + + # Metas in HTML page + scale = 'width=device-width, initial-scale=1.0' + visit = '3 days' + title = '%s %s %s'%(post_title, domain.sep_titles, domain.domain_title) + tags = '%s,%s'%(domain.domain_tags, post_tags) + + metas = '\n' + \ + '\n'%scale + \ + '\n' + \ + '\n' + \ + '\n'%visit + \ + '\n'%domain.domain_lang + \ + '\n'%domain.domain_mail + \ + '\n'%domain.domain_license + \ + '\n' + \ + '\n'%title + \ + '\n'%post_author + \ + '\n'%post_about + \ + '\n'%tags + \ + '\n'%post_date + \ + '%s\n'%title + + print(metas) + diff --git a/src/var/lib/tyto/program/wip.py b/src/var/lib/tyto/program/wip.py index 908caa4..5886ee0 100644 --- a/src/var/lib/tyto/program/wip.py +++ b/src/var/lib/tyto/program/wip.py @@ -17,7 +17,7 @@ #********************************************************************** import sys, os, re -import check, log, domain +import check, log, domain, html Post_Err = False @@ -116,6 +116,9 @@ def manage_wip(file_post, Force): print('> Article with Tabs:') tab_article(wip_html.rsplit('\n')) + # Create full page + html.html_main_page() + #============================# @@ -563,14 +566,12 @@ def wip_bruts(article): global wip_html wip_html = '' - all_vars = set(globals()) for var in all_vars: if var.startswith('brut_'): brut = globals()[var] - # Search in article lines for _image: for line in article: if not line.startswith('_brut:'): From 9d8d54d5d428002cdaf7271303f7f5a9972992bc Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Wed, 23 Nov 2022 11:54:27 +0100 Subject: [PATCH 025/247] html: progress on HTML page build --- src/var/lib/tyto/program/check.py | 14 +++-- src/var/lib/tyto/program/domain.py | 60 ++++++++++++++------- src/var/lib/tyto/program/html.py | 84 +++++++++++++++++++++++++++++- 3 files changed, 134 insertions(+), 24 deletions(-) diff --git a/src/var/lib/tyto/program/check.py b/src/var/lib/tyto/program/check.py index 07f6101..5f50d8b 100644 --- a/src/var/lib/tyto/program/check.py +++ b/src/var/lib/tyto/program/check.py @@ -55,9 +55,6 @@ def post_IDs(file_post): print(':< Unused argument file') sys.exit(1) - # Set HTML file from file_post - file_html = file_post.replace('.tyto','.html') - # Check if file exists or exit global post_uri post_uri = '%s%s'%(domain.domain_articles, file_post) @@ -65,6 +62,16 @@ def post_IDs(file_post): print(':< Unused file: %s'%post_uri) sys.exit(1) + + global post_url + # Set HTML file from file_post + file_html = file_post.replace('.tyto','.html') + if file_html.endswith('index.html'): + file_html = file_html.remplace('index.html', '') + post_url = '%s%s/%s'%( + domain.domain_protocol, domain.domain_name, file_html + ) + # From argument file_post # Set WEB link prefix. Count / in uri global weburi @@ -1172,6 +1179,7 @@ def create_DB(post_db): 'post_ID = "%s"'%curr_post_ID, 'post_db = "%s"'%post_db, 'post_tmp = "%s"'%post_tmp, + 'post_url = "%s"'%post_url, '\n# Article Status', 'post_chk = ("%s","%s")'%(hash_chk,time_chk), 'post_wip = ("%s","%s")'%(hash_wip,time_wip), diff --git a/src/var/lib/tyto/program/domain.py b/src/var/lib/tyto/program/domain.py index 6a0ecf2..48256ba 100644 --- a/src/var/lib/tyto/program/domain.py +++ b/src/var/lib/tyto/program/domain.py @@ -78,9 +78,10 @@ except: #===========================# # Append new line to a file # #---------------------------# -def append_f(f,line_val): +def append_f(f, line_val): file = open(f, "a") file.write('%s\n'%line_val) + file.close() #======================================# # Just a generic exit # @@ -107,18 +108,12 @@ def exiting(process,out,msg): #==========================#------------------------------------------- def manage_domain(Domain, Opt): if not Opt: - try: - # No option: get domain and print it - print('\n',datas_domain) - except: - sys.exit(0) + try: print('\n',datas_domain) # No option: get domain and print it + except: sys.exit(0) elif Opt == 'New': - try: - # Domain NAME is defined in CLI - set_domain = Domain - except: - set_domain = '' + try: set_domain = Domain # Domain NAME is defined in CLI + except: set_domain = '' add_domain(set_domain) @@ -133,9 +128,9 @@ def manage_domain(Domain, Opt): # Compare before and after domain conf file new_conf_ID = check.get_filesum(domain_conf,True) if not old_conf_ID == new_conf_ID: - exiting('root',2,':D Updated domain configuration file.') + exiting('root', 2, ':D Updated domain configuration file.') else: - exiting('root',2,':D Unchanged domain configuration file.') + exiting('root', 2, ':D Unchanged domain configuration file.') else: sys.exit(0) @@ -147,8 +142,7 @@ def manage_domain(Domain, Opt): #-----------------------------------#---------------------------------- def add_domain(set_domain): # Exit if a domain already exists - if domain_active: - sys.exit(0) + if domain_active: sys.exit(0) global temp_domain temp_domain = '%s/tyto_domain.tmp'%curr_dir @@ -189,6 +183,7 @@ def add_domain(set_domain): post_temp = file.read() for line in post_temp.split('\n'): print(' │ %s'%line) + file.close() # Ask to confirm to write activation domain print(' ├─────────────────────────────') @@ -196,7 +191,25 @@ def add_domain(set_domain): if confirm in ['y', 'Y']: create_domain() else: - exiting('form',1,'') + exiting('form', 1, '') + +#==============# +# Get protocol # +#--------------# +def get_protocol(set_domain): + global domain_protocol + domain_protocol = '' + + # check protocol https, http + if set_domain.startswith('https://'): domain_protocol = 'https://' + elif set_domain.startswith('http://') : domain_protocol = 'http://' + + if domain_protocol: + set_domain = set_domain.replace(domain_protocol,"") + else: + confirm = input(' ├ Use "https" ? ') + if confirm in ['y', 'Y']: domain_protocol = 'https://' + else : domain_protocol = 'http://' #==============================# # If domain name is set in CLI # @@ -204,6 +217,9 @@ def add_domain(set_domain): #------------------------------# def domain_input_confirn(set_domain): global domain_name + + get_protocol(set_domain) + confirm = input(' ├ Add Domain (%s) here ? '%set_domain) if confirm in ['y', 'Y']: # Check if domain already registred @@ -211,20 +227,25 @@ def domain_input_confirn(set_domain): if isdomain in domains_db: dom_folder = globals().get(isdomain,False) if dom_folder and not dom_folder == curr_dir: - exiting('root',2,'\n:/ Domain exists in %s'%dom_folder) + exiting('root', 2, '\n:/ Domain exists in %s'%dom_folder) domain_name = set_domain else: - exiting('root',1,'') + exiting('root', 1, '') #=====================# # Add new domain_name # #---------------------# def domain_input(): - global domain_name + global domain_name, domain_protocol set_domain = input(' ├ Enter Domain Name: ') + if not set_domain: exiting('root', 1, '') else : domain_name = set_domain + domain_protocol = '' + get_protocol(set_domain) + + #====================# # Domain FORM # # domain_name is set # @@ -241,6 +262,7 @@ def domain_form(): # Add settings from domain name before starting form append_f(temp_domain,'domain_name = "%s"'%domain_name) + append_f(temp_domain,'domain_protocol = "%s"'%domain_protocol) append_f(temp_domain,'domain_conf = "%s"'%conf_domain) append_f(temp_domain,'domain_db = "%s"'%domain_db) append_f(temp_domain,'domain_logs = "%s"'%domain_logs) diff --git a/src/var/lib/tyto/program/html.py b/src/var/lib/tyto/program/html.py index 1db253a..cd73b9d 100644 --- a/src/var/lib/tyto/program/html.py +++ b/src/var/lib/tyto/program/html.py @@ -23,10 +23,25 @@ def html_main_page(): post_db = exec(open(check.curr_post_db).read(),globals()) # Metas in HTML page + #------------------- scale = 'width=device-width, initial-scale=1.0' visit = '3 days' title = '%s %s %s'%(post_title, domain.sep_titles, domain.domain_title) tags = '%s,%s'%(domain.domain_tags, post_tags) + icon = '/template/favicon.png' + f_css = '/template/styles.css' + f_rss = '/rss.xml' + i_rss = 'RSS 2.0, %s %s %s'%( + domain.domain_title, domain.sep_titles, domain.domain_name + ) + + # External URL in metas (if exists) + if domain.domain_exturl: + relme = '\n'%( + domain.domain_exturl + ) + else: + relme = '' metas = '\n' + \ '\n'%scale + \ @@ -42,7 +57,72 @@ def html_main_page(): '\n'%post_about + \ '\n'%tags + \ '\n'%post_date + \ - '%s\n'%title + '\n'%post_url + \ + '\n'%(f_rss, i_rss) + \ + '\n'%f_css + \ + '\n'%icon + \ + '%s'%relme + \ + '%s'%title - print(metas) + # header in HTML page + #-------------------- + headers = '
\n'%domain.domain_css + \ + ' \n' + \ + '
\n' + \ + '

\n' + \ + ' %s\n'%( + domain.domain_title, + domain.sep_titles, + domain.domain_name, + domain.domain_title + ) + \ + '

\n' + \ + '

%s

\n'%domain.domain_about + \ + '
\n' + \ + '
\n' + + # Article (in section, including aside) + articles = '
\n' + \ + '
\n'%( + post_ID, domain.domain_css + ) + \ + '
\n' + \ + '

\n' + \ + ' %s\n'%(post_author, post_author) + \ + ' - \n' + \ + ' %s\n'%post_date + \ + '

\n' + \ + '
' + + # Create full page + #----------------- + page = '\n' + \ + ' \n'%domain.domain_lang + \ + ' ' + + # Add tab metas in page + for meta in metas.rsplit('\n'): + page = '%s\n%s%s'%(page, 6*' ', meta) + + page = '%s\n%s\n'%(page, 4*' ') + \ + '%s\n '%(4*' ', post_ID, domain.domain_css) + + # Add tab header in page + for header in headers.rsplit('\n'): + page = '%s\n%s%s'%(page, 6*' ', header) + + # Add tab article in page + for article in articles.rsplit('\n'): + page = '%s\n%s%s'%(page, 6*' ', article) + + print(page) From 7b38db9f37ffab585fdfe5be0404b0e9f427bd24 Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Wed, 23 Nov 2022 17:22:29 +0100 Subject: [PATCH 026/247] html: HTML page build --- src/var/lib/tyto/program/domain.py | 34 ++++++++++--- src/var/lib/tyto/program/html.py | 79 ++++++++++++++++++++++++++++-- src/var/lib/tyto/program/wip.py | 4 +- 3 files changed, 104 insertions(+), 13 deletions(-) diff --git a/src/var/lib/tyto/program/domain.py b/src/var/lib/tyto/program/domain.py index 48256ba..02366fe 100644 --- a/src/var/lib/tyto/program/domain.py +++ b/src/var/lib/tyto/program/domain.py @@ -259,10 +259,8 @@ def domain_form(): domain_articles = '%s/articles/'%curr_dir domain_images = '%simages/'%domain_articles domain_files = '%sfiles/'%domain_articles - - # Add settings from domain name before starting form - append_f(temp_domain,'domain_name = "%s"'%domain_name) - append_f(temp_domain,'domain_protocol = "%s"'%domain_protocol) + domain_url = '%s%s'%(domain_protocol, domain_name) + append_f(temp_domain,'domain_conf = "%s"'%conf_domain) append_f(temp_domain,'domain_db = "%s"'%domain_db) append_f(temp_domain,'domain_logs = "%s"'%domain_logs) @@ -282,10 +280,8 @@ def domain_form(): # Local server Directory # ---------------------- global srv - try: - srv - except: - srv = '/var/www' + try: srv + except: srv = '/var/www' set_srv = input(' ├ Local server directory (%s) ? '%srv) if not set_srv and not srv: @@ -306,6 +302,7 @@ def domain_form(): srv_www_files = '%s/%s/www/files/'%(srv,domain_name) srv_www_images = '%s/%s/www/images/'%(srv,domain_name) srv_www_template = '%s/%s/www/template/'%(srv,domain_name) + # Write settings to temp_omain append_f(temp_domain,'\n# Server directories') append_f(temp_domain,'srv = "%s"'%srv) @@ -337,6 +334,9 @@ def domain_form(): domain_title = domain_title.replace('"','\\"') append_f(temp_domain,'\n# Domain datas for web pages') + append_f(temp_domain,'domain_name = "%s"'%domain_name) + append_f(temp_domain,'domain_protocol = "%s"'%domain_protocol) + append_f(temp_domain,'domain_url = "%s"'%domain_url) append_f(temp_domain,'domain_title = "%s"'%domain_title) # Separator Pages Titles (default '-') @@ -457,6 +457,24 @@ def domain_form(): append_f(temp_domain,'domain_license = "%s"'%domain_license) + # Copyright URL + #-------------- + global domain_lic_url + + try: + domain_lic_url + show_license = domain_lic_url[:14] + '...' + except: + domain_lic_url = '' + + set_lic_url = input(' ├ Copyright URL (%s) ? '%show_license) + if not set_lic_url and not domain_lic_url: + exiting('form', 2, '\n:< Copyright URL is required.') + elif set_lic_url: + set_lic_url: domain_lic_url = set_lic_url + + append_f(temp_domain,'domain_lic_url = "%s"'%domain_lic_url) + # Sidebar Title # ------------- global sidebar_title diff --git a/src/var/lib/tyto/program/html.py b/src/var/lib/tyto/program/html.py index cd73b9d..207eff0 100644 --- a/src/var/lib/tyto/program/html.py +++ b/src/var/lib/tyto/program/html.py @@ -18,7 +18,7 @@ #********************************************************************** import check, log, domain -def html_main_page(): +def html_main_page(wip_html): # Source DB variables post_db = exec(open(check.curr_post_db).read(),globals()) @@ -91,7 +91,7 @@ def html_main_page(): '\n' # Article (in section, including aside) - articles = '
\n' + \ + articles = '
\n' + \ '
\n'%( post_ID, domain.domain_css ) + \ @@ -101,7 +101,64 @@ def html_main_page(): ' - \n' + \ ' %s\n'%post_date + \ '

\n' + \ - ' ' + ' \n' + + + # Aside after article + #-------------------- + asides = '' + + # Footer, and of page + #-------------------- + tytogen = 'https://git.a-lec.org/echolib/tyto-litterateur' + footers = '
\n' + \ + '

%s

\n'%domain.domain_title + \ + ' \n' + \ + ' \n' + \ + '
' # Create full page #----------------- @@ -124,5 +181,21 @@ def html_main_page(): for article in articles.rsplit('\n'): page = '%s\n%s%s'%(page, 6*' ', article) + # Add post from wip.html + for line in wip_html: + page = '%s\n%s%s'%(page, 4*' ', line) + page = '%s\n%s
\n'%(page, 8*' ') + + # Add latest-posts in page + #------------------------- + for aside in asides.rsplit('\n'): + page = '%s\n%s%s'%(page, 8*' ', aside) + page = '%s\n%s
'%(page, 6*' ') + + # Add footer in page + #------------------- + for footer in footers.rsplit('\n'): + page = '%s\n%s%s'%(page, 4*' ', footer) + print(page) diff --git a/src/var/lib/tyto/program/wip.py b/src/var/lib/tyto/program/wip.py index 5886ee0..f962030 100644 --- a/src/var/lib/tyto/program/wip.py +++ b/src/var/lib/tyto/program/wip.py @@ -117,7 +117,7 @@ def manage_wip(file_post, Force): tab_article(wip_html.rsplit('\n')) # Create full page - html.html_main_page() + html.html_main_page(wip_html.rsplit('\n')) @@ -783,4 +783,4 @@ def tab_article(article): if wip_tmp: wip_tmp = '%s\n%s%s'%(wip_tmp, int(tab)*' ', line) else : wip_tmp = '%s%s'%(int(tab)*' ', line) - print(wip_tmp) + wip_html = wip_tmp From c7893a29229985fae29e62cd31fe506bdc371415 Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Wed, 23 Nov 2022 17:36:53 +0100 Subject: [PATCH 027/247] html: HTML page build --- src/var/lib/tyto/program/html.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/var/lib/tyto/program/html.py b/src/var/lib/tyto/program/html.py index 207eff0..41b4202 100644 --- a/src/var/lib/tyto/program/html.py +++ b/src/var/lib/tyto/program/html.py @@ -129,30 +129,30 @@ def html_main_page(wip_html): ' \n' + \ From b3781b17d0451557b46d6294ceea455e10a6ed92 Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Wed, 23 Nov 2022 18:31:46 +0100 Subject: [PATCH 030/247] html: in-dev for translations --- src/var/lib/tyto/program/html.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/var/lib/tyto/program/html.py b/src/var/lib/tyto/program/html.py index 09f613f..4a6bfa8 100644 --- a/src/var/lib/tyto/program/html.py +++ b/src/var/lib/tyto/program/html.py @@ -23,10 +23,11 @@ trans = [ [ 'Licence', 'License' ], # 0 [ 'Générateur', 'Generator' ], # 1 [ 'À propos de', 'About' ], # 2 - [ 'Envoyer un courriel à ', 'Send a mail to' ], # 3 + [ 'Envoyer un courriel à', 'Send a mail to' ], # 3 [ 'Détails de la licence', 'License\'s details'], # 4 [ 'Courriel', 'Mail' ], # 5 - [ 'Site web généré par', 'Website generated by'] + [ 'Site web généré par', 'Website generated by'], # 6 + [ 'Syndication de', 'Syndication of' ] # 7 ] #=======================================# @@ -161,7 +162,7 @@ def html_main_page(wip_html): ' \n' + \ '\n' - + + # Article (in section, including aside) + #-------------------------------------- articles = '
\n' + \ '
\n'%( post_ID, domain.domain_css @@ -167,10 +172,10 @@ def html_main_page(wip_html): ' \n' + \ ' \n' + \ '' - + + # Footer, and of page #-------------------- - tytogen = 'https://git.a-lec.org/echolib/tyto-litterateur' footers = '
\n' + \ '

%s %s

\n'%( trans[2][fl], domain.domain_title) + \ @@ -199,22 +204,27 @@ def html_main_page(wip_html): domain.domain_license ) + \ ' \n' + \ - '
  • RSS: \n' + \ - ' \n' + \ + ' RSS: \n' + \ + ' /rss.xml\n'%( trans[7][fl], domain.domain_title ) + \ '
  • \n' + \ '
  • %s: \n'%trans[1][fl] + \ - ' Tyto - Littérateur\n'%trans[6][fl] + \ + ' %s \n'%(trans[6][fl], Tyto) + \ + ' (Code)\n'%(trans[8][fl]) + \ '
  • \n' + \ ' \n' + \ ' \n' + \ '
    ' - + + # Create file if not exists + #-------------------------- files_tpl = [ [ '%smetas.html'%domain.srv_wip_template, metas ], [ '%sheader.html'%domain.srv_wip_template, headers ], @@ -240,7 +250,9 @@ def html_main_page(wip_html): page = '%s\n%s%s'%(page, 6*' ', meta) page = '%s\n%s\n'%(page, 4*' ') + \ - '%s\n '%(4*' ', post_ID, domain.domain_css) + '\n%s'%( + 4*' ', post_ID, domain.domain_css + ) # Add tab header in page for header in headers.rsplit('\n'): @@ -266,5 +278,5 @@ def html_main_page(wip_html): for footer in footers.rsplit('\n'): page = '%s\n%s%s'%(page, 4*' ', footer) - #print(page) + print(page) From 3e3885edf6e2a761538f0a4c647ebfcbd82385c3 Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Thu, 24 Nov 2022 11:28:18 +0100 Subject: [PATCH 033/247] html: use template file else defaut --- src/var/lib/tyto/program/html.py | 50 +++++++++++++++++++++++++------- 1 file changed, 39 insertions(+), 11 deletions(-) diff --git a/src/var/lib/tyto/program/html.py b/src/var/lib/tyto/program/html.py index 74b6bfe..6cc1a0f 100644 --- a/src/var/lib/tyto/program/html.py +++ b/src/var/lib/tyto/program/html.py @@ -222,7 +222,7 @@ def html_main_page(wip_html): ' \n' + \ '' - + # Create file if not exists #-------------------------- files_tpl = [ @@ -230,6 +230,7 @@ def html_main_page(wip_html): [ '%sheader.html'%domain.srv_wip_template, headers ], [ '%sfooter.html'%domain.srv_wip_template, footers ], ] + for file_tpl in files_tpl: if not os.path.exists(file_tpl[0]): datas = open(file_tpl[0], 'w') @@ -238,31 +239,50 @@ def html_main_page(wip_html): msg_log = 'Create default file: %s'%file_tpl[0] log.append_f(check.post_logs, msg_log, 0) - - # Create full page - #----------------- + #------------------# + # Create full page # + #------------------# page = '\n' + \ ' \n'%domain.domain_lang + \ ' ' # Add tab metas in page - for meta in metas.rsplit('\n'): - page = '%s\n%s%s'%(page, 6*' ', meta) - + #---------------------- + if os.path.exists(files_tpl[0][0]): + metas_datas = open(files_tpl[0][0], 'r').read() + for meta_line in metas_datas.rsplit('\n'): + page = '%s\n%s%s'%(page, 6*' ', meta_line) + else: + # No file: use this default + for meta in metas.rsplit('\n'): + page = '%s\n%s%s'%(page, 6*' ', meta) + msg_log = 'Use default metas in page. Unused file: %s'%files_tpl[0][0] + log.append_f(check.post_logs, msg_log, 0) + page = '%s\n%s\n'%(page, 4*' ') + \ '\n%s'%( 4*' ', post_ID, domain.domain_css ) # Add tab header in page - for header in headers.rsplit('\n'): - page = '%s\n%s%s'%(page, 6*' ', header) + #----------------------- + if os.path.exists(files_tpl[1][0]): + headers_datas = open(files_tpl[1][0], 'r').read() + for header_line in headers_datas.rsplit('\n'): + page = '%s\n%s%s'%(page, 6*' ', header_line) + else: + # No file: use this default + for header in headers.rsplit('\n'): + page = '%s\n%s%s'%(page, 6*' ', header) + msg_log = 'Use default header in page. Unused file: %s'%files_tpl[1][0] + log.append_f(check.post_logs, msg_log, 0) # Add tab article in page for article in articles.rsplit('\n'): page = '%s\n%s%s'%(page, 6*' ', article) # Add post from wip.html + #----------------------- for line in wip_html: page = '%s\n%s%s'%(page, 4*' ', line) page = '%s\n%s
    \n'%(page, 8*' ') @@ -275,8 +295,16 @@ def html_main_page(wip_html): # Add footer in page #------------------- - for footer in footers.rsplit('\n'): - page = '%s\n%s%s'%(page, 4*' ', footer) + if os.path.exists(files_tpl[2][0]): + footers_datas = open(files_tpl[2][0], 'r').read() + for footer_line in footers_datas.rsplit('\n'): + page = '%s\n%s%s'%(page, 4*' ', footer_line) + else: + # No file: use this default + for footer in footers.rsplit('\n'): + page = '%s\n%s%s'%(page, 4*' ', footer) + msg_log = 'Use default footer in page. Unused file: %s'%files_tpl[2][0] + log.append_f(check.post_logs, msg_log, 0) print(page) From ecef8c10476a448da9f1cffb52c6457e6e40a1c0 Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Thu, 24 Nov 2022 12:12:10 +0100 Subject: [PATCH 034/247] html: convert date in FR + file aside.html --- src/var/lib/tyto/program/html.py | 58 ++++++++++++++++++++++---------- 1 file changed, 41 insertions(+), 17 deletions(-) diff --git a/src/var/lib/tyto/program/html.py b/src/var/lib/tyto/program/html.py index 6cc1a0f..40e98d4 100644 --- a/src/var/lib/tyto/program/html.py +++ b/src/var/lib/tyto/program/html.py @@ -23,15 +23,17 @@ Tyto = 'Tyto - Littérateur' tytogen = 'https://git.a-lec.org/echolib/tyto-litterateur' tytourl = 'https://tyto.echolib.re' trans = [ - [ 'Licence', 'License' ], # 0 - [ 'Générateur', 'Generator' ], # 1 - [ 'À propos de', 'About' ], # 2 - [ 'Envoyer un courriel à', 'Send a mail to' ], # 3 - [ 'Détails de la licence', 'License\'s details'], # 4 - [ 'Courriel', 'Mail' ], # 5 - [ 'Site web généré par %s'%Tyto, 'Website generated by %s'%Tyto ], # 6 - [ 'Syndication de', 'Syndication of' ], # 7 - [ 'Site officiel de %s'%Tyto, 'Official website of %s'%Tyto ] # 8 + [ 'Licence', 'License' ], # 0 + [ 'Générateur', 'Generator' ], # 1 + [ 'À propos de', 'About' ], # 2 + [ 'Envoyer un courriel à', 'Send a mail to' ], # 3 + [ 'Détails de la licence', 'License\'s details'], # 4 + [ 'Courriel', 'Mail' ], # 5 + [ 'Site web généré par %s'%Tyto, 'Website generated by %s'%Tyto ], # 6 + [ 'Syndication de', 'Syndication of' ], # 7 + [ 'Site officiel de %s'%Tyto, 'Official website of %s'%Tyto ], # 8 + [ 'Écrit par', 'Written by' ], # 9 + [ 'le ', 'on '] # 10 ] #=======================================# @@ -40,17 +42,25 @@ trans = [ #---------------------------------------# def translations(): global fl # fl = field lang + global post_date # Default FR/fr if re.match('fr', domain.domain_lang, re.IGNORECASE): fl = 0 else : fl = 1 + # Change date format for FR + if fl == 0: + fr_date = post_date.rsplit('-') + print(">>>>", fr_date) + post_date = fr_date[2] + '/' + fr_date[1] + '/' + fr_date[0] #========================# # Create FULL HTML5 Page # # includes wip.html # #------------------------# def html_main_page(wip_html): + global post_date + # Source DB variables post_db = exec(open(check.curr_post_db).read(),globals()) @@ -73,7 +83,7 @@ def html_main_page(wip_html): msg_log = 'Unregistred logo in configuration domain' log.append_f(check.post_logs, msg_log, 1) - # Check here for template files + # Check for template files (styles, logo...) files_uri = ( '%s%s'%(domain.srv_wip, icon[1:len(icon)]), '%s%s'%(domain.srv_wip, f_css[1:len(f_css)]), @@ -87,7 +97,7 @@ def html_main_page(wip_html): # Set some terms from lang domain translations() - # External URL in metas (if exists) + # External URL in metas (if exists in config domain) if domain.domain_exturl: relme = '\n'%( domain.domain_exturl @@ -95,6 +105,8 @@ def html_main_page(wip_html): else: relme = '' + # Metas in HTML page + #------------------- metas = '\n' + \ '\n'%scale + \ '\n' + \ @@ -144,16 +156,18 @@ def html_main_page(wip_html): '\n' - # Article (in section, including aside) + # Article (in section) #-------------------------------------- articles = '
    \n' + \ '
    \n'%( - post_ID, domain.domain_css + post_ID, domain.domain_css ) + \ '
    \n' + \ '

    \n' + \ - ' %s\n'%(post_author, post_author) + \ - ' - \n' + \ + ' %s %s\n'%( + post_author, trans[9][fl], post_author + ) + \ + ' , %s\n'%trans[10][fl] + \ ' %s\n'%post_date + \ '

    \n' + \ '
    \n' @@ -229,6 +243,7 @@ def html_main_page(wip_html): [ '%smetas.html'%domain.srv_wip_template, metas ], [ '%sheader.html'%domain.srv_wip_template, headers ], [ '%sfooter.html'%domain.srv_wip_template, footers ], + [ '%saside.html'%domain.srv_wip_template, asides ] ] for file_tpl in files_tpl: @@ -289,8 +304,17 @@ def html_main_page(wip_html): # Add latest-posts in page #------------------------- - for aside in asides.rsplit('\n'): - page = '%s\n%s%s'%(page, 8*' ', aside) + if os.path.exists(files_tpl[3][0]): + asides_datas = open(files_tpl[3][0], 'r').read() + for aside_line in asides_datas.rsplit('\n'): + page = '%s\n%s%s'%(page, 8*' ', aside_line) + else: + # No file: use this default + for aside in asides.rsplit('\n'): + page = '%s\n%s%s'%(page, 8*' ', aside) + + msg_log = 'Use default sidebar in page. Unused file: %s'%files_tpl[3][0] + log.append_f(check.post_logs, msg_log, 0) page = '%s\n%s
    '%(page, 6*' ') # Add footer in page From 8043053d74e43c0800ba83d6f29dc752348c6748 Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Thu, 24 Nov 2022 14:51:49 +0100 Subject: [PATCH 035/247] html: more titles tags in page --- src/var/lib/tyto/program/html.py | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/src/var/lib/tyto/program/html.py b/src/var/lib/tyto/program/html.py index 40e98d4..fe05a27 100644 --- a/src/var/lib/tyto/program/html.py +++ b/src/var/lib/tyto/program/html.py @@ -32,8 +32,11 @@ trans = [ [ 'Site web généré par %s'%Tyto, 'Website generated by %s'%Tyto ], # 6 [ 'Syndication de', 'Syndication of' ], # 7 [ 'Site officiel de %s'%Tyto, 'Official website of %s'%Tyto ], # 8 - [ 'Écrit par', 'Written by' ], # 9 - [ 'le ', 'on '] # 10 + [ 'Écrit par', 'Written by' ], # 9 + [ 'le ', 'on '], # 10 + [ 'Description de', 'Description of '], # 11 + [ 'sur', 'on'], # 12 + [ 'est l\'auteur de l\'article :', 'is the author of post:'] # 13 ] #=======================================# @@ -151,7 +154,15 @@ def html_main_page(wip_html): domain.domain_title ) + \ ' \n' + \ - '

    %s

    \n'%domain.domain_about + \ + '

    %s\n'%( + trans[11][fl], + domain.domain_title, + trans[12][fl], + domain.domain_url, + domain.domain_about + ) + \ + '

    \n' + \ ' \n' + \ '\n' @@ -159,13 +170,15 @@ def html_main_page(wip_html): # Article (in section) #-------------------------------------- articles = '
    \n' + \ - '
    \n'%( + '
    \n'%( post_ID, domain.domain_css - ) + \ + ) + \ '
    \n' + \ '

    \n' + \ - ' %s %s\n'%( - post_author, trans[9][fl], post_author + ' %s %s\n'%( + post_author, trans[13][fl], post_title, + trans[9][fl], post_author ) + \ ' , %s\n'%trans[10][fl] + \ ' %s\n'%post_date + \ From 4a5a741c2c9e7e1dd9679eb4f0ba18dbad6c75a5 Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Fri, 25 Nov 2022 10:45:56 +0100 Subject: [PATCH 036/247] html: little changes for RSS title et link meta --- src/var/lib/tyto/program/html.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/var/lib/tyto/program/html.py b/src/var/lib/tyto/program/html.py index fe05a27..0ccfb17 100644 --- a/src/var/lib/tyto/program/html.py +++ b/src/var/lib/tyto/program/html.py @@ -54,7 +54,6 @@ def translations(): # Change date format for FR if fl == 0: fr_date = post_date.rsplit('-') - print(">>>>", fr_date) post_date = fr_date[2] + '/' + fr_date[1] + '/' + fr_date[0] #========================# @@ -77,7 +76,7 @@ def html_main_page(wip_html): logo = '/template/%s'%domain.domain_logo f_css = '/template/styles.css' f_rss = '/rss.xml' - i_rss = 'RSS 2.0, %s %s %s'%( + i_rss = 'RSS 2.0. %s %s %s'%( domain.domain_title, domain.sep_titles, domain.domain_name ) @@ -234,9 +233,9 @@ def html_main_page(wip_html): '

  • \n' + \ ' RSS: \n' + \ ' /rss.xml\n'%( - trans[7][fl], domain.domain_title + ' type="application/rss+xml"\n' + \ + ' title="Syndication %s">/rss.xml\n'%( + i_rss ) + \ '
  • \n' + \ '
  • %s: \n'%trans[1][fl] + \ From a457c78610524deb706c18b21e827e719042db3d Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Fri, 25 Nov 2022 11:31:13 +0100 Subject: [PATCH 037/247] wip: get page from html module --- src/var/lib/tyto/program/html.py | 6 +++--- src/var/lib/tyto/program/wip.py | 14 ++++++++------ 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/var/lib/tyto/program/html.py b/src/var/lib/tyto/program/html.py index 0ccfb17..ff30536 100644 --- a/src/var/lib/tyto/program/html.py +++ b/src/var/lib/tyto/program/html.py @@ -19,6 +19,7 @@ import re, os import check, log, domain +page = '' Tyto = 'Tyto - Littérateur' tytogen = 'https://git.a-lec.org/echolib/tyto-litterateur' tytourl = 'https://tyto.echolib.re' @@ -61,7 +62,7 @@ def translations(): # includes wip.html # #------------------------# def html_main_page(wip_html): - global post_date + global post_date, page # Source DB variables post_db = exec(open(check.curr_post_db).read(),globals()) @@ -342,5 +343,4 @@ def html_main_page(wip_html): msg_log = 'Use default footer in page. Unused file: %s'%files_tpl[2][0] log.append_f(check.post_logs, msg_log, 0) - print(page) - + #print(page) diff --git a/src/var/lib/tyto/program/wip.py b/src/var/lib/tyto/program/wip.py index ac072bf..7298a57 100644 --- a/src/var/lib/tyto/program/wip.py +++ b/src/var/lib/tyto/program/wip.py @@ -110,8 +110,6 @@ def manage_wip(file_post, Force): # Get Legacy contents from base64 markers convert_all_b64(wip_html.rsplit('\n')) - #print('> Article HTML:') - #print(wip_html) #print('> Article with Tabs:') tab_article(wip_html.rsplit('\n')) @@ -119,6 +117,10 @@ def manage_wip(file_post, Force): # Create full page html.html_main_page(wip_html.rsplit('\n')) + wip_html = html.page + print('> Article HTML:') + print(wip_html) + #============================# # HTML CONVERTERS # @@ -137,10 +139,10 @@ def wip_begin_markers(wip_lines): wip_tmp = '' # Set marker (regex to find), HTML, Need CSS marks_html = [ - ['^\|$|^\|\s' , '
    ' , True ], - ['^>>\s' , '' , True ], - [r'^\($|\(\s' , '

    ' , True ], - ['^\)$|^\)\s' , '

    ' , False], + ['^\|$|^\|\s' , '
    ' , True ], + ['^>>\s' , '' , True ], + [r'^\($|\(\s' , '

    ' , True ], + ['^\)$|^\)\s' , '

    ' , False], ['^\[\[$|^\[\[\s' , '
    '          , False]
                    ]
    
    From 9f43f9a8a03f79b82835915c90214c4328d2e7e4 Mon Sep 17 00:00:00 2001
    From: Cyrille L 
    Date: Fri, 25 Nov 2022 12:06:46 +0100
    Subject: [PATCH 038/247] wip: get page from html module
    
    ---
     src/var/lib/tyto/program/html.py | 2 --
     src/var/lib/tyto/program/wip.py  | 6 ++++--
     2 files changed, 4 insertions(+), 4 deletions(-)
    
    diff --git a/src/var/lib/tyto/program/html.py b/src/var/lib/tyto/program/html.py
    index ff30536..a378285 100644
    --- a/src/var/lib/tyto/program/html.py
    +++ b/src/var/lib/tyto/program/html.py
    @@ -342,5 +342,3 @@ def html_main_page(wip_html):
           page = '%s\n%s%s'%(page, 4*' ', footer)
         msg_log = 'Use default footer in page. Unused file: %s'%files_tpl[2][0]
         log.append_f(check.post_logs, msg_log, 0)
    -  
    -  #print(page)
    diff --git a/src/var/lib/tyto/program/wip.py b/src/var/lib/tyto/program/wip.py
    index 7298a57..454d681 100644
    --- a/src/var/lib/tyto/program/wip.py
    +++ b/src/var/lib/tyto/program/wip.py
    @@ -118,8 +118,10 @@ def manage_wip(file_post, Force):
       html.html_main_page(wip_html.rsplit('\n'))
       
       wip_html = html.page
    -  print('> Article HTML:')
    -  print(wip_html)
    +  print('> Article HTML:\n', wip_html)
    +
    +  print(">", file_post)
    +  
       
     
     #============================#
    
    From 0560c4665c9b0cac668d3d301300e53fb04cd7fe Mon Sep 17 00:00:00 2001
    From: Cyrille L 
    Date: Fri, 25 Nov 2022 17:09:37 +0100
    Subject: [PATCH 039/247] check: fixed for empty markers in header post
    
    ---
     src/var/lib/tyto/program/check.py | 62 +++++++++++++++++++++++--------
     src/var/lib/tyto/program/wip.py   | 10 ++++-
     2 files changed, 56 insertions(+), 16 deletions(-)
    
    diff --git a/src/var/lib/tyto/program/check.py b/src/var/lib/tyto/program/check.py
    index 8f79bcc..4027cb3 100644
    --- a/src/var/lib/tyto/program/check.py
    +++ b/src/var/lib/tyto/program/check.py
    @@ -553,11 +553,20 @@ def check_files(line, ln, stats_files_uniq):
       global stats_files_p
     
       # Create variable array
    +  try:    file_name = line.split('file:')[1].lstrip()
    +  except: file_name = ''
    +  try:    file_uri  = headers.rsplit('\n')[ln].lstrip()
    +  except: file_uri  = ''
    +  try:    file_alt  = headers.rsplit('\n')[ln+1].lstrip()
    +  except: file_alt  = ''
    +  
    +  if not file_name:
    +    msg_log = 'Line %s. Unused NAME for marker "image:"'%ln
    +    log.append_f(post_logs,msg_log,1)
    +    Post_Err = True
    +    return(1)
    +  
       file_nbr  = 'file_%s'%stats_files_uniq
    -  file_name = line.split('file:')[1].lstrip()
    -  file_uri  = headers.rsplit('\n')[ln].lstrip()
    -  file_alt  = headers.rsplit('\n')[ln+1].lstrip()
    -
       # Check 2nd line
       check_new_marker(file_uri)
       if new_marker: file_uri = ''
    @@ -639,11 +648,20 @@ def check_bruts(line, ln, stats_files_uniq):
       global stats_bruts_p
       
       # Create variable array
    -  brut_nbr  = 'brut_%s'%stats_bruts_uniq
    -  brut_name = line.split('brut:')[1].lstrip().rsplit(' ')[0]
    -  brut_uri  = headers.rsplit('\n')[ln].lstrip()
    -  brut_alt  = headers.rsplit('\n')[ln+1].lstrip()
    +  try:    brut_name = line.split('brut:')[1].lstrip().rsplit(' ')[0]
    +  except: brut_name = ''
    +  try:    brut_uri  = headers.rsplit('\n')[ln].lstrip()
    +  except: brut_uri  = ''
    +  try:    brut_alt  = headers.rsplit('\n')[ln+1].lstrip()
    +  except: brut_alt  = ''
     
    +  if not brut_name:
    +    msg_log = 'Line %s. Unused NAME for marker "brut:"'%ln
    +    log.append_f(post_logs,msg_log,1)
    +    Post_Err = True
    +    return(1)
    +
    +  brut_nbr  = 'brut_%s'%stats_bruts_uniq
       # Check 2nd line
       check_new_marker(brut_uri)
       if new_marker: brut_uri = ''
    @@ -725,11 +743,21 @@ def check_images(line, ln, stats_images_uniq):
       global stats_images_p
       
       # Create variable array
    -  image_nbr  = 'image_%s'%stats_images_uniq
    -  image_name = line.split('image:')[1].lstrip().rsplit(' ')[0]
    -  image_uri  = headers.rsplit('\n')[ln].lstrip()
    -  image_alt  = headers.rsplit('\n')[ln+1].lstrip()
    +  
    +  try:    image_name = line.split('image:')[1].lstrip().rsplit(' ')[0]
    +  except: image_name = ''
    +  try:    image_uri  = headers.rsplit('\n')[ln].lstrip()
    +  except: image_uri  = ''
    +  try:    image_alt  = headers.rsplit('\n')[ln+1].lstrip()
    +  except: image_alt  = ''
     
    +  if not image_name:
    +    msg_log = 'Line %s. Unused NAME for marker "image:"'%ln
    +    log.append_f(post_logs,msg_log,1)
    +    Post_Err = True
    +    return(1)
    +    
    +  image_nbr  = 'image_%s'%stats_images_uniq
       # Check 2nd line
       check_new_marker(image_uri)
       if new_marker: image_uri = ''
    @@ -811,15 +839,19 @@ def check_abbrs(line, ln, stats_abbrs_uniq):
       global stats_abbrs_p
       
       # Create variable array
    -  abbr_name = line.split('abbr:')[1].lstrip()
    -  abbr_alt  = headers.rsplit('\n')[ln].lstrip()
    -  abbr_rep  = headers.rsplit('\n')[ln+1].lstrip()
    +  try:    abbr_name = line.split('abbr:')[1].lstrip()
    +  except: abbr_name = ''
    +  try:    abbr_alt  = headers.rsplit('\n')[ln].lstrip()
    +  except: abbr_alt  = ''
    +  try:    abbr_rep  = headers.rsplit('\n')[ln+1].lstrip()
    +  except: abbr_rep  = ''
     
       # Set/Check values to check in header
       if not abbr_name:
         msg_log = 'Line %s. Unused NAME for marker "abbr:"'%ln
         log.append_f(post_logs,msg_log,1)
         Post_Err = True
    +    return(1)
       elif abbr_name.isupper() is False:
         msg_log = 'Line %s. NAME not in CAPITAL for marker "abbr:"'%ln
         log.append_f(post_logs,msg_log,1)
    diff --git a/src/var/lib/tyto/program/wip.py b/src/var/lib/tyto/program/wip.py
    index 454d681..6dbcb83 100644
    --- a/src/var/lib/tyto/program/wip.py
    +++ b/src/var/lib/tyto/program/wip.py
    @@ -120,8 +120,16 @@ def manage_wip(file_post, Force):
       wip_html = html.page
       print('> Article HTML:\n', wip_html)
     
    -  print(">", file_post)
    +  # Create file to wip srv (replace file, if exists)
    +  wip_file = '%s%s'%(domain.srv_wip, file_post.replace('.tyto','.html'))
    +  if os.path.exists(wip_file):
    +    os.remove(wip_file)
       
    +  page_file = open(wip_file, 'w')
    +  page_file.write(wip_html)
    +  page_file.close()
    +
    +
       
     
     #============================#
    
    From a2045a62ba5cc4c5193c1766e189229defe32b31 Mon Sep 17 00:00:00 2001
    From: Cyrille L 
    Date: Fri, 25 Nov 2022 17:33:54 +0100
    Subject: [PATCH 040/247] check: fixed for empty markers in header post
    
    ---
     src/var/lib/tyto/program/check.py | 21 +++++++++++++++------
     1 file changed, 15 insertions(+), 6 deletions(-)
    
    diff --git a/src/var/lib/tyto/program/check.py b/src/var/lib/tyto/program/check.py
    index 4027cb3..8a7cfd3 100644
    --- a/src/var/lib/tyto/program/check.py
    +++ b/src/var/lib/tyto/program/check.py
    @@ -419,6 +419,7 @@ def if_mandat_marker(marker, m_in):
                    m_in[1], marker
                    )
         log.append_f(post_logs, msg_log, 1)
    +    Post_Err = True
     
     #================================#
     # Check Date format and validity #
    @@ -499,12 +500,21 @@ def check_links(line, ln, stats_links_uniq):
       global Post_Err, stats_links_p
     
       # Create variable array
    +  try:    link_name = line.split('link:')[1].lstrip()
    +  except: link_name = ''
    +  try:    link_url  = headers.rsplit('\n')[ln].lstrip()
    +  except: link_url  = ''
    +  try:    link_alt  = headers.rsplit('\n')[ln+1].lstrip()
    +  except: link_alt  = ''
    +
    +  if not link_name:
    +    msg_log = 'Line %s. Unused NAME for marker "link:"'%ln
    +    log.append_f(post_logs,msg_log,1)
    +    Post_Err = True
    +    return(1)
    +
       link_nbr  = 'link_%s'%stats_links_uniq
    -  link_name = line.split('link:')[1].lstrip()
    -  link_url  = headers.rsplit('\n')[ln].lstrip()
    -  link_alt  = headers.rsplit('\n')[ln+1].lstrip()
    -  
    -   # Check 2nd line
    +  # Check 2nd line
       check_new_marker(link_url)
       if new_marker: link_url = ''
     
    @@ -530,7 +540,6 @@ def check_links(line, ln, stats_links_uniq):
         log.append_f(post_logs,msg_log,1)
         Post_Err = True
         
    -    
       if Post_Err: return
       # Set final marker_N
       link = (
    
    From 6c0486cd0a195a26bea211b6b00d070beeb7b13d Mon Sep 17 00:00:00 2001
    From: Cyrille L 
    Date: Fri, 25 Nov 2022 17:40:37 +0100
    Subject: [PATCH 041/247] check: fixed for empty markers in header post
    
    ---
     src/var/lib/tyto/program/wip.py | 4 +++-
     1 file changed, 3 insertions(+), 1 deletion(-)
    
    diff --git a/src/var/lib/tyto/program/wip.py b/src/var/lib/tyto/program/wip.py
    index 6dbcb83..9374386 100644
    --- a/src/var/lib/tyto/program/wip.py
    +++ b/src/var/lib/tyto/program/wip.py
    @@ -128,7 +128,9 @@ def manage_wip(file_post, Force):
       page_file = open(wip_file, 'w')
       page_file.write(wip_html)
       page_file.close()
    -
    +  
    +  time_wip = log.nowdate()
    +  print("T",time_wip)
     
       
     
    
    From 9b24821e470fdd064a002e2a842bdd271c001638 Mon Sep 17 00:00:00 2001
    From: Cyrille L 
    Date: Fri, 25 Nov 2022 18:37:32 +0100
    Subject: [PATCH 042/247] check: fix global post_url
    
    ---
     src/var/lib/tyto/program/check.py | 7 +++++--
     src/var/lib/tyto/program/wip.py   | 9 +++++++--
     2 files changed, 12 insertions(+), 4 deletions(-)
    
    diff --git a/src/var/lib/tyto/program/check.py b/src/var/lib/tyto/program/check.py
    index 8a7cfd3..a8164c6 100644
    --- a/src/var/lib/tyto/program/check.py
    +++ b/src/var/lib/tyto/program/check.py
    @@ -67,6 +67,9 @@ def post_IDs(file_post):
       file_html = file_post.replace('.tyto','.html')
       if file_html.endswith('index.html'):
         file_html = file_html.remplace('index.html', '')
    +
    +  # Complete URL post file
    +  global post_url
       post_url = '%s%s/%s'%(
                   domain.domain_protocol, domain.domain_name, file_html
                   )
    @@ -88,11 +91,11 @@ def post_IDs(file_post):
       
       # Get Hash from article's content
       global hash_chk
    -  hash_chk = get_filesum(post_uri,True)
    +  hash_chk = get_filesum(post_uri, True)
       
       # Get Hash ID from URI
       global curr_post_ID, curr_post_db, post_logs
    -  curr_post_ID  = get_filesum(post_uri,False)
    +  curr_post_ID  = get_filesum(post_uri, False)
       
       # Set database file for this article
       curr_post_db  = '%s%s.conf'%(domain.domain_db, curr_post_ID)
    diff --git a/src/var/lib/tyto/program/wip.py b/src/var/lib/tyto/program/wip.py
    index 9374386..cc76e05 100644
    --- a/src/var/lib/tyto/program/wip.py
    +++ b/src/var/lib/tyto/program/wip.py
    @@ -129,10 +129,15 @@ def manage_wip(file_post, Force):
       page_file.write(wip_html)
       page_file.close()
       
    +  post_uri = '%s%s'%(domain.domain_articles, file_post)
       time_wip = log.nowdate()
    -  print("T",time_wip)
    -
    +  hash_wip = check.get_filesum(post_uri, True)
       
    +  rep_post_wip = 'post_wip = %s'%str(check.post_wip)
    +  tmp_post_wip = ('"%s"'%hash_wip, '"%s"'%time_wip)
    +  post_wip = 'post_wip = %s'%str(tmp_post_wip)
    +  print(rep_post_wip, '>>', post_wip)
    +
     
     #============================#
     # HTML CONVERTERS            #
    
    From 442d4c6c444364d22ea1ac3bc1bfbcc59b0bf4fc Mon Sep 17 00:00:00 2001
    From: Cyrille L 
    Date: Fri, 25 Nov 2022 18:57:38 +0100
    Subject: [PATCH 043/247] check + wip: fix db + replace post_wip to db
    
    ---
     src/var/lib/tyto/program/check.py |  6 +++---
     src/var/lib/tyto/program/wip.py   | 11 +++++++++--
     2 files changed, 12 insertions(+), 5 deletions(-)
    
    diff --git a/src/var/lib/tyto/program/check.py b/src/var/lib/tyto/program/check.py
    index a8164c6..2783c30 100644
    --- a/src/var/lib/tyto/program/check.py
    +++ b/src/var/lib/tyto/program/check.py
    @@ -1224,9 +1224,9 @@ def create_DB(post_db):
                     'post_tmp  = "%s"'%post_tmp,
                     'post_url  = "%s"'%post_url,
                     '\n# Article Status',
    -                'post_chk = ("%s","%s")'%(hash_chk,time_chk),
    -                'post_wip = ("%s","%s")'%(hash_wip,time_wip),
    -                'post_www = ("%s","%s")'%(hash_www,time_www),
    +                'post_chk = (\'%s\', \'%s\')'%(hash_chk,time_chk),
    +                'post_wip = (\'%s\', \'%s\')'%(hash_wip,time_wip),
    +                'post_www = (\'%s\', \'%s\')'%(hash_www,time_www),
                     '\n# Mandatory Headers',
                     'post_title  = "%s"'%title[2],
                     'post_about  = "%s"'%about[2],
    diff --git a/src/var/lib/tyto/program/wip.py b/src/var/lib/tyto/program/wip.py
    index cc76e05..c58ba28 100644
    --- a/src/var/lib/tyto/program/wip.py
    +++ b/src/var/lib/tyto/program/wip.py
    @@ -133,11 +133,18 @@ def manage_wip(file_post, Force):
       time_wip = log.nowdate()
       hash_wip = check.get_filesum(post_uri, True)
       
    -  rep_post_wip = 'post_wip = %s'%str(check.post_wip)
    -  tmp_post_wip = ('"%s"'%hash_wip, '"%s"'%time_wip)
    +  rep_post_wip = 'post_wip = (\'%s\', \'%s\')'%(
    +                  check.post_wip[0], check.post_wip[1])
    +  tmp_post_wip = (hash_wip, time_wip)
       post_wip = 'post_wip = %s'%str(tmp_post_wip)
       print(rep_post_wip, '>>', post_wip)
     
    +  with open(check.post_db, 'r') as file:
    +    filedata = file.read()
    +    filedata = filedata.replace(rep_post_wip, post_wip)
    +  with open(check.post_db, 'w') as file:
    +    file.write(filedata)
    +
     
     #============================#
     # HTML CONVERTERS            #
    
    From 3fbbfdfc1a3ba7eccba72b06f6896265f969b121 Mon Sep 17 00:00:00 2001
    From: Cyrille L 
    Date: Fri, 25 Nov 2022 19:05:59 +0100
    Subject: [PATCH 044/247] wip: add log when database is edited
    
    ---
     src/var/lib/tyto/program/check.py | 2 +-
     src/var/lib/tyto/program/wip.py   | 5 ++++-
     2 files changed, 5 insertions(+), 2 deletions(-)
    
    diff --git a/src/var/lib/tyto/program/check.py b/src/var/lib/tyto/program/check.py
    index 2783c30..8353657 100644
    --- a/src/var/lib/tyto/program/check.py
    +++ b/src/var/lib/tyto/program/check.py
    @@ -1211,7 +1211,7 @@ def create_DB(post_db):
     
       # log
       msg_log = 'Create Database: %s'%post_db
    -  log.append_f(post_logs,msg_log,0)
    +  log.append_f(post_logs, msg_log, 0)
     
       # Main Post Conf
       lines_conf = (
    diff --git a/src/var/lib/tyto/program/wip.py b/src/var/lib/tyto/program/wip.py
    index c58ba28..e684bb0 100644
    --- a/src/var/lib/tyto/program/wip.py
    +++ b/src/var/lib/tyto/program/wip.py
    @@ -137,13 +137,16 @@ def manage_wip(file_post, Force):
                       check.post_wip[0], check.post_wip[1])
       tmp_post_wip = (hash_wip, time_wip)
       post_wip = 'post_wip = %s'%str(tmp_post_wip)
    -  print(rep_post_wip, '>>', post_wip)
     
    +  # Replace post_wip in DB
       with open(check.post_db, 'r') as file:
         filedata = file.read()
         filedata = filedata.replace(rep_post_wip, post_wip)
       with open(check.post_db, 'w') as file:
         file.write(filedata)
    +  # log
    +  msg_log = 'Edit Database: %s'%check.post_db
    +  log.append_f(check.post_logs, msg_log, 0)
     
     
     #============================#
    
    From 1b8a6b1d0c624ca23b6102be358b1f8a09fa5f04 Mon Sep 17 00:00:00 2001
    From: Cyrille L 
    Date: Sat, 26 Nov 2022 12:34:59 +0100
    Subject: [PATCH 045/247] readme: update for simple doc
    
    ---
     README.md | 144 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
     1 file changed, 144 insertions(+)
    
    diff --git a/README.md b/README.md
    index eae71ee..2f6b149 100644
    --- a/README.md
    +++ b/README.md
    @@ -2,4 +2,148 @@
     
     ## Répertoire de code du projet Tyto
     
    +## Comment définir les métas
    +```
    +# Obligatoires uniques
    +title:  Titre
    +about:  Infos de l'article
    +author: Autheur
    +tags:   mots-clé-1,mots-clé-2
    +date:   YYYY-MM-DD (AAAA-MM-JJ)
     
    +# Optionnels myltiples
    +link:   Nom du lien
    +        URL
    +        Texte Alternatif
    +
    +image:  Nom
    +        URI
    +        Texte Alternatif
    +
    +file:   Nom du lien
    +        URL
    +        Texte Alternatif
    +
    +brut:   Nom
    +        URI
    +        Texte Alternatif
    +
    +abbr:   NOM (en majuscule)
    +        Définition du NOM
    +        nom (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
    +### Titre h1 à h6
    +```
    +#1 Titre 1
    +(
    +Un paragraphe
    +)
    +
    +#2 Titre 2
    +```
    +### 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
    +-)
    +```
    +
    +### 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
    +```
    +>> id
    +(
    +un long paragraphe
    +)
    +(
    +>_ID:Retourner au point d'ancre_<
    +)
    +```
    +
    +### Lien vers URL
    +```
    +Voir ce _Nom du lien
    +```
    +
    +### Lien vers fichier
    +```
    +Voir ce __Nom du lien
    +```
    +
    +### Gras, Strong, italique...
    +```
    +*_très gras_* >>> 
    ++_gras léger_+ >>> 
    +/_en italique_/ >>> 
    +\_en italique_\ >>> 
    +~_texte barré_~ >>> 
    +<_Code_> ou (_Code_) >>> 
    +=_Citation rapide_= >>> 
    +×_Classe personnalisée_× >>> 
    +-_Souligné_- >>>  
    +
    +```
    +
    +### Abréviations
    +```
    +# NOM sera remplacé par nom si défini en entête
    +# nom
    +Avec ce NOM.
    +```
    +
    +### Images
    +```
    +_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://...
    +```
    +
    +### Code Brut depuis un fichier
    +```
    +_brut:NOM
    +```
    
    From 8fccbeee256f75441b15e80d1ce944f8da548981 Mon Sep 17 00:00:00 2001
    From: Cyrille L 
    Date: Sat, 26 Nov 2022 12:45:46 +0100
    Subject: [PATCH 046/247] readme: update for simple doc
    
    ---
     README.md | 11 ++++++++++-
     1 file changed, 10 insertions(+), 1 deletion(-)
    
    diff --git a/README.md b/README.md
    index 2f6b149..d80c415 100644
    --- a/README.md
    +++ b/README.md
    @@ -98,10 +98,15 @@ Citation simple sans référence
     un long paragraphe
     )
     (
    ->_ID:Retourner au point d'ancre_<
    +>_id:Retourner au point d'ancre_<
     )
     ```
     
    +### Retour à la ligne HTML
    +```
    +| >>> 
    +``` + ### Lien vers URL ``` Voir ce _Nom du lien @@ -135,12 +140,16 @@ Avec ce NOM. ### Images ``` +# Chaque image doit être placée en début de ligne +# Placer en paragraphe pour chaque ou après "|" sinon, +# affichage les une à côté des autres _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://... +_image:NOM c=CSS t=https:// w=320px h=240 ``` ### Code Brut depuis un fichier From 570ed1973acb10b84248d8433dd9b836cdac8f15 Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Mon, 28 Nov 2022 11:46:39 +0100 Subject: [PATCH 047/247] domain: local db goes to USER .local folder --- src/var/lib/tyto/program/domain.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/var/lib/tyto/program/domain.py b/src/var/lib/tyto/program/domain.py index 02366fe..645e20c 100644 --- a/src/var/lib/tyto/program/domain.py +++ b/src/var/lib/tyto/program/domain.py @@ -22,9 +22,12 @@ #======# import sys, os, subprocess, datetime import check, log - + +# Get user dir +home_dir = os.path.expanduser('~') + # In Tyto DB dir -tyto_db = '/var/lib/tyto/db/' +tyto_db = '%s/.local/tyto'%home_dir tyto_domains = '%sdomains.conf'%tyto_db # In Tyto log dir @@ -279,7 +282,9 @@ def domain_form(): # Local server Directory # ---------------------- - global srv + global srv, srv_wip, srv_wip_files, srv_wip_images, srv_wip_template + global srv_www, srv_www_files, srv_www_images, srv_wip_template + try: srv except: srv = '/var/www' From 2ce6e0d4a53272ea84d2859bc9d8d476fc799fb4 Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Mon, 28 Nov 2022 12:10:22 +0100 Subject: [PATCH 048/247] html: little changes in classes, IDs name --- src/var/lib/tyto/program/html.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/var/lib/tyto/program/html.py b/src/var/lib/tyto/program/html.py index a378285..e163de0 100644 --- a/src/var/lib/tyto/program/html.py +++ b/src/var/lib/tyto/program/html.py @@ -137,7 +137,7 @@ def html_main_page(wip_html): headers = '
    \n'%domain.domain_css + \ '
    \n' + \ ' \n' + \ - ' \n'%domain.domain_title + \ @@ -207,9 +207,9 @@ def html_main_page(wip_html): '

    %s %s

    \n'%( trans[2][fl], domain.domain_title) + \ ' \n' + \ - '
    \n' @@ -215,7 +215,7 @@ def html_main_page(wip_html): '
      \n' + \ '
    • URL:\n' + \ ' \n' + \ + ' href="/"\n' + \ ' title="%s">%s\n'%( domain.domain_title, domain.domain_url ) + \ @@ -255,10 +255,8 @@ def html_main_page(wip_html): # Create file if not exists #-------------------------- files_tpl = [ - [ '%smetas.html'%domain.srv_wip_template, metas ], [ '%sheader.html'%domain.srv_wip_template, headers ], - [ '%sfooter.html'%domain.srv_wip_template, footers ], - [ '%saside.html'%domain.srv_wip_template, asides ] + [ '%sfooter.html'%domain.srv_wip_template, footers ] ] for file_tpl in files_tpl: @@ -278,16 +276,9 @@ def html_main_page(wip_html): # Add tab metas in page #---------------------- - if os.path.exists(files_tpl[0][0]): - metas_datas = open(files_tpl[0][0], 'r').read() - for meta_line in metas_datas.rsplit('\n'): - page = '%s\n%s%s'%(page, 6*' ', meta_line) - else: - # No file: use this default - for meta in metas.rsplit('\n'): - page = '%s\n%s%s'%(page, 6*' ', meta) - msg_log = 'Use default metas in page. Unused file: %s'%files_tpl[0][0] - log.append_f(check.post_logs, msg_log, 0) + # No file: use this default + for meta in metas.rsplit('\n'): + page = '%s\n%s%s'%(page, 6*' ', meta) page = '%s\n%s\n'%(page, 4*' ') + \ '\n%s'%( @@ -296,15 +287,16 @@ def html_main_page(wip_html): # Add tab header in page #----------------------- - if os.path.exists(files_tpl[1][0]): - headers_datas = open(files_tpl[1][0], 'r').read() + if os.path.exists(files_tpl[0][0]): + headers_datas = open(files_tpl[0][0], 'r').read() for header_line in headers_datas.rsplit('\n'): page = '%s\n%s%s'%(page, 6*' ', header_line) else: # No file: use this default for header in headers.rsplit('\n'): page = '%s\n%s%s'%(page, 6*' ', header) - msg_log = 'Use default header in page. Unused file: %s'%files_tpl[1][0] + + msg_log = 'Use default header in page. Unused file: %s'%files_tpl[0][0] log.append_f(check.post_logs, msg_log, 0) # Add tab article in page @@ -319,28 +311,21 @@ def html_main_page(wip_html): # Add latest-posts in page #------------------------- - if os.path.exists(files_tpl[3][0]): - asides_datas = open(files_tpl[3][0], 'r').read() - for aside_line in asides_datas.rsplit('\n'): - page = '%s\n%s%s'%(page, 8*' ', aside_line) - else: - # No file: use this default - for aside in asides.rsplit('\n'): - page = '%s\n%s%s'%(page, 8*' ', aside) - - msg_log = 'Use default sidebar in page. Unused file: %s'%files_tpl[3][0] - log.append_f(check.post_logs, msg_log, 0) + # No file: use this default + for aside in asides.rsplit('\n'): + page = '%s\n%s%s'%(page, 8*' ', aside) + page = '%s\n%s
  • '%(page, 6*' ') # Add footer in page #------------------- - if os.path.exists(files_tpl[2][0]): - footers_datas = open(files_tpl[2][0], 'r').read() + if os.path.exists(files_tpl[1][0]): + footers_datas = open(files_tpl[1][0], 'r').read() for footer_line in footers_datas.rsplit('\n'): page = '%s\n%s%s'%(page, 4*' ', footer_line) else: # No file: use this default for footer in footers.rsplit('\n'): page = '%s\n%s%s'%(page, 4*' ', footer) - msg_log = 'Use default footer in page. Unused file: %s'%files_tpl[2][0] + msg_log = 'Use default footer in page. Unused file: %s'%files_tpl[1][0] log.append_f(check.post_logs, msg_log, 0) diff --git a/src/var/lib/tyto/program/wip.py b/src/var/lib/tyto/program/wip.py index 60d03ec..69030fc 100644 --- a/src/var/lib/tyto/program/wip.py +++ b/src/var/lib/tyto/program/wip.py @@ -178,8 +178,8 @@ def wip_begin_markers(wip_lines): ['^>>\s' , '' , True ], [r'^\($|\(\s' , '

    ' , True ], ['^\)$|^\)\s' , '

    ' , False], - ['^\[\[$|^\[\[\s' , '
    ', True ],
    -                ['^\]\]$|^\]\]\s'   , '
    ' , False] + ['^\[\[$|^\[\[\s' , '',True ], + ['^\]\]$|^\]\]\s' , '' , False] ] for line in wip_lines: @@ -624,10 +624,9 @@ def wip_bruts(article): # Convert each lines to HTML, add to string for ln, bline in enumerate(brut_datas.rsplit('\n'), 1): - brut_line_html = '' + \ - '%s'%ln + \ - '%s'%bline + \ - '' + brut_line_html = '
    %s
    '%( + ln, bline, bline + ) if brut_html: brut_html = '%s\n%s'%(brut_html,brut_line_html) else : brut_html = brut_line_html @@ -635,9 +634,9 @@ def wip_bruts(article): get_css(line) # Add first and last HTML tags to string - brut_html = '
    \n'%(
    +          brut_html = '\n'%(
                            css_set, brut[2]) + \
    -                      '%s\n
    '%brut_html + '%s\n'%brut_html # Replace line if wip_html: wip_html = '%s\n%s'%(wip_html, brut_html) @@ -680,10 +679,9 @@ def convert_bcodes(article, fm, lm, css): if bCode: bCode_ln += 1 - line = '' + \ - '%s'%bCode_ln + \ - '%s'%line + \ - '' + line = '
    %s
    '%( + bCode_ln, line, line + ) if bCode_lines: bCode_lines = '%s\n%s'%(bCode_lines, line) else : bCode_lines = line else: From bc1dddf1cb873f4dd3c35ad0c7e1df4a70bb8d88 Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Sun, 4 Dec 2022 17:21:22 +0100 Subject: [PATCH 060/247] html: fixes in footer --- src/var/lib/tyto/program/html.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/var/lib/tyto/program/html.py b/src/var/lib/tyto/program/html.py index 32d538d..138d257 100644 --- a/src/var/lib/tyto/program/html.py +++ b/src/var/lib/tyto/program/html.py @@ -33,7 +33,7 @@ trans = [ [ 'Courriel', 'Mail' ], # 5 [ 'Site web généré par %s'%Tyto, 'Website generated by %s'%Tyto ], # 6 [ 'Syndication de', 'Syndication of' ], # 7 - [ 'Site officiel de %s'%Tyto, 'Official website of %s'%Tyto ], # 8 + [ 'Dépôt officiel de %s'%Tyto, 'Official repository of %s'%Tyto ], # 8 [ 'Écrit par', 'Written by' ], # 9 [ 'le ', 'on '], # 10 [ 'Description de', 'Description of '], # 11 From 53c1fc5dcfc7893793b38db1c70a7bc0acdb5375 Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Mon, 5 Dec 2022 10:44:57 +0100 Subject: [PATCH 061/247] check, wip: image copy --- src/var/lib/tyto/program/check.py | 10 +++++++--- src/var/lib/tyto/program/wip.py | 25 ++++++++++++++++++------- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/src/var/lib/tyto/program/check.py b/src/var/lib/tyto/program/check.py index c68f163..b7c467b 100644 --- a/src/var/lib/tyto/program/check.py +++ b/src/var/lib/tyto/program/check.py @@ -76,7 +76,10 @@ def post_IDs(file_post): post_url = '%s%s/%s'%( domain.domain_protocol, domain.domain_name, file_html ) - + + global post_dir + post_dir = file_post.replace(os.path.basename(file_post), '') + # From argument file_post # Set WEB link prefix. Count / in uri global weburi @@ -824,9 +827,9 @@ def check_images(line, ln, stats_images_uniq): # Current or custom URI else: - usr_file = '%s%s'%(domain.domain_articles,image_uri) + usr_file = '%s%s%s'%(domain.domain_articles, post_dir, image_uri) if not os.path.exists(usr_file): - msg_log = 'Unused file for marker "file:" in %s'%usr_file + msg_log = 'Unused file for marker "image:" in %s'%usr_file log.append_f(post_logs, msg_log, 1) Post_Err = True @@ -1225,6 +1228,7 @@ def create_DB(post_db): 'post_ID = "%s"'%curr_post_ID, 'post_db = "%s"'%post_db, 'post_tmp = "%s"'%post_tmp, + 'post_dir = "%s"'%post_dir, 'post_url = "%s"'%post_url, 'post_srv = "%s"'%post_srv, 'web_uri = "%s"'%weburi, diff --git a/src/var/lib/tyto/program/wip.py b/src/var/lib/tyto/program/wip.py index 69030fc..be5e537 100644 --- a/src/var/lib/tyto/program/wip.py +++ b/src/var/lib/tyto/program/wip.py @@ -16,7 +16,7 @@ #---------------------------------------------------------------------- #********************************************************************** -import sys, os, re +import sys, os, re, shutil import check, log, domain, html, rss Post_Err = False @@ -121,22 +121,21 @@ def manage_wip(file_post, Force): print('> Article HTML:\n', wip_html) # Create file to wip srv (replace file, if exists) - wip_file = file_post.replace('.tyto','.html') - wip_uri = '%s%s'%(domain.srv_wip, wip_file) - wip_dir = wip_uri.replace(os.path.basename(wip_uri), '') + wip_file = '%s%s'%(domain.srv_wip, check.post_srv) if os.path.exists(wip_file): os.remove(wip_file) # Create sub folder if needed + wip_dir = '%s%s'%(domain.srv_wip, check.post_dir) os.makedirs(wip_dir, exist_ok=True) - page_file = open(wip_uri, 'w') + + page_file = open(wip_file, 'w') page_file.write(wip_html) page_file.close() - post_uri = '%s%s'%(domain.domain_articles, file_post) time_wip = log.nowdate() - hash_wip = check.get_filesum(post_uri, True) + hash_wip = check.get_filesum(check.post_file, True) rep_post_wip = 'post_wip = (\'%s\', \'%s\')'%( check.post_wip[0], check.post_wip[1]) @@ -527,6 +526,18 @@ def wip_images(article): if var.startswith('image_'): image = globals()[var] + # Copy file in wip + image_src = '%s%s%s'%( + domain.domain_articles, check.post_dir, image[1] + ) + image_dst = '%s%s%s'%( + domain.srv_wip, check.post_dir, image[1] + ) + shutil.copy2(image_src, image_dst) + # log + msg_log = 'Wip > Image: %s > %s'%(image_src, image_dst) + log.append_f(check.post_logs, msg_log, 0) + # Search in article lines for _image: for line in article.rsplit('\n'): if not line.startswith('_image:'): From ba0e0e826d0b134573b057e8779fc1d06c66864a Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Thu, 15 Dec 2022 12:44:24 +0100 Subject: [PATCH 062/247] New cleaned code --- FR_Installation.md | 21 - README.md | 57 +- src/usr/{local => }/bin/tyto | 0 src/var/lib/tyto/help/CHANGELOG.md | 16 - src/var/lib/tyto/help/FR_Installation.md | 21 - src/var/lib/tyto/help/LICENSE | 661 -------- src/var/lib/tyto/help/README.md | 180 --- src/var/lib/tyto/program/check.py | 1771 +++++++--------------- src/var/lib/tyto/program/domain.py | 840 +++++----- src/var/lib/tyto/program/html.py | 331 ---- src/var/lib/tyto/program/log.py | 81 - src/var/lib/tyto/program/publish.py | 9 - src/var/lib/tyto/program/rss.py | 102 -- src/var/lib/tyto/program/sidebar.py | 199 +-- src/var/lib/tyto/program/tyto.py | 403 +++++ src/var/lib/tyto/program/wip.old.py | 412 ----- src/var/lib/tyto/program/wip.py | 850 +---------- 17 files changed, 1371 insertions(+), 4583 deletions(-) delete mode 100644 FR_Installation.md rename src/usr/{local => }/bin/tyto (100%) delete mode 100644 src/var/lib/tyto/help/CHANGELOG.md delete mode 100644 src/var/lib/tyto/help/FR_Installation.md delete mode 100644 src/var/lib/tyto/help/LICENSE delete mode 100644 src/var/lib/tyto/help/README.md delete mode 100644 src/var/lib/tyto/program/html.py delete mode 100644 src/var/lib/tyto/program/log.py delete mode 100644 src/var/lib/tyto/program/publish.py delete mode 100644 src/var/lib/tyto/program/rss.py create mode 100644 src/var/lib/tyto/program/tyto.py delete mode 100644 src/var/lib/tyto/program/wip.old.py diff --git a/FR_Installation.md b/FR_Installation.md deleted file mode 100644 index f508aec..0000000 --- a/FR_Installation.md +++ /dev/null @@ -1,21 +0,0 @@ -# Installation manuelle - -Si vous utilisez Debian, il est plus que recommandé de procéder à -l'installation par le paquet .deb - -## Préparer les dossiers -```` -sudo mkdir -p /var/lib/tyto /etc/tyto /var/log/tyto -sudo touch /usr/local/bin/tyto -sudo chown -R USER:GROUP /var/lib/tyto /etc/tyto /var/log/tyto -sudo chown USER:GROUP /usr/local/bin/tyto -sudo chmod +x /usr/local/bin/tyto - -git clone https://git.a-lec.org/echolib/tyto -rsync -a folders'repo/ to /folders/ - -# Créer votre dossier pour le serveur web -# On utilise en général /var/www/ -# Celui-ci sera à renseigner lors de la création d'un domaine dans Tyto -sudo mkdir -p /var/www/ -```` diff --git a/README.md b/README.md index d80c415..6a2121e 100644 --- a/README.md +++ b/README.md @@ -41,25 +41,26 @@ abbr: NOM (en majuscule) ### Titre h1 à h6 ``` #1 Titre 1 -( +(( Un paragraphe -) +)) #2 Titre 2 ``` + ### Paragraphes ``` -( CSS +(( CSS Un paragraphe -) +)) ``` ### Code Brut ``` -[[ CSS +{{ CSS def hello_world(): print("Hello") -]] +}} ``` ### Listes ul/ol @@ -75,36 +76,36 @@ def hello_world(): ### Citations ``` -(( CSS +[[ 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 +[[ CSS Citation simple sans référence -)) +]] ``` ### Ancres ``` ->> id -( +-> id +(( un long paragraphe -) -( +)) +(( >_id:Retourner au point d'ancre_< -) +)) ``` ### Retour à la ligne HTML ``` -| >>>
    +| #
    ``` ### Lien vers URL @@ -119,21 +120,23 @@ Voir ce __Nom du lien ### Gras, Strong, italique... ``` -*_très gras_* >>> -+_gras léger_+ >>> -/_en italique_/ >>> -\_en italique_\ >>> -~_texte barré_~ >>> -<_Code_> ou (_Code_) >>> -=_Citation rapide_= >>> -×_Classe personnalisée_× >>> --_Souligné_- >>> +*_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 si défini en entête +# ! 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. ``` diff --git a/src/usr/local/bin/tyto b/src/usr/bin/tyto similarity index 100% rename from src/usr/local/bin/tyto rename to src/usr/bin/tyto diff --git a/src/var/lib/tyto/help/CHANGELOG.md b/src/var/lib/tyto/help/CHANGELOG.md deleted file mode 100644 index 75c6ac6..0000000 --- a/src/var/lib/tyto/help/CHANGELOG.md +++ /dev/null @@ -1,16 +0,0 @@ -# Changelog - -Tyto - Littérateur -- Repository: https://git.a-lec.org/echolib/tyto -- Issues: https://git.a-lec.org/echolib/tyto/-/issues -- Changelog: https://git.a-lec.org/echolib/tyto/-/blob/main/CHANGELOG.md -- License: https://git.a-lec.org/echolib/tyto/-/blob/main/LICENSE - -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 static pages. Tyto works on a GNU/Linux system -and needs minimal dependancies. -- python3 rsync nano gawk curl - -## [0.9.0] First Commit version (pre-final) - diff --git a/src/var/lib/tyto/help/FR_Installation.md b/src/var/lib/tyto/help/FR_Installation.md deleted file mode 100644 index f508aec..0000000 --- a/src/var/lib/tyto/help/FR_Installation.md +++ /dev/null @@ -1,21 +0,0 @@ -# Installation manuelle - -Si vous utilisez Debian, il est plus que recommandé de procéder à -l'installation par le paquet .deb - -## Préparer les dossiers -```` -sudo mkdir -p /var/lib/tyto /etc/tyto /var/log/tyto -sudo touch /usr/local/bin/tyto -sudo chown -R USER:GROUP /var/lib/tyto /etc/tyto /var/log/tyto -sudo chown USER:GROUP /usr/local/bin/tyto -sudo chmod +x /usr/local/bin/tyto - -git clone https://git.a-lec.org/echolib/tyto -rsync -a folders'repo/ to /folders/ - -# Créer votre dossier pour le serveur web -# On utilise en général /var/www/ -# Celui-ci sera à renseigner lors de la création d'un domaine dans Tyto -sudo mkdir -p /var/www/ -```` diff --git a/src/var/lib/tyto/help/LICENSE b/src/var/lib/tyto/help/LICENSE deleted file mode 100644 index 2a1caa8..0000000 --- a/src/var/lib/tyto/help/LICENSE +++ /dev/null @@ -1,661 +0,0 @@ - GNU AFFERO GENERAL PUBLIC LICENSE - Version 3, 19 November 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU Affero General Public License is a free, copyleft license for -software and other kinds of works, specifically designed to ensure -cooperation with the community in the case of network server software. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -our General Public Licenses are intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - Developers that use our General Public Licenses protect your rights -with two steps: (1) assert copyright on the software, and (2) offer -you this License which gives you legal permission to copy, distribute -and/or modify the software. - - A secondary benefit of defending all users' freedom is that -improvements made in alternate versions of the program, if they -receive widespread use, become available for other developers to -incorporate. Many developers of free software are heartened and -encouraged by the resulting cooperation. However, in the case of -software used on network servers, this result may fail to come about. -The GNU General Public License permits making a modified version and -letting the public access it on a server without ever releasing its -source code to the public. - - The GNU Affero General Public License is designed specifically to -ensure that, in such cases, the modified source code becomes available -to the community. It requires the operator of a network server to -provide the source code of the modified version running there to the -users of that server. Therefore, public use of a modified version, on -a publicly accessible server, gives the public access to the source -code of the modified version. - - An older license, called the Affero General Public License and -published by Affero, was designed to accomplish similar goals. This is -a different license, not a version of the Affero GPL, but Affero has -released a new version of the Affero GPL which permits relicensing under -this license. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU Affero General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Remote Network Interaction; Use with the GNU General Public License. - - Notwithstanding any other provision of this License, if you modify the -Program, your modified version must prominently offer all users -interacting with it remotely through a computer network (if your version -supports such interaction) an opportunity to receive the Corresponding -Source of your version by providing access to the Corresponding Source -from a network server at no charge, through some standard or customary -means of facilitating copying of software. This Corresponding Source -shall include the Corresponding Source for any work covered by version 3 -of the GNU General Public License that is incorporated pursuant to the -following paragraph. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the work with which it is combined will remain governed by version -3 of the GNU General Public License. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU Affero General Public License from time to time. Such new versions -will be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU Affero General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU Affero General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU Affero General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - GSL Statique Littérateur - Copyright (C) 2022 Libre en Communs / Commissions / Infrastructure - - 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 . - -Also add information on how to contact you by electronic and paper mail. - - If your software can interact with users remotely through a computer -network, you should also make sure that it provides a way for users to -get its source. For example, if your program is a web application, its -interface could display a "Source" link that leads users to an archive -of the code. There are many ways you could offer source, and different -solutions will be better for different programs; see section 13 for the -specific requirements. - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU AGPL, see -. diff --git a/src/var/lib/tyto/help/README.md b/src/var/lib/tyto/help/README.md deleted file mode 100644 index 9f49fa4..0000000 --- a/src/var/lib/tyto/help/README.md +++ /dev/null @@ -1,180 +0,0 @@ -# STL: Statique Littérateur -STL est une évolution du projet GSL. STL permet de créer un ou plusieurs -sites web/blogs statiques, en fonction de leur nom de domaine. - -Tout comme GSL, STL reprend une grande partie de l'écriture nouvelle de -vos articles, en apportant quelques évolutions. Les articles sont donc -au format .stl. - - -# Fonctionnement de STL ; le dossier de base -Contrairement à GSL, vos articles et les pages de votre site web sont -situés dans le même dossier de base. Pour obtenir ce dossier de base, -et configurer votre domaine, vous devez d'abord vous placer dans le -dossier de votre choix, puis lancer la commande de configuration. - -``` -cd MON-DOSSIER-PREFERE -stl domain new - -# Vous pouvez également pré-remplir votre domaine en fonction de l'URL -stl domain new https://mon-site.xyz -``` - -Dans ce dossier de base (MON-DOSSIER-PREFERE), après la configuration de -votre domaine, vous trouverez de nouveaux dossiers : -- articles/ -- - images/ -- - files/ - -Les sous-dossiers images/ et files/ sont proposés afin de faciliter la -réutilisation d'images et de fichiers (PDF, ou autres) déjà présents -dans un autre article. Lors de la synchronisation, il seront copiés à la -racine wip de votre serveur. Le but : faire en sorte que le -navigateur n'ait pas à recharger un même fichier depuis une URL -différente - ce qui plomberait la rapidité d'affichage de la page et -l'intérêt d'un site statique. L'utilisation de cette fonction dans vos -articles est simple ; voir la documentation expliquant comment écrire un -article dans le dossier help. - -Dans le dossier du serveur (/var/www est un exemple), vous trouverez -les dossiers suivants : -- /var/www/DOMAIN/wip/ -- - template (logos, styles.css, sidebar.html, footer.html, metas.html...) -- - images -- - files -- /var/www/DOMAIN/www/ (non créé pour une installation locale) -- - template/ -- - images -- - files - - -## Installation (server, ou local) -Il est possible d'utiliser STL de 2 manières différentes. Lors de la -configuation d'un nouveau domaine, vous devrez choisir entre une -installation faite sur un serveur distant, et une installation faite -en local (sur votre PC). Vous pouvez bien sûr choisir une installation -de type "server" sur votre PC, si celui-ci sert de serveur web. - -Concernant la décoration du site (styles.css, logos), les fichiers -devront être placés dans le dossier serveur /wip/template/ (créé par STL -lors de l'ajout d'un domaine). - - -### Installation "server" -À choisir si votre PC sert de serveur web, ou si vous avez installé STL -sur votre serveur distant. - -Lorsque vous installez STL, sur votre serveur distant, vous pouvez gérer -pour un même nom de domaine, votre site sur 2 adresses URL différentes. -La version WIP, permet de prévisualiser les modifications apportées à -vos pages (sans modifier celles sur WWW) avant de les valider sur votre -site officiel. - -Lorsque votre site prévisualisé sur WIP vous plaît, vous pouvez alors -synchroniser le dossier WIP sur WWW grâce à la commande : - -``` -# Pour publier un article précis -stl publish (ARTICLE) - -# Pour publier tous les articles dans WIP -stl publish all -``` - -Note : cette commande crée automatiquement le flux RSS dans WIP avant -de tous synchroniser sur WWW. - - -### Installation "local" -À choisir si vous voulez utiliser STL sur votre PC, et synchroniser -vous-même le dossier WIP sur votre serveur distant. Inutile donc, -d'installer STL sur le serveur distant. - -Lors d'une utilisation locale, STL ne crée pas le dossier WWW, et ne -synchronise donc pas le dossier WIP vers WWW. C'est à vous de le faire -(via ssh, par exemple). - -Vous devrez lorsque votre site vous plaît localement lancer la création -du flux RSS - avant de synchroniser votre site local sur votre serveur -distant - avec la commande : - -``` -stl rss -``` - - -# Utilisation de STL -Afin de gérer vos articles, vous devez vous placer dans MON-DOSSIER-PREFERE. -L'autocomplétion est activée et personnalisée pour vous aider à trouver -(ARTICLE.stl). - - -## Créer votre arborescence -Dans MON-DOSSIER-PREFERE, vous trouverez le dossier "articles". Celui-ci -sert de base à votre domain.xyz sur votre serveur. C'est dans ce dossier -"articles", que vous pouvez créer vos articles et vos sous-dossiers. -Il est à noter que le nom de l'article est important, puisque STL -l'utilisera en le transformant en .html. Il est donc recommandé - mais -pas obligatoire - de nommer vos articles index.stl, pour obtenir une page -index.html. Si vous voulez créer une page 404, nommez votre article 404.stl -à la racine du dossier "articles". - - -## Convertir votre article en HTML -Placez vous dans MON-DOSSIER-PREFERE. - -Avant de pouvoir convertir votre article, STL dispose d'un système de -vérification de la syntaxe STL. Si des erreurs sont trouvées, un système -de logs vous aidera à corriger ces erreurs. - -``` -# N'oubliez pas d'utiliser l'autocomplétion -stl check (ARTICLE.stl) -``` - -Vous pouvez maintenant le convertir en HTML dans le dossier wip - -``` -stl wip (ARTICLE.stl) -``` - - -## Utiliser la sidebar -C'est la seule partie du site qui est semi-statique. STL fait appel à -nginx, qui va se charger de traduire la balise HTML ``, -et afficher le rendu du fichier sidebar.html - -Chaque article, une fois convertit avec l'argument wip peut être placé -dans la sidebar à la position désirée, entre 1 et la valeur maximum -décidée, lors de la configuration du domaine. - -``` -stl sidebar add 1 (ARTICLE.stl) -``` - -Vous pouvez également décider de placer un article ausitôt convertit -avec l'argument wip sidebar=POSITON - -``` -stl wip sidebar=2 (ARTICLE.stl) -``` - -## Documentation de STL -Les fichiers de documentations sont dans le dossier help. -Le README est accessible depuis la ligne de commande, comme les arguments -utilisables. - -``` -stl help -stl readme -``` - - -## Dépendances -STL est écrit en bash, et a besoin des utilitaires -- gawk -- rsync -- nano -- curl - diff --git a/src/var/lib/tyto/program/check.py b/src/var/lib/tyto/program/check.py index b7c467b..aab12c7 100644 --- a/src/var/lib/tyto/program/check.py +++ b/src/var/lib/tyto/program/check.py @@ -2,8 +2,8 @@ # Name: Tyto - Littérateur # Type: Global functions for check # Description: Check article contents. Create Stats and Database -# file: wip.py -# Folder: /var/lib/tyto/scripts/ +# file: check.py +# Folder: /var/lib/tyto/program/ # By echolib (XMPP: im@echolib.re) # License: GNU AFFERO GENERAL PUBLIC LICENSE Version 3, 19 November 2007 @@ -19,1302 +19,593 @@ # Import needed libs import sys, os, re, datetime -import domain, log, wip +from datetime import datetime +from time import gmtime, strftime +import time +import tyto -Post_Err = False -post_uri = '' -msg_log = '' +# Load domain configuration if exists +if tyto.domain_exists: exec(open(tyto.domain_conf).read()) -# markers (regex) -m_anchor = r'^>>' # No close marker - -# 'Open' , 'Close' , 'Name' -markers_reg = [ - [ r'^\($|^\(\s' , r'^\)$' , 'paragraphs' ], - [ r'^\(\($|^\(\(\s', r'^\)\)$', 'quotes' ], - [ r'^\[\[$|^\[\[\s', r'^\]\]$', 'brut codes' ], - [ r'^-\($|^-\(\s' , r'^-\)$' , 'lists' ] - ] -markers_opt = ( - 'image:', - 'file:', - 'link:', - 'abbr:' - ) - -#=======# -# Tools # -#=======#-------------------------------------------------------------- -#===============================# -# Define article IDs, if exists # -# Used for check, wip... # -#-------------------------------# -def post_IDs(file_post): - # Check if argument's file (.tyto) or exit - if not file_post: - print(':< Unused argument file') - sys.exit(1) - - global post_srv - post_srv = file_post.replace('.tyto','.html') - - # Check if file exists or exit - global post_uri - post_uri = '%s%s'%(domain.domain_articles, file_post) - - if not os.path.exists(post_uri): - print(':< Unused file: %s'%post_uri) - sys.exit(1) - - # Set HTML file from file_post - file_html = file_post.replace('.tyto','.html') - if file_html.endswith('index.html'): - file_html = file_html.replace('index.html', '') - - # Complete URL post file - global post_url - post_url = '%s%s/%s'%( - domain.domain_protocol, domain.domain_name, file_html - ) - - global post_dir - post_dir = file_post.replace(os.path.basename(file_post), '') - - # From argument file_post - # Set WEB link prefix. Count / in uri - global weburi - slash = 0 - weburi = '' - - for s in file_post: - if s == '/': slash += 1 - - if slash == 0: - weburi = './' - else: - for i in range(0,slash): - weburi = '%s../'%weburi - - # Get Hash from article's content - global hash_chk - hash_chk = get_filesum(post_uri, True) - - # Get Hash ID from URI - global curr_post_ID, curr_post_db, post_logs - curr_post_ID = get_filesum(post_uri, False) - - # Set database file for this article - curr_post_db = '%s%s.conf'%(domain.domain_db, curr_post_ID) - - # Set and check/create logs file for this article - post_logs = '%s%s.log'%(domain.domain_logs, curr_post_ID) - - #------------------ - # Article Database - #------------------ - # Check if Article has DB - # Source its conf and compare - global db_exist - try: - exec(open(curr_post_db).read(),globals()) - db_exist = True - except: - db_exist = False - - if db_exist: - # Set HTML file - global srv_post_wip, srv_post_www - srv_post_wip = [False, domain.srv_wip + file_html] - srv_post_www = [False, domain.srv_www + file_html] - - # Set to True, if file exists on servers - if os.path.exists(srv_post_wip[1]): srv_post_wip[0] = True - if os.path.exists(srv_post_www[1]): srv_post_www[0] = True - -#============================================# -# Check and if not exist, create domain dirs # -# Also Used to create when new domain set # -#--------------------------------------------# -def create_domain_dirs(path_type): - # Needed direcories when creating a new domain - if 'all' in path_type: - all_dirs = [ - domain.srv_wip_template, - domain.srv_wip_images, - domain.srv_wip_files, - domain.srv_www_template, - domain.srv_www_images, - domain.srv_www_files, - domain.domain_articles, - domain.domain_images, - domain.domain_files, - domain.domain_sdb_dir, - domain.domain_db, - domain.domain_logs - ] - for folder in all_dirs: - os.makedirs(folder, exist_ok=True) - - # Check/Create needed directories (only for 'check' process) - if 'db' in path_type: - os.makedirs(domain.domain_db, exist_ok=True) - os.makedirs(domain.domain_logs, exist_ok=True) - -#=======================# -# Return sum of srcfile # -# src: True = file # -# False = string # -#-----------------------# -def get_filesum(path,src): - from hashlib import blake2b - file_sum = blake2b(digest_size=4) - - if src: file_sum.update(open(path, 'rb').read()) - else : file_sum.update(path.encode()) - return file_sum.hexdigest() +post_err = False #=========================# # Manage Argument 'check' # # Start checking article # #-------------------------#-------------------------------------------- -def manage_check(file_post, Force): - # Set needed IDs - post_IDs(file_post) +def manage_check(target, option): + global post_bottom, article_bottom + global post_words - # Start checking Post, then exit if errors found in - process_article(post_uri, Force) - - -#==========================# -# Pre-processing post file # -#--------------------------# -def process_article(post_uri, Force): - global article - # Check needed directories. Create if not exist - create_domain_dirs('db') - - # Create logs - #------------- - if not os.path.exists(post_logs): - file = open(post_logs, "w") - file.write('') - file.close() - msg_log = 'Log > Create logs file for %s in %s\n'%( - post_uri, post_logs) - log.append_f(post_logs, msg_log, 0) - - # Article Database - #------------------ - # In check process: no values (kept from db, if exists) - global hash_wip, hash_www, time_wip, time_www - - hash_wip = time_wip = hash_www = time_www = '' - - if db_exist: - # backup hash_wip/www values - hash_wip = post_wip[0];time_wip = post_wip[1] - hash_www = post_www[0];time_www = post_www[1] + # target needed + if not target: tyto.exiting("5", '', True) - # Compare chk Hashes. - # Pass if Force, and not same - if hash_chk == post_chk[0] and not Force: - print(':D Check was already done, on', post_chk[1]) - sys.exit(0) + # Article exists + has DB ? + db_exists = tyto.get_db_post(target) + + # Manage option + if option == 'Edit': + tyto.edit_file(tyto.uri_root) + return - # Processing - #----------- - # Prepare: put post's contents file in headers and article strings - post_to_strings(post_uri) + if db_exists: + exec(open(tyto.post_db).read(),globals()) + if hash_chk == tyto.hash_post and not option == 'Force': + tyto.exiting("20", date_chk, True) + + # Start processes + file_to_string(tyto.uri_root) + + # Protect inline-codes + tyto.protect_icodes(post_bottom, article_bottom) + post_bottom = tyto.protect_article.rsplit('\n') + article_bottom = tyto.protect_article + + # Protect block-codes and quotes + tyto.protect_bcodes_quotes('check', post_bottom) + post_bottom = tyto.protect_article.rsplit('\n') + article_bottom = tyto.protect_article + + # Count words in article. Not from quotes, block-codes, icode = 1 + post_words = len(article_bottom.strip().split(" ")) + + # Check for valid contents + check_content(post_bottom) + post_bottom = article_bottom.rsplit('\n') + + check_headers(post_header) + - # Send to log - msg_log = 'Check > Article: %s. logs: %s'%(post_uri,post_logs) - log.append_f(domain.tyto_logs,msg_log,0) + # Exit if unused needed tags + if post_err: tyto.exiting("7", '', True) - # Check markers in headers - check_post_header(headers.rsplit('\n')) - if Post_Err: sys.exit(1) - - # Protect bCodes, keep markers for stats, before checking other markers - wip.convert_bcodes(article.rsplit('\n'), - '[[', ']]', - domain.domain_css) - article = wip.article_temp - - # Protect quotes, keep markers for stats, before checking other markers - wip.convert_bcodes(article.rsplit('\n'), - '((', '))', - domain.domain_css) - article = wip.article_temp - - # Protect iCodes, keep markers for stats - wip.convert_icodes(article.rsplit('\n'), domain.domain_css) - article = wip.article_temp - - # Check titles/comments in article - check_article_titles(article.rsplit('\n')) - - # Check links (anchors) - check_links_anchors(article) - - # Check titles/comments in article - check_lists_contents(article.rsplit('\n')) - - # Check other markers - check_article_markers(article) - - # Error in article - #--------------------- - if Post_Err: sys.exit(1) - - # No Domain registred yet - #------------------------- - # If in a domain Process to DB - if not domain.domain_active: - print(':/ Article is Ok, but will not be converted') - sys.exit(0) + # No error + create_database() - # No Error... - #------------ - # Create (file).wip for this article to use with wip argument - global post_tmp - post_tmp = '%s%s.wip'%(domain.domain_db, curr_post_ID) - - # Create NEW file - file = open(post_tmp, "w") - file.write('') - for line in article.rsplit('\n'): - if len(line) == 0 : continue - elif line.startswith('# ') : continue - elif line.startswith('##') : continue - file.write(line + '\n') - file.close() - - # Create DB - create_DB(curr_post_db) - print(':D Article is Ok and ready to "tyto wip"') -#=========================================# -# Put file in strings => headers, article # -# But, check if separator is defined... # -#-----------------------------------------# -def post_to_strings(post_uri): - # Check if separator from header and article ; else: exit - file_string = open(post_uri,'r').read() - if not '-----' in file_string: - msg_log = 'Unused separator "-----" (header,post)' - log.append_f(post_logs, msg_log, 1) - sys.exit(0) +#=====================# +# Find in post_bottom # +#---------------------# +def isin(term, post_bottom): + for x in post_bottom: + if re.search(r'%s'%term, x): + return True + return False + + +#=================================# +# Create string article from file # +# Check if separator or exit # +#---------------------------------# +def file_to_string(post_file): + # Check if separator + global article + global article_header, article_bottom + global post_header, post_bottom - # From Separator... - # Split post in 2 strings for Headers and Article - global headers, article, post_lines, headers_ln + article = open(post_file, 'r').read() - headers = article = '' - post_lines = file_string.rsplit('\n') - post = False + if not '-----' in article: + tyto.exiting("6", '-----', True) - for line in post_lines: - if line.startswith('-----'): - post = True + # Set from separator, NOT splitted by new line + article_header = article.rsplit('-----')[0] + article_bottom = article.rsplit('-----')[1] + + # Set from separator, splitted by new line + post_header = article.rsplit('-----')[0].rsplit('\n') + post_bottom = article.rsplit('-----')[1].rsplit('\n') + + +#==================================# +# Check tags from article's header # +#----------------------------------# +def check_headers(post_header): + global post_err, err, web_uri, date_check + global date, title, author, tags, about + global stat_links, stat_images, stat_files, stat_bruts, stat_abbrs + global post_tags + + #post_tags = 0 + + # Needed Tags + title = author = tags = about = '' + date = () + + # Statistics + stat_links = stat_images = stat_files = stat_bruts = stat_abbrs = 0 + +### + # First session for needed tags # + # Read articles lines, till separator # + #-------------------------------------# + for ln, line in enumerate(post_header, 1): + + # Set each needed tag # + # Only the first one is set # + #---------------------------# + tag = 'title:' + if line.startswith(tag): + if title: continue + title = line.rsplit(tag)[1].lstrip() continue - if post: article = '%s\n%s'%(article,line) # In post content - else: headers = '%s\n%s'%(headers,line) # In post header - - # Get number lines in headers, min line separator - headers_ln = len(headers.split("\n")) - 1 + tag = 'about:' + if line.startswith(tag): + if about: continue + about = line.rsplit(tag)[1].lstrip() + continue -#=================# -# HEADERS CONTENT # -#=================# -#====================================# -# Init stats, arrays... # -# Loop into headers to check markers # -#------------------------------------# -def check_post_header(headers): - # Mandatory markers - global title, about, author, tags, date + tag = 'tags:' + if line.startswith(tag): + if tags: continue + tags = line.rsplit(tag)[1].lstrip() + post_tags = len(tags.strip().split(",")) + continue + + tag = 'author:' + if line.startswith(tag): + if author: continue + author = line.rsplit(tag)[1].lstrip() + continue - # Set Mandatory marker. 0:True/False 1:ln 2: Content - title = about = author = tags = date = ('','','') - - # Set Stats - global stats_links_uniq, stats_links, stats_links_p - global stats_files_uniq, stats_files_p - global stats_images_uniq, stats_images_p - global stats_abbrs_uniq, stats_abbrs_p - global stats_bruts_uniq, stats_bruts_p - - stats_links_uniq = stats_links = stats_links_p = 0 - stats_files_uniq = stats_files_p = 0 - stats_images_uniq = stats_images_p = 0 - stats_abbrs_uniq = stats_abbrs_p = 0 - stats_bruts_uniq = stats_bruts_p = 0 - - # Set Optional markers. 0:ln 1:Name 2:URL 3:Alt - link = file = image = brut = ('','','','') - - #----------------------- - # Loop in headers string - #----------------------- - for ln, line in enumerate(headers, 1): - - #----------------------- - # Set mandatory markers - #----------------------- - if line.startswith('title:'): - title = (True,ln,line.split('title:')[1].lstrip()) - elif line.startswith('about:'): - about = (True,ln,line.split('about:')[1].lstrip()) - elif line.startswith('author:'): - author = (True,ln,line.split('author:')[1].lstrip()) - elif line.startswith('tags:'): - tags = (True,ln,line.split('tags:')[1].lstrip()) - elif line.startswith('date:'): - date = (True,ln,line.split('date:')[1].lstrip()) - - #---------------------- - # Set optional markers - #---------------------- - # link: - if line.startswith('link:'): - stats_links_uniq += 1 - check_links(line, ln, stats_links_uniq) - # file: - elif line.startswith('file:'): - stats_files_uniq += 1 - check_files(line, ln, stats_files_uniq) - # image: - elif line.startswith('image:'): - stats_images_uniq += 1 - check_images(line, ln, stats_images_uniq) - # abbr: - elif line.startswith('abbr:'): - stats_abbrs_uniq += 1 - check_abbrs(line, ln, stats_abbrs_uniq) - # brut: - elif line.startswith('brut:'): - stats_bruts_uniq += 1 - check_bruts(line, ln, stats_bruts_uniq) + tag = 'date:' + if line.startswith(tag): + if date: continue + date = line.rsplit(tag)[1].lstrip() + check_date(date, ln) + if not post_err: + if tyto.n == 0: + date = date.rsplit('-') + date = date[2] + '/' + date[1] + '/' + date[0] + date = (date, date_check) + continue - #------------------------------- - # Check valid Mandatory markers - #------------------------------- - if_mandat_marker('title:', title) - if_mandat_marker('about:', about) - if_mandat_marker('author:', author) - if_mandat_marker('tags:', tags) - if_mandat_marker('date:', date) - if date: check_date(date) - - -#===================# -# MANDATORY Markers # -#===================#-------------------------------------------------- -#=====================================# -# Check if marker is used and defined # -#-------------------------------------# -def if_mandat_marker(marker, m_in): - global Post_Err - if not m_in[0]: - msg_log = 'Unused needed marker "%s"'%marker - log.append_f(post_logs, msg_log, 1) - Post_Err = True - elif not m_in[2]: - msg_log = 'Line %s. Undefined marker "%s"'%( - m_in[1], marker - ) - log.append_f(post_logs, msg_log, 1) - Post_Err = True + # Check needed tags # + #-------------------# + # Set needed tags + need_headers = { + 'title:' : title, + 'anout:' : about, + 'tags:' : tags, + 'author:': author, + 'date:' : date + } + + # Check if set needed tags + for tag in need_headers: + if not need_headers[tag]: + tyto.exiting("6", tag, False) + + +### + # Second session for optional tags # + # Read articles lines, till separator # + #-------------------------------------# + for ln, line in enumerate(post_header, 1): + if line.startswith('-----'): break + + + # Set each optional tags + #----------------------- + + # ABBR + #----- + tag = 'abbr:' + if line.startswith(tag): + stat_abbrs += 1 + var_tag = 'abbr_%s'%stat_abbrs + + abbr_short = post_header[ln - 1].rsplit(tag)[1].lstrip() + if not abbr_short: + tyto.exiting("2", "Line %s (SHORT, %s)"%(ln, tag), False) + post_err = True + if not abbr_short.isupper(): + tyto.exiting("3", "Line %s (Upper SHORT, %s)"%(ln, tag), False) + post_err = True + continue + if not isin(r'\b%s\b'%abbr_short, post_bottom): + tyto.exiting("6", abbr_short, False) + post_err = True + + abbr_long = post_header[ln].lstrip() + if abbr_long.startswith(tyto.headers): abbr_long = '' + if not abbr_long: + tyto.exiting("2", "Line %s (Long, %s)"%(ln + 1, tag), False) + post_err = True + + abbr_alt = post_header[ln + 1].lstrip() + if abbr_alt.startswith(tyto.headers): abbr_alt = '' + if not abbr_alt: abbr_alt = abbr_short + + if not post_err: + web_link = '%s'%( + 'abbr', abbr_long, abbr_alt + ) + globals()['abbr_%s'%stat_abbrs] = ( + abbr_short, web_link + ) + + # LINK + #----- + tag = 'link:' + if line.startswith(tag): + stat_links += 1 + var_tag = 'link_%s'%stat_links + + link_name = post_header[ln - 1].rsplit(tag)[1].lstrip() + if not link_name: + tyto.exiting("2", "Line %s (Name, %s)"%(ln, tag), False) + post_err = True + if not isin(r'\b_%s\b'%link_name, post_bottom): + tyto.exiting("6", "_%s"%link_name, False) + post_err = True + + link_url = post_header[ln].lstrip() + if link_url.startswith(tyto.headers): link_url = '' + if not link_url: + tyto.exiting("2", "Line %s (URL, %s)"%(ln + 1, tag), False) + post_err = True + + link_alt = post_header[ln + 1].lstrip() + if link_alt.startswith(tyto.headers): link_alt = '' + if not link_alt: + tyto.exiting("2", "Line %s (Alt-Text, %s)"%(ln + 2, tag), False) + post_err = True + + if not post_err: + web_link = '%s'%( + 'link', link_url, link_alt, link_name + ) + globals()['link_%s'%stat_links] = ( + '_%s'%link_name, web_link + ) + + # IMAGE + #------ + tag = 'image:' + if line.startswith(tag): + stat_images += 1 + var_tag = 'image_%s'%stat_images + + image_name = post_header[ln - 1] + image_name = image_name.rsplit(tag)[1].lstrip().rsplit(' ')[0] + if not image_name: + tyto.exiting("2", "Line %s (Name, %s)"%(ln, tag), False) + post_err = True + if not isin(r'\b_%s%s\b'%(tag, image_name), post_bottom): + tyto.exiting("6", "_%s%s"%(tag, image_name), False) + post_err = True + + image_uri = post_header[ln].lstrip() + if image_uri.startswith(tyto.headers): image_uri = '' + if not image_uri: + tyto.exiting("2", "Line %s (URI, %s)"%(ln + 1, tag), False) + post_err = True + else: + check_file_uri('image', image_uri, ln + 1) + + image_alt = post_header[ln + 1].lstrip() + if image_alt.startswith(tyto.headers): image_alt = '' + if not image_alt: + tyto.exiting("2", "Line %s (Alt-Text, %s)"%(ln + 2, tag), False) + post_err = True + + if not post_err: + globals()['image_%s'%stat_images] = ( + '_%s%s'%(tag, image_name), + web_uri, + image_alt + ) + + # BRUT + #----- + tag = 'brut:' + if line.startswith(tag): + stat_bruts += 1 + var_tag = 'brut_%s'%stat_bruts + + brut_name = post_header[ln - 1] + brut_name = brut_name.rsplit(tag)[1].lstrip().rsplit(' ')[0] + if not brut_name: + tyto.exiting("2", "Line %s (Name, %s)"%(ln, tag), False) + post_err = True + if not isin(r'\b_%s%s\b'%(tag, brut_name), post_bottom): + tyto.exiting("6", "_%s%s"%(tag, brut_name), False) + post_err = True + + brut_uri = post_header[ln].lstrip() + if brut_uri.startswith(tyto.headers): brut_uri = '' + if not brut_uri: + tyto.exiting("2", "Line %s (URI, %s)"%(ln + 1, tag), False) + post_err = True + else: + check_file_uri('file', brut_uri, ln + 1) + + brut_alt = post_header[ln + 1].lstrip() + if brut_alt.startswith(tyto.headers): brut_alt = '' + if not brut_alt: + tyto.exiting("2", "Line %s (Alt-Text, %s)"%(ln + 2, tag), False) + post_err = True + + if not post_err: + globals()['brut_%s'%stat_bruts] = ( + '_%s%s'%(tag, brut_name), + web_uri, + brut_alt + ) + + # FILE + #----- + tag = 'file:' + if line.startswith(tag): + stat_files += 1 + var_tag = 'file_%s'%stat_files + + file_name = post_header[ln - 1].rsplit(tag)[1].lstrip() + if not file_name: + tyto.exiting("2", "Line %s (Name, %s)"%(ln, tag), False) + post_err = True + if not isin(r'\b__%s\b'%file_name, post_bottom): + tyto.exiting("6", "__%s"%file_name, False) + post_err = True + + file_uri = post_header[ln].lstrip() + if file_uri.startswith(tyto.headers): file_uri = '' + if not file_uri: + tyto.exiting("2", "Line %s (URI, %s)"%(ln + 1, tag), False) + post_err = True + else: + check_file_uri('file', file_uri, ln + 1) + + file_alt = post_header[ln + 1].lstrip() + if file_alt.startswith(tyto.headers): file_alt = '' + if not file_alt: + tyto.exiting("2", "Line %s (Alt-Text, %s)"%(ln + 2, tag), False) + post_err = True + + if not post_err: + web_link = '%s'%( + 'file', web_uri, file_alt, file_name + ) + globals()['file_%s'%stat_files] = ( + '__%s'%file_name, web_link + ) + + # Exit if error in optional tags + #------------------------------- + if post_err: + tyto.exiting("7", '', True) + #================================# # Check Date format and validity # # Create False date_check # #--------------------------------# -def check_date(date): - from datetime import datetime - from time import gmtime, strftime - import time - global Post_Err, date_check +def check_date(date, ln): + global post_err, date_check # Check if article date is valid (True) fmt_article = "%Y-%m-%d" try: - bool(datetime.strptime(date[2], fmt_article)) + bool(datetime.strptime(date, fmt_article)) except ValueError: - Post_Err = True - msg_log = 'Line %s. Invalid date: %s'%(date[1],date[2]) - log.append_f(post_logs, msg_log, 1) + post_err = True + tyto.exiting("3", 'Line %s (date, %s)'%(ln, date), False) # Create date_check (epoch) from article's Date + now TIME - if not Post_Err: + if not post_err: fmt_check = '%Y-%m-%d %H:%M:%S' time_check = strftime("%H:%M:%S", gmtime()) - date_check = date[2] + ' ' + time_check - date_check = time.mktime(time.strptime(date_check,fmt_check)) + date_check = date + ' ' + time_check + date_check = time.mktime(time.strptime(date_check, fmt_check)) -#==================# -# OPTIONAL Markers # -#==================#--------------------------------------------------- -#===============================# -# Statistics # -# Return term number in article # -#-------------------------------# -def stats_counter(term): - term = r"%s"%term - return(sum(1 for match in re.finditer(r'\b%s\b'%term, article))) +#===================================# +# Check if file exists # +# Get filetype, filename, i=var nbr # +#-----------------------------------# +def check_file_uri(filetype, filename, ln): + global post_err, err, web_uri -#============================ -# Check optional marker set # -# Called from # -# - check_links # -# - check_files # -# - check_images # -#---------------------------# -def if_option_marker(marker, m_in): - global Post_Err + # Set file uri from filename + # (@ = images/, / = articles/, else = post_dir) + if filename.startswith('@'): + if filetype == 'image': + fileuri = domain_images + filename[1: len(filename)] + elif filetype == 'file': + fileuri = domain_files + filename[1: len(filename)] - if not m_in[1]: - msg_log = 'Line %s. Unused NAME for marker "%s"'%( - m_in[0], marker - ) - log.append_f(post_logs,msg_log,1) - Post_Err = True + elif filename.startswith('/'): + fileuri = domain_articles + filename[1: len(filename)] - if not m_in[2]: - msg_log = 'Line %s. Unused URL for marker "%s"'%( - m_in[0], marker - ) - log.append_f(post_logs,msg_log,1) - Post_Err = True - - if not m_in[3]: - msg_log = 'Line %s. Unused Alt-Text for marker "%s"'%( - m_in[0]+1, marker - ) - log.append_f(post_logs, msg_log, 1) - Post_Err = True - -#=================================# -# Check every marker "link:" # -# For line, from loop header file # -# Also, create Stats # -#---------------------------------# -def check_links(line, ln, stats_links_uniq): - global Post_Err, stats_links_p - - # Create variable array - try: link_name = line.split('link:')[1].lstrip() - except: link_name = '' - try: link_url = headers.rsplit('\n')[ln].lstrip() - except: link_url = '' - try: link_alt = headers.rsplit('\n')[ln+1].lstrip() - except: link_alt = '' - - if not link_name: - msg_log = 'Line %s. Unused NAME for marker "link:"'%ln - log.append_f(post_logs, msg_log, 1) - Post_Err = True - return(1) - - link_nbr = 'link_%s'%stats_links_uniq - # Check 2nd line - check_new_marker(link_url) - if new_marker: link_url = '' - - # Check 3rd line - check_new_marker(link_alt) - if new_marker: link_alt = '' - - link = ( - ln, - link_name, - link_url, - link_alt - ) - - # Set/Check values to check in header - globals()[link_nbr] = link - if_option_marker('link:', globals()[link_nbr]) - - # Check NAME in article - link_page = '_%s'%link_name - if not link_page in article: - msg_log = 'Unused "%s" for marker "link:" in article"'%link_page - log.append_f(post_logs, msg_log, 1) - Post_Err = True - - if Post_Err: return - # Set final marker_N - link = ( - '%s'%link_name, - link_url, - link_alt - ) - globals()[link_nbr] = link - - # Stats: count occurence - stats_links_p = stats_links_p + stats_counter(link_page) - -#=================================# -# Check every marker "file:" # -# For line, from loop header file # -# Also, create Stats # -#---------------------------------# -def check_files(line, ln, stats_files_uniq): - global Post_Err - global stats_files_p - - # Create variable array - try: file_name = line.split('file:')[1].lstrip() - except: file_name = '' - try: file_uri = headers.rsplit('\n')[ln].lstrip() - except: file_uri = '' - try: file_alt = headers.rsplit('\n')[ln+1].lstrip() - except: file_alt = '' - - if not file_name: - msg_log = 'Line %s. Unused NAME for marker "image:"'%ln - log.append_f(post_logs,msg_log,1) - Post_Err = True - return(1) - - file_nbr = 'file_%s'%stats_files_uniq - # Check 2nd line - check_new_marker(file_uri) - if new_marker: file_uri = '' - - # Check 3rd line - check_new_marker(file_alt) - if new_marker: file_alt = '' - - file = ( - ln, - file_name, - file_uri, - file_alt - ) - - # Set/Check values to check in header - globals()[file_nbr] = file - if_option_marker('file:', globals()[file_nbr]) - - # Check NAME in article - file_page = '__%s'%file_name - if not file_page in article: - msg_log = 'Unused "%s" for marker "file:" in article"'%file_page - log.append_f(post_logs, msg_log, 1) - Post_Err = True - - # Check URI value (exists and where) - # In Generic folder /files/ - if file_uri.startswith('@'): - file_uri = file_uri.replace('@','') - gen_file = '%s%s'%(domain.domain_files, file_uri) - if not os.path.exists(gen_file): - msg_log = 'Unused file for marker "file:" in %s'%gen_file - log.append_f(post_logs, msg_log, 1) - Post_Err = True - else: - file_uri = '/files/%s'%file_uri - - # From Root articles (www/ in web) - elif file_uri.startswith('/'): - file_uri = file_uri[1:len(file_uri)] # No need first / to check - usr_file = '%s%s'%(domain.domain_articles, file_uri) - if not os.path.exists(usr_file): - msg_log = 'Unused file for marker "file:" in %s'%usr_file - log.append_f(post_logs, msg_log, 1) - Post_Err = True - else: - file_uri = '/%s'%file_uri - - # Current or custom URI else: - usr_file = '%s%s'%(domain.domain_articles, file_uri) - if not os.path.exists(usr_file): - msg_log = 'Unused file for marker "file:" in %s'%usr_file - log.append_f(post_logs, msg_log, 1) - Post_Err = True + fileuri = tyto.post_dir + filename - if Post_Err: return - #-------------------- - # Set final marker_N - #-------------------- - file = ( - '%s'%file_name, - file_uri, - file_alt - ) - globals()[file_nbr] = file + # Check if file exists + if not os.path.exists(fileuri): + tyto.exiting("1", "Line %s, %s"%(ln, fileuri), False) + post_err = True + return - # Stats: count occurence - stats_files_p = stats_counter(file_page) - -#=================================# -# Check every marker "brut:" # -# For line, from loop header file # -# Also, create Stats # -#---------------------------------# -def check_bruts(line, ln, stats_files_uniq): - global Post_Err - global stats_bruts_p - - # Create variable array - try: brut_name = line.split('brut:')[1].lstrip().rsplit(' ')[0] - except: brut_name = '' - try: brut_uri = headers.rsplit('\n')[ln].lstrip() - except: brut_uri = '' - try: brut_alt = headers.rsplit('\n')[ln+1].lstrip() - except: brut_alt = '' - - if not brut_name: - msg_log = 'Line %s. Unused NAME for marker "brut:"'%ln - log.append_f(post_logs,msg_log,1) - Post_Err = True - return(1) - - brut_nbr = 'brut_%s'%stats_bruts_uniq - # Check 2nd line - check_new_marker(brut_uri) - if new_marker: brut_uri = '' - - # Check 3rd line - check_new_marker(brut_alt) - if new_marker: brut_alt = '' - - brut = ( - ln, - brut_name, - brut_uri, - brut_alt - ) - - # Set/Check values to check in header - globals()[brut_nbr] = brut - if_option_marker('brut:', globals()[brut_nbr]) - - # Check value in article - brut_page = '_brut:%s'%brut_name - if not brut_page in article: - msg_log = 'Unused "%s" for marker "brut:" in article"'%brut_page - log.append_f(post_logs, msg_log, 1) - Post_Err = True - - # Check URI value (exists and where) - # In Generic folder /files/ - if brut_uri.startswith('@'): - brut_uri = brut_uri.replace('@','') - gen_file = '%s%s'%(domain.domain_files, brut_uri) - if not os.path.exists(gen_file): - msg_log = 'Unused file for marker "brut:" in %s'%gen_file - log.append_f(post_logs, msg_log, 1) - Post_Err = True - else: - brut_uri = '/files/%s'%brut_uri - - # From Root articles (www/ in web) - elif brut_uri.startswith('/'): - brut_uri = brut_uri[1:len(brut_uri)] # No need first / to check - usr_file = '%s%s'%(domain.domain_articles, brut_uri) - if not os.path.exists(usr_file): - msg_log = 'Unused file for marker "brut:" in %s'%usr_file - log.append_f(post_logs, msg_log, 1) - Post_Err = True - else: - brut_uri = '/%s'%brut_uri - - # Current or custom URI - else: - usr_file = '%s%s'%(domain.domain_articles, brut_uri) - if not os.path.exists(usr_file): - msg_log = 'Unused file for marker "brut:" in %s'%usr_file - log.append_f(post_logs, msg_log, 1) - Post_Err = True - - if Post_Err: return - #-------------------- - # Set final marker_N - #-------------------- - brut = ( - '%s'%brut_name, - brut_uri, - brut_alt - ) - globals()[brut_nbr] = brut - - # Stats: count occurence - stats_bruts_p = stats_counter(brut_page) - -#=================================# -# Check every marker "image:" # -# For line, from loop header file # -# Also, create Stats # -#---------------------------------# -def check_images(line, ln, stats_images_uniq): - global Post_Err - global stats_images_p - - # Create variable array - - try: image_name = line.split('image:')[1].lstrip().rsplit(' ')[0] - except: image_name = '' - try: image_uri = headers.rsplit('\n')[ln].lstrip() - except: image_uri = '' - try: image_alt = headers.rsplit('\n')[ln+1].lstrip() - except: image_alt = '' - - if not image_name: - msg_log = 'Line %s. Unused NAME for marker "image:"'%ln - log.append_f(post_logs,msg_log,1) - Post_Err = True - return(1) - - image_nbr = 'image_%s'%stats_images_uniq - # Check 2nd line - check_new_marker(image_uri) - if new_marker: image_uri = '' - - # Check 3rd line - check_new_marker(image_alt) - if new_marker: image_alt = '' - - image = ( - ln, - image_name, - image_uri, - image_alt - ) - - # Set/Check values to check in header - globals()[image_nbr] = image - if_option_marker('image:', globals()[image_nbr]) - - # Check value in article - image_page = '_image:%s'%image_name - if not image_page in article: - msg_log = 'Unused "%s" for marker "image:" in article"'%image_page - log.append_f(post_logs, msg_log, 1) - Post_Err = True - - # Check URI value (exists and where) - # Set HTML value in DB - if image_uri.startswith('@'): - image_uri = image_uri.replace('@','') - gen_image = '%s%s'%(domain.domain_images, image_uri) - if not os.path.exists(gen_image): - msg_log = 'Unused file for marker "imagee:" in %s'%gen_image - log.append_f(post_logs, msg_log, 1) - Post_Err = True - else: - image_uri = '/images/%s'%image_uri - - # From Root articles (www/ in web) - elif image_uri.startswith('/'): - image_uri = image_uri[1:len(image_uri)] # No need first / to check - usr_file = '%s%s'%(domain.domain_articles, image_uri) - if not os.path.exists(usr_file): - msg_log = 'Unused file for marker "image:" in %s'%usr_file - log.append_f(post_logs, msg_log, 1) - Post_Err = True - else: - image_uri = '/%s'%image_uri - - # Current or custom URI - else: - usr_file = '%s%s%s'%(domain.domain_articles, post_dir, image_uri) - if not os.path.exists(usr_file): - msg_log = 'Unused file for marker "image:" in %s'%usr_file - log.append_f(post_logs, msg_log, 1) - Post_Err = True - - if Post_Err: return - #-------------------- - # Set final marker_N - #-------------------- - image = ( - '%s'%image_name, - image_uri, - image_alt - ) - globals()[image_nbr] = image - - # Stats: count occurence - stats_images_p = stats_counter(image_page) - -#=================================# -# Check every marker "abbr:" # -# For line, from loop header file # -# Also, create Stats # -#---------------------------------# -def check_abbrs(line, ln, stats_abbrs_uniq): - global Post_Err - global stats_abbrs_p - - # Create variable array - try: abbr_name = line.split('abbr:')[1].lstrip() - except: abbr_name = '' - try: abbr_alt = headers.rsplit('\n')[ln].lstrip() - except: abbr_alt = '' - try: abbr_rep = headers.rsplit('\n')[ln+1].lstrip() - except: abbr_rep = '' - - # Set/Check values to check in header - if not abbr_name: - msg_log = 'Line %s. Unused NAME for marker "abbr:"'%ln - log.append_f(post_logs,msg_log,1) - Post_Err = True - return(1) - elif abbr_name.isupper() is False: - msg_log = 'Line %s. NAME not in CAPITAL for marker "abbr:"'%ln - log.append_f(post_logs,msg_log,1) - Post_Err = True - - # Check 2rd line - check_new_marker(abbr_alt) - if new_marker: abbr_name = '' - # Set/Check values to check in header - if not abbr_alt: - msg_log = 'Line %s. Unused alt-text for marker "abbr:"'%ln + 1 - log.append_f(post_logs,msg_log,1) - Post_Err = True - - # Check 3rd line - check_new_marker(abbr_rep) - if new_marker or not abbr_rep: abbr_rep = abbr_name - - # Check NAME in article - if not abbr_name in article: - msg_log = 'Unused "%s" for marker "abbr:" in article"'%abbr_name - log.append_f(post_logs,msg_log,1) - Post_Err = True - return(1) - - # Statistics for all ABBR in article - stats_abbrs_p = stats_abbrs_p + stats_counter(abbr_name) - - abbr_nbr = 'abbr_%s'%stats_abbrs_uniq - abbr = ( - abbr_name, - abbr_alt, - abbr_rep - ) - globals()[abbr_nbr] = abbr - -#============================# -# Check marker's 3rd line # -# if new marker, or empty # -# for every optional markers # -#----------------------------# -def check_new_marker(line3): - global new_marker - - new_marker = False - - for marker in markers_opt: - if line3.startswith(marker) or line3.startswith('#'): - new_marker = True - -#=================# -# ARTICLE CONTENT # -#=================# -#=====================================# -# Main for all markers to check # -# Loop into header post, till '-----' # -#-------------------------------------# -def check_article_markers(article): - global Post_Err - global stats_p, stats_bcodes, stats_anchors, stats_quotes - global stats_lists, stats_lists_u, stats_lists_o - global stats_titles, stats_comments - - stats_p = stats_pe = stats_qe = stats_le = 0 - stats_lists = stats_lists_u = stats_lists_o = 0 - stats_anchors = stats_quotes = 0 - precode = False # Do not treat line if in precode: (( - - #------------------------ - # Loop lines from article - #------------------------ - for ln, line in enumerate(article.rsplit('\n'), 1): - - # Do not check line if in precode: [[ and ]] - if re.match(markers_reg[2][0], line): precode = True - elif re.match(markers_reg[2][1], line): precode = False - if precode: continue - - #------------------------- - # Markers at begining line - #------------------------- - # Paragraphs: ( and ) - if re.match(markers_reg[0][0], line): stats_p += 1 - elif re.match(markers_reg[0][1], line): stats_pe += 1 - - # Lists: (- and -) ; count items with = and + at begining - elif re.match(markers_reg[3][0], line): stats_lists += 1 - elif re.match(markers_reg[3][1], line): stats_le += 1 - elif line.startswith('='): stats_lists_u +=1 - elif line.startswith('+'): stats_lists_o +=1 - - # Anchors: <: - elif re.match(m_anchor, line): - try : css = line.split(' ')[1] - except: css = '' - if not css: - msg_log = 'Line %s. Unused anchor ID: ">> ID"'%(ln+headers_ln) - log.append_f(post_logs,msg_log,1) - Post_Err = True - else: - stats_anchors += 1 - - # Quotes - elif re.match(markers_reg[1][0], line): stats_quotes += 1 - elif re.match(markers_reg[1][1], line): stats_qe += 1 - - # Check if referenced in header for markers - for marker in '_image:', '_code:', '_brut:': - if re.match(r'^%s'%marker, line): - m_name = line.split(':')[1].split(' ')[0] - marker_h = marker[1:len(marker)] - if not re.findall(r'\b%s\s+%s\b'%(marker_h, m_name), headers): - msg_log = 'Line %s. Unused marker "%s %s" in header'%( - ln+headers_ln, marker_h, m_name - ) - log.append_f(post_logs, msg_log, 1) - Post_Err = True - - #------------------------------ - # Check valid contents markers - #------------------------------ - # Paragraphs - if stats_p != stats_pe: - msg_log = 'Unpaired paragraph markers: %s "(" and %s ")"'%( - stats_p, stats_pe - ) - log.append_f(post_logs,msg_log,1) - Post_Err = True - - # Precodes - if stats_bcodes != stats_ce: - msg_log = 'Unpaired precode markers: %s "[[" and %s "]]"'%( - stats_bcodes, stats_ce - ) - log.append_f(post_logs,msg_log,1) - Post_Err = True - - # lists - if stats_lists != stats_le: - msg_log = 'Unpaired list markers: %s "-(" and %s "-)"'%( - stats_lists, stats_le - ) - log.append_f(post_logs,msg_log,1) - Post_Err = True - - # Quotes - if stats_quotes != stats_qe: - msg_log = 'Unpaired quote markers: %s "((" and %s "))"'%( - stats_quotes, stats_qe - ) - log.append_f(post_logs,msg_log,1) - Post_Err = True - - #------------------------------------ - # Markers in text (strongs, bolds...) - #------------------------------------ - global m_stats - # Markers around words - m_words = ('*_', '_*', - '+_', '_+', - '/_', '_/', - '~_', '_~', - '×_', '_×', - '-_', '_-', - '(_', '_)', - '<_', '_>', - '\\_', '_\\', - '=_', '_=', - '>_', '_<' - ) - # Init words markers statistics - m_stats = ['0', '0', - '0', '0', - '0', '0', - '0', '0', - '0', '0', - '0', '0', - '0', '0', - '0', '0', - '0', '0', - '0', '0', - '0', '0' - ] - # markers Names (Only used for logs) - m_names = ('strong', - 'bold', - 'emphasis', - 'deletion', - 'custom', - 'underline', - 'iCode', - 'iCode', - 'italics', - 'cite', - 'link anchor' - ) - - # Count markers, get, check and set stats. - pos = pos_name = 0 - for marker in m_words: - m_stats[pos] = article.count(marker) - #print(marker, m_stats) - if pos % 2 != 0: - if m_stats[pos-1] != m_stats[pos]: - msg_log = 'Unpaired %s markers %s "%s" and %s "%s"'%( - m_names[pos_name], - m_stats[pos-1], m_words[pos-1], - m_stats[pos], m_words[pos] - ) - log.append_f(post_logs,msg_log,1) - Post_Err = True - pos_name += 1 - pos += 1 - # Add specific alternative iCode '<_','_>' to legacy iCode stats - m_stats[12] = m_stats[12] + m_stats[14] - -#======================================================# -# Thses markers needs ref line, in case invalid # -# As bCodes needs convertion, they must be check first # -# Done after post_to_strings # -# Also count stats: bCodes, titles, comments # -#------------------------------------------------------# -def check_article_titles(article): - global Post_Err - global stats_bcodes, stats_ce - global stats_comments, stats_titles - - stats_bcodes = stats_ce = 0 - stats_comments = stats_titles = 0 - precode = False - - #------------------------ - # Loop lines from article - #------------------------ - for ln, line in enumerate(article, 1): - - # Do not check line if in precode: [[ and ]] - if re.match(markers_reg[2][0], line): - precode = True - stats_bcodes += 1 - elif re.match(markers_reg[2][1], line): - precode = False - stats_ce += 1 - if precode: continue - - # Titles - if line.startswith(r'#'): - Title_Err = False - title = line.split(' ', 1) - ht = line[1] - - # Check title marker #[1-6] - if ht == ' ' or ht == '#': - stats_comments += 1 - continue - - # Title number not in range - elif ht.isdigit(): - if not int(ht) in range(1,7): - msg_log = 'Line %s. Mismatch title number "%s" (1-6)'%( - ln + headers_ln, ht) - log.append_f(post_logs,msg_log,1) - Post_Err = True - continue - - # Not a digit in marker title - else: - msg_log = 'Line %s. Mismatch title number "%s" (1-6)'%( - ln + headers_ln, ht) - log.append_f(post_logs,msg_log,1) - Post_Err = True - continue - - # Check description's title - try: - title[1] - if not title[1] or title[1] == ' ': Title_Err = True - else : stats_titles += 1 - except: - Title_Err = True - - if Title_Err: - msg_log = 'Line %s. Unused title description "%s ??"'%( - ln + headers_ln, title[0] - ) - log.append_f(post_logs,msg_log,1) - Post_Err = True + web_uri = '/' + fileuri.replace(domain_articles, "") #===========================# -# Check links anchors # -# (if '>> ID' is registred) # +# Check tags in post_bottom # #---------------------------# -def check_links_anchors(article): - global Post_Err - - anchors_link = re.findall(r'\>_(.*?)_\<', article) - for anchor in anchors_link: - anchor_id = anchor.rsplit(':',1)[0] - if not re.search(r'\>\> %s'%anchor_id, article): - msg_log = 'Unused anchor ID ">> %s" from link "%s"'%( - anchor_id, anchor - ) - log.append_f(post_logs,msg_log,1) - Post_Err = True - -#====================================# -# Check inside list for only + and = # -# Multilines for one marker list # -# MUST have at leat one space (\s) # -#------------------------------------# -def check_lists_contents(article): - global Post_Err +def check_content(post_bottom): + global post_err + global article_bottom + # Check tags for words (strongs, italics...) + # Set stats for each one + #------------------------------------------- + for tag in tyto.words_tags: + c_opened = c_closed = 0 + + if tag[5] == 'w': + c_opened = article_bottom.count(tag[0]) + c_closed = article_bottom.count(tag[1]) + # Useless tag now, replace + article_bottom = article_bottom.replace(tag[0], '') + article_bottom = article_bottom.replace(tag[1], '') + elif tag[5] == 't': + for line in post_bottom: + if line.startswith(tag[0]): c_opened += 1 + if line.startswith(tag[1]): c_closed += 1 + + if c_opened != c_closed: + tyto.exiting("8", '%s: %s %s'%(tag[4], tag[0], tag[1]), False) + post_err = True + return # Useless and could code errors to check nexts + else: + globals()['post_%s'%tag[4]] = int(c_opened) + + + # Check if anchor has target + # Count anchors target + #--------------------------- + global stat_ancs + stat_ancs = 0 + + for line in post_bottom: + if line.startswith(tyto.single_tags[1][0]): stat_ancs += 1 + if tyto.words_tags[0][0] and tyto.words_tags[0][1] in line: + anchors = re.findall(r">_(.*?)_<", line) + for anchor in anchors: + css_anchor = anchor.rsplit(':')[0] + tag = '%s %s'%(tyto.single_tags[1][0], css_anchor) + if not tag in post_bottom: + tyto.exiting("6", 'anchor, %s'%tag, False) + post_err = True + + + # Check if content list is valid + #------------------------------- inlist = False - - for line in article: + markers_lists = '%s, %s, or space'%( + tyto.markers_lists[0], + tyto.markers_lists[1] + ) + for ln, line in enumerate(article.rsplit('\n'), 1): + if line.startswith('-('): inlist = True;continue + elif line.startswith('-)'): inlist = False + if not inlist: continue - if re.match(markers_reg[3][0], line): - inlist = True - continue - elif re.match(markers_reg[3][1], line): - inlist = False - - if inlist and not re.match(r'^\+|^\=|\s', line): - msg_log = 'Content list not "+" or "=": %s'%line - log.append_f(post_logs, msg_log, 1) - Post_Err = True - -#====================================# -# Create Database file for this Post # -#------------------------------------# -def create_DB(post_db): - # Create NEW database for article - file = open(post_db, "w") - file.write('') - file.close() + if not line[0] in tyto.markers_lists: + tyto.exiting("3", 'line %s must start with %s'%( + ln, markers_lists + ), False) + post_err = True + - # time of check at creating DB - global time_chk - time_chk = log.nowdate() +#===============================================# +# Create new article's database at each check ! # +#-----------------------------------------------# +def create_database(): + web_uri = tyto.web_uri[1: len(tyto.web_uri)] + if tyto.web_uri.endswith('index.html'): tyto.web_uri = '/' + database = '# Post Configuration for Tyto\n' + \ + 'post_id = "%s"\n'%tyto.uri_id + \ + 'root_uri = "%s"\n'%tyto.uri_root + \ + 'wip_uri = "%s%s"\n'%(srv_wip, web_uri) + \ + 'www_uri = "%s%s"\n'%(srv_www, web_uri) + \ + 'http_uri = "%s"\n'%tyto.web_uri + \ + 'hash_wip = ""\n' + \ + 'date_www = ""\n' + \ + 'hash_www = ""\n' + \ + 'date_chk = "%s"\n'%tyto.nowdate() + \ + 'hash_chk = "%s"\n'%tyto.hash_post + \ + 'date_wip = ""\n' + \ + '\n# Post configuration from needed tags\n' + \ + 'title = "%s"\n'%title + \ + 'about = "%s"\n'%about + \ + 'author = "%s"\n'%author + \ + 'tags = "%s"\n'%tags + \ + 'date = %s\n'%str(date) + \ + '\n# Post configuration from optional tags' + + if stat_abbrs > 0: + for i in range(1, stat_abbrs + 1): + database = '%sabbr_%s = %s'%( + database, i, globals()['abbr_%s'%i] + ) - # Specific statistics for links (add all) - stats_links = stats_links_p + stats_files_p + stats_images_p + if stat_links > 0: + for i in range(1, stat_links + 1): + database = '%s\nlink_%s = %s'%( + database, i, globals()['link_%s'%i] + ) - # log - msg_log = 'Create Database: %s'%post_db - log.append_f(post_logs, msg_log, 0) + if stat_images > 0: + for i in range(1, stat_images + 1): + database = '%s\nimage_%s = %s'%( + database, i, globals()['image_%s'%i] + ) - # Main Post Conf - lines_conf = ( - '# Domain', - 'post_domain = "%s"'%domain.domain_name, - '\n# Metas & URIs', - 'post_file = "%s"'%post_uri, - 'post_ID = "%s"'%curr_post_ID, - 'post_db = "%s"'%post_db, - 'post_tmp = "%s"'%post_tmp, - 'post_dir = "%s"'%post_dir, - 'post_url = "%s"'%post_url, - 'post_srv = "%s"'%post_srv, - 'web_uri = "%s"'%weburi, - '\n# Article Status', - 'post_chk = (\'%s\', \'%s\')'%(hash_chk,time_chk), - 'post_wip = (\'%s\', \'%s\')'%(hash_wip,time_wip), - 'post_www = (\'%s\', \'%s\')'%(hash_www,time_www), - '\n# Mandatory Headers', - 'post_title = "%s"'%title[2], - 'post_about = "%s"'%about[2], - 'post_tags = "%s"'%tags[2], - 'post_date = "%s"'%date[2], - 'post_check = "%s" # └+CheckTime'%date_check, - 'post_author = "%s"'%author[2], - '\n# Optional Headers' - ) - for line_conf in lines_conf: - domain.append_f(post_db, line_conf) + if stat_files > 0: + for i in range(1, stat_files + 1): + database = '%s\nfile_%s = %s'%( + database, i, globals()['file_%s'%i] + ) - # Optional headers to Post conf - # Add every "link:" array found to DB, one per line - if stats_links_uniq > 0: - for n in range(1,stats_links_uniq+1): - m = 'link_%s'%n - domain.append_f(post_db,'%s = %s'%(m,globals()[m])) + if stat_bruts > 0: + for i in range(1, stat_bruts + 1): + database = '%s\nbrut_%s = %s'%( + database, i, globals()['brut_%s'%i] + ) - # Add every "file:" array found to DB, one per line - if stats_files_uniq > 0: - for n in range(1, stats_files_uniq+1): - m = 'file_%s'%n - domain.append_f(post_db, '%s = %s'%(m,globals()[m])) - - # Add every "image:" array found to DB, one per line - if stats_images_uniq > 0: - for n in range(1, stats_images_uniq+1): - m = 'image_%s'%n - domain.append_f(post_db, '%s = %s'%(m,globals()[m])) - - # Add every "image:" array found to DB, one per line - if stats_bruts_uniq > 0: - for n in range(1, stats_bruts_uniq+1): - m = 'brut_%s'%n - domain.append_f(post_db, '%s = %s'%(m,globals()[m])) - - # Add every "abbr:" array found to DB, one per line - if stats_abbrs_uniq > 0: - for n in range(1, stats_abbrs_uniq+1): - m = 'abbr_%s'%n - domain.append_f(post_db, '%s = %s'%(m,globals()[m])) - - # Statistics Post conf - lines_conf = '' - lines_conf = ( - '\n# Statistics (Uniq)', - 'links_u = %d'%stats_links_uniq, - 'files_u = %d'%stats_files_uniq, - 'images_u = %d'%stats_images_uniq, - 'bruts_u = %d'%stats_bruts_uniq, - 'abbrs_u = %d'%stats_abbrs_uniq, - '\n# Statistics (Wordings)', - 'strongs = %d'%m_stats[0], - 'bolds = %d'%m_stats[2], - 'emphasis = %d'%m_stats[4], - 'italics = %d'%m_stats[16], - 'cites = %d'%m_stats[18], - 'deletions = %d'%m_stats[6], - 'customs = %d'%m_stats[8], - 'underlines = %d'%m_stats[10], - 'icodes = %d'%m_stats[12], - '\n# Statistics (Links)', - 'links = %d'%stats_links, - 'links_p = %d'%stats_links_p, - 'files_p = %d'%stats_files_p, - 'images_p = %d'%stats_images_p, - 'bruts_p = %d'%stats_bruts_p, - 'abbrs_p = %d'%stats_abbrs_p, - '\n# Statistics (Templates)', - 'titles = %d'%stats_titles, - 'anchors = %d'%stats_anchors, - 'paragraphs = %d'%stats_p, - 'quotes = %d'%stats_quotes, - 'lists = %d'%stats_lists, - 'lists_u = %d'%stats_lists_u, - 'lists_o = %d'%stats_lists_o, - 'precodes = %d'%stats_bcodes, - 'comments = %d'%stats_comments - ) - for line_conf in lines_conf: - domain.append_f(post_db, line_conf) + db_stats = '\n# Statistics from optional tags\n' + \ + 'uniq_anchors = %s\n'%(int(stat_ancs)) + \ + 'uniq_abbrs = %s\n'%(int(stat_abbrs)) + \ + 'uniq_links = %s\n'%(int(stat_links)) + \ + 'uniq_images = %s\n'%(int(stat_images)) + \ + 'uniq_files = %s\n'%(int(stat_files)) + \ + 'uniq_bruts = %s\n'%(int(stat_bruts)) + \ + '\n# Statistics from post content\n' + \ + 'stat_tags = %s\n'%(int(post_tags)) + \ + 'stat_words = %s\n'%(int(post_words)) + \ + 'stat_titles = %s\n'%(int(tyto.nbr_titles)) + \ + 'stat_paragraphs = %s\n'%(int(post_paragraphs)) + \ + 'stat_anchors = %s\n'%(int(post_anchors)) + \ + 'stat_strongs = %s\n'%(int(post_strongs)) + \ + 'stat_bolds = %s\n'%(int(post_bolds)) + \ + 'stat_emphasis = %s\n'%(int(post_emphasis)) + \ + 'stat_italics = %s\n'%(int(post_italics)) + \ + 'stat_dels = %s\n'%(int(post_dels)) + \ + 'stat_underlines = %s\n'%(int(post_underlines)) + \ + 'stat_cites = %s\n'%(int(post_cites)) + \ + 'stat_customs = %s\n'%(int(post_customs)) + \ + 'stat_codes = %s\n'%(int(tyto.nbr_codes)) + \ + 'stat_bcodes = %s\n'%(int(tyto.nbr_bcodes)) + \ + 'stat_quotes = %s\n'%(int(tyto.nbr_quotes)) + \ + 'stat_lists = %s\n'%(int(post_lists)) + + database = '%s\n%s'%(database, db_stats) + tyto.set_file(tyto.post_db, 'new', database) + tyto.exiting("21", '', True) diff --git a/src/var/lib/tyto/program/domain.py b/src/var/lib/tyto/program/domain.py index 6a65828..723dee6 100644 --- a/src/var/lib/tyto/program/domain.py +++ b/src/var/lib/tyto/program/domain.py @@ -1,9 +1,9 @@ #!/usr/bin/env python3 # Name: Tyto - Littérateur # Type: Global functions for domain -# Description: Add new domain, check domain dir... +# Description: Create/edit a domain # file: domain.py -# Folder: /var/lib/tyto/scripts/ +# Folder: /var/lib/tyto/program/ # By echolib (XMPP: im@echolib.re) # License: GNU AFFERO GENERAL PUBLIC LICENSE Version 3, 19 November 2007 @@ -17,139 +17,44 @@ #********************************************************************** -#======# -# MAIN # -#======# -import sys, os, subprocess, datetime -import check, log - -# Get user dir -home_dir = os.path.expanduser('~') - -# In Tyto DB dir -tyto_db = '%s/.local/tyto'%home_dir -tyto_domains = '%sdomains.conf'%tyto_db - -# In Tyto log dir -tyto_logs_dir = '/var/log/tyto/' -tyto_logs = '%styto.log'%tyto_logs_dir - -# Current dir -curr_dir = domain_articles = domain_logs = os.getcwd() - -# set domain configuration file from current directory -conf_domain = '%s/tyto_domain.conf'%curr_dir - -# Activation domain -domain_active = domain_conf = False - -# Set needed directories - -# Create Tyto logs -if not os.path.exists(tyto_logs): - file = open(tyto_logs, "w") - file.write('') - file.close() - msg_log = 'Log > Create logs file for Tyto in %s\n'%tyto_logs - log.append_f(tyto_logs, msg_log, 0) - -# Get database domains -# If not exists, create the file conf -# Will receive all domain registred -try: - exec(open(tyto_domains).read()) -except: - domains_file = open(tyto_domains, 'w') - domains_file.write("# Tyto's file with all activated domains\n") - domains_file.close() - -domains_db = open(tyto_domains,'r').read() - -# Get user domain configuration file -# If exists, set to True, and exec -try: # os.path.exists(conf_domain): - exec(open(conf_domain).read()) - datas_domain = open(conf_domain, "r").read() - if domain_active: print(':D Activated domain: "%s"'%domain_name) - else : print(':/ Not activated domain in',conf_domain) -except: - print(':< Unused domain file:', conf_domain) - -#=======# -# Tools # -#=======#-------------------------------------------------------------- -#===========================# -# Append new line to a file # -#---------------------------# -def append_f(f, line_val): - file = open(f, "a") - file.write('%s\n'%line_val) - file.close() - -#======================================# -# Just a generic exit # -# out defines message, not exit status # -# for process form: " -# - rename temp domain conf to legacy # -#--------------------------------------# -def exiting(process, out, msg): - msgs = [ - ':D All done !', - ':/ Maybe next time...', - '%s'%msg - ] - - if process == 'form': - os.rename(temp_domain, conf_domain) - - print(msgs[out]) - sys.exit(0) - +import os, locale +import tyto #==========================# # Manage Argument 'domain' # -#==========================#------------------------------------------- -def manage_domain(Domain, Opt): - if not Opt: - try: print('\n',datas_domain) # No option: get domain and print it - except: sys.exit(0) - - elif Opt == 'New': - try: set_domain = Domain # Domain NAME is defined in CLI - except: set_domain = '' - - add_domain(set_domain) +#--------------------------# +def manage_domain(target, option): + if option == 'Edit': + if tyto.domain_exists: + print(":D Edit domain configuration file:", tyto.domain_conf) + tyto.edit_file(tyto.domain_conf) - elif Opt == 'Edit': - if domain_conf: - print(':> Editing',domain_conf) - old_conf_ID = check.get_filesum(domain_conf, True) - edit_domain = subprocess.run(['/usr/bin/nano', - '--linenumbers', - domain_conf]) - - # Compare before and after domain conf file - new_conf_ID = check.get_filesum(domain_conf,True) - if not old_conf_ID == new_conf_ID: - exiting('root', 2, ':D Updated domain configuration file.') - else: - exiting('root', 2, ':D Unchanged domain configuration file.') + if option == 'New': + if not tyto.domain_exists: + create_domain(target) else: - sys.exit(0) + print(':) A domain exists in this directory') + ask = input('-> Edit it with the form ? ') + if ask in ['y', 'Y']: create_domain(target) + else: tyto.exiting("255", '', True) + + +#=====================# +# Check target if URL # +#---------------------# +def isurl(target): + global url + if target.startswith('http'): + url = target + else: + tyto.exiting("2", target, True) + +#=====================# +# Create a new domain # +#---------------------# +def create_domain(target): + if target: isurl(target) -#===================================# -# Main fonction to add a new domain # -# Check first, if it already exists # -# Domain not activated: # -# - Show registred values in form # -#-----------------------------------#---------------------------------- -def add_domain(set_domain): - # Exit if a domain already exists - if domain_active: sys.exit(0) - - global temp_domain - temp_domain = '%s/tyto_domain.tmp'%curr_dir - print('\n' ' ┌──────────────────────────────────────────────┐\n' ' │ Configure a new domain for current directory │\n' @@ -160,406 +65,349 @@ def add_domain(set_domain): ' ├──────────────────────────────────────────────┘' ) - # Create new temp conf file - # Used to prepare values, leaving legacy conf file - file = open(temp_domain, "w") - file.write('# Tyto Configuration Domain\n') - file.close() - # Domain is or not given in CLI. - # Start form - if set_domain: - domain_input_confirn(set_domain) - domain_form() - else: - domain_input() - domain_form() - - # End of form. - # Show resume's domain configuration from temp conf file - print('\n' - ' ┌─────────────────────────────┐\n' - ' │ Please check domain datas...│\n' - ' ├─────────────────────────────┘' - ) - with open(temp_domain, "r") as file: - post_temp = file.read() - for line in post_temp.split('\n'): - print(' │ %s'%line) - file.close() - - # Ask to confirm to write activation domain - print(' ├─────────────────────────────') - confirm = input(' └ Activate domain configuration ? ') - if confirm in ['y', 'Y']: create_domain() - else : exiting('form', 1, '') - -#==============# -# Get protocol # -#--------------# -def get_protocol(set_domain): - global domain_protocol - domain_protocol = '' + # Get complete URL from target or ask + #------------------------------------ + try: domain_url = tyto.domain_url + except: domain_url = '' - # check protocol https, http - if set_domain.startswith('https://'): domain_protocol = 'https://' - elif set_domain.startswith('http://') : domain_protocol = 'http://' + ask = '' + ask = input(' ├ [HTTP...] URL to website ? ("%s") '%domain_url) + if ask: + isurl(ask) + domain_url = url + elif not domain_url: + tyto.exiting("255", '', True) - if domain_protocol: - set_domain = set_domain.replace(domain_protocol,"") - else: - confirm = input(' ├ Use "https" ? ') - if confirm in ['y', 'Y']: domain_protocol = 'https://' - else : domain_protocol = 'http://' - -#==============================# -# If domain name is set in CLI # -# Confirm process # -#------------------------------# -def domain_input_confirn(set_domain): - global domain_name + domain_short = domain_url.rsplit('://')[1] - get_protocol(set_domain) - - confirm = input(' ├ Add Domain (%s) here ? '%set_domain) - if confirm in ['y', 'Y']: - # Check if domain already registred - isdomain = set_domain.replace('.','_') - if isdomain in domains_db: - dom_folder = globals().get(isdomain,False) - if dom_folder and not dom_folder == curr_dir: - exiting('root', 2, '\n:/ Domain exists in %s'%dom_folder) - domain_name = set_domain - else: - exiting('root', 1, '') - -#=====================# -# Add new domain_name # -#---------------------# -def domain_input(): - global domain_name, domain_protocol - set_domain = input(' ├ Enter Domain Name: ') - - if not set_domain: exiting('root', 1, '') - else : domain_name = set_domain - - domain_protocol = '' - get_protocol(set_domain) - - -#====================# -# Domain FORM # -# domain_name is set # -# Configure domain # -#--------------------# -def domain_form(): - - # First settings to put in temp_domain config file - domain_db = '%s/%s/articles/'%(tyto_db,domain_name) - domain_logs = '%s%s/'%(tyto_logs_dir,domain_name) - domain_articles = '%s/articles/'%curr_dir - domain_images = '%simages/'%domain_articles - domain_files = '%sfiles/'%domain_articles - domain_url = '%s%s'%(domain_protocol, domain_name) - - append_f(temp_domain,'domain_conf = "%s"'%conf_domain) - append_f(temp_domain,'domain_db = "%s"'%domain_db) - append_f(temp_domain,'domain_logs = "%s"'%domain_logs) - append_f(temp_domain,'\n# Article directories') - append_f(temp_domain,'domain_dir = "%s"'%curr_dir) - append_f(temp_domain,'domain_articles = "%s"'%domain_articles) - append_f(temp_domain,'domain_files = "%s"'%domain_files) - append_f(temp_domain,'domain_images = "%s"'%domain_images) - - # ----------------------- # - # Starting Form # - # Some values are defaut # - # Values can be registred # - # from legacy conf file # - # ----------------------- # - - # Local server Directory - # ---------------------- - global srv, srv_wip, srv_wip_files, srv_wip_images, srv_wip_template - global srv_www, srv_www_files, srv_www_images, srv_wip_template - - try: srv - except: srv = '/var/www' - - set_srv = input(' ├ Local server directory (%s) ? '%srv) - if not set_srv and not srv: - exiting('form',1,'') - if set_srv and set_srv[-1] == '/': - srv = set_srv[:-1] - - if not os.path.exists(srv): - exiting('form',2,'\n:< Unsed directory "%s"'%srv) - - # Settings for server - srv_domain = '%s/%s/'%(srv,domain_name) - srv_wip = '%s/%s/wip/'%(srv,domain_name) - srv_wip_files = '%s/%s/wip/files/'%(srv,domain_name) - srv_wip_images = '%s/%s/wip/images/'%(srv,domain_name) - srv_wip_template = '%s/%s/wip/template/'%(srv,domain_name) - srv_www = '%s/%s/www/'%(srv,domain_name) - srv_www_files = '%s/%s/www/files/'%(srv,domain_name) - srv_www_images = '%s/%s/www/images/'%(srv,domain_name) - srv_www_template = '%s/%s/www/template/'%(srv,domain_name) - - # Write settings to temp_omain - append_f(temp_domain,'\n# Server directories') - append_f(temp_domain,'srv = "%s"'%srv) - append_f(temp_domain,'srv_domain = "%s"'%srv_domain) - append_f(temp_domain,'srv_wip = "%s"'%srv_wip) - append_f(temp_domain,'srv_wip_files = "%s"'%srv_wip_files) - append_f(temp_domain,'srv_wip_images = "%s"'%srv_wip_images) - append_f(temp_domain,'srv_wip_template = "%s"'%srv_wip_template) - append_f(temp_domain,'srv_www = "%s"'%srv_www) - append_f(temp_domain,'srv_www_files = "%s"'%srv_www_files) - append_f(temp_domain,'srv_www_images = "%s"'%srv_www_images) - append_f(temp_domain,'srv_www_template = "%s"'%srv_www_template) - - # Domain Title for website - # ------------------------ - global domain_title + # Prefix wip + #----------- try: - domain_title - show_title = domain_title[:14] + '...' + try_wipurl = target.rsplit('.') + try_wipurl = 'https://www-wip.%s.%s'%(try_wipurl[1], try_wipurl[2]) except: - domain_title = show_title = '' - - set_title = input(' ├ Domain Title (%s) ? '%show_title) - if not set_title and not domain_title: - exiting('form',1,'') - if set_title: - domain_title = set_title - if '"' in domain_title: - domain_title = domain_title.replace('"','\\"') + try_wipurl = 'https://www-wip.%s'%target - append_f(temp_domain,'\n# Domain datas for web pages') - append_f(temp_domain,'domain_name = "%s"'%domain_name) - append_f(temp_domain,'domain_protocol = "%s"'%domain_protocol) - append_f(temp_domain,'domain_url = "%s"'%domain_url) - append_f(temp_domain,'domain_title = "%s"'%domain_title) + try: domain_wipurl = tyto.domain_wipurl + except: domain_wipurl = try_wipurl - # Separator Pages Titles (default '-') - # ------------------------------------ - global sep_titles - try: sep_titles - except: sep_titles = '-' + ask = '' + ask = input(' ├ URL to wip ? ("%s") '%domain_wipurl) + if ask: + isurl(ask) + domain_wipurl = ask - set_sep = input(' ├ Website pages separator (%s) ? '%sep_titles) - if set_sep: - if len(set_sep) > 2: - exiting('form', 2, '\n:< Seperator is 2 characters max') - sep_titles = set_sep + + db_dir = '%s/.local/tyto/'%tyto.home_dir + conf_domain = 'domain_conf = "%s"\n'%tyto.domain_conf + \ + 'domain_db = "%s/%s/articles/"\n'%(db_dir, target) + \ + 'domain_dir = "%s/"\n'%tyto.in_dir + \ + 'domain_articles = "%s/articles/"\n'%tyto.in_dir + \ + 'domain_files = "%s/articles/files/"\n'%tyto.in_dir + \ + 'domain_images = "%s/articles/images/"\n'%tyto.in_dir + \ + '\ndomain_short = "%s"\n'%domain_short + \ + 'domain_url = "%s"\n'%domain_url + \ + 'domain_wipurl = "%s"\n'%domain_wipurl + + tyto.set_file(tyto.domain_conf, True, conf_domain) + - append_f(temp_domain,'sep_titles = "%s"'%sep_titles) - - # Domain description - # ------------------ - global domain_about - try: - domain_about - show_about = domain_about[:14] + '...' - except: - domain_about = show_about = '' - - set_about = input(' ├ Domain description (%s) ? '%show_about) - if not set_about and not domain_about: exiting('form',1,'') - if set_about: domain_about = set_about - if '"' in domain_about: domain_about = domain_about.replace('"','\\"') + # Get title domain + #----------------- + try: domain_title = tyto.domain_title + except: domain_title = '' - append_f(temp_domain,'domain_about = "%s"'%domain_about) + ask = '' + ask = input(' ├ Domain title ? ("%s") '%domain_title) + if ask: domain_title = ask + elif not domain_title: tyto.exit("255") + if '"' in domain_title: domain_title=domain_title.replace('"', '\\"') - # Lang for HTML Pages - # ------------------- - global domain_lang - try: - domain_lang - except: - # Get default system language (2/3 chars for HTML) - import locale - domain_lang = locale.getdefaultlocale()[0].split('_')[0] + tyto.set_file(tyto.domain_conf, False, + 'domain_title = "%s"'%domain_title) + + + # Get Description domain + #----------------------- + try: domain_about = tyto.domain_about + except: domain_about = '' - set_lang = input(' ├ Website HTML lang (%s) ? '%domain_lang) - if set_lang: - if len(set_lang) > 3: - exiting('form',2,'\n:< HTML Lang is 3 characters max') - domain_lang = set_lang + ask = '' + ask = input(' ├ Domain Description ? ("%s") '%domain_about) + if ask: domain_about = ask + elif not domain_about: tyto.exit("255") + if '"' in domain_about: domain_about=domain_about.replace('"', '\\"') - append_f(temp_domain,'domain_lang = "%s"'%domain_lang) + tyto.set_file(tyto.domain_conf, False, + 'domain_about = "%s"'%domain_about) - # Domain CSS (prefix class). alphanum only - # ---------------------------------------- - global domain_css - try: - domain_css - except: - domain_css = 'tyto' + + # Get Lang domain + #---------------- + try: domain_lang = tyto.domain_lang + except: domain_lang = locale.getdefaultlocale()[0].split('_')[0] - set_css = input(' ├ Generic CSS class (%s) ? '%domain_css) - if set_css: - domain_css = set_css - if not domain_css.isalnum(): - css_alnum = ''.join(c for c in domain_css if c.isalnum()) - domain_css = css_alnum - - append_f(temp_domain,'domain_css = "%s"'%domain_css) - - # Domain mail - # ----------- - global domain_mail - try: - domain_mail - show_mail = domain_mail[:14] + '...' - except: - domain_mail = show_mail = '' - - set_mail = input(' ├ Contact admin mail (%s) ? '%show_mail) - if not set_mail and not domain_mail: exiting('form', 1, '') - if set_mail: - if not '@' and not '.' in set_mail: - exiting('form', 2, '\n:< Invalid mail format (x@x.x)') - domain_mail = set_mail - elif not domain_mail: - exiting('form', 2, '\n:< Mail is required.') - - append_f(temp_domain,'domain_mail = "%s"'%domain_mail) - - # Domain Tags - # ----------- - global domain_tags - try: - domain_tags - show_tags = domain_tags[:14] + '...' - except: - domain_tags = show_tags = '' - - set_tags = input(' ├ Domain Tags [x,y] (%s) ? '%show_tags) - if not set_tags and not domain_tags: exiting('form', 1, '') - if set_tags: domain_tags = set_tags - - append_f(temp_domain,'domain_tags = "%s"'%domain_tags) - - # Webpages Copyright - # ------------------ - global domain_license - try: - domain_license - show_license = domain_license[:14] + '...' - except: - domain_license = show_license = 'CC BY-NC-SA' + ask = '' + ask = input(' ├ [2 characters] Website language ? ("%s") '%domain_lang) + if ask: + if len(ask) == 2: domain_lang = ask + else: tyto.exiting("3", ask, True) + elif not domain_lang: tyto.exiting("255", '', True) - set_license = input(' ├ Website copyright (%s) ? '%show_license) - if set_license: domain_license = set_license + tyto.set_file(tyto.domain_conf, False, + 'domain_lang = "%s"'%domain_lang) + + + # Get mail domain + #---------------- + try: domain_mail = tyto.domain_mail + except: domain_mail = '' + + ask = '' + ask = input(' ├ Webmaster\'s mail ? ("%s") '%domain_mail) + if ask: + if not "@" in ask and not "." in ask: tyto.exiting("3", ask, True) + domain_mail = ask + elif not domain_mail: tyto.exiting("255", '', True) + + tyto.set_file(tyto.domain_conf, False, + 'domain_mail = "%s"'%domain_mail) + + + # Get Tags domain + #---------------- + try: domain_tags = tyto.domain_tags + except: domain_tags = '' + + ask = '' + ask = input(' ├ [comma separated] Domain tags ? ("%s") '%domain_tags) + if ask: domain_tags = ask + elif not domain_tags: tyto.exiting("255", '', True) + + tyto.set_file(tyto.domain_conf, False, + 'domain_tags = "%s"'%domain_tags) + + + # Get License domain + #------------------- + try: domain_license = tyto.domain_license + except: domain_license = 'CC BY-NC-SA' + + ask = '' + ask = input(' ├ Domain License ? ("%s") '%domain_license) + if ask: domain_license = ask + elif not domain_license: tyto.exiting("255", '', True) if '"' in domain_license: - domain_license = domain_license.replace('"','\\"') - - append_f(temp_domain,'domain_license = "%s"'%domain_license) - - # Copyright URL - #-------------- - global domain_lic_url + domain_license=domain_license.replace('"', '\\"') - try: - domain_lic_url - show_license = domain_lic_url[:14] + '...' - except: - domain_lic_url = '' + tyto.set_file(tyto.domain_conf, False, + 'domain_license = "%s"'%domain_license) - set_lic_url = input(' ├ Copyright URL (%s) ? '%show_license) - if not set_lic_url and not domain_lic_url: - exiting('form', 2, '\n:< Copyright URL is required.') - elif set_lic_url: - set_lic_url: domain_lic_url = set_lic_url - append_f(temp_domain,'domain_lic_url = "%s"'%domain_lic_url) + # Get License URL + #---------------- + try: domain_licurl = tyto.domain_licurl + except: domain_licurl = '' + + ask = '' + ask = input(' ├ Optional. License URL ? ("%s") '%domain_licurl) + if ask: + if not ask.startswith('http'): tyto.exiting("3", ask, True) + domain_licurl = ask + + tyto.set_file(tyto.domain_conf, False, + 'domain_licurl = "%s"'%domain_licurl) + + + # CSS Prefix + #----------- + try: domain_css = tyto.domain_css + except: domain_css = 'tyto' + + ask = '' + ask = input(' ├ [alnum] Prefix CSS ? ("%s") '%domain_css) + if ask: + if not ask.isalnum(): tyto.exiting("3", ask, True) + domain_css = ask.lower() + + tyto.set_file(tyto.domain_conf, False, + 'domain_css = "%s"'%domain_css) + + + # Titles webpage separator + #------------------------- + try: domain_sep = tyto.domain_sep + except: domain_sep = "-" + + ask = '' + ask = input(' ├ [1 character] Pages titles separator ? ("%s") '%domain_sep) + if ask: + if not len(ask) == 1: tyto.exiting("3", ask, True) + domain_sep = ask + + tyto.set_file(tyto.domain_conf, False, + 'domain_sep = "%s"'%domain_sep) + # Sidebar Title - # ------------- - global sidebar_title - try: - sidebar_title - show_st = sidebar_title[:14] + '...' - except: - if 'fr' in domain_lang: sidebar_title = show_st = "À l'affiche !" - else : sidebar_title = show_st = "Featured !" - - set_st = input(' ├ Sidebar title (%s) ? '%show_st) - if set_st: sidebar_title = set_st + #-------------- + try: sidebar_title = tyto.sidebar_title + except: sidebar_title = tyto.trans[0][tyto.n] + + ask = '' + ask = input(' ├ Sidebar title ? ("%s") '%sidebar_title) + if ask: sidebar_title = ask if '"' in sidebar_title: - sidebar_title = sidebar_title.replace('"','\\"') + sidebar_title = sidebar_title.replace('"', '\\"') + + sidebar_conf = '%s/articles/sidebar/'%tyto.in_dir + sidebar_datas = '\nsidebar_dir = "%s"\n'%sidebar_conf + \ + 'sidebar_load = "%styto.sidebar"\n'%sidebar_conf + \ + 'sidebar_title = "%s"'%sidebar_title + + tyto.set_file(tyto.domain_conf, False, sidebar_datas) + + + # Sidebar Items + #-------------- + try: sidebar_items = tyto.sidebar_items + except: sidebar_items = "6" + + ask = '' + ask = input(' ├ [max=16] Sidebar Items ? ("%s") '%sidebar_items) + if ask: + if not ask.isdigit(): tyto.exiting("3", ask, True) + elif int(ask) in range(1,17): sidebar_items = int(ask) + + tyto.set_file(tyto.domain_conf, False, + 'sidebar_items = "%s"'%int(sidebar_items)) + + + + # Get srv root + #------------- + try: domain_srv = tyto.domain_srv + except: domain_srv = '/var/www' - # Sidbar items number. Default: 12 - # ------------------- - global sidebar_items - try: - sidebar_items - except: - sidebar_items = 8 + ask = '' + ask = input(' ├ System server ? ("%s") '%domain_srv) + if ask: + if not os.path.exists(srv): tyto.exiting("1", ask, True) + elif not domain_srv: tyto.exiting("255", '', True) - set_si = input(' ├ Sidebar max items [1-16] (%s) ? '%sidebar_items) - if set_si and set_si.isdigit(): - if set_si in range(1,16): - exiting('form',2,'\n:< Items number: 1-16') - sidebar_items = set_si - - # Domain LOGO (optional) - # ---------------------- - global domain_logo - try: - domain_logo - show_logo = domain_logo[:14] + '...' - except: - domain_logo = show_logo = '' + root_srv_dom = '%s/%s'%(domain_srv, domain_short) + srvs = '\nsrv_root = "%s/"\n'%domain_srv + \ + 'srv_domain = "%s/"\n'%root_srv_dom + \ + 'srv_wip = "%s/wip/"\n'%root_srv_dom + \ + 'srv_wip_tpl = "%s/wip/template/"\n'%root_srv_dom + \ + 'srv_wip_images = "%s/wip/images/"\n'%root_srv_dom + \ + 'srv_wip_files = "%s/wip/files/"\n'%root_srv_dom + \ + 'srv_www = "%s/www/"\n'%root_srv_dom + \ + 'srv_www_tpl = "%s/www/template/"\n'%root_srv_dom + \ + 'srv_www_images = "%s/www/images/"\n'%root_srv_dom + \ + 'srv_www_files = "%s/www/files/"'%root_srv_dom + tyto.set_file(tyto.domain_conf, False, srvs) - set_logo = input(' ├ Optional. Logo filename (%s) ? '%show_logo) - if set_logo: domain_logo = set_logo - append_f(temp_domain,'domain_logo = "%s"'%domain_logo) - # External URL profile (optional) - # ------------------------------- - global domain_exturl - try: - domain_exturl - show_e= domain_exturl[:14] + '...' - except: - domain_exturl = show_e = '' + # Activate Domain after Resumed configuration ? + #---------------------------------------------- + try: domain_active = tyto.domain_active + except: domain_active = False - set_e = input(' └ Optionnal. URL to a social network (%s) ? '%show_e) - if set_e: domain_exturl = set_e + file = open(tyto.domain_conf, 'r').read() + resume = ' │\n' + \ + ' ├──────────────────────────────────────┐\n' + \ + ' │ Please, READ the configuration datas │\n' + \ + ' ├──────────────────────────────────────┘' - append_f(temp_domain,'domain_exturl = "%s"'%domain_exturl) + print(resume) + + for line in file.rsplit('\n'): + print(' │', line) - # Adding sidebar conf - sidebar_dir = '%s/articles/sidebar/'%curr_dir - sidebar_load = '%styto.sidebar'%sidebar_dir - append_f(temp_domain,'\n# Sidebar') - append_f(temp_domain,'domain_sdb_dir = "%s"'%sidebar_dir) - append_f(temp_domain,'domain_sdb_load = "%s"'%sidebar_load) - append_f(temp_domain,'domain_sdb_title = "%s"'%sidebar_title) - append_f(temp_domain,'domain_sdb_items = "%s"'%sidebar_items) - -#==========================# -# If confirm activation # -# Add value to domain conf # -# Create all directories # -#--------------------------# -def create_domain(): - # Add activation var to temp domain conf - append_f(temp_domain,'\n# Domain activation') - append_f(temp_domain,'domain_active = True') + ask = input(' ├ Activate and prepare domain ? ') + if not ask in ['y', 'Y']: + tyto.set_file(tyto.domain_conf, False, + '\ndomain_active = False') + tyto.exiting("255", '', True) - # Add var domain_name to tyto_domains file, if not exists - domain_var = domain_name.replace('.','_') - if not domain_var in domains_db: - append_f(tyto_domains,'%s = "%s"'%(domain_var,curr_dir)) + # Activate Domain + #---------------- + tyto.set_file(tyto.domain_conf, False, + '\ndomain_active = True') - # Create all directories for this domain - check.create_domain_dirs('all') + # Load config + exec(open(tyto.domain_conf).read(),globals()) - # Will rename temp_domain conf to legacy domain conf file - exiting('form',2,'\n:D Activated domain: "%s"'%domain_name) + # Create sidebar + create_sidebar(opt, sidebar_dir) + + # Create folders from configuration file + folders = ( + srv_wip_tpl, srv_wip_images, srv_wip_files, + srv_www_tpl, srv_www_images, srv_www_files, + domain_files, domain_images, sidebar_dir, + domain_db, + ) + + print(' │') + for folder in folders: + if not os.path.exists(folder): + print(' ├ Create directory: %s'%folder) + if not os.makedirs(folder, exist_ok=True): + print(' │ Exists directory: %s'%folder) + + print(' │') + print(' ├──────────────────────────────────────┐') + print(' │ Domain is ready. Have fun, writers ! │') + print(' └──────────────────────────────────────┘') +#==============================# +# sidebar load file translated # +#------------------------------# +def create_sidebar(opt, sidebar_dir): + try: sidebar_load + except: sidebar_load = "%styto.sidebar"%sidebar_dir + + sdb_load_fr = '# Pour : Tyto - Littérateur\n' + \ + '# Type : fichier texte\n' + \ + '# Description : Fichier appelé par : tyto sidebar\n' + \ + '# Fichier : tyto.sidebar\n' + \ + '# Dossier : %s\n'%sidebar_dir + \ + '# Comment : 1 URI de l\'article par ligne\n' + \ + '# Ne commence pas par "/"\n' + \ + '# L\'ordre définit la position\n' + \ + '\n# %s\n'%(15 * "-") +\ + '# Exemples :\n' + \ + '# index.tyto\n' + \ + '# dir1/index.tyto\n' + \ + '# %s\n\n'%(15 * "-") + + sdb_load_en = '# For: Tyto - Littérateur\n' + \ + '# Type: Text file\n' + \ + '# Description: file called with: tyto sidebar\n' + \ + '# File: tyto.sidebar\n' + \ + '# Directory: %s\n'%sidebar_dir + \ + '# Comment: 1 article URI per line\n' + \ + '# not begining with "/"\n' + \ + '# Order in sidebar position\n' + \ + '\n# %s\n'%(15 * "-") +\ + '# Examples :\n' + \ + '# index.tyto\n' + \ + '# dir1/index.tyto\n' + \ + '# %s\n\n'%(15 * "-") + + if tyto.n == 0: sdb_load = sdb_load_fr + elif tyto.n == 1: sdb_load = sdb_load_en + + if not opt == 'Remove' and os.path.exists(sidebar_load): + ask = '' + ask = input(' ├ Initialize new sidebar ? ') + if not ask in ['y', 'Y']: + return + + tyto.set_file(sidebar_load, 'new', sdb_load) + + print(' ├ Create new file: %s'%sidebar_load) diff --git a/src/var/lib/tyto/program/html.py b/src/var/lib/tyto/program/html.py deleted file mode 100644 index 138d257..0000000 --- a/src/var/lib/tyto/program/html.py +++ /dev/null @@ -1,331 +0,0 @@ -#!/usr/bin/env python3 -# Name: Tyto - Littérateur -# Type: Global functions for HTML page -# Description: Create final HTML Page -# file: html.py -# Folder: /var/lib/tyto/programs/ -# By echolib (XMPP: im@echolib.re) -# License: GNU AFFERO GENERAL PUBLIC LICENSE Version 3, 19 November 2007 - -#------------ -# funny stats -#------------ -# lines: -# functions: -# comments: -#---------------------------------------------------------------------- - -#********************************************************************** - -import re, os -import check, log, domain - -page = '' -Tyto = 'Tyto - Littérateur' -tytogen = 'https://git.a-lec.org/echolib/tyto-litterateur' -tytourl = 'https://tyto.echolib.re' -trans = [ - [ 'Licence', 'License' ], # 0 - [ 'Générateur', 'Generator' ], # 1 - [ 'À propos de', 'About' ], # 2 - [ 'Envoyer un courriel à', 'Send a mail to' ], # 3 - [ 'Détails de la licence', 'License\'s details'], # 4 - [ 'Courriel', 'Mail' ], # 5 - [ 'Site web généré par %s'%Tyto, 'Website generated by %s'%Tyto ], # 6 - [ 'Syndication de', 'Syndication of' ], # 7 - [ 'Dépôt officiel de %s'%Tyto, 'Official repository of %s'%Tyto ], # 8 - [ 'Écrit par', 'Written by' ], # 9 - [ 'le ', 'on '], # 10 - [ 'Description de', 'Description of '], # 11 - [ 'sur', 'on'], # 12 - [ 'est l\'auteur de l\'article :', 'is the author of post:'] # 13 - ] - -#=======================================# -# Translations terms # -# Only FR (default) and Other (english) # -#---------------------------------------# -def translations(post_date): - global fl # fl = field lang - global sdb_date - - # Default FR/fr - if re.match('fr', domain.domain_lang, re.IGNORECASE): fl = 0 - else : fl = 1 - - # Change date format for FR - if fl == 0: - fr_date = post_date.rsplit('-') - post_date = fr_date[2] + '/' + fr_date[1] + '/' + fr_date[0] - sdb_date = post_date - -#========================# -# Create FULL HTML5 Page # -# includes wip.html # -#------------------------# -def html_main_page(wip_html): - global post_date, page - - # Source DB variables - post_db = exec(open(check.curr_post_db).read(),globals()) - - # Metas in HTML page - #------------------- - scale = 'width=device-width, initial-scale=1.0' - visit = '3 days' - title = '%s %s %s'%(post_title, domain.sep_titles, domain.domain_title) - tags = '%s,%s'%(domain.domain_tags, post_tags) - icon = '/template/favicon.png' - logo = '/template/%s'%domain.domain_logo - f_css = '%stemplate/styles.css'%web_uri - f_rss = '/rss.xml' - i_rss = 'RSS 2.0. %s %s %s'%( - domain.domain_title, domain.sep_titles, domain.domain_name - ) - - # If no logo - if not domain.domain_logo: - msg_log = 'Unregistred logo in configuration domain' - log.append_f(check.post_logs, msg_log, 1) - - # Check for template files (styles, logo...) - files_uri = ( - '%s%s'%(domain.srv_wip, icon[1:len(icon)]), - '%s%s'%(domain.srv_wip, f_css[1:len(f_css)]), - '%s%s'%(domain.srv_wip, logo[1:len(logo)]) - ) - for file_uri in files_uri: - if not os.path.exists(file_uri): - msg_log = 'Unused template file: %s'%file_uri - log.append_f(check.post_logs, msg_log, 1) - - # Set some terms from lang domain - translations(post_date) - - # External URL in metas (if exists in config domain) - if domain.domain_exturl: - relme = '\n'%( - domain.domain_exturl - ) - else: - relme = '' - - # Metas in HTML page - #------------------- - metas = '\n' + \ - '\n'%scale + \ - '\n' + \ - '\n' + \ - '\n'%visit + \ - '\n'%domain.domain_lang + \ - '\n'%domain.domain_mail + \ - '\n'%domain.domain_license + \ - '\n'%Tyto + \ - '\n'%title + \ - '\n'%post_author + \ - '\n'%post_about + \ - '\n'%tags + \ - '\n'%post_date + \ - '\n'%post_url + \ - '\n'%(f_rss, i_rss) + \ - '\n'%f_css + \ - '\n'%icon + \ - '%s'%relme + \ - '%s'%title - - - # header in HTML page - #-------------------- - headers = '
    \n'%domain.domain_css + \ - ' \n' + \ - '
    \n' + \ - '

    \n' + \ - ' %s\n'%( - domain.domain_title, - domain.sep_titles, - domain.domain_name, - domain.domain_title - ) + \ - '

    \n' + \ - '

    %s\n'%( - trans[11][fl], - domain.domain_title, - trans[12][fl], - domain.domain_url, - domain.domain_about - ) + \ - '

    \n' + \ - '
    \n' + \ - '
    \n' - - - # Article (in section) - #-------------------------------------- - articles = '
    \n' + \ - '
    \n'%( - post_ID, domain.domain_css - ) + \ - '
    \n' + \ - '

    \n' + \ - ' %s %s\n'%( - post_author, trans[13][fl], post_title, - trans[9][fl], post_author - ) + \ - ' , %s\n'%trans[10][fl] + \ - ' %s\n'%sdb_date + \ - '

    \n' + \ - '
    \n' - - - # Aside after article - #-------------------- - asides = '' - - - # Footer, and of page - #-------------------- - footers = '
    \n' + \ - '

    %s %s

    \n'%( - trans[2][fl], domain.domain_title) + \ - ' \n' + \ - ' \n' + \ - '
    ' - - - # Create file if not exists - #-------------------------- - files_tpl = [ - [ '%sheader.html'%domain.srv_wip_template, headers ], - [ '%sfooter.html'%domain.srv_wip_template, footers ] - ] - - for file_tpl in files_tpl: - if not os.path.exists(file_tpl[0]): - datas = open(file_tpl[0], 'w') - datas.write(file_tpl[1]) - datas.close() - msg_log = 'Create default file: %s'%file_tpl[0] - log.append_f(check.post_logs, msg_log, 0) - - #------------------# - # Create full page # - #------------------# - page = '\n' + \ - ' \n'%domain.domain_lang + \ - ' ' - - # Add tab metas in page - #---------------------- - # No file: use this default - for meta in metas.rsplit('\n'): - page = '%s\n%s%s'%(page, 6*' ', meta) - - page = '%s\n%s\n'%(page, 4*' ') + \ - '\n%s'%( - 4*' ', post_ID, domain.domain_css - ) - - # Add tab header in page - #----------------------- - if os.path.exists(files_tpl[0][0]): - headers_datas = open(files_tpl[0][0], 'r').read() - for header_line in headers_datas.rsplit('\n'): - page = '%s\n%s%s'%(page, 6*' ', header_line) - else: - # No file: use this default - for header in headers.rsplit('\n'): - page = '%s\n%s%s'%(page, 6*' ', header) - - msg_log = 'Use default header in page. Unused file: %s'%files_tpl[0][0] - log.append_f(check.post_logs, msg_log, 0) - - # Add tab article in page - for article in articles.rsplit('\n'): - page = '%s\n%s%s'%(page, 6*' ', article) - - # Add post from wip.html - #----------------------- - for line in wip_html: - page = '%s\n%s%s'%(page, 4*' ', line) - page = '%s\n%s
    \n'%(page, 8*' ') - - # Add latest-posts in page - #------------------------- - # No file: use this default - for aside in asides.rsplit('\n'): - page = '%s\n%s%s'%(page, 8*' ', aside) - - page = '%s\n%s
    '%(page, 6*' ') - - # Add footer in page - #------------------- - if os.path.exists(files_tpl[1][0]): - footers_datas = open(files_tpl[1][0], 'r').read() - for footer_line in footers_datas.rsplit('\n'): - page = '%s\n%s%s'%(page, 4*' ', footer_line) - else: - # No file: use this default - for footer in footers.rsplit('\n'): - page = '%s\n%s%s'%(page, 4*' ', footer) - msg_log = 'Use default footer in page. Unused file: %s'%files_tpl[1][0] - log.append_f(check.post_logs, msg_log, 0) diff --git a/src/var/lib/tyto/program/log.py b/src/var/lib/tyto/program/log.py deleted file mode 100644 index cd92783..0000000 --- a/src/var/lib/tyto/program/log.py +++ /dev/null @@ -1,81 +0,0 @@ -#!/usr/bin/env python3 -# Name: Tyto - Littérateur -# Type: Global functions for logs -# Description: Print data to specific log file -# file: log.py -# Folder: /var/lib/tyto/scripts/ -# By echolib (XMPP: im@echolib.re) -# License: GNU AFFERO GENERAL PUBLIC LICENSE Version 3, 19 November 2007 - -#------------ -# funny stats -#------------ -# lines: -# functions: -# comments: -#---------------------------------------------------------------------- - -#********************************************************************** -import check, domain - -#=======================# -# Manage Argument 'log' # -# Read, remove log file # -#-----------------------# -def manage_log(file_post, Opt): - import os, sys - - if file_post: - # No domain set, but ask for article : exit - if not domain.domain_conf: - sys.exit(1) - - # Get complete URI for post - post_uri = '%s%s'%(domain.domain_articles, file_post) - - # Get ID from URI - post_ID = check.get_filesum(post_uri,False) - - # Set log file for article - post_logs = '%s%s.log'%(domain.domain_logs,post_ID) - else: - post_logs = domain.tyto_logs - - if os.path.exists(post_logs): - if Opt == 'Remove' : - os.remove(post_logs) - msg_log = 'Log > Removed file: %s'%post_logs - if file_post: - append_f(domain.tyto_logs,msg_log,0) - else: - print(':) %s'%msg_log) - else: - file = open(post_logs,'r').read() - print(file) - else: - print(':| Unsed file yet: %s'%post_logs) - -#==============================# -# Set and return date and time # -# (especially for logs) # -#------------------------------# -def nowdate(): - import datetime - - now = datetime.datetime.now() - return(now.strftime('%Y-%m-%d %H:%M:%S')) - -#==================================# -# Append line to specific log file # -#----------------------------------# -def append_f(f,line,n): - smiley = [':D',':<\033[1;31m','\033[1;33m:|'] - now = nowdate() - - # Open file to append line - file = open(f, "a") - file.write('%s %s\n'%(now,line)) - file.close() - - if not line.endswith('\n'): - print('%s %s\033[0;0m'%(smiley[n],line)) diff --git a/src/var/lib/tyto/program/publish.py b/src/var/lib/tyto/program/publish.py deleted file mode 100644 index c8ce4cf..0000000 --- a/src/var/lib/tyto/program/publish.py +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/env python3 - -import rss, domain - -def manage_publish(file_post, Force): - - # At ending process.. - # Create rss.xml for www - rss.find_www(domain.srv_www, 'www') diff --git a/src/var/lib/tyto/program/rss.py b/src/var/lib/tyto/program/rss.py deleted file mode 100644 index 36c9181..0000000 --- a/src/var/lib/tyto/program/rss.py +++ /dev/null @@ -1,102 +0,0 @@ -#!/usr/bin/env python3 -# Name: Tyto - Littérateur -# Type: Global functions for HTML page -# Description: Create RSS for wip, publish -# file: rss.py -# Folder: /var/lib/tyto/programs/ -# By echolib (XMPP: im@echolib.re) -# License: GNU AFFERO GENERAL PUBLIC LICENSE Version 3, 19 November 2007 - -#------------ -# funny stats -#------------ -# lines: -# functions: -# comments: -#---------------------------------------------------------------------- - -#********************************************************************** - -import os, glob -import domain, html, log - -rss_headers = '\n' + \ - '\n' + \ - ' \n' + \ - ' %s %s %s %s Flux RSS 2.0\n'%( - domain.domain_title, - domain.sep_titles, - domain.domain_name, - domain.sep_titles - ) + \ - ' %s\n'%domain.domain_url + \ - ' %s\n'%domain.domain_about + \ - ' %s\n'%domain.domain_lang + \ - ' %s\n'%log.nowdate() + \ - ' %s\n'%domain.domain_license + \ - ' %s\n'%domain.domain_mail + \ - ' Tyto - Littérateur\n' - - -#==================================# -# Create RSS.xmp at ending process # -# srv: srv_www or srv_wip # -#----------------------------------# -def find_www(srv, srv_type): - # Create sidebar.html - rss_file = srv + 'rss.xml' - file = open(rss_file, 'w') - file.write(rss_headers) - file.close() - - # Get conf file, sort by ctime, and reverse - files = glob.glob("%s*.conf"%domain.domain_db) - files.sort(key=lambda x: os.path.getctime(x)) - files.reverse() # last created first - - # Check db_file if article is in www - rss_item = 0 - for db_file in files: - exec(open(db_file).read(),globals()) - - # Check srv_type (www or wip) - if srv_type == 'www': hash_srv = post_www - elif srv_type == 'wip': hash_srv = post_wip - post_uri_www = '%s%s'%(srv, post_srv) - - if not hash_srv[0]: - continue - - if not os.path.exists('%s%s'%(srv, post_srv)): - msg_log = 'RSS > Unused Article in www: %s'%post_uri_www - log.append_f(domain.tyto_logs, msg_log, 1) - continue - - rss_item += 1 - rss_post = ' \n' + \ - ' %s\n'%post_title + \ - ' %s\n'%post_url + \ - ' %s\n'%post_url + \ - ' %s\n'%hash_srv[1] + \ - ' %s\n'%post_about + \ - ' %s\n' + \ - ' \n' - - file = open(rss_file, 'a') - file.write(rss_post) - file.close() - - # Close tags - file = open(rss_file, 'a') - file.write(' \n') - file.close() - - # Log - - msg_log = 'RSS > Create file with %s items in: %s'%( - rss_item, rss_file - ) - log.append_f(domain.tyto_logs, msg_log, 0) - - - diff --git a/src/var/lib/tyto/program/sidebar.py b/src/var/lib/tyto/program/sidebar.py index 59124b8..11808c1 100644 --- a/src/var/lib/tyto/program/sidebar.py +++ b/src/var/lib/tyto/program/sidebar.py @@ -1,9 +1,9 @@ #!/usr/bin/env python3 # Name: Tyto - Littérateur -# Type: Global functions for HTML page -# Description: Create sidebar from file tyto.sidebar +# Type: Global functions to manage sidebar +# Description: Create domain # file: sidebar.py -# Folder: /var/lib/tyto/programs/ +# Folder: /var/lib/tyto/program/ # By echolib (XMPP: im@echolib.re) # License: GNU AFFERO GENERAL PUBLIC LICENSE Version 3, 19 November 2007 @@ -16,182 +16,25 @@ #---------------------------------------------------------------------- #********************************************************************** +import sys +import tyto -import re, os, sys, subprocess -import log, domain, check, html +# Load domain configuration if exists +if tyto.domain_exists: exec(open(tyto.domain_conf).read()) -sidebar_file = '%ssidebar.html'%domain.srv_wip_template - -#========================# -# Manage sidebar command # -#------------------------# -def manage_sidebar(article, Opt): - create = False - - # Create tyto.sidebar - if not os.path.exists(domain.domain_sdb_load): - create_sdb_load() - create = True - - # Wan to edit (in nano) - # Then, ask to make HTML sidebar (if file changed) - if Opt == "Edit": - old_sdb_ID = check.get_filesum(domain.domain_sdb_load, True) - edit_sdb = subprocess.run(['/usr/bin/nano', - '--linenumbers', - domain.domain_sdb_load]) - new_sdb_ID = check.get_filesum(domain.domain_sdb_load, True) - if old_sdb_ID == new_sdb_ID: - sys.exit(0) - else: - ask_make_sdb = input('! Create new HTML sidebar ? ') - if not ask_make_sdb in ['y', 'Y']: domain.exiting('root', 1, '') - - loop_sidebar(create) +#==============================# +# Manage arguments for sidebar # +#------------------------------# +def manage_sidebar(target, option): + # Initialize new sidebar + if not target: + if option == "Remove": + import domain + domain.create_sidebar(opt, sidebar_dir) + if option == 'Edit': + print(":D Edit sidebar configuration file:", sidebar_load) + tyto.edit_file(sidebar_load) -#========================# -# Read tyto.sidebar file # -#------------------------# -def loop_sidebar(create): - Post_Err = False - sdb_posts = posts_uri = [] - max_items = int(domain.domain_sdb_items) + 1 - counter = 0 # To not set more than set in config - sdb_loaded = (open(domain.domain_sdb_load)).read() - - for line in sdb_loaded.rsplit('\n'): - if create : print(line) - elif line.startswith('#'): continue - elif len(line) == 0 : continue - else: - if line.startswith('/'): line = line[1:len(line)] # No need /... - - post_uri = '%s%s'%(domain.domain_articles, line) - posts_uri = posts_uri + [post_uri] - - if not os.path.exists(post_uri): - print(':< From URI: %s. Unused file: %s'%(line, post_uri)) - Post_Err = True - else: - counter += 1 - if counter == max_items: break - hash_post = check.get_filesum(post_uri, False) - sdb_posts = sdb_posts + [hash_post] - - if Post_Err: - msg_log = 'Sidebar > Not created. Mismatch some article\'s URI' - log.append_f(domain.tyto_logs, msg_log, 1) else: - - print('>', sdb_posts, posts_uri) - - # Create sidebar.html - file = open(sidebar_file, 'w') - file.close() - - i = 0 - for item in sdb_posts: - db_article = '%s%s.conf'%(domain.domain_db, item) - if os.path.exists(db_article): - print("OK for",item, posts_uri[i]) - create_sdb_item(db_article) - else: - msg_log = 'Sidebar > Article not yet ready: %s'%posts_uri[i] - log.append_f(domain.tyto_logs, msg_log, 1) - i += 1 - - -#==========================================# -# Create HTML item in sidebar from article # -#------------------------------------------# -def create_sdb_item(db_article): - # Load DB for specific article - exec(open(db_article).read(),globals()) - - # Get article URL from filepath - post_short_uri = post_file.replace(domain.domain_articles, '/') - post_short_uri = post_short_uri.replace(".tyto", ".html") - # URL do not need /index.html - if post_short_uri.endswith('index.html'): - post_short_uri = post_short_uri.replace('index.html', '') - - # Article must have same hash from chk and wip - if not post_wip[0] == post_chk[0]: - print(':< Article has changed and needs to be checked first') - return(1) - - # Create sidebar.html - html.translations(post_date) - - sdb_html_item = '' - - with open(sidebar_file, 'a') as file: - for line in sdb_html_item.rsplit('\n'): - file.write('%s%s\n'%(16*' ', line)) - - - -#=====================# -# Create sidebar file # -# from choosen lang # -#---------------------# -def create_sdb_load(): - sdb_file_fr = '# Nom: Tyto - Littérateur\n' + \ - '# Type: fichier texte\n' + \ - '# Description: Fichier appelé par : tyto sidebar\n' + \ - '# fichier: tyto.sidebar\n' + \ - '# Dossier: articles/sidebar/\n' + \ - '# (depuis le dossier du domaine)\n' + \ - '# Comment: 1 URI de l\'article par ligne\n' + \ - '# Ne commence pas par "/"\n' + \ - '# L\'ordre définit la position\n' + \ - '# exemples :\n' + \ - '# index.tyto\n' + \ - '# dir1/index.tyto\n' - - sdb_file_en = '# Name: Tyto - Littérateur\n' + \ - '# Type: Text file\n' + \ - '# Description: file called with: tyto sidebar\n' + \ - '# file: tyto.sidebar\n' + \ - '# Folder: articles/sidebar/\n' + \ - '# (from the domain folder)\n' + \ - '# Comment: 1 article URI per line\n' + \ - '# not begining with "/"\n' + \ - '# Order in sidebar position\n' + \ - '# examples :\n' + \ - '# index.tyto\n' + \ - '# dir1/index.tyto\n' - - if re.match('fr', domain.domain_lang, re.IGNORECASE): - sdb_file = sdb_file_fr - else: - sdb_file = sdb_file_en - - file = open(domain.domain_sdb_load, "w") - file.write(sdb_file) - file.close() - msg_log = 'Sidebar > Create new sidebar file in %s'%( - domain.domain_sdb_load - ) - log.append_f(domain.tyto_logs, msg_log, 0) - + db_exists = tyto.get_db_post(target) # Article exists + has DB ? + if not db_exists: tyto.exiting("4", '') # Needs database diff --git a/src/var/lib/tyto/program/tyto.py b/src/var/lib/tyto/program/tyto.py new file mode 100644 index 0000000..c95bf51 --- /dev/null +++ b/src/var/lib/tyto/program/tyto.py @@ -0,0 +1,403 @@ +#!/usr/bin/env python3 +# Name: Tyto - Littérateur +# Type: Global functions for Tyto +# Description: Settings, Tools and +# file: tyto.py +# Folder: /var/lib/tyto/program/ +# By echolib (XMPP: im@echolib.re) +# License: GNU AFFERO GENERAL PUBLIC LICENSE Version 3, 19 November 2007 + +#------------ +# funny stats +#------------ +# lines: +# functions: +# comments: +#---------------------------------------------------------------------- + +#********************************************************************** + +import os, sys, subprocess, locale, base64, datetime +from hashlib import blake2b + +# Second argument in command +#--------------------------- +arguments = ( + '-a', 'add', + '-R', 'remove', + '-e', 'edit', + '-n', 'new', + '-F', 'force' + ) + + +# Settings +#--------- +domain_active = False +home_dir = os.path.expanduser('~') +in_dir = os.getcwd() + +# Set uri for configuration domain file +try: + sys.argv[2] + if not sys.argv[2] in arguments: + conf_dir = '%s/%s'%(in_dir,sys.argv[2]) + conf_dir = conf_dir.rsplit('articles')[0] + else: + conf_dir = in_dir.rsplit('articles')[0] + '/' +except: + conf_dir = in_dir.rsplit('articles')[0] + '/' + +domain_conf = '%styto_domain.conf'%conf_dir +db_dir = '%s/.local/tyto/'%home_dir + + +# Check if domain config file +#---------------------------- +stdout = '%s %s domain "%s" in %s' # Message to show domain status + +if os.path.exists(domain_conf): + exec(open(domain_conf).read()) + datas_domain = open(domain_conf, "r").read() + domain_exists = True + if domain_active: + smiley = ':D'; status = 'Active' + domain_active = True + else: + smiley = ':/'; status = 'Inactive' + domain_active = False + print(stdout%( + smiley, status, domain_short, domain_conf + ) + ) +else: + print(':| No domain configured in this directory: %s'%domain_conf) + domain_exists = domain_active = False + +if domain_exists: + db_dir = '%s%s/articles'%(db_dir, domain_short) + + +# Basic translations: french, english +#------------------------------------ +try: lang = domain_lang +except: lang = locale.getdefaultlocale()[0].split('_')[0] +if lang.lower() == 'fr': n = 0 +else: n = 1 + +# Translations French/English +trans = [ + ['À l\'affiche !', 'Featured !' ] + ] + +# Set all tags used in article's header +headers = ( + 'title:', + 'about:', + 'author:', + 'tags:', + 'date:', + 'link:', + 'image:', + 'file:', + 'abbr:', + 'brut:', + '#' + ) + +# Words and template Tags (paragraphs, lists, bold, strong...) +# Used to check, and replace (wip) tags +# As base64 is used, do NOT set marker: =_ _= +# [5] = name for stats and log. +# [6] = Check content differently. 't' = startswith +#------------------------------------------------------------- +words_tags = [ +('>_', '_<', '', 'anchors', 'w'), +('*_', '_*', '', '', 'strongs', 'w'), +('+_', '_+', '', '', 'bolds', 'w'), +('/_', '_/', '', '', 'emphasis', 'w'), +('[_', '_]', '', '', 'italics', 'w'), +('~_', '_~', '', '', 'dels', 'w'), +('._', '_.', '', '', 'underlines', 'w'), +(':_', '_:', '', '', 'cites', 'w'), +('%_', '_%', '', '', 'customs', 'w'), +('{_', '_}', '', '', 'codes', 'w'), +('((', '))', '

    ', '

    ', 'paragraphs', 't'), +('[[', ']]', '[[', ']]', 'quotes', 't'), +('{{', '}}', '{{', '}}', 'bcodes', 't'), +('-(', '-)', '-(', '-)', 'lists', 't') +] + + +# Tags that do not need to be paired +#----------------------------------- +single_tags = [ +('|', '
    '), # New Line +('->', '
    ') # Anchors +] + +# Markers for lists, to check in list content +#-------------------------------------------- +markers_lists = ('+', '=', ' ') + +# Tags used for titles +titles_tags = ('#1 ', '#2 ', '#3 ', '#4 ', '#5 ', '#6 ') + + +#=======# +# TOOLS # +#=======#-------------------------------------------------------------- +#=======================# +# Return sum of srcfile # +# src: True = Content # +# False = URI # +#-----------------------# +def get_filesum(path, src): + file_sum = blake2b(digest_size=4) + + if src: file_sum.update(open(path, 'rb').read()) + else : file_sum.update(path.encode()) + return file_sum.hexdigest() + + +#==============================# +# Set and return date and time # +# (especially for logs) # +#------------------------------# +def nowdate(): + now = datetime.datetime.now() + return(now.strftime('%Y-%m-%d %H:%M:%S')) + + +#=======================# +# Check if article file # +# Check if article DB # +#-----------------------# +def get_db_post(target): + # Check if target file exists + global uri_post + uri_post = '%s/%s'%(in_dir, target) + if not os.path.exists(uri_post): + exiting("1", uri_post, True) + + global uri_root + uri_root = uri_post + + global uri_src + uri_src = '/' + uri_post.rsplit(domain_articles)[1] + + global hash_post + hash_post = get_filesum(uri_post, True) # From content file + + global web_uri + ext = os.path.splitext(uri_post) + new_ext = '.html' + uri_post = uri_post.replace(ext[1], new_ext) + + web_uri = '/' + uri_post.rsplit(domain_articles)[1] + + global post_filename, post_dir + post_filename = os.path.basename(uri_post) + post_dir = uri_post.replace(post_filename, '') + + global uri_id + uri_id = get_filesum(uri_post, False) # From URI file + + global post_db + post_db = '%s/%s.conf'%(db_dir, uri_id) + + if os.path.exists(post_db): db_exists = True + else : db_exists = False + + return(db_exists) + + +#======================# +# Open and edit a file # +#----------------------# +def edit_file(edit_file): + file_edit = subprocess.run( + [ + '/usr/bin/nano', + '--linenumbers', + edit_file + ] + ) + + +#================# +# Create a file # +# Or append text # +#----------------# +def set_file(path, new, text): + if new: opt = "w" + else: opt = "a" + + file = open(path, opt) + file.write(text + '\n') + file.close() + + +#==========================# +# Get CSS from line if set # +#--------------------------# +def get_css(line): + # Use this default, if not in conf + try: set_css = domain_css + except: domain_css = 'tyto' + + # Get CSS from line + try: set_css = line.rsplit(' ')[1] + except: set_css = domain_css + + return set_css + + +#=======================# +# Protec iCodes # +# Used in check and wip # +#-----------------------~ +def protect_icodes(post_bottom, article_bottom): + global protect_article + global nbr_codes + + nbr_codes = 0 # Stats here for DB as content will change + protect_article = article_bottom + incode = False + src_code = rep_code = '' + + # Get only lines that contains code + for ln, line in enumerate(post_bottom): + if '{_' and '_}' in line: + + # Iterate in line + for i, c in enumerate(line): + 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 == '\\': + incode = True + nbr_codes += 1 + code = words_tags[9][2] + continue + + # No more in code if + if c_a == '}' and not c_b == '\\': + incode = False + code = '%s%s%s'%(code, src_code, words_tags[9][3]) + b64_code = b64('Encode', code) + rep_code = "%s%s%s"%( + words_tags[9][0],rep_code,words_tags[9][1] + ) + temp_post = protect_article.replace(rep_code, b64_code) + protect_article = temp_post + + src_code = rep_code = b64_code = '' + continue + + # Construct original replacement code and source code + if incode: + rep_code = '%s%s'%(rep_code, c) + if c == '\\': continue + src_code = '%s%s'%(src_code, c) + + +#=============================================# +# Protect block-Codes, quotes # +# Also remove commented lines # +# Used in check and wip # +# For check, create new article without bcode # +# For wip, remplace content with base64 # +#---------------------------------------------# +def protect_bcodes_quotes(process, post_bottom): + + global protect_article + in_bcode = in_quote = False + protect_article = '' + + if process == 'check': + global nbr_titles, nbr_bcodes, nbr_quotes # Stats for DB + nbr_titles = nbr_bcodes = nbr_quotes = 0 + + for line in post_bottom: + if line.startswith(words_tags[12][0]): + in_bcode = True + nbr_bcodes += 1 + continue + elif line.startswith(words_tags[12][1]): + in_bcode = False + continue + elif line.startswith('#'): # As convention + if line.startswith(titles_tags): nbr_titles += 1 + else: continue + + if in_bcode: continue + elif line.startswith(words_tags[11][0]): + in_quote = True + nbr_quotes += 1 + continue + elif line.startswith(words_tags[11][1]): + in_quote = False + continue + + if in_quote: + if not line in (words_tags[10][0], words_tags[10][1]): + continue + + if not protect_article: protect_article = line + else: protect_article = '%s\n%s'%(protect_article, line) + + +#=====================================# +# Encode/Decode string to/from base64 # +# Data protection # +#-------------------------------------# +def b64(action, content): + if action == 'Encode': + global b64_content + b64_base64 = '' + content_bytes = content.encode("ascii") + base64_bytes = base64.b64encode(content_bytes) + b64_content = 'B64_' + base64_bytes.decode("ascii") + '_B64' + return b64_content + + elif action == 'Decode': + global src_content + src_content = '' + content_bytes = post_content.encode("ascii") + base64_bytes = base64.b64decode(content_bytes) + src_content = base64_bytes.decode("ascii") + return src_content + + else: + print("Options: 'Encode', 'Decode'") + sys.exit(1) + + +#================================# +# Exit from program with message # +#--------------------------------# +def exiting(nbr, value, out): + nbrs = { + '1' : ':< \033[1;31mUnused ressource\033[0;0m: "%s"'%value, + '2' : ':< \033[1;31mIncomplete data\033[0;0m: "%s"'%value, + '3' : ':< \033[1;31mInvalid data\033[0;0m: "%s"'%value, + '4' : ':< \033[1;31mNo database yet\033[0;0m. Check article first.', + '5' : ':< \033[1;31mUnused argument\033[0;0m file', + '6' : ':< \033[1;31mUnused "%s"\033[0;0m in article'%value, + '7' : ':< Article is \033[1;31mnot valid yet\033[0;0m', + '8' : ':< tags "%s" \033[1;31mnot paired\033[0;0m'%value, + '9' : ':D Article has changed (wip is old)', + '20' : ':D Article already up-to-date on: %s'%value, + '21' : ':D Article is valid and ready to wip', + '255' : ':| Maybe later...' + } + + msg = nbrs[nbr] + print(msg) + + if int(nbr) >= 20: nbr = 0 + if out: sys.exit(int(nbr)) diff --git a/src/var/lib/tyto/program/wip.old.py b/src/var/lib/tyto/program/wip.old.py deleted file mode 100644 index 17cd287..0000000 --- a/src/var/lib/tyto/program/wip.old.py +++ /dev/null @@ -1,412 +0,0 @@ -#!/usr/bin/python -# Name: Tyto - Littérateur -# Type: Global functions for wip -# Description: Converters from Source to HTML -# file: wip.py -# Folder: /var/lib/tyto/scripts/ -# By echolib (XMPP: im@echolib.re) -# License: GNU AFFERO GENERAL PUBLIC LICENSE Version 3, 19 November 2007 - -#------------ -# funny stats -#------------ -# lines: -# functions: -# comments: -#---------------------------------------------------------------------- - -#********************************************************************** - -import os, sys -import check,log,domain - -Tyto_Err = False -post_uri = '' -# -# Manage WIP argument -# -def manage_wip(file_post, Force): - # Check if argument's file (.tyto) - if not file_post: - print(':( Unused argument file') - sys.exit(1) - - # Check if file exists - post_uri = '%s%s'%(domain.domain_articles,file_post) - if not os.path.exists(post_uri): - print(':( Unused file: %s'%post_uri) - sys.exit(1) - - # Get ID from URI (to get DB file) - post_ID = check.get_filesum(post_uri,False) - - # Set database file for this article - # Check if DB exists - post_db = '%s%s.db'%(domain.domain_db, post_ID) - if not os.path.exists(post_db): - print(':( Use "check" before "wip".') - sys.exit(1) - - # Set and check/create logs file for this article - post_logs = '%s%s.log'%(domain.domain_logs,post_ID) - - -#========# -# # -# Basics # -# # -#========#------------------------------------------------------------- -#===========================# -# Convert file to post_temp # -#---------------------------# -def post_to_string(file_path): - global post_temp - post_temp = '' - post_html = '' - with open(file_path, "r") as file: - post_temp = file.read() - - remove_empty_lines(post_temp.split('\n')) - post_html = post_temp - -#===========================# -# Convert content TO base64 # -#---------------------------# -def convert_to_b64(post_content): - import base64 - global b64_content - post_content_base64 = '' - content_bytes = post_content.encode("ascii") - base64_bytes = base64.b64encode(content_bytes) - b64_content = 'B64_' + base64_bytes.decode("ascii") + '_B64' - -#================================# -# Convert FROM base64 to content # -#--------------------------------# -def convert_from_b64(post_content): - import base64 - global src_content - post_content_src = '' - content_bytes = post_content.encode("ascii") - base64_bytes = base64.b64decode(content_bytes) - src_content = base64_bytes.decode("ascii") - -#==========================# -# Get Writer's CSS config # -# For compatible's markers # -#--------------------------# -def get_css(css,css_gen): - global css_set - - try: - css_set = line.split(" ")[1] - except: - css_set = '%s%s'%(css,css_gen) - -#=============================# -# Get post, witout empty line # -#-----------------------------# -def remove_empty_lines(post): - global post_html, post_temp, line - post_temp = '' - post_html = '' - - for line in post: - c = len(line) - if c > 0: - #print(c,line) - if not post_temp: - post_temp = line - else: - post_temp = '%s\n%s'%(post_temp,line) - - post_html = post_temp - - -#============# -# # -# Converters # -# # -#============#--------------------------------------------------------- -#==========================# -# Convert bCodes to base64 # -#--------------------------# -def convert_bcodes(post,fm,lm,css): - import re - global post_html, line, css_set - post_temp = '' - span_nbr = ''%css - span_code = ''%css - span_end = '' - pre_end = '
    ' - ln_nbr = 0 - bCode = False - blines = '' - - for line in post: - if line.startswith(fm): # Starting bcode marker - ln_nbr = 0 - bCode = True - get_css(css,'_bcode') - pre_start = '
    '%css_set
    -      blines    = '%s'%pre_start
    -      css_set   = ''
    -      continue
    -    elif line.startswith(lm): # Ending bcode marker
    -      bCode     = False
    -      line      = ''
    -      blines    = '%s\n%s'%(blines,pre_end)
    -      convert_to_b64(blines)
    -      post_temp = '%s\n%s'%(post_temp,b64_content)
    -
    -    if not bCode:
    -      post_temp = '%s\n%s'%(post_temp,line)
    -    else:
    -      ln_nbr += 1
    -      blines = '%s\n  %s%d%s%s%s%s'%\
    -                (
    -                blines,span_nbr,ln_nbr,span_end,span_code,line,span_end
    -                )
    -
    -  remove_empty_lines(post_temp.split('\n'))
    -  post_html = post_temp
    -
    -#============================================#
    -# Convert Base64 strings to original content #
    -#--------------------------------------------#
    -def convert_b64_lines(post):
    -  import re
    -  global post_html,line
    -  post_temp    = ''
    -  post_html    = ''
    -  b64_contents = ''
    -  
    -  for line in post:
    -    if not 'B64_' in line:
    -      post_temp = '%s\n%s'%(post_temp,line)
    -    else:
    -      b64_contents = re.findall(r"B64_(.*?)_B64", line)
    -      for b64_content in b64_contents:
    -        convert_from_b64(b64_content)
    -        line = line.replace('B64_%s_B64'%b64_content, src_content)
    -      post_temp = '%s\n%s'%(post_temp,line)
    -
    -  remove_empty_lines(post_temp)
    -  post_html = post_temp
    -
    -#==========================#
    -# Convert iCodes to base64 #
    -# fm = FIRST Marker        #
    -# lm = LAST Marker         #
    -#--------------------------#
    -def convert_icodes(post, fm, lm, css):
    -  import re
    -  global post_html
    -  post_temp       = '' # Temp string to become post_html string page
    -  icodes_contents = '' # strings containing icode
    -  fm_html         = ''%css
    -  lm_html         = ''
    -  fm_spe          = '!%s'%(fm)  # Special for !<_
    -  lm_spe          = '%s!'%lm    # Special for _>!
    -  
    -  for line in post:
    -    # Special marker containting legacy one
    -    if lm_spe and fm_spe in line:
    -      icodes_contents = re.findall(r"%s(.*?)%s"%(fm_spe,lm_spe), line)
    -      for icode in icodes_contents:
    -        content_rep = '%s%s%s'%(fm_spe,icode,lm_spe)
    -        icode = '%s'%(css,icode)
    -        convert_to_b64(icode)
    -        line = line.replace(content_rep,b64_content)
    -    
    -    # Legacy marker
    -    if lm and fm in line:
    -      icodes_contents = re.findall(r"%s(.*?)%s"%(fm,lm), line)
    -      for icode in icodes_contents:
    -        content_rep = '%s%s%s'%(fm,icode,lm)
    -        icode = '%s'%(css,icode)
    -        convert_to_b64(icode)
    -        line = line.replace(content_rep,b64_content)
    -    
    -    post_temp = '%s\n%s'%(post_temp,line)
    -  post_html = post_temp
    -
    -#====================================#
    -# Convert Quotes                     #
    -# 2 types:                           #
    -#   - Advanced, with author          #
    -#   - Simple, with no author         #
    -# mt = marker type (Should be 3 '-') #
    -#------------------------------------#---------------------------------
    -#=========================#
    -# Return datas after term #
    -#-------------------------#
    -def get_quote_datas(term,line):
    -  import re
    -
    -  term_data = re.compile('%s(.*)$'%term)
    -  if term_data:
    -    return term_data.search(line).group(1)
    -
    -#=====================#
    -# Loop in Post        #
    -# Convert quotes only #
    -#---------------------#
    -def convert_quotes(post,mt,css):
    -  import re
    -  global post_html,line,htmlquote, cite
    -  post_temp = '' # Temp string to become post_html string page
    -  Quote     = False
    -  bquote    = htmlquote = htmllines = ''
    -  cite      = ''
    -  link      = cite_HTML = ''
    -  lang      = lang_HTML = ''
    -  book = year = title_HTML = ''
    -  quote_nbr = 0
    -
    -  for line in post:
    -    # Starting quote
    -    if line.startswith(mt):
    -      if not Quote:
    -        Quote = True
    -        get_css(css,'_quote')
    -        quote_nbr += 1
    -        line = '_QUOTE_%d'%quote_nbr
    -        if post_temp:
    -          post_temp = '%s\n%s'%(post_temp,line)
    -        else:
    -          post_temp = line
    -        continue
    -      # End of quote
    -      # Create HTML and convert marker to Base64
    -      else:
    -        Quote = False
    -        
    -        # Create HTML datas
    -        if cite and book and year:
    -          title_HTML = ' title="%s - %s (%s)"'%(cite,book,year)
    -        elif book and year:
    -          title_HTML = ' title="%s (%s)"'%(book,year)
    -        elif book:
    -          title_HTML = ' title="%s"'%book
    -        elif year:
    -          title_HTML = ' title="%s"'%year
    -        
    -        htmlquote = '
    >' # No close marker + # Article exists + has DB ? + db_exists = tyto.get_db_post(target) + if not db_exists: + tyto.exiting("4", '', True) -# 'Open' , 'Close' , 'Name' -markers_reg = [ - [ r'^\($|^\(\s' , r'^\)$' , 'paragraphs' ], - [ r'^\(\($|^\(\(\s', r'^\)\)$', 'quotes' ], - [ r'^\[\[$|^\[\[\s', r'^\]\]$', 'brut codes' ], - [ r'^-\($|^-\(\s' , r'^-\)$' , 'lists' ] - ] + # Has DB: conditions to process + is_wip = True + is_new = False + is_file = True + do_wip = False -#=====================# -# Manage WIP argument # -#---------------------# -def manage_wip(file_post, Force): - # Get IDs from Article - check.post_IDs(file_post) + # Load DB + exec(open(tyto.post_db).read(),globals()) - # Check DB - if not check.db_exist: - print(':( Article must be checked first.') - sys.exit(1) + # In any case, if Force + if option == 'Force': + wip_article() + return - # Check ID.wip - if not os.path.exists(check.post_tmp): - print(':( Article must be check again (unsed %s)'%( - check.post_tmp - ) - ) - sys.exit(1) - - # Current Article has changed (not same hash in DB for chk) - if check.hash_chk != check.post_chk[0]: - print(':| Article has changed. Check it first.') - sys.exit(0) - - # Article has same hash in DB for wip - if check.hash_chk == check.post_wip[0]: - # Check if file exists on the server - if check.srv_post_wip[0] and not Force: - print(':| Article was already converted on %s'%( - check.post_wip[1] - ) - ) - sys.exit(0) + # Compare and check file + if not hash_wip == hash_chk: is_wip = False ; do_wip = True + if not hash_wip == tyto.hash_post: is_new = True ; do_wip = True + if not os.path.exists(wip_uri): is_file = False ; do_wip = True - - # All is good, converting... - #--------------------------- - # Source DB variables - post_db = exec(open(check.curr_post_db).read(),globals()) - - # Send to log - msg_log = 'Wip > Article: %s. logs: %s'%( - check.post_uri, check.post_logs - ) - log.append_f(domain.tyto_logs, msg_log, 0) - - # Set file_string from post_tmp - file_string = open(check.post_tmp, 'r').read() - post_lines = file_string.rsplit('\n') - - # Set wip_html string. Will be the HTML part
    - global wip_html - wip_html = '' - - for line in post_lines: - if len(line) == 0: continue - wip_html = '%s%s\n'%(wip_html, line) - - wip_begin_markers(wip_html.rsplit('\n')) - wip_titles( wip_html.rsplit('\n')) - wip_words_markers(wip_html) - - if files_u > 0: wip_files_links(wip_html) - if images_u > 0: wip_images( wip_html) - if anchors > 0: wip_anchors( wip_html) - if abbrs_u > 0: wip_abbrs( wip_html) - - # After all, convert protected contents - if links_u > 0: wip_links( wip_html) - if quotes > 0: wip_quotes( wip_html.rsplit('\n')) - - # brut files - if bruts_u > 0: wip_bruts( wip_html.rsplit('\n')) - - # Get Legacy contents from base64 markers - convert_all_b64(wip_html.rsplit('\n')) - - - #print('> Article with Tabs:') - tab_article(wip_html.rsplit('\n')) - - # Create full page - html.html_main_page(wip_html.rsplit('\n')) - - wip_html = html.page - print('> Article HTML:\n', wip_html) - - # Create file to wip srv (replace file, if exists) - wip_file = '%s%s'%(domain.srv_wip, check.post_srv) - if os.path.exists(wip_file): - os.remove(wip_file) - - # Create sub folder if needed - wip_dir = '%s%s'%(domain.srv_wip, check.post_dir) - os.makedirs(wip_dir, exist_ok=True) - - - page_file = open(wip_file, 'w') - page_file.write(wip_html) - page_file.close() - - time_wip = log.nowdate() - hash_wip = check.get_filesum(check.post_file, True) - - rep_post_wip = 'post_wip = (\'%s\', \'%s\')'%( - check.post_wip[0], check.post_wip[1]) - tmp_post_wip = (hash_wip, time_wip) - post_wip = 'post_wip = %s'%str(tmp_post_wip) - - # Replace post_wip in DB - with open(check.post_db, 'r') as file: - filedata = file.read() - filedata = filedata.replace(rep_post_wip, post_wip) - with open(check.post_db, 'w') as file: - file.write(filedata) - # log - msg_log = 'Edit Database: %s'%check.post_db - log.append_f(check.post_logs, msg_log, 0) - - # At ending process.. - # Create rss.xml for www - rss.find_www(domain.srv_wip, 'wip') - -#============================# -# HTML CONVERTERS # -# wip_tmp: new replacedlines # -#============================#----------------------------------------- -#============================# -# New line: | # -# Anchors: >> # -# Paragraphs: ( =

    # -# bCodes: [[ = # -# Convert to HTML >> base64 # -#----------------------------# -def wip_begin_markers(wip_lines): - global wip_html - - wip_tmp = '' - # Set marker (regex to find), HTML, Need CSS - marks_html = [ - ['^\|$|^\|\s' , '
    ' , True ], - ['^>>\s' , '' , True ], - [r'^\($|\(\s' , '

    ' , True ], - ['^\)$|^\)\s' , '

    ' , False], - ['^\[\[$|^\[\[\s' , '',True ], - ['^\]\]$|^\]\]\s' , '' , False] - ] - - for line in wip_lines: - if len(line) == 0: continue - - # Find if line has marker and remplace - for marker in marks_html: - if re.match(marker[0], line): - if marker[2]: # Has CSS - get_css(line) - line = line.replace(line, marker[1]%css_set) - else: - line = line.replace(line, marker[1]) - convert_to_b64(line) - line = b64_content - wip_tmp = '%s%s\n'%(wip_tmp, line) - - wip_html = wip_tmp - -#===========================# -# Titles: #[1-6] = # -# Add a
    # -# - if contents after title # -# (and not a new title) # -#---------------------------# -def wip_titles(wip_lines): - global wip_html - - wip_tmp = '' - has_div = False - - for ln, line in enumerate(wip_lines, 1): - if len(line) == 0: continue - - # Title found - if re.match('#\d\s', line): - tn = line[1] - ts = tn * 2 # Tab spaces - if has_div: # Before Title, if div was open, close it - wip_tmp = '%s
    \n'%wip_tmp - has_div = False - - # Replace #[1-6] TITLE - wip_tmp = '%s%s\n'%( - wip_tmp, - line.replace('#%s '%tn, - ''%( - tn,domain.domain_css - ) - ), - tn - ) - - # Check next line - # Add div if contents after, and not a new title - if not re.match('#\d\s', wip_lines[ln]): # NOT a new title - wip_tmp = '%s
    \n'%( - wip_tmp, domain.domain_css,tn - ) - has_div = True - else: - wip_tmp = '%s%s\n'%(wip_tmp, line) - - if has_div: # Close last div - wip_tmp = '%s
    \n'%wip_tmp - has_div = False - - wip_html = wip_tmp - - -#================================================# -# Create Anchors (links) and convert to HTML # -# Target anchors are done with wip_begin_markers # -# Each are converted to Base64 # -#------------------------------------------------# -def wip_anchors(article): - global wip_html - - anchor_fmt = '%s' - anchors_link = re.findall(r'\>_(.*?)_\<', article) - - for anchor in anchors_link: - anchor_id = anchor.rsplit(':',1)[0] - anchor_name = anchor.rsplit(':',1)[1] - anchor_b64 = anchor_fmt%(anchor_id, anchor_name) - convert_to_b64(anchor_b64) - article = article.replace('>_%s_<'%anchor, b64_content) - - wip_html = article - -#==============================# -# Convert links to HTML # -# Each are converted to Base64 # -#------------------------------# -def wip_links(article): - global wip_html - - link_fmt = '%s' - all_vars = set(globals()) - - for var in all_vars: - if var.startswith('link_'): - link = globals()[var] - link_b64 = link_fmt%(domain.domain_css, link[1], - link[2], link[0] - ) - convert_to_b64(link_b64) - article = article.replace('_%s'%link[0], b64_content) - - wip_html = article - -#===========================================# -# Convert abbrs to HTML # -# each found are converted to Base64 # -# (avoid mismatch HTML if same word inside) # -#-------------------------------------------# -def wip_abbrs(article): - global wip_html - - abbr_fmt = '%s' - all_vars = set(globals()) - - for var in all_vars: - if var.startswith('abbr_'): - abbr = globals()[var] - abbr_b64 = abbr_fmt%(domain.domain_css, abbr[1], abbr[2]) - convert_to_b64(abbr_b64) - article = article.replace(abbr[0], b64_content) - - wip_html = article - -#======================================# -# Words Markers (strongs, emphasis...) # -#--------------------------------------# -def wip_words_markers(wip_tmp): - global wip_html - - # Set marker, and its HTML value - marks_html = [ - ['*_' , ''%domain.domain_css], - ['_*' , '' ], - ['+_' , ''%domain.domain_css ], - ['_+' , '' ], - ['-_' , ''%domain.domain_css ], - ['_-' , '' ], - ['~_' , ''%domain.domain_css ], - ['_~' , '' ], - ['/_' , ''%domain.domain_css ], - ['_/' , '' ], - ['\\_' , ''%domain.domain_css ], - ['_\\' , '' ], - ['=_' , ''%domain.domain_css ], - ['_=' , '' ], - ['×_' , '' ], - ['_×' , '' ], - ['(_' , ''%domain.domain_css ], - ['_)' , '' ], - ['<_' , ''%domain.domain_css ], - ['_>' , '' ] - ] - - # Replace marker in string's article (wip_html) - for marker in marks_html: - wip_tmp = wip_tmp.replace(marker[0], marker[1]) - - wip_html = wip_tmp - - -#========# -# Quotes # -#========# -#======================== # -# Loop lines in article # -# For each quote, convert # -# (Decode base64, HTML) # -#-------------------------# -def wip_quotes(wip_lines): - global wip_html, quote_css - - wip_html = '' - quote = False - - for line in wip_lines: - # Starting quote marker - if re.match(markers_reg[1][0], line): - get_css(line) - quote_css = css_set - quote = True - continue - - # Ending quote marker - elif re.match(markers_reg[1][1], line): - quote = False - continue - - # In quote, Should be base64 line containing quote - # Call convert_quote() to create quote_html - # Replace line, with html_quote - if quote: - if re.match('B64\|', line): - line = line.replace('B64|', '') - line = line.replace('|B64', '') - convert_from_b64(line) - bQuote = src_content - convert_quote(bQuote.rsplit('\n')) - line = quote_html - - # Create new HTML article - if wip_html: wip_html = '%s\n%s'%(wip_html, line) - else : wip_html = line - -#============================# -# Convert brut Quote to HTML # -#----------------------------# -def convert_quote(bQuote): - global quote_html - - quote_html = '' - cite = link = lang = year = book = '' - author_title = author_show = author_html = '' - cite_html = lang_html = figca_html = '' - year_show = book_show = '' - - # Set Datas (if exists) - for line in bQuote: - # Get Datas from markers in quote - if line.startswith('_cite:'): - cite = quote_data(line) - elif line.startswith('_link:'): - link = quote_data(line) - cite_html = ' cite="%s"'%link - elif line.startswith('_lang:'): - lang = quote_data(line) - lang_html = ' lang="%s"'%lang - elif line.startswith('_year:'): - year = quote_data(line) - year_show = ' (%s)'%year - elif line.startswith('_book:'): - book = quote_data(line) - book_show = ' - %s'%book - - # Only accepted marker: paragraphs - elif re.match(markers_reg[0][0], line): - get_css(line) - line = '

    '%css_set - if quote_html: quote_html = '%s\n%s'%(quote_html, line) - else : quote_html = line - elif re.match(markers_reg[0][1], line): - line = '

    ' - quote_html = '%s\n%s'%(quote_html, line) - - # main quote content - else: - if quote_html: quote_html = '%s\n%s'%(quote_html, line) - else : quote_html = line - - if not cite : author_show = 'NC' - if year and book: author_show = '%s%s%s'%( - author_show, book_show, year_show - ) - - if cite or link: - author_show = '%s%s'%(cite, author_show) - author_title = ' title="%s"'%author_show - - # Create main blockquote - blockquote = '
    \n%s
    '%( - quote_css, author_title, cite_html, lang_html, - quote_html - ) - - if cite: - if link: author_html = '%s'%( - quote_css, link, author_show - ) - else : author_html = author_show - - if year: author_html = ''%( - year, author_html - ) - - figca_html = '
    \n'%quote_css + \ - '\n%s\n\n'%( - quote_css, author_html - ) + \ - '
    ' - - quote_html = '
    \n%s\n%s\n
    '%( - quote_css, blockquote,figca_html - ) + if do_wip: + # Show message if wip was done + if hash_wip: + if not is_file: tyto.exiting("1", wip_uri, False) + if is_new: tyto.exiting("9", '', False) + wip_article() else: - if year: quote_html = ''%( - year, blockquote - ) - else : quote_html = blockquote + tyto.exiting("20", date_wip, True) -#=================================# -# Return datas in quote from line # -#---------------------------------# -def quote_data(line): - return line.split(' ', 1)[1].lstrip() +#===================# +# Start wip modules # +# Set Db # +#-------------------# +def wip_article(): + print('Convert') - -#=========================# -# Convert files_links # -# from header "file: xxx" # -#-------------------------# -def wip_files_links(article): - global wip_html - - flink_fmt = '%s' - all_vars = set(globals()) - - for var in all_vars: - if var.startswith('file_'): - flink = globals()[var] - flink_b64 = flink_fmt%(domain.domain_css, - flink[2], - flink[1], - flink[0] - ) - convert_to_b64(flink_b64) - article = article.replace('__%s'%flink[0], b64_content) - - wip_html = article - - -#==========================# -# Convert images # -# from header "image: xxx" # -# Get parameters from line # -#--------------------------# -def wip_images(article): - global wip_html - - regex_dw = r"([0-9]+)([a-z]+)" - wip_html = '' - image_fmt = '%s' - img_style = '%s' # %(wh_style) style="..." if width and/or height - - all_vars = set(globals()) - - for var in all_vars: - if var.startswith('image_'): - image = globals()[var] - - # Copy file in wip - image_src = '%s%s%s'%( - domain.domain_articles, check.post_dir, image[1] - ) - image_dst = '%s%s%s'%( - domain.srv_wip, check.post_dir, image[1] - ) - shutil.copy2(image_src, image_dst) - # log - msg_log = 'Wip > Image: %s > %s'%(image_src, image_dst) - log.append_f(check.post_logs, msg_log, 0) - - # Search in article lines for _image: - for line in article.rsplit('\n'): - if not line.startswith('_image:'): - if wip_html: wip_html = '%s\n%s'%(wip_html, line) - else : wip_html = line - - elif line.startswith('_image:%s'%image[0]): - width = height = set_css = target = '' - image_html = '' - wh_style = '' # width and/or height parameters - - # Get parameters and set values for this marker - image_params = (line.rsplit(' ')) - for param in image_params: - # CSS - if param.startswith('c='): - set_css = param.rsplit('=')[1] - - # Width - elif param.startswith('w='): - width = param.rsplit('=')[1] - if not width: width = '' - elif width.isdigit(): - width = 'width:%spx;'%width - else: - wspl = re.match(regex_dw, width, re.I).groups() - width = 'width:%s;'%width - - # Height - elif param.startswith('h='): - height = param.rsplit('=')[1] - if not height: height = '' - elif height.isdigit(): - height = 'height:%spx;'%height - else: - hspl = re.match(regex_dw, height, re.I).groups() - height = 'height:%s;'%height - - # Target - elif param.startswith('t='): - target = param.rsplit('=')[1] - if not target: target = image[1] - - # Check values and construct HTML - if not set_css: set_css = domain.domain_css - if width and height: wh_style = 'style="%s%s" '%(width,height) - elif width : wh_style = 'style="%s" '%width - elif height : wh_style = 'style="%s" '%height - - image_html = image_fmt%(set_css, - image[2], image[2], - img_style%wh_style, - image[1] - ) - - # Create Target link if t= - if target: - line = '%s'%( - set_css, target, image_html - ) - else: - line = image_html - - # Replace line - if wip_html: wip_html = '%s\n%s'%(wip_html, line) - else : wip_html = line - - -#=============================================# -# Convert line _brut: to pre HTML, like bCode # -#---------------------------------------------# -def wip_bruts(article): - global wip_html - - wip_html = '' - all_vars = set(globals()) - - for var in all_vars: - if var.startswith('brut_'): - brut = globals()[var] - - # Search in article lines for _image: - for line in article: - if not line.startswith('_brut:'): - if wip_html: wip_html = '%s\n%s'%(wip_html, line) - else : wip_html = line - - elif line.startswith('_brut:%s'%brut[0]): - # Open target file - brut_file = '' - brut_html = '' # brut file contents - brut_uri = brut[1][1:len(brut[1])] # No need first "/" - brut_file = '%s%s'%(domain.domain_articles, brut_uri) - brut_datas = open(brut_file, 'r').read() - - # Convert each lines to HTML, add to string - for ln, bline in enumerate(brut_datas.rsplit('\n'), 1): - brut_line_html = '
    %s
    '%( - ln, bline, bline - ) - if brut_html: brut_html = '%s\n%s'%(brut_html,brut_line_html) - else : brut_html = brut_line_html - - # Get CSS, if exists, before creating last brut_html - get_css(line) - - # Add first and last HTML tags to string - brut_html = '\n'%( - css_set, brut[2]) + \ - '%s\n'%brut_html - - # Replace line - if wip_html: wip_html = '%s\n%s'%(wip_html, brut_html) - else : wip_html = brut_html - - -#=========================# -# Done when command check # -# - convert_bcodes() # -# - convert_icodes() # -#=========================# -#====================================# -# Protect bCodes contents to base64 # -# fm: First marker ; lm: last marker # -#-----------------------------------=# -def convert_bcodes(article, fm, lm, css): - global article_temp - - article_temp = '' - bCode = False - bCode_lines = '' - bCode_ln = 0 - - for line in article: - if line.startswith(fm): - bCode = True - if article_temp: article_temp = '%s\n%s'%(article_temp, line) - else : article_temp = line - continue - - if line.startswith(lm): - bCode = False - - convert_to_b64(bCode_lines) - bCode_lines = '' - article_temp = '%s\n%s\n%s'%( - article_temp, b64_content, line - ) - continue - - if bCode: - bCode_ln += 1 - line = '
    %s
    '%( - bCode_ln, line, line - ) - if bCode_lines: bCode_lines = '%s\n%s'%(bCode_lines, line) - else : bCode_lines = line - else: - if article_temp: article_temp = '%s\n%s'%(article_temp, line) - else : article_temp = line - -#====================================# -# Protect iCodes contents to base64 # -# fm: First marker ; lm: last marker # -#-----------------------------------=# -def convert_icodes(article, css): - import re - global article_temp - - article_temp = '' - fm1 = '<_' - lm1 = '_>' - fm2 = '(_' ; fm2_r = '\(_' - lm2 = '_)' ; lm2_r = '_\)' - - for line in article: - # Specific marker format - if fm1 and lm1 in line: - iCodes = re.findall(r"%s(.*?)%s"%(fm1,lm1), line) - for iCode in iCodes: - convert_to_b64(iCode) - line = line.replace(fm1 + iCode + lm1, - fm1 + b64_content + lm1 - ) - - # Legacy marker format - if fm2 and lm2 in line: - iCodes = re.findall(r"%s(.*?)%s"%(fm2_r,lm2_r), line) - for iCode in iCodes: - convert_to_b64(iCode) - line = line.replace(fm2 + iCode + lm2, - fm2 + b64_content + lm2 - ) - - article_temp = '%s%s\n'%( - article_temp, line - ) - - -#=======================================# -# Convert all base64 to legacy contents # -#---------------------------------------# -def convert_all_b64(wip_lines): - global wip_html - - wip_tmp = '' - - for line in wip_lines: - b64s = re.findall(r'B64\|(.*?)\|B64', line) - for b64 in b64s: - convert_from_b64(b64) - line = line.replace('B64|%s|B64'%b64, src_content) - if wip_tmp: wip_tmp = wip_tmp + line + '\n' - else : wip_tmp = line + '\n' - - wip_html = wip_tmp - - -#=======# -# TOOLS # -#=======#-------------------------------------------------------------- -#==========================# -# Get Writer's CSS config # -# For compatible's markers # -# css_gen: generic value # -#--------------------------# -def get_css(line): - global css_set - try : css_set = line.split(" ")[1] - except: css_set = domain.domain_css - - -#=====================================# -# Base64 # -# Mainly used when article is checked # -#-------------------------------------#-------------------------------- -#===========================# -# Convert content TO base64 # -#---------------------------# -def convert_to_b64(post_content): - import base64 - global b64_content - - post_content_base64 = '' - content_bytes = post_content.encode("utf8") - base64_bytes = base64.b64encode(content_bytes) - b64_content = 'B64|' + base64_bytes.decode("utf8") + '|B64' - -#================================# -# Convert FROM base64 to content # -#--------------------------------# -def convert_from_b64(post_content): - import base64 - global src_content - - post_content_src = '' - content_bytes = post_content.encode("utf8") - base64_bytes = base64.b64decode(content_bytes) - src_content = base64_bytes.decode("utf8") - - -#=======================# -# Tabulations formating # -#-----------------------# -def tab_article(article): - global wip_html - - wip_tmp = '' - tab = 0 - - for line in article: - if len(line) == 0: continue - - if line.startswith(' Date: Thu, 15 Dec 2022 12:45:24 +0100 Subject: [PATCH 063/247] New cleaned code --- src/usr/bin/tyto | 117 ++-- src/var/lib/tyto/help/CHANGELOG.md | 16 + src/var/lib/tyto/help/FR_Installation.md | 21 + src/var/lib/tyto/help/LICENSE | 661 +++++++++++++++++++++++ src/var/lib/tyto/help/README.md | 180 ++++++ 5 files changed, 927 insertions(+), 68 deletions(-) create mode 100644 src/var/lib/tyto/help/CHANGELOG.md create mode 100644 src/var/lib/tyto/help/FR_Installation.md create mode 100644 src/var/lib/tyto/help/LICENSE create mode 100644 src/var/lib/tyto/help/README.md diff --git a/src/usr/bin/tyto b/src/usr/bin/tyto index 9ee6d8e..1680482 100755 --- a/src/usr/bin/tyto +++ b/src/usr/bin/tyto @@ -21,81 +21,62 @@ # comments: #---------------------------------------------------------------------- -''' -All scripts are in /var/lib/tyto/program/ -Directories that must be writeable by Tyto - - /var/lib/tyto/db/ - - /var/log/tyto/ - - /[LOCAL Server]/ (registred per domain) -''' - #********************************************************************** -# Import needed libs and tyto's libs import sys sys.path.insert(0, '/var/lib/tyto/program') -import check, wip, domain, log, sidebar, publish - -#=======# -# Tools # -#=======#-------------------------------------------------------------- -#=======================================# -# Check argument from main command line # -# # total arguments # -#---------------------------------------# -def tyto_args(ta): - global file_post, Opt - Domain = False - Opt = '' - Target = '' - - # Start process accoring to first argument action - Actions = { 'check' : check.manage_check, - 'wip' : wip.manage_wip, - 'domain' : domain.manage_domain, - 'log' : log.manage_log, - 'sidebar' : sidebar.manage_sidebar, - 'publish' : publish.manage_publish - } - - # Dict for Options - Options = { - '-R' : "Remove", 'remove' : "Remove", - '-n' : "New", 'new' : "New", - '-e' : "Edit", 'edit' : "Edit", - '-F' : "Force", 'force' : "Force" - } - - # Set Opt from other arguments options - # Set Target for article or new domain name - if sys.argv[1] == 'domain': Domain = True - - for i in range(2, ta): - if sys.argv[i].endswith('.tyto'): - Target = sys.argv[i] - if Target[0] == '/': - Target = Target[1:len(Target)] - else: - try: - Opt = Options[sys.argv[i]] - except: - if Domain: - Target = sys.argv[i] - else: - print(':( Invalid option "%s"'%sys.argv[i]) - sys.exit(0) - - try: - Actions[sys.argv[1]](Target, Opt) - except KeyError: - print(':< Invalid action "%s"'%sys.argv[1]) - - - +import check, domain, wip, sidebar #====================# # MAIN # # Treat Arguments # #--------------------#------------------------------------------------- -tyto_args(len(sys.argv)) +if not __name__ == "__main__": + print(':< Mismatch program start') + sys.exit(1) + +noarg = False +target = '' +option = '' + +# Command start argument +actions = { + 'check' : check.manage_check, + 'wip' : wip.manage_wip, + 'domain' : domain.manage_domain, + 'sidebar' : sidebar.manage_sidebar + } + +# Dict for Options +options = { + '-a' : 'Add', 'add' : 'Add', + '-R' : "Remove", 'remove' : "Remove", + '-n' : "New", 'new' : "New", + '-e' : "Edit", 'edit' : "Edit", + '-F' : "Force", 'force' : "Force" + } + +# Set Argument 2 or 3 +#-------------------- +for i in range(2,4): + try: + sys.argv[i] + try: + if not option: option = options[sys.argv[i]] + else: target: target = sys.argv[i] + except: + if not target: target = sys.argv[i] + else: option: option = options[sys.argv[i]] + except: + noarg = True + + if noarg: continue + + +# Argument 1 +#----------- +try: + actions[sys.argv[1]](target, option) +except KeyError: + print(':< Invalid action "%s": [check, wip...]'%sys.argv[1]) diff --git a/src/var/lib/tyto/help/CHANGELOG.md b/src/var/lib/tyto/help/CHANGELOG.md new file mode 100644 index 0000000..75c6ac6 --- /dev/null +++ b/src/var/lib/tyto/help/CHANGELOG.md @@ -0,0 +1,16 @@ +# Changelog + +Tyto - Littérateur +- Repository: https://git.a-lec.org/echolib/tyto +- Issues: https://git.a-lec.org/echolib/tyto/-/issues +- Changelog: https://git.a-lec.org/echolib/tyto/-/blob/main/CHANGELOG.md +- License: https://git.a-lec.org/echolib/tyto/-/blob/main/LICENSE + +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 static pages. Tyto works on a GNU/Linux system +and needs minimal dependancies. +- python3 rsync nano gawk curl + +## [0.9.0] First Commit version (pre-final) + diff --git a/src/var/lib/tyto/help/FR_Installation.md b/src/var/lib/tyto/help/FR_Installation.md new file mode 100644 index 0000000..f508aec --- /dev/null +++ b/src/var/lib/tyto/help/FR_Installation.md @@ -0,0 +1,21 @@ +# Installation manuelle + +Si vous utilisez Debian, il est plus que recommandé de procéder à +l'installation par le paquet .deb + +## Préparer les dossiers +```` +sudo mkdir -p /var/lib/tyto /etc/tyto /var/log/tyto +sudo touch /usr/local/bin/tyto +sudo chown -R USER:GROUP /var/lib/tyto /etc/tyto /var/log/tyto +sudo chown USER:GROUP /usr/local/bin/tyto +sudo chmod +x /usr/local/bin/tyto + +git clone https://git.a-lec.org/echolib/tyto +rsync -a folders'repo/ to /folders/ + +# Créer votre dossier pour le serveur web +# On utilise en général /var/www/ +# Celui-ci sera à renseigner lors de la création d'un domaine dans Tyto +sudo mkdir -p /var/www/ +```` diff --git a/src/var/lib/tyto/help/LICENSE b/src/var/lib/tyto/help/LICENSE new file mode 100644 index 0000000..2a1caa8 --- /dev/null +++ b/src/var/lib/tyto/help/LICENSE @@ -0,0 +1,661 @@ + GNU AFFERO GENERAL PUBLIC LICENSE + Version 3, 19 November 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU Affero General Public License is a free, copyleft license for +software and other kinds of works, specifically designed to ensure +cooperation with the community in the case of network server software. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +our General Public Licenses are intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + Developers that use our General Public Licenses protect your rights +with two steps: (1) assert copyright on the software, and (2) offer +you this License which gives you legal permission to copy, distribute +and/or modify the software. + + A secondary benefit of defending all users' freedom is that +improvements made in alternate versions of the program, if they +receive widespread use, become available for other developers to +incorporate. Many developers of free software are heartened and +encouraged by the resulting cooperation. However, in the case of +software used on network servers, this result may fail to come about. +The GNU General Public License permits making a modified version and +letting the public access it on a server without ever releasing its +source code to the public. + + The GNU Affero General Public License is designed specifically to +ensure that, in such cases, the modified source code becomes available +to the community. It requires the operator of a network server to +provide the source code of the modified version running there to the +users of that server. Therefore, public use of a modified version, on +a publicly accessible server, gives the public access to the source +code of the modified version. + + An older license, called the Affero General Public License and +published by Affero, was designed to accomplish similar goals. This is +a different license, not a version of the Affero GPL, but Affero has +released a new version of the Affero GPL which permits relicensing under +this license. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU Affero General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Remote Network Interaction; Use with the GNU General Public License. + + Notwithstanding any other provision of this License, if you modify the +Program, your modified version must prominently offer all users +interacting with it remotely through a computer network (if your version +supports such interaction) an opportunity to receive the Corresponding +Source of your version by providing access to the Corresponding Source +from a network server at no charge, through some standard or customary +means of facilitating copying of software. This Corresponding Source +shall include the Corresponding Source for any work covered by version 3 +of the GNU General Public License that is incorporated pursuant to the +following paragraph. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the work with which it is combined will remain governed by version +3 of the GNU General Public License. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU Affero General Public License from time to time. Such new versions +will be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU Affero General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU Affero General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU Affero General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + GSL Statique Littérateur + Copyright (C) 2022 Libre en Communs / Commissions / Infrastructure + + 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 . + +Also add information on how to contact you by electronic and paper mail. + + If your software can interact with users remotely through a computer +network, you should also make sure that it provides a way for users to +get its source. For example, if your program is a web application, its +interface could display a "Source" link that leads users to an archive +of the code. There are many ways you could offer source, and different +solutions will be better for different programs; see section 13 for the +specific requirements. + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU AGPL, see +. diff --git a/src/var/lib/tyto/help/README.md b/src/var/lib/tyto/help/README.md new file mode 100644 index 0000000..9f49fa4 --- /dev/null +++ b/src/var/lib/tyto/help/README.md @@ -0,0 +1,180 @@ +# STL: Statique Littérateur +STL est une évolution du projet GSL. STL permet de créer un ou plusieurs +sites web/blogs statiques, en fonction de leur nom de domaine. + +Tout comme GSL, STL reprend une grande partie de l'écriture nouvelle de +vos articles, en apportant quelques évolutions. Les articles sont donc +au format .stl. + + +# Fonctionnement de STL ; le dossier de base +Contrairement à GSL, vos articles et les pages de votre site web sont +situés dans le même dossier de base. Pour obtenir ce dossier de base, +et configurer votre domaine, vous devez d'abord vous placer dans le +dossier de votre choix, puis lancer la commande de configuration. + +``` +cd MON-DOSSIER-PREFERE +stl domain new + +# Vous pouvez également pré-remplir votre domaine en fonction de l'URL +stl domain new https://mon-site.xyz +``` + +Dans ce dossier de base (MON-DOSSIER-PREFERE), après la configuration de +votre domaine, vous trouverez de nouveaux dossiers : +- articles/ +- - images/ +- - files/ + +Les sous-dossiers images/ et files/ sont proposés afin de faciliter la +réutilisation d'images et de fichiers (PDF, ou autres) déjà présents +dans un autre article. Lors de la synchronisation, il seront copiés à la +racine wip de votre serveur. Le but : faire en sorte que le +navigateur n'ait pas à recharger un même fichier depuis une URL +différente - ce qui plomberait la rapidité d'affichage de la page et +l'intérêt d'un site statique. L'utilisation de cette fonction dans vos +articles est simple ; voir la documentation expliquant comment écrire un +article dans le dossier help. + +Dans le dossier du serveur (/var/www est un exemple), vous trouverez +les dossiers suivants : +- /var/www/DOMAIN/wip/ +- - template (logos, styles.css, sidebar.html, footer.html, metas.html...) +- - images +- - files +- /var/www/DOMAIN/www/ (non créé pour une installation locale) +- - template/ +- - images +- - files + + +## Installation (server, ou local) +Il est possible d'utiliser STL de 2 manières différentes. Lors de la +configuation d'un nouveau domaine, vous devrez choisir entre une +installation faite sur un serveur distant, et une installation faite +en local (sur votre PC). Vous pouvez bien sûr choisir une installation +de type "server" sur votre PC, si celui-ci sert de serveur web. + +Concernant la décoration du site (styles.css, logos), les fichiers +devront être placés dans le dossier serveur /wip/template/ (créé par STL +lors de l'ajout d'un domaine). + + +### Installation "server" +À choisir si votre PC sert de serveur web, ou si vous avez installé STL +sur votre serveur distant. + +Lorsque vous installez STL, sur votre serveur distant, vous pouvez gérer +pour un même nom de domaine, votre site sur 2 adresses URL différentes. +La version WIP, permet de prévisualiser les modifications apportées à +vos pages (sans modifier celles sur WWW) avant de les valider sur votre +site officiel. + +Lorsque votre site prévisualisé sur WIP vous plaît, vous pouvez alors +synchroniser le dossier WIP sur WWW grâce à la commande : + +``` +# Pour publier un article précis +stl publish (ARTICLE) + +# Pour publier tous les articles dans WIP +stl publish all +``` + +Note : cette commande crée automatiquement le flux RSS dans WIP avant +de tous synchroniser sur WWW. + + +### Installation "local" +À choisir si vous voulez utiliser STL sur votre PC, et synchroniser +vous-même le dossier WIP sur votre serveur distant. Inutile donc, +d'installer STL sur le serveur distant. + +Lors d'une utilisation locale, STL ne crée pas le dossier WWW, et ne +synchronise donc pas le dossier WIP vers WWW. C'est à vous de le faire +(via ssh, par exemple). + +Vous devrez lorsque votre site vous plaît localement lancer la création +du flux RSS - avant de synchroniser votre site local sur votre serveur +distant - avec la commande : + +``` +stl rss +``` + + +# Utilisation de STL +Afin de gérer vos articles, vous devez vous placer dans MON-DOSSIER-PREFERE. +L'autocomplétion est activée et personnalisée pour vous aider à trouver +(ARTICLE.stl). + + +## Créer votre arborescence +Dans MON-DOSSIER-PREFERE, vous trouverez le dossier "articles". Celui-ci +sert de base à votre domain.xyz sur votre serveur. C'est dans ce dossier +"articles", que vous pouvez créer vos articles et vos sous-dossiers. +Il est à noter que le nom de l'article est important, puisque STL +l'utilisera en le transformant en .html. Il est donc recommandé - mais +pas obligatoire - de nommer vos articles index.stl, pour obtenir une page +index.html. Si vous voulez créer une page 404, nommez votre article 404.stl +à la racine du dossier "articles". + + +## Convertir votre article en HTML +Placez vous dans MON-DOSSIER-PREFERE. + +Avant de pouvoir convertir votre article, STL dispose d'un système de +vérification de la syntaxe STL. Si des erreurs sont trouvées, un système +de logs vous aidera à corriger ces erreurs. + +``` +# N'oubliez pas d'utiliser l'autocomplétion +stl check (ARTICLE.stl) +``` + +Vous pouvez maintenant le convertir en HTML dans le dossier wip + +``` +stl wip (ARTICLE.stl) +``` + + +## Utiliser la sidebar +C'est la seule partie du site qui est semi-statique. STL fait appel à +nginx, qui va se charger de traduire la balise HTML ``, +et afficher le rendu du fichier sidebar.html + +Chaque article, une fois convertit avec l'argument wip peut être placé +dans la sidebar à la position désirée, entre 1 et la valeur maximum +décidée, lors de la configuration du domaine. + +``` +stl sidebar add 1 (ARTICLE.stl) +``` + +Vous pouvez également décider de placer un article ausitôt convertit +avec l'argument wip sidebar=POSITON + +``` +stl wip sidebar=2 (ARTICLE.stl) +``` + +## Documentation de STL +Les fichiers de documentations sont dans le dossier help. +Le README est accessible depuis la ligne de commande, comme les arguments +utilisables. + +``` +stl help +stl readme +``` + + +## Dépendances +STL est écrit en bash, et a besoin des utilitaires +- gawk +- rsync +- nano +- curl + From 4491cb94d23d10c5b0cfcdaa278ff5385f318dad Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Fri, 16 Dec 2022 11:36:43 +0100 Subject: [PATCH 064/247] New cleaned code. Indev for wip. Some convertions done --- src/var/lib/tyto/program/check.py | 7 +- src/var/lib/tyto/program/tyto.py | 53 +++++++++++- src/var/lib/tyto/program/wip.py | 131 ++++++++++++++++++++++++++++-- 3 files changed, 180 insertions(+), 11 deletions(-) diff --git a/src/var/lib/tyto/program/check.py b/src/var/lib/tyto/program/check.py index aab12c7..6751e9a 100644 --- a/src/var/lib/tyto/program/check.py +++ b/src/var/lib/tyto/program/check.py @@ -63,7 +63,7 @@ def manage_check(target, option): article_bottom = tyto.protect_article # Protect block-codes and quotes - tyto.protect_bcodes_quotes('check', post_bottom) + tyto.protect_bcodes_quotes('check', post_bottom, article_bottom) post_bottom = tyto.protect_article.rsplit('\n') article_bottom = tyto.protect_article @@ -99,13 +99,13 @@ def isin(term, post_bottom): # Check if separator or exit # #---------------------------------# def file_to_string(post_file): - # Check if separator global article global article_header, article_bottom global post_header, post_bottom article = open(post_file, 'r').read() + # Check if separator or exit if not '-----' in article: tyto.exiting("6", '-----', True) @@ -528,8 +528,11 @@ def check_content(post_bottom): # Create new article's database at each check ! # #-----------------------------------------------# def create_database(): + # No first / from dir post web_uri = tyto.web_uri[1: len(tyto.web_uri)] + # No need index.html for web link if tyto.web_uri.endswith('index.html'): tyto.web_uri = '/' + database = '# Post Configuration for Tyto\n' + \ 'post_id = "%s"\n'%tyto.uri_id + \ 'root_uri = "%s"\n'%tyto.uri_root + \ diff --git a/src/var/lib/tyto/program/tyto.py b/src/var/lib/tyto/program/tyto.py index c95bf51..1171226 100644 --- a/src/var/lib/tyto/program/tyto.py +++ b/src/var/lib/tyto/program/tyto.py @@ -128,7 +128,6 @@ words_tags = [ ('-(', '-)', '-(', '-)', 'lists', 't') ] - # Tags that do not need to be paired #----------------------------------- single_tags = [ @@ -312,11 +311,12 @@ def protect_icodes(post_bottom, article_bottom): # For check, create new article without bcode # # For wip, remplace content with base64 # #---------------------------------------------# -def protect_bcodes_quotes(process, post_bottom): +def protect_bcodes_quotes(process, post_bottom, article_bottom): global protect_article in_bcode = in_quote = False protect_article = '' + temp_article = article_bottom if process == 'check': global nbr_titles, nbr_bcodes, nbr_quotes # Stats for DB @@ -349,7 +349,54 @@ def protect_bcodes_quotes(process, post_bottom): if not protect_article: protect_article = line else: protect_article = '%s\n%s'%(protect_article, line) - + + # For wip, bcodes are converted to base64 + #---------------------------------------- + elif process == 'wip': + + # Convert bcodes and quotes + # include markers in base64, remove from article + bcode = quote = '' + for ln, line in enumerate(post_bottom): + # bcode + if line.startswith(words_tags[12][0]): + in_bcode = True + elif line.startswith(words_tags[12][1]): + bcode = '%s\n%s'%(bcode, line) + in_bcode = False + b64_bcode = b64('Encode', bcode) + protect_article = '%s\n%s'%(protect_article, b64_bcode) + bcode = '' + continue + elif line.startswith('#'): # As convention + if not line.startswith(titles_tags): + continue + + # quote + elif line.startswith(words_tags[11][0]): + if not in_bcode: + in_quote = True + elif line.startswith(words_tags[11][1]): + if not in_bcode: + quote = '%s\n%s'%(quote, line) + in_quote = False + b64_quote = b64('Encode', quote) + protect_article = '%s\n%s'%(protect_article, b64_quote) + quote = '' + continue + + # Priority to bcode + if in_bcode: + if bcode: bcode = '%s\n%s'%(bcode, line) + else: bcode = line + else: + if in_quote: + if quote: quote = '%s\n%s'%(quote, line) + else: quote = line + else: + if not protect_article: protect_article = line + else: protect_article = '%s\n%s'%(protect_article, line) + #=====================================# # Encode/Decode string to/from base64 # diff --git a/src/var/lib/tyto/program/wip.py b/src/var/lib/tyto/program/wip.py index c666c84..38d3a1f 100644 --- a/src/var/lib/tyto/program/wip.py +++ b/src/var/lib/tyto/program/wip.py @@ -25,6 +25,7 @@ def manage_wip(target, option): # Article exists + has DB ? db_exists = tyto.get_db_post(target) + target = tyto.uri_root if not db_exists: tyto.exiting("4", '', True) @@ -39,7 +40,7 @@ def manage_wip(target, option): # In any case, if Force if option == 'Force': - wip_article() + wip_article(target) return # Compare and check file @@ -52,7 +53,7 @@ def manage_wip(target, option): if hash_wip: if not is_file: tyto.exiting("1", wip_uri, False) if is_new: tyto.exiting("9", '', False) - wip_article() + wip_article(target) else: tyto.exiting("20", date_wip, True) @@ -61,9 +62,127 @@ def manage_wip(target, option): # Start wip modules # # Set Db # #-------------------# -def wip_article(): +def wip_article(target): print('Convert') + + # Convert file to strings + file_to_string(target) -# Convert anchors -#tyto.get_css(line) -#print(tyto.single_tags[1][1]%tyto.set_css) + global post_header, article_header + global post_bottom, article_bottom + + # Protect inline-codes + tyto.protect_icodes(post_bottom, article_bottom) + post_bottom = tyto.protect_article.rsplit('\n') + article_bottom = tyto.protect_article + + # Protect block-codes and quotes + tyto.protect_bcodes_quotes('wip', post_bottom, article_bottom) + post_bottom = tyto.protect_article.rsplit('\n') + article_bottom = tyto.protect_article + + # Convert contents from modules + wip_single_tags() # br /, anchors + wip_words_tags() # Paragraphs, strongs, italics + wip_links() # Links from headers in DB + + print(article_bottom) + +#=================================# +# Create string article from file # +# post is string splitted '\n' # +# article is string not splitted # +#---------------------------------# +def file_to_string(target): + global article + global article_header, article_bottom + global post_header, post_bottom + + article = open(target, 'r').read() + + # Set from separator, NOT splitted by new line + article_header = article.rsplit('-----')[0] + article_bottom = article.rsplit('-----')[1] + + # Set from separator, splitted by new line + post_header = article.rsplit('-----')[0].rsplit('\n') + post_bottom = article.rsplit('-----')[1].rsplit('\n') + + +#=============================# +# Convert tags (br /, anchor) # +#-----------------------------# +def wip_single_tags(): + global article_bottom + + #
    from "|" + article_bottom = article_bottom.replace( + tyto.single_tags[0][0], tyto.single_tags[0][1] + ) + + for line in article_bottom.rsplit('\n'): + if line.startswith(tyto.single_tags[1][0]): + set_css = tyto.get_css(line) + article_bottom = article_bottom.replace( + line, + tyto.single_tags[1][1]%set_css + ) + + +#==================================# +# Convert tags (strong, icodes...) # +# Convert Paragraphs # +#----------------------------------# +def wip_words_tags(): + global article_bottom + + # Strongs, italics... (8 tags) + m = 0 + for tag in tyto.words_tags: + if m > 8: break + + # Open tag + article_bottom = article_bottom.replace(tag[0], tag[2]) + # Close tag + article_bottom = article_bottom.replace(tag[1], tag[3]) + m += 1 + + # Paragraphs + for ln, line in enumerate(article_bottom.rsplit('\n')): + # Open tag + if line.startswith(tyto.words_tags[10][0]): + set_css = tyto.get_css(line) + article_bottom = article_bottom.replace( + article_bottom.rsplit('\n')[ln], + tyto.words_tags[10][2]%set_css + ) + # Close tag + if line.startswith(tyto.words_tags[10][1]): + article_bottom = article_bottom.replace( + line, + tyto.words_tags[10][3] + ) + + +#=======================# +# Convert links from DB # +# - link_%i # +# - file_%i # +#-----------------------# +def wip_links(): + global article_bottom + + if uniq_links > 0: + for i in range(1, uniq_links + 1): + link = 'link_%s'%i + article_bottom = article_bottom.replace( + eval(link)[0], eval(link)[1] + ) + + if uniq_files > 0: + for i in range(1, uniq_files + 1): + file = 'file_%s'%i + article_bottom = article_bottom.replace( + eval(file)[0], eval(file)[1] + ) + From 38e977ec1dfd5ff60aed840d9ec5b741060d8691 Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Sat, 17 Dec 2022 11:42:31 +0100 Subject: [PATCH 065/247] New code cleaned. Indev: wip. Some converting done --- README.md | 17 ++++-- src/var/lib/tyto/program/check.py | 10 ++-- src/var/lib/tyto/program/wip.py | 99 +++++++++++++++++++++++++++---- 3 files changed, 106 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 6a2121e..d6e14ae 100644 --- a/README.md +++ b/README.md @@ -110,14 +110,19 @@ un long paragraphe ### Lien vers URL ``` -Voir ce _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 ``` -Voir ce __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: + ### Gras, Strong, italique... ``` *_très gras_* # @@ -148,11 +153,11 @@ Avec ce NOM. # affichage les une à côté des autres _image:NOM _image:NOM c=CSS -_image:NOM c=CSS w=1080 +_image:NOM c=css w=1080 _image:NOM w=640em h=480em -_image:NOM t= <<< Rend l'image interne cliquable -_image:NOM t=https://... -_image:NOM c=CSS t=https:// w=320px h=240 +_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 diff --git a/src/var/lib/tyto/program/check.py b/src/var/lib/tyto/program/check.py index 6751e9a..85af71c 100644 --- a/src/var/lib/tyto/program/check.py +++ b/src/var/lib/tyto/program/check.py @@ -277,8 +277,9 @@ def check_headers(post_header): post_err = True if not post_err: - web_link = '%s'%( - 'link', link_url, link_alt, link_name + web_link = '%s'%( + '%s', link_alt, link_name ) globals()['link_%s'%stat_links] = ( '_%s'%link_name, web_link @@ -388,8 +389,9 @@ def check_headers(post_header): post_err = True if not post_err: - web_link = '%s'%( - 'file', web_uri, file_alt, file_name + web_link = '%s'%( + '%s', file_alt, file_name ) globals()['file_%s'%stat_files] = ( '__%s'%file_name, web_link diff --git a/src/var/lib/tyto/program/wip.py b/src/var/lib/tyto/program/wip.py index 38d3a1f..696f48c 100644 --- a/src/var/lib/tyto/program/wip.py +++ b/src/var/lib/tyto/program/wip.py @@ -16,7 +16,7 @@ #---------------------------------------------------------------------- #********************************************************************** -import os +import os, re import tyto def manage_wip(target, option): @@ -84,7 +84,8 @@ def wip_article(target): # Convert contents from modules wip_single_tags() # br /, anchors wip_words_tags() # Paragraphs, strongs, italics - wip_links() # Links from headers in DB + wip_links() # Links_%i from headers in DB + wip_images() # Images_%i from headers in DB print(article_bottom) @@ -172,17 +173,95 @@ def wip_words_tags(): def wip_links(): global article_bottom - if uniq_links > 0: - for i in range(1, uniq_links + 1): - link = 'link_%s'%i - article_bottom = article_bottom.replace( - eval(link)[0], eval(link)[1] - ) - + # Doing files, first, becase of similar marker if uniq_files > 0: for i in range(1, uniq_files + 1): file = 'file_%s'%i article_bottom = article_bottom.replace( - eval(file)[0], eval(file)[1] + eval(file)[0]+'+', eval(file)[1]%('_blank') + ) + article_bottom = article_bottom.replace( + eval(file)[0], eval(file)[1]%('_self') ) + if uniq_links > 0: + for i in range(1, uniq_links + 1): + link = 'link_%s'%i + article_bottom = article_bottom.replace( + eval(link)[0]+'+', eval(link)[1]%('_blank') + ) + article_bottom = article_bottom.replace( + eval(link)[0], eval(link)[1]%('_self') + ) + +#-------------------------------------# +# Get width and height for image # +# from parameter c=, from wip_image() # +#-------------------------------------# +def get_wh_image(value): + sizes = re.findall(r'(\d+)|(\D+)', value) + if not sizes[0][1]: return('%spx'%value) + else: return(value) + +#=================================# +# Find all _image, get parameters # +# Convert _images:%name to HTML # +#---------------------------------# +def wip_images(): + global article_bottom + + if uniq_images > 0: + image_link = '%s' + image_show = '%s' + + for ln, line in enumerate(article_bottom.rsplit('\n')): + if line.startswith('_image:'): + values = line.rsplit(' ') + #print(values) + + for i in range(1, uniq_images + 1): + image = 'image_%s'%i + target = width = height = False + set_css = tyto.domain_css + '_image' + + if eval(image)[0] == values[0]: + for value in values: + if 't=' in value: + target = value.rsplit('=',1)[1] + if target == "+": image_target = eval(image)[1] + else: image_target = target + + if 'c=' in value: + set_css = value.rsplit('=', 1)[1] + + if 'w=' in value: + width = get_wh_image(value.rsplit('=',1)[1]) + + if 'h=' in value: + height = get_wh_image(value.rsplit('=',1)[1]) + + if width and height: + style = ' style="width:%s;height=%s"'%(width, height) + elif width: + style = ' style="width:%s"'%width + elif height: + style = ' style="height:%s"'%height + else: + style = '' + + image_src = image_show%( + set_css, eval(image)[1], eval(image)[2], style + ) + + if target: + image_tgt = image_link%( + set_css, image_target, eval(image)[2], '%s' + ) + else: + image_tgt = '%s' + + image_html = image_tgt%image_src + + article_bottom = article_bottom.replace( + article_bottom.rsplit('\n')[ln], image_html + ) From fc1c059fda16cf9b3274e618da9fe25819205d01 Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Sun, 18 Dec 2022 14:56:36 +0100 Subject: [PATCH 066/247] New code cleaned. Indev: wip. Some converting done --- src/var/lib/tyto/program/wip.py | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/var/lib/tyto/program/wip.py b/src/var/lib/tyto/program/wip.py index 696f48c..f9e4fb2 100644 --- a/src/var/lib/tyto/program/wip.py +++ b/src/var/lib/tyto/program/wip.py @@ -214,17 +214,21 @@ def wip_images(): image_link = '%s' image_show = '%s' + # Check each line for ln, line in enumerate(article_bottom.rsplit('\n')): + # match line if line.startswith('_image:'): values = line.rsplit(' ') - #print(values) + # search match tag in DB for i in range(1, uniq_images + 1): image = 'image_%s'%i target = width = height = False set_css = tyto.domain_css + '_image' + imag_html = '' if eval(image)[0] == values[0]: + # Get parameters from match line for value in values: if 't=' in value: target = value.rsplit('=',1)[1] @@ -249,10 +253,12 @@ def wip_images(): else: style = '' + # set from parameter image_src = image_show%( set_css, eval(image)[1], eval(image)[2], style ) + # Set link for image if target: image_tgt = image_link%( set_css, image_target, eval(image)[2], '%s' @@ -260,8 +266,10 @@ def wip_images(): else: image_tgt = '%s' + # Set HTML to replace line number image_html = image_tgt%image_src - - article_bottom = article_bottom.replace( - article_bottom.rsplit('\n')[ln], image_html - ) + + article_bottom = article_bottom.replace( + article_bottom.rsplit('\n')[ln], image_html + ) + From b8ddd5666202c24ee130e129a6e59fa3c0312cb5 Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Sun, 18 Dec 2022 15:03:27 +0100 Subject: [PATCH 067/247] Readme --- src/var/lib/tyto/help/FR_Installation.md | 21 -- src/var/lib/tyto/help/README.md | 286 +++++++++++------------ 2 files changed, 136 insertions(+), 171 deletions(-) delete mode 100644 src/var/lib/tyto/help/FR_Installation.md diff --git a/src/var/lib/tyto/help/FR_Installation.md b/src/var/lib/tyto/help/FR_Installation.md deleted file mode 100644 index f508aec..0000000 --- a/src/var/lib/tyto/help/FR_Installation.md +++ /dev/null @@ -1,21 +0,0 @@ -# Installation manuelle - -Si vous utilisez Debian, il est plus que recommandé de procéder à -l'installation par le paquet .deb - -## Préparer les dossiers -```` -sudo mkdir -p /var/lib/tyto /etc/tyto /var/log/tyto -sudo touch /usr/local/bin/tyto -sudo chown -R USER:GROUP /var/lib/tyto /etc/tyto /var/log/tyto -sudo chown USER:GROUP /usr/local/bin/tyto -sudo chmod +x /usr/local/bin/tyto - -git clone https://git.a-lec.org/echolib/tyto -rsync -a folders'repo/ to /folders/ - -# Créer votre dossier pour le serveur web -# On utilise en général /var/www/ -# Celui-ci sera à renseigner lors de la création d'un domaine dans Tyto -sudo mkdir -p /var/www/ -```` diff --git a/src/var/lib/tyto/help/README.md b/src/var/lib/tyto/help/README.md index 9f49fa4..d6e14ae 100644 --- a/src/var/lib/tyto/help/README.md +++ b/src/var/lib/tyto/help/README.md @@ -1,180 +1,166 @@ -# STL: Statique Littérateur -STL est une évolution du projet GSL. STL permet de créer un ou plusieurs -sites web/blogs statiques, en fonction de leur nom de domaine. +# Tyto -Tout comme GSL, STL reprend une grande partie de l'écriture nouvelle de -vos articles, en apportant quelques évolutions. Les articles sont donc -au format .stl. - - -# Fonctionnement de STL ; le dossier de base -Contrairement à GSL, vos articles et les pages de votre site web sont -situés dans le même dossier de base. Pour obtenir ce dossier de base, -et configurer votre domaine, vous devez d'abord vous placer dans le -dossier de votre choix, puis lancer la commande de configuration. +## Répertoire de code du projet Tyto +## Comment définir les métas ``` -cd MON-DOSSIER-PREFERE -stl domain new +# Obligatoires uniques +title: Titre +about: Infos de l'article +author: Autheur +tags: mots-clé-1,mots-clé-2 +date: YYYY-MM-DD (AAAA-MM-JJ) -# Vous pouvez également pré-remplir votre domaine en fonction de l'URL -stl domain new https://mon-site.xyz +# Optionnels myltiples +link: Nom du lien + URL + Texte Alternatif + +image: Nom + URI + Texte Alternatif + +file: Nom du lien + URL + Texte Alternatif + +brut: Nom + URI + Texte Alternatif + +abbr: NOM (en majuscule) + Définition du NOM + nom (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 +---------- ``` -Dans ce dossier de base (MON-DOSSIER-PREFERE), après la configuration de -votre domaine, vous trouverez de nouveaux dossiers : -- articles/ -- - images/ -- - files/ - -Les sous-dossiers images/ et files/ sont proposés afin de faciliter la -réutilisation d'images et de fichiers (PDF, ou autres) déjà présents -dans un autre article. Lors de la synchronisation, il seront copiés à la -racine wip de votre serveur. Le but : faire en sorte que le -navigateur n'ait pas à recharger un même fichier depuis une URL -différente - ce qui plomberait la rapidité d'affichage de la page et -l'intérêt d'un site statique. L'utilisation de cette fonction dans vos -articles est simple ; voir la documentation expliquant comment écrire un -article dans le dossier help. - -Dans le dossier du serveur (/var/www est un exemple), vous trouverez -les dossiers suivants : -- /var/www/DOMAIN/wip/ -- - template (logos, styles.css, sidebar.html, footer.html, metas.html...) -- - images -- - files -- /var/www/DOMAIN/www/ (non créé pour une installation locale) -- - template/ -- - images -- - files - - -## Installation (server, ou local) -Il est possible d'utiliser STL de 2 manières différentes. Lors de la -configuation d'un nouveau domaine, vous devrez choisir entre une -installation faite sur un serveur distant, et une installation faite -en local (sur votre PC). Vous pouvez bien sûr choisir une installation -de type "server" sur votre PC, si celui-ci sert de serveur web. - -Concernant la décoration du site (styles.css, logos), les fichiers -devront être placés dans le dossier serveur /wip/template/ (créé par STL -lors de l'ajout d'un domaine). - - -### Installation "server" -À choisir si votre PC sert de serveur web, ou si vous avez installé STL -sur votre serveur distant. - -Lorsque vous installez STL, sur votre serveur distant, vous pouvez gérer -pour un même nom de domaine, votre site sur 2 adresses URL différentes. -La version WIP, permet de prévisualiser les modifications apportées à -vos pages (sans modifier celles sur WWW) avant de les valider sur votre -site officiel. - -Lorsque votre site prévisualisé sur WIP vous plaît, vous pouvez alors -synchroniser le dossier WIP sur WWW grâce à la commande : - +## Comment écrire un article +### Titre h1 à h6 ``` -# Pour publier un article précis -stl publish (ARTICLE) +#1 Titre 1 +(( +Un paragraphe +)) -# Pour publier tous les articles dans WIP -stl publish all +#2 Titre 2 ``` -Note : cette commande crée automatiquement le flux RSS dans WIP avant -de tous synchroniser sur WWW. - - -### Installation "local" -À choisir si vous voulez utiliser STL sur votre PC, et synchroniser -vous-même le dossier WIP sur votre serveur distant. Inutile donc, -d'installer STL sur le serveur distant. - -Lors d'une utilisation locale, STL ne crée pas le dossier WWW, et ne -synchronise donc pas le dossier WIP vers WWW. C'est à vous de le faire -(via ssh, par exemple). - -Vous devrez lorsque votre site vous plaît localement lancer la création -du flux RSS - avant de synchroniser votre site local sur votre serveur -distant - avec la commande : - +### Paragraphes ``` -stl rss +(( CSS +Un paragraphe +)) ``` - -# Utilisation de STL -Afin de gérer vos articles, vous devez vous placer dans MON-DOSSIER-PREFERE. -L'autocomplétion est activée et personnalisée pour vous aider à trouver -(ARTICLE.stl). - - -## Créer votre arborescence -Dans MON-DOSSIER-PREFERE, vous trouverez le dossier "articles". Celui-ci -sert de base à votre domain.xyz sur votre serveur. C'est dans ce dossier -"articles", que vous pouvez créer vos articles et vos sous-dossiers. -Il est à noter que le nom de l'article est important, puisque STL -l'utilisera en le transformant en .html. Il est donc recommandé - mais -pas obligatoire - de nommer vos articles index.stl, pour obtenir une page -index.html. Si vous voulez créer une page 404, nommez votre article 404.stl -à la racine du dossier "articles". - - -## Convertir votre article en HTML -Placez vous dans MON-DOSSIER-PREFERE. - -Avant de pouvoir convertir votre article, STL dispose d'un système de -vérification de la syntaxe STL. Si des erreurs sont trouvées, un système -de logs vous aidera à corriger ces erreurs. - +### Code Brut ``` -# N'oubliez pas d'utiliser l'autocomplétion -stl check (ARTICLE.stl) +{{ CSS +def hello_world(): + print("Hello") +}} ``` -Vous pouvez maintenant le convertir en HTML dans le dossier wip - +### Listes ul/ol ``` -stl wip (ARTICLE.stl) +-( CSS += Liste ul +== Sous-liste ul +=== Sous-sous-liste ul +++++ Sous-sous-sous-liste ol ++++ Sous-sous-liste ol +-) ``` - -## Utiliser la sidebar -C'est la seule partie du site qui est semi-statique. STL fait appel à -nginx, qui va se charger de traduire la balise HTML ``, -et afficher le rendu du fichier sidebar.html - -Chaque article, une fois convertit avec l'argument wip peut être placé -dans la sidebar à la position désirée, entre 1 et la valeur maximum -décidée, lors de la configuration du domaine. - +### Citations ``` -stl sidebar add 1 (ARTICLE.stl) +[[ 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 +]] ``` -Vous pouvez également décider de placer un article ausitôt convertit -avec l'argument wip sidebar=POSITON - +### Ancres ``` -stl wip sidebar=2 (ARTICLE.stl) +-> id +(( +un long paragraphe +)) +(( +>_id:Retourner au point d'ancre_< +)) ``` -## Documentation de STL -Les fichiers de documentations sont dans le dossier help. -Le README est accessible depuis la ligne de commande, comme les arguments -utilisables. - +### Retour à la ligne HTML ``` -stl help -stl readme +| #
    ``` +### Lien vers URL +``` +Voir ce _Nom du lien # Ouverture même fenêtre +Voir ce _Nom du lien+ # ouverture nouvelle fenêtre +``` -## Dépendances -STL est écrit en bash, et a besoin des utilitaires -- gawk -- rsync -- nano -- curl +### 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 en paragraphe pour chaque ou après "|" sinon, +# affichage les une à côté des autres +_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 +``` From c73e78f504fc10803d508223d842728f21dcbc9a Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Sun, 18 Dec 2022 15:08:26 +0100 Subject: [PATCH 068/247] Readme --- src/var/lib/tyto/help/README.md | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/var/lib/tyto/help/README.md b/src/var/lib/tyto/help/README.md index d6e14ae..b9f905e 100644 --- a/src/var/lib/tyto/help/README.md +++ b/src/var/lib/tyto/help/README.md @@ -149,15 +149,16 @@ Avec ce NOM. ### Images ``` # Chaque image doit être placée en début de ligne -# Placer en paragraphe pour chaque ou après "|" sinon, -# affichage les une à côté des autres -_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 +# 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 From eae4f8591c82b975b2775ae7d81b223b8465ac67 Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Sun, 18 Dec 2022 15:14:28 +0100 Subject: [PATCH 069/247] Readme --- README.md | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index d6e14ae..b9f905e 100644 --- a/README.md +++ b/README.md @@ -149,15 +149,16 @@ Avec ce NOM. ### Images ``` # Chaque image doit être placée en début de ligne -# Placer en paragraphe pour chaque ou après "|" sinon, -# affichage les une à côté des autres -_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 +# 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 From dff84b969ab723fde84fcc5ff77885c67cc87c18 Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Sun, 18 Dec 2022 15:34:29 +0100 Subject: [PATCH 070/247] fix: b64(). Indev for quotes --- src/var/lib/tyto/program/tyto.py | 12 ++++++------ src/var/lib/tyto/program/wip.py | 19 +++++++++++++++++++ 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/src/var/lib/tyto/program/tyto.py b/src/var/lib/tyto/program/tyto.py index 1171226..70a5747 100644 --- a/src/var/lib/tyto/program/tyto.py +++ b/src/var/lib/tyto/program/tyto.py @@ -287,7 +287,7 @@ def protect_icodes(post_bottom, article_bottom): if c_a == '}' and not c_b == '\\': incode = False code = '%s%s%s'%(code, src_code, words_tags[9][3]) - b64_code = b64('Encode', code) + b64_code = b64('Encode', code, 'I64_', '_I64') rep_code = "%s%s%s"%( words_tags[9][0],rep_code,words_tags[9][1] ) @@ -364,7 +364,7 @@ def protect_bcodes_quotes(process, post_bottom, article_bottom): elif line.startswith(words_tags[12][1]): bcode = '%s\n%s'%(bcode, line) in_bcode = False - b64_bcode = b64('Encode', bcode) + b64_bcode = b64('Encode', bcode, 'B64_', '_B64') protect_article = '%s\n%s'%(protect_article, b64_bcode) bcode = '' continue @@ -380,7 +380,7 @@ def protect_bcodes_quotes(process, post_bottom, article_bottom): if not in_bcode: quote = '%s\n%s'%(quote, line) in_quote = False - b64_quote = b64('Encode', quote) + b64_quote = b64('Encode', quote, 'Q64_', '_Q64') protect_article = '%s\n%s'%(protect_article, b64_quote) quote = '' continue @@ -402,19 +402,19 @@ def protect_bcodes_quotes(process, post_bottom, article_bottom): # Encode/Decode string to/from base64 # # Data protection # #-------------------------------------# -def b64(action, content): +def b64(action, content, before, after): if action == 'Encode': global b64_content b64_base64 = '' content_bytes = content.encode("ascii") base64_bytes = base64.b64encode(content_bytes) - b64_content = 'B64_' + base64_bytes.decode("ascii") + '_B64' + b64_content = before + base64_bytes.decode("ascii") + after return b64_content elif action == 'Decode': global src_content src_content = '' - content_bytes = post_content.encode("ascii") + content_bytes = content.encode("ascii") base64_bytes = base64.b64decode(content_bytes) src_content = base64_bytes.decode("ascii") return src_content diff --git a/src/var/lib/tyto/program/wip.py b/src/var/lib/tyto/program/wip.py index f9e4fb2..fec5fcb 100644 --- a/src/var/lib/tyto/program/wip.py +++ b/src/var/lib/tyto/program/wip.py @@ -86,6 +86,9 @@ def wip_article(target): wip_words_tags() # Paragraphs, strongs, italics wip_links() # Links_%i from headers in DB wip_images() # Images_%i from headers in DB + + # Quotes + wip_quotes() # Decode B64 and convert print(article_bottom) @@ -273,3 +276,19 @@ def wip_images(): article_bottom.rsplit('\n')[ln], image_html ) + +# +# INDEV: convert quote in article +# +def wip_quotes() : + global article_bottom + + for ln, line in enumerate(article_bottom.rsplit('\n')): + if line.startswith('Q64'): + line = line.replace('Q64_', '') + line = line.replace('_Q64', '') + quote = tyto.b64('Decode', line, 'Q64_', '_Q64').rsplit("\n") + + # Read the quote + for qline in quote: + print('>', qline) From a5c4db30944b6bcb49bed9ce7820b569a49623fa Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Sun, 18 Dec 2022 15:39:02 +0100 Subject: [PATCH 071/247] fix: b64(). Indev for quotes --- src/var/lib/tyto/program/wip.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/var/lib/tyto/program/wip.py b/src/var/lib/tyto/program/wip.py index fec5fcb..1afb991 100644 --- a/src/var/lib/tyto/program/wip.py +++ b/src/var/lib/tyto/program/wip.py @@ -291,4 +291,6 @@ def wip_quotes() : # Read the quote for qline in quote: - print('>', qline) + if line.startswith('tyto.words_tags[11][0]'): + set_css = get_css(line) + print(set_css) From 61a27495eae945d613f77f2f740c53b3eb2c5f51 Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Sun, 18 Dec 2022 16:08:03 +0100 Subject: [PATCH 072/247] Indev for quotes --- src/var/lib/tyto/program/wip.py | 48 ++++++++++++++++++++++++++++++--- 1 file changed, 44 insertions(+), 4 deletions(-) diff --git a/src/var/lib/tyto/program/wip.py b/src/var/lib/tyto/program/wip.py index 1afb991..58d069d 100644 --- a/src/var/lib/tyto/program/wip.py +++ b/src/var/lib/tyto/program/wip.py @@ -289,8 +289,48 @@ def wip_quotes() : line = line.replace('_Q64', '') quote = tyto.b64('Decode', line, 'Q64_', '_Q64').rsplit("\n") - # Read the quote + # Read the quote. Get parameters + author = date = lang = book = link = quote_html = '' for qline in quote: - if line.startswith('tyto.words_tags[11][0]'): - set_css = get_css(line) - print(set_css) + if qline.startswith(tyto.words_tags[11][0]): + set_css = tyto.get_css(qline) + continue + if qline.startswith('_cite:'): + author = qline.rsplit('_cite:')[1].lstrip() + continue + if qline.startswith('_date:'): + date = qline.rsplit('_date:')[1].lstrip() + continue + if qline.startswith('_book:'): + book = qline.rsplit('_book:')[1].lstrip() + continue + if qline.startswith('_lang:'): + lang = qline.rsplit('_lang:')[1].lstrip() + continue + if qline.startswith('_link:'): + lang = qline.rsplit('_link:')[1].lstrip() + continue + + # paragraphs + # Construct quote_html + if qline.startswith(tyto.words_tags[10][0]): + par_css = tyto.get_css(qline) + qline_html = '%s'%(tyto.words_tags[10][2]%par_css) + + if quote_html: quote_html = '%s\n%s'%(quote_html,qline_html) + else: quote_html = qline_html + continue + + if qline.startswith(tyto.words_tags[10][1]): + qline_html = tyto.words_tags[10][3] + quote_html = '%s\n%s'%(quote_html, qline_html) + continue + + # End of quote + if qline.startswith(tyto.words_tags[11][1]): + continue + + if quote_html: quote_html = '%s\n%s'%(quote_html,qline) + else: quote_html = qline + + print('>>>>', quote_html) From 4ea481bbf1654a75786d6d5e2588f00e1266ad36 Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Mon, 19 Dec 2022 12:35:54 +0100 Subject: [PATCH 073/247] Indev for quotes --- src/var/lib/tyto/program/tyto.py | 11 ++++++++ src/var/lib/tyto/program/wip.py | 43 ++++++++++++++++++++------------ 2 files changed, 38 insertions(+), 16 deletions(-) diff --git a/src/var/lib/tyto/program/tyto.py b/src/var/lib/tyto/program/tyto.py index 70a5747..2bce32d 100644 --- a/src/var/lib/tyto/program/tyto.py +++ b/src/var/lib/tyto/program/tyto.py @@ -140,9 +140,20 @@ single_tags = [ markers_lists = ('+', '=', ' ') # Tags used for titles +#--------------------- titles_tags = ('#1 ', '#2 ', '#3 ', '#4 ', '#5 ', '#6 ') +# Tags for quote +quote_tags = [ + ('_cite:', 'author'), + ('_date:', 'date'), + ('_link:', 'link'), + ('_book:', 'book'), + ('_lang:', 'lang') +] + + #=======# # TOOLS # #=======#-------------------------------------------------------------- diff --git a/src/var/lib/tyto/program/wip.py b/src/var/lib/tyto/program/wip.py index 58d069d..d3cc65d 100644 --- a/src/var/lib/tyto/program/wip.py +++ b/src/var/lib/tyto/program/wip.py @@ -277,11 +277,21 @@ def wip_images(): ) +#============================================# +# Get parameters for quote (author, date...) # +#--------------------------------------------# +def quote_params(qline): + for tag in tyto.quote_tags: + if qline.startswith(tag[0]): + globals()[tag[1]] = qline.rsplit(' ',1)[1].lstrip() + return(True) + # # INDEV: convert quote in article # def wip_quotes() : global article_bottom + global author, link, lang, book, date for ln, line in enumerate(article_bottom.rsplit('\n')): if line.startswith('Q64'): @@ -291,25 +301,13 @@ def wip_quotes() : # Read the quote. Get parameters author = date = lang = book = link = quote_html = '' + for qline in quote: if qline.startswith(tyto.words_tags[11][0]): set_css = tyto.get_css(qline) continue - if qline.startswith('_cite:'): - author = qline.rsplit('_cite:')[1].lstrip() - continue - if qline.startswith('_date:'): - date = qline.rsplit('_date:')[1].lstrip() - continue - if qline.startswith('_book:'): - book = qline.rsplit('_book:')[1].lstrip() - continue - if qline.startswith('_lang:'): - lang = qline.rsplit('_lang:')[1].lstrip() - continue - if qline.startswith('_link:'): - lang = qline.rsplit('_link:')[1].lstrip() - continue + + if quote_params(qline): continue # paragraphs # Construct quote_html @@ -333,4 +331,17 @@ def wip_quotes() : if quote_html: quote_html = '%s\n%s'%(quote_html,qline) else: quote_html = qline - print('>>>>', quote_html) + if author: + quote_html = '
    \n'%set_css + \ + '
    \n' + \ + '%s\n'%quote_html + \ + '
    \n' + \ + '
    ' + else: + quote_html = '
    \n'%set_css + \ + '%s\n'%quote_html + \ + '
    ' + + + print(quote_html) + From 7dc124d688017332b5bd20420c4521df0d419756 Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Mon, 19 Dec 2022 12:39:50 +0100 Subject: [PATCH 074/247] Indev for quotes --- src/var/lib/tyto/program/wip.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/var/lib/tyto/program/wip.py b/src/var/lib/tyto/program/wip.py index d3cc65d..558e86a 100644 --- a/src/var/lib/tyto/program/wip.py +++ b/src/var/lib/tyto/program/wip.py @@ -331,14 +331,21 @@ def wip_quotes() : if quote_html: quote_html = '%s\n%s'%(quote_html,qline) else: quote_html = qline + + if lang: + lang = ' lang="%s"'%lang if author: - quote_html = '
    \n'%set_css + \ - '
    \n' + \ + quote_html = '
    ' + \ + '
    \n'%( + set_css, lang + ) + \ '%s\n'%quote_html + \ '
    \n' + \ '
    ' else: - quote_html = '
    \n'%set_css + \ + quote_html = '
    \n'%( + set_css, lang + ) + \ '%s\n'%quote_html + \ '
    ' From 992ecd1a6b857346daed3e008b2498a14b161748 Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Mon, 19 Dec 2022 12:45:28 +0100 Subject: [PATCH 075/247] Indev for quotes --- src/var/lib/tyto/program/wip.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/var/lib/tyto/program/wip.py b/src/var/lib/tyto/program/wip.py index 558e86a..438f073 100644 --- a/src/var/lib/tyto/program/wip.py +++ b/src/var/lib/tyto/program/wip.py @@ -301,6 +301,7 @@ def wip_quotes() : # Read the quote. Get parameters author = date = lang = book = link = quote_html = '' + cite = '' for qline in quote: if qline.startswith(tyto.words_tags[11][0]): @@ -332,19 +333,23 @@ def wip_quotes() : else: quote_html = qline + if link: + cite = ' cite="%s"'%(link) + if lang: lang = ' lang="%s"'%lang + if author: - quote_html = '
    ' + \ - '
    \n'%( - set_css, lang + quote_html = '
    \n' + \ + '
    \n'%( + set_css, lang, cite ) + \ '%s\n'%quote_html + \ '
    \n' + \ '
    ' else: - quote_html = '
    \n'%( - set_css, lang + quote_html = '
    \n'%( + set_css, lang, cite ) + \ '%s\n'%quote_html + \ '
    ' From 458514649be578f84655bcafeed98a2b4a188224 Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Mon, 19 Dec 2022 12:49:23 +0100 Subject: [PATCH 076/247] Indev for quotes --- src/var/lib/tyto/program/wip.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/var/lib/tyto/program/wip.py b/src/var/lib/tyto/program/wip.py index 438f073..ed3d993 100644 --- a/src/var/lib/tyto/program/wip.py +++ b/src/var/lib/tyto/program/wip.py @@ -341,11 +341,11 @@ def wip_quotes() : if author: quote_html = '
    \n' + \ - '
    \n'%( + '
    \n'%( set_css, lang, cite ) + \ '%s\n'%quote_html + \ - '
    \n' + \ + '
    \n' + \ '
    ' else: quote_html = '
    \n'%( From 7f4b35b8fe7ae91dea65fdebf2eacddb211f8d39 Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Mon, 19 Dec 2022 13:01:47 +0100 Subject: [PATCH 077/247] Indev for quotes --- src/var/lib/tyto/program/wip.py | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/src/var/lib/tyto/program/wip.py b/src/var/lib/tyto/program/wip.py index ed3d993..9536b8a 100644 --- a/src/var/lib/tyto/program/wip.py +++ b/src/var/lib/tyto/program/wip.py @@ -310,26 +310,41 @@ def wip_quotes() : if quote_params(qline): continue - # paragraphs + # Paragraph [10] Open # Construct quote_html if qline.startswith(tyto.words_tags[10][0]): par_css = tyto.get_css(qline) - qline_html = '%s'%(tyto.words_tags[10][2]%par_css) - - if quote_html: quote_html = '%s\n%s'%(quote_html,qline_html) - else: quote_html = qline_html + if author: + qline_html = ' %s'%(tyto.words_tags[10][2]%par_css) + else: + qline_html = ' %s'%(tyto.words_tags[10][2]%par_css) + + if quote_html: + qquote_html = '%s\n%s'%(quote_html, qline_html) + else: + quote_html = '%s'%qline_html + continue + # Paragraph Close if qline.startswith(tyto.words_tags[10][1]): qline_html = tyto.words_tags[10][3] - quote_html = '%s\n%s'%(quote_html, qline_html) + if author: + quote_html = '%s\n %s'%(quote_html, qline_html) + else: + quote_html = '%s\n %s'%(quote_html, qline_html) continue # End of quote if qline.startswith(tyto.words_tags[11][1]): continue - if quote_html: quote_html = '%s\n%s'%(quote_html,qline) + # Add other lines + if quote_html: + if author: + quote_html = '%s\n %s'%(quote_html, qline) + else: + quote_html = '%s\n %s'%(quote_html, qline) else: quote_html = qline From 439641718849483ea8cd8578d255e26d94cf98ff Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Mon, 19 Dec 2022 16:34:09 +0100 Subject: [PATCH 078/247] Indev for quotes --- src/var/lib/tyto/program/wip.py | 39 +++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/src/var/lib/tyto/program/wip.py b/src/var/lib/tyto/program/wip.py index 9536b8a..3281038 100644 --- a/src/var/lib/tyto/program/wip.py +++ b/src/var/lib/tyto/program/wip.py @@ -294,6 +294,7 @@ def wip_quotes() : global author, link, lang, book, date for ln, line in enumerate(article_bottom.rsplit('\n')): + # Decode from base64 if line.startswith('Q64'): line = line.replace('Q64_', '') line = line.replace('_Q64', '') @@ -302,50 +303,56 @@ def wip_quotes() : # Read the quote. Get parameters author = date = lang = book = link = quote_html = '' cite = '' + tab_p = tab_c = 2 # Init 2 tabs after
    for qline in quote: + # Begin marker quote [11] if qline.startswith(tyto.words_tags[11][0]): set_css = tyto.get_css(qline) continue + # Search for parameters ans set them if quote_params(qline): continue - + # Paragraph [10] Open # Construct quote_html if qline.startswith(tyto.words_tags[10][0]): par_css = tyto.get_css(qline) + if author: - qline_html = ' %s'%(tyto.words_tags[10][2]%par_css) + tab_p = tab_p + 2 + tab_c = tab_c + 4 else: - qline_html = ' %s'%(tyto.words_tags[10][2]%par_css) - + tab_c = tab_c + 2 + + # Replace opened paragrph with html line + qline_html = '%s%s'%( + tab_p * ' ', tyto.words_tags[10][2]%par_css + ) + + # Add line to quote_html if quote_html: qquote_html = '%s\n%s'%(quote_html, qline_html) else: quote_html = '%s'%qline_html - continue # Paragraph Close if qline.startswith(tyto.words_tags[10][1]): + # Replace closed paragrph with html line qline_html = tyto.words_tags[10][3] - if author: - quote_html = '%s\n %s'%(quote_html, qline_html) - else: - quote_html = '%s\n %s'%(quote_html, qline_html) + quote_html = '%s\n%s%s'%(quote_html, int(tab_p) * ' ',qline_html) continue - # End of quote + # End of marker quote if qline.startswith(tyto.words_tags[11][1]): continue # Add other lines if quote_html: - if author: - quote_html = '%s\n %s'%(quote_html, qline) - else: - quote_html = '%s\n %s'%(quote_html, qline) - else: quote_html = qline + quote_html = '%s\n%s%s'%(quote_html, int(tab_c) * ' ', qline) + else: + quote_html = '%s%s'%(tab_c * ' ', qline) if link: @@ -369,6 +376,6 @@ def wip_quotes() : '%s\n'%quote_html + \ '
    ' - + print('> quote:') print(quote_html) From b1e250a3cfd25eba8ab454be87d5213e99a329eb Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Mon, 19 Dec 2022 16:35:18 +0100 Subject: [PATCH 079/247] Indev for quotes --- src/var/lib/tyto/program/wip.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/var/lib/tyto/program/wip.py b/src/var/lib/tyto/program/wip.py index 3281038..d205267 100644 --- a/src/var/lib/tyto/program/wip.py +++ b/src/var/lib/tyto/program/wip.py @@ -362,7 +362,7 @@ def wip_quotes() : lang = ' lang="%s"'%lang if author: - quote_html = '
    \n' + \ + quote_html = '
    \n'%set_css + \ '
    \n'%( set_css, lang, cite ) + \ From cacad4565d2c89dcbf25fea8d545afe5910423e8 Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Mon, 19 Dec 2022 17:41:57 +0100 Subject: [PATCH 080/247] Quotes: working, but missing HTML time tag --- src/var/lib/tyto/program/wip.py | 74 +++++++++++++++++++++++---------- 1 file changed, 51 insertions(+), 23 deletions(-) diff --git a/src/var/lib/tyto/program/wip.py b/src/var/lib/tyto/program/wip.py index d205267..28e0043 100644 --- a/src/var/lib/tyto/program/wip.py +++ b/src/var/lib/tyto/program/wip.py @@ -302,8 +302,9 @@ def wip_quotes() : # Read the quote. Get parameters author = date = lang = book = link = quote_html = '' - cite = '' + cite = figc = '' tab_p = tab_c = 2 # Init 2 tabs after
    + auth_html = title_html = '' for qline in quote: # Begin marker quote [11] @@ -319,11 +320,9 @@ def wip_quotes() : if qline.startswith(tyto.words_tags[10][0]): par_css = tyto.get_css(qline) - if author: - tab_p = tab_p + 2 - tab_c = tab_c + 4 - else: - tab_c = tab_c + 2 + # Set tabulation for paragraphs and content + if author: tab_p = tab_p + 2 ; tab_c = tab_c + 4 + else: tab_c = tab_c + 2 # Replace opened paragrph with html line qline_html = '%s%s'%( @@ -349,33 +348,62 @@ def wip_quotes() : continue # Add other lines - if quote_html: - quote_html = '%s\n%s%s'%(quote_html, int(tab_c) * ' ', qline) + if quote_html: quote_html = '%s\n%s%s'%( + quote_html, int(tab_c) * ' ', qline + ) + else: quote_html = '%s%s'%(tab_c * ' ', qline) + + # New quote set, then, repare datas + if link: cite = ' cite="%s"'%(link) + if lang: lang = ' lang="%s"'%lang + + # Preparing title="" tag and author reference + if author: + if book and date: + title_html = ' title="%s - %s (%s)"'%( + author, book, date + ) + auth_html = '%s - %s (%s)'%( + author, book, date + ) + elif book: + title_html = ' title="%s - %s"'%(author, book) + auth_html = '%s - %s'%(author, book) + elif date: + title_html = ' title="%s (%s)"'%(author, date) + auth_html = '%s (%s)'%(author, date) else: - quote_html = '%s%s'%(tab_c * ' ', qline) - - - if link: - cite = ' cite="%s"'%(link) - - if lang: - lang = ' lang="%s"'%lang + title_html = ' title="%s"'%author + auth_html = '%s'%author + if link: figc= '%s'%( + link, auth_html + ) + else: + if book and date: title_html = ' title="%s (%s)"'%( + book, date + ) + elif book: title_html = ' title="%s"'%(book) + elif date: title_html = ' title="(%s)"'%(date) + # Create HTML Quote with datas if author: quote_html = '
    \n'%set_css + \ - '
    \n'%( - set_css, lang, cite + '
    \n'%( + set_css, lang, cite, title_html ) + \ '%s\n'%quote_html + \ '
    \n' + \ + '
    \n'%set_css + \ + ' %s\n'%figc + \ + '
    \n' + \ '
    ' else: - quote_html = '
    \n'%( - set_css, lang, cite + quote_html = '
    \n'%( + set_css, lang, cite, title_html ) + \ '%s\n'%quote_html + \ '
    ' - - print('> quote:') - print(quote_html) + + # Replace line with final HTML Quote + article_bottom = article_bottom.replace('Q64_%s_Q64'%line, quote_html) From f279583d113f210d456c565e6030bb371dc6765c Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Mon, 19 Dec 2022 17:53:24 +0100 Subject: [PATCH 081/247] Quotes: working, but missing HTML time tag --- README.md | 41 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b9f905e..695608c 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ author: Autheur tags: mots-clé-1,mots-clé-2 date: YYYY-MM-DD (AAAA-MM-JJ) -# Optionnels myltiples +# Optionnels multiples link: Nom du lien URL Texte Alternatif @@ -165,3 +165,42 @@ _image:Nom c=CSS t=https://... w=320px h=240 ``` _brut:NOM ``` + +### Citations +Possibilité dans toute citation d'utiliser les marqueurs +optionnels _xxx: +``` +# Brut: +[[ CSS_TEST +_cite: echolib +_date: 2022 +_lang: fr +_link: https://tyto.echolib.re +_book: Référence +(( +Pfff, vraiment ! +)) +]] + +# Sotie HTML: +
    +
    +

    + Pfff, vraiment ! +

    +
    +
    + echolib - Reference (2022) +
    +
    + +# Brut +[[ +Une citation simple, et sans paragraphe +]] + +# Sortie HTML +
    + Une citation simple, et sans paragraphe +
    +``` From 4d285c4d27b0657ab2b083486562091db156afd5 Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Mon, 26 Dec 2022 11:14:28 +0100 Subject: [PATCH 082/247] check: added search in header when '_image:NAME' in content --- src/var/lib/tyto/program/check.py | 10 ++++++++++ src/var/lib/tyto/program/tyto.py | 1 + 2 files changed, 11 insertions(+) diff --git a/src/var/lib/tyto/program/check.py b/src/var/lib/tyto/program/check.py index 85af71c..ba355a2 100644 --- a/src/var/lib/tyto/program/check.py +++ b/src/var/lib/tyto/program/check.py @@ -526,6 +526,16 @@ def check_content(post_bottom): post_err = True + # Check for _image:NAME from content in header + #--------------------------------------------- + for ln, line in enumerate(post_bottom): + if line.startswith('_image:'): + image_id = line.rsplit(':', 1)[1].rsplit(' ')[0] + print(article_header) + if not re.search(r'^image:\s|%s'%image_id, article_header): + tyto.exiting("10", "image: %s"%image_id, True) + + #===============================================# # Create new article's database at each check ! # #-----------------------------------------------# diff --git a/src/var/lib/tyto/program/tyto.py b/src/var/lib/tyto/program/tyto.py index 2bce32d..654dfa5 100644 --- a/src/var/lib/tyto/program/tyto.py +++ b/src/var/lib/tyto/program/tyto.py @@ -449,6 +449,7 @@ def exiting(nbr, value, out): '7' : ':< Article is \033[1;31mnot valid yet\033[0;0m', '8' : ':< tags "%s" \033[1;31mnot paired\033[0;0m'%value, '9' : ':D Article has changed (wip is old)', + '10' : ':< \033[1;31mUnused "%s"\033[0;0m in article\'s header'%value, '20' : ':D Article already up-to-date on: %s'%value, '21' : ':D Article is valid and ready to wip', '255' : ':| Maybe later...' From 1a14dbb2a95ad5cbf7e349376c7d098ebf99abcd Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Mon, 26 Dec 2022 11:15:33 +0100 Subject: [PATCH 083/247] check: added search in header when '_image:NAME' in content --- src/var/lib/tyto/program/check.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/var/lib/tyto/program/check.py b/src/var/lib/tyto/program/check.py index ba355a2..2df8f21 100644 --- a/src/var/lib/tyto/program/check.py +++ b/src/var/lib/tyto/program/check.py @@ -531,7 +531,6 @@ def check_content(post_bottom): for ln, line in enumerate(post_bottom): if line.startswith('_image:'): image_id = line.rsplit(':', 1)[1].rsplit(' ')[0] - print(article_header) if not re.search(r'^image:\s|%s'%image_id, article_header): tyto.exiting("10", "image: %s"%image_id, True) From a5601062ff107f47e8cd459b09c87a4d6129f00a Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Mon, 26 Dec 2022 11:39:14 +0100 Subject: [PATCH 084/247] wip: HTML time tag added to quotes (when registred) + base64 in utf8 --- README.md | 20 ++++++++++++-------- src/var/lib/tyto/program/tyto.py | 8 ++++---- src/var/lib/tyto/program/wip.py | 10 +++++++++- 3 files changed, 25 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 695608c..e39d947 100644 --- a/README.md +++ b/README.md @@ -152,6 +152,7 @@ Avec ce NOM. # 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 @@ -168,12 +169,12 @@ _brut:NOM ### Citations Possibilité dans toute citation d'utiliser les marqueurs -optionnels _xxx: +optionnels _xxx. Pour la date, utilisez le FORMAT INTERNATIONAL ``` -# Brut: +# Source [[ CSS_TEST _cite: echolib -_date: 2022 +_date: 2022-12-28 _lang: fr _link: https://tyto.echolib.re _book: Référence @@ -182,24 +183,27 @@ Pfff, vraiment ! )) ]] -# Sotie HTML: +# HTML:
    -
    +
    +
    - echolib - Reference (2022) + echolib - Reference (2022-12-28)
    -# Brut + +# Source [[ Une citation simple, et sans paragraphe ]] -# Sortie HTML +# HTML
    Une citation simple, et sans paragraphe
    diff --git a/src/var/lib/tyto/program/tyto.py b/src/var/lib/tyto/program/tyto.py index 654dfa5..57b1da4 100644 --- a/src/var/lib/tyto/program/tyto.py +++ b/src/var/lib/tyto/program/tyto.py @@ -417,17 +417,17 @@ def b64(action, content, before, after): if action == 'Encode': global b64_content b64_base64 = '' - content_bytes = content.encode("ascii") + content_bytes = content.encode("utf8") base64_bytes = base64.b64encode(content_bytes) - b64_content = before + base64_bytes.decode("ascii") + after + b64_content = before + base64_bytes.decode("utf8") + after return b64_content elif action == 'Decode': global src_content src_content = '' - content_bytes = content.encode("ascii") + content_bytes = content.encode("utf8") base64_bytes = base64.b64decode(content_bytes) - src_content = base64_bytes.decode("ascii") + src_content = base64_bytes.decode("utf8") return src_content else: diff --git a/src/var/lib/tyto/program/wip.py b/src/var/lib/tyto/program/wip.py index 28e0043..2647cfa 100644 --- a/src/var/lib/tyto/program/wip.py +++ b/src/var/lib/tyto/program/wip.py @@ -385,23 +385,31 @@ def wip_quotes() : elif book: title_html = ' title="%s"'%(book) elif date: title_html = ' title="(%s)"'%(date) + if date: + time_html_o = '\n' + # Create HTML Quote with datas if author: quote_html = '
    \n'%set_css + \ '
    \n'%( set_css, lang, cite, title_html ) + \ + ' ' + time_html_o + \ '%s\n'%quote_html + \ + ' ' + time_html_c + \ '
    \n' + \ '
    \n'%set_css + \ ' %s\n'%figc + \ '
    \n' + \ '
    ' else: - quote_html = '
    \n'%( + quote_html ='
    \n'%( set_css, lang, cite, title_html ) + \ + time_html_o + \ '%s\n'%quote_html + \ + time_html_c + \ '
    ' # Replace line with final HTML Quote From 0378edcdf4baa8f8fed63ac4e105dc6d44edf0fc Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Mon, 26 Dec 2022 14:20:52 +0100 Subject: [PATCH 085/247] wip: HTML time tag added to quotes (when registred) + base64 in utf8 --- README.md | 2 +- src/var/lib/tyto/program/check.py | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index e39d947..177e85d 100644 --- a/README.md +++ b/README.md @@ -183,7 +183,7 @@ Pfff, vraiment ! )) ]] -# HTML: +# HTML
    ' # Replace line with final HTML Quote - article_bottom = article_bottom.replace('Q64_%s_Q64'%line, quote_html) + article_bottom = article_bottom.replace( + 'Q64.%s.Q64'%line, quote_html + ) From 45c915e42189a5022ab2b191360cc963dbb606b1 Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Thu, 29 Dec 2022 23:22:42 +0100 Subject: [PATCH 093/247] check: add inline-code check for markers in same line --- src/var/lib/tyto/program/check.py | 35 +++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/src/var/lib/tyto/program/check.py b/src/var/lib/tyto/program/check.py index 249a2e0..c5f88ba 100644 --- a/src/var/lib/tyto/program/check.py +++ b/src/var/lib/tyto/program/check.py @@ -57,6 +57,8 @@ def manage_check(target, option): # Start processes file_to_string(tyto.uri_root) + # Specific to inline-code: check markers on same line + check_icodes(article.rsplit('\n')) # Protect inline-codes tyto.protect_icodes(post_bottom, article_bottom) post_bottom = tyto.protect_article.rsplit('\n') @@ -118,6 +120,37 @@ def file_to_string(post_file): post_bottom = article.rsplit('-----')[1].rsplit('\n') +# +# Check inline code, for markers on same line +# +def check_icodes(article): + quote = bcode = False + + for ln, line in enumerate(article, 1): + icode_m1 = icode_m2 = 0 + + # Pass Comments + if line.startswith('#'): continue + + # Pass quotes + if line.startswith(tyto.words_tags[11][0]): quote = True + if line.startswith(tyto.words_tags[11][1]): quote = False + + # Pass bcode + if line.startswith(tyto.words_tags[12][0]): bcode = True + if line.startswith(tyto.words_tags[12][1]): bcode = False + + if bcode or quote: continue + + if tyto.words_tags[9][0] or tyto.words_tags[9][1] in line: + icode_m1 = line.count(tyto.words_tags[9][0]) + icode_m2 = line.count(tyto.words_tags[9][1]) + if icode_m1 != icode_m2: + tyto.exiting("8", 'inline-code: line %s. %s %s'%(ln, + tyto.words_tags[9][0], tyto.words_tags[9][1] + ), True + ) + #==================================# # Check tags from article's header # #----------------------------------# @@ -127,8 +160,6 @@ def check_headers(post_header): global stat_links, stat_images, stat_files, stat_bruts, stat_abbrs global post_tags - #post_tags = 0 - # Needed Tags title = author = tags = about = '' date = () From 2d1ccc1ec8947dfc060ab5c58904cc3d6962e2a7 Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Thu, 29 Dec 2022 23:44:07 +0100 Subject: [PATCH 094/247] wip: Added module to convert inline-codes --- src/var/lib/tyto/program/wip.py | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/src/var/lib/tyto/program/wip.py b/src/var/lib/tyto/program/wip.py index c17b7b9..f979dec 100644 --- a/src/var/lib/tyto/program/wip.py +++ b/src/var/lib/tyto/program/wip.py @@ -89,6 +89,9 @@ def wip_article(target): # Quotes wip_quotes() # Decode B64 and convert + + # inline_codes + wip_icodes() print(article_bottom) @@ -286,9 +289,9 @@ def quote_params(qline): globals()[tag[1]] = qline.rsplit(' ',1)[1].lstrip() return(True) -# -# INDEV: convert quote in article -# +#==========================# +# Convert quote in article # +#--------------------------# def wip_quotes() : global article_bottom global author, link, lang, book, date @@ -417,4 +420,15 @@ def wip_quotes() : article_bottom = article_bottom.replace( 'Q64.%s.Q64'%line, quote_html ) - + +#==========================# +# Convert all inline-codes # +#--------------------------# +def wip_icodes(): + global article_bottom + + matches = re.findall(r'I64.(.*?).I64', article_bottom) + for match in matches: + rep_icode = 'I64.' + match + '.I64' + src_icode = tyto.b64("Decode", match, 'I64.', '.I64') + article_bottom = article_bottom.replace(rep_icode, src_icode) From ba052211cac03fa2446e74320f00c98cce01edad Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Fri, 30 Dec 2022 01:20:19 +0100 Subject: [PATCH 095/247] wip: Added module block-code (InDev for more html tags, maybe) --- src/var/lib/tyto/program/wip.py | 49 +++++++++++++++++++++++++++++++-- 1 file changed, 46 insertions(+), 3 deletions(-) diff --git a/src/var/lib/tyto/program/wip.py b/src/var/lib/tyto/program/wip.py index f979dec..0c84e67 100644 --- a/src/var/lib/tyto/program/wip.py +++ b/src/var/lib/tyto/program/wip.py @@ -87,14 +87,18 @@ def wip_article(target): wip_links() # Links_%i from headers in DB wip_images() # Images_%i from headers in DB - # Quotes - wip_quotes() # Decode B64 and convert + # Quotes. Decode base64 Q64 and convert to HTML + wip_quotes() - # inline_codes + # inline_codes. Decode base64 icode and replace wip_icodes() + + # Block-codes. Decode B64 and convert to HTML + wip_bcodes() print(article_bottom) + #=================================# # Create string article from file # # post is string splitted '\n' # @@ -421,8 +425,10 @@ def wip_quotes() : 'Q64.%s.Q64'%line, quote_html ) + #==========================# # Convert all inline-codes # +# Content is HTML ready # #--------------------------# def wip_icodes(): global article_bottom @@ -432,3 +438,40 @@ def wip_icodes(): rep_icode = 'I64.' + match + '.I64' src_icode = tyto.b64("Decode", match, 'I64.', '.I64') article_bottom = article_bottom.replace(rep_icode, src_icode) + + +#==================================================# +# Convert all block-codes # +# Content is raw, and have to be converted in HTML # +#--------------------------------------------------# +def wip_bcodes(): + global article_bottom + + matches = re.findall(r'B64.(.*?).B64', article_bottom) + for match in matches: + rep_bcode = 'B64.' + match + '.B64' + src_bcode = tyto.b64("Decode", match, 'B64.', '.B64') + + # Convert src_bcode + for line in src_bcode.rsplit('\n'): + + # CSS + opened marker + if line.startswith(tyto.words_tags[12][0]): + set_css = tyto.get_css(line) + html_bcode = '
    \n'%set_css + \
    +                   '  '
    +      
    +      # closed marker
    +      elif line.startswith(tyto.words_tags[12][1]):
    +        html_bcode = '%s\n  \n'%html_bcode + \
    +                     '
    ' + + # Block-code content per line + else: + html_bcode = '%s\n %s'%(html_bcode, line) + + article_bottom = article_bottom.replace(rep_bcode, html_bcode) + + + + From b72a1133f6433690e4a4ec2368c7ee518f7f911d Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Fri, 30 Dec 2022 17:19:20 +0100 Subject: [PATCH 096/247] wip: Added module titles (remove empty lines, create divs if contents after title) --- src/var/lib/tyto/program/wip.py | 61 ++++++++++++++++++++++++++++++--- 1 file changed, 56 insertions(+), 5 deletions(-) diff --git a/src/var/lib/tyto/program/wip.py b/src/var/lib/tyto/program/wip.py index 0c84e67..babd408 100644 --- a/src/var/lib/tyto/program/wip.py +++ b/src/var/lib/tyto/program/wip.py @@ -86,6 +86,7 @@ def wip_article(target): wip_words_tags() # Paragraphs, strongs, italics wip_links() # Links_%i from headers in DB wip_images() # Images_%i from headers in DB + wip_titles() # Quotes. Decode base64 Q64 and convert to HTML wip_quotes() @@ -454,24 +455,74 @@ def wip_bcodes(): # Convert src_bcode for line in src_bcode.rsplit('\n'): - # CSS + opened marker if line.startswith(tyto.words_tags[12][0]): set_css = tyto.get_css(line) html_bcode = '
    \n'%set_css + \
                        '  '
    -      
           # closed marker
           elif line.startswith(tyto.words_tags[12][1]):
             html_bcode = '%s\n  \n'%html_bcode + \
                          '
    ' - # Block-code content per line else: html_bcode = '%s\n %s'%(html_bcode, line) article_bottom = article_bottom.replace(rep_bcode, html_bcode) + +#========================================# +# Convert titles to HTML # +# Check between titles to set div or not # +#----------------------------------------# +def wip_titles(): + global article_bottom + article_temp = article_bottom + article_tmp2 = '' # COnstruct article, without empty lines + + for line in article_bottom.rsplit('\n'): + if line.startswith('#'): + hx = line[1] + title_cont = line[2: len(line)].lstrip() + title_html = '%s'%(hx, hx, title_cont, hx) + article_temp = article_temp.replace(line, title_html) - - + + + # Remove useless empty lines from article + for line in article_temp.rsplit('\n'): + if line: + if article_tmp2: article_tmp2 = '%s\n%s'%(article_tmp2, line) + else: article_tmp2 = line + + article_temp = article_tmp2 + + # Add div after title if needed + for ln, line in enumerate(article_tmp2.rsplit('\n')): + if line.startswith(''%line + ) + + article_tmp2 = article_temp + # Add div after title if needed + indiv = False + for ln, line in enumerate(article_tmp2.rsplit('\n')): + if line.startswith('\n%s'%line + ) + indiv = False + + if indiv: + article_temp = '%s\n'%article_temp + + # Replace article with new contents + article_bottom = article_temp From 757e387d84d8014abcf9b07d52d556fd483150d3 Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Fri, 30 Dec 2022 17:54:44 +0100 Subject: [PATCH 097/247] wip: (fix) module titles (remove empty lines, create divs if contents after title) --- src/var/lib/tyto/program/wip.py | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/var/lib/tyto/program/wip.py b/src/var/lib/tyto/program/wip.py index babd408..248c782 100644 --- a/src/var/lib/tyto/program/wip.py +++ b/src/var/lib/tyto/program/wip.py @@ -500,22 +500,32 @@ def wip_titles(): # Add div after title if needed for ln, line in enumerate(article_tmp2.rsplit('\n')): if line.startswith(''%line ) + continue + else: + continue + # Close div before title if needed article_tmp2 = article_temp - # Add div after title if needed indiv = False for ln, line in enumerate(article_tmp2.rsplit('\n')): - if line.startswith('\n%s'%line ) From 3e8ca0e64328c51b6781cade101856b685d89aff Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Fri, 30 Dec 2022 18:12:52 +0100 Subject: [PATCH 098/247] wip: (fix) module titles (remove empty lines, create divs if contents after title) --- README.md | 30 ++++++++++++++++++++++++++---- src/var/lib/tyto/program/wip.py | 16 ++++++++-------- 2 files changed, 34 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 177e85d..2cae31f 100644 --- a/README.md +++ b/README.md @@ -38,14 +38,36 @@ abbr: NOM (en majuscule) ``` ## Comment écrire un article -### Titre h1 à h6 + +### É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 + +# Source #1 Titre 1 -(( -Un paragraphe -)) +Contenu 1 #2 Titre 2 + +#3 Titre 3 +contenu 2 + +#4 Titre 4 + +# HTML +

    Titre 1

    +
    +Contenu 1 +
    +

    Titre 2

    +

    Titre 3

    +
    +contenu 2 +
    +

    Titre 4

    ``` ### Paragraphes diff --git a/src/var/lib/tyto/program/wip.py b/src/var/lib/tyto/program/wip.py index 248c782..b95e43c 100644 --- a/src/var/lib/tyto/program/wip.py +++ b/src/var/lib/tyto/program/wip.py @@ -517,19 +517,19 @@ def wip_titles(): article_tmp2 = article_temp indiv = False for ln, line in enumerate(article_tmp2.rsplit('\n')): - if line.startswith('\n%s'%line ) indiv = False + + if line.startswith(' Date: Sat, 31 Dec 2022 00:19:47 +0100 Subject: [PATCH 099/247] check: fixes for tags + brut: to raw: --- README.md | 2 +- src/var/lib/tyto/program/check.py | 92 +++++++++++++++---------------- src/var/lib/tyto/program/tyto.py | 4 +- 3 files changed, 49 insertions(+), 49 deletions(-) diff --git a/README.md b/README.md index 2cae31f..1828d4e 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ file: Nom du lien URL Texte Alternatif -brut: Nom +raw : Nom URI Texte Alternatif diff --git a/src/var/lib/tyto/program/check.py b/src/var/lib/tyto/program/check.py index c5f88ba..248285f 100644 --- a/src/var/lib/tyto/program/check.py +++ b/src/var/lib/tyto/program/check.py @@ -157,7 +157,7 @@ def check_icodes(article): def check_headers(post_header): global post_err, err, web_uri, date_check global date, title, author, tags, about - global stat_links, stat_images, stat_files, stat_bruts, stat_abbrs + global stat_links, stat_images, stat_files, stat_raws, stat_abbrs global post_tags # Needed Tags @@ -165,7 +165,7 @@ def check_headers(post_header): date = () # Statistics - stat_links = stat_images = stat_files = stat_bruts = stat_abbrs = 0 + stat_links = stat_images = stat_files = stat_raws = stat_abbrs = 0 ### # First session for needed tags # @@ -176,32 +176,32 @@ def check_headers(post_header): # Set each needed tag # # Only the first one is set # #---------------------------# - tag = 'title:' + tag = tyto.headers[0] # title: if line.startswith(tag): if title: continue title = line.rsplit(tag)[1].lstrip() continue - tag = 'about:' + tag = tyto.headers[1] # about: if line.startswith(tag): if about: continue about = line.rsplit(tag)[1].lstrip() continue - tag = 'tags:' + tag = tyto.headers[2] # author: + if line.startswith(tag): + if author: continue + author = line.rsplit(tag)[1].lstrip() + continue + + tag = tyto.headers[3] # tags: if line.startswith(tag): if tags: continue tags = line.rsplit(tag)[1].lstrip() post_tags = len(tags.strip().split(",")) continue - - tag = 'author:' - if line.startswith(tag): - if author: continue - author = line.rsplit(tag)[1].lstrip() - continue - tag = 'date:' + tag = tyto.headers[4] # date: if line.startswith(tag): if date: continue date = line.rsplit(tag)[1].lstrip() @@ -219,11 +219,11 @@ def check_headers(post_header): #-------------------# # Set needed tags need_headers = { - 'title:' : title, - 'anout:' : about, - 'tags:' : tags, - 'author:': author, - 'date:' : date + tyto.headers[0] : title, + tyto.headers[1] : about, + tyto.headers[2] : author, + tyto.headers[3] : tags, + tyto.headers[4] : date } # Check if set needed tags @@ -245,7 +245,7 @@ def check_headers(post_header): # ABBR #----- - tag = 'abbr:' + tag = tyto.headers[8] # abbr: if line.startswith(tag): stat_abbrs += 1 var_tag = 'abbr_%s'%stat_abbrs @@ -282,7 +282,7 @@ def check_headers(post_header): # LINK #----- - tag = 'link:' + tag = tyto.headers[5] # link: if line.startswith(tag): stat_links += 1 var_tag = 'link_%s'%stat_links @@ -318,7 +318,7 @@ def check_headers(post_header): # IMAGE #------ - tag = 'image:' + tag = tyto.headers[6] # image: if line.startswith(tag): stat_images += 1 var_tag = 'image_%s'%stat_images @@ -353,41 +353,41 @@ def check_headers(post_header): image_alt ) - # BRUT - #----- - tag = 'brut:' + # RAW File + #--------- + tag = tyto.headers[9] # raw: if line.startswith(tag): - stat_bruts += 1 - var_tag = 'brut_%s'%stat_bruts + stat_raws += 1 + var_tag = 'raw_%s'%stat_raws - brut_name = post_header[ln - 1] - brut_name = brut_name.rsplit(tag)[1].lstrip().rsplit(' ')[0] - if not brut_name: + raw_name = post_header[ln - 1] + raw_name = raw_name.rsplit(tag)[1].lstrip().rsplit(' ')[0] + if not raw_name: tyto.exiting("2", "Line %s (Name, %s)"%(ln, tag), False) post_err = True - if not isin(r'\b_%s%s\b'%(tag, brut_name), post_bottom): - tyto.exiting("6", "_%s%s"%(tag, brut_name), False) + if not isin(r'\b_%s%s\b'%(tag, raw_name), post_bottom): + tyto.exiting("6", "_%s%s"%(tag, raw_name), False) post_err = True - brut_uri = post_header[ln].lstrip() - if brut_uri.startswith(tyto.headers): brut_uri = '' - if not brut_uri: + raw_uri = post_header[ln].lstrip() + if raw_uri.startswith(tyto.headers): raw_uri = '' + if not raw_uri: tyto.exiting("2", "Line %s (URI, %s)"%(ln + 1, tag), False) post_err = True else: - check_file_uri('file', brut_uri, ln + 1) + check_file_uri('file', raw_uri, ln + 1) - brut_alt = post_header[ln + 1].lstrip() - if brut_alt.startswith(tyto.headers): brut_alt = '' - if not brut_alt: + raw_alt = post_header[ln + 1].lstrip() + if raw_alt.startswith(tyto.headers): raw_alt = '' + if not raw_alt: tyto.exiting("2", "Line %s (Alt-Text, %s)"%(ln + 2, tag), False) post_err = True if not post_err: - globals()['brut_%s'%stat_bruts] = ( - '_%s%s'%(tag, brut_name), + globals()['raw_%s'%stat_raws] = ( + '_%s%s'%(tag, raw_name), web_uri, - brut_alt + raw_alt ) # FILE @@ -568,7 +568,7 @@ def check_content(post_bottom): match = False for hline in post_header: - if hline.startswith('image:'): + if hline.startswith(htag): htag_id = hline.rsplit(':', 1)[1].lstrip() if htag_id == tag_id: match = True @@ -642,10 +642,10 @@ def create_database(): database, i, globals()['file_%s'%i] ) - if stat_bruts > 0: - for i in range(1, stat_bruts + 1): - database = '%s\nbrut_%s = %s'%( - database, i, globals()['brut_%s'%i] + if stat_raws > 0: + for i in range(1, stat_raws + 1): + database = '%s\nraw_%s = %s'%( + database, i, globals()['raw_%s'%i] ) db_stats = '\n# Statistics from optional tags\n' + \ @@ -654,7 +654,7 @@ def create_database(): 'uniq_links = %s\n'%(int(stat_links)) + \ 'uniq_images = %s\n'%(int(stat_images)) + \ 'uniq_files = %s\n'%(int(stat_files)) + \ - 'uniq_bruts = %s\n'%(int(stat_bruts)) + \ + 'uniq_raws = %s\n'%(int(stat_raws)) + \ '\n# Statistics from post content\n' + \ 'stat_tags = %s\n'%(int(post_tags)) + \ 'stat_words = %s\n'%(int(post_words)) + \ diff --git a/src/var/lib/tyto/program/tyto.py b/src/var/lib/tyto/program/tyto.py index 7d03fd8..4bbae03 100644 --- a/src/var/lib/tyto/program/tyto.py +++ b/src/var/lib/tyto/program/tyto.py @@ -101,7 +101,7 @@ headers = ( 'image:', 'file:', 'abbr:', - 'brut:', + 'raw:', '#' ) @@ -164,7 +164,7 @@ quote_tags = [ ] # Tags to check for header in content -content_tags = ("_image:", '_brut:') +content_tags = ("_image:", '_raw:') #=======# From 93b9fc7a2e24f4ef817dfff7d17774ed023d2c20 Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Sat, 31 Dec 2022 01:40:38 +0100 Subject: [PATCH 100/247] wip: indev, added raw file module (some checks on URI left) --- src/var/lib/tyto/program/check.py | 2 +- src/var/lib/tyto/program/tyto.py | 6 ++-- src/var/lib/tyto/program/wip.py | 52 +++++++++++++++++++++++++------ 3 files changed, 46 insertions(+), 14 deletions(-) diff --git a/src/var/lib/tyto/program/check.py b/src/var/lib/tyto/program/check.py index 248285f..9eb1535 100644 --- a/src/var/lib/tyto/program/check.py +++ b/src/var/lib/tyto/program/check.py @@ -669,7 +669,7 @@ def create_database(): 'stat_underlines = %s\n'%(int(post_underlines)) + \ 'stat_cites = %s\n'%(int(post_cites)) + \ 'stat_customs = %s\n'%(int(post_customs)) + \ - 'stat_codes = %s\n'%(int(tyto.nbr_codes)) + \ + 'stat_icodes = %s\n'%(int(tyto.nbr_icodes)) + \ 'stat_bcodes = %s\n'%(int(tyto.nbr_bcodes)) + \ 'stat_quotes = %s\n'%(int(tyto.nbr_quotes)) + \ 'stat_lists = %s\n'%(int(post_lists)) diff --git a/src/var/lib/tyto/program/tyto.py b/src/var/lib/tyto/program/tyto.py index 4bbae03..b790dda 100644 --- a/src/var/lib/tyto/program/tyto.py +++ b/src/var/lib/tyto/program/tyto.py @@ -282,9 +282,9 @@ def get_css(line): #-----------------------~ def protect_icodes(post_bottom, article_bottom): global protect_article - global nbr_codes + global nbr_icodes - nbr_codes = 0 # Stats here for DB as content will change + nbr_icodes = 0 # Stats here for DB as content will change protect_article = article_bottom incode = False src_code = rep_code = '' @@ -304,7 +304,7 @@ def protect_icodes(post_bottom, article_bottom): # incode if if c_b == '{' and not c_bb == '\\': incode = True - nbr_codes += 1 + nbr_icodes += 1 code = words_tags[9][2] continue diff --git a/src/var/lib/tyto/program/wip.py b/src/var/lib/tyto/program/wip.py index b95e43c..06643e5 100644 --- a/src/var/lib/tyto/program/wip.py +++ b/src/var/lib/tyto/program/wip.py @@ -86,17 +86,13 @@ def wip_article(target): wip_words_tags() # Paragraphs, strongs, italics wip_links() # Links_%i from headers in DB wip_images() # Images_%i from headers in DB - wip_titles() - - # Quotes. Decode base64 Q64 and convert to HTML - wip_quotes() - - # inline_codes. Decode base64 icode and replace - wip_icodes() - - # Block-codes. Decode B64 and convert to HTML - wip_bcodes() + wip_titles() # Convert #N, remove empty line, add divs + wip_quotes() # Quotes. Decode base64 Q64 and convert to HTML + wip_icodes() # inline_codes. Decode base64 icode and replace + wip_bcodes() # Block-codes. Decode B64 and convert to HTML + wip_raws(target) # Read file and convert to HTML + # Result (temp display) print(article_bottom) @@ -219,6 +215,8 @@ def get_wh_image(value): # Convert _images:%name to HTML # #---------------------------------# def wip_images(): + if uniq_images == 0: return + global article_bottom if uniq_images > 0: @@ -298,6 +296,8 @@ def quote_params(qline): # Convert quote in article # #--------------------------# def wip_quotes() : + if stat_quotes == 0: return + global article_bottom global author, link, lang, book, date @@ -432,6 +432,8 @@ def wip_quotes() : # Content is HTML ready # #--------------------------# def wip_icodes(): + if stat_icodes == 0: return + global article_bottom matches = re.findall(r'I64.(.*?).I64', article_bottom) @@ -446,6 +448,8 @@ def wip_icodes(): # Content is raw, and have to be converted in HTML # #--------------------------------------------------# def wip_bcodes(): + if stat_bcodes == 0: return + global article_bottom matches = re.findall(r'B64.(.*?).B64', article_bottom) @@ -536,3 +540,31 @@ def wip_titles(): # Replace article with new contents article_bottom = article_temp + + +# +# Convert raw file to HTML with
     + 
    +#
    +def wip_raws(target):
    +  if uniq_raws == 0: return
    +  
    +  global article_bottom
    +  
    +  for i in range(1, uniq_raws + 1):
    +    raw = 'raw_%s'%i
    +    raw_file = open(
    +                    '%s%s'%(
    +                    tyto.domain_articles, eval(raw)[1]
    +                    )
    +                   ).read()
    +    raw_html = '
    \n'%(
    +               tyto.domain_css, eval(raw)[2]
    +               ) + \
    +               '  '
    +    for line in raw_file.rsplit('\n'):
    +      raw_html = '%s\n    %s'%(raw_html, line)
    +
    +    raw_html = '%s\n  \n
    '%(raw_html) + article_bottom = article_bottom.replace( + eval(raw)[0], raw_html + ) From 6983ea89edc47b8f0b536e93d000a3ed97f64dfd Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Sat, 31 Dec 2022 15:47:14 +0100 Subject: [PATCH 101/247] wip: fix quotes. Added pre-tabs for html article --- src/var/lib/tyto/program/wip.py | 67 ++++++++++++++++++++++++++++----- 1 file changed, 57 insertions(+), 10 deletions(-) diff --git a/src/var/lib/tyto/program/wip.py b/src/var/lib/tyto/program/wip.py index 06643e5..1d0af86 100644 --- a/src/var/lib/tyto/program/wip.py +++ b/src/var/lib/tyto/program/wip.py @@ -91,6 +91,7 @@ def wip_article(target): wip_icodes() # inline_codes. Decode base64 icode and replace wip_bcodes() # Block-codes. Decode B64 and convert to HTML wip_raws(target) # Read file and convert to HTML + wip_tabs() # make HTML tabulations # Result (temp display) print(article_bottom) @@ -311,6 +312,7 @@ def wip_quotes() : # Read the quote. Get parameters author = date = lang = book = link = quote_html = '' cite = figc = '' + tab_t = '' tab_p = tab_c = 2 # Init 2 tabs after
    auth_html = title_html = '' @@ -383,9 +385,13 @@ def wip_quotes() : else: title_html = ' title="%s"'%author auth_html = '%s'%author + if link: figc= '%s'%( link, auth_html ) + else: + figc = '%s'%auth_html + else: if book and date: title_html = ' title="%s (%s)"'%( book, date @@ -395,8 +401,9 @@ def wip_quotes() : time_html_o = time_html_c = '' if date: - time_html_o = '\n' + if author: tab_t = ' ' + time_html_o = '%s\n'%tab_t # Create HTML Quote with datas if author: @@ -404,9 +411,9 @@ def wip_quotes() : '
    \n'%( set_css, lang, cite, title_html ) + \ - ' ' + time_html_o + \ + time_html_o + \ '%s\n'%quote_html + \ - ' ' + time_html_c + \ + time_html_c + \ '
    \n' + \ '
    \n'%set_css + \ ' %s\n'%figc + \ @@ -521,15 +528,17 @@ def wip_titles(): article_tmp2 = article_temp indiv = False for ln, line in enumerate(article_tmp2.rsplit('\n')): + try: article_tmp2.rsplit('\n')[ln + 1] + except: continue + if line.startswith('\n%s'%line ) indiv = False - if line.startswith(' + -# +#==============================================# +# Convert raw file to HTML with
     +  #
    +#----------------------------------------------#
     def wip_raws(target):
       if uniq_raws == 0: return
       
    @@ -568,3 +577,41 @@ def wip_raws(target):
         article_bottom = article_bottom.replace(
                          eval(raw)[0], raw_html
                          )
    +
    +#
    +# Make HTML tabulations
    +#
    +def wip_tabs():
    +  global article_bottom
    +  article_temp = ''
    +  tab_start = 8 # From 
    tag + indiv = False + + for line in article_bottom.rsplit('\n'): + # Titles + if line.startswith(''): + tab = int(tab) - 2 + article_temp = '%s\n%s%s'%(article_temp, tab * ' ', line) + indiv = False + continue + + # Other contents + else: + article_temp = '%s\n%s%s'%(article_temp, tab * ' ', line) + + article_bottom = article_temp + From d46937e20f83e74317f9cc4434fbf69c7c0e2cd8 Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Sat, 31 Dec 2022 15:54:12 +0100 Subject: [PATCH 102/247] wip: fix module order --- src/var/lib/tyto/program/wip.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/var/lib/tyto/program/wip.py b/src/var/lib/tyto/program/wip.py index 1d0af86..0890514 100644 --- a/src/var/lib/tyto/program/wip.py +++ b/src/var/lib/tyto/program/wip.py @@ -70,17 +70,17 @@ def wip_article(target): global post_header, article_header global post_bottom, article_bottom - - # Protect inline-codes - tyto.protect_icodes(post_bottom, article_bottom) - post_bottom = tyto.protect_article.rsplit('\n') - article_bottom = tyto.protect_article - + # Protect block-codes and quotes tyto.protect_bcodes_quotes('wip', post_bottom, article_bottom) post_bottom = tyto.protect_article.rsplit('\n') article_bottom = tyto.protect_article + # Protect inline-codes + tyto.protect_icodes(post_bottom, article_bottom) + post_bottom = tyto.protect_article.rsplit('\n') + article_bottom = tyto.protect_article + # Convert contents from modules wip_single_tags() # br /, anchors wip_words_tags() # Paragraphs, strongs, italics From 5a38722c6b27617472fa351994b4bf8cacd09fb8 Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Sat, 31 Dec 2022 16:52:26 +0100 Subject: [PATCH 103/247] wip: fix tabs --- src/var/lib/tyto/program/wip.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/var/lib/tyto/program/wip.py b/src/var/lib/tyto/program/wip.py index 0890514..7172194 100644 --- a/src/var/lib/tyto/program/wip.py +++ b/src/var/lib/tyto/program/wip.py @@ -584,6 +584,7 @@ def wip_raws(target): def wip_tabs(): global article_bottom article_temp = '' + tab = 0 tab_start = 8 # From
    tag indiv = False From cb6bc7690dfbdc6161e3503d2278da042242fbbc Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Sat, 31 Dec 2022 16:54:01 +0100 Subject: [PATCH 104/247] wip: fix tabs --- src/var/lib/tyto/program/wip.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/var/lib/tyto/program/wip.py b/src/var/lib/tyto/program/wip.py index 7172194..e0c2928 100644 --- a/src/var/lib/tyto/program/wip.py +++ b/src/var/lib/tyto/program/wip.py @@ -584,8 +584,7 @@ def wip_raws(target): def wip_tabs(): global article_bottom article_temp = '' - tab = 0 - tab_start = 8 # From
    tag + tab = tab_start = 8 # From
    tag indiv = False for line in article_bottom.rsplit('\n'): From d550b599c2a9d14bef36f2fb8ed3cf7c94ee2401 Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Sat, 31 Dec 2022 17:19:58 +0100 Subject: [PATCH 105/247] wip: Added module abbrs --- src/var/lib/tyto/program/check.py | 2 +- src/var/lib/tyto/program/wip.py | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/var/lib/tyto/program/check.py b/src/var/lib/tyto/program/check.py index 9eb1535..d7cfdee 100644 --- a/src/var/lib/tyto/program/check.py +++ b/src/var/lib/tyto/program/check.py @@ -620,7 +620,7 @@ def create_database(): if stat_abbrs > 0: for i in range(1, stat_abbrs + 1): - database = '%sabbr_%s = %s'%( + database = '%s\nabbr_%s = %s'%( database, i, globals()['abbr_%s'%i] ) diff --git a/src/var/lib/tyto/program/wip.py b/src/var/lib/tyto/program/wip.py index e0c2928..c84f16a 100644 --- a/src/var/lib/tyto/program/wip.py +++ b/src/var/lib/tyto/program/wip.py @@ -85,6 +85,7 @@ def wip_article(target): wip_single_tags() # br /, anchors wip_words_tags() # Paragraphs, strongs, italics wip_links() # Links_%i from headers in DB + wip_abbrs() # Convert abbr wip_images() # Images_%i from headers in DB wip_titles() # Convert #N, remove empty line, add divs wip_quotes() # Quotes. Decode base64 Q64 and convert to HTML @@ -202,6 +203,21 @@ def wip_links(): eval(link)[0], eval(link)[1]%('_self') ) + +# +# Convert Abbrs +# +def wip_abbrs(): + if uniq_abbrs == 0: return + + global article_bottom + abbr_html = '%s' + + for i in range(1, uniq_abbrs + 1): + abbr = 'abbr_%s'%i + article_bottom = article_bottom.replace(eval(abbr)[0], eval(abbr)[1]) + + #-------------------------------------# # Get width and height for image # # from parameter c=, from wip_image() # From 272cd6831c6df01b36c28cf0c8046ac7c2a201ba Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Sat, 31 Dec 2022 17:21:05 +0100 Subject: [PATCH 106/247] wip: Added module abbrs --- src/var/lib/tyto/program/wip.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/var/lib/tyto/program/wip.py b/src/var/lib/tyto/program/wip.py index c84f16a..e471d1b 100644 --- a/src/var/lib/tyto/program/wip.py +++ b/src/var/lib/tyto/program/wip.py @@ -211,7 +211,6 @@ def wip_abbrs(): if uniq_abbrs == 0: return global article_bottom - abbr_html = '%s' for i in range(1, uniq_abbrs + 1): abbr = 'abbr_%s'%i From 2d2d3b564e4aff943dd8c322cb2ee1d093cbaab2 Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Sun, 1 Jan 2023 18:42:54 +0100 Subject: [PATCH 107/247] Changes. ABBRs: use \!ABBR in article. See README --- README.md | 5 +++-- src/var/lib/tyto/program/check.py | 6 +++--- src/var/lib/tyto/program/wip.py | 6 +++--- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 1828d4e..ea91fe9 100644 --- a/README.md +++ b/README.md @@ -161,11 +161,12 @@ Vous pouvez avoir un NAME identique pour file: et link: ### Abréviations ``` -# ! NOM sera remplacé par "nom" dans la page si défini en entête +# 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 +# Mettre '!' devant NOM dans l'article # nom -Avec ce NOM. +Avec ce !NOM. ``` ### Images diff --git a/src/var/lib/tyto/program/check.py b/src/var/lib/tyto/program/check.py index d7cfdee..c7ffdd8 100644 --- a/src/var/lib/tyto/program/check.py +++ b/src/var/lib/tyto/program/check.py @@ -258,8 +258,8 @@ def check_headers(post_header): tyto.exiting("3", "Line %s (Upper SHORT, %s)"%(ln, tag), False) post_err = True continue - if not isin(r'\b%s\b'%abbr_short, post_bottom): - tyto.exiting("6", abbr_short, False) + if not isin(r'!\b%s\b'%abbr_short, post_bottom): + tyto.exiting("6", '!%s'%abbr_short, False) post_err = True abbr_long = post_header[ln].lstrip() @@ -277,7 +277,7 @@ def check_headers(post_header): 'abbr', abbr_long, abbr_alt ) globals()['abbr_%s'%stat_abbrs] = ( - abbr_short, web_link + '!%s'%abbr_short, web_link ) # LINK diff --git a/src/var/lib/tyto/program/wip.py b/src/var/lib/tyto/program/wip.py index e471d1b..754c943 100644 --- a/src/var/lib/tyto/program/wip.py +++ b/src/var/lib/tyto/program/wip.py @@ -204,9 +204,9 @@ def wip_links(): ) -# -# Convert Abbrs -# +#===============# +# Convert Abbrs # +#---------------# def wip_abbrs(): if uniq_abbrs == 0: return From cee1c677393f823cfcfe43bc5cb5c48b0e917f39 Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Sun, 1 Jan 2023 23:37:19 +0100 Subject: [PATCH 108/247] check: corrupt database. wip: add hash and date to database --- src/var/lib/tyto/program/check.py | 17 ++++++++++------ src/var/lib/tyto/program/tyto.py | 34 +++++++++++++++++++++++++++++++ src/var/lib/tyto/program/wip.py | 1 + 3 files changed, 46 insertions(+), 6 deletions(-) diff --git a/src/var/lib/tyto/program/check.py b/src/var/lib/tyto/program/check.py index c7ffdd8..c5513c6 100644 --- a/src/var/lib/tyto/program/check.py +++ b/src/var/lib/tyto/program/check.py @@ -50,9 +50,14 @@ def manage_check(target, option): return if db_exists: - exec(open(tyto.post_db).read(),globals()) - if hash_chk == tyto.hash_post and not option == 'Force': - tyto.exiting("20", date_chk, True) + try: + exec(open(tyto.post_db).read(),globals()) + try: + if hash_chk == tyto.hash_post and not option == 'Force': + tyto.exiting("20", date_chk, True) + except: pass + except: pass + # Start processes file_to_string(tyto.uri_root) @@ -604,12 +609,12 @@ def create_database(): 'wip_uri = "%s%s"\n'%(srv_wip, web_uri) + \ 'www_uri = "%s%s"\n'%(srv_www, web_uri) + \ 'http_uri = "%s"\n'%tyto.web_uri + \ - 'hash_wip = ""\n' + \ - 'date_www = ""\n' + \ - 'hash_www = ""\n' + \ 'date_chk = "%s"\n'%tyto.nowdate() + \ 'hash_chk = "%s"\n'%tyto.hash_post + \ 'date_wip = ""\n' + \ + 'hash_wip = ""\n' + \ + 'date_www = ""\n' + \ + 'hash_www = ""\n' + \ '\n# Post configuration from needed tags\n' + \ 'title = "%s"\n'%title + \ 'about = "%s"\n'%about + \ diff --git a/src/var/lib/tyto/program/tyto.py b/src/var/lib/tyto/program/tyto.py index b790dda..9c7340a 100644 --- a/src/var/lib/tyto/program/tyto.py +++ b/src/var/lib/tyto/program/tyto.py @@ -232,6 +232,12 @@ def get_db_post(target): if os.path.exists(post_db): db_exists = True else : db_exists = False + # Check if null byte + if db_exists and os.stat(post_db).st_size < 1000: + os.remove(post_db) + exiting('23', post_db, False) + db_exists = False + return(db_exists) @@ -449,6 +455,33 @@ def b64(action, content, before, after): sys.exit(1) +# +# Replace in post_db +# Used for wip and publish +# to replace hash and date when done +# +def replace_in_db(post_db, process, hash_post): + file_db = open(post_db, "r") + lines = file_db.readlines() + new_file = '' + + for line in lines: + if line.startswith('hash_%s'%process): + line = line.replace(line, 'hash_%s = "%s"'%(process, hash_post)) + new_file = '%s%s\n'%(new_file, line) + elif line.startswith('date_%s'%process): + line = line.replace(line, 'date_%s = "%s"'%(process, nowdate())) + new_file = '%s%s\n'%(new_file, line) + else: + if new_file: new_file = '%s%s'%(new_file, line) + else: new_file = line + + file = open(post_db, 'w') + file.write(new_file) + file.close() + + + #================================# # Exit from program with message # #--------------------------------# @@ -467,6 +500,7 @@ def exiting(nbr, value, out): '20' : ':D Article already up-to-date on: %s'%value, '21' : ':D \033[1;32mArticle is valid\033[0;0m and ready to wip', '22' : ':? Symbols: %s \033[1;33mnot paired\033[0;0m'%value, + '23' : ':< \033[1;33mDatabase was corrupt\033[0;0m: %s'%value, '255' : ':| Maybe later...' } diff --git a/src/var/lib/tyto/program/wip.py b/src/var/lib/tyto/program/wip.py index 754c943..2821494 100644 --- a/src/var/lib/tyto/program/wip.py +++ b/src/var/lib/tyto/program/wip.py @@ -96,6 +96,7 @@ def wip_article(target): # Result (temp display) print(article_bottom) + tyto.replace_in_db(tyto.post_db, 'wip', tyto.hash_post) #=================================# From 6877d67533eaa497a5418738bdfcc36dab12fbd6 Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Tue, 3 Jan 2023 11:38:02 +0100 Subject: [PATCH 109/247] wip: fix. Protected quotes and bcodes --- src/var/lib/tyto/program/tyto.py | 88 ++++++++++++++++---------------- src/var/lib/tyto/program/wip.py | 4 +- 2 files changed, 46 insertions(+), 46 deletions(-) diff --git a/src/var/lib/tyto/program/tyto.py b/src/var/lib/tyto/program/tyto.py index 9c7340a..4efa14a 100644 --- a/src/var/lib/tyto/program/tyto.py +++ b/src/var/lib/tyto/program/tyto.py @@ -381,53 +381,53 @@ def protect_bcodes_quotes(process, post_bottom, article_bottom): if not protect_article: protect_article = line else: protect_article = '%s\n%s'%(protect_article, line) + # For wip, bcodes are converted to base64 #---------------------------------------- elif process == 'wip': - - # Convert bcodes and quotes - # include markers in base64, remove from article bcode = quote = '' - for ln, line in enumerate(post_bottom): - # bcode - if line.startswith(words_tags[12][0]): - in_bcode = True - elif line.startswith(words_tags[12][1]): - bcode = '%s\n%s'%(bcode, line) - in_bcode = False - b64_bcode = b64('Encode', bcode, 'B64.', '.B64') - protect_article = '%s\n%s'%(protect_article, b64_bcode) - bcode = '' - continue - elif line.startswith('#'): # As convention - if not line.startswith(titles_tags): - continue + end_bcode = end_quote = False + + for line in post_bottom: + # Bcode + if not in_quote: + if line.startswith(words_tags[12][0]): + in_bcode = True + elif line.startswith(words_tags[12][1]): + bcode = '%s\n%s'%(bcode, line) + b64_bcode = b64('Encode', bcode, 'B64.', '.B64') + line = b64_bcode + end_bcode = True + in_bcode = False - # quote - elif line.startswith(words_tags[11][0]): - if not in_bcode: + # Quote + if not in_bcode: + if line.startswith(words_tags[11][0]): in_quote = True - elif line.startswith(words_tags[11][1]): - if not in_bcode: + elif line.startswith(words_tags[11][1]): quote = '%s\n%s'%(quote, line) + b64_quote = b64('Encode', quote, 'Q64.', '.Q64') + line = b64_quote + end_quote = True in_quote = False - b64_quote = b64('Encode', quote, 'Q64.', '.Q64') - protect_article = '%s\n%s'%(protect_article, b64_quote) - quote = '' - continue - - # Priority to bcode + if in_bcode: - if bcode: bcode = '%s\n%s'%(bcode, line) - else: bcode = line - else: - if in_quote: - if quote: quote = '%s\n%s'%(quote, line) - else: quote = line - else: - if not protect_article: protect_article = line - else: protect_article = '%s\n%s'%(protect_article, line) + if not bcode: bcode = line + else: bcode = '%s\n%s'%(bcode, line) + + elif in_quote: + if not quote: quote = line + else: quote = '%s\n%s'%(quote, line) + + if end_bcode: bcode = ''; end_bcode = False ; in_bcode = False + elif end_quote: quote = ''; end_quote = False ; in_quote = False + if in_quote or in_bcode: + continue + else: + if not protect_article: protect_article = line + else: protect_article = '%s\n%s'%(protect_article, line) + #=====================================# # Encode/Decode string to/from base64 # @@ -455,11 +455,11 @@ def b64(action, content, before, after): sys.exit(1) -# -# Replace in post_db -# Used for wip and publish -# to replace hash and date when done -# +#====================================# +# Replace in post_db # +# Used for wip and publish # +# to replace hash and date when done # +#------------------------------------# def replace_in_db(post_db, process, hash_post): file_db = open(post_db, "r") lines = file_db.readlines() @@ -481,7 +481,6 @@ def replace_in_db(post_db, process, hash_post): file.close() - #================================# # Exit from program with message # #--------------------------------# @@ -500,7 +499,8 @@ def exiting(nbr, value, out): '20' : ':D Article already up-to-date on: %s'%value, '21' : ':D \033[1;32mArticle is valid\033[0;0m and ready to wip', '22' : ':? Symbols: %s \033[1;33mnot paired\033[0;0m'%value, - '23' : ':< \033[1;33mDatabase was corrupt\033[0;0m: %s'%value, + '23' : ':? \033[1;33mDatabase was corrupt\033[0;0m: %s'%value, + '24' : ':? \033[1;33mMissing wip file\033[0;0m: %s'%value, '255' : ':| Maybe later...' } diff --git a/src/var/lib/tyto/program/wip.py b/src/var/lib/tyto/program/wip.py index 2821494..dfd7511 100644 --- a/src/var/lib/tyto/program/wip.py +++ b/src/var/lib/tyto/program/wip.py @@ -19,7 +19,7 @@ import os, re import tyto -def manage_wip(target, option): +def manage_wip(target, option): # target needed if not target: tyto.exiting("5", '', True) @@ -51,7 +51,7 @@ def manage_wip(target, option): if do_wip: # Show message if wip was done if hash_wip: - if not is_file: tyto.exiting("1", wip_uri, False) + if not is_file: tyto.exiting("24", wip_uri, False) if is_new: tyto.exiting("9", '', False) wip_article(target) else: From 739236bc47d15c37bda5316335af7b22452b7ca5 Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Tue, 3 Jan 2023 14:07:28 +0100 Subject: [PATCH 110/247] check: Protected quotes and bcodes (+stats) in main fonction protect_bcodes_quotes() --- src/var/lib/tyto/program/tyto.py | 114 +++++++++++++------------------ 1 file changed, 49 insertions(+), 65 deletions(-) diff --git a/src/var/lib/tyto/program/tyto.py b/src/var/lib/tyto/program/tyto.py index 4efa14a..c593a59 100644 --- a/src/var/lib/tyto/program/tyto.py +++ b/src/var/lib/tyto/program/tyto.py @@ -345,88 +345,72 @@ def protect_icodes(post_bottom, article_bottom): def protect_bcodes_quotes(process, post_bottom, article_bottom): global protect_article + global nbr_titles, nbr_bcodes, nbr_quotes # Stats for DB in_bcode = in_quote = False protect_article = '' temp_article = article_bottom + nbr_titles = nbr_bcodes = nbr_quotes = 0 + bcode = quote = '' + end_bcode = end_quote = False - if process == 'check': - global nbr_titles, nbr_bcodes, nbr_quotes # Stats for DB - nbr_titles = nbr_bcodes = nbr_quotes = 0 - - for line in post_bottom: + for line in post_bottom: + # Bcode + if not in_quote: if line.startswith(words_tags[12][0]): in_bcode = True - nbr_bcodes += 1 - continue + if process == 'check': + if not protect_article: protect_article = line + else: protect_article = '%s\n%s'%(protect_article, line) + nbr_bcodes += 1 elif line.startswith(words_tags[12][1]): - in_bcode = False - continue - elif line.startswith('#'): # As convention - if line.startswith(titles_tags): nbr_titles += 1 - else: continue - - if in_bcode: continue - elif line.startswith(words_tags[11][0]): - in_quote = True - nbr_quotes += 1 - continue - elif line.startswith(words_tags[11][1]): - in_quote = False - continue - - if in_quote: - if not line in (words_tags[10][0], words_tags[10][1]): - continue - - if not protect_article: protect_article = line - else: protect_article = '%s\n%s'%(protect_article, line) - - - # For wip, bcodes are converted to base64 - #---------------------------------------- - elif process == 'wip': - bcode = quote = '' - end_bcode = end_quote = False - - for line in post_bottom: - # Bcode - if not in_quote: - if line.startswith(words_tags[12][0]): - in_bcode = True - elif line.startswith(words_tags[12][1]): + if process == "wip": bcode = '%s\n%s'%(bcode, line) b64_bcode = b64('Encode', bcode, 'B64.', '.B64') line = b64_bcode end_bcode = True - in_bcode = False - - # Quote - if not in_bcode: - if line.startswith(words_tags[11][0]): - in_quote = True - elif line.startswith(words_tags[11][1]): + in_bcode = False + + # Quote + if not in_bcode: + if line.startswith(words_tags[11][0]): + in_quote = True + if process == 'check': + if not protect_article: protect_article = line + else: protect_article = '%s\n%s'%(protect_article, line) + nbr_quotes += 1 + elif line.startswith(words_tags[11][1]): + if process == "wip": quote = '%s\n%s'%(quote, line) b64_quote = b64('Encode', quote, 'Q64.', '.Q64') line = b64_quote end_quote = True - in_quote = False - - if in_bcode: - if not bcode: bcode = line - else: bcode = '%s\n%s'%(bcode, line) - - elif in_quote: - if not quote: quote = line - else: quote = '%s\n%s'%(quote, line) + in_quote = False - if end_bcode: bcode = ''; end_bcode = False ; in_bcode = False - elif end_quote: quote = ''; end_quote = False ; in_quote = False + # Count titles for check + # Pass if line is a comment + if not in_bcode or not in_quote: + if line.startswith(titles_tags): + if process == 'check': + nbr_titles += 1 + elif line.startswith('#'): + continue + + if in_bcode: + if not bcode: bcode = line + else: bcode = '%s\n%s'%(bcode, line) + + elif in_quote: + if not quote: quote = line + else: quote = '%s\n%s'%(quote, line) - if in_quote or in_bcode: - continue - else: - if not protect_article: protect_article = line - else: protect_article = '%s\n%s'%(protect_article, line) + if end_bcode: bcode = ''; end_bcode = False ; in_bcode = False + elif end_quote: quote = ''; end_quote = False ; in_quote = False + + if in_quote or in_bcode: + continue + else: + if not protect_article: protect_article = line + else: protect_article = '%s\n%s'%(protect_article, line) #=====================================# From b62137bc0ea4ad78bc018ee6b621eabcc303c391 Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Tue, 3 Jan 2023 14:52:43 +0100 Subject: [PATCH 111/247] stdout: colors and messages --- src/var/lib/tyto/program/tyto.py | 38 ++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/src/var/lib/tyto/program/tyto.py b/src/var/lib/tyto/program/tyto.py index c593a59..18419da 100644 --- a/src/var/lib/tyto/program/tyto.py +++ b/src/var/lib/tyto/program/tyto.py @@ -30,7 +30,6 @@ arguments = ( '-F', 'force' ) - # Settings #--------- domain_active = False @@ -104,6 +103,12 @@ headers = ( 'raw:', '#' ) + +# Colors +CS = '\033[0;0m' +CR = '\033[1;31m' +CY = '\033[1;33m' +CG = '\033[1;32m' # Words and template Tags (paragraphs, lists, bold, strong...) # Used to check, and replace (wip) tags @@ -339,11 +344,10 @@ def protect_icodes(post_bottom, article_bottom): # Protect block-Codes, quotes # # Also remove commented lines # # Used in check and wip # -# For check, create new article without bcode # -# For wip, remplace content with base64 # +# check: create string without quotes, bcode # +# wip: remplace quotes, bcode with base64 # #---------------------------------------------# def protect_bcodes_quotes(process, post_bottom, article_bottom): - global protect_article global nbr_titles, nbr_bcodes, nbr_quotes # Stats for DB in_bcode = in_quote = False @@ -470,21 +474,21 @@ def replace_in_db(post_db, process, hash_post): #--------------------------------# def exiting(nbr, value, out): nbrs = { - '1' : ':< \033[1;31mUnused ressource\033[0;0m: "%s"'%value, - '2' : ':< \033[1;31mIncomplete data\033[0;0m: "%s"'%value, - '3' : ':< \033[1;31mInvalid data\033[0;0m: "%s"'%value, - '4' : ':< \033[1;31mNo database yet\033[0;0m. Check article first.', - '5' : ':< \033[1;31mUnused argument\033[0;0m file', - '6' : ':< \033[1;31mUnused "%s"\033[0;0m in article'%value, - '7' : ':< Article is \033[1;31mnot valid yet\033[0;0m', - '8' : ':< %s: \033[1;31mnot paired\033[0;0m'%value, + '1' : ':< %sUnused ressource%s: %s'%(CR, CS, value), + '2' : ':< %sIncomplete data%s: "%s"'%(CR, CS, value), + '3' : ':< %sInvalid data%s: "%s"'%(CR, CS, value), + '4' : ':< %sNo database yet%s. Check article first.'%(CR, CS), + '5' : ':< %sUnused argument%s: [file]'%(CR, CS), + '6' : ':< %sUnused "%s"%s in article'%(CR, CS, value), + '7' : ':< Article is %snot valid yet%s'%(CR, CS), + '8' : ':< %s: %snot paired%s'%(value, CR, CS), '9' : ':D Article has changed (wip is old)', - '10' : ':< \033[1;31mUnused "%s"\033[0;0m in article\'s header'%value, - '20' : ':D Article already up-to-date on: %s'%value, - '21' : ':D \033[1;32mArticle is valid\033[0;0m and ready to wip', + '10' : ':< %sUnused "%s"%s in article\'s header'%(CR, value, CS), + '20' : ':D %sUp-to-date%s article on: %s'%(CG, CS, value), + '21' : ':D %sValid%s article to wip'%(CG, CS), '22' : ':? Symbols: %s \033[1;33mnot paired\033[0;0m'%value, - '23' : ':? \033[1;33mDatabase was corrupt\033[0;0m: %s'%value, - '24' : ':? \033[1;33mMissing wip file\033[0;0m: %s'%value, + '23' : ':? %sCorrupted database%s: %s'%(CY, CS, value), + '24' : ':? %sMissing wip file%s: %s'%(CY, CS, value), '255' : ':| Maybe later...' } From 0bc41f26609ef96c1f1be781385bfe5b1002581a Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Tue, 3 Jan 2023 14:57:22 +0100 Subject: [PATCH 112/247] stdout: colors and messages --- src/var/lib/tyto/program/tyto.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/var/lib/tyto/program/tyto.py b/src/var/lib/tyto/program/tyto.py index 18419da..248c40b 100644 --- a/src/var/lib/tyto/program/tyto.py +++ b/src/var/lib/tyto/program/tyto.py @@ -481,12 +481,12 @@ def exiting(nbr, value, out): '5' : ':< %sUnused argument%s: [file]'%(CR, CS), '6' : ':< %sUnused "%s"%s in article'%(CR, CS, value), '7' : ':< Article is %snot valid yet%s'%(CR, CS), - '8' : ':< %s: %snot paired%s'%(value, CR, CS), + '8' : ':< %sNot paired%s: %s'%(CR, CS, value), '9' : ':D Article has changed (wip is old)', '10' : ':< %sUnused "%s"%s in article\'s header'%(CR, value, CS), '20' : ':D %sUp-to-date%s article on: %s'%(CG, CS, value), '21' : ':D %sValid%s article to wip'%(CG, CS), - '22' : ':? Symbols: %s \033[1;33mnot paired\033[0;0m'%value, + '22' : ':? %sNot paired%s symbols: %s'%(CY, CS, value), '23' : ':? %sCorrupted database%s: %s'%(CY, CS, value), '24' : ':? %sMissing wip file%s: %s'%(CY, CS, value), '255' : ':| Maybe later...' From 9a407e8e61188bcbe3f8f90adf0f42998dbaaeba Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Wed, 4 Jan 2023 09:38:25 +0100 Subject: [PATCH 113/247] lots of new littles things. Better wip management --- src/usr/bin/tyto | 4 +++- src/var/lib/tyto/program/check.py | 23 +++++++++++++++++++---- src/var/lib/tyto/program/domain.py | 8 +++++++- src/var/lib/tyto/program/tyto.py | 11 ++++++----- src/var/lib/tyto/program/wip.py | 25 +++++++++---------------- 5 files changed, 44 insertions(+), 27 deletions(-) diff --git a/src/usr/bin/tyto b/src/usr/bin/tyto index 1680482..8d97ea0 100755 --- a/src/usr/bin/tyto +++ b/src/usr/bin/tyto @@ -54,7 +54,9 @@ options = { '-R' : "Remove", 'remove' : "Remove", '-n' : "New", 'new' : "New", '-e' : "Edit", 'edit' : "Edit", - '-F' : "Force", 'force' : "Force" + '-F' : "Force", 'force' : "Force", + '-s' : "Show", + '-d' : 'DB' } # Set Argument 2 or 3 diff --git a/src/var/lib/tyto/program/check.py b/src/var/lib/tyto/program/check.py index c5513c6..a28b034 100644 --- a/src/var/lib/tyto/program/check.py +++ b/src/var/lib/tyto/program/check.py @@ -28,6 +28,7 @@ import tyto if tyto.domain_exists: exec(open(tyto.domain_conf).read()) post_err = False +date_wip = hash_wip = date_www = hash_www = '' #=========================# @@ -48,8 +49,20 @@ def manage_check(target, option): if option == 'Edit': tyto.edit_file(tyto.uri_root) return + elif option == 'Show': + article_raw = open(tyto.uri_root).read() + for line in article_raw.rsplit('\n'): + print(line) + return if db_exists: + # Just read the DB from command + if option == 'DB': + article_db = open(tyto.post_db).read() + for line in article_db.rsplit('\n'): + print(line) + return + try: exec(open(tyto.post_db).read(),globals()) try: @@ -64,6 +77,7 @@ def manage_check(target, option): # Specific to inline-code: check markers on same line check_icodes(article.rsplit('\n')) + # Protect inline-codes tyto.protect_icodes(post_bottom, article_bottom) post_bottom = tyto.protect_article.rsplit('\n') @@ -609,12 +623,13 @@ def create_database(): 'wip_uri = "%s%s"\n'%(srv_wip, web_uri) + \ 'www_uri = "%s%s"\n'%(srv_www, web_uri) + \ 'http_uri = "%s"\n'%tyto.web_uri + \ + '\n' + \ 'date_chk = "%s"\n'%tyto.nowdate() + \ 'hash_chk = "%s"\n'%tyto.hash_post + \ - 'date_wip = ""\n' + \ - 'hash_wip = ""\n' + \ - 'date_www = ""\n' + \ - 'hash_www = ""\n' + \ + 'date_wip = "%s"\n'%date_wip + \ + 'hash_wip = "%s"\n'%hash_wip + \ + 'date_www = "%s"\n'%date_www + \ + 'hash_www = "%s"\n'%hash_www + \ '\n# Post configuration from needed tags\n' + \ 'title = "%s"\n'%title + \ 'about = "%s"\n'%about + \ diff --git a/src/var/lib/tyto/program/domain.py b/src/var/lib/tyto/program/domain.py index 723dee6..1b45b75 100644 --- a/src/var/lib/tyto/program/domain.py +++ b/src/var/lib/tyto/program/domain.py @@ -29,7 +29,7 @@ def manage_domain(target, option): print(":D Edit domain configuration file:", tyto.domain_conf) tyto.edit_file(tyto.domain_conf) - if option == 'New': + elif option == 'New': if not tyto.domain_exists: create_domain(target) else: @@ -38,6 +38,12 @@ def manage_domain(target, option): if ask in ['y', 'Y']: create_domain(target) else: tyto.exiting("255", '', True) + elif option == 'DB' or option == 'Show': + if tyto.domain_exists: + domain_db = open(tyto.domain_conf).read() + for line in domain_db.rsplit('\n'): + print(line) + #=====================# # Check target if URL # diff --git a/src/var/lib/tyto/program/tyto.py b/src/var/lib/tyto/program/tyto.py index 248c40b..4d7e893 100644 --- a/src/var/lib/tyto/program/tyto.py +++ b/src/var/lib/tyto/program/tyto.py @@ -392,18 +392,19 @@ def protect_bcodes_quotes(process, post_bottom, article_bottom): # Count titles for check # Pass if line is a comment - if not in_bcode or not in_quote: + if not in_bcode and not in_quote: if line.startswith(titles_tags): if process == 'check': nbr_titles += 1 elif line.startswith('#'): - continue + continue if in_bcode: if not bcode: bcode = line else: bcode = '%s\n%s'%(bcode, line) elif in_quote: + if line.startswith('#'): continue if not quote: quote = line else: quote = '%s\n%s'%(quote, line) @@ -482,13 +483,13 @@ def exiting(nbr, value, out): '6' : ':< %sUnused "%s"%s in article'%(CR, CS, value), '7' : ':< Article is %snot valid yet%s'%(CR, CS), '8' : ':< %sNot paired%s: %s'%(CR, CS, value), - '9' : ':D Article has changed (wip is old)', + '9' : ':< Article %shas changed%s. Check it first'%(CR, CS), '10' : ':< %sUnused "%s"%s in article\'s header'%(CR, value, CS), '20' : ':D %sUp-to-date%s article on: %s'%(CG, CS, value), - '21' : ':D %sValid%s article to wip'%(CG, CS), + '21' : ':D %sValid%s article. Ready to wip'%(CG, CS), '22' : ':? %sNot paired%s symbols: %s'%(CY, CS, value), '23' : ':? %sCorrupted database%s: %s'%(CY, CS, value), - '24' : ':? %sMissing wip file%s: %s'%(CY, CS, value), + '24' : ':? %sfile missing%s (wip article): %s'%(CY, CS, value), '255' : ':| Maybe later...' } diff --git a/src/var/lib/tyto/program/wip.py b/src/var/lib/tyto/program/wip.py index dfd7511..55aab43 100644 --- a/src/var/lib/tyto/program/wip.py +++ b/src/var/lib/tyto/program/wip.py @@ -29,33 +29,26 @@ def manage_wip(target, option): if not db_exists: tyto.exiting("4", '', True) - # Has DB: conditions to process - is_wip = True - is_new = False - is_file = True - do_wip = False - # Load DB exec(open(tyto.post_db).read(),globals()) + # Exit if article has changed + if hash_chk != tyto.hash_post: tyto.exiting("9", '', True) + # In any case, if Force if option == 'Force': wip_article(target) return # Compare and check file - if not hash_wip == hash_chk: is_wip = False ; do_wip = True - if not hash_wip == tyto.hash_post: is_new = True ; do_wip = True - if not os.path.exists(wip_uri): is_file = False ; do_wip = True - - if do_wip: - # Show message if wip was done - if hash_wip: - if not is_file: tyto.exiting("24", wip_uri, False) - if is_new: tyto.exiting("9", '', False) + if hash_wip != hash_chk: wip_article(target) else: - tyto.exiting("20", date_wip, True) + if not os.path.exists(wip_uri): + tyto.exiting("24", wip_uri, False) + wip_article(target) + else: + tyto.exiting("20", date_wip, True) #===================# From e3908df489271c4459134e8d0e1163ab17d38e30 Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Thu, 5 Jan 2023 17:37:23 +0100 Subject: [PATCH 114/247] Fix: new domain_conf check. HTML: indev, created some metas tags --- src/var/lib/tyto/program/check.py | 12 +++- src/var/lib/tyto/program/domain.py | 35 ++++----- src/var/lib/tyto/program/html.py | 109 +++++++++++++++++++++++++++++ src/var/lib/tyto/program/tyto.py | 50 ++++++++----- src/var/lib/tyto/program/wip.py | 8 ++- 5 files changed, 175 insertions(+), 39 deletions(-) create mode 100644 src/var/lib/tyto/program/html.py diff --git a/src/var/lib/tyto/program/check.py b/src/var/lib/tyto/program/check.py index a28b034..453d021 100644 --- a/src/var/lib/tyto/program/check.py +++ b/src/var/lib/tyto/program/check.py @@ -41,7 +41,7 @@ def manage_check(target, option): # target needed if not target: tyto.exiting("5", '', True) - + # Article exists + has DB ? db_exists = tyto.get_db_post(target) @@ -70,7 +70,13 @@ def manage_check(target, option): tyto.exiting("20", date_chk, True) except: pass except: pass - + + # Get sub_uri for HTML + global sub_uri + sub_uri = tyto.uri_post.rsplit('articles/')[1] + sub_nbr = sub_uri.count('/') + if sub_nbr == 0 : sub_uri = './' + else: sub_uri = sub_nbr * '../' # Start processes file_to_string(tyto.uri_root) @@ -96,7 +102,6 @@ def manage_check(target, option): post_bottom = article_bottom.rsplit('\n') check_headers(post_header) - # Exit if unused needed tags if post_err: tyto.exiting("7", '', True) @@ -623,6 +628,7 @@ def create_database(): 'wip_uri = "%s%s"\n'%(srv_wip, web_uri) + \ 'www_uri = "%s%s"\n'%(srv_www, web_uri) + \ 'http_uri = "%s"\n'%tyto.web_uri + \ + 'sub_uri = "%s"\n'%sub_uri + \ '\n' + \ 'date_chk = "%s"\n'%tyto.nowdate() + \ 'hash_chk = "%s"\n'%tyto.hash_post + \ diff --git a/src/var/lib/tyto/program/domain.py b/src/var/lib/tyto/program/domain.py index 1b45b75..8fd3ef8 100644 --- a/src/var/lib/tyto/program/domain.py +++ b/src/var/lib/tyto/program/domain.py @@ -31,11 +31,11 @@ def manage_domain(target, option): elif option == 'New': if not tyto.domain_exists: - create_domain(target) + create_domain(target, option) else: print(':) A domain exists in this directory') ask = input('-> Edit it with the form ? ') - if ask in ['y', 'Y']: create_domain(target) + if ask in ['y', 'Y']: create_domain(target, option) else: tyto.exiting("255", '', True) elif option == 'DB' or option == 'Show': @@ -58,7 +58,7 @@ def isurl(target): #=====================# # Create a new domain # #---------------------# -def create_domain(target): +def create_domain(target, option): if target: isurl(target) print('\n' @@ -105,13 +105,13 @@ def create_domain(target): domain_wipurl = ask - db_dir = '%s/.local/tyto/'%tyto.home_dir - conf_domain = 'domain_conf = "%s"\n'%tyto.domain_conf + \ - 'domain_db = "%s/%s/articles/"\n'%(db_dir, target) + \ - 'domain_dir = "%s/"\n'%tyto.in_dir + \ - 'domain_articles = "%s/articles/"\n'%tyto.in_dir + \ - 'domain_files = "%s/articles/files/"\n'%tyto.in_dir + \ - 'domain_images = "%s/articles/images/"\n'%tyto.in_dir + \ + db_dir = '%s/.local/tyto/%s/'%(tyto.home_dir, domain_short) + conf_domain = 'domain_dir = "%s"\n'%tyto.conf_dir + \ + 'domain_conf = "%s"\n'%tyto.domain_conf + \ + 'domain_articles = "%sarticles/"\n'%tyto.conf_dir + \ + 'domain_files = "%sarticles/files/"\n'%tyto.conf_dir + \ + 'domain_images = "%sarticles/images/"\n'%tyto.conf_dir + \ + 'domain_db = "%sarticles/"\n'%(db_dir) + \ '\ndomain_short = "%s"\n'%domain_short + \ 'domain_url = "%s"\n'%domain_url + \ 'domain_wipurl = "%s"\n'%domain_wipurl @@ -128,7 +128,8 @@ def create_domain(target): ask = input(' ├ Domain title ? ("%s") '%domain_title) if ask: domain_title = ask elif not domain_title: tyto.exit("255") - if '"' in domain_title: domain_title=domain_title.replace('"', '\\"') + if '"' in domain_title: + domain_title = domain_title.replace('"', '') tyto.set_file(tyto.domain_conf, False, 'domain_title = "%s"'%domain_title) @@ -143,7 +144,8 @@ def create_domain(target): ask = input(' ├ Domain Description ? ("%s") '%domain_about) if ask: domain_about = ask elif not domain_about: tyto.exit("255") - if '"' in domain_about: domain_about=domain_about.replace('"', '\\"') + if '"' in domain_about: + domain_about = domain_about.replace('"', '') tyto.set_file(tyto.domain_conf, False, 'domain_about = "%s"'%domain_about) @@ -205,7 +207,7 @@ def create_domain(target): if ask: domain_license = ask elif not domain_license: tyto.exiting("255", '', True) if '"' in domain_license: - domain_license=domain_license.replace('"', '\\"') + domain_license = domain_license.replace('"', '') tyto.set_file(tyto.domain_conf, False, 'domain_license = "%s"'%domain_license) @@ -265,9 +267,9 @@ def create_domain(target): ask = input(' ├ Sidebar title ? ("%s") '%sidebar_title) if ask: sidebar_title = ask if '"' in sidebar_title: - sidebar_title = sidebar_title.replace('"', '\\"') + sidebar_title = sidebar_title.replace('"', '') - sidebar_conf = '%s/articles/sidebar/'%tyto.in_dir + sidebar_conf = '%sarticles/sidebar/'%tyto.conf_dir sidebar_datas = '\nsidebar_dir = "%s"\n'%sidebar_conf + \ 'sidebar_load = "%styto.sidebar"\n'%sidebar_conf + \ 'sidebar_title = "%s"'%sidebar_title @@ -290,7 +292,6 @@ def create_domain(target): 'sidebar_items = "%s"'%int(sidebar_items)) - # Get srv root #------------- try: domain_srv = tyto.domain_srv @@ -347,7 +348,7 @@ def create_domain(target): exec(open(tyto.domain_conf).read(),globals()) # Create sidebar - create_sidebar(opt, sidebar_dir) + create_sidebar(option, sidebar_dir) # Create folders from configuration file folders = ( diff --git a/src/var/lib/tyto/program/html.py b/src/var/lib/tyto/program/html.py new file mode 100644 index 0000000..56c1311 --- /dev/null +++ b/src/var/lib/tyto/program/html.py @@ -0,0 +1,109 @@ +#!/usr/bin/env python3 +# Name: Tyto - Littérateur +# Type: HTML template +# Description: Create raw HTML template +# file: html.py +# Folder: /var/lib/tyto/program/ +# By echolib (XMPP: im@echolib.re) +# License: GNU AFFERO GENERAL PUBLIC LICENSE Version 3, 19 November 2007 + +#------------ +# funny stats +#------------ +# lines: +# functions: +# comments: +#---------------------------------------------------------------------- + +#********************************************************************** + +import tyto + +# Load domain configuration DB +exec(open(tyto.domain_conf).read(),globals()) + +Tyto = 'Tyto - Littérateur' +tytogit = 'https://git.a-lec.org/echolib/tyto-litterateur' +tytoweb = 'https://tyto.echolib.re' + +#==========================# +# Load article DB # +# Start HTML page sections # +#--------------------------# +def set_page(post_db): + exec(open(post_db).read(),globals()) + + create_metas_page() # Include metas tags + create_main_page() # At last, create main page + + +#============================================# +# Set metas_page to be included in main page # +#--------------------------------------------# +def create_metas_page(): + global metas_page + + # Settings for metas + #------------------- + metas_page = '' + tab = 4 + scale = 'width=device-width, initial-scale=1.0' + visit = '3 days' + all_tags = domain_tags + ',' + tags + post_url = domain_url + http_uri + css_file = 'template/style.css' + css_ref = 'media="screen" href="%s%s" />'%(sub_uri, css_file) + rss_file = 'rss.xml' + rss_ref = 'type="application/rss+xml" ' + \ + 'href="%s%s" title="RSS 2.0. %s %s %s'%( + sub_uri, rss_file, domain_title, domain_sep, domain_short + ) + icon_file = 'favicon.png' + icon_ref = 'type="image/png" href="%s%s"'%(sub_uri, icon_file) + en_date = tyto.set_en_date(date[0]) + + + # Set all raw HTML metas + #----------------------- + metas = '\n' + \ + '\n'%scale + \ + '\n' + \ + '\n' + \ + '\n'%visit + \ + '\n'%domain_lang + \ + '\n'%domain_mail + \ + '\n'%domain_license + \ + '\n'%Tyto + \ + '\n'%title + \ + '\n'%author + \ + '\n'%about + \ + '\n'%all_tags + \ + '\n'%en_date + \ + '\n'%post_url + \ + '\n'%(rss_ref) + \ + '\n'%icon_ref + + + # Create HTML tabulation for metas + #--------------------------------- + for line in metas.rsplit('\n'): + if metas_page: metas_page = '%s\n%s%s'%(metas_page, tab * ' ', line) + else: metas_page = '%s%s'%(tab * ' ', line) + + +#=======================================# +# Set main page, with all HTML sections # +#---------------------------------------# +def create_main_page(): + global main_page + + main_page = '\n' + \ + '\n'%domain_lang + \ + ' \n' + \ + '%s\n'%metas_page + \ + ' \n\n' + \ + ' \n' + \ + '%s\n' + \ + ' \n' + \ + '' diff --git a/src/var/lib/tyto/program/tyto.py b/src/var/lib/tyto/program/tyto.py index 4d7e893..ea83501 100644 --- a/src/var/lib/tyto/program/tyto.py +++ b/src/var/lib/tyto/program/tyto.py @@ -27,7 +27,8 @@ arguments = ( '-R', 'remove', '-e', 'edit', '-n', 'new', - '-F', 'force' + '-F', 'force', + '-d' ) # Settings @@ -35,20 +36,21 @@ arguments = ( domain_active = False home_dir = os.path.expanduser('~') in_dir = os.getcwd() +domain_conf = in_dir -# Set uri for configuration domain file -try: - sys.argv[2] - if not sys.argv[2] in arguments: - conf_dir = '%s/%s'%(in_dir,sys.argv[2]) - conf_dir = conf_dir.rsplit('articles')[0] - else: - conf_dir = in_dir.rsplit('articles')[0] + '/' -except: - conf_dir = in_dir.rsplit('articles')[0] + '/' +if '/articles' in in_dir: + domain_conf = in_dir.rsplit('/articles')[0] +else: + try: + sys.argv[2] + if not sys.argv[2] in arguments: + if 'articles/' in sys.argv[2]: + domain_conf = in_dir.rsplit('articles/')[0] + except: + domain_conf = in_dir -domain_conf = '%styto_domain.conf'%conf_dir -db_dir = '%s/.local/tyto/'%home_dir +conf_dir = domain_conf + "/" +domain_conf = '%s/tyto_domain.conf'%domain_conf # Check if domain config file @@ -63,18 +65,18 @@ if os.path.exists(domain_conf): smiley = ':D'; status = 'Active' domain_active = True else: - smiley = ':/'; status = 'Inactive' + smiley = ':|'; status = 'Inactive' domain_active = False print(stdout%( smiley, status, domain_short, domain_conf ) ) else: - print(':| No domain configured in this directory: %s'%domain_conf) + print(':? No domain configured in this directory: %s'%domain_conf) domain_exists = domain_active = False if domain_exists: - db_dir = '%s%s/articles'%(db_dir, domain_short) + db_dir = domain_db # Basic translations: french, english @@ -84,11 +86,13 @@ except: lang = locale.getdefaultlocale()[0].split('_')[0] if lang.lower() == 'fr': n = 0 else: n = 1 + # Translations French/English trans = [ ['À l\'affiche !', 'Featured !' ] ] + # Set all tags used in article's header headers = ( 'title:', @@ -103,13 +107,15 @@ headers = ( 'raw:', '#' ) - + + # Colors CS = '\033[0;0m' CR = '\033[1;31m' CY = '\033[1;33m' CG = '\033[1;32m' + # Words and template Tags (paragraphs, lists, bold, strong...) # Used to check, and replace (wip) tags # As base64 is used, do NOT set marker: =_ _= @@ -190,13 +196,21 @@ def get_filesum(path, src): #==============================# # Set and return date and time # -# (especially for logs) # #------------------------------# def nowdate(): now = datetime.datetime.now() return(now.strftime('%Y-%m-%d %H:%M:%S')) +#=======================================# +# Convert date DD/MM/YYYY to YYYY-MM-DD # +#---------------------------------------# +def set_en_date(date): + if domain_lang.lower() == 'fr': + udate = date.rsplit('/') + return('%s-%s-%s'%(udate[2], udate[1], udate[0])) + + #=======================# # Check if article file # # Check if article DB # diff --git a/src/var/lib/tyto/program/wip.py b/src/var/lib/tyto/program/wip.py index 55aab43..8d1e3db 100644 --- a/src/var/lib/tyto/program/wip.py +++ b/src/var/lib/tyto/program/wip.py @@ -17,7 +17,7 @@ #********************************************************************** import os, re -import tyto +import tyto, html def manage_wip(target, option): # target needed @@ -89,6 +89,12 @@ def wip_article(target): # Result (temp display) print(article_bottom) + + # Get article DB in html.py + html.set_page(tyto.post_db) + print(html.main_page) + + # Replace in DB hash_wip and date_wip tyto.replace_in_db(tyto.post_db, 'wip', tyto.hash_post) From 87c79b803dbf4a8869d5faa5ae46075f06cdebde Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Thu, 5 Jan 2023 17:59:09 +0100 Subject: [PATCH 115/247] form: added profile question for rel='me'. HTML: added link to metas --- src/var/lib/tyto/program/domain.py | 19 +++++++++++++++++-- src/var/lib/tyto/program/html.py | 16 +++++++++++----- 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/src/var/lib/tyto/program/domain.py b/src/var/lib/tyto/program/domain.py index 8fd3ef8..812d469 100644 --- a/src/var/lib/tyto/program/domain.py +++ b/src/var/lib/tyto/program/domain.py @@ -213,8 +213,8 @@ def create_domain(target, option): 'domain_license = "%s"'%domain_license) - # Get License URL - #---------------- + # Get License URL (optionnal) + #---------------------------- try: domain_licurl = tyto.domain_licurl except: domain_licurl = '' @@ -258,6 +258,21 @@ def create_domain(target, option): 'domain_sep = "%s"'%domain_sep) + # Profile for rel="me" (optionnal) + #--------------------------------- + try: domain_relme = tyto.domain_relme + except: domain_relme = '' + + ask = '' + ask = input(' ├ Optional. Profile URL ? ("%s") '%domain_relme) + if ask: + if not ask.startswith('http'): tyto.exiting("3", ask, True) + domain_relme = ask + + tyto.set_file(tyto.domain_conf, False, + 'domain_relme = "%s"'%domain_relme) + + # Sidebar Title #-------------- try: sidebar_title = tyto.sidebar_title diff --git a/src/var/lib/tyto/program/html.py b/src/var/lib/tyto/program/html.py index 56c1311..2c730bc 100644 --- a/src/var/lib/tyto/program/html.py +++ b/src/var/lib/tyto/program/html.py @@ -55,13 +55,18 @@ def create_metas_page(): css_ref = 'media="screen" href="%s%s" />'%(sub_uri, css_file) rss_file = 'rss.xml' rss_ref = 'type="application/rss+xml" ' + \ - 'href="%s%s" title="RSS 2.0. %s %s %s'%( - sub_uri, rss_file, domain_title, domain_sep, domain_short - ) + 'href="%s%s" title="RSS 2.0. %s %s %s'%( + sub_uri, rss_file, domain_title, domain_sep, domain_short + ) icon_file = 'favicon.png' icon_ref = 'type="image/png" href="%s%s"'%(sub_uri, icon_file) en_date = tyto.set_en_date(date[0]) - + relme = '' # External URL in metas (if exists in config domain) + if domain_relme: + relme = '\n'%( + domain_relme + ) + # Set all raw HTML metas #----------------------- @@ -82,7 +87,8 @@ def create_metas_page(): '\n'%post_url + \ '\n'%(rss_ref) + \ '\n'%icon_ref + ''%icon_ref + \ + '%s'%relme # Create HTML tabulation for metas From aa99f32c46c19d1894318706426a11d821f6ee3e Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Fri, 6 Jan 2023 10:09:55 +0100 Subject: [PATCH 116/247] HTML: tags. Add content of wip/template/metas.html (if exists) --- src/var/lib/tyto/program/html.py | 26 ++++++++++++++++++++++---- src/var/lib/tyto/program/tyto.py | 1 + 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/var/lib/tyto/program/html.py b/src/var/lib/tyto/program/html.py index 2c730bc..7913020 100644 --- a/src/var/lib/tyto/program/html.py +++ b/src/var/lib/tyto/program/html.py @@ -16,7 +16,7 @@ #---------------------------------------------------------------------- #********************************************************************** - +import os import tyto # Load domain configuration DB @@ -26,6 +26,7 @@ Tyto = 'Tyto - Littérateur' tytogit = 'https://git.a-lec.org/echolib/tyto-litterateur' tytoweb = 'https://tyto.echolib.re' + #==========================# # Load article DB # # Start HTML page sections # @@ -66,12 +67,27 @@ def create_metas_page(): relme = '\n'%( domain_relme ) - + + # Check for user metas from wip template/metas.html + #-------------------------------------------------- + metas_file = '%smetas.html'%srv_wip_tpl + user_metas = '' + try: + user_file = open(metas_file, 'r').read() + tyto.exiting("25", 'metas from: %s'%metas_file, False) + for line in user_file.rsplit('\n'): + if line.startswith('\n'%scale + \ + '\n'%domain_url + \ '\n' + \ '\n' + \ '\n'%visit + \ @@ -88,7 +104,9 @@ def create_metas_page(): '\n'%(rss_ref) + \ ''%icon_ref + \ - '%s'%relme + '%s'%relme + \ + user_metas + \ + '%s'%title # Create HTML tabulation for metas diff --git a/src/var/lib/tyto/program/tyto.py b/src/var/lib/tyto/program/tyto.py index ea83501..c47f6c7 100644 --- a/src/var/lib/tyto/program/tyto.py +++ b/src/var/lib/tyto/program/tyto.py @@ -504,6 +504,7 @@ def exiting(nbr, value, out): '22' : ':? %sNot paired%s symbols: %s'%(CY, CS, value), '23' : ':? %sCorrupted database%s: %s'%(CY, CS, value), '24' : ':? %sfile missing%s (wip article): %s'%(CY, CS, value), + '25' : ':D Add contents %s'%value, '255' : ':| Maybe later...' } From 173eb7027fe47eb357f2337f09b0360d6adff5d8 Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Fri, 6 Jan 2023 15:16:33 +0100 Subject: [PATCH 117/247] HTML: set customizable metas.html from form --- src/var/lib/tyto/program/domain.py | 63 ++++++++++++++++++++++++++---- src/var/lib/tyto/program/html.py | 14 +++---- src/var/lib/tyto/program/tyto.py | 2 +- src/var/lib/tyto/program/wip.py | 2 +- 4 files changed, 64 insertions(+), 17 deletions(-) diff --git a/src/var/lib/tyto/program/domain.py b/src/var/lib/tyto/program/domain.py index 812d469..042d6d6 100644 --- a/src/var/lib/tyto/program/domain.py +++ b/src/var/lib/tyto/program/domain.py @@ -356,15 +356,11 @@ def create_domain(target, option): # Activate Domain #---------------- - tyto.set_file(tyto.domain_conf, False, - '\ndomain_active = True') + tyto.set_file(tyto.domain_conf, False, '\ndomain_active = True') # Load config exec(open(tyto.domain_conf).read(),globals()) - - # Create sidebar - create_sidebar(option, sidebar_dir) - + # Create folders from configuration file folders = ( srv_wip_tpl, srv_wip_images, srv_wip_files, @@ -380,12 +376,64 @@ def create_domain(target, option): if not os.makedirs(folder, exist_ok=True): print(' │ Exists directory: %s'%folder) + # Create tyto.sidebar and metas.html + print(' │') + create_sidebar(option, sidebar_dir) + create_metas_file(srv_wip_tpl) + print(' │') print(' ├──────────────────────────────────────┐') print(' │ Domain is ready. Have fun, writers ! │') print(' └──────────────────────────────────────┘') +#========================================# +# Create metas.html with default content # +#----------------------------------------# +def create_metas_file(srv_wip_tpl): + metas_file = '%smetas.html'%srv_wip_tpl + if os.path.exists(metas_file): + ask = '' + ask = input(' ├ Initialize default metas.html ? ') + if not ask in ['y', 'Y']: + return + + metas_tags = '# Custom metas\n' + \ + '# You can add HTML meta tags or edit them\n' + \ + '# As Tyto makes static pages,\n' + \ + '# for any changes, you will have to commands:\n' + \ + '# "tyto wip again" and "tyto publish again"\n' + \ + '# to apply new changes to your live articles.\n' + \ + '# ! Only and lines are used !\n' + \ + '\n' + \ + '# Already set metas with values:\n' + \ + '# \n' + \ + '# \n' + \ + '# \n' + \ + '# \n' + \ + '# \n' + \ + '# \n' + \ + '# \n' + \ + '# \n' + \ + '# \n' + \ + '# \n' + \ + '# \n' + \ + '# \n' + \ + '# \n' + \ + '# # RSS\n' + \ + '# \n' + \ + '# \n' + \ + '# # if profile url in config\n' + \ + '\n' + \ + '\n' + \ + '\n' + \ + '' + + tyto.set_file(metas_file, True, metas_tags) + print(' ├ Create file: %s'%metas_file) + print(' │ ! Check this file, before starting !') + + #==============================# # sidebar load file translated # #------------------------------# @@ -431,5 +479,4 @@ def create_sidebar(opt, sidebar_dir): return tyto.set_file(sidebar_load, 'new', sdb_load) - - print(' ├ Create new file: %s'%sidebar_load) + print(' ├ Create file: %s'%sidebar_load) diff --git a/src/var/lib/tyto/program/html.py b/src/var/lib/tyto/program/html.py index 7913020..a35f2be 100644 --- a/src/var/lib/tyto/program/html.py +++ b/src/var/lib/tyto/program/html.py @@ -49,7 +49,6 @@ def create_metas_page(): metas_page = '' tab = 4 scale = 'width=device-width, initial-scale=1.0' - visit = '3 days' all_tags = domain_tags + ',' + tags post_url = domain_url + http_uri css_file = 'template/style.css' @@ -72,25 +71,26 @@ def create_metas_page(): #-------------------------------------------------- metas_file = '%smetas.html'%srv_wip_tpl user_metas = '' + metas_used = ('\n'%scale + \ '\n'%domain_url + \ - '\n' + \ - '\n' + \ - '\n'%visit + \ '\n'%domain_lang + \ '\n'%domain_mail + \ '\n'%domain_license + \ diff --git a/src/var/lib/tyto/program/tyto.py b/src/var/lib/tyto/program/tyto.py index c47f6c7..ad41223 100644 --- a/src/var/lib/tyto/program/tyto.py +++ b/src/var/lib/tyto/program/tyto.py @@ -503,7 +503,7 @@ def exiting(nbr, value, out): '21' : ':D %sValid%s article. Ready to wip'%(CG, CS), '22' : ':? %sNot paired%s symbols: %s'%(CY, CS, value), '23' : ':? %sCorrupted database%s: %s'%(CY, CS, value), - '24' : ':? %sfile missing%s (wip article): %s'%(CY, CS, value), + '24' : ':? %sfile missing%s %s'%(CY, CS, value), '25' : ':D Add contents %s'%value, '255' : ':| Maybe later...' } diff --git a/src/var/lib/tyto/program/wip.py b/src/var/lib/tyto/program/wip.py index 8d1e3db..772e23c 100644 --- a/src/var/lib/tyto/program/wip.py +++ b/src/var/lib/tyto/program/wip.py @@ -45,7 +45,7 @@ def manage_wip(target, option): wip_article(target) else: if not os.path.exists(wip_uri): - tyto.exiting("24", wip_uri, False) + tyto.exiting("24", '(wip article): %s'%wip_uri, False) wip_article(target) else: tyto.exiting("20", date_wip, True) From d008f6e78fc856842f8916e98de774f23322663c Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Fri, 6 Jan 2023 16:27:46 +0100 Subject: [PATCH 118/247] wip: added option 'again' to wip all already wip articles (indev) --- src/usr/bin/tyto | 15 ++++++------- src/var/lib/tyto/program/tyto.py | 3 ++- src/var/lib/tyto/program/wip.py | 36 ++++++++++++++++++++++++++++---- 3 files changed, 42 insertions(+), 12 deletions(-) diff --git a/src/usr/bin/tyto b/src/usr/bin/tyto index 8d97ea0..7479021 100755 --- a/src/usr/bin/tyto +++ b/src/usr/bin/tyto @@ -50,13 +50,14 @@ actions = { # Dict for Options options = { - '-a' : 'Add', 'add' : 'Add', - '-R' : "Remove", 'remove' : "Remove", - '-n' : "New", 'new' : "New", - '-e' : "Edit", 'edit' : "Edit", - '-F' : "Force", 'force' : "Force", - '-s' : "Show", - '-d' : 'DB' + '-a' : 'Add', 'add' : 'Add', + '-R' : "Remove", 'remove' : "Remove", + '-n' : "New", 'new' : "New", + '-e' : "Edit", 'edit' : "Edit", + '-F' : "Force", 'force' : "Force", + '-s' : "Show", + '-d' : 'DB', + 'again': 'Again' } # Set Argument 2 or 3 diff --git a/src/var/lib/tyto/program/tyto.py b/src/var/lib/tyto/program/tyto.py index ad41223..c155ffd 100644 --- a/src/var/lib/tyto/program/tyto.py +++ b/src/var/lib/tyto/program/tyto.py @@ -28,7 +28,8 @@ arguments = ( '-e', 'edit', '-n', 'new', '-F', 'force', - '-d' + '-d', + 'again' ) # Settings diff --git a/src/var/lib/tyto/program/wip.py b/src/var/lib/tyto/program/wip.py index 772e23c..3cbea08 100644 --- a/src/var/lib/tyto/program/wip.py +++ b/src/var/lib/tyto/program/wip.py @@ -20,6 +20,32 @@ import os, re import tyto, html def manage_wip(target, option): + global post_db, hash_post + + #----------------------------------------- + # Option 'Again' to wip again, based on DB + #----------------------------------------- + if option == 'Again': + ask = '' + ask = input(":? wip again all already converted articles ? ") + if not ask in ['y', 'Y']: + return + + # Load domain configuration DB + exec(open(tyto.domain_conf).read(),globals()) + for post_db in os.listdir(domain_db): + if post_db.endswith('.conf'): + # Load DB + post_db = '%s%s'%(domain_db, post_db) + exec(open(post_db).read(),globals()) + print("->", root_uri) + hash_post = tyto.get_filesum(post_db, True) # From content file + wip_article(root_uri) + return + + #------------------------ + # Per article with target + #------------------------ # target needed if not target: tyto.exiting("5", '', True) @@ -30,10 +56,12 @@ def manage_wip(target, option): tyto.exiting("4", '', True) # Load DB - exec(open(tyto.post_db).read(),globals()) + post_db = tyto.post_db + hash_post = tyto.hash_post + exec(open(post_db).read(),globals()) # Exit if article has changed - if hash_chk != tyto.hash_post: tyto.exiting("9", '', True) + if hash_chk != hash_post: tyto.exiting("9", '', True) # In any case, if Force if option == 'Force': @@ -91,11 +119,11 @@ def wip_article(target): print(article_bottom) # Get article DB in html.py - html.set_page(tyto.post_db) + html.set_page(post_db) print(html.main_page) # Replace in DB hash_wip and date_wip - tyto.replace_in_db(tyto.post_db, 'wip', tyto.hash_post) + tyto.replace_in_db(post_db, 'wip', hash_post) #=================================# From 2743cc8c5579e5977f677ab3f9c26f61e52a54d9 Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Fri, 6 Jan 2023 16:37:09 +0100 Subject: [PATCH 119/247] wip: 'again'. Fix hash_wip from root_uri + check if hash_wip in DB --- src/var/lib/tyto/program/wip.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/var/lib/tyto/program/wip.py b/src/var/lib/tyto/program/wip.py index 3cbea08..99f249e 100644 --- a/src/var/lib/tyto/program/wip.py +++ b/src/var/lib/tyto/program/wip.py @@ -38,8 +38,10 @@ def manage_wip(target, option): # Load DB post_db = '%s%s'%(domain_db, post_db) exec(open(post_db).read(),globals()) + if not hash_wip: continue + print("->", root_uri) - hash_post = tyto.get_filesum(post_db, True) # From content file + hash_post = tyto.get_filesum(root_uri, True) # From content file wip_article(root_uri) return From aef44c86efd908e162840c75dcb3fdd26cead215 Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Tue, 10 Jan 2023 10:06:58 +0100 Subject: [PATCH 120/247] html: indev for navbar. Include article in page. domain: add logo, navbar in form --- src/var/lib/tyto/program/check.py | 3 +- src/var/lib/tyto/program/domain.py | 26 ++++++++ src/var/lib/tyto/program/html.py | 96 ++++++++++++++++++++++++++++-- src/var/lib/tyto/program/tyto.py | 5 +- src/var/lib/tyto/program/wip.py | 6 +- 5 files changed, 124 insertions(+), 12 deletions(-) diff --git a/src/var/lib/tyto/program/check.py b/src/var/lib/tyto/program/check.py index 453d021..fb277f4 100644 --- a/src/var/lib/tyto/program/check.py +++ b/src/var/lib/tyto/program/check.py @@ -94,9 +94,10 @@ def manage_check(target, option): post_bottom = tyto.protect_article.rsplit('\n') article_bottom = tyto.protect_article - # Count words in article. Not from quotes, block-codes, icode = 1 + # Count words in article. Quotes, block-codes, icode = 1 per each post_words = len(article_bottom.strip().split(" ")) + # Check for valid contents check_content(post_bottom) post_bottom = article_bottom.rsplit('\n') diff --git a/src/var/lib/tyto/program/domain.py b/src/var/lib/tyto/program/domain.py index 042d6d6..2ca6db6 100644 --- a/src/var/lib/tyto/program/domain.py +++ b/src/var/lib/tyto/program/domain.py @@ -197,6 +197,17 @@ def create_domain(target, option): 'domain_tags = "%s"'%domain_tags) + # Get logo's website + #------------------- + try: domain_logo = tyto.domain_logo + except: domain_logo = 'logo.png' + + ask = '' + ask = input(' ├ logo filename ? ("%s") '%domain_logo) + tyto.set_file(tyto.domain_conf, False, + 'domain_logo = "%s"'%domain_logo) + + # Get License domain #------------------- try: domain_license = tyto.domain_license @@ -272,7 +283,22 @@ def create_domain(target, option): tyto.set_file(tyto.domain_conf, False, 'domain_relme = "%s"'%domain_relme) + + # Activate menu bar from root articles folders ? + #----------------------------------------------- + try: domain_menubar = tyto.domain_menubar + except: domain_menubar = 'False' + ask = '' + ask = input(' ├ Use sub-folders as menu bar ? (%s) '%domain_menubar) + + if ask in ['y', 'Y']: domain_menubar = "True" + else: domain_menubar = 'False' + + tyto.set_file(tyto.domain_conf, False, + 'domain_menubar = %s'%(domain_menubar)) + + # Sidebar Title #-------------- try: sidebar_title = tyto.sidebar_title diff --git a/src/var/lib/tyto/program/html.py b/src/var/lib/tyto/program/html.py index a35f2be..c869dd6 100644 --- a/src/var/lib/tyto/program/html.py +++ b/src/var/lib/tyto/program/html.py @@ -31,11 +31,11 @@ tytoweb = 'https://tyto.echolib.re' # Load article DB # # Start HTML page sections # #--------------------------# -def set_page(post_db): +def set_page(post_db, target, article_bottom): exec(open(post_db).read(),globals()) - create_metas_page() # Include metas tags - create_main_page() # At last, create main page + create_metas_page() # Include metas tags + create_main_page(target, article_bottom) # At last, create main page #============================================# @@ -119,15 +119,99 @@ def create_metas_page(): #=======================================# # Set main page, with all HTML sections # #---------------------------------------# -def create_main_page(): +def create_main_page(target, article_bottom): global main_page - main_page = '\n' + \ + # Create link for website's logo + #------------------------------- + logo_html = '\n'%(11 * " ") + \ + '%s\n'%(15 * " ", domain_title) + \ + '%sid="site_logo_image">\n'%(15 * " ") + \ + '%s'%(8 * " ") + + #------------------------------------# + # Create HTML menu from root folders # + #------------------------------------# + menu_html = '' + + # Conditions to create navbar + #---------------------------- + # True in config + if domain_menubar: + # Filter these directories + nodirs = ('files', 'images', 'sidebar') + + # Open HTML tags + menu_html = '%s\n'%(menu_html, 8 * ' ', 6 * ' ') + + + #-----------------------# + # Create main HTML Page # + #-----------------------# + main_page = '\n' + \ '\n'%domain_lang + \ ' \n' + \ '%s\n'%metas_page + \ ' \n\n' + \ ' \n' + \ - '%s\n' + \ + '
    \n' + \ + ' \n' + \ + '\n' + \ + '
    \n' + \ + ' \n' + \ + '

    %s

    \n'%domain_title + \ + '
    \n' + \ + '

    %s

    \n'%domain_about + \ + '
    \n' + \ + '%s'%menu_html + \ + '
    \n' + \ + '\n' + \ + '
    \n' + \ + '%s\n'%article_bottom + \ + '
    \n' + \ + '\n' + \ ' \n' + \ '' diff --git a/src/var/lib/tyto/program/tyto.py b/src/var/lib/tyto/program/tyto.py index c155ffd..0e5b541 100644 --- a/src/var/lib/tyto/program/tyto.py +++ b/src/var/lib/tyto/program/tyto.py @@ -90,8 +90,9 @@ else: n = 1 # Translations French/English trans = [ - ['À l\'affiche !', 'Featured !' ] - ] +['À l\'affiche !', 'Featured !' ], #0 +['Accueil', 'Home'] #1 +] # Set all tags used in article's header diff --git a/src/var/lib/tyto/program/wip.py b/src/var/lib/tyto/program/wip.py index 99f249e..e34ea93 100644 --- a/src/var/lib/tyto/program/wip.py +++ b/src/var/lib/tyto/program/wip.py @@ -118,10 +118,10 @@ def wip_article(target): wip_tabs() # make HTML tabulations # Result (temp display) - print(article_bottom) + #print(article_bottom) # Get article DB in html.py - html.set_page(post_db) + html.set_page(post_db, target, article_bottom) print(html.main_page) # Replace in DB hash_wip and date_wip @@ -629,7 +629,7 @@ def wip_raws(target): def wip_tabs(): global article_bottom article_temp = '' - tab = tab_start = 8 # From
    tag + tab = tab_start = 2 # From
    tag indiv = False for line in article_bottom.rsplit('\n'): From 2db9fa9af81e24b2092a1af2526c37cbfc580e18 Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Tue, 10 Jan 2023 18:25:27 +0100 Subject: [PATCH 121/247] new navbar manager from file tyto.navbar. Form: question to use sidebar --- src/usr/bin/tyto | 13 +- src/var/lib/tyto/program/check.py | 1 + src/var/lib/tyto/program/domain.py | 153 ++++++++++++++---- src/var/lib/tyto/program/html.py | 70 ++++---- .../tyto/program/{sidebar.py => navbars.py} | 24 ++- src/var/lib/tyto/program/wip.py | 1 + 6 files changed, 179 insertions(+), 83 deletions(-) rename src/var/lib/tyto/program/{sidebar.py => navbars.py} (65%) diff --git a/src/usr/bin/tyto b/src/usr/bin/tyto index 7479021..4cf951e 100755 --- a/src/usr/bin/tyto +++ b/src/usr/bin/tyto @@ -26,7 +26,7 @@ import sys sys.path.insert(0, '/var/lib/tyto/program') -import check, domain, wip, sidebar +import check, domain, wip, navbars #====================# # MAIN # @@ -42,11 +42,12 @@ option = '' # Command start argument actions = { - 'check' : check.manage_check, - 'wip' : wip.manage_wip, - 'domain' : domain.manage_domain, - 'sidebar' : sidebar.manage_sidebar - } + 'check' : check.manage_check, + 'wip' : wip.manage_wip, + 'domain' : domain.manage_domain, + 'sidebar' : navbars.manage_navbars, + 'navbar' : navbars.manage_navbars + } # Dict for Options options = { diff --git a/src/var/lib/tyto/program/check.py b/src/var/lib/tyto/program/check.py index fb277f4..26fbc82 100644 --- a/src/var/lib/tyto/program/check.py +++ b/src/var/lib/tyto/program/check.py @@ -22,6 +22,7 @@ import sys, os, re, datetime from datetime import datetime from time import gmtime, strftime import time + import tyto # Load domain configuration if exists diff --git a/src/var/lib/tyto/program/domain.py b/src/var/lib/tyto/program/domain.py index 2ca6db6..3037dd1 100644 --- a/src/var/lib/tyto/program/domain.py +++ b/src/var/lib/tyto/program/domain.py @@ -18,6 +18,7 @@ #********************************************************************** import os, locale + import tyto #==========================# @@ -106,12 +107,16 @@ def create_domain(target, option): db_dir = '%s/.local/tyto/%s/'%(tyto.home_dir, domain_short) + navbars_conf= '%sarticles/navbars/'%tyto.conf_dir conf_domain = 'domain_dir = "%s"\n'%tyto.conf_dir + \ 'domain_conf = "%s"\n'%tyto.domain_conf + \ 'domain_articles = "%sarticles/"\n'%tyto.conf_dir + \ 'domain_files = "%sarticles/files/"\n'%tyto.conf_dir + \ 'domain_images = "%sarticles/images/"\n'%tyto.conf_dir + \ 'domain_db = "%sarticles/"\n'%(db_dir) + \ + 'navbars_dir = "%s"\n'%navbars_conf + \ + 'navbar_load = "%styto.navbar"\n'%navbars_conf + \ + 'sidebar_load = "%styto.sidebar"\n'%navbars_conf + \ '\ndomain_short = "%s"\n'%domain_short + \ 'domain_url = "%s"\n'%domain_url + \ 'domain_wipurl = "%s"\n'%domain_wipurl @@ -284,53 +289,72 @@ def create_domain(target, option): 'domain_relme = "%s"'%domain_relme) - # Activate menu bar from root articles folders ? - #----------------------------------------------- + # Activate menu bar from tyto.navbar ? + #------------------------------------- try: domain_menubar = tyto.domain_menubar except: domain_menubar = 'False' ask = '' - ask = input(' ├ Use sub-folders as menu bar ? (%s) '%domain_menubar) + ask = input(' ├ Create menu bar from tyto.navbar file ? (%s) '%( + domain_menubar + ) + ) - if ask in ['y', 'Y']: domain_menubar = "True" - else: domain_menubar = 'False' + if ask in ['y', 'Y']: domain_menubar = 'True' + else: domain_menubar = domain_menubar tyto.set_file(tyto.domain_conf, False, 'domain_menubar = %s'%(domain_menubar)) + # Activate side bar from tyto.sidebar ? + #-------------------------------------- + try: domain_sidebar = tyto.domain_sidebar + except: domain_sidebar = 'False' + + ask = '' + ask = input(' ├ Create article\'s list from tyto.sidebar file ? (%s) '%( + domain_sidebar + ) + ) + + if ask in ['y', 'Y']: domain_sidebar = 'True' + else: domain_sidebar = domain_sidebar + + tyto.set_file(tyto.domain_conf, False, + 'domain_sidebar = %s'%(domain_sidebar)) + + # Sidebar Title #-------------- try: sidebar_title = tyto.sidebar_title except: sidebar_title = tyto.trans[0][tyto.n] - ask = '' - ask = input(' ├ Sidebar title ? ("%s") '%sidebar_title) - if ask: sidebar_title = ask - if '"' in sidebar_title: - sidebar_title = sidebar_title.replace('"', '') - - sidebar_conf = '%sarticles/sidebar/'%tyto.conf_dir - sidebar_datas = '\nsidebar_dir = "%s"\n'%sidebar_conf + \ - 'sidebar_load = "%styto.sidebar"\n'%sidebar_conf + \ - 'sidebar_title = "%s"'%sidebar_title - - tyto.set_file(tyto.domain_conf, False, sidebar_datas) - + if domain_sidebar: + ask = '' + ask = input(' ├ Sidebar title ? ("%s") '%sidebar_title) + if ask: sidebar_title = ask + if '"' in sidebar_title: + sidebar_title = sidebar_title.replace('"', '') + + tyto.set_file(tyto.domain_conf, False, + 'sidebar_title = "%s"'%(sidebar_title)) + # Sidebar Items #-------------- try: sidebar_items = tyto.sidebar_items except: sidebar_items = "6" - ask = '' - ask = input(' ├ [max=16] Sidebar Items ? ("%s") '%sidebar_items) - if ask: - if not ask.isdigit(): tyto.exiting("3", ask, True) - elif int(ask) in range(1,17): sidebar_items = int(ask) + if domain_sidebar: + ask = '' + ask = input(' ├ [max=16] Sidebar Items ? ("%s") '%sidebar_items) + if ask: + if not ask.isdigit(): tyto.exiting("3", ask, True) + elif int(ask) in range(1,17): sidebar_items = int(ask) tyto.set_file(tyto.domain_conf, False, - 'sidebar_items = "%s"'%int(sidebar_items)) + 'sidebar_items = %s'%(sidebar_items)) # Get srv root @@ -391,7 +415,7 @@ def create_domain(target, option): folders = ( srv_wip_tpl, srv_wip_images, srv_wip_files, srv_www_tpl, srv_www_images, srv_www_files, - domain_files, domain_images, sidebar_dir, + domain_files, domain_images, navbars_dir, domain_db, ) @@ -404,7 +428,8 @@ def create_domain(target, option): # Create tyto.sidebar and metas.html print(' │') - create_sidebar(option, sidebar_dir) + create_sidebar(option, navbars_dir) + create_navbar(option, navbars_dir) create_metas_file(srv_wip_tpl) print(' │') @@ -463,16 +488,18 @@ def create_metas_file(srv_wip_tpl): #==============================# # sidebar load file translated # #------------------------------# -def create_sidebar(opt, sidebar_dir): +def create_sidebar(opt, navbars_dir): try: sidebar_load - except: sidebar_load = "%styto.sidebar"%sidebar_dir + except: sidebar_load = "%styto.sidebar"%navbars_dir sdb_load_fr = '# Pour : Tyto - Littérateur\n' + \ '# Type : fichier texte\n' + \ - '# Description : Fichier appelé par : tyto sidebar\n' + \ + '# Description : Fichier appelé par "tyto sidebar"\n' + \ + '# (Liste d\'articles)\n' + \ '# Fichier : tyto.sidebar\n' + \ - '# Dossier : %s\n'%sidebar_dir + \ + '# Dossier : %s\n'%navbars_dir + \ '# Comment : 1 URI de l\'article par ligne\n' + \ + '# (depuis articles/)\n' + \ '# Ne commence pas par "/"\n' + \ '# L\'ordre définit la position\n' + \ '\n# %s\n'%(15 * "-") +\ @@ -483,10 +510,12 @@ def create_sidebar(opt, sidebar_dir): sdb_load_en = '# For: Tyto - Littérateur\n' + \ '# Type: Text file\n' + \ - '# Description: file called with: tyto sidebar\n' + \ + '# Description: file called with "tyto sidebar"\n' + \ + '# (articles\'s list)\n' + \ '# File: tyto.sidebar\n' + \ - '# Directory: %s\n'%sidebar_dir + \ + '# Directory: %s\n'%navbars_dir + \ '# Comment: 1 article URI per line\n' + \ + '# (from articles/)\n' + \ '# not begining with "/"\n' + \ '# Order in sidebar position\n' + \ '\n# %s\n'%(15 * "-") +\ @@ -506,3 +535,63 @@ def create_sidebar(opt, sidebar_dir): tyto.set_file(sidebar_load, 'new', sdb_load) print(' ├ Create file: %s'%sidebar_load) + + +#=============================# +# navbar load file translated # +#-----------------------------# +def create_navbar(opt, navbars_dir): + try: navbar_load + except: navbar_load = "%styto.navbar"%navbars_dir + + nav_load_fr = '# Pour : Tyto - Littérateur\n' + \ + '# Type : fichier texte\n' + \ + '# Description : Fichier utilisé par "tyto wip"\n' + \ + '# (Liste des catégories)\n' + \ + '# Fichier : tyto.navbar\n' + \ + '# Dossier : %s\n'%navbars_dir + \ + '# Comment : 1 nom de dossier par ligne\n' + \ + '# (depuis articles/)\n' + \ + '# Ne commence pas par "/"\n' + \ + '# L\'ordre définit la position\n' + \ + '# Note: Pour éviter l\'erreur 404 :\n' + \ + '# - ajouter un article index.{ext}\n' + \ + '# dans le dossier mentionné\n' + \ + '# - utiliser check et wip dessus' + \ + '\n# %s\n'%(15 * "-") +\ + '# Exemples :\n' + \ + '# documentation\n' + \ + '# a-propos\n' + \ + '# %s\n\n'%(15 * "-") + + nav_load_en = '# For: Tyto - Littérateur\n' + \ + '# Type: Text file\n' + \ + '# Description: file used with "tyto wip"\n' + \ + '# (categories\'s list)\n' + \ + '# File: tyto.navbar\n' + \ + '# Directory: %s\n'%navbars_dir + \ + '# Comment: 1 folder name per line\n' + \ + '# (from articles/)\n' + \ + '# not begining with "/"\n' + \ + '# Order in sidebar position\n' + \ + '# Remember: To avoid 404 error, you must:\n' + \ + '# - add index.{ext} file article\n' + \ + '# in set folder\n' + \ + '# - check and wip it' + \ + '\n# %s\n'%(15 * "-") +\ + '# Examples :\n' + \ + '# documentation\n' + \ + '# about\n' + \ + '# %s\n\n'%(15 * "-") + + if tyto.n == 0: nav_load = nav_load_fr + elif tyto.n == 1: nav_load = nav_load_en + + if not opt == 'Remove' and os.path.exists(navbar_load): + ask = '' + ask = input(' ├ Initialize new navbar ? ') + if not ask in ['y', 'Y']: + return + + tyto.set_file(navbar_load, 'new', nav_load) + print(' ├ Create file: %s'%navbar_load) diff --git a/src/var/lib/tyto/program/html.py b/src/var/lib/tyto/program/html.py index c869dd6..2d8388e 100644 --- a/src/var/lib/tyto/program/html.py +++ b/src/var/lib/tyto/program/html.py @@ -17,6 +17,7 @@ #********************************************************************** import os + import tyto # Load domain configuration DB @@ -143,46 +144,39 @@ def create_main_page(target, article_bottom): #---------------------------- # True in config if domain_menubar: - # Filter these directories - nodirs = ('files', 'images', 'sidebar') + # Create folder links (from tyto.navbar) in navbar + try: + nav_file = open(navbar_load, 'r').read() + nav_bar = True + except: + tyto.exiting("1", '(navbar) %s'%navbar_load, False) + nav_bar = False - # Open HTML tags - menu_html = '%s\n'%(menu_html, 8 * ' ', 6 * ' ') + if nav_bar: + # Open HTML tags + menu_html = '%s\n'%(menu_html, 8 * ' ', 6 * ' ') + #-----------------------# # Create main HTML Page # diff --git a/src/var/lib/tyto/program/sidebar.py b/src/var/lib/tyto/program/navbars.py similarity index 65% rename from src/var/lib/tyto/program/sidebar.py rename to src/var/lib/tyto/program/navbars.py index 11808c1..02255f7 100644 --- a/src/var/lib/tyto/program/sidebar.py +++ b/src/var/lib/tyto/program/navbars.py @@ -17,6 +17,7 @@ #********************************************************************** import sys + import tyto # Load domain configuration if exists @@ -25,16 +26,25 @@ if tyto.domain_exists: exec(open(tyto.domain_conf).read()) #==============================# # Manage arguments for sidebar # #------------------------------# -def manage_sidebar(target, option): - # Initialize new sidebar +def manage_navbars(target, option): + import domain + actions = { + 'sidebar' : domain.create_sidebar, + 'navbar' : domain.create_navbar + } + + if sys.argv[1] == "sidebar": file = sidebar_load + elif sys.argv[1] == 'navbar': file = navbar_load + + # Initialize new file if not target: if option == "Remove": - import domain - domain.create_sidebar(opt, sidebar_dir) - if option == 'Edit': - print(":D Edit sidebar configuration file:", sidebar_load) - tyto.edit_file(sidebar_load) + actions[sys.argv[1]](opt, navbars_dir) + elif option == 'Edit': + print(":D Edit %s configuration file:"%sys.argv[1], file) + tyto.edit_file(file) else: db_exists = tyto.get_db_post(target) # Article exists + has DB ? if not db_exists: tyto.exiting("4", '') # Needs database + diff --git a/src/var/lib/tyto/program/wip.py b/src/var/lib/tyto/program/wip.py index e34ea93..4a9949e 100644 --- a/src/var/lib/tyto/program/wip.py +++ b/src/var/lib/tyto/program/wip.py @@ -17,6 +17,7 @@ #********************************************************************** import os, re + import tyto, html def manage_wip(target, option): From 4e21403e3dd19ba7e3b7fdfda88b56bb9e4f63da Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Wed, 11 Jan 2023 10:00:42 +0100 Subject: [PATCH 122/247] html: better navbar management. Use virtual nginx line from navbar.html --- src/var/lib/tyto/program/html.py | 112 +++++++++++++++++----------- src/var/lib/tyto/program/navbars.py | 5 +- src/var/lib/tyto/program/tyto.py | 3 + 3 files changed, 75 insertions(+), 45 deletions(-) diff --git a/src/var/lib/tyto/program/html.py b/src/var/lib/tyto/program/html.py index 2d8388e..1cbecac 100644 --- a/src/var/lib/tyto/program/html.py +++ b/src/var/lib/tyto/program/html.py @@ -21,12 +21,13 @@ import os import tyto # Load domain configuration DB -exec(open(tyto.domain_conf).read(),globals()) +exec(open(tyto.domain_conf).read()) Tyto = 'Tyto - Littérateur' tytogit = 'https://git.a-lec.org/echolib/tyto-litterateur' tytoweb = 'https://tyto.echolib.re' +navbar_file = '%snavbar.html'%srv_wip_tpl #==========================# # Load article DB # @@ -134,50 +135,21 @@ def create_main_page(target, article_bottom): '%salt="logo: %s">\n'%(15 * " ", domain_title) + \ '%sid="site_logo_image">\n'%(15 * " ") + \ '%s'%(8 * " ") - - #------------------------------------# - # Create HTML menu from root folders # - #------------------------------------# - menu_html = '' - - # Conditions to create navbar - #---------------------------- - # True in config - if domain_menubar: - # Create folder links (from tyto.navbar) in navbar - try: - nav_file = open(navbar_load, 'r').read() - nav_bar = True - except: - tyto.exiting("1", '(navbar) %s'%navbar_load, False) - nav_bar = False - - if nav_bar: - # Open HTML tags - menu_html = '%s\n'%(menu_html, 8 * ' ', 6 * ' ') + # Check for menu bar + # Delete file if deactivated in conf + if domain_menubar: + if os.path.exists(navbar_file): + tyto.exiting("25", 'menu from: %s'%navbar_file, False) + else: + tyto.exiting("24", '(menu file): %s'%navbar_file, False) + else: + if os.path.exists(navbar_file) and os.stat(navbar_file).st_size > 1: + tyto.set_file(navbar_file, 'new', '') + tyto.exiting("26", 'domain_menubar', False) + tyto.exiting('27', 'contents (menu file): %s'%navbar_file, False) + #-----------------------# # Create main HTML Page # #-----------------------# @@ -200,7 +172,7 @@ def create_main_page(target, article_bottom): ' \n' + \ '

    %s

    \n'%domain_about + \ '
    \n' + \ - '%s'%menu_html + \ + '' + \ ' \n' + \ '\n' + \ '
    \n' + \ @@ -209,3 +181,55 @@ def create_main_page(target, article_bottom): '\n' + \ ' \n' + \ '' + + +#====================================# +# Create HTML menu from root folders # +#------------------------------------# +def create_navbar(): + # Conditions to create navbar + if not domain_menubar: + tyto.set_file(navbar_file, 'new', '') + tyto.exiting("26", 'domain_menubar', False) + if os.path.exists(navbar_file) and os.stat(navbar_file).st_size > 1: + tyto.exiting('27', 'contents (menu file): %s'%navbar_file, False) + return + + # True in config + # Create folder links (from navbars/tyto.navbar) + try: nav_file = open(navbar_load, 'r').read() + except: tyto.exiting("1", '(navbar) %s'%navbar_load, True) + + # Open HTML tags + menu_html = '%s\n'%(menu_html, 8 * ' ', 6 * ' ') + tyto.set_file('%snavbar.html'%srv_wip_tpl, 'new', menu_html) diff --git a/src/var/lib/tyto/program/navbars.py b/src/var/lib/tyto/program/navbars.py index 02255f7..afc1ecf 100644 --- a/src/var/lib/tyto/program/navbars.py +++ b/src/var/lib/tyto/program/navbars.py @@ -18,7 +18,7 @@ #********************************************************************** import sys -import tyto +import tyto, html # Load domain configuration if exists if tyto.domain_exists: exec(open(tyto.domain_conf).read()) @@ -43,6 +43,9 @@ def manage_navbars(target, option): elif option == 'Edit': print(":D Edit %s configuration file:"%sys.argv[1], file) tyto.edit_file(file) + elif option == 'New': + html.create_navbar() + else: db_exists = tyto.get_db_post(target) # Article exists + has DB ? diff --git a/src/var/lib/tyto/program/tyto.py b/src/var/lib/tyto/program/tyto.py index 0e5b541..9dd88bb 100644 --- a/src/var/lib/tyto/program/tyto.py +++ b/src/var/lib/tyto/program/tyto.py @@ -507,6 +507,9 @@ def exiting(nbr, value, out): '23' : ':? %sCorrupted database%s: %s'%(CY, CS, value), '24' : ':? %sfile missing%s %s'%(CY, CS, value), '25' : ':D Add contents %s'%value, + '26' : ':? %sDeactivated%s "%s" in domain conf'%(CY, CS, value), + '27' : ':? %sDeleted%s %s'%(CY, CS, value), + '28' : ':? %sUnused directory%s: %s'%(CY, CS, value), '255' : ':| Maybe later...' } From 3b501b75feda1079edf6f5ff7dad218b3cefbb9f Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Wed, 11 Jan 2023 10:17:22 +0100 Subject: [PATCH 123/247] tyto.navbar: added more comments (how to create title) --- src/var/lib/tyto/program/domain.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/var/lib/tyto/program/domain.py b/src/var/lib/tyto/program/domain.py index 3037dd1..7e10a06 100644 --- a/src/var/lib/tyto/program/domain.py +++ b/src/var/lib/tyto/program/domain.py @@ -550,18 +550,20 @@ def create_navbar(opt, navbars_dir): '# (Liste des catégories)\n' + \ '# Fichier : tyto.navbar\n' + \ '# Dossier : %s\n'%navbars_dir + \ - '# Comment : 1 nom de dossier par ligne\n' + \ + '# Comment : 1 nom de dossier par ligne *1\n' + \ '# (depuis articles/)\n' + \ '# Ne commence pas par "/"\n' + \ '# L\'ordre définit la position\n' + \ '# Note: Pour éviter l\'erreur 404 :\n' + \ '# - ajouter un article index.{ext}\n' + \ '# dans le dossier mentionné\n' + \ - '# - utiliser check et wip dessus' + \ + '# - utiliser check et wip dessus\n' + \ + '# Option *1: Pour définir un titre de lien :\n' + \ + '# - ajouter "= titre de lien"\n' + \ '\n# %s\n'%(15 * "-") +\ '# Exemples :\n' + \ '# documentation\n' + \ - '# a-propos\n' + \ + '# a-propos = Informations concernant ce site\n' + \ '# %s\n\n'%(15 * "-") nav_load_en = '# For: Tyto - Littérateur\n' + \ @@ -570,18 +572,20 @@ def create_navbar(opt, navbars_dir): '# (categories\'s list)\n' + \ '# File: tyto.navbar\n' + \ '# Directory: %s\n'%navbars_dir + \ - '# Comment: 1 folder name per line\n' + \ + '# Comment: 1 folder name per line *1\n' + \ '# (from articles/)\n' + \ '# not begining with "/"\n' + \ '# Order in sidebar position\n' + \ '# Remember: To avoid 404 error, you must:\n' + \ '# - add index.{ext} file article\n' + \ '# in set folder\n' + \ - '# - check and wip it' + \ + '# - check and wip it\n' + \ + '# Option *1: To define a title link:' + \ + '# - add "= title link"\n' + \ '\n# %s\n'%(15 * "-") +\ '# Examples :\n' + \ '# documentation\n' + \ - '# about\n' + \ + '# about = infos about this website\n' + \ '# %s\n\n'%(15 * "-") if tyto.n == 0: nav_load = nav_load_fr From 73546b59661aac8c5d4eba4ab512275a462e6c76 Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Sat, 14 Jan 2023 22:18:13 +0100 Subject: [PATCH 124/247] indev: external html config file manage --- src/usr/bin/tyto | 8 +- src/var/lib/tyto/program/domain.py | 130 ++++++++------ src/var/lib/tyto/program/html.py | 264 ++++++++++++++++++++-------- src/var/lib/tyto/program/navbars.py | 3 +- src/var/lib/tyto/program/tyto.py | 6 +- src/var/lib/tyto/program/wip.py | 4 +- 6 files changed, 276 insertions(+), 139 deletions(-) diff --git a/src/usr/bin/tyto b/src/usr/bin/tyto index 4cf951e..819c3f8 100755 --- a/src/usr/bin/tyto +++ b/src/usr/bin/tyto @@ -26,7 +26,7 @@ import sys sys.path.insert(0, '/var/lib/tyto/program') -import check, domain, wip, navbars +import check, domain, wip, html #====================# # MAIN # @@ -45,8 +45,10 @@ actions = { 'check' : check.manage_check, 'wip' : wip.manage_wip, 'domain' : domain.manage_domain, - 'sidebar' : navbars.manage_navbars, - 'navbar' : navbars.manage_navbars + 'sidebar' : html.manage_configs, + 'navbar' : html.manage_configs, + 'metas' : html.manage_configs, + 'footer' : html.manage_configs } # Dict for Options diff --git a/src/var/lib/tyto/program/domain.py b/src/var/lib/tyto/program/domain.py index 7e10a06..30c80da 100644 --- a/src/var/lib/tyto/program/domain.py +++ b/src/var/lib/tyto/program/domain.py @@ -19,7 +19,7 @@ import os, locale -import tyto +import tyto, html #==========================# # Manage Argument 'domain' # @@ -107,16 +107,19 @@ def create_domain(target, option): db_dir = '%s/.local/tyto/%s/'%(tyto.home_dir, domain_short) - navbars_conf= '%sarticles/navbars/'%tyto.conf_dir + navbars_conf= '%sarticles/_configs/'%tyto.conf_dir conf_domain = 'domain_dir = "%s"\n'%tyto.conf_dir + \ 'domain_conf = "%s"\n'%tyto.domain_conf + \ 'domain_articles = "%sarticles/"\n'%tyto.conf_dir + \ 'domain_files = "%sarticles/files/"\n'%tyto.conf_dir + \ 'domain_images = "%sarticles/images/"\n'%tyto.conf_dir + \ 'domain_db = "%sarticles/"\n'%(db_dir) + \ + 'html_db = "%shtml/"\n'%(db_dir) + \ 'navbars_dir = "%s"\n'%navbars_conf + \ 'navbar_load = "%styto.navbar"\n'%navbars_conf + \ 'sidebar_load = "%styto.sidebar"\n'%navbars_conf + \ + 'metas_load = "%styto.metas.html"\n'%navbars_conf + \ + 'footer_load = "%styto.footer.html"\n'%navbars_conf + \ '\ndomain_short = "%s"\n'%domain_short + \ 'domain_url = "%s"\n'%domain_url + \ 'domain_wipurl = "%s"\n'%domain_wipurl @@ -416,7 +419,7 @@ def create_domain(target, option): srv_wip_tpl, srv_wip_images, srv_wip_files, srv_www_tpl, srv_www_images, srv_www_files, domain_files, domain_images, navbars_dir, - domain_db, + domain_db, html_db ) print(' │') @@ -428,9 +431,14 @@ def create_domain(target, option): # Create tyto.sidebar and metas.html print(' │') - create_sidebar(option, navbars_dir) - create_navbar(option, navbars_dir) - create_metas_file(srv_wip_tpl) + create_sidebar(option) + html.manage_configs('sidebar', '-n') + create_navbar(option) + html.manage_configs('navbar', '-n') + create_metas_file(option) + html.manage_configs('metas', '-n') + html.create_footer(option) + html.manage_configs('footer', '-n') print(' │') print(' ├──────────────────────────────────────┐') @@ -441,21 +449,13 @@ def create_domain(target, option): #========================================# # Create metas.html with default content # #----------------------------------------# -def create_metas_file(srv_wip_tpl): - metas_file = '%smetas.html'%srv_wip_tpl - if os.path.exists(metas_file): - ask = '' - ask = input(' ├ Initialize default metas.html ? ') - if not ask in ['y', 'Y']: - return - - metas_tags = '# Custom metas\n' + \ - '# You can add HTML meta tags or edit them\n' + \ - '# As Tyto makes static pages,\n' + \ - '# for any changes, you will have to commands:\n' + \ - '# "tyto wip again" and "tyto publish again"\n' + \ - '# to apply new changes to your live articles.\n' + \ +def create_metas_file(option): + metas_load = tyto.metas_load + metas_tags = '\n' + \ '\n' + \ '\n' + \ '' - - tyto.set_file(metas_file, True, metas_tags) - print(' ├ Create file: %s'%metas_file) - print(' │ ! Check this file, before starting !') + + + # Create new file, or ask if exists + ask = ' ├ Use default tyto.metas.html ? ' + log = ' ├ Create file: %s'%metas_load + + if os.path.exists(metas_load): + if option == '-i': return # Continue to create template/metas.html + res = input(ask) + if not res in ['y', 'Y']: return + + tyto.set_file(metas_load, 'new', metas_tags) + print(log) #==============================# # sidebar load file translated # #------------------------------# -def create_sidebar(opt, navbars_dir): - try: sidebar_load - except: sidebar_load = "%styto.sidebar"%navbars_dir - +def create_sidebar(option): + sidebar_load = tyto.sidebar_load sdb_load_fr = '# Pour : Tyto - Littérateur\n' + \ '# Type : fichier texte\n' + \ '# Description : Fichier appelé par "tyto sidebar"\n' + \ '# (Liste d\'articles)\n' + \ - '# Fichier : tyto.sidebar\n' + \ - '# Dossier : %s\n'%navbars_dir + \ + '# Fichier : %s\n'%sidebar_load + \ '# Comment : 1 URI de l\'article par ligne\n' + \ '# (depuis articles/)\n' + \ '# Ne commence pas par "/"\n' + \ @@ -512,8 +525,7 @@ def create_sidebar(opt, navbars_dir): '# Type: Text file\n' + \ '# Description: file called with "tyto sidebar"\n' + \ '# (articles\'s list)\n' + \ - '# File: tyto.sidebar\n' + \ - '# Directory: %s\n'%navbars_dir + \ + '# File: %s\n'%sidebar_load + \ '# Comment: 1 article URI per line\n' + \ '# (from articles/)\n' + \ '# not begining with "/"\n' + \ @@ -526,30 +538,31 @@ def create_sidebar(opt, navbars_dir): if tyto.n == 0: sdb_load = sdb_load_fr elif tyto.n == 1: sdb_load = sdb_load_en - - if not opt == 'Remove' and os.path.exists(sidebar_load): - ask = '' - ask = input(' ├ Initialize new sidebar ? ') - if not ask in ['y', 'Y']: - return + + ask = ' ├ Use default (empty) sidebar config ? ' + log = ' ├ Create file: %s'%sidebar_load + + # Create new file, or ask if exists + ask = ' ├ Use default (empty) sidebar config file ? ' + log = ' ├ Create file: %s'%sidebar_load + + if os.path.exists(sidebar_load): + res = input(ask) + if not res in ['y', 'Y']: return tyto.set_file(sidebar_load, 'new', sdb_load) - print(' ├ Create file: %s'%sidebar_load) + print(log) #=============================# # navbar load file translated # #-----------------------------# -def create_navbar(opt, navbars_dir): - try: navbar_load - except: navbar_load = "%styto.navbar"%navbars_dir - +def create_navbar(option): nav_load_fr = '# Pour : Tyto - Littérateur\n' + \ '# Type : fichier texte\n' + \ '# Description : Fichier utilisé par "tyto wip"\n' + \ '# (Liste des catégories)\n' + \ - '# Fichier : tyto.navbar\n' + \ - '# Dossier : %s\n'%navbars_dir + \ + '# Fichier : %s\n'%navbar_load + \ '# Comment : 1 nom de dossier par ligne *1\n' + \ '# (depuis articles/)\n' + \ '# Ne commence pas par "/"\n' + \ @@ -559,19 +572,18 @@ def create_navbar(opt, navbars_dir): '# dans le dossier mentionné\n' + \ '# - utiliser check et wip dessus\n' + \ '# Option *1: Pour définir un titre de lien :\n' + \ - '# - ajouter "= titre de lien"\n' + \ + '# - ajouter "# titre de lien"\n' + \ '\n# %s\n'%(15 * "-") +\ '# Exemples :\n' + \ '# documentation\n' + \ - '# a-propos = Informations concernant ce site\n' + \ + '# a-propos # Informations concernant ce site\n' + \ '# %s\n\n'%(15 * "-") nav_load_en = '# For: Tyto - Littérateur\n' + \ '# Type: Text file\n' + \ '# Description: file used with "tyto wip"\n' + \ '# (categories\'s list)\n' + \ - '# File: tyto.navbar\n' + \ - '# Directory: %s\n'%navbars_dir + \ + '# File : %s\n'%navbar_load + \ '# Comment: 1 folder name per line *1\n' + \ '# (from articles/)\n' + \ '# not begining with "/"\n' + \ @@ -581,21 +593,23 @@ def create_navbar(opt, navbars_dir): '# in set folder\n' + \ '# - check and wip it\n' + \ '# Option *1: To define a title link:' + \ - '# - add "= title link"\n' + \ + '# - add "# title link"\n' + \ '\n# %s\n'%(15 * "-") +\ '# Examples :\n' + \ '# documentation\n' + \ - '# about = infos about this website\n' + \ + '# about # infos about this website\n' + \ '# %s\n\n'%(15 * "-") if tyto.n == 0: nav_load = nav_load_fr elif tyto.n == 1: nav_load = nav_load_en - if not opt == 'Remove' and os.path.exists(navbar_load): - ask = '' - ask = input(' ├ Initialize new navbar ? ') - if not ask in ['y', 'Y']: - return + # Create new file, or ask if exists + ask = ' ├ Use default (empty) navbar config file ? ' + log = ' ├ Create file: %s'%navbar_load + + if os.path.exists(navbar_load): + res = input(ask) + if not res in ['y', 'Y']: return tyto.set_file(navbar_load, 'new', nav_load) - print(' ├ Create file: %s'%navbar_load) + print(log) diff --git a/src/var/lib/tyto/program/html.py b/src/var/lib/tyto/program/html.py index 1cbecac..f1a0414 100644 --- a/src/var/lib/tyto/program/html.py +++ b/src/var/lib/tyto/program/html.py @@ -16,19 +16,52 @@ #---------------------------------------------------------------------- #********************************************************************** -import os +import os, sys -import tyto +import tyto, domain, html # Load domain configuration DB exec(open(tyto.domain_conf).read()) Tyto = 'Tyto - Littérateur' -tytogit = 'https://git.a-lec.org/echolib/tyto-litterateur' -tytoweb = 'https://tyto.echolib.re' +Tytogit = 'https://git.a-lec.org/echolib/tyto-litterateur' +Tytogti = 'Dépôt officiel du code source de Tyto - Littérateur' +Tytoweb = 'https://tyto.echolib.re' +Tytowti = 'Site web officiel du logiciel Tyto - Littérateur' +Tytosrc = '(Code source)' navbar_file = '%snavbar.html'%srv_wip_tpl +# +# Manage fies for HTML +# (sidebar, metas, footer, navbar) +# +def manage_configs(target, option): + + args1 = ('metas', 'sidebar', 'footer', 'navbar') + args2 = ('-n', '-e', '-R') + opts = ('New', 'Edit', 'Remove') + + if target in args1: sys.argv[1] = target + elif target and not option: option = target + if not sys.argv[1] in args1: tyto.exiting('11', '%s'%str(args1), True) + if not option in opts and not option == '-i' and not option in args2: + tyto.exiting('11', '%s'%str(args2), True) + + # Getting default file + if option == 'New': + actions = { + 'sidebar' : domain.create_sidebar, + 'navbar' : domain.create_navbar, + 'metas' : create_user_metas, + 'footer' : html.create_footer + } + + actions[sys.argv[1]](option) + + #==========================# # Load article DB # # Start HTML page sections # @@ -49,7 +82,6 @@ def create_metas_page(): # Settings for metas #------------------- metas_page = '' - tab = 4 scale = 'width=device-width, initial-scale=1.0' all_tags = domain_tags + ',' + tags post_url = domain_url + http_uri @@ -61,62 +93,46 @@ def create_metas_page(): sub_uri, rss_file, domain_title, domain_sep, domain_short ) icon_file = 'favicon.png' - icon_ref = 'type="image/png" href="%s%s"'%(sub_uri, icon_file) + icon_ref = 'type="image/png" href="%stemplate/%s"'%(sub_uri, icon_file) en_date = tyto.set_en_date(date[0]) relme = '' # External URL in metas (if exists in config domain) if domain_relme: - relme = '\n'%( + relme = '\n '%( domain_relme ) - - # Check for user metas from wip template/metas.html - #-------------------------------------------------- - metas_file = '%smetas.html'%srv_wip_tpl - user_metas = '' - metas_used = ('\n'%scale + \ - '\n'%domain_url + \ - '\n'%domain_lang + \ - '\n'%domain_mail + \ - '\n'%domain_license + \ - '\n'%Tyto + \ - '\n'%title + \ - '\n'%author + \ - '\n'%about + \ - '\n'%all_tags + \ - '\n'%en_date + \ - '\n'%post_url + \ - '\n'%(rss_ref) + \ - ''%icon_ref + \ + global metas + metas = ' \n' + \ + ' \n'%scale + \ + ' \n'%domain_url + \ + ' \n'%domain_lang + \ + ' \n'%domain_mail + \ + ' \n'%domain_license + \ + ' \n'%Tyto + \ + ' \n'%title + \ + ' \n'%author + \ + ' \n'%about + \ + ' \n'%all_tags + \ + ' \n'%en_date + \ + ' \n'%post_url + \ + ' \n'%(rss_ref) + \ + ' '%icon_ref + \ + ' \n' + \ + ' \n'%domain_title + \ + ' \n'%title + \ + ' \n' + \ + ' \n'%post_url + \ + ' \n' + \ + ' \n' + \ '%s'%relme + \ - user_metas + \ - '%s'%title + '\n\n' + \ + ' %s'%title - # Create HTML tabulation for metas - #--------------------------------- - for line in metas.rsplit('\n'): - if metas_page: metas_page = '%s\n%s%s'%(metas_page, tab * ' ', line) - else: metas_page = '%s%s'%(tab * ' ', line) - #=======================================# # Set main page, with all HTML sections # @@ -136,27 +152,16 @@ def create_main_page(target, article_bottom): '%sid="site_logo_image">\n'%(15 * " ") + \ '%s'%(8 * " ") - # Check for menu bar - # Delete file if deactivated in conf - if domain_menubar: - if os.path.exists(navbar_file): - tyto.exiting("25", 'menu from: %s'%navbar_file, False) - else: - tyto.exiting("24", '(menu file): %s'%navbar_file, False) - else: - if os.path.exists(navbar_file) and os.stat(navbar_file).st_size > 1: - tyto.set_file(navbar_file, 'new', '') - tyto.exiting("26", 'domain_menubar', False) - tyto.exiting('27', 'contents (menu file): %s'%navbar_file, False) - + create_navbar('-n', navbars_dir) + #-----------------------# # Create main HTML Page # #-----------------------# main_page = '\n' + \ '\n'%domain_lang + \ ' \n' + \ - '%s\n'%metas_page + \ + '%s\n'%metas + \ ' \n\n' + \ ' \n' + \ '
    \n' + \ @@ -172,27 +177,31 @@ def create_main_page(target, article_bottom): ' \n' + \ '

    %s

    \n'%domain_about + \ ' \n' + \ - '' + \ + '\n' + \ '
    \n' + \ '\n' + \ '
    \n' + \ '%s\n'%article_bottom + \ '
    \n' + \ '\n' + \ + '\n' + \ ' \n' + \ '' + footer_file = '%sfooter.html'%srv_wip_tpl + if not os.path.exists(footer_file): + tyto.exiting("1", footer_file, True) #====================================# # Create HTML menu from root folders # #------------------------------------# -def create_navbar(): +def create_navbar(option, target): # Conditions to create navbar if not domain_menubar: - tyto.set_file(navbar_file, 'new', '') tyto.exiting("26", 'domain_menubar', False) if os.path.exists(navbar_file) and os.stat(navbar_file).st_size > 1: - tyto.exiting('27', 'contents (menu file): %s'%navbar_file, False) + tyto.set_file(navbar_file, 'new', '') + tyto.exiting('27', 'contents (navbar): %s'%navbar_file, False) return # True in config @@ -208,9 +217,9 @@ def create_navbar(): for line in nav_file.rsplit('\n'): if not line or line.startswith(nolines): continue - if '=' in line: - direc = line.rsplit('=')[0].rstrip() - title = '%stitle="%s"\n'%(15 * ' ', line.rsplit('=')[1].lstrip()) + if '#' in line: + direc = line.rsplit('#')[0].rstrip() + title = '%stitle="%s"\n'%(15 * ' ', line.rsplit('#')[1].lstrip()) else: direc = line title = '' @@ -232,4 +241,117 @@ def create_navbar(): # Close HTML tags menu_html = '\n%s\n%s\n%s\n'%(menu_html, 8 * ' ', 6 * ' ') - tyto.set_file('%snavbar.html'%srv_wip_tpl, 'new', menu_html) + tyto.set_file(navbar_file, 'new', menu_html) + + +# +# Create metas.html from tyto.metas.html +# +def create_user_metas(option): + domain.create_metas_file("-i") # Ensure config file exists + + metas_html = '%smetas.html'%srv_wip_tpl + user_metas = '' + metas_used = ('\n' + \ + ' \n' + \ + '

    %s

    \n'%( + domain_title) + \ + '
    \n' + \ + ' \n'%( + domain_about) + \ + ' \n' + \ + '\n' + \ + ' \n' + \ + '\n' + + + # Create new file, or ask if exists + ask = ' ├ Use default footer.html ? ' + log = ' ├ Create file: %s'%footer_load + + if os.path.exists(footer_load): + if option == '-i': return + res = input(ask) + if not res in ['y', 'Y']: return + + tyto.set_file(footer_load, 'new', footer) + print(log) + +''' + '
  • \n' + \ + ' %s\n'% + \ + '
  • \n' + \ + Copyright © 2021-2022 + +''' + +# +# Create footer.html from tyto.footer.html +# +def create_user_footer(option): + create_footer("-i") # Ensure config file exists + + footer_html = '%sfooter.html'%srv_wip_tpl + user_footer = '' + noline = ('\n' + \ - ' \n'%domain_title + \ - ' \n'%title + \ - ' \n' + \ - ' \n'%post_url + \ - ' \n' + \ - ' \n' + \ - '%s'%relme + \ - '\n\n' + \ - ' %s'%title - + metas = \ + ' \n' + \ + ' \n'%scale + \ + ' \n'%domain_url + \ + ' \n'%domain_lang + \ + ' \n'%domain_mail + \ + ' \n'%domain_license + \ + ' \n'%Tyto + \ + ' \n'%title + \ + ' \n'%author + \ + ' \n'%about + \ + ' \n'%all_tags + \ + ' \n'%en_date + \ + ' \n'%post_url + \ + ' \n'%(rss_ref) + \ + ' '%icon_ref + \ + ' \n' + \ + ' \n'%domain_title + \ + ' \n'%title + \ + ' \n' + \ + ' \n'%post_url + \ + ' \n'%about + \ + ' \n' + \ + '%s'%relme + \ + '\n\n' + \ + ' %s'%title #=======================================# @@ -158,35 +157,36 @@ def create_main_page(target, article_bottom): #-----------------------# # Create main HTML Page # #-----------------------# - main_page = '\n' + \ - '\n'%domain_lang + \ - ' \n' + \ - '%s\n'%metas + \ - ' \n\n' + \ - ' \n' + \ - '
    \n' + \ - ' \n' + \ - '\n' + \ - '
    \n' + \ - ' \n' + \ - '

    %s

    \n'%domain_title + \ - '
    \n' + \ - '

    %s

    \n'%domain_about + \ - '
    \n' + \ - '\n' + \ - '
    \n' + \ - '\n' + \ - '
    \n' + \ - '%s\n'%article_bottom + \ - '
    \n' + \ - '\n' + \ - '\n' + \ - ' \n' + \ - '' + main_page = \ + '\n' + \ + '\n'%domain_lang + \ + ' \n' + \ + '%s\n'%metas + \ + ' \n\n' + \ + ' \n' + \ + '
    \n' + \ + ' \n' + \ + '\n' + \ + '
    \n' + \ + ' \n' + \ + '

    %s

    \n'%domain_title + \ + '
    \n' + \ + '

    %s

    \n'%domain_about + \ + '
    \n' + \ + '\n' + \ + '
    \n' + \ + '\n' + \ + '
    \n' + \ + '%s\n'%article_bottom + \ + '
    \n' + \ + '\n' + \ + '\n' + \ + ' \n' + \ + '' footer_file = '%sfooter.html'%srv_wip_tpl if not os.path.exists(footer_file): @@ -244,9 +244,9 @@ def create_navbar(option, target): tyto.set_file(navbar_file, 'new', menu_html) -# -# Create metas.html from tyto.metas.html -# +#========================================# +# Create metas.html from tyto.metas.html # +#----------------------------------------# def create_user_metas(option): domain.create_metas_file("-i") # Ensure config file exists @@ -279,50 +279,90 @@ def create_footer(option): domain_licurl = "/" # Default footer contents - footer = '
    \n' + \ - ' \n' + \ - '\n' + \ - ' \n' + \ - '
    \n' + footer = \ + '\n'%Tyto + \ + '
    \n' + \ + ' \n' + \ + '\n' + \ + ' \n' + \ + '
    ' # Create new file, or ask if exists - ask = ' ├ Use default footer.html ? ' - log = ' ├ Create file: %s'%footer_load + ask_load = ' ├ Use default _configs/tyto.footer.html ? ' + log_load = ' ├ Create file: %s'%footer_load + create_load = True + + footer_html = '%sfooter.html'%srv_wip_tpl + ask_html = ' ├ Replace template/footer.html ' + \ + 'from _configs/tyto.footer.html ? ' + log_html = ' ├ Create file: %s'%footer_html + create_html = True + user_footer = '' + + + # Auto create if not tyto.footer.html in _configs + # Pass if exists, user not wants, option is 'New' (only footer.html) + res = '' + if os.path.exists(footer_load): + if option == 'New': + create_load = False + else: + res = input(ask_load) + if not res in ['y', 'Y']: create_load = False + + if create_load: + tyto.set_file(footer_load, 'new', footer) + print(log_load) - if os.path.exists(footer_load): - if option == '-i': return - res = input(ask) - if not res in ['y', 'Y']: return - tyto.set_file(footer_load, 'new', footer) - print(log) + # Auto create if not footer.html in template/ + # Create if option is 'New' + res = '' + if os.path.exists(footer_html): + if option == 'New': + create_html = True + else: + res = input(ask_html) + if not res in ['y', 'Y']: create_html = False + if create_html: + user_file = open(footer_load, 'r').read() + + for line in user_file.rsplit('\n'): + if not line: continue + if user_footer: user_footer = "%s\n %s"%(user_footer, line) + else: user_footer = ' %s'%line + + tyto.set_file(footer_html, 'new', user_footer) + print(log_html) + + + + ''' '
  • \n' + \ ' Date: Mon, 16 Jan 2023 10:46:23 +0100 Subject: [PATCH 126/247] indev: changed code for managing tyto.metas.html and metas.html --- src/var/lib/tyto/program/domain.py | 57 +--------------- src/var/lib/tyto/program/html.py | 102 +++++++++++++++++++++++++---- 2 files changed, 89 insertions(+), 70 deletions(-) diff --git a/src/var/lib/tyto/program/domain.py b/src/var/lib/tyto/program/domain.py index bba8e5b..3988417 100644 --- a/src/var/lib/tyto/program/domain.py +++ b/src/var/lib/tyto/program/domain.py @@ -435,7 +435,7 @@ def create_domain(target, option): #create_sidebar(option) #html.manage_configs('sidebar', 'Force') #html.manage_configs('navbar', 'Force') - #html.manage_configs('metas', 'Force') + html.manage_configs('metas', 'Force') html.manage_configs('footer', 'Force') print(' │') @@ -443,62 +443,7 @@ def create_domain(target, option): print(' │ Domain is ready. Have fun, writers ! │') print(' └──────────────────────────────────────┘') - -#========================================# -# Create metas.html with default content # -#----------------------------------------# -def create_metas_file(option): - metas_load = tyto.metas_load - metas_tags = '\n' + \ - '\n' + \ - '\n' + \ - '' - - - # Create new file, or ask if exists - ask = ' ├ Use default tyto.metas.html ? ' - log = ' ├ Create file: %s'%metas_load - if os.path.exists(metas_load): - if option == '-i': return # Continue to create template/metas.html - res = input(ask) - if not res in ['y', 'Y']: return - - tyto.set_file(metas_load, 'new', metas_tags) - print(log) - - #==============================# # sidebar load file translated # #------------------------------# diff --git a/src/var/lib/tyto/program/html.py b/src/var/lib/tyto/program/html.py index a1160fc..5226840 100644 --- a/src/var/lib/tyto/program/html.py +++ b/src/var/lib/tyto/program/html.py @@ -139,6 +139,19 @@ def create_metas_page(): def create_main_page(target, article_bottom): global main_page + # Check needed footer.html + footer_file = '%sfooter.html'%srv_wip_tpl + if not os.path.exists(footer_file): + tyto.exiting("1", footer_file, True) + + # Check optional metas.html + metas_file = '%smetas.html'%srv_wip_tpl + if not os.path.exists(metas_file): + tyto.exiting("24", '(user metas tags): '%metas_file, True) + + # Check for menu bar + create_navbar('-n', navbars_dir) + # Create link for website's logo #------------------------------- logo_html = '\n'%(15 * " ") + \ '%s'%(8 * " ") - # Check for menu bar - create_navbar('-n', navbars_dir) #-----------------------# # Create main HTML Page # @@ -188,9 +199,6 @@ def create_main_page(target, article_bottom): ' \n' + \ '' - footer_file = '%sfooter.html'%srv_wip_tpl - if not os.path.exists(footer_file): - tyto.exiting("1", footer_file, True) #====================================# # Create HTML menu from root folders # @@ -248,14 +256,82 @@ def create_navbar(option, target): # Create metas.html from tyto.metas.html # #----------------------------------------# def create_user_metas(option): - domain.create_metas_file("-i") # Ensure config file exists + metas_tags = \ + '\n' + \ + '\n' + \ + '\n' + \ + '' - metas_html = '%smetas.html'%srv_wip_tpl - user_metas = '' - metas_used = (' Date: Mon, 16 Jan 2023 11:43:07 +0100 Subject: [PATCH 127/247] indev: navbar manage --- src/var/lib/tyto/program/domain.py | 14 ++++++-------- src/var/lib/tyto/program/html.py | 27 +++++++++++++++++---------- src/var/lib/tyto/program/tyto.py | 1 + 3 files changed, 24 insertions(+), 18 deletions(-) diff --git a/src/var/lib/tyto/program/domain.py b/src/var/lib/tyto/program/domain.py index 3988417..6d0023f 100644 --- a/src/var/lib/tyto/program/domain.py +++ b/src/var/lib/tyto/program/domain.py @@ -433,8 +433,8 @@ def create_domain(target, option): # Force will ask to create in template print(' │') #create_sidebar(option) - #html.manage_configs('sidebar', 'Force') - #html.manage_configs('navbar', 'Force') + html.manage_configs('sidebar', 'Force') + html.manage_configs('navbar', 'Force') html.manage_configs('metas', 'Force') html.manage_configs('footer', 'Force') @@ -481,12 +481,9 @@ def create_sidebar(option): if tyto.n == 0: sdb_load = sdb_load_fr elif tyto.n == 1: sdb_load = sdb_load_en - - ask = ' ├ Use default (empty) sidebar config ? ' - log = ' ├ Create file: %s'%sidebar_load - + # Create new file, or ask if exists - ask = ' ├ Use default (empty) sidebar config file ? ' + ask = ' ├ Use default (empty) _configs/tyto.sidebar file ? ' log = ' ├ Create file: %s'%sidebar_load if os.path.exists(sidebar_load): @@ -501,6 +498,7 @@ def create_sidebar(option): # navbar load file translated # #-----------------------------# def create_navbar(option): + navbar_load = tyto.navbar_load nav_load_fr = '# Pour : Tyto - Littérateur\n' + \ '# Type : fichier texte\n' + \ '# Description : Fichier utilisé par "tyto wip"\n' + \ @@ -547,7 +545,7 @@ def create_navbar(option): elif tyto.n == 1: nav_load = nav_load_en # Create new file, or ask if exists - ask = ' ├ Use default (empty) navbar config file ? ' + ask = ' ├ Use default (empty) _configs/tyto.navbar file ? ' log = ' ├ Create file: %s'%navbar_load if os.path.exists(navbar_load): diff --git a/src/var/lib/tyto/program/html.py b/src/var/lib/tyto/program/html.py index 5226840..87aeb39 100644 --- a/src/var/lib/tyto/program/html.py +++ b/src/var/lib/tyto/program/html.py @@ -34,10 +34,11 @@ Tytosrc = '('%(8 * ' ') @@ -238,6 +238,7 @@ def create_navbar(option, target): continue # Add link to HTML structure + empty = False menu_item = '\n%s
  • - -# Source +# Source: citation basique [[ Une citation simple, et sans paragraphe ]] From 809fa6edaafca46ff6343d5c26745b8f243021c0 Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Wed, 8 Mar 2023 11:30:59 +0100 Subject: [PATCH 175/247] Anchors. Fix and process change (Needs tests) --- src/var/lib/tyto/program/tyto.py | 2 +- src/var/lib/tyto/program/wip.py | 28 ++++++++++++++++++++++------ 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/src/var/lib/tyto/program/tyto.py b/src/var/lib/tyto/program/tyto.py index 027af3f..57c2f0b 100644 --- a/src/var/lib/tyto/program/tyto.py +++ b/src/var/lib/tyto/program/tyto.py @@ -87,7 +87,7 @@ headers = ( # [6] = Check content differently. 't' = startswith #------------------------------------------------------------- words_tags = [ -('>_', '_<', '', 'anchors', 'w'), +('>_', '_<', '', '', 'anchors', 'w'), ('*_', '_*', '', '', 'strongs', 'w'), ('+_', '_+', '', '', 'bolds', 'w'), ('/_', '_/', '', '', 'emphasis', 'w'), diff --git a/src/var/lib/tyto/program/wip.py b/src/var/lib/tyto/program/wip.py index 0c3df8b..5ea5bb3 100644 --- a/src/var/lib/tyto/program/wip.py +++ b/src/var/lib/tyto/program/wip.py @@ -199,10 +199,17 @@ def wip_single_tags(): def wip_words_tags(): global article_bottom - # Strongs, italics... (8 tags) + # Strongs, italics... + # (Stop after 8 tags) + # For anchor (0), must do it differently m = 0 for tag in tyto.words_tags: - if m > 8: break + if m == 0: + m += 1 + # Close anchor (generic) + article_bottom = article_bottom.replace(tag[1], tag[3]) + continue + elif m > 8: break # Open tag article_bottom = article_bottom.replace(tag[0], tag[2]) @@ -210,8 +217,9 @@ def wip_words_tags(): article_bottom = article_bottom.replace(tag[1], tag[3]) m += 1 - # Paragraphs + for ln, line in enumerate(article_bottom.rsplit('\n')): + # Paragraphs # Open tag if line.startswith(tyto.words_tags[10][0]): set_css = tyto.get_css(line) @@ -220,12 +228,20 @@ def wip_words_tags(): tyto.words_tags[10][2]%set_css ) # Close tag - if line.startswith(tyto.words_tags[10][1]): + elif line.startswith(tyto.words_tags[10][1]): article_bottom = article_bottom.replace( line, tyto.words_tags[10][3] ) - + # Open anchors + anchor_links = re.findall(r'>_(.+?):', line) + for item in anchor_links: + anchor_id = '%s%s:'%(tyto.words_tags[0][0], item) + print(anchor_id) + article_bottom = article_bottom.replace( + anchor_id, tyto.words_tags[0][2]%item + ) + #=======================# # Convert links from DB # @@ -632,7 +648,7 @@ def wip_raws(target): global article_bottom - for i in range(1, db.uniq_raws + 1): + for i in range(1, db.xtuniq_raws + 1): raw = 'db.raw_%s'%i raw_file = open( '%s%s'%( From 35421678b8a6be1c02a8cd29cbbd546470038179 Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Wed, 8 Mar 2023 11:48:17 +0100 Subject: [PATCH 176/247] Anchors convertion + updated README --- README.md | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index dcd8dfc..7a5de37 100644 --- a/README.md +++ b/README.md @@ -103,13 +103,19 @@ def hello_world(): ### Ancres ``` +# Source` -> id -(( -un long paragraphe -)) + +# HTML + + +# Source (( >_id:Retourner au point d'ancre id_< )) + +# HTML +Retourner au point d'ancre id ``` ### Retour à la ligne HTML @@ -130,7 +136,7 @@ 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 file: et link: ### Gras, Strong, italique... ``` @@ -211,7 +217,8 @@ Pfff, vraiment ! echolib - Reference (2022-12-28)
    - +```` +``` # Source: citation basique [[ Une citation simple, et sans paragraphe From 36520d9ab6b56c9546d13d37c7c40afb49e62c3a Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Wed, 8 Mar 2023 11:48:36 +0100 Subject: [PATCH 177/247] Anchors convertion + updated README --- src/var/lib/tyto/program/wip.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/var/lib/tyto/program/wip.py b/src/var/lib/tyto/program/wip.py index 5ea5bb3..a49a51e 100644 --- a/src/var/lib/tyto/program/wip.py +++ b/src/var/lib/tyto/program/wip.py @@ -237,7 +237,6 @@ def wip_words_tags(): anchor_links = re.findall(r'>_(.+?):', line) for item in anchor_links: anchor_id = '%s%s:'%(tyto.words_tags[0][0], item) - print(anchor_id) article_bottom = article_bottom.replace( anchor_id, tyto.words_tags[0][2]%item ) From 0d91e2dce97703995aafd20ef7a6afdae9bc8d96 Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Thu, 9 Mar 2023 09:35:34 +0100 Subject: [PATCH 178/247] fix anchors. Now working. New classes CSS (anchor_target, anchor_link) --- src/var/lib/tyto/program/tyto.py | 4 ++-- src/var/lib/tyto/program/wip.py | 13 ++++++------- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/var/lib/tyto/program/tyto.py b/src/var/lib/tyto/program/tyto.py index 57c2f0b..15df944 100644 --- a/src/var/lib/tyto/program/tyto.py +++ b/src/var/lib/tyto/program/tyto.py @@ -87,7 +87,7 @@ headers = ( # [6] = Check content differently. 't' = startswith #------------------------------------------------------------- words_tags = [ -('>_', '_<', '', '', 'anchors', 'w'), +('>_', '_<', '', '', 'anchors', 'w'), ('*_', '_*', '', '', 'strongs', 'w'), ('+_', '_+', '', '', 'bolds', 'w'), ('/_', '_/', '', '', 'emphasis', 'w'), @@ -117,7 +117,7 @@ tpl_tags = [ #----------------------------------- single_tags = [ ('|', '
    '), # New Line -('->', '') # Anchors +('->', '') # Anchors ] # Markers for lists, to check in list content diff --git a/src/var/lib/tyto/program/wip.py b/src/var/lib/tyto/program/wip.py index a49a51e..21f769b 100644 --- a/src/var/lib/tyto/program/wip.py +++ b/src/var/lib/tyto/program/wip.py @@ -288,10 +288,10 @@ def wip_abbrs(): ) -#-------------------------------------# -# Get width and height for image # -# from parameter c=, from wip_image() # -#-------------------------------------# +#---------------------------------------# +# Get width and height for image # +# from parameter w/h=, from wip_image() # +#---------------------------------------# def get_wh_image(value): sizes = re.findall(r'(\d+)|(\D+)', value) if not sizes[0][1]: return('%spx'%value) @@ -373,7 +373,7 @@ def wip_images(): ) -#============================================# +#--------------------------------------------# # Get parameters for quote (author, date...) # #--------------------------------------------# def quote_params(qline): @@ -589,8 +589,7 @@ def wip_titles(): title_html = '%s'%(hx, hx, title_cont, hx) article_temp = article_temp.replace(line, title_html) - - + # Remove useless empty lines from article for line in article_temp.rsplit('\n'): if line: From 43895adef79bd83b6f276855ce91f7adc2709a00 Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Thu, 9 Mar 2023 09:51:01 +0100 Subject: [PATCH 179/247] New CSS class for div after titles. Same as hX: "title_X" --- src/var/lib/tyto/program/wip.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/var/lib/tyto/program/wip.py b/src/var/lib/tyto/program/wip.py index 21f769b..b9e7052 100644 --- a/src/var/lib/tyto/program/wip.py +++ b/src/var/lib/tyto/program/wip.py @@ -580,7 +580,7 @@ def wip_titles(): global article_bottom article_temp = article_bottom - article_tmp2 = '' # COnstruct article, without empty lines + article_tmp2 = '' # Construct article, without empty lines for line in article_bottom.rsplit('\n'): if line.startswith('#'): @@ -608,7 +608,7 @@ def wip_titles(): continue else: article_temp = article_temp.replace( - line, '%s\n
    '%line + line, '%s\n
    '%(line, hx) ) continue else: From 6671b03e95730acf94b133ba1563c37b1573b9eb Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Fri, 10 Mar 2023 12:17:45 +0100 Subject: [PATCH 180/247] Lots of changes. Need tests, but should work --- src/var/lib/tyto/program/args.py | 1 + src/var/lib/tyto/program/check.py | 179 +++++++++++++-------- src/var/lib/tyto/program/logs.py | 1 + src/var/lib/tyto/program/tyto.py | 252 ++++++++++++++++-------------- src/var/lib/tyto/program/wip.py | 202 ++++++++++++------------ 5 files changed, 349 insertions(+), 286 deletions(-) diff --git a/src/var/lib/tyto/program/args.py b/src/var/lib/tyto/program/args.py index a7bb3e8..62c9b7c 100644 --- a/src/var/lib/tyto/program/args.py +++ b/src/var/lib/tyto/program/args.py @@ -54,6 +54,7 @@ pass_db = \ 'edit-wip', 'edit-www', 'publish', + 'show', 'show-db', 'show-wip', 'show-www', diff --git a/src/var/lib/tyto/program/check.py b/src/var/lib/tyto/program/check.py index ce5ea7f..fe5bbd8 100644 --- a/src/var/lib/tyto/program/check.py +++ b/src/var/lib/tyto/program/check.py @@ -35,7 +35,7 @@ def manage_check(target): # target needed if not target: logs.out("5", '', True) - global date_wip, hash_wip, date_www, hash_www + global date_wip, hash_wip, date_www, hash_www, post_bottom date_wip = hash_wip = date_www = hash_www = '' # Article has DB @@ -98,28 +98,30 @@ def manage_check(target): # Start checking processes #------------------------- file_to_string(db.uri_file) - + # Specific to inline-code: check markers on same line - check_icodes(article.rsplit('\n')) + if_icodes_bcodes_quotes(post_bottom) + + # Protect block-codes and quotes + if bcode or quote: + tyto.protect_bcodes_quotes('check', post_bottom) + post_bottom = tyto.protect_article # Protect inline-codes - tyto.protect_icodes(post_bottom, article_bottom) - post_bottom = tyto.protect_article.rsplit('\n') - article_bottom = tyto.protect_article - - # Protect block-codes and quotes - tyto.protect_bcodes_quotes('check', post_bottom, article_bottom) - post_bottom = tyto.protect_article.rsplit('\n') - article_bottom = tyto.protect_article + if icode: + tyto.protect_icodes(post_bottom) + post_bottom = tyto.protect_article + # Count words in article. Quotes, block-codes, icode = 1 per each - post_words = len(article_bottom.strip().split(" ")) - + post_words = len(post_bottom.strip().split(" ")) + # Check for valid contents check_content(post_bottom) - post_bottom = article_bottom.rsplit('\n') + post_bottom = post_bottom.rsplit('\n') - check_headers(post_header) + #post_header = post_header.rsplit('\n') + check_headers(post_header.rsplit('\n')) # Exit if unused needed tags if post_err: @@ -131,62 +133,81 @@ def manage_check(target): create_database() -#=====================# -# Find in post_bottom # -#---------------------# -def isin(term, post_bottom): - for x in post_bottom: - if re.search(r'%s'%term, x): - return True - return False - - #=================================# # Create string article from file # # Check if separator or exit # #---------------------------------# def file_to_string(post_file): global article - global article_header, article_bottom global post_header, post_bottom + post_header = post_bottom = '' + sep = False article = open(post_file, 'r').read() + for line in article.rsplit('\n'): + if line.startswith('-----'): + sep = True + continue + + if sep: + if not post_bottom: post_bottom = line + else: post_bottom = '%s\n%s'%(post_bottom, line) + else: + if not post_header: post_header = line + else: post_header = '%s\n%s'%(post_header, line) + # Check if separator or exit - if not '-----' in article: logs.out("6", '-----', True) - - # Set from separator, NOT splitted by new line - article_header = article.rsplit('-----')[0] - article_bottom = article.rsplit('-----')[1] - - # Set from separator, splitted by new line - post_header = article.rsplit('-----')[0].rsplit('\n') - post_bottom = article.rsplit('-----')[1].rsplit('\n') + if not sep: + logs.out("6", '-----', True) #=============================================# +# Check if bcodes and quotes # # Check inline code, for markers on same line # +# Stats for titles, quotes, bcodes, uniq_ancs # #---------------------------------------------# -def check_icodes(article): - quote = bcode = False +def if_icodes_bcodes_quotes(post_bottom): + global icode, quote, bcode + global nbr_titles, nbr_quotes, nbr_bcodes, nbr_ancs + icode = quote = in_quote = bcode = in_bcode = False + nbr_titles = nbr_quotes = nbr_bcodes = nbr_ancs = 0 - for ln, line in enumerate(article, 1): - icode_m1 = icode_m2 = 0 - - # Pass Comments - if line.startswith('#'): continue + for ln, line in enumerate(post_bottom.rsplit('\n'), 1): + # Pass Comments, count titles + # Count titles + if not line: + continue + elif line.startswith(tyto.titles_tags): + nbr_titles += 1 + continue + elif line.startswith('#'): + continue # Pass quotes - if line.startswith(tyto.words_tags[11][0]): quote = True - if line.startswith(tyto.words_tags[11][1]): quote = False + elif line.startswith(tyto.words_tags[11][0]) and not in_bcode: + quote = in_quote = True + nbr_quotes += 1 + continue + elif line.startswith(tyto.words_tags[11][1]): + in_quote = False + continue # Pass bcode - if line.startswith(tyto.words_tags[12][0]): bcode = True - if line.startswith(tyto.words_tags[12][1]): bcode = False + elif line.startswith(tyto.words_tags[12][0]) and not in_quote: + bcode = in_bcode = True + nbr_bcodes += 1 + continue + elif line.startswith(tyto.words_tags[12][1]): + in_bcode = False + continue - if bcode or quote: continue - - if tyto.words_tags[9][0] or tyto.words_tags[9][1] in line: + if in_bcode or in_quote: + continue + elif line.startswith(tyto.single_tags[1][0]): + nbr_ancs += 1 + elif tyto.words_tags[9][0] or tyto.words_tags[9][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]) if icode_m1 != icode_m2: @@ -194,6 +215,8 @@ def check_icodes(article): tyto.words_tags[9][0], tyto.words_tags[9][1] ), True ) + else: + icode = True #==================================# @@ -226,7 +249,6 @@ def check_headers(post_header): # Read articles lines, till separator # #-------------------------------------# for ln, line in enumerate(post_header, 1): - # Set each needed tag # # Only the first one is set # #---------------------------# @@ -283,7 +305,7 @@ def check_headers(post_header): # Check if set needed tags for tag in need_headers: if not need_headers[tag]: - logs_out("6", tag, False) + logs.out("6", tag, False) post_err = True @@ -573,7 +595,6 @@ def check_file_uri(filetype, filename, ln): #---------------------------# def check_content(post_bottom): global post_err - global article_bottom # Check tags for words (strongs, italics...) # Set stats for each one @@ -582,13 +603,13 @@ def check_content(post_bottom): c_opened = c_closed = 0 if tag[5] == 'w': - c_opened = article_bottom.count(tag[0]) - c_closed = article_bottom.count(tag[1]) + c_opened = post_bottom.count(tag[0]) + c_closed = post_bottom.count(tag[1]) # Useless tag now, replace - article_bottom = article_bottom.replace(tag[0], '') - article_bottom = article_bottom.replace(tag[1], '') + post_bottom = post_bottom.replace(tag[0], '') + post_bottom = post_bottom.replace(tag[1], '') elif tag[5] == 't': - for line in post_bottom: + for line in post_bottom.rsplit('\n'): if line.startswith(tag[0]): c_opened += 1 if line.startswith(tag[1]): c_closed += 1 @@ -602,12 +623,9 @@ def check_content(post_bottom): # Check if anchor has target # Count anchors target - #--------------------------- - global stat_ancs - stat_ancs = 0 - - for line in post_bottom: - if line.startswith(tyto.single_tags[1][0]): stat_ancs += 1 + #--------------------------- + for line in post_bottom.rsplit('\n'): + # Anchor link if tyto.words_tags[0][0] and tyto.words_tags[0][1] in line: anchors = re.findall(r">_(.*?)_<", line) for anchor in anchors: @@ -616,6 +634,16 @@ def check_content(post_bottom): if not tag in post_bottom: logs.out("6", 'anchor, %s'%tag, False) post_err = True + + # Anchor source "->" + elif line.startswith(tyto.single_tags[1][0]): + set_css = tyto.get_css(line) + is_uniq_anchor = "%s %s"%(tyto.single_tags[1][0], set_css) + c_uniq_anchor = post_bottom.count(is_uniq_anchor) + if c_uniq_anchor > 1: + logs.out("15", '%s "%s"'%(c_uniq_anchor, is_uniq_anchor), False) + post_err = True + break # Lists: check if contents are valid @@ -663,8 +691,8 @@ def check_content(post_bottom): # Template Tags (warning for not paired symbols) #----------------------------------------------- for tag in tyto.tpl_tags: - tpl1 = article_bottom.count(tag[0]) - tpl2 = article_bottom.count(tag[1]) + tpl1 = post_bottom.count(tag[0]) + tpl2 = post_bottom.count(tag[1]) if tpl1 != tpl2: logs.out("22", '"%s", "%s"'%(tag[0], tag[1]), False) @@ -735,7 +763,7 @@ def create_database(): ) db_stats = '\n# Statistics from optional tags\n' + \ - 'uniq_anchors = %d\n'%stat_ancs + \ + 'uniq_anchors = %d\n'%nbr_ancs + \ 'uniq_abbrs = %d\n'%stat_abbrs + \ 'uniq_links = %d\n'%stat_links + \ 'uniq_images = %d\n'%stat_images + \ @@ -744,7 +772,7 @@ def create_database(): '\n# Statistics from post content\n' + \ 'stat_tags = %d\n'%post_tags + \ 'stat_words = %d\n'%post_words + \ - 'stat_titles = %d\n'%tyto.nbr_titles + \ + 'stat_titles = %d\n'%nbr_titles + \ 'stat_paragraphs = %d\n'%post_paragraphs + \ 'stat_anchors = %d\n'%post_anchors + \ 'stat_strongs = %d\n'%post_strongs + \ @@ -756,10 +784,23 @@ def create_database(): 'stat_cites = %d\n'%post_cites + \ 'stat_customs = %d\n'%post_customs + \ 'stat_icodes = %d\n'%tyto.nbr_icodes + \ - 'stat_bcodes = %d\n'%tyto.nbr_bcodes + \ - 'stat_quotes = %d\n'%tyto.nbr_quotes + \ + 'stat_bcodes = %d\n'%nbr_bcodes + \ + 'stat_quotes = %d\n'%nbr_quotes + \ 'stat_lists = %d\n'%post_lists + ''' + + ''' database = '%s\n%s'%(database, db_stats) tyto.set_file(db.post_db, 'new', database) logs.out("21", '', True) + + +#=====================# +# Find in post_bottom # +#---------------------# +def isin(term, post_bottom): + for x in post_bottom: + if re.search(r'%s'%term, x): + return True + return False diff --git a/src/var/lib/tyto/program/logs.py b/src/var/lib/tyto/program/logs.py index 50185ab..0400829 100644 --- a/src/var/lib/tyto/program/logs.py +++ b/src/var/lib/tyto/program/logs.py @@ -44,6 +44,7 @@ def out(nbr, value, out): '12' : ':< %sUnused "%s"%s in article\'s header'%(CR, value, CS), '13' : ':< %sNo file or directory%s here (deleted ?)'%(CR, CS), '14' : ':< %sMismatch%s program start'%(CR, CS), + '15' : ':< Anchor %snot uniq%s: %s'%(CR, CS, value), '19' : ':D Article %swip%s on: %s'%(CG, CS, value), '20' : ':D Article %scheck%s on: %s'%(CG, CS, value), '21' : ':D Article %sValid%s. Ready to wip'%(CG, CS), diff --git a/src/var/lib/tyto/program/tyto.py b/src/var/lib/tyto/program/tyto.py index 15df944..d8aba7e 100644 --- a/src/var/lib/tyto/program/tyto.py +++ b/src/var/lib/tyto/program/tyto.py @@ -244,137 +244,149 @@ def get_css(line): return set_css +#=============================================# +# First check process to protect contents # +# Protect block-Codes, quotes # +# Also remove empty/commented lines # +# Used in check and wip # +# check: create string without quotes, bcodes # +# wip: remplace quotes, bcode with base64 # +#---------------------------------------------# +def protect_bcodes_quotes(process, post_bottom): + global protect_article + global nbr_titles, nbr_bcodes, nbr_quotes # Stats for DB + + in_bcode = in_quote = False + protect_article = '' + bcode = quote = '' # Only for wip process + + for line in post_bottom.rsplit('\n'): + start_bcode = close_bcode = False + start_quote = close_quote = False + + # Settings and counters + #---------------------- + # Bcode (at close, replace with base64) + if not in_quote: + if line.startswith(words_tags[12][0]): # Open + start_bcode = True + in_bcode = True + elif line.startswith(words_tags[12][1]): # Close + close_bcode = True + in_bcode = False + if process == "wip": + bcode = '%s\n%s'%(bcode, line) + b64_bcode = b64('Encode', bcode, 'B64.', '.B64') + line = b64_bcode + + # Quote (at close, replace with base64) + if not in_bcode: + if line.startswith(words_tags[11][0]): # Open + start_quote = True + in_quote = True + elif line.startswith(words_tags[11][1]): # Close + close_quote = True + in_quote = False + if process == "wip": + quote = '%s\n%s'%(quote, line) + b64_quote = b64('Encode', quote, 'Q64.', '.Q64') + line = b64_quote + + if not in_quote and not in_bcode: + if not line: continue + if line.startswith('#') and not line.startswith(titles_tags): + continue + + + # Counters and keep tags for check process + #----------------------------------------- + if process == "check": + if in_bcode and not start_bcode \ + or in_quote and not start_quote : + continue + + + # Set new article content for wip process + #---------------------------------------- + elif process == "wip": + # bcode convertion to base64 + if in_bcode: + # Convert lines to b64 + if not bcode: bcode = line + else: bcode = '%s\n%s'%(bcode, line) + line = '' + elif in_quote: + # Convert lines to b64 + if not quote: quote = line + else: quote = '%s\n%s'%(quote, line) + line = '' + + + # Set new content + #---------------- + # check: remove quote/bcode, keep tags + # wip: replace close tag with quote/bcode (keep in open tag) + if not line: continue + if not protect_article: protect_article = line + else: protect_article = '%s\n%s'%(protect_article, line) + + + # Clean in wip process for new quote/bcode + if process == "wip": + if close_bcode: bcode = b64_bcode = '' + if close_quote: quote = b64_quote = '' + + #=======================# # Protec iCodes # # Used in check and wip # #-----------------------~ -def protect_icodes(post_bottom, article_bottom): +def protect_icodes(post_bottom): global protect_article global nbr_icodes - nbr_icodes = 0 # Stats here for DB as content will change - protect_article = article_bottom - incode = False + nbr_icodes = 0 # Stats here for DB as content will change + protect_article = post_bottom + in_icode = False src_code = rep_code = '' # Get only lines that contains code - for ln, line in enumerate(post_bottom): - if words_tags[9][0] and words_tags[9][1] in line: - - # Iterate in line - 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 == '\\': - incode = True - nbr_icodes += 1 - code = words_tags[9][2] - continue - - # No more in code if - if c_a == '}' and not c_b == '\\': - incode = False - code = '%s%s%s'%(code, src_code, words_tags[9][3]) - b64_code = b64('Encode', code, 'I64.', '.I64') - rep_code = "%s%s%s"%( - words_tags[9][0], rep_code, words_tags[9][1] - ) - temp_post = protect_article.replace(rep_code, b64_code) - protect_article = temp_post - - src_code = rep_code = b64_code = '' - continue + for ln, line in enumerate(post_bottom.rsplit('\n')): + if not words_tags[9][0] in line: continue + + # Iterate (c)haracter in line + 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 - # Construct original replacement code and source code - if incode: - rep_code = '%s%s'%(rep_code, c) - if c == '\\': continue - src_code = '%s%s'%(src_code, c) - - -#=============================================# -# Protect block-Codes, quotes # -# Also remove commented lines # -# Used in check and wip # -# check: create string without quotes, bcode # -# wip: remplace quotes, bcode with base64 # -#---------------------------------------------# -def protect_bcodes_quotes(process, post_bottom, article_bottom): - global protect_article - global nbr_titles, nbr_bcodes, nbr_quotes # Stats for DB - - in_bcode = in_quote = False - end_bcode = end_quote = False - protect_article = '' - temp_article = article_bottom - nbr_titles = nbr_bcodes = nbr_quotes = 0 - bcode = quote = '' - - - for line in post_bottom: - # Bcode - if not in_quote: - if line.startswith(words_tags[12][0]): - in_bcode = True - if process == 'check': - if not protect_article: protect_article = line - else: protect_article = '%s\n%s'%(protect_article, line) - nbr_bcodes += 1 - elif line.startswith(words_tags[12][1]): - if process == "wip": - bcode = '%s\n%s'%(bcode, line) - b64_bcode = b64('Encode', bcode, 'B64.', '.B64') - line = b64_bcode - end_bcode = True - in_bcode = False - - # Quote - if not in_bcode: - if line.startswith(words_tags[11][0]): - in_quote = True - if process == 'check': - if not protect_article: protect_article = line - else: protect_article = '%s\n%s'%(protect_article, line) - nbr_quotes += 1 - elif line.startswith(words_tags[11][1]): - if process == "wip": - quote = '%s\n%s'%(quote, line) - b64_quote = b64('Encode', quote, 'Q64.', '.Q64') - line = b64_quote - end_quote = True - in_quote = False - - # Count titles for check - # Pass if line is a comment - if not in_bcode and not in_quote: - if line.startswith(titles_tags): - if process == 'check': - nbr_titles += 1 - elif line.startswith('#'): - continue - - if in_bcode: - if not bcode: bcode = line - else: bcode = '%s\n%s'%(bcode, line) - - elif in_quote: - if line.startswith('#'): continue - if not quote: quote = line - else: quote = '%s\n%s'%(quote, line) - - if end_bcode: bcode = ''; end_bcode = False ; in_bcode = False - elif end_quote: quote = ''; end_quote = False ; in_quote = False - - if in_quote or in_bcode: - continue - else: - if not protect_article: protect_article = line - else: protect_article = '%s\n%s'%(protect_article, line) + # incode if + if c_b == '{' and not c_bb == '\\': + in_icode = True + nbr_icodes += 1 + code = words_tags[9][2] + continue + + # No more in code if + if c_a == '}' and not c_b == '\\': + in_icode = False + code = '%s%s%s'%(code, src_code, words_tags[9][3]) + b64_code = b64('Encode', code, 'I64.', '.I64') + rep_code = "%s%s%s"%( + words_tags[9][0], rep_code, words_tags[9][1] + ) + protect_article = protect_article.replace(rep_code, b64_code) + + src_code = rep_code = b64_code = '' + 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) #=====================================# diff --git a/src/var/lib/tyto/program/wip.py b/src/var/lib/tyto/program/wip.py index b9e7052..70395d0 100644 --- a/src/var/lib/tyto/program/wip.py +++ b/src/var/lib/tyto/program/wip.py @@ -30,6 +30,8 @@ def manage_wip(target): # Check if can process domain.domain_needed() + wip_article(db.post_src) + return # Option 'all' to wip again, based on DB #--------------------------------------- @@ -106,18 +108,19 @@ def wip_article(target): # Convert file to strings file_to_string(target) - global post_header, article_header - global post_bottom, article_bottom - + global post_header + global post_bottom + # Protect block-codes and quotes - tyto.protect_bcodes_quotes('wip', post_bottom, article_bottom) - post_bottom = tyto.protect_article.rsplit('\n') - article_bottom = tyto.protect_article + if db.stat_bcodes or db.stat_quotes > 0: + tyto.protect_bcodes_quotes('wip', post_bottom) + post_bottom = tyto.protect_article # Protect inline-codes - tyto.protect_icodes(post_bottom, article_bottom) - post_bottom = tyto.protect_article.rsplit('\n') - article_bottom = tyto.protect_article + if db.stat_icodes > 0: + tyto.protect_icodes(post_bottom) + post_bottom = tyto.protect_article + # Convert contents from modules wip_single_tags() # br /, anchors @@ -139,7 +142,7 @@ def wip_article(target): tyto.replace_in_db(db.post_db, 'wip', db.hash_post) # Get article DB in html.py - html.set_page(db.uri_file, article_bottom) + html.set_page(db.uri_file, post_bottom) #print(html.main_page) # Create wip file @@ -156,48 +159,52 @@ def wip_article(target): # post is string splitted '\n' # # article is string not splitted # #---------------------------------# -def file_to_string(target): +def file_to_string(post_file): global article - global article_header, article_bottom global post_header, post_bottom - article = open(target, 'r').read() + post_header = post_bottom = '' + sep = False + article = open(post_file, 'r').read() - # Set from separator, NOT splitted by new line - article_header = article.rsplit('-----')[0] - article_bottom = article.rsplit('-----')[1] - - # Set from separator, splitted by new line - post_header = article.rsplit('-----')[0].rsplit('\n') - post_bottom = article.rsplit('-----')[1].rsplit('\n') + for line in article.rsplit('\n'): + if line.startswith('-----'): + sep = True + continue + + if sep: + if not post_bottom: post_bottom = line + else: post_bottom = '%s\n%s'%(post_bottom, line) + else: + if not post_header: post_header = line + else: post_header = '%s\n%s'%(post_header, line) #=============================# # Convert tags (br /, anchor) # #-----------------------------# def wip_single_tags(): - global article_bottom + global post_bottom #
    from "|" - article_bottom = article_bottom.replace( - tyto.single_tags[0][0], tyto.single_tags[0][1] - ) + post_bottom = post_bottom.replace(tyto.single_tags[0][0], + tyto.single_tags[0][1] + ) - for line in article_bottom.rsplit('\n'): + for line in post_bottom.rsplit('\n'): if line.startswith(tyto.single_tags[1][0]): set_css = tyto.get_css(line) - article_bottom = article_bottom.replace( - line, - tyto.single_tags[1][1]%set_css - ) - + post_bottom = post_bottom.replace(line, + tyto.single_tags[1][1]%set_css + ) + #==================================# # Convert tags (strong, icodes...) # # Convert Paragraphs # #----------------------------------# def wip_words_tags(): - global article_bottom + global post_bottom # Strongs, italics... # (Stop after 8 tags) @@ -207,40 +214,40 @@ def wip_words_tags(): if m == 0: m += 1 # Close anchor (generic) - article_bottom = article_bottom.replace(tag[1], tag[3]) + post_bottom = post_bottom.replace(tag[1], tag[3]) continue elif m > 8: break # Open tag - article_bottom = article_bottom.replace(tag[0], tag[2]) + post_bottom = post_bottom.replace(tag[0], tag[2]) # Close tag - article_bottom = article_bottom.replace(tag[1], tag[3]) + post_bottom = post_bottom.replace(tag[1], tag[3]) m += 1 - for ln, line in enumerate(article_bottom.rsplit('\n')): + for ln, line in enumerate(post_bottom.rsplit('\n')): # Paragraphs # Open tag - if line.startswith(tyto.words_tags[10][0]): - set_css = tyto.get_css(line) - article_bottom = article_bottom.replace( - article_bottom.rsplit('\n')[ln], - tyto.words_tags[10][2]%set_css - ) - # Close tag - elif line.startswith(tyto.words_tags[10][1]): - article_bottom = article_bottom.replace( - line, - tyto.words_tags[10][3] - ) + if db.stat_paragraphs > 0: + if line.startswith(tyto.words_tags[10][0]): + set_css = tyto.get_css(line) + post_bottom = post_bottom.replace(post_bottom.rsplit('\n')[ln], + tyto.words_tags[10][2]%set_css + ) + # Close tag + elif line.startswith(tyto.words_tags[10][1]): + post_bottom = post_bottom.replace(line, + tyto.words_tags[10][3] + ) # Open anchors + if db.stat_anchors == 0: continue anchor_links = re.findall(r'>_(.+?):', line) for item in anchor_links: - anchor_id = '%s%s:'%(tyto.words_tags[0][0], item) - article_bottom = article_bottom.replace( - anchor_id, tyto.words_tags[0][2]%item - ) - + anchor_id = '%s%s:'%(tyto.words_tags[0][0], item) + post_bottom = post_bottom.replace(anchor_id, + tyto.words_tags[0][2]%item + ) + #=======================# # Convert links from DB # @@ -248,28 +255,28 @@ def wip_words_tags(): # - file_%i # #-----------------------# def wip_links(): - global article_bottom + global post_bottom # Doing files, first, becase of similar marker if db.uniq_files > 0: for i in range(1, db.uniq_files + 1): file = 'db.file_%s'%i - article_bottom = article_bottom.replace( - eval(file)[0]+'+', eval(file)[1]%('_blank') - ) - article_bottom = article_bottom.replace( - eval(file)[0], eval(file)[1]%('_self') - ) + post_bottom = post_bottom.replace(eval(file)[0]+'+', + eval(file)[1]%('_blank') + ) + post_bottom = post_bottom.replace(eval(file)[0], + eval(file)[1]%('_self') + ) if db.uniq_links > 0: for i in range(1, db.uniq_links + 1): link = 'link_%s'%i - article_bottom = article_bottom.replace( - eval(link)[0]+'+', eval(link)[1]%('_blank') - ) - article_bottom = article_bottom.replace( - eval(link)[0], eval(link)[1]%('_self') - ) + post_bottom = post_bottom.replace(eval(link)[0]+'+', + eval(link)[1]%('_blank') + ) + post_bottom = post_bottom.replace(eval(link)[0], + eval(link)[1]%('_self') + ) #===============# @@ -278,14 +285,13 @@ def wip_links(): def wip_abbrs(): if db.uniq_abbrs == 0: return - global article_bottom + global post_bottom for i in range(1, db.uniq_abbrs + 1): abbr = 'abbr_%s'%i - article_bottom = article_bottom.replace( - eval(abbr)[0], - eval(abbr)[1] - ) + post_bottom = post_bottom.replace(eval(abbr)[0], + eval(abbr)[1] + ) #---------------------------------------# @@ -304,12 +310,12 @@ def get_wh_image(value): def wip_images(): if db.uniq_images == 0: return - global article_bottom + global post_bottom image_link = '%s' image_show = '%s' # Check each line - for ln, line in enumerate(article_bottom.rsplit('\n')): + for ln, line in enumerate(post_bottom.rsplit('\n')): # match line if line.startswith('_image:'): values = line.rsplit(' ') @@ -368,9 +374,9 @@ def wip_images(): # Set HTML to replace line number image_html = image_tgt%image_src - article_bottom = article_bottom.replace( - article_bottom.rsplit('\n')[ln], image_html - ) + post_bottom = post_bottom.replace(post_bottom.rsplit('\n')[ln], + image_html + ) #--------------------------------------------# @@ -388,10 +394,10 @@ def quote_params(qline): def wip_quotes() : if db.stat_quotes == 0: return - global article_bottom + global post_bottom global author, link, lang, book, date - for ln, line in enumerate(article_bottom.rsplit('\n')): + for ln, line in enumerate(post_bottom.rsplit('\n')): # Decode from base64 if line.startswith('Q64'): line = line.replace('Q64.', '') @@ -424,9 +430,9 @@ def wip_quotes() : else: tab_c = tab_c + 2 # Replace opened paragrph with html line - qline_html = '%s%s'%( - tab_p * ' ', tyto.words_tags[10][2]%par_css - ) + qline_html = '%s%s'%(tab_p * ' ', + tyto.words_tags[10][2]%par_css + ) # Add line to quote_html if quote_html: @@ -518,9 +524,9 @@ def wip_quotes() : '
    ' # Replace line with final HTML Quote - article_bottom = article_bottom.replace( - 'Q64.%s.Q64'%line, quote_html - ) + post_bottom = post_bottom.replace('Q64.%s.Q64'%line, + quote_html + ) #==========================# @@ -530,13 +536,13 @@ def wip_quotes() : def wip_icodes(): if db.stat_icodes == 0: return - global article_bottom + global post_bottom - matches = re.findall(r'I64.(.*?).I64', article_bottom) + matches = re.findall(r'I64.(.*?).I64', post_bottom) for match in matches: rep_icode = 'I64.' + match + '.I64' src_icode = tyto.b64("Decode", match, 'I64.', '.I64') - article_bottom = article_bottom.replace(rep_icode, src_icode) + post_bottom = post_bottom.replace(rep_icode, src_icode) #==================================================# @@ -546,9 +552,9 @@ def wip_icodes(): def wip_bcodes(): if db.stat_bcodes == 0: return - global article_bottom + global post_bottom - matches = re.findall(r'B64.(.*?).B64', article_bottom) + matches = re.findall(r'B64.(.*?).B64', post_bottom) for match in matches: rep_bcode = 'B64.' + match + '.B64' src_bcode = tyto.b64("Decode", match, 'B64.', '.B64') @@ -566,9 +572,11 @@ def wip_bcodes(): '
    ' # Block-code content per line else: - html_bcode = '%s\n %s'%(html_bcode, line) + html_bcode = '%s\n %s'%(html_bcode, + line + ) - article_bottom = article_bottom.replace(rep_bcode, html_bcode) + post_bottom = post_bottom.replace(rep_bcode, html_bcode) #========================================# @@ -578,11 +586,11 @@ def wip_bcodes(): def wip_titles(): if db.stat_titles == 0: return - global article_bottom - article_temp = article_bottom + global post_bottom + article_temp = post_bottom article_tmp2 = '' # Construct article, without empty lines - for line in article_bottom.rsplit('\n'): + for line in post_bottom.rsplit('\n'): if line.startswith('#'): hx = line[1] title_cont = line[2: len(line)].lstrip() @@ -635,7 +643,7 @@ def wip_titles(): article_temp = '%s\n'%article_temp # Replace article with new contents - article_bottom = article_temp + post_bottom = article_temp #==============================================# @@ -671,7 +679,7 @@ def wip_raws(target): # Make HTML tabulations # #-----------------------# def wip_tabs(): - global article_bottom + global post_bottom article_temp = '' tab = tab_start = 6 # From
    tag indiv = False @@ -685,7 +693,7 @@ def wip_tabs(): '6' : '16' } - for line in article_bottom.rsplit('\n'): + for line in post_bottom.rsplit('\n'): # Titles if line.startswith(' Date: Fri, 10 Mar 2023 12:21:51 +0100 Subject: [PATCH 181/247] fix: post_bottom in wip_raws --- src/var/lib/tyto/program/wip.py | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/var/lib/tyto/program/wip.py b/src/var/lib/tyto/program/wip.py index 70395d0..03533fe 100644 --- a/src/var/lib/tyto/program/wip.py +++ b/src/var/lib/tyto/program/wip.py @@ -135,9 +135,6 @@ def wip_article(target): wip_raws(target) # Read file and convert to HTML wip_tabs() # make HTML tabulations - # Result (temp display) - #print(article_bottom) - # Replace in DB hash_wip and date_wip tyto.replace_in_db(db.post_db, 'wip', db.hash_post) @@ -652,9 +649,9 @@ def wip_titles(): def wip_raws(target): if db.uniq_raws == 0: return - global article_bottom + global post_bottom - for i in range(1, db.xtuniq_raws + 1): + for i in range(1, db.uniq_raws + 1): raw = 'db.raw_%s'%i raw_file = open( '%s%s'%( @@ -671,9 +668,10 @@ def wip_raws(target): ) raw_html = '%s\n \n'%(raw_html) - article_bottom = article_bottom.replace( - eval(raw)[0], raw_html - ) + post_bottom = post_bottom.replace(eval(raw)[0], + raw_html + ) + #=======================# # Make HTML tabulations # From 8a43b795bb1e79a14becb9c12b19e95ca2a628d8 Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Fri, 10 Mar 2023 15:31:17 +0100 Subject: [PATCH 182/247] Statoolinfos. Indev to create stat files on command for wip/www server --- src/usr/bin/tyto | 4 +- src/var/lib/tyto/program/args.py | 1 + src/var/lib/tyto/program/check.py | 3 +- src/var/lib/tyto/program/infos.py | 3 +- src/var/lib/tyto/program/stats.py | 118 ++++++++++++++++++++++++++++++ src/var/lib/tyto/program/tyto.py | 1 + src/var/lib/tyto/program/wip.py | 93 ++++++++++++----------- 7 files changed, 176 insertions(+), 47 deletions(-) create mode 100644 src/var/lib/tyto/program/stats.py diff --git a/src/usr/bin/tyto b/src/usr/bin/tyto index 0409cdd..d5dfb5b 100755 --- a/src/usr/bin/tyto +++ b/src/usr/bin/tyto @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Version: 0.9.0 +# Version: 0.9.1 # Name: Tyto - Littérateur # Type: Executable # Description: Multiple Static Websites generator and manager @@ -57,7 +57,7 @@ actions = { 'show-db' : show.manage_show, 'show-wip' : show.manage_show, 'show-www' : show.manage_show, - 'template' : publish.manage_publish, + 'template' : publish.manage_publish, 'wip' : wip.manage_wip, } diff --git a/src/var/lib/tyto/program/args.py b/src/var/lib/tyto/program/args.py index 62c9b7c..e00e599 100644 --- a/src/var/lib/tyto/program/args.py +++ b/src/var/lib/tyto/program/args.py @@ -69,6 +69,7 @@ pass_targets = \ 'metas', 'navbar', 'sidebar', + 'stats', 'template' ) diff --git a/src/var/lib/tyto/program/check.py b/src/var/lib/tyto/program/check.py index fe5bbd8..5b0c470 100644 --- a/src/var/lib/tyto/program/check.py +++ b/src/var/lib/tyto/program/check.py @@ -138,8 +138,7 @@ def manage_check(target): # Check if separator or exit # #---------------------------------# def file_to_string(post_file): - global article - global post_header, post_bottom + global article, post_header, post_bottom post_header = post_bottom = '' sep = False diff --git a/src/var/lib/tyto/program/infos.py b/src/var/lib/tyto/program/infos.py index 50135ed..09833ad 100644 --- a/src/var/lib/tyto/program/infos.py +++ b/src/var/lib/tyto/program/infos.py @@ -79,7 +79,8 @@ def tyto(target): ' footer : Create/Show footer HTML config\'s file\n' ' metas : Create/Show metas HTML config\'s file\n' ' navbar : Create/Show navbar config\'s file\n' - ' sidebar : Create/Show sidebar config\'s file\n\n' + ' sidebar : Create/Show sidebar config\'s file\n' + ' stats : Create statistics file in root srv\n\n' '# Examples:\n' ' - Check article\'s syntax: tyto check mysubdir/index.tyto\n' ' - Create default _configs/tyto.sidebar: tyto new sidebar\n' diff --git a/src/var/lib/tyto/program/stats.py b/src/var/lib/tyto/program/stats.py new file mode 100644 index 0000000..6179bf2 --- /dev/null +++ b/src/var/lib/tyto/program/stats.py @@ -0,0 +1,118 @@ +#!/usr/bin/env python3 +# Name: Tyto - Littérateur +# Type: Statistics generator +# Description: Create/Show statistics (wip, publish...) +# file: stats.py +# Folder: /var/lib/tyto/program/ +# By echolib (XMPP: im@echolib.re) +# License: GNU AFFERO GENERAL PUBLIC LICENSE Version 3, 19 November 2007 + +#------------ +# funny stats +#------------ +# lines: +# functions: +# comments: +#---------------------------------------------------------------------- + +#********************************************************************** + +import os, importlib +import args, logs, db, domain, tyto + +sti_anchors = sti_abbrs = sti_links = 0 +sti_images = sti_files = sti_raws = 0 +sti_tags = sti_words = sti_titles = sti_paragraphs = sti_anclink = 0 +sti_strongs = sti_bolds = sti_emphasis = sti_italics = sti_dels = 0 +sti_underlines = sti_cites = sti_customs = sti_icodes = 0 +sti_bcodes = sti_quotes = sti_lists = 0 + +#=======================# +# Manage "stats" option # +#-----------------------# +def manage_stats(process): + domain.domain_needed() + + do = { + 'wip' : loop_articles, + 'www' : loop_articles, + 'show-wip' : count_stats, # NO + 'show_www' : count_stats, # NO + } + + do[args.action](process) + + +def loop_articles(process): + if process == 'wip': + file_stats = '%s%s'%(db.srv_wip, tyto.stats_f) + elif process == 'www': + file_stats = '%s%s'%(db.srv_www, tyto.stats_f) + + # Get databases of wip's articles + for post_db in os.listdir(db.articles_db): + if post_db.endswith('.conf'): + # Load DB + post_db = '%s%s'%(db.articles_db, post_db) + exec(open(post_db).read(),globals()) + args.target = post_src.rsplit('%s/'%db.in_dir)[1] + importlib.reload(db) + + # Check hash status (wip/www) + # wip + if process == 'wip': + if not db.hash_wip: continue + + print(':> [%s] | %s'%(db.title, db.post_src)) + + # Article has changed and could have different stats + if not db.hash_wip == db.hash_chk: + logs.out("9", db.post_src, False) + continue + + count_stats() + + # www + elif process == 'www': + if not db.hash_www: continue + + print("> anchors", sti_anchors, sti_strongs) + logs.out("33", file_stats, False) + +# +# Set Statistics and count +# +def count_stats(): + # Set Statistics + global sti_anchors, sti_abbrs, sti_links + global sti_images, sti_files, sti_raws + global sti_tags, sti_words, sti_titles, sti_paragraphs, sti_anclink + global sti_strongs, sti_bolds, sti_emphasis, sti_italics, sti_dels + global sti_underlines, sti_cites, sti_customs, sti_icodes + global sti_bcodes, sti_quotes, sti_lists + + # Set statistics + sti_anchors = sti_anchors + db.uniq_anchors + sti_abbrs = sti_abbrs + db.uniq_abbrs + sti_links = sti_links + db.uniq_links + sti_images = sti_images + db.uniq_images + sti_files = sti_files + db.uniq_files + sti_raws = sti_raws + db.uniq_raws + sti_tags = sti_tags + db.stat_tags + sti_words = sti_words + db.stat_words + sti_titles = sti_titles + db.stat_titles + sti_paragraphs = sti_paragraphs + db.stat_paragraphs + sti_anclink = sti_anclink + db.stat_anchors + sti_strongs = sti_strongs + db.stat_strongs + sti_bolds = sti_bolds + db.stat_bolds + sti_emphasis = sti_emphasis + db.stat_emphasis + sti_italics = sti_italics + db.stat_italics + sti_dels = sti_dels + db.stat_dels + sti_underlines = sti_underlines + db.stat_underlines + sti_cites = sti_cites + db.stat_cites + sti_customs = sti_customs + db.stat_customs + sti_icodes = sti_icodes + db.stat_icodes + sti_bcodes = sti_bcodes + db.stat_bcodes + sti_quotes = sti_quotes + db.stat_quotes + sti_lists = sti_lists + db.stat_lists + diff --git a/src/var/lib/tyto/program/tyto.py b/src/var/lib/tyto/program/tyto.py index d8aba7e..f45d823 100644 --- a/src/var/lib/tyto/program/tyto.py +++ b/src/var/lib/tyto/program/tyto.py @@ -38,6 +38,7 @@ else: n = 1 Tyto = 'Tyto - Littérateur' Tytogit = 'https://git.a-lec.org/echolib/tyto-litterateur' Tytoweb = 'https://tyto.echolib.re' +stats_f = 'tyto_statoolinfos.conf' # Translations French/English trans = [ diff --git a/src/var/lib/tyto/program/wip.py b/src/var/lib/tyto/program/wip.py index 03533fe..c488234 100644 --- a/src/var/lib/tyto/program/wip.py +++ b/src/var/lib/tyto/program/wip.py @@ -18,7 +18,7 @@ #********************************************************************** import os, re, shutil, importlib -import logs, args, db, tyto, html, domain +import logs, args, db, tyto, html, domain, stats #=========================================# @@ -30,45 +30,18 @@ def manage_wip(target): # Check if can process domain.domain_needed() - wip_article(db.post_src) - return - - # Option 'all' to wip again, based on DB - #--------------------------------------- - if target == 'all': - ask = '' - ask = input(" ├ Wip again all already converted articles ? ") - if not ask in ['y', 'Y']: - return - - # Load domain configuration DB - for post_db in os.listdir(db.articles_db): - if post_db.endswith('.conf'): - # Load DB - post_db = '%s%s'%(db.articles_db, post_db) - exec(open(post_db).read(),globals()) - args.target = post_src.rsplit('%s/'%db.in_dir)[1] - importlib.reload(db) - if not db.hash_wip: - continue - - print(':> [%s] | %s'%(db.title, db.post_src)) - hash_post = tyto.get_filesum(db.post_src, True) # From content file - if hash_post != db.hash_chk: - logs.out("25", db.uri_file, False) - ocontinue - wip_article(db.post_src) - return - + # wip_article(db.post_src) ; return # Force wip without checking # Target is footer, sidebar, navbar, metas #----------------------------------------- if target in args.pass_targets: do = { + 'all' : wip_all, 'sidebar' : html.create_sidebar, 'navbar' : html.create_navbar, 'metas' : html.create_user_metas, - 'footer' : html.create_user_footer + 'footer' : html.create_user_footer, + 'stats' : stats.manage_stats } do[target]('wip') @@ -100,6 +73,37 @@ def manage_wip(target): wip_article(db.uri_file) +#========================================# +# Option 'all' to wip again, based on DB # +#----------------------------------------# +def wip_all(process): + +# if target == 'all': + ask = '' + ask = input(" ├ Wip again all already converted articles ? ") + if not ask in ['y', 'Y']: + return + + # Load domain configuration DB + for post_db in os.listdir(db.articles_db): + if post_db.endswith('.conf'): + # Load DB + post_db = '%s%s'%(db.articles_db, post_db) + exec(open(post_db).read(),globals()) + args.target = post_src.rsplit('%s/'%db.in_dir)[1] + importlib.reload(db) + if not db.hash_wip: + continue + + print(':> [%s] | %s'%(db.title, db.post_src)) + hash_post = tyto.get_filesum(db.post_src, True) # From content file + if hash_post != db.hash_chk: + logs.out("25", db.uri_file, False) + continue + wip_article(db.post_src) + return + + #===================# # Start wip modules # # Set DB # @@ -153,12 +157,9 @@ def wip_article(target): #=================================# # Create string article from file # -# post is string splitted '\n' # -# article is string not splitted # #---------------------------------# def file_to_string(post_file): - global article - global post_header, post_bottom + global article, post_header, post_bottom post_header = post_bottom = '' sep = False @@ -442,7 +443,9 @@ def wip_quotes() : if qline.startswith(tyto.words_tags[10][1]): # Replace closed paragrph with html line qline_html = tyto.words_tags[10][3] - quote_html = '%s\n%s%s'%(quote_html, int(tab_p) * ' ',qline_html) + quote_html = '%s\n%s%s'%( + quote_html, int(tab_p) * ' ', qline_html + ) continue # End of marker quote @@ -591,7 +594,9 @@ def wip_titles(): if line.startswith('#'): hx = line[1] title_cont = line[2: len(line)].lstrip() - title_html = '%s'%(hx, hx, title_cont, hx) + title_html = '%s'%( + hx, hx, title_cont, hx + ) article_temp = article_temp.replace(line, title_html) @@ -696,8 +701,10 @@ def wip_tabs(): if line.startswith(' Date: Fri, 10 Mar 2023 15:49:22 +0100 Subject: [PATCH 183/247] Statoolinfos: indev to create contents file --- src/var/lib/tyto/program/stats.py | 41 +++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 8 deletions(-) diff --git a/src/var/lib/tyto/program/stats.py b/src/var/lib/tyto/program/stats.py index 6179bf2..7f4fe2a 100644 --- a/src/var/lib/tyto/program/stats.py +++ b/src/var/lib/tyto/program/stats.py @@ -25,7 +25,8 @@ sti_images = sti_files = sti_raws = 0 sti_tags = sti_words = sti_titles = sti_paragraphs = sti_anclink = 0 sti_strongs = sti_bolds = sti_emphasis = sti_italics = sti_dels = 0 sti_underlines = sti_cites = sti_customs = sti_icodes = 0 -sti_bcodes = sti_quotes = sti_lists = 0 +sti_bcodes = sti_quotes = sti_lists = sti_articles = 0 + #=======================# # Manage "stats" option # @@ -43,11 +44,19 @@ def manage_stats(process): do[args.action](process) +#==========================# +# Check databases' article # +#--------------------------# def loop_articles(process): + global file_uri, domain_srv + global sti_articles + if process == 'wip': - file_stats = '%s%s'%(db.srv_wip, tyto.stats_f) + file_uri = '%s%s'%(db.srv_wip, tyto.stats_f) + domain_srv = db.domain_wip_url elif process == 'www': - file_stats = '%s%s'%(db.srv_www, tyto.stats_f) + file_uri = '%s%s'%(db.srv_www, tyto.stats_f) + domain_srv = db.domain_www_url # Get databases of wip's articles for post_db in os.listdir(db.articles_db): @@ -70,18 +79,20 @@ def loop_articles(process): logs.out("9", db.post_src, False) continue + sti_articles += 1 count_stats() # www elif process == 'www': if not db.hash_www: continue - print("> anchors", sti_anchors, sti_strongs) - logs.out("33", file_stats, False) + create_stats_file(file_uri) -# -# Set Statistics and count -# + +#================================# +# Set Statistics and count # +# in a loop, from loop_article() # +#--------------------------------# def count_stats(): # Set Statistics global sti_anchors, sti_abbrs, sti_links @@ -115,4 +126,18 @@ def count_stats(): sti_bcodes = sti_bcodes + db.stat_bcodes sti_quotes = sti_quotes + db.stat_quotes sti_lists = sti_lists + db.stat_lists + + +#============================# +# Create stat file in server # +#----------------------------# +def create_stats_file(file_uri): + sti = \ + '# Statistics file created by %s\n'%tyto.Tyto + \ + '# Website: %s\n'%domain_srv + \ + '\n' + \ + 'stats_articles = %d\n'%int(sti_articles) + + tyto.set_file(file_uri, 'New', sti) + logs.out("33", file_uri, False) From 57b401da707abbbfc73b8ba0a3f04c6f00ea987e Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Sat, 11 Mar 2023 11:51:23 +0100 Subject: [PATCH 184/247] stats for statoolinfos: generated on demand with "wip stats". Todo: "publish stats" --- src/var/lib/tyto/program/stats.py | 38 ++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/src/var/lib/tyto/program/stats.py b/src/var/lib/tyto/program/stats.py index 7f4fe2a..f5d1dd4 100644 --- a/src/var/lib/tyto/program/stats.py +++ b/src/var/lib/tyto/program/stats.py @@ -22,7 +22,7 @@ import args, logs, db, domain, tyto sti_anchors = sti_abbrs = sti_links = 0 sti_images = sti_files = sti_raws = 0 -sti_tags = sti_words = sti_titles = sti_paragraphs = sti_anclink = 0 +sti_tags = sti_words = sti_titles = sti_paragraphs = sti_anclinks = 0 sti_strongs = sti_bolds = sti_emphasis = sti_italics = sti_dels = 0 sti_underlines = sti_cites = sti_customs = sti_icodes = 0 sti_bcodes = sti_quotes = sti_lists = sti_articles = 0 @@ -97,7 +97,7 @@ def count_stats(): # Set Statistics global sti_anchors, sti_abbrs, sti_links global sti_images, sti_files, sti_raws - global sti_tags, sti_words, sti_titles, sti_paragraphs, sti_anclink + global sti_tags, sti_words, sti_titles, sti_paragraphs, sti_anclinks global sti_strongs, sti_bolds, sti_emphasis, sti_italics, sti_dels global sti_underlines, sti_cites, sti_customs, sti_icodes global sti_bcodes, sti_quotes, sti_lists @@ -113,12 +113,12 @@ def count_stats(): sti_words = sti_words + db.stat_words sti_titles = sti_titles + db.stat_titles sti_paragraphs = sti_paragraphs + db.stat_paragraphs - sti_anclink = sti_anclink + db.stat_anchors + sti_anclinks = sti_anclinks + db.stat_anchors sti_strongs = sti_strongs + db.stat_strongs sti_bolds = sti_bolds + db.stat_bolds sti_emphasis = sti_emphasis + db.stat_emphasis sti_italics = sti_italics + db.stat_italics - sti_dels = sti_dels + db.stat_dels + sti_dels = sti_dels + db.stat_dels sti_underlines = sti_underlines + db.stat_underlines sti_cites = sti_cites + db.stat_cites sti_customs = sti_customs + db.stat_customs @@ -135,9 +135,35 @@ def create_stats_file(file_uri): sti = \ '# Statistics file created by %s\n'%tyto.Tyto + \ '# Website: %s\n'%domain_srv + \ + '# Generated: %s\n'%tyto.nowdate() + \ '\n' + \ - 'stats_articles = %d\n'%int(sti_articles) - + '# Uniq statistics from articles\' headers\n' + \ + 'stats_articles = %d\n'%int(sti_articles) + \ + 'stats_uniq_anchors = %d\n'%int(sti_anchors) + \ + 'stats_uniq_abbrs = %d\n'%int(sti_abbrs) + \ + 'stats_uniq_links = %d\n'%int(sti_links) + \ + 'stats_uniq_images = %d\n'%int(sti_images) + \ + 'stats_uniq_files = %d\n'%int(sti_files) + \ + 'stats_uniq_raws = %d\n'%int(sti_raws) + \ + '\n' + \ + '# Statistics from articles\' content\n' + \ + 'stats_tags = %d\n'%int(sti_tags) + \ + 'stats_words = %d\n'%int(sti_words) + \ + 'stats_titles = %d\n'%int(sti_titles) + \ + 'stats_paragraphs = %d\n'%int(sti_paragraphs) + \ + 'stats_link_anchors = %d\n'%int(sti_anclinks) + \ + 'stats_strongs = %d\n'%int(sti_strongs) + \ + 'stats_bolds = %d\n'%int(sti_bolds) + \ + 'stats_emphasis = %d\n'%int(sti_emphasis) + \ + 'stats_italics = %d\n'%int(sti_italics) + \ + 'stats_dels = %d\n'%int(sti_dels) + \ + 'stats_underlines = %d\n'%int(sti_underlines) + \ + 'stats_cites = %d\n'%int(sti_cites) + \ + 'stats_customs = %d\n'%int(sti_customs) + \ + 'stats_icodes = %d\n'%int(sti_icodes) + \ + 'stats_bcodes = %d\n'%int(sti_bcodes) + \ + 'stats_quotes = %d\n'%int(sti_quotes) + \ + 'stats_lists = %d\n'%int(sti_lists) tyto.set_file(file_uri, 'New', sti) logs.out("33", file_uri, False) From 35794a8ae884bc788e7a4fe9167511eda438b61e Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Sat, 11 Mar 2023 17:56:11 +0100 Subject: [PATCH 185/247] stats for statoolinfos. wip/publish OK. Fix db check for publish --- src/var/lib/tyto/program/publish.py | 9 ++--- src/var/lib/tyto/program/stats.py | 52 ++++++++++++++--------------- src/var/lib/tyto/program/tyto.py | 6 ++-- 3 files changed, 34 insertions(+), 33 deletions(-) diff --git a/src/var/lib/tyto/program/publish.py b/src/var/lib/tyto/program/publish.py index bebea51..e6dfdce 100644 --- a/src/var/lib/tyto/program/publish.py +++ b/src/var/lib/tyto/program/publish.py @@ -18,7 +18,7 @@ #********************************************************************** import os, sys, shutil, importlib -import logs, args, db, html, tyto, domain +import logs, args, db, html, tyto, domain, stats #==============================# @@ -39,7 +39,8 @@ def manage_publish(target): 'navbar' : html.create_navbar, 'metas' : html.create_user_metas, 'footer' : html.create_user_footer, - 'template' : create_template + 'template' : create_template, + 'stats' : stats.manage_stats } do[target]('www') @@ -63,9 +64,9 @@ def manage_publish(target): if db.hash_wip: # wip and current article have different hash if db.hash_post != db.hash_chk: - logs.out("25", db.uri_file, False) + logs.out("9", db.uri_file, False) err_pub = True - elif db.hash_post != db.hash_wip: + elif db.hash_wip != db.hash_chk: logs.out("30", db.uri_file, False) err_pub = True diff --git a/src/var/lib/tyto/program/stats.py b/src/var/lib/tyto/program/stats.py index f5d1dd4..9263c83 100644 --- a/src/var/lib/tyto/program/stats.py +++ b/src/var/lib/tyto/program/stats.py @@ -36,7 +36,7 @@ def manage_stats(process): do = { 'wip' : loop_articles, - 'www' : loop_articles, + 'publish' : loop_articles, 'show-wip' : count_stats, # NO 'show_www' : count_stats, # NO } @@ -60,33 +60,33 @@ def loop_articles(process): # Get databases of wip's articles for post_db in os.listdir(db.articles_db): - if post_db.endswith('.conf'): - # Load DB - post_db = '%s%s'%(db.articles_db, post_db) - exec(open(post_db).read(),globals()) - args.target = post_src.rsplit('%s/'%db.in_dir)[1] - importlib.reload(db) + if not post_db.endswith('.conf'): continue + + # Load DB + post_db = '%s%s'%(db.articles_db, post_db) + exec(open(post_db).read(),globals()) + args.target = post_src.rsplit('%s/'%db.in_dir)[1] + importlib.reload(db) + + # Check hash status (wip/www) + if process == 'wip': hash_srv = db.hash_wip + elif process == 'www': hash_srv = db.hash_www + + if not hash_srv: continue - # Check hash status (wip/www) - # wip - if process == 'wip': - if not db.hash_wip: continue - - print(':> [%s] | %s'%(db.title, db.post_src)) - - # Article has changed and could have different stats - if not db.hash_wip == db.hash_chk: - logs.out("9", db.post_src, False) - continue - - sti_articles += 1 - count_stats() + print(':> [%s] | %s'%(db.title, db.post_src)) + + # Article has changed and could have different stats + if hash_srv != db.hash_chk: + logs.out("9", db.post_src, False) + continue + + sti_articles += 1 + count_stats() - # www - elif process == 'www': - if not db.hash_www: continue - - create_stats_file(file_uri) + # Create file if article + if sti_articles > 0: create_stats_file(file_uri) + else: logs.out("28", '(%s stats)'%process, True) #================================# diff --git a/src/var/lib/tyto/program/tyto.py b/src/var/lib/tyto/program/tyto.py index f45d823..6acd320 100644 --- a/src/var/lib/tyto/program/tyto.py +++ b/src/var/lib/tyto/program/tyto.py @@ -21,11 +21,11 @@ import os, sys, subprocess, locale, base64, datetime, shutil from hashlib import blake2b import db, logs -domain_active = False -home_dir = os.path.expanduser('~') +domain_active = False +home_dir = os.path.expanduser('~') try: in_dir = os.getcwd() except: logs.out("13", '', True) -domain_conf = in_dir +domain_conf = in_dir # Set translations: french, english #---------------------------------- From 532c63dbdd0e96d9bbd2dfca5b1f1b769732d46b Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Sun, 12 Mar 2023 16:19:34 +0100 Subject: [PATCH 186/247] stats: added show-wip/show-www argument to read srv pages statistics --- src/var/lib/tyto/program/show.py | 37 +++++++++++++++----------- src/var/lib/tyto/program/stats.py | 44 ++++++++++++++++++++----------- 2 files changed, 50 insertions(+), 31 deletions(-) diff --git a/src/var/lib/tyto/program/show.py b/src/var/lib/tyto/program/show.py index cbed2c0..3f9e839 100644 --- a/src/var/lib/tyto/program/show.py +++ b/src/var/lib/tyto/program/show.py @@ -18,7 +18,7 @@ #********************************************************************** import os, importlib -import args, db, logs, domain, tyto, check +import args, db, logs, domain, tyto, check, stats #======================# @@ -56,22 +56,29 @@ def manage_show(target): } elif args.action in actions_wip: - do = { - "domain" : db.domain_conf, - "footer" : db.wip_footer, - "metas" : db.wip_metas, - "navbar" : db.wip_navbar, - "sidebar" : db.wip_sidebar - } + if target == 'stats': + stats.manage_stats('wip') + return + + do = { + "domain" : db.domain_conf, + "footer" : db.wip_footer, + "metas" : db.wip_metas, + "navbar" : db.wip_navbar, + "sidebar" : db.wip_sidebar + } elif args.action in actions_www: - do = { - "domain" : db.domain_conf, - "footer" : db.www_footer, - "metas" : db.www_metas, - "navbar" : db.www_navbar, - "sidebar" : db.www_sidebar - } + if target == 'stats': + stats.manage_stats('www') + return + do = { + "domain" : db.domain_conf, + "footer" : db.www_footer, + "metas" : db.www_metas, + "navbar" : db.www_navbar, + "sidebar" : db.www_sidebar + } # Target is a post uri #--------------------- diff --git a/src/var/lib/tyto/program/stats.py b/src/var/lib/tyto/program/stats.py index 9263c83..229f3a0 100644 --- a/src/var/lib/tyto/program/stats.py +++ b/src/var/lib/tyto/program/stats.py @@ -18,14 +18,14 @@ #********************************************************************** import os, importlib -import args, logs, db, domain, tyto +import args, logs, db, domain, tyto, show sti_anchors = sti_abbrs = sti_links = 0 sti_images = sti_files = sti_raws = 0 sti_tags = sti_words = sti_titles = sti_paragraphs = sti_anclinks = 0 sti_strongs = sti_bolds = sti_emphasis = sti_italics = sti_dels = 0 sti_underlines = sti_cites = sti_customs = sti_icodes = 0 -sti_bcodes = sti_quotes = sti_lists = sti_articles = 0 +sti_bcodes = sti_quotes = sti_lists = 0 #=======================# @@ -34,20 +34,6 @@ sti_bcodes = sti_quotes = sti_lists = sti_articles = 0 def manage_stats(process): domain.domain_needed() - do = { - 'wip' : loop_articles, - 'publish' : loop_articles, - 'show-wip' : count_stats, # NO - 'show_www' : count_stats, # NO - } - - do[args.action](process) - - -#==========================# -# Check databases' article # -#--------------------------# -def loop_articles(process): global file_uri, domain_srv global sti_articles @@ -57,6 +43,23 @@ def loop_articles(process): elif process == 'www': file_uri = '%s%s'%(db.srv_www, tyto.stats_f) domain_srv = db.domain_www_url + + do = { + 'wip' : loop_articles, + 'publish' : loop_articles, + 'show-wip' : show_stats, + 'show-www' : show_stats + } + + do[args.action](process) + + +#==========================# +# Check databases' article # +#--------------------------# +def loop_articles(process): + global sti_articles + sti_articles = 0 # Get databases of wip's articles for post_db in os.listdir(db.articles_db): @@ -72,6 +75,7 @@ def loop_articles(process): if process == 'wip': hash_srv = db.hash_wip elif process == 'www': hash_srv = db.hash_www + # Now generic for wip/www if not hash_srv: continue print(':> [%s] | %s'%(db.title, db.post_src)) @@ -135,6 +139,7 @@ def create_stats_file(file_uri): sti = \ '# Statistics file created by %s\n'%tyto.Tyto + \ '# Website: %s\n'%domain_srv + \ + '# File: %s\n'%file_uri + \ '# Generated: %s\n'%tyto.nowdate() + \ '\n' + \ '# Uniq statistics from articles\' headers\n' + \ @@ -167,3 +172,10 @@ def create_stats_file(file_uri): tyto.set_file(file_uri, 'New', sti) logs.out("33", file_uri, False) + + +#======================================# +# Show statistics from pages on server # +#--------------------------------------# +def show_stats(process): + show.read_lines(file_uri) From 04303d8b2becd13017cb6908885dcee183070931 Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Sun, 12 Mar 2023 16:21:29 +0100 Subject: [PATCH 187/247] minor changes in show.py --- src/var/lib/tyto/program/show.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/var/lib/tyto/program/show.py b/src/var/lib/tyto/program/show.py index 3f9e839..5d5b4a3 100644 --- a/src/var/lib/tyto/program/show.py +++ b/src/var/lib/tyto/program/show.py @@ -72,6 +72,7 @@ def manage_show(target): if target == 'stats': stats.manage_stats('www') return + do = { "domain" : db.domain_conf, "footer" : db.www_footer, From 78b4af691404e4ec0ee1ed5e41ff436a4bdefca2 Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Mon, 13 Mar 2023 12:53:26 +0100 Subject: [PATCH 188/247] added RSS 2.0 at publish. RSS link in default footer. Some changes --- src/var/lib/tyto/program/db.py | 2 + src/var/lib/tyto/program/domain.py | 89 +++++++++++++++++---------- src/var/lib/tyto/program/html.py | 13 ++-- src/var/lib/tyto/program/logs.py | 2 +- src/var/lib/tyto/program/publish.py | 7 ++- src/var/lib/tyto/program/rss.py | 95 +++++++++++++++++++++++++++++ src/var/lib/tyto/program/stats.py | 2 +- src/var/lib/tyto/program/tyto.py | 4 +- 8 files changed, 168 insertions(+), 46 deletions(-) create mode 100644 src/var/lib/tyto/program/rss.py diff --git a/src/var/lib/tyto/program/db.py b/src/var/lib/tyto/program/db.py index c07810b..3a62151 100644 --- a/src/var/lib/tyto/program/db.py +++ b/src/var/lib/tyto/program/db.py @@ -100,6 +100,8 @@ domain_values = \ 'www_sidebar', 'www_metas', 'www_footer', + 'www_rss', + 'domain_rss', 'domain_footer_about', 'domain_active', ) diff --git a/src/var/lib/tyto/program/domain.py b/src/var/lib/tyto/program/domain.py index 9aa95b1..aad5529 100644 --- a/src/var/lib/tyto/program/domain.py +++ b/src/var/lib/tyto/program/domain.py @@ -193,10 +193,53 @@ def create_domain(target): 'www_navbar = "%snavbar.html"\n'%srv_www_tpl + \ 'www_sidebar = "%ssidebar.html"\n'%srv_www_tpl + \ 'www_metas = "%smetas.html"\n'%srv_www_tpl + \ - 'www_footer = "%sfooter.html"\n'%srv_www_tpl + 'www_footer = "%sfooter.html"'%srv_www_tpl tyto.set_file(db.domain_conf, False, set_f) + + # Get logo's website + #------------------- + try: domain_logo = db.domain_logo + except: domain_logo = 'logo.png' + ask = '' + try: + ask = input(' ├ logo filename ? {%s} '%domain_logo) + except KeyboardInterrupt: + print('') + logs.out("255", '', True) + + if ask: domain_logo = ask + + set_f = 'wip_logo = "%s%s"\n'%(srv_wip_tpl, domain_logo) + \ + 'www_logo = "%s%s"'%(srv_www_tpl, domain_logo) + tyto.set_file(db.domain_conf, False, set_f) + + + # RSS/Atom filename + #------------------ + try: domain_rss = db.domain_rss + except: domain_rss = 'rss.xml' + + ask = '' + try: + ask = input(' ├ Atom/RSS filename ? {%s} '%domain_rss) + except KeyboardInterrupt: + print('') + logs.out("255", '', True) + + if ask: + www_rss = ask + + set_f = 'www_rss = "%s/www/%s"\n'%(root_srv_dom, domain_rss) + \ + '\n# Domain user\'s settings\n' + \ + 'domain_logo = "%s"\n'%domain_logo + \ + 'domain_rss = "%s"'%domain_rss + + + tyto.set_file(db.domain_conf, False, set_f) + + # Get title domain #----------------- try: domain_title = db.domain_title @@ -213,8 +256,7 @@ def create_domain(target): if '"' in domain_title: domain_title = domain_title.replace('"', '') - set_f = '# Domain user\'s settings\n' + \ - 'domain_title = "%s"'%domain_title + set_f = 'domain_title = "%s"'%domain_title tyto.set_file(db.domain_conf, False, set_f) @@ -319,27 +361,6 @@ def create_domain(target): tyto.set_file(db.domain_conf, False, set_f) - # Get logo's website - #------------------- - try: domain_logo = db.domain_logo - except: domain_logo = 'logo.png' - - ask = '' - try: - ask = input(' ├ logo filename ? {%s} '%domain_logo) - except KeyboardInterrupt: - print('') - logs.out("255", '', True) - - if ask: domain_logo = ask - - set_f = 'domain_logo = "%s"\n'%domain_logo + \ - 'wip_logo = "%s%s"\n'%(srv_wip_tpl, domain_logo) + \ - 'www_logo = "%s%s"\n'%(srv_www_tpl, domain_logo) - tyto.set_file(db.domain_conf, False, set_f) - - - # Get License domain #------------------- try: domain_license = db.domain_license @@ -419,7 +440,7 @@ def create_domain(target): set_f = 'domain_termsurl = "%s"'%domain_termsurl tyto.set_file(db.domain_conf, False, set_f) - + # CSS Prefix #----------- @@ -520,6 +541,7 @@ def create_domain(target): set_f = 'sidebar_items = %d'%int(sidebar_items) tyto.set_file(db.domain_conf, False, set_f) + # Create domain_footer_about (user custom description in footer) #--------------------------------------------------------------- try: @@ -609,7 +631,6 @@ def create_sidebar(option): # Create new file, or ask if exists with option = 'reset' ask = ' ├ Reset sidebar configuration file ? ' - log = ' ├ Create source file: %s'%db.sidebar_load res = '' if os.path.exists(db.sidebar_load): try: @@ -669,7 +690,7 @@ def create_sidebar(option): tyto.set_file(db.sidebar_load, 'new', sdb_load) tyto.create_db_load(db.sidebar_load, db.sidebar_load_db) - print(log) + logs.out("33", db.sidebar_load, False) #=============================# @@ -686,7 +707,6 @@ def create_navbar(option): # Create new file, or ask if exists ask = ' ├ Reset navbar configuration file ? ' - log = ' ├ Create source file: %s'%db.navbar_load res = '' if os.path.exists(db.navbar_load): try: @@ -747,7 +767,7 @@ def create_navbar(option): tyto.set_file(db.navbar_load, 'new', nvb_load) tyto.create_db_load(db.navbar_load, db.navbar_load_db) - print(log) + logs.out("33", db.navbar_load, False) #========================# @@ -810,7 +830,6 @@ def create_metas(option): # Create new default file, or ask if exists ask = ' ├ Reset metas configuration file ? ' - log = ' ├ Create source file: %s'%db.metas_load res = '' if os.path.exists(db.metas_load): try: @@ -822,7 +841,7 @@ def create_metas(option): tyto.set_file(db.metas_load, 'new', metas_tags) tyto.create_db_load(db.metas_load, db.metas_load_db) - print(log) + logs.out("33", db.metas_load, False) #=============================# @@ -839,7 +858,6 @@ def create_footer(option): # Create new default file, or ask if exists ask = ' ├ Reset footer configuration file ? ' - log = ' ├ Create source file: %s'%db.footer_load res = '' if os.path.exists(db.footer_load): try: @@ -955,6 +973,11 @@ def create_footer(option): tyto.trans[14][tyto.n] ) + \ ' \n' + \ + '
  • \n' + \ + ' RSS 2.0\n' + \ + '
  • \n' + \ ' \n' + \ ' \n' + \ ' \n' + \ '\n' + \ ' \n' + \ @@ -187,7 +202,7 @@ def create_main_page(target, article_bottom): #--------------------------------------------# def create_html_infos_section(process): # Need to reload the DB to get last time updated - exec(open(db.post_db).read(), globals()) + exec(open(db.config).read(), globals()) global post_pub, meta_pub, date_raw if process == 'wip': @@ -205,7 +220,7 @@ def create_html_infos_section(process): # Show source code in article-infos if True in DB post_code = '' - if db.article_code: + if dom.article_code: # Set HTML post_code = \ ' ' + \ @@ -213,7 +228,7 @@ def create_html_infos_section(process): os.path.basename(db.short_src), tyto.trans[21][tyto.n], tyto.trans[3][tyto.n] - ) + ) + \ ' ' @@ -248,26 +263,24 @@ def create_html_infos_section(process): # Create HTML sidebar from file tyto.sidebar # #--------------------------------------------# def create_sidebar(option): - domain.domain_needed + dom.valid() try: - db.sidebar_load - if not tyto.exists(db.sidebar_load): - logs.out("1", db.sidebar_load, True) + if not tyto.exists(dom.sidebar_f): + logs.out("1", dom.sidebar_f, True) except: - logs.out("1", 'Sidebar load file', True) + logs.out("1", 'Sidebar ?', True) try: - db.sidebar_items - if int(db.sidebar_items) > 16: db.sidebar_items = 6 + if int(dom.sidebar_items) > 16: db.sidebar_items = 6 except: db.sidebar_items = 6 pub_opts = ('www', 'pub') - if option == 'wip': target = db.wip_sidebar - elif option == 'www': target = db.www_sidebar - elif option == 'pub': target = db.www_sidebar + if option == 'wip': target = dom.wip_sidebar_f + elif option == 'www': target = dom.www_sidebar_f + elif option == 'pub': target = dom.www_sidebar_f # If content in sidebar, go True sidebar_new = False @@ -285,8 +298,8 @@ def create_sidebar(option): counter = 0 nolines = ('#', '/') - sidebar_title = db.sidebar_title - sidebar_lines = open(db.sidebar_load, 'r').read() + sidebar_title = dom.sidebar_title + sidebar_lines = open(dom.sidebar_f, 'r').read() for line in sidebar_lines.rsplit('\n'): if not line or line.startswith(nolines): continue @@ -296,14 +309,14 @@ def create_sidebar(option): # Get full article URI and check if exists sidebar_has = True - f_uri = '%s%s'%(db.domain_articles, line) + f_uri = '%s%s'%(dom.articles_d, line) if not tyto.exists(f_uri): logs.out("24", f_uri, False) continue # Get Hash from uri to get db file hash_uri = tyto.get_filesum(f_uri, False) - db_uri = '%s%s.conf'%(db.articles_db, hash_uri) + db_uri = '%s%s.config'%(dom.articles_db_d, hash_uri) if not tyto.exists(db_uri): logs.out('25', line, False) continue @@ -332,9 +345,9 @@ def create_sidebar(option): # Count: no more than max configured items counter += 1 - if counter > db.sidebar_items: + if counter > dom.sidebar_items: logs.out("31", '(%s): %s "%s"'%( - db.sidebar_items, line, title), + dom.sidebar_items, line, title), False ) continue diff --git a/src/var/lib/tyto/program/show.py b/src/var/lib/tyto/program/show.py index 3d571a8..b8febea 100644 --- a/src/var/lib/tyto/program/show.py +++ b/src/var/lib/tyto/program/show.py @@ -1,11 +1,28 @@ #!/usr/bin/env python3 -# Name: Tyto - Littérateur -# Type: Command arguments 'show', 'showdb' manager -# Description: manage 'show' and 'showdb' from command action argument -# file: show.py -# Folder: /var/lib/tyto/program/ -# By echolib (XMPP: im@echolib.re) -# License: GNU AFFERO GENERAL PUBLIC LICENSE Version 3, 19 November 2007 +# 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 show*/edit* arguments. +# Read or edit file from [target] argument +# File: /var/lib/tyto/program/show.py +#---------------------------------------------------------------------- #------------ # funny stats @@ -17,9 +34,64 @@ #********************************************************************** -import os, sys, importlib +import os, sys, locale, importlib import args, lang, logs, dom, db, form, tyto, check, stats +# load locale translation +trans_dir = '/var/lib/tyto/translations' +sys.path.insert(0, trans_dir) + +# System language +try: lang_sys = locale.getdefaultlocale()[0].split('_')[0] +except: lang_sys = 'en' + +# Get default system language +# or set "en" (english) if no translation file +try: + lang_site = lang_sys + os.path.exists('%s/site_%s.py'%(trans_dir, lang_site)) +except: + lang_site = 'en' + +# Set language site/form from configuration domain +# or set default english if not known +try: + dom.exists + lang_site = dom.lang_site + os.path.exists('%s/site_%s.py'%(trans_dir, lang_site)) + tr = importlib.import_module('site_%s'%lang_site, package=None) +except: + tr = importlib.import_module('site_%s'%lang_site, package=None) + + +#========================# +# Read lines from a file # +# alone: True/False # +#------------------------# +def read_lines(f, alone): + if not f: return + if not tyto.exists(f): logs.out("1", f, True) + + datas = open(f).read() + + # Align content line, after line number + ln_datas = len(datas.splitlines()) + 1 + sp_max = len(str(ln_datas)) + + print(' ├', f) + print(' ├─%s─┐'%(sp_max * '─')) + for ln, line in enumerate(datas.rsplit('\n'), 1): + sp = sp_max - len(str(ln)) + print(' │ %s %s│ %s'%(ln, int(sp) * " ", line)) + + # Ends for show. False should be for form + if alone: decor = '└' + else: decor = '├' + print(' %s─%s─┘'%(decor, sp_max * '─')) + + dom.valid() + + #======================# # From command line: # # - 'showdb' / 'show' # @@ -28,130 +100,126 @@ import args, lang, logs, dom, db, form, tyto, check, stats # final html, db, load # #----------------------# def manage(target): - # Domain must be valid if not dom.exists: logs.out("10", '', True) - if not target == "domain": dom.valid() + dom.valid() - do = False actions_read = ('show', 'show-about', 'show-db', 'show-wip', 'show-www') actions_edit = ('edit', 'edit-about', 'edit-db', 'edit-wip', 'edit-www') + post_src = post_db = post_wip = post_www = False - actions_about= ('show-about', 'edit-about') - actions_wip = ('show-wip', 'edit-wip') - actions_www = ('show-www', 'edit-www') - - actions_post = ('show', 'edit') - actions_db = ('show-db', 'edit-db') - - # Target is not a post uri (sidebar, navbar, metas, footer) - #---------------------------------------------------------- - if target in args.pass_targets: - if args.action in actions_post: - do = { - "domain" : dom.config, - "footer" : dom.footer_f, - "metas" : dom.metas_f, - "navbar" : dom.navbar_f, - "sidebar" : dom.sidebar_f - } - - elif args.action in actions_about: - do = { - "footer" : dom.footer_about_f - } - - elif args.action in actions_wip: - if target == 'stats': - stats.manage_stats('wip') - return + # Set file from post DB when target is an article + #------------------------------------------------ + try: post_src = db.uri_file + except: pass - do = { - "domain" : dom.config, - "footer" : dom.wip_footer_f, - "metas" : dom.wip_metas_f, - "navbar" : dom.wip_navbar_f, - "sidebar" : dom.wip_sidebar_f - } + if post_src: + target = "post" + try: post_db = db.config + except: pass - elif args.action in actions_www: - if target == 'stats': - stats.manage_stats('www') - return - - do = { - "domain" : dom.config, - "footer" : dom.www_footer_f, - "metas" : dom.www_metas_f, - "navbar" : dom.www_navbar_f, - "sidebar" : dom.www_sidebar_f - } - - # Target is a post uri - #--------------------- - elif db.uri_file: + try: post_wip = db.post_wip + except: pass - # Get hash when edit, and ask if file changed + try: post_www = db.post_www + except: pass + + # Except for show-about > Show post DB + if args.action == "show-about": + target = 'post' + + # When edit article, get src hash if args.action == "edit": curr_hash = tyto.get_filesum(db.uri_file, True) - - if args.action in actions_post: - target = "post" - do = {"post" : db.uri_file} - - # Post has database - elif db.exists: - do = { - "db" : db.config, - "wip" : db.post_wip, - "www" : db.post_www - } - if args.action in actions_wip: target = "wip" - elif args.action in actions_www: target = "www" - elif args.action in actions_db: target = "db" + + + # Convert command action to do[] + # as edit* &nd show* [action] have same target file + actions = \ + { + 'show' : 'src', + 'edit' : 'src', + 'post' : 'src', + 'show-db' : 'db', + 'edit-db' : 'db', + 'show-about' : 'about', + 'edit-about' : 'about', + 'show-wip' : 'wip', + 'edit-wip' : 'wip', + 'show-www' : 'www', + 'edit-www' : 'www' + } + action = actions[args.action] - #print('> show: target', target) - - if not do: - if not db.post: sys.exit(1) - - - # Read lines of, or edit file - if args.action in actions_read: read_lines(do[target]) - elif args.action in actions_edit: tyto.edit_file(do[target]) + # Set target file from "new" [action] + do = \ + { + 'src' : { + 'domain' : dom.config, + 'footer' : dom.footer_f, + 'metas' : dom.metas_f, + 'navbar' : dom.navbar_f, + 'sidebar' : dom.sidebar_f, + 'post' : post_src + }, + 'db' : { + 'domain' : dom.config, + 'footer' : dom.footer_f, + 'metas' : dom.metas_f, + 'navbar' : dom.navbar_f, + '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, + 'metas' : dom.wip_metas_f, + 'navbar' : dom.wip_navbar_f, + 'sidebar' : dom.wip_sidebar_f, + 'post' : post_wip + }, + 'www' : { + 'domain' : dom.config, + 'footer' : dom.www_footer_f, + 'metas' : dom.www_metas_f, + 'navbar' : dom.www_navbar_f, + 'sidebar' : dom.www_sidebar_f, + 'post' : post_www + }, + } - # After editing article, if change, ask to check again - if args.action == "edit" and not args.pass_targets: - new_hash = tyto.get_filesum(db.uri_file, True) + # Read or edit file, according to legacy args.action + try: + file = do[action][target] + if args.action in actions_read: + read_lines(file, True) + elif args.action in actions_edit: + tyto.edit_file(file) + except: + logs.out("28", '%s + %s'%(action, target), True) + + + # If edit article and hash changed, ask to check + if args.action == "edit" and post_src: + new_hash = tyto.get_filesum(post_src, True) if curr_hash != new_hash: ask = '' - try: ask = input('-> Check your changes ? ') + try: ask = input(' ├ %s%s '%(tr.post_chg, tr.q)) except KeyboardInterrupt: print('') logs.out("255", '', True) - if not ask in ['y', 'Y']: + if not ask in form.answer_yes: logs.out("255", '', True) # Reload post DB (if edited article, and check it if ask "y") importlib.reload(db) - check.manage_check(db.uri_file) - - -#============================================# -# Generic function to read lines from a file # -#--------------------------------------------# -def read_lines(f): - if not f: return # Maybe - if not tyto.exists(f): logs.out("1", f, True) + check.manage(post_src) - datas = open(f).read() - - # Align content line, after line number - ln_datas = len(datas.splitlines()) + 1 - sp_max = len(str(ln_datas)) - - for ln, line in enumerate(datas.rsplit('\n'), 1): - sp = sp_max - len(str(ln)) - print(' │ %s %s│ %s'%(ln, int(sp) * " ", line)) - - dom.valid() diff --git a/src/var/lib/tyto/program/tyto.py b/src/var/lib/tyto/program/tyto.py index 295f4cf..c3b01f2 100644 --- a/src/var/lib/tyto/program/tyto.py +++ b/src/var/lib/tyto/program/tyto.py @@ -135,14 +135,22 @@ words_tags = [ ('-(', '-)', '-(', '-)', 'lists', 't') ] +# Tags that do not need to be paired +#----------------------------------- +single_tags = [ +('|', '
    '), # New Line +('->', '') # Anchors +] + # When counting words, do no count line starting with: nolinewords = \ ( -'((', '))', -'{{', ']]', -'{{', '}}', -'->', '|', -'_image:', '_taw:' +words_tags[10][0], words_tags[10][1], # paragraphs +words_tags[11][0], words_tags[11][1], # quotes +words_tags[12][0], words_tags[12][1], # bcodes +words_tags[13][0], words_tags[13][1], # lists +single_tags[0][0], single_tags[1][0], # New line, anchor +'_%s:'%opt_header_tags[1], '_%s:'%opt_header_tags[4] # _image:, _raw: ) # warning symbols (Check if paired) @@ -156,16 +164,9 @@ tpl_tags = [ ] -# Tags that do not need to be paired -#----------------------------------- -single_tags = [ -('|', '
    '), # New Line -('->', '') # Anchors -] - # Markers for lists, to check in list content #-------------------------------------------- -markers_lists = ('+', '=', ' ') +markers_lists = ('+', '=', ' ', '#') # Tags used for titles #--------------------- @@ -335,23 +336,34 @@ def protect_bcodes_quotes(process, post_bottom): b64_quote = b64('Encode', quote, 'Q64.', '.Q64') line = b64_quote + ''' + # Remove coemments and empty lines for wip if not in_quote and not in_bcode: - if not line: continue + if not line: + continue if line.startswith('#') and not line.startswith(titles_tags): continue - + ''' # Counters and keep tags for check process #----------------------------------------- if process == "check": if in_bcode and not start_bcode \ or in_quote and not start_quote : - continue + line = '#-Protectedline-' # Set new article content for wip process #---------------------------------------- elif process == "wip": + # Remove empty line and comments + if not in_quote and not in_bcode: + if not line: + continue + elif line.startswith('#') \ + and not line.startswith(titles_tags): + continue + # bcode convertion to base64 if in_bcode: # Convert lines to b64 @@ -369,7 +381,6 @@ def protect_bcodes_quotes(process, post_bottom): #---------------- # check: remove quote/bcode, keep tags # wip: replace close tag with quote/bcode (keep in open tag) - if not line: continue if not protect_article: protect_article = line else: protect_article = '%s\n%s'%(protect_article, line) @@ -498,34 +509,43 @@ def replace_in_db(post_db, process, hash_post): # Copy files used by article to srv # #-----------------------------------# def files_to_srv(server): + import db for uri in db.uris: + + # Extract Directories from uri file + d_in = uri.split("/")[-1] + d_in = uri.rsplit(d_in)[0] + # Destination file to server - f_src = '%s%s'%(db.domain_articles, uri) - if server == 'wip': f_dst = '%s%s'%(db.srv_wip, uri) - elif server == 'www': f_dst = '%s%s'%(db.srv_www, uri) + f_src = '%s%s'%(dom.articles_d[:-1], uri) + if server == 'wip': + f_dst = '%s%s'%(dom.srv_wip[:-1], uri) + d_dst = '%s%s'%(dom.srv_wip[:-1], d_in) + elif server == 'www': + f_dst = '%s%s'%(dom.srv_www[:-1], uri) + d_dst = '%s%s'%(dom.srv_www[:-1], d_in) # Create folder and subfolders - f_uri = uri.split("/")[-1] - f_uri = uri.rsplit(f_uri)[0] try: - os.makedirs('%s%s'%(f_dst, f_uri), exist_ok=True) + os.makedirs(d_dst, exist_ok=True) + logs.out("33", d_dst, False) except: - logs.out('4', '%s%s'%(f_dst, f_uri), True) + logs.out('4', d_dst, True) try: shutil.copy2(f_src, f_dst) - logs.out("33", f_dst, False) + logs.out("32", f_dst, False) except: logs.out('4', f_dst, True) - if db.article_code: - if server == "wip": base_srv = db.srv_wip - elif server == "www": base_srv = db.srv_www + if dom.article_code: + if server == "wip": base_srv = dom.srv_wip + elif server == "www": base_srv = dom.srv_www f_dst = "%s%s"%(base_srv, db.short_src) try: shutil.copy2(db.post_src, f_dst) - logs.out("33", f_dst, False) + logs.out("32", f_dst, False) except: logs.out('4', f_dst, True) diff --git a/src/var/lib/tyto/program/wip.py b/src/var/lib/tyto/program/wip.py index 43ac736..6d84b9a 100644 --- a/src/var/lib/tyto/program/wip.py +++ b/src/var/lib/tyto/program/wip.py @@ -1,11 +1,30 @@ #!/usr/bin/env python3 -# Name: Tyto - Littérateur -# Type: Convert article to HTML -# Description: Converters from Source to HTML -# file: wip.py -# Folder: /var/lib/tyto/program/ -# By echolib (XMPP: im@echolib.re) -# License: GNU AFFERO GENERAL PUBLIC LICENSE Version 3, 19 November 2007 +# Tyto - Littérateur +# +# Copyright (C) 2023 Cyrille Louarn +# Copyright (C) 2023 Adrien Bourmault +# +# 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) +# XMPP: neox (neox@a-lec.org) +# +# Description: Manage 'wip' argument +# Convert article to HTML from Tyto's format markers +# File: /var/lib/tyto/program/wip.py +#---------------------------------------------------------------------- #------------ # funny stats @@ -17,10 +36,36 @@ #********************************************************************** -import os, re, sys, shutil, importlib +import os, re, sys, locale, shutil, importlib, time from pathlib import Path -import args, logs, dom, db, tyto, html, form, stats +import args, logs, lang, dom, db, tyto, html, form, stats + +# load locale translation +trans_dir = '/var/lib/tyto/translations' +sys.path.insert(0, trans_dir) + +# System language +try: lang_sys = locale.getdefaultlocale()[0].split('_')[0] +except: lang_sys = 'en' + +# Get default system language +# or set "en" (english) if no translation file +try: + lang_site = lang_sys + os.path.exists('%s/site_%s.py'%(trans_dir, lang_site)) +except: + lang_site = 'en' + +# Set language site/form from configuration domain +# or set default english if not known +try: + dom.exists + lang_site = dom.lang_site + os.path.exists('%s/site_%s.py'%(trans_dir, lang_site)) + tr = importlib.import_module('site_%s'%lang_site, package=None) +except: + tr = importlib.import_module('site_%s'%lang_site, package=None) #=========================================# @@ -55,10 +100,10 @@ def manage_wip(target): # Per article with target #------------------------ # Exit with these conditions - if not target: logs.out("5", '', True) - if not db.post_exists: sys.exit(1) - if not db.db_exists: logs.out("25", db.uri_file, True) - if db.old_chk: logs.out("9", db.uri_file, True) + if not target: logs.out("5", '', True) + if not db.exists: sys.exit(1) + if not db.config: logs.out("25", db.uri_file, True) + if db.old_chk: logs.out("9", db.uri_file, True) # Article has changed or wip file missing if db.old_wip or not db.file_wip: @@ -68,12 +113,14 @@ def manage_wip(target): else: logs.out("19", db.date_wip, False) try: - res = input(' ├ Create new wip page ? ') + res = input(' ├ [%s] %s%s '%(db.title, tr.wip_new, tr.q)) except KeyboardInterrupt: print('') logs.out("255", '', True) - if not res in ['y', 'Y']: return + if not res in form.answer_yes: + logs.out("255", '', True) + wip_article(db.uri_file) @@ -85,7 +132,7 @@ def wip_all(process): tyto.process_all('Wip') # Sort by newer articles (created by last check) - db_articles = sorted(Path(db.articles_db).iterdir(), + db_articles = sorted(Path(db.articles_db_d).iterdir(), key=os.path.getmtime ) @@ -93,7 +140,7 @@ def wip_all(process): option = args.target found = False for post_db in db_articles: - if not str(post_db).endswith('.conf'): continue + if not str(post_db).endswith('.config'): continue # Load DB exec(open(post_db).read(),globals()) @@ -104,7 +151,7 @@ def wip_all(process): if option == "again" and db.old_wip: continue if option == "newer" and not db.old_wip: continue - print(':> [%s] - %s'%(db.title, db.post_src)) + print(' ├ [%s] > %s'%(db.title, db.post_src)) if db.old_chk: logs.out("9", '', False) continue @@ -127,14 +174,14 @@ def wip_article(target): global post_bottom # Protect block-codes and quotes - if db.stat_bcodes or db.stat_quotes > 0: + if db.post_bcodes or db.post_quotes > 0: tyto.protect_bcodes_quotes('wip', post_bottom) post_bottom = tyto.protect_article # Protect inline-codes - if db.stat_icodes > 0: + if db.post_icodes > 0: tyto.protect_icodes(post_bottom) - post_bottom = tyto.protect_article + post_bottom = tyto.protect_article # Convert contents from modules @@ -151,16 +198,17 @@ def wip_article(target): wip_tabs() # make HTML tabulations # Replace in DB hash_wip and date_wip - tyto.replace_in_db(db.post_db, 'wip', db.hash_post) + tyto.replace_in_db(db.config, 'wip', db.hash_post) # Get article DB in html.py html.set_page(db.uri_file, post_bottom) #print(html.main_page) # Create wip file - os.makedirs('%s%s'%(db.srv_wip, db.direc_src), exist_ok=True) + os.makedirs('%s%s'%(dom.srv_wip, db.direc_src), exist_ok=True) + logs.out("33", '%s%s'%(dom.srv_wip, db.direc_src), False) tyto.set_file(db.post_wip, 'New', html.main_page) - logs.out("33", db.post_wip, False) + logs.out("32", db.post_wip, False) # Copy needed files (Also create sub-folders) tyto.files_to_srv('wip') @@ -182,8 +230,9 @@ def file_to_string(post_file): continue if sep: - if not post_bottom: post_bottom = line - else: post_bottom = '%s\n%s'%(post_bottom, line) + if not line: continue + elif not post_bottom: post_bottom = line + else: post_bottom = '%s\n%s'%(post_bottom, line) else: if not post_header: post_header = line else: post_header = '%s\n%s'%(post_header, line) @@ -237,7 +286,7 @@ def wip_words_tags(): for ln, line in enumerate(post_bottom.rsplit('\n')): # Paragraphs # Open tag - if db.stat_paragraphs > 0: + if db.post_paragraphs > 0: if line.startswith(tyto.words_tags[10][0]): set_css = tyto.get_css(line) post_bottom = post_bottom.replace(post_bottom.rsplit('\n')[ln], @@ -249,7 +298,8 @@ def wip_words_tags(): tyto.words_tags[10][3] ) # Open anchors - if db.stat_anchors == 0: continue + if db.post_anchors == 0: continue + anchor_links = re.findall(r'>_(.+?):', line) for item in anchor_links: anchor_id = '%s%s:'%(tyto.words_tags[0][0], item) @@ -333,7 +383,7 @@ def wip_images(): for i in range(1, db.uniq_images + 1): image = 'db.image_%s'%i target = width = height = False - set_css = db.domain_css + '_image' + set_css = dom.css + '_image' imag_html = '' if eval(image)[0] == values[0]: @@ -401,7 +451,7 @@ def quote_params(qline): # Convert quote in article # #--------------------------# def wip_quotes() : - if db.stat_quotes == 0: return + if db.post_quotes == 0: return global post_bottom global author, link, lang, book, date @@ -545,7 +595,7 @@ def wip_quotes() : # Content is HTML ready # #--------------------------# def wip_icodes(): - if db.stat_icodes == 0: return + if db.post_icodes == 0: return global post_bottom @@ -561,7 +611,7 @@ def wip_icodes(): # Content is raw, and have to be converted in HTML # #--------------------------------------------------# def wip_bcodes(): - if db.stat_bcodes == 0: return + if db.post_bcodes == 0: return global post_bottom @@ -595,7 +645,7 @@ def wip_bcodes(): # Check between titles to set div or not # #----------------------------------------# def wip_titles(): - if db.stat_titles == 0: return + if db.post_titles == 0: return global post_bottom article_temp = post_bottom @@ -740,3 +790,94 @@ def wip_tabs(): post_bottom = article_temp + +#=================================# +# Convert list in markers to HTML # +# Def from neox <- Thx a lot # +#---------------------------------# +def convert_list(markdown_str): + + # First step : reshape lines + + items = [] + inside_item = 0 + index = -1 + + # Cut string with \n's + strlist = markdown_str.split("\n") + + # Find items + for i in range(len(strlist)): + if "-(" in strlist[i] or "-)" in strlist[i]: + continue + + if strlist[i][0] != "=" and strlist[i][0] != "+": + if inside_item != 1: + inside_item = 1 + else: + inside_item = 0 + + if inside_item == 0: + items.append(strlist[i]) + index += 1 + + if inside_item == 1: + items[index] += strlist[i].lstrip() + + #print("[{}] index {}, inside_item {}, curstr {}\n".format(i, index, inside_item, strlist[i])) + + # Second step : parsing + UL = 1 + OL = 2 + CLOSING = ["ERROR", "\n", "\n"] + OPENING = ["ERROR", "
      \n", "
        \n"] + + rank_stack = [] + rank = 0 + cur_rank = 0 + state = 0 + old_state = 0 + work_str = "" + + for i in range(len(items)): + if "-(" in items[i] or "-)" in items[i]: + continue + rank = cur_rank + descriptor = items[i].split(" ")[0] + text = items[i][items[i].find(" "):] + cur_rank = len(descriptor) + + if "=" in descriptor: + state = UL + elif "+" in descriptor: + state = OL + else: + raise(Exception) + + # rank up + if cur_rank > rank: + for i in range(cur_rank - rank - 1): + work_str += " "*(rank+i) + OPENING[rank_stack.append(UL)] + rank_stack.append(state) + + work_str += " "*rank + OPENING[state] + + # rank down + elif cur_rank < rank: + for i in range(rank - cur_rank - 1): + work_str += " "*(rank-i-1) + CLOSING[rank_stack.pop()] + + work_str += " "*cur_rank + CLOSING[rank_stack.pop()] + + + work_str += " "*cur_rank + "
      1. " + text + "
      2. \n" + + print("[{}] rank_stack {}, state {}, old_state {}, rank {}, cur_rank {}, text {}\n".format( + i, rank_stack, state, old_state, rank, cur_rank, text)) + + work_str += " "*(cur_rank-1) + CLOSING[rank_stack.pop()] + + return(work_str) + + +#print(convert_list(str_exemple)) diff --git a/src/var/lib/tyto/translations/site_en.py b/src/var/lib/tyto/translations/site_en.py index 23b83b8..163bb06 100644 --- a/src/var/lib/tyto/translations/site_en.py +++ b/src/var/lib/tyto/translations/site_en.py @@ -59,10 +59,15 @@ mail_to = "Contact by %s the admin of"%mail.lower() feed = "Feed" generator = "Generator" +# Check +post_chg = "Article was edited. Check it" + +# Wip +wip_new = "Create new HTML page in wip" + # Form #---------------------------------------------------------------------- form_edit = "Edit the domain with the form" - form_start = ' ├──────────────────────────────────────────────┐\n' + \ ' │ Configure a new domain for current directory │\n' + \ ' │ Answer Y/y = yes. Enter to keep {default} │\n' + \ diff --git a/src/var/lib/tyto/translations/site_fr.py b/src/var/lib/tyto/translations/site_fr.py index 783ea43..72051a6 100644 --- a/src/var/lib/tyto/translations/site_fr.py +++ b/src/var/lib/tyto/translations/site_fr.py @@ -59,6 +59,12 @@ mail_to = "Contacter par %s l'administrateur de"%mail.lower() feed = "Flux" generator = "Generateur" +# Check +post_chg = "Article édité. Le vérifier" + +# Wip +wip_new = "Créer une nouvelle page HTML dans wip" + # Formulaire #---------------------------------------------------------------------- form_edit = "Éditer le domaine avec le formulaire" From e43f2eaaa4a81181fc575dfcd658979141a52691 Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Fri, 31 Mar 2023 16:37:58 +0200 Subject: [PATCH 212/247] Some cleaning. wip_links Ok. New processes --- src/var/lib/tyto/program/check.py | 50 +- src/var/lib/tyto/program/form.py | 928 +++++++++++------------ src/var/lib/tyto/program/html.py | 509 ++++++------- src/var/lib/tyto/program/lang.py | 47 -- src/var/lib/tyto/program/langs.py | 76 ++ src/var/lib/tyto/program/logs.py | 79 +- src/var/lib/tyto/program/show.py | 141 ++-- src/var/lib/tyto/program/tyto.py | 8 +- src/var/lib/tyto/program/wip.py | 95 ++- src/var/lib/tyto/translations/logs_en.py | 8 + src/var/lib/tyto/translations/logs_fr.py | 12 +- src/var/lib/tyto/translations/site_en.py | 4 +- src/var/lib/tyto/translations/site_fr.py | 4 +- 13 files changed, 923 insertions(+), 1038 deletions(-) delete mode 100644 src/var/lib/tyto/program/lang.py create mode 100644 src/var/lib/tyto/program/langs.py diff --git a/src/var/lib/tyto/program/check.py b/src/var/lib/tyto/program/check.py index 5e02a6d..73f7a96 100644 --- a/src/var/lib/tyto/program/check.py +++ b/src/var/lib/tyto/program/check.py @@ -5,8 +5,8 @@ # # 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. +# 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 @@ -39,33 +39,7 @@ import time, importlib, sys, os, re, datetime from datetime import datetime from time import gmtime, strftime -import args, dom, logs, status, db, form, tyto - - -# load locale translation -trans_dir = '/var/lib/tyto/translations' -sys.path.insert(0, trans_dir) - - -# Get default system language -# or set "en" (english) if no translation file -try: - lang_site = locale.getdefaultlocale()[0].split('_')[0] - os.path.exists('%s/site_%s.py'%(trans_dir, lang_site)) -except: - lang_site = 'en' - -lang_sys = lang_site - -# Set language site/form from configuration domain -# or set default english if not known -try: - dom.exists - lang_site = dom.lang_site - os.path.exists('%s/site_%s.py'%(trans_dir, lang_site)) - tr = importlib.import_module('site_%s'%lang_site, package=None) -except: - tr = importlib.import_module('site_%s'%lang_site, package=None) +import args, dom, logs, status, db, form, tyto, langs post_err = False @@ -76,7 +50,7 @@ post_err = False #-------------------------#-------------------------------------------- def manage(target): dom.valid() - + # target needed if not target: logs.out("5", args.action, True) @@ -86,14 +60,10 @@ def manage(target): and db.exists \ and not db.old_chk: logs.out("20", '%s > %s'%(db.date_chk, db.uri_file), False) - ask = '' - try: - ask = input(' ├ %s%s '%(tr.check_a, tr.q)) - except KeyboardInterrupt: - print('') - logs.out("255", '', True) - if not ask in form.answer_yes: - return + answer = form.asking(' ├ %s%s '%( + langs.site.check_a, langs.site.q + ), True) + check_process(target) # All @@ -416,7 +386,7 @@ def check_date(date): date_check = time.mktime(time.strptime(date_check, fmt_check)) # Set franch format in post DB - if lang_site == 'fr': + if dom.lang_site == 'fr': date = date.rsplit('-') date = date[2] + '/' + date[1] + '/' + date[0] @@ -486,7 +456,7 @@ def check_3lines(tag, ln, line): if not name: logs.out("2", 'L=%s. "%s: %s" > %s'%( - ln, tag, tr.name, db.uri_file + ln, tag, langs.site.name, db.uri_file ), False) post_err = True diff --git a/src/var/lib/tyto/program/form.py b/src/var/lib/tyto/program/form.py index 501a85f..3e5aad9 100644 --- a/src/var/lib/tyto/program/form.py +++ b/src/var/lib/tyto/program/form.py @@ -1,11 +1,29 @@ #!/usr/bin/env python3 -# Name: Tyto - Littérateur -# Type: Global functions for domain -# Description: Create/edit a domain -# file: domain.py -# Folder: /var/lib/tyto/program/ -# By echolib (XMPP: im@echolib.re) -# License: GNU AFFERO GENERAL PUBLIC LICENSE Version 3, 19 November 2007 +# 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 'domain' argument. +# Create domain config from form +# Create config files for user to custom +# File: /var/lib/tyto/program/form.py +#---------------------------------------------------------------------- #------------ # funny stats @@ -20,57 +38,62 @@ from datetime import datetime import os, sys, locale, importlib -# load locale translation +import logs, dom, tyto, html, show, langs + +# locale translation directory trans_dir = '/var/lib/tyto/translations' -sys.path.insert(0, trans_dir) -import logs, dom, tyto, html, show - -# System language -try: lang_sys = locale.getdefaultlocale()[0].split('_')[0] -except: lang_sys = 'en' - -# Get default system language -# or set "en" (english) if no translation file +# Get default System language try: - lang_site = lang_sys - os.path.exists('%s/site_%s.py'%(trans_dir, lang_site)) + lang_sys = locale.getdefaultlocale()[0].split('_')[0] + os.path.exists('%s/site_%s.py'%(trans_dir, lang_sys)) except: - lang_site = 'en' + lang_sys = 'en' -# Set language site/form from configuration domain -# or set default english if not known -try: - dom.exists - lang_site = dom.lang_site - os.path.exists('%s/site_%s.py'%(trans_dir, lang_site)) - tr = importlib.import_module('site_%s'%lang_site, package=None) -except: - tr = importlib.import_module('site_%s'%lang_site, package=None) +lang_site = lang_sys +# Generic answer answer_yes = ('y', 'Y', 'yes', 'Yes', 'YES', 'o', 'O', 'oui', 'Oui', 'Oui' ) +#=======================================# +# Function called when asking something # +# Catch interruption # +# if logs.out True: sys exit # +# yes_no False: return answer # +# True: exit if not in yes # +#---------------------------------------# +def asking(question, yes_no): + try: + answer = input(question) + except KeyboardInterrupt: + print('') + logs.out("255", '', True) + + if yes_no: + if not answer in answer_yes: + logs.out("255", '', True) + + else: + return(answer) + + #==========================# # Manage Argument 'domain' # # target: 3rd argument # #--------------------------# -def manage(target): +def manage(target): + if not dom.exists: logs.out("43", '', False) create_domain(target) elif dom.incomplete: create_domain(target) else: - try: - ask = input(' ├ %s%s '%(tr.form_edit, tr.q)) - except KeyboardInterrupt: - print('') - logs.out("255", '', True) - if ask in answer_yes: create_domain(target) - else: logs.out("255", '', True) + asking(' ├ %s%s '%(langs.site.form_edit, langs.site.q), True) + create_domain(target) #=====================# @@ -81,121 +104,115 @@ def create_domain(target): logs.out("51", '"%s" -> http(s)://...'%target, False) target = '' - print(tr.form_start) - - + print(langs.site.form_start) + # Get complete URL from target or ask #------------------------------------ + valid_url = ('http://', 'https://') + try: www_url = dom.www_url except: - if target: www_url = target - else: www_url = '' + if target: www_url = target + else: www_url = '' - valid_url = ('http://', 'https://') - ask = '' - try: - ask = input(' ├ [http(s)://...] %s%s {%s} '%( - tr.form_url, tr.q, www_url - ) - ) - except KeyboardInterrupt: - print('') + answer = asking(' ├ [http(s)://...] %s%s {%s} '%( + langs.site.form_url, langs.site.q, www_url + ), False) + + if answer: + if answer.startswith(valid_url): www_url = answer + else: logs.out("2", '"http(s)://%s"%s'%(answer, langs.site.q), True) + elif not www_url: logs.out("255", '', True) - - if ask: - if not ask.startswith(valid_url): - logs.out("2", 'http(s)://%s'%ask, True) - www_url = ask - if not www_url: - logs.out("255", '', True) - - # Remove unused last / if exists - if www_url[-1] == "/": - www_url = www_url[:-1] + if www_url[-1] == "/": www_url = www_url[:-1] + protocol = www_url.rsplit('://')[0] shortname = www_url.rsplit('://')[1] - # Prefix wip - #----------- + # Prefix wip ; guess it if unknown + #--------------------------------- try: wip_url = dom.wip_url - except: + except: # Set domain with www-wip - wip_url = '' - wip_url = shortname.rsplit('.', 2) - if len(wip_url) > 2: - wip_url = '%s://www-wip.%s.%s'%(protocol, wip_url[1], wip_url[2]) - else: - wip_url = '%s://www-wip.%s.%s'%(protocol, wip_url[0], wip_url[1]) + try: + wip_url = shortname.rsplit('.', 2) + if len(wip_url) > 2: + wip_url = '%s://www-wip.%s.%s'%( + protocol, wip_url[1], wip_url[2] + ) + else: + wip_url = '%s://www-wip.%s.%s'%( + protocol, wip_url[0], wip_url[1] + ) + except: + wip_url = '' - ask = '' - try: - ask = input(' ├ %s%s {%s} '%(tr.form_wip, tr.q, wip_url)) - except KeyboardInterrupt: - print('') + answer = asking(' ├ [http(s)://...] %s%s {%s} '%( + langs.site.form_wip, langs.site.q, wip_url + ), False) + if answer: + if answer.startswith(valid_url): wip_url = answer + else: logs.out("2", '"http(s)://www-wip.%s"%s'%( + answer, langs.site.q + ), True) + elif not wip_url: logs.out("255", '', True) - - if ask: - if not ask.startswith(valid_url): - logs.out("2", '"%s" -> http(s)://...'%ask, True) - wip_url = ask - - # Remove unused last / if exists - if wip_url[-1] == "/": - wip_url = wip_url[:-1] + + if wip_url[-1] == "/": wip_url = wip_url[:-1] # Translations for logs #---------------------- try: lang_logs = dom.lang_logs except: lang_logs = lang_sys + + answer = asking(' ├ %s%s {%s} '%( + langs.site.form_trlog, langs.site.q, lang_logs + ), False) - ask = '' - try: - ask = input(' ├ %s%s {%s} '%(tr.form_trlog, tr.q, lang_logs)) - except KeyboardInterrupt: - print('') - logs.out("255", '', True) + if answer: + if len(answer) == 2: lang_logs = answer.lower() + else: logs.out("3", answer, True) - if ask: - if len(ask) == 2: lang_logs = ask.lower() - else: logs.out("3", ask, True) - if not tyto.exists('%s/logs_%s.py'%(trans_dir, lang_logs)): - lang_logs = 'en' + if not tyto.exists('%s/logs_%s.py'%(trans_dir, lang_logs)): + lang_logs = 'en' - # Register variables in domain database + # Start registering variables in domain database + #----------------------------------------------- global navbars_conf local_user = '%s/.local/tyto/%s/'%(dom.home_dir, shortname) modules_dir = '%s/articles/_configs/'%dom.folder footer_about_f = '%sfooter_about.html'%modules_dir - set_f = '# Home Domain\n' + \ - 'directory = "%s/"\n'%dom.folder + \ - 'database = "%s"\n'%dom.config + \ - '\n# Local user configuration\n' + \ - 'lang_sys = "%s"\n'%lang_sys + \ - 'local_user = "%s"\n'%local_user + \ - 'lang_logs = "%s"\n'%lang_logs + \ - 'articles_db_d = "%sarticles/"\n'%local_user + \ - '\n# Working directories\n' + \ - 'articles_d = "%s/articles/"\n'%dom.folder + \ - 'files_d = "%s/articles/files/"\n'%dom.folder + \ - 'images_d = "%s/articles/images/"\n'%dom.folder + \ - 'modules_d = "%s"\n'%modules_dir + \ - '\n# Modules files\n' + \ - 'navbar_f = "%styto.navbar"\n'%modules_dir + \ - '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 + \ - 'wip_url = "%s"\n'%wip_url + set_f = \ + '# Home Domain\n' + \ + 'directory = "%s/"\n'%dom.folder + \ + 'database = "%s"\n'%dom.config + \ + '\n# Local user configuration\n' + \ + 'lang_sys = "%s"\n'%lang_sys + \ + 'local_user = "%s"\n'%local_user + \ + 'lang_logs = "%s"\n'%lang_logs + \ + 'articles_db_d = "%sarticles/"\n'%local_user + \ + '\n# Working directories\n' + \ + 'articles_d = "%s/articles/"\n'%dom.folder + \ + 'files_d = "%s/articles/files/"\n'%dom.folder + \ + 'images_d = "%s/articles/images/"\n'%dom.folder + \ + 'modules_d = "%s"\n'%modules_dir + \ + '\n# Modules files\n' + \ + 'navbar_f = "%styto.navbar"\n'%modules_dir + \ + '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 + \ + 'wip_url = "%s"\n'%wip_url tyto.set_file(dom.config, True, set_f) logs.out("32", dom.config, False) @@ -203,20 +220,22 @@ def create_domain(target): # Get srv root #------------- - try: srv = dom.srv - except: srv = '/var/www' - - ask = '' try: - ask = input(' ├ %s%s {%s} '%(tr.form_srv, tr.q, srv)) - except KeyboardInterrupt: - print('') + srv = dom.srv + except: + if tyto.exists('/var/www') : srv = '/var/www' + else: srv = '' + + answer = asking(' ├ %s%s {%s} '%( + langs.site.form_srv, langs.site.q, srv + ), False) + if answer: + if tyto.exists(answer): srv = answer + else: logs.out("1", srv, True) + elif not srv: logs.out("255", '', True) - if ask: - srv = ask - if not tyto.exists(srv): logs.out("1", srv, True) - if srvl[-1] == "/": srv = srv[:-1] + if srvl[-1] == "/": srv = srv[:-1] root_srv_dom = '%s/%s'%(srv, shortname) srv_wip_tpl = "%s/wip/template/"%root_srv_dom @@ -250,15 +269,12 @@ def create_domain(target): #------------------- try: logo = dom.logo except: logo = 'logo.png' + + answer = asking(' ├ %s%s {%s} '%( + langs.site.form_logo, langs.site.q, logo + ), False) - ask = '' - try: - ask = input(' ├ %s%s {%s} '%(tr.form_logo, tr.q, logo)) - except KeyboardInterrupt: - print('') - logs.out("255", '', True) - - if ask: logo = ask + if answer: logo = answer set_f = 'wip_logo_f = "%s%s"\n'%(srv_wip_tpl, logo) + \ 'www_logo_f = "%s%s"'%(srv_www_tpl, logo) @@ -270,15 +286,12 @@ def create_domain(target): #------------------ try: rss = dom.rss except: rss = 'rss.xml' + + answer = asking(' ├ %s%s {%s} '%( + langs.site.form_rss_f, langs.site.q, rss + ), False) - ask = '' - try: - ask = input(' ├ %s%s {%s} '%(tr.form_rss_f, tr.q, rss)) - except KeyboardInterrupt: - print('') - logs.out("255", '', True) - - if ask: www_rss = ask + if answer: www_rss = answer set_f = 'www_rss_f = "%s/www/%s"\n'%(root_srv_dom, rss) + \ '\n# Domain user\'s settings\n' + \ @@ -292,21 +305,16 @@ def create_domain(target): #------------------- try: rss_items = dom.rss_items except: rss_items = "100" + + answer = asking(' ├ %s%s {%s} '%( + langs.site.form_rss_i, langs.site.q, rss_items + ), False) - ask = '' - try: - ask = input(' ├ %s%s {%s} '%(tr.form_rss_i, tr.q, rss_items)) - except KeyboardInterrupt: - print('') - logs.out("255", '', True) - - if ask: - if not ask.isdigit() and int(ask) > 1: - logs.out("3", ask, True) - rss_items = ask - rss_items = int(rss_items) - - set_f = 'rss_items = %d'%rss_items + if answer: + if answer.isdigit() and int(answer) > 1: rss_items = answer + else: logs.out("3", answer, True) + + set_f = 'rss_items = %d'%int(rss_items) tyto.set_file(dom.config, False, set_f) @@ -314,16 +322,14 @@ def create_domain(target): #----------------- try: title = dom.title except: title = '' + + answer = asking(' ├ %s%s {%s} '%( + langs.site.form_title, langs.site.q, title + ), False) - ask = '' - try: - ask = input(' ├ %s%s {%s} '%(tr.form_title, tr.q, title)) - except KeyboardInterrupt: - print('') - logs.out("255", '', True) + if answer: title = answer + elif not title: logs.out("255", '', True) - if ask: title = ask - if not title: logs.out("255", '', True) if '"' in title: title = title.replace('"', '') set_f = 'title = "%s"'%title @@ -335,14 +341,11 @@ def create_domain(target): try: date except: date = datetime.now().year - ask = '' - try: - ask = input(' ├ %s%s {%s} '%(tr.form_date, tr.q, date)) - except KeyboardInterrupt: - print('') - logs.out("255", '', True) + answer = asking(' ├ %s%s {%s} '%( + langs.site.form_date, langs.site.q, date + ), False) - if ask: date = ask + if answer: date = answer set_f = 'date = "%s"'%date tyto.set_file(dom.config, False, set_f) @@ -352,16 +355,14 @@ def create_domain(target): #----------------------- try: about = dom.about except: about = '' + + answer = asking(' ├ %s%s {%s} '%( + langs.site.form_about, langs.site.q, about + ), False) - ask = '' - try: - ask = input(' ├ %s%s {%s} '%(tr.form_about, tr.q, about)) - except KeyboardInterrupt: - print('') - logs.out("255", '', True) + if answer: about = answer + elif not about: logs.out("255", '', True) - if ask: about = ask - elif not about: logs.out("255", '', True) if '"' in about: about = about.replace('"', '') set_f = 'about = "%s"'%about @@ -370,21 +371,14 @@ def create_domain(target): # Get Lang domain for web pages #------------------------------ - #try: lang_site = dom.lang_site - #except: pass # Already set lang_site - global lang_site - - ask = '' - try: - ask = input(' ├ %s%s {%s} '%(tr.form_trsite, tr.q, lang_site)) - except KeyboardInterrupt: - print('') - logs.out("255", '', True) - - if ask: - if len(ask) == 2: lang_site = ask.lower() - else: logs.out("3", ask, True) + answer = asking(' ├ %s%s {%s} '%( + langs.site.form_trsite, langs.site.q, lang_site + ), False) + if answer: + if len(answer) == 2: lang_site = answer.lower() + else: logs.out("3", answer, True) + if not tyto.exists('%s/site_%s.py'%(trans_dir, lang_site)): lang_site = 'en' @@ -396,18 +390,15 @@ def create_domain(target): #---------------- try: mail = dom.mail except: mail = '' + + answer = asking(' ├ %s%s {%s} '%( + langs.site.form_mail, langs.site.q, mail + ), False) - ask = '' - try: - ask = input(' ├ %s%s {%s} '%(tr.form_mail, tr.q, mail)) - except KeyboardInterrupt: - print('') - logs.out("255", '', True) + if answer: mail = answer + elif not mail: logs.out("255", '', True) - if ask: mail = ask - if not mail: - logs.out("255", '', True) - elif not "@" in mail and not "." in mail: + if not re.search('^\w+@\w+.\w+$', mail): logs.out("3", mail, True) set_f = 'mail = "%s"'%mail @@ -418,16 +409,15 @@ def create_domain(target): #---------------- try: tags = dom.tags except: tags = '' + + answer = asking(' ├ %s%s {%s} '%( + langs.site.form_tags, langs.site.q, tags + ), False) + + if answer: tags = answer + elif not tags: logs.out("255", '', True) - ask = '' - try: - ask = input(' ├ %s%s {%s} '%(tr.form_tags, tr.q, tags)) - except KeyboardInterrupt: - print('') - logs.out("255", '', True) - - if ask: tags = ask - if not tags: logs.out("255", '', True) + if '"' in tags: tags = tags.replace('"', '') set_f = 'tags = "%s"'%tags tyto.set_file(dom.config, False, set_f) @@ -437,16 +427,14 @@ def create_domain(target): #------------------- try: domlicense = dom.license except: domlicense = 'CC BY-NC-SA 3.0' + + answer = asking(' ├ %s%s {%s} '%( + langs.site.form_lic, langs.site.q, domlicense + ), False) + + if answer: domlicense = answer + elif not domlicense: logs.out("255", '', True) - ask = '' - try: - ask = input(' ├ %s%s {%s} '%(tr.form_lic, tr.q, domlicense)) - except KeyboardInterrupt: - print('') - logs.out("255", '', True) - - if ask: domlicense = ask - if not domlicense: logs.out("255", '', True) if '"' in domlicense: domlicense = domlicense.replace('"', '') set_f = 'license = "%s"'%domlicense @@ -457,20 +445,15 @@ def create_domain(target): #--------------------------- try: licurl = dom.license_url except: licurl = '' + + answer = asking(' ├ %s [http(s)://...] %s%s {%s} '%( + langs.site.form_opt, langs.site.form_licurl, + langs.site.q, licurl + ), False) - ask = '' - try: - ask = input(' ├ %s [http(s)://...] %s%s {%s} '%( - tr.form_opt, tr.form_licurl, tr.q, licurl - ) - ) - except KeyboardInterrupt: - print('') - logs.out("255", '', True) - - if ask: - if not ask.startswith('http'): logs.out("3", ask, True) - licurl = ask + if answer: + if answer.startswith(valid_url): licurl = answer + else: logs.out("2", '"http(s)://%s"%s'%(answer, langs.site.q), True) set_f = 'license_url = "%s"'%licurl tyto.set_file(dom.config, False, set_f) @@ -481,19 +464,14 @@ def create_domain(target): try: legalurl = dom.legal_url except: legalurl = '' - ask = '' - try: - ask = input(' ├ %s [http(s)://...] %s%s {%s} '%( - tr.form_opt, tr.form_legal, tr.q, legalurl - ) - ) - except KeyboardInterrupt: - print('') - logs.out("255", '', True) - - if ask: - if not ask.startswith('http'): logs.out("3", ask, True) - legalurl = ask + answer = asking(' ├ %s [http(s)://...] %s%s {%s} '%( + langs.site.form_opt, langs.site.form_legal, + langs.site.q, legalurl + ), False) + + if answer: + if answer.startswith(valid_url): legalurl = answer + else: logs.out("2", '"http(s)://%s"%s'%(answer, langs.site.q), True) set_f = 'legal_url = "%s"'%legalurl tyto.set_file(dom.config, False, set_f) @@ -504,19 +482,14 @@ def create_domain(target): try: termsurl = dom.terms_url except: termsurl = '' - ask = '' - try: - ask = input(' ├ %s [http(s)://...] %s%s {%s} '%( - tr.form_opt, tr.form_terms, tr.q, termsurl - ) - ) - except KeyboardInterrupt: - print('') - logs.out("255", '', True) - - if ask: - if not ask.startswith('http'): logs.out("3", ask, True) - domain_legalurl = ask + answer = asking(' ├ %s [http(s)://...] %s%s {%s} '%( + langs.site.form_opt, langs.site.form_terms, + langs.site.q, termsurl + ), False) + + if answer: + if answer.startswith(valid_url): termsurl = answer + else: logs.out("2", '"http(s)://%s"%s'%(answer, langs.site.q), True) set_f = 'terms_url = "%s"'%termsurl tyto.set_file(dom.config, False, set_f) @@ -527,17 +500,13 @@ def create_domain(target): try: css = dom_css except: css = 'tyto' - ask = '' - try: - ask = input(' ├ %s%s {%s} '%(tr.form_css, tr.q, css)) - except KeyboardInterrupt: - print('') - logs.out("255", '', True) - - if ask: - if not ask.isalnum(): logs.out("3", ask, True) - css = ask.lower() - + answer = asking(' ├ %s%s {%s} '%( + langs.site.form_css, langs.site.q, css + ), False) + + if answer: css = answer.lower() + if not css.isalnum(): logs.out("3", css, True) + set_f = 'css = "%s"'%css tyto.set_file(dom.config, False, set_f) @@ -547,16 +516,12 @@ def create_domain(target): try: sep = dom.sep except: sep = "-" - ask = '' - try: - ask = input(' ├ %s%s {%s} '%(tr.form_sep, tr.q, sep)) - except KeyboardInterrupt: - print('') - logs.out("255", '', True) - - if ask: - if not len(ask) == 1: logs.out("3", ask, True) - sep = ask + answer = asking(' ├ %s%s {%s} '%( + langs.site.form_sep, langs.site.q, sep + ), False) + + if answer: sep = answer + if not len(sep) == 1: logs.out("3", answer, True) set_f = 'sep = "%s"'%sep tyto.set_file(dom.config, False, set_f) @@ -569,17 +534,14 @@ def create_domain(target): article_code = "True" except: article_code = "False" - - ask = '' - try: - ask = input(' ├ %s%s {%s} '%(tr.form_pscode, tr.q, article_code)) - except KeyboardInterrupt: - print('') - logs.out("255", '', True) - - if ask: - if ask in answer_yes: article_code = "True" - else: article_code = "False" + + answer = (' ├ %s%s {%s} '%( + langs.site.form_pscode, langs.site.q, article_code + ), False) + + if answer: + if answer in answer_yes: article_code = "True" + else: article_code = "False" set_f = 'article_code = %s'%article_code tyto.set_file(dom.config, False, set_f) @@ -590,19 +552,14 @@ def create_domain(target): try: relme = dom.relme except: relme = '' - ask = '' - try: - ask = input(' ├ %s %s%s {%s} '%( - tr.form_opt, tr.form_relme, tr.q, relme - ) - ) - except KeyboardInterrupt: - print('') - logs.out("255", '', True) + answer = asking(' ├ %s [http(s)://...] %s%s {%s} '%( + langs.site.form_opt, langs.site.form_relme, + langs.site.q, relme + ), False) - if ask: - if not ask.startswith('http'): logs.out("3", ask, True) - relme = ask + if answer: + if answer.startswith(valid_url): relme = answer + else: logs.out("2", '"http(s)://%s"%s'%(answer, langs.site.q), True) set_f = 'relme = "%s"'%relme tyto.set_file(dom.config, False, set_f) @@ -611,19 +568,14 @@ def create_domain(target): # Sidebar Title #-------------- try: sdb_title = dom.sidebar_title - except: sdb_title = tr.site_sdb_t - - ask = '' - try: - ask = input(' ├ %s. %s%s {%s} '%( - tr.sidebar, tr.title, tr.q, sdb_title - ) - ) - except KeyboardInterrupt: - print('') - logs.out("255", '', True) + except: sdb_title = langs.site.site_sdb_t - if ask: sdb_title = ask + answer = asking(' ├ %s. %s%s {%s} '%( + langs.site.sidebar, langs.site.title, + langs.site.q, sdb_title + ), False) + + if answer: sdb_title = answer if '"' in sdb_title: sdb_title = sdb_title.replace('"', '') set_f = 'sidebar_title = "%s"'%sdb_title @@ -634,20 +586,16 @@ def create_domain(target): #-------------- try: sdb_items = dom.sidebar_items except: sdb_items = "6" - - ask = '' - try: - ask = input(' ├ [max=16] %s. %s%s {%s} '%( - tr.sidebar, tr.form_sdb_i, tr.q, sdb_items - ) - ) - except KeyboardInterrupt: - print('') - logs.out("255", '', True) - - if ask: - if not ask.isdigit(): logs.out("3", ask, True) - elif int(ask) in range(1,17): sdb_items = int(ask) + + answer = asking(' ├ [max=16] %s. %s%s {%s} '%( + langs.site.sidebar, langs.site.form_sdb_i, + langs.site.q, sdb_items + ), False) + + if answer: + if answer.isdigit() and int(answer) in range(1,17): + sdb_items = int(answer) + else: logs.out("3", answer, True) set_f = 'sidebar_items = %d'%int(sdb_items) tyto.set_file(dom.config, False, set_f) @@ -658,29 +606,31 @@ def create_domain(target): try: active = dom.activated except: active = False - print(tr.form_warn) + print(langs.site.form_warn) show.read_lines(dom.config, False) + # Activate and prepare domain ? #------------------------------ - try: - ask = input(' ├ %s%s '%(tr.form_activ, tr.q)) - except KeyboardInterrupt: - print('') - logs.out("255", '', True) + answer = asking(' ├ %s%s '%( + langs.site.form_activ, langs.site.q + ), False) - if not ask in answer_yes: + if not answer in answer_yes: tyto.set_file(dom.config, False, '\nactivated = False') logs.out("255", '', True) - + + # Activate Domain #---------------- tyto.set_file(dom.config, False, '\nactivated = True') + # RELoad config #-------------- importlib.reload(dom) - + + # Create folders from configuration file #--------------------------------------- folders = \ @@ -704,44 +654,34 @@ def create_domain(target): # Create in _configs/ modules files #---------------------------------- - create_sidebar('form') - create_navbar('form') create_metas('form') + create_navbar('form') + create_sidebar('form') create_footer('form') create_footer_about('form') - print(tr.form_ready) + print(langs.site.form_ready) - - #========================# + +#=============================================================# +# # +# CREATE MODULES' USER FILE AND CREATE WIP FILES FROM MODULES # +# # +#=============================================================# +#========================# # metas_load source file # #------------------------# def create_metas(option): if not dom.ready: dom.valid() - # Defaut metas valuees when FIRST created - metas_srvs = \ - ' \n' + \ - ' \n' + \ - ' \n' + \ - ' ' - - # Create an empty html file in wip/www server if not exists - if not tyto.exists(dom.wip_metas_f): - tyto.set_file(dom.wip_metas_f, 'new', metas_srvs) - logs.out("32", dom.wip_metas_f, False) - - # Create new default config file, or ask if exists if tyto.exists(dom.metas_f): - ask = '' - try: - ask = input(' ├ %s. %s%s '%(tr.metas, tr.form_reset, tr.q)) - except KeyboardInterrupt: - print('') - logs.out("255", '', True) + answer = asking(' ├ %s. %s%s '%( + langs.site.metas, langs.site.form_reset, + langs.site.q + ), False) - if not ask in answer_yes: + if not answer in answer_yes: if option == "form": return logs.out("255", '', True) @@ -762,13 +702,11 @@ def create_metas(option): '# - Do NOT copy this file to template directory\n' + \ '# - These tags are already set' - try: metas_lang = tr.metas_doc + try: metas_lang = langs.site.metas_doc except: metas_lang = metas_en metas_tags = \ - '%s'%metas_lang%(tyto.Tyto, - dom.metas_f - ) + \ + '%s'%metas_lang%(tyto.Tyto, dom.metas_f) + \ '\n' + \ '# %s)'%(9 * ' ', tr.source_code) + '%stitle="%s"\n'%(9 * ' ', langs.site.tyto_git_t%(tyto.Tyto)) + \ + '%sid="footer_item_link">%s)'%(9 * ' ', langs.site.source_code) tyto_show = \ '%s%s %s'%(9 * ' ', tyto.Tyto, Tytosrc) # Show copyright date from creation to now year @@ -964,7 +898,7 @@ def create_footer(option): # Simple link to home domain_home = \ '\n%s%s'%(9 * ' ', dom.title) # Insert content of footer_about_f or default if not exists @@ -988,14 +922,14 @@ def create_footer(option): if dom.legal_url: legal_link = \ '%s'%(11 * ' ', tr.legal_t) + '%stitle="%s - %s"\n'%(11 * ' ', langs.site.legal_t, dom.title) + \ + '%sclass="footer_item_link">%s'%(11 * ' ', langs.site.legal_t) if dom.terms_url: terms_link = \ '%s'%(11 * ' ', tr.terms_s) + '%stitle="%s - %s"\n'%(11 * ' ', langs.site.terms_t, dom.title) + \ + '%sclass="footer_item_link">%s'%(11 * ' ', langs.site.terms_s) # create laws links from terms and legal if exists footer_laws = '' @@ -1009,7 +943,9 @@ def create_footer(option): footer_laws_links = '' if footer_laws: footer_laws_links = \ - ' \n' @@ -1034,7 +970,7 @@ def create_footer(option): '# - Do NOT copy to template directory' '# %s\n'%(20 * "-") - try: footer_lang = tr.footer_doc + try: footer_lang = langs.site.footer_doc except: footer_lang = footer_en # Final HTML footer code @@ -1044,9 +980,9 @@ def create_footer(option): ' \n' + \ @@ -1054,17 +990,23 @@ def create_footer(option): ' \n' + \ ' \n' + \ '' - # Create an empty html file in wip/www server if not exists - if not tyto.exists(dom.wip_footer_f): - tyto.set_file(dom.wip_footer_f, 'new', '') - logs.out("32", dom.wip_footer_f, False) - # Create new default file, or ask if exists - ask = '' if tyto.exists(dom.footer_f): - try: - ask = input(' ├ %s. %s%s '%(tr.footer, tr.form_reset, tr.q)) - except KeyboardInterrupt: - print('') - logs.out("255", '', True) - - if not ask in answer_yes: + answer = asking(' ├ %s. %s%s '%( + langs.site.footer, langs.site.form_reset, + langs.site.q + ), False) + + if not answer in answer_yes: if option == "form": return logs.out("255", '', True) tyto.set_file(dom.footer_f, 'new', footer) logs.out("32", dom.footer_f, False) - + + # Create footer file in wip server if not exists + if not tyto.exists(dom.wip_footer_f): + html.create_user_footer('wip') + + # Generic HTML list in footer """ ' \n' - if not sidebar_new: - # Empty file - if not sidebar_has: - logs.out('29', '(sidebar): %s'%db.sidebar_load, False) + # Nothing to do + if not sidebar_items: + if not tyto.exists(target): + tyto.set_file(target, 'New', '') + logs.out("32", target, False) return - else: # Some items, but no one is valid - logs.out('28', '(sidebar)', False) - return - - # Create HTML complete sidebar - sidebar_temp = sidebar_html%(sidebar_title, sidebar_list) - - # Indent HTML code - sidebar_content = '' - for line in sidebar_temp.rsplit('\n'): - sidebar_content = sidebar_content + '%s%s\n'%(4 * ' ', line) - - # Create file if sidebar has content - if sidebar_new: - ask_html = ' ├ Replace %s ? '%target - res = '' - - if not option == 'pub' and tyto.exists(target): - res = input(ask_html) - if not res in ['y', 'Y']: - logs.out("255", '', True) - - tyto.set_file(target, True, sidebar_content) - logs.out("33", target, False) - - -#==================================# -# Create HTML navbar from config # -# If no index in src: STOP # -# For wip, create if no index.html # -# for publish all/navbar, STOP # -#----------------------------------# -def create_navbar(option): - domain.domain_needed() - - # more confitions to pass - try: - db.navbar_load - if not tyto.exists(db.navbar_load): - logs.out("1", db.navbar_load, True) - except: - logs.out("1", 'Navbar load file', True) - - # Set target from option - pub_opts = ('www', 'pub') - if option == 'wip': target = db.wip_navbar - elif option == 'www': target = db.www_navbar - elif option == 'pub': target = db.www_navbar - - # If content and error - navbar_new = False - navbar_has = False - e_src_index = False - e_www_index = False # If error, do not create file in www server - - # Set first HTML line - menu_html = '%s\n'%(menu_html, 8 * ' ', 6 * ' ') - tyto.set_file(target, 'New', menu_html) - logs.out("33", target, False) - - -#========================================================# -# Create metas.html from _configs/tyto.metas.html # -# Manage options Edit, New, Force, Create # -# Create DB file with hash from _configs/tyto.metas.html # -# To manage new creation if changes # -#--------------------------------------------------------# -def create_user_metas(option): - dom.valid() - - if option == 'wip': target = dom.wip_metas_f - elif option == 'www': target = dom.www_metas_f - elif option == 'pub': target = dom.www_metas_f - - # Create wip metas.html file according to option - #----------------------------------------------- - ask_html = ' ├ Replace %s ? '%target - user_metas = '' - metas_used = (' +# +# 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: Load translations file for log +# File: /var/lib/tyto/program/log.py +#---------------------------------------------------------------------- + +#------------ +# funny stats +#------------ +# lines: +# functions: +# comments: +#---------------------------------------------------------------------- + +#********************************************************************** + +import locale, sys, os, importlib +import dom + +# Import translation directory +trans_dir = '/var/lib/tyto/translations' +sys.path.insert(0, trans_dir) + + +# Get default system language +# or set "en" (english) if no translation file +try: + lang_sys = locale.getdefaultlocale()[0].split('_')[0] + os.path.exists('%s/logs_%s.py'%(trans_dir, lang_sys)) +except: + lang_sys = 'en' + + +# Set language logs from configuration domain +# or set default english if not known +try: + dom.exists + lang_logs = dom.lang_logs + os.path.exists('%s/logs_%s.py'%(trans_dir, lang_logs)) + log = importlib.import_module('logs_%s'%lang_logse, package=None) +except: + log = importlib.import_module('logs_%s'%lang_sys, package=None) +''' + exec(open('%s/logs_%s.py'%(trans_dir, lang.logs)).read()) +except: + exec(open('%s/logs_%s.py'%(trans_dir, lang_sys)).read()) +''' + +# Set language site/form from configuration domain +# or set default english if not known +try: + dom.exists + lang_site = dom.lang_site + os.path.exists('%s/site_%s.py'%(trans_dir, lang_site)) + site = importlib.import_module('site_%s'%lang_site, package=None) +except: + site = importlib.import_module('site_%s'%lang_sys, package=None) diff --git a/src/var/lib/tyto/program/logs.py b/src/var/lib/tyto/program/logs.py index d4eaff5..35d28f3 100644 --- a/src/var/lib/tyto/program/logs.py +++ b/src/var/lib/tyto/program/logs.py @@ -18,7 +18,7 @@ #********************************************************************** import os, sys -import lang +import langs # Set colors CS = '\033[0;0m' @@ -31,50 +31,49 @@ CG = '\033[1;32m' #--------------------------------# def out(nbr, value, out): logs = { - '1' : ' ╞ %s%s%s > %s'%(CR, lang.unused_r, CS, value), - '2' : ' ╞ %s%s%s > %s'%(CR, lang.data_inc, CS, value), - '3' : ' ╞ %s%s%s %s'%(CR, lang.data_inv, CS, value), + '1' : ' ╞ %s%s%s > %s'%(CR, langs.log.unused_r, CS, value), + '2' : ' ╞ %s%s%s > %s'%(CR, langs.log.data_inc, CS, value), + '3' : ' ╞ %s%s%s %s'%(CR, langs.log.data_inv, CS, value), '4' : ' ╘ %sUnable to create file%s: %s'%(CR, CS, value), - '5' : ' ╘ %s%s%s > "%s"'%(CR, lang.no_arg, CS, value), - '6' : ' ╞ %s%s%s > %s'%(CR, lang.sep_inv, CS, value), - '7' : ' ╘ %s%s%s > %s'%(CR, lang.post_inv, CS, value), - '8' : ' ╞ %s%s%s %s'%(CR, lang.mark_np, CS, value), + '5' : ' ╘ %s%s%s > "%s"'%(CR, langs.log.no_arg, CS, value), + '6' : ' ╞ %s%s%s > %s'%(CR, langs.log.sep_inv, CS, value), + '7' : ' ╘ %s%s%s > %s'%(CR, langs.log.post_inv, CS, value), + '8' : ' ╞ %s%s%s %s'%(CR, langs.log.mark_np, CS, value), '9' : ' ╞ Article %shas changed%s. Check it first'%(CR, CS), - '10' : ' ╘ %s%s%s'%(CR, lang.dom_no, CS), - '11' : ' ╘ %s%s%s > %s'%(CR, lang.err_arg, CS, value), - '12' : ' ╞ %s%s%s > %s'%(CR, lang.post_inc, CS, value), - '13' : ' ╞ %s%s%s'%(CR, lang.no_fidi, CS), + '10' : ' ╘ %s%s%s'%(CR, langs.log.dom_no, CS), + '11' : ' ╘ %s%s%s > %s'%(CR, langs.log.err_arg, CS, value), + '12' : ' ╞ %s%s%s > %s'%(CR, langs.log.post_inc, CS, value), + '13' : ' ╞ %s%s%s'%(CR, langs.log.no_fidi, CS), '14' : ' ╞ %sMismatch%s program start'%(CR, CS), - '15' : ' ╞ %s%s%s %s'%(CR, lang.anch_nu, CS, value), - '16' : ' ╞ %s%s%s "%s = ?"'%(CR, lang.unused_c, CS, value), - '17' : ' ╞ %s%s%s "%s ?"'%(CR, lang.unused_v, CS, value), - '18' : ' ╘ %s%s%s > %s'%(CR, lang.unused_p, CS, value), + '15' : ' ╞ %s%s%s %s'%(CR, langs.log.anch_nu, CS, value), + '16' : ' ╞ %s%s%s "%s = ?"'%(CR, langs.log.unused_c, CS, value), + '17' : ' ╞ %s%s%s "%s ?"'%(CR, langs.log.unused_v, CS, value), + '18' : ' ╘ %s%s%s > %s'%(CR, langs.log.unused_p, CS, value), '19' : ' ╞ Article %swip%s on: %s'%(CG, CS, value), - '20' : ' ╞ %s%s%s %s'%(CG, lang.check_on, CS, value), - '21' : ' ╘ %s%s%s > %s'%(CG, lang.post_val, CS, value), - '22' : ' ╞ %s%s%s %s'%(CY, lang.symb_np, CS, value), - '23' : ' ╞ %s%s%s > %s'%(CY, lang.db_inv, CS, value), - '24' : ' ╞ %s%s%s > %s'%(CY, lang.unused_r, CS, value), - '25' : ' ╞ Article %snot yet checked%s: %s'%(CY, CS, value), - '26' : ' ╞ %sNo index%s article %s'%(CY, CS, value), - '27' : ' ╞ %s%s%s %s'%(CY, lang.snpic_d, CS, value), - '28' : ' ╘ %s (%s)'%(lang.ntd, value), + '20' : ' ╞ %s%s%s %s'%(CG, langs.log.check_on, CS, value), + '21' : ' ╘ %s%s%s > %s'%(CG, langs.log.post_val, CS, value), + '22' : ' ╞ %s%s%s %s'%(CY, langs.log.symb_np, CS, value), + '23' : ' ╞ %s%s%s > %s'%(CY, langs.log.db_inv, CS, value), + '24' : ' ╞ %s%s%s > %s'%(CY, langs.log.unused_r, CS, value), + '25' : ' ╞ %s%s%s > %s'%(CY, langs.log.nycheck, CS, value), + '26' : ' ╞ %s%s%s %s'%(CY, langs.log.nyfile, CS, value), + '27' : ' ╞ %s%s%s %s'%(CY, langs.log.snpic_d, CS, value), + '28' : ' ╘ %s (%s)'%(langs.log.ntd, value), '29' : ' ╞ %sEmpty configuration%s %s'%(CY, CS, value), - '30' : ' ╞ Article %snot yet wip%s: %s'%(CY, CS, value), - '31' : ' ╞ Not included. %sMax items reached%s %s'%(CY, CS, value), - '32' : ' ╞══ %s%s%s > %s'%(CG, lang.file_c, CS, value), - '33' : ' ╞══ %s%s%s > %s'%(CG, lang.dir_c, CS, value), - '34' : ' ╞══ %s%s%s > %s'%(CG, lang.file_n, CS, value), - '35' : ' ╞ %sAdd item%s %s'%(CG, CS, value), - '36' : ' ╡ %s %s'%(lang.file_e, value), - '37' : ' ╡ %s %s'%(lang.dir_e, value), - '40' : ' ╒ %s%s%s > "%s"'%(CY, lang.dom_ina, CS, value), - '41' : ' ╒ %s%s%s > "%s"'%(CR, lang.dom_inc, CS, value), - '42' : ' ╒ %s%s%s > "%s"'%(CG, lang.dom_act, CS, value), - '43' : ' ╒ %s%s%s'%(CY, lang.dom_no, CS), - '44' : ' ╞ %s%s%s "tyto check %s"'%(CY, lang.check_m, CS, value), - '51' : ' ╞ %s%s%s > %s'%(CY, lang.data_inc, CS, value), - '255' : ' ╘ %s'%lang.laterout + '30' : ' ╞ %s%s%s > %s'%(CY, langs.log.nywip, CS, value), + '32' : ' ╞══ %s%s%s > %s'%(CG, langs.log.file_c, CS, value), + '33' : ' ╞══ %s%s%s > %s'%(CG, langs.log.dir_c, CS, value), + '34' : ' ╞══ %s%s%s > %s'%(CG, langs.log.file_n, CS, value), + '35' : ' ╞═ %s%s%s %s'%(CG, langs.log.add, CS, value), + '36' : ' ╡ %s %s'%(langs.log.file_e, value), + '37' : ' ╡ %s %s'%(langs.log.dir_e, value), + '40' : ' ╒ %s%s%s > "%s"'%(CY, langs.log.dom_ina, CS, value), + '41' : ' ╒ %s%s%s > "%s"'%(CR, langs.log.dom_inc, CS, value), + '42' : ' ╒ %s%s%s > "%s"'%(CG, langs.log.dom_act, CS, value), + '43' : ' ╒ %s%s%s'%(CY, langs.log.dom_no, CS), + '44' : ' ╞ %s%s%s "tyto check %s"'%(CY, langs.log.check_m, CS, value), + '51' : ' ╞ %s%s%s > %s'%(CY, langs.log.data_inc, CS, value), + '255' : ' ╘ %s'%langs.log.laterout } msg = logs[nbr] diff --git a/src/var/lib/tyto/program/show.py b/src/var/lib/tyto/program/show.py index b8febea..0625183 100644 --- a/src/var/lib/tyto/program/show.py +++ b/src/var/lib/tyto/program/show.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 # Tyto - Littérateur # -# Copyright (C) 2023 Cyrille Louarn +# 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 @@ -34,35 +34,8 @@ #********************************************************************** -import os, sys, locale, importlib -import args, lang, logs, dom, db, form, tyto, check, stats - -# load locale translation -trans_dir = '/var/lib/tyto/translations' -sys.path.insert(0, trans_dir) - -# System language -try: lang_sys = locale.getdefaultlocale()[0].split('_')[0] -except: lang_sys = 'en' - -# Get default system language -# or set "en" (english) if no translation file -try: - lang_site = lang_sys - os.path.exists('%s/site_%s.py'%(trans_dir, lang_site)) -except: - lang_site = 'en' - -# Set language site/form from configuration domain -# or set default english if not known -try: - dom.exists - lang_site = dom.lang_site - os.path.exists('%s/site_%s.py'%(trans_dir, lang_site)) - tr = importlib.import_module('site_%s'%lang_site, package=None) -except: - tr = importlib.import_module('site_%s'%lang_site, package=None) - +import os, sys, importlib +import args, logs, dom, db, form, tyto, check, stats, langs #========================# # Read lines from a file # @@ -94,10 +67,8 @@ def read_lines(f, alone): #======================# # From command line: # -# - 'showdb' / 'show' # -# - 'editdb' / 'edit' # -# Show or edit files # -# final html, db, load # +# Show or edit file # +# final html, db, src # #----------------------# def manage(target): if not dom.exists: logs.out("10", '', True) @@ -127,10 +98,6 @@ def manage(target): if args.action == "show-about": target = 'post' - # When edit article, get src hash - if args.action == "edit": - curr_hash = tyto.get_filesum(db.uri_file, True) - # Convert command action to do[] # as edit* &nd show* [action] have same target file @@ -153,71 +120,71 @@ def manage(target): # Set target file from "new" [action] do = \ { - 'src' : { - 'domain' : dom.config, - 'footer' : dom.footer_f, - 'metas' : dom.metas_f, - 'navbar' : dom.navbar_f, - 'sidebar' : dom.sidebar_f, - 'post' : post_src - }, - 'db' : { - 'domain' : dom.config, - 'footer' : dom.footer_f, - 'metas' : dom.metas_f, - 'navbar' : dom.navbar_f, - '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, - 'metas' : dom.wip_metas_f, - 'navbar' : dom.wip_navbar_f, - 'sidebar' : dom.wip_sidebar_f, - 'post' : post_wip - }, - 'www' : { - 'domain' : dom.config, - 'footer' : dom.www_footer_f, - 'metas' : dom.www_metas_f, - 'navbar' : dom.www_navbar_f, - 'sidebar' : dom.www_sidebar_f, - 'post' : post_www - }, + 'src' : { + 'domain' : dom.config, + 'footer' : dom.footer_f, + 'metas' : dom.metas_f, + 'navbar' : dom.navbar_f, + 'sidebar' : dom.sidebar_f, + 'post' : post_src + }, + 'db' : { + 'domain' : dom.config, + 'footer' : dom.footer_f, + 'metas' : dom.metas_f, + 'navbar' : dom.navbar_f, + '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, + 'metas' : dom.wip_metas_f, + 'navbar' : dom.wip_navbar_f, + 'sidebar' : dom.wip_sidebar_f, + 'post' : post_wip + }, + 'www' : { + 'domain' : dom.config, + 'footer' : dom.www_footer_f, + 'metas' : dom.www_metas_f, + 'navbar' : dom.www_navbar_f, + 'sidebar' : dom.www_sidebar_f, + 'post' : post_www + }, } # Read or edit file, according to legacy args.action try: file = do[action][target] + if args.action in actions_read: read_lines(file, True) + elif args.action in actions_edit: + curr_hash = tyto.get_filesum(file, True) tyto.edit_file(file) + except: logs.out("28", '%s + %s'%(action, target), True) # If edit article and hash changed, ask to check if args.action == "edit" and post_src: - new_hash = tyto.get_filesum(post_src, True) + new_hash = tyto.get_filesum(file, True) if curr_hash != new_hash: - ask = '' - try: ask = input(' ├ %s%s '%(tr.post_chg, tr.q)) - except KeyboardInterrupt: - print('') - logs.out("255", '', True) - - if not ask in form.answer_yes: - logs.out("255", '', True) + if file == post_src: + form.asking(' ├ %s%s '%( + langs.site.post_chg, langs.site.q + ), True) # Reload post DB (if edited article, and check it if ask "y") importlib.reload(db) diff --git a/src/var/lib/tyto/program/tyto.py b/src/var/lib/tyto/program/tyto.py index c3b01f2..40fee31 100644 --- a/src/var/lib/tyto/program/tyto.py +++ b/src/var/lib/tyto/program/tyto.py @@ -516,7 +516,8 @@ def files_to_srv(server): d_in = uri.split("/")[-1] d_in = uri.rsplit(d_in)[0] - # Destination file to server + # Destination file and directories according to server + # (remove last / from domain directory value) f_src = '%s%s'%(dom.articles_d[:-1], uri) if server == 'wip': f_dst = '%s%s'%(dom.srv_wip[:-1], uri) @@ -525,19 +526,22 @@ def files_to_srv(server): f_dst = '%s%s'%(dom.srv_www[:-1], uri) d_dst = '%s%s'%(dom.srv_www[:-1], d_in) - # Create folder and subfolders + # Create sub-directories in server try: os.makedirs(d_dst, exist_ok=True) logs.out("33", d_dst, False) except: logs.out('4', d_dst, True) + # COpy files to server try: shutil.copy2(f_src, f_dst) logs.out("32", f_dst, False) except: logs.out('4', f_dst, True) + # Copy source post file in server + # if article_code is True in domain DB if dom.article_code: if server == "wip": base_srv = dom.srv_wip elif server == "www": base_srv = dom.srv_www diff --git a/src/var/lib/tyto/program/wip.py b/src/var/lib/tyto/program/wip.py index 6d84b9a..1fa25b6 100644 --- a/src/var/lib/tyto/program/wip.py +++ b/src/var/lib/tyto/program/wip.py @@ -1,13 +1,13 @@ #!/usr/bin/env python3 # Tyto - Littérateur # -# Copyright (C) 2023 Cyrille Louarn +# Copyright (C) 2023 Cyrille Louarn # Copyright (C) 2023 Adrien Bourmault # # 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. +# 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 @@ -39,7 +39,7 @@ import os, re, sys, locale, shutil, importlib, time from pathlib import Path -import args, logs, lang, dom, db, tyto, html, form, stats +import args, logs, dom, db, tyto, html, form, stats # load locale translation trans_dir = '/var/lib/tyto/translations' @@ -112,15 +112,7 @@ def manage_wip(target): # wip is up-to-date: ask to wip again else: logs.out("19", db.date_wip, False) - try: - res = input(' ├ [%s] %s%s '%(db.title, tr.wip_new, tr.q)) - except KeyboardInterrupt: - print('') - logs.out("255", '', True) - - if not res in form.answer_yes: - logs.out("255", '', True) - + form.asking(' ├ [%s] %s%s '%(db.title, tr.wip_new, tr.q), True) wip_article(db.uri_file) @@ -308,34 +300,55 @@ def wip_words_tags(): ) -#=======================# -# Convert links from DB # -# - link_%i # -# - file_%i # -#-----------------------# -def wip_links(): +#========================# +# Convert links set inDB # +# - file_%i # +# - link_%i # +# from marker to HTML # +#------------------------# +def wip_link_convert(marker, html): global post_bottom + post_bottom = post_bottom.replace(marker, html) - # Doing files, first, becase of similar marker - if db.uniq_files > 0: +def wip_links(): + if db.uniq_files == 0 and db.uniq_links == 0: return + + link_tb = 'target="_blank"' + link_ts = 'target="_self"' + link_html = '%s' + + # ! Doing link files, first, becase of similar marker + #---------------------------------------------------- + if db.uniq_files > 0: for i in range(1, db.uniq_files + 1): - file = 'db.file_%s'%i - post_bottom = post_bottom.replace(eval(file)[0]+'+', - eval(file)[1]%('_blank') - ) - post_bottom = post_bottom.replace(eval(file)[0], - eval(file)[1]%('_self') - ) + link = 'db.file_%s'%i + link_css = "link_file" + link_name = eval(link)[0][2:] + link_anc = eval(link)[1] + link_title = eval(link)[2] + link_set = link_html%( + link_css, link_anc, link_title, "%s", link_name + ) + + wip_link_convert(eval(link)[0]+'+', link_set%link_tb) + wip_link_convert(eval(link)[0], link_set%link_ts) + - if db.uniq_links > 0: + # Convert simple links + #--------------------- + if db.uniq_links > 0: for i in range(1, db.uniq_links + 1): - link = 'db.link_%s'%i - post_bottom = post_bottom.replace(eval(link)[0]+'+', - eval(link)[1]%('_blank') - ) - post_bottom = post_bottom.replace(eval(link)[0], - eval(link)[1]%('_self') - ) + link = 'db.link_%s'%i + link_css = "link" + link_name = eval(link)[0][1:] + link_anc = eval(link)[1] + link_title = eval(link)[2] + link_set = link_html%( + link_css, link_anc, link_title, "%s", link_name + ) + + wip_link_convert(eval(link)[0]+'+', link_set%link_tb) + wip_link_convert(eval(link)[0], link_set%link_ts) #===============# @@ -370,8 +383,8 @@ def wip_images(): if db.uniq_images == 0: return global post_bottom - image_link = '%s' - image_show = '%s' + image_link = '%s' + image_show = '%s' # Check each line for ln, line in enumerate(post_bottom.rsplit('\n')): @@ -419,13 +432,15 @@ def wip_images(): image_target = eval(image)[1] image_target = db.sub_uri + image_target[1:] image_src = image_show%( - set_css, image_target, eval(image)[2], style + set_css, image_target, + eval(image)[2], eval(image)[2], + style ) # Set link for image if target: image_tgt = image_link%( - set_css, image_target, eval(image)[2], '%s' + set_css, image_target, '%s' ) else: image_tgt = '%s' diff --git a/src/var/lib/tyto/translations/logs_en.py b/src/var/lib/tyto/translations/logs_en.py index baafdf8..7fad89a 100644 --- a/src/var/lib/tyto/translations/logs_en.py +++ b/src/var/lib/tyto/translations/logs_en.py @@ -11,6 +11,10 @@ #********************************************************************** # Generic +sidebar = 'Sidebar' +navbar = 'Navbar' +metas = 'Metas Tags' +footer = 'Footer' line = "Ligne" ntd = "Nothing to do" @@ -44,5 +48,9 @@ mark_np = "Not paired marks" symb_np = "Not paired symbols" snpic_d = "Using default snpic. Not found" anch_nu = "Anchor not uniq" +nyfile = "file not yet created" +nycheck = "Article not yet checked" +nywip = "Article not yet wip" +add = "Add:" laterout = "Maybe later..." diff --git a/src/var/lib/tyto/translations/logs_fr.py b/src/var/lib/tyto/translations/logs_fr.py index 3823509..899cb8a 100644 --- a/src/var/lib/tyto/translations/logs_fr.py +++ b/src/var/lib/tyto/translations/logs_fr.py @@ -11,7 +11,12 @@ #********************************************************************** # Generique -linecol = "Line" +sidebar = 'Barre Latérale' +navbar = 'Barre de navigation' +metas = 'Balises Metas' +footer = "Pied de Page" + +line = "Line" ntd = "Rien à faire" unused_r = "Ressource manquante" @@ -44,5 +49,10 @@ mark_np = "Marqueurs non jumelés" symb_np = "Symboles non jumelés" snpic_d = "snpic utilisé par défaut. Manquant" anch_nu = "Ancre non unique" +nyfile = "Fichier pas encore créé" +nycheck = "Article pas encore 'check'" +nywip = "Article pas encore 'wip'" +add = "Ajout:" + laterout = "Pour plus tard..." diff --git a/src/var/lib/tyto/translations/site_en.py b/src/var/lib/tyto/translations/site_en.py index 163bb06..8948ad4 100644 --- a/src/var/lib/tyto/translations/site_en.py +++ b/src/var/lib/tyto/translations/site_en.py @@ -23,7 +23,7 @@ This is a python file, so... DO NOT REMOVE: # Generic sidebar = 'Sidebar' navbar = 'Navbar' -metas = 'HTML Metas Tags' +metas = 'Metas Tags' footer = 'Footer' title = 'Title' File = 'File' @@ -178,7 +178,7 @@ sidebar_doc = \ '# Order in sidebar position\n' + \ '# Max articles = %d\n' + \ '# Option Tp set sidebar title:\n' + \ -' ": Sidebar Title"\n' + \ +'# ": Sidebar Title"\n' + \ '\n# %s\n'%(20 * "-") + \ '# Examples :\n' + \ '# : My new articles list' diff --git a/src/var/lib/tyto/translations/site_fr.py b/src/var/lib/tyto/translations/site_fr.py index 72051a6..449a9d6 100644 --- a/src/var/lib/tyto/translations/site_fr.py +++ b/src/var/lib/tyto/translations/site_fr.py @@ -23,7 +23,7 @@ Ceci est un fichier python, donc... NE PAS ENLEVER : # Generic sidebar = 'Barre Latérale' navbar = 'Barre de navigation' -metas = 'Balises Metas HTML' +metas = 'Balises Metas' footer = "Pied de Page" title = 'Titre' File = 'Fichier' @@ -179,7 +179,7 @@ sidebar_doc = \ '# L\'ordre définit la position\n' + \ '# Articles max = %d\n' + \ '# Option Pour définir un titre à la barre latérale:\n' + \ -' ": Titre de la sidebar"\n' + \ +'# ": Titre de la sidebar"\n' + \ '\n# %s\n'%(20 * "-") + \ '# Exemples :\n' + \ '# : Ma liste des nouveaux articles\n' + \ From 29ee8cc704e8ecbce9fb1968e8a95d5eb5f25761 Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Sun, 2 Apr 2023 15:59:06 +0200 Subject: [PATCH 213/247] New processes and updated codes --- src/usr/bin/tyto | 2 +- src/var/lib/tyto/program/args.py | 109 ++++++---- src/var/lib/tyto/program/check.py | 37 ++-- src/var/lib/tyto/program/db.py | 4 +- src/var/lib/tyto/program/dom.py | 258 +++++++++++++---------- src/var/lib/tyto/program/form.py | 192 +++++++++-------- src/var/lib/tyto/program/html.py | 159 +++++++------- src/var/lib/tyto/program/infos.py | 52 +---- src/var/lib/tyto/program/logs.py | 8 +- src/var/lib/tyto/program/show.py | 35 +-- src/var/lib/tyto/program/status.py | 34 ++- src/var/lib/tyto/program/tyto.py | 98 ++++----- src/var/lib/tyto/program/wip.py | 60 ++---- src/var/lib/tyto/translations/logs_en.py | 15 +- src/var/lib/tyto/translations/logs_fr.py | 13 +- src/var/lib/tyto/translations/site_en.py | 62 ++++++ src/var/lib/tyto/translations/site_fr.py | 64 +++++- src/var/lib/tyto/tyto_domain.default | 75 +++++++ 18 files changed, 742 insertions(+), 535 deletions(-) create mode 100644 src/var/lib/tyto/tyto_domain.default diff --git a/src/usr/bin/tyto b/src/usr/bin/tyto index 8144919..f4c9f0f 100755 --- a/src/usr/bin/tyto +++ b/src/usr/bin/tyto @@ -64,7 +64,7 @@ actions = { 'show-www' : show.manage, 'status' : status.check, 'template' : publish.manage_publish, - 'wip' : wip.manage_wip, + 'wip' : wip.manage, } diff --git a/src/var/lib/tyto/program/args.py b/src/var/lib/tyto/program/args.py index 2c9a86c..86bba91 100644 --- a/src/var/lib/tyto/program/args.py +++ b/src/var/lib/tyto/program/args.py @@ -1,11 +1,27 @@ #!/usr/bin/env python3 -# Name: Tyto - Littérateur -# Type: Command arguments -# Description: Check arguments -# file: args.py -# Folder: /var/lib/tyto/program/ -# By echolib (XMPP: im@echolib.re) -# License: GNU AFFERO GENERAL PUBLIC LICENSE Version 3, 19 November 2007 +# 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 arguments from command line +# File: /var/lib/tyto/program/args.py +#---------------------------------------------------------------------- #------------ # funny stats @@ -20,27 +36,28 @@ import sys import infos, logs + # 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' +'check', +'edit', +'edit-about', +'edit-db', +'edit-wip', +'edit-www', +'help', +'new', +'show', +'show-about', +'show-db', +'show-wip', +'show-www', +'status', +'wip', +'publish' ) pass_actions = ( @@ -51,35 +68,35 @@ pass_actions = ( # 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', - 'wip', +'check', +'edit', +'edit-db', +'edit-wip', +'edit-www', +'publish', +'show', +'show-about', +'show-db', +'show-wip', +'show-www', +'wip', ) pass_targets = \ ( - 'all', - 'again', - 'newer', - 'domain', - 'footer', - 'metas', - 'navbar', - 'sidebar', - 'stats', - 'template' +'all', +'again', +'newer', +'domain', +'footer', +'metas', +'navbar', +'sidebar', +'stats', +'template' ) -multi_chk = ('all', 'again') +multi_chk = ('all', 'again', 'newer') action = '' target = '' diff --git a/src/var/lib/tyto/program/check.py b/src/var/lib/tyto/program/check.py index 73f7a96..3d9bc0c 100644 --- a/src/var/lib/tyto/program/check.py +++ b/src/var/lib/tyto/program/check.py @@ -38,7 +38,6 @@ 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 post_err = False @@ -53,27 +52,23 @@ def manage(target): # target needed if not target: - logs.out("5", args.action, True) + logs.out("5", '[target]', True) + + elif target in args.multi_chk: + check_all(target) + + elif not db.post: + logs.out("1", db.uri_file, True) # Already check - elif not target in args.multi_chk \ - and db.exists \ + elif db.exists \ and not db.old_chk: 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) - + ), True) check_process(target) - # All - elif target in args.multi_chk: - check_all(target) - - # No file found - elif not db.post: - sys.exit(1) - else: check_process(target) @@ -98,7 +93,7 @@ def check_all(option): importlib.reload(db) #print(':> [%s] - %s'%(db.title, db.post_src)) - if not db.exists: continue + if not db.exists: continue if option == 'all' and not db.old_chk: continue found = True @@ -367,9 +362,10 @@ def check_needed_tags(post_header): # Create False date_check # #--------------------------------# def check_date(date): - global post_err + global post_err, date_tr # Check if article date is valid (True) + date_tr = date fmt_article = "%Y-%m-%d" try: @@ -387,10 +383,9 @@ def check_date(date): # Set franch format in post DB if dom.lang_site == 'fr': - date = date.rsplit('-') - date = date[2] + '/' + date[1] + '/' + date[0] - - date = (date, date_check) + date = date.rsplit('-') + date_tr = date[2] + '/' + date[1] + '/' + date[0] + print("> Convert date in FR >", date_tr) #===========================================# @@ -750,7 +745,7 @@ def create_database(): 'about = "%s"\n'%about + \ 'author = "%s"\n'%author + \ 'tags = "%s"\n'%tags + \ - 'date = "%s"\n'%date + \ + 'date = "%s"\n'%date_tr + \ 'snpic = "%s"\n'%snpic_url + \ '\n# Used files\n' + \ 'uris = %s'%str(files_post) diff --git a/src/var/lib/tyto/program/db.py b/src/var/lib/tyto/program/db.py index df750ac..8ed7559 100644 --- a/src/var/lib/tyto/program/db.py +++ b/src/var/lib/tyto/program/db.py @@ -18,7 +18,6 @@ #********************************************************************** import os - import args, logs, dom, form, tyto remove = exists = post = corrupt = False @@ -26,6 +25,7 @@ remove = exists = post = corrupt = False try: in_dir = os.getcwd() except: logs.out("13", '', True) + # target needs db (file). # action like show, wip, edit-db # not domain, all, again... @@ -52,9 +52,7 @@ if args.target \ post = True hash_post = tyto.get_filesum(uri_file, True) else: - post = False remove = True - logs.out("1", uri_file, False) # Check if database config is valid (contains values) if exists: diff --git a/src/var/lib/tyto/program/dom.py b/src/var/lib/tyto/program/dom.py index a3f7c97..b5d0b8f 100644 --- a/src/var/lib/tyto/program/dom.py +++ b/src/var/lib/tyto/program/dom.py @@ -1,11 +1,27 @@ #!/usr/bin/env python3 -# Name: Tyto - Littérateur -# Type: DB for domain -# Description: Search domain datas and get statuses -# file: dom.py -# Folder: /var/lib/tyto/program/ -# By echolib (XMPP: im@echolib.re) -# License: GNU AFFERO GENERAL PUBLIC LICENSE Version 3, 19 November 2007 +# 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 domain configuration +# File: /var/lib/tyto/program/dom.py +#---------------------------------------------------------------------- #------------ # funny stats @@ -17,17 +33,99 @@ #********************************************************************** -import os, sys, importlib, locale +import os, sys, importlib, langs lib = 'tyto_domain' exists = incomplete = active = ready = shortname = False -local_user = articles_db = activated = False +local_user = articles_db_d = False hole = False # Set current directory try: in_dir = os.getcwd() 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', +'www_css_f', +'www_navbar_f', +'www_sidebar_f', +'www_metas_f', +'www_footer_f', +'www_logo_f', +'www_rss_f', +'logo', +'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' +) + +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('~') @@ -39,7 +137,7 @@ if not hole: # Set configuration domain file config = '%s/tyto_domain.py'%folder - # Set exists if configuration file + # Set exists if configuration file if os.path.exists(config): exists = True exec(open(config).read()) @@ -48,112 +146,52 @@ if not hole: try: shortname except: shortname = config - if activated: - active = 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_navbar_f', - 'wip_sidebar_f', - 'wip_metas_f', - 'wip_footer_f', - 'www_navbar_f', - 'www_sidebar_f', - 'www_metas_f', - 'www_footer_f', - 'wip_logo_f', - 'www_logo_f', - 'www_rss_f', - 'logo', - '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' - ) + try: active = activated + except: pass + + 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 - create_files = \ - ( - 'navbar_f', - 'sidebar_f', - 'metas_f', - 'footer_f', - 'footer_about_f' - ) - err_val = (()) # Make a list from values error - dir_new = (()) # Make a list for directories to create - file_new = (()) # Make a list for files to check - file_mod = (()) # male a list for modules files to create - for value in dom_values: - try: - eval(str(value)) - except: - err_val = err_val + ((value),) - 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 not incomplete and active: - ready = True - for value in dom_values: - # Check if directory exists and create it - if value.endswith('_d') and \ - not os.path.exists(eval(str(value))): - os.makedirs(eval(str(value)), exist_ok=True) - dir_new = dir_new + ((eval(str(value))),) - - # Check if file exists - if value.endswith('_f') and \ - not os.path.exists(eval(str(value))): - if value in create_files: - file_mod = file_mod + ((value),) - else: - file_new = file_new + ((eval(str(value))),) + if not incomplete: + 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 #====================================# diff --git a/src/var/lib/tyto/program/form.py b/src/var/lib/tyto/program/form.py index 3e5aad9..82b472c 100644 --- a/src/var/lib/tyto/program/form.py +++ b/src/var/lib/tyto/program/form.py @@ -36,7 +36,7 @@ #********************************************************************** from datetime import datetime -import os, sys, locale, importlib +import os, sys, re, locale, importlib import logs, dom, tyto, html, show, langs @@ -85,7 +85,6 @@ def asking(question, yes_no): # target: 3rd argument # #--------------------------# def manage(target): - if not dom.exists: logs.out("43", '', False) create_domain(target) @@ -100,16 +99,17 @@ def manage(target): # Create a new domain # #---------------------# def create_domain(target): - if target and not target.startswith('http'): + valid_url = ('http://', 'https://') + invalid = False + + if target and not target.startswith(valid_url): logs.out("51", '"%s" -> http(s)://...'%target, False) target = '' print(langs.site.form_start) # Get complete URL from target or ask - #------------------------------------ - valid_url = ('http://', 'https://') - + #------------------------------------ try: www_url = dom.www_url except: @@ -153,7 +153,7 @@ def create_domain(target): answer = asking(' ├ [http(s)://...] %s%s {%s} '%( langs.site.form_wip, langs.site.q, wip_url - ), False) + ), False) if answer: if answer.startswith(valid_url): wip_url = answer else: logs.out("2", '"http(s)://www-wip.%s"%s'%( @@ -172,11 +172,11 @@ def create_domain(target): answer = asking(' ├ %s%s {%s} '%( langs.site.form_trlog, langs.site.q, lang_logs - ), False) + ), False) if answer: if len(answer) == 2: lang_logs = answer.lower() - else: logs.out("3", answer, True) + else: logs.out("3", answer, False) if not tyto.exists('%s/logs_%s.py'%(trans_dir, lang_logs)): lang_logs = 'en' @@ -220,23 +220,37 @@ def create_domain(target): # Get srv root #------------- - try: - srv = dom.srv - except: - if tyto.exists('/var/www') : srv = '/var/www' - else: srv = '' + try: srv = dom.srv + except: srv = '/var/www' answer = asking(' ├ %s%s {%s} '%( langs.site.form_srv, langs.site.q, srv ), False) - if answer: - if tyto.exists(answer): srv = answer - else: logs.out("1", srv, True) - elif not srv: - logs.out("255", '', True) - if srvl[-1] == "/": srv = srv[:-1] + if answer: srv = answer + if not tyto.exists(srv): + logs.out("1", srv, False) + srv = '' + invalid = True + elif srv[-1] == "/": + srv = srv[:-1] + + # Get logo's website + #------------------- + try: logo = dom.logo + except: logo = 'logo.png' + + answer = asking(' ├ %s%s {%s} '%( + langs.site.form_logo, langs.site.q, logo + ), False) + + if answer: logo = answer + if not logo: logo='logo.png' + + + # Set config's directories for servers + #------------------------------------- root_srv_dom = '%s/%s'%(srv, shortname) srv_wip_tpl = "%s/wip/template/"%root_srv_dom srv_www_tpl = "%s/www/template/"%root_srv_dom @@ -252,11 +266,17 @@ def create_domain(target): 'srv_www_images_d = "%s/www/images/"\n'%root_srv_dom + \ 'srv_www_files_d = "%s/www/files/"\n'%root_srv_dom + \ '\n' + \ - '# Servers files\n' + \ + '# Servers files (wip)\n' + \ + 'wip_logo_f = "%s%s"\n'%(srv_wip_tpl, logo) + \ + 'wip_css_f = "%sstyles.css"\n'%srv_wip_tpl + \ '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 + \ 'wip_footer_f = "%sfooter.html"\n'%srv_wip_tpl + \ + '\n' + \ + '# Servers files (www)\n' + \ + 'www_logo_f = "%s%s"\n'%(srv_www_tpl, logo) + \ + 'www_css_f = "%sstyles.css"\n'%srv_www_tpl + \ '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 + \ @@ -265,23 +285,6 @@ def create_domain(target): tyto.set_file(dom.config, False, set_f) - # Get logo's website - #------------------- - try: logo = dom.logo - except: logo = 'logo.png' - - answer = asking(' ├ %s%s {%s} '%( - langs.site.form_logo, langs.site.q, logo - ), False) - - if answer: logo = answer - - set_f = 'wip_logo_f = "%s%s"\n'%(srv_wip_tpl, logo) + \ - 'www_logo_f = "%s%s"'%(srv_www_tpl, logo) - - tyto.set_file(dom.config, False, set_f) - - # RSS/Atom filename #------------------ try: rss = dom.rss @@ -304,15 +307,15 @@ def create_domain(target): # RSS/Atom max items #------------------- try: rss_items = dom.rss_items - except: rss_items = "100" + except: rss_items = 100 answer = asking(' ├ %s%s {%s} '%( langs.site.form_rss_i, langs.site.q, rss_items ), False) - if answer: - if answer.isdigit() and int(answer) > 1: rss_items = answer - else: logs.out("3", answer, True) + if answer: rss_items = answer + if not str(rss_items).isdigit() or not int(rss_items) > 1: + rss_items = 100 set_f = 'rss_items = %d'%int(rss_items) tyto.set_file(dom.config, False, set_f) @@ -324,14 +327,13 @@ def create_domain(target): except: title = '' answer = asking(' ├ %s%s {%s} '%( - langs.site.form_title, langs.site.q, title - ), False) + langs.site.form_title, langs.site.q, title + ), False) if answer: title = answer - elif not title: logs.out("255", '', True) - - if '"' in title: title = title.replace('"', '') - + if not title: invalid = True + elif '"' in title: title = title.replace('"', '') + set_f = 'title = "%s"'%title tyto.set_file(dom.config, False, set_f) @@ -360,24 +362,26 @@ def create_domain(target): langs.site.form_about, langs.site.q, about ), False) - if answer: about = answer - elif not about: logs.out("255", '', True) - - if '"' in about: about = about.replace('"', '') - + if answer: about = answer + if not about: invalid = True + elif '"' in about: about = about.replace('"', '') + set_f = 'about = "%s"'%about tyto.set_file(dom.config, False, set_f) # Get Lang domain for web pages #------------------------------ + try: lang_site + except: lang_site = lang_sys + answer = asking(' ├ %s%s {%s} '%( langs.site.form_trsite, langs.site.q, lang_site ), False) if answer: if len(answer) == 2: lang_site = answer.lower() - else: logs.out("3", answer, True) + else: logs.out("3", answer, False) if not tyto.exists('%s/site_%s.py'%(trans_dir, lang_site)): lang_site = 'en' @@ -395,11 +399,10 @@ def create_domain(target): langs.site.form_mail, langs.site.q, mail ), False) - if answer: mail = answer - elif not mail: logs.out("255", '', True) - + if answer: mail = answer if not re.search('^\w+@\w+.\w+$', mail): - logs.out("3", mail, True) + logs.out("3", mail, False) + invalid = True set_f = 'mail = "%s"'%mail tyto.set_file(dom.config, False, set_f) @@ -414,10 +417,9 @@ def create_domain(target): langs.site.form_tags, langs.site.q, tags ), False) - if answer: tags = answer - elif not tags: logs.out("255", '', True) - - if '"' in tags: tags = tags.replace('"', '') + if answer: tags = answer + if not tags: invalid = True + elif '"' in tags: tags = tags.replace('"', '') set_f = 'tags = "%s"'%tags tyto.set_file(dom.config, False, set_f) @@ -432,9 +434,7 @@ def create_domain(target): langs.site.form_lic, langs.site.q, domlicense ), False) - if answer: domlicense = answer - elif not domlicense: logs.out("255", '', True) - + if answer: domlicense = answer if '"' in domlicense: domlicense = domlicense.replace('"', '') set_f = 'license = "%s"'%domlicense @@ -451,9 +451,11 @@ def create_domain(target): langs.site.q, licurl ), False) - if answer: - if answer.startswith(valid_url): licurl = answer - else: logs.out("2", '"http(s)://%s"%s'%(answer, langs.site.q), True) + if answer: licurl = answer + if not licurl.startswith(valid_url): + if answer: + logs.out("2", '"http(s)://%s"%s'%(licurl, langs.site.q), False) + licurl = '' set_f = 'license_url = "%s"'%licurl tyto.set_file(dom.config, False, set_f) @@ -469,9 +471,11 @@ def create_domain(target): langs.site.q, legalurl ), False) - if answer: - if answer.startswith(valid_url): legalurl = answer - else: logs.out("2", '"http(s)://%s"%s'%(answer, langs.site.q), True) + if answer: legalurl = answer + if not legalurl.startswith(valid_url): + if answer: + logs.out("2", '"http(s)://%s"%s'%(legalurl, langs.site.q), False) + legalurl = '' set_f = 'legal_url = "%s"'%legalurl tyto.set_file(dom.config, False, set_f) @@ -487,9 +491,11 @@ def create_domain(target): langs.site.q, termsurl ), False) - if answer: - if answer.startswith(valid_url): termsurl = answer - else: logs.out("2", '"http(s)://%s"%s'%(answer, langs.site.q), True) + if answer: termsurl = answer + if not termsurl.startswith(valid_url): + if answer: + logs.out("2", '"http(s)://%s"%s'%(termsurl, langs.site.q), False) + termsurl = '' set_f = 'terms_url = "%s"'%termsurl tyto.set_file(dom.config, False, set_f) @@ -505,7 +511,9 @@ def create_domain(target): ), False) if answer: css = answer.lower() - if not css.isalnum(): logs.out("3", css, True) + if not css.isalnum(): + logs.out("3", css, False) + css = 'tyto' set_f = 'css = "%s"'%css tyto.set_file(dom.config, False, set_f) @@ -521,8 +529,10 @@ def create_domain(target): ), False) if answer: sep = answer - if not len(sep) == 1: logs.out("3", answer, True) - + if not len(sep) == 1: + logs.out("3", answer, False) + sep = "-" + set_f = 'sep = "%s"'%sep tyto.set_file(dom.config, False, set_f) @@ -557,9 +567,11 @@ def create_domain(target): langs.site.q, relme ), False) - if answer: - if answer.startswith(valid_url): relme = answer - else: logs.out("2", '"http(s)://%s"%s'%(answer, langs.site.q), True) + if answer: relme = answer + if not relme.startswith(valid_url): + if answer: + logs.out("2", '"http(s)://%s"%s'%(relme, langs.site.q), False) + relmel = '' set_f = 'relme = "%s"'%relme tyto.set_file(dom.config, False, set_f) @@ -576,7 +588,10 @@ def create_domain(target): ), False) if answer: sdb_title = answer - if '"' in sdb_title: sdb_title = sdb_title.replace('"', '') + if not sdb_title: + sdb_title = '' + invalid = True + elif '"' in sdb_title: sdb_title = sdb_title.replace('"', '') set_f = 'sidebar_title = "%s"'%sdb_title tyto.set_file(dom.config, False, set_f) @@ -585,22 +600,27 @@ def create_domain(target): # Sidebar Items #-------------- try: sdb_items = dom.sidebar_items - except: sdb_items = "6" + except: sdb_items = 6 answer = asking(' ├ [max=16] %s. %s%s {%s} '%( langs.site.sidebar, langs.site.form_sdb_i, langs.site.q, sdb_items ), False) - if answer: - if answer.isdigit() and int(answer) in range(1,17): - sdb_items = int(answer) - else: logs.out("3", answer, True) + if answer: sdb_items = answer + 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) tyto.set_file(dom.config, False, set_f) + # Domain config invalid, do not activate + if invalid: + tyto.set_file(dom.config, False, '\nactivated = False') + print(langs.site.form_inv) + logs.out("2", dom.config, True) + # Resumed configuration #----------------------- try: active = dom.activated diff --git a/src/var/lib/tyto/program/html.py b/src/var/lib/tyto/program/html.py index 0818534..f4fdcea 100644 --- a/src/var/lib/tyto/program/html.py +++ b/src/var/lib/tyto/program/html.py @@ -19,7 +19,7 @@ # XMPP: echolib (im@echolib.re) # # Description: Create HTML page -# File: /var/lib/tyto/program/show.py +# File: /var/lib/tyto/program/html.py #---------------------------------------------------------------------- #------------ @@ -33,7 +33,6 @@ #********************************************************************** import os, sys, importlib - import logs, db, dom, tyto, form, langs # Publish option can be @@ -62,8 +61,7 @@ def create_metas_page(): metas_page = '' scale = 'width=device-width, initial-scale=1.0' all_tags = dom.tags + ',' + db.tags - css_file = 'styles.css' - css_ref = 'href="%stemplate/%s"'%(db.sub_uri, css_file) + css_ref = 'href="%stemplate/%s"'%(db.sub_uri, dom.css) rss_ref = 'type="application/rss+xml" ' + \ 'href="%s%s" title="RSS 2.0. %s %s %s"'%( db.sub_uri, dom.rss, @@ -80,7 +78,7 @@ def create_metas_page(): ) # Create author and date publish section infos - create_html_infos_section('wip') + create_html_time_meta('wip') # Set all raw HTML metas #----------------------- @@ -117,28 +115,34 @@ def create_metas_page(): # Set main page, with all HTML sections # #---------------------------------------# def create_main_page(target, article_bottom): - global main_page - - if not tyto.exists(dom.wip_footer_f): - logs.out("1", dom.wip_footer_f, True) - - if not tyto.exists(dom.wip_metas_f): - logs.out("24", '(HTML metas): %s'%dom.wip_metas_f, False) + global main_page, post_html_code # Create link for website's logo #------------------------------- - logo_html = '\n'%(11 * " ") + \ - '%s\n'%(15 * " ") + \ - '%s'%(8 * " ") - + logo_html = \ + '\n'%(11 * " ") + \ + '%s\n'%(15 * " ") + \ + '%s'%(8 * " ") + + post_html_code = '' + if dom.article_code: + post_html_code = \ + ' ' + \ + ' {%s}\n'%( + langs.site.tyto_psrc, + langs.site.source_code + ) + #-----------------------# # Create main HTML Page # #-----------------------# @@ -156,7 +160,7 @@ def create_main_page(target, article_bottom): '\n' + \ '
        \n' + \ ' \n' + \ '

        %s

        \n'%dom.title + \ '
        \n' + \ @@ -167,7 +171,17 @@ def create_main_page(target, article_bottom): '\n' + \ '
        \n' + \ '
        \n' + \ - '%s\n'%post_pub + \ + '

        \n' + \ + ' %s\n'%( + title, langs.site.w_written, db.date, langs.site.by, + db.author, + langs.site.article + ) + \ + '%s'%post_html_code + \ + '%s\n'%time_html_pub + \ + ' %s\n'%db.author + \ + '

        \n' + \ '
        \n' + \ '%s\n'%article_bottom + \ '
        \n' + \ @@ -182,11 +196,12 @@ def create_main_page(target, article_bottom): # Create HTML line for article infos section # # when wip, and publish # #--------------------------------------------# -def create_html_infos_section(process): +def create_html_time_meta(process): # Need to reload the DB to get last time updated exec(open(db.config).read(), globals()) - global post_pub, meta_pub, date_raw + global time_html_pub, meta_pub, date_raw + if process == 'wip': date_raw = date_wip #
      \n"] + OPENING = ["ERROR", "
        \n", "
          \n"] + + rank_stack = [] + rank = 0 + cur_rank = 0 + state = 0 + old_state = 0 + work_str = "" + + for i in range(len(items)): + if tyto.words_tags[13][0] in items[i] or \ + tyto.words_tags[13][1] in items[i]: + continue + + rank = cur_rank + descriptor = items[i].split(" ")[0] + text = items[i][items[i].find(" "):].lstrip() + cur_rank = len(descriptor) + + if "=" in descriptor: + state = UL + elif "+" in descriptor: + state = OL + else: + raise(Exception) + + # rank up + if cur_rank > rank: + for i in range(cur_rank - rank - 1): + work_str += " "*(rank+i) + OPENING[rank_stack.append(UL)] + rank_stack.append(state) + + work_str += " "*rank + OPENING[state] + + # rank down + elif cur_rank < rank: + for i in range(rank - cur_rank - 1): + work_str += " "*(rank-i-1) + CLOSING[rank_stack.pop()] + + work_str += " "*cur_rank + CLOSING[rank_stack.pop()] + + work_str += " "*cur_rank + '
        1. ' + text + "
        2. \n" + + work_str += " "*(cur_rank-1) + CLOSING[rank_stack.pop()] + + return work_str + + +#=======================================# +# Replace tag with contents of raw file # +#---------------------------------------# +def wip_fileraws(target): for i in range(1, db.uniq_raws + 1): - raw = 'db.raw_%s'%i - raw_file = open( - '%s%s'%( - db.domain_articles, eval(raw)[1] - ) - ).read() - raw_html = '
          \n'%(
          -               db.domain_css, eval(raw)[2]
          -               ) + \
          -               '  '
          +    raw      = 'db.raw_%s'%i
          +    raw_file = open('%s%s'%(dom.articles_d, eval(raw)[1])).read()
          +    if eval(raw)[2]:
          +      raw_alt = ' # %s'%eval(raw)[2]
          +    raw_inc  = ''%raw_alt
          +    
               for line in raw_file.rsplit('\n'):
          -      raw_html = '%s\n    %s'%(
          -                  raw_html, line
          -                 )
          -
          -    raw_html = '%s\n  \n
          '%(raw_html) - post_bottom = post_bottom.replace(eval(raw)[0], - raw_html - ) - + if not line: + continue + raw_inc = '%s\n%s'%(raw_inc, line) + + raw_inc = '%s\n'%(raw_inc, raw_alt) + replace_in_post(eval(raw)[0], + raw_inc + ) + #=======================# # Make HTML tabulations # #-----------------------# def wip_tabs(): global post_bottom + article_temp = '' tab = tab_start = 6 # From
          tag indiv = False @@ -748,9 +912,17 @@ def wip_tabs(): '6' : '16' } + cs = 0 for line in post_bottom.rsplit('\n'): # Titles - if line.startswith(''): tab = int(tab) - 2 article_temp = '%s\n%s%s'%(article_temp, int(tab) * ' ', line) @@ -780,95 +953,4 @@ def wip_tabs(): article_temp = '%s\n%s%s'%(article_temp, int(tab) * ' ', line) post_bottom = article_temp - -#=================================# -# Convert list in markers to HTML # -# Def from neox <- Thx a lot # -#---------------------------------# -def convert_list(markdown_str): - - # First step : reshape lines - - items = [] - inside_item = 0 - index = -1 - - # Cut string with \n's - strlist = markdown_slangs.site.split("\n") - - # Find items - for i in range(len(strlist)): - if "-(" in strlist[i] or "-)" in strlist[i]: - continue - - if strlist[i][0] != "=" and strlist[i][0] != "+": - if inside_item != 1: - inside_item = 1 - else: - inside_item = 0 - - if inside_item == 0: - items.append(strlist[i]) - index += 1 - - if inside_item == 1: - items[index] += strlist[i].lstrip() - - #print("[{}] index {}, inside_item {}, curstr {}\n".format(i, index, inside_item, strlist[i])) - - # Second step : parsing - UL = 1 - OL = 2 - CLOSING = ["ERROR", "
      \n", "\n"] - OPENING = ["ERROR", "
        \n", "
          \n"] - - rank_stack = [] - rank = 0 - cur_rank = 0 - state = 0 - old_state = 0 - work_str = "" - - for i in range(len(items)): - if "-(" in items[i] or "-)" in items[i]: - continue - rank = cur_rank - descriptor = items[i].split(" ")[0] - text = items[i][items[i].find(" "):] - cur_rank = len(descriptor) - - if "=" in descriptor: - state = UL - elif "+" in descriptor: - state = OL - else: - raise(Exception) - - # rank up - if cur_rank > rank: - for i in range(cur_rank - rank - 1): - work_str += " "*(rank+i) + OPENING[rank_stack.append(UL)] - rank_stack.append(state) - - work_str += " "*rank + OPENING[state] - - # rank down - elif cur_rank < rank: - for i in range(rank - cur_rank - 1): - work_str += " "*(rank-i-1) + CLOSING[rank_stack.pop()] - - work_str += " "*cur_rank + CLOSING[rank_stack.pop()] - - - work_str += " "*cur_rank + "
        1. " + text + "
        2. \n" - - print("[{}] rank_stack {}, state {}, old_state {}, rank {}, cur_rank {}, text {}\n".format( - i, rank_stack, state, old_state, rank, cur_rank, text)) - - work_str += " "*(cur_rank-1) + CLOSING[rank_stack.pop()] - - return(work_str) - - -#print(convert_list(str_exemple)) diff --git a/src/var/lib/tyto/translations/logs_en.py b/src/var/lib/tyto/translations/logs_en.py index 847ccc6..ae40f69 100644 --- a/src/var/lib/tyto/translations/logs_en.py +++ b/src/var/lib/tyto/translations/logs_en.py @@ -46,6 +46,7 @@ post_val = "Article is valid" post_chg = "Article changed: 'check' it first" sep_inv = "Unused separator in article" unused_v = "Unused value in article" +unused_t = "Unused value in header" unused_p = "Empty article" mark_np = "Not paired marks" symb_np = "Not paired symbols" diff --git a/src/var/lib/tyto/translations/logs_fr.py b/src/var/lib/tyto/translations/logs_fr.py index 87ca173..c598c4a 100644 --- a/src/var/lib/tyto/translations/logs_fr.py +++ b/src/var/lib/tyto/translations/logs_fr.py @@ -46,6 +46,7 @@ post_val = "Article valide" post_chg = "Article modifié : commencer par 'check'" sep_inv = "Séparateur manquant dans l'article" unused_v = "Valeur manquante dans l'article" +unused_t = "Valeur manquante dans l'entête" unused_p = "L'article est vide" mark_np = "Marqueurs non jumelés" symb_np = "Symboles non jumelés" diff --git a/src/var/lib/tyto/translations/site_en.py b/src/var/lib/tyto/translations/site_en.py index 92b4caf..663c852 100644 --- a/src/var/lib/tyto/translations/site_en.py +++ b/src/var/lib/tyto/translations/site_en.py @@ -29,7 +29,7 @@ footer = 'Footer' title = 'Title' File = 'File' name = 'Name' -by = 'par' +by = "by" q = '?' i = '!' pp = ":" @@ -45,7 +45,8 @@ tyto_psrc = "Show this article's source code in Tyto format" w_written = "was written the" w_published = "was published the" written = "written the" -published = "wpublished the" +written_by = 'written by' +published = "Published the" # Sidebar site_sdb_t = "Featured..." diff --git a/src/var/lib/tyto/translations/site_fr.py b/src/var/lib/tyto/translations/site_fr.py index ade2b16..1187b06 100644 --- a/src/var/lib/tyto/translations/site_fr.py +++ b/src/var/lib/tyto/translations/site_fr.py @@ -29,7 +29,7 @@ footer = 'Pied de Page' title = 'Titre' File = 'Fichier' name = 'Nom' -by = 'par' +by = "par" q = ' ?' i = ' !' pp = " :" @@ -45,7 +45,8 @@ tyto_psrc = "Voir le code source au format Tyto de cet article" w_written = "a été écrit le" w_published = "a été publié le" written = "écrit le" -published = "publié le" +written_by = 'écrit par' +published = "Publié le" # Barre latérale site_sdb_t = "À l'affiche..." From 99389285b08ca52726f78361f7a0ed54a59fc1a6 Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Tue, 4 Apr 2023 10:54:09 +0200 Subject: [PATCH 215/247] RSS updated (multi-langs). Logs updated --- src/var/lib/tyto/program/check.py | 2 +- src/var/lib/tyto/program/form.py | 73 +++++++++++------------ src/var/lib/tyto/program/html.py | 8 +-- src/var/lib/tyto/program/logs.py | 2 + src/var/lib/tyto/program/publish.py | 32 ++++++---- src/var/lib/tyto/program/rss.py | 75 +++++++++++++++--------- src/var/lib/tyto/program/tyto.py | 13 ++-- src/var/lib/tyto/program/wip.py | 1 - src/var/lib/tyto/translations/logs_en.py | 3 + src/var/lib/tyto/translations/logs_fr.py | 4 +- 10 files changed, 119 insertions(+), 94 deletions(-) diff --git a/src/var/lib/tyto/program/check.py b/src/var/lib/tyto/program/check.py index 3cc37cb..5daf1c0 100644 --- a/src/var/lib/tyto/program/check.py +++ b/src/var/lib/tyto/program/check.py @@ -858,6 +858,6 @@ def create_database(): # Create Post DB #--------------- database = '%s\n%s\n%s'%(database, opt_tags, db_stats) - tyto.set_file(db.config, 'new', database) + tyto.set_file(db.config, 'New', database) logs.out("21", db.uri_file, False) diff --git a/src/var/lib/tyto/program/form.py b/src/var/lib/tyto/program/form.py index 82b472c..b597485 100644 --- a/src/var/lib/tyto/program/form.py +++ b/src/var/lib/tyto/program/form.py @@ -37,7 +37,6 @@ from datetime import datetime import os, sys, re, locale, importlib - import logs, dom, tyto, html, show, langs # locale translation directory @@ -184,7 +183,6 @@ def create_domain(target): # Start registering variables in domain database #----------------------------------------------- - global navbars_conf local_user = '%s/.local/tyto/%s/'%(dom.home_dir, shortname) modules_dir = '%s/articles/_configs/'%dom.folder footer_about_f = '%sfooter_about.html'%modules_dir @@ -215,7 +213,6 @@ def create_domain(target): 'wip_url = "%s"\n'%wip_url tyto.set_file(dom.config, True, set_f) - logs.out("32", dom.config, False) # Get srv root @@ -254,33 +251,34 @@ def create_domain(target): root_srv_dom = '%s/%s'%(srv, shortname) srv_wip_tpl = "%s/wip/template/"%root_srv_dom srv_www_tpl = "%s/www/template/"%root_srv_dom - set_f = '# Servers directories\n' + \ - 'srv_root = "%s/"\n'%srv + \ - 'srv_domain = "%s/"\n'%root_srv_dom + \ - 'srv_wip = "%s/wip/"\n'%root_srv_dom + \ - 'srv_wip_tpl_d = "%s"\n'%srv_wip_tpl + \ - 'srv_wip_images_d = "%s/wip/images/"\n'%root_srv_dom + \ - 'srv_wip_files_d = "%s/wip/files/"\n'%root_srv_dom + \ - 'srv_www = "%s/www/"\n'%root_srv_dom + \ - 'srv_www_tpl_d = "%s"\n'%srv_www_tpl + \ - 'srv_www_images_d = "%s/www/images/"\n'%root_srv_dom + \ - 'srv_www_files_d = "%s/www/files/"\n'%root_srv_dom + \ - '\n' + \ - '# Servers files (wip)\n' + \ - 'wip_logo_f = "%s%s"\n'%(srv_wip_tpl, logo) + \ - 'wip_css_f = "%sstyles.css"\n'%srv_wip_tpl + \ - '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 + \ - 'wip_footer_f = "%sfooter.html"\n'%srv_wip_tpl + \ - '\n' + \ - '# Servers files (www)\n' + \ - 'www_logo_f = "%s%s"\n'%(srv_www_tpl, logo) + \ - 'www_css_f = "%sstyles.css"\n'%srv_www_tpl + \ - '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"'%srv_www_tpl + set_f = \ + '# Servers directories\n' + \ + 'srv_root = "%s/"\n'%srv + \ + 'srv_domain = "%s/"\n'%root_srv_dom + \ + 'srv_wip = "%s/wip/"\n'%root_srv_dom + \ + 'srv_wip_tpl_d = "%s"\n'%srv_wip_tpl + \ + 'srv_wip_images_d = "%s/wip/images/"\n'%root_srv_dom + \ + 'srv_wip_files_d = "%s/wip/files/"\n'%root_srv_dom + \ + 'srv_www = "%s/www/"\n'%root_srv_dom + \ + 'srv_www_tpl_d = "%s"\n'%srv_www_tpl + \ + 'srv_www_images_d = "%s/www/images/"\n'%root_srv_dom + \ + 'srv_www_files_d = "%s/www/files/"\n'%root_srv_dom + \ + '\n' + \ + '# Servers files (wip)\n' + \ + 'wip_logo_f = "%s%s"\n'%(srv_wip_tpl, logo) + \ + 'wip_css_f = "%sstyles.css"\n'%srv_wip_tpl + \ + '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 + \ + 'wip_footer_f = "%sfooter.html"\n'%srv_wip_tpl + \ + '\n' + \ + '# Servers files (www)\n' + \ + 'www_logo_f = "%s%s"\n'%(srv_www_tpl, logo) + \ + 'www_css_f = "%sstyles.css"\n'%srv_www_tpl + \ + '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"'%srv_www_tpl tyto.set_file(dom.config, False, set_f) @@ -758,8 +756,7 @@ def create_metas(option): '\n' + \ '' - tyto.set_file(dom.metas_f, 'new', metas_tags) - logs.out("32", dom.metas_f, False) + 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): @@ -820,8 +817,7 @@ def create_navbar(option): navbar_lang = navbar_lang%(tyto.Tyto, dom.navbar_f) - tyto.set_file(dom.navbar_f, 'new', navbar_lang) - logs.out("32", dom.navbar_f, False) + tyto.set_file(dom.navbar_f, 'New', navbar_lang) # Create wip navbar file html.create_navbar('wip') @@ -836,7 +832,6 @@ def create_sidebar(option): # 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', '') - logs.out("32", dom.wip_sidebar_f, False) # Create new config file, or ask if exists with option = 'reset' if tyto.exists(dom.sidebar_f): @@ -887,8 +882,7 @@ def create_sidebar(option): dom.sidebar_items ) - tyto.set_file(dom.sidebar_f, 'new', sidebar_lang) - logs.out("32", dom.sidebar_f, False) + tyto.set_file(dom.sidebar_f, 'New', sidebar_lang) #=============================# @@ -1054,8 +1048,7 @@ def create_footer(option): if option == "form": return logs.out("255", '', True) - tyto.set_file(dom.footer_f, 'new', footer) - logs.out("32", dom.footer_f, False) + tyto.set_file(dom.footer_f, 'New', footer) # Create footer file in wip server if not exists if not tyto.exists(dom.wip_footer_f): @@ -1083,4 +1076,4 @@ def create_footer_about(option): ''%dom.about tyto.set_file(dom.footer_about_f, False, set_f) - logs.out("32", dom.footer_about_f, False) + diff --git a/src/var/lib/tyto/program/html.py b/src/var/lib/tyto/program/html.py index fa68e76..b5385e2 100644 --- a/src/var/lib/tyto/program/html.py +++ b/src/var/lib/tyto/program/html.py @@ -270,8 +270,7 @@ def create_user_metas(option): if user_metas: user_metas = "%s\n%s%s"%(user_metas, tab, line) else: user_metas = '%s%s'%(tab, line) - tyto.set_file(target, True, user_metas) - logs.out("32", target, False) + tyto.set_file(target, 'New', user_metas) #==============================================# @@ -366,7 +365,6 @@ def create_navbar(option): if not navbar_items: if not tyto.exists(target): tyto.set_file(target, 'New', '') - logs.out("32", target, False) logs.out('28', '%s'%langs.log.navbar, False) return @@ -382,7 +380,6 @@ def create_navbar(option): ), True) tyto.set_file(target, 'New', menu_html) - logs.out("32", target, False) #==============================================# @@ -483,7 +480,6 @@ def create_sidebar(option): if not sidebar_items: if not tyto.exists(target): tyto.set_file(target, 'New', '') - logs.out("32", target, False) logs.out('28', '%s'%langs.log.sidebar, False) return @@ -504,7 +500,6 @@ def create_sidebar(option): ), True) tyto.set_file(target, True, sidebar_content) - logs.out("32", target, False) #===================================================# @@ -533,5 +528,4 @@ def create_user_footer(option): else: footer = '%s%s'%(tab, line) tyto.set_file(target, 'New', footer) - logs.out("32", target, False) diff --git a/src/var/lib/tyto/program/logs.py b/src/var/lib/tyto/program/logs.py index 9777c5a..3d254f8 100644 --- a/src/var/lib/tyto/program/logs.py +++ b/src/var/lib/tyto/program/logs.py @@ -90,6 +90,8 @@ def out(nbr, value, out): '42' : ' ╒ %s%s%s > "%s"'%(CG, langs.log.dom_act, CS, value), '43' : ' ╒ %s%s%s'%(CY, langs.log.dom_no, CS), '44' : ' ╞ %s%s%s "tyto check %s"'%(CY, langs.log.check_m, CS, value), + '45' : ' ╞ %s%s %s%s > %s'%(CY, langs.log.meta_t, langs.log.no_up, CS, value), + '46' : ' ╞ %s%s %s%s > %s'%(CY, langs.log.time_t, langs.log.no_up, CS, value), '51' : ' ╞ %s%s%s > %s'%(CY, langs.log.data_inc, CS, value), '60' : ' │\n ╞ %s'%langs.log.status_r, '255' : ' ╘ %s'%langs.log.laterout diff --git a/src/var/lib/tyto/program/publish.py b/src/var/lib/tyto/program/publish.py index 1665548..7bf1d2e 100644 --- a/src/var/lib/tyto/program/publish.py +++ b/src/var/lib/tyto/program/publish.py @@ -74,7 +74,7 @@ def manage_publish(target): publish_article() # Create new ATOM/RSS file - #rss.create_feed() + rss.create_feed() #===============# @@ -100,10 +100,8 @@ def publish_article(): #-------------------------------------------------# def replace_lines_pub(): html.create_html_time_meta('publish') - print(html.time_html_pub) in_pub = False - time_wip_pub = '' wip_html_post = open(db.post_wip, 'r').read() www_html_post = wip_html_post @@ -116,8 +114,6 @@ def replace_lines_pub(): elif line.startswith(''): time_wip_pub = '%s\n%s'%(time_wip_pub, line) in_pub = False - print('> time_wip_pub') - print(time_wip_pub) break elif line.startswith(''): @@ -127,15 +123,27 @@ def replace_lines_pub(): if in_pub: time_wip_pub = '%s\n%s'%(time_wip_pub, line) - www_html_post = www_html_post.replace(time_wip_pub, - html.time_html_pub - ) - - www_html_post = www_html_post.replace(time_wip_meta, html.meta_pub) + # Update file with new time meta + try: + www_html_post = \ + www_html_post.replace(time_wip_meta, + html.meta_pub + ) + except: + logs.out("45", db.post_www, False) + + # update file with new article time + try: + www_html_post = \ + www_html_post.replace(time_wip_pub, + html.time_html_pub + ) + except: + logs.out("46", db.post_www, False) + #print(www_html_post) - tyto.set_file(db.post_www, 'new', www_html_post) - logs.out("32", db.post_www, False) + tyto.set_file(db.post_www, 'New', www_html_post) #================================# diff --git a/src/var/lib/tyto/program/rss.py b/src/var/lib/tyto/program/rss.py index c8c465c..6833547 100644 --- a/src/var/lib/tyto/program/rss.py +++ b/src/var/lib/tyto/program/rss.py @@ -1,11 +1,27 @@ #!/usr/bin/env python3 -# Name: Tyto - Littérateur -# Type: ATOM/RSS template -# Description: Create raw RSS template -# file: rss.py -# Folder: /var/lib/tyto/program/ -# By echolib (XMPP: im@echolib.re) -# License: GNU AFFERO GENERAL PUBLIC LICENSE Version 3, 19 November 2007 +# 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: Create feed RSS/Atom +# File: /var/lib/tyto/program/rss.py +#---------------------------------------------------------------------- #------------ # funny stats @@ -33,42 +49,48 @@ def create_feed(): '\n' + \ ' \n' + \ ' %s - %s - Flux RSS 2.0\n'%( - db.domain_title, db.domain_www_url - ) + \ - ' %s\n'%db.domain_www_url + \ - ' %s %s (%s)\n'%( - tyto.trans[19][tyto.n], db.domain_title, db.domain_about - ) + \ + dom.title, dom.www_url + ) + \ + ' %s\n'%dom.www_url + \ + ' RSS 2.0 - %s (%s)\n'%( + dom.title, dom.about + ) + \ ' \n' + \ - ' %s/%s\n'%(db.domain_www_url, db.domain_logo) + \ - ' logo %s\n'%db.domain_title + \ - ' %s\n'%db.domain_www_url + \ + ' %s/%s\n'%(dom.www_url, dom.logo) + \ + ' logo %s\n'%dom.title + \ + ' %s\n'%dom.www_url + \ ' \n' + \ - ' %s\n'%db.domain_lang + \ - ' %s\n'%db.domain_tags + \ + ' %s\n'%dom.lang_site + \ + ' %s\n'%dom.tags + \ ' %s\n'%tyto.nowdate() + \ - ' %s\n'%db.domain_license + \ - ' %s\n'%db.domain_mail + \ + ' %s\n'%dom.license + \ + ' %s\n'%dom.mail + \ ' %s'%tyto.Tyto # Sort by newer articles (created by last check) - db_articles = sorted(Path(db.articles_db).iterdir(), + db_articles = sorted(Path(dom.articles_db_d).iterdir(), key=os.path.getmtime, reverse=True ) + rss_item = False nbr_item = 0 + # Loop published articles. Get databases of articles for post_db in db_articles: - if not str(post_db).endswith('.conf'): continue + if not str(post_db).endswith('.config'): + continue # Load DB exec(open(post_db).read(),globals()) - if not hash_www or hash_chk != hash_www: continue + if not hash_www or hash_chk != hash_www: + continue rss_item = True nbr_item += 1 - if nbr_item > dom.rss_items: break + + if nbr_item > dom.rss_items: + break set_f = \ '%s\n'%set_f + \ @@ -81,7 +103,7 @@ def create_feed(): ' %s\n'%author + \ ' \n' + \ ' %s\n'%snpic + \ - ' %s %s\n'%(tyto.trans[20][tyto.n], title) + \ + ' %s\n'%(title) + \ ' %s\n'%http_www + \ ' \n' + \ ' %s\n'%tags + \ @@ -98,6 +120,5 @@ def create_feed(): ' \n' + \ '' - tyto.set_file(db.www_rss, 'New', set_f) - logs.out("33", db.www_rss, False) + tyto.set_file(dom.www_rss_f, 'New', set_f) diff --git a/src/var/lib/tyto/program/tyto.py b/src/var/lib/tyto/program/tyto.py index 87f8d57..2ce06b4 100644 --- a/src/var/lib/tyto/program/tyto.py +++ b/src/var/lib/tyto/program/tyto.py @@ -241,11 +241,12 @@ def edit_file(edit_file): logs.out("1", "/usr/bin/nano", True) -#=================# -# Create a file # -# Or append text # -# new: True/false # -#-----------------# +#=====================# +# Create a file # +# Or append text # +# new: True = create # +# False = Append # +#---------------------# def set_file(path, new, text): if new: opt = "w" else: opt = "a" @@ -254,6 +255,8 @@ def set_file(path, new, text): file = open(path, opt) file.write(text + '\n') file.close() + if opt == 'w': + logs.out("32", path, False) except: logs.out("4", path, True) diff --git a/src/var/lib/tyto/program/wip.py b/src/var/lib/tyto/program/wip.py index 2b8c201..5f3fa5d 100644 --- a/src/var/lib/tyto/program/wip.py +++ b/src/var/lib/tyto/program/wip.py @@ -178,7 +178,6 @@ def wip_article(target): os.makedirs('%s%s'%(dom.srv_wip, db.direc_src), exist_ok=True) logs.out("33", '%s%s'%(dom.srv_wip, db.direc_src), False) tyto.set_file(db.post_wip, 'New', html.main_page) - logs.out("32", db.post_wip, False) # Copy needed files (Also create sub-folders) tyto.files_to_srv('wip') diff --git a/src/var/lib/tyto/translations/logs_en.py b/src/var/lib/tyto/translations/logs_en.py index ae40f69..e315034 100644 --- a/src/var/lib/tyto/translations/logs_en.py +++ b/src/var/lib/tyto/translations/logs_en.py @@ -13,10 +13,13 @@ # Generic sidebar = 'Sidebar' navbar = 'Navbar' +meta_t = ' tag' +time_t = '
      \n%s\n'%(menu_html, 8 * ' ', 6 * ' ') - - # Ask to replace only for www - if option == 'www': - form.asking(' ├ %s. %s(%s)%s '%( - langs.site.navbar, langs.site.form_rep, - option, langs.site.q - ), True) - tyto.set_file(target, 'New', menu_html) @@ -391,7 +392,7 @@ def create_navbar(option): #----------------------------------------------# def create_sidebar(option): dom.valid() - + if not tyto.exists(dom.sidebar_f): logs.out("1", dom.sidebar_f, True) @@ -400,6 +401,13 @@ def create_sidebar(option): if option == 'wip': target = dom.wip_sidebar_f elif option in pub_opts: target = dom.www_sidebar_f + if option == 'www' and tyto.exists(target): + form.asking(' ├ %s. %s%s '%( + langs.site.sidebar, langs.site.form_rep, langs.site.q + ), True) + + print(' │\n ├ %s'%langs.site.sidebar_inf) + sidebar_items = False # Set HTML sidebar @@ -435,7 +443,6 @@ def create_sidebar(option): if not tyto.exists(db_uri): logs.out('25', line, False) continue - # Load article"s database exec(open(db_uri).read(),globals()) @@ -494,13 +501,6 @@ def create_sidebar(option): sidebar_content = '' for line in sidebar_temp.rsplit('\n'): sidebar_content = sidebar_content + '%s%s\n'%(4 * ' ', line) - - # Ask to replace only for www - if option == 'www': - form.asking(' ├ %s. %s(%s)%s '%( - langs.site.sidebar, langs.site.form_rep, - option, langs.site.q - ), True) tyto.set_file(target, True, sidebar_content) @@ -519,6 +519,8 @@ def create_user_footer(option): langs.site.footer, langs.site.form_rep, langs.site.q ), True) + print(' │\n ├ %s'%langs.site.footer_inf) + try: footer_f = open(dom.footer_f, 'r').read() except: logs.out("1", dom.footer_f, True) diff --git a/src/var/lib/tyto/program/infos.py b/src/var/lib/tyto/program/infos.py index 5b97aa0..976614b 100644 --- a/src/var/lib/tyto/program/infos.py +++ b/src/var/lib/tyto/program/infos.py @@ -33,7 +33,15 @@ #********************************************************************** -import os, langs +import os, importlib +import langs +importlib.reload(langs) + +# Set colors +CS = '\033[0;0m' +CR = '\033[1;31m' +CY = '\033[1;33m' +CG = '\033[1;32m' def tyto(target): noinfos = False @@ -48,19 +56,46 @@ def tyto(target): # Show domains list try: - db_domains = '%s/.local/tyto'%os.path.expanduser('~') + has_domains = True user = os.environ.get('USER') - hashdomain = False - print('# Registred domains for', user) - for folder in os.listdir(db_domains): - if os.path.isdir('%s/%s'%(db_domains, folder)): - if hashdomain: - hasdomain = False - hashdomain = True - print(' -', folder) + user_dir = os.path.expanduser('~') + db_domains = '%s/.local/tyto'%user_dir except: - noinfo = True - print(':< No .../.local/tyto') + has_domains = False - print(':', langs.site.args_helps) + if not os.path.exists(db_domains): + has_domains = False + print('! No directory > %s/'%db_domains) + + if has_domains: + list_domains = (()) + for folder in os.listdir(db_domains): + domain_local_uri = '%s/%s'%(db_domains, folder) + if os.path.isdir(domain_local_uri): + domain_conf = '%s/domain_config.bkp'%domain_local_uri + if os.path.exists(domain_conf): + try: + exec(open(domain_conf).read(),globals()) + except: + continue + if os.path.exists(directory): + dir_domain = '%s%s%s'%(CG, directory, CS) + else: + dir_domain = '%s%s%s'%(CR, directory, CS) + list_domains = \ + (('%s > %s > %s'%(folder, dir_domain, www_url)),) + + if list_domains: + print('# %s %ss %s'%( + langs.site.reg_domains, + langs.site.fo, + user + ) + ) + for domain in list_domains: + print(' - %s'%domain) + + + # Show arguments help + print(langs.site.args_helps) diff --git a/src/var/lib/tyto/program/langs.py b/src/var/lib/tyto/program/langs.py index 200cbde..2fc4ffa 100644 --- a/src/var/lib/tyto/program/langs.py +++ b/src/var/lib/tyto/program/langs.py @@ -59,11 +59,7 @@ try: log = importlib.import_module('logs_%s'%lang_logse, package=None) except: log = importlib.import_module('logs_%s'%lang_sys, package=None) -''' - exec(open('%s/logs_%s.py'%(trans_dir, lang.logs)).read()) -except: - exec(open('%s/logs_%s.py'%(trans_dir, lang_sys)).read()) -''' + # Set language site/form from configuration domain # or set default english if not known diff --git a/src/var/lib/tyto/program/logs.py b/src/var/lib/tyto/program/logs.py index 5e041fe..c23549b 100644 --- a/src/var/lib/tyto/program/logs.py +++ b/src/var/lib/tyto/program/logs.py @@ -96,6 +96,16 @@ def out(nbr, value, out): '51' : ' ╞ %s%s%s > %s'%(CY, langs.log.data_inc, CS, value), '60' : ' │\n ╞ %s'%langs.log.status_r, '61' : ' ╞ %s%s%s > %s'%(CG, langs.log.file_e, CS, value), + '71' : ' ╞═ %s%s%s > %s'%(CY, langs.log.post_nwi, CS, value), + '72' : ' ╞═ %s%s%s > %s'%(CG, langs.log.post_wip, CS, value), + '73' : ' ╞═ %s%s%s > %s'%(CY, langs.log.st_wip_n, CS, value), + '74' : ' ╞═ %s%s%s > %s'%(CY, langs.log.st_wip_o, CS, value), + '81' : ' ╞═ %s%s%s > %s'%(CY, langs.log.post_nww, CS, value), + '82' : ' ╞═ %s%s%s > %s'%(CG, langs.log.post_www, CS, value), + '83' : ' ╞═ %s%s%s > %s'%(CY, langs.log.st_www_n, CS, value), + '84' : ' ╞═ %s%s%s > %s'%(CY, langs.log.st_www_o, CS, value), + '85' : ' ╞═ %s%s%s > %s'%(CY, langs.log.was_pub, CS, value), + '94' : ' ╞═ %s%s%s > %s'%(CY, langs.log.st_chk_o, CS, value), '255' : ' ╘ %s'%langs.log.laterout } diff --git a/src/var/lib/tyto/program/publish.py b/src/var/lib/tyto/program/publish.py index ba3db2d..8cd3bf1 100644 --- a/src/var/lib/tyto/program/publish.py +++ b/src/var/lib/tyto/program/publish.py @@ -71,16 +71,95 @@ def manage_publish(target): # Publish in www server an article check_to_publish('one') + + # Article already published + if db.file_www: + logs.out("85", '%s > %s'%(db.date_chk, db.uri_file), False) + answer = form.asking(' ├ %s%s '%( + langs.site.publish_a, langs.site.q + ), True) + + # Publish publish_article() # Create new ATOM/RSS file rss.create_feed() +#============================================# +# Option 'all' to publish again, based on DB # +#--------------------------------------------# +def publish_all(option): + tyto.show_multi_message('www', dom.srv_www) + form.asking(' ├ %s%s '%(langs.site.proceed, langs.site.q), True) + + # Sort by newer articles (created by last check) + db_articles = sorted(Path(dom.articles_db_d).iterdir(), + key=os.path.getmtime + ) + + # Load domain configuration DB + option = args.target + found = False + for post_db in db_articles: + if not str(post_db).endswith('.config'): continue + + # Load DB + exec(open(post_db).read(),globals()) + args.target = short_src + importlib.reload(db) + + if option == "again" and not db.www_again: continue + elif option == "added" and not db.www_added: continue + elif option == "updated" and not db.www_updated: continue + + check_to_publish('all') + if err_pub: + continue + + found = True + publish_article() + + if not found: + logs.out("28", 'publish %s'%option, True) + + # If found: create new ATOM/RSS file + rss.create_feed() + + +#==============================# +# Check if it can be published # +#------------------------------# +def check_to_publish(process): + global err_pub + err_pub = False + + print(' │\n ├ [%s] > %s'%(db.title, db.post_src)) + + # Article was not checked or changed + if db.no_chk: + logs.out("25", db.uri_file, False) + err_pub = 25 + elif db.old_chk: + logs.out("9", db.uri_file, False) + err_pub = 9 + + # Article must exists in wip server + if db.no_wip or db.old_wip: + logs.out("30", db.uri_file, False) + err_pub = 30 + elif not db.file_wip: + logs.out("1", db.post_wip, False) + err_pub = 1 + + if err_pub: + if process == 'all': return + elif process == 'one': sys.exit(err_pub) + #===============# # Let's publish # #---------------# -def publish_article(): +def publish_article(): # Copy wip page to www page if not os.makedirs('%s%s'%(dom.srv_www, db.direc_src), exist_ok=True): logs.out("33", '%s%s'%(dom.srv_www, db.direc_src), False) @@ -142,7 +221,6 @@ def replace_lines_pub(): logs.out("46", db.post_www, False) - #print(www_html_post) tyto.set_file(db.post_www, 'New', www_html_post) @@ -183,86 +261,3 @@ def publish_template(option): html.create_user_footer('pub') -#============================================# -# Option 'all' to publish again, based on DB # -#--------------------------------------------# -def publish_all(option): - # Ask or show what to do - if args.target == "again": - form.asking(" ├ %s%s "%( - langs.site.wip_again, langs.site.q - ), True) - - elif args.target == "addedd": - print(' │ %s'%langs.site.wip_older) - #os.chdir(dom.articles_d) - - elif args.target == "updated": - print(' │ %s'%langs.site.wip_newer) - - # Sort by newer articles (created by last check) - db_articles = sorted(Path(dom.articles_db_d).iterdir(), - key=os.path.getmtime - ) - - # Load domain configuration DB - option = args.target - found = False - for post_db in db_articles: - if not str(post_db).endswith('.config'): continue - - # Load DB - exec(open(post_db).read(),globals()) - args.target = short_src - importlib.reload(db) - - if not db.hash_wip: continue - if option == "again" and not db.sync_srvs: continue - if option == "added" and not db.old_www: continue - - if db.old_chk: - logs.out("9", '', False) - continue - - check_to_publish('all') - if err_pub: continue - - found = True - publish_article() - - if not found: - logs.out("28", '(publish)', True) - else: - # Create new ATOM/RSS file - rss.create_feed() - - -#==============================# -# Check if it can be published # -#------------------------------# -def check_to_publish(process): - global err_pub - err_pub = False - - print(' │\n ├─ [%s] > %s'%(db.title, db.post_src)) - - # Article was not checked or changed - if db.no_chk: - logs.out("25", db.uri_file, False) - err_pub = 25 - elif db.old_chk: - logs.out("9", db.uri_file, False) - err_pub = 9 - - # Article must exists in wip server - if db.no_wip or db.old_wip: - logs.out("30", db.uri_file, False) - err_pub = 30 - elif not db.file_wip: - logs.out("1", db.post_wip, False) - err_pub = 1 - - if err_pub: - if process == 'all': return - elif process == 'one': sys.exit(err_pub) - diff --git a/src/var/lib/tyto/program/rss.py b/src/var/lib/tyto/program/rss.py index 6833547..add7c84 100644 --- a/src/var/lib/tyto/program/rss.py +++ b/src/var/lib/tyto/program/rss.py @@ -35,7 +35,7 @@ import os from pathlib import Path -import logs, dom, db, tyto +import logs, dom, db, tyto, langs #============================# @@ -120,5 +120,6 @@ def create_feed(): ' \n' + \ '' + print(' │\n ├─ %s'%langs.site.rss_c) tyto.set_file(dom.www_rss_f, 'New', set_f) diff --git a/src/var/lib/tyto/program/status.py b/src/var/lib/tyto/program/status.py index 2bd5324..fdedd8c 100644 --- a/src/var/lib/tyto/program/status.py +++ b/src/var/lib/tyto/program/status.py @@ -33,7 +33,7 @@ #********************************************************************** -import args, dom, logs, tyto, form +import args, dom, logs, tyto, form, db def domain(): if dom.hole: logs.out("13", '', True) @@ -80,9 +80,13 @@ def domain(): # On demand with status action # #------------------------------# def check(target): - conf_err = False - - if target == "domain": + # target needed + if not target: + logs.out("5", '[target]', True) + + elif target == "domain": + conf_err = False + if dom.dir_unu or dom.file_unu: logs.out("60", '', False) @@ -93,6 +97,37 @@ def check(target): for file_unu in dom.file_unu: logs.out("24", file_unu, False) - if conf_err: - logs.out("31", '', True) + if conf_err: + logs.out("31", '', True) + return + + # Unused file + elif not db.post: + logs.out("1", db.uri_file, True) + + # Article has DB + elif db.exists: + # Article datas + print(' │\n ├ [%s] > %s'%(db.title, db.uri_file)) + + # chk + if db.old_chk: logs.out("94", db.uri_file, False) + else: logs.out("20", db.uri_file, False) + + # wip + if not db.file_wip: logs.out("71", db.post_wip, False) + else: logs.out("72", db.post_wip, False) + if db.no_wip: logs.out("73", db.post_wip, False) + elif db.old_wip: logs.out("74", db.post_wip, False) + + # www + if not db.file_www: logs.out("81", db.post_www, False) + else: logs.out("82", db.post_www, False) + if db.no_www: logs.out("83", db.post_www, False) + elif db.old_www: logs.out("84", db.post_www, False) + return + + # Article has NO DB + elif not db.exists: + logs.out("25", db.uri_file, True) diff --git a/src/var/lib/tyto/program/tyto.py b/src/var/lib/tyto/program/tyto.py index 49b36bf..fc5d422 100644 --- a/src/var/lib/tyto/program/tyto.py +++ b/src/var/lib/tyto/program/tyto.py @@ -35,7 +35,7 @@ import os, sys, re, subprocess, locale, base64, datetime, shutil from hashlib import blake2b -import args, dom, logs +import args, dom, logs, langs # :D Tyto = 'Tyto - Littérateur' @@ -182,6 +182,11 @@ quote_tags = [ # Tags to check in header in content _TAG head_tags = ("image:", "raw:", "code;") +# Valid characters for some datas +chrs_invalid = \ +set('{}[]_()+*=/:%~´') + + # Stats for icodes, bcodes, quotes nbr_icodes = 0 @@ -197,6 +202,18 @@ def exists(uri): else: return(False) +#========================================# +# Return converted valid HTML characters # +#----------------------------------------# +def convert_altname(altname): + altname = altname.replace('<', '<') + altname = altname.replace('>', '>') + altname = altname.replace('"', '"') + altname = altname.replace("'", ''') + + return altname + + #=======================# # Return sum of srcfile # # src: True = Content # @@ -309,8 +326,7 @@ def protect_bcodes_quotes(process, post_bottom): in_bcode = False if process == "wip": bcode = '%s\n%s'%(bcode, line) - bcode = bcode.replace('<', '<') - bcode = bcode.replace('>', '>') + bcode = convert_altname(bcode) b64_bcode = b64('Encode', bcode, 'B64.', '.B64') line = b64_bcode @@ -324,8 +340,7 @@ def protect_bcodes_quotes(process, post_bottom): in_quote = False if process == "wip": quote = '%s\n%s'%(quote, line) - quote = quote.replace('<', '<') - quote = quote.replace('>', '>') + quote = convert_altname(quote) b64_quote = b64('Encode', quote, 'Q64.', '.Q64') line = b64_quote @@ -408,8 +423,7 @@ def protect_icodes(post_bottom): # No more in code if if c_a == '}' and not c_b == '\\': in_icode = False - src_code = src_code.replace('<', '<') - src_code = src_code.replace('>', '>') + src_code = convert_altname(src_code) code = '%s%s%s'%(code, src_code, words_tags[9][3]) b64_code = b64('Encode', code, 'I64.', '.I64') rep_code = "%s%s%s"%( @@ -535,3 +549,18 @@ def files_to_srv(server): logs.out("32", f_dst, False) except: logs.out('4', f_dst, True) + + +#========================================# +# For mass treatment, show message about # +#----------------------------------------# +def show_multi_message(server, srv_dir): + if args.target == "added": + print(" │ %s '%s' > %s"%(langs.site.srv_added, server, srv_dir)) + + elif args.target == "updated": + print(" │ %s '%s' > %s "%(langs.site.srv_updated, server, srv_dir)) + + elif args.target == "again": + print(" │ %s '%s' > %s"%(langs.site.srv_again, server, srv_dir)) + diff --git a/src/var/lib/tyto/program/wip.py b/src/var/lib/tyto/program/wip.py index f46dd2e..a9c0759 100644 --- a/src/var/lib/tyto/program/wip.py +++ b/src/var/lib/tyto/program/wip.py @@ -40,6 +40,7 @@ import os, re, sys, locale, shutil, importlib, time from pathlib import Path import args, logs, langs, dom, db, tyto, html, form, stats + #=========================================# # Manage wip action with option as target # #-----------------------------------------# @@ -85,34 +86,15 @@ def manage(target): elif db.old_chk: logs.out("9", db.uri_file, True) - # Article has changed or wip file missing - if db.old_wip or not db.file_wip: - wip_article(db.uri_file) - - # wip is up-to-date: ask to wip again - else: - logs.out("19", db.date_wip, False) - form.asking(' ├ [%s] %s%s '%( - db.title, langs.site.wip_new, langs.site.q - ), True) - wip_article(db.uri_file) + # Create HTML page + wip_article(db.uri_file) #========================================# # Option 'all' to wip again, based on DB # #----------------------------------------# -def wip_all(process): - # Ask or show what to do - if args.target == "again": - form.asking(" ├ %s%s "%( - langs.site.wip_again, langs.site.q - ), True) - - elif args.target == "addedd": - print(' │ %s'%langs.site.wip_older) - - elif args.target == "updated": - print(' │ %s'%langs.site.wip_newer) +def wip_all(process): + tyto.show_multi_message('wip', dom.srv_wip) # Sort by newer articles (created by last check) db_articles = sorted(Path(dom.articles_db_d).iterdir(), @@ -133,23 +115,10 @@ def wip_all(process): importlib.reload(db) except: continue - - # Article has changed and not check - if db.old_chk: - logs.out("9", db.post_src, False) - continue - - # newer: article not yet wip - elif option == "added" and db.hash_wip: - continue - - # All: only old wip - elif option == "updated" and not db.old_wip: - continue - - # again: wip again wip articles - elif option == "again" and not db.hash_wip: - continue + + if option == "added" and not db.wip_added: continue + elif option == "updated" and not db.wip_updated: continue + elif option == "again" and not db.wip_again: continue found = True wip_article(db.post_src) @@ -175,7 +144,7 @@ def wip_article(target): # Convert file to strings file_to_string(target) - print(' │\n ├─ [%s] > %s'%(db.title, db.post_src)) + print(' │\n ├ [%s] > %s'%(db.title, db.post_src)) global post_header global post_bottom @@ -192,11 +161,11 @@ def wip_article(target): # Convert contents from modules + wip_images() # Images_%i from headers in DB wip_single_tags() # br /, anchors wip_words_tags() # Paragraphs, strongs, italics wip_links() # Links_%i from headers in DB wip_abbrs() # Convert abbr - wip_images() # Images_%i from headers in DB 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 @@ -234,15 +203,16 @@ def file_to_string(post_file): for line in article.rsplit('\n'): if line.startswith('-----'): - sep = True - continue + if not sep: + sep = True + continue if sep: if not post_bottom: post_bottom = line - else: post_bottom = '%s\n%s'%(post_bottom, line) + else: post_bottom = '%s\n%s'%(post_bottom, line) else: if not post_header: post_header = line - else: post_header = '%s\n%s'%(post_header, line) + else: post_header = '%s\n%s'%(post_header, line) #===============================================================# @@ -383,9 +353,12 @@ def wip_abbrs(): abbr_src = '%s' for i in range(1, db.uniq_abbrs + 1): - abbr = 'db.abbr_%s'%i - try: abbr_show = eval(abbr)[2] - except: abbr_show = eval(abbr)[0] + abbr = 'db.abbr_%s'%i + + abbr_show = eval(abbr)[2] + if not eval(abbr)[2]: + abbr_show = eval(abbr)[0][1:-1] + abbr_html = abbr_src%(dom.css, eval(abbr)[1], abbr_show @@ -689,7 +662,7 @@ def wip_bcodes(): # Block-code content per line else: html_bcode = \ - '%s\n
      %s
      '%( + '%s\n

      %s

      '%( html_bcode, line ) @@ -779,17 +752,19 @@ def wip_filecode(target): for i in range(1, db.uniq_codes + 1): code = 'db.code_%s'%i code_file = open('%s%s'%(dom.articles_d, eval(code)[1])).read() - code_html = '
      \n'%(
      +    code_html = '\n'%(
                       dom.css, eval(code)[2]
                       ) + \
      -                '  '
      +                '  
      '
           
           for line in code_file.rsplit('\n'):
      -      code_html = '%s\n    %s'%(
      +      line      = line.replace('<', '<')
      +      line      = line.replace('>', '>')
      +      code_html = '%s\n    

      %s

      '%( code_html, line ) - code_html = '%s\n
      \n
      '%(code_html) + code_html = '%s\n
      \n'%(code_html) replace_in_post(eval(code)[0], code_html ) @@ -803,21 +778,21 @@ def wip_lists(): global post_bottom - content_list = '' in_list = False for line in post_bottom.rsplit('\n'): # Open list if line.startswith(tyto.words_tags[13][0]): + block_list = content_list = '' css = tyto.get_css(line) in_list = True - content_list = line + block_list = line continue # Close list elif line.startswith(tyto.words_tags[13][1]): in_list = False - content_list = '%s\n%s'%(content_list, line) + block_list = '%s\n%s'%(block_list, line) html_list = convert_list( content_list ).replace('
        ', @@ -825,10 +800,14 @@ def wip_lists(): ).replace('
      • ', '
      • '%css ) - replace_in_post(content_list, html_list) + + replace_in_post(block_list, html_list) + if in_list: - content_list = '%s\n%s'%(content_list, line) + block_list = '%s\n%s'%(block_list, line) + if not content_list: content_list = line + else: content_list = '%s\n%s'%(content_list, line) else: continue diff --git a/src/var/lib/tyto/translations/logs_en.py b/src/var/lib/tyto/translations/logs_en.py index c53c2e3..88a7436 100644 --- a/src/var/lib/tyto/translations/logs_en.py +++ b/src/var/lib/tyto/translations/logs_en.py @@ -42,12 +42,31 @@ file_e = "File exists" dir_c = "Directory created" dir_e = "Directory exists" -was_chk = "Article 'check'" -was_wip = "Article already 'wip'" -check_m = "Check manually" +# chk +nycheck = "Article not yet checked" +was_chk = "Article was 'check'" +st_chk_o = "Old 'check' status" post_inc = "Unused in article" post_inv = "Article not valid" post_val = "Article is valid" + +# wip +nywip = "Article not yet wip" +was_wip = "Article was 'wip'" +post_nwi = "Article not in 'wip'" +st_wip_n = "Unused 'wip' status" +st_wip_o = "Old 'wip' status" +post_wip = "Article is in 'wip'" + +# www +was_pub = "Article was published" +post_nww = "Article not in 'www'" +st_www_n = "Unused 'www' status" +st_www_o = "Old 'www' status" +post_www = "Article is in 'www'" + +# Misc +check_m = "Check manually" post_chg = "Article changed: 'check' it first" sep_inv = "Unused separator in article" unused_v = "Unused value in article" @@ -58,8 +77,6 @@ symb_np = "Not paired symbols" snpic_d = "Using default snpic. Not found" anch_nu = "Anchor not uniq" nyfile = "file not yet created" -nycheck = "Article not yet checked" -nywip = "Article not yet wip" add = "Add:" nomods = "Create HTML modules first" status_r = "Checking unused ressources..." diff --git a/src/var/lib/tyto/translations/logs_fr.py b/src/var/lib/tyto/translations/logs_fr.py index 2c44941..26a96eb 100644 --- a/src/var/lib/tyto/translations/logs_fr.py +++ b/src/var/lib/tyto/translations/logs_fr.py @@ -41,12 +41,31 @@ file_e = "Fichier présent" dir_c = "Dossier créé" dir_e = "Dossier présent" +# chk +nycheck = "Article pas encore 'check'" was_chk = "Article déjà vérifié" -was_wip = "Article déjà 'wip'" -check_m = "Vérifier manuellement" +st_chk_o = "Statut 'check' Ancien" post_inc = "Donnée manquante dans l'article" post_inv = "Article non valide" post_val = "Article valide" + +# Wip +nywip = "Article pas encore 'wip'" +was_wip = "Article déjà 'wip'" +post_nwi = "Article non présent dans 'wip'" +st_wip_n = "Statut 'wip' Non présent" +st_wip_o = "Statut 'wip' Ancien" +post_wip = "Article présent dans 'wip'" + +# www +was_pub = "Article déjà publié" +post_nww = "Article non présent dans 'www'" +st_www_n = "Statut 'www' Non présent" +st_www_o = "Statut 'www' Ancien" +post_www = "Article présent dans 'www'" + +# Misc +check_m = "Vérifier manuellement" post_chg = "Article modifié : commencer par 'check'" sep_inv = "Séparateur manquant dans l'article" unused_v = "Valeur manquante dans l'article" @@ -57,8 +76,8 @@ symb_np = "Symboles non jumelés" snpic_d = "snpic utilisé par défaut. Manquant" anch_nu = "Ancre non unique" nyfile = "Fichier pas encore créé" -nycheck = "Article pas encore 'check'" -nywip = "Article pas encore 'wip'" + + add = "Ajout:" nomods = "Créer d'abord les modules HTML" status_r = "Vérification des ressources manquantes..." diff --git a/src/var/lib/tyto/translations/site_en.py b/src/var/lib/tyto/translations/site_en.py index a1e655e..92ce345 100644 --- a/src/var/lib/tyto/translations/site_en.py +++ b/src/var/lib/tyto/translations/site_en.py @@ -30,6 +30,8 @@ File = 'File' name = 'Name' by = "by" le = "the" +fo = "for" +proceed = "Continue" q = '?' i = '!' pp = ":" @@ -66,14 +68,26 @@ mail_to = "Contact by %s the admin of"%mail.lower() feed = "Feed" generator = "Generator" +# Misc for Tyto +#-------------- # Check +check_a = "Check again this article" post_chg = "Article was edited. Check it" # Wip wip_new = "Create a new HTML page in 'wip' server again" -wip_again = "Create already converted pages again" -wip_newer = "Create missing HTML pages" -wip_older = "Update HTMl pages" +srv_again = "Create again converted HTMl pages in server" +srv_added = "Create missing HTML pages in server" +srv_updated = "Update HTMl pages in server" + +# publish +publish_a = "Publish again this article" +rss_c = "Create ATOM/RSS feed" + +# Other +uptpl = "Update directory" +stats_f = "Articles: %s (%s words)" +reg_domains = 'Registred domains' # Form #---------------------------------------------------------------------- @@ -131,14 +145,10 @@ form_file_c = "File created" form_reset = "Reset configuration?" form_rep = "Replace HTML file" -check_a = "Check again this article" - -uptpl = "Update directory" - -stats_f = "Articles: %s (%s words)" # Documentation of configuration files #------------------------------------- +metas_inf = "Create tags" metas_doc = \ '# For %s\n' + \ '# Type text/HTML file\n' + \ @@ -152,6 +162,7 @@ metas_doc = \ '# - Do NOT copy this file to template directory\n' + \ '# - These tags are already set' +navbar_inf = "Create navbar" navbar_doc = \ '# For %s\n' + \ '# Type: Text file\n' + \ @@ -179,6 +190,7 @@ navbar_doc = \ '# about # infos about this website\n' + \ '# %s\n\n'%(20 * "-") +sidebar_inf = "Create sidebar" sidebar_doc = \ '# For %s\n' + \ '# Type Text file\n' + \ @@ -204,6 +216,7 @@ sidebar_doc = \ '# dir1/index.tyto\n' + \ '# %s\n\n'%(20 * "-") +footer_inf = "Create footer" footer_doc = \ '# For %s\n' + \ '# Type text/HTML file\n' + \ @@ -235,54 +248,87 @@ footer_about_doc = \ '# %s\n'%(20 * "-") # Help with Tyto commands -args_helps = """\n# New domain: - - Create your domain folder, and go in +args_helps = """\n# New domain : + - Create directory and go in - Create domain with 'tyto new domain [URL]' - - Create article file in articles/ directory - - Use these actions on article file: Check > wip > publish - ! Config files are in _configs/ directory - and used to create HTML file in your template - Your template files (css, logo...) go to wip/template/ server + - Create .tyto file in directory "articles/" + - Use these actions: check > wip > publish + ! - Modules files are in directory "_configs/" + and used to custom some website parts + - (css, logo...) files go in "wip/template/" # Usage: tyto [action] [target] - - [action] > according to [target]: - edit : Edit a file (article, config module) - edit-about: specific for (footer), or like [edit-db] - edit-db : Edit a config file (domain, article (TAKE CARE !)) - edit-wip : Edit html file in wip server - edit_www : Edit html file in www server - new : Create new (domain, sidebar/footer... config's file) - show : Show content file (article, config's module) - show-about: specific for (footer), or like [show-db] - show-db : Show content of article database - show-wip : Show content of HTML file in wip server - show-www : Show content of HTML file in www server\n - check : Check if article is valid and ready to convert - wip : Create HTML page in wip server - publish : Create HTML page in www server\n - - [target] > according to [action] - all : update changed articles - again : process again ALL valid articles - newer : [wip/publish] convert only newer articles - [check] process not yet checked .tyto files in domain - template : - Create new navbar/sidebar/metas/footer in www server - - Copy other wip/template/ files to www server - domain : Create/Show domain config's file - [file] : URI of an article file (autocompletion's friend) - footer : Create/Show footer HTML config file - metas : Create/Show metas HTML config file - navbar : Create/Show navbar config file - sidebar : Create/Show sidebar config file - stats : Create statistics file in root server\n -# Examples: - - Check article syntax: tyto check mysubdir/index.tyto - - Create default _configs/tyto.sidebar: tyto new sidebar - - Edit _configs/tyto.navbar: tyto edit navbar - (each edition launches process if file changed like: - - check - - (navbar, sidebar, metas, footer) : create file on wip server) - - Edit index.html in www server: tyto edit-www index.tyto - - Create sidebar.html in wip server: tyto wip sidebar - - Show footer.html in wip server: tyto show-wip footer - - Create metas.html in www server: tyto publish metas - - Show navbar.html in www server: tyto show-www navbar""" + # Actions + - [action] > According to [target] + + # Edit a file + edit : Source file, configuration module + edit-about: [footer] Edit description section in footer + or same as [edit-db] + edit-db : Edit database/configuration file + edit-wip : Edit a file in server 'wip' + edit_www : Edit a file in server 'www' + new : [domain] Créer un domaine ou le modifier via le formulaire + [sidebar, navbar, footer, metas] Create and replace + with default module configuration file + + # Show contents file (with line number) + show : Show source file, source configuration module + show-about: [footer] Show description footer file + or same as [show-db] + show-db : Show database/configuration file + show-wip : Show a file in server 'wip' + show-www : Show a file in server 'www' + + # Create HTML page + 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' + + # Targets + - [target] > According to [action] + + # Multiple articles + updated : Update articles (already checked) + again : Force all articles (already checked) + added : [check] Search and check for .tyto articles in domain + (not yet checked) + [wip, publish] Create articles HTML pages + that were edited and checked + + # Update modules/files template + template : - Create (replace) modules in directory "template/" + - [publish] Also, copy all other files from "wip/template/" + + # Domain and files + domain : Create or edit a domain + [file] : URI file (autocompletion friendly) + + # Modules + footer : Footer configuration file + metas : , configuration file + navbar : Navbar configuration file + sidebar : Sidebar configuration file + stats : Stats file (server 'wip' er 'www') + +# Examples : + # Check article (according to sub-folder) + $ tyto check mysubdir/index.tyto + + # Create (replace) default sidebar configuration file + $ tyto new sidebar + + # Edit navbar configuration file + $ tyto edit navbar + + # edit doc/index.html in server 'www' + $ tyto edit-www doc/index.tyto + + # Create HTML sidebar file in server 'wip' + $ tyto wip sidebar + + # Show footer HTML file in server 'wip' + $ tyto show-wip footer + + # Create statistics file in serveur 'www' + $ tyto publish stats""" diff --git a/src/var/lib/tyto/translations/site_fr.py b/src/var/lib/tyto/translations/site_fr.py index 6f621db..78d7ddc 100644 --- a/src/var/lib/tyto/translations/site_fr.py +++ b/src/var/lib/tyto/translations/site_fr.py @@ -21,7 +21,7 @@ # Generic article = "Article" sidebar = 'Barre Latérale' -navbar = 'Barre de navigation' +navbar = 'Barre de menu' metas = 'Balises Metas' footer = 'Pied de Page' title = 'Titre' @@ -29,6 +29,8 @@ File = 'Fichier' name = 'Nom' by = "par" le = "le" +fo = "pour" +proceed = "Continuer" q = ' ?' i = ' !' pp = " :" @@ -65,14 +67,27 @@ mail_to = "Contacter par %s l'administrateur de"%mail.lower() feed = "Flux" generator = "Generateur" + +# Misc for Tyto +#-------------- # Check +check_a = "Vérifier encore l'article" post_chg = "Article édité. Le vérifier" # Wip wip_new = "Créer encore une page HTML dans le serveur 'wip'" -wip_again = "Créer encore les pages déjà converties" -wip_newer = "Créer les pages HTML manquantes" -wip_older = "Mise à jour des pages HTML" +srv_again = "Créer encore les pages dans le serveur" +srv_added = "Créer les pages HTML manquantes dans le serveur" +srv_updated = "Mise à jour des pages HTML dans le serveur" + +# publish +publish_a = "Publier encore l'article" +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' # Formulaire #---------------------------------------------------------------------- @@ -131,14 +146,10 @@ form_file_c = "Fichier créé" form_reset = "Réinitialiser la configuration" form_rep = "Remplacer le fichier HTML" -check_a = "Vérifier encore l'article" - -uptpl = "Mettre à jour le dossier" - -stats_f = "Articles : %s (%s mots)" # Documentation des fichiers de configuration #-------------------------------------------- +metas_inf = "Créer les balises " metas_doc = \ '# Pour %s\n' + \ '# Type Fichier text/HTML\n' + \ @@ -152,6 +163,7 @@ metas_doc = \ '# - Ne PAS copier ce fichier dans le dossier template\n' + \ '# - Les balises suivantes sont déjà présentes' +navbar_inf = "Créer la barre de menu" navbar_doc = \ '# Pour %s\n' + \ '# Type fichier texte\n' + \ @@ -179,6 +191,7 @@ navbar_doc = \ '# a-propos # Informations concernant ce site\n' + \ '# %s\n\n'%(20 * "-") +sidebar_inf = "Créer la barre latérale" sidebar_doc = \ '# Pour %s\n' + \ '# Type fichier texte\n' + \ @@ -204,6 +217,7 @@ sidebar_doc = \ '# dir1/index.tyto\n' + \ '# %s\n\n'%(20 * "-") +footer_inf = "Créer le pied de page" footer_doc = \ '# Pour %s\n' + \ '# Type Fichier text/HTML\n' + \ @@ -238,18 +252,18 @@ footer_about_doc = \ args_helps = """\n# Nouveau domaine : - Créer un dossier et aller dedans - Créer un domain avec 'tyto new domain [URL]' - - Créer un fichier .tyto dans le dossier articles/ + - Créer un fichier .tyto dans le dossier "articles/" - Utiliser les actions check > wip > publish - ! - Les fichiers des modules sont dans le dossier _configs/ + ! - Les fichiers des modules sont dans le dossier "_configs/" et utilisés pour personnaliser certaines parties du site - - Les fichier (css, logo...) vont dans le dossier serveur wip/template/ + - Les fichier (css, logo...) vont dans le dossier serveur "wip/template/" # Usage: tyto [action] [target] # Les actions - [action] > Selon l'argument [target] # Modifier un ficher - edit : fichier source, module de configuration + 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 @@ -260,7 +274,7 @@ args_helps = """\n# Nouveau domaine : fichier de configuration du module par le défaut # Afficher un fichier (avec numéros de ligne) - show : fichier source, module de configuration + 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 @@ -284,7 +298,7 @@ args_helps = """\n# Nouveau domaine : qui ont été modifiés et vérifiés # Mise en ligne du thème et des modules - template : - Recréer les modules HTML dans le serveur 'www' + template : - Recréer les modules HTML dans "template/" - Copie tous les autres fichier du dossier wip/template/ # Domaine et fichier @@ -311,7 +325,7 @@ args_helps = """\n# Nouveau domaine : # Modifier doc/index.html dans le serveur 'www' $ tyto edit-www doc/index.tyto - # Créer le module HTML (serveur 'wip') de la barre latérale + # Créer le fichier HTML de la barre latérale (serveur 'wip') $ tyto wip sidebar # Afficher le contenu du pied de page HTML dans le serveur 'wip'