Mercurial > gemma
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 } |