Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 27 additions & 2 deletions app/dl/iter.go
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,10 @@ func (i *iter) process(ctx context.Context) (ret bool, skip bool) {
}

func (i *iter) processSingle(ctx context.Context, message *tg.Message, from peers.Peer, logicalPos int) (bool, bool) {
return i.processSingleWithCaption(ctx, message, from, logicalPos, message.Message)
}

func (i *iter) processSingleWithCaption(ctx context.Context, message *tg.Message, from peers.Peer, logicalPos int, fileCaption string) (bool, bool) {
item, ok := tmedia.GetMedia(message)
if !ok {
logctx.From(ctx).Warn("Message has no media",
Expand All @@ -231,7 +235,7 @@ func (i *iter) processSingle(ctx context.Context, message *tg.Message, from peer
MessageID: message.ID,
MessageDate: int64(message.Date),
FileName: item.Name,
FileCaption: message.Message,
FileCaption: fileCaption,
FileSize: utils.Byte.FormatBinaryBytes(item.Size),
DownloadDate: time.Now().Unix(),
})
Expand Down Expand Up @@ -288,6 +292,7 @@ func (i *iter) processGrouped(ctx context.Context, message *tg.Message, from pee
}

hasValid := false
groupCaption := groupedCaption(grouped)

for idx, msg := range grouped {
logicalPos := startLogicalPos + idx
Expand All @@ -297,7 +302,7 @@ func (i *iter) processGrouped(ctx context.Context, message *tg.Message, from pee
continue
}

ret, skip := i.processSingle(ctx, msg, from, logicalPos)
ret, skip := i.processSingleWithCaption(ctx, msg, from, logicalPos, fileCaption(msg, groupCaption))

// if processSingle encounters a fatal error (not just skip), propagate it
if !ret && !skip {
Expand All @@ -316,6 +321,26 @@ func (i *iter) processGrouped(ctx context.Context, message *tg.Message, from pee
return hasValid, !hasValid
}

func groupedCaption(grouped []*tg.Message) string {
for _, msg := range grouped {
if msg == nil || msg.Message == "" {
continue
}

return msg.Message
}

return ""
}

func fileCaption(message *tg.Message, fallback string) string {
if message.Message != "" {
return message.Message
}

return fallback
}

func (i *iter) Value() downloader.Elem {
return <-i.elem
}
Expand Down
37 changes: 37 additions & 0 deletions app/dl/iter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,47 @@ import (
"testing"
"time"

"github.com/gotd/td/tg"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestGroupedCaption(t *testing.T) {
t.Run("uses first non-empty grouped message caption", func(t *testing.T) {
caption := groupedCaption([]*tg.Message{
{ID: 1, Message: ""},
{ID: 2, Message: "album caption"},
{ID: 3, Message: "later caption"},
})

require.Equal(t, "album caption", caption)
})

t.Run("returns empty caption when group has no caption", func(t *testing.T) {
caption := groupedCaption([]*tg.Message{
nil,
{ID: 1, Message: ""},
{ID: 2, Message: ""},
})

require.Empty(t, caption)
})
}

func TestFileCaption(t *testing.T) {
t.Run("keeps message caption when present", func(t *testing.T) {
caption := fileCaption(&tg.Message{Message: "file caption"}, "album caption")

require.Equal(t, "file caption", caption)
})

t.Run("falls back to grouped caption", func(t *testing.T) {
caption := fileCaption(&tg.Message{Message: ""}, "album caption")

require.Equal(t, "album caption", caption)
})
}

// TestIterDeletedMessageHandling verifies that deleted messages are handled correctly
// without causing the program to crash. This test simulates the scenario where GetSingleMessage
// returns a "may be deleted" error and verifies that the iterator:
Expand Down
2 changes: 1 addition & 1 deletion docs/content/en/guide/template.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Template syntax is based on [Go's text/template](https://golang.org/pkg/text/tem
| `MessageID` | Telegram message id |
| `MessageDate` | Telegram message date(timestamp) |
| `FileName` | Telegram file name |
| `FileCaption` | Telegram file caption, aka. text message |
| `FileCaption` | Telegram file caption, aka. text message. In grouped media, files without their own caption use the first non-empty group caption. |
| `FileSize` | Human-readable file size, like `1GB` |
| `DownloadDate` | Download date(timestamp) |

Expand Down
2 changes: 1 addition & 1 deletion docs/content/zh/guide/template.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ bookToC: false
| `MessageID` | Telegram 消息ID |
| `MessageDate` | Telegram 消息日期(时间戳) |
| `FileName` | Telegram 文件名 |
| `FileCaption` | Telegram 文件说明,也就是文本消息 |
| `FileCaption` | Telegram 文件说明,也就是文本消息。组合消息中没有自身 caption 的文件会使用同组第一个非空 caption。 |
| `FileSize` | 可读的文件大小,例如 `1GB` |
| `DownloadDate` | 下载日期(时间戳) |

Expand Down