from datetime import datetime, timedelta, timezone
from math import ceil
from pathlib import Path
-from typing import Any
+from typing import Annotated, Any
import httpx
import yaml
from github import Github
-from pydantic import BaseModel, SecretStr
+from pydantic import BaseModel, BeforeValidator, SecretStr
from pydantic_settings import BaseSettings
github_graphql_url = "https://api.github.com/graphql"
POINTS_PER_MINUTE_LIMIT = 84 # 5000 points per hour
+MINIMIZED_COMMENTS_REASONS_TO_EXCLUDE = {"abuse", "off-topic", "duplicate", "spam"}
+
class RateLimiter:
def __init__(self) -> None:
avatarUrl
url
}
+ minimizedReason
}
}
+ minimizedReason
}
}
}
}
"""
+LowerStr = Annotated[
+ str, BeforeValidator(lambda v: v.lower() if isinstance(v, str) else v)
+]
+
class Author(BaseModel):
login: str
class CommentsNode(BaseModel):
createdAt: datetime
author: Author | None = None
+ minimizedReason: LowerStr | None = None
class Replies(BaseModel):
class DiscussionsCommentsNode(CommentsNode):
+ minimizedReason: LowerStr | None = None
replies: Replies
discussion_author_name = discussion.author.login
discussion_commentors: dict[str, datetime] = {}
for comment in discussion.comments.nodes:
- if comment.author:
+ if (
+ comment.minimizedReason not in MINIMIZED_COMMENTS_REASONS_TO_EXCLUDE
+ and comment.author
+ ):
authors[comment.author.login] = comment.author
if comment.author.login != discussion_author_name:
author_time = discussion_commentors.get(
author_time, comment.createdAt
)
for reply in comment.replies.nodes:
- if reply.author:
+ if (
+ reply.minimizedReason not in MINIMIZED_COMMENTS_REASONS_TO_EXCLUDE
+ and reply.author
+ ):
authors[reply.author.login] = reply.author
if reply.author.login != discussion_author_name:
author_time = discussion_commentors.get(