[1.9.51] Zone 51 ! Ready to test before final version

This commit is contained in:
Cyrille L 2023-12-29 17:56:22 +01:00
parent 7849ca4f4b
commit d966fa7d9b
24 changed files with 340 additions and 1309 deletions

View File

@ -10,5 +10,12 @@ Tyto - Littérateur
# CURRENTLY IN DEV (in devel branch) ! # CURRENTLY IN DEV (in devel branch) !
## [1.9.50] ## [1.9.51]
- Translated english logs
- Some commands cannot be used if domain is not activated
- New [action] "show": show files contents [multiple targets]
- fix typo in metas module
## [1.9.51]
- Complete new code - Complete new code

View File

@ -1,5 +1,5 @@
# Very early IN dev code # Very early IN dev code
This program can ve tested and should mainly work. Please report any problems This program can be tested and should mainly work. Please report any problems
Tyto - Littérateur is translated in french and english. Tyto - Littérateur is translated in french and english.
@ -19,7 +19,7 @@ tyto help words anchor
- create a domain directory, like www.domain.tld - create a domain directory, like www.domain.tld
- Go to this directory - Go to this directory
- type `tyto new domain` - type `tyto new domain`
- type `tyto check domain` - type `tyto check domain` and PLEASE, CHECK configuration file
- create in new directory domain ".../articles/", an article (see help) - create in new directory domain ".../articles/", an article (see help)
- type `wip myfile.tyto` - type `wip myfile.tyto`

6
debian/control vendored
View File

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

View File

@ -1,5 +1,5 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# version: 1.9.50 # version: 1.9.51
# Tyto - Littérateur # Tyto - Littérateur
# Copyright (C) 2023 Cyrille Louarn <echolib+tyto@a-lec.org> # Copyright (C) 2023 Cyrille Louarn <echolib+tyto@a-lec.org>
@ -54,6 +54,7 @@ def check_install():
"page", "page",
"post", "post",
"publish", "publish",
"show",
"sitemap", "sitemap",
"tools", "tools",
"wip", "wip",
@ -129,7 +130,7 @@ if args.err_action: # [action] error (only)
#===============# #===============#
# Start process # # Start process #
#===============# #===============#
import check, help, new, wip, publish import check, help, new, wip, publish, show
# From command line [ACTION], do # From command line [ACTION], do
do = { do = {
@ -138,13 +139,14 @@ do = {
"new" : new.manage, "new" : new.manage,
"publish" : publish.manage, "publish" : publish.manage,
"wip" : wip.manage, "wip" : wip.manage,
"show" : show.manage,
"start" : domain.manage, "start" : domain.manage,
"stop" : domain.manage, "stop" : domain.manage,
} }
do[args.action]() # Test for errors in python module file (without try)
""" #do[args.action]()
try: do[args.action]() try: do[args.action]()
except KeyError: debug.out(90, args.action, "", True, 2, True) except KeyError: debug.out(90, args.action, "", True, 2, True)
"""

View File

@ -38,6 +38,7 @@ def get_arguments():
"wip" : False, "wip" : False,
"publish" : False, "publish" : False,
"new" : False, "new" : False,
"show" : False,
"start" : False, "start" : False,
"stop" : False, "stop" : False,
"help" : False, "help" : False,
@ -62,6 +63,7 @@ def get_arguments():
}, },
} }
# Arguments from command line # Arguments from command line
# --------------------------- # ---------------------------
set_module = False set_module = False
@ -86,12 +88,17 @@ def get_arguments():
set_module = True set_module = True
continue continue
if commands["modules"]["modules"]:
for arg in commands["modules"]:
commands["modules"][arg] = True
# Register options # Register options
for arg in commands["options"]: for arg in commands["options"]:
if sys.argv[user_arg] == arg: if sys.argv[user_arg] == arg:
commands["options"][sys.argv[user_arg]] = True commands["options"][sys.argv[user_arg]] = True
continue continue
# Action, the first argument # Action, the first argument
# -------------------------- # --------------------------
err_action = True err_action = True
@ -107,84 +114,3 @@ def get_arguments():
err_action = action err_action = action
action = "help" action = "help"
return return
"""
global err_act, action, actions, article, targets, logall, erron, force
hlp_actions = ("help", "-h", "--help")
actions = (
"check", "wip", "publish",
"start", "stop",
"new", hlp_actions,
)
debug_opts = ("--verbose", "-v")
erron_opts = ("--errors", "-E")
force_opts = ("--force", "-F")
# Options
err_act = article = targets = logall = erron = force = False
# First argument must be an action
# --------------------------------
try: action = sys.argv[1]
except: action = ""
if not action in actions or action in hlp_actions:
err_act = action
action = "help"
return
# Set other arguments passed
# --------------------------
global domain, modules, metas, header, navbar, sidebar, footer, set_modules
global sitemap
sitemap = False
domain = modules = metas = header = navbar = sidebar = footer = False
set_modules = {
"modules" : "",
"metas" : "",
"header" : "",
"navbar" : "",
"sidebar" : "",
"footer" : "",
}
for arg in range(2, len(sys.argv)):
# ------
# Target
# ------
# Argument is a .tyto article
if not article and sys.argv[arg].endswith(".tyto"):
article = sys.argv[arg]
continue
# Other targets
# domain
if not domain: domain = bool(sys.argv[arg] == "domain")
if not sitemap: sitemap = bool(sys.argv[arg] == "sitemap")
# Modules
if not modules:
modules = set_modules["modules"] = bool(sys.argv[arg] == "modules")
if not metas:
metas = set_modules["metas"] = bool(sys.argv[arg] == "metas")
if not header:
header = set_modules["header"] = bool(sys.argv[arg] == "header")
if not navbar:
navbar = set_modules["navbar"] = bool(sys.argv[arg] == "navbar")
if not sidebar:
sidebar = set_modules["sidebar"] = bool(sys.argv[arg] == "sidebar")
if not footer:
footer = set_modules["footer"] = bool(sys.argv[arg] == "footer")
# -------
# Options
# -------
if not targets: targets = bool(sys.argv[arg] == "all")
if not logall: logall = bool(sys.argv[arg] in debug_opts)
if not erron: erron = bool(sys.argv[arg] in erron_opts)
if not force: force = bool(sys.argv[arg] in force_opts)
"""

View File

@ -173,6 +173,10 @@ def set_values():
web = { web = {
"wip" : cf.get("WEBSITE", "wip_url"), "wip" : cf.get("WEBSITE", "wip_url"),
"www" : cf.get("WEBSITE", "www_url"), "www" : cf.get("WEBSITE", "www_url"),
"www_logo" : cf.get("WEBSITE", "www_url") \
+ "template/" + cf.get("TEMPLATE_FILENAMES", "logo"),
"www_rss" : cf.get("WEBSITE", "www_url") \
+ cf.get("TEMPLATE_FILENAMES", "rss"),
"css" : cf.get("WEBSITE", "css"), "css" : cf.get("WEBSITE", "css"),
"lang" : cf.get("WEBSITE", "lang"), "lang" : cf.get("WEBSITE", "lang"),
"license" : cf.get("WEBSITE", "license"), "license" : cf.get("WEBSITE", "license"),
@ -216,6 +220,16 @@ def is_ready():
cf_update() cf_update()
set_values() set_values()
#=====================================#
# In some case, domain must be active #
# Exit if not activated #
#-------------------------------------#
def is_active():
is_ready()
conf["activated"] or \
debug.out(203, "activated = False", cf_uri, True, 2, True)
#====================================# #====================================#
# Domain Configuration file sections # # Domain Configuration file sections #

View File

@ -49,7 +49,6 @@ def create():
for db_uri in items: for db_uri in items:
if nbr_item == max_item: if nbr_item == max_item:
print("MAX")
break break
if not check_db(db_uri): if not check_db(db_uri):
@ -80,21 +79,21 @@ def create():
feed = \ feed = \
feed_tpl%( feed_tpl%(
bld_date, bld_date,
domain.web["www"] + domain.cf.get("TEMPLATE_FILENAMES", "rss"), domain.web["www_rss"] + domain.cf.get("TEMPLATE_FILENAMES", "rss"),
domain.conf["title"], domain.conf["title"],
domain.web["www"], domain.web["www"],
domain.conf["about"], domain.conf["about"],
domain.web["www"] + "template/" + domain.cf.get("TEMPLATE_FILENAMES", "logo"), domain.web["www_logo"],
"%s (logo)"%(domain.conf["title"]), "%s (logo)"%(domain.conf["title"]),
domain.web["www"], domain.web["www"],
domain.lang, domain.lang,
domain.conf["tags"], domain.conf["tags"],
bld_date, bld_date,
domain.cf.get("WEBSITE", "license"), domain.cf.get("WEBSITE", "license"),
domain.conf["mail"], domain.conf["mail"],
feed_items feed_items
) )
feed_uri = domain.www + domain.cf.get("TEMPLATE_FILENAMES", "rss") feed_uri = domain.www + domain.cf.get("TEMPLATE_FILENAMES", "rss")
tools.create_file(feed_uri, feed) tools.create_file(feed_uri, feed)

View File

@ -1,257 +0,0 @@
#!/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 General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#----------------------------------------------------------------------
# XMPP: echolib > im@echolib.re
#
# Description: Forms (edit, create domain, questions...)
# File: /var/lib/tyto/program/form.py
#----------------------------------------------------------------------
#-------------------------
# Funny Stats Project
#-------------------------
# file lines :
# file comments :
# file functions:
# file program :
#--------------------------
import os, re
from dateutil.parser import parse
import debug, domain, langs, tools
#====================#
# Exit Tyto with log #
# user interrupts... #
#--------------------#
def maybe_later(expected, answer):
debug.out(255, expected, answer, True, 0, True)
#=========================#
# When asking something #
# yes_only : True / False #
#-------------------------#
def ask(q, yes_only, default):
expected = ""
if yes_only:
expected = langs.logs.ok
try: answer = input(q)
except KeyboardInterrupt: print("") ; maybe_later(expected, "?")
# return default answer if exists
if not answer:
if default:
return default
maybe_later(expected, "?")
# Answer is a Y/N process
if yes_only:
for ok in langs.logs.ok:
if answer.lower() == ok.lower():
return True
maybe_later(expected, answer)
return answer
#====================================#
# Shorter value to show in questions #
# return value[0:12] #
#------------------------------------#
def shorter(value):
if len(value) > 12:
return '%s...'%(value[0:12])
# Or legacy
return value
#=========================#
# Confirm domain name #
# from directory basename #
# ------------------------#
def ask_domain_shortname(config_name):
q = "> %s (%s)%s "%(langs.logs.configure_domain, config_name, langs.logs.q)
ask(q, True, False)
#=======================#
# Getting domain Title #
# update #
# - True: domain file #
# - False: return value #
#-----------------------#
def ask_domain_title(update):
try: title = domain.cf.get("DOMAIN", "title")
except: title = ""
q = "> %s (%s)%s "%(langs.logs.domain_title, shorter(title), langs.logs.q)
answer = ask(q, False, title)
if update: tools.update_ini_file(domain.cf_uri, "DOMAIN", "title", answer)
else: return answer
#===========================#
# Get domain creation date #
# Check if date match regex #
# update #
# - True: domain file #
# - False: return value #
#---------------------------#
def ask_domain_date(update):
try: date = domain.cf.get("DOMAIN", "date")
except: date = "YYYY[-MM][-DD]"
example = date
q = "> %s (%s)%s "%(langs.logs.domain_date, example, langs.logs.q)
answer = ask(q, False, date)
# Check date format (not valid date)
try:
parse(answer)
except:
debug.out(50, "YYYY[-MM-DD]", answer, True, 2, False)
ask_domain_date(update)
return
if update: tools.update_ini_file(domain.cf_uri, "DOMAIN", "date", answer)
else: return answer
#========================#
# Get domain description #
# update #
# - True: domain file #
# - False: return value #
#------------------------#
def ask_domain_about(update):
try: about = domain.cf.get("DOMAIN", "about")
except: about = ""
q = "> %s (%s)%s "%(langs.logs.domain_about, shorter(about), langs.logs.q)
answer = ask(q, False, about)
if update: tools.update_ini_file(domain.cf_uri, "DOMAIN", "about", answer)
else: return answer
#=======================#
# Get domain admin mail #
# update #
# - True: domain file #
# - False: return value #
#-----------------------#
def ask_domain_mail(update):
try: mail = domain.cf.get("DOMAIN", "mail")
except: mail = ""
q = "> %s (%s)%s "%(langs.logs.domain_mail, shorter(mail), langs.logs.q)
answer = ask(q, False, mail)
if update: tools.update_ini_file(domain.cf_uri, "DOMAIN", "mail", answer)
else: return answer
#===============================================#
# Get domain tags (wil be used in all articles) #
# update #
# - True: domain file #
# - False: return value #
#-----------------------------------------------#
def ask_domain_tags(update):
try: tags = domain.cf.get("DOMAIN", "tags")
except: tags = ""
q = "> %s (%s)%s "%(langs.logs.domain_tags, shorter(tags), langs.logs.q)
answer = ask(q, False, tags)
# Remove useless spaces for HTML meta
tuple_tags = answer.rsplit(",")
answer = ""
for i, tag in enumerate(tuple_tags):
answer = answer + tag.strip()
if i != len(tuple_tags) - 1:
answer = answer + ","
if update: tools.update_ini_file(domain.cf_uri, "DOMAIN", "tags", answer)
else: return answer
#===================================#
# Get domain lang #
# default en if no translation file # > !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! < TODO
#-----------------------------------#
def ask_domain_lang(update):
try: lang = domain.cf.get("WEBSITE", "lang") or langs.get_sys_lang()
except: lang = ""
q = "> %s (%s)%s "%(langs.logs.domain_lang, lang, langs.logs.q)
answer = ask(q, False, lang).lower()
# Lang Format is 2 character
if len(answer) != 2:
debug.out("8", "xx", answer, True, 2, False)
debug.out(103, "en", "%swebsite_en.py"%langs.trfs, True, 1, False)
answer = lang
# Check if translation file exists
if not langs.translation_exists("website", answer, False):
lang = lang.get_sys_lang()
debug.out(103, lang, "%swebsite_%s.py"%(langs.trfs, lang), True, 1, False)
answer = lang
if update: tools.update_ini_file(domain.cf_uri, "WEBSITE", "lang", answer)
else: return lang
#===================================#
# Get domain server root #
#-----------------------------------#
def ask_domain_server(update):
try:
srv = domain.cf.get("SERVER", "root")
if not tools.dir_exists(srv, False):
srv = ""
except:
srv = ""
if srv and not tools.dir_exists(srv, False):
srv = ""
q = "> %s (%s)%s "%(langs.logs.domain_srv, srv, langs.logs.q)
answer = ask(q, False, srv)
# Check if directory exists
if not tools.dir_exists(answer, False):
answer = ""
ask_domain_server(update)
return
if update: tools.update_ini_file(domain.cf_uri, "SERVER", "root", answer)
else: return answer

View File

@ -27,7 +27,9 @@ import locale
import domain import domain
# Settings files #==============================#
# Settings register lang files #
#------------------------------#
def set_lang_files(): def set_lang_files():
global lang_files, files_set global lang_files, files_set
@ -46,7 +48,9 @@ def set_lang_files():
files_set = True files_set = True
# Use logs from system language or default "en" #===============================================#
# Use logs from system language or default "en" #
#-----------------------------------------------#
def load_logs(): def load_logs():
global logs, logs_lang, logs_uri global logs, logs_lang, logs_uri
@ -57,13 +61,18 @@ def load_logs():
except: except:
logs_lang = "en" logs_lang = "en"
# To test other lang. Force set specific
#logs_lang = "en"
# Load language file # Load language file
logs_name = lang_files["logs"]["name"]%logs_lang logs_name = lang_files["logs"]["name"]%logs_lang
logs_uri = lang_files["logs"]["uri"]%logs_lang logs_uri = lang_files["logs"]["uri"]%logs_lang
logs = __import__(logs_name) logs = __import__(logs_name)
# loan language website values #==============================#
# load language website values #
#------------------------------#
def load_site(): def load_site():
global site global site

View File

@ -1,140 +0,0 @@
#!/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 General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#----------------------------------------------------------------------
# XMPP: echolib > im@echolib.re
#
# Description: Manage logs files in /var/log/tyto/
# File: /var/lib/tyto/program/logs.py
#----------------------------------------------------------------------
#-------------------------
# Funny Stats Project
#-------------------------
# file lines :
# file comments :
# file functions:
# file program :
#--------------------------
import os, sys, datetime
# 2 Files for logs
f_current = "/var/log/tyto/current.log" # Last session
f_archive = "/var/log/tyto/archive.log" # All sessions
#==============================#
# Set and return date and time #
#------------------------------#
def nowdate():
return(datetime.datetime.utcnow().isoformat())
#===================================#
# Create logs files (if not exists) #
#-----------------------------------#
def create_files():
global error_write, check
# Process done.
# In error case or files exist, not need to create again
try: check ; return
except: pass
# Process could not write file, no need to continue
try: error_write ; return
except: pass
CS = '\033[0;0m' # Unset
CL = '\033[0;2m' # Gray
CR = '\033[1;31m' # Red
for f in (f_current, f_archive):
if not os.path.exists(f):
try:
with open(f, "w") as f:
f.write("")
except:
print("%s!%s %sUnused%s %s"%(
CR,CS, CL,CS, f )
)
error_write = True
check = True
#=====================================#
# Create current.log for each session #
#
def add_line(nbr, message, var, val):
global first_log
# Create logs files (if not exists)
create_files()
# In error case (unused log file), return
try: error_write ; return
except: pass
# Merge current logs in archive logs (done only at first log)
archive_current_logs()
# At first log only, add command line to current logs
try:
first_log
except:
first_log = True
# Get command line
command = ""
for arg in range(1, len(sys.argv)):
command = command + sys.argv[arg] + " "
with open(f_current, "w") as f:
f.write("[%s] $ tyto %s"%(nowdate(), command))
# Create line for file
n_spaces = 3 - len(str(nbr))
with open(f_current, "a") as f:
f.write("\n[%s] %s%s => %s > %s < %s"%(
nowdate(), nbr, (n_spaces * " "), message, var, val
)
)
#==================================#
# Merge current.log to archive.log #
# Done only once, at first log #
#----------------------------------#
def archive_current_logs():
global merge_done
try: merge_done ; return
except: pass
# Load current logs file lines
current_logs = open(f_current, "r").read()
# No need to append empty current logs file
if current_logs:
# Append current logs file to archive logs
with open(f_archive, "a") as f:
f.write("%s\n\n"%(current_logs))
merge_done = True

View File

@ -538,7 +538,7 @@ header_raw = """
<div id="header_abouts"> <div id="header_abouts">
<p id="header_title">%s</p> <p id="header_title">%s</p>
<p id="header_about">%s</p> <p id="header_about">%s</p>
</div< </div>
</header> </header>
</a> </a>
""" """

View File

@ -36,7 +36,7 @@ def manage():
domain.cf_update() domain.cf_update()
return return
domain.is_ready() domain.is_active()
if args.commands["modules"]["modules"]: if args.commands["modules"]["modules"]:
modules.manage("all") modules.manage("all")
return return
@ -47,4 +47,4 @@ def manage():
args.commands["modules"]["sidebar"] and modules.manage("sidebar") args.commands["modules"]["sidebar"] and modules.manage("sidebar")
args.commands["modules"]["footer"] and modules.manage("footer") args.commands["modules"]["footer"] and modules.manage("footer")
args.commands["modules"]["sitemap"] and sitemap.create() args.commands["targets"]["sitemap"] and sitemap.create()

View File

@ -33,7 +33,7 @@ import domain, args, wip, post, debug, tools, sitemap, feed
# From command "publish", copy wip article to www server # # From command "publish", copy wip article to www server #
#--------------------------------------------------------# #--------------------------------------------------------#
def manage(): def manage():
domain.is_ready() domain.is_active()
global out global out
if args.article: if args.article:

View File

@ -1,34 +0,0 @@
#!/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 General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#----------------------------------------------------------------------
# XMPP: echolib (im@echolib.re)
#
# Description: When user wants to set something (mainly in domain)
# File: /var/lib/tyto/program/set.py
#----------------------------------------------------------------------
#-------------------------
# Funny Stats Project
#-------------------------
# file lines :
# file comments :
# file functions:
# file program :
#--------------------------

View File

@ -14,60 +14,69 @@
# GNU General Public License for more details. # GNU General Public License for more details.
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>. # along with this program. If not, see <https://www.gnu.org/licenses/>..
#---------------------------------------------------------------------- #----------------------------------------------------------------------
# XMPP: echolib > im@echolib.re # XMPP: echolib (im@echolib.re)
# #
# Description: When user wants to see something # Description: When user wants to show something (contents of a file...)
# File: /var/lib/tyto/program/show.py # File: /var/lib/tyto/program/show.py
#---------------------------------------------------------------------- #----------------------------------------------------------------------
#-------------------------
# Funny Stats Project
#-------------------------
# file lines :
# file comments :
# file functions:
# file program :
#--------------------------
import os import os
import domain, debug, wip import args, domain, debug
#====================================# #================================#
# Manage arguments from command line # # From args, show files contents #
# Specific to action "show" # #--------------------------------"
#------------------------------------# def manage():
def manage(action, target): domain.is_ready()
do = {
"domains" : all_domains,
"metas" : metas_post,
}
do[target]() # "all" is not a valid argument here
if args.commands["targets"]["all"]:
debug.out(2, "all ?", "", True, 2, True)
# Avoid error where "modules" is for "all", not a real module
if args.commands["modules"]["modules"]:
args.commands["modules"]["modules"] = False
# User selected modules
for arg in args.commands["modules"]:
if args.commands["modules"][arg]:
contents_file(domain.wrk_dirs["modules"] + "%s.raw"%arg, False)
contents_file(domain.wip_dirs["template"] + "%s.html"%arg, False)
# Show domain configuration file
args.commands["targets"]["domain"] and contents_file(domain.cf_uri, True)
# Show article(s) contents .tyto file
if args.commands["targets"]["*.tyto"]:
for post in args.commands["targets"]["*.tyto"]:
contents_file(os.path.join(domain.user_dir, post), True)
# Sitemap
if args.commands["targets"]["sitemap"]:
contents_file(domain.wrk_dirs["articles"] + "sitemap.tyto", True)
#============================# #=======================================#
# List all registred domains # # Read content of file #
#----------------------------# # raw: False #
def all_domains(): # - Filter line (commants, empty lines) #
domain.ult_dlf_load() #---------------------------------------#
try: def contents_file(uri, raw):
c = 0 if not os.path.exists(uri):
for key, value in domain.ult_dlf.items("DOMAINS"): debug.out(11, "!?", uri, True, 2, False)
if key: c += 1 return
print(": %s > %s"%(key,value))
print("|\n; total =",c)
except: print("; %s\n; %s\n; %s"%(78 * "=", uri, 78 * "="))
debug.out(104, "False", domain.ult_dlf_uri, True, 1, False) with open(uri, "r") as f:
for line in f.read().rsplit("\n"):
if not raw:
if line.startswith("#") or not line or line.isspace():
continue
print(line)
print()
#====================================#
# Show article metas used in page #
# Not included, default set by users #
#------------------------------------#
def metas_post():
print(wip.metas_post)

View File

@ -1,252 +0,0 @@
#!/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 General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#----------------------------------------------------------------------
# XMPP: echolib > im@echolib.re
#
# Description: Create sitemaps
# File: /var/lib/tyto/program/sitemaps.py
#----------------------------------------------------------------------
#-------------------------
# Funny Stats Project
#-------------------------
# file lines :
# file comments :
# file functions:
# file program :
#--------------------------
import os
import args, debug, domain, post, langs, tools, check, wip
sitemap_post = """# %s Tyto - Littérateur
! NoSitemap
title: %s (%s)
about: %s (%s)
tags: %s
author: Tyto
date: %s
-----
#1 %s. %s%s "%s"
(( sitemap
<: sitemap-items
%s
:>
))
#1 %s
(( sitemap
<: sitemap-items
%s
:>
))
"""
sitemap_post_empty = """ %s Tyto - Littérateur
! NoSitemap
title: %s (%s)
about: %s (%s)
tags: %s
author: Tyto
date: %s
-----
(( sitemap
%s
))
"""
# Generic link for sitemap
link = ' %s <a class="%s sitemap" href="%s" title="%s [%s]">%s%s</a>'
#===========================#
# Manage sitemaps creations #
#---------------------------#
def manage():
domain.cf_update_values(False)
domain.ready()
if not domain.sitemaps:
return
global nowdate
nowdate = tools.nowdate().rsplit()[0]
debug.out(216, "sitemap.tyto", "sitemap.html", False, 0, False)
# Create sitemap for root and sub-directories
create_by_dir(domain.wrk_articles)
create_by_subdir()
#====================================================#
# Search in specific path directory #
# for Tyto articles, and filter them by newest first #
#---------------------------------------------------#
def articles_sorted(path):
os.chdir(path)
files = filter(os.path.isfile, os.listdir(path))
files = [os.path.join(path, f) for f in files if f.endswith(".tyto")]
files.sort(key=lambda t: os.path.getmtime(t), reverse=True)
return files
#=======================#
# Return post DB values #
#-----------------------#
def set_db_values():
return post.tmp_db_item("FILE", "target", False), \
post.tmp_db_item("FILE", "web", False), \
post.tmp_db_item("HEADERS", "title", False), \
post.tmp_db_item("HEADERS", "about", False), \
post.tmp_db_item("HEADERS", "date", False), \
post.tmp_db_item("HEADERS", "authors", False)
#=========================================================#
# Main function to make sitemap.tyto and sitemap.html #
# List Tyto articles by newest in each directory #
# Create 2 links lists (only if a valid article is added) #
# 1. directories pointing to sitemap.html
# 2. articles
# ...
#
def create_by_dir(path):
target_dir = path.rsplit(domain.wrk_articles[:-1])[1]
target_slashes = target_dir.count("/")
curr_root = root = list_pages_links = list_posts_links = ""
has_article = False
for root, dirs, files in os.walk(path):
articles = articles_sorted(root)
for article in articles:
has_article = True
if curr_root != root:
curr_root = root
add_page_link = True
else:
add_page_link = False
# Load post DB (if exists)
post.tmp_db_error = False
if not post.tmp_load_db(article) or post.tmp_db_error:
curr_root = ""
continue
target, web, title, about, date, authors = set_db_values()
web_slashes = web.count("/")
# Add page link (pointing to sitemap.html)
# Add only one same link if an article exists
if add_page_link:
# For sub directories, mark "="
# is the différence with web target and root domain
if path != domain.wrk_articles:
web_slashes = web_slashes - target_slashes
if list_pages_links: nl1 = "\n"
else: nl1 = ""
list_pages_links = \
list_pages_links + nl1 + link%(
"=" * web_slashes,
domain.css, "%ssitemap.html"%web,
"%s%s %s"%(
langs.site.sitemap, langs.logs.pp, web
), "Tyto", "", web
)
# Add article link
if list_posts_links: nl2 = "\n"
else: nl2 = ""
list_posts_links = \
list_posts_links + nl2 + link%(
"=" * web_slashes,
domain.css, web, about, authors, date + ", ", title
)
# A sitemap is created if a Tyto article file is found
if not list_posts_links and not has_article:
return
if not list_posts_links:
root_sitemap = \
sitemap_post_empty%(
langs.site.sitemap_gen,
langs.site.sitemap, target_dir,
langs.site.sitemap, target_dir,
langs.site.sitemap,
nowdate,
langs.site.sitemap_empty
)
else:
root_sitemap = \
sitemap_post%(
langs.site.sitemap_gen,
langs.site.sitemap, target_dir,
langs.site.sitemap, target_dir,
langs.site.sitemap,
nowdate,
langs.site.sitemap, langs.site.directory, langs.logs.pp, target_dir,
list_pages_links,
langs.site.posts_list,
list_posts_links,
)
#print(root_sitemap)
if path != domain.wrk_articles: target_file = "/sitemap.tyto"
else: target_file = "sitemap.tyto"
target_file = target_dir[1:] + target_file
#print(">> target_f", target_file)
file_uri = domain.wrk_articles + target_file
#print(">> file_uri", file_uri)
os.chdir(domain.wrk_articles)
args.targets = "all"
tools.create_file(file_uri, root_sitemap)
wip.is_article(target_file)
#==========================================================#
# Loop from all sub directories from root domain articles/ #
# For each, create_by_dir() sitemaps #
#
def create_by_subdir():
for root, dirs, files in os.walk(domain.wrk_articles):
for d in dirs:
dir_uri = os.path.join(root,d)
create_by_dir(dir_uri)

View File

@ -185,9 +185,9 @@ def copy_files(src, dst):
debug.out(5, os.path.basename(src), dst, True, 2, True) debug.out(5, os.path.basename(src), dst, True, 2, True)
# #=========================#
# # Copy files in template/ #
# #-------------------------#
def copy_template_dir(process): def copy_template_dir(process):
src_dirs = { src_dirs = {
"wip" : domain.wrk_dirs["template"], "wip" : domain.wrk_dirs["template"],
@ -202,7 +202,6 @@ def copy_template_dir(process):
shutil.copytree(src_dirs[process], dst_dirs[process], dirs_exist_ok=True) shutil.copytree(src_dirs[process], dst_dirs[process], dirs_exist_ok=True)
#====================================================# #====================================================#
# Sorte dict by length name # # Sorte dict by length name #
# To avoid a bug with replace for similar tags names # # To avoid a bug with replace for similar tags names #

View File

@ -1,121 +0,0 @@
#!/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 General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#----------------------------------------------------------------------
# XMPP: echolib > im@echolib.re
#
# Description: Templates, settings, values
# File: /var/lib/tyto/program/tyto.py
#----------------------------------------------------------------------
import forms, wip
#
# Arguments in command line #
#
actions = (
"check", "wip", "publish",
"start", "stop",
"new",
"set",
"show",
)
targets = (
"domain",
"domains",
"title", "date", "about", "mail", "tags", "lang", "server",
"all",
"metas", "header", "navbar", "sidebar", "footer",
"sitemaps",
)
force_options = ("--force", "-F")
debug_options = ("--debug", "-D")
debug_errors = ('--errors', "-E")
#
#
#
full_name = "Tyto - Littérateur"
web_url = "https://tyto.echolib.re"
git_url = "https://forge.a-lec.org/echolib/tyto-litterateur"
#=============================================================#
# Domain questions #
# Used by domain.cf_set_value() #
# to check for configuration domain in [SECTION]: key = value #
# Ask user if no value and update configuration file #
#-------------------------------------------------------------#
keys_4q = ("server", "title", "date", "about", "mail", "tags")
keys_questions = {
"server" : forms.ask_domain_server,
"title" : forms.ask_domain_title,
"date" : forms.ask_domain_date,
"about" : forms.ask_domain_about,
"mail" : forms.ask_domain_mail,
"tags" : forms.ask_domain_tags
}
# Template file configuration for each a created domain
#
ini_domain_user = """[DOMAIN]
name =
hash =
root =
conf =
[SERVER]
root =
"""
# Domains list ini file
ini_domains_list = """[DOMAINS]
"""
# Put here values where posts target cannot begin with
notarget = ("./", "../")
#======#
# HTML #=======================================================================
#======#
code_bcode = """<code class="%s bcode">
%s%s
</code>"""
code_line = '<p class="bcode">' + \
'<span class="ln bcode">%s</span>' + \
'<span class="line bcode">%s</span>' +\
'</p>'
image_link = '<a href="%s" class="%s" title="%s">' + \
'%s<img src="%s" class="%s" alt="%s" title="%s"%s />' + \
'%s</a>'
a_link = '<a href="%s" class="%s" title="%s">%s</a>'
quote = """<blockquote class="%s"%s%s%s>%s
%s%s
%s
</blockquote>"""

View File

@ -1,66 +0,0 @@
#!/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 General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#----------------------------------------------------------------------
# XMPP: echolib > im@echolib.re
#
# Description: When user wants to set something (mainly in domain)
# File: /var/lib/tyto/program/set.py
#----------------------------------------------------------------------
#-------------------------
# Funny Stats Project
#-------------------------
# file lines :
# file comments :
# file functions:
# file program :
#--------------------------
import langs, forms, domain, wip
#====================================#
# Manage arguments from command line #
# Specific to action "set #
#------------------------------------#
def manage(action, target):
# Load or Exit if no configuration
domain.cf_load()
if action == "set":
do = {
"title" : forms.ask_domain_title,
"date" : forms.ask_domain_date,
"about" : forms.ask_domain_about,
"mail" : forms.ask_domain_mail,
"lang" : forms.ask_domain_lang,
"server" : forms.ask_domain_server,
"metas" : wip.create_default_module,
"header" : wip.create_default_module,
"navbar" : wip.create_default_module,
"sidebar" : wip.create_default_module,
"footer" : wip.create_default_module,
}
try: do[target](target)
except: pass
elif action in ("start", "stop") and target == "domain":
domain.userset_status(action)

View File

@ -33,7 +33,7 @@ import args, domain, debug, post, check, tools, langs, modules, page
# manage from "wip" command # # manage from "wip" command #
#---------------------------# #---------------------------#
def manage(): def manage():
domain.is_ready() domain.is_active()
# Multiple articles process # Multiple articles process
if args.commands["targets"]["all"]: if args.commands["targets"]["all"]:
@ -554,11 +554,11 @@ def bquotes():
else: contents = "%s\n%s"%(contents, bq_line) else: contents = "%s\n%s"%(contents, bq_line)
bquote = HTMLs["bquotes"]%( bquote = HTMLs["bquotes"]%(
css, bq_cite, bq_lang, bq_title, css, bq_cite, bq_lang, bq_title,
html_time_o, html_time_o,
contents, contents,
html_time_c, html_time_c,
html_footer html_footer
) )
replace_article(post.block_tags["bquotes"]["sources"][nbr][0], bquote) replace_article(post.block_tags["bquotes"]["sources"][nbr][0], bquote)

View File

@ -213,6 +213,7 @@ tyto [ACTION] [ARGUMENTS]
start > activate current domain start > activate current domain
stop > deactivate current domain stop > deactivate current domain
check ? + [domain] : check current domain check ? + [domain] : check current domain
show > show files contents [domain], [MODULES]...
wip ? create HTML in "wip/" server wip ? create HTML in "wip/" server
publish ? publish in "www/" server publish ? publish in "www/" server
@ -291,83 +292,77 @@ help_wip = """
help_modules = """ help_modules = """
: [MODULES] (metas...footer, modules) : [MODULES] (metas...footer, modules)
- [new modules] - [new modules]
La première création des fichiers de configuration des modules est First modules configuration files creation are automatic in "/modules/"
automatique dans le dossier du domaine "/modules/". Cette commande domain. This command will RESET ALL modules. sidebar.raw and navbar.raw
demande de réinitialiser TOUS les modules, ce qui videra les entrées are cleaned. Others (metas, header, footer) return to default contents.
de dossiers dans le fichier navbar.raw, et les entrées d'articles dans If you edit/add values in [WEBSITE_FOOTER] section of domain
le fichier sidebar.raw. Les autres modules (metas, header, footer) configuration file, you must reset footer module.
auront leur contenus par défaut. Si vous modifiez le fichier de
configuration du domaine, et notamment les valeurs dans la section
[WEBSITE_FOOTER], il faudra réinitialiser le module footer.
- [new [MODULE]] - [new [MODULE]]
Réinitialiser uniquement le [MODULE] concerné. Reset only this [MODULE].
- [wip modules] - [wip modules]
Cette action force la (re)génération HTML de TOUS les modules This command create (again) ALL HTML modules in "wip/template/" server.
dans le serveur "wip/template/". Peut être utile, notamment Can be usefull when an article data header has changed and this article
pour les modules navbar et sidebar lorsque le titre ou la is set in sidebar or navbar.
descrtiption d'un article se trouvant dedans a été modifié.
- [wip [MODULE]] - [wip [MODULE]]
(re)générer uniquement le [MODULE] concerné Create (again) this [MODULE]
! Pour que ces modules puissent être affichés dans les pages du site, il ! For these modules to be shown in website, you must add in the nginx
faut ajouter dans le fichier de configuration du serveur nginx configuration file (/etc/nginx/sites-available/DOMAIN.TLD):
(/etc/nginx/sites-available/DOMAINE.TLD) :
... ...
ssi on; ssi on;
ssi_last_modified on; ssi_last_modified on;
absolute_redirect off; absolute_redirect off;
... ...
""" """
css_info = "CSS Class can be set (default: css from domain configuration)"
# --------- # # --------- #
# Help list # # Help list #
# --------- # # --------- #
help_list = """ help_list = """
# Liste. Classe CSS possible (défaut : celle dans la configuration) # List. %s
# Une entrée de liste peut être ordonnée avec le signe "+" ou non avec "=" # List item in order with "+" or not with "=".
# Une liste peut contenir des entrées mixées ("+" et "=") # List can be items mixed, but at mark change, add one mark.
# mais au changement de signe, ajouter un signe ! # List item can be set on several lines
# Possible d'écrire une entrée sur plusieurs lignes
(= (=
= Première entrée non ordonnée (ul) = First item (ul)
== Sous entrée non ordonnée == Sub-item (ul)
+++ Première sous-sous entrée ordonnée (ol) +++ First Sub-Sub order item (ol)
+++ Seconde sous-sous entrée ordonnée +++ Second Sub-Sub order item (ol)
= Seconde entrée non ordonnée = Second item (ul)
= Troisième entrée ... = Third item ...
... non ordonnée ... on several line (ul)
)= )=
""" """%css_info
# --------- # # --------- #
# Help cite # # Help cite #
# --------- # # --------- #
help_cite = """ help_cite = """
# Citation (bloc). Classe CSS possible (défaut : celle dans la configuration) # blockquote. %s
# Les métadonnées d'une citation sont toutes optionnelles. # Metadatas are all optional (you can use cite: and/or book: only)
# (Vous pouvez mettre que cite: et book:)
(" ("
cite: Auteur cite: Author
date: AAAA-MM-JJ date: YYYY-MM-DD or YYYY
book: Nom du livre book: Book name
lang: fr lang: en
link: https://... link: https://...
(( ((
Citation complète dans un paragraphe Full quote in a paragraph
)) ))
)" )"
""" """%css_info
help_3lines = """# Ces marqueurs multiples doivent toujours être configurés sur 3 lignes help_3lines = """# These markers must be configured on 3 lines.
# Les noms doivent tous être uniques et reportés dans le contenu # NAME must be uniq and reported on writings with "::" before the NAME"""
# rédactionnel avec "::" devant le nom"""
# ---------- # # ---------- #
# Help image # # Help image #
@ -375,17 +370,17 @@ help_3lines = """# Ces marqueurs multiples doivent toujours être configurés su
help_image_header = """ help_image_header = """
image: Image001 image: Image001
URI URI
Texte alternatif Alternative Text
""" """
help_image_writer = """ help_image_writer = """
# Images. (Nom reporté de l'entête) # Images. (NAME reported from header)
# Options possibles devant respecter le format : # Optional settings after must be in that format : :
# ::Nom "c=ClassCSS", "w=WIDTH", "h=HEIGHT", "f=Légende de l'image" # ::NAME "c=ClassCSS", "w=WIDTH", "h=HEIGHT", "f=Legend of the pic"
# ! Une seule option termine par "," # ! One option must end with ","
::Image001 ::Image001
::Image001 "f=Une légende", ::Image001 "f=Legend of the pic",
""" """
help_image = """ help_image = """
@ -403,15 +398,15 @@ help_image = """
# Help link # # Help link #
# --------- # # --------- #
help_link_header = """ help_link_header = """
link: Nom du lien link: a Link NAME
URL / uri (non vérifié) URL / uri (not checked)
Texte alternatif Alternative Text
""" """
help_link_writer = """ help_link_writer = """
# Écrire un lien (Nom reporté de l'entête) # Write a link (NAME reported from header)
::Nom du lien ::a Link NAME
""" """
help_link = """ help_link = """
@ -424,17 +419,43 @@ help_link = """
help_link_writer, help_link_writer,
) )
# --------- #
# Help file #
# --------- #
help_file_header = """
file: this file
URI
Alternative Text
"""
help_file_writer = """
# Write a link to a file (NAME reported from header)
::this file
"""
help_file = """
%s
%s
-----
%s"""%(
help_3lines,
help_file_header,
help_file_writer,
)
# --------- # # --------- #
# Help Code # # Help Code #
# --------- # # --------- #
help_code_header = \ help_code_header = """
"""code: CodePython001 code: CodePython001
URI URI
Description placée en commentaire HTML""" Description written in HTML comment
"""
help_code_writer = """ help_code_writer = """
# Afficher le code source d'un fichier # Show source code of a file
# Code. (Nom reporté de l'entête) # Code. (NAME reported from header)
::CodePython001 ::CodePython001
""" """
@ -456,12 +477,12 @@ help_code = """
help_raw_header = """ help_raw_header = """
raw: CodeHTML001 raw: CodeHTML001
URI URI
Description placée en commentaire HTML Description written in HTML comment
""" """
help_raw_writer = """ help_raw_writer = """
# Coller le contenu du fichier brut (exécuté par le navigateur) # Paste raw contents of a file (executed by the browser)
# Raw. (Nom reporté de l'entête) # Raw. (NAME reported from header)
::CodeHTML001 ::CodeHTML001
""" """
@ -487,7 +508,7 @@ abbr: CSS
""" """
help_abbr_writer = """ help_abbr_writer = """
# Abréviations. (Nom reporté de l'entête) # Abbreviation. (NAME reported from header)
::CSS ::CSS
""" """
@ -507,18 +528,17 @@ help_abbr = """
# Help ABBR # # Help ABBR #
# --------- # # --------- #
help_anc_header = """ help_anc_header = """
# Définir une ancre # Set an anchor
# ! Chaque ancre doit avoir une ID unique # ! Each anchor ID must be uniq (and not start with "toc_")
# (et ne pas commencer par "toc_")
-> top -> top
""" """
help_anc_writer = """ help_anc_writer = """
# Lien vers une ancre définie # Link to an anchor
# format : >`ID: Message à afficher`< # Format : >`ID: Message to show`<
>`top:Aller en haut`< >`top:Go to Top of the page`<
""" """
help_anc = """%s%s help_anc = """%s%s
@ -532,29 +552,34 @@ help_anc = """%s%s
# Words tags # # Words tags #
# ---------- # # ---------- #
help_words = """ help_words = """
# Écrire les marqueurs de mots # Write words markers
# Chaque marqueur à la classe CSS de la configuration # Each markers has css from domain configuration
# Astuce : ** + ← + `` + ← + très gras # Tip : ** + ← + `` + ← + in strong
*`très gras`* => <strong> *`in strong`* => <strong>
+`gras`+ => <b> +`bold`+ => <b>
/`italique`/ => <em> /`emphasis`/ => <em>
;`italique`; => <i> ;`italic`; => <i>
_`souligné`_ => <u> _`underline`_ => <u>
~`effacé`~ => <del> ~`deleted`~ => <del>
[`cité`] => <q> # Contenu [`quote`] => <q> # Content
:`cité`: => <cite> # auteur, nom :`cite`: => <cite> # Author, reference
|`perso`| => <span> |`custom`| => <span>
# Code dans un texte # Code in text
# ! Les marqueurs d'ouverture et de fermeture de code sont sur la MEME LIGNE # ! Opened and closed markers must be on the SAME LINE
{` <li>Une entée de liste</li> `} => <code> {` <li>Une entée de liste</li> `} => <code>
# ! Dans certains cas, il faut ajouter un espace après le 1er marqueur # In some cases, add space after opened marker and before closed marker,
# et/ou avant le second. Ils seront automatiquement supprimés # they will be deleted
*`DOMAIN/articles/ `* # évite /` : marqueur italique ouvert *`DOMAIN/articles/ `* # as /` is the emphasis opened marker
# Multiple markers. Add "&"
# Tip : ** + ← + `` + ← && + ← + __ + ← `` + ← Strong and underline
*`&_`Strong and underline`_&`*
""" """
# ------------ # # ------------ #
@ -562,66 +587,65 @@ _`souligné`_ => <u>
# ------------ # # ------------ #
help_article = """ help_article = """
: [.tyto] : [.tyto]
Un fichier-article .tyto est séparé en 2 par au moins 5 tirets A .tyto article-file is seperated with 5 dashes "-----" to define header
"-----" pour définir l'entête (les métadonnées), et le contenu (metadatas) and writings contents. Here is a .tyto article-file containing
rédactionnel. Voici le contenu d'un fichier-article .tyto avec all markers to use. linges starting with "# " are file comments. You can
tous les marqueurs possibles. Les lignes commençant par "#" sont also yse them in your articles.
des commentaires (que vous pouvez aussi utiliser dans vos articles)
# Début du fichier # Starting file
# ---------------- # -------------
# Ces 5 marqueurs sont obligatoires # These 5 markers MUST be set, each on ONE LINE
# ---------- # ----------
title: Titre <h1> de l'article title: The <h1> article title
about: Description de l'article about: Description of the article
tags: étiquette1,étiquette longue,étiquette3 tags: tag1,another tag,tag3
date: AAAA-MM-JJ date: YYYY-MM-DD
authors: auteur1,auteur2 authors: Author1,author2
# Tous les marqueurs suivants sont optionnels # All these markers are optional
# ---------- # ----------
# Si non renseigné, le logo de l'article sera celui du site # If not set, article log is domain logo image
logo: URI logo: URI
%s %s
%s%s%s%s%s%s %s%s%s%s%s%s
# URI # URI
# - Commence par @ : # - Starts with @
# - - le fichier est dans articles/images/ pour les marqueurs logo: et image: # - - file is from articles/images/ for logo: and image: markers
# - - le fichier est dans articles/files/ pour les autres marqueurs # - - file is from articles/files/ for other markers
# - Commence par / : # - Starts with /
# - - le fichier est depuis la racine articles/ du domaine # - - file is from root domain articles/
# - Commence pas par @ ou / : # - NOT starts with @ or /
# - - le fichier est depuis le dossier où se trouve le fichier-article .tyto # - - file is from directory where article-file.tyto is
# Marqueur pour NE PAS inclure l'article dans le sitemap # Marker to NOT include article in sitemap
! NOMAP ! NOMAP
# Marqueur pour NE PAS inclure l'article dans le flux RSS # Marker to NOT include article in RSS/feed
! NORSS ! NORSS
# Séparateur # Separator
----- -----
%s %s
# Marqueur pour créer la table des matières en fonction des titres # Marker to create table of contents according to Titles
! TOC ! TOC
# Les titres (#1 à #5, équivalents de <h2> à <h6>) # Titles (#1 to #5, mean <h2> to <h6>)
#1 Titre 1 #1 Title 1
#2 Sous-titre 1 #2 Sub-title 1
# Paragraphe. Classe CSS possible (défaut : celle dans la configuration) # Paragraph. %s
(( ((
Un paragraphe Some Texts in a paragraph...
(( note (( note
Un sous-paragraphe ayant la classe CSS "note" A sub-paragraph with CSS class "note"
)) ))
)) ))
# Block-Code. Classe CSS possible (défaut : celle dans la configuration) # Block-Code. %s
# ! Le marqueur d'ouverture est à la même position que le marqueur de fermeture # ! Opened marker is at same position than closed marker
{{ PyCode {{ PyCode
... ...
... ...
@ -637,19 +661,21 @@ logo: URI
%s %s
%s %s
# Retour à la ligne. Classe CSS possible (défaut : celle dans la configuration) # New line. %s
# La ligne commence par le symbôle "|" (<br>) # Line starts with "|" (<br>)
::Image001 ((
| ::Image001
::Image001 "c=Maclasse", |
::Image001 "c=MyClass",
))
# Tirer un trait. Classe CSS possible (défaut : celle dans la configuration) # Dash line. %s
# La ligne contient juste "--" (<hr>) # Line contains only "--" (<hr>)
-- --
%s %s
# -------------- # -----------
# Fin du fichier # Ending file
"""%( """%(
help_3lines, help_3lines,
help_link_header, help_link_header,
@ -659,6 +685,8 @@ logo: URI
help_raw_header, help_raw_header,
help_abbr_header, help_abbr_header,
help_anc_header, help_anc_header,
css_info,
css_info,
help_list, help_list,
help_cite, help_cite,
help_image_writer, help_image_writer,
@ -668,5 +696,7 @@ logo: URI
help_file_writer, help_file_writer,
help_words, help_words,
help_abbr_writer, help_abbr_writer,
css_info,
css_info,
help_anc_writer, help_anc_writer,
) )

View File

@ -213,6 +213,7 @@ tyto [ACTION] [ARGUMENTS]
start > activer le domain actuel start > activer le domain actuel
stop > désactiver le domaine actuel stop > désactiver le domaine actuel
check ? + [domain] : vérifier le domaine actuel check ? + [domain] : vérifier le domaine actuel
show > montre le contenu des fichiers [domain], [MODULES]...
wip ? créer de l'HTML dans le serveur "wip/" wip ? créer de l'HTML dans le serveur "wip/"
publish ? publier dans le serveur "www/" publish ? publier dans le serveur "www/"
@ -326,14 +327,16 @@ help_modules = """
... ...
""" """
css_info = "Classe CSS possible (défaut : css de la configuration)"
# --------- # # --------- #
# Help list # # Help list #
# --------- # # --------- #
help_list = """ help_list = """
# Liste. Classe CSS possible (défaut : celle dans la configuration) # Liste. %s
# Une entrée de liste peut être ordonnée avec le signe "+" ou non avec "=" # Une entrée de liste peut être ordonnée (signe "+") ou non (signe "=")
# Une liste peut contenir des entrées mixées ("+" et "=") # Une liste peut contenir des entrées mixées mais au changement de signe,
# mais au changement de signe, ajouter un signe ! # ajouter un signe !
# Possible d'écrire une entrée sur plusieurs lignes # Possible d'écrire une entrée sur plusieurs lignes
(= (=
@ -345,19 +348,19 @@ help_list = """
= Troisième entrée ... = Troisième entrée ...
... non ordonnée ... non ordonnée
)= )=
""" """%css_info
# --------- # # --------- #
# Help cite # # Help cite #
# --------- # # --------- #
help_cite = """ help_cite = """
# Citation (bloc). Classe CSS possible (défaut : celle dans la configuration) # Citation (bloc). %s
# Les métadonnées d'une citation sont toutes optionnelles. # Les métadonnées sont toutes optionnelles (vous pouvez utiliser que
# (Vous pouvez mettre que cite: et book:) # cite: et/our book: seulement)
(" ("
cite: Auteur cite: Auteur
date: AAAA-MM-JJ date: AAAA-MM-JJ ou AAAA
book: Nom du livre book: Nom du livre
lang: fr lang: fr
link: https://... link: https://...
@ -366,7 +369,7 @@ help_cite = """
Citation complète dans un paragraphe Citation complète dans un paragraphe
)) ))
)" )"
""" """%css_info
help_3lines = """# Ces marqueurs multiples doivent toujours être configurés sur 3 lignes help_3lines = """# Ces marqueurs multiples doivent toujours être configurés sur 3 lignes
# Les noms doivent tous être uniques et reportés dans le contenu # Les noms doivent tous être uniques et reportés dans le contenu
@ -388,7 +391,7 @@ help_image_writer = """
# ! Une seule option termine par "," # ! Une seule option termine par ","
::Image001 ::Image001
::Image001 "f=Une légende", ::Image001 "f=Légende de l'image",
""" """
help_image = """ help_image = """
@ -428,7 +431,7 @@ help_link = """
) )
# --------- # # --------- #
# Help link # # Help file #
# --------- # # --------- #
help_file_header = """ help_file_header = """
file: ce fichier file: ce fichier
@ -452,7 +455,6 @@ help_file = """
help_file_writer, help_file_writer,
) )
# --------- # # --------- #
# Help Code # # Help Code #
# --------- # # --------- #
@ -538,15 +540,14 @@ help_abbr = """
# --------- # # --------- #
help_anc_header = """ help_anc_header = """
# Définir une ancre # Définir une ancre
# ! Chaque ancre doit avoir une ID unique # ! Chaque ancre doit avoir une ID unique (et ne pas commencer par "toc_")
# (et ne pas commencer par "toc_")
-> top -> top
""" """
help_anc_writer = """ help_anc_writer = """
# Lien vers une ancre définie # Lien vers une ancre définie
# format : >`ID: Message à afficher`< # Format : >`ID: Message à afficher`<
>`top:Aller en haut`< >`top:Aller en haut`<
""" """
@ -573,7 +574,7 @@ help_words = """
_`souligné`_ => <u> _`souligné`_ => <u>
~`effacé`~ => <del> ~`effacé`~ => <del>
[`cité`] => <q> # Contenu [`cité`] => <q> # Contenu
:`cité`: => <cite> # auteur, nom :`cité`: => <cite> # Auteur, référence
|`perso`| => <span> |`perso`| => <span>
# Code dans un texte # Code dans un texte
@ -584,7 +585,12 @@ _`souligné`_ => <u>
# ! Dans certains cas, il faut ajouter un espace après le 1er marqueur # ! Dans certains cas, il faut ajouter un espace après le 1er marqueur
# et/ou avant le second. Ils seront automatiquement supprimés # et/ou avant le second. Ils seront automatiquement supprimés
*`DOMAIN/articles/ `* # évite /` : marqueur italique ouvert *`DOMAINE/articles/ `* # comme /` est le marqueur italique d'ouverture
# Multiples marqueurs. Ajouter "&"
# Tip : ** + ← + `` + ← && + ← + __ + ← `` + ← Très gras et souligné
*`&_`Très gras et souligné`_&`*
""" """
# ------------ # # ------------ #
@ -595,19 +601,19 @@ help_article = """
Un fichier-article .tyto est séparé en 2 par au moins 5 tirets Un fichier-article .tyto est séparé en 2 par au moins 5 tirets
"-----" pour définir l'entête (les métadonnées), et le contenu "-----" pour définir l'entête (les métadonnées), et le contenu
rédactionnel. Voici le contenu d'un fichier-article .tyto avec rédactionnel. Voici le contenu d'un fichier-article .tyto avec
tous les marqueurs possibles. Les lignes commençant par "#" sont tous les marqueurs possibles. Les lignes commençant par "# " sont
des commentaires (que vous pouvez aussi utiliser dans vos articles) des commentaires (que vous pouvez aussi utiliser dans vos articles)
# Début du fichier # Début du fichier
# ---------------- # ----------------
# Ces 5 marqueurs sont obligatoires # Ces 5 marqueurs sont obligatoires, chacun sur UNE LIGNE
# ---------- # ----------
title: Titre <h1> de l'article title: Titre <h1> de l'article
about: Description de l'article about: Description de l'article
tags: étiquette1,étiquette longue,étiquette3 tags: étiquette1,étiquette longue,étiquette3
date: AAAA-MM-JJ date: AAAA-MM-JJ
authors: auteur1,auteur2 authors: Auteur1,auteur2
# Tous les marqueurs suivants sont optionnels # Tous les marqueurs suivants sont optionnels
# ---------- # ----------
@ -617,12 +623,12 @@ logo: URI
%s %s
%s%s%s%s%s%s %s%s%s%s%s%s
# URI # URI
# - Commence par @ : # - Commence par @
# - - le fichier est dans articles/images/ pour les marqueurs logo: et image: # - - le fichier est dans articles/images/ pour les marqueurs logo: et image:
# - - le fichier est dans articles/files/ pour les autres marqueurs # - - le fichier est dans articles/files/ pour les autres marqueurs
# - Commence par / : # - Commence par /
# - - le fichier est depuis la racine articles/ du domaine # - - le fichier est depuis la racine articles/ du domaine
# - Commence pas par @ ou / : # - Commence pas par @ ou /
# - - le fichier est depuis le dossier où se trouve le fichier-article .tyto # - - le fichier est depuis le dossier où se trouve le fichier-article .tyto
# Marqueur pour NE PAS inclure l'article dans le sitemap # Marqueur pour NE PAS inclure l'article dans le sitemap
@ -642,15 +648,15 @@ logo: URI
#1 Titre 1 #1 Titre 1
#2 Sous-titre 1 #2 Sous-titre 1
# Paragraphe. Classe CSS possible (défaut : celle dans la configuration) # Paragraphe. %s
(( ((
Un paragraphe Un paragraphe...
(( note (( note
Un sous-paragraphe ayant la classe CSS "note" Un sous-paragraphe ayant la classe CSS "note"
)) ))
)) ))
# Block-Code. Classe CSS possible (défaut : celle dans la configuration) # Code (bloc). %s
# ! Le marqueur d'ouverture est à la même position que le marqueur de fermeture # ! Le marqueur d'ouverture est à la même position que le marqueur de fermeture
{{ PyCode {{ PyCode
... ...
@ -667,13 +673,15 @@ logo: URI
%s %s
%s %s
# Retour à la ligne. Classe CSS possible (défaut : celle dans la configuration) # Retour à la ligne. %s
# La ligne commence par le symbôle "|" (<br>) # La ligne commence par le symbôle "|" (<br>)
::Image001 ((
| ::Image001
::Image001 "c=Maclasse", |
::Image001 "c=Maclasse",
))
# Tirer un trait. Classe CSS possible (défaut : celle dans la configuration) # Tirer un trait. %s
# La ligne contient juste "--" (<hr>) # La ligne contient juste "--" (<hr>)
-- --
%s %s
@ -689,6 +697,8 @@ logo: URI
help_raw_header, help_raw_header,
help_abbr_header, help_abbr_header,
help_anc_header, help_anc_header,
css_info,
css_info,
help_list, help_list,
help_cite, help_cite,
help_image_writer, help_image_writer,
@ -698,5 +708,7 @@ logo: URI
help_file_writer, help_file_writer,
help_words, help_words,
help_abbr_writer, help_abbr_writer,
css_info,
css_info,
help_anc_writer, help_anc_writer,
) )

View File

@ -1,53 +0,0 @@
#!/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 General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>..
#----------------------------------------------------------------------
# XMPP: echolib (im@echolib.re)
#
# Description: English website translation file
# File: /var/lib/tyto/translations/logs_en.py
#
# How to translate:
# - create filename website_xx.py in /var/lib/tyto/translations/
# where xx are 2 first lang letters (es, for spanish...)
# - copy its contents and translate values
#----------------------------------------------------------------------
# Note: python file
sidebar_title = "Featured posts"
directory = "Directory"
sitemap = "Sitemap"
sitemap_gen = "Sitemap source article generated by"
sitemap_empty = "Nothing to show yet"
posts_list = "Articles list"
source_code = "Source code"
permalink = "Permalink"
license = "License"
license_title = "Website %s of"%license
legals = "Legal Mentions"
legals_title = "%s of"%legals
terms = "Terms of Service"
terms_title = "%s of"%terms
bylaws = "Bylaws"
bylaws_title = "%s of"%bylaws
feed_rss = "RSS feed 2.0"
generated_by = "Generated by"
off_website = "Official website"

View File

@ -1,53 +0,0 @@
#!/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 General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>..
#----------------------------------------------------------------------
# XMPP: echolib (im@echolib.re)
#
# Description: Fichier français de traduction des sites web
# File: /var/lib/tyto/translations/website_fr.py
#
# Comment traduire :
# - créer un fichier nommé logs_xx.py dans /var/lib/tyto/translations/
# oû xx sont les 2 première lettres de la langue (es, pour espagnol...)
# - Copier ce contenu dedans, et traduire les variables
#----------------------------------------------------------------------
# Note: Fichier au format python
sidebar_title = "Articles recommandés"
directory = "Dossier"
sitemap = "Plan du site"
sitemap_gen = "Article source du plan du site généré par"
sitemap_empty = "Rien à afficher pour le moment."
posts_list = "Liste des articles"
source_code = "Code source"
permalink = "Permalien"
license = "Licence"
license_title = "%s du site web de"%license
legals = "Mentions légales"
legals_title = "%s de"%legals
terms = "C.G.U"
terms_title = "%s de"%terms
bylaws = "Statuts"
bylaws_title = "%s de"%bylaws
feed_rss = "Flux RSS 2.0"
generated_by = "Géneré par"
off_website = "Site web officiel"