not sure this works, but untested code to handle collection follow
Ted Unangst tedu@tedunangst.com
Fri, 25 Oct 2019 20:31:07 -0400
3 files changed,
104 insertions(+),
1 deletions(-)
M
activity.go
→
activity.go
@@ -1193,6 +1193,40 @@ }
for a := range rcpts { go deliverate(0, user.ID, a, msg) } + if honk.Public && len(honk.Onts) > 0 { + collectiveaction(honk) + } +} + +func collectiveaction(honk *Honk) { + user := getserveruser() + for _, ont := range honk.Onts { + dubs := getnameddubs(serverUID, ont) + if len(dubs) == 0 { + continue + } + j := junk.New() + j["@context"] = itiswhatitis + j["type"] = "Add" + j["id"] = user.URL + "/add/" + shortxid(ont+honk.XID) + j["actor"] = user.URL + j["object"] = honk.XID + j["target"] = fmt.Sprintf("https://%s/o/%s", ont[1:]) + rcpts := make(map[string]bool) + for _, dub := range dubs { + var box *Box + ok := boxofboxes.Get(dub.XID, &box) + if ok && box.Shared != "" { + rcpts["%"+box.Shared] = true + } else { + rcpts[dub.XID] = true + } + } + msg := j.ToBytes() + for a := range rcpts { + go deliverate(0, user.ID, a, msg) + } + } } func junkuser(user *WhatAbout) []byte {
M
database.go
→
database.go
@@ -112,6 +112,15 @@ }
func getdubs(userid int64) []*Honker { rows, err := stmtDubbers.Query(userid) + return dubsfromrows(rows, err) +} + +func getnameddubs(userid int64, name string) []*Honker { + rows, err := stmtNamedDubbers.Query(userid, name) + return dubsfromrows(rows, err) +} + +func dubsfromrows(rows *sql.Rows, err error) []*Honker { if err != nil { log.Printf("error querying dubs: %s", err) return nil@@ -664,7 +673,7 @@ log.Fatal(err)
} } -var stmtHonkers, stmtDubbers, stmtSaveHonker, stmtUpdateFlavor, stmtUpdateHonker *sql.Stmt +var stmtHonkers, stmtDubbers, stmtNamedDubbers, stmtSaveHonker, stmtUpdateFlavor, stmtUpdateHonker *sql.Stmt var stmtAnyXonk, stmtOneXonk, stmtPublicHonks, stmtUserHonks, stmtHonksByCombo, stmtHonksByConvoy *sql.Stmt var stmtHonksByOntology, stmtHonksForUser, stmtHonksForMe, stmtSaveDub, stmtHonksByXonker *sql.Stmt var stmtHonksBySearch, stmtHonksByHonker, stmtSaveHonk, stmtUserByName, stmtUserByNumber *sql.Stmt@@ -692,6 +701,7 @@ stmtUpdateFlavor = preparetodie(db, "update honkers set flavor = ? where userid = ? and xid = ? and flavor = ?")
stmtUpdateHonker = preparetodie(db, "update honkers set name = ?, combos = ? where honkerid = ? and userid = ?") stmtOneHonker = preparetodie(db, "select xid from honkers where name = ? and userid = ?") stmtDubbers = preparetodie(db, "select honkerid, userid, name, xid, flavor from honkers where userid = ? and flavor = 'dub'") + stmtNamedDubbers = preparetodie(db, "select honkerid, userid, name, xid, flavor from honkers where userid = ? and name = ? and flavor = 'dub'") selecthonks := "select honks.honkid, honks.userid, username, what, honker, oonker, honks.xid, rid, dt, url, audience, noise, precis, format, convoy, whofore, flags from honks join users on honks.userid = users.userid " limit := " order by honks.honkid desc limit 250"
M
web.go
→
web.go
@@ -26,6 +26,7 @@ notrand "math/rand"
"net/http" "net/url" "os" + "regexp" "sort" "strconv" "strings"@@ -447,8 +448,66 @@ }
http.Error(w, "what did you call me?", http.StatusTeapot) return } + user := getserveruser() + who, _ := j.GetString("actor") + origin := keymatch(keyname, who) + if origin == "" { + log.Printf("keyname actor mismatch: %s <> %s", keyname, who) + return + } + if rejectactor(user.ID, who) { + return + } what, _ := j.GetString("type") log.Printf("server got a %s", what) + switch what { + case "Follow": + obj, _ := j.GetString("object") + if obj == user.URL { + log.Printf("can't follow the server!") + return + } + re_ont := regexp.MustCompile("https://" + serverName + "/o/([[:alnum:]]+)") + m := re_ont.FindStringSubmatch(obj) + if len(m) == 2 { + ont := "#" + m[1] + log.Printf("%s wants to follow %s", who, ont) + db := opendatabase() + row := db.QueryRow("select xid from honkers where name = ? and xid = ? and userid = ? and flavor in ('dub', 'undub')", ont, who, user.ID) + var x string + err = row.Scan(&x) + if err != sql.ErrNoRows { + // incomplete... + log.Printf("duplicate follow request: %s", who) + _, err = stmtUpdateFlavor.Exec("dub", user.ID, who, "undub") + if err != nil { + log.Printf("error updating honker: %s", err) + } + } else { + stmtSaveDub.Exec(user.ID, ont, who, "dub") + } + go rubadubdub(user, j) + } + case "Undo": + obj, ok := j.GetMap("object") + if !ok { + log.Printf("unknown undo no object") + } else { + what, _ := obj.GetString("type") + switch what { + case "Follow": + // incomplete... + log.Printf("updating honker undo: %s", who) + _, err = stmtUpdateFlavor.Exec("undub", user.ID, who, "dub") + if err != nil { + log.Printf("error updating honker: %s", err) + return + } + default: + log.Printf("unknown undo: %s", what) + } + } + } } func serveractor(w http.ResponseWriter, r *http.Request) {