Commit 4ef9709

benny-dou <60535774+benny-dou@users.noreply.github.com>
2025-05-28 17:35:28
feat(danmu): convert currency to USD
1 parent ae25099
Changed files (1)
src
others
src/others/danmu.py
@@ -13,7 +13,7 @@ from loguru import logger
 from pyrogram.client import Client
 from pyrogram.types import Message
 
-from config import DANMU, PREFIX, TEXT_LENGTH, TZ, cache
+from config import DANMU, PREFIX, PROXY, TEXT_LENGTH, TOKEN, TZ, cache
 from database import create_cf_d1_table, list_cf_r2, query_cf_d1, set_cf_r2
 from messages.parser import parse_msg
 from messages.progress import modify_progress
@@ -21,6 +21,7 @@ from messages.sender import send2tg
 from messages.utils import blockquote, equal_prefix, startswith_prefix
 from networking import hx_req
 from others.emoji import CURRENCY
+from price.coinmarketcap import get_cmc_fiat
 from utils import nowdt, number
 
 HELP = f"""📖**查询弹幕记录**
@@ -124,14 +125,21 @@ async def query_danmu(client: Client, message: Message, *, show_name: bool = Tru
         await modify_progress(message=status_msg, text=caption + f"\n⏳已获取 {processed} 条弹幕", **kwargs)
 
     profit = ""
+    profit_usd = 0
     for currency, amount in sorted(super_chats.items()):
         profit += f"\n{CURRENCY.get(currency, '❔')}**{currency}**: {number(amount)}"
+        profit_usd += amount * (await to_usd(currency))
+    # if only "USD" ccy, do not include total USD
+    super_chats.pop("USD", None)  # remove "USD"
+    if profit_usd > 0 and super_chats:
+        profit += f"\n💵**总计**: {profit_usd:.2f} USD"
+
     final = f"{header}{profit}\n{blockquote(danmu)}"
     if len(final) < TEXT_LENGTH - 10:
         await modify_progress(message=status_msg, text=final, force_update=True, **kwargs)
     else:
         caption += f"\n#️⃣弹幕数: {count}"
-        caption += f"\n🎉SuperChat:{profit}" if profit else ""
+        caption += f"\n\n🎉**SuperChat**:{profit}" if profit else ""
         with BytesIO(danmu.encode("utf-8")) as f:
             await client.send_document(info["cid"], f, file_name=f"{user}{match_time}{keyword}弹幕记录.txt", caption=caption)
         await modify_progress(message=status_msg, del_status=True, **kwargs)
@@ -199,6 +207,25 @@ async def sync_danmu_to_r2() -> None:
             await batch_sync({year: [year]})
 
 
+@cache.memoize(ttl=28800)
+async def to_usd(ccy: str) -> Decimal:
+    """Convert 1 unit ccy to USD."""
+    if ccy == "USD":
+        return Decimal()
+    fiats = await get_cmc_fiat()  # {"ccy": (name, id)}
+    if ccy not in fiats:
+        return Decimal()
+
+    ccy_id = fiats[ccy][1]
+    usd_id = fiats["USD"][1]
+    url = "https://pro-api.coinmarketcap.com/v2/tools/price-conversion"
+    headers = {"Accepts": "application/json", "X-CMC_PRO_API_KEY": TOKEN.CMC_API_KEY}
+    params = {"amount": 1, "id": ccy_id, "convert_id": usd_id}
+    response = await hx_req(url, params=params, headers=headers, proxy=PROXY.CRYPTO, check_keys=["data.quote"], check_kv={"status.error_code": 0})
+    rate = glom(response, f"data.quote.{usd_id}.price", default=Decimal())
+    return Decimal(rate)
+
+
 @cache.memoize(ttl=3600)
 async def sync_danmu_to_d1() -> None:
     """Deprecated, D1 only allow 5M reads, 100K writes."""