@ -23,7 +23,6 @@ import (
"fmt"
"html"
"io"
"log"
notrand "math/rand"
"net/http"
"net/url"
@ -96,7 +95,7 @@ func PostMsg(keyname string, key httpsig.PrivateKey, url string, msg []byte) err
default :
return fmt . Errorf ( "http post status: %d" , resp . StatusCode )
}
log. Printf ( "successful post: %s %d" , url , resp . StatusCode )
i log. Printf ( "successful post: %s %d" , url , resp . StatusCode )
return nil
}
@ -113,13 +112,13 @@ func GetJunkHardMode(url string) (junk.Junk, error) {
if err != nil {
emsg := err . Error ( )
if emsg == "http get status: 502" || strings . Contains ( emsg , "timeout" ) {
log. Printf ( "trying again after error: %s" , emsg )
i log. Printf ( "trying again after error: %s" , emsg )
time . Sleep ( time . Duration ( 60 + notrand . Int63n ( 60 ) ) * time . Second )
j , err = GetJunk ( url )
if err != nil {
log. Printf ( "still couldn't get it" )
i log. Printf ( "still couldn't get it" )
} else {
log. Printf ( "retry success!" )
i log. Printf ( "retry success!" )
}
}
}
@ -158,7 +157,7 @@ func fetchsome(url string) ([]byte, error) {
}
req , err := http . NewRequest ( "GET" , url , nil )
if err != nil {
log. Printf ( "error fetching %s: %s" , url , err )
i log. Printf ( "error fetching %s: %s" , url , err )
return nil , err
}
req . Header . Set ( "User-Agent" , "honksnonk/5.0; " + serverName )
@ -167,7 +166,7 @@ func fetchsome(url string) ([]byte, error) {
req = req . WithContext ( ctx )
resp , err := client . Do ( req )
if err != nil {
log. Printf ( "error fetching %s: %s" , url , err )
i log. Printf ( "error fetching %s: %s" , url , err )
return nil , err
}
defer resp . Body . Close ( )
@ -191,7 +190,7 @@ func savedonk(url string, name, desc, media string, localize bool) *Donk {
if donk := finddonk ( url ) ; donk != nil {
return donk
}
log. Printf ( "saving donk: %s" , url )
i log. Printf ( "saving donk: %s" , url )
data := [ ] byte { }
if localize {
fn := func ( ) ( interface { } , error ) {
@ -199,19 +198,19 @@ func savedonk(url string, name, desc, media string, localize bool) *Donk {
}
ii , err := flightdeck . Call ( url , fn )
if err != nil {
log. Printf ( "error fetching donk: %s" , err )
i log. Printf ( "error fetching donk: %s" , err )
localize = false
goto saveit
}
data = ii . ( [ ] byte )
if len ( data ) == 10 * 1024 * 1024 {
log. Printf ( "truncation likely" )
i log. Printf ( "truncation likely" )
}
if strings . HasPrefix ( media , "image" ) {
img , err := shrinkit ( data )
if err != nil {
log. Printf ( "unable to decode image: %s" , err )
i log. Printf ( "unable to decode image: %s" , err )
localize = false
data = [ ] byte { }
goto saveit
@ -220,12 +219,12 @@ func savedonk(url string, name, desc, media string, localize bool) *Donk {
media = "image/" + img . Format
} else if media == "application/pdf" {
if len ( data ) > 1000000 {
log. Printf ( "not saving large pdf" )
i log. Printf ( "not saving large pdf" )
localize = false
data = [ ] byte { }
}
} else if len ( data ) > 100000 {
log. Printf ( "not saving large attachment" )
i log. Printf ( "not saving large attachment" )
localize = false
data = [ ] byte { }
}
@ -233,7 +232,7 @@ func savedonk(url string, name, desc, media string, localize bool) *Donk {
saveit :
fileid , err := savefile ( name , desc , url , media , localize , data )
if err != nil {
log. Printf ( "error saving file %s: %s" , url , err )
e log. Printf ( "error saving file %s: %s" , url , err )
return nil
}
donk := new ( Donk )
@ -249,7 +248,7 @@ func iszonked(userid int64, xid string) bool {
return true
}
if err != sql . ErrNoRows {
log. Printf ( "error querying zonk: %s" , err )
i log. Printf ( "error querying zonk: %s" , err )
}
return false
}
@ -274,11 +273,11 @@ func needxonkidX(user *WhatAbout, xid string, isannounce bool) bool {
return false
}
if rejectorigin ( user . ID , xid , isannounce ) {
log. Printf ( "rejecting origin: %s" , xid )
i log. Printf ( "rejecting origin: %s" , xid )
return false
}
if iszonked ( user . ID , xid ) {
log. Printf ( "already zonked: %s" , xid )
i log. Printf ( "already zonked: %s" , xid )
return false
}
var id int64
@ -288,7 +287,7 @@ func needxonkidX(user *WhatAbout, xid string, isannounce bool) bool {
return false
}
if err != sql . ErrNoRows {
log. Printf ( "error querying xonk: %s" , err )
i log. Printf ( "error querying xonk: %s" , err )
}
return true
}
@ -300,12 +299,12 @@ func eradicatexonk(userid int64, xid string) {
}
_ , err := stmtSaveZonker . Exec ( userid , xid , "zonk" )
if err != nil {
log. Printf ( "error eradicating: %s" , err )
e log. Printf ( "error eradicating: %s" , err )
}
}
func savexonk ( x * Honk ) {
log. Printf ( "saving xonk: %s" , x . XID )
i log. Printf ( "saving xonk: %s" , x . XID )
go handles ( x . Honker )
go handles ( x . Oonker )
savehonk ( x )
@ -322,11 +321,11 @@ var boxofboxes = cache.New(cache.Options{Filler: func(ident string) (*Box, bool)
row := stmtGetXonker . QueryRow ( ident , "boxes" )
err := row . Scan ( & info )
if err != nil {
log. Printf ( "need to get boxes for %s" , ident )
d log. Printf ( "need to get boxes for %s" , ident )
var j junk . Junk
j , err = GetJunk ( ident )
if err != nil {
log. Printf ( "error getting boxes: %s" , err )
d log. Printf ( "error getting boxes: %s" , err )
return nil , false
}
allinjest ( originate ( ident ) , j )
@ -342,10 +341,10 @@ var boxofboxes = cache.New(cache.Options{Filler: func(ident string) (*Box, bool)
} } )
func gimmexonks ( user * WhatAbout , outbox string ) {
log. Printf ( "getting outbox: %s" , outbox )
d log. Printf ( "getting outbox: %s" , outbox )
j , err := GetJunk ( outbox )
if err != nil {
log. Printf ( "error getting outbox: %s" , err )
i log. Printf ( "error getting outbox: %s" , err )
return
}
t , _ := j . GetString ( "type" )
@ -364,7 +363,7 @@ func gimmexonks(user *WhatAbout, outbox string) {
if ok {
j , err = GetJunk ( page1 )
if err != nil {
log. Printf ( "error gettings page1: %s" , err )
i log. Printf ( "error gettings page1: %s" , err )
return
}
items , _ = j . GetArray ( "orderedItems" )
@ -390,7 +389,7 @@ func gimmexonks(user *WhatAbout, outbox string) {
}
obj , err = GetJunk ( xid )
if err != nil {
log. Printf ( "error getting item: %s" , err )
i log. Printf ( "error getting item: %s" , err )
continue
}
xonksaver ( user , obj , originate ( xid ) )
@ -467,14 +466,14 @@ func xonksaver(user *WhatAbout, item junk.Junk, origin string) *Honk {
var xonkxonkfn func ( item junk . Junk , origin string , isUpdate bool ) * Honk
saveonemore := func ( xid string ) {
log. Printf ( "getting onemore: %s" , xid )
d log. Printf ( "getting onemore: %s" , xid )
if depth >= maxdepth {
log. Printf ( "in too deep" )
i log. Printf ( "in too deep" )
return
}
obj , err := GetJunkHardMode ( xid )
if err != nil {
log. Printf ( "error getting onemore: %s: %s" , xid , err )
i log. Printf ( "error getting onemore: %s: %s" , xid , err )
return
}
depth ++
@ -506,16 +505,16 @@ func xonksaver(user *WhatAbout, item junk.Junk, origin string) *Honk {
return nil
}
if originate ( xid ) != origin {
log. Printf ( "forged delete: %s" , xid )
i log. Printf ( "forged delete: %s" , xid )
return nil
}
log. Printf ( "eradicating %s" , xid )
i log. Printf ( "eradicating %s" , xid )
eradicatexonk ( user . ID , xid )
return nil
case "Remove" :
xid , _ = item . GetString ( "object" )
targ , _ := obj . GetString ( "target" )
log. Printf ( "remove %s from %s" , obj , targ )
i log. Printf ( "remove %s from %s" , obj , targ )
return nil
case "Tombstone" :
xid , _ = item . GetString ( "id" )
@ -523,10 +522,10 @@ func xonksaver(user *WhatAbout, item junk.Junk, origin string) *Honk {
return nil
}
if originate ( xid ) != origin {
log. Printf ( "forged delete: %s" , xid )
i log. Printf ( "forged delete: %s" , xid )
return nil
}
log. Printf ( "eradicating %s" , xid )
i log. Printf ( "eradicating %s" , xid )
eradicatexonk ( user . ID , xid )
return nil
case "Announce" :
@ -539,10 +538,10 @@ func xonksaver(user *WhatAbout, item junk.Junk, origin string) *Honk {
if ! needbonkid ( user , xid ) {
return nil
}
log. Printf ( "getting bonk: %s" , xid )
d log. Printf ( "getting bonk: %s" , xid )
obj , err = GetJunkHardMode ( xid )
if err != nil {
log. Printf ( "error getting bonk: %s: %s" , xid , err )
i log. Printf ( "error getting bonk: %s: %s" , xid , err )
}
origin = originate ( xid )
what = "bonk"
@ -553,18 +552,18 @@ func xonksaver(user *WhatAbout, item junk.Junk, origin string) *Honk {
obj , ok = item . GetMap ( "object" )
if ! ok {
xid , _ = item . GetString ( "object" )
log. Printf ( "getting created honk: %s" , xid )
d log. Printf ( "getting created honk: %s" , xid )
if originate ( xid ) != origin {
log. Printf ( "out of bounds %s not from %s" , xid , origin )
i log. Printf ( "out of bounds %s not from %s" , xid , origin )
return nil
}
obj , err = GetJunkHardMode ( xid )
if err != nil {
log. Printf ( "error getting creation: %s" , err )
i log. Printf ( "error getting creation: %s" , err )
}
}
if obj == nil {
log. Printf ( "no object for creation %s" , id )
i log. Printf ( "no object for creation %s" , id )
return nil
}
return xonkxonkfn ( obj , origin , isUpdate )
@ -572,12 +571,12 @@ func xonksaver(user *WhatAbout, item junk.Junk, origin string) *Honk {
xid , ok = item . GetString ( "object" )
if ok {
if ! needxonkid ( user , xid ) {
log. Printf ( "don't need read obj: %s" , xid )
d log. Printf ( "don't need read obj: %s" , xid )
return nil
}
obj , err = GetJunkHardMode ( xid )
if err != nil {
log. Printf ( "error getting read: %s" , err )
i log. Printf ( "error getting read: %s" , err )
return nil
}
return xonkxonkfn ( obj , originate ( xid ) , false )
@ -588,12 +587,12 @@ func xonksaver(user *WhatAbout, item junk.Junk, origin string) *Honk {
if ok {
// check target...
if ! needxonkid ( user , xid ) {
log. Printf ( "don't need added obj: %s" , xid )
d log. Printf ( "don't need added obj: %s" , xid )
return nil
}
obj , err = GetJunkHardMode ( xid )
if err != nil {
log. Printf ( "error getting add: %s" , err )
i log. Printf ( "error getting add: %s" , err )
return nil
}
return xonkxonkfn ( obj , originate ( xid ) , false )
@ -624,7 +623,7 @@ func xonksaver(user *WhatAbout, item junk.Junk, origin string) *Honk {
obj = item
what = "chonk"
default :
log. Printf ( "unknown activity: %s" , what )
i log. Printf ( "unknown activity: %s" , what )
dumpactivity ( item )
return nil
}
@ -634,13 +633,13 @@ func xonksaver(user *WhatAbout, item junk.Junk, origin string) *Honk {
}
if xid == "" {
log. Printf ( "don't know what xid is" )
item . Write ( os. Stdout )
i log. Printf ( "don't know what xid is" )
item . Write ( ilog. Writer ( ) )
return nil
}
if originate ( xid ) != origin {
log. Printf ( "original sin: %s not from %s" , xid , origin )
item . Write ( os. Stdout )
i log. Printf ( "original sin: %s not from %s" , xid , origin )
item . Write ( ilog. Writer ( ) )
return nil
}
@ -729,14 +728,14 @@ func xonksaver(user *WhatAbout, item junk.Junk, origin string) *Honk {
what = "tonk"
}
if len ( content ) > 90001 {
log. Printf ( "content too long. truncating" )
i log. Printf ( "content too long. truncating" )
content = content [ : 90001 ]
}
xonk . Noise = content
xonk . Precis = precis
if rejectxonk ( & xonk ) {
log. Printf ( "fast reject: %s" , xid )
d log. Printf ( "fast reject: %s" , xid )
return nil
}
@ -771,16 +770,16 @@ func xonksaver(user *WhatAbout, item junk.Junk, origin string) *Honk {
}
localize := false
if numatts > 4 {
log. Printf ( "excessive attachment: %s" , at )
i log. Printf ( "excessive attachment: %s" , at )
} else if at == "Document" || at == "Image" {
mt = strings . ToLower ( mt )
log. Printf ( "attachment: %s %s" , mt , u )
d log. Printf ( "attachment: %s %s" , mt , u )
if mt == "text/plain" || mt == "application/pdf" ||
strings . HasPrefix ( mt , "image" ) {
localize = true
}
} else {
log. Printf ( "unknown attachment: %s" , at )
i log. Printf ( "unknown attachment: %s" , at )
}
if skipMedia ( & xonk ) {
localize = false
@ -795,7 +794,7 @@ func xonksaver(user *WhatAbout, item junk.Junk, origin string) *Honk {
for _ , atti := range atts {
att , ok := atti . ( junk . Junk )
if ! ok {
log. Printf ( "attachment that wasn't map?" )
i log. Printf ( "attachment that wasn't map?" )
continue
}
procatt ( att )
@ -934,10 +933,10 @@ func xonksaver(user *WhatAbout, item junk.Junk, origin string) *Honk {
}
if isUpdate {
log. Printf ( "something has changed! %s" , xonk . XID )
d log. Printf ( "something has changed! %s" , xonk . XID )
prev := getxonk ( user . ID , xonk . XID )
if prev == nil {
log. Printf ( "didn't find old version for update: %s" , xonk . XID )
i log. Printf ( "didn't find old version for update: %s" , xonk . XID )
isUpdate = false
} else {
xonk . ID = prev . ID
@ -971,7 +970,7 @@ func xonksaver(user *WhatAbout, item junk.Junk, origin string) *Honk {
if goingup == 0 {
for _ , replid := range replies {
if needxonkid ( user , replid ) {
log. Printf ( "missing a reply: %s" , replid )
d log. Printf ( "missing a reply: %s" , replid )
saveonemore ( replid )
}
}
@ -985,7 +984,7 @@ func xonksaver(user *WhatAbout, item junk.Junk, origin string) *Honk {
func dumpactivity ( item junk . Junk ) {
fd , err := os . OpenFile ( "savedinbox.json" , os . O_CREATE | os . O_WRONLY | os . O_APPEND , 0666 )
if err != nil {
log. Printf ( "error opening inbox! %s" , err )
e log. Printf ( "error opening inbox! %s" , err )
return
}
defer fd . Close ( )
@ -1028,7 +1027,7 @@ func itakeitallback(user *WhatAbout, xid string, owner string, folxid string) {
func subsub ( user * WhatAbout , xid string , owner string , folxid string ) {
if xid == "" {
log. Printf ( "can't subscribe to empty" )
i log. Printf ( "can't subscribe to empty" )
return
}
j := junk . New ( )
@ -1508,7 +1507,7 @@ func asjonker(name string) ([]byte, bool) {
var handfull = cache . New ( cache . Options { Filler : func ( name string ) ( string , bool ) {
m := strings . Split ( name , "@" )
if len ( m ) != 2 {
log. Printf ( "bad fish name: %s" , name )
d log. Printf ( "bad fish name: %s" , name )
return "" , true
}
var href string
@ -1517,10 +1516,10 @@ var handfull = cache.New(cache.Options{Filler: func(name string) (string, bool)
if err == nil {
return href , true
}
log. Printf ( "fishing for %s" , name )
d log. Printf ( "fishing for %s" , name )
j , err := GetJunkFast ( fmt . Sprintf ( "https://%s/.well-known/webfinger?resource=acct:%s" , m [ 1 ] , name ) )
if err != nil {
log. Printf ( "failed to go fish %s: %s" , name , err )
i log. Printf ( "failed to go fish %s: %s" , name , err )
return "" , true
}
links , _ := j . GetArray ( "links" )
@ -1536,7 +1535,7 @@ var handfull = cache.New(cache.Options{Filler: func(name string) (string, bool)
when := time . Now ( ) . UTC ( ) . Format ( dbtimeformat )
_ , err := stmtSaveXonker . Exec ( name , href , "fishname" , when )
if err != nil {
log. Printf ( "error saving fishname: %s" , err )
e log. Printf ( "error saving fishname: %s" , err )
}
return href , true
}
@ -1624,33 +1623,33 @@ func ingestpubkey(origin string, obj junk.Junk) {
return
}
if ! ok || origin != originate ( keyname ) {
log. Printf ( "bad key origin %s <> %s" , origin , keyname )
i log. Printf ( "bad key origin %s <> %s" , origin , keyname )
return
}
log. Printf ( "ingesting a needed pubkey: %s" , keyname )
d log. Printf ( "ingesting a needed pubkey: %s" , keyname )
owner , ok := obj . GetString ( "owner" )
if ! ok {
log. Printf ( "error finding %s pubkey owner" , keyname )
i log. Printf ( "error finding %s pubkey owner" , keyname )
return
}
data , ok = obj . GetString ( "publicKeyPem" )
if ! ok {
log. Printf ( "error finding %s pubkey" , keyname )
i log. Printf ( "error finding %s pubkey" , keyname )
return
}
if originate ( owner ) != origin {
log. Printf ( "bad key owner: %s <> %s" , owner , origin )
i log. Printf ( "bad key owner: %s <> %s" , owner , origin )
return
}
_ , _ , err = httpsig . DecodeKey ( data )
if err != nil {
log. Printf ( "error decoding %s pubkey: %s" , keyname , err )
i log. Printf ( "error decoding %s pubkey: %s" , keyname , err )
return
}
when := time . Now ( ) . UTC ( ) . Format ( dbtimeformat )
_ , err = stmtSaveXonker . Exec ( keyname , data , "pubkey" , when )
if err != nil {
log. Printf ( "error saving key: %s" , err )
e log. Printf ( "error saving key: %s" , err )
}
}
@ -1668,7 +1667,7 @@ func ingestboxes(origin string, obj junk.Junk) {
if err == nil {
return
}
log. Printf ( "ingesting boxes: %s" , ident )
d log. Printf ( "ingesting boxes: %s" , ident )
inbox , _ := obj . GetString ( "inbox" )
outbox , _ := obj . GetString ( "outbox" )
sbox , _ := obj . GetString ( "endpoints" , "sharedInbox" )
@ -1677,7 +1676,7 @@ func ingestboxes(origin string, obj junk.Junk) {
m := strings . Join ( [ ] string { inbox , outbox , sbox } , " " )
_ , err = stmtSaveXonker . Exec ( ident , m , "boxes" , when )
if err != nil {
log. Printf ( "error saving boxes: %s" , err )
e log. Printf ( "error saving boxes: %s" , err )
}
}
}
@ -1701,7 +1700,7 @@ func ingesthandle(origin string, obj junk.Junk) {
when := time . Now ( ) . UTC ( ) . Format ( dbtimeformat )
_ , err = stmtSaveXonker . Exec ( xid , handle , "handle" , when )
if err != nil {
log. Printf ( "error saving handle: %s" , err )
e log. Printf ( "error saving handle: %s" , err )
}
}
}
@ -1742,17 +1741,17 @@ func updateMe(username string) {
func followme ( user * WhatAbout , who string , name string , j junk . Junk ) {
folxid , _ := j . GetString ( "id" )
log. Printf ( "updating honker follow: %s %s" , who , folxid )
i log. Printf ( "updating honker follow: %s %s" , who , folxid )
var x string
db := opendatabase ( )
row := db . QueryRow ( "select xid from honkers where name = ? and xid = ? and userid = ? and flavor in ('dub', 'undub')" , name , who , user . ID )
err := row . Scan ( & x )
if err != sql . ErrNoRows {
log. Printf ( "duplicate follow request: %s" , who )
i log. Printf ( "duplicate follow request: %s" , who )
_ , err = stmtUpdateFlavor . Exec ( "dub" , folxid , user . ID , name , who , "undub" )
if err != nil {
log. Printf ( "error updating honker: %s" , err )
e log. Printf ( "error updating honker: %s" , err )
}
} else {
stmtSaveDub . Exec ( user . ID , name , who , "dub" , folxid )
@ -1770,16 +1769,16 @@ func unfollowme(user *WhatAbout, who string, name string, j junk.Junk) {
err := row . Scan ( & who , & name )
if err != nil {
if err != sql . ErrNoRows {
log. Printf ( "error scanning honker: %s" , err )
e log. Printf ( "error scanning honker: %s" , err )
}
return
}
}
log. Printf ( "updating honker undo: %s %s" , who , folxid )
i log. Printf ( "updating honker undo: %s %s" , who , folxid )
_ , err := stmtUpdateFlavor . Exec ( "undub" , folxid , user . ID , name , who , "dub" )
if err != nil {
log. Printf ( "error updating honker: %s" , err )
e log. Printf ( "error updating honker: %s" , err )
return
}
}
@ -1791,14 +1790,14 @@ func followyou(user *WhatAbout, honkerid int64) {
honkerid , user . ID )
err := row . Scan ( & url , & owner )
if err != nil {
log. Printf ( "can't get honker xid: %s" , err )
e log. Printf ( "can't get honker xid: %s" , err )
return
}
folxid := xfiltrate ( )
log. Printf ( "subscribing to %s" , url )
i log. Printf ( "subscribing to %s" , url )
_ , err = db . Exec ( "update honkers set flavor = ?, folxid = ? where honkerid = ?" , "presub" , folxid , honkerid )
if err != nil {
log. Printf ( "error updating honker: %s" , err )
e log. Printf ( "error updating honker: %s" , err )
return
}
go subsub ( user , url , owner , folxid )
@ -1811,13 +1810,13 @@ func unfollowyou(user *WhatAbout, honkerid int64) {
var url , owner , folxid string
err := row . Scan ( & url , & owner , & folxid )
if err != nil {
log. Printf ( "can't get honker xid: %s" , err )
e log. Printf ( "can't get honker xid: %s" , err )
return
}
log. Printf ( "unsubscribing from %s" , url )
i log. Printf ( "unsubscribing from %s" , url )
_ , err = db . Exec ( "update honkers set flavor = ? where honkerid = ?" , "unsub" , honkerid )
if err != nil {
log. Printf ( "error updating honker: %s" , err )
e log. Printf ( "error updating honker: %s" , err )
return
}
go itakeitallback ( user , url , owner , folxid )
@ -1826,19 +1825,19 @@ func unfollowyou(user *WhatAbout, honkerid int64) {
func followyou2 ( user * WhatAbout , j junk . Junk ) {
who , _ := j . GetString ( "actor" )
log. Printf ( "updating honker accept: %s" , who )
i log. Printf ( "updating honker accept: %s" , who )
db := opendatabase ( )
row := db . QueryRow ( "select name, folxid from honkers where userid = ? and xid = ? and flavor in ('presub')" ,
user . ID , who )
var name , folxid string
err := row . Scan ( & name , & folxid )
if err != nil {
log. Printf ( "can't get honker name: %s" , err )
e log. Printf ( "can't get honker name: %s" , err )
return
}
_ , err = stmtUpdateFlavor . Exec ( "sub" , folxid , user . ID , name , who , "presub" )
if err != nil {
log. Printf ( "error updating honker: %s" , err )
e log. Printf ( "error updating honker: %s" , err )
return
}
}
@ -1846,20 +1845,20 @@ func followyou2(user *WhatAbout, j junk.Junk) {
func nofollowyou2 ( user * WhatAbout , j junk . Junk ) {
who , _ := j . GetString ( "actor" )
log. Printf ( "updating honker reject: %s" , who )
i log. Printf ( "updating honker reject: %s" , who )
db := opendatabase ( )
row := db . QueryRow ( "select name, folxid from honkers where userid = ? and xid = ? and flavor in ('presub', 'sub')" ,
user . ID , who )
var name , folxid string
err := row . Scan ( & name , & folxid )
if err != nil {
log. Printf ( "can't get honker name: %s" , err )
e log. Printf ( "can't get honker name: %s" , err )
return
}
_ , err = stmtUpdateFlavor . Exec ( "unsub" , folxid , user . ID , name , who , "presub" )
_ , err = stmtUpdateFlavor . Exec ( "unsub" , folxid , user . ID , name , who , "sub" )
if err != nil {
log. Printf ( "error updating honker: %s" , err )
e log. Printf ( "error updating honker: %s" , err )
return
}
}