diff --git a/CHANGELOG.md b/CHANGELOG.md index 66e73bc..81672e3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,9 @@ Tyto - Littérateur - License: - Documentation: +## [1.9.6] +- Better management to create/update domain + ## [1.9.5] - Preparing post database diff --git a/README.md b/README.md index ac7fcac..3646fe3 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,6 @@ tyto ## ToDo next (working on) - check action -- user is in articles/ directory - target post exists and compatible - create template post database diff --git a/src/usr/bin/tyto b/src/usr/bin/tyto index c1cb731..004eafd 100755 --- a/src/usr/bin/tyto +++ b/src/usr/bin/tyto @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# Version: 1.9.5 -# Updated: 2023-09-25 1695637945 +# Version: 1.9.6 +# Updated: 2023-09-26 1695738690 # Tyto - Littérateur # Copyright (C) 2023 Cyrille Louarn diff --git a/src/var/lib/tyto/program/__pycache__/check.cpython-311.pyc b/src/var/lib/tyto/program/__pycache__/check.cpython-311.pyc index 5bb30de..8bd2865 100644 Binary files a/src/var/lib/tyto/program/__pycache__/check.cpython-311.pyc and b/src/var/lib/tyto/program/__pycache__/check.cpython-311.pyc differ diff --git a/src/var/lib/tyto/program/__pycache__/debug.cpython-311.pyc b/src/var/lib/tyto/program/__pycache__/debug.cpython-311.pyc index b9fb11d..28e7f8b 100644 Binary files a/src/var/lib/tyto/program/__pycache__/debug.cpython-311.pyc and b/src/var/lib/tyto/program/__pycache__/debug.cpython-311.pyc differ diff --git a/src/var/lib/tyto/program/__pycache__/domain.cpython-311.pyc b/src/var/lib/tyto/program/__pycache__/domain.cpython-311.pyc index 8215033..86a913d 100644 Binary files a/src/var/lib/tyto/program/__pycache__/domain.cpython-311.pyc and b/src/var/lib/tyto/program/__pycache__/domain.cpython-311.pyc differ diff --git a/src/var/lib/tyto/program/__pycache__/forms.cpython-311.pyc b/src/var/lib/tyto/program/__pycache__/forms.cpython-311.pyc index d8bafe2..7469883 100644 Binary files a/src/var/lib/tyto/program/__pycache__/forms.cpython-311.pyc and b/src/var/lib/tyto/program/__pycache__/forms.cpython-311.pyc differ diff --git a/src/var/lib/tyto/program/__pycache__/langs.cpython-311.pyc b/src/var/lib/tyto/program/__pycache__/langs.cpython-311.pyc index 00b7f8a..fa48364 100644 Binary files a/src/var/lib/tyto/program/__pycache__/langs.cpython-311.pyc and b/src/var/lib/tyto/program/__pycache__/langs.cpython-311.pyc differ diff --git a/src/var/lib/tyto/program/__pycache__/tools.cpython-311.pyc b/src/var/lib/tyto/program/__pycache__/tools.cpython-311.pyc index 853beec..3129a0b 100644 Binary files a/src/var/lib/tyto/program/__pycache__/tools.cpython-311.pyc and b/src/var/lib/tyto/program/__pycache__/tools.cpython-311.pyc differ diff --git a/src/var/lib/tyto/program/__pycache__/userset.cpython-311.pyc b/src/var/lib/tyto/program/__pycache__/userset.cpython-311.pyc index c09b1ea..f0eeefd 100644 Binary files a/src/var/lib/tyto/program/__pycache__/userset.cpython-311.pyc and b/src/var/lib/tyto/program/__pycache__/userset.cpython-311.pyc differ diff --git a/src/var/lib/tyto/program/check.py b/src/var/lib/tyto/program/check.py index c4a2e13..1909e19 100644 --- a/src/var/lib/tyto/program/check.py +++ b/src/var/lib/tyto/program/check.py @@ -33,7 +33,7 @@ #-------------------------- import sys -import domain, langs, debug, post +import domain, langs, debug, post, tools #===========================================# @@ -41,9 +41,10 @@ import domain, langs, debug, post # Domain must be valid to proceed # # Create user work domain directories # #-------------------------------------------# -def manage(action, target): +def manage(action, target): # Load domain configuration (update it if needed), check if valid domain.cf_valid() or debug.out(105, domain.name, domain.cf_uri, True, 1, True) target.endswith(".tyto") and post.is_article(target) langs.load_website_lang() + diff --git a/src/var/lib/tyto/program/debug.py b/src/var/lib/tyto/program/debug.py index 31ae03f..85c9e44 100644 --- a/src/var/lib/tyto/program/debug.py +++ b/src/var/lib/tyto/program/debug.py @@ -82,6 +82,7 @@ def out(nbr, var, val, show, color, stop): 6 : langs.logs.err_no_dir, 7 : langs.logs.err_cr_file, 8 : langs.logs.err_lang, + 9 : langs.logs.err_ini_file, 20 : langs.logs.err_bad_uri, 21 : langs.logs.err_post_sep, 22 : langs.logs.err_post_head, diff --git a/src/var/lib/tyto/program/domain.py b/src/var/lib/tyto/program/domain.py index 2209ef5..41892b5 100644 --- a/src/var/lib/tyto/program/domain.py +++ b/src/var/lib/tyto/program/domain.py @@ -73,7 +73,10 @@ def ult_cf_load(): ult_cf = False if not os.path.exists(ult_cf_uri): - debug.out(100, name, ult_cf_uri, True, 1, True) + tools.create_file(ult_cf_uri, tyto.ini_domain_user) + if os.path.exists(cf_uri): cf_update_values() + else: debug.out(100, name, ult_cf_uri, True, 1, True) + ult_cf = configparser.ConfigParser() ult_cf.read(ult_cf_uri) @@ -84,7 +87,11 @@ def ult_cf_load(): #-----------------------------------# def ult_dlf_load(): global ult_dlf - + + # User Domains list file + if not os.path.exists(ult_dlf_uri): + tools.create_file(ult_dlf_uri, tyto.ini_domains_list) + ult_dlf = False ult_dlf = configparser.ConfigParser() ult_dlf.read(ult_dlf_uri) @@ -156,36 +163,63 @@ def cf_create(): tools.create_file(ult_dlf_uri, tyto.ini_domains_list) # Ask user for domain settings - forms.ask_domain_title() - forms.ask_domain_date() - forms.ask_domain_about() - forms.ask_domain_mail() - forms.ask_domain_tags() + cf_load() + forms.ask_domain_title(True) + forms.ask_domain_date(True) + forms.ask_domain_about(True) + forms.ask_domain_mail(True) + forms.ask_domain_tags(True) # Set default lang, from config file or system lang - forms.ask_domain_lang() + forms.ask_domain_lang(True) # Set server directory - forms.ask_domain_server() - + forms.ask_domain_server(True) + # Update Domain Configuration file + cf_update_values() + + #===========================================# # Set or Update domain configuration values # +# Ask for some values if empty # +# Ensure to set correct values # #-------------------------------------------# -def cf_update_values(srv): +def cf_update_values(): # Prepare Domain Configuration File keys values #----------------------------------------------- cf_load() - # Test server directory, and exit if not exists - srv = srv or cf.get("SERVER", "root") # Set from db if unknown + # Server + srv = cf.get("SERVER", "root") or \ + cf.set("SERVER", "root", forms.ask_domain_server(False)) - # Test registred website lang - # change to default lang sys, or "en" if no translation file - # Load website lang file + # Title + cf.get("DOMAIN", "title") or \ + cf.set("DOMAIN", "title", forms.ask_domain_title(False)) + + # Date + cf.get("DOMAIN", "date") or \ + cf.set("DOMAIN", "date", forms.ask_domain_date(False)) + + # About + cf.get("DOMAIN", "about") or \ + cf.set("DOMAIN", "about", forms.ask_domain_about(False)) + + # mail + cf.get("DOMAIN", "mail") or \ + cf.set("DOMAIN", "mail", forms.ask_domain_mail(False)) + + # tags + cf.get("DOMAIN", "tags") or \ + cf.set("DOMAIN", "tags", forms.ask_domain_tags(False)) + + # Lang + cf.get("WEBSITE", "lang") or \ + cf.set("WEBSITE", "date", forms.ask_domain_lang(False)) langs.load_website_lang() - cf.set("WEBSITE", "lang", langs.site_lang) + # Set URIs from srv uri srv_dom = os.path.join(srv, name + "/") srv_wip = os.path.join(srv_dom, "wip/") srv_www = os.path.join(srv_dom, "www/") @@ -315,7 +349,7 @@ def cf_update_values(srv): cf.write(f) # Update User local domain configuration file - #-------------------------------------------- + #-------------------------------------------- ult_cf_load() ult_cf.set("DOMAIN", "name", name) ult_cf.set("DOMAIN", "hash", tools.get_filesum(cf_uri, True)) @@ -343,40 +377,26 @@ def cf_update_values(srv): def cf_valid(): global active + # Check some values in ult_cf cf_load() - # - cf name must be config_name + ult_cf_load() + + if not tools.compare_ini_ft(cf_uri, tyto.ini_domain): + return + + # - domain name must be cf_name try: cf_name = cf.get("DOMAIN", "name") except: debug.out(100, name, cf_uri, True, 2, True) - if cf_name != name: - debug.out(100, name, cf_uri, True, 2, True) + cf_update_values() - # - root server must exists - try: cf_srv = cf.get("SERVER", "root") - except: debug.out(100, "SERVER root", "?", True, 2, True) - if not cf_srv or not tools.dir_exists(cf_srv, True): - debug.out(100, "SERVER root", "? %s"%cf_srv, True, 2, True) - - # Check some values in ult_cf - ult_cf_load() - try: - ult_cf_name = ult_cf.get("DOMAIN", "name") - ult_cf_hash = ult_cf.get("DOMAIN", "hash") - ult_cf_conf = ult_cf.get("DOMAIN", "conf") - ult_cf_root = ult_cf.get("DOMAIN", "root") - except: - debug.out(100, name, ult_cf_uri, True, 1, True) - - # Compare values (exit if mismatch) - if ult_cf_name != name or \ - ult_cf_conf != cf_uri or \ - cf_name != ult_cf_name: - debug.out(100, name, "?", True, 1, True) + try: ult_cf_hash = ult_cf.get("DOMAIN", "hash") + except: cf_update_values() # Check if cf need to be updated now_cf_hash = tools.get_filesum(cf_uri, True) if now_cf_hash != ult_cf_hash: - cf_update_values("") + cf_update_values() active = is_active() active and create_work_dirs() diff --git a/src/var/lib/tyto/program/forms.py b/src/var/lib/tyto/program/forms.py index 7a3e641..57f10eb 100644 --- a/src/var/lib/tyto/program/forms.py +++ b/src/var/lib/tyto/program/forms.py @@ -78,7 +78,7 @@ def ask(q, yes_only, default): #====================================# # Shorter value to show in questions # -# return value[0:12] +# return value[0:12] # #------------------------------------# def shorter(value): if len(value) > 12: @@ -95,29 +95,46 @@ def shorter(value): 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 # -#----------------------# -def ask_domain_title(): - domain.cf_load() - title = domain.cf.get("DOMAIN", "title") +#=======================# +# Getting domain Title # +# update # +# - True: domain file # +# - False: return value # +#-----------------------# +def ask_domain_title(update): + try: title = domain.cf.get("DOMAIN", "title") + except: title = "" + """ + if update: + domain.cf_load() + title = domain.cf.get("DOMAIN", "title") + """ + q = "> %s (%s)%s "%(langs.logs.domain_title, shorter(title), langs.logs.q) answer = ask(q, False, title) - if answer != title: - tools.update_ini_file(domain.cf_uri, "DOMAIN", "title", answer) + + 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(): - domain.cf_load() - date = domain.cf.get("DOMAIN", "date") +def ask_domain_date(update): + try: date = domain.cf.get("DOMAIN", "date") + except: date = "YYYY[-MM-DD]" + """ + if update: + domain.cf_load() + date = domain.cf.get("DOMAIN", "date") + """ example = date or "YYYY[-MM-DD]" q = "> %s (%s)%s "%(langs.logs.domain_date, example, langs.logs.q) @@ -140,65 +157,99 @@ def ask_domain_date(): if not test: debug.out(50, "YYYY[-MM-DD]", answer, True, 2, True) - if answer != date: - tools.update_ini_file(domain.cf_uri, "DOMAIN", "date", answer) + 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(): - domain.cf_load() - about = domain.cf.get("DOMAIN", "about") +def ask_domain_about(update): + try: about = domain.cf.get("DOMAIN", "about") + except: about = "" + """ + if update: + domain.cf_load() + about = domain.cf.get("DOMAIN", "about") + """ + q = "> %s (%s)%s "%(langs.logs.domain_about, shorter(about), langs.logs.q) answer = ask(q, False, about) - if answer != about: - tools.update_ini_file(domain.cf_uri, "DOMAIN", "about", answer) + + 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(): - domain.cf_load() - mail = domain.cf.get("DOMAIN", "mail") - +def ask_domain_mail(update): + try: mail = domain.cf.get("DOMAIN", "mail") + except: mail = "" + """ + if update: + domain.cf_load() + mail = domain.cf.get("DOMAIN", "mail") + """ + q = "> %s (%s)%s "%(langs.logs.domain_mail, shorter(mail), langs.logs.q) answer = ask(q, False, mail) - if answer != mail: - tools.update_ini_file(domain.cf_uri, "DOMAIN", "mail", answer) + + 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(): - domain.cf_load() - tags = domain.cf.get("DOMAIN", "tags") +def ask_domain_tags(update): + try: tags = domain.cf.get("DOMAIN", "tags") + except: tags = "" + """ + if update: + domain.cf_load() + tags = domain.cf.get("DOMAIN", "tags") + """ q = "> %s (%s)%s "%(langs.logs.domain_tags, shorter(tags), langs.logs.q) answer = ask(q, False, tags) - if answer != 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 + "," + # 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 + "," - tools.update_ini_file(domain.cf_uri, "DOMAIN", "tags", 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(): - langs.get_website_lang() - lang = langs.site_lang +def ask_domain_lang(update): + try: + lang = domain.cf.get("WEBSITE", "lang") or langs.get_sys_lang() + except: + lang = "" + """ + if update: + domain.cf_load() + lang = domain.cf.get("WEBSITE", "lang") + """ q = "> %s (%s)%s "%(langs.logs.domain_lang, lang, langs.logs.q) answer = ask(q, False, lang).lower() @@ -211,19 +262,28 @@ def ask_domain_lang(): # Check if translation file exists if not langs.translation_exists("website", answer, False): - debug.out(103, "en", "%swebsite_en.py"%langs.trfs, True, 1, False) + lang = lang.get_sys_lang() + debug.out(103, lang, "%swebsite_%s.py"%(langs.trfs, lang), True, 1, False) answer = lang - if answer != lang: - tools.update_ini_file(domain.cf_uri, "WEBSITE", "lang", answer) + if update: tools.update_ini_file(domain.cf_uri, "WEBSITE", "lang", answer) + else: return lang #===================================# # Get domain server root # #-----------------------------------# -def ask_domain_server(): - domain.cf_load() - srv = domain.cf.get("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 update: + domain.cf_load() + srv = domain.cf.get("SERVER", "root") + """ if srv and not tools.dir_exists(srv, False): srv = "" @@ -233,9 +293,10 @@ def ask_domain_server(): # Check if directory exists if not tools.dir_exists(answer, False): - answer = srv - ask_domain_server() + answer = "" + ask_domain_server(update) return - domain.cf_update_values(answer) + if update: tools.update_ini_file(domain.cf_uri, "SERVER", "root", answer) + else: return srv diff --git a/src/var/lib/tyto/program/langs.py b/src/var/lib/tyto/program/langs.py index a336f1a..77054bc 100644 --- a/src/var/lib/tyto/program/langs.py +++ b/src/var/lib/tyto/program/langs.py @@ -56,7 +56,7 @@ def translation_exists(module, lang, out): tr_file = "%s%s_%s.py"%(trfs, module, lang) if not os.path.exists(tr_file): - debug.out(5, lang, tr_file, True, 2, out) + debug.out(5, lang, tr_file, True, 2, False) return False return True @@ -126,10 +126,11 @@ def get_website_lang(): #----------------------------------# def load_website_lang(): global site, site_lang, set_site + + site = __import__("website_%s"%get_website_lang()) try: set_site except: - site = __import__("website_%s"%get_website_lang()) debug.out(208, site_lang, tr_website_uri, False, 0, False) set_site = True diff --git a/src/var/lib/tyto/program/tools.py b/src/var/lib/tyto/program/tools.py index 429cf5d..b3ac765 100644 --- a/src/var/lib/tyto/program/tools.py +++ b/src/var/lib/tyto/program/tools.py @@ -33,8 +33,41 @@ #-------------------------- from hashlib import blake2b -import os, configparser -import debug +import os, configparser, datetime, time +import debug, domain + + +#==============================# +# Set and return date and time # +# With local options from lang # +#------------------------------# +def nowdate(spec): + # Default + F_Int = "'%Y-%m-%d %I:%M:%S %p'" # Full International date + S_Int = "'%Y-%m-%d" # Short International date + + # Get spec option for local date + # Get Used domain lang and set format date + locales = ("FLocal", "SLocal") + if spec in locales: + domain.cf_load() + lang = domain.cf.get("WEBSITE", "lang") + if lang == "fr": + S_Int = "'%d/%m/%Y'" + F_Int = "'%d/%m/%Y %H:%M:%S'" + + + now = datetime.datetime.now() + setdate = { + "FInt" : now.strftime(F_Int), + "SInt" : now.strftime(S_Int), + "FLocal" : now.strftime(F_Int), + "SLocal" : now.strftime(S_Int), + "Year" : now.strftime('%Y'), + "Epoch" : int(now.timestamp()), + } + + return setdate[spec] #========================# @@ -115,3 +148,26 @@ def update_ini_file(file_path, section, key, val): config.set(section, key, val) with open(file_path, "w") as f: config.write(f) + + +#==================================================# +# Compare database file with origin file template # +# Used for domain and article configuration file # +# Return True, if ini keys are same # +#--------------------------------------------------# +def compare_ini_ft(cf_uri, template): + with open(cf_uri, "r") as f: + ln = 0 + lines = f.read() + lines = lines.rsplit("\n") + + for key_t in template.rsplit("\n"): + ln += 1 + key_t = key_t.rsplit("=")[0] + key_f = lines[ln -1].rsplit("=")[0] + + if not key_t == key_f: + debug.out(9, "l=%s: %s != %s"%(ln, key_f, key_t), cf_uri, False, 2, False) + return False + + return True diff --git a/src/var/lib/tyto/program/userset.py b/src/var/lib/tyto/program/userset.py index 09eee8c..d752dd7 100644 --- a/src/var/lib/tyto/program/userset.py +++ b/src/var/lib/tyto/program/userset.py @@ -41,6 +41,7 @@ import langs, forms, domain #------------------------------------# def manage(action, target): if action == "set": + domain.cf_load() do = { "title" : forms.ask_domain_title, "date" : forms.ask_domain_date, @@ -50,9 +51,8 @@ def manage(action, target): "server" : forms.ask_domain_server, } - do[target]() - elif action in ("start", "stop") \ - and target == "domain": + do[target](True) + elif action in ("start", "stop") and target == "domain": domain.userset_status(action) diff --git a/src/var/lib/tyto/translations/__pycache__/logs_fr.cpython-311.pyc b/src/var/lib/tyto/translations/__pycache__/logs_fr.cpython-311.pyc index 2332974..1ba5efa 100644 Binary files a/src/var/lib/tyto/translations/__pycache__/logs_fr.cpython-311.pyc and b/src/var/lib/tyto/translations/__pycache__/logs_fr.cpython-311.pyc differ diff --git a/src/var/lib/tyto/translations/__pycache__/website_en.cpython-311.pyc b/src/var/lib/tyto/translations/__pycache__/website_en.cpython-311.pyc new file mode 100644 index 0000000..fa9c125 Binary files /dev/null and b/src/var/lib/tyto/translations/__pycache__/website_en.cpython-311.pyc differ diff --git a/src/var/lib/tyto/translations/logs_fr.py b/src/var/lib/tyto/translations/logs_fr.py index 2af3159..a75af9e 100644 --- a/src/var/lib/tyto/translations/logs_fr.py +++ b/src/var/lib/tyto/translations/logs_fr.py @@ -60,6 +60,7 @@ err_bad_uri = "URI non compatible" err_post_sep = "Séparateur manquant" err_post_head = "Erreur dans l'Entête" err_post_empty = "Article vide" +err_ini_file = "Configuration invalide" # Warnings warn_no_dom = "Domaine non configuré"