Fix issues with dir-cache-time, umask and wrongly set gid,uid, add extra vfs options
This commit is contained in:
@@ -105,7 +105,6 @@ type Rclone struct {
|
|||||||
VfsReadChunkSize string `json:"vfs_read_chunk_size,omitempty"` // Read chunk size (default 128M)
|
VfsReadChunkSize string `json:"vfs_read_chunk_size,omitempty"` // Read chunk size (default 128M)
|
||||||
VfsReadChunkSizeLimit string `json:"vfs_read_chunk_size_limit,omitempty"` // Max chunk size (default off)
|
VfsReadChunkSizeLimit string `json:"vfs_read_chunk_size_limit,omitempty"` // Max chunk size (default off)
|
||||||
VfsReadAhead string `json:"vfs_read_ahead,omitempty"` // read ahead size
|
VfsReadAhead string `json:"vfs_read_ahead,omitempty"` // read ahead size
|
||||||
VfsPollInterval string `json:"vfs_poll_interval,omitempty"` // How often to rclone cleans the cache (default 1m)
|
|
||||||
BufferSize string `json:"buffer_size,omitempty"` // Buffer size for reading files (default 16M)
|
BufferSize string `json:"buffer_size,omitempty"` // Buffer size for reading files (default 16M)
|
||||||
|
|
||||||
VfsCacheMinFreeSpace string `json:"vfs_cache_min_free_space,omitempty"`
|
VfsCacheMinFreeSpace string `json:"vfs_cache_min_free_space,omitempty"`
|
||||||
|
|||||||
@@ -6,15 +6,16 @@ import (
|
|||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/rs/zerolog"
|
|
||||||
"github.com/sirrobot01/decypharr/internal/config"
|
|
||||||
"github.com/sirrobot01/decypharr/internal/logger"
|
|
||||||
"github.com/sirrobot01/decypharr/internal/request"
|
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/rs/zerolog"
|
||||||
|
"github.com/sirrobot01/decypharr/internal/config"
|
||||||
|
"github.com/sirrobot01/decypharr/internal/logger"
|
||||||
|
"github.com/sirrobot01/decypharr/internal/request"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Type is a type of arr
|
// Type is a type of arr
|
||||||
@@ -109,7 +110,7 @@ func (a *Arr) Request(method, endpoint string, payload interface{}) (*http.Respo
|
|||||||
|
|
||||||
func (a *Arr) Validate() error {
|
func (a *Arr) Validate() error {
|
||||||
if a.Token == "" || a.Host == "" {
|
if a.Token == "" || a.Host == "" {
|
||||||
return fmt.Errorf("arr not configured: %s", a.Name)
|
return nil
|
||||||
}
|
}
|
||||||
resp, err := a.Request("GET", "/api/v3/health", nil)
|
resp, err := a.Request("GET", "/api/v3/health", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -3,13 +3,14 @@ package store
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/sirrobot01/decypharr/pkg/debrid/types"
|
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/sirrobot01/decypharr/pkg/debrid/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
type fileInfo struct {
|
type fileInfo struct {
|
||||||
@@ -120,7 +121,7 @@ func (c *Cache) refreshTorrents(ctx context.Context) {
|
|||||||
close(workChan)
|
close(workChan)
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
|
|
||||||
c.listingDebouncer.Call(false)
|
c.listingDebouncer.Call(true)
|
||||||
|
|
||||||
c.logger.Debug().Msgf("Processed %d new torrents", counter)
|
c.logger.Debug().Msgf("Processed %d new torrents", counter)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
package types
|
package types
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/sirrobot01/decypharr/internal/config"
|
|
||||||
"slices"
|
"slices"
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
|
||||||
|
"github.com/sirrobot01/decypharr/internal/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Accounts struct {
|
type Accounts struct {
|
||||||
@@ -35,7 +36,6 @@ type Account struct {
|
|||||||
Debrid string // e.g., "realdebrid", "torbox", etc.
|
Debrid string // e.g., "realdebrid", "torbox", etc.
|
||||||
Order int
|
Order int
|
||||||
Disabled bool
|
Disabled bool
|
||||||
InUse bool
|
|
||||||
Token string `json:"token"`
|
Token string `json:"token"`
|
||||||
links map[string]*DownloadLink
|
links map[string]*DownloadLink
|
||||||
mu sync.RWMutex
|
mu sync.RWMutex
|
||||||
@@ -103,16 +103,6 @@ func (a *Accounts) setCurrent(account *Account) {
|
|||||||
if account == nil {
|
if account == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Set every account InUse to false
|
|
||||||
a.accounts.Range(func(key, value interface{}) bool {
|
|
||||||
acc, ok := value.(*Account)
|
|
||||||
if ok {
|
|
||||||
acc.InUse = false
|
|
||||||
a.accounts.Store(key, acc)
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
account.InUse = true
|
|
||||||
a.current.Store(account)
|
a.current.Store(account)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/sirrobot01/decypharr/internal/config"
|
"github.com/sirrobot01/decypharr/internal/config"
|
||||||
@@ -115,7 +116,8 @@ func (m *Manager) performMount(mountPath, provider, webdavURL string) error {
|
|||||||
mountArgs["_config"] = configOpts
|
mountArgs["_config"] = configOpts
|
||||||
}
|
}
|
||||||
vfsOpt := map[string]interface{}{
|
vfsOpt := map[string]interface{}{
|
||||||
"CacheMode": cfg.Rclone.VfsCacheMode,
|
"CacheMode": cfg.Rclone.VfsCacheMode,
|
||||||
|
"DirCacheTime": cfg.Rclone.DirCacheTime,
|
||||||
}
|
}
|
||||||
vfsOpt["PollInterval"] = 0 // Poll interval not supported for webdav, set to 0
|
vfsOpt["PollInterval"] = 0 // Poll interval not supported for webdav, set to 0
|
||||||
|
|
||||||
@@ -125,6 +127,13 @@ func (m *Manager) performMount(mountPath, provider, webdavURL string) error {
|
|||||||
if cfg.Rclone.VfsCacheMaxAge != "" {
|
if cfg.Rclone.VfsCacheMaxAge != "" {
|
||||||
vfsOpt["CacheMaxAge"] = cfg.Rclone.VfsCacheMaxAge
|
vfsOpt["CacheMaxAge"] = cfg.Rclone.VfsCacheMaxAge
|
||||||
}
|
}
|
||||||
|
if cfg.Rclone.VfsDiskSpaceTotal != "" {
|
||||||
|
vfsOpt["DiskSpaceTotalSize"] = cfg.Rclone.VfsDiskSpaceTotal
|
||||||
|
}
|
||||||
|
if cfg.Rclone.VfsReadChunkSizeLimit != "" {
|
||||||
|
vfsOpt["ChunkSizeLimit"] = cfg.Rclone.VfsReadChunkSizeLimit
|
||||||
|
}
|
||||||
|
|
||||||
if cfg.Rclone.VfsCacheMaxSize != "" {
|
if cfg.Rclone.VfsCacheMaxSize != "" {
|
||||||
vfsOpt["CacheMaxSize"] = cfg.Rclone.VfsCacheMaxSize
|
vfsOpt["CacheMaxSize"] = cfg.Rclone.VfsCacheMaxSize
|
||||||
}
|
}
|
||||||
@@ -147,7 +156,7 @@ func (m *Manager) performMount(mountPath, provider, webdavURL string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if cfg.Rclone.VfsReadChunkStreams != 0 {
|
if cfg.Rclone.VfsReadChunkStreams != 0 {
|
||||||
vfsOpt["ReadChunkStreams"] = cfg.Rclone.VfsReadChunkStreams
|
vfsOpt["ChunkStreams"] = cfg.Rclone.VfsReadChunkStreams
|
||||||
}
|
}
|
||||||
|
|
||||||
if cfg.Rclone.NoChecksum {
|
if cfg.Rclone.NoChecksum {
|
||||||
@@ -160,11 +169,19 @@ func (m *Manager) performMount(mountPath, provider, webdavURL string) error {
|
|||||||
|
|
||||||
// Add mount options based on configuration
|
// Add mount options based on configuration
|
||||||
if cfg.Rclone.UID != 0 {
|
if cfg.Rclone.UID != 0 {
|
||||||
mountOpt["UID"] = cfg.Rclone.UID
|
vfsOpt["UID"] = cfg.Rclone.UID
|
||||||
}
|
}
|
||||||
if cfg.Rclone.GID != 0 {
|
if cfg.Rclone.GID != 0 {
|
||||||
mountOpt["GID"] = cfg.Rclone.GID
|
vfsOpt["GID"] = cfg.Rclone.GID
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if cfg.Rclone.Umask != "" {
|
||||||
|
umask, err := strconv.ParseInt(cfg.Rclone.Umask, 8, 32)
|
||||||
|
if err == nil {
|
||||||
|
vfsOpt["Umask"] = uint32(umask)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if cfg.Rclone.AttrTimeout != "" {
|
if cfg.Rclone.AttrTimeout != "" {
|
||||||
if attrTimeout, err := time.ParseDuration(cfg.Rclone.AttrTimeout); err == nil {
|
if attrTimeout, err := time.ParseDuration(cfg.Rclone.AttrTimeout); err == nil {
|
||||||
mountOpt["AttrTimeout"] = attrTimeout.String()
|
mountOpt["AttrTimeout"] = attrTimeout.String()
|
||||||
@@ -182,7 +199,7 @@ func (m *Manager) performMount(mountPath, provider, webdavURL string) error {
|
|||||||
_, err := m.makeRequest(req, true)
|
_, err := m.makeRequest(req, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Clean up mount point on failure
|
// Clean up mount point on failure
|
||||||
m.forceUnmountPath(mountPath)
|
_ = m.forceUnmountPath(mountPath)
|
||||||
return fmt.Errorf("failed to create mount for %s: %w", provider, err)
|
return fmt.Errorf("failed to create mount for %s: %w", provider, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,11 +3,12 @@ package rclone
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/rs/zerolog"
|
|
||||||
"github.com/sirrobot01/decypharr/internal/config"
|
|
||||||
"net/url"
|
"net/url"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/rs/zerolog"
|
||||||
|
"github.com/sirrobot01/decypharr/internal/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Mount represents a mount using the rclone RC client
|
// Mount represents a mount using the rclone RC client
|
||||||
|
|||||||
@@ -136,7 +136,6 @@ func (s *Server) handleStats(w http.ResponseWriter, r *http.Request) {
|
|||||||
accountDetail := map[string]any{
|
accountDetail := map[string]any{
|
||||||
"order": account.Order,
|
"order": account.Order,
|
||||||
"disabled": account.Disabled,
|
"disabled": account.Disabled,
|
||||||
"in_use": account.InUse,
|
|
||||||
"token_masked": maskedToken,
|
"token_masked": maskedToken,
|
||||||
"username": account.Username,
|
"username": account.Username,
|
||||||
"traffic_used": account.TrafficUsed,
|
"traffic_used": account.TrafficUsed,
|
||||||
|
|||||||
@@ -372,10 +372,6 @@
|
|||||||
'<span class="badge badge-error badge-sm">Disabled</span>' :
|
'<span class="badge badge-error badge-sm">Disabled</span>' :
|
||||||
'<span class="badge badge-success badge-sm">Active</span>';
|
'<span class="badge badge-success badge-sm">Active</span>';
|
||||||
|
|
||||||
const inUseBadge = account.in_use ?
|
|
||||||
'<span class="badge badge-info badge-sm">In Use</span>' :
|
|
||||||
'';
|
|
||||||
|
|
||||||
html += `
|
html += `
|
||||||
<div class="card bg-base-100 compact">
|
<div class="card bg-base-100 compact">
|
||||||
<div class="card-body p-3">
|
<div class="card-body p-3">
|
||||||
|
|||||||
Reference in New Issue
Block a user