From 4a25cd3b8a245e3b6527773cb4c16c60dad0592b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Omar=20Vergara=20P=C3=A9rez?= Date: Mon, 16 Sep 2024 22:59:58 -0600 Subject: [PATCH] feat(main): add api router --- main.go | 112 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) diff --git a/main.go b/main.go index d4a9be0..a1931f9 100644 --- a/main.go +++ b/main.go @@ -330,6 +330,108 @@ func handleModal(w http.ResponseWriter, r *http.Request) error { return nil } +func getFormats(w http.ResponseWriter, r *http.Request) error { + return nil +} + +func uploadFile(w http.ResponseWriter, r *http.Request) error { + var ( + convertedFile io.Reader + convertedFilePath string + convertedFileName string + err error + ) + + file, fileHeader, err := r.FormFile(uploadFileFormField) + if err != nil { + log.Printf("error ocurred getting file from form: %v", err) + return WithHTTPStatus(err, http.StatusBadRequest) + } + defer file.Close() + + targetFileSubType := r.FormValue("targetFormat") + + fileBytes, err := io.ReadAll(file) + if err != nil { + log.Printf("error ocurred reading file: %v", err) + return WithHTTPStatus(err, http.StatusInternalServerError) + } + + // Call Detect fuction to get the mimetype of the input file. + detectedFileType := mimetype.Detect(fileBytes) + + // Parse the mimetype to get the type and the sub-type of the input file. + fileType, subType, err := files.TypeAndSupType(detectedFileType.String()) + if err != nil { + log.Printf("error occurred getting type and subtype from mimetype: %v", err) + return WithHTTPStatus(err, http.StatusBadRequest) + + } + // Get the right factory based off the input file type. + fileFactory, err := files.BuildFactory(fileType, fileHeader.Filename) + if err != nil { + log.Printf("error occurred while getting a file factory: %v", err) + return WithHTTPStatus(err, http.StatusBadRequest) + } + + f, err := fileFactory.NewFile(subType) + if err != nil { + log.Printf("error occurred getting the file object: %v", err) + return WithHTTPStatus(err, http.StatusBadRequest) + } + + // Return the kind of the output file. + targetFileType := files.SupportedFileTypes()[targetFileSubType] + + // Convert the file to the target format. + // convertedFile is an io.Reader. + convertedFile, err = f.ConvertTo( + cases.Title(language.English).String(targetFileType), + targetFileSubType, + bytes.NewReader(fileBytes), + ) + if err != nil { + log.Printf("error ocurred while processing the input file: %v", err) + return WithHTTPStatus(err, http.StatusInternalServerError) + } + + switch fileType { + case "application", "text": + targetFileSubType = "zip" + } + + convertedFileName = filename(fileHeader.Filename, targetFileSubType) + convertedFilePath = filepath.Join(uploadPath, convertedFileName) + + newFile, err := os.Create(convertedFilePath) + if err != nil { + log.Printf("error occurred while creating the output file: %v", err) + return WithHTTPStatus(err, http.StatusInternalServerError) + } + defer newFile.Close() + + buf := new(bytes.Buffer) + if _, err := buf.ReadFrom(convertedFile); err != nil { + log.Printf("error occurred while readinf from the converted file: %v", err) + return WithHTTPStatus(err, http.StatusInternalServerError) + } + + convertedFileBytes := buf.Bytes() + if _, err := newFile.Write(convertedFileBytes); err != nil { + log.Printf("error occurred writing converted output to a file in disk: %v", err) + return WithHTTPStatus(err, http.StatusInternalServerError) + } + + w.WriteHeader(http.StatusOK) + w.Header().Set("Content-Type", "application/octet-stream") + if _, err := w.Write(convertedFileBytes); err != nil { + log.Printf("error occurred writing converted file to response writer: %v", err) + return WithHTTPStatus(err, http.StatusInternalServerError) + } + + return nil +} + func newRouter() http.Handler { r := chi.NewRouter() r.Use(middleware.Logger) @@ -344,6 +446,13 @@ func newRouter() http.Handler { return r } +func apiRouter() http.Handler { + r := chi.NewRouter() + r.Get("/formats", toHandler(getFormats)) + r.Post("/upload", toHandler(uploadFile)) + return r +} + func addRoutes(r *chi.Mux, fs, fsUpload http.Handler) { r.HandleFunc("/healthz", healthz) r.Handle("/static/*", fs) @@ -352,6 +461,9 @@ func addRoutes(r *chi.Mux, fs, fsUpload http.Handler) { r.Post("/upload", toHandler(handleUploadFile)) r.Post("/format", toHandler(handleFileFormat)) r.Get("/modal", toHandler(handleModal)) + + // Mount the api router. + r.Mount("/api/v1", apiRouter()) } func run(ctx context.Context) error {