generic AP and honk progress

This commit is contained in:
Iris Lightshard 2024-11-29 12:00:54 -07:00
parent 3d99b53935
commit 194a5aed48
Signed by: Iris Lightshard
GPG key ID: 688407174966CAF3
2 changed files with 91 additions and 8 deletions

View file

@ -6,6 +6,7 @@ import (
"io" "io"
"net/http" "net/http"
"os" "os"
"strings"
"time" "time"
"forge.lightcrystal.systems/lightcrystal/underbbs/models" "forge.lightcrystal.systems/lightcrystal/underbbs/models"
@ -15,6 +16,8 @@ type anonAPAdapter struct {
data *chan models.SocketData data *chan models.SocketData
server string server string
client http.Client client http.Client
protocol string
nickname string
} }
type apLink struct { type apLink struct {
@ -23,6 +26,20 @@ type apLink struct {
Type string Type string
} }
type apAttachment struct {
MediaType string
Type string
Name string
Summary string
Url string
}
type apTag struct {
Href string
Name string
Type string
}
type apIcon struct { type apIcon struct {
MediaType string MediaType string
Type string Type string
@ -38,13 +55,31 @@ type apActor struct {
Url string Url string
} }
type apActivity struct {
Id string
Content string
AttributedTo string
Context string
Conversation string
Published string
Tag []apTag
Attachment []apAttachment
To string
Url string
Actor *string
Object *string
InReplyTo *string
}
type webFinger struct { type webFinger struct {
Links []apLink Links []apLink
} }
func (self *anonAPAdapter) Init(data *chan models.SocketData, server string) error { func (self *anonAPAdapter) Init(data *chan models.SocketData, server, protocol, nickname string) error {
self.data = data self.data = data
self.server = server self.server = server
self.nickname = nickname
self.protocol = protocol
return nil return nil
} }
@ -65,8 +100,39 @@ func (self *anonAPAdapter) makeApRequest(method, url string, data io.Reader) (*h
return self.client.Do(req) return self.client.Do(req)
} }
func toMsg(activity map[string]interface{}) *models.Message { func (self *anonAPAdapter) toMsg(activity apActivity) *models.Message {
return nil t, err := time.Parse(time.RFC3339, activity.Published)
if err != nil {
t = time.Now()
}
vis := strings.Split(activity.To, "#")
if len(vis) > 1 {
activity.To = vis[1]
}
m := &models.Message{
Datagram: models.Datagram{
Id: activity.Id,
Uri: activity.Url,
Type: "message",
Created: t.UnixMilli(),
Updated: nil,
Protocol: self.protocol,
Adapter: self.nickname,
},
Author: activity.AttributedTo,
Content: activity.Content,
ReplyTo: activity.InReplyTo,
Visibility: activity.To,
}
for _, a := range activity.Attachment {
m.Attachments = append(m.Attachments, models.Attachment{
Src: a.Url,
Desc: a.Summary,
})
}
return m
} }
func (self *anonAPAdapter) send(data models.SocketData) { func (self *anonAPAdapter) send(data models.SocketData) {
@ -77,21 +143,23 @@ func (self *anonAPAdapter) send(data models.SocketData) {
} }
} }
func toAuthor(actor apActor) *models.Author { func (self *anonAPAdapter) toAuthor(actor apActor) *models.Author {
curtime := time.Now().UnixMilli() curtime := time.Now().UnixMilli()
self := &models.Author{ a := &models.Author{
Datagram: models.Datagram{ Datagram: models.Datagram{
Id: actor.Id, Id: actor.Id,
Uri: actor.Url, Uri: actor.Url,
Type: "author", Type: "author",
Created: curtime, Created: curtime,
Updated: &curtime, Updated: &curtime,
Protocol: self.protocol,
Adapter: self.nickname,
}, },
Name: actor.PreferredUsername, Name: actor.PreferredUsername,
ProfileData: actor.Summary, ProfileData: actor.Summary,
ProfilePic: actor.Icon.Url, ProfilePic: actor.Icon.Url,
} }
return self return a
} }
func (self *anonAPAdapter) Fetch(etype string, ids []string) error { func (self *anonAPAdapter) Fetch(etype string, ids []string) error {
@ -122,12 +190,27 @@ func (self *anonAPAdapter) Fetch(etype string, ids []string) error {
authorData := getBodyJson(res) authorData := getBodyJson(res)
actor := apActor{} actor := apActor{}
json.Unmarshal(authorData, &actor) json.Unmarshal(authorData, &actor)
author := toAuthor(actor) author := self.toAuthor(actor)
if author != nil { if author != nil {
self.send(author) self.send(author)
} }
case "byAuthor": case "byAuthor":
// get outbox
// for each item in outbox, check if it's a Create/Update or an Announce
// Create/Update you can directly deserialize the object
// if it's an Announce, try to get the object and deserialize it, build a boost out of it
case "message": case "message":
res, err := self.makeApRequest("GET", id, nil)
if err != nil {
return err
}
activityData := getBodyJson(res)
activity := apActivity{}
json.Unmarshal(activityData, &activity)
message := self.toMsg(activity)
if message != nil {
self.send(message)
}
case "children": case "children":
case "convoy": case "convoy":
default: default:

View file

@ -78,7 +78,7 @@ func (self *HonkAdapter) Fetch(etype string, ids []string) error {
// KISS // KISS
if self.isAnonymous() { if self.isAnonymous() {
aaa := anonAPAdapter{} aaa := anonAPAdapter{}
aaa.Init(self.data, self.server) aaa.Init(self.data, self.server, "honk", self.nickname)
return aaa.Fetch(etype, ids) return aaa.Fetch(etype, ids)
} }