Commit Graph

62 Commits

Author SHA1 Message Date
JOUNGWOOK KWON
8eb6b7a7f9 feat: Groq fallback writer 추가 — Gemini rate limit 시 자동 전환
- GroqWriter 클래스 추가 (llama-3.3-70b-versatile)
- FallbackWriter 래퍼: primary 실패/빈응답 → fallback chain 자동 시도
- engine.json에 groq 설정 + fallback_chain: ["groq"] 추가

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-30 18:40:01 +09:00
JOUNGWOOK KWON
8a15148b7b fix: 한국어 조사 제거로 Google News RSS 검색 정확도 개선
_extract_search_keywords()에서 한국어 조사/어미(을, 에서, 에서만 등)를
regex로 제거하고 키워드를 3개로 축소하여 검색 적중률 향상.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-30 18:32:43 +09:00
JOUNGWOOK KWON
b3ccbba491 fix: Google News og:title 덮어쓰기 방지 - 원본 RSS 제목 보존
_fetch_sources_content()에서 Google News 페이지의 og:title='Google News'로
원래 RSS 기사 제목이 덮어씌워지던 문제 수정.
- 'Google News' 등 플랫폼 이름이면 무시, 원래 RSS 제목 유지
- og:description도 'google news' 포함 시 무시
이로써 DuckDuckGo 원문 기사 이미지 검색이 제대로 작동

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-30 18:28:13 +09:00
JOUNGWOOK KWON
178caade3f feat: 원문 기사 이미지 DuckDuckGo 검색 + Blogger img 삽입 방식 개선
1. _search_real_article_image(): DuckDuckGo HTML 검색으로 원문 기사 URL 찾기
   - Google News 소스 제목 → DDG 검색 → 실제 URL → og:image
   - DDG redirect URL(uddg 파라미터)에서 실제 URL 추출
2. build_full_html(): 이미지를 div 래핑 없이 body_html 맨 앞에 직접 삽입
   - Blogger가 div class를 제거하는 문제 해결
3. fetch_featured_image() 우선순위 변경:
   RSS이미지 → og:image → DDG검색(원문) → Pexels → Wikipedia

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-30 18:19:13 +09:00
JOUNGWOOK KWON
d9f932b333 fix: Wikipedia 이미지 태그 전체 시도, TOC h2>=3 스마트 복원
- fetch_featured_image: 태그 전체(최대 8개) 시도, 제목 제외(너무 길어 매칭 안됨)
  px 크기 regex로 일괄 800px 교체
- TOC: h2>=3 조건부 표시 복원 (완전제거→스마트 표시)
  두 파일(publisher_bot, blog_converter) 동일하게 적용

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-30 18:04:21 +09:00
JOUNGWOOK KWON
b98d694b65 fix: 목차 완전 제거, Wikipedia 이미지 fallback 추가
1. publisher_bot.py + blog_converter.py: 목차(TOC) 완전 비활성화
2. fetch_featured_image(): Wikipedia REST API로 무료 이미지 fallback
   - 제목/태그로 한국어 Wikipedia 검색 → 썸네일 추출
   - 실패 시 영문 Wikipedia 시도 (최대 4개 키워드)
   - 200px 썸네일 → 800px 고해상도로 교체

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-30 17:54:07 +09:00
JOUNGWOOK KWON
f3526bbcdd fix: source_image에도 플랫폼 로고 필터 적용 (근본 원인 수정)
NAS IP에서 Google News RSS URL이 200 응답하며 og:image에 lh3.googleusercontent.com
썸네일을 반환하는 문제. 두 곳 모두 차단:
- fetch_featured_image(): source_image에 _is_platform_logo() 체크 추가
- _fetch_sources_content(): og:image 저장 전 플랫폼 로고 패턴 필터 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-30 17:46:45 +09:00
JOUNGWOOK KWON
ee91d83d37 fix: lh3.googleusercontent.com 필터 추가, Google News 리다이렉트 head→get 수정
- _is_platform_logo(): lh3.googleusercontent.com (Google News CDN 썸네일) 스킵 패턴 추가
- _fetch_og_image(): requests.head() → requests.get() (head는 리다이렉트 미작동)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-30 17:33:24 +09:00
JOUNGWOOK KWON
07703a0f6b fix: Google 뉴스 URL 리다이렉트 추적 + sources 최종 반영
- requests.head() → requests.get()으로 변경 (Google 뉴스 리다이렉트 정상 추적)
- enriched sources(실제 기사 URL)를 article에 덮어써서 출처 박스에 반영
- source_image도 크롤링된 og:image로 채워짐

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-30 17:28:00 +09:00
JOUNGWOOK KWON
3119823128 fix: /idea 긴 문장 검색 시 핵심 키워드 추출
'월드컵을 지상파에서 못보는 상황에 대한 반대의 글' → '월드컵 지상파에서 못보는'
불용어 제거 후 핵심 키워드 3~5개만 추출하여 Google 뉴스 검색.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-30 17:18:05 +09:00
JOUNGWOOK KWON
45a352c343 fix: feedparser URL 직접 호출 → requests + feedparser 텍스트 파싱
feedparser.parse(URL)이 NAS에서 15초+ 소요되어 타임아웃 발생.
requests.get()으로 1초에 가져온 후 feedparser.parse(text)로 파싱하면 총 1.3초.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-30 17:16:02 +09:00
JOUNGWOOK KWON
0e72e6de88 feat: pending 글 카테고리 변경 기능 추가
- /setcorner <번호> <카테고리>: 커맨드로 변경
- /pending 버튼에 🏷 카테고리 변경 버튼 추가 → 클릭 시 9개 카테고리 선택 버튼 표시

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-30 17:13:40 +09:00
JOUNGWOOK KWON
8c66d9b9e0 debug: _fetch_sources_content 로그 추가 2026-03-30 16:24:03 +09:00
JOUNGWOOK KWON
e077b593c9 feat: /idea 글 작성 시 소스 크롤링 → Gemini에 실제 내용 전달
/write 시점에 Google 뉴스 URL → 실제 기사 URL 변환 후 내용 크롤링.
Gemini 프롬프트에 기사 제목+요약+URL 전달 → 실제 소스 기반 글 작성.
출처 박스에 실제 기사 링크 표시.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-30 16:20:26 +09:00
JOUNGWOOK KWON
6d9cf8d6da feat: /idea sources 배열을 Gemini 프롬프트와 출처 섹션에 반영
- sources 배열의 제목+URL을 참고 자료로 프롬프트에 포함
- SOURCES 섹션에 각 기사 URL·제목·날짜 모두 기재
- 소스 없을 때는 "AI 자체 지식 활용" 명시

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-30 16:17:51 +09:00
JOUNGWOOK KWON
7fd57e61b4 fix: /idea RSS 소스 검색 복원 + 15초 타임아웃 폴백
검색 성공 시 소스 표시, 15초 초과 시 키워드만으로 저장 후 진행.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-30 15:45:54 +09:00
JOUNGWOOK KWON
b41e8d0ff2 fix: /idea 타임아웃 — 리다이렉트/크롤링 제거하고 RSS만 파싱
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-30 15:39:57 +09:00
JOUNGWOOK KWON
f25a95440a fix: /idea 타임아웃 — 리다이렉트/크롤링 제거하고 RSS만 파싱
NAS→Google 뉴스 리다이렉트 추적이 매우 느려서 Telegram 타임아웃 발생.
RSS 피드 파싱만으로 제목/설명 수집, URL 변환은 글 작성 시점에 처리.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-30 15:36:01 +09:00
JOUNGWOOK KWON
c836c720da fix: /idea 명령 타임아웃 — 첫 기사만 크롤링으로 속도 최적화
5개 기사 모두 리다이렉트 추적하면 50초+ 걸려서 Telegram 타임아웃 발생.
첫 번째 기사만 URL 변환+크롤링하고 나머지는 RSS 제목만 저장.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-30 15:26:15 +09:00
JOUNGWOOK KWON
3d6736503f feat: /idea 명령 추가 — 키워드로 글감 자동 생성
텔레그램에서 /idea <키워드> [카테고리] 로 글감 등록.
- Google 뉴스 RSS로 관련 기사 최대 5개 자동 검색
- 첫 번째 기사에서 설명/이미지 크롤링
- 검색된 기사들을 sources로 저장 → 글 작성 시 참고 자료로 활용
- 카테고리 미지정 시 키워드 기반 자동 추정

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-30 15:14:37 +09:00
JOUNGWOOK KWON
52c06e4cd4 fix: 목차(TOC)를 h2가 3개 이상일 때만 표시
짧은 글에서 '목차' 텍스트만 덩그러니 나오는 문제 수정.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-30 13:59:10 +09:00
JOUNGWOOK KWON
6e92b76077 feat: /topic 명령 추가 — URL을 글감으로 등록
텔레그램에서 /topic <URL> [카테고리] 로 기사 URL을 글감으로 등록.
- 기사 크롤링: 제목, 설명, og:image, 사이트명 자동 추출
- 카테고리 미지정 시 키워드 기반 자동 추정
- Google 뉴스 URL 자동 변환
- 등록 후 /write 번호로 바로 글 작성 가능

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-30 13:54:51 +09:00
JOUNGWOOK KWON
2fcb2d353d fix: Google 뉴스 RSS URL을 실제 기사 URL로 변환
수집 시 news.google.com/rss/articles/CBMi... 형태의 인코딩 URL을
리다이렉트 따라가서 실제 기사 URL로 저장. 출처 링크 클릭 시 원본 기사로 이동 가능.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-30 13:46:14 +09:00
JOUNGWOOK KWON
d0cabc3f13 fix: og:image에서 플랫폼 로고(Google뉴스 등) 필터링
- _is_platform_logo(): 로고/아이콘/기본이미지 패턴 감지
- Google 뉴스 URL인 경우 실제 기사 URL로 리다이렉트 추적
- 로고 이미지 걸러지면 Pexels 폴백으로 진행

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-30 13:44:53 +09:00
JOUNGWOOK KWON
adc4d252ac feat: /write 명령에 카테고리 오버라이드 기능 추가
/write 7 AI인사이트 형태로 카테고리를 변경하여 발행 가능.
두 번째 인자가 유효한 카테고리명이면 corner 오버라이드, 아니면 기존 direction으로 처리.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-30 13:17:04 +09:00
JOUNGWOOK KWON
33f0c5d2b1 feat: 앱추천 카테고리를 건강정보로 교체
- blogs.json labels: 앱추천 → 건강정보
- sources.json: 앱추천 RSS 5개 삭제, 건강정보 RSS 7개 추가
  (헬스조선, 연합뉴스 건강, 메디게이트뉴스, 하이닥, 코메디닷컴, 메디컬투데이, 건강 구글뉴스)
- x_keywords: 앱 추천 → 건강 정보, 의료 뉴스, 건강 관리

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-30 13:01:44 +09:00
JOUNGWOOK KWON
e250126431 fix: 글쓰기 프롬프트에서 자기소개/인사말 제거
매 글마다 "편집자 eli입니다" 반복 → 바로 주제 진입으로 변경

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-30 12:57:03 +09:00
JOUNGWOOK KWON
1c6a20e7ea feat: 블로그 글 하단에 원문 출처 링크 표시
- 본문 끝에 출처 박스 추가 (배경색 + 좌측 보더)
- sources 배열과 source_url 모두 표시
- 중복 URL 제거, 새 탭 열기(target=_blank)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-30 12:54:45 +09:00
JOUNGWOOK KWON
a3fbed40ec fix: _publish_next 중복 정의 제거 — pending 이동 안 되던 근본 원인
upstream의 drafts/ 기반 _publish_next(520줄)가 수정된 originals→pending
버전(257줄)을 덮어쓰고 있었음. Python은 마지막 정의를 사용하므로
originals/에서 pending_review/로 이동이 전혀 안 되던 것.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-30 12:41:06 +09:00
JOUNGWOOK KWON
53393a6354 fix: 대표 이미지를 원본 기사 og:image 크롤링으로 변경
- Unsplash Source API 중단으로 기존 폴백 작동 안 함
- 원본 기사 URL에서 og:image / twitter:image 크롤링 (가장 확실)
- 우선순위: RSS 이미지 → og:image 크롤링 → Pexels API
- lxml 파서 사용 (이미 Docker에 설치됨)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-30 12:35:03 +09:00
JOUNGWOOK KWON
d85671e6ac fix: pending 파일명 _pending.json 접미사 추가 + 에러 복구 강화
- _publish_next에서 파일명에 _pending 접미사 추가 (get_pending_list 매칭)
- check_safety 실패 시에도 수동 검토로 전환 (무조건 pending 이동)
- safety_keywords.json의 재테크절약 → 재테크 수정
- /write 후 인라인 버튼 callback_data도 _pending 파일명 사용

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-30 12:31:00 +09:00
JOUNGWOOK KWON
9280be7e52 feat: 원본 RSS 소스 이미지를 대표 이미지로 우선 사용
- RSS 수집 시 media:thumbnail, media:content, enclosure, <img> 태그에서 이미지 추출
- source_image를 topic → article → publisher로 전달
- 발행 시 우선순위: 원본 소스 이미지 → Pexels → Unsplash

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-30 12:22:48 +09:00
JOUNGWOOK KWON
02484679e2 feat: 블로그 대표 이미지 자동 삽입 (Pexels/Unsplash)
- 발행 시 본문에 <img>가 없으면 자동으로 대표 이미지 추가
- Pexels API (PEXELS_API_KEY 있을 때) → Unsplash Source (무료 폴백)
- 글 태그/코너 기반 키워드로 관련 이미지 검색
- Blogger가 첫 번째 <img>를 자동으로 thumbnail로 사용

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-30 12:21:06 +09:00
JOUNGWOOK KWON
7a03fb984a feat: 텔레그램 인라인 버튼으로 승인/거부 (터치 한 번으로 발행)
- /write 완료 시 미리보기 + [승인 발행] [거부] 인라인 버튼 표시
- /pending 목록도 각 글마다 인라인 버튼 포함
- 버튼 클릭 → 즉시 발행/거부 처리, 메시지 업데이트
- 기존 /approve, /reject 명령어도 유지

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-30 12:16:14 +09:00
JOUNGWOOK KWON
01f95dbc6b fix: /collect, /topics 전체 글감 표시 (15개 제한 제거)
텔레그램 4096자 제한 고려하여 30개씩 페이지 나눠 전송

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-30 12:11:24 +09:00
JOUNGWOOK KWON
e3c963a014 feat: 영문 RSS 글감 자동 번역+재작성 지원
- 수집 시 영문 소스 자동 감지 (한국어 비율 5% 미만)
- 영문 글감 글쓰기 프롬프트에 번역+한국맥락 재작성 지시 추가
- 한국 시장 비교, 국내 대안 서비스 언급 유도
- 제목도 한국어로 새로 작성하도록 지시

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-30 11:53:01 +09:00
JOUNGWOOK KWON
af57c3500c fix: 수집 필터 완화 — 영문 RSS 살리기 + 코너 자동배정 + 클릭베이트 완화
- 영문 RSS(카테고리 지정됨)에 한국관련성 기본 10점 부여 (즉시폐기 방지)
- korean_relevance 키워드에 AI/GPT/Apple/Netflix 등 글로벌 키워드 추가
- 키워드 매칭을 case-insensitive로 변경
- RSS 카테고리를 corner로 직접 배정 (쉬운세상 대신 실제 라벨)
- 클릭베이트 필터에서 충격/대박/레전드/역대급 제거 (TV뉴스 과다 필터링)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-30 11:50:47 +09:00
JOUNGWOOK KWON
0783775cdd feat: RSS 소스 17개 추가 — TV로보는세상 6개 + 기존 카테고리 보강
- TV로보는세상: 연합뉴스연예, 한경연예, MBC, TV리포트, OSEN, 스포츠조선
- AI인사이트: Google News AI, Ars Technica
- 여행맛집: Google News 여행맛집, 마이리얼트립
- 제품리뷰: 뽐뿌, Wired
- 앱추천: 9to5Mac, Android Authority
- 재테크: 조선비즈, 이데일리
- x_keywords: TV/드라마/넷플릭스 키워드 추가

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-30 11:48:11 +09:00
JOUNGWOOK KWON
2c80ed1a52 chore: 라벨 변경 — 재테크절약→재테크, TV로보는세상 추가
blogs.json, sources.json 라벨을 블로그 메뉴와 일치시킴

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-30 11:46:23 +09:00
JOUNGWOOK KWON
9cf1f44a8b fix: /collect, /topics 결과에 글 번호 표시 추가
수집 완료 후 바로 번호 포함 목록을 보여줘서
/write [번호]로 바로 글 작성할 수 있도록 개선

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-30 11:42:28 +09:00
JOUNGWOOK KWON
9f68133217 feat: /collect, /write 텔레그램 명령어 추가 + eli 페르소나 적용
- cmd_collect: 즉시 글감 수집
- cmd_write [번호] [방향]: 특정 글감 글 작성 + auto pending
- _publish_next(): originals → pending_review 자동 이동
- _call_openclaw: direction 파라미터 지원
- 글쓰기 시스템 프롬프트 eli 블로그 페르소나로 변경
- 기본 코너: 쉬운세상 → AI인사이트

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-30 11:27:02 +09:00
JOUNGWOOK KWON
3e2405dff9 feat: upstream v3.2.1 기반으로 업그레이드 + eli 블로그 커스터마이징
- upstream sinmb79/blog-writer v3.2.1 코드 베이스 적용
- config_resolver, CLI, writer_bot, shorts pipeline 등 신규 기능 포함
- load_dotenv Windows 경로 → Docker 호환 load_dotenv() 변경 (25개 파일)
- runtime_guard.py Docker 환경 bypass 추가
- config/blogs.json: eli-ai 블로그 정체성 (8개 카테고리)
- config/sources.json: 38개 RSS 소스 유지
- config/engine.json: writing provider → gemini (2.5-flash)
- config/safety_keywords.json: 모든 글 수동 승인 (score 101)
- bots/scheduler.py: 시스템 프롬프트 eli 블로그 기준으로 업데이트
- bots/publisher_bot.py: .env refresh token OAuth 폴백 로직 추가
- requirements.txt: google-generativeai, groq 활성화
- Dockerfile + docker-compose.yml: NAS Docker 배포 설정
- CLAUDE.md: 프로젝트 메타데이터

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-30 09:21:14 +09:00
sinmb79
66be55ba8a fix(v3): code review 5개 이슈 수정
- korean_preprocessor: 발음 사전 176 → 206개 (200+ 달성)
- video_engine: SoraEngine 완전 제거 (2026-03-24 서비스 종료)
- smart_video_router: veo3/seedance2 빈 문자열 반환 → ffmpeg_slides 폴백
- cli/init: gemini_web 서비스 설정 질문 추가 (user_profile 일치)
- caption_renderer, tts_engine, video_assembler: --test 스탠드얼론 블록 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
v3.2.1
2026-03-29 16:14:51 +09:00
sinmb79
6571afc982 feat(v3): PR 10 - bw init setup wizard + prompt_styles.json
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-29 12:05:51 +09:00
sinmb79
6c5c1b9d50 feat(v3): PR 9 - MVP CLI (8 commands) + pyproject.toml
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-29 12:03:07 +09:00
sinmb79
65481eb9e4 feat(v3): PR 8 — PromptTracker (SQLite logging infra) 2026-03-29 11:59:34 +09:00
sinmb79
8931adeafd feat(v3): PR 7 — ResilientAssembler with GPU encoder detection + per-clip fallback
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-29 11:58:16 +09:00
sinmb79
0dedb0d7f8 feat(v3): PR 6 — HookOptimizer + MicroSignals (3 signals)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-29 11:56:34 +09:00
sinmb79
834577fc07 feat(v3): PR 5 — caption templates (3 styles) + MotionEngine (7 patterns)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-29 11:53:03 +09:00
sinmb79
b666b67a03 feat(v3): PR 4 — korean_preprocessor + SmartTTSRouter
- Add bots/prompt_layer/korean_preprocessor.py: 200+ entry pronunciation
  map, number→Korean conversion, dynamic SSML/marker pause insertion
- Upgrade bots/shorts/tts_engine.py: SmartTTSRouter (budget-aware engine
  selection with failure fallback), _tts_openai() function, Korean
  preprocessing step in generate_tts()

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-29 11:48:19 +09:00