mirror of
https://github.com/edufeed-org/eventstore.git
synced 2025-12-09 16:24:32 +00:00
refactored, added some tests, still a lot to do
This commit is contained in:
parent
fec3e8e2a5
commit
bf07264e17
7 changed files with 1152 additions and 181 deletions
4
go.mod
4
go.mod
|
|
@ -5,6 +5,7 @@ go 1.24.1
|
||||||
require (
|
require (
|
||||||
github.com/fiatjaf/eventstore v0.16.2
|
github.com/fiatjaf/eventstore v0.16.2
|
||||||
github.com/nbd-wtf/go-nostr v0.51.8
|
github.com/nbd-wtf/go-nostr v0.51.8
|
||||||
|
github.com/stretchr/testify v1.10.0
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
|
@ -15,6 +16,7 @@ require (
|
||||||
github.com/bytedance/sonic/loader v0.2.4 // indirect
|
github.com/bytedance/sonic/loader v0.2.4 // indirect
|
||||||
github.com/cloudwego/base64x v0.1.5 // indirect
|
github.com/cloudwego/base64x v0.1.5 // indirect
|
||||||
github.com/coder/websocket v1.8.12 // indirect
|
github.com/coder/websocket v1.8.12 // indirect
|
||||||
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
github.com/decred/dcrd/crypto/blake256 v1.1.0 // indirect
|
github.com/decred/dcrd/crypto/blake256 v1.1.0 // indirect
|
||||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 // indirect
|
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 // indirect
|
||||||
github.com/josharian/intern v1.0.0 // indirect
|
github.com/josharian/intern v1.0.0 // indirect
|
||||||
|
|
@ -23,6 +25,7 @@ require (
|
||||||
github.com/mailru/easyjson v0.9.0 // indirect
|
github.com/mailru/easyjson v0.9.0 // indirect
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
github.com/puzpuzpuz/xsync/v3 v3.5.1 // indirect
|
github.com/puzpuzpuz/xsync/v3 v3.5.1 // indirect
|
||||||
github.com/tidwall/gjson v1.18.0 // indirect
|
github.com/tidwall/gjson v1.18.0 // indirect
|
||||||
github.com/tidwall/match v1.1.1 // indirect
|
github.com/tidwall/match v1.1.1 // indirect
|
||||||
|
|
@ -31,4 +34,5 @@ require (
|
||||||
golang.org/x/arch v0.15.0 // indirect
|
golang.org/x/arch v0.15.0 // indirect
|
||||||
golang.org/x/exp v0.0.0-20250305212735-054e65f0b394 // indirect
|
golang.org/x/exp v0.0.0-20250305212735-054e65f0b394 // indirect
|
||||||
golang.org/x/sys v0.31.0 // indirect
|
golang.org/x/sys v0.31.0 // indirect
|
||||||
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
)
|
)
|
||||||
|
|
|
||||||
1
go.sum
1
go.sum
|
|
@ -74,6 +74,7 @@ golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c=
|
||||||
golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
|
golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
|
||||||
golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
|
golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
|
||||||
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
|
|
|
||||||
457
typesense30142/nostr_amb.go
Normal file
457
typesense30142/nostr_amb.go
Normal file
|
|
@ -0,0 +1,457 @@
|
||||||
|
package typesense30142
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/nbd-wtf/go-nostr"
|
||||||
|
)
|
||||||
|
|
||||||
|
// converts a nostr event to stringified JSON
|
||||||
|
func eventToStringifiedJSON(event *nostr.Event) (string, error) {
|
||||||
|
jsonData, err := json.Marshal(event)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
jsonString := string(jsonData)
|
||||||
|
return jsonString, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// NostrToAMB converts a Nostr event of kind 30142 to AMB metadata
|
||||||
|
func NostrToAMB(event *nostr.Event) (*AMBMetadata, error) {
|
||||||
|
if event == nil {
|
||||||
|
return nil, fmt.Errorf("cannot convert nil event")
|
||||||
|
}
|
||||||
|
|
||||||
|
eventRaw, err := eventToStringifiedJSON(event)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error converting event to JSON: %w", err)
|
||||||
|
}
|
||||||
|
amb := &AMBMetadata{
|
||||||
|
Type: []string{"LearningResource"},
|
||||||
|
NostrMetadata: NostrMetadata{
|
||||||
|
EventID: event.ID,
|
||||||
|
EventPubKey: event.PubKey,
|
||||||
|
EventContent: event.Content,
|
||||||
|
EventCreatedAt: event.CreatedAt,
|
||||||
|
EventKind: event.Kind,
|
||||||
|
EventSig: event.Sig,
|
||||||
|
EventRaw: eventRaw,
|
||||||
|
},
|
||||||
|
About: []*About{},
|
||||||
|
Keywords: []string{},
|
||||||
|
InLanguage: []string{},
|
||||||
|
Creator: []*Creator{},
|
||||||
|
Contributor: []*Contributor{},
|
||||||
|
Publisher: []*Publisher{},
|
||||||
|
Funder: []*Funder{},
|
||||||
|
LearningResourceType: []*LearningResourceType{},
|
||||||
|
Audience: []*Audience{},
|
||||||
|
Teaches: []*Teaches{},
|
||||||
|
Assesses: []*Assesses{},
|
||||||
|
CompetencyRequired: []*CompetencyRequired{},
|
||||||
|
EducationalLevel: []*EducationalLevel{},
|
||||||
|
IsBasedOn: []*IsBasedOn{},
|
||||||
|
IsPartOf: []*IsPartOf{},
|
||||||
|
HasPart: []*HasPart{},
|
||||||
|
Trailer: []*Trailer{},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tag := range event.Tags {
|
||||||
|
if len(tag) < 2 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
switch tag[0] {
|
||||||
|
case "d":
|
||||||
|
if len(tag) >= 2 {
|
||||||
|
amb.D = tag[1]
|
||||||
|
amb.ID = event.ID
|
||||||
|
}
|
||||||
|
case "type":
|
||||||
|
if len(tag) >= 2 {
|
||||||
|
amb.Type = tag[1:]
|
||||||
|
}
|
||||||
|
|
||||||
|
case "name":
|
||||||
|
if len(tag) >= 2 {
|
||||||
|
amb.Name = tag[1]
|
||||||
|
}
|
||||||
|
case "description":
|
||||||
|
if len(tag) >= 2 {
|
||||||
|
amb.Description = tag[1]
|
||||||
|
}
|
||||||
|
case "creator":
|
||||||
|
if len(tag) >= 3 {
|
||||||
|
creator := &Creator{
|
||||||
|
BaseEntity: BaseEntity{
|
||||||
|
ID: tag[1],
|
||||||
|
Name: tag[2],
|
||||||
|
},
|
||||||
|
Affiliation: &Affiliation{},
|
||||||
|
}
|
||||||
|
if len(tag) >= 4 {
|
||||||
|
creator.Type = tag[3]
|
||||||
|
}
|
||||||
|
if len(tag) >= 5 {
|
||||||
|
creator.Affiliation.Name = tag[4]
|
||||||
|
}
|
||||||
|
if len(tag) >= 6 {
|
||||||
|
creator.Affiliation.Type = tag[5]
|
||||||
|
}
|
||||||
|
if len(tag) >= 7 {
|
||||||
|
creator.Affiliation.ID = tag[6]
|
||||||
|
}
|
||||||
|
amb.Creator = append(amb.Creator, creator)
|
||||||
|
}
|
||||||
|
case "image":
|
||||||
|
if len(tag) >= 2 {
|
||||||
|
amb.Image = tag[1]
|
||||||
|
}
|
||||||
|
case "about":
|
||||||
|
if len(tag) >= 4 {
|
||||||
|
subject := &About{
|
||||||
|
ControlledVocabulary: ControlledVocabulary{
|
||||||
|
ID: tag[1],
|
||||||
|
PrefLabel: tag[2],
|
||||||
|
InLanguage: tag[3],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if len(tag) >= 5 {
|
||||||
|
subject.Type = tag[4]
|
||||||
|
}
|
||||||
|
amb.About = append(amb.About, subject)
|
||||||
|
}
|
||||||
|
case "learningResourceType":
|
||||||
|
if len(tag) >= 4 {
|
||||||
|
lrt := &LearningResourceType{
|
||||||
|
ControlledVocabulary: ControlledVocabulary{
|
||||||
|
ID: tag[1],
|
||||||
|
PrefLabel: tag[2],
|
||||||
|
InLanguage: tag[3],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
amb.LearningResourceType = append(amb.LearningResourceType, lrt)
|
||||||
|
}
|
||||||
|
case "inLanguage":
|
||||||
|
if len(tag) >= 2 {
|
||||||
|
amb.InLanguage = append(amb.InLanguage, tag[1])
|
||||||
|
}
|
||||||
|
case "keywords":
|
||||||
|
if len(tag) >= 2 {
|
||||||
|
amb.Keywords = tag[1:]
|
||||||
|
}
|
||||||
|
case "license":
|
||||||
|
if len(tag) >= 3 {
|
||||||
|
amb.License = &License{
|
||||||
|
ID: tag[1],
|
||||||
|
Name: tag[2],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case "datePublished":
|
||||||
|
if len(tag) >= 2 {
|
||||||
|
amb.DatePublished = tag[1]
|
||||||
|
}
|
||||||
|
case "dateCreated":
|
||||||
|
if len(tag) >= 2 {
|
||||||
|
amb.DateCreated = tag[1]
|
||||||
|
}
|
||||||
|
case "dateModified":
|
||||||
|
if len(tag) >= 2 {
|
||||||
|
amb.DateModified = tag[1]
|
||||||
|
}
|
||||||
|
case "publisher":
|
||||||
|
if len(tag) >= 3 {
|
||||||
|
publisher := &Publisher{
|
||||||
|
BaseEntity: BaseEntity{
|
||||||
|
ID: tag[1],
|
||||||
|
Name: tag[2],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if len(tag) >= 4 {
|
||||||
|
publisher.Type = tag[3]
|
||||||
|
}
|
||||||
|
amb.Publisher = append(amb.Publisher, publisher)
|
||||||
|
}
|
||||||
|
case "contributor":
|
||||||
|
if len(tag) >= 4 {
|
||||||
|
contributor := &Contributor{
|
||||||
|
BaseEntity: BaseEntity{
|
||||||
|
ID: tag[1],
|
||||||
|
Name: tag[2],
|
||||||
|
Type: tag[3],
|
||||||
|
},
|
||||||
|
Affiliation: &Affiliation{},
|
||||||
|
}
|
||||||
|
if len(tag) >= 5 {
|
||||||
|
contributor.Affiliation.Name = tag[4]
|
||||||
|
}
|
||||||
|
if len(tag) >= 6 {
|
||||||
|
contributor.Affiliation.Type = tag[5]
|
||||||
|
}
|
||||||
|
if len(tag) >= 7 {
|
||||||
|
contributor.Affiliation.ID = tag[6]
|
||||||
|
}
|
||||||
|
amb.Contributor = append(amb.Contributor, contributor)
|
||||||
|
}
|
||||||
|
case "funder":
|
||||||
|
if len(tag) >= 3 {
|
||||||
|
funder := &Funder{
|
||||||
|
BaseEntity: BaseEntity{
|
||||||
|
ID: tag[1],
|
||||||
|
Name: tag[2],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if len(tag) >= 4 {
|
||||||
|
funder.Type = tag[3]
|
||||||
|
}
|
||||||
|
amb.Funder = append(amb.Funder, funder)
|
||||||
|
}
|
||||||
|
case "isAccessibleForFree":
|
||||||
|
if len(tag) >= 2 && (tag[1] == "true" || tag[1] == "1") {
|
||||||
|
amb.IsAccessibleForFree = true
|
||||||
|
}
|
||||||
|
case "audience":
|
||||||
|
if len(tag) >= 4 {
|
||||||
|
audience := &Audience{
|
||||||
|
ControlledVocabulary: ControlledVocabulary{
|
||||||
|
ID: tag[1],
|
||||||
|
PrefLabel: tag[2],
|
||||||
|
InLanguage: tag[3],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
amb.Audience = append(amb.Audience, audience)
|
||||||
|
}
|
||||||
|
case "duration":
|
||||||
|
if len(tag) >= 2 {
|
||||||
|
amb.Duration = tag[1]
|
||||||
|
}
|
||||||
|
case "conditionsOfAccess":
|
||||||
|
if len(tag) == 4 {
|
||||||
|
conditionsOfAccess := &ConditionsOfAccess{
|
||||||
|
ControlledVocabulary: ControlledVocabulary{
|
||||||
|
ID: tag[1],
|
||||||
|
PrefLabel: tag[2],
|
||||||
|
InLanguage: tag[3],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
amb.ConditionsOfAccess = conditionsOfAccess
|
||||||
|
}
|
||||||
|
case "teaches":
|
||||||
|
if len(tag) >= 3 {
|
||||||
|
teaches := &Teaches{
|
||||||
|
ControlledVocabulary: ControlledVocabulary{
|
||||||
|
ID: tag[1],
|
||||||
|
PrefLabel: tag[2],
|
||||||
|
InLanguage: tag[3],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
amb.Teaches = append(amb.Teaches, teaches)
|
||||||
|
}
|
||||||
|
case "assesses":
|
||||||
|
if len(tag) >= 3 {
|
||||||
|
assesses := &Assesses{
|
||||||
|
ControlledVocabulary: ControlledVocabulary{
|
||||||
|
ID: tag[1],
|
||||||
|
PrefLabel: tag[2],
|
||||||
|
InLanguage: tag[3],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
amb.Assesses = append(amb.Assesses, assesses)
|
||||||
|
}
|
||||||
|
case "competencyRequired":
|
||||||
|
if len(tag) >= 3 {
|
||||||
|
competencyRequired := &CompetencyRequired{
|
||||||
|
ControlledVocabulary: ControlledVocabulary{
|
||||||
|
ID: tag[1],
|
||||||
|
PrefLabel: tag[2],
|
||||||
|
InLanguage: tag[3],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
amb.CompetencyRequired = append(amb.CompetencyRequired, competencyRequired)
|
||||||
|
}
|
||||||
|
case "educationalLevel":
|
||||||
|
if len(tag) >= 3 {
|
||||||
|
educationalLevel := &EducationalLevel{
|
||||||
|
ControlledVocabulary: ControlledVocabulary{
|
||||||
|
ID: tag[1],
|
||||||
|
PrefLabel: tag[2],
|
||||||
|
InLanguage: tag[3],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
amb.EducationalLevel = append(amb.EducationalLevel, educationalLevel)
|
||||||
|
}
|
||||||
|
case "interactivityType":
|
||||||
|
if len(tag) >= 3 {
|
||||||
|
interactivityType := &InteractivityType{
|
||||||
|
ControlledVocabulary: ControlledVocabulary{
|
||||||
|
ID: tag[1],
|
||||||
|
PrefLabel: tag[2],
|
||||||
|
InLanguage: tag[3],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
amb.InteractivityType = interactivityType
|
||||||
|
}
|
||||||
|
case "isBasedOn":
|
||||||
|
if len(tag) >= 3 {
|
||||||
|
isBasedOn := &IsBasedOn{
|
||||||
|
ID: tag[1],
|
||||||
|
Name: tag[2],
|
||||||
|
}
|
||||||
|
amb.IsBasedOn = append(amb.IsBasedOn, isBasedOn)
|
||||||
|
}
|
||||||
|
case "isPartOf":
|
||||||
|
if len(tag) >= 4 {
|
||||||
|
isPartOf := &IsPartOf{
|
||||||
|
BaseEntity: BaseEntity{
|
||||||
|
ID: tag[1],
|
||||||
|
Name: tag[2],
|
||||||
|
Type: tag[3],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
amb.IsPartOf = append(amb.IsPartOf, isPartOf)
|
||||||
|
}
|
||||||
|
case "hasPart":
|
||||||
|
if len(tag) >= 4 {
|
||||||
|
hasPart := &HasPart{
|
||||||
|
BaseEntity: BaseEntity{
|
||||||
|
ID: tag[1],
|
||||||
|
Name: tag[2],
|
||||||
|
Type: tag[3],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
amb.HasPart = append(amb.HasPart, hasPart)
|
||||||
|
}
|
||||||
|
case "trailer":
|
||||||
|
if len(tag) >= 8 {
|
||||||
|
trailer := &Trailer{
|
||||||
|
ContentUrl: tag[1],
|
||||||
|
Type: tag[2],
|
||||||
|
EncodingFormat: tag[3],
|
||||||
|
ContentSize: tag[4],
|
||||||
|
Sha256: tag[5],
|
||||||
|
EmbedUrl: tag[6],
|
||||||
|
Bitrate: tag[7],
|
||||||
|
}
|
||||||
|
amb.Trailer = append(amb.Trailer, trailer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return amb, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// // NostrToAMB converts a Nostr event of kind 30142 to AMB metadata
|
||||||
|
// func NostrToAMB(event *nostr.Event) (*AMBMetadata, error) {
|
||||||
|
// eventRaw, _ := eventToStringifiedJSON(event)
|
||||||
|
|
||||||
|
// amb := &AMBMetadata{
|
||||||
|
// Type: "LearningResource",
|
||||||
|
// NostrMetadata: NostrMetadata{
|
||||||
|
// EventID: event.ID,
|
||||||
|
// EventPubKey: event.PubKey,
|
||||||
|
// EventContent: event.Content,
|
||||||
|
// EventCreatedAt: event.CreatedAt,
|
||||||
|
// EventKind: event.Kind,
|
||||||
|
// EventSig: event.Sig,
|
||||||
|
// EventRaw: eventRaw,
|
||||||
|
// },
|
||||||
|
// }
|
||||||
|
|
||||||
|
// for _, tag := range event.Tags {
|
||||||
|
// if len(tag) < 2 {
|
||||||
|
// continue
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // TODO alle Attribute durchgehen für das parsen
|
||||||
|
// switch tag[0] {
|
||||||
|
// case "d":
|
||||||
|
// if len(tag) >= 2 {
|
||||||
|
// amb.ID = event.ID
|
||||||
|
// amb.D = tag[1]
|
||||||
|
// }
|
||||||
|
// case "name":
|
||||||
|
// if len(tag) >= 2 {
|
||||||
|
// amb.Name = tag[1]
|
||||||
|
// }
|
||||||
|
// case "description":
|
||||||
|
// if len(tag) >= 2 {
|
||||||
|
// amb.Description = tag[1]
|
||||||
|
// }
|
||||||
|
// case "creator":
|
||||||
|
// if len(tag) >= 2 {
|
||||||
|
// creator := &Creator{}
|
||||||
|
// creator.Name = tag[1]
|
||||||
|
// if len(tag) >= 3 {
|
||||||
|
// creator.ID = tag[2]
|
||||||
|
// }
|
||||||
|
// if len(tag) >= 4 {
|
||||||
|
// creator.Type = tag[3]
|
||||||
|
// }
|
||||||
|
|
||||||
|
// amb.Creator = append(amb.Creator, creator)
|
||||||
|
// }
|
||||||
|
// case "image":
|
||||||
|
// if len(tag) >= 2 {
|
||||||
|
// amb.Image = tag[1]
|
||||||
|
// }
|
||||||
|
// case "about":
|
||||||
|
// if len(tag) >= 3 {
|
||||||
|
// subject := &About{}
|
||||||
|
// subject.PrefLabel = tag[1]
|
||||||
|
// subject.InLanguage = tag[2]
|
||||||
|
// if len(tag) >= 4 {
|
||||||
|
// subject.ID = tag[3]
|
||||||
|
// }
|
||||||
|
// amb.About = append(amb.About, subject)
|
||||||
|
// }
|
||||||
|
// case "learningResourceType":
|
||||||
|
// if len(tag) >= 3 {
|
||||||
|
// lrt := &LearningResourceType{}
|
||||||
|
// lrt.PrefLabel = tag[1]
|
||||||
|
// lrt.InLanguage = tag[2]
|
||||||
|
// if len(tag) >= 4 {
|
||||||
|
// lrt.ID = tag[3]
|
||||||
|
// }
|
||||||
|
// amb.LearningResourceType = append(amb.LearningResourceType, lrt)
|
||||||
|
// }
|
||||||
|
// case "inLanguage":
|
||||||
|
// if len(tag) >= 2 {
|
||||||
|
// amb.InLanguage = append(amb.InLanguage, tag[1])
|
||||||
|
// }
|
||||||
|
// case "keywords":
|
||||||
|
// if len(tag) >= 2 {
|
||||||
|
// amb.Keywords = tag[1:]
|
||||||
|
// }
|
||||||
|
// case "license":
|
||||||
|
// if len(tag) >= 3 {
|
||||||
|
// amb.License = &License{}
|
||||||
|
// amb.License.ID = tag[1]
|
||||||
|
// amb.License.Name = tag[2]
|
||||||
|
|
||||||
|
// }
|
||||||
|
// case "datePublished":
|
||||||
|
// if len(tag) >= 2 {
|
||||||
|
// amb.DatePublished = tag[1]
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return amb, nil
|
||||||
|
// }
|
||||||
|
|
||||||
|
// converts a stringified JSON event to a nostr.Event
|
||||||
|
func StringifiedJSONToNostrEvent(jsonString string) (nostr.Event, error) {
|
||||||
|
var event nostr.Event
|
||||||
|
err := json.Unmarshal([]byte(jsonString), &event)
|
||||||
|
if err != nil {
|
||||||
|
return nostr.Event{}, err
|
||||||
|
}
|
||||||
|
return event, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func Hello(name string) (string, error) {
|
||||||
|
resp := "Hello " + name + " nice to meet you"
|
||||||
|
return resp, nil
|
||||||
|
}
|
||||||
637
typesense30142/nostr_amb_test.go
Normal file
637
typesense30142/nostr_amb_test.go
Normal file
|
|
@ -0,0 +1,637 @@
|
||||||
|
package typesense30142
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/nbd-wtf/go-nostr"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
func TestNostrToAmbEvent(t *testing.T) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
sk := nostr.GeneratePrivateKey()
|
||||||
|
event := &nostr.Event{
|
||||||
|
Content: "",
|
||||||
|
CreatedAt: nostr.Now(),
|
||||||
|
Kind: 30142,
|
||||||
|
Tags: nostr.Tags{
|
||||||
|
{"d", "test-resource-id"},
|
||||||
|
{"name", "Test Resource"},
|
||||||
|
{"description", "This is a test resource"},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
event.Sign(sk)
|
||||||
|
|
||||||
|
amb, err := NostrToAMB(event)
|
||||||
|
|
||||||
|
assert.NoError(err)
|
||||||
|
assert.NotNil(amb)
|
||||||
|
|
||||||
|
assert.Equal(event.ID, amb.EventID)
|
||||||
|
assert.Equal(event.PubKey, amb.EventPubKey)
|
||||||
|
assert.Equal(event.Content, amb.EventContent)
|
||||||
|
assert.Equal(event.Kind, amb.EventKind)
|
||||||
|
assert.Equal(event.Sig, amb.EventSig)
|
||||||
|
assert.Equal(event.CreatedAt, amb.EventCreatedAt)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Helper function to create a test event with a specific tag
|
||||||
|
func createTestEvent(tags nostr.Tags) *nostr.Event {
|
||||||
|
sk := nostr.GeneratePrivateKey()
|
||||||
|
event := &nostr.Event{
|
||||||
|
Content: "",
|
||||||
|
CreatedAt: nostr.Now(),
|
||||||
|
Kind: 30142,
|
||||||
|
Tags: tags,
|
||||||
|
}
|
||||||
|
event.Sign(sk)
|
||||||
|
return event
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNostrToAMB_BasicFields(t *testing.T) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
tags := nostr.Tags{
|
||||||
|
{"d", "test-resource-id"},
|
||||||
|
{"name", "Test Resource"},
|
||||||
|
{"description", "This is a test resource"},
|
||||||
|
}
|
||||||
|
event := createTestEvent(tags)
|
||||||
|
|
||||||
|
amb, err := NostrToAMB(event)
|
||||||
|
|
||||||
|
assert.NoError(err)
|
||||||
|
assert.NotNil(amb)
|
||||||
|
|
||||||
|
assert.Equal(event.ID, amb.ID)
|
||||||
|
assert.Equal("test-resource-id", amb.D)
|
||||||
|
assert.Equal("Test Resource", amb.Name)
|
||||||
|
assert.Equal("This is a test resource", amb.Description)
|
||||||
|
|
||||||
|
assert.Equal(event.ID, amb.EventID)
|
||||||
|
assert.Equal(event.PubKey, amb.EventPubKey)
|
||||||
|
assert.Equal(event.Content, amb.EventContent)
|
||||||
|
assert.Equal(event.CreatedAt, amb.EventCreatedAt)
|
||||||
|
assert.Equal(event.Kind, amb.EventKind)
|
||||||
|
assert.Equal(event.Sig, amb.EventSig)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNostrToAMB_About(t *testing.T) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
tags := nostr.Tags{
|
||||||
|
{"d", "test-resource-id"},
|
||||||
|
{"about", "http://w3id.org/kim/schulfaecher/s1009", "Französisch", "de"},
|
||||||
|
}
|
||||||
|
event := createTestEvent(tags)
|
||||||
|
|
||||||
|
amb, err := NostrToAMB(event)
|
||||||
|
|
||||||
|
assert.NoError(err)
|
||||||
|
assert.NotNil(amb)
|
||||||
|
|
||||||
|
assert.NotEmpty(amb.About)
|
||||||
|
assert.Equal(1, len(amb.About))
|
||||||
|
assert.Equal("http://w3id.org/kim/schulfaecher/s1009", amb.About[0].ID)
|
||||||
|
assert.Equal("Französisch", amb.About[0].PrefLabel)
|
||||||
|
assert.Equal("de", amb.About[0].InLanguage)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNostrToAMB_Keywords(t *testing.T) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
tags := nostr.Tags{
|
||||||
|
{"d", "test-resource-id"},
|
||||||
|
{"keywords", "Französisch", "Niveau A2", "Sprache"},
|
||||||
|
}
|
||||||
|
event := createTestEvent(tags)
|
||||||
|
|
||||||
|
amb, err := NostrToAMB(event)
|
||||||
|
|
||||||
|
assert.NoError(err)
|
||||||
|
assert.NotNil(amb)
|
||||||
|
|
||||||
|
assert.Equal(3, len(amb.Keywords))
|
||||||
|
assert.Contains(amb.Keywords, "Französisch")
|
||||||
|
assert.Contains(amb.Keywords, "Niveau A2")
|
||||||
|
assert.Contains(amb.Keywords, "Sprache")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNostrToAMB_InLanguage(t *testing.T) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
tags := nostr.Tags{
|
||||||
|
{"d", "test-resource-id"},
|
||||||
|
{"inLanguage", "fr"},
|
||||||
|
{"inLanguage", "de"},
|
||||||
|
}
|
||||||
|
event := createTestEvent(tags)
|
||||||
|
|
||||||
|
amb, err := NostrToAMB(event)
|
||||||
|
|
||||||
|
assert.NoError(err)
|
||||||
|
assert.NotNil(amb)
|
||||||
|
|
||||||
|
assert.Equal(2, len(amb.InLanguage))
|
||||||
|
assert.Contains(amb.InLanguage, "fr")
|
||||||
|
assert.Contains(amb.InLanguage, "de")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNostrToAMB_Image(t *testing.T) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
imageURL := "https://www.tutory.de/worksheet/fbbadf1a-145a-463d-9a43-1ae9965c86b9.jpg?width=1000"
|
||||||
|
tags := nostr.Tags{
|
||||||
|
{"d", "test-resource-id"},
|
||||||
|
{"image", imageURL},
|
||||||
|
}
|
||||||
|
event := createTestEvent(tags)
|
||||||
|
|
||||||
|
amb, err := NostrToAMB(event)
|
||||||
|
|
||||||
|
assert.NoError(err)
|
||||||
|
assert.NotNil(amb)
|
||||||
|
|
||||||
|
assert.Equal(imageURL, amb.Image)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNostrToAMB_Creator(t *testing.T) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
tags := nostr.Tags{
|
||||||
|
{"d", "test-resource-id"},
|
||||||
|
{"creator", "http://author1.org", "Autorin 1", "Person"},
|
||||||
|
{"creator", "http://author2.org", "Autorin 2", "Person"},
|
||||||
|
}
|
||||||
|
event := createTestEvent(tags)
|
||||||
|
|
||||||
|
amb, err := NostrToAMB(event)
|
||||||
|
|
||||||
|
assert.NoError(err)
|
||||||
|
assert.NotNil(amb)
|
||||||
|
|
||||||
|
assert.Equal(2, len(amb.Creator))
|
||||||
|
|
||||||
|
assert.Equal("http://author1.org", amb.Creator[0].ID)
|
||||||
|
assert.Equal("Autorin 1", amb.Creator[0].Name)
|
||||||
|
assert.Equal("Person", amb.Creator[0].Type)
|
||||||
|
|
||||||
|
assert.Equal("http://author2.org", amb.Creator[1].ID)
|
||||||
|
assert.Equal("Autorin 2", amb.Creator[1].Name)
|
||||||
|
assert.Equal("Person", amb.Creator[1].Type)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNostrToAMB_Contributor(t *testing.T) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
tags := nostr.Tags{
|
||||||
|
{"d", "test-resource-id"},
|
||||||
|
{"contributor", "http://author1.org", "Autorin 1", "Person"},
|
||||||
|
{"contributor", "http://author2.org", "Autorin 2", "Person"},
|
||||||
|
}
|
||||||
|
event := createTestEvent(tags)
|
||||||
|
|
||||||
|
amb, err := NostrToAMB(event)
|
||||||
|
|
||||||
|
assert.NoError(err)
|
||||||
|
assert.NotNil(amb)
|
||||||
|
|
||||||
|
assert.Equal(2, len(amb.Contributor))
|
||||||
|
|
||||||
|
assert.Equal("http://author1.org", amb.Contributor[0].ID)
|
||||||
|
assert.Equal("Autorin 1", amb.Contributor[0].Name)
|
||||||
|
assert.Equal("Person", amb.Contributor[0].Type)
|
||||||
|
|
||||||
|
assert.Equal("http://author2.org", amb.Contributor[1].ID)
|
||||||
|
assert.Equal("Autorin 2", amb.Contributor[1].Name)
|
||||||
|
assert.Equal("Person", amb.Contributor[1].Type)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNostrToAMB_Dates(t *testing.T) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
tags := nostr.Tags{
|
||||||
|
{"d", "test-resource-id"},
|
||||||
|
{"dateCreated", "2019-07-02"},
|
||||||
|
{"datePublished", "2019-07-03"},
|
||||||
|
{"dateModified", "2019-07-04"},
|
||||||
|
}
|
||||||
|
event := createTestEvent(tags)
|
||||||
|
|
||||||
|
amb, err := NostrToAMB(event)
|
||||||
|
|
||||||
|
assert.NoError(err)
|
||||||
|
assert.NotNil(amb)
|
||||||
|
|
||||||
|
assert.Equal("2019-07-02", amb.DateCreated)
|
||||||
|
assert.Equal("2019-07-03", amb.DatePublished)
|
||||||
|
assert.Equal("2019-07-04", amb.DateModified)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNostrToAMB_Publisher(t *testing.T) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
tags := nostr.Tags{
|
||||||
|
{"d", "test-resource-id"},
|
||||||
|
{"publisher", "http://publisher1.org", "Publisher 1", "Person"},
|
||||||
|
{"publisher", "http://publisher2.org", "Publisher 2", "Organization"},
|
||||||
|
}
|
||||||
|
event := createTestEvent(tags)
|
||||||
|
|
||||||
|
amb, err := NostrToAMB(event)
|
||||||
|
|
||||||
|
assert.NoError(err)
|
||||||
|
assert.NotNil(amb)
|
||||||
|
|
||||||
|
assert.Equal(2, len(amb.Publisher))
|
||||||
|
|
||||||
|
assert.Equal("http://publisher1.org", amb.Publisher[0].ID)
|
||||||
|
assert.Equal("Publisher 1", amb.Publisher[0].Name)
|
||||||
|
assert.Equal("Person", amb.Publisher[0].Type)
|
||||||
|
|
||||||
|
assert.Equal("http://publisher2.org", amb.Publisher[1].ID)
|
||||||
|
assert.Equal("Publisher 2", amb.Publisher[1].Name)
|
||||||
|
assert.Equal("Organization", amb.Publisher[1].Type)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNostrToAMB_Funder(t *testing.T) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
tags := nostr.Tags{
|
||||||
|
{"d", "test-resource-id"},
|
||||||
|
{"funder", "http://funder1.org", "Funder 1", "Person"},
|
||||||
|
{"funder", "http://funder2.org", "Funder 2", "Organization"},
|
||||||
|
}
|
||||||
|
event := createTestEvent(tags)
|
||||||
|
|
||||||
|
amb, err := NostrToAMB(event)
|
||||||
|
|
||||||
|
assert.NoError(err)
|
||||||
|
assert.NotNil(amb)
|
||||||
|
|
||||||
|
assert.Equal(2, len(amb.Funder))
|
||||||
|
|
||||||
|
assert.Equal("http://funder1.org", amb.Funder[0].ID)
|
||||||
|
assert.Equal("Funder 1", amb.Funder[0].Name)
|
||||||
|
assert.Equal("Person", amb.Funder[0].Type)
|
||||||
|
|
||||||
|
assert.Equal("http://funder2.org", amb.Funder[1].ID)
|
||||||
|
assert.Equal("Funder 2", amb.Funder[1].Name)
|
||||||
|
assert.Equal("Organization", amb.Funder[1].Type)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNostrToAMB_IsAccessibleForFree(t *testing.T) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
tags := nostr.Tags{
|
||||||
|
{"d", "test-resource-id"},
|
||||||
|
{"isAccessibleForFree", "true"},
|
||||||
|
}
|
||||||
|
event := createTestEvent(tags)
|
||||||
|
|
||||||
|
amb, err := NostrToAMB(event)
|
||||||
|
|
||||||
|
assert.NoError(err)
|
||||||
|
assert.NotNil(amb)
|
||||||
|
|
||||||
|
assert.True(amb.IsAccessibleForFree)
|
||||||
|
|
||||||
|
// Test with "false" value
|
||||||
|
tags = nostr.Tags{
|
||||||
|
{"d", "test-resource-id"},
|
||||||
|
{"isAccessibleForFree", "false"},
|
||||||
|
}
|
||||||
|
event = createTestEvent(tags)
|
||||||
|
|
||||||
|
amb, err = NostrToAMB(event)
|
||||||
|
|
||||||
|
assert.NoError(err)
|
||||||
|
assert.NotNil(amb)
|
||||||
|
|
||||||
|
assert.False(amb.IsAccessibleForFree)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNostrToAMB_License(t *testing.T) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
tags := nostr.Tags{
|
||||||
|
{"d", "test-resource-id"},
|
||||||
|
{"license", "https://creativecommons.org/publicdomain/zero/1.0/", "CC-0"},
|
||||||
|
}
|
||||||
|
event := createTestEvent(tags)
|
||||||
|
|
||||||
|
amb, err := NostrToAMB(event)
|
||||||
|
|
||||||
|
assert.NoError(err)
|
||||||
|
assert.NotNil(amb)
|
||||||
|
|
||||||
|
assert.NotNil(amb.License)
|
||||||
|
assert.Equal("https://creativecommons.org/publicdomain/zero/1.0/", amb.License.ID)
|
||||||
|
assert.Equal("CC-0", amb.License.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNostrToAMB_ConditionsOfAccess(t *testing.T) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
tags := nostr.Tags{
|
||||||
|
{"d", "test-resource-id"},
|
||||||
|
{"conditionsOfAccess", "http://w3id.org/kim/conditionsOfAccess/no_login", "Kein Login", "de"},
|
||||||
|
}
|
||||||
|
event := createTestEvent(tags)
|
||||||
|
|
||||||
|
amb, err := NostrToAMB(event)
|
||||||
|
|
||||||
|
assert.NoError(err)
|
||||||
|
assert.NotNil(amb)
|
||||||
|
|
||||||
|
assert.NotNil(amb.ConditionsOfAccess)
|
||||||
|
assert.Equal("http://w3id.org/kim/conditionsOfAccess/no_login", amb.ConditionsOfAccess.ID)
|
||||||
|
assert.Equal("Kein Login", amb.ConditionsOfAccess.PrefLabel)
|
||||||
|
assert.Equal("de", amb.ConditionsOfAccess.InLanguage)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNostrToAMB_LearningResourceType(t *testing.T) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
tags := nostr.Tags{
|
||||||
|
{"d", "test-resource-id"},
|
||||||
|
{"learningResourceType", "http://w3id.org/openeduhub/vocabs/new_lrt/video", "Video", "de"},
|
||||||
|
{"learningResourceType", "http://w3id.org/openeduhub/vocabs/new_lrt/tutorial", "Tutorial", "en"},
|
||||||
|
}
|
||||||
|
event := createTestEvent(tags)
|
||||||
|
|
||||||
|
amb, err := NostrToAMB(event)
|
||||||
|
|
||||||
|
assert.NoError(err)
|
||||||
|
assert.NotNil(amb)
|
||||||
|
|
||||||
|
assert.Equal(2, len(amb.LearningResourceType))
|
||||||
|
|
||||||
|
assert.Equal("http://w3id.org/openeduhub/vocabs/new_lrt/video", amb.LearningResourceType[0].ID)
|
||||||
|
assert.Equal("Video", amb.LearningResourceType[0].PrefLabel)
|
||||||
|
assert.Equal("de", amb.LearningResourceType[0].InLanguage)
|
||||||
|
|
||||||
|
assert.Equal("http://w3id.org/openeduhub/vocabs/new_lrt/tutorial", amb.LearningResourceType[1].ID)
|
||||||
|
assert.Equal("Tutorial", amb.LearningResourceType[1].PrefLabel)
|
||||||
|
assert.Equal("en", amb.LearningResourceType[1].InLanguage)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNostrToAMB_Audience(t *testing.T) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
tags := nostr.Tags{
|
||||||
|
{"d", "test-resource-id"},
|
||||||
|
{"audience", "http://purl.org/dcx/lrmi-vocabs/educationalAudienceRole/student", "Schüler:in", "de"},
|
||||||
|
{"audience", "http://purl.org/dcx/lrmi-vocabs/educationalAudienceRole/teacher", "Lehrer:in", "de"},
|
||||||
|
}
|
||||||
|
event := createTestEvent(tags)
|
||||||
|
|
||||||
|
amb, err := NostrToAMB(event)
|
||||||
|
|
||||||
|
assert.NoError(err)
|
||||||
|
assert.NotNil(amb)
|
||||||
|
|
||||||
|
assert.Equal(2, len(amb.Audience))
|
||||||
|
|
||||||
|
assert.Equal("http://purl.org/dcx/lrmi-vocabs/educationalAudienceRole/student", amb.Audience[0].ID)
|
||||||
|
assert.Equal("Schüler:in", amb.Audience[0].PrefLabel)
|
||||||
|
assert.Equal("de", amb.Audience[0].InLanguage)
|
||||||
|
|
||||||
|
assert.Equal("http://purl.org/dcx/lrmi-vocabs/educationalAudienceRole/teacher", amb.Audience[1].ID)
|
||||||
|
assert.Equal("Lehrer:in", amb.Audience[1].PrefLabel)
|
||||||
|
assert.Equal("de", amb.Audience[1].InLanguage)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNostrToAMB_Teaches(t *testing.T) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
tags := nostr.Tags{
|
||||||
|
{"d", "test-resource-id"},
|
||||||
|
{"teaches", "http://awesome-skills.org/1", "Zuhören", "de"},
|
||||||
|
{"teaches", "http://awesome-skills.org/2", "Sprechen", "de"},
|
||||||
|
}
|
||||||
|
event := createTestEvent(tags)
|
||||||
|
|
||||||
|
amb, err := NostrToAMB(event)
|
||||||
|
|
||||||
|
assert.NoError(err)
|
||||||
|
assert.NotNil(amb)
|
||||||
|
|
||||||
|
assert.Equal(2, len(amb.Teaches))
|
||||||
|
|
||||||
|
assert.Equal("http://awesome-skills.org/1", amb.Teaches[0].ID)
|
||||||
|
assert.Equal("Zuhören", amb.Teaches[0].PrefLabel)
|
||||||
|
assert.Equal("de", amb.Teaches[0].InLanguage)
|
||||||
|
|
||||||
|
assert.Equal("http://awesome-skills.org/2", amb.Teaches[1].ID)
|
||||||
|
assert.Equal("Sprechen", amb.Teaches[1].PrefLabel)
|
||||||
|
assert.Equal("de", amb.Teaches[1].InLanguage)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNostrToAMB_Assesses(t *testing.T) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
tags := nostr.Tags{
|
||||||
|
{"d", "test-resource-id"},
|
||||||
|
{"assesses", "http://awesome-skills.org/1", "Hörverständnis", "de"},
|
||||||
|
{"assesses", "http://awesome-skills.org/2", "Grammatik", "de"},
|
||||||
|
}
|
||||||
|
event := createTestEvent(tags)
|
||||||
|
|
||||||
|
amb, err := NostrToAMB(event)
|
||||||
|
|
||||||
|
assert.NoError(err)
|
||||||
|
assert.NotNil(amb)
|
||||||
|
|
||||||
|
assert.Equal(2, len(amb.Assesses))
|
||||||
|
|
||||||
|
assert.Equal("http://awesome-skills.org/1", amb.Assesses[0].ID)
|
||||||
|
assert.Equal("Hörverständnis", amb.Assesses[0].PrefLabel)
|
||||||
|
assert.Equal("de", amb.Assesses[0].InLanguage)
|
||||||
|
|
||||||
|
assert.Equal("http://awesome-skills.org/2", amb.Assesses[1].ID)
|
||||||
|
assert.Equal("Grammatik", amb.Assesses[1].PrefLabel)
|
||||||
|
assert.Equal("de", amb.Assesses[1].InLanguage)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNostrToAMB_CompetencyRequired(t *testing.T) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
tags := nostr.Tags{
|
||||||
|
{"d", "test-resource-id"},
|
||||||
|
{"competencyRequired", "http://awesome-skills.org/1", "Basisvokabular", "de"},
|
||||||
|
{"competencyRequired", "http://awesome-skills.org/2", "Grundkenntnisse", "de"},
|
||||||
|
}
|
||||||
|
event := createTestEvent(tags)
|
||||||
|
|
||||||
|
amb, err := NostrToAMB(event)
|
||||||
|
|
||||||
|
assert.NoError(err)
|
||||||
|
assert.NotNil(amb)
|
||||||
|
|
||||||
|
assert.Equal(2, len(amb.CompetencyRequired))
|
||||||
|
|
||||||
|
assert.Equal("http://awesome-skills.org/1", amb.CompetencyRequired[0].ID)
|
||||||
|
assert.Equal("Basisvokabular", amb.CompetencyRequired[0].PrefLabel)
|
||||||
|
assert.Equal("de", amb.CompetencyRequired[0].InLanguage)
|
||||||
|
|
||||||
|
assert.Equal("http://awesome-skills.org/2", amb.CompetencyRequired[1].ID)
|
||||||
|
assert.Equal("Grundkenntnisse", amb.CompetencyRequired[1].PrefLabel)
|
||||||
|
assert.Equal("de", amb.CompetencyRequired[1].InLanguage)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNostrToAMB_EducationalLevel(t *testing.T) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
tags := nostr.Tags{
|
||||||
|
{"d", "test-resource-id"},
|
||||||
|
{"educationalLevel", "https://w3id.org/kim/educationalLevel/level_2", "Sekundarstufe 1", "de"},
|
||||||
|
{"educationalLevel", "https://w3id.org/kim/educationalLevel/level_3", "Sekundarstufe 2", "de"},
|
||||||
|
}
|
||||||
|
event := createTestEvent(tags)
|
||||||
|
|
||||||
|
amb, err := NostrToAMB(event)
|
||||||
|
|
||||||
|
assert.NoError(err)
|
||||||
|
assert.NotNil(amb)
|
||||||
|
|
||||||
|
assert.Equal(2, len(amb.EducationalLevel))
|
||||||
|
|
||||||
|
assert.Equal("https://w3id.org/kim/educationalLevel/level_2", amb.EducationalLevel[0].ID)
|
||||||
|
assert.Equal("Sekundarstufe 1", amb.EducationalLevel[0].PrefLabel)
|
||||||
|
assert.Equal("de", amb.EducationalLevel[0].InLanguage)
|
||||||
|
|
||||||
|
assert.Equal("https://w3id.org/kim/educationalLevel/level_3", amb.EducationalLevel[1].ID)
|
||||||
|
assert.Equal("Sekundarstufe 2", amb.EducationalLevel[1].PrefLabel)
|
||||||
|
assert.Equal("de", amb.EducationalLevel[1].InLanguage)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNostrToAMB_InteractivityType(t *testing.T) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
tags := nostr.Tags{
|
||||||
|
{"d", "test-resource-id"},
|
||||||
|
{"interactivityType", "http://purl.org/dcx/lrmi-vocabs/interactivityType/active", "aktiv", "de"},
|
||||||
|
}
|
||||||
|
event := createTestEvent(tags)
|
||||||
|
|
||||||
|
amb, err := NostrToAMB(event)
|
||||||
|
|
||||||
|
assert.NoError(err)
|
||||||
|
assert.NotNil(amb)
|
||||||
|
|
||||||
|
assert.NotNil(amb.InteractivityType)
|
||||||
|
assert.Equal("http://purl.org/dcx/lrmi-vocabs/interactivityType/active", amb.InteractivityType.ID)
|
||||||
|
assert.Equal("aktiv", amb.InteractivityType.PrefLabel)
|
||||||
|
assert.Equal("de", amb.InteractivityType.InLanguage)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNostrToAMB_IsBasedOn(t *testing.T) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
tags := nostr.Tags{
|
||||||
|
{"d", "test-resource-id"},
|
||||||
|
{"isBasedOn", "http://an-awesome-resource.org", "Französisch I"},
|
||||||
|
}
|
||||||
|
event := createTestEvent(tags)
|
||||||
|
|
||||||
|
amb, err := NostrToAMB(event)
|
||||||
|
|
||||||
|
assert.NoError(err)
|
||||||
|
assert.NotNil(amb)
|
||||||
|
|
||||||
|
assert.Equal(1, len(amb.IsBasedOn))
|
||||||
|
assert.Equal("http://an-awesome-resource.org", amb.IsBasedOn[0].ID)
|
||||||
|
assert.Equal("Französisch I", amb.IsBasedOn[0].Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNostrToAMB_IsPartOf(t *testing.T) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
tags := nostr.Tags{
|
||||||
|
{"d", "test-resource-id"},
|
||||||
|
{"isPartOf", "http://whole.org", "Whole", "PresentationDigitalDocument"},
|
||||||
|
}
|
||||||
|
event := createTestEvent(tags)
|
||||||
|
|
||||||
|
amb, err := NostrToAMB(event)
|
||||||
|
|
||||||
|
assert.NoError(err)
|
||||||
|
assert.NotNil(amb)
|
||||||
|
|
||||||
|
assert.Equal(1, len(amb.IsPartOf))
|
||||||
|
assert.Equal("http://whole.org", amb.IsPartOf[0].ID)
|
||||||
|
assert.Equal("Whole", amb.IsPartOf[0].Name)
|
||||||
|
assert.Equal("PresentationDigitalDocument", amb.IsPartOf[0].Type)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNostrToAMB_HasPart(t *testing.T) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
tags := nostr.Tags{
|
||||||
|
{"d", "test-resource-id"},
|
||||||
|
{"hasPart", "http://part1.org", "Part 1", "LearningResource"},
|
||||||
|
{"hasPart", "http://part2.org", "Part 2", "LearningResource"},
|
||||||
|
}
|
||||||
|
event := createTestEvent(tags)
|
||||||
|
|
||||||
|
amb, err := NostrToAMB(event)
|
||||||
|
|
||||||
|
assert.NoError(err)
|
||||||
|
assert.NotNil(amb)
|
||||||
|
|
||||||
|
assert.Equal(2, len(amb.HasPart))
|
||||||
|
assert.Equal("http://part1.org", amb.HasPart[0].ID)
|
||||||
|
assert.Equal("Part 1", amb.HasPart[0].Name)
|
||||||
|
assert.Equal("LearningResource", amb.HasPart[0].Type)
|
||||||
|
|
||||||
|
assert.Equal("http://part2.org", amb.HasPart[1].ID)
|
||||||
|
assert.Equal("Part 2", amb.HasPart[1].Name)
|
||||||
|
assert.Equal("LearningResource", amb.HasPart[1].Type)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNostrToAMB_Duration(t *testing.T) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
tags := nostr.Tags{
|
||||||
|
{"d", "test-resource-id"},
|
||||||
|
{"duration", "PT30M"},
|
||||||
|
}
|
||||||
|
event := createTestEvent(tags)
|
||||||
|
|
||||||
|
amb, err := NostrToAMB(event)
|
||||||
|
|
||||||
|
assert.NoError(err)
|
||||||
|
assert.NotNil(amb)
|
||||||
|
|
||||||
|
assert.Equal("PT30M", amb.Duration)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNostrToAMB_Trailer(t *testing.T) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
tags := nostr.Tags{
|
||||||
|
{"d", "test-resource-id"},
|
||||||
|
{"trailer", "https://example.com/video.mp4", "Video", "video/mp4", "10MB", "abc123", "https://example.com/embed", "1Mbps"},
|
||||||
|
}
|
||||||
|
event := createTestEvent(tags)
|
||||||
|
|
||||||
|
amb, err := NostrToAMB(event)
|
||||||
|
|
||||||
|
assert.NoError(err)
|
||||||
|
assert.NotNil(amb)
|
||||||
|
|
||||||
|
assert.Equal(1, len(amb.Trailer))
|
||||||
|
assert.Equal("https://example.com/video.mp4", amb.Trailer[0].ContentUrl)
|
||||||
|
assert.Equal("Video", amb.Trailer[0].Type)
|
||||||
|
assert.Equal("video/mp4", amb.Trailer[0].EncodingFormat)
|
||||||
|
assert.Equal("10MB", amb.Trailer[0].ContentSize)
|
||||||
|
assert.Equal("abc123", amb.Trailer[0].Sha256)
|
||||||
|
assert.Equal("https://example.com/embed", amb.Trailer[0].EmbedUrl)
|
||||||
|
assert.Equal("1Mbps", amb.Trailer[0].Bitrate)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -32,6 +32,48 @@ func (ts *TSBackend) QueryEvents(ctx context.Context, filter nostr.Filter) (chan
|
||||||
return ch, nil
|
return ch, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SearchResources searches for resources and returns both the AMB metadata and converted Nostr events
|
||||||
|
func (ts *TSBackend) SearchResources(searchStr string) ([]nostr.Event, error) {
|
||||||
|
parsedQuery := ParseSearchQuery(searchStr)
|
||||||
|
|
||||||
|
mainQuery, params, err := BuildTypesenseQuery(parsedQuery)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error building Typesense query: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// URL encode the main query
|
||||||
|
encodedQuery := url.QueryEscape(mainQuery)
|
||||||
|
|
||||||
|
// Default fields to search in
|
||||||
|
queryBy := "name,description"
|
||||||
|
|
||||||
|
// Start building the search URL
|
||||||
|
searchURL := fmt.Sprintf("%s/collections/%s/documents/search?q=%s&query_by=%s",
|
||||||
|
ts.Host, ts.CollectionName, encodedQuery, queryBy)
|
||||||
|
|
||||||
|
// Add additional parameters
|
||||||
|
for key, value := range params {
|
||||||
|
searchURL += fmt.Sprintf("&%s=%s", key, url.QueryEscape(value))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Debug information
|
||||||
|
fmt.Printf("Search URL: %s\n", searchURL)
|
||||||
|
|
||||||
|
resp, err := ts.makehttpRequest(searchURL, http.MethodGet, nil)
|
||||||
|
|
||||||
|
body, err := io.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error reading response body: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for errors
|
||||||
|
if resp.StatusCode != http.StatusOK {
|
||||||
|
return nil, fmt.Errorf("search failed with status code %d: %s", resp.StatusCode, string(body))
|
||||||
|
}
|
||||||
|
|
||||||
|
return parseSearchResponse(body)
|
||||||
|
}
|
||||||
|
|
||||||
// SearchQuery represents a parsed search query with raw terms and field filters
|
// SearchQuery represents a parsed search query with raw terms and field filters
|
||||||
type SearchQuery struct {
|
type SearchQuery struct {
|
||||||
RawTerms []string
|
RawTerms []string
|
||||||
|
|
@ -109,48 +151,6 @@ func BuildTypesenseQuery(query SearchQuery) (string, map[string]string, error) {
|
||||||
return mainQuery, params, nil
|
return mainQuery, params, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SearchResources searches for resources and returns both the AMB metadata and converted Nostr events
|
|
||||||
func (ts *TSBackend) SearchResources(searchStr string) ([]nostr.Event, error) {
|
|
||||||
parsedQuery := ParseSearchQuery(searchStr)
|
|
||||||
|
|
||||||
mainQuery, params, err := BuildTypesenseQuery(parsedQuery)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("error building Typesense query: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// URL encode the main query
|
|
||||||
encodedQuery := url.QueryEscape(mainQuery)
|
|
||||||
|
|
||||||
// Default fields to search in
|
|
||||||
queryBy := "name,description"
|
|
||||||
|
|
||||||
// Start building the search URL
|
|
||||||
searchURL := fmt.Sprintf("%s/collections/%s/documents/search?q=%s&query_by=%s",
|
|
||||||
ts.Host, ts.CollectionName, encodedQuery, queryBy)
|
|
||||||
|
|
||||||
// Add additional parameters
|
|
||||||
for key, value := range params {
|
|
||||||
searchURL += fmt.Sprintf("&%s=%s", key, url.QueryEscape(value))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Debug information
|
|
||||||
fmt.Printf("Search URL: %s\n", searchURL)
|
|
||||||
|
|
||||||
resp, err := ts.makehttpRequest(searchURL, http.MethodGet, nil)
|
|
||||||
|
|
||||||
body, err := io.ReadAll(resp.Body)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("error reading response body: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for errors
|
|
||||||
if resp.StatusCode != http.StatusOK {
|
|
||||||
return nil, fmt.Errorf("search failed with status code %d: %s", resp.StatusCode, string(body))
|
|
||||||
}
|
|
||||||
|
|
||||||
return parseSearchResponse(body)
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseSearchResponse(responseBody []byte) ([]nostr.Event, error) {
|
func parseSearchResponse(responseBody []byte) ([]nostr.Event, error) {
|
||||||
var searchResponse SearchResponse
|
var searchResponse SearchResponse
|
||||||
if err := json.Unmarshal(responseBody, &searchResponse); err != nil {
|
if err := json.Unmarshal(responseBody, &searchResponse); err != nil {
|
||||||
|
|
|
||||||
1
typesense30142/query_test.go
Normal file
1
typesense30142/query_test.go
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
// "hello learningResourceType.prefLabel:bla"
|
||||||
|
|
@ -1,10 +1,6 @@
|
||||||
package typesense30142
|
package typesense30142
|
||||||
|
|
||||||
import (
|
import "github.com/nbd-wtf/go-nostr"
|
||||||
"encoding/json"
|
|
||||||
|
|
||||||
"github.com/nbd-wtf/go-nostr"
|
|
||||||
)
|
|
||||||
|
|
||||||
// BaseEntity contains common fields used across many entity types
|
// BaseEntity contains common fields used across many entity types
|
||||||
type BaseEntity struct {
|
type BaseEntity struct {
|
||||||
|
|
@ -45,7 +41,8 @@ type Creator struct {
|
||||||
// Contributor represents someone who contributed to the content
|
// Contributor represents someone who contributed to the content
|
||||||
type Contributor struct {
|
type Contributor struct {
|
||||||
BaseEntity
|
BaseEntity
|
||||||
HonoricPrefix string `json:"honoricPrefix,omitempty"`
|
Affiliation *Affiliation `json:"affiliation,omitempty"`
|
||||||
|
HonoricPrefix string `json:"honoricPrefix,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Publisher represents the publisher of the content
|
// Publisher represents the publisher of the content
|
||||||
|
|
@ -80,23 +77,17 @@ type Audience struct {
|
||||||
|
|
||||||
// Teaches represents what the content teaches
|
// Teaches represents what the content teaches
|
||||||
type Teaches struct {
|
type Teaches struct {
|
||||||
ID string `json:"id"`
|
ControlledVocabulary
|
||||||
LabeledEntity
|
|
||||||
LanguageEntity
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assesses represents what the content assesses
|
// Assesses represents what the content assesses
|
||||||
type Assesses struct {
|
type Assesses struct {
|
||||||
ID string `json:"id"`
|
ControlledVocabulary
|
||||||
LabeledEntity
|
|
||||||
LanguageEntity
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// CompetencyRequired represents required competencies
|
// CompetencyRequired represents required competencies
|
||||||
type CompetencyRequired struct {
|
type CompetencyRequired struct {
|
||||||
ID string `json:"id"`
|
ControlledVocabulary
|
||||||
LabeledEntity
|
|
||||||
LanguageEntity
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// EducationalLevel represents the educational level
|
// EducationalLevel represents the educational level
|
||||||
|
|
@ -111,6 +102,7 @@ type InteractivityType struct {
|
||||||
|
|
||||||
// IsBasedOn represents a reference to source material
|
// IsBasedOn represents a reference to source material
|
||||||
type IsBasedOn struct {
|
type IsBasedOn struct {
|
||||||
|
ID string `json:"id"`
|
||||||
Type string `json:"type,omitempty"`
|
Type string `json:"type,omitempty"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Creator *Creator `json:"creator,omitempty"`
|
Creator *Creator `json:"creator,omitempty"`
|
||||||
|
|
@ -156,11 +148,11 @@ type NostrMetadata struct {
|
||||||
|
|
||||||
// AMBMetadata represents the full metadata structure
|
// AMBMetadata represents the full metadata structure
|
||||||
type AMBMetadata struct {
|
type AMBMetadata struct {
|
||||||
// Event ID
|
// Event ID
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
// Document ID
|
// Document ID
|
||||||
D string `json:"d"`
|
D string `json:"d"`
|
||||||
Type string `json:"type"`
|
Type []string `json:"type"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Description string `json:"description,omitempty"`
|
Description string `json:"description,omitempty"`
|
||||||
About []*About `json:"about,omitempty"`
|
About []*About `json:"about,omitempty"`
|
||||||
|
|
@ -205,124 +197,3 @@ type AMBMetadata struct {
|
||||||
// Nostr integration
|
// Nostr integration
|
||||||
NostrMetadata `json:",inline"`
|
NostrMetadata `json:",inline"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// converts a nostr event to stringified JSON
|
|
||||||
func eventToStringifiedJSON(event *nostr.Event) (string, error) {
|
|
||||||
jsonData, err := json.Marshal(event)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
jsonString := string(jsonData)
|
|
||||||
return jsonString, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// NostrToAMB converts a Nostr event of kind 30142 to AMB metadata
|
|
||||||
func NostrToAMB(event *nostr.Event) (*AMBMetadata, error) {
|
|
||||||
eventRaw, _ := eventToStringifiedJSON(event)
|
|
||||||
|
|
||||||
amb := &AMBMetadata{
|
|
||||||
Type: "LearningResource",
|
|
||||||
NostrMetadata: NostrMetadata{
|
|
||||||
EventID: event.ID,
|
|
||||||
EventPubKey: event.PubKey,
|
|
||||||
EventContent: event.Content,
|
|
||||||
EventCreatedAt: event.CreatedAt,
|
|
||||||
EventKind: event.Kind,
|
|
||||||
EventSig: event.Sig,
|
|
||||||
EventRaw: eventRaw,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, tag := range event.Tags {
|
|
||||||
if len(tag) < 2 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO alle Attribute durchgehen für das parsen
|
|
||||||
switch tag[0] {
|
|
||||||
case "d":
|
|
||||||
if len(tag) >= 2 {
|
|
||||||
amb.ID = event.ID
|
|
||||||
amb.D = tag[1]
|
|
||||||
}
|
|
||||||
case "name":
|
|
||||||
if len(tag) >= 2 {
|
|
||||||
amb.Name = tag[1]
|
|
||||||
}
|
|
||||||
case "description":
|
|
||||||
if len(tag) >= 2 {
|
|
||||||
amb.Description = tag[1]
|
|
||||||
}
|
|
||||||
case "creator":
|
|
||||||
if len(tag) >= 2 {
|
|
||||||
creator := &Creator{}
|
|
||||||
creator.Name = tag[1]
|
|
||||||
if len(tag) >= 3 {
|
|
||||||
creator.ID = tag[2]
|
|
||||||
}
|
|
||||||
if len(tag) >= 4 {
|
|
||||||
creator.Type = tag[3]
|
|
||||||
}
|
|
||||||
|
|
||||||
amb.Creator = append(amb.Creator, creator)
|
|
||||||
}
|
|
||||||
case "image":
|
|
||||||
if len(tag) >= 2 {
|
|
||||||
amb.Image = tag[1]
|
|
||||||
}
|
|
||||||
case "about":
|
|
||||||
if len(tag) >= 3 {
|
|
||||||
subject := &About{}
|
|
||||||
subject.PrefLabel = tag[1]
|
|
||||||
subject.InLanguage = tag[2]
|
|
||||||
if len(tag) >= 4 {
|
|
||||||
subject.ID = tag[3]
|
|
||||||
}
|
|
||||||
amb.About = append(amb.About, subject)
|
|
||||||
}
|
|
||||||
case "learningResourceType":
|
|
||||||
if len(tag) >= 3 {
|
|
||||||
lrt := &LearningResourceType{}
|
|
||||||
lrt.PrefLabel = tag[1]
|
|
||||||
lrt.InLanguage = tag[2]
|
|
||||||
if len(tag) >= 4 {
|
|
||||||
lrt.ID = tag[3]
|
|
||||||
}
|
|
||||||
amb.LearningResourceType = append(amb.LearningResourceType, lrt)
|
|
||||||
}
|
|
||||||
case "inLanguage":
|
|
||||||
if len(tag) >= 2 {
|
|
||||||
amb.InLanguage = append(amb.InLanguage, tag[1])
|
|
||||||
}
|
|
||||||
case "keywords":
|
|
||||||
if len(tag) >= 2 {
|
|
||||||
amb.Keywords = tag[1:]
|
|
||||||
}
|
|
||||||
case "license":
|
|
||||||
if len(tag) >= 3 {
|
|
||||||
amb.License = &License{}
|
|
||||||
amb.License.ID = tag[1]
|
|
||||||
amb.License.Name = tag[2]
|
|
||||||
|
|
||||||
}
|
|
||||||
case "datePublished":
|
|
||||||
if len(tag) >= 2 {
|
|
||||||
amb.DatePublished = tag[1]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return amb, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// converts a stringified JSON event to a nostr.Event
|
|
||||||
func StringifiedJSONToNostrEvent(jsonString string) (nostr.Event, error) {
|
|
||||||
var event nostr.Event
|
|
||||||
err := json.Unmarshal([]byte(jsonString), &event)
|
|
||||||
if err != nil {
|
|
||||||
return nostr.Event{}, err
|
|
||||||
}
|
|
||||||
return event, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue