Makefile: fix a bug with making deb (segfault) and adding proper licensing notice #1

Closed
neox wants to merge 6 commits from neox-patch-1 into master
32 changed files with 2788 additions and 1858 deletions

View File

@ -1,32 +1,13 @@
# Changelog # Changelog
Tyto - Littérateur Tyto - Littérateur
- Repository: https://git.a-lec.org/echolib/tyto-litterateur - Repository: https://git.a-lec.org/echolib/tyto-litterateur
- Issues: https://git.a-lec.org/echolib/tyto-litterateur/-/issues - Issues: https://git.a-lec.org/echolib/tyto-litterateur/-/issues
- Changelog: https://git.a-lec.org/echolib/tyto-litterateur/-/blob/master/CHANGELOG.md - Changelog: https://git.a-lec.org/echolib/tyto-litterateur/-/blob/master/CHANGELOG.md
- License: https://git.a-lec.org/echolib/tyto-litterateur/-/blob/master/LICENSE - License: https://git.a-lec.org/echolib/tyto-litterateur/-/blob/master/LICENSE
- Documentation: https://tyto.echolib.re
## [0.10.6]
## [0.10.2]
- Citer dans un texte > `[_` + `_]`
- Italique `<em>` > `;_` + `_;`
- Italique `<i>` > {_:_` + `_:`
## [0.10.1]
- Fix with try in check for static page
## [0.10.0]
- Add full static page option (--static) only with wip
- Add <div> markers: `<<`, `>>`
- Add new container <div> in footer
- Better status display for article
- fix lang setting
- fix for less warnings in HTML validity
## [0.9.1]
- wip: tabulation when using `<hr />`
- wip: inline quote markers `@_myquote_@`
- wip: inline italic marker `:_maybe_:`
- wip: fix data retreive in complete quote
## [0.9.0]
- Last testings before final

View File

@ -1,12 +1,23 @@
#!/bin/bash #!/bin/bash
#
# Copyright (C) 2023-2024 Adrien Bourmault <neox@a-lec.org>
#
# This file is part of tyto-litterateur.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# file: Makefile default: tyto.deb
# By neox
# License: GNU AFFERO GENERAL PUBLIC LICENSE Version 3, 19 November 2007
default: debian/tyto.deb
### MAKE DEB ### MAKE DEB
@ -14,14 +25,14 @@ default: debian/tyto.deb
.PHONY: clean .PHONY: clean
debian/tyto.deb: debian/debian-binary debian/control.tar.gz debian/data.tar.gz tyto.deb: debian/debian-binary debian/control.tar.gz debian/data.tar.gz
ar -r debian/tyto.deb debian/debian-binary debian/control.tar.gz debian/data.tar.gz cd debian && ar -r ../tyto.deb debian-binary control.tar.gz data.tar.gz
debian/data.tar.gz: debian/data.tar.gz:
cd src && tar czvf ../debian/data.tar.gz usr var cd src && tar czvf ../debian/data.tar.gz usr var
debian/control.tar.gz: debian/control.tar.gz:
tar czvf debian/control.tar.gz debian/control #preinst postinst prerm postrm cd debian && tar czvf control.tar.gz control #preinst postinst prerm postrm
debian/debian-binary: debian/debian-binary:
echo 2.0 > debian/debian-binary echo 2.0 > debian/debian-binary
@ -29,4 +40,4 @@ debian/debian-binary:
clean: clean:
-rm debian/*.tar.gz -rm debian/*.tar.gz
-rm debian/debian-binary -rm debian/debian-binary
-rm debian/*.deb -rm *.deb

257
README.md
View File

@ -1,220 +1,53 @@
# Tyto # Tyto
Pour obtenir de l'aide, taper juste la commande tyto - FR. Pour obtenir de l'aide, taper juste la commande tyto
- EN. To get help, just type tyto.
- - Doc is only in french yet, but Tyto is translated, also for your websites
## Répertoire de code du projet Tyto ## Répertoire de code du projet Tyto
TODO https://git.a-lec.org/echolib/tyto-litterateur
## Comment définir les métas ## Documentation officielle
``` https://tyto.echolib.re (en cours de construction)
# Obligatoires uniques
# Ces marqueurs se configurent sur UNE ligne
title: Titre
about: Infos de l'article
author: Auteur
tags: mot-clé-1,mot 2,
date: YYYY-MM-DD (AAAA-MM-JJ)
# L'image doit être configurée avec le même Nom ## Créer un domaine
# dans les marqueurs multiples
# Utilise l'image précisée comme "avatar" dans les réseaux sociaux
snpic: Nom
# Optionnels multiples
# Ces marqueurs se configurent sur 3 lignes
link: Nom du lien
URL
Texte Alternatif
image: Nom
URI
Texte Alternatif
file: Nom du lien
URL
Texte Alternatif
raw: Nom
URI
Texte Alternatif
abbr: abbrev
Définition de abbrev
ABBR (forme à afficher dans l'artile (optionnel))
# Séparateur d'au moins 5 "-" pour définir la fin
# des métadonnées d'entête de l'article
----------
```
## Comment écrire un article
### Écrire des titres
```
# Les titres HTML vont de 1 à 6.
# Utiliser #N, où N est entre 1 et 6.
# Si du contenu existe entre les titres, une <div> est ajoutée
# Astuce: on commence en général par #2 dans l'article le titre du site
# étant en #1
# Source
#2 Titre 1
Contenu 1
#3 Titre 2
#4 Titre 3
contenu 2
#5 Titre 4
```
### Balise div
```
<< CSS
((
1er paragraphes dans une balise div class="CSS"
))
((
2e paragraphes dans une balise div class="CSS"
))
>>
```
### Paragraphes
```
(( CSS
Un paragraphe
))
```
### Code Brut
```
{{ CSS
def hello_world():
print("Hello")
}}
```
### Listes ul/ol
```
-( CSS
= Liste ul
== Sous-liste ul
=== Sous-sous-liste ul
++++ Sous-sous-sous-liste ol
+++ Sous-sous-liste ol
-)
```
### Ancres
```
# Source de l'ancre cible. "id" est son identité
-> id
# Source de l'ancre d'appel
# Définir l'identité cible et le texte du lien
>_id:Retourner au point d'ancre id_<
```
### Retour à la ligne HTML
```
# Source
|
# HTML
<br />
```
### Lien vers URL
```
# Placer "_" devant le Nom du lien
Voir ce _Nom du lien # Ouverture même fenêtre
Voir ce _Nom du lien+ # ouverture nouvelle fenêtre
```
### Lien vers fichier
```
# Placer "__" devant le Nom du lien
Voir ce __Nom du lien # Ouverture même fenêtre
Voir ce __Nom du lien+ # ouverture nouvelle fenêtre
```
Note:
Vous pouvez avoir un Nom identique pour les marqueurs `file:` et `link:`
### Gras, Strong, italique...
```
*_très gras_* # <strong>
+_gras léger_+ # <b>
;_en italique_; # <em>
:_en italique_: # <i>
~_texte barré_~ # <del>
[_Citation rapide_] # <cite>
%_Classe personnalisée_% >>> <span class="custom">
._Souligné_. # <u>
{_Code_} # <code>
# Montrer comment écrire du code dans Tyto:
# Bypass avec \ devant {_ et _}
{_\{_Comme ça\_}_}
```
### Abréviations
```
# abbrev sera remplacé par "ABBR" dans la page si défini en entête
# sinon, abbrev sera conservé
# - Toujours écrire dans l'article :
# - entre parenthèses ET majuscules les "(ABBREV)"
Avec cette (ABBREV).
# HTML: <abbr title="Définition de abbrev">ABBR</abbr>
```
### Images
```
# Chaque image doit être placée en début de ligne
# Placer dans un paragraphe pour chacune ou après "|",
# sinon, affichage les une à côté des autres
# ! Si pas d'unité pour w= et h= : défaut "px"
_image:Nom
_image:Nom c=CSS
_image:Nom c=css w=1080
_image:Nom w=640em h=480em
_image:Nom t=+ # Rend l'image interne cliquable
_image:Nom t=https://...# Donne un lien web à l'image
_image:Nom c=CSS t=https://... w=320px h=240 # 240px
```
### Code brut depuis un fichier
```
_raw:Nom
```
### Citations
Possibilité dans toute citation d'utiliser les marqueurs
optionnels `_xxx:`. Pour la date, utilisez le FORMAT INTERNATIONAL
```
# Source: citation complète
[[ CSS_TEST
_cite: echolib
_date: 2022-12-28 (format AAAA ou AAAA-MM ou AAAA-MM-JJ)
_lang: fr
_link: https://tyto.echolib.re
_book: Référence
((
Pfff, vraiment !
))
]]
```` ````
mkdir -p MONDOMAIN
cd MONDOMAIN
tyto new domain URL
````
# Créer un article
https://tyto.echolib.re/%C3%A9crire/
``` ```
# Source: citation basique cd articles/
[[ tyto new index
Une citation simple, et sans paragraphe tyto edit index.tyto
]] ```
# Vérifier, prévisualiser un article
```
tyto check index.tyto
tyto wip index.tyto
```
# Les modules
https://tyto.echolib.re/usages/modules.html
La barre latérale, le menu, le pied de page et les balises génériques metas
ne seront pas visible localement sans serveur nginx.
Utiliser l'option --static avec la commande wip pour les voir. Attention,
utiliser la commande publish après avoir utilisé l'option --static sur wip
mettra en ligne la version statique de la page. Il faut donc avant la
commande publish, recommencer la commande wip sur un article sans l'option
--static pour utiliser l'include de nginx (comportement par défaut)
# Publier !
```
# La première fois, ou après mise à jour des modules ou des fichiers (logo, css...)
tyto publish template
# Mettre dans le dossier "www" officiel
tyto publish index.tyto
``` ```

4
debian/control vendored
View File

@ -1,5 +1,5 @@
Package: tyto Package: tyto
Version: 0.10.2 Version: 1.0.0
Section: custom Section: custom
Priority: optional Priority: optional
Architecture: all Architecture: all
@ -7,4 +7,4 @@ Essential: no
Depends: nano,python3 Depends: nano,python3
Installed-Size: `du -ks .|cut -f 1` Installed-Size: `du -ks .|cut -f 1`
Maintainer: echolib <echolib@a-lec.org> Maintainer: echolib <echolib@a-lec.org>
Description: Tyto - Litterateur is a libre project to create and manage multiple websites from articles files. Tyto uses its own syntax to convert your articles in HTML5 pages. Tyto works on a GNU/Linux system and needs minimal dependencies. Description: Tyto - Litterateur is a libre project in FR/EN to create and manage multiple static websites from articles files. Tyto uses its own syntax to convert your articles in HTML5 pages. Tyto works on a GNU/Linux system and needs minimal dependencies.

View File

@ -1,5 +1,5 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# Version: 0.10.2 # Version: 1.0.0
# Tyto - Littérateur # Tyto - Littérateur
# #
# Copyright (C) 2023 Cyrille Louarn <echolib+tyto@a-lec.org> # Copyright (C) 2023 Cyrille Louarn <echolib+tyto@a-lec.org>
@ -24,28 +24,28 @@
# File: /usr/bin/tyto # File: /usr/bin/tyto
#---------------------------------------------------------------------- #----------------------------------------------------------------------
#------------ #-------------------------
# funny stats # Funny Stats Project
#------------ #-------------------------
# scripts files: # Project files : 20
# app lines: # Project lines : 7508
# app comments: # Project comments : 1153
# app functions: # Project functions: 109
# lines: # Project program : 5652
# functions: #
# comments: # file lines : 93
#---------------------------------------------------------------------- # file comments : 33
# file functions: 0
#********************************************************************** # file program : 47
#--------------------------
import sys import sys
sys.path.insert(0, '/var/lib/tyto/program') sys.path.insert(0, '/var/lib/tyto/program')
#====================# #====================#
# MAIN # # MAIN #
# Treat Arguments # # Treat Arguments #
#--------------------#------------------------------------------------- #--------------------#
import logs import logs
if not __name__ == "__main__": if not __name__ == "__main__":
@ -62,25 +62,27 @@ status.domain()
# Command start argument # Command start argument
import check, form, html, new, publish, show, wip, infos import check, form, html, new, publish, show, wip, infos, creators
actions = { actions = {
'check' : check.manage, "check" : check.manage,
'help' : infos.tyto, "help" : infos.tyto,
'edit' : show.manage, "edit" : show.manage,
'edit-about' : show.manage, "edit-about" : show.manage,
'edit-db' : show.manage, "edit-db" : show.manage,
'edit-wip' : show.manage, "edit-wip" : show.manage,
'edit-www' : show.manage, "edit-www" : show.manage,
'new' : new.manage, "force-wip" : wip.manage,
'publish' : publish.manage_publish, "new" : new.manage,
'show' : show.manage, "publish" : publish.manage,
'show-about' : show.manage, "preview" : show.manage,
'show-db' : show.manage, "quick-pub" : publish.manage,
'show-wip' : show.manage, "show" : show.manage,
'show-www' : show.manage, "show-about" : show.manage,
'status' : status.check, "show-db" : show.manage,
'template' : publish.manage_publish, "show-wip" : show.manage,
'wip' : wip.manage, "show-www" : show.manage,
"status" : status.check,
"wip" : wip.manage,
} }

View File

@ -0,0 +1,311 @@
#!/bin/bash
# Tyto - Littérateur
#
# Copyright (C) 2023 Cyrille Louarn <echolib+tyto@a-lec.org>
#
# 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 <https://www.gnu.org/licenses/>.
#----------------------------------------------------------------------
# XMPP: echolib (im@echolib.re)
#
# Description: Autocompletion commands
# File: /usr/share/bash-completion/completions/tyto
#----------------------------------------------------------------------
#-------------------------
# Funny Stats Project
#-------------------------
# file lines : 311
# file comments : 45
# file functions: 0
# file program : 234
#--------------------------
#=================#
# Actions section #
#=================#============================================================
# Actions: argument 1 #
#---------------------#
_tyto_actions() {
cat <<EOL
check
domains
edit
edit-about
edit-db
edit-wip
edit-www
force-wip
help
new
show
show-about
show-db
show-wip
show-www
preview
publish
quick-pub
status
version
wip
EOL
}
_tyto_actions_only() {
grep -F -q -x "$1" <<EOL
domains
help
version
EOL
}
# Actions for articles and modules
#--------------------------------
_tyto_actions_wp() {
grep -F -q -x "$1" <<EOL
publish
wip
EOL
}
# Actions for edit
#-----------------
_tyto_actions_edits() {
grep -F -q -x "$1" <<EOL
edit
edit-about
edit-db
edit-wip
edit-www
EOL
}
# Actions for show
#-----------------
_tyto_actions_shows() {
grep -F -q -x "$1" <<EOL
show
show-about
show-db
show-wip
show-www
EOL
}
#=================#
# Targets section #
#=================#============================================================
# Targets for articles and modules
#--------------------------------
_tyto_targets_wp() {
cat <<EOL
added
again
footer
metas
navbar
sidebar
stats
template
updated
EOL
find . -type f -name "*.tyto" -printf '%P\n' 2>/dev/null
}
# Targets with quick-pub
#-----------------------
_tyto_targets_qp() {
find . -type f -name "*.tyto" -printf '%P\n' 2>/dev/null
}
# Targets with edit
#------------------
_tyto_targets_edits() {
cat <<EOL
domain
footer
metas
navbar
sidebar
EOL
find . -type f -name "*.tyto" -printf '%P\n' 2>/dev/null
}
# Targets with edit
#------------------
_tyto_targets_shows() {
cat <<EOL
domain
footer
metas
navbar
sidebar
stats
EOL
find . -type f -name "*.tyto" -printf '%P\n' 2>/dev/null
}
# Targets: argument 2 (all + .tyto files)
#----------------------------------------
_tyto_targets() {
cat <<EOL
added
again
domain
footer
metas
navbar
sidebar
stats
template
updated
EOL
find . -type f -name "*.tyto" -printf '%P\n' 2>/dev/null
}
# Targets: only with action "new"
#--------------------------------
_tyto_targets_new() {
cat <<EOL
domain
footer
metas
navbar
sidebar
sitemap
EOL
}
# Targets to NOT activate --force
#--------------------------------
_tyto_targets_not_options() {
grep -F -q -x "$1" <<EOL
added
again
domain
footer
metas
navbar
sidebar
stats
template
updated
EOL
}
#=================#
# Options section #
#=================#============================================================
_tyto_options() {
cat <<EOL
--static
EOL
}
# Only with [publish template]
_tyto_options_pt() {
cat <<EOL
--no-mods
EOL
}
#=====================#
# Main autocompletion #
#=====================#========================================================
_tyto_completions() {
local cur
cur="${COMP_WORDS[COMP_CWORD]}"
case $COMP_CWORD in
# Actions
1)
COMPREPLY=( $(compgen -W "$(_tyto_actions)" -- ${cur}) )
return 0
;;
# Targets
2)
local prev="${COMP_WORDS[COMP_CWORD-1]}"
# With action "new"
if [ "$prev" == "new" ];then
COMPREPLY=( $(compgen -W "$(_tyto_targets_new)" -- ${cur}) )
return 0
elif [ "$prev" == "quick-pub" ] ||
[ "$prev" == "preview" ];then
COMPREPLY=( $(compgen -W "$(_tyto_targets_qp)" -- ${cur}) )
return 0
elif [ "$prev" == "force-wip" ];then
COMPREPLY=( $(compgen -W "$(_tyto_targets_qp)" -- ${cur}) )
return 0
# With action "edit"
elif _tyto_actions_edits "$prev";then
COMPREPLY=( $(compgen -W "$(_tyto_targets_edits)" -- ${cur}) )
return 0
# With action "show"
elif _tyto_actions_shows "$prev";then
COMPREPLY=( $(compgen -W "$(_tyto_targets_shows)" -- ${cur}) )
return 0
# With wip/publish only
elif _tyto_actions_wp "$prev";then
COMPREPLY=( $(compgen -W "$(_tyto_targets_wp)" -- ${cur}) )
return 0
# When action is alone
elif ! _tyto_actions_only "$prev";then
COMPREPLY=( $(compgen -W "$(_tyto_targets)" -- ${cur}) )
return 0
fi
;;
# Optionss
3)
local prev1="${COMP_WORDS[COMP_CWORD-1]}"
local prev2="${COMP_WORDS[COMP_CWORD-2]}"
if [ "$prev2" == "wip" ];then
if ! _tyto_targets_not_options "$prev1";then
COMPREPLY=( $(compgen -W "$(_tyto_options)" -- ${cur}) )
return 0
fi
# Only with [publish template]
elif [ "$prev2" == "publish" ] && \
[ "$prev1" == "template" ];then
COMPREPLY=( $(compgen -W "$(_tyto_options_pt)" -- ${cur}) )
return 0
fi
;;
esac
}
complete -F _tyto_completions 'tyto'

View File

@ -1,16 +1,14 @@
# Changelog # Changelog
Tyto - Littérateur Tyto - Littérateur
- Repository: https://git.a-lec.org/echolib/tyto - Repository: https://git.a-lec.org/echolib/tyto-litterateur
- Issues: https://git.a-lec.org/echolib/tyto/-/issues - Issues: https://git.a-lec.org/echolib/tyto-litterateur/-/issues
- Changelog: https://git.a-lec.org/echolib/tyto/-/blob/main/CHANGELOG.md - Changelog: https://git.a-lec.org/echolib/tyto-litterateur/-/blob/master/CHANGELOG.md
- License: https://git.a-lec.org/echolib/tyto/-/blob/main/LICENSE - License: https://git.a-lec.org/echolib/tyto-litterateur/-/blob/master/LICENSE
- Documentation: https://tyto.echolib.re
## [1.0.0]
- (2023.05.09)
- - Official first public release
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)

View File

@ -1,167 +1,53 @@
# Tyto # Tyto
- FR. Pour obtenir de l'aide, taper juste la commande tyto
- EN. To get help, just type tyto.
- - Doc is only in french yet, but Tyto is translated, also for your websites
## Répertoire de code du projet Tyto ## Répertoire de code du projet Tyto
https://git.a-lec.org/echolib/tyto-litterateur
## Comment définir les métas ## Documentation officielle
https://tyto.echolib.re (en cours de construction)
## Créer un domaine
````
mkdir -p MONDOMAIN
cd MONDOMAIN
tyto new domain URL
````
# Créer un article
https://tyto.echolib.re/%C3%A9crire/
``` ```
# Obligatoires uniques cd articles/
title: Titre tyto new index
about: Infos de l'article tyto edit index.tyto
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 # Vérifier, prévisualiser un article
### Titre h1 à h6
``` ```
#1 Titre 1 tyto check index.tyto
(( tyto wip index.tyto
Un paragraphe
))
#2 Titre 2
``` ```
### Paragraphes # Les modules
``` https://tyto.echolib.re/usages/modules.html
(( CSS
Un paragraphe
))
```
### Code Brut La barre latérale, le menu, le pied de page et les balises génériques metas
``` ne seront pas visible localement sans serveur nginx.
{{ CSS
def hello_world():
print("Hello")
}}
```
### Listes ul/ol Utiliser l'option --static avec la commande wip pour les voir. Attention,
``` utiliser la commande publish après avoir utilisé l'option --static sur wip
-( CSS mettra en ligne la version statique de la page. Il faut donc avant la
= Liste ul commande publish, recommencer la commande wip sur un article sans l'option
== Sous-liste ul --static pour utiliser l'include de nginx (comportement par défaut)
=== 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 # Publier !
Citation simple sans référence
]]
``` ```
# La première fois, ou après mise à jour des modules ou des fichiers (logo, css...)
tyto publish template
### Ancres # Mettre dans le dossier "www" officiel
``` tyto publish index.tyto
-> id
((
un long paragraphe
))
((
>_id:Retourner au point d'ancre_<
))
```
### Retour à la ligne HTML
```
| # <br />
```
### Lien vers URL
```
Voir ce _Nom du lien # Ouverture même fenêtre
Voir ce _Nom du lien+ # ouverture nouvelle fenêtre
```
### Lien vers fichier
```
Voir ce __Nom du lien # Ouverture même fenêtre
Voir ce __Nom du lien+ # ouverture nouvelle fenêtre
```
Note:
Vous pouvez avoir un NAME identique pour file: et link:
### Gras, Strong, italique...
```
*_très gras_* # <strong>
+_gras léger_+ # <b>
/_en italique_/ # <em>
[_en italique_] # <i>
~_texte barré_~ # <del>
{_Code_} # <code>
:_Citation rapide_: # <cite>
%_Classe personnalisée_% >>> <span class="custom">
._Souligné_. # <u>
```
### 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
# <abbr title="Définition du NOM">nom</abbr>
Avec ce NOM.
```
### Images
```
# Chaque image doit être placée en début de ligne
# Placer dans un paragraphe pour chaque ou après "|",
# sinon, affichage les une à côté des autres
# ! Si pas d'unité pour w= et h= : défaut "px"
_image:Nom
_image:Nom c=CSS
_image:Nom c=css w=1080
_image:Nom w=640em h=480em
_image:Nom t=+ # Rend l'image interne cliquable
_image:Nom t=https://...# Donne un lien à l'image
_image:Nom c=CSS t=https://... w=320px h=240
```
### Code Brut depuis un fichier
```
_brut:NOM
``` ```

View File

@ -3,12 +3,23 @@
* DOMAIN MUST be changed by domain css set in configuration * DOMAIN MUST be changed by domain css set in configuration
*/ */
/*
/* include header to footer */
div#site_container {
}
/* Include article + sidebar */
div#article_sidebar_container {
}
/*=====================================================================
* Header * Header
*/ */
header#header_page { header#header_page {
} }
/* Block */
div#site_logo { div#site_logo {
} }
@ -18,6 +29,7 @@ a#site_logo_link {
img#site_logo_image { img#site_logo_image {
} }
/* Block */
div#site_infos { div#site_infos {
} }
@ -31,7 +43,7 @@ p#site_about {
} }
/* /*=====================================================================
* navbar * navbar
*/ */
nav#site_menu { nav#site_menu {
@ -46,16 +58,18 @@ li.site_menu_item {
a.site_menu_link { a.site_menu_link {
} }
/*
/*=====================================================================
* article * article
*/ */
article#article_main { article#article_main {
} }
h1#main_title { /* article title */
} h2#main_title {
h2.title_2 {
} }
/* Writer titles*/
h3.title_3 { h3.title_3 {
} }
h4.title_4 { h4.title_4 {
@ -65,9 +79,17 @@ h5.title_5 {
h6.title_6 { h6.title_6 {
} }
/* Between every <h2-6> IF CONTENTS */ /* Between every <h3-6> IF CONTENTS */
div.contents { div.contents {
} }
div.contents_2 {
}
div.contents_3 {
}
div.contents_4 {
}
div.contents_5 {
}
/* Default if not set in post */ /* Default if not set in post */
p.DOMAIN { p.DOMAIN {
@ -78,6 +100,12 @@ br.DOMAIN {
a.link { a.link {
} }
a.link-file {
}
/* When block quote with _cite:*/
a.figc {
}
a.anchor_link { a.anchor_link {
} }
@ -88,31 +116,32 @@ abbr.DOMAIN {
img.DOMAIN_image { img.DOMAIN_image {
} }
code.icode {
}
ul.DOMAIN { ul.DOMAIN {
} }
li.DOMAIN li.DOMAIN {
}
strong.strong { /* Words tags*/
code.icode {
} }
b.bold { strong.DOMAIN {
} }
em.em{ b.DOMAIN {
} }
i.italic { em.DOMAIN{
} }
del.del { i.DOMAIN {
} }
u.underline { del.DOMAIN {
} }
cite.cite { u.DOMAIN {
}
cite.DOMAIN {
} }
span.custom { span.custom {
} }
/* Block_code */ /* Block-code */
code.DOMAIN { code.DOMAIN {
} }
pre.bcode { pre.bcode {
@ -132,13 +161,19 @@ span#article_code {
a#article_code_link { a#article_code_link {
} }
/*
/* Sitemap */
ul.sitemap {
}
/*=====================================================================
* sidebar * sidebar
*/ */
aside#sidebar { aside#sidebar {
} }
h1#sidebar_title { h2#sidebar_title {
} }
ul#sidebar_list { ul#sidebar_list {
} }
@ -146,13 +181,13 @@ li.sidebar_item {
} }
a.sidebar_item_link { a.sidebar_item_link {
} }
h2.sidebar_item_title { h3.sidebar_item_title {
} }
p.sidebar_item_about { p.sidebar_item_about {
} }
/* /*=====================================================================
* footer * footer
*/ */
footer#footer_page { footer#footer_page {
@ -165,7 +200,7 @@ div#footer_container {
/* Block*/ /* Block*/
div#footer_infos { div#footer_infos {
} }
h1#footer_site_title { h2#footer_site_title {
} }
p#footer_about { p#footer_about {
} }
@ -187,5 +222,3 @@ p.footer_copyright {
} }
p.footer_generator { p.footer_generator {
} }

View File

@ -3,9 +3,9 @@ directory = ""
database = "" database = ""
# Local user configuration # Local user configuration
lang_sys = "SYS" lang_sys = ""
local_user = "" local_user = ""
lang_logs = "SYS" lang_logs = ""
articles_db_d = "" articles_db_d = ""
# Working directories # Working directories
@ -19,7 +19,6 @@ navbar_f = ""
sidebar_f = "" sidebar_f = ""
metas_f = "" metas_f = ""
footer_f = "" footer_f = ""
footer_about_f = ""
# Domain # Domain
shortname = "" shortname = ""
@ -27,8 +26,8 @@ www_url = ""
wip_url = "" wip_url = ""
# Servers directories # Servers directories
srv_root = "" srv_root = "/var/www/"
srv_domain = "" srv_domain = "
srv_wip = "" srv_wip = ""
srv_wip_tpl_d = "" srv_wip_tpl_d = ""
srv_wip_images_d = "" srv_wip_images_d = ""
@ -38,36 +37,46 @@ srv_www_tpl_d = ""
srv_www_images_d = "" srv_www_images_d = ""
srv_www_files_d = "" srv_www_files_d = ""
# Servers files # Servers files (wip)
wip_favicon_f = ""
wip_logo_f = ""
wip_css_f = ""
wip_navbar_f = "" wip_navbar_f = ""
wip_sidebar_f = "" wip_sidebar_f = ""
wip_metas_f = "" wip_metas_f = ""
wip_footer_f = "" wip_footer_f = ""
wip_stats_f = ""
# Servers files (www)
www_favicon_f = ""
www_logo_f = ""
www_css_f = ""
www_navbar_f = "" www_navbar_f = ""
www_sidebar_f = "" www_sidebar_f = ""
www_metas_f = "" www_metas_f = ""
www_footer_f = "" www_footer_f = ""
wip_logo_f = "" www_stats_f = ""
www_logo_f = ""
www_rss_f = "" www_rss_f = ""
# Domain user's settings # Domain user's settings
favicon = "favicon.png"
logo = "logo.png" logo = "logo.png"
styles = "styles.css"
rss = "rss.xml" rss = "rss.xml"
rss_items = 100 rss_items = 100
title = "" title = ""
date = "" date = ""
about = "" about = ""
lang_site = "SYS" lang_site = ""
mail = "" mail = ""
tags = "" tags = ""
license = "" license = "gfdl-1.3"
license_url = "" license_url = ""
legal_url = "" legal_url = ""
terms_url = "" terms_url = ""
css = "tyto" css = "tyto"
sep = "-" sep = "-"
article_code = False article_code = True
relme = "" relme = ""
sidebar_title = "" sidebar_title = ""
sidebar_items = 6 sidebar_items = 6

View File

@ -23,120 +23,148 @@
# File: /var/lib/tyto/program/args.py # File: /var/lib/tyto/program/args.py
#---------------------------------------------------------------------- #----------------------------------------------------------------------
#------------ #-------------------------
# funny stats # Funny Stats Project
#------------ #-------------------------
# lines: # file lines : 174
# functions: # file comments : 29
# comments: # file functions: 2
#---------------------------------------------------------------------- # file program : 135
#--------------------------
#**********************************************************************
import os, sys import os, sys
import infos import infos
try:
action
target
# Arguments from command line except:
# 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'
)
option = \ # Arguments from command line
( # tyto [action] [target]
'--static', #----------------------------
) actions = \
(
pass_actions = ('new') 'check',
'edit',
# Actions that needs to check for article's database 'edit-db',
pass_db = \ 'edit-wip',
( 'edit-www',
'check', 'force-wip',
'edit', 'new',
'edit-db', 'preview',
'edit-wip', 'publish',
'edit-www', 'quick-pub',
'publish', 'show',
'show', 'show-db',
'show-about', 'show-wip',
'show-db', 'show-www',
'show-wip', 'status',
'show-www', 'wip',
'status', )
'wip',
) quicks = \
(
pass_targets = \ 'force-wip',
( 'quick-pub',
'added', )
'again',
'updated', options = \
'domain', (
'footer', '--static',
'metas', )
'navbar',
'sidebar', pass_actions = ('new')
'stats',
'template' # Actions that needs to check for article's database
) pass_db = \
(
pass_status = \ 'check',
( 'edit',
'domain', 'edit-db',
) 'edit-wip',
'edit-www',
multi_chk = ('added', 'again', 'updated') 'force-wip',
'publish',
''' 'preview',
action = '' 'quick-pub',
target = '' 'show',
option = '' 'show-about',
''' 'show-db',
'show-wip',
'show-www',
# action 'status',
#------- 'wip',
try: action = sys.argv[1] )
except: action = ''
pass_targets = \
# With no argument, show help (
if not action: 'added',
infos.tyto(target) 'again',
sys.exit(0) 'updated',
'domain',
# Unused argument [action] 'footer',
if action in actions: act_err = False 'metas',
else: act_err = True 'navbar',
'sidebar',
'sitemap',
# target 'stats',
#------- 'template'
try: target = sys.argv[2] )
except: target = ''
pass_status = \
(
# option 'domain',
try: option = sys.argv[3] )
except: option = ''
multi_chk = \
(
'added',
'again',
'updated'
)
helps = \
(
'domains',
'version',
'help'
)
# action
#-------
try: action = sys.argv[1]
except: action = ''
act_err = False
# With no argument, show help
if not action:
infos.tyto('full')
sys.exit(0)
elif action in helps:
infos.tyto(action)
# Unused argument [action]
elif not action in actions:
act_err = True
# target
#-------
try:
target = sys.argv[2]
except:
infos.tyto('full')
sys.exit(0)
# options
try: option = sys.argv[3]
except: option = ''
# Set action and target for binary # Set action and target for binary
def set_action(): def set_action():

View File

@ -24,21 +24,19 @@
# File: /var/lib/tyto/program/check.py # File: /var/lib/tyto/program/check.py
#---------------------------------------------------------------------- #----------------------------------------------------------------------
#------------ #-------------------------
# funny stats # Funny Stats Project
#------------ #-------------------------
# lines: # file lines : 1146
# functions: # file comments : 163
# comments: # file functions: 25
#---------------------------------------------------------------------- # file program : 873
#--------------------------
#**********************************************************************
# Import needed libs
import time, importlib, sys, os, re, datetime import time, importlib, sys, os, re, datetime
from datetime import datetime from datetime import datetime
from time import gmtime, strftime from time import gmtime, strftime
import args, dom, logs, status, db, form, tyto, langs, wip import args, dom, logs, status, db, form, tyto, langs, wip, html
domain_dir = post_err = multi_chk = False domain_dir = post_err = multi_chk = False
@ -68,12 +66,13 @@ def manage(target):
logs.out("1", db.uri_file, True) logs.out("1", db.uri_file, True)
# Already check # Already check
elif db.exists and not db.old_chk: elif db.exists:
print(' ├ [%s] > %s'%(db.title, db.uri_file)) db.show_title()
logs.out("20", '%s > %s'%(db.date_chk, db.uri_file), False) if not db.old_chk and not args.option == "--force":
answer = form.asking('%s%s '%( logs.out("20", '%s > %s'%(db.date_chk, db.uri_file), False)
langs.site.check_a, langs.site.q answer = form.asking('%s%s '%(
), True) langs.site.check_a, langs.site.q
), True)
check_process(target) check_process(target)
else: else:
@ -88,7 +87,7 @@ def manage(target):
# Argument is a module name # # Argument is a module name #
# Check if modules files exists # # Check if modules files exists #
#-------------------------------# #-------------------------------#
def check_module(target): def check_module(target):
if target == "domain": if target == "domain":
status.check(target) status.check(target)
return return
@ -100,8 +99,10 @@ def check_module(target):
if not os.path.exists(t): if not os.path.exists(t):
logs.out("24", t, False) logs.out("24", t, False)
unused_f = True unused_f = True
if not unused_f: if not unused_f:
logs.out("28", "%s"%langs.log.all_ok, False) logs.out("28", "%s"%langs.log.all_ok, False)
except: except:
logs.out("28", "%s + %s"%(args.action, target), True) logs.out("28", "%s + %s"%(args.action, target), True)
@ -121,6 +122,7 @@ def check_all(option):
# Then Do a check, and return # Then Do a check, and return
#----------------------------------------- #-----------------------------------------
if option == "added": if option == "added":
no_post = True
for root, dirs, files in os.walk(dom.articles_d[:-1]): for root, dirs, files in os.walk(dom.articles_d[:-1]):
for file in files: for file in files:
if (file.endswith('.tyto')): if (file.endswith('.tyto')):
@ -131,9 +133,13 @@ def check_all(option):
if os.path.exists(db_config): if os.path.exists(db_config):
continue continue
no_post = False
importlib.reload(db) importlib.reload(db)
check_process(args.target) check_process(args.target)
print() print()
if no_post:
logs.out("28", '%s'%langs.log.nonewpost, True)
return return
# With [updated], Article must have changed # With [updated], Article must have changed
@ -166,15 +172,25 @@ def check_all(option):
# Check articles process # # Check articles process #
#------------------------# #------------------------#
def check_process(target): def check_process(target):
global post_err
if not db.post: if not db.post:
logs.out("1", db.post, True) logs.out("1", db.post, False)
post_err = True
return
# Start checking processes
#-------------------------
# Convert file to string
# Also check for separator and empty article
file_to_string()
if post_err:
return
global post_bottom, article_bottom global post_bottom, article_bottom
global date_wip, hash_wip, date_www, hash_www, post_bottom global date_wip, hash_wip, date_www, hash_www, post_bottom
global post_err
date_wip = hash_wip = date_www = hash_www = '' date_wip = hash_wip = date_www = hash_www = ''
post_err = False
# Set values for wip and www from DB # Set values for wip and www from DB
if db.exists: if db.exists:
@ -213,12 +229,6 @@ def check_process(target):
http_www = "%s/%s"%(dom.www_url, srv_post_short_uri) http_www = "%s/%s"%(dom.www_url, srv_post_short_uri)
http_wip = '%s/%s'%(dom.wip_url, srv_post_short_uri) http_wip = '%s/%s'%(dom.wip_url, srv_post_short_uri)
# Start checking processes
#-------------------------
# Convert file to string
# Also check for separator and empty article
file_to_string()
# Check for icodes, bcodes, quotes # Check for icodes, bcodes, quotes
# check icodes marks on same line # check icodes marks on same line
if_icodes_bcodes_quotes(post_bottom) if_icodes_bcodes_quotes(post_bottom)
@ -229,10 +239,12 @@ def check_process(target):
post_bottom = tyto.protect_article post_bottom = tyto.protect_article
# Protect inline-codes # Protect inline-codes
if icode: if icode: post_bottom = tyto.protect_icodes(post_bottom)
tyto.protect_icodes(post_bottom)
post_bottom = tyto.protect_article # Replace escaped markers
post_bottom = tyto.protect_escaped(post_bottom, False)
# Check header tags configurations # Check header tags configurations
check_needed_tags(post_header.rsplit('\n')) check_needed_tags(post_header.rsplit('\n'))
if post_err: if post_err:
@ -241,15 +253,22 @@ def check_process(target):
return return
print('\n ├ [%s] > %s'%(title, db.uri_file)) print('\n ├ [%s] > %s'%(title, db.uri_file))
# Check optional tags configuration
check_opt_tags(post_header.rsplit('\n')) check_opt_tags(post_header.rsplit('\n'))
if post_err: if post_err:
if db.exists and tyto.exists(db.config): if db.exists and tyto.exists(db.config):
os.remove(db.config) os.remove(db.config)
return return
check_titles() # #1-5 (titles)
# Check for valid contents check_words_tags() # Strongs, italics...
check_content(post_bottom) check_blocks_tags() # Paragraphs, quotes...
check_anchors() # Anchors
check_contents_list() # Lists ul/ol contents
check_legacy_HTML() # Real HTML tags
check_tags_set() # Check _TAG:Name (_image:Name)
check_contents_writer() # Convinience
# Remove db (if exists) on post error and return # Remove db (if exists) on post error and return
if post_err: if post_err:
@ -269,14 +288,22 @@ def check_process(target):
# Check if separator or exit # # Check if separator or exit #
#---------------------------------# #---------------------------------#
def file_to_string(): def file_to_string():
global post_err
global article, post_header, post_bottom global article, post_header, post_bottom
global ln_header, ln_bottom, ln_article global ln_header, ln_bottom, ln_article
post_err = False
post_header = post_bottom = '' post_header = post_bottom = ''
sep = content = False sep = content = False
article = open(db.uri_file, 'r').read() article = open(db.uri_file, 'r').read()
for line in article.rsplit('\n'): for line in article.rsplit('\n'):
if line.startswith(logs.shebang):
print('')
logs.out("82", db.uri_file, False)
post_err = True
return
if line.startswith('-----'): if line.startswith('-----'):
if not sep: if not sep:
sep = True sep = True
@ -292,12 +319,17 @@ def file_to_string():
# Check if separator or exit # Check if separator or exit
if not sep: if not sep:
logs.out("6", '"-----" > %s'%db.uri_file, True) print('')
logs.out("6", '"-----" > %s'%db.uri_file, False)
post_err = True
return
if not content: if not content:
if db.exists and tyto.exists(db.config): if db.exists and tyto.exists(db.config):
os.remove(db.config) os.remove(db.config)
logs.out("18", db.uri_file, True) logs.out("18", db.uri_file, False)
post_err = True
return
# +2 > (start at 0 + separator line) # +2 > (start at 0 + separator line)
ln_article = len(article.splitlines()) + 1 ln_article = len(article.splitlines()) + 1
@ -313,11 +345,11 @@ def file_to_string():
def count_words(post_bottom): def count_words(post_bottom):
global post_words global post_words
post_words = 0 post_words = 0
for line in post_bottom: for line in post_bottom:
if not line \ if not line \
or line.startswith(tyto.nolinewords) \ or line.startswith(tyto.nolinewords) \
or line.startswith("#") and \ or line.startswith("#") and not line.startswith(tyto.titles_user):
not line.startswith(tyto.titles_tags):
continue continue
post_words = post_words + len(line.strip().split(" ")) post_words = post_words + len(line.strip().split(" "))
@ -330,11 +362,11 @@ def count_words(post_bottom):
#---------------------------------------------# #---------------------------------------------#
def if_icodes_bcodes_quotes(post_bottom): def if_icodes_bcodes_quotes(post_bottom):
global icode, quote, bcode, post_err global icode, quote, bcode, post_err
global post_titles, nbr_quotes, nbr_bcodes, nbr_ancs, post_comments global nbr_quotes, nbr_bcodes, nbr_ancs, post_comments
global post_images, post_raws, fcodes global post_images, post_raws, fcodes
icode = quote = in_quote = bcode = in_bcode = in_bq = False icode = quote = in_quote = bcode = in_bcode = in_bq = False
post_titles = nbr_quotes = nbr_bcodes = nbr_ancs = 0 nbr_quotes = nbr_bcodes = nbr_ancs = 0
post_images = post_comments = post_raws = fcodes = 0 post_images = post_comments = post_raws = fcodes = 0
for ln, line in enumerate(post_bottom.rsplit('\n'), 1): for ln, line in enumerate(post_bottom.rsplit('\n'), 1):
@ -363,10 +395,7 @@ def if_icodes_bcodes_quotes(post_bottom):
if in_bq: if in_bq:
continue continue
elif line.startswith(tyto.titles_tags): elif line.startswith('#') and not line.startswith(tyto.titles_user):
post_titles += 1
continue
elif line.startswith('#'):
post_comments += 1 post_comments += 1
continue continue
elif line.startswith(tyto.single_tags[1][0]): elif line.startswith(tyto.single_tags[1][0]):
@ -380,14 +409,14 @@ def if_icodes_bcodes_quotes(post_bottom):
fcodes += 1 fcodes += 1
# icodes # icodes
elif tyto.words_tags[9][0] or tyto.words_tags[9][1] in line: elif tyto.icode_tags[0] in line or tyto.icode_tags[1] in line:
icode_m1 = icode_m2 = 0 icode_m1 = icode_m2 = 0
icode_m1 = line.count(tyto.words_tags[9][0]) icode_m1 = line.count(tyto.icode_tags[0])
icode_m2 = line.count(tyto.words_tags[9][1]) icode_m2 = line.count(tyto.icode_tags[1])
if icode_m1 != icode_m2: if icode_m1 != icode_m2:
logs.out("8", 'L=%s. icode "%s" + "%s" > %s'%( logs.out("8", 'L=%s. icode "%s" + "%s" > %s'%(
ln + 1 + ln_header, ln + 1 + ln_header,
tyto.words_tags[9][0], tyto.words_tags[9][1], tyto.icode_tags[0], tyto.icode_tags[1],
db.uri_file db.uri_file
), False ), False
) )
@ -402,23 +431,30 @@ def if_icodes_bcodes_quotes(post_bottom):
#-----------------------------------------# #-----------------------------------------#
def check_needed_tags(post_header): def check_needed_tags(post_header):
global post_err global post_err
global title, author, about, tags, date global title, author, about, tags, date, sitemap
global stat_tags global stat_tags
title = author = about = tags = '' title = author = about = tags = ''
sitemap = "True"
date = () date = ()
stat_tags = 0 stat_tags = 0
# Check post header for each needed tags # Check post header for each needed tags
for tag in tyto.needed_header_tags: for tag in tyto.needed_header_tags:
for ln, line in enumerate(post_header, 1): for ln, line in enumerate(post_header, 1):
# Sitemap : set to False if #NoSitemap
if line.startswith("# NoSitemap"):
sitemap = "False"
# Break if already set # Break if already set
if globals()[tag]: break if globals()[tag]:
break
# Set data from tag # Set data from tag
if line.startswith('%s:'%tag): if line.startswith('%s:'%tag):
globals()[tag] = line.rsplit('%s:'%tag)[1].lstrip() globals()[tag] = line.rsplit('%s:'%tag)[1].lstrip()
globals()[tag] = tyto.convert_altname(globals()[tag]) globals()[tag] = tyto.convert_altname(globals()[tag])
# Stat for "tags:" # Stat for "tags:"
if tag == 'tags': if tag == 'tags':
stat_tags = len(globals()[tag].strip().split(",")) stat_tags = len(globals()[tag].strip().split(","))
@ -428,8 +464,6 @@ def check_needed_tags(post_header):
if not globals()[tag]: if not globals()[tag]:
logs.out("38", '%s:'%tag, False) logs.out("38", '%s:'%tag, False)
post_err = True post_err = True
# Check date format # Check date format
# Set french format in post DB # Set french format in post DB
@ -724,6 +758,22 @@ def check_snpic(name):
def check_anchors(): def check_anchors():
global post_err global post_err
c_opened = c_closed = 0
c_opened = post_bottom.count(tyto.anchor_tags[0])
c_closed = post_bottom.count(tyto.anchor_tags[1])
if c_opened != c_closed:
logs.out("8", '%s "%s" + "%s" > %s'%(
tyto.anchor_tags[4],
tyto.anchor_tags[0], tyto.anchor_tags[1],
db.uri_file
), False)
post_err = True
return
globals()['post_%s'%tyto.anchor_tags[4]] = int(c_opened)
# Anchor target # Anchor target
if nbr_ancs > 0: if nbr_ancs > 0:
# Create anchors names targets # Create anchors names targets
@ -754,31 +804,51 @@ def check_anchors():
post_err = True post_err = True
return return
# Check in anchor link has target one # Check if anchor link has target one
else: else:
for ln, line in enumerate(post_bottom.rsplit('\n'), 1): for ln, line in enumerate(post_bottom.rsplit('\n'), 1):
ln = ln + ln_header + 1
# Anchor link # Anchor link
if tyto.words_tags[0][0] and tyto.words_tags[0][1] in line: if tyto.anchor_tags[0] and tyto.anchor_tags[1] in line:
anchors = re.findall(r">_(.*?)_<", line) anchors = re.findall(r">_(.*?)_<", line)
for anchor in anchors: for anchor in anchors:
anchor_name = anchor.rsplit(':')[0].lstrip() anchor_name = anchor.rsplit(':')[0].lstrip()
if not anchor_name in anchors_names: if not anchor_name in anchors_names:
logs.out("12", 'L=%s. anchor "%s" > %s'%( logs.out("12", 'L=%s. anchor "%s" > %s'%(
ln + 1 + ln_header, anchor_name, db.uri_file ln, anchor_name, db.uri_file
), False) ), False)
post_err = True post_err = True
#===========================# #==========================#
# Check tags in post_bottom # # Check titles and content #
#---------------------------# #--------------------------#
def check_content(post_bottom): def check_titles():
global post_err global post_err, post_titles
post_titles = 0
for ln, line in enumerate(post_bottom.rsplit('\n'), 1):
ln = ln + ln_header + 1
# Check tags for words (strongs, italics...) if line.startswith(tyto.titles_user):
# Set stats for each one title_name = line[2: len(line)].lstrip()
#------------------------------------------- if not title_name:
for tag in tyto.words_tags: post_err = True
logs.out("84", 'L=%s > %s'%(ln, db.uri_file), False)
continue
post_titles += 1
#============================================#
# Check tags for words (strongs, italics...) #
# Set stats for each one #
#--------------------------------------------#
def check_words_tags():
global post_err, post_bottom
for tag in tyto.markers_tags:
c_opened = c_closed = 0 c_opened = c_closed = 0
c_opened = post_bottom.count(tag[0]) c_opened = post_bottom.count(tag[0])
@ -794,12 +864,16 @@ def check_content(post_bottom):
post_err = True post_err = True
else: else:
globals()['post_%s'%tag[4]] = int(c_opened) globals()['post_%s'%tag[4]] = int(c_opened)
# Check block tags paragraphs, qyotes...) #=========================================#
# Set stats for each one # Check block tags paragraphs, quotes...) #
#------------------------------------------- # Set stats for each one #
#-----------------------------------------#-
def check_blocks_tags():
global post_err
for tag in tyto.block_tags: for tag in tyto.block_tags:
c_opened = c_closed = 0 c_opened = c_closed = 0
@ -817,18 +891,18 @@ def check_content(post_bottom):
globals()['post_%s'%tag[4]] = int(c_opened) globals()['post_%s'%tag[4]] = int(c_opened)
# Check if anchor has target #====================================#
# Count anchors target # Lists: check if contents are valid #
#--------------------------- #------------------------------------#
check_anchors() def check_contents_list():
global post_err
# Lists: check if contents are valid
#-----------------------------------
if post_lists > 0: if post_lists > 0:
inlist = False inlist = False
for ln, line in enumerate(post_bottom.rsplit('\n'), 1): for ln, line in enumerate(post_bottom.rsplit('\n'), 1):
if line.startswith(tyto.block_tags[3][0]): ln = ln + ln_header + 1
if line.startswith(tyto.block_tags[3][0]):
inlist = True inlist = True
continue continue
elif line.startswith(tyto.block_tags[3][1]): elif line.startswith(tyto.block_tags[3][1]):
@ -839,16 +913,39 @@ def check_content(post_bottom):
if inlist and not line or not line[0] in tyto.markers_lists: if inlist and not line or not line[0] in tyto.markers_lists:
logs.out("3", 'L=%s. %s %s > %s'%( logs.out("3", 'L=%s. %s %s > %s'%(
ln + ln_header, ln,
tyto.block_tags[3][4], tyto.block_tags[3][4],
tyto.markers_lists, tyto.markers_lists,
db.uri_file db.uri_file
), False) ), False)
post_err = True post_err = True
#==================================#
# Legacy HTML Tags, check if aired #
#----------------------------------#
def check_legacy_HTML():
global post_err
# Check for all match _TAGS:NAME from content in header for tag in tyto.leg_html_tags:
#------------------------------------------------------ leg1 = post_bottom.count(tag[0])
leg2 = post_bottom.count(tag[1])
if leg1 != leg2:
logs.out("8", '"%s" + "%s" > %s'%(
tag[0], tag[1], db.uri_file
), False)
post_err = True
#================================#
# Check for all match _TAGS:NAME #
# (from content in header) #
# _image:, _raw:... #
#--------------------------------#
def check_tags_set():
global post_err
set_tags = () set_tags = ()
for ln, line in enumerate(post_bottom): for ln, line in enumerate(post_bottom):
for htag in tyto.head_tags: for htag in tyto.head_tags:
@ -866,23 +963,13 @@ def check_content(post_bottom):
if match: continue if match: continue
else: else:
logs.out("12", "%s %s"%(htag, ptag_set), False) logs.out("12", "%s %s"%(htag, ptag_set), False)
post_err = True post_err = True
# Legacy HTML not paired error
for tag in tyto.leg_html_tags:
leg1 = post_bottom.count(tag[0])
leg2 = post_bottom.count(tag[1])
if leg1 != leg2:
logs.out("8", '"%s" + "%s" > %s'%(
tag[0], tag[1], db.uri_file
), False)
post_err = True
# Template Tags (warning for not paired symbols) #================================================#
#----------------------------------------------- # Template Tags (warning for not paired symbols) #
#------------------------------------------------#
def check_contents_writer():
for tag in tyto.tpl_tags: for tag in tyto.tpl_tags:
tpl1 = post_bottom.count(tag[0]) tpl1 = post_bottom.count(tag[0])
tpl2 = post_bottom.count(tag[1]) tpl2 = post_bottom.count(tag[1])
@ -910,7 +997,7 @@ def check_static_posts():
try: try:
post_datas = open(srv_post, "r").read() post_datas = open(srv_post, "r").read()
if not re.findall( if not re.findall(
tyto.tags_html_mods[dom.wip_metas_f], html.tags_html_mods[dom.wip_metas_f],
post_datas post_datas
): ):
globals()[static] = "True" globals()[static] = "True"
@ -936,6 +1023,7 @@ def create_database():
'meta_tags = "%s"\n'%tags + \ 'meta_tags = "%s"\n'%tags + \
'date = "%s"\n'%date_tr + \ 'date = "%s"\n'%date_tr + \
'snpic = "%s"\n'%snpic_url + \ 'snpic = "%s"\n'%snpic_url + \
'sitemap = %s\n'%sitemap + \
'\n# Post Configurations\n' + \ '\n# Post Configurations\n' + \
'post_id = "%s"\n'%db.uri_id + \ 'post_id = "%s"\n'%db.uri_id + \
'post_src = "%s"\n'%db.uri_file + \ 'post_src = "%s"\n'%db.uri_file + \
@ -943,20 +1031,20 @@ def create_database():
'short_src = "%s"\n'%src_post_short_uri + \ 'short_src = "%s"\n'%src_post_short_uri + \
'short_srv = "%s"\n'%srv_post_short_uri + \ 'short_srv = "%s"\n'%srv_post_short_uri + \
'sub_uri = "%s"\n'%sub_uri + \ 'sub_uri = "%s"\n'%sub_uri + \
'date_chk = "%s"\n'%tyto.nowdate() + \ 'date_chk = "%s"\n'%tyto.nowdate() + \
'hash_chk = "%s"\n'%db.hash_post + \ 'hash_chk = "%s"\n'%db.hash_post + \
'\n# wip configuration\n' + \ '\n# wip configuration\n' + \
'post_wip = "%s"\n'%srv_post_wip_uri + \ 'post_wip = "%s"\n'%srv_post_wip_uri + \
'http_wip = "%s"\n'%http_wip + \ 'http_wip = "%s"\n'%http_wip + \
'static_wip = %s\n'%wip_static + \ 'static_wip = %s\n'%wip_static + \
'date_wip = "%s"\n'%date_wip + \ 'date_wip = "%s"\n'%date_wip + \
'hash_wip = "%s"\n'%hash_wip + \ 'hash_wip = "%s"\n'%hash_wip + \
'\n# www configuration\n' + \ '\n# www configuration\n' + \
'post_www = "%s"\n'%srv_post_www_uri + \ 'post_www = "%s"\n'%srv_post_www_uri + \
'http_www = "%s"\n'%http_www + \ 'http_www = "%s"\n'%http_www + \
'static_www = %s\n'%www_static + \ 'static_www = %s\n'%www_static + \
'date_www = "%s"\n'%date_www + \ 'date_www = "%s"\n'%date_www + \
'hash_www = "%s"\n'%hash_www + \ 'hash_www = "%s"\n'%hash_www + \
'\n# Used files\n' + \ '\n# Used files\n' + \
'uris = %s'%str(files_post) 'uris = %s'%str(files_post)

View File

@ -0,0 +1,241 @@
#!/usr/bin/env python3
# Tyto - Littérateur
#
# Copyright (C) 2023 Cyrille Louarn <echolib@dismail.de>
#
# 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 <https://www.gnu.org/licenses/>.
#----------------------------------------------------------------------
# XMPP: echolib (im@echolib.re)
#
# Description: Manage 'creators' argument.
# Create articles
# File: /var/lib/tyto/program/creators.py
#----------------------------------------------------------------------
#-------------------------
# Funny Stats Project
#-------------------------
# file lines : 241
# file comments : 41
# file functions: 3
# file program : 182
#--------------------------
import os, importlib, datetime, subprocess
import args, dom, db, langs, tyto, check, wip, logs
#========================#
# Manage action [create] #
#------------------------#
def manage(target):
target = args.target
creators = {
"sitemap" : create_sitemap,
}
try: creators[target](target)
except: logs.out("28", "%s + %s"%(args.action, args.target), True)
#=====================#
# Set and return date #
#---------------------#
def nowdate():
now = datetime.datetime.now()
return(now.strftime('%Y-%m-%d'))
#============================#
# Create sitemap.tyto file #
# Then check it, and wip it #
# ! sitemap is the "www" one #
# seen in 'wip' server #
#----------------------------#
def create_sitemap(target):
dom.valid()
# Define sitemap.tyto
sitemap_tyto = \
'# %s Tyto - Littérateur [tyto new sitemap]\n'%langs.site.sitemap_gen + \
'# NoSitemap\n' + \
'title: %s (%s %s)\n'%(langs.site.sitemap_t, '%s', langs.site.links) + \
'about: %s Tyto - Littérateur\n'%langs.site.sitemap_gen + \
'author: Tyto\n' + \
'tags: sitemap\n' + \
'date: %s\n'%nowdate() + \
'\n' + \
'%s\n' + \
'-----\n' + \
'\n' + \
'%s\n' + \
'|\n' + \
'<hr class="hr">\n' + \
'|\n' + \
'\n' + \
'%s\n'
tab = 8
uri_dir_set = ""
# Contents in article's Header
links = ""
# Index of all links in article
index_l = '-( index\n= <a href="#index">/</a>'
# All links in sitemap
contents = '-( sitemap\n= / <z id="index"></a>'
# Not real articles folder
forbid_dir = (
dom.files_d,
dom.images_d,
dom.modules_d
)
# Get all .tyto files from domain
nbr_files = 0
for r, dirs, files in os.walk(os.getcwd()):
if r.startswith(forbid_dir):
continue
# Take only .tyto files
for f in files:
if not f.endswith(".tyto"):
continue
try:
uri_file = r.rsplit(dom.articles_d)[1]
uri_file = os.path.join(uri_file, f)
except:
uri_file = f
uri_dir = uri_file.rsplit(f)[0]
if not uri_dir:
uri_dir = "~/"
# Try to load Article Database
args.action = "check"
args.target = uri_file
importlib.reload(db)
if not db.exists:
continue
else:
try:
db.hash_www
db.sitemap
if not db.sitemap:
continue
except:
continue
# Count
nbr_files += 1
# create defined link
if not links:
links = \
"link: %s\n%s%s\n%s%s\n"%(
db.title, tab * " ", db.short_srv, tab * " ", db.about
)
else:
links = \
"%s\nlink: %s\n%s%s\n%s%s\n"%(
links,
db.title, tab * " ",
db.short_srv, tab * " ", db.about
)
# Create list link line
curr_dir = uri_dir.count("/")
root_dir = uri_dir.rsplit("/")[0]
ranc_dir = root_dir.replace(" ", "_")
try: prev_dir
except: prev_dir = curr_dir
try: name_dir
except: name_dir = root_dir
#print(":",prev_dir, name_dir, curr_dir, root_dir)
#print(": %s"%(uri_dir.rsplit("/")[int(curr_dir - 1)]))
#print(">", subdirs, uri_dir.rsplit("/"))
#print(":", prev_dir, curr_dir)
if name_dir != root_dir:
index_l = '%s\n= <a href="#%s">%s</a>'%(
index_l,
ranc_dir,
root_dir
)
contents = '%s\n%s [%s] <a id="%s"></a>'%(
contents,
int(curr_dir) * "=",
root_dir,
ranc_dir
)
name_dir = root_dir
prev_dir = curr_dir
if prev_dir != curr_dir:
sanc_dir = uri_dir.rsplit("/")[int(curr_dir - 1)].replace(" ", "_")
index_l = '%s\n%s <a href="#%s">%s</a>'%(
index_l,
int(curr_dir) * "=",
sanc_dir,
uri_dir.rsplit("/")[int(curr_dir - 1)]
)
contents = '%s\n%s [%s] <a id="%s"></a>'%(
contents,
int(curr_dir) * "=",
uri_dir.rsplit("/")[int(curr_dir - 1)],
sanc_dir
)
prev_dir = curr_dir
contents = "%s\n%s _%s"%(
contents,
int(curr_dir + 1) * '=',
db.title
)
# Ending markers
index_l = "%s\n-)"%index_l
contents = "%s\n-)"%contents
# Fill new sitemap.tyto and create
sitemap_tyto = \
sitemap_tyto%(
nbr_files,
links,
index_l,
contents
)
sitemap_file = "%ssitemap.tyto"%dom.articles_d
tyto.set_file(sitemap_file, "New", sitemap_tyto)
# Check and wip
print()
www = subprocess.run(
[
'/usr/bin/tyto',
'force-wip',
'sitemap.tyto'
],
)

View File

@ -23,15 +23,15 @@
# File: /var/lib/tyto/program/db.py # File: /var/lib/tyto/program/db.py
#---------------------------------------------------------------------- #----------------------------------------------------------------------
#------------ #-------------------------
# funny stats # Funny Stats Project
#------------ #-------------------------
# lines: # file lines : 206
# functions: # file comments : 37
# comments: # file functions: 1
#---------------------------------------------------------------------- # file program : 152
#--------------------------
#**********************************************************************
import os import os
import args, logs, dom, form, tyto, check, publish import args, logs, dom, form, tyto, check, publish
@ -79,62 +79,63 @@ if args.target \
# Check if database config is valid (contains values) # Check if database config is valid (contains values)
if exists: if exists:
values = \ values = \
( (
'post_id', 'post_id',
'post_src', 'post_src',
'post_wip', 'post_wip',
'static_wip', 'static_wip',
'post_www', 'post_www',
'static_www', 'static_www',
'direc_src', 'direc_src',
'short_src', 'short_src',
'short_srv', 'short_srv',
'sub_uri', 'sub_uri',
'http_wip', 'http_wip',
'http_www', 'http_www',
'date_chk', 'date_chk',
'hash_chk', 'hash_chk',
'date_wip', 'date_wip',
'hash_wip', 'hash_wip',
'date_www', 'date_www',
'hash_www', 'hash_www',
'title', 'title',
'about', 'about',
'author', 'author',
'meta_tags', 'meta_tags',
'date', 'date',
'snpic', 'snpic',
'uris', 'sitemap',
'uniq_anchors', 'uris',
'uniq_abbrs', 'uniq_anchors',
'uniq_links', 'uniq_abbrs',
'uniq_images', 'uniq_links',
'uniq_files', 'uniq_images',
'uniq_raws', 'uniq_files',
'comments', 'uniq_raws',
'tags', 'comments',
'words', 'tags',
'titles', 'words',
'paragraphs', 'titles',
'links', 'paragraphs',
'images', 'links',
'anchors', 'images',
'abbrs', 'anchors',
'strongs', 'abbrs',
'bolds', 'strongs',
'emphasis', 'bolds',
'italics', 'emphasis',
'dels', 'italics',
'underlines', 'dels',
'cites', 'underlines',
'customs', 'cites',
'icodes', 'customs',
'bcodes', 'icodes',
'quotes', 'bcodes',
'lists', 'quotes',
'files', 'lists',
'raws', 'files',
'codes', 'raws',
'codes',
) )
# Set exist for wip and www files # Set exist for wip and www files
@ -193,3 +194,13 @@ if args.target \
# Article is updated on both servers # Article is updated on both servers
if hash_chk == hash_wip == hash_www: sync_srvs = True if hash_chk == hash_wip == hash_www: sync_srvs = True
#=========================#
# Show title and uri file #
#-------------------------#
def show_title():
try:
print('"%s" > %s'%(title, uri_file))
except:
return

View File

@ -23,271 +23,291 @@
# File: /var/lib/tyto/program/dom.py # File: /var/lib/tyto/program/dom.py
#---------------------------------------------------------------------- #----------------------------------------------------------------------
#------------ #-------------------------
# funny stats # Funny Stats Project
#------------ #-------------------------
# lines: # file lines : 318
# functions: # file comments : 31
# comments: # file functions: 1
#---------------------------------------------------------------------- # file program : 277
#--------------------------
#**********************************************************************
import os, sys, importlib, langs import os, sys, importlib, langs
import args import args
lib = 'tyto_domain'
exists = incomplete = active = ready = shortname = corrupt = False
local_user = articles_db_d = False
hole = False
# Set current directory
try: try:
user_dir ready
except: except:
lib = 'tyto_domain'
exists = incomplete = active = ready = shortname = corrupt = False
local_user = articles_db_d = False
hole = False
# Set current directory
try: try:
user_dir = os.getcwd() + "/" user_dir
except: except:
hole = True
# Settings for domain, check if db is not corrupted
dom_values = \
(
'directory',
'database',
'local_user',
'lang_sys',
'lang_logs',
'articles_db_d',
'articles_d',
'files_d',
'images_d',
'modules_d',
'navbar_f',
'sidebar_f',
'metas_f',
'footer_f',
'footer_about_f',
'shortname',
'www_url',
'wip_url',
'srv_root',
'srv_domain',
'srv_wip',
'srv_wip_tpl_d',
'srv_wip_images_d',
'srv_wip_files_d',
'srv_www',
'srv_www_tpl_d',
'srv_www_images_d',
'srv_www_files_d',
'wip_css_f',
'wip_logo_f',
'wip_navbar_f',
'wip_sidebar_f',
'wip_metas_f',
'wip_footer_f',
'wip_stats_f',
'www_css_f',
'www_navbar_f',
'www_sidebar_f',
'www_metas_f',
'www_footer_f',
'www_stats_f',
'www_logo_f',
'www_rss_f',
'logo',
'styles',
'rss',
'rss_items',
'title',
'date',
'about',
'lang_site',
'mail',
'tags',
'license',
'license_url',
'legal_url',
'terms_url',
'css',
'sep',
'article_code',
'relme',
'sidebar_title',
'sidebar_items',
'activated'
)
create_files = \
(
'navbar_f',
'sidebar_f',
'metas_f',
'footer_f',
'footer_about_f'
)
wip_html_mods = ()
err_val = (()) # Make a list from values error
file_unu = (()) # Make a list for files to check
file_mod = (()) # male a list for modules files to create
dir_new = (()) # Make a list for directories created
dir_unu = (()) # Not created, unused
if not hole:
home_dir = os.path.expanduser('~')
# Set configuration domain directory
root_dir = user_dir
if '/articles' in user_dir:
root_dir = user_dir.rsplit('/articles')[0] + "/"
# Set configuration domain file
config = '%styto_domain.py'%root_dir
shortname = config
# Set exists if configuration file
if os.path.exists(config):
exists = True
try: try:
exec(open(config).read()) user_dir = os.getcwd() + "/"
try:
os.path.exists(articles_d)
if '/articles' in user_dir:
user_uri_dir = user_dir.rsplit(articles_d)[1]
else:
user_uri_dir = ''
os.chdir(articles_d)
except: corrupt = True
except: except:
corrupt = True hole = True
if not args.target in args.pass_targets: # Set current user name
if args.target.startswith("articles/"): try:
args.target = args.target.rsplit("articles/")[1] user
args.target = user_uri_dir + args.target except:
try:
user = os.environ.get('USER')
except:
user = ''
# Settings for domain, check if db is not corrupted
dom_values = \
(
'directory',
'database',
'local_user',
'lang_sys',
'lang_logs',
'articles_db_d',
'articles_d',
'files_d',
'images_d',
'modules_d',
'navbar_f',
'sidebar_f',
'metas_f',
'footer_f',
'shortname',
'www_url',
'wip_url',
'srv_root',
'srv_domain',
'srv_wip',
'srv_wip_tpl_d',
'srv_wip_images_d',
'srv_wip_files_d',
'srv_www',
'srv_www_tpl_d',
'srv_www_images_d',
'srv_www_files_d',
'wip_favicon_f',
'wip_css_f',
'wip_logo_f',
'wip_navbar_f',
'wip_sidebar_f',
'wip_metas_f',
'wip_footer_f',
'wip_stats_f',
'www_navbar_f',
'www_sidebar_f',
'www_metas_f',
'www_footer_f',
'www_stats_f',
'www_logo_f',
'www_css_f',
'www_rss_f',
'www_favicon_f',
'favicon',
'logo',
'styles',
'rss',
'rss_items',
'title',
'date',
'about',
'lang_site',
'mail',
'tags',
'license',
'license_url',
'legal_url',
'terms_url',
'css',
'sep',
'article_code',
'relme',
'sidebar_title',
'sidebar_items',
'activated'
)
create_files = \
(
'navbar_f',
'sidebar_f',
'metas_f',
'footer_f',
)
wip_html_mods = ()
err_val = (()) # Make a list from values error
if not hole:
home_dir = os.path.expanduser('~')
# For logs: show uri if not shortname known # Set configuration domain directory
try: shortname root_dir = user_dir
except: pass if '/articles' in user_dir:
root_dir = user_dir.rsplit('/articles')[0] + "/"
# Set configuration domain file
config = '%styto_domain.py'%root_dir
shortname = config
try: active = activated # Set exists if configuration file
except: pass if os.path.exists(config):
exists = True
if not corrupt: try:
for value in dom_values: exec(open(config).read())
try: try:
eval(str(value)) os.path.exists(articles_d)
value_set = True if '/articles' in user_dir:
except: user_uri_dir = user_dir.rsplit(articles_d)[1]
err_val = err_val + ((value),) else:
value_set = False user_uri_dir = ''
incomplete = True os.chdir(articles_d)
active = False except: corrupt = True
except:
corrupt = True
if value.endswith('_d'):
if value_set:
if not os.path.exists(eval(str(value))):
try:
os.makedirs(eval(str(value)), exist_ok=True)
dir_new = dir_new + ((eval(str(value))),)
except:
dir_unu = dir_unu + ((eval(str(value))),)
elif value.endswith('_f'):
if value_set:
if not os.path.exists(eval(str(value))):
if value in create_files:
file_mod = file_mod + ((value),)
else:
file_unu = file_unu + ((eval(str(value))),)
#==============================================#
# When an active and complete domain is needed #
#----------------------------------------------#
if exists and not incomplete and not corrupt:
wip_html_mods = \
(
eval(str('wip_navbar_f')),
eval(str('wip_sidebar_f')),
eval(str('wip_metas_f')),
eval(str('wip_footer_f'))
)
if active:
ready = True
metas = (
eval(str('metas_f')),
eval(str('wip_metas_f')),
eval(str('www_metas_f'))
)
navbars = (
eval(str('navbar_f')),
eval(str('wip_navbar_f')),
eval(str('www_navbar_f'))
)
sidebars = (
eval(str('sidebar_f')),
eval(str('wip_sidebar_f')),
eval(str('www_sidebar_f'))
)
footers = (
eval(str('footer_f')),
eval(str('wip_footer_f')),
eval(str('www_footer_f')),
eval(str('footer_about_f'))
)
templates = (
eval(str('wip_logo_f')),
eval(str('wip_css_f')),
eval(str('wip_navbar_f')),
eval(str('wip_sidebar_f')),
eval(str('wip_metas_f')),
eval(str('wip_footer_f')),
eval(str('wip_stats_f')),
eval(str('www_logo_f')),
eval(str('www_css_f')),
eval(str('www_navbar_f')),
eval(str('www_sidebar_f')),
eval(str('www_metas_f')),
eval(str('www_footer_f')),
eval(str('www_stats_f')),
eval(str('www_rss_f')),
)
modules = {
"metas" : metas,
"navbar" : navbars,
"sidebar" : sidebars,
"footer" : footers,
"template": templates,
}
templates_wip = { if not args.target in args.pass_targets:
eval(str('wip_logo_f')), if args.target.startswith("articles/"):
eval(str('wip_css_f')), args.target = args.target.rsplit("articles/")[1]
eval(str('wip_navbar_f')), args.target = user_uri_dir + args.target
eval(str('wip_sidebar_f')),
eval(str('wip_metas_f')), # For logs: show uri if not shortname known
eval(str('wip_footer_f')), try: shortname
eval(str('wip_stats_f')), except: pass
}
try: active = activated
except: pass
# Check set values configuration
if not corrupt:
for value in dom_values:
try:
eval(str(value))
value_set = True
except:
err_val = err_val + ((value),)
value_set = False
incomplete = True
active = False
templates_www = {
eval(str('www_logo_f')), #==============================================#
eval(str('www_css_f')), # When an active and complete domain is needed #
eval(str('www_navbar_f')), #----------------------------------------------#
eval(str('www_sidebar_f')), if exists and not incomplete and not corrupt:
eval(str('www_metas_f')), if active:
eval(str('www_footer_f')), ready = True
eval(str('www_stats_f')),
eval(str('www_rss_f')) wip_html_mods = \
} (
eval(str('wip_navbar_f')),
eval(str('wip_sidebar_f')),
eval(str('wip_metas_f')),
eval(str('wip_footer_f'))
)
www_html_mods = \
(
eval(str('www_navbar_f')),
eval(str('www_sidebar_f')),
eval(str('www_metas_f')),
eval(str('www_footer_f'))
)
metas = \
(
eval(str('metas_f')),
eval(str('wip_metas_f')),
eval(str('www_metas_f'))
)
navbars = \
(
eval(str('navbar_f')),
eval(str('wip_navbar_f')),
eval(str('www_navbar_f'))
)
sidebars = \
(
eval(str('sidebar_f')),
eval(str('wip_sidebar_f')),
eval(str('www_sidebar_f'))
)
footers = \
(
eval(str('footer_f')),
eval(str('wip_footer_f')),
eval(str('www_footer_f')),
)
templates = \
(
eval(str('wip_logo_f')),
eval(str('wip_favicon_f')),
eval(str('wip_css_f')),
eval(str('wip_navbar_f')),
eval(str('wip_sidebar_f')),
eval(str('wip_metas_f')),
eval(str('wip_footer_f')),
eval(str('wip_stats_f')),
eval(str('www_favicon_f')),
eval(str('www_logo_f')),
eval(str('www_css_f')),
eval(str('www_navbar_f')),
eval(str('www_sidebar_f')),
eval(str('www_metas_f')),
eval(str('www_footer_f')),
eval(str('www_stats_f')),
eval(str('www_rss_f')),
)
statistics = \
(
eval(str('wip_stats_f')),
eval(str('www_stats_f')),
)
modules = \
{
"metas" : metas,
"navbar" : navbars,
"sidebar" : sidebars,
"footer" : footers,
"template": templates,
"stats" : statistics,
}
templates_files_wip = \
(
eval(str('wip_favicon_f')),
eval(str('wip_logo_f')),
eval(str('wip_css_f')),
eval(str('wip_navbar_f')),
eval(str('wip_sidebar_f')),
eval(str('wip_metas_f')),
eval(str('wip_footer_f')),
eval(str('wip_stats_f')),
)
templates_files_www = \
(
eval(str('www_favicon_f')),
eval(str('www_logo_f')),
eval(str('www_css_f')),
eval(str('www_navbar_f')),
eval(str('www_sidebar_f')),
eval(str('www_metas_f')),
eval(str('www_footer_f')),
eval(str('www_stats_f')),
eval(str('www_rss_f'))
)
#====================================# #====================================#
# Check if domain is ready and ready # # Check if domain is ready and ready #
@ -295,3 +315,4 @@ if not hole:
def valid(): def valid():
if incomplete: sys.exit(41) if incomplete: sys.exit(41)
elif not active: sys.exit(42) elif not active: sys.exit(42)
elif not ready: sys.exit(41)

View File

@ -25,36 +25,38 @@
# File: /var/lib/tyto/program/form.py # File: /var/lib/tyto/program/form.py
#---------------------------------------------------------------------- #----------------------------------------------------------------------
#------------ #-------------------------
# funny stats # Funny Stats Project
#------------ #-------------------------
# lines: # file lines : 1092
# functions: # file comments : 104
# comments: # file functions: 7
#---------------------------------------------------------------------- # file program : 872
#--------------------------
#**********************************************************************
from datetime import datetime from datetime import datetime
import os, sys, shutil, re, locale, importlib import os, sys, shutil, re, locale, importlib
import logs, dom, tyto, html, show, langs import logs, dom, tyto, html, show, langs
# locale translation directory
trans_dir = '/var/lib/tyto/translations'
# Get default System language
try: try:
lang_sys = locale.getdefaultlocale()[0].split('_')[0] lang_site
os.path.exists('%s/site_%s.py'%(trans_dir, lang_sys))
except: except:
lang_sys = 'en' # locale translation directory
trans_dir = '/var/lib/tyto/translations'
lang_site = lang_sys
# Get default System language
try:
lang_sys = locale.getdefaultlocale()[0].split('_')[0]
os.path.exists('%s/site_%s.py'%(trans_dir, lang_sys))
except:
lang_sys = 'en'
lang_site = lang_sys
# Generic answer # Generic answer
answer_yes = ('y', 'Y', 'yes', 'Yes', 'YES', try: answer_yes
'o', 'O', 'oui', 'Oui', 'Oui' except: answer_yes = langs.answer_yes
)
#=======================================# #=======================================#
@ -72,7 +74,11 @@ def asking(question, yes_no):
logs.out("255", '', True) logs.out("255", '', True)
if yes_no: if yes_no:
if not answer in answer_yes: go = False
for yes_names in answer_yes:
if answer.lower() in yes_names:
go = True
if not go:
logs.out("255", '', True) logs.out("255", '', True)
else: else:
@ -207,7 +213,6 @@ def create_domain(target):
'sidebar_f = "%styto.sidebar"\n'%modules_dir + \ 'sidebar_f = "%styto.sidebar"\n'%modules_dir + \
'metas_f = "%styto.metas.html"\n'%modules_dir + \ 'metas_f = "%styto.metas.html"\n'%modules_dir + \
'footer_f = "%styto.footer.html"\n'%modules_dir + \ 'footer_f = "%styto.footer.html"\n'%modules_dir + \
'footer_about_f = "%s"\n'%footer_about_f + \
'\n# Domain\n' + \ '\n# Domain\n' + \
'shortname = "%s"\n'%shortname + \ 'shortname = "%s"\n'%shortname + \
'www_url = "%s"\n'%www_url + \ 'www_url = "%s"\n'%www_url + \
@ -244,7 +249,28 @@ def create_domain(target):
), False) ), False)
if answer: logo = answer if answer: logo = answer
if not logo: logo='logo.png'
# Get css file name
#------------------
try: css_file = dom.css_file
except: css_file = "styles.css"
answer = asking('%s%s {%s} '%(
langs.site.form_css_f, langs.site.q, css_file
), False)
if answer: css_file = answer
# Get favicon file name
#----------------------
try: favicon_file = dom.favicon_file
except: favicon_file = "favicon.png"
answer = asking('%s%s {%s} '%(
langs.site.form_fav_f, langs.site.q, favicon_file
), False)
if answer: favicon_file = answer
# Set config's directories for servers # Set config's directories for servers
@ -256,7 +282,7 @@ def create_domain(target):
srv_www_tpl = "%s/www/template/"%root_srv_dom srv_www_tpl = "%s/www/template/"%root_srv_dom
set_f = \ set_f = \
'# Servers directories\n' + \ '\n# Servers directories\n' + \
'srv_root = "%s/"\n'%srv + \ 'srv_root = "%s/"\n'%srv + \
'srv_domain = "%s/"\n'%root_srv_dom + \ 'srv_domain = "%s/"\n'%root_srv_dom + \
'srv_wip = "%s/wip/"\n'%root_srv_dom + \ 'srv_wip = "%s/wip/"\n'%root_srv_dom + \
@ -269,8 +295,9 @@ def create_domain(target):
'srv_www_files_d = "%s/www/files/"\n'%root_srv_dom + \ 'srv_www_files_d = "%s/www/files/"\n'%root_srv_dom + \
'\n' + \ '\n' + \
'# Servers files (wip)\n' + \ '# Servers files (wip)\n' + \
'wip_favicon_f = "%s%s"\n'%(srv_wip_tpl, favicon_file) + \
'wip_logo_f = "%s%s"\n'%(srv_wip_tpl, logo) + \ 'wip_logo_f = "%s%s"\n'%(srv_wip_tpl, logo) + \
'wip_css_f = "%sstyles.css"\n'%srv_wip_tpl + \ 'wip_css_f = "%s%s"\n'%(srv_wip_tpl, css_file) + \
'wip_navbar_f = "%snavbar.html"\n'%srv_wip_tpl + \ 'wip_navbar_f = "%snavbar.html"\n'%srv_wip_tpl + \
'wip_sidebar_f = "%ssidebar.html"\n'%srv_wip_tpl + \ 'wip_sidebar_f = "%ssidebar.html"\n'%srv_wip_tpl + \
'wip_metas_f = "%smetas.html"\n'%srv_wip_tpl + \ 'wip_metas_f = "%smetas.html"\n'%srv_wip_tpl + \
@ -278,13 +305,14 @@ def create_domain(target):
'wip_stats_f = "%s"\n'%stats_wip_f + \ 'wip_stats_f = "%s"\n'%stats_wip_f + \
'\n' + \ '\n' + \
'# Servers files (www)\n' + \ '# Servers files (www)\n' + \
'www_favicon_f = "%s%s"\n'%(srv_www_tpl, favicon_file) + \
'www_logo_f = "%s%s"\n'%(srv_www_tpl, logo) + \ 'www_logo_f = "%s%s"\n'%(srv_www_tpl, logo) + \
'www_css_f = "%sstyles.css"\n'%srv_www_tpl + \ 'www_css_f = "%s%s"\n'%(srv_www_tpl, css_file) + \
'www_navbar_f = "%snavbar.html"\n'%srv_www_tpl + \ 'www_navbar_f = "%snavbar.html"\n'%srv_www_tpl + \
'www_sidebar_f = "%ssidebar.html"\n'%srv_www_tpl + \ 'www_sidebar_f = "%ssidebar.html"\n'%srv_www_tpl + \
'www_metas_f = "%smetas.html"\n'%srv_www_tpl + \ 'www_metas_f = "%smetas.html"\n'%srv_www_tpl + \
'www_footer_f = "%sfooter.html"\n'%srv_www_tpl + \ 'www_footer_f = "%sfooter.html"\n'%srv_www_tpl + \
'www_stats_f = "%s"'%stats_www_f 'www_stats_f = "%s"\n'%stats_www_f
tyto.set_file(dom.config, False, set_f) tyto.set_file(dom.config, False, set_f)
@ -300,11 +328,13 @@ def create_domain(target):
if answer: www_rss = answer if answer: www_rss = answer
set_f = 'www_rss_f = "%s/www/%s"\n'%(root_srv_dom, rss) + \ set_f = \
'\n# Domain user\'s settings\n' + \ 'www_rss_f = "%s/www/%s"\n'%(root_srv_dom, rss) + \
'logo = "%s"\n'%logo + \ '\n# Domain user\'s settings\n' + \
'styles = "styles.css"\n' + \ 'favicon = "%s"\n'%favicon_file + \
'rss = "%s"'%rss 'logo = "%s"\n'%logo + \
'styles = "%s"\n'%css_file + \
'rss = "%s"\n'%rss
tyto.set_file(dom.config, False, set_f) tyto.set_file(dom.config, False, set_f)
@ -322,7 +352,7 @@ def create_domain(target):
if not str(rss_items).isdigit() or not int(rss_items) > 1: if not str(rss_items).isdigit() or not int(rss_items) > 1:
rss_items = 100 rss_items = 100
set_f = 'rss_items = %d'%int(rss_items) set_f = 'rss_items = %d\n'%int(rss_items)
tyto.set_file(dom.config, False, set_f) tyto.set_file(dom.config, False, set_f)
@ -339,7 +369,7 @@ def create_domain(target):
if not title: invalid = True if not title: invalid = True
else: title = tyto.convert_altname(title) else: title = tyto.convert_altname(title)
set_f = 'title = "%s"'%title set_f = 'title = "%s"\n'%title
tyto.set_file(dom.config, False, set_f) tyto.set_file(dom.config, False, set_f)
@ -354,7 +384,7 @@ def create_domain(target):
if answer: date = answer if answer: date = answer
set_f = 'date = "%s"'%date set_f = 'date = "%s"\n'%date
tyto.set_file(dom.config, False, set_f) tyto.set_file(dom.config, False, set_f)
@ -371,7 +401,7 @@ def create_domain(target):
if not about: invalid = True if not about: invalid = True
else: about = tyto.convert_altname(about) else: about = tyto.convert_altname(about)
set_f = 'about = "%s"'%about set_f = 'about = "%s"\n'%about
tyto.set_file(dom.config, False, set_f) tyto.set_file(dom.config, False, set_f)
@ -391,7 +421,7 @@ def create_domain(target):
if not tyto.exists('%s/site_%s.py'%(trans_dir, lang_site)): if not tyto.exists('%s/site_%s.py'%(trans_dir, lang_site)):
lang_site = 'en' lang_site = 'en'
set_f = 'lang_site = "%s"'%lang_site set_f = 'lang_site = "%s"\n'%lang_site
tyto.set_file(dom.config, False, set_f) tyto.set_file(dom.config, False, set_f)
@ -404,12 +434,13 @@ def create_domain(target):
langs.site.form_mail, langs.site.q, mail langs.site.form_mail, langs.site.q, mail
), False) ), False)
if answer: mail = answer if answer: mail = answer
if not re.search('^\w+@\w+.\w+$', mail): passplus = mail.replace('+', '').replace('-', '')
if not re.search('^\w+@\w+.\w+$', passplus):
logs.out("3", mail, False) logs.out("3", mail, False)
invalid = True invalid = True
set_f = 'mail = "%s"'%mail set_f = 'mail = "%s"\n'%mail
tyto.set_file(dom.config, False, set_f) tyto.set_file(dom.config, False, set_f)
@ -426,14 +457,14 @@ def create_domain(target):
if not tags: invalid = True if not tags: invalid = True
elif '"' in tags: tags = tags.replace('"', '') elif '"' in tags: tags = tags.replace('"', '')
set_f = 'tags = "%s"'%tags set_f = 'tags = "%s"\n'%tags
tyto.set_file(dom.config, False, set_f) tyto.set_file(dom.config, False, set_f)
# Get License domain # Get License domain
#------------------- #-------------------
try: domlicense = dom.license try: domlicense = dom.license
except: domlicense = 'CC BY-NC-SA 3.0' except: domlicense = 'gfdl-1.3'
answer = asking('%s%s {%s} '%( answer = asking('%s%s {%s} '%(
langs.site.form_lic, langs.site.q, domlicense langs.site.form_lic, langs.site.q, domlicense
@ -442,14 +473,16 @@ def create_domain(target):
if answer: domlicense = answer if answer: domlicense = answer
if '"' in domlicense: domlicense = domlicense.replace('"', '') if '"' in domlicense: domlicense = domlicense.replace('"', '')
set_f = 'license = "%s"'%domlicense set_f = 'license = "%s"\n'%domlicense
tyto.set_file(dom.config, False, set_f) tyto.set_file(dom.config, False, set_f)
# Get License URL (optional) # Get License URL (optional)
#--------------------------- #---------------------------
try: licurl = dom.license_url try: licurl = dom.license_url
except: licurl = '' except:
if domlicense == "gfdl-1.3":
licurl = "https://www.gnu.org/licenses/fdl-1.3.txt"
answer = asking('%s [http(s)://...] %s%s {%s} '%( answer = asking('%s [http(s)://...] %s%s {%s} '%(
langs.site.form_opt, langs.site.form_licurl, langs.site.form_opt, langs.site.form_licurl,
@ -462,7 +495,7 @@ def create_domain(target):
logs.out("2", '"http(s)://%s"%s'%(licurl, langs.site.q), False) logs.out("2", '"http(s)://%s"%s'%(licurl, langs.site.q), False)
licurl = '' licurl = ''
set_f = 'license_url = "%s"'%licurl set_f = 'license_url = "%s"\n'%licurl
tyto.set_file(dom.config, False, set_f) tyto.set_file(dom.config, False, set_f)
@ -482,7 +515,7 @@ def create_domain(target):
logs.out("2", '"http(s)://%s"%s'%(legalurl, langs.site.q), False) logs.out("2", '"http(s)://%s"%s'%(legalurl, langs.site.q), False)
legalurl = '' legalurl = ''
set_f = 'legal_url = "%s"'%legalurl set_f = 'legal_url = "%s"\n'%legalurl
tyto.set_file(dom.config, False, set_f) tyto.set_file(dom.config, False, set_f)
@ -502,7 +535,7 @@ def create_domain(target):
logs.out("2", '"http(s)://%s"%s'%(termsurl, langs.site.q), False) logs.out("2", '"http(s)://%s"%s'%(termsurl, langs.site.q), False)
termsurl = '' termsurl = ''
set_f = 'terms_url = "%s"'%termsurl set_f = 'terms_url = "%s"\n'%termsurl
tyto.set_file(dom.config, False, set_f) tyto.set_file(dom.config, False, set_f)
@ -520,7 +553,7 @@ def create_domain(target):
logs.out("3", css, False) logs.out("3", css, False)
css = 'tyto' css = 'tyto'
set_f = 'css = "%s"'%css set_f = 'css = "%s"\n'%css
tyto.set_file(dom.config, False, set_f) tyto.set_file(dom.config, False, set_f)
@ -538,27 +571,27 @@ def create_domain(target):
logs.out("3", answer, False) logs.out("3", answer, False)
sep = "-" sep = "-"
set_f = 'sep = "%s"'%sep set_f = 'sep = "%s"\n'%sep
tyto.set_file(dom.config, False, set_f) tyto.set_file(dom.config, False, set_f)
# Show article source ? # Show article source ?
#---------------------- #----------------------
try: try:
dom.article_code if dom.article_code: article_code = "True"
article_code = "True" else: article_code = "False"
except: except:
article_code = "False" article_code = "False"
answer = ('%s%s {%s} '%( answer = asking('%s%s {%s} (Y|n) '%(
langs.site.form_pscode, langs.site.q, article_code langs.site.form_pscode, langs.site.q, str(article_code)
), False) ), False)
if answer: if answer:
if answer in answer_yes: article_code = "True" if answer in answer_yes: article_code = "True"
else: article_code = "False" else: article_code = "False"
set_f = 'article_code = %s'%article_code set_f = 'article_code = %s\n'%article_code
tyto.set_file(dom.config, False, set_f) tyto.set_file(dom.config, False, set_f)
@ -578,7 +611,7 @@ def create_domain(target):
logs.out("2", '"http(s)://%s"%s'%(relme, langs.site.q), False) logs.out("2", '"http(s)://%s"%s'%(relme, langs.site.q), False)
relmel = '' relmel = ''
set_f = 'relme = "%s"'%relme set_f = 'relme = "%s"\n'%relme
tyto.set_file(dom.config, False, set_f) tyto.set_file(dom.config, False, set_f)
@ -599,7 +632,7 @@ def create_domain(target):
else: else:
sdb_title = tyto.convert_altname(sdb_title) sdb_title = tyto.convert_altname(sdb_title)
set_f = 'sidebar_title = "%s"'%sdb_title set_f = 'sidebar_title = "%s"\n'%sdb_title
tyto.set_file(dom.config, False, set_f) tyto.set_file(dom.config, False, set_f)
@ -617,7 +650,7 @@ def create_domain(target):
if not str(sdb_items).isdigit() or not int(sdb_items) in range(1,17): if not str(sdb_items).isdigit() or not int(sdb_items) in range(1,17):
sdb_items = 6 sdb_items = 6
set_f = 'sidebar_items = %d'%int(sdb_items) set_f = 'sidebar_items = %d\n'%int(sdb_items)
tyto.set_file(dom.config, False, set_f) tyto.set_file(dom.config, False, set_f)
@ -650,13 +683,17 @@ def create_domain(target):
# Activate Domain # Activate Domain
#---------------- #----------------
tyto.set_file(dom.config, False, '\nactivated = True') tyto.set_file(dom.config, False, '\nactivated = True')
shutil.copy2(dom.config, config_bkp)
logs.out("32", config_bkp, False)
# RELoad config # ReLoad config
#-------------- #--------------
importlib.reload(dom) importlib.reload(dom)
# Backup and create local user dir
if not os.makedirs(dom.articles_db_d, exist_ok=True):
logs.out("33", dom.articles_db_d, False)
shutil.copy2(dom.config, config_bkp)
logs.out("32", config_bkp, False)
# Create folders from configuration file # Create folders from configuration file
#--------------------------------------- #---------------------------------------
@ -674,18 +711,18 @@ def create_domain(target):
logs.out("37", folder, False) logs.out("37", folder, False)
else: else:
os.makedirs(folder, exist_ok=True) os.makedirs(folder, exist_ok=True)
logs.out("33", foloder, False) logs.out("33", folder, False)
print('') print('')
# Create in _configs/ modules files # Create in _configs/ modules files
#---------------------------------- #----------------------------------
create_metas('form')
create_navbar('form') html.create_user_metas('new')
create_sidebar('form') html.create_navbar('new')
create_footer('form') html.create_sidebar('new')
create_footer_about('form') html.create_user_footer('new')
print(langs.site.form_ready) print(langs.site.form_ready)
@ -700,16 +737,18 @@ def create_domain(target):
#------------------------# #------------------------#
def create_metas(option): def create_metas(option):
if not dom.ready: dom.valid() if not dom.ready: dom.valid()
print('\n%s'%langs.site.metas_inf)
if option != "new": return
# Create new default config file, or ask if exists # Create new default config file, or ask if exists
if tyto.exists(dom.metas_f): if tyto.exists(dom.metas_f):
answer = asking('%s. %s%s '%( answer = asking('%s%s '%(
langs.site.metas, langs.site.form_reset, langs.site.form_reset, langs.site.q
langs.site.q
), False) ), False)
if not answer in answer_yes: if not answer in answer_yes:
if option == "form": return if option == "new": return
logs.out("255", '', True) logs.out("255", '', True)
# Set default content for # Set default content for
@ -766,10 +805,6 @@ def create_metas(option):
'<meta name="revisit-after" content="3 days">' '<meta name="revisit-after" content="3 days">'
tyto.set_file(dom.metas_f, 'New', metas_tags) tyto.set_file(dom.metas_f, 'New', metas_tags)
# Create an empty html file in wip/www server if not exists
if not tyto.exists(dom.wip_metas_f):
html.create_user_metas('wip')
#=============================# #=============================#
@ -778,15 +813,17 @@ def create_metas(option):
def create_navbar(option): def create_navbar(option):
if not dom.ready: dom.valid() if not dom.ready: dom.valid()
print('\n%s'%langs.site.navbar_inf)
if option != "new": return
# Create new config file, or ask if exists # Create new config file, or ask if exists
if tyto.exists(dom.navbar_f): if tyto.exists(dom.navbar_f):
answer = asking('%s. %s%s '%( answer = asking('%s%s '%(
langs.site.navbar, langs.site.form_reset, langs.site.form_reset, langs.site.q
langs.site.q
), False) ), False)
if not answer in answer_yes: if not answer in answer_yes:
if option == "form": return if option == "new": return
logs.out("255", '', True) logs.out("255", '', True)
@ -827,9 +864,6 @@ def create_navbar(option):
navbar_lang = navbar_lang%(tyto.Tyto, dom.navbar_f) navbar_lang = navbar_lang%(tyto.Tyto, dom.navbar_f)
tyto.set_file(dom.navbar_f, 'New', navbar_lang) tyto.set_file(dom.navbar_f, 'New', navbar_lang)
# Create wip navbar file
html.create_navbar('wip')
#==============================# #==============================#
@ -838,19 +872,21 @@ def create_navbar(option):
def create_sidebar(option): def create_sidebar(option):
if not dom.ready: dom.valid() if not dom.ready: dom.valid()
print('\n%s'%langs.site.sidebar_inf)
if option != "new": return
# Create an empty html file in wip/www server if not exists # Create an empty html file in wip/www server if not exists
if not tyto.exists(dom.wip_sidebar_f): if not tyto.exists(dom.wip_sidebar_f):
tyto.set_file(dom.wip_sidebar_f, 'new', '') tyto.set_file(dom.wip_sidebar_f, 'new', '')
# Create new config file, or ask if exists with option = 'reset' # Create new config file, or ask if exists with option = 'reset'
if tyto.exists(dom.sidebar_f): if tyto.exists(dom.sidebar_f):
answer = asking('%s. %s%s '%( answer = asking('%s%s '%(
langs.site.sidebar, langs.site.form_reset, langs.site.form_reset, langs.site.q
langs.site.q
), False) ), False)
if not answer in answer_yes: if not answer in answer_yes:
if option == "form": return if option == "new": return
logs.out("255", '', True) logs.out("255", '', True)
@ -900,6 +936,9 @@ def create_sidebar(option):
def create_footer(option): def create_footer(option):
if not dom.ready: dom.valid() if not dom.ready: dom.valid()
print('\n%s'%langs.site.footer_inf)
if option != "new": return
# Default footer contents # Default footer contents
#------------------------ #------------------------
Tytosrc = \ Tytosrc = \
@ -924,19 +963,8 @@ def create_footer(option):
'%stitle="%s"\n'%(9 * ' ', langs.site.go_home) + \ '%stitle="%s"\n'%(9 * ' ', langs.site.go_home) + \
'%sclass="footer_title_link">%s</a>'%(9 * ' ', dom.title) '%sclass="footer_title_link">%s</a>'%(9 * ' ', dom.title)
# Insert content of footer_about_f or default if not exists # Insert content of fabout domain
footer_about = '' footer_about = "<p>%s</p>"%dom.about
if tyto.exists(dom.footer_about_f):
footer_custom = open(dom.footer_about_f).read()
for line in footer_custom.rsplit('\n'):
if not line or line.startswith('#'):
continue
line = '%s%s'%(6 * ' ', line)
if footer_about: footer_about = '%s\n%s'%(footer_about, line)
else: footer_about = line
else:
footer_about = "<p>%s</p>"%dom.about
# License URL. Set to homepage if unknown # License URL. Set to homepage if unknown
if not dom.license_url: dom.license_url = '/' if not dom.license_url: dom.license_url = '/'
@ -999,15 +1027,15 @@ def create_footer(option):
# Final HTML footer code # Final HTML footer code
footer = \ footer = \
'%s\n'%footer_lang%(tyto.Tyto, dom.footer_f) + \ '%s\n'%footer_lang%(tyto.Tyto, dom.footer_f) + \
'<footer id="footer_page">\n' + \ '<footer accesskey="f" id="footer_page">\n' + \
' <div id="footer_container"> \n' + \ ' <div id="footer_container"> \n' + \
' <div id="footer_infos">\n' + \ ' <div id="footer_infos">\n' + \
' <h1 id="footer_site_title"\n' + \ ' <h2 id="footer_site_title"\n' + \
' title="%s %s">%s %s\n'%( ' title="%s %s">%s %s\n'%(
langs.site.add_inf, dom.title, langs.site.add_inf, dom.title,
langs.site.about, dom.title langs.site.about, dom.title
) + \ ) + \
' </h1>\n' + \ ' </h2>\n' + \
'%s\n'%(footer_about) + \ '%s\n'%(footer_about) + \
' </div>\n' + \ ' </div>\n' + \
'\n' + \ '\n' + \
@ -1031,7 +1059,7 @@ def create_footer(option):
' <li class="footer_item">%s%s \n'%( ' <li class="footer_item">%s%s \n'%(
langs.site.feed, langs.site.pp langs.site.feed, langs.site.pp
) + \ ) + \
' <a href="%s/%s"\n'%(dom.www_url, dom.rss) + \ ' <a href="/%s"\n'%(dom.rss) + \
' title="RSS 2.0 - %s"\n'%dom.title + \ ' title="RSS 2.0 - %s"\n'%dom.title + \
' class="footer_item_link">RSS 2.0</a>\n' + \ ' class="footer_item_link">RSS 2.0</a>\n' + \
' </li>\n' + \ ' </li>\n' + \
@ -1052,41 +1080,13 @@ def create_footer(option):
# Create new default file, or ask if exists # Create new default file, or ask if exists
if tyto.exists(dom.footer_f): if tyto.exists(dom.footer_f):
answer = asking('%s. %s%s '%( answer = asking('%s%s '%(
langs.site.footer, langs.site.form_reset, langs.site.form_reset, langs.site.q
langs.site.q
), False) ), False)
if not answer in answer_yes: if not answer in answer_yes:
if option == "form": return if option == "new": return
logs.out("255", '', True) logs.out("255", '', True)
tyto.set_file(dom.footer_f, 'New', footer) 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):
html.create_user_footer('wip')
# Generic HTML list in footer
"""
' <li class="footer_item">\n' + \
' <a href="%s"\n'% + \
' title="%s"\n'% + \
' class="footer_item_link">%s</a> %s\n'%() + \
' </li>\n'
"""
#========================================#
# Create custom about section for footer #
#----------------------------------------#
def create_footer_about(option):
if not tyto.exists(dom.footer_about_f):
set_f = '%s\n'%langs.site.footer_about_doc%(tyto.Tyto,
dom.footer_about_f
) + \
'<p id="footer_about">%s</p>'%dom.about
tyto.set_file(dom.footer_about_f, False, set_f)

View File

@ -22,25 +22,37 @@
# File: /var/lib/tyto/program/html.py # File: /var/lib/tyto/program/html.py
#---------------------------------------------------------------------- #----------------------------------------------------------------------
#------------ #-------------------------
# funny stats # Funny Stats Project
#------------ #-------------------------
# lines: # file lines : 544
# functions: # file comments : 71
# comments: # file functions: 8
#---------------------------------------------------------------------- # file program : 414
#--------------------------
#**********************************************************************
import os, sys, importlib import os, sys, importlib
import logs, db, dom, tyto, form, langs import logs, db, dom, tyto, form, langs
# Publish option can be # Publish option can be
wip_opts = ('wip', 'new')
pub_opts = ('www', 'pub') pub_opts = ('www', 'pub')
# Not a line if it starts with...(for sidebar, navbar) # Not a line if it starts with...(for sidebar, navbar)
nolines = ('#', '/') nolines = ('#', '/')
# For static modules
if dom.ready:
tags_html_mods = \
{
dom.wip_navbar_f : '<!--# include virtual="/template/navbar.html"-->',
dom.wip_sidebar_f : '<!--# include virtual="/template/sidebar.html"-->',
dom.wip_metas_f : '<!--# include virtual="/template/metas.html"-->',
dom.wip_footer_f : '<!--# include virtual="/template/footer.html"-->'
}
#==========================# #==========================#
# Load article DB # # Load article DB #
# Start HTML page sections # # Start HTML page sections #
@ -67,9 +79,8 @@ def create_metas_page():
db.sub_uri, dom.rss, db.sub_uri, dom.rss,
dom.title, dom.sep, dom.shortname dom.title, dom.sep, dom.shortname
) )
icon_file = 'favicon.png'
icon_ref = 'type="image/png" href="%stemplate/%s"'%( icon_ref = 'type="image/png" href="%stemplate/%s"'%(
db.sub_uri, icon_file db.sub_uri, dom.favicon
) )
relme = '' # External URL in metas (if exists in config domain) relme = '' # External URL in metas (if exists in config domain)
if dom.relme: if dom.relme:
@ -84,7 +95,7 @@ def create_metas_page():
#----------------------- #-----------------------
global metas global metas
metas = \ metas = \
tyto.tags_html_mods[dom.wip_metas_f] + '\n' + \ tags_html_mods[dom.wip_metas_f] + '\n' + \
' <meta name="viewport" content="%s">\n'%scale + \ ' <meta name="viewport" content="%s">\n'%scale + \
' <meta name=”url” content=”%s”>\n'%dom.www_url + \ ' <meta name=”url” content=”%s”>\n'%dom.www_url + \
' <meta name="language" content="%s">\n'%dom.lang_site + \ ' <meta name="language" content="%s">\n'%dom.lang_site + \
@ -153,23 +164,25 @@ def create_main_page(target, article_bottom):
'%s\n'%metas + \ '%s\n'%metas + \
' </head>\n\n' + \ ' </head>\n\n' + \
' <body>\n' + \ ' <body>\n' + \
' <div id="site_container">\n' + \
' <header id="header_page">\n' + \ ' <header id="header_page">\n' + \
' <div id="site_logo">\n' + \ ' <div id="site_logo">\n' + \
' %s\n'%logo_html + \ ' %s\n'%logo_html + \
' </div>\n' + \ ' </div>\n' + \
' <div id="site_infos">\n' + \ ' <div id="site_infos">\n' + \
' <a href="/"\n' + \ ' <h1 id="site_title">\n' + \
' title="%s"\n'%(langs.site.home) + \ ' <a href="/"\n' + \
' id="site_link">\n' + \ ' title="%s"\n'%(langs.site.home) + \
' <h1 id="site_title">%s</h1>\n'%dom.title + \ ' id="site_link">%s</a>\n'%dom.title + \
' </a>\n' + \ ' </h1>\n' + \
' <p id="site_about">%s</p>\n'%dom.about + \ ' <p id="site_about">%s</p>\n'%dom.about + \
' </div>\n' + \ ' </div>\n' + \
' </header>\n' + \ ' </header>\n' + \
tyto.tags_html_mods[dom.wip_navbar_f] + '\n' + \ tags_html_mods[dom.wip_navbar_f] + '\n' + \
' <div id="article_sidebar_container">\n' + \
' <article id="article_main">\n' + \ ' <article id="article_main">\n' + \
' <h1 id="main_title"\n' + \ ' <h1 accesskey="t" id="post_title"\n' + \
' title="[%s] %s %s %s %s">%s</h1>\n'%( ' title="[%s] %s %s %s %s">%s</h1>\n'%(
db.title, langs.site.w_written, db.date, db.title, langs.site.w_written, db.date,
langs.site.by, db.author, langs.site.by, db.author,
db.title, db.title,
@ -188,8 +201,10 @@ def create_main_page(target, article_bottom):
' </div>\n' + \ ' </div>\n' + \
' </article>\n' + \ ' </article>\n' + \
'\n' + \ '\n' + \
tyto.tags_html_mods[dom.wip_sidebar_f] + '\n' + \ tags_html_mods[dom.wip_sidebar_f] + '\n' + \
tyto.tags_html_mods[dom.wip_footer_f] + '\n' + \ ' </div>\n' + \
tags_html_mods[dom.wip_footer_f] + '\n' + \
' </div>\n' + \
' </body>\n' + \ ' </body>\n' + \
'</html>' '</html>'
@ -203,7 +218,7 @@ def create_html_time_meta(process):
importlib.reload(db) importlib.reload(db)
global time_html_pub, meta_pub, date_raw global time_html_pub, meta_pub, date_raw
if process == 'wip': if process == 'wip':
try: try:
date_raw = db.date_wip # <time datetime= / meta search_date date_raw = db.date_wip # <time datetime= / meta search_date
@ -231,7 +246,7 @@ def create_html_time_meta(process):
' <span id="article_pub"\n' + \ ' <span id="article_pub"\n' + \
' title="[%s] %s %s (%s)">%s</span>\n'%( ' title="[%s] %s %s (%s)">%s</span>\n'%(
db.title, langs.site.w_published, date_pub, time_pub, db.title, langs.site.w_published, date_pub, time_pub,
date_pub db.date
) + \ ) + \
' </time>\n' + \ ' </time>\n' + \
'<!--/Tyto_Published-->' '<!--/Tyto_Published-->'
@ -250,15 +265,15 @@ def create_html_time_meta(process):
def create_user_metas(option): def create_user_metas(option):
dom.valid() dom.valid()
if option == 'wip': target = dom.wip_metas_f form.create_metas(option)
if option in wip_opts: target = dom.wip_metas_f
elif option in pub_opts: target = dom.www_metas_f elif option in pub_opts: target = dom.www_metas_f
if option == 'www' and tyto.exists(target): if option == 'www' and tyto.exists(target):
form.asking('%s. %s%s '%( form.asking('%s. %s%s '%(
langs.site.metas, langs.site.form_rep, langs.site.q langs.site.metas, langs.site.form_rep, langs.site.q
), True) ), True)
print('\n%s'%langs.site.metas_inf)
# Create wip metas.html file according to option # Create wip metas.html file according to option
#----------------------------------------------- #-----------------------------------------------
@ -284,10 +299,12 @@ def create_user_metas(option):
def create_navbar(option): def create_navbar(option):
dom.valid() dom.valid()
form.create_navbar(option)
if not tyto.exists(dom.navbar_f): if not tyto.exists(dom.navbar_f):
logs.out("1", dom.navbar_f, True) logs.out("1", dom.navbar_f, True)
if option == 'wip': target = dom.wip_navbar_f if option in wip_opts: target = dom.wip_navbar_f
elif option in pub_opts: target = dom.www_navbar_f elif option in pub_opts: target = dom.www_navbar_f
if option == 'www' and tyto.exists(target): if option == 'www' and tyto.exists(target):
@ -296,14 +313,12 @@ def create_navbar(option):
option, langs.site.q option, langs.site.q
), True) ), True)
print('\n%s'%langs.site.navbar_inf)
# navbar has items # navbar has items
navbar_items = False navbar_items = False
# Set first HTML line # Set first HTML line
menu_html = \ menu_html = \
'%s<nav id="site_menu">\n'%(4 * ' ') + \ '%s<nav accesskey="m" id="site_menu">\n'%(4 * ' ') + \
'%s<menu id="site_menu_items">'%(6 * ' ') '%s<menu id="site_menu_items">'%(6 * ' ')
navbar_lines = open(dom.navbar_f, 'r').read() navbar_lines = open(dom.navbar_f, 'r').read()
@ -345,7 +360,7 @@ def create_navbar(option):
continue continue
# index.html server files must exist (or 404 error) # index.html server files must exist (or 404 error)
if option == 'wip': if option in wip_opts:
if not tyto.exists(wip_index): if not tyto.exists(wip_index):
logs.out('26', '> %s'%(wip_index), False) logs.out('26', '> %s'%(wip_index), False)
no_wip_index = True no_wip_index = True
@ -374,10 +389,7 @@ def create_navbar(option):
# Nothing to do # Nothing to do
if not navbar_items: if not navbar_items:
if not tyto.exists(target): tyto.set_file(target, 'New', '')
tyto.set_file(target, 'New', '')
logs.out('28', '%s'%langs.log.navbar, False)
return
# Create ending HTML file # Create ending HTML file
else: else:
@ -392,12 +404,14 @@ def create_navbar(option):
def create_sidebar(option): def create_sidebar(option):
dom.valid() dom.valid()
form.create_sidebar(option)
if not tyto.exists(dom.sidebar_f): if not tyto.exists(dom.sidebar_f):
logs.out("1", dom.sidebar_f, True) logs.out("1", dom.sidebar_f, True)
if int(dom.sidebar_items) > 16: db.sidebar_items = 6 if int(dom.sidebar_items) > 16: db.sidebar_items = 6
if option == 'wip': target = dom.wip_sidebar_f if option in wip_opts: target = dom.wip_sidebar_f
elif option in pub_opts: target = dom.www_sidebar_f elif option in pub_opts: target = dom.www_sidebar_f
if option == 'www' and tyto.exists(target): if option == 'www' and tyto.exists(target):
@ -405,15 +419,13 @@ def create_sidebar(option):
langs.site.sidebar, langs.site.form_rep, langs.site.q langs.site.sidebar, langs.site.form_rep, langs.site.q
), True) ), True)
print('\n%s'%langs.site.sidebar_inf)
sidebar_items = False sidebar_items = False
# Set HTML sidebar # Set HTML sidebar
sidebar_list = '' sidebar_list = ''
sidebar_html = \ sidebar_html = \
'<aside id="sidebar">\n' + \ '<aside accesskey="s" id="sidebar">\n' + \
' <h1 id="sidebar_title">%s</h1>\n' + \ ' <h2 id="sidebar_title">%s</h2>\n' + \
' <ul id="sidebar_list">\n' + \ ' <ul id="sidebar_list">\n' + \
'%s' + \ '%s' + \
' </ul>\n' + \ ' </ul>\n' + \
@ -447,7 +459,7 @@ def create_sidebar(option):
exec(open(db_uri).read(),globals()) exec(open(db_uri).read(),globals())
# Check wip status and if article exists in server # Check wip status and if article exists in server
if option == 'wip': if option in wip_opts:
if hash_wip != hash_chk: if hash_wip != hash_chk:
logs.out("30", line, False) logs.out("30", line, False)
continue continue
@ -477,20 +489,17 @@ def create_sidebar(option):
' <li class="sidebar_item">\n' + \ ' <li class="sidebar_item">\n' + \
' <a class="sidebar_item_link"\n' + \ ' <a class="sidebar_item_link"\n' + \
' href="/%s">\n'%short_srv + \ ' href="/%s">\n'%short_srv + \
' <h2 class="sidebar_item_title">%s</h2>\n'%title + \ ' <h3 class="sidebar_item_title">%s</h3>\n'%title + \
' <p class="sidebar_item_about"\n' + \ ' <p class="sidebar_item_about"\n' + \
' title="%s">\n'%link_title + \ ' title="%s">\n'%link_title + \
' %s [%s] - %s\n'%(date, author, about) + \ ' %s - %s\n'%(date, about) + \
' </p>\n' + \ ' </p>\n' + \
' </a>\n' + \ ' </a>\n' + \
' </li>\n' ' </li>\n'
# Nothing to do # Nothing to do
if not sidebar_items: if not sidebar_items:
if not tyto.exists(target): tyto.set_file(target, 'New', '')
tyto.set_file(target, 'New', '')
logs.out('28', '%s'%langs.log.sidebar, False)
return
else: else:
# Create HTML complete sidebar # Create HTML complete sidebar
@ -510,7 +519,9 @@ def create_sidebar(option):
def create_user_footer(option): def create_user_footer(option):
dom.valid() dom.valid()
if option == 'wip': target = dom.wip_footer_f form.create_footer(option)
if option in wip_opts: target = dom.wip_footer_f
elif option in pub_opts: target = dom.www_footer_f elif option in pub_opts: target = dom.www_footer_f
if option == 'www' and tyto.exists(target): if option == 'www' and tyto.exists(target):
@ -518,8 +529,6 @@ def create_user_footer(option):
langs.site.footer, langs.site.form_rep, langs.site.q langs.site.footer, langs.site.form_rep, langs.site.q
), True) ), True)
print('\n%s'%langs.site.footer_inf)
try: footer_f = open(dom.footer_f, 'r').read() try: footer_f = open(dom.footer_f, 'r').read()
except: logs.out("1", dom.footer_f, True) except: logs.out("1", dom.footer_f, True)

View File

@ -23,29 +23,32 @@
# File: /var/lib/tyto/program/infos.py # File: /var/lib/tyto/program/infos.py
#---------------------------------------------------------------------- #----------------------------------------------------------------------
#------------ #-------------------------
# funny stats # Funny Stats Project
#------------ #-------------------------
# lines: # file lines : 131
# functions: # file comments : 27
# comments: # file functions: 3
#---------------------------------------------------------------------- # file program : 91
#--------------------------
#**********************************************************************
import os, importlib import os, sys, importlib
import langs import langs
importlib.reload(langs) importlib.reload(langs)
# Set colors # Set colors
CS = '\033[0;0m' CS = '\033[0;0m'
CR = '\033[1;31m' CR = '\033[1;31m'
CY = '\033[1;33m' CY = '\033[1;33m'
CG = '\033[1;32m' CG = '\033[1;32m'
def tyto(target):
noinfos = False
#
# Show Version
#
def version():
# Show Version # Show Version
tytobin = open('/usr/bin/tyto').read() tytobin = open('/usr/bin/tyto').read()
for line in tytobin.rsplit('\n'): for line in tytobin.rsplit('\n'):
@ -54,6 +57,10 @@ def tyto(target):
break break
#==========================================#
# List all found domain in local directory #
#------------------------------------------"
def list_domains():
# Show domains list # Show domains list
try: try:
has_domains = True has_domains = True
@ -68,34 +75,57 @@ def tyto(target):
print('! No directory > %s/'%db_domains) print('! No directory > %s/'%db_domains)
if has_domains: if has_domains:
list_domains = (())
for folder in os.listdir(db_domains): for folder in os.listdir(db_domains):
domain_local_uri = '%s/%s'%(db_domains, folder) domain_local_uri = '%s/%s'%(db_domains, folder)
if os.path.isdir(domain_local_uri): if os.path.isdir(domain_local_uri):
line = ' - %s >'%folder
# Check configuration file and load
domain_conf = '%s/domain_config.bkp'%domain_local_uri domain_conf = '%s/domain_config.bkp'%domain_local_uri
if os.path.exists(domain_conf): if not os.path.exists(domain_conf):
line = '%s %sUnknown%s ?'%(line, CR, CS)
else:
try: try:
exec(open(domain_conf).read(),globals()) exec(open(domain_conf).read(),globals())
line = '%s %sConfig%s > '%(line, CG, CS)
except: except:
continue pass
if os.path.exists(directory):
dir_domain = '%s%s%s'%(CG, directory, CS) try:
else: if os.path.exists(directory):
dir_domain = '%s%s%s'%(CR, directory, CS) line = '%s %s%s%s'%(line, CG, directory, CS)
list_domains = \ else:
(('%s > %s > %s'%(folder, dir_domain, www_url)),) line = '%s %s%s%s'%(line, CR, directory, CS)
except:
if list_domains: line = '%s %sNo root%s > '%(line, CR, CS)
print('# %s %ss %s'%(
langs.site.reg_domains, try:
langs.site.fo, line = '%s %s'%(line, www_url)
user except:
) line = '%s %sNo URL%s > '%(line, CR, CS)
)
for domain in list_domains: print(line)
print(' - %s'%domain)
#
# --help [full]
#
def tyto(target):
if target == "full":
version()
list_domains()
print(langs.site.args_helps)
print(langs.site.ex_helps)
elif target == 'help':
print(langs.site.args_helps)
# Show arguments help elif target == 'domains':
print(langs.site.args_helps) list_domains()
elif target == 'version':
version()
sys.exit(0)

View File

@ -23,50 +23,68 @@
# File: /var/lib/tyto/program/langs.py # File: /var/lib/tyto/program/langs.py
#---------------------------------------------------------------------- #----------------------------------------------------------------------
#------------ #-------------------------
# funny stats # Funny Stats Project
#------------ #-------------------------
# lines: # file lines : 90
# functions: # file comments : 28
# comments: # file functions: 0
#---------------------------------------------------------------------- # file program : 53
#--------------------------
#**********************************************************************
import locale, sys, os, importlib import locale, sys, os, importlib
import dom 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: try:
lang_sys = locale.getdefaultlocale()[0].split('_')[0] site.yes
os.path.exists('%s/logs_%s.py'%(trans_dir, lang_sys))
except: except:
lang_sys = 'en' # Import translation directory
trans_dir = '/var/lib/tyto/translations'
sys.path.insert(0, trans_dir)
# Create yes array with all yes languages
try:
answer_yes
except:
answer_yes = (())
for lang_file in os.listdir(trans_dir):
if lang_file.startswith("site_") and lang_file.endswith(".py"):
lang_file = lang_file.replace(".py", "")
lang = importlib.import_module(lang_file)
answer_yes = answer_yes + ((lang.yes),)
# 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_logs, package=None)
except:
log = importlib.import_module('logs_%s'%lang_sys, package=None)
# 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)
# 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_logs, package=None)
except:
log = importlib.import_module('logs_%s'%lang_sys, package=None)
# 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)

View File

@ -23,24 +23,31 @@
# File: /var/lib/tyto/program/logs.py # File: /var/lib/tyto/program/logs.py
#---------------------------------------------------------------------- #----------------------------------------------------------------------
#------------ #-------------------------
# funny stats # Funny Stats Project
#------------ #-------------------------
# lines: # file lines : 127
# functions: # file comments : 23
# comments: # file functions: 1
#---------------------------------------------------------------------- # file program : 93
#--------------------------
#**********************************************************************
import os, sys import os, sys
import langs import langs
# Set colors
CS = '\033[0;0m' try:
CR = '\033[1;31m' shebang
CY = '\033[1;33m' except:
CG = '\033[1;32m' # Use to mark new article
shebang = "#!/NEW"
# Set colors
CS = '\033[0;0m'
CR = '\033[1;31m'
CY = '\033[1;33m'
CG = '\033[1;32m'
# Exit from program with message # # Exit from program with message #
@ -97,6 +104,9 @@ def out(nbr, value, out):
'60' : '\n%s'%langs.log.status_r, '60' : '\n%s'%langs.log.status_r,
'61' : '%s%s%s > %s'%(CG, langs.log.file_e, CS, value), '61' : '%s%s%s > %s'%(CG, langs.log.file_e, CS, value),
'85' : ' ╞═ %s%s%s > %s'%(CY, langs.log.was_pub, CS, value), '85' : ' ╞═ %s%s%s > %s'%(CY, langs.log.was_pub, CS, value),
'81' : '%s%s%s > %s'%(CR, langs.log.post_exists, CS, value),
'82' : '%s%s "%s"%s > %s'%(CR, langs.log.shebang_r, shebang, CS, value),
'84' : '%s%s%s %s'%(CR, langs.log.title_no, CS, value),
'91' : ' ╞═ %s%s%s > %s'%(CY, langs.log.post_nfd, CS, value), '91' : ' ╞═ %s%s%s > %s'%(CY, langs.log.post_nfd, CS, value),
'92' : ' ╞═ %s%s%s > %s'%(CG, langs.log.post_yfd, CS, value), '92' : ' ╞═ %s%s%s > %s'%(CG, langs.log.post_yfd, CS, value),
'94' : ' ╞═ %s%s%s > %s'%(CY, langs.log.st_chk_o, CS, value), '94' : ' ╞═ %s%s%s > %s'%(CY, langs.log.st_chk_o, CS, value),

View File

@ -23,18 +23,19 @@
# File: /var/lib/tyto/program/new.py # File: /var/lib/tyto/program/new.py
#---------------------------------------------------------------------- #----------------------------------------------------------------------
#------------ #-------------------------
# funny stats # Funny Stats Project
#------------ #-------------------------
# lines: # file lines : 94
# functions: # file comments : 27
# comments: # file functions: 1
#---------------------------------------------------------------------- # file program : 59
#--------------------------
#**********************************************************************
import sys import sys
import args, dom, logs, form, html from unidecode import unidecode
import args, dom, logs, langs, form, html, tyto, show, creators
#===============================================# #===============================================#
@ -42,21 +43,52 @@ import args, dom, logs, form, html
# - domain: target becomes 3rd command argument # # - domain: target becomes 3rd command argument #
#-----------------------------------------------# #-----------------------------------------------#
def manage(target): def manage(target):
# Generic option, except for domain # "domain" target
option = 'new' #----------------
option = args.action
if target == "domain": if target == "domain":
try: option = sys.argv[3] try: option = sys.argv[3]
except: option = '' except: option = args.action
if target in args.pass_targets: if target in args.pass_targets:
actions = { actions = {
'domain' : form.manage, 'domain' : form.manage,
'sidebar' : form.create_sidebar, 'sidebar' : html.create_sidebar,
'navbar' : form.create_navbar, 'navbar' : html.create_navbar,
'metas' : form.create_metas, 'metas' : html.create_user_metas,
'footer' : form.create_footer 'footer' : html.create_user_footer,
'sitemap' : creators.manage
} }
actions[target](option) actions[target](option)
# article target name
#--------------------
else: else:
logs.out("11", '"%s" with "%s"'%(target, option), True) if args.target.endswith(".tyto"):
args.target = args.target.replace(".tyto", '')
# In case needed (todo later)
# u = unidecode(args.target, "utf-8")
# args.target = unidecode(u)
filepost = "%s%s.tyto"%(dom.articles_d, args.target)
if tyto.exists(filepost):
logs.out("81", filepost, True)
else:
form.asking("%s%s {%s}%s "%(
langs.site.new_post,
langs.site.q,
filepost,
langs.site.q
), True)
post = tyto.new_article%(logs.shebang,
args.target,
dom.user,
tyto.nowdate().rsplit(' ')[0]
)
tyto.set_file(filepost, True, post)
show.read_lines(filepost, True)

View File

@ -23,32 +23,51 @@
# File: /var/lib/tyto/program/publish.py # File: /var/lib/tyto/program/publish.py
#---------------------------------------------------------------------- #----------------------------------------------------------------------
#------------ #-------------------------
# funny stats # Funny Stats Project
#------------ #-------------------------
# lines: # file lines : 294
# functions: # file comments : 50
# comments: # file functions: 6
#---------------------------------------------------------------------- # file program : 206
#--------------------------
#**********************************************************************
import os, sys, shutil, importlib import os, sys, shutil, importlib, subprocess
from pathlib import Path from pathlib import Path
import logs, args, dom, db, wip, html, tyto, form, stats, rss, langs import logs, args, dom, db, wip, html, tyto, form, stats, rss, langs, check
#==============================# #==============================#
# Manage action, get post db # # Manage action, get post db #
# check if publish can be done # # check if publish can be done #
#------------------------------# #------------------------------#
def manage_publish(target): def manage(target):
dom.valid() dom.valid()
# Specific QUICK processes: check > wip > publish
if args.action == "quick-pub":
try: db.uri_file
except: logs.out("28", "%s + %s"%(args.action, args.target), True)
wip = subprocess.run(
[
'/usr/bin/tyto',
'force-wip',
target
],
)
importlib.reload(db)
check_to_publish('one')
publish_article()
rss.create_feed()
return
# Target is footer, sidebar, navbar, metas # Target is footer, sidebar, navbar, metas
# template: create/copy template/ files # template: create/copy template/ files
# all: publish all wip article # all: publish all wip article
#----------------------------------------- #-----------------------------------------
if target in args.pass_targets: elif target in args.pass_targets:
do = { do = {
'updated' : publish_all, 'updated' : publish_all,
'again' : publish_all, 'again' : publish_all,
@ -64,6 +83,7 @@ def manage_publish(target):
do[target]('www') do[target]('www')
return return
# Database must exists... # Database must exists...
if not target: logs.out("5", '', True) if not target: logs.out("5", '', True)
if not db.post: logs.out("1", db.uri_file, True) if not db.post: logs.out("1", db.uri_file, True)
@ -134,7 +154,8 @@ def check_to_publish(process):
global err_pub global err_pub
err_pub = False err_pub = False
print('\n ├ [%s] > %s'%(db.title, db.post_src)) print('')
db.show_title()
# Article was not checked or changed # Article was not checked or changed
if db.no_chk: if db.no_chk:
@ -156,12 +177,13 @@ def check_to_publish(process):
if process == 'all': return if process == 'all': return
elif process == 'one': sys.exit(err_pub) elif process == 'one': sys.exit(err_pub)
#===============# #===============#
# Let's publish # # Let's publish #
#---------------# #---------------#
def publish_article(): def publish_article():
# Copy wip page to www page # Copy wip page to www page
if not os.makedirs('%s%s'%(dom.srv_www, db.direc_src), exist_ok=True): if 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) logs.out("33", '%s%s'%(dom.srv_www, db.direc_src), False)
# Replace in DB hash_wip and date_wip # Replace in DB hash_wip and date_wip
@ -261,6 +283,9 @@ def publish_template(option):
logs.out("32", item_dst, False) logs.out("32", item_dst, False)
# Create new file from _configs/ files # Create new file from _configs/ files
if args.option == "--no-mods":
return
html.create_sidebar('pub') html.create_sidebar('pub')
html.create_navbar('pub') html.create_navbar('pub')
html.create_user_metas('pub') html.create_user_metas('pub')

View File

@ -23,15 +23,15 @@
# File: /var/lib/tyto/program/rss.py # File: /var/lib/tyto/program/rss.py
#---------------------------------------------------------------------- #----------------------------------------------------------------------
#------------ #-------------------------
# funny stats # Funny Stats Project
#------------ #-------------------------
# lines: # file lines : 129
# functions: # file comments : 28
# comments: # file functions: 1
#---------------------------------------------------------------------- # file program : 90
#--------------------------
#*********************************************************************
import os import os
from pathlib import Path from pathlib import Path
@ -86,6 +86,10 @@ def create_feed():
if not hash_www or hash_chk != hash_www: if not hash_www or hash_chk != hash_www:
continue continue
# NoSitemap
if not db.sitemap:
continue
rss_item = True rss_item = True
nbr_item += 1 nbr_item += 1

View File

@ -24,19 +24,20 @@
# File: /var/lib/tyto/program/show.py # File: /var/lib/tyto/program/show.py
#---------------------------------------------------------------------- #----------------------------------------------------------------------
#------------ #-------------------------
# funny stats # Funny Stats Project
#------------ #-------------------------
# lines: # file lines : 216
# functions: # file comments : 39
# comments: # file functions: 3
#---------------------------------------------------------------------- # file program : 156
#--------------------------
#**********************************************************************
import os, sys, importlib import os, sys, importlib, subprocess
import args, logs, langs, dom, db, form, tyto, check, html, stats import args, logs, langs, dom, db, form, tyto, check, html, stats
#========================# #========================#
# Read lines from a file # # Read lines from a file #
# alone: True/False # # alone: True/False #
@ -93,90 +94,85 @@ def manage(target):
try: post_www = db.post_www try: post_www = db.post_www
except: pass except: pass
# Except for show-about > Show post DB
if args.action == "show-about":
target = 'post'
# Convert command action to do[] # Convert command action to do[]
# as edit* &nd show* [action] have same target file # as edit* &nd show* [action] have same target file
actions = \ actions = \
{ {
"show" : 'src', "show" : 'src',
"edit" : 'src', "edit" : 'src',
"post" : 'src', "post" : 'src',
"show-db" : 'db', "preview" : 'wip',
"edit-db" : 'db', "show-db" : 'db',
"show-about" : 'about', "edit-db" : 'db',
"edit-about" : 'about', "show-wip" : 'wip',
"show-wip" : 'wip', "edit-wip" : 'wip',
"edit-wip" : 'wip', "show-www" : 'www',
"show-www" : 'www', "edit-www" : 'www'
"edit-www" : 'www' }
}
action = actions[args.action] action = actions[args.action]
# Set target file from "new" [action] # Set target file from "new" [action]
do = \ do = \
{ {
'src' : { 'src' : {
"domain" : dom.config, "domain" : dom.config,
"footer" : dom.footer_f, "footer" : dom.footer_f,
"metas" : dom.metas_f, "metas" : dom.metas_f,
"navbar" : dom.navbar_f, "navbar" : dom.navbar_f,
"sidebar" : dom.sidebar_f, "sidebar" : dom.sidebar_f,
"post" : post_src "post" : post_src
}, },
'db' : { 'db' : {
"domain" : dom.config, "domain" : dom.config,
"footer" : dom.footer_f, "footer" : dom.footer_f,
"metas" : dom.metas_f, "metas" : dom.metas_f,
"navbar" : dom.navbar_f, "navbar" : dom.navbar_f,
"sidebar" : dom.sidebar_f, "sidebar" : dom.sidebar_f,
"post" : post_db "post" : post_db
}, },
'about' : { 'wip' : {
"domain" : dom.config, "domain" : dom.config,
"footer" : dom.footer_about_f, "footer" : dom.wip_footer_f,
"metas" : dom.metas_f, "metas" : dom.wip_metas_f,
"navbar" : dom.navbar_f, "navbar" : dom.wip_navbar_f,
"sidebar" : dom.sidebar_f, "sidebar" : dom.wip_sidebar_f,
"post" : post_db "post" : post_wip,
}, "sitemap" : '%ssitemap.html'%dom.srv_wip,
'wip' : { "stats" : dom.wip_stats_f,
"domain" : dom.config, },
"footer" : dom.wip_footer_f, 'www' : {
"metas" : dom.wip_metas_f, "domain" : dom.config,
"navbar" : dom.wip_navbar_f, "footer" : dom.www_footer_f,
"sidebar" : dom.wip_sidebar_f, "metas" : dom.www_metas_f,
"post" : post_wip, "navbar" : dom.www_navbar_f,
"stats" : dom.wip_stats_f, "sidebar" : dom.www_sidebar_f,
}, "post" : post_www,
'www' : { "stats" : dom.www_stats_f,
"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,
"stats" : dom.www_stats_f,
},
}
# Read or edit file, according to legacy args.action # Read or edit file, according to legacy args.action
try: file = do[action][target]
file = do[action][target] if not file:
logs.out("28", '%s + %s'%(args.action, args.target), True)
if args.action in actions_read:
read_lines(file, True) if not file or not tyto.exists(file):
logs.out("1", file, True)
elif args.action in actions_edit:
curr_hash = tyto.get_filesum(file, True) # Except for show-about > Show post DB
tyto.edit_file(file) if args.action == "preview":
preview_wip(file)
return
elif args.action in actions_read:
read_lines(file, True)
except: elif args.action in actions_edit:
logs.out("28", '%s + %s'%(args.action, target), True) curr_hash = tyto.get_filesum(file, True)
tyto.edit_file(file)
# If edit article and hash changed, ask to check # If edit article and hash changed, ask to check
@ -188,16 +184,33 @@ def manage(target):
# Launch process for some changed file # Launch process for some changed file
#------------------------------------- #-------------------------------------
if file == post_src: 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") # Reload post DB (if edited article, and check it if ask "y")
importlib.reload(db) importlib.reload(db)
check.manage(post_src) check = subprocess.run(
[
'/usr/bin/tyto',
'check',
args.target
]
)
elif file == dom.sidebar_f: html.create_sidebar('wip') elif file == dom.sidebar_f: html.create_sidebar('wip')
elif file == dom.navbar_f: html.create_navbar('wip') elif file == dom.navbar_f: html.create_navbar('wip')
elif file == dom.metas_f: html.create_user_metas('wip') elif file == dom.metas_f: html.create_user_metas('wip')
#=====================================#
# Preview in browser wip page #
# Ensure xdg-open (useless in server) #
#-------------------------------------#
def preview_wip(file):
try:
xdg = subprocess.run(
[
'/usr/bin/xdg-open',
file,
],
)
except:
logs.out("28", "/usr/bin/xdg-open %s"%file, True)

View File

@ -23,19 +23,20 @@
# File: /var/lib/tyto/program/stats.py # File: /var/lib/tyto/program/stats.py
#---------------------------------------------------------------------- #----------------------------------------------------------------------
#------------ #-------------------------
# funny stats # Funny Stats Project
#------------ #-------------------------
# lines: # file lines : 226
# functions: # file comments : 38
# comments: # file functions: 4
#---------------------------------------------------------------------- # file program : 166
#--------------------------
#**********************************************************************
import os, importlib import os, importlib
import args, dom, logs, form, tyto, show, langs import args, dom, logs, form, tyto, show, langs
sti_articles = 0 sti_articles = 0
#=======================# #=======================#

View File

@ -23,84 +23,155 @@
# File: /var/lib/tyto/program/status.py # File: /var/lib/tyto/program/status.py
#---------------------------------------------------------------------- #----------------------------------------------------------------------
#------------ #-------------------------
# funny stats # Funny Stats Project
#------------ #-------------------------
# lines: # file lines : 241
# functions: # file comments : 51
# comments: # file functions: 3
#---------------------------------------------------------------------- # file program : 170
#--------------------------
#**********************************************************************
import args, dom, logs, tyto, form, db import os
import args, dom, logs
#=====================#
# Check domain status #
#---------------------#
def domain(): def domain():
if dom.hole: logs.out("13", '', True) if dom.hole:
elif args.action == 'new': return logs.out("13", '', True)
elif args.act_err: logs.out("11", args.action, True)
elif not dom.exists: logs.out("10", '', True)
elif dom.corrupt: logs.out("39", dom.shortname, True)
print("") # Only condition to not check domain status here
if dom.incomplete: logs.out("41", dom.shortname, False) if args.action == 'new' and \
elif dom.active: logs.out("42", dom.shortname, False) args.target == "domain":
elif not dom.active: logs.out("40", dom.shortname, False) return
# As subprocesses, avoid show domain status each time
if args.action in args.quicks:
return
# No backward in target # [action] not in list
if args.act_err:
logs.out("11", args.action, True)
# No domain found
if not dom.exists:
logs.out("10", '', True)
# Domain id corrupted
if dom.corrupt:
logs.out("39", dom.shortname, True)
# Domain is incomplete
if dom.incomplete:
logs.out("41", dom.shortname, False)
# Show unused values
for err_val in dom.err_val:
logs.out("16", err_val, True)
# Domain not activated
if not dom.active:
logs.out("40", dom.shortname, True)
# Domain is activated
if dom.active:
logs.out("42", dom.shortname, False)
# No backward in [target]
if "../" in args.target: if "../" in args.target:
logs.out("11", '"../"', True) logs.out("11", '"../"', True)
# Show unused values
for err_val in dom.err_val: #===========================#
logs.out("16", err_val, False) # Create unused directories #
#---------------------------#
import tyto
srv_show_wip = srv_show_www = local_show = dom_err = False
for value in dom.dom_values:
set_value = eval(str('dom.%s'%value))
# Missing directories (was created) # wip directories
for dir_new in dom.dir_new: if value.endswith('_d'):
logs.out("33", dir_new, False) if value.startswith("srv_wip"):
if not tyto.exists(set_value):
if not srv_show_wip:
print('\n │ [wip]')
srv_show_wip = True
try:
os.makedirs(set_value, exist_ok=True)
logs.out("33", set_value, False)
except:
logs.out("1", set_value, False)
dom_err = True
# www directories
elif value.startswith("srv_www"):
if not tyto.exists(set_value):
if not srv_show_www:
print('\n │ [www]')
srv_show_www = True
try:
os.makedirs(set_value, exist_ok=True)
logs.out("33", set_value, False)
except:
logs.out("1", set_value, False)
dom_err = True
# local directories
else:
if not tyto.exists(set_value):
if not local_show:
print('\n │ [local]')
local_show = True
try:
os.makedirs(set_value, exist_ok=True)
logs.out("33", set_value, False)
except:
logs.out("1", set_value, False)
dom_err = True
# Create missing modules files # Create missing modules files
create_files = \ import html
{
'navbar_f' : form.create_navbar, if not tyto.exists(dom.metas_f) or \
'sidebar_f' : form.create_sidebar, not tyto.exists(dom.wip_metas_f):
'metas_f' : form.create_metas, html.create_user_metas('new')
'footer_f' : form.create_footer,
'footer_about_f': form.create_footer_about if not tyto.exists(dom.navbar_f) or \
} not tyto.exists(dom.wip_navbar_f):
html.create_navbar('new')
if not tyto.exists(dom.sidebar_f) or \
not tyto.exists(dom.wip_sidebar_f):
html.create_sidebar('new')
if not tyto.exists(dom.footer_f) or \
not tyto.exists(dom.wip_footer_f):
html.create_user_footer('new')
for value in dom.file_mod:
create_files[value]('form')
for file_mods in dom.wip_html_mods:
if not tyto.exists(file_mods):
logs.out("1", file_mods, False)
#==============================# #==============================#
# On demand with status action # # On demand with status action #
#------------------------------# #------------------------------#
def check(target): def check(target):
import db
# target needed # target needed
if not target: if not target:
logs.out("5", '[target]', True) logs.out("5", '[target]', True)
# Domain statuses # Domain statuses
elif target == "domain": elif target == "domain":
conf_err = False # Check unused files in servers
logs.out("60", '', False)
if dom.dir_unu or dom.file_unu: check_domain_files("wip")
logs.out("60", '', False) check_domain_files("www")
for dir_unu in dom.dir_unu:
logs.out("1", dir_unu, False)
conf_err = True
for file_unu in dom.file_unu:
logs.out("24", file_unu, False)
if conf_err:
logs.out("31", '', True)
return return
# target is an article # target is an article
@ -147,4 +218,24 @@ def check(target):
# Article has NO DB # Article has NO DB
elif not db.exists: elif not db.exists:
logs.out("25", db.uri_file, True) logs.out("25", db.uri_file, True)
#=====================#
# Check servers files #
#---------------------#
def check_domain_files(srv):
import tyto
if srv == "www": template_files = dom.templates_files_www
elif srv == "wip": template_files = dom.templates_files_wip
else: return
dom_err = False
print(' │ [%s]'%srv)
for f in template_files:
if not tyto.exists(f):
dom_err = True
logs.out("1", f, False)
if not dom_err:
logs.out("28", 'tout va bien', False)

View File

@ -23,20 +23,21 @@
# File: /var/lib/tyto/program/tyto.py # File: /var/lib/tyto/program/tyto.py
#---------------------------------------------------------------------- #----------------------------------------------------------------------
#------------ #-------------------------
# funny stats # Funny Stats Project
#------------ #-------------------------
# lines: # file lines : 725
# functions: # file comments : 121
# comments: # file functions: 14
#---------------------------------------------------------------------- # file program : 522
#--------------------------
#**********************************************************************
import os, sys, re, subprocess, locale, base64, datetime, shutil import os, sys, re, subprocess, locale, base64, datetime, shutil
from hashlib import blake2b from hashlib import blake2b
import args, dom, logs, langs import args, dom, logs, langs
# :D # :D
Tyto = 'Tyto - Littérateur' Tyto = 'Tyto - Littérateur'
Tytogit = 'https://git.a-lec.org/echolib/tyto-litterateur' Tytogit = 'https://git.a-lec.org/echolib/tyto-litterateur'
@ -45,128 +46,210 @@ Tytoweb = 'https://tyto.echolib.re'
# Needed header tags # Needed header tags
needed_header_tags = \ needed_header_tags = \
( (
'title', 'title',
'about', 'about',
'author', 'author',
'tags', 'tags',
'date' 'date'
) )
# Optional header tags # Optional header tags
opt_header_tags = \ opt_header_tags = \
( (
'file', 'file',
'image', 'image',
'link', 'link',
'abbr', 'abbr',
'raw', 'raw',
'code', 'code',
'snpic' 'snpic'
) )
opt_tags_long_name = \ opt_tags_long_name = \
( (
'link', 'link',
'file' 'file'
) )
opt_tags_check_uri = \ opt_tags_check_uri = \
( (
'image', 'image',
'file', 'file',
'raw', 'raw',
'code' 'code'
) )
# Set all tags used in article's header # Set all tags used in article's header
headers = \ headers = \
( (
'title:', 'title:',
'about:', 'about:',
'author:', 'author:',
'tags:', 'tags:',
'date:', 'date:',
'link:', 'link:',
'image:', 'image:',
'file:', 'file:',
'abbr:', 'abbr:',
'code:', 'code:',
'raw:', 'raw:',
'#', '#',
'snpic:', 'snpic:',
) )
# Words and template Tags (paragraphs, lists, bold, strong...) # Words Tags (paragraphs, lists, bold, strong...)
# Used to check, and replace (wip) tags # Used to check, and replace (wip) tags
# As base64 is used, do NOT set marker: =_ _= # ! As base64 is used, do NOT set marker: =_ _=
# [5] = name for stats and log. # [5] = name for stats and log.
# [6] = Check content differently. 't' = startswith
#------------------------------------------------------------- #-------------------------------------------------------------
words_tags = [ icode_tags = \
('>_', '_<', (
'<a class="anchor_link" href="#%s">', '{_', '_}',
'</a>', 'anchors', 'w' '<code class="icode">', '</code>',
), 'icodes',
('*_', '_*', '<strong class="strong">', '</strong>', 'strongs', 'w'), '\\{_', '\\_}'
('+_', '_+', '<b class="bold">', '</b>', 'bolds', 'w'), )
(';_', '_;', '<em class="em">', '</em>', 'emphasis', 'w'),
(':_', '_:', '<i class="italic">', '</i>', 'italics', 'w'), strong_tags = \
('~_', '_~', '<del class="del">', '</del>', 'dels', 'w'), (
('._', '_.', '<u class="underline">', '</u>', 'underlines', 'w'), '*_', '_*',
('[_', '_]', '<cite class="cite">', '</cite>', 'cites', 'w'), '<strong class="%s">'%dom.css, '</strong>',
('%_', '_%', '<span class="custom">', '</span>', 'customs', 'w'), 'strongs',
('{_', '_}', '<code class="icode">', '</code>', 'codes', 'w'), '\\*_', '\\_*',
] '-S1-', '-S2-'
)
bold_tags = \
(
'+_', '_+',
'<b class="%s">'%dom.css, '</b>',
'bolds',
'\\+_', '\\_+',
'-B1-', '-B2-'
)
em_tags = \
(
';_', '_;',
'<em class="%s">'%dom.css, '</em>',
'emphasis',
'\\;_', '\\_;',
'-EM1-', '-EM2-'
)
i_tags = \
(
':_', '_:',
'<i class="%s">'%dom.css, '</i>',
'italics',
'\\:_', '\\_:',
'-I1-', '-I2-'
)
u_tags = \
(
'._', '_.', '<u class="%s">'%dom.css,
'</u>',
'underlines',
'\\._', '\\_.',
'-U1-', '-U2-'
)
del_tags = \
(
'~_', '_~',
'<del class="%s">'%dom.css, '</del>',
'dels',
'\\~_', '\\_~',
'-DE1-', '-DE2-'
)
cite_tags = \
(
'[_', '_]',
'<cite class="%s">'%dom.css, '</cite>',
'cites',
'\\[_', '\\_]',
'-CI1-', '-CI2-'
)
custom1_tags = \
(
'%_', '_%',
'<span class="custom">', '</span>',
'customs',
'\\%_', '\\_%',
'-CU1-', '-CU2-'
)
markers_tags = \
[
strong_tags,
bold_tags,
em_tags,
i_tags,
u_tags,
del_tags,
cite_tags,
custom1_tags,
]
# At begining line, create block contents # At begining line, create block contents
block_tags = \ block_tags = [
[ ('((', '))', '<p class="%s">', '</p>', 'paragraphs'),
('((', '))', '<p class="%s">', '</p>', 'paragraphs'), ('[[', ']]', '[[', ']]', 'quotes'),
('[[', ']]', '[[', ']]', 'quotes'), ('{{', '}}', '{{', '}}', 'bcodes'),
('{{', '}}', '{{', '}}', 'bcodes'), ('-(', '-)', '-(', '-)', 'lists'),
('-(', '-)', '-(', '-)', 'lists'), ('<<', '>>', '<div class="%s">', '</div>', 'div'),
('<<', '>>', '<div class="%s">', '</div>', 'div'),
] ]
# Anchor tags
anchor_tags = \
(
'>_', '_<',
'<a class="anchor_link" href="#%s">', '</a>',
'anchors'
)
# Tags that do not need to be paired # Tags that do not need to be paired
#----------------------------------- #-----------------------------------
single_tags = [ single_tags = [
('|', '<br class="%s" />'), # New Line ('|', '<br class="%s">'), # New Line
('->', '<a class="anchor_target" id="%s"></a>'), # Anchors ('->', '<a class="anchor_target" id="%s"></a>'), # Anchors
] ]
# When counting words, do no count line starting with: # When counting words, do no count line starting with:
nolinewords = \ nolinewords = \
( (
block_tags[0][0], block_tags[0][1], # paragraphs block_tags[0][0], block_tags[0][1], # paragraphs
block_tags[1][0], block_tags[1][1], # quotes block_tags[1][0], block_tags[1][1], # quotes
block_tags[2][0], block_tags[2][1], # bcodes block_tags[2][0], block_tags[2][1], # bcodes
block_tags[3][0], block_tags[3][1], # lists block_tags[3][0], block_tags[3][1], # lists
single_tags[0][0], single_tags[1][0], # New line, anchor single_tags[0][0], single_tags[1][0], # New line, anchor
'_%s:'%opt_header_tags[1], '_%s:'%opt_header_tags[4], # _image:, _raw: '_%s:'%opt_header_tags[1], '_%s:'%opt_header_tags[4], # _image:, _raw:
'_%s:'%opt_header_tags[5] # _code '_%s:'%opt_header_tags[5] # _code
) )
# warning symbols (Check if paired) # warning symbols (Check if paired)
#---------------------------------- #----------------------------------
tpl_tags = [ tpl_tags = [
('(', ')'), ('(', ')'),
('[', ']'), ('[', ']'),
('{', '}'), ('{', '}'),
('«', '»'), ('«', '»'),
] ]
# When including HTML in article, check some paired tags # When including HTML in article, check some paired tags
#------------------------------------------------------- #-------------------------------------------------------
leg_html_tags = [ leg_html_tags = [
('<!--', '-->'), ('<!--', '-->'),
('<div', '</div>'), ('<div', '</div>'),
('<ul', '</ul>'), ('<ul', '</ul>'),
('<li', '</li>'), ('<li', '</li>'),
('<p', '</p>'), ('<p', '</p>'),
('<span','</span>'), ('<span','</span>'),
] ]
@ -176,35 +259,68 @@ markers_lists = ('+', '=', ' ', '#')
# Tags used for titles # Tags used for titles
#--------------------- #---------------------
titles_tags = ('#1 ', '#2 ', '#3 ', '#4 ', '#5 ', '#6 ') titles_user = ('#1', '#2', '#3', '#4', '#5')
titles_html = ('<h1', '<h2', '<h3', '<h4', '<h5', '<h6')
titles_tags = [
("", "",),
('#1 ', '<h2 class="title_2">%s</h2>'),
('#2 ', '<h3 class="title_3">%s</h3>'),
('#3 ', '<h4 class="title_5">%s</h4>'),
('#4 ', '<h5 class="title_6">%s</h5>'),
('#5 ', '<h6 class="title_6">%s</h6>')
]
# Tags for quote # Tags for quote
quote_tags = [ quote_tags = [
('_cite:', 'author'), ('_cite:', 'author'),
('_date:', 'date'), ('_date:', 'date'),
('_link:', 'link'), ('_link:', 'link'),
('_book:', 'book'), ('_book:', 'book'),
('_lang:', 'lang') ('_lang:', 'lang')
] ]
# Tags to check in header in content _TAG # Tags to check in header in content _TAG
head_tags = ("image:", "raw:", "code;") head_tags = ("image:", "raw:", "code;")
# For static modules
tags_html_mods = \
{
dom.wip_navbar_f : '<!--# include virtual="/template/navbar.html"-->',
dom.wip_sidebar_f : '<!--# include virtual="/template/sidebar.html"-->',
dom.wip_metas_f : '<!--# include virtual="/template/metas.html"-->',
dom.wip_footer_f : '<!--# include virtual="/template/footer.html"-->'
}
# Valid characters for some datas # Valid characters for some datas
chrs_invalid = \ chrs_invalid = \
set('{}[]_()+*=/:%~´') set('{}[]_()+*=/:%~´')
new_article = """%s
# Tyto - Litterateur (tyto new %s)
title:
about:
author: %s
tags:
date: %s
#abbr: TYTO
Le générateur de sites web Libre
Tyto - Littérateur
# Use this image for social networks
#snpic: Pic-1
#image: Pic-1
URI
Texte-alternatif
#link: lien 1
URI/URL
Text-alternatif
-----
#_image:Pic-1 c=title_class
#1
((
))
"""
# Stats for icodes, bcodes, quotes # Stats for icodes, bcodes, quotes
nbr_icodes = 0 nbr_icodes = 0
@ -238,9 +354,6 @@ def convert_altname(altname):
# False = URI # # False = URI #
#-----------------------# #-----------------------#
def get_filesum(path, src): def get_filesum(path, src):
#if not src and not exists(path):
# logs.out("1", path, True)
file_sum = blake2b(digest_size=4) file_sum = blake2b(digest_size=4)
if src: file_sum.update(open(path, 'rb').read()) if src: file_sum.update(open(path, 'rb').read())
@ -312,6 +425,29 @@ def get_css(line):
return css return css
#==============================#
# Replace escaped markers #
# check: with "" #
# wip: with altternate #
# reverse: True/False #
#------------------------------#
def protect_escaped(post_bottom, reverse):
for m1, m2, h1, h2, n, e1, e2, r1, r2 in markers_tags:
# In check mode, No need to keep escaped markers
if args.action == "check":
r1 = r2 = ''
if reverse:
post_bottom = post_bottom.replace(r1, m1)
post_bottom = post_bottom.replace(r2, m2)
else:
post_bottom = post_bottom.replace(e1, r1)
post_bottom = post_bottom.replace(e2, r2)
return post_bottom
#=============================================# #=============================================#
# First check process to protect contents # # First check process to protect contents #
# Protect block-Codes, quotes # # Protect block-Codes, quotes #
@ -377,7 +513,7 @@ def protect_bcodes_quotes(process, post_bottom):
if not in_quote and not in_bcode: if not in_quote and not in_bcode:
if not line: if not line:
continue continue
elif line.startswith('#') and not line.startswith(titles_tags): elif line.startswith('#') and not line.startswith(titles_user):
continue continue
# bcode convertion to base64 # bcode convertion to base64
@ -386,11 +522,14 @@ def protect_bcodes_quotes(process, post_bottom):
if not bcode: bcode = line if not bcode: bcode = line
else: bcode = '%s\n%s'%(bcode, line) else: bcode = '%s\n%s'%(bcode, line)
line = '' line = ''
continue
elif in_quote: elif in_quote:
# Convert lines to b64 # Convert lines to b64
if not quote: quote = line if not quote: quote = line
else: quote = '%s\n%s'%(quote, line) else: quote = '%s\n%s'%(quote, line)
line = '' line = ''
continue
# Set new content # Set new content
@ -407,56 +546,70 @@ def protect_bcodes_quotes(process, post_bottom):
if close_quote: quote = b64_quote = '' if close_quote: quote = b64_quote = ''
#=======================# #=======================================#
# Protec iCodes # # Protec iCodes #
# Used in check and wip # # Used in check and wip #
#-----------------------~ # Methode: iterate (c)haracter in lines #
# check: remove icdoe #
# wip: convert to b64 #
#---------------------------------------#
def protect_icodes(post_bottom): def protect_icodes(post_bottom):
global protect_article
global nbr_icodes global nbr_icodes
protect_article = post_bottom
in_icode = False
src_code = rep_code = ''
# Get only lines that contains code # Get only lines that contains code
in_icode = ok_icode = go_icode = False
for ln, line in enumerate(post_bottom.rsplit('\n')): for ln, line in enumerate(post_bottom.rsplit('\n')):
if not words_tags[9][0] in line: continue if not icode_tags[0] in line or \
not icode_tags[1] in line:
# Iterate (c)haracter in line continue
code = ""
for i, c in enumerate(line): for i, c in enumerate(line):
c_b = c_bb = c_a = "" if c == "_":
if c == '_': try:
c_b = line[i-1] # before # {_
c_bb = line[i-2] # before, before if line[i-1] == icode_tags[0][0] and line[i-2] != "\\":
c_a = line[i+1] # after in_icode = True
ok_icode = False
# incode if #go_icode = True
if c_b == '{' and not c_bb == '\\': continue
in_icode = True # _}
nbr_icodes += 1 elif line[i+1] == icode_tags[1][1] and line[i-2] != "\\":
code = words_tags[9][2] in_icode = False
ok_icode = True
go_icode = False
except:
continue continue
# No more in code if
if c_a == '}' and not c_b == '\\':
in_icode = False
src_code = convert_altname(src_code)
code = '%s%s%s'%(code, src_code, words_tags[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: if in_icode:
rep_code = '%s%s'%(rep_code, c) ok_icode = False
if c == '\\': continue code = "%s%s"%(code, c)
src_code = '%s%s'%(src_code, c)
# End icode
if ok_icode:
nbr_icodes += 1
tyto_code = "%s%s%s"%(icode_tags[0], code, icode_tags[1])
if args.action == "check":
post_bottom = \
post_bottom = post_bottom.replace(tyto_code , '')
elif args.action == "wip":
code = convert_altname(code) # HTML sympbols
html_code = "%s%s%s"%(
icode_tags[2], code, icode_tags[3])
b64_code = b64('Encode', html_code, 'I64.', '.I64')
post_bottom = post_bottom.replace(tyto_code, b64_code)
# Reset for next
code = tyto_code = html_code = b64_code = ""
ok_icode = False
post_bottom = post_bottom.replace("\\%s"%icode_tags[0], icode_tags[0])
post_bottom = post_bottom.replace("\\%s"%icode_tags[1], icode_tags[1])
return post_bottom
#=====================================# #=====================================#

View File

@ -26,19 +26,19 @@
# File: /var/lib/tyto/program/wip.py # File: /var/lib/tyto/program/wip.py
#---------------------------------------------------------------------- #----------------------------------------------------------------------
#------------ #-------------------------
# funny stats # Funny Stats Project
#------------ #-------------------------
# lines: # file lines : 1110
# functions: # file comments : 167
# comments: # file functions: 26
#---------------------------------------------------------------------- # file program : 860
#--------------------------
#**********************************************************************
import os, re, sys, locale, shutil, importlib, time import os, re, sys, locale, shutil, importlib, time, subprocess
from pathlib import Path from pathlib import Path
import args, logs, langs, dom, db, tyto, html, form, stats import args, logs, langs, dom, db, tyto, html, form, stats, check
#=========================================# #=========================================#
@ -49,11 +49,35 @@ def manage(target):
global post_db, hash_post, target_all global post_db, hash_post, target_all
# wip_article(db.post_src) ; return # Force wip without checking
if not target: if not target:
logs.out("5", '[target]', True) logs.out("5", '[target]', True)
# option --force to check and wip processes
if args.action == 'force-wip':
if args.target in args.pass_targets:
logs.out("28", "%s + %s"%(args.target, args.option), True)
chk = subprocess.run(
[
'/usr/bin/tyto',
'check',
target,
'--force'
],
)
print()
wip = subprocess.run(
[
'/usr/bin/tyto',
'wip',
target,
],
)
return
# Modules and multi-articles
elif target in args.pass_targets: elif target in args.pass_targets:
do = { do = {
'updated' : wip_all, 'updated' : wip_all,
@ -144,7 +168,8 @@ def wip_article(target):
# Convert file to strings # Convert file to strings
file_to_string(target) file_to_string(target)
print('\n ├ [%s] > %s'%(db.title, db.post_src)) #print(' │\n')
db.show_title()
global post_header global post_header
global post_bottom global post_bottom
@ -156,11 +181,13 @@ def wip_article(target):
# Protect inline-codes # Protect inline-codes
if db.icodes > 0: if db.icodes > 0:
tyto.protect_icodes(post_bottom) post_bottom = tyto.protect_icodes(post_bottom)
post_bottom = tyto.protect_article
# Replace escaped markers
post_bottom = tyto.protect_escaped(post_bottom, False)
# Convert contents from modules # Convert contents from modules
wip_clean_lines() # Remove comments and empty lines
wip_images() # Images_%i from headers in DB wip_images() # Images_%i from headers in DB
wip_single_tags() # br /, anchors wip_single_tags() # br /, anchors
wip_words_tags() # Paragraphs, strongs, italics wip_words_tags() # Paragraphs, strongs, italics
@ -169,6 +196,9 @@ def wip_article(target):
wip_titles() # Convert #N, remove empty line, add divs wip_titles() # Convert #N, remove empty line, add divs
wip_lists() # convert ul/ol lists wip_lists() # convert ul/ol lists
wip_quotes() # Quotes. Decode base64 Q64 and convert to HTML wip_quotes() # Quotes. Decode base64 Q64 and convert to HTML
# Replace escaped markers
post_bottom = tyto.protect_escaped(post_bottom, True)
wip_icodes() # inline_codes. Decode base64 icode and replace wip_icodes() # inline_codes. Decode base64 icode and replace
wip_filecode(target) # Read file and convert to HTML wip_filecode(target) # Read file and convert to HTML
wip_bcodes() # Block-codes. Decode B64 and convert to HTML wip_bcodes() # Block-codes. Decode B64 and convert to HTML
@ -223,6 +253,31 @@ def file_to_string(post_file):
else: post_header = '%s\n%s'%(post_header, line) else: post_header = '%s\n%s'%(post_header, line)
#=================================#
# Remove comments and empty lines #
#---------------------------------#
def wip_clean_lines():
global post_bottom
# Remove comments
if db.comments > 0:
for line in post_bottom.rsplit('\n'):
if line.startswith('#') and not line.startswith(tyto.titles_user):
replace_in_post(line, "")
# Remove empty lines
post_temp = ''
for line in post_bottom.rsplit('\n'):
if not line: continue
if not post_temp: post_temp = line
else: post_temp = "%s\n%s"%(post_temp, line)
post_bottom = post_temp
#=========================================# #=========================================#
# Create real static page, by # # Create real static page, by #
# including modules contents in HTML page # # including modules contents in HTML page #
@ -240,7 +295,7 @@ def wip_static():
wip_module = open(module, 'r').read() wip_module = open(module, 'r').read()
wip_html_post = \ wip_html_post = \
wip_html_post.replace( wip_html_post.replace(
tyto.tags_html_mods[module], html.tags_html_mods[module],
wip_module wip_module
) )
tyto.set_file(db.post_wip, "New", wip_html_post) tyto.set_file(db.post_wip, "New", wip_html_post)
@ -255,7 +310,9 @@ def wip_static():
#---------------------------------------------------------------# #---------------------------------------------------------------#
def replace_in_post(src, html): def replace_in_post(src, html):
global post_bottom global post_bottom
post_bottom = post_bottom.replace(src, html)
if src in post_bottom:
post_bottom = post_bottom.replace(src, html)
#=============================# #=============================#
@ -282,21 +339,7 @@ def wip_single_tags():
#----------------------------------# #----------------------------------#
def wip_words_tags(): def wip_words_tags():
# Strongs, italics... # Strongs, italics...
# (Stop after 8 tags) for tag in tyto.markers_tags:
# For anchor (0), must do it differently
m = 0
for tag in tyto.words_tags:
if m == 0:
m += 1
# Close anchor (generic)
replace_in_post(tag[1],
tag[3]
)
continue
elif m > 8:
break
# Open tag # Open tag
replace_in_post(tag[0], replace_in_post(tag[0],
tag[2] tag[2]
@ -305,7 +348,6 @@ def wip_words_tags():
replace_in_post(tag[1], replace_in_post(tag[1],
tag[3] tag[3]
) )
m += 1
for ln, line in enumerate(post_bottom.rsplit('\n')): for ln, line in enumerate(post_bottom.rsplit('\n')):
@ -339,46 +381,83 @@ def wip_words_tags():
anchor_links = re.findall(r'>_(.+?):', line) anchor_links = re.findall(r'>_(.+?):', line)
for item in anchor_links: for item in anchor_links:
anchor_id = '%s%s:'%(tyto.words_tags[0][0], item) anchor_id = '%s%s:'%(tyto.anchor_tags[0], item)
replace_in_post(anchor_id, replace_in_post(anchor_id,
tyto.words_tags[0][2]%item tyto.anchor_tags[2]%item
) )
replace_in_post(tyto.anchor_tags[1],
tyto.anchor_tags[3]
)
#========================# #============================#
# Convert links set inDB # # from wip_links #
# - file_%i # # Get arrays, in DB #
# - link_%i # # sort all links by length #
# from marker to HTML # # (avoic abcd to target abc) #
#------------------------# # return db.NAME_i array #
#----------------------------#
def wip_return_link_nbr(marker, nbr):
items = [()]
links = (())
# Get length link and i (from all arrays ) in new array
for i in range(1, nbr + 1):
item = 'db.%s_%s'%(marker, i)
len_link = len(eval(item)[1])
items = items + [(len_link, i),]
# Sort length by bigger in new array
for i in sorted(items,reverse=True):
try: links = links + ((i[1]),)
except: pass
return links
#=========================#
# Convert links set in DB #
# - file_%i #
# - link_%i #
#-------------------------#
def wip_links(): def wip_links():
if db.uniq_files == 0 and db.uniq_links == 0: return if db.uniq_files == 0 and db.uniq_links == 0: return
link_tb = 'target="_blank"' link_tb = 'target="_blank"'
link_ts = 'target="_self"' link_ts = 'target="_self"'
link_html = '<a class="%s" href="%s" title="%s" %s>%s</a>' link_html = '<a class="%s" href="%s" title="%s" %s>%s</a>'
# ! Doing link files, first, becase of similar marker # ! Doing link files, first, becase of similar marker
#---------------------------------------------------- #----------------------------------------------------
if db.uniq_files > 0: if db.uniq_files > 0:
for i in range(1, db.uniq_files + 1):
link = 'db.file_%s'%i links = wip_return_link_nbr("file", db.uniq_files)
link_css = "link_file" for i in links:
link_name = eval(link)[0][2:] if not i:
link_anc = eval(link)[1] return
link_title = eval(link)[2]
link_set = link_html%( flink = 'db.file_%s'%i
link_css, link_anc, link_title, "%s", link_name flink_css = "link_file"
flink_name = eval(flink)[0][2:]
flink_anc = eval(flink)[1]
flink_title = eval(flink)[2]
flink_set = link_html%(
flink_css, flink_anc, flink_title, "%s", flink_name
) )
replace_in_post(eval(link)[0]+'+', link_set%link_tb) replace_in_post(eval(flink)[0]+'+', flink_set%link_tb)
replace_in_post(eval(link)[0], link_set%link_ts) replace_in_post(eval(flink)[0], flink_set%link_ts)
# Convert simple links # Convert simple links
#--------------------- #---------------------
if db.uniq_links > 0: if db.uniq_links > 0:
for i in range(1, db.uniq_links + 1):
links = wip_return_link_nbr("link", db.uniq_links)
for i in links:
if not i:
return
link = 'db.link_%s'%i link = 'db.link_%s'%i
link_css = "link" link_css = "link"
link_name = eval(link)[0][1:] link_name = eval(link)[0][1:]
@ -425,6 +504,7 @@ def get_wh_image(value):
if not sizes[0][1]: return('%spx'%value) if not sizes[0][1]: return('%spx'%value)
else: return(value) else: return(value)
#=================================# #=================================#
# Find all _image, get parameters # # Find all _image, get parameters #
# Convert _images:%name to HTML # # Convert _images:%name to HTML #
@ -483,7 +563,7 @@ def wip_images():
else: else:
style = '' style = ''
# set <img /> from parameter # set <img> from parameter
image_target = eval(image)[1] image_target = eval(image)[1]
image_target = db.sub_uri + image_target[1:] image_target = db.sub_uri + image_target[1:]
image_src = image_show%( image_src = image_show%(
@ -517,6 +597,7 @@ def quote_params(qline):
globals()[tag[1]] = qline.rsplit('%s '%tag[0])[1].lstrip() globals()[tag[1]] = qline.rsplit('%s '%tag[0])[1].lstrip()
return(True) return(True)
#==========================# #==========================#
# Convert quote in article # # Convert quote in article #
#--------------------------# #--------------------------#
@ -720,75 +801,69 @@ def wip_bcodes():
#========================================# #========================================#
# Convert titles to HTML # # Convert titles to HTML #
# Check between titles to set div or not # # #1 = <h3>, #2 = <h4>... #
#----------------------------------------# #----------------------------------------#
def wip_titles(): def wip_titles():
if db.titles == 0: return if db.titles == 0: return
global post_bottom global post_bottom
article_temp = post_bottom for line in post_bottom.rsplit('\n'):
article_tmp2 = '' # Construct article, without empty lines if line.startswith(tyto.titles_user):
tx = line[1]
for line in post_bottom.rsplit('\n'): title_name = line[2: len(line)].lstrip()
if line.startswith('#'): title_html = tyto.titles_tags[int(tx)][1]%title_name
hx = line[1] replace_in_post(line, title_html)
title_cont = line[2: len(line)].lstrip()
title_html = '<h%s class="title_%s">%s</h%s>'%(
hx, hx, title_cont, hx
)
article_temp = article_temp.replace(line, title_html)
# Remove useless empty lines from article wip_titles_div()
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
#======================================#
# Create div between titles if content #
#--------------------------------------#
def wip_titles_div():
global post_bottom
# Add div after title if needed article_tmp = ''
for ln, line in enumerate(article_tmp2.rsplit('\n')):
if line.startswith('<h'):
try: article_tmp2.rsplit('\n')[ln + 1]
except: continue
if article_tmp2.rsplit('\n')[ln + 1].startswith('<h'):
continue
else:
article_temp = \
article_temp.replace(line,
'%s\n<div class="contents">'%(line)
)
continue
else:
continue
# Close div before title if needed div_close = False
article_tmp2 = article_temp for ln, line in enumerate(post_bottom.rsplit('\n')):
indiv = False # Remove empty lines
for ln, line in enumerate(article_tmp2.rsplit('\n')): if not line: continue
try: article_tmp2.rsplit('\n')[ln + 1]
except: continue
if line.startswith('<h') and indiv: div_open = False
article_temp = \ # Title <hX> found
article_temp.replace(line, if line.startswith(tyto.titles_html):
'</div>\n%s'%line hx = line[2]
)
indiv = False # Div need to be close vefore title
if div_close:
if article_tmp2.rsplit('\n')[ln + 1].startswith('<div'): line = '</div>\n%s'%line
indiv = True div_close = False
continue
# Has content after, open div
try:
post_bottom.rsplit('\n')[ln + 1]
div_open = True
except:
continue
# New div
if div_open:
line = '%s\n<div class="contents contents_%s">'%(line, hx)
div_close = True
# Save new article with div and no empty lines
#---------------------------------------------
if not article_tmp: article_tmp = line
else: article_tmp = "%s\n%s"%(article_tmp, line)
if indiv: # Close last div (if any)
article_temp = '%s\n</div>'%article_temp if div_close:
article_tmp = "%s\n</div>"%(article_tmp)
# Replace article with new contents post_bottom = article_tmp
post_bottom = article_temp
#==============================================# #==============================================#
# Convert raw file to HTML with <pre> + <code> # # Convert raw file to HTML with <pre> + <code> #
@ -951,8 +1026,10 @@ def wip_fileraws(target):
for i in range(1, db.uniq_raws + 1): for i in range(1, db.uniq_raws + 1):
raw = 'db.raw_%s'%i raw = 'db.raw_%s'%i
raw_file = open('%s%s'%(dom.articles_d, eval(raw)[1])).read() raw_file = open('%s%s'%(dom.articles_d, eval(raw)[1])).read()
raw_alt = ""
if eval(raw)[2]: if eval(raw)[2]:
raw_alt = ' # %s'%eval(raw)[2] raw_alt = ' # %s'%eval(raw)[2]
raw_inc = '<!--Tyto_Include file%s-->'%raw_alt raw_inc = '<!--Tyto_Include file%s-->'%raw_alt
for line in raw_file.rsplit('\n'): for line in raw_file.rsplit('\n'):

View File

@ -11,44 +11,48 @@
#********************************************************************** #**********************************************************************
# Generic # Generic
sidebar = 'Sidebar' sidebar = 'Sidebar'
navbar = 'Navbar' navbar = 'Navbar'
meta_t = '<meta> tag' meta_t = '<meta> tag'
time_t = '<time> tag' time_t = '<time> tag'
metas = 'Metas Tags' metas = 'Metas Tags'
footer = 'Footer' footer = 'Footer'
line = "Ligne" line = "Ligne"
no_up = "not updated"
no_up = "not updated" ntd = "Nothing to do"
ntd = "Nothing to do" all_ok = "All is OK"
all_ok = "All is OK" nonewpost = "No new article"
unused_r = "Unused ressource" unused_r = "Unused ressource"
unused_c = "Unused database value" unused_c = "Unused database value"
db_inv = "Corrupted article's database" db_inv = "Corrupted article's database"
err_arg = "Argument error" err_arg = "Argument error"
no_arg = "Unused argument" no_arg = "Unused argument"
no_fidi = "Black Hole: no file or directory here" no_fidi = "Black Hole: no file or directory here"
dom_ina = "Inactive domain" dom_ina = "Inactive domain"
dom_inc = "Incomplete domain" dom_inc = "Incomplete domain"
dom_act = "Active domain" dom_act = "Active domain"
dom_cor = "Corrupted domain" dom_cor = "Corrupted domain"
data_inc = "Incomplete data" data_inc = "Incomplete data"
data_inv = "Invalid data" data_inv = "Invalid data"
dom_no = "No domain found" dom_no = "No domain found"
file_c = "File created" file_c = "File created"
file_n = "File changed" file_n = "File changed"
file_e = "File exists" file_e = "File exists"
dir_c = "Directory created" dir_c = "Directory created"
dir_e = "Directory exists" dir_e = "Directory exists"
post_exists = "Ab article already exists"
# chk # chk
shebang_r= 'Remove shebang'
nycheck = "Article not yet checked" nycheck = "Article not yet checked"
was_chk = "Article was 'check'" was_chk = "Article was 'check'"
st_chk_o = "Old 'check' status" st_chk_o = "Old 'check' status"
post_inc = "Unused in article" post_inc = "Unused in article"
post_inv = "Article not valid" post_inv = "Article not valid"
post_val = "Article is valid" post_val = "Article is valid"
title_no = "Empty title"
unused_p = "Empty article"
# wip # wip
nywip = "Article not yet wip" nywip = "Article not yet wip"
@ -71,7 +75,6 @@ post_chg = "Article changed: 'check' it first"
sep_inv = "Unused separator in article" sep_inv = "Unused separator in article"
unused_v = "Unused value in article" unused_v = "Unused value in article"
unused_t = "Unused value in header" unused_t = "Unused value in header"
unused_p = "Empty article"
mark_np = "Not paired marks" mark_np = "Not paired marks"
symb_np = "Not paired symbols" symb_np = "Not paired symbols"
snpic_d = "Using default snpic. Not found" snpic_d = "Using default snpic. Not found"

View File

@ -11,53 +11,55 @@
#********************************************************************** #**********************************************************************
# Generique # Generique
sidebar = 'Barre Latérale' sidebar = 'Barre Latérale'
navbar = 'Barre de navigation' navbar = 'Barre de navigation'
meta_t = 'Balise <meta>' meta_t = 'Balise <meta>'
time_t = 'Balise <time>' time_t = 'Balise <time>'
metas = 'Balises Metas' metas = 'Balises Metas'
footer = "Pied de Page" footer = "Pied de Page"
line = "Line" line = "Line"
no_up = "non mise à jour"
no_up = "non mise à jour" ntd = "Rien à faire"
ntd = "Rien à faire" all_ok = "Tout va bien"
all_ok = "Tout va bien" nonewpost = "Rien de nouveau"
unused_r = "Ressource manquante" unused_r = "Ressource manquante"
unused_c = "Valeur de la base de donnée manquante" unused_c = "Valeur de la base de donnée manquante"
db_inv = "Base de donnée de l'article corrompue" db_inv = "Base de donnée de l'article corrompue"
err_arg = "Erreur d'argument" err_arg = "Erreur d'argument"
no_arg = "Argument manquant" no_arg = "Argument manquant"
no_fidi = "Trou Noir: aucun fichier ou dossier ici" no_fidi = "Trou Noir: aucun fichier ou dossier ici"
dom_ina = "Domaine inactif" dom_ina = "Domaine inactif"
dom_inc = "Domaine incomplet" dom_inc = "Domaine incomplet"
dom_act = "Domaine actif" dom_act = "Domaine actif"
dom_cor = "Domaine corrompu" dom_cor = "Domaine corrompu"
data_inc = "Donnée incomplète" data_inc = "Donnée incomplète"
data_inv = "Donnée invalide" data_inv = "Donnée invalide"
dom_no = "Aucun domaine trouvé" dom_no = "Aucun domaine trouvé"
file_c = "Fichier créé" file_c = "Fichier créé"
file_n = "Fichier modifié" file_n = "Fichier modifié"
file_e = "Fichier présent" file_e = "Fichier présent"
dir_c = "Dossier créé" dir_c = "Dossier créé"
dir_e = "Dossier présent" dir_e = "Dossier présent"
post_exists = "Un article existe déjà"
# chk # chk
shebang_r= 'Enlever le shebang'
nycheck = "Article pas encore 'check'" nycheck = "Article pas encore 'check'"
was_chk = "Article déjà vérifié" was_chk = "Article déjà vérifié"
st_chk_o = "Statut 'check' Ancien" st_chk_o = "Statut 'check' Ancien"
post_inc = "Donnée manquante dans l'article" post_inc = "Donnée manquante dans l'article"
post_inv = "Article non valide" post_inv = "Article non valide"
post_val = "Article valide" post_val = "Article valide"
title_no = "Titre vide"
unused_p = "Article vide"
# Wip # Wip
nywip = "Article pas encore 'wip'" nywip = "Article pas encore 'wip'"
was_wip = "Article déjà 'wip'" was_wip = "Article déjà 'wip'"
# www # www
was_pub = "Article déjà publié" was_pub = "Article déjà publié"
# Misc # Misc
post_nfd = "Page non présente" post_nfd = "Page non présente"
post_yfd = "Page présente" post_yfd = "Page présente"
@ -72,7 +74,6 @@ post_chg = "Article modifié : commencer par 'check'"
sep_inv = "Séparateur manquant dans l'article" sep_inv = "Séparateur manquant dans l'article"
unused_v = "Valeur manquante dans l'article" unused_v = "Valeur manquante dans l'article"
unused_t = "Valeur manquante dans l'entête" unused_t = "Valeur manquante dans l'entête"
unused_p = "L'article est vide"
mark_np = "Marqueurs non jumelés" mark_np = "Marqueurs non jumelés"
symb_np = "Symboles non jumelés" symb_np = "Symboles non jumelés"
snpic_d = "snpic utilisé par défaut. Manquant" snpic_d = "snpic utilisé par défaut. Manquant"

View File

@ -18,9 +18,12 @@
# - "\n" # - "\n"
# - "+ \" # - "+ \"
# Keep array ! ('','',)
yes = ("y", "yes",)
# Generic # Generic
article = "Article" article = "Article"
links = "links"
sidebar = 'Sidebar' sidebar = 'Sidebar'
navbar = 'Navbar' navbar = 'Navbar'
metas = 'Metas Tags' metas = 'Metas Tags'
@ -73,6 +76,7 @@ generator = "Generator"
# Check # Check
check_a = "Check again this article" check_a = "Check again this article"
post_chg = "Article was edited. Check it" post_chg = "Article was edited. Check it"
new_post = "Create article"
# Wip # Wip
wip_new = "Create a new HTML page in 'wip' server again" wip_new = "Create a new HTML page in 'wip' server again"
@ -88,7 +92,9 @@ rss_c = "Create ATOM/RSS feed"
# Other # Other
uptpl = "Update directory" uptpl = "Update directory"
stats_f = "Articles: %s (%s words)" stats_f = "Articles: %s (%s words)"
reg_domains = 'Registred domains' reg_domains = "Registred domains"
sitemap_gen = "Sitemap generated by"
sitemap_t = "Sitemap"
# Form # Form
#---------------------------------------------------------------------- #----------------------------------------------------------------------
@ -114,36 +120,38 @@ form_inv = ' │\n' + \
' └─────────────────────────────────────┘' ' └─────────────────────────────────────┘'
form_opt = "[Optional]" form_opt = "[Optional]"
form_url = "URL to official website?" form_url = "URL to official website"
form_wip = "URL to 'wip' website?" form_wip = "URL to 'wip' website"
form_db_new = "Created new database" form_db_new = "Created new database"
form_trlog = "[2 char.] Logs language?" form_trlog = "[2 char.] Logs language"
form_srv = "Local server directory?" form_srv = "Local server directory"
form_logo = "Logo filename?" form_logo = "Logo filename"
form_rss_f = "Atom/RSS filename?" form_fav_f = "Favicon filename !(.png)"
form_rss_i = "Atom/RSS articles' number?" form_css_f = "CSS filename"
form_title = "Website title?" form_rss_f = "Atom/RSS filename"
form_date = "Domain creation year?" form_rss_i = "Atom/RSS articles' number"
form_about = "Domain Description?" form_title = "Website title"
form_mail = "Webmaster's mail?" form_date = "Domain creation year"
form_tags = "[comma separated] Domain tags?" form_about = "Domain Description"
form_lic = "Domain License?" form_mail = "Webmaster's mail"
form_licurl = "License URL?" form_tags = "[comma separated] Domain tags"
form_legal = "Legal Notice URL?" form_lic = "Domain License"
form_terms = "Terms of Use URL?" form_licurl = "License URL"
form_css = "[alnum] CSS Prefix?" form_legal = "Legal Notice URL"
form_sep = "[1 char.] Pages titles separator?" form_terms = "Terms of Use URL"
form_pscode = "Show Article source code?" form_css = "[alnum] CSS Prefix"
form_relme = 'rel="me" URL?' form_sep = "[1 char.] Pages titles separator"
form_trsite = "[2 char.] Website language?" form_pscode = "Show Article source code"
form_sdb_i = "Article number?" form_relme = 'rel="me" URL'
form_activ = "Activate and prepare domain?" form_trsite = "[2 char.] Website language"
form_sdb_i = "Article number"
form_activ = "Activate and prepare domain"
form_dir_e = "Directory exists" form_dir_e = "Directory exists"
form_dir_c = "Directory created" form_dir_c = "Directory created"
form_file_e = "File exists" form_file_e = "File exists"
form_file_c = "File created" form_file_c = "File created"
form_reset = "Reset configuration?" form_reset = "Reset configuration"
form_rep = "Replace HTML file" form_rep = "Replace HTML file"
@ -235,19 +243,6 @@ footer_doc = \
'# - Do NOT copy to template directory' '# - Do NOT copy to template directory'
'# %s\n'%(20 * "-") '# %s\n'%(20 * "-")
footer_about_doc = \
'# For %s\n' + \
'# Type text/HTML file\n' + \
'# Description Used when a footer is generated\n' + \
'# Content inserted in "about" section\n' + \
'# File %s\n' + \
'# How Put any HTML code\n' + \
'# Notes - Lines are ignored if:\n' + \
'# - empty\n' + \
'# - begin with "#"\n' + \
'# - Do NOT copy to template directory\n' + \
'# %s\n'%(20 * "-")
# Help with Tyto commands # Help with Tyto commands
args_helps = """\n# New domain : args_helps = """\n# New domain :
- Create directory and go in - Create directory and go in
@ -259,9 +254,12 @@ args_helps = """\n# New domain :
- (css, logo...) files go in "wip/template/" - (css, logo...) files go in "wip/template/"
# Usage: tyto [action] [target] # Usage: tyto [action] [target]
# Actions # [action] > withour [target]
- [action] > According to [target] version : Show installed version
domains : Show installed domains
help : Show commands help
# [action] > According to [target]
# Edit a file # Edit a file
edit : Source file, configuration module edit : Source file, configuration module
edit-about: [footer] Edit description section in footer edit-about: [footer] Edit description section in footer
@ -272,7 +270,9 @@ args_helps = """\n# New domain :
new : [domain] Créer un domaine ou le modifier via le formulaire new : [domain] Créer un domaine ou le modifier via le formulaire
[sidebar, navbar, footer, metas] Create and replace [sidebar, navbar, footer, metas] Create and replace
with default module configuration file with default module configuration file
[filename] (no .tyto) Create article in current folder
[sitemap], create new website sitemap
# Show contents file (with line number) # Show contents file (with line number)
show : Show source file, source configuration module show : Show source file, source configuration module
show-about: [footer] Show description footer file show-about: [footer] Show description footer file
@ -284,11 +284,12 @@ args_helps = """\n# New domain :
# Create HTML page # Create HTML page
check : Check the validity of a tyto format file check : Check the validity of a tyto format file
wip : Create article HTML page in server 'wip' wip : Create article HTML page in server 'wip'
force-wip : [file], check, and then, wip
preview : [module]/[file], open 'wip' file on default browser
publish : Create article HTML page in server 'www' publish : Create article HTML page in server 'www'
quick-pub : [file], check, wip, publish
# Targets # [target] > According to [action]
- [target] > According to [action]
# Multiple articles # Multiple articles
updated : Update articles (already checked) updated : Update articles (already checked)
again : Force all articles (already checked) again : Force all articles (already checked)
@ -311,8 +312,14 @@ args_helps = """\n# New domain :
navbar : Navbar configuration file navbar : Navbar configuration file
sidebar : Sidebar configuration file sidebar : Sidebar configuration file
stats : Stats file (server 'wip' er 'www') stats : Stats file (server 'wip' er 'www')
sitemap : sitemap.tyto/.html file
# Examples : # [option] :
--static : Créer une page HTML entièrement statique
--no-mods : With [publish template], do not recreate modules
"""
ex_helps = """# Examples :
# Check article (according to sub-folder) # Check article (according to sub-folder)
$ tyto check mysubdir/index.tyto $ tyto check mysubdir/index.tyto

View File

@ -18,8 +18,12 @@
# - "\n" # - "\n"
# - "+ \" # - "+ \"
# Garder ! ('','',)
yes = ("o", "oui",)
# Generic # Generic
article = "Article" article = "Article"
links = "liens"
sidebar = 'Barre Latérale' sidebar = 'Barre Latérale'
navbar = 'Barre de menu' navbar = 'Barre de menu'
metas = 'Balises Metas' metas = 'Balises Metas'
@ -67,12 +71,12 @@ mail_to = "Contacter par %s l'administrateur de"%mail.lower()
feed = "Flux" feed = "Flux"
generator = "Generateur" generator = "Generateur"
# Misc for Tyto # Misc for Tyto
#-------------- #--------------
# Check # Check
check_a = "Vérifier encore l'article" check_a = "Vérifier encore l'article"
post_chg = "Article édité. Le vérifier" post_chg = "Article édité. Le vérifier"
new_post = "Créer l'article"
# Wip # Wip
wip_new = "Créer encore une page HTML dans le serveur 'wip'" wip_new = "Créer encore une page HTML dans le serveur 'wip'"
@ -88,12 +92,13 @@ rss_c = "Créer le flux ATOM/RSS"
# Autre # Autre
uptpl = "Mettre à jour le dossier" uptpl = "Mettre à jour le dossier"
stats_f = "Articles : %s (%s mots)" stats_f = "Articles : %s (%s mots)"
reg_domains = 'Domaines enregistrés' reg_domains = "Domaines enregistrés"
sitemap_gen = "Plan du site (sitemap) généré par"
sitemap_t = "Plan du site"
# Formulaire # Formulaire
#---------------------------------------------------------------------- #----------------------------------------------------------------------
form_edit = "Éditer le domaine avec le formulaire" form_edit = "Éditer le domaine avec le formulaire"
form_start = ' ├───────────────────────────────────────────────┐\n' + \ form_start = ' ├───────────────────────────────────────────────┐\n' + \
' │ Configurer un domaine pour le dossier courant │\n' + \ ' │ Configurer un domaine pour le dossier courant │\n' + \
' │ Répondre O/o = Oui. Entrer garde le {default}\n' + \ ' │ Répondre O/o = Oui. Entrer garde le {default}\n' + \
@ -121,6 +126,8 @@ form_db_new = "Nouvelle base de données crée"
form_trlog = "[2 car.] Langue des messages" form_trlog = "[2 car.] Langue des messages"
form_srv = "Dossier du serveur local" form_srv = "Dossier du serveur local"
form_logo = "Nom du fichier du logo" form_logo = "Nom du fichier du logo"
form_fav_f = "Nom du fichier favicon !(.png)"
form_css_f = "Nom du fichier CSS"
form_rss_f = "Nom du fichier Atom/RSS" form_rss_f = "Nom du fichier Atom/RSS"
form_rss_i = "Nombre d'articles Atom/RSS" form_rss_i = "Nombre d'articles Atom/RSS"
form_title = "Titre du site web" form_title = "Titre du site web"
@ -236,19 +243,6 @@ footer_doc = \
'# - Ne PAS copier ce fichier dans le dossier template\n' + \ '# - Ne PAS copier ce fichier dans le dossier template\n' + \
'# %s\n'%(20 * "-") '# %s\n'%(20 * "-")
footer_about_doc = \
'# Pour %s\n' + \
'# Type Fichier text/HTML\n' + \
'# Description Utilisé lors de la génération du pied de page\n' + \
'# Contenu inséré dans la section "about"\n' + \
'# Fichier %s\n' + \
'# Comment Insérer du code HTML\n' + \
'# Notes - Les lignes sont ignorées si :\n' + \
'# - vides\n' + \
'# - commencent par "#"\n' + \
'# - Ne PAS copier ce fichier dans le dossier template\n' + \
'# %s\n'%(20 * "-")
# Help with Tyto commands # Help with Tyto commands
args_helps = """\n# Nouveau domaine : args_helps = """\n# Nouveau domaine :
- Créer un dossier et aller dedans - Créer un dossier et aller dedans
@ -260,24 +254,26 @@ args_helps = """\n# Nouveau domaine :
- 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] # Usage: tyto [action] [target]
# Les actions # [action] > Sans [target]
- [action] > Selon l'argument [target] version : Montre la version installée
domains : Montre les domains installés
help : Montre l'aide des commandes
# [action] > Selon l'argument [target]
# Modifier un ficher # 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 edit-db : Modifier une base de données/fichier de configuration
edit-wip : Modifier un fichier dans le serveur 'wip' edit-wip : Modifier un fichier dans le serveur 'wip'
edit_www : Modifier un fichier dans le serveur 'www' edit_www : Modifier un fichier dans le serveur 'www'
new : [domain] Créer un domaine ou le modifier via le formulaire new : [domain] Créer un domaine ou le modifier via le formulaire
[sidebar, navbar, footer, metas] Créer ou remplacer le [sidebar, navbar, footer, metas] Créer ou remplacer le
fichier de configuration du module par le défaut fichier de configuration du module par le défaut
[filename] (sans .tyto) Créer un article dans le
dossier actuel
[sitemap], créer le plan du site (sitemap)
# Afficher un fichier (avec numéros de ligne) # 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 show-db : Afficher une base de données/fichier de configuration
show-wip : Afficher un fichier dans le serveur 'wip' show-wip : Afficher un fichier dans le serveur 'wip'
show-www : Afficher un fichier dans le serveur 'www' show-www : Afficher un fichier dans le serveur 'www'
@ -285,11 +281,12 @@ args_helps = """\n# Nouveau domaine :
# Processus de création / Mise en ligne # Processus de création / Mise en ligne
check : Vérifier la validité d'un article au format tyto check : Vérifier la validité d'un article au format tyto
wip : Créer une page HTML de l'article dans le serveur 'wip' wip : Créer une page HTML de l'article dans le serveur 'wip'
force-wip : [file], check, wip
preview : [module]/[file], ouvre le fichier 'wip' dans le navigateur par défaut
publish : Créer une page HTML de l'article dans le serveur 'www' publish : Créer une page HTML de l'article dans le serveur 'www'
quick-pub : [file] , check, wip, publish
# Les cibles # [target] > Selon l'action [action]
- [target] > Selon l'action [action]
# Traitement en masse # Traitement en masse
updated : Mise à jour des articles modifiés (déjà vérifiés) updated : Mise à jour des articles modifiés (déjà vérifiés)
again : Forcer TOUS les articles déjà vérifiés again : Forcer TOUS les articles déjà vérifiés
@ -312,8 +309,14 @@ args_helps = """\n# Nouveau domaine :
navbar : Fichier de configuration du menu de navigation navbar : Fichier de configuration du menu de navigation
sidebar : Fichier de configuration de la barre latérale sidebar : Fichier de configuration de la barre latérale
stats : Fichier de statistiques (serveur 'wip' ou 'www') stats : Fichier de statistiques (serveur 'wip' ou 'www')
sitemap : Fichier sitemap.tyto/.html
# [option]
--static : Créer une page HTML entièrement statique
--no-mods : Avec [publish template], ne pas recréer les modules
"""
# Exemples : ex_helps = """# Exemples :
# Vérifier l'article dans le sous dossier (suivant l'emplacement) # Vérifier l'article dans le sous dossier (suivant l'emplacement)
$ tyto check mysubdir/index.tyto $ tyto check mysubdir/index.tyto