Speichere Konfiguration in config/config.json
This commit is contained in:
parent
43b3631da2
commit
c38286bcc5
14 changed files with 249 additions and 78 deletions
88
config/config.go
Normal file
88
config/config.go
Normal file
|
@ -0,0 +1,88 @@
|
|||
package config
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
Server struct {
|
||||
ListenAddress string
|
||||
ListenPort int
|
||||
Protocol string
|
||||
Domain string
|
||||
}
|
||||
Date struct {
|
||||
MinuteGranularity int
|
||||
}
|
||||
Request struct {
|
||||
SecretLength int
|
||||
}
|
||||
Mailer struct {
|
||||
Type string
|
||||
FromAddress string
|
||||
FromName template.HTML
|
||||
SmtpHost string
|
||||
SmtpPort int
|
||||
SmtpUseAuth bool
|
||||
SmtpIdentity string
|
||||
SmtpPassword string
|
||||
}
|
||||
SQL struct {
|
||||
Type string
|
||||
SQLiteFile string
|
||||
MysqlUser string
|
||||
MysqlPassword string
|
||||
MysqlHost string
|
||||
MysqlPort int
|
||||
MysqlDatabase string
|
||||
}
|
||||
}
|
||||
|
||||
// ReadConfigFile takes a file path as an argument and attempts to
|
||||
// unmarshal the content of the file into a struct containing a
|
||||
// configuration.
|
||||
func ReadConfigFile(filename string, conf *Config) error {
|
||||
configData, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = json.Unmarshal(configData, conf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return validateConfig(conf)
|
||||
}
|
||||
|
||||
func validateConfig(conf *Config) error {
|
||||
var err error
|
||||
if !(conf.Server.ListenPort >= 1 && conf.Server.ListenPort <= 65535) {
|
||||
err = fmt.Errorf("Validating config: Server port must be between 1 and 65535, but is %d.", conf.Server.ListenPort)
|
||||
log.Println(err.Error())
|
||||
}
|
||||
if !(conf.Server.Protocol == "http" || conf.Server.Protocol == "https") {
|
||||
err = fmt.Errorf("Validating config: Server protocol must be http or https, but is '%s'.", conf.Server.Protocol)
|
||||
log.Println(err.Error())
|
||||
}
|
||||
if !(conf.Date.MinuteGranularity >= 1 && conf.Date.MinuteGranularity <= 60) {
|
||||
err = fmt.Errorf("Validating config: Minute granularity must be between 1 and 60, but is %d.", conf.Date.MinuteGranularity)
|
||||
log.Println(err.Error())
|
||||
}
|
||||
if !(conf.Request.SecretLength >= 5 && conf.Request.SecretLength <= 50) {
|
||||
err = fmt.Errorf("Validating config: Requests' secret length must be between 5 and 50, but is %d.", conf.Request.SecretLength)
|
||||
log.Println(err.Error())
|
||||
}
|
||||
if !(conf.Mailer.Type == "Stdout" || conf.Mailer.Type == "Smtp") {
|
||||
err = fmt.Errorf("Validating config: Mailer type must be 'stdout' or 'smtp', but is '%s'.", conf.Mailer.Type)
|
||||
log.Println(err.Error())
|
||||
}
|
||||
if !(conf.SQL.Type == "SQLite" || conf.SQL.Type == "Mysql") {
|
||||
err = fmt.Errorf("Validating config: SQL type must be 'SQLite' or 'Mysql', but is '%s'.", conf.SQL.Type)
|
||||
log.Println(err.Error())
|
||||
}
|
||||
return err
|
||||
|
||||
}
|
33
config/config.json
Normal file
33
config/config.json
Normal file
|
@ -0,0 +1,33 @@
|
|||
{
|
||||
"server": {
|
||||
"listenAddress": "",
|
||||
"listenPort": 8080,
|
||||
"protocol": "https",
|
||||
"domain": "localhost:8080"
|
||||
},
|
||||
"date": {
|
||||
"minuteGranularity": 5
|
||||
},
|
||||
"request": {
|
||||
"secretLength": 15
|
||||
},
|
||||
"mailer": {
|
||||
"type": "Stdout",
|
||||
"fromAddress": "sprechstunden@localhost",
|
||||
"fromName": "Mathebau Sprechstunden <sprechstunden@localhost>",
|
||||
"smtpHost": "localhost",
|
||||
"smtpPort": 25,
|
||||
"smtpUseAuth": false,
|
||||
"smtpIdentity": "",
|
||||
"smtpPassword": ""
|
||||
},
|
||||
"SQL": {
|
||||
"type": "SQLite",
|
||||
"SQLiteFile": "officeHours.db",
|
||||
"mysqlUser": "officeHours",
|
||||
"mysqlPassword": "",
|
||||
"mysqlHost": "localhost",
|
||||
"mysqlPort": 3306,
|
||||
"mysqlDatabase": "officeHours"
|
||||
}
|
||||
}
|
|
@ -77,14 +77,14 @@ func (b *BaseHandler) AddOfficeHourHandler(w http.ResponseWriter, req *http.Requ
|
|||
errors = append(errors, "Die Stunde muss eine ganze Zahl sein.")
|
||||
}
|
||||
if !(hour >= 8 && hour <= 17) {
|
||||
errors = append(errors, fmt.Sprintf("Sprechstunden müssen zwischen 08:00 Uhr und 17:%d starten.", 60-models.MinuteGranularity))
|
||||
errors = append(errors, fmt.Sprintf("Sprechstunden müssen zwischen 08:00 Uhr und 17:%d starten.", 60-b.config.Date.MinuteGranularity))
|
||||
}
|
||||
minute, err = strconv.Atoi(time[1])
|
||||
if err != nil {
|
||||
errors = append(errors, "Die Minute muss eine ganze Zahl sein.")
|
||||
}
|
||||
if !(minute >= 0 && minute <= 60-models.MinuteGranularity && minute%models.MinuteGranularity == 0) {
|
||||
errors = append(errors, fmt.Sprintf("Sprechstunden dürfen nur alle %d Minuten starten.", models.MinuteGranularity))
|
||||
if !(minute >= 0 && minute <= 60-b.config.Date.MinuteGranularity && minute%b.config.Date.MinuteGranularity == 0) {
|
||||
errors = append(errors, fmt.Sprintf("Sprechstunden dürfen nur alle %d Minuten starten.", b.config.Date.MinuteGranularity))
|
||||
}
|
||||
}
|
||||
date := models.Date{week, day, hour, minute}
|
||||
|
@ -92,8 +92,8 @@ func (b *BaseHandler) AddOfficeHourHandler(w http.ResponseWriter, req *http.Requ
|
|||
if err != nil {
|
||||
errors = append(errors, "Die Dauer muss eine ganze Zahl sein.")
|
||||
}
|
||||
if !(duration >= models.MinuteGranularity && duration <= 120 && duration%models.MinuteGranularity == 0) {
|
||||
errors = append(errors, fmt.Sprintf("Sprechstunden müssen zwischen %d und 120 Minuten lang sein.", models.MinuteGranularity))
|
||||
if !(duration >= b.config.Date.MinuteGranularity && duration <= 120 && duration%b.config.Date.MinuteGranularity == 0) {
|
||||
errors = append(errors, fmt.Sprintf("Sprechstunden müssen zwischen %d und 120 Minuten lang sein.", b.config.Date.MinuteGranularity))
|
||||
}
|
||||
|
||||
roomname := req.FormValue("raumname")
|
||||
|
@ -120,7 +120,7 @@ func (b *BaseHandler) AddOfficeHourHandler(w http.ResponseWriter, req *http.Requ
|
|||
var data maskData = maskData{
|
||||
courses,
|
||||
rooms,
|
||||
models.MinuteGranularity,
|
||||
b.config.Date.MinuteGranularity,
|
||||
courseid,
|
||||
roomid,
|
||||
date,
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
package controllers
|
||||
|
||||
import "sprechstundentool/models"
|
||||
import (
|
||||
"sprechstundentool/config"
|
||||
"sprechstundentool/models"
|
||||
)
|
||||
|
||||
// BaseHandler will hold everything that controller needs
|
||||
type BaseHandler struct {
|
||||
|
@ -9,9 +12,15 @@ type BaseHandler struct {
|
|||
courseRepo models.CourseRepository
|
||||
tutorRepo models.TutorRepository
|
||||
requestRepo models.RequestRepository
|
||||
config config.Config
|
||||
}
|
||||
|
||||
// NewBaseHandler returns a new BaseHandler
|
||||
func NewBaseHandler(roomRepo models.RoomRepository, officeHourRepo models.OfficeHourRepository, courseRepo models.CourseRepository, tutorRepo models.TutorRepository, requestRepo models.RequestRepository) *BaseHandler {
|
||||
return &BaseHandler{roomRepo, officeHourRepo, courseRepo, tutorRepo, requestRepo}
|
||||
func NewBaseHandler(roomRepo models.RoomRepository,
|
||||
officeHourRepo models.OfficeHourRepository,
|
||||
courseRepo models.CourseRepository,
|
||||
tutorRepo models.TutorRepository,
|
||||
requestRepo models.RequestRepository,
|
||||
config config.Config) *BaseHandler {
|
||||
return &BaseHandler{roomRepo, officeHourRepo, courseRepo, tutorRepo, requestRepo, config}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ func (b *BaseHandler) DeleteOfficeHourHandler(w http.ResponseWriter, req *http.R
|
|||
Templates.ExecuteTemplate(w, "deleteSuccess.html", struct{}{})
|
||||
} else {
|
||||
officeHours, _ := b.officeHourRepo.GetAll(true)
|
||||
timetable, slots := GetTimetable(officeHours)
|
||||
b.writeTimetablePage(w, req, printTimetable(timetable, slots, true))
|
||||
timetable, slots := b.GetTimetable(officeHours)
|
||||
b.writeTimetablePage(w, req, b.printTimetable(timetable, slots, true))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,8 +20,8 @@ func (b *BaseHandler) GetByRoomHandler(w http.ResponseWriter, req *http.Request)
|
|||
return
|
||||
}
|
||||
officeHours, _ := b.officeHourRepo.FindByRoom(room, true)
|
||||
timetable, slots := GetTimetable(officeHours)
|
||||
b.writeTimetablePage(w, req, printTimetable(timetable, slots, false))
|
||||
timetable, slots := b.GetTimetable(officeHours)
|
||||
b.writeTimetablePage(w, req, b.printTimetable(timetable, slots, false))
|
||||
}
|
||||
|
||||
func (b *BaseHandler) GetByCourseHandler(w http.ResponseWriter, req *http.Request) {
|
||||
|
@ -35,8 +35,8 @@ func (b *BaseHandler) GetByCourseHandler(w http.ResponseWriter, req *http.Reques
|
|||
return
|
||||
}
|
||||
officeHours, _ := b.officeHourRepo.FindByCourse(course, true)
|
||||
timetable, slots := GetTimetable(officeHours)
|
||||
b.writeTimetablePage(w, req, printTimetable(timetable, slots, false))
|
||||
timetable, slots := b.GetTimetable(officeHours)
|
||||
b.writeTimetablePage(w, req, b.printTimetable(timetable, slots, false))
|
||||
}
|
||||
|
||||
func (b *BaseHandler) writeTimetablePage(w http.ResponseWriter, req *http.Request, timetable template.HTML) {
|
||||
|
|
|
@ -8,11 +8,11 @@ import (
|
|||
"sprechstundentool/models"
|
||||
)
|
||||
|
||||
func GetTimetable(officeHours []models.OfficeHour) (timetable map[models.Date]map[int]models.OfficeHour, slots []int) {
|
||||
func (b *BaseHandler) GetTimetable(officeHours []models.OfficeHour) (timetable map[models.Date]map[int]models.OfficeHour, slots []int) {
|
||||
var fullTimetable = make(map[models.Date]map[int]models.OfficeHour)
|
||||
for _, officeHour := range officeHours {
|
||||
var slot int = 0
|
||||
for minute := 0; minute < officeHour.Duration; minute += models.MinuteGranularity { // find slot id
|
||||
for minute := 0; minute < officeHour.Duration; minute += b.config.Date.MinuteGranularity { // find slot id
|
||||
_, exists := fullTimetable[models.GetEndDate(officeHour.Date, minute, true)]
|
||||
if exists {
|
||||
_, exists := fullTimetable[models.GetEndDate(officeHour.Date, minute, true)][slot]
|
||||
|
@ -25,7 +25,7 @@ func GetTimetable(officeHours []models.OfficeHour) (timetable map[models.Date]ma
|
|||
fullTimetable[models.GetEndDate(officeHour.Date, minute, true)] = make(map[int]models.OfficeHour)
|
||||
}
|
||||
}
|
||||
for minute := 0; minute < officeHour.Duration; minute += models.MinuteGranularity { // write officeHour id to timetable
|
||||
for minute := 0; minute < officeHour.Duration; minute += b.config.Date.MinuteGranularity { // write officeHour id to timetable
|
||||
fullTimetable[models.GetEndDate(officeHour.Date, minute, true)][slot] = officeHour
|
||||
}
|
||||
}
|
||||
|
@ -47,10 +47,10 @@ func GetTimetable(officeHours []models.OfficeHour) (timetable map[models.Date]ma
|
|||
return fullTimetable, slots
|
||||
}
|
||||
|
||||
func printTimetable(timetable map[models.Date]map[int]models.OfficeHour, slots []int, deleteIcons bool) template.HTML {
|
||||
func (b *BaseHandler) printTimetable(timetable map[models.Date]map[int]models.OfficeHour, slots []int, deleteIcons bool) template.HTML {
|
||||
var tableBody string
|
||||
for hour := 8; hour < 19; hour += 1 {
|
||||
for minute := 0; minute < 60; minute += models.MinuteGranularity {
|
||||
for minute := 0; minute < 60; minute += b.config.Date.MinuteGranularity {
|
||||
tableBody += "<tr>"
|
||||
if minute == 0 {
|
||||
tableBody += fmt.Sprintf("<td>%d Uhr</td>\n", hour)
|
||||
|
@ -65,10 +65,10 @@ func printTimetable(timetable map[models.Date]map[int]models.OfficeHour, slots [
|
|||
var continued bool = false // is this slot occupied by the same office hour the previous minute?
|
||||
var predecessorExists bool
|
||||
var predecessor models.OfficeHour
|
||||
if hour > 0 && minute < models.MinuteGranularity {
|
||||
predecessor, predecessorExists = timetable[models.Date{0, day, hour - 1, 60 - models.MinuteGranularity}][slot]
|
||||
if hour > 0 && minute < b.config.Date.MinuteGranularity {
|
||||
predecessor, predecessorExists = timetable[models.Date{0, day, hour - 1, 60 - b.config.Date.MinuteGranularity}][slot]
|
||||
} else {
|
||||
predecessor, predecessorExists = timetable[models.Date{0, day, hour, minute - models.MinuteGranularity}][slot]
|
||||
predecessor, predecessorExists = timetable[models.Date{0, day, hour, minute - b.config.Date.MinuteGranularity}][slot]
|
||||
}
|
||||
if predecessorExists {
|
||||
continued = (predecessor == current)
|
||||
|
@ -83,7 +83,7 @@ func printTimetable(timetable map[models.Date]map[int]models.OfficeHour, slots [
|
|||
OfficeHour models.OfficeHour
|
||||
MinuteGranularity int
|
||||
DeleteIcons bool
|
||||
}{current, models.MinuteGranularity, deleteIcons}
|
||||
}{current, b.config.Date.MinuteGranularity, deleteIcons}
|
||||
Templates.ExecuteTemplate(&celldata, "td.html", data)
|
||||
tableBody += celldata.String()
|
||||
}
|
||||
|
|
40
main.go
40
main.go
|
@ -1,42 +1,47 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
"log/syslog"
|
||||
"net/http"
|
||||
"os"
|
||||
"sprechstundentool/config"
|
||||
"sprechstundentool/controllers"
|
||||
"sprechstundentool/repositories"
|
||||
"sprechstundentool/sqldb"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func main() {
|
||||
logwriter, e := syslog.New(syslog.LOG_ERR, "sprechstunden")
|
||||
logwriter, e := syslog.New(syslog.LOG_ERR, "office hours")
|
||||
if e == nil {
|
||||
log.SetOutput(logwriter)
|
||||
}
|
||||
|
||||
var db *sql.DB
|
||||
switch os.Getenv("ohtDbType") {
|
||||
case "mysql":
|
||||
db = sqldb.ConnectMysql(os.Getenv("ohtDbMysqlConnection"))
|
||||
default:
|
||||
if os.Getenv("ohtDbFile") != "" && !strings.Contains(os.Getenv("ohtDbFile"), "/") {
|
||||
db = sqldb.ConnectSQLite(os.Getenv("ohtDbFile"))
|
||||
} else {
|
||||
db = sqldb.ConnectSQLite("sprechstunden.db")
|
||||
}
|
||||
configFile := flag.String(
|
||||
"config",
|
||||
"config/config.json",
|
||||
"File path to the configuration file")
|
||||
flag.Parse()
|
||||
if *configFile == "" {
|
||||
flag.Usage()
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
var conf config.Config
|
||||
err := config.ReadConfigFile(*configFile, &conf)
|
||||
if err != nil {
|
||||
log.Fatalf("%s: %s", "Reading JSON config file into config structure", err)
|
||||
}
|
||||
|
||||
db := sqldb.Connect(conf)
|
||||
// Create repos
|
||||
roomRepo := repositories.NewRoomRepo(db)
|
||||
courseRepo := repositories.NewCourseRepo(db)
|
||||
tutorRepo := repositories.NewTutorRepo(db)
|
||||
officeHourRepo := repositories.NewOfficeHourRepo(db, roomRepo, tutorRepo, courseRepo)
|
||||
requestRepo := repositories.NewRequestRepo(db, officeHourRepo)
|
||||
h := controllers.NewBaseHandler(roomRepo, officeHourRepo, courseRepo, tutorRepo, requestRepo)
|
||||
requestRepo := repositories.NewRequestRepo(db, officeHourRepo, conf)
|
||||
h := controllers.NewBaseHandler(roomRepo, officeHourRepo, courseRepo, tutorRepo, requestRepo, conf)
|
||||
|
||||
http.HandleFunc("/getByRoom", h.GetByRoomHandler)
|
||||
http.HandleFunc("/getByCourse", h.GetByCourseHandler)
|
||||
|
@ -45,5 +50,6 @@ func main() {
|
|||
http.HandleFunc("/deleteOfficeHour", h.DeleteOfficeHourHandler)
|
||||
http.HandleFunc("/", h.RootHandler)
|
||||
|
||||
http.ListenAndServe(":8080", nil)
|
||||
err = http.ListenAndServe(fmt.Sprintf("%s:%d", conf.Server.ListenAddress, conf.Server.ListenPort), nil)
|
||||
fmt.Println(err.Error())
|
||||
}
|
||||
|
|
|
@ -8,8 +8,6 @@ type Date struct {
|
|||
Minute int
|
||||
}
|
||||
|
||||
const MinuteGranularity int = 5
|
||||
|
||||
func DayName(day int) string {
|
||||
switch day {
|
||||
case 0:
|
||||
|
|
|
@ -11,8 +11,6 @@ type Request struct {
|
|||
const RequestActivate int = 1
|
||||
const RequestDelete int = 2
|
||||
|
||||
const SecretLength int = 15
|
||||
|
||||
type RequestRepository interface {
|
||||
Add(officeHour OfficeHour, action int) (int, error)
|
||||
FindBySecret(secret string) (Request, error)
|
||||
|
|
|
@ -114,7 +114,10 @@ func (r *OfficeHourRepo) Add(officeHour models.OfficeHour) (id int, err error) {
|
|||
|
||||
func (r *OfficeHourRepo) Delete(officeHour models.OfficeHour) error {
|
||||
_, err := r.db.Exec("DELETE FROM officeHour WHERE id=?", officeHour.Id)
|
||||
return fmt.Errorf("Error deleting officeHour from database: %s", err.Error())
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error deleting officeHour from database: %s", err.Error())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *OfficeHourRepo) getFromRow(row *sql.Row) (models.OfficeHour, error) {
|
||||
|
|
|
@ -5,8 +5,11 @@ import (
|
|||
"bytes"
|
||||
"crypto/rand"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"log"
|
||||
"math/big"
|
||||
"net/smtp"
|
||||
"sprechstundentool/config"
|
||||
"sprechstundentool/controllers"
|
||||
"sprechstundentool/models"
|
||||
)
|
||||
|
@ -14,12 +17,14 @@ import (
|
|||
type RequestRepo struct {
|
||||
db *sql.DB
|
||||
officeHourRepo models.OfficeHourRepository
|
||||
config config.Config
|
||||
}
|
||||
|
||||
func NewRequestRepo(db *sql.DB, officeHourRepo models.OfficeHourRepository) *RequestRepo {
|
||||
func NewRequestRepo(db *sql.DB, officeHourRepo models.OfficeHourRepository, config config.Config) *RequestRepo {
|
||||
return &RequestRepo{
|
||||
db: db,
|
||||
officeHourRepo: officeHourRepo,
|
||||
config: config,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -68,8 +73,8 @@ func (r *RequestRepo) Add(officeHour models.OfficeHour, action int) (int, error)
|
|||
* but don't insert new request into database.
|
||||
*/
|
||||
for _, request := range existents {
|
||||
if request.Action == action { // already covered by selection && request.OfficeHour == officeHour {
|
||||
return request.Id, sendConfirmationMail(request)
|
||||
if request.Action == action { // already covered by selection: && request.OfficeHour == officeHour {
|
||||
return request.Id, r.sendConfirmationMail(request)
|
||||
}
|
||||
}
|
||||
secret, err := r.newSecret()
|
||||
|
@ -85,7 +90,7 @@ func (r *RequestRepo) Add(officeHour models.OfficeHour, action int) (int, error)
|
|||
if err != nil {
|
||||
return request.Id, err
|
||||
}
|
||||
return request.Id, sendConfirmationMail(request)
|
||||
return request.Id, r.sendConfirmationMail(request)
|
||||
}
|
||||
|
||||
func (r *RequestRepo) Execute(request models.Request) error {
|
||||
|
@ -104,29 +109,42 @@ func (r *RequestRepo) Execute(request models.Request) error {
|
|||
}
|
||||
|
||||
func (r *RequestRepo) newSecret() (string, error) {
|
||||
secret := randomString(models.SecretLength)
|
||||
|
||||
_, err := r.FindBySecret(secret)
|
||||
if err != nil && err != sql.ErrNoRows {
|
||||
return "", err
|
||||
}
|
||||
var err error
|
||||
var secret string
|
||||
// find unused secret
|
||||
for err != sql.ErrNoRows {
|
||||
secret = randomString(models.SecretLength)
|
||||
secret = randomString(r.config.Request.SecretLength)
|
||||
_, err = r.FindBySecret(secret)
|
||||
if err != nil && err != sql.ErrNoRows {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
return secret, nil
|
||||
}
|
||||
|
||||
func sendConfirmationMail(request models.Request) error {
|
||||
to := []string{request.OfficeHour.Tutor.Email}
|
||||
func (r *RequestRepo) sendConfirmationMail(request models.Request) error {
|
||||
var message bytes.Buffer
|
||||
err := controllers.Templates.ExecuteTemplate(&message, "confirmationMail", request)
|
||||
var data = struct {
|
||||
Config config.Config
|
||||
Request models.Request
|
||||
}{r.config, request}
|
||||
err := controllers.Templates.ExecuteTemplate(&message, "confirmationMail", data)
|
||||
if err != nil {
|
||||
log.Printf("Error parsing confirmation Mail: %s", err.Error())
|
||||
return err
|
||||
}
|
||||
err = smtp.SendMail("192.168.0.24:25", nil, "Mathebau Sprechstunden <sprechstunden@mathebau.de>", to, message.Bytes())
|
||||
return err
|
||||
switch r.config.Mailer.Type {
|
||||
case "Stdout":
|
||||
fmt.Println(message.String())
|
||||
case "Smtp":
|
||||
to := []string{request.OfficeHour.Tutor.Email}
|
||||
var auth smtp.Auth
|
||||
if r.config.Mailer.SmtpUseAuth {
|
||||
auth = smtp.PlainAuth(r.config.Mailer.SmtpIdentity, r.config.Mailer.FromAddress, r.config.Mailer.SmtpPassword, r.config.Mailer.SmtpHost)
|
||||
}
|
||||
return smtp.SendMail(fmt.Sprintf("%s:%d", r.config.Mailer.SmtpHost, r.config.Mailer.SmtpPort), auth, string(r.config.Mailer.FromName), to, message.Bytes())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func randomString(n int) string {
|
||||
|
|
|
@ -2,13 +2,31 @@ package sqldb
|
|||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"log"
|
||||
"sprechstundentool/config"
|
||||
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
_ "github.com/mattn/go-sqlite3"
|
||||
)
|
||||
|
||||
func ConnectSQLite(file string) *sql.DB {
|
||||
func Connect(config config.Config) *sql.DB {
|
||||
switch config.SQL.Type {
|
||||
case "SQLite":
|
||||
return connectSQLite(config.SQL.SQLiteFile)
|
||||
case "Mysql":
|
||||
return connectMysql(config.SQL.MysqlUser,
|
||||
config.SQL.MysqlPassword,
|
||||
config.SQL.MysqlHost,
|
||||
config.SQL.MysqlPort,
|
||||
config.SQL.MysqlDatabase)
|
||||
default:
|
||||
log.Fatal("Type of database not recognised.")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func connectSQLite(file string) *sql.DB {
|
||||
db, err := sql.Open("sqlite3", file)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
|
@ -17,16 +35,16 @@ func ConnectSQLite(file string) *sql.DB {
|
|||
return db
|
||||
}
|
||||
|
||||
func ConnectMysql(connection string) *sql.DB {
|
||||
db, err := sql.Open("mysql", connection)
|
||||
func connectMysql(user string, password string, address string, port int, database string) *sql.DB {
|
||||
db, err := sql.Open("mysql", fmt.Sprintf("%s:%s@tcp(%s:%d)/%s", user, password, address, port, database))
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
log.Fatalf("Error connecting to database: %s", err)
|
||||
}
|
||||
|
||||
err = db.Ping()
|
||||
// handle error
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
log.Fatalf("Error pinging database: %s", err)
|
||||
}
|
||||
return db
|
||||
}
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
From: Mathebau Sprechstunden <sprechstunden@mathebau.de>
|
||||
To: {{.OfficeHour.Tutor.Email}}
|
||||
Subject: Sprechstunde {{if eq .Action 1}}anlegen{{end}}{{if eq .Action 2}}löschen{{end}}
|
||||
From: {{.Config.Mailer.FromName}}
|
||||
To: {{.Request.OfficeHour.Tutor.Email}}
|
||||
Subject: Sprechstunde {{if eq .Request.Action 1}}anlegen{{end}}{{if eq .Request.Action 2}}löschen{{end}}
|
||||
|
||||
Hallo {{.OfficeHour.Tutor.Name}},
|
||||
Hallo {{.Request.OfficeHour.Tutor.Name}},
|
||||
|
||||
mit deiner Emailadresse soll eine Sprechstunde mit folgenden Daten {{if eq .Action 1}}angelegt werden{{end}}{{if eq .Action 2}}gelöscht werden{{end}}:
|
||||
mit deiner Emailadresse soll eine Sprechstunde mit folgenden Daten {{if eq .Request.Action 1}}angelegt werden{{end}}{{if eq .Request.Action 2}}gelöscht werden{{end}}:
|
||||
|
||||
{{.OfficeHour.Course.Name}}
|
||||
{{DayName .OfficeHour.Date.Day}}
|
||||
{{printf "%02d" .OfficeHour.Date.Hour}}:{{printf "%02d" .OfficeHour.Date.Minute}} Uhr bis {{printf "%02d" .OfficeHour.EndDate.Hour}}:{{printf "%02d" .OfficeHour.EndDate.Minute}} Uhr
|
||||
{{.OfficeHour.Tutor.Name}}
|
||||
{{.OfficeHour.Room.Name}}
|
||||
{{.Request.OfficeHour.Course.Name}}
|
||||
{{DayName .Request.OfficeHour.Date.Day}}
|
||||
{{printf "%02d" .Request.OfficeHour.Date.Hour}}:{{printf "%02d" .Request.OfficeHour.Date.Minute}} Uhr bis {{printf "%02d" .Request.OfficeHour.EndDate.Hour}}:{{printf "%02d" .Request.OfficeHour.EndDate.Minute}} Uhr
|
||||
{{.Request.OfficeHour.Tutor.Name}}
|
||||
{{.Request.OfficeHour.Room.Name}}
|
||||
|
||||
Falls dies richtig ist, so bestätige die Sprechstunde durch Abrufen der folgenden URL:
|
||||
https://sprechstunden.mathebau.de/confirmRequest?code={{.Secret}}
|
||||
{{.Config.Server.Protocol}}://{{.Config.Server.Domain}}/confirmRequest?code={{.Request.Secret}}
|
||||
Solltest du diese Email nicht erwartet haben, so kannst du sie einfach ignorieren.
|
||||
|
||||
Deine Fachschaft Mathematik
|
Loading…
Reference in a new issue