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

liqd / roots / 22995037636

12 Mar 2026 09:24AM UTC coverage: 81.129% (-0.4%) from 81.522%
22995037636

push

github

web-flow
apps/summarization: refactor export (#88)

74 of 360 new or added lines in 16 files covered. (20.56%)

7386 of 9104 relevant lines covered (81.13%)

0.81 hits per line

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

12.79
/apps/summarization/export_utils/processing/grouping.py
1
from .module_utils import get_module_type_from_name
1✔
2

3

4
def create_module_base(item):
1✔
5
    """Create base module structure"""
NEW
6
    return {
×
7
        "module_id": item["module_id"],
8
        "module_name": item["module_name"],
9
        "module_type": get_module_type_from_name(item["module_name"]),
10
        "phase_status": item["active_status"],
11
        "module_order": 0,
12
        "link": None,
13
        "signals": {
14
            "has_comments": False,
15
            "has_votes": False,
16
            "has_ratings": False,
17
            "has_open_answers": False,
18
            "has_base_text": False,
19
        },
20
        "counts": {
21
            "ideas": 0,
22
            "comments": 0,
23
            "votes": 0,
24
            "ratings": 0,
25
            "open_answers": 0,
26
        },
27
        "content": {},
28
        "meta": {
29
            "module_start": item["module_start"],
30
            "module_end": item["module_end"],
31
        },
32
    }
33

34

35
def group_by_module(export_data):
1✔
36
    """Group all items by module and organize them into past/current/upcoming sections."""
NEW
37
    modules_by_id = {}
×
38

39
    # Define item type handlers
NEW
40
    handlers = {
×
41
        "ideas": process_ideas,
42
        "mapideas": process_mapideas,
43
        "polls": process_polls,
44
        "proposals": process_proposals,
45
        "topics": process_topics,
46
        "debates": process_debates,
47
        "documents": process_documents,
48
    }
49

50
    # Collect all items by module
NEW
51
    for item_type, items in [
×
52
        ("ideas", export_data.get("ideas", [])),
53
        ("mapideas", export_data.get("mapideas", [])),
54
        ("polls", export_data.get("polls", [])),
55
        ("topics", export_data.get("topics", [])),
56
        ("proposals", export_data.get("proposals", [])),
57
        ("debates", export_data.get("debates", [])),
58
        ("documents", export_data.get("documents", [])),
59
    ]:
NEW
60
        handler = handlers.get(item_type)
×
NEW
61
        if not handler:
×
NEW
62
            continue
×
63

NEW
64
        for item in items:
×
NEW
65
            module_id = item["module_id"]
×
NEW
66
            if module_id not in modules_by_id:
×
NEW
67
                modules_by_id[module_id] = create_module_base(item)
×
68

NEW
69
            handler(modules_by_id[module_id], item)
×
70

71
    # Organize by status
NEW
72
    result = {
×
73
        "project": export_data["project"],
74
        "phases": {
75
            "past": {"phase_status": "past", "modules": []},
76
            "current": {"phase_status": "current", "modules": []},
77
            "upcoming": {"phase_status": "upcoming", "modules": []},
78
        },
79
    }
80

81
    # Group modules by status
NEW
82
    status_map = {"past": "past", "active": "current", "future": "upcoming"}
×
NEW
83
    for module in modules_by_id.values():
×
NEW
84
        phase = status_map.get(module["phase_status"])
×
NEW
85
        if phase:
×
NEW
86
            result["phases"][phase]["modules"].append(module)
×
87
        else:
NEW
88
            print(
×
89
                f"WARNING: Unknown phase_status '{module['phase_status']}' for module {module['module_name']}"
90
            )
91

NEW
92
    return result
×
93

94

95
def restructure_by_phase(export_data):
1✔
96
    """Restructure modules array into phases object with past/current/upcoming."""
NEW
97
    phases = {
×
98
        "past": {"phase_status": "past", "modules": []},
99
        "current": {"phase_status": "current", "modules": []},
100
        "upcoming": {"phase_status": "upcoming", "modules": []},
101
    }
102

NEW
103
    status_map = {"past": "past", "active": "current", "future": "upcoming"}
×
104

NEW
105
    for module in export_data.get("modules", []):
×
NEW
106
        phase = status_map.get(module["active_status"])
×
NEW
107
        if phase:
×
108
            # Remove active_status from module since it's now at phase level
NEW
109
            module_copy = module.copy()
×
NEW
110
            module_copy.pop("active_status", None)
×
NEW
111
            phases[phase]["modules"].append(module_copy)
×
112

NEW
113
    return {
×
114
        "project": export_data["project"],
115
        "phases": phases,
116
        "offline_events": export_data.get("offline_events", []),
117
    }
118

119

120
def process_ideas(module, item):
1✔
121
    """Process an idea item"""
NEW
122
    module["counts"]["ideas"] += 1
×
NEW
123
    module["counts"]["comments"] += item["comment_count"]
×
NEW
124
    module["counts"]["ratings"] += item["rating_count"]
×
NEW
125
    if item["comment_count"]:
×
NEW
126
        module["signals"]["has_comments"] = True
×
NEW
127
    if item["rating_count"]:
×
NEW
128
        module["signals"]["has_ratings"] = True
×
NEW
129
    module["content"].setdefault("ideas", []).append(item)
×
130

131

132
def process_mapideas(module, item):
1✔
133
    """Process a map idea item (same as regular ideas)"""
NEW
134
    module["counts"]["ideas"] += 1
×
NEW
135
    module["counts"]["comments"] += item["comment_count"]
×
NEW
136
    module["counts"]["ratings"] += item["rating_count"]
×
NEW
137
    if item["comment_count"]:
×
NEW
138
        module["signals"]["has_comments"] = True
×
NEW
139
    if item["rating_count"]:
×
NEW
140
        module["signals"]["has_ratings"] = True
×
NEW
141
    module["content"].setdefault("mapideas", []).append(item)
×
142

143

144
def process_polls(module, item):
1✔
145
    """Process a poll item"""
NEW
146
    module["counts"]["votes"] += item["total_votes"]
×
NEW
147
    module["counts"]["comments"] += item["comment_count"]
×
NEW
148
    if item["comment_count"]:
×
NEW
149
        module["signals"]["has_comments"] = True
×
NEW
150
    if item["total_votes"]:
×
NEW
151
        module["signals"]["has_votes"] = True
×
NEW
152
    module["content"].setdefault("questions", []).extend(item["questions"])
×
NEW
153
    module["content"]["description"] = item.get("description", "")
×
NEW
154
    module["content"]["comments"] = item.get("comments", [])
×
155

156

157
def process_topics(module, item):
1✔
158
    """Process a topic item"""
NEW
159
    module["counts"]["comments"] += item["comment_count"]
×
NEW
160
    module["counts"]["ratings"] += item["rating_count"]
×
NEW
161
    if item["comment_count"]:
×
NEW
162
        module["signals"]["has_comments"] = True
×
NEW
163
    if item["rating_count"]:
×
NEW
164
        module["signals"]["has_ratings"] = True
×
NEW
165
    module["content"].setdefault("topics", []).append(item)
×
166

167

168
def process_proposals(module, item):
1✔
169
    """Process a proposal item (similar to ideas but with budget)."""
NEW
170
    module["counts"]["ideas"] += 1
×
NEW
171
    module["counts"]["comments"] += item["comment_count"]
×
NEW
172
    module["counts"]["ratings"] += item["rating_count"]
×
NEW
173
    if item["comment_count"]:
×
NEW
174
        module["signals"]["has_comments"] = True
×
NEW
175
    if item["rating_count"]:
×
NEW
176
        module["signals"]["has_ratings"] = True
×
NEW
177
    module["content"].setdefault("proposals", []).append(item)
×
178

179

180
def process_debates(module, item):
1✔
181
    """Process a debate item"""
NEW
182
    module["counts"]["comments"] += item["comment_count"]
×
NEW
183
    if item["comment_count"]:
×
NEW
184
        module["signals"]["has_comments"] = True
×
NEW
185
    module["content"].setdefault("debates", []).append(item)
×
186

187

188
def process_documents(module, item):
1✔
189
    """Process a document chapter"""
NEW
190
    if item not in module["content"].get("chapters", []):
×
NEW
191
        module["content"].setdefault("chapters", []).append(item)
×
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