Revision 001200c3

b/kamaki/cli/commands/pithos_cli.py
36 36
from kamaki.cli.errors import raiseCLIError, CLISyntaxError
37 37
from kamaki.cli.utils import (
38 38
    format_size,
39
    to_bytes,
39 40
    print_dict,
40 41
    pretty_keys,
41 42
    page_hold,
......
88 89
            '- total quota:      /store quota',
89 90
            '- container quota:  /store quota <container>',
90 91
            'Users shall set a higher container quota, if available:',
91
            '-                  /store setquota <limit in KB> <container>'
92
            '-                  /store setquota <quota>[unit] <container>'
92 93
            ])
93 94

  
94 95

  
......
1780 1781

  
1781 1782
@command(pithos_cmds)
1782 1783
class store_quota(_store_account_command):
1783
    """Get quota (in KB) for account or container"""
1784
    """Get quota for account or container"""
1785

  
1786
    arguments = dict(
1787
        in_bytes=FlagArgument('Show result in bytes', ('-b', '--bytes'))
1788
        )
1784 1789

  
1785 1790
    def main(self, container=None):
1786 1791
        super(self.__class__, self).main()
......
1799 1804
            raiseCLIError(err)
1800 1805
        except Exception as err:
1801 1806
            raiseCLIError(err)
1807
        if not self['in_bytes']:
1808
            for k in reply:
1809
                reply[k] = format_size(reply[k])
1802 1810
        print_dict(pretty_keys(reply, '-'))
1803 1811

  
1804 1812

  
1805 1813
@command(pithos_cmds)
1806 1814
class store_setquota(_store_account_command):
1807
    """Set new quota (in KB) for account or container"""
1815
    """Set new quota for account or container
1816
    By default, quota is set in bytes
1817
    Users may specify a different unit, e.g:
1818
    /store setquota 2.3GB mycontainer
1819
    Accepted units: B, KiB (1024 B), KB (1000 B), MiB, MB, GiB, GB, TiB, TB
1820
    """
1821

  
1822
    def _calculate_quota(self, user_input):
1823
        quota = 0
1824
        try:
1825
            quota = int(user_input)
1826
        except ValueError:
1827
            index = 0
1828
            digits = [str(num) for num in range(0, 10)] + ['.']
1829
            while user_input[index] in digits:
1830
                index += 1
1831
            quota = user_input[:index]
1832
            format = user_input[index:]
1833
            try:
1834
                return to_bytes(quota, format)
1835
            except Exception as qe:
1836
                raiseCLIError(qe,
1837
                    'Failed to convert %s to bytes' % user_input,
1838
                    details=['Syntax: setquota <quota>[format] [container]',
1839
                        'e.g.: setquota 2.3GB mycontainer',
1840
                        'Acceptable formats:',
1841
                        '(*1024): B, KiB, MiB, GiB, TiB',
1842
                        '(*1000): B, KB, MB, GB, TB'])
1843
        return quota
1808 1844

  
1809 1845
    def main(self, quota, container=None):
1810 1846
        super(self.__class__, self).main()
1847
        quota = self._calculate_quota(quota)
1811 1848
        try:
1812 1849
            if container is None:
1813 1850
                self.client.set_account_quota(quota)
b/kamaki/cli/utils.py
257 257

  
258 258

  
259 259
def format_size(size):
260
    units = ('B', 'K', 'M', 'G', 'T')
260
    units = ('B', 'KiB', 'MiB', 'GiB', 'TiB')
261 261
    try:
262 262
        size = float(size)
263 263
    except ValueError as err:
......
265 265
    for unit in units:
266 266
        if size < 1024:
267 267
            break
268
        size /= 1024
269
    s = ('%.1f' % size)
270
    if '.0' == s[-2:]:
271
        s = s[:-2]
268
        size /= 1024.0
269
    s = ('%.2f' % size)
270
    while '.' in s and s[-1] in ('0', '.'):
271
        s = s[:-1]
272 272
    return s + unit
273 273

  
274 274

  
275
def to_bytes(size, format):
276
    """
277
    :param size: (float) the size in the given format
278
    :param format: (case insensitive) KiB, KB, MiB, MB, GiB, GB, TiB, TB
279

  
280
    :returns: (int) the size in bytes
281
    """
282
    format = format.upper()
283
    if format == 'B':
284
        return int(size)
285
    size = float(size)
286
    units_dc = ('KB', 'MB', 'GB', 'TB')
287
    units_bi = ('KIB', 'MIB', 'GIB', 'TIB')
288

  
289
    factor = 1024 if format in units_bi else 1000 if format in units_dc else 0
290
    if not factor:
291
        raise ValueError('Invalid data size format %s' % format)
292
    for prefix in ('K', 'M', 'G', 'T'):
293
        size *= factor
294
        if format.startswith(prefix):
295
            break
296
    return int(size)
297

  
298

  
275 299
def dict2file(d, f, depth=0):
276 300
    for k, v in d.items():
277 301
        f.write('%s%s: ' % ('\t' * depth, k))
......
325 349
    return terms
326 350

  
327 351

  
328
def ask_user(msg, true_responses=('Y', 'y')):
352
def ask_user(msg, true_resp=['Y', 'y']):
329 353
    """Print msg and read user response
330 354

  
331
    :param true_responses: (tuple of chars)
355
    :param true_resp: (tuple of chars)
332 356

  
333 357
    :returns: (bool) True if reponse in true responses, False otherwise
334 358
    """
335
    stdout.write('%s (%s for yes):' % (msg, true_responses))
359
    stdout.write('%s (%s or enter for yes):' % (msg, ', '.join(true_resp)))
336 360
    stdout.flush()
337
    user_response = stdin.read(1)
338
    return user_response[0] in true_responses
361
    user_response = stdin.readline()
362
    return user_response[0] in true_resp + ['\n']

Also available in: Unified diff