print as writing
This commit is contained in:
parent
ac797b7d19
commit
7438c2b6d7
@ -6,39 +6,12 @@ from shutil import rmtree
|
|||||||
|
|
||||||
from spip2md.config import CFG
|
from spip2md.config import CFG
|
||||||
from spip2md.database import DB
|
from spip2md.database import DB
|
||||||
from spip2md.regexmap import SPECIAL_OUTPUT
|
|
||||||
from spip2md.spipobjects import RootRubrique, Rubrique
|
from spip2md.spipobjects import RootRubrique, Rubrique
|
||||||
|
from spip2md.style import BOLD, esc
|
||||||
# Define styles
|
|
||||||
BOLD = 1 # Bold
|
|
||||||
ITALIC = 3 # Italic
|
|
||||||
UNDER = 4 # Underline
|
|
||||||
# Define colors
|
|
||||||
RED = 91 # Red
|
|
||||||
GREEN = 92 # Green
|
|
||||||
YELLOW = 93 # Yellow
|
|
||||||
BLUE = 94 # Blue
|
|
||||||
C0 = 95 # Color
|
|
||||||
C1 = 96 # Color
|
|
||||||
C2 = 96 # Color
|
|
||||||
|
|
||||||
|
|
||||||
# Terminal escape sequence
|
# Count on outputted tree
|
||||||
def esc(*args: int) -> str:
|
def count_output(
|
||||||
if len(args) == 0:
|
|
||||||
params: str = "0;" # Defaults to reset
|
|
||||||
else:
|
|
||||||
params: str = ""
|
|
||||||
# Build a string from args, that will be stripped from its trailing ;
|
|
||||||
for a in args:
|
|
||||||
params += str(a) + ";"
|
|
||||||
# Base terminal escape sequence that needs to be closed by "m"
|
|
||||||
return "\033[" + params[:-1] + "m"
|
|
||||||
|
|
||||||
|
|
||||||
# Print one root section list output correctly
|
|
||||||
# sys.setrecursionlimit(2000)
|
|
||||||
def print_output(
|
|
||||||
tree: list[str | list[str | list]],
|
tree: list[str | list[str | list]],
|
||||||
indent: str = " ",
|
indent: str = " ",
|
||||||
depth: int = -1,
|
depth: int = -1,
|
||||||
@ -47,15 +20,11 @@ def print_output(
|
|||||||
) -> tuple[int, int]:
|
) -> tuple[int, int]:
|
||||||
for sub in tree:
|
for sub in tree:
|
||||||
if type(sub) == list:
|
if type(sub) == list:
|
||||||
branches, leaves = print_output(
|
branches, leaves = count_output(
|
||||||
sub, indent, depth + 1, branches + 1, leaves
|
sub, indent, depth + 1, branches + 1, leaves
|
||||||
)
|
)
|
||||||
elif type(sub) == str:
|
elif type(sub) == str:
|
||||||
leaves += 1
|
leaves += 1
|
||||||
# Highlight special elements (in red for the moment)
|
|
||||||
for elmnt in SPECIAL_OUTPUT:
|
|
||||||
sub = elmnt.sub(esc(BOLD, GREEN) + r"\1" + esc(), sub)
|
|
||||||
print(indent * depth + sub)
|
|
||||||
return (branches, leaves)
|
return (branches, leaves)
|
||||||
|
|
||||||
|
|
||||||
@ -84,12 +53,13 @@ def main(*argv):
|
|||||||
# Get the virtual id=0 section
|
# Get the virtual id=0 section
|
||||||
root: Rubrique = RootRubrique()
|
root: Rubrique = RootRubrique()
|
||||||
|
|
||||||
# Write everything & print the output human-readably
|
# Write everything while printing the output human-readably
|
||||||
branches, leaves = print_output(root.write_tree(CFG.output_dir))
|
branches, leaves = count_output(root.write_tree(CFG.output_dir))
|
||||||
# End, summary message
|
# End, summary message
|
||||||
print(
|
print(
|
||||||
f"""
|
f"""
|
||||||
Exported a total of {leaves} Markdown files, stored into {branches} directories"""
|
Exported a total of {esc(BOLD)}{leaves}{esc()} Markdown files, \
|
||||||
|
stored into {esc(BOLD)}{branches}{esc()} directories"""
|
||||||
)
|
)
|
||||||
|
|
||||||
# print() # Break line between export & unknown characters warning
|
# print() # Break line between export & unknown characters warning
|
||||||
|
@ -260,3 +260,10 @@ SPECIAL_OUTPUT = (
|
|||||||
compile(r"(?<= )(->)(?= )"), # Arrow
|
compile(r"(?<= )(->)(?= )"), # Arrow
|
||||||
compile(r"(?<=^Exporting )([0-9]+?)(?= )"), # Total
|
compile(r"(?<=^Exporting )([0-9]+?)(?= )"), # Total
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Warning elements in terminal output to highlight
|
||||||
|
WARNING_OUTPUT = (
|
||||||
|
compile(r"(ERROR)"), # ERROR
|
||||||
|
compile(r"(MISSING NAME)"), # MISSING NAME
|
||||||
|
compile(r"(NOT FOUND)"), # NOT FOUND
|
||||||
|
)
|
||||||
|
@ -26,9 +26,12 @@ from spip2md.regexmap import (
|
|||||||
ISO_UTF,
|
ISO_UTF,
|
||||||
MULTILANG_BLOCK,
|
MULTILANG_BLOCK,
|
||||||
MULTILANGS,
|
MULTILANGS,
|
||||||
|
SPECIAL_OUTPUT,
|
||||||
SPIP_MARKDOWN,
|
SPIP_MARKDOWN,
|
||||||
UNKNOWN_ISO,
|
UNKNOWN_ISO,
|
||||||
|
WARNING_OUTPUT,
|
||||||
)
|
)
|
||||||
|
from spip2md.style import BLUE, BOLD, GREEN, WARNING_STYLE, YELLOW, esc
|
||||||
|
|
||||||
|
|
||||||
class SpipWritable:
|
class SpipWritable:
|
||||||
@ -38,6 +41,7 @@ class SpipWritable:
|
|||||||
titre: str
|
titre: str
|
||||||
descriptif: str
|
descriptif: str
|
||||||
profondeur: int
|
profondeur: int
|
||||||
|
style: tuple[int, ...]
|
||||||
|
|
||||||
# Returns the first detected language (& instantiate a new object for the second)
|
# Returns the first detected language (& instantiate a new object for the second)
|
||||||
# (currently don’t instantiate, just warns)
|
# (currently don’t instantiate, just warns)
|
||||||
@ -82,6 +86,19 @@ class SpipWritable:
|
|||||||
f"Subclasses need to implement filename(), date: {date}"
|
f"Subclasses need to implement filename(), date: {date}"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Print one or more string(s) in which special elements are stylized
|
||||||
|
def style_print(self, string: str, indent: bool = True, end: str = "\n") -> str:
|
||||||
|
stylized: str = string
|
||||||
|
for o in SPECIAL_OUTPUT:
|
||||||
|
stylized = o.sub(esc(*self.style) + r"\1" + esc(), stylized)
|
||||||
|
for w in WARNING_OUTPUT:
|
||||||
|
stylized = w.sub(esc(*WARNING_STYLE) + r"\1" + esc(), stylized)
|
||||||
|
if indent:
|
||||||
|
stylized = " " * self.profondeur + stylized
|
||||||
|
print(stylized, end=end)
|
||||||
|
# Return the stylized string
|
||||||
|
return stylized
|
||||||
|
|
||||||
def begin_message(self, index: int, limit: int, step: int = 100) -> list[str]:
|
def begin_message(self, index: int, limit: int, step: int = 100) -> list[str]:
|
||||||
output: list[str] = []
|
output: list[str] = []
|
||||||
# Output the remaining number of objects to export every step object
|
# Output the remaining number of objects to export every step object
|
||||||
@ -91,12 +108,16 @@ class SpipWritable:
|
|||||||
output[-1] += f" level {self.profondeur}"
|
output[-1] += f" level {self.profondeur}"
|
||||||
s: str = "s" if limit - index > 1 else ""
|
s: str = "s" if limit - index > 1 else ""
|
||||||
output[-1] += f" {type(self).__name__}{s}"
|
output[-1] += f" {type(self).__name__}{s}"
|
||||||
|
# Print the output as the program goes
|
||||||
|
self.style_print(output[-1])
|
||||||
# Output the counter & title of the object being exported
|
# Output the counter & title of the object being exported
|
||||||
output.append(f"{index + 1}. ")
|
output.append(f"{index + 1}. ")
|
||||||
if len(self.titre) > 0:
|
if len(self.titre) > 0:
|
||||||
output[-1] += self.titre
|
output[-1] += self.titre.strip(" ")
|
||||||
else:
|
else:
|
||||||
output[-1] += "MISSING NAME"
|
output[-1] += "MISSING NAME"
|
||||||
|
# Print the output as the program goes
|
||||||
|
self.style_print(output[-1], end="")
|
||||||
return output
|
return output
|
||||||
|
|
||||||
# Write object to output destination
|
# Write object to output destination
|
||||||
@ -110,10 +131,15 @@ class SpipWritable:
|
|||||||
output: str = " -> "
|
output: str = " -> "
|
||||||
if message is Exception:
|
if message is Exception:
|
||||||
output += "ERROR "
|
output += "ERROR "
|
||||||
|
# Print the output as the program goes
|
||||||
|
self.style_print(output + str(message), indent=False)
|
||||||
return output + str(message)
|
return output + str(message)
|
||||||
|
|
||||||
|
|
||||||
class Document(SpipWritable, SpipDocuments):
|
class Document(SpipWritable, SpipDocuments):
|
||||||
|
# Documents accent color is blue
|
||||||
|
style = (BOLD, BLUE)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
table_name: str = "spip_documents"
|
table_name: str = "spip_documents"
|
||||||
|
|
||||||
@ -277,6 +303,9 @@ class SpipObject(SpipWritable):
|
|||||||
|
|
||||||
|
|
||||||
class Article(SpipObject, SpipArticles):
|
class Article(SpipObject, SpipArticles):
|
||||||
|
# Articles accent color is yellow
|
||||||
|
style = (BOLD, YELLOW)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
table_name: str = "spip_articles"
|
table_name: str = "spip_articles"
|
||||||
|
|
||||||
@ -332,6 +361,9 @@ class Article(SpipObject, SpipArticles):
|
|||||||
|
|
||||||
|
|
||||||
class Rubrique(SpipObject, SpipRubriques):
|
class Rubrique(SpipObject, SpipRubriques):
|
||||||
|
# Sections accent color is green
|
||||||
|
style = (BOLD, GREEN)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
table_name: str = "spip_rubriques"
|
table_name: str = "spip_rubriques"
|
||||||
|
|
||||||
@ -373,6 +405,7 @@ class Rubrique(SpipObject, SpipRubriques):
|
|||||||
output: list[str] = []
|
output: list[str] = []
|
||||||
total = len(objects)
|
total = len(objects)
|
||||||
for i, obj in enumerate(objects):
|
for i, obj in enumerate(objects):
|
||||||
|
obj.profondeur = self.profondeur + 1
|
||||||
for m in obj.begin_message(i, total):
|
for m in obj.begin_message(i, total):
|
||||||
output.append(m)
|
output.append(m)
|
||||||
try:
|
try:
|
||||||
@ -385,7 +418,7 @@ class Rubrique(SpipObject, SpipRubriques):
|
|||||||
output.append(write_loop(documents))
|
output.append(write_loop(documents))
|
||||||
|
|
||||||
# Get all child section of self
|
# Get all child section of self
|
||||||
child_sections = (
|
child_sections: ModelSelect = (
|
||||||
Rubrique.select()
|
Rubrique.select()
|
||||||
.where(Rubrique.id_parent == self.id_rubrique)
|
.where(Rubrique.id_parent == self.id_rubrique)
|
||||||
.order_by(Rubrique.date.desc())
|
.order_by(Rubrique.date.desc())
|
||||||
@ -410,18 +443,20 @@ class RootRubrique(Rubrique):
|
|||||||
|
|
||||||
def write_tree(
|
def write_tree(
|
||||||
self, parent_dir: str, sections_limit: int = 0, articles_limit: int = 0
|
self, parent_dir: str, sections_limit: int = 0, articles_limit: int = 0
|
||||||
) -> list[str | list[Any]]:
|
) -> list[str | list]:
|
||||||
# Define dictionary output to diplay
|
# Define dictionary output to diplay
|
||||||
output: list[str | list[Any]] = []
|
output: list[str | list] = []
|
||||||
# Starting message
|
# Print starting message
|
||||||
output.append(
|
print(
|
||||||
f"""\
|
f"""\
|
||||||
Begin exporting `{CFG.db}@{CFG.db_host}` SPIP database to plain Markdown+YAML
|
Begin exporting {esc(BOLD)}{CFG.db}@{CFG.db_host}{esc()} SPIP database to plain \
|
||||||
files into the directory `{parent_dir}`, as database user `{CFG.db_user}`
|
Markdown+YAML files,
|
||||||
|
into the directory {esc(BOLD)}{parent_dir}{esc()}, \
|
||||||
|
as database user {esc(BOLD)}{CFG.db_user}{esc(BOLD)}
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
# Get all child section of self
|
# Get all child section of self
|
||||||
child_sections = (
|
child_sections: ModelSelect = (
|
||||||
Rubrique.select()
|
Rubrique.select()
|
||||||
.where(Rubrique.id_parent == self.id_rubrique)
|
.where(Rubrique.id_parent == self.id_rubrique)
|
||||||
.order_by(Rubrique.date.desc())
|
.order_by(Rubrique.date.desc())
|
||||||
@ -430,4 +465,5 @@ files into the directory `{parent_dir}`, as database user `{CFG.db_user}`
|
|||||||
# Do the same for subsections (write their entire subtree)
|
# Do the same for subsections (write their entire subtree)
|
||||||
for i, s in enumerate(child_sections):
|
for i, s in enumerate(child_sections):
|
||||||
output.append(s.write_tree(parent_dir, i, nb))
|
output.append(s.write_tree(parent_dir, i, nb))
|
||||||
|
print() # Break line for level 1
|
||||||
return output
|
return output
|
||||||
|
27
spip2md/style.py
Normal file
27
spip2md/style.py
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
# Define styles for terminal printing
|
||||||
|
BOLD = 1 # Bold
|
||||||
|
ITALIC = 3 # Italic
|
||||||
|
UNDER = 4 # Underline
|
||||||
|
# Define colors
|
||||||
|
RED = 91 # Red
|
||||||
|
GREEN = 92 # Green
|
||||||
|
YELLOW = 93 # Yellow
|
||||||
|
BLUE = 94 # Blue
|
||||||
|
C0 = 95 # Color
|
||||||
|
C1 = 96 # Color
|
||||||
|
C2 = 96 # Color
|
||||||
|
# Style used for warnings
|
||||||
|
WARNING_STYLE = (BOLD, RED)
|
||||||
|
|
||||||
|
|
||||||
|
# Terminal escape sequence
|
||||||
|
def esc(*args: int) -> str:
|
||||||
|
if len(args) == 0:
|
||||||
|
params: str = "0;" # Defaults to reset
|
||||||
|
else:
|
||||||
|
params: str = ""
|
||||||
|
# Build a string from args, that will be stripped from its trailing ;
|
||||||
|
for a in args:
|
||||||
|
params += str(a) + ";"
|
||||||
|
# Base terminal escape sequence that needs to be closed by "m"
|
||||||
|
return "\033[" + params[:-1] + "m"
|
Loading…
Reference in New Issue
Block a user