summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--endpoint_export_choices.go (renamed from endpoint_export.go)4
-rw-r--r--endpoint_export_students.go141
-rw-r--r--main.go3
-rw-r--r--templates/staff.html3
4 files changed, 147 insertions, 4 deletions
diff --git a/endpoint_export.go b/endpoint_export_choices.go
index 3c8c36e..890f170 100644
--- a/endpoint_export.go
+++ b/endpoint_export_choices.go
@@ -27,7 +27,7 @@ import (
"strings"
)
-func handleExport(w http.ResponseWriter, req *http.Request) {
+func handleExportChoices(w http.ResponseWriter, req *http.Request) {
_, _, department, err := getUserInfoFromRequest(req)
if err != nil {
wstr(
@@ -159,7 +159,7 @@ func handleExport(w http.ResponseWriter, req *http.Request) {
}
w.Header().Set("Content-Type", "text/csv; charset=utf-8")
- w.Header().Set("Content-Disposition", "attachment;filename=cca.csv")
+ w.Header().Set("Content-Disposition", "attachment;filename=cca_choices.csv")
csvWriter := csv.NewWriter(w)
err = csvWriter.Write([]string{
"Student Name",
diff --git a/endpoint_export_students.go b/endpoint_export_students.go
new file mode 100644
index 0000000..75f9150
--- /dev/null
+++ b/endpoint_export_students.go
@@ -0,0 +1,141 @@
+/*
+ * Staff page
+ *
+ * Copyright (C) 2024 Runxi Yu <https://runxiyu.org>
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package main
+
+import (
+ "encoding/csv"
+ "fmt"
+ "net/http"
+ "strconv"
+)
+
+func handleExportStudents(w http.ResponseWriter, req *http.Request) {
+ _, _, department, err := getUserInfoFromRequest(req)
+ if err != nil {
+ wstr(
+ w,
+ http.StatusInternalServerError,
+ fmt.Sprintf("Error: %v", err),
+ )
+ }
+ if department != staffDepartment {
+ wstr(
+ w,
+ http.StatusForbidden,
+ "You are not authorized to view this page",
+ )
+ return
+ }
+
+ rows, err := db.Query(req.Context(), "SELECT name, email, department, confirmed FROM users")
+ if err != nil {
+ wstr(
+ w,
+ http.StatusInternalServerError,
+ "Unexpected database error",
+ )
+ return
+ }
+ output := make([][]string, 0)
+ for {
+ if !rows.Next() {
+ err := rows.Err()
+ if err != nil {
+ wstr(
+ w,
+ http.StatusInternalServerError,
+ "Unexpected database error",
+ )
+ return
+ }
+ break
+ }
+ var currentUserName, currentEmail, currentDepartment string
+ var currentConfirmed bool
+ err := rows.Scan(
+ &currentUserName,
+ &currentEmail,
+ &currentDepartment,
+ &currentConfirmed,
+ )
+ if err != nil {
+ wstr(
+ w,
+ http.StatusInternalServerError,
+ "Unexpected database error",
+ )
+ return
+ }
+
+ if currentDepartment == staffDepartment {
+ continue
+ }
+
+ output = append(
+ output,
+ []string{
+ currentUserName,
+ currentEmail,
+ currentDepartment,
+ strconv.FormatBool(currentConfirmed),
+ },
+ )
+ }
+
+ w.Header().Set("Content-Type", "text/csv; charset=utf-8")
+ w.Header().Set("Content-Disposition", "attachment;filename=cca_students.csv")
+ csvWriter := csv.NewWriter(w)
+ err = csvWriter.Write([]string{
+ "Student Name",
+ "Student ID",
+ "Grade/Year",
+ "Group/Activity",
+ "Container",
+ "Section ID",
+ "Course ID",
+ })
+ if err != nil {
+ wstr(
+ w,
+ http.StatusInternalServerError,
+ "Error writing output",
+ )
+ return
+ }
+ err = csvWriter.WriteAll(output)
+ if err != nil {
+ wstr(
+ w,
+ http.StatusInternalServerError,
+ "Error writing output",
+ )
+ return
+ }
+ csvWriter.Flush()
+ if csvWriter.Error() != nil {
+ wstr(
+ w,
+ http.StatusInternalServerError,
+ "Error occurred flushing output",
+ )
+ return
+ }
+}
diff --git a/main.go b/main.go
index be9de22..2d64ada 100644
--- a/main.go
+++ b/main.go
@@ -117,7 +117,8 @@ func main() {
log.Println("Registering handlers")
http.HandleFunc("/{$}", handleIndex)
- http.HandleFunc("/export", handleExport)
+ http.HandleFunc("/export/choices", handleExportChoices)
+ http.HandleFunc("/export/students", handleExportStudents)
http.HandleFunc("/auth", handleAuth)
http.HandleFunc("/ws", handleWs)
http.HandleFunc("/state/{s}", handleState)
diff --git a/templates/staff.html b/templates/staff.html
index a8bab1a..3ed6f3e 100644
--- a/templates/staff.html
+++ b/templates/staff.html
@@ -48,7 +48,8 @@
</p>
</div>
<div class="reading-width">
- <p><a href="./export" class="btn-normal btn">Export all choices as a spreadsheet</a></p>
+ <p><a href="./export/choices" class="btn-normal btn">Export all choices as a spreadsheet</a></p>
+ <p><a href="./export/students" class="btn-normal btn">Export student confirmed status as a spreadsheet</a></p>
{{- if ge .State 1 }}
<p><a href="./state/0" class="btn-danger btn">Disable student access</a></p>
{{- if ge .State 2 }}