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