Tags are a string slice

This commit is contained in:
andrea 2024-04-12 13:39:49 +02:00
parent e5f6d3ffaf
commit 2c854d4f8b
7 changed files with 50 additions and 110 deletions

View file

@ -41,6 +41,7 @@ Question text with #tag1 #tag2 (3).
{Text: "Answer 4"}, {Text: "Answer 4"},
}, },
CorrectPos: 0, CorrectPos: 0,
Tags: []string{"#tag1", "#tag2"},
} }
q := new(Quiz) q := new(Quiz)

View file

@ -14,12 +14,12 @@ type AttributeList map[string]string
type Participant struct { type Participant struct {
Meta Meta
Firstname string Firstname string `json:"firstname" csv:"firstname"`
Lastname string Lastname string `json:"lastname" csv:"lastname"`
Token string Token string `json:"token" csv:"token"`
Attributes AttributeList `csv:"Attributes"` Attributes AttributeList `csv:"attributes"`
} }
func (p *Participant) String() string { func (p *Participant) String() string {

View file

@ -15,11 +15,11 @@ type Quiz struct {
Meta Meta
Hash string `json:"hash"` Hash string `json:"hash"`
Question *Question `json:"question" gorm:"foreignKey:ID"` Question *Question `json:"question"`
Answers []*Answer `json:"answers" gorm:"many2many:quiz_answers"` Answers []*Answer `json:"answers"`
Tags []*Tag `json:"tags" yaml:"-" gorm:"-"` Tags []string `json:"tags" yaml:"-"`
Correct *Answer `json:"correct" gorm:"foreignKey:ID"` Correct *Answer `json:"correct"`
CorrectPos uint `gorm:"-"` // Position of the correct answer during quiz creation CorrectPos uint // Position of the correct answer during quiz creation
Type int `json:"type"` Type int `json:"type"`
} }
@ -33,6 +33,7 @@ func MarkdownToQuiz(quiz *Quiz, markdown string) error {
questionText := "" questionText := ""
answers := []*Answer{} answers := []*Answer{}
tags := make([]string, 0)
for _, line := range lines { for _, line := range lines {
if strings.HasPrefix(line, "*") { if strings.HasPrefix(line, "*") {
@ -45,6 +46,8 @@ func MarkdownToQuiz(quiz *Quiz, markdown string) error {
} }
questionText += line questionText += line
} }
parseTags(&tags, line)
} }
questionText = strings.TrimRight(questionText, "\n") questionText = strings.TrimRight(questionText, "\n")
@ -61,8 +64,7 @@ func MarkdownToQuiz(quiz *Quiz, markdown string) error {
quiz.Question = question quiz.Question = question
quiz.Answers = answers quiz.Answers = answers
quiz.Tags = tags
//quiz = &Quiz{Question: question, Answers: answers, CorrectPos: 0}
if meta != nil { if meta != nil {
quiz.Meta = *meta quiz.Meta = *meta
@ -201,3 +203,30 @@ func readLine(reader *strings.Reader) (string, error) {
return sb.String(), nil return sb.String(), nil
} }
func parseTags(tags *[]string, text string) {
// Trim the following chars
trimChars := "*:.,/\\@()[]{}<>"
// Split the text into words
words := strings.Fields(text)
for _, word := range words {
// If the word starts with '#', it is considered as a tag
if strings.HasPrefix(word, "#") {
// Check if the tag already exists in the tags slice
exists := false
for _, tag := range *tags {
if tag == word {
exists = true
break
}
}
// If the tag does not exist in the tags slice, add it
if !exists {
*tags = append(*tags, strings.TrimRight(word, trimChars))
}
}
}
}

View file

@ -1,14 +1,5 @@
package models package models
import (
"time"
"gorm.io/gorm"
)
type Tag struct { type Tag struct {
CreatedAt time.Time Name string `json:"name"`
UpdatedAt time.Time
DeletedAt gorm.DeletedAt `gorm:"index"`
Name string `json:"name" gorm:"primaryKey"`
} }

View file

@ -58,7 +58,7 @@ func (s *QuizStore) Create(quiz *models.Quiz) (*models.Quiz, error) {
answers = append(answers, storedAnswer) answers = append(answers, storedAnswer)
} }
tags := make([]*models.Tag, 0) tags := make([]string, 0)
q, err := s.Store.Create(&models.Quiz{ q, err := s.Store.Create(&models.Quiz{
Meta: quiz.Meta, Meta: quiz.Meta,
@ -96,7 +96,7 @@ func (s *QuizStore) Update(quiz *models.Quiz, id string) (*models.Quiz, error) {
answers = append(answers, storedAnswer) answers = append(answers, storedAnswer)
} }
tags := make([]*models.Tag, 0) tags := make([]string, 0)
q, err := s.Store.Update(&models.Quiz{ q, err := s.Store.Update(&models.Quiz{
Question: parseTags[*models.Question](&tags, question)[0], Question: parseTags[*models.Question](&tags, question)[0],
@ -112,49 +112,7 @@ func (s *QuizStore) Update(quiz *models.Quiz, id string) (*models.Quiz, error) {
return q, nil return q, nil
} }
func (s *QuizStore) FilterInCollection(collection *models.Collection, filter map[string]string) []*models.Quiz { func parseTags[T fmt.Stringer](tags *[]string, entities ...T) []T {
quizzes := s.ReadAll()
if filter == nil {
return quizzes
}
tagsValue := filter["tags"]
if tagsValue == "" || len(tagsValue) == 0 {
return quizzes
}
fTags := strings.Split(tagsValue, ",")
filteredQuizzes := s.Filter(quizzes, func(q *models.Quiz) bool {
count := 0
for _, qTag := range q.Tags {
if s.isTagInFilter(qTag, fTags) {
count++
}
}
if count == len(fTags) {
return true
}
return false
})
collection.Quizzes = filteredQuizzes
return collection.Quizzes
}
func (s *QuizStore) isTagInFilter(tag *models.Tag, fTags []string) bool {
for _, t := range fTags {
if tag.Name == strings.TrimSpace(t) {
return true
}
}
return false
}
func parseTags[T fmt.Stringer](tags *[]*models.Tag, entities ...T) []T {
for _, entity := range entities { for _, entity := range entities {
// Trim the following chars // Trim the following chars
trimChars := "*:.,/\\@()[]{}<>" trimChars := "*:.,/\\@()[]{}<>"
@ -168,7 +126,7 @@ func parseTags[T fmt.Stringer](tags *[]*models.Tag, entities ...T) []T {
// Check if the tag already exists in the tags slice // Check if the tag already exists in the tags slice
exists := false exists := false
for _, tag := range *tags { for _, tag := range *tags {
if tag.Name == word { if tag == word {
exists = true exists = true
break break
} }
@ -176,7 +134,7 @@ func parseTags[T fmt.Stringer](tags *[]*models.Tag, entities ...T) []T {
// If the tag does not exist in the tags slice, add it // If the tag does not exist in the tags slice, add it
if !exists { if !exists {
*tags = append(*tags, &models.Tag{Name: strings.TrimRight(word, trimChars)}) *tags = append(*tags, strings.TrimRight(word, trimChars))
} }
} }
} }

View file

@ -183,45 +183,6 @@ func (t *quizTestSuite) TestDeleteQuiz() {
} }
} }
func (t *quizTestSuite) TestFilter() {
store := NewQuizStore()
quiz_1, _ := store.Create(
&models.Quiz{
Question: &models.Question{Text: "Question text with #tag1."},
Answers: []*models.Answer{
{Text: "Answer 1"},
{Text: "Answer 2 with #tag2"},
{Text: "Answer 3"},
{Text: "Answer 4"},
},
CorrectPos: 0,
})
quiz_2, _ := store.Create(
&models.Quiz{
Question: &models.Question{Text: "Question text with #tag3."},
Answers: []*models.Answer{
{Text: "Answer 1"},
{Text: "Answer 2 with #tag4"},
{Text: "Answer 3"},
{Text: "Answer 4"},
},
CorrectPos: 0,
})
quizzes := store.Filter([]*models.Quiz{quiz_1, quiz_2}, func(q *models.Quiz) bool {
for _, t := range q.Tags {
if t.Name == "#tag1" {
return true
}
}
return false
})
t.Equal(1, len(quizzes))
}
func (t *quizTestSuite) TestParseTextForTags() { func (t *quizTestSuite) TestParseTextForTags() {
store := NewQuizStore() store := NewQuizStore()
@ -244,8 +205,8 @@ func (t *quizTestSuite) TestParseTextForTags() {
t.Nil(err, "Quiz should be found in the store.") t.Nil(err, "Quiz should be found in the store.")
t.Equal(2, len(storedQuiz.Tags)) t.Equal(2, len(storedQuiz.Tags))
if !t.Failed() { if !t.Failed() {
t.Equal("#tag1", storedQuiz.Tags[0].Name) t.Equal("#tag1", storedQuiz.Tags[0])
t.Equal("#tag2", storedQuiz.Tags[1].Name) t.Equal("#tag2", storedQuiz.Tags[1])
} }
} }

View file

@ -1,4 +1,4 @@
Lastname,Firstname,Token,Attributes lastname,firstname,token,attributes
CABRERA,GAIA,982998,class:1 D LIN CABRERA,GAIA,982998,class:1 D LIN
VERDI,ANNA,868424,class:1 D LIN VERDI,ANNA,868424,class:1 D LIN
BIANCHI,ELENA,795233,class:1 D LIN BIANCHI,ELENA,795233,class:1 D LIN

1 Lastname lastname Firstname firstname Token token Attributes attributes
2 CABRERA CABRERA GAIA GAIA 982998 982998 class:1 D LIN class:1 D LIN
3 VERDI VERDI ANNA ANNA 868424 868424 class:1 D LIN class:1 D LIN
4 BIANCHI BIANCHI ELENA ELENA 795233 795233 class:1 D LIN class:1 D LIN