|
- package controllers
-
- import (
- "fmt"
- "html/template"
- "net/http"
- "strings"
- "time"
-
- "git.kirsle.net/apps/gophertype/pkg/authentication"
- "git.kirsle.net/apps/gophertype/pkg/console"
- "git.kirsle.net/apps/gophertype/pkg/glue"
- "git.kirsle.net/apps/gophertype/pkg/mail"
- "git.kirsle.net/apps/gophertype/pkg/markdown"
- "git.kirsle.net/apps/gophertype/pkg/models"
- "git.kirsle.net/apps/gophertype/pkg/responses"
- "git.kirsle.net/apps/gophertype/pkg/session"
- "git.kirsle.net/apps/gophertype/pkg/settings"
- "github.com/albrow/forms"
- "github.com/gorilla/mux"
- "github.com/kirsle/blog/src/log"
- )
-
- func init() {
- glue.Register(glue.Endpoint{
- Path: "/ask",
- Methods: []string{"GET", "POST"},
- Handler: QuestionHandler,
- })
- glue.Register(glue.Endpoint{
- Path: "/ask/answer",
- Methods: []string{"POST"},
- Middleware: []mux.MiddlewareFunc{
- authentication.LoginRequired,
- },
- Handler: AnswerHandler,
- })
- }
-
- // QuestionHandler implements the "Ask Me Anything" at the URL "/ask"
- func QuestionHandler(w http.ResponseWriter, r *http.Request) {
- var (
- v = responses.NewTemplateVars(w, r)
- ses = session.Get(r)
- )
-
- // Load their cached name from any previous comments they may have posted.
- name, _ := ses.Values["c.name"].(string)
-
- q := models.Questions.New()
- q.Name = name
-
- for r.Method == http.MethodPost {
- form, _ := forms.Parse(r)
- q.ParseForm(r)
-
- // Validate form parameters.
- val := form.Validator()
- val.Require("question")
- if val.HasErrors() {
- v.ValidationError = val.ErrorMap()
- v.V["Error"] = "Missing required form fields."
- break
- }
-
- // Cache their name in their session for future comments/asks.
- ses.Values["c.name"] = q.Name
- ses.Save(r, w)
-
- // Save the question.
- err := q.Save()
- if err != nil {
- log.Error("Error saving neq eustion: %s", err)
- responses.Error(w, r, http.StatusInternalServerError, "Error saving question: "+err.Error())
- return
- }
-
- // Email the site admin.
- if name == "" {
- name = "Anonymous"
- }
- subject := fmt.Sprintf("Ask Me Anything (%s) from %s", settings.Current.Title, name)
- go mail.EmailAdmins(mail.Email{
- Subject: subject,
- Template: "_builtin/email/generic.gohtml",
- Data: map[string]interface{}{
- "Subject": subject,
- "Message": template.HTML(
- markdown.RenderMarkdown(fmt.Sprintf(
- "%s\n\nAnswer this at %s",
- q.Question,
- strings.TrimSuffix(settings.Current.BaseURL, "/")+"/ask",
- )),
- ),
- },
- })
-
- session.Flash(w, r, "Your question has been recorded!")
- responses.Redirect(w, r, "/ask")
- return
- }
-
- // If logged in, load the pending questions.
- if authentication.LoggedIn(r) {
- pending, err := models.Questions.Pending()
- if err != nil {
- console.Error("Error loading pending questions: %s", err)
- }
- v.V["Pending"] = pending
- }
-
- // Load the recently answered questions for public users.
- recent, err := models.Questions.RecentlyAnswered(10)
- if err != nil {
- console.Error("Error loading recently answered questions: %s", err)
- }
-
- v.V["Q"] = q
- v.V["Recent"] = recent
- responses.RenderTemplate(w, r, "_builtin/questions.gohtml", v)
- }
-
- // AnswerHandler handles answering (and deleting) questions.
- func AnswerHandler(w http.ResponseWriter, r *http.Request) {
- v := responses.NewTemplateVars(w, r)
-
- CurrentUser, _ := authentication.CurrentUser(r)
-
- // Validate form parameters.
- form, _ := forms.Parse(r)
- val := form.Validator()
- val.Require("id")
- val.Require("answer")
- val.Require("submit")
- if val.HasErrors() {
- v.ValidationError = val.ErrorMap()
- v.V["Error"] = "Missing required form fields."
- responses.RenderTemplate(w, r, "_builtin/questions.gohtml", v)
- return
- }
-
- // Look up the question.
- q, err := models.Questions.Load(form.GetInt("id"))
- if err != nil {
- responses.Error(w, r, http.StatusInternalServerError, err.Error())
- return
- }
-
- // Handle submit actions.
- switch form.Get("submit") {
- case "answer":
- // Prepare a Markdown themed blog post for this answer.
- name := q.Name
- if name == "" {
- name = "Anonymous"
- }
-
- post := models.Post{
- Title: "Ask",
- ContentType: "markdown",
- Privacy: models.Public,
- EnableComments: true,
- AuthorID: CurrentUser.ID,
- Tags: []models.TaggedPost{
- models.TaggedPost{Tag: "ask"},
- },
- Fragment: fmt.Sprintf("ask-%s",
- time.Now().Format("20060102150405"),
- ),
- Body: fmt.Sprintf(
- "> **%s** asks:\n\n> %s\n\n%s\n",
- name,
- strings.Replace(q.Question, "\n", "\n> ", 0),
- form.Get("answer"),
- ),
- }
- post.Save()
-
- // Associate the question to this post ID.
- q.PostID = post.ID
- q.Answered = true
- q.Save()
-
- // Send the admin to the post edit page.
- responses.Redirect(w, r, "/"+post.Fragment)
- case "delete":
- q.Delete()
- session.Flash(w, r, "Question deleted!")
- responses.Redirect(w, r, "/ask")
- default:
- responses.BadRequest(w, r, "Invalid submit method.")
- }
- }
|