""" 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)