<<<<<<< HEAD
To-do list Tetris program - optimizing your daily tasks with travel time consideration.
# 1. Install dependencies
pip install -r requirements.txt
# 2. Setup API keys
cp env.example .env
# Edit .env with your Naver Cloud Platform API keys
# 3. Enable APIs (IMPORTANT!)
# Go to https://console.ncloud.com/
# AI·NAVER API > Your Application
# Enable BOTH:
# ✅ Geocoding (Map Geocoding)
# ✅ Directions 5 (Map Directions 5)
# 4. Test
python test_directions_only.py # Test with coordinates
python check_api.py # Full test
# 5. Run
python daystack.pyYour curl worked because Directions API is enabled. But you also need Geocoding API:
- Go to Naver Cloud Console
- Navigate to:
AI·NAVER API > Application > (Your App) - Scroll to "서비스 선택" (Service Selection)
- Check BOTH boxes:
- ✅ Geocoding - Map Geocoding
- ✅ Directions 5 - Map Directions 5
- Click "수정" (Modify) to save
- Wait 1-2 minutes
- Run:
python check_api.py
Directions works but Geocoding fails (401)? → You enabled Directions but not Geocoding. Follow steps above.
Want to test without Geocoding?
python test_directions_only.py # Uses hardcoded coordinatesdaystack.py- Main applicationscheduler.py- Task allocationnaver_api.py- API wrapper (fixed URLs: maps.apigw.ntruss.com)crawler.py- LMS crawlercheck_api.py- Diagnostic tooltest_directions_only.py- Test directions without geocoding
python daystack.py # Full app
python naver_api.py # Test both APIs
python test_directions_only.py # Test directions only
python check_api.py # Diagnose issuesBased on yontil-main patterns. See SETUP.md for customization.
이동 시간을 고려한 지능형 일정 자동 최적화 시스템
YCC 스케줄러는 Naver Maps API를 활용하여 실제 이동 시간을 계산하고, 일정 사이의 빈 시간에 할 일을 자동으로 배치하는 스마트 스케줄링 시스템입니다.
- ✅ 주소 자동 변환: 텍스트 주소를 GPS 좌표로 변환 (Naver Geocoding API)
- ✅ 이동 시간 계산: 두 지점 간 실제 이동 시간 산출 (Naver Directions 5 API)
- ✅ 자동 일정 최적화: 이동 시간을 제외한 실제 가용 시간에 작업 자동 배치
- ✅ 안전 여유 시간: 예상치 못한 지연을 위한 버퍼 타임 추가
- ✅ Coursemos 크롤러: LMS 과제 자동 수집 (yontil-main 패턴 기반)
- Naver Cloud Platform 회원가입
- 콘솔에서
AI·NAVER API > Application등록 - 다음 API 활성화:
- Maps: 지도 표시
- Geocoding: 주소 → 좌표 변환
- Directions 5: 길찾기 및 이동 시간 계산
Client ID와Client Secret발급받기
- Python 3.8 이상 권장
- pip 패키지 관리자
# 1. 저장소 클론 또는 다운로드
cd scheduler
# 2. 필수 라이브러리 설치
pip install -r requirements.txt
# 3. 환경 변수 설정
# .env 파일을 생성하고 API 키를 입력하세요프로젝트 루트에 .env 파일을 생성하고 다음 내용을 입력하세요:
# Naver Cloud Platform API Credentials
NAVER_CLIENT_ID=your_client_id_here
NAVER_CLIENT_SECRET=your_client_secret_here
# Optional: Add buffer time (in minutes) for travel calculations
TRAVEL_TIME_BUFFER=15.env 파일은 절대 공개 저장소에 업로드하지 마세요!
# 메인 애플리케이션 실행
python main.py
# 빠른 테스트 (API 연결 확인)
python main.py --testReact 기반의 웹 UI는 src/frontend 디렉터리의 Next.js 15 + TypeScript 앱에서 제공합니다.
# 최초 1회 (의존성 설치)
cd src/frontend
npm install
# 개발 서버 실행
npm run dev기본적으로 http://localhost:3000 에서 열리며, 추후 Python 백엔드 API와 연동할 때는
Next.js의 API Route 또는 next.config.ts rewrites를 통해 localhost 로컬 엔드포인트에 프록시하면 됩니다.
- 프론트엔드는
react-leaflet을 사용하여 일정 이동 경로를 시각화합니다. - 백엔드가 주소를 좌표로 변환해야 하므로
.env에 NAVER Geocoding API 키를 반드시 설정하세요. - FastAPI가 실행 중이면
GET /api/sample및 프론트엔드 대시보드에서 자동으로 지도에 경로가 표시됩니다.
- 프론트엔드는
react-leaflet을 사용하여 일정 이동 경로를 시각화합니다. - 백엔드가 주소를 좌표로 변환해야 하므로
.env에 NAVER Geocoding API 키를 반드시 설정하세요. - FastAPI가 실행 중이면
GET /api/sample및 프론트엔드 대시보드에서 자동으로 지도에 경로가 표시됩니다.
FastAPI 서버는 스케줄러 결과를 HTTP로 노출합니다.
# FastAPI 개발 서버 실행
python -m uvicorn backend.api:app --reload --app-dir src- 기본 포트:
http://localhost:8000 - 모든 엔드포인트는
/api아래에서 제공됩니다. (예:GET /api/sample) - 프론트엔드에서는
NEXT_PUBLIC_API_BASE_URL환경 변수를 사용해 API 주소를 바꿀 수 있습니다. (기본값:http://localhost:8000/api)
CLI 메인 로직(daystack.py)은 FastAPI/Next.js와 동일한 컨트롤러를 사용합니다.
python daystack.py- 옵션 1: Coursemos 크롤러(모의 데이터)에서 과제 가져오기
- 옵션 2: 직접 할 일과 예상 시간을 입력
CLI에서 사용하는 일정/과제 정보는 GET /api/sample에도 동일하게 반영되어 프론트엔드에서 시각화됩니다.
CLI 메인 로직(daystack.py)은 FastAPI/Next.js와 동일한 컨트롤러를 사용합니다.
python daystack.py- 옵션 1: Coursemos 크롤러(모의 데이터)에서 과제 가져오기
- 옵션 2: 직접 할 일과 예상 시간을 입력
CLI에서 사용하는 일정/과제 정보는 GET /api/sample에도 동일하게 반영되어 프론트엔드에서 시각화됩니다.
이 프로젝트는 포괄적인 문서를 제공합니다:
- DOCUMENTATION_INDEX.md - 📖 모든 문서의 인덱스와 학습 경로
빠른 링크:
- 🚀 처음 사용: 이 README를 끝까지 읽으세요
- 🔧 크롤러 커스터마이징: QUICKSTART_COURSEMOS.md
- 🏗️ 아키텍처 이해: PROJECT_SUMMARY.md
- 🎯 yontil-main 패턴: YONTIL_INTEGRATION_GUIDE.md
scheduler/
│
├── main.py # 메인 애플리케이션
├── config.py # 설정 및 환경 변수 관리
├── geocoding.py # 주소 → 좌표 변환
├── directions.py # 이동 시간 계산
├── scheduler.py # 일정 최적화 로직
├── coursemos_crawler.py # Coursemos LMS 크롤러 (yontil-main 기반)
│
├── requirements.txt # 필수 라이브러리 목록
├── example.env # 환경 변수 예시
├── .gitignore # Git 제외 파일 목록
├── README.md # 프로젝트 문서 (본 파일)
├── PRD.md # 제품 요구사항 명세서
│
├── YONTIL_INTEGRATION_GUIDE.md # yontil-main 패턴 적용 가이드 ⭐
├── ARCHITECTURE_COMPARISON.md # 아키텍처 상세 비교 ⭐
│
└── yontil-main/ # 참조 프로젝트 (Learnus 크롤러)
└── src/
└── core/
├── login/ # 로그인 패턴 참조
└── tasks/ # 과제 수집 패턴 참조
이 프로젝트의 coursemos_crawler.py는 yontil-main (연세대학교 LearnUs LMS 크롬 확장 프로그램)의 검증된 로그인 및 과제 수집 패턴을 Python으로 적용했습니다.
참조 문서:
- QUICKSTART_COURSEMOS.md - Coursemos 크롤러 빠른 시작 가이드 ⭐ START HERE
- YONTIL_INTEGRATION_GUIDE.md - yontil-main 패턴을 어떻게 적용했는지 상세 설명
- ARCHITECTURE_COMPARISON.md - TypeScript vs Python 구현 비교
- yontil-main 소스 코드 - 원본 참조 프로젝트
주요 적용 패턴:
- ✅ 다단계 로그인 플로우 (Multi-step authentication)
- ✅ HTML hidden field 파싱 (CSRF 토큰 추출)
- ✅ 코스별 과제 순회 수집 (Course → Tasks hierarchy)
- ✅ 미완료 과제 필터링 (
:not(.completed)selector)
## 💻 사용 방법
### 기본 사용법
1. **프로그램 실행**
```bash
python main.py
-
모드 선택
1: Coursemos 크롤러 사용 (현재는 샘플 데이터)2: 수동으로 할 일 입력
-
결과 확인
- 이동 시간을 고려한 최적화된 일정표 출력
- 할당되지 않은 작업 목록 표시
각 모듈은 독립적으로 실행하여 테스트할 수 있습니다:
# 주소 변환 테스트
python geocoding.py
# 이동 시간 계산 테스트
python directions.py
# 스케줄러 로직 테스트
python scheduler.py
# Coursemos 크롤러 테스트
python coursemos_crawler.pyfrom backend.geocoding import get_location_coords
coords = get_location_coords("강남역")
print(coords) # "127.027926,37.497952"from backend.directions import get_travel_time_from_addresses
travel_time = get_travel_time_from_addresses("강남역", "판교역")
print(f"예상 소요 시간: {travel_time}분")from backend.scheduler import allocate_tasks, print_schedule
# 현재 일정
schedule = [
{"name": "수업", "end_time": "13:00", "location": "강남역"},
{"name": "아르바이트", "start_time": "15:00", "location": "판교역"}
]
# 할 일 목록
todos = [
{"task": "과제 작성", "estimated_time": 40},
{"task": "독서", "estimated_time": 30}
]
# 최적화 실행
optimized = allocate_tasks(schedule, todos)
print_schedule(optimized)# 이동 시간 버퍼 (분 단위)
TRAVEL_TIME_BUFFER = 15
# 위치 별칭 설정
LOCATION_ALIASES = {
"학교": "분당구 불정로 6",
"집": "서울시 강남구 역삼동",
"도서관": "서울시 서초구 서초동"
}┌─────────────┐
│ 사용자 입력 │ (주소, 일정, 할 일)
└──────┬──────┘
│
▼
┌─────────────────────────────────┐
│ Naver Geocoding API │
│ (주소 → 좌표 변환) │
└──────┬──────────────────────────┘
│
▼
┌─────────────────────────────────┐
│ Naver Directions 5 API │
│ (이동 시간 계산) │
└──────┬──────────────────────────┘
│
▼
┌─────────────────────────────────┐
│ 스케줄러 로직 │
│ - 가용 시간 계산 │
│ - 작업 자동 배치 │
│ - 최적화된 일정 생성 │
└──────┬──────────────────────────┘
│
▼
┌─────────────┐
│ 최적화된 일정 │
└─────────────┘
실제 가용 시간 = (다음 일정 시작 시간 - 현재 일정 종료 시간)
- 이동 시간
- 안전 버퍼
- 일정을 시간순으로 정렬
- 각 일정 사이의 간격 계산
- 이동 시간 및 버퍼 차감
- 남은 시간에 맞는 작업 할당
- 할당되지 않은 작업 리포트
-
API 무료 사용량
- Naver Maps API는 월별 무료 사용량이 제한되어 있습니다
- Directions 5: 월 300만 건 무료 (2024년 기준, 정책 변경 가능)
-
주소 정확성
- "학교", "집" 같은 별칭은
config.py에 정확한 주소로 매핑해야 합니다 - 모호한 주소는 API가 잘못된 좌표를 반환할 수 있습니다
- "학교", "집" 같은 별칭은
-
시간 예측 정확도
- API가 제공하는 시간은 '예상' 시간입니다
- 실제 교통 상황에 따라 달라질 수 있으므로 버퍼 시간을 충분히 설정하세요
-
Coursemos 크롤러
- yontil-main 프로젝트의 Learnus 로그인/크롤링 패턴을 기반으로 구현
- requests + BeautifulSoup과 Selenium 두 가지 모드 지원
- 실제 Coursemos 연동을 위한 가이드:
COURSEMOS_INTEGRATION_GUIDE.md참조
현재 coursemos_crawler.py는 yontil-main 프로젝트의 Learnus 크롤링 패턴을 기반으로 구현되어 있습니다.
실제 Coursemos와 연동하려면:
COURSEMOS_INTEGRATION_GUIDE.md가이드 참조- Coursemos의 실제 URL과 HTML 구조에 맞게 수정
- 로그인 프로세스 분석 및 적용
- CSS 셀렉터 업데이트
yontil-main/src/core/login/login-learnus.ts- 다단계 로그인yontil-main/src/core/tasks/fetch-tasks.ts- 과제 목록 크롤링yontil-main/src/utils/parse-html-string.ts- HTML 파싱
- 대중교통 이동 시간 지원 (ODsay API 연동)
- 데이터베이스 연동 (일정 및 작업 저장)
- 웹 인터페이스 개발
- 모바일 앱 연동
- 작업 우선순위 설정
- 머신러닝 기반 작업 소요 시간 예측
- Google Calendar 연동
이 프로젝트는 교육 목적으로 개발되었습니다.
버그 리포트, 기능 제안, Pull Request 환영합니다!
프로젝트 관련 문의사항이 있으시면 이슈를 등록해주세요.
Made with ❤️ for YCC Project
982aa41f098ce56c6c07f6784c8d7d70fbb48feb