临时文件传输服务
基于 Flask 的个人临时文件分享服务,支持 Web 界面、API 接口和 SQLite 数据库。
功能介绍
- 通过 Web 界面或 API 接口上传文件
- 选择过期时间:1 小时、24 小时或 7 天
- 生成分享链接(UUID)供下载使用
- 文件数据存储在磁盘,元数据存储在 SQLite
- Web 下载页面和简单的 API 接口支持程序化上传
技术栈
- Flask (Python)
- SQLite (元数据存储)
- 文件系统存储实际文件数据
本地开发环境搭建
1. 环境要求
- Python 3.8+ (当前环境使用 Python 3.x)
- pip
2. 安装依赖
pip install -r requirements.txt
3. 运行服务
python app.py
4. 访问地址
- Web 界面: http://localhost:5000
- API 接口: 详见 /api/upload 和 /api/file 接口
部署说明
生产环境部署信息:
- 域名:
xiaji-temp.duckdns.org - HTTPS: Let's Encrypt SSL 证书,自动续期 (certbot timer)
- Nginx: 反向代理,500MB 上传限制,80→443 自动跳转
- Gunicorn: 4 个工作者进程,systemd 管理
项目结构
| 文件 | 说明 |
|---|---|
app.py |
Flask 应用程序主文件 |
config.py |
配置常量 |
database.py |
SQLite 辅助函数和数据访问 |
requirements.txt |
Python 依赖包 |
templates/ |
Jinja 模板 (index.html, download.html) |
upload_client.py |
简单的 API 客户端示例,用于测试 |
uploads/ |
上传文件存储目录 (运行时创建) |
temp_file_trans_client/ |
PySide6 桌面客户端 |
桌面客户端
使用 Python + PySide6 + PyInstaller 构建的桌面客户端,支持拖拽上传文件。
客户端功能
- 拖拽文件到指定区域上传
- 点击选择文件上传
- 显示上传进度
- 上传成功显示分享链接
- 支持复制链接到剪贴板
- 可配置服务器地址
运行客户端
cd temp_file_trans_client
pip install -r requirements.txt
python main.py
打包为 exe
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) |
返回示例:
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"filename": "file.zip",
"filesize": 1048576,
"expiry_hours": 24,
"share_url": "https://xiaji-temp.duckdns.org/file/550e8400..."
}
获取文件信息
GET /api/file/{file_id}
返回示例:
{
"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 调用示例
上传文件
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']}")
获取文件信息
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)")
使用客户端脚本
也可以直接使用附带的客户端脚本上传文件:
python upload_client.py /path/to/file.zip 24h
后续计划
- 添加管理员/API 认证
- 添加用户级别的速率限制和上传大小限制
- 添加自动化测试和 CI/CD 集成
许可证
MIT 许可证 (或您偏好的许可证,按需更新)
联系方式
如需联系维护者,请使用您偏好的渠道。
Description
Languages
Python
51.8%
HTML
26.1%
Rust
21.7%
Batchfile
0.4%