add:支持使用阿里云OSS进行对象存储服务

fix:删除utils中未使用的第三方库chardet
This commit is contained in:
ZHYCarge
2023-01-15 22:06:01 +08:00
parent cfa865c6cd
commit 1b26b03758
7 changed files with 93 additions and 10 deletions
+6
View File
@@ -127,6 +127,7 @@ async def index(code: str, ip: str = Depends(error_ip_limit), s: AsyncSession =
await s.execute(update(Codes).where(Codes.id == info.id).values(count=info.count - 1)) await s.execute(update(Codes).where(Codes.id == info.id).values(count=info.count - 1))
await s.commit() await s.commit()
if info.type != 'text': if info.type != 'text':
if settings.STORAGE_ENGINE == 'filesystem':
info.text = f'/select?code={code}' info.text = f'/select?code={code}'
return { return {
'detail': f'取件成功,文件将在{settings.DELETE_EXPIRE_FILES_INTERVAL}分钟后删除', 'detail': f'取件成功,文件将在{settings.DELETE_EXPIRE_FILES_INTERVAL}分钟后删除',
@@ -175,8 +176,11 @@ async def get_file(code: str, ip: str = Depends(error_ip_limit), s: AsyncSession
return {'detail': '查询成功', 'data': info.text} return {'detail': '查询成功', 'data': info.text}
# 如果是文件,返回文件 # 如果是文件,返回文件
else: else:
if settings.STORAGE_ENGINE == 'filesystem':
filepath = await storage.get_filepath(info.text) filepath = await storage.get_filepath(info.text)
return FileResponse(filepath, filename=info.name) return FileResponse(filepath, filename=info.name)
else:
return {'detail': '查询成功', 'data': info.text}
@app.post('/share', dependencies=[Depends(admin_required)], description='分享文件') @app.post('/share', dependencies=[Depends(admin_required)], description='分享文件')
@@ -206,6 +210,8 @@ async def share(background_tasks: BackgroundTasks, text: str = Form(default=None
background_tasks.add_task(storage.save_file, file, _text) background_tasks.add_task(storage.save_file, file, _text)
else: else:
size, _text, _type, name = len(text), text, 'text', '文本分享' size, _text, _type, name = len(text), text, 'text', '文本分享'
if settings.STORAGE_ENGINE == 'aliyunsystem':
_text = f"https://{settings.BUCKET_NAME}.{settings.OSS_ENDPOINT}/"+_text
info = Codes(code=code, text=_text, size=size, type=_type, name=name, count=exp_count, exp_time=exp_time, key=key) info = Codes(code=code, text=_text, size=size, type=_type, name=name, count=exp_count, exp_time=exp_time, key=key)
s.add(info) s.add(info)
await s.commit() await s.commit()
+10
View File
@@ -21,6 +21,7 @@
- [x] 匿名分享:无需注册,无需登录 - [x] 匿名分享:无需注册,无需登录
- [x] 管理面板:查看所有文件,删除文件 - [x] 管理面板:查看所有文件,删除文件
- [x] 一键部署:docker一键部署 - [x] 一键部署:docker一键部署
- [x] 多种存储方式:阿里云OSS、本地文件流
## 部署方式 ## 部署方式
@@ -160,6 +161,15 @@ DESCRIPTION=FileCodeBox,文件快递柜,口令传送箱,匿名口令分享
KEYWORDS=FileCodeBox,文件快递柜,口令传送箱,匿名口令分享文本,文件,图片,视频,音频,压缩包等文件 KEYWORDS=FileCodeBox,文件快递柜,口令传送箱,匿名口令分享文本,文件,图片,视频,音频,压缩包等文件
# 存储引擎 # 存储引擎
STORAGE_ENGINE=filesystem STORAGE_ENGINE=filesystem
# 如果使用阿里云OSS服务的话需要额外创建如下参数:
# 阿里云账号AccessKey
KeyId=阿里云账号AccessKey
# 阿里云账号AccessKeySecret
KeySecret=阿里云账号AccessKeySecret
# 阿里云OSS Bucket的地域节点
OSS_ENDPOINT=阿里云OSS Bucket的地域节点
# 阿里云OSS Bucket的BucketName
BUCKET_NAME=阿里云OSS Bucket的BucketName
``` ```
## 接口文档 ## 接口文档
+10
View File
@@ -22,6 +22,7 @@
- [x] anonymous sharing: no registration, no login - [x] anonymous sharing: no registration, no login
- [x] management Panel: View all files and delete them - [x] management Panel: View all files and delete them
- [x] one-click deployment: docker one-click deployment - [x] one-click deployment: docker one-click deployment
- [x] A variety of storage methods : Aliyun OSS、 local file flow
## Deployment method ## Deployment method
@@ -175,6 +176,15 @@ DESCRIPTION=FileCodeBox,文件快递柜,口令传送箱,匿名口令分享
KEYWORDS=FileCodeBox,文件快递柜,口令传送箱,匿名口令分享文本,文件,图片,视频,音频,压缩包等文件 KEYWORDS=FileCodeBox,文件快递柜,口令传送箱,匿名口令分享文本,文件,图片,视频,音频,压缩包等文件
# 存储引擎 # 存储引擎
STORAGE_ENGINE=filesystem STORAGE_ENGINE=filesystem
# 如果使用阿里云OSS服务的话需要额外创建如下参数:
# 阿里云账号AccessKey
KeyId=阿里云账号AccessKey
# 阿里云账号AccessKeySecret
KeySecret=阿里云账号AccessKeySecret
# 阿里云OSS Bucket的地域节点
OSS_ENDPOINT=阿里云OSS Bucket的地域节点
# 阿里云OSS Bucket的BucketName
BUCKET_NAME=阿里云OSS Bucket的BucketName
``` ```
## Status ## Status
+1
View File
@@ -5,3 +5,4 @@ python-multipart==0.0.5
uvicorn==0.15.0 uvicorn==0.15.0
greenlet==2.0.1 greenlet==2.0.1
starlette~=0.22.0 starlette~=0.22.0
oss2==2.16.0
+10 -1
View File
@@ -48,5 +48,14 @@ TITLE = config('TITLE', cast=str, default="文件快递柜")
DESCRIPTION = config('DESCRIPTION', cast=str, default="FileCodeBox,文件快递柜,口令传送箱,匿名口令分享文本,文件等文件") DESCRIPTION = config('DESCRIPTION', cast=str, default="FileCodeBox,文件快递柜,口令传送箱,匿名口令分享文本,文件等文件")
# 网站关键词 # 网站关键词
KEYWORDS = config('KEYWORDS', cast=str, default="FileCodeBox,文件快递柜,口令传送箱,匿名口令分享文本,文件等文件") KEYWORDS = config('KEYWORDS', cast=str, default="FileCodeBox,文件快递柜,口令传送箱,匿名口令分享文本,文件等文件")
# 存储引擎 # 存储引擎['aliyunsystem','filesystem']
STORAGE_ENGINE = config('STORAGE_ENGINE', cast=str, default="filesystem") STORAGE_ENGINE = config('STORAGE_ENGINE', cast=str, default="filesystem")
# 如果使用阿里云OSS的话需要创建如下参数
# 阿里云账号AccessKey
KeyId = config('KeyId',cast=str,default="阿里云账号AccessKey")
# 阿里云账号AccessKeySecret
KeySecret = config('KeySecret',cast=str,default="阿里云账号AccessKeySecret")
# 阿里云OSS Bucket的地域节点
OSS_ENDPOINT= config('BUCKET_URL',cast=str,default="阿里云OSS Bucket的地域节点")
# 阿里云OSS Bucket的BucketName
BUCKET_NAME = config('BUCKET_NAME',cast=str,default="阿里云OSS Bucket的BucketName")
+52 -3
View File
@@ -3,10 +3,58 @@ import asyncio
from datetime import datetime from datetime import datetime
from pathlib import Path from pathlib import Path
from typing import BinaryIO from typing import BinaryIO
from fastapi import UploadFile from fastapi import UploadFile
import settings import settings
import oss2
class AliyunFileStore:
auth = oss2.Auth(settings.KeyId, settings.KeySecret)
bucket = oss2.Bucket(auth, settings.OSS_ENDPOINT, settings.BUCKET_NAME)
def upload_file(self, upload_filepath, remote_filepath):
self.bucket.put_object_from_file(remote_filepath, upload_filepath)
async def get_text(self, file: UploadFile, key: str):
ext = file.filename.split('.')[-1]
now = datetime.now()
path = f"FileCodeBox/upload/{now.year}/{now.month}/{now.day}"
text = f"{path}/{f'{key}.{ext}'}"
return text
async def get_filepath(self, text: str):
return text
@staticmethod
async def get_size(file: UploadFile):
f = file.file
f.seek(0, os.SEEK_END)
size = f.tell()
f.seek(0, os.SEEK_SET)
return size
@staticmethod
def _save(filepath, file: BinaryIO):
with open(filepath, 'wb') as f:
chunk_size = 256 * 1024
chunk = file.read(chunk_size)
while chunk:
f.write(chunk)
chunk = file.read(chunk_size)
async def save_file(self, file: UploadFile, remote_filepath: str):
now = int(datetime.now().timestamp())
upload_filepath = settings.DATA_ROOT+str(now)
await asyncio.to_thread(self._save, upload_filepath, file.file)
self.upload_file(upload_filepath,remote_filepath)
await asyncio.to_thread(os.remove,upload_filepath)
async def delete_files(self, texts):
tasks = [self.delete_file(text) for text in texts]
await asyncio.gather(*tasks)
async def delete_file(self, text: str):
self.bucket.delete_object(text)
class FileSystemStorage: class FileSystemStorage:
@@ -68,5 +116,6 @@ class FileSystemStorage:
STORAGE_ENGINE = { STORAGE_ENGINE = {
"filesystem": FileSystemStorage "filesystem": FileSystemStorage,
"aliyunsystem": AliyunFileStore
} }
-2
View File
@@ -1,8 +1,6 @@
import datetime import datetime
import random import random
import asyncio import asyncio
import chardet
from sqlalchemy import or_, select, delete from sqlalchemy import or_, select, delete
from sqlalchemy.ext.asyncio.session import AsyncSession from sqlalchemy.ext.asyncio.session import AsyncSession
import settings import settings