Personal Git forge.
package appimport ( md "farga/app/middleware" "farga/db/types" "farga/lib" "fmt" "net/http" "strconv" "github.com/gorilla/mux")// /{user}/{repo}/issuesfunc (a *App) RepoIssuesIndex(w http.ResponseWriter, r *http.Request) { repo := r.Context().Value(md.RepoKey).(types.Repo) a.renderRepo(w, r, "issues/list", RepoViewOptions{ View: "issues", DB: &repo, Issues: repo.Issues, })}type repoNewIssueForm struct { Title string `form:"title" validate:"required,min=10"` Description string `form:"description" validate:"required,min=30,max=3000"` SubmitAnonymously bool `form:"submit_anonymously" validate:"boolean"`}type createIssueCommentForm struct { Comment string `form:"comment" validate:"required,min=10,max=3000"`}func (a *App) repoIssueReport(w http.ResponseWriter, r *http.Request) { repo := r.Context().Value(md.RepoKey).(types.Repo) loggedIn := r.Context().Value(lib.LoggedInKey).(bool) allowAnonymousIssues := repo.Config.AllowAnonymousIssues allowNewIssues := repo.Config.AllowNewIssues if !allowNewIssues { http.Error(w, "This repository is not accepting new issues.", http.StatusForbidden) return } if !loggedIn && !allowAnonymousIssues { http.Error(w, "This repository is not accepting anonymous issues.", http.StatusForbidden) return } switch r.Method { case "GET": a.renderRepo(w, r, "issues/report", RepoViewOptions{ View: "issues", DB: &repo, }) case "POST": form, _ := md.Form[repoNewIssueForm](r) // check if the submiter went overboard if len(form.Title) > lib.IssueTitleMaxLen { http.Redirect(w, r, lib.RepoRoot(repo)+"?err=IssueTitleTooLong", http.StatusSeeOther) return } if len(form.Description) > lib.IssueDescriptionMaxLen { http.Redirect(w, r, lib.RepoRoot(repo)+"?err=IssueDescriptionTooLong", http.StatusTemporaryRedirect) return } var issue = types.Issue{ RepoID: &repo.ID, Title: form.Title, Description: form.Description, } if !form.SubmitAnonymously { user, ok := r.Context().Value(lib.UserKey).(*types.User) if ok { issue.UserID = &user.ID // claim ownership } else { // requester wanted to submit as a registered user, but they weren't logged in. http.Redirect(w, r, "/auth/login?err=RequireAuth", http.StatusSeeOther) return } } err := a.Store.NewIssue(&issue) if err != nil { fmt.Println(err) http.Error(w, "Something went wrong while creating your issue.", http.StatusInternalServerError) return } http.Redirect(w, r, fmt.Sprintf("%s/%s/%d", lib.RepoRoot(repo), "issues", issue.IssueID), http.StatusSeeOther) default: http.Error(w, "nuh uh. Method not allowed.", http.StatusMethodNotAllowed) }}func (a *App) repoIssueClose(w http.ResponseWriter, r *http.Request) { repo := r.Context().Value(md.RepoKey).(types.Repo) issueNumber, err := strconv.ParseUint(mux.Vars(r)["issueID"], 10, 32) if err != nil { http.NotFound(w, r) return } issue, err := a.Store.Issue(&repo, uint(issueNumber)) if err != nil { http.NotFound(w, r) return } if err := a.Store.CloseIssue(&issue); err != nil { fmt.Println(err) http.Error(w, "Oops.", http.StatusInternalServerError) return } http.Redirect(w, r, fmt.Sprintf("%s/issues/%d", lib.RepoRoot(repo), issue.IssueID), http.StatusSeeOther)}func (a *App) repoIssueView(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) repo := r.Context().Value(md.RepoKey).(types.Repo) issueNumber, err := strconv.ParseUint(vars["issueID"], 10, 32) if err != nil { http.NotFound(w, r) return } issue, err := a.Store.Issue(&repo, uint(issueNumber)) if err != nil { http.NotFound(w, r) return } switch r.Method { case "GET": comments, err := a.Store.IssueComments(issue.ID) if err != nil { http.Error(w, "Oops.", http.StatusInternalServerError) return } a.renderRepo(w, r, "issues/view", RepoViewOptions{ DB: &repo, View: "issues", Issue: issue, IssueComments: comments, }) case "POST": form, ok := md.Form[createIssueCommentForm](r) if !ok { http.Error(w, "Something went wrong while processing your request.", http.StatusInternalServerError) return } if len(form.Comment) > lib.IssueCommentMaxLen { http.Redirect(w, r, r.URL.String()+"?err=IssueCommentTooLong", http.StatusSeeOther) return } user, ok := r.Context().Value(lib.UserKey).(*types.User) if !ok || user == nil { // needs to be logged in. http.Redirect(w, r, "/auth/login?err=RequireAuth", http.StatusSeeOther) return } var issueComment = types.IssueComment{ IssueID: &issue.ID, Comment: form.Comment, UserID: &user.ID, } err := a.Store.NewIssueComment(&issueComment) if err != nil { fmt.Println(err) http.Error(w, "Oops.", http.StatusInternalServerError) return } http.Redirect(w, r, r.URL.String(), http.StatusSeeOther) default: http.Error(w, "nuh uh. Method not allowed.", http.StatusMethodNotAllowed) }}