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 (
|
||||
github.com/fiatjaf/eventstore v0.16.2
|
||||
github.com/nbd-wtf/go-nostr v0.51.8
|
||||
github.com/stretchr/testify v1.10.0
|
||||
)
|
||||
|
||||
require (
|
||||
|
|
@ -15,6 +16,7 @@ require (
|
|||
github.com/bytedance/sonic/loader v0.2.4 // indirect
|
||||
github.com/cloudwego/base64x v0.1.5 // 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/dcrec/secp256k1/v4 v4.4.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/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // 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/tidwall/gjson v1.18.0 // 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/exp v0.0.0-20250305212735-054e65f0b394 // 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/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
|
||||
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/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
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
|
||||
}
|
||||
|
||||
// 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
|
||||
type SearchQuery struct {
|
||||
RawTerms []string
|
||||
|
|
@ -109,48 +151,6 @@ func BuildTypesenseQuery(query SearchQuery) (string, map[string]string, error) {
|
|||
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) {
|
||||
var searchResponse SearchResponse
|
||||
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
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/nbd-wtf/go-nostr"
|
||||
)
|
||||
import "github.com/nbd-wtf/go-nostr"
|
||||
|
||||
// BaseEntity contains common fields used across many entity types
|
||||
type BaseEntity struct {
|
||||
|
|
@ -45,6 +41,7 @@ type Creator struct {
|
|||
// Contributor represents someone who contributed to the content
|
||||
type Contributor struct {
|
||||
BaseEntity
|
||||
Affiliation *Affiliation `json:"affiliation,omitempty"`
|
||||
HonoricPrefix string `json:"honoricPrefix,omitempty"`
|
||||
}
|
||||
|
||||
|
|
@ -80,23 +77,17 @@ type Audience struct {
|
|||
|
||||
// Teaches represents what the content teaches
|
||||
type Teaches struct {
|
||||
ID string `json:"id"`
|
||||
LabeledEntity
|
||||
LanguageEntity
|
||||
ControlledVocabulary
|
||||
}
|
||||
|
||||
// Assesses represents what the content assesses
|
||||
type Assesses struct {
|
||||
ID string `json:"id"`
|
||||
LabeledEntity
|
||||
LanguageEntity
|
||||
ControlledVocabulary
|
||||
}
|
||||
|
||||
// CompetencyRequired represents required competencies
|
||||
type CompetencyRequired struct {
|
||||
ID string `json:"id"`
|
||||
LabeledEntity
|
||||
LanguageEntity
|
||||
ControlledVocabulary
|
||||
}
|
||||
|
||||
// EducationalLevel represents the educational level
|
||||
|
|
@ -111,6 +102,7 @@ type InteractivityType struct {
|
|||
|
||||
// IsBasedOn represents a reference to source material
|
||||
type IsBasedOn struct {
|
||||
ID string `json:"id"`
|
||||
Type string `json:"type,omitempty"`
|
||||
Name string `json:"name"`
|
||||
Creator *Creator `json:"creator,omitempty"`
|
||||
|
|
@ -160,7 +152,7 @@ type AMBMetadata struct {
|
|||
ID string `json:"id"`
|
||||
// Document ID
|
||||
D string `json:"d"`
|
||||
Type string `json:"type"`
|
||||
Type []string `json:"type"`
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description,omitempty"`
|
||||
About []*About `json:"about,omitempty"`
|
||||
|
|
@ -205,124 +197,3 @@ type AMBMetadata struct {
|
|||
// Nostr integration
|
||||
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