blog/src/controllers/events/events.go

150 lines
3.7 KiB
Go

package events
import (
"fmt"
"net/http"
"sort"
"github.com/gorilla/mux"
"github.com/kirsle/blog/src/log"
"github.com/kirsle/blog/src/middleware/auth"
"github.com/kirsle/blog/src/render"
"github.com/kirsle/blog/src/responses"
"github.com/kirsle/blog/models/comments"
"github.com/kirsle/blog/models/events"
"github.com/urfave/negroni"
)
// Register the blog routes to the app.
func Register(r *mux.Router, loginError http.HandlerFunc) {
// Login-required routers.
loginRouter := mux.NewRouter()
loginRouter.HandleFunc("/e/admin/edit", editHandler)
loginRouter.HandleFunc("/e/admin/invite/{id}", inviteHandler)
loginRouter.HandleFunc("/e/admin/", indexHandler)
r.PathPrefix("/e/admin").Handler(
negroni.New(
negroni.HandlerFunc(auth.LoginRequired(loginError)),
negroni.Wrap(loginRouter),
),
)
// Public routes
r.HandleFunc("/e/{fragment}", viewHandler)
r.HandleFunc("/c/logout", contactLogoutHandler)
r.HandleFunc("/c/{secret}", contactAuthHandler)
}
// Admin index to view all events.
func indexHandler(w http.ResponseWriter, r *http.Request) {
result, err := events.All()
if err != nil {
log.Error("error listing all events: %s", err)
}
sort.Sort(sort.Reverse(events.ByDate(result)))
render.Template(w, r, "events/index", map[string]interface{}{
"events": result,
})
}
// User handler to view a single event page.
func viewHandler(w http.ResponseWriter, r *http.Request) {
params := mux.Vars(r)
fragment, ok := params["fragment"]
if !ok {
responses.NotFound(w, r, "Not Found")
return
}
event, err := events.LoadFragment(fragment)
if err != nil {
responses.FlashAndRedirect(w, r, "/", "Event Not Found")
return
}
// Template variables.
v := map[string]interface{}{
"event": event,
"authedRSVP": events.RSVP{},
}
// Sort the guest list.
sort.Sort(events.ByName(event.RSVP))
// Is the browser session authenticated as a contact?
authedContact, err := AuthedContact(r)
if err == nil {
v["authedContact"] = authedContact
// Do they have an RSVP?
for _, rsvp := range event.RSVP {
if rsvp.ContactID == authedContact.ID {
v["authedRSVP"] = rsvp
break
}
}
}
// Count up the RSVP statuses, and also look for the authed contact's RSVP.
var (
countGoing int
countMaybe int
countNotGoing int
countInvited int
)
for _, rsvp := range event.RSVP {
if authedContact.ID != 0 && rsvp.ContactID == authedContact.ID {
v["authedRVSP"] = rsvp
}
switch rsvp.Status {
case events.StatusGoing:
countGoing++
case events.StatusMaybe:
countMaybe++
case events.StatusNotGoing:
countNotGoing++
default:
countInvited++
}
}
v["countGoing"] = countGoing
v["countMaybe"] = countMaybe
v["countNotGoing"] = countNotGoing
v["countInvited"] = countInvited
// If we're posting, are we RSVPing?
if r.Method == http.MethodPost {
action := r.PostFormValue("action")
switch action {
case "answer-rsvp":
// Subscribe them to the comment thread on this page if we have an email.
if authedContact.Email != "" {
thread := fmt.Sprintf("event-%d", event.ID)
log.Info("events.viewHandler: subscribe email %s to thread %s", authedContact.Email, thread)
ml := comments.LoadMailingList()
ml.Subscribe(thread, authedContact.Email)
}
answer := r.PostFormValue("submit")
for _, rsvp := range event.RSVP {
if rsvp.ContactID == authedContact.ID {
log.Info("Mark RSVP status %s for contact %s", answer, authedContact.Name())
rsvp.Status = answer
rsvp.Save()
responses.FlashAndReload(w, r, "You have confirmed '%s' for your RSVP.", answer)
return
}
}
default:
responses.FlashAndReload(w, r, "Invalid form action.")
}
responses.FlashAndReload(w, r, "Unknown error.")
return
}
render.Template(w, r, "events/view", v)
}