Extraire le contenu d'une archive .tar ou .rar

Contenu du snippet

Ce script permet d'extraire le contenu d'une archive au format .tar ou .rar. Il fonctionne en mode commande, et utilise les modules tarfile et rarfile. Il est aussi possible d'ajouter un raccourci vers le script dans le menu contextuel 'Envoyer vers' de windows 7.

Source / Exemple :


# -*- coding: utf-8 -*-

"""
    GESTION DE FICHIER ARCHIVE
    
    Le script est exécuté avec les paramètres :
    [1] : le chemin d'accès complet ou relatif à l'archive (obligatoire).
    [2] : le dossier complet ou relatif contenant les fichiers extraits. Si
    le paramètre est omis, alors les fichiers sont extraits dans le dossier
    contenant l'archive. Le dossier d'extraction porte le nom de l'archive
    concaténé avec la date et l'heure.
    
    Module permettant de traiter les archives .rar :
    1) Télécharger l'archive contenant le module rarfile.py
            http://pypi.python.org/pypi/rarfile/2.2
    2) Décompresser l'archive.
    3) Installer le module rarfile.py avec la commande :
            setup.py install
    
    Ce module fait appel l'utilitaire unrar.exe qui doit être
    téléchargé avec WinRAR :
    http://download.cnet.com/WinRAR-32-bit/3000-2250_4-10007677.html
    1) Installer WinRAR en lançant l'exécutable.
    2) L'exécutable unrar.exe se trouve dans le dossier d'installation.
    3) Copier unrar.exe dans le dossier d'exécution du script.
    Cette manipulation est aussi expliquée dans la FAQ du module python.
"""

# -----------------------------------------------------------------------------
# Les modules
# -----------------------------------------------------------------------------

import sys 
import time                     
import os.path, os 
import tarfile, rarfile

# -----------------------------------------------------------------------------
# Les fonctions
# -----------------------------------------------------------------------------

def executer():
    """Exécute l'extraction du contenu de l'archive.\n
    Si le 1er argument n'est pas un fichier, alors renvoie False.
    Si le second argument n'est pas vide, et n'est pas un dossier valide, alors
    renvoie False.
    Si le second argument est vide, alors le dossier d'extraction est égal au
    nom de l'archive concaténé avec la date et l'heure.
    Appelle la fonction d'extraction.\n
    Renvoie True si le contenu est extrait sans erreur; et, False sinon."""
    
    # Attention : sys.argv[0] est le chemin complet du script.
    nb_arguments = len(sys.argv) 
    
    # Le script est exécuté avec des arguments ?
    if nb_arguments < 2:
        print("Le script prend le fichier archive comme argument !")
        return False
    
    fichier_archive, dossier_extraction = "", ""
    
    # Le 1er argument est un fichier ?
    if os.path.isfile(sys.argv[1]) == False:
        print("Ce fichier archive n'existe pas !")
        return False
        
    fichier_archive = sys.argv[1]
    
    # Le 2è argument est un dossier d'extraction valide ?
    if nb_arguments == 3:
        if os.path.isdir(sys.argv[2]) == False:
            print("Le dossier d'extraction n'existe pas !")
            return False
        else:
            dossier_extraction = sys.argv[2]
            
    # Sinon, définir le dossier d'extraction par défaut
    else: 
        t = os.path.split(sys.argv[0])
        time_sec = time.time()
        date = time.localtime(time_sec)
        str = time.strftime("%Y%m%d_%H%M%S", date)
        dossier_extraction = os.path.join(t[0], fichier_archive + "_" + str)
    
    # Lance l'extraction en fonction du type d'archive .tar ou .rar.
    extension = os.path.splitext(fichier_archive)[1]
    if extension == ".gz" or extension == ".tar":
        return extraire_une_archive_tar(fichier_archive, dossier_extraction)
    elif extension == ".rar":
        return extraire_une_archive_rar(fichier_archive, dossier_extraction)
    else:
        print("\nL'archive n'est pas de type .tar ou .rar.")
        return False
    
    
def extraire_une_archive_tar(fichier_archive, dossier_extraction):
    """Extrait le contenu d'une archive au format tar avec ou sans 
    compression.\n
    'fichier_archive' est le chemin complet ou relatif du fichier archive
    à lire. Il porte l'extension .tar ou .tar.gz.\n
    'dossier_extraction' est le dossier complet d'extraction du
    contenu.\n
    Renvoie False, si le fichier n'est pas une archive au format tar.
    Renvoie False, si les fichiers extraits ne correspondent pas à l'archive.
    Renvoie True, si le contenu de l'archive est extrait.\n
    Appelée par executer()."""
    
    if tarfile.is_tarfile(fichier_archive) == False:
        print("\nL'extraction est impossible car l'archive est sans doute corrompue !")
        return False

    archive = tarfile.open(name = fichier_archive, mode = "r", errorlevel = 2)
    
    creer_dossier_extraction(dossier_extraction)
      
    # Créer le dict. des fichiers archive.
    les_fichiers_archive = {}
    info_archive = archive.getmembers()
    for info in info_archive:
        if info.isfile() == True:
            fichier = os.path.split(info.name)[1]
            les_fichiers_archive[fichier] = info.size
        elif info.isdir() == True:
            les_fichiers_archive[info.name] = 0
            

    extraction_du_contenu_rar_tar(archive, dossier_extraction)
    
    les_fichiers_extraits = liste_contenu_dossier(dossier_extraction)
    
    return comparer_contenu_et_extraction(les_fichiers_archive, les_fichiers_extraits)
    

def extraire_une_archive_rar(fichier_archive, dossier_extraction):
    """Extrait le contenu d'une archive au format rar avec ou sans 
    compression.\n
    'fichier_archive' est le chemin complet ou relatif du fichier archive
    à lire. Il porte l'extension .rar.\n
    'dossier_extraction' est le dossier complet d'extraction du
    contenu.\n
    Renvoie False, si le fichier n'est pas une archive au format rar.
    Renvoie False, si les fichiers extraits ne correspondent pas à l'archive.
    Renvoie True, si le contenu de l'archive est extrait.\n
    Appelée par executer()."""
    
    if rarfile.is_rarfile(fichier_archive) == False:
        print("\nL'extraction est impossible car l'archive est sans doute corrompue !")
        return False
    
    # Le classe RarFile utilise unrar.exe en mode commande pour extraire
    # l'archive. Il reste donc à définir la localisation de unrar.exe
    # avec la constante rarfile.UNRAR_TOOL.
    rarfile.UNRAR_TOOL = os.path.split(sys.argv[0])[0] + os.sep + rarfile.UNRAR_TOOL
    
    creer_dossier_extraction(dossier_extraction)
    
    archive = rarfile.RarFile(fichier_archive) # ouvre l'archive
       
    # Créer le dict. des fichiers archive.
    les_fichiers_archive = {}
    info_archive = archive.infolist()
    for info in info_archive:
        fichier = os.path.split(info.filename)[1]
        les_fichiers_archive[fichier] = info.file_size
    
    extraction_du_contenu_rar_tar(archive, dossier_extraction)
    
    les_fichiers_extraits = liste_contenu_dossier(dossier_extraction)
    
    return comparer_contenu_et_extraction(les_fichiers_archive, les_fichiers_extraits)
    
    
def extraction_du_contenu_rar_tar(archive, dossier_extraction):
    """Extrait le contenu d'une archive .rar ou .tar., et ferme l'archive.\n
    'fichier_archive' : l'archive.\n
    'dossier_extraction' : le dossier d'extraction.\n
    Appelée par extraire_une_archive_tar(), extraire_une_archive_rar()."""
    
    archive.extractall(path = dossier_extraction)
    archive.close()
    print("\nL'extraction est terminée.")

    
def comparer_contenu_et_extraction(les_fichiers_archive, les_fichiers_extraits):
    """Compare le contenu de l'archive avec les fichiers extraits.\n
    'les_fichiers_archive' : dict. des fichiers contenus dans l'archive.\n
    'les_fichiers_extraits' : dict. des fichiers extraits.\n
    Renvoie True s'il n'y a pas de différence ; False sinon.
    Appelée par extraire_une_archive_tar(), extraire_une_archive_rar()."""
    
    if les_fichiers_archive != les_fichiers_extraits:
        print("\nLes fichiers extraits ne correspondent pas à l'archive !")
        return False
    else:
        print("\nLes fichiers extraits correspondent à l'archive.")
        return True

    
def creer_dossier_extraction(dossier_extraction):
    """Création du dossier d'extraction.\n
    'dossier_extraction' : chemin absolu du dossier à créer.\n
    Appelée par extraire_une_archive_tar(), et extraire_une_archive_tar()."""
   
    if os.path.exists(dossier_extraction) == False: # Créer le dossier d'archive
        os.mkdir(dossier_extraction)
    
    print("\nL'archive est extraite dans " + dossier_extraction)

    
def liste_contenu_dossier(dossier_racine):
    """Liste le contenu d'un dossier.\n
    'dossier_racine' : chemin absolu du dossier.
    Renvoie un dictionnaire :\n
    fichier : taille"""
        
    les_fichiers = { }
    for dossier, sous_dossiers, fichiers in os.walk(dossier_racine):
        for ssd in sous_dossiers:
            les_fichiers[ssd] = 0
        for f in fichiers:
            statinfo = os.stat(os.path.join(dossier, f))
            taille_f = statinfo.st_size
            les_fichiers[f] = taille_f
            
    return les_fichiers

    
# -----------------------------------------------------------------------------
# Main
# -----------------------------------------------------------------------------

if __name__ == "__main__":
    if sys.argv[1] == "?": # afficher l'aide
        print("\n")
        print(__doc__)
    else:
        code_retour = executer()
        input("\n<ENTREE> pour terminer.")
        if code_retour == False:
            sys.exit(1)

Conclusion :


Win7 dispose d'un utilitaire pour extraire les archives .zip. Ce script est un complément pour traiter les archives .tar et .rar.

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.