diff options
author | Julio Capote <jcapote@gmail.com> | 2023-01-02 02:57:23 +0000 |
---|---|---|
committer | Julio Capote <jcapote@gmail.com> | 2023-01-02 02:57:23 +0000 |
commit | 2148666991eb98fa6935f4f36fc29cf1e704f834 (patch) | |
tree | df9ef2db74685543d7458650b69ce89db14ae51a | |
parent | 5efad50005484e4bcd56fd68a46040e3d89b0efe (diff) | |
download | communique-2148666991eb98fa6935f4f36fc29cf1e704f834.tar.gz |
followers and following endpoints
-rw-r--r-- | http/router.go | 26 | ||||
-rw-r--r-- | registry/registry.go | 50 | ||||
-rw-r--r-- | urls/urls.go | 12 | ||||
-rw-r--r-- | views/outbox.go | 8 | ||||
-rw-r--r-- | views/profile.go | 61 |
5 files changed, 140 insertions, 17 deletions
diff --git a/http/router.go b/http/router.go index 04fa583..9730dbf 100644 --- a/http/router.go +++ b/http/router.go @@ -47,6 +47,28 @@ func (s *Router) Start(zapWriter io.Writer) { }) + router.GET("/actors/:actor/followers", func(c *gin.Context) { + actorParam := c.Param("actor") + resource, _ := s.registry.Followers(actorParam) + if resource != nil { + c.Writer.Header().Set("Content-Type", "application/activity+json") + c.JSON(http.StatusOK, resource) + } else { + c.JSON(http.StatusNotFound, nil) + } + }) + + router.GET("/actors/:actor/following", func(c *gin.Context) { + actorParam := c.Param("actor") + resource, _ := s.registry.Following(actorParam) + if resource != nil { + c.Writer.Header().Set("Content-Type", "application/activity+json") + c.JSON(http.StatusOK, resource) + } else { + c.JSON(http.StatusNotFound, nil) + } + }) + // // Inbox // router.POST("/actors/:actor/inbox", func(c *gin.Context) { // actorParam := c.Param("actor") @@ -81,7 +103,7 @@ func (s *Router) Start(zapWriter io.Writer) { actorParam := c.Param("actor") idParam := c.Param("id") var resource map[string]interface{} - resource, _ = s.registry.Activity(actorParam, idParam) + resource, _ = s.registry.ActivityOrNote("activity", actorParam, idParam) if resource != nil { c.Writer.Header().Set("Content-Type", "application/activity+json") @@ -96,7 +118,7 @@ func (s *Router) Start(zapWriter io.Writer) { actorParam := c.Param("actor") idParam := c.Param("id") var resource map[string]interface{} - resource, _ = s.registry.Note(actorParam, idParam) + resource, _ = s.registry.ActivityOrNote("note", actorParam, idParam) if resource != nil { c.Writer.Header().Set("Content-Type", "application/activity+json") diff --git a/registry/registry.go b/registry/registry.go index 13f2889..0a5df77 100644 --- a/registry/registry.go +++ b/registry/registry.go @@ -7,6 +7,7 @@ import ( "git.capotej.com/capotej/communique/config" "git.capotej.com/capotej/communique/models" + "git.capotej.com/capotej/communique/urls" "git.capotej.com/capotej/communique/views" ) @@ -62,7 +63,7 @@ func (r *Registry) OutboxCollection(name string) (map[string]interface{}, error) return nil, err } var outboxItems []models.OutboxItem - for _, v := range page { + for _, v := range page[0:20] { //TODO pagination buf := bytes.NewBuffer(v) dec := gob.NewDecoder(buf) var outboxItem models.OutboxItem @@ -74,29 +75,53 @@ func (r *Registry) OutboxCollection(name string) (map[string]interface{}, error) } return views.RenderOutboxCollection(handler.handlerCfg.Name, r.cfg.Domain, outboxItems) } +func (r *Registry) Following(name string) (map[string]interface{}, error) { + handler := r.findByName(name) + if handler == nil { + return nil, nil + } + profile, err := urls.UrlProfile(name, r.cfg.Domain) + if err != nil { + return nil, err + } + following, err := urls.UrlFollowing(name, r.cfg.Domain) + if err != nil { + return nil, err + } + result := make(map[string]interface{}) + result["@context"] = "https://www.w3.org/ns/activitystreams" + result["attributedTo"] = profile.String() + result["id"] = following.String() + result["totalItems"] = 0 + result["orderedItems"] = []bool{} + result["type"] = "OrderedCollection" + return result, nil +} -func (r *Registry) Activity(name, id string) (map[string]interface{}, error) { +func (r *Registry) Followers(name string) (map[string]interface{}, error) { handler := r.findByName(name) if handler == nil { return nil, nil } - lookup := models.NewOutboxItem(handler.handlerCfg) - lookup.Id = []byte(id) - result, err := r.persister.Find(lookup) + profile, err := urls.UrlProfile(name, r.cfg.Domain) if err != nil { return nil, err } - buf := bytes.NewBuffer(result) - dec := gob.NewDecoder(buf) - var outboxItem models.OutboxItem - err = dec.Decode(&outboxItem) + followers, err := urls.UrlFollowers(name, r.cfg.Domain) if err != nil { return nil, err } - return views.RenderActivity(handler.handlerCfg.Name, r.cfg.Domain, outboxItem) + result := make(map[string]interface{}) + result["@context"] = "https://www.w3.org/ns/activitystreams" + result["attributedTo"] = profile.String() + result["id"] = followers.String() + result["totalItems"] = 0 + result["orderedItems"] = []bool{} + result["type"] = "OrderedCollection" + return result, nil } -func (r *Registry) Note(name, id string) (map[string]interface{}, error) { +func (r *Registry) ActivityOrNote(activityOrNote, name, id string) (map[string]interface{}, error) { handler := r.findByName(name) if handler == nil { return nil, nil @@ -114,6 +139,9 @@ func (r *Registry) Note(name, id string) (map[string]interface{}, error) { if err != nil { return nil, err } + if activityOrNote == "activity" { + return views.RenderActivity(handler.handlerCfg.Name, r.cfg.Domain, outboxItem) + } return views.RenderNote(handler.handlerCfg.Name, r.cfg.Domain, outboxItem) } diff --git a/urls/urls.go b/urls/urls.go index 6a2025b..65aa042 100644 --- a/urls/urls.go +++ b/urls/urls.go @@ -25,6 +25,18 @@ func UrlOutbox(name, domain string) (*url.URL, error) { return linkTo("outbox", domain, "actors", name, "outbox") } +func UrlProfile(name, domain string) (*url.URL, error) { + return linkTo("outbox", domain, "actors", name) +} + +func UrlFollowers(name, domain string) (*url.URL, error) { + return linkTo("outbox", domain, "actors", name, "followers") +} + +func UrlFollowing(name, domain string) (*url.URL, error) { + return linkTo("outbox", domain, "actors", name, "following") +} + func UrlActivity(name, domain, id string) (*url.URL, error) { return linkTo("activity", domain, "actors", name, "activity", id) } diff --git a/views/outbox.go b/views/outbox.go index ee28842..8aef906 100644 --- a/views/outbox.go +++ b/views/outbox.go @@ -57,6 +57,14 @@ func RenderOutboxCollection(name, domain string, page []models.OutboxItem) (map[ crea.SetActivityStreamsTo(toProp) crea.SetActivityStreamsPublished(publishedProp) + actorUrl, err := urls.UrlProfile(name, domain) + if err != nil { + return nil, err + } + actorProp := streams.NewActivityStreamsActorProperty() + actorProp.AppendIRI(actorUrl) + crea.SetActivityStreamsActor(actorProp) + noteUrl, err := urls.UrlNote(name, domain, string(v.Id)) if err != nil { return nil, err diff --git a/views/profile.go b/views/profile.go index 12aae54..5b82b46 100644 --- a/views/profile.go +++ b/views/profile.go @@ -1,21 +1,74 @@ package views import ( + "fmt" + "git.capotej.com/capotej/communique/urls" "github.com/go-fed/activity/streams" ) func RenderProfile(name, domain string) (map[string]interface{}, error) { - u, err := urls.UrlInbox(name, domain) + inbox, err := urls.UrlInbox(name, domain) + if err != nil { + return nil, err + } + + inboxProp := streams.NewActivityStreamsInboxProperty() + inboxProp.SetIRI(inbox) + + outbox, err := urls.UrlOutbox(name, domain) + if err != nil { + return nil, err + } + + outboxProp := streams.NewActivityStreamsOutboxProperty() + outboxProp.SetIRI(outbox) + + actorUrl, err := urls.UrlProfile(name, domain) + if err != nil { + return nil, err + } + + followingUrl, err := urls.UrlFollowing(name, domain) if err != nil { return nil, err } - inb := streams.NewActivityStreamsInboxProperty() - inb.SetIRI(u) + followersUrl, err := urls.UrlFollowers(name, domain) + if err != nil { + return nil, err + } p := streams.NewActivityStreamsService() - p.SetActivityStreamsInbox(inb) + idProp := streams.NewJSONLDIdProperty() + idProp.Set(actorUrl) + p.SetJSONLDId(idProp) + p.SetActivityStreamsInbox(inboxProp) + p.SetActivityStreamsOutbox(outboxProp) + + nameProp := streams.NewActivityStreamsNameProperty() + nameProp.AppendXMLSchemaString(name) + p.SetActivityStreamsName(nameProp) + + usernameProp := streams.NewActivityStreamsPreferredUsernameProperty() + usernameProp.SetXMLSchemaString(name) + p.SetActivityStreamsPreferredUsername(usernameProp) + + urlProp := streams.NewActivityStreamsUrlProperty() + urlProp.AppendIRI(actorUrl) + p.SetActivityStreamsUrl(urlProp) + + summaryProp := streams.NewActivityStreamsSummaryProperty() + summaryProp.AppendXMLSchemaString(fmt.Sprintf("profile for %s", name)) + p.SetActivityStreamsSummary(summaryProp) + + followersProp := streams.NewActivityStreamsFollowersProperty() + followersProp.SetIRI(followersUrl) + p.SetActivityStreamsFollowers(followersProp) + + followingProp := streams.NewActivityStreamsFollowingProperty() + followingProp.SetIRI(followingUrl) + p.SetActivityStreamsFollowing(followingProp) return streams.Serialize(p) } |