Boing boom tschak chonky chatter

This commit is contained in:
Ted Unangst 2020-05-13 17:15:29 -04:00
parent 8196f8b53e
commit 74b55fec6f
10 changed files with 174 additions and 2 deletions

View File

@ -607,6 +607,9 @@ func xonksaver(user *WhatAbout, item junk.Junk, origin string) *Honk {
case "Event":
obj = item
what = "event"
case "ChatMessage":
obj = item
what = "chonk"
default:
log.Printf("unknown activity: %s", what)
dumpactivity(item)
@ -876,6 +879,20 @@ func xonksaver(user *WhatAbout, item junk.Junk, origin string) *Honk {
}
imaginate(&xonk)
if what == "chonk" {
ch := Chonk{
UserID: xonk.UserID,
XID: xid,
Who: xonk.Honker,
Target: xonk.Honker,
Date: xonk.Date,
Noise: xonk.Noise,
Format: xonk.Format,
}
savechonk(&ch)
return nil
}
if isUpdate {
log.Printf("something has changed! %s", xonk.XID)
prev := getxonk(user.ID, xonk.XID)
@ -1246,6 +1263,35 @@ func boxuprcpts(user *WhatAbout, addresses []string, useshared bool) map[string]
return rcpts
}
func sendchonk(user *WhatAbout, ch *Chonk) {
dt := ch.Date.Format(time.RFC3339)
aud := []string{ch.Target}
jo := junk.New()
jo["id"] = ch.XID
jo["type"] = "ChatMessage"
jo["published"] = dt
jo["attributedTo"] = user.URL
jo["to"] = aud
jo["content"] = ch.Noise
j := junk.New()
j["@context"] = itiswhatitis
j["id"] = user.URL + "/" + "honk" + "/" + shortxid(ch.XID)
j["type"] = "Create"
j["actor"] = user.URL
j["published"] = dt
j["to"] = aud
j["object"] = jo
msg := j.ToBytes()
rcpts := make(map[string]bool)
rcpts[ch.Target] = true
for a := range rcpts {
go deliverate(0, user.ID, a, msg)
}
}
func honkworldwide(user *WhatAbout, honk *Honk) {
jonk, _ := jonkjonk(user, honk)
jonk["@context"] = itiswhatitis

View File

@ -482,6 +482,37 @@ func finddonk(url string) *Donk {
return nil
}
func savechonk(ch *Chonk) error {
dt := ch.Date.UTC().Format(dbtimeformat)
res, err := stmtSaveChonk.Exec(ch.UserID, ch.XID, ch.Who, ch.Target, dt, ch.Noise, ch.Format)
if err == nil {
ch.ID, _ = res.LastInsertId()
}
return err
}
func loadchatter(userid int64) map[string][]*Chonk {
rows, err := stmtLoadChonks.Query(userid)
if err != nil {
log.Printf("error loading chonks: %s", err)
return nil
}
defer rows.Close()
chonks := make(map[string][]*Chonk)
for rows.Next() {
ch := new(Chonk)
var dt string
err = rows.Scan(&ch.ID, &ch.UserID, &ch.XID, &ch.Who, &ch.Target, &dt, &ch.Noise, &ch.Format)
if err != nil {
log.Printf("error scanning chonk: %s", err)
continue
}
ch.Date, _ = time.Parse(dbtimeformat, dt)
chonks[ch.Target] = append(chonks[ch.Target], ch)
}
return chonks
}
func savehonk(h *Honk) error {
dt := h.Date.UTC().Format(dbtimeformat)
aud := strings.Join(h.Audience, " ")
@ -739,6 +770,7 @@ var stmtHonksForUserFirstClass *sql.Stmt
var stmtSaveMeta, stmtDeleteAllMeta, stmtDeleteSomeMeta, stmtUpdateHonk *sql.Stmt
var stmtHonksISaved, stmtGetFilters, stmtSaveFilter, stmtDeleteFilter *sql.Stmt
var stmtGetTracks *sql.Stmt
var stmtSaveChonk, stmtLoadChonks *sql.Stmt
func preparetodie(db *sql.DB, s string) *sql.Stmt {
stmt, err := db.Prepare(s)
@ -816,4 +848,6 @@ func prepareStatements(db *sql.DB) {
stmtSaveFilter = preparetodie(db, "insert into hfcs (userid, json) values (?, ?)")
stmtDeleteFilter = preparetodie(db, "delete from hfcs where userid = ? and hfcsid = ?")
stmtGetTracks = preparetodie(db, "select fetches from tracks where xid = ?")
stmtSaveChonk = preparetodie(db, "insert into chonks (userid, xid, who, target, dt, noise, format) values (?, ?, ?, ?, ?, ?, ?)")
stmtLoadChonks = preparetodie(db, "select chonkid, userid, xid, who, target, dt, noise, format from chonks where userid = ?")
}

View File

@ -2,6 +2,8 @@ changelog
=== next
++ Boing boom tschak chonky chatter.
+ Quote unquote reliability improvements.
+ Much better omit images handling.

17
fun.go
View File

@ -178,6 +178,23 @@ func replaceimgsand(zap map[string]bool, absolute bool) func(node *html.Node) st
}
}
func filterchonk(ch *Chonk) {
var htf htfilter.Filter
htf.SpanClasses = allowedclasses
htf.BaseURL, _ = url.Parse(ch.XID)
ch.HTML, _ = htf.String(ch.Noise)
n := string(ch.HTML)
if strings.HasPrefix(n, "<p>") {
ch.HTML = template.HTML(n[3:])
}
if short := shortname(ch.UserID, ch.Who); short != "" {
ch.Handle = short
} else {
_, ch.Handle = handles(ch.Who)
}
}
func inlineimgsfor(honk *Honk) func(node *html.Node) string {
return func(node *html.Node) string {
src := htfilter.GetAttr(node, "src")

13
honk.go
View File

@ -94,6 +94,19 @@ type Honk struct {
Mentions []Mention
}
type Chonk struct {
ID int64
UserID int64
XID string
Who string
Target string
Date time.Time
Noise string
Format string
Handle string
HTML template.HTML
}
type Mention struct {
Who string
Where string

View File

@ -3,6 +3,7 @@ package main
var sqlSchema = `
create table honks (honkid integer primary key, userid integer, what text, honker text, xid text, rid text, dt text, url text, audience text, noise text, convoy text, whofore integer, format text, precis text, oonker text, flags integer);
create table chonks (chonkid integer primary key, userid integer, xid text, who txt, target text, dt text, noise text, format text);
create table donks (honkid integer, fileid integer);
create table filemeta (fileid integer primary key, xid text, name text, description text, url text, media text, local integer);
create table honkers (honkerid integer primary key, userid integer, name text, xid text, flavor text, combos text, owner text, meta text);

View File

@ -1,5 +1,6 @@
create table honks (honkid integer primary key, userid integer, what text, honker text, xid text, rid text, dt text, url text, audience text, noise text, convoy text, whofore integer, format text, precis text, oonker text, flags integer);
create table chonks (chonkid integer primary key, userid integer, xid text, who txt, target text, dt text, noise text, format text);
create table donks (honkid integer, fileid integer);
create table filemeta (fileid integer primary key, xid text, name text, description text, url text, media text, local integer);
create table honkers (honkerid integer primary key, userid integer, name text, xid text, flavor text, combos text, owner text, meta text);

View File

@ -24,7 +24,7 @@ import (
"time"
)
var myVersion = 34
var myVersion = 35
func doordie(db *sql.DB, s string, args ...interface{}) {
_, err := db.Exec(s, args...)
@ -366,6 +366,10 @@ func upgradedb() {
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:
default:
log.Fatalf("can't upgrade unknown version %d", dbversion)

View File

@ -31,13 +31,13 @@
{{ end }}
</ul>
</details>
<li><a href="/chatter">chatter</a>
<li><a href="/o">tags</a>
<li><a href="/events">events</a>
<li><a id="savedlink" href="/saved">saved</a>
<li><a href="/honkers">honkers</a>
<li><a href="/hfcs">filters</a>
<li><a href="/{{ .UserSep }}/{{ .UserInfo.Username }}">my honks</a>
<li><a href="/xzone">xzone</a>
<li><a href="/account">account</a>
<li style="list-style-type:none; margin-left:-1em">
<details>
@ -46,6 +46,7 @@
<li><a href="/about">about</a>
<li><a href="/front">front</a>
<li><a href="/funzone">funzone</a>
<li><a href="/xzone">xzone</a>
</ul>
</details>
<li><a href="/help/honk.1.html">help</a>

53
web.go
View File

@ -1770,6 +1770,56 @@ func showhonkers(w http.ResponseWriter, r *http.Request) {
}
}
func showchatter(w http.ResponseWriter, r *http.Request) {
u := login.GetUserInfo(r)
chatter := loadchatter(u.UserID)
for _, chonks := range chatter {
for _, ch := range chonks {
filterchonk(ch)
}
}
templinfo := getInfo(r)
templinfo["Chatter"] = chatter
templinfo["ChonkCSRF"] = login.GetCSRF("sendchonk", r)
err := readviews.Execute(w, "chatter.html", templinfo)
if err != nil {
log.Print(err)
}
}
func submitchonk(w http.ResponseWriter, r *http.Request) {
u := login.GetUserInfo(r)
user, _ := butwhatabout(u.Username)
noise := r.FormValue("noise")
target := r.FormValue("target")
format := "markdown"
dt := time.Now().UTC()
xid := fmt.Sprintf("%s/%s/%s", user.URL, "chonk", xfiltrate())
if !strings.HasPrefix(target, "https://") {
target = fullname(target, u.UserID)
}
if target == "" {
http.Error(w, "who is that?", http.StatusInternalServerError)
return
}
ch := Chonk{
UserID: u.UserID,
XID: xid,
Who: user.URL,
Target: target,
Date: dt,
Noise: noise,
Format: format,
}
savechonk(&ch)
go sendchonk(user, &ch)
http.Redirect(w, r, "/chatter", http.StatusSeeOther)
}
var combocache = cache.New(cache.Options{Filler: func(userid int64) ([]string, bool) {
honkers := gethonkers(userid)
var combos []string
@ -2361,6 +2411,7 @@ func serve() {
viewDir+"/views/honkpage.html",
viewDir+"/views/honkfrags.html",
viewDir+"/views/honkers.html",
viewDir+"/views/chatter.html",
viewDir+"/views/hfcs.html",
viewDir+"/views/combos.html",
viewDir+"/views/honkform.html",
@ -2435,6 +2486,8 @@ func serve() {
loggedin := mux.NewRoute().Subrouter()
loggedin.Use(login.Required)
loggedin.HandleFunc("/first", homepage)
loggedin.HandleFunc("/chatter", showchatter)
loggedin.Handle("/sendchonk", login.CSRFWrap("sendchonk", http.HandlerFunc(submitchonk)))
loggedin.HandleFunc("/saved", homepage)
loggedin.HandleFunc("/account", accountpage)
loggedin.HandleFunc("/funzone", showfunzone)