mirror of
https://github.com/iluvcapra/wavinfo.git
synced 2025-12-31 08:50:41 +00:00
Implementing an interactive shell
...for browsing metadata
This commit is contained in:
@@ -7,6 +7,9 @@ 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):
|
||||
@@ -23,6 +26,85 @@ 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 == 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(f"List:")
|
||||
for i in range(len(root)):
|
||||
self.print_value(root, i)
|
||||
|
||||
elif isinstance(root, dict):
|
||||
print(f"Dictionary:")
|
||||
for key in root:
|
||||
self.print_value(root, key)
|
||||
|
||||
else:
|
||||
print(f"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()
|
||||
|
||||
@@ -38,7 +120,15 @@ def main():
|
||||
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)
|
||||
@@ -65,7 +155,12 @@ def main():
|
||||
|
||||
ret_dict['scopes'][scope][name] = value
|
||||
|
||||
json.dump(ret_dict, cls=MyJSONEncoder, fp=sys.stdout, indent=2)
|
||||
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)
|
||||
@@ -73,6 +168,12 @@ def main():
|
||||
except Exception as e:
|
||||
raise e
|
||||
|
||||
if len(interactive_dict) > 0:
|
||||
cli = MetaBrowser()
|
||||
cli.metadata = interactive_dict
|
||||
cli.cmdloop()
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
Reference in New Issue
Block a user