diff --git a/__pycache__/auth.cpython-313.pyc b/__pycache__/auth.cpython-313.pyc index 6a1d985..dd75ae9 100644 Binary files a/__pycache__/auth.cpython-313.pyc and b/__pycache__/auth.cpython-313.pyc differ diff --git a/api/__pycache__/contents.cpython-313.pyc b/api/__pycache__/contents.cpython-313.pyc index a810951..5420930 100644 Binary files a/api/__pycache__/contents.cpython-313.pyc and b/api/__pycache__/contents.cpython-313.pyc differ diff --git a/api/contents.py b/api/contents.py index 5fa828b..4a3e7f2 100644 --- a/api/contents.py +++ b/api/contents.py @@ -496,6 +496,89 @@ async def get_latest_content_binary( detail=f"生成二进制数据失败: {str(e)}" ) +@router.get("/public/devices/{device_id}/content/latest/binary") +async def get_latest_content_binary_public( + device_id: str, + invert: bool = Query(False, description="是否反转颜色"), + rotate: bool = Query(False, description="是否旋转90度"), + dither: bool = Query(True, description="是否使用抖动算法"), + db: Session = Depends(get_db) +): + """ + 获取设备最新活跃内容的二进制数据,适用于墨水屏显示(无需鉴权) + """ + # 检查设备是否存在 + device = db.query(DeviceModel).filter(DeviceModel.device_id == device_id).first() + if not device: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail="设备不存在" + ) + + # 获取最新的活跃内容 + content = db.query(ContentModel).filter( + ContentModel.device_id == device_id, + ContentModel.is_active == True + ).order_by(ContentModel.version.desc()).first() + + if not content: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail="设备没有活跃内容" + ) + + if not content.image_path: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail="内容没有关联的图片" + ) + + try: + # 获取完整的图片路径 + # 检查image_path是否已经包含static目录 + if content.image_path.startswith('static/'): + # 已经包含static目录,直接使用 + image_path = content.image_path + elif content.image_path.startswith('/'): + # 以/开头的完整路径,去掉开头的斜杠 + image_path = content.image_path[1:] + else: + # 相对路径,添加static_dir前缀 + image_path = os.path.join(settings.static_dir, content.image_path) + + # 确保图片文件存在 + if not os.path.exists(image_path): + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail="图片文件不存在" + ) + + # 转换为二进制数据 + binary_data = convert_to_binary_data( + image_path, + width=settings.ink_width, + height=settings.ink_height, + invert=invert, + rotate=rotate, + dither=dither + ) + + # 返回二进制数据 + return Response( + content=binary_data, + media_type="application/octet-stream", + headers={ + "Content-Disposition": f"attachment; filename={device_id}_latest.bin", + "Content-Length": str(len(binary_data)) + } + ) + + except Exception as e: + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail=f"生成二进制数据失败: {str(e)}" + ) + @router.get("/devices/{device_id}/content/{version}/binary", dependencies=[Depends(get_api_key)]) async def get_content_binary( device_id: str, diff --git a/auth.py b/auth.py index fe8bf4d..fb23e67 100644 --- a/auth.py +++ b/auth.py @@ -66,7 +66,17 @@ class APIKeyMiddleware(BaseHTTPMiddleware): """ 判断是否跳过鉴权的路径 """ - # 所有API路径都需要鉴权,不跳过 + # 公共API路径不需要鉴权 + public_api_paths = [ + "/api/contents/public/", + ] + + # 检查是否是公共API路径 + for public_path in public_api_paths: + if path.startswith(public_path): + return True + + # 所有其他API路径都需要鉴权,不跳过 # 如果路径以/api开头,则不跳过(需要鉴权) if path.startswith("/api"): return False diff --git a/static/processed/d9af5c53-ddb3-4093-ac62-607ef1a332f6.bmp b/static/processed/d9af5c53-ddb3-4093-ac62-607ef1a332f6.bmp new file mode 100644 index 0000000..6d9ea42 Binary files /dev/null and b/static/processed/d9af5c53-ddb3-4093-ac62-607ef1a332f6.bmp differ diff --git a/static/uploads/957ebda9-1c3d-4b93-bbbc-fc5351479034.png b/static/uploads/957ebda9-1c3d-4b93-bbbc-fc5351479034.png new file mode 100644 index 0000000..50531a4 Binary files /dev/null and b/static/uploads/957ebda9-1c3d-4b93-bbbc-fc5351479034.png differ diff --git a/tool/__pycache__/image_converter.cpython-313.pyc b/tool/__pycache__/image_converter.cpython-313.pyc index 6ddb0bd..09960dd 100644 Binary files a/tool/__pycache__/image_converter.cpython-313.pyc and b/tool/__pycache__/image_converter.cpython-313.pyc differ