all repos — honk @ dc081988e58738d4f2b6749d088bd5dd2753b46b

my fork of honk

the gods have spoken
Anirudh Oppiliappan x@icyphox.sh
Tue, 18 Jul 2023 18:44:09 +0300
commit

dc081988e58738d4f2b6749d088bd5dd2753b46b

parent

9d1ce56876d246a178bd9a6faf9711877353ce9e

M MakefileMakefile

@@ -2,7 +2,7 @@

all: honk honk: .preflightcheck schema.sql *.go go.mod - go build -mod=`ls -d vendor 2> /dev/null` -o honk + env CGO_ENABLED=1 go build -mod=`ls -d vendor 2> /dev/null` -o honk .preflightcheck: preflight.sh @sh ./preflight.sh
M activity.goactivity.go

@@ -507,42 +507,57 @@ return ""

} var re_mast0link = regexp.MustCompile(`https://[[:alnum:].]+/users/[[:alnum:]]+/statuses/[[:digit:]]+`) -var re_masto1ink = regexp.MustCompile(`https://[[:alnum:].]+/@[[:alnum:]]+/[[:digit:]]+`) +var re_masto1ink = regexp.MustCompile(`https://([[:alnum:].]+)/@([[:alnum:]]+)/([[:digit:]]+)`) var re_misslink = regexp.MustCompile(`https://[[:alnum:].]+/notes/[[:alnum:]]+`) var re_honklink = regexp.MustCompile(`https://[[:alnum:].]+/u/[[:alnum:]]+/h/[[:alnum:]]+`) var re_r0malink = regexp.MustCompile(`https://[[:alnum:].]+/objects/[[:alnum:]-]+`) var re_roma1ink = regexp.MustCompile(`https://[[:alnum:].]+/notice/[[:alnum:]]+`) var re_qtlinks = regexp.MustCompile(`>https://[^\s<]+<`) -func qutify(user *WhatAbout, content string) string { - // well this is gross - malcontent := strings.ReplaceAll(content, `</span><span class="ellipsis">`, "") - malcontent = strings.ReplaceAll(malcontent, `</span><span class="invisible">`, "") - mlinks := re_qtlinks.FindAllString(malcontent, -1) - for _, m := range mlinks { - m = m[1 : len(m)-1] - if re_mast0link.MatchString(m) || re_masto1ink.MatchString(m) || - re_misslink.MatchString(m) || - re_honklink.MatchString(m) || - re_r0malink.MatchString(m) || re_roma1ink.MatchString(m) { - j, err := GetJunk(user.ID, m) - if err == nil { - q, ok := j.GetString("content") - if ok { - content = fmt.Sprintf("%s<blockquote>%s</blockquote>", content, q) - } - } - } - } - return content -} - func xonksaver(user *WhatAbout, item junk.Junk, origin string) *Honk { depth := 0 maxdepth := 10 currenttid := "" goingup := 0 var xonkxonkfn func(item junk.Junk, origin string, isUpdate bool) *Honk + + qutify := func(user *WhatAbout, content string) string { + if depth >= maxdepth { + ilog.Printf("in too deep") + return content + } + // well this is gross + malcontent := strings.ReplaceAll(content, `</span><span class="ellipsis">`, "") + malcontent = strings.ReplaceAll(malcontent, `</span><span class="invisible">`, "") + mlinks := re_qtlinks.FindAllString(malcontent, -1) + for _, m := range mlinks { + tryit := false + m = m[1 : len(m)-1] + if re_mast0link.MatchString(m) || re_misslink.MatchString(m) || + re_honklink.MatchString(m) || re_r0malink.MatchString(m) || + re_roma1ink.MatchString(m) { + tryit = true + } else if re_masto1ink.MatchString(m) { + m = re_masto1ink.ReplaceAllString(m, "https://$1/users/$2/statuses/$3") + tryit = true + } + if tryit { + if x := getxonk(user.ID, m); x != nil { + content = fmt.Sprintf("%s<blockquote>%s</blockquote>", content, x.Noise) + } else if j, err := GetJunk(user.ID, m); err == nil { + q, ok := j.GetString("content") + if ok { + content = fmt.Sprintf("%s<blockquote>%s</blockquote>", content, q) + } + prevdepth := depth + depth = maxdepth + xonkxonkfn(j, originate(m), false) + depth = prevdepth + } + } + } + return content + } saveonemore := func(xid string) { dlog.Printf("getting onemore: %s", xid)

@@ -830,9 +845,6 @@ }

if ot == "Move" { targ, _ := obj.GetString("target") content += string(templates.Sprintf(`<p>Moved to <a href="%s">%s</a>`, targ, targ)) - } - if what == "honk" && rid != "" { - what = "tonk" } if len(content) > 90001 { ilog.Printf("content too long. truncating")

@@ -1219,8 +1231,6 @@ }

switch h.What { case "update": - fallthrough - case "tonk": fallthrough case "event": fallthrough
M admin.goadmin.go

@@ -125,7 +125,7 @@ C.tcsetattr(1, C.TCSAFLUSH, savedtio)

} defer restore() go func() { - sig := make(chan os.Signal) + sig := make(chan os.Signal, 1) signal.Notify(sig, os.Interrupt) <-sig restore()
M database.godatabase.go

@@ -305,6 +305,26 @@ }

if t == "" { continue } + if t == "@me" { + queries = append(queries, "whofore = 1") + continue + } + if t == "@self" { + queries = append(queries, "(whofore = 2 or whofore = 3)") + continue + } + if strings.HasPrefix(t, "before:") { + before := t[7:] + queries = append(queries, "dt < ?") + params = append(params, before) + continue + } + if strings.HasPrefix(t, "after:") { + after := t[6:] + queries = append(queries, "dt > ?") + params = append(params, after) + continue + } if strings.HasPrefix(t, "site:") { site := t[5:] site = "%" + site + "%"

@@ -486,8 +506,6 @@ if err != nil {

elog.Printf("error parsing badonks: %s", err) continue } - case "wonkles": - case "guesses": case "oldrev": default: elog.Printf("unknown meta genus: %s", genus)

@@ -1161,14 +1179,14 @@ limit := " order by honks.honkid desc limit 250"

smalllimit := " order by honks.honkid desc limit ?" butnotthose := " and convoy not in (select name from zonkers where userid = ? and wherefore = 'zonvoy' order by zonkerid desc limit 100)" stmtOneXonk = preparetodie(db, selecthonks+"where honks.userid = ? and xid = ?") - stmtAnyXonk = preparetodie(db, selecthonks+"where xid = ? order by honks.honkid asc") + stmtAnyXonk = preparetodie(db, selecthonks+"where xid = ? and what <> 'bonk' order by honks.honkid asc") stmtOneBonk = preparetodie(db, selecthonks+"where honks.userid = ? and xid = ? and what = 'bonk' and whofore = 2") stmtPublicHonks = preparetodie(db, selecthonks+"where whofore = 2 and dt > ?"+smalllimit) stmtEventHonks = preparetodie(db, selecthonks+"where (whofore = 2 or honks.userid = ?) and what = 'event'"+smalllimit) stmtUserHonks = preparetodie(db, selecthonks+"where honks.honkid > ? and (whofore = 2 or whofore = ?) and username = ? and dt > ?"+smalllimit) myhonkers := " and honker in (select xid from honkers where userid = ? and (flavor = 'sub' or flavor = 'peep' or flavor = 'presub') and combos not like '% - %')" stmtHonksForUser = preparetodie(db, selecthonks+"where honks.honkid > ? and honks.userid = ? and dt > ?"+myhonkers+butnotthose+limit) - stmtHonksForUserFirstClass = preparetodie(db, selecthonks+"where honks.honkid > ? and honks.userid = ? and dt > ? and (what <> 'tonk')"+myhonkers+butnotthose+limit) + stmtHonksForUserFirstClass = preparetodie(db, selecthonks+"where honks.honkid > ? and honks.userid = ? and dt > ? and (rid = '' or what = 'bonk')"+myhonkers+butnotthose+limit) stmtHonksForMe = preparetodie(db, selecthonks+"where honks.honkid > ? and honks.userid = ? and dt > ? and whofore = 1"+butnotthose+limit) stmtHonksFromLongAgo = preparetodie(db, selecthonks+"where honks.honkid > ? and honks.userid = ? and dt > ? and dt < ? and whofore = 2"+butnotthose+limit) stmtHonksISaved = preparetodie(db, selecthonks+"where honks.honkid > ? and honks.userid = ? and flags & 4 order by honks.honkid desc")
M docs/changelog.txtdocs/changelog.txt

@@ -2,6 +2,10 @@ changelog

=== next ++ New threaded display order. + ++ Improved search. + + Tuned up superdeliverator. + Import from instagram.
M docs/honk.1docs/honk.1

@@ -143,10 +143,18 @@ .Ss Search

Find old honks. It's basic substring match with a few extensions. The following keywords are supported: -.Bl -tag -width honker -.It site +.Bl -tag -width honker: +.It @me +Honks mentioning the user. +.It @self +Honks by the user. +.It before: +Honks posted before YYYY-MM-DD. +.It after: +As above. +.It site: Substring match on the post domain name. -.It honker +.It honker: Exact match, either AP actor or honker nickname. .It - Negate term.
M fun.gofun.go

@@ -93,7 +93,7 @@ for _, h := range honks {

// idk where else to put this h.DatePretty = prettifydate(h.Date) h.What += "ed" - if h.What == "tonked" { + if h.What == "honked" && h.RID != "" { h.What = "honked back" h.Style += " subtle" }

@@ -238,7 +238,8 @@

func translatechonk(ch *Chonk) { noise := ch.Noise if ch.Format == "markdown" { - noise = markitzero(noise) + var marker mz.Marker + noise = marker.Mark(noise) } var htf htfilter.Filter htf.SpanClasses = allowedclasses

@@ -327,7 +328,8 @@ } else {

honk.Precis = noise[:idx] noise = noise[idx+1:] } - honk.Precis = markitzero(strings.TrimSpace(honk.Precis)) + var marker mz.Marker + honk.Precis = marker.Mark(strings.TrimSpace(honk.Precis)) honk.Noise = noise } }

@@ -574,7 +576,7 @@ return fmt.Sprintf(fill, html.EscapeString(where), html.EscapeString(who))

} func ontoreplacer(h string) string { - return fmt.Sprintf(`<a href="https://%s/o/%s">%s</a>`, serverName, + return fmt.Sprintf(`<a class="mention hashtag" href="https://%s/o/%s">%s</a>`, serverName, strings.ToLower(h[1:]), h) }

@@ -719,13 +721,9 @@ zaggies.Clear(keyname)

} func keymatch(keyname string, actor string) string { - hash := strings.IndexByte(keyname, '#') - if hash == -1 { - hash = len(keyname) - } - owner := keyname[0:hash] - if owner == actor { - return originate(actor) + origin := originate(actor) + if origin == originate(keyname) { + return origin } return "" }
M go.modgo.mod

@@ -6,11 +6,9 @@ require (

github.com/andybalholm/cascadia v1.3.1 github.com/dustin/go-humanize v1.0.0 github.com/gorilla/mux v1.8.0 - github.com/kr/pretty v0.3.1 // indirect github.com/mattn/go-runewidth v0.0.13 - github.com/sassoftware/relic v7.2.1+incompatible golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4 humungus.tedunangst.com/r/go-sqlite3 v1.1.3 - humungus.tedunangst.com/r/webs v0.6.61 + humungus.tedunangst.com/r/webs v0.6.62 )
M go.sumgo.sum

@@ -1,23 +1,13 @@

github.com/andybalholm/cascadia v1.3.1 h1:nhxRkql1kdYCc8Snf7D5/D3spOX+dBgjA6u8x004T2c= github.com/andybalholm/cascadia v1.3.1/go.mod h1:R4bJ1UQfqADjvDa4P6HZHLh/3OxWWEqc0Sk8XGwHqvA= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= -github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= -github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= -github.com/sassoftware/relic v7.2.1+incompatible h1:Pwyh1F3I0r4clFJXkSI8bOyJINGqpgjJU3DYAZeI05A= -github.com/sassoftware/relic v7.2.1+incompatible/go.mod h1:CWfAxv73/iLZ17rbyhIEq3K9hs5w6FpNMdUT//qR+zk= golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 h1:kUhD7nTDoI3fVd9G4ORWrbV5NY0liEs/Jg2pv5f+bBA= golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/image v0.0.0-20220413100746-70e8d0d3baa9 h1:LRtI4W37N+KFebI/qV0OFiLUv4GLOWeEW5hn/KEJvxE=

@@ -37,5 +27,5 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=

golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= humungus.tedunangst.com/r/go-sqlite3 v1.1.3 h1:G2N4wzDS0NbuvrZtQJhh4F+3X+s7BF8b9ga8k38geUI= humungus.tedunangst.com/r/go-sqlite3 v1.1.3/go.mod h1:FtEEmQM7U2Ey1TuEEOyY1BmphTZnmiEjPsNLEAkpf/M= -humungus.tedunangst.com/r/webs v0.6.61 h1:Sgy0Htb8Y0jmmLPp73nYDuD4NebeUsgXftP+wB86wSg= -humungus.tedunangst.com/r/webs v0.6.61/go.mod h1:03R0N9BcT49HB4TDd1YmarpbiPvPzVDm74Mk4h1hYPc= +humungus.tedunangst.com/r/webs v0.6.62 h1:T/T0a2xWw1cYKTMqKXwP4GStRPUfOWYytN9zCMMlqpA= +humungus.tedunangst.com/r/webs v0.6.62/go.mod h1:03R0N9BcT49HB4TDd1YmarpbiPvPzVDm74Mk4h1hYPc=
M honk.gohonk.go

@@ -159,7 +159,6 @@ flagIsBonked = 2

flagIsSaved = 4 flagIsUntagged = 8 flagIsReacted = 16 - flagIsWonked = 32 ) func (honk *Honk) IsAcked() bool {
M import.goimport.go

@@ -148,9 +148,6 @@ Whofore: 2,

Format: "html", Precis: toot.Object.Summary, } - if honk.RID != "" { - honk.What = "tonk" - } if !loudandproud(honk.Audience) { honk.Whofore = 3 }

@@ -387,13 +384,11 @@ what := "honk"

noise := "" if parent := tweetmap[t.Tweet.InReplyToStatusID]; parent != nil { t.convoy = parent.convoy - what = "tonk" } else { t.convoy = "data:,acoustichonkytonk-" + t.Tweet.IdStr if t.Tweet.InReplyToScreenName != "" { noise = fmt.Sprintf("re: https://twitter.com/%s/status/%s\n\n", t.Tweet.InReplyToScreenName, t.Tweet.InReplyToStatusID) - what = "tonk" } } audience := []string{thewholeworld}
D markitzero.go

@@ -1,25 +0,0 @@

-// -// Copyright (c) 2019 Ted Unangst <tedu@tedunangst.com> -// -// Permission to use, copy, modify, and distribute this software for any -// purpose with or without fee is hereby granted, provided that the above -// copyright notice and this permission notice appear in all copies. -// -// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -package main - -import ( - "humungus.tedunangst.com/r/webs/mz" -) - -func markitzero(s string) string { - var marker mz.Marker - return marker.Mark(s) -}
M unveil.gounveil.go

@@ -25,11 +25,10 @@ */

import "C" import ( - "fmt" "unsafe" ) -func Unveil(path string, perms string) error { +func Unveil(path string, perms string) { cpath := C.CString(path) defer C.free(unsafe.Pointer(cpath)) cperms := C.CString(perms)

@@ -37,20 +36,18 @@ defer C.free(unsafe.Pointer(cperms))

rv, err := C.unveil(cpath, cperms) if rv != 0 { - return fmt.Errorf("unveil(%s, %s) failure (%d)", path, perms, err) + elog.Fatalf("unveil(%s, %s) failure (%d)", path, perms, err) } - return nil } -func Pledge(promises string) error { +func Pledge(promises string) { cpromises := C.CString(promises) defer C.free(unsafe.Pointer(cpromises)) rv, err := C.pledge(cpromises, nil) if rv != 0 { - return fmt.Errorf("pledge(%s) failure (%d)", promises, err) + elog.Fatalf("pledge(%s) failure (%d)", promises, err) } - return nil } func init() {
M upgradedb.goupgradedb.go

@@ -18,11 +18,9 @@

import ( "database/sql" "os" - "strings" - "time" ) -var myVersion = 42 +var myVersion = 43 type dbexecer interface { Exec(query string, args ...interface{}) (sql.Result, error)

@@ -41,164 +39,10 @@ dbversion := 0

getconfig("dbversion", &dbversion) getconfig("servername", &serverName) - if dbversion < 13 { + if dbversion < 40 { elog.Fatal("database is too old to upgrade") } switch dbversion { - case 25: - doordie(db, "delete from auth") - doordie(db, "alter table auth add column expiry text") - doordie(db, "update config set value = 26 where key = 'dbversion'") - fallthrough - case 26: - s := "" - getconfig("servermsg", &s) - if s == "" { - setconfig("servermsg", "<h2>Things happen.</h2>") - } - s = "" - getconfig("aboutmsg", &s) - if s == "" { - setconfig("aboutmsg", "<h3>What is honk?</h3><p>Honk is amazing!") - } - s = "" - getconfig("loginmsg", &s) - if s == "" { - setconfig("loginmsg", "<h2>login</h2>") - } - d := -1 - getconfig("devel", &d) - if d == -1 { - setconfig("devel", 0) - } - doordie(db, "update config set value = 27 where key = 'dbversion'") - fallthrough - case 27: - createserveruser(db) - doordie(db, "update config set value = 28 where key = 'dbversion'") - fallthrough - case 28: - doordie(db, "drop table doovers") - doordie(db, "create table doovers(dooverid integer primary key, dt text, tries integer, userid integer, rcpt text, msg blob)") - doordie(db, "update config set value = 29 where key = 'dbversion'") - fallthrough - case 29: - doordie(db, "alter table honkers add column owner text") - doordie(db, "update honkers set owner = xid") - doordie(db, "update config set value = 30 where key = 'dbversion'") - fallthrough - case 30: - tx, err := db.Begin() - if err != nil { - elog.Fatal(err) - } - rows, err := tx.Query("select userid, options from users") - if err != nil { - elog.Fatal(err) - } - m := make(map[int64]string) - for rows.Next() { - var userid int64 - var options string - err = rows.Scan(&userid, &options) - if err != nil { - elog.Fatal(err) - } - var uo UserOptions - uo.SkinnyCSS = strings.Contains(options, " skinny ") - m[userid], err = jsonify(uo) - if err != nil { - elog.Fatal(err) - } - } - rows.Close() - for u, o := range m { - _, err = tx.Exec("update users set options = ? where userid = ?", o, u) - if err != nil { - elog.Fatal(err) - } - } - err = tx.Commit() - if err != nil { - elog.Fatal(err) - } - doordie(db, "update config set value = 31 where key = 'dbversion'") - fallthrough - case 31: - doordie(db, "create table tracks (xid text, fetches text)") - doordie(db, "create index idx_trackhonkid on tracks(xid)") - doordie(db, "update config set value = 32 where key = 'dbversion'") - fallthrough - case 32: - doordie(db, "alter table xonkers add column dt text") - doordie(db, "update xonkers set dt = ?", time.Now().UTC().Format(dbtimeformat)) - doordie(db, "update config set value = 33 where key = 'dbversion'") - fallthrough - case 33: - doordie(db, "alter table honkers add column meta text") - doordie(db, "update honkers set meta = '{}'") - doordie(db, "update config set value = 34 where key = 'dbversion'") - fallthrough - case 34: - doordie(db, "create table chonks (chonkid integer primary key, userid integer, xid text, who txt, target text, dt text, noise text, format text)") - doordie(db, "update config set value = 35 where key = 'dbversion'") - fallthrough - case 35: - doordie(db, "alter table donks add column chonkid integer") - doordie(db, "update donks set chonkid = -1") - doordie(db, "create index idx_donkshonk on donks(honkid)") - doordie(db, "create index idx_donkschonk on donks(chonkid)") - doordie(db, "update config set value = 36 where key = 'dbversion'") - fallthrough - case 36: - doordie(db, "alter table honkers add column folxid text") - doordie(db, "update honkers set folxid = 'lostdata'") - doordie(db, "update config set value = 37 where key = 'dbversion'") - fallthrough - case 37: - doordie(db, "update honkers set combos = '' where combos is null") - doordie(db, "update honkers set owner = '' where owner is null") - doordie(db, "update honkers set meta = '' where meta is null") - doordie(db, "update honkers set folxid = '' where folxid is null") - doordie(db, "update config set value = 38 where key = 'dbversion'") - fallthrough - case 38: - doordie(db, "update honkers set folxid = abs(random())") - doordie(db, "update config set value = 39 where key = 'dbversion'") - fallthrough - case 39: - blobdb := openblobdb() - doordie(blobdb, "alter table filedata add column hash text") - doordie(blobdb, "create index idx_filehash on filedata(hash)") - rows, err := blobdb.Query("select xid, content from filedata") - if err != nil { - elog.Fatal(err) - } - m := make(map[string]string) - for rows.Next() { - var xid string - var data sql.RawBytes - err := rows.Scan(&xid, &data) - if err != nil { - elog.Fatal(err) - } - hash := hashfiledata(data) - m[xid] = hash - } - rows.Close() - tx, err := blobdb.Begin() - if err != nil { - elog.Fatal(err) - } - for xid, hash := range m { - doordie(tx, "update filedata set hash = ? where xid = ?", hash, xid) - } - err = tx.Commit() - if err != nil { - elog.Fatal(err) - } - doordie(db, "update config set value = 40 where key = 'dbversion'") - fallthrough case 40: doordie(db, "PRAGMA journal_mode=WAL") blobdb := openblobdb()

@@ -238,6 +82,11 @@ }

doordie(db, "update config set value = 42 where key = 'dbversion'") fallthrough case 42: + doordie(db, "update honks set what = 'honk', flags = flags & ~ 32 where what = 'tonk' or what = 'wonk'") + doordie(db, "delete from honkmeta where genus = 'wonkles' or genus = 'guesses'") + doordie(db, "update config set value = 43 where key = 'dbversion'") + fallthrough + case 43: default: elog.Fatalf("can't upgrade unknown version %d", dbversion)
M util.goutil.go

@@ -90,7 +90,7 @@ defer func() {

os.Remove(dbname) os.Exit(1) }() - c := make(chan os.Signal) + c := make(chan os.Signal, 1) signal.Notify(c, os.Interrupt) go func() { <-c

@@ -209,7 +209,7 @@ db := opendatabase()

defer func() { os.Exit(1) }() - c := make(chan os.Signal) + c := make(chan os.Signal, 1) signal.Notify(c, os.Interrupt) go func() { <-c

@@ -263,7 +263,7 @@ }

defer func() { os.Exit(1) }() - c := make(chan os.Signal) + c := make(chan os.Signal, 1) signal.Notify(c, os.Interrupt) go func() { <-c
M web.goweb.go

@@ -365,7 +365,7 @@ return

} what, _ := j.GetString("type") obj, _ := j.GetString("object") - if what == "Like" || (what == "EmojiReact" && originate(obj) != serverName) { + if what == "Like" || what == "Dislike" || (what == "EmojiReact" && originate(obj) != serverName) { return } who, _ := j.GetString("actor")

@@ -724,14 +724,19 @@ }

return } u := login.GetUserInfo(r) - honks := gethonksbyuser(name, u != nil && u.Username == name, 0) + if u != nil && u.Username != name { + u = nil + } + honks := gethonksbyuser(name, u != nil, 0) templinfo := getInfo(r) templinfo["PageName"] = "user" templinfo["PageArg"] = name templinfo["Name"] = user.Name templinfo["WhatAbout"] = user.HTAbout templinfo["ServerMessage"] = "" - templinfo["HonkCSRF"] = login.GetCSRF("honkhonk", r) + if u != nil { + templinfo["HonkCSRF"] = login.GetCSRF("honkhonk", r) + } honkpage(w, u, honks, templinfo) }

@@ -1019,6 +1024,17 @@ trackchan <- Track{xid: xid, who: who}

} } +func sameperson(h1, h2 *Honk) bool { + n1, n2 := h1.Honker, h2.Honker + if h1.Oonker != "" { + n1 = h1.Oonker + } + if h2.Oonker != "" { + n2 = h2.Oonker + } + return n1 == n2 +} + func threadsort(honks []*Honk) []*Honk { sort.Slice(honks, func(i, j int) bool { return honks[i].Date.Before(honks[j].Date)

@@ -1036,7 +1052,7 @@ var nextlevel func(p *Honk)

level := 0 nextlevel = func(p *Honk) { levelup := level < 4 - if pp := honkx[p.RID]; p.RID == "" || (pp != nil && p.Honker == pp.Honker) { + if pp := honkx[p.RID]; p.RID == "" || (pp != nil && sameperson(p, pp)) { levelup = false } if level > 0 && len(kids[p.RID]) == 1 {

@@ -1050,7 +1066,7 @@ }

p.Style += fmt.Sprintf(" level%d", level) childs := kids[p.XID] sort.SliceStable(childs, func(i, j int) bool { - return childs[i].Honker == p.Honker && childs[j].Honker != p.Honker + return sameperson(childs[i], p) && !sameperson(childs[j], p) }) for _, h := range childs { if !done[h] {

@@ -1174,7 +1190,9 @@ }

} templinfo["ServerMessage"] = "one honk maybe more" - templinfo["HonkCSRF"] = login.GetCSRF("honkhonk", r) + if u != nil { + templinfo["HonkCSRF"] = login.GetCSRF("honkhonk", r) + } templinfo["APAltLink"] = templates.Sprintf("<link href='%s' rel='alternate' type='application/activity+json'>", xid) honkpage(w, u, honks, templinfo) }

@@ -1722,9 +1740,6 @@ honk.Format = format

} else { xid := fmt.Sprintf("%s/%s/%s", user.URL, honkSep, xfiltrate()) what := "honk" - if rid != "" { - what = "tonk" - } honk = &Honk{ UserID: userinfo.UserID, Username: userinfo.Username,

@@ -2644,6 +2659,7 @@ return

} defer fd.Close() io.Copy(fd, r.Body) + fd.WriteString("\n") } var endoftheworld = make(chan bool)

@@ -2651,7 +2667,7 @@ var readyalready = make(chan bool)

var workinprogress = 0 func enditall() { - sig := make(chan os.Signal) + sig := make(chan os.Signal, 1) signal.Notify(sig, os.Interrupt, syscall.SIGTERM, syscall.SIGQUIT) <-sig ilog.Printf("stopping...")