83 lines
2.0 KiB
Go
83 lines
2.0 KiB
Go
// backend/internal/refresh.go
|
|
package internal
|
|
|
|
import (
|
|
"io"
|
|
"log"
|
|
"net/http"
|
|
"os"
|
|
"strings"
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
// Debounce refresh calls so a burst of uploads/renames/deletes only triggers one scan.
|
|
var (
|
|
refreshMu sync.Mutex
|
|
refreshTimer *time.Timer
|
|
)
|
|
|
|
// RefreshLibrary triggers a Jellyfin library scan.
|
|
// - Prefers JELLYFIN_API_KEY (admin key). Falls back to userToken if no key.
|
|
// - Debounced: calls within 2s are coalesced to a single scan.
|
|
func (j *Jellyfin) RefreshLibrary(userToken string) {
|
|
refreshMu.Lock()
|
|
defer refreshMu.Unlock()
|
|
|
|
if refreshTimer != nil {
|
|
// push the timer out a bit if more events arrive
|
|
refreshTimer.Reset(2 * time.Second)
|
|
return
|
|
}
|
|
|
|
refreshTimer = time.AfterFunc(2*time.Second, func() {
|
|
base := strings.TrimRight(os.Getenv("JELLYFIN_URL"), "/")
|
|
if base == "" {
|
|
log.Printf("jellyfin refresh: JELLYFIN_URL missing; skipping")
|
|
safeClearTimer()
|
|
return
|
|
}
|
|
token := os.Getenv("JELLYFIN_API_KEY")
|
|
if token == "" {
|
|
token = userToken // last resort (may fail if user is not admin)
|
|
}
|
|
if token == "" {
|
|
log.Printf("jellyfin refresh: no token; skipping")
|
|
safeClearTimer()
|
|
return
|
|
}
|
|
|
|
req, _ := http.NewRequest(http.MethodPost, base+"/Library/Refresh", nil)
|
|
// Jellyfin/Emby accept API key via header or query; header is cleanest.
|
|
// Either X-Emby-Token or X-MediaBrowser-Token are accepted; we use X-Emby-Token.
|
|
req.Header.Set("X-Emby-Token", token)
|
|
|
|
client := j.Client
|
|
if client == nil {
|
|
client = &http.Client{Timeout: 20 * time.Second}
|
|
}
|
|
resp, err := client.Do(req)
|
|
if err != nil {
|
|
log.Printf("jellyfin refresh: request error: %v", err)
|
|
safeClearTimer()
|
|
return
|
|
}
|
|
_, _ = io.Copy(io.Discard, resp.Body)
|
|
_ = resp.Body.Close()
|
|
|
|
if resp.StatusCode >= 300 {
|
|
log.Printf("jellyfin refresh: HTTP %s", resp.Status)
|
|
} else {
|
|
log.Printf("jellyfin refresh: triggered")
|
|
}
|
|
|
|
safeClearTimer()
|
|
})
|
|
}
|
|
|
|
func safeClearTimer() {
|
|
refreshMu.Lock()
|
|
defer refreshMu.Unlock()
|
|
refreshTimer = nil
|
|
}
|