mirror of
https://github.com/thomiceli/opengist.git
synced 2025-07-10 09:51:51 +02:00
Search gists on user profile with title, visibility, language & topics (#422)
This commit is contained in:
@ -6,6 +6,7 @@ import (
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"slices"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@ -50,16 +51,16 @@ func (v Visibility) Next() Visibility {
|
||||
}
|
||||
}
|
||||
|
||||
func ParseVisibility[T string | int](v T) (Visibility, error) {
|
||||
func ParseVisibility[T string | int](v T) Visibility {
|
||||
switch s := fmt.Sprint(v); s {
|
||||
case "0", "public":
|
||||
return PublicVisibility, nil
|
||||
return PublicVisibility
|
||||
case "1", "unlisted":
|
||||
return UnlistedVisibility, nil
|
||||
return UnlistedVisibility
|
||||
case "2", "private":
|
||||
return PrivateVisibility, nil
|
||||
return PrivateVisibility
|
||||
default:
|
||||
return -1, fmt.Errorf("unknown visibility %q", s)
|
||||
return PublicVisibility
|
||||
}
|
||||
}
|
||||
|
||||
@ -84,7 +85,8 @@ type Gist struct {
|
||||
Forked *Gist `gorm:"foreignKey:ForkedID;constraint:OnUpdate:CASCADE,OnDelete:SET NULL"`
|
||||
ForkedID uint
|
||||
|
||||
Topics []GistTopic `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE"`
|
||||
Topics []GistTopic `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE"`
|
||||
Languages []GistLanguage `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE"`
|
||||
}
|
||||
|
||||
type Like struct {
|
||||
@ -166,25 +168,59 @@ func GetAllGistsFromSearch(currentUserId uint, query string, offset int, sort st
|
||||
}
|
||||
|
||||
func gistsFromUserStatement(fromUserId uint, currentUserId uint) *gorm.DB {
|
||||
return db.
|
||||
Where("((gists.private = 0) or (gists.private > 0 and gists.user_id = ?))", currentUserId).
|
||||
Where("users.id = ?", fromUserId).
|
||||
Joins("join users on gists.user_id = users.id")
|
||||
}
|
||||
|
||||
func gistsFromUserStatementWithPreloads(fromUserId uint, currentUserId uint) *gorm.DB {
|
||||
return db.Preload("User").Preload("Forked.User").Preload("Topics").
|
||||
Where("((gists.private = 0) or (gists.private > 0 and gists.user_id = ?))", currentUserId).
|
||||
Where("users.id = ?", fromUserId).
|
||||
Joins("join users on gists.user_id = users.id")
|
||||
}
|
||||
|
||||
func GetAllGistsFromUser(fromUserId uint, currentUserId uint, offset int, sort string, order string) ([]*Gist, error) {
|
||||
func GetAllGistsFromUser(fromUserId uint, currentUserId uint, title string, language string, visibility string, topics []string, offset int, sort string, order string) ([]*Gist, int64, error) {
|
||||
var gists []*Gist
|
||||
err := gistsFromUserStatement(fromUserId, currentUserId).Limit(11).
|
||||
var count int64
|
||||
|
||||
baseQuery := gistsFromUserStatementWithPreloads(fromUserId, currentUserId).Model(&Gist{})
|
||||
|
||||
if title != "" {
|
||||
baseQuery = baseQuery.Where("gists.title like ?", "%"+title+"%")
|
||||
}
|
||||
|
||||
if language != "" {
|
||||
baseQuery = baseQuery.Joins("join gist_languages on gists.id = gist_languages.gist_id").
|
||||
Where("gist_languages.language = ?", language)
|
||||
}
|
||||
|
||||
if visibility != "" {
|
||||
baseQuery = baseQuery.Where("gists.private = ?", ParseVisibility(visibility))
|
||||
}
|
||||
|
||||
if len(topics) > 0 {
|
||||
baseQuery = baseQuery.Joins("join gist_topics on gists.id = gist_topics.gist_id").
|
||||
Where("gist_topics.topic in ?", topics)
|
||||
}
|
||||
|
||||
err := baseQuery.Count(&count).Error
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
err = baseQuery.Limit(11).
|
||||
Offset(offset * 10).
|
||||
Order("gists." + sort + "_at " + order).
|
||||
Find(&gists).Error
|
||||
|
||||
return gists, err
|
||||
return gists, count, err
|
||||
}
|
||||
|
||||
func CountAllGistsFromUser(fromUserId uint, currentUserId uint) (int64, error) {
|
||||
var count int64
|
||||
err := gistsFromUserStatement(fromUserId, currentUserId).Model(&Gist{}).Count(&count).Error
|
||||
err := gistsFromUserStatementWithPreloads(fromUserId, currentUserId).Model(&Gist{}).Count(&count).Error
|
||||
return count, err
|
||||
}
|
||||
|
||||
@ -258,7 +294,18 @@ func GetAllGistsByIds(ids []uint) ([]*Gist, error) {
|
||||
Where("id in ?", ids).
|
||||
Find(&gists).Error
|
||||
|
||||
return gists, err
|
||||
// keep order
|
||||
ordered := make([]*Gist, 0, len(ids))
|
||||
for _, wantedId := range ids {
|
||||
for _, gist := range gists {
|
||||
if gist.ID == wantedId {
|
||||
ordered = append(ordered, gist)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ordered, err
|
||||
}
|
||||
|
||||
func (gist *Gist) Create() error {
|
||||
@ -593,6 +640,47 @@ func DeserialiseInitRepository(user string) (*Gist, error) {
|
||||
return &gist, nil
|
||||
}
|
||||
|
||||
func (gist *Gist) UpdateLanguages() {
|
||||
languages, err := gist.GetLanguagesFromFiles()
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msgf("Cannot get languages for gist %d", gist.ID)
|
||||
return
|
||||
}
|
||||
|
||||
slices.Sort(languages)
|
||||
languages = slices.Compact(languages)
|
||||
|
||||
tx := db.Begin()
|
||||
if tx.Error != nil {
|
||||
log.Error().Err(tx.Error).Msgf("Cannot start transaction for gist %d", gist.ID)
|
||||
return
|
||||
}
|
||||
|
||||
if err := tx.Where("gist_id = ?", gist.ID).Delete(&GistLanguage{}).Error; err != nil {
|
||||
tx.Rollback()
|
||||
log.Error().Err(err).Msgf("Cannot delete languages for gist %d", gist.ID)
|
||||
return
|
||||
}
|
||||
|
||||
for _, language := range languages {
|
||||
gistLanguage := &GistLanguage{
|
||||
GistID: gist.ID,
|
||||
Language: language,
|
||||
}
|
||||
if err := tx.Create(gistLanguage).Error; err != nil {
|
||||
tx.Rollback()
|
||||
log.Error().Err(err).Msgf("Cannot create gist language %s for gist %d", language, gist.ID)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if err := tx.Commit().Error; err != nil {
|
||||
tx.Rollback()
|
||||
log.Error().Err(err).Msgf("Cannot commit transaction for gist %d", gist.ID)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (gist *Gist) ToDTO() (*GistDTO, error) {
|
||||
files, err := gist.Files("HEAD", false)
|
||||
if err != nil {
|
||||
@ -684,6 +772,9 @@ func (gist *Gist) ToIndexedGist() (*index.Gist, error) {
|
||||
wholeContent := ""
|
||||
for _, file := range files {
|
||||
wholeContent += file.Content
|
||||
if !strings.HasSuffix(wholeContent, "\n") {
|
||||
wholeContent += "\n"
|
||||
}
|
||||
exts = append(exts, filepath.Ext(file.Filename))
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user