comparison pkg/imports/report.go @ 5334:45805c454436 extented-report

Load users from database who should receive a report. Generate the report. TODO: Send the report by mail.
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Tue, 01 Jun 2021 01:22:10 +0200
parents 795a0a0b5047
children dcd5692a2889
comparison
equal deleted inserted replaced
5333:6c0f40676984 5334:45805c454436
15 15
16 import ( 16 import (
17 "context" 17 "context"
18 "database/sql" 18 "database/sql"
19 "errors" 19 "errors"
20 "fmt"
21 "log"
22 "os"
23 "path/filepath"
24 "regexp"
20 25
21 "gemma.intevation.de/gemma/pkg/common" 26 "gemma.intevation.de/gemma/pkg/common"
27 "gemma.intevation.de/gemma/pkg/config"
22 "gemma.intevation.de/gemma/pkg/models" 28 "gemma.intevation.de/gemma/pkg/models"
29 "gemma.intevation.de/gemma/pkg/xlsx"
30
31 "github.com/360EntSecGroup-Skylar/excelize/v2"
23 ) 32 )
24 33
25 type Report struct { 34 type Report struct {
26 models.QueueConfigurationType 35 models.QueueConfigurationType
27 Name string `json:"Name"` 36 Name string `json:"Name"`
67 } 76 }
68 r.Name = name 77 r.Name = name
69 return nil 78 return nil
70 } 79 }
71 80
81 func (r *Report) loadTemplate() (*excelize.File, *xlsx.Action, error) {
82 path := config.ReportPath()
83 if path == "" {
84 return nil, nil, errors.New("no report dir configured")
85 }
86
87 if stat, err := os.Stat(path); err != nil {
88 if os.IsNotExist(err) {
89 return nil, nil, fmt.Errorf("report dir '%s' does not exists", path)
90 }
91 return nil, nil, err
92 } else if !stat.Mode().IsDir() {
93 return nil, nil, fmt.Errorf("report dir '%s' is not a directory", path)
94 }
95
96 // TODO: Prevent this earlier.
97 if match, _ := regexp.MatchString(`^[a-zA-Z0-9_]+$`, r.Name); !match {
98 return nil, nil, errors.New("invalid report name")
99 }
100
101 xlsxFilename := filepath.Join(path, r.Name+".xlsx")
102 yamlFilename := filepath.Join(path, r.Name+".yaml")
103
104 for _, check := range []string{xlsxFilename, yamlFilename} {
105 if _, err := os.Stat(check); err != nil {
106 if os.IsNotExist(err) {
107 return nil, nil, fmt.Errorf("'%s' does not exists", check)
108 }
109 return nil, nil, err
110 }
111 }
112
113 template, err := excelize.OpenFile(xlsxFilename)
114 if err != nil {
115 return nil, nil, err
116 }
117
118 action, err := xlsx.ActionFromFile(yamlFilename)
119 if err != nil {
120 return nil, nil, err
121 }
122
123 return template, action, nil
124 }
125
126 const selectReportUsersSQL = `
127 SELECT username, email_address
128 FROM users.list_users
129 WHERE report_reciever
130 ORDER BY country, username`
131
72 func (r *Report) Do( 132 func (r *Report) Do(
73 ctx context.Context, 133 ctx context.Context,
74 importID int64, 134 importID int64,
75 conn *sql.Conn, 135 conn *sql.Conn,
76 feedback Feedback, 136 feedback Feedback,
77 ) (interface{}, error) { 137 ) (interface{}, error) {
78 138
79 // TODO: Implement me! 139 template, action, err := r.loadTemplate()
140 if err != nil {
141 return nil, err
142 }
143
144 tx, err := conn.BeginTx(ctx, &sql.TxOptions{ReadOnly: true})
145 if err != nil {
146 return nil, err
147 }
148 defer tx.Rollback()
149
150 type user struct {
151 name string
152 email string
153 }
154
155 var users []user
156
157 if err := func() error {
158 rows, err := tx.QueryContext(ctx, selectReportUsersSQL)
159 if err != nil {
160 return err
161 }
162 defer rows.Close()
163
164 for rows.Next() {
165 var u user
166 if err := rows.Scan(&u.name, &u.email); err != nil {
167 return err
168 }
169 users = append(users, u)
170 }
171 return rows.Err()
172 }(); err != nil {
173 return nil, err
174 }
175
176 if len(users) == 0 {
177 feedback.Warn("No users found to send reports to.")
178 return nil, nil
179 }
180
181 if err := action.Execute(ctx, tx, template); err != nil {
182 log.Printf("error: %v\n", err)
183 return nil, fmt.Errorf("Generating report failed: %v", err)
184 }
185
186 // TODO: Send report via email to users.
80 187
81 return nil, nil 188 return nil, nil
82 } 189 }