Beispiel #1
0
func ArticleListHandler(ctx *app.Context) {
	data := map[string]interface{}{
		"Articles": getArticles(ctx),
		"Title":    ctx.App().Name(),
	}
	ctx.MustExecute("list.html", data)
}
Beispiel #2
0
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)
}
Beispiel #3
0
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)
}
Beispiel #4
0
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)
		}
	}
}
Beispiel #5
0
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)
}
Beispiel #6
0
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)
}
Beispiel #7
0
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)
}
Beispiel #8
0
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)
}
Beispiel #9
0
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)
}
Beispiel #10
0
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)
}
Beispiel #11
0
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)
}
Beispiel #12
0
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)
}