# -*- coding: utf-8 -*-
"""
Different types of command line parameters.
.. moduleauthor:: Florian Aldehoff <samsifter@biohazardous.de>
"""
from os.path import basename
[docs]class FilterParameter():
"""Abstraction of a general command line argument for standalone filters.
Serves as base class for thresholds and filepath arguments.
"""
def __init__(self, text, desc, cli_name, default, value=None,
required=False, active=False):
"""Initialize new instance of FilterParameter.
Parameters
----------
text : str
Short label of parameter in GUI, should not exceed one line.
desc : str
Longer description of parameter in GUI, should explain details of
usage.
cli_name : str
Name of parameter in CLI, eg. ``--foo``
default : str
Default value, required for GUI widget presets.
value : str, optional
Parameter value set by GUI elements, default value is used if this
is (by default) not set.
required : bool, optional
Is parameter required to run program? Defaults to False.
active : bool, optional
Is parameter activated? Defaults to False.
"""
self.text = text
self.desc = desc
self.cli_name = cli_name
self.default = default
self.value = value
self.required = required
self.active = active # should be set after value
[docs] def clone(self):
"""Create new instance with identical settings.
Returns
-------
FilterParameter
Exact clone of this parameter.
"""
return FilterParameter(
self.text, self.desc, self.cli_name, self.default, self.value,
self.required, self.active
)
[docs] def __str__(self):
"""String representation of this parameter."""
return self.text
[docs] def __repr__(self):
"""Representation of this parameter for debugging."""
rep = "\n -> %s" % self.text
rep += "\n - description:\t%s" % self.desc
rep += "\n - default:\t%s" % self.default
rep += "\n - value\t:\t%s" % self.value
rep += "\n - CLI name:\t%s" % self.cli_name
rep += "\n - required:\t%s" % self.required
rep += "\n - active:\t%s" % self.active
return rep
[docs] def cli(self, basenames=False):
"""Representation of this parameter on command line interface."""
# assert basenames # only to prevent pylint warning
if self.active or self.required:
return self.cli_name
else:
return ""
[docs] def get_form_text(self):
"""Representation of this parameter in form layouts."""
return self.text + ":"
# Getters & Setters
[docs] def get_description(self):
return self.desc
[docs] def set_description(self, desc):
"""Set descriptive text of parameter.
Parameters
----------
desc : str
Longer description of parameter in GUI, should explain details of
usage.
"""
self.desc = desc
[docs] def set_value(self, value):
"""Set value, also activate parameter.
Here the value and active status are linked, derived classes override
this behaviour.
Parameters
----------
value : str
Parameter value set by GUI elements, default value is used if this
is (by default) not set.
"""
self.value = value
self.active = value
[docs] def get_value(self):
if self.value is None:
return self.default
else:
return self.value
[docs] def set_default(self, default):
"""Set the default value used when no value is specified.
Parameters
----------
default : str
Default value, required for GUI widget presets.
"""
self.default = default
if self.value is None:
self.value = default
[docs] def get_default(self):
return self.default
[docs] def get_cli_name(self):
return self.cli_name
[docs] def set_cli_name(self, cli_name):
"""Set the CLI name of the parameter, eg. ``--foo`` or ``-f``.
Parameters
----------
cli_name : str
Name of parameter in CLI, eg. ``--foo``.
"""
self.cli_name = cli_name
[docs] def is_active(self):
return self.active
[docs] def set_active(self, active=True):
"""Activate parameter to force showing it on the commandline.
Parameters
----------
active : bool, optional
Is parameter activated? Defaults to True.
"""
self.active = active
[docs] def is_required(self):
return self.required
[docs] def set_required(self, required=True):
"""Make parameter required.
Parameters
----------
required : bool, optional
Is parameter required? Defaults to True.
"""
self.required = required
[docs]class FilterThreshold(FilterParameter):
"""Abstraction of a numerical command line parameter used as treshold.
Extends filter parameter by minimum and maximum of permitted value range
with variable precision and optional unit.
"""
def __init__(self, text, desc, cli_name, default=5.00, minimum=0.00,
maximum=100.00, precision=2, unit=None, value=None,
required=False, active=False):
"""Initialize new instance of FilterThreshold.
Parameters
----------
text : str
Short label of parameter in GUI, should not exceed one line.
desc : str
Longer description of parameter in GUI, should explain details of
usage.
cli_name : str
Name of parameter in CLI, eg. ``--foo``
default : float, optional
Default value, required for GUI widget presets; defaults to 5.
minimum : float, optional
Minimum of permitted value range, defaults to 0.
maximum : float, optional
Maximum of permitted value range, defaults to 100.
precision : int, optional
Number of required decimals for values, defaults to 2
(eg. ``0.12``)
unit : str, optional
Value unit, will be used in labels within square brackets (eg.
``[kB]``)
value : float, optional
Parameter value set by GUI elements, default value is used if this
is (by default) not set.
required : bool, optional
Is parameter required to run program? Defaults to False.
active : bool, optional
Is parameter activated? Defaults to False.
"""
super(FilterThreshold, self).__init__(
text, desc, cli_name, default, value, required, active
)
self.unit = unit
self.minimum = minimum
self.maximum = maximum
self.precision = precision
[docs] def clone(self):
"""Create new instance with identical settings.
Returns
-------
FilterThreshold
Exact clone of this parameter.
"""
return FilterThreshold(
self.text, self.desc, self.cli_name, self.default, self.minimum,
self.maximum, self.precision, self.unit, self.value, self.required,
self.active
)
[docs] def get_form_text(self):
"""Representation of this parameter in form layouts.
Overrides base method and provides additional information on unit.
"""
text = self.text
if self.unit is not None:
text += " [" + self.unit + "]"
text += ":"
return text
[docs] def __repr__(self):
"""Representation of this parameter for debugging.
Extends base method with additional attributes.
"""
rep = super(FilterThreshold, self).__repr__()
rep += "\n - unit:\t\t%s" % self.unit
rep += "\n - minimum:\t%s" % self.minimum
rep += "\n - maximum:\t%s" % self.maximum
rep += "\n - precision:\t%s" % self.precision
return rep
[docs] def cli(self, basenames=False):
"""Representation of this parameter on command line interface.
Overrides base method to handle unset values.
"""
if self.active or self.required:
if self.value is None:
return "%s %s" % (self.cli_name, self.default)
else:
return "%s %s" % (self.cli_name, self.value)
else:
return ""
# Getters & Setters
[docs] def get_maximum(self):
return self.maximum
[docs] def set_maximum(self, maximum):
"""Set maximum of value range.
Parameters
----------
maximum : float
Maximum of permitted value range
"""
self.maximum = maximum
[docs] def get_minimum(self):
return self.minimum
[docs] def set_minimum(self, minimum):
"""Set minimum of value range.
Parameters
----------
minimum : float
Minimum of permitted value range
"""
self.minimum = minimum
[docs] def get_unit(self):
return self.unit
[docs] def set_unit(self, unit):
"""Set the optional unit of the threshold.
Parameters
----------
unit : str
Unit of threshold, displayed in square brackets next to parameter
text in GUI.
"""
self.unit = unit
[docs] def get_precision(self):
return self.precision
[docs] def set_precision(self, precision):
"""Set precision of threshold.
Precision corresponds to the required number of decimals.
Parameters
----------
precision : int
Number of required decimals for threshold.
"""
self.precision = precision
[docs] def set_value(self, value):
"""Set value of parameter.
Overriding base class to consider value precision.
Parameters
----------
value : float
Numerical threshold.
"""
if self.precision == 0:
self.value = int(value)
else:
self.value = value
# active parameter once value is changed
self.active = self.value is not None
[docs]class FilterFilepath(FilterParameter):
"""Parameter setting filepath for input or output file.
Extends parameter base class with a list of supported file extensions and
requirements for read and write access.
"""
def __init__(self, text, desc, cli_name, default, extensions=('csv'),
readable=True, writable=False, value=None, required=False,
active=False):
super(FilterFilepath, self).__init__(
text, desc, cli_name, default, value, required, active
)
self.extensions = extensions
self.readable = readable
self.writable = writable
[docs] def clone(self):
"""Create new instance with identical settings.
Returns
-------
FilterParameter
An exact copy of this instance.
"""
return FilterFilepath(
self.text, self.desc, self.cli_name, self.default, self.extensions,
self.readable, self.writable, self.value, self.required,
self.active
)
[docs] def __repr__(self):
"""Representation of this parameter for debugging.
Extends base method with additional attributes.
"""
rep = super(FilterFilepath, self).__repr__()
rep += "\n - extensions:\t%s" % self.extensions
rep += "\n - readable:\t%s" % self.readable
rep += "\n - writable:\t%s" % self.writable
return rep
[docs] def cli(self, basenames=False):
"""Representation of this parameter on command line interface.
Overrides base method to handle option for shortened filepaths.
Parameters
----------
basenames : bool, optional
Shorten file paths to filename only, defaults to False.
Returns
-------
str
Full command line argument for this parameter with optionally
shortened filenames.
"""
if self.active or self.required:
if self.value is None:
if basenames:
return "%s %s" % (self.cli_name, basename(self.default))
else:
return "%s %s" % (self.cli_name, self.default)
else:
if basenames:
return "%s %s" % (self.cli_name, basename(self.value))
else:
return "%s %s" % (self.cli_name, self.value)
else:
return ""
# Getters & Setters
[docs] def set_value(self, value):
"""Set parameter value.
Overrides base method to active parameter only when value has changed.
"""
self.value = value
# active parameter once value is changed
self.active = self.value is not None
[docs] def get_extensions(self):
return self.extensions
[docs] def set_extensions(self, extensions):
"""Set list of supported file extensions.
Parameters
----------
extensions : list of str
List of supported file extensions. Default extension is listed
first.
"""
self.extensions = extensions
[docs]class FilterSwitch(FilterParameter):
"""Command line switch for a list of exclusive options.
Extends base class with a list of selectable options. Defaults to a simple
binary switch between True and False.
"""
def __init__(self, text, desc, cli_name, default, options=(True, False),
value=None, required=False, active=False):
super(FilterSwitch, self).__init__(
text, desc, cli_name, default, value, required, active
)
self.options = options
[docs] def clone(self):
"""Create new instance with identical settings.
Returns
-------
FilterSwitch
An exact copy of this instance.
"""
return FilterSwitch(
self.text, self.desc, self.cli_name, self.default, self.options,
self.value, self.required, self.active
)
[docs] def __repr__(self):
"""Representation of this parameter for debugging.
Extends base method with additional attributes.
"""
rep = super(FilterSwitch, self).__repr__()
rep += "\n - options\t%s" % self.options
return rep
[docs] def cli(self, basenames=False):
"""Representation of this parameter on command line interface.
Overrides base method to handle unset values.
"""
if self.active or self.required:
if self.value is None:
return "%s %s" % (self.cli_name, self.default)
else:
return "%s %s" % (self.cli_name, self.value)
else:
return ""
# Getters & Setters
[docs] def set_value(self, value):
"""Set parameter value.
Overrides base method to active parameter only when value has changed.
Parameters
----------
value : int
Parameter value set by GUI elements, default value is used if this
is (by default) not set. Corresponds to 1-based index of options
list.
"""
self.value = value
# active parameter once value is changed
self.active = self.value is not None
[docs] def get_option(self, index):
"""Get specific option out of the available options.
Parameters
----------
index : int
Index of option in list of options.
Returns
-------
str
Desired option (or None on invalid index)
"""
try:
return self.options[index]
except IndexError:
return None
[docs] def get_options(self):
return self.options
[docs] def set_options(self, options):
"""Set options to choose from.
Parameters
----------
options : list of str
List of options to choose from. Default value is listed first.
"""
self.options = options