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
+
+
+{{ $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" . }}
-
-
-{{ $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)