basically finish anonAp adapter, it can fetch a user's profile, their outbox, or an individual note
This commit is contained in:
parent
194a5aed48
commit
a2017e3de8
1 changed files with 197 additions and 75 deletions
|
@ -13,9 +13,9 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type anonAPAdapter struct {
|
type anonAPAdapter struct {
|
||||||
data *chan models.SocketData
|
data *chan models.SocketData
|
||||||
server string
|
server string
|
||||||
client http.Client
|
client http.Client
|
||||||
protocol string
|
protocol string
|
||||||
nickname string
|
nickname string
|
||||||
}
|
}
|
||||||
|
@ -27,17 +27,17 @@ type apLink struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type apAttachment struct {
|
type apAttachment struct {
|
||||||
MediaType string
|
MediaType string
|
||||||
Type string
|
Type string
|
||||||
Name string
|
Name string
|
||||||
Summary string
|
Summary string
|
||||||
Url string
|
Url string
|
||||||
}
|
}
|
||||||
|
|
||||||
type apTag struct {
|
type apTag struct {
|
||||||
Href string
|
Href string
|
||||||
Name string
|
Name string
|
||||||
Type string
|
Type string
|
||||||
}
|
}
|
||||||
|
|
||||||
type apIcon struct {
|
type apIcon struct {
|
||||||
|
@ -55,20 +55,70 @@ type apActor struct {
|
||||||
Url string
|
Url string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type apOutbox struct {
|
||||||
|
OrderedItems []interface{} `json:"-"`
|
||||||
|
RawOrderedItems []json.RawMessage `json:"OrderedItems"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *apOutbox) UnmarshalJSON(b []byte) error {
|
||||||
|
type obInternal apOutbox
|
||||||
|
err := json.Unmarshal(b, (*obInternal)(self))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, raw := range self.RawOrderedItems {
|
||||||
|
var i apOutboxItem
|
||||||
|
err := json.Unmarshal(raw, &i)
|
||||||
|
|
||||||
|
var x interface{}
|
||||||
|
switch i.Type {
|
||||||
|
case "Create":
|
||||||
|
fallthrough
|
||||||
|
case "Update":
|
||||||
|
x = &apOutboxItemCreateUpdate{}
|
||||||
|
case "Announce":
|
||||||
|
x = &apOutboxItemAnnounce{}
|
||||||
|
}
|
||||||
|
err = json.Unmarshal(raw, &x)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
self.OrderedItems = append(self.OrderedItems, x)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type apOutboxItem struct {
|
||||||
|
Actor string
|
||||||
|
Id string
|
||||||
|
Type string
|
||||||
|
To string
|
||||||
|
Published string
|
||||||
|
}
|
||||||
|
|
||||||
|
type apOutboxItemCreateUpdate struct {
|
||||||
|
Object apActivity
|
||||||
|
apOutboxItem
|
||||||
|
}
|
||||||
|
|
||||||
|
type apOutboxItemAnnounce struct {
|
||||||
|
Object string
|
||||||
|
apOutboxItem
|
||||||
|
}
|
||||||
|
|
||||||
type apActivity struct {
|
type apActivity struct {
|
||||||
Id string
|
Id string
|
||||||
Content string
|
Content string
|
||||||
AttributedTo string
|
AttributedTo string
|
||||||
Context string
|
Context string
|
||||||
Conversation string
|
Conversation string
|
||||||
Published string
|
Published string
|
||||||
Tag []apTag
|
Tag []apTag
|
||||||
Attachment []apAttachment
|
Attachment []apAttachment
|
||||||
To string
|
To string
|
||||||
Url string
|
Url string
|
||||||
Actor *string
|
InReplyTo *string
|
||||||
Object *string
|
|
||||||
InReplyTo *string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type webFinger struct {
|
type webFinger struct {
|
||||||
|
@ -85,6 +135,10 @@ func (self *anonAPAdapter) Init(data *chan models.SocketData, server, protocol,
|
||||||
|
|
||||||
func getBodyJson(res *http.Response) []byte {
|
func getBodyJson(res *http.Response) []byte {
|
||||||
l := res.ContentLength
|
l := res.ContentLength
|
||||||
|
// 4k is a reasonable max size if we get unknown length right?
|
||||||
|
if l < 0 {
|
||||||
|
l = 4096
|
||||||
|
}
|
||||||
jsonData := make([]byte, l)
|
jsonData := make([]byte, l)
|
||||||
res.Body.Read(jsonData)
|
res.Body.Read(jsonData)
|
||||||
return jsonData
|
return jsonData
|
||||||
|
@ -101,36 +155,36 @@ func (self *anonAPAdapter) makeApRequest(method, url string, data io.Reader) (*h
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *anonAPAdapter) toMsg(activity apActivity) *models.Message {
|
func (self *anonAPAdapter) toMsg(activity apActivity) *models.Message {
|
||||||
t, err := time.Parse(time.RFC3339, activity.Published)
|
t, err := time.Parse(time.RFC3339, activity.Published)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t = time.Now()
|
t = time.Now()
|
||||||
}
|
}
|
||||||
vis := strings.Split(activity.To, "#")
|
vis := strings.Split(activity.To, "#")
|
||||||
if len(vis) > 1 {
|
if len(vis) > 1 {
|
||||||
activity.To = vis[1]
|
activity.To = vis[1]
|
||||||
}
|
}
|
||||||
m := &models.Message{
|
m := &models.Message{
|
||||||
Datagram: models.Datagram{
|
Datagram: models.Datagram{
|
||||||
Id: activity.Id,
|
Id: activity.Id,
|
||||||
Uri: activity.Url,
|
Uri: activity.Url,
|
||||||
Type: "message",
|
Type: "message",
|
||||||
Created: t.UnixMilli(),
|
Created: t.UnixMilli(),
|
||||||
Updated: nil,
|
Updated: nil,
|
||||||
Protocol: self.protocol,
|
Protocol: self.protocol,
|
||||||
Adapter: self.nickname,
|
Adapter: self.nickname,
|
||||||
},
|
},
|
||||||
Author: activity.AttributedTo,
|
Author: activity.AttributedTo,
|
||||||
Content: activity.Content,
|
Content: activity.Content,
|
||||||
ReplyTo: activity.InReplyTo,
|
ReplyTo: activity.InReplyTo,
|
||||||
Visibility: activity.To,
|
Visibility: activity.To,
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, a := range activity.Attachment {
|
for _, a := range activity.Attachment {
|
||||||
m.Attachments = append(m.Attachments, models.Attachment{
|
m.Attachments = append(m.Attachments, models.Attachment{
|
||||||
Src: a.Url,
|
Src: a.Url,
|
||||||
Desc: a.Summary,
|
Desc: a.Summary,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
|
@ -147,13 +201,13 @@ func (self *anonAPAdapter) toAuthor(actor apActor) *models.Author {
|
||||||
curtime := time.Now().UnixMilli()
|
curtime := time.Now().UnixMilli()
|
||||||
a := &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,
|
Protocol: self.protocol,
|
||||||
Adapter: self.nickname,
|
Adapter: self.nickname,
|
||||||
},
|
},
|
||||||
Name: actor.PreferredUsername,
|
Name: actor.PreferredUsername,
|
||||||
ProfileData: actor.Summary,
|
ProfileData: actor.Summary,
|
||||||
|
@ -195,22 +249,90 @@ func (self *anonAPAdapter) Fetch(etype string, ids []string) error {
|
||||||
self.send(author)
|
self.send(author)
|
||||||
}
|
}
|
||||||
case "byAuthor":
|
case "byAuthor":
|
||||||
// get outbox
|
// get outbox
|
||||||
// for each item in outbox, check if it's a Create/Update or an Announce
|
if string([]byte{id[0]}) == "@" {
|
||||||
// Create/Update you can directly deserialize the object
|
id = id[1:]
|
||||||
// if it's an Announce, try to get the object and deserialize it, build a boost out of it
|
}
|
||||||
|
res, err := http.Get(self.server + "/.well-known/webfinger?resource=acct:" + id)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
data := getBodyJson(res)
|
||||||
|
wf := webFinger{}
|
||||||
|
json.Unmarshal(data, &wf)
|
||||||
|
var profile string
|
||||||
|
for _, l := range wf.Links {
|
||||||
|
if l.Rel == "self" {
|
||||||
|
profile = l.Href
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
res, err = self.makeApRequest("GET", profile+"/outbox", nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
obData := getBodyJson(res)
|
||||||
|
ob := apOutbox{}
|
||||||
|
ob.UnmarshalJSON(obData)
|
||||||
|
for _, i := range ob.OrderedItems {
|
||||||
|
switch a := i.(type) {
|
||||||
|
case *apOutboxItemCreateUpdate:
|
||||||
|
msg := self.toMsg(a.Object)
|
||||||
|
if msg != nil {
|
||||||
|
self.send(msg)
|
||||||
|
}
|
||||||
|
case *apOutboxItemAnnounce:
|
||||||
|
res, err = self.makeApRequest("GET", a.Object, nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fmt.Println(a.Object)
|
||||||
|
activityData := getBodyJson(res)
|
||||||
|
activity := apActivity{}
|
||||||
|
json.Unmarshal(activityData, &activity)
|
||||||
|
ogMsg := self.toMsg(activity)
|
||||||
|
if ogMsg != nil {
|
||||||
|
self.send(ogMsg)
|
||||||
|
}
|
||||||
|
t, err := time.Parse(time.RFC3339, a.Published)
|
||||||
|
if err != nil {
|
||||||
|
t = time.Now()
|
||||||
|
}
|
||||||
|
vis := strings.Split(a.To, "#")
|
||||||
|
if len(vis) > 1 {
|
||||||
|
a.To = vis[1]
|
||||||
|
}
|
||||||
|
boostMsg := models.Message{
|
||||||
|
Datagram: models.Datagram{
|
||||||
|
Id: a.Id,
|
||||||
|
Uri: a.Id,
|
||||||
|
Protocol: self.protocol,
|
||||||
|
Adapter: self.nickname,
|
||||||
|
Type: "message",
|
||||||
|
Created: t.UnixMilli(),
|
||||||
|
},
|
||||||
|
Author: a.Actor,
|
||||||
|
RenoteId: &ogMsg.Id,
|
||||||
|
Visibility: a.To,
|
||||||
|
}
|
||||||
|
self.send(boostMsg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 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)
|
res, err := self.makeApRequest("GET", id, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
activityData := getBodyJson(res)
|
activityData := getBodyJson(res)
|
||||||
activity := apActivity{}
|
activity := apActivity{}
|
||||||
json.Unmarshal(activityData, &activity)
|
json.Unmarshal(activityData, &activity)
|
||||||
message := self.toMsg(activity)
|
message := self.toMsg(activity)
|
||||||
if message != nil {
|
if message != nil {
|
||||||
self.send(message)
|
self.send(message)
|
||||||
}
|
}
|
||||||
case "children":
|
case "children":
|
||||||
case "convoy":
|
case "convoy":
|
||||||
default:
|
default:
|
||||||
|
|
Loading…
Reference in a new issue