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
206type Donk struct {
207 FileID int64
208 XID string
209 Name string
210 Desc string
211 URL string
212 Media string
213 Local bool
214 External bool
215 Meta DonkMeta
216}
217type DonkMeta struct {
218 Length int `json:",omitempty"`
219 Width int `json:",omitempty"`
220 Height int `json:",omitempty"`
221}
222
223type Place struct {
224 Name string
225 Latitude float64
226 Longitude float64
227 Url string
228}
229
230type Duration int64
231
232func (d Duration) String() string {
233 s := time.Duration(d).String()
234 if strings.HasSuffix(s, "m0s") {
235 s = s[:len(s)-2]
236 }
237 if strings.HasSuffix(s, "h0m") {
238 s = s[:len(s)-2]
239 }
240 return s
241}
242
243func parseDuration(s string) time.Duration {
244 didx := strings.IndexByte(s, 'd')
245 if didx != -1 {
246 days, _ := strconv.ParseInt(s[:didx], 10, 0)
247 dur, _ := time.ParseDuration(s[didx:])
248 return dur + 24*time.Hour*time.Duration(days)
249 }
250 dur, _ := time.ParseDuration(s)
251 return dur
252}
253
254type Time struct {
255 StartTime time.Time
256 EndTime time.Time
257 Duration Duration
258}
259
260type Honker struct {
261 ID int64
262 UserID UserID
263 Name string
264 XID string
265 Handle string
266 Flavor string
267 Combos []string
268 Meta HonkerMeta
269}
270
271type HonkerMeta struct {
272 Notes string
273}
274
275type SomeThing struct {
276 What int
277 XID string
278 Owner string
279 Name string
280}
281
282const (
283 SomeNothing int = iota
284 SomeActor
285 SomeCollection
286)