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
|
# Changelog
|
||||||
|
|
||||||
Tyto - Littérateur
|
Tyto - Littérateur
|
||||||
- Repository: https://git.a-lec.org/echolib/tyto
|
- Repository: https://git.a-lec.org/echolib/tyto-litterateur
|
||||||
- Issues: https://git.a-lec.org/echolib/tyto/-/issues
|
- Issues: https://git.a-lec.org/echolib/tyto-litterateur/-/issues
|
||||||
- Changelog: https://git.a-lec.org/echolib/tyto/-/blob/main/CHANGELOG.md
|
- Changelog: https://git.a-lec.org/echolib/tyto-litterateur/-/blob/master/CHANGELOG.md
|
||||||
- License: https://git.a-lec.org/echolib/tyto/-/blob/main/LICENSE
|
- License: https://git.a-lec.org/echolib/tyto-litterateur/-/blob/master/LICENSE
|
||||||
|
|
||||||
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.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
|
# Tyto
|
||||||
|
Pour obtenir de l'aide, taper juste la commande tyto
|
||||||
|
|
||||||
## Répertoire de code du projet 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