Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 16/10/2016, à 16:20

JujuLand

Outil de sauvegarde de mail en pdf + pièces jointes

Ayant eu à enregistrer en pdf (mode texte) des mails de fichier mbox et à en extraire les pièces jointes, j'ai été amené à modifier le script python 'mbox-extract-attachments' de Pablo Castellano datant de 2012 et qui ne faisait que l'extraction.

Comme le copier/coller semble mettre l'indentation en vrac, ce qui est catastrophisue, je mets ici le lien de l'archive.

Version: 1.50 du 13/11/2016
Principales caractéristiques:

- Décodage des mails, sujets, destinaitaires (to et cc) encodés en ISO-8859-1 ou UTF-8 et html
- Enregistrement des mails en pdf, avec le sujet du mail dans le nom de fichier, avec gestion des sujets identiques pour ne pas écraser un pdf par un autre. ( Exemple : Mail_sujet_du_mail.pdf.1 ).
- Le pdf comporte en outre la liste des pièces jointes cliquables ou non.
- Enregistrement des pièces jointes avec gestion des pièces ayant un nom identique.
- Les pièces et mails sont enregistrés dans le même dossier.
- Liens mailto de From, To, Cc cliquables.
- les messages sont en couleur pour une meilleure lisibilité.
- Possibilité de remplacer dans le dossier target, le nom du user pour faire des traitements sur un ordi autre que celui de destination ou pour générer un pdf avec un user différent (voir dans le README de l'archive, l'utilisation de ce paramètre).
- Fichier de configuration gérant les paramètres par défaut:
     - l'utilisation ou non du paramètre du chemin d'accès au fichier mbox
     - l'utilisation ou non du paramètre du chemin de destination
     - la génération ou non des liens cliquables
     - le type de traitement à exécuter
     - la création automatique ou non du dossier target
     - le nettoyage des accents dans le nom du dossier target
     - le chemin d'accès au fichier mbox
     - le chemin de destination du traitement
     - le nom de user à spécifier dans les liens
     - le chemin de destination des logs

Exemple de fichier config qui s'appelle .mbox2pdf et se situe dans le dossier utilisateur

auto_mbox=1
auto_target=1
no_accent=1
auto_create=1
link_att=1
treat=tout
mbox_path=/home/alain/.thunderbird/crtothve.default/Mail/Local Folders/Archives.sbd/
target_path=/home/alain/Bureau/Archives_GADEL/split/
move_user=gadel
log_path=/home/alain/Bureau/logs/

Remarques concernant ce fichier:
    - le fichier peut être absent.
    - l'ordre des lignes est figé et doit être celui présenté dans l'exemple
    - chaque ligne peut être vide ou absente, mais les lignes 1 à 4 doivent toujours précéder les chemins (lignes 7 et 8)
    - les valeurs de treat sont les suivantes : pdf / att / tout (en minuscule)
    - mbox_path, target_path et log_path doivent être terminés par un slash (/)
    - move_user permet de générer pour un autre utilisateur (remplacement dans les liens)
    - auto_create crée le dossier target si nécessaire, pour ne plus avoir à le créer avant utilisation
    - no_accent nettoie le nom du répertoire target de ses accents pour avoir des liens cliquables dans les pdf
    - seule la valeur de treat peut être modifiée en ligne de commande
    - dans le cas d'absence de ligne ou carremment de fichier les valeurs par défaut sont les suivantes:
        - auto_mbox   => 0
        - auto_target   => 0
        - no_accent    => 0
        - auto_create  => 0
        - link_att         => 0
        - treat             => att
        - mbox_path   => ""
        - target_path  => ""
        - move_user   => ""

Source du script:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# mbox-extract-attachments.py - Extract attachments from mbox files - 16/March/2012
# Copyright (C) 2012 Pablo Castellano <pablo@anche.no>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#

# Notes (RFC 1341):
# The use of a Content-Type of multipart in a body part within another multipart entity is explicitly allowed.
#     In such cases, for obvious reasons, care must be taken to ensure that each nested multipart entity must
#     use a different boundary delimiter. See Appendix C for an example of nested multipart entities. 
# The use of the multipart Content-Type with only a single body part may be useful in certain contexts, and is
#     explicitly permitted. 
# The only mandatory parameter for the multipart Content-Type is the boundary parameter, which consists of 1 to 70
#     characters from a set of characters known to be very robust through email gateways, and NOT ending with white
#     space. (If a boundary appears to end with white space, the white space must be presumed to have been added by
#     a gateway, and should be deleted.) It is formally specified by the following BNF

# Related RFCs: 2047, 2044, 1522


__author__ = "Pablo Castellano <pablo@anche.no>"
__license__ = "GNU GPLv3+"
__version__ = 1.2
__date__ = "12/04/2012"
__extend_author__ = "Alain Aupeix <alain.aupeix@wanadoo.fr>"
__extended__ = 1.50
__extend_date__ = "13/11/2016"

import mailbox
import base64
import os
import sys
import email
import subprocess
import string
from string import upper
import re
from reportlab.lib.pagesizes import A4
from reportlab.lib.units import cm
from reportlab.platypus import Paragraph, SimpleDocTemplate, Spacer
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.lib.styles import ParagraphStyle
from reportlab.pdfbase import pdfmetrics

# Normal
gBla = '\033[1;30m'
gRed = '\033[1;31m'
gGre = '\033[1;32m'
gYel = '\033[1;33m'
gBlu = '\033[1;34m'
gMag = '\033[1;35m'
gCya = '\033[1;36m'
gWhi = '\033[1;37m'
# Sans couleur
noColor = '\033[0m'


BLACKLIST = ('signature.asc', 'message-footer.txt', 'smime.p7s')
VERBOSE = 1

attachments = 0 #Count extracted attachment
skipped = 0

###################################################################################
def Join_line(texte):
###################################################################################
	texte=re.sub("\r","",texte)
	texte=re.sub("\n","",texte)
	texte=re.sub("\?= =\?UTF-8\?Q\?","",texte)
	texte=re.sub("\?= =\?utf-8\?q\?","",texte)
	texte=re.sub("\?= =\?utf-8\?Q\?","",texte)
	texte=re.sub("\?= =\?UTF-8\?B\?","",texte)
	texte=re.sub("\?= =\?utf-8\?b\?","",texte)
	texte=re.sub("\?= =\?utf-8\?B\?","",texte)
	texte=re.sub("\?= =\?ISO-8859-1\?Q\?","",texte)
	texte=re.sub("\?= =\?iso-8859-1\?q\?","",texte)
	texte=re.sub("\?= =\?iso-8859-1\?Q\?","",texte)
	texte=re.sub("\?= =\?ISO-8859-1\?B\?","",texte)
	texte=re.sub("\?= =\?iso-8859-1\?b\?","",texte)
	texte=re.sub("\?= =\?iso-8859-1\?B\?","",texte)
	texte=re.sub("\?= =\?ISO-8859-15\?Q\?","",texte) 
	texte=re.sub("\?= =\?iso-8859-15\?Q\?","",texte) 
	texte=re.sub("\?= =\?ISO-8859-15\?q\?","",texte) 
	texte=re.sub("\?= =\?iso-8859-15\?q\?","",texte) 
	texte=re.sub("\?= =\?windows-1252\?Q\?","",texte)
	texte=re.sub("\?= =\?Windows-1252\?Q\?","",texte)
	texte=re.sub("\?= =\?windows-1256\?Q\?","",texte)
	texte=re.sub("\?= =\?windows-1258\?Q\?","",texte)

	return texte        

###################################################################################
def Clean_codage(texte):
###################################################################################
        texte=re.sub("\n  ","",texte)
        texte=re.sub("\n ","",texte)

	texte=re.sub("=\?utf-8\?q\?","",texte)
	texte=re.sub("=\?utf-8\?Q\?","",texte)
	texte=re.sub("=\?UTF-8\?Q\?","",texte)
	texte=re.sub("=\?iso-8859-1\?q\?","",texte)
	texte=re.sub("=\?iso-8859-1\?Q\?","",texte)
	texte=re.sub("=\?ISO-8859-1\?Q\?","",texte)
	texte=re.sub("=\?ISO-8859-15\?Q\?","",texte) 
	texte=re.sub("=\?Windows-1252\?Q\?","",texte)
	texte=re.sub("=\?windows-1252\?Q\?","",texte)
	texte=re.sub("=\?windows-1256\?Q\?","",texte)
	texte=re.sub("=\?Windows-1256\?Q\?","",texte)
	texte=re.sub("=\?windows-1258\?Q\?","",texte)
	texte=re.sub("=\?Windows-1258\?Q\?","",texte)

	texte=re.sub("=C3=80","A",texte)
	texte=re.sub("=C3=81","A",texte)
	texte=re.sub("=C3=82","A",texte)
	texte=re.sub("=C3=83","A",texte)
	texte=re.sub("=C3=84","A",texte)
	texte=re.sub("=C3=85","A",texte)
	texte=re.sub("=C3=86","Ae",texte)
	texte=re.sub("=C3=87","C",texte)
	texte=re.sub("=C3=88","E",texte)
	texte=re.sub("=C3=89","E",texte)
	texte=re.sub("=C3=8a","E",texte)
	texte=re.sub("=C3=8b","E",texte)
	texte=re.sub("=C3=8C","I",texte)
	texte=re.sub("=C3=8D","I",texte)
	texte=re.sub("=C3=8E","I",texte)
	texte=re.sub("=C3=8F","I",texte)
	texte=re.sub("=C3=91","N",texte)
	texte=re.sub("=C3=92","O",texte)
	texte=re.sub("=C3=93","O",texte)
	texte=re.sub("=C3=94","O",texte)
	texte=re.sub("=C3=95","O",texte)
	texte=re.sub("=C3=96","O",texte)
	texte=re.sub("=C3=99","U",texte)
	texte=re.sub("=C3=9A","U",texte)
	texte=re.sub("=C3=9B","U",texte)
	texte=re.sub("=C3=9C","U",texte)
	texte=re.sub("=C3=9D","Y",texte)
	texte=re.sub("=C3=A0","a",texte)
	texte=re.sub("=c3=a0","a",texte)
	texte=re.sub("=C3=A1","a",texte)
	texte=re.sub("=C3=A2","a",texte)
	texte=re.sub("=C3=A3","a",texte)
	texte=re.sub("=C3=A4","a",texte)
	texte=re.sub("=C3=A5","a",texte)
	texte=re.sub("=C3=A7","c",texte)
	texte=re.sub("=C3=A8","e",texte)
	texte=re.sub("=C3=A9","e",texte)
	texte=re.sub("=c3=a9","e",texte)
	texte=re.sub("=C3=AA","e",texte)
	texte=re.sub("=C3=AB","e",texte)
	texte=re.sub("=C3=AC","ì",texte)
	texte=re.sub("=C3=AD","i",texte)
	texte=re.sub("=C3=AE","i",texte)
	texte=re.sub("=C3=AF","i",texte)
	texte=re.sub("=C3=B1","n",texte)
	texte=re.sub("=C3=B2","o",texte)
	texte=re.sub("=C3=B3","o",texte)
	texte=re.sub("=C3=B4","o",texte)
	texte=re.sub("=C3=B5","o",texte)
	texte=re.sub("=C3=B6","o",texte)
	texte=re.sub("=C3=B9","u",texte)
	texte=re.sub("=C3=BA","u",texte)
	texte=re.sub("=C3=BB","u",texte)
	texte=re.sub("=C3=BC","u",texte)
	texte=re.sub("=C3=BD","y",texte)
	texte=re.sub("=C3=BF","ÿ",texte)

	texte=re.sub("=0A"," ",texte)
	texte=re.sub("=20"," ",texte)
	texte=re.sub("=21"," ",texte)
	texte=re.sub("=22"," ",texte)
	texte=re.sub("=26"," ",texte)
	texte=re.sub("=27"," ",texte)
	texte=re.sub("=28","[",texte)
	texte=re.sub("=29","]",texte)
	texte=re.sub("=2D",".",texte)
	texte=re.sub("=2E"," ",texte)
	texte=re.sub("=3A"," ",texte)
	texte=re.sub("=3B"," ",texte)
	texte=re.sub("=3D"," ",texte)
	texte=re.sub("=3E"," ",texte)
	texte=re.sub("=3F"," ",texte)
	texte=re.sub("=5D"," ",texte)
	texte=re.sub("=5F"," ",texte)
	texte=re.sub("=92"," ",texte) 
	texte=re.sub("=B0","]",texte) 
	texte=re.sub("=AB","[",texte) 
	texte=re.sub("=BB","]",texte) 
	texte=re.sub("=A0"," ",texte) 
	texte=re.sub("=AC"," ",texte) 
	texte=re.sub("=C0","A",texte)
	texte=re.sub("=C1","A",texte)
	texte=re.sub("=C2","A",texte)
	texte=re.sub("=C3","A",texte)
	texte=re.sub("=C4","A",texte)
	texte=re.sub("=C5","A",texte)
	texte=re.sub("=C7","C",texte)
	texte=re.sub("=C8","E",texte)
	texte=re.sub("=C9","E",texte)
	texte=re.sub("=CA","E",texte)
	texte=re.sub("=CB","E",texte)
	texte=re.sub("=CC","I",texte)
	texte=re.sub("=CD","I",texte)
	texte=re.sub("=CE","I",texte)
	texte=re.sub("=CF","I",texte)
	texte=re.sub("=D1","N",texte)
	texte=re.sub("=D2","O",texte)
	texte=re.sub("=D3","O",texte)
	texte=re.sub("=D4","O",texte)
	texte=re.sub("=D5","O",texte)
	texte=re.sub("=D6","O",texte)
	texte=re.sub("=D9","U",texte)
	texte=re.sub("=DA","U",texte)
	texte=re.sub("=DB","U",texte)
	texte=re.sub("=DC","U",texte)
	texte=re.sub("=DD","Y",texte)
	texte=re.sub("=E0","a",texte)
	texte=re.sub("=E1","a",texte)
	texte=re.sub("=E2","a",texte)
	texte=re.sub("=E3","a",texte)
	texte=re.sub("=E4","a",texte)
	texte=re.sub("=E5","a",texte)
	texte=re.sub("=E7","c",texte)
	texte=re.sub("=E8","e",texte)
	texte=re.sub("=E9","e",texte)
	texte=re.sub("=EA","e",texte)
	texte=re.sub("=EB","e",texte)
	texte=re.sub("=EC","i",texte)
	texte=re.sub("=ED","i",texte)
	texte=re.sub("=EE","i",texte)
	texte=re.sub("=EF","i",texte)
	texte=re.sub("=F1","n",texte)
	texte=re.sub("=F2","o",texte)
	texte=re.sub("=F3","o",texte)
	texte=re.sub("=F4","o",texte)
	texte=re.sub("=F5","o",texte)
	texte=re.sub("=F6","o",texte)
	texte=re.sub("=F9","u",texte)
	texte=re.sub("=FA","u",texte)
	texte=re.sub("=FB","u",texte)
	texte=re.sub("=FC","u",texte)
	texte=re.sub("=FD","y",texte)
	texte=re.sub("=FF","ÿ",texte)
	texte=re.sub("=3F","?",texte)
        texte=re.sub("=3A","_",texte)
	texte=re.sub("=2C",",",texte)
	texte=re.sub("=2F","",texte)
	texte=re.sub("\?=","",texte)

	if texte.find("?Q?") != -1 :
	        if re.search("@",texte) is not None and ( re.search("\"",texte) is not None or re.search("'",texte) is not None ):
			texte=re.sub("\"","",texte)
			texte=re.sub("'","",texte)
	if element == "subject" :
		texte=re.sub("/","_",texte)
		texte=re.sub(":","_",texte)
		texte=re.sub("&eacute","é",texte)
		texte=re.sub(" utf-8 Q","",texte)
           
	texte=re.sub("\xc2\x80","euro",texte)
	texte=re.sub("\xc2\x92","'",texte)
	texte=re.sub("\xc2\x96","_",texte)
	texte=re.sub("\xc2\x9c","oe",texte)

	return texte        

###################################################################################
def decode_ansi(texte):
###################################################################################
	texte=re.sub("\x80","",texte)
	texte=re.sub("\x85","",texte)
	texte=re.sub("\x94",'"',texte)
	texte=re.sub("\x93",'"',texte)
	texte=re.sub("\x9c",'oe',texte)
	texte=re.sub("\x99",'',texte)
	texte=re.sub("\xa0","",texte)
	texte=re.sub("\xa6","",texte)
	texte=re.sub("\xb0","'",texte)
	texte=re.sub("\xb9","'",texte)
	texte=re.sub("\xa0","",texte)
	texte=re.sub("\xab","'",texte)
	texte=re.sub("\xb4","",texte)
	texte=re.sub("\xb8","",texte)
	texte=re.sub("\xbb","'",texte)
	texte=re.sub("\xbf","",texte)

	texte=re.sub("\x80","A",texte)
	texte=re.sub("\xc0","A",texte)
	texte=re.sub("\xc1","A",texte)
	texte=re.sub("\xc2","A",texte)
	texte=re.sub("\xc3","A",texte)
	texte=re.sub("\xc4","A",texte)
	texte=re.sub("\xc5","A",texte)
	texte=re.sub("\xc7","C",texte)
	texte=re.sub("\xc8","E",texte)
	texte=re.sub("\xc9","E",texte)
	texte=re.sub("\xca","E",texte)
	texte=re.sub("\xcb","E",texte)
	texte=re.sub("\xcc","I",texte)
	texte=re.sub("\xcd","I",texte)
	texte=re.sub("\xce","I",texte)
	texte=re.sub("\xcf","I",texte)
	texte=re.sub("\xd1","N",texte)
	texte=re.sub("\xd2","O",texte)
	texte=re.sub("\xd3","O",texte)
	texte=re.sub("\xd4","O",texte)
	texte=re.sub("\xd5","O",texte)
	texte=re.sub("\xd6","O",texte)
	texte=re.sub("\xd9","U",texte)
	texte=re.sub("\xda","U",texte)
	texte=re.sub("\xdb","U",texte)
	texte=re.sub("\xdf","U",texte)
	texte=re.sub("\xdd","Y",texte)
	texte=re.sub("\xe0","a",texte)
	texte=re.sub("\xe1","a",texte)
	texte=re.sub("\xe2","a",texte)
	texte=re.sub("\xe3","a",texte)
	texte=re.sub("\xe4","a",texte)
	texte=re.sub("\xe5","a",texte)
	texte=re.sub("\xe7","c",texte)
	texte=re.sub("\xe8","e",texte)
	texte=re.sub("\xe9","e",texte)
	texte=re.sub("\xea","e",texte)
	texte=re.sub("\xeb","e",texte)
	texte=re.sub("\xec","ì",texte)
	texte=re.sub("\xed","í",texte)
	texte=re.sub("\xee","i",texte)
	texte=re.sub("\xef","i",texte)
	texte=re.sub("\xf1","n",texte)
	texte=re.sub("\xf2","o",texte)
	texte=re.sub("\xf3","o",texte)
	texte=re.sub("\xf4","o",texte)
	texte=re.sub("\xf5","o",texte)
	texte=re.sub("\xf6","o",texte)
	texte=re.sub("\xf9","u",texte)
	texte=re.sub("\xfa","u",texte)
	texte=re.sub("\xfb","u",texte)
	texte=re.sub("\xfc","u",texte)
	texte=re.sub("\xfd","y",texte)
	texte=re.sub("\xff","y",texte)

	return texte

###################################################################################
def decode_utf8(texte):
###################################################################################
	texte=re.sub("\xc3\x80","A",texte)
	texte=re.sub("\xc3\x81","A",texte)
	texte=re.sub("\xc3\x82","A",texte)
	texte=re.sub("\xc3\x83","A",texte)
	texte=re.sub("\xc3\x84","A",texte)
	texte=re.sub("\xc3\x85","A",texte)
	texte=re.sub("\xc3\x86","A",texte)
	texte=re.sub("\xc3\x87","C",texte)
	texte=re.sub("\xc3\x88","E",texte)
	texte=re.sub("\xc3\x89","E",texte)
	texte=re.sub("\xc3\x8a","E",texte)
	texte=re.sub("\xc3\x8b","E",texte)
	texte=re.sub("\xc3\x8c","I",texte)
	texte=re.sub("\xc3\x8d","I",texte)
	texte=re.sub("\xc3\x8e","I",texte)
	texte=re.sub("\xc3\x8f","I",texte)
	texte=re.sub("\xc3\x91","N",texte)
	texte=re.sub("\xc3\x92","O",texte)
	texte=re.sub("\xc3\x93","O",texte)
	texte=re.sub("\xc3\x94","O",texte)
	texte=re.sub("\xc3\x95","O",texte)
	texte=re.sub("\xc3\x96","O",texte)
	texte=re.sub("\xc3\x99","U",texte)
	texte=re.sub("\xc3\x9a","U",texte)
	texte=re.sub("\xc3\x9b","U",texte)
	texte=re.sub("\xc3\x9c","U",texte)
	texte=re.sub("\xc3\x9d","Y",texte)
	texte=re.sub("\xc3\xa0","a",texte)
	texte=re.sub("\xc3\xa1","a",texte)
	texte=re.sub("\xc3\xa2","a",texte)
	texte=re.sub("\xc3\xa3","a",texte)
	texte=re.sub("\xc3\xa4","a",texte)
	texte=re.sub("\xc3\xa5","a",texte)
	texte=re.sub("\xc3\xa7","c",texte)
	texte=re.sub("\xc3\xa8","e",texte)
	texte=re.sub("\xc3\xa9","e",texte)
	texte=re.sub("\xc3\xaa","e",texte)
	texte=re.sub("\xc3\xab","e",texte)
	texte=re.sub("\xc3\xac","ì",texte)
	texte=re.sub("\xc3\xad","í",texte)
	texte=re.sub("\xc3\xae","i",texte)
	texte=re.sub("\xc3\xaf","i",texte)
	texte=re.sub("\xc3\xb0","]",texte)
	texte=re.sub("\xc3\xb1","n",texte)
	texte=re.sub("\xc3\xb2","o",texte)
	texte=re.sub("\xc3\xb3","o",texte)
	texte=re.sub("\xc3\xb4","o",texte)
	texte=re.sub("\xc3\xb5","o",texte)
	texte=re.sub("\xc3\xb6","o",texte)
	texte=re.sub("\xc3\xb9","u",texte)
	texte=re.sub("\xc3\xba","u",texte)
	texte=re.sub("\xc3\xbb","u",texte)
	texte=re.sub("\xc3\xbc","u",texte)
	texte=re.sub("\xc3\xbd","y",texte)
	texte=re.sub("\xc3\xbf","y",texte)

	texte=re.sub("A\xc2\xa8","e",texte)
	texte=re.sub("A\xc2\xa9","e",texte)
	texte=re.sub("A\xc2\xaa","e",texte)
	texte=re.sub("A\xc2\xab","e",texte)
#	texte=re.sub("\xc2\x80","euro",texte)

	return texte

###################################################################################
def noAccent(texte):
###################################################################################
	texte=re.sub("À","A",texte)
	texte=re.sub("Á","A",texte)
	texte=re.sub("Â","A",texte)
	texte=re.sub("Ã","A",texte)
	texte=re.sub("Ä","A",texte)
	texte=re.sub("Å","A",texte)
	texte=re.sub("Ç","C",texte)
	texte=re.sub("È","E",texte)
	texte=re.sub("É","E",texte)
	texte=re.sub("Ê","E",texte)
	texte=re.sub("Ë","E",texte)
	texte=re.sub("Ì","I",texte)
	texte=re.sub("Í","I",texte)
	texte=re.sub("Î","I",texte)
	texte=re.sub("Ï","I",texte)
	texte=re.sub("Ñ","N",texte)
	texte=re.sub("Ò","O",texte)
	texte=re.sub("Ó","O",texte)
	texte=re.sub("Ô","O",texte)
	texte=re.sub("Õ","O",texte)
	texte=re.sub("Ö","O",texte)
	texte=re.sub("Ù","U",texte)
	texte=re.sub("Ú","U",texte)
	texte=re.sub("Û","U",texte)
	texte=re.sub("Ü","U",texte)
	texte=re.sub("Ý","Y",texte)
	texte=re.sub("à","a",texte)
	texte=re.sub("á","a",texte)
	texte=re.sub("â","a",texte)
	texte=re.sub("ã","a",texte)
	texte=re.sub("ä","a",texte)
	texte=re.sub("å","a",texte)
	texte=re.sub("ç","c",texte)
	texte=re.sub("è","e",texte)
	texte=re.sub("é","e",texte)
	texte=re.sub("ê","e",texte)
	texte=re.sub("ë","e",texte)
	texte=re.sub("ì","i",texte)
	texte=re.sub("í","i",texte)
	texte=re.sub("î","i",texte)
	texte=re.sub("ï","i",texte)
	texte=re.sub("ñ","n",texte)
	texte=re.sub("ò","o",texte)
	texte=re.sub("ó","o",texte)
	texte=re.sub("ô","o",texte)
	texte=re.sub("õ","o",texte)
	texte=re.sub("ö","o",texte)
	texte=re.sub("ù","u",texte)
	texte=re.sub("ú","u",texte)
	texte=re.sub("û","u",texte)
	texte=re.sub("ü","u",texte)
	texte=re.sub("ý","y",texte)
	texte=re.sub("ÿ","y",texte)

	return texte

# Search for filename or find recursively if it's multipart
###################################################################################
def extract_attachment(payload):
###################################################################################
	global attachments, skipped
	filename = payload.get_filename()
	if filename is not None:
		if treat == "att" or treat == "tout" :
			print "\n%sPièce(s) jointe(s) trouvée(s)!%s" %(gGre, noColor)
		if filename.find('=?') != -1:
			ll = email.header.decode_header(filename)
			filename = ""
			for l in ll:
				filename = filename + l[0]

		if filename in BLACKLIST:
			skipped = skipped + 1
			if (VERBOSE >= 1) and (treat == "att" or treat == "tout") :
				print "%sNon traitée %s%s%s (liste noire)%s\n" %(gCya, gYel, filename, gCya, noColor)
			return

		# Puede no venir especificado el nombre del archivo??		
		#	if filename is None:
		#		filename = "unknown_%d_%d.txt" %(i, p)
		content = payload.as_string()
		# Skip headers, go to the content
		fh = content.find('\n\n')
		content = content[fh:]

		# if it's base64....
		if payload.get('Content-Transfer-Encoding') == 'base64':
			content = base64.decodestring(content)
		# quoted-printable
		# what else? ...

		# Nettoyage du nom de la pièce jointe
		filename=re.sub("\n","",filename)
		filename=re.sub("\r","",filename)
		filename=noAccent(filename)
		filename=decode_utf8(filename)
		filename=decode_ansi(filename)
		filename=re.sub("\x92","_",filename)
		filename=re.sub("\xb0","]",filename)
		filename=re.sub("\xb4","'",filename)

		if treat == "pdf" or treat == "tout" :
			origine=directory+"/"+filename
			cleaned=noAccent(directory+"/"+filename)
			if treat == "pdf":
				print "Pièce jointe : %s%s%s (%s%d%s octets)%s" %(gYel, filename, gGre, gYel, len(content), gGre, noColor)
			if link_att == "1" and treat == "tout" and origine == cleaned :
				if move_user != "" :
					path=re.sub(os.environ["USER"],move_user, directory)
				else:
					path=directory
				cline="Pièce jointe (cliquable): "+'<link href="file://'+path+"/"+filename+'">'+filename+"</link>  ("+str(len(content))+" octets)"
			else :
				cline="Pièce jointe : "+filename+" ("+str(len(content))+" octets)"
			body.append(Spacer(0, cm * .4))
			body.append(Paragraph("----------------------------------------------------------------------------------------------------------------------------------------", bold))
			body.append(Paragraph(cline,bold))
		if treat == "att" or treat == "tout" :
			filename=re.sub("\n","",filename)
			print "%sExtraction de %s%s%s (%s%d%s octets)%s" %(gGre, gYel, filename, gGre, gYel, len(content), gGre, noColor)
			n = 1
			orig_filename = filename
			while os.path.exists(filename):
				filename = orig_filename + "." + str(n)
				n = n+1
			try:
				fp = open(filename, "w")
				fp.write(content)
			except IOError:
				print "%sAbandon, %Erreur d'entrée-sortie!!!%s" %(gRed, gCya, noColor)
				sys.exit(2)
			finally:
				fp.close()	
		
		attachments = attachments + 1
	else:
		if payload.is_multipart():
			for payl in payload.get_payload():
				extract_attachment(payl)

### Main ##########################################################################

name=sys.argv[0]+"/"
prog=name.split('/')
progname=prog[len(prog)-2]
print "\n%s%s %s%s%s" %(gMag, progname, gRed, __version__, noColor)
print "%sExtraire les pièces jointes des fichiers mbox%s" %(gGre, noColor)
print "%sCopyright (C) 2012 %s%s" %(gBlu, __author__, noColor)
print "%sVersion étendue: %s%s%s" %(gMag, gRed, __extended__, noColor)
print "%sPièces jointes + export des mails en pdf%s" %(gGre, noColor)
print "%sCopyright (C) 2016 %s%s" %(gBlu, __extend_author__, noColor)
print

if len(sys.argv) < 3 or len(sys.argv) > 4:
	print "%sUsage: %s%s %s<fichier> <destination> %s[%spdf%s|%satt%s|%stout%s]%s" %(gMag, gYel, progname, gGre, gMag, gYel, gMag, gYel, gMag, gRed, gMag, noColor)
        print
	sys.exit(0)

filename = sys.argv[1]
directory = sys.argv[2]
auto_mbox = "0"
auto_target = "0"
link_att = "0"
treat="att"
mbox_path=""
target_path=""
move_user=""
no_accent="0"
auto_create="0"

# Fichier de config
if os.path.exists(os.environ['HOME']+"/.mbox2pdf") :
	config=os.environ['HOME']+"/.mbox2pdf"
	monfichier=open(config,"r")	
	params=monfichier.read()
	configs=params.split("\n")
	for config in configs :
		if re.search("auto_mbox=",config) is not None :
			auto_mbox=re.sub("auto_mbox=","",config)
		if re.search("auto_target=",config) is not None :
			auto_target=re.sub("auto_target=","",config)
		if re.search("link_att=",config) is not None :
			link_att=re.sub("link_att=","",config)
		if re.search("treat=",config) is not None :
			treat=re.sub("treat=","",config)
		if re.search("auto_create=",config) is not None :
			auto_create=re.sub("auto_create=","",config)
		if re.search("no_accent=",config) is not None :
			no_accent=re.sub("no_accent=","",config)
		if re.search("mbox_path=",config) is not None and auto_mbox == "1" :
			mbox_path=re.sub("mbox_path=","",config)
		if re.search("target_path=",config) is not None and auto_target == "1" :
			target_path=re.sub("target_path=","",config)
		if re.search("move_user=",config) is not None :
			move_user=re.sub("move_user=","",config)

# Test Répertoire mbox
if not os.path.exists(mbox_path) :        # or os.path.isdir(mbox_path):
	print "%sRépertoire inexistant: %s%s%s\n" %(gYel, gRed, mbox_path, noColor)
	sys.exit(1)
else :
	directory=filename
	filename=mbox_path+filename

# Test existence de mbox
if not os.path.exists(filename):
	print "%sFichier inexistant: %s%s%s\n" %(gYel, gRed, filename, noColor) 
	sys.exit(1)
else :
	print "%sFichier mbox: %s%s%s" %(gGre, gYel, filename, noColor)

# Test Répertoire target
if not os.path.exists(target_path) and auto_create != "1" : # or not os.path.isdir(target_path):
	print "%sRépertoire inexistant: %s%s%s\n" %(gYel, gRed, target_path, noColor)
	sys.exit(1)

# Nettoyage de directory
if no_accent == "1" :
	directory=target_path+noAccent(directory)
else :
	directory=target_path+directory

# Création de directory
if not os.path.exists(directory) and auto_create == "1" :
	os.mkdir(directory)	
elif not os.path.exists(directory) :
	print "%sRépertoire inexistant: %s%s%s\n" %(gYel, gRed, directory, noColor)
	sys.exit(1)
else :
	print "%sDossier: %s%s%s" %(gGre, gYel,directory, noColor)

if len(sys.argv) == 4:
	treat = sys.argv[3]

os.chdir(directory)
mb = mailbox.mbox(filename)
nmes = len(mb)

# Styles utilisés
normal = ParagraphStyle(
	name='Normal',
	fontName='Helvetica',
	fontSize=9,
)
bold = ParagraphStyle(
	name='Normal',
	fontName='Helvetica-Bold',
	fontSize=9,
)

# Ne fonctionne pas !!!
italic = ParagraphStyle(
	name='Italic',
	fontName='Helvetica',
	fontSize=9,
)

# Analyse du fichier mbox
for i in range(len(mb)):
	if (VERBOSE >= 1):
		print "--------------\n%sAnalyse du message numéro :%s%d%s"  %(gWhi, gCya, i, noColor)

	mes = mb.get_message(i)
	em = email.message_from_string(mes.as_string())

	element="subject"
	subject = em.get('Subject')
	if subject is None  or len(subject) == 0 :
		sujet="[sans sujet]"
	else:
		sujet=Join_line(subject)
		debut=""
		fin=""
		if re.search("\?Q\?",subject.upper()) is not None :
			subject=Clean_codage(subject)
		bus=subject.split("=?")
		if len(bus) > 1:
			if re.search("=\?",bus[0]) is None :
				debut=bus[0]
				nbus=""
				for l in subject:
                                    if l[0] == "=" or len(nbus) > 0:
 					nbus=nbus+l[0]
				subject=nbus
				nbus2=nbus.split("?=")
				if len(nbus2) == 1:
					subject=subject+"?="
		bus=subject.split("?=")
                if len(bus) > 1 :
			fin=bus[1]
			subject=bus[0]+"?="
	   	subject=re.sub(":","_",subject)
	  	subject=re.sub("=E2=2C=AC","euros",subject)
	  	subject=re.sub("=E2=82=AC","",subject)
	  	subject=re.sub("=C3=A9","e",subject)

		if re.search("\?=",subject) is not None :
			if re.search("\?UTF-8\?",subject.upper()) is not None :
				code="utf-8"
			else:
				code="iso-8859"
			ll = email.header.decode_header(subject)
			sujet = ""
                	keep=0
			for l in ll:
				sujet=l[0]
				break
			if code == "utf-8":
				sujet=decode_utf8(sujet)
			else :
				sujet=decode_ansi(sujet)
			if debut != "" :
				sujet=debut+sujet
			if fin != "" :
				if re.search("=\?",fin) is not None:
					milieu=""
					fin0=""
					for l in fin:
						if l[0] == "=" or len(fin0) > 0:
							fin0=fin0+l[0]
						else :
							milieu=milieu+l[0]
					isfin=fin.split("=?")
					if len(isfin[0]) == 0:
						fin1=fin0
						fin0=milieu
						milieu=fin1
					if len(isfin) > 1:
						fin0=fin0+"\?="
						fin0=re.sub("\?=\?=","\?=",fin0)
					sujet=sujet+milieu
					if re.search("\?=",fin0) is not None :
						if re.search("\?B\?",fin0) is not None :
							ll = email.header.decode_header(fin0)
							fin=""
				                	keep=0
							for l in ll:
								fin=l[0]
								break
							if code == "utf-8":
								fin=decode_utf8(fin)
							else :
								fin=decode_ansi(fin)
							fin0=fin
						else :
							fin0=Clean_codage(fin0)
					sujet=sujet+fin0
				else:
					sujet=sujet+fin
		else :
			sujet=subject
	sujet=re.sub("_"," ",sujet)
	sujet=re.sub("       "," ",sujet)
	sujet=re.sub("      "," ",sujet)
	sujet=re.sub("     "," ",sujet)
	sujet=re.sub("    "," ",sujet)
	sujet=re.sub("   "," ",sujet)
	sujet=re.sub("  "," ",sujet)
	sujet=re.sub("\t"," ",sujet)
	sujet=noAccent(sujet)
	sujet=re.sub("/"," ",sujet)
	sujet=re.sub(":"," ",sujet)
	sujet=re.sub("\"","",sujet)
	sujet=re.sub("=5B","[",sujet)

	sujet=decode_utf8(sujet)
	sujet=decode_ansi(sujet)	

	sujet=re.sub("\x92"," ",sujet)
	sujet=re.sub("\xb0","]",sujet)
	if re.search("=\?",sujet) is not None:
		sujet=Clean_codage(sujet)

	element=""

	em_from = em.get('From')
	if em_from is None or len(em_from) == 0 :
		cfrom = '[Expéditeur inconnu]'
        else:
		em_from=Join_line(em_from)
		debut=""
		fin=""
		milieu=""
		em_from1=""
		em_from2=""
		cfrom1=""
		cfrom2=""
		if re.search("\?Q\?",em_from.upper()) is not None :
			em_from=Clean_codage(em_from)
		bus=em_from.split("=?")
		if len(bus) > 1:
			nbus=""
			for l in em_from:
				if l[0] == "<" or len(fin) > 0:
					fin=fin+l[0]
				else :
					nbus=nbus+l[0]
			em_from0=nbus
			bus2=em_from0.split("=?")
			if len(bus2) > 1:
				debut=bus2[0]
				em_from1="=?"+bus2[1]+"?="
				if len(bus) > 2:
					milieu=bus[2]
					if len(bus) > 3:
						bus3=bus[3].split("=?")
						em_from2="=?"+bus3[0]+"?="
		else :
			em_from1=em_from
		if re.search("\?",em_from) is not None :
			if re.search("\?UTF-8\?",em_from.upper()) is not None :
				code="utf-8"
			else :
				code="iso-8859"

			ll = email.header.decode_header(em_from1)
			cfrom1 = ""
	                keep=0
			for l in ll:
				cfrom1=l[0]
				break
			if code == "utf-8":
				cfrom1=decode_utf8(cfrom1)
			else :
				cfrom1=decode_ansi(cfrom1)
			if em_from2 != "" :
				ll = email.header.decode_header(em_from2)
				cfrom2 = ""
		                keep=0
				for l in ll:
					cfrom2=l[0]
					break
				if code == "utf-8":
					cfrom2=decode_utf8(cfrom2)
				else :
					cfrom2=decode_ansi(cfrom2)
			cfrom1=re.sub("\?","",cfrom1)
			cfrom2=re.sub("\?","",cfrom2)
			cfrom1=re.sub("=","",cfrom1)
			cfrom2=re.sub("=","",cfrom2)
			cfrom=debut+cfrom1+milieu+cfrom2+fin
			if re.search(" <", cfrom) is None :
				cfrom=re.sub("<"," <",cfrom)
                else :
			cfrom=em_from
			if re.search("<",cfrom) is None:
				cfrom="<"+cfrom+">"
	cfrom=re.sub("\"","",cfrom)
	cfrom=re.sub("'","",cfrom)
	cfrom=re.sub("<","[",cfrom)
	cfrom=re.sub(">","]",cfrom)
	cfrom=re.sub("=","",cfrom)

	tfrom=cfrom.split("[")
	if len(tfrom) == 1:
		tmail=tfrom[0]
	else:
		tmail=tfrom[1]
	umail=tmail.split("]")
	mfrom=umail[0]
	dfrom='<a href="mailto:'+mfrom+'"><font color="blue">'+cfrom+"</link>"

	em_to = em.get('To')
	if em_to is None or len(em_to) == 0  :
		em_to = '[Destinataire inconnu]'
        else:
		em_to=re.sub("\r","",em_to)
		em_to=re.sub("\n","",em_to)
		em_to=re.sub("<","[",em_to)
		em_to=re.sub(">","]",em_to)
		em_to=re.sub('"',"",em_to)

	em_Cc = em.get('Cc')
	if em_Cc is None or len(em_Cc) == 0  :
		cCc = 'None'
        else:
		cCc=re.sub("\r","",em_Cc)
		cCc=re.sub("\n","",cCc)
		cCc=re.sub("<","[",cCc)
		cCc=re.sub(">","]",cCc)
		cCc=re.sub('"',"",cCc)

	em_date = em.get('Date')
	if em_date is None or len(em_date) == 0  :
		cdate = '[Date inconnue]'
        else:
        	if re.search("=\?",em_date) is not None :
			if re.search("\?UTF-8\?",em_date.upper()) is not None :
				code="utf-8"
			else:
				code="iso-8859"
			ll = email.header.decode_header(em_date)
			cdate = ""
			keep=0
			for l in ll:
				cdate=l[0]
				break
			if code == "utf-8":
				cdate=decode_utf8(cdate)
			else :
				cdate=decode_ansi(cdate)
                else :
			cdate=re.sub("\xc2\x92","'",em_date)

	# Création du mail en pdf
	if treat == "pdf" or treat == "tout" :
		em_type = em.get('Content-Type')
        	em_boundary = re.sub('\n','',em_type)
        	em_boundary = re.sub('multipart/alternative; boundary=','',em_boundary)
	        em_boundary = re.sub('multipart/mixed; boundary=','',em_boundary)
	        em_boundary = re.sub('"','',em_boundary)

	        psujet=re.sub("_"," ",sujet)
		psujet=re.sub("   "," ",sujet)
		psujet=re.sub("  "," ",sujet)
		print "Sujet:     %s%s%s" %(gBlu, psujet, noColor)
		print "De:        %s%s%s" %(gGre, cfrom, noColor)
		print "Date:      %s%s%s" %(gYel, cdate, noColor)

		pour=""
		em_to=Join_line(em_to)
		lcto=em_to.split(', ')
		for ecto in lcto :
			debut=""
			fin=""
			address=""
			milieu=""
			ecto0=""
			scto1=""
			scto2=""
			cto1=""
			cto2=""
			mcto=""
			if em_to == '[Destinataire inconnu]':
				pour=em_to
				dispour=em_to
				break
			if em_to == 'undisclosed-recipients:;':
				pour='[Destinataire(s) masqué(s)]'
				dispour='[Destinataire(s) masqué(s)]'
				break
			if em_to == 'destinataires inconnus:;':
				pour='[Destinataire(s) masqué(s)]'
				dispour='[Destinataire(s) masqué(s)]'
				break
			if len(ecto) > 0 :
				ncto=""
				for l in ecto:
					if l[0] == "[" or len(address) > 0:
						address=address+l[0]
					else :
						ncto=ncto+l[0]
				if address == "":
					ecto=ncto+" ["+ncto+"]"
					address="["+ncto+"]"
					ncto=""
				if re.search("\?Q\?",ncto.upper()) is not None :
					ncto=Clean_codage(ncto)
				if re.search("==",ncto) is not None:
					ncto=re.sub("==","qp",ncto)
				if re.search("=\?=",ncto) is not None:
					ncto=re.sub("=\?=","ù\?=",ncto)
				scto=ncto.split("=?")
				if len(scto) > 1:
					for ecto0 in scto :
						if re.search("qp",ecto0) is not None:
							fin0=ecto0.split("?=")
							if len(fin0) > 1:
								fin=fin0[1]+"ù"
							else:
								fin=""
							ecto0=fin0[0]+"==?="
							ecto0=re.sub(" =","=",ecto0)
						if ecto0 != "":
							if re.search("\?=",ecto0) is None and re.search("=",ecto0) is None:
								debut=debut+ecto0
							else :
								if re.search("= ",ecto0) is not None:
									ecto1=ecto0.split(" ")
									fin=" "+ecto1[1]
									ecto0=re.sub(fin,"",ecto0)
								ecto0=re.sub(" ","",ecto0)
								if re.search("\=",ecto0) is not None and re.search("\?=",ecto0) is None:
									ecto0=ecto0+"?="
								ecto0="=?"+ecto0
								if re.search("\?UTF-8\?",ecto0.upper()) is not None :
									code="utf-8"
								else:
									code="iso-8859"
								if re.search("\?Q\?",ecto0.upper()) is None :
									ll = email.header.decode_header(ecto0)
									ecto1 = ""
									keep=0
									for l in ll:
										ecto1=l[0]
										break
									if code == "utf-8":
										ecto1=decode_utf8(ecto1)
									else :
										ecto1=decode_ansi(ecto1)
									ecto3=ecto1.split("\n")
	                                                                ecto1=ecto3[0] 
									ecto2=ecto1.split(" ")
									ecto=""
									rg=0
									if ecto2[0] == "":
										for ecto3 in ecto2 :
											if rg > 0 :
												ecto=ecto+ecto3
											rg=rg+1
									else :
										ecto=ecto1
								else:
									ecto=Clean_codage(ecto0)
								fin=re.sub(" ù","",fin)
								ecto=debut+ecto+fin+" "+address
				else:
					ecto=ncto+address
				ecto=re.sub("'","",ecto)
				scto=address.split("[")
				if len(scto) == 1:
					mcto=scto[0]
				else:
					tmail=scto[1]
					umail=tmail.split("]")
					mcto=umail[0]
				dpour=ecto
				ecto='<a href="mailto:'+mcto+'"><font color="blue">'+ecto+"</link>"
				if pour == "" :
					pour=ecto
					dispour=dpour
				else :
					pour=pour+", "+ecto
					dispour=dispour+", "+dpour
		pour=re.sub("  "," ",pour)
		dispour=re.sub("  "," ",dispour)	
		print "Pour:      %s%s%s" %(gCya, dispour, noColor)

		if cCc == "None" :
                  cCc="None"
                else :
			copie=""
			lcCc=cCc.split(', ')
			for ecCc in lcCc :
				debut=""
				fin=""
				address=""
				milieu=""
				ecCc0=""
				scCc1=""
				scCc2=""
				cCc1=""
				cCc2=""
				mcCc=""
				if len(ecCc) > 0 :
					ecCc=Join_line(ecCc)
					ncCc=""
					for l in ecCc:
						if l[0] == "[" or len(address) > 0:
							address=address+l[0]
						else :
							ncCc=ncCc+l[0]
					if address == "":
						ecCc=ncCc+" ["+ncCc+"]"
						address="["+ncCc+"]"
						ncCc=""
					if re.search("\?Q\?",ncCc.upper()) is not None :
						ncCc=Clean_codage(ncCc)
					if re.search("==",ncCc) is not None:
						ncCc=re.sub("==","qp",ncCc)
					elif re.search("=\?=",ncCc) is not None:
						ncCc=re.sub("=\?=","q|p",ncCc)
					scCc=ncCc.split("=?")
					if len(scCc) > 1:
						for ecCc0 in scCc :
							if re.search("qp",ecCc0) is not None:
								fin0=ecCc0.split("?=")
								if len(fin0) > 1:
									fin=fin0[1]+"ù"
								else:
									fin=""
								ecCc0=fin0[0]+"?="
							elif re.search("q|p",ecCc0) is not None:
								fin0=ecCc0.split("?=")
								if len(fin0) > 1:
									fin=fin0[1]+"ù"
								else:
									fin=""
								ecCc0=fin0[0]+"=?="
								ecCc0=re.sub(" =","=",ecCc0)
							if ecCc0 != "":
								if re.search("\?=",ecCc0) is None and re.search("=",ecCc0) is None:
									debut=debut+ecCc0
								else :
									ecCc0=re.sub(" ","",ecCc0)
									if re.search("\=",ecCc0) is not None and re.search("\?=",ecCc0) is None:
										ecCc0=ecCc0+"?="
									ecCc0="=?"+ecCc0
									ecCc0=re.sub("qp","==",ecCc0)
									ecCc0=re.sub("q\|p","=\?=",ecCc0)
									if re.search("\?UTF-8\?",ecCc0.upper()) is not None :
										code="utf-8"
									else:
										code="iso-8859"
									ll = email.header.decode_header(ecCc0)
									ecCc1 = ""
									keep=0
									for l in ll:
										ecCc1=l[0]
										break
									if code == "utf-8":
										ecCc1=decode_utf8(ecCc1)
									else :
										ecCc1=decode_ansi(ecCc1)
										ecCc3=ecCc1.split("\n")
										ecCc1=ecCc3[0] 
									ecCc2=ecCc1.split(" ")
									ecCc=""
									rg=0
									
									if ecCc2[0] == "":
										for ecCc3 in ecCc2 :
											if rg > 0 :
												ecCc=ecCc+ecCc3
											rg=rg+1
									else :
										ecCc=ecCc1
									fin=re.sub(" ù","",fin)
									ecCc=debut+ecCc+fin+" "+address
									ecCc=re.sub("\xa9","",ecCc)
									ecCc=re.sub("\r","",ecCc)
									ecCc=re.sub("\n","",ecCc)
									ecCc=re.sub('\"',"",ecCc)
									ecCc=re.sub("'","",ecCc)
									ecCc=re.sub('"',"",ecCc)
					else:
						ecCc=ncCc+address
					ecCc=re.sub("'","",ecCc)
					scCc=address.split("[")
					if len(scCc) == 1:
						mcCc=scCc[0]
					else:
						tmail=scCc[1]
						umail=tmail.split("]")
						mcCc=umail[0]
					dcopie=ecCc
					ecCc='<a href="mailto:'+mcCc+'"><font color="blue">'+ecCc+"</link>"
					if copie == "" :
						copie=ecCc
						dispcopy=dcopie
					else :
						copie=copie+", "+ecCc
						dispcopy=dispcopy+", "+dcopie
			copie=re.sub("  "," ",copie)
			dispcopy=re.sub("  "," ",dispcopy)	
			print "Copie:     %s%s%s" %(gBlu, dispcopy, noColor)

		psujet="Sujet:     "+sujet
	        pfrom= "De:      "+dfrom
	        pdate= "Date:    "+cdate
	        pto=   "Pour:    "+pour
		if cCc != "None":
			pCc=   "Copie:   "+copie
	        body = []
		body.append(Paragraph(psujet, bold))
		body.append(Paragraph(pfrom, bold))
		body.append(Paragraph(pdate, bold))
	 	body.append(Paragraph(pto, bold))
		if cCc != "None" :
		 	body.append(Paragraph(pCc, bold))
		body.append(Spacer(0, cm * .08))
	 	body.append(Paragraph("----------------------------------------------------------------------------------------------------------------------------------------", bold))
		body.append(Spacer(0, cm * .4))
	     	em_body = mes.as_string()
                if sujet == "[sans sujet]" :
                   sujet="sans_sujet"
		sujet="Mail_"+sujet+".pdf"
		if len(sujet) > 155 :
			ll=""
			for lettre in sujet :
				ll=ll+lettre[0]
				if len(ll) > 154:
					sujet=ll
					break
		orig_sujet = sujet
                n=1
		while os.path.exists(sujet):
			sujet = orig_sujet + "." + str(n)
			n = n+1
		try:
			orig_sujet=sujet
		except IOError:
			print "%sAbandon, %Erreur d'entrée-sortie!!!%s" %(gRed, gCya, noColor)
			sys.exit(2)
		docpdf = SimpleDocTemplate(sujet, pagesize = A4)
		paragraphs = em_body.split("\n")
	        ensuite=0
	        precedent=1
	        if re.search("text/plain",em_type) is not None:
			if re.search("UTF-8",em_type) is None:
				code="iso8859"
			else :
				code="utf8"
			for para in paragraphs:
		                if re.search("Content-Disposition",para) is not None and ensuite == 0 :
					ensuite=3
			                continue
				elif re.search("Content-Transfer-Encoding",para) is not None and ensuite == 0 :
					ensuite=2
					cte=8
			                continue
	                	elif re.search("--",para) is not None and re.search("-- Message",para) is None and ensuite > 1 :
		        	        ensuite=1
	                        	break
	        	        elif ensuite == 2 and re.search("Pour : ",para) is not None :
		        	        ensuite=3
        	        	elif ensuite == 3 :
#					if code == "utf8" :
#						para=decode_utf8(para)
#					else :
#						para=decode_ansi(para)
					para=noAccent(para)
					longueur = len(para)
					if longueur > 0 or precedent > 0 :
	                                        if para == "**" :
							continue
						para = re.sub("\*\*\*"," ",para)
						body.append(Paragraph(para, normal))
						if re.search("Pièce jointe",para) is None :
							body.append(Spacer(0, cm * .08))
		elif re.search("multipart/",em_type) is not None :
			if re.search(".",em_boundary) is not None :
				att=em_boundary.partition('.')
				att_boundary=att[0]+"."+att[1]
			else :
				att=em_boundary
			for para in paragraphs:
		                if re.search("Content-Type\: text\/plain",para) is not None and ensuite == 0 :
					ensuite=1
			                continue
				elif re.search(em_boundary,para) is not None and ensuite == 2 :
		        	        ensuite=1
		                        break
				elif re.search(att_boundary,para) is not None and ensuite == 2 :
		        	        ensuite=1
		                        break
				elif re.search("cid:",para) is not None and ensuite == 2 :
		        	        ensuite=1
		                        break
				elif re.search("> ",para) is not None and ensuite == 2 :
		        	        ensuite=1
		                        break
		                elif re.search("Content-",para) is None and re.search(em_boundary,para) is not None and ensuite == 1:
		        	        ensuite=1
		                        continue
				elif re.search("Content-",para) is None and ensuite == 1 :
					ensuite=2
			                continue
	        	        elif ensuite == 2 :
					para=Clean_codage(para)
					longueur = len(para)
					if longueur > 0 or precedent > 0 :
	                                        if para == "**" :
							continue
						para = re.sub("\*\*\*"," ",para)
						if re.search("href",para) is not None:
							print para
						body.append(Paragraph(para, normal))
						body.append(Spacer(0, cm * .08))
		else :
			html_body=""
			for para in paragraphs:
				if re.search("<html>",para) is not None and ensuite == 0 :
					ensuite=1
					html_body=para+"\n"
	        	        elif ensuite == 1 :
					html_body=html_body+para+"\n"
			monfichier=open("html.html","w")
			monfichier.write(html_body)
			monfichier.close()
			text_body=subprocess.check_output(["html2text", "html.html"])
			paragraphs = text_body.split("\n")
			for para in paragraphs:
				body.append(Paragraph(para, normal))
				body.append(Spacer(0, cm * .08))

	filename = mes.get_filename()
	# Puede tener filename siendo multipart???
	if em.is_multipart():
		for payl in em.get_payload():
			extract_attachment(payl)
	else:
		extract_attachment(em)

	if treat == "pdf" or treat == "tout" :
		docpdf.build(body)

## Récapitulatif
print "\n--------------"
print "%sTotal des mails traités:%s %d%s" %(gYel, gCya, len(mb), noColor)
if treat == "att" or treat == "tout" :
	print "%sTotal des pièces jointes extraites:%s %d%s" %(gYel, gCya, attachments, noColor)
	print "%sTotal des pièces jointes non traitées:%s %d%s" %(gYel, gCya, skipped, noColor)
print

Execution du script:

mbox2pdf-extract-attachments 1.2
Extraire les pièces jointes des fichiers mbox
Copyright (C) 2012 Pablo Castellano <mail>
Version étendue: 1.32
Pièces jointes + export des mails en pdf
Copyright (C) 2016 Alain Aupeix <mail>

Usage: mbox2pdf-extract-attachments <fichier> <destination> [pdf|att|tout]

En cas de présence du fichier de configuration, seul le choix du type de traitement est paramétrable sur la ligne de commande.

Exemple d'un traitement:

mbox2pdf-extract-attachments 1.2
Extraire les pièces jointes des fichiers mbox
Copyright (C) 2012 Pablo Castellano
Version étendue: 1.32
Pièces jointes + export des mails en pdf
Copyright (C) 2016 Alain Aupeix

Fichier mbox: /home/alain/.thunderbird/crtothve.default/Mail/Local Folders/Archives.sbd/mboxfile
Dossier: /home/alain/Bureau/Archives_MAIL/split/mboxfile
--------------
Analyse du message numéro :0
Sujet:     CLIMAT
De:        Liliane Expéditeur [lili.expediteur@provider.fr]
Date:     Tue, 17 Dec 2013 08:18:38 +0100
Pour:     Le Destinataire [le.destinataire@provider.fr]
Cc   :     [autre@provider.fr]

Mail_CLIMAT.pdf
--------------
Analyse du message numéro :1
Sujet:     [sans sujet]
De:        Liliane Expéditeur [lili.expediteur@provider.fr]
Date:      Wed, 27 Nov 2013 14:18:12 +0100
Pour:      Le Destinataire [le.destinataire@provider.fr]
--------------
...
Analyse du message numéro :9
Sujet:     [sans sujet]
De:        Liliane Expéditeur [lili.expediteur@provider.fr]
Date:      Sat, 25 Jan 2014 15:42:12 +0100
Pour:      autre.testinataire@autre.fr

Pièce(s) jointe(s) trouvée(s)!
Extraction de Les chaufferies bois du Lot.doc (30720 octets)
--------------
Analyse du message numéro :10
Sujet:     notes
De:        Liliane Expéditeur [lili.expediteur@provider.fr]
Date:      Mon, 10 Feb 2014 13:02:59 +0100
Pour:      Le Destinataire [le.destinataire@provider.fr]
...
--------------
Total des mails traités: 20
Total des pièces jointes extraites: 16
Total des pièces jointes non traitées: 0

Remarques sur le traitement:

- si le chemin destination comporte un nom avec un caractère accentué, quelqu'en soit l'endroit, ou que treat = pdf,  le pdf ne comportera aucun lien vers des pièces jointes. Seul treat = all permet de générer des liens
- si la destination précisée n'est pas la destination finale, en clair que les dossiers soient déplacés ensuite, les liens seront bien créés, mais seront alors mauvais.
- j'ai essayé de créer des liens sans le chemin, vu que les pièces jointes sont dans le même répertoire, python n'aime pas.
- les liens créés s'ouvrent avec evince, mais pas avec Acrobat qui veut le nom sans file:// Comme on est sous Linux, je privilégie evince wink

Boucle de traitement:

Pour automatiser le traitement de plusieurs mbox situées dans le même dossier, j'ai fait un petit script bash qui s'appuie sur le fichier ~/.mbox2pdf et qui génère en plus un fichier log par mbox. Ces logs sont situés dans le dossier paramétré dans .mbox2pdf

#!/bin/bash

if [ -f ~/.mbox2pdf ]; then
   mkdir ~/Bureau/logs 2>/dev/null
   mbox_path=$(cat ~/.mbox2pdf|grep mbox_path)
   mbox_path=$(echo $mbox_path |sed 's|mbox_path=||g')
   log_path=$(cat ~/.mbox2pdf|grep "log_path="|sed 's|log_path=||g')
   mboxes=$(ls -a1 "${mbox_path}"|grep -v ".msf"|grep ".")
   rm ${log_path}/* 2>/dev/null
   for mbox in $mboxes ; do
	if [ "$mbox" != "." ] && [ "$mbox" != ".." ];then
	       mbox2pdf-extract-attachments $mbox $mbox |tee ${log_path}${mbox}.log
	       cat ${log_path}${mbox}.log   |sed 's|\[1;31m||g' > ${log_path}_1_${mbox}.log
	       cat ${log_path}_1_${mbox}.log|sed 's|\[1;32m||g' > ${log_path}_2_${mbox}.log
	       cat ${log_path}_2_${mbox}.log|sed 's|\[1;33m||g' > ${log_path}_3_${mbox}.log
	       cat ${log_path}_3_${mbox}.log|sed 's|\[1;34m||g' > ${log_path}_4_${mbox}.log
	       cat ${log_path}_4_${mbox}.log|sed 's|\[1;35m||g' > ${log_path}_5_${mbox}.log
	       cat ${log_path}_5_${mbox}.log|sed 's|\[1;36m||g' > ${log_path}_6_${mbox}.log
	       cat ${log_path}_6_${mbox}.log|sed 's|\[1;37m||g' > ${log_path}_7_${mbox}.log
	       cat ${log_path}_7_${mbox}.log|sed 's|\[0m||g' > ${log_path}_8_${mbox}.log
	       cat ${log_path}_8_${mbox}.log|sed 's|\x1b||g' > ${log_path}${mbox}.log
	       rm ${log_path}_*${mbox}.log
	fi
   done
else
    echo "Fichier config inexistant !!!"
fi

Script de statistiques:

Afin de traquer les possibles plantages et de pouvoir calculer les stats de mbox2pdf, j'ai fait un petit script nommé mbox2pdf_stat

#!/bin/bash

if [ -f ~/.mbox2pdf ]; then
   target_path=$(cat ~/.mbox2pdf|grep "target_path="|sed 's|target_path=||g')
   log_path=$(cat ~/.mbox2pdf|grep "log_path="|sed 's|log_path=||g')
   cd "$log_path"
   rm mbox2pdf_stat.csv 2>/dev/null
   for i in $(ls -1 *.log)
   do
      j=$(cat $i|grep 'Total des mails traités')
      k=$(cat $i|grep 'Total des pièces jointes extraites')
      echo "$i : $j : $k" >> mbox2pdf_stat.csv
      l=$(cat $i|grep "utf-8")
      m=$(cat $i|grep "UTF-8")
      n=$(cat $i|grep "iso-")
      o=$(cat $i|grep "ISO-")
      echo "===============" >> mbox2pdf_to_decode.txt
      echo "$i"              >> mbox2pdf_to_decode.txt
      echo "===============" >> mbox2pdf_to_decode.txt
      echo "$l"              >> mbox2pdf_to_decode.txt
      echo "$m"              >> mbox2pdf_to_decode.txt
      echo "$n"              >> mbox2pdf_to_decode.txt
      echo "$o"              >> mbox2pdf_to_decode.txt
   done
   echo "============================" >> mbox2pdf_to_decode.txt
   rep=${target_path}*/Mail_*
   echo "Noms de fichiers incorrects:" >> mbox2pdf_to_decode.txt
   echo "============================" >> mbox2pdf_to_decode.txt
   ls -1 "${target_path}"* | grep '?=' >> mbox2pdf_to_decode.txt
   echo "============================" >> mbox2pdf_to_decode.txt

   xdg-open mbox2pdf_stat.csv
   xdg-open mbox2pdf_to_decode.txt
else
    echo "Fichier config inexistant !!!"
fi

Voila ...

Si vous avez des remarques à faire ou modifications à proposer, ne vous génez pas ... smile

A+

Dernière modification par JujuLand (Le 13/11/2016, à 18:09)


Xubuntu 16.04 > Dell DM061 (2007) + Dell Inspiron 531 (2008)
Xubuntu 16.04 > Asus X51L (2009) + MSI GX723 (2009)
Xubuntu 22.04 > HP 15BA048NF (2018)

Hors ligne

#2 Le 17/10/2016, à 12:31

JujuLand

Re : Outil de sauvegarde de mail en pdf + pièces jointes

Comme je n'ai pas de solution pour les liens avec accents dans les pdf, j'ai ajouté un param dans le fichier de config qui transforme le nom du dossier target en enlevant les accents. Ceci permet notamment d'avoir des liens qui fonctionnent.

De plus, pour éviter d'avoir à créer le dossier target si celui-ci n'existe pas, un param dans le fichier a été ajouter pour faire la création automatique.

Reste la vérification lors d'une utilisation ultérieure, à ne pas créer les pièces jointes et le pdf si celui-ci existe déja et que les dates du mail étaient les mêmes.

A suivre ...

Le source dans le premier post, ainsi que les commentaires ont été mis à jour ...

A+

Dernière modification par JujuLand (Le 17/10/2016, à 13:57)


Xubuntu 16.04 > Dell DM061 (2007) + Dell Inspiron 531 (2008)
Xubuntu 16.04 > Asus X51L (2009) + MSI GX723 (2009)
Xubuntu 22.04 > HP 15BA048NF (2018)

Hors ligne

#3 Le 30/10/2016, à 00:09

JujuLand

Re : Outil de sauvegarde de mail en pdf + pièces jointes

Pour les premiers tests sur un fichier mbox, j'avais réussi à faire fonctionne çà correctement.
Un essai sur un ensemble de mbox (dans une boucle), a été plus catastrophique ...

J'ai repri les boucles de to et Cc, et je pense que ce coup-ci, c'est ok.

Mais j'ai encore un petit problème. Je veus transformer une chaîne, et je m'y casse un peu les dents:

 Transformer cà (les quotes simples ou doubles et le \ sont évidemment dans la chaîne)
"'\"GUICHARD Olivier (Chef de l'Unité) - DDT 76/SDPDD/PT\"'"
en çà:
GUICHARD Olivier (Chef de l'Unité) - DDT 76/SDPDD/PT

Si quelqu'un a une solution. Le problème est évidemment sur le \ ...

Merci

Version mise à jour (1.35) sur le premier post.
Comme le copier/coller dans le post semble avoir mis en vrac l'indentation, ce qui est catastrophique pour du source python, je mets le lien vers l'archive en début du premier post.

A+

Dernière modification par JujuLand (Le 30/10/2016, à 10:33)


Xubuntu 16.04 > Dell DM061 (2007) + Dell Inspiron 531 (2008)
Xubuntu 16.04 > Asus X51L (2009) + MSI GX723 (2009)
Xubuntu 22.04 > HP 15BA048NF (2018)

Hors ligne

#4 Le 01/11/2016, à 22:10

JujuLand

Re : Outil de sauvegarde de mail en pdf + pièces jointes

Après quelques test, je me suis apreçu de quelques anomalies condernant le décodage, aussi j'ai repris ça, et j'ai éliminé quelques problèmes.

Sur les essais qui ont portés sur 233 fichiers mbox, contenant 2776 mails et 5181 pièces jointes, je n'ai plus d'erreur.
Aussi, on peut considérer que ce script devient utilisable ...

Ont été ajoutés un script bash pour automatiser le traitement de mbox situés dans le même dossier, et un outil de statistique, ainsi qu'un README.

Tout çà dans une archive disponible à partir du premier post

Voilà ...
A+


Xubuntu 16.04 > Dell DM061 (2007) + Dell Inspiron 531 (2008)
Xubuntu 16.04 > Asus X51L (2009) + MSI GX723 (2009)
Xubuntu 22.04 > HP 15BA048NF (2018)

Hors ligne

#5 Le 13/11/2016, à 16:14

JujuLand

Re : Outil de sauvegarde de mail en pdf + pièces jointes

Version 1.50 du 13/11/2016
- Quelques petites correction concernant le traitement de l'encodage.
- Ajout de liens pour  from, to et Cc
- Modification des noms
    - mbox2pdf-extract-attachments => mbox2pdf
    - mbox2pdf => mbox2pdf-multi
    - mbox2pdf_stat => mbox2pdf-stat
- Amélioration de mbox2pdf-stat

Reste à faire :
- Simplification du code en passant le décodage dans une fonction
- Amélioration du traitement du corps du mail (cas de mails imbriqués)

Tout çà dans une archive disponible à partir du premier post

A+


Xubuntu 16.04 > Dell DM061 (2007) + Dell Inspiron 531 (2008)
Xubuntu 16.04 > Asus X51L (2009) + MSI GX723 (2009)
Xubuntu 22.04 > HP 15BA048NF (2018)

Hors ligne