mirror of
https://github.com/iluvcapra/wavinfo.git
synced 2026-01-02 18:00:41 +00:00
Implementing an interactive shell
...for browsing metadata
This commit is contained in:
@@ -7,6 +7,9 @@ import sys
|
|||||||
import json
|
import json
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
from base64 import b64encode
|
from base64 import b64encode
|
||||||
|
from cmd import Cmd
|
||||||
|
from shlex import split
|
||||||
|
from typing import List, Dict
|
||||||
|
|
||||||
|
|
||||||
class MyJSONEncoder(json.JSONEncoder):
|
class MyJSONEncoder(json.JSONEncoder):
|
||||||
@@ -23,6 +26,85 @@ class MissingDataError(RuntimeError):
|
|||||||
pass
|
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():
|
def main():
|
||||||
parser = OptionParser()
|
parser = OptionParser()
|
||||||
|
|
||||||
@@ -38,7 +120,15 @@ def main():
|
|||||||
default=False,
|
default=False,
|
||||||
action='store_true')
|
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)
|
(options, args) = parser.parse_args(sys.argv)
|
||||||
|
|
||||||
|
interactive_dict = []
|
||||||
|
|
||||||
for arg in args[1:]:
|
for arg in args[1:]:
|
||||||
try:
|
try:
|
||||||
this_file = WavInfoReader(path=arg)
|
this_file = WavInfoReader(path=arg)
|
||||||
@@ -65,7 +155,12 @@ def main():
|
|||||||
|
|
||||||
ret_dict['scopes'][scope][name] = value
|
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:
|
except MissingDataError as e:
|
||||||
print("MissingDataError: Missing metadata (%s) in file %s" %
|
print("MissingDataError: Missing metadata (%s) in file %s" %
|
||||||
(e, arg), file=sys.stderr)
|
(e, arg), file=sys.stderr)
|
||||||
@@ -73,6 +168,12 @@ def main():
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise e
|
raise e
|
||||||
|
|
||||||
|
if len(interactive_dict) > 0:
|
||||||
|
cli = MetaBrowser()
|
||||||
|
cli.metadata = interactive_dict
|
||||||
|
cli.cmdloop()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
|||||||
Reference in New Issue
Block a user