patacrep / patanet

Web interface for LaTeX songbook generation
GNU Affero General Public License v3.0
10 stars 3 forks source link

Trigger generation of PDF file from a list of song files #8

Closed jmclem closed 10 years ago

oliverpool commented 10 years ago

Je pense qu'il faut séparer en deux issues / étapes distinctes :

  1. Créer/modifier les fichier *.sb (faire une classe qui permette de charger un sb et de le sauvegarder en tant que fichier)
  2. Lancer la compilation PDF de ce fichier .sb (<= "juste" un appel système et une redirection)
Luthaf commented 10 years ago

Je suis d'accord. C'est ce qui est dans la feuille de route d'ailleurs. Je veut bien me charger de l'un et de l'autre.

Luthaf commented 10 years ago

Pour la partie création des fichiers .sb, je viens d'envoyer mes commits. Il manque encore les modifications de la liste des chants. Pour éviter d'ouvrir et de fermer le fichier à chaque ajout, je pensais stoker temporairement cette liste dans une session utilisateur. Qu'en pensez-vous ?

Si vous avez des remarques sur ce que j'ai déjà écrit (1c503c6f7007f3ad7e3007b2f354262bddc37983), je prend aussi =)

Luthaf commented 10 years ago

Réorganisation du code de compilation

Pour la partie compilation, j'ai assez violemment réorganisé le code. Il n'y a plus que le moteur dans ma version de la branche next, et ce dernier est organisé sous la forme d'un module python.

Il compile sans problème les songbooks actuels, il ne manque que les partitions lilypond. La chaîne de compilation actuelle est la suivante:

./songbook.py -s /path/to/songbook-options.sb -l /path/to/songs/library/
        -> Génération du fichier .tex
        -> Première compilation en pdf
        -> Génération des fichiers d'index
        -> Seconde compilation en pdf

Là dedans, la génération automatique des images pdf correspondant aux partitions Lilypond peut intervenir à 3 endroits:

PS : jmclem, j'ai rajouté à la main ta gestion d'erreurs, je ne savais pas si le merge automatique allait être possible vu le nombre de fichier que j'ai déplacés.

Améliorer les templates

Je trouve que le système actuel de templates est assez peu intuitif et personnalisable, je pense que ça vaudrait le coup d'utiliser un système de templates plus complet, comme jinja2 par exemple.

Cela permettrai en utilisant un script songbook.py un poil modifié (en fait il ne faut changer que la fonction makeTexFile) d'avoir une bonne compatibilité avec la ligne de commande, et si le client graphique fait appel à cette ligne de commande, avec ce client graphique.

Utiliser un système de templates permettrai alors d'ajouter beaucoup plus facilement des personnalisations au carnet de chant : seul les options et les templates seraient à modifier, et non pas le moteur. Ça permettrai entre autre d'ajouter des options de sections de chant, d'images, ... directement dans la liste des chansons. Cela permettrai aussi de rendre le code plus lisible : actuellement toutes les options sont écrites dans des macros tex qui sont utilisées plus loin.

Qu'en pensez-vous ?

jmclem commented 10 years ago

Je n'ai pas encore jeté un oeil sur tes modifs, mais déjà chapeau pour ton travail ! En ce qui concerne la réorganisation du moteur avec templates, il serait peut-être judicieux d'en débattre sur les forums paracrep, ils ont ferrade un avis et des expériences à partager.

Luthaf commented 10 years ago

Oui, en effet =) Mais ils n'ont pas tout à fait la réactivité que je constate sur GitHub ^^

Je vais ouvrir un sujet.

Luthaf commented 10 years ago

J'ai ajouté la liste des carnets et la vue d'un carnet particulier. Il faut encore récupérer la liste des chants et la lier aux pages correspondante, mais je le ferai après l'ajout de chants aux carnets.

oliverpool commented 10 years ago

J'ai du mal à te suivre quand tu parles de jinja2: "seul les options et les templates seraient à modifier, et non pas le moteur" <= tu as un exemple ? J'ai cru comprendre que ca simplifierait la gestion des formulaires, mais je ne trouve rien de tel sur le site web (donc j'ai du mal comprendre ;-)

Luthaf commented 10 years ago

Je viens de me relire, et je n'était pas très clair ... En fait il y a deux choses à la fois pour les templates :

Un exemple : je veut utiliser un police sans sérif à la place d'une police serif pour mon carnet.

Dans ce cas, le gain n'est pas énorme, mais je trouve que le résultat est plus lisible : les options sont dans le fichier .sb et pas dans le template. Un autre exemple plus pratique : je veux ajouter des sections à mon carnet.

"songs": [ {"sectionname" : "ma section 1",
                 "songs" : ["chant1","chant2","chant3"]
                 },
                 {"sectionname" : "ma section 2",
                 "songs" : ["chant56","chant5","il-pleut-bergere"]
                 }
               ]

et dans le template utilisé je met :

{% for section in songs %}
\songsection{ {{section.sectioname}} }
\begin{songs}
    {% for song in section.songs %}
    \input{ {{song}} }
    {% endfor %}
\end{songs} 
{% endfor %}

Ce qui est encore une fois plus pratique à lire, et surtout plus pratique à modifier. Je peut utiliser le même code de composition du fichier .tex, que j'ai des sections de chants, pas de sections de chants, des versions différentes pour le même chant ou pas, ... Seuls changent les fichiers .sb et les templates.

PS : désolé pour le bloc de texte, je ne voyais pas comment l'expliquer de manière plus synthétique =)

oliverpool commented 10 years ago

ok, donc jinja est vraiment intéressant pour le "moteur patacrep" (et pas vraiment pour le site web) Pour le site web, il faut peut être restructurer les templates pour factoriser du code

Luthaf commented 10 years ago

Ok, une question plus liée au problème des fichiers .sb

Je partait plutôt sur un enregistrement provisoire de la liste des chants dans les sessions de l'utilisateur, et enregistrement final sur le fichiers .sb après action de sa part. Cela permet de modifier rapidement l'ordre des chants, d'ajouter et de supprimer un certain nombre de chants sans avoir à ouvrir puis lire puis écrire puis fermer les fichiers .sb.

En pratique ça vaut le coup si on met les sessions en cache. Qu'en pensez-vous ?

oliverpool commented 10 years ago

Après réflexion, je suis presque partisan de stocker les .sb en BDD :

Avantage : si des fichiers .sg changent de nom/de place, l'id permet toujours de les retrouver !!

oliverpool commented 10 years ago

Du coup ca permet une deuxième chose: les fichiers .sb sont créés uniquement pour la compilation Une fois le pdf compilé, le .sb est supprimé => cela permet d'établir une sorte de liste d'attente (le moteur compile tant qu'il y a des fichiers .sb)

jmclem commented 10 years ago

Je suis aussi pour le stockage principal en bdd (avec lequel nous travaillons dans le cadre de l'app).

Peut-être sera-t-il utile (je n'ai pas encore la réponse) de les exporter dans une repo pour le versionnement et la réplication, mais cela resterait alors une action secondaire.

oliverpool commented 10 years ago

est-ce qu'un versionnement des receuils (fichier .sb) est bien nécéssaire ?

Luthaf commented 10 years ago

Après réflexion, je suis presque partisan de stocker les .sb en BDD

Pourquoi pas, c'est en effet plus pratique pour la liste des chants. Pour les options par-contre, on perd énormément en flexibilité. Si elles sont stockées sous la forme de booléens, on ne peut pas ajouter d'options sans modifier la BDD. Est-ce que vous pensez qu'il serait possible de stocker ces options sous la forme d'une liste dans un CHARFIELD ?

cela permet d'établir une sorte de liste d'attente (le moteur compile tant qu'il y a des fichiers .sb)

Je ne te suit pas là : pour moi il faut lancer n processus de compilations, un pour chaque demande des utilisateurs. Si tu pensais à un deamon qui tourne en tache de fond, ce n'est pas évident, d'autant plus que pdflatex ne peut pas fonctionner en mode deamon.

est-ce qu'un versionnement des receuils (fichier .sb) est bien nécéssaire ?

Je ne pense pas.

jmclem commented 10 years ago

Je ne te suit pas là : pour moi il faut lancer n processus de compilations, un pour chaque demande des utilisateurs.

oui, et on peut le faire sous la forme d'un ajout dans une liste de compilations à effectuer (peu importe la forme de la liste : fichiers dans un répertoire, entrées dans un fichier texte, table en bdd, ...). Cette liste est traitée de manière asynchrone par un processus externe.

Si tu pensais à un deamon qui tourne en tache de fond, ce n'est pas évident, d'autant plus que pdflatex ne peut pas fonctionner en mode deamon.

un process lancé par un cronjob peut le faire aussi.

Luthaf commented 10 years ago

Ok. Mais alors les résultats de compilations ne seraient pas accessibles immédiatement : si par exemple on lance deux fois la compilation par jour, les utilisateurs ne pourront récupérer les PDF que 2 fois par jour.

Ce qui est dommage à mon sens : c'est relativement gênant pour tout ceux qui sont dans une optique "ahhhhh ! j'ai oublié de faire mon carnet pour ce WE !!! Vite, je vais aller sur ce super site dont on m'a parlé pour en faire un vite et bien !" ^^

oliverpool commented 10 years ago

Le cronjob peut tourner toutes les min : si il n'y a rien à compiler, il termine immédiatement.

Ou alors l'utilisateur qui vient de valider son carnet demande régulièrement au serveur (scipt JS toutes les 30s par exemple) l'état de la file d'attente. Quand le serveur reçoit cette demande, il vérifie si il y a une compilation en cours. Si il n'y en a pas il démarre la compilation (asynchrone) sur le premier .sb de la liste d'attente. Une fois le pdf compilé le script JS redirige vers une page permettant de le télécharger.

Luthaf commented 10 years ago

Bon, je lance la modification alors =)

Les recueils seront stockés dans les tables suivante :

Ça vous parait bien comme architecture ? J'ai un peu peur de la taille de la table songs_in_songbookspour ma part ...

oliverpool commented 10 years ago

effectivement, songs_in_songbooks va rapidement grossir, mais il s'agit seulement de numéro (des champs qui prennent pas trop de place normalement)

Luthaf commented 10 years ago

La proposition de champs personnalisés se basant sur SeparatedValuesField repose en fait sur une trop vieille version de Django, en particulier non compatible avec South. Je fait donc des tests avec DjangoToolBox qui propose des ListField et des DictField.

Edit : ça ne fonctionne pas non plus, je crois que les JSONField vont faire mon bonheur (ou peut-être pas ...)

Luthaf commented 10 years ago

Ça marche !!!

Par contre, après m'être arraché les cheveux sur south, j'ai décidé unilatéralement et de manière totalement arbitraire de commencer un nouveau cycle de migrations ! Les anciennes migrations sont dans le dossier old-migrations.

oliverpool commented 10 years ago

(du coup ca rajoute une dépendance, qu'il faudrait mentionner dans le readme) [ou mieux : un fichier requirement.txt via pip freeze]

Luthaf commented 10 years ago

[ou mieux : un fichier requirement.txt via pip freeze]

J'y pensais, mais je ne l'ai pas encore fait.

Edit : Fait ! ceb39d1b70e212fb0f22703a53d67e16ef4bdd09

jmclem commented 10 years ago

Pas de problème pour south, on en n'est qu'au début, c'est bien d'en connaître les limites. On est encore à un stade où une remise à plat de la bdd ne fait pas mal ;) En parlant de South, je rencontre aussi de temps en temps des difficultés pour créer les migrations automatiquement, c'est assez sensible. J'en ai déjà été pour mes frais de coder à la main les deux méthodes forward et backward, ou de bidouiller pour que ça fonctionne.

Luthaf commented 10 years ago

Bon, j'ai continué dans la gestion des carnets de chants : on peut maintenant y ajouter des chants ! (560220464453e3d84f82af94ad21b00cc7218550)

Reste à implémenter :

Pfew, c'est pas encore fini ^^

oliverpool commented 10 years ago

Cool ! J'ai modifié un peu les liens et le "Carnet courant" pour utiliser au mieux tes ajouts de fonctionnalités ! (et j'ai corrigé des petits bugs : 4e2c653 & 1e69464)

Luthaf commented 10 years ago

Le triages des chants dans le carnet

Cette partie a un poil avancée, il faut encore que je vois comment ajouter des chants à une section particulière, et comment ajouter des sections. Du coup, je me pose une question sur le mode d'ajout de chants à une section :

jmclem commented 10 years ago

Je suis partisan de prendre comme base le support de js. La très grande majorité des navigateurs le font aujourd'hui et les utilisateurs y sont habitués.

On 2 février 2014 23:55:01 UTC+01:00, Luthaf notifications@github.com wrote:

Le triages des chants dans le carnet

Cette partie a un poil avancée, il faut encore que je vois comment ajouter des chants à une section particulière, et comment ajouter des sections. Du coup, je me pose une question sur le mode d'ajout de chants à une section :

  • en sélectionnant la section dans la session ? Je ne suis pas pour, c'est plutôt lourd ...
  • en ajoutant un ensemble de <input> liés à chaque section, et avec des sortes de sous-formulaires ? De ce que j'en ai vu, c'est possible en HTML5, mais encore assez peu supporté. Il faudrait donc ajouter du JS. Mais alors quid de ceux qui ne supportent pas JS ?

Reply to this email directly or view it on GitHub: https://github.com/Luthaf/songbook-web/issues/8#issuecomment-33916068

oliverpool commented 10 years ago

J'ai eu une idée radicalement différente pour la gestion des sections : #30

jmclem commented 10 years ago

Je relance la génération des .sg et le lancement de la compilation.

Après avoir fait quelques recherches, il existe déjà des outils qui prennent en charge l'execution de files d'attentes de jobs à executer. Je vois pour l'instant les possibilités suivantes:

  1. à chaque demande de compilation, on fait un appel subprocess.popen ou équivalent
  2. on utilise django background tasks
  3. on utilise Celery
  4. on utilise UWSGI
  5. on utilise Beanstalk

Les 3 derniers sont carréments plus complets. Ils necessitent un messaging système, un démon qui traite les demandes, ... Le premier est un peu simpliste peut-être : c'est à nous de gérer les plantages, ... Je pencherais pour la deuxième solution (django bg tasks) qui me semble un bon compromis pour l'instant. Pour des raisons de performance, il sera peut-être nécessaire de passer sur un des trois derniers, on verra à ce moment là.

Luthaf commented 10 years ago

Je peut déjà lancer une première version avec compilation immédiate, et puis on verra après pour le lancement de compilations en arrière-plan. Je n'ai pas tout compris pour Django bg tasks, mais ça a l'air pas trop mal.

jmclem commented 10 years ago

As tu déjà avancé là dessus? je viens de m'y mettre (création d'un fichier .sb).

Ce que j'ai commencé : ajouter une fonction "get_as_json" dans Songbook qui retourne une chaine json du contenu de fichier .sb.

Mon idée est d'appeler songbook.get_as_json depuis un controlleur qui se charge d'écrire un fichier temporaire et de démarrer un job.

Je ne suis pas encore trop loin, donc si tu as plus, vas-y.

Luthaf commented 10 years ago

Je n'ai rien commencé encore. Toutefois, l'idée et le developpement actuel du songbook-core partait plus sur l'utilisation d'un objet python pour créer un carnet PDF. Il faudrait passer un dictionnaire sb à la fonction buildsongbook(ici).

Donc il suffit de créer ce dictionnaire à partir des attributs de l'objet songbook en fait. Ça permet de ne pas avoir à sérialiser/désérialiser juste pour le plaisir =)

jmclem commented 10 years ago

ok, effectivement, je le fais comme ça alors, merci pour l'info !

jmclem commented 10 years ago

@Luthaf : Arg, de quelle indiscipline je fis preuve... te voyant occupé avec songbook-core et le front-end de songbook-web, et dans l'élan de vouloir faire avancer le schmilblick, voilà t y pas que je m'approprie cette issue, alors qu'elle t'étais assignée, ce que je viens de réaliser. Donc, tu me dis si tu préfères en garder la charge !

Luthaf commented 10 years ago

Que d'élans lyriques ! Vas-y donc, si tu es motivé =) Ça fera en effet avancer le schmilblick, et j'ai assez de trucs à faire pour m'occuper ;-)

jmclem commented 10 years ago

J'ai pushé sur mon clone de la repo les premières modifs (https://github.com/jmclem/songbook-web/commit/292f08b444994acd440ca6a49101ce48d9c74287).

J'adresse un nouvel aspect ici : #36

jmclem commented 10 years ago

Je viens de faire un push (https://github.com/patacrep/songbook-web/commit/8cbfd2328b78c309f6da1ba510dd830924f4752b). Il doit permettre de générer un pdf pour un carnet de chant en appelant l'URL /en/songbooks/<id>/render

Le traitement est asynchrone (il faut démarrer ./manage.py process_tasks dans un autre shell).

En rappelant la page "render", l'info est mise à jour. Quand (si?) le traitement est fini, le lien vers le pdf est proposé.

Lorsqu'un traitement a déjà été effectué pour un carnet, il n'est pas relancé en appelant la page "render". Il faut y adjoindre le paramètre ?force=1 pour relancer la génération.

C'est sans doute pas encore super stable; essayez et dites moi.

Ah, au fait, il vous faudra pip install background_task

oliverpool commented 10 years ago

:+1: (trop déçu de ne pas avoir le temps de tester aujourd'hui... je serai absent et sans internet quasiment jusqu'en avril...)

Luthaf commented 10 years ago

Cool ! Je test tout de suite.

Il doit permettre de générer un pdf pour un carnet de chant en appelant l'URL /en/songbooks/<id>/render

Normalement /fr/songbooks/<id>/render doit marcher aussi.

jmclem commented 10 years ago

Oui, bien sur pour fr.

Tu peux voir le déroulement de la compilation dans la fenêtre shell du process_tasks.

Je croise les doigts....

En passant : rien n'est définitif. Il faudra entre autre se mettre d'accord sur le moyen de donner le PDF à l'utilisateur : lien par mail ? Lien dans le navigateur (comme actuellement) ? Liste des carnets disponibles en PDF?

Luthaf commented 10 years ago

Euh ... Je ne vois rien dans la fenêtre du process_task ... Je vais regarder d'un peu plus près plus tard.

Lien dans le navigateur (comme actuellement) ? Liste des carnets disponibles en PDF?

Je suis pour ces deux là.

jmclem commented 10 years ago

Tu peux vérifier si la génération fonctionne (manage. py buildsongbook <slug>). Il faut aussi migrer la bdd.

Luthaf commented 10 years ago

Ça commence à marcher =) Un problème de configuration différente.

EDIT : c'est bon, ça marche ! Il faut la version next du songbook-core et du songbook-data. C'est trop cool !!!

jmclem commented 10 years ago

Cool :) Je ferme cette issue, nous en ré-ouvrirons pour traiter les problèmes.