Skip to content

Commit 57ce693

Browse files
authored
Merge pull request #38 from LumePart/feat/download-migration
download migration for slskd
2 parents 9df7cfa + 269d394 commit 57ce693

File tree

3 files changed

+74
-6
lines changed

3 files changed

+74
-6
lines changed

src/config/config.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ type Slskd struct {
7878
URL string `env:"SLSKD_URL"`
7979
Retry int `env:"SLSKD_RETRY" env-default:"5"` // Number of times to check search status before skipping the track
8080
DownloadAttempts int `env:"SLSKD_DL_ATTEMPTS" env-default:"3"` // Max number of files to attempt downloading per track
81+
SlskdDir string `env:"SLSKD_DIR" env-default:"/slskd/"`
82+
MigrateDL bool `env:"MIGRATE_DOWNLOADS" env-default:"false"` // Move downloads from SlskdDir to DownloadDir
8183
Timeout time.Duration `env:"SLSKD_TIMEOUT" env-default:"20s"`
8284
Filters Filters
8385
}

src/downloader/downloader.go

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import (
77
"strings"
88
"regexp"
99
"fmt"
10+
"path/filepath"
11+
"io"
1012
"golang.org/x/sync/errgroup"
1113

1214
cfg "explo/src/config"
@@ -33,7 +35,7 @@ func NewDownloader(cfg *cfg.DownloadConfig, httpClient *util.HttpClient) *Downlo
3335
case "youtube":
3436
downloader = append(downloader, NewYoutube(cfg.Youtube, cfg.Discovery, cfg.DownloadDir, httpClient))
3537
case "slskd":
36-
slskdClient := NewSlskd(cfg.Slskd)
38+
slskdClient := NewSlskd(cfg.Slskd, cfg.DownloadDir)
3739
slskdClient.AddHeader()
3840
downloader = append(downloader, slskdClient)
3941
default:
@@ -128,4 +130,60 @@ func getFilename(title, artist string) string {
128130
a := re.ReplaceAllString(artist, "_")
129131

130132
return fmt.Sprintf("%s-%s",t,a)
133+
}
134+
135+
func moveDownload(srcDir, destDir, trackPath, file string) error { // Move download from the source dir to the dest dir (download dir)
136+
trackDir := filepath.Join(srcDir, trackPath)
137+
srcFile := filepath.Join(trackDir, file)
138+
139+
info, err := os.Stat(srcFile)
140+
if err != nil {
141+
return fmt.Errorf("stat error: %s", err.Error())
142+
}
143+
144+
in, err := os.Open(srcFile)
145+
if err != nil {
146+
return fmt.Errorf("couldn't open source file: %s", err.Error())
147+
}
148+
149+
defer func() {
150+
if cerr := in.Close(); cerr != nil {
151+
log.Printf("warning: failed to close source file: %s", cerr)
152+
}
153+
}()
154+
155+
dstDir := filepath.Join(destDir, trackPath)
156+
if err = os.MkdirAll(dstDir, os.ModePerm); err != nil {
157+
return fmt.Errorf("couldn't make download directory: %s", err.Error())
158+
}
159+
160+
dstFile := filepath.Join(dstDir, file)
161+
out, err := os.Create(dstFile)
162+
if err != nil {
163+
return fmt.Errorf("couldn't create destination file: %s", err.Error())
164+
}
165+
166+
defer func() {
167+
if err = out.Close(); err != nil {
168+
log.Printf("failed to close destination file: %s", err.Error())
169+
}
170+
}()
171+
172+
if _, err = io.Copy(out, in); err != nil {
173+
return fmt.Errorf("copy failed: %s", err.Error())
174+
}
175+
176+
if err = out.Sync(); err != nil {
177+
return fmt.Errorf("sync failed: %s", err.Error())
178+
}
179+
180+
if err = os.Chmod(dstFile, info.Mode()); err != nil {
181+
return fmt.Errorf("chmod failed: %s", err.Error())
182+
}
183+
184+
if err = os.Remove(srcFile); err != nil {
185+
return fmt.Errorf("failed to delete original file: %s", err.Error())
186+
}
187+
188+
return nil
131189
}

src/downloader/slskd.go

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -96,12 +96,14 @@ type DownloadMonitor struct {
9696
type Slskd struct {
9797
Headers map[string]string
9898
HttpClient *util.HttpClient
99+
DownloadDir string
99100
Cfg config.Slskd
100101
}
101102

102-
func NewSlskd(cfg config.Slskd) *Slskd {
103+
func NewSlskd(cfg config.Slskd, downloadDir string) *Slskd {
103104
return &Slskd{Cfg: cfg,
104-
HttpClient: util.NewHttp(util.HttpClientConfig{Timeout: cfg.Timeout})}
105+
HttpClient: util.NewHttp(util.HttpClientConfig{Timeout: cfg.Timeout}),
106+
DownloadDir: downloadDir,}
105107
}
106108

107109
func (c *Slskd) AddHeader() {
@@ -399,8 +401,14 @@ func (c *Slskd) MonitorDownloads(tracks []*models.Track) error {
399401
if fileStatus.BytesRemaining == 0 || fileStatus.PercentComplete == 100 || strings.Contains(fileStatus.State, "Succeeded") {
400402
track.Present = true
401403
log.Printf("[slskd] %s downloaded successfully", track.File)
402-
track.File = parsePath(track.File)
404+
file, path := parsePath(track.File)
405+
if c.Cfg.MigrateDL {
406+
if err = moveDownload(c.Cfg.SlskdDir, c.DownloadDir, path, file); err != nil {
407+
debug.Debug(err.Error())
408+
}
409+
}
403410
delete(progressMap, key)
411+
track.File = file
404412
successDownloads += 1
405413
continue
406414

@@ -479,8 +487,8 @@ func (c Slskd) deleteDownload(user, ID string) error {
479487
return nil
480488
}
481489

482-
func parsePath(p string) string { // parse filepath to downloaded format and return filename
490+
func parsePath(p string) (string, string) { // parse filepath to downloaded format, return filename and parent dir
483491
p = strings.ReplaceAll(p, `\`, `/`)
484-
return filepath.Base(p)
492+
return filepath.Base(p), filepath.Base(filepath.Dir(p))
485493

486494
}

0 commit comments

Comments
 (0)