auto: 일일 백업 2026-10-08 02:00
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -3,6 +3,7 @@ from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import subprocess
|
||||
import sys
|
||||
from datetime import date, datetime
|
||||
from decimal import Decimal, ROUND_HALF_UP
|
||||
@@ -140,6 +141,53 @@ def format_alert(kind: str, row: dict, detail: dict) -> str:
|
||||
return '\n\n'.join(sections)
|
||||
|
||||
|
||||
GAHEE_CRED = Path('/Users/snowoyh/.openclaw/credentials/gahee_imessage.json')
|
||||
IPO_SUBSCRIBED = Path('/Users/snowoyh/.openclaw/agents/stock/workspace/state/behive_ipo_subscribed.json')
|
||||
|
||||
|
||||
def gahee_listing_message(target: date, rows: list[tuple[dict, dict]] | None) -> tuple[list[str], str]:
|
||||
"""가희가 청약한 종목 중 target 상장분 → (ipoCode 목록, 문자 본문). 없으면 ([], '').
|
||||
상장일은 API 상장 목록 ∪ 청약기록 lcal_date(네이버 조회 실패해도 기록으로 보낸다)."""
|
||||
try:
|
||||
subscribed = json.loads(IPO_SUBSCRIBED.read_text())
|
||||
except Exception:
|
||||
return [], ''
|
||||
by_code = {(r.get('ipoCode') or r.get('itemCode') or '').strip(): (r, d) for r, d in (rows or [])}
|
||||
codes, blocks = [], []
|
||||
for code, rec in subscribed.items():
|
||||
broker = ((rec.get('by') or {}).get('gahee') or {}).get('broker')
|
||||
if not broker or (code not in by_code and rec.get('lcal_date') != target.isoformat()):
|
||||
continue
|
||||
row, detail = by_code.get(code, ({}, None))
|
||||
if detail is None:
|
||||
try:
|
||||
detail = _detail(code)
|
||||
except Exception:
|
||||
detail = {}
|
||||
price = next((b['price'] for b in _manager_blocks(row, detail) if b.get('price') is not None), None)
|
||||
lines = [f"[공모주 상장] 오늘 {rec.get('name') or row.get('compName') or code} 상장일이에요",
|
||||
f'· 청약 증권사: {broker}']
|
||||
if price is not None:
|
||||
lines.append(f'· 확정 공모가: {price:,}원')
|
||||
lines.append(f'· 09:00 거래 시작 — 배정 주식은 {broker} 앱에서 확인하세요')
|
||||
codes.append(code)
|
||||
blocks.append('\n'.join(lines))
|
||||
return codes, '\n\n'.join(blocks)
|
||||
|
||||
|
||||
def send_gahee_imessage(text: str) -> bool:
|
||||
"""가희 리마인더(gahee_reminder._send_imessage)와 같은 방식 — imessage 강제(sms 는 이 수신자에게 3전 3패).
|
||||
⚠️ rc=0 은 Messages 에 넘겼다는 뜻일 뿐 전달 확인이 아니다. 코디 셸에선 AppleEvents 거부로 안 되고 launchd 경유로만."""
|
||||
handle = json.loads(GAHEE_CRED.read_text()).get('handle')
|
||||
if not handle:
|
||||
return False
|
||||
p = subprocess.run(['imsg', 'send', '--to', handle, '--text', text, '--service', 'imessage'],
|
||||
capture_output=True, text=True, timeout=30)
|
||||
if p.returncode != 0:
|
||||
print(f'gahee imsg send rc={p.returncode}: {p.stderr[:200]}', file=sys.stderr)
|
||||
return p.returncode == 0
|
||||
|
||||
|
||||
def collect_for_date(kind: str, target: date) -> list[tuple[dict, dict]]:
|
||||
payload = json.loads(fetch(NAVER_IPO_API_URL, encoding='utf-8'))
|
||||
matches = []
|
||||
@@ -178,6 +226,30 @@ def main() -> int:
|
||||
print(f'IPO interests added: {", ".join(added)}')
|
||||
except Exception as exc:
|
||||
print(f'IPO interests add failed: {type(exc).__name__}: {exc}', file=sys.stderr)
|
||||
if not args.dry_run:
|
||||
# 비하이브 '공모청약' 영상 요약 → 자산웹 공모주 탭. 새 영상 없으면 채널 페이지 1콜로 끝난다.
|
||||
try:
|
||||
from ipo_youtube_digest import run as run_ipo_youtube
|
||||
print(f'IPO youtube digest: {json.dumps(run_ipo_youtube(), ensure_ascii=False)}')
|
||||
except Exception as exc:
|
||||
print(f'IPO youtube digest failed: {type(exc).__name__}: {exc}', file=sys.stderr)
|
||||
if args.kind == 'listing':
|
||||
# 가희가 청약한 종목의 상장일 아침 iMessage(2026-10-07 관리자님 요청). 같은 날 여러 종목이면 한 통.
|
||||
try:
|
||||
codes, text = gahee_listing_message(target, rows)
|
||||
state = load_state()
|
||||
key = f'gahee_listing|{target.isoformat()}|{",".join(sorted(codes))}'
|
||||
if not codes:
|
||||
pass
|
||||
elif args.dry_run:
|
||||
print(f'[dry-run] 가희 상장 문자:\n{text}\n')
|
||||
elif key not in state.get('sent', {}):
|
||||
if send_gahee_imessage(text):
|
||||
state.setdefault('sent', {})[key] = datetime.now(KST).isoformat()
|
||||
save_state(state)
|
||||
print(f'gahee listing imessage sent: {",".join(codes)}')
|
||||
except Exception as exc:
|
||||
print(f'gahee listing imessage failed: {type(exc).__name__}: {exc}', file=sys.stderr)
|
||||
if rows is None:
|
||||
return 1
|
||||
|
||||
|
||||
Reference in New Issue
Block a user