利用服务器公网IP和域名,通过简单的Python代码实现Twikoo评论中的图片功能。
由于没有购买和注册图床服务,且没有绑定腾讯云服务,所以只能自行想办法实现Twikoo的评论带图片功能。
想起来之前工作中有利用FastAPI实现过在Streamlit大模型RAG检索对话中的图片显示功能,因此考虑在此复用。
查看Twikoo代码中的请求方式
Twikoo官方GitHub地址: twikoo
代码路径: src/server/function/twikoo/utils/image.js
代码地址: https://github.com/twikoojs/twikoo/blob/main/src/server/function/twikoo/utils/image.js
评论图床引用代码片段:
if (!config.IMAGE_CDN || !config.IMAGE_CDN_TOKEN ) { throw new Error ('未配置图片上传服务' ) } if (config.IMAGE_CDN === '7bu' ) { await fn.uploadImageToLskyPro ({ photo, fileName, config, res, imageCdn : 'https://7bu.top' }) } else if (config.IMAGE_CDN === 'smms' ) { await fn.uploadImageToSmms ({ photo, fileName, config, res, imageCdn : 'https://smms.app/api/v2/upload' }) } else if (isUrl (config.IMAGE_CDN )) { await fn.uploadImageToLskyPro ({ photo, fileName, config, res, imageCdn : config.IMAGE_CDN }) } else if (config.IMAGE_CDN === 'lskypro' ) { await fn.uploadImageToLskyPro ({ photo, fileName, config, res, imageCdn : config.IMAGE_CDN_URL }) } else if (config.IMAGE_CDN === 'piclist' ) { await fn.uploadImageToPicList ({ photo, fileName, config, res, imageCdn : config.IMAGE_CDN_URL }) } else { throw new Error ('不支持的图片上传服务' ) }
在源代码的第24行,有 if (isUrl(config.IMAGE_CDN)),即支持自定义图片功能的地址,因此只需要在方法中搞清楚请求头的相关参数即可。
请求代码如下:
async uploadImageToLskyPro ({ photo, fileName, config, res, imageCdn } ) { const formData = new FormData () formData.append ('file' , fn.base64UrlToReadStream (photo, fileName)) if (process.env .TWIKOO_LSKY_STRATEGY_ID ) { formData.append ('strategy_id' , parseInt (process.env .TWIKOO_LSKY_STRATEGY_ID )) } const url = `${imageCdn} /api/v1/upload` let token = config.IMAGE_CDN_TOKEN if (!token.startsWith ('Bearer' )) { token = `Bearer ${token} ` } const uploadResult = await axios.post (url, formData, { headers : { ...formData.getHeaders (), Authorization : token } }) if (uploadResult.data .status ) { res.data = uploadResult.data .data res.data .url = res.data .links .url } else { throw new Error (uploadResult.data .message ) } },
确定好请求头的相关参数,下面即可利用Python的FastAPI包实现图片服务,具体代码如下:
from fastapi import FastAPI, UploadFile, File, Form, HTTPException, Header, Dependsfrom fastapi.middleware.cors import CORSMiddlewarefrom fastapi.staticfiles import StaticFilesfrom typing import Optional import osapp = FastAPI() UPLOAD_Folder = 'Saved_Images' os.makedirs(UPLOAD_Folder, exist_ok=True ) app.mount("/images" , StaticFiles(directory=UPLOAD_Folder), name="static" ) @app.post("/" ) async def image_server (): return {'message' : 'Hello' } @app.post("/api/v1/upload" ) async def upload_image ( file: UploadFile = File(... ), strategy_id: int = Form(None ), authorization: str = Header(... ) ): if authorization != 'Bearer xxx' : reponse = { 'status' : False , 'data' : { 'links' : { 'url' : '--' } }, 'message' : 'Toekn Invalid..' } return reponse file_content = await file.read() cur_folder = authorization.replace('Bearer ' , '' ) if cur_folder: os.makedirs(f'{UPLOAD_Folder} /{cur_folder} ' , exist_ok=True ) file_path = f'{UPLOAD_Folder} /{cur_folder} /{file.filename} ' else : os.makedirs(f'{UPLOAD_Folder} ' , exist_ok=True ) file_path = f'{UPLOAD_Folder} /{file.filename} ' with open (file_path, "wb" ) as f: f.write(file_content) upload_success = True if not os.path.exists(file_path): upload_success = False message = "File and form data received successfully" data = { "links" : { "url" : f"https://{域名orIP地址} /images/{cur_folder} /{file.filename} " } } response = { "status" : upload_success, "data" : data if upload_success else None , "message" : message if upload_success else "Upload failed" } if not upload_success: raise HTTPException(status_code=400 , detail=response["message" ]) return response if __name__ == "__main__" : import uvicorn uvicorn.run(app, host="0.0.0.0" , port=8005 )
至此,基于Pythond FastAPI的图片服务已经实现,附Python代码请求的脚本:
import requestsfrom fastapi import HTTPExceptionfrom typing import Optional url = "http://127.0.0.1:8005/api/v1/upload" file_path = "star.png" form_data = { "strategy_id" : 123 } headers = { "Authorization" : "Bearer xxx" } with open (file_path, "rb" ) as file: files = {"file" : (file_path, file, "multipart/form-data" )} try : response = requests.post(url, files=files, data=form_data, headers=headers) response.raise_for_status() print (response.json()) except requests.exceptions.HTTPError as http_err: print (f"HTTP error occurred: {http_err} " ) except Exception as err: print (f"An error occurred: {err} " )
Twikoo管理页面配置
需配置的地方: IMAGE_CDN, IMAGE_CDN_TOKEN
配置完成,即可实现Twikoo评论带图片啦~
Note: 为确保能正常显示在公网,建议使用https域名进行配置,单纯IP可能不一定正常显示,未测试。