diff --git a/internal/api/response/message.go b/internal/api/response/message.go index 2fc89fb2..ed476fe4 100644 --- a/internal/api/response/message.go +++ b/internal/api/response/message.go @@ -4,21 +4,20 @@ import ( "fmt" "time" - tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5" "github.com/systemli/ticker/internal/config" "github.com/systemli/ticker/internal/storage" ) type Message struct { - ID int `json:"id"` - CreationDate time.Time `json:"creation_date"` - Text string `json:"text"` - Ticker int `json:"ticker"` - TweetID string `json:"tweet_id"` - TweetUser string `json:"tweet_user"` - TelegramMessages []tgbotapi.Message `json:"telegram_messages"` - GeoInformation string `json:"geo_information"` - Attachments []MessageAttachment `json:"attachments"` + ID int `json:"id"` + CreationDate time.Time `json:"creation_date"` + Text string `json:"text"` + Ticker int `json:"ticker"` + TwitterURL string `json:"twitter_url,omitempty"` + TelegramURL string `json:"telegram_url,omitempty"` + MastodonURL string `json:"mastodon_url,omitempty"` + GeoInformation string `json:"geo_information"` + Attachments []MessageAttachment `json:"attachments"` } type MessageAttachment struct { @@ -36,15 +35,15 @@ func MessageResponse(message storage.Message, config config.Config) Message { } return Message{ - ID: message.ID, - CreationDate: message.CreationDate, - Text: message.Text, - Ticker: message.Ticker, - TweetID: message.Tweet.ID, - TweetUser: message.Tweet.UserName, - TelegramMessages: message.Telegram.Messages, - GeoInformation: string(m), - Attachments: attachments, + ID: message.ID, + CreationDate: message.CreationDate, + Text: message.Text, + Ticker: message.Ticker, + TwitterURL: message.TwitterURL(), + TelegramURL: message.TelegramURL(), + MastodonURL: message.MastodonURL(), + GeoInformation: string(m), + Attachments: attachments, } } diff --git a/internal/api/response/message_test.go b/internal/api/response/message_test.go new file mode 100644 index 00000000..788ea22b --- /dev/null +++ b/internal/api/response/message_test.go @@ -0,0 +1,28 @@ +package response + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/systemli/ticker/internal/config" + "github.com/systemli/ticker/internal/storage" +) + +func TestMessagesResponse(t *testing.T) { + config := config.Config{UploadURL: "https://upload.example.com"} + message := storage.NewMessage() + message.Attachments = []storage.Attachment{{UUID: "uuid", Extension: "jpg"}} + + response := MessagesResponse([]storage.Message{message}, config) + + assert.Equal(t, 1, len(response)) + assert.Empty(t, response[0].TwitterURL) + assert.Empty(t, response[0].TelegramURL) + assert.Empty(t, response[0].MastodonURL) + assert.Equal(t, `{"type":"FeatureCollection","features":[]}`, response[0].GeoInformation) + assert.Equal(t, 1, len(response[0].Attachments)) + + attachments := response[0].Attachments + + assert.Equal(t, "https://upload.example.com/media/uuid.jpg", attachments[0].URL) +} diff --git a/internal/api/response/timeline.go b/internal/api/response/timeline.go new file mode 100644 index 00000000..96678e6a --- /dev/null +++ b/internal/api/response/timeline.go @@ -0,0 +1,47 @@ +package response + +import ( + "fmt" + "time" + + "github.com/systemli/ticker/internal/config" + "github.com/systemli/ticker/internal/storage" +) + +type Timeline []TimelineEntry + +type TimelineEntry struct { + ID int `json:"id"` + CreationDate time.Time `json:"creation_date"` + Text string `json:"text"` + GeoInformation string `json:"geo_information"` + Attachments []MessageAttachment `json:"attachments"` +} + +type Attachment struct { + URL string `json:"url"` + ContentType string `json:"content_type"` +} + +func TimelineResponse(messages []storage.Message, config config.Config) []TimelineEntry { + timeline := make([]TimelineEntry, 0) + for _, message := range messages { + m, _ := message.GeoInformation.MarshalJSON() + + var attachments []MessageAttachment + for _, attachment := range message.Attachments { + name := fmt.Sprintf("%s.%s", attachment.UUID, attachment.Extension) + attachments = append(attachments, MessageAttachment{URL: MediaURL(config.UploadURL, name), ContentType: attachment.ContentType}) + } + + timeline = append(timeline, TimelineEntry{ + ID: message.ID, + CreationDate: message.CreationDate, + Text: message.Text, + GeoInformation: string(m), + Attachments: attachments, + }) + + } + return timeline +} diff --git a/internal/api/response/timeline_test.go b/internal/api/response/timeline_test.go new file mode 100644 index 00000000..b786a27c --- /dev/null +++ b/internal/api/response/timeline_test.go @@ -0,0 +1,25 @@ +package response + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/systemli/ticker/internal/config" + "github.com/systemli/ticker/internal/storage" +) + +func TestTimelineResponse(t *testing.T) { + config := config.Config{UploadURL: "https://upload.example.com"} + message := storage.NewMessage() + message.Attachments = []storage.Attachment{{UUID: "uuid", Extension: "jpg"}} + + response := TimelineResponse([]storage.Message{message}, config) + + assert.Equal(t, 1, len(response)) + assert.Equal(t, `{"type":"FeatureCollection","features":[]}`, response[0].GeoInformation) + assert.Equal(t, 1, len(response[0].Attachments)) + + attachments := response[0].Attachments + + assert.Equal(t, "https://upload.example.com/media/uuid.jpg", attachments[0].URL) +} diff --git a/internal/api/timeline.go b/internal/api/timeline.go index f8df9073..3947a4c5 100644 --- a/internal/api/timeline.go +++ b/internal/api/timeline.go @@ -40,5 +40,5 @@ func (h *handler) GetTimeline(c *gin.Context) { return } - c.JSON(http.StatusOK, response.SuccessResponse(map[string]interface{}{"messages": response.MessagesResponse(messages, h.config)})) + c.JSON(http.StatusOK, response.SuccessResponse(map[string]interface{}{"messages": response.TimelineResponse(messages, h.config)})) } diff --git a/internal/storage/message.go b/internal/storage/message.go index 7164c0be..bd3eebc5 100644 --- a/internal/storage/message.go +++ b/internal/storage/message.go @@ -1,6 +1,7 @@ package storage import ( + "fmt" "time" tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5" @@ -56,3 +57,28 @@ func (m *Message) AddAttachments(uploads []Upload) { m.AddAttachment(upload) } } + +func (m *Message) TwitterURL() string { + if m.Tweet.ID == "" { + return "" + } + + return fmt.Sprintf("https://twitter.com/%s/status/%s", m.Tweet.UserName, m.Tweet.ID) +} + +func (m *Message) TelegramURL() string { + if len(m.Telegram.Messages) == 0 { + return "" + } + + message := m.Telegram.Messages[0] + return fmt.Sprintf("https://t.me/%s/%d", message.Chat.UserName, message.MessageID) +} + +func (m *Message) MastodonURL() string { + if m.Mastodon.ID == "" { + return "" + } + + return m.Mastodon.URL +} diff --git a/internal/storage/message_test.go b/internal/storage/message_test.go new file mode 100644 index 00000000..f74e51c4 --- /dev/null +++ b/internal/storage/message_test.go @@ -0,0 +1,61 @@ +package storage + +import ( + "testing" + + tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5" + "github.com/mattn/go-mastodon" + "github.com/stretchr/testify/assert" +) + +func TestAddAttachments(t *testing.T) { + upload := NewUpload("image.jpg", "image/jped", 1) + message := NewMessage() + message.AddAttachments([]Upload{upload}) + + assert.Equal(t, 1, len(message.Attachments)) +} + +func TestTwitterURL(t *testing.T) { + message := NewMessage() + + assert.Empty(t, message.TwitterURL()) + + message.Tweet.ID = "1" + message.Tweet.UserName = "systemli" + + assert.Equal(t, "https://twitter.com/systemli/status/1", message.TwitterURL()) +} + +func TestTelegramURL(t *testing.T) { + message := NewMessage() + + assert.Empty(t, message.TelegramURL()) + + message.Telegram = TelegramMeta{ + Messages: []tgbotapi.Message{ + { + MessageID: 1, + Chat: &tgbotapi.Chat{ + UserName: "systemli", + }}, + }, + } + + assert.Equal(t, "https://t.me/systemli/1", message.TelegramURL()) + +} + +func TestMastodonURL(t *testing.T) { + message := NewMessage() + + assert.Empty(t, message.MastodonURL()) + + url := "https://mastodon.social/web/@systemli/1" + message.Mastodon = mastodon.Status{ + ID: "1", + URL: url, + } + + assert.Equal(t, url, message.MastodonURL()) +}