Add album/track releases with audio analysis, AnalyzeAlbumRelease RPC, Docker path auto-resolution, release parsing decision tree
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
package torrent
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
dockerclient "github.com/docker/docker/client"
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
type PathMapper struct {
|
||||
containerPath string
|
||||
hostPath string
|
||||
}
|
||||
|
||||
func NewPathMapper(containerName string, torrentClient TorrentClient) (*PathMapper, error) {
|
||||
if containerName == "" {
|
||||
savePath, err := torrentClient.DefaultSavePath()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("getting default save path: %w", err)
|
||||
}
|
||||
log.Info().Str("path", savePath).Msg("no container configured, using direct path")
|
||||
return &PathMapper{containerPath: savePath, hostPath: savePath}, nil
|
||||
}
|
||||
|
||||
savePath, err := torrentClient.DefaultSavePath()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("getting default save path: %w", err)
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
defer cancel()
|
||||
|
||||
cli, err := dockerclient.NewClientWithOpts(dockerclient.FromEnv, dockerclient.WithAPIVersionNegotiation())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("creating docker client: %w", err)
|
||||
}
|
||||
defer cli.Close()
|
||||
|
||||
inspect, err := cli.ContainerInspect(ctx, containerName)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("inspecting container %s: %w", containerName, err)
|
||||
}
|
||||
|
||||
hostPath := ""
|
||||
for _, mount := range inspect.Mounts {
|
||||
if mount.Destination == savePath {
|
||||
hostPath = mount.Source
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if hostPath == "" {
|
||||
return nil, fmt.Errorf("no mount found for %s in container %s", savePath, containerName)
|
||||
}
|
||||
|
||||
log.Info().
|
||||
Str("container", containerName).
|
||||
Str("container_path", savePath).
|
||||
Str("host_path", hostPath).
|
||||
Msg("resolved download path mapping")
|
||||
|
||||
return &PathMapper{containerPath: savePath, hostPath: hostPath}, nil
|
||||
}
|
||||
|
||||
func (m *PathMapper) ToHost(containerPath string) string {
|
||||
if m.containerPath == m.hostPath {
|
||||
return containerPath
|
||||
}
|
||||
return strings.Replace(containerPath, m.containerPath, m.hostPath, 1)
|
||||
}
|
||||
|
||||
func (m *PathMapper) ToContainer(hostPath string) string {
|
||||
if m.containerPath == m.hostPath {
|
||||
return hostPath
|
||||
}
|
||||
return strings.Replace(hostPath, m.hostPath, m.containerPath, 1)
|
||||
}
|
||||
|
||||
func (m *PathMapper) HostDownloadPath() string {
|
||||
return m.hostPath
|
||||
}
|
||||
|
||||
func (m *PathMapper) ContainerDownloadPath() string {
|
||||
return m.containerPath
|
||||
}
|
||||
Reference in New Issue
Block a user