Sync gists from database or filesystem (admin panel)

This commit is contained in:
Thomas Miceli 2023-03-19 01:51:25 +01:00
parent be7e9ab385
commit 11b3eed250
No known key found for this signature in database
GPG key ID: D86C6F6390AF050F
4 changed files with 105 additions and 1 deletions

View file

@ -93,6 +93,15 @@ func GetAllGistsFromUser(fromUser string, currentUserId uint, offset int, sort s
return gists, err
}
func GetAllGistsRows() ([]*Gist, error) {
var gists []*Gist
err := db.Table("gists").
Preload("User").
Find(&gists).Error
return gists, err
}
func (gist *Gist) Create() error {
// avoids foreign key constraint error because the default value in the struct is 0
return db.Omit("forked_id").Create(&gist).Error

View file

@ -2,11 +2,20 @@ package web
import (
"github.com/labstack/echo/v4"
"github.com/rs/zerolog/log"
"opengist/internal/config"
"opengist/internal/git"
"opengist/internal/models"
"os"
"path/filepath"
"runtime"
"strconv"
"strings"
)
var (
syncReposFromFS = false
syncReposFromDB = false
)
func adminIndex(ctx echo.Context) error {
@ -39,6 +48,8 @@ func adminIndex(ctx echo.Context) error {
}
setData(ctx, "countKeys", countKeys)
setData(ctx, "syncReposFromFS", syncReposFromFS)
setData(ctx, "syncReposFromDB", syncReposFromDB)
return html(ctx, "admin_index.html")
}
@ -109,5 +120,65 @@ func adminGistDelete(ctx echo.Context) error {
addFlash(ctx, "Gist has been deleted", "success")
return redirect(ctx, "/admin/gists")
}
func adminSyncReposFromFS(ctx echo.Context) error {
addFlash(ctx, "Syncing repositories from filesystem...", "success")
go func() {
if syncReposFromFS {
return
}
syncReposFromFS = true
gists, err := models.GetAllGistsRows()
if err != nil {
log.Error().Err(err).Msg("Cannot get gists")
syncReposFromFS = false
return
}
for _, gist := range gists {
// if repository does not exist, delete gist from database
if _, err := os.Stat(git.RepositoryPath(gist.User.Username, gist.Uuid)); err != nil && !os.IsExist(err) {
if err2 := gist.Delete(); err2 != nil {
log.Error().Err(err2).Msg("Cannot delete gist")
syncReposFromFS = false
return
}
}
}
syncReposFromFS = false
}()
return redirect(ctx, "/admin")
}
func adminSyncReposFromDB(ctx echo.Context) error {
addFlash(ctx, "Syncing repositories from database...", "success")
go func() {
if syncReposFromDB {
return
}
syncReposFromDB = true
entries, err := filepath.Glob(filepath.Join(config.GetHomeDir(), "repos", "*", "*"))
if err != nil {
log.Error().Err(err).Msg("Cannot read repos directories")
syncReposFromDB = false
return
}
for _, e := range entries {
path := strings.Split(e, string(os.PathSeparator))
gist, _ := models.GetGist(path[len(path)-2], path[len(path)-1])
if gist.ID == 0 {
if err := git.DeleteRepository(path[len(path)-2], path[len(path)-1]); err != nil {
log.Error().Err(err).Msg("Cannot delete repository")
syncReposFromDB = false
return
}
}
}
syncReposFromDB = false
return
}()
return redirect(ctx, "/admin")
}

View file

@ -140,6 +140,8 @@ func Start() {
g2.POST("/users/:user/delete", adminUserDelete)
g2.GET("/gists", adminGists)
g2.POST("/gists/:gist/delete", adminGistDelete)
g2.POST("/sync-fs", adminSyncReposFromFS)
g2.POST("/sync-db", adminSyncReposFromDB)
}
g1.GET("/all", allGists)

View file

@ -49,6 +49,28 @@
</table>
</div>
</div>
<div class="sm:overflow-hidden ">
<div class="space-y-2 bg-gray-800 py-6 px-6 rounded-md border border-gray-700">
<div>
<span class="text-base font-bold leading-6 text-slate-300">Actions</span>
</div>
<div class="space-y-2">
<form action="/admin/sync-fs" method="POST">
{{ .csrfHtml }}
<button type="submit" {{ if .syncReposFromFS }}disabled="disabled"{{ end }} class="whitespace-nowrap text-slate-300{{ if .syncReposFromFS }} text-slate-500 cursor-not-allowed {{ end }}rounded border border-gray-600 bg-gray-800 px-2.5 py-2 text-xs font-medium text-white shadow-sm hover:bg-gray-700 hover:border-gray-500 hover:text-slate-300 focus:outline-none focus:ring-1 focus:border-primary-500 focus:ring-primary-500 leading-3">
Synchorize gists from filesystem
</button>
</form>
<form action="/admin/sync-db" method="POST">
{{ .csrfHtml }}
<button type="submit" {{ if .syncReposFromDB }}disabled="disabled"{{ end }} class="whitespace-nowrap text-slate-300{{ if .syncReposFromDB }} text-slate-500 cursor-not-allowed {{ end }}rounded border border-gray-600 bg-gray-800 px-2.5 py-2 text-xs font-medium text-white shadow-sm hover:bg-gray-700 hover:border-gray-500 hover:text-slate-300 focus:outline-none focus:ring-1 focus:border-primary-500 focus:ring-primary-500 leading-3">
Synchorize gists from database
</button>
</form>
</div>
</div>
</div>
</div>
{{ template "admin_footer" .}}