diff --git a/database.go b/database.go index 212b24e..e52d98c 100644 --- a/database.go +++ b/database.go @@ -515,7 +515,7 @@ var stmtThumbBiters, stmtDeleteHonk, stmtDeleteDonks, stmtDeleteOnts, stmtSaveZo 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 @@ func prepareStatements(db *sql.DB) { 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 = ?") } diff --git a/fun.go b/fun.go index fb4ba81..e2a0b61 100644 --- a/fun.go +++ b/fun.go @@ -75,12 +75,8 @@ func reverbolate(userid int64, honks []*Honk) { 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 = "" } } diff --git a/hfcs.go b/hfcs.go index 30154e5..a19f854 100644 --- a/hfcs.go +++ b/hfcs.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 @@ var filtcache = cacheNew(func(userid int64) (afiltermap, bool) { 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 @@ func stealthmode(userid int64, r *http.Request) bool { 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 @@ func matchfilter(h *Honk, f *Filter) bool { } } } + 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 @@ func matchfilter(h *Honk, f *Filter) bool { } } } - if match { - return true - } - return false + return match } func rejectxonk(xonk *Honk) bool { @@ -215,15 +241,27 @@ func skipMedia(xonk *Honk) bool { 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 + } + } + filts = getfilters(userid, filtRewrite) + for _, f := range filts { + if matchfilter(h, f) { + h.Noise = f.re_rewrite.ReplaceAllString(h.Noise, f.Replace) } } - return "" } func osmosis(honks []*Honk, userid int64) []*Honk { diff --git a/views/header.html b/views/header.html index 81425c1..90c808d 100644 --- a/views/header.html +++ b/views/header.html @@ -37,7 +37,7 @@
  • about
  • front
  • xzone -
  • zonkzone +
  • hfcs
  • funzone
  • account
  • diff --git a/views/hfcs.html b/views/hfcs.html new file mode 100644 index 0000000..1e98909 --- /dev/null +++ b/views/hfcs.html @@ -0,0 +1,51 @@ +{{ template "header.html" . }} +
    +
    +

    +Honk Filtering and Censoring System +

    + +

    new filter

    +

    - name +

    match

    +

    - who/where +

    + +

    - text +

    + +

    - announce of +

    action

    +

    + + + + + + + +

    - rewrite +

    - replace +

    +

    +
    +{{ $csrf := .FilterCSRF }} +{{ range .Filters }} +
    +

    Name: {{ .Name }} +

    Date: {{ .Date.Format "2006-01-02" }} +{{ with .Actor }}

    Who: {{ . }}{{ end }} {{ with .IncludeAudience }} (inclusive) {{ end }} +{{ with .Text }}

    Text: {{ . }}{{ end }} +

    Actions: {{ range .Actions }} {{ . }} {{ end }} +{{ with .Rewrite }}

    Rewrite: {{ . }}{{ end }} +{{ with .Replace }}

    Replace: {{ . }}{{ end }} +

    + + + + +
    +

    +

    +{{ end }} +
    diff --git a/views/zonkers.html b/views/zonkers.html deleted file mode 100644 index 1a15b3c..0000000 --- a/views/zonkers.html +++ /dev/null @@ -1,24 +0,0 @@ -{{ template "header.html" . }} -
    -
    -

    -Work in progress -

    -{{ $zonkcsrf := .ZonkCSRF }} -{{ range $how, $filters := .Filters }} -{{ range $filters }} -
    -

    How: {{ $how }} -{{ with .Actor }}

    Who: {{ . }}{{ end }} -{{ with .Text }}

    What: {{ . }}{{ end }} -

    - - - - -
    -

    -

    -{{ end }} -{{ end }} -
    diff --git a/web.go b/web.go index 61ba082..71dcc12 100644 --- a/web.go +++ b/web.go @@ -1237,36 +1237,64 @@ func submithonker(w http.ResponseWriter, r *http.Request) { 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 @@ func serve() { "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 @@ func serve() { 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)