11import datetime
2- import os
32import uuid
4- import threading
53import random
64import asyncio
75from pathlib import Path
1614
1715import settings
1816from database import get_session , Codes , init_models , engine
17+ from storage import STORAGE_ENGINE
1918
2019app = FastAPI (debug = settings .DEBUG )
2120
2625STATIC_URL = settings .STATIC_URL
2726app .mount (STATIC_URL , StaticFiles (directory = DATA_ROOT ), name = "static" )
2827
28+ storage = STORAGE_ENGINE [settings .STORAGE_ENGINE ]()
29+
2930
3031@app .on_event ('startup' )
3132async def startup ():
@@ -45,18 +46,13 @@ async def startup():
4546error_ip_count = {}
4647
4748
48- def delete_file (files ):
49- for file in files :
50- if file ['type' ] != 'text' :
51- os .remove (DATA_ROOT / file ['text' ].lstrip (STATIC_URL + '/' ))
52-
53-
5449async def delete_expire_files ():
5550 while True :
5651 async with AsyncSession (engine , expire_on_commit = False ) as s :
5752 query = select (Codes ).where (or_ (Codes .exp_time < datetime .datetime .now (), Codes .count == 0 ))
5853 exps = (await s .execute (query )).scalars ().all ()
59- await asyncio .to_thread (delete_file , [{'type' : old .type , 'text' : old .text } for old in exps ])
54+ files = [{'type' : old .type , 'text' : old .text } for old in exps ]
55+ await storage .delete_files (files )
6056 exps_ids = [exp .id for exp in exps ]
6157 query = delete (Codes ).where (Codes .id .in_ (exps_ids ))
6258 await s .execute (query )
@@ -71,18 +67,6 @@ async def get_code(s: AsyncSession):
7167 return str (code )
7268
7369
74- def get_file_name (key , ext , file , file_bytes ):
75- now = datetime .datetime .now ()
76- path = DATA_ROOT / f"upload/{ now .year } /{ now .month } /{ now .day } /"
77- name = f'{ key } .{ ext } '
78- if not path .exists ():
79- path .mkdir (parents = True )
80- filepath = path / name
81- with open (filepath , 'wb' ) as f :
82- f .write (file_bytes )
83- return f"{ STATIC_URL } /{ filepath .relative_to (DATA_ROOT )} " , file .content_type , file .filename
84-
85-
8670@app .get (f'/{ settings .ADMIN_ADDRESS } ' )
8771async def admin ():
8872 return HTMLResponse (admin_html )
@@ -103,7 +87,7 @@ async def admin_delete(request: Request, code: str, s: AsyncSession = Depends(ge
10387 if request .headers .get ('pwd' ) == settings .ADMIN_PASSWORD :
10488 query = select (Codes ).where (Codes .code == code )
10589 file = (await s .execute (query )).scalars ().first ()
106- await asyncio . to_thread ( delete_file , [ {'type' : file .type , 'text' : file .text }] )
90+ await storage . delete_file ( {'type' : file .type , 'text' : file .text })
10791 await s .delete (file )
10892 await s .commit ()
10993 return {'code' : 200 , 'msg' : '删除成功' }
@@ -142,7 +126,8 @@ async def get_file(code: str, s: AsyncSession = Depends(get_session)):
142126 if info .type == 'text' :
143127 return {'code' : code , 'msg' : '查询成功' , 'data' : info .text }
144128 else :
145- return FileResponse (DATA_ROOT / info .text .lstrip (STATIC_URL + '/' ), filename = info .name )
129+ filepath = await storage .get_filepath (info .text )
130+ return FileResponse (filepath , filename = info .name )
146131 else :
147132 return {'code' : 404 , 'msg' : '口令不存在' }
148133
@@ -157,7 +142,7 @@ async def index(request: Request, code: str, s: AsyncSession = Depends(get_sessi
157142 if not info :
158143 return {'code' : 404 , 'msg' : f'取件码错误,错误{ settings .ERROR_COUNT - ip_error (ip )} 次将被禁止10分钟' }
159144 if info .exp_time < datetime .datetime .now () or info .count == 0 :
160- threading . Thread ( target = delete_file , args = ([ {'type' : info .type , 'text' : info .text }],)). start ( )
145+ await storage . delete_file ( {'type' : info .type , 'text' : info .text })
161146 await s .delete (info )
162147 await s .commit ()
163148 return {'code' : 404 , 'msg' : '取件码已过期,请联系寄件人' }
@@ -193,11 +178,11 @@ async def share(text: str = Form(default=None), style: str = Form(default='2'),
193178 exp_count = - 1
194179 key = uuid .uuid4 ().hex
195180 if file :
196- file_bytes = file . file .read ()
181+ file_bytes = await file .read ()
197182 size = len (file_bytes )
198183 if size > settings .FILE_SIZE_LIMIT :
199184 return {'code' : 404 , 'msg' : '文件过大' }
200- _text , _type , name = get_file_name ( key , file . filename . split ( '.' )[ - 1 ] , file , file_bytes )
185+ _text , _type , name = await storage . save_file ( file , file_bytes , key ) , file . content_type , file . filename
201186 else :
202187 size , _text , _type , name = len (text ), text , 'text' , '文本分享'
203188 info = Codes (
0 commit comments