From b6799ab360ed627f530f4dc20e8afbfa9c14b2a0 Mon Sep 17 00:00:00 2001 From: Cyrille L Date: Tue, 28 Mar 2023 14:37:42 +0200 Subject: [PATCH] check. new written functions --- README.md | 19 +- src/var/lib/tyto/program/check.py | 913 ++++++++++++++--------- src/var/lib/tyto/program/logs.py | 5 +- src/var/lib/tyto/program/show.py | 9 +- src/var/lib/tyto/program/tyto.py | 34 + src/var/lib/tyto/translations/logs_en.py | 2 + src/var/lib/tyto/translations/logs_fr.py | 2 + 7 files changed, 601 insertions(+), 383 deletions(-) diff --git a/README.md b/README.md index 7a5de37..af4b100 100644 --- a/README.md +++ b/README.md @@ -29,9 +29,9 @@ raw: Nom URI Texte Alternatif -abbr: NOM (en majuscule) - Définition du NOM - nom (forme à afficher dans l'artile (optionnel)) +abbr: abbrev + Définition de abbrev + ABBR (forme à afficher dans l'artile (optionnel)) # L'image doit d'abord être configurée # Utiliser l'image précisée comme défaut dans les réseaux sociaux @@ -158,13 +158,14 @@ Vous pouvez avoir un Nom identique pour file: et link: ### Abréviations ``` -# NOM sera remplacé par "nom" dans la page si défini en entête -# sinon, NOM sera conservé -# - Toujours écrire en majuscule les ABBR dans l'article brut -# - Mettre '!' devant NOM dans l'article +# abbrev sera remplacé par "ABBR" dans la page si défini en entête +# sinon, abbrev sera conservé +# - Toujours écrire dans l'article : +# - entre parenthèses ET majuscules les "(ABBREV)" + -Avec ce !NOM. -# HTML: nom +Avec cette (ABBREV). +# HTML: ABBR ``` ### Images diff --git a/src/var/lib/tyto/program/check.py b/src/var/lib/tyto/program/check.py index 6767edd..d2e16eb 100644 --- a/src/var/lib/tyto/program/check.py +++ b/src/var/lib/tyto/program/check.py @@ -126,7 +126,6 @@ def check_process(target): if not db.post: sys.exit(1) global post_bottom, article_bottom - global post_words global date_wip, hash_wip, date_www, hash_www, post_bottom global post_err date_wip = hash_wip = date_www = hash_www = '' @@ -189,11 +188,13 @@ def check_process(target): tyto.protect_icodes(post_bottom) post_bottom = tyto.protect_article - # Check tags configuration - check_headers(post_header.rsplit('\n')) + # 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 - - # Check for valid contents + + # Check for valid contents check_content(post_bottom) # Remove db (if exists) on post error and return @@ -202,19 +203,8 @@ def check_process(target): os.remove(db.config) return - - # Count words in article. - # Quotes, block-codes, icode = 1 per each - # At db creation, remove title numbers - post_words = 0 - for line in post_bottom.rsplit("\n"): - if not line \ - or line.startswith(tyto.nolinewords) \ - or line.startswith("#") and \ - not line.startswith(tyto.titles_tags): - continue - post_words = post_words + len(line.strip().split(" ")) - + # COunt words + count_words(post_bottom.rsplit("\n")) # Create article's database create_database() @@ -226,6 +216,7 @@ def check_process(target): #---------------------------------# def file_to_string(): global article, post_header, post_bottom + global ln_header, ln_bottom, ln_article post_header = post_bottom = '' sep = content = False @@ -246,14 +237,37 @@ def file_to_string(): # Check if separator or exit if not sep: - logs.out("6", '----- > %s'%db.uri_file, True) + logs.out("6", '"-----" > %s'%db.uri_file, True) if not content: if db.exists and tyto.exists(db.config): os.remove(db.config) logs.out("18", db.uri_file, True) + # +2 > (start at 0 + separator line) + ln_article = len(article.splitlines()) + 1 + ln_header = len(post_header.splitlines()) + 2 + ln_bottom = len(post_bottom.splitlines()) + 2 + +#=========================================# +# Count words in article. # +# Quotes, block-codes, icode = 1 per each # +# At db creation, remove title numbers # +#-----------------------------------------" +def count_words(post_bottom): + global post_words + post_words = 0 + for line in post_bottom: + if not line \ + or line.startswith(tyto.nolinewords) \ + or line.startswith("#") and \ + not line.startswith(tyto.titles_tags): + continue + + post_words = post_words + len(line.strip().split(" ")) + + #=============================================# # Check if bcodes and quotes # # Check inline code, for markers on same line # @@ -267,8 +281,7 @@ def if_icodes_bcodes_quotes(post_bottom): nbr_titles = nbr_quotes = nbr_bcodes = nbr_ancs = 0 for ln, line in enumerate(post_bottom.rsplit('\n'), 1): - # Pass Comments, count titles - # Count titles + # Comments, count titles if not line: continue elif line.startswith(tyto.titles_tags): @@ -277,35 +290,38 @@ def if_icodes_bcodes_quotes(post_bottom): elif line.startswith('#'): continue - # Pass quotes + # quotes elif line.startswith(tyto.words_tags[11][0]) and not in_bcode: quote = in_quote = True - nbr_quotes += 1 continue elif line.startswith(tyto.words_tags[11][1]): in_quote = False + nbr_quotes += 1 continue - # Pass bcode + # bcode elif line.startswith(tyto.words_tags[12][0]) and not in_quote: bcode = in_bcode = True - nbr_bcodes += 1 continue elif line.startswith(tyto.words_tags[12][1]): in_bcode = False + nbr_bcodes += 1 continue if in_bcode or in_quote: continue + elif line.startswith(tyto.single_tags[1][0]): nbr_ancs += 1 + + # icodes elif tyto.words_tags[9][0] or tyto.words_tags[9][1] in line: icode_m1 = icode_m2 = 0 icode_m1 = line.count(tyto.words_tags[9][0]) icode_m2 = line.count(tyto.words_tags[9][1]) if icode_m1 != icode_m2: - print(" ├─", line) - logs.out("8", 'icode: L=%s. "%s %s" > %s'%(ln, + logs.out("8", 'L=%s. icode "%s" + "%s" > %s'%( + ln + ln_header, tyto.words_tags[9][0], tyto.words_tags[9][1], db.uri_file ), False @@ -315,6 +331,505 @@ def if_icodes_bcodes_quotes(post_bottom): icode = True +#=========================================# +# Check needed tags from article's header # +# Each one must be uniq. Only first taken # +#-----------------------------------------# +def check_needed_tags(post_header): + global post_err + global title, author, about, tags, date + global stat_tags + + title = author = about = tags = '' + date = () + stat_tags = 0 + + # Check post header for each needed tags + for tag in tyto.needed_header_tags: + for ln, line in enumerate(post_header, 1): + # Break if already set + if globals()[tag]: break + + # Set data from tag + if line.startswith('%s:'%tag): + globals()[tag] = line.rsplit('%s:'%tag)[1].lstrip() + # Stat for "tags:" + if tag == 'tags': + stat_tags = len(globals()[tag].strip().split(",")) + + # Check if unused needed tags + for tag in tyto.needed_header_tags: + if not globals()[tag]: + logs.out("17", '%s:'%tag, False) + post_err = True + + # Check date format + # Set french format in post DB + if not post_err: + check_date(date) + + +#================================# +# Check Date format and validity # +# Create False date_check # +#--------------------------------# +def check_date(date): + global post_err + + # Check if article date is valid (True) + fmt_article = "%Y-%m-%d" + + try: + bool(datetime.strptime(date, fmt_article)) + except ValueError: + post_err = True + logs.out("3", 'date: "%s" (YYYY-MM-DD) > %s'%(date, db.uri_file), False) + + # Create date_check (epoch) from article's Date + now TIME + if not post_err: + fmt_check = '%Y-%m-%d %H:%M:%S' + time_check = strftime("%H:%M:%S", gmtime()) + date_check = date + ' ' + time_check + date_check = time.mktime(time.strptime(date_check, fmt_check)) + + # Set franch format in post DB + if lang_site == 'fr': + date = date.rsplit('-') + date = date[2] + '/' + date[1] + '/' + date[0] + + date = (date, date_check) + + +#===========================================# +# Check optional tags from article's header # +# Multiple settings for each on 3 lines # +#-------------------------------------------# +def check_opt_tags(post_header): + global stat_links, stat_images, stat_files, stat_raws, stat_abbrs + global stat_snpics, snpic_url + global opt_tags_post_name + global files_post + + # Statistics + stat_links = stat_images = stat_files = stat_raws = stat_abbrs = 0 + stat_snpics = 0 + files_post = (()) + + # Set default post pic + snpic_url = '%s/template/%s'%(dom.www_url, dom.logo) + + # Search for term in article + opt_tags_post_name = \ + { + 'link' : "_%s", + 'image' : "_image:%s", + 'file' : "__%s", + 'raw' : "_raw:%s", + 'abbr' : "(%s)" + } + + # Check post header for each optional tags + for tag in tyto.opt_header_tags: + for ln, line in enumerate(post_header, 1): + if line.startswith('%s:'%tag): + check_3lines(tag, ln, line) + + +#============================================# +# Do stats, check 3 lines tags from ln # +# Set data for each 2 next lines # +# Exception for snpic (Different conditions) # +#--------------------------------------------# +def check_3lines(tag, ln, line): + global post_err, db_tag, files_post + + stat_tag = "stat_%ss"%tag + + # Create variable for post DB + globals()[stat_tag] += 1 + db_tag = '%s_%s'%(tag, globals()[stat_tag]) + globals()[db_tag] = (()) + + # NAME + #----- + # ln is legacy (from loop), so take line content + # Take only first word if not a long name tag + if tag in tyto.opt_tags_long_name: + name = line.rsplit('%s:'%tag)[1].lstrip() + else: + name = line.rsplit('%s:'%tag)[1].lstrip().rsplit(' ')[0] + if tag == "abbr": + name = name.upper() + + if not name: + logs.out("2", 'L=%s. "%s: %s" > %s'%( + ln, tag, tr.name, db.uri_file + ), False) + post_err = True + + # snpic only needs a Name + elif tag == "snpic": + check_snpic(name) + return + + elif not isin(r'\b%s\b'%(opt_tags_post_name[tag]%name), post_bottom): + logs.out("12", '"%s" > %s'%( + opt_tags_post_name[tag]%name, db.uri_file + ), False) + post_err = True + + globals()[db_tag] = ((name),) + + # URI/URL and Alt-Text + #--------------------- + # loop 1,2. Next real line from start tag + for l in range(1,3): + if l == 1: data_log = "URI/URL" + elif l == 2: data_log = "Alt-Text" + + ln += 1 + try: + # ln - 1 as string post_header starts with 0 + data = post_header.rsplit('\n')[ln - 1].lstrip() + if data.startswith(tyto.headers): data = '' + except: + data = '' + + if not data: + logs.out("2", 'L=%s. "%s" (%s:) > %s'%( + ln, data_log, tag, db.uri_file + ), False) + post_err = True + + # For tags having URI, check if file exists + # Set data for post DB + if l == 1 and tag in tyto.opt_tags_check_uri: + check_file_uri(tag, data, ln) + globals()[db_tag] = globals()[db_tag] + ((web_uri),) + files_post = files_post + (('%s'%web_uri),) + else: + globals()[db_tag] = globals()[db_tag] + ((data),) + + +#=====================# +# Find in post_bottom # +#---------------------# +def isin(term, post_file): + for line in post_file.rsplit('\n'): + if re.search(term, line): + return(True) + return(False) + + +#===================================# +# Check if file exists # +# Get filetype, filename, i=var nbr # +#-----------------------------------# +def check_file_uri(filetype, filename, ln): + global post_err, err, web_uri + + # Set file uri from filename + # (@ = images/, / = articles/, else = post_dir) + if filename.startswith('@'): + if filetype == 'image' or filetype == "snpic": + fileuri = dom.images_d + filename[1: len(filename)] + elif filetype == 'file' or filetype == 'raw': + fileuri = dom.files_d + filename[1: len(filename)] + + else: + post_dir = db.uri_file.split("/")[-1] + post_dir = db.uri_file.rsplit(post_dir)[0] + if filename.startswith('/'): + fileuri = post_dir + filename[1: len(filename)] + else: + fileuri = post_dir + filename + + # Check if file exists + if not filetype == "snpic" and not tyto.exists(fileuri): + logs.out("1", "L=%s. %s > %s"%(ln, fileuri, db.uri_file), False) + post_err = True + return + + web_uri = '/' + fileuri.replace(dom.articles_d, "") + + +#====================================# +# Check for snpic # +# (Used pic for social network) # +# Needs: # +# - a Name # +# - an image tag set with same name # +#-----------------------------------# +def check_snpic(name): + global snpic_url, snpic_post, post_err + + try: + snpic_post + return + except: + pass + + # Search post_header for image: %name + Found = False + tag = tyto.opt_header_tags[1] + for ln, line in enumerate(post_header.rsplit('\n'), 1): + if line.startswith('%s:'%tag): + try: + check_name = line.rsplit('%s:'%tag)[1].lstrip().rsplit(' ')[0] + except: + check_name = '' + + if check_name == name: + Found = True + snpic_post = post_header.rsplit('\n')[ln].lstrip() + check_file_uri("snpic", snpic_post, ln) + break + + if not Found: + logs.out("27", '"%s: %s" > %s'%(tag, name, db.uri_file), False) + return + + snpic_post = True + snpic_url = dom.www_url + web_uri + + +#===========================# +# Check tags in post_bottom # +#---------------------------# +def check_content(post_bottom): + global post_err + + # Check if anchor has target + # Count anchors target + #--------------------------- + for ln, line in enumerate(post_bottom.rsplit('\n'), 1): + # Anchor link + if tyto.words_tags[0][0] and tyto.words_tags[0][1] in line: + anchors = re.findall(r">_(.*?)_<", line) + for anchor in anchors: + css_anchor = anchor.rsplit(':')[0] + tag = '%s %s'%(tyto.single_tags[1][0], css_anchor) + if not tag in post_bottom: + logs.out("12", 'L=%s. anchor "%s" > %s'%( + ln + ln_header, tag, db.uri_file + ), False) + post_err = True + + # Anchor source "->" + if line.startswith(tyto.single_tags[1][0]): + set_css = tyto.get_css(line) + is_uniq_anchor = "%s %s"%(tyto.single_tags[1][0], set_css) + c_uniq_anchor = post_bottom.count(is_uniq_anchor) + if c_uniq_anchor > 1: + logs.out("15", 'L=%s. %sx "%s" > %s'%( + ln + ln_header, c_uniq_anchor, is_uniq_anchor, + db.uri_file + ), False) + post_err = True + break + + + # Lists: check if contents are valid + #----------------------------------- + inlist = False + markers_lists = '%s, %s, or space'%( + tyto.markers_lists[0], + tyto.markers_lists[1] + ) + for ln, line in enumerate(article.rsplit('\n'), 1): + if line.startswith('-('): inlist = True;continue + elif line.startswith('-)'): inlist = False + if not inlist: continue + + if inlist and not line or not line[0] in tyto.markers_lists: + logs.out("3", 'line %s must start with %s'%( + ln, markers_lists + ), False + ) + post_err = True + + + # Check for all match _TAGS:NAME from content in header + #------------------------------------------------------ + set_tags = () + for ln, line in enumerate(post_bottom): + for htag in tyto.head_tags: + match = False + ptag = '_%s'%htag + + if line.startswith(ptag): + ptag_set = line.rsplit(':', 1)[1].lstrip().rsplit(' ')[0] + if ptag_set in set_tags: continue + for hline in post_header: + if re.search(r"^%s\s+%s$"%(htag,ptag_set), hline): + match = True + set_tags = (ptag_set) + + if match: continue + else: + logs.out("12", "%s %s"%(htag, ptag_set), False) + post_err = True + + + # Check tags for words (strongs, italics...) + # Set stats for each one + #------------------------------------------- + for tag in tyto.words_tags: + c_opened = c_closed = 0 + + if tag[5] == 'w': + c_opened = post_bottom.count(tag[0]) + c_closed = post_bottom.count(tag[1]) + # Useless tag now, replace + post_bottom = post_bottom.replace(tag[0], '') + post_bottom = post_bottom.replace(tag[1], '') + elif tag[5] == 't': + for line in post_bottom.rsplit('\n'): + if line.startswith(tag[0]): c_opened += 1 + if line.startswith(tag[1]): c_closed += 1 + + if c_opened != c_closed: + logs.out("8", '%s "%s" + "%s" > %s'%( + tag[4], tag[0], tag[1], db.uri_file + ), False) + post_err = True + return # Useless and could code errors to check nexts + else: + globals()['post_%s'%tag[4]] = int(c_opened) + + + # Template Tags (warning for not paired symbols) + #----------------------------------------------- + for tag in tyto.tpl_tags: + tpl1 = post_bottom.count(tag[0]) + tpl2 = post_bottom.count(tag[1]) + + if tpl1 != tpl2: + logs.out("22", '"%s" + "%s" > %s'%( + tag[0], tag[1], db.uri_file + ), False) + + +#===============================# +# Create new article's database # +#------------------------------&co-# +def create_database(): + # Post Configurations + #-------------------- + database = \ + '# Post Configurations\n' + \ + 'post_id = "%s"\n'%db.uri_id + \ + 'post_src = "%s"\n'%db.uri_file + \ + 'post_wip = "%s"\n'%srv_post_wip_uri + \ + 'post_www = "%s"\n'%srv_post_www_uri + \ + '\n' + \ + 'direc_src = "%s"\n'%direc_src + \ + 'short_src = "%s"\n'%src_post_short_uri + \ + 'short_srv = "%s"\n'%srv_post_short_uri + \ + 'sub_uri = "%s"\n'%sub_uri + \ + 'http_wip = "%s"\n'%http_wip + \ + 'http_www = "%s"\n'%http_www + \ + '\n' + \ + 'date_chk = "%s"\n'%tyto.nowdate() + \ + 'hash_chk = "%s"\n'%db.hash_post + \ + 'date_wip = "%s"\n'%date_wip + \ + 'hash_wip = "%s"\n'%hash_wip + \ + 'date_www = "%s"\n'%date_www + \ + 'hash_www = "%s"\n'%hash_www + \ + '\n# Needed tags configurations\n' + \ + 'title = "%s"\n'%title + \ + 'about = "%s"\n'%about + \ + 'author = "%s"\n'%author + \ + 'tags = "%s"\n'%tags + \ + 'date = "%s"\n'%date + \ + 'snpic = "%s"\n'%snpic_url + \ + '\n# Used files\n' + \ + 'uris = %s'%str(files_post) + + + # Tags configuration + #------------------- + datas_tag = '' + if stat_abbrs > 0: + for i in range(1, stat_abbrs + 1): + datas_tag = '%s\nabbr_%s = %s'%( + datas_tag, i, globals()['abbr_%s'%i] + ) + + if stat_links > 0: + for i in range(1, stat_links + 1): + datas_tag = '%s\nlink_%s = %s'%( + datas_tag, i, globals()['link_%s'%i] + ) + + if stat_images > 0: + for i in range(1, stat_images + 1): + datas_tag = '%s\nimage_%s = %s'%( + datas_tag, i, globals()['image_%s'%i] + ) + + if stat_files > 0: + for i in range(1, stat_files + 1): + datas_tag = '%s\nfile_%s = %s'%( + datas_tag, i, globals()['file_%s'%i] + ) + + if stat_raws > 0: + for i in range(1, stat_raws + 1): + datas_tag = '%s\nraw_%s = %s'%( + datas_tag, i, globals()['raw_%s'%i] + ) + + opt_tags = '' + if datas_tag: + opt_tags = \ + '\n# Optional tags configurations' + \ + '%s\n'%datas_tag + + # Statistics configurations + #-------------------------- + stat_words = post_words - nbr_titles # Count real words + + db_stats = \ + '# Statistics configurations\n' + \ + 'uniq_anchors = %d\n'%nbr_ancs + \ + 'uniq_abbrs = %d\n'%stat_abbrs + \ + 'uniq_links = %d\n'%stat_links + \ + 'uniq_images = %d\n'%stat_images + \ + 'uniq_files = %d\n'%stat_files + \ + 'uniq_raws = %d\n'%stat_raws + \ + '\n# Statistics from post content\n' + \ + 'stat_tags = %d\n'%stat_tags + \ + 'stat_lines = %d\n'%ln_article + \ + 'stat_words = %d\n'%stat_words + \ + 'stat_titles = %d\n'%nbr_titles + \ + 'stat_paragraphs = %d\n'%post_paragraphs + \ + 'stat_anchors = %d\n'%post_anchors + \ + 'stat_strongs = %d\n'%post_strongs + \ + 'stat_bolds = %d\n'%post_bolds + \ + 'stat_emphasis = %d\n'%post_emphasis + \ + 'stat_italics = %d\n'%post_italics + \ + 'stat_dels = %d\n'%post_dels + \ + 'stat_underlines = %d\n'%post_underlines + \ + 'stat_cites = %d\n'%post_cites + \ + 'stat_customs = %d\n'%post_customs + \ + 'stat_icodes = %d\n'%tyto.nbr_icodes + \ + 'stat_bcodes = %d\n'%nbr_bcodes + \ + 'stat_quotes = %d\n'%nbr_quotes + \ + 'stat_lists = %d\n'%post_lists + + # Create Post DB + #--------------- + database = '%s\n%s\n%s'%(database, opt_tags, db_stats) + tyto.set_file(db.config, 'new', database) + logs.out("21", db.uri_file, False) + + + + + + + #==================================# # Check tags from article's header # #----------------------------------# @@ -334,77 +849,12 @@ def check_headers(post_header): snpic_name = '' # Needed Tags - title = author = tags = about = '' + title = author = about = tags = '' date = () # Statistics stat_links = stat_images = stat_files = stat_raws = stat_abbrs = 0 -### - # First session for needed tags # - # Read articles lines, till separator # - #-------------------------------------# - for ln, line in enumerate(post_header, 1): - # Set each needed tag # - # Only the first one is set # - #---------------------------# - tag = tyto.headers[0] # title: - if line.startswith(tag): - if title: continue - title = line.rsplit(tag)[1].lstrip() - continue - - tag = tyto.headers[1] # about: - if line.startswith(tag): - if about: continue - about = line.rsplit(tag)[1].lstrip() - continue - - tag = tyto.headers[2] # author: - if line.startswith(tag): - if author: continue - author = line.rsplit(tag)[1].lstrip() - continue - - tag = tyto.headers[3] # tags: - if line.startswith(tag): - if tags: continue - tags = line.rsplit(tag)[1].lstrip() - post_tags = len(tags.strip().split(",")) - continue - - tag = tyto.headers[4] # date: - if line.startswith(tag): - if date: continue - date = line.rsplit(tag)[1].lstrip() - check_date(date, ln, line) - - if not post_err: - if lang_site == 'fr': - date = date.rsplit('-') - date = date[2] + '/' + date[1] + '/' + date[0] - date = (date, date_check) - continue - - - # Check needed tags # - #-------------------# - # Set needed tags - need_headers = \ - { - tyto.headers[0] : title, - tyto.headers[1] : about, - tyto.headers[2] : author, - tyto.headers[3] : tags, - tyto.headers[4] : date - } - - # Check if set needed tags - for tag in need_headers: - if not need_headers[tag]: - logs.out("17", tag, False) - post_err = True - ### # Second session for optional tags # @@ -707,280 +1157,3 @@ def check_headers(post_header): post_err = True -#================================# -# Check Date format and validity # -# Create False date_check # -#--------------------------------# -def check_date(date, ln, line): - global post_err, date_check - - # Check if article date is valid (True) - fmt_article = "%Y-%m-%d" - - try: - bool(datetime.strptime(date, fmt_article)) - except ValueError: - post_err = True - print(" ├─", line) - logs.out("3", 'date: L=%s. "%s" > %s'%( - ln, date, db.uri_file - ), False) - - # Create date_check (epoch) from article's Date + now TIME - if not post_err: - fmt_check = '%Y-%m-%d %H:%M:%S' - time_check = strftime("%H:%M:%S", gmtime()) - date_check = date + ' ' + time_check - date_check = time.mktime(time.strptime(date_check, fmt_check)) - - -#===================================# -# Check if file exists # -# Get filetype, filename, i=var nbr # -#-----------------------------------# -def check_file_uri(filetype, filename, ln): - global post_err, err, web_uri - - # Set file uri from filename - # (@ = images/, / = articles/, else = post_dir) - if filename.startswith('@'): - if filetype == 'image': - fileuri = dom.images_d + filename[1: len(filename)] - elif filetype == 'file': - fileuri = dom.files_d + filename[1: len(filename)] - - else: - post_dir = db.uri_file.split("/")[-1] - post_dir = db.uri_file.rsplit(post_dir)[0] - if filename.startswith('/'): - fileuri = post_dir + filename[1: len(filename)] - else: - fileuri = post_dir + filename - - # Check if file exists - if not tyto.exists(fileuri): - logs.out("1", "L=%s. %s > %s"%(ln, fileuri, db.uri_file), False) - post_err = True - return - - web_uri = '/' + fileuri.replace(dom.articles_d, "") - - -#===========================# -# Check tags in post_bottom # -#---------------------------# -def check_content(post_bottom): - global post_err - - #print("post_bottom") - #print(post_bottom) - - # Check tags for words (strongs, italics...) - # Set stats for each one - #------------------------------------------- - for tag in tyto.words_tags: - c_opened = c_closed = 0 - - if tag[5] == 'w': - c_opened = post_bottom.count(tag[0]) - c_closed = post_bottom.count(tag[1]) - # Useless tag now, replace - post_bottom = post_bottom.replace(tag[0], '') - post_bottom = post_bottom.replace(tag[1], '') - elif tag[5] == 't': - for line in post_bottom.rsplit('\n'): - if line.startswith(tag[0]): c_opened += 1 - if line.startswith(tag[1]): c_closed += 1 - - if c_opened != c_closed: - logs.out("8", '%s: "%s", "%s"'%(tag[4], tag[0], tag[1]), False) - post_err = True - return # Useless and could code errors to check nexts - else: - globals()['post_%s'%tag[4]] = int(c_opened) - - - # Check if anchor has target - # Count anchors target - #--------------------------- - for line in post_bottom.rsplit('\n'): - # Anchor link - if tyto.words_tags[0][0] and tyto.words_tags[0][1] in line: - anchors = re.findall(r">_(.*?)_<", line) - for anchor in anchors: - css_anchor = anchor.rsplit(':')[0] - tag = '%s %s'%(tyto.single_tags[1][0], css_anchor) - if not tag in post_bottom: - logs.out("6", 'anchor, %s'%tag, False) - post_err = True - - # Anchor source "->" - elif line.startswith(tyto.single_tags[1][0]): - set_css = tyto.get_css(line) - is_uniq_anchor = "%s %s"%(tyto.single_tags[1][0], set_css) - c_uniq_anchor = post_bottom.count(is_uniq_anchor) - if c_uniq_anchor > 1: - logs.out("15", '%s "%s"'%(c_uniq_anchor, is_uniq_anchor), False) - post_err = True - break - - - # Lists: check if contents are valid - #----------------------------------- - inlist = False - markers_lists = '%s, %s, or space'%( - tyto.markers_lists[0], - tyto.markers_lists[1] - ) - for ln, line in enumerate(article.rsplit('\n'), 1): - if line.startswith('-('): inlist = True;continue - elif line.startswith('-)'): inlist = False - if not inlist: continue - - if inlist and not line or not line[0] in tyto.markers_lists: - logs.out("3", 'line %s must start with %s'%( - ln, markers_lists - ), False - ) - post_err = True - - - # Check for all match _TAGS:NAME from content in header - #------------------------------------------------------ - set_tags = () - for ln, line in enumerate(post_bottom): - for htag in tyto.head_tags: - match = False - ptag = '_%s'%htag - - if line.startswith(ptag): - ptag_set = line.rsplit(':', 1)[1].lstrip().rsplit(' ')[0] - if ptag_set in set_tags: continue - for hline in post_header: - if re.search(r"^%s\s+%s$"%(htag,ptag_set), hline): - match = True - set_tags = (ptag_set) - - if match: continue - else: - logs.out("12", "%s %s"%(htag, ptag_set), False) - post_err = True - - - # Template Tags (warning for not paired symbols) - #----------------------------------------------- - for tag in tyto.tpl_tags: - tpl1 = post_bottom.count(tag[0]) - tpl2 = post_bottom.count(tag[1]) - - if tpl1 != tpl2: - logs.out("22", '"%s", "%s"'%(tag[0], tag[1]), False) - - -#===============================================# -# Create new article's database at each check ! # -#-----------------------------------------------# -def create_database(): - database = '# Post Configuration for Tyto\n' + \ - 'post_id = "%s"\n'%db.uri_id + \ - 'post_src = "%s"\n'%db.uri_file + \ - 'post_wip = "%s"\n'%srv_post_wip_uri + \ - 'post_www = "%s"\n'%srv_post_www_uri + \ - '\n' + \ - 'direc_src = "%s"\n'%direc_src + \ - 'short_src = "%s"\n'%src_post_short_uri + \ - 'short_srv = "%s"\n'%srv_post_short_uri + \ - 'sub_uri = "%s"\n'%sub_uri + \ - 'http_wip = "%s"\n'%http_wip + \ - 'http_www = "%s"\n'%http_www + \ - '\n' + \ - 'date_chk = "%s"\n'%tyto.nowdate() + \ - 'hash_chk = "%s"\n'%db.hash_post + \ - 'date_wip = "%s"\n'%date_wip + \ - 'hash_wip = "%s"\n'%hash_wip + \ - 'date_www = "%s"\n'%date_www + \ - 'hash_www = "%s"\n'%hash_www + \ - '\n# Post configuration from needed tags\n' + \ - 'title = "%s"\n'%title + \ - 'about = "%s"\n'%about + \ - 'author = "%s"\n'%author + \ - 'tags = "%s"\n'%tags + \ - 'date = %s\n'%str(date) + \ - 'snpic = "%s"\n'%snpic_url + \ - '\n# Used files\n' + \ - 'uris = (%s)\n'%files_post + \ - '\n# Post configuration from optional tags' - - if stat_abbrs > 0: - for i in range(1, stat_abbrs + 1): - database = '%s\nabbr_%s = %s'%( - database, i, globals()['abbr_%s'%i] - ) - - if stat_links > 0: - for i in range(1, stat_links + 1): - database = '%s\nlink_%s = %s'%( - database, i, globals()['link_%s'%i] - ) - - if stat_images > 0: - for i in range(1, stat_images + 1): - database = '%s\nimage_%s = %s'%( - database, i, globals()['image_%s'%i] - ) - - if stat_files > 0: - for i in range(1, stat_files + 1): - database = '%s\nfile_%s = %s'%( - database, i, globals()['file_%s'%i] - ) - - if stat_raws > 0: - for i in range(1, stat_raws + 1): - database = '%s\nraw_%s = %s'%( - database, i, globals()['raw_%s'%i] - ) - - # Count real words - stat_words = post_words - nbr_titles - - db_stats = '\n# Statistics from optional tags\n' + \ - 'uniq_anchors = %d\n'%nbr_ancs + \ - 'uniq_abbrs = %d\n'%stat_abbrs + \ - 'uniq_links = %d\n'%stat_links + \ - 'uniq_images = %d\n'%stat_images + \ - 'uniq_files = %d\n'%stat_files + \ - 'uniq_raws = %d\n'%stat_raws + \ - '\n# Statistics from post content\n' + \ - 'stat_tags = %d\n'%post_tags + \ - 'stat_words = %d\n'%stat_words + \ - 'stat_titles = %d\n'%nbr_titles + \ - 'stat_paragraphs = %d\n'%post_paragraphs + \ - 'stat_anchors = %d\n'%post_anchors + \ - 'stat_strongs = %d\n'%post_strongs + \ - 'stat_bolds = %d\n'%post_bolds + \ - 'stat_emphasis = %d\n'%post_emphasis + \ - 'stat_italics = %d\n'%post_italics + \ - 'stat_dels = %d\n'%post_dels + \ - 'stat_underlines = %d\n'%post_underlines + \ - 'stat_cites = %d\n'%post_cites + \ - 'stat_customs = %d\n'%post_customs + \ - 'stat_icodes = %d\n'%tyto.nbr_icodes + \ - 'stat_bcodes = %d\n'%nbr_bcodes + \ - 'stat_quotes = %d\n'%nbr_quotes + \ - 'stat_lists = %d\n'%post_lists - - - database = '%s\n%s'%(database, db_stats) - tyto.set_file(db.config, 'new', database) - logs.out("21", db.uri_file, False) - - -#=====================# -# Find in post_bottom # -#---------------------# -def isin(term, post_bottom): - for x in post_bottom.rsplit('\n'): - if re.search(r'%s'%term, x): - return(True) - return(False) diff --git a/src/var/lib/tyto/program/logs.py b/src/var/lib/tyto/program/logs.py index 6320d84..9ff1ea7 100644 --- a/src/var/lib/tyto/program/logs.py +++ b/src/var/lib/tyto/program/logs.py @@ -36,7 +36,7 @@ def out(nbr, value, out): '3' : ' ╞ %s%s%s %s'%(CR, lang.data_inv, CS, value), '4' : ' ╘ %sUnable to create file%s: %s'%(CR, CS, value), '5' : ' ╘ %s%s%s > "%s"'%(CR, lang.no_arg, CS, value), - '6' : ' ╞ %s%s%s > "%s"'%(CR, lang.sep_inv, CS, value), + '6' : ' ╞ %s%s%s > %s'%(CR, lang.sep_inv, CS, value), '7' : ' ╘ %s%s%s > %s'%(CR, lang.post_inv, CS, value), '8' : ' ╞ %s%s%s %s'%(CR, lang.mark_np, CS, value), '9' : ' ╞ Article %shas changed%s. Check it first'%(CR, CS), @@ -45,7 +45,7 @@ def out(nbr, value, out): '12' : ' ╞ %s%s%s > %s'%(CR, lang.post_inc, CS, value), '13' : ' ╞ %s%s%s'%(CR, lang.no_fidi, CS), '14' : ' ╞ %sMismatch%s program start'%(CR, CS), - '15' : ' ╞ Anchor %snot uniq%s: %s'%(CR, CS, value), + '15' : ' ╞ %s%s%s %s'%(CR, lang.anch_nu, CS, value), '16' : ' ╞ %s%s%s "%s = ?"'%(CR, lang.unused_c, CS, value), '17' : ' ╞ %s%s%s "%s ?"'%(CR, lang.unused_v, CS, value), '18' : ' ╘ %s%s%s > %s'%(CR, lang.unused_p, CS, value), @@ -57,6 +57,7 @@ def out(nbr, value, out): '24' : ' ╞ %s%s%s > %s'%(CY, lang.unused_r, CS, value), '25' : ' ╞ Article %snot yet checked%s: %s'%(CY, CS, value), '26' : ' ╞ %sNo index%s article %s'%(CY, CS, value), + '27' : ' ╞ %s%s%s %s'%(CY, lang.snpic_d, CS, value), '28' : ' ╘ %s (%s)'%(lang.ntd, value), '29' : ' ╞ %sEmpty configuration%s %s'%(CY, CS, value), '30' : ' ╞ Article %snot yet wip%s: %s'%(CY, CS, value), diff --git a/src/var/lib/tyto/program/show.py b/src/var/lib/tyto/program/show.py index 63a0cb8..6f7a266 100644 --- a/src/var/lib/tyto/program/show.py +++ b/src/var/lib/tyto/program/show.py @@ -145,7 +145,12 @@ def read_lines(f): if not tyto.exists(f): logs.out("1", f, True) datas = open(f).read() - for line in datas.rsplit('\n'): - print(' │', line) + ln_datas = len(datas.splitlines()) + 1 + sp_max = len(str(ln_datas)) + spaces = '%s'%(sp_max * " ") + for ln, line in enumerate(datas.rsplit('\n'), 1): + sp = sp_max - len(str(ln)) + + print(' │ %s %s│ %s'%(ln, int(sp) * " ", line)) dom.valid() diff --git a/src/var/lib/tyto/program/tyto.py b/src/var/lib/tyto/program/tyto.py index f934bf9..295f4cf 100644 --- a/src/var/lib/tyto/program/tyto.py +++ b/src/var/lib/tyto/program/tyto.py @@ -61,6 +61,40 @@ trans = [ ] +# Needed header tags +needed_header_tags = \ +( +'title', +'about', +'author', +'tags', +'date' +) + +# Optional header tags +opt_header_tags = \ +( +'link', +'image', +'file', +'abbr', +'raw', +'snpic' +) + +opt_tags_long_name = \ +( +'link', +'file' +) + +opt_tags_check_uri = \ +( +'image', +'file', +'raw' +) + # Set all tags used in article's header headers = ( 'title:', diff --git a/src/var/lib/tyto/translations/logs_en.py b/src/var/lib/tyto/translations/logs_en.py index 41340f2..03cbeab 100644 --- a/src/var/lib/tyto/translations/logs_en.py +++ b/src/var/lib/tyto/translations/logs_en.py @@ -41,5 +41,7 @@ unused_v = "Unused value in article" unused_p = "Empty article" mark_np = "Not paired marks" symb_np = "Not paired symbols" +snpic_d = "Using default snpic. Not found" +anch_nu = "Anchor not uniq" laterout = "Maybe later..." diff --git a/src/var/lib/tyto/translations/logs_fr.py b/src/var/lib/tyto/translations/logs_fr.py index f0b184d..bf5ee0b 100644 --- a/src/var/lib/tyto/translations/logs_fr.py +++ b/src/var/lib/tyto/translations/logs_fr.py @@ -41,5 +41,7 @@ unused_v = "Valeur manquante dans l'article" unused_p = "L'article est vide" mark_np = "Marqueurs non jumelés" symb_np = "Symboles non jumelés" +snpic_d = "snpic utilisé par défaut. Manquant" +anch_nu = "Ancre non unique" laterout = "Pour plus tard..."