1package activityserve
2
3import (
4	"bytes"
5	"encoding/json"
6	"fmt"
7	"io/ioutil"
8	"net/http"
9
10	"github.com/gologme/log"
11)
12
13// RemoteActor is a type that holds an actor
14// that we want to interact with
15type RemoteActor struct {
16	iri, outbox, inbox, sharedInbox string
17	info                            map[string]interface{}
18}
19
20// NewRemoteActor returns a remoteActor which holds
21// all the info required for an actor we want to
22// interact with (not essentially sitting in our instance)
23func NewRemoteActor(iri string) (RemoteActor, error) {
24
25	info, err := get(iri)
26	if err != nil {
27		log.Info("Couldn't get remote actor information")
28		log.Info(err)
29		return RemoteActor{}, err
30	}
31
32	outbox, _ := info["outbox"].(string)
33	inbox, _ := info["inbox"].(string)
34	var endpoints map[string]interface{}
35	var sharedInbox string
36	if info["endpoints"] != nil {
37		endpoints = info["endpoints"].(map[string]interface{})
38		if val, ok := endpoints["sharedInbox"]; ok {
39			sharedInbox = val.(string)
40		}
41	}
42
43	return RemoteActor{
44		iri:         iri,
45		outbox:      outbox,
46		inbox:       inbox,
47		sharedInbox: sharedInbox,
48	}, err
49}
50
51func (ra RemoteActor) getLatestPosts(number int) (map[string]interface{}, error) {
52	return get(ra.outbox)
53}
54
55func get(iri string) (info map[string]interface{}, err error) {
56
57	buf := new(bytes.Buffer)
58
59	req, err := http.NewRequest("GET", iri, buf)
60	if err != nil {
61		log.Info(err)
62		return
63	}
64	req.Header.Add("Accept", "application/activity+json")
65	req.Header.Add("User-Agent", userAgent+" "+version)
66	req.Header.Add("Accept-Charset", "utf-8")
67
68	resp, err := client.Do(req)
69
70	if err != nil {
71		log.Info("Cannot perform the request")
72		log.Info(err)
73		return
74	}
75
76	responseData, _ := ioutil.ReadAll(resp.Body)
77
78	if !isSuccess(resp.StatusCode) {
79		err = fmt.Errorf("GET request to %s failed (%d): %s\nResponse: %s \nHeaders: %s", iri, resp.StatusCode, resp.Status, FormatJSON(responseData), FormatHeaders(req.Header))
80		log.Info(err)
81		return
82	}
83
84	var e interface{}
85	err = json.Unmarshal(responseData, &e)
86
87	if err != nil {
88		log.Info("something went wrong when unmarshalling the json")
89		log.Info(err)
90		return
91	}
92	info = e.(map[string]interface{})
93
94	return
95}
96
97// GetInbox returns the inbox url of the actor
98func (ra RemoteActor) GetInbox() string {
99	return ra.inbox
100}
101
102// GetSharedInbox returns the inbox url of the actor
103func (ra RemoteActor) GetSharedInbox() string {
104	if ra.sharedInbox == "" {
105		return ra.inbox
106	}
107	return ra.sharedInbox
108}
109