all repos — honk @ 965911ce320cc525f8c84bf5b1cf0c93812a9d16

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	"fmt"
 20	"html/template"
 21	"log"
 22	"os"
 23	"strconv"
 24	"strings"
 25	"time"
 26)
 27
 28type WhatAbout struct {
 29	ID        int64
 30	Name      string
 31	Display   string
 32	About     string
 33	Key       string
 34	URL       string
 35	SkinnyCSS bool
 36}
 37
 38type Honk struct {
 39	ID       int64
 40	UserID   int64
 41	Username string
 42	What     string
 43	Honker   string
 44	Handle   string
 45	Oonker   string
 46	Oondle   string
 47	XID      string
 48	RID      string
 49	Date     time.Time
 50	URL      string
 51	Noise    string
 52	Precis   string
 53	Format   string
 54	Convoy   string
 55	Audience []string
 56	Public   bool
 57	Whofore  int64
 58	Replies  []*Honk
 59	Flags    int64
 60	HTPrecis template.HTML
 61	HTML     template.HTML
 62	Style    string
 63	Open     string
 64	Donks    []*Donk
 65	Onts     []string
 66	Place    *Place
 67	Time     *Time
 68}
 69
 70type OldRevision struct {
 71	Precis string
 72	Noise  string
 73}
 74
 75const (
 76	flagIsAcked  = 1
 77	flagIsBonked = 2
 78	flagIsSaved  = 4
 79)
 80
 81func (honk *Honk) IsAcked() bool {
 82	return honk.Flags&flagIsAcked != 0
 83}
 84
 85func (honk *Honk) IsBonked() bool {
 86	return honk.Flags&flagIsBonked != 0
 87}
 88
 89func (honk *Honk) IsSaved() bool {
 90	return honk.Flags&flagIsSaved != 0
 91}
 92
 93type Donk struct {
 94	FileID int64
 95	XID    string
 96	Name   string
 97	Desc   string
 98	URL    string
 99	Media  string
100	Local  bool
101}
102
103type Place struct {
104	Name      string
105	Latitude  float64
106	Longitude float64
107	Url       string
108}
109
110type Duration int64
111
112func (d Duration) String() string {
113	s := time.Duration(d).String()
114	if strings.HasSuffix(s, "m0s") {
115		s = s[:len(s)-2]
116	}
117	if strings.HasSuffix(s, "h0m") {
118		s = s[:len(s)-2]
119	}
120	return s
121}
122
123func parseDuration(s string) time.Duration {
124	didx := strings.IndexByte(s, 'd')
125	if didx != -1 {
126		days, _ := strconv.ParseInt(s[:didx], 10, 0)
127		dur, _ := time.ParseDuration(s[didx:])
128		return dur + 24*time.Hour*time.Duration(days)
129	}
130	dur, _ := time.ParseDuration(s)
131	return dur
132}
133
134type Time struct {
135	StartTime time.Time
136	EndTime   time.Time
137	Duration  Duration
138}
139
140type Honker struct {
141	ID     int64
142	UserID int64
143	Name   string
144	XID    string
145	Handle string
146	Flavor string
147	Combos []string
148}
149
150var serverName string
151var iconName = "icon.png"
152var serverMsg template.HTML
153var aboutMsg template.HTML
154var loginMsg template.HTML
155
156func ElaborateUnitTests() {
157}
158
159func main() {
160	cmd := "run"
161	if len(os.Args) > 1 {
162		cmd = os.Args[1]
163	}
164	switch cmd {
165	case "init":
166		initdb()
167	case "upgrade":
168		upgradedb()
169	}
170	db := opendatabase()
171	dbversion := 0
172	getconfig("dbversion", &dbversion)
173	if dbversion != myVersion {
174		log.Fatal("incorrect database version. run upgrade.")
175	}
176	getconfig("servermsg", &serverMsg)
177	getconfig("aboutmsg", &aboutMsg)
178	getconfig("loginmsg", &loginMsg)
179	getconfig("servername", &serverName)
180	getconfig("usersep", &userSep)
181	getconfig("honksep", &honkSep)
182	prepareStatements(db)
183	switch cmd {
184	case "admin":
185		adminscreen()
186	case "debug":
187		if len(os.Args) != 3 {
188			log.Fatal("need an argument: debug (on|off)")
189		}
190		switch os.Args[2] {
191		case "on":
192			updateconfig("debug", 1)
193		case "off":
194			updateconfig("debug", 0)
195		default:
196			log.Fatal("argument must be on or off")
197		}
198	case "adduser":
199		adduser()
200	case "chpass":
201		chpass()
202	case "cleanup":
203		arg := "30"
204		if len(os.Args) > 2 {
205			arg = os.Args[2]
206		}
207		cleanupdb(arg)
208	case "ping":
209		if len(os.Args) < 4 {
210			fmt.Printf("usage: honk ping from to\n")
211			return
212		}
213		name := os.Args[2]
214		targ := os.Args[3]
215		user, err := butwhatabout(name)
216		if err != nil {
217			log.Printf("unknown user")
218			return
219		}
220		ping(user, targ)
221	case "run":
222		serve()
223	case "test":
224		ElaborateUnitTests()
225	default:
226		log.Fatal("unknown command")
227	}
228}