Statistics
| Branch: | Tag: | Revision:

root / kamaki / cli / commands / __init__.py @ 38a79780

History | View | Annotate | Download (12.4 kB)

1 e3f01d64 Stavros Sachtouris
# Copyright 2011-2013 GRNET S.A. All rights reserved.
2 5eae854d Stavros Sachtouris
#
3 5eae854d Stavros Sachtouris
# Redistribution and use in source and binary forms, with or
4 5eae854d Stavros Sachtouris
# without modification, are permitted provided that the following
5 5eae854d Stavros Sachtouris
# conditions are met:
6 5eae854d Stavros Sachtouris
#
7 5eae854d Stavros Sachtouris
#   1. Redistributions of source code must retain the above
8 5eae854d Stavros Sachtouris
#      copyright notice, this list of conditions and the following
9 5eae854d Stavros Sachtouris
#      disclaimer.
10 5eae854d Stavros Sachtouris
#
11 5eae854d Stavros Sachtouris
#   2. Redistributions in binary form must reproduce the above
12 5eae854d Stavros Sachtouris
#      copyright notice, this list of conditions and the following
13 5eae854d Stavros Sachtouris
#      disclaimer in the documentation and/or other materials
14 5eae854d Stavros Sachtouris
#      provided with the distribution.
15 5eae854d Stavros Sachtouris
#
16 5eae854d Stavros Sachtouris
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 5eae854d Stavros Sachtouris
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 5eae854d Stavros Sachtouris
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 5eae854d Stavros Sachtouris
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 5eae854d Stavros Sachtouris
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 5eae854d Stavros Sachtouris
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 5eae854d Stavros Sachtouris
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 5eae854d Stavros Sachtouris
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 5eae854d Stavros Sachtouris
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 5eae854d Stavros Sachtouris
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 5eae854d Stavros Sachtouris
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 5eae854d Stavros Sachtouris
# POSSIBILITY OF SUCH DAMAGE.
28 5eae854d Stavros Sachtouris
#
29 5eae854d Stavros Sachtouris
# The views and conclusions contained in the software and
30 5eae854d Stavros Sachtouris
# documentation are those of the authors and should not be
31 5eae854d Stavros Sachtouris
# interpreted as representing official policies, either expressed
32 5eae854d Stavros Sachtouris
# or implied, of GRNET S.A.command
33 5eae854d Stavros Sachtouris
34 137c51f5 Stavros Sachtouris
from kamaki.cli.logger import get_logger
35 ddcb2e09 Stavros Sachtouris
from kamaki.cli.utils import (
36 ddcb2e09 Stavros Sachtouris
    print_list, print_dict, print_json, print_items, ask_user,
37 ddcb2e09 Stavros Sachtouris
    filter_dicts_by_dict)
38 6d190dd1 Stavros Sachtouris
from kamaki.cli.argument import FlagArgument, ValueArgument
39 f76c6bbc Stavros Sachtouris
from kamaki.cli.errors import CLIInvalidArgument
40 ff1c0296 Stavros Sachtouris
from sys import stdin, stdout, stderr
41 6069b53b Stavros Sachtouris
42 0d4a6d0a Stavros Sachtouris
log = get_logger(__name__)
43 6069b53b Stavros Sachtouris
44 234954d1 Stavros Sachtouris
45 392d902d Stavros Sachtouris
def DontRaiseKeyError(func):
46 b4f69041 Stavros Sachtouris
    def wrap(*args, **kwargs):
47 b4f69041 Stavros Sachtouris
        try:
48 392d902d Stavros Sachtouris
            return func(*args, **kwargs)
49 b4f69041 Stavros Sachtouris
        except KeyError:
50 b4f69041 Stavros Sachtouris
            return None
51 b4f69041 Stavros Sachtouris
    return wrap
52 b4f69041 Stavros Sachtouris
53 b4f69041 Stavros Sachtouris
54 392d902d Stavros Sachtouris
def addLogSettings(func):
55 b4f69041 Stavros Sachtouris
    def wrap(self, *args, **kwargs):
56 b4f69041 Stavros Sachtouris
        try:
57 392d902d Stavros Sachtouris
            return func(self, *args, **kwargs)
58 b4f69041 Stavros Sachtouris
        finally:
59 b4f69041 Stavros Sachtouris
            self._set_log_params()
60 b4f69041 Stavros Sachtouris
    return wrap
61 b4f69041 Stavros Sachtouris
62 b4f69041 Stavros Sachtouris
63 5eae854d Stavros Sachtouris
class _command_init(object):
64 36526b3c Stavros Sachtouris
65 56d84a4e Stavros Sachtouris
    # self.arguments (dict) contains all non-positional arguments
66 56d84a4e Stavros Sachtouris
    # self.required (list or tuple) contains required argument keys
67 56d84a4e Stavros Sachtouris
    #     if it is a list, at least one of these arguments is required
68 56d84a4e Stavros Sachtouris
    #     if it is a tuple, all arguments are required
69 56d84a4e Stavros Sachtouris
    #     Lists and tuples can nest other lists and/or tuples
70 56d84a4e Stavros Sachtouris
71 1757c616 Stavros Sachtouris
    def __init__(
72 1757c616 Stavros Sachtouris
            self,
73 ff1c0296 Stavros Sachtouris
            arguments={}, auth_base=None, cloud=None,
74 ff1c0296 Stavros Sachtouris
            _in=None, _out=None, _err=None):
75 ff1c0296 Stavros Sachtouris
        self._in, self._out, self._err = (
76 ff1c0296 Stavros Sachtouris
            _in or stdin, _out or stdout, _err or stderr)
77 20206179 Stavros Sachtouris
        self.required = getattr(self, 'required', None)
78 e15d78e2 Stavros Sachtouris
        if hasattr(self, 'arguments'):
79 e15d78e2 Stavros Sachtouris
            arguments.update(self.arguments)
80 915b99b5 Stavros Sachtouris
        if isinstance(self, _optional_output_cmd):
81 915b99b5 Stavros Sachtouris
            arguments.update(self.oo_arguments)
82 545c6c29 Stavros Sachtouris
        if isinstance(self, _optional_json):
83 545c6c29 Stavros Sachtouris
            arguments.update(self.oj_arguments)
84 6d190dd1 Stavros Sachtouris
        if isinstance(self, _name_filter):
85 6d190dd1 Stavros Sachtouris
            arguments.update(self.nf_arguments)
86 6d190dd1 Stavros Sachtouris
        if isinstance(self, _id_filter):
87 6d190dd1 Stavros Sachtouris
            arguments.update(self.if_arguments)
88 60c42f9f Stavros Sachtouris
        try:
89 60c42f9f Stavros Sachtouris
            arguments.update(self.wait_arguments)
90 60c42f9f Stavros Sachtouris
        except AttributeError:
91 60c42f9f Stavros Sachtouris
            pass
92 e15d78e2 Stavros Sachtouris
        self.arguments = dict(arguments)
93 5eae854d Stavros Sachtouris
        try:
94 e15d78e2 Stavros Sachtouris
            self.config = self['config']
95 5eae854d Stavros Sachtouris
        except KeyError:
96 5eae854d Stavros Sachtouris
            pass
97 844a6bdb Stavros Sachtouris
        self.auth_base = auth_base or getattr(self, 'auth_base', None)
98 844a6bdb Stavros Sachtouris
        self.cloud = cloud or getattr(self, 'cloud', None)
99 5eae854d Stavros Sachtouris
100 ff1c0296 Stavros Sachtouris
    def write(self, s):
101 a5b748c2 Stavros Sachtouris
        self._out.write('%s' % s)
102 ff1c0296 Stavros Sachtouris
        self._out.flush()
103 ff1c0296 Stavros Sachtouris
104 ff1c0296 Stavros Sachtouris
    def writeln(self, s=''):
105 a5b748c2 Stavros Sachtouris
        self.write('%s\n' % s)
106 ff1c0296 Stavros Sachtouris
107 ff1c0296 Stavros Sachtouris
    def error(self, s=''):
108 a5b748c2 Stavros Sachtouris
        self._err.write('%s\n' % s)
109 ff1c0296 Stavros Sachtouris
        self._err.flush()
110 ff1c0296 Stavros Sachtouris
111 ddcb2e09 Stavros Sachtouris
    def print_list(self, *args, **kwargs):
112 ddcb2e09 Stavros Sachtouris
        kwargs.setdefault('out', self._out)
113 76f58e2e Stavros Sachtouris
        return print_list(*args, **kwargs)
114 ddcb2e09 Stavros Sachtouris
115 ddcb2e09 Stavros Sachtouris
    def print_dict(self, *args, **kwargs):
116 ddcb2e09 Stavros Sachtouris
        kwargs.setdefault('out', self._out)
117 76f58e2e Stavros Sachtouris
        return print_dict(*args, **kwargs)
118 ddcb2e09 Stavros Sachtouris
119 ddcb2e09 Stavros Sachtouris
    def print_json(self, *args, **kwargs):
120 ddcb2e09 Stavros Sachtouris
        kwargs.setdefault('out', self._out)
121 76f58e2e Stavros Sachtouris
        return print_json(*args, **kwargs)
122 ddcb2e09 Stavros Sachtouris
123 ddcb2e09 Stavros Sachtouris
    def print_items(self, *args, **kwargs):
124 ddcb2e09 Stavros Sachtouris
        kwargs.setdefault('out', self._out)
125 76f58e2e Stavros Sachtouris
        return print_items(*args, **kwargs)
126 ddcb2e09 Stavros Sachtouris
127 ddcb2e09 Stavros Sachtouris
    def ask_user(self, *args, **kwargs):
128 ddcb2e09 Stavros Sachtouris
        kwargs.setdefault('user_in', self._in)
129 ddcb2e09 Stavros Sachtouris
        kwargs.setdefault('out', self._out)
130 76f58e2e Stavros Sachtouris
        return ask_user(*args, **kwargs)
131 ddcb2e09 Stavros Sachtouris
132 b4f69041 Stavros Sachtouris
    @DontRaiseKeyError
133 b4f69041 Stavros Sachtouris
    def _custom_url(self, service):
134 144b3551 Stavros Sachtouris
        return self.config.get_cloud(self.cloud, '%s_url' % service)
135 b4f69041 Stavros Sachtouris
136 b4f69041 Stavros Sachtouris
    @DontRaiseKeyError
137 b4f69041 Stavros Sachtouris
    def _custom_token(self, service):
138 144b3551 Stavros Sachtouris
        return self.config.get_cloud(self.cloud, '%s_token' % service)
139 b4f69041 Stavros Sachtouris
140 b4f69041 Stavros Sachtouris
    @DontRaiseKeyError
141 b4f69041 Stavros Sachtouris
    def _custom_type(self, service):
142 144b3551 Stavros Sachtouris
        return self.config.get_cloud(self.cloud, '%s_type' % service)
143 b4f69041 Stavros Sachtouris
144 b4f69041 Stavros Sachtouris
    @DontRaiseKeyError
145 b4f69041 Stavros Sachtouris
    def _custom_version(self, service):
146 144b3551 Stavros Sachtouris
        return self.config.get_cloud(self.cloud, '%s_version' % service)
147 b4f69041 Stavros Sachtouris
148 f1e5b343 Stavros Sachtouris
    def _uuids2usernames(self, uuids):
149 db93db3e Stavros Sachtouris
        return self.auth_base.post_user_catalogs(uuids)
150 f1e5b343 Stavros Sachtouris
151 f1e5b343 Stavros Sachtouris
    def _usernames2uuids(self, username):
152 db93db3e Stavros Sachtouris
        return self.auth_base.post_user_catalogs(displaynames=username)
153 f1e5b343 Stavros Sachtouris
154 95641ecc Stavros Sachtouris
    def _uuid2username(self, uuid):
155 f1e5b343 Stavros Sachtouris
        return self._uuids2usernames([uuid]).get(uuid, None)
156 95641ecc Stavros Sachtouris
157 95641ecc Stavros Sachtouris
    def _username2uuid(self, username):
158 f1e5b343 Stavros Sachtouris
        return self._usernames2uuids([username]).get(username, None)
159 95641ecc Stavros Sachtouris
160 f47417e7 Stavros Sachtouris
    def _set_log_params(self):
161 b3bb083f Stavros Sachtouris
        try:
162 64a3c0de Stavros Sachtouris
            self.client.LOG_TOKEN = (
163 534e7bbb Stavros Sachtouris
                self['config'].get('global', 'log_token').lower() == 'on')
164 64a3c0de Stavros Sachtouris
        except Exception as e:
165 64a3c0de Stavros Sachtouris
            log.debug('Failed to read custom log_token setting:'
166 64a3c0de Stavros Sachtouris
                '%s\n default for log_token is off' % e)
167 64a3c0de Stavros Sachtouris
        try:
168 64a3c0de Stavros Sachtouris
            self.client.LOG_DATA = (
169 534e7bbb Stavros Sachtouris
                self['config'].get('global', 'log_data').lower() == 'on')
170 c5b9380c Stavros Sachtouris
        except Exception as e:
171 64a3c0de Stavros Sachtouris
            log.debug('Failed to read custom log_data setting:'
172 64a3c0de Stavros Sachtouris
                '%s\n default for log_data is off' % e)
173 64a3c0de Stavros Sachtouris
        try:
174 64a3c0de Stavros Sachtouris
            self.client.LOG_PID = (
175 534e7bbb Stavros Sachtouris
                self['config'].get('global', 'log_pid').lower() == 'on')
176 64a3c0de Stavros Sachtouris
        except Exception as e:
177 64a3c0de Stavros Sachtouris
            log.debug('Failed to read custom log_pid setting:'
178 64a3c0de Stavros Sachtouris
                '%s\n default for log_pid is off' % e)
179 c5b9380c Stavros Sachtouris
180 8547cd19 Stavros Sachtouris
    def _safe_progress_bar(
181 8547cd19 Stavros Sachtouris
            self, msg, arg='progress_bar', countdown=False, timeout=100):
182 5a673575 Stavros Sachtouris
        """Try to get a progress bar, but do not raise errors"""
183 5a673575 Stavros Sachtouris
        try:
184 5a673575 Stavros Sachtouris
            progress_bar = self.arguments[arg]
185 ff1c0296 Stavros Sachtouris
            progress_bar.file = self._err
186 8547cd19 Stavros Sachtouris
            gen = progress_bar.get_generator(
187 8547cd19 Stavros Sachtouris
                msg, countdown=countdown, timeout=timeout)
188 5a673575 Stavros Sachtouris
        except Exception:
189 5a673575 Stavros Sachtouris
            return (None, None)
190 5a673575 Stavros Sachtouris
        return (progress_bar, gen)
191 5a673575 Stavros Sachtouris
192 5a673575 Stavros Sachtouris
    def _safe_progress_bar_finish(self, progress_bar):
193 5a673575 Stavros Sachtouris
        try:
194 5a673575 Stavros Sachtouris
            progress_bar.finish()
195 5a673575 Stavros Sachtouris
        except Exception:
196 5a673575 Stavros Sachtouris
            pass
197 5a673575 Stavros Sachtouris
198 5a37a189 Stavros Sachtouris
    def __getitem__(self, argterm):
199 5a37a189 Stavros Sachtouris
        """
200 5a37a189 Stavros Sachtouris
        :param argterm: (str) the name/label of an argument in self.arguments
201 5a37a189 Stavros Sachtouris

202 b113e74b Stavros Sachtouris
        :returns: the value of the corresponding Argument (not the argument
203 b113e74b Stavros Sachtouris
            object)
204 5a37a189 Stavros Sachtouris

205 5a37a189 Stavros Sachtouris
        :raises KeyError: if argterm not in self.arguments of this object
206 5a37a189 Stavros Sachtouris
        """
207 b113e74b Stavros Sachtouris
        return self.arguments[argterm].value
208 5a37a189 Stavros Sachtouris
209 5a37a189 Stavros Sachtouris
    def __setitem__(self, argterm, arg):
210 5a37a189 Stavros Sachtouris
        """Install an argument as argterm
211 5a37a189 Stavros Sachtouris
        If argterm points to another argument, the other argument is lost
212 5a37a189 Stavros Sachtouris

213 5a37a189 Stavros Sachtouris
        :param argterm: (str)
214 5a37a189 Stavros Sachtouris

215 5a37a189 Stavros Sachtouris
        :param arg: (Argument)
216 5a37a189 Stavros Sachtouris
        """
217 5a37a189 Stavros Sachtouris
        if not hasattr(self, 'arguments'):
218 5a37a189 Stavros Sachtouris
            self.arguments = {}
219 5a37a189 Stavros Sachtouris
        self.arguments[argterm] = arg
220 5a37a189 Stavros Sachtouris
221 b113e74b Stavros Sachtouris
    def get_argument_object(self, argterm):
222 b113e74b Stavros Sachtouris
        """
223 b113e74b Stavros Sachtouris
        :param argterm: (str) the name/label of an argument in self.arguments
224 b113e74b Stavros Sachtouris

225 b113e74b Stavros Sachtouris
        :returns: the arument object
226 b113e74b Stavros Sachtouris

227 b113e74b Stavros Sachtouris
        :raises KeyError: if argterm not in self.arguments of this object
228 b113e74b Stavros Sachtouris
        """
229 b113e74b Stavros Sachtouris
        return self.arguments[argterm]
230 b113e74b Stavros Sachtouris
231 5eae854d Stavros Sachtouris
    def get_argument(self, argterm):
232 5a37a189 Stavros Sachtouris
        """
233 5a37a189 Stavros Sachtouris
        :param argterm: (str) the name/label of an argument in self.arguments
234 5a37a189 Stavros Sachtouris

235 5a37a189 Stavros Sachtouris
        :returns: the value of the arument object
236 5a37a189 Stavros Sachtouris

237 5a37a189 Stavros Sachtouris
        :raises KeyError: if argterm not in self.arguments of this object
238 5a37a189 Stavros Sachtouris
        """
239 e15d78e2 Stavros Sachtouris
        return self[argterm]
240 915b99b5 Stavros Sachtouris
241 915b99b5 Stavros Sachtouris
242 545c6c29 Stavros Sachtouris
#  feature classes - inherit them to get special features for your commands
243 545c6c29 Stavros Sachtouris
244 545c6c29 Stavros Sachtouris
245 f76c6bbc Stavros Sachtouris
class OutputFormatArgument(ValueArgument):
246 f76c6bbc Stavros Sachtouris
    """Accepted output formats: json (default)"""
247 f76c6bbc Stavros Sachtouris
248 f76c6bbc Stavros Sachtouris
    formats = ('json', )
249 f76c6bbc Stavros Sachtouris
250 f76c6bbc Stavros Sachtouris
    def ___init__(self, *args, **kwargs):
251 f76c6bbc Stavros Sachtouris
        super(OutputFormatArgument, self).___init__(*args, **kwargs)
252 f76c6bbc Stavros Sachtouris
253 f76c6bbc Stavros Sachtouris
    @property
254 f76c6bbc Stavros Sachtouris
    def value(self):
255 9b3c8fd9 Stavros Sachtouris
        return getattr(self, '_value', None)
256 f76c6bbc Stavros Sachtouris
257 f76c6bbc Stavros Sachtouris
    @value.setter
258 f76c6bbc Stavros Sachtouris
    def value(self, newvalue):
259 f76c6bbc Stavros Sachtouris
        if not newvalue:
260 f76c6bbc Stavros Sachtouris
            self._value = self.default
261 f76c6bbc Stavros Sachtouris
        elif newvalue.lower() in self.formats:
262 f76c6bbc Stavros Sachtouris
            self._value = newvalue.lower
263 f76c6bbc Stavros Sachtouris
        else:
264 f76c6bbc Stavros Sachtouris
            raise CLIInvalidArgument(
265 f76c6bbc Stavros Sachtouris
                'Invalid value %s for argument %s' % (
266 eb647cfe Stavros Sachtouris
                    newvalue, self.lvalue),
267 f76c6bbc Stavros Sachtouris
                details=['Valid output formats: %s' % ', '.join(self.formats)])
268 f76c6bbc Stavros Sachtouris
269 f76c6bbc Stavros Sachtouris
270 915b99b5 Stavros Sachtouris
class _optional_output_cmd(object):
271 915b99b5 Stavros Sachtouris
272 915b99b5 Stavros Sachtouris
    oo_arguments = dict(
273 915b99b5 Stavros Sachtouris
        with_output=FlagArgument('show response headers', ('--with-output')),
274 f76c6bbc Stavros Sachtouris
        json_output=FlagArgument(
275 f76c6bbc Stavros Sachtouris
            'show headers in json (DEPRECATED from v0.12,'
276 de329b4c Stavros Sachtouris
            '  please use --output-format=json instead)', ('-j', '--json'))
277 915b99b5 Stavros Sachtouris
    )
278 915b99b5 Stavros Sachtouris
279 915b99b5 Stavros Sachtouris
    def _optional_output(self, r):
280 915b99b5 Stavros Sachtouris
        if self['json_output']:
281 1757c616 Stavros Sachtouris
            print_json(r, out=self._out)
282 915b99b5 Stavros Sachtouris
        elif self['with_output']:
283 1757c616 Stavros Sachtouris
            print_items([r] if isinstance(r, dict) else r, out=self._out)
284 545c6c29 Stavros Sachtouris
285 545c6c29 Stavros Sachtouris
286 545c6c29 Stavros Sachtouris
class _optional_json(object):
287 545c6c29 Stavros Sachtouris
288 545c6c29 Stavros Sachtouris
    oj_arguments = dict(
289 f76c6bbc Stavros Sachtouris
        output_format=OutputFormatArgument(
290 f76c6bbc Stavros Sachtouris
            'Show output in chosen output format (%s)' % ', '.join(
291 f76c6bbc Stavros Sachtouris
                OutputFormatArgument.formats),
292 f76c6bbc Stavros Sachtouris
            '--output-format'),
293 f76c6bbc Stavros Sachtouris
        json_output=FlagArgument(
294 f76c6bbc Stavros Sachtouris
            'show output in json (DEPRECATED from v0.12,'
295 f76c6bbc Stavros Sachtouris
            ' please use --output-format instead)', ('-j', '--json'))
296 545c6c29 Stavros Sachtouris
    )
297 545c6c29 Stavros Sachtouris
298 1757c616 Stavros Sachtouris
    def _print(self, output, print_method=print_items, **print_method_kwargs):
299 f76c6bbc Stavros Sachtouris
        if self['json_output'] or self['output_format']:
300 1757c616 Stavros Sachtouris
            print_json(output, out=self._out)
301 545c6c29 Stavros Sachtouris
        else:
302 eddaace7 Stavros Sachtouris
            print_method_kwargs.setdefault('out', self._out)
303 eddaace7 Stavros Sachtouris
            print_method(output, **print_method_kwargs)
304 6d190dd1 Stavros Sachtouris
305 6d190dd1 Stavros Sachtouris
306 6d190dd1 Stavros Sachtouris
class _name_filter(object):
307 6d190dd1 Stavros Sachtouris
308 6d190dd1 Stavros Sachtouris
    nf_arguments = dict(
309 6d190dd1 Stavros Sachtouris
        name=ValueArgument('filter by name', '--name'),
310 6d190dd1 Stavros Sachtouris
        name_pref=ValueArgument(
311 6d190dd1 Stavros Sachtouris
            'filter by name prefix (case insensitive)', '--name-prefix'),
312 6d190dd1 Stavros Sachtouris
        name_suff=ValueArgument(
313 6d190dd1 Stavros Sachtouris
            'filter by name suffix (case insensitive)', '--name-suffix'),
314 6d190dd1 Stavros Sachtouris
        name_like=ValueArgument(
315 6d190dd1 Stavros Sachtouris
            'print only if name contains this (case insensitive)',
316 6d190dd1 Stavros Sachtouris
            '--name-like')
317 6d190dd1 Stavros Sachtouris
    )
318 6d190dd1 Stavros Sachtouris
319 6d190dd1 Stavros Sachtouris
    def _non_exact_name_filter(self, items):
320 6d190dd1 Stavros Sachtouris
        np, ns, nl = self['name_pref'], self['name_suff'], self['name_like']
321 6d190dd1 Stavros Sachtouris
        return [item for item in items if (
322 f3740b99 Stavros Sachtouris
            (not np) or (item['name'] or '').lower().startswith(
323 f3740b99 Stavros Sachtouris
                np.lower())) and (
324 f3740b99 Stavros Sachtouris
            (not ns) or (item['name'] or '').lower().endswith(
325 f3740b99 Stavros Sachtouris
                ns.lower())) and (
326 f3740b99 Stavros Sachtouris
            (not nl) or nl.lower() in (item['name'] or '').lower())]
327 6d190dd1 Stavros Sachtouris
328 6d190dd1 Stavros Sachtouris
    def _exact_name_filter(self, items):
329 f3740b99 Stavros Sachtouris
        return filter_dicts_by_dict(items, dict(name=self['name'] or '')) if (
330 6d190dd1 Stavros Sachtouris
            self['name']) else items
331 6d190dd1 Stavros Sachtouris
332 6d190dd1 Stavros Sachtouris
    def _filter_by_name(self, items):
333 6d190dd1 Stavros Sachtouris
        return self._non_exact_name_filter(self._exact_name_filter(items))
334 6d190dd1 Stavros Sachtouris
335 6d190dd1 Stavros Sachtouris
336 6d190dd1 Stavros Sachtouris
class _id_filter(object):
337 6d190dd1 Stavros Sachtouris
338 6d190dd1 Stavros Sachtouris
    if_arguments = dict(
339 6d190dd1 Stavros Sachtouris
        id=ValueArgument('filter by id', '--id'),
340 6d190dd1 Stavros Sachtouris
        id_pref=ValueArgument(
341 6d190dd1 Stavros Sachtouris
            'filter by id prefix (case insensitive)', '--id-prefix'),
342 6d190dd1 Stavros Sachtouris
        id_suff=ValueArgument(
343 6d190dd1 Stavros Sachtouris
            'filter by id suffix (case insensitive)', '--id-suffix'),
344 6d190dd1 Stavros Sachtouris
        id_like=ValueArgument(
345 aef3fa1f Stavros Sachtouris
            'print only if id contains this (case insensitive)', '--id-like')
346 6d190dd1 Stavros Sachtouris
    )
347 6d190dd1 Stavros Sachtouris
348 6d190dd1 Stavros Sachtouris
    def _non_exact_id_filter(self, items):
349 6d190dd1 Stavros Sachtouris
        np, ns, nl = self['id_pref'], self['id_suff'], self['id_like']
350 6d190dd1 Stavros Sachtouris
        return [item for item in items if (
351 6d190dd1 Stavros Sachtouris
            (not np) or (
352 6d190dd1 Stavros Sachtouris
                '%s' % item['id']).lower().startswith(np.lower())) and (
353 6d190dd1 Stavros Sachtouris
            (not ns) or ('%s' % item['id']).lower().endswith(ns.lower())) and (
354 6d190dd1 Stavros Sachtouris
            (not nl) or nl.lower() in ('%s' % item['id']).lower())]
355 6d190dd1 Stavros Sachtouris
356 6d190dd1 Stavros Sachtouris
    def _exact_id_filter(self, items):
357 6d190dd1 Stavros Sachtouris
        return filter_dicts_by_dict(items, dict(id=self['id'])) if (
358 6d190dd1 Stavros Sachtouris
            self['id']) else items
359 6d190dd1 Stavros Sachtouris
360 6d190dd1 Stavros Sachtouris
    def _filter_by_id(self, items):
361 6d190dd1 Stavros Sachtouris
        return self._non_exact_id_filter(self._exact_id_filter(items))