-
Notifications
You must be signed in to change notification settings - Fork 0
/
mass-unpack.py
85 lines (75 loc) · 2.63 KB
/
mass-unpack.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
"""
unpacks rar files that are double-packed
]usually scene-release files are packed this way[
"""
__author__ = 'iexa'
from pathlib import Path
import rarfile as rf
from time import time
# import zipfile as zf
def unpack(file, todir):
"""unpacks a double-packed file; needs unrar on syspath; returns Path of it or False"""
def testpath(z):
"""test file exts for rar multipart start -input: Path.suffixes list"""
if len(z) == 1 and z[0] == '.rar': return True
elif len(z) >= 2 and z[-2] in ('.part1', '.part01'): return True
elif len(z) >= 2 and z[-1] == '.rar' and '.part' not in z[-2]: return True
return False
z = rf.RarFile(file, crc_check=False)
extraction_dir = Path(z.namelist()[0]).parent
print(' '*7, f"| {file.stat().st_size>>20}mb unpacking...", end='', flush=True)
t0 = time()
try:
z.extractall(path=todir)
except rf.Error:
print(' '*7, f'\nINFO: ==> CHECK <== ARCHIVE FILE ERROR ?CRC or PASSWORD?')
z.close()
return False
z.close()
inside = [x for x in (todir/extraction_dir).iterdir() if testpath(x.suffixes)]
if len(inside) != 1:
print(' '*7, f'\nINFO: ==> CHECK <== CANNOT UNPACK INSIDE FILE(s)')
return False
print(f'{round(time()-t0,1)}s, now the inner one...', end='', flush=True)
t0 = time()
inside = inside[0]
z = rf.RarFile(inside, crc_check=False)
final_file = z.namelist()[0]
if len(z.namelist()) > 1:
print(' '*7, f'\nINFO: ==> CHECK <== MORE THAN 1 INSIDE FILES')
return False
try:
z.extractall(path=(todir/extraction_dir))
except rf.Error:
print(' '*7, f'\nINFO: ==> CHECK <== INSIDE ARCHIVE FILE ERROR ?CRC or PASSWORD?')
z.close()
return False
z.close()
print(f'{round(time()-t0,1)}s done.', flush=True)
return todir / extraction_dir / final_file
""" MAIN """
startpath = Path('/Volumes/X3/SWTEMP')
t0 = time()
allfiles = tuple(startpath.glob('*.rar'))
allfiles_cnt = len(allfiles)
print(f'>>> Unpacking from {startpath}')
for nr, p1 in enumerate(allfiles, start=1):
print(f'{str(nr).zfill(3)}/{str(allfiles_cnt).zfill(3)}: {p1.name}', flush=True)
gotit = unpack(p1, startpath)
if not gotit:
print('-'*7, '==> CHECK <== something went wrong with this one')
continue
# some filename massaging
rename_to = str(gotit.parent.relative_to(startpath))
rename_to = rename_to.translate(rename_to.maketrans('_.', ' '))
rename_to = rename_to.partition(' eShop')[0] + '.nsp'
gotit.rename(startpath / Path(rename_to))
# cleanup files
for x in gotit.parent.iterdir():
x.unlink()
gotit.parent.rmdir()
p1.unlink()
# if nr > 77:
# break
t1 = int(time()-t0)
print(f'>>> DONE in {t1//60}m {t1%60}s - [phew!]')