调整文件大小计算和写入方法
This commit is contained in:
@@ -4,7 +4,7 @@ import random
|
|||||||
import asyncio
|
import asyncio
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
from fastapi import FastAPI, Depends, UploadFile, Form, File, HTTPException
|
from fastapi import FastAPI, Depends, UploadFile, Form, File, HTTPException, BackgroundTasks
|
||||||
from starlette.responses import HTMLResponse, FileResponse
|
from starlette.responses import HTMLResponse, FileResponse
|
||||||
from starlette.staticfiles import StaticFiles
|
from starlette.staticfiles import StaticFiles
|
||||||
|
|
||||||
@@ -130,8 +130,8 @@ async def index(code: str, ip: str = Depends(ip_limit), s: AsyncSession = Depend
|
|||||||
|
|
||||||
|
|
||||||
@app.post('/share')
|
@app.post('/share')
|
||||||
async def share(text: str = Form(default=None), style: str = Form(default='2'), value: int = Form(default=1),
|
async def share(background_tasks: BackgroundTasks, text: str = Form(default=None), style: str = Form(default='2'),
|
||||||
file: UploadFile = File(default=None), s: AsyncSession = Depends(get_session)):
|
value: int = Form(default=1), file: UploadFile = File(default=None), s: AsyncSession = Depends(get_session)):
|
||||||
code = await get_code(s)
|
code = await get_code(s)
|
||||||
if style == '2':
|
if style == '2':
|
||||||
if value > 7:
|
if value > 7:
|
||||||
@@ -148,11 +148,11 @@ async def share(text: str = Form(default=None), style: str = Form(default='2'),
|
|||||||
exp_count = -1
|
exp_count = -1
|
||||||
key = uuid.uuid4().hex
|
key = uuid.uuid4().hex
|
||||||
if file:
|
if file:
|
||||||
file_bytes = await file.read()
|
size = await storage.get_size(file)
|
||||||
size = len(file_bytes)
|
|
||||||
if size > settings.FILE_SIZE_LIMIT:
|
if size > settings.FILE_SIZE_LIMIT:
|
||||||
raise HTTPException(status_code=400, detail="文件过大")
|
raise HTTPException(status_code=400, detail="文件过大")
|
||||||
_text, _type, name = await storage.save_file(file, file_bytes, key), file.content_type, file.filename
|
_text, _type, name = await storage.get_text(file, key), file.content_type, file.filename
|
||||||
|
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', '文本分享'
|
||||||
info = Codes(
|
info = Codes(
|
||||||
|
|||||||
+29
-13
@@ -1,7 +1,10 @@
|
|||||||
import os
|
import os
|
||||||
import asyncio
|
import asyncio
|
||||||
import datetime
|
from datetime import datetime
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
from typing import BinaryIO
|
||||||
|
|
||||||
|
from fastapi import UploadFile
|
||||||
|
|
||||||
import settings
|
import settings
|
||||||
|
|
||||||
@@ -11,25 +14,38 @@ class FileSystemStorage:
|
|||||||
STATIC_URL = settings.STATIC_URL
|
STATIC_URL = settings.STATIC_URL
|
||||||
NAME = "filesystem"
|
NAME = "filesystem"
|
||||||
|
|
||||||
async def get_filepath(self, path):
|
async def get_filepath(self, text: str):
|
||||||
return self.DATA_ROOT / path.lstrip(self.STATIC_URL + '/')
|
return self.DATA_ROOT / text.lstrip(self.STATIC_URL + '/')
|
||||||
|
|
||||||
def _save(self, filepath, file_bytes):
|
async def get_text(self, file: UploadFile, key: str):
|
||||||
with open(filepath, 'wb') as f:
|
|
||||||
f.write(file_bytes)
|
|
||||||
|
|
||||||
async def save_file(self, file, file_bytes, key):
|
|
||||||
now = datetime.datetime.now()
|
|
||||||
path = self.DATA_ROOT / f"upload/{now.year}/{now.month}/{now.day}/"
|
|
||||||
ext = file.filename.split('.')[-1]
|
ext = file.filename.split('.')[-1]
|
||||||
name = f'{key}.{ext}'
|
now = datetime.now()
|
||||||
|
path = self.DATA_ROOT / f"upload/{now.year}/{now.month}/{now.day}/"
|
||||||
if not path.exists():
|
if not path.exists():
|
||||||
path.mkdir(parents=True)
|
path.mkdir(parents=True)
|
||||||
filepath = path / name
|
filepath = path / f'{key}.{ext}'
|
||||||
await asyncio.to_thread(self._save, filepath, file_bytes)
|
|
||||||
text = f"{self.STATIC_URL}/{filepath.relative_to(self.DATA_ROOT)}"
|
text = f"{self.STATIC_URL}/{filepath.relative_to(self.DATA_ROOT)}"
|
||||||
return text
|
return text
|
||||||
|
|
||||||
|
async def get_size(self, file: UploadFile):
|
||||||
|
f = file.file
|
||||||
|
f.seek(0, os.SEEK_END)
|
||||||
|
size = f.tell()
|
||||||
|
f.seek(0, os.SEEK_SET)
|
||||||
|
return size
|
||||||
|
|
||||||
|
def _save(self, 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, text: str):
|
||||||
|
filepath = await self.get_filepath(text)
|
||||||
|
await asyncio.to_thread(self._save, filepath, file.file)
|
||||||
|
|
||||||
async def delete_file(self, file):
|
async def delete_file(self, file):
|
||||||
# 是文件就删除
|
# 是文件就删除
|
||||||
if file['type'] != 'text':
|
if file['type'] != 'text':
|
||||||
|
|||||||
Reference in New Issue
Block a user