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"
|
"math/rand"
|
||||||
"os"
|
"os"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -4164,6 +4165,35 @@ func (m *Messenger) prepareMessage(msg *common.Message, s *server.MediaServer) {
|
||||||
if msg.ContentType == protobuf.ChatMessage_IMAGE {
|
if msg.ContentType == protobuf.ChatMessage_IMAGE {
|
||||||
msg.ImageLocalURL = s.MakeImageURL(msg.ID)
|
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 {
|
if msg.ContentType == protobuf.ChatMessage_AUDIO {
|
||||||
msg.AudioLocalURL = s.MakeAudioURL(msg.ID)
|
msg.AudioLocalURL = s.MakeAudioURL(msg.ID)
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,11 +25,13 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
basePath = "/messages"
|
basePath = "/messages"
|
||||||
identiconsPath = basePath + "/identicons"
|
identiconsPath = basePath + "/identicons"
|
||||||
imagesPath = basePath + "/images"
|
imagesPath = basePath + "/images"
|
||||||
audioPath = basePath + "/audio"
|
audioPath = basePath + "/audio"
|
||||||
ipfsPath = "/ipfs"
|
ipfsPath = "/ipfs"
|
||||||
|
discordAuthorsPath = "/discord/authors"
|
||||||
|
discordAttachmentsPath = basePath + "/discord/attachments"
|
||||||
|
|
||||||
// Handler routes for pairing
|
// Handler routes for pairing
|
||||||
pairingBase = "/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 {
|
func handleImage(db *sql.DB, logger *zap.Logger) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
messageIDs, ok := r.URL.Query()["messageId"]
|
messageIDs, ok := r.URL.Query()["messageId"]
|
||||||
|
|
|
@ -33,12 +33,14 @@ func NewMediaServer(db *sql.DB, downloader *ipfs.Downloader, multiaccountsDB *mu
|
||||||
multiaccountsDB: multiaccountsDB,
|
multiaccountsDB: multiaccountsDB,
|
||||||
}
|
}
|
||||||
s.SetHandlers(HandlerPatternMap{
|
s.SetHandlers(HandlerPatternMap{
|
||||||
imagesPath: handleImage(s.db, s.logger),
|
imagesPath: handleImage(s.db, s.logger),
|
||||||
audioPath: handleAudio(s.db, s.logger),
|
audioPath: handleAudio(s.db, s.logger),
|
||||||
identiconsPath: handleIdenticon(s.logger),
|
identiconsPath: handleIdenticon(s.logger),
|
||||||
ipfsPath: handleIPFS(s.downloader, s.logger),
|
ipfsPath: handleIPFS(s.downloader, s.logger),
|
||||||
accountImagesPath: handleAccountImages(s.multiaccountsDB, s.logger),
|
accountImagesPath: handleAccountImages(s.multiaccountsDB, s.logger),
|
||||||
contactImagesPath: handleContactImages(s.db, s.logger),
|
contactImagesPath: handleContactImages(s.db, s.logger),
|
||||||
|
discordAuthorsPath: handleDiscordAuthorAvatar(s.db, s.logger),
|
||||||
|
discordAttachmentsPath: handleDiscordAttachment(s.db, s.logger),
|
||||||
})
|
})
|
||||||
|
|
||||||
return s, nil
|
return s, nil
|
||||||
|
@ -66,6 +68,22 @@ func (s *MediaServer) MakeImageURL(id string) string {
|
||||||
return u.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 {
|
func (s *MediaServer) MakeAudioURL(id string) string {
|
||||||
u := s.MakeBaseURL()
|
u := s.MakeBaseURL()
|
||||||
u.Path = audioPath
|
u.Path = audioPath
|
||||||
|
|
Loading…
Reference in New Issue