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

liqd / adhocracy-plus / 29025448509

09 Jul 2026 02:27PM UTC coverage: 64.997% (-16.4%) from 81.351%
29025448509

Pull #3140

github

web-flow
Merge 53c04aee4 into 01f7616a8
Pull Request #3140: Update dependency css-loader to v7.1.4

6722 of 10342 relevant lines covered (65.0%)

0.65 hits per line

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

5.97
/apps/summarization/export_utils/processing/cleaning.py
1
def clean_dict(data):
1✔
2
    """Remove empty/null values from a dictionary recursively."""
3
    if not isinstance(data, dict):
×
4
        return data
×
5

6
    cleaned = {}
×
7
    for key, value in data.items():
×
8
        # Skip None values
9
        if value is None:
×
10
            continue
×
11

12
        # Skip empty lists
13
        if isinstance(value, list) and len(value) == 0:
×
14
            continue
×
15

16
        # Skip empty strings
17
        if isinstance(value, str) and value == "":
×
18
            continue
×
19

20
        # Recursively clean nested dicts
21
        if isinstance(value, dict):
×
22
            cleaned_value = clean_dict(value)
×
23
            if cleaned_value:  # Only include non-empty dicts
×
24
                cleaned[key] = cleaned_value
×
25
        else:
26
            cleaned[key] = value
×
27

28
    return cleaned
×
29

30

31
def clean_comment(comment):
1✔
32
    """Clean a comment by removing redundant fields."""
33
    cleaned = {
×
34
        "id": comment["id"],
35
        "text": comment["text"],
36
    }
37

38
    # Only include replies if they exist
39
    if comment.get("replies"):
×
40
        cleaned["replies"] = [clean_comment(r) for r in comment["replies"]]
×
41
        cleaned["reply_count"] = len(cleaned["replies"])
×
42

43
    # Only include ratings if they exist
44
    if comment.get("ratings"):
×
45
        cleaned["ratings"] = comment["ratings"]
×
46

47
    return cleaned
×
48

49

50
def clean_content_item(item):  # noqa: C901
1✔
51
    """Clean a content item (idea, poll, etc.) by removing empty fields."""
52
    cleaned = {}
×
53

54
    # Always include essential fields
55
    for field in ["id", "name", "description", "created", "reference_number"]:
×
56
        if field in item:
×
57
            cleaned[field] = item[field]
×
58

59
    # Optional fields only if they have values
60
    if item.get("category"):
×
61
        cleaned["category"] = item["category"]
×
62

63
    if item.get("labels"):
×
64
        cleaned["labels"] = item["labels"]
×
65

66
    if item.get("attachments"):
×
67
        cleaned["attachments"] = item["attachments"]
×
68

69
    if item.get("images") and item["images"] != [""]:
×
70
        cleaned["images"] = item["images"]
×
71

72
    # Clean comments
73
    if item.get("comments"):
×
74
        cleaned["comments"] = [clean_comment(c) for c in item["comments"]]
×
75

76
    # Clean ratings
77
    if item.get("ratings"):
×
78
        cleaned["ratings"] = item["ratings"]
×
79

80
    # Poll-specific fields
81
    if item.get("choices"):
×
82
        cleaned["choices"] = item["choices"]
×
83
    if item.get("answers"):
×
84
        cleaned["answers"] = item["answers"]
×
85
    if item.get("other_answers"):
×
86
        cleaned["other_answers"] = item["other_answers"]
×
87

88
    # Map-specific fields
89
    if item.get("point") and (item["point"].get("lat") or item["point"].get("lng")):
×
90
        cleaned["point"] = item["point"]
×
91
    if item.get("point_label"):
×
92
        cleaned["point_label"] = item["point_label"]
×
93

94
    return cleaned
×
95

96

97
def clean_export(export_data):
1✔
98
    """Clean the entire export by removing empty/null values."""
99
    cleaned = {
×
100
        "project": clean_dict(export_data["project"]),  # Keep this for project
101
        "phases": {},
102
        "offline_events": export_data.get("offline_events", []),
103
    }
104

105
    # Clean each phase
106
    for phase_name, phase_data in export_data["phases"].items():
×
107
        cleaned_phase = {"phase_status": phase_data["phase_status"], "modules": []}
×
108

109
        for module in phase_data["modules"]:
×
110
            cleaned_module = {
×
111
                "module_id": module["module_id"],
112
                "module_name": module["module_name"],
113
                "module_type": module["module_type"],
114
                "module_start": module["module_start"],
115
                "module_end": module["module_end"],
116
                "url": module["url"],
117
                "content": {},
118
            }
119

120
            # Only include description if it exists
121
            if module.get("description"):
×
122
                cleaned_module["description"] = module["description"]
×
123

124
            # Clean each content type
125
            for content_type, items in module["content"].items():
×
126
                if items:
×
127
                    cleaned_module["content"][content_type] = [
×
128
                        clean_content_item(item) for item in items
129
                    ]
130

131
            cleaned_phase["modules"].append(cleaned_module)  # Remove clean_dict
×
132

133
        cleaned["phases"][phase_name] = cleaned_phase
×
134

135
    return cleaned  # Remove final clean_dict
×
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