Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
thomiceli committed Jan 21, 2025
1 parent 6b9e3ce commit 32bc012
Show file tree
Hide file tree
Showing 11 changed files with 85 additions and 47 deletions.
4 changes: 2 additions & 2 deletions internal/db/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ func Setup(dbUri string) error {
return err
}

if err = db.AutoMigrate(&User{}, &Gist{}, &SSHKey{}, &AdminSetting{}, &Invitation{}, &WebAuthnCredential{}, &TOTP{}, &GistTag{}); err != nil {
if err = db.AutoMigrate(&User{}, &Gist{}, &SSHKey{}, &AdminSetting{}, &Invitation{}, &WebAuthnCredential{}, &TOTP{}, &GistTopic{}); err != nil {
return err
}

Expand Down Expand Up @@ -258,5 +258,5 @@ func DeprecationDBFilename() {
}

func TruncateDatabase() error {
return db.Migrator().DropTable("likes", &User{}, "gists", &SSHKey{}, &AdminSetting{}, &Invitation{}, &WebAuthnCredential{}, &TOTP{}, &GistTag{})
return db.Migrator().DropTable("likes", &User{}, "gists", &SSHKey{}, &AdminSetting{}, &Invitation{}, &WebAuthnCredential{}, &TOTP{}, &GistTopic{})
}
64 changes: 28 additions & 36 deletions internal/db/gist.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ type Gist struct {
Forked *Gist `gorm:"foreignKey:ForkedID;constraint:OnUpdate:CASCADE,OnDelete:SET NULL"`
ForkedID uint

Tags []GistTag `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE"`
Topics []GistTopic `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE"`
}

type Like struct {
Expand All @@ -91,6 +91,12 @@ type Like struct {
CreatedAt int64
}

func (gist *Gist) BeforeUpdate(tx *gorm.DB) error {
// remove all tags
err := tx.Model(&GistTopic{}).Where("gist_id = ?", gist.ID).Delete(&GistTopic{}).Error
return err
}

func (gist *Gist) BeforeDelete(tx *gorm.DB) error {
// Decrement fork counter if the gist was forked
err := tx.Model(&Gist{}).
Expand All @@ -102,7 +108,7 @@ func (gist *Gist) BeforeDelete(tx *gorm.DB) error {

func GetGist(user string, gistUuid string) (*Gist, error) {
gist := new(Gist)
err := db.Preload("User").Preload("Forked.User").Preload("Tags").
err := db.Preload("User").Preload("Forked.User").Preload("Topics").
Where("(gists.uuid like ? OR gists.url = ?) AND users.username like ?", gistUuid+"%", gistUuid, user).
Joins("join users on gists.user_id = users.id").
First(&gist).Error
Expand Down Expand Up @@ -537,38 +543,12 @@ func (gist *Gist) GetLanguagesFromFiles() ([]string, error) {
return languages, nil
}

func (gist *Gist) UpdateTags(tags []string) error {
if err := db.Where("gist_id = ?", gist.ID).Delete(&GistTag{}).Error; err != nil {
return err
}

// Add new tags
now := time.Now().Unix()
var gistTags []GistTag
for _, tag := range tags {
normalizedTag := strings.ToLower(strings.TrimSpace(tag))
if normalizedTag == "" {
continue
}
gistTags = append(gistTags, GistTag{
GistID: gist.ID,
Tag: normalizedTag,
CreatedAt: now,
})
}

if len(gistTags) > 0 {
return db.Create(&gistTags).Error
}
return nil
}

func (gist *Gist) GetTags() ([]string, error) {
var tags []string
err := db.Model(&GistTag{}).
func (gist *Gist) GetTopics() ([]string, error) {
var topics []string
err := db.Model(&GistTopic{}).
Where("gist_id = ?", gist.ID).
Pluck("tag", &tags).Error
return tags, err
Pluck("topic", &topics).Error
return topics, err
}

// -- DTO -- //
Expand All @@ -580,7 +560,7 @@ type GistDTO struct {
Files []FileDTO `validate:"min=1,dive"`
Name []string `form:"name"`
Content []string `form:"content"`
Tags []string `validate:"max=10,dive,max=50" form:"tags"` // Max 10 tags, each max 50 chars
Topics string `validate:"gisttopics" form:"topics"`
VisibilityDTO
}

Expand All @@ -599,16 +579,28 @@ func (dto *GistDTO) ToGist() *Gist {
Description: dto.Description,
Private: dto.Private,
URL: dto.URL,
Topics: dto.TopicStrToSlice(),
}
}

func (dto *GistDTO) ToExistingGist(gist *Gist) *Gist {
gist.Title = dto.Title
gist.Description = dto.Description
gist.URL = dto.URL
gist.Topics = dto.TopicStrToSlice()
return gist
}

func (dto *GistDTO) TopicStrToSlice() []GistTopic {
topics := strings.Fields(dto.Topics)
gistTopics := make([]GistTopic, 0, len(topics))
for _, topic := range topics {
gistTopics = append(gistTopics, GistTopic{Topic: topic})
}
fmt.Println(len(gistTopics))
return gistTopics
}

// -- Index -- //

func (gist *Gist) ToIndexedGist() (*index.Gist, error) {
Expand All @@ -634,7 +626,7 @@ func (gist *Gist) ToIndexedGist() (*index.Gist, error) {
return nil, err
}

tags, err := gist.GetTags()
topics, err := gist.GetTopics()
if err != nil {
return nil, err
}
Expand All @@ -647,7 +639,7 @@ func (gist *Gist) ToIndexedGist() (*index.Gist, error) {
Filenames: fileNames,
Extensions: exts,
Languages: langs,
Tags: tags,
Topics: topics,
CreatedAt: gist.CreatedAt,
UpdatedAt: gist.UpdatedAt,
}
Expand Down
7 changes: 3 additions & 4 deletions internal/db/gist_tag.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package db

type GistTag struct {
GistID uint `gorm:"primaryKey"`
Tag string `gorm:"primaryKey;size:50"`
CreatedAt int64
type GistTopic struct {
GistID uint `gorm:"primaryKey"`
Topic string `gorm:"primaryKey;size:50"`
}
2 changes: 1 addition & 1 deletion internal/index/bleve.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ func SearchGists(queryStr string, queryMetadata SearchGistMetadata, gistsIds []u
addQuery("Extensions", "."+queryMetadata.Extension)
addQuery("Filenames", queryMetadata.Filename)
addQuery("Languages", queryMetadata.Language)
addQuery("Tags", queryMetadata.Tag)
addQuery("Topics", queryMetadata.Topic)

languageFacet := bleve.NewFacetRequest("Languages", 10)

Expand Down
4 changes: 2 additions & 2 deletions internal/index/gist.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ type Gist struct {
Filenames []string
Extensions []string
Languages []string
Tags []string
Topics []string
CreatedAt int64
UpdatedAt int64
}
Expand All @@ -19,5 +19,5 @@ type SearchGistMetadata struct {
Filename string
Extension string
Language string
Tag string
Topic string
}
27 changes: 27 additions & 0 deletions internal/validator/validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ func NewValidator() *OpengistValidator {
_ = v.RegisterValidation("notreserved", validateReservedKeywords)
_ = v.RegisterValidation("alphanumdash", validateAlphaNumDash)
_ = v.RegisterValidation("alphanumdashorempty", validateAlphaNumDashOrEmpty)
_ = v.RegisterValidation("gisttopics", validateGistTopics)
return &OpengistValidator{v}
}

Expand Down Expand Up @@ -46,6 +47,8 @@ func ValidationMessages(err *error, locale *i18n.Locale) string {
messages[i] = locale.String("validation.not-enough", e.Field())
case "notreserved":
messages[i] = locale.String("validation.invalid", e.Field())
case "gisttopics":
messages[i] = "invalid topics"
}
}

Expand All @@ -72,3 +75,27 @@ func validateAlphaNumDash(fl validator.FieldLevel) bool {
func validateAlphaNumDashOrEmpty(fl validator.FieldLevel) bool {
return regexp.MustCompile(`^$|^[a-zA-Z0-9-]+$`).MatchString(fl.Field().String())
}

func validateGistTopics(fl validator.FieldLevel) bool {
topicsInput := fl.Field().String()
if topicsInput == "" {
return true
}

topics := strings.Fields(topicsInput)

if len(topics) > 10 {
return false
}

for _, tag := range topics {
if len(tag) > 50 {
return false
}
if !regexp.MustCompile(`^[a-zA-Z0-9-]+$`).MatchString(tag) {
return false
}
}

return true
}
2 changes: 1 addition & 1 deletion internal/web/handlers/gist/all.go
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ func Search(ctx *context.Context) error {
Filename: meta["filename"],
Extension: meta["extension"],
Language: meta["language"],
Tag: meta["tag"],
Topic: meta["topic"],
}, visibleGistsIds, pageInt)
if err != nil {
return ctx.ErrorRes(500, "Error searching gists", err)
Expand Down
2 changes: 1 addition & 1 deletion internal/web/server/middlewares.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ func (s *Server) registerMiddlewares() {
return nil
},
}))
s.echo.Use(middleware.Recover())
// s.echo.Use(middleware.Recover())
s.echo.Use(middleware.Secure())
s.echo.Use(Middleware(sessionInit).toEcho())

Expand Down
10 changes: 10 additions & 0 deletions internal/web/server/renderer.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"))
Expand Down
7 changes: 7 additions & 0 deletions templates/base/gist_header.html
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,13 @@ <h1 class="text-2xl font-bold leading-tight break-all">
{{ if .gist.Private }} • <span class="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-gray-100 dark:bg-gray-700 text-slate-700 dark:text-slate-300"> {{ visibilityStr .gist.Private false }} </span>{{ end }}
</p>
<p class="mt-1 text-sm max-w-2xl text-slate-600 dark:text-slate-400">{{ .gist.Description }}</p>
{{ if .gist.Topics }}
<div class="mt-2">
{{ range .gist.Topics }}
<a href="{{ $.c.ExternalUrl }}/topics/{{ .Topic }}" class="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-gray-100 dark:bg-gray-700 text-slate-700 dark:text-slate-300 hover:bg-gray-200 dark:hover:bg-gray-600 hover:text-slate-700 dark:hover:text-slate-300">{{ .Topic }}</a>
{{ end }}
</div>
{{ end }}
</header>
<main class="mt-4">

Expand Down
3 changes: 3 additions & 0 deletions templates/pages/edit.html
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ <h1 class="text-2xl font-bold leading-tight text-slate-700 dark:text-slate-300">
<div class="col-span-6 sm:col-span-3 mt-2">
<input type="text" value="{{ .gist.URL }}" placeholder="{{ .locale.Tr "gist.new.url" }}" name="url" id="url" class="bg-white dark:bg-black shadow-sm focus:ring-primary-500 focus:border-primary-500 block w-full sm:text-sm border-gray-200 dark:border-gray-700 rounded-md" maxlength="32">
</div>
<div class="col-span-12 sm:col-span-12 mt-2">
<input type="text" value="{{ topicsToStr .gist.Topics }}" placeholder="{{ .locale.Tr "gist.new.url" }}" name="topics" id="topics" class="bg-white dark:bg-black shadow-sm focus:ring-primary-500 focus:border-primary-500 block w-full sm:text-sm border-gray-200 dark:border-gray-700 rounded-md" maxlength="100">
</div>
</div>
</div>
<div id="editors" class="space-y-4">
Expand Down

0 comments on commit 32bc012

Please sign in to comment.