[bugfix] Use length in runes when trimming for RSS (#2094)
This commit is contained in:
parent
992c7ce4c2
commit
5588d4e88e
|
@ -32,8 +32,8 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
rssMaxTitleChars = 128
|
rssTitleMaxRunes = 128
|
||||||
rssDescriptionMaxChars = 256
|
rssDescriptionMaxRunes = 256
|
||||||
)
|
)
|
||||||
|
|
||||||
func (c *converter) StatusToRSSItem(ctx context.Context, s *gtsmodel.Status) (*feeds.Item, error) {
|
func (c *converter) StatusToRSSItem(ctx context.Context, s *gtsmodel.Status) (*feeds.Item, error) {
|
||||||
|
@ -43,9 +43,9 @@ func (c *converter) StatusToRSSItem(ctx context.Context, s *gtsmodel.Status) (*f
|
||||||
// example: Venice Film Festival Tries to Quit Sinking
|
// example: Venice Film Festival Tries to Quit Sinking
|
||||||
var title string
|
var title string
|
||||||
if s.ContentWarning != "" {
|
if s.ContentWarning != "" {
|
||||||
title = trimTo(s.ContentWarning, rssMaxTitleChars)
|
title = trimTo(s.ContentWarning, rssTitleMaxRunes)
|
||||||
} else {
|
} else {
|
||||||
title = trimTo(s.Text, rssMaxTitleChars)
|
title = trimTo(s.Text, rssTitleMaxRunes)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Link -- The URL of the item.
|
// Link -- The URL of the item.
|
||||||
|
@ -97,7 +97,7 @@ func (c *converter) StatusToRSSItem(ctx context.Context, s *gtsmodel.Status) (*f
|
||||||
descriptionBuilder.WriteString("\"")
|
descriptionBuilder.WriteString("\"")
|
||||||
}
|
}
|
||||||
|
|
||||||
description := trimTo(descriptionBuilder.String(), rssDescriptionMaxChars)
|
description := trimTo(descriptionBuilder.String(), rssDescriptionMaxRunes)
|
||||||
|
|
||||||
// ID -- A string that uniquely identifies the item.
|
// ID -- A string that uniquely identifies the item.
|
||||||
// example: http://inessential.com/2002/09/01.php#a2
|
// example: http://inessential.com/2002/09/01.php#a2
|
||||||
|
@ -167,10 +167,26 @@ func (c *converter) StatusToRSSItem(ctx context.Context, s *gtsmodel.Status) (*f
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// trimTo trims the given `in` string to
|
||||||
|
// the length `to`, measured in runes.
|
||||||
|
//
|
||||||
|
// The reason for using runes is to avoid
|
||||||
|
// cutting off UTF-8 characters in the
|
||||||
|
// middle, and generating garbled bytes.
|
||||||
|
//
|
||||||
|
// If trimming was necessary, the returned
|
||||||
|
// string will be suffixed with ellipsis
|
||||||
|
// (`...`) to indicate omission.
|
||||||
func trimTo(in string, to int) string {
|
func trimTo(in string, to int) string {
|
||||||
if len(in) <= to {
|
var (
|
||||||
|
runes = []rune(in)
|
||||||
|
runesLen = len(runes)
|
||||||
|
)
|
||||||
|
|
||||||
|
if runesLen <= to {
|
||||||
|
// Fine as-is.
|
||||||
return in
|
return in
|
||||||
}
|
}
|
||||||
|
|
||||||
return in[:to-3] + "..."
|
return string(runes[:to-3]) + "..."
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,9 +19,13 @@ package typeutils_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/xml"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/suite"
|
"github.com/stretchr/testify/suite"
|
||||||
|
"github.com/superseriousbusiness/gotosocial/internal/ap"
|
||||||
|
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
|
||||||
|
"github.com/superseriousbusiness/gotosocial/internal/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
type InternalToRSSTestSuite struct {
|
type InternalToRSSTestSuite struct {
|
||||||
|
@ -80,6 +84,63 @@ func (suite *InternalToRSSTestSuite) TestStatusToRSSItem2() {
|
||||||
suite.Equal("hello world! #welcome ! first post on the instance <img src=\"http://localhost:8080/fileserver/01AY6P665V14JJR0AFVRT7311Y/emoji/original/01F8MH9H8E4VG3KDYJR9EGPXCQ.png\" title=\":rainbow:\" alt=\":rainbow:\" class=\"emoji\"/> !", item.Content)
|
suite.Equal("hello world! #welcome ! first post on the instance <img src=\"http://localhost:8080/fileserver/01AY6P665V14JJR0AFVRT7311Y/emoji/original/01F8MH9H8E4VG3KDYJR9EGPXCQ.png\" title=\":rainbow:\" alt=\":rainbow:\" class=\"emoji\"/> !", item.Content)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (suite *InternalToRSSTestSuite) TestStatusToRSSItem3() {
|
||||||
|
account := suite.testAccounts["admin_account"]
|
||||||
|
s := >smodel.Status{
|
||||||
|
ID: "01H7G0VW1ACBZTRHN6RSA4JWVH",
|
||||||
|
URI: "http://localhost:8080/users/admin/statuses/01H7G0VW1ACBZTRHN6RSA4JWVH",
|
||||||
|
URL: "http://localhost:8080/@admin/statuses/01H7G0VW1ACBZTRHN6RSA4JWVH",
|
||||||
|
ContentWarning: "这是简体中文帖子的一些示例内容。\n\n我希望我能读到这个,因为与无聊的旧 ASCII 相比,这些字符绝对漂亮。 不幸的是,我是一个愚蠢的西方人。\n\n无论如何,无论是谁读到这篇文章,你今天过得怎么样? 希望你过得愉快! 如果您有一段时间没有这样做,请从椅子上站起来,喝一杯水,并将您的眼睛集中在远处的物体上,而不是电脑屏幕上!",
|
||||||
|
Content: "这是另一段,只是为了确保这篇文章足够长。 通过前肢上长而弯曲的爪子的数量可以轻松识别不同的树懒类别。 顾名思义,二趾树懒的前肢上有两个爪子,而三趾树懒的四个肢上都有三个爪子。 二趾树懒也比三趾树懒稍大,并且都属于不同的分类科。 美洲共有六种树懒,主要分布在中美洲和南美洲的热带雨林中。\n\n\n\n\t霍夫曼二趾树懒 (Choloepus hoffmanni)\n\n\t林奈二趾树懒 (Choloepus didactylus)\n\n\t侏儒三趾树懒 (Bradypus pygmaeus)\n\n\t鬃三趾树懒 (Bradypus torquatus)\n\n\t棕喉树懒 (Bradypus variegatus)\n\n\t浅喉树懒 (Bradypus tridactylus)\n\n\n\n目前,有 4 种树懒被 IUCN 濒危物种红色名录列为最不受关注的物种。 鬃毛三趾树懒很脆弱,而侏儒三趾树懒则极度濒危,树懒物种面临最大的灭绝风险。",
|
||||||
|
Local: util.Ptr(true),
|
||||||
|
AccountURI: account.URI,
|
||||||
|
AccountID: account.ID,
|
||||||
|
Visibility: gtsmodel.VisibilityDefault,
|
||||||
|
ActivityStreamsType: ap.ObjectNote,
|
||||||
|
Federated: util.Ptr(true),
|
||||||
|
Boostable: util.Ptr(true),
|
||||||
|
Replyable: util.Ptr(true),
|
||||||
|
Likeable: util.Ptr(true),
|
||||||
|
}
|
||||||
|
item, err := suite.typeconverter.StatusToRSSItem(context.Background(), s)
|
||||||
|
suite.NoError(err)
|
||||||
|
|
||||||
|
data, err := xml.MarshalIndent(item, "", " ")
|
||||||
|
if err != nil {
|
||||||
|
suite.FailNow(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
suite.Equal(`<Item>
|
||||||
|
<Title>这是简体中文帖子的一些示例内容。

我希望我能读到这个,因为与无聊的旧 ASCII 相比,这些字符绝对漂亮。 不幸的是,我是一个愚蠢的西方人。

无论如何,无论是谁读到这篇文章,你今天过得怎么样? 希望你过得愉快! 如果您有一段时间没有这样做,请从椅...</Title>
|
||||||
|
<Link>
|
||||||
|
<Href>http://localhost:8080/@admin/statuses/01H7G0VW1ACBZTRHN6RSA4JWVH</Href>
|
||||||
|
<Rel></Rel>
|
||||||
|
<Type></Type>
|
||||||
|
<Length></Length>
|
||||||
|
</Link>
|
||||||
|
<Source>
|
||||||
|
<Href>http://localhost:8080/@admin/feed.rss</Href>
|
||||||
|
<Rel></Rel>
|
||||||
|
<Type></Type>
|
||||||
|
<Length></Length>
|
||||||
|
</Source>
|
||||||
|
<Author>
|
||||||
|
<Name>@admin@localhost:8080</Name>
|
||||||
|
<Email></Email>
|
||||||
|
</Author>
|
||||||
|
<Description>@admin@localhost:8080 made a new post</Description>
|
||||||
|
<Id>http://localhost:8080/@admin/statuses/01H7G0VW1ACBZTRHN6RSA4JWVH</Id>
|
||||||
|
<Updated>0001-01-01T00:00:00Z</Updated>
|
||||||
|
<Created>0001-01-01T00:00:00Z</Created>
|
||||||
|
<Enclosure>
|
||||||
|
<Url></Url>
|
||||||
|
<Length></Length>
|
||||||
|
<Type></Type>
|
||||||
|
</Enclosure>
|
||||||
|
<Content>这是另一段,只是为了确保这篇文章足够长。 通过前肢上长而弯曲的爪子的数量可以轻松识别不同的树懒类别。 顾名思义,二趾树懒的前肢上有两个爪子,而三趾树懒的四个肢上都有三个爪子。 二趾树懒也比三趾树懒稍大,并且都属于不同的分类科。 美洲共有六种树懒,主要分布在中美洲和南美洲的热带雨林中。



	霍夫曼二趾树懒 (Choloepus hoffmanni)

	林奈二趾树懒 (Choloepus didactylus)

	侏儒三趾树懒 (Bradypus pygmaeus)

	鬃三趾树懒 (Bradypus torquatus)

	棕喉树懒 (Bradypus variegatus)

	浅喉树懒 (Bradypus tridactylus)



目前,有 4 种树懒被 IUCN 濒危物种红色名录列为最不受关注的物种。 鬃毛三趾树懒很脆弱,而侏儒三趾树懒则极度濒危,树懒物种面临最大的灭绝风险。</Content>
|
||||||
|
</Item>`, string(data))
|
||||||
|
}
|
||||||
|
|
||||||
func TestInternalToRSSTestSuite(t *testing.T) {
|
func TestInternalToRSSTestSuite(t *testing.T) {
|
||||||
suite.Run(t, new(InternalToRSSTestSuite))
|
suite.Run(t, new(InternalToRSSTestSuite))
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue