diff --git a/CHANGELOG.md b/CHANGELOG.md index 75c6ac6..54e5f86 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,16 +1,10 @@ # Changelog Tyto - Littérateur -- Repository: https://git.a-lec.org/echolib/tyto -- Issues: https://git.a-lec.org/echolib/tyto/-/issues -- Changelog: https://git.a-lec.org/echolib/tyto/-/blob/main/CHANGELOG.md -- License: https://git.a-lec.org/echolib/tyto/-/blob/main/LICENSE - -Tyto - Litterateur is a Libre project to create and manage multiple -websites from articles' files. Tyto uses its own syntax to convert -your articles in HTML5 static pages. Tyto works on a GNU/Linux system -and needs minimal dependancies. -- python3 rsync nano gawk curl - -## [0.9.0] First Commit version (pre-final) +- Repository: https://git.a-lec.org/echolib/tyto-litterateur +- Issues: https://git.a-lec.org/echolib/tyto-litterateur/-/issues +- Changelog: https://git.a-lec.org/echolib/tyto-litterateur/-/blob/master/CHANGELOG.md +- License: https://git.a-lec.org/echolib/tyto-litterateur/-/blob/master/LICENSE +## [0.9.0] +- Last testings before final diff --git a/debian/control b/debian/control index c38bd5b..962e249 100644 --- a/debian/control +++ b/debian/control @@ -1,10 +1,10 @@ Package: tyto -Version: 0.1.0 +Version: 0.9.0 Section: custom Priority: optional Architecture: all Essential: no -Depends: rsync,nano,gawk,curl +Depends: nano,python3 Installed-Size: `du -ks .|cut -f 1` Maintainer: echolib -Description: Tyto - Litterateur is a libre project to create and manage multiple websites from articles' files. Tyto uses its own syntax to convert your articles in HTML5 static pages. Tyto works on a GNU/Linux system and needs minimal dependencies. \ No newline at end of file +Description: Tyto - Litterateur is a libre project to create and manage multiple websites from articles files. Tyto uses its own syntax to convert your articles in HTML5 pages. Tyto works on a GNU/Linux system and needs minimal dependencies. diff --git a/src/usr/bin/tyto b/src/usr/bin/tyto index c222220..1824ec3 100755 --- a/src/usr/bin/tyto +++ b/src/usr/bin/tyto @@ -1,4 +1,5 @@ #!/usr/bin/env python3 +# Version: 0.9.0 # Tyto - Littérateur # # Copyright (C) 2023 Cyrille Louarn diff --git a/src/var/lib/tyto/help/styles.css b/src/var/lib/tyto/help/styles.css index 21ecc2f..31ccc5c 100644 --- a/src/var/lib/tyto/help/styles.css +++ b/src/var/lib/tyto/help/styles.css @@ -117,22 +117,18 @@ code.DOMAIN { } pre.bcode { } -div.bcode { +p.bcode { } /* section for author and date */ section#article_infos { } - span#article_author { } - span#article_pub { } - span#article_code { } - a#article_code_link { } @@ -140,6 +136,49 @@ a#article_code_link { * sidebar */ +aside#sidebar { +} +h1#sidebar_title { +} +ul#sidebar_list { +} +li.sidebar_item { +} +a.sidebar_item_link { +} +h2.sidebar_item_title { +} +p.sidebar_item_about { +} + + /* * footer */ +footer#footer_page { +} +/* Block*/ +div#footer_infos { +} +h1#footer_site_title { +} +p#footer_about { +} +/* Block */ +div#footer_references { +} +ul.footer_items { +} +li.footer_item { +} +a.footer_item_link { +} +/* Block */ +div#footer_credits { +} +p.footer_copyright { +} +p.footer_generator { +} + + diff --git a/src/var/lib/tyto/program/args.py b/src/var/lib/tyto/program/args.py index aeed9b4..102b140 100644 --- a/src/var/lib/tyto/program/args.py +++ b/src/var/lib/tyto/program/args.py @@ -79,6 +79,7 @@ pass_db = \ 'show-db', 'show-wip', 'show-www', +'status', 'wip', ) @@ -96,6 +97,11 @@ pass_targets = \ 'template' ) +pass_status = \ +( +'domain', +) + multi_chk = ('added', 'again', 'updated') action = '' diff --git a/src/var/lib/tyto/program/check.py b/src/var/lib/tyto/program/check.py index 09cccd7..8ce9dac 100644 --- a/src/var/lib/tyto/program/check.py +++ b/src/var/lib/tyto/program/check.py @@ -38,7 +38,7 @@ import time, importlib, sys, os, re, datetime from datetime import datetime from time import gmtime, strftime -import args, dom, logs, status, db, form, tyto, langs +import args, dom, logs, status, db, form, tyto, langs, wip domain_dir = post_err = multi_chk = False @@ -69,7 +69,7 @@ def manage(target): # Already check elif db.exists and not db.old_chk: - print(' ├─ [%s] > %s'%(db.title, db.uri_file)) + print(' ├ [%s] > %s'%(db.title, db.uri_file)) logs.out("20", '%s > %s'%(db.date_chk, db.uri_file), False) answer = form.asking(' ├ %s%s '%( langs.site.check_a, langs.site.q @@ -151,8 +151,8 @@ def check_all(option): except: continue - if option == 'updated' and not db.old_chk: - continue + if option == 'updated' and not db.chk_updated: continue + if option == 'again' and not db.chk_again: continue found = True check_process(args.target) @@ -196,7 +196,7 @@ def check_process(target): srv_post_www_uri = dom.srv_www + srv_post_short_uri direc_src = src_post_short_uri.split("/")[-1] direc_src = src_post_short_uri.rsplit(direc_src)[0] - + # Get sub_uri for HTML global sub_uri sub_uri = db.uri_file.rsplit('articles/')[1] @@ -235,11 +235,18 @@ def check_process(target): # Check header tags configurations check_needed_tags(post_header.rsplit('\n')) - check_opt_tags(post_header.rsplit('\n')) - #print("In Dev: return from process...") - if post_err: return + if post_err: + if db.exists and tyto.exists(db.config): + os.remove(db.config) + return + print(' │\n ├ [%s] > %s'%(title, db.uri_file)) + + check_opt_tags(post_header.rsplit('\n')) + if post_err: + if db.exists and tyto.exists(db.config): + os.remove(db.config) + return - print(' │\n ├─ [%s] > %s'%(title, db.uri_file)) # Check for valid contents check_content(post_bottom) @@ -271,8 +278,9 @@ def file_to_string(): for line in article.rsplit('\n'): if line.startswith('-----'): - sep = True - continue + if not sep: + sep = True + continue if sep: if line: content = True @@ -410,7 +418,7 @@ def check_needed_tags(post_header): # Set data from tag if line.startswith('%s:'%tag): globals()[tag] = line.rsplit('%s:'%tag)[1].lstrip() - globals()[tag] = globals()[tag].replace('"', '') + globals()[tag] = tyto.convert_altname(globals()[tag]) # Stat for "tags:" if tag == 'tags': stat_tags = len(globals()[tag].strip().split(",")) @@ -420,6 +428,8 @@ def check_needed_tags(post_header): if not globals()[tag]: logs.out("38", '%s:'%tag, False) post_err = True + + # Check date format # Set french format in post DB @@ -495,6 +505,27 @@ def check_opt_tags(post_header): check_3lines(tag, ln, line) +#===================================# +# Check if registred value is valid # +#-----------------------------------# +def valid_data_name(tag, name): + global post_err + data_inv = '' + data_err = False + + for c in name: + if c in tyto.chrs_invalid: + post_err = True + data_err = True + data_inv = '%s%s'%(data_inv, str(c)) + + if data_err: + logs.out("3", '"%s: %s" > %s'%(tag, name, data_inv), False) + return False + + return True + + #============================================# # Do stats, check 3 lines tags from ln # # Set data for each 2 next lines # @@ -519,7 +550,8 @@ def check_3lines(tag, ln, line): name = line.rsplit('%s:'%tag)[1].lstrip() else: name = line.rsplit('%s:'%tag)[1].lstrip().rsplit(' ')[0] - + if not valid_data_name(tag, name): return + if not name: logs.out("2", 'L=%s. "%s: %s" > %s'%( @@ -576,6 +608,10 @@ def check_3lines(tag, ln, line): ), False) post_err = True + # Convert special characters for HTML + if not tag in tyto.opt_tags_check_uri: + data = tyto.convert_altname(data) + # For tags having URI, check if file exists # Set data for post DB if l == 1 and tag in tyto.opt_tags_check_uri: diff --git a/src/var/lib/tyto/program/db.py b/src/var/lib/tyto/program/db.py index 7cbf754..5cac1b1 100644 --- a/src/var/lib/tyto/program/db.py +++ b/src/var/lib/tyto/program/db.py @@ -36,7 +36,10 @@ import os import args, logs, dom, form, tyto, check, publish -remove = exists = post = corrupt = False +remove = exists = post = corrupt = file_wip = file_www = False +chk_again = chk_updated = False +wip_again = wip_added = wip_updated = False +www_again = www_added = www_updated = False if dom.hole: logs.out("13", '', True) @@ -59,7 +62,10 @@ if args.target \ config = '%s%s.config'%(dom.articles_db_d, uri_id) if tyto.exists(config): exists = True - exec(open(config).read()) + try: + exec(open(config).read()) + except: + exists = False else: exists = False @@ -129,6 +135,7 @@ if args.target \ 'codes', ) + # Set exist for wip and www files for value in values: try: eval(str(value)) @@ -143,7 +150,6 @@ if args.target \ exists = False logs.out("23", config, False) - file_wip = file_www = False old_chk = old_wip = old_www = False no_chk = no_wip = no_www = False sync_srvs = False @@ -154,19 +160,34 @@ if args.target \ if tyto.exists(post_wip): file_wip = True if tyto.exists(post_www): file_www = True - # Source article has changed - if hash_post != hash_chk: old_chk = True - - # WIP article is old - if hash_chk != hash_wip: old_wip = True - - # WWW article is old - if hash_wip != hash_www: old_www = True - # Statuses not set in Db if not hash_chk: no_chk = True if not hash_wip: no_wip = True if not hash_www: no_www = True + # Source article has changed + if hash_post != hash_chk: old_chk = chk_updated = True + if hash_chk: chk_again = True + + # WIP article is old + if not old_chk: + if hash_wip and hash_chk != hash_wip: old_wip = wip_updated = True + if no_wip: wip_added = True + if hash_wip: wip_again = True + if not file_wip: + old_wip = wip_updated = True + wip_added = True + wip_again = True + + # WWW article is old + if not old_wip: + if hash_www and hash_www != hash_wip: old_www = www_updated = True + if hash_www: www_again = True + if no_www: www_added = True + if not file_www: + old_www = www_updated = True + www_added = True + www_again = True + # Article is updated on both servers if hash_chk == hash_wip == hash_www: sync_srvs = True diff --git a/src/var/lib/tyto/program/form.py b/src/var/lib/tyto/program/form.py index 809fc56..6316e1d 100644 --- a/src/var/lib/tyto/program/form.py +++ b/src/var/lib/tyto/program/form.py @@ -36,7 +36,7 @@ #********************************************************************** from datetime import datetime -import os, sys, re, locale, importlib +import os, sys, shutil, re, locale, importlib import logs, dom, tyto, html, show, langs # locale translation directory @@ -184,12 +184,13 @@ def create_domain(target): # Start registering variables in domain database #----------------------------------------------- local_user = '%s/.local/tyto/%s/'%(dom.home_dir, shortname) - modules_dir = '%s/articles/_configs/'%dom.folder + modules_dir = '%sarticles/_configs/'%dom.root_dir footer_about_f = '%sfooter_about.html'%modules_dir + config_bkp = '%sdomain_config.bkp'%local_user set_f = \ '# Home Domain\n' + \ - 'directory = "%s/"\n'%dom.folder + \ + 'directory = "%s"\n'%dom.root_dir + \ 'database = "%s"\n'%dom.config + \ '\n# Local user configuration\n' + \ 'lang_sys = "%s"\n'%lang_sys + \ @@ -197,9 +198,9 @@ def create_domain(target): 'lang_logs = "%s"\n'%lang_logs + \ 'articles_db_d = "%sarticles/"\n'%local_user + \ '\n# Working directories\n' + \ - 'articles_d = "%s/articles/"\n'%dom.folder + \ - 'files_d = "%s/articles/files/"\n'%dom.folder + \ - 'images_d = "%s/articles/images/"\n'%dom.folder + \ + 'articles_d = "%sarticles/"\n'%dom.root_dir + \ + 'files_d = "%sarticles/files/"\n'%dom.root_dir + \ + 'images_d = "%sarticles/images/"\n'%dom.root_dir + \ 'modules_d = "%s"\n'%modules_dir + \ '\n# Modules files\n' + \ 'navbar_f = "%styto.navbar"\n'%modules_dir + \ @@ -336,7 +337,7 @@ def create_domain(target): if answer: title = answer if not title: invalid = True - elif '"' in title: title = title.replace('"', '') + else: title = tyto.convert_altname(title) set_f = 'title = "%s"'%title tyto.set_file(dom.config, False, set_f) @@ -368,7 +369,7 @@ def create_domain(target): if answer: about = answer if not about: invalid = True - elif '"' in about: about = about.replace('"', '') + else: about = tyto.convert_altname(about) set_f = 'about = "%s"'%about tyto.set_file(dom.config, False, set_f) @@ -595,7 +596,8 @@ def create_domain(target): if not sdb_title: sdb_title = '' invalid = True - elif '"' in sdb_title: sdb_title = sdb_title.replace('"', '') + else: + sdb_title = tyto.convert_altname(sdb_title) set_f = 'sidebar_title = "%s"'%sdb_title tyto.set_file(dom.config, False, set_f) @@ -648,7 +650,8 @@ def create_domain(target): # Activate Domain #---------------- tyto.set_file(dom.config, False, '\nactivated = True') - + shutil.copy2(dom.config, config_bkp) + logs.out("32", config_bkp, False) # RELoad config #-------------- @@ -902,7 +905,7 @@ def create_footer(option): Tytosrc = \ '\n%s(%s)'%(9 * ' ', langs.site.source_code) + '%sclass="footer_item_link">%s)'%(9 * ' ', langs.site.source_code) tyto_show = \ '%s%s'%(9 * ' ', dom.title) + '%sclass="footer_title_link">%s'%(9 * ' ', dom.title) # Insert content of footer_about_f or default if not exists footer_about = '' @@ -1034,10 +1037,12 @@ def create_footer(option): ' \n' + \ ' \n' + \ ' \n' + \ diff --git a/src/var/lib/tyto/program/html.py b/src/var/lib/tyto/program/html.py index 020ad85..5c5c46a 100644 --- a/src/var/lib/tyto/program/html.py +++ b/src/var/lib/tyto/program/html.py @@ -254,14 +254,15 @@ def create_user_metas(option): if option == 'wip': target = dom.wip_metas_f elif option in pub_opts: target = dom.www_metas_f - # Create wip metas.html file according to option - #----------------------------------------------- if option == 'www' and tyto.exists(target): form.asking(' ├ %s. %s%s '%( langs.site.metas, langs.site.form_rep, langs.site.q ), True) + + print(' │\n ├ %s'%langs.site.metas_inf) - + # Create wip metas.html file according to option + #----------------------------------------------- try: user_file = open(dom.metas_f, 'r').read() except: logs.out("1", dom.metas_f, True) @@ -290,6 +291,14 @@ def create_navbar(option): if option == 'wip': target = dom.wip_navbar_f elif option in pub_opts: target = dom.www_navbar_f + if option == 'www' and tyto.exists(target): + form.asking(' ├ %s. %s(%s)%s '%( + langs.site.navbar, langs.site.form_rep, + option, langs.site.q + ), True) + + print(' │\n ├ %s'%langs.site.navbar_inf) + # navbar has items navbar_items = False @@ -374,14 +383,6 @@ def create_navbar(option): # Create ending HTML file else: menu_html = '\n%s\n%s\n%s\n'%(menu_html, 8 * ' ', 6 * ' ') - - # Ask to replace only for www - if option == 'www': - form.asking(' ├ %s. %s(%s)%s '%( - langs.site.navbar, langs.site.form_rep, - option, langs.site.q - ), True) - tyto.set_file(target, 'New', menu_html) @@ -391,7 +392,7 @@ def create_navbar(option): #----------------------------------------------# def create_sidebar(option): dom.valid() - + if not tyto.exists(dom.sidebar_f): logs.out("1", dom.sidebar_f, True) @@ -400,6 +401,13 @@ def create_sidebar(option): if option == 'wip': target = dom.wip_sidebar_f elif option in pub_opts: target = dom.www_sidebar_f + if option == 'www' and tyto.exists(target): + form.asking(' ├ %s. %s%s '%( + langs.site.sidebar, langs.site.form_rep, langs.site.q + ), True) + + print(' │\n ├ %s'%langs.site.sidebar_inf) + sidebar_items = False # Set HTML sidebar @@ -435,7 +443,6 @@ def create_sidebar(option): if not tyto.exists(db_uri): logs.out('25', line, False) continue - # Load article"s database exec(open(db_uri).read(),globals()) @@ -494,13 +501,6 @@ def create_sidebar(option): sidebar_content = '' for line in sidebar_temp.rsplit('\n'): sidebar_content = sidebar_content + '%s%s\n'%(4 * ' ', line) - - # Ask to replace only for www - if option == 'www': - form.asking(' ├ %s. %s(%s)%s '%( - langs.site.sidebar, langs.site.form_rep, - option, langs.site.q - ), True) tyto.set_file(target, True, sidebar_content) @@ -519,6 +519,8 @@ def create_user_footer(option): langs.site.footer, langs.site.form_rep, langs.site.q ), True) + print(' │\n ├ %s'%langs.site.footer_inf) + try: footer_f = open(dom.footer_f, 'r').read() except: logs.out("1", dom.footer_f, True) diff --git a/src/var/lib/tyto/program/infos.py b/src/var/lib/tyto/program/infos.py index 5b97aa0..976614b 100644 --- a/src/var/lib/tyto/program/infos.py +++ b/src/var/lib/tyto/program/infos.py @@ -33,7 +33,15 @@ #********************************************************************** -import os, langs +import os, importlib +import langs +importlib.reload(langs) + +# Set colors +CS = '\033[0;0m' +CR = '\033[1;31m' +CY = '\033[1;33m' +CG = '\033[1;32m' def tyto(target): noinfos = False @@ -48,19 +56,46 @@ def tyto(target): # Show domains list try: - db_domains = '%s/.local/tyto'%os.path.expanduser('~') + has_domains = True user = os.environ.get('USER') - hashdomain = False - print('# Registred domains for', user) - for folder in os.listdir(db_domains): - if os.path.isdir('%s/%s'%(db_domains, folder)): - if hashdomain: - hasdomain = False - hashdomain = True - print(' -', folder) + user_dir = os.path.expanduser('~') + db_domains = '%s/.local/tyto'%user_dir except: - noinfo = True - print(':< No .../.local/tyto') + has_domains = False - print(':', langs.site.args_helps) + if not os.path.exists(db_domains): + has_domains = False + print('! No directory > %s/'%db_domains) + + if has_domains: + list_domains = (()) + for folder in os.listdir(db_domains): + domain_local_uri = '%s/%s'%(db_domains, folder) + if os.path.isdir(domain_local_uri): + domain_conf = '%s/domain_config.bkp'%domain_local_uri + if os.path.exists(domain_conf): + try: + exec(open(domain_conf).read(),globals()) + except: + continue + if os.path.exists(directory): + dir_domain = '%s%s%s'%(CG, directory, CS) + else: + dir_domain = '%s%s%s'%(CR, directory, CS) + list_domains = \ + (('%s > %s > %s'%(folder, dir_domain, www_url)),) + + if list_domains: + print('# %s %ss %s'%( + langs.site.reg_domains, + langs.site.fo, + user + ) + ) + for domain in list_domains: + print(' - %s'%domain) + + + # Show arguments help + print(langs.site.args_helps) diff --git a/src/var/lib/tyto/program/langs.py b/src/var/lib/tyto/program/langs.py index 200cbde..2fc4ffa 100644 --- a/src/var/lib/tyto/program/langs.py +++ b/src/var/lib/tyto/program/langs.py @@ -59,11 +59,7 @@ try: log = importlib.import_module('logs_%s'%lang_logse, package=None) except: log = importlib.import_module('logs_%s'%lang_sys, package=None) -''' - exec(open('%s/logs_%s.py'%(trans_dir, lang.logs)).read()) -except: - exec(open('%s/logs_%s.py'%(trans_dir, lang_sys)).read()) -''' + # Set language site/form from configuration domain # or set default english if not known diff --git a/src/var/lib/tyto/program/logs.py b/src/var/lib/tyto/program/logs.py index 5e041fe..c23549b 100644 --- a/src/var/lib/tyto/program/logs.py +++ b/src/var/lib/tyto/program/logs.py @@ -96,6 +96,16 @@ def out(nbr, value, out): '51' : ' ╞ %s%s%s > %s'%(CY, langs.log.data_inc, CS, value), '60' : ' │\n ╞ %s'%langs.log.status_r, '61' : ' ╞ %s%s%s > %s'%(CG, langs.log.file_e, CS, value), + '71' : ' ╞═ %s%s%s > %s'%(CY, langs.log.post_nwi, CS, value), + '72' : ' ╞═ %s%s%s > %s'%(CG, langs.log.post_wip, CS, value), + '73' : ' ╞═ %s%s%s > %s'%(CY, langs.log.st_wip_n, CS, value), + '74' : ' ╞═ %s%s%s > %s'%(CY, langs.log.st_wip_o, CS, value), + '81' : ' ╞═ %s%s%s > %s'%(CY, langs.log.post_nww, CS, value), + '82' : ' ╞═ %s%s%s > %s'%(CG, langs.log.post_www, CS, value), + '83' : ' ╞═ %s%s%s > %s'%(CY, langs.log.st_www_n, CS, value), + '84' : ' ╞═ %s%s%s > %s'%(CY, langs.log.st_www_o, CS, value), + '85' : ' ╞═ %s%s%s > %s'%(CY, langs.log.was_pub, CS, value), + '94' : ' ╞═ %s%s%s > %s'%(CY, langs.log.st_chk_o, CS, value), '255' : ' ╘ %s'%langs.log.laterout } diff --git a/src/var/lib/tyto/program/publish.py b/src/var/lib/tyto/program/publish.py index ba3db2d..8cd3bf1 100644 --- a/src/var/lib/tyto/program/publish.py +++ b/src/var/lib/tyto/program/publish.py @@ -71,16 +71,95 @@ def manage_publish(target): # Publish in www server an article check_to_publish('one') + + # Article already published + if db.file_www: + logs.out("85", '%s > %s'%(db.date_chk, db.uri_file), False) + answer = form.asking(' ├ %s%s '%( + langs.site.publish_a, langs.site.q + ), True) + + # Publish publish_article() # Create new ATOM/RSS file rss.create_feed() +#============================================# +# Option 'all' to publish again, based on DB # +#--------------------------------------------# +def publish_all(option): + tyto.show_multi_message('www', dom.srv_www) + form.asking(' ├ %s%s '%(langs.site.proceed, langs.site.q), True) + + # Sort by newer articles (created by last check) + db_articles = sorted(Path(dom.articles_db_d).iterdir(), + key=os.path.getmtime + ) + + # Load domain configuration DB + option = args.target + found = False + for post_db in db_articles: + if not str(post_db).endswith('.config'): continue + + # Load DB + exec(open(post_db).read(),globals()) + args.target = short_src + importlib.reload(db) + + if option == "again" and not db.www_again: continue + elif option == "added" and not db.www_added: continue + elif option == "updated" and not db.www_updated: continue + + check_to_publish('all') + if err_pub: + continue + + found = True + publish_article() + + if not found: + logs.out("28", 'publish %s'%option, True) + + # If found: create new ATOM/RSS file + rss.create_feed() + + +#==============================# +# Check if it can be published # +#------------------------------# +def check_to_publish(process): + global err_pub + err_pub = False + + print(' │\n ├ [%s] > %s'%(db.title, db.post_src)) + + # Article was not checked or changed + if db.no_chk: + logs.out("25", db.uri_file, False) + err_pub = 25 + elif db.old_chk: + logs.out("9", db.uri_file, False) + err_pub = 9 + + # Article must exists in wip server + if db.no_wip or db.old_wip: + logs.out("30", db.uri_file, False) + err_pub = 30 + elif not db.file_wip: + logs.out("1", db.post_wip, False) + err_pub = 1 + + if err_pub: + if process == 'all': return + elif process == 'one': sys.exit(err_pub) + #===============# # Let's publish # #---------------# -def publish_article(): +def publish_article(): # Copy wip page to www page if not os.makedirs('%s%s'%(dom.srv_www, db.direc_src), exist_ok=True): logs.out("33", '%s%s'%(dom.srv_www, db.direc_src), False) @@ -142,7 +221,6 @@ def replace_lines_pub(): logs.out("46", db.post_www, False) - #print(www_html_post) tyto.set_file(db.post_www, 'New', www_html_post) @@ -183,86 +261,3 @@ def publish_template(option): html.create_user_footer('pub') -#============================================# -# Option 'all' to publish again, based on DB # -#--------------------------------------------# -def publish_all(option): - # Ask or show what to do - if args.target == "again": - form.asking(" ├ %s%s "%( - langs.site.wip_again, langs.site.q - ), True) - - elif args.target == "addedd": - print(' │ %s'%langs.site.wip_older) - #os.chdir(dom.articles_d) - - elif args.target == "updated": - print(' │ %s'%langs.site.wip_newer) - - # Sort by newer articles (created by last check) - db_articles = sorted(Path(dom.articles_db_d).iterdir(), - key=os.path.getmtime - ) - - # Load domain configuration DB - option = args.target - found = False - for post_db in db_articles: - if not str(post_db).endswith('.config'): continue - - # Load DB - exec(open(post_db).read(),globals()) - args.target = short_src - importlib.reload(db) - - if not db.hash_wip: continue - if option == "again" and not db.sync_srvs: continue - if option == "added" and not db.old_www: continue - - if db.old_chk: - logs.out("9", '', False) - continue - - check_to_publish('all') - if err_pub: continue - - found = True - publish_article() - - if not found: - logs.out("28", '(publish)', True) - else: - # Create new ATOM/RSS file - rss.create_feed() - - -#==============================# -# Check if it can be published # -#------------------------------# -def check_to_publish(process): - global err_pub - err_pub = False - - print(' │\n ├─ [%s] > %s'%(db.title, db.post_src)) - - # Article was not checked or changed - if db.no_chk: - logs.out("25", db.uri_file, False) - err_pub = 25 - elif db.old_chk: - logs.out("9", db.uri_file, False) - err_pub = 9 - - # Article must exists in wip server - if db.no_wip or db.old_wip: - logs.out("30", db.uri_file, False) - err_pub = 30 - elif not db.file_wip: - logs.out("1", db.post_wip, False) - err_pub = 1 - - if err_pub: - if process == 'all': return - elif process == 'one': sys.exit(err_pub) - diff --git a/src/var/lib/tyto/program/rss.py b/src/var/lib/tyto/program/rss.py index 6833547..add7c84 100644 --- a/src/var/lib/tyto/program/rss.py +++ b/src/var/lib/tyto/program/rss.py @@ -35,7 +35,7 @@ import os from pathlib import Path -import logs, dom, db, tyto +import logs, dom, db, tyto, langs #============================# @@ -120,5 +120,6 @@ def create_feed(): ' \n' + \ '' + print(' │\n ├─ %s'%langs.site.rss_c) tyto.set_file(dom.www_rss_f, 'New', set_f) diff --git a/src/var/lib/tyto/program/status.py b/src/var/lib/tyto/program/status.py index 2bd5324..fdedd8c 100644 --- a/src/var/lib/tyto/program/status.py +++ b/src/var/lib/tyto/program/status.py @@ -33,7 +33,7 @@ #********************************************************************** -import args, dom, logs, tyto, form +import args, dom, logs, tyto, form, db def domain(): if dom.hole: logs.out("13", '', True) @@ -80,9 +80,13 @@ def domain(): # On demand with status action # #------------------------------# def check(target): - conf_err = False - - if target == "domain": + # target needed + if not target: + logs.out("5", '[target]', True) + + elif target == "domain": + conf_err = False + if dom.dir_unu or dom.file_unu: logs.out("60", '', False) @@ -93,6 +97,37 @@ def check(target): for file_unu in dom.file_unu: logs.out("24", file_unu, False) - if conf_err: - logs.out("31", '', True) + if conf_err: + logs.out("31", '', True) + return + + # Unused file + elif not db.post: + logs.out("1", db.uri_file, True) + + # Article has DB + elif db.exists: + # Article datas + print(' │\n ├ [%s] > %s'%(db.title, db.uri_file)) + + # chk + if db.old_chk: logs.out("94", db.uri_file, False) + else: logs.out("20", db.uri_file, False) + + # wip + if not db.file_wip: logs.out("71", db.post_wip, False) + else: logs.out("72", db.post_wip, False) + if db.no_wip: logs.out("73", db.post_wip, False) + elif db.old_wip: logs.out("74", db.post_wip, False) + + # www + if not db.file_www: logs.out("81", db.post_www, False) + else: logs.out("82", db.post_www, False) + if db.no_www: logs.out("83", db.post_www, False) + elif db.old_www: logs.out("84", db.post_www, False) + return + + # Article has NO DB + elif not db.exists: + logs.out("25", db.uri_file, True) diff --git a/src/var/lib/tyto/program/tyto.py b/src/var/lib/tyto/program/tyto.py index 49b36bf..fc5d422 100644 --- a/src/var/lib/tyto/program/tyto.py +++ b/src/var/lib/tyto/program/tyto.py @@ -35,7 +35,7 @@ import os, sys, re, subprocess, locale, base64, datetime, shutil from hashlib import blake2b -import args, dom, logs +import args, dom, logs, langs # :D Tyto = 'Tyto - Littérateur' @@ -182,6 +182,11 @@ quote_tags = [ # Tags to check in header in content _TAG head_tags = ("image:", "raw:", "code;") +# Valid characters for some datas +chrs_invalid = \ +set('{}[]_()+*=/:%~´') + + # Stats for icodes, bcodes, quotes nbr_icodes = 0 @@ -197,6 +202,18 @@ def exists(uri): else: return(False) +#========================================# +# Return converted valid HTML characters # +#----------------------------------------# +def convert_altname(altname): + altname = altname.replace('<', '<') + altname = altname.replace('>', '>') + altname = altname.replace('"', '"') + altname = altname.replace("'", ''') + + return altname + + #=======================# # Return sum of srcfile # # src: True = Content # @@ -309,8 +326,7 @@ def protect_bcodes_quotes(process, post_bottom): in_bcode = False if process == "wip": bcode = '%s\n%s'%(bcode, line) - bcode = bcode.replace('<', '<') - bcode = bcode.replace('>', '>') + bcode = convert_altname(bcode) b64_bcode = b64('Encode', bcode, 'B64.', '.B64') line = b64_bcode @@ -324,8 +340,7 @@ def protect_bcodes_quotes(process, post_bottom): in_quote = False if process == "wip": quote = '%s\n%s'%(quote, line) - quote = quote.replace('<', '<') - quote = quote.replace('>', '>') + quote = convert_altname(quote) b64_quote = b64('Encode', quote, 'Q64.', '.Q64') line = b64_quote @@ -408,8 +423,7 @@ def protect_icodes(post_bottom): # No more in code if if c_a == '}' and not c_b == '\\': in_icode = False - src_code = src_code.replace('<', '<') - src_code = src_code.replace('>', '>') + src_code = convert_altname(src_code) code = '%s%s%s'%(code, src_code, words_tags[9][3]) b64_code = b64('Encode', code, 'I64.', '.I64') rep_code = "%s%s%s"%( @@ -535,3 +549,18 @@ def files_to_srv(server): logs.out("32", f_dst, False) except: logs.out('4', f_dst, True) + + +#========================================# +# For mass treatment, show message about # +#----------------------------------------# +def show_multi_message(server, srv_dir): + if args.target == "added": + print(" │ %s '%s' > %s"%(langs.site.srv_added, server, srv_dir)) + + elif args.target == "updated": + print(" │ %s '%s' > %s "%(langs.site.srv_updated, server, srv_dir)) + + elif args.target == "again": + print(" │ %s '%s' > %s"%(langs.site.srv_again, server, srv_dir)) + diff --git a/src/var/lib/tyto/program/wip.py b/src/var/lib/tyto/program/wip.py index f46dd2e..a9c0759 100644 --- a/src/var/lib/tyto/program/wip.py +++ b/src/var/lib/tyto/program/wip.py @@ -40,6 +40,7 @@ import os, re, sys, locale, shutil, importlib, time from pathlib import Path import args, logs, langs, dom, db, tyto, html, form, stats + #=========================================# # Manage wip action with option as target # #-----------------------------------------# @@ -85,34 +86,15 @@ def manage(target): elif db.old_chk: logs.out("9", db.uri_file, True) - # Article has changed or wip file missing - if db.old_wip or not db.file_wip: - wip_article(db.uri_file) - - # wip is up-to-date: ask to wip again - else: - logs.out("19", db.date_wip, False) - form.asking(' ├ [%s] %s%s '%( - db.title, langs.site.wip_new, langs.site.q - ), True) - wip_article(db.uri_file) + # Create HTML page + wip_article(db.uri_file) #========================================# # Option 'all' to wip again, based on DB # #----------------------------------------# -def wip_all(process): - # Ask or show what to do - if args.target == "again": - form.asking(" ├ %s%s "%( - langs.site.wip_again, langs.site.q - ), True) - - elif args.target == "addedd": - print(' │ %s'%langs.site.wip_older) - - elif args.target == "updated": - print(' │ %s'%langs.site.wip_newer) +def wip_all(process): + tyto.show_multi_message('wip', dom.srv_wip) # Sort by newer articles (created by last check) db_articles = sorted(Path(dom.articles_db_d).iterdir(), @@ -133,23 +115,10 @@ def wip_all(process): importlib.reload(db) except: continue - - # Article has changed and not check - if db.old_chk: - logs.out("9", db.post_src, False) - continue - - # newer: article not yet wip - elif option == "added" and db.hash_wip: - continue - - # All: only old wip - elif option == "updated" and not db.old_wip: - continue - - # again: wip again wip articles - elif option == "again" and not db.hash_wip: - continue + + if option == "added" and not db.wip_added: continue + elif option == "updated" and not db.wip_updated: continue + elif option == "again" and not db.wip_again: continue found = True wip_article(db.post_src) @@ -175,7 +144,7 @@ def wip_article(target): # Convert file to strings file_to_string(target) - print(' │\n ├─ [%s] > %s'%(db.title, db.post_src)) + print(' │\n ├ [%s] > %s'%(db.title, db.post_src)) global post_header global post_bottom @@ -192,11 +161,11 @@ def wip_article(target): # Convert contents from modules + wip_images() # Images_%i from headers in DB wip_single_tags() # br /, anchors wip_words_tags() # Paragraphs, strongs, italics wip_links() # Links_%i from headers in DB wip_abbrs() # Convert abbr - wip_images() # Images_%i from headers in DB wip_titles() # Convert #N, remove empty line, add divs wip_lists() # convert ul/ol lists wip_quotes() # Quotes. Decode base64 Q64 and convert to HTML @@ -234,15 +203,16 @@ def file_to_string(post_file): for line in article.rsplit('\n'): if line.startswith('-----'): - sep = True - continue + if not sep: + sep = True + continue if sep: if not post_bottom: post_bottom = line - else: post_bottom = '%s\n%s'%(post_bottom, line) + else: post_bottom = '%s\n%s'%(post_bottom, line) else: if not post_header: post_header = line - else: post_header = '%s\n%s'%(post_header, line) + else: post_header = '%s\n%s'%(post_header, line) #===============================================================# @@ -383,9 +353,12 @@ def wip_abbrs(): abbr_src = '%s' for i in range(1, db.uniq_abbrs + 1): - abbr = 'db.abbr_%s'%i - try: abbr_show = eval(abbr)[2] - except: abbr_show = eval(abbr)[0] + abbr = 'db.abbr_%s'%i + + abbr_show = eval(abbr)[2] + if not eval(abbr)[2]: + abbr_show = eval(abbr)[0][1:-1] + abbr_html = abbr_src%(dom.css, eval(abbr)[1], abbr_show @@ -689,7 +662,7 @@ def wip_bcodes(): # Block-code content per line else: html_bcode = \ - '%s\n
%s
'%( + '%s\n

%s

'%( html_bcode, line ) @@ -779,17 +752,19 @@ def wip_filecode(target): for i in range(1, db.uniq_codes + 1): code = 'db.code_%s'%i code_file = open('%s%s'%(dom.articles_d, eval(code)[1])).read() - code_html = '
\n'%(
+    code_html = '\n'%(
                 dom.css, eval(code)[2]
                 ) + \
-                '  '
+                '  
'
     
     for line in code_file.rsplit('\n'):
-      code_html = '%s\n    %s'%(
+      line      = line.replace('<', '<')
+      line      = line.replace('>', '>')
+      code_html = '%s\n    

%s

'%( code_html, line ) - code_html = '%s\n
\n
'%(code_html) + code_html = '%s\n
\n'%(code_html) replace_in_post(eval(code)[0], code_html ) @@ -803,21 +778,21 @@ def wip_lists(): global post_bottom - content_list = '' in_list = False for line in post_bottom.rsplit('\n'): # Open list if line.startswith(tyto.words_tags[13][0]): + block_list = content_list = '' css = tyto.get_css(line) in_list = True - content_list = line + block_list = line continue # Close list elif line.startswith(tyto.words_tags[13][1]): in_list = False - content_list = '%s\n%s'%(content_list, line) + block_list = '%s\n%s'%(block_list, line) html_list = convert_list( content_list ).replace('