underbbs/adapter/anonAp.go

138 lines
2.7 KiB
Go

package adapter
import (
"encoding/json"
"fmt"
"io"
"net/http"
"os"
"time"
"forge.lightcrystal.systems/lightcrystal/underbbs/models"
)
type anonAPAdapter struct {
data *chan models.SocketData
server string
client http.Client
}
type apLink struct {
Href string
Rel string
Type string
}
type apIcon struct {
MediaType string
Type string
Url string
}
type apActor struct {
Icon apIcon
Id string
Name string
PreferredUsername string
Summary string
Url string
}
type webFinger struct {
Links []apLink
}
func (self *anonAPAdapter) Init(data *chan models.SocketData, server string) error {
self.data = data
self.server = server
return nil
}
func getBodyJson(res *http.Response) []byte {
l := res.ContentLength
jsonData := make([]byte, l)
res.Body.Read(jsonData)
return jsonData
}
func (self *anonAPAdapter) makeApRequest(method, url string, data io.Reader) (*http.Response, error) {
req, err := http.NewRequest(method, url, data)
if err != nil {
return nil, err
}
req.Header.Set("Accept", "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"")
return self.client.Do(req)
}
func toMsg(activity map[string]interface{}) *models.Message {
return nil
}
func (self *anonAPAdapter) send(data models.SocketData) {
if self.data != nil {
*self.data <- data
} else {
fmt.Fprintln(os.Stderr, string(data.ToDatagram()))
}
}
func toAuthor(actor apActor) *models.Author {
curtime := time.Now().UnixMilli()
self := &models.Author{
Datagram: models.Datagram{
Id: actor.Id,
Uri: actor.Url,
Type: "author",
Created: curtime,
Updated: &curtime,
},
Name: actor.PreferredUsername,
ProfileData: actor.Summary,
ProfilePic: actor.Icon.Url,
}
return self
}
func (self *anonAPAdapter) Fetch(etype string, ids []string) error {
for _, id := range ids {
switch etype {
case "author": // webfinger lookup on id
if string([]byte{id[0]}) == "@" {
id = id[1:]
}
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, nil)
if err != nil {
return err
}
authorData := getBodyJson(res)
actor := apActor{}
json.Unmarshal(authorData, &actor)
author := toAuthor(actor)
if author != nil {
self.send(author)
}
case "byAuthor":
case "message":
case "children":
case "convoy":
default:
break
}
}
return nil
}