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