mirror of
https://github.com/thomiceli/opengist.git
synced 2024-12-22 20:42:40 +00:00
Sync gists from database or filesystem (admin panel)
This commit is contained in:
parent
be7e9ab385
commit
11b3eed250
4 changed files with 105 additions and 1 deletions
|
@ -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
|
||||
|
|
|
@ -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")
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
22
templates/pages/admin_index.html
vendored
22
templates/pages/admin_index.html
vendored
|
@ -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" .}}
|
||||
|
|
Loading…
Reference in a new issue