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