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
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]
def subject_metadata(quantity=0, metacsv=None):
def subject_metadatas(options):
""" Return metadata on subject to produce
if csv is given it will based on is
@ -115,18 +115,55 @@ def subject_metadata(quantity=0, metacsv=None):
:example:
>>> subject_metadata(10)
"""
if metacsv:
metadata = []
for (i, s) in enumerate(extract_student_csv(metacsv)):
if options["students_csv"]:
metadatas = []
for (i, s) in enumerate(extract_student_csv(options["students_csv"])):
d = {"num": f"{i+1:02d}"}
d.update(s)
metadata.append(d)
elif quantity > 0:
metadata = [{"num": f"{i+1:02d}"} for i in range(quantity)]
metadatas.append(d)
elif options["number_subjects"] > 0:
metadatas = [{"num": f"{i+1:02d}"} for i in range(options["number_subjects"])]
else:
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):
@ -141,9 +178,7 @@ def produce_and_compile(options):
template = Path(options["template"]).name
logger.debug(f"Template will be {template}")
list_infos = subject_metadata(
options["number_subjects"], options["students_csv"]
)
list_infos = subject_metadatas(options)
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',
],
entry_points={
"console_scripts": ['bopytex= bopytex.bopytex:main']
"console_scripts": ['bopytex=bopytex.script:new']
},
)

View File

@ -6,7 +6,7 @@ import pytest
import os
from pathlib import Path
from shutil import copyfile
from bopytex import produce_and_compile
from bopytex.bopytex import produce_and_compile, subject_metadatas
SNIPPETS_PATH = Path("snippets/")
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):
test_tpl = list(Path(".").glob("tpl_*.tex"))
assert [tpl.name for tpl in test_tpl] == ["tpl_test.tex"]
test_tpl = Path(".").glob("tpl_*.tex")
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,
"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,
}
)
"num": "01",
"nom": "Bob",
"classe": "1ST",
"elo": "1000",
"texfile": "01_test.tex",
"directory": ".",
},
{
"num": "02",
"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):
wdir = prepare_test_template
@ -122,7 +182,7 @@ def test_activate_solution():
pass
#def test_snippets(prepare_snippets):
# def test_snippets(prepare_snippets):
# snippets = list(Path(".").glob("tpl_*.tex"))
# for tpl in snippets:
# produce_and_compile(