honk/honk.go

292 lines
5.4 KiB
Go
Raw Normal View History

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 (
2019-10-25 23:31:48 +02:00
"crypto/rsa"
"flag"
2019-04-09 13:59:33 +02:00
"fmt"
"html/template"
"log"
2019-10-29 20:53:20 +01:00
notrand "math/rand"
"os"
2019-10-21 08:28:35 +02:00
"strconv"
2019-10-03 06:11:02 +02:00
"strings"
2019-04-09 13:59:33 +02:00
"time"
)
2019-11-09 03:15:40 +01:00
var softwareVersion = "develop"
2019-10-29 20:53:20 +01:00
func init() {
notrand.Seed(time.Now().Unix())
}
2019-04-09 13:59:33 +02:00
type WhatAbout struct {
ID int64
Name string
Display string
About string
Key string
URL string
Options UserOptions
SecKey *rsa.PrivateKey
}
type UserOptions struct {
2019-11-07 03:33:13 +01:00
SkinnyCSS bool `json:",omitempty"`
Avatar string `json:",omitempty"`
MapLink string `json:",omitempty"`
2019-04-09 13:59:33 +02:00
}
type KeyInfo struct {
keyname string
seckey *rsa.PrivateKey
}
2019-10-25 23:31:48 +02:00
const serverUID int64 = -2
2019-04-13 19:58:42 +02:00
type Honk struct {
ID int64
UserID int64
Username string
What string
Honker string
Handle string
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
Precis string
2019-09-11 22:20:22 +02:00
Format string
Convoy string
2019-04-13 19:58:42 +02:00
Audience []string
Public bool
Whofore int64
Replies []*Honk
2019-08-16 21:13:33 +02:00
Flags int64
2019-09-18 21:08:50 +02:00
HTPrecis template.HTML
2019-04-13 19:58:42 +02:00
HTML template.HTML
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-09-28 06:12:50 +02:00
Place *Place
Time *Time
2019-04-09 13:59:33 +02:00
}
type OldRevision struct {
Precis string
Noise string
}
2019-08-16 21:35:12 +02:00
const (
2019-10-30 00:14:41 +01:00
flagIsAcked = 1
flagIsBonked = 2
flagIsSaved = 4
flagIsUntagged = 8
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-10-11 22:03:17 +02:00
func (honk *Honk) IsSaved() bool {
return honk.Flags&flagIsSaved != 0
}
2019-10-30 00:14:41 +01:00
func (honk *Honk) IsUntagged() bool {
return honk.Flags&flagIsUntagged != 0
}
2019-04-13 19:58:42 +02:00
type Donk struct {
2019-10-16 08:06:53 +02:00
FileID int64
XID string
Name string
Desc string
URL string
Media string
Local bool
2019-04-09 13:59:33 +02:00
}
2019-09-28 06:12:50 +02:00
type Place struct {
Name string
Latitude float64
Longitude float64
2019-09-29 22:07:35 +02:00
Url string
2019-09-28 06:12:50 +02:00
}
2019-10-03 06:11:02 +02:00
type Duration int64
func (d Duration) String() string {
s := time.Duration(d).String()
if strings.HasSuffix(s, "m0s") {
s = s[:len(s)-2]
}
if strings.HasSuffix(s, "h0m") {
s = s[:len(s)-2]
}
return s
}
2019-10-21 08:28:35 +02:00
func parseDuration(s string) time.Duration {
didx := strings.IndexByte(s, 'd')
if didx != -1 {
days, _ := strconv.ParseInt(s[:didx], 10, 0)
dur, _ := time.ParseDuration(s[didx:])
return dur + 24*time.Hour*time.Duration(days)
}
dur, _ := time.ParseDuration(s)
return dur
}
type Time struct {
StartTime time.Time
EndTime time.Time
2019-10-03 06:11:02 +02:00
Duration Duration
}
2019-04-13 19:58:42 +02:00
type Honker struct {
ID int64
UserID int64
Name string
XID string
Handle string
2019-04-13 19:58:42 +02:00
Flavor string
Combos []string
2019-04-09 13:59:33 +02:00
}
type SomeThing struct {
What int
XID string
Owner string
Name string
}
const (
SomeNothing int = iota
SomeActor
SomeCollection
)
var serverName string
var dataDir = "."
var viewDir = "."
var iconName = "icon.png"
var serverMsg template.HTML
var aboutMsg template.HTML
var loginMsg template.HTML
2019-04-09 13:59:33 +02:00
func ElaborateUnitTests() {
}
func main() {
flag.StringVar(&dataDir, "datadir", dataDir, "data directory")
flag.StringVar(&viewDir, "viewdir", viewDir, "view directory")
flag.Parse()
args := flag.Args()
2019-04-09 13:59:33 +02:00
cmd := "run"
if len(args) > 0 {
cmd = args[0]
2019-04-09 13:59:33 +02:00
}
switch cmd {
case "init":
initdb()
case "upgrade":
upgradedb()
case "version":
2019-11-09 03:15:40 +01:00
fmt.Println(softwareVersion)
os.Exit(0)
2019-04-09 13:59:33 +02:00
}
db := opendatabase()
dbversion := 0
getconfig("dbversion", &dbversion)
if dbversion != myVersion {
log.Fatal("incorrect database version. run upgrade.")
}
getconfig("servermsg", &serverMsg)
getconfig("aboutmsg", &aboutMsg)
getconfig("loginmsg", &loginMsg)
getconfig("servername", &serverName)
getconfig("usersep", &userSep)
getconfig("honksep", &honkSep)
prepareStatements(db)
2019-04-09 13:59:33 +02:00
switch cmd {
2019-10-21 01:06:29 +02:00
case "admin":
adminscreen()
2019-11-13 01:00:00 +01:00
case "import":
if len(args) != 4 {
log.Fatal("import username twitter [srcdir]")
}
importMain(args[1], args[2], args[3])
2019-10-20 22:39:01 +02:00
case "debug":
if len(args) != 2 {
2019-10-20 22:39:01 +02:00
log.Fatal("need an argument: debug (on|off)")
}
switch args[1] {
2019-10-20 22:39:01 +02:00
case "on":
updateconfig("debug", 1)
2019-10-20 22:39:01 +02:00
case "off":
updateconfig("debug", 0)
2019-10-20 22:39:01 +02:00
default:
log.Fatal("argument must be on or off")
}
2019-05-22 21:11:39 +02:00
case "adduser":
adduser()
2019-12-10 20:03:44 +01:00
case "deluser":
if len(args) < 2 {
fmt.Printf("usage: honk deluser username\n")
return
}
deluser(args[1])
2019-10-13 01:21:29 +02:00
case "chpass":
chpass()
case "cleanup":
2019-07-16 02:49:01 +02:00
arg := "30"
if len(args) > 1 {
arg = args[1]
}
2019-07-16 02:49:01 +02:00
cleanupdb(arg)
case "ping":
if len(args) < 3 {
fmt.Printf("usage: honk ping from to\n")
return
}
name := args[1]
targ := args[2]
user, err := butwhatabout(name)
if err != nil {
log.Printf("unknown user")
return
}
ping(user, targ)
2019-04-09 13:59:33 +02:00
case "run":
serve()
case "backend":
backendServer()
2019-04-09 13:59:33 +02:00
case "test":
ElaborateUnitTests()
default:
log.Fatal("unknown command")
}
}