HonkAdapter: subscribe!
This commit is contained in:
parent
a053406fc5
commit
b00f26b17d
3 changed files with 133 additions and 17 deletions
124
adapter/honk.go
124
adapter/honk.go
|
@ -1,15 +1,38 @@
|
||||||
package adapter
|
package adapter
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
. "forge.lightcrystal.systems/lightcrystal/underbbs/models"
|
. "forge.lightcrystal.systems/lightcrystal/underbbs/models"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type donk struct {
|
||||||
|
Desc string
|
||||||
|
URL string
|
||||||
|
}
|
||||||
|
|
||||||
|
type honk struct {
|
||||||
|
ID int
|
||||||
|
Honker string
|
||||||
|
Handles []string
|
||||||
|
Oonker *string
|
||||||
|
XID string
|
||||||
|
RID *string
|
||||||
|
Noise string
|
||||||
|
Donks []donk
|
||||||
|
Convoy string
|
||||||
|
Public bool
|
||||||
|
Date string
|
||||||
|
}
|
||||||
|
|
||||||
type HonkAdapter struct {
|
type HonkAdapter struct {
|
||||||
data *chan SocketData
|
data *chan SocketData
|
||||||
nickname string
|
nickname string
|
||||||
|
@ -17,6 +40,12 @@ type HonkAdapter struct {
|
||||||
username string
|
username string
|
||||||
password string
|
password string
|
||||||
token string
|
token string
|
||||||
|
|
||||||
|
cache map[string]time.Time
|
||||||
|
maxId int
|
||||||
|
mtx sync.RWMutex
|
||||||
|
|
||||||
|
stop chan bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *HonkAdapter) isAnonymous() bool {
|
func (self *HonkAdapter) isAnonymous() bool {
|
||||||
|
@ -48,8 +77,7 @@ func (self *HonkAdapter) Init(settings Settings, data *chan SocketData) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
self.password = *settings.Password
|
self.password = *settings.Password
|
||||||
// store all the settings
|
|
||||||
// make a request to get the token
|
|
||||||
r, err := http.PostForm(self.server+"/dologin", url.Values{
|
r, err := http.PostForm(self.server+"/dologin", url.Values{
|
||||||
"username": []string{self.username},
|
"username": []string{self.username},
|
||||||
"password": []string{self.password},
|
"password": []string{self.password},
|
||||||
|
@ -70,11 +98,99 @@ func (self *HonkAdapter) Init(settings Settings, data *chan SocketData) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *HonkAdapter) Subscribe(string) []error {
|
func (self *HonkAdapter) Subscribe(filter string) []error {
|
||||||
// similar to the misskey adapter, we will poll for new honks and send them on the channel as they come in
|
if self.stop != nil {
|
||||||
|
close(self.stop)
|
||||||
|
self.maxId = 0
|
||||||
|
}
|
||||||
|
self.stop = make(chan bool)
|
||||||
|
|
||||||
|
go self.gethonks(filter)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (self *HonkAdapter) gethonks(filter string) {
|
||||||
|
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case _, ok := <-self.stop:
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
honkForm := url.Values{
|
||||||
|
"action": []string{"gethonks"},
|
||||||
|
"token": []string{self.token},
|
||||||
|
"page": []string{filter},
|
||||||
|
}
|
||||||
|
if self.maxId != 0 {
|
||||||
|
honkForm["after"] = []string{strconv.FormatInt(int64(self.maxId), 10)}
|
||||||
|
}
|
||||||
|
res, err := http.PostForm(self.server+"/api", honkForm)
|
||||||
|
if err != nil {
|
||||||
|
// return?
|
||||||
|
}
|
||||||
|
honksData := getBodyJson(res)
|
||||||
|
honks := []honk{}
|
||||||
|
json.Unmarshal(honksData, &honks)
|
||||||
|
for _, h := range honks {
|
||||||
|
if h.ID > self.maxId {
|
||||||
|
self.maxId = h.ID
|
||||||
|
msg := self.toMsg(h)
|
||||||
|
self.send(msg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
time.Sleep(5 * time.Second)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *HonkAdapter) toMsg(h honk) Message {
|
||||||
|
t, err := time.Parse(time.RFC3339, h.Date)
|
||||||
|
if err != nil {
|
||||||
|
t = time.Now()
|
||||||
|
}
|
||||||
|
tt := t.UnixMilli()
|
||||||
|
|
||||||
|
a := h.Honker
|
||||||
|
if h.Oonker != nil {
|
||||||
|
a = *h.Oonker
|
||||||
|
}
|
||||||
|
|
||||||
|
msg := Message{
|
||||||
|
Datagram: Datagram{
|
||||||
|
Id: h.XID,
|
||||||
|
Uri: h.XID,
|
||||||
|
Protocol: "honk",
|
||||||
|
Adapter: self.nickname,
|
||||||
|
Type: "message",
|
||||||
|
Created: tt,
|
||||||
|
},
|
||||||
|
Author: a,
|
||||||
|
Content: h.Noise,
|
||||||
|
ReplyTo: h.RID,
|
||||||
|
Visibility: "Private",
|
||||||
|
}
|
||||||
|
if h.Public {
|
||||||
|
msg.Visibility = "Public"
|
||||||
|
}
|
||||||
|
if h.Oonker != nil {
|
||||||
|
r := fmt.Sprintf("%s/bonk/%d", h.Honker, h.ID)
|
||||||
|
msg.Renoter = h.Oonker
|
||||||
|
msg.RenoteId = &r
|
||||||
|
msg.RenoteTime = &tt
|
||||||
|
}
|
||||||
|
for _, d := range h.Donks {
|
||||||
|
a := Attachment{
|
||||||
|
Src: d.URL,
|
||||||
|
Desc: d.Desc,
|
||||||
|
}
|
||||||
|
msg.Attachments = append(msg.Attachments, a)
|
||||||
|
}
|
||||||
|
return msg
|
||||||
|
}
|
||||||
|
|
||||||
func (self *HonkAdapter) Fetch(etype string, ids []string) error {
|
func (self *HonkAdapter) Fetch(etype string, ids []string) error {
|
||||||
// honk API is limited, we fall back to the anonymous adapter for fetch ops
|
// honk API is limited, we fall back to the anonymous adapter for fetch ops
|
||||||
aaa := anonAPAdapter{}
|
aaa := anonAPAdapter{}
|
||||||
|
|
Loading…
Reference in a new issue