Tags
This commit is contained in:
parent
4f3ecda14c
commit
4da6162dd4
7 changed files with 138 additions and 9 deletions
|
@ -5,4 +5,5 @@ import "time"
|
|||
type Meta struct {
|
||||
ID string `json:"id" yaml:"id"`
|
||||
CreatedAt time.Time `json:"created_at" yaml:"created_at"`
|
||||
Tags []*Tag `json:"tags" yaml:"tags"`
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@ package models
|
|||
|
||||
type Quiz struct {
|
||||
Meta
|
||||
// ID string `json:"id"`
|
||||
Hash string `json:"hash"`
|
||||
Question *Question `json:"question"`
|
||||
Answers []*Answer `json:"answers"`
|
||||
|
|
5
models/tag.go
Normal file
5
models/tag.go
Normal file
|
@ -0,0 +1,5 @@
|
|||
package models
|
||||
|
||||
type Tag struct {
|
||||
Name string `json:"name"`
|
||||
}
|
|
@ -84,7 +84,6 @@ func (s *FileProboCollectorStore) Reindex() error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
q, err := s.memoryStore.CreateQuiz(&client.CreateUpdateQuizRequest{
|
||||
Quiz: quiz,
|
||||
Meta: meta,
|
||||
|
@ -217,6 +216,67 @@ func MarkdownFromQuiz(quiz *models.Quiz) (string, error) {
|
|||
return markdown, nil
|
||||
}
|
||||
|
||||
// func QuizFromMarkdown(markdown string) (*client.Quiz, *models.Meta, error) {
|
||||
// meta, remainingMarkdown, err := parseMetaHeaderFromMarkdown(markdown)
|
||||
// if err != nil {
|
||||
// return nil, nil, err
|
||||
// }
|
||||
|
||||
// if meta == nil {
|
||||
// meta = new(models.Meta)
|
||||
// if meta.Tags == nil {
|
||||
// meta.Tags = make([]*models.Tag, 0)
|
||||
// }
|
||||
// } else if meta.Tags == nil {
|
||||
// meta.Tags = make([]*models.Tag, 0)
|
||||
// }
|
||||
|
||||
// lines := strings.Split(remainingMarkdown, "\n")
|
||||
|
||||
// questionText := ""
|
||||
// answers := []*client.Answer{}
|
||||
|
||||
// for _, line := range lines {
|
||||
// // Check if the line contains a tag
|
||||
// if strings.Contains(line, "#") {
|
||||
// // Split the line into words
|
||||
// words := strings.Split(line, " ")
|
||||
// for _, word := range words {
|
||||
// // If the word starts with '#', add it to the tags
|
||||
// if strings.HasPrefix(word, "#") {
|
||||
// meta.Tags = append(meta.Tags, &models.Tag{Name: word[1:]})
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// if strings.HasPrefix(line, "*") {
|
||||
// answerText := strings.TrimPrefix(line, "* ")
|
||||
// correct := len(answers) == 0
|
||||
// answer := &client.Answer{Text: answerText, Correct: correct}
|
||||
// answers = append(answers, answer)
|
||||
// } else {
|
||||
// if questionText != "" {
|
||||
// questionText += "\n"
|
||||
// }
|
||||
// questionText += line
|
||||
// }
|
||||
// }
|
||||
|
||||
// questionText = strings.TrimRight(questionText, "\n")
|
||||
|
||||
// if questionText == "" {
|
||||
// return nil, nil, fmt.Errorf("Question text should not be empty.")
|
||||
// }
|
||||
|
||||
// if len(answers) < 2 {
|
||||
// return nil, nil, fmt.Errorf("Number of answers should be at least 2 but parsed answers are %d.", len(answers))
|
||||
// }
|
||||
// question := &client.Question{Text: questionText}
|
||||
// quiz := &client.Quiz{Question: question, Answers: answers}
|
||||
|
||||
// return quiz, meta, nil
|
||||
// }
|
||||
|
||||
func QuizFromMarkdown(markdown string) (*client.Quiz, *models.Meta, error) {
|
||||
meta, remainingMarkdown, err := parseMetaHeaderFromMarkdown(markdown)
|
||||
if err != nil {
|
||||
|
@ -275,7 +335,6 @@ func (s *FileProboCollectorStore) WriteMetaHeaderToFile(filename string, meta *m
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if readMeta == nil {
|
||||
_, err := writeMetaHeader(path.Join(s.Dir, filename), meta)
|
||||
if err != nil {
|
||||
|
|
|
@ -29,7 +29,7 @@ func (t *testSuite) TestQuizFromMarkdown() {
|
|||
|
||||
Question text (2).
|
||||
|
||||
Question text (3).
|
||||
Question text with #tag1 #tag2 (3).
|
||||
|
||||
* Answer 1
|
||||
* Answer 2
|
||||
|
@ -37,7 +37,7 @@ Question text (3).
|
|||
* Answer 4`
|
||||
|
||||
expectedQuiz := &client.Quiz{
|
||||
Question: &client.Question{Text: "Question text (1).\n\nQuestion text (2).\n\nQuestion text (3)."},
|
||||
Question: &client.Question{Text: "Question text (1).\n\nQuestion text (2).\n\nQuestion text with #tag1 #tag2 (3)."},
|
||||
Answers: []*client.Answer{
|
||||
{Text: "Answer 1", Correct: true},
|
||||
{Text: "Answer 2", Correct: false},
|
||||
|
@ -51,6 +51,7 @@ Question text (3).
|
|||
|
||||
if !t.Failed() {
|
||||
t.True(reflect.DeepEqual(quiz, expectedQuiz), fmt.Sprintf("Expected %+v, got %+v", expectedQuiz, quiz))
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -205,7 +206,7 @@ func (t *testSuite) TestUpdateQuiz() {
|
|||
|
||||
if !t.Failed() {
|
||||
clientQuiz := &client.Quiz{
|
||||
Question: &client.Question{Text: "Updated question text."},
|
||||
Question: &client.Question{Text: "Updated question text with #tag."},
|
||||
Answers: []*client.Answer{
|
||||
{Text: "Answer 1", Correct: true},
|
||||
{Text: "Answer 2", Correct: false},
|
||||
|
@ -221,6 +222,7 @@ func (t *testSuite) TestUpdateQuiz() {
|
|||
|
||||
t.Nil(err, fmt.Sprintf("Quiz should be updated without errors: %v", err))
|
||||
t.Equal(updatedQuiz.ID, quiz.ID, fmt.Sprintf("IDs should remain the same after an update: updated ID %v original ID %v", updatedQuiz.ID, quiz.ID))
|
||||
t.True(len(updatedQuiz.Tags) == 1, "Length of tags array should be 1")
|
||||
|
||||
if !t.Failed() {
|
||||
path, err := store.GetPath(updatedQuiz)
|
||||
|
@ -265,7 +267,7 @@ func (t *testSuite) TestWriteMetaHeaderToFile() {
|
|||
|
||||
if !t.Failed() {
|
||||
meta, err := store.ReadMetaHeaderFromFile("quiz_5.md")
|
||||
t.True(err == nil)
|
||||
t.True(err == nil, fmt.Sprintf("Reading the header returns the following error: %v", err))
|
||||
if !t.Failed() {
|
||||
t.True(meta != nil, "Meta header should not be nil")
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ package memory
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"git.andreafazzi.eu/andrea/probo/client"
|
||||
|
@ -153,6 +154,36 @@ func (s *MemoryProboCollectorStore) CalculateQuizHash(quiz *client.Quiz) string
|
|||
return hashes[len(hashes)-1]
|
||||
}
|
||||
|
||||
func (s *MemoryProboCollectorStore) parseTextForTags(text string, tags *[]*models.Tag) 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.Name == word {
|
||||
exists = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// If the tag does not exist in the tags slice, add it
|
||||
if !exists {
|
||||
*tags = append(*tags, &models.Tag{Name: strings.TrimRight(word, trimChars)})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return text
|
||||
}
|
||||
|
||||
func (s *MemoryProboCollectorStore) createOrUpdateQuiz(r *client.CreateUpdateQuizRequest, id string) (*models.Quiz, bool, error) {
|
||||
hashes := s.hasher.QuizHashes(r.Quiz)
|
||||
quizHash := hashes[len(hashes)-1]
|
||||
|
@ -171,6 +202,8 @@ func (s *MemoryProboCollectorStore) createOrUpdateQuiz(r *client.CreateUpdateQui
|
|||
if r.Meta != nil {
|
||||
if r.Meta.ID != "" {
|
||||
id = r.Meta.ID
|
||||
} else {
|
||||
id = uuid.New().String()
|
||||
}
|
||||
} else {
|
||||
id = uuid.New().String()
|
||||
|
@ -178,12 +211,16 @@ func (s *MemoryProboCollectorStore) createOrUpdateQuiz(r *client.CreateUpdateQui
|
|||
quiz = new(models.Quiz)
|
||||
}
|
||||
|
||||
if quiz.Tags == nil {
|
||||
quiz.Tags = make([]*models.Tag, 0)
|
||||
}
|
||||
|
||||
questionHash := hashes[0]
|
||||
q := s.getQuestionFromHash(questionHash)
|
||||
if q == nil { // if the question is not in the store then we should add it
|
||||
q = s.createQuestionFromHash(questionHash, &models.Question{
|
||||
ID: uuid.New().String(),
|
||||
Text: r.Quiz.Question.Text,
|
||||
Text: s.parseTextForTags(r.Quiz.Question.Text, &quiz.Tags),
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -199,7 +236,7 @@ func (s *MemoryProboCollectorStore) createOrUpdateQuiz(r *client.CreateUpdateQui
|
|||
if a == nil { // if the answer is not in the store add it
|
||||
a = s.createAnswerFromHash(answerHash, &models.Answer{
|
||||
ID: uuid.New().String(),
|
||||
Text: answer.Text,
|
||||
Text: s.parseTextForTags(answer.Text, &quiz.Tags),
|
||||
})
|
||||
}
|
||||
if answer.Correct {
|
||||
|
|
|
@ -45,6 +45,32 @@ func (t *testSuite) TestReadQuizByHash() {
|
|||
|
||||
}
|
||||
|
||||
func (t *testSuite) TestParseTextForTags() {
|
||||
store := NewMemoryProboCollectorStore(
|
||||
sha256.NewDefault256Hasher(sha256.DefaultSHA256HashingFn),
|
||||
)
|
||||
quiz, _ := store.CreateQuiz(
|
||||
&client.CreateUpdateQuizRequest{
|
||||
Quiz: &client.Quiz{
|
||||
Question: &client.Question{Text: "Newly created question text with #tag1."},
|
||||
Answers: []*client.Answer{
|
||||
{Text: "Answer 1", Correct: true},
|
||||
{Text: "Answer 2 with #tag2", Correct: false},
|
||||
{Text: "Answer 3", Correct: false},
|
||||
{Text: "Answer 4", Correct: false},
|
||||
},
|
||||
},
|
||||
})
|
||||
quizFromMemory, err := store.ReadQuizByHash(quiz.Hash)
|
||||
t.Nil(err, "Quiz should be found in the store")
|
||||
if !t.Failed() {
|
||||
t.True(len(quizFromMemory.Tags) == 2, "Two tags should be present.")
|
||||
t.Equal("#tag1", quizFromMemory.Tags[0].Name)
|
||||
t.Equal("#tag2", quizFromMemory.Tags[1].Name)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (t *testSuite) TestUpdateQuiz() {
|
||||
store := NewMemoryProboCollectorStore(
|
||||
sha256.NewDefault256Hasher(sha256.DefaultSHA256HashingFn),
|
||||
|
|
Loading…
Reference in a new issue