Various improvements
This commit is contained in:
parent
c0594e4e04
commit
ffadbe80c8
31
actor.go
31
actor.go
|
@ -96,12 +96,10 @@ func (a *Actor) save() error {
|
||||||
Followers: a.followers,
|
Followers: a.followers,
|
||||||
}
|
}
|
||||||
f, err := os.OpenFile(storage+slash+"actors"+slash+a.Name+slash+a.Name+".json", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
|
f, err := os.OpenFile(storage+slash+"actors"+slash+a.Name+slash+a.Name+".json", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
|
||||||
|
defer func() { _ = f.Close() }()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer func() {
|
|
||||||
_ = f.Close()
|
|
||||||
}()
|
|
||||||
jsonEncoder := json.NewEncoder(f)
|
jsonEncoder := json.NewEncoder(f)
|
||||||
jsonEncoder.SetIndent("", "\t")
|
jsonEncoder.SetIndent("", "\t")
|
||||||
err = jsonEncoder.Encode(actorToSave)
|
err = jsonEncoder.Encode(actorToSave)
|
||||||
|
@ -131,11 +129,12 @@ func (a *Actor) PostArticle(url string) error {
|
||||||
return errors.New("failed to fetch article")
|
return errors.New("failed to fetch article")
|
||||||
}
|
}
|
||||||
err = json.NewDecoder(resp.Body).Decode(&article)
|
err = json.NewDecoder(resp.Body).Decode(&article)
|
||||||
|
_ = resp.Body.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.New("failed to decode fetched article")
|
return errors.New("failed to decode fetched article")
|
||||||
}
|
}
|
||||||
create["object"] = article
|
create["object"] = article
|
||||||
a.sendToFollowers(&create)
|
a.sendToFollowers(create)
|
||||||
// Boost article if it contains "inReplyTo"
|
// Boost article if it contains "inReplyTo"
|
||||||
if article["inReplyTo"] != nil {
|
if article["inReplyTo"] != nil {
|
||||||
announce := make(map[string]interface{})
|
announce := make(map[string]interface{})
|
||||||
|
@ -146,7 +145,7 @@ func (a *Actor) PostArticle(url string) error {
|
||||||
announce["actor"] = a.iri
|
announce["actor"] = a.iri
|
||||||
announce["to"] = []string{"https://www.w3.org/ns/activitystreams#Public"}
|
announce["to"] = []string{"https://www.w3.org/ns/activitystreams#Public"}
|
||||||
announce["published"] = article["published"]
|
announce["published"] = article["published"]
|
||||||
a.sendToFollowers(&announce)
|
a.sendToFollowers(announce)
|
||||||
}
|
}
|
||||||
// Send update event if it contains "updated" and "updated" != "published"
|
// Send update event if it contains "updated" and "updated" != "published"
|
||||||
if article["updated"] != nil && article["published"] != nil && article["updated"] != article["published"] {
|
if article["updated"] != nil && article["published"] != nil && article["updated"] != article["published"] {
|
||||||
|
@ -155,7 +154,7 @@ func (a *Actor) PostArticle(url string) error {
|
||||||
update["type"] = "Update"
|
update["type"] = "Update"
|
||||||
update["object"] = url
|
update["object"] = url
|
||||||
update["actor"] = a.iri
|
update["actor"] = a.iri
|
||||||
a.sendToFollowers(&update)
|
a.sendToFollowers(update)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -163,8 +162,8 @@ func (a *Actor) PostArticle(url string) error {
|
||||||
// signedHTTPPost performs an HTTP post on behalf of Actor with the
|
// signedHTTPPost performs an HTTP post on behalf of Actor with the
|
||||||
// request-target, date, host and digest headers signed
|
// request-target, date, host and digest headers signed
|
||||||
// with the actor's private key.
|
// with the actor's private key.
|
||||||
func (a *Actor) signedHTTPPost(content *map[string]interface{}, to string) (err error) {
|
func (a *Actor) signedHTTPPost(content map[string]interface{}, to string) (err error) {
|
||||||
b, err := json.Marshal(*content)
|
b, err := json.Marshal(content)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -217,7 +216,7 @@ func (a *Actor) RemoveFollower(iri string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// send to followers sends a batch of http posts to each one of the followers
|
// send to followers sends a batch of http posts to each one of the followers
|
||||||
func (a *Actor) sendToFollowers(activity *map[string]interface{}) {
|
func (a *Actor) sendToFollowers(activity map[string]interface{}) {
|
||||||
recipients := make([]string, len(a.followers))
|
recipients := make([]string, len(a.followers))
|
||||||
i := 0
|
i := 0
|
||||||
for _, inbox := range a.followers {
|
for _, inbox := range a.followers {
|
||||||
|
@ -236,12 +235,12 @@ func (a *Actor) newID() (hash string, url string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Accept a follow request
|
// Accept a follow request
|
||||||
func (a *Actor) Accept(follow *map[string]interface{}) {
|
func (a *Actor) Accept(follow map[string]interface{}) {
|
||||||
// it's a follow, write it down
|
// it's a follow, write it down
|
||||||
newFollower := (*follow)["actor"].(string)
|
newFollower := follow["actor"].(string)
|
||||||
fmt.Println("New follow request:", newFollower)
|
fmt.Println("New follow request:", newFollower)
|
||||||
// check we aren't following ourselves
|
// check we aren't following ourselves
|
||||||
if newFollower == (*follow)["object"] {
|
if newFollower == follow["object"] {
|
||||||
// actor and object are equal
|
// actor and object are equal
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -254,15 +253,15 @@ func (a *Actor) Accept(follow *map[string]interface{}) {
|
||||||
// Add or update follower
|
// Add or update follower
|
||||||
_ = a.NewFollower(newFollower, follower.inbox)
|
_ = a.NewFollower(newFollower, follower.inbox)
|
||||||
// remove @context from the inner activity
|
// remove @context from the inner activity
|
||||||
delete(*follow, "@context")
|
delete(follow, "@context")
|
||||||
accept := make(map[string]interface{})
|
accept := make(map[string]interface{})
|
||||||
accept["@context"] = "https://www.w3.org/ns/activitystreams"
|
accept["@context"] = "https://www.w3.org/ns/activitystreams"
|
||||||
accept["to"] = (*follow)["actor"]
|
accept["to"] = follow["actor"]
|
||||||
_, accept["id"] = a.newID()
|
_, accept["id"] = a.newID()
|
||||||
accept["actor"] = a.iri
|
accept["actor"] = a.iri
|
||||||
accept["object"] = *follow
|
accept["object"] = follow
|
||||||
accept["type"] = "Accept"
|
accept["type"] = "Accept"
|
||||||
err = a.signedHTTPPost(&accept, follower.inbox)
|
err = a.signedHTTPPost(accept, follower.inbox)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("Failed to accept:", follower.iri)
|
fmt.Println("Failed to accept:", follower.iri)
|
||||||
fmt.Println(err.Error())
|
fmt.Println(err.Error())
|
||||||
|
|
5
feed.go
5
feed.go
|
@ -7,7 +7,7 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
func allFeedItems(url string) (*[]string, error) {
|
func allFeedItems(url string) ([]string, error) {
|
||||||
jsonFeed := &struct {
|
jsonFeed := &struct {
|
||||||
Items []struct {
|
Items []struct {
|
||||||
Url string `json:"url"`
|
Url string `json:"url"`
|
||||||
|
@ -23,6 +23,7 @@ func allFeedItems(url string) (*[]string, error) {
|
||||||
return nil, errors.New("failed to get json feed")
|
return nil, errors.New("failed to get json feed")
|
||||||
}
|
}
|
||||||
err = json.NewDecoder(resp.Body).Decode(&jsonFeed)
|
err = json.NewDecoder(resp.Body).Decode(&jsonFeed)
|
||||||
|
_ = resp.Body.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.New("failed to parse json feed")
|
return nil, errors.New("failed to parse json feed")
|
||||||
}
|
}
|
||||||
|
@ -30,5 +31,5 @@ func allFeedItems(url string) (*[]string, error) {
|
||||||
for _, item := range jsonFeed.Items {
|
for _, item := range jsonFeed.Items {
|
||||||
allUrls = append(allUrls, item.Url)
|
allUrls = append(allUrls, item.Url)
|
||||||
}
|
}
|
||||||
return &allUrls, nil
|
return allUrls, nil
|
||||||
}
|
}
|
||||||
|
|
19
http.go
19
http.go
|
@ -26,13 +26,13 @@ func Serve() {
|
||||||
fmt.Println(actor.feed, err.Error())
|
fmt.Println(actor.feed, err.Error())
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if len(*articles) < 1 {
|
if len(articles) < 1 {
|
||||||
fmt.Println(actor.feed, "Empty feed")
|
fmt.Println(actor.feed, "Empty feed")
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
err = actor.PostArticle((*articles)[0])
|
err = actor.PostArticle(articles[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("Posting", (*articles)[0], "failed")
|
fmt.Println("Posting", articles[0], "failed")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
@ -69,6 +69,7 @@ func Serve() {
|
||||||
inboxHandler := func(w http.ResponseWriter, r *http.Request) {
|
inboxHandler := func(w http.ResponseWriter, r *http.Request) {
|
||||||
activity := make(map[string]interface{})
|
activity := make(map[string]interface{})
|
||||||
err := json.NewDecoder(r.Body).Decode(&activity)
|
err := json.NewDecoder(r.Body).Decode(&activity)
|
||||||
|
_ = r.Body.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
|
@ -81,7 +82,7 @@ func Serve() {
|
||||||
}
|
}
|
||||||
switch activity["type"] {
|
switch activity["type"] {
|
||||||
case "Follow":
|
case "Follow":
|
||||||
actor.Accept(&activity)
|
actor.Accept(activity)
|
||||||
case "Undo":
|
case "Undo":
|
||||||
{
|
{
|
||||||
if object, ok := activity["object"].(map[string]interface{}); ok {
|
if object, ok := activity["object"].(map[string]interface{}); ok {
|
||||||
|
@ -111,8 +112,12 @@ func Serve() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Send Webmentions
|
// Send Webmentions
|
||||||
|
sent := map[string]bool{}
|
||||||
for _, link := range dl {
|
for _, link := range dl {
|
||||||
|
if !sent[link] {
|
||||||
sendWebmention(webmentionClient, actor, id, link)
|
sendWebmention(webmentionClient, actor, id, link)
|
||||||
|
sent[link] = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -125,7 +130,7 @@ func Serve() {
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
// Log inbox request
|
// Log inbox request
|
||||||
logInbox(actor, &activity)
|
logInbox(actor, activity)
|
||||||
}
|
}
|
||||||
// Return 201
|
// Return 201
|
||||||
w.WriteHeader(http.StatusCreated)
|
w.WriteHeader(http.StatusCreated)
|
||||||
|
@ -141,12 +146,12 @@ func Serve() {
|
||||||
log.Fatal(http.ListenAndServe(":8081", nil))
|
log.Fatal(http.ListenAndServe(":8081", nil))
|
||||||
}
|
}
|
||||||
|
|
||||||
func logInbox(actor *Actor, activity *map[string]interface{}) {
|
func logInbox(actor *Actor, activity map[string]interface{}) {
|
||||||
f, err := os.OpenFile(storage+slash+"actors"+slash+actor.Name+slash+"inbox", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
f, err := os.OpenFile(storage+slash+"actors"+slash+actor.Name+slash+"inbox", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
||||||
|
defer func() { _ = f.Close() }()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer func() { _ = f.Close() }()
|
|
||||||
_ = json.NewEncoder(f).Encode(activity)
|
_ = json.NewEncoder(f).Encode(activity)
|
||||||
_, _ = f.WriteString("\n---\n")
|
_, _ = f.WriteString("\n---\n")
|
||||||
}
|
}
|
||||||
|
|
Reference in New Issue