diff --git a/server/data/sessions/session_24e5a5f5-8293-4e13-a825-656117db4d5b.json b/server/data/sessions/session_24e5a5f5-8293-4e13-a825-656117db4d5b.json new file mode 100644 index 0000000..500d4aa --- /dev/null +++ b/server/data/sessions/session_24e5a5f5-8293-4e13-a825-656117db4d5b.json @@ -0,0 +1 @@ +{"id":"24e5a5f5-8293-4e13-a825-656117db4d5b","created_at":"2023-12-12T09:00:57.405268351+01:00","updated_at":"2023-12-12T09:20:41.050431537+01:00","Name":"My session","Exams":{"111222":{"id":"c0140b05-a843-4599-b405-3517357bd2b5","created_at":"2023-12-12T09:00:57.402306603+01:00","updated_at":"2023-12-12T09:00:57.402306722+01:00","Participant":{"id":"1234","created_at":"2023-12-05T21:11:37.566330708+01:00","updated_at":"2023-12-12T09:00:57.402100526+01:00","Firstname":"Giuly","Lastname":"Mon Amour","Token":"111222","Attributes":{"class":"1 D LIN"}},"Quizzes":[{"id":"908bb025-6370-4273-8448-8470f9336f26","created_at":"2023-12-05T21:22:06.322398595+01:00","updated_at":"2023-12-12T09:00:57.40230252+01:00","hash":"","question":{"id":"8e963b00-477a-4a1a-bf22-d74b931f9058","created_at":"2023-12-12T09:00:57.402266804+01:00","updated_at":"2023-12-12T09:00:57.402266953+01:00","text":"Chi è l'#amore più grande della mia vita?"},"answers":[{"id":"df78ba57-b53b-411d-a8fc-ef57bce961d2","created_at":"2023-12-12T09:00:57.402274057+01:00","updated_at":"2023-12-12T09:00:57.40227419+01:00","text":"Giuly (❤️)"},{"id":"eb89e7fa-0909-4f84-bcbb-5fe89a015757","created_at":"2023-12-12T09:00:57.402276551+01:00","updated_at":"2023-12-12T09:00:57.402276604+01:00","text":"Daisy"},{"id":"3185a66b-5fce-4e22-bcd0-6dc06f2d4261","created_at":"2023-12-12T09:00:57.402278951+01:00","updated_at":"2023-12-12T09:00:57.402279003+01:00","text":"Jenny"},{"id":"49bbe2ca-9408-40e9-8625-442b27b32026","created_at":"2023-12-12T09:00:57.402281071+01:00","updated_at":"2023-12-12T09:00:57.402281125+01:00","text":"Lilly"}],"tags":[],"correct":{"id":"df78ba57-b53b-411d-a8fc-ef57bce961d2","created_at":"2023-12-12T09:00:57.402274057+01:00","updated_at":"2023-12-12T09:00:57.40227419+01:00","text":"Giuly (❤️)"},"CorrectPos":0,"type":0}]},"333222":{"id":"5b6e3f92-1a6f-4028-b618-ad434a1f6e16","created_at":"2023-12-12T09:00:57.402308673+01:00","updated_at":"2023-12-12T09:00:57.402308733+01:00","Participant":{"id":"564d0c7f-4840-443c-8325-ecd02d03624d","created_at":"2023-12-05T21:11:37.566330708+01:00","updated_at":"2023-12-12T09:00:57.401968656+01:00","Firstname":"Andrea","Lastname":"Fazzi","Token":"333222","Attributes":{"class":"1 D LIN"}},"Quizzes":[{"id":"908bb025-6370-4273-8448-8470f9336f26","created_at":"2023-12-05T21:22:06.322398595+01:00","updated_at":"2023-12-12T09:00:57.40230252+01:00","hash":"","question":{"id":"8e963b00-477a-4a1a-bf22-d74b931f9058","created_at":"2023-12-12T09:00:57.402266804+01:00","updated_at":"2023-12-12T09:00:57.402266953+01:00","text":"Chi è l'#amore più grande della mia vita?"},"answers":[{"id":"df78ba57-b53b-411d-a8fc-ef57bce961d2","created_at":"2023-12-12T09:00:57.402274057+01:00","updated_at":"2023-12-12T09:00:57.40227419+01:00","text":"Giuly (❤️)"},{"id":"eb89e7fa-0909-4f84-bcbb-5fe89a015757","created_at":"2023-12-12T09:00:57.402276551+01:00","updated_at":"2023-12-12T09:00:57.402276604+01:00","text":"Daisy"},{"id":"3185a66b-5fce-4e22-bcd0-6dc06f2d4261","created_at":"2023-12-12T09:00:57.402278951+01:00","updated_at":"2023-12-12T09:00:57.402279003+01:00","text":"Jenny"},{"id":"49bbe2ca-9408-40e9-8625-442b27b32026","created_at":"2023-12-12T09:00:57.402281071+01:00","updated_at":"2023-12-12T09:00:57.402281125+01:00","text":"Lilly"}],"tags":[],"correct":{"id":"df78ba57-b53b-411d-a8fc-ef57bce961d2","created_at":"2023-12-12T09:00:57.402274057+01:00","updated_at":"2023-12-12T09:00:57.40227419+01:00","text":"Giuly (❤️)"},"CorrectPos":0,"type":0}]}}} \ No newline at end of file diff --git a/server/payload.json b/server/payload.json new file mode 100644 index 0000000..97a93b4 --- /dev/null +++ b/server/payload.json @@ -0,0 +1,170 @@ +{ + "ID": "fe0a7ee0-f31a-413d-f123-ab5068bcaaaa", + "Name": "Test session", + "Exams": { + "111222": { + "id": "fe0a7ee0-f31a-413d-ba81-ab5068bc4c73", + "created_at": "0001-01-01T00:00:00Z", + "updated_at": "0001-01-01T00:00:00Z", + "Participant": { + "ID": "1234", + "Firstname": "John", + "Lastname": "Smith", + "Token": 111222, + "Attributes": { + "class": "1 D LIN" + } + }, + "Quizzes": [ + { + "id": "0610939b-a1a3-4d0e-bbc4-2aae0e8ee4b9", + "created_at": "2023-11-27T17:51:53.910642221+01:00", + "updated_at": "0001-01-01T00:00:00Z", + "hash": "", + "question": { + "id": "98c0eec9-677f-464e-9e3e-864a859f29a3", + "created_at": "0001-01-01T00:00:00Z", + "updated_at": "0001-01-01T00:00:00Z", + "text": "Question text with #tag1." + }, + "answers": [ + { + "id": "1ab5ff1f-74c8-4efc-abdc-d03a3640f3bc", + "text": "Answer 1" + }, + { + "id": "74547724-b905-476f-8cfc-6ee633f92ef3", + "text": "Answer 2" + }, + { + "id": "96c1a8ee-c50c-4ebc-89e4-9f3ca356adbd", + "text": "Answer 3" + }, + { + "id": "16c4b95e-64ce-4666-8cbe-b66fa59eb23b", + "text": "Answer 4" + } + ], + "tags": [ + { + "CreatedAt": "0001-01-01T00:00:00Z", + "UpdatedAt": "0001-01-01T00:00:00Z", + "DeletedAt": null, + "name": "#tag1" + } + ], + "correct": { + "id": "1ab5ff1f-74c8-4efc-abdc-d03a3640f3bc", + "text": "Answer 1" + }, + "CorrectPos": 0, + "type": 0 + }, + { + "id": "915818c4-b0ce-4efc-8def-7fc8d5fa7454", + "created_at": "2023-11-27T17:51:53.91077796+01:00", + "updated_at": "0001-01-01T00:00:00Z", + "hash": "", + "question": { + "id": "70793f0d-2855-4140-814e-40167464424b", + "created_at": "0001-01-01T00:00:00Z", + "updated_at": "0001-01-01T00:00:00Z", + "text": "Another question text with #tag1." + }, + "answers": [ + { + "id": "1ab5ff1f-74c8-4efc-abdc-d03a3640f3bc", + "text": "Answer 1" + }, + { + "id": "74547724-b905-476f-8cfc-6ee633f92ef3", + "text": "Answer 2" + }, + { + "id": "96c1a8ee-c50c-4ebc-89e4-9f3ca356adbd", + "text": "Answer 3" + }, + { + "id": "16c4b95e-64ce-4666-8cbe-b66fa59eb23b", + "text": "Answer 4" + } + ], + "tags": [ + { + "CreatedAt": "0001-01-01T00:00:00Z", + "UpdatedAt": "0001-01-01T00:00:00Z", + "DeletedAt": null, + "name": "#tag1" + } + ], + "correct": { + "id": "1ab5ff1f-74c8-4efc-abdc-d03a3640f3bc", + "text": "Answer 1" + }, + "CorrectPos": 0, + "type": 0 + } + ] + } + }, + "333444": { + "id": "12345678-abcd-efgh-ijkl-9876543210ef", + "created_at": "2023-12-01T12:00:00Z", + "updated_at": "2023-12-01T12:00:00Z", + "Participant": { + "ID": "5678", + "Firstname": "Jane", + "Lastname": "Doe", + "Token": 333444, + "Attributes": { + "class": "2 A SCI" + } + }, + "Quizzes": [ + { + "id": "22222222-abcd-efgh-ijkl-9876543210ef", + "created_at": "2023-12-01T12:00:00Z", + "updated_at": "2023-12-01T12:00:00Z", + "hash": "", + "question": { + "id": "33333333-abcd-efgh-ijkl-9876543210ef", + "created_at": "2023-12-01T12:00:00Z", + "updated_at": "2023-12-01T12:00:00Z", + "text": "Sample question text." + }, + "answers": [ + { + "id": "44444444-abcd-efgh-ijkl-9876543210ef", + "text": "Option 1" + }, + { + "id": "55555555-abcd-efgh-ijkl-9876543210ef", + "text": "Option 2" + }, + { + "id": "66666666-abcd-efgh-ijkl-9876543210ef", + "text": "Option 3" + }, + { + "id": "77777777-abcd-efgh-ijkl-9876543210ef", + "text": "Option 4" + } + ], + "tags": [ + { + "CreatedAt": "2023-12-01T12:00:00Z", + "UpdatedAt": "2023-12-01T12:00:00Z", + "DeletedAt": null, + "name": "#tag2" + } + ], + "correct": { + "id": "44444444-abcd-efgh-ijkl-9876543210ef", + "text": "Option 1" + }, + "CorrectPos": 0, + "type": 0 + } + ] + } +} diff --git a/server/testdata/responses/README b/server/testdata/responses/README new file mode 100644 index 0000000..687ddb6 --- /dev/null +++ b/server/testdata/responses/README @@ -0,0 +1 @@ +Please keep this file in the git tree in order to add the testdata/sessions folder. diff --git a/sessionmanager/sessionmanager.go b/sessionmanager/sessionmanager.go new file mode 100644 index 0000000..0908f06 --- /dev/null +++ b/sessionmanager/sessionmanager.go @@ -0,0 +1,83 @@ +package sessionmanager + +import ( + "bytes" + "encoding/json" + "io" + "net/http" + + "git.andreafazzi.eu/andrea/probo/models" + "git.andreafazzi.eu/andrea/probo/store" +) + +type SessionManager struct { + Name string + + ParticipantStore *store.ParticipantStore + QuizStore *store.QuizStore + + ParticipantFilter map[string]string + QuizFilter map[string]string + ServerURL string + Token int + + examStore *store.ExamStore +} + +func NewSessionManager(url string, name string, pStore *store.ParticipantStore, qStore *store.QuizStore, pFilter map[string]string, qFilter map[string]string) (*SessionManager, error) { + sm := new(SessionManager) + + sm.Name = name + sm.ServerURL = url + sm.examStore = store.NewStore[*models.Exam]() + + for _, p := range pStore.ReadAll() { + _, err := sm.examStore.Create(&models.Exam{ + Participant: p, + Quizzes: qStore.ReadAll(), + }) + if err != nil { + return nil, err + } + } + + return sm, nil +} + +func (sm *SessionManager) GetExams() []*models.Exam { + return sm.examStore.ReadAll() +} + +func (sm *SessionManager) Push() (string, error) { + session := &models.Session{ + Name: sm.Name, + Exams: make(map[string]*models.Exam), + } + + for _, e := range sm.GetExams() { + session.Exams[e.Participant.Token] = e + } + + payload, err := session.Marshal() + if err != nil { + return "", err + } + + response, err := http.Post(sm.ServerURL, "application/json", bytes.NewReader(payload)) + if err != nil { + return "", err + } + + responseBody, err := io.ReadAll(response.Body) + if err != nil { + return "", err + } + + result := map[string]string{} + err = json.Unmarshal(responseBody, &result) + if err != nil { + return "", err + } + + return result["id"], nil +} diff --git a/store/file/session.go b/store/file/session.go new file mode 100644 index 0000000..870f34b --- /dev/null +++ b/store/file/session.go @@ -0,0 +1,25 @@ +package file + +import ( + "git.andreafazzi.eu/andrea/probo/models" + "git.andreafazzi.eu/andrea/probo/store" +) + +type SessionFileStore = FileStore[*models.Session, *store.Store[*models.Session]] + +func NewSessionFileStore(config *FileStoreConfig[*models.Session, *store.SessionStore]) (*SessionFileStore, error) { + return NewFileStore[*models.Session](config, store.NewStore[*models.Session]()) +} + +func NewDefaultSessionFileStore() (*SessionFileStore, error) { + return NewSessionFileStore( + &FileStoreConfig[*models.Session, *store.SessionStore]{ + FilePathConfig: FilePathConfig{GetDefaultSessionDir(), "session", ".json"}, + IndexDirFunc: DefaultIndexDirFunc[*models.Session, *store.SessionStore], + CreateEntityFunc: func() *models.Session { + return &models.Session{} + }, + }, + ) + +} diff --git a/store/session.go b/store/session.go new file mode 100644 index 0000000..909c1f7 --- /dev/null +++ b/store/session.go @@ -0,0 +1,5 @@ +package store + +import "git.andreafazzi.eu/andrea/probo/models" + +type SessionStore = Store[*models.Session]