commit ceefd07930b134aba4a3354e5ba65575f8ac0813 Author: Michael Lehmann Date: Tue Aug 6 22:56:35 2024 +0200 Intial Commit. diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7265edf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +newsboat-yt diff --git a/config/config.go b/config/config.go new file mode 100644 index 0000000..08f8b88 --- /dev/null +++ b/config/config.go @@ -0,0 +1,36 @@ +package config + +import ( + "errors" + "fmt" + "kattudden/newsboat-yt/utils" + "path/filepath" +) + + +type Config struct { + DatabaseDirectory string + DatabaseFilename string + DatabasePath string + DownloadPath string +} + + +func New() (*Config, error) { + databaseFileName := "db.sqlite" + databaseDirectory := ".cache/newsboat-yt" + downloadDirectory := "Videos/newsboat-yt" + + userHomeDir, err := utils.GetCurrentUserHomeDir() + if err != nil { + fmt.Println(err) + return nil, errors.New("failed to generate config!") + } + + return &Config { + DatabaseDirectory: databaseDirectory, + DatabaseFilename: databaseFileName, + DatabasePath: filepath.Join(userHomeDir, databaseDirectory, databaseFileName), + DownloadPath: filepath.Join(userHomeDir, downloadDirectory), + }, nil +} diff --git a/database/database.go b/database/database.go new file mode 100644 index 0000000..a9c2a2a --- /dev/null +++ b/database/database.go @@ -0,0 +1,130 @@ +package database + +import ( + "database/sql" + "fmt" + "kattudden/newsboat-yt/config" + + "github.com/google/uuid" + _"github.com/mattn/go-sqlite3" +) + +var conf, _ = config.New() + +func getDatabase() (*sql.DB, error){ + db, err := sql.Open("sqlite3", conf.DatabasePath) + if err != nil { + panic(err) + } + return db, nil +} + + +func createTable(db *sql.DB) { + sqlStatement := "CREATE TABLE IF NOT EXISTS queue (id TEXT not null primary key, link TEXT not null, downloaded BOOLEAN)" + _, err := db.Exec(sqlStatement) + if err != nil { + panic(err) + } +} + + +func InsertUrl(url string) error { + db, err := getDatabase() + if err != nil { + return err + } + + createTable(db) + + uuid := uuid.NewString() + sqlStatement := fmt.Sprintf("INSERT INTO queue (id, link, downloaded) VALUES (?, ?, ?)") + + tx, err := db.Begin() + if err != nil { + return err + } + + stmt, err := tx.Prepare(sqlStatement) + if err != nil { + return err + } + + defer stmt.Close() + + _, err = stmt.Exec(uuid, url, false) + if err != nil { + return err + } + + tx.Commit() + db.Close() + + return nil +} + + +type Url struct { + ID string + Link string +} + + +func GetUrls() ([]Url){ + db, _ := getDatabase() + + queryStatement := "SELECT id, link from queue WHERE downloaded = 0" + rows, _ := db.Query(queryStatement) + + var urls []Url + + for rows.Next() { + var id string + var link string + + rows.Scan(&id, &link) + + entry := Url{ + ID: id, + Link: link, + } + + urls = append(urls, entry) + } + + db.Close() + + return urls +} + + +func MarkUrlDownloaded(id string) error { + db, err := getDatabase() + if err != nil { + return err + } + + sqlStatement := `UPDATE queue SET downloaded = true WHERE id = ?` + + tx, err := db.Begin() + if err != nil { + return err + } + + stmt, err := tx.Prepare(sqlStatement) + if err != nil { + return err + } + + defer stmt.Close() + + _, err = stmt.Exec(id) + if err != nil { + return err + } + + tx.Commit() + db.Close() + + return nil +} diff --git a/download/download.go b/download/download.go new file mode 100644 index 0000000..422fae6 --- /dev/null +++ b/download/download.go @@ -0,0 +1,35 @@ +package download + +import ( + "errors" + "fmt" + "kattudden/newsboat-yt/config" + "kattudden/newsboat-yt/utils" + "os/exec" +) + + +func YoutubeVideo(url string) error { + conf, _ := config.New() + + err := utils.EnsureDirectory(conf.DownloadPath) + if err != nil { + return errors.New("failed to create download directory!") + } + + downloadBinary := "yt-dlp" + + output := fmt.Sprintf("%s/%%(title)s.%%(ext)s", conf.DownloadPath) + args := []string{"-S", "filesize~100M", "-o", output, url} + cmd := exec.Command(downloadBinary, args...) + + fmt.Println(cmd.String()) + + err = cmd.Run() + if err != nil { + fmt.Println(err) + return errors.New("failed to download video!") + } + + return nil +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..b55e7e9 --- /dev/null +++ b/go.mod @@ -0,0 +1,8 @@ +module kattudden/newsboat-yt + +go 1.22.5 + +require ( + github.com/google/uuid v1.6.0 // indirect + github.com/mattn/go-sqlite3 v1.14.22 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..e056088 --- /dev/null +++ b/go.sum @@ -0,0 +1,4 @@ +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= +github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= diff --git a/main.go b/main.go new file mode 100644 index 0000000..1486072 --- /dev/null +++ b/main.go @@ -0,0 +1,46 @@ +package main + +import ( + "fmt" + "flag" + "kattudden/newsboat-yt/database" + "kattudden/newsboat-yt/download" +) + + +func main() { + + + newUrl := flag.String("u", "", "add url to download queue.") + processQueue := flag.Bool("d", false, "start downloading from queue.") + + flag.Parse() + + if *newUrl != "" { + fmt.Println("Adding new URL.") + database.InsertUrl(*newUrl) + return + } + + if *processQueue { + fmt.Println("Processing queue...") + + urls := database.GetUrls() + for _, url := range urls { + err := download.YoutubeVideo(url.Link) + if err != nil { + fmt.Println("failed to download video: ", url.Link) + return + } + + fmt.Println("successfully downloaded: ", url.Link) + database.MarkUrlDownloaded(url.ID) + } + + fmt.Println("Done!") + return + } + + fmt.Println("Missing Argmuent; doing nothing.") + return +} diff --git a/utils/utils.go b/utils/utils.go new file mode 100644 index 0000000..b4cd35b --- /dev/null +++ b/utils/utils.go @@ -0,0 +1,44 @@ +package utils + +import ( + "errors" + "os" + "os/user" + "runtime" +) + + +func GetCurrentUserHomeDir() (homeDir string, err error){ + usr, err := user.Current() + if err != nil { + return "", errors.New("failed to get user homedir.") + } + + homeDir = usr.HomeDir + return homeDir, nil +} + + +func GetCurrentUserName() (userName string, err error) { + usr, err := user.Current() + if err != nil { + return "", errors.New("failed to get username.") + } + + userName = usr.Username + return userName, nil +} + +func EnsureDirectory(path string) error { + err := os.MkdirAll(path, os.ModePerm) + if err != nil { + return errors.New("failed to create folder.") + } + return nil +} + + +func GetOSFamily() (os string) { + os = runtime.GOOS + return +}