-
Notifications
You must be signed in to change notification settings - Fork 42
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add a package to abstract SQL operations #18
Changes from all commits
1a3d667
67c4186
0cc196f
f822956
fb45f41
c34141d
ff71aa2
d6423c2
9e364a7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,6 +3,7 @@ package main | |
import ( | ||
"bytes" | ||
"database/sql" | ||
"errors" | ||
"flag" | ||
"fmt" | ||
"io" | ||
|
@@ -12,7 +13,8 @@ import ( | |
"os" | ||
"os/exec" | ||
"text/template" | ||
"time" | ||
|
||
"github.com/nnev/website/data" | ||
) | ||
|
||
var cmdAnnounce = &Command{ | ||
|
@@ -31,18 +33,7 @@ func init() { | |
cmdAnnounce.Run = RunAnnounce | ||
} | ||
|
||
func isStammtisch(date time.Time) (stammt bool, err error) { | ||
err = db.QueryRow("SELECT stammtisch FROM termine WHERE date = $1", date).Scan(&stammt) | ||
return | ||
} | ||
|
||
func announceStammtisch(date time.Time) { | ||
loc, err := getLocation(date) | ||
if err != nil { | ||
log.Println("Kann Location nicht auslesen:", err) | ||
return | ||
} | ||
|
||
func announceStammtisch(t *data.Termin) error { | ||
maildraft := `Liebe Treffler, | ||
|
||
am kommenden Donnerstag ist wieder Stammtisch. Diesmal sind wir bei {{.Location}}. | ||
|
@@ -56,43 +47,22 @@ Damit wir passend reservieren können, tragt bitte bis Dienstag Abend, | |
|
||
mailtmpl := template.Must(template.New("maildraft").Parse(maildraft)) | ||
mailbuf := new(bytes.Buffer) | ||
type data struct { | ||
Location string | ||
} | ||
if err = mailtmpl.Execute(mailbuf, data{loc}); err != nil { | ||
log.Println("Fehler beim Füllen des Templates:", err) | ||
return | ||
if err := mailtmpl.Execute(mailbuf, t); err != nil { | ||
return fmt.Errorf("Fehler beim Füllen des Templates: %v", err) | ||
} | ||
mail := mailbuf.Bytes() | ||
|
||
sendAnnouncement("Bitte für Stammtisch eintragen", mail) | ||
return sendAnnouncement("Bitte für Stammtisch eintragen", mail) | ||
} | ||
|
||
func announceC14(date time.Time) { | ||
var data struct { | ||
Topic, | ||
Abstract, | ||
Speaker string | ||
} | ||
|
||
if err := db.QueryRow("SELECT topic FROM vortraege WHERE date = $1", date).Scan(&data.Topic); err != nil { | ||
if err == sql.ErrNoRows { | ||
fmt.Println("Es gibt nächsten Donnerstag noch keine c¼h. :(") | ||
return | ||
} | ||
|
||
log.Println("Kann topic nicht auslesen:", err) | ||
return | ||
} | ||
|
||
if err := db.QueryRow("SELECT abstract FROM vortraege WHERE date = $1", date).Scan(&data.Abstract); err != nil { | ||
log.Println("Kann abstract nicht auslesen:", err) | ||
return | ||
func announceC14(t *data.Termin) error { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same here with |
||
vortrag, err := t.GetVortrag(cmdAnnounce.Tx) | ||
if err == sql.ErrNoRows { | ||
fmt.Println("Es gibt nächsten Donnerstag noch keine c¼h. :(") | ||
return nil | ||
} | ||
|
||
if err := db.QueryRow("SELECT speaker FROM vortraege WHERE date = $1", date).Scan(&data.Speaker); err != nil { | ||
log.Println("Kann speaker nicht auslesen:", err) | ||
return | ||
if err != nil { | ||
log.Fatal("Kann vortrag nicht lesen:", err) | ||
} | ||
|
||
maildraft := `Liebe Treffler, | ||
|
@@ -113,15 +83,14 @@ Wer mehr Informationen möchte: | |
|
||
mailtmpl := template.Must(template.New("maildraft").Parse(maildraft)) | ||
mailbuf := new(bytes.Buffer) | ||
if err := mailtmpl.Execute(mailbuf, data); err != nil { | ||
log.Println("Fehler beim Füllen des Templates:", err) | ||
return | ||
if err := mailtmpl.Execute(mailbuf, vortrag); err != nil { | ||
return fmt.Errorf("Fehler beim Füllen des Templates: %v", err) | ||
} | ||
mail := mailbuf.Bytes() | ||
sendAnnouncement(data.Topic, mail) | ||
return sendAnnouncement(vortrag.Topic, mail) | ||
} | ||
|
||
func sendAnnouncement(subject string, msg []byte) { | ||
func sendAnnouncement(subject string, msg []byte) error { | ||
mail := new(bytes.Buffer) | ||
fmt.Fprintf(mail, "From: [email protected]\r\n") | ||
fmt.Fprintf(mail, "To: %s\r\n", mime.QEncoding.Encode("utf-8", *targetmailaddr)) | ||
|
@@ -143,29 +112,23 @@ func sendAnnouncement(subject string, msg []byte) { | |
cmd.Stderr = stdout | ||
|
||
if err := cmd.Run(); err != nil { | ||
log.Println("Fehler beim Senden der Mail: ", err) | ||
log.Println("Output von Sendmail:") | ||
io.Copy(os.Stderr, stdout) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we are handing errors upwards anyways, it would be consequenial to return some error here as well, wouldn't it? Can be implemented later though, but we should file an issue then, so that it is done eventually. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good point. I'm considering it in-scope and have added it. |
||
return fmt.Errorf("Fehler beim Senden der Mail: %v", err) | ||
} | ||
return nil | ||
} | ||
|
||
func RunAnnounce() { | ||
var nextRelevantDate time.Time | ||
|
||
if err := db.QueryRow("SELECT date FROM termine WHERE date > NOW() AND override = '' ORDER BY date ASC LIMIT 1").Scan(&nextRelevantDate); err != nil { | ||
log.Println("Kann nächsten Termin nicht auslesen:", err) | ||
return | ||
func RunAnnounce() error { | ||
t, err := data.FutureTermine(cmdAnnounce.Tx).First() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
if err == sql.ErrNoRows { | ||
return errors.New("Keine termine gefunden") | ||
} | ||
|
||
isStm, err := isStammtisch(nextRelevantDate) | ||
if err != nil { | ||
log.Println("Kann stammtischiness nicht auslesen:", err) | ||
return | ||
return fmt.Errorf("Kann nächsten Termin nicht auslesen: %v", err) | ||
} | ||
|
||
if isStm { | ||
announceStammtisch(nextRelevantDate) | ||
} else { | ||
announceC14(nextRelevantDate) | ||
if t.Stammtisch.Bool { | ||
return announceStammtisch(t) | ||
} | ||
return announceC14(t) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
t *date.Termin
: one character-variables are easy to write, but having an actual word is better for later when someone works into the code.Therefore imho
s/t/termin/
here (and in the places where it is used).There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cf. variable name style and named result parameters (even though this is about a parameter, but the same reasoning applies). In short: a) variable/parameter name lengths should be inversely correlated to the distance between declaration and use and b) the signature of a function should be readable and not stutter (
termin *data.Termin
would be an example of stuttering).Your personal opinion on this particular styleguide item might differ (mine doesn't), but in any case I'd prefer to go with the clear mandate of the go culture here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same applies to the other instances of this comment.