feat: Implement command flag management for rclone configurations

- Added functionality to manage command flags and their values in the configuration form.
- Updated the database schema to include a new field for storing command flag values.
- Enhanced backend logic to process and store flag values for non-boolean flags during configuration creation and updates.
- Improved the user interface to dynamically require destination fields based on selected commands.
- Refactored related templates and handlers to support the new command flag management features.
This commit is contained in:
StarFleetCPTN committed 2025-03-23 20:30:02 -07:00
1 parent 0cebfcf1f5
commit 233f1779d8
20 files changed
+457 -239

No files matched your search

+63
View File
@@ -6,6 +6,7 @@ import (
"log"
"net/http"
"strconv"
"strings"
"time"
"github.com/gin-gonic/gin"
@@ -156,6 +157,37 @@ func (h *Handlers) HandleCreateConfig(c *gin.Context) {
}
}
// Process flag values for non-boolean flags
flagValues := make(map[uint]string)
for key, values := range c.Request.PostForm {
// Check if key is a flag value field (format: flag_value_ID)
if strings.HasPrefix(key, "flag_value_") {
flagIDStr := strings.TrimPrefix(key, "flag_value_")
flagID, err := strconv.ParseUint(flagIDStr, 10, 64)
if err != nil {
log.Printf("Error parsing flag value ID: %v", err)
continue
}
// Only process if the corresponding enable checkbox is checked
enableKey := fmt.Sprintf("flag_enable_%s", flagIDStr)
enableValue := c.Request.PostForm.Get(enableKey)
if enableValue == "on" && len(values) > 0 && values[0] != "" {
flagValues[uint(flagID)] = values[0]
}
}
}
// Store flag values as JSON if any exist
if len(flagValues) > 0 {
flagValuesJSON, err := json.Marshal(flagValues)
if err != nil {
log.Printf("Error marshaling flag values: %v", err)
} else {
config.CommandFlagValues = string(flagValuesJSON)
}
}
// Process builtin auth settings
useBuiltinAuthSourceVal := c.Request.FormValue("use_builtin_auth_source")
useBuiltinAuthSourceValue := useBuiltinAuthSourceVal == "on" || useBuiltinAuthSourceVal == "true"
@@ -343,6 +375,37 @@ func (h *Handlers) HandleUpdateConfig(c *gin.Context) {
}
}
// Process flag values for non-boolean flags
flagValues := make(map[uint]string)
for key, values := range c.Request.PostForm {
// Check if key is a flag value field (format: flag_value_ID)
if strings.HasPrefix(key, "flag_value_") {
flagIDStr := strings.TrimPrefix(key, "flag_value_")
flagID, err := strconv.ParseUint(flagIDStr, 10, 64)
if err != nil {
log.Printf("Error parsing flag value ID: %v", err)
continue
}
// Only process if the corresponding enable checkbox is checked
enableKey := fmt.Sprintf("flag_enable_%s", flagIDStr)
enableValue := c.Request.PostForm.Get(enableKey)
if enableValue == "on" && len(values) > 0 && values[0] != "" {
flagValues[uint(flagID)] = values[0]
}
}
}
// Store flag values as JSON if any exist
if len(flagValues) > 0 {
flagValuesJSON, err := json.Marshal(flagValues)
if err != nil {
log.Printf("Error marshaling flag values: %v", err)
} else {
config.CommandFlagValues = string(flagValuesJSON)
}
}
// Process builtin auth settings
useBuiltinAuthSourceVal := c.Request.FormValue("use_builtin_auth_source")
useBuiltinAuthSourceValue := useBuiltinAuthSourceVal == "on" || useBuiltinAuthSourceVal == "true"
+4 -4
View File
@@ -675,7 +675,7 @@ func (h *Handlers) HandleRunJob(c *gin.Context) {
var job db.Job
if err := h.DB.First(&job, id).Error; err != nil {
c.Header("Content-Type", "text/html")
c.String(http.StatusNotFound, "<script>window.notyfInstance.error('Job not found')</script>")
c.String(http.StatusNotFound, "Job not found")
return
}
@@ -685,7 +685,7 @@ func (h *Handlers) HandleRunJob(c *gin.Context) {
isAdmin, exists := c.Get("isAdmin")
if !exists || isAdmin != true {
c.Header("Content-Type", "text/html")
c.String(http.StatusForbidden, "<script>window.notyfInstance.error('You do not have permission to run this job')</script>")
c.String(http.StatusForbidden, "You do not have permission to run this job")
return
}
}
@@ -720,7 +720,7 @@ func (h *Handlers) HandleRunJob(c *gin.Context) {
// Run the job immediately using the scheduler
if err := h.Scheduler.RunJobNow(job.ID); err != nil {
c.Header("Content-Type", "text/html")
errorMsg := fmt.Sprintf("<script>window.notyfInstance.error('Failed to run job: %s')</script>", err.Error())
errorMsg := fmt.Sprintf("%s", err.Error())
c.String(http.StatusInternalServerError, errorMsg)
return
}
@@ -730,7 +730,7 @@ func (h *Handlers) HandleRunJob(c *gin.Context) {
c.Header("Content-Type", "text/html")
// Return HTML with JavaScript to trigger the notification
successScript := fmt.Sprintf("<script>window.notyfInstance.success('Job \"%s\" has been started successfully')</script>", jobName)
successScript := fmt.Sprintf("Job \"%s\" has been started successfully", jobName)
c.String(http.StatusOK, successScript)
}
+6
View File
@@ -4,6 +4,7 @@ import (
"html/template"
"log"
"net/http"
"sort"
"strconv"
"github.com/gin-gonic/gin"
@@ -76,6 +77,11 @@ func (h *RcloneHandler) RcloneCommandFlags(c *gin.Context) {
return
}
// Sort the flags alphabetically by name
sort.Slice(command.Flags, func(i, j int) bool {
return command.Flags[i].Name < command.Flags[j].Name
})
_ = common.RcloneCommandFlagsContent(command).Render(c.Request.Context(), c.Writer)
}