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 "html/template"
20 "strconv"
21 "strings"
22 "time"
23
24 "humungus.tedunangst.com/r/webs/httpsig"
25)
26
27type WhatAbout struct {
28 ID UserID
29 Name string
30 Display string
31 About string
32 HTAbout template.HTML
33 Onts []string
34 Key string
35 URL string
36 Options UserOptions
37 SecKey httpsig.PrivateKey
38 ChatPubKey boxPubKey
39 ChatSecKey boxSecKey
40}
41
42type UserOptions struct {
43 SkinnyCSS bool `json:",omitempty"`
44 OmitImages bool `json:",omitempty"`
45 MentionAll bool `json:",omitempty"`
46 InlineQuotes bool `json:",omitempty"`
47 Avahex bool `json:",omitempty"`
48 Avatar string `json:",omitempty"`
49 CustomDisplay string `json:",omitempty"`
50 Banner string `json:",omitempty"`
51 MapLink string `json:",omitempty"`
52 Reaction string `json:",omitempty"`
53 MeCount int64
54 ChatCount int64
55 ChatPubKey string
56 ChatSecKey string
57}
58
59type KeyInfo struct {
60 keyname string
61 seckey httpsig.PrivateKey
62}
63
64type UserID int64
65
66const serverUID UserID = -2
67const readyLuserOne UserID = 1
68
69type Honk struct {
70 ID int64
71 UserID UserID
72 Username string
73 DisplayName string
74 What string
75 Honker string
76 Handle string
77 Handles string
78 Oonker string
79 Oondle string
80 XID string
81 RID string
82 Date time.Time
83 DatePretty string
84 URL string
85 Noise string
86 Precis string
87 Format string
88 Convoy string
89 Audience []string
90 Public bool
91 Whofore int64
92 Replies []*Honk
93 Flags int64
94 HTPrecis template.HTML
95 HTML template.HTML
96 Style string
97 Open string
98 Donks []*Donk
99 Onts []string
100 Place *Place
101 Time *Time
102 Link string
103 Mentions []Mention
104 Badonks []Badonk
105 SeeAlso string
106 Onties string
107 LegalName string
108}
109
110type Badonk struct {
111 Who string
112 What string
113}
114
115type Chonk struct {
116 ID int64
117 UserID UserID
118 XID string
119 Who string
120 Target string
121 Date time.Time
122 Noise string
123 Format string
124 Donks []*Donk
125 Handle string
126 HTML template.HTML
127}
128
129type Chatter struct {
130 Target string
131 Chonks []*Chonk
132}
133
134type Mention struct {
135 Who string
136 Where string
137}
138
139func (mention *Mention) IsPresent(noise string) bool {
140 nick := strings.TrimLeft(mention.Who, "@")
141 idx := strings.IndexByte(nick, '@')
142 if idx != -1 {
143 nick = nick[:idx]
144 }
145 return strings.Contains(noise, ">@"+nick) || strings.Contains(noise, "@<span>"+nick)
146}
147
148func OntIsPresent(ont, noise string) bool {
149 ont = strings.ToLower(ont[1:])
150 idx := strings.IndexByte(noise, '#')
151 for idx >= 0 {
152 if strings.HasPrefix(noise[idx:], "#<span>") {
153 idx += 6
154 }
155 idx += 1
156 if idx+len(ont) >= len(noise) {
157 return false
158 }
159 test := noise[idx : idx+len(ont)]
160 test = strings.ToLower(test)
161 if test == ont {
162 return true
163 }
164 newidx := strings.IndexByte(noise[idx:], '#')
165 if newidx == -1 {
166 return false
167 }
168 idx += newidx
169 }
170 return false
171}
172
173type OldRevision struct {
174 Precis string
175 Noise string
176}
177
178const (
179 flagIsAcked = 1
180 flagIsBonked = 2
181 flagIsSaved = 4
182 flagIsUntagged = 8
183 flagIsReacted = 16
184)
185
186func (honk *Honk) IsAcked() bool {
187 return honk.Flags&flagIsAcked != 0
188}
189
190func (honk *Honk) IsBonked() bool {
191 return honk.Flags&flagIsBonked != 0
192}
193
194func (honk *Honk) IsSaved() bool {
195 return honk.Flags&flagIsSaved != 0
196}
197
198func (honk *Honk) IsUntagged() bool {
199 return honk.Flags&flagIsUntagged != 0
200}
201
202func (honk *Honk) IsReacted() bool {
203 return honk.Flags&flagIsReacted != 0
204}
205
206func (honk *Honk) ShortXID() string {
207 return shortxid(honk.XID)
208}
209
210type Donk struct {
211 FileID int64
212 XID string
213 Name string
214 Desc string
215 URL string
216 Media string
217 Local bool
218 External bool
219 Meta DonkMeta
220}
221type DonkMeta struct {
222 Length int `json:",omitempty"`
223 Width int `json:",omitempty"`
224 Height int `json:",omitempty"`
225}
226
227type Place struct {
228 Name string
229 Latitude float64
230 Longitude float64
231 Url string
232}
233
234type Duration int64
235
236func (d Duration) String() string {
237 s := time.Duration(d).String()
238 if strings.HasSuffix(s, "m0s") {
239 s = s[:len(s)-2]
240 }
241 if strings.HasSuffix(s, "h0m") {
242 s = s[:len(s)-2]
243 }
244 return s
245}
246
247func parseDuration(s string) time.Duration {
248 didx := strings.IndexByte(s, 'd')
249 if didx != -1 {
250 days, _ := strconv.ParseInt(s[:didx], 10, 0)
251 dur, _ := time.ParseDuration(s[didx:])
252 return dur + 24*time.Hour*time.Duration(days)
253 }
254 dur, _ := time.ParseDuration(s)
255 return dur
256}
257
258type Time struct {
259 StartTime time.Time
260 EndTime time.Time
261 Duration Duration
262}
263
264type Honker struct {
265 ID int64
266 UserID UserID
267 Name string
268 XID string
269 Handle string
270 Flavor string
271 Combos []string
272 Meta HonkerMeta
273}
274
275type HonkerMeta struct {
276 Notes string
277}
278
279type SomeThing struct {
280 What int
281 XID string
282 Owner string
283 Name string
284}
285
286const (
287 SomeNothing int = iota
288 SomeActor
289 SomeCollection
290)