chore: rename module from torrentclaw-cli to unarr
- Rename Go module path github.com/torrentclaw/torrentclaw-cli → github.com/torrentclaw/unarr - Update all imports, ldflags, scripts, docs, and Docker config - Add GitHub Actions release workflow (goreleaser on tag push)
This commit is contained in:
parent
9cc806d11f
commit
5a7449b9e6
58 changed files with 166 additions and 141 deletions
|
|
@ -6,7 +6,7 @@ import (
|
|||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/torrentclaw/torrentclaw-cli/internal/config"
|
||||
"github.com/torrentclaw/unarr/internal/config"
|
||||
)
|
||||
|
||||
// DaemonState is written to disk every heartbeat for external tools to read.
|
||||
|
|
|
|||
|
|
@ -10,9 +10,9 @@ import (
|
|||
|
||||
"github.com/fatih/color"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/torrentclaw/torrentclaw-cli/internal/agent"
|
||||
"github.com/torrentclaw/torrentclaw-cli/internal/config"
|
||||
"github.com/torrentclaw/torrentclaw-cli/internal/ui"
|
||||
"github.com/torrentclaw/unarr/internal/agent"
|
||||
"github.com/torrentclaw/unarr/internal/config"
|
||||
"github.com/torrentclaw/unarr/internal/ui"
|
||||
)
|
||||
|
||||
func newCleanCmd() *cobra.Command {
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import (
|
|||
"github.com/charmbracelet/huh"
|
||||
"github.com/fatih/color"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/torrentclaw/torrentclaw-cli/internal/config"
|
||||
"github.com/torrentclaw/unarr/internal/config"
|
||||
)
|
||||
|
||||
var configCategories = []string{"downloads", "organization", "notifications", "device", "region", "connection", "advanced"}
|
||||
|
|
|
|||
|
|
@ -13,12 +13,12 @@ import (
|
|||
|
||||
"github.com/fatih/color"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/torrentclaw/torrentclaw-cli/internal/agent"
|
||||
"github.com/torrentclaw/torrentclaw-cli/internal/config"
|
||||
"github.com/torrentclaw/torrentclaw-cli/internal/engine"
|
||||
"github.com/torrentclaw/torrentclaw-cli/internal/library"
|
||||
"github.com/torrentclaw/torrentclaw-cli/internal/usenet/download"
|
||||
"github.com/torrentclaw/torrentclaw-cli/internal/upgrade"
|
||||
"github.com/torrentclaw/unarr/internal/agent"
|
||||
"github.com/torrentclaw/unarr/internal/config"
|
||||
"github.com/torrentclaw/unarr/internal/engine"
|
||||
"github.com/torrentclaw/unarr/internal/library"
|
||||
"github.com/torrentclaw/unarr/internal/usenet/download"
|
||||
"github.com/torrentclaw/unarr/internal/upgrade"
|
||||
)
|
||||
|
||||
// newStartCmd creates the top-level `unarr start` command.
|
||||
|
|
|
|||
|
|
@ -9,8 +9,8 @@ import (
|
|||
|
||||
"github.com/fatih/color"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/torrentclaw/torrentclaw-cli/internal/agent"
|
||||
"github.com/torrentclaw/torrentclaw-cli/internal/config"
|
||||
"github.com/torrentclaw/unarr/internal/agent"
|
||||
"github.com/torrentclaw/unarr/internal/config"
|
||||
)
|
||||
|
||||
func newDoctorCmd() *cobra.Command {
|
||||
|
|
|
|||
|
|
@ -12,9 +12,9 @@ import (
|
|||
|
||||
"github.com/fatih/color"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/torrentclaw/torrentclaw-cli/internal/agent"
|
||||
"github.com/torrentclaw/torrentclaw-cli/internal/engine"
|
||||
"github.com/torrentclaw/torrentclaw-cli/internal/parser"
|
||||
"github.com/torrentclaw/unarr/internal/agent"
|
||||
"github.com/torrentclaw/unarr/internal/engine"
|
||||
"github.com/torrentclaw/unarr/internal/parser"
|
||||
)
|
||||
|
||||
func newDownloadCmd() *cobra.Command {
|
||||
|
|
|
|||
|
|
@ -13,10 +13,10 @@ import (
|
|||
"github.com/fatih/color"
|
||||
"github.com/google/uuid"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/torrentclaw/torrentclaw-cli/internal/agent"
|
||||
"github.com/torrentclaw/torrentclaw-cli/internal/arr"
|
||||
"github.com/torrentclaw/torrentclaw-cli/internal/config"
|
||||
"github.com/torrentclaw/torrentclaw-cli/internal/mediaserver"
|
||||
"github.com/torrentclaw/unarr/internal/agent"
|
||||
"github.com/torrentclaw/unarr/internal/arr"
|
||||
"github.com/torrentclaw/unarr/internal/config"
|
||||
"github.com/torrentclaw/unarr/internal/mediaserver"
|
||||
)
|
||||
|
||||
func newInitCmd() *cobra.Command {
|
||||
|
|
|
|||
|
|
@ -9,8 +9,8 @@ import (
|
|||
"github.com/spf13/cobra"
|
||||
tc "github.com/torrentclaw/go-client"
|
||||
|
||||
"github.com/torrentclaw/torrentclaw-cli/internal/parser"
|
||||
"github.com/torrentclaw/torrentclaw-cli/internal/ui"
|
||||
"github.com/torrentclaw/unarr/internal/parser"
|
||||
"github.com/torrentclaw/unarr/internal/ui"
|
||||
)
|
||||
|
||||
func newInspectCmd() *cobra.Command {
|
||||
|
|
|
|||
|
|
@ -11,10 +11,10 @@ import (
|
|||
"github.com/charmbracelet/huh"
|
||||
"github.com/fatih/color"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/torrentclaw/torrentclaw-cli/internal/agent"
|
||||
"github.com/torrentclaw/torrentclaw-cli/internal/arr"
|
||||
"github.com/torrentclaw/torrentclaw-cli/internal/config"
|
||||
"github.com/torrentclaw/torrentclaw-cli/internal/mediaserver"
|
||||
"github.com/torrentclaw/unarr/internal/agent"
|
||||
"github.com/torrentclaw/unarr/internal/arr"
|
||||
"github.com/torrentclaw/unarr/internal/config"
|
||||
"github.com/torrentclaw/unarr/internal/mediaserver"
|
||||
)
|
||||
|
||||
func newMigrateCmd() *cobra.Command {
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import (
|
|||
"github.com/spf13/cobra"
|
||||
tc "github.com/torrentclaw/go-client"
|
||||
|
||||
"github.com/torrentclaw/torrentclaw-cli/internal/ui"
|
||||
"github.com/torrentclaw/unarr/internal/ui"
|
||||
)
|
||||
|
||||
func newPopularCmd() *cobra.Command {
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import (
|
|||
"github.com/spf13/cobra"
|
||||
tc "github.com/torrentclaw/go-client"
|
||||
|
||||
"github.com/torrentclaw/torrentclaw-cli/internal/ui"
|
||||
"github.com/torrentclaw/unarr/internal/ui"
|
||||
)
|
||||
|
||||
func newRecentCmd() *cobra.Command {
|
||||
|
|
|
|||
|
|
@ -9,8 +9,8 @@ import (
|
|||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/torrentclaw/torrentclaw-cli/internal/agent"
|
||||
"github.com/torrentclaw/torrentclaw-cli/internal/config"
|
||||
"github.com/torrentclaw/unarr/internal/agent"
|
||||
"github.com/torrentclaw/unarr/internal/config"
|
||||
)
|
||||
|
||||
// ReloadableConfig holds a reference to the daemon for hot-reload.
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
package cmd
|
||||
|
||||
import "github.com/torrentclaw/torrentclaw-cli/internal/agent"
|
||||
import "github.com/torrentclaw/unarr/internal/agent"
|
||||
|
||||
// ReloadableConfig holds a reference to the daemon for hot-reload.
|
||||
type ReloadableConfig struct {
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@ import (
|
|||
|
||||
"github.com/fatih/color"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/torrentclaw/torrentclaw-cli/internal/config"
|
||||
"github.com/torrentclaw/torrentclaw-cli/internal/sentry"
|
||||
"github.com/torrentclaw/unarr/internal/config"
|
||||
"github.com/torrentclaw/unarr/internal/sentry"
|
||||
tc "github.com/torrentclaw/go-client"
|
||||
)
|
||||
|
||||
|
|
@ -37,7 +37,7 @@ Get started:
|
|||
unarr start Start the download daemon
|
||||
|
||||
Documentation: https://torrentclaw.com/cli
|
||||
Source: https://github.com/torrentclaw/torrentclaw-cli`,
|
||||
Source: https://github.com/torrentclaw/unarr`,
|
||||
PersistentPreRun: func(cmd *cobra.Command, args []string) {
|
||||
if noColor || os.Getenv("NO_COLOR") != "" {
|
||||
color.NoColor = true
|
||||
|
|
|
|||
|
|
@ -12,9 +12,9 @@ import (
|
|||
|
||||
"github.com/fatih/color"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/torrentclaw/torrentclaw-cli/internal/agent"
|
||||
"github.com/torrentclaw/torrentclaw-cli/internal/config"
|
||||
"github.com/torrentclaw/torrentclaw-cli/internal/library"
|
||||
"github.com/torrentclaw/unarr/internal/agent"
|
||||
"github.com/torrentclaw/unarr/internal/config"
|
||||
"github.com/torrentclaw/unarr/internal/library"
|
||||
)
|
||||
|
||||
func newScanCmd() *cobra.Command {
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import (
|
|||
"github.com/spf13/cobra"
|
||||
tc "github.com/torrentclaw/go-client"
|
||||
|
||||
"github.com/torrentclaw/torrentclaw-cli/internal/ui"
|
||||
"github.com/torrentclaw/unarr/internal/ui"
|
||||
)
|
||||
|
||||
func newSearchCmd() *cobra.Command {
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import (
|
|||
|
||||
"github.com/fatih/color"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/torrentclaw/torrentclaw-cli/internal/upgrade"
|
||||
"github.com/torrentclaw/unarr/internal/upgrade"
|
||||
)
|
||||
|
||||
func newSelfUpdateCmd() *cobra.Command {
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import (
|
|||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/torrentclaw/torrentclaw-cli/internal/ui"
|
||||
"github.com/torrentclaw/unarr/internal/ui"
|
||||
)
|
||||
|
||||
func newStatsCmd() *cobra.Command {
|
||||
|
|
|
|||
|
|
@ -12,9 +12,9 @@ import (
|
|||
|
||||
"github.com/fatih/color"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/torrentclaw/torrentclaw-cli/internal/engine"
|
||||
"github.com/torrentclaw/torrentclaw-cli/internal/parser"
|
||||
"github.com/torrentclaw/torrentclaw-cli/internal/ui"
|
||||
"github.com/torrentclaw/unarr/internal/engine"
|
||||
"github.com/torrentclaw/unarr/internal/parser"
|
||||
"github.com/torrentclaw/unarr/internal/ui"
|
||||
)
|
||||
|
||||
func newStreamCmd() *cobra.Command {
|
||||
|
|
|
|||
|
|
@ -8,10 +8,10 @@ import (
|
|||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/torrentclaw/torrentclaw-cli/internal/agent"
|
||||
"github.com/torrentclaw/torrentclaw-cli/internal/config"
|
||||
"github.com/torrentclaw/torrentclaw-cli/internal/engine"
|
||||
"github.com/torrentclaw/torrentclaw-cli/internal/ui"
|
||||
"github.com/torrentclaw/unarr/internal/agent"
|
||||
"github.com/torrentclaw/unarr/internal/config"
|
||||
"github.com/torrentclaw/unarr/internal/engine"
|
||||
"github.com/torrentclaw/unarr/internal/ui"
|
||||
)
|
||||
|
||||
// streamRegistry tracks active stream tasks and servers for cancellation.
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ func newStubCmd(name, short string) *cobra.Command {
|
|||
fmt.Println()
|
||||
color.New(color.FgYellow).Printf(" ⚠️ '%s' is coming in a future release.\n", name)
|
||||
fmt.Println()
|
||||
fmt.Println(" Follow progress at: https://github.com/torrentclaw/torrentclaw-cli")
|
||||
fmt.Println(" Follow progress at: https://github.com/torrentclaw/unarr")
|
||||
fmt.Println()
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import (
|
|||
"github.com/spf13/cobra"
|
||||
tc "github.com/torrentclaw/go-client"
|
||||
|
||||
"github.com/torrentclaw/torrentclaw-cli/internal/ui"
|
||||
"github.com/torrentclaw/unarr/internal/ui"
|
||||
)
|
||||
|
||||
func newWatchCmd() *cobra.Command {
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/torrentclaw/torrentclaw-cli/internal/agent"
|
||||
"github.com/torrentclaw/unarr/internal/agent"
|
||||
)
|
||||
|
||||
func TestDebridAvailable(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import (
|
|||
"log"
|
||||
"sync"
|
||||
|
||||
"github.com/torrentclaw/torrentclaw-cli/internal/agent"
|
||||
"github.com/torrentclaw/unarr/internal/agent"
|
||||
)
|
||||
|
||||
// ManagerConfig holds download manager settings.
|
||||
|
|
@ -24,6 +24,7 @@ type Manager struct {
|
|||
|
||||
activeMu sync.RWMutex
|
||||
active map[string]*Task
|
||||
cancels map[string]context.CancelFunc // per-task cancel functions
|
||||
|
||||
sem chan struct{}
|
||||
wg sync.WaitGroup
|
||||
|
|
@ -45,6 +46,7 @@ func NewManager(cfg ManagerConfig, reporter *ProgressReporter, downloaders ...Do
|
|||
reporter: reporter,
|
||||
downloaders: dlMap,
|
||||
active: make(map[string]*Task),
|
||||
cancels: make(map[string]context.CancelFunc),
|
||||
sem: make(chan struct{}, cfg.MaxConcurrent),
|
||||
}
|
||||
}
|
||||
|
|
@ -53,8 +55,12 @@ func NewManager(cfg ManagerConfig, reporter *ProgressReporter, downloaders ...Do
|
|||
func (m *Manager) Submit(ctx context.Context, at agent.Task) {
|
||||
task := NewTaskFromAgent(at)
|
||||
|
||||
// Per-task cancellable context so CancelTask can unblock the goroutine
|
||||
taskCtx, taskCancel := context.WithCancel(ctx)
|
||||
|
||||
m.activeMu.Lock()
|
||||
m.active[task.ID] = task
|
||||
m.cancels[task.ID] = taskCancel
|
||||
m.activeMu.Unlock()
|
||||
|
||||
m.reporter.Track(task)
|
||||
|
|
@ -65,7 +71,8 @@ func (m *Manager) Submit(ctx context.Context, at agent.Task) {
|
|||
m.wg.Add(1)
|
||||
go func() {
|
||||
defer m.wg.Done()
|
||||
m.processTask(ctx, task)
|
||||
defer taskCancel()
|
||||
m.processTask(taskCtx, task)
|
||||
}()
|
||||
return
|
||||
}
|
||||
|
|
@ -74,6 +81,7 @@ func (m *Manager) Submit(ctx context.Context, at agent.Task) {
|
|||
select {
|
||||
case m.sem <- struct{}{}:
|
||||
case <-ctx.Done():
|
||||
taskCancel()
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -81,7 +89,8 @@ func (m *Manager) Submit(ctx context.Context, at agent.Task) {
|
|||
go func() {
|
||||
defer m.wg.Done()
|
||||
defer func() { <-m.sem }()
|
||||
m.processTask(ctx, task)
|
||||
defer taskCancel()
|
||||
m.processTask(taskCtx, task)
|
||||
}()
|
||||
}
|
||||
|
||||
|
|
@ -119,12 +128,19 @@ func (m *Manager) ActiveTasks() []*Task {
|
|||
func (m *Manager) CancelTask(taskID string) {
|
||||
m.activeMu.RLock()
|
||||
task, ok := m.active[taskID]
|
||||
cancel := m.cancels[taskID]
|
||||
m.activeMu.RUnlock()
|
||||
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
// Cancel the task's context first — this unblocks the goroutine
|
||||
// (e.g. stuck waiting for metadata) so it exits and releases the semaphore slot.
|
||||
if cancel != nil {
|
||||
cancel()
|
||||
}
|
||||
|
||||
if dl, exists := m.downloaders[task.ResolvedMethod]; exists {
|
||||
dl.Pause(taskID) // stop download, keep files
|
||||
}
|
||||
|
|
@ -141,12 +157,17 @@ func (m *Manager) CancelTask(taskID string) {
|
|||
func (m *Manager) PauseTask(taskID string) {
|
||||
m.activeMu.RLock()
|
||||
task, ok := m.active[taskID]
|
||||
cancel := m.cancels[taskID]
|
||||
m.activeMu.RUnlock()
|
||||
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
if cancel != nil {
|
||||
cancel()
|
||||
}
|
||||
|
||||
if dl, exists := m.downloaders[task.ResolvedMethod]; exists {
|
||||
dl.Pause(taskID) // stop download, keep files for resume
|
||||
}
|
||||
|
|
@ -159,12 +180,17 @@ func (m *Manager) PauseTask(taskID string) {
|
|||
func (m *Manager) CancelAndDeleteFiles(taskID string) {
|
||||
m.activeMu.RLock()
|
||||
task, ok := m.active[taskID]
|
||||
cancel := m.cancels[taskID]
|
||||
m.activeMu.RUnlock()
|
||||
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
if cancel != nil {
|
||||
cancel()
|
||||
}
|
||||
|
||||
if dl, exists := m.downloaders[task.ResolvedMethod]; exists {
|
||||
dl.Cancel(taskID) // stop download + delete files
|
||||
}
|
||||
|
|
@ -204,8 +230,12 @@ func (m *Manager) Shutdown(ctx context.Context) {
|
|||
}
|
||||
}
|
||||
|
||||
// Clean active map
|
||||
// Clean active map and cancel functions
|
||||
m.activeMu.Lock()
|
||||
for id, cancel := range m.cancels {
|
||||
cancel()
|
||||
delete(m.cancels, id)
|
||||
}
|
||||
m.active = make(map[string]*Task)
|
||||
m.activeMu.Unlock()
|
||||
}
|
||||
|
|
@ -214,6 +244,7 @@ func (m *Manager) processTask(ctx context.Context, task *Task) {
|
|||
defer func() {
|
||||
m.activeMu.Lock()
|
||||
delete(m.active, task.ID)
|
||||
delete(m.cancels, task.ID)
|
||||
m.activeMu.Unlock()
|
||||
}()
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/torrentclaw/torrentclaw-cli/internal/agent"
|
||||
"github.com/torrentclaw/unarr/internal/agent"
|
||||
)
|
||||
|
||||
func TestManagerSubmitAndWait(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import (
|
|||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/torrentclaw/torrentclaw-cli/internal/agent"
|
||||
"github.com/torrentclaw/unarr/internal/agent"
|
||||
)
|
||||
|
||||
// ActionFunc is called when the server signals an action on a task.
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/torrentclaw/torrentclaw-cli/internal/agent"
|
||||
"github.com/torrentclaw/unarr/internal/agent"
|
||||
)
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import (
|
|||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/torrentclaw/torrentclaw-cli/internal/agent"
|
||||
"github.com/torrentclaw/unarr/internal/agent"
|
||||
)
|
||||
|
||||
// TaskStatus represents the current state of a download task.
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ package engine
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/torrentclaw/torrentclaw-cli/internal/agent"
|
||||
"github.com/torrentclaw/unarr/internal/agent"
|
||||
)
|
||||
|
||||
func TestNewTaskFromAgent(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ import (
|
|||
"github.com/anacrolix/dht/v2/krpc"
|
||||
"github.com/anacrolix/torrent"
|
||||
"github.com/anacrolix/torrent/storage"
|
||||
"github.com/torrentclaw/torrentclaw-cli/internal/config"
|
||||
"github.com/torrentclaw/unarr/internal/config"
|
||||
"golang.org/x/time/rate"
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -20,11 +20,13 @@ type UPnPMapping struct {
|
|||
// setupUPnP discovers the gateway, maps the port, and gets the public IP.
|
||||
// Returns nil if UPnP is not available or fails.
|
||||
func setupUPnP(internalPort int) (*UPnPMapping, error) {
|
||||
devices := upnp.Discover(0, 5*time.Second, alog.Logger{})
|
||||
log.Println("stream: discovering UPnP gateway (10s timeout)...")
|
||||
devices := upnp.Discover(0, 10*time.Second, alog.Logger{})
|
||||
if len(devices) == 0 {
|
||||
return nil, fmt.Errorf("no UPnP devices found")
|
||||
return nil, fmt.Errorf("no UPnP devices found (is UPnP enabled on your router?)")
|
||||
}
|
||||
|
||||
log.Printf("stream: found %d UPnP device(s), using %s", len(devices), devices[0].ID())
|
||||
device := devices[0]
|
||||
|
||||
// Get public IP
|
||||
|
|
@ -32,13 +34,15 @@ func setupUPnP(internalPort int) (*UPnPMapping, error) {
|
|||
if err != nil {
|
||||
return nil, fmt.Errorf("get external IP: %w", err)
|
||||
}
|
||||
log.Printf("stream: public IP via UPnP: %s", externalIP)
|
||||
|
||||
// Map port (0 = let router choose external port, 2h lease)
|
||||
// Map port (same internal/external, 2h lease)
|
||||
mappedPort, err := device.AddPortMapping(upnp.TCP, internalPort, internalPort, "unarr stream", 2*time.Hour)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("add port mapping: %w", err)
|
||||
return nil, fmt.Errorf("add port mapping %d: %w", internalPort, err)
|
||||
}
|
||||
|
||||
log.Printf("stream: UPnP port mapped %s:%d -> local:%d (2h lease)", externalIP, mappedPort, internalPort)
|
||||
return &UPnPMapping{
|
||||
ExternalIP: externalIP.String(),
|
||||
ExternalPort: mappedPort,
|
||||
|
|
|
|||
|
|
@ -10,12 +10,12 @@ import (
|
|||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/torrentclaw/torrentclaw-cli/internal/agent"
|
||||
"github.com/torrentclaw/torrentclaw-cli/internal/config"
|
||||
"github.com/torrentclaw/torrentclaw-cli/internal/usenet/download"
|
||||
"github.com/torrentclaw/torrentclaw-cli/internal/usenet/nntp"
|
||||
"github.com/torrentclaw/torrentclaw-cli/internal/usenet/nzb"
|
||||
"github.com/torrentclaw/torrentclaw-cli/internal/usenet/postprocess"
|
||||
"github.com/torrentclaw/unarr/internal/agent"
|
||||
"github.com/torrentclaw/unarr/internal/config"
|
||||
"github.com/torrentclaw/unarr/internal/usenet/download"
|
||||
"github.com/torrentclaw/unarr/internal/usenet/nntp"
|
||||
"github.com/torrentclaw/unarr/internal/usenet/nzb"
|
||||
"github.com/torrentclaw/unarr/internal/usenet/postprocess"
|
||||
)
|
||||
|
||||
// activeDownload holds the state for a single in-progress usenet download.
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import (
|
|||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/torrentclaw/torrentclaw-cli/internal/config"
|
||||
"github.com/torrentclaw/unarr/internal/config"
|
||||
)
|
||||
|
||||
// CachePath returns the default library cache file path.
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import (
|
|||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/torrentclaw/torrentclaw-cli/internal/library/mediainfo"
|
||||
"github.com/torrentclaw/unarr/internal/library/mediainfo"
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ package library
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/torrentclaw/torrentclaw-cli/internal/library/mediainfo"
|
||||
"github.com/torrentclaw/unarr/internal/library/mediainfo"
|
||||
)
|
||||
|
||||
func TestResolveResolution(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -11,8 +11,8 @@ import (
|
|||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/torrentclaw/torrentclaw-cli/internal/library/mediainfo"
|
||||
"github.com/torrentclaw/torrentclaw-cli/internal/parser"
|
||||
"github.com/torrentclaw/unarr/internal/library/mediainfo"
|
||||
"github.com/torrentclaw/unarr/internal/parser"
|
||||
)
|
||||
|
||||
// videoExts are file extensions considered as video files.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
package library
|
||||
|
||||
import "github.com/torrentclaw/torrentclaw-cli/internal/agent"
|
||||
import "github.com/torrentclaw/unarr/internal/agent"
|
||||
|
||||
// BuildSyncItems converts cached library items to sync request items.
|
||||
// Shared between unarr scan (cmd/scan.go) and auto-scan (cmd/daemon.go).
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
package library
|
||||
|
||||
import "github.com/torrentclaw/torrentclaw-cli/internal/library/mediainfo"
|
||||
import "github.com/torrentclaw/unarr/internal/library/mediainfo"
|
||||
|
||||
// LibraryItem represents a single scanned media file.
|
||||
type LibraryItem struct {
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import (
|
|||
)
|
||||
|
||||
// dsn is injected at build time via ldflags. If empty, Sentry is disabled.
|
||||
// Set via: -ldflags "-X github.com/torrentclaw/torrentclaw-cli/internal/sentry.dsn=..."
|
||||
// Set via: -ldflags "-X github.com/torrentclaw/unarr/internal/sentry.dsn=..."
|
||||
var dsn string
|
||||
|
||||
const flushTimeout = 2 * time.Second
|
||||
|
|
|
|||
|
|
@ -12,9 +12,9 @@ import (
|
|||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/torrentclaw/torrentclaw-cli/internal/usenet/nntp"
|
||||
"github.com/torrentclaw/torrentclaw-cli/internal/usenet/nzb"
|
||||
"github.com/torrentclaw/torrentclaw-cli/internal/usenet/yenc"
|
||||
"github.com/torrentclaw/unarr/internal/usenet/nntp"
|
||||
"github.com/torrentclaw/unarr/internal/usenet/nzb"
|
||||
"github.com/torrentclaw/unarr/internal/usenet/yenc"
|
||||
)
|
||||
|
||||
// Progress is emitted during download.
|
||||
|
|
|
|||
|
|
@ -8,10 +8,10 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/torrentclaw/torrentclaw-cli/internal/usenet/download"
|
||||
"github.com/torrentclaw/torrentclaw-cli/internal/usenet/nntp"
|
||||
"github.com/torrentclaw/torrentclaw-cli/internal/usenet/nzb"
|
||||
"github.com/torrentclaw/torrentclaw-cli/internal/usenet/postprocess"
|
||||
"github.com/torrentclaw/unarr/internal/usenet/download"
|
||||
"github.com/torrentclaw/unarr/internal/usenet/nntp"
|
||||
"github.com/torrentclaw/unarr/internal/usenet/nzb"
|
||||
"github.com/torrentclaw/unarr/internal/usenet/postprocess"
|
||||
)
|
||||
|
||||
// TestE2EDownload is a real end-to-end test that downloads from Usenet.
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import (
|
|||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/torrentclaw/torrentclaw-cli/internal/usenet/nzb"
|
||||
"github.com/torrentclaw/unarr/internal/usenet/nzb"
|
||||
)
|
||||
|
||||
// Binary progress file format:
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import (
|
|||
|
||||
"time"
|
||||
|
||||
"github.com/torrentclaw/torrentclaw-cli/internal/usenet/nzb"
|
||||
"github.com/torrentclaw/unarr/internal/usenet/nzb"
|
||||
)
|
||||
|
||||
var fixedPast = time.Now().Add(-30 * 24 * time.Hour)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue