1
0
Fork 0
sstvdec/sstv/command.py

138 lines
4.5 KiB
Python
Raw Normal View History

2019-07-15 11:18:24 -06:00
"""Parsing arguments and starting program from command line"""
2019-07-15 10:46:41 -06:00
2019-10-31 04:53:09 -06:00
import argparse
from sys import argv, exit
2019-10-31 04:53:09 -06:00
from PIL import Image
from soundfile import available_formats as available_audio_formats
from .common import log_message
2019-07-15 10:28:23 -06:00
from .decode import SSTVDecoder
2019-07-15 12:57:36 -06:00
from .spec import VIS_MAP
2019-07-15 10:28:23 -06:00
2019-07-15 10:46:41 -06:00
2019-07-15 10:28:23 -06:00
class SSTVCommand(object):
"""Main class to handle the command line features"""
2019-07-15 10:28:23 -06:00
examples_of_use = """
examples:
Decode local SSTV audio file named 'audio.ogg' to 'result.png':
$ sstv -d audio.ogg
Decode SSTV audio file in /tmp to './image.jpg':
$ sstv -d /tmp/signal.wav -o ./image.jpg
2019-07-18 11:01:21 -06:00
Start decoding SSTV signal at 50.5 seconds into the audio
2019-10-31 04:47:12 -06:00
$ sstv -d audio.ogg -s 50.50"""
2019-07-15 10:28:23 -06:00
def __init__(self, shell_args=None):
"""Handle command line arguments"""
2019-07-15 10:28:23 -06:00
self._audio_file = None
self._output_file = None
if shell_args is None:
self.args = self.parse_args(argv[1:])
else:
self.args = self.parse_args(shell_args)
2019-07-15 10:28:23 -06:00
def __enter__(self):
return self
def __exit__(self, exc_type, exc_val, traceback):
self.close()
def __del__(self):
self.close()
def init_args(self):
"""Initialise argparse parser"""
2019-07-15 10:28:23 -06:00
version = "sstv 0.1"
parser = argparse.ArgumentParser(
prog="sstv",
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog=self.examples_of_use)
parser.add_argument("-d", "--decode", type=argparse.FileType('rb'),
2019-07-16 00:57:05 -06:00
help="decode SSTV audio file", dest="audio_file")
parser.add_argument("-o", "--output", type=str,
2019-07-16 00:57:05 -06:00
help="save output image to custom location",
default="result.png", dest="output_file")
parser.add_argument("-s", "--skip", type=float,
help="time in seconds to start decoding signal at",
default=0.0, dest="skip")
2019-07-15 10:46:41 -06:00
parser.add_argument("-V", "--version", action="version",
version=version)
2019-07-15 10:28:23 -06:00
parser.add_argument("--list-modes", action="store_true",
dest="list_modes",
help="list supported SSTV modes")
parser.add_argument("--list-audio-formats", action="store_true",
dest="list_audio_formats",
help="list supported audio file formats")
parser.add_argument("--list-image-formats", action="store_true",
dest="list_image_formats",
help="list supported image file formats")
return parser
def parse_args(self, shell_args):
"""Parse command line arguments"""
2019-07-15 10:28:23 -06:00
parser = self.init_args()
args = parser.parse_args(shell_args)
2019-07-15 10:28:23 -06:00
self._audio_file = args.audio_file
self._output_file = args.output_file
2019-07-16 00:57:05 -06:00
self._skip = args.skip
2019-07-15 10:46:41 -06:00
2019-07-15 10:28:23 -06:00
if args.list_modes:
self.list_supported_modes()
exit(0)
if args.list_audio_formats:
self.list_supported_audio_formats()
exit(0)
if args.list_image_formats:
self.list_supported_image_formats()
exit(0)
if self._audio_file is None:
parser.print_help()
exit(2)
return args
def start(self):
"""Start decoder"""
2019-07-15 10:28:23 -06:00
with SSTVDecoder(self._audio_file) as sstv:
2019-07-16 00:57:05 -06:00
img = sstv.decode(self._skip)
2019-07-15 14:40:08 -06:00
if img is None: # No SSTV signal found
exit(2)
2019-07-15 10:28:23 -06:00
try:
img.save(self._output_file)
except (KeyError, ValueError):
log_message("Error saving file, saved to result.png instead",
err=True)
2019-07-15 10:28:23 -06:00
img.save("result.png")
2019-07-15 10:46:41 -06:00
2019-07-15 10:28:23 -06:00
def close(self):
"""Closes any input/output files if they exist"""
2019-07-15 10:28:23 -06:00
if self._audio_file is not None and not self._audio_file.closed:
self._audio_file.close()
def list_supported_modes(self):
2019-07-15 12:57:36 -06:00
modes = ', '.join([fmt.NAME for fmt in VIS_MAP.values()])
print("Supported modes: {}".format(modes))
2019-07-15 10:28:23 -06:00
def list_supported_audio_formats(self):
2019-07-15 12:57:36 -06:00
audio_formats = ', '.join(available_audio_formats().keys())
print("Supported audio formats: {}".format(audio_formats))
2019-07-15 10:28:23 -06:00
def list_supported_image_formats(self):
2019-07-15 12:57:36 -06:00
Image.init()
image_formats = ', '.join(Image.SAVE.keys())
print("Supported image formats: {}".format(image_formats))