Add callback URL for post-processing
This commit is contained in:
@@ -152,6 +152,7 @@ type Config struct {
|
|||||||
Auth *Auth `json:"-"`
|
Auth *Auth `json:"-"`
|
||||||
DiscordWebhook string `json:"discord_webhook_url,omitempty"`
|
DiscordWebhook string `json:"discord_webhook_url,omitempty"`
|
||||||
RemoveStalledAfter string `json:"remove_stalled_after,omitzero"`
|
RemoveStalledAfter string `json:"remove_stalled_after,omitzero"`
|
||||||
|
CallbackURL string `json:"callback_url,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Config) JsonFile() string {
|
func (c *Config) JsonFile() string {
|
||||||
|
|||||||
@@ -45,6 +45,8 @@ func getDiscordHeader(event string) string {
|
|||||||
return "[Decypharr] Repair Completed, Awaiting action"
|
return "[Decypharr] Repair Completed, Awaiting action"
|
||||||
case "repair_complete":
|
case "repair_complete":
|
||||||
return "[Decypharr] Repair Complete"
|
return "[Decypharr] Repair Complete"
|
||||||
|
case "repair_cancelled":
|
||||||
|
return "[Decypharr] Repair Cancelled"
|
||||||
default:
|
default:
|
||||||
// split the event string and capitalize the first letter of each word
|
// split the event string and capitalize the first letter of each word
|
||||||
evs := strings.Split(event, "_")
|
evs := strings.Split(event, "_")
|
||||||
|
|||||||
@@ -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 {
|
func (c *Cache) GetBrokenFiles(t *CachedTorrent, filenames []string) []string {
|
||||||
files := make(map[string]types.File)
|
files := make(map[string]types.File)
|
||||||
repairStrategy := config.Get().Repair.Strategy
|
repairStrategy := config.Get().Repair.Strategy
|
||||||
|
|||||||
@@ -246,35 +246,6 @@ func (wb *Web) handleUpdateConfig(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
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
|
// Update Arrs through the service
|
||||||
storage := wire.Get()
|
storage := wire.Get()
|
||||||
arrStorage := storage.Arr()
|
arrStorage := storage.Arr()
|
||||||
@@ -287,10 +258,10 @@ func (wb *Web) handleUpdateConfig(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
newConfigArrs = append(newConfigArrs, a)
|
newConfigArrs = append(newConfigArrs, a)
|
||||||
}
|
}
|
||||||
currentConfig.Arrs = newConfigArrs
|
updatedConfig.Arrs = newConfigArrs
|
||||||
|
|
||||||
// Add config arr into the config
|
// Add config arr into the config
|
||||||
for _, a := range currentConfig.Arrs {
|
for _, a := range updatedConfig.Arrs {
|
||||||
if a.Host == "" || a.Token == "" {
|
if a.Host == "" || a.Token == "" {
|
||||||
continue // Skip empty arrs
|
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)
|
http.Error(w, "Error saving config: "+err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -1085,6 +1085,7 @@ class ConfigManager {
|
|||||||
min_file_size: document.getElementById('minFileSize').value,
|
min_file_size: document.getElementById('minFileSize').value,
|
||||||
max_file_size: document.getElementById('maxFileSize').value,
|
max_file_size: document.getElementById('maxFileSize').value,
|
||||||
remove_stalled_after: document.getElementById('removeStalledAfter').value,
|
remove_stalled_after: document.getElementById('removeStalledAfter').value,
|
||||||
|
callback_url: document.getElementById('callbackUrl').value,
|
||||||
|
|
||||||
// Debrid configurations
|
// Debrid configurations
|
||||||
debrids: this.collectDebridConfigs(),
|
debrids: this.collectDebridConfigs(),
|
||||||
|
|||||||
@@ -120,7 +120,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</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">
|
<div class="form-control">
|
||||||
<label class="label" for="minFileSize">
|
<label class="label" for="minFileSize">
|
||||||
<span class="label-text font-medium">Minimum File Size</span>
|
<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>
|
<span class="label-text-alt">Duration before removing stalled torrents</span>
|
||||||
</div>
|
</div>
|
||||||
</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>
|
</div>
|
||||||
|
|
||||||
<!-- Authentication Settings Section -->
|
<!-- Authentication Settings Section -->
|
||||||
@@ -364,71 +373,68 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="grid grid-cols-1 lg:grid-cols-2 gap-4">
|
<div class="grid grid-cols-1 lg:grid-cols-2 gap-4">
|
||||||
<div class="space-y-4">
|
<div class="form-control">
|
||||||
<div class="form-control">
|
<label class="label" for="repair.interval">
|
||||||
<label class="label" for="repair.interval">
|
<span class="label-text font-medium">Repair Interval</span>
|
||||||
<span class="label-text font-medium">Repair Interval</span>
|
</label>
|
||||||
</label>
|
<input type="text" class="input input-bordered" name="repair.interval" id="repair.interval" placeholder="24h">
|
||||||
<input type="text" class="input input-bordered" name="repair.interval" id="repair.interval" placeholder="24h">
|
<div class="label">
|
||||||
<div class="label">
|
<span class="label-text-alt">How often to run repair (e.g., 24h, 1d, 03:00, or crontab)</span>
|
||||||
<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>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="space-y-4">
|
<div class="form-control">
|
||||||
<div class="form-control">
|
<label class="label" for="repair.workers">
|
||||||
<label class="label" for="repair.zurg_url">
|
<span class="label-text font-medium">Worker Threads</span>
|
||||||
<span class="label-text font-medium">Zurg URL</span>
|
</label>
|
||||||
</label>
|
<input type="number" class="input input-bordered" name="repair.workers" id="repair.workers" min="1" placeholder="40">
|
||||||
<input type="url" class="input input-bordered" name="repair.zurg_url" id="repair.zurg_url" placeholder="http://zurg:9999">
|
<div class="label">
|
||||||
<div class="label">
|
<span class="label-text-alt">Number of concurrent repair workers</span>
|
||||||
<span class="label-text-alt">Optional Zurg instance to speed up repairs</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>
|
||||||
</div>
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="form-control">
|
<div class="form-control">
|
||||||
<label class="label cursor-pointer justify-start gap-3">
|
<label class="label cursor-pointer justify-start gap-3">
|
||||||
<input type="checkbox" class="checkbox" name="repair.use_webdav" id="repair.use_webdav">
|
<input type="checkbox" class="checkbox" name="repair.auto_process" id="repair.auto_process">
|
||||||
<div>
|
<div>
|
||||||
<span class="label-text font-medium">Use WebDAV</span>
|
<span class="label-text font-medium">Auto Process</span>
|
||||||
<div class="label-text-alt">Use internal WebDAV for repairs</div>
|
<div class="label-text-alt">Automatically delete broken symlinks and re-search</div>
|
||||||
</div>
|
</div>
|
||||||
</label>
|
</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>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
|
"github.com/sirrobot01/decypharr/internal/config"
|
||||||
"github.com/sirrobot01/decypharr/internal/request"
|
"github.com/sirrobot01/decypharr/internal/request"
|
||||||
"github.com/sirrobot01/decypharr/internal/utils"
|
"github.com/sirrobot01/decypharr/internal/utils"
|
||||||
"github.com/sirrobot01/decypharr/pkg/arr"
|
"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 {
|
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{
|
return &ImportRequest{
|
||||||
Id: uuid.New().String(),
|
Id: uuid.New().String(),
|
||||||
Status: "started",
|
Status: "started",
|
||||||
|
|||||||
Reference in New Issue
Block a user