diff --git a/hfcs.go b/hfcs.go index 08a36a5..cc5c710 100644 --- a/hfcs.go +++ b/hfcs.go @@ -67,11 +67,12 @@ func (ft filtType) String() string { type afiltermap map[filtType][]*Filter +var filtInvalidator cache.Invalidator var filtcache *cache.Cache func init() { // resolve init loop - filtcache = cache.New(cache.Options{Filler: filtcachefiller}) + filtcache = cache.New(cache.Options{Filler: filtcachefiller, Invalidator: &filtInvalidator}) } func filtcachefiller(userid int64) (afiltermap, bool) { @@ -157,7 +158,7 @@ func filtcachefiller(userid int64) (afiltermap, bool) { func filtcacheclear(userid int64, dur time.Duration) { time.Sleep(dur + time.Second) - filtcache.Clear(userid) + filtInvalidator.Clear(userid) } func getfilters(userid int64, scope filtType) []*Filter { @@ -169,19 +170,44 @@ func getfilters(userid int64, scope filtType) []*Filter { return nil } +type arejectmap map[string][]*Filter + +var rejectAnyKey = "..." + +var rejectcache = cache.New(cache.Options{Filler: func(userid int64) (arejectmap, bool) { + m := make(arejectmap) + filts := getfilters(userid, filtReject) + for _, f := range filts { + if f.Text != "" { + key := rejectAnyKey + m[key] = append(m[key], f) + continue + } + if f.IsAnnounce && f.AnnounceOf != "" { + key := f.AnnounceOf + m[key] = append(m[key], f) + } + if f.Actor != "" { + key := f.Actor + m[key] = append(m[key], f) + } + } + return m, true +}, Invalidator: &filtInvalidator}) + +func rejectfilters(userid int64, name string) []*Filter { + var m arejectmap + rejectcache.Get(userid, &m) + return m[name] +} + func rejectorigin(userid int64, origin string, isannounce bool) bool { if o := originate(origin); o != "" { origin = o } - filts := getfilters(userid, filtReject) + filts := rejectfilters(userid, origin) for _, f := range filts { - if f.Text != "" { - continue - } - if f.IsAnnounce { - if !isannounce { - continue - } + if isannounce && f.IsAnnounce { if f.AnnounceOf == origin { log.Printf("rejecting announce: %s", origin) return true @@ -196,13 +222,26 @@ func rejectorigin(userid int64, origin string, isannounce bool) bool { } func rejectactor(userid int64, actor string) bool { - origin := originate(actor) - filts := getfilters(userid, filtReject) + filts := rejectfilters(userid, actor) for _, f := range filts { - if f.IsAnnounce || f.Text != "" { + if f.IsAnnounce { continue } - if f.Actor == actor || (origin != "" && f.Actor == origin) { + if f.Actor == actor { + log.Printf("rejecting actor: %s", actor) + return true + } + } + origin := originate(actor) + if origin == "" { + return false + } + filts = rejectfilters(userid, origin) + for _, f := range filts { + if f.IsAnnounce { + continue + } + if f.Actor == origin { log.Printf("rejecting actor: %s", actor) return true } @@ -287,10 +326,17 @@ func matchfilterX(h *Honk, f *Filter) string { } func rejectxonk(xonk *Honk) bool { - filts := getfilters(xonk.UserID, filtReject) + var m arejectmap + rejectcache.Get(xonk.UserID, &m) + filts := m[rejectAnyKey] + filts = append(filts, m[xonk.Honker]...) + filts = append(filts, m[xonk.Oonker]...) + for _, a := range xonk.Audience { + filts = append(filts, m[a]...) + } for _, f := range filts { - if matchfilter(xonk, f) { - log.Printf("rejecting %s because %s", xonk.XID, f.Actor) + if cause := matchfilterX(xonk, f); cause != "" { + log.Printf("rejecting %s because %s", xonk.XID, cause) return true } } diff --git a/web.go b/web.go index c89c339..ef09b9c 100644 --- a/web.go +++ b/web.go @@ -1874,7 +1874,7 @@ func savehfcs(w http.ResponseWriter, r *http.Request) { if err != nil { log.Printf("error deleting filter: %s", err) } - filtcache.Clear(userinfo.UserID) + filtInvalidator.Clear(userinfo.UserID) http.Redirect(w, r, "/hfcs", http.StatusSeeOther) return } @@ -1912,7 +1912,7 @@ func savehfcs(w http.ResponseWriter, r *http.Request) { log.Printf("error saving filter: %s", err) } - filtcache.Clear(userinfo.UserID) + filtInvalidator.Clear(userinfo.UserID) http.Redirect(w, r, "/hfcs", http.StatusSeeOther) }