package app import ( "bytes" "encoding/json" "html/template" "io/fs" "log" "net/http" "net/url" "strconv" "git.atik.me/basicweb/models" ) type App struct { LabsFS fs.FS WebFS fs.FS Labs map[int]models.Lab } func New(labsFS fs.FS, webFS fs.FS) App { return App{ LabsFS: labsFS, WebFS: webFS, Labs: getLabsList(labsFS), } } func (a *App) MainPageHandler(writer http.ResponseWriter, request *http.Request) { html, err := template.ParseFS(a.WebFS, "templates/index.html") if err != nil { log.Fatal(err) } if err := html.Execute(writer, a.Labs); err != nil { log.Fatal(err) } } func (a *App) LabPageHandler(writer http.ResponseWriter, request *http.Request) { html, err := template.ParseFS(a.WebFS, "templates/lab.html") if err != nil { log.Fatal(err) } parsedURL, err := url.Parse(request.URL.String()) if err != nil { writer.WriteHeader(http.StatusInternalServerError) writer.Write([]byte("Internal server error")) return } strNumber := parsedURL.Query().Get("number") if strNumber == "" { writer.WriteHeader(http.StatusNotFound) writer.Write([]byte("Не указан номер лабораторной работы!")) return } number, err := strconv.Atoi(strNumber) if err != nil { writer.WriteHeader(http.StatusNotFound) writer.Write([]byte("Некорректный номер лабораторной работы!")) return } lab, ok := a.Labs[number] if !ok || !lab.Complete { writer.WriteHeader(http.StatusNotFound) writer.Write([]byte("Лаборатораня работа с номером " + strconv.Itoa(number) + " не найдена!")) return } if err := html.Execute(writer, lab); err != nil { log.Fatal(err) } } func getLabsList(labsFS fs.FS) map[int]models.Lab { var result = make(map[int]models.Lab) folders, err := fs.ReadDir(labsFS, "labs") if err != nil { log.Fatal(err) } for _, folder := range folders { if folder.IsDir() { fileData, err := fs.ReadFile(labsFS, "labs/"+folder.Name()+"/desc.json") if err != nil { log.Fatal(err) } reader := bytes.NewReader(fileData) decoder := json.NewDecoder(reader) lab := models.Lab{} if err := decoder.Decode(&lab); err != nil { log.Fatal(err) } result[lab.Number] = lab } } return result }