mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-31 21:28:11 +09:00 
			
		
		
		
	Clean api code
This commit is contained in:
		
							
								
								
									
										13
									
								
								cmd/dump.go
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								cmd/dump.go
									
									
									
									
									
								
							| @@ -5,9 +5,11 @@ | ||||
| package cmd | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"log" | ||||
| 	"os" | ||||
| 	"path" | ||||
| 	"time" | ||||
|  | ||||
| 	"github.com/Unknwon/cae/zip" | ||||
| 	"github.com/codegangsta/cli" | ||||
| @@ -43,11 +45,12 @@ func runDump(*cli.Context) { | ||||
| 		log.Fatalf("Fail to dump database: %v", err) | ||||
| 	} | ||||
|  | ||||
| 	fileName := fmt.Sprintf("gogs-dump-%d.zip", time.Now().Unix()) | ||||
| 	log.Printf("Packing dump files...") | ||||
| 	z, err := zip.Create("gogs-dump.zip") | ||||
| 	z, err := zip.Create(fileName) | ||||
| 	if err != nil { | ||||
| 		os.Remove("gogs-dump.zip") | ||||
| 		log.Fatalf("Fail to create gogs-dump.zip: %v", err) | ||||
| 		os.Remove(fileName) | ||||
| 		log.Fatalf("Fail to create %s: %v", fileName, err) | ||||
| 	} | ||||
|  | ||||
| 	execDir, _ := base.ExecDir() | ||||
| @@ -56,8 +59,8 @@ func runDump(*cli.Context) { | ||||
| 	z.AddFile("custom/conf/app.ini", path.Join(execDir, "custom/conf/app.ini")) | ||||
| 	z.AddDir("log", path.Join(execDir, "log")) | ||||
| 	if err = z.Close(); err != nil { | ||||
| 		os.Remove("gogs-dump.zip") | ||||
| 		log.Fatalf("Fail to save gogs-dump.zip: %v", err) | ||||
| 		os.Remove(fileName) | ||||
| 		log.Fatalf("Fail to save %s: %v", fileName, err) | ||||
| 	} | ||||
|  | ||||
| 	log.Println("Finish dumping!") | ||||
|   | ||||
							
								
								
									
										15
									
								
								cmd/web.go
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								cmd/web.go
									
									
									
									
									
								
							| @@ -15,6 +15,7 @@ import ( | ||||
| 	qlog "github.com/qiniu/log" | ||||
|  | ||||
| 	"github.com/gogits/gogs/modules/auth" | ||||
| 	"github.com/gogits/gogs/modules/auth/apiv1" | ||||
| 	"github.com/gogits/gogs/modules/avatar" | ||||
| 	"github.com/gogits/gogs/modules/base" | ||||
| 	"github.com/gogits/gogs/modules/log" | ||||
| @@ -54,7 +55,10 @@ func runWeb(*cli.Context) { | ||||
| 	m := newMartini() | ||||
|  | ||||
| 	// Middlewares. | ||||
| 	m.Use(middleware.Renderer(middleware.RenderOptions{Funcs: []template.FuncMap{base.TemplateFuncs}})) | ||||
| 	m.Use(middleware.Renderer(middleware.RenderOptions{ | ||||
| 		Funcs:      []template.FuncMap{base.TemplateFuncs}, | ||||
| 		IndentJSON: true, | ||||
| 	})) | ||||
| 	m.Use(middleware.InitContext()) | ||||
|  | ||||
| 	reqSignIn := middleware.Toggle(&middleware.ToggleOptions{SignInRequire: true}) | ||||
| @@ -76,10 +80,15 @@ func runWeb(*cli.Context) { | ||||
|  | ||||
| 	m.Group("/api/v1", func(r martini.Router) { | ||||
| 		// Miscellaneous. | ||||
| 		r.Post("/markdown", v1.Markdown) | ||||
| 		r.Post("/markdown", bindIgnErr(apiv1.MarkdownForm{}), v1.Markdown) | ||||
| 		r.Post("/markdown/raw", v1.MarkdownRaw) | ||||
|  | ||||
| 		// Users. | ||||
| 		r.Get("/users/search", v1.SearchUser) | ||||
|  | ||||
| 		r.Any("**", func(ctx *middleware.Context) { | ||||
| 			ctx.JSON(404, &base.ApiJsonErr{"Not Found", v1.DOC_URL}) | ||||
| 		}) | ||||
| 	}) | ||||
|  | ||||
| 	avt := avatar.CacheServer("public/img/avatar/", "public/img/avatar_default.jpg") | ||||
| @@ -87,7 +96,7 @@ func runWeb(*cli.Context) { | ||||
| 	m.Get("/avatar/:hash", avt.ServeHTTP) | ||||
|  | ||||
| 	m.Group("/user", func(r martini.Router) { | ||||
| 		r.Get("/login", user.SignIn) | ||||
| 		r.Get("/login", user.SignIn) // TODO | ||||
| 		r.Post("/login", bindIgnErr(auth.LogInForm{}), user.SignInPost) | ||||
| 		r.Get("/login/:name", user.SocialSignIn) | ||||
| 		r.Get("/sign_up", user.SignUp) | ||||
|   | ||||
							
								
								
									
										89
									
								
								modules/auth/apiv1/miscellaneous.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								modules/auth/apiv1/miscellaneous.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,89 @@ | ||||
| // Copyright 2014 The Gogs Authors. All rights reserved. | ||||
| // Use of this source code is governed by a MIT-style | ||||
| // license that can be found in the LICENSE file. | ||||
|  | ||||
| package apiv1 | ||||
|  | ||||
| import ( | ||||
| 	"net/http" | ||||
| 	"reflect" | ||||
|  | ||||
| 	"github.com/go-martini/martini" | ||||
|  | ||||
| 	"github.com/gogits/gogs/modules/auth" | ||||
| 	"github.com/gogits/gogs/modules/base" | ||||
| 	"github.com/gogits/gogs/modules/log" | ||||
| 	"github.com/gogits/gogs/modules/middleware/binding" | ||||
| ) | ||||
|  | ||||
| type MarkdownForm struct { | ||||
| 	Text    string `form:"text" binding:"Required"` | ||||
| 	Mode    string `form:"mode"` | ||||
| 	Context string `form:"context"` | ||||
| } | ||||
|  | ||||
| func (f *MarkdownForm) Name(field string) string { | ||||
| 	names := map[string]string{ | ||||
| 		"Text": "text", | ||||
| 	} | ||||
| 	return names[field] | ||||
| } | ||||
|  | ||||
| func (f *MarkdownForm) Validate(errs *binding.BindingErrors, req *http.Request, ctx martini.Context) { | ||||
| 	data := ctx.Get(reflect.TypeOf(base.TmplData{})).Interface().(base.TmplData) | ||||
| 	validateApiReq(errs, data, f) | ||||
| } | ||||
|  | ||||
| func validateApiReq(errs *binding.BindingErrors, data base.TmplData, f auth.Form) { | ||||
| 	if errs.Count() == 0 { | ||||
| 		return | ||||
| 	} else if len(errs.Overall) > 0 { | ||||
| 		for _, err := range errs.Overall { | ||||
| 			log.Error("%s: %v", reflect.TypeOf(f), err) | ||||
| 		} | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	data["HasError"] = true | ||||
|  | ||||
| 	typ := reflect.TypeOf(f) | ||||
| 	val := reflect.ValueOf(f) | ||||
|  | ||||
| 	if typ.Kind() == reflect.Ptr { | ||||
| 		typ = typ.Elem() | ||||
| 		val = val.Elem() | ||||
| 	} | ||||
|  | ||||
| 	for i := 0; i < typ.NumField(); i++ { | ||||
| 		field := typ.Field(i) | ||||
|  | ||||
| 		fieldName := field.Tag.Get("form") | ||||
| 		// Allow ignored fields in the struct | ||||
| 		if fieldName == "-" { | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		if err, ok := errs.Fields[field.Name]; ok { | ||||
| 			data["Err_"+field.Name] = true | ||||
| 			switch err { | ||||
| 			case binding.BindingRequireError: | ||||
| 				data["ErrorMsg"] = f.Name(field.Name) + " cannot be empty" | ||||
| 			case binding.BindingAlphaDashError: | ||||
| 				data["ErrorMsg"] = f.Name(field.Name) + " must be valid alpha or numeric or dash(-_) characters" | ||||
| 			case binding.BindingAlphaDashDotError: | ||||
| 				data["ErrorMsg"] = f.Name(field.Name) + " must be valid alpha or numeric or dash(-_) or dot characters" | ||||
| 			case binding.BindingMinSizeError: | ||||
| 				data["ErrorMsg"] = f.Name(field.Name) + " must contain at least " + auth.GetMinMaxSize(field) + " characters" | ||||
| 			case binding.BindingMaxSizeError: | ||||
| 				data["ErrorMsg"] = f.Name(field.Name) + " must contain at most " + auth.GetMinMaxSize(field) + " characters" | ||||
| 			case binding.BindingEmailError: | ||||
| 				data["ErrorMsg"] = f.Name(field.Name) + " is not a valid e-mail address" | ||||
| 			case binding.BindingUrlError: | ||||
| 				data["ErrorMsg"] = f.Name(field.Name) + " is not a valid URL" | ||||
| 			default: | ||||
| 				data["ErrorMsg"] = "Unknown error: " + err | ||||
| 			} | ||||
| 			return | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| @@ -91,7 +91,7 @@ func (f *LogInForm) Validate(errors *binding.BindingErrors, req *http.Request, c | ||||
| 	validate(errors, data, f) | ||||
| } | ||||
|  | ||||
| func getMinMaxSize(field reflect.StructField) string { | ||||
| func GetMinMaxSize(field reflect.StructField) string { | ||||
| 	for _, rule := range strings.Split(field.Tag.Get("binding"), ";") { | ||||
| 		if strings.HasPrefix(rule, "MinSize(") || strings.HasPrefix(rule, "MaxSize(") { | ||||
| 			return rule[8 : len(rule)-1] | ||||
| @@ -128,9 +128,9 @@ func validate(errors *binding.BindingErrors, data base.TmplData, form Form) { | ||||
| 			case binding.BindingAlphaDashDotError: | ||||
| 				data["ErrorMsg"] = form.Name(field.Name) + " must be valid alpha or numeric or dash(-_) or dot characters" | ||||
| 			case binding.BindingMinSizeError: | ||||
| 				data["ErrorMsg"] = form.Name(field.Name) + " must contain at least " + getMinMaxSize(field) + " characters" | ||||
| 				data["ErrorMsg"] = form.Name(field.Name) + " must contain at least " + GetMinMaxSize(field) + " characters" | ||||
| 			case binding.BindingMaxSizeError: | ||||
| 				data["ErrorMsg"] = form.Name(field.Name) + " must contain at most " + getMinMaxSize(field) + " characters" | ||||
| 				data["ErrorMsg"] = form.Name(field.Name) + " must contain at most " + GetMinMaxSize(field) + " characters" | ||||
| 			case binding.BindingEmailError: | ||||
| 				data["ErrorMsg"] = form.Name(field.Name) + " is not a valid e-mail address" | ||||
| 			case binding.BindingUrlError: | ||||
|   | ||||
| @@ -7,6 +7,11 @@ package base | ||||
| type ( | ||||
| 	// Type TmplData represents data in the templates. | ||||
| 	TmplData map[string]interface{} | ||||
|  | ||||
| 	ApiJsonErr struct { | ||||
| 		Message string `json:"message"` | ||||
| 		DocUrl  string `json:"documentation_url"` | ||||
| 	} | ||||
| ) | ||||
|  | ||||
| var GoGetMetas = make(map[string]bool) | ||||
|   | ||||
| @@ -132,9 +132,7 @@ func RenderSpecialLink(rawBytes []byte, urlPrefix string) []byte { | ||||
| 	return rawBytes | ||||
| } | ||||
|  | ||||
| func RenderMarkdown(rawBytes []byte, urlPrefix string) []byte { | ||||
| 	body := RenderSpecialLink(rawBytes, urlPrefix) | ||||
| 	// fmt.Println(string(body)) | ||||
| func RenderRawMarkdown(body []byte, urlPrefix string) []byte { | ||||
| 	htmlFlags := 0 | ||||
| 	// htmlFlags |= gfm.HTML_USE_XHTML | ||||
| 	// htmlFlags |= gfm.HTML_USE_SMARTYPANTS | ||||
| @@ -163,7 +161,12 @@ func RenderMarkdown(rawBytes []byte, urlPrefix string) []byte { | ||||
| 	extensions |= gfm.EXTENSION_NO_EMPTY_LINE_BEFORE_BLOCK | ||||
|  | ||||
| 	body = gfm.Markdown(body, renderer, extensions) | ||||
| 	// fmt.Println(string(body)) | ||||
| 	return body | ||||
| } | ||||
|  | ||||
| func RenderMarkdown(rawBytes []byte, urlPrefix string) []byte { | ||||
| 	body := RenderSpecialLink(rawBytes, urlPrefix) | ||||
| 	body = RenderRawMarkdown(body, urlPrefix) | ||||
| 	return body | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -21,23 +21,21 @@ type ToggleOptions struct { | ||||
|  | ||||
| func Toggle(options *ToggleOptions) martini.Handler { | ||||
| 	return func(ctx *Context) { | ||||
| 		// Cannot view any page before installation. | ||||
| 		if !base.InstallLock { | ||||
| 			ctx.Redirect("/install") | ||||
| 			return | ||||
| 		} | ||||
|  | ||||
| 		// Redirect to dashboard if user tries to visit any non-login page. | ||||
| 		if options.SignOutRequire && ctx.IsSigned && ctx.Req.RequestURI != "/" { | ||||
| 			ctx.Redirect("/") | ||||
| 			return | ||||
| 		} | ||||
|  | ||||
| 		if !options.DisableCsrf { | ||||
| 			if ctx.Req.Method == "POST" { | ||||
| 				if !ctx.CsrfTokenValid() { | ||||
| 					ctx.Error(403, "CSRF token does not match") | ||||
| 					return | ||||
| 				} | ||||
| 			} | ||||
| 		if !options.DisableCsrf && ctx.Req.Method == "POST" && !ctx.CsrfTokenValid() { | ||||
| 			ctx.Error(403, "CSRF token does not match") | ||||
| 			return | ||||
| 		} | ||||
|  | ||||
| 		if options.SignInRequire { | ||||
|   | ||||
| @@ -78,6 +78,19 @@ func (ctx *Context) Query(name string) string { | ||||
| // 	return ctx.p[name] | ||||
| // } | ||||
|  | ||||
| // HasError returns true if error occurs in form validation. | ||||
| func (ctx *Context) HasApiError() bool { | ||||
| 	hasErr, ok := ctx.Data["HasError"] | ||||
| 	if !ok { | ||||
| 		return false | ||||
| 	} | ||||
| 	return hasErr.(bool) | ||||
| } | ||||
|  | ||||
| func (ctx *Context) GetErrMsg() string { | ||||
| 	return ctx.Data["ErrorMsg"].(string) | ||||
| } | ||||
|  | ||||
| // HasError returns true if error occurs in form validation. | ||||
| func (ctx *Context) HasError() bool { | ||||
| 	hasErr, ok := ctx.Data["HasError"] | ||||
|   | ||||
| @@ -62,6 +62,12 @@ var Gogits = { | ||||
|             var method = $(this).data('ajax-method') || 'get'; | ||||
|             var ajaxName = $(this).data('ajax-name'); | ||||
|             var data = {}; | ||||
|  | ||||
|             if (ajaxName.endsWith("preview")) { | ||||
|                 data["mode"] = "gfm"; | ||||
|                 data["context"] = $(this).data('ajax-context'); | ||||
|             } | ||||
|  | ||||
|             $('[data-ajax-rel=' + ajaxName + ']').each(function () { | ||||
|                 var field = $(this).data("ajax-field"); | ||||
|                 var t = $(this).data("ajax-val"); | ||||
| @@ -547,10 +553,8 @@ function initIssue() { | ||||
|     (function () { | ||||
|         $('[data-ajax-name=issue-preview]').on("click", function () { | ||||
|             var $this = $(this); | ||||
|             $this.toggleAjax(function (json) { | ||||
|                 if (json.ok) { | ||||
|                     $($this.data("preview")).html(json.content); | ||||
|                 } | ||||
|             $this.toggleAjax(function (resp) { | ||||
|                 $($this.data("preview")).html(resp); | ||||
|             }) | ||||
|         }); | ||||
|         $('.issue-write a[data-toggle]').on("click", function () { | ||||
|   | ||||
| @@ -5,14 +5,38 @@ | ||||
| package v1 | ||||
|  | ||||
| import ( | ||||
| 	"io/ioutil" | ||||
| 	"strings" | ||||
|  | ||||
| 	"github.com/gogits/gogs/modules/auth/apiv1" | ||||
| 	"github.com/gogits/gogs/modules/base" | ||||
| 	"github.com/gogits/gogs/modules/middleware" | ||||
| ) | ||||
|  | ||||
| func Markdown(ctx *middleware.Context) { | ||||
| 	content := ctx.Query("content") | ||||
| 	ctx.Render.JSON(200, map[string]interface{}{ | ||||
| 		"ok":      true, | ||||
| 		"content": string(base.RenderMarkdown([]byte(content), ctx.Query("repoLink"))), | ||||
| 	}) | ||||
| const DOC_URL = "http://gogs.io/docs" | ||||
|  | ||||
| // Render an arbitrary Markdown document. | ||||
| func Markdown(ctx *middleware.Context, form apiv1.MarkdownForm) { | ||||
| 	if ctx.HasApiError() { | ||||
| 		ctx.JSON(422, base.ApiJsonErr{ctx.GetErrMsg(), DOC_URL}) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	switch form.Mode { | ||||
| 	case "gfm": | ||||
| 		ctx.Write(base.RenderMarkdown([]byte(form.Text), | ||||
| 			base.AppUrl+strings.TrimPrefix(form.Context, "/"))) | ||||
| 	default: | ||||
| 		ctx.Write(base.RenderRawMarkdown([]byte(form.Text), "")) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Render a Markdown document in raw mode. | ||||
| func MarkdownRaw(ctx *middleware.Context) { | ||||
| 	body, err := ioutil.ReadAll(ctx.Req.Body) | ||||
| 	if err != nil { | ||||
| 		ctx.JSON(422, base.ApiJsonErr{err.Error(), DOC_URL}) | ||||
| 		return | ||||
| 	} | ||||
| 	ctx.Write(base.RenderRawMarkdown(body, "")) | ||||
| } | ||||
|   | ||||
| @@ -24,9 +24,19 @@ func Home(ctx *middleware.Context) { | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	repos, _ := models.GetRecentUpdatedRepositories() | ||||
| 	// Show recent updated repositoires for new visiters. | ||||
| 	repos, err := models.GetRecentUpdatedRepositories() | ||||
| 	if err != nil { | ||||
| 		ctx.Handle(500, "dashboard.Home(GetRecentUpdatedRepositories)", err) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	for _, repo := range repos { | ||||
| 		repo.Owner, _ = models.GetUserById(repo.OwnerId) | ||||
| 		repo.Owner, err = models.GetUserById(repo.OwnerId) | ||||
| 		if err != nil { | ||||
| 			ctx.Handle(500, "dashboard.Home(GetUserById)", err) | ||||
| 			return | ||||
| 		} | ||||
| 	} | ||||
| 	ctx.Data["Repos"] = repos | ||||
| 	ctx.Data["PageIsHome"] = true | ||||
|   | ||||
| @@ -78,7 +78,7 @@ func Install(ctx *middleware.Context, form auth.InstallForm) { | ||||
| 	ctx.Data["Title"] = "Install" | ||||
| 	ctx.Data["PageIsInstall"] = true | ||||
|  | ||||
| 	// Get and assign value to install form. | ||||
| 	// Get and assign values to install form. | ||||
| 	if len(form.Host) == 0 { | ||||
| 		form.Host = models.DbCfg.Host | ||||
| 	} | ||||
| @@ -109,11 +109,11 @@ func Install(ctx *middleware.Context, form auth.InstallForm) { | ||||
| 	} | ||||
|  | ||||
| 	renderDbOption(ctx) | ||||
| 	curDbValue := "" | ||||
| 	curDbOp := "" | ||||
| 	if models.EnableSQLite3 { | ||||
| 		curDbValue = "SQLite3" // Default when enabled. | ||||
| 		curDbOp = "SQLite3" // Default when enabled. | ||||
| 	} | ||||
| 	ctx.Data["CurDbValue"] = curDbValue | ||||
| 	ctx.Data["CurDbOption"] = curDbOp | ||||
|  | ||||
| 	auth.AssignForm(form, ctx.Data) | ||||
| 	ctx.HTML(200, "install") | ||||
| @@ -129,7 +129,7 @@ func InstallPost(ctx *middleware.Context, form auth.InstallForm) { | ||||
| 	ctx.Data["PageIsInstall"] = true | ||||
|  | ||||
| 	renderDbOption(ctx) | ||||
| 	ctx.Data["CurDbValue"] = form.Database | ||||
| 	ctx.Data["CurDbOption"] = form.Database | ||||
|  | ||||
| 	if ctx.HasError() { | ||||
| 		ctx.HTML(200, "install") | ||||
| @@ -157,7 +157,7 @@ func InstallPost(ctx *middleware.Context, form auth.InstallForm) { | ||||
| 	if err := models.NewTestEngine(x); err != nil { | ||||
| 		if strings.Contains(err.Error(), `Unknown database type: sqlite3`) { | ||||
| 			ctx.RenderWithErr("Your release version does not support SQLite3, please download the official binary version "+ | ||||
| 				"from https://github.com/gogits/gogs/wiki/Install-from-binary, NOT the gobuild version.", "install", &form) | ||||
| 				"from http://gogs.io/docs/installation/install_from_binary.md, NOT the gobuild version.", "install", &form) | ||||
| 		} else { | ||||
| 			ctx.RenderWithErr("Database setting is not correct: "+err.Error(), "install", &form) | ||||
| 		} | ||||
|   | ||||
| @@ -4,6 +4,6 @@ | ||||
|         <li class="list-group-item{{if .PageIsUsers}} active{{end}}"><a href="/admin/users"><i class="fa fa-users fa-lg"></i> Users</a></li> | ||||
|         <li class="list-group-item{{if .PageIsRepos}} active{{end}}"><a href="/admin/repos"><i class="fa fa-book fa-lg"></i> Repositories</a></li> | ||||
|         <li class="list-group-item{{if .PageIsConfig}} active{{end}}"><a href="/admin/config"><i class="fa fa-cogs fa-lg"></i> Configuration</a></li> | ||||
|         <li class="list-group-item{{if .PageIsAuths}} active{{end}}"><a href="/admin/auths"><i class="fa fa-check-square-o fa-lg"></i> Authentication</a></li> | ||||
|         <li class="list-group-item{{if .PageIsAuths}} active{{end}}"><a href="/admin/auths"><i class="fa fa-certificate fa-lg"></i> Authentication</a></li> | ||||
|     </ul> | ||||
| </div> | ||||
| @@ -3,20 +3,25 @@ | ||||
|         <nav class="nav"> | ||||
|             <a id="nav-logo" class="nav-item pull-left{{if .PageIsHome}} active{{end}}" href="/"><img src="/img/favicon.png" alt="Gogs Logo" id="logo"></a> | ||||
|             <a class="nav-item pull-left{{if .PageIsUserDashboard}} active{{end}}" href="/">Dashboard</a> | ||||
|             <a class="nav-item pull-left{{if .PageIsHelp}} active{{end}}" target="_blank" href="http://gogs.io/docs">Help</a>{{if .IsSigned}} | ||||
|             {{if .HasAccess}}<form class="nav-item pull-left{{if .PageIsNewRepo}} active{{end}}" id="nav-search-form"> | ||||
|             <a class="nav-item pull-left{{if .PageIsHelp}} active{{end}}" target="_blank" href="http://gogs.io/docs">Help</a> | ||||
|             {{if .IsSigned}} | ||||
|             {{if .HasAccess}} | ||||
|             <form class="nav-item pull-left{{if .PageIsNewRepo}} active{{end}}" id="nav-search-form"> | ||||
|                 <div class="input-group"> | ||||
|                     <div class="input-group-btn"> | ||||
|                         <button type="button" class="btn btn-sm btn-default dropdown-toggle" data-toggle="dropdown">{{if .Repository}}This Repository{{else}}All Repositories{{end}} <span class="caret"></span></button> | ||||
|                         <ul class="dropdown-menu"> | ||||
|                             {{if .Repository}}<li><a href="#">This Repository</a></li> | ||||
|                             <li class="divider"></li>{{end}} | ||||
|                             {{if .Repository}} | ||||
|                             <li><a href="#">This Repository</a></li> | ||||
|                             <li class="divider"></li> | ||||
|                             {{end}} | ||||
|                             <li><a href="#">All Repositories</a></li> | ||||
|                         </ul> | ||||
|                     </div> | ||||
|                     <input type="search" class="form-control input-sm" name="q" placeholder="search code, commits and issues"/> | ||||
|                 </div> | ||||
|             </form>{{end}} | ||||
|             </form> | ||||
|             {{end}} | ||||
|             <a id="nav-out" class="nav-item navbar-right navbar-btn btn btn-danger" href="/user/logout/"><i class="fa fa-power-off fa-lg"></i></a> | ||||
|             <a id="nav-avatar" class="nav-item navbar-right{{if .PageIsUserProfile}} active{{end}}" href="{{.SignedUser.HomeLink}}" data-toggle="tooltip" data-placement="bottom" title="{{.SignedUserName}}"> | ||||
|                 <img src="{{.SignedUser.AvatarLink}}?s=28" alt="user-avatar" title="username"/> | ||||
| @@ -33,8 +38,10 @@ | ||||
|                     </ul> | ||||
|                 </div> | ||||
|             </div> | ||||
|             {{else}}<a id="nav-signin" class="nav-item navbar-right navbar-btn btn btn-danger" href="/user/login/" rel="nofollow">Sign In</a> | ||||
|             <a id="nav-signup" class="nav-item navbar-right" href="/user/sign_up/" rel="nofollow">Sign Up</a>{{end}} | ||||
|             {{else}} | ||||
|             <a id="nav-signin" class="nav-item navbar-right navbar-btn btn btn-danger" href="/user/login/" rel="nofollow">Sign In</a> | ||||
|             <a id="nav-signup" class="nav-item navbar-right" href="/user/sign_up/" rel="nofollow">Sign Up</a> | ||||
|             {{end}} | ||||
|         </nav> | ||||
|     </div> | ||||
| </div> | ||||
|   | ||||
| @@ -10,7 +10,7 @@ | ||||
| 	<h5>Here are some recent updated repositories:</h5> | ||||
|     <div class="tab-pane active"> | ||||
|         <ul class="list-unstyled repo-list"> | ||||
|         {{range .Repos}} | ||||
|             {{range .Repos}} | ||||
|             <li> | ||||
|                 <div class="meta pull-right"><!-- <i class="fa fa-star"></i> {{.NumStars}} --> <i class="fa fa-code-fork"></i> {{.NumForks}}</div> | ||||
|                 <h4> | ||||
| @@ -19,7 +19,7 @@ | ||||
|                 <p class="desc">{{.Description}}</p> | ||||
|                 <div class="info">Last updated {{.Updated|TimeSince}}</div> | ||||
|             </li> | ||||
|         {{end}} | ||||
|             {{end}} | ||||
|         </ul> | ||||
|     </div> | ||||
| 	{{end}} | ||||
|   | ||||
| @@ -9,15 +9,15 @@ | ||||
|             <label class="col-md-3 control-label">Database Type: </label> | ||||
|             <div class="col-md-8"> | ||||
|                 <select name="database" id="install-database" class="form-control"> | ||||
|                     {{if .CurDbValue}}<option value="{{.CurDbValue}}">{{.CurDbValue}}</option>{{end}} | ||||
|                     {{if .CurDbOption}}<option value="{{.CurDbOption}}">{{.CurDbOption}}</option>{{end}} | ||||
|                     {{range .DbOptions}} | ||||
|                     {{if not (eq $.CurDbValue .)}}<option value="{{.}}">{{.}}</option>{{end}} | ||||
|                     {{if not (eq $.CurDbOption .)}}<option value="{{.}}" >{{.}}</option>{{end}} | ||||
|                     {{end}} | ||||
|                 </select> | ||||
|             </div> | ||||
|         </div> | ||||
|  | ||||
|         <div class="server-sql {{if eq .CurDbValue "SQLite3"}}hide{{end}}"> | ||||
|         <div class="server-sql {{if eq .CurDbOption "SQLite3"}}hide{{end}}"> | ||||
|             <div class="form-group"> | ||||
|                 <label class="col-md-3 control-label">Host: </label> | ||||
|                 <div class="col-md-8"> | ||||
| @@ -27,7 +27,6 @@ | ||||
|  | ||||
|             <div class="form-group"> | ||||
|                 <label class="col-md-3 control-label">User: </label> | ||||
|  | ||||
|                 <div class="col-md-8"> | ||||
|                     <input name="user" class="form-control" placeholder="Type database username" value="{{.user}}"> | ||||
|                 </div> | ||||
| @@ -35,7 +34,6 @@ | ||||
|  | ||||
|             <div class="form-group"> | ||||
|                 <label class="col-md-3 control-label">Password: </label> | ||||
|  | ||||
|                 <div class="col-md-8"> | ||||
|                     <input name="passwd" type="password" class="form-control" placeholder="Type database password" value="{{.passwd}}"> | ||||
|                 </div> | ||||
| @@ -43,14 +41,13 @@ | ||||
|  | ||||
|             <div class="form-group"> | ||||
|                 <label class="col-md-3 control-label">Database Name: </label> | ||||
|  | ||||
|                 <div class="col-md-8"> | ||||
|                     <input name="database_name" type="text" class="form-control" placeholder="Type mysql database name" value="{{.database_name}}"> | ||||
|                     <p class="help-block">Recommend use INNODB engine with utf8_general_ci charset.</p> | ||||
|                 </div> | ||||
|             </div> | ||||
|  | ||||
|             <div class="form-group pgsql-setting {{if not (eq .CurDbValue "PostgreSQL")}}hide{{end}}"> | ||||
|             <div class="form-group pgsql-setting {{if not (eq .CurDbOption "PostgreSQL")}}hide{{end}}"> | ||||
|                 <label class="col-md-3 control-label">SSL Mode: </label> | ||||
|                 <div class="col-md-8"> | ||||
|                     <select name="ssl_mode" class="form-control"> | ||||
| @@ -62,10 +59,9 @@ | ||||
|             </div> | ||||
|         </div> | ||||
|  | ||||
|         <div class="sqlite-setting {{if not (eq .CurDbValue "SQLite3")}}hide{{end}}"> | ||||
|         <div class="sqlite-setting {{if not (eq .CurDbOption "SQLite3")}}hide{{end}}"> | ||||
|             <div class="form-group"> | ||||
|                 <label class="col-md-3 control-label">Path: </label> | ||||
|  | ||||
|                 <div class="col-md-8"> | ||||
|                     <input name="database_path" class="form-control" placeholder="Type sqlite3 file path" value="{{.database_path}}"> | ||||
|                     <p class="help-block">The file path of SQLite3 database.</p> | ||||
| @@ -78,17 +74,14 @@ | ||||
|         <p class="help-block text-center">General Settings of Gogs</p> | ||||
|         <div class="form-group"> | ||||
|             <label class="col-md-3 control-label">Repository Path: </label> | ||||
|  | ||||
|             <div class="col-md-8"> | ||||
|                 <input name="repo_path" type="text" class="form-control" placeholder="Type your repository directory" value="{{.repo_path}}" required="required"> | ||||
|  | ||||
|                 <p class="help-block">The git copy of each repository is saved in this directory.</p> | ||||
|             </div> | ||||
|         </div> | ||||
|  | ||||
|         <div class="form-group"> | ||||
|             <label class="col-md-3 control-label">Run User: </label> | ||||
|  | ||||
|             <div class="col-md-8"> | ||||
|                 <input name="run_user" type="text" class="form-control" placeholder="Type system user name" value="{{.run_user}}" required="required"> | ||||
|                 <p class="help-block">The user has access to visit and run Gogs.</p> | ||||
| @@ -97,7 +90,6 @@ | ||||
|          | ||||
|         <div class="form-group"> | ||||
|             <label class="col-md-3 control-label">Domain: </label> | ||||
|  | ||||
|             <div class="col-md-8"> | ||||
|                 <input name="domain" type="text" class="form-control" placeholder="Type your domain name" value="{{.domain}}" required="required"> | ||||
|                 <p class="help-block">This affects SSH clone URL.</p> | ||||
| @@ -106,7 +98,6 @@ | ||||
|          | ||||
|         <div class="form-group"> | ||||
|             <label class="col-md-3 control-label">App URL: </label> | ||||
|  | ||||
|             <div class="col-md-8"> | ||||
|                 <input name="app_url" type="text" class="form-control" placeholder="Type app root URL" value="{{.app_url}}" required="required"> | ||||
|                 <p class="help-block">This affects HTTP/HTTPS clone URL and somewhere in e-mail.</p> | ||||
| @@ -116,7 +107,7 @@ | ||||
|         <hr/> | ||||
|  | ||||
|         <p class="help-block text-center">Admin Account Settings</p> | ||||
|         <div class="form-group"> | ||||
|         <div class="form-group {{if .Err_AdminName}}has-error has-feedback{{end}}"> | ||||
|             <label class="col-md-3 control-label">Username: </label> | ||||
|             <div class="col-md-8"> | ||||
|                 <input name="admin_name" type="text" class="form-control" placeholder="Type admin user name" value="{{.admin_name}}" required="required"> | ||||
| @@ -152,31 +143,30 @@ | ||||
|                     <div class="modal-header"><h4 class="modal-title">Advanced Options</h4></div> | ||||
|                     <div class="modal-body"> | ||||
|                         <p class="help-block text-center">Email Service Settings</p> | ||||
|  | ||||
|                         <div class="form-group"> | ||||
|                             <label class="col-md-3 control-label">SMTP Host: </label> | ||||
|  | ||||
|                             <div class="col-md-8"> | ||||
|                                 <input name="smtp_host" type="text" class="form-control" placeholder="Type SMTP host address and port" value="{{.smtp_host}}"> | ||||
|                             </div> | ||||
|                         </div> | ||||
|  | ||||
|                         <div class="form-group"> | ||||
|                             <label class="col-md-3 control-label">Username: </label> | ||||
|  | ||||
|                             <div class="col-md-8"> | ||||
|                                 <input name="mailer_user" type="text" class="form-control" placeholder="Type SMTP user e-mail address" value="{{.mailer_user}}"> | ||||
|                             </div> | ||||
|                         </div> | ||||
|  | ||||
|                         <div class="form-group"> | ||||
|                             <label class="col-md-3 control-label">Password: </label> | ||||
|  | ||||
|                             <div class="col-md-8"> | ||||
|                                 <input name="mailer_pwd" type="password" class="form-control" placeholder="Type SMTP user password" value="{{.mailer_pwd}}"> | ||||
|                             </div> | ||||
|                         </div> | ||||
|                         <hr/> | ||||
|                         <p class="text-center help-block">Notification Settings</p> | ||||
|  | ||||
|                         <hr/> | ||||
|  | ||||
|                         <p class="text-center help-block">Notification Settings</p> | ||||
|                         <div class="form-group"> | ||||
|                             <div class="col-md-offset-3 col-md-7"> | ||||
|                                 <div class="checkbox"> | ||||
| @@ -202,7 +192,6 @@ | ||||
|                 </div> | ||||
|             </div> | ||||
|         </div> | ||||
|  | ||||
|     </form> | ||||
| </div> | ||||
| {{template "base/footer" .}} | ||||
|   | ||||
| @@ -20,12 +20,12 @@ | ||||
|                     </div> | ||||
|                     <ul class="nav nav-tabs" data-init="tabs"> | ||||
|                         <li class="active issue-write"><a href="#issue-textarea" data-toggle="tab">Write</a></li> | ||||
|                         <li class="issue-preview"><a href="#issue-preview" data-toggle="tab" data-ajax="/api/v1/markdown?repoLink={{.RepoLink}}" data-ajax-name="issue-preview" data-ajax-method="post" data-preview="#issue-preview">Preview</a></li> | ||||
|                         <li class="issue-preview"><a href="#issue-preview" data-toggle="tab" data-ajax="/api/v1/markdown" data-ajax-name="issue-preview" data-ajax-context="{{.RepoLink}}" data-ajax-method="post" data-preview="#issue-preview">Preview</a></li> | ||||
|                     </ul> | ||||
|                     <div class="tab-content"> | ||||
|                         <div class="tab-pane" id="issue-textarea"> | ||||
|                             <div class="form-group"> | ||||
|                                 <textarea class="form-control" name="content" id="issue-content" rows="10" placeholder="Write some content" data-ajax-rel="issue-preview" data-ajax-val="val" data-ajax-field="content">{{.content}}</textarea> | ||||
|                                 <textarea class="form-control" name="content" id="issue-content" rows="10" placeholder="Write some content" data-ajax-rel="issue-preview" data-ajax-val="val" data-ajax-field="text">{{.content}}</textarea> | ||||
|                             </div> | ||||
|                         </div> | ||||
|                         <div class="tab-pane issue-preview-content" id="issue-preview">loading...</div> | ||||
|   | ||||
| @@ -72,13 +72,13 @@ | ||||
|                                 </div> | ||||
|                                 <ul class="nav nav-tabs" data-init="tabs"> | ||||
|                                     <li class="active issue-write"><a href="#issue-textarea" data-toggle="tab">Write</a></li> | ||||
|                                     <li class="issue-preview"><a href="#issue-preview" data-toggle="tab" data-ajax="/api/v1/markdown?repoLink={{.RepoLink}}" data-ajax-name="issue-preview" data-ajax-method="post" data-preview="#issue-preview">Preview</a></li> | ||||
|                                     <li class="issue-preview"><a href="#issue-preview" data-toggle="tab" data-ajax="/api/v1/markdown" data-ajax-name="issue-preview"  data-ajax-context="{{.RepoLink}}" data-ajax-method="post" data-preview="#issue-preview">Preview</a></li> | ||||
|                                 </ul> | ||||
|                                 <div class="tab-content"> | ||||
|                                     <div class="tab-pane" id="issue-textarea"> | ||||
|                                         <div class="form-group"> | ||||
|                                             <input type="hidden" value="{{.Issue.Index}}" name="issueIndex"/> | ||||
|                                             <textarea class="form-control" name="content" id="issue-reply-content" rows="10" placeholder="Write some content" data-ajax-rel="issue-preview" data-ajax-val="val" data-ajax-field="content">{{.content}}</textarea> | ||||
|                                             <textarea class="form-control" name="content" id="issue-reply-content" rows="10" placeholder="Write some content" data-ajax-rel="issue-preview" data-ajax-val="val" data-ajax-field="text">{{.content}}</textarea> | ||||
|                                         </div> | ||||
|                                     </div> | ||||
|                                     <div class="tab-pane issue-preview-content" id="issue-preview">Loading...</div> | ||||
|   | ||||
| @@ -6,56 +6,55 @@ | ||||
|     {{template "repo/setting_nav" .}} | ||||
|     <div id="repo-setting-container" class="col-md-10"> | ||||
|         {{template "base/alert" .}} | ||||
|         <div class="panel panel-default"> | ||||
|             <div class="panel-heading"> | ||||
|                 Add Webhook | ||||
|             </div> | ||||
|             <div class="panel-body"> | ||||
|                 <p>We’ll send a POST request to the URL below with details of any subscribed events.</p> | ||||
|                 <hr/> | ||||
|                 <form id="repo-hooks-add-form" action="/{{.Owner.Name}}/{{.Repository.Name}}/settings/hooks/add" method="post" class="col-md-7"> | ||||
|                     <div class="form-group"> | ||||
|                         <label for="payload-url">Payload URL</label> | ||||
|                         <input id="payload-url" class="form-control" type="url" required="required" name="url"/> | ||||
|                     </div> | ||||
|                     <div class="form-group"> | ||||
|                         <label for="payload-version">Payload Version</label> | ||||
|                         <select name="version" id="payload-version" class="form-control"> | ||||
|                             <option value="json">application/json</option> | ||||
|                         </select> | ||||
|                     </div> | ||||
|                     <div class="form-group"> | ||||
|                         <label for="payload-secret">Secret</label> | ||||
|                         <input id="payload-secret" class="form-control" type="text" required="required" name="secret"/> | ||||
|                     </div> | ||||
|                     <hr/> | ||||
|                     <div class="form-group"> | ||||
|                         <label>Which events would you like to trigger this webhook?</label> | ||||
|                         <div class="radio"> | ||||
|         <form id="repo-hooks-add-form" action="/{{.Owner.Name}}/{{.Repository.Name}}/settings/hooks/add" method="post"> | ||||
|             <div class="panel panel-default"> | ||||
|                 <div class="panel-heading"> | ||||
|                     Add Webhook | ||||
|                 </div> | ||||
|  | ||||
|                 <div class="panel-body"> | ||||
|                     <div class="col-md-7"> | ||||
|                         <p>We’ll send a POST request to the URL below with details of any subscribed events.</p> | ||||
|                         <hr/> | ||||
|                         <div class="form-group"> | ||||
|                             <label for="payload-url">Payload URL</label> | ||||
|                             <input id="payload-url" class="form-control" type="url" required="required" name="url"/> | ||||
|                         </div> | ||||
|                         <div class="form-group"> | ||||
|                             <label for="payload-version">Payload Version</label> | ||||
|                             <select name="version" id="payload-version" class="form-control"> | ||||
|                                 <option value="json">application/json</option> | ||||
|                             </select> | ||||
|                         </div> | ||||
|                         <div class="form-group"> | ||||
|                             <label for="payload-secret">Secret</label> | ||||
|                             <input id="payload-secret" class="form-control" type="text" required="required" name="secret"/> | ||||
|                         </div> | ||||
|                         <hr/> | ||||
|                         <div class="form-group"> | ||||
|                             <label>Which events would you like to trigger this webhook?</label> | ||||
|                             <div class="radio"> | ||||
|                                 <label> | ||||
|                                     <input class="form-control" type="radio" value="push" checked name="trigger"/> Just the <i>push</i> event. | ||||
|                                 </label> | ||||
|                             </div> | ||||
|                         </div> | ||||
|                         <hr/> | ||||
|                         <div class="form-group"> | ||||
|                             <label> | ||||
|                                 <input class="form-control" type="radio" value="push" name="trigger"/> Just the <i>push</i> event. | ||||
|                                 <input type="checkbox" name="active" value="Active" checked/>   | ||||
|                                 Active | ||||
|                             </label> | ||||
|                             <p class="help-block">We will deliver event details when this hook is triggered.</p> | ||||
|                         </div> | ||||
|                     </div> | ||||
|                     <hr/> | ||||
|                     <div class="form-group"> | ||||
|                         <label> | ||||
|                             <input type="checkbox" name="active" value="Active" checked/>   | ||||
|                             Active | ||||
|                         </label> | ||||
|                         <p class="help-block">We will deliver event details when this hook is triggered.</p> | ||||
|                     </div> | ||||
|                     <hr/> | ||||
|                     <div class="form-group"> | ||||
|                         <button class="btn btn-success">Add Webhook</button> | ||||
|                     </div> | ||||
|                 </form> | ||||
|             </div> | ||||
|             <div class="panel-footer"> | ||||
|                 <a href="/{{.Owner.Name}}/{{.Repository.Name}}/settings/hooks"><button class="btn btn-primary">Webhooks List</button></a> | ||||
|             </div> | ||||
|         </div> | ||||
|                 </div> | ||||
|  | ||||
|                 <div class="panel-footer"> | ||||
|                     <button class="btn btn-success">Add Webhook</button> | ||||
|                 </div> | ||||
|             </div> | ||||
|         </form> | ||||
|     </div> | ||||
| </div> | ||||
| {{template "base/footer" .}} | ||||
| @@ -11,6 +11,7 @@ | ||||
|                 <div class="panel-heading"> | ||||
|                     Manage Webhook | ||||
|                 </div> | ||||
|  | ||||
|                 <div class="panel-body"> | ||||
|                     <div class="col-md-7"> | ||||
|                         <p>We’ll send a POST request to the URL below with details of any subscribed events.</p> | ||||
| @@ -51,6 +52,7 @@ | ||||
|                         </div> | ||||
|                     </div> | ||||
|                 </div> | ||||
|  | ||||
|                 <div class="panel-footer"> | ||||
|                     <button class="btn btn-primary">Update Webhook</button>   | ||||
|                     <a href="/{{.Owner.Name}}/{{.Repository.Name}}/settings/hooks?remove="><button class="btn btn-danger">Delete Webhook</button></a> | ||||
| @@ -61,6 +63,7 @@ | ||||
|         	  <div class="panel-heading"> | ||||
|         			<h3 class="panel-title">Recent Deliveries</h3> | ||||
|         	  </div> | ||||
|                | ||||
|         	  <div class="panel-body"> | ||||
|         			Coming soon | ||||
|         	  </div> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user