Federated via graft
0

Configure Feed

Select the types of activity you want to include in your feed.

1package activitypub 2 3import ( 4 "strconv" 5 "time" 6 7 "graft/internal/state" 8) 9 10// OrderedCollection wraps a series' outbox: every mirrored event as a 11// Create{Note} activity, newest first. 12type OrderedCollection struct { 13 Context string `json:"@context"` 14 ID string `json:"id"` 15 Type string `json:"type"` 16 TotalItems int `json:"totalItems"` 17 OrderedItems []Create `json:"orderedItems"` 18} 19 20type Create struct { 21 Context string `json:"@context,omitempty"` 22 ID string `json:"id"` 23 Type string `json:"type"` 24 Actor string `json:"actor"` 25 Published string `json:"published"` 26 To []string `json:"to,omitempty"` 27 Object Note `json:"object"` 28} 29 30// Note is one mirrored event, addressable on its own 31// (/actors/{series}/notes/{id}) so a reply's inReplyTo can point back at 32// the specific commit/issue/patch it's about. 33type Note struct { 34 Context string `json:"@context,omitempty"` 35 ID string `json:"id"` 36 Type string `json:"type"` 37 AttributedTo string `json:"attributedTo"` 38 Content string `json:"content"` 39 URL string `json:"url,omitempty"` 40 Published string `json:"published"` 41 To []string `json:"to,omitempty"` 42} 43 44const publicAudience = "https://www.w3.org/ns/activitystreams#Public" 45 46// NoteURI returns the stable object URI for one activity_log entry's Note. 47func NoteURI(host, series string, entryID int64) string { 48 return ActorURI(host, series) + "/notes/" + strconv.FormatInt(entryID, 10) 49} 50 51// BuildNote turns one mirrored event into its Note representation. 52func BuildNote(host, series string, e state.ActivityEntry) Note { 53 actor := ActorURI(host, series) 54 content := kindLabel(e.Kind) + ": " + e.Summary 55 return Note{ 56 ID: NoteURI(host, series, e.ID), 57 Type: "Note", 58 AttributedTo: actor, 59 Content: content, 60 URL: e.URL, 61 Published: e.OccurredAt.Format(time.RFC3339), 62 To: []string{publicAudience}, 63 } 64} 65 66// BuildOutbox wraps a series' recent activity entries (newest first, as 67// returned by state.Store.ActivityForSeries) into an OrderedCollection of 68// Create activities. 69func BuildOutbox(host, series string, entries []state.ActivityEntry) OrderedCollection { 70 base := ActorURI(host, series) 71 actor := base 72 items := make([]Create, 0, len(entries)) 73 for _, e := range entries { 74 note := BuildNote(host, series, e) 75 items = append(items, Create{ 76 ID: note.ID + "/activity", 77 Type: "Create", 78 Actor: actor, 79 Published: note.Published, 80 To: []string{publicAudience}, 81 Object: note, 82 }) 83 } 84 return OrderedCollection{ 85 Context: "https://www.w3.org/ns/activitystreams", 86 ID: base + "/outbox", 87 Type: "OrderedCollection", 88 TotalItems: len(items), 89 OrderedItems: items, 90 } 91} 92 93func kindLabel(kind string) string { 94 switch kind { 95 case "git": 96 return "Commit" 97 case "issue": 98 return "Issue" 99 case "patch": 100 return "Patch" 101 default: 102 return kind 103 } 104}