Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 32 additions & 12 deletions cmd/email.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,24 +15,25 @@ var (
Use: "email [subcommand]",
Short: "send email",
Long: `Send emails.
primuss-data [all|<ancode>] --- send emails to teachers about primuss data and nta
constraints --- ask for constraints
prepared --- announce exams to plan and constraints
draft --- announce draft plan
published-exams --- announce published exams
published-rooms --- announce published rooms
invigilations --- send email requesting invigilations constraints
published-invigilations --- announce published invigilations
nta-with-room-alone --- send emails to students with room alone before planning
nta-planned --- send emails about rooms to all students with nta after planning
primuss-data [all|<ancode>] --- send emails to teachers about primuss data and nta
constraints --- ask for constraints
prepared --- announce exams to plan and constraints
draft --- announce draft plan
published-exams --- announce published exams
published-rooms --- announce published rooms
invigilations --- send email requesting invigilations constraints
published-invigilations --- announce published invigilations
nta-with-room-alone --- send emails to students with room alone before planning
nta-planned --- send emails about rooms to all students with nta after planning
cover-pages [all|<teacherid>] --- send emails with externally generated cover pages
`,
Args: cobra.MinimumNArgs(1),
Run: func(cmd *cobra.Command, args []string) {
plexams := initPlexamsConfig()
switch args[0] {
case "primuss-data":
if len(args) < 2 {
log.Fatal("need program and primuss-ancode")
log.Fatal("need ancode or all")
}
if args[1] == "all" {
err := plexams.SendGeneratedExamMails(context.Background(), run)
Expand Down Expand Up @@ -95,7 +96,26 @@ nta-planned --- send emails about rooms to all students with nta after plann
if err != nil {
log.Fatalf("got error: %v\n", err)
}

case "cover-pages":
if len(args) < 2 {
log.Fatal("need teacher id or all")
}
if args[1] == "all" {
err := plexams.SendCoverPagesMails(context.Background(), run)
if err != nil {
log.Fatalf("got error: %v\n", err)
}
} else {
teacherID, err := strconv.Atoi(args[1])
if err != nil {
fmt.Printf("cannot use %s as teacher id", args[1])
os.Exit(1)
}
err = plexams.SendCoverPageMail(context.Background(), teacherID, run)
if err != nil {
log.Fatalf("got error: %v\n", err)
}
}
default:
fmt.Println("email called with unknown sub command")
}
Expand Down
6 changes: 3 additions & 3 deletions cmd/export.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@ var (
Use: "export",
Short: "export [subcommand]",
Long: `Generate various CSVs.
plannedRooms - export rooms of planned exams.`,
planned-rooms - export rooms of planned exams.`,
Args: cobra.MinimumNArgs(1),
Run: func(cmd *cobra.Command, args []string) {
plexams := initPlexamsConfig()
switch args[0] {
case "plannedRooms":
case "planned-rooms":
if len(jsonfile) == 0 {
jsonfile = "PlannedRooms.json"
jsonfile = "planned-rooms.json"
}
fmt.Printf("generating %s\n", jsonfile)
err := plexams.ExportPlannedRooms(jsonfile)
Expand Down
2 changes: 2 additions & 0 deletions plexams/email.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import (

//go:embed tmpl/constraintsEmail.tmpl
//go:embed tmpl/constraintsEmailHTML.tmpl
//go:embed tmpl/coverPageEmail.tmpl
//go:embed tmpl/coverPageEmailHTML.tmpl
//go:embed tmpl/draftEmailFS.tmpl
//go:embed tmpl/draftEmailFSHTML.tmpl
//go:embed tmpl/draftEmailZPA.tmpl
Expand Down
152 changes: 152 additions & 0 deletions plexams/email_cover_pages.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
package plexams

import (
"bytes"
"context"
"fmt"
"html/template"
"os"
"strings"
"time"

set "github.com/deckarep/golang-set/v2"
"github.com/jordan-wright/email"
"github.com/logrusorgru/aurora"
"github.com/obcode/plexams.go/graph/model"
"github.com/rs/zerolog/log"
"github.com/spf13/viper"
"github.com/theckman/yacspin"
)

type CoverMailData struct {
Teacher *model.Teacher
PlanerName string
GeneratorName string
}

func (p *Plexams) SendCoverPagesMails(ctx context.Context, run bool) error {
plannedExams, err := p.PlannedExams(ctx)
if err != nil {
return err
}

examerIDs := set.NewSet[int]()
for _, exam := range plannedExams {
if exam.Constraints != nil && exam.Constraints.NotPlannedByMe {
continue
}
examerIDs.Add(exam.ZpaExam.MainExamerID)
}

for examerID := range examerIDs.Iter() {
p.SendCoverPageMail(ctx, examerID, run)

Check failure on line 42 in plexams/email_cover_pages.go

View workflow job for this annotation

GitHub Actions / lint

Error return value of `p.SendCoverPageMail` is not checked (errcheck)
}

return nil
}

func (p *Plexams) SendCoverPageMail(ctx context.Context, examerID int, run bool) error {
cfg := yacspin.Config{
Frequency: 100 * time.Millisecond,
CharSet: yacspin.CharSets[69],
Suffix: aurora.Sprintf(aurora.Cyan(" sending email with cover pages for %4d"), examerID),
SuffixAutoColon: true,
StopCharacter: "✓",
StopColors: []string{"fgGreen"},
StopFailMessage: "error happend",
StopFailCharacter: "✗",
StopFailColors: []string{"fgRed"},
}
spinner, err := yacspin.New(cfg)
if err != nil {
log.Debug().Err(err).Msg("cannot create spinner")
}
err = spinner.Start()
if err != nil {
log.Debug().Err(err).Msg("cannot start spinner")
}

teacher, err := p.GetTeacher(ctx, examerID)
if err != nil {
log.Debug().Err(err).Msg("cannot get teacher by ID")
return err
}

dir := viper.GetString("coverPages.dir")
prefix := viper.GetString("coverPages.prefix")
filename := fmt.Sprintf("%s/%s%d.pdf", dir, prefix, examerID)

pdfData, err := os.ReadFile(filename)
if err != nil {
spinner.StopFailMessage(aurora.Sprintf(aurora.Red(" %s: file not found: %s"),
aurora.Magenta(teacher.Fullname), aurora.Magenta(filename)))
spinner.StopFail() //nolint:errcheck
return err
}

coverMailData := &CoverMailData{
PlanerName: p.planer.Name,
Teacher: teacher,
GeneratorName: "Edda Eich-Söllner",
}

tmpl, err := template.ParseFS(emailTemplates, "tmpl/coverPageEmail.tmpl")
if err != nil {
return err
}
bufText := new(bytes.Buffer)
err = tmpl.Execute(bufText, coverMailData)
if err != nil {
return err
}

tmpl, err = template.ParseFS(emailTemplates, "tmpl/coverPageEmailHTML.tmpl")
if err != nil {
return err
}
bufHTML := new(bytes.Buffer)
err = tmpl.Execute(bufHTML, coverMailData)
if err != nil {
return err
}

subject := fmt.Sprintf("[Prüfungsplanung %s] Deckblätter für Ihre Prüfungen",
p.semester)

var to []string
if run {
to = []string{teacher.Email}
} else {
to = []string{"galority@gmail.com"}
}

err = p.sendMail(to,
nil,
subject,
bufText.Bytes(),
bufHTML.Bytes(),
[]*email.Attachment{{
Filename: strings.ReplaceAll(fmt.Sprintf("%s_Deckblaetter_Pruefungen_%s.pdf", p.semester, teacher.Fullname), " ", "_"),
ContentType: "application/pdf",
Header: map[string][]string{},
Content: pdfData,
HTMLRelated: false,
}},
true,
)

if err != nil {
spinner.StopFailMessage(aurora.Sprintf(aurora.Red(" error while sending email to %s"), teacher.Fullname))
return err
}

spinner.StopMessage(aurora.Sprintf(aurora.Cyan(" successfully send to %s"), teacher.Fullname))

err = spinner.Stop()

if err != nil {
log.Debug().Err(err).Msg("cannot stop spinner")
}

return nil
}
10 changes: 10 additions & 0 deletions plexams/tmpl/coverPageEmail.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
Hallo {{ .Teacher.Fullname }},

im Anhang finden Sie die von {{ .GeneratorName }} generierten Deckblätter für Ihre Prüfungen.

Mit freundlichen Grüßen
{{ .PlanerName }}
Prüfungsplaner der FK07

--
Diese E-Mail wurde generiert und gesendet von https://github.com/obcode/plexams.go
13 changes: 13 additions & 0 deletions plexams/tmpl/coverPageEmailHTML.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<p>Hallo {{ .Teacher.Fullname }},</p>

<p>im Anhang finden Sie die von {{ .GeneratorName }} generierten Deckblätter für Ihre Prüfungen.</p>

<p>Mit freundlichen Grüßen</p>
<p>{{ .PlanerName }}<br />
Prüfungsplaner der FK07
</p>

<pre>
--
Diese E-Mail wurde generiert und gesendet von https://github.com/obcode/plexams.go
</pre>
2 changes: 2 additions & 0 deletions plexams/tmpl/publishedEmailRooms.tmpl
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
[Antworten bitte nicht via E-Mail, sondern via JIRA (https://jira.cc.hm.edu/servicedesk/customer/portal/13)]

Liebe Prüfende,

ich habe gerade die Räume ins ZPA gepusht. Bitte schauen Sie auf https://zpa.cs.hm.edu/teacher/exam_plan/ ob das so für Ihre Prüfungen passt.

Ich habe versucht die Raumnutzung sehr zu optimieren, daher gibt es z.B. mehrere kleine (unter 10 Anmeldungen) Prüfungen in einem Raum oder ein Raum für eine Prüfung ist gleichzeitig Reserveraum für eine weitere Prüfung.
Expand Down
2 changes: 2 additions & 0 deletions plexams/tmpl/publishedEmailRoomsHTML.tmpl
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
<p>[Antworten bitte nicht via E-Mail,
sondern via <a href="https://jira.cc.hm.edu/servicedesk/customer/portal/13">JIRA</a>]</p>

<p>Liebe Prüfende,</p>

<p>ich habe gerade die Räume ins ZPA gepusht. Bitte schauen Sie auf <a href='https://zpa.cs.hm.edu/teacher/exam_plan/'>https://zpa.cs.hm.edu/teacher/exam_plan/</a>
ob das so für Ihre Prüfungen passt.</p>
<p>Ich habe versucht die Raumnutzung sehr zu optimieren, daher gibt es z.B. mehrere kleine (unter 10 Anmeldungen) Prüfungen in einem Raum oder
Expand Down
Loading