Tags are a string slice
This commit is contained in:
parent
e5f6d3ffaf
commit
2c854d4f8b
7 changed files with 50 additions and 110 deletions
|
@ -41,6 +41,7 @@ Question text with #tag1 #tag2 (3).
|
|||
{Text: "Answer 4"},
|
||||
},
|
||||
CorrectPos: 0,
|
||||
Tags: []string{"#tag1", "#tag2"},
|
||||
}
|
||||
|
||||
q := new(Quiz)
|
||||
|
|
|
@ -14,12 +14,12 @@ type AttributeList map[string]string
|
|||
type Participant struct {
|
||||
Meta
|
||||
|
||||
Firstname string
|
||||
Lastname string
|
||||
Firstname string `json:"firstname" csv:"firstname"`
|
||||
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 {
|
||||
|
|
|
@ -15,11 +15,11 @@ type Quiz struct {
|
|||
Meta
|
||||
|
||||
Hash string `json:"hash"`
|
||||
Question *Question `json:"question" gorm:"foreignKey:ID"`
|
||||
Answers []*Answer `json:"answers" gorm:"many2many:quiz_answers"`
|
||||
Tags []*Tag `json:"tags" yaml:"-" gorm:"-"`
|
||||
Correct *Answer `json:"correct" gorm:"foreignKey:ID"`
|
||||
CorrectPos uint `gorm:"-"` // Position of the correct answer during quiz creation
|
||||
Question *Question `json:"question"`
|
||||
Answers []*Answer `json:"answers"`
|
||||
Tags []string `json:"tags" yaml:"-"`
|
||||
Correct *Answer `json:"correct"`
|
||||
CorrectPos uint // Position of the correct answer during quiz creation
|
||||
Type int `json:"type"`
|
||||
}
|
||||
|
||||
|
@ -33,6 +33,7 @@ func MarkdownToQuiz(quiz *Quiz, markdown string) error {
|
|||
|
||||
questionText := ""
|
||||
answers := []*Answer{}
|
||||
tags := make([]string, 0)
|
||||
|
||||
for _, line := range lines {
|
||||
if strings.HasPrefix(line, "*") {
|
||||
|
@ -45,6 +46,8 @@ func MarkdownToQuiz(quiz *Quiz, markdown string) error {
|
|||
}
|
||||
questionText += line
|
||||
}
|
||||
|
||||
parseTags(&tags, line)
|
||||
}
|
||||
|
||||
questionText = strings.TrimRight(questionText, "\n")
|
||||
|
@ -61,8 +64,7 @@ func MarkdownToQuiz(quiz *Quiz, markdown string) error {
|
|||
|
||||
quiz.Question = question
|
||||
quiz.Answers = answers
|
||||
|
||||
//quiz = &Quiz{Question: question, Answers: answers, CorrectPos: 0}
|
||||
quiz.Tags = tags
|
||||
|
||||
if meta != nil {
|
||||
quiz.Meta = *meta
|
||||
|
@ -201,3 +203,30 @@ func readLine(reader *strings.Reader) (string, error) {
|
|||
|
||||
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))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,14 +1,5 @@
|
|||
package models
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type Tag struct {
|
||||
CreatedAt time.Time
|
||||
UpdatedAt time.Time
|
||||
DeletedAt gorm.DeletedAt `gorm:"index"`
|
||||
Name string `json:"name" gorm:"primaryKey"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@ func (s *QuizStore) Create(quiz *models.Quiz) (*models.Quiz, error) {
|
|||
answers = append(answers, storedAnswer)
|
||||
}
|
||||
|
||||
tags := make([]*models.Tag, 0)
|
||||
tags := make([]string, 0)
|
||||
|
||||
q, err := s.Store.Create(&models.Quiz{
|
||||
Meta: quiz.Meta,
|
||||
|
@ -96,7 +96,7 @@ func (s *QuizStore) Update(quiz *models.Quiz, id string) (*models.Quiz, error) {
|
|||
answers = append(answers, storedAnswer)
|
||||
}
|
||||
|
||||
tags := make([]*models.Tag, 0)
|
||||
tags := make([]string, 0)
|
||||
|
||||
q, err := s.Store.Update(&models.Quiz{
|
||||
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
|
||||
}
|
||||
|
||||
func (s *QuizStore) FilterInCollection(collection *models.Collection, filter map[string]string) []*models.Quiz {
|
||||
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 {
|
||||
func parseTags[T fmt.Stringer](tags *[]string, entities ...T) []T {
|
||||
for _, entity := range entities {
|
||||
// Trim the following chars
|
||||
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
|
||||
exists := false
|
||||
for _, tag := range *tags {
|
||||
if tag.Name == word {
|
||||
if tag == word {
|
||||
exists = true
|
||||
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 !exists {
|
||||
*tags = append(*tags, &models.Tag{Name: strings.TrimRight(word, trimChars)})
|
||||
*tags = append(*tags, strings.TrimRight(word, trimChars))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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() {
|
||||
store := NewQuizStore()
|
||||
|
||||
|
@ -244,8 +205,8 @@ func (t *quizTestSuite) TestParseTextForTags() {
|
|||
t.Nil(err, "Quiz should be found in the store.")
|
||||
t.Equal(2, len(storedQuiz.Tags))
|
||||
if !t.Failed() {
|
||||
t.Equal("#tag1", storedQuiz.Tags[0].Name)
|
||||
t.Equal("#tag2", storedQuiz.Tags[1].Name)
|
||||
t.Equal("#tag1", storedQuiz.Tags[0])
|
||||
t.Equal("#tag2", storedQuiz.Tags[1])
|
||||
}
|
||||
}
|
||||
|
||||
|
|
2
pkg/store/testdata/participants.csv
vendored
2
pkg/store/testdata/participants.csv
vendored
|
@ -1,4 +1,4 @@
|
|||
Lastname,Firstname,Token,Attributes
|
||||
lastname,firstname,token,attributes
|
||||
CABRERA,GAIA,982998,class:1 D LIN
|
||||
VERDI,ANNA,868424,class:1 D LIN
|
||||
BIANCHI,ELENA,795233,class:1 D LIN
|
||||
|
|
|
Loading…
Reference in a new issue