From 1013603612bef7ebef52db433c5031da8de47cea Mon Sep 17 00:00:00 2001
From: Paul Pettit
Date: Thu, 20 Apr 2017 15:20:45 +0100
Subject: [PATCH 1/4] properly validate and parse profile options.
this should make it so that validation and parsing of profile
options uses the same logic, see #507
---
galicaster/recorder/base.py | 10 +-
galicaster/utils/validator.py | 273 ++++++++++++++++++----------------
2 files changed, 148 insertions(+), 135 deletions(-)
diff --git a/galicaster/recorder/base.py b/galicaster/recorder/base.py
index 3da68b8c..ddb8f5a7 100644
--- a/galicaster/recorder/base.py
+++ b/galicaster/recorder/base.py
@@ -66,12 +66,14 @@ def __init__(self, options):
# TODO parsear
for k, v in options.iteritems():
- if v:
- self.options[k] = validator.parse_automatic(v)
-
+ gc_parameter = None
+ if self.gc_parameters.has_key(k):
+ gc_parameter = self.gc_parameters[k]
+ if v is not None:
+ error, self.options[k] = validator.parse_validate(k, v, gc_parameter)
# Validate option values
try:
- global_error, self.options = validator.validate_track(self.options)
+ global_error, self.options = validator.validate_track(self.options, gc_parameters=self.gc_parameters)
except Exception as exc:
error_msg = 'Profile error in {0}, track {1}. {2}'.format(
path, self.options['name'], exc)
diff --git a/galicaster/utils/validator.py b/galicaster/utils/validator.py
index d00ae4ee..2ca62873 100644
--- a/galicaster/utils/validator.py
+++ b/galicaster/utils/validator.py
@@ -60,135 +60,8 @@ def set_default():
global_error_msg = None
for k,v in gc_parameters.iteritems():
- if not options[k] and options[k] is not False and options[k] is not 0:
- set_default()
- continue
-
- if v['type'] == 'integer':
- if type(options[k]) != int:
- if not re.search('[^0-9]',options[k]):
- options[k] = int(options[k])
- else:
- current_error = 'INFO: Parameter "{}" with value {} must be {}'.format(k, options[k], v['type'])
-
- if options[k] < v['range'][0] or options[k] > v['range'][1]:
- current_error = 'INFO: Parameter "{}" with value {} out of range {}'.format(
- k, options[k], v['range'])
-
-
- elif v['type'] == 'float':
- try:
- options[k] = float(options[k])
- if options[k] < v['range'][0] or options[k] > v['range'][1]:
- current_error = 'INFO: Parameter "{}" with value {} out of range {}'.format(
- k, options[k], v['range'])
- except:
- current_error = 'INFO: Parameter "{}" with value {} must be {}'.format(
- k, options[k], v['type'])
-
-
- elif v['type'] == 'hexadecimal':
- try:
- int(options[k])
- except Exception as exc:
- current_error = 'INFO: Parameter "{}" with value {} must be {}: {}'.format(
- k, options[k], v['type'], exc)
-
-
- elif v['type'] == 'boolean':
- parse = options[k]
-
- if type(options[k]) == type(''):
- parse = options[k].lower()
- if parse in [True, 'true', 'yes', 1, '1', "True"]:
- options[k] = True
- elif parse in [False, 'false', 'no', 0, '0', "False"]:
- options[k] = False
- else:
- current_error = 'INFO: Parameter "{}" with value {} must be an accepted {} ({}). Boolean parser ignores case'.format(
- k, options[k], v['type'],'true, yes, 1, false, no, 0')
-
-
- elif v['type'] == 'flavor' and options[k] not in FLAVOR:
- current_error = 'INFO: Parameter "{}" with value {} is not a valid {}. Valid flavors are {}'.format(k, options[k], v['type'], FLAVOR)
-
-
- elif v['type'] == 'select' and options[k] not in v['options']:
- current_error = 'INFO: Parameter "{}" with value {} must be a valid option {}'.format(k, options[k], v['options'])
-
- elif v['type'] == 'list':
- # If it is not a list try to convert to dict using JSON
- if not (type(options[k]) is list):
- try:
- options[k] = json.loads(options[k], "utf-8")
- except Exception as exc:
- current_error = 'INFO: Parameter "{}" with value {} must be {}. {}'.format(
- k, options[k], v['type'], exc)
-
- # Check if now it is a list
- if not (type(options[k]) is list):
- if not current_error:
- current_error = 'INFO: Parameter "{}" with value {} must be {}'.format(
- k, options[k], v['type'])
-
-
- elif v['type'] == 'dict':
- # If it is not a dict try to convert to dict using JSON
- if not isinstance(options[k], dict):
- try:
- options[k] = json.loads(options[k], "utf-8")
- except Exception as exc:
- current_error = 'INFO: Parameter "{}" with value {} must be {}. {}'.format(
- k, options[k], v['type'], exc)
-
- # Parse dict
- if not isinstance(options[k], dict):
- if not current_error:
- current_error = 'INFO: Parameter "{}" with value {} must be {}.'.format(
- k, options[k], v['type'])
- # else:
- # iteration_error, options[k] = validate_track(options[k], v['default'], recursive=True)
- # current_error = iteration_error
-
-
- #TODO add check location tests and check only in bins with location
- #if v['type'] == 'device' and type(self).__name__ != 'GCpulse' and not path.exists(options[k]):
- # raise SystemError('Parameter "{0}" on {1} is not a valid {2}'.format(
- # k, type(self).__name__ , v['type']))
-
-
- # TODO improve the caps validation
- # https://gstreamer.freedesktop.org/data/doc/gstreamer/head/pwg/html/section-types-definitions.html#table-video-types
- elif v['type'] == 'caps':
- try:
- caps = Gst.Caps.from_string(options[k])
- structure = caps.get_structure(0)
- caps_name = structure.get_name()
-
- # Must be a tuple (True, value), it would be false if it is not defined
- # Note that caps like 'video/x-raw,framerate=5/1' does not have height or width but it works anyway
- # if not structure.get_int('height')[0]:
- # if not current_error:
- # current_error = 'INFO: Parameter "{}" with value {} must have a height defined.'.format(k, options[k])
-
- # if not structure.get_int('width')[0]:
- # if not current_error:
- # current_error = 'INFO: Parameter "{}" with value {} must be a width defined.'.format(
- # k, options[k])
-
- if not "video" in caps_name and not "image" in caps_name:
- if not current_error:
- current_error = 'INFO: Parameter "{}" with value {} must be of type video or image.'.format(
- k, options[k])
-
- except Exception as exc:
- current_error = 'INFO: Parameter "{}" with value {} must be valid caps. {}'.format(
- k, options[k], exc)
-
-
- # If the value is not set, put the default value
- if options[k] is None and v.has_key("default") :
- options[k] = v['default']
+ current_error, value = parse_validate(k, options[k], v)
+ options[k] = value
if current_error:
if not recursive:
@@ -207,8 +80,6 @@ def set_default():
global_error_msg = current_error
current_error = None
-
-
return global_error_msg, options
@@ -221,6 +92,146 @@ def get_gc_parameters_from_bin(device):
return Klass.gc_parameters
+def parse_validate(k, option, gc_parameter=None):
+ current_error = None
+
+ if not gc_parameter:
+ return current_error, option
+
+ if not option and option is not False and option is not 0:
+ # If the value is not set, put the default value
+ if gc_parameter.has_key("default") :
+ option = parse_automatic(gc_parameter['default'])
+ return current_error, option
+
+ if gc_parameter['type'] == 'integer':
+ if type(option) != int:
+ if not re.search('[^0-9]',option):
+ option = int(option)
+ else:
+ current_error = 'INFO: Parameter "{}" with value {} must be {}'.format(k, option, gc_parameter['type'])
+
+ if option < gc_parameter['range'][0] or option > gc_parameter['range'][1]:
+ current_error = 'INFO: Parameter "{}" with value {} out of range {}'.format(
+ k, option, gc_parameter['range'])
+
+
+ elif gc_parameter['type'] == 'float':
+ try:
+ option = float(option)
+ if option < gc_parameter['range'][0] or option > gc_parameter['range'][1]:
+ current_error = 'INFO: Parameter "{}" with value {} out of range {}'.format(
+ k, option, gc_parameter['range'])
+ except:
+ current_error = 'INFO: Parameter "{}" with value {} must be {}'.format(
+ k, option, gc_parameter['type'])
+
+
+ elif gc_parameter['type'] == 'hexadecimal':
+ try:
+ int(option)
+ except Exception as exc:
+ current_error = 'INFO: Parameter "{}" with value {} must be {}: {}'.format(
+ k, option, gc_parameter['type'], exc)
+
+
+ elif gc_parameter['type'] == 'boolean':
+ parse = option
+
+ if type(option) == type(''):
+ parse = option.lower()
+ if parse in [True, 'true', 'yes', 1, '1', "True"]:
+ option = True
+ elif parse in [False, 'false', 'no', 0, '0', "False"]:
+ option = False
+ else:
+ current_error = 'INFO: Parameter "{}" with value {} must be an accepted {} ({}). Boolean parser ignores case'.format(
+ k, option, gc_parameter['type'],'true, yes, 1, false, no, 0')
+
+
+ elif gc_parameter['type'] == 'flavor' and option not in FLAVOR:
+ current_error = 'INFO: Parameter "{}" with value {} is not a valid {}. Valid flavors are {}'.format(k, option, gc_parameter['type'], FLAVOR)
+
+
+ elif gc_parameter['type'] == 'select' and option not in gc_parameter['options']:
+ current_error = 'INFO: Parameter "{}" with value {} must be a valid option {}'.format(k, option, gc_parameter['options'])
+
+ elif gc_parameter['type'] == 'list':
+ # If it is not a list try to convert to dict using JSON
+ if not (type(option) is list):
+ try:
+ option = json.loads(option, "utf-8")
+ except Exception as exc:
+ current_error = 'INFO: Parameter "{}" with value {} must be {}. {}'.format(
+ k, option, gc_parameter['type'], exc)
+
+ # Check if now it is a list
+ if not (type(option) is list):
+ if not current_error:
+ current_error = 'INFO: Parameter "{}" with value {} must be {}'.format(
+ k, option, gc_parameter['type'])
+
+
+ elif gc_parameter['type'] == 'dict':
+ # If it is not a dict try to convert to dict using JSON
+ if not isinstance(option, dict):
+ try:
+ option = json.loads(option, "utf-8")
+ except Exception as exc:
+ current_error = 'INFO: Parameter "{}" with value {} must be {}. {}'.format(
+ k, option, gc_parameter['type'], exc)
+
+ # Parse dict
+ if not isinstance(option, dict):
+ if not current_error:
+ current_error = 'INFO: Parameter "{}" with value {} must be {}.'.format(
+ k, option, gc_parameter['type'])
+ # else:
+ # iteration_error, options[k] = validate_track(options[k], v['default'], recursive=True)
+ # current_error = iteration_error
+
+
+ #TODO add check location tests and check only in bins with location
+ #if v['type'] == 'device' and type(self).__name__ != 'GCpulse' and not path.exists(options[k]):
+ # raise SystemError('Parameter "{0}" on {1} is not a valid {2}'.format(
+ # k, type(self).__name__ , v['type']))
+
+
+ # TODO improve the caps validation
+ # https://gstreamer.freedesktop.org/data/doc/gstreamer/head/pwg/html/section-types-definitions.html#table-video-types
+ elif gc_parameter['type'] == 'caps':
+ try:
+ caps = Gst.Caps.from_string(option)
+ structure = caps.get_structure(0)
+ caps_name = structure.get_name()
+
+ # Must be a tuple (True, value), it would be false if it is not defined
+ # Note that caps like 'video/x-raw,framerate=5/1' does not have height or width but it works anyway
+ # if not structure.get_int('height')[0]:
+ # if not current_error:
+ # current_error = 'INFO: Parameter "{}" with value {} must have a height defined.'.format(k, options[k])
+
+ # if not structure.get_int('width')[0]:
+ # if not current_error:
+ # current_error = 'INFO: Parameter "{}" with value {} must be a width defined.'.format(
+ # k, options[k])
+
+ if not "video" in caps_name and not "image" in caps_name:
+ if not current_error:
+ current_error = 'INFO: Parameter "{}" with value {} must be of type video or image.'.format(
+ k, option)
+
+ except Exception as exc:
+ current_error = 'INFO: Parameter "{}" with value {} must be valid caps. {}'.format(
+ k, option, exc)
+
+
+ # If the value is not set, put the default value
+ if option is None and gc_parameter.has_key("default") :
+ option = gc_parameter['default']
+
+ return current_error, option
+
def parse_automatic(value):
# Parses from string to integer, float, boolean... If not returns the string
try:
From 770defb2ac95bc6ad368edbb7c1a8e27134d557e Mon Sep 17 00:00:00 2001
From: Paul Pettit
Date: Fri, 21 Apr 2017 12:45:29 +0100
Subject: [PATCH 2/4] refactor profile validation
---
galicaster/core/conf.py | 9 +-
galicaster/recorder/base.py | 10 +-
galicaster/utils/validator.py | 279 ++++++++++++++--------------------
3 files changed, 122 insertions(+), 176 deletions(-)
diff --git a/galicaster/core/conf.py b/galicaster/core/conf.py
index 18897961..6e02cbe3 100644
--- a/galicaster/core/conf.py
+++ b/galicaster/core/conf.py
@@ -22,9 +22,6 @@
from datetime import datetime
from galicaster.utils import validator
-YES = ['true', 'yes', 'ok', 'si', 'y']
-NO = ['false', 'no', 'n']
-
"""
These classes shapes the galicaster configuration.
The Conf class gets all the configurable parameters and recording profiles including the default one.
@@ -235,9 +232,9 @@ def get_boolean(self, sect, opt, default=False):
Bool: the value of option opt in section sect as a boolean if there are no errors. Default otherwise.
"""
value = self.get_lower(sect, opt)
- if value in YES:
+ if value in validator.YES:
return True
- elif value in NO:
+ elif value in validator.NO:
return False
else:
self.logger and self.logger.warning('Unknown value "{0}" obtaining a boolean from the parameter "{1}" in section "{2}", FORCED TO "{3}"'.format(value, opt, sect, default))
@@ -658,7 +655,7 @@ def create_profile_from_conf(self, activated=True):
profile.import_tracks_from_parser(parser)
if activated:
- def f(x): return x.get('active', 'true').lower() in YES
+ def f(x): return x.get('active', 'true').lower() in validator.YES
profile.tracks = filter(f, profile.tracks)
return profile
diff --git a/galicaster/recorder/base.py b/galicaster/recorder/base.py
index ddb8f5a7..d95a804f 100644
--- a/galicaster/recorder/base.py
+++ b/galicaster/recorder/base.py
@@ -65,21 +65,13 @@ def __init__(self, options):
self.options = dict([(k,v['default']) for k,v in self.gc_parameters.iteritems()])
# TODO parsear
+ # Validate option values
for k, v in options.iteritems():
gc_parameter = None
if self.gc_parameters.has_key(k):
gc_parameter = self.gc_parameters[k]
if v is not None:
error, self.options[k] = validator.parse_validate(k, v, gc_parameter)
- # Validate option values
- try:
- global_error, self.options = validator.validate_track(self.options, gc_parameters=self.gc_parameters)
- except Exception as exc:
- error_msg = 'Profile error in {0}, track {1}. {2}'.format(
- path, self.options['name'], exc)
-
- logger.error(error_msg)
- raise SystemError(error_msg)
# Sanitaze values
self.options["name"] = re.sub(r'\W+', '', self.options["name"])
diff --git a/galicaster/utils/validator.py b/galicaster/utils/validator.py
index 2ca62873..2976b5d8 100644
--- a/galicaster/utils/validator.py
+++ b/galicaster/utils/validator.py
@@ -22,62 +22,38 @@
from gi.repository import Gst
-#import gst
-
FLAVOR = ['presenter', 'presentation', 'other']
+YES = [True, 'true', 'yes', 'ok', 'si', 'y', 1, '1']
+NO = [False, 'false', 'no', 'n', 0, '0']
-def validate_track(options, gc_parameters=None, recursive=False):
+def validate_track(options, gc_parameters=None):
""" Transforms string on proper types and checks value validity """
- def set_default():
- # If the value is not set, put the default value
- if v.has_key("default") :
- options[k] = parse_automatic(v['default'])
-
- #try:
- # get_module(options['device'])
- #except:
- # raise SystemError(
- # "Track {0}: device type {0} doesn't exists.".format(
- # options['name'],options['device']))
-
- iteration_error = None
+ global_error_msg = None
options = dict(options)
if not gc_parameters:
gc_parameters = get_gc_parameters_from_bin(options['device'])
- # Init options with default gc_parameters values and options
- default_options = dict([(k,parse_automatic(v['default'])) for k,v in gc_parameters.iteritems()])
-
- for k, v in options.iteritems():
- default_options[k] = parse_automatic(v)
-
- options = default_options.copy()
-
current_error = None
- global_error_msg = None
- for k,v in gc_parameters.iteritems():
- current_error, value = parse_validate(k, options[k], v)
+ for k, gc_parameter in gc_parameters.iteritems():
+ v = None
+ if options.has_key(k):
+ v = options[k]
+ current_error, value = parse_validate(k, v, gc_parameter)
options[k] = value
if current_error:
- if not recursive:
- if global_error_msg:
- global_error_msg = "{} - {}, forced to {}.".format(
- global_error_msg, current_error, v['default'])
- else:
- global_error_msg = "{}, forced to {}.".format(
- current_error, v['default'])
-
- if not iteration_error:
- options[k] = v['default']
-
+ if global_error_msg:
+ global_error_msg = "{} - {}, forced to {}.".format(
+ global_error_msg, current_error, gc_parameter['default'])
else:
- options[k] = v['default']
- global_error_msg = current_error
+ global_error_msg = "{}, forced to {}.".format(
+ current_error, gc_parameter['default'])
+
+ options[k] = gc_parameter['default']
current_error = None
return global_error_msg, options
@@ -91,151 +67,132 @@ def get_gc_parameters_from_bin(device):
return Klass.gc_parameters
+def check_range(key, value, gc_parameter):
+ current_error = None
+ if value < gc_parameter['range'][0] or value > gc_parameter['range'][1]:
+ value = gc_parameter['default']
+ current_error = 'INFO: Parameter "{}" with value {} out of range {}. Forced to {}'.format(
+ key, value, gc_parameter['range'], value)
+ return current_error, value
def parse_validate(k, option, gc_parameter=None):
current_error = None
-
if not gc_parameter:
return current_error, option
- if not option and option is not False and option is not 0:
+ if option is None:
# If the value is not set, put the default value
if gc_parameter.has_key("default") :
- option = parse_automatic(gc_parameter['default'])
- return current_error, option
+ option = gc_parameter['default']
- if gc_parameter['type'] == 'integer':
- if type(option) != int:
- if not re.search('[^0-9]',option):
+ if option is not None:
+ if gc_parameter['type'] == 'integer':
+ try:
option = int(option)
- else:
+ current_error, option = check_range(k, option, gc_parameter)
+ except ValueError as exc:
current_error = 'INFO: Parameter "{}" with value {} must be {}'.format(k, option, gc_parameter['type'])
- if option < gc_parameter['range'][0] or option > gc_parameter['range'][1]:
- current_error = 'INFO: Parameter "{}" with value {} out of range {}'.format(
- k, option, gc_parameter['range'])
-
-
- elif gc_parameter['type'] == 'float':
- try:
- option = float(option)
- if option < gc_parameter['range'][0] or option > gc_parameter['range'][1]:
- current_error = 'INFO: Parameter "{}" with value {} out of range {}'.format(
- k, option, gc_parameter['range'])
- except:
- current_error = 'INFO: Parameter "{}" with value {} must be {}'.format(
- k, option, gc_parameter['type'])
-
-
- elif gc_parameter['type'] == 'hexadecimal':
- try:
- int(option)
- except Exception as exc:
- current_error = 'INFO: Parameter "{}" with value {} must be {}: {}'.format(
- k, option, gc_parameter['type'], exc)
-
-
- elif gc_parameter['type'] == 'boolean':
- parse = option
-
- if type(option) == type(''):
- parse = option.lower()
- if parse in [True, 'true', 'yes', 1, '1', "True"]:
- option = True
- elif parse in [False, 'false', 'no', 0, '0', "False"]:
- option = False
- else:
- current_error = 'INFO: Parameter "{}" with value {} must be an accepted {} ({}). Boolean parser ignores case'.format(
- k, option, gc_parameter['type'],'true, yes, 1, false, no, 0')
-
-
- elif gc_parameter['type'] == 'flavor' and option not in FLAVOR:
- current_error = 'INFO: Parameter "{}" with value {} is not a valid {}. Valid flavors are {}'.format(k, option, gc_parameter['type'], FLAVOR)
-
-
- elif gc_parameter['type'] == 'select' and option not in gc_parameter['options']:
- current_error = 'INFO: Parameter "{}" with value {} must be a valid option {}'.format(k, option, gc_parameter['options'])
-
- elif gc_parameter['type'] == 'list':
- # If it is not a list try to convert to dict using JSON
- if not (type(option) is list):
+ elif gc_parameter['type'] == 'float':
try:
- option = json.loads(option, "utf-8")
- except Exception as exc:
- current_error = 'INFO: Parameter "{}" with value {} must be {}. {}'.format(
- k, option, gc_parameter['type'], exc)
-
- # Check if now it is a list
- if not (type(option) is list):
- if not current_error:
+ option = float(option)
+ current_error, option = check_range(k, option, gc_parameter)
+ except:
current_error = 'INFO: Parameter "{}" with value {} must be {}'.format(
k, option, gc_parameter['type'])
-
- elif gc_parameter['type'] == 'dict':
- # If it is not a dict try to convert to dict using JSON
- if not isinstance(option, dict):
+ elif gc_parameter['type'] == 'hexadecimal':
try:
- option = json.loads(option, "utf-8")
+ option = int(str(option), 16)
except Exception as exc:
- current_error = 'INFO: Parameter "{}" with value {} must be {}. {}'.format(
+ current_error = 'INFO: Parameter "{}" with value {} must be {}: {}'.format(
k, option, gc_parameter['type'], exc)
- # Parse dict
- if not isinstance(option, dict):
- if not current_error:
- current_error = 'INFO: Parameter "{}" with value {} must be {}.'.format(
- k, option, gc_parameter['type'])
- # else:
- # iteration_error, options[k] = validate_track(options[k], v['default'], recursive=True)
- # current_error = iteration_error
-
-
- #TODO add check location tests and check only in bins with location
- #if v['type'] == 'device' and type(self).__name__ != 'GCpulse' and not path.exists(options[k]):
- # raise SystemError('Parameter "{0}" on {1} is not a valid {2}'.format(
- # k, type(self).__name__ , v['type']))
-
-
- # TODO improve the caps validation
- # https://gstreamer.freedesktop.org/data/doc/gstreamer/head/pwg/html/section-types-definitions.html#table-video-types
- elif gc_parameter['type'] == 'caps':
- try:
- caps = Gst.Caps.from_string(option)
- structure = caps.get_structure(0)
- caps_name = structure.get_name()
+ elif gc_parameter['type'] == 'boolean':
+ parse = option
- # Must be a tuple (True, value), it would be false if it is not defined
- # Note that caps like 'video/x-raw,framerate=5/1' does not have height or width but it works anyway
- # if not structure.get_int('height')[0]:
- # if not current_error:
- # current_error = 'INFO: Parameter "{}" with value {} must have a height defined.'.format(k, options[k])
-
- # if not structure.get_int('width')[0]:
- # if not current_error:
- # current_error = 'INFO: Parameter "{}" with value {} must be a width defined.'.format(
- # k, options[k])
-
- if not "video" in caps_name and not "image" in caps_name:
- if not current_error:
- current_error = 'INFO: Parameter "{}" with value {} must be of type video or image.'.format(
- k, option)
-
- except Exception as exc:
- current_error = 'INFO: Parameter "{}" with value {} must be valid caps. {}'.format(
- k, option, exc)
+ if type(option) == type(''):
+ parse = option.lower()
+ if parse in YES:
+ option = True
+ elif parse in NO:
+ option = False
+ else:
+ current_error = 'INFO: Parameter "{}" with value {} must be an accepted {} ({}). Boolean parser ignores case'.format(
+ k, option, gc_parameter['type'],'true, yes, 1, false, no, 0')
+
+ elif gc_parameter['type'] == 'flavor' and option not in FLAVOR:
+ current_error = 'INFO: Parameter "{}" with value {} is not a valid {}. Valid flavors are {}'.format(k, option, gc_parameter['type'], FLAVOR)
+
+ elif gc_parameter['type'] == 'select' and option not in gc_parameter['options']:
+ current_error = 'INFO: Parameter "{}" with value {} must be a valid option {}'.format(k, option, gc_parameter['options'])
+
+ elif gc_parameter['type'] == 'list':
+ # If it is not a list try to convert to dict using JSON
+ if type(option) is not list:
+ try:
+ option = json.loads(option, "utf-8")
+ except Exception as exc:
+ current_error = 'INFO: Parameter "{}" with value {} must be {}. {}'.format(
+ k, option, gc_parameter['type'], exc)
+
+ # Check if now it is a list
+ if type(option) is not list:
+ if not current_error:
+ current_error = 'INFO: Parameter "{}" with value {} must be {}'.format(
+ k, option, gc_parameter['type'])
+
+ elif gc_parameter['type'] == 'dict':
+ # If it is not a dict try to convert to dict using JSON
+ if not isinstance(option, dict):
+ try:
+ option = json.loads(option, "utf-8")
+ except Exception as exc:
+ current_error = 'INFO: Parameter "{}" with value {} must be {}. {}'.format(
+ k, option, gc_parameter['type'], exc)
+
+ # Parse dict
+ if not isinstance(option, dict):
+ if not current_error:
+ current_error = 'INFO: Parameter "{}" with value {} must be {}.'.format(
+ k, option, gc_parameter['type'])
+
+ #TODO add check location tests and check only in bins with location
+ #if v['type'] == 'device' and type(self).__name__ != 'GCpulse' and not path.exists(options[k]):
+ # raise SystemError('Parameter "{0}" on {1} is not a valid {2}'.format(
+ # k, type(self).__name__ , v['type']))
+
+ # TODO improve the caps validation
+ # https://gstreamer.freedesktop.org/data/doc/gstreamer/head/pwg/html/section-types-definitions.html#table-video-types
+ elif gc_parameter['type'] == 'caps':
+ try:
+ caps = Gst.Caps.from_string(option)
+ structure = caps.get_structure(0)
+ caps_name = structure.get_name()
+
+ # Must be a tuple (True, value), it would be false if it is not defined
+ # Note that caps like 'video/x-raw,framerate=5/1' does not have height or width but it works anyway
+ # if not structure.get_int('height')[0]:
+ # if not current_error:
+ # current_error = 'INFO: Parameter "{}" with value {} must have a height defined.'.format(k, options[k])
+
+ # if not structure.get_int('width')[0]:
+ # if not current_error:
+ # current_error = 'INFO: Parameter "{}" with value {} must be a width defined.'.format(
+ # k, options[k])
+
+ if not "video" in caps_name and not "image" in caps_name:
+ if not current_error:
+ current_error = 'INFO: Parameter "{}" with value {} must be of type video or image.'.format(
+ k, option)
+
+ except Exception as exc:
+ current_error = 'INFO: Parameter "{}" with value {} must be valid caps. {}'.format(
+ k, option, exc)
# If the value is not set, put the default value
- if option is None and gc_parameter.has_key("default") :
+ if option is None or current_error and gc_parameter.has_key("default") :
option = gc_parameter['default']
return current_error, option
-
-def parse_automatic(value):
- # Parses from string to integer, float, boolean... If not returns the string
- try:
- return ast.literal_eval(value)
- except:
- return value
- return value
From 1c252c73124e310cfbadd82748e57199f56e2fc2 Mon Sep 17 00:00:00 2001
From: Paul Pettit
Date: Fri, 21 Apr 2017 12:54:42 +0100
Subject: [PATCH 3/4] remove unused iumports
---
galicaster/utils/validator.py | 2 --
1 file changed, 2 deletions(-)
diff --git a/galicaster/utils/validator.py b/galicaster/utils/validator.py
index 2976b5d8..48ebb152 100644
--- a/galicaster/utils/validator.py
+++ b/galicaster/utils/validator.py
@@ -16,9 +16,7 @@
"""
import sys
-import re
import json
-import ast
from gi.repository import Gst
From 83443c42c87f9e47521979a5beb914d7aa225aee Mon Sep 17 00:00:00 2001
From: Paul Pettit
Date: Fri, 21 Apr 2017 13:12:06 +0100
Subject: [PATCH 4/4] restore accidentally commented out section
---
galicaster/recorder/base.py | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/galicaster/recorder/base.py b/galicaster/recorder/base.py
index d95a804f..ab2863f1 100644
--- a/galicaster/recorder/base.py
+++ b/galicaster/recorder/base.py
@@ -54,10 +54,10 @@ def __init__(self, options):
if current_profile:
path = current_profile.path
# Check the profile parameters (*.ini)
- # for k in options:
- # if k not in self.gc_parameters and k not in ['device', 'active', 'path']:
- # logger.warning('Does not exit the parameter "{0}". Please check the file {1}'.format(
- # k, current_profile_path))
+ for k in options:
+ if k not in self.gc_parameters and k not in ['device', 'active', 'path']:
+ logger.warning('The profile parameter "{0}" does not exist. Please check the file {1}'.format(
+ k, path))