Intial Commit.
This commit is contained in:
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
newsboat-yt
|
||||
36
config/config.go
Normal file
36
config/config.go
Normal file
@@ -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
|
||||
}
|
||||
130
database/database.go
Normal file
130
database/database.go
Normal file
@@ -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
|
||||
}
|
||||
35
download/download.go
Normal file
35
download/download.go
Normal file
@@ -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
|
||||
}
|
||||
8
go.mod
Normal file
8
go.mod
Normal file
@@ -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
|
||||
)
|
||||
4
go.sum
Normal file
4
go.sum
Normal file
@@ -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=
|
||||
46
main.go
Normal file
46
main.go
Normal file
@@ -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
|
||||
}
|
||||
44
utils/utils.go
Normal file
44
utils/utils.go
Normal file
@@ -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
|
||||
}
|
||||
Reference in New Issue
Block a user