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