mirror of
https://github.com/truewhile/MeBox.git
synced 2026-09-29 03:26:37 +08:00
b0fe40142a
* Rebrand MMTL to MeBox across codebase and assets Rename the project display name, Go module path, environment variable prefix (MEBOX_*), Docker image references, and UI branding from MMTL/mmtl to MeBox/mebox. Replace logo assets with the new MeBox icon and keep legacy SQLite migration support for existing mmtl.db deployments. Co-authored-by: truewhile <truewhile@users.noreply.github.com> * Fix logo icons: use cube-only crop without truncated text Previous icon generation cropped too much of the source image, including partial MeBox wordmark text that was cut off in square icon containers. Regenerate logo-64/192/512, favicon, and SVG from cube-only region. Co-authored-by: truewhile <truewhile@users.noreply.github.com> --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: truewhile <truewhile@users.noreply.github.com>
68 lines
2.0 KiB
Go
68 lines
2.0 KiB
Go
package handler
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
|
|
"github.com/truewhile/MeBox/internal/service"
|
|
)
|
|
|
|
var embyPlaceholderPNG = []byte{
|
|
0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a,
|
|
0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52,
|
|
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
|
|
0x08, 0x06, 0x00, 0x00, 0x00, 0x1f, 0x15, 0xc4,
|
|
0x89, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x44, 0x41,
|
|
0x54, 0x78, 0x9c, 0x63, 0x50, 0xd1, 0x30, 0xf8,
|
|
0x0f, 0x00, 0x02, 0x6c, 0x01, 0x7c, 0x30, 0xed,
|
|
0x6e, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45,
|
|
0x4e, 0x44, 0xae, 0x42, 0x60, 0x82,
|
|
}
|
|
|
|
// embyItemImageHandler 把 /Items/{id}/Images/Primary 等请求直接输出为图片。
|
|
// Emby 客户端缓存图片 URL 时经常不会继续携带 token;如果重定向到受保护的
|
|
// /api/img 会变成 401,所以这里复用 ImageProxy 但不再走 /api 路由。
|
|
func embyItemImageHandler(svc *service.Container) gin.HandlerFunc {
|
|
return func(c *gin.Context) {
|
|
clearEmbyImageNoStoreHeaders(c)
|
|
ctx, cancel := context.WithTimeout(c.Request.Context(), 8*time.Second)
|
|
defer cancel()
|
|
req := c.Request.WithContext(ctx)
|
|
id := c.Param("id")
|
|
imgType := strings.ToLower(c.Param("type"))
|
|
raw, err := svc.Emby.ImageURL(ctx, id, imgType)
|
|
if err != nil || raw == "" {
|
|
embyServePlaceholderImage(c)
|
|
return
|
|
}
|
|
if svc.ImageProxy == nil {
|
|
embyServePlaceholderImage(c)
|
|
return
|
|
}
|
|
if err := svc.ImageProxy.Serve(ctx, c.Writer, req, raw); err != nil {
|
|
embyServePlaceholderImage(c)
|
|
}
|
|
}
|
|
}
|
|
|
|
func clearEmbyImageNoStoreHeaders(c *gin.Context) {
|
|
c.Writer.Header().Del("Pragma")
|
|
c.Writer.Header().Del("Expires")
|
|
}
|
|
|
|
func embyServePlaceholderImage(c *gin.Context) {
|
|
c.Header("Content-Type", "image/png")
|
|
c.Header("Cache-Control", "public, max-age=3600")
|
|
c.Header("Content-Length", strconv.Itoa(len(embyPlaceholderPNG)))
|
|
if c.Request.Method == http.MethodHead {
|
|
c.Status(http.StatusOK)
|
|
return
|
|
}
|
|
c.Data(http.StatusOK, "image/png", embyPlaceholderPNG)
|
|
}
|