update:images

This commit is contained in:
lan
2023-12-06 08:37:33 +08:00
parent 48fe424ed4
commit bb00ffb582
9 changed files with 58 additions and 55 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 597 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 672 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 584 KiB

+44 -2
View File
@@ -2,6 +2,7 @@
# @Author : Lan # @Author : Lan
# @File : views.py # @File : views.py
# @Software: PyCharm # @Software: PyCharm
# 导入所需的库和模块
from fastapi import APIRouter, Form, UploadFile, File, Depends, HTTPException from fastapi import APIRouter, Form, UploadFile, File, Depends, HTTPException
from apps.admin.depends import admin_required from apps.admin.depends import admin_required
from apps.base.models import FileCodes from apps.base.models import FileCodes
@@ -12,15 +13,19 @@ from core.settings import settings
from core.storage import file_storage from core.storage import file_storage
from core.utils import get_select_token from core.utils import get_select_token
# 创建一个API路由
share_api = APIRouter( share_api = APIRouter(
prefix='/share', prefix='/share', # 路由前缀
tags=['分享'], tags=['分享'], # 标签
) )
# 分享文本的API
@share_api.post('/text/', dependencies=[Depends(admin_required)]) @share_api.post('/text/', dependencies=[Depends(admin_required)])
async def share_text(text: str = Form(...), expire_value: int = Form(default=1, gt=0), expire_style: str = Form(default='day'), ip: str = Depends(upload_ip_limit)): async def share_text(text: str = Form(...), expire_value: int = Form(default=1, gt=0), expire_style: str = Form(default='day'), ip: str = Depends(upload_ip_limit)):
# 获取过期信息
expired_at, expired_count, used_count, code = await get_expire_info(expire_value, expire_style) expired_at, expired_count, used_count, code = await get_expire_info(expire_value, expire_style)
# 创建一个新的FileCodes实例
await FileCodes.create( await FileCodes.create(
code=code, code=code,
text=text, text=text,
@@ -30,19 +35,27 @@ async def share_text(text: str = Form(...), expire_value: int = Form(default=1,
size=len(text), size=len(text),
prefix='文本分享' prefix='文本分享'
) )
# 添加IP到限制列表
upload_ip_limit.add_ip(ip) upload_ip_limit.add_ip(ip)
# 返回API响应
return APIResponse(detail={ return APIResponse(detail={
'code': code, 'code': code,
}) })
# 分享文件的API
@share_api.post('/file/', dependencies=[Depends(admin_required)]) @share_api.post('/file/', dependencies=[Depends(admin_required)])
async def share_file(expire_value: int = Form(default=1, gt=0), expire_style: str = Form(default='day'), file: UploadFile = File(...), ip: str = Depends(upload_ip_limit)): async def share_file(expire_value: int = Form(default=1, gt=0), expire_style: str = Form(default='day'), file: UploadFile = File(...), ip: str = Depends(upload_ip_limit)):
# 检查文件大小是否超过限制
if file.size > settings.uploadSize: if file.size > settings.uploadSize:
raise HTTPException(status_code=403, detail=f'文件大小超过限制,最大为{settings.uploadSize}字节') raise HTTPException(status_code=403, detail=f'文件大小超过限制,最大为{settings.uploadSize}字节')
# 获取过期信息
expired_at, expired_count, used_count, code = await get_expire_info(expire_value, expire_style) expired_at, expired_count, used_count, code = await get_expire_info(expire_value, expire_style)
# 获取文件路径和名称
path, suffix, prefix, uuid_file_name, save_path = await get_file_path_name(file) path, suffix, prefix, uuid_file_name, save_path = await get_file_path_name(file)
# 保存文件
await file_storage.save_file(file, save_path) await file_storage.save_file(file, save_path)
# 创建一个新的FileCodes实例
await FileCodes.create( await FileCodes.create(
code=code, code=code,
prefix=prefix, prefix=prefix,
@@ -54,43 +67,65 @@ async def share_file(expire_value: int = Form(default=1, gt=0), expire_style: st
expired_count=expired_count, expired_count=expired_count,
used_count=used_count, used_count=used_count,
) )
# 添加IP到限制列表
upload_ip_limit.add_ip(ip) upload_ip_limit.add_ip(ip)
# 返回API响应
return APIResponse(detail={ return APIResponse(detail={
'code': code, 'code': code,
'name': file.filename, 'name': file.filename,
}) })
# 根据code获取文件
async def get_code_file_by_code(code): async def get_code_file_by_code(code):
# 查询文件
file_code = await FileCodes.filter(code=code).first() file_code = await FileCodes.filter(code=code).first()
# 检查文件是否存在
if not file_code: if not file_code:
return False, '文件不存在' return False, '文件不存在'
# 检查文件是否过期
if await file_code.is_expired(): if await file_code.is_expired():
return False, '文件已过期', return False, '文件已过期',
return True, file_code return True, file_code
# 获取文件的API
@share_api.get('/select/') @share_api.get('/select/')
async def get_code_file(code: str, ip: str = Depends(error_ip_limit)): async def get_code_file(code: str, ip: str = Depends(error_ip_limit)):
# 获取文件
has, file_code = await get_code_file_by_code(code) has, file_code = await get_code_file_by_code(code)
# 检查文件是否存在
if not has: if not has:
# 添加IP到限制列表
error_ip_limit.add_ip(ip) error_ip_limit.add_ip(ip)
# 返回API响应
return APIResponse(code=404, detail=file_code) return APIResponse(code=404, detail=file_code)
# 更新文件的使用次数和过期次数
file_code.used_count += 1 file_code.used_count += 1
file_code.expired_count -= 1 file_code.expired_count -= 1
# 保存文件
await file_code.save() await file_code.save()
# 返回文件响应
return await file_storage.get_file_response(file_code) return await file_storage.get_file_response(file_code)
# 选择文件的API
@share_api.post('/select/') @share_api.post('/select/')
async def select_file(data: SelectFileModel, ip: str = Depends(error_ip_limit)): async def select_file(data: SelectFileModel, ip: str = Depends(error_ip_limit)):
# 获取文件
has, file_code = await get_code_file_by_code(data.code) has, file_code = await get_code_file_by_code(data.code)
# 检查文件是否存在
if not has: if not has:
# 添加IP到限制列表
error_ip_limit.add_ip(ip) error_ip_limit.add_ip(ip)
# 返回API响应
return APIResponse(code=404, detail=file_code) return APIResponse(code=404, detail=file_code)
# 更新文件的使用次数和过期次数
file_code.used_count += 1 file_code.used_count += 1
file_code.expired_count -= 1 file_code.expired_count -= 1
# 保存文件
await file_code.save() await file_code.save()
# 返回API响应
return APIResponse(detail={ return APIResponse(detail={
'code': file_code.code, 'code': file_code.code,
'name': file_code.prefix + file_code.suffix, 'name': file_code.prefix + file_code.suffix,
@@ -99,14 +134,21 @@ async def select_file(data: SelectFileModel, ip: str = Depends(error_ip_limit)):
}) })
# 下载文件的API
@share_api.get('/download') @share_api.get('/download')
async def download_file(key: str, code: str, ip: str = Depends(error_ip_limit)): async def download_file(key: str, code: str, ip: str = Depends(error_ip_limit)):
# 检查token是否有效
is_valid = await get_select_token(code) == key is_valid = await get_select_token(code) == key
if not is_valid: if not is_valid:
# 添加IP到限制列表
error_ip_limit.add_ip(ip) error_ip_limit.add_ip(ip)
# 获取文件
has, file_code = await get_code_file_by_code(code) has, file_code = await get_code_file_by_code(code)
# 检查文件是否存在
if not file_code: if not file_code:
# 返回API响应
return APIResponse(code=404, detail='文件不存在') return APIResponse(code=404, detail='文件不存在')
# 如果文件是文本,返回文本内容,否则返回文件响应
if file_code.text: if file_code.text:
return APIResponse(detail=file_code.text) return APIResponse(detail=file_code.text)
else: else:
+7 -5
View File
@@ -10,6 +10,7 @@ import io
import re import re
import sys import sys
import aioboto3 import aioboto3
import botocore
from fastapi import HTTPException, Response, UploadFile from fastapi import HTTPException, Response, UploadFile
from core.response import APIResponse from core.response import APIResponse
from core.settings import data_root, settings from core.settings import data_root, settings
@@ -94,7 +95,10 @@ class S3FileStorage(FileStorageInterface):
self.endpoint_url = settings.s3_endpoint_url self.endpoint_url = settings.s3_endpoint_url
self.aws_session_token = settings.aws_session_token self.aws_session_token = settings.aws_session_token
self.proxy = settings.s3_proxy self.proxy = settings.s3_proxy
self.session = aioboto3.Session(aws_access_key_id=self.access_key_id, aws_secret_access_key=self.secret_access_key) self.session = aioboto3.Session(
aws_access_key_id=self.access_key_id,
aws_secret_access_key=self.secret_access_key,
)
async def save_file(self, file: UploadFile, save_path: str): async def save_file(self, file: UploadFile, save_path: str):
async with self.session.client("s3", endpoint_url=self.endpoint_url, aws_session_token=self.aws_session_token) as s3: async with self.session.client("s3", endpoint_url=self.endpoint_url, aws_session_token=self.aws_session_token) as s3:
@@ -116,8 +120,7 @@ class S3FileStorage(FileStorageInterface):
tmp.seek(0) tmp.seek(0)
content = tmp.read() content = tmp.read()
tmp.close() tmp.close()
return Response(content, media_type="application/octet-stream", headers= return Response(content, media_type="application/octet-stream", headers={"Content-Disposition": f'attachment; filename="{filename.encode("utf-8").decode("latin-1")}"'})
{"Content-Disposition": f'attachment; filename="{filename.encode("utf-8").decode("latin-1")}"'})
except Exception: except Exception:
raise HTTPException(status_code=503, detail='服务代理下载异常,请稍后再试') raise HTTPException(status_code=503, detail='服务代理下载异常,请稍后再试')
@@ -228,8 +231,7 @@ class OneDriveFileStorage(FileStorageInterface):
tmp.seek(0) tmp.seek(0)
content = tmp.read() content = tmp.read()
tmp.close() tmp.close()
return Response(content, media_type="application/octet-stream", headers= return Response(content, media_type="application/octet-stream", headers={"Content-Disposition": f'attachment; filename="{filename.encode("utf-8").decode("latin-1")}"'})
{"Content-Disposition": f'attachment; filename="{filename.encode("utf-8").decode("latin-1")}"'})
except Exception: except Exception:
raise HTTPException(status_code=503, detail='服务代理下载异常,请稍后再试') raise HTTPException(status_code=503, detail='服务代理下载异常,请稍后再试')
+7 -48
View File
@@ -103,72 +103,31 @@ docker logs filecodebox
[https://share.lanol.cn](https://share.lanol.cn) [https://share.lanol.cn](https://share.lanol.cn)
### 暗黑模式 ### 截图
<table style="width:100%">
<tr style="width: 100%">
<td style="width: 50%">
<img src="https://fastly.jsdelivr.net/gh/vastsa/FileCodeBox@V1.6/images/img_10.png" alt="寄文件">
</td>
<td style="width: 50%">
<img src="https://fastly.jsdelivr.net/gh/vastsa/FileCodeBox@V1.6/images/img_11.png" alt="寄文件">
</td>
</tr>
</table>
### 寄件
<table style="width:100%"> <table style="width:100%">
<tr style="width: 100%"> <tr style="width: 100%">
<td style="width: 50%"> <td style="width: 50%">
<img src="https://fastly.jsdelivr.net/gh/vastsa/FileCodeBox@V1.6/images/img_1.png" alt="寄文件"> <img src="./.github/images/img.png" alt="寄文件">
</td> </td>
<td style="width: 50%"> <td style="width: 50%">
<img src="https://fastly.jsdelivr.net/gh/vastsa/FileCodeBox@V1.6/images/img_2.png" alt="寄文"> <img src="./.github/images/img_1.png" alt="寄文">
</td> </td>
</tr> </tr>
<tr style="width: 100%;">
<td colspan="2" style="width: 100%;">
<img src="https://fastly.jsdelivr.net/gh/vastsa/FileCodeBox@V1.6/images/img_3.png" alt="寄文本">
</td>
</tr>
</table>
### 取件
<table style="width: 100%">
<tr style="width: 100%"> <tr style="width: 100%">
<td style="width: 50%"> <td style="width: 50%">
<img src="https://fastly.jsdelivr.net/gh/vastsa/FileCodeBox@V1.6/images/img_6.png" alt="件"> <img src="./.github/images/img_2.png" alt="寄文件">
</td> </td>
<td style="width: 50%"> <td style="width: 50%">
<img src="https://fastly.jsdelivr.net/gh/vastsa/FileCodeBox@V1.6/images/img_5.png" alt="取件码错误"> <img src="./.github/images/img_3.png" alt="寄文件">
</td> </td>
</tr> </tr>
<tr style="width: 100%;">
<td colspan="2" style="width: 100%;">
<img src="https://fastly.jsdelivr.net/gh/vastsa/FileCodeBox@V1.6/images/img_4.png" alt="取文件">
</td>
</tr>
</table>
### 管理
<table style="width: 100%">
<tr style="width: 100%"> <tr style="width: 100%">
<td style="width: 50%"> <td style="width: 50%">
<img src="https://fastly.jsdelivr.net/gh/vastsa/FileCodeBox@V1.6/images/img_7.png" alt="admin"> <img src="./.github/images/img_4.png" alt="寄文件">
</td> </td>
<td style="width: 50%"> <td style="width: 50%">
<img src="https://fastly.jsdelivr.net/gh/vastsa/FileCodeBox@V1.6/images/img_12.png" alt="admin"> <img src="./.github/images/img_5.png" alt="寄文件">
</td>
</tr>
<tr style="width: 100%;">
<td colspan="2" style="width: 100%;">
<img src="https://fastly.jsdelivr.net/gh/vastsa/FileCodeBox@V1.6/images/img_13.png" alt="admin">
</td> </td>
</tr> </tr>
</table> </table>