works with ubuntu
commit
ccfefd5b77
|
|
@ -0,0 +1,3 @@
|
||||||
|
ytubeSpdrun
|
||||||
|
**/*.sw*
|
||||||
|
youtuber
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
package config
|
||||||
|
|
||||||
|
var (
|
||||||
|
Feed = "https://www.youtube.com/feeds/videos.xml?channel_id=UCwX0AEx-qIhQ9kgtlNhyIXw"
|
||||||
|
Root = "/tmp"
|
||||||
|
)
|
||||||
|
|
||||||
|
/*
|
||||||
|
config = {
|
||||||
|
"path" : "../TV/Shepherds_Chapel" ,
|
||||||
|
"rss" : "https://www.youtube.com/feeds/videos.xml?channel_id=UCwX0AEx-qIhQ9kgtlNhyIXw" ,
|
||||||
|
"last" : 0 ,
|
||||||
|
"lasttime" : datetime.datetime(1999,1,1) ,
|
||||||
|
"onlynew" : False ,
|
||||||
|
"delay" : 12 ,
|
||||||
|
"clear" : False ,
|
||||||
|
"logloc" : "./log" ,
|
||||||
|
"idle" : False ,
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
package feed
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/mmcdole/gofeed"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Fetch(s string) ([]Item, error) {
|
||||||
|
resp, err := http.Get(s)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
gofeed, err := gofeed.NewParser().Parse(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
links := make([]Item, 0)
|
||||||
|
|
||||||
|
for _, item := range gofeed.Items {
|
||||||
|
timestamp := strings.Split(item.Title, " ")[1]
|
||||||
|
t, err := time.Parse("1/2/06", timestamp)
|
||||||
|
if err == nil {
|
||||||
|
links = append(links, Item{
|
||||||
|
Link: item.Link,
|
||||||
|
Title: strings.ReplaceAll(item.Title, "/", "-"),
|
||||||
|
Date: t,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return links, nil
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
package feed
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
type Item struct {
|
||||||
|
Link string
|
||||||
|
Date time.Time
|
||||||
|
Title string
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,41 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"local/youtuber/config"
|
||||||
|
"local/youtuber/feed"
|
||||||
|
"local/youtuber/youtubedl"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"path"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
os.Setenv("LC_ALL", "C.UTF-8")
|
||||||
|
results, err := feed.Fetch(config.Feed)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
log.Println(results)
|
||||||
|
|
||||||
|
youtubedl, err := youtubedl.New()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, result := range results {
|
||||||
|
target := fmt.Sprintf(
|
||||||
|
"s%02d%02de%02d_%s.%%(ext)s",
|
||||||
|
result.Date.Year()-2000,
|
||||||
|
result.Date.Month(),
|
||||||
|
result.Date.Day(),
|
||||||
|
strings.Join(strings.Split(result.Title, " ")[2:], "_"),
|
||||||
|
)
|
||||||
|
if err := youtubedl.Download(result.Link, path.Join(config.Root, target)); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
log.Println(youtubedl)
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,101 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"local/jbtserve/jbt"
|
||||||
|
"local/system/sysconf"
|
||||||
|
"log"
|
||||||
|
"net"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"os/signal"
|
||||||
|
"path"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
|
"github.com/otium/ytdl"
|
||||||
|
)
|
||||||
|
|
||||||
|
var validURL = regexp.MustCompile("(?is)https?://([a-z1-9]+.)+[a-z]+/.*")
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
if os.Getenv("MNT") == "" {
|
||||||
|
os.Setenv("MNT", "./")
|
||||||
|
}
|
||||||
|
if !strings.HasSuffix(os.Getenv("MNT"), "/") {
|
||||||
|
os.Setenv("MNT", os.Getenv("MNT")+"/")
|
||||||
|
}
|
||||||
|
config := sysconf.Get("ytubespdrun")
|
||||||
|
exit := make(chan bool)
|
||||||
|
go jbt.RegisterDeregister(config.Name, config.Port, exit)
|
||||||
|
log.Print("Listen on", net.JoinHostPort(config.IP, config.Port))
|
||||||
|
go func() {
|
||||||
|
log.Print(http.ListenAndServe(net.JoinHostPort(config.IP, config.Port), http.HandlerFunc(accept)))
|
||||||
|
}()
|
||||||
|
sigc := make(chan os.Signal)
|
||||||
|
signal.Notify(sigc,
|
||||||
|
syscall.SIGINT,
|
||||||
|
)
|
||||||
|
<-sigc
|
||||||
|
<-exit
|
||||||
|
<-exit
|
||||||
|
}
|
||||||
|
|
||||||
|
func accept(w http.ResponseWriter, r *http.Request) {
|
||||||
|
config := sysconf.Get("ytubespdrun")
|
||||||
|
if r.Method != "POST" {
|
||||||
|
w.WriteHeader(http.StatusMethodNotAllowed)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
body, err := ioutil.ReadAll(r.Body)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
token := string(body)
|
||||||
|
token = strings.Split(token, "&")[0]
|
||||||
|
log.Print("Received request", token)
|
||||||
|
if !validURL.MatchString(token) {
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := download(token, config.Log); err != nil {
|
||||||
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
|
fmt.Fprintf(w, "Cannot download %s, encountered error %v", token, err)
|
||||||
|
log.Print("Failed request", token)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
log.Print("Completed request", token)
|
||||||
|
}
|
||||||
|
|
||||||
|
func download(url, log string) error {
|
||||||
|
vid, err := ytdl.GetVideoInfo(url)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
format := vid.Formats.Best(ytdl.FormatExtensionKey)
|
||||||
|
if len(format) < 1 {
|
||||||
|
return errors.New("no formats available")
|
||||||
|
}
|
||||||
|
log.Print("Downloading format", format[0].Resolution, format[0].Extension, format[0].Itag, "for video", vid.Title)
|
||||||
|
file, err := os.Create(os.Getenv("MNT") + strings.Replace(fmt.Sprintf("%s.%s", vid.Title, format[0].Extension), " ", "_", -1))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
return vid.Download(format[0], file)
|
||||||
|
}
|
||||||
|
|
||||||
|
func pathAdvance(r *http.Request) string {
|
||||||
|
p := path.Clean("/" + r.URL.Path)
|
||||||
|
i := strings.Index(p[1:], "/") + 1
|
||||||
|
if i <= 0 {
|
||||||
|
r.URL.Path = "/"
|
||||||
|
return p[1:]
|
||||||
|
}
|
||||||
|
r.URL.Path = p[i:]
|
||||||
|
return p[1:i]
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
#! /bin/bash
|
||||||
|
|
||||||
|
rsync -avzP --delete --exclude "alt.db" --exclude "alt.log" . /mnt/ipod/squeaky2x3D/curProjects/curProjects/Go/src/local/$(basename $(pwd))/
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
package youtubedl
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"os/exec"
|
||||||
|
"path"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Client struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func New() (*Client, error) {
|
||||||
|
return &Client{}, install()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) Download(video, local string) error {
|
||||||
|
cmd := exec.Command("youtube-dl", "-f", "22", "-o", local, "--write-sub", "--write-auto-sub", "--sub-format", "srt", video)
|
||||||
|
log.Println(cmd.Path, cmd.Args)
|
||||||
|
out, err := cmd.CombinedOutput()
|
||||||
|
if err != nil {
|
||||||
|
err = fmt.Errorf("%v: %s", err, out)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
cmd = exec.Command("python3", "-m", "vtt_to_srt", path.Dir(local))
|
||||||
|
out, err = cmd.CombinedOutput()
|
||||||
|
if err != nil {
|
||||||
|
err = fmt.Errorf("%v: %s", err, out)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
package youtubedl
|
||||||
|
|
||||||
|
import "os/exec"
|
||||||
|
|
||||||
|
func install() error {
|
||||||
|
cmd := exec.Command("youtube-dl", "--version")
|
||||||
|
if err := cmd.Run(); err == nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
cmd = exec.Command("sudo", "pip3", "install", "youtube-dl")
|
||||||
|
if err := cmd.Run(); err == nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func installYtdl() error {
|
||||||
|
cmd := exec.Command("youtube-dl", "--version")
|
||||||
|
if err := cmd.Run(); err == nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
cmd = exec.Command("sudo", "pip3", "install", "youtube-dl")
|
||||||
|
if err := cmd.Run(); err == nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func installVTT() error {
|
||||||
|
cmd := exec.Command("python3", "-m", "vtt_to_srt")
|
||||||
|
if err := cmd.Run(); err == nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
cmd = exec.Command("sudo", "pip3", "install", "vtt_to_srt3")
|
||||||
|
if err := cmd.Run(); err == nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue