mirror of
https://github.com/iluvcapra/wavinfo.git
synced 2025-12-31 08:50:41 +00:00
179 lines
5.1 KiB
Python
179 lines
5.1 KiB
Python
import datetime
|
|
from . import WavInfoReader
|
|
from . import __version__
|
|
|
|
from optparse import OptionParser
|
|
import sys
|
|
import json
|
|
from enum import Enum
|
|
from base64 import b64encode
|
|
from cmd import Cmd
|
|
from shlex import split
|
|
from typing import List, Dict
|
|
|
|
|
|
class MyJSONEncoder(json.JSONEncoder):
|
|
def default(self, o):
|
|
if isinstance(o, Enum):
|
|
return o._name_
|
|
elif isinstance(o, bytes):
|
|
return 'base64:' + b64encode(o).decode('ascii')
|
|
else:
|
|
return super().default(o)
|
|
|
|
|
|
class MissingDataError(RuntimeError):
|
|
pass
|
|
|
|
|
|
class MetaBrowser(Cmd):
|
|
prompt = "(wavinfo) "
|
|
|
|
metadata: List | Dict
|
|
path: List[str] = []
|
|
|
|
@property
|
|
def cwd(self):
|
|
root: List | Dict = self.metadata
|
|
for key in self.path:
|
|
if isinstance(root, list):
|
|
root = root[int(key)]
|
|
else:
|
|
root = root[key]
|
|
|
|
return root
|
|
|
|
@staticmethod
|
|
def print_value(collection, key):
|
|
val = collection[key]
|
|
if isinstance(val, int):
|
|
print(f" - {key}: {val}")
|
|
elif isinstance(val, str):
|
|
print(f" - {key}: \"{val}\"")
|
|
elif isinstance(val, dict):
|
|
print(f" - {key}: Dict ({len(val)} keys)")
|
|
elif isinstance(val, list):
|
|
print(f" - {key}: List ({len(val)} keys)")
|
|
elif isinstance(val, bytes):
|
|
print(f" - {key}: ({len(val)} bytes)")
|
|
elif val is None:
|
|
print(f" - {key}: (NO VALUE)")
|
|
else:
|
|
print(f" - {key}: Unknown")
|
|
|
|
def do_ls(self, _):
|
|
'List items at the current node: LS'
|
|
root = self.cwd
|
|
|
|
if isinstance(root, list):
|
|
print("List:")
|
|
for i in range(len(root)):
|
|
self.print_value(root, i)
|
|
|
|
elif isinstance(root, dict):
|
|
print("Dictionary:")
|
|
for key in root:
|
|
self.print_value(root, key)
|
|
|
|
else:
|
|
print("Cannot print node, is not a list or dictionary.")
|
|
|
|
def do_cd(self, args):
|
|
'Switch to a different node: CD node-name | ".."'
|
|
argv = split(args)
|
|
if argv[0] == "..":
|
|
self.path = self.path[0:-1]
|
|
else:
|
|
if isinstance(self.cwd, list):
|
|
if int(argv[0]) < len(self.cwd):
|
|
self.path = self.path + [argv[0]]
|
|
else:
|
|
print(f"Index {argv[0]} does not exist")
|
|
elif isinstance(self.cwd, dict):
|
|
if argv[0] in self.cwd.keys():
|
|
self.path = self.path + [argv[0]]
|
|
else:
|
|
print(f"Key \"{argv[0]}\" does not exist")
|
|
|
|
if len(self.path) > 0:
|
|
self.prompt = "(" + "/".join(self.path) + ") "
|
|
else:
|
|
self.prompt = "(wavinfo) "
|
|
|
|
def do_bye(self, _):
|
|
'Exit the interactive browser: BYE'
|
|
return True
|
|
|
|
|
|
def main():
|
|
parser = OptionParser()
|
|
|
|
parser.usage = 'wavinfo (--adm | --ixml) <FILE> +'
|
|
|
|
parser.add_option('--adm', dest='adm',
|
|
help='Output ADM XML',
|
|
default=False,
|
|
action='store_true')
|
|
|
|
parser.add_option('--ixml', dest='ixml',
|
|
help='Output iXML',
|
|
default=False,
|
|
action='store_true')
|
|
|
|
parser.add_option('-i',
|
|
help='Read metadata with an interactive prompt',
|
|
default=False,
|
|
action='store_true')
|
|
|
|
(options, args) = parser.parse_args(sys.argv)
|
|
|
|
interactive_dict = []
|
|
|
|
for arg in args[1:]:
|
|
try:
|
|
this_file = WavInfoReader(path=arg)
|
|
if options.adm:
|
|
if this_file.adm:
|
|
sys.stdout.write(this_file.adm.xml_str())
|
|
else:
|
|
raise MissingDataError("adm")
|
|
elif options.ixml:
|
|
if this_file.ixml:
|
|
sys.stdout.write(this_file.ixml.xml_str())
|
|
else:
|
|
raise MissingDataError("ixml")
|
|
else:
|
|
ret_dict = {
|
|
'filename': arg,
|
|
'run_date': datetime.datetime.now().isoformat(),
|
|
'application': "wavinfo " + __version__,
|
|
'scopes': {}
|
|
}
|
|
for scope, name, value in this_file.walk():
|
|
if scope not in ret_dict['scopes'].keys():
|
|
ret_dict['scopes'][scope] = {}
|
|
|
|
ret_dict['scopes'][scope][name] = value
|
|
|
|
if options.i:
|
|
interactive_dict.append(ret_dict)
|
|
else:
|
|
json.dump(ret_dict, cls=MyJSONEncoder, fp=sys.stdout,
|
|
indent=2)
|
|
|
|
except MissingDataError as e:
|
|
print("MissingDataError: Missing metadata (%s) in file %s" %
|
|
(e, arg), file=sys.stderr)
|
|
continue
|
|
except Exception as e:
|
|
raise e
|
|
|
|
if len(interactive_dict) > 0:
|
|
cli = MetaBrowser()
|
|
cli.metadata = interactive_dict
|
|
cli.cmdloop()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|