Release 0.9.0
arguments "all", "again", "newer" with wip/publish. Invert item in RSS (newest... See merge request echolib/tyto-litterateur!3
This commit is contained in:
commit
4aba6ee8d3
18
CHANGELOG.md
18
CHANGELOG.md
|
@ -1,16 +1,10 @@
|
|||
# Changelog
|
||||
|
||||
Tyto - Littérateur
|
||||
- Repository: https://git.a-lec.org/echolib/tyto
|
||||
- Issues: https://git.a-lec.org/echolib/tyto/-/issues
|
||||
- Changelog: https://git.a-lec.org/echolib/tyto/-/blob/main/CHANGELOG.md
|
||||
- License: https://git.a-lec.org/echolib/tyto/-/blob/main/LICENSE
|
||||
|
||||
Tyto - Litterateur is a Libre project to create and manage multiple
|
||||
websites from articles' files. Tyto uses its own syntax to convert
|
||||
your articles in HTML5 static pages. Tyto works on a GNU/Linux system
|
||||
and needs minimal dependancies.
|
||||
- python3 rsync nano gawk curl
|
||||
|
||||
## [0.9.0] First Commit version (pre-final)
|
||||
- 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
|
||||
|
||||
## [0.9.0]
|
||||
- Last testings before final
|
||||
|
|
|
@ -1,21 +0,0 @@
|
|||
# Installation manuelle
|
||||
|
||||
Si vous utilisez Debian, il est plus que recommandé de procéder à
|
||||
l'installation par le paquet .deb
|
||||
|
||||
## Préparer les dossiers
|
||||
````
|
||||
sudo mkdir -p /var/lib/tyto /etc/tyto /var/log/tyto
|
||||
sudo touch /usr/local/bin/tyto
|
||||
sudo chown -R USER:GROUP /var/lib/tyto /etc/tyto /var/log/tyto
|
||||
sudo chown USER:GROUP /usr/local/bin/tyto
|
||||
sudo chmod +x /usr/local/bin/tyto
|
||||
|
||||
git clone https://git.a-lec.org/echolib/tyto
|
||||
rsync -a folders'repo/ to /folders/
|
||||
|
||||
# Créer votre dossier pour le serveur web
|
||||
# On utilise en général /var/www/
|
||||
# Celui-ci sera à renseigner lors de la création d'un domaine dans Tyto
|
||||
sudo mkdir -p /var/www/
|
||||
````
|
|
@ -0,0 +1,32 @@
|
|||
#!/bin/bash
|
||||
|
||||
# file: Makefile
|
||||
|
||||
# By neox
|
||||
|
||||
# License: GNU AFFERO GENERAL PUBLIC LICENSE Version 3, 19 November 2007
|
||||
|
||||
default: debian/tyto.deb
|
||||
|
||||
### MAKE DEB
|
||||
|
||||
.INTERMEDIATE: debian/debian-binary debian/control.tar.gz debian/data.tar.gz
|
||||
|
||||
.PHONY: clean
|
||||
|
||||
debian/tyto.deb: debian/debian-binary debian/control.tar.gz debian/data.tar.gz
|
||||
ar -r debian/tyto.deb debian/debian-binary debian/control.tar.gz debian/data.tar.gz
|
||||
|
||||
debian/data.tar.gz:
|
||||
cd src && tar czvf ../debian/data.tar.gz usr var
|
||||
|
||||
debian/control.tar.gz:
|
||||
tar czvf debian/control.tar.gz debian/control #preinst postinst prerm postrm
|
||||
|
||||
debian/debian-binary:
|
||||
echo 2.0 > debian/debian-binary
|
||||
|
||||
clean:
|
||||
-rm debian/*.tar.gz
|
||||
-rm debian/debian-binary
|
||||
-rm debian/*.deb
|
238
README.md
238
README.md
|
@ -1,5 +1,243 @@
|
|||
# Tyto
|
||||
Pour obtenir de l'aide, taper juste la commande tyto
|
||||
|
||||
## Répertoire de code du projet Tyto
|
||||
TODO
|
||||
|
||||
## 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)
|
||||
|
||||
# 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
|
||||
|
||||
# Source
|
||||
#1 Titre 1
|
||||
Contenu 1
|
||||
|
||||
#2 Titre 2
|
||||
|
||||
#3 Titre 3
|
||||
contenu 2
|
||||
|
||||
#4 Titre 4
|
||||
|
||||
# HTML
|
||||
<h1 class="title_1">Titre 1</h1>
|
||||
<div class="content_title">
|
||||
Contenu 1
|
||||
</div>
|
||||
<h2 class="title_2">Titre 2</h2>
|
||||
<h3 class="title_3">Titre 3</h3>
|
||||
<div class="content_title">
|
||||
contenu 2
|
||||
</div>
|
||||
<h4 class="title_4">Titre 4</h4>
|
||||
```
|
||||
|
||||
### 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
|
||||
|
||||
# HTML
|
||||
<a href="id2"></a>
|
||||
|
||||
# Source de l'ancre d'appel
|
||||
# Définir l'identité cible et le texte du lien
|
||||
((
|
||||
>_id:Retourner au point d'ancre id_<
|
||||
))
|
||||
|
||||
# HTML
|
||||
<a class="anchor" href="#id">Retourner au point d'ancre id</a>
|
||||
```
|
||||
|
||||
### Retour à la ligne HTML
|
||||
```
|
||||
# Source
|
||||
|
|
||||
|
||||
# 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 Nom identique pour les marqueur `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
|
||||
_lang: fr
|
||||
_link: https://tyto.echolib.re
|
||||
_book: Référence
|
||||
((
|
||||
Pfff, vraiment !
|
||||
))
|
||||
]]
|
||||
|
||||
# HTML
|
||||
<figure class="CSS_TEST">
|
||||
<blockquote class="CSS_TEST" lang="fr" cite="https://tyto.echolib.re" title="echolib - Reference (2022-12-28)">
|
||||
<time datetime="2022-12-28">
|
||||
<p class="tyto">
|
||||
Pfff, vraiment !
|
||||
</p>
|
||||
</time>
|
||||
</blockquote>
|
||||
<figcaption class="CSS_TEST">
|
||||
<a class="figc" href="https://tyto.echolib.re">echolib - Reference (2022-12-28)</a>
|
||||
</figcaption>
|
||||
</figure>
|
||||
````
|
||||
```
|
||||
# Source: citation basique
|
||||
[[
|
||||
Une citation simple, et sans paragraphe
|
||||
]]
|
||||
|
||||
# HTML
|
||||
<blockquote class="tyto">
|
||||
Une citation simple, et sans paragraphe
|
||||
</blockquote>
|
||||
```
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
Package: tyto
|
||||
Version: 0.9.0
|
||||
Section: custom
|
||||
Priority: optional
|
||||
Architecture: all
|
||||
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.
|
|
@ -0,0 +1,91 @@
|
|||
#!/usr/bin/env python3
|
||||
# Version: 0.9.0
|
||||
# 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: Main binary to execute
|
||||
# File: /usr/bin/tyto
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
#------------
|
||||
# funny stats
|
||||
#------------
|
||||
# scripts files:
|
||||
# app lines:
|
||||
# app comments:
|
||||
# app functions:
|
||||
# lines:
|
||||
# functions:
|
||||
# comments:
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
#**********************************************************************
|
||||
|
||||
import sys
|
||||
sys.path.insert(0, '/var/lib/tyto/program')
|
||||
|
||||
|
||||
#====================#
|
||||
# MAIN #
|
||||
# Treat Arguments #
|
||||
#--------------------#-------------------------------------------------
|
||||
import logs
|
||||
|
||||
if not __name__ == "__main__":
|
||||
logs.out("14", '', True)
|
||||
|
||||
# Check arguments
|
||||
import args
|
||||
action = args.set_action()
|
||||
target = args.set_target()
|
||||
|
||||
# Check domain
|
||||
import dom, status
|
||||
status.domain()
|
||||
|
||||
|
||||
# Command start argument
|
||||
import check, form, html, new, publish, show, wip, infos
|
||||
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,
|
||||
}
|
||||
|
||||
|
||||
# Start action
|
||||
# Argument's Check done in args.py
|
||||
#---------------------------------
|
||||
actions[action](target)
|
||||
|
|
@ -1,99 +0,0 @@
|
|||
#!/usr/bin/env python3
|
||||
# Version: 0.9.0
|
||||
# Name: Tyto - Littérateur
|
||||
# Type: Executable
|
||||
# Description: Multiple Static Websites generator and manager
|
||||
# file: tyto
|
||||
# Folder: /usr/local/bin/
|
||||
# By echolib (XMPP: im@echolib.re)
|
||||
# Repo: https://git.a-lec.org/echolib/tyto.git
|
||||
# License: GNU AFFERO GENERAL PUBLIC LICENSE Version 3, 19 November 2007
|
||||
|
||||
#------------
|
||||
# funny stats
|
||||
#------------
|
||||
# scripts files:
|
||||
# app lines:
|
||||
# app comments:
|
||||
# app functions:
|
||||
# lines:
|
||||
# functions:
|
||||
# comments:
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
'''
|
||||
All scripts are in /var/lib/tyto/program/
|
||||
Directories that must be writeable by Tyto
|
||||
- /var/lib/tyto/db/
|
||||
- /var/log/tyto/
|
||||
- /[LOCAL Server]/ (registred per domain)
|
||||
'''
|
||||
|
||||
#**********************************************************************
|
||||
|
||||
# Import needed libs and tyto's libs
|
||||
import sys
|
||||
sys.path.insert(0, '/var/lib/tyto/program')
|
||||
import check, wip, domain, log
|
||||
|
||||
#=======#
|
||||
# Tools #
|
||||
#=======#--------------------------------------------------------------
|
||||
#=======================================#
|
||||
# Check argument from main command line #
|
||||
# # total arguments #
|
||||
#---------------------------------------#
|
||||
def tyto_args(ta):
|
||||
global file_post, Opt
|
||||
Domain = False
|
||||
Opt = ''
|
||||
Target = ''
|
||||
|
||||
# Start process accoring to first argument action
|
||||
Actions = { 'check' : check.manage_check,
|
||||
'wip' : wip.manage_wip,
|
||||
'domain' : domain.manage_domain,
|
||||
'log' : log.manage_log
|
||||
}
|
||||
|
||||
# Dict for Options
|
||||
Options = {
|
||||
'-R' : "Remove", 'remove' : "Remove",
|
||||
'-n' : "New", 'new' : "New",
|
||||
'-e' : "Edit", 'edit' : "Edit",
|
||||
'-F' : "Force", 'force' : "Force"
|
||||
}
|
||||
|
||||
# Set Opt from other arguments options
|
||||
# Set Target for article or new domain name
|
||||
if sys.argv[1] == 'domain': Domain = True
|
||||
|
||||
for i in range(2, ta):
|
||||
if sys.argv[i].endswith('.tyto'):
|
||||
Target = sys.argv[i]
|
||||
if Target[0] == '/':
|
||||
Target = Target[1:len(Target)]
|
||||
else:
|
||||
try:
|
||||
Opt = Options[sys.argv[i]]
|
||||
except:
|
||||
if Domain:
|
||||
Target = sys.argv[i]
|
||||
else:
|
||||
print(':( Invalid option "%s"'%sys.argv[i])
|
||||
sys.exit(0)
|
||||
|
||||
try:
|
||||
Actions[sys.argv[1]](Target, Opt)
|
||||
except KeyError:
|
||||
print(':( Invalid action "%s"'%sys.argv[1])
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#====================#
|
||||
# MAIN #
|
||||
# Treat Arguments #
|
||||
#--------------------#-------------------------------------------------
|
||||
tyto_args(len(sys.argv))
|
|
@ -0,0 +1,16 @@
|
|||
# Changelog
|
||||
|
||||
Tyto - Littérateur
|
||||
- Repository: https://git.a-lec.org/echolib/tyto
|
||||
- Issues: https://git.a-lec.org/echolib/tyto/-/issues
|
||||
- Changelog: https://git.a-lec.org/echolib/tyto/-/blob/main/CHANGELOG.md
|
||||
- License: https://git.a-lec.org/echolib/tyto/-/blob/main/LICENSE
|
||||
|
||||
Tyto - Litterateur is a Libre project to create and manage multiple
|
||||
websites from articles' files. Tyto uses its own syntax to convert
|
||||
your articles in HTML5 static pages. Tyto works on a GNU/Linux system
|
||||
and needs minimal dependancies.
|
||||
- python3 rsync nano gawk curl
|
||||
|
||||
## [0.9.0] First Commit version (pre-final)
|
||||
|
|
@ -0,0 +1,167 @@
|
|||
# Tyto
|
||||
|
||||
## Répertoire de code du projet Tyto
|
||||
|
||||
## Comment définir les métas
|
||||
```
|
||||
# Obligatoires uniques
|
||||
title: Titre
|
||||
about: Infos de l'article
|
||||
author: Autheur
|
||||
tags: mots-clé-1,mots-clé-2
|
||||
date: YYYY-MM-DD (AAAA-MM-JJ)
|
||||
|
||||
# Optionnels myltiples
|
||||
link: Nom du lien
|
||||
URL
|
||||
Texte Alternatif
|
||||
|
||||
image: Nom
|
||||
URI
|
||||
Texte Alternatif
|
||||
|
||||
file: Nom du lien
|
||||
URL
|
||||
Texte Alternatif
|
||||
|
||||
brut: Nom
|
||||
URI
|
||||
Texte Alternatif
|
||||
|
||||
abbr: NOM (en majuscule)
|
||||
Définition du NOM
|
||||
nom (forme à afficher dans l'artile (optionnel))
|
||||
|
||||
# Séparateur d'au moins 5 "-" pour définir la fin
|
||||
# des métadonnées d'entête de l'article
|
||||
----------
|
||||
```
|
||||
|
||||
## Comment écrire un article
|
||||
### Titre h1 à h6
|
||||
```
|
||||
#1 Titre 1
|
||||
((
|
||||
Un paragraphe
|
||||
))
|
||||
|
||||
#2 Titre 2
|
||||
```
|
||||
|
||||
### Paragraphes
|
||||
```
|
||||
(( CSS
|
||||
Un paragraphe
|
||||
))
|
||||
```
|
||||
|
||||
### Code Brut
|
||||
```
|
||||
{{ CSS
|
||||
def hello_world():
|
||||
print("Hello")
|
||||
}}
|
||||
```
|
||||
|
||||
### Listes ul/ol
|
||||
```
|
||||
-( CSS
|
||||
= Liste ul
|
||||
== Sous-liste ul
|
||||
=== Sous-sous-liste ul
|
||||
++++ Sous-sous-sous-liste ol
|
||||
+++ Sous-sous-liste ol
|
||||
-)
|
||||
```
|
||||
|
||||
### Citations
|
||||
```
|
||||
[[ CSS
|
||||
_cite: autheur
|
||||
_lang: langue
|
||||
_link: lien
|
||||
_year: année ou date YYYY-MM-DD
|
||||
_book: référence
|
||||
((
|
||||
Citation placée dans un paragraphe
|
||||
))
|
||||
]]
|
||||
|
||||
[[ CSS
|
||||
Citation simple sans référence
|
||||
]]
|
||||
```
|
||||
|
||||
### Ancres
|
||||
```
|
||||
-> id
|
||||
((
|
||||
un long paragraphe
|
||||
))
|
||||
((
|
||||
>_id:Retourner au point d'ancre_<
|
||||
))
|
||||
```
|
||||
|
||||
### 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
|
||||
```
|
|
@ -0,0 +1,184 @@
|
|||
/*
|
||||
* All class / ID used by Tyto - Littérateur in a page
|
||||
* DOMAIN MUST be changed by domain css set in configuration
|
||||
*/
|
||||
|
||||
/*
|
||||
* Header
|
||||
*/
|
||||
header#header_page {
|
||||
}
|
||||
|
||||
div#site_logo {
|
||||
}
|
||||
|
||||
a#site_logo_link {
|
||||
}
|
||||
|
||||
img#site_logo_image {
|
||||
}
|
||||
|
||||
div#site_infos {
|
||||
}
|
||||
|
||||
a#site_link {
|
||||
}
|
||||
|
||||
h1#site_title {
|
||||
}
|
||||
|
||||
p#site_about {
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* navbar
|
||||
*/
|
||||
nav#site_menu {
|
||||
}
|
||||
|
||||
ul#site_menu_items {
|
||||
}
|
||||
|
||||
li.site_menu_item {
|
||||
}
|
||||
|
||||
a.site_menu_link {
|
||||
}
|
||||
|
||||
/*
|
||||
* article
|
||||
*/
|
||||
article#article_main {
|
||||
}
|
||||
|
||||
h1#main_title {
|
||||
}
|
||||
h2.title_2 {
|
||||
}
|
||||
h3.title_3 {
|
||||
}
|
||||
h4.title_4 {
|
||||
}
|
||||
h5.title_5 {
|
||||
}
|
||||
h6.title_6 {
|
||||
}
|
||||
|
||||
/* Between every <h2-6> IF CONTENTS */
|
||||
div.contents {
|
||||
}
|
||||
|
||||
/* Default if not set in post */
|
||||
p.DOMAIN {
|
||||
}
|
||||
|
||||
br.DOMAIN {
|
||||
}
|
||||
|
||||
a.link {
|
||||
}
|
||||
|
||||
a.anchor_link {
|
||||
}
|
||||
|
||||
abbr.DOMAIN {
|
||||
}
|
||||
|
||||
img.DOMAIN_image {
|
||||
}
|
||||
|
||||
code.icode {
|
||||
}
|
||||
|
||||
ul.DOMAIN {
|
||||
}
|
||||
li.DOMAIN
|
||||
|
||||
strong.strong {
|
||||
}
|
||||
b.bold {
|
||||
}
|
||||
em.em{
|
||||
}
|
||||
i.italic {
|
||||
}
|
||||
del.del {
|
||||
}
|
||||
u.underline {
|
||||
}
|
||||
cite.cite {
|
||||
}
|
||||
span.custom {
|
||||
}
|
||||
|
||||
/* Block_code */
|
||||
code.DOMAIN {
|
||||
}
|
||||
pre.bcode {
|
||||
}
|
||||
p.bcode {
|
||||
}
|
||||
|
||||
/* section for author and date */
|
||||
section#article_infos {
|
||||
}
|
||||
span#article_author {
|
||||
}
|
||||
span#article_pub {
|
||||
}
|
||||
span#article_code {
|
||||
}
|
||||
a#article_code_link {
|
||||
}
|
||||
|
||||
/*
|
||||
* sidebar
|
||||
*/
|
||||
|
||||
aside#sidebar {
|
||||
}
|
||||
h1#sidebar_title {
|
||||
}
|
||||
ul#sidebar_list {
|
||||
}
|
||||
li.sidebar_item {
|
||||
}
|
||||
a.sidebar_item_link {
|
||||
}
|
||||
h2.sidebar_item_title {
|
||||
}
|
||||
p.sidebar_item_about {
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* footer
|
||||
*/
|
||||
footer#footer_page {
|
||||
}
|
||||
/* Block*/
|
||||
div#footer_infos {
|
||||
}
|
||||
h1#footer_site_title {
|
||||
}
|
||||
p#footer_about {
|
||||
}
|
||||
/* Block */
|
||||
div#footer_references {
|
||||
}
|
||||
ul.footer_items {
|
||||
}
|
||||
li.footer_item {
|
||||
}
|
||||
a.footer_item_link {
|
||||
}
|
||||
/* Block */
|
||||
div#footer_credits {
|
||||
}
|
||||
p.footer_copyright {
|
||||
}
|
||||
p.footer_generator {
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,138 @@
|
|||
#!/usr/bin/env python3
|
||||
# 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: Manage arguments from command line
|
||||
# File: /var/lib/tyto/program/args.py
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
#------------
|
||||
# funny stats
|
||||
#------------
|
||||
# lines:
|
||||
# functions:
|
||||
# comments:
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
#**********************************************************************
|
||||
|
||||
import os, sys
|
||||
import infos
|
||||
|
||||
|
||||
# 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'
|
||||
)
|
||||
|
||||
pass_actions = (
|
||||
'new'
|
||||
|
||||
)
|
||||
|
||||
# Actions that needs to check for article's database
|
||||
pass_db = \
|
||||
(
|
||||
'check',
|
||||
'edit',
|
||||
'edit-db',
|
||||
'edit-wip',
|
||||
'edit-www',
|
||||
'publish',
|
||||
'show',
|
||||
'show-about',
|
||||
'show-db',
|
||||
'show-wip',
|
||||
'show-www',
|
||||
'status',
|
||||
'wip',
|
||||
)
|
||||
|
||||
pass_targets = \
|
||||
(
|
||||
'added',
|
||||
'again',
|
||||
'updated',
|
||||
'domain',
|
||||
'footer',
|
||||
'metas',
|
||||
'navbar',
|
||||
'sidebar',
|
||||
'stats',
|
||||
'template'
|
||||
)
|
||||
|
||||
pass_status = \
|
||||
(
|
||||
'domain',
|
||||
)
|
||||
|
||||
multi_chk = ('added', 'again', 'updated')
|
||||
|
||||
action = ''
|
||||
target = ''
|
||||
noaction = False
|
||||
|
||||
# action
|
||||
#-------
|
||||
try: action = sys.argv[1]
|
||||
except: noaction = True
|
||||
|
||||
# With no argument, show help
|
||||
if noaction:
|
||||
infos.tyto(target)
|
||||
sys.exit(0)
|
||||
|
||||
# Unused argument [action]
|
||||
act_err = False
|
||||
if not action in actions:
|
||||
act_err = True
|
||||
|
||||
|
||||
# target
|
||||
#-------
|
||||
try: target = sys.argv[2]
|
||||
except: target = ''
|
||||
|
||||
|
||||
# Set action and target for binary
|
||||
def set_action():
|
||||
return(action)
|
||||
|
||||
def set_target():
|
||||
return(target)
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,193 @@
|
|||
#!/usr/bin/env python3
|
||||
# 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: Load article's database and check validity
|
||||
# File: /var/lib/tyto/program/db.py
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
#------------
|
||||
# funny stats
|
||||
#------------
|
||||
# lines:
|
||||
# functions:
|
||||
# comments:
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
#**********************************************************************
|
||||
|
||||
import os
|
||||
import args, logs, dom, form, tyto, check, publish
|
||||
|
||||
remove = exists = post = corrupt = file_wip = file_www = False
|
||||
chk_again = chk_updated = False
|
||||
wip_again = wip_added = wip_updated = False
|
||||
www_again = www_added = www_updated = False
|
||||
|
||||
if dom.hole:
|
||||
logs.out("13", '', True)
|
||||
|
||||
|
||||
# target needs db (file).
|
||||
# action like show, wip, edit-db
|
||||
# not domain, all, again...
|
||||
if args.target \
|
||||
and args.action in args.pass_db \
|
||||
and not args.target in args.pass_targets:
|
||||
|
||||
# Domain must be valid
|
||||
if not dom.exists: logs.out("10", '', True)
|
||||
|
||||
uri_file = '%s%s'%(dom.articles_d, args.target)
|
||||
uri_id = tyto.get_filesum(uri_file, False)
|
||||
|
||||
# Set DB file
|
||||
config = '%s%s.config'%(dom.articles_db_d, uri_id)
|
||||
if tyto.exists(config):
|
||||
exists = True
|
||||
try:
|
||||
exec(open(config).read())
|
||||
except:
|
||||
exists = False
|
||||
else:
|
||||
exists = False
|
||||
|
||||
# Article file exists
|
||||
if tyto.exists(uri_file):
|
||||
post = True
|
||||
hash_post = tyto.get_filesum(uri_file, True)
|
||||
else:
|
||||
remove = True
|
||||
|
||||
# Check if database config is valid (contains values)
|
||||
if exists:
|
||||
values = \
|
||||
(
|
||||
'post_id',
|
||||
'post_src',
|
||||
'post_wip',
|
||||
'post_www',
|
||||
'direc_src',
|
||||
'short_src',
|
||||
'short_srv',
|
||||
'sub_uri',
|
||||
'http_wip',
|
||||
'http_www',
|
||||
'date_chk',
|
||||
'hash_chk',
|
||||
'date_wip',
|
||||
'hash_wip',
|
||||
'date_www',
|
||||
'hash_www',
|
||||
'title',
|
||||
'about',
|
||||
'author',
|
||||
'meta_tags',
|
||||
'date',
|
||||
'snpic',
|
||||
'uris',
|
||||
'uniq_anchors',
|
||||
'uniq_abbrs',
|
||||
'uniq_links',
|
||||
'uniq_images',
|
||||
'uniq_files',
|
||||
'uniq_raws',
|
||||
'comments',
|
||||
'tags',
|
||||
'words',
|
||||
'titles',
|
||||
'paragraphs',
|
||||
'links',
|
||||
'images',
|
||||
'anchors',
|
||||
'abbrs',
|
||||
'strongs',
|
||||
'bolds',
|
||||
'emphasis',
|
||||
'italics',
|
||||
'dels',
|
||||
'underlines',
|
||||
'cites',
|
||||
'customs',
|
||||
'icodes',
|
||||
'bcodes',
|
||||
'quotes',
|
||||
'lists',
|
||||
'files',
|
||||
'raws',
|
||||
'codes',
|
||||
)
|
||||
|
||||
# Set exist for wip and www files
|
||||
for value in values:
|
||||
try:
|
||||
eval(str(value))
|
||||
except:
|
||||
remove = True
|
||||
corrupt = True
|
||||
break
|
||||
|
||||
# Remove DB if unused source article or corrupted DB
|
||||
if remove and exists:
|
||||
os.remove(config)
|
||||
exists = False
|
||||
logs.out("23", config, False)
|
||||
|
||||
old_chk = old_wip = old_www = False
|
||||
no_chk = no_wip = no_www = False
|
||||
sync_srvs = False
|
||||
|
||||
# Set Statuses for chk, wip, www
|
||||
if exists:
|
||||
# File exists on servers
|
||||
if tyto.exists(post_wip): file_wip = True
|
||||
if tyto.exists(post_www): file_www = True
|
||||
|
||||
# Statuses not set in Db
|
||||
if not hash_chk: no_chk = True
|
||||
if not hash_wip: no_wip = True
|
||||
if not hash_www: no_www = True
|
||||
|
||||
# Source article has changed
|
||||
if hash_post != hash_chk: old_chk = chk_updated = True
|
||||
if hash_chk: chk_again = True
|
||||
|
||||
# WIP article is old
|
||||
if not old_chk:
|
||||
if hash_wip and hash_chk != hash_wip: old_wip = wip_updated = True
|
||||
if no_wip: wip_added = True
|
||||
if hash_wip: wip_again = True
|
||||
if not file_wip:
|
||||
old_wip = wip_updated = True
|
||||
wip_added = True
|
||||
wip_again = True
|
||||
|
||||
# WWW article is old
|
||||
if not old_wip:
|
||||
if hash_www and hash_www != hash_wip: old_www = www_updated = True
|
||||
if hash_www: www_again = True
|
||||
if no_www: www_added = True
|
||||
if not file_www:
|
||||
old_www = www_updated = True
|
||||
www_added = True
|
||||
www_again = True
|
||||
|
||||
# Article is updated on both servers
|
||||
if hash_chk == hash_wip == hash_www: sync_srvs = True
|
|
@ -0,0 +1,276 @@
|
|||
#!/usr/bin/env python3
|
||||
# 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: Load domain database and check validity
|
||||
# File: /var/lib/tyto/program/dom.py
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
#------------
|
||||
# funny stats
|
||||
#------------
|
||||
# lines:
|
||||
# functions:
|
||||
# comments:
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
#**********************************************************************
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
|
||||
if not hole:
|
||||
home_dir = os.path.expanduser('~')
|
||||
|
||||
# Set configuration domain directory
|
||||
root_dir = user_dir
|
||||
if '/articles' in user_dir:
|
||||
root_dir = user_dir.rsplit('/articles')[0] + "/"
|
||||
|
||||
# Set configuration domain file
|
||||
config = '%styto_domain.py'%root_dir
|
||||
shortname = config
|
||||
|
||||
# Set exists if configuration file
|
||||
if os.path.exists(config):
|
||||
exists = True
|
||||
try:
|
||||
exec(open(config).read())
|
||||
try:
|
||||
os.path.exists(articles_d)
|
||||
if '/articles' in user_dir:
|
||||
user_uri_dir = user_dir.rsplit(articles_d)[1]
|
||||
else:
|
||||
user_uri_dir = ''
|
||||
os.chdir(articles_d)
|
||||
except: corrupt = True
|
||||
except:
|
||||
corrupt = True
|
||||
|
||||
if not args.target in args.pass_targets:
|
||||
if args.target.startswith("articles/"):
|
||||
args.target = args.target.rsplit("articles/")[1]
|
||||
args.target = user_uri_dir + args.target
|
||||
|
||||
# For logs: show uri if not shortname known
|
||||
try: shortname
|
||||
except: pass
|
||||
|
||||
try: active = activated
|
||||
except: pass
|
||||
|
||||
if not corrupt:
|
||||
for value in dom_values:
|
||||
try:
|
||||
eval(str(value))
|
||||
value_set = True
|
||||
except:
|
||||
err_val = err_val + ((value),)
|
||||
value_set = False
|
||||
incomplete = True
|
||||
active = False
|
||||
|
||||
|
||||
if value.endswith('_d'):
|
||||
if value_set:
|
||||
if not os.path.exists(eval(str(value))):
|
||||
try:
|
||||
os.makedirs(eval(str(value)), exist_ok=True)
|
||||
dir_new = dir_new + ((eval(str(value))),)
|
||||
except:
|
||||
dir_unu = dir_unu + ((eval(str(value))),)
|
||||
|
||||
elif value.endswith('_f'):
|
||||
if value_set:
|
||||
if not os.path.exists(eval(str(value))):
|
||||
if value in create_files:
|
||||
file_mod = file_mod + ((value),)
|
||||
else:
|
||||
file_unu = file_unu + ((eval(str(value))),)
|
||||
|
||||
|
||||
#==============================================#
|
||||
# When an active and complete domain is needed #
|
||||
#----------------------------------------------#
|
||||
if exists and not incomplete and not corrupt:
|
||||
wip_html_mods = \
|
||||
(
|
||||
eval(str('wip_navbar_f')),
|
||||
eval(str('wip_sidebar_f')),
|
||||
eval(str('wip_metas_f')),
|
||||
eval(str('wip_footer_f'))
|
||||
)
|
||||
if active:
|
||||
ready = True
|
||||
|
||||
metas = (
|
||||
eval(str('metas_f')),
|
||||
eval(str('wip_metas_f')),
|
||||
eval(str('www_metas_f'))
|
||||
)
|
||||
navbars = (
|
||||
eval(str('navbar_f')),
|
||||
eval(str('wip_navbar_f')),
|
||||
eval(str('www_navbar_f'))
|
||||
)
|
||||
sidebars = (
|
||||
eval(str('sidebar_f')),
|
||||
eval(str('wip_sidebar_f')),
|
||||
eval(str('www_sidebar_f'))
|
||||
)
|
||||
footers = (
|
||||
eval(str('footer_f')),
|
||||
eval(str('wip_footer_f')),
|
||||
eval(str('www_footer_f')),
|
||||
eval(str('footer_about_f'))
|
||||
)
|
||||
|
||||
templates = (
|
||||
eval(str('wip_logo_f')),
|
||||
eval(str('wip_css_f')),
|
||||
eval(str('wip_navbar_f')),
|
||||
eval(str('wip_sidebar_f')),
|
||||
eval(str('wip_metas_f')),
|
||||
eval(str('wip_footer_f')),
|
||||
eval(str('wip_stats_f')),
|
||||
eval(str('www_logo_f')),
|
||||
eval(str('www_css_f')),
|
||||
eval(str('www_navbar_f')),
|
||||
eval(str('www_sidebar_f')),
|
||||
eval(str('www_metas_f')),
|
||||
eval(str('www_footer_f')),
|
||||
eval(str('www_stats_f')),
|
||||
eval(str('www_rss_f')),
|
||||
)
|
||||
|
||||
modules = {
|
||||
"metas" : metas,
|
||||
"navbar" : navbars,
|
||||
"sidebar" : sidebars,
|
||||
"footer" : footers,
|
||||
"template": templates,
|
||||
}
|
||||
|
||||
#====================================#
|
||||
# Check if domain is ready and ready #
|
||||
#------------------------------------#
|
||||
def valid():
|
||||
if incomplete: sys.exit(41)
|
||||
elif not active: sys.exit(42)
|
|
@ -1,540 +0,0 @@
|
|||
#!/usr/bin/env python3
|
||||
# Name: Tyto - Littérateur
|
||||
# Type: Global functions for domain
|
||||
# Description: Add new domain, check domain dir...
|
||||
# file: domain.py
|
||||
# Folder: /var/lib/tyto/scripts/
|
||||
# By echolib (XMPP: im@echolib.re)
|
||||
# License: GNU AFFERO GENERAL PUBLIC LICENSE Version 3, 19 November 2007
|
||||
|
||||
#------------
|
||||
# funny stats
|
||||
#------------
|
||||
# lines:
|
||||
# functions:
|
||||
# comments:
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
#**********************************************************************
|
||||
|
||||
#======#
|
||||
# MAIN #
|
||||
#======#
|
||||
import sys, os, subprocess, datetime
|
||||
import check, log
|
||||
|
||||
# In Tyto DB dir
|
||||
tyto_db = '/var/lib/tyto/db/'
|
||||
tyto_domains = '%sdomains.conf'%tyto_db
|
||||
|
||||
# In Tyto log dir
|
||||
tyto_logs_dir = '/var/log/tyto/'
|
||||
tyto_logs = '%styto.log'%tyto_logs_dir
|
||||
|
||||
# Current dir
|
||||
curr_dir = domain_articles = domain_logs = os.getcwd()
|
||||
|
||||
# set domain configuration file from current directory
|
||||
conf_domain = '%s/tyto_domain.conf'%curr_dir
|
||||
|
||||
# Activation domain
|
||||
domain_active = domain_conf = False
|
||||
|
||||
# Set needed directories
|
||||
|
||||
# Create Tyto logs
|
||||
if not os.path.exists(tyto_logs):
|
||||
file = open(tyto_logs, "w")
|
||||
file.write('')
|
||||
file.close()
|
||||
msg_log = 'Log > Create logs file for Tyto in %s\n'%tyto_logs
|
||||
log.append_f(tyto_logs,msg_log,0)
|
||||
|
||||
# Get database domains
|
||||
# If not exists, create the file conf
|
||||
# Will receive all domain registred
|
||||
try:
|
||||
exec(open(tyto_domains).read())
|
||||
except:
|
||||
domains_file = open(tyto_domains, 'w')
|
||||
domains_file.write("# Tyto's file with all activated domains\n")
|
||||
domains_file.close()
|
||||
|
||||
domains_db = open(tyto_domains,'r').read()
|
||||
|
||||
# Get user domain configuration file #
|
||||
# If exists, set to True, and exec
|
||||
try: # os.path.exists(conf_domain):
|
||||
exec(open(conf_domain).read())
|
||||
datas_domain = open(conf_domain, "r").read()
|
||||
if domain_active:
|
||||
print(':) Activated domain: "%s"'%domain_name)
|
||||
else:
|
||||
print(':/ Not activated domain in',conf_domain)
|
||||
except:
|
||||
print(':( Unused domain file:', conf_domain)
|
||||
|
||||
#=======#
|
||||
# Tools #
|
||||
#=======#--------------------------------------------------------------
|
||||
#============================#
|
||||
# Append new value to a file #
|
||||
#----------------------------#
|
||||
def append_f(f,line_val):
|
||||
file = open(f, "a")
|
||||
file.write('%s\n'%line_val)
|
||||
|
||||
#======================================#
|
||||
# Just a generic exit #
|
||||
# out defines message, not exit status #
|
||||
# for process form: "
|
||||
# - rename temp domain conf to legacy #
|
||||
#--------------------------------------#
|
||||
def exiting(process,out,msg):
|
||||
msgs = [
|
||||
'\n:) All done !',
|
||||
'\n:/ Maybe next time...',
|
||||
'%s'%msg
|
||||
]
|
||||
|
||||
if process == 'form':
|
||||
os.rename(temp_domain, conf_domain)
|
||||
|
||||
print(msgs[out])
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
#==========================#
|
||||
# Manage Argument 'domain' #
|
||||
#==========================#-------------------------------------------
|
||||
def manage_domain(Domain, Opt):
|
||||
if not Opt:
|
||||
try:
|
||||
# No option: get domain and print it
|
||||
print('\n',datas_domain)
|
||||
except:
|
||||
sys.exit(0)
|
||||
|
||||
elif Opt == 'New':
|
||||
try:
|
||||
# Domain NAME is defined in CLI
|
||||
set_domain = Domain
|
||||
except:
|
||||
set_domain = ''
|
||||
|
||||
add_domain(set_domain)
|
||||
|
||||
elif Opt == 'Edit' or '-E':
|
||||
if domain_conf:
|
||||
print(':> Editing',domain_conf)
|
||||
old_conf_ID = check.get_filesum(domain_conf, True)
|
||||
edit_domain = subprocess.run(['/usr/bin/nano',
|
||||
'--linenumbers',
|
||||
domain_conf])
|
||||
|
||||
# Compare before and after domain conf file
|
||||
new_conf_ID = check.get_filesum(domain_conf,True)
|
||||
if not old_conf_ID == new_conf_ID:
|
||||
exiting('root',2,':) Updated domain configuration file.')
|
||||
else:
|
||||
exiting('root',2,':) Unchanged domain configuration file.')
|
||||
else:
|
||||
sys.exit(0)
|
||||
|
||||
#===================================#
|
||||
# Main fonction to add a new domain #
|
||||
# Check first, if it already exists #
|
||||
# Domain not activated: #
|
||||
# - Show registred values in form #
|
||||
#-----------------------------------#----------------------------------
|
||||
def add_domain(set_domain):
|
||||
# Exit if a domain already exists
|
||||
if domain_active:
|
||||
sys.exit(0)
|
||||
|
||||
global temp_domain
|
||||
temp_domain = '%s/tyto_domain.tmp'%curr_dir
|
||||
|
||||
print('\n'
|
||||
' ┌──────────────────────────────────────────────┐\n'
|
||||
' │ Configure a new domain for current directory │\n'
|
||||
' │ Answer Y = yes. Default value = (default) │\n'
|
||||
' │ Empty Answer cancel process, except for │\n'
|
||||
' │ - "Optional" │\n'
|
||||
' │ - "(default) value │\n'
|
||||
' ├──────────────────────────────────────────────┘'
|
||||
)
|
||||
|
||||
# Create new temp conf file
|
||||
# Used to prepare values, leaving legacy conf file
|
||||
file = open(temp_domain, "w")
|
||||
file.write('# Tyto Configuration Domain\n')
|
||||
file.close()
|
||||
|
||||
# Domain is or not given in CLI.
|
||||
# Start form
|
||||
if set_domain:
|
||||
domain_input_confirn(set_domain)
|
||||
domain_form()
|
||||
else:
|
||||
domain_input()
|
||||
domain_form()
|
||||
|
||||
# End of form.
|
||||
# Show resume's domain configuration from temp conf file
|
||||
print('\n'
|
||||
' ┌─────────────────────────────┐\n'
|
||||
' │ Please check domain datas...│\n'
|
||||
' ├─────────────────────────────┘'
|
||||
)
|
||||
with open(temp_domain, "r") as file:
|
||||
post_temp = file.read()
|
||||
for line in post_temp.split('\n'):
|
||||
print(' │ %s'%line)
|
||||
|
||||
# Ask to confirm to write activation domain
|
||||
print(' ├─────────────────────────────')
|
||||
confirm = input(' └ Activate domain configuration ? ')
|
||||
if confirm in ['y', 'Y']:
|
||||
create_domain()
|
||||
else:
|
||||
exiting('form',1,'')
|
||||
|
||||
#==============================#
|
||||
# If domain name is set in CLI #
|
||||
# Confirm process #
|
||||
#------------------------------#
|
||||
def domain_input_confirn(set_domain):
|
||||
global domain_name
|
||||
confirm = input(' ├ Add Domain (%s) here ? '%set_domain)
|
||||
if confirm in ['y', 'Y']:
|
||||
# Check if domain already registred
|
||||
isdomain = set_domain.replace('.','_')
|
||||
if isdomain in domains_db:
|
||||
dom_folder = globals().get(isdomain,False)
|
||||
if dom_folder and not dom_folder == curr_dir:
|
||||
exiting('root',2,'\n:/ Domain exists in %s'%dom_folder)
|
||||
domain_name = set_domain
|
||||
else:
|
||||
exiting('root',1,'')
|
||||
|
||||
#=====================#
|
||||
# Add new domain_name #
|
||||
#---------------------#
|
||||
def domain_input():
|
||||
global domain_name
|
||||
set_domain = input(' ├ Enter Domain Name: ')
|
||||
if not set_domain:
|
||||
exiting('root',1,'')
|
||||
else:
|
||||
domain_name = set_domain
|
||||
|
||||
#====================#
|
||||
# Domain FORM #
|
||||
# domain_name is set #
|
||||
# Configure domain #
|
||||
#--------------------#
|
||||
def domain_form():
|
||||
|
||||
# First settings to put in temp_domain config file
|
||||
domain_db = '%s/%s/articles/'%(tyto_db,domain_name)
|
||||
domain_logs = '%s%s/'%(tyto_logs_dir,domain_name)
|
||||
domain_articles = '%s/articles/'%curr_dir
|
||||
domain_images = '%simages/'%domain_articles
|
||||
domain_files = '%sfiles/'%domain_articles
|
||||
|
||||
# Add settings from domain name before starting form
|
||||
append_f(temp_domain,'domain_name = "%s"'%domain_name)
|
||||
append_f(temp_domain,'domain_conf = "%s"'%conf_domain)
|
||||
append_f(temp_domain,'domain_db = "%s"'%domain_db)
|
||||
append_f(temp_domain,'domain_logs = "%s"'%domain_logs)
|
||||
append_f(temp_domain,'\n# Article directories')
|
||||
append_f(temp_domain,'domain_dir = "%s"'%curr_dir)
|
||||
append_f(temp_domain,'domain_articles = "%s"'%domain_articles)
|
||||
append_f(temp_domain,'domain_files = "%s"'%domain_files)
|
||||
append_f(temp_domain,'domain_images = "%s"'%domain_images)
|
||||
|
||||
# ----------------------- #
|
||||
# Starting Form #
|
||||
# Some values are defaut #
|
||||
# Values can be registred #
|
||||
# from legacy conf file #
|
||||
# ----------------------- #
|
||||
|
||||
# Local server Directory
|
||||
# ----------------------
|
||||
global srv
|
||||
try:
|
||||
srv
|
||||
except:
|
||||
srv = '/var/www'
|
||||
|
||||
set_srv = input(' ├ Local server directory (%s) ? '%srv)
|
||||
if not set_srv and not srv:
|
||||
exiting('form',1,'')
|
||||
if set_srv and set_srv[-1] == '/':
|
||||
srv = set_srv[:-1]
|
||||
|
||||
if not os.path.exists(srv):
|
||||
exiting('form',2,'\n:( Unsed directory "%s"'%srv)
|
||||
|
||||
# Settings for server
|
||||
srv_domain = '%s/%s/'%(srv,domain_name)
|
||||
srv_wip = '%s/%s/wip/'%(srv,domain_name)
|
||||
srv_wip_files = '%s/%s/wip/files/'%(srv,domain_name)
|
||||
srv_wip_images = '%s/%s/wip/images/'%(srv,domain_name)
|
||||
srv_wip_template = '%s/%s/wip/template/'%(srv,domain_name)
|
||||
srv_www = '%s/%s/www/'%(srv,domain_name)
|
||||
srv_www_files = '%s/%s/www/files/'%(srv,domain_name)
|
||||
srv_www_images = '%s/%s/www/images/'%(srv,domain_name)
|
||||
srv_www_template = '%s/%s/www/template/'%(srv,domain_name)
|
||||
# Write settings to temp_omain
|
||||
append_f(temp_domain,'\n# Server directories')
|
||||
append_f(temp_domain,'srv = "%s"'%srv)
|
||||
append_f(temp_domain,'srv_domain = "%s"'%srv_domain)
|
||||
append_f(temp_domain,'srv_wip = "%s"'%srv_wip)
|
||||
append_f(temp_domain,'srv_wip_files = "%s"'%srv_wip_files)
|
||||
append_f(temp_domain,'srv_wip_images = "%s"'%srv_wip_images)
|
||||
append_f(temp_domain,'srv_wip_template = "%s"'%srv_wip_template)
|
||||
append_f(temp_domain,'srv_www = "%s"'%srv_www)
|
||||
append_f(temp_domain,'srv_www_files = "%s"'%srv_www_files)
|
||||
append_f(temp_domain,'srv_www_images = "%s"'%srv_www_images)
|
||||
append_f(temp_domain,'srv_www_template = "%s"'%srv_www_template)
|
||||
|
||||
# Domain Title for website
|
||||
# ------------------------
|
||||
global domain_title
|
||||
try:
|
||||
domain_title
|
||||
show_title = domain_title[:14] + '...'
|
||||
except:
|
||||
domain_title = show_title = ''
|
||||
|
||||
set_title = input(' ├ Domain Title (%s) ? '%show_title)
|
||||
if not set_title and not domain_title:
|
||||
exiting('form',1,'')
|
||||
if set_title:
|
||||
domain_title = set_title
|
||||
if '"' in domain_title:
|
||||
domain_title = domain_title.replace('"','\\"')
|
||||
|
||||
append_f(temp_domain,'\n# Domain datas for web pages')
|
||||
append_f(temp_domain,'domain_title = "%s"'%domain_title)
|
||||
|
||||
# Separator Pages Titles (default '-')
|
||||
# ------------------------------------
|
||||
global sep_titles
|
||||
try:
|
||||
sep_titles
|
||||
except:
|
||||
sep_titles = '-'
|
||||
|
||||
set_sep = input(' ├ Website pages separator (%s) ? '%sep_titles)
|
||||
if set_sep:
|
||||
if len(set_sep) > 2:
|
||||
exiting('form',2,'\n:( Seperator is 2 characters max')
|
||||
sep_titles = set_sep
|
||||
|
||||
append_f(temp_domain,'sep_titles = "%s"'%sep_titles)
|
||||
|
||||
# Domain description
|
||||
# ------------------
|
||||
global domain_about
|
||||
try:
|
||||
domain_about
|
||||
show_about = domain_about[:14] + '...'
|
||||
except:
|
||||
domain_about = show_about = ''
|
||||
|
||||
set_about = input(' ├ Domain description (%s) ? '%show_about)
|
||||
if not set_about and not domain_about:
|
||||
exiting('form',1,'')
|
||||
if set_about:
|
||||
domain_about = set_about
|
||||
if '"' in domain_about:
|
||||
domain_about = domain_about.replace('"','\\"')
|
||||
|
||||
append_f(temp_domain,'domain_about = "%s"'%domain_about)
|
||||
|
||||
# Lang for HTML Pages
|
||||
# -------------------
|
||||
global domain_lang
|
||||
try:
|
||||
domain_lang
|
||||
except:
|
||||
# Get default system language (2/3 chars for HTML)
|
||||
import locale
|
||||
domain_lang = locale.getdefaultlocale()[0].split('_')[0]
|
||||
|
||||
set_lang = input(' ├ Website HTML lang (%s) ? '%domain_lang)
|
||||
if set_lang:
|
||||
if len(set_lang) > 3:
|
||||
exiting('form',2,'\n:( HTML Lang is 3 characters max')
|
||||
domain_lang = set_lang
|
||||
|
||||
append_f(temp_domain,'domain_lang = "%s"'%domain_lang)
|
||||
|
||||
# Domain CSS (prefix class). alphanum only
|
||||
# ----------------------------------------
|
||||
global domain_css
|
||||
try:
|
||||
domain_css
|
||||
except:
|
||||
domain_css = 'tyto'
|
||||
|
||||
set_css = input(' ├ Generic CSS class (%s) ? '%domain_css)
|
||||
if set_css:
|
||||
domain_css = set_css
|
||||
if not domain_css.isalnum():
|
||||
css_alnum = ''.join(c for c in domain_css if c.isalnum())
|
||||
domain_css = css_alnum
|
||||
|
||||
append_f(temp_domain,'domain_css = "%s"'%domain_css)
|
||||
|
||||
# Domain mail
|
||||
# -----------
|
||||
global domain_mail
|
||||
try:
|
||||
domain_mail
|
||||
show_mail = domain_mail[:14] + '...'
|
||||
except:
|
||||
domain_mail = show_mail = ''
|
||||
|
||||
set_mail = input(' ├ Contact admin mail (%s) ? '%show_mail)
|
||||
if not set_mail and not domain_mail:
|
||||
exiting('form',1,'')
|
||||
if set_mail:
|
||||
if not '@' and not '.' in set_mail:
|
||||
exiting('form',2,'\n:( Invalid mail format (x@x.x)')
|
||||
domain_mail = set_mail
|
||||
elif not domain_mail:
|
||||
exiting('form',2,'\n:( Mail is required.')
|
||||
|
||||
append_f(temp_domain,'domain_mail = "%s"'%domain_mail)
|
||||
|
||||
# Domain Tags
|
||||
# -----------
|
||||
global domain_tags
|
||||
try:
|
||||
domain_tags
|
||||
show_tags = domain_tags[:14] + '...'
|
||||
except:
|
||||
domain_tags = show_tags = ''
|
||||
|
||||
set_tags = input(' ├ Domain Tags [x,y] (%s) ? '%show_tags)
|
||||
if not set_tags and not domain_tags:
|
||||
exiting('form',1,'')
|
||||
if set_tags:
|
||||
domain_tags = set_tags
|
||||
|
||||
append_f(temp_domain,'domain_tags = "%s"'%domain_tags)
|
||||
|
||||
# Webpages Copyright
|
||||
# ------------------
|
||||
global domain_license
|
||||
try:
|
||||
domain_license
|
||||
show_license = domain_license[:14] + '...'
|
||||
except:
|
||||
domain_license = show_license = 'CC BY-NC-SA'
|
||||
|
||||
set_license = input(' ├ Website copyright (%s) ? '%show_license)
|
||||
if set_license:
|
||||
domain_license = set_license
|
||||
if '"' in domain_license:
|
||||
domain_license = domain_license.replace('"','\\"')
|
||||
|
||||
append_f(temp_domain,'domain_license = "%s"'%domain_license)
|
||||
|
||||
# Sidebar Title
|
||||
# -------------
|
||||
global sidebar_title
|
||||
try:
|
||||
sidebar_title
|
||||
show_st = sidebar_title[:14] + '...'
|
||||
except:
|
||||
if 'fr' in domain_lang:
|
||||
sidebar_title = show_st = "À l'affiche !"
|
||||
else:
|
||||
sidebar_title = show_st = "Featured !"
|
||||
|
||||
set_st = input(' ├ Sidebar title (%s) ? '%show_st)
|
||||
if set_st:
|
||||
sidebar_title = set_st
|
||||
if '"' in sidebar_title:
|
||||
sidebar_title = sidebar_title.replace('"','\\"')
|
||||
|
||||
# Sidbar items number. Default: 12
|
||||
# -------------------
|
||||
global sidebar_items
|
||||
try:
|
||||
sidebar_items
|
||||
except:
|
||||
sidebar_items = 8
|
||||
|
||||
set_si = input(' ├ Sidebar max items [1-16] (%s) ? '%sidebar_items)
|
||||
if set_si and set_si.isdigit():
|
||||
if set_si in range(1,16):
|
||||
exiting('form',2,'\n:( Items number: 1-16')
|
||||
sidebar_items = set_si
|
||||
|
||||
# Domain LOGO (optional)
|
||||
# ----------------------
|
||||
global domain_logo
|
||||
try:
|
||||
domain_logo
|
||||
show_logo = domain_logo[:14] + '...'
|
||||
except:
|
||||
domain_logo = show_logo = ''
|
||||
|
||||
set_logo = input(' ├ Optional. Logo filename (%s) ? '%show_logo)
|
||||
if set_logo:
|
||||
domain_logo = set_logo
|
||||
append_f(temp_domain,'domain_logo = "%s"'%domain_logo)
|
||||
|
||||
# External URL profile (optional)
|
||||
# -------------------------------
|
||||
global domain_exturl
|
||||
try:
|
||||
domain_exturl
|
||||
show_e= domain_exturl[:14] + '...'
|
||||
except:
|
||||
domain_exturl = show_e = ''
|
||||
|
||||
set_e = input(' └ Optionnal. URL to a social network (%s) ? '%show_e)
|
||||
if set_e:
|
||||
domain_exturl = set_e
|
||||
|
||||
append_f(temp_domain,'domain_exturl = "%s"'%domain_exturl)
|
||||
|
||||
# Adding sidebar conf
|
||||
sidebar_dir = '%s/articles/sidebar/'%curr_dir
|
||||
sidebar_load = '%styto.sidebar'%sidebar_dir
|
||||
append_f(temp_domain,'\n# Sidebar')
|
||||
append_f(temp_domain,'domain_sdb_dir = "%s"'%sidebar_dir)
|
||||
append_f(temp_domain,'domain_sdb_load = "%s"'%sidebar_load)
|
||||
append_f(temp_domain,'domain_sdb_title = "%s"'%sidebar_title)
|
||||
append_f(temp_domain,'domain_sdb_items = "%s"'%sidebar_items)
|
||||
|
||||
#==========================#
|
||||
# If confirm activation #
|
||||
# Add value to domain conf #
|
||||
# Create all directories #
|
||||
#--------------------------#
|
||||
def create_domain():
|
||||
# Add activation var to temp domain conf
|
||||
append_f(temp_domain,'\n# Domain activation')
|
||||
append_f(temp_domain,'domain_active = True')
|
||||
|
||||
# Add var domain_name to tyto_domains file, if not exists
|
||||
domain_var = domain_name.replace('.','_')
|
||||
if not domain_var in domains_db:
|
||||
append_f(tyto_domains,'%s = "%s"'%(domain_var,curr_dir))
|
||||
|
||||
# Create all directories for this domain
|
||||
check.create_domain_dirs('all')
|
||||
|
||||
# Will rename temp_domain conf to legacy domain conf file
|
||||
exiting('form',2,'\n:) Activated domain: "%s"'%domain_name)
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,536 @@
|
|||
# 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: Create HTML page
|
||||
# File: /var/lib/tyto/program/html.py
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
#------------
|
||||
# funny stats
|
||||
#------------
|
||||
# lines:
|
||||
# functions:
|
||||
# comments:
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
#**********************************************************************
|
||||
|
||||
import os, sys, importlib
|
||||
import logs, db, dom, tyto, form, langs
|
||||
|
||||
# Publish option can be
|
||||
pub_opts = ('www', 'pub')
|
||||
|
||||
# Not a line if it starts with...(for sidebar, navbar)
|
||||
nolines = ('#', '/')
|
||||
|
||||
#==========================#
|
||||
# Load article DB #
|
||||
# Start HTML page sections #
|
||||
#--------------------------#
|
||||
def set_page(target, article_bottom):
|
||||
create_metas_page() # Include metas tags
|
||||
create_main_page(target, article_bottom) # Create main page
|
||||
|
||||
|
||||
#============================================#
|
||||
# Set metas_page to be included in main page #
|
||||
#--------------------------------------------#
|
||||
def create_metas_page():
|
||||
global metas_page
|
||||
|
||||
# Settings for metas
|
||||
#-------------------
|
||||
metas_page = ''
|
||||
scale = 'width=device-width, initial-scale=1.0'
|
||||
all_tags = dom.tags + ',' + db.meta_tags
|
||||
css_ref = 'href="%stemplate/%s"'%(db.sub_uri, dom.styles)
|
||||
rss_ref = 'type="application/rss+xml" ' + \
|
||||
'href="%s%s" title="RSS 2.0. %s %s %s"'%(
|
||||
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
|
||||
)
|
||||
relme = '' # External URL in metas (if exists in config domain)
|
||||
if dom.relme:
|
||||
relme = '\n <link rel="me" type="text/html" href="%s">'%(
|
||||
dom.relme
|
||||
)
|
||||
|
||||
# Create author and date publish section infos
|
||||
create_html_time_meta('wip')
|
||||
|
||||
# Set all raw HTML metas
|
||||
#-----------------------
|
||||
global metas
|
||||
metas = \
|
||||
'<!--# include virtual="/template/metas.html"-->\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 + \
|
||||
' <meta name="reply-to" content="%s" />\n'%dom.mail + \
|
||||
' <meta name="copyright" content="%s" />\n'%dom.license + \
|
||||
' <meta name="generator" content="%s" />\n'%tyto.Tyto + \
|
||||
' <meta name="title" content="%s" />\n'%db.title + \
|
||||
' <meta name="author" content="%s" />\n'%db.author + \
|
||||
' <meta name="description" content="%s" />\n'%db.about + \
|
||||
' <meta name="keywords" content="%s" />\n'%all_tags + \
|
||||
'%s'%meta_pub + \
|
||||
' <link rel="canonical" href="%s" />\n'%db.http_www + \
|
||||
' <link rel="alternate" %s />\n'%(rss_ref) + \
|
||||
' <link rel="stylesheet" %s />\n'%css_ref + \
|
||||
' <link rel="shortcut icon" %s />\n'%icon_ref + \
|
||||
' <!-- Open Graph data -->\n' + \
|
||||
' <meta property="og:site_name" content="%s" />\n'%dom.title + \
|
||||
' <meta property="og:title" content="%s" />\n'%db.title + \
|
||||
' <meta property="og:type" content="article" />\n' + \
|
||||
' <meta property="og:url" content="%s" />\n'%db.http_www + \
|
||||
' <meta property="og:description" content="%s" />\n'%db.about + \
|
||||
' <meta property="og:image" content="%s" />\n'%db.snpic + \
|
||||
'%s'%relme + \
|
||||
' <title>%s %s %s</title>'%(db.title, dom.sep, dom.title)
|
||||
|
||||
|
||||
#=======================================#
|
||||
# Set main page, with all HTML sections #
|
||||
#---------------------------------------#
|
||||
def create_main_page(target, article_bottom):
|
||||
global main_page, post_html_code
|
||||
|
||||
# Create link for website's logo
|
||||
#-------------------------------
|
||||
logo_html = \
|
||||
'<a href="/"\n' + \
|
||||
'%stitle="%s %s logo: %s"\n'%(11 * " ",
|
||||
langs.site.home, dom.sep, dom.title
|
||||
) + \
|
||||
'%sid="site_logo_link">\n'%(11 * " ") + \
|
||||
'%s<img src="%stemplate/%s"\n'%(
|
||||
10 * " ", db.sub_uri, dom.logo
|
||||
) + \
|
||||
'%salt="logo: %s"\n'%(15 * " ", dom.title) + \
|
||||
'%sid="site_logo_image" />\n'%(15 * " ") + \
|
||||
'%s</a>'%(8 * " ")
|
||||
|
||||
post_html_code = ''
|
||||
if dom.article_code:
|
||||
post_html_code = \
|
||||
' <span id="article_code"> \n' + \
|
||||
' <a id="article_code_link"\n' + \
|
||||
' href="./%s"\n'%os.path.basename(db.short_src) + \
|
||||
' title="%s [%s]">{%s}</a></span> \n'%(
|
||||
langs.site.tyto_psrc, db.title,
|
||||
langs.site.source_code
|
||||
)
|
||||
|
||||
#-----------------------#
|
||||
# Create main HTML Page #
|
||||
#-----------------------#
|
||||
main_page = \
|
||||
'<!Doctype html>\n' + \
|
||||
'<html lang="%s">\n'%dom.lang_site + \
|
||||
' <head>\n' + \
|
||||
'%s\n'%metas + \
|
||||
' </head>\n\n' + \
|
||||
' <body>\n' + \
|
||||
' <header id="header_page">\n' + \
|
||||
' <div id="site_logo">\n' + \
|
||||
' %s\n'%logo_html + \
|
||||
' </div>\n' + \
|
||||
' <div id="site_infos">\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' + \
|
||||
' <p id="site_about">%s</p>\n'%dom.about + \
|
||||
' </div>\n' + \
|
||||
' </header>\n' + \
|
||||
'<!--# include virtual="/template/navbar.html"-->\n' + \
|
||||
'\n' + \
|
||||
' <article id="article_main">\n' + \
|
||||
' <h1 id="main_title"\n' + \
|
||||
' title="[%s] %s %s %s %s">%s</h1>\n'%(
|
||||
db.title, langs.site.w_written, db.date,
|
||||
langs.site.by, db.author,
|
||||
db.title,
|
||||
) + \
|
||||
'%s\n'%article_bottom + \
|
||||
' <section id="article_infos">\n' + \
|
||||
' <p>\n' + \
|
||||
' <span id="article_author"\n' + \
|
||||
' title="%s %s [%s]">%s</span>, %s\n'%(
|
||||
db.author, langs.site.author_of, db.title,
|
||||
db.author, langs.site.le
|
||||
) + \
|
||||
'%s\n'%time_html_pub + \
|
||||
'%s'%post_html_code + \
|
||||
' </p>\n' + \
|
||||
' </section>\n' + \
|
||||
' </article>\n' + \
|
||||
'\n' + \
|
||||
'<!--# include virtual="/template/sidebar.html"-->\n' + \
|
||||
'<!--# include virtual="/template/footer.html"-->\n' + \
|
||||
' </body>\n' + \
|
||||
'</html>'
|
||||
|
||||
|
||||
#============================================#
|
||||
# Create HTML line for article infos section #
|
||||
# when wip, and publish #
|
||||
#--------------------------------------------#
|
||||
def create_html_time_meta(process):
|
||||
# Need to reload the DB to get last time updated
|
||||
importlib.reload(db)
|
||||
|
||||
global time_html_pub, meta_pub, date_raw
|
||||
|
||||
if process == 'wip':
|
||||
try:
|
||||
date_raw = db.date_wip # <time datetime= / meta search_date
|
||||
date_pub = db.date_wip.rsplit(' ')[0]
|
||||
time_pub = db.date_wip.rsplit(' ')[1]
|
||||
except:
|
||||
logs.out("23", '"date_wip = ?" > %s'%db.uri_file, True)
|
||||
|
||||
elif process == 'publish':
|
||||
try:
|
||||
date_raw = db.date_www # <time datetime=
|
||||
date_pub = db.date_www.rsplit(' ')[0]
|
||||
time_pub = db.date_www.rsplit(' ')[1]
|
||||
except:
|
||||
logs.out("23", '"date_www = ?" > %s'%db.uri_file, True)
|
||||
|
||||
if dom.lang_site == 'fr':
|
||||
date_new = date_pub.rsplit('-')
|
||||
date_pub = date_new[2] + '/' + date_new[1] + '/' + date_new[0]
|
||||
|
||||
# in <article> > section info : line with new date
|
||||
time_html_pub = \
|
||||
'<!--Tyto_Published-->\n' + \
|
||||
' <time datetime="%s">\n'%date_raw + \
|
||||
' <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
|
||||
) + \
|
||||
' </time>\n' + \
|
||||
'<!--/Tyto_Published-->'
|
||||
|
||||
# meta search_date=
|
||||
meta_pub = \
|
||||
'<!--Tyto_Meta--> <meta name="search_date" content="%s" />\n'%(
|
||||
date_raw.rsplit(' ')[0]
|
||||
)
|
||||
|
||||
|
||||
#=================================================#
|
||||
# Create metas.html from _configs/tyto.metas.html #
|
||||
# Opiton 'pub' force create (when publish) #
|
||||
#-------------------------------------------------#
|
||||
def create_user_metas(option):
|
||||
dom.valid()
|
||||
|
||||
if option == 'wip': target = dom.wip_metas_f
|
||||
elif option in pub_opts: target = dom.www_metas_f
|
||||
|
||||
if option == 'www' and tyto.exists(target):
|
||||
form.asking(' ├ %s. %s%s '%(
|
||||
langs.site.metas, langs.site.form_rep, langs.site.q
|
||||
), True)
|
||||
|
||||
print(' │\n ├ %s'%langs.site.metas_inf)
|
||||
|
||||
# Create wip metas.html file according to option
|
||||
#-----------------------------------------------
|
||||
try: user_file = open(dom.metas_f, 'r').read()
|
||||
except: logs.out("1", dom.metas_f, True)
|
||||
|
||||
user_metas = ''
|
||||
tab = 4 * ' '
|
||||
metas_used = ('<meta ', '<link ')
|
||||
for line in user_file.rsplit('\n'):
|
||||
if line.startswith(metas_used):
|
||||
if user_metas: user_metas = "%s\n%s%s"%(user_metas, tab, line)
|
||||
else: user_metas = '%s%s'%(tab, line)
|
||||
|
||||
tyto.set_file(target, 'New', user_metas)
|
||||
|
||||
|
||||
#==============================================#
|
||||
# Create HTML sidebar from file tyto.navbar #
|
||||
# If no index file in src directory: pass # #
|
||||
# Create empty file in template/ if not exists #
|
||||
#----------------------------------------------#
|
||||
def create_navbar(option):
|
||||
dom.valid()
|
||||
|
||||
if not tyto.exists(dom.navbar_f):
|
||||
logs.out("1", dom.navbar_f, True)
|
||||
|
||||
if option == 'wip': target = dom.wip_navbar_f
|
||||
elif option in pub_opts: target = dom.www_navbar_f
|
||||
|
||||
if option == 'www' and tyto.exists(target):
|
||||
form.asking(' ├ %s. %s(%s)%s '%(
|
||||
langs.site.navbar, langs.site.form_rep,
|
||||
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<ul id="site_menu_items">'%(6 * ' ')
|
||||
|
||||
navbar_lines = open(dom.navbar_f, 'r').read()
|
||||
|
||||
for line in navbar_lines.rsplit('\n'):
|
||||
if not line or line.startswith(nolines): continue
|
||||
|
||||
# Get HTML title if defined (commented after)
|
||||
if '#' in line:
|
||||
direc = line.rsplit('#')[0].rstrip()
|
||||
title = '%stitle="%s"\n'%(15 * ' ', line.rsplit('#')[1].lstrip())
|
||||
else:
|
||||
direc = line
|
||||
title = ''
|
||||
|
||||
# Check if directory exists in articles/
|
||||
dir_uri = os.path.join(dom.articles_d, direc)
|
||||
if not os.path.isdir(dir_uri):
|
||||
logs.out("24", '%s/'%dir_uri, False)
|
||||
continue
|
||||
|
||||
# Check if an index.[ext] exists (src, wip, www)
|
||||
no_wip_index = False
|
||||
no_www_index = False
|
||||
src_index = ''
|
||||
wip_index = '%s%s/index.html'%(dom.srv_wip, direc)
|
||||
www_index = '%s%s/index.html'%(dom.srv_www, direc)
|
||||
|
||||
# Source index article must exist
|
||||
src_index = [ \
|
||||
filename \
|
||||
for filename in os.listdir(dir_uri) \
|
||||
if filename.startswith("index.") \
|
||||
and os.path.isfile \
|
||||
]
|
||||
if not src_index:
|
||||
src_index = '%s%s/index.tyto'%(dom.articles_d, direc)
|
||||
logs.out('26', '> %s'%(src_index), False)
|
||||
continue
|
||||
|
||||
# index.html server files must exist (or 404 error)
|
||||
if option == 'wip':
|
||||
if not tyto.exists(wip_index):
|
||||
logs.out('26', '> %s'%(wip_index), False)
|
||||
no_wip_index = True
|
||||
continue
|
||||
|
||||
elif option in pub_opts:
|
||||
if not tyto.exists(www_index):
|
||||
logs.out('26', '> %s'%(www_index), False)
|
||||
no_www_index = True
|
||||
continue
|
||||
|
||||
|
||||
# Add link to HTML structure
|
||||
navbar_items = True
|
||||
menu_item = \
|
||||
'\n%s<li class="site_menu_item">\n'%(8 * ' ') + \
|
||||
'%s<a class="site_menu_link"\n'%(10 * ' ') + \
|
||||
'%s'%title + \
|
||||
'%shref="/%s/">%s</a>\n'%(
|
||||
15 * ' ', direc, direc
|
||||
) + \
|
||||
'%s</li>'%(8 * ' ')
|
||||
|
||||
menu_html = '%s%s'%(menu_html, menu_item)
|
||||
|
||||
|
||||
# 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:
|
||||
menu_html = '\n%s\n%s</ul>\n%s</nav>\n'%(menu_html, 8 * ' ', 6 * ' ')
|
||||
tyto.set_file(target, 'New', menu_html)
|
||||
|
||||
|
||||
#==============================================#
|
||||
# Create HTML sidebar from file tyto.sidebar #
|
||||
# Create empty file in template/ if not exists #
|
||||
#----------------------------------------------#
|
||||
def create_sidebar(option):
|
||||
dom.valid()
|
||||
|
||||
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
|
||||
elif option in pub_opts: target = dom.www_sidebar_f
|
||||
|
||||
if option == 'www' and tyto.exists(target):
|
||||
form.asking(' ├ %s. %s%s '%(
|
||||
langs.site.sidebar, langs.site.form_rep, langs.site.q
|
||||
), True)
|
||||
|
||||
print(' │\n ├ %s'%langs.site.sidebar_inf)
|
||||
|
||||
sidebar_items = False
|
||||
|
||||
# Set HTML sidebar
|
||||
sidebar_list = ''
|
||||
sidebar_html = \
|
||||
'<aside id="sidebar">\n' + \
|
||||
' <h1 id="sidebar_title">%s</h1>\n' + \
|
||||
' <ul id="sidebar_list">\n' + \
|
||||
'%s' + \
|
||||
' </ul>\n' + \
|
||||
'</aside>'
|
||||
|
||||
sidebar_title = dom.sidebar_title
|
||||
sidebar_lines = open(dom.sidebar_f, 'r').read()
|
||||
|
||||
counter = 0
|
||||
for line in sidebar_lines.rsplit('\n'):
|
||||
if not line or line.startswith(nolines):
|
||||
continue
|
||||
|
||||
if line.startswith(':'):
|
||||
sidebar_title = line.rsplit(':')[1].lstrip()
|
||||
continue
|
||||
|
||||
f_uri = '%s%s'%(dom.articles_d, line)
|
||||
if not tyto.exists(f_uri):
|
||||
logs.out("24", f_uri, False)
|
||||
continue
|
||||
|
||||
# Get Hash from uri to get db file
|
||||
hash_uri = tyto.get_filesum(f_uri, False)
|
||||
db_uri = '%s%s.config'%(dom.articles_db_d, hash_uri)
|
||||
if not tyto.exists(db_uri):
|
||||
logs.out('25', line, False)
|
||||
continue
|
||||
|
||||
# Load article"s database
|
||||
exec(open(db_uri).read(),globals())
|
||||
|
||||
# Check wip status and if article exists in server
|
||||
if option == 'wip':
|
||||
if hash_wip != hash_chk:
|
||||
logs.out("30", line, False)
|
||||
continue
|
||||
if not tyto.exists(post_wip):
|
||||
logs.out("24", post_wip, False)
|
||||
continue
|
||||
|
||||
elif option in pub_opts:
|
||||
if hash_www != hash_chk:
|
||||
logs.out("30", line, False)
|
||||
continue
|
||||
if not tyto.exists(post_www):
|
||||
logs.out("24", post_www, False)
|
||||
continue
|
||||
|
||||
# Add item if not max
|
||||
sidebar_items = True
|
||||
counter += 1
|
||||
if counter > dom.sidebar_items: break
|
||||
|
||||
# Show item to add
|
||||
logs.out("35", '"%s" > %s'%(title, line), False)
|
||||
|
||||
# Create HTML list for this article
|
||||
link_title = '%s [%s]'%(title, author)
|
||||
sidebar_list = sidebar_list + \
|
||||
' <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 + \
|
||||
' <p class="sidebar_item_about"\n' + \
|
||||
' title="%s">\n'%link_title + \
|
||||
' %s [%s] - %s\n'%(date, author, 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
|
||||
sidebar_temp = sidebar_html%(sidebar_title, sidebar_list)
|
||||
|
||||
# Indent HTML code
|
||||
sidebar_content = ''
|
||||
for line in sidebar_temp.rsplit('\n'):
|
||||
sidebar_content = sidebar_content + '%s%s\n'%(4 * ' ', line)
|
||||
|
||||
tyto.set_file(target, True, sidebar_content)
|
||||
|
||||
|
||||
#===================================================#
|
||||
# Create footer.html from _configs/tyto.footer.html #
|
||||
#----------------------------------------------=====#
|
||||
def create_user_footer(option):
|
||||
dom.valid()
|
||||
|
||||
if option == 'wip': target = dom.wip_footer_f
|
||||
elif option in pub_opts: target = dom.www_footer_f
|
||||
|
||||
if option == 'www' and tyto.exists(target):
|
||||
form.asking(' ├ %s. %s%s '%(
|
||||
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)
|
||||
|
||||
footer = ''
|
||||
tab = 4 * ' '
|
||||
for line in footer_f.rsplit('\n'):
|
||||
if not line or line.startswith('#'): continue
|
||||
|
||||
if footer: footer = "%s\n%s%s"%(footer, tab, line)
|
||||
else: footer = '%s%s'%(tab, line)
|
||||
|
||||
tyto.set_file(target, 'New', footer)
|
||||
|
|
@ -0,0 +1,101 @@
|
|||
#!/usr/bin/env python3
|
||||
# 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: Show helps and informations
|
||||
# File: /var/lib/tyto/program/infos.py
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
#------------
|
||||
# funny stats
|
||||
#------------
|
||||
# lines:
|
||||
# functions:
|
||||
# comments:
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
#**********************************************************************
|
||||
|
||||
import os, importlib
|
||||
import langs
|
||||
importlib.reload(langs)
|
||||
|
||||
# Set colors
|
||||
CS = '\033[0;0m'
|
||||
CR = '\033[1;31m'
|
||||
CY = '\033[1;33m'
|
||||
CG = '\033[1;32m'
|
||||
|
||||
def tyto(target):
|
||||
noinfos = False
|
||||
|
||||
# Show Version
|
||||
tytobin = open('/usr/bin/tyto').read()
|
||||
for line in tytobin.rsplit('\n'):
|
||||
if line.startswith('# Version:'):
|
||||
print(line)
|
||||
break
|
||||
|
||||
|
||||
# Show domains list
|
||||
try:
|
||||
has_domains = True
|
||||
user = os.environ.get('USER')
|
||||
user_dir = os.path.expanduser('~')
|
||||
db_domains = '%s/.local/tyto'%user_dir
|
||||
except:
|
||||
has_domains = False
|
||||
|
||||
if not os.path.exists(db_domains):
|
||||
has_domains = False
|
||||
print('! No directory > %s/'%db_domains)
|
||||
|
||||
if has_domains:
|
||||
list_domains = (())
|
||||
for folder in os.listdir(db_domains):
|
||||
domain_local_uri = '%s/%s'%(db_domains, folder)
|
||||
if os.path.isdir(domain_local_uri):
|
||||
domain_conf = '%s/domain_config.bkp'%domain_local_uri
|
||||
if os.path.exists(domain_conf):
|
||||
try:
|
||||
exec(open(domain_conf).read(),globals())
|
||||
except:
|
||||
continue
|
||||
if os.path.exists(directory):
|
||||
dir_domain = '%s%s%s'%(CG, directory, CS)
|
||||
else:
|
||||
dir_domain = '%s%s%s'%(CR, directory, CS)
|
||||
list_domains = \
|
||||
(('%s > %s > %s'%(folder, dir_domain, www_url)),)
|
||||
|
||||
if list_domains:
|
||||
print('# %s %ss %s'%(
|
||||
langs.site.reg_domains,
|
||||
langs.site.fo,
|
||||
user
|
||||
)
|
||||
)
|
||||
for domain in list_domains:
|
||||
print(' - %s'%domain)
|
||||
|
||||
|
||||
# Show arguments help
|
||||
print(langs.site.args_helps)
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
#!/usr/bin/env python3
|
||||
# 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: Load translations file for logs and forms/sites
|
||||
# File: /var/lib/tyto/program/langs.py
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
#------------
|
||||
# funny stats
|
||||
#------------
|
||||
# lines:
|
||||
# functions:
|
||||
# comments:
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
#**********************************************************************
|
||||
|
||||
import locale, sys, os, importlib
|
||||
import dom
|
||||
|
||||
# Import translation directory
|
||||
trans_dir = '/var/lib/tyto/translations'
|
||||
sys.path.insert(0, trans_dir)
|
||||
|
||||
|
||||
# Get default system language
|
||||
# or set "en" (english) if no translation file
|
||||
try:
|
||||
lang_sys = locale.getdefaultlocale()[0].split('_')[0]
|
||||
os.path.exists('%s/logs_%s.py'%(trans_dir, lang_sys))
|
||||
except:
|
||||
lang_sys = 'en'
|
||||
|
||||
|
||||
# Set language logs from configuration domain
|
||||
# or set default english if not known
|
||||
try:
|
||||
dom.exists
|
||||
lang_logs = dom.lang_logs
|
||||
os.path.exists('%s/logs_%s.py'%(trans_dir, lang_logs))
|
||||
log = importlib.import_module('logs_%s'%lang_logse, package=None)
|
||||
except:
|
||||
log = importlib.import_module('logs_%s'%lang_sys, package=None)
|
||||
|
||||
|
||||
# Set language site/form from configuration domain
|
||||
# or set default english if not known
|
||||
try:
|
||||
dom.exists
|
||||
lang_site = dom.lang_site
|
||||
os.path.exists('%s/site_%s.py'%(trans_dir, lang_site))
|
||||
site = importlib.import_module('site_%s'%lang_site, package=None)
|
||||
except:
|
||||
site = importlib.import_module('site_%s'%lang_sys, package=None)
|
|
@ -1,81 +0,0 @@
|
|||
#!/usr/bin/env python3
|
||||
# Name: Tyto - Littérateur
|
||||
# Type: Global functions for logs
|
||||
# Description: Print data to specific log file
|
||||
# file: log.py
|
||||
# Folder: /var/lib/tyto/scripts/
|
||||
# By echolib (XMPP: im@echolib.re)
|
||||
# License: GNU AFFERO GENERAL PUBLIC LICENSE Version 3, 19 November 2007
|
||||
|
||||
#------------
|
||||
# funny stats
|
||||
#------------
|
||||
# lines:
|
||||
# functions:
|
||||
# comments:
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
#**********************************************************************
|
||||
import check, domain
|
||||
|
||||
#=======================#
|
||||
# Manage Argument 'log' #
|
||||
# Read, remove log file #
|
||||
#-----------------------#
|
||||
def manage_log(file_post, Opt):
|
||||
import os, sys
|
||||
|
||||
if file_post:
|
||||
# No domain set, but ask for article : exit
|
||||
if not domain.domain_conf:
|
||||
sys.exit(1)
|
||||
|
||||
# Get complete URI for post
|
||||
post_uri = '%s%s'%(domain.domain_articles, file_post)
|
||||
|
||||
# Get ID from URI
|
||||
post_ID = check.get_filesum(post_uri,False)
|
||||
|
||||
# Set log file for article
|
||||
post_logs = '%s%s.log'%(domain.domain_logs,post_ID)
|
||||
else:
|
||||
post_logs = domain.tyto_logs
|
||||
|
||||
if os.path.exists(post_logs):
|
||||
if Opt == 'Remove' :
|
||||
os.remove(post_logs)
|
||||
msg_log = 'Log > Removed file: %s'%post_logs
|
||||
if file_post:
|
||||
append_f(domain.tyto_logs,msg_log,0)
|
||||
else:
|
||||
print(':) %s'%msg_log)
|
||||
else:
|
||||
file = open(post_logs,'r').read()
|
||||
print(file)
|
||||
else:
|
||||
print(':| Unsed file yet: %s'%post_logs)
|
||||
|
||||
#==============================#
|
||||
# Set and return date and time #
|
||||
# (especially for logs) #
|
||||
#------------------------------#
|
||||
def nowdate():
|
||||
import datetime
|
||||
|
||||
now = datetime.datetime.now()
|
||||
return(now.strftime('%Y-%m-%d %H:%M:%S'))
|
||||
|
||||
#==================================#
|
||||
# Append line to specific log file #
|
||||
#----------------------------------#
|
||||
def append_f(f,line,n):
|
||||
smiley = [':)',':(\033[1;31m','\033[1;33m:|']
|
||||
now = nowdate()
|
||||
|
||||
# Open file to append line
|
||||
file = open(f, "a")
|
||||
file.write('%s %s\n'%(now,line))
|
||||
file.close()
|
||||
|
||||
if not line.endswith('\n'):
|
||||
print('%s %s\033[0;0m'%(smiley[n],line))
|
|
@ -0,0 +1,118 @@
|
|||
#!/usr/bin/env python3
|
||||
# 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: Show logs messages, exit with nbr
|
||||
# File: /var/lib/tyto/program/logs.py
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
#------------
|
||||
# funny stats
|
||||
#------------
|
||||
# lines:
|
||||
# functions:
|
||||
# comments:
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
#**********************************************************************
|
||||
|
||||
import os, sys
|
||||
import langs
|
||||
|
||||
# Set colors
|
||||
CS = '\033[0;0m'
|
||||
CR = '\033[1;31m'
|
||||
CY = '\033[1;33m'
|
||||
CG = '\033[1;32m'
|
||||
|
||||
|
||||
# Exit from program with message #
|
||||
#--------------------------------#
|
||||
def out(nbr, value, out):
|
||||
logs = {
|
||||
'1' : ' ╞ %s%s%s > %s'%(CR, langs.log.unused_r, CS, value),
|
||||
'2' : ' ╞ %s%s%s > %s'%(CR, langs.log.data_inc, CS, value),
|
||||
'3' : ' ╞ %s%s%s %s'%(CR, langs.log.data_inv, CS, value),
|
||||
'4' : ' ╘ %sUnable to create file%s: %s'%(CR, CS, value),
|
||||
'5' : ' ╘ %s%s%s > "%s"'%(CR, langs.log.no_arg, CS, value),
|
||||
'6' : ' ╞ %s%s%s > %s'%(CR, langs.log.sep_inv, CS, value),
|
||||
'7' : ' ╘ %s%s%s > %s'%(CR, langs.log.post_inv, CS, value),
|
||||
'8' : ' ╞ %s%s%s %s'%(CR, langs.log.mark_np, CS, value),
|
||||
'9' : ' ╞ %s%s%s > %s'%(CR, langs.log.post_chg, CS, value),
|
||||
'10' : ' ╘ %s%s%s'%(CR, langs.log.dom_no, CS),
|
||||
'11' : ' ╘ %s%s%s > %s'%(CR, langs.log.err_arg, CS, value),
|
||||
'12' : ' ╞ %s%s%s > %s'%(CR, langs.log.post_inc, CS, value),
|
||||
'13' : ' ╞ %s%s%s'%(CR, langs.log.no_fidi, CS),
|
||||
'14' : ' ╞ %sMismatch%s program start'%(CR, CS),
|
||||
'15' : ' ╞ %s%s%s %s'%(CR, langs.log.anch_nu, CS, value),
|
||||
'16' : ' ╞ %s%s%s "%s = ?"'%(CR, langs.log.unused_c, CS, value),
|
||||
'17' : ' ╞ %s%s%s "%s ?"'%(CR, langs.log.unused_v, CS, value),
|
||||
'18' : ' ╘ %s%s%s > %s'%(CR, langs.log.unused_p, CS, value),
|
||||
'19' : ' ╞ %s%s%s %s'%(CG, langs.log.was_wip, CS, value),
|
||||
'20' : ' ╞ %s%s%s %s'%(CG, langs.log.was_chk, CS, value),
|
||||
'21' : ' ╘ %s%s%s > %s'%(CG, langs.log.post_val, CS, value),
|
||||
'22' : ' ╞ %s%s%s %s'%(CY, langs.log.symb_np, CS, value),
|
||||
'23' : ' ╞ %s%s%s > %s'%(CY, langs.log.db_inv, CS, value),
|
||||
'24' : ' ╞ %s%s%s > %s'%(CY, langs.log.unused_r, CS, value),
|
||||
'25' : ' ╞ %s%s%s > %s'%(CY, langs.log.nycheck, CS, value),
|
||||
'26' : ' ╞ %s%s%s %s'%(CY, langs.log.nyfile, CS, value),
|
||||
'27' : ' ╞ %s%s%s %s'%(CY, langs.log.snpic_d, CS, value),
|
||||
'28' : ' ╘ %s (%s)'%(langs.log.ntd, value),
|
||||
'29' : ' ╞ %sEmpty configuration%s %s'%(CY, CS, value),
|
||||
'30' : ' ╞ %s%s%s > %s'%(CY, langs.log.nywip, CS, value),
|
||||
'31' : ' ╘ %s%s%s'%(CR, langs.log.nomods, CS),
|
||||
'32' : ' ╞══ %s%s%s > %s'%(CG, langs.log.file_c, CS, value),
|
||||
'33' : ' ╞══ %s%s%s > %s'%(CG, langs.log.dir_c, CS, value),
|
||||
'34' : ' ╞══ %s%s%s > %s'%(CG, langs.log.file_n, CS, value),
|
||||
'35' : ' ╞═ %s%s%s %s'%(CG, langs.log.add, CS, value),
|
||||
'36' : ' ╡ %s %s'%(langs.log.file_e, value),
|
||||
'37' : ' ╡ %s %s'%(langs.log.dir_e, value),
|
||||
'38' : ' ╞ %s%s%s "%s ?"'%(CR, langs.log.unused_t, CS, value),
|
||||
'39' : ' ╒ %s%s%s > %s'%(CR, langs.log.dom_cor, CS, value),
|
||||
'40' : ' ╒ %s%s%s > %s'%(CY, langs.log.dom_ina, CS, value),
|
||||
'41' : ' ╒ %s%s%s > %s'%(CR, langs.log.dom_inc, CS, value),
|
||||
'42' : ' ╒ %s%s%s > %s'%(CG, langs.log.dom_act, CS, value),
|
||||
'43' : ' ╒ %s%s%s'%(CY, langs.log.dom_no, CS),
|
||||
'44' : ' ╞ %s%s%s "tyto check %s"'%(CY, langs.log.check_m, CS, value),
|
||||
'45' : ' ╞ %s%s %s%s > %s'%(CY, langs.log.meta_t, langs.log.no_up, CS, value),
|
||||
'46' : ' ╞ %s%s %s%s > %s'%(CY, langs.log.time_t, langs.log.no_up, CS, value),
|
||||
'51' : ' ╞ %s%s%s > %s'%(CY, langs.log.data_inc, CS, value),
|
||||
'60' : ' │\n ╞ %s'%langs.log.status_r,
|
||||
'61' : ' ╞ %s%s%s > %s'%(CG, langs.log.file_e, CS, value),
|
||||
'71' : ' ╞═ %s%s%s > %s'%(CY, langs.log.post_nwi, CS, value),
|
||||
'72' : ' ╞═ %s%s%s > %s'%(CG, langs.log.post_wip, CS, value),
|
||||
'73' : ' ╞═ %s%s%s > %s'%(CY, langs.log.st_wip_n, CS, value),
|
||||
'74' : ' ╞═ %s%s%s > %s'%(CY, langs.log.st_wip_o, CS, value),
|
||||
'81' : ' ╞═ %s%s%s > %s'%(CY, langs.log.post_nww, CS, value),
|
||||
'82' : ' ╞═ %s%s%s > %s'%(CG, langs.log.post_www, CS, value),
|
||||
'83' : ' ╞═ %s%s%s > %s'%(CY, langs.log.st_www_n, CS, value),
|
||||
'84' : ' ╞═ %s%s%s > %s'%(CY, langs.log.st_www_o, CS, value),
|
||||
'85' : ' ╞═ %s%s%s > %s'%(CY, langs.log.was_pub, CS, value),
|
||||
'94' : ' ╞═ %s%s%s > %s'%(CY, langs.log.st_chk_o, CS, value),
|
||||
'255' : ' ╘ %s'%langs.log.laterout
|
||||
}
|
||||
|
||||
msg = logs[nbr]
|
||||
print(msg)
|
||||
|
||||
out_0 = (21, 28)
|
||||
if int(nbr) in out_0: nbr = 0
|
||||
if out: sys.exit(int(nbr))
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
#!/usr/bin/env python3
|
||||
# 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: Create something new (domain, sidebar...)
|
||||
# File: /var/lib/tyto/program/new.py
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
#------------
|
||||
# funny stats
|
||||
#------------
|
||||
# lines:
|
||||
# functions:
|
||||
# comments:
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
#**********************************************************************
|
||||
|
||||
import sys
|
||||
import args, dom, logs, form, html
|
||||
|
||||
|
||||
#===============================================#
|
||||
# manage argument new for #
|
||||
# - domain: target becomes 3rd command argument #
|
||||
#-----------------------------------------------#
|
||||
def manage(target):
|
||||
# Generic option, except for domain
|
||||
option = 'new'
|
||||
if target == "domain":
|
||||
try: option = sys.argv[3]
|
||||
except: option = ''
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
actions[target](option)
|
||||
else:
|
||||
logs.out("11", '"%s" with "%s"'%(target, option), True)
|
|
@ -0,0 +1,263 @@
|
|||
#!/usr/bin/env python3
|
||||
# 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: Publish on www server
|
||||
# File: /var/lib/tyto/program/publish.py
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
#------------
|
||||
# funny stats
|
||||
#------------
|
||||
# lines:
|
||||
# functions:
|
||||
# comments:
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
#**********************************************************************
|
||||
|
||||
import os, sys, shutil, importlib
|
||||
from pathlib import Path
|
||||
import logs, args, dom, db, wip, html, tyto, form, stats, rss, langs
|
||||
|
||||
#==============================#
|
||||
# Manage action, get post db #
|
||||
# check if publish can be done #
|
||||
#------------------------------#
|
||||
def manage_publish(target):
|
||||
dom.valid()
|
||||
|
||||
# Target is footer, sidebar, navbar, metas
|
||||
# template: create/copy template/ files
|
||||
# all: publish all wip article
|
||||
#-----------------------------------------
|
||||
if target in args.pass_targets:
|
||||
do = {
|
||||
'updated' : publish_all,
|
||||
'again' : publish_all,
|
||||
'added' : publish_all,
|
||||
'sidebar' : html.create_sidebar,
|
||||
'navbar' : html.create_navbar,
|
||||
'metas' : html.create_user_metas,
|
||||
'footer' : html.create_user_footer,
|
||||
'template' : publish_template,
|
||||
'stats' : stats.manage
|
||||
}
|
||||
|
||||
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)
|
||||
if not db.exists: logs.out("25", db.uri_file, True)
|
||||
|
||||
# Publish in www server an article
|
||||
check_to_publish('one')
|
||||
|
||||
# Article already published
|
||||
if db.file_www:
|
||||
logs.out("85", '%s > %s'%(db.date_chk, db.uri_file), False)
|
||||
answer = form.asking(' ├ %s%s '%(
|
||||
langs.site.publish_a, langs.site.q
|
||||
), True)
|
||||
|
||||
# Publish
|
||||
publish_article()
|
||||
|
||||
# Create new ATOM/RSS file
|
||||
rss.create_feed()
|
||||
|
||||
|
||||
#============================================#
|
||||
# Option 'all' to publish again, based on DB #
|
||||
#--------------------------------------------#
|
||||
def publish_all(option):
|
||||
tyto.show_multi_message('www', dom.srv_www)
|
||||
form.asking(' ├ %s%s '%(langs.site.proceed, langs.site.q), True)
|
||||
|
||||
# Sort by newer articles (created by last check)
|
||||
db_articles = sorted(Path(dom.articles_db_d).iterdir(),
|
||||
key=os.path.getmtime
|
||||
)
|
||||
|
||||
# Load domain configuration DB
|
||||
option = args.target
|
||||
found = False
|
||||
for post_db in db_articles:
|
||||
if not str(post_db).endswith('.config'): continue
|
||||
|
||||
# Load DB
|
||||
exec(open(post_db).read(),globals())
|
||||
args.target = short_src
|
||||
importlib.reload(db)
|
||||
|
||||
if option == "again" and not db.www_again: continue
|
||||
elif option == "added" and not db.www_added: continue
|
||||
elif option == "updated" and not db.www_updated: continue
|
||||
|
||||
check_to_publish('all')
|
||||
if err_pub:
|
||||
continue
|
||||
|
||||
found = True
|
||||
publish_article()
|
||||
|
||||
if not found:
|
||||
logs.out("28", 'publish %s'%option, True)
|
||||
|
||||
# If found: create new ATOM/RSS file
|
||||
rss.create_feed()
|
||||
|
||||
|
||||
#==============================#
|
||||
# Check if it can be published #
|
||||
#------------------------------#
|
||||
def check_to_publish(process):
|
||||
global err_pub
|
||||
err_pub = False
|
||||
|
||||
print(' │\n ├ [%s] > %s'%(db.title, db.post_src))
|
||||
|
||||
# Article was not checked or changed
|
||||
if db.no_chk:
|
||||
logs.out("25", db.uri_file, False)
|
||||
err_pub = 25
|
||||
elif db.old_chk:
|
||||
logs.out("9", db.uri_file, False)
|
||||
err_pub = 9
|
||||
|
||||
# Article must exists in wip server
|
||||
if db.no_wip or db.old_wip:
|
||||
logs.out("30", db.uri_file, False)
|
||||
err_pub = 30
|
||||
elif not db.file_wip:
|
||||
logs.out("1", db.post_wip, False)
|
||||
err_pub = 1
|
||||
|
||||
if err_pub:
|
||||
if process == 'all': return
|
||||
elif process == 'one': sys.exit(err_pub)
|
||||
|
||||
#===============#
|
||||
# Let's publish #
|
||||
#---------------#
|
||||
def publish_article():
|
||||
# Copy wip page to www page
|
||||
if not os.makedirs('%s%s'%(dom.srv_www, db.direc_src), exist_ok=True):
|
||||
logs.out("33", '%s%s'%(dom.srv_www, db.direc_src), False)
|
||||
|
||||
# Replace in DB hash_wip and date_wip
|
||||
tyto.replace_in_db(db.config, 'www', db.hash_post)
|
||||
|
||||
# Copy needed files (Also create sub-folders)
|
||||
tyto.files_to_srv('www')
|
||||
|
||||
# Replace publish HTML line
|
||||
replace_lines_pub()
|
||||
|
||||
|
||||
#=================================================#
|
||||
# Replace line in article containing publish date #
|
||||
#-------------------------------------------------#
|
||||
def replace_lines_pub():
|
||||
html.create_html_time_meta('publish')
|
||||
|
||||
in_pub = False
|
||||
wip_html_post = open(db.post_wip, 'r').read()
|
||||
www_html_post = wip_html_post
|
||||
|
||||
for line in wip_html_post.rsplit('\n'):
|
||||
if line.startswith('<!--Tyto_Published-->'):
|
||||
in_pub = True
|
||||
time_wip_pub = line
|
||||
continue
|
||||
|
||||
elif line.startswith('<!--/Tyto_Published-->'):
|
||||
time_wip_pub = '%s\n%s'%(time_wip_pub, line)
|
||||
in_pub = False
|
||||
break
|
||||
|
||||
elif line.startswith('<!--Tyto_Meta-->'):
|
||||
time_wip_meta = line
|
||||
continue
|
||||
|
||||
if in_pub:
|
||||
time_wip_pub = '%s\n%s'%(time_wip_pub, line)
|
||||
|
||||
# Update file with new time meta
|
||||
try:
|
||||
www_html_post = \
|
||||
www_html_post.replace(time_wip_meta,
|
||||
html.meta_pub
|
||||
)
|
||||
except:
|
||||
logs.out("45", db.post_www, False)
|
||||
|
||||
# update file with new article time
|
||||
try:
|
||||
www_html_post = \
|
||||
www_html_post.replace(time_wip_pub,
|
||||
html.time_html_pub
|
||||
)
|
||||
except:
|
||||
logs.out("46", db.post_www, False)
|
||||
|
||||
|
||||
tyto.set_file(db.post_www, 'New', www_html_post)
|
||||
|
||||
|
||||
#================================#
|
||||
# Publish template in www server #
|
||||
#--------------------------------#
|
||||
def publish_template(option):
|
||||
form.asking(' ├ %s%s > %s '%(
|
||||
langs.site.uptpl, langs.site.q,
|
||||
dom.srv_www_tpl_d
|
||||
), True)
|
||||
|
||||
# Copy all file in wip server template, except "nofiles"
|
||||
nofiles = (
|
||||
'footer.html',
|
||||
'metas.html',
|
||||
'navbar.html',
|
||||
'sidebar.html'
|
||||
)
|
||||
|
||||
for item in os.listdir(dom.srv_wip_tpl_d):
|
||||
if item.startswith(nofiles):
|
||||
continue
|
||||
|
||||
item_src = '%s%s'%(dom.srv_wip_tpl_d, item)
|
||||
item_dst = '%s%s'%(dom.srv_www_tpl_d, item)
|
||||
if os.path.isdir(item_src):
|
||||
shutil.copytree(item_src, item_dst, dirs_exist_ok=True)
|
||||
logs.out("33", item_dst, False)
|
||||
else:
|
||||
shutil.copy2(item_src, item_dst)
|
||||
logs.out("32", item_dst, False)
|
||||
|
||||
# Create new file from _configs/ files
|
||||
html.create_sidebar('pub')
|
||||
html.create_navbar('pub')
|
||||
html.create_user_metas('pub')
|
||||
html.create_user_footer('pub')
|
||||
|
||||
|
|
@ -0,0 +1,125 @@
|
|||
#!/usr/bin/env python3
|
||||
# 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: Create feed RSS/Atom
|
||||
# File: /var/lib/tyto/program/rss.py
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
#------------
|
||||
# funny stats
|
||||
#------------
|
||||
# lines:
|
||||
# functions:
|
||||
# comments:
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
#*********************************************************************
|
||||
|
||||
import os
|
||||
from pathlib import Path
|
||||
import logs, dom, db, tyto, langs
|
||||
|
||||
|
||||
#============================#
|
||||
# Create ATOM/RSS feed #
|
||||
# only with publish argument #
|
||||
#----------------------------#
|
||||
def create_feed():
|
||||
# Generic fedd Header
|
||||
set_f = \
|
||||
'<?xml version="1.0" encoding="utf-8"?>\n' + \
|
||||
'<rss version="2.0">\n' + \
|
||||
' <channel>\n' + \
|
||||
' <title>%s - %s - Flux RSS 2.0</title>\n'%(
|
||||
dom.title, dom.www_url
|
||||
) + \
|
||||
' <link>%s</link>\n'%dom.www_url + \
|
||||
' <description>RSS 2.0 - %s (%s)</description>\n'%(
|
||||
dom.title, dom.about
|
||||
) + \
|
||||
' <image>\n' + \
|
||||
' <url>%s/%s</url>\n'%(dom.www_url, dom.logo) + \
|
||||
' <title>logo %s</title>\n'%dom.title + \
|
||||
' <link>%s</link>\n'%dom.www_url + \
|
||||
' </image>\n' + \
|
||||
' <language>%s</language>\n'%dom.lang_site + \
|
||||
' <category>%s</category>\n'%dom.tags + \
|
||||
' <lastBuildDate>%s</lastBuildDate>\n'%tyto.nowdate() + \
|
||||
' <copyright>%s</copyright>\n'%dom.license + \
|
||||
' <webMaster>%s</webMaster>\n'%dom.mail + \
|
||||
' <generator>%s</generator>'%tyto.Tyto
|
||||
|
||||
# Sort by newer articles (created by last check)
|
||||
db_articles = sorted(Path(dom.articles_db_d).iterdir(),
|
||||
key=os.path.getmtime,
|
||||
reverse=True
|
||||
)
|
||||
|
||||
rss_item = False
|
||||
nbr_item = 0
|
||||
|
||||
# Loop published articles. Get databases of articles
|
||||
for post_db in db_articles:
|
||||
if not str(post_db).endswith('.config'):
|
||||
continue
|
||||
|
||||
# Load DB
|
||||
exec(open(post_db).read(),globals())
|
||||
if not hash_www or hash_chk != hash_www:
|
||||
continue
|
||||
|
||||
rss_item = True
|
||||
nbr_item += 1
|
||||
|
||||
if nbr_item > dom.rss_items:
|
||||
break
|
||||
|
||||
set_f = \
|
||||
'%s\n'%set_f + \
|
||||
'\n <item>\n' + \
|
||||
' <title>%s</title>\n'%title + \
|
||||
' <link>%s</link>\n'%http_www + \
|
||||
' <guid>%s</guid>\n'%http_www + \
|
||||
' <pubDate>%s</pubDate>\n'%date_www + \
|
||||
' <description>%s</description>\n'%about + \
|
||||
' <author>%s</author>\n'%author + \
|
||||
' <image>\n' + \
|
||||
' <url>%s</url>\n'%snpic + \
|
||||
' <title>%s</title>\n'%(title) + \
|
||||
' <link>%s</link>\n'%http_www + \
|
||||
' </image>\n' + \
|
||||
' <category>%s</category>\n'%tags + \
|
||||
' </item>'
|
||||
|
||||
|
||||
# Do nothing if no item
|
||||
if not rss_item:
|
||||
logs.out("28", '(ATOM/RSS)', False)
|
||||
return
|
||||
|
||||
set_f = \
|
||||
'%s\n'%set_f + \
|
||||
' </channel>\n' + \
|
||||
'</rss>'
|
||||
|
||||
print(' │\n ├─ %s'%langs.site.rss_c)
|
||||
tyto.set_file(dom.www_rss_f, 'New', set_f)
|
||||
|
|
@ -0,0 +1,203 @@
|
|||
#!/usr/bin/env python3
|
||||
# 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: Manage show*/edit* arguments.
|
||||
# Read or edit file from [target] argument
|
||||
# File: /var/lib/tyto/program/show.py
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
#------------
|
||||
# funny stats
|
||||
#------------
|
||||
# lines:
|
||||
# functions:
|
||||
# comments:
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
#**********************************************************************
|
||||
|
||||
import os, sys, importlib
|
||||
import args, logs, langs, dom, db, form, tyto, check, html, stats
|
||||
|
||||
#========================#
|
||||
# Read lines from a file #
|
||||
# alone: True/False #
|
||||
#------------------------#
|
||||
def read_lines(f, alone):
|
||||
if not f: return
|
||||
if not tyto.exists(f): logs.out("1", f, True)
|
||||
|
||||
datas = open(f).read()
|
||||
|
||||
# Align content line, after line number
|
||||
ln_datas = len(datas.splitlines()) + 1
|
||||
sp_max = len(str(ln_datas))
|
||||
|
||||
print(' ├', f)
|
||||
print(' ├─%s─┐'%(sp_max * '─'))
|
||||
for ln, line in enumerate(datas.rsplit('\n'), 1):
|
||||
sp = sp_max - len(str(ln))
|
||||
print(' │%s %s │ %s'%(int(sp) * " ", ln, line))
|
||||
|
||||
# Ends for show. False should be for form
|
||||
if alone: decor = '└'
|
||||
else: decor = '├'
|
||||
print(' %s─%s─┘'%(decor, sp_max * '─'))
|
||||
|
||||
if not f == dom.config: dom.valid()
|
||||
|
||||
|
||||
#======================#
|
||||
# From command line: #
|
||||
# Show or edit file #
|
||||
# final html, db, src #
|
||||
#----------------------#
|
||||
def manage(target):
|
||||
if not dom.exists: logs.out("10", '', True)
|
||||
dom.valid()
|
||||
|
||||
actions_read = ('show', 'show-about', 'show-db', 'show-wip', 'show-www')
|
||||
actions_edit = ('edit', 'edit-about', 'edit-db', 'edit-wip', 'edit-www')
|
||||
post_src = post_db = post_wip = post_www = False
|
||||
|
||||
# Set file from post DB when target is an article
|
||||
#------------------------------------------------
|
||||
try: post_src = db.uri_file
|
||||
except: pass
|
||||
|
||||
if post_src:
|
||||
target = "post"
|
||||
try: post_db = db.config
|
||||
except: pass
|
||||
|
||||
try: post_wip = db.post_wip
|
||||
except: pass
|
||||
|
||||
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[]
|
||||
# as edit* &nd show* [action] have same target file
|
||||
actions = \
|
||||
{
|
||||
"show" : 'src',
|
||||
"edit" : 'src',
|
||||
"post" : 'src',
|
||||
"show-db" : 'db',
|
||||
"edit-db" : 'db',
|
||||
"show-about" : 'about',
|
||||
"edit-about" : 'about',
|
||||
"show-wip" : 'wip',
|
||||
"edit-wip" : 'wip',
|
||||
"show-www" : 'www',
|
||||
"edit-www" : 'www'
|
||||
}
|
||||
action = actions[args.action]
|
||||
|
||||
# Set target file from "new" [action]
|
||||
do = \
|
||||
{
|
||||
'src' : {
|
||||
"domain" : dom.config,
|
||||
"footer" : dom.footer_f,
|
||||
"metas" : dom.metas_f,
|
||||
"navbar" : dom.navbar_f,
|
||||
"sidebar" : dom.sidebar_f,
|
||||
"post" : post_src
|
||||
},
|
||||
'db' : {
|
||||
"domain" : dom.config,
|
||||
"footer" : dom.footer_f,
|
||||
"metas" : dom.metas_f,
|
||||
"navbar" : dom.navbar_f,
|
||||
"sidebar" : dom.sidebar_f,
|
||||
"post" : post_db
|
||||
},
|
||||
'about' : {
|
||||
"domain" : dom.config,
|
||||
"footer" : dom.footer_about_f,
|
||||
"metas" : dom.metas_f,
|
||||
"navbar" : dom.navbar_f,
|
||||
"sidebar" : dom.sidebar_f,
|
||||
"post" : post_db
|
||||
},
|
||||
'wip' : {
|
||||
"domain" : dom.config,
|
||||
"footer" : dom.wip_footer_f,
|
||||
"metas" : dom.wip_metas_f,
|
||||
"navbar" : dom.wip_navbar_f,
|
||||
"sidebar" : dom.wip_sidebar_f,
|
||||
"post" : post_wip,
|
||||
"stats" : dom.wip_stats_f,
|
||||
},
|
||||
'www' : {
|
||||
"domain" : dom.config,
|
||||
"footer" : dom.www_footer_f,
|
||||
"metas" : dom.www_metas_f,
|
||||
"navbar" : dom.www_navbar_f,
|
||||
"sidebar" : dom.www_sidebar_f,
|
||||
"post" : post_www,
|
||||
"stats" : dom.www_stats_f,
|
||||
},
|
||||
}
|
||||
|
||||
# Read or edit file, according to legacy args.action
|
||||
try:
|
||||
file = do[action][target]
|
||||
|
||||
if args.action in actions_read:
|
||||
read_lines(file, True)
|
||||
|
||||
elif args.action in actions_edit:
|
||||
curr_hash = tyto.get_filesum(file, True)
|
||||
tyto.edit_file(file)
|
||||
|
||||
except:
|
||||
logs.out("28", '%s + %s'%(args.action, target), True)
|
||||
|
||||
|
||||
# If edit article and hash changed, ask to check
|
||||
if args.action == "edit":
|
||||
new_hash = tyto.get_filesum(file, True)
|
||||
|
||||
if curr_hash == new_hash: return
|
||||
|
||||
# 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)
|
||||
|
||||
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')
|
||||
|
||||
|
|
@ -0,0 +1,225 @@
|
|||
#!/usr/bin/env python3
|
||||
# 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: Create total statistics file for www or wip
|
||||
# File: /var/lib/tyto/program/stats.py
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
#------------
|
||||
# funny stats
|
||||
#------------
|
||||
# lines:
|
||||
# functions:
|
||||
# comments:
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
#**********************************************************************
|
||||
|
||||
import os, importlib
|
||||
import args, dom, logs, form, tyto, show, langs
|
||||
|
||||
sti_articles = 0
|
||||
|
||||
#=======================#
|
||||
# Manage "stats" option #
|
||||
#-----------------------#
|
||||
def manage(process):
|
||||
dom.valid()
|
||||
|
||||
global file_uri, domain_srv
|
||||
|
||||
if process == 'wip':
|
||||
file_uri = dom.wip_stats_f
|
||||
domain_srv = dom.wip_url
|
||||
elif process == 'www':
|
||||
file_uri = dom.www_stats_f
|
||||
domain_srv = dom.www_url
|
||||
|
||||
loop_articles(process)
|
||||
|
||||
|
||||
#==========================#
|
||||
# Check databases' article #
|
||||
#--------------------------#
|
||||
def loop_articles(process):
|
||||
global sti_articles
|
||||
|
||||
# Get databases of articles
|
||||
for db in os.listdir(dom.articles_db_d):
|
||||
if not db.endswith('.config'):
|
||||
continue
|
||||
|
||||
# Load DB
|
||||
db = '%s%s'%(dom.articles_db_d, db)
|
||||
exec(open(db).read(),globals())
|
||||
|
||||
# Check hash status (wip/www)
|
||||
hash_srv = ''
|
||||
if process == 'wip': hash_srv = hash_wip
|
||||
elif process == 'www': hash_srv = hash_www
|
||||
|
||||
# - Now generic for wip and www
|
||||
# - Article has changed and could have different stats
|
||||
if not hash_srv or \
|
||||
hash_srv != hash_chk:
|
||||
continue
|
||||
|
||||
sti_articles += 1
|
||||
if sti_articles == 1: count_stats(False)
|
||||
else: count_stats(True)
|
||||
|
||||
# Create file if article
|
||||
if sti_articles > 0: create_stats_file(file_uri)
|
||||
else: logs.out("28", '%s stats'%process, True)
|
||||
|
||||
|
||||
#===============================#
|
||||
# False: Set First statistics #
|
||||
# True: Count total statistics #
|
||||
#-------------------------------#
|
||||
def count_stats(add):
|
||||
# Set
|
||||
if not add:
|
||||
global stats, authors, author_names
|
||||
|
||||
# Specific for Authors (not in database stats)
|
||||
author_names = author.replace(' ', '').split(",")
|
||||
authors = 0
|
||||
|
||||
stats = { \
|
||||
"sti_uniq_anchors" : uniq_anchors,
|
||||
"sti_uniq_abbrs" : uniq_abbrs,
|
||||
"sti_uniq_links" : uniq_links,
|
||||
"sti_uniq_images" : uniq_images,
|
||||
"sti_uniq_files" : uniq_files,
|
||||
"sti_uniq_codes" : uniq_codes,
|
||||
"sti_uniq_raws" : uniq_raws,
|
||||
"sti_comments" : comments,
|
||||
"sti_tags" : tags,
|
||||
"sti_lines" : lines,
|
||||
"sti_words" : words,
|
||||
"sti_titles" : titles,
|
||||
"sti_paragraphs" : paragraphs,
|
||||
"sti_links" : links,
|
||||
"sti_images" : images,
|
||||
"sti_anchors" : anchors,
|
||||
"sti_abbrs" : abbrs,
|
||||
"sti_strongs" : strongs,
|
||||
"sti_bolds" : bolds,
|
||||
"sti_emphasis" : emphasis,
|
||||
"sti_italics" : italics,
|
||||
"sti_dels" : dels,
|
||||
"sti_underlines" : underlines,
|
||||
"sti_cites" : cites,
|
||||
"sti_customs" : customs,
|
||||
"sti_icodes" : icodes,
|
||||
"sti_bcodes" : bcodes,
|
||||
"sti_quotes" : quotes,
|
||||
"sti_lists" : lists,
|
||||
"sti_files" : files,
|
||||
"sti_raws" : raws,
|
||||
"sti_codes" : codes,
|
||||
}
|
||||
|
||||
# Count
|
||||
else:
|
||||
# Authors are not set in database stats
|
||||
new_authors = author.replace(' ', '').split(",")
|
||||
|
||||
# Do not count author if known
|
||||
for name in new_authors:
|
||||
if name in author_names:
|
||||
continue
|
||||
|
||||
author_names = author_names + [name]
|
||||
|
||||
# From database stats
|
||||
for i in stats:
|
||||
stat_db = i.rsplit("sti_")[1]
|
||||
stats[i] = stats[i] + eval(stat_db)
|
||||
|
||||
|
||||
#============================#
|
||||
# Create stat file in server #
|
||||
#----------------------------#
|
||||
def create_stats_file(file_uri):
|
||||
# Count authors
|
||||
authors = len(author_names)
|
||||
|
||||
sti = \
|
||||
'# Statistics file created by %s\n'%tyto.Tyto + \
|
||||
'# Website: %s\n'%domain_srv + \
|
||||
'# File: %s\n'%file_uri + \
|
||||
'# Generated: %s\n'%tyto.nowdate() + \
|
||||
'\n' + \
|
||||
'# Uniq statistics from articles headers\n' + \
|
||||
'articles = %d\n'%int(sti_articles) + \
|
||||
'uniq_authors = %d\n'%int(authors) + \
|
||||
'uniq_anchors = %d\n'%stats["sti_uniq_anchors"] + \
|
||||
'uniq_abbrs = %d\n'%stats["sti_uniq_abbrs"] + \
|
||||
'uniq_links = %d\n'%stats["sti_uniq_links"] + \
|
||||
'uniq_images = %d\n'%stats["sti_uniq_images"] + \
|
||||
'uniq_files = %d\n'%stats["sti_uniq_files"] + \
|
||||
'uniq_codes = %d\n'%stats["sti_uniq_codes"] + \
|
||||
'uniq_raws = %d\n'%stats["sti_uniq_raws"] + \
|
||||
'\n' + \
|
||||
'# Statistics from articles contents\n' + \
|
||||
'comments = %d\n'%stats["sti_comments"] + \
|
||||
'tags = %d\n'%stats["sti_tags"] + \
|
||||
'lines = %d\n'%stats["sti_lines"] + \
|
||||
'words = %d\n'%stats["sti_words"] + \
|
||||
'titles = %d\n'%stats["sti_titles"] + \
|
||||
'paragraphs = %d\n'%stats["sti_paragraphs"] + \
|
||||
'links = %d\n'%stats["sti_links"] + \
|
||||
'images = %d\n'%stats["sti_images"] + \
|
||||
'anchors = %d\n'%stats["sti_anchors"] + \
|
||||
'abbrs = %d\n'%stats["sti_abbrs"] + \
|
||||
'strongs = %d\n'%stats["sti_strongs"] + \
|
||||
'bolds = %d\n'%stats["sti_bolds"] + \
|
||||
'emphasis = %d\n'%stats["sti_emphasis"] + \
|
||||
'italics = %d\n'%stats["sti_italics"] + \
|
||||
'dels = %d\n'%stats["sti_dels"] + \
|
||||
'underlines = %d\n'%stats["sti_underlines"] + \
|
||||
'cites = %d\n'%stats["sti_cites"] + \
|
||||
'customs = %d\n'%stats["sti_customs"] + \
|
||||
'icodes = %d\n'%stats["sti_icodes"] + \
|
||||
'bcodes = %d\n'%stats["sti_bcodes"] + \
|
||||
'quotes = %d\n'%stats["sti_quotes"] + \
|
||||
'lists = %d\n'%stats["sti_lists"] + \
|
||||
'\n' + \
|
||||
'# Included files in articles contents\n' + \
|
||||
'files = %d\n'%stats["sti_files"] + \
|
||||
'codes = %d\n'%stats["sti_codes"] + \
|
||||
'raws = %d\n'%stats["sti_raws"]
|
||||
|
||||
|
||||
tyto.set_file(file_uri, 'New', sti)
|
||||
try:
|
||||
print(' └', langs.site.stats_f%(
|
||||
sti_articles, stats["sti_words"]
|
||||
)
|
||||
)
|
||||
except:
|
||||
print(' └ Articles = %s ; Words = %s'%(
|
||||
sti_articles, stats["sti_words"]
|
||||
)
|
||||
)
|
||||
|
|
@ -0,0 +1,133 @@
|
|||
#!/usr/bin/env python3
|
||||
# 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: Show statuses for domain
|
||||
# File: /var/lib/tyto/program/status.py
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
#------------
|
||||
# funny stats
|
||||
#------------
|
||||
# lines:
|
||||
# functions:
|
||||
# comments:
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
#**********************************************************************
|
||||
|
||||
import args, dom, logs, tyto, form, db
|
||||
|
||||
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)
|
||||
|
||||
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)
|
||||
|
||||
# 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 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
|
||||
}
|
||||
|
||||
for value in dom.file_mod:
|
||||
create_files[value]('form')
|
||||
|
||||
for file_mods in dom.wip_html_mods:
|
||||
if not tyto.exists(file_mods):
|
||||
logs.out("1", file_mods, False)
|
||||
|
||||
#==============================#
|
||||
# On demand with status action #
|
||||
#------------------------------#
|
||||
def check(target):
|
||||
# target needed
|
||||
if not target:
|
||||
logs.out("5", '[target]', True)
|
||||
|
||||
elif target == "domain":
|
||||
conf_err = False
|
||||
|
||||
if dom.dir_unu or dom.file_unu:
|
||||
logs.out("60", '', False)
|
||||
|
||||
for dir_unu in dom.dir_unu:
|
||||
logs.out("1", dir_unu, False)
|
||||
conf_err = True
|
||||
|
||||
for file_unu in dom.file_unu:
|
||||
logs.out("24", file_unu, False)
|
||||
|
||||
if conf_err:
|
||||
logs.out("31", '', True)
|
||||
return
|
||||
|
||||
# Unused file
|
||||
elif not db.post:
|
||||
logs.out("1", db.uri_file, True)
|
||||
|
||||
# Article has DB
|
||||
elif db.exists:
|
||||
# Article datas
|
||||
print(' │\n ├ [%s] > %s'%(db.title, db.uri_file))
|
||||
|
||||
# chk
|
||||
if db.old_chk: logs.out("94", db.uri_file, False)
|
||||
else: logs.out("20", db.uri_file, False)
|
||||
|
||||
# wip
|
||||
if not db.file_wip: logs.out("71", db.post_wip, False)
|
||||
else: logs.out("72", db.post_wip, False)
|
||||
if db.no_wip: logs.out("73", db.post_wip, False)
|
||||
elif db.old_wip: logs.out("74", db.post_wip, False)
|
||||
|
||||
# www
|
||||
if not db.file_www: logs.out("81", db.post_www, False)
|
||||
else: logs.out("82", db.post_www, False)
|
||||
if db.no_www: logs.out("83", db.post_www, False)
|
||||
elif db.old_www: logs.out("84", db.post_www, False)
|
||||
return
|
||||
|
||||
# Article has NO DB
|
||||
elif not db.exists:
|
||||
logs.out("25", db.uri_file, True)
|
||||
|
|
@ -0,0 +1,566 @@
|
|||
#!/usr/bin/env python3
|
||||
# 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: Tools and some seetings.
|
||||
# File: /var/lib/tyto/program/tyto.py
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
#------------
|
||||
# funny stats
|
||||
#------------
|
||||
# lines:
|
||||
# functions:
|
||||
# comments:
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
#**********************************************************************
|
||||
|
||||
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'
|
||||
Tytoweb = 'https://tyto.echolib.re'
|
||||
|
||||
|
||||
# Needed header tags
|
||||
needed_header_tags = \
|
||||
(
|
||||
'title',
|
||||
'about',
|
||||
'author',
|
||||
'tags',
|
||||
'date'
|
||||
)
|
||||
|
||||
# Optional header tags
|
||||
opt_header_tags = \
|
||||
(
|
||||
'file',
|
||||
'image',
|
||||
'link',
|
||||
'abbr',
|
||||
'raw',
|
||||
'code',
|
||||
'snpic'
|
||||
)
|
||||
|
||||
opt_tags_long_name = \
|
||||
(
|
||||
'link',
|
||||
'file'
|
||||
)
|
||||
|
||||
opt_tags_check_uri = \
|
||||
(
|
||||
'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:',
|
||||
)
|
||||
|
||||
|
||||
# Words and template Tags (paragraphs, lists, bold, strong...)
|
||||
# Used to check, and replace (wip) tags
|
||||
# As base64 is used, do NOT set marker: =_ _=
|
||||
# [5] = name for stats and log.
|
||||
# [6] = Check content differently. 't' = startswith
|
||||
#-------------------------------------------------------------
|
||||
words_tags = [
|
||||
('>_', '_<', '<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'),
|
||||
('((', '))', '<p class="%s">', '</p>', 'paragraphs', 't'),
|
||||
('[[', ']]', '[[', ']]', 'quotes', 't'),
|
||||
('{{', '}}', '{{', '}}', 'bcodes', 't'),
|
||||
('-(', '-)', '-(', '-)', 'lists', 't')
|
||||
]
|
||||
|
||||
# Tags that do not need to be paired
|
||||
#-----------------------------------
|
||||
single_tags = [
|
||||
('|', '<br class="%s" />'), # New Line
|
||||
('->', '<a class="anchor_target" id="%s"></a>') # Anchors
|
||||
]
|
||||
|
||||
# When counting words, do no count line starting with:
|
||||
nolinewords = \
|
||||
(
|
||||
words_tags[10][0], words_tags[10][1], # paragraphs
|
||||
words_tags[11][0], words_tags[11][1], # quotes
|
||||
words_tags[12][0], words_tags[12][1], # bcodes
|
||||
words_tags[13][0], words_tags[13][1], # lists
|
||||
single_tags[0][0], single_tags[1][0], # New line, anchor
|
||||
'_%s:'%opt_header_tags[1], '_%s:'%opt_header_tags[4], # _image:, _raw:
|
||||
'_%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>'),
|
||||
]
|
||||
|
||||
|
||||
# Markers for lists, to check in list content
|
||||
#--------------------------------------------
|
||||
markers_lists = ('+', '=', ' ', '#')
|
||||
|
||||
# Tags used for titles
|
||||
#---------------------
|
||||
titles_tags = ('#1 ', '#2 ', '#3 ', '#4 ', '#5 ', '#6 ')
|
||||
|
||||
|
||||
# Tags for quote
|
||||
quote_tags = [
|
||||
('_cite:', 'author'),
|
||||
('_date:', 'date'),
|
||||
('_link:', 'link'),
|
||||
('_book:', 'book'),
|
||||
('_lang:', 'lang')
|
||||
]
|
||||
|
||||
# Tags to check in header in content _TAG
|
||||
head_tags = ("image:", "raw:", "code;")
|
||||
|
||||
# Valid characters for some datas
|
||||
chrs_invalid = \
|
||||
set('{}[]_()+*=/:%~´')
|
||||
|
||||
|
||||
# Stats for icodes, bcodes, quotes
|
||||
nbr_icodes = 0
|
||||
|
||||
|
||||
#=======#
|
||||
# TOOLS #
|
||||
#=======#--------------------------------------------------------------
|
||||
#
|
||||
# Return True if file exists
|
||||
#
|
||||
def exists(uri):
|
||||
if os.path.exists(uri): return(True)
|
||||
else: return(False)
|
||||
|
||||
|
||||
#========================================#
|
||||
# Return converted valid HTML characters #
|
||||
#----------------------------------------#
|
||||
def convert_altname(altname):
|
||||
altname = altname.replace('<', '<')
|
||||
altname = altname.replace('>', '>')
|
||||
altname = altname.replace('"', '"')
|
||||
altname = altname.replace("'", ''')
|
||||
|
||||
return altname
|
||||
|
||||
|
||||
#=======================#
|
||||
# Return sum of srcfile #
|
||||
# src: True = Content #
|
||||
# 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())
|
||||
else: file_sum.update(path.encode())
|
||||
return file_sum.hexdigest()
|
||||
|
||||
|
||||
#==============================#
|
||||
# Set and return date and time #
|
||||
#------------------------------#
|
||||
def nowdate():
|
||||
now = datetime.datetime.now()
|
||||
return(now.strftime('%Y-%m-%d %H:%M:%S'))
|
||||
|
||||
|
||||
#======================#
|
||||
# Open and edit a file #
|
||||
#----------------------#
|
||||
def edit_file(edit_file):
|
||||
if not os.path.exists(edit_file):
|
||||
logs.out("1", edit_file, True)
|
||||
|
||||
try:
|
||||
file_edit = subprocess.run(
|
||||
[
|
||||
'/usr/bin/nano',
|
||||
'--linenumbers',
|
||||
edit_file
|
||||
]
|
||||
)
|
||||
except:
|
||||
logs.out("1", "/usr/bin/nano", True)
|
||||
|
||||
|
||||
#=====================#
|
||||
# Create a file #
|
||||
# Or append text #
|
||||
# new: True = create #
|
||||
# False = Append #
|
||||
#---------------------#
|
||||
def set_file(path, new, text):
|
||||
if new: opt = "w"
|
||||
else: opt = "a"
|
||||
|
||||
try:
|
||||
file = open(path, opt)
|
||||
file.write(text + '\n')
|
||||
file.close()
|
||||
if opt == 'w':
|
||||
logs.out("32", path, False)
|
||||
except:
|
||||
logs.out("4", path, True)
|
||||
|
||||
|
||||
#==========================#
|
||||
# Get CSS from line if set #
|
||||
#--------------------------#
|
||||
def get_css(line):
|
||||
# Use this default, if not in conf
|
||||
css = 'tyto'
|
||||
|
||||
try: css = dom.css
|
||||
except: pass
|
||||
|
||||
# Get CSS from line
|
||||
try: css = re.search (r'(?<=' ') +([^ -.]*)', line).group(1)
|
||||
except: pass
|
||||
|
||||
return css
|
||||
|
||||
|
||||
#=============================================#
|
||||
# First check process to protect contents #
|
||||
# Protect block-Codes, quotes #
|
||||
# Also remove empty/commented lines #
|
||||
# Used in check and wip #
|
||||
# check: create string without quotes, bcodes #
|
||||
# wip: remplace quotes, bcode with base64 #
|
||||
#---------------------------------------------#
|
||||
def protect_bcodes_quotes(process, post_bottom):
|
||||
global protect_article
|
||||
global nbr_titles, nbr_bcodes, nbr_quotes # Stats for DB
|
||||
|
||||
in_bcode = in_quote = False
|
||||
protect_article = ''
|
||||
bcode = quote = '' # Only for wip process
|
||||
|
||||
for line in post_bottom.rsplit('\n'):
|
||||
start_bcode = close_bcode = False
|
||||
start_quote = close_quote = False
|
||||
|
||||
# Settings and counters
|
||||
#----------------------
|
||||
# Bcode (at close, replace with base64)
|
||||
if not in_quote:
|
||||
if line.startswith(words_tags[12][0]): # Open
|
||||
start_bcode = True
|
||||
in_bcode = True
|
||||
elif line.startswith(words_tags[12][1]): # Close
|
||||
close_bcode = True
|
||||
in_bcode = False
|
||||
if process == "wip":
|
||||
bcode = '%s\n%s'%(bcode, line)
|
||||
bcode = convert_altname(bcode)
|
||||
b64_bcode = b64('Encode', bcode, 'B64.', '.B64')
|
||||
line = b64_bcode
|
||||
|
||||
# Quote (at close, replace with base64)
|
||||
if not in_bcode:
|
||||
if line.startswith(words_tags[11][0]): # Open
|
||||
start_quote = True
|
||||
in_quote = True
|
||||
elif line.startswith(words_tags[11][1]): # Close
|
||||
close_quote = True
|
||||
in_quote = False
|
||||
if process == "wip":
|
||||
quote = '%s\n%s'%(quote, line)
|
||||
quote = convert_altname(quote)
|
||||
b64_quote = b64('Encode', quote, 'Q64.', '.Q64')
|
||||
line = b64_quote
|
||||
|
||||
|
||||
# Counters and keep tags for check process
|
||||
#-----------------------------------------
|
||||
if process == "check":
|
||||
if in_bcode and not start_bcode \
|
||||
or in_quote and not start_quote :
|
||||
line = '#-Protectedline-'
|
||||
|
||||
# Set new article content for wip process
|
||||
#----------------------------------------
|
||||
elif process == "wip":
|
||||
# Remove empty line and comments
|
||||
if not in_quote and not in_bcode:
|
||||
if not line:
|
||||
continue
|
||||
elif line.startswith('#') and not line.startswith(titles_tags):
|
||||
continue
|
||||
|
||||
# bcode convertion to base64
|
||||
elif in_bcode:
|
||||
# Convert lines to b64
|
||||
if not bcode: bcode = line
|
||||
else: bcode = '%s\n%s'%(bcode, line)
|
||||
line = ''
|
||||
elif in_quote:
|
||||
# Convert lines to b64
|
||||
if not quote: quote = line
|
||||
else: quote = '%s\n%s'%(quote, line)
|
||||
line = ''
|
||||
|
||||
|
||||
# Set new content
|
||||
#----------------
|
||||
# check: remove quote/bcode, keep tags
|
||||
# wip: replace close tag with quote/bcode (keep in open tag)
|
||||
if not protect_article: protect_article = line
|
||||
else: protect_article = '%s\n%s'%(protect_article, line)
|
||||
|
||||
|
||||
# Clean in wip process for new quote/bcode
|
||||
if process == "wip":
|
||||
if close_bcode: bcode = b64_bcode = ''
|
||||
if close_quote: quote = b64_quote = ''
|
||||
|
||||
|
||||
#=======================#
|
||||
# Protec iCodes #
|
||||
# Used in check and wip #
|
||||
#-----------------------~
|
||||
def protect_icodes(post_bottom):
|
||||
global protect_article
|
||||
global nbr_icodes
|
||||
|
||||
protect_article = post_bottom
|
||||
in_icode = False
|
||||
src_code = rep_code = ''
|
||||
|
||||
# Get only lines that contains code
|
||||
for ln, line in enumerate(post_bottom.rsplit('\n')):
|
||||
if not words_tags[9][0] in line: continue
|
||||
|
||||
# Iterate (c)haracter in line
|
||||
for i, c in enumerate(line):
|
||||
c_b = c_bb = c_a = ""
|
||||
if c == '_':
|
||||
c_b = line[i-1] # before
|
||||
c_bb = line[i-2] # before, before
|
||||
c_a = line[i+1] # after
|
||||
|
||||
# incode if
|
||||
if c_b == '{' and not c_bb == '\\':
|
||||
in_icode = True
|
||||
nbr_icodes += 1
|
||||
code = words_tags[9][2]
|
||||
continue
|
||||
|
||||
# No more in code if
|
||||
if c_a == '}' and not c_b == '\\':
|
||||
in_icode = False
|
||||
src_code = convert_altname(src_code)
|
||||
code = '%s%s%s'%(code, src_code, words_tags[9][3])
|
||||
b64_code = b64('Encode', code, 'I64.', '.I64')
|
||||
rep_code = "%s%s%s"%(
|
||||
words_tags[9][0], rep_code, words_tags[9][1]
|
||||
)
|
||||
protect_article = protect_article.replace(rep_code, b64_code)
|
||||
|
||||
src_code = rep_code = b64_code = ''
|
||||
continue
|
||||
|
||||
# Construct original replacement code and source code
|
||||
if in_icode:
|
||||
rep_code = '%s%s'%(rep_code, c)
|
||||
if c == '\\': continue
|
||||
src_code = '%s%s'%(src_code, c)
|
||||
|
||||
|
||||
#=====================================#
|
||||
# Encode/Decode string to/from base64 #
|
||||
# Data protection in UTF8 #
|
||||
#-------------------------------------#
|
||||
def b64(action, content, before, after):
|
||||
if action == 'Encode':
|
||||
global b64_content
|
||||
|
||||
b64_base64 = ''
|
||||
content_bytes = content.encode("utf8")
|
||||
base64_bytes = base64.b64encode(content_bytes)
|
||||
b64_content = before + base64_bytes.decode("utf8") + after
|
||||
return b64_content
|
||||
|
||||
elif action == 'Decode':
|
||||
global src_content
|
||||
|
||||
src_content = ''
|
||||
content_bytes = content.encode("utf8")
|
||||
base64_bytes = base64.b64decode(content_bytes)
|
||||
src_content = base64_bytes.decode("utf8")
|
||||
return src_content
|
||||
|
||||
else:
|
||||
print("Options: 'Encode', 'Decode'")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
#====================================#
|
||||
# Replace in post_db #
|
||||
# Used for wip and publish #
|
||||
# to replace hash and date when done #
|
||||
#------------------------------------#
|
||||
def replace_in_db(post_db, process, hash_post):
|
||||
try:
|
||||
file_db = open(post_db, "r")
|
||||
lines = file_db.readlines()
|
||||
except:
|
||||
logs.out("1", post_db, True)
|
||||
|
||||
new_file = ''
|
||||
|
||||
for line in lines:
|
||||
if line.startswith('hash_%s'%process):
|
||||
line = line.replace(line, 'hash_%s = "%s"'%(process, hash_post))
|
||||
new_file = '%s%s\n'%(new_file, line)
|
||||
elif line.startswith('date_%s'%process):
|
||||
line = line.replace(line, 'date_%s = "%s"'%(process, nowdate()))
|
||||
new_file = '%s%s\n'%(new_file, line)
|
||||
else:
|
||||
if new_file: new_file = '%s%s'%(new_file, line)
|
||||
else: new_file = line
|
||||
|
||||
try:
|
||||
file = open(post_db, 'w')
|
||||
file.write(new_file)
|
||||
file.close()
|
||||
except:
|
||||
logs.out("1", post_db, True)
|
||||
|
||||
|
||||
#===================================#
|
||||
# Copy files used by article to srv #
|
||||
#-----------------------------------#
|
||||
def files_to_srv(server):
|
||||
import db
|
||||
for uri in db.uris:
|
||||
|
||||
# Extract Directories from uri file
|
||||
d_in = uri.split("/")[-1]
|
||||
d_in = uri.rsplit(d_in)[0]
|
||||
|
||||
# Destination file and directories according to server
|
||||
# (remove last / from domain directory value)
|
||||
f_src = '%s%s'%(dom.articles_d[:-1], uri)
|
||||
if server == 'wip':
|
||||
f_dst = '%s%s'%(dom.srv_wip[:-1], uri)
|
||||
d_dst = '%s%s'%(dom.srv_wip[:-1], d_in)
|
||||
elif server == 'www':
|
||||
f_dst = '%s%s'%(dom.srv_www[:-1], uri)
|
||||
d_dst = '%s%s'%(dom.srv_www[:-1], d_in)
|
||||
|
||||
# Create sub-directories in server
|
||||
try:
|
||||
if os.makedirs(d_dst, exist_ok=True):
|
||||
logs.out("33", d_dst, False)
|
||||
except:
|
||||
logs.out('4', d_dst, True)
|
||||
|
||||
# COpy files to server
|
||||
try:
|
||||
shutil.copy2(f_src, f_dst)
|
||||
logs.out("32", f_dst, False)
|
||||
except:
|
||||
logs.out('4', f_dst, True)
|
||||
|
||||
# Copy source post file in server
|
||||
# if article_code is True in domain DB
|
||||
if dom.article_code:
|
||||
if server == "wip": base_srv = dom.srv_wip
|
||||
elif server == "www": base_srv = dom.srv_www
|
||||
|
||||
f_dst = "%s%s"%(base_srv, db.short_src)
|
||||
try:
|
||||
shutil.copy2(db.post_src, f_dst)
|
||||
logs.out("32", f_dst, False)
|
||||
except:
|
||||
logs.out('4', f_dst, True)
|
||||
|
||||
|
||||
#========================================#
|
||||
# For mass treatment, show message about #
|
||||
#----------------------------------------#
|
||||
def show_multi_message(server, srv_dir):
|
||||
if args.target == "added":
|
||||
print(" │ %s '%s' > %s"%(langs.site.srv_added, server, srv_dir))
|
||||
|
||||
elif args.target == "updated":
|
||||
print(" │ %s '%s' > %s "%(langs.site.srv_updated, server, srv_dir))
|
||||
|
||||
elif args.target == "again":
|
||||
print(" │ %s '%s' > %s"%(langs.site.srv_again, server, srv_dir))
|
||||
|
|
@ -1,412 +0,0 @@
|
|||
#!/usr/bin/python
|
||||
# Name: Tyto - Littérateur
|
||||
# Type: Global functions for wip
|
||||
# Description: Converters from Source to HTML
|
||||
# file: wip.py
|
||||
# Folder: /var/lib/tyto/scripts/
|
||||
# By echolib (XMPP: im@echolib.re)
|
||||
# License: GNU AFFERO GENERAL PUBLIC LICENSE Version 3, 19 November 2007
|
||||
|
||||
#------------
|
||||
# funny stats
|
||||
#------------
|
||||
# lines:
|
||||
# functions:
|
||||
# comments:
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
#**********************************************************************
|
||||
|
||||
import os, sys
|
||||
import check,log,domain
|
||||
|
||||
Tyto_Err = False
|
||||
post_uri = ''
|
||||
#
|
||||
# Manage WIP argument
|
||||
#
|
||||
def manage_wip(file_post, Force):
|
||||
# Check if argument's file (.tyto)
|
||||
if not file_post:
|
||||
print(':( Unused argument file')
|
||||
sys.exit(1)
|
||||
|
||||
# Check if file exists
|
||||
post_uri = '%s%s'%(domain.domain_articles,file_post)
|
||||
if not os.path.exists(post_uri):
|
||||
print(':( Unused file: %s'%post_uri)
|
||||
sys.exit(1)
|
||||
|
||||
# Get ID from URI (to get DB file)
|
||||
post_ID = check.get_filesum(post_uri,False)
|
||||
|
||||
# Set database file for this article
|
||||
# Check if DB exists
|
||||
post_db = '%s%s.db'%(domain.domain_db, post_ID)
|
||||
if not os.path.exists(post_db):
|
||||
print(':( Use "check" before "wip".')
|
||||
sys.exit(1)
|
||||
|
||||
# Set and check/create logs file for this article
|
||||
post_logs = '%s%s.log'%(domain.domain_logs,post_ID)
|
||||
|
||||
|
||||
#========#
|
||||
# #
|
||||
# Basics #
|
||||
# #
|
||||
#========#-------------------------------------------------------------
|
||||
#===========================#
|
||||
# Convert file to post_temp #
|
||||
#---------------------------#
|
||||
def post_to_string(file_path):
|
||||
global post_temp
|
||||
post_temp = ''
|
||||
post_html = ''
|
||||
with open(file_path, "r") as file:
|
||||
post_temp = file.read()
|
||||
|
||||
remove_empty_lines(post_temp.split('\n'))
|
||||
post_html = post_temp
|
||||
|
||||
#===========================#
|
||||
# Convert content TO base64 #
|
||||
#---------------------------#
|
||||
def convert_to_b64(post_content):
|
||||
import base64
|
||||
global b64_content
|
||||
post_content_base64 = ''
|
||||
content_bytes = post_content.encode("ascii")
|
||||
base64_bytes = base64.b64encode(content_bytes)
|
||||
b64_content = 'B64_' + base64_bytes.decode("ascii") + '_B64'
|
||||
|
||||
#================================#
|
||||
# Convert FROM base64 to content #
|
||||
#--------------------------------#
|
||||
def convert_from_b64(post_content):
|
||||
import base64
|
||||
global src_content
|
||||
post_content_src = ''
|
||||
content_bytes = post_content.encode("ascii")
|
||||
base64_bytes = base64.b64decode(content_bytes)
|
||||
src_content = base64_bytes.decode("ascii")
|
||||
|
||||
#==========================#
|
||||
# Get Writer's CSS config #
|
||||
# For compatible's markers #
|
||||
#--------------------------#
|
||||
def get_css(css,css_gen):
|
||||
global css_set
|
||||
|
||||
try:
|
||||
css_set = line.split(" ")[1]
|
||||
except:
|
||||
css_set = '%s%s'%(css,css_gen)
|
||||
|
||||
#=============================#
|
||||
# Get post, witout empty line #
|
||||
#-----------------------------#
|
||||
def remove_empty_lines(post):
|
||||
global post_html, post_temp, line
|
||||
post_temp = ''
|
||||
post_html = ''
|
||||
|
||||
for line in post:
|
||||
c = len(line)
|
||||
if c > 0:
|
||||
#print(c,line)
|
||||
if not post_temp:
|
||||
post_temp = line
|
||||
else:
|
||||
post_temp = '%s\n%s'%(post_temp,line)
|
||||
|
||||
post_html = post_temp
|
||||
|
||||
|
||||
#============#
|
||||
# #
|
||||
# Converters #
|
||||
# #
|
||||
#============#---------------------------------------------------------
|
||||
#==========================#
|
||||
# Convert bCodes to base64 #
|
||||
#--------------------------#
|
||||
def convert_bcodes(post,fm,lm,css):
|
||||
import re
|
||||
global post_html, line, css_set
|
||||
post_temp = ''
|
||||
span_nbr = '<span class="%s_bcode_ln">'%css
|
||||
span_code = '<span class="%s_bcode_ct">'%css
|
||||
span_end = '</span>'
|
||||
pre_end = '</pre>'
|
||||
ln_nbr = 0
|
||||
bCode = False
|
||||
blines = ''
|
||||
|
||||
for line in post:
|
||||
if line.startswith(fm): # Starting bcode marker
|
||||
ln_nbr = 0
|
||||
bCode = True
|
||||
get_css(css,'_bcode')
|
||||
pre_start = '<pre class="%s">'%css_set
|
||||
blines = '%s'%pre_start
|
||||
css_set = ''
|
||||
continue
|
||||
elif line.startswith(lm): # Ending bcode marker
|
||||
bCode = False
|
||||
line = ''
|
||||
blines = '%s\n%s'%(blines,pre_end)
|
||||
convert_to_b64(blines)
|
||||
post_temp = '%s\n%s'%(post_temp,b64_content)
|
||||
|
||||
if not bCode:
|
||||
post_temp = '%s\n%s'%(post_temp,line)
|
||||
else:
|
||||
ln_nbr += 1
|
||||
blines = '%s\n %s%d%s%s%s%s'%\
|
||||
(
|
||||
blines,span_nbr,ln_nbr,span_end,span_code,line,span_end
|
||||
)
|
||||
|
||||
remove_empty_lines(post_temp.split('\n'))
|
||||
post_html = post_temp
|
||||
|
||||
#============================================#
|
||||
# Convert Base64 strings to original content #
|
||||
#--------------------------------------------#
|
||||
def convert_b64_lines(post):
|
||||
import re
|
||||
global post_html,line
|
||||
post_temp = ''
|
||||
post_html = ''
|
||||
b64_contents = ''
|
||||
|
||||
for line in post:
|
||||
if not 'B64_' in line:
|
||||
post_temp = '%s\n%s'%(post_temp,line)
|
||||
else:
|
||||
b64_contents = re.findall(r"B64_(.*?)_B64", line)
|
||||
for b64_content in b64_contents:
|
||||
convert_from_b64(b64_content)
|
||||
line = line.replace('B64_%s_B64'%b64_content, src_content)
|
||||
post_temp = '%s\n%s'%(post_temp,line)
|
||||
|
||||
remove_empty_lines(post_temp)
|
||||
post_html = post_temp
|
||||
|
||||
#==========================#
|
||||
# Convert iCodes to base64 #
|
||||
# fm = FIRST Marker #
|
||||
# lm = LAST Marker #
|
||||
#--------------------------#
|
||||
def convert_icodes(post, fm, lm, css):
|
||||
import re
|
||||
global post_html
|
||||
post_temp = '' # Temp string to become post_html string page
|
||||
icodes_contents = '' # strings containing icode
|
||||
fm_html = '<code class="%s_icode">'%css
|
||||
lm_html = '</code>'
|
||||
fm_spe = '!%s'%(fm) # Special for !<_
|
||||
lm_spe = '%s!'%lm # Special for _>!
|
||||
|
||||
for line in post:
|
||||
# Special marker containting legacy one
|
||||
if lm_spe and fm_spe in line:
|
||||
icodes_contents = re.findall(r"%s(.*?)%s"%(fm_spe,lm_spe), line)
|
||||
for icode in icodes_contents:
|
||||
content_rep = '%s%s%s'%(fm_spe,icode,lm_spe)
|
||||
icode = '<code class="%s_icode">%s</code>'%(css,icode)
|
||||
convert_to_b64(icode)
|
||||
line = line.replace(content_rep,b64_content)
|
||||
|
||||
# Legacy marker
|
||||
if lm and fm in line:
|
||||
icodes_contents = re.findall(r"%s(.*?)%s"%(fm,lm), line)
|
||||
for icode in icodes_contents:
|
||||
content_rep = '%s%s%s'%(fm,icode,lm)
|
||||
icode = '<code class="%s_icode">%s</code>'%(css,icode)
|
||||
convert_to_b64(icode)
|
||||
line = line.replace(content_rep,b64_content)
|
||||
|
||||
post_temp = '%s\n%s'%(post_temp,line)
|
||||
post_html = post_temp
|
||||
|
||||
#====================================#
|
||||
# Convert Quotes #
|
||||
# 2 types: #
|
||||
# - Advanced, with author #
|
||||
# - Simple, with no author #
|
||||
# mt = marker type (Should be 3 '-') #
|
||||
#------------------------------------#---------------------------------
|
||||
#=========================#
|
||||
# Return datas after term #
|
||||
#-------------------------#
|
||||
def get_quote_datas(term,line):
|
||||
import re
|
||||
|
||||
term_data = re.compile('%s(.*)$'%term)
|
||||
if term_data:
|
||||
return term_data.search(line).group(1)
|
||||
|
||||
#=====================#
|
||||
# Loop in Post #
|
||||
# Convert quotes only #
|
||||
#---------------------#
|
||||
def convert_quotes(post,mt,css):
|
||||
import re
|
||||
global post_html,line,htmlquote, cite
|
||||
post_temp = '' # Temp string to become post_html string page
|
||||
Quote = False
|
||||
bquote = htmlquote = htmllines = ''
|
||||
cite = ''
|
||||
link = cite_HTML = ''
|
||||
lang = lang_HTML = ''
|
||||
book = year = title_HTML = ''
|
||||
quote_nbr = 0
|
||||
|
||||
for line in post:
|
||||
# Starting quote
|
||||
if line.startswith(mt):
|
||||
if not Quote:
|
||||
Quote = True
|
||||
get_css(css,'_quote')
|
||||
quote_nbr += 1
|
||||
line = '_QUOTE_%d'%quote_nbr
|
||||
if post_temp:
|
||||
post_temp = '%s\n%s'%(post_temp,line)
|
||||
else:
|
||||
post_temp = line
|
||||
continue
|
||||
# End of quote
|
||||
# Create HTML and convert marker to Base64
|
||||
else:
|
||||
Quote = False
|
||||
|
||||
# Create HTML datas
|
||||
if cite and book and year:
|
||||
title_HTML = ' title="%s - %s (%s)"'%(cite,book,year)
|
||||
elif book and year:
|
||||
title_HTML = ' title="%s (%s)"'%(book,year)
|
||||
elif book:
|
||||
title_HTML = ' title="%s"'%book
|
||||
elif year:
|
||||
title_HTML = ' title="%s"'%year
|
||||
|
||||
htmlquote = '<blockquote class="%s"%s'%(css_set,lang_HTML)
|
||||
htmlquote = '%s%s%s>'%(htmlquote,cite_HTML,title_HTML)
|
||||
|
||||
# Create Advance quote
|
||||
if cite:
|
||||
sp = ' '*4
|
||||
htmlquote = '<figure class="%s">\n %s'%(css_set,htmlquote)
|
||||
for bline in bquote.split('\n'):
|
||||
htmllines = '%s\n%s%s'%(htmllines, sp, bline)
|
||||
htmlquote = '%s%s\n </blockquote>'%(htmlquote,htmllines)
|
||||
htmlquote = '%s\n <figcaption>\n%s<cite>\n'%(htmlquote,sp)
|
||||
htmlquote = '%s%s <a href="%s">%s</a>'%(htmlquote,sp,link,cite)
|
||||
htmlquote = '%s\n%s</cite>\n </figcaption>\n</figure>'%(htmlquote,sp)
|
||||
|
||||
# Create SIMPLE HTML quote with indents
|
||||
else:
|
||||
sp = ' '*2
|
||||
for bline in bquote.split('\n'):
|
||||
htmllines = '%s\n%s%s'%(htmllines, sp, bline)
|
||||
htmlquote = '%s%s\n</blockquote>'%(htmlquote,htmllines)
|
||||
|
||||
|
||||
# Convert quote to Base64
|
||||
convert_to_b64(htmlquote)
|
||||
post_temp = post_temp.replace('_QUOTE_%s'%quote_nbr,b64_content)
|
||||
bquote = htmlquote = htmllines = ''
|
||||
continue
|
||||
|
||||
# If in quote, get datas (if exist)
|
||||
if Quote:
|
||||
if line.startswith('_cite: '):
|
||||
cite = get_quote_datas('_cite: ',line)
|
||||
elif line.startswith('_link: '):
|
||||
link = get_quote_datas('_link: ',line)
|
||||
if link:
|
||||
cite_HTML = ' cite="%s"'%(link)
|
||||
elif line.startswith('_lang: '):
|
||||
lang = get_quote_datas('_lang: ',line)
|
||||
if lang:
|
||||
lang_HTML = ' lang="%s"'%lang
|
||||
elif line.startswith('_book: '):
|
||||
book = get_quote_datas('_book: ',line)
|
||||
elif line.startswith('_year: '):
|
||||
year = get_quote_datas('_year: ',line)
|
||||
elif line.startswith('('):
|
||||
line = '<p class="%s_p %s_p-quote">'%(css,css)
|
||||
if bquote:
|
||||
bquote = '%s\n%s'%(bquote,line)
|
||||
else:
|
||||
bquote = line
|
||||
elif line.startswith(')'):
|
||||
line = '</p>'
|
||||
bquote = '%s\n%s'%(bquote,line)
|
||||
else:
|
||||
if bquote:
|
||||
bquote = '%s\n %s'%(bquote,line)
|
||||
else:
|
||||
bquote = line
|
||||
# if NOT in quote
|
||||
else:
|
||||
if post_temp:
|
||||
post_temp = '%s\n%s'%(post_temp,line)
|
||||
else:
|
||||
post_temp = line
|
||||
|
||||
post_html = post_temp
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# Replace line inplace, except those begining with #
|
||||
def replace_in_file(file_path, old_text, new_text):
|
||||
import fileinput
|
||||
with fileinput.input(file_path, inplace=True) as file:
|
||||
for line in file:
|
||||
new_line = line.replace(old_text, new_text)
|
||||
print(new_line, end='')
|
||||
|
||||
|
||||
|
||||
# Replace text with file content
|
||||
# WILLNOT BE USED
|
||||
def replace_with_file(file_path, old_text):
|
||||
import os
|
||||
files = sorted(os.listdir('/tmp'),reverse=True)
|
||||
for filename in files:
|
||||
if filename.startswith(old_text):
|
||||
with open('/tmp/%s'%filename, 'r') as fsrc:
|
||||
src = fsrc.read()
|
||||
src = src.rstrip()
|
||||
with open(file_path, 'r') as fdst:
|
||||
dst = fdst.read()
|
||||
rep_file = dst.replace(filename, src)
|
||||
with open(file_path, 'w') as fdst:
|
||||
fdst.write(rep_file)
|
||||
os.remove('/tmp/%s'%filename)
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,86 @@
|
|||
#!/usr/bin/env python3
|
||||
# Name: Tyto - Littérateur
|
||||
# Type: translation file
|
||||
# Description: Only for logs (internal messages) [en]
|
||||
# file: logs_en.py
|
||||
# Folder: /var/lib/tyto/translations/
|
||||
# By echolib (XMPP: im@echolib.re)
|
||||
# Repo: https://git.a-lec.org/echolib/tyto.git
|
||||
# License: GNU AFFERO GENERAL PUBLIC LICENSE Version 3, 19 November 2007
|
||||
|
||||
#**********************************************************************
|
||||
|
||||
# Generic
|
||||
sidebar = 'Sidebar'
|
||||
navbar = 'Navbar'
|
||||
meta_t = '<meta> tag'
|
||||
time_t = '<time> tag'
|
||||
metas = 'Metas Tags'
|
||||
footer = 'Footer'
|
||||
line = "Ligne"
|
||||
|
||||
no_up = "not updated"
|
||||
ntd = "Nothing to do"
|
||||
all_ok = "All is OK"
|
||||
unused_r = "Unused ressource"
|
||||
unused_c = "Unused database value"
|
||||
db_inv = "Corrupted article's database"
|
||||
err_arg = "Argument error"
|
||||
no_arg = "Unused argument"
|
||||
no_fidi = "Black Hole: no file or directory here"
|
||||
dom_ina = "Inactive domain"
|
||||
dom_inc = "Incomplete domain"
|
||||
dom_act = "Active domain"
|
||||
dom_cor = "Corrupted domain"
|
||||
data_inc = "Incomplete data"
|
||||
data_inv = "Invalid data"
|
||||
dom_no = "No domain found"
|
||||
|
||||
file_c = "File created"
|
||||
file_n = "File changed"
|
||||
file_e = "File exists"
|
||||
dir_c = "Directory created"
|
||||
dir_e = "Directory exists"
|
||||
|
||||
# chk
|
||||
nycheck = "Article not yet checked"
|
||||
was_chk = "Article was 'check'"
|
||||
st_chk_o = "Old 'check' status"
|
||||
post_inc = "Unused in article"
|
||||
post_inv = "Article not valid"
|
||||
post_val = "Article is valid"
|
||||
|
||||
# wip
|
||||
nywip = "Article not yet wip"
|
||||
was_wip = "Article was 'wip'"
|
||||
post_nwi = "Article not in 'wip'"
|
||||
st_wip_n = "Unused 'wip' status"
|
||||
st_wip_o = "Old 'wip' status"
|
||||
post_wip = "Article is in 'wip'"
|
||||
|
||||
# www
|
||||
was_pub = "Article was published"
|
||||
post_nww = "Article not in 'www'"
|
||||
st_www_n = "Unused 'www' status"
|
||||
st_www_o = "Old 'www' status"
|
||||
post_www = "Article is in 'www'"
|
||||
|
||||
# Misc
|
||||
check_m = "Check manually"
|
||||
post_chg = "Article changed: 'check' it first"
|
||||
sep_inv = "Unused separator in article"
|
||||
unused_v = "Unused value in article"
|
||||
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"
|
||||
anch_nu = "Anchor not uniq"
|
||||
nyfile = "file not yet created"
|
||||
add = "Add:"
|
||||
nomods = "Create HTML modules first"
|
||||
status_r = "Checking unused ressources..."
|
||||
was_wip = "Article already 'wip'"
|
||||
|
||||
|
||||
laterout = "Maybe later..."
|
|
@ -0,0 +1,85 @@
|
|||
#!/usr/bin/env python3
|
||||
# Nom: Tyto - Littérateur
|
||||
# Type: Fichier de traduction
|
||||
# Description: Seulement pour les logs (messages internes) [fr]
|
||||
# Fichier: logs_fr.py
|
||||
# Dossier: /var/lib/tyto/translations/
|
||||
# Par echolib (XMPP: im@echolib.re)
|
||||
# Dépôt: https://git.a-lec.org/echolib/tyto.git
|
||||
# Licence: GNU AFFERO GENERAL PUBLIC LICENSE Version 3, 19 November 2007
|
||||
|
||||
#**********************************************************************
|
||||
|
||||
# Generique
|
||||
sidebar = 'Barre Latérale'
|
||||
navbar = 'Barre de navigation'
|
||||
meta_t = 'Balise <meta>'
|
||||
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"
|
||||
unused_r = "Ressource manquante"
|
||||
unused_c = "Valeur de la base de donnée manquante"
|
||||
db_inv = "Base de donnée de l'article corrompue"
|
||||
err_arg = "Erreur d'argument"
|
||||
no_arg = "Argument manquant"
|
||||
no_fidi = "Trou Noir: aucun fichier ou dossier ici"
|
||||
dom_ina = "Domaine inactif"
|
||||
dom_inc = "Domaine incomplet"
|
||||
dom_act = "Domaine actif"
|
||||
dom_cor = "Domaine corrompu"
|
||||
data_inc = "Donnée incomplète"
|
||||
data_inv = "Donnée invalide"
|
||||
dom_no = "Aucun domaine trouvé"
|
||||
file_c = "Fichier créé"
|
||||
file_n = "Fichier modifié"
|
||||
file_e = "Fichier présent"
|
||||
dir_c = "Dossier créé"
|
||||
dir_e = "Dossier présent"
|
||||
|
||||
# chk
|
||||
nycheck = "Article pas encore 'check'"
|
||||
was_chk = "Article déjà vérifié"
|
||||
st_chk_o = "Statut 'check' Ancien"
|
||||
post_inc = "Donnée manquante dans l'article"
|
||||
post_inv = "Article non valide"
|
||||
post_val = "Article valide"
|
||||
|
||||
# Wip
|
||||
nywip = "Article pas encore 'wip'"
|
||||
was_wip = "Article déjà 'wip'"
|
||||
post_nwi = "Article non présent dans 'wip'"
|
||||
st_wip_n = "Statut 'wip' Non présent"
|
||||
st_wip_o = "Statut 'wip' Ancien"
|
||||
post_wip = "Article présent dans 'wip'"
|
||||
|
||||
# www
|
||||
was_pub = "Article déjà publié"
|
||||
post_nww = "Article non présent dans 'www'"
|
||||
st_www_n = "Statut 'www' Non présent"
|
||||
st_www_o = "Statut 'www' Ancien"
|
||||
post_www = "Article présent dans 'www'"
|
||||
|
||||
# Misc
|
||||
check_m = "Vérifier manuellement"
|
||||
post_chg = "Article modifié : commencer par 'check'"
|
||||
sep_inv = "Séparateur manquant dans l'article"
|
||||
unused_v = "Valeur manquante dans l'article"
|
||||
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"
|
||||
anch_nu = "Ancre non unique"
|
||||
nyfile = "Fichier pas encore créé"
|
||||
|
||||
|
||||
add = "Ajout:"
|
||||
nomods = "Créer d'abord les modules HTML"
|
||||
status_r = "Vérification des ressources manquantes..."
|
||||
|
||||
laterout = "Pour plus tard..."
|
|
@ -0,0 +1,334 @@
|
|||
#!/usr/bin/env python3
|
||||
# Name: Tyto - Littérateur
|
||||
# Type: translation file
|
||||
# Description: Only for website [en]
|
||||
# file: site_en.py
|
||||
# Folder: /var/lib/tyto/translations/
|
||||
# By echolib (XMPP: im@echolib.re)
|
||||
# Repo: https://git.a-lec.org/echolib/tyto.git
|
||||
# License: GNU AFFERO GENERAL PUBLIC LICENSE Version 3, 19 November 2007
|
||||
|
||||
#**********************************************************************
|
||||
|
||||
# IMPORTANT Instructions
|
||||
#-----------------------
|
||||
# This is a python file, so... DO NOT REMOVE:
|
||||
# - "#"
|
||||
# - "%s", "%d"
|
||||
# - "\n"
|
||||
# - "+ \"
|
||||
|
||||
|
||||
# Generic
|
||||
article = "Article"
|
||||
sidebar = 'Sidebar'
|
||||
navbar = 'Navbar'
|
||||
metas = 'Metas Tags'
|
||||
footer = 'Footer'
|
||||
title = 'Title'
|
||||
File = 'File'
|
||||
name = 'Name'
|
||||
by = "by"
|
||||
le = "the"
|
||||
fo = "for"
|
||||
proceed = "Continue"
|
||||
q = '?'
|
||||
i = '!'
|
||||
pp = ":"
|
||||
|
||||
# Website
|
||||
#----------------------------------------------------------------------
|
||||
# Misc.
|
||||
source_code = "Source code"
|
||||
home = "Home"
|
||||
go_home = "Go to Homepage"
|
||||
read = "Read"
|
||||
tyto_psrc = "Source code in Tyto format of"
|
||||
w_written = "was written the"
|
||||
w_published = "was published the"
|
||||
written = "written the"
|
||||
author_of = "is the uthor of"
|
||||
|
||||
# Sidebar
|
||||
site_sdb_t = "Featured..."
|
||||
|
||||
# Footer
|
||||
tyto_site_t = "Official website of %s, the Libre websites generator"
|
||||
tyto_git_t = "%s's official source code repository"
|
||||
legal_t = "Legal notice"
|
||||
terms_t = "Terms of Use"
|
||||
terms_s = "T.o.U"
|
||||
law = "Law"
|
||||
about = "About"
|
||||
add_inf = "additional Informations %s"%about.lower()
|
||||
licence = "License"
|
||||
contact = "Contact"
|
||||
mail = "Mail"
|
||||
mail_to = "Contact by %s the admin of"%mail.lower()
|
||||
feed = "Feed"
|
||||
generator = "Generator"
|
||||
|
||||
# Misc for Tyto
|
||||
#--------------
|
||||
# Check
|
||||
check_a = "Check again this article"
|
||||
post_chg = "Article was edited. Check it"
|
||||
|
||||
# Wip
|
||||
wip_new = "Create a new HTML page in 'wip' server again"
|
||||
srv_again = "Create again converted HTMl pages in server"
|
||||
srv_added = "Create missing HTML pages in server"
|
||||
srv_updated = "Update HTMl pages in server"
|
||||
|
||||
# publish
|
||||
publish_a = "Publish again this article"
|
||||
rss_c = "Create ATOM/RSS feed"
|
||||
|
||||
# Other
|
||||
uptpl = "Update directory"
|
||||
stats_f = "Articles: %s (%s words)"
|
||||
reg_domains = 'Registred domains'
|
||||
|
||||
# Form
|
||||
#----------------------------------------------------------------------
|
||||
form_edit = "Edit the domain with the form"
|
||||
form_start = ' ├──────────────────────────────────────────────┐\n' + \
|
||||
' │ Configure a new domain for current directory │\n' + \
|
||||
' │ Answer Y/y = yes. Enter to keep {default} │\n' + \
|
||||
' │ Empty Answer cancel process, except for │\n' + \
|
||||
' │ - [Optional] │\n' + \
|
||||
' │ - known {default} value │\n' + \
|
||||
' ├──────────────────────────────────────────────┘'
|
||||
form_warn = ' │\n' + \
|
||||
' ├──────────────────────────────────────┐\n' + \
|
||||
' │ Please, READ the configuration datas │\n' + \
|
||||
' ├──────────────────────────────────────┘'
|
||||
form_ready = ' │\n' + \
|
||||
' ├──────────────────────────────────────┐\n' + \
|
||||
' │ Domain is ready. Have fun, writers ! │\n' + \
|
||||
' └──────────────────────────────────────┘'
|
||||
form_inv = ' │\n' + \
|
||||
' ├─────────────────────────────────────┐\n' + \
|
||||
' │ Domain is INVALID. Try form again ! │\n' + \
|
||||
' └─────────────────────────────────────┘'
|
||||
|
||||
form_opt = "[Optional]"
|
||||
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_dir_e = "Directory exists"
|
||||
form_dir_c = "Directory created"
|
||||
form_file_e = "File exists"
|
||||
form_file_c = "File created"
|
||||
|
||||
form_reset = "Reset configuration?"
|
||||
form_rep = "Replace HTML file"
|
||||
|
||||
|
||||
# Documentation of configuration files
|
||||
#-------------------------------------
|
||||
metas_inf = "Create <meta> tags"
|
||||
metas_doc = \
|
||||
'# For %s\n' + \
|
||||
'# Type text/HTML file\n' + \
|
||||
'# Description Configuration file for HTML <metas> tags\n' + \
|
||||
'# Content inserted in <head> section\n' + \
|
||||
'# File %s\n' + \
|
||||
'# How Insert <metas ...> and <link ...>\n' + \
|
||||
'# Notes - Ony these tags are added :\n' + \
|
||||
'# - <metas>\n' + \
|
||||
'~ - <link>\n' + \
|
||||
'# - Do NOT copy this file to template directory\n' + \
|
||||
'# - These tags are already set'
|
||||
|
||||
navbar_inf = "Create navbar"
|
||||
navbar_doc = \
|
||||
'# For %s\n' + \
|
||||
'# Type: Text file\n' + \
|
||||
'# Description Configuration file for navbar"\n' + \
|
||||
'# (directories\'s list)\n' + \
|
||||
'# Commands tyto new navbar (reset)\n' + \
|
||||
'# tyto wip/publish navbar (Create)\n' + \
|
||||
'# tyto show navbar (show config)\n' + \
|
||||
'# tyto show-wip/show-www navbar (Show HTML)\n' + \
|
||||
'# tyto edit navbar (edit this file)\n' + \
|
||||
'# File %s\n' + \
|
||||
'# Comment 1 folder name per line *1\n' + \
|
||||
'# (from articles/)\n' + \
|
||||
'# not begining with "/"\n' + \
|
||||
'# Order in sidebar position\n' + \
|
||||
'# Remember To avoid 404 error, you must:\n' + \
|
||||
'# - add article index.{tyto}\n' + \
|
||||
'# in set folder\n' + \
|
||||
'# - check and wip article\n' + \
|
||||
'# *1 Option To define a title link:' + \
|
||||
'# - add "# title link"\n' + \
|
||||
'\n# %s\n'%(20 * "-") +\
|
||||
'# Examples :\n' + \
|
||||
'# documentation\n' + \
|
||||
'# about # infos about this website\n' + \
|
||||
'# %s\n\n'%(20 * "-")
|
||||
|
||||
sidebar_inf = "Create sidebar"
|
||||
sidebar_doc = \
|
||||
'# For %s\n' + \
|
||||
'# Type Text file\n' + \
|
||||
'# Description Configuration file for sidebar\n' + \
|
||||
'# (articles\'s list)\n' + \
|
||||
'# File %s\n' + \
|
||||
'# Commands tyto new sidebar (reset)\n' + \
|
||||
'# tyto wip/publish sidebar (Create)\n' + \
|
||||
'# tyto show sidebar (Show config)\n' + \
|
||||
'# tyto show-wip/show-www sidebar (Show HTML)\n' + \
|
||||
'# tyto edit sidebar (edit this file)\n' + \
|
||||
'# How 1 article URI per line\n' + \
|
||||
'# (from articles/)\n' + \
|
||||
'# not begining with "/"\n' + \
|
||||
'# Order in sidebar position\n' + \
|
||||
'# Max articles = %d\n' + \
|
||||
'# Option Tp set sidebar title:\n' + \
|
||||
'# ": Sidebar Title"\n' + \
|
||||
'\n# %s\n'%(20 * "-") + \
|
||||
'# Examples :\n' + \
|
||||
'# : My new articles list'
|
||||
'# index.tyto\n' + \
|
||||
'# dir1/index.tyto\n' + \
|
||||
'# %s\n\n'%(20 * "-")
|
||||
|
||||
footer_inf = "Create footer"
|
||||
footer_doc = \
|
||||
'# For %s\n' + \
|
||||
'# Type text/HTML file\n' + \
|
||||
'# Description Configuration file for footer\n' + \
|
||||
'# File %s\n' + \
|
||||
'# Commands tyto new footer (reset)\n' + \
|
||||
'# tyto wip/publish footer (Create)\n' + \
|
||||
'# tyto show footer (Show config)\n' + \
|
||||
'# tyto show-wip/show-www footer (Show HTML)\n' + \
|
||||
'# tyto edit footer (edit this file)\n' + \
|
||||
'# How Put any HTML code\n' + \
|
||||
'# Notes - Lines are ignored if:\n' + \
|
||||
'# - empty\n' + \
|
||||
'# - begin with "#"\n' + \
|
||||
'# - 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
|
||||
- Create domain with 'tyto new domain [URL]'
|
||||
- Create .tyto file in directory "articles/"
|
||||
- Use these actions: check > wip > publish
|
||||
! - Modules files are in directory "_configs/"
|
||||
and used to custom some website parts
|
||||
- (css, logo...) files go in "wip/template/"
|
||||
|
||||
# Usage: tyto [action] [target]
|
||||
# Actions
|
||||
- [action] > According to [target]
|
||||
|
||||
# Edit a file
|
||||
edit : Source file, configuration module
|
||||
edit-about: [footer] Edit description section in footer
|
||||
or same as [edit-db]
|
||||
edit-db : Edit database/configuration file
|
||||
edit-wip : Edit a file in server 'wip'
|
||||
edit_www : Edit a file in server 'www'
|
||||
new : [domain] Créer un domaine ou le modifier via le formulaire
|
||||
[sidebar, navbar, footer, metas] Create and replace
|
||||
with default module configuration file
|
||||
|
||||
# Show contents file (with line number)
|
||||
show : Show source file, source configuration module
|
||||
show-about: [footer] Show description footer file
|
||||
or same as [show-db]
|
||||
show-db : Show database/configuration file
|
||||
show-wip : Show a file in server 'wip'
|
||||
show-www : Show a file in server 'www'
|
||||
|
||||
# Create HTML page
|
||||
check : Check the validity of a tyto format file
|
||||
wip : Create article HTML page in server 'wip'
|
||||
publish : Create article HTML page in server 'www'
|
||||
|
||||
# Targets
|
||||
- [target] > According to [action]
|
||||
|
||||
# Multiple articles
|
||||
updated : Update articles (already checked)
|
||||
again : Force all articles (already checked)
|
||||
added : [check] Search and check for .tyto articles in domain
|
||||
(not yet checked)
|
||||
[wip, publish] Create articles HTML pages
|
||||
that were edited and checked
|
||||
|
||||
# Update modules/files template
|
||||
template : - Create (replace) modules in directory "template/"
|
||||
- [publish] Also, copy all other files from "wip/template/"
|
||||
|
||||
# Domain and files
|
||||
domain : Create or edit a domain
|
||||
[file] : URI file (autocompletion friendly)
|
||||
|
||||
# Modules
|
||||
footer : Footer configuration file
|
||||
metas : <meta>, <link> configuration file
|
||||
navbar : Navbar configuration file
|
||||
sidebar : Sidebar configuration file
|
||||
stats : Stats file (server 'wip' er 'www')
|
||||
|
||||
# Examples :
|
||||
# Check article (according to sub-folder)
|
||||
$ tyto check mysubdir/index.tyto
|
||||
|
||||
# Create (replace) default sidebar configuration file
|
||||
$ tyto new sidebar
|
||||
|
||||
# Edit navbar configuration file
|
||||
$ tyto edit navbar
|
||||
|
||||
# edit doc/index.html in server 'www'
|
||||
$ tyto edit-www doc/index.tyto
|
||||
|
||||
# Create HTML sidebar file in server 'wip'
|
||||
$ tyto wip sidebar
|
||||
|
||||
# Show footer HTML file in server 'wip'
|
||||
$ tyto show-wip footer
|
||||
|
||||
# Create statistics file in serveur 'www'
|
||||
$ tyto publish stats"""
|
|
@ -0,0 +1,335 @@
|
|||
#!/usr/bin/env python3
|
||||
# Nom: Tyto - Littérateur
|
||||
# Type: Fichier de traduction
|
||||
# Description: Seulement pour le site web [fr]
|
||||
# Fichier: site_fr.py
|
||||
# Dossier: /var/lib/tyto/translations/
|
||||
# Par echolib (XMPP: im@echolib.re)
|
||||
# Dépôt: https://git.a-lec.org/echolib/tyto.git
|
||||
# Licence: GNU AFFERO GENERAL PUBLIC LICENSE Version 3, 19 November 2007
|
||||
|
||||
#**********************************************************************
|
||||
|
||||
# Instructions IMPORTANTES
|
||||
#-------------------------
|
||||
# Ceci est un fichier python, donc... NE PAS ENLEVER :
|
||||
# - "#"
|
||||
# - "%s", "%d"
|
||||
# - "\n"
|
||||
# - "+ \"
|
||||
|
||||
# Generic
|
||||
article = "Article"
|
||||
sidebar = 'Barre Latérale'
|
||||
navbar = 'Barre de menu'
|
||||
metas = 'Balises Metas'
|
||||
footer = 'Pied de Page'
|
||||
title = 'Titre'
|
||||
File = 'Fichier'
|
||||
name = 'Nom'
|
||||
by = "par"
|
||||
le = "le"
|
||||
fo = "pour"
|
||||
proceed = "Continuer"
|
||||
q = ' ?'
|
||||
i = ' !'
|
||||
pp = " :"
|
||||
|
||||
# Site web
|
||||
#----------------------------------------------------------------------
|
||||
# Divers
|
||||
source_code = "Code source"
|
||||
home = "Accueil"
|
||||
go_home = "Aller à la page d'accueil"
|
||||
read = "À lire"
|
||||
tyto_psrc = "Code source au format Tyto de"
|
||||
w_written = "a été écrit le"
|
||||
w_published = "a été publié le"
|
||||
written = "écrit le"
|
||||
author_of = "est l'auteur de"
|
||||
|
||||
# Barre latérale
|
||||
site_sdb_t = "À l'affiche..."
|
||||
|
||||
# Pied de page
|
||||
tyto_site_t = "Site web officiel du générateur de sites web Libre %s"
|
||||
tyto_git_t = "Dépôt officiel du code source de %s"
|
||||
legal_t = "Mentions légales"
|
||||
terms_t = "Conditions Générales d'Utilisation"
|
||||
terms_s = "C.G.U"
|
||||
law = "Loi"
|
||||
about = "À propos de"
|
||||
add_inf = "Information supplémentaires %s"%about.lower()
|
||||
licence = "Licence"
|
||||
contact = "Contact"
|
||||
mail = "Courriel"
|
||||
mail_to = "Contacter par %s l'administrateur de"%mail.lower()
|
||||
feed = "Flux"
|
||||
generator = "Generateur"
|
||||
|
||||
|
||||
# Misc for Tyto
|
||||
#--------------
|
||||
# Check
|
||||
check_a = "Vérifier encore l'article"
|
||||
post_chg = "Article édité. Le vérifier"
|
||||
|
||||
# Wip
|
||||
wip_new = "Créer encore une page HTML dans le serveur 'wip'"
|
||||
srv_again = "Créer encore les pages dans le serveur"
|
||||
srv_added = "Créer les pages HTML manquantes dans le serveur"
|
||||
srv_updated = "Mise à jour des pages HTML dans le serveur"
|
||||
|
||||
# publish
|
||||
publish_a = "Publier encore l'article"
|
||||
rss_c = "Créer le flux ATOM/RSS"
|
||||
|
||||
# Autre
|
||||
uptpl = "Mettre à jour le dossier"
|
||||
stats_f = "Articles : %s (%s mots)"
|
||||
reg_domains = 'Domaines enregistrés'
|
||||
|
||||
# Formulaire
|
||||
#----------------------------------------------------------------------
|
||||
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' + \
|
||||
' │ Sans réponse : arrêt, sauf pour │\n' + \
|
||||
' │ - [Optionnel] │\n' + \
|
||||
' │ - Valeur {default} connue │\n' + \
|
||||
' ├───────────────────────────────────────────────┘'
|
||||
form_warn = ' │\n' + \
|
||||
' ├──────────────────────────────────────────┐\n' + \
|
||||
' │ SVP, lisez les données de configurations │\n' + \
|
||||
' ├──────────────────────────────────────────┘'
|
||||
form_ready = ' │\n' + \
|
||||
' ├─────────────────────────────────────────┐\n' + \
|
||||
' │ Le domaine est prêt. Amusez-vous bien ! │\n' + \
|
||||
' └─────────────────────────────────────────┘'
|
||||
form_inv = ' │\n' + \
|
||||
' ├───────────────────────────────────────────┐\n' + \
|
||||
' │ Le Domaine est INVALIDE. Essayez encore ! │\n' + \
|
||||
' └───────────────────────────────────────────┘'
|
||||
|
||||
form_opt = "[Optionnel]"
|
||||
form_url = "URL du site web officiel"
|
||||
form_wip = "URL du site web 'wip'"
|
||||
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_rss_f = "Nom du fichier Atom/RSS"
|
||||
form_rss_i = "Nombre d'articles Atom/RSS"
|
||||
form_title = "Titre du site web"
|
||||
form_date = "Année de création du domaine"
|
||||
form_about = "Description du domaine"
|
||||
form_mail = "Courriel du webmestre"
|
||||
form_tags = "[séparées par une virgule] Étiquettes du domaine"
|
||||
form_lic = "Licence du domaine"
|
||||
form_licurl = "URL de la licence"
|
||||
form_legal = "URL des mentions légales"
|
||||
form_terms = "URL des CGU"
|
||||
form_css = "[alnum] Préfix CSS"
|
||||
form_sep = "[1 car.] Séparateur des titres de pages"
|
||||
form_pscode = "Montrer le code source des articles"
|
||||
form_relme = 'URL pour rel="me"'
|
||||
form_trsite = "[2 car.] Langue du site web"
|
||||
form_sdb_i = "Nombre d'articles"
|
||||
form_activ = "Activer et preparer le domaine"
|
||||
form_dir_e = "Dossier présent"
|
||||
form_dir_c = "Dossier créé"
|
||||
form_file_e = "Fichier présent"
|
||||
form_file_c = "Fichier créé"
|
||||
|
||||
form_reset = "Réinitialiser la configuration"
|
||||
form_rep = "Remplacer le fichier HTML"
|
||||
|
||||
|
||||
# Documentation des fichiers de configuration
|
||||
#--------------------------------------------
|
||||
metas_inf = "Créer les balises <meta>"
|
||||
metas_doc = \
|
||||
'# Pour %s\n' + \
|
||||
'# Type Fichier text/HTML\n' + \
|
||||
'# Description Fichier de configuration des balises <meta> HTML \n' + \
|
||||
'# Contenu inséré dans la section <head>\n' + \
|
||||
'# Fichier %s\n' + \
|
||||
'# Comment Insérer des balises <metas ...> et <link ...>\n' + \
|
||||
'# Notes - Sont ajoutées uniquement les balises :\n' + \
|
||||
'# - <metas>\n' + \
|
||||
'~ - <link>\n' + \
|
||||
'# - Ne PAS copier ce fichier dans le dossier template\n' + \
|
||||
'# - Les balises suivantes sont déjà présentes'
|
||||
|
||||
navbar_inf = "Créer la barre de menu"
|
||||
navbar_doc = \
|
||||
'# Pour %s\n' + \
|
||||
'# Type fichier texte\n' + \
|
||||
'# Description Utilisé par "wip/publish navbar"\n' + \
|
||||
'# (Liste des dossiers)\n' + \
|
||||
"# Commandes tyto new navbar (réinitialiser)\n" + \
|
||||
'# tyto wip/publish navbar (créer)\n' + \
|
||||
'# tyto show navbar (afficher la configuration)\n' + \
|
||||
'# tyto show-wip/show-www navbar (afficher l\'HTML)\n' + \
|
||||
'# tyto edit navbar (editer ce fichier)\n' + \
|
||||
'# Fichier %s\n' + \
|
||||
'# Comment 1 nom de dossier par ligne *1\n' + \
|
||||
'# (depuis articles/)\n' + \
|
||||
'# Ne commence pas par "/"\n' + \
|
||||
'# L\'ordre définit la position\n' + \
|
||||
'# Note Pour éviter l\'erreur 404 :\n' + \
|
||||
'# - ajouter un article index.{ext}\n' + \
|
||||
'# dans le dossier mentionné\n' + \
|
||||
'# - check et wip sur l\'article\n' + \
|
||||
'# *1 Option Pour définir un titre de lien :\n' + \
|
||||
'# - ajouter "# titre du lien"\n' + \
|
||||
'\n# %s\n'%(20 * "-") +\
|
||||
'# Exemples :\n' + \
|
||||
'# documentation\n' + \
|
||||
'# a-propos # Informations concernant ce site\n' + \
|
||||
'# %s\n\n'%(20 * "-")
|
||||
|
||||
sidebar_inf = "Créer la barre latérale"
|
||||
sidebar_doc = \
|
||||
'# Pour %s\n' + \
|
||||
'# Type fichier texte\n' + \
|
||||
'# Description Fichier de configuration de la barre latérale\n' + \
|
||||
'# (Liste d\'articles)\n' + \
|
||||
'# Fichier %s\n' + \
|
||||
"# Commandes tyto new sidebar (réinitialiser)\n" + \
|
||||
'# tyto wip/publish sidebar (créer)\n' + \
|
||||
'# tyto show sidebar (afficher la configuration)\n' + \
|
||||
'# tyto show-wip/show-www sidebar (afficher l\'HTML)\n' + \
|
||||
'# tyto edit sidebar (editer ce fichier)\n' + \
|
||||
'# Comment 1 URI de l\'article par ligne\n' + \
|
||||
'# (depuis articles/)\n' + \
|
||||
'# Ne commence pas par "/"\n' + \
|
||||
'# L\'ordre définit la position\n' + \
|
||||
'# Articles max = %d\n' + \
|
||||
'# Option Pour définir un titre à la barre latérale:\n' + \
|
||||
'# ": Titre de la sidebar"\n' + \
|
||||
'\n# %s\n'%(20 * "-") + \
|
||||
'# Exemples :\n' + \
|
||||
'# : Ma liste des nouveaux articles\n' + \
|
||||
'# index.tyto\n' + \
|
||||
'# dir1/index.tyto\n' + \
|
||||
'# %s\n\n'%(20 * "-")
|
||||
|
||||
footer_inf = "Créer le pied de page"
|
||||
footer_doc = \
|
||||
'# Pour %s\n' + \
|
||||
'# Type Fichier text/HTML\n' + \
|
||||
'# Description Fichier de configuration du pied de page\n' + \
|
||||
'# Fichier %s\n' + \
|
||||
"# Commandes tyto new footer (réinitialiser)\n" + \
|
||||
'# tyto wip/publish footer (créer)\n' + \
|
||||
'# tyto show footer (afficher la configuration)\n' + \
|
||||
'# tyto show-wip/show-www footer (afficher l\'HTML)\n' + \
|
||||
'# tyto edit footer (editer ce fichier)\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 * "-")
|
||||
|
||||
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
|
||||
- Créer un domain avec 'tyto new domain [URL]'
|
||||
- Créer un fichier .tyto dans le dossier "articles/"
|
||||
- Utiliser les actions check > wip > publish
|
||||
! - Les fichiers des modules sont dans le dossier "_configs/"
|
||||
et utilisés pour personnaliser certaines parties du site
|
||||
- Les fichier (css, logo...) vont dans le dossier serveur "wip/template/"
|
||||
|
||||
# Usage: tyto [action] [target]
|
||||
# Les actions
|
||||
- [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
|
||||
|
||||
# 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'
|
||||
|
||||
# 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'
|
||||
publish : Créer une page HTML de l'article dans le serveur 'www'
|
||||
|
||||
# Les cibles
|
||||
- [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
|
||||
added : [check] Vérifier tous les article .tyto dans le domaine
|
||||
qui n'ont pas été déjà validés
|
||||
[wip, publish] Créer les pages HTML des articles
|
||||
qui ont été modifiés et vérifiés
|
||||
|
||||
# Mise en ligne du thème et des modules
|
||||
template : - Recréer les modules HTML dans "template/"
|
||||
- Copie tous les autres fichier du dossier wip/template/
|
||||
|
||||
# Domaine et fichier
|
||||
domain : Créer un domain ou le modifier
|
||||
[file] : URI du fichier (l'autocompletion est votre amie)
|
||||
|
||||
# Les modules
|
||||
footer : Fichier de configuration du pied de page
|
||||
metas : Fichier de configuration des balises HTML <meta>, <link>
|
||||
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')
|
||||
|
||||
# Exemples :
|
||||
# Vérifier l'article dans le sous dossier (suivant l'emplacement)
|
||||
$ tyto check mysubdir/index.tyto
|
||||
|
||||
# Créer ou remettre par défaut la barre latérale
|
||||
$ tyto new sidebar
|
||||
|
||||
# Modifier la configuration du menu de navigation
|
||||
$ tyto edit navbar
|
||||
|
||||
# Modifier doc/index.html dans le serveur 'www'
|
||||
$ tyto edit-www doc/index.tyto
|
||||
|
||||
# Créer le fichier HTML de la barre latérale (serveur 'wip')
|
||||
$ tyto wip sidebar
|
||||
|
||||
# Afficher le contenu du pied de page HTML dans le serveur 'wip'
|
||||
$ tyto show-wip footer
|
||||
|
||||
# Créer le fichier de statistiques dans le serveur 'www'
|
||||
$ tyto publish stats"""
|
|
@ -0,0 +1,75 @@
|
|||
# Home Domain
|
||||
directory = ""
|
||||
database = ""
|
||||
|
||||
# Local user configuration
|
||||
lang_sys = "SYS"
|
||||
local_user = ""
|
||||
lang_logs = "SYS"
|
||||
articles_db_d = ""
|
||||
|
||||
# Working directories
|
||||
articles_d = ""
|
||||
files_d = ""
|
||||
images_d = ""
|
||||
modules_d = ""
|
||||
|
||||
# Modules files
|
||||
navbar_f = ""
|
||||
sidebar_f = ""
|
||||
metas_f = ""
|
||||
footer_f = ""
|
||||
footer_about_f = ""
|
||||
|
||||
# Domain
|
||||
shortname = ""
|
||||
www_url = ""
|
||||
wip_url = ""
|
||||
|
||||
# Servers directories
|
||||
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 = ""
|
||||
|
||||
# Servers files
|
||||
wip_navbar_f = ""
|
||||
wip_sidebar_f = ""
|
||||
wip_metas_f = ""
|
||||
wip_footer_f = ""
|
||||
www_navbar_f = ""
|
||||
www_sidebar_f = ""
|
||||
www_metas_f = ""
|
||||
www_footer_f = ""
|
||||
wip_logo_f = ""
|
||||
www_logo_f = ""
|
||||
www_rss_f = ""
|
||||
|
||||
# Domain user's settings
|
||||
logo = "logo.png"
|
||||
rss = "rss.xml"
|
||||
rss_items = 100
|
||||
title = ""
|
||||
date = ""
|
||||
about = ""
|
||||
lang_site = "SYS"
|
||||
mail = ""
|
||||
tags = ""
|
||||
license = ""
|
||||
license_url = ""
|
||||
legal_url = ""
|
||||
terms_url = ""
|
||||
css = "tyto"
|
||||
sep = "-"
|
||||
article_code = False
|
||||
relme = ""
|
||||
sidebar_title = ""
|
||||
sidebar_items = 6
|
||||
|
||||
activated = False
|
Loading…
Reference in New Issue