From 23f2976139144c648f2bddc2d75b3cf4976af612 Mon Sep 17 00:00:00 2001 From: happybell80 Date: Sat, 6 Sep 2025 16:47:38 +0900 Subject: [PATCH] =?UTF-8?q?Add:=20skill-publish=20=EC=84=9C=EB=B9=84?= =?UTF-8?q?=EC=8A=A4=20=EA=B5=AC=ED=98=84=20=ED=8A=B8=EB=9F=AC=EB=B8=94?= =?UTF-8?q?=EC=8A=88=ED=8C=85=20=EB=AC=B8=EC=84=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - pyproject.toml 패키지 경로 오류 해결 - Docker network 설정 제거 - Import 경로 src → app 일괄 변경 - 누락된 함수/클래스 구현 (get_logger, login_to_squarespace, NewsDataManager) - Gitea Actions SSH 배포 설정 - 환경변수 설정 가이드 --- .../250906_skill_publish_implementation.md | 144 ++++++++++++++++++ 1 file changed, 144 insertions(+) create mode 100644 troubleshooting/250906_skill_publish_implementation.md diff --git a/troubleshooting/250906_skill_publish_implementation.md b/troubleshooting/250906_skill_publish_implementation.md new file mode 100644 index 0000000..288d337 --- /dev/null +++ b/troubleshooting/250906_skill_publish_implementation.md @@ -0,0 +1,144 @@ +# skill-publish 서비스 구현 및 오류 해결 + +## 작성일: 2025-09-06 +## 작성자: happybell80 +## 관련: skill-publish (포트 8511), company-x_hompage 코드 이식 + +## 1. 프로젝트 초기 구성 +**목표**: company-x_hompage/src/publishers 코드를 skill-publish로 분리 +- 저장소: https://git.ro-being.com/ivada_Ro-being/skill-publish.git +- 포트: 8511 (내부 통신용, Nginx 불필요) +- 서버: 51124 + +## 2. 주요 오류 및 해결 + +### 2.1 pyproject.toml 패키지 경로 오류 +**오류**: `No directory matches the name of your project (skill_publish)` +**원인**: hatchling이 패키지 경로를 찾지 못함 +**해결**: pyproject.toml에 추가 +```toml +[tool.hatch.build.targets.wheel] +packages = ["app"] +``` + +### 2.2 Docker network 오류 +**오류**: `network ivada-network declared as external, but could not be found` +**원인**: 외부 네트워크 불필요 (내부 통신만 사용) +**해결**: docker-compose.yml에서 제거 +- 삭제: `version: '3.8'` (obsolete) +- 삭제: networks 섹션 전체 + +### 2.3 Gitea Actions SSH 배포 오류 +**오류**: 로컬 경로 접근 시도 +**원인**: skill_news 참고하여 SSH 방식 누락 +**해결**: .gitea/workflows/deploy.yml 수정 +```yaml +- name: Setup SSH + run: | + echo "${{ secrets.SSH_PRIVATE_KEY_51124 }}" > ~/.ssh/deploy_key + chmod 600 ~/.ssh/deploy_key + ssh-keyscan -p 51124 -H ${{ secrets.SSH_HOST_51124 }} >> ~/.ssh/known_hosts + +- name: Deploy to 51124 Server + run: | + ssh -p 51124 -i ~/.ssh/deploy_key admin@${{ secrets.SSH_HOST_51124 }} << 'DEPLOY_SCRIPT' + cd /home/admin/ivada_project/skill-publish + git pull origin main --rebase + docker compose down || echo "Container was not running" + docker compose up -d --build + DEPLOY_SCRIPT +``` + +### 2.4 Import 경로 오류 (src → app) +**오류**: `ImportError: No module named 'src'` +**원인**: company-x_hompage는 src/, skill-publish는 app/ 구조 +**해결**: 모든 파일에서 일괄 변경 +```bash +find app/services -name "*.py" -exec sed -i 's/from src\./from app./g' {} \; +``` +**수정 파일**: +- app/services/*.py (8개 파일) +- squarespace_login.py, post_formatter.py, image_uploader.py 등 + +### 2.5 get_logger 함수 누락 +**오류**: `ImportError: cannot import name 'get_logger'` +**원인**: company-x_hompage와 logger 구조 차이 +**해결**: app/utils/logger.py에 호환성 함수 추가 +```python +def get_logger(name: str, category: str = 'general') -> logging.Logger: + return setup_logger(name) +``` + +### 2.6 login_to_squarespace 함수 누락 +**오류**: `ImportError: cannot import name 'login_to_squarespace'` +**원인**: publisher_service.py에서 함수형 호출, 원본은 클래스만 존재 +**해결**: app/services/squarespace_login.py에 호환 함수 추가 +```python +async def login_to_squarespace(page: Page) -> bool: + login_instance = SquarespaceLogin() + success, error = await login_instance.login(page) + return success +``` + +### 2.7 NewsDataManager 클래스 누락 +**오류**: `NameError: name 'NewsDataManager' is not defined` +**원인**: company-x_hompage의 collectors 모듈 미포함 +**해결**: app/services/post_formatter.py에서 직접 파일 I/O로 대체 +```python +# 변경 전 +self.manager = NewsDataManager(keyword) +unpublished = self.manager.get_unposted_articles(limit=100) + +# 변경 후 +self.news_file = self.news_dir / f"{self.safe_keyword}_news.json" +if self.news_file.exists(): + with open(self.news_file, 'r', encoding='utf-8') as f: + all_news = json.load(f) + unpublished = [a for a in all_news if not a.get('posted', False)][:100] +``` + +### 2.8 ImageDownloader 클래스 누락 +**해결**: app/services/image_uploader.py:10에서 주석 처리 +```python +# from app.image_downloader import ImageDownloader +``` + +## 3. 환경변수 설정 (51124 서버) +```bash +cat > /home/admin/ivada_project/skill-publish/.env << 'EOF' +PORT=8511 +SQUARESPACE_EMAIL=실제이메일 +SQUARESPACE_PASSWORD=실제비밀번호 +SQUARESPACE_SITE_URL=https://www.company-x.partners +HEADLESS_BROWSER=true +EOF +``` + +## 4. 최종 구조 +``` +skill-publish/ +├── app/ +│ ├── main.py (FastAPI 앱) +│ ├── config.py (설정) +│ ├── services/ +│ │ ├── publisher_service.py (메인 서비스) +│ │ ├── squarespace_*.py (이식된 코드) +│ │ └── post_formatter.py (수정됨) +│ └── utils/ +│ └── logger.py (호환성 추가) +├── Dockerfile (Playwright 포함) +├── docker-compose.yml (네트워크 제거) +└── .gitea/workflows/deploy.yml (SSH 배포) +``` + +## 5. 교훈 +1. **코드 이식시 import 경로 전면 검토 필수** +2. **Docker 네트워크는 필요한 경우만 사용** +3. **Gitea Actions는 SSH 배포 패턴 통일** +4. **의존성 모듈은 독립적으로 구현 또는 제거** +5. **환경변수로 하드코딩 제거 (GEMINI_MODEL 등)** + +## 6. 다음 단계 +- rb8001과 HTTP 통신 테스트 +- 실제 Squarespace 게시 로직 완성 +- JSON 기반 큐 시스템 검증 \ No newline at end of file