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
31 changed files with 2766 additions and 1847 deletions
Showing only changes of commit 5d17b15e15 - Show all commits

View File

@ -5,28 +5,9 @@ Tyto - Littérateur
- Issues: https://git.a-lec.org/echolib/tyto-litterateur/-/issues
- Changelog: https://git.a-lec.org/echolib/tyto-litterateur/-/blob/master/CHANGELOG.md
- License: https://git.a-lec.org/echolib/tyto-litterateur/-/blob/master/LICENSE
- Documentation: https://tyto.echolib.re
## [0.10.2]
- Citer dans un texte > `[_` + `_]`
- Italique `<em>` > `;_` + `_;`
- Italique `<i>` > {_:_` + `_:`
## [0.10.6]
## [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

257
README.md
View File

@ -1,220 +1,53 @@
# Tyto
Pour obtenir de l'aide, taper juste la commande tyto
- FR. Pour obtenir de l'aide, taper juste la commande tyto
- EN. To get help, just type tyto.
- - Doc is only in french yet, but Tyto is translated, also for your websites
## Répertoire de code du projet Tyto
TODO
https://git.a-lec.org/echolib/tyto-litterateur
## Comment définir les métas
```
# Obligatoires uniques
# Ces marqueurs se configurent sur UNE ligne
title: Titre
about: Infos de l'article
author: Auteur
tags: mot-clé-1,mot 2,
date: YYYY-MM-DD (AAAA-MM-JJ)
## Documentation officielle
https://tyto.echolib.re (en cours de construction)
# L'image doit être configurée avec le même Nom
# dans les marqueurs multiples
# Utilise l'image précisée comme "avatar" dans les réseaux sociaux
snpic: Nom
# Optionnels multiples
# Ces marqueurs se configurent sur 3 lignes
link: Nom du lien
URL
Texte Alternatif
image: Nom
URI
Texte Alternatif
file: Nom du lien
URL
Texte Alternatif
raw: Nom
URI
Texte Alternatif
abbr: abbrev
Définition de abbrev
ABBR (forme à afficher dans l'artile (optionnel))
# Séparateur d'au moins 5 "-" pour définir la fin
# des métadonnées d'entête de l'article
----------
```
## Comment écrire un article
### Écrire des titres
```
# Les titres HTML vont de 1 à 6.
# Utiliser #N, où N est entre 1 et 6.
# Si du contenu existe entre les titres, une <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 !
))
]]
## Créer un domaine
````
mkdir -p MONDOMAIN
cd MONDOMAIN
tyto new domain URL
````
# Créer un article
https://tyto.echolib.re/%C3%A9crire/
```
# Source: citation basique
[[
Une citation simple, et sans paragraphe
]]
cd articles/
tyto new index
tyto edit index.tyto
```
# Vérifier, prévisualiser un article
```
tyto check index.tyto
tyto wip index.tyto
```
# Les modules
https://tyto.echolib.re/usages/modules.html
La barre latérale, le menu, le pied de page et les balises génériques metas
ne seront pas visible localement sans serveur nginx.
Utiliser l'option --static avec la commande wip pour les voir. Attention,
utiliser la commande publish après avoir utilisé l'option --static sur wip
mettra en ligne la version statique de la page. Il faut donc avant la
commande publish, recommencer la commande wip sur un article sans l'option
--static pour utiliser l'include de nginx (comportement par défaut)
# Publier !
```
# La première fois, ou après mise à jour des modules ou des fichiers (logo, css...)
tyto publish template
# Mettre dans le dossier "www" officiel
tyto publish index.tyto
```

4
debian/control vendored
View File

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

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
Tyto - Littérateur
- Repository: https://git.a-lec.org/echolib/tyto
- Issues: https://git.a-lec.org/echolib/tyto/-/issues
- Changelog: https://git.a-lec.org/echolib/tyto/-/blob/main/CHANGELOG.md
- License: https://git.a-lec.org/echolib/tyto/-/blob/main/LICENSE
- Repository: https://git.a-lec.org/echolib/tyto-litterateur
- Issues: https://git.a-lec.org/echolib/tyto-litterateur/-/issues
- Changelog: https://git.a-lec.org/echolib/tyto-litterateur/-/blob/master/CHANGELOG.md
- License: https://git.a-lec.org/echolib/tyto-litterateur/-/blob/master/LICENSE
- Documentation: https://tyto.echolib.re
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
## [1.0.0]
- (2023.05.09)
- - Official first public release
## [0.9.0] First Commit version (pre-final)

View File

@ -1,167 +1,53 @@
# 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
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
title: Titre
about: Infos de l'article
author: Autheur
tags: mots-clé-1,mots-clé-2
date: YYYY-MM-DD (AAAA-MM-JJ)
# Optionnels myltiples
link: Nom du lien
URL
Texte Alternatif
image: Nom
URI
Texte Alternatif
file: Nom du lien
URL
Texte Alternatif
brut: Nom
URI
Texte Alternatif
abbr: NOM (en majuscule)
Définition du NOM
nom (forme à afficher dans l'artile (optionnel))
# Séparateur d'au moins 5 "-" pour définir la fin
# des métadonnées d'entête de l'article
----------
cd articles/
tyto new index
tyto edit index.tyto
```
## Comment écrire un article
### Titre h1 à h6
# Vérifier, prévisualiser un article
```
#1 Titre 1
((
Un paragraphe
))
#2 Titre 2
tyto check index.tyto
tyto wip index.tyto
```
### Paragraphes
```
(( CSS
Un paragraphe
))
```
# Les modules
https://tyto.echolib.re/usages/modules.html
### Code Brut
```
{{ CSS
def hello_world():
print("Hello")
}}
```
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.
### Listes ul/ol
```
-( CSS
= Liste ul
== Sous-liste ul
=== Sous-sous-liste ul
++++ Sous-sous-sous-liste ol
+++ Sous-sous-liste 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
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)
### Citations
```
[[ CSS
_cite: autheur
_lang: langue
_link: lien
_year: année ou date YYYY-MM-DD
_book: référence
((
Citation placée dans un paragraphe
))
]]
[[ CSS
Citation simple sans référence
]]
# Publier !
```
# La première fois, ou après mise à jour des modules ou des fichiers (logo, css...)
tyto publish template
### Ancres
```
-> 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
# Mettre dans le dossier "www" officiel
tyto publish index.tyto
```

View File

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

View File

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

View File

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

View File

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

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
#----------------------------------------------------------------------
#------------
# funny stats
#------------
# lines:
# functions:
# comments:
#----------------------------------------------------------------------
#-------------------------
# Funny Stats Project
#-------------------------
# file lines : 206
# file comments : 37
# file functions: 1
# file program : 152
#--------------------------
#**********************************************************************
import os
import args, logs, dom, form, tyto, check, publish
@ -104,6 +104,7 @@ if args.target \
'meta_tags',
'date',
'snpic',
'sitemap',
'uris',
'uniq_anchors',
'uniq_abbrs',
@ -193,3 +194,13 @@ if args.target \
# Article is updated on both servers
if hash_chk == hash_wip == hash_www: sync_srvs = True
#=========================#
# Show title and uri file #
#-------------------------#
def show_title():
try:
print('"%s" > %s'%(title, uri_file))
except:
return

View File

@ -23,120 +23,132 @@
# File: /var/lib/tyto/program/dom.py
#----------------------------------------------------------------------
#------------
# funny stats
#------------
# lines:
# functions:
# comments:
#----------------------------------------------------------------------
#-------------------------
# Funny Stats Project
#-------------------------
# file lines : 318
# file comments : 31
# file functions: 1
# file program : 277
#--------------------------
#**********************************************************************
import os, sys, importlib, langs
import args
lib = 'tyto_domain'
exists = incomplete = active = ready = shortname = corrupt = False
local_user = articles_db_d = False
hole = False
# Set current directory
try:
user_dir
ready
except:
lib = 'tyto_domain'
exists = incomplete = active = ready = shortname = corrupt = False
local_user = articles_db_d = False
hole = False
# Set current directory
try:
user_dir
except:
try:
user_dir = os.getcwd() + "/"
except:
hole = True
# Settings for domain, check if db is not corrupted
dom_values = \
(
'directory',
'database',
'local_user',
'lang_sys',
'lang_logs',
'articles_db_d',
'articles_d',
'files_d',
'images_d',
'modules_d',
'navbar_f',
'sidebar_f',
'metas_f',
'footer_f',
'footer_about_f',
'shortname',
'www_url',
'wip_url',
'srv_root',
'srv_domain',
'srv_wip',
'srv_wip_tpl_d',
'srv_wip_images_d',
'srv_wip_files_d',
'srv_www',
'srv_www_tpl_d',
'srv_www_images_d',
'srv_www_files_d',
'wip_css_f',
'wip_logo_f',
'wip_navbar_f',
'wip_sidebar_f',
'wip_metas_f',
'wip_footer_f',
'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
# Set current user name
try:
user
except:
try:
user = os.environ.get('USER')
except:
user = ''
if not hole:
# 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('~')
# Set configuration domain directory
@ -176,6 +188,7 @@ if not hole:
try: active = activated
except: pass
# Check set values configuration
if not corrupt:
for value in dom_values:
try:
@ -188,28 +201,13 @@ if not hole:
active = False
if value.endswith('_d'):
if value_set:
if not os.path.exists(eval(str(value))):
try:
os.makedirs(eval(str(value)), exist_ok=True)
dir_new = dir_new + ((eval(str(value))),)
except:
dir_unu = dir_unu + ((eval(str(value))),)
elif value.endswith('_f'):
if value_set:
if not os.path.exists(eval(str(value))):
if value in create_files:
file_mod = file_mod + ((value),)
else:
file_unu = file_unu + ((eval(str(value))),)
#==============================================#
# When an active and complete domain is needed #
#----------------------------------------------#
if exists and not incomplete and not corrupt:
if active:
ready = True
wip_html_mods = \
(
eval(str('wip_navbar_f')),
@ -217,39 +215,49 @@ if not hole:
eval(str('wip_metas_f')),
eval(str('wip_footer_f'))
)
if active:
ready = True
metas = (
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 = (
navbars = \
(
eval(str('navbar_f')),
eval(str('wip_navbar_f')),
eval(str('www_navbar_f'))
)
sidebars = (
sidebars = \
(
eval(str('sidebar_f')),
eval(str('wip_sidebar_f')),
eval(str('www_sidebar_f'))
)
footers = (
footers = \
(
eval(str('footer_f')),
eval(str('wip_footer_f')),
eval(str('www_footer_f')),
eval(str('footer_about_f'))
)
templates = (
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')),
@ -260,15 +268,25 @@ if not hole:
eval(str('www_rss_f')),
)
modules = {
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_wip = {
templates_files_wip = \
(
eval(str('wip_favicon_f')),
eval(str('wip_logo_f')),
eval(str('wip_css_f')),
eval(str('wip_navbar_f')),
@ -276,9 +294,11 @@ if not hole:
eval(str('wip_metas_f')),
eval(str('wip_footer_f')),
eval(str('wip_stats_f')),
}
)
templates_www = {
templates_files_www = \
(
eval(str('www_favicon_f')),
eval(str('www_logo_f')),
eval(str('www_css_f')),
eval(str('www_navbar_f')),
@ -287,7 +307,7 @@ if not hole:
eval(str('www_footer_f')),
eval(str('www_stats_f')),
eval(str('www_rss_f'))
}
)
#====================================#
# Check if domain is ready and ready #
@ -295,3 +315,4 @@ if not hole:
def valid():
if incomplete: sys.exit(41)
elif not active: sys.exit(42)
elif not ready: sys.exit(41)

View File

@ -25,36 +25,38 @@
# File: /var/lib/tyto/program/form.py
#----------------------------------------------------------------------
#------------
# funny stats
#------------
# lines:
# functions:
# comments:
#----------------------------------------------------------------------
#-------------------------
# Funny Stats Project
#-------------------------
# file lines : 1092
# file comments : 104
# file functions: 7
# file program : 872
#--------------------------
#**********************************************************************
from datetime import datetime
import os, sys, shutil, re, locale, importlib
import logs, dom, tyto, html, show, langs
# locale translation directory
trans_dir = '/var/lib/tyto/translations'
# Get default System language
try:
lang_site
except:
# locale translation directory
trans_dir = '/var/lib/tyto/translations'
# Get default System language
try:
lang_sys = locale.getdefaultlocale()[0].split('_')[0]
os.path.exists('%s/site_%s.py'%(trans_dir, lang_sys))
except:
except:
lang_sys = 'en'
lang_site = lang_sys
lang_site = lang_sys
# Generic answer
answer_yes = ('y', 'Y', 'yes', 'Yes', 'YES',
'o', 'O', 'oui', 'Oui', 'Oui'
)
try: answer_yes
except: answer_yes = langs.answer_yes
#=======================================#
@ -72,7 +74,11 @@ def asking(question, yes_no):
logs.out("255", '', True)
if yes_no:
if not answer in answer_yes:
go = False
for yes_names in answer_yes:
if answer.lower() in yes_names:
go = True
if not go:
logs.out("255", '', True)
else:
@ -207,7 +213,6 @@ def create_domain(target):
'sidebar_f = "%styto.sidebar"\n'%modules_dir + \
'metas_f = "%styto.metas.html"\n'%modules_dir + \
'footer_f = "%styto.footer.html"\n'%modules_dir + \
'footer_about_f = "%s"\n'%footer_about_f + \
'\n# Domain\n' + \
'shortname = "%s"\n'%shortname + \
'www_url = "%s"\n'%www_url + \
@ -244,7 +249,28 @@ def create_domain(target):
), False)
if answer: logo = answer
if not logo: logo='logo.png'
# Get css file name
#------------------
try: css_file = dom.css_file
except: css_file = "styles.css"
answer = asking('%s%s {%s} '%(
langs.site.form_css_f, langs.site.q, css_file
), False)
if answer: css_file = answer
# Get favicon file name
#----------------------
try: favicon_file = dom.favicon_file
except: favicon_file = "favicon.png"
answer = asking('%s%s {%s} '%(
langs.site.form_fav_f, langs.site.q, favicon_file
), False)
if answer: favicon_file = answer
# Set config's directories for servers
@ -256,7 +282,7 @@ def create_domain(target):
srv_www_tpl = "%s/www/template/"%root_srv_dom
set_f = \
'# Servers directories\n' + \
'\n# Servers directories\n' + \
'srv_root = "%s/"\n'%srv + \
'srv_domain = "%s/"\n'%root_srv_dom + \
'srv_wip = "%s/wip/"\n'%root_srv_dom + \
@ -269,8 +295,9 @@ def create_domain(target):
'srv_www_files_d = "%s/www/files/"\n'%root_srv_dom + \
'\n' + \
'# Servers files (wip)\n' + \
'wip_favicon_f = "%s%s"\n'%(srv_wip_tpl, favicon_file) + \
'wip_logo_f = "%s%s"\n'%(srv_wip_tpl, logo) + \
'wip_css_f = "%sstyles.css"\n'%srv_wip_tpl + \
'wip_css_f = "%s%s"\n'%(srv_wip_tpl, css_file) + \
'wip_navbar_f = "%snavbar.html"\n'%srv_wip_tpl + \
'wip_sidebar_f = "%ssidebar.html"\n'%srv_wip_tpl + \
'wip_metas_f = "%smetas.html"\n'%srv_wip_tpl + \
@ -278,13 +305,14 @@ def create_domain(target):
'wip_stats_f = "%s"\n'%stats_wip_f + \
'\n' + \
'# Servers files (www)\n' + \
'www_favicon_f = "%s%s"\n'%(srv_www_tpl, favicon_file) + \
'www_logo_f = "%s%s"\n'%(srv_www_tpl, logo) + \
'www_css_f = "%sstyles.css"\n'%srv_www_tpl + \
'www_css_f = "%s%s"\n'%(srv_www_tpl, css_file) + \
'www_navbar_f = "%snavbar.html"\n'%srv_www_tpl + \
'www_sidebar_f = "%ssidebar.html"\n'%srv_www_tpl + \
'www_metas_f = "%smetas.html"\n'%srv_www_tpl + \
'www_footer_f = "%sfooter.html"\n'%srv_www_tpl + \
'www_stats_f = "%s"'%stats_www_f
'www_stats_f = "%s"\n'%stats_www_f
tyto.set_file(dom.config, False, set_f)
@ -300,11 +328,13 @@ def create_domain(target):
if answer: www_rss = answer
set_f = 'www_rss_f = "%s/www/%s"\n'%(root_srv_dom, rss) + \
set_f = \
'www_rss_f = "%s/www/%s"\n'%(root_srv_dom, rss) + \
'\n# Domain user\'s settings\n' + \
'favicon = "%s"\n'%favicon_file + \
'logo = "%s"\n'%logo + \
'styles = "styles.css"\n' + \
'rss = "%s"'%rss
'styles = "%s"\n'%css_file + \
'rss = "%s"\n'%rss
tyto.set_file(dom.config, False, set_f)
@ -322,7 +352,7 @@ def create_domain(target):
if not str(rss_items).isdigit() or not int(rss_items) > 1:
rss_items = 100
set_f = 'rss_items = %d'%int(rss_items)
set_f = 'rss_items = %d\n'%int(rss_items)
tyto.set_file(dom.config, False, set_f)
@ -339,7 +369,7 @@ def create_domain(target):
if not title: invalid = True
else: title = tyto.convert_altname(title)
set_f = 'title = "%s"'%title
set_f = 'title = "%s"\n'%title
tyto.set_file(dom.config, False, set_f)
@ -354,7 +384,7 @@ def create_domain(target):
if answer: date = answer
set_f = 'date = "%s"'%date
set_f = 'date = "%s"\n'%date
tyto.set_file(dom.config, False, set_f)
@ -371,7 +401,7 @@ def create_domain(target):
if not about: invalid = True
else: about = tyto.convert_altname(about)
set_f = 'about = "%s"'%about
set_f = 'about = "%s"\n'%about
tyto.set_file(dom.config, False, set_f)
@ -391,7 +421,7 @@ def create_domain(target):
if not tyto.exists('%s/site_%s.py'%(trans_dir, lang_site)):
lang_site = 'en'
set_f = 'lang_site = "%s"'%lang_site
set_f = 'lang_site = "%s"\n'%lang_site
tyto.set_file(dom.config, False, set_f)
@ -405,11 +435,12 @@ def create_domain(target):
), False)
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)
invalid = True
set_f = 'mail = "%s"'%mail
set_f = 'mail = "%s"\n'%mail
tyto.set_file(dom.config, False, set_f)
@ -426,14 +457,14 @@ def create_domain(target):
if not tags: invalid = True
elif '"' in tags: tags = tags.replace('"', '')
set_f = 'tags = "%s"'%tags
set_f = 'tags = "%s"\n'%tags
tyto.set_file(dom.config, False, set_f)
# Get License domain
#-------------------
try: domlicense = dom.license
except: domlicense = 'CC BY-NC-SA 3.0'
except: domlicense = 'gfdl-1.3'
answer = asking('%s%s {%s} '%(
langs.site.form_lic, langs.site.q, domlicense
@ -442,14 +473,16 @@ def create_domain(target):
if answer: domlicense = answer
if '"' in domlicense: domlicense = domlicense.replace('"', '')
set_f = 'license = "%s"'%domlicense
set_f = 'license = "%s"\n'%domlicense
tyto.set_file(dom.config, False, set_f)
# Get License URL (optional)
#---------------------------
try: licurl = dom.license_url
except: licurl = ''
except:
if domlicense == "gfdl-1.3":
licurl = "https://www.gnu.org/licenses/fdl-1.3.txt"
answer = asking('%s [http(s)://...] %s%s {%s} '%(
langs.site.form_opt, langs.site.form_licurl,
@ -462,7 +495,7 @@ def create_domain(target):
logs.out("2", '"http(s)://%s"%s'%(licurl, langs.site.q), False)
licurl = ''
set_f = 'license_url = "%s"'%licurl
set_f = 'license_url = "%s"\n'%licurl
tyto.set_file(dom.config, False, set_f)
@ -482,7 +515,7 @@ def create_domain(target):
logs.out("2", '"http(s)://%s"%s'%(legalurl, langs.site.q), False)
legalurl = ''
set_f = 'legal_url = "%s"'%legalurl
set_f = 'legal_url = "%s"\n'%legalurl
tyto.set_file(dom.config, False, set_f)
@ -502,7 +535,7 @@ def create_domain(target):
logs.out("2", '"http(s)://%s"%s'%(termsurl, langs.site.q), False)
termsurl = ''
set_f = 'terms_url = "%s"'%termsurl
set_f = 'terms_url = "%s"\n'%termsurl
tyto.set_file(dom.config, False, set_f)
@ -520,7 +553,7 @@ def create_domain(target):
logs.out("3", css, False)
css = 'tyto'
set_f = 'css = "%s"'%css
set_f = 'css = "%s"\n'%css
tyto.set_file(dom.config, False, set_f)
@ -538,27 +571,27 @@ def create_domain(target):
logs.out("3", answer, False)
sep = "-"
set_f = 'sep = "%s"'%sep
set_f = 'sep = "%s"\n'%sep
tyto.set_file(dom.config, False, set_f)
# Show article source ?
#----------------------
try:
dom.article_code
article_code = "True"
if dom.article_code: article_code = "True"
else: article_code = "False"
except:
article_code = "False"
answer = ('%s%s {%s} '%(
langs.site.form_pscode, langs.site.q, article_code
answer = asking('%s%s {%s} (Y|n) '%(
langs.site.form_pscode, langs.site.q, str(article_code)
), False)
if answer:
if answer in answer_yes: article_code = "True"
else: article_code = "False"
set_f = 'article_code = %s'%article_code
set_f = 'article_code = %s\n'%article_code
tyto.set_file(dom.config, False, set_f)
@ -578,7 +611,7 @@ def create_domain(target):
logs.out("2", '"http(s)://%s"%s'%(relme, langs.site.q), False)
relmel = ''
set_f = 'relme = "%s"'%relme
set_f = 'relme = "%s"\n'%relme
tyto.set_file(dom.config, False, set_f)
@ -599,7 +632,7 @@ def create_domain(target):
else:
sdb_title = tyto.convert_altname(sdb_title)
set_f = 'sidebar_title = "%s"'%sdb_title
set_f = 'sidebar_title = "%s"\n'%sdb_title
tyto.set_file(dom.config, False, set_f)
@ -617,7 +650,7 @@ def create_domain(target):
if not str(sdb_items).isdigit() or not int(sdb_items) in range(1,17):
sdb_items = 6
set_f = 'sidebar_items = %d'%int(sdb_items)
set_f = 'sidebar_items = %d\n'%int(sdb_items)
tyto.set_file(dom.config, False, set_f)
@ -650,13 +683,17 @@ def create_domain(target):
# Activate Domain
#----------------
tyto.set_file(dom.config, False, '\nactivated = True')
shutil.copy2(dom.config, config_bkp)
logs.out("32", config_bkp, False)
# RELoad config
# ReLoad config
#--------------
importlib.reload(dom)
# Backup and create local user dir
if not os.makedirs(dom.articles_db_d, exist_ok=True):
logs.out("33", dom.articles_db_d, False)
shutil.copy2(dom.config, config_bkp)
logs.out("32", config_bkp, False)
# Create folders from configuration file
#---------------------------------------
@ -674,18 +711,18 @@ def create_domain(target):
logs.out("37", folder, False)
else:
os.makedirs(folder, exist_ok=True)
logs.out("33", foloder, False)
logs.out("33", folder, False)
print('')
# Create in _configs/ modules files
#----------------------------------
create_metas('form')
create_navbar('form')
create_sidebar('form')
create_footer('form')
create_footer_about('form')
html.create_user_metas('new')
html.create_navbar('new')
html.create_sidebar('new')
html.create_user_footer('new')
print(langs.site.form_ready)
@ -701,15 +738,17 @@ def create_domain(target):
def create_metas(option):
if not dom.ready: dom.valid()
print('\n%s'%langs.site.metas_inf)
if option != "new": return
# Create new default config file, or ask if exists
if tyto.exists(dom.metas_f):
answer = asking('%s. %s%s '%(
langs.site.metas, langs.site.form_reset,
langs.site.q
answer = asking('%s%s '%(
langs.site.form_reset, langs.site.q
), False)
if not answer in answer_yes:
if option == "form": return
if option == "new": return
logs.out("255", '', True)
# Set default content for
@ -767,10 +806,6 @@ def create_metas(option):
tyto.set_file(dom.metas_f, 'New', metas_tags)
# Create an empty html file in wip/www server if not exists
if not tyto.exists(dom.wip_metas_f):
html.create_user_metas('wip')
#=============================#
# navbar load file translated #
@ -778,15 +813,17 @@ def create_metas(option):
def create_navbar(option):
if not dom.ready: dom.valid()
print('\n%s'%langs.site.navbar_inf)
if option != "new": return
# Create new config file, or ask if exists
if tyto.exists(dom.navbar_f):
answer = asking('%s. %s%s '%(
langs.site.navbar, langs.site.form_reset,
langs.site.q
answer = asking('%s%s '%(
langs.site.form_reset, langs.site.q
), False)
if not answer in answer_yes:
if option == "form": return
if option == "new": return
logs.out("255", '', True)
@ -828,9 +865,6 @@ def create_navbar(option):
tyto.set_file(dom.navbar_f, 'New', navbar_lang)
# Create wip navbar file
html.create_navbar('wip')
#==============================#
# sidebar load file translated #
@ -838,19 +872,21 @@ def create_navbar(option):
def create_sidebar(option):
if not dom.ready: dom.valid()
print('\n%s'%langs.site.sidebar_inf)
if option != "new": return
# Create an empty html file in wip/www server if not exists
if not tyto.exists(dom.wip_sidebar_f):
tyto.set_file(dom.wip_sidebar_f, 'new', '')
# Create new config file, or ask if exists with option = 'reset'
if tyto.exists(dom.sidebar_f):
answer = asking('%s. %s%s '%(
langs.site.sidebar, langs.site.form_reset,
langs.site.q
answer = asking('%s%s '%(
langs.site.form_reset, langs.site.q
), False)
if not answer in answer_yes:
if option == "form": return
if option == "new": return
logs.out("255", '', True)
@ -900,6 +936,9 @@ def create_sidebar(option):
def create_footer(option):
if not dom.ready: dom.valid()
print('\n%s'%langs.site.footer_inf)
if option != "new": return
# Default footer contents
#------------------------
Tytosrc = \
@ -924,18 +963,7 @@ def create_footer(option):
'%stitle="%s"\n'%(9 * ' ', langs.site.go_home) + \
'%sclass="footer_title_link">%s</a>'%(9 * ' ', dom.title)
# Insert content of footer_about_f or default if not exists
footer_about = ''
if tyto.exists(dom.footer_about_f):
footer_custom = open(dom.footer_about_f).read()
for line in footer_custom.rsplit('\n'):
if not line or line.startswith('#'):
continue
line = '%s%s'%(6 * ' ', line)
if footer_about: footer_about = '%s\n%s'%(footer_about, line)
else: footer_about = line
else:
# Insert content of fabout domain
footer_about = "<p>%s</p>"%dom.about
# License URL. Set to homepage if unknown
@ -999,15 +1027,15 @@ def create_footer(option):
# Final HTML footer code
footer = \
'%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_infos">\n' + \
' <h1 id="footer_site_title"\n' + \
' <h2 id="footer_site_title"\n' + \
' title="%s %s">%s %s\n'%(
langs.site.add_inf, dom.title,
langs.site.about, dom.title
) + \
' </h1>\n' + \
' </h2>\n' + \
'%s\n'%(footer_about) + \
' </div>\n' + \
'\n' + \
@ -1031,7 +1059,7 @@ def create_footer(option):
' <li class="footer_item">%s%s \n'%(
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 + \
' class="footer_item_link">RSS 2.0</a>\n' + \
' </li>\n' + \
@ -1052,41 +1080,13 @@ def create_footer(option):
# Create new default file, or ask if exists
if tyto.exists(dom.footer_f):
answer = asking('%s. %s%s '%(
langs.site.footer, langs.site.form_reset,
langs.site.q
answer = asking('%s%s '%(
langs.site.form_reset, langs.site.q
), False)
if not answer in answer_yes:
if option == "form": return
if option == "new": return
logs.out("255", '', True)
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
#----------------------------------------------------------------------
#------------
# funny stats
#------------
# lines:
# functions:
# comments:
#----------------------------------------------------------------------
#-------------------------
# Funny Stats Project
#-------------------------
# file lines : 544
# file comments : 71
# file functions: 8
# file program : 414
#--------------------------
#**********************************************************************
import os, sys, importlib
import logs, db, dom, tyto, form, langs
# Publish option can be
wip_opts = ('wip', 'new')
pub_opts = ('www', 'pub')
# Not a line if it starts with...(for sidebar, navbar)
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 #
# Start HTML page sections #
@ -67,9 +79,8 @@ def create_metas_page():
db.sub_uri, dom.rss,
dom.title, dom.sep, dom.shortname
)
icon_file = 'favicon.png'
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)
if dom.relme:
@ -84,7 +95,7 @@ def create_metas_page():
#-----------------------
global 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=”url” content=”%s”>\n'%dom.www_url + \
' <meta name="language" content="%s">\n'%dom.lang_site + \
@ -153,22 +164,24 @@ def create_main_page(target, article_bottom):
'%s\n'%metas + \
' </head>\n\n' + \
' <body>\n' + \
' <div id="site_container">\n' + \
' <header id="header_page">\n' + \
' <div id="site_logo">\n' + \
' %s\n'%logo_html + \
' </div>\n' + \
' <div id="site_infos">\n' + \
' <h1 id="site_title">\n' + \
' <a href="/"\n' + \
' title="%s"\n'%(langs.site.home) + \
' id="site_link">\n' + \
' <h1 id="site_title">%s</h1>\n'%dom.title + \
' </a>\n' + \
' id="site_link">%s</a>\n'%dom.title + \
' </h1>\n' + \
' <p id="site_about">%s</p>\n'%dom.about + \
' </div>\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' + \
' <h1 id="main_title"\n' + \
' <h1 accesskey="t" id="post_title"\n' + \
' title="[%s] %s %s %s %s">%s</h1>\n'%(
db.title, langs.site.w_written, db.date,
langs.site.by, db.author,
@ -188,8 +201,10 @@ def create_main_page(target, article_bottom):
' </div>\n' + \
' </article>\n' + \
'\n' + \
tyto.tags_html_mods[dom.wip_sidebar_f] + '\n' + \
tyto.tags_html_mods[dom.wip_footer_f] + '\n' + \
tags_html_mods[dom.wip_sidebar_f] + '\n' + \
' </div>\n' + \
tags_html_mods[dom.wip_footer_f] + '\n' + \
' </div>\n' + \
' </body>\n' + \
'</html>'
@ -231,7 +246,7 @@ def create_html_time_meta(process):
' <span id="article_pub"\n' + \
' title="[%s] %s %s (%s)">%s</span>\n'%(
db.title, langs.site.w_published, date_pub, time_pub,
date_pub
db.date
) + \
' </time>\n' + \
'<!--/Tyto_Published-->'
@ -250,7 +265,9 @@ def create_html_time_meta(process):
def create_user_metas(option):
dom.valid()
if option == 'wip': target = dom.wip_metas_f
form.create_metas(option)
if option in wip_opts: target = dom.wip_metas_f
elif option in pub_opts: target = dom.www_metas_f
if option == 'www' and tyto.exists(target):
@ -258,8 +275,6 @@ def create_user_metas(option):
langs.site.metas, langs.site.form_rep, langs.site.q
), True)
print('\n%s'%langs.site.metas_inf)
# Create wip metas.html file according to option
#-----------------------------------------------
try: user_file = open(dom.metas_f, 'r').read()
@ -284,10 +299,12 @@ def create_user_metas(option):
def create_navbar(option):
dom.valid()
form.create_navbar(option)
if not tyto.exists(dom.navbar_f):
logs.out("1", dom.navbar_f, True)
if option == 'wip': target = dom.wip_navbar_f
if option in wip_opts: target = dom.wip_navbar_f
elif option in pub_opts: target = dom.www_navbar_f
if option == 'www' and tyto.exists(target):
@ -296,14 +313,12 @@ def create_navbar(option):
option, langs.site.q
), True)
print('\n%s'%langs.site.navbar_inf)
# navbar has items
navbar_items = False
# Set first HTML line
menu_html = \
'%s<nav id="site_menu">\n'%(4 * ' ') + \
'%s<nav accesskey="m" id="site_menu">\n'%(4 * ' ') + \
'%s<menu id="site_menu_items">'%(6 * ' ')
navbar_lines = open(dom.navbar_f, 'r').read()
@ -345,7 +360,7 @@ def create_navbar(option):
continue
# index.html server files must exist (or 404 error)
if option == 'wip':
if option in wip_opts:
if not tyto.exists(wip_index):
logs.out('26', '> %s'%(wip_index), False)
no_wip_index = True
@ -374,10 +389,7 @@ def create_navbar(option):
# Nothing to do
if not navbar_items:
if not tyto.exists(target):
tyto.set_file(target, 'New', '')
logs.out('28', '%s'%langs.log.navbar, False)
return
# Create ending HTML file
else:
@ -392,12 +404,14 @@ def create_navbar(option):
def create_sidebar(option):
dom.valid()
form.create_sidebar(option)
if not tyto.exists(dom.sidebar_f):
logs.out("1", dom.sidebar_f, True)
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
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
), True)
print('\n%s'%langs.site.sidebar_inf)
sidebar_items = False
# Set HTML sidebar
sidebar_list = ''
sidebar_html = \
'<aside id="sidebar">\n' + \
' <h1 id="sidebar_title">%s</h1>\n' + \
'<aside accesskey="s" id="sidebar">\n' + \
' <h2 id="sidebar_title">%s</h2>\n' + \
' <ul id="sidebar_list">\n' + \
'%s' + \
' </ul>\n' + \
@ -447,7 +459,7 @@ def create_sidebar(option):
exec(open(db_uri).read(),globals())
# Check wip status and if article exists in server
if option == 'wip':
if option in wip_opts:
if hash_wip != hash_chk:
logs.out("30", line, False)
continue
@ -477,20 +489,17 @@ def create_sidebar(option):
' <li class="sidebar_item">\n' + \
' <a class="sidebar_item_link"\n' + \
' 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' + \
' title="%s">\n'%link_title + \
' %s [%s] - %s\n'%(date, author, about) + \
' %s - %s\n'%(date, about) + \
' </p>\n' + \
' </a>\n' + \
' </li>\n'
# Nothing to do
if not sidebar_items:
if not tyto.exists(target):
tyto.set_file(target, 'New', '')
logs.out('28', '%s'%langs.log.sidebar, False)
return
else:
# Create HTML complete sidebar
@ -510,7 +519,9 @@ def create_sidebar(option):
def create_user_footer(option):
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
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
), True)
print('\n%s'%langs.site.footer_inf)
try: footer_f = open(dom.footer_f, 'r').read()
except: logs.out("1", dom.footer_f, True)

View File

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

View File

@ -23,50 +23,68 @@
# File: /var/lib/tyto/program/langs.py
#----------------------------------------------------------------------
#------------
# funny stats
#------------
# lines:
# functions:
# comments:
#----------------------------------------------------------------------
#-------------------------
# Funny Stats Project
#-------------------------
# file lines : 90
# file comments : 28
# file functions: 0
# file program : 53
#--------------------------
#**********************************************************************
import locale, sys, os, importlib
import dom
# Import translation directory
trans_dir = '/var/lib/tyto/translations'
sys.path.insert(0, trans_dir)
# Get default system language
# or set "en" (english) if no translation file
try:
site.yes
except:
# 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:
except:
lang_sys = 'en'
# Set language logs from configuration domain
# or set default english if not known
try:
# 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:
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:
# 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:
except:
site = importlib.import_module('site_%s'%lang_sys, package=None)

View File

@ -23,24 +23,31 @@
# File: /var/lib/tyto/program/logs.py
#----------------------------------------------------------------------
#------------
# funny stats
#------------
# lines:
# functions:
# comments:
#----------------------------------------------------------------------
#-------------------------
# Funny Stats Project
#-------------------------
# file lines : 127
# file comments : 23
# file functions: 1
# file program : 93
#--------------------------
#**********************************************************************
import os, sys
import langs
# Set colors
CS = '\033[0;0m'
CR = '\033[1;31m'
CY = '\033[1;33m'
CG = '\033[1;32m'
try:
shebang
except:
# 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 #
@ -97,6 +104,9 @@ def out(nbr, value, out):
'60' : '\n%s'%langs.log.status_r,
'61' : '%s%s%s > %s'%(CG, langs.log.file_e, 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),
'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),

View File

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

View File

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

View File

@ -24,19 +24,20 @@
# File: /var/lib/tyto/program/show.py
#----------------------------------------------------------------------
#------------
# funny stats
#------------
# lines:
# functions:
# comments:
#----------------------------------------------------------------------
#-------------------------
# Funny Stats Project
#-------------------------
# file lines : 216
# file comments : 39
# 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
#========================#
# Read lines from a file #
# alone: True/False #
@ -94,9 +95,6 @@ def manage(target):
try: post_www = db.post_www
except: pass
# Except for show-about > Show post DB
if args.action == "show-about":
target = 'post'
# Convert command action to do[]
@ -106,10 +104,9 @@ def manage(target):
"show" : 'src',
"edit" : 'src',
"post" : 'src',
"preview" : 'wip',
"show-db" : 'db',
"edit-db" : 'db',
"show-about" : 'about',
"edit-about" : 'about',
"show-wip" : 'wip',
"edit-wip" : 'wip',
"show-www" : 'www',
@ -136,14 +133,6 @@ def manage(target):
"sidebar" : dom.sidebar_f,
"post" : post_db
},
'about' : {
"domain" : dom.config,
"footer" : dom.footer_about_f,
"metas" : dom.metas_f,
"navbar" : dom.navbar_f,
"sidebar" : dom.sidebar_f,
"post" : post_db
},
'wip' : {
"domain" : dom.config,
"footer" : dom.wip_footer_f,
@ -151,6 +140,7 @@ def manage(target):
"navbar" : dom.wip_navbar_f,
"sidebar" : dom.wip_sidebar_f,
"post" : post_wip,
"sitemap" : '%ssitemap.html'%dom.srv_wip,
"stats" : dom.wip_stats_f,
},
'www' : {
@ -165,19 +155,25 @@ def manage(target):
}
# Read or edit file, according to legacy args.action
try:
file = do[action][target]
if not file:
logs.out("28", '%s + %s'%(args.action, args.target), True)
if args.action in actions_read:
if not file or not tyto.exists(file):
logs.out("1", file, True)
# Except for show-about > Show post DB
if args.action == "preview":
preview_wip(file)
return
elif args.action in actions_read:
read_lines(file, True)
elif args.action in actions_edit:
curr_hash = tyto.get_filesum(file, True)
tyto.edit_file(file)
except:
logs.out("28", '%s + %s'%(args.action, target), True)
# If edit article and hash changed, ask to check
if args.action == "edit":
@ -188,16 +184,33 @@ def manage(target):
# Launch process for some changed file
#-------------------------------------
if file == post_src:
form.asking('%s%s '%(
langs.site.post_chg, langs.site.q
), True)
# Reload post DB (if edited article, and check it if ask "y")
importlib.reload(db)
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.navbar_f: html.create_navbar('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
#----------------------------------------------------------------------
#------------
# funny stats
#------------
# lines:
# functions:
# comments:
#----------------------------------------------------------------------
#-------------------------
# Funny Stats Project
#-------------------------
# file lines : 226
# file comments : 38
# file functions: 4
# file program : 166
#--------------------------
#**********************************************************************
import os, importlib
import args, dom, logs, form, tyto, show, langs
sti_articles = 0
#=======================#

View File

@ -23,84 +23,155 @@
# File: /var/lib/tyto/program/status.py
#----------------------------------------------------------------------
#------------
# funny stats
#------------
# lines:
# functions:
# comments:
#----------------------------------------------------------------------
#-------------------------
# Funny Stats Project
#-------------------------
# file lines : 241
# file comments : 51
# file functions: 3
# file program : 170
#--------------------------
#**********************************************************************
import args, dom, logs, tyto, form, db
import os
import args, dom, logs
#=====================#
# Check domain status #
#---------------------#
def domain():
if dom.hole: logs.out("13", '', True)
elif args.action == 'new': return
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)
if dom.hole:
logs.out("13", '', True)
print("")
if dom.incomplete: logs.out("41", dom.shortname, False)
elif dom.active: logs.out("42", dom.shortname, False)
elif not dom.active: logs.out("40", dom.shortname, False)
# Only condition to not check domain status here
if args.action == 'new' and \
args.target == "domain":
return
# No backward in target
# As subprocesses, avoid show domain status each time
if args.action in args.quicks:
return
# [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:
logs.out("11", '"../"', True)
# Show unused values
for err_val in dom.err_val:
logs.out("16", err_val, False)
# Missing directories (was created)
for dir_new in dom.dir_new:
logs.out("33", dir_new, 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))
# wip directories
if value.endswith('_d'):
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_files = \
{
'navbar_f' : form.create_navbar,
'sidebar_f' : form.create_sidebar,
'metas_f' : form.create_metas,
'footer_f' : form.create_footer,
'footer_about_f': form.create_footer_about
}
import html
for value in dom.file_mod:
create_files[value]('form')
if not tyto.exists(dom.metas_f) or \
not tyto.exists(dom.wip_metas_f):
html.create_user_metas('new')
for file_mods in dom.wip_html_mods:
if not tyto.exists(file_mods):
logs.out("1", file_mods, False)
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')
#==============================#
# On demand with status action #
#------------------------------#
def check(target):
import db
# target needed
if not target:
logs.out("5", '[target]', True)
# Domain statuses
elif target == "domain":
conf_err = False
if dom.dir_unu or dom.file_unu:
# Check unused files in servers
logs.out("60", '', False)
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)
check_domain_files("wip")
check_domain_files("www")
return
# target is an article
@ -148,3 +219,23 @@ def check(target):
elif not db.exists:
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
#----------------------------------------------------------------------
#------------
# funny stats
#------------
# lines:
# functions:
# comments:
#----------------------------------------------------------------------
#-------------------------
# Funny Stats Project
#-------------------------
# file lines : 725
# file comments : 121
# file functions: 14
# file program : 522
#--------------------------
#**********************************************************************
import os, sys, re, subprocess, locale, base64, datetime, shutil
from hashlib import blake2b
import args, dom, logs, langs
# :D
Tyto = 'Tyto - Littérateur'
Tytogit = 'https://git.a-lec.org/echolib/tyto-litterateur'
@ -45,128 +46,210 @@ Tytoweb = 'https://tyto.echolib.re'
# Needed header tags
needed_header_tags = \
(
'title',
'about',
'author',
'tags',
'date'
)
(
'title',
'about',
'author',
'tags',
'date'
)
# Optional header tags
opt_header_tags = \
(
'file',
'image',
'link',
'abbr',
'raw',
'code',
'snpic'
)
(
'file',
'image',
'link',
'abbr',
'raw',
'code',
'snpic'
)
opt_tags_long_name = \
(
'link',
'file'
)
(
'link',
'file'
)
opt_tags_check_uri = \
(
'image',
'file',
'raw',
'code'
)
(
'image',
'file',
'raw',
'code'
)
# Set all tags used in article's header
headers = \
(
'title:',
'about:',
'author:',
'tags:',
'date:',
'link:',
'image:',
'file:',
'abbr:',
'code:',
'raw:',
'#',
'snpic:',
)
(
'title:',
'about:',
'author:',
'tags:',
'date:',
'link:',
'image:',
'file:',
'abbr:',
'code:',
'raw:',
'#',
'snpic:',
)
# Words and template Tags (paragraphs, lists, bold, strong...)
# Words Tags (paragraphs, lists, bold, strong...)
# 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.
# [6] = Check content differently. 't' = startswith
#-------------------------------------------------------------
words_tags = [
('>_', '_<',
'<a class="anchor_link" href="#%s">',
'</a>', 'anchors', 'w'
),
('*_', '_*', '<strong class="strong">', '</strong>', 'strongs', 'w'),
('+_', '_+', '<b class="bold">', '</b>', 'bolds', 'w'),
(';_', '_;', '<em class="em">', '</em>', 'emphasis', 'w'),
(':_', '_:', '<i class="italic">', '</i>', 'italics', 'w'),
('~_', '_~', '<del class="del">', '</del>', 'dels', 'w'),
('._', '_.', '<u class="underline">', '</u>', 'underlines', 'w'),
('[_', '_]', '<cite class="cite">', '</cite>', 'cites', 'w'),
('%_', '_%', '<span class="custom">', '</span>', 'customs', 'w'),
('{_', '_}', '<code class="icode">', '</code>', 'codes', 'w'),
]
icode_tags = \
(
'{_', '_}',
'<code class="icode">', '</code>',
'icodes',
'\\{_', '\\_}'
)
strong_tags = \
(
'*_', '_*',
'<strong class="%s">'%dom.css, '</strong>',
'strongs',
'\\*_', '\\_*',
'-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
block_tags = \
[
('((', '))', '<p class="%s">', '</p>', 'paragraphs'),
('[[', ']]', '[[', ']]', 'quotes'),
('{{', '}}', '{{', '}}', 'bcodes'),
('-(', '-)', '-(', '-)', 'lists'),
('<<', '>>', '<div class="%s">', '</div>', 'div'),
block_tags = [
('((', '))', '<p class="%s">', '</p>', 'paragraphs'),
('[[', ']]', '[[', ']]', 'quotes'),
('{{', '}}', '{{', '}}', 'bcodes'),
('-(', '-)', '-(', '-)', 'lists'),
('<<', '>>', '<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
#-----------------------------------
single_tags = [
('|', '<br class="%s" />'), # New Line
('->', '<a class="anchor_target" id="%s"></a>'), # Anchors
('|', '<br class="%s">'), # New Line
('->', '<a class="anchor_target" id="%s"></a>'), # Anchors
]
# When counting words, do no count line starting with:
nolinewords = \
(
block_tags[0][0], block_tags[0][1], # paragraphs
block_tags[1][0], block_tags[1][1], # quotes
block_tags[2][0], block_tags[2][1], # bcodes
block_tags[3][0], block_tags[3][1], # lists
single_tags[0][0], single_tags[1][0], # New line, anchor
'_%s:'%opt_header_tags[1], '_%s:'%opt_header_tags[4], # _image:, _raw:
'_%s:'%opt_header_tags[5] # _code
)
(
block_tags[0][0], block_tags[0][1], # paragraphs
block_tags[1][0], block_tags[1][1], # quotes
block_tags[2][0], block_tags[2][1], # bcodes
block_tags[3][0], block_tags[3][1], # lists
single_tags[0][0], single_tags[1][0], # New line, anchor
'_%s:'%opt_header_tags[1], '_%s:'%opt_header_tags[4], # _image:, _raw:
'_%s:'%opt_header_tags[5] # _code
)
# warning symbols (Check if paired)
#----------------------------------
tpl_tags = [
('(', ')'),
('[', ']'),
('{', '}'),
('«', '»'),
('(', ')'),
('[', ']'),
('{', '}'),
('«', '»'),
]
# When including HTML in article, check some paired tags
#-------------------------------------------------------
leg_html_tags = [
('<!--', '-->'),
('<div', '</div>'),
('<ul', '</ul>'),
('<li', '</li>'),
('<p', '</p>'),
('<span','</span>'),
('<!--', '-->'),
('<div', '</div>'),
('<ul', '</ul>'),
('<li', '</li>'),
('<p', '</p>'),
('<span','</span>'),
]
@ -176,35 +259,68 @@ markers_lists = ('+', '=', ' ', '#')
# 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
quote_tags = [
('_cite:', 'author'),
('_date:', 'date'),
('_link:', 'link'),
('_book:', 'book'),
('_lang:', 'lang')
('_cite:', 'author'),
('_date:', 'date'),
('_link:', 'link'),
('_book:', 'book'),
('_lang:', 'lang')
]
# Tags to check in header in content _TAG
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
chrs_invalid = \
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
nbr_icodes = 0
@ -238,9 +354,6 @@ def convert_altname(altname):
# False = URI #
#-----------------------#
def get_filesum(path, src):
#if not src and not exists(path):
# logs.out("1", path, True)
file_sum = blake2b(digest_size=4)
if src: file_sum.update(open(path, 'rb').read())
@ -312,6 +425,29 @@ def get_css(line):
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 #
# 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 line:
continue
elif line.startswith('#') and not line.startswith(titles_tags):
elif line.startswith('#') and not line.startswith(titles_user):
continue
# bcode convertion to base64
@ -386,11 +522,14 @@ def protect_bcodes_quotes(process, post_bottom):
if not bcode: bcode = line
else: bcode = '%s\n%s'%(bcode, line)
line = ''
continue
elif in_quote:
# Convert lines to b64
if not quote: quote = line
else: quote = '%s\n%s'%(quote, line)
line = ''
continue
# Set new content
@ -407,56 +546,70 @@ def protect_bcodes_quotes(process, post_bottom):
if close_quote: quote = b64_quote = ''
#=======================#
#=======================================#
# Protec iCodes #
# Used in check and wip #
#-----------------------~
# Methode: iterate (c)haracter in lines #
# check: remove icdoe #
# wip: convert to b64 #
#---------------------------------------#
def protect_icodes(post_bottom):
global protect_article
global nbr_icodes
protect_article = post_bottom
in_icode = False
src_code = rep_code = ''
# Get only lines that contains code
in_icode = ok_icode = go_icode = False
for ln, line in enumerate(post_bottom.rsplit('\n')):
if not words_tags[9][0] in line: continue
if not icode_tags[0] in line or \
not icode_tags[1] in line:
continue
# Iterate (c)haracter in line
code = ""
for i, c in enumerate(line):
c_b = c_bb = c_a = ""
if c == '_':
c_b = line[i-1] # before
c_bb = line[i-2] # before, before
c_a = line[i+1] # after
# incode if
if c_b == '{' and not c_bb == '\\':
if c == "_":
try:
# {_
if line[i-1] == icode_tags[0][0] and line[i-2] != "\\":
in_icode = True
nbr_icodes += 1
code = words_tags[9][2]
ok_icode = False
#go_icode = True
continue
# No more in code if
if c_a == '}' and not c_b == '\\':
# _}
elif line[i+1] == icode_tags[1][1] and line[i-2] != "\\":
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 = ''
ok_icode = True
go_icode = False
except:
continue
# Construct original replacement code and source code
if in_icode:
rep_code = '%s%s'%(rep_code, c)
if c == '\\': continue
src_code = '%s%s'%(src_code, c)
ok_icode = False
code = "%s%s"%(code, c)
# End icode
if ok_icode:
nbr_icodes += 1
tyto_code = "%s%s%s"%(icode_tags[0], code, icode_tags[1])
if args.action == "check":
post_bottom = \
post_bottom = post_bottom.replace(tyto_code , '')
elif args.action == "wip":
code = convert_altname(code) # HTML 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
#----------------------------------------------------------------------
#------------
# funny stats
#------------
# lines:
# functions:
# comments:
#----------------------------------------------------------------------
#-------------------------
# Funny Stats Project
#-------------------------
# file lines : 1110
# file comments : 167
# 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
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
# wip_article(db.post_src) ; return # Force wip without checking
if not target:
logs.out("5", '[target]', True)
# option --force to check and wip processes
if args.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:
do = {
'updated' : wip_all,
@ -144,7 +168,8 @@ def wip_article(target):
# Convert file to strings
file_to_string(target)
print('\n ├ [%s] > %s'%(db.title, db.post_src))
#print(' │\n')
db.show_title()
global post_header
global post_bottom
@ -156,11 +181,13 @@ def wip_article(target):
# Protect inline-codes
if db.icodes > 0:
tyto.protect_icodes(post_bottom)
post_bottom = tyto.protect_article
post_bottom = tyto.protect_icodes(post_bottom)
# Replace escaped markers
post_bottom = tyto.protect_escaped(post_bottom, False)
# Convert contents from modules
wip_clean_lines() # Remove comments and empty lines
wip_images() # Images_%i from headers in DB
wip_single_tags() # br /, anchors
wip_words_tags() # Paragraphs, strongs, italics
@ -169,6 +196,9 @@ def wip_article(target):
wip_titles() # Convert #N, remove empty line, add divs
wip_lists() # convert ul/ol lists
wip_quotes() # Quotes. Decode base64 Q64 and convert to HTML
# Replace escaped markers
post_bottom = tyto.protect_escaped(post_bottom, True)
wip_icodes() # inline_codes. Decode base64 icode and replace
wip_filecode(target) # Read file and convert to HTML
wip_bcodes() # Block-codes. Decode B64 and convert to HTML
@ -223,6 +253,31 @@ def file_to_string(post_file):
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 #
# including modules contents in HTML page #
@ -240,7 +295,7 @@ def wip_static():
wip_module = open(module, 'r').read()
wip_html_post = \
wip_html_post.replace(
tyto.tags_html_mods[module],
html.tags_html_mods[module],
wip_module
)
tyto.set_file(db.post_wip, "New", wip_html_post)
@ -255,6 +310,8 @@ def wip_static():
#---------------------------------------------------------------#
def replace_in_post(src, html):
global post_bottom
if src in post_bottom:
post_bottom = post_bottom.replace(src, html)
@ -282,21 +339,7 @@ def wip_single_tags():
#----------------------------------#
def wip_words_tags():
# Strongs, italics...
# (Stop after 8 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
for tag in tyto.markers_tags:
# Open tag
replace_in_post(tag[0],
tag[2]
@ -305,7 +348,6 @@ def wip_words_tags():
replace_in_post(tag[1],
tag[3]
)
m += 1
for ln, line in enumerate(post_bottom.rsplit('\n')):
@ -339,18 +381,45 @@ def wip_words_tags():
anchor_links = re.findall(r'>_(.+?):', line)
for item in anchor_links:
anchor_id = '%s%s:'%(tyto.words_tags[0][0], item)
anchor_id = '%s%s:'%(tyto.anchor_tags[0], item)
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 #
# Get arrays, in DB #
# sort all links by length #
# (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 #
# from marker to HTML #
#------------------------#
#-------------------------#
def wip_links():
if db.uniq_files == 0 and db.uniq_links == 0: return
@ -361,24 +430,34 @@ def wip_links():
# ! Doing link files, first, becase of similar marker
#----------------------------------------------------
if db.uniq_files > 0:
for i in range(1, db.uniq_files + 1):
link = 'db.file_%s'%i
link_css = "link_file"
link_name = eval(link)[0][2:]
link_anc = eval(link)[1]
link_title = eval(link)[2]
link_set = link_html%(
link_css, link_anc, link_title, "%s", link_name
links = wip_return_link_nbr("file", db.uniq_files)
for i in links:
if not i:
return
flink = 'db.file_%s'%i
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(link)[0], link_set%link_ts)
replace_in_post(eval(flink)[0]+'+', flink_set%link_tb)
replace_in_post(eval(flink)[0], flink_set%link_ts)
# Convert simple links
#---------------------
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_css = "link"
link_name = eval(link)[0][1:]
@ -425,6 +504,7 @@ def get_wh_image(value):
if not sizes[0][1]: return('%spx'%value)
else: return(value)
#=================================#
# Find all _image, get parameters #
# Convert _images:%name to HTML #
@ -483,7 +563,7 @@ def wip_images():
else:
style = ''
# set <img /> from parameter
# set <img> from parameter
image_target = eval(image)[1]
image_target = db.sub_uri + image_target[1:]
image_src = image_show%(
@ -517,6 +597,7 @@ def quote_params(qline):
globals()[tag[1]] = qline.rsplit('%s '%tag[0])[1].lstrip()
return(True)
#==========================#
# Convert quote in article #
#--------------------------#
@ -720,74 +801,68 @@ def wip_bcodes():
#========================================#
# Convert titles to HTML #
# Check between titles to set div or not #
# #1 = <h3>, #2 = <h4>... #
#----------------------------------------#
def wip_titles():
if db.titles == 0: return
global post_bottom
article_temp = post_bottom
article_tmp2 = '' # Construct article, without empty lines
for line in post_bottom.rsplit('\n'):
if line.startswith('#'):
hx = line[1]
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)
if line.startswith(tyto.titles_user):
tx = line[1]
title_name = line[2: len(line)].lstrip()
title_html = tyto.titles_tags[int(tx)][1]%title_name
replace_in_post(line, title_html)
wip_titles_div()
# Remove useless empty lines from article
for line in article_temp.rsplit('\n'):
if line:
if article_tmp2: article_tmp2 = '%s\n%s'%(article_tmp2, line)
else: article_tmp2 = line
#======================================#
# Create div between titles if content #
#--------------------------------------#
def wip_titles_div():
global post_bottom
article_temp = article_tmp2
article_tmp = ''
# Add div after title if needed
for ln, line in enumerate(article_tmp2.rsplit('\n')):
if line.startswith('<h'):
try: article_tmp2.rsplit('\n')[ln + 1]
except: continue
div_close = False
for ln, line in enumerate(post_bottom.rsplit('\n')):
# Remove empty lines
if not line: 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:
div_open = False
# Title <hX> found
if line.startswith(tyto.titles_html):
hx = line[2]
# Div need to be close vefore title
if div_close:
line = '</div>\n%s'%line
div_close = False
# Has content after, open div
try:
post_bottom.rsplit('\n')[ln + 1]
div_open = True
except:
continue
# Close div before title if needed
article_tmp2 = article_temp
indiv = False
for ln, line in enumerate(article_tmp2.rsplit('\n')):
try: article_tmp2.rsplit('\n')[ln + 1]
except: continue
# New div
if div_open:
line = '%s\n<div class="contents contents_%s">'%(line, hx)
div_close = True
if line.startswith('<h') and indiv:
article_temp = \
article_temp.replace(line,
'</div>\n%s'%line
)
indiv = False
# 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 article_tmp2.rsplit('\n')[ln + 1].startswith('<div'):
indiv = True
continue
# Close last div (if any)
if div_close:
article_tmp = "%s\n</div>"%(article_tmp)
if indiv:
article_temp = '%s\n</div>'%article_temp
# Replace article with new contents
post_bottom = article_temp
post_bottom = article_tmp
#==============================================#
@ -951,8 +1026,10 @@ def wip_fileraws(target):
for i in range(1, db.uniq_raws + 1):
raw = 'db.raw_%s'%i
raw_file = open('%s%s'%(dom.articles_d, eval(raw)[1])).read()
raw_alt = ""
if eval(raw)[2]:
raw_alt = ' # %s'%eval(raw)[2]
raw_inc = '<!--Tyto_Include file%s-->'%raw_alt
for line in raw_file.rsplit('\n'):

View File

@ -18,10 +18,10 @@ time_t = '<time> tag'
metas = 'Metas Tags'
footer = 'Footer'
line = "Ligne"
no_up = "not updated"
ntd = "Nothing to do"
all_ok = "All is OK"
nonewpost = "No new article"
unused_r = "Unused ressource"
unused_c = "Unused database value"
db_inv = "Corrupted article's database"
@ -41,14 +41,18 @@ file_n = "File changed"
file_e = "File exists"
dir_c = "Directory created"
dir_e = "Directory exists"
post_exists = "Ab article already exists"
# chk
shebang_r= 'Remove shebang'
nycheck = "Article not yet checked"
was_chk = "Article was 'check'"
st_chk_o = "Old 'check' status"
post_inc = "Unused in article"
post_inv = "Article not valid"
post_val = "Article is valid"
title_no = "Empty title"
unused_p = "Empty article"
# wip
nywip = "Article not yet wip"
@ -71,7 +75,6 @@ post_chg = "Article changed: 'check' it first"
sep_inv = "Unused separator in article"
unused_v = "Unused value in article"
unused_t = "Unused value in header"
unused_p = "Empty article"
mark_np = "Not paired marks"
symb_np = "Not paired symbols"
snpic_d = "Using default snpic. Not found"

View File

@ -18,10 +18,10 @@ time_t = 'Balise <time>'
metas = 'Balises Metas'
footer = "Pied de Page"
line = "Line"
no_up = "non mise à jour"
ntd = "Rien à faire"
all_ok = "Tout va bien"
nonewpost = "Rien de nouveau"
unused_r = "Ressource manquante"
unused_c = "Valeur de la base de donnée manquante"
db_inv = "Base de donnée de l'article corrompue"
@ -40,24 +40,26 @@ file_n = "Fichier modifié"
file_e = "Fichier présent"
dir_c = "Dossier créé"
dir_e = "Dossier présent"
post_exists = "Un article existe déjà"
# chk
shebang_r= 'Enlever le shebang'
nycheck = "Article pas encore 'check'"
was_chk = "Article déjà vérifié"
st_chk_o = "Statut 'check' Ancien"
post_inc = "Donnée manquante dans l'article"
post_inv = "Article non valide"
post_val = "Article valide"
title_no = "Titre vide"
unused_p = "Article vide"
# Wip
nywip = "Article pas encore 'wip'"
was_wip = "Article déjà 'wip'"
# www
was_pub = "Article déjà publié"
# Misc
post_nfd = "Page non 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"
unused_v = "Valeur manquante dans l'article"
unused_t = "Valeur manquante dans l'entête"
unused_p = "L'article est vide"
mark_np = "Marqueurs non jumelés"
symb_np = "Symboles non jumelés"
snpic_d = "snpic utilisé par défaut. Manquant"

View File

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

View File

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