diff --git a/TODO b/TODO index f0ab480..e997831 100644 --- a/TODO +++ b/TODO @@ -51,4 +51,6 @@ [ ] Leave them read-only? [ ] Leave them as is? [✔] Handle followers and following uri's -[ ] Do I care about the inbox? \ No newline at end of file +[ ] Do I care about the inbox? +[ ] Expose configuration to apps +[ ] Do not boost replies (configurable) \ No newline at end of file diff --git a/actor.go b/actor.go index 196f52a..7b3095a 100644 --- a/actor.go +++ b/actor.go @@ -198,6 +198,41 @@ func LoadActor(name string) (Actor, error) { publicKeyID: baseURL + name + "#main-key", } + actor.OnFollow = func(activity map[string]interface{}) { actor.Accept(activity) } + + return actor, nil +} + +// GetActor attempts to LoadActor and if it doesn't exist +// creates one +func GetActor(name, summary, actorType string) (Actor, error) { + actor, err := LoadActor(name) + + if err != nil { + log.Info("Actor doesn't exist, creating...") + actor, err = MakeActor(name, summary, actorType) + if err != nil { + log.Info("Can't create actor!") + return Actor{}, err + } + } + + // if the info provided for the actor is different + // from what the actor has, edit the actor + save := false + if summary != actor.summary { + actor.summary = summary + save = true + } + if actorType != actor.actorType { + actor.actorType = actorType + save = true + } + // if anything changed write it to disk + if save { + actor.save() + } + return actor, nil } @@ -262,11 +297,16 @@ func (a *Actor) whoAmI() string { }` } -func (a *Actor) newID() (hash string, url string) { +func (a *Actor) newItemID() (hash string, url string) { hash = uniuri.New() return hash, baseURL + a.name + "/item/" + hash } +func (a *Actor) newID() (hash string, url string) { + hash = uniuri.New() + return hash, baseURL + a.name + "/" + hash +} + // TODO Reply(content string, inReplyTo string) // ReplyNote sends a note to a specific actor in reply to @@ -280,7 +320,7 @@ func (a *Actor) newID() (hash string, url string) { // func (a *Actor) CreateNote(content, inReplyTo string) { // for now I will just write this to the outbox - hash, id := a.newID() + hash, id := a.newItemID() create := make(map[string]interface{}) note := make(map[string]interface{}) create["@context"] = context() @@ -555,7 +595,7 @@ func (a *Actor) Follow(user string) (err error) { } follow := make(map[string]interface{}) - _, id := a.newID() + hash, id := a.newItemID() follow["@context"] = context() follow["actor"] = a.iri @@ -575,7 +615,7 @@ func (a *Actor) Follow(user string) (err error) { return } // save the activity - a.saveItem(id, follow) + a.saveItem(hash, follow) // we are going to save only on accept so look at // the http handler for the accept code }() @@ -591,7 +631,7 @@ func (a *Actor) Follow(user string) (err error) { // id to the id of the original Follow activity that // was accepted when initially following that user // (this is read from the `actor.following` map -func (a *Actor) Unfollow(user string){ +func (a *Actor) Unfollow(user string) { log.Info("Unfollowing " + user) // create an undo activiy @@ -606,7 +646,7 @@ func (a *Actor) Unfollow(user string){ follow["@context"] = context() follow["actor"] = a.iri - follow["id"] = baseURL + "/item/" + hash + follow["id"] = baseURL + "/item/" + hash follow["object"] = user follow["type"] = "Follow" @@ -642,7 +682,7 @@ func (a *Actor) Unfollow(user string){ func (a *Actor) Announce(url string) { // our announcements are public. Public stuff have a "To" to the url below toURL := "https://www.w3.org/ns/activitystreams#Public" - id, hash := a.newID() + id, hash := a.newItemID() announce := make(map[string]interface{}) diff --git a/http.go b/http.go index 9bdb4d7..141624c 100644 --- a/http.go +++ b/http.go @@ -107,7 +107,7 @@ func Serve() { "first" : "` + baseURL + actor.name + `/outbox?page=1", "id" : "` + baseURL + actor.name + `/outbox", "last" : "` + baseURL + actor.name + `/outbox?page=` + strconv.Itoa(totalLines/postsPerPage+1) + `", - "totalItems" : 10, + "totalItems" : ` + strconv.Itoa(totalLines) + `, "type" : "OrderedCollection" }`) } else { @@ -213,7 +213,7 @@ func Serve() { return } // try to get the hash only - hash := strings.Replace(id, baseURL+actor.name+"/", "", 1) + hash := strings.Replace(id, baseURL+actor.name+"/item/", "", 1) // if there are still slashes in the result this means the // above didn't work if strings.ContainsAny(hash, "/") { @@ -234,6 +234,17 @@ func Serve() { } actor.following[acceptor] = hash actor.save() + case "Reject": + rejector := activity["actor"].(string) + actor, err := LoadActor(mux.Vars(r)["actor"]) // load the actor from disk + if err != nil { + log.Error("No such actor") + return + } + // write the actor to the list of rejected follows so that + // we won't try following them again + actor.rejected[rejector] = "" + actor.save() default: } @@ -282,7 +293,7 @@ func Serve() { return } postJSON, err := json.Marshal(post) - if err!= nil{ + if err != nil { log.Info("failed to marshal json from item " + hash + " text") return }