Skip to content

Commit ab71e42

Browse files
Initial commit
0 parents  commit ab71e42

17 files changed

Lines changed: 4413 additions & 0 deletions

.env.example

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
TUNNEL_TOKEN=your_tunnel_token_here
2+
SECRET_KEY=your_random_secret_string_here
3+
4+
TURNSTILE_SITE_KEY=your_turnstile_site_key_here
5+
TURNSTILE_SECRET_KEY=your_turnstile_secret_key_here

.github/workflows/deploy.yml

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
name: Deploy to VPS
2+
3+
on:
4+
push:
5+
branches: [ "main" ]
6+
7+
env:
8+
REGISTRY: ghcr.io
9+
IMAGE_NAME: ${{ github.repository }}
10+
11+
jobs:
12+
build_and_deploy:
13+
runs-on: ubuntu-latest
14+
permissions:
15+
contents: read
16+
packages: write
17+
18+
steps:
19+
- name: Checkout repository
20+
uses: actions/checkout@v4
21+
22+
- name: Set up Python
23+
uses: actions/setup-python@v5
24+
with:
25+
python-version: '3.11'
26+
27+
- name: Basic Syntax Check
28+
run: |
29+
python -m py_compile server.py
30+
python -m py_compile fetcher.py
31+
32+
- name: Log in to the Container registry
33+
uses: docker/login-action@v3
34+
with:
35+
registry: ${{ env.REGISTRY }}
36+
username: ${{ github.actor }}
37+
password: ${{ secrets.GITHUB_TOKEN }}
38+
39+
- name: Extract metadata (tags, labels) for Docker
40+
id: meta
41+
uses: docker/metadata-action@v5
42+
with:
43+
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
44+
tags: |
45+
type=raw,value=latest
46+
type=sha,format=long
47+
48+
- name: Build and push Docker image
49+
uses: docker/build-push-action@v5
50+
with:
51+
context: .
52+
push: true
53+
tags: ${{ steps.meta.outputs.tags }}
54+
labels: ${{ steps.meta.outputs.labels }}
55+
56+
- name: Deploy to VPS via SSH
57+
uses: appleboy/ssh-action@master
58+
with:
59+
host: ${{ secrets.VPS_HOST }}
60+
username: ${{ secrets.VPS_USERNAME }}
61+
key: ${{ secrets.VPS_SSH_KEY }}
62+
port: ${{ secrets.VPS_PORT }}
63+
script: |
64+
# 登入 GHCR
65+
echo "${{ secrets.GHCR_PAT }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin
66+
67+
# 使用明確 SHA tag 更新服務 (避免 latest 不觸發更新的問題)
68+
docker service update \
69+
--with-registry-auth \
70+
--image ghcr.io/${{ github.repository }}:sha-${{ github.sha }} \
71+
school_grades_app
72+
73+
# 等待更新完成並檢查狀態
74+
docker service ps school_grades_app --no-trunc --format "{{.CurrentState}}" | head -1

.gitignore

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# Python
2+
__pycache__/
3+
*.py[cod]
4+
*$py.class
5+
*.so
6+
.Python
7+
build/
8+
develop-eggs/
9+
dist/
10+
downloads/
11+
eggs/
12+
.eggs/
13+
lib/
14+
lib64/
15+
parts/
16+
sdist/
17+
var/
18+
wheels/
19+
share/python-wheels/
20+
*.egg-info/
21+
.installed.cfg
22+
*.egg
23+
MANIFEST
24+
25+
# Virtual Environment
26+
.env
27+
.venv
28+
env/
29+
venv/
30+
ENV/
31+
env.bak/
32+
venv.bak/
33+
34+
# Environment Variables (CRITICAL for security)
35+
.env
36+
37+
# Application Data & Temporary Files
38+
grades_raw.json
39+
shared_grades/
40+
*.json
41+
!requirements.txt
42+
!.env.example
43+
!package.json
44+
!manifest.json
45+
*.md
46+
!README.md
47+
# Exclude specific JSONs but allow config templates if any
48+
49+
# Large Files
50+
*.tar
51+
*.tar.gz
52+
53+
# Logs
54+
*.log
55+
56+
# Docker
57+
.dockerignore
58+
59+
# IDE & OS
60+
.idea/
61+
.vscode/
62+
.DS_Store
63+
Thumbs.db

Dockerfile

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
FROM python:3.11-slim
2+
3+
WORKDIR /app
4+
5+
# Install system dependencies (curl for healthcheck)
6+
RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/*
7+
8+
# Install Python dependencies
9+
COPY requirements.txt .
10+
RUN pip install --no-cache-dir -r requirements.txt
11+
12+
# Copy application code
13+
COPY . .
14+
15+
# Create necessary directories
16+
RUN mkdir -p shared_grades
17+
18+
# Expose port
19+
EXPOSE 5000
20+
21+
# Use gunicorn for production
22+
CMD ["gunicorn", "--bind", "0.0.0.0:5000", "--timeout", "120", "--workers", "5", "--threads", "4", "server:app"]

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2026 alvin000009238
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
# 成績分析平台 - 中大壢中
2+
3+
4+
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5+
6+
7+
> [!IMPORTANT]
8+
> 本專案為非官方開發之第三方服務,我們與壢中及欣河智慧校園平台無任何直接關聯。
9+
10+
本專案實作了自動化的成績查詢流程,全程透過原生的 HTTP 請求(使用 Python `requests` 模組)與學校系統的 API 介接,免去開啟實際瀏覽器的負擔。由於摒棄了複雜的網站前端渲染,它能提供非常快速且輕量化的連線體驗,並支援取得成績後建立分享連結的功能。
11+
12+
## Table of Contents
13+
14+
- [Background](#background)
15+
- [Install](#install)
16+
- [Usage](#usage)
17+
- [Maintainers](#maintainers)
18+
- [License](#license)
19+
20+
## Background
21+
22+
此專案開發初衷是為了解決複雜的成績查詢手續。應用程式負責打理自動登入驗證與建立 session,並藉由輕量型 API 接口處理後續的網路請求。這使得使用者能夠透過更為友善直觀的介面,快速查詢個人成績並與他人分享。
23+
24+
## Install
25+
26+
本專案**僅提供本地開發及部署環境教學**。你需要 Python 3.10+ 版本環境才能執行此專案。
27+
28+
### 1. 取得專案原始碼
29+
30+
```bash
31+
git clone https://github.com/alvin000009238/grades.git
32+
cd grades
33+
```
34+
35+
### 2. 環境變數設定
36+
37+
此專案需要設定特定的環境變數,請參考 `.env.example` 建立你自己的 `.env` 檔案。
38+
39+
Linux / macOS:
40+
```bash
41+
cp .env.example .env
42+
```
43+
44+
Windows (PowerShell):
45+
```powershell
46+
Copy-Item .env.example .env
47+
```
48+
49+
編輯 `.env`,設定例如 `SECRET_KEY` 的必要變數。
50+
51+
### 3. 設定 Python 虛擬環境並安裝依賴
52+
53+
強烈建議使用 [venv](https://docs.python.org/3/library/venv.html) 將本專案的依賴隔離於你的全域 Python 環境中:
54+
55+
```bash
56+
# 建立虛擬環境
57+
python -m venv venv
58+
59+
# 啟動虛擬環境 (Linux/macOS)
60+
source venv/bin/activate
61+
62+
# 啟動虛擬環境 (Windows PowerShell)
63+
.\venv\Scripts\Activate.ps1
64+
```
65+
66+
接著安裝必要的 Python 套件:
67+
68+
```bash
69+
# 安裝所有相依套件
70+
pip install -r requirements.txt
71+
```
72+
73+
## Usage
74+
75+
確保已經處於虛擬環境中(終端機介面前有 `(venv)` 標示)並且所有依賴都已正確安裝。
76+
77+
啟動 Flask 開發伺服器:
78+
79+
```bash
80+
python server.py
81+
```
82+
83+
在你的瀏覽器中開啟 `http://127.0.0.1:5000` 來使用此應用程式。
84+
85+
> [!WARNING]
86+
> 本應用預設以 `debug=True` 運行於 Flask 的內建伺服器(Development Server),這並不適合直接暴露於公共網路環境,也不適用於生產模式部署。
87+
88+
## Maintainers
89+
90+
[@alvin000009238](https://github.com/alvin000009238)
91+
92+
## License
93+
94+
[MIT](LICENSE) © 2026 alvin000009238

docker-compose.yml

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
services:
2+
app:
3+
image: ghcr.io/${GHCR_IMAGE:-alvin000009238/school_grades}:latest
4+
volumes:
5+
- ./shared_grades:/app/shared_grades
6+
environment:
7+
- PYTHONUNBUFFERED=1
8+
- SECRET_KEY=${SECRET_KEY}
9+
- TURNSTILE_SITE_KEY=${TURNSTILE_SITE_KEY}
10+
- TURNSTILE_SECRET_KEY=${TURNSTILE_SECRET_KEY}
11+
- TZ=Asia/Taipei
12+
13+
deploy:
14+
restart_policy:
15+
condition: any
16+
update_config:
17+
order: start-first
18+
failure_action: rollback
19+
delay: 10s
20+
healthcheck:
21+
test: [ "CMD", "curl", "-f", "http://localhost:5000/health" ]
22+
interval: 10s
23+
timeout: 5s
24+
retries: 3
25+
start_period: 10s
26+
27+
tunnel:
28+
image: cloudflare/cloudflared:latest
29+
command: tunnel run
30+
environment:
31+
- TUNNEL_TOKEN=${TUNNEL_TOKEN}
32+
deploy:
33+
restart_policy:
34+
condition: any

0 commit comments

Comments
 (0)