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