22import datetime
33import uuid
44from pathlib import Path
5+
6+ from pydantic import BaseModel
57from sqlalchemy import select , func , update
68from sqlalchemy .ext .asyncio import AsyncSession
79from starlette .requests import Request
810from starlette .responses import HTMLResponse , FileResponse , RedirectResponse
911from starlette .staticfiles import StaticFiles
10- from core .utils import error_ip_limit , upload_ip_limit , get_code , storage , delete_expire_files , get_token
12+ from core .utils import error_ip_limit , upload_ip_limit , get_code , storage , delete_expire_files , get_token , \
13+ get_expire_info
1114from core .depends import admin_required
1215from fastapi import FastAPI , Depends , UploadFile , Form , File , HTTPException , BackgroundTasks , Header
1316from core .database import init_models , Options , Codes , get_session
@@ -42,16 +45,22 @@ async def startup(s: AsyncSession = Depends(get_session)):
4245@app .get ('/' )
4346async def index ():
4447 return HTMLResponse (
45- index_html .replace ('{{title}}' , settings .TITLE ).replace ('{{description}}' , settings .DESCRIPTION ).replace (
46- '{{keywords}}' , settings .KEYWORDS ).replace ("'{{fileSizeLimit}}'" , str (settings .FILE_SIZE_LIMIT ))
48+ index_html
49+ .replace ('{{title}}' , settings .TITLE )
50+ .replace ('{{description}}' , settings .DESCRIPTION )
51+ .replace ('{{keywords}}' , settings .KEYWORDS )
52+ .replace ("'{{fileSizeLimit}}'" , str (settings .FILE_SIZE_LIMIT ))
4753 )
4854
4955
5056@app .get (f'/{ settings .ADMIN_ADDRESS } ' , description = '管理页面' )
5157async def admin ():
5258 return HTMLResponse (
53- admin_html .replace ('{{title}}' , settings .TITLE ).replace ('{{description}}' , settings .DESCRIPTION ).replace (
54- '{{admin_address}}' , settings .ADMIN_ADDRESS ).replace ('{{keywords}}' , settings .KEYWORDS )
59+ admin_html
60+ .replace ('{{title}}' , settings .TITLE )
61+ .replace ('{{description}}' , settings .DESCRIPTION )
62+ .replace ('{{admin_address}}' , settings .ADMIN_ADDRESS )
63+ .replace ('{{keywords}}' , settings .KEYWORDS )
5564 )
5665
5766
@@ -125,11 +134,10 @@ async def index(code: str, ip: str = Depends(error_ip_limit), s: AsyncSession =
125134 if not info :
126135 error_count = settings .ERROR_COUNT - error_ip_limit .add_ip (ip )
127136 raise HTTPException (status_code = 404 , detail = f"取件码错误,{ error_count } 次后将被禁止{ settings .ERROR_MINUTE } 分钟" )
128- if info .exp_time < datetime .datetime .now () or info .count == 0 :
137+ if ( info .exp_time and info . exp_time < datetime .datetime .now () ) or info .count == 0 :
129138 raise HTTPException (status_code = 404 , detail = "取件码已失效,请联系寄件人" )
130139 await s .execute (update (Codes ).where (Codes .id == info .id ).values (count = info .count - 1 ))
131140 await s .commit ()
132- print (info .type )
133141 if info .type != 'text' :
134142 info .text = f'/select?code={ info .code } &token={ await get_token (code , ip )} '
135143 return {
@@ -140,7 +148,6 @@ async def index(code: str, ip: str = Depends(error_ip_limit), s: AsyncSession =
140148
141149@app .get ('/banner' )
142150async def banner (request : Request ):
143- # 数据库查询config
144151 return {
145152 'detail' : '查询成功' ,
146153 'data' : settings .BANNERS ,
@@ -191,40 +198,40 @@ async def merge_chunks(file_key: str, file_name: str, total_chunks: int):
191198 return {'code' : 200 , 'data' : await storage .merge_chunks (file_key , file_name , total_chunks )}
192199
193200
194- @ app . post ( '/share' , dependencies = [ Depends ( admin_required )], description = '分享文件' )
195- async def share ( text : str = Form ( default = None ), size : int = Form ( default = 0 ), file_key : str = Form ( default = None ),
196- _type : str = Form ( default = None ), name : str = Form ( default = 'text' ),
197- style : str = Form ( default = '2' ), value : int = Form ( default = 1 ), is_file : int = Form ( default = True ),
198- ip : str = Depends ( upload_ip_limit ), s : AsyncSession = Depends ( get_session )):
199- if style == '2' :
200- if value > settings . MAX_DAYS :
201- raise HTTPException ( status_code = 400 , detail = f"最大有效天数为 { settings . MAX_DAYS } 天" )
202- # 如果天数大于0,就设置过期时间,否则就设置为永久,无过期时间
203- if settings . ENABLE_PERMANENT and value < 0 :
204- exp_time = None
205- else :
206- exp_time = datetime . datetime . now () + datetime . timedelta ( days = value )
207- exp_count = - 1
208- elif style == '1' :
209- if value < 1 :
210- raise HTTPException ( status_code = 400 , detail = "最小有效次数为1次" )
211- exp_time = datetime . datetime . now () + datetime . timedelta ( days = 1 )
212- exp_count = value
213- else :
214- exp_time = datetime . datetime . now () + datetime . timedelta ( days = 1 )
215- exp_count = - 1
216- print ( is_file )
217- if is_file :
218- key = file_key
219- # size = await storage.get_size(file)
220- # if size > settings.FILE_SIZE_LIMIT:
221- # raise HTTPException(status_code=400, detail="文件过大")
222- _text , size , name = text , size , name
223- # background_tasks.add_task(storage.save_file, file, _text )
224- else :
225- key = uuid . uuid4 (). hex
226- size , _text , _type , name = len ( text ), text , 'text' , '文本分享'
227- code = await get_code ( s )
201+ class ShareDataModel ( BaseModel ):
202+ text : str
203+ size : int = 0
204+ exp_style : str
205+ exp_value : int
206+ type : str
207+ name : str
208+ key : str = uuid . uuid4 (). hex
209+
210+
211+ @ app . post ( '/share/file/' , dependencies = [ Depends ( admin_required )], description = '分享文件' )
212+ async def share_file ( file_model : ShareDataModel , s : AsyncSession = Depends ( get_session ),
213+ ip : str = Depends ( error_ip_limit )):
214+ exp_error , exp_time , exp_count , code = await get_expire_info ( file_model . exp_style , file_model . exp_value , s )
215+ if exp_error :
216+ raise HTTPException ( status_code = 400 , detail = '过期值异常' )
217+ s . add ( Codes ( code = code , text = file_model . text , size = file_model . size , type = file_model . type , name = file_model . name ,
218+ count = exp_count , exp_time = exp_time , key = file_model . key ) )
219+ await s . commit ()
220+ upload_ip_limit . add_ip ( ip )
221+ return {
222+ 'detail' : '分享成功,请点击我的文件按钮查看上传列表' ,
223+ 'data' : { 'code' : code , 'key' : file_model . key , 'name' : file_model . name }
224+ }
225+
226+
227+ @ app . post ( '/share/text/' , dependencies = [ Depends ( admin_required )])
228+ async def share_text ( text_model : ShareDataModel , s : AsyncSession = Depends ( get_session ),
229+ ip : str = Depends ( error_ip_limit )):
230+ exp_error , exp_time , exp_count , code = await get_expire_info ( text_model . exp_style , text_model . exp_value , s , )
231+ if exp_error :
232+ raise HTTPException ( status_code = 400 , detail = '过期值异常' )
233+ exp_status , exp_time , exp_count , code = await get_expire_info ( text_model . exp_style , text_model . exp_value , s )
234+ size , _text , _type , name , key = len ( text_model . text ), text_model . text , 'text' , '文本分享' , text_model . key
228235 s .add (Codes (code = code , text = _text , size = size , type = _type , name = name , count = exp_count , exp_time = exp_time , key = key ))
229236 await s .commit ()
230237 upload_ip_limit .add_ip (ip )
0 commit comments