all repos — honk @ c95afc9403e5987b1c18be3edd55f2d4a06b8475

my fork of honk

finish up the hfcs filtering work
Ted Unangst tedu@tedunangst.com
Sun, 06 Oct 2019 20:26:21 -0400
commit

c95afc9403e5987b1c18be3edd55f2d4a06b8475

parent

3a8a2d07ff9708f21f2189686066356b17963c90

7 files changed, 160 insertions(+), 69 deletions(-)

jump to
M database.godatabase.go

@@ -515,7 +515,7 @@ var stmtThumbBiters, stmtDeleteHonk, stmtDeleteDonks, stmtDeleteOnts, stmtSaveZonker *sql.Stmt

var stmtGetZonkers, stmtRecentHonkers, stmtGetXonker, stmtSaveXonker, stmtDeleteXonker *sql.Stmt var stmtSelectOnts, stmtSaveOnt, stmtUpdateFlags, stmtClearFlags *sql.Stmt var stmtHonksForUserFirstClass, stmtSaveMeta, stmtDeleteMeta, stmtUpdateHonk *sql.Stmt -var stmtGetFilters *sql.Stmt +var stmtGetFilters, stmtSaveFilter, stmtDeleteFilter *sql.Stmt func preparetodie(db *sql.DB, s string) *sql.Stmt { stmt, err := db.Prepare(s)

@@ -583,4 +583,6 @@ stmtUpdateFlags = preparetodie(db, "update honks set flags = flags | ? where honkid = ?")

stmtClearFlags = preparetodie(db, "update honks set flags = flags & ~ ? where honkid = ?") stmtSelectOnts = preparetodie(db, "select distinct(ontology) from onts join honks on onts.honkid = honks.honkid where (honks.userid = ? or honks.whofore = 2)") stmtGetFilters = preparetodie(db, "select hfcsid, json from hfcs where userid = ?") + stmtSaveFilter = preparetodie(db, "insert into hfcs (userid, json) values (?, ?)") + stmtDeleteFilter = preparetodie(db, "delete from hfcs where userid = ? and hfcsid = ?") }
M fun.gofun.go

@@ -75,12 +75,8 @@ if h.Precis != "" {

h.Open = "" } } else { - if badword := unsee(userid, h); badword != "" { - if h.Precis == "" { - h.Precis = badword - } - h.Open = "" - } else if h.Precis == "unspecified horror" { + unsee(userid, h) + if h.Open == "open" && h.Precis == "unspecified horror" { h.Precis = "" } }
M hfcs.gohfcs.go

@@ -19,22 +19,28 @@ import (

"log" "net/http" "regexp" + "sort" + "time" ) type Filter struct { - ID int64 - Actor string - IncludeAudience bool - Text string + ID int64 `json:"-"` + Actions []filtType `json:"-"` + Name string + Date time.Time + Actor string `json:",omitempty"` + IncludeAudience bool `json:",omitempty"` + Text string `json:",omitempty"` re_text *regexp.Regexp - IsAnnounce bool - Reject bool - SkipMedia bool - Hide bool - Collapse bool - Rewrite string + IsAnnounce bool `json:",omitempty"` + AnnounceOf string `json:",omitempty"` + Reject bool `json:",omitempty"` + SkipMedia bool `json:",omitempty"` + Hide bool `json:",omitempty"` + Collapse bool `json:",omitempty"` + Rewrite string `json:",omitempty"` re_rewrite *regexp.Regexp - Replace string + Replace string `json:",omitempty"` } type filtType uint

@@ -85,23 +91,40 @@ log.Printf("error compiling filter text: %s", err)

continue } } + if filt.Rewrite != "" { + filt.re_rewrite, err = regexp.Compile("\\b(?i:" + filt.Rewrite + ")\\b") + if err != nil { + log.Printf("error compiling filter rewrite: %s", err) + continue + } + } filt.ID = filterid if filt.Reject { + filt.Actions = append(filt.Actions, filtReject) filtmap[filtReject] = append(filtmap[filtReject], filt) } if filt.SkipMedia { + filt.Actions = append(filt.Actions, filtSkipMedia) filtmap[filtSkipMedia] = append(filtmap[filtSkipMedia], filt) } if filt.Hide { + filt.Actions = append(filt.Actions, filtHide) filtmap[filtHide] = append(filtmap[filtHide], filt) } if filt.Collapse { + filt.Actions = append(filt.Actions, filtCollapse) filtmap[filtCollapse] = append(filtmap[filtCollapse], filt) } if filt.Rewrite != "" { + filt.Actions = append(filt.Actions, filtRewrite) filtmap[filtRewrite] = append(filtmap[filtRewrite], filt) } + filtmap[filtAny] = append(filtmap[filtAny], filt) } + sorting := filtmap[filtAny] + sort.Slice(filtmap[filtAny], func(i, j int) bool { + return sorting[i].Name < sorting[j].Name + }) return filtmap, true })

@@ -147,13 +170,12 @@ if agent != "" {

fake := rejectorigin(userid, agent) if fake { log.Printf("faking 404 for %s", agent) - return fake + return true } } return false } -// todo func matchfilter(h *Honk, f *Filter) bool { match := true if match && f.Actor != "" {

@@ -175,6 +197,13 @@ }

} } } + if match && f.IsAnnounce { + match = false + if (f.AnnounceOf == "" && h.Oonker != "") || f.AnnounceOf == h.Oonker || + f.AnnounceOf == originate(h.Oonker) { + match = true + } + } if match && f.Text != "" { match = false re := f.re_text

@@ -189,10 +218,7 @@ }

} } } - if match { - return true - } - return false + return match } func rejectxonk(xonk *Honk) bool {

@@ -215,15 +241,27 @@ }

return false } -// todo -func unsee(userid int64, h *Honk) string { +func unsee(userid int64, h *Honk) { filts := getfilters(userid, filtCollapse) for _, f := range filts { if matchfilter(h, f) { - return f.Text + bad := f.Text + if f.Actor != "" { + bad = f.Actor + } + if h.Precis == "" { + h.Precis = bad + } + h.Open = "" + break } } - return "" + filts = getfilters(userid, filtRewrite) + for _, f := range filts { + if matchfilter(h, f) { + h.Noise = f.re_rewrite.ReplaceAllString(h.Noise, f.Replace) + } + } } func osmosis(honks []*Honk, userid int64) []*Honk {
M views/header.htmlviews/header.html

@@ -37,7 +37,7 @@ <li><a href="/o">tags</a>

<li><a href="/about">about</a> <li><a href="/front">front</a> <li><a href="/xzone">xzone</a> -<li><a href="/zonkzone">zonkzone</a> +<li><a href="/hfcs">hfcs</a> <li><a href="/funzone">funzone</a> <li><a href="/account">account</a> <li>
A views/hfcs.html

@@ -0,0 +1,51 @@

+{{ template "header.html" . }} +<main> +<div class="info"> +<p> +Honk Filtering and Censoring System +<form action="/savehfcs" method="POST"> +<input type="hidden" name="CSRF" value="{{ .FilterCSRF }}"> +<h3>new filter</h3> +<p><input tabindex=1 type="text" name="name" value="" autocomplete=off> - name +<h3>match</h3> +<p><input tabindex=1 type="text" name="actor" value="" autocomplete=off> - who/where +<p><span><label for="incaud">include audience:</label> +<input tabindex=1 type="checkbox" id="incaud" name="incaud" value="yes"><span></span></span> +<p><input tabindex=1 type="text" name="filttext" value="" autocomplete=off> - text +<p><span><label for="isannounce">is announce:</label> +<input tabindex=1 type="checkbox" id="isannounce" name="isannounce" value="yes"><span></span></span> +<p><input tabindex=1 type="text" name="announceof" value="" autocomplete=off> - announce of +<h3>action</h3> +<p><span><label for="doreject">reject:</label> +<input tabindex=1 type="checkbox" id="doreject" name="doreject" value="yes"><span></span></span> +<span><label for="doskipmedia">skip media:</label> +<input tabindex=1 type="checkbox" id="doskipmedia" name="doskipmedia" value="yes"><span></span></span> +<span><label for="dohide">hide:</label> +<input tabindex=1 type="checkbox" id="dohide" name="dohide" value="yes"><span></span></span> +<span><label for="docollapse">collapse:</label> +<input tabindex=1 type="checkbox" id="docollapse" name="docollapse" value="yes"><span></span></span> +<p><input tabindex=1 type="text" name="filtrewrite" value="" autocomplete=off> - rewrite +<p><input tabindex=1 type="text" name="filtreplace" value="" autocomplete=off> - replace +<p><button>impose your will</button> +</form> +</div> +{{ $csrf := .FilterCSRF }} +{{ range .Filters }} +<section class="honk"> +<p>Name: {{ .Name }} +<p>Date: {{ .Date.Format "2006-01-02" }} +{{ with .Actor }}<p>Who: {{ . }}{{ end }} {{ with .IncludeAudience }} (inclusive) {{ end }} +{{ with .Text }}<p>Text: {{ . }}{{ end }} +<p>Actions: {{ range .Actions }} {{ . }} {{ end }} +{{ with .Rewrite }}<p>Rewrite: {{ . }}{{ end }} +{{ with .Replace }}<p>Replace: {{ . }}{{ end }} +<form action="/savehfcs" method="POST"> +<input type="hidden" name="CSRF" value="{{ $csrf }}"> +<input type="hidden" name="hfcsid" value="{{ .ID }}"> +<input type="hidden" name="itsok" value="iforgiveyou"> +<button name="pardon" value="pardon">pardon</button> +</form> +<p> +</section> +{{ end }} +</main>
D views/zonkers.html

@@ -1,24 +0,0 @@

-{{ template "header.html" . }} -<main> -<div class="info"> -<p> -Work in progress -</div> -{{ $zonkcsrf := .ZonkCSRF }} -{{ range $how, $filters := .Filters }} -{{ range $filters }} -<section class="honk"> -<p>How: {{ $how }} -{{ with .Actor }}<p>Who: {{ . }}{{ end }} -{{ with .Text }}<p>What: {{ . }}{{ end }} -<form action="/zonkzonk" method="POST"> -<input type="hidden" name="CSRF" value="{{ $zonkcsrf }}"> -<input type="hidden" name="zonkerid" value="{{ .ID }}"> -<input type="hidden" name="itsok" value="iforgiveyou"> -<button name="pardon" value="pardon">pardon</button> -</form> -<p> -</section> -{{ end }} -{{ end }} -</main>
M web.goweb.go

@@ -1237,36 +1237,64 @@ }

http.Redirect(w, r, "/honkers", http.StatusSeeOther) } -func zonkzone(w http.ResponseWriter, r *http.Request) { +func hfcspage(w http.ResponseWriter, r *http.Request) { userinfo := login.GetUserInfo(r) - var filters afiltermap - filtcache.Get(userinfo.UserID, &filters) + filters := getfilters(userinfo.UserID, filtAny) templinfo := getInfo(r) templinfo["Filters"] = filters - templinfo["ZonkCSRF"] = login.GetCSRF("zonkzonk", r) - err := readviews.Execute(w, "zonkers.html", templinfo) + templinfo["FilterCSRF"] = login.GetCSRF("filter", r) + err := readviews.Execute(w, "hfcs.html", templinfo) if err != nil { log.Print(err) } } -// todo -func zonkzonk(w http.ResponseWriter, r *http.Request) { +func savehfcs(w http.ResponseWriter, r *http.Request) { userinfo := login.GetUserInfo(r) itsok := r.FormValue("itsok") if itsok == "iforgiveyou" { - zonkerid, _ := strconv.ParseInt(r.FormValue("zonkerid"), 10, 0) - db := opendatabase() - db.Exec("delete from hfcs where userid = ? and hfcsid = ?", - userinfo.UserID, zonkerid) + hfcsid, _ := strconv.ParseInt(r.FormValue("hfcsid"), 10, 0) + _, err := stmtDeleteFilter.Exec(userinfo.UserID, hfcsid) + if err != nil { + log.Printf("error deleting filter: %s", err) + } filtcache.Clear(userinfo.UserID) - http.Redirect(w, r, "/zonkzone", http.StatusSeeOther) + http.Redirect(w, r, "/hfcs", http.StatusSeeOther) return } - http.Redirect(w, r, "/zonkzone", http.StatusSeeOther) + filt := new(Filter) + filt.Name = r.FormValue("name") + filt.Date = time.Now().UTC() + filt.Actor = r.FormValue("actor") + filt.IncludeAudience = r.FormValue("incaud") == "yes" + filt.Text = r.FormValue("filttext") + filt.IsAnnounce = r.FormValue("isannounce") == "yes" + filt.AnnounceOf = r.FormValue("announceof") + filt.Reject = r.FormValue("doreject") == "yes" + filt.SkipMedia = r.FormValue("doskipmedia") == "yes" + filt.Hide = r.FormValue("dohide") == "yes" + filt.Collapse = r.FormValue("docollapse") == "yes" + filt.Rewrite = r.FormValue("filtrewrite") + filt.Replace = r.FormValue("filtreplace") + + if filt.Actor == "" && filt.Text == "" { + log.Printf("blank filter") + return + } + + j, err := jsonify(filt) + if err == nil { + _, err = stmtSaveFilter.Exec(userinfo.UserID, j) + } + if err != nil { + log.Printf("error saving filter: %s", err) + } + + filtcache.Clear(userinfo.UserID) + http.Redirect(w, r, "/hfcs", http.StatusSeeOther) } func accountpage(w http.ResponseWriter, r *http.Request) {

@@ -1485,7 +1513,7 @@ readviews = templates.Load(debug,

"views/honkpage.html", "views/honkfrags.html", "views/honkers.html", - "views/zonkers.html", + "views/hfcs.html", "views/combos.html", "views/honkform.html", "views/honk.html",

@@ -1545,13 +1573,13 @@ loggedin.HandleFunc("/account", accountpage)

loggedin.HandleFunc("/funzone", showfunzone) loggedin.HandleFunc("/chpass", dochpass) loggedin.HandleFunc("/atme", homepage) - loggedin.HandleFunc("/zonkzone", zonkzone) + loggedin.HandleFunc("/hfcs", hfcspage) loggedin.HandleFunc("/xzone", xzone) loggedin.HandleFunc("/edit", edithonkpage) loggedin.Handle("/honk", login.CSRFWrap("honkhonk", http.HandlerFunc(submithonk))) loggedin.Handle("/bonk", login.CSRFWrap("honkhonk", http.HandlerFunc(submitbonk))) loggedin.Handle("/zonkit", login.CSRFWrap("honkhonk", http.HandlerFunc(zonkit))) - loggedin.Handle("/zonkzonk", login.CSRFWrap("zonkzonk", http.HandlerFunc(zonkzonk))) + loggedin.Handle("/savehfcs", login.CSRFWrap("filter", http.HandlerFunc(savehfcs))) loggedin.Handle("/saveuser", login.CSRFWrap("saveuser", http.HandlerFunc(saveuser))) loggedin.Handle("/ximport", login.CSRFWrap("ximport", http.HandlerFunc(ximport))) loggedin.HandleFunc("/honkers", showhonkers)