func ArticleListHandler(ctx *app.Context) { data := map[string]interface{}{ "Articles": getArticles(ctx), "Title": ctx.App().Name(), } ctx.MustExecute("list.html", data) }
func signInHandler(ctx *app.Context) { modal := ctx.FormValue("modal") != "" d := data(ctx) if !modal && !d.allowDirectSignIn() && d.hasEnabledSocialSignin() { // Redirect to the only available social sign-in ctx.MustRedirectReverse(false, d.enabledSocialAccountTypes()[0].HandlerName) return } from := ctx.FormValue(app.SignInFromParameterName) signIn := SignIn{From: from} form := form.New(ctx, &signIn) if d.allowDirectSignIn() && form.Submitted() && form.IsValid() { ctx.MustSignIn(asGondolaUser(reflect.ValueOf(signIn.User))) ctx.RedirectBack() return } user, _ := newEmptyUser(ctx) data := map[string]interface{}{ "SocialAccountTypes": d.enabledSocialAccountTypes(), "From": from, "SignInForm": form, "SignUpForm": SignUpForm(ctx, user), "AllowDirectSignIn": d.allowDirectSignIn(), "AllowRegistration": d.allowRegistration(), } tmpl := SignInTemplateName if modal && SignInModalTemplateName != "" { tmpl = SignInModalTemplateName } ctx.MustExecute(tmpl, data) }
func StdListHandler(ctx *app.Context) { dctx := getEnvironment(ctx) allPkgs, err := dctx.ImportPackages(dctx.Join(dctx.Context.GOROOT, "src")) if err != nil { panic(err) } var pkgs []*doc.Package var cmds []*doc.Package for _, v := range allPkgs { if dctx.Base(v.Dir()) == "cmd" { cmds = append(cmds, v) } else { pkgs = append(pkgs, v) } } title := "Go Standard Library" groups := []packageGroup{ {Title: "Go Standard Library", Packages: pkgs}, {Title: "Go Commands", Packages: cmds}, } data := map[string]interface{}{ "Header": title, "Title": title, "Groups": groups, } ctx.MustExecute(PackagesTemplateName, data) }
func windowCallbackHandler(ctx *app.Context, user reflect.Value, callback string) { inWindow := ctx.FormValue("window") != "" if user.IsValid() { ctx.MustSignIn(asGondolaUser(user)) } if inWindow { var payload []byte if user.IsValid() { var err error payload, err = JSONEncode(ctx, user.Interface()) if err != nil { panic(err) } } ctx.MustExecute("js-callback.html", map[string]interface{}{ "Callback": callback, "Payload": payload, }) } else { if user.IsValid() { redirectToFrom(ctx) } else { ctx.MustRedirectReverse(false, app.SignInHandlerName) } } }
func ListHandler(ctx *app.Context) { var groups []*packageGroup dctx := getEnvironment(ctx) for _, gr := range appDocGroups(ctx) { var groupPackages []*doc.Package for _, v := range gr.Packages { pkgs, err := dctx.ImportPackages(packageDir(dctx, v)) if err != nil { log.Errorf("error importing %s: %s", v, err) continue } groupPackages = append(groupPackages, pkgs...) } if len(groupPackages) > 0 { groups = append(groups, &packageGroup{ Title: gr.Title, Packages: groupPackages, }) } } if len(groups) == 0 { ctx.NotFound("no packages to list") return } title := "Package Index" data := map[string]interface{}{ "Header": title, "Title": title, "Groups": groups, } ctx.MustExecute(PackagesTemplateName, data) }
func ArticleHandler(ctx *app.Context) { slug := ctx.IndexValue(0) var art *article.Article articles := getArticles(ctx) for _, v := range articles { if v.Slug() == slug { art = v break } } if art == nil { for _, v := range articles { for _, s := range v.AllSlugs() { if s == slug { ctx.MustRedirectReverse(true, ctx.HandlerName(), s) return } } } ctx.NotFound("article not found") return } fs := vfs.Memory() filename := path.Base(art.Filename) if filename == "" { filename = "article.html" } if err := vfs.WriteFile(fs, filename, art.Text, 0644); err != nil { panic(err) } log.Debugf("loading article %s", articleId(art)) tmpl, err := app.LoadTemplate(ctx.App(), fs, nil, filename) if err != nil { panic(err) } var buf bytes.Buffer if err := tmpl.ExecuteTo(&buf, ctx, nil); err != nil { panic(err) } body := buf.String() data := map[string]interface{}{ "Article": art, "Title": art.Title(), "Body": template.HTML(body), } ctx.MustExecute("article.html", data) }
func ResetHandler(ctx *app.Context) { d := data(ctx) if !d.allowDirectSignIn() { ctx.NotFound("") return } payload := ctx.FormValue("p") var valid bool var expired bool var f *form.Form var user reflect.Value var err error var done bool if payload != "" { user, err = decodeResetPayload(ctx, payload) if err == nil && user.IsValid() { valid = true } else { if err == errResetExpired { expired = true } } } if valid { passwordForm := &PasswordForm{User: user} f = form.New(ctx, passwordForm) if f.Submitted() && f.IsValid() { ctx.Orm().MustSave(user.Interface()) ctx.MustSignIn(asGondolaUser(user)) done = true } } data := map[string]interface{}{ "Valid": valid, "Expired": expired, "Done": done, "User": user, "PasswordForm": f, "Payload": payload, } ctx.MustExecute(ResetTemplateName, data) }
func signUpHandler(ctx *app.Context) { d := data(ctx) if !d.allowDirectSignIn() { ctx.NotFound("") return } from := ctx.FormValue(app.SignInFromParameterName) user, _ := newEmptyUser(ctx) form := SignUpForm(ctx, user) if form.Submitted() && form.IsValid() { saveNewUser(ctx, user) ctx.RedirectBack() return } data := map[string]interface{}{ "From": from, "SignUpForm": form, } ctx.MustExecute(SignUpTemplateName, data) }
func (p *Project) Handler(ctx *app.Context) { if len(p.errors) > 0 { data := map[string]interface{}{ "Project": p, "Errors": p.errors, "Count": len(p.errors), } ctx.MustExecute("errors.html", data) return } if p.runError != nil { // Exited at start s := p.out.String() var errorMessage string if m := panicRe.FindStringSubmatch(s); len(m) > 1 { errorMessage = m[1] } data := map[string]interface{}{ "Project": p, "Error": errorMessage, "ExitCode": p.exitCode, "Output": uncolor(s), } ctx.MustExecute("exited.html", data) return } if p.proxy == nil { // Building if ctx.R.Method == "GET" { data := map[string]interface{}{ "Project": p, "Name": p.Name(), } ctx.MustExecute("building.html", data) return } // Wait until the app starts for { time.Sleep(10 * time.Millisecond) if p.proxy != nil { break } } } for !p.proxyChecked { // Check if we can connect to the app, to make // sure it has really started. conn, err := net.Dial("tcp", fmt.Sprintf("localhost:%d", p.port)) if err == nil { conn.Close() p.proxyChecked = true break } time.Sleep(10 * time.Millisecond) } // Proxy p.proxy.ServeHTTP(ctx, ctx.R) }
func forgotHandler(ctx *app.Context) { d := data(ctx) if !d.allowDirectSignIn() { ctx.NotFound("") return } var user User var isEmail bool var sent bool var fields struct { Username string `form:",singleline,label=Username or Email"` ValidateUsername func(*app.Context) error } fields.ValidateUsername = func(c *app.Context) error { username := Normalize(fields.Username) isEmail = strings.Contains(username, "@") var field string if isEmail { field = "User.NormalizedEmail" } else { field = "User.NormalizedUsername" } userVal, userIface := newEmptyUser(ctx) ok := c.Orm().MustOne(orm.Eq(field, username), userIface) if !ok { if isEmail { return i18n.Errorf("address %q does not belong to any registered user", username) } return i18n.Errorf("username %q does not belong to any registered user", username) } user = getUserValue(userVal, "User").(User) if user.Email == "" { return i18n.Errorf("username %q does not have any registered emails", username) } return nil } f := form.New(ctx, &fields) if f.Submitted() && f.IsValid() { se, err := ctx.App().EncryptSigner(Salt) if err != nil { panic(err) } values := make(url.Values) values.Add("u", strconv.FormatInt(user.Id(), 36)) values.Add("t", strconv.FormatInt(time.Now().Unix(), 36)) values.Add("n", stringutil.Random(64)) payload := values.Encode() p, err := se.EncryptSign([]byte(payload)) if err != nil { panic(err) } abs := ctx.URL() reset := fmt.Sprintf("%s://%s%s?p=%s", abs.Scheme, abs.Host, ctx.MustReverse(ResetHandlerName), p) data := map[string]interface{}{ "URL": reset, } from := mail.DefaultFrom() if from == "" { from = fmt.Sprintf("no-reply@%s", abs.Host) } msg := &mail.Message{ To: user.Email, From: from, Subject: fmt.Sprintf(ctx.T("Reset your %s password"), d.opts.SiteName), } ctx.MustSendMail("reset_password.txt", data, msg) sent = true } data := map[string]interface{}{ "ForgotForm": f, "IsEmail": isEmail, "Sent": sent, "User": user, } ctx.MustExecute(ForgotTemplateName, data) }
func PackageHandler(ctx *app.Context) { dctx := getEnvironment(ctx) rel := ctx.IndexValue(0) if rel[len(rel)-1] == '/' { ctx.MustRedirectReverse(true, PackageHandlerName, rel[:len(rel)-1]) return } pkg, err := dctx.ImportPackage(rel) if err != nil { panic(err) } var title string var header string var distinct bool switch { case pkg.IsMain(): title = "Command " + path.Base(rel) header = title case pkg.IsEmpty(): prefix := "Directory " header = prefix + path.Base(rel) if pkg.ImportPath() != "" { title = prefix + pkg.ImportPath() } else { title = header } default: title = "Package " + pkg.ImportPath() header = "Package " + pkg.Name() distinct = path.Base(pkg.ImportPath()) != pkg.Name() } breadcrumbs := []*breadcrumb{ {Title: "Index", Href: ctx.MustReverse(ListHandlerName)}, } if pkg.IsStd() { breadcrumbs = append(breadcrumbs, &breadcrumb{ Title: "std", Href: ctx.MustReverse(PackageHandlerName, "std"), }) } for ii := 0; ii < len(rel); { var end int slash := strings.IndexByte(rel[ii:], '/') if slash < 0 { end = len(rel) } else { end = ii + slash } breadcrumbs = append(breadcrumbs, &breadcrumb{ Title: rel[ii:end], Href: ctx.MustReverse(PackageHandlerName, rel[:end]), }) ii = end + 1 } data := map[string]interface{}{ "Header": header, "Title": title, "Breadcrumbs": breadcrumbs, "Package": pkg, "Distinct": distinct, } ctx.MustExecute("package.html", data) }
func SourceHandler(ctx *app.Context) { dctx := doc.GetEnvironment(ctx.App()) rel := ctx.IndexValue(0) p := dctx.FromSlash(rel) pDir := dctx.Dir(p) if pDir == "." { pDir = p } else { } dir := packageDir(dctx, pDir) filePath := dir if pDir+dctx.Separator != p && pDir != p { filePath = dctx.Join(dir, dctx.Base(p)) } log.Debugf("Loading source from %s", filePath) var breadcrumbs []*breadcrumb for ii := 0; ii < len(rel); { var end int slash := strings.IndexByte(rel[ii:], '/') if slash < 0 { end = len(rel) } else { end = ii + slash } breadcrumbs = append(breadcrumbs, &breadcrumb{ Title: rel[ii:end], Href: ctx.MustReverse(SourceHandlerName, rel[:end]), }) ii = end + 1 } var tmpl string var title string var files []string var code template.HTML var lines []int if dctx.IsDir(filePath) { if rel != "" && rel[len(rel)-1] != '/' { ctx.MustRedirectReverse(true, SourceHandlerName, rel+"/") return } contents, err := dctx.ReadDir(filePath) if err != nil { panic(err) } for _, v := range contents { if n := v.Name(); len(n) > 0 && n[0] != '.' { files = append(files, n) } } title = "Directory " + dctx.Base(rel) tmpl = "dir.html" } else { f, err := dctx.OpenFile(filePath) if err != nil { ctx.NotFound("File not found") return } defer f.Close() contents, err := ioutil.ReadAll(f) if err != nil { panic(err) } contentType := http.DetectContentType(contents) if !strings.HasPrefix(contentType, "text") { ctx.Header().Set("Content-Type", contentType) switch contentType { case "image/gif", "image/png", "image/jpeg": default: ctx.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=%s;", dctx.Base(rel))) } ctx.Write(contents) return } title = "File " + dctx.Base(rel) var buf bytes.Buffer buf.WriteString("<span id=\"line-1\">") last := 0 line := 1 for ii, v := range contents { if v == '\n' { buf.WriteString(html.Escape(string(contents[last:ii]))) lines = append(lines, line) last = ii line++ buf.WriteString(fmt.Sprintf("</span><span id=\"line-%d\">", line)) } } buf.Write(contents[last:]) buf.WriteString("</span>") code = template.HTML(buf.String()) tmpl = "source.html" } data := map[string]interface{}{ "Title": rel, "Header": title, "Breadcrumbs": breadcrumbs, "Files": files, "Code": code, "Lines": lines, "Padding": math.Ceil(math.Log10(float64(len(lines)+1))) + 0.1, "Highlighter": highlighters[path.Ext(rel)], } ctx.MustExecute(tmpl, data) }