package api import ( "encoding/json" "fmt" "html/template" "io/ioutil" "net/http" "sort" "strings" "github.com/gorilla/mux" "github.com/gorilla/schema" "gogs.carducci-dante.gov.it/andrea.fazzi/karmen/datasource/edt" "gogs.carducci-dante.gov.it/andrea.fazzi/karmen/orm" "gogs.carducci-dante.gov.it/andrea.fazzi/karmen/renderer" ) func teachersHandler() http.Handler { fn := func(w http.ResponseWriter, r *http.Request) { var data struct { Teachers []orm.Teacher } if err := orm.DB().Preload("Classes").Preload("Subjects").Find(&data.Teachers).Error; err != nil { panic(err) } sort.Slice(data.Teachers, func(i, j int) bool { return strings.ToLower(data.Teachers[i].Surname) < strings.ToLower(data.Teachers[j].Surname) }) if err := renderer.Render(w, "base", "teachers", data); err != nil { panic(err) } } return http.HandlerFunc(fn) } func teacherShowHandler() http.Handler { fn := func(w http.ResponseWriter, r *http.Request) { var data struct { Teacher orm.Teacher Subjects []orm.Subject Classes []orm.Class Activities []orm.Activity } if err := orm.DB().First(&data.Teacher, mux.Vars(r)["id"]).Error; err != nil { panic(err) } if err := orm.DB().Model(&data.Teacher).Related(&data.Subjects, "Subjects").Error; err != nil { panic(err) } if err := orm.DB().Model(&data.Teacher).Related(&data.Classes, "Classes").Error; err != nil { panic(err) } sort.Slice(data.Classes, func(i, j int) bool { return strings.ToLower(data.Classes[i].Name) < strings.ToLower(data.Classes[j].Name) }) if err := orm.DB().Model(&data.Teacher).Related(&data.Activities, "Activities").Error; err != nil { panic(err) } sort.Slice(data.Activities, func(i, j int) bool { return data.Activities[i].Hours > data.Activities[j].Hours }) if err := renderer.Render(w, "base", "teachers_show", data); err != nil { panic(err) } } return http.HandlerFunc(fn) } func teachersAddHandler() http.Handler { fn := func(w http.ResponseWriter, r *http.Request) { if r.Method == "GET" { var data struct { Update bool SubmitUrl template.URL } data.SubmitUrl = template.URL(fmt.Sprintf("/teachers/add")) if err := renderer.Render(w, "base", "teachers_add_update", data); err != nil { panic(err) } } else if r.Method == "POST" { var teacher orm.Teacher if err := r.ParseForm(); err != nil { panic(err) } decoder := schema.NewDecoder() if err := decoder.Decode(&teacher, r.PostForm); err != nil { panic(err) } // Generate username and initial password teacher.Username = teacher.GenerateUsername() teacher.Password = teacher.GenerateSaltedPassword(teacher.Username) orm.DB().NewRecord(teacher) if err := orm.DB().Create(&teacher).Error; err != nil { panic(err) } http.Redirect(w, r, fmt.Sprintf("/teachers/%d", teacher.ID), http.StatusSeeOther) } } return http.HandlerFunc(fn) } func teachersDeleteHandler() http.Handler { fn := func(w http.ResponseWriter, r *http.Request) { var teacher orm.Teacher if err := orm.DB().First(&teacher, mux.Vars(r)["id"]).Error; err != nil { panic(err) } if err := orm.DB().Delete(&teacher).Error; err != nil { panic(err) } var data struct { RedirectUrl string `json:"redirect_url"` } data.RedirectUrl = "/teachers" w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(data) } return http.HandlerFunc(fn) } func teacherUpdateHandler() http.Handler { fn := func(w http.ResponseWriter, r *http.Request) { if r.Method == "GET" { var data struct { Update bool SubmitUrl template.URL Teacher orm.Teacher } if err := orm.DB().First(&data.Teacher, mux.Vars(r)["id"]).Error; err != nil { panic(err) } data.Update = true data.SubmitUrl = template.URL(fmt.Sprintf("/teachers/%d/update", data.Teacher.ID)) if err := renderer.Render(w, "base", "teachers_add_update", data); err != nil { panic(err) } } else if r.Method == "POST" { var ( teacher orm.Teacher oldPassword string ) if err := orm.DB().First(&teacher, mux.Vars(r)["id"]).Error; err != nil { panic(err) } oldPassword = teacher.Password if err := r.ParseForm(); err != nil { panic(err) } decoder := schema.NewDecoder() if err := decoder.Decode(&teacher, r.PostForm); err != nil { panic(err) } if oldPassword != teacher.Password { teacher.Password = teacher.GenerateSaltedPassword(teacher.Password) } if err := orm.DB().Save(&teacher).Error; err != nil { panic(err) } var data struct { Teachers []orm.Teacher } data.Teachers = make([]orm.Teacher, 0) if err := orm.DB().Find(&data.Teachers).Error; err != nil { panic(err) } http.Redirect(w, r, fmt.Sprintf("/teachers/%d", teacher.ID), http.StatusSeeOther) } } return http.HandlerFunc(fn) } func teachersCheckUsernameHandler() http.Handler { fn := func(w http.ResponseWriter, r *http.Request) { var teacher orm.Teacher var data struct { Exists bool `json:"exists"` } if orm.DB().Where("username = ?", mux.Vars(r)["username"]).Find(&teacher).RecordNotFound() { data.Exists = false } else { data.Exists = true } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(data) } return http.HandlerFunc(fn) } func teachersImportHandler() http.Handler { fn := func(w http.ResponseWriter, r *http.Request) { r.ParseMultipartForm(32 << 20) file, _, err := r.FormFile("teachers_import") if err != nil { panic(err) } defer file.Close() data, err := ioutil.ReadAll(file) if err != nil { panic(err) } if importer, err := edt.NewImporter( string(data), map[string]string{ "COGNOME": "surname", "NOME": "name", }, ); err != nil { panic(err) } else { if err := orm.Import(&orm.Teacher{}, importer); err != nil { panic(err) } http.Redirect(w, r, "/teachers", http.StatusSeeOther) } } return http.HandlerFunc(fn) }