码迷,mamicode.com
首页 > 编程语言 > 详细

python 压缩 解压

时间:2017-10-12 14:03:34      阅读:169      评论:0      收藏:0      [点我收藏+]

标签:解压   pass   package   tmp   字典   elf   return   color   ted   

unrar在Linux机器中对中文的支持有漏洞

class DecompressionModel:
    def __init__(self):
        pass

    @staticmethod
    def decompression(rar_file, specified_list, destination_path):
        """

        :param rar_file: abstract path of rar_file
        :param specified_list: the specified directory list
        :param destination_path: destination path for unrar
        :return:
        """
        # DecompressionModel._rar_decompression_command(rarfile, specified_list, base_path)
        if rar_file.endswith(".rar"):
            DecompressionModel._rar_decompression_unrar(rar_file, specified_list, destination_path)
            DecompressionModel._rar_decompression_command(rar_file, specified_list, destination_path)
        else:
            if rar_file.endswith(".zip"):
                DecompressionModel._zip_decompression(rar_file, specified_list, destination_path)
            else:
                error_out_print("Error: decompression file [%s] is not zip or rar file. please have a check." % rar_file)
                sys.exit(-1)

    @staticmethod
    def _zip_decompression(zip_file, specified_list, destination_path):
        zip_decompression(zip_file, destination_path, specified_list)

    @staticmethod
    def _rar_decompression_command(rar_file, specified_list, destination_path):
        standout_print("Info: decompression with command.rar file [%s],specified list %s, in base path[%s]" % (rar_file, specified_list, destination_path))
        if specified_list:
            for specified_directory in specified_list:
                DecompressionModel._unrar_command(rar_file, specified_directory, destination_path)
        else:
            DecompressionModel._unrar_command(rar_file, None, destination_path)

    @staticmethod
    def _rar_decompression_unrar(rar_file, specified_list, destination_path):
        standout_print("Info: decompression with unrar package. rar file [%s],specified list %s, in base path[%s]" % (rar_file, specified_list, destination_path))
        rar_file = rar_file.replace("\\", "/")
        destination_path = destination_path.replace("\\", "/")

        if not os.path.exists(rar_file) or rar_file.find(".rar") == -1:
            error_out_print("Error: rar file not exist or this file is not rar file.[%s] " % rar_file)
            sys.exit(-1)

        unrar_model = UNRARModel(rar_filename=rar_file, to_path=destination_path)

        if specified_list:
            unrar_model.decompression_list(specified_list)
        else:
            unrar_model.decompression_file()
        standout_print("Info: unrar file done.from [%s] to [%s]." % (rar_file, destination_path))
        if specified_list:
            standout_print("Info: the specified directory is [%s]" % specified_list)

    @staticmethod
    def _unrar_command(rar_file, specified_directory, base_path):
        if not os.path.exists(rar_file) or (not rar_file.endswith(".rar")):
            error_out_print("Error: rar file not exist.[%s] or is not a rar file. please have a check" % rar_file)
            sys.exit(-1)

        if not os.path.exists(base_path):
            standout_print("Failed: rar decompression base path[%s] not exist." % base_path)
            os.makedirs(base_path)
            # sys.exit(-1)

        os.chdir(base_path)
        temp_dir = None
        if specified_directory:
            # unrar extract the specified directory
            # if the specified directory exist, it will full decompression, but we want partly
            # 1. create temp
            if os.path.exists(specified_directory):
                temp_dir = os.path.join(base_path, str(time()))
                os.chdir(temp_dir)
            # 2. unrar
            cmd = "unrar x %s %s>/dev/null 2>&1" % (rar_file, specified_directory)
        else:
            # unrar this rar files
            cmd = "unrar x %s>/dev/null 2>&1" % rar_file
        standout_print("Info: base dir [%s]" % os.path.abspath(os.curdir))
        execute_cmd(cmd)
        # after unrar remove ,rar file
        # remove_file(rar_file)
        if temp_dir:
            for file_name in os.listdir(os.path.join(temp_dir, specified_directory)):
                # move files in tmp_path/specified_directory to to_path
                from_path = os.path.join(temp_dir, specified_directory, file_name)
                to_path = os.path.join(base_path, specified_directory)
                move_directory(from_path, to_path)
            remove_dirs(temp_dir)


class UNRARModel:
    def __init__(self, rar_filename, to_path):
        self.rar_file = rar_filename
        self.to_path = to_path
        self.infolist = None
        self.rar_obj = None

        self.init()

    def init(self):
        self.rar_obj = rarfile.RarFile(path_to_unicode(self.rar_file))
        self.infolist = self.rar_obj.infolist()

    def _extract_list(self, selected_dir):
        """
        use rarfile decompression specified directory must give the full name of file
        like unrar ALL.rar ALL/EX_INFO/SCENICROUT is wrong here,
        must :
        1. find files which in ALL/EX_INFO/SCENICROUT
        2. get these files name and return
        :param selected_dir:
        :return:
        """
        selected_infolist = []
        for d in selected_dir:
            for info in self.infolist:
                filename = info.filename.replace("\\", "/")  # in win
                if filename.find(d) != -1 and info.file_size != 0L:
                    selected_infolist.append(info)

        return selected_infolist

    def decompression_list(self, selected_dir):
        """
        extract the Specified directory
        :param selected_dir: Specified directory
        :return:
        """
        selected_infolist = self._extract_list(selected_dir)
        for member in selected_infolist:
            self.rar_obj.extract(path=self.to_path, member=member)

    def decompression_file(self):
        for info in self.infolist:
            filename = info.filename
            self.rar_obj.extract(path_to_unicode(filename), path=path_to_unicode(self.to_path))

components.py

import sys
import os
import shutil
import zipfile
import tarfile


def standout_print(info):
    """
    print information to standout
    :param info:
    :return:
    """
    if type(info) == unicode:
        info = info.encode("utf-8")
    sys.stdout.write("%s" % info)
    sys.stdout.write("\n")
    sys.stdout.flush()


def error_out_print(info):
    """
    print error message
    :param info:
    :return:
    """
    if type(info) == unicode:
        info = info.encode("utf-8")
    sys.stderr.write(info)
    sys.stderr.write("\n")
    sys.stderr.flush()


def remove_file(file_path):
    """
    remove file
    :param file_path:
    :return:
    """
    if os.path.exists(file_path):
        os.remove(file_path)
        standout_print("Info: remove files %s finish." % file_path)
    else:
        error_out_print("Error: remove file not exist.[%s]" % file_path)
        sys.exit(-1)


def remove_dirs(dir_path):
    dir_path = path_to_str(dir_path)
    if os.path.exists(dir_path):
        shutil.rmtree(dir_path)
        standout_print("Info: remove directory %s finish." % dir_path)
    else:
        error_out_print("Error: remove directory not exist.[%s]" % dir_path)
        sys.exit(-1)


def check_directory(dic_path):
    """
    check this directory is empty or not
    :param dic_path:
    :return:
    """
    if not os.path.exists(dic_path):
        return False

    if not os.listdir(dic_path):
        return False

    return True


def execute_cmd(cmd):
    cmd = cmd.strip()
    standout_print("Info: execute command [ %s ] . " % cmd)
    result_statue = os.system(cmd)

    if not cmd and result_statue:
        error_out_print("Error: execute command [%s]. program stop" % cmd)
        sys.exit(-1)

    standout_print("Info: execute cmd[%s] success." % cmd)
    return True


# def move_directory(from_directory, to_directory):
#     if not os.path.exists(from_directory):
#         error_out_print("Error: mv directory is not exist. please check [%s]" % from_directory)
#         sys.exit(-1)
#
#     mv_cmd = "mv %s %s" % (from_directory,to_directory)
#     execute_cmd(mv_cmd)


def move_directory(from_path, to_path):
    """
    directory from_path `s basename
    move directory of from_path to to_path
    :param from_path:
    :param to_path:
    :return:
    """
    if not os.path.exists(from_path):
        error_out_print("Error: mv directory is not exist. please check [%s]" % path_to_str(from_path))
        sys.exit(-1)
    standout_print("Info: begin move files in [%s] to [%s] finished." % (path_to_str(from_path), path_to_str(to_path)))
    to_file = os.path.join(to_path, os.path.basename(from_path))
    if os.path.exists(to_file):
        if os.path.isdir(to_file):
            remove_dirs(to_file)
        if os.path.isfile(to_file):
            remove_file(to_file)
    shutil.move(from_path, to_path)
    standout_print("Info: move directory from[%s] to [%s] finished." % (path_to_str(from_path), path_to_str(to_path)))


def zip_decompression(zip_file, to_path, specified_list=None):
    #
    if not os.path.exists(zip_file):
        error_out_print("Error: zip file[ % ] is not exist." % zip_file)
        sys.exit(-1)
    if not zipfile.is_zipfile(zip_file):
        error_out_print("Error: zip file[  % ] is not a zip file. please check" % zipfile)
        sys.exit(-1)

    fz = zipfile.ZipFile(zip_file, "r")
    if not specified_list:
        specified_list = fz.namelist()

    for file_name in specified_list:
        fz.extract(file_name, to_path)
    standout_print("Info: zip decompress finish. file[%s] to [%s]." % (zip_file, to_path))


def make_targz(tar_from_path_list, tar_to_file_path, base_dir):
    standout_print("Info: tar gz data in %s to [%s], in basedir [%s]" % (tar_from_path_list, tar_to_file_path, base_dir))
    tar_to_file_path = os.path.join(base_dir, tar_to_file_path)
    tar_to_file_path = tar_to_file_path.replace("\\", "/")
    with tarfile.open(tar_to_file_path, "w:gz") as tar_file:
        for tar_from_path in tar_from_path_list:
            tar_from_path = os.path.join(base_dir, tar_from_path.strip())
            tar_from_path = tar_from_path.replace("\\", "/")
            arc_name = tar_from_path.replace(base_dir, "").strip(os.path.sep)
            tar_file.add(tar_from_path, arcname=arc_name)
        tar_file.close()
        standout_print("Info: tar directory %s to file [%s] finish." % (tar_from_path_list, tar_to_file_path))
        return

    standout_print("Error: tar directory %s to file [%s] failed. please have a check." % (tar_from_path_list, tar_to_file_path))
    sys.exit(-1)


def make_zip(zip_from_file_path, zip_to_file_path, base_dir):
    standout_print("Info: zip [%s] to file [%s] in path[%s]." % (zip_from_file_path, zip_to_file_path, base_dir))
    zip_to_file_path = os.path.join(base_dir, zip_to_file_path)
    zip_file = zipfile.ZipFile(zip_to_file_path, w, zipfile.ZIP_DEFLATED)

    data_path = os.path.join(base_dir, zip_from_file_path)
    data_path = data_path.replace("\\", "/")

    pre_len = len(data_path)
    for p, dirs, file_names in os.walk(data_path):
        for filename in file_names:
            file_path = os.path.join(p, filename).replace("\\", "/")
            arc_name = file_path[pre_len:].strip(os.path.sep)
            zip_file.write(file_path, arc_name)

    zip_file.close()
    standout_print("Info: finish zip.")


def path_to_unicode(path_name, coding="utf-8"):
    """
    this method use to find file or directory which contains chinese
    if not use this transform
    os.listdir(path) and os.walk() will wrong in window platform
    :param path_name: name of path
    :param coding:
    :return:
    """
    if not type(path_name) == unicode:
        return unicode(path_name, coding)
    return path_name


def path_to_str(path_name, coding="utf-8"):
    """
    this method will change path which is unicode type
    to str type
    because in linux platform unicode obj + str obi will exception
    :param path_name:
    :param coding:
    :return:
    """
    if type(path_name) == unicode:
        return path_name.encode(coding)
    return path_name


def parse_path(path, deep=1):
    """

    :param path:
    :param deep:
    :return:
    """
    path = path_to_unicode(path)
    structure_dic = {}
    file_list = os.listdir(path)
    for f in file_list:
        f_path = os.path.join(path, f)
        structure_value = None
        if os.path.isdir(f_path):
            if deep < 3:
                structure_value = parse_path(f_path, deep=(deep + 1))
            else:
                structure_value = ""
        structure_dic[f] = structure_value
    return structure_dic


def compare_dic(dic_new, dic_format):
    import operator
    return operator.ge(dic_new, dic_format)


if __name__ == __main__:
    parse_directory = rD:\test_temp\tmp_autonav\17Q2_A5_20170630
    structure_directory = parse_path(parse_directory)
    import json

    json_data = json.dumps(structure_directory)
    print json_data

利用python 对各种格式的文件压缩 解压 操作,文件的一些操作,目录结构读成字典的形式,字典的比较方法(http://www.runoob.com/python/att-dictionary-cmp.html)。

python 压缩 解压

标签:解压   pass   package   tmp   字典   elf   return   color   ted   

原文地址:http://www.cnblogs.com/dasheng-maritime/p/7655657.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!