• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

deadc0de6 / catcli / 4399176145

pending completion
4399176145

Pull #30

github

GitHub
Merge ee2cf80d9 into 7590ad02c
Pull Request #30: Fuse

474 of 474 new or added lines in 13 files covered. (100.0%)

1304 of 1691 relevant lines covered (77.11%)

3.86 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

68.42
/catcli/utils.py
1
"""
2
author: deadc0de6 (https://github.com/deadc0de6)
3
Copyright (c) 2017, deadc0de6
4

5
helpers
6
"""
7

8
import os
5✔
9
import hashlib
5✔
10
import tempfile
5✔
11
import subprocess
5✔
12
import datetime
5✔
13

14
# local imports
15
from catcli import nodes
5✔
16
from catcli.exceptions import CatcliException
5✔
17

18

19
SEPARATOR = '/'
5✔
20
WILD = '*'
5✔
21

22

23
def path_to_top(path: str) -> str:
5✔
24
    """path pivot under top"""
25
    pre = f'{SEPARATOR}{nodes.NAME_TOP}'
×
26
    if not path.startswith(pre):
×
27
        # prepend with top node path
28
        path = pre + path
×
29
    return path
×
30

31

32
def path_to_search_all(path: str) -> str:
5✔
33
    """path to search for all subs"""
34
    if not path:
5✔
35
        path = SEPARATOR
5✔
36
    if not path.startswith(SEPARATOR):
5✔
37
        path = SEPARATOR + path
5✔
38
    pre = f'{SEPARATOR}{nodes.NAME_TOP}'
5✔
39
    if not path.startswith(pre):
5✔
40
        # prepend with top node path
41
        path = pre + path
5✔
42
    if not path.endswith(SEPARATOR):
5✔
43
        # ensure ends with a separator
44
        path += SEPARATOR
5✔
45
    if not path.endswith(WILD):
5✔
46
        # add wild card
47
        path += WILD
5✔
48
    return path
5✔
49

50

51
def md5sum(path: str) -> str:
5✔
52
    """
53
    calculate md5 sum of a file
54
    may raise exception
55
    """
56
    rpath = os.path.realpath(path)
5✔
57
    if not os.path.exists(rpath):
5✔
58
        raise CatcliException(f'md5sum - file does not exist: {rpath}')
×
59
    try:
5✔
60
        with open(rpath, mode='rb') as file:
5✔
61
            hashv = hashlib.md5()
5✔
62
            while True:
3✔
63
                buf = file.read(4096)
5✔
64
                if not buf:
5✔
65
                    break
5✔
66
                hashv.update(buf)
5✔
67
            return hashv.hexdigest()
5✔
68
    except PermissionError:
×
69
        pass
×
70
    except OSError as exc:
×
71
        raise CatcliException(f'md5sum error: {exc}') from exc
×
72
    return ''
×
73

74

75
def size_to_str(size: float,
5✔
76
                raw: bool = True) -> str:
77
    """convert size to string, optionally human readable"""
78
    div = 1024.
5✔
79
    suf = ['B', 'K', 'M', 'G', 'T', 'P']
5✔
80
    if raw or size < div:
5✔
81
        return f'{size}'
5✔
82
    for i in suf:
5✔
83
        if size < div:
5✔
84
            return f'{size:.1f}{i}'
5✔
85
        size = size / div
5✔
86
    sufix = suf[-1]
×
87
    return f'{size:.1f}{sufix}'
×
88

89

90
def epoch_to_str(epoch: float) -> str:
5✔
91
    """convert epoch to string"""
92
    if not epoch:
5✔
93
        return ''
×
94
    fmt = '%Y-%m-%d %H:%M:%S'
5✔
95
    timestamp = datetime.datetime.fromtimestamp(epoch)
5✔
96
    return timestamp.strftime(fmt)
5✔
97

98

99
def ask(question: str) -> bool:
5✔
100
    """ask the user what to do"""
101
    resp = input(f'{question} [y|N] ? ')
×
102
    return resp.lower() == 'y'
×
103

104

105
def edit(string: str) -> str:
5✔
106
    """edit the information with the default EDITOR"""
107
    data = string.encode('utf-8')
×
108
    editor = os.environ.get('EDITOR', 'vim')
×
109
    with tempfile.NamedTemporaryFile(prefix='catcli', suffix='.tmp') as file:
×
110
        file.write(data)
×
111
        file.flush()
×
112
        subprocess.call([editor, file.name])
×
113
        file.seek(0)
×
114
        new = file.read()
×
115
    return new.decode('utf-8')
×
116

117

118
def fix_badchars(string: str) -> str:
5✔
119
    """fix none utf-8 chars in string"""
120
    return string.encode('utf-8', 'ignore').decode('utf-8')
5✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc