[mail] Début de templating, internationalisation, html et plain text
le corps du message est régigé en markdown <http://daringfireball.net/projects/markdown/syntax> que l'on utilise ensuite pour générer à la fois le plain text du message et la partie html. On a donc besoin du module python markdown packagé dans python-markdown. Les headers sont en plain text. On utilise jinja2 comme moteur de template (le même que celui de django) Le mail de bienvenue est là en exemple.
This commit is contained in:
parent
cbbf060fb2
commit
bde23e7ca2
8 changed files with 199 additions and 0 deletions
90
gestion/mail/mail.py
Normal file
90
gestion/mail/mail.py
Normal file
|
@ -0,0 +1,90 @@
|
|||
#! /usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import os
|
||||
import jinja2
|
||||
import sys
|
||||
from email.header import Header
|
||||
from email.message import Message
|
||||
from email.mime.multipart import MIMEMultipart
|
||||
from email.mime.text import MIMEText
|
||||
from markdown import markdown
|
||||
|
||||
sys.path.append('/usr/scripts/')
|
||||
from gestion.email_tools import format_sender
|
||||
sys.path.pop()
|
||||
|
||||
default_language = 'fr'
|
||||
template_path = '/usr/scripts/gestion/mail/template/'
|
||||
html_template = template_path + 'html'
|
||||
html_mutilang_template = template_path + 'html_multilang'
|
||||
text_mutilang_template = template_path + 'text_multilang'
|
||||
|
||||
templateLoader = jinja2.FileSystemLoader( searchpath=["/", template_path] )
|
||||
templateEnv = jinja2.Environment( loader=templateLoader )
|
||||
|
||||
|
||||
### For an example:
|
||||
### print generate('bienvenue', {'From':'respbats@crans.org', 'To':'admin@genua.fr', 'lang_info':'English version below'}).as_string()
|
||||
|
||||
|
||||
def submessage(playload, type, charset='utf-8'):
|
||||
"""Renvois un sous message à mettre dans un message multipart"""
|
||||
submsg=MIMEText('', type, charset)
|
||||
del(submsg['Content-Transfer-Encoding'])
|
||||
submsg['Content-Transfer-Encoding']='8bit'
|
||||
submsg.set_payload(playload)
|
||||
return submsg
|
||||
|
||||
def htmlmultilang(mail, lang1, lang2, params, lang_info='', charset='utf-8'):
|
||||
"""Génère un html bilingue"""
|
||||
file1 = template_path + mail + '/body/' + lang1
|
||||
file2 = template_path + mail + '/body/' + lang2
|
||||
if lang1 == lang2 or not os.path.isfile(file2):
|
||||
txt = templateEnv.get_template(file1).render(params)
|
||||
html = templateEnv.get_template(html_template).render({'body': markdown(txt)})
|
||||
return submessage(html.encode(charset), 'html', charset)
|
||||
else:
|
||||
txt1 = templateEnv.get_template(file1).render(params)
|
||||
txt2 = templateEnv.get_template(file2).render(params)
|
||||
params.update({'lang1':lang1, 'lang2':lang2, 'body1': markdown(txt1), 'body2':markdown(txt2)})
|
||||
html = templateEnv.get_template(html_mutilang_template).render(params)
|
||||
return submessage(html.encode(charset), 'html', charset)
|
||||
|
||||
def textmultilang(mail, lang1, lang2, params, charset='utf-8'):
|
||||
"""Génère un plain text bilingue"""
|
||||
file1 = template_path + mail + '/body/' + lang1
|
||||
file2 = template_path + mail + '/body/' + lang2
|
||||
if lang1 == lang2 or not os.path.isfile(file2):
|
||||
txt = templateEnv.get_template(file1).render(params)
|
||||
return submessage(txt.encode(charset), 'plain', charset)
|
||||
else:
|
||||
txt1 = templateEnv.get_template(file1).render(params)
|
||||
txt2 = templateEnv.get_template(file2).render(params)
|
||||
params.update({'body1': txt1, 'body2':txt2})
|
||||
txt = templateEnv.get_template(text_mutilang_template).render(params)
|
||||
return submessage(txt.encode(charset), 'plain', charset)
|
||||
|
||||
def generate(mail, params, lang=default_language, lang_fallback=default_language, lang_alt='en', charset='utf-8'):
|
||||
"""Génère un message multipart"""
|
||||
msg = MIMEMultipart('alternative')
|
||||
if os.path.isdir(template_path + mail):
|
||||
for filename in [dir for dir in os.listdir(template_path + mail) if os.path.isdir(template_path + mail + '/' + dir)]:
|
||||
if os.path.isfile(template_path + mail + '/' + filename + '/' + lang):
|
||||
lang_tmp = lang
|
||||
file = template_path + mail + '/' + filename + '/' + lang
|
||||
else:
|
||||
lang_tmp = lang_fallback
|
||||
file = template_path + mail + '/' + filename + '/' + lang_tmp
|
||||
|
||||
if filename == 'body':
|
||||
msg.attach(textmultilang(mail, lang_tmp, lang_alt, params, charset))
|
||||
msg.attach(htmlmultilang(mail, lang_tmp, lang_alt, params, charset))
|
||||
else:
|
||||
txt = templateEnv.get_template(file).render(params)
|
||||
if filename in ['From', 'To', 'Cc', 'Bcc']:
|
||||
msg[filename] = format_sender(txt, charset)
|
||||
else:
|
||||
msg[filename]=Header(txt.encode(charset), charset)
|
||||
|
||||
return msg
|
1
gestion/mail/template/bienvenue/From/fr
Normal file
1
gestion/mail/template/bienvenue/From/fr
Normal file
|
@ -0,0 +1 @@
|
|||
Crans <{{From}}>
|
1
gestion/mail/template/bienvenue/Subject/fr
Normal file
1
gestion/mail/template/bienvenue/Subject/fr
Normal file
|
@ -0,0 +1 @@
|
|||
[CRANS] Bienvenue au Cr@ns !
|
1
gestion/mail/template/bienvenue/To/fr
Normal file
1
gestion/mail/template/bienvenue/To/fr
Normal file
|
@ -0,0 +1 @@
|
|||
{{To}}
|
67
gestion/mail/template/bienvenue/body/fr
Normal file
67
gestion/mail/template/bienvenue/body/fr
Normal file
|
@ -0,0 +1,67 @@
|
|||
Bienvenue !
|
||||
===========
|
||||
|
||||
Si tu lis ce mail, c'est que ton inscription à l'association
|
||||
s'est déroulée correctement.
|
||||
|
||||
Le Cr@ns est une association gérée par des étudiants bénévoles pour les
|
||||
étudiants résidant sur le campus.
|
||||
|
||||
Ses membres actifs s'occupent de la maintenance du réseau, des adhésions
|
||||
(câblages), ainsi que de plusieurs services mis à la disposition de tous ses
|
||||
adhérents :
|
||||
|
||||
* La connexion à Internet en filaire et en wifi [1] ;
|
||||
* Un wiki, regroupant plein d'informations diverses concernant la vie ici [2] ;
|
||||
* Les news, fora de discussion abordant divers thèmes [3] ;
|
||||
* Un serveur IRC [4] ;
|
||||
* Un serveur de messagerie instantanée Jabber [5] ;
|
||||
* Un service de messagerie : une adresse mail @crans.org disponible à vie,
|
||||
fiable, et avec possibilité d'installer des filtres très précis [6] ;
|
||||
* Un espace personnel de **2Go** sur le serveur des adhérents [7] ;
|
||||
* Un service d'impression, 24h/24 7j/7, A3 ou A4, couleur ou noir et blanc,
|
||||
avec ou sans agrafe, à prix coûtant [8] ;
|
||||
* La télévision par le réseau [9].
|
||||
|
||||
Afin d'assurer le bon fonctionnement de ces services, il est
|
||||
nécessaire que chaque membre respecte du règlement intérieur [10] accepté lors
|
||||
de son inscription.
|
||||
|
||||
|
||||
La notice d'utilisation des services du CR@NS est disponible à cette adresse :
|
||||
<https://wiki.crans.org/CransPratique>. Nous conseillons vivement de s'y
|
||||
reporter aussi bien pour apprendre à utiliser les différents services que pour
|
||||
résoudre les problèmes éventuellement rencontrés.
|
||||
|
||||
Chaque membre intéressé par le fonctionnement de l'association peut contacter
|
||||
l'équipe technique à <nounous@crans.org> ou l'équipe administrative à
|
||||
<ca@crans.org> et/ou se rendre aux réunions publiques du Cr@ns [11].
|
||||
|
||||
**Aucune connaissance technique préalable n'est requise pour participer !**
|
||||
|
||||
**A noter** : l'accès sans authentification aux news et au wiki est limité à
|
||||
un usage interne au campus.
|
||||
|
||||
* Pour accéder depuis l'extérieur au wiki, il faut se créer un compte [12].
|
||||
* Pour accéder depuis l'extérieur aux news, il faut s'identifier
|
||||
(Utilisateur : Vivelapa / Mot de passe : ranoia!)
|
||||
|
||||
|
||||
--
|
||||
|
||||
Les membres actifs.
|
||||
|
||||
[1]: <https://wiki.crans.org/WiFi>
|
||||
[2]: <https://wiki.crans.org>
|
||||
[3]: <https://wiki.crans.org/VieCrans/ForumNews>
|
||||
[4]: <https://wiki.crans.org/VieCrans/UtiliserIrc>
|
||||
[5]: <https://wiki.crans.org/VieCrans/UtiliserJabber>
|
||||
[6]: <https://wiki.crans.org/VieCrans/LesMails>
|
||||
[7]: <https://wiki.crans.org/VieCrans/GestionCompte>
|
||||
[8]: <https://wiki.crans.org/VieCrans/ImpressionReseau>
|
||||
[9]: <https://wiki.crans.org/TvReseau>
|
||||
[10]: <https://wiki.crans.org/CransAdministratif/R%C3%A8glementInt%C3%A9rieur>
|
||||
[11]: <https://wiki.crans.org/CompteRendusCrans>
|
||||
[12]: <http://wiki.crans.org/?action=newaccount>
|
||||
|
||||
PS: Il t'est conseillé de conserver ce mail à toutes fins utiles
|
15
gestion/mail/template/html
Normal file
15
gestion/mail/template/html
Normal file
|
@ -0,0 +1,15 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta http-equiv="Content-Style-Type" content="text/css" />
|
||||
<meta name="generator" content="pandoc" />
|
||||
<title></title>
|
||||
<style type="text/css">code{white-space: pre;}body{max-width: 55em;text-align:justify;}</style>
|
||||
</head>
|
||||
<body>
|
||||
{% block body %}
|
||||
{{body}}
|
||||
{% endblock %}
|
||||
</body>
|
||||
</html>
|
13
gestion/mail/template/html_multilang
Normal file
13
gestion/mail/template/html_multilang
Normal file
|
@ -0,0 +1,13 @@
|
|||
{% extends "html" %}
|
||||
{% block body %}
|
||||
|
||||
<p>{{lang_info}}</p>
|
||||
|
||||
<div lang="{{lang1}}">
|
||||
{{body1}}
|
||||
</div>
|
||||
<hr/>
|
||||
<div lang="{{lang2}}">
|
||||
{{body2}}
|
||||
</div>
|
||||
{% endblock %}
|
11
gestion/mail/template/text_multilang
Normal file
11
gestion/mail/template/text_multilang
Normal file
|
@ -0,0 +1,11 @@
|
|||
{{lang_info}}
|
||||
|
||||
|
||||
{{body1}}
|
||||
|
||||
|
||||
================================================================================
|
||||
|
||||
|
||||
{{body2}}
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue