mirror of
https://github.com/thomiceli/opengist.git
synced 2025-06-16 15:17:13 +02:00
Add topics for Gists (#413)
This commit is contained in:
@ -10,8 +10,6 @@ import (
|
||||
"github.com/thomiceli/opengist/internal/web/handlers"
|
||||
"gorm.io/gorm"
|
||||
"html/template"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func AllGists(ctx *context.Context) error {
|
||||
@ -48,35 +46,25 @@ func AllGists(ctx *context.Context) error {
|
||||
currentUserId = 0
|
||||
}
|
||||
|
||||
mode := ctx.GetData("mode")
|
||||
if fromUserStr == "" {
|
||||
urlctx := ctx.Request().URL.Path
|
||||
if strings.HasSuffix(urlctx, "search") {
|
||||
if mode == "search" {
|
||||
ctx.SetData("htmlTitle", ctx.TrH("gist.list.search-results"))
|
||||
ctx.SetData("mode", "search")
|
||||
ctx.SetData("searchQuery", ctx.QueryParam("q"))
|
||||
ctx.SetData("searchQueryUrl", template.URL("&q="+ctx.QueryParam("q")))
|
||||
urlPage = "search"
|
||||
gists, err = db.GetAllGistsFromSearch(currentUserId, ctx.QueryParam("q"), pageInt-1, sort, order)
|
||||
} else if strings.HasSuffix(urlctx, "all") {
|
||||
gists, err = db.GetAllGistsFromSearch(currentUserId, ctx.QueryParam("q"), pageInt-1, sort, order, "")
|
||||
} else if mode == "topics" {
|
||||
ctx.SetData("htmlTitle", ctx.TrH("gist.list.topic-results-topic", ctx.Param("topic")))
|
||||
ctx.SetData("topic", ctx.Param("topic"))
|
||||
urlPage = "topics/" + ctx.Param("topic")
|
||||
gists, err = db.GetAllGistsFromSearch(currentUserId, "", pageInt-1, sort, order, ctx.Param("topic"))
|
||||
} else if mode == "all" {
|
||||
ctx.SetData("htmlTitle", ctx.TrH("gist.list.all"))
|
||||
ctx.SetData("mode", "all")
|
||||
urlPage = "all"
|
||||
gists, err = db.GetAllGistsForCurrentUser(currentUserId, pageInt-1, sort, order)
|
||||
}
|
||||
} else {
|
||||
liked := false
|
||||
forked := false
|
||||
|
||||
liked, err = regexp.MatchString(`/[^/]*/liked`, ctx.Request().URL.Path)
|
||||
if err != nil {
|
||||
return ctx.ErrorRes(500, "Error matching regexp", err)
|
||||
}
|
||||
|
||||
forked, err = regexp.MatchString(`/[^/]*/forked`, ctx.Request().URL.Path)
|
||||
if err != nil {
|
||||
return ctx.ErrorRes(500, "Error matching regexp", err)
|
||||
}
|
||||
|
||||
var fromUser *db.User
|
||||
|
||||
fromUser, err = db.GetUserByUsername(fromUserStr)
|
||||
@ -106,20 +94,17 @@ func AllGists(ctx *context.Context) error {
|
||||
ctx.SetData("countForked", countForked)
|
||||
}
|
||||
|
||||
if liked {
|
||||
if mode == "liked" {
|
||||
urlPage = fromUserStr + "/liked"
|
||||
ctx.SetData("htmlTitle", ctx.TrH("gist.list.all-liked-by", fromUserStr))
|
||||
ctx.SetData("mode", "liked")
|
||||
gists, err = db.GetAllGistsLikedByUser(fromUser.ID, currentUserId, pageInt-1, sort, order)
|
||||
} else if forked {
|
||||
} else if mode == "forked" {
|
||||
urlPage = fromUserStr + "/forked"
|
||||
ctx.SetData("htmlTitle", ctx.TrH("gist.list.all-forked-by", fromUserStr))
|
||||
ctx.SetData("mode", "forked")
|
||||
gists, err = db.GetAllGistsForkedByUser(fromUser.ID, currentUserId, pageInt-1, sort, order)
|
||||
} else {
|
||||
} else if mode == "fromUser" {
|
||||
urlPage = fromUserStr
|
||||
ctx.SetData("htmlTitle", ctx.TrH("gist.list.all-from", fromUserStr))
|
||||
ctx.SetData("mode", "fromUser")
|
||||
gists, err = db.GetAllGistsFromUser(fromUser.ID, currentUserId, pageInt-1, sort, order)
|
||||
}
|
||||
}
|
||||
@ -171,6 +156,7 @@ func Search(ctx *context.Context) error {
|
||||
Filename: meta["filename"],
|
||||
Extension: meta["extension"],
|
||||
Language: meta["language"],
|
||||
Topic: meta["topic"],
|
||||
}, visibleGistsIds, pageInt)
|
||||
if err != nil {
|
||||
return ctx.ErrorRes(500, "Error searching gists", err)
|
||||
|
@ -67,14 +67,14 @@ func ProcessCreate(ctx *context.Context) error {
|
||||
if err != nil {
|
||||
ctx.AddFlash(validator.ValidationMessages(&err, ctx.GetData("locale").(*i18n.Locale)), "error")
|
||||
if isCreate {
|
||||
return ctx.Html("create.html")
|
||||
return ctx.HtmlWithCode(400, "create.html")
|
||||
} else {
|
||||
files, err := gist.Files("HEAD", false)
|
||||
if err != nil {
|
||||
return ctx.ErrorRes(500, "Error fetching files", err)
|
||||
}
|
||||
ctx.SetData("files", files)
|
||||
return ctx.Html("edit.html")
|
||||
return ctx.HtmlWithCode(400, "edit.html")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -43,6 +43,7 @@ func Fork(ctx *context.Context) error {
|
||||
UserID: currentUser.ID,
|
||||
ForkedID: gist.ID,
|
||||
NbFiles: gist.NbFiles,
|
||||
Topics: gist.Topics,
|
||||
}
|
||||
|
||||
if err = newGist.CreateForked(); err != nil {
|
||||
|
@ -54,6 +54,11 @@ func GistJson(ctx *context.Context) error {
|
||||
renderedFiles := render.HighlightFiles(files)
|
||||
ctx.SetData("files", renderedFiles)
|
||||
|
||||
topics, err := gist.GetTopics()
|
||||
if err != nil {
|
||||
return ctx.ErrorRes(500, "Error fetching topics for gist", err)
|
||||
}
|
||||
|
||||
htmlbuf := bytes.Buffer{}
|
||||
w := bufio.NewWriter(&htmlbuf)
|
||||
if err = ctx.Echo().Renderer.Render(w, "gist_embed.html", ctx.DataMap(), ctx); err != nil {
|
||||
@ -80,6 +85,7 @@ func GistJson(ctx *context.Context) error {
|
||||
"created_at": time.Unix(gist.CreatedAt, 0).Format(time.RFC3339),
|
||||
"visibility": gist.VisibilityStr(),
|
||||
"files": renderedFiles,
|
||||
"topics": topics,
|
||||
"embed": map[string]string{
|
||||
"html": htmlbuf.String(),
|
||||
"css": cssUrl,
|
||||
|
@ -405,3 +405,11 @@ func gistNewPushSoftInit(next Handler) Handler {
|
||||
return next(ctx)
|
||||
}
|
||||
}
|
||||
func setAllGistsMode(mode string) Middleware {
|
||||
return func(next Handler) Handler {
|
||||
return func(ctx *context.Context) error {
|
||||
ctx.SetData("mode", mode)
|
||||
return next(ctx)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -179,6 +179,16 @@ func (s *Server) setFuncMap() {
|
||||
_, err := url.ParseRequestURI(s)
|
||||
return err == nil
|
||||
},
|
||||
"topicsToStr": func(topics []db.GistTopic) string {
|
||||
str := ""
|
||||
for i, topic := range topics {
|
||||
if i > 0 {
|
||||
str += " "
|
||||
}
|
||||
str += topic.Topic
|
||||
}
|
||||
return str
|
||||
},
|
||||
}
|
||||
|
||||
t := template.Must(template.New("t").Funcs(fm).ParseFS(templates.Files, "*/*.html"))
|
||||
|
@ -90,17 +90,19 @@ func (s *Server) registerRoutes() {
|
||||
r.Any("/init/*", git.GitHttp, gistNewPushSoftInit)
|
||||
}
|
||||
|
||||
r.GET("/all", gist.AllGists, checkRequireLogin)
|
||||
r.GET("/all", gist.AllGists, checkRequireLogin, setAllGistsMode("all"))
|
||||
|
||||
if index.Enabled() {
|
||||
r.GET("/search", gist.Search, checkRequireLogin)
|
||||
} else {
|
||||
r.GET("/search", gist.AllGists, checkRequireLogin)
|
||||
r.GET("/search", gist.AllGists, checkRequireLogin, setAllGistsMode("search"))
|
||||
}
|
||||
|
||||
r.GET("/:user", gist.AllGists, checkRequireLogin)
|
||||
r.GET("/:user/liked", gist.AllGists, checkRequireLogin)
|
||||
r.GET("/:user/forked", gist.AllGists, checkRequireLogin)
|
||||
r.GET("/:user", gist.AllGists, checkRequireLogin, setAllGistsMode("fromUser"))
|
||||
r.GET("/:user/liked", gist.AllGists, checkRequireLogin, setAllGistsMode("liked"))
|
||||
r.GET("/:user/forked", gist.AllGists, checkRequireLogin, setAllGistsMode("forked"))
|
||||
|
||||
r.GET("/topics/:topic", gist.AllGists, checkRequireLogin, setAllGistsMode("topics"))
|
||||
|
||||
sC := r.SubGroup("/:user/:gistname")
|
||||
{
|
||||
|
@ -131,6 +131,7 @@ func TestAdminUser(t *testing.T) {
|
||||
},
|
||||
Name: []string{"gist1.txt"},
|
||||
Content: []string{"yeah"},
|
||||
Topics: "",
|
||||
}
|
||||
err := s.Request("POST", "/", gist1, 302)
|
||||
require.NoError(t, err)
|
||||
@ -170,6 +171,7 @@ func TestAdminGist(t *testing.T) {
|
||||
},
|
||||
Name: []string{"gist1.txt"},
|
||||
Content: []string{"yeah"},
|
||||
Topics: "",
|
||||
}
|
||||
err := s.Request("POST", "/", gist1, 302)
|
||||
require.NoError(t, err)
|
||||
|
@ -110,6 +110,7 @@ func TestAnonymous(t *testing.T) {
|
||||
},
|
||||
Name: []string{"gist1.txt", "gist2.txt", "gist3.txt"},
|
||||
Content: []string{"yeah", "yeah\ncool", "yeah\ncool gist actually"},
|
||||
Topics: "",
|
||||
}
|
||||
err = s.Request("POST", "/", gist1, 302)
|
||||
require.NoError(t, err)
|
||||
@ -165,6 +166,7 @@ func TestGitOperations(t *testing.T) {
|
||||
Content: []string{
|
||||
"yeah",
|
||||
},
|
||||
Topics: "",
|
||||
}
|
||||
err := s.Request("POST", "/", gist1, 302)
|
||||
require.NoError(t, err)
|
||||
@ -180,6 +182,7 @@ func TestGitOperations(t *testing.T) {
|
||||
Content: []string{
|
||||
"cool",
|
||||
},
|
||||
Topics: "",
|
||||
}
|
||||
err = s.Request("POST", "/", gist2, 302)
|
||||
require.NoError(t, err)
|
||||
@ -195,6 +198,7 @@ func TestGitOperations(t *testing.T) {
|
||||
Content: []string{
|
||||
"super",
|
||||
},
|
||||
Topics: "",
|
||||
}
|
||||
err = s.Request("POST", "/", gist3, 302)
|
||||
require.NoError(t, err)
|
||||
|
@ -21,7 +21,7 @@ func TestGists(t *testing.T) {
|
||||
err = s.Request("GET", "/all", nil, 200)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = s.Request("POST", "/", nil, 200)
|
||||
err = s.Request("POST", "/", nil, 400)
|
||||
require.NoError(t, err)
|
||||
|
||||
gist1 := db.GistDTO{
|
||||
@ -32,6 +32,7 @@ func TestGists(t *testing.T) {
|
||||
},
|
||||
Name: []string{"gist1.txt", "gist2.txt", "gist3.txt"},
|
||||
Content: []string{"yeah", "yeah\ncool", "yeah\ncool gist actually"},
|
||||
Topics: "",
|
||||
}
|
||||
err = s.Request("POST", "/", gist1, 302)
|
||||
require.NoError(t, err)
|
||||
@ -63,8 +64,9 @@ func TestGists(t *testing.T) {
|
||||
},
|
||||
Name: []string{"", "gist2.txt", "gist3.txt"},
|
||||
Content: []string{"", "yeah\ncool", "yeah\ncool gist actually"},
|
||||
Topics: "",
|
||||
}
|
||||
err = s.Request("POST", "/", gist2, 200)
|
||||
err = s.Request("POST", "/", gist2, 400)
|
||||
require.NoError(t, err)
|
||||
|
||||
gist3 := db.GistDTO{
|
||||
@ -75,6 +77,7 @@ func TestGists(t *testing.T) {
|
||||
},
|
||||
Name: []string{""},
|
||||
Content: []string{"yeah"},
|
||||
Topics: "",
|
||||
}
|
||||
err = s.Request("POST", "/", gist3, 302)
|
||||
require.NoError(t, err)
|
||||
@ -86,7 +89,7 @@ func TestGists(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "gistfile1.txt", gist3files[0])
|
||||
|
||||
err = s.Request("POST", "/"+gist1db.User.Username+"/"+gist1db.Uuid+"/edit", nil, 200)
|
||||
err = s.Request("POST", "/"+gist1db.User.Username+"/"+gist1db.Uuid+"/edit", nil, 400)
|
||||
require.NoError(t, err)
|
||||
|
||||
gist1.Name = []string{"gist1.txt"}
|
||||
@ -118,6 +121,7 @@ func TestVisibility(t *testing.T) {
|
||||
},
|
||||
Name: []string{""},
|
||||
Content: []string{"yeah"},
|
||||
Topics: "",
|
||||
}
|
||||
err := s.Request("POST", "/", gist1, 302)
|
||||
require.NoError(t, err)
|
||||
@ -160,6 +164,7 @@ func TestLikeFork(t *testing.T) {
|
||||
},
|
||||
Name: []string{""},
|
||||
Content: []string{"yeah"},
|
||||
Topics: "",
|
||||
}
|
||||
err := s.Request("POST", "/", gist1, 302)
|
||||
require.NoError(t, err)
|
||||
@ -220,6 +225,7 @@ func TestCustomUrl(t *testing.T) {
|
||||
},
|
||||
Name: []string{"gist1.txt", "gist2.txt", "gist3.txt"},
|
||||
Content: []string{"yeah", "yeah\ncool", "yeah\ncool gist actually"},
|
||||
Topics: "",
|
||||
}
|
||||
err := s.Request("POST", "/", gist1, 302)
|
||||
require.NoError(t, err)
|
||||
@ -251,6 +257,7 @@ func TestCustomUrl(t *testing.T) {
|
||||
},
|
||||
Name: []string{"gist1.txt", "gist2.txt", "gist3.txt"},
|
||||
Content: []string{"yeah", "yeah\ncool", "yeah\ncool gist actually"},
|
||||
Topics: "",
|
||||
}
|
||||
err = s.Request("POST", "/", gist2, 302)
|
||||
require.NoError(t, err)
|
||||
@ -261,3 +268,75 @@ func TestCustomUrl(t *testing.T) {
|
||||
require.Equal(t, gist2db.Uuid, gist2db.Identifier())
|
||||
require.NotEqual(t, gist2db.URL, gist2db.Identifier())
|
||||
}
|
||||
|
||||
func TestTopics(t *testing.T) {
|
||||
s := Setup(t)
|
||||
defer Teardown(t, s)
|
||||
|
||||
user1 := db.UserDTO{Username: "thomas", Password: "thomas"}
|
||||
register(t, s, user1)
|
||||
|
||||
gist1 := db.GistDTO{
|
||||
Title: "gist1",
|
||||
URL: "my-gist",
|
||||
Description: "my first gist",
|
||||
VisibilityDTO: db.VisibilityDTO{
|
||||
Private: 0,
|
||||
},
|
||||
Name: []string{"gist1.txt", "gist2.txt", "gist3.txt"},
|
||||
Content: []string{"yeah", "yeah\ncool", "yeah\ncool gist actually"},
|
||||
Topics: "topic1 topic2 topic3",
|
||||
}
|
||||
err := s.Request("POST", "/", gist1, 302)
|
||||
require.NoError(t, err)
|
||||
|
||||
gist1db, err := db.GetGistByID("1")
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, []db.GistTopic{
|
||||
{GistID: 1, Topic: "topic1"},
|
||||
{GistID: 1, Topic: "topic2"},
|
||||
{GistID: 1, Topic: "topic3"},
|
||||
}, gist1db.Topics)
|
||||
|
||||
gist2 := db.GistDTO{
|
||||
Title: "gist2",
|
||||
URL: "my-gist",
|
||||
Description: "my second gist",
|
||||
VisibilityDTO: db.VisibilityDTO{
|
||||
Private: 0,
|
||||
},
|
||||
Name: []string{"gist1.txt", "gist2.txt", "gist3.txt"},
|
||||
Content: []string{"yeah", "yeah\ncool", "yeah\ncool gist actually"},
|
||||
Topics: "topic1 topic2 topic3 topic2 topic4 topic1",
|
||||
}
|
||||
err = s.Request("POST", "/", gist2, 302)
|
||||
require.NoError(t, err)
|
||||
|
||||
gist2db, err := db.GetGistByID("2")
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, []db.GistTopic{
|
||||
{GistID: 2, Topic: "topic1"},
|
||||
{GistID: 2, Topic: "topic2"},
|
||||
{GistID: 2, Topic: "topic3"},
|
||||
{GistID: 2, Topic: "topic4"},
|
||||
}, gist2db.Topics)
|
||||
|
||||
gist3 := db.GistDTO{
|
||||
Title: "gist3",
|
||||
URL: "my-gist",
|
||||
Description: "my third gist",
|
||||
VisibilityDTO: db.VisibilityDTO{
|
||||
Private: 0,
|
||||
},
|
||||
Name: []string{"gist1.txt", "gist2.txt", "gist3.txt"},
|
||||
Content: []string{"yeah", "yeah\ncool", "yeah\ncool gist actually"},
|
||||
Topics: "topic1 topic2 topic3 topic4 topic5 topic6 topic7 topic8 topic9 topic10 topic11",
|
||||
}
|
||||
err = s.Request("POST", "/", gist3, 400)
|
||||
require.NoError(t, err)
|
||||
|
||||
gist3.Topics = "topictoolongggggggggggggggggggggggggggggggggggggggg"
|
||||
err = s.Request("POST", "/", gist3, 400)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
Reference in New Issue
Block a user