Repository navigation
Releases: ssucream/study-helper
Release list
study-helper v26.8.0
study-helper v26.8.0
숭실대학교 LMS 강의 영상 재생 · 다운로드 · AI 요약 도구.
패치노트
추가
- OpenRouter API 지원 추가 (
src/summarizer/summarizer.py,src/config.py,src/ui/settings.py)- OpenRouter는 OpenAI 호환 API이므로 기존
openai패키지에base_url만 다르게 지정해 재사용 — 신규 의존성 없음 - OpenRouter는 모델이 수백 개라 Gemini/OpenAI처럼 목록에서 고르는 대신 모델 ID를 직접 입력받음 (
openrouter.ai/models안내)
- OpenRouter는 OpenAI 호환 API이므로 기존
- OpenAI 모델 curated 목록 추가 (
src/summarizer/summarizer.py)OPENAI_MODEL_IDS(gpt-4o-mini/gpt-4o/gpt-4.1-mini/o4-mini)를 Gemini와 동일한 방식으로 설정 화면에 노출
- 설정 화면에 AI 에이전트 선택 단계 추가 (
src/ui/settings.py)- AI 요약 활성화 시 Gemini/OpenAI/OpenRouter 중 에이전트를 먼저 선택한 뒤, 선택한 에이전트에 맞는 API 키·모델 입력 화면으로 분기
- README 러시아어 번역본 제공 (
README.md,README-ko.md)- 기존 한국어 README를
README-ko.md로 이동하고README.md를 러시아어 번역본으로 신규 작성 - 두 문서 최상단에 언어 전환 링크 추가 (TUI 화면 예시는 실제 인터페이스와 동일하게 한국어 원문 유지)
- 기존 한국어 README를
수정
- OpenAI 요약 시 Gemini 모델로 강제 호출되던 버그 수정 (
src/ui/download.py)- 원인:
model = Config.GEMINI_MODEL if Config.AI_AGENT == "gemini" else ""가 OpenAI 선택 시 항상 빈 문자열을 반환했고, 이어지는model or GEMINI_DEFAULT_MODEL폴백이 Gemini 기본 모델(gemini-2.5-flash)을 채워 OpenAI API에 존재하지 않는 모델명으로 요청이 전송됨 - 게다가 설정 화면(
ui/settings.py)에 OpenAI를 선택하는 경로 자체가 없어.env를 직접 편집해야만AI_AGENT=openai를 쓸 수 있었음 — 사실상 미완성 기능이었음 Config.get_ai_credentials()로 에이전트별 (api_key, model) 조회 로직을 일원화해ui/download.py·ui/auto.py에 중복돼 있던 2-way 삼항연산을 제거
- 원인:
변경
Config.save_settings()3-에이전트 대응으로 일반화 (src/config.py)gemini_model파라미터를ai_model로 일반화하고, 선택된 에이전트에 대응하는.env키(GEMINI_MODEL/OPENAI_MODEL/OPENROUTER_MODEL,GOOGLE_API_KEY/OPENAI_API_KEY/OPENROUTER_API_KEY)에만 저장하도록 변경
- Gemini API 키 발급 가이드 문서 제거 (
docs/gemini-api-key.md,README-ko.md)- 가이드 문서와 README의 참조 링크 2곳 삭제
사전 요구사항
설치 및 실행
-
아래 첨부 파일(
docker-compose.yml,.env.example) 다운로드 -
.env.example→.env로 이름 변경 후 필요한 값 설정 (학번/비밀번호는 첫 실행 시 자동 저장) -
이미지 pull 및 실행
docker compose pull
docker compose run --rm study-helper
docker compose up사용 금지 — 로그 멀티플렉싱으로 TUI가 깨집니다.run --rm만 사용하세요.
Docker Hub
docker pull igor0670/study-helper:v26.8.0study-helper v26.7.0
study-helper v26.7.0
숭실대학교 LMS 강의 영상 재생 · 다운로드 · AI 요약 도구.
패치노트
변경
CourseScraper페이지 접근 캡슐화 (src/scraper/course_scraper.py,src/main.py,src/ui/auto.py)main.py·ui/auto.py에서 프라이빗 속성scraper._page를 5곳에서 직접 참조하던 것을page프로퍼티 추가로 정리
crypto.py키 경로 판별 로직 중복 제거 (src/crypto.py)_load_or_create_key()가_resolve_key_path()와 동일한 "디렉토리면 내부 key 파일 사용" 로직을 인라인으로 중복 구현하던 것을_resolve_key_path()재사용으로 통합decrypt()의except (InvalidToken, Exception):을except Exception:으로 정리 —InvalidToken은 이미Exception의 서브클래스라 의미 없는 중복이었음, 미사용InvalidTokenimport 제거
수정
- 다운로드 경로의
주차없는 강의 기본 디렉토리 오류 수정 (src/downloader/video_downloader.py)- 원인:
make_filepath()의_sanitize_filename(week_label or "") or "기타"에서_sanitize_filename()이 빈 입력에도 항상"lecture"를 반환해"기타"폴백 분기가 도달 불가능한 죽은 코드였음 week_label이 비어 있을 때만"기타"를 사용하도록 조건을 명시적으로 분리
- 원인:
추가
- 순수 함수 단위 테스트 추가 (
tests/test_video_downloader.py,tests/test_background_player.py)_sanitize_filename/make_filepath(경로 sanitize, 상위 디렉토리 순회 방지, 주차 추출, 빈 라벨 폴백) 및_parse_player_url(duration sentinel 정규화, TargetUrl 디코딩) 커버
사전 요구사항
설치 및 실행
-
아래 첨부 파일(
docker-compose.yml,.env.example) 다운로드 -
.env.example→.env로 이름 변경 후 필요한 값 설정 (학번/비밀번호는 첫 실행 시 자동 저장) -
이미지 pull 및 실행
docker compose pull
docker compose run --rm study-helper
docker compose up사용 금지 — 로그 멀티플렉싱으로 TUI가 깨집니다.run --rm만 사용하세요.
Docker Hub
docker pull igor0670/study-helper:v26.7.0study-helper v26.06.01
study-helper v26.06.01
숭실대학교 LMS 강의 영상 재생 · 다운로드 · AI 요약 도구.
패치노트
수정
OTHER타입 항목 마감 임박 알림 오발송 수정 (src/notifier/deadline_checker.py)- 원인: PDF 강의 자료가
LectureType.FILE이 아닌LectureType.OTHER로 스크래핑되는 경우, 기존_NON_DEADLINE_TYPES = {LectureType.FILE}필터를 통과해 마감 임박 알림이 발송됨 - 스크래퍼의
_TYPE_CLASS_MAP에 미등록된 아이콘 CSS 클래스를 가진 파일 항목은 기본값인OTHER로 분류 —FILE필터만으로는 차단 불가 _NON_DEADLINE_TYPES에LectureType.OTHER추가, 출석 추적이 없는 모든 미분류 항목을 알림 대상에서 제외
- 원인: PDF 강의 자료가
사전 요구사항
설치 및 실행
-
아래 첨부 파일(
docker-compose.yml,.env.example) 다운로드 -
.env.example→.env로 이름 변경 후 필요한 값 설정 (학번/비밀번호는 첫 실행 시 자동 저장) -
이미지 pull 및 실행
docker compose pull
docker compose run --rm study-helper
docker compose up사용 금지 — 로그 멀티플렉싱으로 TUI가 깨집니다.run --rm만 사용하세요.
Docker Hub
docker pull igor0670/study-helper:v26.06.01study-helper v26.05.03
study-helper v26.05.03
숭실대학교 LMS 강의 영상 재생 · 다운로드 · AI 요약 도구.
패치노트
수정
-
자동 모드 종료 후 버전 업데이트 알림 미출력 수정 (
src/main.py)- 원인: 버전 체크가 컨테이너 시작 시 1회만 실행되어, 자동 모드 실행 중 새 버전이 배포된 경우 메인 화면 복귀 시 알림이 표시되지 않음
run_auto_mode()반환 직후_check_update_compat()를 재호출해latest_version을 갱신하도록 수정
-
자동 모드 종료 시 "0" 이중 입력 필요 문제 수정 (
src/ui/auto.py)- 원인: 재생 중
_input_listener와player.py의_stop_listener가 동시에sys.stdin.readline을 호출하는 경쟁 조건 발생 — "0" 입력이 어느 쪽에 소비돼도 처리되지 않고 버려짐 _input_listener에서playing_event.is_set()체크를readline호출 이전에 수행하도록 변경 — 재생 중에는 sleep으로 대기해 stdin을 점유하지 않음
- 원인: 재생 중
-
장기 구동 시 메모리 누수 완화 (
src/ui/player.py,src/player/background_player.py,src/ui/auto.py)log_buffer메모리 누적 제거: 재생 로그를list[str]에 적재하는 방식에서get_error_logger()로 파일에 직접 스트리밍 기록으로 전환 — 오류 시에만 logs/ 파일 유지, 정상 완료·중단 시 자동 삭제_fake_video_cache참조 해제 보장:_cleanup()에서_fake_video_cache.clear()명시적 호출 추가- 사이클 내 Chromium 힙 누적 억제: 강의 5개 처리마다 브라우저 중간 재시작 추가 (기존: 사이클 완료 후 1회 재시작만 수행)
수정 (이전 릴리즈 v26.05.02 포함)
- 마감 알림 테스트 파일 import 정렬 오류 수정 (
tests/test_deadline_checker.py)- ruff
I001/F401: import 블록 순서 미정렬 및 미사용pytestimport 제거
- ruff
사전 요구사항
설치 및 실행
-
아래 첨부 파일(
docker-compose.yml,.env.example) 다운로드 -
.env.example→.env로 이름 변경 후 필요한 값 설정 (학번/비밀번호는 첫 실행 시 자동 저장) -
이미지 pull 및 실행
docker compose pull
docker compose run --rm study-helper
docker compose up사용 금지 — 로그 멀티플렉싱으로 TUI가 깨집니다.run --rm만 사용하세요.
Docker Hub
docker pull igor0670/study-helper:v26.05.03study-helper v26.05.02
study-helper v26.05.02
숭실대학교 LMS 강의 영상 재생 · 다운로드 · AI 요약 도구.
패치노트
수정
- PDF 파일 열람 항목 마감 임박 알림 오발송 수정 (
src/notifier/deadline_checker.py)- 원인:
find_approaching_deadlines()가VIDEO_LECTURE_TYPES(영상)만 제외하고LectureType.FILE(PDF 파일 열람)은 제외하지 않아, UX방법론·컴퓨터그래픽스 과목의 강의 자료 파일 항목이 마감 임박 알림 대상에 포함 - 파일 열람 항목은
attendance = "none",completion = "incomplete"상태이지만 출석 추적 엘리먼트 자체가 없어 영상 미시청 항목과 구분 불가 — LMS APIenabled_component_types에도"file"이 미포함(출석 추적 없음) _NON_DEADLINE_TYPES = {LectureType.FILE}집합을 도입해 영상 타입과 동일한 방식으로 skip 처리_TYPE_LABELS에서LectureType.FILE항목 제거
- 원인:
- 마감 알림 단위 테스트 추가 (
tests/test_deadline_checker.py)- 신규 파일:
find_approaching_deadlines,_parse_lms_date핵심 케이스 15개 커버 - FILE 제외, QUIZ/ASSIGNMENT/DISCUSSION 포함, 완료·출석·중복·마감일 없음·과거 마감 제외 케이스 포함
- 신규 파일:
사전 요구사항
설치 및 실행
-
아래 첨부 파일(
docker-compose.yml,.env.example) 다운로드 -
.env.example→.env로 이름 변경 후 필요한 값 설정 (학번/비밀번호는 첫 실행 시 자동 저장) -
이미지 pull 및 실행
docker compose pull
docker compose run --rm study-helper
docker compose up사용 금지 — 로그 멀티플렉싱으로 TUI가 깨집니다.run --rm만 사용하세요.
Docker Hub
docker pull igor0670/study-helper:v26.05.02study-helper v26.05.01
study-helper v26.05.01
숭실대학교 LMS 강의 영상 재생 · 다운로드 · AI 요약 도구.
패치노트
수정
- learningx API 401 세션 만료 시 자동 재로그인 후 재시도 (
src/player/background_player.py)- 원인: 자동 모드에서 장시간 재생 후 learningx API 토큰이 만료되면 다음 강의의
attendance_items호출이 401을 반환해 재생 실패 — 기존 코드는 즉시 오류 반환만 처리 _play_via_learningx_api()에lecture_url,is_retry파라미터 추가- 401 수신 시
ensure_logged_in()으로 재인증 후lecture_url로 재이동해 LTI 세션을 새로 획득하고 1회 자동 재시도 is_retry가드로 무한 재귀 방지 /lecture_url미전달 시 기존 오류 반환으로 하위 호환 유지- 참고: learningx API 세션은 Canvas 세션과 독립적으로 만료될 수 있어 기존
_needs_login()체크만으로는 감지 불가
- 원인: 자동 모드에서 장시간 재생 후 learningx API 토큰이 만료되면 다음 강의의
- vendors.js 502 발생 시 페이지 새로고침 후 재시도 (
src/player/background_player.py)- 원인: learningx 플레이어 초기화에 필수인
vendors.js가 502를 반환하면 commons frame이 생성되지 않아 Plan A 사용 불가 → Plan B(learningx API)로 강제 진입 — 위의 401 문제와 결합 시 재생 완전 실패 page.on("response")스니퍼로vendors.js 502를 감지, commons frame 탐색 실패 시 페이지를 1회 새로고침해 정상 로드 유도- 재시도 후에도 frame이 없으면 기존 Plan B 경로로 진행하여 하위 호환 유지
- 원인: learningx 플레이어 초기화에 필수인
사전 요구사항
설치 및 실행
-
아래 첨부 파일(
docker-compose.yml,.env.example) 다운로드 -
.env.example→.env로 이름 변경 후 필요한 값 설정 (학번/비밀번호는 첫 실행 시 자동 저장) -
이미지 pull 및 실행
docker compose pull
docker compose run --rm study-helper
docker compose up사용 금지 — 로그 멀티플렉싱으로 TUI가 깨집니다.run --rm만 사용하세요.
Docker Hub
docker pull igor0670/study-helper:v26.05.01study-helper v26.04.04
study-helper v26.04.04
숭실대학교 LMS 강의 영상 재생 · 다운로드 · AI 요약 도구.
패치노트
수정
- learningx item_id 불일치 수정 (
src/player/background_player.py)- 원인:
_play_via_learningx_api()와_fetch_learningx_duration()이 LTI view URL 경로의 item_id를 사용했으나, 실제 attendance item_id는 DOM의#root[data-item_id]속성에 별도로 존재 (예: URL835118vs DOM839643) - 수정:
tool_contentframe DOM에서data-item_id를 우선 읽어 item_id를 교정하도록 변경 — 두 값이 다를 경우 로그에 교정 내역 출력
- 원인:
- 403 응답 시 명확한 오류 메시지 표시 (
src/player/background_player.py)- 기존:
"learningx API 오류: 403"으로 표시 - 수정:
"출석 기간이 열려 있지 않거나 이 강의에 대한 접근 권한이 없습니다."로 표시 — 서버 응답의message필드도 로그에 기록
- 기존:
- 401/404 응답 시 명확한 오류 메시지 추가 (
src/player/background_player.py)- 401:
"세션이 만료됐습니다. 재실행하면 자동으로 재로그인됩니다." - 404:
"강의를 찾을 수 없습니다. 강의 목록을 다시 불러와 주세요."
- 401:
- 진도 보고 JSONP 결과 미검증 수정 (
src/player/background_player.py)- 기존: JSONP 응답 수신 시
result:false/error여부와 무관하게reported = True로 설정 → 진도 보고 실패를 성공으로 처리 - 수정:
"result":true"포함 여부 검사 후 설정 — 실패 응답 시page.request.get폴백으로 진행
- 기존: JSONP 응답 수신 시
- 진도 보고 연속 실패 시 세션 만료 감지 (
src/player/background_player.py)- 연속 실패 카운터(
_consecutive_fail) 추가 — 5회 연속 실패 시"진도 보고 연속 실패 — 세션이 만료됐을 수 있습니다"오류로 조기 종료 - 장시간 강의(1~2시간) 재생 중 세션 만료로 이후 모든 진도 보고가 무효화되는 상황 방지
- 연속 실패 카운터(
- Plan A frame 언로드 시 Plan B 자동 전환 (
src/player/background_player.py)- 기존: 재생 중 video frame이 언로드되면 미완료 상태에서 루프 종료
- 수정: 재생 미완료(현재 위치 < 종료 기준) 상태에서 언로드 시
_play_via_progress_api()(Plan B)로 자동 전환
- attendance_items API 비정상 응답 처리 강화 (
src/player/background_player.py)- 기존: 403/404 등 비정상 응답에서
json.loads()실패 예외가 실제 HTTP 상태코드 원인을 가림 - 수정: 200 이외 응답에서 JSON 파싱 건너뛰고 상태코드를 직접 로깅 — 403은 출석 기간 미개방으로 명시
- 기존: 403/404 등 비정상 응답에서
_parse_player_urlendat 파싱 오류 방어 (src/player/background_player.py)endat=abc등 비정상 값에서ValueError가 호출 스택으로 전파되던 문제 수정 —try-except로 감싸 파싱 실패 시0.0폴백
사전 요구사항
설치 및 실행
-
아래 첨부 파일(
docker-compose.yml,.env.example) 다운로드 -
.env.example→.env로 이름 변경 후 필요한 값 설정 (학번/비밀번호는 첫 실행 시 자동 저장) -
이미지 pull 및 실행
docker compose pull
docker compose run --rm study-helper
docker compose up사용 금지 — 로그 멀티플렉싱으로 TUI가 깨집니다.run --rm만 사용하세요.
Docker Hub
docker pull igor0670/study-helper:v26.04.04study-helper v26.04.03
study-helper v26.04.03
숭실대학교 LMS 강의 영상 재생 · 다운로드 · AI 요약 도구.
패치노트
수정
- 텔레그램 파일 전송 실패 시 무음 처리 문제 수정 (
src/notifier/telegram_notifier.py)- 기존:
_send_document()의except Exception: return False로 모든 오류가 무음 처리되어 파일 미전송 원인 파악 불가 - 수정: 파일 없음 / 크기 초과(50 MB) / HTTP 오류 / 예외 각각에 대해
stderr출력 추가
- 기존:
- LMS 로그인 실패 문제 수정 —
/?리다이렉트 미감지 (src/auth/login.py,src/player/background_player.py,src/scraper/course_scraper.py)- 원인: Canvas가 미인증 상태에서
login문자열 없는 URL(/?)로 리다이렉트할 경우 기존"login" in page.url체크로는 감지 불가 → 로그인 성공으로 오판 _needs_login()추가: URL 체크와.login_btn버튼 존재 여부를 함께 확인하여/?리다이렉트 케이스 포함 감지expect_navigation방식 → 10초 폴링 방식(_wait_for_login_result())으로 교체하여 네트워크 상태 무관하게 안정적 판정- 다이얼로그(alert) 자동 accept 및 실패 감지 추가
- 로그인 오류 문구 텍스트 감지 추가 (
_has_login_error_text()) background_player.py,course_scraper.py의 세션 만료 감지 로직도_needs_login()사용으로 통일
- 원인: Canvas가 미인증 상태에서
사전 요구사항
설치 및 실행
-
아래 첨부 파일(
docker-compose.yml,.env.example) 다운로드 -
.env.example→.env로 이름 변경 후 필요한 값 설정 (학번/비밀번호는 첫 실행 시 자동 저장) -
이미지 pull 및 실행
docker compose pull
docker compose run --rm study-helper
docker compose up사용 금지 — 로그 멀티플렉싱으로 TUI가 깨집니다.run --rm만 사용하세요.
Docker Hub
docker pull igor0670/study-helper:v26.04.03study-helper v26.04.02
study-helper v26.04.02
숭실대학교 LMS 강의 영상 재생 · 다운로드 · AI 요약 도구.
패치노트
수정
- V8 힙 상한 축소 (
src/scraper/course_scraper.py)--js-flags=--max-old-space-size=1024→512: 렌더러 프로세스당 V8 힙 상한을 절반으로 줄여 최대 1 GB 절감
- GPU 비디오 프레임 메모리 버퍼 비활성화 (
src/scraper/course_scraper.py)--disable-gpu-memory-buffer-video-frames추가: GPU 메모리 버퍼를 통한 비디오 프레임 처리 비활성화
canPlayType오버라이드 누적 등록 문제 수정 (src/scraper/course_scraper.py,src/player/background_player.py)- 기존:
play_lecture()호출마다page.add_init_script()로 동일한 H.264 위장 스크립트가 페이지에 누적 등록 (강의 N개 = N회 등록, 이후 모든 페이지 이동 시 N번 재실행) - 수정:
CourseScraper._setup_browser()의context.add_init_script()로 이동하여 브라우저 컨텍스트 생성 시 1회만 등록
- 기존:
- 자동 모드 사이클 완료 후 브라우저 재시작 (
src/ui/auto.py)- 원인: Chromium의 PartitionAlloc 메모리 할당자가 강의 재생 중 확보한 메모리를 OS에 반환하지 않고 내부 풀로 보유 —
about:blank이동만으로는 해소되지 않아 사이클마다 점유량이 누적 증가 - 스케줄 사이클에서 강의 처리 완료 후
scraper.close()→scraper.start()로 Chromium 프로세스를 완전 교체하여 메모리 풀 초기화 - 재시작 실패 시 예외 처리 후 기존 브라우저로 다음 사이클 계속 진행
- 원인: Chromium의 PartitionAlloc 메모리 할당자가 강의 재생 중 확보한 메모리를 OS에 반환하지 않고 내부 풀로 보유 —
사전 요구사항
설치 및 실행
-
아래 첨부 파일(
docker-compose.yml,.env.example) 다운로드 -
.env.example→.env로 이름 변경 후 필요한 값 설정 (학번/비밀번호는 첫 실행 시 자동 저장) -
이미지 pull 및 실행
docker compose pull
docker compose run --rm study-helper
docker compose up사용 금지 — 로그 멀티플렉싱으로 TUI가 깨집니다.run --rm만 사용하세요.
Docker Hub
docker pull igor0670/study-helper:v26.04.02study-helper v26.03.18
study-helper v26.03.18
숭실대학교 LMS 강의 영상 재생 · 다운로드 · AI 요약 도구.
패치노트
수정
- README curl 다운로드 경로 수정 (
README.md)- GitHub 사용자명 오기 수정:
igor0670→HelloJamong .env.example다운로드 URL:default.env.example→.env.example(릴리즈 asset 파일명 일치)
- GitHub 사용자명 오기 수정:
- 릴리즈 asset 파일명 수정 (
.github/workflows/release.yml)- 릴리즈 업로드 파일명이
default.env.example로 올라가던 문제 수정 —.env.example로 통일
- 릴리즈 업로드 파일명이
사전 요구사항
설치 및 실행
-
아래 첨부 파일(
docker-compose.yml,.env.example) 다운로드 -
.env.example→.env로 이름 변경 후 필요한 값 설정 (학번/비밀번호는 첫 실행 시 자동 저장) -
이미지 pull 및 실행
docker compose pull
docker compose run --rm study-helper
docker compose up사용 금지 — 로그 멀티플렉싱으로 TUI가 깨집니다.run --rm만 사용하세요.
Docker Hub
docker pull igor0670/study-helper:v26.03.18