// 对一些堂量的基本检测。 func TestConsts(t *testing.T) { a := assert.New(t) a.True(is.URL(RepoURL)) a.True(is.URL(OfficialURL)) a.True(version.SemVerValid(Version)) }
// 对一些堂量的基本检测。 func TestConsts(t *testing.T) { a := assert.New(t) a.True(version.SemVerValid(Version)) a.True(len(Name) > 0) a.True(is.URL(RepoURL)) a.True(is.URL(OfficialURL)) a.True(len(ConfigFilename) > 0).True(strings.IndexAny(ConfigFilename, "/\\") < 0) a.True(len(DefaultTitle) > 0) a.True(len(DefaultGroupName) > 0).True(strings.IndexAny(DefaultGroupName, "/\\") < 0) a.True(len(Profile) > 0).True(strings.IndexAny(Profile, "/\\") < 0) tag, err := language.Parse(DefaultLocale) a.NotError(err).NotEqual(tag, language.Und) }
// @api post /api/posts/{id}/comments 提交新评论 // @apiGroup front // // @apiRequest json // @apiParam parent int 评论的父级内容 // @apiParam postID int 评论的文章 // @apiParam content string 评论的内容 // @apiParam authorName string 评论的作者 // @apiParam authorURL string 评论作者的网站地址,可为空 // @apiParam authorEmail string 评论作者的邮箱 // // @apiSuccess 201 created func frontPostPostComment(w http.ResponseWriter, r *http.Request) { c := &struct { Parent int64 `json:"parent"` PostID int64 `json:"postID"` Content string `json:"content"` AuthorName string `json:"authorName"` AuthorURL string `json:"authorURL"` AuthorEmail string `json:"authorEmail"` }{} if !util.ReadJSON(w, r, c) { return } // 判断文章状态 if c.PostID <= 0 { util.RenderJSON(w, http.StatusNotFound, nil, nil) return } p := &models.Post{ID: c.PostID} if err := db.Select(p); err != nil { logs.Error("forntPostPostComment:", err) util.RenderJSON(w, http.StatusInternalServerError, nil, nil) return } if (len(p.Title) == 0 && len(p.Content) == 0) || p.State != models.PostStatePublished { util.RenderJSON(w, http.StatusNotFound, nil, nil) return } if !p.AllowComment { util.RenderJSON(w, http.StatusMethodNotAllowed, nil, nil) return } // 判断提交数据的状态 errs := &util.ErrorResult{} if c.Parent < 0 { errs.Detail["parent"] = "无效的parent" } if len(c.Content) == 0 { errs.Detail["content"] = "content不能为空" } if len(c.AuthorURL) > 0 && !is.URL(c.AuthorURL) { errs.Detail["authorURL"] = "无效的authorURL" } if !is.Email(c.AuthorEmail) { errs.Detail["authorEmail"] = "无效的authorEmail" } if len(c.AuthorName) == 0 { errs.Detail["authorName"] = "authorName不能为空" } c.AuthorName = html.EscapeString(c.AuthorName) // url只提取其host部分,其余的都去掉 u, err := url.Parse(c.AuthorURL) if err != nil { logs.Error("frontPostComment:", err) util.RenderJSON(w, http.StatusInternalServerError, nil, nil) return } c.AuthorURL = u.Scheme + ":" + u.Host c.Content = html.EscapeString(c.Content) c.Content = strings.Replace(c.Content, "\n", "<br />", -1) comm := &models.Comment{ PostID: c.PostID, Parent: c.Parent, AuthorURL: c.AuthorURL, AuthorName: c.AuthorName, AuthorEmail: c.AuthorEmail, Content: c.Content, Created: time.Now().Unix(), State: models.CommentStateWaiting, IP: r.RemoteAddr, Agent: r.UserAgent(), IsAdmin: false, } if _, err := db.Insert(comm); err != nil { logs.Error("frontPostComment:", err) util.RenderJSON(w, http.StatusInternalServerError, nil, nil) return } util.RenderJSON(w, http.StatusCreated, nil, nil) }
// 解析 @apidoc 及其子标签 // // @apidoc title of doc // @apiVersion 2.0 // @apiBaseURL https://api.caixw.io // @apiLicense MIT https://opensource.org/licenses/MIT // // @apiContent // content1 // content2 func (l *lexer) scanAPIDoc(d *Doc) *app.SyntaxError { if len(d.Title) > 0 || len(d.Version) > 0 { return l.syntaxError("重复的 @apidoc 标签:title=" + d.Title + ",Version=" + d.Version) } t := l.readTag() d.Title = t.readLine() if len(d.Title) == 0 { return l.syntaxError("@apidoc 未指定标题") } if !t.atEOF() { return l.syntaxError("@apidoc 过多的参数") } LOOP: for { switch { case l.matchTag("@apiVersion"): t := l.readTag() d.Version = t.readLine() if len(d.Version) == 0 { return t.syntaxError("@apiVersion 未指定参数") } if !t.atEOF() { return t.syntaxError("@apiVersion 过多的参数") } case l.matchTag("@apiBaseURL"): t := l.readTag() d.BaseURL = t.readLine() if len(d.BaseURL) == 0 { return t.syntaxError("@apiBaseURL 未指定参数") } if !t.atEOF() { return t.syntaxError("@apiBaseURL 过多的参数") } case l.matchTag("@apiLicense"): t := l.readTag() d.LicenseName = t.readWord() d.LicenseURL = t.readLine() if len(d.LicenseName) == 0 { return t.syntaxError("@apiLicense 缺少必要的参数") } if len(d.LicenseURL) > 0 && !is.URL(d.LicenseURL) { return t.syntaxError("@apiLicense 第二个参数必须为一个 URL") } if !t.atEOF() { return t.syntaxError("@apiLicense 过多的参数") } case l.matchTag("@apiContent"): d.Content = string(l.data[l.pos:]) case l.match("@api"): l.backup() return l.syntaxError("不认识的标签" + l.readWord()) default: if l.atEOF() { break LOOP } l.pos++ // 去掉无用的字符。 } } return nil }
// 解析 @apidoc 及其子标签 // // @apidoc title of doc // @apiVersion 2.0 // @apiBaseURL https://api.caixw.io // @apiLicense MIT https://opensource.org/licenses/MIT // // @apiContent // content1 // content2 func (l *lexer) scanAPIDoc(d *Doc) *app.SyntaxError { if len(d.Title) > 0 || len(d.Version) > 0 { return l.syntaxError(locale.ErrDuplicateTag, "@apidoc") } t := l.readTag() d.Title = t.readLine() if len(d.Title) == 0 { return l.syntaxError(locale.ErrTagArgNotEnough, "@apidoc") } if !t.atEOF() { return l.syntaxError(locale.ErrTagArgTooMuch, "@apidoc") } LOOP: for { switch { case l.matchTag("@apiVersion"): t := l.readTag() d.Version = t.readLine() if len(d.Version) == 0 { return t.syntaxError(locale.ErrTagArgNotEnough, "@apiVersion") } if !t.atEOF() { return t.syntaxError(locale.ErrTagArgTooMuch, "@apiVersion") } case l.matchTag("@apiBaseURL"): t := l.readTag() d.BaseURL = t.readLine() if len(d.BaseURL) == 0 { return t.syntaxError(locale.ErrTagArgNotEnough, "@apiBaseURL") } if !t.atEOF() { return t.syntaxError(locale.ErrTagArgTooMuch, "@apiBaseURL") } case l.matchTag("@apiLicense"): t := l.readTag() d.LicenseName = t.readWord() d.LicenseURL = t.readLine() if len(d.LicenseName) == 0 { return t.syntaxError(locale.ErrTagArgNotEnough, "@apiLicense") } if len(d.LicenseURL) > 0 && !is.URL(d.LicenseURL) { return t.syntaxError(locale.ErrSecondArgMustURL) } if !t.atEOF() { return t.syntaxError(locale.ErrTagArgTooMuch, "@apiLicense") } case l.matchTag("@apiContent"): d.Content = string(l.data[l.pos:]) case l.match("@api"): l.backup() return l.syntaxError(locale.ErrUnknownTag, l.readWord()) default: if l.atEOF() { break LOOP } l.pos++ // 去掉无用的字符。 } } return nil }