package pana import ( "encoding/json" "iter" ld "sourcery.dny.nu/longdistance" "sourcery.dny.nu/pana/vocab/ostatus" as "sourcery.dny.nu/pana/vocab/w3/activitystreams" ) // Object is the ActivityStreams Object type. type Object ld.Node // NewObject initialises a new Object. func NewObject() *Object { return &Object{ Properties: make(ld.Properties), Type: []string{as.TypeObject}, } } // Build finalises the Object. // // This returns [Any] since that's what [Activity.SetObject] expects. func (o *Object) Build() Any { return Any(*o) } // GetID returns the object ID from [ld.Node.ID]. // // This is equivalent to the 'id' property in compacted form JSON or the '@id' // property in expanded form. // // If an object doesn't have an ID but does have other properties it is an // anonymous object (a blank node). This represents something that exists but is // not named or referencable. func (o *Object) GetID() string { return o.ID } // SetID sets the object ID in [ld.Node.ID]. func (o *Object) SetID(id string) *Object { o.ID = id return o } // GetType returns the first type from [ld.Node.Type]. // // This is equivalent to the 'type' property in compacted form JSON or the // '@type' property in expanded form. // // It will return the empty string if the object has no type. // // An object can have multiple types, but this is so uncommon on the fediverse // that this method only returns the first type. You can check the size of // [ld.Node.Type] if you'd like. func (o *Object) GetType() string { if o.Type == nil { return "" } return o.Type[0] } // SetType sets the type in [ld.Node.Type]. func (o *Object) SetType(t string) *Object { o.Type = []string{t} return o } // GetCc returns the audience IDs from [as.Cc]. // // See https://www.w3.org/TR/activitystreams-vocabulary/#dfn-cc. func (o *Object) GetCc() iter.Seq[string] { return func(yield func(string) bool) { for _, n := range (*ld.Node)(o).GetNodes(as.Cc) { if !yield(n.ID) { return } } } } // AddCc appends audience IDs to [as.Cc]. func (o *Object) AddCc(ids ...string) *Object { (*ld.Node)(o).AddNodes(as.Cc, toReference(ids...)...) return o } // GetContent returns the localised values in [as.Content]. // // See https://www.w3.org/TR/activitystreams-vocabulary/#dfn-content. func (o *Object) GetContent() iter.Seq[*Localised] { return func(yield func(*Localised) bool) { for _, n := range (*ld.Node)(o).GetNodes(as.Content) { if !yield((*Localised)(&n)) { return } } } } // AddContent adds values to [as.Content]. func (o *Object) AddContent(ls ...Localised) *Object { (*ld.Node)(o).AddNodes(as.Content, toLDNodes(ls...)...) return o } // GetContext returns the ID in [as.Context]. // // This is not the JSON-LD [ld.KeywordContext]. // // See https://www.w3.org/TR/activitystreams-vocabulary/#dfn-context. func (o *Object) GetContext() string { if nodes := (*ld.Node)(o).GetNodes(as.Context); len(nodes) == 1 { return nodes[0].ID } return "" } // SetContext sets the ID in [as.Context]. func (o *Object) SetContext(id string) *Object { (*ld.Node)(o).SetNodes(as.Context, ld.Node{ID: id}) return o } // GetTo returns the audience IDs from [as.To]. // // See https://www.w3.org/TR/activitystreams-vocabulary/#dfn-to. func (o *Object) GetTo() iter.Seq[string] { return func(yield func(string) bool) { for _, n := range (*ld.Node)(o).GetNodes(as.To) { if !yield(n.ID) { return } } } } // AddTo appends audience IDs to [as.To]. func (o *Object) AddTo(ids ...string) *Object { (*ld.Node)(o).AddNodes(as.To, toReference(ids...)...) return o } // GetPublished retrieves the value from [as.Published]. // // See https://www.w3.org/TR/activitystreams-vocabulary/#dfn-published. func (o *Object) GetPublished() json.RawMessage { if nodes := (*ld.Node)(o).GetNodes(as.Published); len(nodes) == 1 { return nodes[0].Value } return nil } // SetPublished sets the value in [as.Published]. func (o *Object) SetPublished(value json.RawMessage) *Object { (*ld.Node)(o).SetNodes(as.Published, ld.Node{Value: value}) return o } // GetAttributedTo returns the actor IDs from [as.AttributedTo]. // // See https://www.w3.org/TR/activitystreams-vocabulary/#dfn-attributedto. func (o *Object) GetAttributedTo() iter.Seq[string] { return func(yield func(string) bool) { for _, n := range (*ld.Node)(o).GetNodes(as.AttributedTo) { if !yield(n.ID) { return } } } } // AddAttributedTo appends actor IDs to [as.AttributedTo]. func (o *Object) AddAttributedTo(ids ...string) *Object { (*ld.Node)(o).AddNodes(as.To, toReference(ids...)...) return o } // GetReplies returns the [Collection] stored in [as.Replies]. // // See https://www.w3.org/TR/activitystreams-vocabulary/#dfn-replies. func (o *Object) GetReplies() *Collection { if nodes := (*ld.Node)(o).GetNodes(as.Replies); len(nodes) == 1 { return (*Collection)(&nodes[0]) } return nil } // SetReplies sets the [Collection] in [as.Replies]. func (o *Object) SetReplies(c Collection) *Object { (*ld.Node)(o).SetNodes(as.Replies, ld.Node(c)) return o } // GetURL returns the URL in [as.URL]. // // See https://www.w3.org/TR/activitystreams-vocabulary/#dfn-url. func (o *Object) GetURL() string { if nodes := (*ld.Node)(o).GetNodes(as.URL); len(nodes) == 1 { return nodes[0].ID } return "" } // SetURL sets the URL in [as.URL]. func (o *Object) SetURL(url string) *Object { (*ld.Node)(o).SetNodes(as.URL, toReference(url)...) return o } // GetConversation returns the URI in [ostatus.Conversation]. // // This is a [tag URI]. // // [tag URI]: https://datatracker.ietf.org/doc/html/rfc4151 func (o *Object) GetConversation() string { if nodes := (*ld.Node)(o).GetNodes(ostatus.Conversation); len(nodes) == 1 { return nodes[0].ID } return "" } // SetConversation sets the URI in [ostatus.Conversation]. func (o *Object) SetConversation(uri string) *Object { (*ld.Node)(o).SetNodes(ostatus.Conversation, ld.Node{ID: uri}) return o } // GetAtomUri returns the URI in [ostatus.AtomURI]. // // [tag URI]: https://datatracker.ietf.org/doc/html/rfc4151 func (o *Object) GetAtomURI() string { if nodes := (*ld.Node)(o).GetNodes(ostatus.AtomURI); len(nodes) == 1 { return nodes[0].ID } return "" } // SetAtomUri sets the URI in [ostatus.AtomURI]. func (o *Object) SetAtomURI(uri string) *Object { (*ld.Node)(o).SetNodes(ostatus.AtomURI, ld.Node{ID: uri}) return o } // GetSummary returns the localised values in [as.Summary]. // // See https://www.w3.org/TR/activitystreams-vocabulary/#dfn-summary. func (o *Object) GetSummary() iter.Seq[*Localised] { return func(yield func(*Localised) bool) { for _, n := range (*ld.Node)(o).GetNodes(as.Summary) { if !yield((*Localised)(&n)) { return } } } } // AddSummary adds values to [as.Summary]. func (o *Object) AddSummary(ls ...Localised) *Object { (*ld.Node)(o).AddNodes(as.Summary, toLDNodes(ls...)...) return o } // GetTag returns the values in [as.Tag]. // // This returns Any because it can be an Emoji, a Hashtag, combinations of the // two or more. // // See https://www.w3.org/TR/activitystreams-vocabulary/#dfn-tag. func (o *Object) GetTag() iter.Seq[*Any] { return func(yield func(*Any) bool) { for _, n := range (*ld.Node)(o).GetNodes(as.Tag) { if !yield((*Any)(&n)) { return } } } } // AddTag appends a tag to [as.Tag]. func (o *Object) AddTag(tag ...Any) *Object { (*ld.Node)(o).AddNodes(as.Tag, toLDNodes(tag...)...) return o } // GetInReplyTo returns the URL in [as.InReplyTo]. // // See https://www.w3.org/TR/activitystreams-vocabulary/#dfn-inreplyto. func (o *Object) GetInReplyTo() string { if nodes := (*ld.Node)(o).GetNodes(as.InReplyTo); len(nodes) == 1 { return nodes[0].ID } return "" } // SetInReplyTo sets the URL in [as.InReplyTo]. func (o *Object) SetInReplyTo(url string) *Object { (*ld.Node)(o).SetNodes(as.InReplyTo, ld.Node{ID: url}) return o } // GetAttachment returns the attachments in [as.Attachment]. // // This returns [Any] because is can be a Document, PropertyValue, a combination // of both and more. // // See https://www.w3.org/TR/activitystreams-vocabulary/#dfn-attachment. func (o *Object) GetAttachment() iter.Seq[*Any] { return func(yield func(*Any) bool) { for _, n := range (*ld.Node)(o).GetNodes(as.Attachment) { if !yield((*Any)(&n)) { return } } } } // AddAttachment appends attachments to [as.Attachment]. func (o *Object) AddAttachment(atch ...Any) *Object { (*ld.Node)(o).AddNodes(as.Attachment, toLDNodes(atch...)...) return o } // GetSensitive returns the value from [as.Sensitive]. // // See https://swicg.github.io/miscellany/#sensitive. func (o *Object) GetSensitive() json.RawMessage { if nodes := (*ld.Node)(o).GetNodes(as.Sensitive); len(nodes) == 1 { return nodes[0].Value } return nil } // SetSensitive sets the value in [as.Sensitive]. func (o *Object) SetSensitive(v json.RawMessage) *Object { (*ld.Node)(o).SetNodes(as.Sensitive, ld.Node{Value: v}) return o } // GetInReplyToAtomURI returns the URI in [ostatus.InReplyToAtomUri]. func (o *Object) GetInReplyToAtomURI() string { if nodes := (*ld.Node)(o).GetNodes(ostatus.InReplyToAtomURI); len(nodes) == 1 { return nodes[0].ID } return "" } // SetInReplyToAtomURI sets the URI in [ostatus.InReplyToAtomUri]. func (o *Object) SetInReplyToAtomURI(uri string) *Object { (*ld.Node)(o).SetNodes(ostatus.InReplyToAtomURI, ld.Node{ID: uri}) return o } // GetUpdated returns the value in [as.Updated]. // // See https://www.w3.org/TR/activitystreams-vocabulary/#dfn-endtime. func (o *Object) GetUpdated() json.RawMessage { if nodes := (*ld.Node)(o).GetNodes(as.Updated); len(nodes) == 1 { return nodes[0].Value } return nil } // SetUpdated sets the value in [as.Updated]. func (o *Object) SetUpdated(v json.RawMessage) *Object { (*ld.Node)(o).SetNodes(as.Updated, ld.Node{Value: v}) return o } // GetName returns the localised values in [as.Name]. func (o *Object) GetName() iter.Seq[*Localised] { return func(yield func(*Localised) bool) { for _, n := range (*ld.Node)(o).GetNodes(as.Name) { if !yield((*Localised)(&n)) { return } } } } // AddName appends localised values to [as.Name]. func (o *Object) AddName(ls ...Localised) *Object { (*ld.Node)(o).AddNodes(as.Name, toLDNodes(ls...)...) return o } // GetLikes returns the [Collection] stored in [as.Likes]. // // See https://www.w3.org/TR/activitypub/#likes. func (o *Object) GetLikes() *Collection { if nodes := (*ld.Node)(o).GetNodes(as.Likes); len(nodes) == 1 { return (*Collection)(&nodes[0]) } return nil } // SetLikes sets the [Collection] in [as.Likes]. func (o *Object) SetLikes(c Collection) *Object { (*ld.Node)(o).SetNodes(as.Likes, ld.Node(c)) return o } // GetShares returns the [Collection] stored in [as.Shares]. // // See https://www.w3.org/TR/activitypub/#shares. func (o *Object) GetShares() *Collection { if nodes := (*ld.Node)(o).GetNodes(as.Shares); len(nodes) == 1 { return (*Collection)(&nodes[0]) } return nil } // SetShares sets the [Collection] in [as.Shares]. func (o *Object) SetShares(c Collection) *Object { (*ld.Node)(o).SetNodes(as.Shares, ld.Node(c)) return o }