Mercurial > gemma
view pkg/controllers/report.go @ 5637:7f9600ab5461
merge
author | Thomas Junk <thomas.junk@intevation.de> |
---|---|
date | Wed, 14 Jun 2023 08:45:11 +0200 |
parents | 847de131893a |
children | 2dd155cc95ec |
line wrap: on
line source
// This is Free Software under GNU Affero General Public License v >= 3.0 // without warranty, see README.md and license for details. // // SPDX-License-Identifier: AGPL-3.0-or-later // License-Filename: LICENSES/AGPL-3.0.txt // // Copyright (C) 2021 by via donau // – Österreichische Wasserstraßen-Gesellschaft mbH // Software engineering by Intevation GmbH // // Author(s): // * Sascha L. Teichmann <sascha.teichmann@intevation.de> package controllers import ( "database/sql" "fmt" "net/http" "os" "path/filepath" "sort" "strings" "gemma.intevation.de/gemma/pkg/config" "gemma.intevation.de/gemma/pkg/xlsx" "gemma.intevation.de/gemma/pkg/log" mw "gemma.intevation.de/gemma/pkg/middleware" "github.com/gorilla/mux" "github.com/xuri/excelize/v2" ) func listReports(req *http.Request) (jr mw.JSONResult, err error) { path := config.ReportPath() if path == "" { err = mw.JSONError{ Code: http.StatusNotFound, Message: http.StatusText(http.StatusNotFound), } return } // This would be easier with Go 1.16+. dir, err := os.Open(path) if err != nil { log.Errorf("%v\n", err) err = mw.JSONError{ Code: http.StatusInternalServerError, Message: "Listing report templates failed.", } return } defer dir.Close() files, err := dir.Readdirnames(-1) if err != nil { log.Errorf("%v\n", err) err = mw.JSONError{ Code: http.StatusInternalServerError, Message: "Listing report templates failed.", } return } pairs := map[string]int{} all: for _, file := range files { var mask int switch { case strings.HasSuffix(file, ".xlsx"): mask = 1 case strings.HasSuffix(file, ".yaml"): mask = 2 default: continue all } basename := filepath.Base(file) name := strings.TrimSuffix(basename, filepath.Ext(basename)) pairs[name] |= mask } var reports []string for name, mask := range pairs { if mask == 3 { reports = append(reports, name) } } sort.Strings(reports) out := struct { Reports []string `json:"reports"` }{ Reports: reports, } jr = mw.JSONResult{Result: out} return } func report(rw http.ResponseWriter, req *http.Request) { path := config.ReportPath() if path == "" { http.NotFound(rw, req) return } if stat, err := os.Stat(path); err != nil { if os.IsNotExist(err) { log.Errorf("report dir '%s' does not exists.\n", path) http.NotFound(rw, req) } else { log.Errorf("%v\n", err) http.Error(rw, "Error: "+err.Error(), http.StatusInternalServerError) } return } else if !stat.Mode().IsDir() { log.Errorf("report dir '%s' is not a directory.\n", path) http.NotFound(rw, req) return } vars := mux.Vars(req) name := vars["name"] xlsxFilename := filepath.Join(path, name+".xlsx") yamlFilename := filepath.Join(path, name+".yaml") for _, check := range []string{xlsxFilename, yamlFilename} { if _, err := os.Stat(check); err != nil { if os.IsNotExist(err) { http.NotFound(rw, req) } else { log.Errorf("%v\n", err) http.Error(rw, "Error: "+err.Error(), http.StatusInternalServerError) } return } } template, err := excelize.OpenFile(xlsxFilename) if err != nil { log.Errorf("%v\n", err) http.Error(rw, "Error: "+err.Error(), http.StatusInternalServerError) return } action, err := xlsx.ActionFromFile(yamlFilename) if err != nil { http.Error(rw, "Error: "+err.Error(), http.StatusInternalServerError) log.Errorf("%v\n", err) return } ctx := req.Context() conn := mw.GetDBConn(req) tx, err := conn.BeginTx(ctx, &sql.TxOptions{ReadOnly: true}) if err != nil { http.Error(rw, "Error: "+err.Error(), http.StatusInternalServerError) log.Errorf("%v\n", err) return } defer tx.Rollback() if err := action.Execute(ctx, tx, template); err != nil { log.Errorf("%v\n", err) http.Error(rw, "Error: "+err.Error(), http.StatusInternalServerError) return } rw.Header().Set( "Content-Disposition", fmt.Sprintf("attachment; filename=%s.xlsx", name)) rw.Header().Set( "Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") if _, err := template.WriteTo(rw); err != nil { log.Errorf("%v\n", err) } }