306 lines
9.3 KiB
Python
306 lines
9.3 KiB
Python
import os
|
|
import sys
|
|
import yaml
|
|
|
|
|
|
class Config:
|
|
def __init__(self):
|
|
# Load initial config file
|
|
if len(sys.argv) > 1:
|
|
config_file = sys.argv[1]
|
|
else:
|
|
config_file = os.path.join(os.path.dirname(__file__), "ptv.yaml")
|
|
self.load_config(config_file)
|
|
|
|
# Load the profile explicitly at the end of initiailization so that
|
|
# profile settings take precedence over global config settings
|
|
self.load_config(os.path.join(self.profile, "profile.yaml"))
|
|
|
|
def load_config(self, filename):
|
|
with open(filename, "r") as infile:
|
|
self._image_closed = None
|
|
self._image_open = None
|
|
self._image_blink_closed = None
|
|
self._image_blink_open = None
|
|
|
|
for k, v in yaml.load(infile, Loader=yaml.Loader).items():
|
|
# This ugly thing checks if a config parameter named in the
|
|
# config file maps to a class property. If not, we throw an
|
|
# error and exit because the config file is broken.
|
|
# FIXME: Find a better way to do this
|
|
if not isinstance(getattr(type(self), k, None), property):
|
|
print(f"Invalid config paramter: {k}")
|
|
sys.exit(1)
|
|
setattr(self, k, v)
|
|
|
|
@property
|
|
def profile(self):
|
|
try:
|
|
return self._profile
|
|
except AttributeError:
|
|
print("profile is a required parameter")
|
|
sys.exit(1)
|
|
|
|
@profile.setter
|
|
def profile(self, profile):
|
|
# Check filename is a string
|
|
if not isinstance(profile, str):
|
|
print("Config paramter profile must be a valid filename")
|
|
sys.exit(1)
|
|
|
|
# Look for file in working dir and script dir
|
|
targets = [os.path.join(os.path.dirname(__file__), profile), profile]
|
|
|
|
for target in targets:
|
|
if os.path.exists(target):
|
|
if not os.path.exists(os.path.join(target, "profile.yaml")):
|
|
print(f"Profile path {profile} does not contain a profile.yaml file")
|
|
sys.exit(1)
|
|
self._profile = target
|
|
self.load_config(os.path.join(target, "profile.yaml"))
|
|
return
|
|
|
|
# Can't find the profile file, fail
|
|
print(f"Cannot find file {profile}")
|
|
sys.exit(1)
|
|
|
|
@property
|
|
def image_closed(self):
|
|
try:
|
|
return self._image_closed
|
|
except AttributeError:
|
|
print("image_closed is a required paramter")
|
|
sys.exit(1)
|
|
|
|
@image_closed.setter
|
|
def image_closed(self, filename):
|
|
# Check filename is a string
|
|
if not isinstance(filename, str):
|
|
print("Config parameter image_closed must be a valid filename")
|
|
|
|
# Look for the file in profile dir, script dir, and working dir
|
|
targets = [os.path.join(self.profile, filename), os.path.join(os.path.dirname(__file__), filename), filename]
|
|
|
|
for target in targets:
|
|
if os.path.exists(target):
|
|
self._image_closed = target
|
|
return
|
|
|
|
# Can't find the image, fail
|
|
print(f"Cannot find file {filename}")
|
|
sys.exit(1)
|
|
|
|
@property
|
|
def image_open(self):
|
|
try:
|
|
return self._image_open
|
|
except AttributeError:
|
|
return None
|
|
|
|
@image_open.setter
|
|
def image_open(self, filename):
|
|
# Check filename is a string
|
|
if not isinstance(filename, str):
|
|
print("Config parameter image_open must be a valid filename")
|
|
|
|
# Look for the file in profile dir, script dir, and working dir
|
|
targets = [os.path.join(self.profile, filename), os.path.join(os.path.dirname(__file__), filename), filename]
|
|
|
|
for target in targets:
|
|
if os.path.exists(target):
|
|
self._image_open = target
|
|
return
|
|
|
|
# Can't find the image, fail
|
|
print(f"Cannot find file {filename}")
|
|
sys.exit(1)
|
|
|
|
@property
|
|
def image_blink_open(self):
|
|
try:
|
|
return self._image_blink_open
|
|
except AttributeError:
|
|
return None
|
|
|
|
@image_blink_open.setter
|
|
def image_blink_open(self, filename):
|
|
# Check filename is a string
|
|
if not isinstance(filename, str):
|
|
print("Config parameter image_blink_open must be a valid filename")
|
|
|
|
# Look for the file in profile dir, script dir, and working dir
|
|
targets = [os.path.join(self.profile, filename), os.path.join(os.path.dirname(__file__), filename), filename]
|
|
|
|
for target in targets:
|
|
if os.path.exists(target):
|
|
self._image_blink_open = target
|
|
return
|
|
|
|
# Can't find the image, fail
|
|
print(f"Cannot find file {filename}")
|
|
sys.exit(1)
|
|
|
|
@property
|
|
def image_blink_closed(self):
|
|
try:
|
|
return self._image_blink_closed
|
|
except AttributeError:
|
|
return None
|
|
|
|
@image_blink_closed.setter
|
|
def image_blink_closed(self, filename):
|
|
# Check filename is a string
|
|
if not isinstance(filename, str):
|
|
print("Config parameter image_blink_closed must be a valid filename")
|
|
|
|
# Look for the file in profile dir, script dir, and working dir
|
|
targets = [os.path.join(self.profile, filename), os.path.join(os.path.dirname(__file__), filename), filename]
|
|
|
|
for target in targets:
|
|
if os.path.exists(target):
|
|
self._image_blink_closed = target
|
|
return
|
|
|
|
# Can't find the image, fail
|
|
print(f"Cannot find file {filename}")
|
|
sys.exit(1)
|
|
|
|
@property
|
|
def bg_color(self):
|
|
try:
|
|
return self._bg_color
|
|
except AttributeError:
|
|
return (0, 0, 0)
|
|
|
|
@bg_color.setter
|
|
def bg_color(self, color):
|
|
if not isinstance(color, (list, tuple)) or len(color) != 3:
|
|
print("Config parameter bg_color must be a three-item list")
|
|
sys.exit(1)
|
|
self._bg_color = color
|
|
|
|
@property
|
|
def audio_checks(self):
|
|
try:
|
|
return self._audio_checks
|
|
except AttributeError:
|
|
return 60
|
|
|
|
@audio_checks.setter
|
|
def audio_checks(self, checks):
|
|
if not isinstance(checks, int):
|
|
print("Config parameter audio_checks must be an integer")
|
|
sys.exit(1)
|
|
self._audio_checks = checks
|
|
|
|
@property
|
|
def threshold(self):
|
|
try:
|
|
return self._threshold
|
|
except AttributeError:
|
|
return 6000
|
|
|
|
@threshold.setter
|
|
def threshold(self, threshold):
|
|
if not isinstance(threshold, int):
|
|
print("Config parameter threshold must be an integer")
|
|
sys.exit(1)
|
|
self._threshold = threshold
|
|
|
|
@property
|
|
def smoothing(self):
|
|
try:
|
|
return self._smoothing
|
|
except AttributeError:
|
|
return 3
|
|
|
|
@smoothing.setter
|
|
def smoothing(self, smoothing):
|
|
if not isinstance(smoothing, int):
|
|
print("Config paramter smoothing must be an integer")
|
|
sys.exit(1)
|
|
self._smoothing = smoothing
|
|
|
|
@property
|
|
def mic_rate(self):
|
|
try:
|
|
return self._mic_rate
|
|
except AttributeError:
|
|
return 44100
|
|
|
|
@mic_rate.setter
|
|
def mic_rate(self, rate):
|
|
if not isinstance(rate, int):
|
|
print("Config paramter mic_rate must be an integer")
|
|
sys.exit(1)
|
|
self._mic_rate = rate
|
|
|
|
@property
|
|
def mic_stereo(self):
|
|
try:
|
|
return self._mic_stereo
|
|
except AttributeError:
|
|
return True
|
|
|
|
@mic_stereo.setter
|
|
def mic_stereo(self, is_stereo):
|
|
if not isinstance(is_stereo, bool):
|
|
print("Config paramter mic_stereo must be a boolean")
|
|
sys.exit(1)
|
|
self._mic_stereo = True
|
|
|
|
@property
|
|
def blink_frames(self):
|
|
try:
|
|
return self._blink_frames
|
|
except AttributeError:
|
|
return 0
|
|
|
|
@blink_frames.setter
|
|
def blink_frames(self, frames):
|
|
if not isinstance(frames, int):
|
|
print("Config parameter blink_frames must be an integer")
|
|
sys.exit(1)
|
|
self._blink_frames = frames
|
|
|
|
@property
|
|
def blink_chance(self):
|
|
try:
|
|
return self._blink_chance
|
|
except AttributeError:
|
|
return 0
|
|
|
|
@blink_chance.setter
|
|
def blink_chance(self, chance):
|
|
if not isinstance(chance, float) and not isinstance(chance, int):
|
|
print("Config parameter blink_chance must be an integer or float")
|
|
sys.exit(1)
|
|
self._blink_chance = chance
|
|
|
|
@property
|
|
def shake_delay(self):
|
|
try:
|
|
return self._shake_delay
|
|
except AttributeError:
|
|
return 0
|
|
|
|
@shake_delay.setter
|
|
def shake_delay(self, delay):
|
|
if not isinstance(delay, int):
|
|
print("Config parameter shake_delay must be an integer")
|
|
sys.exit(1)
|
|
self._shake_delay = delay
|
|
|
|
@property
|
|
def shake_intensity(self):
|
|
try:
|
|
return self._shake_intensity
|
|
except AttributeError:
|
|
return 0
|
|
|
|
@shake_intensity.setter
|
|
def shake_intensity(self, intensity):
|
|
if not isinstance(intensity, int):
|
|
print("Config parameter shake_intensity must be an integer")
|
|
sys.exit(1)
|
|
self._shake_intensity = intensity
|