Revision 23963422 kamaki/cli/utils/__init__.py

b/kamaki/cli/utils/__init__.py
67 67
    stdout.write(w)
68 68

  
69 69

  
70
def _flush():
71
    """stdout.flush wrapper is used to help unittests check what is called"""
72
    stdout.flush()
73

  
74

  
75
def _readline():
76
    """stdout.readline wrapper is used to help unittests"""
77
    return stdout.readline()
78

  
79

  
70 80
def suggest_missing(miss=None, exclude=[]):
71 81
    global suggest
72 82
    sgs = dict(suggest)
......
295 305
        page_hold(i + 1, page_size, len(items))
296 306

  
297 307

  
298
def format_size(size):
299
    units = ('B', 'KiB', 'MiB', 'GiB', 'TiB')
308
def format_size(size, decimal_factors=False):
309
    units = ('B', 'KB', 'MB', 'GB', 'TB') if decimal_factors else (
310
        'B', 'KiB', 'MiB', 'GiB', 'TiB')
311
    step = 1000 if decimal_factors else 1024
312
    fstep = float(step)
300 313
    try:
301 314
        size = float(size)
302
    except ValueError as err:
303
        raiseCLIError(err, 'Cannot format %s in bytes' % size)
304
    for unit in units:
305
        if size < 1024:
315
    except (ValueError, TypeError) as err:
316
        raiseCLIError(err, 'Cannot format %s in bytes' % (
317
            ','.join(size) if isinstance(size, tuple) else size))
318
    for i, unit in enumerate(units):
319
        if size < step or i + 1 == len(units):
306 320
            break
307
        size /= 1024.0
321
        size /= fstep
308 322
    s = ('%.2f' % size)
323
    s = s.replace('%s' % step, '%s.99' % (step - 1)) if size <= fstep else s
309 324
    while '.' in s and s[-1] in ('0', '.'):
310 325
        s = s[:-1]
311 326
    return s + unit
......
317 332
    :param format: (case insensitive) KiB, KB, MiB, MB, GiB, GB, TiB, TB
318 333

  
319 334
    :returns: (int) the size in bytes
335
    :raises ValueError: if invalid size or format
336
    :raises AttributeError: if format is not str
337
    :raises TypeError: if size is not arithmetic or convertible to arithmetic
320 338
    """
321 339
    format = format.upper()
322 340
    if format == 'B':
......
337 355

  
338 356
def dict2file(d, f, depth=0):
339 357
    for k, v in d.items():
340
        f.write('%s%s: ' % ('\t' * depth, k))
358
        f.write('%s%s: ' % (' ' * INDENT_TAB * depth, k))
341 359
        if isinstance(v, dict):
342 360
            f.write('\n')
343 361
            dict2file(v, f, depth + 1)
344
        elif isinstance(v, list):
362
        elif isinstance(v, list) or isinstance(v, tuple):
345 363
            f.write('\n')
346 364
            list2file(v, f, depth + 1)
347 365
        else:
348
            f.write(' %s\n' % v)
366
            f.write('%s\n' % v)
349 367

  
350 368

  
351 369
def list2file(l, f, depth=1):
352 370
    for item in l:
353 371
        if isinstance(item, dict):
354 372
            dict2file(item, f, depth + 1)
355
        elif isinstance(item, list):
373
        elif isinstance(item, list) or isinstance(item, tuple):
356 374
            list2file(item, f, depth + 1)
357 375
        else:
358
            f.write('%s%s\n' % ('\t' * depth, item))
376
            f.write('%s%s\n' % (' ' * INDENT_TAB * depth, item))
359 377

  
360 378
# Split input auxiliary
361 379

  
......
365 383
    return (re_parser.split(line), re_parser.findall(line))
366 384

  
367 385

  
368
def _sub_split(line):
369
    terms = []
370
    (sub_trivials, sub_interesting) = _parse_with_regex(line, ' ".*?" ')
371
    for subi, subipart in enumerate(sub_interesting):
372
        terms += sub_trivials[subi].split()
373
        terms.append(subipart[2:-2])
374
    terms += sub_trivials[-1].split()
375
    return terms
376

  
377

  
378
def old_split_input(line):
379
    """Use regular expressions to split a line correctly"""
380
    line = ' %s ' % line
381
    (trivial_parts, interesting_parts) = _parse_with_regex(line, ' \'.*?\' ')
382
    terms = []
383
    for i, ipart in enumerate(interesting_parts):
384
        terms += _sub_split(trivial_parts[i])
385
        terms.append(ipart[2:-2])
386
    terms += _sub_split(trivial_parts[-1])
387
    return terms
388

  
389

  
390 386
def _get_from_parsed(parsed_str):
391 387
    try:
392 388
        parsed_str = parsed_str.strip()
393 389
    except:
394 390
        return None
395
    if parsed_str:
396
        if parsed_str[0] == parsed_str[-1] and parsed_str[0] in ("'", '"'):
397
            return [parsed_str[1:-1]]
398
        return parsed_str.split(' ')
399
    return None
391
    return ([parsed_str[1:-1]] if (
392
        parsed_str[0] == parsed_str[-1] and parsed_str[0] in ("'", '"')) else (
393
            parsed_str.split(' '))) if parsed_str else None
400 394

  
401 395

  
402 396
def split_input(line):
......
405 399
    reg_expr = '\'.*?\'|".*?"|^[\S]*$'
406 400
    (trivial_parts, interesting_parts) = _parse_with_regex(line, reg_expr)
407 401
    assert(len(trivial_parts) == 1 + len(interesting_parts))
408
    #print('  [split_input] trivial_parts %s are' % trivial_parts)
409
    #print('  [split_input] interesting_parts %s are' % interesting_parts)
410 402
    terms = []
411 403
    for i, tpart in enumerate(trivial_parts):
412 404
        part = _get_from_parsed(tpart)
......
428 420

  
429 421
    :returns: (bool) True if reponse in true responses, False otherwise
430 422
    """
431
    stdout.write('%s [%s/N]: ' % (msg, ', '.join(true_resp)))
432
    stdout.flush()
433
    user_response = stdin.readline()
423
    _write('%s [%s/N]: ' % (msg, ', '.join(true_resp)))
424
    _flush()
425
    user_response = _readline()
434 426
    return user_response[0].lower() in true_resp
435 427

  
436 428

  
437 429
def spiner(size=None):
438 430
    spins = ('/', '-', '\\', '|')
439
    stdout.write(' ')
431
    _write(' ')
440 432
    size = size or -1
441 433
    i = 0
442 434
    while size - i:
443
        stdout.write('\b%s' % spins[i % len(spins)])
444
        stdout.flush()
435
        _write('\b%s' % spins[i % len(spins)])
436
        _flush()
445 437
        i += 1
446 438
        sleep(0.1)
447 439
        yield
448 440
    yield
449 441

  
450
if __name__ == '__main__':
451
    examples = [
452
        'la_la le_le li_li',
453
        '\'la la\' \'le le\' \'li li\'',
454
        '\'la la\' le_le \'li li\'',
455
        'la_la \'le le\' li_li',
456
        'la_la \'le le\' \'li li\'',
457
        '"la la" "le le" "li li"',
458
        '"la la" le_le "li li"',
459
        'la_la "le le" li_li',
460
        '"la_la" "le le" "li li"',
461
        '\'la la\' "le le" \'li li\'',
462
        'la_la \'le le\' "li li"',
463
        'la_la \'le le\' li_li',
464
        '\'la la\' le_le "li li"',
465
        '"la la" le_le \'li li\'',
466
        '"la la" \'le le\' li_li',
467
        'la_la \'le\'le\' "li\'li"',
468
        '"la \'le le\' la"',
469
        '\'la "le le" la\'',
470
        '\'la "la" la\' "le \'le\' le" li_"li"_li',
471
        '\'\' \'L\' "" "A"']
472

  
473
    for i, example in enumerate(examples):
474
        print('%s. Split this: (%s)' % (i + 1, example))
475
        ret = old_split_input(example)
476
        print('\t(%s) of size %s' % (ret, len(ret)))
477

  
478 442

  
479 443
def get_path_size(testpath):
480 444
    if path.isfile(testpath):

Also available in: Unified diff