Skip to content

Commit

Permalink
add nip92 imeta parsing helper.
Browse files Browse the repository at this point in the history
  • Loading branch information
fiatjaf committed Dec 29, 2024
1 parent 91efcb3 commit a4bae38
Show file tree
Hide file tree
Showing 2 changed files with 173 additions and 0 deletions.
73 changes: 73 additions & 0 deletions nip92/imeta.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package nip92

import (
"strconv"
"strings"

"github.com/nbd-wtf/go-nostr"
)

type IMeta []IMetaEntry

func (imeta IMeta) Get(url string) (IMetaEntry, bool) {
for _, entry := range imeta {
if entry.URL == url {
return entry, true
}
}
return IMetaEntry{}, false
}

type IMetaEntry struct {
URL string
Blurhash string
Width int
Height int
Alt string
}

func ParseTags(tags nostr.Tags) IMeta {
var imeta IMeta
for i, tag := range tags {
if len(tag) > 2 && tag[0] == "imeta" {
entry := IMetaEntry{}
for _, item := range tag[1:] {
div := strings.Index(item, " ")
switch item[0:div] {
case "url":
entry.URL = item[div+1:]
case "alt":
entry.Alt = item[div+1:]
case "blurhash":
entry.Blurhash = item[div+1:]
case "dim":
xySplit := strings.Index(item[div+1:], "x")
if xySplit == -1 {
// if any tag is wrong them we don't trust this guy anyway
return nil
}

x, err := strconv.Atoi(item[div+1 : div+1+xySplit])
if err != nil {
return nil
}
entry.Width = x

y, err := strconv.Atoi(item[div+1+xySplit+1:])
if err != nil {
return nil
}
entry.Height = y
}
}

if imeta == nil {
imeta = make(IMeta, 1, len(tags)-i)
imeta[0] = entry
} else {
imeta = append(imeta, entry)
}
}
}
return imeta
}
100 changes: 100 additions & 0 deletions nip92/imeta_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
package nip92

import (
"testing"

"github.com/nbd-wtf/go-nostr"
"github.com/stretchr/testify/require"
)

func TestIMetaParsing(t *testing.T) {
for i, tcase := range []struct {
expected IMeta
tags nostr.Tags
}{
{
expected: nil,
tags: nostr.Tags{},
},
{
expected: nil,
tags: nostr.Tags{{"t", "nothing"}},
},
{
expected: nil,
tags: nostr.Tags{{"imeta", "nothing"}},
},
{
expected: nil,
tags: nostr.Tags{
{
"imeta",
"url https://i.nostr.build/yhsyFkwxWlw7odSB.gif",
"blurhash eDG*7p~AE34;E29x^ij?EMWBEMIWI;IpbI0g0gn+%1oyNGEMM|%1n%",
"dim 225x191",
},
{
"imeta",
"blurhash qwkueh",
"dim oxo",
},
},
},
{
expected: IMeta{
{
URL: "https://i.nostr.build/yhsyFkwxWlw7odSB.gif",
Blurhash: "eDG*7p~AE34;E29x^ij?EMWBEMIWI;IpbI0g0gn+%1oyNGEMM|%1n%",
Width: 225,
Height: 191,
},
},
tags: nostr.Tags{
{
"imeta",
"url https://i.nostr.build/yhsyFkwxWlw7odSB.gif",
"blurhash eDG*7p~AE34;E29x^ij?EMWBEMIWI;IpbI0g0gn+%1oyNGEMM|%1n%",
"dim 225x191",
},
},
},
{
expected: IMeta{
{
URL: "https://image.nostr.build/94060676611fe7fca86588068d3f140607eda443f6d66d6b9754e93b0b8439ac.jpg",
Blurhash: "eQF?RxZ}nNo~fk*0s6Z~kYem0iacsRkEsl9eW;oHkDoIxbtSobRkRi",
Width: 3024,
Height: 3024,
},
{
URL: "https://image.nostr.build/9bc3998f79c401bc9d3b3b74c1cbff0a3225f754194b94a6f5750ca6ea492846.jpg",
Blurhash: "#2Ss1[RO%MIUx]R*-;WUtR0Kt6njof-;xu-pofxt4-M{yExt%2s.xaV[jF4TM|?bt6tmt6tRaybI0KtS=wRkWYWAtRjYt7tR%M?vNerWRjIBV@RjIAxYIpRP_3NGaKWXRj",
Width: 1920,
Height: 1494,
Alt: "Verifiable file url",
},
},
tags: nostr.Tags{
{
"imeta",
"url https://image.nostr.build/94060676611fe7fca86588068d3f140607eda443f6d66d6b9754e93b0b8439ac.jpg",
"blurhash eQF?RxZ}nNo~fk*0s6Z~kYem0iacsRkEsl9eW;oHkDoIxbtSobRkRi",
"dim 3024x3024",
},
{
"imeta",
"url https://image.nostr.build/9bc3998f79c401bc9d3b3b74c1cbff0a3225f754194b94a6f5750ca6ea492846.jpg",
"m image/jpeg",
"alt Verifiable file url",
"x 80a8f087f6c45ec7fb9e8839e5af095df9b439a0836cdf70a244086b6b2c1a88",
"size 121397",
"dim 1920x1494",
"blurhash #2Ss1[RO%MIUx]R*-;WUtR0Kt6njof-;xu-pofxt4-M{yExt%2s.xaV[jF4TM|?bt6tmt6tRaybI0KtS=wRkWYWAtRjYt7tR%M?vNerWRjIBV@RjIAxYIpRP_3NGaKWXRj",
"ox 9bc3998f79c401bc9d3b3b74c1cbff0a3225f754194b94a6f5750ca6ea492846",
},
},
},
} {
require.Equal(t, tcase.expected, ParseTags(tcase.tags), "case %d", i)
}
}

0 comments on commit a4bae38

Please sign in to comment.