all repos — honk @ 8c14fb9c6de790b2c62c4f690b9a4e6f9c77a944

my fork of honk

honk.go (view raw)

  1//
  2// Copyright (c) 2019 Ted Unangst <tedu@tedunangst.com>
  3//
  4// Permission to use, copy, modify, and distribute this software for any
  5// purpose with or without fee is hereby granted, provided that the above
  6// copyright notice and this permission notice appear in all copies.
  7//
  8// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  9// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 10// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 11// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 12// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 13// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 14// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 15
 16package main
 17
 18import (
 19	"crypto/rsa"
 20	"fmt"
 21	"html/template"
 22	"log"
 23	"os"
 24	"strconv"
 25	"strings"
 26	"time"
 27)
 28
 29type WhatAbout struct {
 30	ID        int64
 31	Name      string
 32	Display   string
 33	About     string
 34	Key       string
 35	URL       string
 36	SkinnyCSS bool
 37	SecKey    *rsa.PrivateKey
 38}
 39
 40const serverUID int64 = -2
 41
 42type Honk struct {
 43	ID       int64
 44	UserID   int64
 45	Username string
 46	What     string
 47	Honker   string
 48	Handle   string
 49	Oonker   string
 50	Oondle   string
 51	XID      string
 52	RID      string
 53	Date     time.Time
 54	URL      string
 55	Noise    string
 56	Precis   string
 57	Format   string
 58	Convoy   string
 59	Audience []string
 60	Public   bool
 61	Whofore  int64
 62	Replies  []*Honk
 63	Flags    int64
 64	HTPrecis template.HTML
 65	HTML     template.HTML
 66	Style    string
 67	Open     string
 68	Donks    []*Donk
 69	Onts     []string
 70	Place    *Place
 71	Time     *Time
 72}
 73
 74type OldRevision struct {
 75	Precis string
 76	Noise  string
 77}
 78
 79const (
 80	flagIsAcked  = 1
 81	flagIsBonked = 2
 82	flagIsSaved  = 4
 83)
 84
 85func (honk *Honk) IsAcked() bool {
 86	return honk.Flags&flagIsAcked != 0
 87}
 88
 89func (honk *Honk) IsBonked() bool {
 90	return honk.Flags&flagIsBonked != 0
 91}
 92
 93func (honk *Honk) IsSaved() bool {
 94	return honk.Flags&flagIsSaved != 0
 95}
 96
 97type Donk struct {
 98	FileID int64
 99	XID    string
100	Name   string
101	Desc   string
102	URL    string
103	Media  string
104	Local  bool
105}
106
107type Place struct {
108	Name      string
109	Latitude  float64
110	Longitude float64
111	Url       string
112}
113
114type Duration int64
115
116func (d Duration) String() string {
117	s := time.Duration(d).String()
118	if strings.HasSuffix(s, "m0s") {
119		s = s[:len(s)-2]
120	}
121	if strings.HasSuffix(s, "h0m") {
122		s = s[:len(s)-2]
123	}
124	return s
125}
126
127func parseDuration(s string) time.Duration {
128	didx := strings.IndexByte(s, 'd')
129	if didx != -1 {
130		days, _ := strconv.ParseInt(s[:didx], 10, 0)
131		dur, _ := time.ParseDuration(s[didx:])
132		return dur + 24*time.Hour*time.Duration(days)
133	}
134	dur, _ := time.ParseDuration(s)
135	return dur
136}
137
138type Time struct {
139	StartTime time.Time
140	EndTime   time.Time
141	Duration  Duration
142}
143
144type Honker struct {
145	ID     int64
146	UserID int64
147	Name   string
148	XID    string
149	Handle string
150	Flavor string
151	Combos []string
152}
153
154var serverName string
155var iconName = "icon.png"
156var serverMsg template.HTML
157var aboutMsg template.HTML
158var loginMsg template.HTML
159
160func ElaborateUnitTests() {
161}
162
163func main() {
164	cmd := "run"
165	if len(os.Args) > 1 {
166		cmd = os.Args[1]
167	}
168	switch cmd {
169	case "init":
170		initdb()
171	case "upgrade":
172		upgradedb()
173	}
174	db := opendatabase()
175	dbversion := 0
176	getconfig("dbversion", &dbversion)
177	if dbversion != myVersion {
178		log.Fatal("incorrect database version. run upgrade.")
179	}
180	getconfig("servermsg", &serverMsg)
181	getconfig("aboutmsg", &aboutMsg)
182	getconfig("loginmsg", &loginMsg)
183	getconfig("servername", &serverName)
184	getconfig("usersep", &userSep)
185	getconfig("honksep", &honkSep)
186	prepareStatements(db)
187	switch cmd {
188	case "admin":
189		adminscreen()
190	case "debug":
191		if len(os.Args) != 3 {
192			log.Fatal("need an argument: debug (on|off)")
193		}
194		switch os.Args[2] {
195		case "on":
196			updateconfig("debug", 1)
197		case "off":
198			updateconfig("debug", 0)
199		default:
200			log.Fatal("argument must be on or off")
201		}
202	case "adduser":
203		adduser()
204	case "chpass":
205		chpass()
206	case "cleanup":
207		arg := "30"
208		if len(os.Args) > 2 {
209			arg = os.Args[2]
210		}
211		cleanupdb(arg)
212	case "ping":
213		if len(os.Args) < 4 {
214			fmt.Printf("usage: honk ping from to\n")
215			return
216		}
217		name := os.Args[2]
218		targ := os.Args[3]
219		user, err := butwhatabout(name)
220		if err != nil {
221			log.Printf("unknown user")
222			return
223		}
224		ping(user, targ)
225	case "run":
226		serve()
227	case "test":
228		ElaborateUnitTests()
229	default:
230		log.Fatal("unknown command")
231	}
232}