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

cisagov / pshtt / 11299335419

06 Aug 2024 09:00PM UTC coverage: 34.903% (+0.5%) from 34.375%
11299335419

push

github

web-flow
Merge pull request #255 from cisagov/lineage/skeleton

⚠️ CONFLICT! Lineage pull request for: skeleton

54 of 303 branches covered (17.82%)

Branch coverage included in aggregate %.

1 of 2 new or added lines in 2 files covered. (50.0%)

361 of 886 relevant lines covered (40.74%)

1.63 hits per line

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

37.93
/src/pshtt/utils.py
1
"""Define utility functions for the pshtt library."""
2

3
# Standard Python Libraries
4
import contextlib
4✔
5
import csv
4✔
6
import datetime
4✔
7
import errno
4✔
8
import json
4✔
9
import logging
4✔
10
import os
4✔
11
import re
4✔
12
import sys
4✔
13
import traceback
4✔
14

15

16
# Display exception without re-throwing it.
17
def format_last_exception():
4✔
18
    """Pretty format the last raised exception."""
19
    exc_type, exc_value, exc_traceback = sys.exc_info()
×
20
    return "\n".join(traceback.format_exception(exc_type, exc_value, exc_traceback))
×
21

22

23
# mkdir -p in python, from:
24
# http://stackoverflow.com/questions/600268/mkdir-p-functionality-in-python
25
def mkdir_p(path):
4✔
26
    """Make a directory and any missing directories in the path."""
27
    try:
×
28
        os.makedirs(path)
×
29
    except OSError as exc:  # Python >2.5
×
30
        if exc.errno == errno.EEXIST:
×
31
            pass
×
32
        else:
33
            raise
×
34

35

36
def json_for(data):
4✔
37
    """Pretty format the given object to JSON."""
38
    return json.dumps(data, sort_keys=True, indent=2, default=format_datetime)
×
39

40

41
def write(content, destination, binary=False):
4✔
42
    """Write contents to a destination after making any missing directories."""
43
    parent = os.path.dirname(destination)
×
44
    if parent != "":
×
45
        mkdir_p(parent)
×
46

NEW
47
    with (
×
48
        open(destination, "bw") if binary else open(destination, "w", encoding="utf-8")
49
    ) as f:
50
        f.write(content)
×
51

52

53
def format_datetime(obj):
4✔
54
    """Provide a formatted datetime."""
55
    if isinstance(obj, datetime.date):
×
56
        return obj.isoformat()
×
57
    if isinstance(obj, str):
×
58
        return obj
×
59
    return None
×
60

61

62
# Load domains from a CSV, skip a header row
63
def load_domains(domain_csv):
4✔
64
    """Load a list of domains from a CSV file."""
65
    domains = []
×
66
    with open(domain_csv, encoding="utf-8") as csvfile:
×
67
        for row in csv.reader(csvfile):
×
68
            # Skip empty rows.
69
            if not row or not row[0].strip():
×
70
                continue
×
71

72
            row[0] = row[0].lower()
×
73
            # Skip any header row.
74
            if not domains and row[0].startswith("domain"):
×
75
                continue
×
76

77
            domains.append(row[0])
×
78
    return domains
×
79

80

81
# Configure logging level, so logging.debug can hinge on --debug.
82
def configure_logging(debug_logging=False):
4✔
83
    """Configure the logging library."""
84
    log_level = logging.DEBUG if debug_logging else logging.WARNING
×
85
    logging.basicConfig(format="%(message)s", level=log_level)
×
86

87

88
def format_domains(domains):
4✔
89
    """Format a given list of domains."""
90
    formatted_domains = []
×
91

92
    for domain in domains:
×
93
        # Replace a single instance of http://, https://, and www. if present.
94
        formatted_domains.append(re.sub(r"^(https?://)?(www\.)?", "", domain))
×
95

96
    return formatted_domains
×
97

98

99
def debug(*args, divider=False):
4✔
100
    """Output a debugging message."""
101
    if divider:
4!
102
        logging.debug("\n-------------------------\n")
×
103

104
    if args:
4!
105
        logging.debug(*args)
4✔
106

107

108
@contextlib.contextmanager
4✔
109
def smart_open(filename=None):
4✔
110
    """Context manager that can handle writing to a file or stdout.
111

112
    Adapted from: https://stackoverflow.com/a/17603000
113
    """
114
    handle = sys.stdout if filename is None else open(filename, "w", encoding="utf-8")
4✔
115

116
    try:
4✔
117
        yield handle
4✔
118
    finally:
119
        if handle is not sys.stdout:
4✔
120
            handle.close()
4✔
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

© 2025 Coveralls, Inc