Feat: rewrite produce_and_compile to new in script

This commit is contained in:
Bertrand Benjamin 2019-12-23 18:12:58 +01:00
parent 1ba29c057b
commit d0741b254f
6 changed files with 287 additions and 133 deletions

View File

@ -2,7 +2,7 @@
# encoding: utf-8 # encoding: utf-8
from .bopytex import produce_and_compile #from .bopytex import subject_metadatas, crazy_feed, pdfjoin
# ----------------------------- # -----------------------------

View File

@ -1,103 +0,0 @@
#!/usr/bin/env python
# encoding: utf-8
import click
import logging
from .bopytex import produce_and_compile
formatter = logging.Formatter("%(name)s :: %(levelname)s :: %(message)s")
steam_handler = logging.StreamHandler()
steam_handler.setLevel(logging.DEBUG)
steam_handler.setFormatter(formatter)
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
logger.addHandler(steam_handler)
@click.command()
@click.argument(
"template",
type=click.Path(exists=True),
nargs=1,
#help="File with the template. The name should have the following form tpl_... .",
)
@click.option(
"-w",
"--working-dir",
type=click.Path(exists=True),
help="Where fed templates and compiled files will be placed",
)
@click.option(
"-s",
"--students-csv",
type=str,
default='',
help="CSV containing list of students names",
)
@click.option(
"-d",
"--dirty",
is_flag=True,
default=False,
help="Do not clean after compilation",
)
@click.option(
"-n",
"--no-compile",
is_flag=True,
default=False,
help="Do not compile source code",
)
@click.option(
"-N",
"--number_subjects",
type=int,
default=1,
help="The number of subjects to make",
)
@click.option(
"-j",
"--no-join",
is_flag=True,
default=False,
help="Do not join pdfs to a single pdf and remove individuals",
)
@click.option(
"-O",
"--only-corr",
is_flag=True,
default=False,
help="Create and compile only correction from existing subjects",
)
@click.option(
"-c",
"--corr",
is_flag=True,
default=False,
help="Create and compile correction while making subjects",
)
@click.option(
"-C",
"--crazy",
is_flag=True,
default=False,
help="Crazy mode. Tries and tries again until template feeding success!",
)
def cli(**options):
""" Bopytex
Feed the template (tpl_...) and then compile it with latex.
"""
logger.debug(f"CI parser gets {options}")
produce_and_compile(options)
if __name__ == "__main__":
cli()
# -----------------------------
# Reglages pour 'vim'
# vim:set autoindent expandtab tabstop=4 shiftwidth=4:
# cursor: 16 del

View File

@ -106,7 +106,7 @@ def extract_student_csv(csv_filename):
return [r for r in reader] return [r for r in reader]
def subject_metadata(quantity=0, metacsv=None): def subject_metadatas(options):
""" Return metadata on subject to produce """ Return metadata on subject to produce
if csv is given it will based on is if csv is given it will based on is
@ -115,18 +115,55 @@ def subject_metadata(quantity=0, metacsv=None):
:example: :example:
>>> subject_metadata(10) >>> subject_metadata(10)
""" """
if metacsv: if options["students_csv"]:
metadata = [] metadatas = []
for (i, s) in enumerate(extract_student_csv(metacsv)): for (i, s) in enumerate(extract_student_csv(options["students_csv"])):
d = {"num": f"{i+1:02d}"} d = {"num": f"{i+1:02d}"}
d.update(s) d.update(s)
metadata.append(d) metadatas.append(d)
elif quantity > 0: elif options["number_subjects"] > 0:
metadata = [{"num": f"{i+1:02d}"} for i in range(quantity)] metadatas = [{"num": f"{i+1:02d}"} for i in range(options["number_subjects"])]
else: else:
raise ValueError("Need metacsv or quantity to build subject metadata") raise ValueError("Need metacsv or quantity to build subject metadata")
return metadata for meta in metadatas:
meta.update(
{
"template": str(Path(options["template"]).name),
"texfile": str(Path(options["template"]).name).replace(
"tpl", meta["num"]
),
"directory": str(Path(options["template"]).parent),
}
)
return metadatas
def feed(*args, **kwrds):
""" Nice and smooth pytex feed """
pytex.feed(*args, **kwrds)
def crazy_feed(*args, **kwrds):
""" Crazy mod for pytex feed """
while True:
try:
pytex.feed(*args, **kwrds)
except:
logger.debug(f"Crazy feed is working hard...! {args} {kwrds}")
else:
break
def clean(directory):
pytex.clean(directory)
def texcompile(filename):
logger.debug(f"Start compiling {filename}")
pytex.pdflatex(Path(filename))
logger.debug(f"End compiling")
def produce_and_compile(options): def produce_and_compile(options):
@ -141,9 +178,7 @@ def produce_and_compile(options):
template = Path(options["template"]).name template = Path(options["template"]).name
logger.debug(f"Template will be {template}") logger.debug(f"Template will be {template}")
list_infos = subject_metadata( list_infos = subject_metadatas(options)
options["number_subjects"], options["students_csv"]
)
logger.debug(f"Metadata {list_infos}") logger.debug(f"Metadata {list_infos}")

162
bopytex/script.py Normal file
View File

@ -0,0 +1,162 @@
#!/usr/bin/env python
# encoding: utf-8
import click
import logging
from pathlib import Path
from .bopytex import subject_metadatas, crazy_feed, pdfjoin, feed, clean, texcompile
formatter = logging.Formatter("%(name)s :: %(levelname)s :: %(message)s")
steam_handler = logging.StreamHandler()
steam_handler.setLevel(logging.DEBUG)
steam_handler.setFormatter(formatter)
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
logger.addHandler(steam_handler)
@click.command()
@click.argument(
"template",
type=click.Path(exists=True),
nargs=1,
# help="File with the template. The name should have the following form tpl_... .",
)
@click.option(
"-w",
"--working-dir",
type=click.Path(exists=True),
help="Where fed templates and compiled files will be placed",
)
@click.option(
"-s",
"--students-csv",
type=str,
default="",
help="CSV containing list of students names",
)
@click.option(
"-d", "--dirty", is_flag=True, default=False, help="Do not clean after compilation",
)
@click.option(
"-n",
"--no-compile",
is_flag=True,
default=False,
help="Do not compile source code",
)
@click.option(
"-N",
"--number_subjects",
type=int,
default=1,
help="The number of subjects to make",
)
@click.option(
"-j",
"--no-join",
is_flag=True,
default=False,
help="Do not join pdfs to a single pdf and remove individuals",
)
@click.option(
"-O",
"--only-corr",
is_flag=True,
default=False,
help="Create and compile only correction from existing subjects",
)
@click.option(
"-c",
"--corr",
is_flag=True,
default=False,
help="Create and compile correction while making subjects",
)
@click.option(
"-C",
"--crazy",
is_flag=True,
default=False,
help="Crazy mode. Tries and tries again until template feeding success!",
)
def new(**options):
""" Bopytex
Feed the template (tpl_...) and then compile it with latex.
"""
logger.debug(f"CI parser gets {options}")
template = Path(options["template"]).name
directory = Path(options["template"]).parent
metadatas = subject_metadatas(options)
logger.debug(f"Metadata {metadatas}")
for meta in metadatas:
logger.debug(f"Feeding template toward {meta['texfile']}")
if options["crazy"]:
crazy_feed(
template=Path(meta["directory"]) / meta["template"],
data=meta,
output=meta["texfile"],
force=1,
)
else:
feed(
template=Path(meta["directory"]) / meta["template"],
data=meta,
output=meta["texfile"],
force=1,
)
assert(Path(meta["texfile"]).exists())
logger.debug(f"{meta['texfile']} fed")
if options["corr"]:
logger.debug(f"Building correction for {meta['texfile']}")
meta.update({
"corr_texfile": activate_printanswers(meta["texfile"]),
})
if not options["no_compile"]:
for prefix in ["", "corr_"]:
key = prefix + "texfile"
try:
meta[key]
except KeyError:
pass
else:
texcompile(meta[key])
meta.update({
prefix+'pdffile': meta[key].replace('tex', 'pdf')
})
if not options["no_join"]:
for prefix in ["", "corr_"]:
key = prefix + "pdffile"
try:
pdfs = [m[key] for m in metadatas]
except KeyError:
pass
else:
pdfjoin(
pdfs,
template.replace("tpl", prefix+"all").replace(".tex", ".pdf"),
directory,
rm_pdfs=1,
)
if not options["dirty"]:
clean(directory)
# produce_and_compile(options)
if __name__ == "__main__":
new()
# -----------------------------
# Reglages pour 'vim'
# vim:set autoindent expandtab tabstop=4 shiftwidth=4:
# cursor: 16 del

View File

@ -15,7 +15,7 @@ setup(
'mypytex', 'mypytex',
], ],
entry_points={ entry_points={
"console_scripts": ['bopytex= bopytex.bopytex:main'] "console_scripts": ['bopytex=bopytex.script:new']
}, },
) )

View File

@ -6,7 +6,7 @@ import pytest
import os import os
from pathlib import Path from pathlib import Path
from shutil import copyfile from shutil import copyfile
from bopytex import produce_and_compile from bopytex.bopytex import produce_and_compile, subject_metadatas
SNIPPETS_PATH = Path("snippets/") SNIPPETS_PATH = Path("snippets/")
TEST_PATH = Path("test") TEST_PATH = Path("test")
@ -71,23 +71,83 @@ def test_produce_and_compile_base(prepare_test_template):
def test_produce_and_compile_csv(prepare_test_template): def test_produce_and_compile_csv(prepare_test_template):
test_tpl = list(Path(".").glob("tpl_*.tex")) test_tpl = Path(".").glob("tpl_*.tex")
assert [tpl.name for tpl in test_tpl] == ["tpl_test.tex"]
for tpl in test_tpl: for tpl in test_tpl:
produce_and_compile( options = {
"template": tpl,
"working_dir": None,
"only_corr": False,
"students_csv": "students.csv",
"number_subjects": 1,
"dirty": False,
"no_compile": False,
"no_join": False,
"corr": False,
"crazy": False,
}
# produce_and_compile(options)
def test_metadatas(prepare_test_template):
test_tpl = Path(".").glob("tpl_*.tex")
for tpl in test_tpl:
options = {
"template": tpl,
"working_dir": None,
"only_corr": False,
"students_csv": "students.csv",
"number_subjects": 1,
"dirty": False,
"no_compile": False,
"no_join": False,
"corr": False,
"crazy": False,
}
metadatas = subject_metadatas(options)
meta = [
{ {
"template": tpl, "num": "01",
"working_dir": None, "nom": "Bob",
"only_corr": False, "classe": "1ST",
"students_csv": "students.csv", "elo": "1000",
"number_subjects": 1, "texfile": "01_test.tex",
"dirty": False, "directory": ".",
"no_compile": False, },
"no_join": False, {
"corr": False, "num": "02",
"crazy": False, "nom": "Pipo",
} "classe": "1ST",
) "elo": "1300",
"texfile": "02_test.tex",
"directory": ".",
},
{
"num": "03",
"nom": "Popi",
"classe": "1ST",
"elo": "100",
"texfile": "03_test.tex",
"directory": ".",
},
{
"num": "04",
"nom": "Boule",
"classe": "1ST",
"elo": "4000",
"texfile": "04_test.tex",
"directory": ".",
},
{
"num": "05",
"nom": "Bill",
"classe": "1ST",
"elo": "1300",
"texfile": "05_test.tex",
"directory": ".",
},
]
assert metadatas == meta
def test_pdfjoin_current_directory(prepare_test_template): def test_pdfjoin_current_directory(prepare_test_template):
wdir = prepare_test_template wdir = prepare_test_template
@ -122,7 +182,7 @@ def test_activate_solution():
pass pass
#def test_snippets(prepare_snippets): # def test_snippets(prepare_snippets):
# snippets = list(Path(".").glob("tpl_*.tex")) # snippets = list(Path(".").glob("tpl_*.tex"))
# for tpl in snippets: # for tpl in snippets:
# produce_and_compile( # produce_and_compile(