make it possible for filters to expire

This commit is contained in:
Ted Unangst 2019-10-21 02:28:35 -04:00
parent 9d89310be0
commit 37fd41892e
4 changed files with 53 additions and 4 deletions

33
hfcs.go
View File

@ -43,6 +43,7 @@ type Filter struct {
Rewrite string `json:",omitempty"` Rewrite string `json:",omitempty"`
re_rewrite *regexp.Regexp re_rewrite *regexp.Regexp
Replace string `json:",omitempty"` Replace string `json:",omitempty"`
Expiration time.Time
} }
type filtType uint type filtType uint
@ -65,7 +66,14 @@ func (ft filtType) String() string {
type afiltermap map[filtType][]*Filter type afiltermap map[filtType][]*Filter
var filtcache = cache.New(cache.Options{Filler: func(userid int64) (afiltermap, bool) { var filtcache *cache.Cache
func init() {
// resolve init loop
filtcache = cache.New(cache.Options{Filler: filtcachefiller})
}
func filtcachefiller(userid int64) (afiltermap, bool) {
rows, err := stmtGetFilters.Query(userid) rows, err := stmtGetFilters.Query(userid)
if err != nil { if err != nil {
log.Printf("error querying filters: %s", err) log.Printf("error querying filters: %s", err)
@ -73,6 +81,10 @@ var filtcache = cache.New(cache.Options{Filler: func(userid int64) (afiltermap,
} }
defer rows.Close() defer rows.Close()
now := time.Now()
var expflush time.Time
filtmap := make(afiltermap) filtmap := make(afiltermap)
for rows.Next() { for rows.Next() {
filt := new(Filter) filt := new(Filter)
@ -86,6 +98,14 @@ var filtcache = cache.New(cache.Options{Filler: func(userid int64) (afiltermap,
log.Printf("error scanning filter: %s", err) log.Printf("error scanning filter: %s", err)
continue continue
} }
if !filt.Expiration.IsZero() {
if filt.Expiration.Before(now) {
continue
}
if expflush.IsZero() || filt.Expiration.Before(expflush) {
expflush = filt.Expiration
}
}
if filt.Text != "" { if filt.Text != "" {
filt.re_text, err = regexp.Compile("\\b(?i:" + filt.Text + ")\\b") filt.re_text, err = regexp.Compile("\\b(?i:" + filt.Text + ")\\b")
if err != nil { if err != nil {
@ -127,8 +147,17 @@ var filtcache = cache.New(cache.Options{Filler: func(userid int64) (afiltermap,
sort.Slice(filtmap[filtAny], func(i, j int) bool { sort.Slice(filtmap[filtAny], func(i, j int) bool {
return sorting[i].Name < sorting[j].Name return sorting[i].Name < sorting[j].Name
}) })
if !expflush.IsZero() {
dur := expflush.Sub(now)
go filtcacheclear(userid, dur)
}
return filtmap, true return filtmap, true
}}) }
func filtcacheclear(userid int64, dur time.Duration) {
time.Sleep(dur + time.Second)
filtcache.Clear(userid)
}
func getfilters(userid int64, scope filtType) []*Filter { func getfilters(userid int64, scope filtType) []*Filter {
var filtmap afiltermap var filtmap afiltermap

12
honk.go
View File

@ -20,6 +20,7 @@ import (
"html/template" "html/template"
"log" "log"
"os" "os"
"strconv"
"strings" "strings"
"time" "time"
) )
@ -119,6 +120,17 @@ func (d Duration) String() string {
return s return s
} }
func parseDuration(s string) time.Duration {
didx := strings.IndexByte(s, 'd')
if didx != -1 {
days, _ := strconv.ParseInt(s[:didx], 10, 0)
dur, _ := time.ParseDuration(s[didx:])
return dur + 24*time.Hour*time.Duration(days)
}
dur, _ := time.ParseDuration(s)
return dur
}
type Time struct { type Time struct {
StartTime time.Time StartTime time.Time
EndTime time.Time EndTime time.Time

View File

@ -36,6 +36,10 @@ Honk Filtering and Censorship System
<p><label for="replace">replace:</label><br> <p><label for="replace">replace:</label><br>
<input tabindex=1 type="text" name="filtreplace" value="" autocomplete=off> <input tabindex=1 type="text" name="filtreplace" value="" autocomplete=off>
<hr> <hr>
<h3>expiration</h3>
<p><label for="filtduration">duration:</label><br>
<input tabindex=1 type="text" name="filtduration" value="" autocomplete=off>
<hr>
<p><button>impose your will</button> <p><button>impose your will</button>
</form> </form>
</div> </div>
@ -49,6 +53,7 @@ Honk Filtering and Censorship System
<p>Actions: {{ range .Actions }} {{ . }} {{ end }} <p>Actions: {{ range .Actions }} {{ . }} {{ end }}
{{ with .Rewrite }}<p>Rewrite: {{ . }}{{ end }} {{ with .Rewrite }}<p>Rewrite: {{ . }}{{ end }}
{{ with .Replace }}<p>Replace: {{ . }}{{ end }} {{ with .Replace }}<p>Replace: {{ . }}{{ end }}
{{ if not .Expiration.IsZero }}<p>Expiration: {{ .Expiration.Format "2006-01-02 03:04" }}{{ end }}
<form action="/savehfcs" method="POST"> <form action="/savehfcs" method="POST">
<input type="hidden" name="CSRF" value="{{ $csrf }}"> <input type="hidden" name="CSRF" value="{{ $csrf }}">
<input type="hidden" name="hfcsid" value="{{ .ID }}"> <input type="hidden" name="hfcsid" value="{{ .ID }}">

7
web.go
View File

@ -1217,8 +1217,8 @@ func submithonk(w http.ResponseWriter, r *http.Request) {
} }
} }
timeend := r.FormValue("timeend") timeend := r.FormValue("timeend")
dur, err := time.ParseDuration(timeend) dur := parseDuration(timeend)
if err == nil { if dur != 0 {
t.Duration = Duration(dur) t.Duration = Duration(dur)
} }
if !t.StartTime.IsZero() { if !t.StartTime.IsZero() {
@ -1460,6 +1460,9 @@ func savehfcs(w http.ResponseWriter, r *http.Request) {
filt.Collapse = r.FormValue("docollapse") == "yes" filt.Collapse = r.FormValue("docollapse") == "yes"
filt.Rewrite = strings.TrimSpace(r.FormValue("filtrewrite")) filt.Rewrite = strings.TrimSpace(r.FormValue("filtrewrite"))
filt.Replace = strings.TrimSpace(r.FormValue("filtreplace")) filt.Replace = strings.TrimSpace(r.FormValue("filtreplace"))
if dur := parseDuration(r.FormValue("filtduration")); dur > 0 {
filt.Expiration = time.Now().UTC().Add(dur)
}
if filt.Actor == "" && filt.Text == "" { if filt.Actor == "" && filt.Text == "" {
log.Printf("blank filter") log.Printf("blank filter")