Commit d2e13b7a authored by Louis's avatar Louis
Browse files

Merge branch 'develop' into jinja2

parents b39a7d7f 0877d049
{
"Arithmetique": "36c89ba9c16cbb81ced232cb1351cf2f",
"ArrondirNombreDecimal": "08996c503f0247ecb648384bb7b2e107",
"CalculMental": "4901e9079081b9e8d7144e68471245f9",
"ClasserNombres": "8585b809a4a76662119cc707e07e7ea5",
"ConstruireZigZag": "70d954ff1917c2325c7361b48d33d159",
"Decomposition": "a46b03497215eef464483cb358979cf6",
"Divisible": "4ff24d8b50e0b398994c64ba547b1e43",
"Droites": "25d39b1644c2ac6eb069c7d01f3bfdca",
"EcrireNombreLettre": "fdc2fe3da7b2f17c85fcc7126deb100d",
"EcritureFractionnaire": "ef797cc813006127ea3685130d39691c",
"Fd1Tangentes": "10ed3a781b3ee3ee8480ed73db2e90c9",
"FractionPartage": "d798dc7ffae542cb6881fd5da25958bb",
"MesureAngles": "d5422b7c1b3a0820ab656ac4dc5dba8b",
"Operations": "e6fa199addd2b8b0805dc02079628521",
"Perpendiculaires": "80dc4d19e3f46d4b2e420dfbea25fa05",
"PlaceVirgule": "dc97d0824aacc0a1b1924eda68d8717f",
"ProduitPuissanceDix": "d5df1cbf4d828411299e3370a1b3243b",
"Proprietes": "3cb11aa523d1fcf2683ea2744c4e5555",
"QuestionsAbscisses": "b7eae0bc7f877a7f620689b3bbfb414b",
"Sd1FormeCanonique": "f78281da5d32e20c7a0d5e300478766f",
"Sd2aRacines": "2f11cef3bc6a29eff021bd1c0fff42b1",
"SymetrieQuadrillage": "f79d5ca772a4840b590d552a27546729",
"TermesDUneSuite": "57f50d6dfdc64550646ec5288f444349",
"Vf1SensEtTableau": "0e6054761005a362c9e97a66c03a0ad7",
"Vf2ExtremaGraphiques": "b8f3ab8cceb2998f0ea9d9b3f7b1c10b",
"Vf3VariationVersCourbe": "460224bf91303cb23d5adb11dcca3d22",
"Vf4ComparerImages": "313503660276fc9ddc2d2b9b5e608e82",
"Vf5Extrema_Tableau": "d58a01457aeee9abe065c660c8bf5003",
"affine": "d59d306c3b583e752abd19973dab1911",
"aires": "d83cd0409cba7b45c4487ec16117f83d",
"calcul_mental": "e94d03eb289969a2d07679a6e9bbde31",
"cercle_trigonometrique": "da12abb4ef0528b9ca79fe357140aa2e",
"distributivite": "ada27ad2c07bd517f4b19750fe4d9389",
"double_distributivite": "45cf4927f68f8ef1740c84ae2d45736a",
"ecr_sc": "5a5b065374a37450c3bbd618d1175b14",
"espace": "77af7781cc2dc667f8e35052b283c6ad",
"exo_aire_diques": "62efe885702214fec795a741913ed30a",
"exo_comptable": "30a8b5439ab6df48a77f4e6dc7f82c98",
"exo_conversion_2d": "a064dd8bb7e13dce00d03d56be30243c",
"exo_conversion_3d": "047731063bbc9a53caeefd1a00504605",
"exo_echelles": "1482f57b6fe6a03a561a35ee5e4eece7",
"exo_factorisation_degre2": "53a1fc07612ec0b6ad754a347846fee0",
"exo_factorisation_degre3": "7797a19025da6c1b2e4909f57a8edf7d",
"exo_puissances": "21719abe190cd965b2b746f0319613b8",
"exo_pythagore": "99e6cab622f2fc16c45312b8b11efd21",
"exo_quadrilatere": "1725e00c7283f71cfea92d4d52c0dea6",
"exo_racines_degre2": "77d067bee4c451d5c58e79809799c14a",
"exo_reciproque_pythagore": "5549bd612d1f35bb6e0aa14fa9e6dc49",
"exo_tableau_de_signe": "09d6318fe54af7e9429e10ba41b4812a",
"exo_thales": "ad9d5f7a260cb0141529fa152066e217",
"exo_triangle": "f531abaf68720c64ba3de011427594ab",
"exo_triangle_cercle": "2aa79f1915225eda7e6e638b6e6b0806",
"exo_trigo": "986315f9428c91ed7423a40547cd2280",
"exo_variation": "9d0afce73694beadc976cd67021e4415",
"exo_variation_lim": "995bf240a3cb41cf1ff10fff02e547fd",
"factorisation": "b6e16e8095c7045b020f15979a7c32bb",
"fractions_egales": "4dc1398258c024c1ed1976f824342ab6",
"id_rem": "85784ea63d773cea50594cd3b25c10d1",
"notion_fonction": "0c475e156e10d2549d078ee98a7954ef",
"priorites": "1a33352c95904a62c89e9ac5422f070e",
"produits_fractions": "1ec8441fa0c2b65e83fc917ba9590c14",
"reduire": "65c4efb0471a98b13b30e5522513da0d",
"relatifs": "eea418bc96bf719a23c5c7aadae5c11e",
"reperage": "e0d249a113d402bd0a03407e238a9266",
"sommes_fractions": "94139621a1435707f3336af0fb84f71a",
"sommes_fractions_positives": "decc495020936524446b548c4e934156",
"soustraction": "23041e0aacb62dc45b7012966161429c",
"statistiques": "596f67893e614e2e4ced4835e4caf826",
"symetrie": "1a76c0c3785736dd183d45c8e1bf5c61",
"tex_equations": "eee1af4b0fb27913c5c5ae8ad9cc491c",
"tex_fractions": "8debaa79c8ac55aac882747ab7bbf441",
"tex_pgcd": "4c0f8d3f07920dc12a6e15925b19aab8",
"tex_proba": "90c77505099e9d2d443b0ca1ea83720d",
"tex_proprietes": "da460f29044d19fa309f7457297af582",
"tex_proprietes_neg": "9f6a3157f590315b06048ca954896d54",
"tex_puissances": "310d7fcc1625b8128fefb6d3b06680c9",
"tex_racines": "9b611486b949464105721e786ac6825a",
"tex_reciproque_thales": "3a00e9ced552c876cd8ea95cd24acdb5",
"tex_systemes": "d9a6be28248a5e7774fed4b4b1029290",
"tex_thales": "a566a9e5e3e1eb4c17afeb30084c999b",
"tex_trigo": "5789554330e12fccd6ca361f731de255",
"tex_units": "a3359aa785f55d89aac533c1e183f802",
"vecteurs_add": "051a8f6a1f76259a37a925bcfdc79ea0"
}
\ No newline at end of file
#!/usr/bin/python
# -*- coding: utf-8 -*-
import os, sys, codecs, shutil, glob
from os.path import dirname, normpath, join, abspath, realpath, split
from subprocess import call, Popen
_path = normpath(join(abspath(dirname(__file__)), "../src"))
sys.path[0] = realpath(_path)
import hashlib
# pylint: disable=invalid-name
"""Crée et met à jour les vignettes des exercices."""
import gettext
import hashlib
import json
import logging
import os
import random
import shutil
import sys
import tempfile
from subprocess import call
from contextlib import contextmanager
# Définition de `_()` comme la fonction identité.
# Pour le moment, les vignettes des exercices ne sont pas traduites.
gettext.install('pyromaths', unicode=1)
ROOTDIR = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir))
PYROMATHSPATH = os.path.join(ROOTDIR, "src")
sys.path.insert(0, os.path.realpath(PYROMATHSPATH))
# pylint: disable=wrong-import-position
import pyromaths
from pyromaths.Values import data_dir, configdir
from pyromaths.outils.System import creation
THUMBDIR = os.path.join(data_dir(), "ex", "img")
MD5PATH = os.path.join(THUMBDIR, "md5sum.json")
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s %(message)s',
)
@contextmanager
def md5file():
"""Contexte pour lire et écrire les md5sum des exercices."""
# Création du fichier s'il n'existe pas déjà.
if not os.path.exists(MD5PATH):
with open(MD5PATH, mode="w") as fichier:
json.dump({}, fichier)
def main():
#===============================================================================
# Imports spécifiques à Pyromaths
#===============================================================================
logging.info("Lecture du fichier '%s'.", MD5PATH)
with open(MD5PATH, mode="r") as fichier:
md5sums = json.loads(fichier.read())
locale_dir = join(dirname(__file__), '../locale/')
locale_dir = realpath(locale_dir)
yield md5sums
gettext.install('pyromaths', localedir=locale_dir, unicode=1)
from pyromaths import pyromaths, ex
from pyromaths.Values import data_dir, configdir
from pyromaths.outils.System import creation
_param = {
logging.info("Écriture du fichier '%s'.", MD5PATH)
with open(MD5PATH, mode="w") as fichier:
json.dump(md5sums, fichier, sort_keys=True, indent=4)
@contextmanager
def create_temp_dir():
"""Contexte pour la création et la suppression du répertoire temporaire."""
name = tempfile.mkdtemp()
yield name
shutil.rmtree(name)
def parametres_exo(exo, tempdir):
"""Renvoit les paramètres de la création d'un unique exercice."""
return {
'creer_pdf': True,
'creer_unpdf': False,
'titre': u"Thumbnail",
'corrige': False,
'niveau': "",
'nom_fichier': u'thumb.tex',
'chemin_fichier': "/tmp/",
'fiche_exo': '/tmp/thumb.tex',
'fiche_cor': '/tmp/thumb-corrige.tex',
'chemin_fichier': tempdir,
'fiche_exo': os.path.join(tempdir, 'thumb.tex'),
'fiche_cor': os.path.join(tempdir, 'thumb-corrige.tex'),
'configdir': configdir(),
'datadir': data_dir(),
'modele': 'pyromaths.tex',
'liste_exos': [],
'openpdf': 0,
'liste_exos': [exo()],
}
def md5check(exercise, imgdir, newfile=None):
''' Check if the file has been changed or renamed. '''
if newfile is None:
newfile = os.path.join(imgdir,'tmp', os.path.basename(exercise.thumb()))
# open md5sums file
md = open(os.path.join(imgdir, 'md5sums'), 'r')
thesum = hashlib.md5(open(newfile, 'rb').read()).hexdigest()
print thesum
originalfile=''
newname=True
for l in md:
if thesum in l:
originalfile=os.path.join(imgdir, l.lstrip(thesum).lstrip())
if os.path.basename(newfile) in l:
newname=False
md.close()
shutil.copyfile(newfile, exercise.thumb())
os.chdir(imgdir)
#raise ValueError('asked to stop')
if originalfile:
if originalfile!=exercise.thumb():
log.write('%s renamed to %s' % (originalfile, exercise.thumb()))
call(['git', 'mv', originalfile, exercise.thumb()], stdout=log)
else:
if newname:
log.write('Created file %s' % (exercise.thumb()))
call(['git', 'add', exercise.thumb()], stdout=log)
else:
log.write('%s replaced by %s' % (originalfile, exercise.thumb()))
os.remove(os.path.join(newfile))
def _thumb(exercise, outfile=None):
''' Create a thumbnail for this 'exercise'. '''
if outfile is None:
print("EXERCICE.THUMB : ",exercise.thumb())
outfile = os.path.join(os.path.dirname(exercise.thumb()), 'tmp', os.path.basename(exercise.thumb()))
print outfile
# create pdf
_param['liste_exos'] = [exercise()]
creation(_param)
# extract optimized thumbnail
call(["convert", "-density", "288", "/tmp/thumb.pdf",
"-resize", "25%", "-crop", "710x560+0+85",
"-flatten", "-trim", "/tmp/thumb.png"],
stdout=log)
call(["pngnq", "-f", "-s1", "-n32", "/tmp/thumb.png"], stdout=log)
log.write(outfile)
shutil.copyfile( "/tmp/thumb-nq8.png", outfile)
call(args=["optipng", "-o7", outfile])
md5check(exercise, os.path.dirname(exercise.thumb()))
def thumbs(pkg=ex, recursive=True):
''' Create all exercise thumbnails. '''
import random
random.seed(0)
imgdir = join(_param['datadir'], 'ex', 'img')
print "IMGDIR : ", imgdir
try:
os.mkdir(os.path.join(imgdir, 'tmp'))
except OSError:
pass
#raise ValueError('voila')
for fl in glob.glob(join(imgdir, "ex-??.png")):
#Do what you want with the file
os.remove(fl)
for e in ex._exercises(pkg):
_thumb(e)
if not recursive: return
try:
os.chdir(imgdir)
mdfile=open('md5sums','w')
for fl in glob.glob(join(imgdir, "ex-??.png")):
#Do what you want with the file
thesum = hashlib.md5(open(fl, 'rb').read()).hexdigest()
mdfile.write(thesum + ' ' + os.path.basename(fl) + '\n')
mdfile.close()
os.rmdir(os.path.join(imgdir, 'tmp'))
except OSError:
pass
for pk in ex._subpackages(pkg):
thumbs(pk)
log = open('/tmp/preview-pyromaths.log' , 'w')
thumbs()
log.close()
def create_thumbnail(exercise, tempdir):
"""Crée la vignette de l'exercice"""
outfile = exercise.thumb()
logging.info("Compilation de l'exercice.")
random.seed(0)
creation(parametres_exo(exercise, tempdir))
logging.info("Extraction de la vignette.")
call([
"convert",
"-density", "288",
os.path.join(tempdir, "thumb.pdf"),
"-resize", "25%",
"-crop", "710x560+0+85",
"-flatten", "-trim",
os.path.join(tempdir, "thumb.png"),
])
logging.info("Appel de `pngnq` sur la vignette.")
call([
"pngnq", "-f", "-s1", "-n32", os.path.join(tempdir, "thumb.png"),
])
shutil.copyfile(os.path.join(tempdir, "thumb-nq8.png"), outfile)
logging.info("Optimisation de la vignette.")
call(args=["optipng", "-o7", outfile])
def md5sum(exo):
"""Calcule et renvoit le hash md5sum de l'énoncé 0 de l'exercice."""
random.seed(0)
return hashlib.md5(
"\n"
.join(exo().tex_statement())
.encode(errors="backslashreplace")
).hexdigest()
def main(tempdir):
"""Fonction principale"""
with md5file() as md5sums:
levels = pyromaths.ex.load_levels()
for level in levels:
for exo in levels[level]:
logging.info("Exercice '%s'.", exo.name())
if md5sums.get(exo.name(), "0") == md5sum(exo):
logging.info("L'exercice n'a pas été modifié.")
continue
create_thumbnail(exo, tempdir)
md5sums[exo.name()] = md5sum(exo)
if __name__ == "__main__":
main()
with create_temp_dir() as temp:
main(temp)
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment