Skip to content

Commit a4e58e6

Browse files
Reorder mentions.py for better code organization
1 parent cde6827 commit a4e58e6

File tree

1 file changed

+102
-110
lines changed

1 file changed

+102
-110
lines changed

src/django_github_app/mentions.py

Lines changed: 102 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -76,116 +76,6 @@ class Mention:
7676
next_mention: Mention | None = None
7777

7878

79-
@dataclass
80-
class Comment:
81-
body: str
82-
author: str
83-
created_at: datetime
84-
url: str
85-
mentions: list[Mention]
86-
87-
@property
88-
def line_count(self) -> int:
89-
"""Number of lines in the comment."""
90-
if not self.body:
91-
return 0
92-
return len(self.body.splitlines())
93-
94-
@classmethod
95-
def from_event(cls, event: sansio.Event) -> Comment:
96-
match event.event:
97-
case "issue_comment" | "pull_request_review_comment" | "commit_comment":
98-
comment_data = event.data.get("comment")
99-
case "pull_request_review":
100-
comment_data = event.data.get("review")
101-
case _:
102-
comment_data = None
103-
104-
if not comment_data:
105-
raise ValueError(f"Cannot extract comment from event type: {event.event}")
106-
107-
created_at_str = comment_data.get("created_at", "")
108-
if created_at_str:
109-
# GitHub timestamps are in ISO format: 2024-01-01T12:00:00Z
110-
created_at_aware = datetime.fromisoformat(
111-
created_at_str.replace("Z", "+00:00")
112-
)
113-
if settings.USE_TZ:
114-
created_at = created_at_aware
115-
else:
116-
created_at = timezone.make_naive(
117-
created_at_aware, timezone.get_default_timezone()
118-
)
119-
else:
120-
created_at = timezone.now()
121-
122-
author = comment_data.get("user", {}).get("login", "")
123-
if not author and "sender" in event.data:
124-
author = event.data.get("sender", {}).get("login", "")
125-
126-
return cls(
127-
body=comment_data.get("body", ""),
128-
author=author,
129-
created_at=created_at,
130-
url=comment_data.get("html_url", ""),
131-
mentions=[],
132-
)
133-
134-
135-
@dataclass
136-
class MentionEvent:
137-
comment: Comment
138-
triggered_by: Mention
139-
scope: MentionScope | None
140-
141-
@classmethod
142-
def from_event(
143-
cls,
144-
event: sansio.Event,
145-
*,
146-
username: str | re.Pattern[str] | None = None,
147-
pattern: str | re.Pattern[str] | None = None,
148-
scope: MentionScope | None = None,
149-
):
150-
"""Generate MentionEvent instances from a GitHub event.
151-
152-
Yields MentionEvent for each mention that matches the given criteria.
153-
"""
154-
# Check scope match first
155-
event_scope = MentionScope.from_event(event)
156-
if scope is not None and event_scope != scope:
157-
return
158-
159-
# Parse mentions
160-
mentions = parse_mentions_for_username(event, username)
161-
if not mentions:
162-
return
163-
164-
# Create comment
165-
comment = Comment.from_event(event)
166-
comment.mentions = mentions
167-
168-
# Yield contexts for matching mentions
169-
for mention in mentions:
170-
# Check pattern match if specified
171-
if pattern is not None:
172-
match = check_pattern_match(mention.text, pattern)
173-
if not match:
174-
continue
175-
mention.match = match
176-
177-
yield cls(
178-
comment=comment,
179-
triggered_by=mention,
180-
scope=event_scope,
181-
)
182-
183-
184-
CODE_BLOCK_PATTERN = re.compile(r"```[\s\S]*?```", re.MULTILINE)
185-
INLINE_CODE_PATTERN = re.compile(r"`[^`]+`")
186-
QUOTE_PATTERN = re.compile(r"^\s*>.*$", re.MULTILINE)
187-
188-
18979
def check_pattern_match(
19080
text: str, pattern: str | re.Pattern[str] | None
19181
) -> re.Match[str] | None:
@@ -208,6 +98,11 @@ def check_pattern_match(
20898
return re.match(escaped_pattern, text, re.IGNORECASE)
20999

210100

101+
CODE_BLOCK_PATTERN = re.compile(r"```[\s\S]*?```", re.MULTILINE)
102+
INLINE_CODE_PATTERN = re.compile(r"`[^`]+`")
103+
QUOTE_PATTERN = re.compile(r"^\s*>.*$", re.MULTILINE)
104+
105+
211106
def parse_mentions_for_username(
212107
event: sansio.Event, username_pattern: str | re.Pattern[str] | None = None
213108
) -> list[Mention]:
@@ -299,3 +194,100 @@ def parse_mentions_for_username(
299194
mention.next_mention = mentions[i + 1]
300195

301196
return mentions
197+
198+
199+
@dataclass
200+
class Comment:
201+
body: str
202+
author: str
203+
created_at: datetime
204+
url: str
205+
mentions: list[Mention]
206+
207+
@property
208+
def line_count(self) -> int:
209+
"""Number of lines in the comment."""
210+
if not self.body:
211+
return 0
212+
return len(self.body.splitlines())
213+
214+
@classmethod
215+
def from_event(cls, event: sansio.Event) -> Comment:
216+
match event.event:
217+
case "issue_comment" | "pull_request_review_comment" | "commit_comment":
218+
comment_data = event.data.get("comment")
219+
case "pull_request_review":
220+
comment_data = event.data.get("review")
221+
case _:
222+
comment_data = None
223+
224+
if not comment_data:
225+
raise ValueError(f"Cannot extract comment from event type: {event.event}")
226+
227+
created_at_str = comment_data.get("created_at", "")
228+
if created_at_str:
229+
# GitHub timestamps are in ISO format: 2024-01-01T12:00:00Z
230+
created_at_aware = datetime.fromisoformat(
231+
created_at_str.replace("Z", "+00:00")
232+
)
233+
if settings.USE_TZ:
234+
created_at = created_at_aware
235+
else:
236+
created_at = timezone.make_naive(
237+
created_at_aware, timezone.get_default_timezone()
238+
)
239+
else:
240+
created_at = timezone.now()
241+
242+
author = comment_data.get("user", {}).get("login", "")
243+
if not author and "sender" in event.data:
244+
author = event.data.get("sender", {}).get("login", "")
245+
246+
return cls(
247+
body=comment_data.get("body", ""),
248+
author=author,
249+
created_at=created_at,
250+
url=comment_data.get("html_url", ""),
251+
mentions=[],
252+
)
253+
254+
255+
@dataclass
256+
class MentionEvent:
257+
comment: Comment
258+
triggered_by: Mention
259+
scope: MentionScope | None
260+
261+
@classmethod
262+
def from_event(
263+
cls,
264+
event: sansio.Event,
265+
*,
266+
username: str | re.Pattern[str] | None = None,
267+
pattern: str | re.Pattern[str] | None = None,
268+
scope: MentionScope | None = None,
269+
):
270+
event_scope = MentionScope.from_event(event)
271+
if scope is not None and event_scope != scope:
272+
return
273+
274+
mentions = parse_mentions_for_username(event, username)
275+
if not mentions:
276+
return
277+
278+
comment = Comment.from_event(event)
279+
comment.mentions = mentions
280+
281+
for mention in mentions:
282+
if pattern is not None:
283+
match = check_pattern_match(mention.text, pattern)
284+
if not match:
285+
continue
286+
mention.match = match
287+
288+
yield cls(
289+
comment=comment,
290+
triggered_by=mention,
291+
scope=event_scope,
292+
)
293+

0 commit comments

Comments
 (0)