all repos — honk @ ae62659c3be421818be2278a121e73b94a3679bc

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