完成部分API路由以及文档
This commit is contained in:
12
.gitignore
vendored
Normal file
12
.gitignore
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
__pycache__/
|
||||
.pytest_cache/
|
||||
.venv/
|
||||
.env/
|
||||
.vscode/
|
||||
.VSCodeCounter/
|
||||
|
||||
*.py[cod]
|
||||
*.pyo
|
||||
*.pyd
|
||||
|
||||
*.code-workspace
|
||||
29
README.md
29
README.md
@@ -1,2 +1,27 @@
|
||||
# Server
|
||||
DiskNext 服务端。支持多家云存储的公私兼备的网盘系统。
|
||||
<h1 align="center">
|
||||
<br>
|
||||
DiskNext Server
|
||||
<br>
|
||||
</h1>
|
||||
|
||||
<h4 align="center">支持多家云存储的公私兼备的云服务系统.</h4>
|
||||
|
||||
本来此项目并没有这么快开始,但由于我曾经使用过的某个类似产品的作者吃相实在难看,故决定自己实现一个。
|
||||
|
||||
此项目的愿景是集百家之长(Cloudreve + Alist + FnOS)。你也可以考虑付费支持我们的发展 -> `DiskNext Pro`.
|
||||
|
||||
目前正处于 `OMEGA` 实验阶段,比 `Alpha` 版还更早期,仅供测试。
|
||||
|
||||
## :alembic: 技术栈
|
||||
|
||||
* [Python ](https://www.python.org/) + [FastAPI](https://fastapi.tiangolo.com/)
|
||||
|
||||
<!-- * [React](https://github.com/facebook/react) + [Redux](https://github.com/reduxjs/redux) + [Material-UI](https://github.com/mui-org/material-ui) -->
|
||||
|
||||
## :scroll: 许可证
|
||||
|
||||
GPL V3
|
||||
|
||||
---
|
||||
> GitHub [@Yuerchu](https://github.com/Yuerchu) ·
|
||||
> Twitter [@LaBoyXiaoXin](https://twitter.com/LaBoyXiaoXin)
|
||||
|
||||
29
main.py
Normal file
29
main.py
Normal file
@@ -0,0 +1,29 @@
|
||||
from fastapi import FastAPI
|
||||
from routers import routers
|
||||
from pkg.conf import appmeta
|
||||
|
||||
app = FastAPI(
|
||||
title=appmeta.APP_NAME,
|
||||
summary=appmeta.summary,
|
||||
description=appmeta.description,
|
||||
version=appmeta.BackendVersion,
|
||||
openapi_tags=appmeta.tags_meta,
|
||||
license_info=appmeta.license_info,
|
||||
|
||||
)
|
||||
|
||||
for router in routers.Router:
|
||||
app.include_router(
|
||||
router,
|
||||
prefix='/api',
|
||||
responses={
|
||||
200: {"description": "成功响应 Successful operation"},
|
||||
401: {"description": "未授权 Unauthorized"},
|
||||
403: {"description": "禁止访问 Forbidden"},
|
||||
404: {"description": "未找到 Not found"},
|
||||
500: {"description": "内部服务器错误 Internal server error"}
|
||||
},)
|
||||
|
||||
if __name__ == "__main__":
|
||||
import uvicorn
|
||||
uvicorn.run(app='main:app', host="0.0.0.0", port=5213, reload=True)
|
||||
30
middleware/auth.py
Normal file
30
middleware/auth.py
Normal file
@@ -0,0 +1,30 @@
|
||||
from typing import Annotated, Literal
|
||||
from fastapi import Depends
|
||||
from pkg.JWT import jwt
|
||||
|
||||
async def AuthRequired(
|
||||
token: Annotated[str, Depends(jwt.oauth2_scheme)]
|
||||
) -> Literal[True]:
|
||||
'''
|
||||
AuthRequired 需要登录
|
||||
'''
|
||||
return True
|
||||
|
||||
async def SignRequired(
|
||||
token: Annotated[str, Depends(jwt.oauth2_scheme)]
|
||||
) -> Literal[True]:
|
||||
'''
|
||||
SignAuthRequired 需要登录并验证请求签名
|
||||
'''
|
||||
return True
|
||||
|
||||
async def AdminRequired(
|
||||
token: Annotated[str, Depends(jwt.oauth2_scheme)]
|
||||
) -> Literal[True]:
|
||||
'''
|
||||
验证是否为管理员。
|
||||
|
||||
使用方法:
|
||||
>>> APIRouter(dependencies=[Depends(is_admin)])
|
||||
'''
|
||||
...
|
||||
215
models/model.py
Normal file
215
models/model.py
Normal file
@@ -0,0 +1,215 @@
|
||||
from datetime import datetime
|
||||
from sqlalchemy import Column, Integer, String, Text, BigInteger, Boolean, DateTime, ForeignKey
|
||||
from sqlalchemy.ext.declarative import declarative_base
|
||||
|
||||
Base = declarative_base()
|
||||
|
||||
class BaseModel(Base):
|
||||
__abstract__ = True
|
||||
|
||||
id = Column(Integer, primary_key=True, autoincrement=True)
|
||||
created_at = Column(DateTime, default=datetime.now)
|
||||
updated_at = Column(DateTime, default=datetime.now, onupdate=datetime.now)
|
||||
deleted_at = Column(DateTime, nullable=True)
|
||||
|
||||
class Download(BaseModel):
|
||||
__tablename__ = 'downloads'
|
||||
|
||||
status = Column(Integer, nullable=True)
|
||||
type = Column(Integer, nullable=True)
|
||||
source = Column(Text, nullable=True)
|
||||
total_size = Column(BigInteger, nullable=True)
|
||||
downloaded_size = Column(BigInteger, nullable=True)
|
||||
g_id = Column(Text, nullable=True)
|
||||
speed = Column(Integer, nullable=True)
|
||||
parent = Column(Text, nullable=True)
|
||||
attrs = Column(Text, nullable=True)
|
||||
error = Column(Text, nullable=True)
|
||||
dst = Column(Text, nullable=True)
|
||||
user_id = Column(Integer, nullable=True)
|
||||
task_id = Column(Integer, nullable=True)
|
||||
node_id = Column(Integer, nullable=True)
|
||||
|
||||
class File(BaseModel):
|
||||
__tablename__ = 'files'
|
||||
|
||||
name = Column(String(255), nullable=True)
|
||||
source_name = Column(Text, nullable=True)
|
||||
user_id = Column(Integer, nullable=True)
|
||||
size = Column(BigInteger, nullable=True)
|
||||
pic_info = Column(String(255), nullable=True)
|
||||
folder_id = Column(Integer, nullable=True)
|
||||
policy_id = Column(Integer, nullable=True)
|
||||
upload_session_id = Column(String(255), nullable=True, unique=True)
|
||||
metadata = Column(Text, nullable=True)
|
||||
|
||||
class Folder(BaseModel):
|
||||
__tablename__ = 'folders'
|
||||
|
||||
name = Column(String(255), nullable=True)
|
||||
parent_id = Column(Integer, nullable=True, index=True)
|
||||
owner_id = Column(Integer, nullable=True, index=True)
|
||||
policy_id = Column(Integer, nullable=True)
|
||||
|
||||
__table_args__ = {'uniqueConstraints': [('name', 'parent_id')]}
|
||||
|
||||
class Group(BaseModel):
|
||||
__tablename__ = 'groups'
|
||||
|
||||
name = Column(String(255), nullable=True)
|
||||
policies = Column(String(255), nullable=True)
|
||||
max_storage = Column(BigInteger, nullable=True)
|
||||
share_enabled = Column(Boolean, nullable=True)
|
||||
web_dav_enabled = Column(Boolean, nullable=True)
|
||||
speed_limit = Column(Integer, nullable=True)
|
||||
options = Column(String(255), nullable=True)
|
||||
|
||||
class Node(BaseModel):
|
||||
__tablename__ = 'nodes'
|
||||
|
||||
status = Column(Integer, nullable=True)
|
||||
name = Column(String(255), nullable=True)
|
||||
type = Column(Integer, nullable=True)
|
||||
server = Column(String(255), nullable=True)
|
||||
slave_key = Column(Text, nullable=True)
|
||||
master_key = Column(Text, nullable=True)
|
||||
aria2_enabled = Column(Boolean, nullable=True)
|
||||
aria2_options = Column(Text, nullable=True)
|
||||
rank = Column(Integer, nullable=True)
|
||||
|
||||
class Order(BaseModel):
|
||||
__tablename__ = 'orders'
|
||||
|
||||
user_id = Column(Integer, nullable=True)
|
||||
order_no = Column(String(255), nullable=True, index=True)
|
||||
type = Column(Integer, nullable=True)
|
||||
method = Column(String(255), nullable=True)
|
||||
product_id = Column(BigInteger, nullable=True)
|
||||
num = Column(Integer, nullable=True)
|
||||
name = Column(String(255), nullable=True)
|
||||
price = Column(Integer, nullable=True)
|
||||
status = Column(Integer, nullable=True)
|
||||
|
||||
class Policy(BaseModel):
|
||||
__tablename__ = 'policies'
|
||||
|
||||
name = Column(String(255), nullable=True)
|
||||
type = Column(String(255), nullable=True)
|
||||
server = Column(String(255), nullable=True)
|
||||
bucket_name = Column(String(255), nullable=True)
|
||||
is_private = Column(Boolean, nullable=True)
|
||||
base_url = Column(String(255), nullable=True)
|
||||
access_key = Column(Text, nullable=True)
|
||||
secret_key = Column(Text, nullable=True)
|
||||
max_size = Column(BigInteger, nullable=True)
|
||||
auto_rename = Column(Boolean, nullable=True)
|
||||
dir_name_rule = Column(String(255), nullable=True)
|
||||
file_name_rule = Column(String(255), nullable=True)
|
||||
is_origin_link_enable = Column(Boolean, nullable=True)
|
||||
options = Column(Text, nullable=True)
|
||||
|
||||
class Redeem(BaseModel):
|
||||
__tablename__ = 'redeems'
|
||||
|
||||
type = Column(Integer, nullable=True)
|
||||
product_id = Column(BigInteger, nullable=True)
|
||||
num = Column(Integer, nullable=True)
|
||||
code = Column(Text, nullable=True)
|
||||
used = Column(Boolean, nullable=True)
|
||||
|
||||
class Report(BaseModel):
|
||||
__tablename__ = 'reports'
|
||||
|
||||
share_id = Column(Integer, nullable=True, index=True)
|
||||
reason = Column(Integer, nullable=True)
|
||||
description = Column(String(255), nullable=True)
|
||||
|
||||
class Setting(BaseModel):
|
||||
__tablename__ = 'settings'
|
||||
|
||||
type = Column(String(255), nullable=False)
|
||||
name = Column(String(255), nullable=False, unique=True, index=True)
|
||||
value = Column(Text, nullable=True)
|
||||
|
||||
class Share(BaseModel):
|
||||
__tablename__ = 'shares'
|
||||
|
||||
password = Column(String(255), nullable=True)
|
||||
is_dir = Column(Boolean, nullable=True)
|
||||
user_id = Column(Integer, nullable=True)
|
||||
source_id = Column(Integer, nullable=True)
|
||||
views = Column(Integer, nullable=True)
|
||||
downloads = Column(Integer, nullable=True)
|
||||
remain_downloads = Column(Integer, nullable=True)
|
||||
expires = Column(DateTime, nullable=True)
|
||||
preview_enabled = Column(Boolean, nullable=True)
|
||||
source_name = Column(String(255), nullable=True, index=True)
|
||||
score = Column(Integer, nullable=True)
|
||||
|
||||
class SourceLink(BaseModel):
|
||||
__tablename__ = 'source_links'
|
||||
|
||||
file_id = Column(Integer, nullable=True)
|
||||
name = Column(String(255), nullable=True)
|
||||
downloads = Column(Integer, nullable=True)
|
||||
|
||||
class StoragePack(BaseModel):
|
||||
__tablename__ = 'storage_packs'
|
||||
|
||||
name = Column(String(255), nullable=True)
|
||||
user_id = Column(Integer, nullable=True)
|
||||
active_time = Column(DateTime, nullable=True)
|
||||
expired_time = Column(DateTime, nullable=True, index=True)
|
||||
size = Column(BigInteger, nullable=True)
|
||||
|
||||
class Tag(BaseModel):
|
||||
__tablename__ = 'tags'
|
||||
|
||||
name = Column(String(255), nullable=True)
|
||||
icon = Column(String(255), nullable=True)
|
||||
color = Column(String(255), nullable=True)
|
||||
type = Column(Integer, nullable=True)
|
||||
expression = Column(Text, nullable=True)
|
||||
user_id = Column(Integer, nullable=True)
|
||||
|
||||
class Task(BaseModel):
|
||||
__tablename__ = 'tasks'
|
||||
|
||||
status = Column(Integer, nullable=True)
|
||||
type = Column(Integer, nullable=True)
|
||||
user_id = Column(Integer, nullable=True)
|
||||
progress = Column(Integer, nullable=True)
|
||||
error = Column(Text, nullable=True)
|
||||
props = Column(Text, nullable=True)
|
||||
|
||||
class User(BaseModel):
|
||||
__tablename__ = 'users'
|
||||
|
||||
email = Column(String(100), nullable=True, unique=True)
|
||||
nick = Column(String(50), nullable=True)
|
||||
password = Column(String(255), nullable=True)
|
||||
status = Column(Integer, nullable=True)
|
||||
group_id = Column(Integer, nullable=True)
|
||||
storage = Column(BigInteger, nullable=True)
|
||||
two_factor = Column(String(255), nullable=True)
|
||||
avatar = Column(String(255), nullable=True)
|
||||
options = Column(Text, nullable=True)
|
||||
authn = Column(Text, nullable=True)
|
||||
open_id = Column(String(255), nullable=True)
|
||||
score = Column(Integer, nullable=True)
|
||||
previous_group_id = Column(Integer, nullable=True)
|
||||
group_expires = Column(DateTime, nullable=True)
|
||||
notify_date = Column(DateTime, nullable=True)
|
||||
phone = Column(String(255), nullable=True)
|
||||
|
||||
class WebDAV(BaseModel):
|
||||
__tablename__ = 'webdavs'
|
||||
|
||||
name = Column(String(255), nullable=True)
|
||||
password = Column(String(255), nullable=True)
|
||||
user_id = Column(Integer, nullable=True)
|
||||
root = Column(Text, nullable=True)
|
||||
readonly = Column(Boolean, nullable=True)
|
||||
use_proxy = Column(Boolean, nullable=True)
|
||||
|
||||
__table_args__ = {'uniqueConstraints': [('password', 'user_id')]}
|
||||
7
models/response.py
Normal file
7
models/response.py
Normal file
@@ -0,0 +1,7 @@
|
||||
from pydantic import BaseModel, Field
|
||||
from typing import Union, Optional
|
||||
|
||||
class ResponseModel(BaseModel):
|
||||
code: int = Field(default=0, description="系统内部状态码, 0表示成功,其他表示失败", lt=60000, gt=0)
|
||||
data: Union[dict, list, str, int, float, None] = Field(None, description="响应数据")
|
||||
msg: Optional[str] = Field(default=None, description="响应消息,可以是错误消息或信息提示")
|
||||
9
pkg/JWT/jwt.py
Normal file
9
pkg/JWT/jwt.py
Normal file
@@ -0,0 +1,9 @@
|
||||
from fastapi.security import OAuth2PasswordBearer
|
||||
|
||||
oauth2_scheme = OAuth2PasswordBearer(
|
||||
scheme_name='获取 JWT Bearer 令牌',
|
||||
description='用于获取 JWT Bearer 令牌,需要以表单的形式提交',
|
||||
tokenUrl="/api/user/session",
|
||||
)
|
||||
|
||||
SECRET_KEY = ''
|
||||
103
pkg/conf/appmeta.py
Normal file
103
pkg/conf/appmeta.py
Normal file
@@ -0,0 +1,103 @@
|
||||
APP_NAME = 'DiskNext Server'
|
||||
summary = '一款基于 FastAPI 的可公私兼备的网盘系统'
|
||||
description = 'DiskNext Server 是一款基于 FastAPI 的网盘系统,支持个人和企业使用。它提供了高性能的文件存储和管理功能,支持多种认证方式。'
|
||||
license_info = {"name": "GPLv3", "url": "https://opensource.org/license/gpl-3.0"}
|
||||
|
||||
BackendVersion = "0.0.1"
|
||||
|
||||
IsPro = False
|
||||
|
||||
tags_meta = [
|
||||
{
|
||||
"name": "site",
|
||||
"description": "站点",
|
||||
},
|
||||
{
|
||||
"name": "user",
|
||||
"description": "用户",
|
||||
},
|
||||
{
|
||||
"name": "user_settings",
|
||||
"description": "用户设置",
|
||||
},
|
||||
{
|
||||
"name": "share",
|
||||
"description": "分享",
|
||||
},
|
||||
{
|
||||
"name": "file",
|
||||
"description": "文件",
|
||||
},
|
||||
{
|
||||
"name": "aria2",
|
||||
"description": "离线下载",
|
||||
},
|
||||
{
|
||||
"name": "directory",
|
||||
"description": "目录",
|
||||
},
|
||||
{
|
||||
"name": "object",
|
||||
"description": "对象,文件和目录的抽象",
|
||||
},
|
||||
{
|
||||
"name": "callback",
|
||||
"description": "回调接口",
|
||||
},
|
||||
{
|
||||
"name": "oauth",
|
||||
"description": "OAuth 认证",
|
||||
},
|
||||
{
|
||||
"name": "pay",
|
||||
"description": "支付回调",
|
||||
},
|
||||
{
|
||||
"name": "upload",
|
||||
"description": "上传回调",
|
||||
},
|
||||
{
|
||||
"name": "vas",
|
||||
"description": "增值服务",
|
||||
},
|
||||
{
|
||||
"name": "tag",
|
||||
"description": "用户标签",
|
||||
},
|
||||
{
|
||||
"name": "webdav",
|
||||
"description": "WebDAV管理相关",
|
||||
},
|
||||
{
|
||||
"name": "admin",
|
||||
"description": "管理员接口",
|
||||
},
|
||||
{
|
||||
"name": "admin_group",
|
||||
"description": "管理员组接口",
|
||||
},
|
||||
{
|
||||
"name": "admin_user",
|
||||
"description": "管理员用户接口",
|
||||
},
|
||||
{
|
||||
"name": "admin_file",
|
||||
"description": "管理员文件接口",
|
||||
},
|
||||
{
|
||||
"name": "admin_aria2",
|
||||
"description": "管理员离线下载接口",
|
||||
},
|
||||
{
|
||||
"name": "admin_policy",
|
||||
"description": "管理员策略接口",
|
||||
},
|
||||
{
|
||||
"name": "admin_task",
|
||||
"description": "管理员任务接口",
|
||||
},
|
||||
{
|
||||
"name": "admin_vas",
|
||||
"description": "管理员增值服务接口",
|
||||
}
|
||||
]
|
||||
487
routers/controllers/admin.py
Normal file
487
routers/controllers/admin.py
Normal file
@@ -0,0 +1,487 @@
|
||||
from fastapi import APIRouter, Depends
|
||||
from middleware.auth import AdminRequired
|
||||
from models.response import ResponseModel
|
||||
|
||||
# 管理员根目录 /api/admin
|
||||
admin_router = APIRouter(
|
||||
prefix="/admin",
|
||||
tags=["admin"],
|
||||
)
|
||||
|
||||
# 用户组 /api/admin/group
|
||||
admin_group_router = APIRouter(
|
||||
prefix="/admin/group",
|
||||
tags=["admin", "admin_group"],
|
||||
)
|
||||
|
||||
# 用户 /api/admin/user
|
||||
admin_user_router = APIRouter(
|
||||
prefix="/admin/user",
|
||||
tags=["admin", "admin_user"],
|
||||
)
|
||||
|
||||
# 文件 /api/admin/file
|
||||
admin_file_router = APIRouter(
|
||||
prefix="/admin/file",
|
||||
tags=["admin", "admin_file"],
|
||||
)
|
||||
|
||||
# 离线下载 /api/admin/aria2
|
||||
admin_aria2_router = APIRouter(
|
||||
prefix='/admin/aria2',
|
||||
tags=['admin', 'admin_aria2']
|
||||
)
|
||||
|
||||
# 存储策略管理 /api/admin/policy
|
||||
admin_policy_router = APIRouter(
|
||||
prefix='/admin/policy',
|
||||
tags=['admin', 'admin_policy']
|
||||
)
|
||||
|
||||
# 分享 /api/admin/share
|
||||
admin_share_router = APIRouter(
|
||||
prefix='/admin/share',
|
||||
tags=['admin', 'admin_share']
|
||||
)
|
||||
|
||||
# 任务 /api/admin/task
|
||||
admin_task_router = APIRouter(
|
||||
prefix='/admin/task',
|
||||
tags=['admin', 'admin_task']
|
||||
)
|
||||
|
||||
# 增值服务 /api/admin/vas
|
||||
admin_vas_router = APIRouter(
|
||||
prefix='/admin/vas',
|
||||
tags=['admin', 'admin_vas']
|
||||
)
|
||||
|
||||
|
||||
@admin_router.get(
|
||||
path='/summary',
|
||||
summary='获取站点概况',
|
||||
description='Get site summary information',
|
||||
dependencies=[Depends(AdminRequired)],
|
||||
)
|
||||
def router_admin_get_summary() -> ResponseModel:
|
||||
"""
|
||||
获取站点概况信息,包括用户数、分享数、文件数等。
|
||||
|
||||
Returns:
|
||||
ResponseModel: 包含站点概况信息的响应模型。
|
||||
"""
|
||||
...
|
||||
|
||||
@admin_router.get(
|
||||
path='/news',
|
||||
summary='获取社区新闻',
|
||||
description='Get community news',
|
||||
dependencies=[Depends(AdminRequired)],
|
||||
)
|
||||
def router_admin_get_news() -> ResponseModel:
|
||||
"""
|
||||
获取社区新闻信息,包括最新的动态和公告。
|
||||
|
||||
Returns:
|
||||
ResponseModel: 包含社区新闻信息的响应模型。
|
||||
"""
|
||||
...
|
||||
|
||||
@admin_router.patch(
|
||||
path='/settings',
|
||||
summary='更新设置',
|
||||
description='Update settings',
|
||||
dependencies=[Depends(AdminRequired)],
|
||||
)
|
||||
def router_admin_update_settings() -> ResponseModel:
|
||||
"""
|
||||
更新站点设置,包括站点名称、描述等。
|
||||
|
||||
Returns:
|
||||
ResponseModel: 包含更新结果的响应模型。
|
||||
"""
|
||||
...
|
||||
|
||||
@admin_router.get(
|
||||
path='/settings',
|
||||
summary='获取设置',
|
||||
description='Get settings',
|
||||
dependencies=[Depends(AdminRequired)],
|
||||
)
|
||||
def router_admin_get_settings() -> ResponseModel:
|
||||
"""
|
||||
获取站点设置,包括站点名称、描述等。
|
||||
|
||||
Returns:
|
||||
ResponseModel: 包含站点设置的响应模型。
|
||||
"""
|
||||
...
|
||||
|
||||
@admin_group_router.get(
|
||||
path='/',
|
||||
summary='获取用户组列表',
|
||||
description='Get user group list',
|
||||
dependencies=[Depends(AdminRequired)],
|
||||
)
|
||||
def router_admin_get_groups() -> ResponseModel:
|
||||
"""
|
||||
获取用户组列表,包括每个用户组的名称和权限信息。
|
||||
|
||||
Returns:
|
||||
ResponseModel: 包含用户组列表的响应模型。
|
||||
"""
|
||||
...
|
||||
|
||||
@admin_group_router.get(
|
||||
path='/{group_id}',
|
||||
summary='获取用户组信息',
|
||||
description='Get user group information by ID',
|
||||
dependencies=[Depends(AdminRequired)],
|
||||
)
|
||||
def router_admin_get_group(group_id: int) -> ResponseModel:
|
||||
"""
|
||||
根据用户组ID获取用户组信息,包括名称、权限等。
|
||||
|
||||
Args:
|
||||
group_id (int): 用户组ID。
|
||||
|
||||
Returns:
|
||||
ResponseModel: 包含用户组信息的响应模型。
|
||||
"""
|
||||
...
|
||||
|
||||
@admin_group_router.get(
|
||||
path='/list/{group_id}',
|
||||
summary='获取用户组成员列表',
|
||||
description='Get user group member list by group ID',
|
||||
dependencies=[Depends(AdminRequired)],
|
||||
)
|
||||
def router_admin_get_group_members(
|
||||
group_id: int,
|
||||
page: int = 1,
|
||||
page_size: int = 20
|
||||
) -> ResponseModel:
|
||||
"""
|
||||
根据用户组ID获取用户组成员列表。
|
||||
|
||||
Args:
|
||||
group_id (int): 用户组ID。
|
||||
page (int): 页码,默认为1。
|
||||
page_size (int, optional): 每页显示的成员数量,默认为20。
|
||||
|
||||
Returns:
|
||||
ResponseModel: 包含用户组成员列表的响应模型。
|
||||
"""
|
||||
...
|
||||
|
||||
@admin_group_router.post(
|
||||
path='/',
|
||||
summary='创建用户组',
|
||||
description='Create a new user group',
|
||||
dependencies=[Depends(AdminRequired)],
|
||||
)
|
||||
def router_admin_create_group() -> ResponseModel:
|
||||
"""
|
||||
创建一个新的用户组,设置名称和权限等信息。
|
||||
|
||||
Returns:
|
||||
ResponseModel: 包含创建结果的响应模型。
|
||||
"""
|
||||
...
|
||||
|
||||
@admin_group_router.patch(
|
||||
path='/{group_id}',
|
||||
summary='更新用户组信息',
|
||||
description='Update user group information by ID',
|
||||
dependencies=[Depends(AdminRequired)],
|
||||
)
|
||||
def router_admin_update_group(group_id: int) -> ResponseModel:
|
||||
"""
|
||||
根据用户组ID更新用户组信息,包括名称、权限等。
|
||||
|
||||
Args:
|
||||
group_id (int): 用户组ID。
|
||||
|
||||
Returns:
|
||||
ResponseModel: 包含更新结果的响应模型。
|
||||
"""
|
||||
...
|
||||
|
||||
@admin_group_router.delete(
|
||||
path='/{group_id}',
|
||||
summary='删除用户组',
|
||||
description='Delete user group by ID',
|
||||
dependencies=[Depends(AdminRequired)],
|
||||
)
|
||||
def router_admin_delete_group(group_id: int) -> ResponseModel:
|
||||
"""
|
||||
根据用户组ID删除用户组。
|
||||
|
||||
Args:
|
||||
group_id (int): 用户组ID。
|
||||
|
||||
Returns:
|
||||
ResponseModel: 包含删除结果的响应模型。
|
||||
"""
|
||||
...
|
||||
|
||||
@admin_user_router.get(
|
||||
path='/info/{user_id}',
|
||||
summary='获取用户信息',
|
||||
description='Get user information by ID',
|
||||
dependencies=[Depends(AdminRequired)],
|
||||
)
|
||||
def router_admin_get_user(user_id: int) -> ResponseModel:
|
||||
"""
|
||||
根据用户ID获取用户信息,包括用户名、邮箱、注册时间等。
|
||||
|
||||
Args:
|
||||
user_id (int): 用户ID。
|
||||
|
||||
Returns:
|
||||
ResponseModel: 包含用户信息的响应模型。
|
||||
"""
|
||||
...
|
||||
|
||||
@admin_user_router.get(
|
||||
path='/list',
|
||||
summary='获取用户列表',
|
||||
description='Get user list',
|
||||
dependencies=[Depends(AdminRequired)],
|
||||
)
|
||||
def router_admin_get_users(
|
||||
page: int = 1,
|
||||
page_size: int = 20
|
||||
) -> ResponseModel:
|
||||
"""
|
||||
获取用户列表,支持分页。
|
||||
|
||||
Args:
|
||||
page (int): 页码,默认为1。
|
||||
page_size (int, optional): 每页显示的用户数量,默认为20。
|
||||
|
||||
Returns:
|
||||
ResponseModel: 包含用户列表的响应模型。
|
||||
"""
|
||||
...
|
||||
|
||||
@admin_user_router.post(
|
||||
path='/create',
|
||||
summary='创建用户',
|
||||
description='Create a new user',
|
||||
dependencies=[Depends(AdminRequired)],
|
||||
)
|
||||
def router_admin_create_user() -> ResponseModel:
|
||||
"""
|
||||
创建一个新的用户,设置用户名、密码等信息。
|
||||
|
||||
Returns:
|
||||
ResponseModel: 包含创建结果的响应模型。
|
||||
"""
|
||||
...
|
||||
|
||||
@admin_user_router.patch(
|
||||
path='/{user_id}',
|
||||
summary='更新用户信息',
|
||||
description='Update user information by ID',
|
||||
dependencies=[Depends(AdminRequired)],
|
||||
)
|
||||
def router_admin_update_user(user_id: int) -> ResponseModel:
|
||||
"""
|
||||
根据用户ID更新用户信息,包括用户名、邮箱等。
|
||||
|
||||
Args:
|
||||
user_id (int): 用户ID。
|
||||
|
||||
Returns:
|
||||
ResponseModel: 包含更新结果的响应模型。
|
||||
"""
|
||||
...
|
||||
|
||||
@admin_user_router.delete(
|
||||
path='/{user_id}',
|
||||
summary='删除用户',
|
||||
description='Delete user by ID',
|
||||
dependencies=[Depends(AdminRequired)],
|
||||
)
|
||||
def router_admin_delete_user(user_id: int) -> ResponseModel:
|
||||
"""
|
||||
根据用户ID删除用户。
|
||||
|
||||
Args:
|
||||
user_id (int): 用户ID。
|
||||
|
||||
Returns:
|
||||
ResponseModel: 包含删除结果的响应模型。
|
||||
"""
|
||||
...
|
||||
|
||||
@admin_user_router.post(
|
||||
path='/calibrate/{user_id}',
|
||||
summary='校准用户存储容量',
|
||||
description='Calibrate the user storage.',
|
||||
dependencies=[Depends(AdminRequired)]
|
||||
)
|
||||
def router_admin_calibrate_storage():
|
||||
...
|
||||
|
||||
@admin_file_router.get(
|
||||
path='/list',
|
||||
summary='获取文件',
|
||||
description='Get file list',
|
||||
dependencies=[Depends(AdminRequired)],
|
||||
)
|
||||
def router_admin_get_file_list() -> ResponseModel:
|
||||
"""
|
||||
获取文件列表,包括文件名称、大小、上传时间等。
|
||||
|
||||
Returns:
|
||||
ResponseModel: 包含文件列表的响应模型。
|
||||
"""
|
||||
...
|
||||
|
||||
@admin_file_router.get(
|
||||
path='/preview/{file_id}',
|
||||
summary='预览文件',
|
||||
description='Preview file by ID',
|
||||
dependencies=[Depends(AdminRequired)],
|
||||
)
|
||||
def router_admin_preview_file(file_id: int) -> ResponseModel:
|
||||
"""
|
||||
根据文件ID预览文件内容。
|
||||
|
||||
Args:
|
||||
file_id (int): 文件ID。
|
||||
|
||||
Returns:
|
||||
ResponseModel: 包含文件预览内容的响应模型。
|
||||
"""
|
||||
...
|
||||
|
||||
@admin_file_router.patch(
|
||||
path='/ban/{file_id}',
|
||||
summary='封禁文件',
|
||||
description='Ban the file, user can\'t open, copy, move, download or share this file if administrator ban.',
|
||||
dependencies=[Depends(AdminRequired)],
|
||||
)
|
||||
def router_admin_ban_file(file_id: int) -> ResponseModel:
|
||||
"""
|
||||
根据文件ID封禁文件。
|
||||
|
||||
如果管理员封禁了某个文件,用户将无法打开、复制或移动、下载或分享此文件。
|
||||
|
||||
Args:
|
||||
file_id (int): 文件ID。
|
||||
|
||||
Returns:
|
||||
ResponseModel: 包含删除结果的响应模型。
|
||||
"""
|
||||
...
|
||||
|
||||
@admin_file_router.delete(
|
||||
path='/{file_id}',
|
||||
summary='删除文件',
|
||||
description='Delete file by ID',
|
||||
dependencies=[Depends(AdminRequired)],
|
||||
)
|
||||
def router_admin_delete_file(file_id: int) -> ResponseModel:
|
||||
"""
|
||||
根据文件ID删除文件。
|
||||
|
||||
Args:
|
||||
file_id (int): 文件ID。
|
||||
|
||||
Returns:
|
||||
ResponseModel: 包含删除结果的响应模型。
|
||||
"""
|
||||
...
|
||||
|
||||
@admin_aria2_router.post(
|
||||
path='/test',
|
||||
summary='测试连接配置',
|
||||
description='',
|
||||
dependencies=[Depends(AdminRequired)]
|
||||
)
|
||||
def router_admin_aira2_test() -> ResponseModel:
|
||||
...
|
||||
|
||||
@admin_policy_router.get(
|
||||
path='/list',
|
||||
summary='列出存储策略',
|
||||
description='',
|
||||
dependencies=[Depends(AdminRequired)]
|
||||
)
|
||||
def router_policy_list() -> ResponseModel:
|
||||
...
|
||||
|
||||
@admin_policy_router.post(
|
||||
path='/test/path',
|
||||
summary='测试本地路径可用性',
|
||||
description='',
|
||||
dependencies=[Depends(AdminRequired)]
|
||||
)
|
||||
def router_policy_test_path() -> ResponseModel:
|
||||
...
|
||||
|
||||
@admin_policy_router.post(
|
||||
path='/test/slave',
|
||||
summary='测试从机通信',
|
||||
description='',
|
||||
dependencies=[Depends(AdminRequired)]
|
||||
)
|
||||
def router_policy_test_slave() -> ResponseModel:
|
||||
...
|
||||
|
||||
@admin_policy_router.post(
|
||||
path='/',
|
||||
summary='创建存储策略',
|
||||
description='',
|
||||
dependencies=[Depends(AdminRequired)]
|
||||
)
|
||||
def router_policy_add_policy() -> ResponseModel:
|
||||
...
|
||||
|
||||
@admin_policy_router.post(
|
||||
path='/cors',
|
||||
summary='创建跨域策略',
|
||||
description='',
|
||||
dependencies=[Depends(AdminRequired)]
|
||||
)
|
||||
def router_policy_add_cors() -> ResponseModel:
|
||||
...
|
||||
|
||||
@admin_policy_router.post(
|
||||
path='/scf',
|
||||
summary='创建COS回调函数',
|
||||
description='',
|
||||
dependencies=[Depends(AdminRequired)]
|
||||
)
|
||||
def router_policy_add_scf() -> ResponseModel:
|
||||
...
|
||||
|
||||
@admin_policy_router.get(
|
||||
path='/{id}/oauth',
|
||||
summary='获取 OneDrive OAuth URL',
|
||||
description='',
|
||||
dependencies=[Depends(AdminRequired)]
|
||||
)
|
||||
def router_policy_onddrive_oauth() -> ResponseModel:
|
||||
...
|
||||
|
||||
@admin_policy_router.get(
|
||||
path='/{id}',
|
||||
summary='获取存储策略',
|
||||
description='',
|
||||
dependencies=[Depends(AdminRequired)]
|
||||
)
|
||||
def router_policy_get_policy() -> ResponseModel:
|
||||
...
|
||||
|
||||
@admin_policy_router.delete(
|
||||
path='/{id}',
|
||||
summary='删除存储策略',
|
||||
description='',
|
||||
dependencies=[Depends(AdminRequired)]
|
||||
)
|
||||
def router_policy_delete_policy() -> ResponseModel:
|
||||
...
|
||||
107
routers/controllers/aria2.py
Normal file
107
routers/controllers/aria2.py
Normal file
@@ -0,0 +1,107 @@
|
||||
from fastapi import APIRouter, Depends
|
||||
from middleware.auth import SignRequired
|
||||
from models.response import ResponseModel
|
||||
|
||||
aria2_router = APIRouter(
|
||||
prefix="/aria2",
|
||||
tags=["aria2"]
|
||||
)
|
||||
|
||||
@aria2_router.post(
|
||||
path='/url',
|
||||
summary='创建URL下载任务',
|
||||
description='Create a URL download task endpoint.',
|
||||
dependencies=[Depends(SignRequired)]
|
||||
)
|
||||
def router_aria2_url() -> ResponseModel:
|
||||
"""
|
||||
Create a URL download task endpoint.
|
||||
|
||||
Returns:
|
||||
ResponseModel: A model containing the response data for the URL download task.
|
||||
"""
|
||||
...
|
||||
|
||||
@aria2_router.post(
|
||||
path='/torrent/{id}',
|
||||
summary='创建种子下载任务',
|
||||
description='Create a torrent download task endpoint.',
|
||||
dependencies=[Depends(SignRequired)]
|
||||
)
|
||||
def router_aria2_torrent(id: str) -> ResponseModel:
|
||||
"""
|
||||
Create a torrent download task endpoint.
|
||||
|
||||
Args:
|
||||
id (str): The ID of the torrent to download.
|
||||
|
||||
Returns:
|
||||
ResponseModel: A model containing the response data for the torrent download task.
|
||||
"""
|
||||
...
|
||||
|
||||
@aria2_router.put(
|
||||
path='/select/{gid}',
|
||||
summary='重新选择要下载的文件',
|
||||
description='Re-select files to download endpoint.',
|
||||
dependencies=[Depends(SignRequired)]
|
||||
)
|
||||
def router_aria2_select(gid: str) -> ResponseModel:
|
||||
"""
|
||||
Re-select files to download endpoint.
|
||||
|
||||
Args:
|
||||
gid (str): The GID of the download task.
|
||||
|
||||
Returns:
|
||||
ResponseModel: A model containing the response data for the re-selection of files.
|
||||
"""
|
||||
...
|
||||
|
||||
@aria2_router.delete(
|
||||
path='/task/{gid}',
|
||||
summary='取消或删除下载任务',
|
||||
description='Delete a download task endpoint.',
|
||||
dependencies=[Depends(SignRequired)]
|
||||
)
|
||||
def router_aria2_delete(gid: str) -> ResponseModel:
|
||||
"""
|
||||
Delete a download task endpoint.
|
||||
|
||||
Args:
|
||||
gid (str): The GID of the download task to delete.
|
||||
|
||||
Returns:
|
||||
ResponseModel: A model containing the response data for the deletion of the download task.
|
||||
"""
|
||||
...
|
||||
|
||||
@aria2_router.get(
|
||||
'/downloading',
|
||||
summary='获取正在下载中的任务',
|
||||
description='Get currently downloading tasks endpoint.',
|
||||
dependencies=[Depends(SignRequired)]
|
||||
)
|
||||
def router_aria2_downloading() -> ResponseModel:
|
||||
"""
|
||||
Get currently downloading tasks endpoint.
|
||||
|
||||
Returns:
|
||||
ResponseModel: A model containing the response data for currently downloading tasks.
|
||||
"""
|
||||
...
|
||||
|
||||
@aria2_router.get(
|
||||
path='/finished',
|
||||
summary='获取已完成的任务',
|
||||
description='Get finished tasks endpoint.',
|
||||
dependencies=[Depends(SignRequired)]
|
||||
)
|
||||
def router_aria2_finished() -> ResponseModel:
|
||||
"""
|
||||
Get finished tasks endpoint.
|
||||
|
||||
Returns:
|
||||
ResponseModel: A model containing the response data for finished tasks.
|
||||
"""
|
||||
...
|
||||
279
routers/controllers/callback.py
Normal file
279
routers/controllers/callback.py
Normal file
@@ -0,0 +1,279 @@
|
||||
from fastapi import APIRouter, Depends
|
||||
from fastapi.responses import PlainTextResponse
|
||||
from middleware.auth import SignRequired
|
||||
from models.response import ResponseModel
|
||||
|
||||
callback_router = APIRouter(
|
||||
prefix='/callback',
|
||||
tags=["callback"],
|
||||
)
|
||||
|
||||
oauth_router = APIRouter(
|
||||
prefix='/callback/oauth',
|
||||
tags=["callback", "oauth"],
|
||||
)
|
||||
|
||||
pay_router = APIRouter(
|
||||
prefix='/callback/pay',
|
||||
tags=["callback", "pay"],
|
||||
)
|
||||
|
||||
upload_router = APIRouter(
|
||||
prefix='/callback/upload',
|
||||
tags=["callback", "upload"],
|
||||
)
|
||||
|
||||
callback_router.include_router(oauth_router)
|
||||
callback_router.include_router(pay_router)
|
||||
callback_router.include_router(upload_router)
|
||||
|
||||
@oauth_router.post(
|
||||
path='/qq',
|
||||
summary='QQ互联回调',
|
||||
description='Handle QQ OAuth callback and return user information.',
|
||||
)
|
||||
def router_callback_qq() -> ResponseModel:
|
||||
"""
|
||||
Handle QQ OAuth callback and return user information.
|
||||
|
||||
Returns:
|
||||
ResponseModel: A model containing the response data for the QQ OAuth callback.
|
||||
"""
|
||||
...
|
||||
|
||||
@oauth_router.post(
|
||||
path='/github',
|
||||
summary='GitHub OAuth 回调',
|
||||
description='Handle GitHub OAuth callback and return user information.',
|
||||
)
|
||||
def router_callback_github() -> ResponseModel:
|
||||
"""
|
||||
Handle GitHub OAuth callback and return user information.
|
||||
|
||||
Returns:
|
||||
ResponseModel: A model containing the response data for the GitHub OAuth callback.
|
||||
"""
|
||||
...
|
||||
|
||||
@pay_router.post(
|
||||
path='/alipay',
|
||||
summary='支付宝支付回调',
|
||||
description='Handle Alipay payment callback and return payment status.',
|
||||
)
|
||||
def router_callback_alipay() -> ResponseModel:
|
||||
"""
|
||||
Handle Alipay payment callback and return payment status.
|
||||
|
||||
Returns:
|
||||
ResponseModel: A model containing the response data for the Alipay payment callback.
|
||||
"""
|
||||
...
|
||||
|
||||
@pay_router.post(
|
||||
path='/wechat',
|
||||
summary='微信支付回调',
|
||||
description='Handle WeChat Pay payment callback and return payment status.',
|
||||
)
|
||||
def router_callback_wechat() -> ResponseModel:
|
||||
"""
|
||||
Handle WeChat Pay payment callback and return payment status.
|
||||
|
||||
Returns:
|
||||
ResponseModel: A model containing the response data for the WeChat Pay payment callback.
|
||||
"""
|
||||
...
|
||||
|
||||
@pay_router.post(
|
||||
path='/stripe',
|
||||
summary='Stripe支付回调',
|
||||
description='Handle Stripe payment callback and return payment status.',
|
||||
)
|
||||
def router_callback_stripe() -> ResponseModel:
|
||||
"""
|
||||
Handle Stripe payment callback and return payment status.
|
||||
|
||||
Returns:
|
||||
ResponseModel: A model containing the response data for the Stripe payment callback.
|
||||
"""
|
||||
...
|
||||
|
||||
@pay_router.get(
|
||||
path='/easypay',
|
||||
summary='易支付回调',
|
||||
description='Handle EasyPay payment callback and return payment status.',
|
||||
)
|
||||
def router_callback_easypay() -> PlainTextResponse:
|
||||
"""
|
||||
Handle EasyPay payment callback and return payment status.
|
||||
|
||||
Returns:
|
||||
PlainTextResponse: A response containing the payment status for the EasyPay payment callback.
|
||||
"""
|
||||
...
|
||||
# return PlainTextResponse("success", status_code=200)
|
||||
|
||||
@pay_router.get(
|
||||
path='/custom/{order_no}/{id}',
|
||||
summary='自定义支付回调',
|
||||
description='Handle custom payment callback and return payment status.',
|
||||
)
|
||||
def router_callback_custom(order_no: str, id: str) -> ResponseModel:
|
||||
"""
|
||||
Handle custom payment callback and return payment status.
|
||||
|
||||
Args:
|
||||
order_no (str): The order number for the payment.
|
||||
id (str): The ID associated with the payment.
|
||||
|
||||
Returns:
|
||||
ResponseModel: A model containing the response data for the custom payment callback.
|
||||
"""
|
||||
...
|
||||
|
||||
@upload_router.post(
|
||||
path='/remote/{session_id}/{key}',
|
||||
summary='远程上传回调',
|
||||
description='Handle remote upload callback and return upload status.',
|
||||
)
|
||||
def router_callback_remote(session_id: str, key: str) -> ResponseModel:
|
||||
"""
|
||||
Handle remote upload callback and return upload status.
|
||||
|
||||
Args:
|
||||
session_id (str): The session ID for the upload.
|
||||
key (str): The key for the uploaded file.
|
||||
|
||||
Returns:
|
||||
ResponseModel: A model containing the response data for the remote upload callback.
|
||||
"""
|
||||
...
|
||||
|
||||
@upload_router.post(
|
||||
path='/qiniu/{session_id}',
|
||||
summary='七牛云上传回调',
|
||||
description='Handle Qiniu Cloud upload callback and return upload status.',
|
||||
)
|
||||
def router_callback_qiniu(session_id: str) -> ResponseModel:
|
||||
"""
|
||||
Handle Qiniu Cloud upload callback and return upload status.
|
||||
|
||||
Args:
|
||||
session_id (str): The session ID for the upload.
|
||||
|
||||
Returns:
|
||||
ResponseModel: A model containing the response data for the Qiniu Cloud upload callback.
|
||||
"""
|
||||
...
|
||||
|
||||
@upload_router.post(
|
||||
path='/tencent/{session_id}',
|
||||
summary='腾讯云上传回调',
|
||||
description='Handle Tencent Cloud upload callback and return upload status.',
|
||||
)
|
||||
def router_callback_tencent(session_id: str) -> ResponseModel:
|
||||
"""
|
||||
Handle Tencent Cloud upload callback and return upload status.
|
||||
|
||||
Args:
|
||||
session_id (str): The session ID for the upload.
|
||||
|
||||
Returns:
|
||||
ResponseModel: A model containing the response data for the Tencent Cloud upload callback.
|
||||
"""
|
||||
...
|
||||
|
||||
@upload_router.post(
|
||||
path='/aliyun/{session_id}',
|
||||
summary='阿里云上传回调',
|
||||
description='Handle Aliyun upload callback and return upload status.',
|
||||
)
|
||||
def router_callback_aliyun(session_id: str) -> ResponseModel:
|
||||
"""
|
||||
Handle Aliyun upload callback and return upload status.
|
||||
|
||||
Args:
|
||||
session_id (str): The session ID for the upload.
|
||||
|
||||
Returns:
|
||||
ResponseModel: A model containing the response data for the Aliyun upload callback.
|
||||
"""
|
||||
...
|
||||
|
||||
@upload_router.post(
|
||||
path='/upyun/{session_id}',
|
||||
summary='又拍云上传回调',
|
||||
description='Handle Upyun upload callback and return upload status.',
|
||||
)
|
||||
def router_callback_upyun(session_id: str) -> ResponseModel:
|
||||
"""
|
||||
Handle Upyun upload callback and return upload status.
|
||||
|
||||
Args:
|
||||
session_id (str): The session ID for the upload.
|
||||
|
||||
Returns:
|
||||
ResponseModel: A model containing the response data for the Upyun upload callback.
|
||||
"""
|
||||
...
|
||||
|
||||
@upload_router.post(
|
||||
path='/aws/{session_id}',
|
||||
summary='AWS S3上传回调',
|
||||
description='Handle AWS S3 upload callback and return upload status.',
|
||||
)
|
||||
def router_callback_aws(session_id: str) -> ResponseModel:
|
||||
"""
|
||||
Handle AWS S3 upload callback and return upload status.
|
||||
|
||||
Args:
|
||||
session_id (str): The session ID for the upload.
|
||||
|
||||
Returns:
|
||||
ResponseModel: A model containing the response data for the AWS S3 upload callback.
|
||||
"""
|
||||
...
|
||||
|
||||
@upload_router.post(
|
||||
path='/onedrive/finish/{session_id}',
|
||||
summary='OneDrive上传完成回调',
|
||||
description='Handle OneDrive upload completion callback and return upload status.',
|
||||
)
|
||||
def router_callback_onedrive_finish(session_id: str) -> ResponseModel:
|
||||
"""
|
||||
Handle OneDrive upload completion callback and return upload status.
|
||||
|
||||
Args:
|
||||
session_id (str): The session ID for the upload.
|
||||
|
||||
Returns:
|
||||
ResponseModel: A model containing the response data for the OneDrive upload completion callback.
|
||||
"""
|
||||
...
|
||||
|
||||
@upload_router.get(
|
||||
path='/ondrive/auth',
|
||||
summary='OneDrive授权回调',
|
||||
description='Handle OneDrive authorization callback and return authorization status.',
|
||||
)
|
||||
def router_callback_onedrive_auth() -> ResponseModel:
|
||||
"""
|
||||
Handle OneDrive authorization callback and return authorization status.
|
||||
|
||||
Returns:
|
||||
ResponseModel: A model containing the response data for the OneDrive authorization callback.
|
||||
"""
|
||||
...
|
||||
|
||||
@upload_router.get(
|
||||
path='/google/auth',
|
||||
summary='Google OAuth 完成',
|
||||
description='Handle Google OAuth completion callback and return authorization status.',
|
||||
)
|
||||
def router_callback_google_auth() -> ResponseModel:
|
||||
"""
|
||||
Handle Google OAuth completion callback and return authorization status.
|
||||
|
||||
Returns:
|
||||
ResponseModel: A model containing the response data for the Google OAuth completion callback.
|
||||
"""
|
||||
...
|
||||
41
routers/controllers/directory.py
Normal file
41
routers/controllers/directory.py
Normal file
@@ -0,0 +1,41 @@
|
||||
from fastapi import APIRouter, Depends
|
||||
from middleware.auth import SignRequired
|
||||
from models.response import ResponseModel
|
||||
|
||||
directory_router = APIRouter(
|
||||
prefix="/directory",
|
||||
tags=["directory"]
|
||||
)
|
||||
|
||||
@directory_router.put(
|
||||
path='/',
|
||||
summary='创建目录',
|
||||
description='Create a directory endpoint.',
|
||||
dependencies=[Depends(SignRequired)]
|
||||
)
|
||||
def router_directory_create() -> ResponseModel:
|
||||
"""
|
||||
Create a directory endpoint.
|
||||
|
||||
Returns:
|
||||
ResponseModel: A model containing the response data for the directory creation.
|
||||
"""
|
||||
...
|
||||
|
||||
@directory_router.get(
|
||||
path='/{path:path}',
|
||||
summary='获取目录内容',
|
||||
description='Get directory contents endpoint.',
|
||||
dependencies=[Depends(SignRequired)]
|
||||
)
|
||||
def router_directory_get(path: str) -> ResponseModel:
|
||||
"""
|
||||
Get directory contents endpoint.
|
||||
|
||||
Args:
|
||||
path (str): The path of the directory to retrieve contents from.
|
||||
|
||||
Returns:
|
||||
ResponseModel: A model containing the response data for the directory contents.
|
||||
"""
|
||||
...
|
||||
381
routers/controllers/file.py
Normal file
381
routers/controllers/file.py
Normal file
@@ -0,0 +1,381 @@
|
||||
from fastapi import APIRouter, Depends
|
||||
from middleware.auth import SignRequired
|
||||
from models.response import ResponseModel
|
||||
|
||||
file_router = APIRouter(
|
||||
prefix="/file",
|
||||
tags=["file"]
|
||||
)
|
||||
|
||||
file_upload_router = APIRouter(
|
||||
prefix="/file/upload",
|
||||
tags=["file"]
|
||||
)
|
||||
|
||||
@file_router.get(
|
||||
path='/get/{id}/{name}',
|
||||
summary='文件外链(直接输出文件数据)',
|
||||
description='Get file external link endpoint.',
|
||||
)
|
||||
def router_file_get(id: str, name: str) -> ResponseModel:
|
||||
"""
|
||||
Get file external link endpoint.
|
||||
|
||||
Args:
|
||||
id (str): The ID of the file.
|
||||
name (str): The name of the file.
|
||||
|
||||
Returns:
|
||||
ResponseModel: A model containing the response data for the file.
|
||||
"""
|
||||
...
|
||||
|
||||
@file_router.get(
|
||||
path='/source/{id}/{name}',
|
||||
summary='文件外链(301跳转)',
|
||||
description='Get file external link with 301 redirect endpoint.',
|
||||
)
|
||||
def router_file_source(id: str, name: str) -> ResponseModel:
|
||||
"""
|
||||
Get file external link with 301 redirect endpoint.
|
||||
|
||||
Args:
|
||||
id (str): The ID of the file.
|
||||
name (str): The name of the file.
|
||||
|
||||
Returns:
|
||||
ResponseModel: A model containing the response data for the file with a redirect.
|
||||
"""
|
||||
...
|
||||
|
||||
@file_upload_router.get(
|
||||
path='/download/{id}',
|
||||
summary='下载文件',
|
||||
description='Download file endpoint.',
|
||||
)
|
||||
def router_file_download(id: str) -> ResponseModel:
|
||||
"""
|
||||
Download file endpoint.
|
||||
|
||||
Args:
|
||||
id (str): The ID of the file to download.
|
||||
|
||||
Returns:
|
||||
ResponseModel: A model containing the response data for the file download.
|
||||
"""
|
||||
...
|
||||
|
||||
@file_upload_router.get(
|
||||
path='/archive/{sessionID}/archive.zip',
|
||||
summary='打包并下载文件',
|
||||
description='Archive and download files endpoint.',
|
||||
)
|
||||
def router_file_archive_download(sessionID: str) -> ResponseModel:
|
||||
"""
|
||||
Archive and download files endpoint.
|
||||
|
||||
Args:
|
||||
sessionID (str): The session ID for the archive.
|
||||
|
||||
Returns:
|
||||
ResponseModel: A model containing the response data for the archived files download.
|
||||
"""
|
||||
...
|
||||
|
||||
@file_upload_router.post(
|
||||
path='/{sessionID}/{index}',
|
||||
summary='文件上传',
|
||||
description='File upload endpoint.',
|
||||
)
|
||||
def router_file_upload(sessionID: str, index: int) -> ResponseModel:
|
||||
"""
|
||||
File upload endpoint.
|
||||
|
||||
Args:
|
||||
sessionID (str): The session ID for the upload.
|
||||
index (int): The index of the file being uploaded.
|
||||
|
||||
Returns:
|
||||
ResponseModel: A model containing the response data.
|
||||
"""
|
||||
...
|
||||
|
||||
@file_upload_router.put(
|
||||
path='/',
|
||||
summary='创建上传会话',
|
||||
description='Create an upload session endpoint.',
|
||||
dependencies=[Depends(SignRequired)],
|
||||
)
|
||||
def router_file_upload_session() -> ResponseModel:
|
||||
"""
|
||||
Create an upload session endpoint.
|
||||
|
||||
Returns:
|
||||
ResponseModel: A model containing the response data for the upload session.
|
||||
"""
|
||||
...
|
||||
|
||||
@file_upload_router.delete(
|
||||
path='/{sessionID}',
|
||||
summary='删除上传会话',
|
||||
description='Delete an upload session endpoint.',
|
||||
dependencies=[Depends(SignRequired)]
|
||||
)
|
||||
def router_file_upload_session_delete(sessionID: str) -> ResponseModel:
|
||||
"""
|
||||
Delete an upload session endpoint.
|
||||
|
||||
Args:
|
||||
sessionID (str): The session ID to delete.
|
||||
|
||||
Returns:
|
||||
ResponseModel: A model containing the response data for the deletion.
|
||||
"""
|
||||
...
|
||||
|
||||
@file_upload_router.delete(
|
||||
path='/',
|
||||
summary='清除所有上传会话',
|
||||
description='Clear all upload sessions endpoint.',
|
||||
dependencies=[Depends(SignRequired)]
|
||||
)
|
||||
def router_file_upload_session_clear() -> ResponseModel:
|
||||
"""
|
||||
Clear all upload sessions endpoint.
|
||||
|
||||
Returns:
|
||||
ResponseModel: A model containing the response data for clearing all sessions.
|
||||
"""
|
||||
...
|
||||
|
||||
@file_router.put(
|
||||
path='/update/{id}',
|
||||
summary='更新文件',
|
||||
description='Update file information endpoint.',
|
||||
dependencies=[Depends(SignRequired)]
|
||||
)
|
||||
def router_file_update(id: str) -> ResponseModel:
|
||||
"""
|
||||
Update file information endpoint.
|
||||
|
||||
Args:
|
||||
id (str): The ID of the file to update.
|
||||
|
||||
Returns:
|
||||
ResponseModel: A model containing the response data for the file update.
|
||||
"""
|
||||
...
|
||||
|
||||
@file_router.post(
|
||||
path='/create',
|
||||
summary='创建空白文件',
|
||||
description='Create a blank file endpoint.',
|
||||
dependencies=[Depends(SignRequired)]
|
||||
)
|
||||
def router_file_create() -> ResponseModel:
|
||||
"""
|
||||
Create a blank file endpoint.
|
||||
|
||||
Returns:
|
||||
ResponseModel: A model containing the response data for the file creation.
|
||||
"""
|
||||
...
|
||||
|
||||
@file_router.put(
|
||||
path='/download/{id}',
|
||||
summary='创建文件下载会话',
|
||||
description='Create a file download session endpoint.',
|
||||
dependencies=[Depends(SignRequired)]
|
||||
)
|
||||
def router_file_download(id: str) -> ResponseModel:
|
||||
"""
|
||||
Create a file download session endpoint.
|
||||
|
||||
Args:
|
||||
id (str): The ID of the file to download.
|
||||
|
||||
Returns:
|
||||
ResponseModel: A model containing the response data for the file download session.
|
||||
"""
|
||||
...
|
||||
|
||||
@file_router.get(
|
||||
path='/preview/{id}',
|
||||
summary='预览文件',
|
||||
description='Preview file endpoint.',
|
||||
dependencies=[Depends(SignRequired)]
|
||||
)
|
||||
def router_file_preview(id: str) -> ResponseModel:
|
||||
"""
|
||||
Preview file endpoint.
|
||||
|
||||
Args:
|
||||
id (str): The ID of the file to preview.
|
||||
|
||||
Returns:
|
||||
ResponseModel: A model containing the response data for the file preview.
|
||||
"""
|
||||
...
|
||||
|
||||
@file_router.get(
|
||||
path='/content/{id}',
|
||||
summary='获取文本文件内容',
|
||||
description='Get text file content endpoint.',
|
||||
dependencies=[Depends(SignRequired)]
|
||||
)
|
||||
def router_file_content(id: str) -> ResponseModel:
|
||||
"""
|
||||
Get text file content endpoint.
|
||||
|
||||
Args:
|
||||
id (str): The ID of the text file.
|
||||
|
||||
Returns:
|
||||
ResponseModel: A model containing the response data for the text file content.
|
||||
"""
|
||||
...
|
||||
|
||||
@file_router.get(
|
||||
path='/doc/{id}',
|
||||
summary='获取Office文档预览地址',
|
||||
description='Get Office document preview URL endpoint.',
|
||||
dependencies=[Depends(SignRequired)]
|
||||
)
|
||||
def router_file_doc(id: str) -> ResponseModel:
|
||||
"""
|
||||
Get Office document preview URL endpoint.
|
||||
|
||||
Args:
|
||||
id (str): The ID of the Office document.
|
||||
|
||||
Returns:
|
||||
ResponseModel: A model containing the response data for the Office document preview URL.
|
||||
"""
|
||||
...
|
||||
|
||||
@file_router.get(
|
||||
path='/thumb/{id}',
|
||||
summary='获取文件缩略图',
|
||||
description='Get file thumbnail endpoint.',
|
||||
dependencies=[Depends(SignRequired)]
|
||||
)
|
||||
def router_file_thumb(id: str) -> ResponseModel:
|
||||
"""
|
||||
Get file thumbnail endpoint.
|
||||
|
||||
Args:
|
||||
id (str): The ID of the file to get the thumbnail for.
|
||||
|
||||
Returns:
|
||||
ResponseModel: A model containing the response data for the file thumbnail.
|
||||
"""
|
||||
...
|
||||
|
||||
@file_router.post(
|
||||
path='/source/{id}',
|
||||
summary='取得文件外链',
|
||||
description='Get file external link endpoint.',
|
||||
dependencies=[Depends(SignRequired)]
|
||||
)
|
||||
def router_file_source(id: str) -> ResponseModel:
|
||||
"""
|
||||
Get file external link endpoint.
|
||||
|
||||
Args:
|
||||
id (str): The ID of the file to get the external link for.
|
||||
|
||||
Returns:
|
||||
ResponseModel: A model containing the response data for the file external link.
|
||||
"""
|
||||
...
|
||||
|
||||
@file_router.post(
|
||||
path='/archive',
|
||||
summary='打包要下载的文件',
|
||||
description='Archive files for download endpoint.',
|
||||
dependencies=[Depends(SignRequired)]
|
||||
)
|
||||
def router_file_archive(id: str) -> ResponseModel:
|
||||
"""
|
||||
Archive files for download endpoint.
|
||||
|
||||
Args:
|
||||
id (str): The ID of the file to archive.
|
||||
|
||||
Returns:
|
||||
ResponseModel: A model containing the response data for the archived files.
|
||||
"""
|
||||
...
|
||||
|
||||
@file_router.post(
|
||||
path='/compress',
|
||||
summary='创建文件压缩任务',
|
||||
description='Create file compression task endpoint.',
|
||||
dependencies=[Depends(SignRequired)]
|
||||
)
|
||||
def router_file_compress(id: str) -> ResponseModel:
|
||||
"""
|
||||
Create file compression task endpoint.
|
||||
|
||||
Args:
|
||||
id (str): The ID of the file to compress.
|
||||
|
||||
Returns:
|
||||
ResponseModel: A model containing the response data for the file compression task.
|
||||
"""
|
||||
...
|
||||
|
||||
@file_router.post(
|
||||
path='/decompress',
|
||||
summary='创建文件解压任务',
|
||||
description='Create file extraction task endpoint.',
|
||||
dependencies=[Depends(SignRequired)]
|
||||
)
|
||||
def router_file_decompress(id: str) -> ResponseModel:
|
||||
"""
|
||||
Create file extraction task endpoint.
|
||||
|
||||
Args:
|
||||
id (str): The ID of the file to decompress.
|
||||
|
||||
Returns:
|
||||
ResponseModel: A model containing the response data for the file extraction task.
|
||||
"""
|
||||
...
|
||||
|
||||
@file_router.post(
|
||||
path='/relocate',
|
||||
summary='创建文件转移任务',
|
||||
description='Create file relocation task endpoint.',
|
||||
dependencies=[Depends(SignRequired)]
|
||||
)
|
||||
def router_file_relocate(id: str) -> ResponseModel:
|
||||
"""
|
||||
Create file relocation task endpoint.
|
||||
|
||||
Args:
|
||||
id (str): The ID of the file to relocate.
|
||||
|
||||
Returns:
|
||||
ResponseModel: A model containing the response data for the file relocation task.
|
||||
"""
|
||||
...
|
||||
|
||||
@file_router.get(
|
||||
path='/search/{type}/{keyword}',
|
||||
summary='搜索文件',
|
||||
description='Search files by keyword endpoint.',
|
||||
dependencies=[Depends(SignRequired)]
|
||||
)
|
||||
def router_file_search(type: str, keyword: str) -> ResponseModel:
|
||||
"""
|
||||
Search files by keyword endpoint.
|
||||
|
||||
Args:
|
||||
type (str): The type of search (e.g., 'name', 'content').
|
||||
keyword (str): The keyword to search for.
|
||||
|
||||
Returns:
|
||||
ResponseModel: A model containing the response data for the file search.
|
||||
"""
|
||||
...
|
||||
86
routers/controllers/object.py
Normal file
86
routers/controllers/object.py
Normal file
@@ -0,0 +1,86 @@
|
||||
from fastapi import APIRouter, Depends
|
||||
from middleware.auth import SignRequired
|
||||
from models.response import ResponseModel
|
||||
|
||||
object_router = APIRouter(
|
||||
prefix="/object",
|
||||
tags=["object"]
|
||||
)
|
||||
|
||||
@object_router.delete(
|
||||
path='/',
|
||||
summary='删除对象',
|
||||
description='Delete an object endpoint.',
|
||||
dependencies=[Depends(SignRequired)]
|
||||
)
|
||||
def router_object_delete() -> ResponseModel:
|
||||
"""
|
||||
Delete an object endpoint.
|
||||
|
||||
Returns:
|
||||
ResponseModel: A model containing the response data for the object deletion.
|
||||
"""
|
||||
...
|
||||
|
||||
@object_router.patch(
|
||||
path='/',
|
||||
summary='移动对象',
|
||||
description='Move an object endpoint.',
|
||||
dependencies=[Depends(SignRequired)]
|
||||
)
|
||||
def router_object_move() -> ResponseModel:
|
||||
"""
|
||||
Move an object endpoint.
|
||||
|
||||
Returns:
|
||||
ResponseModel: A model containing the response data for the object move.
|
||||
"""
|
||||
...
|
||||
|
||||
@object_router.post(
|
||||
path='/copy',
|
||||
summary='复制对象',
|
||||
description='Copy an object endpoint.',
|
||||
dependencies=[Depends(SignRequired)]
|
||||
)
|
||||
def router_object_copy() -> ResponseModel:
|
||||
"""
|
||||
Copy an object endpoint.
|
||||
|
||||
Returns:
|
||||
ResponseModel: A model containing the response data for the object copy.
|
||||
"""
|
||||
...
|
||||
|
||||
@object_router.post(
|
||||
path='/rename',
|
||||
summary='重命名对象',
|
||||
description='Rename an object endpoint.',
|
||||
dependencies=[Depends(SignRequired)]
|
||||
)
|
||||
def router_object_rename() -> ResponseModel:
|
||||
"""
|
||||
Rename an object endpoint.
|
||||
|
||||
Returns:
|
||||
ResponseModel: A model containing the response data for the object rename.
|
||||
"""
|
||||
...
|
||||
|
||||
@object_router.get(
|
||||
path='/property/{id}',
|
||||
summary='获取对象属性',
|
||||
description='Get object properties endpoint.',
|
||||
dependencies=[Depends(SignRequired)]
|
||||
)
|
||||
def router_object_property(id: str) -> ResponseModel:
|
||||
"""
|
||||
Get object properties endpoint.
|
||||
|
||||
Args:
|
||||
id (str): The ID of the object to retrieve properties for.
|
||||
|
||||
Returns:
|
||||
ResponseModel: A model containing the response data for the object properties.
|
||||
"""
|
||||
...
|
||||
306
routers/controllers/share.py
Normal file
306
routers/controllers/share.py
Normal file
@@ -0,0 +1,306 @@
|
||||
from fastapi import APIRouter, Depends
|
||||
from middleware.auth import SignRequired
|
||||
from models.response import ResponseModel
|
||||
|
||||
share_router = APIRouter(
|
||||
prefix='/share',
|
||||
tags=["share"],
|
||||
)
|
||||
|
||||
@share_router.get(
|
||||
path='/{info}/{id}',
|
||||
summary='获取分享',
|
||||
description='Get shared content by info type and ID.',
|
||||
)
|
||||
def router_share_get(info: str, id: str) -> ResponseModel:
|
||||
"""
|
||||
Get shared content by info type and ID.
|
||||
|
||||
Args:
|
||||
info (str): The type of information being shared.
|
||||
id (str): The ID of the shared content.
|
||||
|
||||
Returns:
|
||||
dict: A dictionary containing shared content information.
|
||||
"""
|
||||
...
|
||||
|
||||
@share_router.put(
|
||||
path='/download/{id}',
|
||||
summary='创建文件下载会话',
|
||||
description='Create a file download session by ID.',
|
||||
)
|
||||
def router_share_download(id: str) -> ResponseModel:
|
||||
"""
|
||||
Create a file download session by ID.
|
||||
|
||||
Args:
|
||||
id (str): The ID of the file to be downloaded.
|
||||
|
||||
Returns:
|
||||
dict: A dictionary containing download session information.
|
||||
"""
|
||||
...
|
||||
|
||||
@share_router.get(
|
||||
path='preview/{id}',
|
||||
summary='预览分享文件',
|
||||
description='Preview shared file by ID.',
|
||||
)
|
||||
def router_share_preview(id: str) -> ResponseModel:
|
||||
"""
|
||||
Preview shared file by ID.
|
||||
|
||||
Args:
|
||||
id (str): The ID of the file to be previewed.
|
||||
|
||||
Returns:
|
||||
dict: A dictionary containing preview information.
|
||||
"""
|
||||
...
|
||||
|
||||
@share_router.get(
|
||||
path='/doc/{id}',
|
||||
summary='取得Office文档预览地址',
|
||||
description='Get Office document preview URL by ID.',
|
||||
)
|
||||
def router_share_doc(id: str) -> ResponseModel:
|
||||
"""
|
||||
Get Office document preview URL by ID.
|
||||
|
||||
Args:
|
||||
id (str): The ID of the Office document.
|
||||
|
||||
Returns:
|
||||
dict: A dictionary containing the document preview URL.
|
||||
"""
|
||||
...
|
||||
|
||||
@share_router.get(
|
||||
path='/content/{id}',
|
||||
summary='获取文本文件内容',
|
||||
description='Get text file content by ID.',
|
||||
)
|
||||
def router_share_content(id: str) -> ResponseModel:
|
||||
"""
|
||||
Get text file content by ID.
|
||||
|
||||
Args:
|
||||
id (str): The ID of the text file.
|
||||
|
||||
Returns:
|
||||
str: The content of the text file.
|
||||
"""
|
||||
...
|
||||
|
||||
@share_router.get(
|
||||
path='/list/{id}/{path:path}',
|
||||
summary='获取目录列文件',
|
||||
description='Get directory listing by ID and path.',
|
||||
)
|
||||
def router_share_list(id: str, path: str = '') -> ResponseModel:
|
||||
"""
|
||||
Get directory listing by ID and path.
|
||||
|
||||
Args:
|
||||
id (str): The ID of the directory.
|
||||
path (str): The path within the directory.
|
||||
|
||||
Returns:
|
||||
dict: A dictionary containing directory listing information.
|
||||
"""
|
||||
...
|
||||
|
||||
@share_router.get(
|
||||
path='/search/{id}/{type}/{keywords}',
|
||||
summary='分享目录搜索',
|
||||
description='Search within a shared directory by ID, type, and keywords.',
|
||||
)
|
||||
def router_share_search(id: str, type: str, keywords: str) -> ResponseModel:
|
||||
"""
|
||||
Search within a shared directory by ID, type, and keywords.
|
||||
|
||||
Args:
|
||||
id (str): The ID of the shared directory.
|
||||
type (str): The type of search (e.g., file, folder).
|
||||
keywords (str): The keywords to search for.
|
||||
|
||||
Returns:
|
||||
dict: A dictionary containing search results.
|
||||
"""
|
||||
...
|
||||
|
||||
@share_router.post(
|
||||
path='/archive/{id}',
|
||||
summary='归档打包下载',
|
||||
description='Archive and download shared content by ID.',
|
||||
)
|
||||
def router_share_archive(id: str) -> ResponseModel:
|
||||
"""
|
||||
Archive and download shared content by ID.
|
||||
|
||||
Args:
|
||||
id (str): The ID of the content to be archived.
|
||||
|
||||
Returns:
|
||||
dict: A dictionary containing archive download information.
|
||||
"""
|
||||
...
|
||||
|
||||
@share_router.get(
|
||||
path='/readme/{id}',
|
||||
summary='获取README文本文件内容',
|
||||
description='Get README text file content by ID.',
|
||||
)
|
||||
def router_share_readme(id: str) -> ResponseModel:
|
||||
"""
|
||||
Get README text file content by ID.
|
||||
|
||||
Args:
|
||||
id (str): The ID of the README file.
|
||||
|
||||
Returns:
|
||||
str: The content of the README file.
|
||||
"""
|
||||
...
|
||||
|
||||
@share_router.get(
|
||||
path='/thumb/{id}/{file}',
|
||||
summary='获取缩略图',
|
||||
description='Get thumbnail image by ID and file name.',
|
||||
)
|
||||
def router_share_thumb(id: str, file: str) -> ResponseModel:
|
||||
"""
|
||||
Get thumbnail image by ID and file name.
|
||||
|
||||
Args:
|
||||
id (str): The ID of the shared content.
|
||||
file (str): The name of the file for which to get the thumbnail.
|
||||
|
||||
Returns:
|
||||
str: A Base64 encoded string of the thumbnail image.
|
||||
"""
|
||||
...
|
||||
|
||||
@share_router.post(
|
||||
path='/report/{id}',
|
||||
summary='举报分享',
|
||||
description='Report shared content by ID.',
|
||||
)
|
||||
def router_share_report(id: str) -> ResponseModel:
|
||||
"""
|
||||
Report shared content by ID.
|
||||
|
||||
Args:
|
||||
id (str): The ID of the shared content to report.
|
||||
|
||||
Returns:
|
||||
dict: A dictionary containing report submission information.
|
||||
"""
|
||||
...
|
||||
|
||||
@share_router.get(
|
||||
path='/search',
|
||||
summary='搜索公共分享',
|
||||
description='Search public shares by keywords and type.',
|
||||
)
|
||||
def router_share_search_public(keywords: str, type: str = 'all') -> ResponseModel:
|
||||
"""
|
||||
Search public shares by keywords and type.
|
||||
|
||||
Args:
|
||||
keywords (str): The keywords to search for.
|
||||
type (str): The type of search (e.g., all, file, folder).
|
||||
|
||||
Returns:
|
||||
dict: A dictionary containing search results for public shares.
|
||||
"""
|
||||
...
|
||||
|
||||
#####################
|
||||
# 需要登录的接口
|
||||
#####################
|
||||
|
||||
@share_router.post(
|
||||
path='/',
|
||||
summary='创建新分享',
|
||||
description='Create a new share endpoint.',
|
||||
dependencies=[Depends(SignRequired)]
|
||||
)
|
||||
def router_share_create() -> ResponseModel:
|
||||
"""
|
||||
Create a new share endpoint.
|
||||
|
||||
Returns:
|
||||
ResponseModel: A model containing the response data for the new share creation.
|
||||
"""
|
||||
...
|
||||
|
||||
@share_router.get(
|
||||
path='/',
|
||||
summary='列出我的分享',
|
||||
description='Get a list of shares.',
|
||||
dependencies=[Depends(SignRequired)]
|
||||
)
|
||||
def router_share_list() -> ResponseModel:
|
||||
"""
|
||||
Get a list of shares.
|
||||
|
||||
Returns:
|
||||
ResponseModel: A model containing the response data for the list of shares.
|
||||
"""
|
||||
...
|
||||
|
||||
@share_router.post(
|
||||
path='/save/{id}',
|
||||
summary='转存他人分享',
|
||||
description='Save another user\'s share by ID.',
|
||||
dependencies=[Depends(SignRequired)]
|
||||
)
|
||||
def router_share_save(id: str) -> ResponseModel:
|
||||
"""
|
||||
Save another user's share by ID.
|
||||
|
||||
Args:
|
||||
id (str): The ID of the share to be saved.
|
||||
|
||||
Returns:
|
||||
ResponseModel: A model containing the response data for the saved share.
|
||||
"""
|
||||
...
|
||||
|
||||
@share_router.patch(
|
||||
path='/{id}',
|
||||
summary='更新分享信息',
|
||||
description='Update share information by ID.',
|
||||
dependencies=[Depends(SignRequired)]
|
||||
)
|
||||
def router_share_update(id: str) -> ResponseModel:
|
||||
"""
|
||||
Update share information by ID.
|
||||
|
||||
Args:
|
||||
id (str): The ID of the share to be updated.
|
||||
|
||||
Returns:
|
||||
ResponseModel: A model containing the response data for the updated share.
|
||||
"""
|
||||
...
|
||||
|
||||
@share_router.delete(
|
||||
path='/{id}',
|
||||
summary='删除分享',
|
||||
description='Delete a share by ID.',
|
||||
dependencies=[Depends(SignRequired)]
|
||||
)
|
||||
def router_share_delete(id: str) -> ResponseModel:
|
||||
"""
|
||||
Delete a share by ID.
|
||||
|
||||
Args:
|
||||
id (str): The ID of the share to be deleted.
|
||||
|
||||
Returns:
|
||||
ResponseModel: A model containing the response data for the deleted share.
|
||||
"""
|
||||
...
|
||||
52
routers/controllers/site.py
Normal file
52
routers/controllers/site.py
Normal file
@@ -0,0 +1,52 @@
|
||||
from fastapi import APIRouter
|
||||
from models.response import ResponseModel
|
||||
|
||||
site_router = APIRouter(
|
||||
prefix="/site",
|
||||
tags=["site"],
|
||||
)
|
||||
|
||||
@site_router.get(
|
||||
path="/ping",
|
||||
summary="测试用路由",
|
||||
description="A simple endpoint to check if the site is up and running.",
|
||||
response_model=ResponseModel,)
|
||||
def router_site_ping():
|
||||
"""
|
||||
Ping the site to check if it is up and running.
|
||||
|
||||
Returns:
|
||||
str: A message indicating the site is running.
|
||||
"""
|
||||
from pkg.conf.appmeta import BackendVersion
|
||||
return ResponseModel(data=BackendVersion)
|
||||
|
||||
@site_router.get(
|
||||
path='/captcha',
|
||||
summary='验证码',
|
||||
description='Get a Base64 captcha image.',
|
||||
response_model=ResponseModel,
|
||||
)
|
||||
def router_site_captcha():
|
||||
"""
|
||||
Get a Base64 captcha image.
|
||||
|
||||
Returns:
|
||||
str: A Base64 encoded string of the captcha image.
|
||||
"""
|
||||
...
|
||||
|
||||
@site_router.get(
|
||||
path='/config',
|
||||
summary='站点全局配置',
|
||||
description='Get the configuration file.',
|
||||
response_model=ResponseModel,
|
||||
)
|
||||
def router_site_config():
|
||||
"""
|
||||
Get the configuration file.
|
||||
|
||||
Returns:
|
||||
dict: The site configuration.
|
||||
"""
|
||||
...
|
||||
56
routers/controllers/tag.py
Normal file
56
routers/controllers/tag.py
Normal file
@@ -0,0 +1,56 @@
|
||||
from fastapi import APIRouter, Depends
|
||||
from middleware.auth import SignRequired
|
||||
from models.response import ResponseModel
|
||||
|
||||
tag_router = APIRouter(
|
||||
prefix='/tag',
|
||||
tags=["tag"],
|
||||
)
|
||||
|
||||
@tag_router.post(
|
||||
path='/filter',
|
||||
summary='创建文件分类标签',
|
||||
description='Create a file classification tag.',
|
||||
dependencies=[Depends(SignRequired)],
|
||||
)
|
||||
def router_tag_create_filter() -> ResponseModel:
|
||||
"""
|
||||
Create a file classification tag.
|
||||
|
||||
Returns:
|
||||
ResponseModel: A model containing the response data for the created tag.
|
||||
"""
|
||||
...
|
||||
|
||||
@tag_router.post(
|
||||
path='/link',
|
||||
summary='创建目录快捷方式标签',
|
||||
description='Create a directory shortcut tag.',
|
||||
dependencies=[Depends(SignRequired)],
|
||||
)
|
||||
def router_tag_create_link() -> ResponseModel:
|
||||
"""
|
||||
Create a directory shortcut tag.
|
||||
|
||||
Returns:
|
||||
ResponseModel: A model containing the response data for the created tag.
|
||||
"""
|
||||
...
|
||||
|
||||
@tag_router.delete(
|
||||
path='/{id}',
|
||||
summary='删除标签',
|
||||
description='Delete a tag by its ID.',
|
||||
dependencies=[Depends(SignRequired)],
|
||||
)
|
||||
def router_tag_delete(id: str) -> ResponseModel:
|
||||
"""
|
||||
Delete a tag by its ID.
|
||||
|
||||
Args:
|
||||
id (str): The ID of the tag to be deleted.
|
||||
|
||||
Returns:
|
||||
ResponseModel: A model containing the response data for the deletion operation.
|
||||
"""
|
||||
...
|
||||
370
routers/controllers/user.py
Normal file
370
routers/controllers/user.py
Normal file
@@ -0,0 +1,370 @@
|
||||
from fastapi import APIRouter, Depends
|
||||
from middleware.auth import SignRequired
|
||||
from models.response import ResponseModel
|
||||
|
||||
user_router = APIRouter(
|
||||
prefix="/user",
|
||||
tags=["user"],
|
||||
)
|
||||
|
||||
user_settings_router = APIRouter(
|
||||
prefix='/user/settings',
|
||||
tags=["user", "user_settings"],
|
||||
dependencies=[Depends(SignRequired)],
|
||||
)
|
||||
|
||||
@user_router.post(
|
||||
path='/session',
|
||||
summary='用户登录',
|
||||
description='User login endpoint.',
|
||||
)
|
||||
def router_user_session() -> ResponseModel:
|
||||
"""
|
||||
User login endpoint.
|
||||
|
||||
Returns:
|
||||
dict: A dictionary containing user session information.
|
||||
"""
|
||||
...
|
||||
|
||||
@user_router.post(
|
||||
path='/',
|
||||
summary='用户注册',
|
||||
description='User registration endpoint.',
|
||||
)
|
||||
def router_user_register() -> ResponseModel:
|
||||
"""
|
||||
User registration endpoint.
|
||||
|
||||
Returns:
|
||||
dict: A dictionary containing user registration information.
|
||||
"""
|
||||
...
|
||||
|
||||
@user_router.post(
|
||||
path='/2fa',
|
||||
summary='用两步验证登录',
|
||||
description='Two-factor authentication login endpoint.',
|
||||
)
|
||||
def router_user_2fa() -> ResponseModel:
|
||||
"""
|
||||
Two-factor authentication login endpoint.
|
||||
|
||||
Returns:
|
||||
dict: A dictionary containing two-factor authentication information.
|
||||
"""
|
||||
...
|
||||
|
||||
@user_router.post(
|
||||
path='/reset',
|
||||
summary='发送密码重设邮件',
|
||||
description='Send a password reset email.',
|
||||
)
|
||||
def router_user_reset() -> ResponseModel:
|
||||
"""
|
||||
Send a password reset email.
|
||||
|
||||
Returns:
|
||||
dict: A dictionary containing information about the password reset email.
|
||||
"""
|
||||
...
|
||||
|
||||
@user_router.patch(
|
||||
path='/reset',
|
||||
summary='通过邮件里的链接重设密码',
|
||||
description='Reset password via email link.',
|
||||
)
|
||||
def router_user_reset_patch() -> ResponseModel:
|
||||
"""
|
||||
Reset password via email link.
|
||||
|
||||
Returns:
|
||||
dict: A dictionary containing information about the password reset.
|
||||
"""
|
||||
...
|
||||
|
||||
@user_router.get(
|
||||
path='/qq',
|
||||
summary='初始化QQ登录',
|
||||
description='Initialize QQ login for a user.',
|
||||
)
|
||||
def router_user_qq() -> ResponseModel:
|
||||
"""
|
||||
Initialize QQ login for a user.
|
||||
|
||||
Returns:
|
||||
dict: A dictionary containing QQ login initialization information.
|
||||
"""
|
||||
...
|
||||
|
||||
@user_router.get(
|
||||
path='/activate/{id}',
|
||||
summary='邮件激活',
|
||||
description='Activate user account via email link.',
|
||||
)
|
||||
def router_user_activate(id: str) -> ResponseModel:
|
||||
"""
|
||||
Activate user account via email link.
|
||||
|
||||
Args:
|
||||
id (str): The activation ID from the email link.
|
||||
|
||||
Returns:
|
||||
dict: A dictionary containing activation information.
|
||||
"""
|
||||
...
|
||||
|
||||
@user_router.get(
|
||||
path='authn/{username}',
|
||||
summary='WebAuthn登录初始化',
|
||||
description='Initialize WebAuthn login for a user.',
|
||||
)
|
||||
def router_user_authn(username: str) -> ResponseModel:
|
||||
"""
|
||||
Initialize WebAuthn login for a user.
|
||||
|
||||
Args:
|
||||
username (str): The username of the user.
|
||||
|
||||
Returns:
|
||||
dict: A dictionary containing WebAuthn initialization information.
|
||||
"""
|
||||
...
|
||||
|
||||
@user_router.post(
|
||||
path='authn/finish/{username}',
|
||||
summary='WebAuthn登录',
|
||||
description='Finish WebAuthn login for a user.',
|
||||
)
|
||||
def router_user_authn_finish(username: str) -> ResponseModel:
|
||||
"""
|
||||
Finish WebAuthn login for a user.
|
||||
|
||||
Args:
|
||||
username (str): The username of the user.
|
||||
|
||||
Returns:
|
||||
dict: A dictionary containing WebAuthn login information.
|
||||
"""
|
||||
...
|
||||
|
||||
@user_router.get(
|
||||
path='/profile/{id}',
|
||||
summary='获取用户主页展示用分享',
|
||||
description='Get user profile for display.',
|
||||
)
|
||||
def router_user_profile(id: str) -> ResponseModel:
|
||||
"""
|
||||
Get user profile for display.
|
||||
|
||||
Args:
|
||||
id (str): The user ID.
|
||||
|
||||
Returns:
|
||||
dict: A dictionary containing user profile information.
|
||||
"""
|
||||
...
|
||||
|
||||
@user_router.get(
|
||||
path='/avatar/{id}/{size}',
|
||||
summary='获取用户头像',
|
||||
description='Get user avatar by ID and size.',
|
||||
)
|
||||
def router_user_avatar(id: str, size: int = 128) -> ResponseModel:
|
||||
"""
|
||||
Get user avatar by ID and size.
|
||||
|
||||
Args:
|
||||
id (str): The user ID.
|
||||
size (int): The size of the avatar image.
|
||||
|
||||
Returns:
|
||||
str: A Base64 encoded string of the user avatar image.
|
||||
"""
|
||||
...
|
||||
|
||||
#####################
|
||||
# 需要登录的接口
|
||||
#####################
|
||||
|
||||
@user_router.get(
|
||||
path='/me',
|
||||
summary='获取用户信息',
|
||||
description='Get user information.',
|
||||
dependencies=[Depends(SignRequired)],
|
||||
)
|
||||
def router_user_me() -> ResponseModel:
|
||||
"""
|
||||
Get user information.
|
||||
|
||||
Returns:
|
||||
dict: A dictionary containing user information.
|
||||
"""
|
||||
...
|
||||
|
||||
@user_router.get(
|
||||
path='/storage',
|
||||
summary='存储信息',
|
||||
description='Get user storage information.',
|
||||
dependencies=[Depends(SignRequired)],
|
||||
)
|
||||
def router_user_storage() -> ResponseModel:
|
||||
"""
|
||||
Get user storage information.
|
||||
|
||||
Returns:
|
||||
dict: A dictionary containing user storage information.
|
||||
"""
|
||||
...
|
||||
|
||||
@user_router.put(
|
||||
path='/authn/start',
|
||||
summary='WebAuthn登录初始化',
|
||||
description='Initialize WebAuthn login for a user.',
|
||||
dependencies=[Depends(SignRequired)],
|
||||
)
|
||||
def router_user_authn_start() -> ResponseModel:
|
||||
"""
|
||||
Initialize WebAuthn login for a user.
|
||||
|
||||
Returns:
|
||||
dict: A dictionary containing WebAuthn initialization information.
|
||||
"""
|
||||
...
|
||||
|
||||
@user_router.put(
|
||||
path='/authn/finish',
|
||||
summary='WebAuthn登录',
|
||||
description='Finish WebAuthn login for a user.',
|
||||
dependencies=[Depends(SignRequired)],
|
||||
)
|
||||
def router_user_authn_finish() -> ResponseModel:
|
||||
"""
|
||||
Finish WebAuthn login for a user.
|
||||
|
||||
Returns:
|
||||
dict: A dictionary containing WebAuthn login information.
|
||||
"""
|
||||
...
|
||||
|
||||
@user_settings_router.get(
|
||||
path='/policies',
|
||||
summary='获取用户可选存储策略',
|
||||
description='Get user selectable storage policies.',
|
||||
)
|
||||
def router_user_settings_policies() -> ResponseModel:
|
||||
"""
|
||||
Get user selectable storage policies.
|
||||
|
||||
Returns:
|
||||
dict: A dictionary containing available storage policies for the user.
|
||||
"""
|
||||
...
|
||||
|
||||
@user_settings_router.get(
|
||||
path='/nodes',
|
||||
summary='获取用户可选节点',
|
||||
description='Get user selectable nodes.',
|
||||
dependencies=[Depends(SignRequired)],
|
||||
)
|
||||
def router_user_settings_nodes() -> ResponseModel:
|
||||
"""
|
||||
Get user selectable nodes.
|
||||
|
||||
Returns:
|
||||
dict: A dictionary containing available nodes for the user.
|
||||
"""
|
||||
...
|
||||
|
||||
@user_settings_router.get(
|
||||
path='/tasks',
|
||||
summary='任务队列',
|
||||
description='Get user task queue.',
|
||||
dependencies=[Depends(SignRequired)],
|
||||
)
|
||||
def router_user_settings_tasks() -> ResponseModel:
|
||||
"""
|
||||
Get user task queue.
|
||||
|
||||
Returns:
|
||||
dict: A dictionary containing the user's task queue information.
|
||||
"""
|
||||
...
|
||||
|
||||
@user_settings_router.get(
|
||||
path='/',
|
||||
summary='获取当前用户设定',
|
||||
description='Get current user settings.',
|
||||
dependencies=[Depends(SignRequired)],
|
||||
)
|
||||
def router_user_settings() -> ResponseModel:
|
||||
"""
|
||||
Get current user settings.
|
||||
|
||||
Returns:
|
||||
dict: A dictionary containing the user's current settings.
|
||||
"""
|
||||
...
|
||||
|
||||
@user_settings_router.post(
|
||||
path='/avatar',
|
||||
summary='从文件上传头像',
|
||||
description='Upload user avatar from file.',
|
||||
dependencies=[Depends(SignRequired)],
|
||||
)
|
||||
def router_user_settings_avatar() -> ResponseModel:
|
||||
"""
|
||||
Upload user avatar from file.
|
||||
|
||||
Returns:
|
||||
dict: A dictionary containing the result of the avatar upload.
|
||||
"""
|
||||
...
|
||||
|
||||
@user_settings_router.put(
|
||||
path='/avatar',
|
||||
summary='设定为Gravatar头像',
|
||||
description='Set user avatar to Gravatar.',
|
||||
dependencies=[Depends(SignRequired)],
|
||||
)
|
||||
def router_user_settings_avatar_gravatar() -> ResponseModel:
|
||||
"""
|
||||
Set user avatar to Gravatar.
|
||||
|
||||
Returns:
|
||||
dict: A dictionary containing the result of setting the Gravatar avatar.
|
||||
"""
|
||||
...
|
||||
|
||||
@user_settings_router.patch(
|
||||
path='/{option}',
|
||||
summary='更新用户设定',
|
||||
description='Update user settings.',
|
||||
dependencies=[Depends(SignRequired)],
|
||||
)
|
||||
def router_user_settings_patch(option: str) -> ResponseModel:
|
||||
"""
|
||||
Update user settings.
|
||||
|
||||
Args:
|
||||
option (str): The setting option to update.
|
||||
|
||||
Returns:
|
||||
dict: A dictionary containing the result of the settings update.
|
||||
"""
|
||||
...
|
||||
|
||||
@user_settings_router.get(
|
||||
path='/2fa',
|
||||
summary='获取两步验证初始化信息',
|
||||
description='Get two-factor authentication initialization information.',
|
||||
dependencies=[Depends(SignRequired)],
|
||||
)
|
||||
def router_user_settings_2fa() -> ResponseModel:
|
||||
"""
|
||||
Get two-factor authentication initialization information.
|
||||
|
||||
Returns:
|
||||
dict: A dictionary containing two-factor authentication setup information.
|
||||
"""
|
||||
...
|
||||
104
routers/controllers/vas.py
Normal file
104
routers/controllers/vas.py
Normal file
@@ -0,0 +1,104 @@
|
||||
from fastapi import APIRouter, Depends
|
||||
from middleware.auth import SignRequired
|
||||
from models.response import ResponseModel
|
||||
|
||||
vas_router = APIRouter(
|
||||
prefix="/vas",
|
||||
tags=["vas"]
|
||||
)
|
||||
|
||||
@vas_router.get(
|
||||
path='/pack',
|
||||
summary='获取容量包及配额信息',
|
||||
description='Get information about storage packs and quotas.',
|
||||
dependencies=[Depends(SignRequired)]
|
||||
)
|
||||
def router_vas_pack() -> ResponseModel:
|
||||
"""
|
||||
Get information about storage packs and quotas.
|
||||
|
||||
Returns:
|
||||
ResponseModel: A model containing the response data for storage packs and quotas.
|
||||
"""
|
||||
...
|
||||
|
||||
@vas_router.get(
|
||||
path='/product',
|
||||
summary='获取商品信息,同时返回支付信息',
|
||||
description='Get product information along with payment details.',
|
||||
dependencies=[Depends(SignRequired)]
|
||||
)
|
||||
def router_vas_product() -> ResponseModel:
|
||||
"""
|
||||
Get product information along with payment details.
|
||||
|
||||
Returns:
|
||||
ResponseModel: A model containing the response data for products and payment information.
|
||||
"""
|
||||
...
|
||||
|
||||
@vas_router.post(
|
||||
path='/order',
|
||||
summary='新建支付订单',
|
||||
description='Create an order for a product.',
|
||||
dependencies=[Depends(SignRequired)]
|
||||
)
|
||||
def router_vas_order() -> ResponseModel:
|
||||
"""
|
||||
Create an order for a product.
|
||||
|
||||
Returns:
|
||||
ResponseModel: A model containing the response data for the created order.
|
||||
"""
|
||||
...
|
||||
|
||||
@vas_router.get(
|
||||
path='/order/{id}',
|
||||
summary='查询订单状态',
|
||||
description='Get information about a specific payment order by ID.',
|
||||
dependencies=[Depends(SignRequired)]
|
||||
)
|
||||
def router_vas_order_get(id: str) -> ResponseModel:
|
||||
"""
|
||||
Get information about a specific payment order by ID.
|
||||
|
||||
Args:
|
||||
id (str): The ID of the order to retrieve information for.
|
||||
|
||||
Returns:
|
||||
ResponseModel: A model containing the response data for the specified order.
|
||||
"""
|
||||
...
|
||||
|
||||
@vas_router.get(
|
||||
path='/redeem',
|
||||
summary='获取兑换码信息',
|
||||
description='Get information about a specific redemption code.',
|
||||
dependencies=[Depends(SignRequired)]
|
||||
)
|
||||
def router_vas_redeem(code: str) -> ResponseModel:
|
||||
"""
|
||||
Get information about a specific redemption code.
|
||||
|
||||
Args:
|
||||
code (str): The redemption code to retrieve information for.
|
||||
|
||||
Returns:
|
||||
ResponseModel: A model containing the response data for the specified redemption code.
|
||||
"""
|
||||
...
|
||||
|
||||
@vas_router.post(
|
||||
path='/redeem',
|
||||
summary='执行兑换',
|
||||
description='Redeem a redemption code for a product or service.',
|
||||
dependencies=[Depends(SignRequired)]
|
||||
)
|
||||
def router_vas_redeem_post() -> ResponseModel:
|
||||
"""
|
||||
Redeem a redemption code for a product or service.
|
||||
|
||||
Returns:
|
||||
ResponseModel: A model containing the response data for the redeemed code.
|
||||
"""
|
||||
...
|
||||
108
routers/controllers/webdav.py
Normal file
108
routers/controllers/webdav.py
Normal file
@@ -0,0 +1,108 @@
|
||||
from fastapi import APIRouter, Depends, Request
|
||||
from middleware.auth import SignRequired
|
||||
from models.response import ResponseModel
|
||||
|
||||
# WebDAV 管理路由
|
||||
webdav_router = APIRouter(
|
||||
prefix='/webdav',
|
||||
tags=["webdav"],
|
||||
)
|
||||
|
||||
@webdav_router.get(
|
||||
path='/accounts',
|
||||
summary='获取账号信息',
|
||||
description='Get account information for WebDAV.',
|
||||
dependencies=[Depends(SignRequired)],
|
||||
)
|
||||
def router_webdav_accounts() -> ResponseModel:
|
||||
"""
|
||||
Get account information for WebDAV.
|
||||
|
||||
Returns:
|
||||
ResponseModel: A model containing the response data for the account information.
|
||||
"""
|
||||
...
|
||||
|
||||
@webdav_router.post(
|
||||
path='/accounts',
|
||||
summary='新建账号',
|
||||
description='Create a new WebDAV account.',
|
||||
dependencies=[Depends(SignRequired)],
|
||||
)
|
||||
def router_webdav_create_account() -> ResponseModel:
|
||||
"""
|
||||
Create a new WebDAV account.
|
||||
|
||||
Returns:
|
||||
ResponseModel: A model containing the response data for the created account.
|
||||
"""
|
||||
...
|
||||
|
||||
@webdav_router.delete(
|
||||
path='/accounts/{id}',
|
||||
summary='删除账号',
|
||||
description='Delete a WebDAV account by its ID.',
|
||||
dependencies=[Depends(SignRequired)],
|
||||
)
|
||||
def router_webdav_delete_account(id: str) -> ResponseModel:
|
||||
"""
|
||||
Delete a WebDAV account by its ID.
|
||||
|
||||
Args:
|
||||
id (str): The ID of the account to be deleted.
|
||||
|
||||
Returns:
|
||||
ResponseModel: A model containing the response data for the deletion operation.
|
||||
"""
|
||||
...
|
||||
|
||||
@webdav_router.post(
|
||||
path='/mount',
|
||||
summary='新建目录挂载',
|
||||
description='Create a new WebDAV mount point.',
|
||||
dependencies=[Depends(SignRequired)],
|
||||
)
|
||||
def router_webdav_create_mount() -> ResponseModel:
|
||||
"""
|
||||
Create a new WebDAV mount point.
|
||||
|
||||
Returns:
|
||||
ResponseModel: A model containing the response data for the created mount point.
|
||||
"""
|
||||
...
|
||||
|
||||
@webdav_router.delete(
|
||||
path='/mount/{id}',
|
||||
summary='删除目录挂载',
|
||||
description='Delete a WebDAV mount point by its ID.',
|
||||
dependencies=[Depends(SignRequired)],
|
||||
)
|
||||
def router_webdav_delete_mount(id: str) -> ResponseModel:
|
||||
"""
|
||||
Delete a WebDAV mount point by its ID.
|
||||
|
||||
Args:
|
||||
id (str): The ID of the mount point to be deleted.
|
||||
|
||||
Returns:
|
||||
ResponseModel: A model containing the response data for the deletion operation.
|
||||
"""
|
||||
...
|
||||
|
||||
@webdav_router.patch(
|
||||
path='accounts/{id}',
|
||||
summary='更新账号信息',
|
||||
description='Update WebDAV account information by ID.',
|
||||
dependencies=[Depends(SignRequired)],
|
||||
)
|
||||
def router_webdav_update_account(id: str) -> ResponseModel:
|
||||
"""
|
||||
Update WebDAV account information by ID.
|
||||
|
||||
Args:
|
||||
id (str): The ID of the account to be updated.
|
||||
|
||||
Returns:
|
||||
ResponseModel: A model containing the response data for the updated account.
|
||||
"""
|
||||
...
|
||||
43
routers/routers.py
Normal file
43
routers/routers.py
Normal file
@@ -0,0 +1,43 @@
|
||||
from fastapi import APIRouter
|
||||
|
||||
from .controllers import (
|
||||
share,
|
||||
site,
|
||||
user,
|
||||
file,
|
||||
aria2,
|
||||
directory,
|
||||
object,
|
||||
callback,
|
||||
vas,
|
||||
tag,
|
||||
webdav,
|
||||
admin
|
||||
)
|
||||
|
||||
Router: list[APIRouter] = [
|
||||
share.share_router,
|
||||
site.site_router,
|
||||
user.user_router,
|
||||
user.user_settings_router,
|
||||
file.file_router,
|
||||
file.file_upload_router,
|
||||
aria2.aria2_router,
|
||||
directory.directory_router,
|
||||
object.object_router,
|
||||
callback.callback_router,
|
||||
callback.oauth_router,
|
||||
callback.pay_router,
|
||||
callback.upload_router,
|
||||
vas.vas_router,
|
||||
tag.tag_router,
|
||||
webdav.webdav_router,
|
||||
admin.admin_router,
|
||||
admin.admin_group_router,
|
||||
admin.admin_user_router,
|
||||
admin.admin_file_router,
|
||||
admin.admin_aria2_router,
|
||||
admin.admin_policy_router,
|
||||
admin.admin_task_router,
|
||||
admin.admin_vas_router
|
||||
]
|
||||
15
test_main.py
Normal file
15
test_main.py
Normal file
@@ -0,0 +1,15 @@
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from main import app
|
||||
|
||||
client = TestClient(app)
|
||||
|
||||
|
||||
def test_read_main():
|
||||
from pkg.conf.appmeta import BackendVersion
|
||||
response = client.get("/api/site/ping")
|
||||
assert response.status_code == 200
|
||||
assert response.json() == {
|
||||
"code": 0,
|
||||
'data': BackendVersion,
|
||||
'msg': None}
|
||||
Reference in New Issue
Block a user