Initial sanitary RepoRadar release
This commit is contained in:
Executable
+235
@@ -0,0 +1,235 @@
|
||||
"""
|
||||
utils/embeds.py — cyberpunk / hacker-aesthetic embed builders for RepoRadar.
|
||||
|
||||
Every embed is built here so styling stays consistent: dark backdrops, neon
|
||||
accent colours, monospace code blocks, and tidy mobile + desktop formatting.
|
||||
Functions accept the normalised `Repo` dataclass from utils.git_api and return
|
||||
ready-to-send nextcord.Embed objects.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import datetime, timezone
|
||||
|
||||
import nextcord
|
||||
|
||||
from config import settings
|
||||
from utils.git_api import Repo
|
||||
from utils.helpers import discord_timestamp, truncate
|
||||
|
||||
BRAND = "RepoRadar // Project Intelligence"
|
||||
|
||||
|
||||
def _footer(embed: nextcord.Embed) -> nextcord.Embed:
|
||||
embed.set_footer(text=f"⛓ {BRAND}")
|
||||
embed.timestamp = datetime.now(timezone.utc)
|
||||
return embed
|
||||
|
||||
|
||||
# ──────────────────────────────────────────────────────────────
|
||||
# Error / utility embeds
|
||||
# ──────────────────────────────────────────────────────────────
|
||||
def build_error_embed(title: str, message: str) -> nextcord.Embed:
|
||||
embed = nextcord.Embed(
|
||||
title=f"⛔ {title}",
|
||||
description=message,
|
||||
color=settings.color_error,
|
||||
)
|
||||
return _footer(embed)
|
||||
|
||||
|
||||
def build_info_embed(title: str, message: str) -> nextcord.Embed:
|
||||
embed = nextcord.Embed(
|
||||
title=f"✅ {title}",
|
||||
description=message,
|
||||
color=settings.color_success,
|
||||
)
|
||||
return _footer(embed)
|
||||
|
||||
|
||||
# ──────────────────────────────────────────────────────────────
|
||||
# Project-drop embeds
|
||||
# ──────────────────────────────────────────────────────────────
|
||||
def _lang_emoji(language: str) -> str:
|
||||
"""A glanceable marker for the repo's primary language."""
|
||||
return {
|
||||
"python": "🐍", "go": "🐹", "rust": "🦀", "c": "🔧", "c++": "🔧",
|
||||
"java": "☕", "javascript": "🟨", "typescript": "🔷", "shell": "🐚",
|
||||
"ruby": "💎", "php": "🐘", "html": "🌐", "powershell": "💠",
|
||||
}.get((language or "").lower(), "📦")
|
||||
|
||||
|
||||
def build_repo_drop_embed(
|
||||
repo: Repo,
|
||||
*,
|
||||
votes: dict[str, int] | None = None,
|
||||
watch_label: str | None = None,
|
||||
highlight: bool = False,
|
||||
admin_note: str | None = None,
|
||||
) -> nextcord.Embed:
|
||||
"""The card posted when a brand-new project is discovered on the git server."""
|
||||
votes = votes or {"up": 0, "down": 0, "score": 0}
|
||||
title_prefix = "🌟 FEATURED DROP" if highlight else "🆕 NEW PROJECT"
|
||||
embed = nextcord.Embed(
|
||||
title=f"{_lang_emoji(repo.language)} {truncate(repo.full_name or repo.name, 240)}",
|
||||
url=repo.url or None,
|
||||
description=truncate(repo.description or "*No description provided.*", 1024),
|
||||
color=settings.color_highlight if highlight else settings.color_drop,
|
||||
)
|
||||
embed.set_author(name=f"⛓ {title_prefix}")
|
||||
|
||||
embed.add_field(name="◈ Owner", value=f"`{repo.owner or 'unknown'}`", inline=True)
|
||||
if repo.language:
|
||||
embed.add_field(name="◈ Language", value=f"`{repo.language}`", inline=True)
|
||||
embed.add_field(
|
||||
name="◈ Created",
|
||||
value=discord_timestamp(repo.created_at, "R"),
|
||||
inline=True,
|
||||
)
|
||||
embed.add_field(name="◈ ⭐ Stars", value=f"`{repo.stars}`", inline=True)
|
||||
embed.add_field(name="◈ 🍴 Forks", value=f"`{repo.forks}`", inline=True)
|
||||
embed.add_field(
|
||||
name="◈ 🗳 Community",
|
||||
value=f"👍 `{votes['up']}` 👎 `{votes['down']}` • net `{votes['score']:+d}`",
|
||||
inline=True,
|
||||
)
|
||||
|
||||
if repo.topics:
|
||||
embed.add_field(
|
||||
name="◈ Topics",
|
||||
value=" ".join(f"`{t}`" for t in repo.topics[:10]),
|
||||
inline=False,
|
||||
)
|
||||
|
||||
if admin_note:
|
||||
embed.add_field(name="◈ Curator Note", value=truncate(admin_note, 1024), inline=False)
|
||||
|
||||
if watch_label:
|
||||
embed.add_field(name="◈ Source", value=watch_label, inline=False)
|
||||
|
||||
if repo.url:
|
||||
embed.add_field(name="◈ Repository", value=f"[🔗 Open project]({repo.url})", inline=False)
|
||||
|
||||
return _footer(embed)
|
||||
|
||||
|
||||
def build_repo_list_embed(
|
||||
repos: list[Repo],
|
||||
*,
|
||||
title: str = "🛰 LATEST PROJECTS",
|
||||
limit: int = 10,
|
||||
) -> nextcord.Embed:
|
||||
"""Compact chronological list of the newest repositories (newest first)."""
|
||||
embed = nextcord.Embed(
|
||||
title=f"☣ {title}",
|
||||
description=(
|
||||
"```ansi\n\u001b[1;35m> Freshest projects from the git server\u001b[0m\n```"
|
||||
f"Showing the **{min(limit, len(repos))}** most recent."
|
||||
),
|
||||
color=settings.color_drop,
|
||||
)
|
||||
for repo in repos[:limit]:
|
||||
created = discord_timestamp(repo.created_at, "R")
|
||||
meta = f"⭐ {repo.stars} · 🍴 {repo.forks}"
|
||||
if repo.language:
|
||||
meta = f"`{repo.language}` · " + meta
|
||||
desc = truncate(repo.description or "*No description.*", 130)
|
||||
link = f"[open]({repo.url})" if repo.url else ""
|
||||
embed.add_field(
|
||||
name=f"{_lang_emoji(repo.language)} {truncate(repo.full_name or repo.name, 60)}",
|
||||
value=f"{desc}\n{meta} · {created} · {link}",
|
||||
inline=False,
|
||||
)
|
||||
if not repos:
|
||||
embed.description = "No projects could be retrieved right now."
|
||||
return _footer(embed)
|
||||
|
||||
|
||||
def build_git_leaderboard_embed(rows: list[dict], *, limit: int = 10) -> nextcord.Embed:
|
||||
"""Top community-voted projects."""
|
||||
embed = nextcord.Embed(
|
||||
title="🏆 COMMUNITY TOP PROJECTS",
|
||||
description="```ansi\n\u001b[1;32m> Ranked by community vote score\u001b[0m\n```",
|
||||
color=settings.color_success,
|
||||
)
|
||||
medals = {0: "🥇", 1: "🥈", 2: "🥉"}
|
||||
for i, row in enumerate(rows[:limit]):
|
||||
name = row.get("full_name") or row.get("repo_key", "unknown")
|
||||
url = row.get("url") or ""
|
||||
score = int(row.get("score") or 0)
|
||||
up = int(row.get("up") or 0)
|
||||
down = int(row.get("down") or 0)
|
||||
marker = medals.get(i, f"`#{i + 1}`")
|
||||
link = f"[open]({url})" if url else ""
|
||||
embed.add_field(
|
||||
name=f"{marker} {truncate(name, 60)}",
|
||||
value=f"net `{score:+d}` • 👍 `{up}` 👎 `{down}` {link}",
|
||||
inline=False,
|
||||
)
|
||||
if not rows:
|
||||
embed.description = "No votes have been cast yet. Be the first to vote on a drop!"
|
||||
return _footer(embed)
|
||||
|
||||
|
||||
def build_git_status_embed(
|
||||
*,
|
||||
provider: str,
|
||||
base_url: str,
|
||||
configured: bool,
|
||||
drop_channel_id: int | None,
|
||||
highlight_channel_id: int | None,
|
||||
highlight_role_id: int | None,
|
||||
min_stars: int,
|
||||
keywords: str,
|
||||
enabled: bool,
|
||||
watches: list[dict],
|
||||
poll_interval: int,
|
||||
) -> nextcord.Embed:
|
||||
"""Render the current monitor configuration for a guild."""
|
||||
embed = nextcord.Embed(
|
||||
title="⚙ REPORADAR — CONFIGURATION",
|
||||
color=settings.color_drop if configured else settings.color_medium,
|
||||
)
|
||||
status = "🟢 enabled" if enabled else "🔴 disabled"
|
||||
embed.add_field(name="◈ Provider", value=f"`{provider or 'unconfigured'}`", inline=True)
|
||||
embed.add_field(name="◈ Server", value=f"`{base_url or 'api.github.com'}`", inline=True)
|
||||
embed.add_field(name="◈ Monitor", value=status, inline=True)
|
||||
|
||||
embed.add_field(
|
||||
name="◈ Drop channel",
|
||||
value=f"<#{drop_channel_id}>" if drop_channel_id else "`not set`",
|
||||
inline=True,
|
||||
)
|
||||
embed.add_field(
|
||||
name="◈ Highlight channel",
|
||||
value=f"<#{highlight_channel_id}>" if highlight_channel_id else "`not set`",
|
||||
inline=True,
|
||||
)
|
||||
embed.add_field(
|
||||
name="◈ Highlight role",
|
||||
value=f"<@&{highlight_role_id}>" if highlight_role_id else "`none`",
|
||||
inline=True,
|
||||
)
|
||||
embed.add_field(name="◈ Min ⭐ to highlight", value=f"`{min_stars}`", inline=True)
|
||||
embed.add_field(name="◈ Poll interval", value=f"`{poll_interval}s`", inline=True)
|
||||
embed.add_field(
|
||||
name="◈ Highlight keywords",
|
||||
value=f"`{keywords}`" if keywords else "`none`",
|
||||
inline=False,
|
||||
)
|
||||
|
||||
if watches:
|
||||
lines = []
|
||||
for w in watches:
|
||||
scope = w["scope_type"]
|
||||
val = w["scope_value"] or "*entire server*"
|
||||
ch = f" → <#{w['channel_id']}>" if w.get("channel_id") else ""
|
||||
lines.append(f"• `{scope}` **{val}**{ch}")
|
||||
embed.add_field(name="◈ Active watches", value=truncate("\n".join(lines), 1024), inline=False)
|
||||
else:
|
||||
embed.add_field(
|
||||
name="◈ Active watches",
|
||||
value="None yet — add one with `/radar_watch`.",
|
||||
inline=False,
|
||||
)
|
||||
return _footer(embed)
|
||||
Reference in New Issue
Block a user