| package route |
|
|
| import ( |
| "bytes" |
| "image" |
| "net/http" |
| "strconv" |
|
|
| "github.com/gin-gonic/gin" |
| "github.com/gin-gonic/gin/render" |
|
|
| R "github.com/metatube-community/metatube-sdk-go/constant" |
| "github.com/metatube-community/metatube-sdk-go/engine" |
| "github.com/metatube-community/metatube-sdk-go/imageutil" |
| "github.com/metatube-community/metatube-sdk-go/imageutil/badge" |
| mt "github.com/metatube-community/metatube-sdk-go/provider" |
| ) |
|
|
| type imageType uint8 |
|
|
| const ( |
| primaryImageType imageType = iota |
| thumbImageType |
| backdropImageType |
| ) |
|
|
| type imageUri struct { |
| infoUri |
| } |
|
|
| type imageQuery struct { |
| URL string `form:"url"` |
| Ratio float64 `form:"ratio"` |
| Position float64 `form:"pos"` |
| Auto bool `form:"auto"` |
| Badge string `form:"badge"` |
| Quality int `form:"quality"` |
| } |
|
|
| func getImage(app *engine.Engine, typ imageType) gin.HandlerFunc { |
| var ratio float64 |
| switch typ { |
| case primaryImageType: |
| ratio = R.PrimaryImageRatio |
| case thumbImageType: |
| ratio = R.ThumbImageRatio |
| case backdropImageType: |
| ratio = R.BackdropImageRatio |
| default: |
| panic("invalid image type") |
| } |
|
|
| return func(c *gin.Context) { |
| uri := &imageUri{} |
| if err := c.ShouldBindUri(uri); err != nil { |
| abortWithStatusMessage(c, http.StatusBadRequest, err) |
| return |
| } |
| query := &imageQuery{ |
| Ratio: -1, |
| Position: -1, |
| Quality: 90, |
| } |
| if err := c.ShouldBindQuery(query); err != nil { |
| abortWithStatusMessage(c, http.StatusBadRequest, err) |
| return |
| } |
|
|
| |
| |
| var isActorProvider bool |
| switch { |
| case app.IsActorProvider(uri.Provider): |
| isActorProvider = true |
| case app.IsMovieProvider(uri.Provider): |
| isActorProvider = false |
| default: |
| abortWithError(c, mt.ErrProviderNotFound) |
| return |
| } |
|
|
| var ( |
| img image.Image |
| err error |
| ) |
| if query.URL != "" { |
| var provider mt.Provider |
| if isActorProvider { |
| provider = app.MustGetActorProviderByName(uri.Provider) |
| } else { |
| provider = app.MustGetMovieProviderByName(uri.Provider) |
| } |
| |
| if typ != primaryImageType || query.Ratio < 0 { |
| query.Ratio = ratio |
| } |
| img, err = app.GetImageByURL(provider, query.URL, query.Ratio, query.Position, query.Auto) |
| } else if isActorProvider { |
| switch typ { |
| case primaryImageType: |
| img, err = app.GetActorPrimaryImage(uri.AsProviderID()) |
| case thumbImageType, backdropImageType: |
| abortWithStatusMessage(c, http.StatusBadRequest, "unsupported image type") |
| return |
| } |
| } else { |
| switch typ { |
| case primaryImageType: |
| img, err = app.GetMoviePrimaryImage(uri.AsProviderID(), query.Ratio, query.Position) |
| case thumbImageType: |
| img, err = app.GetMovieThumbImage(uri.AsProviderID()) |
| case backdropImageType: |
| img, err = app.GetMovieBackdropImage(uri.AsProviderID()) |
| } |
| } |
| if err != nil { |
| abortWithError(c, err) |
| return |
| } |
|
|
| if query.Badge != "" { |
| if img, err = badge.Badge(img, query.Badge); err != nil { |
| abortWithError(c, err) |
| return |
| } |
| } |
|
|
| c.Header("X-MetaTube-Image-Width", strconv.Itoa(img.Bounds().Dx())) |
| c.Header("X-MetaTube-Image-Height", strconv.Itoa(img.Bounds().Dy())) |
|
|
| buf := &bytes.Buffer{} |
| if err = imageutil.EncodeToJPEG(buf, img, query.Quality); err != nil { |
| panic(err) |
| } |
|
|
| c.Render(http.StatusOK, render.Reader{ |
| ContentType: jpegImageMIMEType, |
| ContentLength: int64(buf.Len()), |
| Reader: buf, |
| }) |
| } |
| } |
|
|
| const jpegImageMIMEType = "image/jpeg" |
|
|