This commit is contained in:
parent
51706d2d11
commit
853e99ca5f
21 changed files with 1402 additions and 77 deletions
|
|
@ -9,6 +9,8 @@ from calendar_feeds import CalendarFeed, CalendarFeedError, fetch_calendar_feed
|
|||
from forgejo_client import ForgejoClient, ForgejoClientError
|
||||
from settings import Settings
|
||||
|
||||
DISCUSSION_LABEL_NAME = "discussion"
|
||||
|
||||
|
||||
async def build_live_prototype_payload(
|
||||
settings: Settings,
|
||||
|
|
@ -109,7 +111,7 @@ async def build_live_prototype_payload(
|
|||
"title": "Discovery state",
|
||||
"description": (
|
||||
f"Detected {len(course_repos)} course repos, {len(post_repos)} post repos, "
|
||||
f"and {len(public_issues)} recent public issues."
|
||||
f"and {len(public_issues)} recent discussion issues."
|
||||
),
|
||||
},
|
||||
)
|
||||
|
|
@ -126,7 +128,7 @@ async def build_live_prototype_payload(
|
|||
"highlights": [
|
||||
"Repo discovery filters to public, non-fork repositories only",
|
||||
"Course repos are detected from /lessons/, post repos from /blogs/",
|
||||
"Recent discussions are loaded from live Forgejo issues",
|
||||
"Recent discussions are loaded from live Forgejo issues labeled discussion",
|
||||
],
|
||||
},
|
||||
"auth": _auth_payload(
|
||||
|
|
@ -301,6 +303,7 @@ async def _summarize_repo(
|
|||
str(repo.get("full_name", f"{owner_login}/{repo_name}")),
|
||||
str(repo.get("description") or ""),
|
||||
str(repo.get("updated_at", "")),
|
||||
_repo_owner_avatar_url(repo),
|
||||
default_branch,
|
||||
str(repo.get("html_url", "")),
|
||||
str(blog_dir.get("name", "")),
|
||||
|
|
@ -312,6 +315,7 @@ async def _summarize_repo(
|
|||
return {
|
||||
"name": repo_name,
|
||||
"owner": owner_login,
|
||||
"owner_avatar_url": _repo_owner_avatar_url(repo),
|
||||
"full_name": repo.get("full_name", f"{owner_login}/{repo_name}"),
|
||||
"html_url": repo.get("html_url", ""),
|
||||
"description": repo.get("description") or "No repository description yet.",
|
||||
|
|
@ -328,6 +332,7 @@ def _course_card(summary: dict[str, Any]) -> dict[str, object]:
|
|||
return {
|
||||
"title": summary["name"],
|
||||
"owner": summary["owner"],
|
||||
"owner_avatar_url": summary["owner_avatar_url"],
|
||||
"name": summary["name"],
|
||||
"repo": summary["full_name"],
|
||||
"html_url": summary["html_url"],
|
||||
|
|
@ -344,6 +349,7 @@ def _post_card(post: dict[str, Any]) -> dict[str, object]:
|
|||
return {
|
||||
"title": post["title"],
|
||||
"owner": post["owner"],
|
||||
"owner_avatar_url": post["owner_avatar_url"],
|
||||
"name": post["name"],
|
||||
"repo": post["repo"],
|
||||
"slug": post["slug"],
|
||||
|
|
@ -359,6 +365,14 @@ def _post_card(post: dict[str, Any]) -> dict[str, object]:
|
|||
}
|
||||
|
||||
|
||||
def issue_has_discussion_label(issue: dict[str, Any]) -> bool:
|
||||
return any(
|
||||
str(label.get("name", "")).strip().casefold() == DISCUSSION_LABEL_NAME
|
||||
for label in issue.get("labels", [])
|
||||
if isinstance(label, dict)
|
||||
)
|
||||
|
||||
|
||||
async def _recent_public_issues(
|
||||
client: ForgejoClient,
|
||||
repos: list[dict[str, Any]],
|
||||
|
|
@ -368,6 +382,7 @@ async def _recent_public_issues(
|
|||
*[_repo_issues(client, repo, limit) for repo in repos],
|
||||
)
|
||||
issues = [issue for issue_list in issue_lists for issue in issue_list]
|
||||
issues = [issue for issue in issues if issue_has_discussion_label(issue)]
|
||||
return sorted(issues, key=lambda issue: str(issue.get("updated_at", "")), reverse=True)[:limit]
|
||||
|
||||
|
||||
|
|
@ -414,6 +429,13 @@ def _repo_owner_login(repo: dict[str, Any]) -> str | None:
|
|||
return None
|
||||
|
||||
|
||||
def _repo_owner_avatar_url(repo: dict[str, Any]) -> str:
|
||||
owner = repo.get("owner", {})
|
||||
if isinstance(owner, dict) and isinstance(owner.get("avatar_url"), str):
|
||||
return owner["avatar_url"]
|
||||
return ""
|
||||
|
||||
|
||||
def _event_cards(calendar_feeds: list[CalendarFeed], limit: int) -> list[dict[str, object]]:
|
||||
upcoming_events = sorted(
|
||||
[event for feed in calendar_feeds for event in feed.events],
|
||||
|
|
@ -481,6 +503,7 @@ def discussion_card_from_issue(
|
|||
"state": issue.get("state", "open"),
|
||||
"body": body,
|
||||
"number": issue_number,
|
||||
"created_at": issue.get("created_at", ""),
|
||||
"updated_at": issue.get("updated_at", ""),
|
||||
"html_url": issue.get("html_url", ""),
|
||||
"labels": [label for label in labels if isinstance(label, str)],
|
||||
|
|
@ -687,6 +710,7 @@ async def _summarize_blog_post(
|
|||
full_name: str,
|
||||
repo_description: str,
|
||||
updated_at: str,
|
||||
owner_avatar_url: str,
|
||||
default_branch: str,
|
||||
repo_html_url: str,
|
||||
post_name: str,
|
||||
|
|
@ -708,6 +732,7 @@ async def _summarize_blog_post(
|
|||
updated_at,
|
||||
post_path,
|
||||
raw_base_url=raw_base_url,
|
||||
owner_avatar_url=owner_avatar_url,
|
||||
)
|
||||
|
||||
assets = _content_assets(post_entries, raw_base_url, post_path)
|
||||
|
|
@ -724,6 +749,7 @@ async def _summarize_blog_post(
|
|||
post_path,
|
||||
raw_base_url=raw_base_url,
|
||||
assets=assets,
|
||||
owner_avatar_url=owner_avatar_url,
|
||||
)
|
||||
|
||||
markdown_name = str(markdown_files[0]["name"])
|
||||
|
|
@ -745,6 +771,7 @@ async def _summarize_blog_post(
|
|||
html_url=str(markdown_files[0].get("html_url", "")),
|
||||
raw_base_url=raw_base_url,
|
||||
assets=assets,
|
||||
owner_avatar_url=owner_avatar_url,
|
||||
)
|
||||
|
||||
metadata, body = _parse_frontmatter(str(file_payload.get("content", "")))
|
||||
|
|
@ -752,6 +779,7 @@ async def _summarize_blog_post(
|
|||
"slug": post_name,
|
||||
"title": str(metadata.get("title") or _display_name(markdown_name) or fallback_title),
|
||||
"owner": owner,
|
||||
"owner_avatar_url": owner_avatar_url,
|
||||
"name": repo,
|
||||
"repo": full_name,
|
||||
"summary": str(metadata.get("summary") or repo_description or ""),
|
||||
|
|
@ -964,11 +992,13 @@ def _empty_blog_post(
|
|||
html_url: str = "",
|
||||
raw_base_url: str = "",
|
||||
assets: list[dict[str, object]] | None = None,
|
||||
owner_avatar_url: str = "",
|
||||
) -> dict[str, object]:
|
||||
return {
|
||||
"slug": post_name,
|
||||
"title": title,
|
||||
"owner": owner,
|
||||
"owner_avatar_url": owner_avatar_url,
|
||||
"name": repo,
|
||||
"repo": full_name,
|
||||
"summary": summary,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue