This commit is contained in:
lan
2023-08-11 19:23:48 +08:00
parent c3664766e9
commit a39cdadc96
39 changed files with 0 additions and 5316 deletions
-174
View File
@@ -1,174 +0,0 @@
import os
import asyncio
import time
import uuid
from datetime import datetime
from pathlib import Path
from typing import BinaryIO
from fastapi import UploadFile
from core.database import Codes
from settings import settings
if settings.STORAGE_ENGINE == 'aliyunsystem':
try:
import oss2
except ImportError:
os.system('pip install oss2')
import oss2
class FileSystemStorage:
def __init__(self):
self.DATA_ROOT = Path(settings.DATA_ROOT)
self.STATIC_URL = settings.STATIC_URL
self.NAME = "filesystem"
self.DOWN_PATH = '/select'
async def get_filepath(self, text: str):
return self.DATA_ROOT / text.lstrip(self.STATIC_URL + '/')
async def get_url(self, info: Codes):
return f'{self.DOWN_PATH}?code={info.code}'
async def get_text(self, file: UploadFile, key: str):
ext = file.filename.split('.')[-1]
now = datetime.now()
path = self.DATA_ROOT / f"upload/{now.year}/{now.month}/{now.day}/"
if not path.exists():
path.mkdir(parents=True)
text = f"{self.STATIC_URL}/{(path / f'{key}.{ext}').relative_to(self.DATA_ROOT)}"
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)
@staticmethod
def _save_chunk(filepath, file: bytes):
with open(filepath, 'wb') as f:
f.write(file)
async def create_upload_file(self):
file_key = uuid.uuid4().hex
file_path = self.DATA_ROOT / f"temp/{file_key}"
if not file_path.exists():
file_path.mkdir(parents=True)
return file_key
async def save_chunk_file(self, file_key, file_chunk, chunk_index, chunk_total):
file_path = self.DATA_ROOT / f"temp/{file_key}/"
await asyncio.to_thread(self._save_chunk, file_path / f"{chunk_total}-{chunk_index}.temp", file_chunk)
async def merge_chunks(self, file_key, file_name, total_chunks: int):
ext = file_name.split('.')[-1]
now = datetime.now()
path = self.DATA_ROOT / f"upload/{now.year}/{now.month}/{now.day}/"
if not path.exists():
path.mkdir(parents=True)
text = f"{self.STATIC_URL}/{(path / f'{file_key}.{ext}').relative_to(self.DATA_ROOT)}"
with open(path / f'{file_key}.{ext}', 'wb') as f:
for i in range(1, total_chunks + 1):
now_temp = self.DATA_ROOT / f'temp/{file_key}/{total_chunks}-{i}.temp'
with open(now_temp, 'rb') as r:
f.write(r.read())
await asyncio.to_thread(os.remove, now_temp)
await asyncio.to_thread(os.rmdir, self.DATA_ROOT / f'temp/{file_key}/')
return text
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, text: str):
filepath = await self.get_filepath(text)
if filepath.exists():
await asyncio.to_thread(os.remove, filepath)
await asyncio.to_thread(self.judge_delete_folder, filepath)
async def delete_files(self, texts):
tasks = [self.delete_file(text) for text in texts]
await asyncio.gather(*tasks)
def judge_delete_folder(self, filepath):
current = filepath.parent
while current != self.DATA_ROOT:
if not list(current.iterdir()):
os.rmdir(current)
current = current.parent
else:
break
class AliyunFileStorage:
def __init__(self):
auth = oss2.Auth(settings.KeyId, settings.KeySecret)
self.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 f"https://{settings.BUCKET_NAME}.{settings.OSS_ENDPOINT}/{text}"
async def get_url(self, info: Codes):
text = info.text.strip(f"https://{settings.BUCKET_NAME}.{settings.OSS_ENDPOINT}/")
url = self.bucket.sign_url('GET', text, settings.ACCESSTIME, slash_safe=True)
return url
@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)
remote_filepath = remote_filepath.strip(f"https://{settings.BUCKET_NAME}.{settings.OSS_ENDPOINT}/")
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):
text = text.strip(f"https://{settings.BUCKET_NAME}.{settings.OSS_ENDPOINT}/")
self.bucket.delete_object(text)
STORAGE_ENGINE = {
"filesystem": FileSystemStorage,
"aliyunsystem": AliyunFileStorage
}