|
| 1 | +import os |
| 2 | +import time |
| 3 | + |
| 4 | +from core.response import APIResponse |
| 5 | +from core.storage import FileStorageInterface, storages |
| 6 | +from core.settings import settings |
| 7 | +from apps.base.models import FileCodes, KeyValue |
| 8 | +from apps.base.utils import get_expire_info, get_file_path_name |
| 9 | +from fastapi import HTTPException |
| 10 | +from core.settings import data_root |
| 11 | + |
| 12 | + |
| 13 | +class FileService: |
| 14 | + def __init__(self): |
| 15 | + self.file_storage: FileStorageInterface = storages[settings.file_storage]() |
| 16 | + |
| 17 | + async def delete_file(self, file_id: int): |
| 18 | + file_code = await FileCodes.get(id=file_id) |
| 19 | + await self.file_storage.delete_file(file_code) |
| 20 | + await file_code.delete() |
| 21 | + |
| 22 | + async def list_files(self, page: int, size: int): |
| 23 | + offset = (page - 1) * size |
| 24 | + files = await FileCodes.all().limit(size).offset(offset) |
| 25 | + total = await FileCodes.all().count() |
| 26 | + return files, total |
| 27 | + |
| 28 | + async def download_file(self, file_id: int): |
| 29 | + file_code = await FileCodes.filter(id=file_id).first() |
| 30 | + if not file_code: |
| 31 | + raise HTTPException(status_code=404, detail='文件不存在') |
| 32 | + if file_code.text: |
| 33 | + return APIResponse(detail=file_code.text) |
| 34 | + else: |
| 35 | + return await self.file_storage.get_file_response(file_code) |
| 36 | + |
| 37 | + async def share_local_file(self, item): |
| 38 | + local_file = LocalFileClass(item.filename) |
| 39 | + if not await local_file.exists(): |
| 40 | + raise HTTPException(status_code=404, detail='文件不存在') |
| 41 | + |
| 42 | + text = await local_file.read() |
| 43 | + expired_at, expired_count, used_count, code = await get_expire_info(item.expire_value, item.expire_style) |
| 44 | + path, suffix, prefix, uuid_file_name, save_path = await get_file_path_name(item) |
| 45 | + |
| 46 | + await self.file_storage.save_file(text, save_path) |
| 47 | + |
| 48 | + await FileCodes.create( |
| 49 | + code=code, |
| 50 | + prefix=prefix, |
| 51 | + suffix=suffix, |
| 52 | + uuid_file_name=uuid_file_name, |
| 53 | + file_path=path, |
| 54 | + size=local_file.size, |
| 55 | + expired_at=expired_at, |
| 56 | + expired_count=expired_count, |
| 57 | + used_count=used_count, |
| 58 | + ) |
| 59 | + |
| 60 | + return { |
| 61 | + 'code': code, |
| 62 | + 'name': local_file.file, |
| 63 | + } |
| 64 | + |
| 65 | + |
| 66 | +class ConfigService: |
| 67 | + def get_config(self): |
| 68 | + return settings.items() |
| 69 | + |
| 70 | + async def update_config(self, data: dict): |
| 71 | + admin_token = data.get('admin_token') |
| 72 | + if admin_token is None or admin_token == '': |
| 73 | + raise HTTPException(status_code=400, detail='管理员密码不能为空') |
| 74 | + |
| 75 | + for key, value in data.items(): |
| 76 | + if key not in settings.default_config: |
| 77 | + continue |
| 78 | + if key in ['errorCount', 'errorMinute', 'max_save_seconds', 'onedrive_proxy', 'openUpload', 'port', 's3_proxy', 'uploadCount', 'uploadMinute', 'uploadSize']: |
| 79 | + data[key] = int(value) |
| 80 | + elif key in ['opacity']: |
| 81 | + data[key] = float(value) |
| 82 | + else: |
| 83 | + data[key] = value |
| 84 | + |
| 85 | + await KeyValue.filter(key='settings').update(value=data) |
| 86 | + for k, v in data.items(): |
| 87 | + settings.__setattr__(k, v) |
| 88 | + |
| 89 | + |
| 90 | +class LocalFileService: |
| 91 | + async def list_files(self): |
| 92 | + files = [] |
| 93 | + for file in os.listdir(data_root / 'local'): |
| 94 | + files.append(LocalFileClass(file)) |
| 95 | + return files |
| 96 | + |
| 97 | + async def delete_file(self, filename: str): |
| 98 | + file = LocalFileClass(filename) |
| 99 | + if await file.exists(): |
| 100 | + await file.delete() |
| 101 | + return '删除成功' |
| 102 | + raise HTTPException(status_code=404, detail='文件不存在') |
| 103 | + |
| 104 | + |
| 105 | +class LocalFileClass: |
| 106 | + def __init__(self, file): |
| 107 | + self.file = file |
| 108 | + self.path = data_root / 'local' / file |
| 109 | + self.ctime = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(os.path.getctime(self.path))) |
| 110 | + self.size = os.path.getsize(self.path) |
| 111 | + |
| 112 | + async def read(self): |
| 113 | + return open(self.path, 'rb') |
| 114 | + |
| 115 | + async def write(self, data): |
| 116 | + with open(self.path, 'w') as f: |
| 117 | + f.write(data) |
| 118 | + |
| 119 | + async def delete(self): |
| 120 | + os.remove(self.path) |
| 121 | + |
| 122 | + async def exists(self): |
| 123 | + return os.path.exists(self.path) |
0 commit comments