docs: translate README to Chinese
This commit is contained in:
303
README.md
303
README.md
@@ -1,120 +1,153 @@
|
|||||||
# Temp File Transfer Service
|
# 临时文件传输服务
|
||||||
|
|
||||||
A Flask-based personal temporary file sharing service with a Web UI, API access, and SQLite-backed metadata.
|
基于 Flask 的个人临时文件分享服务,支持 Web 界面、API 接口和 SQLite 数据库。
|
||||||
|
|
||||||
What it does
|
## 功能介绍
|
||||||
- Upload files via a Web UI or an API endpoint
|
|
||||||
- Choose an expiry: 1 hour, 24 hours, or 7 days
|
- 通过 Web 界面或 API 接口上传文件
|
||||||
- Generate a share URL (UUID) for downloaded access
|
- 选择过期时间:1 小时、24 小时或 7 天
|
||||||
- File data stored on disk; metadata stored in SQLite
|
- 生成分享链接(UUID)供下载使用
|
||||||
- Web-based download page and a simple API for programmatic uploads
|
- 文件数据存储在磁盘,元数据存储在 SQLite
|
||||||
|
- Web 下载页面和简单的 API 接口支持程序化上传
|
||||||
|
|
||||||
|
## 技术栈
|
||||||
|
|
||||||
Tech stack
|
|
||||||
- Flask (Python)
|
- Flask (Python)
|
||||||
- SQLite (metadata)
|
- SQLite (元数据存储)
|
||||||
- Filesystem storage for actual file data
|
- 文件系统存储实际文件数据
|
||||||
|
|
||||||
Local development setup
|
## 本地开发环境搭建
|
||||||
1. Prerequisites
|
|
||||||
- Python 3.8+ (the project currently uses Python 3.x in this environment)
|
### 1. 环境要求
|
||||||
|
|
||||||
|
- Python 3.8+ (当前环境使用 Python 3.x)
|
||||||
- pip
|
- pip
|
||||||
|
|
||||||
2. Install dependencies
|
### 2. 安装依赖
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
pip install -r requirements.txt
|
pip install -r requirements.txt
|
||||||
```
|
```
|
||||||
|
|
||||||
3. Run the server
|
### 3. 运行服务
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
python app.py
|
python app.py
|
||||||
```
|
```
|
||||||
|
|
||||||
4. Access
|
### 4. 访问地址
|
||||||
- Web UI: http://localhost:5000
|
|
||||||
- API: see /api/upload and /api/file endpoints
|
|
||||||
|
|
||||||
Deployment
|
- Web 界面: http://localhost:5000
|
||||||
|
- API 接口: 详见 /api/upload 和 /api/file 接口
|
||||||
|
|
||||||
The production instance runs at:
|
## 部署说明
|
||||||
- **Domain**: `xiaji-temp.duckdns.org`
|
|
||||||
- **HTTPS**: Let's Encrypt SSL with auto-renewal (certbot timer)
|
|
||||||
- **Nginx**: reverse proxy with 500MB upload limit, 80→443 redirect
|
|
||||||
- **Gunicorn**: 4 workers, systemd-managed
|
|
||||||
|
|
||||||
Project layout
|
生产环境部署信息:
|
||||||
- app.py # Flask application
|
|
||||||
- config.py # Configuration constants
|
|
||||||
- database.py # SQLite helpers and data access
|
|
||||||
- requirements.txt # Python dependencies
|
|
||||||
- templates/ # Jinja templates (index.html, download.html)
|
|
||||||
- upload_client.py # Simple API client example for testing
|
|
||||||
- uploads/ # Storage for uploaded files (created at runtime)
|
|
||||||
|
|
||||||
Data model (SQLite)
|
- **域名**: `xiaji-temp.duckdns.org`
|
||||||
- Table: files
|
- **HTTPS**: Let's Encrypt SSL 证书,自动续期 (certbot timer)
|
||||||
- id TEXT PRIMARY KEY
|
- **Nginx**: 反向代理,500MB 上传限制,80→443 自动跳转
|
||||||
- filename TEXT
|
- **Gunicorn**: 4 个工作者进程,systemd 管理
|
||||||
- filepath TEXT
|
|
||||||
- filesize INTEGER
|
|
||||||
- expiry_hours INTEGER
|
|
||||||
- created_at TIMESTAMP
|
|
||||||
- expires_at TIMESTAMP
|
|
||||||
|
|
||||||
Expiry and cleanup
|
## 项目结构
|
||||||
- Expiry options are defined as 1h, 24h, 7d in config
|
|
||||||
- A cleanup operation removes expired files from disk and deletes DB rows
|
|
||||||
- Cleanup is invoked on access endpoints (and can be wired to a cron/daemon later)
|
|
||||||
|
|
||||||
Traffic limits
|
| 文件 | 说明 |
|
||||||
- Maximum file size: 500 MB
|
|------|------|
|
||||||
- Per-IP daily traffic limit: 20 GB (upload + download combined)
|
| `app.py` | Flask 应用程序主文件 |
|
||||||
- IP traffic tracked in SQLite `ip_traffic` table, reset daily
|
| `config.py` | 配置常量 |
|
||||||
|
| `database.py` | SQLite 辅助函数和数据访问 |
|
||||||
|
| `requirements.txt` | Python 依赖包 |
|
||||||
|
| `templates/` | Jinja 模板 (index.html, download.html) |
|
||||||
|
| `upload_client.py` | 简单的 API 客户端示例,用于测试 |
|
||||||
|
| `uploads/` | 上传文件存储目录 (运行时创建) |
|
||||||
|
| `temp_file_trans_client/` | PySide6 桌面客户端 |
|
||||||
|
|
||||||
SSL certificate
|
## 桌面客户端
|
||||||
- Let's Encrypt certificate deployed via certbot
|
|
||||||
- Auto-renewal via systemd timer: `certbot.timer`
|
|
||||||
- Manual renewal test: `certbot renew --dry-run`
|
|
||||||
|
|
||||||
Security notes
|
使用 Python + PySide6 + PyInstaller 构建的桌面客户端,支持拖拽上传文件。
|
||||||
- Do not commit secrets. Secrets should be provided via environment variables in production.
|
|
||||||
- This repository currently avoids embedding credentials.
|
|
||||||
|
|
||||||
Next steps (optional)
|
### 客户端功能
|
||||||
- Add authentication for admin/API usage
|
|
||||||
- Add rate limiting and upload size limits per user
|
|
||||||
- Add automated tests and CI integration
|
|
||||||
|
|
||||||
License
|
- 拖拽文件到指定区域上传
|
||||||
- MIT or your preferred license (update as needed)
|
- 点击选择文件上传
|
||||||
|
- 显示上传进度
|
||||||
|
- 上传成功显示分享链接
|
||||||
|
- 支持复制链接到剪贴板
|
||||||
|
- 可配置服务器地址
|
||||||
|
|
||||||
API Usage (Python)
|
### 运行客户端
|
||||||
|
|
||||||
Upload a file via the API endpoint:
|
```bash
|
||||||
|
cd temp_file_trans_client
|
||||||
```python
|
pip install -r requirements.txt
|
||||||
import requests
|
python main.py
|
||||||
|
|
||||||
BASE_URL = "https://xiaji-temp.duckdns.org"
|
|
||||||
|
|
||||||
expiry = "24h" # 1h, 24h, 7d
|
|
||||||
|
|
||||||
with open("/path/to/your/file.zip", "rb") as f:
|
|
||||||
resp = requests.post(
|
|
||||||
f"{BASE_URL}/api/upload",
|
|
||||||
files={"file": ("file.zip", f)},
|
|
||||||
data={"expiry": expiry},
|
|
||||||
)
|
|
||||||
|
|
||||||
if resp.status_code == 200:
|
|
||||||
data = resp.json()
|
|
||||||
print(f"Share URL: {data['share_url']}")
|
|
||||||
print(f"File ID: {data['id']}")
|
|
||||||
print(f"Size: {data['filesize']} bytes")
|
|
||||||
else:
|
|
||||||
print(f"Upload failed: {resp.json()['error']}")
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Response format:
|
### 打包为 exe
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd temp_file_trans_client
|
||||||
|
pip install pyinstaller
|
||||||
|
pyinstaller build.spec
|
||||||
|
```
|
||||||
|
|
||||||
|
打包后的可执行文件位于 `dist/temp_file_trans_client.exe`
|
||||||
|
|
||||||
|
## 数据模型 (SQLite)
|
||||||
|
|
||||||
|
**files 表结构:**
|
||||||
|
|
||||||
|
| 字段 | 类型 | 说明 |
|
||||||
|
|------|------|------|
|
||||||
|
| id | TEXT PRIMARY KEY | 文件唯一标识 (UUID) |
|
||||||
|
| filename | TEXT | 原始文件名 |
|
||||||
|
| filepath | TEXT | 文件存储路径 |
|
||||||
|
| filesize | INTEGER | 文件大小 (字节) |
|
||||||
|
| expiry_hours | INTEGER | 过期时间 (小时) |
|
||||||
|
| created_at | TIMESTAMP | 创建时间 |
|
||||||
|
| expires_at | TIMESTAMP | 过期时间 |
|
||||||
|
|
||||||
|
## 过期清理
|
||||||
|
|
||||||
|
- 过期选项在 config 中定义为 1h、24h、7d
|
||||||
|
- 清理操作会删除过期文件并清理数据库记录
|
||||||
|
- 访问接口时自动触发清理 (后续可配置 cron/定时任务)
|
||||||
|
|
||||||
|
## 流量限制
|
||||||
|
|
||||||
|
- 最大文件大小:500 MB
|
||||||
|
- 单 IP 每日流量限制:20 GB (上传 + 下载合计)
|
||||||
|
- IP 流量记录在 SQLite `ip_traffic` 表中,每日重置
|
||||||
|
|
||||||
|
## SSL 证书
|
||||||
|
|
||||||
|
- 使用 Let's Encrypt 证书,通过 certbot 部署
|
||||||
|
- 自动续期通过 systemd timer: `certbot.timer`
|
||||||
|
- 手动测试续期: `certbot renew --dry-run`
|
||||||
|
|
||||||
|
## 安全说明
|
||||||
|
|
||||||
|
- 请勿提交密钥等敏感信息。生产环境应通过环境变量提供
|
||||||
|
- 当前仓库未嵌入任何凭证
|
||||||
|
|
||||||
|
## API 接口说明
|
||||||
|
|
||||||
|
### 上传文件
|
||||||
|
|
||||||
|
```
|
||||||
|
POST /api/upload
|
||||||
|
Content-Type: multipart/form-data
|
||||||
|
```
|
||||||
|
|
||||||
|
**请求参数:**
|
||||||
|
|
||||||
|
| 参数 | 类型 | 必填 | 说明 |
|
||||||
|
|------|------|------|------|
|
||||||
|
| file | File | 是 | 要上传的文件 |
|
||||||
|
| expiry | String | 否 | 过期时间: 1h / 24h / 7d (默认 24h) |
|
||||||
|
|
||||||
|
**返回示例:**
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"id": "550e8400-e29b-41d4-a716-446655440000",
|
"id": "550e8400-e29b-41d4-a716-446655440000",
|
||||||
@@ -125,23 +158,91 @@ Response format:
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Get file info via API:
|
### 获取文件信息
|
||||||
```python
|
|
||||||
resp = requests.get(f"{BASE_URL}/api/file/{file_id}")
|
```
|
||||||
if resp.status_code == 200:
|
GET /api/file/{file_id}
|
||||||
info = resp.json()
|
|
||||||
print(f"Daily upload: {info['daily_upload']} bytes")
|
|
||||||
print(f"Daily download: {info['daily_download']} bytes")
|
|
||||||
print(f"Traffic limit: {info['traffic_limit']} bytes (20GB)")
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Or use the bundled client script:
|
**返回示例:**
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "550e8400-e29b-41d4-a716-446655440000",
|
||||||
|
"filename": "file.zip",
|
||||||
|
"filesize": 1048576,
|
||||||
|
"created_at": "2024-01-15 10:30:00",
|
||||||
|
"expires_at": "2024-01-16 10:30:00",
|
||||||
|
"daily_upload": 1048576,
|
||||||
|
"daily_download": 0,
|
||||||
|
"traffic_limit": 21474836480
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 下载文件
|
||||||
|
|
||||||
|
```
|
||||||
|
GET /file/{file_id}
|
||||||
|
GET /download/{file_id}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Python API 调用示例
|
||||||
|
|
||||||
|
### 上传文件
|
||||||
|
|
||||||
|
```python
|
||||||
|
import requests
|
||||||
|
|
||||||
|
BASE_URL = "https://xiaji-temp.duckdns.org"
|
||||||
|
|
||||||
|
expiry = "24h" # 可选: 1h, 24h, 7d
|
||||||
|
|
||||||
|
with open("/path/to/your/file.zip", "rb") as f:
|
||||||
|
resp = requests.post(
|
||||||
|
f"{BASE_URL}/api/upload",
|
||||||
|
files={"file": ("file.zip", f)},
|
||||||
|
data={"expiry": expiry},
|
||||||
|
verify=False # 对于自签名证书
|
||||||
|
)
|
||||||
|
|
||||||
|
if resp.status_code == 200:
|
||||||
|
data = resp.json()
|
||||||
|
print(f"分享链接: {data['share_url']}")
|
||||||
|
print(f"文件 ID: {data['id']}")
|
||||||
|
print(f"文件大小: {data['filesize']} bytes")
|
||||||
|
else:
|
||||||
|
print(f"上传失败: {resp.json()['error']}")
|
||||||
|
```
|
||||||
|
|
||||||
|
### 获取文件信息
|
||||||
|
|
||||||
|
```python
|
||||||
|
resp = requests.get(f"{BASE_URL}/api/file/{file_id}", verify=False)
|
||||||
|
if resp.status_code == 200:
|
||||||
|
info = resp.json()
|
||||||
|
print(f"每日上传: {info['daily_upload']} bytes")
|
||||||
|
print(f"每日下载: {info['daily_download']} bytes")
|
||||||
|
print(f"流量限制: {info['traffic_limit']} bytes (20GB)")
|
||||||
|
```
|
||||||
|
|
||||||
|
## 使用客户端脚本
|
||||||
|
|
||||||
|
也可以直接使用附带的客户端脚本上传文件:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
python upload_client.py /path/to/file.zip 24h
|
python upload_client.py /path/to/file.zip 24h
|
||||||
```
|
```
|
||||||
|
|
||||||
Contributing
|
## 后续计划
|
||||||
- Pull requests are welcome. Please follow the project style and ensure tests pass.
|
|
||||||
|
|
||||||
Contact
|
- [ ] 添加管理员/API 认证
|
||||||
- If you need to reach the maintainer, use your preferred channel.
|
- [ ] 添加用户级别的速率限制和上传大小限制
|
||||||
|
- [ ] 添加自动化测试和 CI/CD 集成
|
||||||
|
|
||||||
|
## 许可证
|
||||||
|
|
||||||
|
MIT 许可证 (或您偏好的许可证,按需更新)
|
||||||
|
|
||||||
|
## 联系方式
|
||||||
|
|
||||||
|
如需联系维护者,请使用您偏好的渠道。
|
||||||
Reference in New Issue
Block a user