summaryrefslogtreecommitdiff
path: root/UnAr.py
blob: a6ba7a3f8f864c5c78ff23206a4cf88b62b5ffac (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
import os
import json
import subprocess

class Archive(object):

    def __init__(self,
        filename,
        password=None,
        encoding=None,
        password_encoding=None,
        no_recursion=False
        ):

        self.filename = filename
        self.password = password
        self.encoding = encoding
        self.password_encoding = password_encoding

        self.info = json.loads(subprocess.check_output(["lsar", "-j", filename]))

        self.contents = []

        if "lsarError" in self.info:
            print("Error {} while opening the archive.".format(info["lsarError"]))
            sys.exit()

        for c in self.info["lsarContents"]:
            if c.get("XADIsDirectory", None) == 1:
                d = Directory(self, c)
                self.contents.append(d)
            else:
                f = File(self, c)
                self.contents.append(f)

    def extract(self,
        output_directory=None,
        force_overwrite=False,
        force_rename=False,
        force_skip=False,
        force_directory=False,
        no_directory=False,
        indexes=False,
        no_recursion=False,
        copy_time=False,
        files=None,
        ):

        if isinstance(files, (str,unicode)):
            files = [files,]
        elif isinstance(files, int):
            files = str(files)
            files = [files,]

        s = ["unar", ]
        if output_directory is not None:
            s.append("-output-directory")
            s.append("{}".format(output_directory))
        if force_overwrite:
            s.append("-force-overwrite")
        if force_rename:
            s.append("-force-rename")
        if force_skip:
            s.append("force-skip")
        if force_directory:
            s.append("-force-directory")
        if no_directory:
            s.append("-no-directory")
        if self.password is not None:
            s.append("-password {}".format(self.password))
        if self.encoding is not None:
            s.append("-encoding {}".format(self.encoding))
        if self.password_encoding is not None:
            s.append("-password-encoding {}".format(self.password_encoding))
        if indexes:
            s.append("-indexes")
        if no_recursion:
            s.append("-no-recursion")
        if copy_time:
            s.append("-copy-time")
        s.append(self.filename)
        if files:
            s += files

        output = subprocess.call(s)

class Directory(object):
    def __init__(self, archive, handle):
        self.archive = archive
        self.handle = handle
        self.idx = handle.get("XADIndex", 0)
        self.name = handle.get("XADFileName", "")

    def extract(self, *args, **kwargs):
        self.archive.extract(*args, files=self.idx, indexes=True, **kwargs)

class File(object):
    def __init__(self, a, f):
        self.archive = archive
        self.handle = handle
        self.idx = handle.get("XADIndex", 0)
        self.name = handle.get("XADFileName", "")
        self.size = handle.get("XADFileSize", 0)
        self.compressed_size = handle.get("XADCompressedSize", 0)

    def __enter__(self):
        self.extract(output_directory="/tmp", force_overwrite=True, no_directory=True)
        self.tmp_path = os.path.join("/tmp", self.name)
        return self.tmp_path

    def __exit__(self, exc_type, exc_val, exc_tb):
        os.remove(self.tmp_path)
        return False

    def extract(self, *args, **kwargs):
        self.archive.extract(*args, files=self.idx, indexes=True, **kwargs)