diff --git a/config/config.go b/config/config.go
index 9b17795..ba6cc53 100644
--- a/config/config.go
+++ b/config/config.go
@@ -189,9 +189,10 @@ func (c *Config) UpdateFromJSON(j []byte) error {
}
// check the command exists
- _, err := exec.LookPath(newConfig.DownloadProfiles[i].Command)
+
+ _, err := AbsPathToExecutable(newConfig.DownloadProfiles[i].Command)
if err != nil {
- return fmt.Errorf("Could not find %s on the path", newConfig.DownloadProfiles[i].Command)
+ return fmt.Errorf("problem with command '%s': %s", newConfig.DownloadProfiles[i].Command, err)
}
}
@@ -337,3 +338,28 @@ func (cs *ConfigService) WriteConfig() {
}
file.Close()
}
+
+// AbsPathToExecutable takes a command name, which may or may not be path-qualified,
+// and returns the fully qualified path to it, or an error if could not be found, or
+// if it does not appear to be a file.
+func AbsPathToExecutable(cmd string) (string, error) {
+
+ pathCmd, err := exec.LookPath(cmd)
+ if err != nil {
+ return "", fmt.Errorf("could not LookPath '%s': %w", cmd, err)
+ }
+
+ execAbsolutePath, err := filepath.Abs(pathCmd)
+ if err != nil {
+ return "", fmt.Errorf("could not get absolute path to '%s': %w", cmd, err)
+ }
+ fi, err := os.Stat(execAbsolutePath)
+ if err != nil {
+ return "", fmt.Errorf("could not get stat '%s': %w", cmd, err)
+ }
+ if !fi.Mode().IsRegular() {
+ return "", fmt.Errorf("'%s' is not a regular file: %w", cmd, err)
+ }
+
+ return execAbsolutePath, nil
+}
diff --git a/config/config_test.go b/config/config_test.go
index f4a23af..22b8e7d 100644
--- a/config/config_test.go
+++ b/config/config_test.go
@@ -2,6 +2,8 @@ package config
import (
"os"
+ "os/exec"
+ "path/filepath"
"testing"
"github.com/stretchr/testify/assert"
@@ -172,3 +174,41 @@ func configServiceFromString(configString string) *ConfigService {
}
return &cs
}
+
+func TestLookForExecutable(t *testing.T) {
+ cmdPath, err := exec.LookPath("sleep")
+ if err != nil {
+ t.Errorf("cannot run this test without knowing about sleep: %s", err)
+ t.FailNow()
+ }
+ cmdDir := filepath.Dir(cmdPath)
+
+ cmd := "sleep"
+ path, err := AbsPathToExecutable(cmd)
+ if assert.NoError(t, err) {
+ assert.Equal(t, cmdPath, path)
+ }
+
+ cmd = cmdPath
+ path, err = AbsPathToExecutable(cmd)
+ if assert.NoError(t, err) {
+ assert.Equal(t, cmdPath, path)
+ }
+
+ cmd = "../../../../../../../../.." + cmdPath
+ path, err = AbsPathToExecutable(cmd)
+ if assert.NoError(t, err) {
+ assert.Equal(t, cmdPath, path)
+ }
+ cmd = "./sleep"
+ _, err = AbsPathToExecutable(cmd)
+ assert.Error(t, err)
+
+ os.Chdir(cmdDir)
+ cmd = "./sleep"
+ path, err = AbsPathToExecutable(cmd)
+ if assert.NoError(t, err) {
+ assert.Equal(t, cmdPath, path)
+ }
+
+}
diff --git a/download/download.go b/download/download.go
index e24f8cc..4d9108f 100644
--- a/download/download.go
+++ b/download/download.go
@@ -281,13 +281,18 @@ func (dl *Download) Begin() {
cmdSlice = append(cmdSlice, dl.Url)
}
- dl.Log = append(dl.Log, fmt.Sprintf("executing: %s with args: %s", dl.DownloadProfile.Command, strings.Join(cmdSlice, " ")))
-
- cmdPath, err := absPathToExecutable(dl.DownloadProfile.Command)
+ cmdPath, err := config.AbsPathToExecutable(dl.DownloadProfile.Command)
if err != nil {
- panic(err)
+ dl.State = STATE_FAILED
+ dl.Finished = true
+ dl.FinishedTS = time.Now()
+ dl.Log = append(dl.Log, fmt.Sprintf("error finding executable for downloader: %s", err.Error()))
+ dl.Lock.Unlock()
+ return
}
+ dl.Log = append(dl.Log, fmt.Sprintf("executing: %s (%s) with args: %s", dl.DownloadProfile.Command, cmdPath, strings.Join(cmdSlice, " ")))
+
cmd := exec.Command(cmdPath, cmdSlice...)
cmd.Dir = dl.Config.Server.DownloadPath
log.Printf("Executing command executable: %s) in %s", cmdPath, dl.Config.Server.DownloadPath)
@@ -299,7 +304,6 @@ func (dl *Download) Begin() {
dl.FinishedTS = time.Now()
dl.Log = append(dl.Log, fmt.Sprintf("error setting up stdout pipe: %v", err))
dl.Lock.Unlock()
-
return
}
@@ -373,28 +377,6 @@ func (dl *Download) Begin() {
dl.Lock.Unlock()
}
-func absPathToExecutable(cmd string) (string, error) {
-
- pathCmd, err := exec.LookPath(cmd)
- if err != nil {
- return "", fmt.Errorf("could not LookPath '%s': %w", cmd, err)
- }
-
- execAbsolutePath, err := filepath.Abs(pathCmd)
- if err != nil {
- return "", fmt.Errorf("could not get absolute path to '%s': %w", cmd, err)
- }
- fi, err := os.Stat(execAbsolutePath)
- if err != nil {
- return "", fmt.Errorf("could not get stat '%s': %w", cmd, err)
- }
- if !fi.Mode().IsRegular() {
- return "", fmt.Errorf("'%s' is not a regular file: %w", cmd, err)
- }
-
- return execAbsolutePath, nil
-}
-
// updateDownload updates the download based on data from the reader. Expects the
// Download to be unlocked.
func (dl *Download) updateDownload(r io.Reader) {
diff --git a/download/download_test.go b/download/download_test.go
index 18cd2ba..0c07deb 100644
--- a/download/download_test.go
+++ b/download/download_test.go
@@ -1,15 +1,11 @@
package download
import (
- "os"
- "os/exec"
- "path/filepath"
"strings"
"sync"
"testing"
"time"
- "github.com/stretchr/testify/assert"
"github.com/tardisx/gropple/config"
)
@@ -364,41 +360,3 @@ Deleting original file The Greatest Shot In Television [2WoDQBhJCVQ].f140.m4a (p
}
}
-
-func TestLookForExecutable(t *testing.T) {
- cmdPath, err := exec.LookPath("sleep")
- if err != nil {
- t.Errorf("cannot run this test without knowing about sleep: %s", err)
- t.FailNow()
- }
- cmdDir := filepath.Dir(cmdPath)
-
- cmd := "sleep"
- path, err := absPathToExecutable(cmd)
- if assert.NoError(t, err) {
- assert.Equal(t, cmdPath, path)
- }
-
- cmd = cmdPath
- path, err = absPathToExecutable(cmd)
- if assert.NoError(t, err) {
- assert.Equal(t, cmdPath, path)
- }
-
- cmd = "../../../../../../../../.." + cmdPath
- path, err = absPathToExecutable(cmd)
- if assert.NoError(t, err) {
- assert.Equal(t, cmdPath, path)
- }
- cmd = "./sleep"
- _, err = absPathToExecutable(cmd)
- assert.Error(t, err)
-
- os.Chdir(cmdDir)
- cmd = "./sleep"
- path, err = absPathToExecutable(cmd)
- if assert.NoError(t, err) {
- assert.Equal(t, cmdPath, path)
- }
-
-}
diff --git a/main.go b/main.go
index b41c5a5..e33ed59 100644
--- a/main.go
+++ b/main.go
@@ -15,7 +15,7 @@ import (
func main() {
versionInfo := &version.Manager{
- VersionInfo: version.Info{CurrentVersion: "v1.1.1-alpha.1"},
+ VersionInfo: version.Info{CurrentVersion: "v1.1.1-alpha.2"},
}
log.Printf("Starting gropple %s - https://github.com/tardisx/gropple", versionInfo.GetInfo().CurrentVersion)
diff --git a/web/data/templates/config.tmpl b/web/data/templates/config.tmpl
index 70e13c7..6d7d11e 100644
--- a/web/data/templates/config.tmpl
+++ b/web/data/templates/config.tmpl
@@ -84,7 +84,10 @@
- Which command to run. Your path will be searched, or you can specify the full path here.
+ Which command to run. Your path will be searched, or you can specify the full path here.
+ If you are using gropple in portable mode and store the executables with the gropple executable, use a prefix of
+ ./, for instance yt-dlp.exe.
+