forked from EMATech/soundcraft-show-format
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathextract.py
executable file
·77 lines (57 loc) · 2.24 KB
/
extract.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
#!/bin/env python
# -*- coding: utf-8 -*-
"""A CLI tool to extract Soundcraft Show files"""
from __future__ import print_function
__author__ = 'Raphaël Doursenaud'
import argparse
import sys
from base64 import b64decode
from zlib import decompress
from os.path import basename, splitext, join, exists
from os import mkdir
from bs4 import BeautifulSoup
parser = argparse.ArgumentParser(description="Extract Soundcraft Show files.")
parser.add_argument('infiles', metavar="INFILE", type=argparse.FileType('r'),
default=sys.stdin, nargs='+',
help="The show file(s) to extract.")
args = parser.parse_args()
for file in args.infiles:
print("Processing " + file.name + ", ", end="")
soup = BeautifulSoup(file, features='xml')
collection = soup('MHxDFile')
size = len(collection)
outfilepath = basename(file.name)
# Remove extension
outfilepath = splitext(outfilepath)[0]
print("found " + str(size) + " files")
# Prepare output folder
if not exists(outfilepath):
mkdir(outfilepath)
for entry in collection:
filename = entry['name']
# Extract only filename from path
filename = filename.rsplit('\\', 1)[-1]
print("Processing (decoding & decompressing) " + filename + " in ./" + outfilepath + "/")
checksum = int(entry['checksum'])
datalength = int(entry['datalength'])
contents = entry.contents[0]
# Base64 decode
try:
contents = b64decode(contents, validate=True)
except TypeError:
# We're most likely running python 2, let's try without validate
contents = b64decode(contents)
# zlib decompress
contents = decompress(contents)
# TODO: Validate the data against the checksum when identified
if len(contents) != datalength:
raise Exception("Data size missmatch!")
# Write result to file
outfile = join(outfilepath, filename)
if exists(outfile):
answer = input("File " + outfile + " already exists! Overwrite? [y/N]")
if not answer in ['Y', 'y']:
print("Skipping…")
continue
with open(outfile, 'wb') as fh:
fh.write(contents)