여러 Google Classroom 클래스에 같은 공지를 한 번에 올리고, 이미 올린 공지를 여러 클래스에서 한꺼번에 수정·삭제하는 Windows 데스크탑 앱입니다.
Classroom 웹 UI는 여러 클래스에 동시 게시는 되지만, 올린 뒤 일괄 수정하는 기능이 없습니다. 이 앱은 게시 이력을 로컬 SQLite에 보관해서 "어떤 공지를 어느 클래스에 올렸는지"를 추적하고, 그걸 근거로 일괄 작업을 수행합니다.
| 기능 | 설명 |
|---|---|
| 다중 클래스 게시 | 검색·전체선택으로 클래스를 고르고 한 번에 게시. 부분 실패 시 실패분만 재시도 |
| 일괄 수정 | 올린 공지의 본문·예약시각을 모든 클래스에서 한 번에 변경 |
| 일괄 삭제 | 모든 클래스에서 삭제. 로컬 이력은 '삭제됨'으로 보존 |
| 첨부파일 · 링크 · YouTube | 파일은 Drive에 자동 업로드 후 첨부 (여러 클래스에 올려도 업로드는 1회) |
| 예약 게시 | Classroom 네이티브 예약 + 앱이 켜져 있을 때 미발행 보정 |
| 자주 쓰는 공지 | 작성 중인 내용 또는 이미 올린 공지를 템플릿으로 저장하고 재사용 |
| 클래스별 방문 | 각 클래스의 공지로 바로 이동 (댓글 확인용) |
Python 3.10 이상만 있으면 됩니다. 런처가 가상 환경 생성과 패키지 설치를 알아서 처리하므로, 처음 실행할 때 한 번만 몇 분 기다리면 됩니다.
Windows
run.cmd
탐색기에서 run.cmd를 더블클릭해도 됩니다. PowerShell에서는 .\run.cmd 로 실행하세요.
Linux / macOS
chmod +x run.sh # 처음 한 번만
./run.shWindows용으로 빌드된 단일 실행 파일을 쓴다면 Python 없이 바로 실행할 수 있습니다:
dist\Classroom공지관리자.exe
수동으로 설치하려면
python -m venv .venv
.\.venv\Scripts\python.exe -m pip install -r requirements.txt
.\.venv\Scripts\python.exe run.pyLinux/macOS는 .venv/bin/python 을 사용하세요.
Linux 참고: PySide6는 시스템 라이브러리를 요구합니다.
run.sh가 부족한 경우를 감지해 필요한 패키지를 알려줍니다. Ubuntu/Debian 기준:sudo apt install libegl1 libxkbcommon-x11-0 libgl1 libxcb-cursor0
앱 안 설정 화면에도 같은 안내가 들어 있습니다.
- Google Cloud Console에서 새 프로젝트를 만듭니다.
- API 및 서비스 → 라이브러리에서 다음 두 API를 사용 설정합니다.
- OAuth 동의 화면 → User Type을 내부로 선택합니다. (학교 Workspace 계정이면 검증 절차·경고 화면 없이 사용 가능)
- 사용자 인증 정보 → OAuth 클라이언트 ID → 애플리케이션 유형 데스크톱 앱 → JSON 다운로드.
- 앱의 설정 화면에서 그 JSON을 지정하고 Google 계정으로 로그인을 누릅니다.
요청 권한(최소):
| 스코프 | 용도 |
|---|---|
classroom.courses.readonly |
내가 교사인 클래스 목록 조회 |
classroom.announcements |
공지 생성·조회·수정·삭제 |
drive.file |
이 앱이 업로드한 파일만 접근 (기존 Drive 전체 아님) |
userinfo.email |
로그인 계정 표시 + 학교 도메인 자동 추출 |
학교 Workspace 관리자가 API 접근을 제한해 둔 경우, 관리 콘솔 → 보안 → API 제어 → 앱 액세스 제어에서 해당 OAuth 클라이언트 ID를 신뢰할 수 있는 앱으로 등록해야 할 수 있습니다.
앱 설계에 직접 영향을 주는, 공식 문서로 확인된 제약입니다.
1. 공지 댓글은 API로 읽을 수 없습니다. Classroom API v1 리소스 목록에 댓글 관련 엔드포인트가 없습니다. 따라서 앱 안에서 댓글을 모아 볼 수 없습니다. 대신 이력 화면의 [모든 클래스 열기] 로 각 공지를 브라우저에서 열어 확인합니다.
2. 수정은 본문·상태·예약시각만 가능합니다.
courses.announcements.patch의 updateMask가 받는 필드는 text, state, scheduledTime 뿐입니다. 첨부(materials)는 수정할 수 없습니다. 첨부를 바꾸려면 이력 화면의 [첨부 변경] 을 사용해 기존 공지를 삭제하고 새로 올려야 하며, 이 경우:
- 학생들에게 새 알림이 다시 갑니다
- 기존 공지의 댓글이 사라집니다
- 기존 방문 링크가 무효가 됩니다
앱이 실행 전에 이 내용을 경고하고 명시적 동의를 받습니다.
3. 이 앱으로 올린 공지만 수정·삭제할 수 있습니다.
공지를 만든 개발자 프로젝트만 수정이 허용되며, 그 외에는 PERMISSION_DENIED가 반환됩니다. Classroom 웹이나 다른 앱에서 올린 공지는 이 앱으로 고칠 수 없습니다.
4. 첨부 파일은 별도 공유가 필요합니다.
Drive 파일을 첨부할 때 shareMode: VIEW만으로는 부족해서, 업로드 직후 학교 도메인 전체에 읽기 권한을 부여합니다. 도메인 공유가 정책상 막혀 있으면 '링크가 있는 모든 사용자'로 폴백하고 경고를 표시합니다(모르는 채로 외부 공개되지 않도록).
| 플랫폼 | 경로 |
|---|---|
| Windows | %LOCALAPPDATA%\gcrmanager\ |
| macOS | ~/Library/Application Support/gcrmanager/ |
| Linux | $XDG_DATA_HOME/gcrmanager/ (기본 ~/.local/share/gcrmanager/) |
gcrmanager/
├── gcrmanager.db 이력 DB (일괄 수정·삭제의 근거)
├── gcrmanager.log 로그
└── backups/ 앱 실행 시 자동 백업 (최근 5개)
정확한 경로는 앱의 설정 → 5. 데이터 에 표시되며 [데이터 폴더 열기] 버튼으로 바로 열 수 있습니다.
인증 토큰은 파일이 아니라 OS 자격 증명 저장소(keyring)에 보관됩니다 — Windows 자격 증명 관리자, macOS 키체인, Linux Secret Service.
gcrmanager.db를 잃으면 일괄 수정·삭제 대상을 추적할 수 없습니다(Classroom 쪽 공지는 그대로 남습니다). 앱이 실행할 때마다 자동 백업하지만, 중요한 경우 이 폴더를 따로 백업하세요.
.\.venv\Scripts\python.exe -m pip install -r requirements-dev.txt
.\.venv\Scripts\python.exe -m pytest # 단위 테스트 (실제 API 호출 없음)
.\.venv\Scripts\python.exe build.py # 단일 exe 빌드 → dist\구조:
gcrmanager/
├── config.py 경로·스코프·API 제약 상수
├── auth.py OAuth 로컬서버 플로우 + keyring
├── api/ Google API 래퍼 (errors/client/classroom/drive)
├── db/ SQLite 스키마·마이그레이션·쿼리
├── services/ 게시·수정·템플릿·예약 (Qt 비의존 → 테스트 용이)
├── workers.py QThreadPool 워커 (UI 블록 방지)
└── ui/ PySide6 화면
services/는 Qt에 의존하지 않아 그냥 호출해 테스트할 수 있습니다. 모든 API 호출은 workers.py를 통해 백그라운드 스레드에서 실행되어 UI가 멈추지 않습니다.