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