Skip to content

Commit

Permalink
feat(MediaServer): add support for discord author and attachment URLs
Browse files Browse the repository at this point in the history
  • Loading branch information
0x-r4bbit committed Sep 29, 2022
1 parent b01a861 commit 1eb8a5c
Show file tree
Hide file tree
Showing 3 changed files with 134 additions and 11 deletions.
30 changes: 30 additions & 0 deletions protocol/messenger.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"math/rand"
"os"
"reflect"
"strings"
"sync"
"time"

Expand Down Expand Up @@ -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)
}
Expand Down
85 changes: 80 additions & 5 deletions server/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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"]
Expand Down
30 changes: 24 additions & 6 deletions server/server_media.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 1eb8a5c

Please sign in to comment.