Statistics
| Branch: | Tag: | Revision:

root / kamaki / cli / commands / __init__.py @ c2332605

History | View | Annotate | Download (13.6 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 fd9457bd Stavros Sachtouris
import codecs
42 c2332605 Stavros Sachtouris
import locale
43 fd9457bd Stavros Sachtouris
44 6069b53b Stavros Sachtouris
45 0d4a6d0a Stavros Sachtouris
log = get_logger(__name__)
46 c2332605 Stavros Sachtouris
pref_enc = locale.getpreferredencoding()
47 c2332605 Stavros Sachtouris
48 c2332605 Stavros Sachtouris
49 c2332605 Stavros Sachtouris
def _encode_nicely(somestr, encoding=pref_enc, replacement='?'):
50 c2332605 Stavros Sachtouris
    """Encode somestr as 'encoding', but don't raise errors (replace with ?)
51 c2332605 Stavros Sachtouris
        :param encoding: (str) encode every character in this encoding
52 c2332605 Stavros Sachtouris
        :param replacement: (char) replace each char raising encode-decode errs
53 c2332605 Stavros Sachtouris
    """
54 c2332605 Stavros Sachtouris
    newstr = ''
55 c2332605 Stavros Sachtouris
    for c in somestr:
56 c2332605 Stavros Sachtouris
        try:
57 c2332605 Stavros Sachtouris
            newc = c.encode(encoding)
58 c2332605 Stavros Sachtouris
            newstr = '%s%s' % (newstr, newc)
59 c2332605 Stavros Sachtouris
        except (UnicodeDecodeError, UnicodeEncodeError) as e:
60 c2332605 Stavros Sachtouris
            log.debug('Encoding(%s): %s' % (encoding, e))
61 c2332605 Stavros Sachtouris
            newstr = '%s%s' % (newstr, replacement)
62 c2332605 Stavros Sachtouris
    return newstr
63 6069b53b Stavros Sachtouris
64 234954d1 Stavros Sachtouris
65 392d902d Stavros Sachtouris
def DontRaiseKeyError(func):
66 b4f69041 Stavros Sachtouris
    def wrap(*args, **kwargs):
67 b4f69041 Stavros Sachtouris
        try:
68 392d902d Stavros Sachtouris
            return func(*args, **kwargs)
69 b4f69041 Stavros Sachtouris
        except KeyError:
70 b4f69041 Stavros Sachtouris
            return None
71 b4f69041 Stavros Sachtouris
    return wrap
72 b4f69041 Stavros Sachtouris
73 b4f69041 Stavros Sachtouris
74 392d902d Stavros Sachtouris
def addLogSettings(func):
75 b4f69041 Stavros Sachtouris
    def wrap(self, *args, **kwargs):
76 b4f69041 Stavros Sachtouris
        try:
77 392d902d Stavros Sachtouris
            return func(self, *args, **kwargs)
78 b4f69041 Stavros Sachtouris
        finally:
79 b4f69041 Stavros Sachtouris
            self._set_log_params()
80 b4f69041 Stavros Sachtouris
    return wrap
81 b4f69041 Stavros Sachtouris
82 b4f69041 Stavros Sachtouris
83 c75be81a Stavros Sachtouris
def dataModification(func):
84 c75be81a Stavros Sachtouris
    def wrap(self, inp):
85 c75be81a Stavros Sachtouris
        try:
86 c75be81a Stavros Sachtouris
            inp = func(self, inp)
87 c75be81a Stavros Sachtouris
        except Exception as e:
88 c75be81a Stavros Sachtouris
            log.warning('WARNING: Error while running %s: %s' % (func, e))
89 c75be81a Stavros Sachtouris
            log.warning('\tWARNING: Kamaki will use original data to go on')
90 c75be81a Stavros Sachtouris
        finally:
91 c75be81a Stavros Sachtouris
            return inp
92 c75be81a Stavros Sachtouris
    return wrap
93 c75be81a Stavros Sachtouris
94 c75be81a Stavros Sachtouris
95 5eae854d Stavros Sachtouris
class _command_init(object):
96 36526b3c Stavros Sachtouris
97 56d84a4e Stavros Sachtouris
    # self.arguments (dict) contains all non-positional arguments
98 56d84a4e Stavros Sachtouris
    # self.required (list or tuple) contains required argument keys
99 56d84a4e Stavros Sachtouris
    #     if it is a list, at least one of these arguments is required
100 56d84a4e Stavros Sachtouris
    #     if it is a tuple, all arguments are required
101 56d84a4e Stavros Sachtouris
    #     Lists and tuples can nest other lists and/or tuples
102 56d84a4e Stavros Sachtouris
103 1757c616 Stavros Sachtouris
    def __init__(
104 1757c616 Stavros Sachtouris
            self,
105 ff1c0296 Stavros Sachtouris
            arguments={}, auth_base=None, cloud=None,
106 ff1c0296 Stavros Sachtouris
            _in=None, _out=None, _err=None):
107 ff1c0296 Stavros Sachtouris
        self._in, self._out, self._err = (
108 ff1c0296 Stavros Sachtouris
            _in or stdin, _out or stdout, _err or stderr)
109 fd9457bd Stavros Sachtouris
        self._in = codecs.getreader('utf-8')(_in or stdin)
110 c2332605 Stavros Sachtouris
        self._out = codecs.getwriter(pref_enc)(_out or stdout)
111 c2332605 Stavros Sachtouris
        self._err = codecs.getwriter(pref_enc)(_err or stderr)
112 20206179 Stavros Sachtouris
        self.required = getattr(self, 'required', None)
113 e15d78e2 Stavros Sachtouris
        if hasattr(self, 'arguments'):
114 e15d78e2 Stavros Sachtouris
            arguments.update(self.arguments)
115 915b99b5 Stavros Sachtouris
        if isinstance(self, _optional_output_cmd):
116 915b99b5 Stavros Sachtouris
            arguments.update(self.oo_arguments)
117 545c6c29 Stavros Sachtouris
        if isinstance(self, _optional_json):
118 545c6c29 Stavros Sachtouris
            arguments.update(self.oj_arguments)
119 6d190dd1 Stavros Sachtouris
        if isinstance(self, _name_filter):
120 6d190dd1 Stavros Sachtouris
            arguments.update(self.nf_arguments)
121 6d190dd1 Stavros Sachtouris
        if isinstance(self, _id_filter):
122 6d190dd1 Stavros Sachtouris
            arguments.update(self.if_arguments)
123 60c42f9f Stavros Sachtouris
        try:
124 60c42f9f Stavros Sachtouris
            arguments.update(self.wait_arguments)
125 60c42f9f Stavros Sachtouris
        except AttributeError:
126 60c42f9f Stavros Sachtouris
            pass
127 e15d78e2 Stavros Sachtouris
        self.arguments = dict(arguments)
128 5eae854d Stavros Sachtouris
        try:
129 e15d78e2 Stavros Sachtouris
            self.config = self['config']
130 5eae854d Stavros Sachtouris
        except KeyError:
131 5eae854d Stavros Sachtouris
            pass
132 844a6bdb Stavros Sachtouris
        self.auth_base = auth_base or getattr(self, 'auth_base', None)
133 844a6bdb Stavros Sachtouris
        self.cloud = cloud or getattr(self, 'cloud', None)
134 5eae854d Stavros Sachtouris
135 ff1c0296 Stavros Sachtouris
    def write(self, s):
136 a5b748c2 Stavros Sachtouris
        self._out.write('%s' % s)
137 ff1c0296 Stavros Sachtouris
        self._out.flush()
138 ff1c0296 Stavros Sachtouris
139 ff1c0296 Stavros Sachtouris
    def writeln(self, s=''):
140 a5b748c2 Stavros Sachtouris
        self.write('%s\n' % s)
141 ff1c0296 Stavros Sachtouris
142 ff1c0296 Stavros Sachtouris
    def error(self, s=''):
143 a5b748c2 Stavros Sachtouris
        self._err.write('%s\n' % s)
144 ff1c0296 Stavros Sachtouris
        self._err.flush()
145 ff1c0296 Stavros Sachtouris
146 ddcb2e09 Stavros Sachtouris
    def print_list(self, *args, **kwargs):
147 ddcb2e09 Stavros Sachtouris
        kwargs.setdefault('out', self._out)
148 76f58e2e Stavros Sachtouris
        return print_list(*args, **kwargs)
149 ddcb2e09 Stavros Sachtouris
150 ddcb2e09 Stavros Sachtouris
    def print_dict(self, *args, **kwargs):
151 ddcb2e09 Stavros Sachtouris
        kwargs.setdefault('out', self._out)
152 76f58e2e Stavros Sachtouris
        return print_dict(*args, **kwargs)
153 ddcb2e09 Stavros Sachtouris
154 ddcb2e09 Stavros Sachtouris
    def print_json(self, *args, **kwargs):
155 ddcb2e09 Stavros Sachtouris
        kwargs.setdefault('out', self._out)
156 76f58e2e Stavros Sachtouris
        return print_json(*args, **kwargs)
157 ddcb2e09 Stavros Sachtouris
158 ddcb2e09 Stavros Sachtouris
    def print_items(self, *args, **kwargs):
159 ddcb2e09 Stavros Sachtouris
        kwargs.setdefault('out', self._out)
160 76f58e2e Stavros Sachtouris
        return print_items(*args, **kwargs)
161 ddcb2e09 Stavros Sachtouris
162 ddcb2e09 Stavros Sachtouris
    def ask_user(self, *args, **kwargs):
163 ddcb2e09 Stavros Sachtouris
        kwargs.setdefault('user_in', self._in)
164 ddcb2e09 Stavros Sachtouris
        kwargs.setdefault('out', self._out)
165 76f58e2e Stavros Sachtouris
        return ask_user(*args, **kwargs)
166 ddcb2e09 Stavros Sachtouris
167 b4f69041 Stavros Sachtouris
    @DontRaiseKeyError
168 b4f69041 Stavros Sachtouris
    def _custom_url(self, service):
169 144b3551 Stavros Sachtouris
        return self.config.get_cloud(self.cloud, '%s_url' % service)
170 b4f69041 Stavros Sachtouris
171 b4f69041 Stavros Sachtouris
    @DontRaiseKeyError
172 b4f69041 Stavros Sachtouris
    def _custom_token(self, service):
173 144b3551 Stavros Sachtouris
        return self.config.get_cloud(self.cloud, '%s_token' % service)
174 b4f69041 Stavros Sachtouris
175 b4f69041 Stavros Sachtouris
    @DontRaiseKeyError
176 b4f69041 Stavros Sachtouris
    def _custom_type(self, service):
177 144b3551 Stavros Sachtouris
        return self.config.get_cloud(self.cloud, '%s_type' % service)
178 b4f69041 Stavros Sachtouris
179 b4f69041 Stavros Sachtouris
    @DontRaiseKeyError
180 b4f69041 Stavros Sachtouris
    def _custom_version(self, service):
181 144b3551 Stavros Sachtouris
        return self.config.get_cloud(self.cloud, '%s_version' % service)
182 b4f69041 Stavros Sachtouris
183 f1e5b343 Stavros Sachtouris
    def _uuids2usernames(self, uuids):
184 db93db3e Stavros Sachtouris
        return self.auth_base.post_user_catalogs(uuids)
185 f1e5b343 Stavros Sachtouris
186 f1e5b343 Stavros Sachtouris
    def _usernames2uuids(self, username):
187 db93db3e Stavros Sachtouris
        return self.auth_base.post_user_catalogs(displaynames=username)
188 f1e5b343 Stavros Sachtouris
189 95641ecc Stavros Sachtouris
    def _uuid2username(self, uuid):
190 f1e5b343 Stavros Sachtouris
        return self._uuids2usernames([uuid]).get(uuid, None)
191 95641ecc Stavros Sachtouris
192 95641ecc Stavros Sachtouris
    def _username2uuid(self, username):
193 f1e5b343 Stavros Sachtouris
        return self._usernames2uuids([username]).get(username, None)
194 95641ecc Stavros Sachtouris
195 f47417e7 Stavros Sachtouris
    def _set_log_params(self):
196 b3bb083f Stavros Sachtouris
        try:
197 64a3c0de Stavros Sachtouris
            self.client.LOG_TOKEN = (
198 534e7bbb Stavros Sachtouris
                self['config'].get('global', 'log_token').lower() == 'on')
199 64a3c0de Stavros Sachtouris
        except Exception as e:
200 64a3c0de Stavros Sachtouris
            log.debug('Failed to read custom log_token setting:'
201 64a3c0de Stavros Sachtouris
                '%s\n default for log_token is off' % e)
202 64a3c0de Stavros Sachtouris
        try:
203 64a3c0de Stavros Sachtouris
            self.client.LOG_DATA = (
204 534e7bbb Stavros Sachtouris
                self['config'].get('global', 'log_data').lower() == 'on')
205 c5b9380c Stavros Sachtouris
        except Exception as e:
206 64a3c0de Stavros Sachtouris
            log.debug('Failed to read custom log_data setting:'
207 64a3c0de Stavros Sachtouris
                '%s\n default for log_data is off' % e)
208 64a3c0de Stavros Sachtouris
        try:
209 64a3c0de Stavros Sachtouris
            self.client.LOG_PID = (
210 534e7bbb Stavros Sachtouris
                self['config'].get('global', 'log_pid').lower() == 'on')
211 64a3c0de Stavros Sachtouris
        except Exception as e:
212 64a3c0de Stavros Sachtouris
            log.debug('Failed to read custom log_pid setting:'
213 64a3c0de Stavros Sachtouris
                '%s\n default for log_pid is off' % e)
214 c5b9380c Stavros Sachtouris
215 8547cd19 Stavros Sachtouris
    def _safe_progress_bar(
216 8547cd19 Stavros Sachtouris
            self, msg, arg='progress_bar', countdown=False, timeout=100):
217 5a673575 Stavros Sachtouris
        """Try to get a progress bar, but do not raise errors"""
218 5a673575 Stavros Sachtouris
        try:
219 5a673575 Stavros Sachtouris
            progress_bar = self.arguments[arg]
220 ff1c0296 Stavros Sachtouris
            progress_bar.file = self._err
221 8547cd19 Stavros Sachtouris
            gen = progress_bar.get_generator(
222 8547cd19 Stavros Sachtouris
                msg, countdown=countdown, timeout=timeout)
223 5a673575 Stavros Sachtouris
        except Exception:
224 5a673575 Stavros Sachtouris
            return (None, None)
225 5a673575 Stavros Sachtouris
        return (progress_bar, gen)
226 5a673575 Stavros Sachtouris
227 5a673575 Stavros Sachtouris
    def _safe_progress_bar_finish(self, progress_bar):
228 5a673575 Stavros Sachtouris
        try:
229 5a673575 Stavros Sachtouris
            progress_bar.finish()
230 5a673575 Stavros Sachtouris
        except Exception:
231 5a673575 Stavros Sachtouris
            pass
232 5a673575 Stavros Sachtouris
233 5a37a189 Stavros Sachtouris
    def __getitem__(self, argterm):
234 5a37a189 Stavros Sachtouris
        """
235 5a37a189 Stavros Sachtouris
        :param argterm: (str) the name/label of an argument in self.arguments
236 5a37a189 Stavros Sachtouris

237 b113e74b Stavros Sachtouris
        :returns: the value of the corresponding Argument (not the argument
238 b113e74b Stavros Sachtouris
            object)
239 5a37a189 Stavros Sachtouris

240 5a37a189 Stavros Sachtouris
        :raises KeyError: if argterm not in self.arguments of this object
241 5a37a189 Stavros Sachtouris
        """
242 b113e74b Stavros Sachtouris
        return self.arguments[argterm].value
243 5a37a189 Stavros Sachtouris
244 5a37a189 Stavros Sachtouris
    def __setitem__(self, argterm, arg):
245 5a37a189 Stavros Sachtouris
        """Install an argument as argterm
246 5a37a189 Stavros Sachtouris
        If argterm points to another argument, the other argument is lost
247 5a37a189 Stavros Sachtouris

248 5a37a189 Stavros Sachtouris
        :param argterm: (str)
249 5a37a189 Stavros Sachtouris

250 5a37a189 Stavros Sachtouris
        :param arg: (Argument)
251 5a37a189 Stavros Sachtouris
        """
252 5a37a189 Stavros Sachtouris
        if not hasattr(self, 'arguments'):
253 5a37a189 Stavros Sachtouris
            self.arguments = {}
254 5a37a189 Stavros Sachtouris
        self.arguments[argterm] = arg
255 5a37a189 Stavros Sachtouris
256 b113e74b Stavros Sachtouris
    def get_argument_object(self, argterm):
257 b113e74b Stavros Sachtouris
        """
258 b113e74b Stavros Sachtouris
        :param argterm: (str) the name/label of an argument in self.arguments
259 b113e74b Stavros Sachtouris

260 b113e74b Stavros Sachtouris
        :returns: the arument object
261 b113e74b Stavros Sachtouris

262 b113e74b Stavros Sachtouris
        :raises KeyError: if argterm not in self.arguments of this object
263 b113e74b Stavros Sachtouris
        """
264 b113e74b Stavros Sachtouris
        return self.arguments[argterm]
265 b113e74b Stavros Sachtouris
266 5eae854d Stavros Sachtouris
    def get_argument(self, argterm):
267 5a37a189 Stavros Sachtouris
        """
268 5a37a189 Stavros Sachtouris
        :param argterm: (str) the name/label of an argument in self.arguments
269 5a37a189 Stavros Sachtouris

270 5a37a189 Stavros Sachtouris
        :returns: the value of the arument object
271 5a37a189 Stavros Sachtouris

272 5a37a189 Stavros Sachtouris
        :raises KeyError: if argterm not in self.arguments of this object
273 5a37a189 Stavros Sachtouris
        """
274 e15d78e2 Stavros Sachtouris
        return self[argterm]
275 915b99b5 Stavros Sachtouris
276 915b99b5 Stavros Sachtouris
277 545c6c29 Stavros Sachtouris
#  feature classes - inherit them to get special features for your commands
278 545c6c29 Stavros Sachtouris
279 545c6c29 Stavros Sachtouris
280 f76c6bbc Stavros Sachtouris
class OutputFormatArgument(ValueArgument):
281 f76c6bbc Stavros Sachtouris
    """Accepted output formats: json (default)"""
282 f76c6bbc Stavros Sachtouris
283 f76c6bbc Stavros Sachtouris
    formats = ('json', )
284 f76c6bbc Stavros Sachtouris
285 f76c6bbc Stavros Sachtouris
    def ___init__(self, *args, **kwargs):
286 f76c6bbc Stavros Sachtouris
        super(OutputFormatArgument, self).___init__(*args, **kwargs)
287 f76c6bbc Stavros Sachtouris
288 f76c6bbc Stavros Sachtouris
    @property
289 f76c6bbc Stavros Sachtouris
    def value(self):
290 9b3c8fd9 Stavros Sachtouris
        return getattr(self, '_value', None)
291 f76c6bbc Stavros Sachtouris
292 f76c6bbc Stavros Sachtouris
    @value.setter
293 f76c6bbc Stavros Sachtouris
    def value(self, newvalue):
294 f76c6bbc Stavros Sachtouris
        if not newvalue:
295 f76c6bbc Stavros Sachtouris
            self._value = self.default
296 f76c6bbc Stavros Sachtouris
        elif newvalue.lower() in self.formats:
297 f76c6bbc Stavros Sachtouris
            self._value = newvalue.lower
298 f76c6bbc Stavros Sachtouris
        else:
299 f76c6bbc Stavros Sachtouris
            raise CLIInvalidArgument(
300 f76c6bbc Stavros Sachtouris
                'Invalid value %s for argument %s' % (
301 eb647cfe Stavros Sachtouris
                    newvalue, self.lvalue),
302 f76c6bbc Stavros Sachtouris
                details=['Valid output formats: %s' % ', '.join(self.formats)])
303 f76c6bbc Stavros Sachtouris
304 f76c6bbc Stavros Sachtouris
305 915b99b5 Stavros Sachtouris
class _optional_output_cmd(object):
306 915b99b5 Stavros Sachtouris
307 915b99b5 Stavros Sachtouris
    oo_arguments = dict(
308 915b99b5 Stavros Sachtouris
        with_output=FlagArgument('show response headers', ('--with-output')),
309 f76c6bbc Stavros Sachtouris
        json_output=FlagArgument(
310 f76c6bbc Stavros Sachtouris
            'show headers in json (DEPRECATED from v0.12,'
311 de329b4c Stavros Sachtouris
            '  please use --output-format=json instead)', ('-j', '--json'))
312 915b99b5 Stavros Sachtouris
    )
313 915b99b5 Stavros Sachtouris
314 915b99b5 Stavros Sachtouris
    def _optional_output(self, r):
315 915b99b5 Stavros Sachtouris
        if self['json_output']:
316 1757c616 Stavros Sachtouris
            print_json(r, out=self._out)
317 915b99b5 Stavros Sachtouris
        elif self['with_output']:
318 1757c616 Stavros Sachtouris
            print_items([r] if isinstance(r, dict) else r, out=self._out)
319 545c6c29 Stavros Sachtouris
320 545c6c29 Stavros Sachtouris
321 545c6c29 Stavros Sachtouris
class _optional_json(object):
322 545c6c29 Stavros Sachtouris
323 545c6c29 Stavros Sachtouris
    oj_arguments = dict(
324 f76c6bbc Stavros Sachtouris
        output_format=OutputFormatArgument(
325 f76c6bbc Stavros Sachtouris
            'Show output in chosen output format (%s)' % ', '.join(
326 f76c6bbc Stavros Sachtouris
                OutputFormatArgument.formats),
327 f76c6bbc Stavros Sachtouris
            '--output-format'),
328 f76c6bbc Stavros Sachtouris
        json_output=FlagArgument(
329 f76c6bbc Stavros Sachtouris
            'show output in json (DEPRECATED from v0.12,'
330 f76c6bbc Stavros Sachtouris
            ' please use --output-format instead)', ('-j', '--json'))
331 545c6c29 Stavros Sachtouris
    )
332 545c6c29 Stavros Sachtouris
333 1757c616 Stavros Sachtouris
    def _print(self, output, print_method=print_items, **print_method_kwargs):
334 f76c6bbc Stavros Sachtouris
        if self['json_output'] or self['output_format']:
335 1757c616 Stavros Sachtouris
            print_json(output, out=self._out)
336 545c6c29 Stavros Sachtouris
        else:
337 eddaace7 Stavros Sachtouris
            print_method_kwargs.setdefault('out', self._out)
338 eddaace7 Stavros Sachtouris
            print_method(output, **print_method_kwargs)
339 6d190dd1 Stavros Sachtouris
340 6d190dd1 Stavros Sachtouris
341 6d190dd1 Stavros Sachtouris
class _name_filter(object):
342 6d190dd1 Stavros Sachtouris
343 6d190dd1 Stavros Sachtouris
    nf_arguments = dict(
344 6d190dd1 Stavros Sachtouris
        name=ValueArgument('filter by name', '--name'),
345 6d190dd1 Stavros Sachtouris
        name_pref=ValueArgument(
346 6d190dd1 Stavros Sachtouris
            'filter by name prefix (case insensitive)', '--name-prefix'),
347 6d190dd1 Stavros Sachtouris
        name_suff=ValueArgument(
348 6d190dd1 Stavros Sachtouris
            'filter by name suffix (case insensitive)', '--name-suffix'),
349 6d190dd1 Stavros Sachtouris
        name_like=ValueArgument(
350 6d190dd1 Stavros Sachtouris
            'print only if name contains this (case insensitive)',
351 6d190dd1 Stavros Sachtouris
            '--name-like')
352 6d190dd1 Stavros Sachtouris
    )
353 6d190dd1 Stavros Sachtouris
354 6d190dd1 Stavros Sachtouris
    def _non_exact_name_filter(self, items):
355 6d190dd1 Stavros Sachtouris
        np, ns, nl = self['name_pref'], self['name_suff'], self['name_like']
356 6d190dd1 Stavros Sachtouris
        return [item for item in items if (
357 f3740b99 Stavros Sachtouris
            (not np) or (item['name'] or '').lower().startswith(
358 f3740b99 Stavros Sachtouris
                np.lower())) and (
359 f3740b99 Stavros Sachtouris
            (not ns) or (item['name'] or '').lower().endswith(
360 f3740b99 Stavros Sachtouris
                ns.lower())) and (
361 f3740b99 Stavros Sachtouris
            (not nl) or nl.lower() in (item['name'] or '').lower())]
362 6d190dd1 Stavros Sachtouris
363 6d190dd1 Stavros Sachtouris
    def _exact_name_filter(self, items):
364 f3740b99 Stavros Sachtouris
        return filter_dicts_by_dict(items, dict(name=self['name'] or '')) if (
365 6d190dd1 Stavros Sachtouris
            self['name']) else items
366 6d190dd1 Stavros Sachtouris
367 6d190dd1 Stavros Sachtouris
    def _filter_by_name(self, items):
368 6d190dd1 Stavros Sachtouris
        return self._non_exact_name_filter(self._exact_name_filter(items))
369 6d190dd1 Stavros Sachtouris
370 6d190dd1 Stavros Sachtouris
371 6d190dd1 Stavros Sachtouris
class _id_filter(object):
372 6d190dd1 Stavros Sachtouris
373 6d190dd1 Stavros Sachtouris
    if_arguments = dict(
374 6d190dd1 Stavros Sachtouris
        id=ValueArgument('filter by id', '--id'),
375 6d190dd1 Stavros Sachtouris
        id_pref=ValueArgument(
376 6d190dd1 Stavros Sachtouris
            'filter by id prefix (case insensitive)', '--id-prefix'),
377 6d190dd1 Stavros Sachtouris
        id_suff=ValueArgument(
378 6d190dd1 Stavros Sachtouris
            'filter by id suffix (case insensitive)', '--id-suffix'),
379 6d190dd1 Stavros Sachtouris
        id_like=ValueArgument(
380 aef3fa1f Stavros Sachtouris
            'print only if id contains this (case insensitive)', '--id-like')
381 6d190dd1 Stavros Sachtouris
    )
382 6d190dd1 Stavros Sachtouris
383 6d190dd1 Stavros Sachtouris
    def _non_exact_id_filter(self, items):
384 6d190dd1 Stavros Sachtouris
        np, ns, nl = self['id_pref'], self['id_suff'], self['id_like']
385 6d190dd1 Stavros Sachtouris
        return [item for item in items if (
386 6d190dd1 Stavros Sachtouris
            (not np) or (
387 6d190dd1 Stavros Sachtouris
                '%s' % item['id']).lower().startswith(np.lower())) and (
388 6d190dd1 Stavros Sachtouris
            (not ns) or ('%s' % item['id']).lower().endswith(ns.lower())) and (
389 6d190dd1 Stavros Sachtouris
            (not nl) or nl.lower() in ('%s' % item['id']).lower())]
390 6d190dd1 Stavros Sachtouris
391 6d190dd1 Stavros Sachtouris
    def _exact_id_filter(self, items):
392 6d190dd1 Stavros Sachtouris
        return filter_dicts_by_dict(items, dict(id=self['id'])) if (
393 6d190dd1 Stavros Sachtouris
            self['id']) else items
394 6d190dd1 Stavros Sachtouris
395 6d190dd1 Stavros Sachtouris
    def _filter_by_id(self, items):
396 6d190dd1 Stavros Sachtouris
        return self._non_exact_id_filter(self._exact_id_filter(items))