auto: 일일 백업 2026-10-08 02:00
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -7318,6 +7318,18 @@ table.adr-info-table td.adr-breakdown { font-size: 11px; color: #8b8f9a; white-s
|
||||
.ipo-done { font-size: 12px; color: #8b8f9a; }
|
||||
.ipo-done.mine { color: #7ee2a8; font-weight: 600; }
|
||||
.ipo-stock.done .ipo-kv { margin-top: 2px; }
|
||||
.ipo-yt { margin: 2px 0 8px; padding: 8px 10px; border-radius: 8px; background: #10131b; border-left: 3px solid #8b8f9a; font-size: 12px; }
|
||||
.ipo-yt.positive { border-left-color: #7ee2a8; }
|
||||
.ipo-yt.negative { border-left-color: #ff8a96; }
|
||||
.ipo-stock.done .ipo-yt { margin-top: 8px; }
|
||||
.ipo-yt-head { font-weight: 600; color: #cfd6e6; margin-bottom: 4px; }
|
||||
.ipo-yt-v { margin-left: 4px; color: #e6e8ec; }
|
||||
.ipo-yt.positive .ipo-yt-v { color: #7ee2a8; }
|
||||
.ipo-yt.negative .ipo-yt-v { color: #ff8a96; }
|
||||
.ipo-yt-pts { margin: 0 0 6px; padding-left: 16px; color: #d6d8dd; line-height: 1.5; }
|
||||
.ipo-yt-pts li { overflow-wrap: anywhere; }
|
||||
.ipo-yt-link, .ipo-yt-more { display: inline-block; margin-right: 10px; color: #8ab4ff; text-decoration: none; font-size: 11px; }
|
||||
.ipo-yt-more { color: #8b8f9a; }
|
||||
/* 자산정보 탭 내부 sub-tab — 자산보기/차트보기. 상단 배치는 밑줄 강조, 하단 배치는 일반 버튼 형태. */
|
||||
.sub-tabs { display: flex; gap: 4px; margin: 8px 14px 0; border-bottom: 1px solid #1f2330; }
|
||||
.sub-tab { appearance: none; background: transparent; color: #8b8f9a; border: 0; border-bottom: 2px solid transparent; padding: 8px 14px; font-size: 13px; cursor: pointer; font-family: inherit; font-weight: 500; }
|
||||
@@ -8455,6 +8467,28 @@ def _ipo_flag() -> tuple[list[str], str]:
|
||||
return (['청약'] if parts else []), ' · '.join(parts)
|
||||
|
||||
|
||||
def _ipo_yt_html(entries: list[dict] | None) -> str:
|
||||
"""비하이브 '공모청약' 영상 요약 블록(ipo_youtube_digest 가 미리 저장, 렌더는 파일 읽기만).
|
||||
전용 영상(제목 #종목명) 우선·최신 1건만 본문으로, 나머지는 링크만."""
|
||||
if not entries:
|
||||
return ''
|
||||
esc = html.escape
|
||||
e = entries[0]
|
||||
pts = ''.join(f'<li>{esc(p)}</li>' for p in e.get('points') or [])
|
||||
more = ''.join(
|
||||
f'<a class="ipo-yt-more" href="{esc(x["url"])}" target="_blank" rel="noopener">▶ {esc(x["title"].replace("[🐝 공모청약]", "").strip()[:28])}</a>'
|
||||
for x in entries[1:]
|
||||
)
|
||||
return (
|
||||
f'<div class="ipo-yt {esc(e.get("verdict") or "neutral")}">'
|
||||
f'<div class="ipo-yt-head">🐝 비하이브 의견 <span class="ipo-yt-v">{esc(e.get("verdict_text") or "")}</span>'
|
||||
f'<span class="ipo-sub"> {esc(_ipo_md((e.get("published_kst") or "")[:10]))}</span></div>'
|
||||
f'<ul class="ipo-yt-pts">{pts}</ul>'
|
||||
f'<a class="ipo-yt-link" href="{esc(e["url"])}" target="_blank" rel="noopener">▶ 영상 보기</a>{more}'
|
||||
'</div>'
|
||||
)
|
||||
|
||||
|
||||
def _render_ipo_panel() -> str:
|
||||
"""자산정보 > 공모주 sub-tab. ① 오늘청약(청약기간 중 종목 × 증권사) ② 청약완료(상장일까지).
|
||||
네이버 IPO API(30분 캐시) + 청약기간 중·완료 종목만 상세 API. 키움 콜 0."""
|
||||
@@ -8465,6 +8499,12 @@ def _render_ipo_panel() -> str:
|
||||
subscribed = _load_ipo_subscribed()
|
||||
if rows is None:
|
||||
return '<div class="market-card market-card-error">공모주 정보를 불러올 수 없습니다.</div>'
|
||||
try:
|
||||
from ipo_youtube_digest import summaries_by_code
|
||||
yt = summaries_by_code()
|
||||
except Exception as e:
|
||||
sys.stderr.write(f'ipo youtube summaries failed: {type(e).__name__}: {e}\n')
|
||||
yt = {}
|
||||
by_code = {(r.get('ipoCode') or r.get('itemCode') or '').strip(): r for r in rows}
|
||||
|
||||
# ① 오늘청약 — 청약기간 중인 종목 전부(1일차·2일차 모두)
|
||||
@@ -8487,7 +8527,7 @@ def _render_ipo_panel() -> str:
|
||||
f'<details class="ipo-stock" data-ipo-key="t:{esc(code)}"><summary class="ipo-stock-name">'
|
||||
f'<span class="ipo-sum-main">{esc(name)}<span class="ipo-sub"> {esc(r.get("marketType") or "")}'
|
||||
f' · {esc(_ipo_period(r.get("poStartDate") or "", r.get("poEndDate") or ""))} · {len(blocks)}곳</span></span>'
|
||||
f'<span class="ipo-sum-tags">{tags}</span></summary>{items}</details>'
|
||||
f'<span class="ipo-sum-tags">{tags}</span></summary>{_ipo_yt_html(yt.get(code))}{items}</details>'
|
||||
)
|
||||
today_html = ''.join(today_parts) or '<div class="ipo-empty">오늘 청약 중인 공모주가 없습니다.</div>'
|
||||
|
||||
@@ -8518,7 +8558,7 @@ def _render_ipo_panel() -> str:
|
||||
f'<dt>청약일</dt><dd>{esc(_ipo_period(r.get("poStartDate") or "", r.get("poEndDate") or ""))}</dd>'
|
||||
f'<dt>환불일</dt><dd>{esc(_ipo_md(r.get("refundDate") or "") or "미정")}</dd>'
|
||||
f'<dt>상장일</dt><dd>{esc(_ipo_md(lcal) or "미정")}</dd>'
|
||||
'</dl></details>'
|
||||
f'</dl>{_ipo_yt_html(yt.get(code))}</details>'
|
||||
)
|
||||
done_html = ''.join(done_parts) or '<div class="ipo-empty">청약완료한 종목이 없습니다.</div>'
|
||||
|
||||
|
||||
Reference in New Issue
Block a user