-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support for .apng and modify the cache
- Loading branch information
Showing
15 changed files
with
363 additions
and
82 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
.idea | ||
/pkg/petpet/test/output.gif | ||
web | ||
web | ||
/pkg/petpet/test/output.apng | ||
/pkg/petpet/test/output_fast.apng |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
package ds_apng | ||
|
||
import ( | ||
"context" | ||
"github.com/gorilla/mux" | ||
"github.com/wavy-cat/petpet-go/internal/handler/http/utils" | ||
"github.com/wavy-cat/petpet-go/internal/service" | ||
"github.com/wavy-cat/petpet-go/pkg/answer" | ||
"go.uber.org/zap" | ||
"net/http" | ||
) | ||
|
||
type Handler struct { | ||
apngService service.APNGService | ||
} | ||
|
||
func NewHandler(apngService service.APNGService) *Handler { | ||
return &Handler{apngService: apngService} | ||
} | ||
|
||
func (h Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { | ||
logger := r.Context().Value("logger").(*zap.Logger) | ||
|
||
// Getting the user ID | ||
userId, ok := mux.Vars(r)["user_id"] | ||
if !ok { | ||
logger.Warn("Failed to get user ID", zap.String("user_id", userId)) | ||
if err := answer.RespondWithErrorMessage(w, http.StatusBadRequest, "User ID not sent"); err != nil { | ||
logger.Error("Error sending response", zap.Error(err)) | ||
} | ||
return | ||
} | ||
|
||
// Getting delay | ||
delay, err := utils.ParseDelay(r.URL.Query().Get("delay")) | ||
if err != nil { | ||
if _, err := answer.RespondHTMLError(w, "Incorrect delay", err.Error()); err != nil { | ||
logger.Error("Error sending response", zap.Error(err)) | ||
} | ||
return | ||
} | ||
|
||
// Setting caching policies | ||
switch r.URL.Query().Get("no-cache") { | ||
case "true": | ||
w.Header().Set("Cache-Control", "no-store, no-cache, must-revalidate, private") | ||
w.Header().Set("Pragma", "no-cache") // For compatibility with older browsers | ||
w.Header().Set("Expires", "0") // For compatibility with older browsers | ||
default: | ||
w.Header().Set("Cache-Control", "max-age=900") | ||
} | ||
|
||
// Calling the service to generate GIF | ||
ctx := context.WithValue(context.Background(), "logger", logger) | ||
gif, err := h.apngService.GetOrGenerateAPNG(ctx, userId, "discord", delay) | ||
if err != nil { | ||
title, description := utils.ParseError(err) | ||
if _, err := answer.RespondHTMLError(w, title, description); err != nil { | ||
logger.Error("Error sending response", zap.Error(err)) | ||
} | ||
return | ||
} | ||
|
||
// Setting Content-Type | ||
w.Header().Set("Content-Type", "image/apng") | ||
|
||
// Returning the result | ||
_, err = w.Write(gif) | ||
if err != nil { | ||
logger.Error("Error sending response", zap.Error(err)) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
8 changes: 4 additions & 4 deletions
8
internal/handler/http/ds/utils.go → internal/handler/http/utils/utils.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
package service | ||
|
||
import ( | ||
"bytes" | ||
"context" | ||
"errors" | ||
"fmt" | ||
"github.com/wavy-cat/petpet-go/internal/repository" | ||
"github.com/wavy-cat/petpet-go/pkg/cache" | ||
"github.com/wavy-cat/petpet-go/pkg/petpet" | ||
"go.uber.org/zap" | ||
"strings" | ||
) | ||
|
||
type APNGService interface { | ||
GetOrGenerateAPNG(ctx context.Context, userId, source string, delay int) ([]byte, error) | ||
} | ||
|
||
type apngService struct { | ||
config petpet.Config | ||
cache cache.BytesCache | ||
providers map[string]repository.AvatarProvider | ||
} | ||
|
||
func NewAPngService(cache cache.BytesCache, providers map[string]repository.AvatarProvider, | ||
config petpet.Config) APNGService { | ||
return &apngService{ | ||
config: config, | ||
cache: cache, | ||
providers: providers, | ||
} | ||
} | ||
|
||
func (g apngService) GetOrGenerateAPNG(ctx context.Context, userId, source string, delay int) ([]byte, error) { | ||
if strings.ToLower(userId) == "user_id" { | ||
return nil, errors.New("replace user_id in the URL with real Discord user ID 😉") | ||
} | ||
|
||
// Getting the required provider | ||
provider, ok := g.providers[source] | ||
if !ok { | ||
return nil, errors.New("unknown avatar source") | ||
} | ||
|
||
// Getting the user's avatar id | ||
avatarId, err := provider.GetAvatarId(ctx, userId) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
// We check if the GIF is in the cache and if so, return it. | ||
cacheName := fmt.Sprintf("%s-%d", avatarId, delay) | ||
|
||
if g.cache != nil { | ||
cachedGif, err := g.cache.Pull(cacheName) | ||
if err == nil { | ||
return cachedGif, nil | ||
} else if err.Error() != "not exist" { | ||
logger, ok := ctx.Value("logger").(*zap.Logger) | ||
if ok { | ||
logger.Warn("Error when retrieving GIF from cache", | ||
zap.Error(err), zap.String("avatar_id", avatarId)) | ||
} | ||
} | ||
} | ||
|
||
// Getting the user's avatar | ||
avatarImage, err := provider.GetAvatarImage(ctx, userId) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
// Generating a GIF | ||
config := g.config | ||
config.Delay = delay | ||
avatarReader := bytes.NewReader(avatarImage) | ||
|
||
var buf bytes.Buffer | ||
defer buf.Reset() | ||
err = petpet.MakeAPNG(avatarReader, &buf, config) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
data := buf.Bytes() | ||
|
||
// Add a GIF to the cache | ||
if g.cache != nil { | ||
go func() { | ||
_ = g.cache.Push(cacheName, data) | ||
}() | ||
} | ||
|
||
// Returning the result | ||
return data, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,3 @@ | ||
# petpet | ||
|
||
Библиотека для генерации pet-pet гифки. | ||
A library for generating pet-pet gifs. |
Oops, something went wrong.