1# Copyright (c) 2010 Mitch Garnaat http://garnaat.org/
2# Copyright (c) 2010, Eucalyptus Systems, Inc.
3#
4# Permission is hereby granted, free of charge, to any person obtaining a
5# copy of this software and associated documentation files (the
6# "Software"), to deal in the Software without restriction, including
7# without limitation the rights to use, copy, modify, merge, publish, dis-
8# tribute, sublicense, and/or sell copies of the Software, and to permit
9# persons to whom the Software is furnished to do so, subject to the fol-
10# lowing conditions:
11#
12# The above copyright notice and this permission notice shall be included
13# in all copies or substantial portions of the Software.
14#
15# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
17# ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
18# SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
19# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21# IN THE SOFTWARE.
22
23import os
24
25class Converter(object):
26
27    @classmethod
28    def convert_string(cls, param, value):
29        # TODO: could do length validation, etc. here
30        if not isinstance(value, basestring):
31            raise ValueError
32        return value
33
34    @classmethod
35    def convert_integer(cls, param, value):
36        # TODO: could do range checking here
37        return int(value)
38
39    @classmethod
40    def convert_boolean(cls, param, value):
41        """
42        For command line arguments, just the presence
43        of the option means True so just return True
44        """
45        return True
46
47    @classmethod
48    def convert_file(cls, param, value):
49        if os.path.exists(value) and not os.path.isdir(value):
50            return value
51        raise ValueError
52
53    @classmethod
54    def convert_dir(cls, param, value):
55        if os.path.isdir(value):
56            return value
57        raise ValueError
58
59    @classmethod
60    def convert(cls, param, value):
61        try:
62            if hasattr(cls, 'convert_'+param.ptype):
63                mthd = getattr(cls, 'convert_'+param.ptype)
64            else:
65                mthd = cls.convert_string
66            return mthd(param, value)
67        except:
68            raise ValidationException(param, '')
69
70class Param(Converter):
71
72    def __init__(self, name=None, ptype='string', optional=True,
73                 short_name=None, long_name=None, doc='',
74                 metavar=None, cardinality=1, default=None,
75                 choices=None, encoder=None, request_param=True):
76        self.name = name
77        self.ptype = ptype
78        self.optional = optional
79        self.short_name = short_name
80        self.long_name = long_name
81        self.doc = doc
82        self.metavar = metavar
83        self.cardinality = cardinality
84        self.default = default
85        self.choices = choices
86        self.encoder = encoder
87        self.request_param = request_param
88
89    @property
90    def optparse_long_name(self):
91        ln = None
92        if self.long_name:
93            ln = '--%s' % self.long_name
94        return ln
95
96    @property
97    def synopsis_long_name(self):
98        ln = None
99        if self.long_name:
100            ln = '--%s' % self.long_name
101        return ln
102
103    @property
104    def getopt_long_name(self):
105        ln = None
106        if self.long_name:
107            ln = '%s' % self.long_name
108            if self.ptype != 'boolean':
109                ln += '='
110        return ln
111
112    @property
113    def optparse_short_name(self):
114        sn = None
115        if self.short_name:
116            sn = '-%s' % self.short_name
117        return sn
118
119    @property
120    def synopsis_short_name(self):
121        sn = None
122        if self.short_name:
123            sn = '-%s' % self.short_name
124        return sn
125
126    @property
127    def getopt_short_name(self):
128        sn = None
129        if self.short_name:
130            sn = '%s' % self.short_name
131            if self.ptype != 'boolean':
132                sn += ':'
133        return sn
134
135    def convert(self, value):
136        """
137        Convert a string value as received in the command line
138        tools and convert to the appropriate type of value.
139        Raise a ValidationError if the value can't be converted.
140
141        :type value: str
142        :param value: The value to convert.  This should always
143                      be a string.
144        """
145        return super(Param, self).convert(self,value)
146
147
148