mirror of
https://github.com/writeas/writefreely
synced 2025-01-24 11:31:09 +01:00
Support un-liking posts from the fediverse
Ref T906
This commit is contained in:
parent
0ce5d3ba26
commit
7f1cc6bf8f
116
activitypub.go
116
activitypub.go
@ -357,8 +357,8 @@ func handleFetchCollectionInbox(app *App, w http.ResponseWriter, r *http.Request
|
|||||||
a := streams.NewAccept()
|
a := streams.NewAccept()
|
||||||
p := c.PersonObject()
|
p := c.PersonObject()
|
||||||
var to *url.URL
|
var to *url.URL
|
||||||
var isFollow, isUnfollow, isLike bool
|
var isFollow, isUnfollow, isLike, isUnlike bool
|
||||||
var likePostID string
|
var likePostID, unlikePostID string
|
||||||
fullActor := &activitystreams.Person{}
|
fullActor := &activitystreams.Person{}
|
||||||
var remoteUser *RemoteUser
|
var remoteUser *RemoteUser
|
||||||
|
|
||||||
@ -392,29 +392,7 @@ func handleFetchCollectionInbox(app *App, w http.ResponseWriter, r *http.Request
|
|||||||
}, 0)
|
}, 0)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Get post ID from URL
|
likePostID, err = parsePostIDFromURL(app, obj)
|
||||||
var collAlias, slug string
|
|
||||||
if m := apCollectionPostIRIRegex.FindStringSubmatch(obj.String()); len(m) == 3 {
|
|
||||||
collAlias = m[1]
|
|
||||||
slug = m[2]
|
|
||||||
} else if m = apDraftPostIRIRegex.FindStringSubmatch(obj.String()); len(m) == 2 {
|
|
||||||
likePostID = m[1]
|
|
||||||
} else {
|
|
||||||
return fmt.Errorf("unable to match objectIRI: %s", obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get postID if all we have is collection and slug
|
|
||||||
if collAlias != "" && slug != "" {
|
|
||||||
c, err := app.db.GetCollection(collAlias)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
p, err := app.db.GetPost(slug, c.ID)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
likePostID = p.ID
|
|
||||||
}
|
|
||||||
|
|
||||||
// Finally, get actor information
|
// Finally, get actor information
|
||||||
_, from := l.GetActor(0)
|
_, from := l.GetActor(0)
|
||||||
@ -465,8 +443,6 @@ func handleFetchCollectionInbox(app *App, w http.ResponseWriter, r *http.Request
|
|||||||
return impart.RenderActivityJSON(w, m, http.StatusOK)
|
return impart.RenderActivityJSON(w, m, http.StatusOK)
|
||||||
},
|
},
|
||||||
UndoCallback: func(u *streams.Undo) error {
|
UndoCallback: func(u *streams.Undo) error {
|
||||||
isUnfollow = true
|
|
||||||
|
|
||||||
m["@context"] = []string{activitystreams.Namespace}
|
m["@context"] = []string{activitystreams.Namespace}
|
||||||
b, _ := json.Marshal(m)
|
b, _ := json.Marshal(m)
|
||||||
if debugging {
|
if debugging {
|
||||||
@ -474,6 +450,31 @@ func handleFetchCollectionInbox(app *App, w http.ResponseWriter, r *http.Request
|
|||||||
}
|
}
|
||||||
|
|
||||||
a.AppendObject(u.Raw())
|
a.AppendObject(u.Raw())
|
||||||
|
|
||||||
|
// Check type -- we handle Undo:Like and Undo:Follow
|
||||||
|
_, err := u.ResolveObject(&streams.Resolver{
|
||||||
|
LikeCallback: func(like *streams.Like) error {
|
||||||
|
isUnlike = true
|
||||||
|
|
||||||
|
_, from := like.GetActor(0)
|
||||||
|
obj := like.Raw().GetObjectIRI(0)
|
||||||
|
unlikePostID, err = parsePostIDFromURL(app, obj)
|
||||||
|
fullActor, remoteUser, err = getActor(app, from.String())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
// TODO: add FollowCallback for more robust handling
|
||||||
|
}, 0)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if isUnlike {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
isUnfollow = true
|
||||||
_, to = u.GetActor(0)
|
_, to = u.GetActor(0)
|
||||||
// TODO: get actor from object.object, not object
|
// TODO: get actor from object.object, not object
|
||||||
obj := u.Raw().GetObjectIRI(0)
|
obj := u.Raw().GetObjectIRI(0)
|
||||||
@ -546,6 +547,39 @@ func handleFetchCollectionInbox(app *App, w http.ResponseWriter, r *http.Request
|
|||||||
log.Info("Successfully liked post %s by remote user %s", likePostID, remoteUser.URL)
|
log.Info("Successfully liked post %s by remote user %s", likePostID, remoteUser.URL)
|
||||||
}
|
}
|
||||||
return impart.RenderActivityJSON(w, "", http.StatusOK)
|
return impart.RenderActivityJSON(w, "", http.StatusOK)
|
||||||
|
} else if isUnlike {
|
||||||
|
t, err := app.db.Begin()
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Unable to start transaction: %v", err)
|
||||||
|
return fmt.Errorf("unable to start transaction: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var remoteUserID int64
|
||||||
|
if remoteUser != nil {
|
||||||
|
remoteUserID = remoteUser.ID
|
||||||
|
} else {
|
||||||
|
remoteUserID, err = apAddRemoteUser(app, t, fullActor)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add follow
|
||||||
|
_, err = t.Exec("DELETE FROM remote_likes WHERE post_id = ? AND remote_user_id = ?", unlikePostID, remoteUserID)
|
||||||
|
if err != nil {
|
||||||
|
t.Rollback()
|
||||||
|
log.Error("Couldn't delete Like from DB: %v\n", err)
|
||||||
|
return fmt.Errorf("Couldn't delete Like from DB: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = t.Commit()
|
||||||
|
if err != nil {
|
||||||
|
t.Rollback()
|
||||||
|
log.Error("Rolling back after Commit(): %v\n", err)
|
||||||
|
return fmt.Errorf("Rolling back after Commit(): %v\n", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if debugging {
|
||||||
|
log.Info("Successfully un-liked post %s by remote user %s", unlikePostID, remoteUser.URL)
|
||||||
|
}
|
||||||
|
return impart.RenderActivityJSON(w, "", http.StatusOK)
|
||||||
}
|
}
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
@ -1078,6 +1112,34 @@ func unmarshalActor(actorResp []byte, actor *activitystreams.Person) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func parsePostIDFromURL(app *App, u *url.URL) (string, error) {
|
||||||
|
// Get post ID from URL
|
||||||
|
var collAlias, slug, postID string
|
||||||
|
if m := apCollectionPostIRIRegex.FindStringSubmatch(u.String()); len(m) == 3 {
|
||||||
|
collAlias = m[1]
|
||||||
|
slug = m[2]
|
||||||
|
} else if m = apDraftPostIRIRegex.FindStringSubmatch(u.String()); len(m) == 2 {
|
||||||
|
postID = m[1]
|
||||||
|
} else {
|
||||||
|
return "", fmt.Errorf("unable to match objectIRI: %s", u)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get postID if all we have is collection and slug
|
||||||
|
if collAlias != "" && slug != "" {
|
||||||
|
c, err := app.db.GetCollection(collAlias)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
p, err := app.db.GetPost(slug, c.ID)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
postID = p.ID
|
||||||
|
}
|
||||||
|
|
||||||
|
return postID, nil
|
||||||
|
}
|
||||||
|
|
||||||
func setCacheControl(w http.ResponseWriter, ttl time.Duration) {
|
func setCacheControl(w http.ResponseWriter, ttl time.Duration) {
|
||||||
w.Header().Set("Cache-Control", fmt.Sprintf("public, max-age=%.0f", ttl.Seconds()))
|
w.Header().Set("Cache-Control", fmt.Sprintf("public, max-age=%.0f", ttl.Seconds()))
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user