tests(all): improve tests, refactor(api): saving books
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
2024-02-24 20:45:26 -05:00
parent 803c187a00
commit 75ed394f8d
28 changed files with 1033 additions and 595 deletions

View File

@@ -19,6 +19,7 @@ import (
"github.com/gin-gonic/gin"
"github.com/itchyny/gojq"
log "github.com/sirupsen/logrus"
"reichard.io/antholume/metadata"
)
type adminAction string
@@ -63,7 +64,7 @@ func (api *API) appPerformAdminAction(c *gin.Context) {
var rAdminAction requestAdminAction
if err := c.ShouldBind(&rAdminAction); err != nil {
log.Error("Invalid Form Bind: ", err)
appErrorPage(c, http.StatusBadRequest, "Invalid or missing form values.")
appErrorPage(c, http.StatusBadRequest, "Invalid or missing form values")
return
}
@@ -75,6 +76,7 @@ func (api *API) appPerformAdminAction(c *gin.Context) {
// 2. Select all / deselect?
case adminCacheTables:
go api.db.CacheTempTables()
// TODO - Message
case adminRestore:
api.processRestoreFile(rAdminAction, c)
return
@@ -83,7 +85,7 @@ func (api *API) appPerformAdminAction(c *gin.Context) {
_, err := api.db.DB.ExecContext(api.db.Ctx, "VACUUM;")
if err != nil {
log.Error("Unable to vacuum DB: ", err)
appErrorPage(c, http.StatusInternalServerError, "Unable to vacuum database.")
appErrorPage(c, http.StatusInternalServerError, "Unable to vacuum database")
return
}
@@ -126,7 +128,7 @@ func (api *API) appGetAdminLogs(c *gin.Context) {
var rAdminLogs requestAdminLogs
if err := c.ShouldBindQuery(&rAdminLogs); err != nil {
log.Error("Invalid URI Bind")
appErrorPage(c, http.StatusNotFound, "Invalid URI parameters.")
appErrorPage(c, http.StatusNotFound, "Invalid URI parameters")
return
}
rAdminLogs.Filter = strings.TrimSpace(rAdminLogs.Filter)
@@ -136,14 +138,14 @@ func (api *API) appGetAdminLogs(c *gin.Context) {
parsed, err := gojq.Parse(rAdminLogs.Filter)
if err != nil {
log.Error("Unable to parse JQ filter")
appErrorPage(c, http.StatusNotFound, "Unable to parse JQ filter.")
appErrorPage(c, http.StatusNotFound, "Unable to parse JQ filter")
return
}
jqFilter, err = gojq.Compile(parsed)
if err != nil {
log.Error("Unable to compile JQ filter")
appErrorPage(c, http.StatusNotFound, "Unable to compile JQ filter.")
appErrorPage(c, http.StatusNotFound, "Unable to compile JQ filter")
return
}
}
@@ -152,7 +154,7 @@ func (api *API) appGetAdminLogs(c *gin.Context) {
logPath := filepath.Join(api.cfg.ConfigPath, "logs/antholume.log")
logFile, err := os.Open(logPath)
if err != nil {
appErrorPage(c, http.StatusBadRequest, "Missing AnthoLume log file.")
appErrorPage(c, http.StatusBadRequest, "Missing AnthoLume log file")
return
}
defer logFile.Close()
@@ -229,7 +231,7 @@ func (api *API) appGetAdminImport(c *gin.Context) {
var rImportFolder requestAdminImport
if err := c.ShouldBindQuery(&rImportFolder); err != nil {
log.Error("Invalid URI Bind")
appErrorPage(c, http.StatusNotFound, "Invalid directory.")
appErrorPage(c, http.StatusNotFound, "Invalid directory")
return
}
@@ -244,7 +246,7 @@ func (api *API) appGetAdminImport(c *gin.Context) {
dPath, err := filepath.Abs(api.cfg.DataPath)
if err != nil {
log.Error("Absolute filepath error: ", rImportFolder.Directory)
appErrorPage(c, http.StatusNotFound, "Unable to get data directory absolute path.")
appErrorPage(c, http.StatusNotFound, "Unable to get data directory absolute path")
return
}
@@ -254,7 +256,7 @@ func (api *API) appGetAdminImport(c *gin.Context) {
entries, err := os.ReadDir(rImportFolder.Directory)
if err != nil {
log.Error("Invalid directory: ", rImportFolder.Directory)
appErrorPage(c, http.StatusNotFound, "Invalid directory.")
appErrorPage(c, http.StatusNotFound, "Invalid directory")
return
}
@@ -279,13 +281,46 @@ func (api *API) appPerformAdminImport(c *gin.Context) {
var rAdminImport requestAdminImport
if err := c.ShouldBind(&rAdminImport); err != nil {
log.Error("Invalid URI Bind")
appErrorPage(c, http.StatusNotFound, "Invalid directory.")
appErrorPage(c, http.StatusNotFound, "Invalid directory")
return
}
// TODO
// TODO - Store results for approval?
fmt.Println(rAdminImport)
// Walk import directory & copy or import files
importDirectory := filepath.Clean(rAdminImport.Directory)
_ = filepath.WalkDir(importDirectory, func(currentPath string, f fs.DirEntry, err error) error {
if err != nil {
return err
}
if f.IsDir() {
return nil
}
// Get metadata
fileMeta, err := metadata.GetMetadata(currentPath)
if err != nil {
fmt.Printf("metadata error: %v\n", err)
return nil
}
// Only needed if copying
newName := deriveBaseFileName(fileMeta)
// Open File on Disk
// file, err := os.Open(currentPath)
// if err != nil {
// return err
// }
// defer file.Close()
// TODO - BasePath in DB
// TODO - Copy / Import
fmt.Printf("New File Metadata: %s\n", newName)
return nil
})
templateVars["CurrentPath"] = filepath.Clean(rAdminImport.Directory)
@@ -297,14 +332,14 @@ func (api *API) processRestoreFile(rAdminAction requestAdminAction, c *gin.Conte
uploadedFile, err := rAdminAction.RestoreFile.Open()
if err != nil {
log.Error("File Error: ", err)
appErrorPage(c, http.StatusInternalServerError, "Unable to open file.")
appErrorPage(c, http.StatusInternalServerError, "Unable to open file")
return
}
fileMime, err := mimetype.DetectReader(uploadedFile)
if err != nil {
log.Error("MIME Error")
appErrorPage(c, http.StatusInternalServerError, "Unable to detect filetype.")
appErrorPage(c, http.StatusInternalServerError, "Unable to detect filetype")
return
}
fileExtension := fileMime.Extension()
@@ -312,7 +347,7 @@ func (api *API) processRestoreFile(rAdminAction requestAdminAction, c *gin.Conte
// Validate Extension
if !slices.Contains([]string{".zip"}, fileExtension) {
log.Error("Invalid FileType: ", fileExtension)
appErrorPage(c, http.StatusBadRequest, "Invalid filetype.")
appErrorPage(c, http.StatusBadRequest, "Invalid filetype")
return
}
@@ -320,7 +355,7 @@ func (api *API) processRestoreFile(rAdminAction requestAdminAction, c *gin.Conte
tempFile, err := os.CreateTemp("", "restore")
if err != nil {
log.Warn("Temp File Create Error: ", err)
appErrorPage(c, http.StatusInternalServerError, "Unable to create temp file.")
appErrorPage(c, http.StatusInternalServerError, "Unable to create temp file")
return
}
defer os.Remove(tempFile.Name())
@@ -330,7 +365,7 @@ func (api *API) processRestoreFile(rAdminAction requestAdminAction, c *gin.Conte
err = c.SaveUploadedFile(rAdminAction.RestoreFile, tempFile.Name())
if err != nil {
log.Error("File Error: ", err)
appErrorPage(c, http.StatusInternalServerError, "Unable to save file.")
appErrorPage(c, http.StatusInternalServerError, "Unable to save file")
return
}
@@ -338,7 +373,7 @@ func (api *API) processRestoreFile(rAdminAction requestAdminAction, c *gin.Conte
fileInfo, err := tempFile.Stat()
if err != nil {
log.Error("File Error: ", err)
appErrorPage(c, http.StatusInternalServerError, "Unable to read file.")
appErrorPage(c, http.StatusInternalServerError, "Unable to read file")
return
}
@@ -346,7 +381,7 @@ func (api *API) processRestoreFile(rAdminAction requestAdminAction, c *gin.Conte
zipReader, err := zip.NewReader(tempFile, fileInfo.Size())
if err != nil {
log.Error("ZIP Error: ", err)
appErrorPage(c, http.StatusInternalServerError, "Unable to read zip.")
appErrorPage(c, http.StatusInternalServerError, "Unable to read zip")
return
}
@@ -380,7 +415,7 @@ func (api *API) processRestoreFile(rAdminAction requestAdminAction, c *gin.Conte
backupFile, err := os.Create(backupFilePath)
if err != nil {
log.Error("Unable to create backup file: ", err)
appErrorPage(c, http.StatusInternalServerError, "Unable to create backup file.")
appErrorPage(c, http.StatusInternalServerError, "Unable to create backup file")
return
}
defer backupFile.Close()
@@ -389,7 +424,7 @@ func (api *API) processRestoreFile(rAdminAction requestAdminAction, c *gin.Conte
_, err = api.db.DB.ExecContext(api.db.Ctx, "VACUUM;")
if err != nil {
log.Error("Unable to vacuum DB: ", err)
appErrorPage(c, http.StatusInternalServerError, "Unable to vacuum database.")
appErrorPage(c, http.StatusInternalServerError, "Unable to vacuum database")
return
}
@@ -398,7 +433,7 @@ func (api *API) processRestoreFile(rAdminAction requestAdminAction, c *gin.Conte
err = api.createBackup(w, []string{"covers", "documents"})
if err != nil {
log.Error("Unable to save backup file: ", err)
appErrorPage(c, http.StatusInternalServerError, "Unable to save backup file.")
appErrorPage(c, http.StatusInternalServerError, "Unable to save backup file")
return
}
@@ -406,26 +441,26 @@ func (api *API) processRestoreFile(rAdminAction requestAdminAction, c *gin.Conte
err = api.removeData()
if err != nil {
log.Error("Unable to delete data: ", err)
appErrorPage(c, http.StatusInternalServerError, "Unable to delete data.")
appErrorPage(c, http.StatusInternalServerError, "Unable to delete data")
return
}
// Restore Data
err = api.restoreData(zipReader)
if err != nil {
appErrorPage(c, http.StatusInternalServerError, "Unable to restore data.")
appErrorPage(c, http.StatusInternalServerError, "Unable to restore data")
log.Panic("Unable to restore data: ", err)
}
// Reinit DB
if err := api.db.Reload(); err != nil {
appErrorPage(c, http.StatusInternalServerError, "Unable to reload DB.")
appErrorPage(c, http.StatusInternalServerError, "Unable to reload DB")
log.Panicf("Unable to reload DB: %v", err)
}
// Rotate Auth Hashes
if err := api.rotateAllAuthHashes(); err != nil {
appErrorPage(c, http.StatusInternalServerError, "Unable to rotate hashes.")
appErrorPage(c, http.StatusInternalServerError, "Unable to rotate hashes")
log.Panicf("Unable to rotate auth hashes: %v", err)
}
@@ -433,6 +468,7 @@ func (api *API) processRestoreFile(rAdminAction requestAdminAction, c *gin.Conte
c.Redirect(http.StatusFound, "/login")
}
// Restore all data
func (api *API) restoreData(zipReader *zip.Reader) error {
// Ensure Directories
api.cfg.EnsureDirectories()
@@ -463,6 +499,7 @@ func (api *API) restoreData(zipReader *zip.Reader) error {
return nil
}
// Remove all data
func (api *API) removeData() error {
allPaths := []string{
"covers",
@@ -485,6 +522,7 @@ func (api *API) removeData() error {
return nil
}
// Backup all data
func (api *API) createBackup(w io.Writer, directories []string) error {
ar := zip.NewWriter(w)