"""
뉴스레터 변환봇 (converters/newsletter_converter.py)
역할: 원본 마크다운 → 주간 뉴스레터 HTML 발췌 (LAYER 2)
- TITLE + META + KEY_POINTS 발췌
- 주간 단위로 모아서 뉴스레터 HTML 생성
출력: data/outputs/weekly_{date}_newsletter.html
Phase 3에서 Substack 등 연동 예정
"""
import json
import logging
from datetime import datetime
from pathlib import Path
BASE_DIR = Path(__file__).parent.parent.parent
LOG_DIR = BASE_DIR / 'logs'
OUTPUT_DIR = BASE_DIR / 'data' / 'outputs'
OUTPUT_DIR.mkdir(exist_ok=True)
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s [%(levelname)s] %(message)s',
handlers=[
logging.FileHandler(LOG_DIR / 'converter.log', encoding='utf-8'),
logging.StreamHandler(),
]
)
logger = logging.getLogger(__name__)
BLOG_BASE_URL = 'https://the4thpath.com'
def extract_newsletter_item(article: dict, blog_url: str = '') -> dict:
"""단일 글에서 뉴스레터용 발췌 추출"""
return {
'title': article.get('title', ''),
'meta': article.get('meta', ''),
'corner': article.get('corner', ''),
'key_points': article.get('key_points', []),
'url': blog_url or f"{BLOG_BASE_URL}/{article.get('slug', '')}",
'extracted_at': datetime.now().isoformat(),
}
def build_newsletter_html(items: list[dict], week_str: str = '') -> str:
"""주간 뉴스레터 HTML 생성"""
if not week_str:
week_str = datetime.now().strftime('%Y년 %m월 %d일 주간')
article_blocks = []
for item in items:
points_html = ''.join(
f'
{p}' for p in item.get('key_points', [])
)
block = f"""
{item.get('corner','')}
{item.get('meta','')}
전체 읽기 →
"""
article_blocks.append(block)
articles_html = '\n'.join(article_blocks)
return f"""
The 4th Path 주간 뉴스레터 — {week_str}
The 4th Path
{week_str} 뉴스레터
{articles_html}
"""
def generate_weekly(articles: list[dict], urls: list[str] = None,
save_file: bool = True) -> str:
"""
여러 글을 모아 주간 뉴스레터 HTML 생성.
articles: article dict 리스트
urls: 각 글의 발행 URL (없으면 slug로 생성)
"""
logger.info(f"주간 뉴스레터 생성 시작: {len(articles)}개 글")
items = []
for i, article in enumerate(articles):
url = (urls[i] if urls and i < len(urls) else '')
items.append(extract_newsletter_item(article, url))
week_str = datetime.now().strftime('%Y년 %m월 %d일')
html = build_newsletter_html(items, week_str)
if save_file:
date_str = datetime.now().strftime('%Y%m%d')
filename = f"weekly_{date_str}_newsletter.html"
output_path = OUTPUT_DIR / filename
output_path.write_text(html, encoding='utf-8')
logger.info(f"뉴스레터 저장: {output_path}")
logger.info("주간 뉴스레터 생성 완료")
return html
if __name__ == '__main__':
samples = [
{
'title': 'ChatGPT 처음 쓰는 사람을 위한 완전 가이드',
'meta': 'ChatGPT를 처음 사용하는 분을 위한 단계별 가이드',
'slug': 'chatgpt-guide',
'corner': '쉬운세상',
'key_points': ['무료로 바로 시작', 'GPT-3.5로도 충분', '프롬프트가 핵심'],
},
{
'title': '개발자 생산성 10배 높이는 AI 도구 5선',
'meta': '실제 사용해본 AI 개발 도구 정직한 리뷰',
'slug': 'ai-dev-tools',
'corner': '숨은보물',
'key_points': ['Cursor로 코딩 속도 3배', 'Copilot과 차이점', '무료 플랜으로 충분'],
},
]
html = generate_weekly(samples)
print(html[:500])