2019-04-09 13:59:33 +02:00
//
// 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 (
"bytes"
"database/sql"
"fmt"
2019-04-15 16:56:43 +02:00
"html"
2019-04-09 13:59:33 +02:00
"html/template"
"io"
2019-09-04 19:19:52 +02:00
"io/ioutil"
2019-04-09 13:59:33 +02:00
"log"
2019-04-16 02:52:24 +02:00
notrand "math/rand"
2019-04-09 13:59:33 +02:00
"net/http"
2019-06-11 04:28:09 +02:00
"net/url"
2019-04-09 13:59:33 +02:00
"os"
"sort"
2019-04-22 23:03:55 +02:00
"strconv"
2019-04-09 13:59:33 +02:00
"strings"
"time"
"github.com/gorilla/mux"
2019-09-04 19:19:52 +02:00
"humungus.tedunangst.com/r/webs/css"
2019-05-18 01:37:43 +02:00
"humungus.tedunangst.com/r/webs/htfilter"
2019-07-29 01:44:27 +02:00
"humungus.tedunangst.com/r/webs/httpsig"
2019-05-05 00:05:15 +02:00
"humungus.tedunangst.com/r/webs/image"
2019-06-11 16:14:12 +02:00
"humungus.tedunangst.com/r/webs/junk"
2019-04-25 05:57:01 +02:00
"humungus.tedunangst.com/r/webs/login"
2019-05-05 04:56:58 +02:00
"humungus.tedunangst.com/r/webs/rss"
2019-04-29 19:15:14 +02:00
"humungus.tedunangst.com/r/webs/templates"
2019-04-09 13:59:33 +02:00
)
type WhatAbout struct {
2019-06-28 04:36:55 +02:00
ID int64
Name string
Display string
About string
Key string
URL string
SkinnyCSS bool
2019-04-09 13:59:33 +02:00
}
2019-04-13 19:58:42 +02:00
type Honk struct {
ID int64
UserID int64
Username string
What string
Honker string
2019-06-03 06:22:00 +02:00
Handle string
2019-05-15 22:27:50 +02:00
Oonker string
2019-07-05 19:07:59 +02:00
Oondle string
2019-04-13 19:58:42 +02:00
XID string
RID string
Date time . Time
URL string
Noise string
2019-05-15 22:27:50 +02:00
Precis string
2019-04-19 17:08:22 +02:00
Convoy string
2019-04-13 19:58:42 +02:00
Audience [ ] string
2019-05-28 08:36:47 +02:00
Public bool
2019-05-20 16:48:02 +02:00
Whofore int64
2019-08-19 05:25:11 +02:00
Replies [ ] * Honk
2019-08-16 21:13:33 +02:00
Flags int64
2019-04-13 19:58:42 +02:00
HTML template . HTML
2019-07-08 02:24:54 +02:00
Style string
2019-07-10 20:36:14 +02:00
Open string
2019-04-13 19:58:42 +02:00
Donks [ ] * Donk
2019-08-25 05:11:53 +02:00
Onts [ ] string
2019-04-09 13:59:33 +02:00
}
2019-08-16 21:35:12 +02:00
const (
2019-08-24 02:43:30 +02:00
flagIsAcked = 1
flagIsBonked = 2
2019-08-16 21:35:12 +02:00
)
2019-08-19 06:01:00 +02:00
func ( honk * Honk ) IsAcked ( ) bool {
return honk . Flags & flagIsAcked != 0
2019-08-16 21:35:12 +02:00
}
2019-08-24 02:43:30 +02:00
func ( honk * Honk ) IsBonked ( ) bool {
return honk . Flags & flagIsBonked != 0
}
2019-04-13 19:58:42 +02:00
type Donk struct {
FileID int64
XID string
Name string
URL string
Media string
2019-05-25 19:34:41 +02:00
Local bool
2019-04-13 19:58:42 +02:00
Content [ ] byte
2019-04-09 13:59:33 +02:00
}
2019-04-13 19:58:42 +02:00
type Honker struct {
ID int64
UserID int64
Name string
XID string
2019-08-16 05:27:55 +02:00
Handle string
2019-04-13 19:58:42 +02:00
Flavor string
2019-04-22 23:03:55 +02:00
Combos [ ] string
2019-04-09 13:59:33 +02:00
}
2019-04-13 19:58:42 +02:00
var serverName string
var iconName = "icon.png"
2019-06-12 05:11:18 +02:00
var serverMsg = "Things happen."
2019-04-13 19:58:42 +02:00
2019-07-23 19:21:09 +02:00
var userSep = "u"
var honkSep = "h"
2019-04-29 19:15:14 +02:00
var readviews * templates . Template
2019-04-13 19:58:42 +02:00
2019-06-28 04:36:55 +02:00
func getuserstyle ( u * login . UserInfo ) template . CSS {
if u == nil {
return ""
}
user , _ := butwhatabout ( u . Username )
if user . SkinnyCSS {
return "main { max-width: 700px; }"
}
return ""
}
2019-04-09 13:59:33 +02:00
func getInfo ( r * http . Request ) map [ string ] interface { } {
2019-06-28 04:36:55 +02:00
u := login . GetUserInfo ( r )
2019-04-09 13:59:33 +02:00
templinfo := make ( map [ string ] interface { } )
2019-04-12 19:12:18 +02:00
templinfo [ "StyleParam" ] = getstyleparam ( "views/style.css" )
templinfo [ "LocalStyleParam" ] = getstyleparam ( "views/local.css" )
2019-06-28 04:36:55 +02:00
templinfo [ "UserStyle" ] = getuserstyle ( u )
2019-04-09 13:59:33 +02:00
templinfo [ "ServerName" ] = serverName
templinfo [ "IconName" ] = iconName
2019-06-28 04:36:55 +02:00
templinfo [ "UserInfo" ] = u
2019-07-23 19:21:09 +02:00
templinfo [ "UserSep" ] = userSep
2019-04-09 13:59:33 +02:00
return templinfo
}
2019-06-25 03:14:47 +02:00
var donotfedafterdark = make ( map [ string ] bool )
func stealthed ( r * http . Request ) bool {
addr := r . Header . Get ( "X-Forwarded-For" )
fake := donotfedafterdark [ addr ]
if fake {
log . Printf ( "faking 404 for %s" , addr )
}
return fake
}
2019-04-09 13:59:33 +02:00
func homepage ( w http . ResponseWriter , r * http . Request ) {
templinfo := getInfo ( r )
2019-04-25 05:57:01 +02:00
u := login . GetUserInfo ( r )
2019-04-14 04:57:16 +02:00
var honks [ ] * Honk
2019-07-10 20:36:14 +02:00
var userid int64 = - 1
2019-06-24 04:43:47 +02:00
if r . URL . Path == "/front" || u == nil {
honks = getpublichonks ( )
} else {
2019-07-10 20:36:14 +02:00
userid = u . UserID
2019-04-20 17:17:00 +02:00
if r . URL . Path == "/atme" {
2019-09-05 23:45:10 +02:00
templinfo [ "PageName" ] = "atme"
2019-07-10 20:36:14 +02:00
honks = gethonksforme ( userid )
2019-04-20 17:17:00 +02:00
} else {
2019-09-05 23:45:10 +02:00
templinfo [ "PageName" ] = "home"
2019-07-10 20:36:14 +02:00
honks = gethonksforuser ( userid )
honks = osmosis ( honks , userid )
2019-09-05 23:29:40 +02:00
}
if len ( honks ) > 0 {
templinfo [ "TopXID" ] = honks [ 0 ] . XID
2019-04-20 17:17:00 +02:00
}
2019-04-25 05:57:01 +02:00
templinfo [ "HonkCSRF" ] = login . GetCSRF ( "honkhonk" , r )
2019-04-09 13:59:33 +02:00
}
2019-04-11 01:25:32 +02:00
2019-08-19 09:02:24 +02:00
tname := "honkpage.html"
if topxid := r . FormValue ( "topxid" ) ; topxid != "" {
for i , h := range honks {
if h . XID == topxid {
honks = honks [ 0 : i ]
break
}
}
log . Printf ( "topxid %d frags" , len ( honks ) )
tname = "honkfrags.html"
}
2019-07-10 20:36:14 +02:00
reverbolate ( userid , honks )
2019-04-11 01:25:32 +02:00
2019-04-09 13:59:33 +02:00
templinfo [ "Honks" ] = honks
templinfo [ "ShowRSS" ] = true
2019-06-12 05:11:18 +02:00
templinfo [ "ServerMessage" ] = serverMsg
2019-04-17 04:26:17 +02:00
if u == nil {
w . Header ( ) . Set ( "Cache-Control" , "max-age=60" )
} else {
w . Header ( ) . Set ( "Cache-Control" , "max-age=0" )
}
2019-08-19 10:36:45 +02:00
w . Header ( ) . Set ( "Content-Type" , "text/html; charset=utf-8" )
2019-08-19 09:02:24 +02:00
err := readviews . Execute ( w , tname , templinfo )
2019-04-09 13:59:33 +02:00
if err != nil {
log . Print ( err )
}
}
2019-06-24 06:31:34 +02:00
func showfunzone ( w http . ResponseWriter , r * http . Request ) {
var emunames , memenames [ ] string
dir , err := os . Open ( "emus" )
if err == nil {
emunames , _ = dir . Readdirnames ( 0 )
dir . Close ( )
}
for i , e := range emunames {
if len ( e ) > 4 {
emunames [ i ] = e [ : len ( e ) - 4 ]
}
}
dir , err = os . Open ( "memes" )
if err == nil {
memenames , _ = dir . Readdirnames ( 0 )
dir . Close ( )
}
templinfo := getInfo ( r )
templinfo [ "Emus" ] = emunames
templinfo [ "Memes" ] = memenames
err = readviews . Execute ( w , "funzone.html" , templinfo )
if err != nil {
log . Print ( err )
}
}
2019-04-09 13:59:33 +02:00
func showrss ( w http . ResponseWriter , r * http . Request ) {
name := mux . Vars ( r ) [ "name" ]
2019-04-14 04:57:16 +02:00
var honks [ ] * Honk
if name != "" {
2019-05-28 08:36:47 +02:00
honks = gethonksbyuser ( name , false )
2019-04-14 04:57:16 +02:00
} else {
2019-04-24 09:04:20 +02:00
honks = getpublichonks ( )
2019-04-14 04:57:16 +02:00
}
2019-07-10 20:36:14 +02:00
reverbolate ( - 1 , honks )
2019-04-09 13:59:33 +02:00
home := fmt . Sprintf ( "https://%s/" , serverName )
base := home
if name != "" {
home += "u/" + name
name += " "
}
2019-05-05 04:56:58 +02:00
feed := rss . Feed {
2019-04-09 13:59:33 +02:00
Title : name + "honk" ,
Link : home ,
Description : name + "honk rss" ,
2019-05-05 04:56:58 +02:00
Image : & rss . Image {
2019-04-09 13:59:33 +02:00
URL : base + "icon.png" ,
Title : name + "honk rss" ,
Link : home ,
} ,
}
var modtime time . Time
for _ , honk := range honks {
2019-08-24 02:35:58 +02:00
if ! firstclass ( honk ) {
continue
}
2019-04-15 16:56:43 +02:00
desc := string ( honk . HTML )
for _ , d := range honk . Donks {
2019-05-31 06:24:18 +02:00
desc += fmt . Sprintf ( ` <p><a href="%s">Attachment: %s</a> ` ,
d . URL , html . EscapeString ( d . Name ) )
2019-04-09 13:59:33 +02:00
}
2019-04-15 16:56:43 +02:00
2019-05-05 04:56:58 +02:00
feed . Items = append ( feed . Items , & rss . Item {
2019-04-09 13:59:33 +02:00
Title : fmt . Sprintf ( "%s %s %s" , honk . Username , honk . What , honk . XID ) ,
2019-05-05 04:56:58 +02:00
Description : rss . CData { desc } ,
2019-04-09 13:59:33 +02:00
Link : honk . URL ,
PubDate : honk . Date . Format ( time . RFC1123 ) ,
2019-05-16 06:49:13 +02:00
Guid : & rss . Guid { IsPermaLink : true , Value : honk . URL } ,
2019-04-09 13:59:33 +02:00
} )
if honk . Date . After ( modtime ) {
modtime = honk . Date
}
}
w . Header ( ) . Set ( "Cache-Control" , "max-age=300" )
w . Header ( ) . Set ( "Last-Modified" , modtime . Format ( http . TimeFormat ) )
err := feed . Write ( w )
if err != nil {
log . Printf ( "error writing rss: %s" , err )
}
}
func butwhatabout ( name string ) ( * WhatAbout , error ) {
row := stmtWhatAbout . QueryRow ( name )
var user WhatAbout
2019-06-28 04:15:59 +02:00
var options string
err := row . Scan ( & user . ID , & user . Name , & user . Display , & user . About , & user . Key , & options )
2019-07-23 19:21:09 +02:00
user . URL = fmt . Sprintf ( "https://%s/%s/%s" , serverName , userSep , user . Name )
2019-06-28 04:36:55 +02:00
user . SkinnyCSS = strings . Contains ( options , " skinny " )
2019-04-09 13:59:33 +02:00
return & user , err
}
2019-06-11 16:14:12 +02:00
func crappola ( j junk . Junk ) bool {
t , _ := j . GetString ( "type" )
a , _ := j . GetString ( "actor" )
o , _ := j . GetString ( "object" )
2019-04-09 13:59:33 +02:00
if t == "Delete" && a == o {
log . Printf ( "crappola from %s" , a )
return true
}
return false
}
2019-04-12 18:32:07 +02:00
func ping ( user * WhatAbout , who string ) {
2019-04-16 20:40:23 +02:00
box , err := getboxes ( who )
2019-04-12 18:32:07 +02:00
if err != nil {
log . Printf ( "no inbox for ping: %s" , err )
return
}
2019-06-11 16:14:12 +02:00
j := junk . New ( )
2019-04-12 18:32:07 +02:00
j [ "@context" ] = itiswhatitis
j [ "type" ] = "Ping"
j [ "id" ] = user . URL + "/ping/" + xfiltrate ( )
j [ "actor" ] = user . URL
j [ "to" ] = who
2019-04-14 16:06:26 +02:00
keyname , key := ziggy ( user . Name )
2019-04-16 20:40:23 +02:00
err = PostJunk ( keyname , key , box . In , j )
2019-04-12 18:32:07 +02:00
if err != nil {
log . Printf ( "can't send ping: %s" , err )
return
}
log . Printf ( "sent ping to %s: %s" , who , j [ "id" ] )
}
func pong ( user * WhatAbout , who string , obj string ) {
2019-04-16 20:40:23 +02:00
box , err := getboxes ( who )
2019-04-12 18:32:07 +02:00
if err != nil {
log . Printf ( "no inbox for pong %s : %s" , who , err )
return
}
2019-06-11 16:14:12 +02:00
j := junk . New ( )
2019-04-12 18:32:07 +02:00
j [ "@context" ] = itiswhatitis
j [ "type" ] = "Pong"
j [ "id" ] = user . URL + "/pong/" + xfiltrate ( )
j [ "actor" ] = user . URL
j [ "to" ] = who
j [ "object" ] = obj
2019-04-14 16:06:26 +02:00
keyname , key := ziggy ( user . Name )
2019-04-16 20:40:23 +02:00
err = PostJunk ( keyname , key , box . In , j )
2019-04-12 18:32:07 +02:00
if err != nil {
log . Printf ( "can't send pong: %s" , err )
return
}
}
2019-04-09 13:59:33 +02:00
func inbox ( w http . ResponseWriter , r * http . Request ) {
name := mux . Vars ( r ) [ "name" ]
user , err := butwhatabout ( name )
if err != nil {
http . NotFound ( w , r )
return
}
var buf bytes . Buffer
io . Copy ( & buf , r . Body )
payload := buf . Bytes ( )
2019-06-11 16:14:12 +02:00
j , err := junk . Read ( bytes . NewReader ( payload ) )
2019-04-09 13:59:33 +02:00
if err != nil {
log . Printf ( "bad payload: %s" , err )
io . WriteString ( os . Stdout , "bad payload\n" )
os . Stdout . Write ( payload )
io . WriteString ( os . Stdout , "\n" )
return
}
if crappola ( j ) {
return
}
2019-07-29 01:44:27 +02:00
keyname , err := httpsig . VerifyRequest ( r , payload , zaggy )
2019-04-09 13:59:33 +02:00
if err != nil {
log . Printf ( "inbox message failed signature: %s" , err )
2019-04-20 22:12:41 +02:00
if keyname != "" {
keyname , err = makeitworksomehowwithoutregardforkeycontinuity ( keyname , r , payload )
2019-08-13 20:13:07 +02:00
if err != nil {
log . Printf ( "still failed: %s" , err )
}
2019-04-20 22:12:41 +02:00
}
if err != nil {
return
}
2019-04-09 13:59:33 +02:00
}
2019-06-11 16:14:12 +02:00
what , _ := j . GetString ( "type" )
2019-04-18 22:39:29 +02:00
if what == "Like" {
return
}
2019-06-11 16:14:12 +02:00
who , _ := j . GetString ( "actor" )
2019-05-21 19:56:15 +02:00
origin := keymatch ( keyname , who )
if origin == "" {
2019-04-09 13:59:33 +02:00
log . Printf ( "keyname actor mismatch: %s <> %s" , keyname , who )
return
}
2019-06-11 16:14:12 +02:00
objid , _ := j . GetString ( "id" )
2019-04-26 21:11:24 +02:00
if thoudostbitethythumb ( user . ID , [ ] string { who } , objid ) {
2019-04-20 04:35:21 +02:00
log . Printf ( "ignoring thumb sucker %s" , who )
return
}
2019-04-09 13:59:33 +02:00
switch what {
2019-04-12 18:32:07 +02:00
case "Ping" :
2019-06-11 16:14:12 +02:00
obj , _ := j . GetString ( "id" )
2019-04-12 18:32:07 +02:00
log . Printf ( "ping from %s: %s" , who , obj )
pong ( user , who , obj )
case "Pong" :
2019-06-11 16:14:12 +02:00
obj , _ := j . GetString ( "object" )
2019-04-12 18:32:07 +02:00
log . Printf ( "pong from %s: %s" , who , obj )
2019-04-09 13:59:33 +02:00
case "Follow" :
2019-06-11 16:14:12 +02:00
obj , _ := j . GetString ( "object" )
2019-04-25 06:59:20 +02:00
if obj == user . URL {
log . Printf ( "updating honker follow: %s" , who )
2019-06-11 05:57:03 +02:00
stmtSaveDub . Exec ( user . ID , who , who , "dub" )
go rubadubdub ( user , j )
2019-04-25 06:59:20 +02:00
} else {
log . Printf ( "can't follow %s" , obj )
}
2019-04-09 13:59:33 +02:00
case "Accept" :
log . Printf ( "updating honker accept: %s" , who )
2019-04-29 04:48:46 +02:00
_ , err = stmtUpdateFlavor . Exec ( "sub" , user . ID , who , "presub" )
if err != nil {
log . Printf ( "error updating honker: %s" , err )
return
}
2019-06-10 20:50:26 +02:00
case "Update" :
2019-06-11 16:14:12 +02:00
obj , ok := j . GetMap ( "object" )
2019-06-10 20:50:26 +02:00
if ok {
2019-06-11 16:14:12 +02:00
what , _ := obj . GetString ( "type" )
2019-06-10 20:50:26 +02:00
switch what {
case "Person" :
return
2019-08-04 04:18:03 +02:00
case "Question" :
return
2019-06-10 20:50:26 +02:00
}
}
log . Printf ( "unknown Update activity" )
fd , _ := os . OpenFile ( "savedinbox.json" , os . O_CREATE | os . O_WRONLY | os . O_APPEND , 0666 )
2019-06-11 16:14:12 +02:00
j . Write ( fd )
2019-06-10 20:50:26 +02:00
io . WriteString ( fd , "\n" )
fd . Close ( )
2019-04-09 13:59:33 +02:00
case "Undo" :
2019-06-11 16:14:12 +02:00
obj , ok := j . GetMap ( "object" )
2019-04-09 13:59:33 +02:00
if ! ok {
log . Printf ( "unknown undo no object" )
} else {
2019-06-11 16:14:12 +02:00
what , _ := obj . GetString ( "type" )
2019-04-20 17:50:01 +02:00
switch what {
case "Follow" :
2019-04-09 13:59:33 +02:00
log . Printf ( "updating honker undo: %s" , who )
2019-04-29 04:48:46 +02:00
_ , err = stmtUpdateFlavor . Exec ( "undub" , user . ID , who , "dub" )
if err != nil {
log . Printf ( "error updating honker: %s" , err )
return
}
2019-05-08 02:55:11 +02:00
case "Announce" :
2019-08-28 03:22:59 +02:00
xid , _ := obj . GetString ( "object" )
log . Printf ( "undo announce: %s" , xid )
case "Like" :
2019-04-20 17:50:01 +02:00
default :
log . Printf ( "unknown undo: %s" , what )
2019-04-09 13:59:33 +02:00
}
}
default :
2019-05-22 00:51:04 +02:00
go consumeactivity ( user , j , origin )
2019-04-09 13:59:33 +02:00
}
}
2019-06-11 04:28:09 +02:00
func ximport ( w http . ResponseWriter , r * http . Request ) {
xid := r . FormValue ( "xid" )
2019-08-30 16:16:59 +02:00
p , _ := investigate ( xid )
2019-08-16 05:27:55 +02:00
if p != nil {
xid = p . XID
2019-07-09 03:18:37 +02:00
}
2019-06-11 04:28:09 +02:00
j , err := GetJunk ( xid )
if err != nil {
2019-07-09 03:18:37 +02:00
http . Error ( w , "error getting external object" , http . StatusInternalServerError )
2019-06-11 04:28:09 +02:00
log . Printf ( "error getting external object: %s" , err )
return
}
2019-06-17 04:36:52 +02:00
log . Printf ( "importing %s" , xid )
2019-06-11 04:28:09 +02:00
u := login . GetUserInfo ( r )
user , _ := butwhatabout ( u . Username )
2019-06-17 04:36:52 +02:00
what , _ := j . GetString ( "type" )
2019-07-10 07:21:56 +02:00
if isactor ( what ) {
2019-06-17 04:36:52 +02:00
outbox , _ := j . GetString ( "outbox" )
gimmexonks ( user , outbox )
http . Redirect ( w , r , "/h?xid=" + url . QueryEscape ( xid ) , http . StatusSeeOther )
return
}
2019-06-11 04:28:09 +02:00
xonk := xonkxonk ( user , j , originate ( xid ) )
convoy := ""
if xonk != nil {
convoy = xonk . Convoy
savexonk ( user , xonk )
}
http . Redirect ( w , r , "/t?c=" + url . QueryEscape ( convoy ) , http . StatusSeeOther )
}
func xzone ( w http . ResponseWriter , r * http . Request ) {
2019-06-16 21:05:50 +02:00
u := login . GetUserInfo ( r )
2019-08-14 21:46:21 +02:00
rows , err := stmtRecentHonkers . Query ( u . UserID , u . UserID )
2019-06-16 21:05:50 +02:00
if err != nil {
log . Printf ( "query err: %s" , err )
return
}
2019-06-17 03:21:56 +02:00
defer rows . Close ( )
2019-08-16 06:05:22 +02:00
var honkers [ ] Honker
2019-06-16 21:05:50 +02:00
for rows . Next ( ) {
2019-08-16 06:05:22 +02:00
var xid string
rows . Scan ( & xid )
2019-08-16 06:15:55 +02:00
honkers = append ( honkers , Honker { XID : xid } )
2019-08-16 06:05:22 +02:00
}
rows . Close ( )
for i , _ := range honkers {
_ , honkers [ i ] . Handle = handles ( honkers [ i ] . XID )
2019-06-16 21:05:50 +02:00
}
2019-06-11 04:28:09 +02:00
templinfo := getInfo ( r )
templinfo [ "XCSRF" ] = login . GetCSRF ( "ximport" , r )
2019-06-16 21:05:50 +02:00
templinfo [ "Honkers" ] = honkers
err = readviews . Execute ( w , "xzone.html" , templinfo )
2019-06-11 04:28:09 +02:00
if err != nil {
log . Print ( err )
}
}
2019-06-25 18:03:37 +02:00
2019-04-09 13:59:33 +02:00
func outbox ( w http . ResponseWriter , r * http . Request ) {
name := mux . Vars ( r ) [ "name" ]
user , err := butwhatabout ( name )
if err != nil {
http . NotFound ( w , r )
return
}
2019-06-25 03:14:47 +02:00
if stealthed ( r ) {
http . NotFound ( w , r )
return
}
2019-05-28 08:36:47 +02:00
honks := gethonksbyuser ( name , false )
2019-04-09 13:59:33 +02:00
2019-07-29 02:01:12 +02:00
var jonks [ ] junk . Junk
2019-04-09 13:59:33 +02:00
for _ , h := range honks {
j , _ := jonkjonk ( user , h )
jonks = append ( jonks , j )
}
2019-06-11 16:14:12 +02:00
j := junk . New ( )
2019-04-09 13:59:33 +02:00
j [ "@context" ] = itiswhatitis
j [ "id" ] = user . URL + "/outbox"
j [ "type" ] = "OrderedCollection"
j [ "totalItems" ] = len ( jonks )
j [ "orderedItems" ] = jonks
w . Header ( ) . Set ( "Content-Type" , theonetruename )
2019-06-11 16:14:12 +02:00
j . Write ( w )
2019-04-09 13:59:33 +02:00
}
2019-04-25 06:35:19 +02:00
func emptiness ( w http . ResponseWriter , r * http . Request ) {
name := mux . Vars ( r ) [ "name" ]
user , err := butwhatabout ( name )
if err != nil {
http . NotFound ( w , r )
return
}
colname := "/followers"
if strings . HasSuffix ( r . URL . Path , "/following" ) {
colname = "/following"
}
2019-06-11 16:14:12 +02:00
j := junk . New ( )
2019-04-25 06:35:19 +02:00
j [ "@context" ] = itiswhatitis
j [ "id" ] = user . URL + colname
j [ "type" ] = "OrderedCollection"
j [ "totalItems" ] = 0
2019-07-29 02:01:12 +02:00
j [ "orderedItems" ] = [ ] junk . Junk { }
2019-04-25 06:35:19 +02:00
w . Header ( ) . Set ( "Content-Type" , theonetruename )
2019-06-11 16:14:12 +02:00
j . Write ( w )
2019-04-25 06:35:19 +02:00
}
2019-04-29 19:32:16 +02:00
func showuser ( w http . ResponseWriter , r * http . Request ) {
2019-04-09 13:59:33 +02:00
name := mux . Vars ( r ) [ "name" ]
user , err := butwhatabout ( name )
if err != nil {
2019-07-23 19:21:09 +02:00
log . Printf ( "user not found %s: %s" , name , err )
2019-04-09 13:59:33 +02:00
http . NotFound ( w , r )
return
}
if friendorfoe ( r . Header . Get ( "Accept" ) ) {
j := asjonker ( user )
w . Header ( ) . Set ( "Content-Type" , theonetruename )
2019-06-11 16:14:12 +02:00
j . Write ( w )
2019-04-09 13:59:33 +02:00
return
}
2019-04-25 05:57:01 +02:00
u := login . GetUserInfo ( r )
2019-05-28 08:36:47 +02:00
honks := gethonksbyuser ( name , u != nil && u . Username == name )
2019-04-24 09:16:43 +02:00
honkpage ( w , r , u , user , honks , "" )
2019-04-09 13:59:33 +02:00
}
2019-04-29 19:32:16 +02:00
func showhonker ( w http . ResponseWriter , r * http . Request ) {
2019-04-25 05:57:01 +02:00
u := login . GetUserInfo ( r )
2019-06-16 21:05:50 +02:00
name := mux . Vars ( r ) [ "name" ]
var honks [ ] * Honk
if name == "" {
name = r . FormValue ( "xid" )
honks = gethonksbyxonker ( u . UserID , name )
} else {
honks = gethonksbyhonker ( u . UserID , name )
}
2019-07-29 01:00:35 +02:00
name = html . EscapeString ( name )
2019-07-29 04:01:34 +02:00
msg := fmt . Sprintf ( ` honks by honker: <a href="%s" ref="noreferrer">%s</a> ` , name , name )
2019-07-29 01:00:35 +02:00
honkpage ( w , r , u , nil , honks , template . HTML ( msg ) )
2019-04-09 13:59:33 +02:00
}
2019-04-29 19:32:16 +02:00
func showcombo ( w http . ResponseWriter , r * http . Request ) {
2019-04-22 23:03:55 +02:00
name := mux . Vars ( r ) [ "name" ]
2019-04-25 05:57:01 +02:00
u := login . GetUserInfo ( r )
2019-04-22 23:03:55 +02:00
honks := gethonksbycombo ( u . UserID , name )
2019-06-18 07:35:58 +02:00
honks = osmosis ( honks , u . UserID )
2019-07-29 01:00:35 +02:00
honkpage ( w , r , u , nil , honks , template . HTML ( html . EscapeString ( "honks by combo: " + name ) ) )
2019-04-22 23:03:55 +02:00
}
2019-04-29 19:32:16 +02:00
func showconvoy ( w http . ResponseWriter , r * http . Request ) {
2019-04-24 08:37:36 +02:00
c := r . FormValue ( "c" )
2019-04-25 05:57:01 +02:00
u := login . GetUserInfo ( r )
2019-07-10 05:37:30 +02:00
honks := gethonksbyconvoy ( u . UserID , c )
2019-07-29 01:00:35 +02:00
honkpage ( w , r , u , nil , honks , template . HTML ( html . EscapeString ( "honks in convoy: " + c ) ) )
2019-04-24 08:37:36 +02:00
}
2019-08-30 17:46:25 +02:00
func showsearch ( w http . ResponseWriter , r * http . Request ) {
q := r . FormValue ( "q" )
u := login . GetUserInfo ( r )
honks := gethonksbysearch ( u . UserID , q )
honkpage ( w , r , u , nil , honks , template . HTML ( html . EscapeString ( "honks for search: " + q ) ) )
}
2019-08-25 05:03:05 +02:00
func showontology ( w http . ResponseWriter , r * http . Request ) {
name := mux . Vars ( r ) [ "name" ]
u := login . GetUserInfo ( r )
2019-08-26 04:53:56 +02:00
var userid int64 = - 1
if u != nil {
userid = u . UserID
}
honks := gethonksbyontology ( userid , "#" + name )
2019-08-25 05:03:05 +02:00
honkpage ( w , r , u , nil , honks , template . HTML ( html . EscapeString ( "honks by ontology: " + name ) ) )
}
2019-04-22 23:03:55 +02:00
2019-08-28 03:43:38 +02:00
func thelistingoftheontologies ( w http . ResponseWriter , r * http . Request ) {
2019-08-28 04:07:08 +02:00
u := login . GetUserInfo ( r )
var userid int64 = - 1
if u != nil {
userid = u . UserID
}
rows , err := stmtSelectOnts . Query ( userid )
2019-08-28 03:43:38 +02:00
if err != nil {
log . Printf ( "selection error: %s" , err )
return
}
var onts [ ] [ ] string
for rows . Next ( ) {
var o string
err := rows . Scan ( & o )
if err != nil {
log . Printf ( "error scanning ont: %s" , err )
continue
}
onts = append ( onts , [ ] string { o , o [ 1 : ] } )
}
2019-08-28 18:07:46 +02:00
if u == nil {
w . Header ( ) . Set ( "Cache-Control" , "max-age=300" )
}
2019-08-28 03:43:38 +02:00
templinfo := getInfo ( r )
templinfo [ "Onts" ] = onts
err = readviews . Execute ( w , "onts.html" , templinfo )
if err != nil {
log . Print ( err )
}
}
2019-04-29 19:32:16 +02:00
func showhonk ( w http . ResponseWriter , r * http . Request ) {
2019-04-09 13:59:33 +02:00
name := mux . Vars ( r ) [ "name" ]
user , err := butwhatabout ( name )
if err != nil {
http . NotFound ( w , r )
return
}
2019-06-25 03:14:47 +02:00
if stealthed ( r ) {
http . NotFound ( w , r )
return
}
2019-05-20 17:48:37 +02:00
xid := fmt . Sprintf ( "https://%s%s" , serverName , r . URL . Path )
2019-08-19 05:25:11 +02:00
honk := getxonk ( user . ID , xid )
if honk == nil {
2019-04-09 13:59:33 +02:00
http . NotFound ( w , r )
return
}
2019-07-04 16:52:22 +02:00
u := login . GetUserInfo ( r )
2019-07-10 05:31:57 +02:00
if u != nil && u . UserID != user . ID {
u = nil
}
2019-08-19 05:25:11 +02:00
if ! honk . Public {
2019-07-10 05:31:57 +02:00
if u == nil {
2019-07-04 16:52:22 +02:00
http . NotFound ( w , r )
return
}
2019-08-19 05:25:11 +02:00
honkpage ( w , r , u , nil , [ ] * Honk { honk } , "one honk maybe more" )
2019-07-04 16:52:22 +02:00
return
}
2019-08-19 05:25:11 +02:00
rawhonks := gethonksbyconvoy ( honk . UserID , honk . Convoy )
2019-04-09 13:59:33 +02:00
if friendorfoe ( r . Header . Get ( "Accept" ) ) {
2019-08-19 05:25:11 +02:00
for _ , h := range rawhonks {
2019-08-19 06:01:00 +02:00
if h . RID == honk . XID && h . Public && ( h . Whofore == 2 || h . IsAcked ( ) ) {
2019-08-19 05:25:11 +02:00
honk . Replies = append ( honk . Replies , h )
}
}
donksforhonks ( [ ] * Honk { honk } )
_ , j := jonkjonk ( user , honk )
2019-04-09 13:59:33 +02:00
j [ "@context" ] = itiswhatitis
w . Header ( ) . Set ( "Content-Type" , theonetruename )
2019-06-11 16:14:12 +02:00
j . Write ( w )
2019-04-09 13:59:33 +02:00
return
}
2019-08-16 21:35:12 +02:00
var honks [ ] * Honk
for _ , h := range rawhonks {
2019-08-19 06:01:00 +02:00
if h . Public && ( h . Whofore == 2 || h . IsAcked ( ) ) {
2019-08-16 21:35:12 +02:00
honks = append ( honks , h )
}
}
2019-05-13 19:00:56 +02:00
honkpage ( w , r , u , nil , honks , "one honk maybe more" )
2019-04-09 13:59:33 +02:00
}
2019-04-25 05:57:01 +02:00
func honkpage ( w http . ResponseWriter , r * http . Request , u * login . UserInfo , user * WhatAbout ,
2019-07-29 01:00:35 +02:00
honks [ ] * Honk , infomsg template . HTML ) {
2019-04-09 13:59:33 +02:00
templinfo := getInfo ( r )
2019-07-10 20:36:14 +02:00
var userid int64 = - 1
2019-04-23 22:48:25 +02:00
if u != nil {
2019-04-25 05:57:01 +02:00
templinfo [ "HonkCSRF" ] = login . GetCSRF ( "honkhonk" , r )
2019-07-10 20:36:14 +02:00
userid = u . UserID
2019-04-09 13:59:33 +02:00
}
2019-04-17 04:23:50 +02:00
if u == nil {
w . Header ( ) . Set ( "Cache-Control" , "max-age=60" )
}
2019-07-10 20:36:14 +02:00
reverbolate ( userid , honks )
2019-04-09 13:59:33 +02:00
if user != nil {
2019-05-18 01:37:43 +02:00
filt := htfilter . New ( )
2019-04-09 13:59:33 +02:00
templinfo [ "Name" ] = user . Name
whatabout := user . About
2019-05-15 01:18:29 +02:00
whatabout = obfusbreak ( user . About )
2019-05-18 01:37:43 +02:00
templinfo [ "WhatAbout" ] , _ = filt . String ( whatabout )
2019-04-09 13:59:33 +02:00
}
templinfo [ "Honks" ] = honks
2019-04-24 09:16:43 +02:00
templinfo [ "ServerMessage" ] = infomsg
2019-04-29 19:15:14 +02:00
err := readviews . Execute ( w , "honkpage.html" , templinfo )
2019-04-09 13:59:33 +02:00
if err != nil {
log . Print ( err )
}
}
func saveuser ( w http . ResponseWriter , r * http . Request ) {
whatabout := r . FormValue ( "whatabout" )
2019-04-25 05:57:01 +02:00
u := login . GetUserInfo ( r )
2019-04-09 13:59:33 +02:00
db := opendatabase ( )
2019-06-28 04:36:55 +02:00
options := ""
if r . FormValue ( "skinny" ) == "skinny" {
options += " skinny "
}
_ , err := db . Exec ( "update users set about = ?, options = ? where username = ?" , whatabout , options , u . Username )
2019-04-09 13:59:33 +02:00
if err != nil {
log . Printf ( "error bouting what: %s" , err )
}
2019-05-15 01:18:29 +02:00
http . Redirect ( w , r , "/account" , http . StatusSeeOther )
2019-04-09 13:59:33 +02:00
}
func gethonkers ( userid int64 ) [ ] * Honker {
rows , err := stmtHonkers . Query ( userid )
if err != nil {
log . Printf ( "error querying honkers: %s" , err )
return nil
}
defer rows . Close ( )
var honkers [ ] * Honker
for rows . Next ( ) {
var f Honker
2019-04-22 23:03:55 +02:00
var combos string
err = rows . Scan ( & f . ID , & f . UserID , & f . Name , & f . XID , & f . Flavor , & combos )
f . Combos = strings . Split ( strings . TrimSpace ( combos ) , " " )
2019-04-09 13:59:33 +02:00
if err != nil {
log . Printf ( "error scanning honker: %s" , err )
return nil
}
honkers = append ( honkers , & f )
}
return honkers
}
func getdubs ( userid int64 ) [ ] * Honker {
rows , err := stmtDubbers . Query ( userid )
if err != nil {
log . Printf ( "error querying dubs: %s" , err )
return nil
}
defer rows . Close ( )
var honkers [ ] * Honker
for rows . Next ( ) {
var f Honker
err = rows . Scan ( & f . ID , & f . UserID , & f . Name , & f . XID , & f . Flavor )
if err != nil {
log . Printf ( "error scanning honker: %s" , err )
return nil
}
honkers = append ( honkers , & f )
}
return honkers
}
2019-05-20 16:48:02 +02:00
func allusers ( ) [ ] login . UserInfo {
var users [ ] login . UserInfo
rows , _ := opendatabase ( ) . Query ( "select userid, username from users" )
defer rows . Close ( )
for rows . Next ( ) {
var u login . UserInfo
rows . Scan ( & u . UserID , & u . Username )
users = append ( users , u )
}
return users
}
2019-05-05 19:52:46 +02:00
func getxonk ( userid int64 , xid string ) * Honk {
2019-05-13 19:00:56 +02:00
h := new ( Honk )
2019-08-28 04:30:29 +02:00
var dt , aud , onts string
2019-05-05 19:52:46 +02:00
row := stmtOneXonk . QueryRow ( userid , xid )
2019-05-15 22:27:50 +02:00
err := row . Scan ( & h . ID , & h . UserID , & h . Username , & h . What , & h . Honker , & h . Oonker , & h . XID , & h . RID ,
2019-08-28 04:30:29 +02:00
& dt , & h . URL , & aud , & h . Noise , & h . Precis , & h . Convoy , & h . Whofore , & h . Flags , & onts )
2019-04-09 13:59:33 +02:00
if err != nil {
2019-04-20 05:00:46 +02:00
if err != sql . ErrNoRows {
log . Printf ( "error scanning xonk: %s" , err )
}
2019-04-09 13:59:33 +02:00
return nil
}
h . Date , _ = time . Parse ( dbtimeformat , dt )
h . Audience = strings . Split ( aud , " " )
2019-05-28 08:36:47 +02:00
h . Public = ! keepitquiet ( h . Audience )
2019-08-30 07:08:15 +02:00
if len ( onts ) > 0 {
h . Onts = strings . Split ( onts , " " )
}
2019-05-13 19:00:56 +02:00
return h
2019-04-09 13:59:33 +02:00
}
2019-08-28 03:22:59 +02:00
func getbonk ( userid int64 , xid string ) * Honk {
h := new ( Honk )
2019-08-28 04:30:29 +02:00
var dt , aud , onts string
2019-08-28 04:15:53 +02:00
row := stmtOneBonk . QueryRow ( userid , xid )
2019-08-28 03:22:59 +02:00
err := row . Scan ( & h . ID , & h . UserID , & h . Username , & h . What , & h . Honker , & h . Oonker , & h . XID , & h . RID ,
2019-08-28 04:30:29 +02:00
& dt , & h . URL , & aud , & h . Noise , & h . Precis , & h . Convoy , & h . Whofore , & h . Flags , & onts )
2019-08-28 03:22:59 +02:00
if err != nil {
if err != sql . ErrNoRows {
log . Printf ( "error scanning xonk: %s" , err )
}
return nil
}
h . Date , _ = time . Parse ( dbtimeformat , dt )
h . Audience = strings . Split ( aud , " " )
h . Public = ! keepitquiet ( h . Audience )
2019-08-30 07:08:15 +02:00
if len ( onts ) > 0 {
h . Onts = strings . Split ( onts , " " )
}
2019-08-28 03:22:59 +02:00
return h
}
2019-04-24 09:04:20 +02:00
func getpublichonks ( ) [ ] * Honk {
2019-05-05 19:54:13 +02:00
dt := time . Now ( ) . UTC ( ) . Add ( - 7 * 24 * time . Hour ) . Format ( dbtimeformat )
2019-05-03 21:28:56 +02:00
rows , err := stmtPublicHonks . Query ( dt )
2019-04-14 04:57:16 +02:00
return getsomehonks ( rows , err )
}
2019-05-28 08:36:47 +02:00
func gethonksbyuser ( name string , includeprivate bool ) [ ] * Honk {
2019-05-05 19:54:13 +02:00
dt := time . Now ( ) . UTC ( ) . Add ( - 7 * 24 * time . Hour ) . Format ( dbtimeformat )
2019-05-28 08:36:47 +02:00
whofore := 2
if includeprivate {
whofore = 3
}
rows , err := stmtUserHonks . Query ( whofore , name , dt )
2019-04-14 04:57:16 +02:00
return getsomehonks ( rows , err )
2019-04-09 13:59:33 +02:00
}
func gethonksforuser ( userid int64 ) [ ] * Honk {
2019-05-05 19:54:13 +02:00
dt := time . Now ( ) . UTC ( ) . Add ( - 7 * 24 * time . Hour ) . Format ( dbtimeformat )
2019-05-17 23:53:06 +02:00
rows , err := stmtHonksForUser . Query ( userid , dt , userid , userid )
2019-04-14 04:57:16 +02:00
return getsomehonks ( rows , err )
2019-04-09 13:59:33 +02:00
}
2019-04-20 17:17:00 +02:00
func gethonksforme ( userid int64 ) [ ] * Honk {
2019-05-05 19:54:13 +02:00
dt := time . Now ( ) . UTC ( ) . Add ( - 7 * 24 * time . Hour ) . Format ( dbtimeformat )
2019-05-03 21:28:56 +02:00
rows , err := stmtHonksForMe . Query ( userid , dt , userid )
2019-04-20 17:17:00 +02:00
return getsomehonks ( rows , err )
}
2019-04-09 13:59:33 +02:00
func gethonksbyhonker ( userid int64 , honker string ) [ ] * Honk {
2019-04-29 02:51:12 +02:00
rows , err := stmtHonksByHonker . Query ( userid , honker , userid )
2019-04-14 04:57:16 +02:00
return getsomehonks ( rows , err )
2019-04-09 13:59:33 +02:00
}
2019-06-16 21:05:50 +02:00
func gethonksbyxonker ( userid int64 , xonker string ) [ ] * Honk {
2019-07-10 05:43:46 +02:00
rows , err := stmtHonksByXonker . Query ( userid , xonker , xonker , userid )
2019-06-16 21:05:50 +02:00
return getsomehonks ( rows , err )
}
2019-04-22 23:03:55 +02:00
func gethonksbycombo ( userid int64 , combo string ) [ ] * Honk {
combo = "% " + combo + " %"
2019-04-29 02:51:12 +02:00
rows , err := stmtHonksByCombo . Query ( userid , combo , userid )
2019-04-22 23:03:55 +02:00
return getsomehonks ( rows , err )
}
2019-04-24 08:37:36 +02:00
func gethonksbyconvoy ( userid int64 , convoy string ) [ ] * Honk {
2019-07-10 05:37:30 +02:00
rows , err := stmtHonksByConvoy . Query ( userid , userid , convoy )
2019-05-13 19:00:56 +02:00
honks := getsomehonks ( rows , err )
for i , j := 0 , len ( honks ) - 1 ; i < j ; i , j = i + 1 , j - 1 {
honks [ i ] , honks [ j ] = honks [ j ] , honks [ i ]
}
return honks
2019-04-24 08:37:36 +02:00
}
2019-08-30 17:46:25 +02:00
func gethonksbysearch ( userid int64 , q string ) [ ] * Honk {
q = "%" + q + "%"
rows , err := stmtHonksBySearch . Query ( userid , q )
honks := getsomehonks ( rows , err )
return honks
}
2019-08-26 04:53:56 +02:00
func gethonksbyontology ( userid int64 , name string ) [ ] * Honk {
rows , err := stmtHonksByOntology . Query ( name , userid , userid )
2019-08-25 05:03:05 +02:00
honks := getsomehonks ( rows , err )
return honks
}
2019-04-09 13:59:33 +02:00
2019-04-14 04:57:16 +02:00
func getsomehonks ( rows * sql . Rows , err error ) [ ] * Honk {
2019-04-09 13:59:33 +02:00
if err != nil {
log . Printf ( "error querying honks: %s" , err )
return nil
}
defer rows . Close ( )
var honks [ ] * Honk
for rows . Next ( ) {
var h Honk
2019-08-28 04:30:29 +02:00
var dt , aud , onts string
err = rows . Scan ( & h . ID , & h . UserID , & h . Username , & h . What , & h . Honker , & h . Oonker , & h . XID ,
& h . RID , & dt , & h . URL , & aud , & h . Noise , & h . Precis , & h . Convoy , & h . Whofore , & h . Flags , & onts )
2019-04-09 13:59:33 +02:00
if err != nil {
log . Printf ( "error scanning honks: %s" , err )
return nil
}
h . Date , _ = time . Parse ( dbtimeformat , dt )
h . Audience = strings . Split ( aud , " " )
2019-05-28 08:36:47 +02:00
h . Public = ! keepitquiet ( h . Audience )
2019-08-30 07:08:15 +02:00
if len ( onts ) > 0 {
h . Onts = strings . Split ( onts , " " )
}
2019-04-09 13:59:33 +02:00
honks = append ( honks , & h )
}
rows . Close ( )
donksforhonks ( honks )
return honks
}
func donksforhonks ( honks [ ] * Honk ) {
db := opendatabase ( )
var ids [ ] string
2019-04-14 04:57:16 +02:00
hmap := make ( map [ int64 ] * Honk )
2019-04-09 13:59:33 +02:00
for _ , h := range honks {
ids = append ( ids , fmt . Sprintf ( "%d" , h . ID ) )
2019-04-14 04:57:16 +02:00
hmap [ h . ID ] = h
2019-04-09 13:59:33 +02:00
}
2019-05-25 19:34:41 +02:00
q := fmt . Sprintf ( "select honkid, donks.fileid, xid, name, url, media, local from donks join files on donks.fileid = files.fileid where honkid in (%s)" , strings . Join ( ids , "," ) )
2019-04-09 13:59:33 +02:00
rows , err := db . Query ( q )
if err != nil {
log . Printf ( "error querying donks: %s" , err )
return
}
defer rows . Close ( )
for rows . Next ( ) {
var hid int64
var d Donk
2019-05-25 19:34:41 +02:00
err = rows . Scan ( & hid , & d . FileID , & d . XID , & d . Name , & d . URL , & d . Media , & d . Local )
2019-04-09 13:59:33 +02:00
if err != nil {
log . Printf ( "error scanning donk: %s" , err )
continue
}
2019-04-14 04:57:16 +02:00
h := hmap [ hid ]
h . Donks = append ( h . Donks , & d )
2019-04-09 13:59:33 +02:00
}
}
func savebonk ( w http . ResponseWriter , r * http . Request ) {
xid := r . FormValue ( "xid" )
2019-05-05 19:52:46 +02:00
userinfo := login . GetUserInfo ( r )
2019-05-20 16:48:02 +02:00
user , _ := butwhatabout ( userinfo . Username )
2019-04-09 13:59:33 +02:00
log . Printf ( "bonking %s" , xid )
2019-05-05 19:52:46 +02:00
xonk := getxonk ( userinfo . UserID , xid )
2019-04-09 13:59:33 +02:00
if xonk == nil {
return
}
2019-05-28 08:36:47 +02:00
if ! xonk . Public {
return
}
2019-05-05 20:08:27 +02:00
donksforhonks ( [ ] * Honk { xonk } )
2019-04-09 13:59:33 +02:00
2019-08-28 03:22:59 +02:00
_ , err := stmtUpdateFlags . Exec ( flagIsBonked , xonk . ID )
2019-08-24 02:43:30 +02:00
if err != nil {
log . Printf ( "error acking bonk: %s" , err )
}
2019-06-26 23:19:45 +02:00
oonker := xonk . Oonker
if oonker == "" {
oonker = xonk . Honker
}
2019-04-09 13:59:33 +02:00
dt := time . Now ( ) . UTC ( )
bonk := Honk {
UserID : userinfo . UserID ,
Username : userinfo . Username ,
What : "bonk" ,
2019-05-20 16:48:02 +02:00
Honker : user . URL ,
2019-04-09 13:59:33 +02:00
XID : xonk . XID ,
Date : dt ,
Donks : xonk . Donks ,
2019-06-26 23:19:45 +02:00
Convoy : xonk . Convoy ,
2019-08-24 02:35:58 +02:00
Audience : [ ] string { thewholeworld , oonker } ,
2019-06-02 21:13:19 +02:00
Public : true ,
2019-04-09 13:59:33 +02:00
}
aud := strings . Join ( bonk . Audience , " " )
2019-05-20 16:48:02 +02:00
whofore := 2
2019-08-28 04:30:29 +02:00
onts := xonk . Onts
2019-05-20 16:48:02 +02:00
res , err := stmtSaveHonk . Exec ( userinfo . UserID , "bonk" , bonk . Honker , xid , "" ,
dt . Format ( dbtimeformat ) , "" , aud , xonk . Noise , xonk . Convoy , whofore , "html" ,
2019-08-25 05:11:53 +02:00
xonk . Precis , oonker , 0 , strings . Join ( onts , " " ) )
2019-04-09 13:59:33 +02:00
if err != nil {
log . Printf ( "error saving bonk: %s" , err )
return
}
bonk . ID , _ = res . LastInsertId ( )
for _ , d := range bonk . Donks {
_ , err = stmtSaveDonk . Exec ( bonk . ID , d . FileID )
if err != nil {
log . Printf ( "err saving donk: %s" , err )
return
}
}
2019-08-25 05:11:53 +02:00
for _ , o := range onts {
_ , err = stmtSaveOnts . Exec ( strings . ToLower ( o ) , bonk . ID )
if err != nil {
log . Printf ( "error saving ont: %s" , err )
}
}
2019-04-09 13:59:33 +02:00
go honkworldwide ( user , & bonk )
}
2019-08-21 07:23:00 +02:00
func sendzonkofsorts ( xonk * Honk , user * WhatAbout , what string ) {
zonk := Honk {
What : what ,
XID : xonk . XID ,
Date : time . Now ( ) . UTC ( ) ,
Audience : oneofakind ( xonk . Audience ) ,
}
zonk . Public = ! keepitquiet ( zonk . Audience )
log . Printf ( "announcing %sed honk: %s" , what , xonk . XID )
go honkworldwide ( user , & zonk )
}
2019-04-15 22:18:38 +02:00
func zonkit ( w http . ResponseWriter , r * http . Request ) {
2019-04-26 15:07:13 +02:00
wherefore := r . FormValue ( "wherefore" )
2019-06-17 18:10:36 +02:00
what := r . FormValue ( "what" )
2019-08-21 07:23:00 +02:00
userinfo := login . GetUserInfo ( r )
user , _ := butwhatabout ( userinfo . Username )
2019-08-16 21:35:12 +02:00
if wherefore == "ack" {
2019-08-21 07:23:00 +02:00
xonk := getxonk ( userinfo . UserID , what )
if xonk != nil {
2019-08-28 03:22:59 +02:00
_ , err := stmtUpdateFlags . Exec ( flagIsAcked , xonk . ID )
if err != nil {
log . Printf ( "error acking: %s" , err )
}
2019-08-21 07:23:00 +02:00
sendzonkofsorts ( xonk , user , "ack" )
}
2019-08-16 21:35:12 +02:00
return
2019-04-26 15:07:13 +02:00
}
2019-04-15 22:18:38 +02:00
2019-08-19 06:01:00 +02:00
if wherefore == "deack" {
2019-08-21 07:23:00 +02:00
xonk := getxonk ( userinfo . UserID , what )
if xonk != nil {
2019-08-28 03:22:59 +02:00
_ , err := stmtClearFlags . Exec ( flagIsAcked , xonk . ID )
if err != nil {
log . Printf ( "error deacking: %s" , err )
}
2019-08-21 07:23:00 +02:00
sendzonkofsorts ( xonk , user , "deack" )
}
2019-08-19 06:01:00 +02:00
return
}
2019-08-24 02:43:30 +02:00
if wherefore == "unbonk" {
2019-08-28 03:22:59 +02:00
xonk := getbonk ( userinfo . UserID , what )
if xonk != nil {
2019-08-28 04:15:53 +02:00
_ , err := stmtZonkDonks . Exec ( xonk . ID )
if err != nil {
log . Printf ( "error zonking: %s" , err )
}
_ , err = stmtZonkIt . Exec ( xonk . ID )
if err != nil {
log . Printf ( "error zonking: %s" , err )
}
xonk = getxonk ( userinfo . UserID , what )
_ , err = stmtClearFlags . Exec ( flagIsBonked , xonk . ID )
2019-08-28 03:22:59 +02:00
if err != nil {
log . Printf ( "error unbonking: %s" , err )
}
sendzonkofsorts ( xonk , user , "unbonk" )
}
2019-08-24 02:43:30 +02:00
return
}
2019-04-26 15:07:13 +02:00
log . Printf ( "zonking %s %s" , wherefore , what )
if wherefore == "zonk" {
2019-05-05 19:52:46 +02:00
xonk := getxonk ( userinfo . UserID , what )
if xonk != nil {
2019-08-16 06:15:55 +02:00
_ , err := stmtZonkDonks . Exec ( xonk . ID )
if err != nil {
log . Printf ( "error zonking: %s" , err )
}
2019-08-28 04:15:53 +02:00
_ , err = stmtZonkIt . Exec ( xonk . ID )
2019-08-16 06:15:55 +02:00
if err != nil {
log . Printf ( "error zonking: %s" , err )
}
2019-05-28 08:36:47 +02:00
if xonk . Whofore == 2 || xonk . Whofore == 3 {
2019-08-21 07:23:00 +02:00
sendzonkofsorts ( xonk , user , "zonk" )
2019-05-05 19:52:46 +02:00
}
2019-05-03 19:42:39 +02:00
}
2019-06-17 18:10:36 +02:00
}
_ , err := stmtSaveZonker . Exec ( userinfo . UserID , what , wherefore )
if err != nil {
log . Printf ( "error saving zonker: %s" , err )
return
2019-04-26 15:07:13 +02:00
}
2019-04-15 22:18:38 +02:00
}
2019-04-09 13:59:33 +02:00
func savehonk ( w http . ResponseWriter , r * http . Request ) {
rid := r . FormValue ( "rid" )
noise := r . FormValue ( "noise" )
2019-04-25 05:57:01 +02:00
userinfo := login . GetUserInfo ( r )
2019-05-20 16:48:02 +02:00
user , _ := butwhatabout ( userinfo . Username )
2019-04-09 13:59:33 +02:00
dt := time . Now ( ) . UTC ( )
2019-07-23 19:21:09 +02:00
xid := fmt . Sprintf ( "%s/%s/%s" , user . URL , honkSep , xfiltrate ( ) )
2019-04-09 13:59:33 +02:00
what := "honk"
if rid != "" {
what = "tonk"
}
honk := Honk {
UserID : userinfo . UserID ,
Username : userinfo . Username ,
What : "honk" ,
2019-05-20 16:48:02 +02:00
Honker : user . URL ,
2019-04-09 13:59:33 +02:00
XID : xid ,
Date : dt ,
}
2019-05-15 22:27:50 +02:00
if strings . HasPrefix ( noise , "DZ:" ) {
idx := strings . Index ( noise , "\n" )
if idx == - 1 {
honk . Precis = noise
noise = ""
} else {
honk . Precis = noise [ : idx ]
noise = noise [ idx + 1 : ]
}
}
2019-06-05 09:52:56 +02:00
noise = hooterize ( noise )
2019-05-15 22:27:50 +02:00
noise = strings . TrimSpace ( noise )
honk . Precis = strings . TrimSpace ( honk . Precis )
2019-04-19 17:50:35 +02:00
var convoy string
2019-04-09 13:59:33 +02:00
if rid != "" {
2019-05-05 19:52:46 +02:00
xonk := getxonk ( userinfo . UserID , rid )
2019-04-11 16:30:53 +02:00
if xonk != nil {
2019-06-02 08:36:10 +02:00
if xonk . Public {
honk . Audience = append ( honk . Audience , xonk . Audience ... )
}
2019-04-19 17:50:35 +02:00
convoy = xonk . Convoy
2019-04-11 16:44:50 +02:00
} else {
2019-04-19 17:50:35 +02:00
xonkaud , c := whosthere ( rid )
2019-04-11 16:44:50 +02:00
honk . Audience = append ( honk . Audience , xonkaud ... )
2019-04-19 17:50:35 +02:00
convoy = c
2019-04-11 16:30:53 +02:00
}
2019-05-28 08:36:47 +02:00
for i , a := range honk . Audience {
if a == thewholeworld {
honk . Audience [ 0 ] , honk . Audience [ i ] = honk . Audience [ i ] , honk . Audience [ 0 ]
break
}
}
2019-04-25 19:10:26 +02:00
honk . RID = rid
2019-05-28 08:36:47 +02:00
} else {
honk . Audience = [ ] string { thewholeworld }
}
if noise != "" && noise [ 0 ] == '@' {
honk . Audience = append ( grapevine ( noise ) , honk . Audience ... )
} else {
honk . Audience = append ( honk . Audience , grapevine ( noise ) ... )
2019-04-09 13:59:33 +02:00
}
2019-04-19 17:50:35 +02:00
if convoy == "" {
convoy = "data:,electrichonkytonk-" + xfiltrate ( )
}
2019-05-03 20:09:08 +02:00
butnottooloud ( honk . Audience )
2019-04-09 13:59:33 +02:00
honk . Audience = oneofakind ( honk . Audience )
2019-06-02 08:36:10 +02:00
if len ( honk . Audience ) == 0 {
log . Printf ( "honk to nowhere" )
2019-06-26 01:17:39 +02:00
http . Error ( w , "honk to nowhere..." , http . StatusNotFound )
2019-06-02 08:36:10 +02:00
return
}
2019-05-28 08:36:47 +02:00
honk . Public = ! keepitquiet ( honk . Audience )
2019-04-09 13:59:33 +02:00
noise = obfusbreak ( noise )
honk . Noise = noise
2019-04-19 17:50:35 +02:00
honk . Convoy = convoy
2019-04-09 13:59:33 +02:00
2019-08-02 16:38:42 +02:00
donkxid := r . FormValue ( "donkxid" )
if donkxid == "" {
file , filehdr , err := r . FormFile ( "donk" )
2019-04-15 16:04:41 +02:00
if err == nil {
2019-08-02 16:38:42 +02:00
var buf bytes . Buffer
io . Copy ( & buf , file )
file . Close ( )
data := buf . Bytes ( )
xid := xfiltrate ( )
var media , name string
img , err := image . Vacuum ( & buf , image . Params { MaxWidth : 2048 , MaxHeight : 2048 } )
if err == nil {
data = img . Data
format := img . Format
media = "image/" + format
if format == "jpeg" {
format = "jpg"
}
name = xid + "." + format
xid = name
} else {
maxsize := 100000
if len ( data ) > maxsize {
log . Printf ( "bad image: %s too much text: %d" , err , len ( data ) )
2019-04-15 16:04:41 +02:00
http . Error ( w , "didn't like your attachment" , http . StatusUnsupportedMediaType )
return
}
2019-08-02 16:38:42 +02:00
for i := 0 ; i < len ( data ) ; i ++ {
if data [ i ] < 32 && data [ i ] != '\t' && data [ i ] != '\r' && data [ i ] != '\n' {
log . Printf ( "bad image: %s not text: %d" , err , data [ i ] )
http . Error ( w , "didn't like your attachment" , http . StatusUnsupportedMediaType )
return
}
}
media = "text/plain"
name = filehdr . Filename
if name == "" {
name = xid + ".txt"
}
xid += ".txt"
2019-04-15 16:04:41 +02:00
}
2019-08-02 16:38:42 +02:00
url := fmt . Sprintf ( "https://%s/d/%s" , serverName , xid )
res , err := stmtSaveFile . Exec ( xid , name , url , media , 1 , data )
if err != nil {
log . Printf ( "unable to save image: %s" , err )
return
2019-04-15 16:04:41 +02:00
}
2019-08-02 16:38:42 +02:00
var d Donk
d . FileID , _ = res . LastInsertId ( )
d . XID = name
d . Name = name
d . Media = media
d . URL = url
d . Local = true
honk . Donks = append ( honk . Donks , & d )
donkxid = d . XID
2019-04-09 13:59:33 +02:00
}
2019-08-02 16:38:42 +02:00
} else {
xid := donkxid
2019-04-15 16:04:41 +02:00
url := fmt . Sprintf ( "https://%s/d/%s" , serverName , xid )
2019-08-02 16:38:42 +02:00
var donk Donk
row := stmtFindFile . QueryRow ( url )
err := row . Scan ( & donk . FileID )
if err == nil {
donk . XID = xid
donk . Local = true
donk . URL = url
honk . Donks = append ( honk . Donks , & donk )
} else {
log . Printf ( "can't find file: %s" , xid )
2019-04-09 13:59:33 +02:00
}
}
2019-04-12 21:26:29 +02:00
herd := herdofemus ( honk . Noise )
for _ , e := range herd {
2019-05-28 10:23:36 +02:00
donk := savedonk ( e . ID , e . Name , "image/png" , true )
2019-04-12 21:26:29 +02:00
if donk != nil {
2019-04-18 22:34:51 +02:00
donk . Name = e . Name
2019-04-12 21:26:29 +02:00
honk . Donks = append ( honk . Donks , donk )
}
}
2019-07-01 01:04:37 +02:00
memetize ( & honk )
2019-04-09 13:59:33 +02:00
aud := strings . Join ( honk . Audience , " " )
2019-05-20 16:48:02 +02:00
whofore := 2
2019-05-28 08:36:47 +02:00
if ! honk . Public {
whofore = 3
}
2019-06-16 20:11:23 +02:00
if r . FormValue ( "preview" ) == "preview" {
2019-06-16 21:05:50 +02:00
honks := [ ] * Honk { & honk }
2019-07-10 20:36:14 +02:00
reverbolate ( userinfo . UserID , honks )
2019-06-16 20:11:23 +02:00
templinfo := getInfo ( r )
templinfo [ "HonkCSRF" ] = login . GetCSRF ( "honkhonk" , r )
templinfo [ "Honks" ] = honks
2019-07-31 03:20:56 +02:00
templinfo [ "InReplyTo" ] = r . FormValue ( "rid" )
2019-06-16 20:11:23 +02:00
templinfo [ "Noise" ] = r . FormValue ( "noise" )
2019-08-02 16:38:42 +02:00
templinfo [ "SavedFile" ] = donkxid
2019-06-16 20:11:23 +02:00
templinfo [ "ServerMessage" ] = "honk preview"
err := readviews . Execute ( w , "honkpage.html" , templinfo )
if err != nil {
log . Print ( err )
}
return
}
2019-08-28 18:07:46 +02:00
honk . Onts = oneofakind ( ontologies ( honk . Noise ) )
2019-05-20 16:48:02 +02:00
res , err := stmtSaveHonk . Exec ( userinfo . UserID , what , honk . Honker , xid , rid ,
2019-08-16 21:13:33 +02:00
dt . Format ( dbtimeformat ) , "" , aud , honk . Noise , convoy , whofore , "html" ,
2019-08-28 18:07:46 +02:00
honk . Precis , honk . Oonker , 0 , strings . Join ( honk . Onts , " " ) )
2019-04-09 13:59:33 +02:00
if err != nil {
log . Printf ( "error saving honk: %s" , err )
2019-07-02 01:31:14 +02:00
http . Error ( w , "something bad happened while saving" , http . StatusInternalServerError )
2019-04-09 13:59:33 +02:00
return
}
honk . ID , _ = res . LastInsertId ( )
for _ , d := range honk . Donks {
_ , err = stmtSaveDonk . Exec ( honk . ID , d . FileID )
if err != nil {
log . Printf ( "err saving donk: %s" , err )
2019-07-02 01:31:14 +02:00
http . Error ( w , "something bad happened while saving" , http . StatusInternalServerError )
2019-04-09 13:59:33 +02:00
return
}
}
2019-08-28 18:07:46 +02:00
for _ , o := range honk . Onts {
2019-08-25 05:11:53 +02:00
_ , err = stmtSaveOnts . Exec ( strings . ToLower ( o ) , honk . ID )
if err != nil {
log . Printf ( "error saving ont: %s" , err )
}
}
2019-04-09 13:59:33 +02:00
2019-08-16 06:28:16 +02:00
go honkworldwide ( user , & honk )
2019-04-09 13:59:33 +02:00
2019-07-02 01:29:50 +02:00
http . Redirect ( w , r , xid , http . StatusSeeOther )
2019-04-09 13:59:33 +02:00
}
2019-04-29 19:32:16 +02:00
func showhonkers ( w http . ResponseWriter , r * http . Request ) {
2019-04-25 05:57:01 +02:00
userinfo := login . GetUserInfo ( r )
2019-04-09 13:59:33 +02:00
templinfo := getInfo ( r )
templinfo [ "Honkers" ] = gethonkers ( userinfo . UserID )
2019-04-25 05:57:01 +02:00
templinfo [ "HonkerCSRF" ] = login . GetCSRF ( "savehonker" , r )
2019-04-29 19:15:14 +02:00
err := readviews . Execute ( w , "honkers.html" , templinfo )
2019-04-09 13:59:33 +02:00
if err != nil {
log . Print ( err )
}
}
2019-05-01 00:48:13 +02:00
func showcombos ( w http . ResponseWriter , r * http . Request ) {
userinfo := login . GetUserInfo ( r )
templinfo := getInfo ( r )
honkers := gethonkers ( userinfo . UserID )
var combos [ ] string
for _ , h := range honkers {
combos = append ( combos , h . Combos ... )
}
2019-05-17 23:53:06 +02:00
for i , c := range combos {
if c == "-" {
combos [ i ] = ""
}
}
2019-05-01 00:48:13 +02:00
combos = oneofakind ( combos )
sort . Strings ( combos )
templinfo [ "Combos" ] = combos
err := readviews . Execute ( w , "combos.html" , templinfo )
if err != nil {
log . Print ( err )
}
}
2019-04-09 13:59:33 +02:00
func savehonker ( w http . ResponseWriter , r * http . Request ) {
2019-04-25 05:57:01 +02:00
u := login . GetUserInfo ( r )
2019-04-09 13:59:33 +02:00
name := r . FormValue ( "name" )
url := r . FormValue ( "url" )
peep := r . FormValue ( "peep" )
2019-04-22 23:03:55 +02:00
combos := r . FormValue ( "combos" )
honkerid , _ := strconv . ParseInt ( r . FormValue ( "honkerid" ) , 10 , 0 )
if honkerid > 0 {
2019-04-26 21:31:42 +02:00
goodbye := r . FormValue ( "goodbye" )
2019-05-26 22:04:39 +02:00
if goodbye == "F" {
2019-04-26 21:31:42 +02:00
db := opendatabase ( )
row := db . QueryRow ( "select xid from honkers where honkerid = ? and userid = ?" ,
honkerid , u . UserID )
var xid string
err := row . Scan ( & xid )
if err != nil {
log . Printf ( "can't get honker xid: %s" , err )
return
}
log . Printf ( "unsubscribing from %s" , xid )
user , _ := butwhatabout ( u . Username )
2019-06-11 05:57:03 +02:00
go itakeitallback ( user , xid )
_ , err = stmtUpdateFlavor . Exec ( "unsub" , u . UserID , xid , "sub" )
2019-04-26 21:31:42 +02:00
if err != nil {
2019-06-11 05:57:03 +02:00
log . Printf ( "error updating honker: %s" , err )
return
2019-04-26 21:31:42 +02:00
}
http . Redirect ( w , r , "/honkers" , http . StatusSeeOther )
return
}
2019-04-22 23:03:55 +02:00
combos = " " + strings . TrimSpace ( combos ) + " "
2019-04-29 04:48:46 +02:00
_ , err := stmtUpdateCombos . Exec ( combos , honkerid , u . UserID )
2019-04-22 23:03:55 +02:00
if err != nil {
log . Printf ( "update honker err: %s" , err )
return
}
http . Redirect ( w , r , "/honkers" , http . StatusSeeOther )
}
2019-04-09 13:59:33 +02:00
flavor := "presub"
if peep == "peep" {
flavor = "peep"
}
2019-08-30 16:16:59 +02:00
p , err := investigate ( url )
if err != nil {
http . Error ( w , "error investigating: " + err . Error ( ) , http . StatusInternalServerError )
2019-08-16 05:27:55 +02:00
log . Printf ( "failed to investigate honker" )
2019-04-09 13:59:33 +02:00
return
}
2019-08-16 05:27:55 +02:00
url = p . XID
if name == "" {
name = p . Handle
}
2019-08-30 16:16:59 +02:00
_ , err = stmtSaveHonker . Exec ( u . UserID , name , url , flavor , combos )
2019-04-09 13:59:33 +02:00
if err != nil {
log . Print ( err )
2019-04-22 23:03:55 +02:00
return
2019-04-09 13:59:33 +02:00
}
if flavor == "presub" {
user , _ := butwhatabout ( u . Username )
go subsub ( user , url )
}
http . Redirect ( w , r , "/honkers" , http . StatusSeeOther )
}
2019-04-22 19:08:35 +02:00
type Zonker struct {
2019-04-26 21:11:24 +02:00
ID int64
2019-04-22 22:14:32 +02:00
Name string
2019-04-22 19:08:35 +02:00
Wherefore string
}
2019-06-02 04:58:46 +02:00
func zonkzone ( w http . ResponseWriter , r * http . Request ) {
2019-04-25 05:57:01 +02:00
userinfo := login . GetUserInfo ( r )
2019-06-17 03:21:56 +02:00
rows , err := stmtGetZonkers . Query ( userinfo . UserID )
2019-04-22 19:08:35 +02:00
if err != nil {
log . Printf ( "err: %s" , err )
return
}
2019-06-17 03:21:56 +02:00
defer rows . Close ( )
2019-04-22 19:08:35 +02:00
var zonkers [ ] Zonker
for rows . Next ( ) {
var z Zonker
2019-04-26 21:11:24 +02:00
rows . Scan ( & z . ID , & z . Name , & z . Wherefore )
2019-04-22 19:08:35 +02:00
zonkers = append ( zonkers , z )
}
2019-06-16 21:05:50 +02:00
sort . Slice ( zonkers , func ( i , j int ) bool {
2019-06-16 20:41:47 +02:00
w1 := zonkers [ i ] . Wherefore
w2 := zonkers [ j ] . Wherefore
if w1 == w2 {
return zonkers [ i ] . Name < zonkers [ j ] . Name
}
if w1 == "zonvoy" {
w1 = "zzzzzzz"
}
if w2 == "zonvoy" {
w2 = "zzzzzzz"
}
return w1 < w2
} )
2019-04-22 19:08:35 +02:00
templinfo := getInfo ( r )
templinfo [ "Zonkers" ] = zonkers
2019-06-02 04:58:46 +02:00
templinfo [ "ZonkCSRF" ] = login . GetCSRF ( "zonkzonk" , r )
2019-04-29 19:15:14 +02:00
err = readviews . Execute ( w , "zonkers.html" , templinfo )
2019-04-22 19:08:35 +02:00
if err != nil {
log . Print ( err )
}
}
2019-06-02 04:58:46 +02:00
func zonkzonk ( w http . ResponseWriter , r * http . Request ) {
2019-04-25 05:57:01 +02:00
userinfo := login . GetUserInfo ( r )
2019-04-26 21:11:24 +02:00
itsok := r . FormValue ( "itsok" )
if itsok == "iforgiveyou" {
zonkerid , _ := strconv . ParseInt ( r . FormValue ( "zonkerid" ) , 10 , 0 )
db := opendatabase ( )
db . Exec ( "delete from zonkers where userid = ? and zonkerid = ?" ,
userinfo . UserID , zonkerid )
bitethethumbs ( )
2019-06-02 04:58:46 +02:00
http . Redirect ( w , r , "/zonkzone" , http . StatusSeeOther )
2019-04-26 21:11:24 +02:00
return
}
2019-04-22 19:08:35 +02:00
wherefore := r . FormValue ( "wherefore" )
name := r . FormValue ( "name" )
if name == "" {
return
}
switch wherefore {
case "zonker" :
2019-06-24 04:21:59 +02:00
case "zomain" :
2019-04-22 19:08:35 +02:00
case "zonvoy" :
2019-06-24 04:21:59 +02:00
case "zord" :
2019-07-10 23:39:41 +02:00
case "zilence" :
2019-04-22 19:08:35 +02:00
default :
return
}
db := opendatabase ( )
db . Exec ( "insert into zonkers (userid, name, wherefore) values (?, ?, ?)" ,
2019-04-26 23:01:17 +02:00
userinfo . UserID , name , wherefore )
2019-07-10 23:39:41 +02:00
if wherefore == "zonker" || wherefore == "zomain" || wherefore == "zord" || wherefore == "zilence" {
2019-04-26 21:11:24 +02:00
bitethethumbs ( )
}
2019-04-22 19:08:35 +02:00
2019-06-02 04:58:46 +02:00
http . Redirect ( w , r , "/zonkzone" , http . StatusSeeOther )
2019-04-22 19:08:35 +02:00
}
2019-05-15 01:18:29 +02:00
func accountpage ( w http . ResponseWriter , r * http . Request ) {
u := login . GetUserInfo ( r )
user , _ := butwhatabout ( u . Username )
templinfo := getInfo ( r )
templinfo [ "UserCSRF" ] = login . GetCSRF ( "saveuser" , r )
templinfo [ "LogoutCSRF" ] = login . GetCSRF ( "logout" , r )
2019-06-28 04:36:55 +02:00
templinfo [ "User" ] = user
2019-05-15 01:18:29 +02:00
err := readviews . Execute ( w , "account.html" , templinfo )
if err != nil {
log . Print ( err )
}
}
func dochpass ( w http . ResponseWriter , r * http . Request ) {
err := login . ChangePassword ( w , r )
if err != nil {
log . Printf ( "error changing password: %s" , err )
}
http . Redirect ( w , r , "/account" , http . StatusSeeOther )
}
2019-05-13 19:02:12 +02:00
func fingerlicker ( w http . ResponseWriter , r * http . Request ) {
orig := r . FormValue ( "resource" )
log . Printf ( "finger lick: %s" , orig )
if strings . HasPrefix ( orig , "acct:" ) {
orig = orig [ 5 : ]
}
name := orig
idx := strings . LastIndexByte ( name , '/' )
if idx != - 1 {
name = name [ idx + 1 : ]
2019-07-23 19:21:09 +02:00
if fmt . Sprintf ( "https://%s/%s/%s" , serverName , userSep , name ) != orig {
2019-05-13 19:02:12 +02:00
log . Printf ( "foreign request rejected" )
name = ""
}
} else {
idx = strings . IndexByte ( name , '@' )
if idx != - 1 {
name = name [ : idx ]
if name + "@" + serverName != orig {
log . Printf ( "foreign request rejected" )
name = ""
}
}
}
user , err := butwhatabout ( name )
if err != nil {
http . NotFound ( w , r )
return
}
2019-06-11 16:14:12 +02:00
j := junk . New ( )
2019-05-13 19:02:12 +02:00
j [ "subject" ] = fmt . Sprintf ( "acct:%s@%s" , user . Name , serverName )
j [ "aliases" ] = [ ] string { user . URL }
2019-07-29 02:01:12 +02:00
var links [ ] junk . Junk
2019-06-11 16:14:12 +02:00
l := junk . New ( )
2019-05-13 19:02:12 +02:00
l [ "rel" ] = "self"
l [ "type" ] = ` application/activity+json `
l [ "href" ] = user . URL
links = append ( links , l )
j [ "links" ] = links
w . Header ( ) . Set ( "Cache-Control" , "max-age=3600" )
w . Header ( ) . Set ( "Content-Type" , "application/jrd+json" )
2019-06-11 16:14:12 +02:00
j . Write ( w )
2019-05-13 19:02:12 +02:00
}
2019-04-16 02:52:24 +02:00
func somedays ( ) string {
secs := 432000 + notrand . Int63n ( 432000 )
return fmt . Sprintf ( "%d" , secs )
}
2019-04-09 13:59:33 +02:00
func avatate ( w http . ResponseWriter , r * http . Request ) {
n := r . FormValue ( "a" )
a := avatar ( n )
2019-04-16 02:52:24 +02:00
w . Header ( ) . Set ( "Cache-Control" , "max-age=" + somedays ( ) )
2019-04-09 13:59:33 +02:00
w . Write ( a )
}
func servecss ( w http . ResponseWriter , r * http . Request ) {
2019-09-04 19:19:52 +02:00
data , _ := ioutil . ReadFile ( "views" + r . URL . Path )
s := css . Process ( string ( data ) )
2019-04-09 13:59:33 +02:00
w . Header ( ) . Set ( "Cache-Control" , "max-age=7776000" )
2019-09-04 19:19:52 +02:00
w . Header ( ) . Set ( "Content-Type" , "text/css; charset=utf-8" )
w . Write ( [ ] byte ( s ) )
2019-04-09 13:59:33 +02:00
}
func servehtml ( w http . ResponseWriter , r * http . Request ) {
templinfo := getInfo ( r )
2019-04-29 19:15:14 +02:00
err := readviews . Execute ( w , r . URL . Path [ 1 : ] + ".html" , templinfo )
2019-04-09 13:59:33 +02:00
if err != nil {
log . Print ( err )
}
}
2019-04-12 21:02:56 +02:00
func serveemu ( w http . ResponseWriter , r * http . Request ) {
xid := mux . Vars ( r ) [ "xid" ]
2019-04-16 02:52:24 +02:00
w . Header ( ) . Set ( "Cache-Control" , "max-age=" + somedays ( ) )
2019-04-12 21:02:56 +02:00
http . ServeFile ( w , r , "emus/" + xid )
}
2019-05-31 06:24:18 +02:00
func servememe ( w http . ResponseWriter , r * http . Request ) {
xid := mux . Vars ( r ) [ "xid" ]
w . Header ( ) . Set ( "Cache-Control" , "max-age=" + somedays ( ) )
http . ServeFile ( w , r , "memes/" + xid )
}
2019-04-09 13:59:33 +02:00
func servefile ( w http . ResponseWriter , r * http . Request ) {
xid := mux . Vars ( r ) [ "xid" ]
row := stmtFileData . QueryRow ( xid )
2019-04-15 16:04:41 +02:00
var media string
2019-04-09 13:59:33 +02:00
var data [ ] byte
2019-04-15 16:04:41 +02:00
err := row . Scan ( & media , & data )
2019-04-09 13:59:33 +02:00
if err != nil {
log . Printf ( "error loading file: %s" , err )
http . NotFound ( w , r )
return
}
2019-04-15 16:04:41 +02:00
w . Header ( ) . Set ( "Content-Type" , media )
2019-04-17 18:32:50 +02:00
w . Header ( ) . Set ( "X-Content-Type-Options" , "nosniff" )
2019-04-16 02:52:24 +02:00
w . Header ( ) . Set ( "Cache-Control" , "max-age=" + somedays ( ) )
2019-04-09 13:59:33 +02:00
w . Write ( data )
}
2019-06-17 19:06:54 +02:00
func nomoroboto ( w http . ResponseWriter , r * http . Request ) {
io . WriteString ( w , "User-agent: *\n" )
2019-07-19 01:16:12 +02:00
io . WriteString ( w , "Disallow: /a\n" )
io . WriteString ( w , "Disallow: /d\n" )
io . WriteString ( w , "Disallow: /meme\n" )
2019-06-17 19:06:54 +02:00
for _ , u := range allusers ( ) {
2019-07-23 19:21:09 +02:00
fmt . Fprintf ( w , "Disallow: /%s/%s/%s/\n" , userSep , u . Username , honkSep )
2019-06-17 19:06:54 +02:00
}
}
2019-04-09 13:59:33 +02:00
func serve ( ) {
db := opendatabase ( )
2019-04-25 05:57:01 +02:00
login . Init ( db )
2019-04-09 13:59:33 +02:00
listener , err := openListener ( )
if err != nil {
log . Fatal ( err )
}
2019-04-15 03:35:42 +02:00
go redeliverator ( )
2019-04-09 13:59:33 +02:00
debug := false
getconfig ( "debug" , & debug )
2019-04-29 19:15:14 +02:00
readviews = templates . Load ( debug ,
2019-04-09 13:59:33 +02:00
"views/honkpage.html" ,
2019-08-19 09:02:24 +02:00
"views/honkfrags.html" ,
2019-04-09 13:59:33 +02:00
"views/honkers.html" ,
2019-04-22 19:08:35 +02:00
"views/zonkers.html" ,
2019-05-01 00:48:13 +02:00
"views/combos.html" ,
2019-04-09 13:59:33 +02:00
"views/honkform.html" ,
"views/honk.html" ,
2019-05-15 01:18:29 +02:00
"views/account.html" ,
2019-06-08 21:31:00 +02:00
"views/about.html" ,
2019-06-24 06:31:34 +02:00
"views/funzone.html" ,
2019-04-09 13:59:33 +02:00
"views/login.html" ,
2019-06-11 04:28:09 +02:00
"views/xzone.html" ,
2019-04-09 13:59:33 +02:00
"views/header.html" ,
2019-08-28 03:43:38 +02:00
"views/onts.html" ,
2019-04-09 13:59:33 +02:00
)
if ! debug {
2019-04-12 19:12:18 +02:00
s := "views/style.css"
savedstyleparams [ s ] = getstyleparam ( s )
s = "views/local.css"
savedstyleparams [ s ] = getstyleparam ( s )
2019-04-09 13:59:33 +02:00
}
2019-04-26 21:11:24 +02:00
bitethethumbs ( )
2019-04-09 13:59:33 +02:00
mux := mux . NewRouter ( )
2019-04-25 05:57:01 +02:00
mux . Use ( login . Checker )
2019-04-09 13:59:33 +02:00
posters := mux . Methods ( "POST" ) . Subrouter ( )
getters := mux . Methods ( "GET" ) . Subrouter ( )
getters . HandleFunc ( "/" , homepage )
2019-09-05 23:29:40 +02:00
getters . HandleFunc ( "/home" , homepage )
2019-06-24 04:43:47 +02:00
getters . HandleFunc ( "/front" , homepage )
2019-06-17 19:06:54 +02:00
getters . HandleFunc ( "/robots.txt" , nomoroboto )
2019-04-09 13:59:33 +02:00
getters . HandleFunc ( "/rss" , showrss )
2019-07-23 19:21:09 +02:00
getters . HandleFunc ( "/" + userSep + "/{name:[[:alnum:]]+}" , showuser )
getters . HandleFunc ( "/" + userSep + "/{name:[[:alnum:]]+}/" + honkSep + "/{xid:[[:alnum:]]+}" , showhonk )
getters . HandleFunc ( "/" + userSep + "/{name:[[:alnum:]]+}/rss" , showrss )
posters . HandleFunc ( "/" + userSep + "/{name:[[:alnum:]]+}/inbox" , inbox )
getters . HandleFunc ( "/" + userSep + "/{name:[[:alnum:]]+}/outbox" , outbox )
getters . HandleFunc ( "/" + userSep + "/{name:[[:alnum:]]+}/followers" , emptiness )
getters . HandleFunc ( "/" + userSep + "/{name:[[:alnum:]]+}/following" , emptiness )
2019-04-09 13:59:33 +02:00
getters . HandleFunc ( "/a" , avatate )
2019-08-28 03:43:38 +02:00
getters . HandleFunc ( "/o" , thelistingoftheontologies )
2019-08-25 05:03:05 +02:00
getters . HandleFunc ( "/o/{name:[a-z0-9-]+}" , showontology )
2019-04-09 13:59:33 +02:00
getters . HandleFunc ( "/d/{xid:[[:alnum:].]+}" , servefile )
2019-05-31 06:24:18 +02:00
getters . HandleFunc ( "/emu/{xid:[[:alnum:]_.-]+}" , serveemu )
getters . HandleFunc ( "/meme/{xid:[[:alnum:]_.-]+}" , servememe )
2019-04-09 13:59:33 +02:00
getters . HandleFunc ( "/.well-known/webfinger" , fingerlicker )
getters . HandleFunc ( "/style.css" , servecss )
2019-04-12 19:12:18 +02:00
getters . HandleFunc ( "/local.css" , servecss )
2019-06-08 21:31:00 +02:00
getters . HandleFunc ( "/about" , servehtml )
2019-04-09 13:59:33 +02:00
getters . HandleFunc ( "/login" , servehtml )
2019-04-25 05:57:01 +02:00
posters . HandleFunc ( "/dologin" , login . LoginFunc )
getters . HandleFunc ( "/logout" , login . LogoutFunc )
2019-04-09 13:59:33 +02:00
loggedin := mux . NewRoute ( ) . Subrouter ( )
2019-04-25 05:57:01 +02:00
loggedin . Use ( login . Required )
2019-05-15 01:18:29 +02:00
loggedin . HandleFunc ( "/account" , accountpage )
2019-06-24 06:31:34 +02:00
loggedin . HandleFunc ( "/funzone" , showfunzone )
2019-05-15 01:18:29 +02:00
loggedin . HandleFunc ( "/chpass" , dochpass )
2019-04-22 22:14:32 +02:00
loggedin . HandleFunc ( "/atme" , homepage )
2019-06-02 04:58:46 +02:00
loggedin . HandleFunc ( "/zonkzone" , zonkzone )
2019-06-11 04:28:09 +02:00
loggedin . HandleFunc ( "/xzone" , xzone )
2019-04-25 05:57:01 +02:00
loggedin . Handle ( "/honk" , login . CSRFWrap ( "honkhonk" , http . HandlerFunc ( savehonk ) ) )
loggedin . Handle ( "/bonk" , login . CSRFWrap ( "honkhonk" , http . HandlerFunc ( savebonk ) ) )
loggedin . Handle ( "/zonkit" , login . CSRFWrap ( "honkhonk" , http . HandlerFunc ( zonkit ) ) )
2019-06-02 04:58:46 +02:00
loggedin . Handle ( "/zonkzonk" , login . CSRFWrap ( "zonkzonk" , http . HandlerFunc ( zonkzonk ) ) )
2019-04-25 05:57:01 +02:00
loggedin . Handle ( "/saveuser" , login . CSRFWrap ( "saveuser" , http . HandlerFunc ( saveuser ) ) )
2019-06-11 04:28:09 +02:00
loggedin . Handle ( "/ximport" , login . CSRFWrap ( "ximport" , http . HandlerFunc ( ximport ) ) )
2019-04-29 19:32:16 +02:00
loggedin . HandleFunc ( "/honkers" , showhonkers )
loggedin . HandleFunc ( "/h/{name:[[:alnum:]]+}" , showhonker )
2019-06-16 21:05:50 +02:00
loggedin . HandleFunc ( "/h" , showhonker )
2019-04-29 19:32:16 +02:00
loggedin . HandleFunc ( "/c/{name:[[:alnum:]]+}" , showcombo )
2019-05-01 00:48:13 +02:00
loggedin . HandleFunc ( "/c" , showcombos )
2019-06-20 21:15:50 +02:00
loggedin . HandleFunc ( "/t" , showconvoy )
2019-08-30 17:46:25 +02:00
loggedin . HandleFunc ( "/q" , showsearch )
2019-04-25 05:57:01 +02:00
loggedin . Handle ( "/savehonker" , login . CSRFWrap ( "savehonker" , http . HandlerFunc ( savehonker ) ) )
2019-04-09 13:59:33 +02:00
err = http . Serve ( listener , mux )
if err != nil {
log . Fatal ( err )
}
}
2019-07-16 02:49:01 +02:00
func cleanupdb ( arg string ) {
2019-05-21 20:06:17 +02:00
db := opendatabase ( )
2019-07-16 02:49:01 +02:00
days , err := strconv . Atoi ( arg )
if err != nil {
honker := arg
expdate := time . Now ( ) . UTC ( ) . Add ( - 3 * 24 * time . Hour ) . Format ( dbtimeformat )
doordie ( db , "delete from donks where honkid in (select honkid from honks where dt < ? and whofore = 0 and honker = ?)" , expdate , honker )
doordie ( db , "delete from honks where dt < ? and whofore = 0 and honker = ?" , expdate , honker )
} else {
expdate := time . Now ( ) . UTC ( ) . Add ( - time . Duration ( days ) * 24 * time . Hour ) . Format ( dbtimeformat )
doordie ( db , "delete from donks where honkid in (select honkid from honks where dt < ? and whofore = 0 and convoy not in (select convoy from honks where whofore = 2 or whofore = 3))" , expdate )
doordie ( db , "delete from honks where dt < ? and whofore = 0 and convoy not in (select convoy from honks where whofore = 2 or whofore = 3)" , expdate )
}
2019-06-08 20:26:30 +02:00
doordie ( db , "delete from files where fileid not in (select fileid from donks)" )
2019-07-29 00:42:21 +02:00
for _ , u := range allusers ( ) {
doordie ( db , "delete from zonkers where userid = ? and wherefore = 'zonvoy' and zonkerid < (select zonkerid from zonkers where userid = ? and wherefore = 'zonvoy' order by zonkerid desc limit 1 offset 200)" , u . UserID , u . UserID )
}
2019-06-08 20:26:30 +02:00
}
2019-04-29 04:48:46 +02:00
var stmtHonkers , stmtDubbers , stmtSaveHonker , stmtUpdateFlavor , stmtUpdateCombos * sql . Stmt
2019-04-24 09:04:20 +02:00
var stmtOneXonk , stmtPublicHonks , stmtUserHonks , stmtHonksByCombo , stmtHonksByConvoy * sql . Stmt
2019-08-25 05:03:05 +02:00
var stmtHonksByOntology , stmtHonksForUser , stmtHonksForMe , stmtSaveDub , stmtHonksByXonker * sql . Stmt
2019-08-30 17:46:25 +02:00
var stmtHonksBySearch , stmtHonksByHonker , stmtSaveHonk , stmtFileData , stmtWhatAbout * sql . Stmt
2019-08-28 03:22:59 +02:00
var stmtOneBonk , stmtFindZonk , stmtFindXonk , stmtSaveDonk , stmtFindFile , stmtSaveFile * sql . Stmt
2019-04-15 03:35:42 +02:00
var stmtAddDoover , stmtGetDoovers , stmtLoadDoover , stmtZapDoover * sql . Stmt
2019-05-05 19:52:46 +02:00
var stmtHasHonker , stmtThumbBiters , stmtZonkIt , stmtZonkDonks , stmtSaveZonker * sql . Stmt
2019-06-26 02:49:25 +02:00
var stmtGetZonkers , stmtRecentHonkers , stmtGetXonker , stmtSaveXonker , stmtDeleteXonker * sql . Stmt
2019-08-28 03:43:38 +02:00
var stmtSelectOnts , stmtSaveOnts , stmtUpdateFlags , stmtClearFlags * sql . Stmt
2019-04-09 13:59:33 +02:00
2019-04-14 23:09:08 +02:00
func preparetodie ( db * sql . DB , s string ) * sql . Stmt {
stmt , err := db . Prepare ( s )
2019-04-09 13:59:33 +02:00
if err != nil {
2019-04-16 17:16:43 +02:00
log . Fatalf ( "error %s: %s" , err , s )
2019-04-09 13:59:33 +02:00
}
2019-04-14 23:09:08 +02:00
return stmt
}
func prepareStatements ( db * sql . DB ) {
2019-04-26 21:31:42 +02:00
stmtHonkers = preparetodie ( db , "select honkerid, userid, name, xid, flavor, combos from honkers where userid = ? and (flavor = 'sub' or flavor = 'peep' or flavor = 'unsub') order by name" )
2019-04-22 23:03:55 +02:00
stmtSaveHonker = preparetodie ( db , "insert into honkers (userid, name, xid, flavor, combos) values (?, ?, ?, ?, ?)" )
2019-04-29 04:48:46 +02:00
stmtUpdateFlavor = preparetodie ( db , "update honkers set flavor = ? where userid = ? and xid = ? and flavor = ?" )
stmtUpdateCombos = preparetodie ( db , "update honkers set combos = ? where honkerid = ? and userid = ?" )
2019-04-23 17:02:43 +02:00
stmtHasHonker = preparetodie ( db , "select honkerid from honkers where xid = ? and userid = ?" )
2019-04-14 23:09:08 +02:00
stmtDubbers = preparetodie ( db , "select honkerid, userid, name, xid, flavor from honkers where userid = ? and flavor = 'dub'" )
2019-04-24 08:52:08 +02:00
2019-08-28 04:30:29 +02:00
selecthonks := "select honks.honkid, honks.userid, username, what, honker, oonker, honks.xid, rid, dt, url, audience, noise, precis, convoy, whofore, flags, onts from honks join users on honks.userid = users.userid "
2019-08-25 05:03:05 +02:00
limit := " order by honks.honkid desc limit 250"
2019-04-29 00:57:43 +02:00
butnotthose := " and convoy not in (select name from zonkers where userid = ? and wherefore = 'zonvoy' order by zonkerid desc limit 100)"
2019-05-05 19:52:46 +02:00
stmtOneXonk = preparetodie ( db , selecthonks + "where honks.userid = ? and xid = ?" )
2019-08-28 03:22:59 +02:00
stmtOneBonk = preparetodie ( db , selecthonks + "where honks.userid = ? and xid = ? and what = 'bonk' and whofore = 2" )
2019-05-20 16:48:02 +02:00
stmtPublicHonks = preparetodie ( db , selecthonks + "where whofore = 2 and dt > ?" + limit )
2019-05-28 08:36:47 +02:00
stmtUserHonks = preparetodie ( db , selecthonks + "where (whofore = 2 or whofore = ?) and username = ? and dt > ?" + limit )
2019-05-17 23:53:06 +02:00
stmtHonksForUser = preparetodie ( db , selecthonks + "where honks.userid = ? and dt > ? and honker in (select xid from honkers where userid = ? and flavor = 'sub' and combos not like '% - %')" + butnotthose + limit )
2019-04-29 00:57:43 +02:00
stmtHonksForMe = preparetodie ( db , selecthonks + "where honks.userid = ? and dt > ? and whofore = 1" + butnotthose + limit )
2019-08-16 07:26:58 +02:00
stmtHonksByHonker = preparetodie ( db , selecthonks + "join honkers on (honkers.xid = honks.honker or honkers.xid = honks.oonker) where honks.userid = ? and honkers.name = ?" + butnotthose + limit )
2019-07-10 05:43:46 +02:00
stmtHonksByXonker = preparetodie ( db , selecthonks + " where honks.userid = ? and (honker = ? or oonker = ?)" + butnotthose + limit )
2019-04-29 00:57:43 +02:00
stmtHonksByCombo = preparetodie ( db , selecthonks + "join honkers on honkers.xid = honks.honker where honks.userid = ? and honkers.combos like ?" + butnotthose + limit )
2019-08-30 17:46:25 +02:00
stmtHonksBySearch = preparetodie ( db , selecthonks + "where honks.userid = ? and noise like ?" + limit )
2019-07-10 05:37:30 +02:00
stmtHonksByConvoy = preparetodie ( db , selecthonks + "where (honks.userid = ? or (? = -1 and whofore = 2)) and convoy = ?" + limit )
2019-08-26 04:53:56 +02:00
stmtHonksByOntology = preparetodie ( db , selecthonks + "join onts on honks.honkid = onts.honkid where onts.ontology = ? and (honks.userid = ? or (? = -1 and honks.whofore = 2))" + limit )
2019-04-24 08:52:08 +02:00
2019-08-25 05:11:53 +02:00
stmtSaveHonk = preparetodie ( db , "insert into honks (userid, what, honker, xid, rid, dt, url, audience, noise, convoy, whofore, format, precis, oonker, flags, onts) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" )
2019-08-25 05:12:42 +02:00
stmtSaveOnts = preparetodie ( db , "insert into onts (ontology, honkid) values (?, ?)" )
2019-04-15 16:04:41 +02:00
stmtFileData = preparetodie ( db , "select media, content from files where xid = ?" )
2019-04-14 23:09:08 +02:00
stmtFindXonk = preparetodie ( db , "select honkid from honks where userid = ? and xid = ?" )
stmtSaveDonk = preparetodie ( db , "insert into donks (honkid, fileid) values (?, ?)" )
2019-08-28 04:15:53 +02:00
stmtZonkIt = preparetodie ( db , "delete from honks where honkid = ?" )
2019-05-05 19:52:46 +02:00
stmtZonkDonks = preparetodie ( db , "delete from donks where honkid = ?" )
2019-05-25 19:34:41 +02:00
stmtFindFile = preparetodie ( db , "select fileid from files where url = ? and local = 1" )
stmtSaveFile = preparetodie ( db , "insert into files (xid, name, url, media, local, content) values (?, ?, ?, ?, ?, ?)" )
2019-06-28 04:15:59 +02:00
stmtWhatAbout = preparetodie ( db , "select userid, username, displayname, about, pubkey, options from users where username = ?" )
2019-04-14 23:09:08 +02:00
stmtSaveDub = preparetodie ( db , "insert into honkers (userid, name, xid, flavor) values (?, ?, ?, ?)" )
2019-04-15 03:35:42 +02:00
stmtAddDoover = preparetodie ( db , "insert into doovers (dt, tries, username, rcpt, msg) values (?, ?, ?, ?, ?)" )
stmtGetDoovers = preparetodie ( db , "select dooverid, dt from doovers" )
stmtLoadDoover = preparetodie ( db , "select tries, username, rcpt, msg from doovers where dooverid = ?" )
stmtZapDoover = preparetodie ( db , "delete from doovers where dooverid = ?" )
2019-07-10 23:39:41 +02:00
stmtThumbBiters = preparetodie ( db , "select userid, name, wherefore from zonkers where (wherefore = 'zonker' or wherefore = 'zomain' or wherefore = 'zord' or wherefore = 'zilence')" )
2019-06-17 18:18:37 +02:00
stmtFindZonk = preparetodie ( db , "select zonkerid from zonkers where userid = ? and name = ? and wherefore = 'zonk'" )
stmtGetZonkers = preparetodie ( db , "select zonkerid, name, wherefore from zonkers where userid = ? and wherefore <> 'zonk'" )
2019-04-29 04:48:46 +02:00
stmtSaveZonker = preparetodie ( db , "insert into zonkers (userid, name, wherefore) values (?, ?, ?)" )
2019-06-03 06:15:06 +02:00
stmtGetXonker = preparetodie ( db , "select info from xonkers where name = ? and flavor = ?" )
stmtSaveXonker = preparetodie ( db , "insert into xonkers (name, info, flavor) values (?, ?, ?)" )
2019-06-26 02:49:25 +02:00
stmtDeleteXonker = preparetodie ( db , "delete from xonkers where name = ? and flavor = ?" )
2019-08-14 21:46:21 +02:00
stmtRecentHonkers = preparetodie ( db , "select distinct(honker) from honks where userid = ? and honker not in (select xid from honkers where userid = ? and flavor = 'sub') order by honkid desc limit 100" )
2019-08-28 03:22:59 +02:00
stmtUpdateFlags = preparetodie ( db , "update honks set flags = flags | ? where honkid = ?" )
stmtClearFlags = preparetodie ( db , "update honks set flags = flags & ~ ? where honkid = ?" )
2019-08-28 04:07:08 +02:00
stmtSelectOnts = preparetodie ( db , "select distinct(ontology) from onts join honks on onts.honkid = honks.honkid where (honks.userid = ? or honks.whofore = 2)" )
2019-04-09 13:59:33 +02:00
}
func ElaborateUnitTests ( ) {
}
func main ( ) {
cmd := "run"
if len ( os . Args ) > 1 {
cmd = os . Args [ 1 ]
}
2019-04-14 22:43:03 +02:00
switch cmd {
case "init" :
initdb ( )
case "upgrade" :
upgradedb ( )
2019-04-09 13:59:33 +02:00
}
2019-04-14 22:43:03 +02:00
db := opendatabase ( )
dbversion := 0
getconfig ( "dbversion" , & dbversion )
if dbversion != myVersion {
log . Fatal ( "incorrect database version. run upgrade." )
}
2019-06-12 05:11:18 +02:00
getconfig ( "servermsg" , & serverMsg )
2019-04-14 22:43:03 +02:00
getconfig ( "servername" , & serverName )
2019-07-23 19:21:09 +02:00
getconfig ( "usersep" , & userSep )
getconfig ( "honksep" , & honkSep )
2019-06-25 03:14:47 +02:00
getconfig ( "dnf" , & donotfedafterdark )
2019-04-14 22:43:03 +02:00
prepareStatements ( db )
2019-04-09 13:59:33 +02:00
switch cmd {
2019-05-22 21:11:39 +02:00
case "adduser" :
adduser ( )
2019-05-21 20:06:17 +02:00
case "cleanup" :
2019-07-16 02:49:01 +02:00
arg := "30"
2019-06-11 20:46:42 +02:00
if len ( os . Args ) > 2 {
2019-07-16 02:49:01 +02:00
arg = os . Args [ 2 ]
2019-06-08 20:26:30 +02:00
}
2019-07-16 02:49:01 +02:00
cleanupdb ( arg )
2019-04-12 18:32:07 +02:00
case "ping" :
if len ( os . Args ) < 4 {
fmt . Printf ( "usage: honk ping from to\n" )
return
}
name := os . Args [ 2 ]
targ := os . Args [ 3 ]
user , err := butwhatabout ( name )
if err != nil {
log . Printf ( "unknown user" )
return
}
ping ( user , targ )
2019-04-09 13:59:33 +02:00
case "peep" :
peeppeep ( )
case "run" :
serve ( )
case "test" :
ElaborateUnitTests ( )
default :
log . Fatal ( "unknown command" )
}
}