Add support for banner image

This commit is contained in:
Melon 2022-05-16 12:57:46 +01:00
parent d42ef41dc0
commit f77e0bd08f
Signed by: melon
GPG Key ID: B0ADD5395BCDAAB6
2 changed files with 118 additions and 101 deletions

View File

@ -12,8 +12,7 @@ import (
"github.com/gorilla/mux" "github.com/gorilla/mux"
"golang.org/x/oauth2" "golang.org/x/oauth2"
"html/template" "html/template"
"image" "io"
"image/png"
"net/http" "net/http"
"os" "os"
) )
@ -61,7 +60,11 @@ func (m *Module) SetupModule(router *mux.Router, f func(cb func(http.ResponseWri
} }
router.HandleFunc("/", m.getClient(m.homepage)) router.HandleFunc("/", m.getClient(m.homepage))
router.HandleFunc("/login", m.sessionWrapper(m.loginPage)) router.HandleFunc("/login", m.sessionWrapper(m.loginPage))
router.HandleFunc("/user/avatar/{userId}/a_{avatarId}", m.getClient(m.userAvatarAnim))
router.HandleFunc("/user/avatar/{userId}/{avatarId}", m.getClient(m.userAvatar)) router.HandleFunc("/user/avatar/{userId}/{avatarId}", m.getClient(m.userAvatar))
router.HandleFunc("/user/banner/{userId}/a_{bannerId}", m.getClient(m.userAvatarAnim))
router.HandleFunc("/user/banner/{userId}/{bannerId}", m.getClient(m.userAvatar))
router.HandleFunc("/guild/icon/{guildId}/a_{iconId}", m.getClient(m.guildIconAnim))
router.HandleFunc("/guild/icon/{guildId}/{iconId}", m.getClient(m.guildIcon)) router.HandleFunc("/guild/icon/{guildId}/{iconId}", m.getClient(m.guildIcon))
router.PathPrefix("/assets/icon/{name}.svg").HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { router.PathPrefix("/assets/icon/{name}.svg").HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
vars := mux.Vars(req) vars := mux.Vars(req)
@ -86,7 +89,7 @@ func (m *Module) getClient(cb func(http.ResponseWriter, *http.Request, *utils.St
}) })
} }
func (m *Module) homepage(rw http.ResponseWriter, req *http.Request, state *utils.State, discordClient *discordgo.Session) { func (m *Module) homepage(rw http.ResponseWriter, _ *http.Request, state *utils.State, discordClient *discordgo.Session) {
myUser, err := discordClient.User("@me") myUser, err := discordClient.User("@me")
if err != nil { if err != nil {
state.Del(KeyOauthClient) state.Del(KeyOauthClient)
@ -122,6 +125,7 @@ func (m *Module) homepage(rw http.ResponseWriter, req *http.Request, state *util
User *discordgo.User User *discordgo.User
UserAccent string UserAccent string
Avatar template.HTMLAttr Avatar template.HTMLAttr
Banner template.HTMLAttr
Guilds []*discordgo.UserGuild Guilds []*discordgo.UserGuild
GuildIcons []template.HTMLAttr GuildIcons []template.HTMLAttr
Connections []*discordgo.UserConnection Connections []*discordgo.UserConnection
@ -129,6 +133,7 @@ func (m *Module) homepage(rw http.ResponseWriter, req *http.Request, state *util
User: myUser, User: myUser,
UserAccent: fmt.Sprintf("#%06x", myUser.AccentColor), UserAccent: fmt.Sprintf("#%06x", myUser.AccentColor),
Avatar: template.HTMLAttr(fmt.Sprintf("src=\"/discord/user/avatar/%s/%s\"", myUser.ID, myUser.Avatar)), Avatar: template.HTMLAttr(fmt.Sprintf("src=\"/discord/user/avatar/%s/%s\"", myUser.ID, myUser.Avatar)),
Banner: template.HTMLAttr(fmt.Sprintf("src=\"/discord/user/banner/%s/%s\"", myUser.ID, myUser.Banner)),
Guilds: myGuilds, Guilds: myGuilds,
GuildIcons: guildIcons, GuildIcons: guildIcons,
Connections: myConns, Connections: myConns,
@ -178,40 +183,51 @@ func (m *Module) loginPage(rw http.ResponseWriter, req *http.Request, state *uti
http.Redirect(rw, req, m.oauthClient.AuthCodeURL(flowState.String(), oauth2.AccessTypeOffline), http.StatusTemporaryRedirect) http.Redirect(rw, req, m.oauthClient.AuthCodeURL(flowState.String(), oauth2.AccessTypeOffline), http.StatusTemporaryRedirect)
} }
func (m *Module) userAvatar(rw http.ResponseWriter, req *http.Request, state *utils.State, discordClient *discordgo.Session) { func (m *Module) bucketFetchImage(rw http.ResponseWriter, discordClient *discordgo.Session, endpoint, emptyEndpoint, contentType string) {
vars := mux.Vars(req) body, err := discordClient.RequestWithBucketID("GET", endpoint, nil, emptyEndpoint)
body, err := discordClient.RequestWithBucketID("GET", discordgo.EndpointUserAvatar(vars["userId"], vars["avatarId"]), nil, discordgo.EndpointUserAvatar("", ""))
if err != nil { if err != nil {
return return
} }
rw.Header().Set("Content-Type", "image/png") rw.Header().Set("Content-Type", contentType)
rw.WriteHeader(200)
myAvatar, _, err := image.Decode(bytes.NewReader(body))
err = png.Encode(rw, myAvatar)
if err != nil {
http.Error(rw, err.Error(), http.StatusInternalServerError)
return
}
}
func (m *Module) guildIcon(rw http.ResponseWriter, req *http.Request, state *utils.State, discordClient *discordgo.Session) {
vars := mux.Vars(req)
body, err := discordClient.RequestWithBucketID("GET", discordgo.EndpointGuildIcon(vars["guildId"], vars["iconId"]), nil, discordgo.EndpointGuildIcon(vars["guildId"], ""))
if err != nil {
return
}
rw.Header().Set("Content-Type", "image/png")
rw.WriteHeader(http.StatusOK) rw.WriteHeader(http.StatusOK)
_, _ = io.Copy(rw, bytes.NewReader(body))
myAvatar, _, err := image.Decode(bytes.NewReader(body))
err = png.Encode(rw, myAvatar)
if err != nil {
http.Error(rw, err.Error(), http.StatusInternalServerError)
return
} }
func (m *Module) userAvatar(rw http.ResponseWriter, req *http.Request, _ *utils.State, discordClient *discordgo.Session) {
vars := mux.Vars(req)
endpoint := discordgo.EndpointUserAvatar
m.bucketFetchImage(rw, discordClient, endpoint(vars["userId"], vars["avatarId"]), endpoint("", ""), "image/png")
}
func (m *Module) userAvatarAnim(rw http.ResponseWriter, req *http.Request, _ *utils.State, discordClient *discordgo.Session) {
vars := mux.Vars(req)
endpoint := discordgo.EndpointUserAvatarAnimated
m.bucketFetchImage(rw, discordClient, endpoint(vars["userId"], "a_"+vars["avatarId"]), endpoint("", ""), "image/gif")
}
func (m *Module) userBanner(rw http.ResponseWriter, req *http.Request, _ *utils.State, discordClient *discordgo.Session) {
vars := mux.Vars(req)
endpoint := discordgo.EndpointUserBanner
m.bucketFetchImage(rw, discordClient, endpoint(vars["userId"], vars["bannerId"]), endpoint("", ""), "image/png")
}
func (m *Module) userBannerAnim(rw http.ResponseWriter, req *http.Request, _ *utils.State, discordClient *discordgo.Session) {
vars := mux.Vars(req)
endpoint := discordgo.EndpointUserBannerAnimated
m.bucketFetchImage(rw, discordClient, endpoint(vars["userId"], "a_"+vars["bannerId"]), endpoint("", ""), "image/gif")
}
func (m *Module) guildIcon(rw http.ResponseWriter, req *http.Request, _ *utils.State, discordClient *discordgo.Session) {
vars := mux.Vars(req)
endpoint := discordgo.EndpointGuildIcon
m.bucketFetchImage(rw, discordClient, endpoint(vars["userId"], vars["guildId"]), endpoint("", ""), "image/png")
}
func (m *Module) guildIconAnim(rw http.ResponseWriter, req *http.Request, _ *utils.State, discordClient *discordgo.Session) {
vars := mux.Vars(req)
endpoint := discordgo.EndpointGuildIconAnimated
m.bucketFetchImage(rw, discordClient, endpoint(vars["userId"], "a_"+vars["guildId"]), endpoint("", ""), "image/gif")
} }
func connectedLinkFunc(a *discordgo.UserConnection) string { func connectedLinkFunc(a *discordgo.UserConnection) string {

View File

@ -48,13 +48,14 @@
<li>ID: {{.ID}}</li> <li>ID: {{.ID}}</li>
<li>Email: {{.Email}}</li> <li>Email: {{.Email}}</li>
<li>Username: {{.Username}}</li> <li>Username: {{.Username}}</li>
<li>Avatar: <img {{$.Avatar}}/></li> <li>Avatar: <img {{$.Avatar}} alt="User Avatar"/></li>
<li>Locale: {{.Locale}}</li> <li>Locale: {{.Locale}}</li>
<li>Discriminator: {{.Discriminator}}</li> <li>Discriminator: {{.Discriminator}}</li>
<li>Verified: {{.Verified}}</li> <li>Verified: {{.Verified}}</li>
<li>MFA: {{.MFAEnabled}}</li> <li>MFA: {{.MFAEnabled}}</li>
<li>Banner: {{.Banner}}</li> <li>Banner: <img {{$.Banner}} alt="User Banner"/></li>
<li>Accent Color: {{$.UserAccent}} <span class="colour-block" style="background-color: {{$.UserAccent}}">&nbsp;</span> <li>Accent Color: {{$.UserAccent}} <span class="colour-block"
style="background-color: {{$.UserAccent}}">&nbsp;</span>
</li> </li>
<li>Bot: {{.Bot}}</li> <li>Bot: {{.Bot}}</li>
<li>Premium: {{.PremiumType}}</li> <li>Premium: {{.PremiumType}}</li>