Add callback URL for post-processing

This commit is contained in:
Mukhtar Akere
2025-08-27 13:02:43 +01:00
parent 267cc2d32b
commit 83058489b6
8 changed files with 80 additions and 94 deletions

View File

@@ -152,6 +152,7 @@ type Config struct {
Auth *Auth `json:"-"`
DiscordWebhook string `json:"discord_webhook_url,omitempty"`
RemoveStalledAfter string `json:"remove_stalled_after,omitzero"`
CallbackURL string `json:"callback_url,omitempty"`
}
func (c *Config) JsonFile() string {

View File

@@ -45,6 +45,8 @@ func getDiscordHeader(event string) string {
return "[Decypharr] Repair Completed, Awaiting action"
case "repair_complete":
return "[Decypharr] Repair Complete"
case "repair_cancelled":
return "[Decypharr] Repair Cancelled"
default:
// split the event string and capitalize the first letter of each word
evs := strings.Split(event, "_")

View File

@@ -59,6 +59,8 @@ func (c *Cache) markAsSuccessfullyReinserted(torrentId string) {
}
}
// GetBrokenFiles checks the files in the torrent for broken links.
// It also attempts to reinsert the torrent if any files are broken.
func (c *Cache) GetBrokenFiles(t *CachedTorrent, filenames []string) []string {
files := make(map[string]types.File)
repairStrategy := config.Get().Repair.Strategy

View File

@@ -246,35 +246,6 @@ func (wb *Web) handleUpdateConfig(w http.ResponseWriter, r *http.Request) {
return
}
// Get the current configuration
currentConfig := config.Get()
// Update fields that can be changed
currentConfig.LogLevel = updatedConfig.LogLevel
currentConfig.MinFileSize = updatedConfig.MinFileSize
currentConfig.MaxFileSize = updatedConfig.MaxFileSize
currentConfig.RemoveStalledAfter = updatedConfig.RemoveStalledAfter
currentConfig.AllowedExt = updatedConfig.AllowedExt
currentConfig.DiscordWebhook = updatedConfig.DiscordWebhook
// Should this be added?
currentConfig.URLBase = updatedConfig.URLBase
currentConfig.BindAddress = updatedConfig.BindAddress
currentConfig.Port = updatedConfig.Port
// Update QBitTorrent config
currentConfig.QBitTorrent = updatedConfig.QBitTorrent
// Update Repair config
currentConfig.Repair = updatedConfig.Repair
currentConfig.Rclone = updatedConfig.Rclone
// Update Debrids
if len(updatedConfig.Debrids) > 0 {
currentConfig.Debrids = updatedConfig.Debrids
// Clear legacy single debrid if using array
}
// Update Arrs through the service
storage := wire.Get()
arrStorage := storage.Arr()
@@ -287,10 +258,10 @@ func (wb *Web) handleUpdateConfig(w http.ResponseWriter, r *http.Request) {
}
newConfigArrs = append(newConfigArrs, a)
}
currentConfig.Arrs = newConfigArrs
updatedConfig.Arrs = newConfigArrs
// Add config arr into the config
for _, a := range currentConfig.Arrs {
for _, a := range updatedConfig.Arrs {
if a.Host == "" || a.Token == "" {
continue // Skip empty arrs
}
@@ -312,7 +283,7 @@ func (wb *Web) handleUpdateConfig(w http.ResponseWriter, r *http.Request) {
}
}
if err := currentConfig.Save(); err != nil {
if err := updatedConfig.Save(); err != nil {
http.Error(w, "Error saving config: "+err.Error(), http.StatusInternalServerError)
return
}

File diff suppressed because one or more lines are too long

View File

@@ -1085,6 +1085,7 @@ class ConfigManager {
min_file_size: document.getElementById('minFileSize').value,
max_file_size: document.getElementById('maxFileSize').value,
remove_stalled_after: document.getElementById('removeStalledAfter').value,
callback_url: document.getElementById('callbackUrl').value,
// Debrid configurations
debrids: this.collectDebridConfigs(),

View File

@@ -120,7 +120,7 @@
</div>
</div>
<div class="grid grid-cols-1 lg:grid-cols-3 gap-4">
<div class="grid grid-cols-1 lg:grid-cols-2 gap-4">
<div class="form-control">
<label class="label" for="minFileSize">
<span class="label-text font-medium">Minimum File Size</span>
@@ -150,6 +150,15 @@
<span class="label-text-alt">Duration before removing stalled torrents</span>
</div>
</div>
<div class="form-control">
<label class="label" for="callbackUrl">
<span class="label-text font-medium">Callback URL</span>
</label>
<input type="text" class="input input-bordered" id="callbackUrl" name="callback_url" placeholder="http://example.com/callback">
<div class="label">
<span class="label-text-alt">Optional callback URL for download status updates</span>
</div>
</div>
</div>
<!-- Authentication Settings Section -->
@@ -364,71 +373,68 @@
</div>
<div class="grid grid-cols-1 lg:grid-cols-2 gap-4">
<div class="space-y-4">
<div class="form-control">
<label class="label" for="repair.interval">
<span class="label-text font-medium">Repair Interval</span>
</label>
<input type="text" class="input input-bordered" name="repair.interval" id="repair.interval" placeholder="24h">
<div class="label">
<span class="label-text-alt">How often to run repair (e.g., 24h, 1d, 03:00, or crontab)</span>
</div>
</div>
<div class="form-control">
<label class="label" for="repair.workers">
<span class="label-text font-medium">Worker Threads</span>
</label>
<input type="number" class="input input-bordered" name="repair.workers" id="repair.workers" min="1" placeholder="40">
<div class="label">
<span class="label-text-alt">Number of concurrent repair workers</span>
</div>
</div>
<div class="form-control">
<label class="label" for="repair.strategy">
<span class="label-text font-medium">Repair Strategy</span>
</label>
<select class="select select-bordered" name="repair.strategy" id="repair.strategy">
<option value="per_torrent" selected>Per Torrent</option>
<option value="per_file">Per File</option>
</select>
<div class="label">
<span class="label-text-alt">How to handle repairs</span>
</div>
<div class="form-control">
<label class="label" for="repair.interval">
<span class="label-text font-medium">Repair Interval</span>
</label>
<input type="text" class="input input-bordered" name="repair.interval" id="repair.interval" placeholder="24h">
<div class="label">
<span class="label-text-alt">How often to run repair (e.g., 24h, 1d, 03:00, or crontab)</span>
</div>
</div>
<div class="space-y-4">
<div class="form-control">
<label class="label" for="repair.zurg_url">
<span class="label-text font-medium">Zurg URL</span>
</label>
<input type="url" class="input input-bordered" name="repair.zurg_url" id="repair.zurg_url" placeholder="http://zurg:9999">
<div class="label">
<span class="label-text-alt">Optional Zurg instance to speed up repairs</span>
<div class="form-control">
<label class="label" for="repair.workers">
<span class="label-text font-medium">Worker Threads</span>
</label>
<input type="number" class="input input-bordered" name="repair.workers" id="repair.workers" min="1" placeholder="40">
<div class="label">
<span class="label-text-alt">Number of concurrent repair workers</span>
</div>
</div>
<div class="form-control">
<label class="label" for="repair.strategy">
<span class="label-text font-medium">Repair Strategy</span>
</label>
<select class="select select-bordered" name="repair.strategy" id="repair.strategy">
<option value="per_torrent" selected>Per Torrent</option>
<option value="per_file">Per File</option>
</select>
<div class="label">
<span class="label-text-alt">How to handle repairs</span>
</div>
</div>
<div class="form-control">
<label class="label" for="repair.zurg_url">
<span class="label-text font-medium">Zurg URL</span>
</label>
<input type="url" class="input input-bordered" name="repair.zurg_url" id="repair.zurg_url" placeholder="http://zurg:9999">
<div class="label">
<span class="label-text-alt">Optional Zurg instance to speed up repairs</span>
</div>
</div>
</div>
<div class="grid grid-cols-2 lg:grid-cols-3 gap-4">
<div class="form-control">
<label class="label cursor-pointer justify-start gap-3">
<input type="checkbox" class="checkbox" name="repair.use_webdav" id="repair.use_webdav">
<div>
<span class="label-text font-medium">Use WebDAV</span>
<div class="label-text-alt">Use internal WebDAV for repairs</div>
</div>
</div>
</label>
</div>
<div class="form-control">
<label class="label cursor-pointer justify-start gap-3">
<input type="checkbox" class="checkbox" name="repair.use_webdav" id="repair.use_webdav">
<div>
<span class="label-text font-medium">Use WebDAV</span>
<div class="label-text-alt">Use internal WebDAV for repairs</div>
</div>
</label>
</div>
<div class="form-control">
<label class="label cursor-pointer justify-start gap-3">
<input type="checkbox" class="checkbox" name="repair.auto_process" id="repair.auto_process">
<div>
<span class="label-text font-medium">Auto Process</span>
<div class="label-text-alt">Automatically delete broken symlinks and re-search</div>
</div>
</label>
</div>
<div class="form-control">
<label class="label cursor-pointer justify-start gap-3">
<input type="checkbox" class="checkbox" name="repair.auto_process" id="repair.auto_process">
<div>
<span class="label-text font-medium">Auto Process</span>
<div class="label-text-alt">Automatically delete broken symlinks and re-search</div>
</div>
</label>
</div>
</div>
</div>

View File

@@ -7,6 +7,7 @@ import (
"encoding/json"
"fmt"
"github.com/google/uuid"
"github.com/sirrobot01/decypharr/internal/config"
"github.com/sirrobot01/decypharr/internal/request"
"github.com/sirrobot01/decypharr/internal/utils"
"github.com/sirrobot01/decypharr/pkg/arr"
@@ -43,6 +44,8 @@ type ImportRequest struct {
}
func NewImportRequest(debrid string, downloadFolder string, magnet *utils.Magnet, arr *arr.Arr, action string, downloadUncached bool, callBackUrl string, importType ImportType) *ImportRequest {
cfg := config.Get()
callBackUrl = cmp.Or(callBackUrl, cfg.CallbackURL)
return &ImportRequest{
Id: uuid.New().String(),
Status: "started",