Files
blog-writer/scripts/get_token.py
sinmb79 8a7a122bb3 feat: v3.0 엔진 추상화 + 소설 파이프라인 추가
[1순위] 엔진 추상화 리팩토링
- config/engine.json: 단일 설정 파일로 writing/tts/image/video/publishing 엔진 제어
- bots/engine_loader.py: EngineLoader 팩토리 클래스 (Claude/OpenClaw/Gemini Writer, gTTS/GoogleCloud/OpenAI/ElevenLabs TTS, DALL-E/External 이미지)

[2순위] VideoEngine 추상화
- bots/converters/video_engine.py: VideoEngine ABC + FFmpegSlidesEngine/SeedanceEngine/SoraEngine/RunwayEngine/VeoEngine 구현
- Seedance 2.0 API 연동 + 실패 시 ffmpeg_slides 자동 fallback

[3순위] 소설 연재 파이프라인
- bots/novel/novel_writer.py: AI 에피소드 자동 생성 (Claude/엔진 추상화)
- bots/novel/novel_blog_converter.py: 에피소드 → 장르별 테마 Blogger HTML
- bots/novel/novel_shorts_converter.py: key_scenes → TTS + Pillow + VideoEngine → MP4
- bots/novel/novel_manager.py: 전체 파이프라인 조율 + Telegram 명령 처리
- config/novels/shadow-protocol.json: 예시 소설 설정 (2040 서울 SF 스릴러)

[스케줄러] 소설 파이프라인 통합
- 매주 월/목 09:00 자동 실행 (job_novel_pipeline)
- Telegram 명령: /novel_list, /novel_gen, /novel_status

[기타 수정]
- collector_bot.py: 한국어 유니코드 감지 + RSS 신뢰도 override 버그 수정
- quality_rules.json: min_score 70→60
- scripts/get_token.py: YouTube OAuth scope 추가
- .env.example: SEEDANCE/ELEVENLABS/GEMINI/RUNWAY API 키 항목 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-26 09:33:04 +09:00

62 lines
2.1 KiB
Python

"""
Google OAuth2 토큰 발급 스크립트
실행: python scripts/get_token.py
결과: credentials.json 필요, token.json 생성, refresh_token 출력
"""
import json
import os
import sys
from google_auth_oauthlib.flow import InstalledAppFlow
from google.oauth2.credentials import Credentials
from google.auth.transport.requests import Request
SCOPES = [
'https://www.googleapis.com/auth/blogger',
'https://www.googleapis.com/auth/webmasters',
'https://www.googleapis.com/auth/youtube.upload',
'https://www.googleapis.com/auth/youtube',
]
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
TOKEN_PATH = os.path.join(BASE_DIR, 'token.json')
CREDENTIALS_PATH = os.path.join(BASE_DIR, 'credentials.json')
def main():
if not os.path.exists(CREDENTIALS_PATH):
print(f"[ERROR] credentials.json 파일이 없습니다: {CREDENTIALS_PATH}")
print("Google Cloud Console에서 OAuth 클라이언트 ID를 생성하고")
print("credentials.json 을 C:\\blog-engine\\ 에 저장하세요.")
sys.exit(1)
creds = None
if os.path.exists(TOKEN_PATH):
creds = Credentials.from_authorized_user_file(TOKEN_PATH, SCOPES)
if not creds or not creds.valid:
if creds and creds.expired and creds.refresh_token:
creds.refresh(Request())
print("[OK] 기존 토큰 갱신 완료")
else:
flow = InstalledAppFlow.from_client_secrets_file(CREDENTIALS_PATH, SCOPES)
creds = flow.run_local_server(port=0)
print("[OK] 새 토큰 발급 완료")
with open(TOKEN_PATH, 'w') as token_file:
token_file.write(creds.to_json())
token_data = json.loads(creds.to_json())
refresh_token = token_data.get('refresh_token', '')
print("\n" + "=" * 50)
print("토큰 발급 성공!")
print("=" * 50)
print(f"\nREFRESH_TOKEN:\n{refresh_token}")
print(f"\n이 값을 .env 파일의 GOOGLE_REFRESH_TOKEN 에 붙여넣으세요.")
print(f"\ntoken.json 저장 위치: {TOKEN_PATH}")
if __name__ == '__main__':
main()