Use Discord avatars as HMN avatars
This commit is contained in:
parent
2ba2fa4d7d
commit
a826f1918e
|
@ -431,7 +431,7 @@ var discordDownloadClient = &http.Client{
|
|||
|
||||
type DiscordResourceBadStatusCode error
|
||||
|
||||
func downloadDiscordResource(ctx context.Context, url string) ([]byte, string, error) {
|
||||
func DownloadDiscordResource(ctx context.Context, url string) ([]byte, string, error) {
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
|
||||
if err != nil {
|
||||
return nil, "", oops.New(err, "failed to make Discord download request")
|
||||
|
@ -491,7 +491,7 @@ func saveAttachment(
|
|||
height = *attachment.Height
|
||||
}
|
||||
|
||||
content, _, err := downloadDiscordResource(ctx, attachment.Url)
|
||||
content, _, err := DownloadDiscordResource(ctx, attachment.Url)
|
||||
if err != nil {
|
||||
return nil, oops.New(err, "failed to download Discord attachment")
|
||||
}
|
||||
|
@ -561,7 +561,7 @@ func saveEmbed(
|
|||
}
|
||||
|
||||
maybeSaveImageish := func(i EmbedImageish, contentTypeCheck func(string) bool) (*uuid.UUID, error) {
|
||||
content, contentType, err := downloadDiscordResource(ctx, *i.Url)
|
||||
content, contentType, err := DownloadDiscordResource(ctx, *i.Url)
|
||||
if err != nil {
|
||||
var statusError DiscordResourceBadStatusCode
|
||||
if errors.As(err, &statusError) {
|
||||
|
@ -838,7 +838,8 @@ func HandleSnippetForInternedMessage(ctx context.Context, dbConn db.ConnOrTx, in
|
|||
}
|
||||
|
||||
// TODO(asaf): I believe this will also match https://example.com?hello=1&whatever=5
|
||||
// Probably need to add word boundaries.
|
||||
//
|
||||
// Probably need to add word boundaries.
|
||||
var REDiscordTag = regexp.MustCompile(`&([a-zA-Z0-9]+(-[a-zA-Z0-9]+)*)`)
|
||||
|
||||
func getDiscordTags(content string) []string {
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
package website
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"git.handmade.network/hmn/hmn/src/assets"
|
||||
"git.handmade.network/hmn/hmn/src/config"
|
||||
"git.handmade.network/hmn/hmn/src/db"
|
||||
"git.handmade.network/hmn/hmn/src/discord"
|
||||
|
@ -14,6 +16,7 @@ import (
|
|||
"git.handmade.network/hmn/hmn/src/models"
|
||||
"git.handmade.network/hmn/hmn/src/oops"
|
||||
"git.handmade.network/hmn/hmn/src/utils"
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
// This callback handles Discord account linking whether the user is signed in
|
||||
|
@ -194,16 +197,26 @@ func DiscordOAuthCallback(c *RequestContext) ResponseData {
|
|||
return c.RejectRequest(fmt.Sprintf("There is already a Handmade Network account with the username \"%s\".", user.Username))
|
||||
}
|
||||
|
||||
var avatarAssetID *uuid.UUID
|
||||
if user.Avatar != nil {
|
||||
// Note! Not using the transaction here. Don't want to fail the login due to avatars.
|
||||
if avatarAsset, err := saveDiscordAvatar(c, c.Conn, user.ID, *user.Avatar); err == nil {
|
||||
avatarAssetID = &avatarAsset.ID
|
||||
} else {
|
||||
c.Logger.Warn().Err(err).Msg("failed to save Discord avatar")
|
||||
}
|
||||
}
|
||||
|
||||
newHMNUser, err := db.QueryOne[models.User](c, tx,
|
||||
`
|
||||
INSERT INTO hmn_user (
|
||||
username, email, password, date_joined, registration_ip
|
||||
username, email, password, avatar_asset_id, date_joined, registration_ip
|
||||
) VALUES (
|
||||
$1, $2, '', $3, $4
|
||||
$1, $2, '', $3, $4, $5
|
||||
)
|
||||
RETURNING $columns
|
||||
`,
|
||||
user.Username, strings.ToLower(user.Email), time.Now(), c.GetIP(),
|
||||
user.Username, strings.ToLower(user.Email), avatarAssetID, time.Now(), c.GetIP(),
|
||||
)
|
||||
if err != nil {
|
||||
return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to create new HMN user for Discord login"))
|
||||
|
@ -366,3 +379,29 @@ func DiscordShowcaseBacklog(c *RequestContext) ResponseData {
|
|||
|
||||
return c.Redirect(hmnurl.BuildUserProfile(c.CurrentUser.Username), http.StatusSeeOther)
|
||||
}
|
||||
|
||||
func saveDiscordAvatar(ctx context.Context, conn db.ConnOrTx, userID, avatarHash string) (*models.Asset, error) {
|
||||
const size = 256
|
||||
|
||||
filename := fmt.Sprintf("%s.png", avatarHash)
|
||||
url := fmt.Sprintf("https://cdn.discordapp.com/avatars/%s/%s?size=%d", userID, filename, size)
|
||||
|
||||
content, _, err := discord.DownloadDiscordResource(ctx, url)
|
||||
if err != nil {
|
||||
return nil, oops.New(err, "failed to download Discord avatar")
|
||||
}
|
||||
|
||||
asset, err := assets.Create(ctx, conn, assets.CreateInput{
|
||||
Content: content,
|
||||
Filename: filename,
|
||||
ContentType: "image/png",
|
||||
|
||||
Width: size,
|
||||
Height: size,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, oops.New(err, "failed to save asset for Discord attachment")
|
||||
}
|
||||
|
||||
return asset, nil
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue