2025-08-25 08:48:52 +01:00
|
|
|
package handlers
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"net/http"
|
|
|
|
|
"path/filepath"
|
|
|
|
|
"strconv"
|
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
|
|
"github.com/gin-gonic/gin"
|
|
|
|
|
|
|
|
|
|
"gobsidian/internal/utils"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
func (h *Handlers) SettingsPageHandler(c *gin.Context) {
|
|
|
|
|
notesTree, err := utils.BuildTreeStructure(h.config.NotesDir, h.config.NotesDirHideSidepane, h.config)
|
|
|
|
|
if err != nil {
|
2025-08-25 09:44:14 +01:00
|
|
|
c.HTML(http.StatusInternalServerError, "error", gin.H{
|
2025-08-25 17:26:27 +01:00
|
|
|
"error": "Failed to build tree structure",
|
|
|
|
|
"app_name": h.config.AppName,
|
|
|
|
|
"message": err.Error(),
|
|
|
|
|
"ContentTemplate": "error_content",
|
|
|
|
|
"ScriptsTemplate": "error_scripts",
|
|
|
|
|
"Page": "error",
|
2025-08-25 08:48:52 +01:00
|
|
|
})
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-25 09:44:14 +01:00
|
|
|
c.HTML(http.StatusOK, "settings", gin.H{
|
2025-08-25 17:26:27 +01:00
|
|
|
"app_name": h.config.AppName,
|
|
|
|
|
"notes_tree": notesTree,
|
|
|
|
|
"active_path": []string{},
|
|
|
|
|
"current_note": nil,
|
2025-08-25 08:48:52 +01:00
|
|
|
"breadcrumbs": []gin.H{
|
|
|
|
|
{"name": "/", "url": "/"},
|
|
|
|
|
{"name": "Settings", "url": ""},
|
|
|
|
|
},
|
2025-08-25 17:26:27 +01:00
|
|
|
"ContentTemplate": "settings_content",
|
|
|
|
|
"ScriptsTemplate": "settings_scripts",
|
|
|
|
|
"Page": "settings",
|
2025-08-25 08:48:52 +01:00
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (h *Handlers) GetImageStorageSettingsHandler(c *gin.Context) {
|
|
|
|
|
c.JSON(http.StatusOK, gin.H{
|
|
|
|
|
"mode": h.config.ImageStorageMode,
|
|
|
|
|
"path": h.config.ImageStoragePath,
|
|
|
|
|
"subfolder": h.config.ImageSubfolderName,
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (h *Handlers) PostImageStorageSettingsHandler(c *gin.Context) {
|
|
|
|
|
modeStr := c.PostForm("storage_mode")
|
|
|
|
|
path := strings.TrimSpace(c.PostForm("storage_path"))
|
|
|
|
|
subfolder := strings.TrimSpace(c.PostForm("subfolder_name"))
|
|
|
|
|
|
|
|
|
|
mode, err := strconv.Atoi(modeStr)
|
|
|
|
|
if err != nil || mode < 1 || mode > 4 {
|
|
|
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid storage mode"})
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Validate path for mode 2
|
|
|
|
|
if mode == 2 && path == "" {
|
|
|
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "Storage path is required for mode 2"})
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Validate subfolder name for mode 4
|
|
|
|
|
if mode == 4 && subfolder == "" {
|
|
|
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "Subfolder name is required for mode 4"})
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Save settings
|
|
|
|
|
if err := h.config.SaveSetting("MD_NOTES_APP", "IMAGE_STORAGE_MODE", modeStr); err != nil {
|
|
|
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to save storage mode"})
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if mode == 2 {
|
|
|
|
|
if err := h.config.SaveSetting("MD_NOTES_APP", "IMAGE_STORAGE_PATH", path); err != nil {
|
|
|
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to save storage path"})
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if mode == 4 {
|
|
|
|
|
if err := h.config.SaveSetting("MD_NOTES_APP", "IMAGE_SUBFOLDER_NAME", subfolder); err != nil {
|
|
|
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to save subfolder name"})
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
c.JSON(http.StatusOK, gin.H{
|
|
|
|
|
"success": true,
|
|
|
|
|
"message": "Image storage settings updated successfully",
|
|
|
|
|
"reload_required": true,
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (h *Handlers) GetNotesDirSettingsHandler(c *gin.Context) {
|
|
|
|
|
c.JSON(http.StatusOK, gin.H{
|
|
|
|
|
"notes_dir": h.config.NotesDir,
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (h *Handlers) PostNotesDirSettingsHandler(c *gin.Context) {
|
|
|
|
|
newDir := strings.TrimSpace(c.PostForm("notes_dir"))
|
|
|
|
|
if newDir == "" {
|
|
|
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "Notes directory is required"})
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Convert to absolute path
|
|
|
|
|
if !filepath.IsAbs(newDir) {
|
|
|
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "Please provide an absolute path"})
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Ensure directory exists
|
|
|
|
|
if err := utils.EnsureDir(newDir); err != nil {
|
|
|
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to create directory: " + err.Error()})
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Save setting
|
|
|
|
|
if err := h.config.SaveSetting("MD_NOTES_APP", "NOTES_DIR", newDir); err != nil {
|
|
|
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to save notes directory"})
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
c.JSON(http.StatusOK, gin.H{
|
|
|
|
|
"success": true,
|
|
|
|
|
"message": "Notes directory updated successfully",
|
|
|
|
|
"reload_required": true,
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (h *Handlers) GetFileExtensionsSettingsHandler(c *gin.Context) {
|
|
|
|
|
c.JSON(http.StatusOK, gin.H{
|
|
|
|
|
"allowed_image_extensions": strings.Join(h.config.AllowedImageExtensions, ", "),
|
|
|
|
|
"allowed_file_extensions": strings.Join(h.config.AllowedFileExtensions, ", "),
|
|
|
|
|
"images_hide": h.config.ImagesHide,
|
2025-08-25 18:15:51 +01:00
|
|
|
"show_images_in_tree": h.config.ShowImagesInTree,
|
|
|
|
|
"show_files_in_tree": h.config.ShowFilesInTree,
|
|
|
|
|
"show_images_in_folder": h.config.ShowImagesInFolder,
|
|
|
|
|
"show_files_in_folder": h.config.ShowFilesInFolder,
|
2025-08-25 08:48:52 +01:00
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (h *Handlers) PostFileExtensionsSettingsHandler(c *gin.Context) {
|
|
|
|
|
imageExtensions := strings.TrimSpace(c.PostForm("allowed_image_extensions"))
|
|
|
|
|
fileExtensions := strings.TrimSpace(c.PostForm("allowed_file_extensions"))
|
2025-08-25 18:15:51 +01:00
|
|
|
imagesHide := c.PostForm("images_hide") == "true" || c.PostForm("images_hide") == "on"
|
|
|
|
|
showImagesInTree := c.PostForm("show_images_in_tree") == "true" || c.PostForm("show_images_in_tree") == "on"
|
|
|
|
|
showFilesInTree := c.PostForm("show_files_in_tree") == "true" || c.PostForm("show_files_in_tree") == "on"
|
|
|
|
|
showImagesInFolder := c.PostForm("show_images_in_folder") == "true" || c.PostForm("show_images_in_folder") == "on"
|
|
|
|
|
showFilesInFolder := c.PostForm("show_files_in_folder") == "true" || c.PostForm("show_files_in_folder") == "on"
|
2025-08-25 08:48:52 +01:00
|
|
|
|
|
|
|
|
// Save settings
|
|
|
|
|
if err := h.config.SaveSetting("MD_NOTES_APP", "ALLOWED_IMAGE_EXTENSIONS", imageExtensions); err != nil {
|
|
|
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to save image extensions"})
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if err := h.config.SaveSetting("MD_NOTES_APP", "ALLOWED_FILE_EXTENSIONS", fileExtensions); err != nil {
|
|
|
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to save file extensions"})
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
imagesHideStr := "false"
|
|
|
|
|
if imagesHide {
|
|
|
|
|
imagesHideStr = "true"
|
|
|
|
|
}
|
|
|
|
|
if err := h.config.SaveSetting("MD_NOTES_APP", "IMAGES_HIDE", imagesHideStr); err != nil {
|
|
|
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to save images hide setting"})
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-25 18:15:51 +01:00
|
|
|
if err := h.config.SaveSetting("MD_NOTES_APP", "SHOW_IMAGES_IN_TREE", boolToStr(showImagesInTree)); err != nil {
|
|
|
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to save SHOW_IMAGES_IN_TREE"})
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if err := h.config.SaveSetting("MD_NOTES_APP", "SHOW_FILES_IN_TREE", boolToStr(showFilesInTree)); err != nil {
|
|
|
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to save SHOW_FILES_IN_TREE"})
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if err := h.config.SaveSetting("MD_NOTES_APP", "SHOW_IMAGES_IN_FOLDER", boolToStr(showImagesInFolder)); err != nil {
|
|
|
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to save SHOW_IMAGES_IN_FOLDER"})
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if err := h.config.SaveSetting("MD_NOTES_APP", "SHOW_FILES_IN_FOLDER", boolToStr(showFilesInFolder)); err != nil {
|
|
|
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to save SHOW_FILES_IN_FOLDER"})
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-25 08:48:52 +01:00
|
|
|
c.JSON(http.StatusOK, gin.H{
|
|
|
|
|
"success": true,
|
|
|
|
|
"message": "File extension settings updated successfully",
|
|
|
|
|
"reload_required": true,
|
|
|
|
|
})
|
|
|
|
|
}
|
2025-08-25 18:15:51 +01:00
|
|
|
|
|
|
|
|
func boolToStr(b bool) string {
|
|
|
|
|
if b {
|
|
|
|
|
return "true"
|
|
|
|
|
}
|
|
|
|
|
return "false"
|
|
|
|
|
}
|