[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) !
## [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

View File

@ -1,5 +1,5 @@
# 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.
@ -19,7 +19,7 @@ tyto help words anchor
- create a domain directory, like www.domain.tld
- Go to this directory
- 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)
- type `wip myfile.tyto`

6
debian/control vendored
View File

@ -1,10 +1,10 @@
Package: tyto
Version: 1.9.50
Version: 1.9.51
Section: custom
Priority: optional
Architecture: all
Essential: no
Depends: nano,python3
Depends: python3
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.

View File

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

View File

@ -38,6 +38,7 @@ def get_arguments():
"wip" : False,
"publish" : False,
"new" : False,
"show" : False,
"start" : False,
"stop" : False,
"help" : False,
@ -62,6 +63,7 @@ def get_arguments():
},
}
# Arguments from command line
# ---------------------------
set_module = False
@ -86,12 +88,17 @@ def get_arguments():
set_module = True
continue
if commands["modules"]["modules"]:
for arg in commands["modules"]:
commands["modules"][arg] = True
# Register options
for arg in commands["options"]:
if sys.argv[user_arg] == arg:
commands["options"][sys.argv[user_arg]] = True
continue
# Action, the first argument
# --------------------------
err_action = True
@ -107,84 +114,3 @@ def get_arguments():
err_action = action
action = "help"
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 = {
"wip" : cf.get("WEBSITE", "wip_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"),
"lang" : cf.get("WEBSITE", "lang"),
"license" : cf.get("WEBSITE", "license"),
@ -216,6 +220,16 @@ def is_ready():
cf_update()
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 #

View File

@ -49,7 +49,6 @@ def create():
for db_uri in items:
if nbr_item == max_item:
print("MAX")
break
if not check_db(db_uri):
@ -80,21 +79,21 @@ def create():
feed = \
feed_tpl%(
bld_date,
domain.web["www"] + domain.cf.get("TEMPLATE_FILENAMES", "rss"),
domain.conf["title"],
domain.web["www"],
domain.conf["about"],
domain.web["www"] + "template/" + domain.cf.get("TEMPLATE_FILENAMES", "logo"),
"%s (logo)"%(domain.conf["title"]),
domain.web["www"],
domain.lang,
domain.conf["tags"],
bld_date,
domain.cf.get("WEBSITE", "license"),
domain.conf["mail"],
feed_items
)
bld_date,
domain.web["www_rss"] + domain.cf.get("TEMPLATE_FILENAMES", "rss"),
domain.conf["title"],
domain.web["www"],
domain.conf["about"],
domain.web["www_logo"],
"%s (logo)"%(domain.conf["title"]),
domain.web["www"],
domain.lang,
domain.conf["tags"],
bld_date,
domain.cf.get("WEBSITE", "license"),
domain.conf["mail"],
feed_items
)
feed_uri = domain.www + domain.cf.get("TEMPLATE_FILENAMES", "rss")
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
# Settings files
#==============================#
# Settings register lang files #
#------------------------------#
def set_lang_files():
global lang_files, files_set
@ -46,7 +48,9 @@ def set_lang_files():
files_set = True
# Use logs from system language or default "en"
#===============================================#
# Use logs from system language or default "en" #
#-----------------------------------------------#
def load_logs():
global logs, logs_lang, logs_uri
@ -57,13 +61,18 @@ def load_logs():
except:
logs_lang = "en"
# To test other lang. Force set specific
#logs_lang = "en"
# Load language file
logs_name = lang_files["logs"]["name"]%logs_lang
logs_uri = lang_files["logs"]["uri"]%logs_lang
logs = __import__(logs_name)
# loan language website values
#==============================#
# load language website values #
#------------------------------#
def load_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">
<p id="header_title">%s</p>
<p id="header_about">%s</p>
</div<
</div>
</header>
</a>
"""

View File

@ -36,7 +36,7 @@ def manage():
domain.cf_update()
return
domain.is_ready()
domain.is_active()
if args.commands["modules"]["modules"]:
modules.manage("all")
return
@ -47,4 +47,4 @@ def manage():
args.commands["modules"]["sidebar"] and modules.manage("sidebar")
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 #
#--------------------------------------------------------#
def manage():
domain.is_ready()
domain.is_active()
global out
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.
# 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
#----------------------------------------------------------------------
#-------------------------
# Funny Stats Project
#-------------------------
# file lines :
# file comments :
# file functions:
# file program :
#--------------------------
import os
import domain, debug, wip
import args, domain, debug
#====================================#
# Manage arguments from command line #
# Specific to action "show" #
#------------------------------------#
def manage(action, target):
do = {
"domains" : all_domains,
"metas" : metas_post,
}
#================================#
# From args, show files contents #
#--------------------------------"
def manage():
domain.is_ready()
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 #
#----------------------------#
def all_domains():
domain.ult_dlf_load()
try:
c = 0
for key, value in domain.ult_dlf.items("DOMAINS"):
if key: c += 1
print(": %s > %s"%(key,value))
print("|\n; total =",c)
#=======================================#
# Read content of file #
# raw: False #
# - Filter line (commants, empty lines) #
#---------------------------------------#
def contents_file(uri, raw):
if not os.path.exists(uri):
debug.out(11, "!?", uri, True, 2, False)
return
except:
debug.out(104, "False", domain.ult_dlf_uri, True, 1, False)
print("; %s\n; %s\n; %s"%(78 * "=", uri, 78 * "="))
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)
#
#
#
#=========================#
# Copy files in template/ #
#-------------------------#
def copy_template_dir(process):
src_dirs = {
"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)
#====================================================#
# Sorte dict by length name #
# 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 #
#---------------------------#
def manage():
domain.is_ready()
domain.is_active()
# Multiple articles process
if args.commands["targets"]["all"]:
@ -554,11 +554,11 @@ def bquotes():
else: contents = "%s\n%s"%(contents, bq_line)
bquote = HTMLs["bquotes"]%(
css, bq_cite, bq_lang, bq_title,
html_time_o,
contents,
html_time_c,
html_footer
css, bq_cite, bq_lang, bq_title,
html_time_o,
contents,
html_time_c,
html_footer
)
replace_article(post.block_tags["bquotes"]["sources"][nbr][0], bquote)

View File

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

View File

@ -213,6 +213,7 @@ tyto [ACTION] [ARGUMENTS]
start > activer le domain actuel
stop > désactiver 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/"
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 = """
# Liste. Classe CSS possible (défaut : celle dans la configuration)
# Une entrée de liste peut être ordonnée avec le signe "+" ou non avec "="
# Une liste peut contenir des entrées mixées ("+" et "=")
# mais au changement de signe, ajouter un signe !
# Liste. %s
# Une entrée de liste peut être ordonnée (signe "+") ou non (signe "=")
# Une liste peut contenir des entrées mixées mais au changement de signe,
# ajouter un signe !
# Possible d'écrire une entrée sur plusieurs lignes
(=
@ -345,19 +348,19 @@ help_list = """
= Troisième entrée ...
... non ordonnée
)=
"""
"""%css_info
# --------- #
# Help cite #
# --------- #
help_cite = """
# Citation (bloc). Classe CSS possible (défaut : celle dans la configuration)
# Les métadonnées d'une citation sont toutes optionnelles.
# (Vous pouvez mettre que cite: et book:)
# Citation (bloc). %s
# Les métadonnées sont toutes optionnelles (vous pouvez utiliser que
# cite: et/our book: seulement)
("
cite: Auteur
date: AAAA-MM-JJ
date: AAAA-MM-JJ ou AAAA
book: Nom du livre
lang: fr
link: https://...
@ -366,7 +369,7 @@ help_cite = """
Citation complète dans un paragraphe
))
)"
"""
"""%css_info
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
@ -388,7 +391,7 @@ help_image_writer = """
# ! Une seule option termine par ","
::Image001
::Image001 "f=Une légende",
::Image001 "f=Légende de l'image",
"""
help_image = """
@ -428,7 +431,7 @@ help_link = """
)
# --------- #
# Help link #
# Help file #
# --------- #
help_file_header = """
file: ce fichier
@ -452,7 +455,6 @@ help_file = """
help_file_writer,
)
# --------- #
# Help Code #
# --------- #
@ -538,15 +540,14 @@ help_abbr = """
# --------- #
help_anc_header = """
# Définir une ancre
# ! Chaque ancre doit avoir une ID unique
# (et ne pas commencer par "toc_")
# ! Chaque ancre doit avoir une ID unique (et ne pas commencer par "toc_")
-> top
"""
help_anc_writer = """
# Lien vers une ancre définie
# format : >`ID: Message à afficher`<
# Format : >`ID: Message à afficher`<
>`top:Aller en haut`<
"""
@ -573,7 +574,7 @@ help_words = """
_`souligné`_ => <u>
~`effacé`~ => <del>
[`cité`] => <q> # Contenu
:`cité`: => <cite> # auteur, nom
:`cité`: => <cite> # Auteur, référence
|`perso`| => <span>
# Code dans un texte
@ -584,7 +585,12 @@ _`souligné`_ => <u>
# ! Dans certains cas, il faut ajouter un espace après le 1er marqueur
# 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
"-----" pour définir l'entête (les métadonnées), et le contenu
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)
# Début du fichier
# ----------------
# Ces 5 marqueurs sont obligatoires
# Ces 5 marqueurs sont obligatoires, chacun sur UNE LIGNE
# ----------
title: Titre <h1> de l'article
about: Description de l'article
tags: étiquette1,étiquette longue,étiquette3
date: AAAA-MM-JJ
authors: auteur1,auteur2
authors: Auteur1,auteur2
# Tous les marqueurs suivants sont optionnels
# ----------
@ -617,12 +623,12 @@ logo: URI
%s
%s%s%s%s%s%s
# URI
# - Commence par @ :
# - Commence par @
# - - le fichier est dans articles/images/ pour les marqueurs logo: et image:
# - - le fichier est dans articles/files/ pour les autres marqueurs
# - Commence par / :
# - Commence par /
# - - 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
# Marqueur pour NE PAS inclure l'article dans le sitemap
@ -642,15 +648,15 @@ logo: URI
#1 Titre 1
#2 Sous-titre 1
# Paragraphe. Classe CSS possible (défaut : celle dans la configuration)
# Paragraphe. %s
((
Un paragraphe
Un paragraphe...
(( 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
{{ PyCode
...
@ -667,13 +673,15 @@ logo: URI
%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>)
::Image001
|
::Image001 "c=Maclasse",
((
::Image001
|
::Image001 "c=Maclasse",
))
# Tirer un trait. Classe CSS possible (défaut : celle dans la configuration)
# Tirer un trait. %s
# La ligne contient juste "--" (<hr>)
--
%s
@ -689,6 +697,8 @@ logo: URI
help_raw_header,
help_abbr_header,
help_anc_header,
css_info,
css_info,
help_list,
help_cite,
help_image_writer,
@ -698,5 +708,7 @@ logo: URI
help_file_writer,
help_words,
help_abbr_writer,
css_info,
css_info,
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"