#!/usr/bin/env python
# -*- coding: utf-8 -*-

'''Script de retrait des vielles Mailing-List
   v1 (03/2012) par Lucas Serrano
   Merci à Vincent Le Gallic pour son aide.
   
   '''

import time
import sys
import os
import argparse

sys.path.insert(0, '/var/lib/mailman')
from Mailman import MailList
from Mailman import Utils

#Parsing des arguments
parser = argparse.ArgumentParser(description = 'Liste les Mailing List dont de dernier post est antérieur à la date donnée')
parser.add_argument('--no-du', dest = 'DISK_USAGE', action = 'store_const', const = False, default = True, help = 'Ne calcule pas la taille des archives')
parser.add_argument('-o', '--order-by', type = str, choices = ['date', 'size', 'members'], metavar = 'paramètre', dest='order', default = 'date', help = "Change le paramètre utiliser pour le classement des résultats. Les paramètres possibles sont: date, size ou members (Par défaut: date)")
parser.add_argument('-r', '--reverse-order', dest='REVERSED', action = 'store_true', default = False, help = "Renverse l'ordre d'affichage des résultats")
parser.add_argument('date', type = str, help = 'Date à laquelle les MLs ne sont plus considérées comme utilisées')


def getData(date, DU):
    '''
    Fonction de collectage de données.
    Récupère d'abord tous les noms des MailingList sous forme d'une liste de noms.
    Récupère ensuite pour chaque liste: la date du dernier post sur la liste, le chemin du dossier d'archivage, la taille de l'archive si le booléen DU est vrai, et le nombre de membres.
    Si la date du dernier post de la liste précèdemment récupérée est inférieure à la date donnée alors les infos de celle-ci sont stockés sous forme de dictionnaire.
    Retourne la liste de ces dictionnaires et la taille totale de tous les dossiers d'archives (0 si DU est à False).
    '''

    tailleTotale = 0
    listeDeListes = Utils.list_names()  #Recupère les noms des listes sous forme de string
    listes = []
    for name in listeDeListes:
	liste = MailList.MailList(name, lock=False)  #Créer les objets temporaire liste à l'aide de leurs noms
	liste_time = liste.last_post_time
	if liste_time <= date:
	    liste_arch_dir = liste.archive_dir()
	    liste_members_nbr = len(liste.members)
	    liste_size=0
	    if DU:
		#Recherche de la taille du dossier d'archive
		for (path, dirs, files) in os.walk(liste_arch_dir):
		    for file in files:
			filename = os.path.join(path, file)
			liste_size += os.path.getsize(filename)
		liste_size = liste_size / 1048576.0
		tailleTotale += liste_size
	    listes.append({"name" : name, "last_post_timestamp" : liste_time, "archive_directory" : liste_arch_dir, "members_number" : liste_members_nbr,"directory_size" : liste_size})	
    return (listes, tailleTotale)

    
def formatData(listes, dict_key, REVERSED):
    '''
    Fonction de formatage des données, attend en entrée une liste de même structure que celle crée par getData. 
    Trie les listes par date du dernier post et crée une date formatée de celui-ci sous le format JJ/MM/AAAA.
    Cette date est ajoutée en tant qu'entrée dans le dictionnaire de chaque liste présente dans la liste de listes.
    '''

    listes.sort(key=lambda l : l[dict_key], reverse=REVERSED) #Classement par type demandée
    for l in listes :  #Crée une date formatée (format JJ/MM/AAAA)
        l['last_post_formated_time']= time.strftime("%d/%m/%Y", time.gmtime(l['last_post_timestamp']))
    return listes

def printData(listes,tailleTotale):
    '''
    Fonction d'écriture du texte à afficher, attend en entrée une liste formatée de même structure que celle formatée par formatData.
    Retourne le texte à afficher.
    '''
    txt = "\n \n%-40s | %-12s |   %s  | %s\n\n" %("Nom de la liste", "Dernier post", "Taille", "Membres")
    for l in listes:
	txt += "%-40s |  %-11s | %-6.1f MB | %s\n" %(l['name'], l['last_post_formated_time'], l['directory_size'], l['members_number'])
    txt += "Taille Totale: %0.1f MB\n" % (tailleTotale)
    return txt


if __name__ == "__main__":
    args = parser.parse_args()
    DISK_USAGE = args.DISK_USAGE
    REVERSED = args.REVERSED
    try:
        date = time.mktime(time.strptime(args.date, "%d/%m/%Y"))
    except:
        sys.exit("\nErreur: Veuillez poster une date de péremption sous le format JJ/MM/AAAA\n")
    dict_key = ''
    order=args.order
    if order == 'members':
        dict_key = 'members_number'
    elif (order == 'size') & (DISK_USAGE == True):  #On vérifie que la demande à un sens
        dict_key = 'directory_size'
    else:
        dict_key = 'last_post_timestamp'
    listes, tailleTotale=getData(date, DISK_USAGE)
    listes=formatData(listes, dict_key, REVERSED)
    txt = printData(listes, tailleTotale)
    print txt
    
