Skip to content

About

오늘의 급식과 학사일정을 포스트잇처럼 보여주는 크로스플랫폼 데스크톱 위젯 (NEIS 개방포털 API)

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

급식쪽지 (SchoolNote)

오늘 우리 학교의 급식 메뉴와 학사일정을,
책상 위 포스트잇처럼 바탕화면에 붙여두는 무료 데스크톱 위젯

🌐 홈페이지 · ⬇ 다운로드

Screenshot


✨ 특징

  • 포스트잇 UI — 제목표시줄 없는 반투명 창. 드래그로 원하는 곳에 붙여두면 위치가 기억됩니다.
  • 트레이 상주 — 숨겨도 트레이 아이콘은 항상 남습니다. 클릭하면 다시 표시.
  • 자동 갱신 — 자정이 지나면 스스로 그날 정보를 가져옵니다.
  • 날짜 탐색 — 마우스 휠이나 ‹ › 버튼으로 날짜를 넘깁니다. 한 번 본 날은 캐시에서 바로 뜹니다.
  • 달력에서 고르기 — 날짜를 누르면 달력이 펼쳐집니다. 급식이 있는 날은 조식·중식·석식이 각각 점으로, 일정이 있는 날은 밑줄로 표시됩니다.
  • 식사 시간에 맞춰 보기 — 켜 두면 지난 식사는 숨기고 지금·다음 식사부터 보여 줍니다. 점심이 끝나면 내일 점심이 뜹니다. 식사 시간대는 직접 정할 수 있습니다.
  • 알레르기 경고 — 내 알레르기가 들어간 음식을 재료까지 빨갛게 강조합니다.
  • 재료·원산지 — 포스트잇을 클릭하면 원산지·영양 정보가 펼쳐집니다.
  • 자동 시작 — 설정에서 켜두면 컴퓨터를 켤 때 함께 실행됩니다.
  • 업데이트 확인 — 설정 › 정보 탭에서 버튼을 누를 때만 최신 버전을 확인하고, 동의하면 내려받아 교체한 뒤 다시 실행합니다. 몰래 도는 백그라운드 확인은 없습니다.
  • 인증키 불필요 — NEIS 공개 API를 그대로 사용합니다. 바로 쓸 수 있습니다.
  • 서버 없음 — 앱이 NEIS API를 직접 호출합니다. 개인정보가 어디로도 전송되지 않습니다.
  • 크로스플랫폼 — Windows / macOS / Linux

🚀 시작하기

실행 파일로 바로 사용 (권장)

최신 릴리스에서 운영체제에 맞는 파일 하나만 받으면 됩니다. 압축을 풀 필요가 없습니다.

OS 파일 실행 방법
Windows SchoolNote-*-windows-x64.exe 받은 파일을 더블클릭
macOS SchoolNote-*-macos.dmg 열어서 급식쪽지를 Applications로 끌어다 놓기
Linux SchoolNote-*-linux-x64 chmod +x 후 실행 (브라우저가 실행 권한을 떼어 냅니다)

처음 실행할 때 경고가 뜰 수 있습니다. 코드 서명이 없는 무료 앱이라서입니다.

  • Windows "PC 보호" 창 → 추가 정보 → 실행
  • macOS "확인되지 않은 개발자" → 앱을 우클릭 → 열기 (한 번만 하면 됩니다)

처음 실행하면 설정 창이 열립니다. 학교 탭에서 학교를 검색해 선택하면 바로 급식이 표시됩니다.

소스에서 직접 실행

Windows — run.bat을 두 번 클릭

macOS / Linux

./run.sh

직접 실행

python -m venv .venv
source .venv/bin/activate  # Windows: .venv\Scripts\activate
pip install -r requirements.txt
python -m app

🗂 프로젝트 구조

schoollunchmemo/
├─ app/
│  ├─ __main__.py          # 진입점, 단일 인스턴스 보장, 로깅
│  ├─ controller.py        # 전체 흐름 조율 (조회 → 렌더 → 상태 표시)
│  ├─ tray.py              # 트레이 아이콘과 메뉴
│  ├─ sticky.py            # 포스트잇 위젯
│  ├─ calendar_popup.py    # 달력 팝업 (급식·일정 표시)
│  ├─ settings_dialog.py   # 설정 창 (학교 / 표시 / 알레르기 / 정보)
│  ├─ config.py            # 설정 로드·저장
│  ├─ autostart.py         # 부팅 시 자동 시작 등록
│  ├─ cache.py             # 날짜 단위 응답 캐시
│  ├─ allergens.py         # 알레르기 19종 코드와 매칭
│  ├─ scheduler.py         # 자정 롤오버 감지
│  ├─ updater.py           # GitHub 릴리스 확인·교체 (수동 트리거)
│  ├─ workers.py           # 백그라운드 작업 실행기
│  ├─ neis/
│  │  ├─ client.py         # HTTP 호출, 타임아웃, 재시도
│  │  ├─ codes.py          # RESULT.CODE 분류
│  │  ├─ models.py         # School / MealMenu / ScheduleEvent
│  │  └─ parser.py         # 응답 정규화
│  └─ resources/
│     ├─ icons.py          # 아이콘 생성 (바이너리 없음)
│     └─ theme.py          # 포스트잇 색상 팔레트
├─ assets/                 # 실행 파일용 아이콘 (.ico/.icns)
├─ scripts/                # 아이콘 생성 등 개발 보조 스크립트
├─ docs/                   # GitHub Pages 홈페이지
├─ tests/
├─ run.bat                 # Windows 실행 스크립트
├─ run.sh                  # macOS / Linux 실행 스크립트
├─ schoolnote.spec         # PyInstaller 빌드 설정
├─ requirements.txt
└─ requirements-dev.txt

⚙️ 동작 원리

컨트롤러가 유일한 조율자입니다. UI 위젯은 시그널만 보내고, 네트워크는 워커 스레드에서만 돌며, 결과는 다시 컨트롤러를 거쳐 화면으로 돌아옵니다.

graph TB
    subgraph UI["UI (메인 스레드)"]
        TRAY[트레이 아이콘]
        NOTE[포스트잇 위젯]
        CAL[달력 팝업]
        DLG[설정 창]
    end

    CTRL[AppController<br/>controller.py]

    subgraph DATA["데이터 계층"]
        CACHE[날짜·월 캐시<br/>cache.py]
        CLIENT[NeisClient<br/>neis/client.py]
        PARSER[정규화<br/>neis/parser.py]
    end

    WORK[워커 스레드풀<br/>workers.py]
    NEIS[(NEIS Open API)]

    TRAY & NOTE & CAL & DLG -- "Qt 시그널" --> CTRL
    CTRL -- "캐시 우선" --> CACHE
    CTRL -- "미스 시" --> WORK
    WORK --> CLIENT
    CLIENT -- "HTTPS (인증키 없음)" --> NEIS
    CTRL --> PARSER
    CTRL -- "렌더" --> NOTE & CAL
Loading

하루치 조회는 이렇게 흐릅니다. 같은 날을 다시 보면 네트워크를 타지 않습니다.

sequenceDiagram
    autonumber
    actor U as 사용자/자정 스케줄러
    participant C as AppController
    participant K as 캐시
    participant N as NeisClient (워커)
    participant API as NEIS API
    participant S as 포스트잇

    U->>C: refresh()
    C->>K: load(학교, 날짜)
    alt 캐시 있음
        K-->>C: 저장된 rows
    else 캐시 없음
        C->>N: fetch_day() — 백그라운드
        N->>API: 급식·학사일정 조회
        API-->>N: JSON rows
        N-->>C: 시그널로 전달 (UI 안 멈춤)
        C->>K: save(rows)
    end
    C->>C: 파싱·알레르기 매칭<br/>(빈 식단 row는 걸러짐)
    C->>S: 렌더
Loading

더 자세한 설계는 PRD 7장에 있습니다.


🧪 테스트

pip install -r requirements-dev.txt
pytest -q

📦 빌드

pip install -r requirements-dev.txt
pyinstaller schoolnote.spec --noconfirm

Windows는 dist/SchoolNote.exe, Linux는 dist/SchoolNote 파일 하나가 나옵니다 (onefile). macOS는 .app이 원래 폴더라 dist/SchoolNote.app 번들을 만들고, 배포 때 .dmg로 쌉니다. macOS / Linux는 해당 OS에서 직접 빌드해야 합니다 (크로스 빌드 불가).
태그를 push하면 GitHub Actions가 세 플랫폼을 자동 빌드합니다.


🔌 사용하는 API

NEIS 교육정보 개방 포털 공개 API (인증키 불필요, 일 1000건 제한)

서비스 엔드포인트 용도
학교기본정보 /hub/schoolInfo 학교 검색
급식식단정보 /hub/mealServiceDietInfo 급식 조회
학사일정 /hub/SchoolSchedule 행사·일정 조회

상세 파라미터와 응답 항목은 PRD 6장에 정리돼 있습니다.


🗺 로드맵

  • v0.1 (MVP) — 포스트잇 위젯, 트레이, 학교 검색, 자동 갱신, Windows 빌드
  • v0.2 — 표시 옵션 전체, 자동 시작, 실행 스크립트, macOS/Linux 빌드
  • v0.3 — 달력으로 날짜 고르기, 정보 탭, 인증키 제거, 글자 크기 설정
  • v0.5.1 — 원산지에서 오늘 쓰인 재료만 강조, 업데이트 후 재실행 실패 수정
  • v0.5 — 식사 시간에 맞춰 보기, 학교 내부 표기 숨기기, 달력·검색 5건 제한 해소, 날짜 머리줄·검색 Enter·선택 색 수정
  • v0.4 — 업데이트 확인 버튼, '항상 위에 표시' 해제가 모든 OS에서 동작, 압축 없이 바로 실행 (.exe / .dmg / 단일 실행 파일)
  • 백로그 — 여러 학교 등록, 내일 급식 미리보기, 특정 메뉴 알림, 주간 요약

진행 상황은 이슈와 마일스톤에서 볼 수 있습니다.


⚖️ 라이선스 및 출처

MIT License — 자세한 내용은 LICENSE를 보세요. Copyright (c) 2026 Gihun Ham (@progh2)

  • 급식·학사일정 데이터: 교육부 NEIS 교육정보 개방 포털 (https://open.neis.go.kr)
  • 본 프로젝트는 교육부·시도교육청과 무관한 비공식 개인 프로젝트입니다.
  • 급식·알레르기 정보는 학교가 등록한 자료입니다. 참고용으로만 쓰고 최종 확인은 학교 공지를 따라 주세요.

About

오늘의 급식과 학사일정을 포스트잇처럼 보여주는 크로스플랫폼 데스크톱 위젯 (NEIS 개방포털 API)

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages