probo/pkg/store/quiz.go

145 lines
3 KiB
Go
Raw Permalink Normal View History

2023-11-13 21:01:12 +01:00
package store
import (
"fmt"
"strings"
2024-02-06 09:03:57 +01:00
"git.andreafazzi.eu/andrea/probo/pkg/models"
2023-11-13 21:01:12 +01:00
)
type ErrQuizAlreadyPresent struct {
hash string
}
func (e *ErrQuizAlreadyPresent) Error() string {
return fmt.Sprintf("Quiz with hash %v is already present in the store.", e.hash)
}
type QuizStore struct {
// Memory store for quizzes. It satisfies FilterStorer
// interface.
*FilterStore[*models.Quiz]
questions *Store[*models.Question]
answers *Store[*models.Answer]
}
func NewQuizStore() *QuizStore {
store := new(QuizStore)
store.questions = NewStore[*models.Question]()
store.answers = NewStore[*models.Answer]()
store.FilterStore = NewFilterStore[*models.Quiz]()
return store
}
func (s *QuizStore) Create(quiz *models.Quiz) (*models.Quiz, error) {
if hash := quiz.GetHash(); hash != "" {
q, ok := s.hashes[hash]
if ok {
return q, &ErrQuizAlreadyPresent{hash}
}
}
question, err := s.questions.Create(quiz.Question)
if err != nil {
return nil, err
}
answers := make([]*models.Answer, 0)
for _, a := range quiz.Answers {
storedAnswer, err := s.answers.Create(a)
if err != nil {
return nil, err
}
answers = append(answers, storedAnswer)
}
2024-04-12 13:39:49 +02:00
tags := make([]string, 0)
2023-11-13 21:01:12 +01:00
q, err := s.Store.Create(&models.Quiz{
Meta: quiz.Meta,
Question: parseTags[*models.Question](&tags, question)[0],
Answers: parseTags[*models.Answer](&tags, answers...),
Correct: answers[quiz.CorrectPos],
CorrectPos: quiz.CorrectPos,
Tags: tags,
})
if err != nil {
return nil, err
}
return q, nil
}
func (s *QuizStore) Update(quiz *models.Quiz, id string) (*models.Quiz, error) {
_, err := s.Read(id)
if err != nil {
return quiz, err
}
question, err := s.questions.Create(quiz.Question)
if err != nil {
return nil, err
}
answers := make([]*models.Answer, 0)
for _, a := range quiz.Answers {
storedAnswer, err := s.answers.Create(a)
if err != nil {
return nil, err
}
answers = append(answers, storedAnswer)
}
2024-04-12 13:39:49 +02:00
tags := make([]string, 0)
2023-11-13 21:01:12 +01:00
q, err := s.Store.Update(&models.Quiz{
Question: parseTags[*models.Question](&tags, question)[0],
Answers: parseTags[*models.Answer](&tags, answers...),
Correct: answers[quiz.CorrectPos],
CorrectPos: quiz.CorrectPos,
Tags: tags,
}, id)
if err != nil {
return nil, err
}
return q, nil
}
2024-04-12 13:39:49 +02:00
func parseTags[T fmt.Stringer](tags *[]string, entities ...T) []T {
2023-11-13 21:01:12 +01:00
for _, entity := range entities {
// Trim the following chars
trimChars := "*:.,/\\@()[]{}<>"
// Split the text into words
words := strings.Fields(entity.String())
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 {
2024-04-12 13:39:49 +02:00
if tag == word {
2023-11-13 21:01:12 +01:00
exists = true
break
}
}
// If the tag does not exist in the tags slice, add it
if !exists {
2024-04-12 13:39:49 +02:00
*tags = append(*tags, strings.TrimRight(word, trimChars))
2023-11-13 21:01:12 +01:00
}
}
}
}
return entities
}