• 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.9
/apps/summarization/export_utils/processing/extractors.py
1
import re
1✔
2

3

4
def extract_attachments(text):
1✔
5
    """Extract upload links from HTML text"""
NEW
6
    if not text:
×
NEW
7
        return []
×
8

9
    # Find all links containing /uploads/ (both href and src attributes)
NEW
10
    pattern_href = r'href="([^"]*?/uploads/[^"]*?)"'
×
NEW
11
    pattern_src = r'src="([^"]*?/uploads/[^"]*?)"'
×
12

NEW
13
    attachments_href = re.findall(pattern_href, text)
×
NEW
14
    attachments_src = re.findall(pattern_src, text)
×
15

16
    # Combine and deduplicate
NEW
17
    attachments = list(dict.fromkeys(attachments_href + attachments_src))
×
18

NEW
19
    return attachments
×
20

21

22
def extract_comments(queryset, include_ratings=True, include_children=True):
1✔
23
    """
24
    Extract comments from any model with a 'comments' GenericRelation.
25
    Filters out removed, censored, or blocked comments.
26
    Recursively includes child comments.
27

28
    Args:
29
        queryset: Comment queryset (e.g., obj.comments.all())
30
        include_ratings: Whether to include ratings on comments
31
        include_children: Whether to recursively include child comments
32

33
    Returns:
34
        List of comment dictionaries with nested 'replies' key
35
    """
NEW
36
    comments_list = []
×
37

38
    # Filter out unwanted comments at the queryset level
NEW
39
    filtered_queryset = queryset.filter(
×
40
        is_removed=False, is_censored=False, is_blocked=False
41
    )
42

NEW
43
    for comment in filtered_queryset:
×
NEW
44
        comment_data = {
×
45
            "id": comment.id,
46
            "text": comment.comment,
47
            # "created": comment.created.isoformat(),
48
        }
49

50
        # Optional fields
NEW
51
        if hasattr(comment, "comment_categories") and comment.comment_categories:
×
NEW
52
            comment_data["comment_categories"] = comment.comment_categories
×
53

NEW
54
        if include_ratings and hasattr(comment, "ratings"):
×
NEW
55
            comment_data["ratings"] = [
×
56
                {
57
                    "id": rating.id,
58
                    "value": rating.value,
59
                }
60
                for rating in comment.ratings.all()
61
            ]
62

63
        # Recursively include child comments (they will also be filtered)
NEW
64
        if include_children and hasattr(comment, "child_comments"):
×
NEW
65
            child_comments = comment.child_comments.all()
×
NEW
66
            if child_comments.exists():
×
NEW
67
                comment_data["replies"] = extract_comments(
×
68
                    child_comments,
69
                    include_ratings=include_ratings,
70
                    include_children=True,
71
                )
NEW
72
                comment_data["reply_count"] = len(comment_data["replies"])
×
73

NEW
74
        comments_list.append(comment_data)
×
75

NEW
76
    return comments_list
×
77

78

79
def extract_ratings(queryset):
1✔
80
    """
81
    Extract ratings from any model with a 'ratings' GenericRelation.
82

83
    Args:
84
        queryset: Rating queryset (e.g., obj.ratings.all())
85

86
    Returns:
87
        List of rating dictionaries
88
    """
NEW
89
    ratings_list = []
×
NEW
90
    for rating in queryset:
×
NEW
91
        ratings_list.append(
×
92
            {
93
                "id": rating.id,
94
                "value": rating.value,
95
            }
96
        )
NEW
97
    return ratings_list
×
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