···11+{
22+ "lexicon": 1,
33+ "id": "place.stream.livestream",
44+ "defs": {
55+ "main": {
66+ "type": "record",
77+ "description": "Record announcing a livestream is happening",
88+ "key": "tid",
99+ "record": {
1010+ "type": "object",
1111+ "required": ["title", "createdAt"],
1212+ "properties": {
1313+ "title": {
1414+ "type": "string",
1515+ "maxLength": 1400,
1616+ "maxGraphemes": 140,
1717+ "description": "The title of the livestream, as it will be announced to followers."
1818+ },
1919+ "url": {
2020+ "type": "string",
2121+ "format": "uri",
2222+ "description": "The URL where this stream can be found. This is primarily a hint for other Streamplace nodes to locate and replicate the stream."
2323+ },
2424+ "createdAt": {
2525+ "type": "string",
2626+ "format": "datetime",
2727+ "description": "Client-declared timestamp when this livestream started."
2828+ }
2929+ }
3030+ }
3131+ }
3232+ }
3333+}
···52525353// basic type to represent logging container. logging context is immutable after
5454// creation, so we don't have to worry about locking.
5555-type metadata map[string]any
5555+type metadata [][]string
56565757func init() {
5858 // Set default v level to 3; this is overridden in main() but is useful for tests
···7070 return &VerboseLogger{level: level}
7171}
72727373+func (m metadata) Map() map[string]string {
7474+ out := map[string]string{}
7575+ for _, pair := range m {
7676+ out[pair[0]] = pair[1]
7777+ }
7878+ return out
7979+}
8080+7381func (m metadata) Flat() []any {
7482 out := []any{}
7575- for k, v := range m {
7676- out = append(out, k)
7777- out = append(out, v)
8383+ for _, pair := range m {
8484+ out = append(out, pair[0])
8585+ out = append(out, pair[1])
7886 }
7987 return out
8088}
···8795 oldMetadata = metadata{}
8896 }
8997 var newMetadata = metadata{}
9090- for k, v := range oldMetadata {
9191- newMetadata[k] = v
9898+ for _, pair := range oldMetadata {
9999+ newMetadata = append(newMetadata, []string{pair[0], pair[1]})
92100 }
93101 for i := range args {
94102 if i%2 == 0 {
95103 continue
96104 }
9797- newMetadata[args[i-1]] = args[i]
105105+ newKey := args[i-1]
106106+ newValue := args[i]
107107+ found := false
108108+ for _, pair := range newMetadata {
109109+ if pair[0] == newKey {
110110+ pair[1] = newValue
111111+ found = true
112112+ break
113113+ }
114114+ }
115115+ if !found {
116116+ newMetadata = append(newMetadata, []string{newKey, newValue})
117117+ }
98118 }
99119 return context.WithValue(ctx, clogContextKey, newMetadata)
100120}
···121141 // meta is {"func": "ToHLS", "file": "gstreamer.go"}
122142 // we want to use the highest level between debug and meta
123143 if debugOk && metaOk {
124124- for mk, mv := range meta {
144144+ for mk, mv := range meta.Map() {
125145 debugValuesForMetaValue, ok := debug[mk]
126146 if !ok {
127147 continue
128148 }
129129- mvstr, ok := mv.(string)
130130- if !ok {
131131- // TODO: possible we will need to handle numeric types
132132- continue
133133- }
134134- ll, ok := debugValuesForMetaValue[mvstr]
149149+ ll, ok := debugValuesForMetaValue[mv]
135150 if !ok {
136151 continue
137152 }
+2-1
pkg/media/media.go
···1818 "stream.place/streamplace/pkg/aqtime"
1919 "stream.place/streamplace/pkg/atproto"
2020 "stream.place/streamplace/pkg/config"
2121+ "stream.place/streamplace/pkg/constants"
2122 "stream.place/streamplace/pkg/crypto/signers"
2223 "stream.place/streamplace/pkg/log"
2324 "stream.place/streamplace/pkg/model"
···343344 // special case for test signers that are only signed with a key
344345 var repoDID string
345346 var signingKeyDID string
346346- if strings.HasPrefix(meta.Creator, atproto.DID_KEY_PREFIX) {
347347+ if strings.HasPrefix(meta.Creator, constants.DID_KEY_PREFIX) {
347348 signingKeyDID = meta.Creator
348349 repoDID = meta.Creator
349350 } else {
···11+// Code generated by github.com/whyrusleeping/cbor-gen. DO NOT EDIT.
22+33+package streamplace
44+55+import (
66+ "fmt"
77+ "io"
88+ "math"
99+ "sort"
1010+1111+ cid "github.com/ipfs/go-cid"
1212+ cbg "github.com/whyrusleeping/cbor-gen"
1313+ xerrors "golang.org/x/xerrors"
1414+)
1515+1616+var _ = xerrors.Errorf
1717+var _ = cid.Undef
1818+var _ = math.E
1919+var _ = sort.Sort
2020+2121+func (t *Key) MarshalCBOR(w io.Writer) error {
2222+ if t == nil {
2323+ _, err := w.Write(cbg.CborNull)
2424+ return err
2525+ }
2626+2727+ cw := cbg.NewCborWriter(w)
2828+2929+ if _, err := cw.Write([]byte{163}); err != nil {
3030+ return err
3131+ }
3232+3333+ // t.LexiconTypeID (string) (string)
3434+ if len("$type") > 1000000 {
3535+ return xerrors.Errorf("Value in field \"$type\" was too long")
3636+ }
3737+3838+ if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("$type"))); err != nil {
3939+ return err
4040+ }
4141+ if _, err := cw.WriteString(string("$type")); err != nil {
4242+ return err
4343+ }
4444+4545+ if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("place.stream.key"))); err != nil {
4646+ return err
4747+ }
4848+ if _, err := cw.WriteString(string("place.stream.key")); err != nil {
4949+ return err
5050+ }
5151+5252+ // t.CreatedAt (string) (string)
5353+ if len("createdAt") > 1000000 {
5454+ return xerrors.Errorf("Value in field \"createdAt\" was too long")
5555+ }
5656+5757+ if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("createdAt"))); err != nil {
5858+ return err
5959+ }
6060+ if _, err := cw.WriteString(string("createdAt")); err != nil {
6161+ return err
6262+ }
6363+6464+ if len(t.CreatedAt) > 1000000 {
6565+ return xerrors.Errorf("Value in field t.CreatedAt was too long")
6666+ }
6767+6868+ if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.CreatedAt))); err != nil {
6969+ return err
7070+ }
7171+ if _, err := cw.WriteString(string(t.CreatedAt)); err != nil {
7272+ return err
7373+ }
7474+7575+ // t.SigningKey (string) (string)
7676+ if len("signingKey") > 1000000 {
7777+ return xerrors.Errorf("Value in field \"signingKey\" was too long")
7878+ }
7979+8080+ if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("signingKey"))); err != nil {
8181+ return err
8282+ }
8383+ if _, err := cw.WriteString(string("signingKey")); err != nil {
8484+ return err
8585+ }
8686+8787+ if len(t.SigningKey) > 1000000 {
8888+ return xerrors.Errorf("Value in field t.SigningKey was too long")
8989+ }
9090+9191+ if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.SigningKey))); err != nil {
9292+ return err
9393+ }
9494+ if _, err := cw.WriteString(string(t.SigningKey)); err != nil {
9595+ return err
9696+ }
9797+ return nil
9898+}
9999+100100+func (t *Key) UnmarshalCBOR(r io.Reader) (err error) {
101101+ *t = Key{}
102102+103103+ cr := cbg.NewCborReader(r)
104104+105105+ maj, extra, err := cr.ReadHeader()
106106+ if err != nil {
107107+ return err
108108+ }
109109+ defer func() {
110110+ if err == io.EOF {
111111+ err = io.ErrUnexpectedEOF
112112+ }
113113+ }()
114114+115115+ if maj != cbg.MajMap {
116116+ return fmt.Errorf("cbor input should be of type map")
117117+ }
118118+119119+ if extra > cbg.MaxLength {
120120+ return fmt.Errorf("Key: map struct too large (%d)", extra)
121121+ }
122122+123123+ n := extra
124124+125125+ nameBuf := make([]byte, 10)
126126+ for i := uint64(0); i < n; i++ {
127127+ nameLen, ok, err := cbg.ReadFullStringIntoBuf(cr, nameBuf, 1000000)
128128+ if err != nil {
129129+ return err
130130+ }
131131+132132+ if !ok {
133133+ // Field doesn't exist on this type, so ignore it
134134+ if err := cbg.ScanForLinks(cr, func(cid.Cid) {}); err != nil {
135135+ return err
136136+ }
137137+ continue
138138+ }
139139+140140+ switch string(nameBuf[:nameLen]) {
141141+ // t.LexiconTypeID (string) (string)
142142+ case "$type":
143143+144144+ {
145145+ sval, err := cbg.ReadStringWithMax(cr, 1000000)
146146+ if err != nil {
147147+ return err
148148+ }
149149+150150+ t.LexiconTypeID = string(sval)
151151+ }
152152+ // t.CreatedAt (string) (string)
153153+ case "createdAt":
154154+155155+ {
156156+ sval, err := cbg.ReadStringWithMax(cr, 1000000)
157157+ if err != nil {
158158+ return err
159159+ }
160160+161161+ t.CreatedAt = string(sval)
162162+ }
163163+ // t.SigningKey (string) (string)
164164+ case "signingKey":
165165+166166+ {
167167+ sval, err := cbg.ReadStringWithMax(cr, 1000000)
168168+ if err != nil {
169169+ return err
170170+ }
171171+172172+ t.SigningKey = string(sval)
173173+ }
174174+175175+ default:
176176+ // Field doesn't exist on this type, so ignore it
177177+ if err := cbg.ScanForLinks(r, func(cid.Cid) {}); err != nil {
178178+ return err
179179+ }
180180+ }
181181+ }
182182+183183+ return nil
184184+}
185185+func (t *Livestream) MarshalCBOR(w io.Writer) error {
186186+ if t == nil {
187187+ _, err := w.Write(cbg.CborNull)
188188+ return err
189189+ }
190190+191191+ cw := cbg.NewCborWriter(w)
192192+ fieldCount := 4
193193+194194+ if t.Url == nil {
195195+ fieldCount--
196196+ }
197197+198198+ if _, err := cw.Write(cbg.CborEncodeMajorType(cbg.MajMap, uint64(fieldCount))); err != nil {
199199+ return err
200200+ }
201201+202202+ // t.Url (string) (string)
203203+ if t.Url != nil {
204204+205205+ if len("url") > 1000000 {
206206+ return xerrors.Errorf("Value in field \"url\" was too long")
207207+ }
208208+209209+ if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("url"))); err != nil {
210210+ return err
211211+ }
212212+ if _, err := cw.WriteString(string("url")); err != nil {
213213+ return err
214214+ }
215215+216216+ if t.Url == nil {
217217+ if _, err := cw.Write(cbg.CborNull); err != nil {
218218+ return err
219219+ }
220220+ } else {
221221+ if len(*t.Url) > 1000000 {
222222+ return xerrors.Errorf("Value in field t.Url was too long")
223223+ }
224224+225225+ if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(*t.Url))); err != nil {
226226+ return err
227227+ }
228228+ if _, err := cw.WriteString(string(*t.Url)); err != nil {
229229+ return err
230230+ }
231231+ }
232232+ }
233233+234234+ // t.LexiconTypeID (string) (string)
235235+ if len("$type") > 1000000 {
236236+ return xerrors.Errorf("Value in field \"$type\" was too long")
237237+ }
238238+239239+ if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("$type"))); err != nil {
240240+ return err
241241+ }
242242+ if _, err := cw.WriteString(string("$type")); err != nil {
243243+ return err
244244+ }
245245+246246+ if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("place.stream.livestream"))); err != nil {
247247+ return err
248248+ }
249249+ if _, err := cw.WriteString(string("place.stream.livestream")); err != nil {
250250+ return err
251251+ }
252252+253253+ // t.Title (string) (string)
254254+ if len("title") > 1000000 {
255255+ return xerrors.Errorf("Value in field \"title\" was too long")
256256+ }
257257+258258+ if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("title"))); err != nil {
259259+ return err
260260+ }
261261+ if _, err := cw.WriteString(string("title")); err != nil {
262262+ return err
263263+ }
264264+265265+ if len(t.Title) > 1000000 {
266266+ return xerrors.Errorf("Value in field t.Title was too long")
267267+ }
268268+269269+ if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Title))); err != nil {
270270+ return err
271271+ }
272272+ if _, err := cw.WriteString(string(t.Title)); err != nil {
273273+ return err
274274+ }
275275+276276+ // t.CreatedAt (string) (string)
277277+ if len("createdAt") > 1000000 {
278278+ return xerrors.Errorf("Value in field \"createdAt\" was too long")
279279+ }
280280+281281+ if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("createdAt"))); err != nil {
282282+ return err
283283+ }
284284+ if _, err := cw.WriteString(string("createdAt")); err != nil {
285285+ return err
286286+ }
287287+288288+ if len(t.CreatedAt) > 1000000 {
289289+ return xerrors.Errorf("Value in field t.CreatedAt was too long")
290290+ }
291291+292292+ if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.CreatedAt))); err != nil {
293293+ return err
294294+ }
295295+ if _, err := cw.WriteString(string(t.CreatedAt)); err != nil {
296296+ return err
297297+ }
298298+ return nil
299299+}
300300+301301+func (t *Livestream) UnmarshalCBOR(r io.Reader) (err error) {
302302+ *t = Livestream{}
303303+304304+ cr := cbg.NewCborReader(r)
305305+306306+ maj, extra, err := cr.ReadHeader()
307307+ if err != nil {
308308+ return err
309309+ }
310310+ defer func() {
311311+ if err == io.EOF {
312312+ err = io.ErrUnexpectedEOF
313313+ }
314314+ }()
315315+316316+ if maj != cbg.MajMap {
317317+ return fmt.Errorf("cbor input should be of type map")
318318+ }
319319+320320+ if extra > cbg.MaxLength {
321321+ return fmt.Errorf("Livestream: map struct too large (%d)", extra)
322322+ }
323323+324324+ n := extra
325325+326326+ nameBuf := make([]byte, 9)
327327+ for i := uint64(0); i < n; i++ {
328328+ nameLen, ok, err := cbg.ReadFullStringIntoBuf(cr, nameBuf, 1000000)
329329+ if err != nil {
330330+ return err
331331+ }
332332+333333+ if !ok {
334334+ // Field doesn't exist on this type, so ignore it
335335+ if err := cbg.ScanForLinks(cr, func(cid.Cid) {}); err != nil {
336336+ return err
337337+ }
338338+ continue
339339+ }
340340+341341+ switch string(nameBuf[:nameLen]) {
342342+ // t.Url (string) (string)
343343+ case "url":
344344+345345+ {
346346+ b, err := cr.ReadByte()
347347+ if err != nil {
348348+ return err
349349+ }
350350+ if b != cbg.CborNull[0] {
351351+ if err := cr.UnreadByte(); err != nil {
352352+ return err
353353+ }
354354+355355+ sval, err := cbg.ReadStringWithMax(cr, 1000000)
356356+ if err != nil {
357357+ return err
358358+ }
359359+360360+ t.Url = (*string)(&sval)
361361+ }
362362+ }
363363+ // t.LexiconTypeID (string) (string)
364364+ case "$type":
365365+366366+ {
367367+ sval, err := cbg.ReadStringWithMax(cr, 1000000)
368368+ if err != nil {
369369+ return err
370370+ }
371371+372372+ t.LexiconTypeID = string(sval)
373373+ }
374374+ // t.Title (string) (string)
375375+ case "title":
376376+377377+ {
378378+ sval, err := cbg.ReadStringWithMax(cr, 1000000)
379379+ if err != nil {
380380+ return err
381381+ }
382382+383383+ t.Title = string(sval)
384384+ }
385385+ // t.CreatedAt (string) (string)
386386+ case "createdAt":
387387+388388+ {
389389+ sval, err := cbg.ReadStringWithMax(cr, 1000000)
390390+ if err != nil {
391391+ return err
392392+ }
393393+394394+ t.CreatedAt = string(sval)
395395+ }
396396+397397+ default:
398398+ // Field doesn't exist on this type, so ignore it
399399+ if err := cbg.ScanForLinks(r, func(cid.Cid) {}); err != nil {
400400+ return err
401401+ }
402402+ }
403403+ }
404404+405405+ return nil
406406+}
+21
pkg/streamplace/streamkey.go
···11+// Code generated by cmd/lexgen (see Makefile's lexgen); DO NOT EDIT.
22+33+package streamplace
44+55+// schema: place.stream.key
66+77+import (
88+ "github.com/bluesky-social/indigo/lex/util"
99+)
1010+1111+func init() {
1212+ util.RegisterType("place.stream.key", &Key{})
1313+} //
1414+// RECORDTYPE: Key
1515+type Key struct {
1616+ LexiconTypeID string `json:"$type,const=place.stream.key" cborgen:"$type,const=place.stream.key"`
1717+ // createdAt: Client-declared timestamp when this key was created.
1818+ CreatedAt string `json:"createdAt" cborgen:"createdAt"`
1919+ // signingKey: The did:key signing key for the stream.
2020+ SigningKey string `json:"signingKey" cborgen:"signingKey"`
2121+}
+23
pkg/streamplace/streamlivestream.go
···11+// Code generated by cmd/lexgen (see Makefile's lexgen); DO NOT EDIT.
22+33+package streamplace
44+55+// schema: place.stream.livestream
66+77+import (
88+ "github.com/bluesky-social/indigo/lex/util"
99+)
1010+1111+func init() {
1212+ util.RegisterType("place.stream.livestream", &Livestream{})
1313+} //
1414+// RECORDTYPE: Livestream
1515+type Livestream struct {
1616+ LexiconTypeID string `json:"$type,const=place.stream.livestream" cborgen:"$type,const=place.stream.livestream"`
1717+ // createdAt: Client-declared timestamp when this livestream started.
1818+ CreatedAt string `json:"createdAt" cborgen:"createdAt"`
1919+ // title: The title of the livestream, as it will be announced to followers.
2020+ Title string `json:"title" cborgen:"title"`
2121+ // url: The URL where this stream can be found. This is primarily a hint for other Streamplace nodes to locate and replicate the stream.
2222+ Url *string `json:"url,omitempty" cborgen:"url,omitempty"`
2323+}