feat(MediaServer): add support for discord author and attachment URLs
This commit is contained in:
parent
b01a861e8e
commit
1eb8a5cc2c
|
@ -14,6 +14,7 @@ import (
|
|||
"math/rand"
|
||||
"os"
|
||||
"reflect"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
|
@ -4164,6 +4165,35 @@ func (m *Messenger) prepareMessage(msg *common.Message, s *server.MediaServer) {
|
|||
if msg.ContentType == protobuf.ChatMessage_IMAGE {
|
||||
msg.ImageLocalURL = s.MakeImageURL(msg.ID)
|
||||
}
|
||||
if msg.ContentType == protobuf.ChatMessage_DISCORD_MESSAGE {
|
||||
|
||||
dm := msg.GetDiscordMessage()
|
||||
exists, err := m.persistence.HasDiscordMessageAuthorImagePayload(dm.Author.Id)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if exists {
|
||||
dm.Author.LocalUrl = s.MakeDiscordAuthorAvatarURL(dm.Author.Id)
|
||||
}
|
||||
|
||||
for idx, attachment := range dm.Attachments {
|
||||
if strings.Contains(attachment.ContentType, "image") {
|
||||
hasPayload, err := m.persistence.HasDiscordMessageAttachmentPayload(attachment.Id)
|
||||
if err != nil {
|
||||
m.logger.Error("failed to check if message attachment exist", zap.Error(err))
|
||||
continue
|
||||
}
|
||||
if hasPayload {
|
||||
localURL := s.MakeDiscordAttachmentURL(dm.Id, attachment.Id)
|
||||
dm.Attachments[idx].LocalUrl = localURL
|
||||
}
|
||||
}
|
||||
}
|
||||
msg.Payload = &protobuf.ChatMessage_DiscordMessage{
|
||||
DiscordMessage: dm,
|
||||
}
|
||||
}
|
||||
if msg.ContentType == protobuf.ChatMessage_AUDIO {
|
||||
msg.AudioLocalURL = s.MakeAudioURL(msg.ID)
|
||||
}
|
||||
|
|
|
@ -25,11 +25,13 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
basePath = "/messages"
|
||||
identiconsPath = basePath + "/identicons"
|
||||
imagesPath = basePath + "/images"
|
||||
audioPath = basePath + "/audio"
|
||||
ipfsPath = "/ipfs"
|
||||
basePath = "/messages"
|
||||
identiconsPath = basePath + "/identicons"
|
||||
imagesPath = basePath + "/images"
|
||||
audioPath = basePath + "/audio"
|
||||
ipfsPath = "/ipfs"
|
||||
discordAuthorsPath = "/discord/authors"
|
||||
discordAttachmentsPath = basePath + "/discord/attachments"
|
||||
|
||||
// Handler routes for pairing
|
||||
pairingBase = "/pairing"
|
||||
|
@ -236,6 +238,79 @@ func handleIdenticon(logger *zap.Logger) http.HandlerFunc {
|
|||
}
|
||||
}
|
||||
|
||||
func handleDiscordAuthorAvatar(db *sql.DB, logger *zap.Logger) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
authorIDs, ok := r.URL.Query()["authorId"]
|
||||
if !ok || len(authorIDs) == 0 {
|
||||
logger.Error("no authorIDs")
|
||||
return
|
||||
}
|
||||
authorID := authorIDs[0]
|
||||
|
||||
var image []byte
|
||||
err := db.QueryRow(`SELECT avatar_image_payload FROM discord_message_authors WHERE id = ?`, authorID).Scan(&image)
|
||||
if err != nil {
|
||||
logger.Error("failed to find image", zap.Error(err))
|
||||
return
|
||||
}
|
||||
if len(image) == 0 {
|
||||
logger.Error("empty image")
|
||||
return
|
||||
}
|
||||
mime, err := images.ImageMime(image)
|
||||
if err != nil {
|
||||
logger.Error("failed to get mime", zap.Error(err))
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", mime)
|
||||
w.Header().Set("Cache-Control", "no-store")
|
||||
|
||||
_, err = w.Write(image)
|
||||
if err != nil {
|
||||
logger.Error("failed to write image", zap.Error(err))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func handleDiscordAttachment(db *sql.DB, logger *zap.Logger) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
messageIDs, ok := r.URL.Query()["messageId"]
|
||||
if !ok || len(messageIDs) == 0 {
|
||||
logger.Error("no messageID")
|
||||
return
|
||||
}
|
||||
attachmentIDs, ok := r.URL.Query()["attachmentId"]
|
||||
if !ok || len(attachmentIDs) == 0 {
|
||||
logger.Error("no attachmentID")
|
||||
return
|
||||
}
|
||||
messageID := messageIDs[0]
|
||||
attachmentID := attachmentIDs[0]
|
||||
var image []byte
|
||||
err := db.QueryRow(`SELECT payload FROM discord_message_attachments WHERE discord_message_id = ? AND id = ?`, messageID, attachmentID).Scan(&image)
|
||||
if err != nil {
|
||||
logger.Error("failed to find image", zap.Error(err))
|
||||
return
|
||||
}
|
||||
if len(image) == 0 {
|
||||
logger.Error("empty image")
|
||||
return
|
||||
}
|
||||
mime, err := images.ImageMime(image)
|
||||
if err != nil {
|
||||
logger.Error("failed to get mime", zap.Error(err))
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", mime)
|
||||
w.Header().Set("Cache-Control", "no-store")
|
||||
|
||||
_, err = w.Write(image)
|
||||
if err != nil {
|
||||
logger.Error("failed to write image", zap.Error(err))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func handleImage(db *sql.DB, logger *zap.Logger) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
messageIDs, ok := r.URL.Query()["messageId"]
|
||||
|
|
|
@ -33,12 +33,14 @@ func NewMediaServer(db *sql.DB, downloader *ipfs.Downloader, multiaccountsDB *mu
|
|||
multiaccountsDB: multiaccountsDB,
|
||||
}
|
||||
s.SetHandlers(HandlerPatternMap{
|
||||
imagesPath: handleImage(s.db, s.logger),
|
||||
audioPath: handleAudio(s.db, s.logger),
|
||||
identiconsPath: handleIdenticon(s.logger),
|
||||
ipfsPath: handleIPFS(s.downloader, s.logger),
|
||||
accountImagesPath: handleAccountImages(s.multiaccountsDB, s.logger),
|
||||
contactImagesPath: handleContactImages(s.db, s.logger),
|
||||
imagesPath: handleImage(s.db, s.logger),
|
||||
audioPath: handleAudio(s.db, s.logger),
|
||||
identiconsPath: handleIdenticon(s.logger),
|
||||
ipfsPath: handleIPFS(s.downloader, s.logger),
|
||||
accountImagesPath: handleAccountImages(s.multiaccountsDB, s.logger),
|
||||
contactImagesPath: handleContactImages(s.db, s.logger),
|
||||
discordAuthorsPath: handleDiscordAuthorAvatar(s.db, s.logger),
|
||||
discordAttachmentsPath: handleDiscordAttachment(s.db, s.logger),
|
||||
})
|
||||
|
||||
return s, nil
|
||||
|
@ -66,6 +68,22 @@ func (s *MediaServer) MakeImageURL(id string) string {
|
|||
return u.String()
|
||||
}
|
||||
|
||||
func (s *MediaServer) MakeDiscordAuthorAvatarURL(authorID string) string {
|
||||
u := s.MakeBaseURL()
|
||||
u.Path = discordAuthorsPath
|
||||
u.RawQuery = url.Values{"authorId": {authorID}}.Encode()
|
||||
|
||||
return u.String()
|
||||
}
|
||||
|
||||
func (s *MediaServer) MakeDiscordAttachmentURL(messageID string, id string) string {
|
||||
u := s.MakeBaseURL()
|
||||
u.Path = discordAttachmentsPath
|
||||
u.RawQuery = url.Values{"messageId": {messageID}, "attachmentId": {id}}.Encode()
|
||||
|
||||
return u.String()
|
||||
}
|
||||
|
||||
func (s *MediaServer) MakeAudioURL(id string) string {
|
||||
u := s.MakeBaseURL()
|
||||
u.Path = audioPath
|
||||
|
|
Loading…
Reference in New Issue