-
Notifications
You must be signed in to change notification settings - Fork 0
/
jz.py
146 lines (124 loc) · 3.61 KB
/
jz.py
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
import zlib
from gc import collect
from sys import argv
from os import getcwd, chdir
VERSION = "1.2.5"
def compress(*argv):
"""
Note: compression cannot be done on the controller
itself at the moment.
"""
# starting print
objc = len(argv) - 1
targetfile = argv[objc]
print(f"Compressing {objc} files onto {targetfile}")
# let's create the string
ctlstr = ""
datastr = bytes()
# the control string format is:
# file1 file1len file2 file2len |eocf
for i in range(0, objc):
fnamee = argv[i]
if fnamee.find("/") != -1:
# file not in cwd, we have to cut the name for the control string
fnamee = fnamee[
fnamee.rfind("/", 1) + 1 :
] # remove everything up until the last /, including the slash
ctlstr += f"{fnamee} " # do not remove the whitespace
try:
with open(argv[i], "rb") as togetlelen:
inpt = togetlelen.read()
ctlstr += f"{len(inpt)} " # do not remove the whitespace
print(f"Loading: {fnamee} ({len(inpt)} bytes)")
datastr += inpt # copying bytes, not str
del inpt
except OSError:
print(
f"Error: Could not open file {argv[i]}"
) # intentionally letting it show the full path
return 1
del i
collect()
collect()
del objc
ctlstr += "|eocf"
total = bytes(ctlstr, "utf-8") + datastr
del datastr
del ctlstr
collect()
collect()
# zlib em
out = zlib.compress(total)
del total
# write to .jz
with open(targetfile, "wb") as jzfile:
jzfile.write(out)
del out
jzfile.flush()
del targetfile
# done
return 0
def decompress(filee, directory=".", quiet=False, debug=False):
if not quiet:
print(
f"Decompressing {filee} into {directory if directory != '.' else 'the current directory'}"
)
# dump file inputted
with open(filee, "rb") as inpf:
dataa = inpf.read()
if debug:
print("Dumped to ram")
# switch to target dir
olddir = getcwd()
chdir(directory)
if debug:
print("switched to target")
# unzlib data
unz = zlib.decompress(dataa)
if debug:
print("decomp done")
del dataa
collect()
collect()
# read control string
ctlstr = str(unz[: unz.find(bytes("|eocf", "utf-8"), 0)], "utf-8")
ctlarr = ctlstr.split()
if debug:
print("parsed control")
# set stepper variables
offset = unz.find(bytes("|eocf", "utf-8"), 0) + 5
for i in range(0, int(len(ctlarr)), 2): # skipping over len
fname = ctlarr[i]
lco = int(ctlarr[i + 1])
if not quiet:
print(f"Extracting: {fname} ({lco} bytes)")
try:
with open(fname, "wb") as fout:
fout.write(unz[offset : offset + lco])
fout.flush()
except OSError:
print("Error: Could not write file")
return 1
offset += lco
del lco, fname
collect()
collect()
if debug:
print("done")
# cleanup
del unz
# switch back to start dir
chdir(olddir)
del olddir
return 0
def help():
print(
f"""
About: jz file compression module.
Version: {VERSION} - Author: Bill Sideris (bill88t)
This project is licenced under the MIT licence.
Usage: jz.compress(\"file1\", \"file2\", \"jz_archive_name\")
jz.decompress(\"jz_archive_name\")
"""
)
return 0