parameter.py 6.56 KB
Newer Older
Jerome Mariette's avatar
Jerome Mariette committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#
# Copyright (C) 2012 INRA
# 
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#

import types
Jerome Mariette's avatar
Jerome Mariette committed
19
import datetime
Jerome Mariette's avatar
Jerome Mariette committed
20
import argparse
21
22
from argparse import _ensure_value
import copy as _copy
Jerome Mariette's avatar
Jerome Mariette committed
23
24
# import custom types
from workflows.types import *
Jerome Mariette's avatar
Jerome Mariette committed
25
26


Jerome Mariette's avatar
Jerome Mariette committed
27
class MiltipleParameters(object):
28
    def __init__(self, types, required):
Jerome Mariette's avatar
Jerome Mariette committed
29
        self.types = types
Jerome Mariette's avatar
Jerome Mariette committed
30
        self.index = None
31
        self.required = required
Jerome Mariette's avatar
Jerome Mariette committed
32
        self.__name__ = "MiltipleParameters"
Jerome Mariette's avatar
Jerome Mariette committed
33
    def __call__(self, arg):
Jerome Mariette's avatar
Jerome Mariette committed
34
35
36
37
38
39
40
41
        parts = arg.split("=")
        if not self.types.has_key(parts[0]):
            raise argparse.ArgumentTypeError(parts[0] + " is an invalid flag! Available ones are: "+", ".join(self.types.keys()))
        try:
            value = self.types[parts[0]](parts[1])
        except:
            raise argparse.ArgumentTypeError("invalid " + self.types[parts[0]].__name__ + " value: '" + parts[1] + "' for sub parameter '" + parts[0] + "'")
        self.index = parts[0]
42
        return (parts[0], value, self.required)
Jerome Mariette's avatar
Jerome Mariette committed
43

44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
class MiltipleAction(argparse.Action):
    def __call__(self, parser, namespace, values, option_string=None):
        try:
            required = _copy.copy(values[0][2])
            for val in values:
                if val[0] in required:
                    del required[required.index(val[0])]
        except: pass
        if len(required) == 1: parser.error(", ".join(required) + " is a required parameter!")
        elif len(required) > 1: parser.error(", ".join(required) + " are required parameters!")
        setattr(namespace, self.dest, values)

class MiltipleAppendAction(argparse.Action):
    def __call__(self, parser, namespace, values, option_string=None):
        try:
            required = _copy.copy(values[0][2])
            for val in values:
                if val[0] in required:
                    del required[required.index(val[0])]
        except: pass
        if len(required) == 1: parser.error(", ".join(required) + " is a required parameter!")
        elif len(required) > 1: parser.error(", ".join(required) + " are required parameters!")
        items = _copy.copy(_ensure_value(namespace, self.dest, []))
        items.append(values)
        setattr(namespace, self.dest, items)        
        
Jerome Mariette's avatar
Jerome Mariette committed
70
71
72
73
class Parameter(object):
    """
    """
    
Jerome Mariette's avatar
Jerome Mariette committed
74
    def __init__(self, name, help, flag, default=None, type=types.StringType, choices=None, 
Jerome Mariette's avatar
Jerome Mariette committed
75
                 required=False, action="store", sub_parameters=[], group="default", display_name=None):
Jerome Mariette's avatar
Jerome Mariette committed
76

Jerome Mariette's avatar
Jerome Mariette committed
77
78
79
        self.name = name
        self.flag = flag
        self.help = help
80
        self.action = action
Jerome Mariette's avatar
Jerome Mariette committed
81
        self.nargs = None
Jerome Mariette's avatar
Jerome Mariette committed
82
        self.sub_parameters = sub_parameters
Jerome Mariette's avatar
Jerome Mariette committed
83
        self.group = group
Jerome Mariette's avatar
Jerome Mariette committed
84
85
86
        if display_name == None:
            self.display_name = name
        else: self.display_name = display_name
Jerome Mariette's avatar
Jerome Mariette committed
87
        
Jerome Mariette's avatar
Jerome Mariette committed
88
        if len(self.sub_parameters) > 0:
Jerome Mariette's avatar
Jerome Mariette committed
89
            self.nargs = "+"
Jerome Mariette's avatar
Jerome Mariette committed
90
91
        if type == "date":
            self.type = date
Jerome Mariette's avatar
Jerome Mariette committed
92
        elif type == "multiple":
93
            sub_param_hash, sub_param_types, sub_param_names, sub_param_required = {}, [], [], []
Jerome Mariette's avatar
Jerome Mariette committed
94
            for sub_param in self.sub_parameters:
Jerome Mariette's avatar
Jerome Mariette committed
95
96
97
98
99
                try: sub_type = sub_param.type
                except: sub_type = types.StringType
                sub_param_hash[sub_param.flag] = sub_type
                sub_param_names.append(sub_param.flag)
                sub_param_types.append(sub_type)
100
101
102
103
104
105
                if sub_param.required: sub_param_required.append(sub_param.flag)
            self.type = MiltipleParameters(sub_param_hash, sub_param_required)
            if self.action == "append":
                self.action = MiltipleAppendAction
            else:
                self.action = MiltipleAction
Jerome Mariette's avatar
Jerome Mariette committed
106
            self.help += " | Format: " + " ".join([cname + "=<" + ctype.__name__.upper() + ">" for ctype, cname in zip(sub_param_types, sub_param_names)]) + ")"
Jerome Mariette's avatar
Jerome Mariette committed
107
108
        elif isinstance(type, types.FunctionType):
            self.type = type
Jerome Mariette's avatar
Jerome Mariette committed
109
110
111
        else:
            try: self.type = eval(type)
            except: self.type = types.StringType
Jerome Mariette's avatar
Jerome Mariette committed
112
            
Jerome Mariette's avatar
Jerome Mariette committed
113
        self.required = str(required).lower() in ("yes", "y", "true",  "t", "1")
Jerome Mariette's avatar
Jerome Mariette committed
114
        self.choices = choices
Jerome Mariette's avatar
Jerome Mariette committed
115
116
        if self.choices:
            self.choices = choices.split("|")
Jerome Mariette's avatar
Jerome Mariette committed
117
                        
Jerome Mariette's avatar
Jerome Mariette committed
118
119
120
121
        self.default = default
        if type == "date" and not self.default:
            today = datetime.date.today()
            self.default = today.strftime('%d/%m/%Y')
122
        elif self.type == types.BooleanType :
Jerome Mariette's avatar
Jerome Mariette committed
123
124
            if self.default: self.default = str(self.default).lower() in ("true",  "t", "1")
            else: self.default = True
125
        elif self.action == "append" or self.action == MiltipleAppendAction:
Jerome Mariette's avatar
Jerome Mariette committed
126
            self.default = []
Jerome Mariette's avatar
Jerome Mariette committed
127
128
129
130
131
        elif type == "multiple":
            self.default = {}
            for param in self.sub_parameters:
                self.default[param.name] = param.default
                
132
    def export_to_argparse(self):
133
134
135
136
        if self.type == types.BooleanType and str(self.default).lower() in ("false",  "f", "0"):
            return {"help": self.help, "required": self.required, "dest": self.name, 
                    "default": False, "action": "store_true"}
        elif self.type == types.BooleanType:
137
            return {"help": self.help, "required": self.required, "dest": self.name, 
138
                    "default": True, "action": "store_false"}
Jerome Mariette's avatar
Jerome Mariette committed
139
140
141
        elif self.nargs > 1:
            return {"type": self.type, "help": self.help, "required": self.required,
                    "dest": self.name, "default": self.default,
Jerome Mariette's avatar
Jerome Mariette committed
142
                    "action": self.action, "choices": self.choices, "nargs": "+"}
143
144
        else:
            return {"type": self.type, "help": self.help, "required": self.required,
Jerome Mariette's avatar
Jerome Mariette committed
145
                    "dest": self.name, "default": self.default,
146
147
                    "action": self.action, "choices": self.choices}
    
Jerome Mariette's avatar
Jerome Mariette committed
148
149
150
    def get_type(self):
        return self.type.__name__
    
Jerome Mariette's avatar
Jerome Mariette committed
151
    def __str__(self):
Jerome Mariette's avatar
Jerome Mariette committed
152
        return self.name + ": " + str(self.flag) + " | " + self.help + " (default=" + \
Jerome Mariette's avatar
Jerome Mariette committed
153
               str(self.default) + ", required=" + str(self.required) + ", flag=" + self.flag + ")"