Metadata-Version: 2.4
Name: comci
Version: 0.4.0
Summary: Comci.net 시간표 API 비공식 클라이언트
Requires-Python: >=3.8
Description-Content-Type: text/markdown
Requires-Dist: requests>=2.28.0

# Comci.net 시간표 API 클라이언트

컴시간(comci.net) 비공식 API를 사용하여 학교 검색 및 시간표 조회를 할 수 있는 Python 모듈입니다.

## 설치

```bash
pip install -r requirements.txt
```

## 사용법

### 1. 학교 검색 (지역, 학교명, 학교코드)

```python
from comci import search_schools

# "신송" 검색
schools = search_schools("신송")
for s in schools:
    print(s["region"], s["school_name"], s["school_code"])
# 인천 신송중학교 49654
# 인천 신송고등학교 51825
```

### 2. 특정 학년/반 시간표 조회

```python
from comci import get_timetable

# 1학년 1반 시간표 (정리.md 반환 구조)
timetable = get_timetable(49654, grade=1, class_num=1)
# {"월": [...], "화": [...], "수": [...], "목": [...], "금": [...]}
```

### 2-1. 주차 선택 (일자 드롭다운과 동일)

학생 시간표에서 URL이 `...MF8x`(이번 주) → `...MF8y`(다음 주)처럼 바뀌는 것은 Base64 안의 마지막 숫자 `r` 때문입니다. `date_index`로 지정합니다.

```python
# r=1 (기본): 이번 주 — http://comci.net:4082/36179?NzM2MjlfNDk2NTRfMF8x 와 동일
get_timetable(49654, grade=1, class_num=1, date_index=1)

# r=2: 다음 주 — ...NzM2MjlfNDk2NTRfMF8y 와 동일
get_timetable(49654, grade=1, class_num=1, date_index=2)
```

### 3. 전체 학년/반 시간표 조회

```python
# 학년, 반 미지정 시 전체
timetable = get_timetable(49654)
# {"1학년 1반": {...}, "1학년 2반": {...}, ...}
```

### 4. 검색 후 바로 시간표 조회

```python
from comci import search_and_get_timetable

timetable = search_and_get_timetable("신송", school_index=0, grade=1, class_num=1)
# 다음 주: date_index=2
timetable_next = search_and_get_timetable("신송", school_index=0, grade=1, class_num=1, date_index=2)
```

### 5. 달력 날짜로 주차(r) 자동 선택 · 메타데이터

`일자자료`·`오늘r`을 쓰지 않고 `r=1`만 고정으로 부르면, **달력상 다음 주**인데 API는 이번 주만 주는 경우가 생깁니다. `on=`에 `datetime.date`를 넘기면 해당 날짜가 들어 있는 주의 `r`을 고른 뒤 그 주 JSON을 다시 요청합니다.

```python
from datetime import date, timedelta
from comci import get_timetable, get_day_timetable

today = date.today()

# 오늘이 속한 주 + 각 칸에 ISO 날짜·r 부착 (기본)
get_timetable(49654, grade=1, class_num=1, on=today)

# 응답에 r, 일자자료 파싱본, 오늘r 포함
bundle = get_timetable(49654, grade=1, class_num=1, on=today, with_context=True)
ctx = bundle["context"]   # requested_r, today_r, weeks, 일자자료, day_dates, …
tt = bundle["timetable"]

# 그날(월~금) 교시 열만
get_day_timetable(49654, today, grade=1, class_num=1)
```

저수준으로는 `fetch_timetable_for_calendar_date`, `extract_timetable_context`, `parse_ilja_weeks`, `comci_weekday`, `timetable_for_calendar_day` 등을 패키지에서 직접 가져다 쓸 수 있습니다.

### 6. 파싱 오류를 숨기지 않기

전 학급 조회 시 일부 반만 실패하면 기본은 건너뛰고, 리스트에만 기록합니다.

```python
errs: list[str] = []
get_timetable(49654, parse_errors_out=errs)
# strict_parse=True 이면 첫 예외에서 중단
```

## 프로젝트 구조

```
comci/
├── __init__.py      # 패키지 진입점
├── config.py        # API URL, 상수
├── school_search.py # 학교 검색
├── timetable.py     # 시간표 API 및 파싱
└── client.py        # 통합 클라이언트
```

## 예시 실행

```bash
python example_usage.py
```

## 시간표 데이터 구조

각 요일별 리스트는 교시(1~8) 순서이며, 각 항목은:

```python
{
    "r": 1,                      # 이번 요청 주차 (URL의 r)
    "day": 1,                    # 월=1 … 금=5
    "calendar_date": "2026-03-16",  # 해당 요일의 실제 날짜 (enrich 기본 True)
    "period": 1,
    "time": "1(09:10)",          # 일과시간
    "subject": "국어",
    "teacher": "김*",
    "room": "101",
    "changed": False             # 자료147이 적용됐고 481과 코드가 다를 때 True
}
```

빈 칸(공강 등)은 기존과 같이 `None`입니다.
