all repos — honk @ 228bfb213f64036a1dc841654b93d0b805ebb569

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