mirror of
https://github.com/superseriousbusiness/gotosocial.git
synced 2025-12-07 16:18:08 -06:00
Merge branch 'main' into add_gallery_web_rendering_mode
This commit is contained in:
commit
5822d451c7
214 changed files with 29471 additions and 4720 deletions
|
|
@ -98,10 +98,17 @@ const (
|
|||
// that we don't *yet* know what type of Object something is.
|
||||
ObjectUnknown = "Unknown"
|
||||
|
||||
// Extensions and unofficial additions.
|
||||
/* Extensions and unofficial additions */
|
||||
|
||||
/* GtS stuff */
|
||||
|
||||
ObjectLikeApproval = "LikeApproval"
|
||||
ObjectReplyApproval = "ReplyApproval"
|
||||
ObjectAnnounceApproval = "AnnounceApproval"
|
||||
|
||||
/* Funkwhale stuff */
|
||||
|
||||
ObjectAlbum = "Album"
|
||||
)
|
||||
|
||||
// isActivity returns whether AS type name is of an Activity (NOT IntransitiveActivity).
|
||||
|
|
|
|||
|
|
@ -1078,7 +1078,14 @@ func ExtractInteractionPolicy(
|
|||
statusable Statusable,
|
||||
owner *gtsmodel.Account,
|
||||
) *gtsmodel.InteractionPolicy {
|
||||
policyProp := statusable.GetGoToSocialInteractionPolicy()
|
||||
ipa, ok := statusable.(InteractionPolicyAware)
|
||||
if !ok {
|
||||
// Not a type with interaction
|
||||
// policy properties settable.
|
||||
return nil
|
||||
}
|
||||
|
||||
policyProp := ipa.GetGoToSocialInteractionPolicy()
|
||||
if policyProp == nil || policyProp.Len() != 1 {
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -76,7 +76,8 @@ func IsStatusable(typeName string) bool {
|
|||
ObjectEvent,
|
||||
ObjectPlace,
|
||||
ObjectProfile,
|
||||
ActivityQuestion:
|
||||
ActivityQuestion,
|
||||
ObjectAlbum:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
|
|
@ -226,11 +227,13 @@ type Statusable interface {
|
|||
WithTo
|
||||
WithCc
|
||||
WithSensitive
|
||||
WithConversation
|
||||
WithContent
|
||||
WithAttachment
|
||||
WithTag
|
||||
WithReplies
|
||||
}
|
||||
|
||||
type InteractionPolicyAware interface {
|
||||
WithInteractionPolicy
|
||||
WithApprovedBy
|
||||
}
|
||||
|
|
@ -589,10 +592,6 @@ type WithSensitive interface {
|
|||
SetActivityStreamsSensitive(vocab.ActivityStreamsSensitiveProperty)
|
||||
}
|
||||
|
||||
// WithConversation ...
|
||||
type WithConversation interface { // TODO
|
||||
}
|
||||
|
||||
// WithContent represents an activity with ActivityStreamsContentProperty
|
||||
type WithContent interface {
|
||||
GetActivityStreamsContent() vocab.ActivityStreamsContentProperty
|
||||
|
|
|
|||
|
|
@ -80,6 +80,56 @@ func (suite *ResolveTestSuite) TestResolveNonAPJSONAsAccountable() {
|
|||
suite.Nil(accountable)
|
||||
}
|
||||
|
||||
func (suite *ResolveTestSuite) TestResolveBandwagonAlbumAsStatusable() {
|
||||
b := []byte(`{
|
||||
"@context": [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
"https://w3id.org/security/v1",
|
||||
{
|
||||
"discoverable": "toot:discoverable",
|
||||
"indexable": "toot:indexable",
|
||||
"toot": "https://joinmastodon.org/ns#"
|
||||
},
|
||||
"https://funkwhale.audio/ns"
|
||||
],
|
||||
"artists": [
|
||||
{
|
||||
"id": "https://bandwagon.fm/@67a0a0808121f77ed3466870",
|
||||
"name": "Luka Prinčič",
|
||||
"type": "Artist"
|
||||
}
|
||||
],
|
||||
"attachment": [
|
||||
{
|
||||
"mediaType": "image/webp",
|
||||
"name": "image",
|
||||
"type": "Document",
|
||||
"url": "https://bandwagon.fm/67a0a219f050061c8b4ce427/attachments/67a0a21bf050061c8b4ce429"
|
||||
}
|
||||
],
|
||||
"attributedTo": "https://bandwagon.fm/@67a0a0808121f77ed3466870",
|
||||
"content": "... a transgenre mutation, a fluid entity, jagged pop, electro-funk, techno-cabaret, a schlager, and soft alternative, queer to the core, satire and tragedy, sharp and fun indulgence for the dance of bodies and brains, activism and hedonism, which would all like to steal your attention.\r\n\r\nDRAGX̶FUNK is pronounced /dɹæɡɑːfʌŋk/.\r\n\r\n---\r\n\r\n## Buy digital\r\n💳 [Stripe](https://buy.stripe.com/6oE8x52iG1Kq5pKeV3)\r\n\r\n---\r\n\r\n## Buy dl/merch\r\n🎵 [Bandcamp](https://lukaprincic.bandcamp.com/album/dragx-funk) \r\n\r\n---\r\n\r\n## More:\r\n🌐 [prin.lu](https://prin.lu/music/241205_dragx-funk/) \r\n👉 [kamizdat.si](https://kamizdat.si/releases/dragx-funk-2/)\r\n",
|
||||
"context": "https://bandwagon.fm/67a0a219f050061c8b4ce427",
|
||||
"id": "https://bandwagon.fm/67a0a219f050061c8b4ce427",
|
||||
"library": "https://bandwagon.fm/67a0a219f050061c8b4ce427/pub/children",
|
||||
"license": "CC-BY-NC-SA",
|
||||
"name": "DRAGX̶FUNK",
|
||||
"published": "2025-03-17T11:40:53Z",
|
||||
"to": [
|
||||
"https://www.w3.org/ns/activitystreams#Public"
|
||||
],
|
||||
"tracks": "https://bandwagon.fm/67a0a219f050061c8b4ce427/pub/children",
|
||||
"type": "Album",
|
||||
"url": "https://bandwagon.fm/67a0a219f050061c8b4ce427"
|
||||
}`)
|
||||
|
||||
statusable, err := ap.ResolveStatusable(
|
||||
context.Background(), io.NopCloser(bytes.NewReader(b)),
|
||||
)
|
||||
suite.NoError(err)
|
||||
suite.NotNil(statusable)
|
||||
}
|
||||
|
||||
func TestResolveTestSuite(t *testing.T) {
|
||||
suite.Run(t, &ResolveTestSuite{})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -153,7 +153,9 @@ func serializeStatusable(t vocab.Type, includeContext bool) (map[string]interfac
|
|||
|
||||
NormalizeOutgoingAttachmentProp(statusable, data)
|
||||
NormalizeOutgoingContentProp(statusable, data)
|
||||
NormalizeOutgoingInteractionPolicyProp(statusable, data)
|
||||
if ipa, ok := statusable.(InteractionPolicyAware); ok {
|
||||
NormalizeOutgoingInteractionPolicyProp(ipa, data)
|
||||
}
|
||||
|
||||
return data, nil
|
||||
}
|
||||
|
|
|
|||
8
internal/cache/cache.go
vendored
8
internal/cache/cache.go
vendored
|
|
@ -144,8 +144,12 @@ func (c *Caches) Start() error {
|
|||
func (c *Caches) Stop() {
|
||||
log.Infof(nil, "stop: %p", c)
|
||||
|
||||
_ = c.Webfinger.Stop()
|
||||
_ = c.StatusesFilterableFields.Stop()
|
||||
if c.Webfinger != nil {
|
||||
_ = c.Webfinger.Stop()
|
||||
}
|
||||
if c.StatusesFilterableFields != nil {
|
||||
_ = c.StatusesFilterableFields.Stop()
|
||||
}
|
||||
}
|
||||
|
||||
// Sweep will sweep all the available caches to ensure none
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ package subscriptions
|
|||
|
||||
import (
|
||||
"bufio"
|
||||
"cmp"
|
||||
"context"
|
||||
"encoding/csv"
|
||||
"encoding/json"
|
||||
|
|
@ -869,10 +870,13 @@ func (s *Subscriptions) adoptPerm(
|
|||
perm.SetCreatedByAccount(permSub.CreatedByAccount)
|
||||
|
||||
// Set new metadata on the perm.
|
||||
perm.SetObfuscate(obfuscate)
|
||||
perm.SetPrivateComment(privateComment)
|
||||
perm.SetPublicComment(publicComment)
|
||||
|
||||
// Avoid trying to blat nil into the db directly by
|
||||
// defaulting to false if not set on wanted perm.
|
||||
perm.SetObfuscate(cmp.Or(obfuscate, util.Ptr(false)))
|
||||
|
||||
// Update the perm in the db.
|
||||
var err error
|
||||
switch p := perm.(type) {
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/stretchr/testify/suite"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/db"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/subscriptions"
|
||||
|
|
@ -814,6 +815,141 @@ func (suite *SubscriptionsTestSuite) TestAdoption() {
|
|||
suite.Equal(testSubscription.ID, existingBlock3.SubscriptionID)
|
||||
}
|
||||
|
||||
func (suite *SubscriptionsTestSuite) TestDomainAllowsAndBlocks() {
|
||||
var (
|
||||
ctx = context.Background()
|
||||
testStructs = testrig.SetupTestStructs(rMediaPath, rTemplatePath)
|
||||
testAccount = suite.testAccounts["admin_account"]
|
||||
subscriptions = subscriptions.New(
|
||||
testStructs.State,
|
||||
testStructs.TransportController,
|
||||
testStructs.TypeConverter,
|
||||
)
|
||||
|
||||
// Create a subscription for a CSV list of goodies.
|
||||
// This one adopts orphans.
|
||||
testAllowSubscription = >smodel.DomainPermissionSubscription{
|
||||
ID: "01JGE681TQSBPAV59GZXPKE62H",
|
||||
Priority: 255,
|
||||
Title: "goodies!",
|
||||
PermissionType: gtsmodel.DomainPermissionAllow,
|
||||
AsDraft: util.Ptr(false),
|
||||
AdoptOrphans: util.Ptr(true),
|
||||
CreatedByAccountID: testAccount.ID,
|
||||
CreatedByAccount: testAccount,
|
||||
URI: "https://lists.example.org/goodies",
|
||||
ContentType: gtsmodel.DomainPermSubContentTypePlain,
|
||||
}
|
||||
|
||||
existingAllow = >smodel.DomainAllow{
|
||||
ID: "01JHX2V5WN250TKB6FQ1M3QE1H",
|
||||
Domain: "people.we.like.com",
|
||||
CreatedByAccount: testAccount,
|
||||
CreatedByAccountID: testAccount.ID,
|
||||
}
|
||||
|
||||
testBlockSubscription = >smodel.DomainPermissionSubscription{
|
||||
ID: "01JPMVY19TKZND838Z7Y6S4EG8",
|
||||
Priority: 255,
|
||||
Title: "baddies!",
|
||||
PermissionType: gtsmodel.DomainPermissionBlock,
|
||||
AsDraft: util.Ptr(false),
|
||||
AdoptOrphans: util.Ptr(false),
|
||||
CreatedByAccountID: testAccount.ID,
|
||||
CreatedByAccount: testAccount,
|
||||
URI: "https://lists.example.org/baddies.csv",
|
||||
ContentType: gtsmodel.DomainPermSubContentTypeCSV,
|
||||
}
|
||||
)
|
||||
defer testrig.TearDownTestStructs(testStructs)
|
||||
|
||||
// Store test subscriptions.
|
||||
if err := testStructs.State.DB.PutDomainPermissionSubscription(
|
||||
ctx, testAllowSubscription,
|
||||
); err != nil {
|
||||
suite.FailNow(err.Error())
|
||||
}
|
||||
if err := testStructs.State.DB.PutDomainPermissionSubscription(
|
||||
ctx, testBlockSubscription,
|
||||
); err != nil {
|
||||
suite.FailNow(err.Error())
|
||||
}
|
||||
|
||||
// Store existing allow.
|
||||
if err := testStructs.State.DB.CreateDomainAllow(ctx, existingAllow); err != nil {
|
||||
suite.FailNow(err.Error())
|
||||
}
|
||||
|
||||
// Put the instance in allowlist mode.
|
||||
config.SetInstanceFederationMode("allowlist")
|
||||
|
||||
// Fetch + process subscribed perms in order.
|
||||
var order [2]gtsmodel.DomainPermissionType
|
||||
if config.GetInstanceFederationMode() == config.InstanceFederationModeBlocklist {
|
||||
order = [2]gtsmodel.DomainPermissionType{
|
||||
gtsmodel.DomainPermissionAllow,
|
||||
gtsmodel.DomainPermissionBlock,
|
||||
}
|
||||
} else {
|
||||
order = [2]gtsmodel.DomainPermissionType{
|
||||
gtsmodel.DomainPermissionBlock,
|
||||
gtsmodel.DomainPermissionAllow,
|
||||
}
|
||||
}
|
||||
for _, permType := range order {
|
||||
subscriptions.ProcessDomainPermissionSubscriptions(ctx, permType)
|
||||
}
|
||||
|
||||
// We should now have allows for each
|
||||
// domain on the subscribed allow list.
|
||||
for _, domain := range []string{
|
||||
"people.we.like.com",
|
||||
"goodeggs.org",
|
||||
"allowthesefolks.church",
|
||||
} {
|
||||
var (
|
||||
perm gtsmodel.DomainPermission
|
||||
err error
|
||||
)
|
||||
if !testrig.WaitFor(func() bool {
|
||||
perm, err = testStructs.State.DB.GetDomainAllow(ctx, domain)
|
||||
return err == nil
|
||||
}) {
|
||||
suite.FailNowf("", "timed out waiting for domain %s", domain)
|
||||
}
|
||||
|
||||
suite.Equal(testAllowSubscription.ID, perm.GetSubscriptionID())
|
||||
}
|
||||
|
||||
// And blocks for for each domain
|
||||
// on the subscribed block list.
|
||||
for _, domain := range []string{
|
||||
"bumfaces.net",
|
||||
"peepee.poopoo",
|
||||
"nothanks.com",
|
||||
} {
|
||||
var (
|
||||
perm gtsmodel.DomainPermission
|
||||
err error
|
||||
)
|
||||
if !testrig.WaitFor(func() bool {
|
||||
perm, err = testStructs.State.DB.GetDomainBlock(ctx, domain)
|
||||
return err == nil
|
||||
}) {
|
||||
suite.FailNowf("", "timed out waiting for domain %s", domain)
|
||||
}
|
||||
|
||||
suite.Equal(testBlockSubscription.ID, perm.GetSubscriptionID())
|
||||
}
|
||||
|
||||
var err error
|
||||
existingAllow, err = testStructs.State.DB.GetDomainAllow(ctx, "people.we.like.com")
|
||||
if err != nil {
|
||||
suite.FailNow(err.Error())
|
||||
}
|
||||
suite.Equal(existingAllow.SubscriptionID, testAllowSubscription.ID)
|
||||
}
|
||||
|
||||
func TestSubscriptionTestSuite(t *testing.T) {
|
||||
suite.Run(t, new(SubscriptionsTestSuite))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -434,9 +434,10 @@ func (c *Converter) ASStatusToStatus(ctx context.Context, statusable ap.Statusab
|
|||
return nil, gtserror.SetMalformed(err)
|
||||
}
|
||||
|
||||
// Status was sent to us or dereffed
|
||||
// by us so it must be federated.
|
||||
// Status was sent to us or dereffed by
|
||||
// us so it must be federated and not local.
|
||||
status.Federated = util.Ptr(true)
|
||||
status.Local = util.Ptr(false)
|
||||
|
||||
// Derive interaction policy for this status.
|
||||
status.InteractionPolicy = ap.ExtractInteractionPolicy(
|
||||
|
|
@ -446,9 +447,11 @@ func (c *Converter) ASStatusToStatus(ctx context.Context, statusable ap.Statusab
|
|||
|
||||
// Set approvedByURI if present,
|
||||
// for later dereferencing.
|
||||
approvedByURI := ap.GetApprovedBy(statusable)
|
||||
if approvedByURI != nil {
|
||||
status.ApprovedByURI = approvedByURI.String()
|
||||
if ipa, ok := statusable.(ap.InteractionPolicyAware); ok {
|
||||
approvedByURI := ap.GetApprovedBy(ipa)
|
||||
if approvedByURI != nil {
|
||||
status.ApprovedByURI = approvedByURI.String()
|
||||
}
|
||||
}
|
||||
|
||||
// Assume not pending approval; this may
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@ import (
|
|||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"testing"
|
||||
|
||||
|
|
@ -224,8 +223,7 @@ func (suite *ASToInternalTestSuite) TestParseOwncastService() {
|
|||
|
||||
b, err := json.Marshal(apiAcct)
|
||||
suite.NoError(err)
|
||||
|
||||
fmt.Printf("\n\n\n%s\n\n\n", string(b))
|
||||
suite.NotNil(b)
|
||||
}
|
||||
|
||||
func (suite *ASToInternalTestSuite) TestParseBookwyrmStatus() {
|
||||
|
|
@ -282,6 +280,65 @@ func (suite *ASToInternalTestSuite) TestParseBookwyrmStatus() {
|
|||
suite.Len(status.Attachments, 1)
|
||||
}
|
||||
|
||||
func (suite *ASToInternalTestSuite) TestParseBandwagonAlbum() {
|
||||
authorAccount := suite.testAccounts["remote_account_1"]
|
||||
|
||||
raw := `{
|
||||
"@context": [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
"https://w3id.org/security/v1",
|
||||
{
|
||||
"discoverable": "toot:discoverable",
|
||||
"indexable": "toot:indexable",
|
||||
"toot": "https://joinmastodon.org/ns#"
|
||||
},
|
||||
"https://funkwhale.audio/ns"
|
||||
],
|
||||
"artists": [
|
||||
{
|
||||
"id": "https://bandwagon.fm/@67a0a0808121f77ed3466870",
|
||||
"name": "Luka Prinčič",
|
||||
"type": "Artist"
|
||||
}
|
||||
],
|
||||
"attachment": [
|
||||
{
|
||||
"mediaType": "image/webp",
|
||||
"name": "image",
|
||||
"type": "Document",
|
||||
"url": "https://bandwagon.fm/67a0a219f050061c8b4ce427/attachments/67a0a21bf050061c8b4ce429"
|
||||
}
|
||||
],
|
||||
"attributedTo": "` + authorAccount.URI + `",
|
||||
"content": "... a transgenre mutation, a fluid entity, jagged pop, electro-funk, techno-cabaret, a schlager, and soft alternative, queer to the core, satire and tragedy, sharp and fun indulgence for the dance of bodies and brains, activism and hedonism, which would all like to steal your attention.\r\n\r\nDRAGX̶FUNK is pronounced /dɹæɡɑːfʌŋk/.\r\n\r\n---\r\n\r\n## Buy digital\r\n💳 [Stripe](https://buy.stripe.com/6oE8x52iG1Kq5pKeV3)\r\n\r\n---\r\n\r\n## Buy dl/merch\r\n🎵 [Bandcamp](https://lukaprincic.bandcamp.com/album/dragx-funk) \r\n\r\n---\r\n\r\n## More:\r\n🌐 [prin.lu](https://prin.lu/music/241205_dragx-funk/) \r\n👉 [kamizdat.si](https://kamizdat.si/releases/dragx-funk-2/)\r\n",
|
||||
"context": "https://bandwagon.fm/67a0a219f050061c8b4ce427",
|
||||
"id": "https://bandwagon.fm/67a0a219f050061c8b4ce427",
|
||||
"library": "https://bandwagon.fm/67a0a219f050061c8b4ce427/pub/children",
|
||||
"license": "CC-BY-NC-SA",
|
||||
"name": "DRAGX̶FUNK",
|
||||
"published": "2025-03-17T11:40:53Z",
|
||||
"to": [
|
||||
"https://www.w3.org/ns/activitystreams#Public"
|
||||
],
|
||||
"tracks": "https://bandwagon.fm/67a0a219f050061c8b4ce427/pub/children",
|
||||
"type": "Album",
|
||||
"url": "https://bandwagon.fm/67a0a219f050061c8b4ce427"
|
||||
}`
|
||||
|
||||
t := suite.jsonToType(raw)
|
||||
asArticle, ok := t.(ap.Statusable)
|
||||
if !ok {
|
||||
suite.FailNow("type not coercible")
|
||||
}
|
||||
|
||||
s, err := suite.typeconverter.ASStatusToStatus(context.Background(), asArticle)
|
||||
if err != nil {
|
||||
suite.FailNow(err.Error())
|
||||
}
|
||||
suite.NotNil(s)
|
||||
suite.NoError(err)
|
||||
}
|
||||
|
||||
func (suite *ASToInternalTestSuite) TestParseFlag1() {
|
||||
reportedAccount := suite.testAccounts["local_account_1"]
|
||||
reportingAccount := suite.testAccounts["remote_account_1"]
|
||||
|
|
|
|||
|
|
@ -705,35 +705,38 @@ func (c *Converter) StatusToAS(ctx context.Context, s *gtsmodel.Status) (ap.Stat
|
|||
status.SetActivityStreamsSensitive(sensitiveProp)
|
||||
|
||||
// interactionPolicy
|
||||
var p *gtsmodel.InteractionPolicy
|
||||
if s.InteractionPolicy != nil {
|
||||
// Use InteractionPolicy
|
||||
// set on the status.
|
||||
p = s.InteractionPolicy
|
||||
} else {
|
||||
// Fall back to default policy
|
||||
// for the status's visibility.
|
||||
p = gtsmodel.DefaultInteractionPolicyFor(s.Visibility)
|
||||
}
|
||||
policy, err := c.InteractionPolicyToASInteractionPolicy(ctx, p, s)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error creating interactionPolicy: %w", err)
|
||||
}
|
||||
|
||||
policyProp := streams.NewGoToSocialInteractionPolicyProperty()
|
||||
policyProp.AppendGoToSocialInteractionPolicy(policy)
|
||||
status.SetGoToSocialInteractionPolicy(policyProp)
|
||||
|
||||
// Parse + set approvedBy.
|
||||
if s.ApprovedByURI != "" {
|
||||
approvedBy, err := url.Parse(s.ApprovedByURI)
|
||||
if ipa, ok := status.(ap.InteractionPolicyAware); ok {
|
||||
var p *gtsmodel.InteractionPolicy
|
||||
if s.InteractionPolicy != nil {
|
||||
// Use InteractionPolicy
|
||||
// set on the status.
|
||||
p = s.InteractionPolicy
|
||||
} else {
|
||||
// Fall back to default policy
|
||||
// for the status's visibility.
|
||||
p = gtsmodel.DefaultInteractionPolicyFor(s.Visibility)
|
||||
}
|
||||
policy, err := c.InteractionPolicyToASInteractionPolicy(ctx, p, s)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error parsing approvedBy: %w", err)
|
||||
return nil, fmt.Errorf("error creating interactionPolicy: %w", err)
|
||||
}
|
||||
|
||||
approvedByProp := streams.NewGoToSocialApprovedByProperty()
|
||||
approvedByProp.Set(approvedBy)
|
||||
status.SetGoToSocialApprovedBy(approvedByProp)
|
||||
// Set interaction policy.
|
||||
policyProp := streams.NewGoToSocialInteractionPolicyProperty()
|
||||
policyProp.AppendGoToSocialInteractionPolicy(policy)
|
||||
ipa.SetGoToSocialInteractionPolicy(policyProp)
|
||||
|
||||
// Parse + set approvedBy.
|
||||
if s.ApprovedByURI != "" {
|
||||
approvedBy, err := url.Parse(s.ApprovedByURI)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error parsing approvedBy: %w", err)
|
||||
}
|
||||
|
||||
approvedByProp := streams.NewGoToSocialApprovedByProperty()
|
||||
approvedByProp.Set(approvedBy)
|
||||
ipa.SetGoToSocialApprovedBy(approvedByProp)
|
||||
}
|
||||
}
|
||||
|
||||
return status, nil
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue